From 220f8ef1e0a0b9ceb84bbd8c4a380c257b720c7d Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Tue, 16 Dec 2025 15:08:05 +0000 Subject: [PATCH 1/8] refactor(app-distrbution): App-Distribution migration to typescript --- packages/app-distribution/lib/index.ts | 26 +++++++ packages/app-distribution/lib/modular.ts | 78 +++++++++++++++++++ .../app-distribution/lib/modular/index.d.ts | 39 ---------- .../app-distribution/lib/modular/index.js | 50 ------------ .../lib/{index.js => namespaced.ts} | 22 +++--- .../lib/{index.d.ts => types.d.ts} | 24 ++++++ packages/app-distribution/package.json | 6 +- 7 files changed, 141 insertions(+), 104 deletions(-) create mode 100644 packages/app-distribution/lib/index.ts create mode 100644 packages/app-distribution/lib/modular.ts delete mode 100644 packages/app-distribution/lib/modular/index.d.ts delete mode 100644 packages/app-distribution/lib/modular/index.js rename packages/app-distribution/lib/{index.js => namespaced.ts} (74%) rename packages/app-distribution/lib/{index.d.ts => types.d.ts} (87%) diff --git a/packages/app-distribution/lib/index.ts b/packages/app-distribution/lib/index.ts new file mode 100644 index 0000000000..d33e3e4007 --- /dev/null +++ b/packages/app-distribution/lib/index.ts @@ -0,0 +1,26 @@ +/* + * 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.d.ts +export type { FirebaseAppDistributionTypes } from './types.d'; + +// Export modular API functions +export * from './modular'; + +// Export namespaced API +export * from './namespaced'; +export { default } from './namespaced'; diff --git a/packages/app-distribution/lib/modular.ts b/packages/app-distribution/lib/modular.ts new file mode 100644 index 0000000000..8c6b241adf --- /dev/null +++ b/packages/app-distribution/lib/modular.ts @@ -0,0 +1,78 @@ +/* + * 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 { MODULAR_DEPRECATION_ARG } from '@react-native-firebase/app/lib/common'; +import type { FirebaseApp } from '@react-native-firebase/app'; +import type { FirebaseAppDistributionTypes } from './types.d'; + +export type FirebaseAppDistribution = FirebaseAppDistributionTypes.Module; +export type AppDistributionRelease = FirebaseAppDistributionTypes.AppDistributionRelease; + +/** + * Get an App Distribution instance for the specified app or current app. + * @param app - The FirebaseApp to use. Optional. + * @returns FirebaseAppDistribution instance for the given app. + */ +export function getAppDistribution(app?: FirebaseApp): FirebaseAppDistribution { + if (app) { + return (getApp(app.name) as any).appDistribution(); + } + return (getApp() as any).appDistribution(); +} + +/** + * Returns true if the App Distribution tester is signed in. + * If not an iOS device, it always rejects, as neither false nor true seem like a sensible default. + * @param appDistribution - FirebaseAppDistribution instance. + * @returns Promise - Whether the tester is signed in. + */ +export function isTesterSignedIn(appDistribution: FirebaseAppDistribution): Promise { + return appDistribution.isTesterSignedIn.call(appDistribution, MODULAR_DEPRECATION_ARG); +} + +/** + * Sign-in the App Distribution tester. + * If not an iOS device, it always rejects, as no defaults seem sensible. + * @param appDistribution - FirebaseAppDistribution instance. + * @returns Promise + */ +export function signInTester(appDistribution: FirebaseAppDistribution): Promise { + return appDistribution.signInTester.call(appDistribution, MODULAR_DEPRECATION_ARG); +} + +/** + * Check to see whether a new distribution is available. + * If not an iOS device, it always rejects, as no default response seems sensible. + * @param appDistribution - FirebaseAppDistribution instance. + * @returns Promise - Information about the available release. + */ +export function checkForUpdate( + appDistribution: FirebaseAppDistribution, +): Promise { + return appDistribution.checkForUpdate.call(appDistribution, MODULAR_DEPRECATION_ARG); +} + +/** + * Sign out App Distribution tester. + * If not an iOS device, it always rejects, as no default response seems sensible. + * @param appDistribution - FirebaseAppDistribution instance. + * @returns Promise + */ +export function signOutTester(appDistribution: FirebaseAppDistribution): Promise { + return appDistribution.signOutTester.call(appDistribution, MODULAR_DEPRECATION_ARG); +} diff --git a/packages/app-distribution/lib/modular/index.d.ts b/packages/app-distribution/lib/modular/index.d.ts deleted file mode 100644 index 1d2a4f8495..0000000000 --- a/packages/app-distribution/lib/modular/index.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ReactNativeFirebase } from '@react-native-firebase/app'; -import { FirebaseAppDistributionTypes } from '..'; - -export type FirebaseAppDistribution = FirebaseAppDistributionTypes.Module; - -/** - * Get an App Distribution instance for the specified app or current app. - */ -export declare function getAppDistribution( - app?: ReactNativeFirebase.FirebaseApp, -): FirebaseAppDistribution; - -/** - * Returns true if the App Distribution tester is signed in. - * If not an iOS device, it always rejects, as neither false nor true seem like a sensible default. - */ -export declare function isTesterSignedIn( - appDistribution: FirebaseAppDistribution, -): Promise; - -/** - * Sign-in the App Distribution tester - * If not an iOS device, it always rejects, as no defaults seem sensible. - */ -export declare function signInTester(appDistribution: FirebaseAppDistribution): Promise; - -/** - * Check to see whether a new distribution is available - * If not an iOS device, it always rejects, as no default response seems sensible. - */ -export declare function checkForUpdate( - appDistribution: FirebaseAppDistribution, -): Promise; - -/** - * Sign out App Distribution tester - * If not an iOS device, it always rejects, as no default response seems sensible. - */ -export declare function signOutTester(appDistribution: FirebaseAppDistribution): Promise; diff --git a/packages/app-distribution/lib/modular/index.js b/packages/app-distribution/lib/modular/index.js deleted file mode 100644 index f8f36b8923..0000000000 --- a/packages/app-distribution/lib/modular/index.js +++ /dev/null @@ -1,50 +0,0 @@ -import { getApp } from '@react-native-firebase/app'; -import { MODULAR_DEPRECATION_ARG } from '@react-native-firebase/app/lib/common'; -/** - * @typedef {import("..").FirebaseApp} FirebaseApp - * @typedef {import("..").FirebaseAppDistributionTypes.AppDistributionRelease} AppDistributionRelease - * @typedef {import("..").FirebaseAppDistributionTypes.Module} FirebaseAppDistribution - */ - -/** - * @param {FirebaseApp | undefined} app - * @returns {FirebaseAppDistribution} - */ -export function getAppDistribution(app) { - if (app) { - return getApp(app.name).appDistribution(app); - } - return getApp().appDistribution(); -} - -/** - * @param {FirebaseAppDistribution} appDistribution - * @returns {Promise} - */ -export function isTesterSignedIn(appDistribution) { - return appDistribution.isTesterSignedIn.call(appDistribution, MODULAR_DEPRECATION_ARG); -} - -/** - * @param {FirebaseAppDistribution} appDistribution - * @returns {Promise} - */ -export function signInTester(appDistribution) { - return appDistribution.signInTester.call(appDistribution, MODULAR_DEPRECATION_ARG); -} - -/** - * @param {FirebaseAppDistribution} appDistribution - * @returns {AppDistributionRelease>} - */ -export function checkForUpdate(appDistribution) { - return appDistribution.checkForUpdate.call(appDistribution, MODULAR_DEPRECATION_ARG); -} - -/** - * @param {FirebaseAppDistribution} appDistribution - * @returns {Promise} - */ -export function signOutTester(appDistribution) { - return appDistribution.signOutTester.call(appDistribution, MODULAR_DEPRECATION_ARG); -} diff --git a/packages/app-distribution/lib/index.js b/packages/app-distribution/lib/namespaced.ts similarity index 74% rename from packages/app-distribution/lib/index.js rename to packages/app-distribution/lib/namespaced.ts index 538142f1c1..de7fb39df5 100644 --- a/packages/app-distribution/lib/index.js +++ b/packages/app-distribution/lib/namespaced.ts @@ -21,8 +21,8 @@ import { FirebaseModule, getFirebaseRoot, } from '@react-native-firebase/app/lib/internal'; - -import version from './version'; +import { version } from './version'; +import type { FirebaseAppDistributionTypes } from './types.d'; const statics = {}; @@ -31,41 +31,39 @@ const namespace = 'appDistribution'; const nativeModuleName = 'RNFBAppDistributionModule'; class FirebaseAppDistributionModule extends FirebaseModule { - isTesterSignedIn() { + isTesterSignedIn(): Promise { if (isIOS) { return this.native.isTesterSignedIn(); } - Promise.reject(new Error('App Distribution is not supported on this platform.')); + return Promise.reject(new Error('App Distribution is not supported on this platform.')); } - signInTester() { + signInTester(): Promise { if (isIOS) { return this.native.signInTester(); } - Promise.reject(new Error('App Distribution is not supported on this platform.')); + return Promise.reject(new Error('App Distribution is not supported on this platform.')); } - checkForUpdate() { + checkForUpdate(): Promise { if (isIOS) { return this.native.checkForUpdate(); } - Promise.reject(new Error('App Distribution is not supported on this platform.')); + return Promise.reject(new Error('App Distribution is not supported on this platform.')); } - signOutTester() { + signOutTester(): Promise { if (isIOS) { return this.native.signOutTester(); } - Promise.reject(new Error('App Distribution is not supported on this platform.')); + return Promise.reject(new Error('App Distribution is not supported on this platform.')); } } -export * from './modular'; - // import { SDK_VERSION } from '@react-native-firebase/app-distribution'; export const SDK_VERSION = version; diff --git a/packages/app-distribution/lib/index.d.ts b/packages/app-distribution/lib/types.d.ts similarity index 87% rename from packages/app-distribution/lib/index.d.ts rename to packages/app-distribution/lib/types.d.ts index 1f9a323186..23dc33c17a 100644 --- a/packages/app-distribution/lib/index.d.ts +++ b/packages/app-distribution/lib/types.d.ts @@ -161,6 +161,30 @@ declare module '@react-native-firebase/app' { } interface FirebaseApp { appDistribution(): FirebaseAppDistributionTypes.Module; + readonly name: string; } } + + export function getApp(appName?: string): ReactNativeFirebase.FirebaseApp; +} + +declare module '@react-native-firebase/app/lib/common' { + export const MODULAR_DEPRECATION_ARG: string; + export const isIOS: boolean; +} + +declare module '@react-native-firebase/app/lib/internal' { + export function createModuleNamespace(config: any): any; + export class FirebaseModule { + constructor(...args: any[]); + native: any; + app: any; + firebaseJson: any; + _customUrlOrRegion: string | null; + } + export function getFirebaseRoot(): any; +} + +declare module './version' { + export const version: string; } diff --git a/packages/app-distribution/package.json b/packages/app-distribution/package.json index b383d99eec..1fa08b6401 100644 --- a/packages/app-distribution/package.json +++ b/packages/app-distribution/package.json @@ -3,10 +3,10 @@ "version": "23.7.0", "author": "Invertase (http://invertase.io)", "description": "React Native Firebase - App Distribution", - "main": "lib/index.js", - "types": "lib/index.d.ts", + "main": "lib/index.ts", + "types": "lib/types.d.ts", "scripts": { - "build": "genversion --semi lib/version.js", + "build": "genversion --esm --semi lib/version.ts", "build:clean": "rimraf android/build && rimraf ios/build", "build:plugin": "rimraf plugin/build && tsc --build plugin", "lint:plugin": "eslint plugin/src/*", From 86ac6d422dd110bc133591adf5dbd519c4fe1dc1 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Tue, 16 Dec 2025 15:14:04 +0000 Subject: [PATCH 2/8] fix: tests and types --- .../__tests__/app-distribution.test.ts | 37 ++++++++- packages/app-distribution/lib/index.ts | 7 ++ packages/app-distribution/lib/modular.ts | 10 +-- .../lib/types/app-distribution.ts | 79 +++++++++++++++++++ 4 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 packages/app-distribution/lib/types/app-distribution.ts diff --git a/packages/app-distribution/__tests__/app-distribution.test.ts b/packages/app-distribution/__tests__/app-distribution.test.ts index 43d817aa8e..65b33ca184 100644 --- a/packages/app-distribution/__tests__/app-distribution.test.ts +++ b/packages/app-distribution/__tests__/app-distribution.test.ts @@ -7,11 +7,14 @@ import { signInTester, checkForUpdate, signOutTester, + type FirebaseAppDistribution, + type AppDistributionRelease, + type FirebaseApp, } from '../lib'; import { createCheckV9Deprecation, - CheckV9DeprecationFunction, + type CheckV9DeprecationFunction, } from '../../app/lib/common/unitTestUtils'; // @ts-ignore test @@ -64,6 +67,38 @@ describe('appDistribution()', function () { it('`signOutTester` function is properly exposed to end user', function () { expect(signOutTester).toBeDefined(); }); + + describe('types', function () { + it('`FirebaseAppDistribution` type is properly exposed to end user', function () { + const appDistribution: FirebaseAppDistribution = ( + firebase.app() as unknown as FirebaseApp + ).appDistribution(); + expect(appDistribution).toBeDefined(); + expect(appDistribution.isTesterSignedIn).toBeDefined(); + expect(appDistribution.signInTester).toBeDefined(); + expect(appDistribution.checkForUpdate).toBeDefined(); + expect(appDistribution.signOutTester).toBeDefined(); + }); + + it('`AppDistributionRelease` type is properly exposed to end user', function () { + // Type check - this will fail at compile time if type is not exported + const release: AppDistributionRelease = { + displayVersion: '1.0.0', + buildVersion: '123', + releaseNotes: 'Test release notes', + downloadURL: 'https://example.com/download', + isExpired: false, + }; + expect(release).toBeDefined(); + expect(release.displayVersion).toBe('1.0.0'); + }); + + it('`FirebaseApp` type is properly exposed to end user', function () { + const app = firebase.app() as unknown as FirebaseApp; + expect(app).toBeDefined(); + expect(app.appDistribution).toBeDefined(); + }); + }); }); describe('test `console.warn` is called for RNFB v8 API & not called for v9 API', function () { diff --git a/packages/app-distribution/lib/index.ts b/packages/app-distribution/lib/index.ts index d33e3e4007..3705868f96 100644 --- a/packages/app-distribution/lib/index.ts +++ b/packages/app-distribution/lib/index.ts @@ -15,6 +15,13 @@ * */ +// Export types from types/app-distribution +export type { + AppDistributionRelease, + FirebaseAppDistribution, + FirebaseApp, +} from './types/app-distribution'; + // Export types from types.d.ts export type { FirebaseAppDistributionTypes } from './types.d'; diff --git a/packages/app-distribution/lib/modular.ts b/packages/app-distribution/lib/modular.ts index 8c6b241adf..1bbc188bb8 100644 --- a/packages/app-distribution/lib/modular.ts +++ b/packages/app-distribution/lib/modular.ts @@ -17,11 +17,11 @@ import { getApp } from '@react-native-firebase/app'; import { MODULAR_DEPRECATION_ARG } from '@react-native-firebase/app/lib/common'; -import type { FirebaseApp } from '@react-native-firebase/app'; -import type { FirebaseAppDistributionTypes } from './types.d'; - -export type FirebaseAppDistribution = FirebaseAppDistributionTypes.Module; -export type AppDistributionRelease = FirebaseAppDistributionTypes.AppDistributionRelease; +import type { + FirebaseAppDistribution, + AppDistributionRelease, + FirebaseApp, +} from './types/app-distribution'; /** * Get an App Distribution instance for the specified app or current app. diff --git a/packages/app-distribution/lib/types/app-distribution.ts b/packages/app-distribution/lib/types/app-distribution.ts new file mode 100644 index 0000000000..666a091bc6 --- /dev/null +++ b/packages/app-distribution/lib/types/app-distribution.ts @@ -0,0 +1,79 @@ +/* + * 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'; + +/** + * The release information returned by the update check when a new version is available. + */ +export interface AppDistributionRelease { + /** + * The short bundle version of this build (example 1.0.0). + */ + displayVersion: string; + + /** + * The build number of this build (example: 123). + */ + buildVersion: string; + + /** + * The release notes for this build, possibly null if no release notes were provided. + */ + releaseNotes: string | null; + + /** + * The URL for the build. + */ + downloadURL: string; + + /** + * Whether the download URL for this release is expired. + */ + isExpired: boolean; +} + +export interface FirebaseAppDistributionModule { + /** + * Returns true if the App Distribution tester is signed in. + * If not an iOS device, it always rejects, as neither false nor true seem like a sensible default. + */ + isTesterSignedIn(): Promise; + + /** + * Sign-in the App Distribution tester + * If not an iOS device, it always rejects, as no defaults seem sensible. + */ + signInTester(): Promise; + + /** + * Check to see whether a new distribution is available + * If not an iOS device, it always rejects, as no default response seems sensible. + */ + checkForUpdate(): Promise; + + /** + * Sign out App Distribution tester + * If not an iOS device, it always rejects, as no default response seems sensible. + */ + signOutTester(): Promise; +} + +export type FirebaseAppDistribution = FirebaseAppDistributionModule; +export type FirebaseApp = ReactNativeFirebase.FirebaseApp & { + appDistribution(): FirebaseAppDistribution; +}; From 12c26d40fd5bf9a761ea43e0656db9648d3fd5c9 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Tue, 16 Dec 2025 15:31:09 +0000 Subject: [PATCH 3/8] fix: types --- packages/app-distribution/lib/namespaced.ts | 10 ++++++---- packages/app-distribution/lib/types.d.ts | 8 ++++---- .../app-distribution/lib/types/app-distribution.ts | 8 ++++---- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/app-distribution/lib/namespaced.ts b/packages/app-distribution/lib/namespaced.ts index de7fb39df5..88a6af38f3 100644 --- a/packages/app-distribution/lib/namespaced.ts +++ b/packages/app-distribution/lib/namespaced.ts @@ -31,7 +31,7 @@ const namespace = 'appDistribution'; const nativeModuleName = 'RNFBAppDistributionModule'; class FirebaseAppDistributionModule extends FirebaseModule { - isTesterSignedIn(): Promise { + isTesterSignedIn(_modularDeprecationArg?: any): Promise { if (isIOS) { return this.native.isTesterSignedIn(); } @@ -39,7 +39,7 @@ class FirebaseAppDistributionModule extends FirebaseModule { return Promise.reject(new Error('App Distribution is not supported on this platform.')); } - signInTester(): Promise { + signInTester(_modularDeprecationArg?: any): Promise { if (isIOS) { return this.native.signInTester(); } @@ -47,7 +47,9 @@ class FirebaseAppDistributionModule extends FirebaseModule { return Promise.reject(new Error('App Distribution is not supported on this platform.')); } - checkForUpdate(): Promise { + checkForUpdate( + _modularDeprecationArg?: any, + ): Promise { if (isIOS) { return this.native.checkForUpdate(); } @@ -55,7 +57,7 @@ class FirebaseAppDistributionModule extends FirebaseModule { return Promise.reject(new Error('App Distribution is not supported on this platform.')); } - signOutTester(): Promise { + signOutTester(_modularDeprecationArg?: any): Promise { if (isIOS) { return this.native.signOutTester(); } diff --git a/packages/app-distribution/lib/types.d.ts b/packages/app-distribution/lib/types.d.ts index 23dc33c17a..b248a1245e 100644 --- a/packages/app-distribution/lib/types.d.ts +++ b/packages/app-distribution/lib/types.d.ts @@ -109,25 +109,25 @@ export namespace FirebaseAppDistributionTypes { * Returns true if the App Distribution tester is signed in. * If not an iOS device, it always rejects, as neither false nor true seem like a sensible default. */ - isTesterSignedIn(): Promise; + isTesterSignedIn(_modularDeprecationArg?: any): Promise; /** * Sign-in the App Distribution tester * If not an iOS device, it always rejects, as no defaults seem sensible. */ - signInTester(): Promise; + signInTester(_modularDeprecationArg?: any): Promise; /** * Check to see whether a new distribution is available * If not an iOS device, it always rejects, as no default response seems sensible. */ - checkForUpdate(): Promise; + checkForUpdate(_modularDeprecationArg?: any): Promise; /** * Sign out App Distribution tester * If not an iOS device, it always rejects, as no default response seems sensible. */ - signOutTester(): Promise; + signOutTester(_modularDeprecationArg?: any): Promise; } } diff --git a/packages/app-distribution/lib/types/app-distribution.ts b/packages/app-distribution/lib/types/app-distribution.ts index 666a091bc6..f64b3db61d 100644 --- a/packages/app-distribution/lib/types/app-distribution.ts +++ b/packages/app-distribution/lib/types/app-distribution.ts @@ -52,25 +52,25 @@ export interface FirebaseAppDistributionModule { * Returns true if the App Distribution tester is signed in. * If not an iOS device, it always rejects, as neither false nor true seem like a sensible default. */ - isTesterSignedIn(): Promise; + isTesterSignedIn(_modularDeprecationArg?: any): Promise; /** * Sign-in the App Distribution tester * If not an iOS device, it always rejects, as no defaults seem sensible. */ - signInTester(): Promise; + signInTester(_modularDeprecationArg?: any): Promise; /** * Check to see whether a new distribution is available * If not an iOS device, it always rejects, as no default response seems sensible. */ - checkForUpdate(): Promise; + checkForUpdate(_modularDeprecationArg?: any): Promise; /** * Sign out App Distribution tester * If not an iOS device, it always rejects, as no default response seems sensible. */ - signOutTester(): Promise; + signOutTester(_modularDeprecationArg?: any): Promise; } export type FirebaseAppDistribution = FirebaseAppDistributionModule; From 9a4ae52a10aa5218bb8f0075e053a9991f026e88 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Tue, 16 Dec 2025 15:53:57 +0000 Subject: [PATCH 4/8] fix: version --- packages/app-distribution/lib/types.d.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/app-distribution/lib/types.d.ts b/packages/app-distribution/lib/types.d.ts index b248a1245e..99a0e4fa4e 100644 --- a/packages/app-distribution/lib/types.d.ts +++ b/packages/app-distribution/lib/types.d.ts @@ -184,7 +184,3 @@ declare module '@react-native-firebase/app/lib/internal' { } export function getFirebaseRoot(): any; } - -declare module './version' { - export const version: string; -} From 5f432f51e505546428ba564ea486f9b91c83cdc7 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Thu, 18 Dec 2025 07:00:05 +0000 Subject: [PATCH 5/8] fix: type defs --- packages/app-distribution/lib/index.ts | 4 +- packages/app-distribution/lib/namespaced.ts | 6 +- packages/app-distribution/lib/types.d.ts | 191 ++---------------- .../lib/types/app-distribution.ts | 10 + packages/app-distribution/package.json | 62 +++++- packages/app-distribution/tsconfig.json | 32 +++ yarn.lock | 2 + 7 files changed, 125 insertions(+), 182 deletions(-) create mode 100644 packages/app-distribution/tsconfig.json diff --git a/packages/app-distribution/lib/index.ts b/packages/app-distribution/lib/index.ts index 3705868f96..88d0917dc3 100644 --- a/packages/app-distribution/lib/index.ts +++ b/packages/app-distribution/lib/index.ts @@ -20,11 +20,9 @@ export type { AppDistributionRelease, FirebaseAppDistribution, FirebaseApp, + FirebaseAppDistributionTypes, } from './types/app-distribution'; -// Export types from types.d.ts -export type { FirebaseAppDistributionTypes } from './types.d'; - // Export modular API functions export * from './modular'; diff --git a/packages/app-distribution/lib/namespaced.ts b/packages/app-distribution/lib/namespaced.ts index 88a6af38f3..e9dc25b68e 100644 --- a/packages/app-distribution/lib/namespaced.ts +++ b/packages/app-distribution/lib/namespaced.ts @@ -22,7 +22,7 @@ import { getFirebaseRoot, } from '@react-native-firebase/app/lib/internal'; import { version } from './version'; -import type { FirebaseAppDistributionTypes } from './types.d'; +import type { FirebaseAppDistributionTypes } from './types/app-distribution'; const statics = {}; @@ -33,6 +33,7 @@ const nativeModuleName = 'RNFBAppDistributionModule'; class FirebaseAppDistributionModule extends FirebaseModule { isTesterSignedIn(_modularDeprecationArg?: any): Promise { if (isIOS) { + // @ts-ignore - native is inherited from FirebaseModule return this.native.isTesterSignedIn(); } @@ -41,6 +42,7 @@ class FirebaseAppDistributionModule extends FirebaseModule { signInTester(_modularDeprecationArg?: any): Promise { if (isIOS) { + // @ts-ignore - native is inherited from FirebaseModule return this.native.signInTester(); } @@ -51,6 +53,7 @@ class FirebaseAppDistributionModule extends FirebaseModule { _modularDeprecationArg?: any, ): Promise { if (isIOS) { + // @ts-ignore - native is inherited from FirebaseModule return this.native.checkForUpdate(); } @@ -59,6 +62,7 @@ class FirebaseAppDistributionModule extends FirebaseModule { signOutTester(_modularDeprecationArg?: any): Promise { if (isIOS) { + // @ts-ignore - native is inherited from FirebaseModule return this.native.signOutTester(); } diff --git a/packages/app-distribution/lib/types.d.ts b/packages/app-distribution/lib/types.d.ts index 99a0e4fa4e..ab85458c72 100644 --- a/packages/app-distribution/lib/types.d.ts +++ b/packages/app-distribution/lib/types.d.ts @@ -1,186 +1,31 @@ /* - * 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. - * + * Type declarations for modules from @react-native-firebase/app + * These are JavaScript modules that don't have type definitions */ -import { ReactNativeFirebase } from '@react-native-firebase/app'; - -/** - * Firebase AppDistribution package for React Native. - * - * #### Example 1 - * - * Access the firebase export from the `app-distribution` package: - * - * ```js - * import { firebase } from '@react-native-firebase/app-distribution'; - * - * // firebase.appDistribution().X - * ``` - * - * #### Example 2 - * - * Using the default export from the `app-distribution` package: - * - * ```js - * import appDistribution from '@react-native-firebase/app-distribution'; - * - * // appDistribution().X - * ``` - * - * #### Example 3 - * - * Using the default export from the `app` package: - * - * ```js - * import firebase from '@react-native-firebase/app'; - * import '@react-native-firebase/app-distribution'; - * - * // firebase.appDistribution().X - * ``` - * - * @firebase app-distribution - */ -export namespace FirebaseAppDistributionTypes { - import FirebaseModule = ReactNativeFirebase.FirebaseModule; - - /** - * The release information returned by the update check when a new version is available. - */ - export interface AppDistributionRelease { - /** - * The short bundle version of this build (example 1.0.0). - */ - displayVersion: string; - - /** - * The build number of this build (example: 123). - */ - buildVersion: string; - - /** - * The release notes for this build, possibly null if no release notes were provided. - */ - releaseNotes: string | null; - - /** - * The URL for the build. - */ - downloadURL: string; - - /** - * Whether the download URL for this release is expired. - */ - isExpired: boolean; - } - - // eslint-disable-next-line @typescript-eslint/no-empty-object-type - export interface Statics { - // firebase.appDistribution.* static props go here - } - - /** - * The Firebase AppDistribution service interface. - * - * > This module is available for the default app only. - * - * #### Example - * - * Get the AppDistribution service for the default app: - * - * ```js - * const defaultAppAppDistribution = firebase.appDistribution(); - * ``` - */ - export class Module extends FirebaseModule { - /** - * Returns true if the App Distribution tester is signed in. - * If not an iOS device, it always rejects, as neither false nor true seem like a sensible default. - */ - isTesterSignedIn(_modularDeprecationArg?: any): Promise; - - /** - * Sign-in the App Distribution tester - * If not an iOS device, it always rejects, as no defaults seem sensible. - */ - signInTester(_modularDeprecationArg?: any): Promise; - - /** - * Check to see whether a new distribution is available - * If not an iOS device, it always rejects, as no default response seems sensible. - */ - checkForUpdate(_modularDeprecationArg?: any): Promise; - - /** - * Sign out App Distribution tester - * If not an iOS device, it always rejects, as no default response seems sensible. - */ - signOutTester(_modularDeprecationArg?: any): Promise; - } -} - -declare const defaultExport: ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< - FirebaseAppDistributionTypes.Module, - FirebaseAppDistributionTypes.Statics ->; - -export const firebase: ReactNativeFirebase.Module & { - appDistribution: typeof defaultExport; - app( - name?: string, - ): ReactNativeFirebase.FirebaseApp & { appDistribution(): FirebaseAppDistributionTypes.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 { - appDistribution: FirebaseModuleWithStaticsAndApp< - FirebaseAppDistributionTypes.Module, - FirebaseAppDistributionTypes.Statics - >; - } - interface FirebaseApp { - appDistribution(): FirebaseAppDistributionTypes.Module; - readonly name: string; - } - } - - export function getApp(appName?: string): ReactNativeFirebase.FirebaseApp; -} - declare module '@react-native-firebase/app/lib/common' { - export const MODULAR_DEPRECATION_ARG: string; export const isIOS: boolean; + export const isAndroid: boolean; + export const MODULAR_DEPRECATION_ARG: any; } declare module '@react-native-firebase/app/lib/internal' { - export function createModuleNamespace(config: any): any; + export function createModuleNamespace(options: { + statics: any; + version: string; + namespace: string; + nativeModuleName: string; + nativeEvents?: boolean | string[]; + hasMultiAppSupport?: boolean; + hasCustomUrlOrRegionSupport?: boolean; + ModuleClass: any; + }): any; export class FirebaseModule { - constructor(...args: any[]); - native: any; app: any; - firebaseJson: any; - _customUrlOrRegion: string | null; + native: any; + emitter: any; + constructor(app: any, config: any, customUrlOrRegion?: any); } export function getFirebaseRoot(): any; } + diff --git a/packages/app-distribution/lib/types/app-distribution.ts b/packages/app-distribution/lib/types/app-distribution.ts index f64b3db61d..c1e2b5a7d3 100644 --- a/packages/app-distribution/lib/types/app-distribution.ts +++ b/packages/app-distribution/lib/types/app-distribution.ts @@ -77,3 +77,13 @@ export type FirebaseAppDistribution = FirebaseAppDistributionModule; export type FirebaseApp = ReactNativeFirebase.FirebaseApp & { appDistribution(): FirebaseAppDistribution; }; + +// Namespace export for backward compatibility +// Using a workaround to create the namespace without circular references +type _AppDistributionRelease = AppDistributionRelease; +type _FirebaseAppDistributionModule = FirebaseAppDistributionModule; + +export namespace FirebaseAppDistributionTypes { + export type AppDistributionRelease = _AppDistributionRelease; + export type Module = _FirebaseAppDistributionModule; +} diff --git a/packages/app-distribution/package.json b/packages/app-distribution/package.json index 1fa08b6401..d46751f7d4 100644 --- a/packages/app-distribution/package.json +++ b/packages/app-distribution/package.json @@ -3,14 +3,16 @@ "version": "23.7.0", "author": "Invertase (http://invertase.io)", "description": "React Native Firebase - App Distribution", - "main": "lib/index.ts", - "types": "lib/types.d.ts", + "main": "./dist/commonjs/index.js", + "module": "./dist/module/index.js", + "types": "./dist/typescript/commonjs/lib/index.d.ts", "scripts": { "build": "genversion --esm --semi lib/version.ts", "build:clean": "rimraf android/build && rimraf ios/build", "build:plugin": "rimraf plugin/build && tsc --build plugin", "lint:plugin": "eslint plugin/src/*", - "prepare": "yarn run build && yarn run build:plugin" + "compile": "bob build", + "prepare": "yarn run build && yarn run build:plugin && yarn compile" }, "repository": { "type": "git", @@ -28,7 +30,9 @@ "expo": ">=47.0.0" }, "devDependencies": { - "expo": "^54.0.27" + "expo": "^54.0.27", + "react-native-builder-bob": "^0.40.12", + "typescript": "^5.8.3" }, "peerDependenciesMeta": { "expo": { @@ -38,5 +42,53 @@ "publishConfig": { "access": "public", "provenance": true - } + }, + "exports": { + ".": { + "source": "./lib/index.ts", + "import": { + "types": "./dist/typescript/module/lib/index.d.ts", + "default": "./dist/module/index.js" + }, + "require": { + "types": "./dist/typescript/commonjs/lib/index.d.ts", + "default": "./dist/commonjs/index.js" + } + }, + "./package.json": "./package.json" + }, + "files": [ + "dist", + "!**/__tests__", + "!**/__fixtures__", + "!**/__mocks__" + ], + "react-native-builder-bob": { + "source": "lib", + "output": "dist", + "targets": [ + [ + "module", + { + "esm": true + } + ], + [ + "commonjs", + { + "esm": true + } + ], + [ + "typescript", + { + "tsc": "../../node_modules/.bin/tsc" + } + ] + ] + }, + "eslintIgnore": [ + "node_modules/", + "dist/" + ] } diff --git a/packages/app-distribution/tsconfig.json b/packages/app-distribution/tsconfig.json new file mode 100644 index 0000000000..37d9af0ace --- /dev/null +++ b/packages/app-distribution/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "bundler", + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "noImplicitUseStrict": false, + "noStrictGenericChecks": false, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "target": "ESNext", + "verbatimModuleSyntax": true, + "baseUrl": ".", + "rootDir": ".", + "paths": { + "@react-native-firebase/app": ["../app/lib"], + "@react-native-firebase/app/lib/*": ["../app/lib/*"] + } + }, + "include": ["lib/**/*"], + "exclude": ["node_modules", "dist", "__tests__", "**/*.test.ts"] + } diff --git a/yarn.lock b/yarn.lock index 2becdc9b4f..c352ab87cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5071,6 +5071,8 @@ __metadata: resolution: "@react-native-firebase/app-distribution@workspace:packages/app-distribution" dependencies: expo: "npm:^54.0.27" + react-native-builder-bob: "npm:^0.40.12" + typescript: "npm:^5.8.3" peerDependencies: "@react-native-firebase/app": 23.7.0 expo: ">=47.0.0" From 5786513ee4ec7bea211153339677c52d535add0a Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Thu, 18 Dec 2025 08:49:20 +0000 Subject: [PATCH 6/8] fix: Lint --- packages/app-distribution/lib/types.d.ts | 1 - packages/app-distribution/lib/types/app-distribution.ts | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app-distribution/lib/types.d.ts b/packages/app-distribution/lib/types.d.ts index ab85458c72..7cddd00edf 100644 --- a/packages/app-distribution/lib/types.d.ts +++ b/packages/app-distribution/lib/types.d.ts @@ -28,4 +28,3 @@ declare module '@react-native-firebase/app/lib/internal' { } export function getFirebaseRoot(): any; } - diff --git a/packages/app-distribution/lib/types/app-distribution.ts b/packages/app-distribution/lib/types/app-distribution.ts index c1e2b5a7d3..d508554f66 100644 --- a/packages/app-distribution/lib/types/app-distribution.ts +++ b/packages/app-distribution/lib/types/app-distribution.ts @@ -83,6 +83,7 @@ export type FirebaseApp = ReactNativeFirebase.FirebaseApp & { type _AppDistributionRelease = AppDistributionRelease; type _FirebaseAppDistributionModule = FirebaseAppDistributionModule; +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace FirebaseAppDistributionTypes { export type AppDistributionRelease = _AppDistributionRelease; export type Module = _FirebaseAppDistributionModule; From 584ead85d0b2e092b6fc07120d77cde3f5d50703 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Thu, 18 Dec 2025 09:01:04 +0000 Subject: [PATCH 7/8] fix: tsconfig --- packages/app-distribution/tsconfig.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/app-distribution/tsconfig.json b/packages/app-distribution/tsconfig.json index 37d9af0ace..d8321c20d1 100644 --- a/packages/app-distribution/tsconfig.json +++ b/packages/app-distribution/tsconfig.json @@ -23,10 +23,9 @@ "baseUrl": ".", "rootDir": ".", "paths": { - "@react-native-firebase/app": ["../app/lib"], - "@react-native-firebase/app/lib/*": ["../app/lib/*"] + "@react-native-firebase/app": ["../app/lib"] } }, "include": ["lib/**/*"], - "exclude": ["node_modules", "dist", "__tests__", "**/*.test.ts"] + "exclude": ["node_modules", "dist", "__tests__", "**/*.test.ts", "../app/**/*"] } From cdff668056ee79dda8ea3a3daf684a25abd859c2 Mon Sep 17 00:00:00 2001 From: MichaelVerdon Date: Thu, 18 Dec 2025 11:14:10 +0000 Subject: [PATCH 8/8] fix: types 2 --- packages/app-distribution/lib/types.d.ts | 15 +++++++++++++++ .../lib/types/app-distribution.ts | 4 ++-- packages/app-distribution/tsconfig.json | 8 ++------ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/packages/app-distribution/lib/types.d.ts b/packages/app-distribution/lib/types.d.ts index 7cddd00edf..e65b022bde 100644 --- a/packages/app-distribution/lib/types.d.ts +++ b/packages/app-distribution/lib/types.d.ts @@ -3,6 +3,21 @@ * These are JavaScript modules that don't have type definitions */ +declare module '@react-native-firebase/app' { + export interface FirebaseApp { + name: string; + options: any; + } + export namespace ReactNativeFirebase { + export interface FirebaseApp { + name: string; + options: any; + } + } + export function getApp(name?: string): FirebaseApp; + export function getApps(): FirebaseApp[]; +} + declare module '@react-native-firebase/app/lib/common' { export const isIOS: boolean; export const isAndroid: boolean; diff --git a/packages/app-distribution/lib/types/app-distribution.ts b/packages/app-distribution/lib/types/app-distribution.ts index d508554f66..ff3ba204d0 100644 --- a/packages/app-distribution/lib/types/app-distribution.ts +++ b/packages/app-distribution/lib/types/app-distribution.ts @@ -15,7 +15,7 @@ * */ -import type { ReactNativeFirebase } from '@react-native-firebase/app'; +import type { FirebaseApp as RNFirebaseApp } from '@react-native-firebase/app'; /** * The release information returned by the update check when a new version is available. @@ -74,7 +74,7 @@ export interface FirebaseAppDistributionModule { } export type FirebaseAppDistribution = FirebaseAppDistributionModule; -export type FirebaseApp = ReactNativeFirebase.FirebaseApp & { +export type FirebaseApp = RNFirebaseApp & { appDistribution(): FirebaseAppDistribution; }; diff --git a/packages/app-distribution/tsconfig.json b/packages/app-distribution/tsconfig.json index d8321c20d1..ef9c03d53f 100644 --- a/packages/app-distribution/tsconfig.json +++ b/packages/app-distribution/tsconfig.json @@ -20,12 +20,8 @@ "strict": true, "target": "ESNext", "verbatimModuleSyntax": true, - "baseUrl": ".", - "rootDir": ".", - "paths": { - "@react-native-firebase/app": ["../app/lib"] - } + "rootDir": "." }, "include": ["lib/**/*"], - "exclude": ["node_modules", "dist", "__tests__", "**/*.test.ts", "../app/**/*"] + "exclude": ["node_modules", "dist", "__tests__", "**/*.test.ts"] }