diff --git a/packages/app-distribution/__tests__/app-distribution.test.ts b/packages/app-distribution/__tests__/app-distribution.test.ts index 647ce0385a..4168d85a21 100644 --- a/packages/app-distribution/__tests__/app-distribution.test.ts +++ b/packages/app-distribution/__tests__/app-distribution.test.ts @@ -79,49 +79,57 @@ describe('appDistribution()', function () { { get: () => jest.fn().mockResolvedValue({ - constants: { - isTesterSignedIn: true, - }, + displayVersion: '1.0.0', + buildVersion: '123', + releaseNotes: null, + downloadURL: 'https://example.com', + isExpired: false, } as never), }, ); }); }); - it('isTesterSignedIn', function () { - const appDistribution = getAppDistribution(); - appDistributionV9Deprecation( - () => isTesterSignedIn(appDistribution), - () => appDistribution.isTesterSignedIn(), - 'isTesterSignedIn', - ); - }); + describe('AppDistribution', function () { + it('isTesterSignedIn()', function () { + const appDistribution = getAppDistribution(); + appDistributionV9Deprecation( + () => isTesterSignedIn(appDistribution), + // @ts-expect-error Combines modular and namespace API + () => appDistribution.isTesterSignedIn(), + 'isTesterSignedIn', + ); + }); - it('signInTester', function () { - const appDistribution = getAppDistribution(); - appDistributionV9Deprecation( - () => signInTester(appDistribution), - () => appDistribution.signInTester(), - 'signInTester', - ); - }); + it('signInTester()', function () { + const appDistribution = getAppDistribution(); + appDistributionV9Deprecation( + () => signInTester(appDistribution), + // @ts-expect-error Combines modular and namespace API + () => appDistribution.signInTester(), + 'signInTester', + ); + }); - it('checkForUpdate', function () { - const appDistribution = getAppDistribution(); - appDistributionV9Deprecation( - () => checkForUpdate(appDistribution), - () => appDistribution.checkForUpdate(), - 'checkForUpdate', - ); - }); + it('checkForUpdate()', function () { + const appDistribution = getAppDistribution(); + appDistributionV9Deprecation( + () => checkForUpdate(appDistribution), + // @ts-expect-error Combines modular and namespace API + () => appDistribution.checkForUpdate(), + 'checkForUpdate', + ); + }); - it('signOutTester', function () { - const appDistribution = getAppDistribution(); - appDistributionV9Deprecation( - () => signOutTester(appDistribution), - () => appDistribution.signOutTester(), - 'signOutTester', - ); + it('signOutTester()', function () { + const appDistribution = getAppDistribution(); + appDistributionV9Deprecation( + () => signOutTester(appDistribution), + // @ts-expect-error Combines modular and namespace API + () => appDistribution.signOutTester(), + 'signOutTester', + ); + }); }); }); }); diff --git a/packages/app-distribution/lib/index.js b/packages/app-distribution/lib/index.js deleted file mode 100644 index 9ae260c374..0000000000 --- a/packages/app-distribution/lib/index.js +++ /dev/null @@ -1,88 +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 { isIOS } from '@react-native-firebase/app/dist/module/common'; -import { - createModuleNamespace, - FirebaseModule, - getFirebaseRoot, -} from '@react-native-firebase/app/dist/module/internal'; - -import version from './version'; - -const statics = {}; - -const namespace = 'appDistribution'; - -const nativeModuleName = 'RNFBAppDistributionModule'; - -class FirebaseAppDistributionModule extends FirebaseModule { - isTesterSignedIn() { - if (isIOS) { - return this.native.isTesterSignedIn(); - } - - Promise.reject(new Error('App Distribution is not supported on this platform.')); - } - - signInTester() { - if (isIOS) { - return this.native.signInTester(); - } - - Promise.reject(new Error('App Distribution is not supported on this platform.')); - } - - checkForUpdate() { - if (isIOS) { - return this.native.checkForUpdate(); - } - - Promise.reject(new Error('App Distribution is not supported on this platform.')); - } - - signOutTester() { - if (isIOS) { - return this.native.signOutTester(); - } - - 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; - -// import appDistribution from '@react-native-firebase/app-distribution'; -// appDistribution().X(...); -export default createModuleNamespace({ - statics, - version, - namespace, - nativeModuleName, - nativeEvents: false, - hasMultiAppSupport: false, - hasCustomUrlOrRegionSupport: false, - ModuleClass: FirebaseAppDistributionModule, -}); - -// import appDistribution, { firebase } from '@react-native-firebase/app-distribution'; -// appDistribution().X(...); -// firebase.appDistribution().X(...); -export const firebase = getFirebaseRoot(); diff --git a/packages/app-distribution/lib/index.ts b/packages/app-distribution/lib/index.ts new file mode 100644 index 0000000000..b98a2437bf --- /dev/null +++ b/packages/app-distribution/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/app-distribution (public/modular API; Statics re-exported via modular) +export type { AppDistributionRelease, AppDistribution } from './types/app-distribution'; +export type { FirebaseAppDistributionTypes } from './types/namespaced'; + +// 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..adc685dc37 --- /dev/null +++ b/packages/app-distribution/lib/modular.ts @@ -0,0 +1,69 @@ +import { getApp } from '@react-native-firebase/app'; +import { MODULAR_DEPRECATION_ARG } from '@react-native-firebase/app/dist/module/common'; +import type { ReactNativeFirebase } from '@react-native-firebase/app'; +import type { AppDistribution, AppDistributionRelease } from './types/app-distribution'; +import type { AppDistributionInternal, WithModularDeprecationArg } from './types/internal'; + +export type { Statics } from './types/app-distribution'; + +export type FirebaseAppDistribution = AppDistribution; + +/** + * Get an App Distribution instance for the specified app or current app. + */ +export function getAppDistribution(app?: ReactNativeFirebase.FirebaseApp): FirebaseAppDistribution { + if (app) { + return getApp(app.name).appDistribution() as FirebaseAppDistribution; + } + return getApp().appDistribution() as 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 function isTesterSignedIn(appDistribution: FirebaseAppDistribution): Promise { + return ( + (appDistribution as AppDistributionInternal).isTesterSignedIn as WithModularDeprecationArg< + AppDistributionInternal['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. + */ +export function signInTester(appDistribution: FirebaseAppDistribution): Promise { + return ( + (appDistribution as AppDistributionInternal).signInTester as WithModularDeprecationArg< + AppDistributionInternal['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. + */ +export function checkForUpdate( + appDistribution: FirebaseAppDistribution, +): Promise { + return ( + (appDistribution as AppDistributionInternal).checkForUpdate as WithModularDeprecationArg< + AppDistributionInternal['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. + */ +export function signOutTester(appDistribution: FirebaseAppDistribution): Promise { + return ( + (appDistribution as AppDistributionInternal).signOutTester as WithModularDeprecationArg< + AppDistributionInternal['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 62aeca9985..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/dist/module/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/namespaced.ts b/packages/app-distribution/lib/namespaced.ts new file mode 100644 index 0000000000..a99334d393 --- /dev/null +++ b/packages/app-distribution/lib/namespaced.ts @@ -0,0 +1,110 @@ +/* + * 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 { isIOS } from '@react-native-firebase/app/dist/module/common'; +import type { ReactNativeFirebase } from '@react-native-firebase/app'; +import { + createModuleNamespace, + FirebaseModule, + getFirebaseRoot, +} from '@react-native-firebase/app/dist/module/internal'; + +import { version } from './version'; +import type { AppDistributionRelease } from './types/app-distribution'; +import type { FirebaseAppDistributionTypes } from './types/namespaced'; + +const statics: FirebaseAppDistributionTypes.Statics = { SDK_VERSION: version }; + +const namespace = 'appDistribution'; + +const nativeModuleName = 'RNFBAppDistributionModule'; + +class FirebaseAppDistributionModule extends FirebaseModule { + isTesterSignedIn(): Promise { + if (isIOS) { + return this.native.isTesterSignedIn(); + } + + return Promise.reject(new Error('App Distribution is not supported on this platform.')); + } + + signInTester(): Promise { + if (isIOS) { + return this.native.signInTester(); + } + + return Promise.reject(new Error('App Distribution is not supported on this platform.')); + } + + checkForUpdate(): Promise { + if (isIOS) { + return this.native.checkForUpdate(); + } + + return Promise.reject(new Error('App Distribution is not supported on this platform.')); + } + + signOutTester(): Promise { + if (isIOS) { + return this.native.signOutTester(); + } + + return Promise.reject(new Error('App Distribution is not supported on this platform.')); + } +} + +// import { SDK_VERSION } from '@react-native-firebase/app-distribution'; +export const SDK_VERSION: string = version; + +// import appDistribution from '@react-native-firebase/app-distribution'; +// appDistribution().X(...); + +const appDistributionNamespace = createModuleNamespace({ + statics, + version, + namespace, + nativeModuleName, + nativeEvents: false, + hasMultiAppSupport: false, + hasCustomUrlOrRegionSupport: false, + ModuleClass: FirebaseAppDistributionModule, +}); + +type AppDistributionNamespace = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< + FirebaseAppDistributionTypes.Module, + FirebaseAppDistributionTypes.Statics +> & { + appDistribution: ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< + FirebaseAppDistributionTypes.Module, + FirebaseAppDistributionTypes.Statics + >; + firebase: ReactNativeFirebase.Module; + app(name?: string): ReactNativeFirebase.FirebaseApp; +}; + +export default appDistributionNamespace as unknown as AppDistributionNamespace; + +// import appDistribution, { firebase } from '@react-native-firebase/app-distribution'; +// appDistribution().X(...); +// firebase.appDistribution().X(...); +export const firebase = + getFirebaseRoot() as unknown as ReactNativeFirebase.FirebaseNamespacedExport< + 'appDistribution', + FirebaseAppDistributionTypes.Module, + FirebaseAppDistributionTypes.Statics, + false + >; 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..07ee5eafff --- /dev/null +++ b/packages/app-distribution/lib/types/app-distribution.ts @@ -0,0 +1,70 @@ +/* + * 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; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface Statics {} + +/** + * The Firebase AppDistribution service interface (modular/public API). + * Only exposes the app reference; use modular functions or the internal type for methods. + * + * > This module is available for the default app only. + * + * #### Example + * + * Get the AppDistribution service for the default app: + * + * ```js + * const defaultAppAppDistribution = getAppDistribution(); + * ``` + */ +export interface AppDistribution { + /** The FirebaseApp this module is associated with */ + app: ReactNativeFirebase.FirebaseApp; +} diff --git a/packages/app-distribution/lib/types/internal.ts b/packages/app-distribution/lib/types/internal.ts new file mode 100644 index 0000000000..7bdf79786a --- /dev/null +++ b/packages/app-distribution/lib/types/internal.ts @@ -0,0 +1,74 @@ +/* + * 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 { AppDistribution, AppDistributionRelease } from './app-distribution'; + +/** + * Wraps a method type so it accepts MODULAR_DEPRECATION_ARG as a trailing argument. + * Allows modular wrappers to use .call(instance, ...args, MODULAR_DEPRECATION_ARG) without changing internal types. + */ +export type WithModularDeprecationArg unknown> = T extends ( + ...args: infer A +) => infer R + ? (...args: [...A, unknown?]) => R + : never; + +/** + * Wrapped native module interface for App Distribution. + */ +export interface RNFBAppDistributionModule { + isTesterSignedIn(): Promise; + signInTester(): Promise; + checkForUpdate(): Promise; + signOutTester(): Promise; +} + +declare module '@react-native-firebase/app/dist/module/internal/NativeModules' { + interface ReactNativeFirebaseNativeModules { + RNFBAppDistributionModule: RNFBAppDistributionModule; + } +} + +/** + * Internal AppDistribution type with access to instance methods. + * Used by namespaced implementation and modular wrappers; not part of the public modular API. + */ +export type AppDistributionInternal = 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. + */ + 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; +}; diff --git a/packages/app-distribution/lib/index.d.ts b/packages/app-distribution/lib/types/namespaced.ts similarity index 61% rename from packages/app-distribution/lib/index.d.ts rename to packages/app-distribution/lib/types/namespaced.ts index 1f9a323186..2865056458 100644 --- a/packages/app-distribution/lib/index.d.ts +++ b/packages/app-distribution/lib/types/namespaced.ts @@ -15,10 +15,10 @@ * */ -import { ReactNativeFirebase } from '@react-native-firebase/app'; +import type { ReactNativeFirebase } from '@react-native-firebase/app'; /** - * Firebase AppDistribution package for React Native. + * Firebase App Distribution package for React Native. * * #### Example 1 * @@ -53,103 +53,94 @@ import { ReactNativeFirebase } from '@react-native-firebase/app'; * * @firebase app-distribution */ + +/** + * @deprecated Use the exported types directly instead. + * FirebaseAppDistributionTypes namespace is kept for backwards compatibility. + */ +/* eslint-disable @typescript-eslint/no-namespace */ export namespace FirebaseAppDistributionTypes { - import FirebaseModule = ReactNativeFirebase.FirebaseModule; + type FirebaseModule = ReactNativeFirebase.FirebaseModule; /** * The release information returned by the update check when a new version is available. + * + * @deprecated Use the exported types directly instead. FirebaseAppDistributionTypes namespace is kept for backwards compatibility. */ 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 + /** + * Cloud Storage statics. + * + * @deprecated Use the exported types directly instead. FirebaseAppDistributionTypes namespace is kept for backwards compatibility. + */ export interface Statics { - // firebase.appDistribution.* static props go here + SDK_VERSION: string; } /** - * The Firebase AppDistribution service interface. + * The Firebase AppDistribution service is available for the default app only. * - * > This module is available for the default app only. + * @deprecated Use the modular API (getAppDistribution, isTesterSignedIn, etc.) and types from '@react-native-firebase/app-distribution' instead. + * FirebaseAppDistributionTypes namespace is kept for backwards compatibility. * * #### Example * - * Get the AppDistribution service for the default app: + * Get the App Distribution service for the **default app**: * * ```js * const defaultAppAppDistribution = firebase.appDistribution(); * ``` */ - export class Module extends FirebaseModule { + export interface Module extends FirebaseModule { + /** + * The current `FirebaseApp` instance for this Firebase service. + * + * @deprecated Use the modular API instead. + */ + app: ReactNativeFirebase.FirebaseApp; + /** * 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. + * + * @deprecated Use the modular `isTesterSignedIn(appDistribution)` instead. */ isTesterSignedIn(): Promise; /** - * Sign-in the App Distribution tester + * Sign-in the App Distribution tester. * If not an iOS device, it always rejects, as no defaults seem sensible. + * + * @deprecated Use the modular `signInTester(appDistribution)` instead. */ signInTester(): Promise; /** - * Check to see whether a new distribution is available + * Check to see whether a new distribution is available. * If not an iOS device, it always rejects, as no default response seems sensible. + * + * @deprecated Use the modular `checkForUpdate(appDistribution)` instead. */ checkForUpdate(): Promise; /** - * Sign out App Distribution tester + * Sign out App Distribution tester. * If not an iOS device, it always rejects, as no default response seems sensible. + * + * @deprecated Use the modular `signOutTester(appDistribution)` instead. */ signOutTester(): 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.`. - */ +/* eslint-disable @typescript-eslint/no-namespace */ declare module '@react-native-firebase/app' { namespace ReactNativeFirebase { import FirebaseModuleWithStaticsAndApp = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp; @@ -164,3 +155,4 @@ declare module '@react-native-firebase/app' { } } } +/* eslint-enable @typescript-eslint/no-namespace */ diff --git a/packages/app-distribution/package.json b/packages/app-distribution/package.json index 614c48dedb..54b823268c 100644 --- a/packages/app-distribution/package.json +++ b/packages/app-distribution/package.json @@ -3,14 +3,15 @@ "version": "23.8.5", "author": "Invertase (http://invertase.io)", "description": "React Native Firebase - App Distribution", - "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", "build:plugin": "rimraf plugin/build && tsc --build plugin", + "compile": "bob build", "lint:plugin": "eslint plugin/src/*", - "prepare": "yarn run build && yarn run build:plugin" + "prepare": "yarn run build && yarn compile" }, "repository": { "type": "git", @@ -28,13 +29,44 @@ "expo": ">=47.0.0" }, "devDependencies": { - "expo": "^54.0.27" + "expo": "^54.0.27", + "react-native-builder-bob": "^0.40.17" }, "peerDependenciesMeta": { "expo": { "optional": true } }, + "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/" + ], "publishConfig": { "access": "public", "provenance": true diff --git a/packages/app-distribution/tsconfig.json b/packages/app-distribution/tsconfig.json new file mode 100644 index 0000000000..7c2d0e4f9b --- /dev/null +++ b/packages/app-distribution/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../tsconfig.packages.base.json", + "compilerOptions": { + "baseUrl": ".", + "rootDir": ".", + "paths": { + "@react-native-firebase/app/dist/module/common/*": ["../app/dist/typescript/lib/common/*"], + "@react-native-firebase/app/dist/module/common": ["../app/dist/typescript/lib/common"], + "@react-native-firebase/app/dist/module/internal/web/*": [ + "../app/dist/typescript/lib/internal/web/*" + ], + "@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": ["../app/dist/typescript/lib"] + } + }, + "include": ["lib/**/*"], + "exclude": ["node_modules", "dist", "__tests__", "**/*.test.ts"] +} + diff --git a/packages/app-distribution/type-test.ts b/packages/app-distribution/type-test.ts index 60426428cd..cc197c3e36 100644 --- a/packages/app-distribution/type-test.ts +++ b/packages/app-distribution/type-test.ts @@ -1,4 +1,14 @@ -import firebase from '.'; +import appDistribution, { + firebase, + FirebaseAppDistributionTypes, + getAppDistribution, + isTesterSignedIn, + signInTester, + checkForUpdate, + signOutTester, +} from '.'; + +console.log(appDistribution().app); // checks module exists at root console.log(firebase.appDistribution().app.name); @@ -9,14 +19,38 @@ console.log(firebase.app().appDistribution().app.name); // checks statics exist console.log(firebase.appDistribution.SDK_VERSION); -// checks root exists -console.log(firebase.SDK_VERSION); +// checks statics exist on defaultExport +console.log(appDistribution.SDK_VERSION); -// checks firebase named export exists on module +// checks root exists console.log(firebase.SDK_VERSION); // checks multi-app support exists console.log(firebase.appDistribution(firebase.app()).app.name); // checks default export supports app arg -console.log(firebase(firebase.app()).app.name); +console.log(appDistribution(firebase.app()).app.name); + +// checks Module instance APIs +const appDistributionInstance = firebase.appDistribution() as unknown as FirebaseAppDistributionTypes.Module; +console.log(appDistributionInstance.app.name); +appDistributionInstance.isTesterSignedIn().then((v: boolean) => console.log(v)); +appDistributionInstance.signInTester().then(() => {}); +appDistributionInstance.checkForUpdate().then((r: FirebaseAppDistributionTypes.AppDistributionRelease) => { + console.log(r.displayVersion, r.buildVersion); +}); +appDistributionInstance.signOutTester().then(() => {}); + +// checks modular API functions +const modularAppDist = getAppDistribution(); +console.log(modularAppDist.app.name); + +const modularAppDistWithApp = getAppDistribution(firebase.app()); +console.log(modularAppDistWithApp.app.name); + +isTesterSignedIn(modularAppDist).then((v: boolean) => console.log(v)); +signInTester(modularAppDist).then(() => {}); +checkForUpdate(modularAppDist).then(release => { + console.log(release.displayVersion, release.buildVersion, release.downloadURL); +}); +signOutTester(modularAppDist).then(() => {}); diff --git a/tsconfig.json b/tsconfig.json index 0658ab77a9..18fa6c24ef 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,9 +2,7 @@ "include": [ "packages/ai/lib/types/polyfills.d.ts", "packages/app-check/lib/index.d.ts", - "packages/app-check/lib/modular/index.d.ts", - "packages/app-distribution/lib/index.d.ts", - "packages/app-distribution/lib/modular/index.d.ts", + "packages/app-check/lib/modular.d.ts", "packages/app/lib/internal/global.d.ts", "packages/app/lib/internal/web/memidb/index.d.ts", "packages/auth/lib/index.d.ts", @@ -40,6 +38,7 @@ "packages/functions/type-test.ts", "packages/app/type-test.ts", "packages/app-check/type-test.ts", + "packages/app-distribution/type-test.ts", "packages/auth/type-test.ts", "packages/crashlytics/type-test.ts", "packages/database/type-test.ts", diff --git a/yarn.lock b/yarn.lock index ecd9f480f4..b3cac62964 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5793,6 +5793,7 @@ __metadata: resolution: "@react-native-firebase/app-distribution@workspace:packages/app-distribution" dependencies: expo: "npm:^54.0.27" + react-native-builder-bob: "npm:^0.40.17" peerDependencies: "@react-native-firebase/app": 23.8.5 expo: ">=47.0.0"