From 8ef9dee5b11af479751bd35d0c9459dc27e286d7 Mon Sep 17 00:00:00 2001 From: Hiranya Jayathilaka Date: Thu, 4 Feb 2021 13:20:31 -0800 Subject: [PATCH] feat: Exposed firebase-admin/project-management entry point --- etc/firebase-admin.api.md | 91 ++-- etc/firebase-admin.project-management.api.md | 115 +++++ generate-reports.js | 1 + gulpfile.js | 1 + src/app/firebase-app.ts | 9 +- src/project-management/android-app.ts | 34 +- src/project-management/app-metadata.ts | 92 ++++ src/project-management/index.ts | 396 ++---------------- src/project-management/ios-app.ts | 26 +- ...project-management-api-request-internal.ts | 10 +- src/project-management/project-management.ts | 15 +- test/unit/index.spec.ts | 1 + .../project-management/android-app.spec.ts | 8 +- test/unit/project-management/index.spec.ts | 75 ++++ test/unit/project-management/ios-app.spec.ts | 6 +- .../project-management-api-request.spec.ts | 5 +- .../project-management.spec.ts | 10 +- 17 files changed, 430 insertions(+), 465 deletions(-) create mode 100644 etc/firebase-admin.project-management.api.md create mode 100644 src/project-management/app-metadata.ts create mode 100644 test/unit/project-management/index.spec.ts diff --git a/etc/firebase-admin.api.md b/etc/firebase-admin.api.md index be4a99b44b..3017438249 100644 --- a/etc/firebase-admin.api.md +++ b/etc/firebase-admin.api.md @@ -607,67 +607,42 @@ export namespace messaging { } // @public -export function projectManagement(app?: app.App): projectManagement.ProjectManagement; +export function projectManagement(app?: App): projectManagement.ProjectManagement; // @public (undocumented) export namespace projectManagement { - export interface AndroidApp { - addShaCertificate(certificateToAdd: ShaCertificate): Promise; - // (undocumented) - appId: string; - deleteShaCertificate(certificateToRemove: ShaCertificate): Promise; - getConfig(): Promise; - getMetadata(): Promise; - getShaCertificates(): Promise; - setDisplayName(newDisplayName: string): Promise; - } - export interface AndroidAppMetadata extends AppMetadata { - packageName: string; - // (undocumented) - platform: AppPlatform.ANDROID; - } - export interface AppMetadata { - appId: string; - displayName?: string; - platform: AppPlatform; - projectId: string; - resourceName: string; - } - export enum AppPlatform { - ANDROID = "ANDROID", - IOS = "IOS", - PLATFORM_UNKNOWN = "PLATFORM_UNKNOWN" - } - export interface IosApp { - // (undocumented) - appId: string; - getConfig(): Promise; - getMetadata(): Promise; - setDisplayName(newDisplayName: string): Promise; - } - export interface IosAppMetadata extends AppMetadata { - bundleId: string; - // (undocumented) - platform: AppPlatform.IOS; - } - export interface ProjectManagement { - androidApp(appId: string): AndroidApp; - // (undocumented) - app: app.App; - createAndroidApp(packageName: string, displayName?: string): Promise; - createIosApp(bundleId: string, displayName?: string): Promise; - iosApp(appId: string): IosApp; - listAndroidApps(): Promise; - listAppMetadata(): Promise; - listIosApps(): Promise; - setDisplayName(newDisplayName: string): Promise; - shaCertificate(shaHash: string): ShaCertificate; - } - export interface ShaCertificate { - certType: ('sha1' | 'sha256'); - resourceName?: string; - shaHash: string; - } + // Warning: (ae-forgotten-export) The symbol "AndroidApp" needs to be exported by the entry point default-namespace.d.ts + // + // (undocumented) + export type AndroidApp = AndroidApp; + // Warning: (ae-forgotten-export) The symbol "AndroidAppMetadata" needs to be exported by the entry point default-namespace.d.ts + // + // (undocumented) + export type AndroidAppMetadata = AndroidAppMetadata; + // Warning: (ae-forgotten-export) The symbol "AppMetadata" needs to be exported by the entry point default-namespace.d.ts + // + // (undocumented) + export type AppMetadata = AppMetadata; + // Warning: (ae-forgotten-export) The symbol "AppPlatform" needs to be exported by the entry point default-namespace.d.ts + // + // (undocumented) + export type AppPlatform = AppPlatform; + // Warning: (ae-forgotten-export) The symbol "IosApp" needs to be exported by the entry point default-namespace.d.ts + // + // (undocumented) + export type IosApp = IosApp; + // Warning: (ae-forgotten-export) The symbol "IosAppMetadata" needs to be exported by the entry point default-namespace.d.ts + // + // (undocumented) + export type IosAppMetadata = IosAppMetadata; + // Warning: (ae-forgotten-export) The symbol "ProjectManagement" needs to be exported by the entry point default-namespace.d.ts + // + // (undocumented) + export type ProjectManagement = ProjectManagement; + // Warning: (ae-forgotten-export) The symbol "ShaCertificate" needs to be exported by the entry point default-namespace.d.ts + // + // (undocumented) + export type ShaCertificate = ShaCertificate; } // @public (undocumented) diff --git a/etc/firebase-admin.project-management.api.md b/etc/firebase-admin.project-management.api.md new file mode 100644 index 0000000000..f8d3ebcf34 --- /dev/null +++ b/etc/firebase-admin.project-management.api.md @@ -0,0 +1,115 @@ +## API Report File for "firebase-admin.project-management" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { Agent } from 'http'; + +// @public (undocumented) +export class AndroidApp { + addShaCertificate(certificateToAdd: ShaCertificate): Promise; + // (undocumented) + readonly appId: string; + deleteShaCertificate(certificateToDelete: ShaCertificate): Promise; + getConfig(): Promise; + getMetadata(): Promise; + getShaCertificates(): Promise; + setDisplayName(newDisplayName: string): Promise; +} + +// @public +export interface AndroidAppMetadata extends AppMetadata { + packageName: string; + // (undocumented) + platform: AppPlatform.ANDROID; +} + +// @public +export interface AppMetadata { + appId: string; + displayName?: string; + platform: AppPlatform; + projectId: string; + resourceName: string; +} + +// @public +export enum AppPlatform { + ANDROID = "ANDROID", + IOS = "IOS", + PLATFORM_UNKNOWN = "PLATFORM_UNKNOWN" +} + +// Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts +// +// @public (undocumented) +export function getProjectManagement(app?: App): ProjectManagement; + +// @public (undocumented) +export class IosApp { + // (undocumented) + readonly appId: string; + getConfig(): Promise; + getMetadata(): Promise; + setDisplayName(newDisplayName: string): Promise; +} + +// @public +export interface IosAppMetadata extends AppMetadata { + bundleId: string; + // (undocumented) + platform: AppPlatform.IOS; +} + +// @public +export class ProjectManagement { + androidApp(appId: string): AndroidApp; + // (undocumented) + readonly app: App; + createAndroidApp(packageName: string, displayName?: string): Promise; + createIosApp(bundleId: string, displayName?: string): Promise; + iosApp(appId: string): IosApp; + listAndroidApps(): Promise; + listAppMetadata(): Promise; + listIosApps(): Promise; + setDisplayName(newDisplayName: string): Promise; + shaCertificate(shaHash: string): ShaCertificate; + } + +// @public +export function projectManagement(app?: App): projectManagement.ProjectManagement; + +// @public (undocumented) +export namespace projectManagement { + // (undocumented) + export type AndroidApp = AndroidApp; + // (undocumented) + export type AndroidAppMetadata = AndroidAppMetadata; + // (undocumented) + export type AppMetadata = AppMetadata; + // (undocumented) + export type AppPlatform = AppPlatform; + // (undocumented) + export type IosApp = IosApp; + // (undocumented) + export type IosAppMetadata = IosAppMetadata; + // (undocumented) + export type ProjectManagement = ProjectManagement; + // (undocumented) + export type ShaCertificate = ShaCertificate; +} + +// @public +export class ShaCertificate { + readonly certType: ('sha1' | 'sha256'); + // (undocumented) + readonly resourceName?: string | undefined; + // (undocumented) + readonly shaHash: string; +} + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/generate-reports.js b/generate-reports.js index 3184a3845f..aaa4094818 100644 --- a/generate-reports.js +++ b/generate-reports.js @@ -40,6 +40,7 @@ const entryPoints = { 'firebase-admin/firestore': './lib/firestore/index.d.ts', 'firebase-admin/instance-id': './lib/instance-id/index.d.ts', 'firebase-admin/messaging': './lib/messaging/index.d.ts', + 'firebase-admin/project-management': './lib/project-management/index.d.ts', 'firebase-admin/security-rules': './lib/security-rules/index.d.ts', 'firebase-admin/remote-config': './lib/remote-config/index.d.ts', }; diff --git a/gulpfile.js b/gulpfile.js index 1f1bff4f6c..413c530e79 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -93,6 +93,7 @@ gulp.task('compile', function() { 'lib/firestore/*.d.ts', 'lib/instance-id/*.d.ts', 'lib/messaging/*.d.ts', + 'lib/project-management/*.d.ts', 'lib/security-rules/*.d.ts', 'lib/remote-config/*.d.ts', '!lib/utils/index.d.ts', diff --git a/src/app/firebase-app.ts b/src/app/firebase-app.ts index 005061de09..95ca40c2bc 100644 --- a/src/app/firebase-app.ts +++ b/src/app/firebase-app.ts @@ -30,7 +30,7 @@ import { Storage } from '../storage/storage'; import { Database } from '../database/index'; import { Firestore } from '../firestore/index'; import { InstanceId } from '../instance-id/index'; -import { ProjectManagement } from '../project-management/project-management'; +import { ProjectManagement } from '../project-management/index'; import { SecurityRules } from '../security-rules/index'; import { RemoteConfig } from '../remote-config/index'; @@ -343,11 +343,8 @@ export class FirebaseApp implements app.App { * @return The ProjectManagement service instance of this app. */ public projectManagement(): ProjectManagement { - return this.ensureService_('project-management', () => { - const projectManagementService: typeof ProjectManagement = - require('../project-management/project-management').ProjectManagement; - return new projectManagementService(this); - }); + const fn = require('../project-management/index').getProjectManagement; + return fn(this); } /** diff --git a/src/project-management/android-app.ts b/src/project-management/android-app.ts index 8afba57094..808c25c7e4 100644 --- a/src/project-management/android-app.ts +++ b/src/project-management/android-app.ts @@ -17,16 +17,34 @@ import { FirebaseProjectManagementError } from '../utils/error'; import * as validator from '../utils/validator'; import { ProjectManagementRequestHandler, assertServerResponse } from './project-management-api-request-internal'; -import { projectManagement } from './index'; +import { AppMetadata, AppPlatform } from './app-metadata'; -import AndroidAppInterface = projectManagement.AndroidApp; -import AndroidAppMetadata = projectManagement.AndroidAppMetadata; -import AppPlatform = projectManagement.AppPlatform; -import ShaCertificateInterface = projectManagement.ShaCertificate; -export class AndroidApp implements AndroidAppInterface { +/** + * Metadata about a Firebase Android App. + */ +export interface AndroidAppMetadata extends AppMetadata { + + platform: AppPlatform.ANDROID; + + /** + * The canonical package name of the Android App, as would appear in the Google Play Developer + * Console. + * + * @example + * ```javascript + * var packageName = androidAppMetadata.packageName; + * ``` + */ + packageName: string; +} + +export class AndroidApp { private readonly resourceName: string; + /** + * @internal + */ constructor( public readonly appId: string, private readonly requestHandler: ProjectManagementRequestHandler) { @@ -184,7 +202,7 @@ export class AndroidApp implements AndroidAppInterface { * Do not call this constructor directly. Instead, use * [`projectManagement.shaCertificate()`](projectManagement.ProjectManagement#shaCertificate). */ -export class ShaCertificate implements ShaCertificateInterface { +export class ShaCertificate { /** * The SHA certificate type. * @@ -210,6 +228,8 @@ export class ShaCertificate implements ShaCertificateInterface { * ```javascript * var resourceName = shaCertificate.resourceName; * ``` + * + * @internal */ constructor(public readonly shaHash: string, public readonly resourceName?: string) { if (/^[a-fA-F0-9]{40}$/.test(shaHash)) { diff --git a/src/project-management/app-metadata.ts b/src/project-management/app-metadata.ts new file mode 100644 index 0000000000..8fd69255d2 --- /dev/null +++ b/src/project-management/app-metadata.ts @@ -0,0 +1,92 @@ +/*! + * Copyright 2021 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + */ + +/** + * Platforms with which a Firebase App can be associated. + */ +export enum AppPlatform { + /** + * Unknown state. This is only used for distinguishing unset values. + */ + PLATFORM_UNKNOWN = 'PLATFORM_UNKNOWN', + + /** + * The Firebase App is associated with iOS. + */ + IOS = 'IOS', + + /** + * The Firebase App is associated with Android. + */ + ANDROID = 'ANDROID', +} + +/** + * Metadata about a Firebase app. + */ +export interface AppMetadata { + /** + * The globally unique, Firebase-assigned identifier of the app. + * + * @example + * ```javascript + * var appId = appMetadata.appId; + * ``` + */ + appId: string; + + /** + * The optional user-assigned display name of the app. + * + * @example + * ```javascript + * var displayName = appMetadata.displayName; + * ``` + */ + displayName?: string; + + /** + * The development platform of the app. Supporting Android and iOS app platforms. + * + * @example + * ```javascript + * var platform = AppPlatform.ANDROID; + * ``` + */ + platform: AppPlatform; + + /** + * The globally unique, user-assigned ID of the parent project for the app. + * + * @example + * ```javascript + * var projectId = appMetadata.projectId; + * ``` + */ + projectId: string; + + /** + * The fully-qualified resource name that identifies this app. + * + * This is useful when manually constructing requests for Firebase's public API. + * + * @example + * ```javascript + * var resourceName = androidAppMetadata.resourceName; + * ``` + */ + resourceName: string; +} diff --git a/src/project-management/index.ts b/src/project-management/index.ts index 2c905d6c22..26e7f7aa5e 100644 --- a/src/project-management/index.ts +++ b/src/project-management/index.ts @@ -14,7 +14,23 @@ * limitations under the License. */ -import { app } from '../firebase-namespace-api'; +import { App, getApp } from '../app'; +import { FirebaseApp } from '../app/firebase-app'; +import { ProjectManagement } from './project-management'; + +export { AppMetadata, AppPlatform } from './app-metadata'; +export { ProjectManagement } from './project-management'; +export { AndroidApp, AndroidAppMetadata, ShaCertificate } from './android-app'; +export { IosApp, IosAppMetadata } from './ios-app'; + +export function getProjectManagement(app?: App): ProjectManagement { + if (typeof app === 'undefined') { + app = getApp(); + } + + const firebaseApp: FirebaseApp = app as FirebaseApp; + return firebaseApp.getOrInitService('projectManagement', (app) => new ProjectManagement(app)); +} /** * Gets the {@link projectManagement.ProjectManagement @@ -44,361 +60,31 @@ import { app } from '../firebase-namespace-api'; * @return The default `ProjectManagement` service if no app is provided or the * `ProjectManagement` service associated with the provided app. */ -export declare function projectManagement(app?: app.App): projectManagement.ProjectManagement; +export declare function projectManagement(app?: App): projectManagement.ProjectManagement; + +import { + AppMetadata as TAppMetadata, + AppPlatform as TAppPlatform, +} from './app-metadata'; +import { ProjectManagement as TProjectManagement } from './project-management'; +import { + AndroidApp as TAndroidApp, + AndroidAppMetadata as TAndroidAppMetadata, + ShaCertificate as TShaCertificate, +} from './android-app'; +import { + IosApp as TIosApp, + IosAppMetadata as TIosAppMetadata, +} from './ios-app'; /* eslint-disable @typescript-eslint/no-namespace */ export namespace projectManagement { - /** - * Metadata about a Firebase Android App. - */ - export interface AndroidAppMetadata extends AppMetadata { - - platform: AppPlatform.ANDROID; - - /** - * The canonical package name of the Android App, as would appear in the Google Play Developer - * Console. - * - * @example - * ```javascript - * var packageName = androidAppMetadata.packageName; - * ``` - */ - packageName: string; - } - - /** - * Metadata about a Firebase app. - */ - export interface AppMetadata { - /** - * The globally unique, Firebase-assigned identifier of the app. - * - * @example - * ```javascript - * var appId = appMetadata.appId; - * ``` - */ - appId: string; - - /** - * The optional user-assigned display name of the app. - * - * @example - * ```javascript - * var displayName = appMetadata.displayName; - * ``` - */ - displayName?: string; - - /** - * The development platform of the app. Supporting Android and iOS app platforms. - * - * @example - * ```javascript - * var platform = AppPlatform.ANDROID; - * ``` - */ - platform: AppPlatform; - - /** - * The globally unique, user-assigned ID of the parent project for the app. - * - * @example - * ```javascript - * var projectId = appMetadata.projectId; - * ``` - */ - projectId: string; - - /** - * The fully-qualified resource name that identifies this app. - * - * This is useful when manually constructing requests for Firebase's public API. - * - * @example - * ```javascript - * var resourceName = androidAppMetadata.resourceName; - * ``` - */ - resourceName: string; - } - - /** - * Platforms with which a Firebase App can be associated. - */ - export enum AppPlatform { - /** - * Unknown state. This is only used for distinguishing unset values. - */ - PLATFORM_UNKNOWN = 'PLATFORM_UNKNOWN', - - /** - * The Firebase App is associated with iOS. - */ - IOS = 'IOS', - - /** - * The Firebase App is associated with Android. - */ - ANDROID = 'ANDROID', - } - - /** - * Metadata about a Firebase iOS App. - */ - export interface IosAppMetadata extends AppMetadata { - platform: AppPlatform.IOS; - - /** - * The canonical bundle ID of the iOS App as it would appear in the iOS App Store. - * - * @example - * ```javascript - * var bundleId = iosAppMetadata.bundleId; - *``` - */ - bundleId: string; - } - - /** - * A reference to a Firebase Android app. - * - * Do not call this constructor directly. Instead, use - * [`projectManagement.androidApp()`](projectManagement.ProjectManagement#androidApp). - */ - export interface AndroidApp { - appId: string; - - /** - * Retrieves metadata about this Android app. - * - * @return A promise that resolves to the retrieved metadata about this Android app. - */ - getMetadata(): Promise; - - /** - * Sets the optional user-assigned display name of the app. - * - * @param newDisplayName The new display name to set. - * - * @return A promise that resolves when the display name has been set. - */ - setDisplayName(newDisplayName: string): Promise; - - /** - * Gets the list of SHA certificates associated with this Android app in Firebase. - * - * @return The list of SHA-1 and SHA-256 certificates associated with this Android app in - * Firebase. - */ - getShaCertificates(): Promise; - - /** - * Adds the given SHA certificate to this Android app. - * - * @param certificateToAdd The SHA certificate to add. - * - * @return A promise that resolves when the given certificate - * has been added to the Android app. - */ - addShaCertificate(certificateToAdd: ShaCertificate): Promise; - - /** - * Deletes the specified SHA certificate from this Android app. - * - * @param certificateToDelete The SHA certificate to delete. - * - * @return A promise that resolves when the specified - * certificate has been removed from the Android app. - */ - deleteShaCertificate(certificateToRemove: ShaCertificate): Promise; - - /** - * Gets the configuration artifact associated with this app. - * - * @return A promise that resolves to the Android app's - * Firebase config file, in UTF-8 string format. This string is typically - * intended to be written to a JSON file that gets shipped with your Android - * app. - */ - getConfig(): Promise; - } - - /** - * A reference to a Firebase iOS app. - * - * Do not call this constructor directly. Instead, use - * [`projectManagement.iosApp()`](projectManagement.ProjectManagement#iosApp). - */ - export interface IosApp { - appId: string; - - /** - * Retrieves metadata about this iOS app. - * - * @return {!Promise} A promise that - * resolves to the retrieved metadata about this iOS app. - */ - getMetadata(): Promise; - - /** - * Sets the optional user-assigned display name of the app. - * - * @param newDisplayName The new display name to set. - * - * @return A promise that resolves when the display name has - * been set. - */ - setDisplayName(newDisplayName: string): Promise; - - /** - * Gets the configuration artifact associated with this app. - * - * @return A promise that resolves to the iOS app's Firebase - * config file, in UTF-8 string format. This string is typically intended to - * be written to a plist file that gets shipped with your iOS app. - */ - getConfig(): Promise; - } - - /** - * A SHA-1 or SHA-256 certificate. - * - * Do not call this constructor directly. Instead, use - * [`projectManagement.shaCertificate()`](projectManagement.ProjectManagement#shaCertificate). - */ - export interface ShaCertificate { - - /** - * The SHA certificate type. - * - * @example - * ```javascript - * var certType = shaCertificate.certType; - * ``` - */ - certType: ('sha1' | 'sha256'); - - /** - * The SHA-1 or SHA-256 hash for this certificate. - * - * @example - * ```javascript - * var shaHash = shaCertificate.shaHash; - * ``` - */ - shaHash: string; - - /** - * The fully-qualified resource name that identifies this sha-key. - * - * This is useful when manually constructing requests for Firebase's public API. - * - * @example - * ```javascript - * var resourceName = shaCertificate.resourceName; - * ``` - */ - resourceName?: string; - } - - /** - * The Firebase ProjectManagement service interface. - * - * Do not call this constructor directly. Instead, use - * [`admin.projectManagement()`](projectManagement#projectManagement). - */ - export interface ProjectManagement { - app: app.App; - - /** - * Lists up to 100 Firebase apps associated with this Firebase project. - * - * @return A promise that resolves to the metadata list of the apps. - */ - listAppMetadata(): Promise; - - /** - * Lists up to 100 Firebase Android apps associated with this Firebase project. - * - * @return The list of Android apps. - */ - listAndroidApps(): Promise; - - /** - * Lists up to 100 Firebase iOS apps associated with this Firebase project. - * - * @return The list of iOS apps. - */ - listIosApps(): Promise; - - /** - * Creates an `AndroidApp` object, referencing the specified Android app within - * this Firebase project. - * - * This method does not perform an RPC. - * - * @param appId The `appId` of the Android app to reference. - * - * @return An `AndroidApp` object that references the specified Firebase Android app. - */ - androidApp(appId: string): AndroidApp; - - /** - * Update the display name of this Firebase project. - * - * @param newDisplayName The new display name to be updated. - * - * @return A promise that resolves when the project display name has been updated. - */ - setDisplayName(newDisplayName: string): Promise; - - /** - * Creates an `iOSApp` object, referencing the specified iOS app within - * this Firebase project. - * - * This method does not perform an RPC. - * - * @param appId The `appId` of the iOS app to reference. - * - * @return An `iOSApp` object that references the specified Firebase iOS app. - */ - iosApp(appId: string): IosApp; - - /** - * Creates a `ShaCertificate` object. - * - * This method does not perform an RPC. - * - * @param shaHash The SHA-1 or SHA-256 hash for this certificate. - * - * @return A `ShaCertificate` object contains the specified SHA hash. - */ - shaCertificate(shaHash: string): ShaCertificate; - - /** - * Creates a new Firebase Android app associated with this Firebase project. - * - * @param packageName The canonical package name of the Android App, - * as would appear in the Google Play Developer Console. - * @param displayName An optional user-assigned display name for this - * new app. - * - * @return A promise that resolves to the newly created Android app. - */ - createAndroidApp( - packageName: string, displayName?: string): Promise; - - /** - * Creates a new Firebase iOS app associated with this Firebase project. - * - * @param bundleId The iOS app bundle ID to use for this new app. - * @param displayName An optional user-assigned display name for this - * new app. - * - * @return A promise that resolves to the newly created iOS app. - */ - createIosApp(bundleId: string, displayName?: string): Promise; - } + export type AppMetadata = TAppMetadata; + export type AppPlatform = TAppPlatform; + export type ProjectManagement = TProjectManagement; + export type IosApp = TIosApp; + export type IosAppMetadata = TIosAppMetadata; + export type AndroidApp = TAndroidApp; + export type AndroidAppMetadata = TAndroidAppMetadata; + export type ShaCertificate = TShaCertificate; } diff --git a/src/project-management/ios-app.ts b/src/project-management/ios-app.ts index b29af6326f..9d01ce23c6 100644 --- a/src/project-management/ios-app.ts +++ b/src/project-management/ios-app.ts @@ -17,15 +17,31 @@ import { FirebaseProjectManagementError } from '../utils/error'; import * as validator from '../utils/validator'; import { ProjectManagementRequestHandler, assertServerResponse } from './project-management-api-request-internal'; -import { projectManagement } from './index'; +import { AppMetadata, AppPlatform } from './app-metadata'; -import IosAppInterface = projectManagement.IosApp; -import IosAppMetadata = projectManagement.IosAppMetadata; -import AppPlatform = projectManagement.AppPlatform; +/** + * Metadata about a Firebase iOS App. + */ +export interface IosAppMetadata extends AppMetadata { + platform: AppPlatform.IOS; -export class IosApp implements IosAppInterface { + /** + * The canonical bundle ID of the iOS App as it would appear in the iOS App Store. + * + * @example + * ```javascript + * var bundleId = iosAppMetadata.bundleId; + *``` + */ + bundleId: string; +} + +export class IosApp { private readonly resourceName: string; + /** + * @internal + */ constructor( public readonly appId: string, private readonly requestHandler: ProjectManagementRequestHandler) { diff --git a/src/project-management/project-management-api-request-internal.ts b/src/project-management/project-management-api-request-internal.ts index a24111f424..4f5b876435 100644 --- a/src/project-management/project-management-api-request-internal.ts +++ b/src/project-management/project-management-api-request-internal.ts @@ -14,14 +14,16 @@ * limitations under the License. */ +import { App } from '../app'; import { FirebaseApp } from '../app/firebase-app'; import { AuthorizedHttpClient, HttpError, HttpMethod, HttpRequestConfig, ExponentialBackoffPoller, } from '../utils/api-request'; import { FirebaseProjectManagementError, ProjectManagementErrorCode } from '../utils/error'; +import { getSdkVersion } from '../utils/index'; import * as validator from '../utils/validator'; import { ShaCertificate } from './android-app'; -import { getSdkVersion } from '../utils/index'; + /** Project management backend host and port. */ const PROJECT_MANAGEMENT_HOST_AND_PORT = 'firebase.googleapis.com:443'; @@ -112,11 +114,11 @@ export class ProjectManagementRequestHandler { } /** - * @param {FirebaseApp} app The app used to fetch access tokens to sign API requests. + * @param app The app used to fetch access tokens to sign API requests. * @constructor */ - constructor(app: FirebaseApp) { - this.httpClient = new AuthorizedHttpClient(app); + constructor(app: App) { + this.httpClient = new AuthorizedHttpClient(app as FirebaseApp); } /** diff --git a/src/project-management/project-management.ts b/src/project-management/project-management.ts index 1a7ac03733..5b0d691823 100644 --- a/src/project-management/project-management.ts +++ b/src/project-management/project-management.ts @@ -14,18 +14,14 @@ * limitations under the License. */ -import { FirebaseApp } from '../app/firebase-app'; +import { App } from '../app'; import { FirebaseProjectManagementError } from '../utils/error'; import * as utils from '../utils/index'; import * as validator from '../utils/validator'; import { AndroidApp, ShaCertificate } from './android-app'; import { IosApp } from './ios-app'; import { ProjectManagementRequestHandler, assertServerResponse } from './project-management-api-request-internal'; -import { projectManagement } from './index'; - -import AppMetadata = projectManagement.AppMetadata; -import AppPlatform = projectManagement.AppPlatform; -import ProjectManagementInterface = projectManagement.ProjectManagement; +import { AppMetadata, AppPlatform } from './app-metadata'; /** * The Firebase ProjectManagement service interface. @@ -33,16 +29,17 @@ import ProjectManagementInterface = projectManagement.ProjectManagement; * Do not call this constructor directly. Instead, use * [`admin.projectManagement()`](projectManagement#projectManagement). */ -export class ProjectManagement implements ProjectManagementInterface { +export class ProjectManagement { private readonly requestHandler: ProjectManagementRequestHandler; private projectId: string; /** - * @param {object} app The app for this ProjectManagement service. + * @param app The app for this ProjectManagement service. * @constructor + * @internal */ - constructor(readonly app: FirebaseApp) { + constructor(readonly app: App) { if (!validator.isNonNullObject(app) || !('options' in app)) { throw new FirebaseProjectManagementError( 'invalid-argument', diff --git a/test/unit/index.spec.ts b/test/unit/index.spec.ts index 2a07381b09..7448610fd1 100644 --- a/test/unit/index.spec.ts +++ b/test/unit/index.spec.ts @@ -67,6 +67,7 @@ import './instance-id/instance-id.spec'; import './instance-id/instance-id-request.spec'; // ProjectManagement +import './project-management/index.spec'; import './project-management/project-management.spec'; import './project-management/project-management-api-request.spec'; import './project-management/android-app.spec'; diff --git a/test/unit/project-management/android-app.spec.ts b/test/unit/project-management/android-app.spec.ts index 1c2d88032f..94ccacbbd3 100644 --- a/test/unit/project-management/android-app.spec.ts +++ b/test/unit/project-management/android-app.spec.ts @@ -20,17 +20,15 @@ import * as chai from 'chai'; import * as _ from 'lodash'; import * as sinon from 'sinon'; import { FirebaseApp } from '../../../src/app/firebase-app'; -import { AndroidApp, ShaCertificate } from '../../../src/project-management/android-app'; import { ProjectManagementRequestHandler } from '../../../src/project-management/project-management-api-request-internal'; import { deepCopy } from '../../../src/utils/deep-copy'; import { FirebaseProjectManagementError } from '../../../src/utils/error'; import * as mocks from '../../resources/mocks'; -import { projectManagement } from '../../../src/project-management/index'; - -import AndroidAppMetadata = projectManagement.AndroidAppMetadata; -import AppPlatform = projectManagement.AppPlatform; +import { + AndroidApp, AndroidAppMetadata, AppPlatform, ShaCertificate, +} from '../../../src/project-management/index'; const expect = chai.expect; diff --git a/test/unit/project-management/index.spec.ts b/test/unit/project-management/index.spec.ts new file mode 100644 index 0000000000..6848494c96 --- /dev/null +++ b/test/unit/project-management/index.spec.ts @@ -0,0 +1,75 @@ +/*! + * @license + * Copyright 2021 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file 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. + */ + +'use strict'; + +import * as chai from 'chai'; +import * as sinonChai from 'sinon-chai'; +import * as chaiAsPromised from 'chai-as-promised'; + +import * as mocks from '../../resources/mocks'; +import { App } from '../../../src/app/index'; +import { getProjectManagement, ProjectManagement } from '../../../src/project-management/index'; + +chai.should(); +chai.use(sinonChai); +chai.use(chaiAsPromised); + +const expect = chai.expect; + +describe('ProjectManagement', () => { + let mockApp: App; + let mockCredentialApp: App; + + const noProjectIdError = 'Failed to determine project ID. Initialize the SDK ' + + 'with service account credentials, or set project ID as an app option. Alternatively, set the ' + + 'GOOGLE_CLOUD_PROJECT environment variable.'; + + beforeEach(() => { + mockApp = mocks.app(); + mockCredentialApp = mocks.mockCredentialApp(); + }); + + describe('getProjectManagement()', () => { + it('should throw when default app is not available', () => { + expect(() => { + return getProjectManagement(); + }).to.throw('The default Firebase app does not exist.'); + }); + + it('should reject given an invalid credential without project ID', () => { + // Project ID not set in the environment. + delete process.env.GOOGLE_CLOUD_PROJECT; + delete process.env.GCLOUD_PROJECT; + const client = getProjectManagement(mockCredentialApp); + return client.listAndroidApps() + .should.eventually.rejectedWith(noProjectIdError); + }); + + it('should not throw given a valid app', () => { + expect(() => { + return getProjectManagement(mockApp); + }).not.to.throw(); + }); + + it('should return the same instance for a given app instance', () => { + const client1: ProjectManagement = getProjectManagement(mockApp); + const client2: ProjectManagement = getProjectManagement(mockApp); + expect(client1).to.equal(client2); + }); + }); +}); diff --git a/test/unit/project-management/ios-app.spec.ts b/test/unit/project-management/ios-app.spec.ts index 53966696d1..f250ed5f10 100644 --- a/test/unit/project-management/ios-app.spec.ts +++ b/test/unit/project-management/ios-app.spec.ts @@ -20,17 +20,13 @@ import * as chai from 'chai'; import * as _ from 'lodash'; import * as sinon from 'sinon'; import { FirebaseApp } from '../../../src/app/firebase-app'; -import { IosApp } from '../../../src/project-management/ios-app'; import { ProjectManagementRequestHandler } from '../../../src/project-management/project-management-api-request-internal'; import { deepCopy } from '../../../src/utils/deep-copy'; import { FirebaseProjectManagementError } from '../../../src/utils/error'; import * as mocks from '../../resources/mocks'; -import { projectManagement } from '../../../src/project-management/index'; - -import IosAppMetadata = projectManagement.IosAppMetadata; -import AppPlatform = projectManagement.AppPlatform; +import { AppPlatform, IosApp, IosAppMetadata } from '../../../src/project-management/index'; const expect = chai.expect; diff --git a/test/unit/project-management/project-management-api-request.spec.ts b/test/unit/project-management/project-management-api-request.spec.ts index 0cbd7929cb..772a33ad4c 100644 --- a/test/unit/project-management/project-management-api-request.spec.ts +++ b/test/unit/project-management/project-management-api-request.spec.ts @@ -29,10 +29,7 @@ import { HttpClient } from '../../../src/utils/api-request'; import * as mocks from '../../resources/mocks'; import * as utils from '../utils'; import { getSdkVersion } from '../../../src/utils/index'; -import { ShaCertificate } from '../../../src/project-management/android-app'; -import { projectManagement } from '../../../src/project-management/index'; - -import AppPlatform = projectManagement.AppPlatform; +import { AppPlatform, ShaCertificate } from '../../../src/project-management/index'; chai.should(); chai.use(sinonChai); diff --git a/test/unit/project-management/project-management.spec.ts b/test/unit/project-management/project-management.spec.ts index a755a5b283..b818bdb1c8 100644 --- a/test/unit/project-management/project-management.spec.ts +++ b/test/unit/project-management/project-management.spec.ts @@ -20,18 +20,14 @@ import * as chai from 'chai'; import * as _ from 'lodash'; import * as sinon from 'sinon'; import { FirebaseApp } from '../../../src/app/firebase-app'; -import { AndroidApp } from '../../../src/project-management/android-app'; -import { ProjectManagement } from '../../../src/project-management/project-management'; import { ProjectManagementRequestHandler } from '../../../src/project-management/project-management-api-request-internal'; import { FirebaseProjectManagementError } from '../../../src/utils/error'; import * as mocks from '../../resources/mocks'; -import { projectManagement } from '../../../src/project-management/index'; - -import AppMetadata = projectManagement.AppMetadata; -import AppPlatform = projectManagement.AppPlatform; -import IosApp = projectManagement.IosApp; +import { + AndroidApp, AppMetadata, AppPlatform, IosApp, ProjectManagement, +} from '../../../src/project-management/index'; const expect = chai.expect;