From 14260af7e7b0da52809176c1221b270113d048fb Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Fri, 27 Feb 2026 12:53:19 +0000 Subject: [PATCH 01/13] refactor(ml): Migrate to typescript --- packages/ml/lib/index.d.ts | 103 -------------------- packages/ml/lib/index.ts | 27 +++++ packages/ml/lib/modular.ts | 35 +++++++ packages/ml/lib/modular/index.d.ts | 14 --- packages/ml/lib/modular/index.js | 17 ---- packages/ml/lib/{index.js => namespaced.ts} | 32 +++--- packages/ml/lib/types/ml.ts | 71 ++++++++++++++ packages/ml/package.json | 32 +++++- packages/ml/tsconfig.json | 15 +++ tsconfig.json | 7 +- 10 files changed, 198 insertions(+), 155 deletions(-) delete mode 100644 packages/ml/lib/index.d.ts create mode 100644 packages/ml/lib/index.ts create mode 100644 packages/ml/lib/modular.ts delete mode 100644 packages/ml/lib/modular/index.d.ts delete mode 100644 packages/ml/lib/modular/index.js rename packages/ml/lib/{index.js => namespaced.ts} (63%) create mode 100644 packages/ml/lib/types/ml.ts create mode 100644 packages/ml/tsconfig.json diff --git a/packages/ml/lib/index.d.ts b/packages/ml/lib/index.d.ts deleted file mode 100644 index 127437634e..0000000000 --- a/packages/ml/lib/index.d.ts +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2016-present Invertase Limited & Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this library except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import { ReactNativeFirebase } from '@react-native-firebase/app'; -/** - * Firebase ML package for React Native. - * - * #### Example 1 - * - * Access the firebase export from the `ml` package: - * - * ```js - * import { firebase } from '@react-native-firebase/ml'; - * - * // firebase.ml().X - * ``` - * - * #### Example 2 - * - * Using the default export from the `ml` package: - * - * ```js - * import ml from '@react-native-firebase/ml'; - * - * // ml().X - * ``` - * - * #### Example 3 - * - * Using the default export from the `app` package: - * - * ```js - * import firebase from '@react-native-firebase/app'; - * import '@react-native-firebase/ml'; - * - * // firebase.ml().X - * ``` - * - * @firebase ml - */ -export namespace FirebaseMLTypes { - import FirebaseModule = ReactNativeFirebase.FirebaseModule; - - export interface Statics { - SDK_VERSION: string; - } - - export class Module extends FirebaseModule { - /** - * The current `FirebaseApp` instance for this Firebase service. - */ - app: ReactNativeFirebase.FirebaseApp; - } -} - -type MLNamespace = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< - FirebaseMLTypes.Module, - FirebaseMLTypes.Statics -> & { - firebase: ReactNativeFirebase.Module; - app(name?: string): ReactNativeFirebase.FirebaseApp; -}; - -declare const defaultExport: MLNamespace; - -export const firebase: ReactNativeFirebase.Module & { - ml: typeof defaultExport; - app(name?: string): ReactNativeFirebase.FirebaseApp & { ml(): FirebaseMLTypes.Module }; -}; - -export default defaultExport; - -export * from './modular'; - -/** - * Attach namespace to `firebase.` and `FirebaseApp.`. - */ -declare module '@react-native-firebase/app' { - namespace ReactNativeFirebase { - import FirebaseModuleWithStaticsAndApp = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp; - interface Module { - ml: FirebaseModuleWithStaticsAndApp; - } - - interface FirebaseApp { - ml(): FirebaseMLTypes.Module; - } - } -} diff --git a/packages/ml/lib/index.ts b/packages/ml/lib/index.ts new file mode 100644 index 0000000000..dad7158212 --- /dev/null +++ b/packages/ml/lib/index.ts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Export types from types/ml +export type { ML, Statics, FirebaseApp } from './types/ml'; +export type { FirebaseMLTypes } from './types/ml'; + +// Export modular API functions +export * from './modular'; + +// Export namespaced API +export * from './namespaced'; +export { default } from './namespaced'; diff --git a/packages/ml/lib/modular.ts b/packages/ml/lib/modular.ts new file mode 100644 index 0000000000..717f403186 --- /dev/null +++ b/packages/ml/lib/modular.ts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { getApp } from '@react-native-firebase/app'; +import type { FirebaseApp } from '@react-native-firebase/app'; +import type { ML } from './types/ml'; + +/** + * Returns the existing default {@link ML} instance that is associated with the + * default {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new + * instance with default settings. + * + * @param app - Optional {@link FirebaseApp} instance. If not provided, uses the default app. + * @returns The {@link ML} instance of the provided app. + */ +export function getML(app?: FirebaseApp): ML { + if (app) { + return getApp(app.name).ml(); + } + return getApp().ml(); +} diff --git a/packages/ml/lib/modular/index.d.ts b/packages/ml/lib/modular/index.d.ts deleted file mode 100644 index ee65cb3b8c..0000000000 --- a/packages/ml/lib/modular/index.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ReactNativeFirebase } from '@react-native-firebase/app'; -import { FirebaseMLTypes } from '..'; - -type FirebaseML = FirebaseMLTypes.Module; -import FirebaseApp = ReactNativeFirebase.FirebaseApp; - -/** - * Returns the existing default {@link FirebaseML} instance that is associated with the - * default {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new - * instance with default settings. - * - * @returns The {@link FirebaseML} instance of the provided app. - */ -export declare function getML(app?: FirebaseApp): FirebaseML; diff --git a/packages/ml/lib/modular/index.js b/packages/ml/lib/modular/index.js deleted file mode 100644 index 8000bc832d..0000000000 --- a/packages/ml/lib/modular/index.js +++ /dev/null @@ -1,17 +0,0 @@ -import { getApp } from '@react-native-firebase/app'; - -/** - * @typedef {import('@firebase/app').FirebaseApp} FirebaseApp - * @typedef {import('..').FirebaseMLTypes.Module} FirebaseML - */ - -/** - * @param {FirebaseApp | undefined} app - * @returns {FirebaseML} - */ -export function getML(app) { - if (app) { - return getApp(app.name).ml(); - } - return getApp().ml(); -} diff --git a/packages/ml/lib/index.js b/packages/ml/lib/namespaced.ts similarity index 63% rename from packages/ml/lib/index.js rename to packages/ml/lib/namespaced.ts index e0da7630e9..efd2b5ddbc 100644 --- a/packages/ml/lib/index.js +++ b/packages/ml/lib/namespaced.ts @@ -20,9 +20,11 @@ import { FirebaseModule, getFirebaseRoot, } from '@react-native-firebase/app/dist/module/internal'; -import version from './version'; +import type { ReactNativeFirebase } from '@react-native-firebase/app'; +import { version } from './version'; +import type { ML, Statics } from './types/ml'; -const statics = {}; +const statics: Partial = {}; const namespace = 'ml'; @@ -30,14 +32,9 @@ const nativeModuleName = 'RNFBMLModule'; class FirebaseMLModule extends FirebaseModule {} -// import { SDK_VERSION } from '@react-native-firebase/ml'; export const SDK_VERSION = version; -export * from './modular'; - -// import ML from '@react-native-firebase/ml'; -// ml().X(...); -export default createModuleNamespace({ +const mlNamespace = createModuleNamespace({ statics, version, namespace, @@ -48,10 +45,17 @@ export default createModuleNamespace({ ModuleClass: FirebaseMLModule, }); -// import ml, { firebase } from '@react-native-firebase/ml'; -// ml().X(...); -// firebase.ml().X(...); -export const firebase = getFirebaseRoot(); +type MLNamespace = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp & { + firebase: ReactNativeFirebase.Module; + app(name?: string): ReactNativeFirebase.FirebaseApp; +}; + +export default mlNamespace as unknown as MLNamespace; -// e.g. -// // import { MLCloudTextRecognizerModelType } from '@react-native-firebase/ml'; +export const firebase = + getFirebaseRoot() as unknown as ReactNativeFirebase.FirebaseNamespacedExport< + 'ml', + ML, + Statics, + false + >; diff --git a/packages/ml/lib/types/ml.ts b/packages/ml/lib/types/ml.ts new file mode 100644 index 0000000000..5b70d92502 --- /dev/null +++ b/packages/ml/lib/types/ml.ts @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import type { ReactNativeFirebase } from '@react-native-firebase/app'; + +// ============ Module Interface ============ + +/** + * ML module instance - returned from firebase.ml() or firebase.app().ml() + * Note: Firebase ML Kit has no JavaScript SDK; types match RNFB native API. + */ +export interface ML extends ReactNativeFirebase.FirebaseModule { + /** The FirebaseApp this module is associated with */ + app: ReactNativeFirebase.FirebaseApp; +} + +// ============ Statics Interface ============ + +/** + * Static properties available on firebase.ml + */ +export interface Statics { + SDK_VERSION: string; +} + +/** + * FirebaseApp type with ml() method. + * @deprecated Import FirebaseApp from '@react-native-firebase/app' instead. + * The ml() method is added via module augmentation. + */ +export type FirebaseApp = ReactNativeFirebase.FirebaseApp; + +// ============ Module Augmentation ============ + +declare module '@react-native-firebase/app' { + namespace ReactNativeFirebase { + interface Module { + ml: FirebaseModuleWithStaticsAndApp; + } + interface FirebaseApp { + ml(): ML; + } + } +} + +// ============ Backwards Compatibility Namespace ============ + +type _Statics = Statics; + +/** + * @deprecated Use the exported types directly instead. + * FirebaseMLTypes namespace is kept for backwards compatibility. + */ +export namespace FirebaseMLTypes { + export type Module = ML; + export type Statics = _Statics; +} diff --git a/packages/ml/package.json b/packages/ml/package.json index 05d5b30f49..d09559141b 100644 --- a/packages/ml/package.json +++ b/packages/ml/package.json @@ -3,12 +3,13 @@ "version": "23.8.6", "author": "Invertase (http://invertase.io)", "description": "React Native Firebase - Firebase ML brings the power of machine learning vision to your React Native application, supporting both Android & iOS.", - "main": "lib/index.js", - "types": "lib/index.d.ts", + "main": "./dist/module/index.js", + "types": "./dist/typescript/lib/index.d.ts", "scripts": { - "build": "genversion --semi lib/version.js", + "build": "genversion --esm --semi lib/version.ts", "build:clean": "rimraf android/build && rimraf ios/build", - "prepare": "yarn run build" + "compile": "bob build", + "prepare": "yarn run build && yarn compile" }, "repository": { "type": "git", @@ -31,5 +32,26 @@ "publishConfig": { "access": "public", "provenance": true - } + }, + "devDependencies": { + "react-native-builder-bob": "^0.40.17", + "typescript": "^5.9.3" + }, + "exports": { + ".": { + "source": "./lib/index.ts", + "types": "./dist/typescript/lib/index.d.ts", + "default": "./dist/module/index.js" + }, + "./package.json": "./package.json" + }, + "react-native-builder-bob": { + "source": "lib", + "output": "dist", + "targets": [ + ["module", { "esm": true }], + ["typescript", { "tsc": "../../node_modules/.bin/tsc" }] + ] + }, + "eslintIgnore": ["node_modules/", "dist/"] } diff --git a/packages/ml/tsconfig.json b/packages/ml/tsconfig.json new file mode 100644 index 0000000000..cdb4ff75a8 --- /dev/null +++ b/packages/ml/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.packages.base.json", + "compilerOptions": { + "baseUrl": ".", + "rootDir": ".", + "moduleResolution": "node", + "paths": { + "@react-native-firebase/app": ["../app/dist/typescript/lib"], + "@react-native-firebase/app/dist/module/common": ["../app/dist/typescript/lib/common"], + "@react-native-firebase/app/dist/module/internal": ["../app/dist/typescript/lib/internal"] + } + }, + "include": ["lib/**/*"], + "exclude": ["node_modules", "dist", "__tests__", "**/*.test.ts"] +} diff --git a/tsconfig.json b/tsconfig.json index 0658ab77a9..0845adf4ea 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -29,8 +29,11 @@ "packages/in-app-messaging/lib/modular/index.d.ts", "packages/installations/lib/index.d.ts", "packages/installations/lib/modular/index.d.ts", - "packages/ml/lib/index.d.ts", - "packages/ml/lib/modular/index.d.ts", + "packages/ml/lib/index.ts", + "packages/ml/lib/modular.ts", + "packages/ml/lib/namespaced.ts", + "packages/ml/lib/version.ts", + "packages/ml/lib/types/ml.ts", "packages/perf/lib/index.d.ts", "packages/perf/lib/modular/index.d.ts", "packages/remote-config/lib/index.d.ts", From f0ad4302672c9ce93a5117d01dcd7326cb409f44 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Mon, 2 Mar 2026 12:49:55 +0000 Subject: [PATCH 02/13] chore: remove builder bob --- packages/ml/package.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/ml/package.json b/packages/ml/package.json index d09559141b..fe57b120b1 100644 --- a/packages/ml/package.json +++ b/packages/ml/package.json @@ -33,10 +33,6 @@ "access": "public", "provenance": true }, - "devDependencies": { - "react-native-builder-bob": "^0.40.17", - "typescript": "^5.9.3" - }, "exports": { ".": { "source": "./lib/index.ts", From ed3577d222e6cb5ccc4d87aade7671d7978e7512 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Mon, 2 Mar 2026 13:15:59 +0000 Subject: [PATCH 03/13] chore: dependencies --- packages/ml/package.json | 23 ++++++++++++++++++++--- yarn.lock | 3 +++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/ml/package.json b/packages/ml/package.json index fe57b120b1..7d1eb49324 100644 --- a/packages/ml/package.json +++ b/packages/ml/package.json @@ -33,6 +33,10 @@ "access": "public", "provenance": true }, + "devDependencies": { + "react-native-builder-bob": "^0.40.17", + "typescript": "^5.9.3" + }, "exports": { ".": { "source": "./lib/index.ts", @@ -45,9 +49,22 @@ "source": "lib", "output": "dist", "targets": [ - ["module", { "esm": true }], - ["typescript", { "tsc": "../../node_modules/.bin/tsc" }] + [ + "module", + { + "esm": true + } + ], + [ + "typescript", + { + "tsc": "../../node_modules/.bin/tsc" + } + ] ] }, - "eslintIgnore": ["node_modules/", "dist/"] + "eslintIgnore": [ + "node_modules/", + "dist/" + ] } diff --git a/yarn.lock b/yarn.lock index e4be9a3184..3b8611de78 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5927,6 +5927,9 @@ __metadata: "@react-native-firebase/ml@npm:23.8.6, @react-native-firebase/ml@workspace:packages/ml": version: 0.0.0-use.local resolution: "@react-native-firebase/ml@workspace:packages/ml" + dependencies: + react-native-builder-bob: "npm:^0.40.17" + typescript: "npm:^5.9.3" peerDependencies: "@react-native-firebase/app": 23.8.6 languageName: unknown From d729cef9ab1bfa257baf34ff2a14539c35e7285c Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Mon, 2 Mar 2026 15:39:00 +0000 Subject: [PATCH 04/13] chore: fix tsconfig --- packages/ml/lib/types/ml.ts | 4 ++++ tsconfig.json | 10 ++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/ml/lib/types/ml.ts b/packages/ml/lib/types/ml.ts index 5b70d92502..3c897580ac 100644 --- a/packages/ml/lib/types/ml.ts +++ b/packages/ml/lib/types/ml.ts @@ -46,6 +46,7 @@ export type FirebaseApp = ReactNativeFirebase.FirebaseApp; // ============ Module Augmentation ============ +/* eslint-disable @typescript-eslint/no-namespace */ declare module '@react-native-firebase/app' { namespace ReactNativeFirebase { interface Module { @@ -56,6 +57,7 @@ declare module '@react-native-firebase/app' { } } } +/* eslint-enable @typescript-eslint/no-namespace */ // ============ Backwards Compatibility Namespace ============ @@ -65,7 +67,9 @@ type _Statics = Statics; * @deprecated Use the exported types directly instead. * FirebaseMLTypes namespace is kept for backwards compatibility. */ +/* eslint-disable @typescript-eslint/no-namespace */ export namespace FirebaseMLTypes { export type Module = ML; export type Statics = _Statics; } +/* eslint-enable @typescript-eslint/no-namespace */ diff --git a/tsconfig.json b/tsconfig.json index 0845adf4ea..9dcfb66513 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -31,9 +31,6 @@ "packages/installations/lib/modular/index.d.ts", "packages/ml/lib/index.ts", "packages/ml/lib/modular.ts", - "packages/ml/lib/namespaced.ts", - "packages/ml/lib/version.ts", - "packages/ml/lib/types/ml.ts", "packages/perf/lib/index.d.ts", "packages/perf/lib/modular/index.d.ts", "packages/remote-config/lib/index.d.ts", @@ -79,7 +76,12 @@ "lib": ["es2015", "es2016", "esnext", "dom"], "types": ["react-native", "node"], "paths": { - "@react-native-firebase/*": ["./packages/*/lib/index.d.ts"] + "@react-native-firebase/*": ["./packages/*/lib/index"], + "@react-native-firebase/app/dist/module/common/*": ["./packages/app/lib/common/*"], + "@react-native-firebase/app/dist/module/common": ["./packages/app/lib/common"], + "@react-native-firebase/app/dist/module/internal/web/*": ["./packages/app/lib/internal/web/*"], + "@react-native-firebase/app/dist/module/internal/*": ["./packages/app/lib/internal/*"], + "@react-native-firebase/app/dist/module/internal": ["./packages/app/lib/internal"] } }, "exclude": ["node_modules", "**/*.spec.ts", "packages/**/dist"] From a3883749fbafa12fd19ef92f7928bdbbd9bf0cf3 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Wed, 4 Mar 2026 10:44:15 +0000 Subject: [PATCH 05/13] refactor: split ml types into public and namespaced --- packages/ml/lib/index.ts | 6 ++-- packages/ml/lib/types/ml.ts | 40 ++------------------- packages/ml/lib/types/namespaced.ts | 54 +++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 40 deletions(-) create mode 100644 packages/ml/lib/types/namespaced.ts diff --git a/packages/ml/lib/index.ts b/packages/ml/lib/index.ts index dad7158212..9a06aed647 100644 --- a/packages/ml/lib/index.ts +++ b/packages/ml/lib/index.ts @@ -15,9 +15,9 @@ * */ -// Export types from types/ml -export type { ML, Statics, FirebaseApp } from './types/ml'; -export type { FirebaseMLTypes } from './types/ml'; +// Export types from types/ml (public/modular API; Statics re-exported via modular) +export type { ML, FirebaseApp } from './types/ml'; +export type { FirebaseMLTypes } from './types/namespaced'; // Export modular API functions export * from './modular'; diff --git a/packages/ml/lib/types/ml.ts b/packages/ml/lib/types/ml.ts index 3c897580ac..52c9ee9be7 100644 --- a/packages/ml/lib/types/ml.ts +++ b/packages/ml/lib/types/ml.ts @@ -17,22 +17,19 @@ import type { ReactNativeFirebase } from '@react-native-firebase/app'; -// ============ Module Interface ============ +// ============ Module Interface (public/modular API) ============ /** - * ML module instance - returned from firebase.ml() or firebase.app().ml() + * ML module instance - returned from firebase.ml() or getML(). * Note: Firebase ML Kit has no JavaScript SDK; types match RNFB native API. */ -export interface ML extends ReactNativeFirebase.FirebaseModule { +export interface ML { /** The FirebaseApp this module is associated with */ app: ReactNativeFirebase.FirebaseApp; } // ============ Statics Interface ============ -/** - * Static properties available on firebase.ml - */ export interface Statics { SDK_VERSION: string; } @@ -40,36 +37,5 @@ export interface Statics { /** * FirebaseApp type with ml() method. * @deprecated Import FirebaseApp from '@react-native-firebase/app' instead. - * The ml() method is added via module augmentation. */ export type FirebaseApp = ReactNativeFirebase.FirebaseApp; - -// ============ Module Augmentation ============ - -/* eslint-disable @typescript-eslint/no-namespace */ -declare module '@react-native-firebase/app' { - namespace ReactNativeFirebase { - interface Module { - ml: FirebaseModuleWithStaticsAndApp; - } - interface FirebaseApp { - ml(): ML; - } - } -} -/* eslint-enable @typescript-eslint/no-namespace */ - -// ============ Backwards Compatibility Namespace ============ - -type _Statics = Statics; - -/** - * @deprecated Use the exported types directly instead. - * FirebaseMLTypes namespace is kept for backwards compatibility. - */ -/* eslint-disable @typescript-eslint/no-namespace */ -export namespace FirebaseMLTypes { - export type Module = ML; - export type Statics = _Statics; -} -/* eslint-enable @typescript-eslint/no-namespace */ diff --git a/packages/ml/lib/types/namespaced.ts b/packages/ml/lib/types/namespaced.ts new file mode 100644 index 0000000000..95269de46d --- /dev/null +++ b/packages/ml/lib/types/namespaced.ts @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import type { ReactNativeFirebase } from '@react-native-firebase/app'; + +type FirebaseModule = ReactNativeFirebase.FirebaseModule; + +/** + * @deprecated Use the exported types directly instead. + * FirebaseMLTypes namespace is kept for backwards compatibility. + */ +/* eslint-disable @typescript-eslint/no-namespace */ +export namespace FirebaseMLTypes { + export interface Statics { + SDK_VERSION: string; + } + + export interface Module extends FirebaseModule { + /** @deprecated Use the modular API instead. */ + app: ReactNativeFirebase.FirebaseApp; + } +} +/* eslint-enable @typescript-eslint/no-namespace */ + +/* eslint-disable @typescript-eslint/no-namespace */ +declare module '@react-native-firebase/app' { + namespace ReactNativeFirebase { + import FirebaseModuleWithStaticsAndApp = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp; + interface Module { + ml: FirebaseModuleWithStaticsAndApp< + FirebaseMLTypes.Module, + FirebaseMLTypes.Statics + >; + } + interface FirebaseApp { + ml(): FirebaseMLTypes.Module; + } + } +} +/* eslint-enable @typescript-eslint/no-namespace */ From fbf793b26a6f79ec254e469682e6cc0775119b14 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Wed, 4 Mar 2026 10:48:06 +0000 Subject: [PATCH 06/13] feat: add ml types/internal with native module augmentation --- packages/ml/lib/types/internal.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 packages/ml/lib/types/internal.ts diff --git a/packages/ml/lib/types/internal.ts b/packages/ml/lib/types/internal.ts new file mode 100644 index 0000000000..dd08289ffc --- /dev/null +++ b/packages/ml/lib/types/internal.ts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * Wrapped native module interface for ML. + * ML Kit module exposes no instance methods beyond the base FirebaseModule. + */ +export interface RNFBMLModule { + // No additional methods; ML uses base FirebaseModule only. +} + +declare module '@react-native-firebase/app/dist/module/internal/NativeModules' { + interface ReactNativeFirebaseNativeModules { + RNFBMLModule: RNFBMLModule; + } +} From 9e1e00656798e240b50a2bf15c7f10906da53086 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Wed, 4 Mar 2026 10:50:41 +0000 Subject: [PATCH 07/13] refactor: use ml namespaced types and extend FirebaseModule --- packages/ml/lib/namespaced.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/ml/lib/namespaced.ts b/packages/ml/lib/namespaced.ts index efd2b5ddbc..bb6d9e0b38 100644 --- a/packages/ml/lib/namespaced.ts +++ b/packages/ml/lib/namespaced.ts @@ -22,15 +22,17 @@ import { } from '@react-native-firebase/app/dist/module/internal'; import type { ReactNativeFirebase } from '@react-native-firebase/app'; import { version } from './version'; -import type { ML, Statics } from './types/ml'; +import type { FirebaseMLTypes } from './types/namespaced'; -const statics: Partial = {}; +const statics: FirebaseMLTypes.Statics = { + SDK_VERSION: version, +}; const namespace = 'ml'; -const nativeModuleName = 'RNFBMLModule'; +const nativeModuleName = 'RNFBMLModule' as const; -class FirebaseMLModule extends FirebaseModule {} +class FirebaseMLModule extends FirebaseModule {} export const SDK_VERSION = version; @@ -45,7 +47,10 @@ const mlNamespace = createModuleNamespace({ ModuleClass: FirebaseMLModule, }); -type MLNamespace = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp & { +type MLNamespace = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< + FirebaseMLTypes.Module, + FirebaseMLTypes.Statics +> & { firebase: ReactNativeFirebase.Module; app(name?: string): ReactNativeFirebase.FirebaseApp; }; @@ -55,7 +60,7 @@ export default mlNamespace as unknown as MLNamespace; export const firebase = getFirebaseRoot() as unknown as ReactNativeFirebase.FirebaseNamespacedExport< 'ml', - ML, - Statics, + FirebaseMLTypes.Module, + FirebaseMLTypes.Statics, false >; From 173135e35e1972dc21572764eb097f8560135f34 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Wed, 4 Mar 2026 11:09:02 +0000 Subject: [PATCH 08/13] refactor: export Statics from ml modular and cast getML return --- packages/ml/lib/modular.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/ml/lib/modular.ts b/packages/ml/lib/modular.ts index 717f403186..ecfa7ae868 100644 --- a/packages/ml/lib/modular.ts +++ b/packages/ml/lib/modular.ts @@ -19,6 +19,8 @@ import { getApp } from '@react-native-firebase/app'; import type { FirebaseApp } from '@react-native-firebase/app'; import type { ML } from './types/ml'; +export type { Statics } from './types/ml'; + /** * Returns the existing default {@link ML} instance that is associated with the * default {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new @@ -29,7 +31,7 @@ import type { ML } from './types/ml'; */ export function getML(app?: FirebaseApp): ML { if (app) { - return getApp(app.name).ml(); + return getApp(app.name).ml() as ML; } - return getApp().ml(); + return getApp().ml() as ML; } From 9ddd428be33ae986cd99f4cfd6d76024503da250 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Wed, 4 Mar 2026 11:10:41 +0000 Subject: [PATCH 09/13] chore: align ml type-test with namespaced cast and tsconfig to type-test only --- packages/ml/type-test.ts | 4 ++-- tsconfig.json | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/ml/type-test.ts b/packages/ml/type-test.ts index 2ea028badb..1ca4c95e82 100644 --- a/packages/ml/type-test.ts +++ b/packages/ml/type-test.ts @@ -1,4 +1,4 @@ -import ml, { firebase, getML } from '.'; +import ml, { firebase, FirebaseMLTypes, getML } from '.'; console.log(ml().app); @@ -24,7 +24,7 @@ console.log(firebase.ml(firebase.app()).app.name); console.log(ml(firebase.app()).app.name); // checks Module instance APIs -const mlInstance = firebase.ml(); +const mlInstance = firebase.ml() as unknown as FirebaseMLTypes.Module; console.log(mlInstance.app.name); // checks modular API functions diff --git a/tsconfig.json b/tsconfig.json index 9dcfb66513..8adcc2e90b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -29,8 +29,6 @@ "packages/in-app-messaging/lib/modular/index.d.ts", "packages/installations/lib/index.d.ts", "packages/installations/lib/modular/index.d.ts", - "packages/ml/lib/index.ts", - "packages/ml/lib/modular.ts", "packages/perf/lib/index.d.ts", "packages/perf/lib/modular/index.d.ts", "packages/remote-config/lib/index.d.ts", From e509fa683701e10817c814bdf52caed3425d92e8 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Wed, 4 Mar 2026 14:58:30 +0000 Subject: [PATCH 10/13] fix: add internal/* path so NativeModules augmentation resolves in tsconfig --- packages/ml/tsconfig.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/ml/tsconfig.json b/packages/ml/tsconfig.json index cdb4ff75a8..63fffa55fc 100644 --- a/packages/ml/tsconfig.json +++ b/packages/ml/tsconfig.json @@ -7,7 +7,10 @@ "paths": { "@react-native-firebase/app": ["../app/dist/typescript/lib"], "@react-native-firebase/app/dist/module/common": ["../app/dist/typescript/lib/common"], - "@react-native-firebase/app/dist/module/internal": ["../app/dist/typescript/lib/internal"] + "@react-native-firebase/app/dist/module/internal": ["../app/dist/typescript/lib/internal"], + "@react-native-firebase/app/dist/module/internal/*": [ + "../app/dist/typescript/lib/internal/*" + ] } }, "include": ["lib/**/*"], From 7297a8a30d91b41cee81dfbba670aab0da90ec5a Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Wed, 4 Mar 2026 15:38:35 +0000 Subject: [PATCH 11/13] format: js format --- packages/ml/lib/types/namespaced.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/ml/lib/types/namespaced.ts b/packages/ml/lib/types/namespaced.ts index 95269de46d..e98e9e1dc7 100644 --- a/packages/ml/lib/types/namespaced.ts +++ b/packages/ml/lib/types/namespaced.ts @@ -41,10 +41,7 @@ declare module '@react-native-firebase/app' { namespace ReactNativeFirebase { import FirebaseModuleWithStaticsAndApp = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp; interface Module { - ml: FirebaseModuleWithStaticsAndApp< - FirebaseMLTypes.Module, - FirebaseMLTypes.Statics - >; + ml: FirebaseModuleWithStaticsAndApp; } interface FirebaseApp { ml(): FirebaseMLTypes.Module; From b76cb1a2c22d9fcb9be99bc3d7b47fd28313a8e0 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Wed, 4 Mar 2026 15:46:41 +0000 Subject: [PATCH 12/13] fix: ensure type exposure for jest --- packages/ml/lib/namespaced.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ml/lib/namespaced.ts b/packages/ml/lib/namespaced.ts index bb6d9e0b38..ac9b6625f9 100644 --- a/packages/ml/lib/namespaced.ts +++ b/packages/ml/lib/namespaced.ts @@ -23,6 +23,7 @@ import { import type { ReactNativeFirebase } from '@react-native-firebase/app'; import { version } from './version'; import type { FirebaseMLTypes } from './types/namespaced'; +import './types/internal'; const statics: FirebaseMLTypes.Statics = { SDK_VERSION: version, From a39901dbcebfe272e3021fb1759672050da88f5b Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Wed, 4 Mar 2026 15:53:18 +0000 Subject: [PATCH 13/13] chore: ignore disable empty object --- packages/ml/lib/types/internal.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ml/lib/types/internal.ts b/packages/ml/lib/types/internal.ts index dd08289ffc..62bb14154b 100644 --- a/packages/ml/lib/types/internal.ts +++ b/packages/ml/lib/types/internal.ts @@ -19,6 +19,7 @@ * Wrapped native module interface for ML. * ML Kit module exposes no instance methods beyond the base FirebaseModule. */ +// eslint-disable-next-line @typescript-eslint/no-empty-object-type export interface RNFBMLModule { // No additional methods; ML uses base FirebaseModule only. }