From 2039a54b2d3e7a349c529e5deeffdae27735d7f2 Mon Sep 17 00:00:00 2001 From: Hiranya Jayathilaka Date: Tue, 12 Jan 2021 17:15:17 -0800 Subject: [PATCH 1/4] feat: Added firebase-admin/app submodule --- api-extractor.json | 4 +- etc/firebase-admin.api.md | 3 + gulpfile.js | 3 +- src/{ => app}/core.ts | 2 +- src/{ => app}/firebase-app.ts | 56 +++--- src/{ => app}/firebase-namespace.ts | 52 +++--- src/app/index.ts | 18 ++ src/app/lifecycle.ts | 45 +++++ src/auth/auth-api-request.ts | 2 +- src/auth/auth.ts | 2 +- src/auth/tenant-manager.ts | 2 +- src/auth/token-generator.ts | 2 +- src/auth/token-verifier.ts | 4 +- src/database/database-internal.ts | 2 +- ...-namespace.d.ts => default-namespace.d.ts} | 0 src/default-namespace.ts | 4 +- src/firebase-namespace-api.ts | 4 +- src/firestore/firestore-internal.ts | 2 +- src/index.d.ts | 2 +- .../instance-id-request-internal.ts | 2 +- src/instance-id/instance-id.ts | 2 +- .../machine-learning-api-client.ts | 2 +- src/machine-learning/machine-learning.ts | 2 +- .../messaging-api-request-internal.ts | 2 +- src/messaging/messaging.ts | 2 +- ...project-management-api-request-internal.ts | 2 +- src/project-management/project-management.ts | 2 +- .../remote-config-api-client-internal.ts | 2 +- src/remote-config/remote-config.ts | 2 +- .../security-rules-api-client-internal.ts | 2 +- src/security-rules/security-rules.ts | 2 +- src/storage/storage.ts | 2 +- src/utils/api-request.ts | 2 +- test/resources/mocks.ts | 4 +- test/unit/{ => app}/firebase-app.spec.ts | 40 ++-- .../unit/{ => app}/firebase-namespace.spec.ts | 48 ++--- test/unit/app/index.spec.ts | 176 ++++++++++++++++++ test/unit/auth/auth-api-request.spec.ts | 2 +- test/unit/auth/auth.spec.ts | 2 +- test/unit/auth/tenant-manager.spec.ts | 2 +- test/unit/auth/token-generator.spec.ts | 2 +- test/unit/auth/token-verifier.spec.ts | 4 +- test/unit/database/database.spec.ts | 2 +- test/unit/firebase.spec.ts | 2 +- test/unit/firestore/firestore.spec.ts | 2 +- test/unit/index.spec.ts | 5 +- .../instance-id/instance-id-request.spec.ts | 2 +- test/unit/instance-id/instance-id.spec.ts | 2 +- .../machine-learning-api-client.spec.ts | 2 +- .../machine-learning/machine-learning.spec.ts | 2 +- test/unit/messaging/messaging.spec.ts | 2 +- .../project-management/android-app.spec.ts | 2 +- test/unit/project-management/ios-app.spec.ts | 2 +- .../project-management-api-request.spec.ts | 2 +- .../project-management.spec.ts | 2 +- .../remote-config-api-client.spec.ts | 2 +- test/unit/remote-config/remote-config.spec.ts | 2 +- .../security-rules-api-client.spec.ts | 2 +- .../security-rules/security-rules.spec.ts | 2 +- test/unit/storage/storage.spec.ts | 2 +- test/unit/utils.ts | 4 +- test/unit/utils/api-request.spec.ts | 2 +- test/unit/utils/index.spec.ts | 2 +- tsconfig.json | 1 + 64 files changed, 405 insertions(+), 160 deletions(-) rename src/{ => app}/core.ts (98%) rename src/{ => app}/firebase-app.ts (89%) rename src/{ => app}/firebase-namespace.ts (90%) create mode 100644 src/app/index.ts create mode 100644 src/app/lifecycle.ts rename src/{firebase-namespace.d.ts => default-namespace.d.ts} (100%) rename test/unit/{ => app}/firebase-app.spec.ts (97%) rename test/unit/{ => app}/firebase-namespace.spec.ts (95%) create mode 100644 test/unit/app/index.spec.ts diff --git a/api-extractor.json b/api-extractor.json index 140b645cfe..6f5a35e026 100644 --- a/api-extractor.json +++ b/api-extractor.json @@ -45,10 +45,10 @@ * * SUPPORTED TOKENS: , , */ - // We point to the firebase-namespace.d.ts file since index.d.ts uses namespace imports that are + // We point to the default-namespace.d.ts file since index.d.ts uses namespace imports that are // not supported by API Extractor. See https://github.com/microsoft/rushstack/issues/1029 and // https://github.com/microsoft/rushstack/issues/2338. - "mainEntryPointFilePath": "/lib/firebase-namespace.d.ts", + "mainEntryPointFilePath": "/lib/default-namespace.d.ts", /** * A list of NPM package names whose exports should be treated as part of this package. diff --git a/etc/firebase-admin.api.md b/etc/firebase-admin.api.md index a89b4359c8..cb1eb2ea4f 100644 --- a/etc/firebase-admin.api.md +++ b/etc/firebase-admin.api.md @@ -427,6 +427,9 @@ export namespace database { const ServerValue: rtdb.ServerValue; } +// @public (undocumented) +export function deleteApp(app: App): Promise; + // @public export interface FirebaseArrayIndexError { error: FirebaseError; diff --git a/gulpfile.js b/gulpfile.js index 3776404b3e..1e1adcbba6 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -87,6 +87,7 @@ gulp.task('compile', function() { 'lib/**/index.d.ts', 'lib/firebase-namespace-api.d.ts', 'lib/core.d.ts', + 'lib/app/*.d.ts', '!lib/utils/index.d.ts', ]; @@ -107,7 +108,7 @@ gulp.task('compile_test', function() { }); gulp.task('copyTypings', function() { - return gulp.src(['src/index.d.ts', 'src/firebase-namespace.d.ts']) + return gulp.src(['src/index.d.ts', 'src/default-namespace.d.ts']) // Add header .pipe(header(banner)) .pipe(gulp.dest(paths.build)) diff --git a/src/core.ts b/src/app/core.ts similarity index 98% rename from src/core.ts rename to src/app/core.ts index b36cc4bb1d..d377a75d2f 100644 --- a/src/core.ts +++ b/src/app/core.ts @@ -16,7 +16,7 @@ import { Agent } from 'http'; -import { credential } from './credential/index'; +import { credential } from '../credential/index'; /** * Available options to pass to [`initializeApp()`](admin#.initializeApp). diff --git a/src/firebase-app.ts b/src/app/firebase-app.ts similarity index 89% rename from src/firebase-app.ts rename to src/app/firebase-app.ts index fb8ad8b0f5..80f0fb2088 100644 --- a/src/firebase-app.ts +++ b/src/app/firebase-app.ts @@ -15,26 +15,26 @@ * limitations under the License. */ -import { AppOptions, app } from './firebase-namespace-api'; -import { credential, GoogleOAuthAccessToken } from './credential/index'; -import { getApplicationDefault } from './credential/credential-internal'; -import * as validator from './utils/validator'; -import { deepCopy } from './utils/deep-copy'; +import { AppOptions, app } from '../firebase-namespace-api'; +import { credential, GoogleOAuthAccessToken } from '../credential/index'; +import { getApplicationDefault } from '../credential/credential-internal'; +import * as validator from '../utils/validator'; +import { deepCopy } from '../utils/deep-copy'; import { FirebaseNamespaceInternals } from './firebase-namespace'; -import { AppErrorCodes, FirebaseAppError } from './utils/error'; - -import { Auth } from './auth/auth'; -import { MachineLearning } from './machine-learning/machine-learning'; -import { Messaging } from './messaging/messaging'; -import { Storage } from './storage/storage'; -import { database } from './database/index'; -import { DatabaseService } from './database/database-internal'; +import { AppErrorCodes, FirebaseAppError } from '../utils/error'; + +import { Auth } from '../auth/auth'; +import { MachineLearning } from '../machine-learning/machine-learning'; +import { Messaging } from '../messaging/messaging'; +import { Storage } from '../storage/storage'; +import { database } from '../database/index'; +import { DatabaseService } from '../database/database-internal'; import { Firestore } from '@google-cloud/firestore'; -import { FirestoreService } from './firestore/firestore-internal'; -import { InstanceId } from './instance-id/instance-id'; -import { ProjectManagement } from './project-management/project-management'; -import { SecurityRules } from './security-rules/security-rules'; -import { RemoteConfig } from './remote-config/remote-config'; +import { FirestoreService } from '../firestore/firestore-internal'; +import { InstanceId } from '../instance-id/instance-id'; +import { ProjectManagement } from '../project-management/project-management'; +import { SecurityRules } from '../security-rules/security-rules'; +import { RemoteConfig } from '../remote-config/remote-config'; import Credential = credential.Credential; import Database = database.Database; @@ -277,7 +277,7 @@ export class FirebaseApp implements app.App { */ public auth(): Auth { return this.ensureService_('auth', () => { - const authService: typeof Auth = require('./auth/auth').Auth; + const authService: typeof Auth = require('../auth/auth').Auth; return new authService(this); }); } @@ -289,7 +289,7 @@ export class FirebaseApp implements app.App { */ public database(url?: string): Database { const service: DatabaseService = this.ensureService_('database', () => { - const dbService: typeof DatabaseService = require('./database/database-internal').DatabaseService; + const dbService: typeof DatabaseService = require('../database/database-internal').DatabaseService; return new dbService(this); }); return service.getDatabase(url); @@ -302,7 +302,7 @@ export class FirebaseApp implements app.App { */ public messaging(): Messaging { return this.ensureService_('messaging', () => { - const messagingService: typeof Messaging = require('./messaging/messaging').Messaging; + const messagingService: typeof Messaging = require('../messaging/messaging').Messaging; return new messagingService(this); }); } @@ -314,14 +314,14 @@ export class FirebaseApp implements app.App { */ public storage(): Storage { return this.ensureService_('storage', () => { - const storageService: typeof Storage = require('./storage/storage').Storage; + const storageService: typeof Storage = require('../storage/storage').Storage; return new storageService(this); }); } public firestore(): Firestore { const service: FirestoreService = this.ensureService_('firestore', () => { - const firestoreService: typeof FirestoreService = require('./firestore/firestore-internal').FirestoreService; + const firestoreService: typeof FirestoreService = require('../firestore/firestore-internal').FirestoreService; return new firestoreService(this); }); return service.client; @@ -334,7 +334,7 @@ export class FirebaseApp implements app.App { */ public instanceId(): InstanceId { return this.ensureService_('iid', () => { - const iidService: typeof InstanceId = require('./instance-id/instance-id').InstanceId; + const iidService: typeof InstanceId = require('../instance-id/instance-id').InstanceId; return new iidService(this); }); } @@ -347,7 +347,7 @@ export class FirebaseApp implements app.App { public machineLearning(): MachineLearning { return this.ensureService_('machine-learning', () => { const machineLearningService: typeof MachineLearning = - require('./machine-learning/machine-learning').MachineLearning; + require('../machine-learning/machine-learning').MachineLearning; return new machineLearningService(this); }); } @@ -360,7 +360,7 @@ export class FirebaseApp implements app.App { public projectManagement(): ProjectManagement { return this.ensureService_('project-management', () => { const projectManagementService: typeof ProjectManagement = - require('./project-management/project-management').ProjectManagement; + require('../project-management/project-management').ProjectManagement; return new projectManagementService(this); }); } @@ -373,7 +373,7 @@ export class FirebaseApp implements app.App { public securityRules(): SecurityRules { return this.ensureService_('security-rules', () => { const securityRulesService: typeof SecurityRules = - require('./security-rules/security-rules').SecurityRules; + require('../security-rules/security-rules').SecurityRules; return new securityRulesService(this); }); } @@ -385,7 +385,7 @@ export class FirebaseApp implements app.App { */ public remoteConfig(): RemoteConfig { return this.ensureService_('remoteConfig', () => { - const remoteConfigService: typeof RemoteConfig = require('./remote-config/remote-config').RemoteConfig; + const remoteConfigService: typeof RemoteConfig = require('../remote-config/remote-config').RemoteConfig; return new remoteConfigService(this); }); } diff --git a/src/firebase-namespace.ts b/src/app/firebase-namespace.ts similarity index 90% rename from src/firebase-namespace.ts rename to src/app/firebase-namespace.ts index 43b12a92c9..a0938fec31 100644 --- a/src/firebase-namespace.ts +++ b/src/app/firebase-namespace.ts @@ -17,25 +17,25 @@ import fs = require('fs'); -import { AppErrorCodes, FirebaseAppError } from './utils/error'; -import { AppOptions, app } from './firebase-namespace-api'; +import { AppErrorCodes, FirebaseAppError } from '../utils/error'; +import { AppOptions, app } from '../firebase-namespace-api'; import { FirebaseApp } from './firebase-app'; -import { cert, refreshToken, applicationDefault } from './credential/credential'; -import { getApplicationDefault } from './credential/credential-internal'; - -import { auth } from './auth/index'; -import { database } from './database/index'; -import { firestore } from './firestore/index'; -import { instanceId } from './instance-id/index'; -import { machineLearning } from './machine-learning/index'; -import { messaging } from './messaging/index'; -import { projectManagement } from './project-management/index'; -import { remoteConfig } from './remote-config/index'; -import { securityRules } from './security-rules/index'; -import { storage } from './storage/index'; - -import * as validator from './utils/validator'; -import { getSdkVersion } from './utils/index'; +import { cert, refreshToken, applicationDefault } from '../credential/credential'; +import { getApplicationDefault } from '../credential/credential-internal'; + +import { auth } from '../auth/index'; +import { database } from '../database/index'; +import { firestore } from '../firestore/index'; +import { instanceId } from '../instance-id/index'; +import { machineLearning } from '../machine-learning/index'; +import { messaging } from '../messaging/index'; +import { projectManagement } from '../project-management/index'; +import { remoteConfig } from '../remote-config/index'; +import { securityRules } from '../security-rules/index'; +import { storage } from '../storage/index'; + +import * as validator from '../utils/validator'; +import { getSdkVersion } from '../utils/index'; import App = app.App; import Auth = auth.Auth; @@ -223,7 +223,7 @@ export class FirebaseNamespace { const fn: FirebaseServiceNamespace = (app?: App) => { return this.ensureApp(app).auth(); }; - const auth = require('./auth/auth').Auth; + const auth = require('../auth/auth').Auth; return Object.assign(fn, { Auth: auth }); } @@ -248,7 +248,7 @@ export class FirebaseNamespace { const fn: FirebaseServiceNamespace = (app?: App) => { return this.ensureApp(app).messaging(); }; - const messaging = require('./messaging/messaging').Messaging; + const messaging = require('../messaging/messaging').Messaging; return Object.assign(fn, { Messaging: messaging }); } @@ -260,7 +260,7 @@ export class FirebaseNamespace { const fn: FirebaseServiceNamespace = (app?: App) => { return this.ensureApp(app).storage(); }; - const storage = require('./storage/storage').Storage; + const storage = require('../storage/storage').Storage; return Object.assign(fn, { Storage: storage }); } @@ -305,7 +305,7 @@ export class FirebaseNamespace { return this.ensureApp(app).machineLearning(); }; const machineLearning = - require('./machine-learning/machine-learning').MachineLearning; + require('../machine-learning/machine-learning').MachineLearning; return Object.assign(fn, { MachineLearning: machineLearning }); } @@ -317,7 +317,7 @@ export class FirebaseNamespace { const fn: FirebaseServiceNamespace = (app?: App) => { return this.ensureApp(app).instanceId(); }; - const instanceId = require('./instance-id/instance-id').InstanceId; + const instanceId = require('../instance-id/instance-id').InstanceId; return Object.assign(fn, { InstanceId: instanceId }); } @@ -329,7 +329,7 @@ export class FirebaseNamespace { const fn: FirebaseServiceNamespace = (app?: App) => { return this.ensureApp(app).projectManagement(); }; - const projectManagement = require('./project-management/project-management').ProjectManagement; + const projectManagement = require('../project-management/project-management').ProjectManagement; return Object.assign(fn, { ProjectManagement: projectManagement }); } @@ -341,7 +341,7 @@ export class FirebaseNamespace { const fn: FirebaseServiceNamespace = (app?: App) => { return this.ensureApp(app).securityRules(); }; - const securityRules = require('./security-rules/security-rules').SecurityRules; + const securityRules = require('../security-rules/security-rules').SecurityRules; return Object.assign(fn, { SecurityRules: securityRules }); } @@ -353,7 +353,7 @@ export class FirebaseNamespace { const fn: FirebaseServiceNamespace = (app?: App) => { return this.ensureApp(app).remoteConfig(); }; - const remoteConfig = require('./remote-config/remote-config').RemoteConfig; + const remoteConfig = require('../remote-config/remote-config').RemoteConfig; return Object.assign(fn, { RemoteConfig: remoteConfig }); } diff --git a/src/app/index.ts b/src/app/index.ts new file mode 100644 index 0000000000..c4f3cc21dd --- /dev/null +++ b/src/app/index.ts @@ -0,0 +1,18 @@ +/*! + * 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. + */ + +export { App, AppOptions } from './core' +export { initializeApp, app, getApps, deleteApp } from './lifecycle'; diff --git a/src/app/lifecycle.ts b/src/app/lifecycle.ts new file mode 100644 index 0000000000..59fd59c5c2 --- /dev/null +++ b/src/app/lifecycle.ts @@ -0,0 +1,45 @@ +/*! + * 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. + */ + +import { AppErrorCodes, FirebaseAppError } from '../utils/error'; +import { App, AppOptions } from './core'; +import { FirebaseNamespace } from './firebase-namespace'; + +/** + * @internal + */ +export const defaultNamespace = new FirebaseNamespace(); + +export function app(name?: string): App { + return defaultNamespace.app(name); +} + +export function initializeApp(options?: AppOptions, name?: string): App { + return defaultNamespace.initializeApp(options, name); +} + +export function getApps(): App[] { + return defaultNamespace.apps; +} + +export function deleteApp(appToDelete: App): Promise { + if (typeof appToDelete !== 'object' || appToDelete === null || !('options' in appToDelete)) { + throw new FirebaseAppError(AppErrorCodes.INVALID_ARGUMENT, 'Invalid app argument.'); + } + + const existingApp = app(appToDelete.name); + return existingApp.delete(); +} diff --git a/src/auth/auth-api-request.ts b/src/auth/auth-api-request.ts index 0380debeb8..7552f5dfb4 100644 --- a/src/auth/auth-api-request.ts +++ b/src/auth/auth-api-request.ts @@ -21,7 +21,7 @@ import { deepCopy, deepExtend } from '../utils/deep-copy'; import { isUidIdentifier, isEmailIdentifier, isPhoneIdentifier, isProviderIdentifier } from './identifier'; -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { AuthClientErrorCode, FirebaseAuthError } from '../utils/error'; import { ApiSettings, AuthorizedHttpClient, HttpRequestConfig, HttpError, diff --git a/src/auth/auth.ts b/src/auth/auth.ts index 8e35df82c4..c205605224 100644 --- a/src/auth/auth.ts +++ b/src/auth/auth.ts @@ -19,7 +19,7 @@ import { UserRecord } from './user-record'; import { isUidIdentifier, isEmailIdentifier, isPhoneIdentifier, isProviderIdentifier, } from './identifier'; -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { FirebaseTokenGenerator, EmulatedSigner, cryptoSignerFromApp } from './token-generator'; import { AbstractAuthRequestHandler, AuthRequestHandler, TenantAwareAuthRequestHandler, useEmulator, diff --git a/src/auth/tenant-manager.ts b/src/auth/tenant-manager.ts index f97f0aaefc..b11f4d605b 100644 --- a/src/auth/tenant-manager.ts +++ b/src/auth/tenant-manager.ts @@ -15,7 +15,7 @@ */ import { AuthRequestHandler } from './auth-api-request'; -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { TenantAwareAuth } from './auth'; import { Tenant, TenantServerResponse } from './tenant'; import { AuthClientErrorCode, FirebaseAuthError } from '../utils/error'; diff --git a/src/auth/token-generator.ts b/src/auth/token-generator.ts index a8a76c7b28..f868f08fc8 100644 --- a/src/auth/token-generator.ts +++ b/src/auth/token-generator.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { ServiceAccountCredential } from '../credential/credential-internal'; import { AuthClientErrorCode, FirebaseAuthError } from '../utils/error'; import { AuthorizedHttpClient, HttpError, HttpRequestConfig, HttpClient } from '../utils/api-request'; diff --git a/src/auth/token-verifier.ts b/src/auth/token-verifier.ts index c39aa84fc7..4c244523a4 100644 --- a/src/auth/token-verifier.ts +++ b/src/auth/token-verifier.ts @@ -19,7 +19,7 @@ import * as util from '../utils/index'; import * as validator from '../utils/validator'; import * as jwt from 'jsonwebtoken'; import { HttpClient, HttpRequestConfig, HttpError } from '../utils/api-request'; -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { auth } from './index'; import DecodedIdToken = auth.DecodedIdToken; @@ -79,7 +79,7 @@ export class FirebaseTokenVerifier { constructor(private clientCertUrl: string, private algorithm: jwt.Algorithm, private issuer: string, private tokenInfo: FirebaseTokenInfo, private readonly app: FirebaseApp) { - + if (!validator.isURL(clientCertUrl)) { throw new FirebaseAuthError( AuthClientErrorCode.INVALID_ARGUMENT, diff --git a/src/database/database-internal.ts b/src/database/database-internal.ts index a469a41773..6b7af1c10c 100644 --- a/src/database/database-internal.ts +++ b/src/database/database-internal.ts @@ -17,7 +17,7 @@ import { URL } from 'url'; import * as path from 'path'; -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { FirebaseDatabaseError, AppErrorCodes, FirebaseAppError } from '../utils/error'; import { Database as DatabaseImpl } from '@firebase/database'; import { database } from './index'; diff --git a/src/firebase-namespace.d.ts b/src/default-namespace.d.ts similarity index 100% rename from src/firebase-namespace.d.ts rename to src/default-namespace.d.ts diff --git a/src/default-namespace.ts b/src/default-namespace.ts index d15f3cae02..60dd22fe3a 100644 --- a/src/default-namespace.ts +++ b/src/default-namespace.ts @@ -15,9 +15,7 @@ * limitations under the License. */ -import { FirebaseNamespace } from './firebase-namespace'; - -const firebaseAdmin = new FirebaseNamespace(); +import { defaultNamespace as firebaseAdmin } from './app/lifecycle'; // Inject a circular default export to allow users to use both: // diff --git a/src/firebase-namespace-api.ts b/src/firebase-namespace-api.ts index da78a8c393..d39caf636f 100644 --- a/src/firebase-namespace-api.ts +++ b/src/firebase-namespace-api.ts @@ -25,9 +25,9 @@ import { remoteConfig } from './remote-config/index'; import { securityRules } from './security-rules/index'; import { storage } from './storage/index'; -import { App as AppCore, AppOptions } from './core'; +import { App as AppCore, AppOptions } from './app/index'; -export * from './core'; +export * from './app/index'; /** * `FirebaseError` is a subclass of the standard JavaScript `Error` object. In diff --git a/src/firestore/firestore-internal.ts b/src/firestore/firestore-internal.ts index 2188ec223a..dc20f1cfdf 100644 --- a/src/firestore/firestore-internal.ts +++ b/src/firestore/firestore-internal.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { FirebaseFirestoreError } from '../utils/error'; import { ServiceAccountCredential, isApplicationDefault } from '../credential/credential-internal'; import { Firestore, Settings } from '@google-cloud/firestore'; diff --git a/src/index.d.ts b/src/index.d.ts index 1807b1e079..b893c88183 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import * as admin from './firebase-namespace'; +import * as admin from './default-namespace'; declare module 'firebase-admin' { } diff --git a/src/instance-id/instance-id-request-internal.ts b/src/instance-id/instance-id-request-internal.ts index e0d404d602..fbd3ba15ed 100644 --- a/src/instance-id/instance-id-request-internal.ts +++ b/src/instance-id/instance-id-request-internal.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { FirebaseInstanceIdError, InstanceIdClientErrorCode } from '../utils/error'; import { ApiSettings, AuthorizedHttpClient, HttpRequestConfig, HttpError, diff --git a/src/instance-id/instance-id.ts b/src/instance-id/instance-id.ts index 80afaeae48..b92662bfd7 100644 --- a/src/instance-id/instance-id.ts +++ b/src/instance-id/instance-id.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { FirebaseInstanceIdError, InstanceIdClientErrorCode } from '../utils/error'; import { FirebaseInstanceIdRequestHandler } from './instance-id-request-internal'; import { instanceId } from './index'; diff --git a/src/machine-learning/machine-learning-api-client.ts b/src/machine-learning/machine-learning-api-client.ts index 2281b84d53..18a53180cd 100644 --- a/src/machine-learning/machine-learning-api-client.ts +++ b/src/machine-learning/machine-learning-api-client.ts @@ -21,7 +21,7 @@ import { PrefixedFirebaseError } from '../utils/error'; import { FirebaseMachineLearningError, MachineLearningErrorCode } from './machine-learning-utils'; import * as utils from '../utils/index'; import * as validator from '../utils/validator'; -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { machineLearning } from './index'; import GcsTfliteModelOptions = machineLearning.GcsTfliteModelOptions; diff --git a/src/machine-learning/machine-learning.ts b/src/machine-learning/machine-learning.ts index dcbb72caec..986c0b852e 100644 --- a/src/machine-learning/machine-learning.ts +++ b/src/machine-learning/machine-learning.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { MachineLearningApiClient, ModelResponse, ModelUpdateOptions, isGcsTfliteModelOptions } from './machine-learning-api-client'; diff --git a/src/messaging/messaging-api-request-internal.ts b/src/messaging/messaging-api-request-internal.ts index d74f621e0d..1e63369018 100644 --- a/src/messaging/messaging-api-request-internal.ts +++ b/src/messaging/messaging-api-request-internal.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { HttpMethod, AuthorizedHttpClient, HttpRequestConfig, HttpError, HttpResponse, } from '../utils/api-request'; diff --git a/src/messaging/messaging.ts b/src/messaging/messaging.ts index 88e66cf565..79da21221a 100644 --- a/src/messaging/messaging.ts +++ b/src/messaging/messaging.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { deepCopy, deepExtend } from '../utils/deep-copy'; import { SubRequest } from './batch-request-internal'; import { validateMessage, BLACKLISTED_DATA_PAYLOAD_KEYS, BLACKLISTED_OPTIONS_KEYS } from './messaging-internal'; diff --git a/src/project-management/project-management-api-request-internal.ts b/src/project-management/project-management-api-request-internal.ts index 445faf83dc..a24111f424 100644 --- a/src/project-management/project-management-api-request-internal.ts +++ b/src/project-management/project-management-api-request-internal.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { AuthorizedHttpClient, HttpError, HttpMethod, HttpRequestConfig, ExponentialBackoffPoller, } from '../utils/api-request'; diff --git a/src/project-management/project-management.ts b/src/project-management/project-management.ts index 9dc8b29902..1a7ac03733 100644 --- a/src/project-management/project-management.ts +++ b/src/project-management/project-management.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { FirebaseProjectManagementError } from '../utils/error'; import * as utils from '../utils/index'; import * as validator from '../utils/validator'; diff --git a/src/remote-config/remote-config-api-client-internal.ts b/src/remote-config/remote-config-api-client-internal.ts index ac2d071453..bb7b5a7eed 100644 --- a/src/remote-config/remote-config-api-client-internal.ts +++ b/src/remote-config/remote-config-api-client-internal.ts @@ -17,7 +17,7 @@ import { remoteConfig } from './index'; import { HttpRequestConfig, HttpClient, HttpError, AuthorizedHttpClient, HttpResponse } from '../utils/api-request'; import { PrefixedFirebaseError } from '../utils/error'; -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import * as utils from '../utils/index'; import * as validator from '../utils/validator'; import { deepCopy } from '../utils/deep-copy'; diff --git a/src/remote-config/remote-config.ts b/src/remote-config/remote-config.ts index d0b0046832..c4f9c9fc03 100644 --- a/src/remote-config/remote-config.ts +++ b/src/remote-config/remote-config.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import * as validator from '../utils/validator'; import { remoteConfig } from './index'; import { FirebaseRemoteConfigError, RemoteConfigApiClient } from './remote-config-api-client-internal'; diff --git a/src/security-rules/security-rules-api-client-internal.ts b/src/security-rules/security-rules-api-client-internal.ts index 50fdbc9cb8..1719e64316 100644 --- a/src/security-rules/security-rules-api-client-internal.ts +++ b/src/security-rules/security-rules-api-client-internal.ts @@ -19,7 +19,7 @@ import { PrefixedFirebaseError } from '../utils/error'; import { FirebaseSecurityRulesError, SecurityRulesErrorCode } from './security-rules-internal'; import * as utils from '../utils/index'; import * as validator from '../utils/validator'; -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; const RULES_V1_API = 'https://firebaserules.googleapis.com/v1'; const FIREBASE_VERSION_HEADER = { diff --git a/src/security-rules/security-rules.ts b/src/security-rules/security-rules.ts index 2206410df0..9b624e03d9 100644 --- a/src/security-rules/security-rules.ts +++ b/src/security-rules/security-rules.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import * as validator from '../utils/validator'; import { SecurityRulesApiClient, RulesetResponse, RulesetContent, ListRulesetsResponse, diff --git a/src/storage/storage.ts b/src/storage/storage.ts index 4364658a8c..fb873efe20 100644 --- a/src/storage/storage.ts +++ b/src/storage/storage.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { FirebaseError } from '../utils/error'; import { ServiceAccountCredential, isApplicationDefault } from '../credential/credential-internal'; import { Bucket, Storage as StorageClient } from '@google-cloud/storage'; diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts index a41a2f9b48..221a5221f2 100644 --- a/src/utils/api-request.ts +++ b/src/utils/api-request.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { FirebaseApp } from '../firebase-app'; +import { FirebaseApp } from '../app/firebase-app'; import { AppErrorCodes, FirebaseAppError } from './error'; import * as validator from './validator'; diff --git a/test/resources/mocks.ts b/test/resources/mocks.ts index 5512756039..1196bba6c8 100644 --- a/test/resources/mocks.ts +++ b/test/resources/mocks.ts @@ -26,8 +26,8 @@ import * as _ from 'lodash'; import * as jwt from 'jsonwebtoken'; import { AppOptions } from '../../src/firebase-namespace-api'; -import { FirebaseNamespace } from '../../src/firebase-namespace'; -import { FirebaseApp } from '../../src/firebase-app'; +import { FirebaseNamespace } from '../../src/app/firebase-namespace'; +import { FirebaseApp } from '../../src/app/firebase-app'; import { credential as _credential, GoogleOAuthAccessToken } from '../../src/credential/index'; import { ServiceAccountCredential } from '../../src/credential/credential-internal'; diff --git a/test/unit/firebase-app.spec.ts b/test/unit/app/firebase-app.spec.ts similarity index 97% rename from test/unit/firebase-app.spec.ts rename to test/unit/app/firebase-app.spec.ts index 49da6736c5..0d2cbb15fa 100644 --- a/test/unit/firebase-app.spec.ts +++ b/test/unit/app/firebase-app.spec.ts @@ -23,25 +23,27 @@ import * as sinon from 'sinon'; import * as sinonChai from 'sinon-chai'; import * as chaiAsPromised from 'chai-as-promised'; -import * as utils from './utils'; -import * as mocks from '../resources/mocks'; - -import { GoogleOAuthAccessToken } from '../../src/credential/index'; -import { ServiceAccountCredential } from '../../src/credential/credential-internal'; -import { FirebaseApp, FirebaseAccessToken } from '../../src/firebase-app'; -import { FirebaseNamespace, FirebaseNamespaceInternals, FIREBASE_CONFIG_VAR } from '../../src/firebase-namespace'; - -import { auth } from '../../src/auth/index'; -import { messaging } from '../../src/messaging/index'; -import { machineLearning } from '../../src/machine-learning/index'; -import { storage } from '../../src/storage/index'; -import { firestore } from '../../src/firestore/index'; -import { database } from '../../src/database/index'; -import { instanceId } from '../../src/instance-id/index'; -import { projectManagement } from '../../src/project-management/index'; -import { securityRules } from '../../src/security-rules/index'; -import { remoteConfig } from '../../src/remote-config/index'; -import { FirebaseAppError, AppErrorCodes } from '../../src/utils/error'; +import * as utils from '../utils'; +import * as mocks from '../../resources/mocks'; + +import { GoogleOAuthAccessToken } from '../../../src/credential/index'; +import { ServiceAccountCredential } from '../../../src/credential/credential-internal'; +import { FirebaseApp, FirebaseAccessToken } from '../../../src/app/firebase-app'; +import { + FirebaseNamespace, FirebaseNamespaceInternals, FIREBASE_CONFIG_VAR +} from '../../../src/app/firebase-namespace'; + +import { auth } from '../../../src/auth/index'; +import { messaging } from '../../../src/messaging/index'; +import { machineLearning } from '../../../src/machine-learning/index'; +import { storage } from '../../../src/storage/index'; +import { firestore } from '../../../src/firestore/index'; +import { database } from '../../../src/database/index'; +import { instanceId } from '../../../src/instance-id/index'; +import { projectManagement } from '../../../src/project-management/index'; +import { securityRules } from '../../../src/security-rules/index'; +import { remoteConfig } from '../../../src/remote-config/index'; +import { FirebaseAppError, AppErrorCodes } from '../../../src/utils/error'; import Auth = auth.Auth; import Database = database.Database; diff --git a/test/unit/firebase-namespace.spec.ts b/test/unit/app/firebase-namespace.spec.ts similarity index 95% rename from test/unit/firebase-namespace.spec.ts rename to test/unit/app/firebase-namespace.spec.ts index 07e5a8ba78..1bc0c0b636 100644 --- a/test/unit/firebase-namespace.spec.ts +++ b/test/unit/app/firebase-namespace.spec.ts @@ -22,9 +22,9 @@ 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 * as mocks from '../../resources/mocks'; -import { FirebaseNamespace } from '../../src/firebase-namespace'; +import { FirebaseNamespace } from '../../../src/app/firebase-namespace'; import { enableLogging, Database as DatabaseImpl, @@ -43,28 +43,28 @@ import { v1beta1, setLogFunction, } from '@google-cloud/firestore'; -import { getSdkVersion } from '../../src/utils/index'; - -import { app } from '../../src/firebase-namespace-api'; -import { auth } from '../../src/auth/index'; -import { messaging } from '../../src/messaging/index'; -import { machineLearning } from '../../src/machine-learning/index'; -import { storage } from '../../src/storage/index'; -import { firestore } from '../../src/firestore/index'; -import { database } from '../../src/database/index'; -import { instanceId } from '../../src/instance-id/index'; -import { projectManagement } from '../../src/project-management/index'; -import { securityRules } from '../../src/security-rules/index'; -import { remoteConfig } from '../../src/remote-config/index'; - -import { Auth as AuthImpl } from '../../src/auth/auth'; -import { InstanceId as InstanceIdImpl } from '../../src/instance-id/instance-id'; -import { MachineLearning as MachineLearningImpl } from '../../src/machine-learning/machine-learning'; -import { Messaging as MessagingImpl } from '../../src/messaging/messaging'; -import { ProjectManagement as ProjectManagementImpl } from '../../src/project-management/project-management'; -import { RemoteConfig as RemoteConfigImpl } from '../../src/remote-config/remote-config'; -import { SecurityRules as SecurityRulesImpl } from '../../src/security-rules/security-rules'; -import { Storage as StorageImpl } from '../../src/storage/storage'; +import { getSdkVersion } from '../../../src/utils/index'; + +import { app } from '../../../src/firebase-namespace-api'; +import { auth } from '../../../src/auth/index'; +import { messaging } from '../../../src/messaging/index'; +import { machineLearning } from '../../../src/machine-learning/index'; +import { storage } from '../../../src/storage/index'; +import { firestore } from '../../../src/firestore/index'; +import { database } from '../../../src/database/index'; +import { instanceId } from '../../../src/instance-id/index'; +import { projectManagement } from '../../../src/project-management/index'; +import { securityRules } from '../../../src/security-rules/index'; +import { remoteConfig } from '../../../src/remote-config/index'; + +import { Auth as AuthImpl } from '../../../src/auth/auth'; +import { InstanceId as InstanceIdImpl } from '../../../src/instance-id/instance-id'; +import { MachineLearning as MachineLearningImpl } from '../../../src/machine-learning/machine-learning'; +import { Messaging as MessagingImpl } from '../../../src/messaging/messaging'; +import { ProjectManagement as ProjectManagementImpl } from '../../../src/project-management/project-management'; +import { RemoteConfig as RemoteConfigImpl } from '../../../src/remote-config/remote-config'; +import { SecurityRules as SecurityRulesImpl } from '../../../src/security-rules/security-rules'; +import { Storage as StorageImpl } from '../../../src/storage/storage'; import App = app.App; import Auth = auth.Auth; diff --git a/test/unit/app/index.spec.ts b/test/unit/app/index.spec.ts new file mode 100644 index 0000000000..08f6ee4bb2 --- /dev/null +++ b/test/unit/app/index.spec.ts @@ -0,0 +1,176 @@ +/*! + * @license + * Copyright 2017 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 _ from 'lodash'; +import * as chai from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import * as mocks from '../../resources/mocks'; +import * as sinon from 'sinon'; + +import { initializeApp, app, getApps, deleteApp } from '../../../src/app/index'; + +chai.should(); +chai.use(chaiAsPromised); + +const expect = chai.expect; + + +describe('firebase-admin/app', () => { + afterEach(() => { + const deletePromises: Array> = []; + getApps().forEach((app) => { + deletePromises.push(deleteApp(app)); + }); + + return Promise.all(deletePromises); + }); + + describe('#initializeApp()', () => { + const invalidOptions: any[] = [null, NaN, 0, 1, true, false, '', 'a', [], _.noop]; + invalidOptions.forEach((invalidOption: any) => { + it('should throw given invalid options object: ' + JSON.stringify(invalidOption), () => { + expect(() => { + initializeApp(invalidOption); + }).to.throw('Invalid Firebase app options'); + }); + }); + + it('should use application default credentials when no credentials are explicitly specified', () => { + const app = initializeApp(mocks.appOptionsNoAuth); + expect(app.options).to.have.property('credential'); + expect(app.options.credential).to.not.be.undefined; + }); + + it('should not modify the provided options object', () => { + const optionsClone = _.clone(mocks.appOptions); + initializeApp(mocks.appOptions); + expect(optionsClone).to.deep.equal(mocks.appOptions); + }); + + const invalidCredentials = [undefined, null, NaN, 0, 1, '', 'a', true, false, '', _.noop]; + invalidCredentials.forEach((invalidCredential) => { + it('should throw given non-object credential: ' + JSON.stringify(invalidCredential), () => { + expect(() => { + initializeApp({ + credential: invalidCredential as any, + }); + }).to.throw('Invalid Firebase app options'); + }); + }); + + it('should throw given a credential which doesn\'t implement the Credential interface', () => { + expect(() => { + initializeApp({ + credential: {}, + } as any); + }).to.throw('Invalid Firebase app options'); + + expect(() => { + initializeApp({ + credential: { + getAccessToken: true, + }, + } as any); + }).to.throw('Invalid Firebase app options'); + }); + }); + + describe('#app()', () => { + const invalidOptions: any[] = [null, NaN, 0, 1, true, false, '', [], _.noop]; + invalidOptions.forEach((invalidOption: any) => { + it('should throw given invalid app name: ' + JSON.stringify(invalidOption), () => { + expect(() => { + app(invalidOption); + }).to.throw('Invalid Firebase app name'); + }); + }); + + it('should return default app when name not specified', () => { + initializeApp(mocks.appOptionsNoAuth); + const defaulApp = app(); + expect(defaulApp.name).to.equal('[DEFAULT]'); + }); + + it('should return named app when available', () => { + initializeApp(mocks.appOptionsNoAuth, 'testApp'); + const testApp = app('testApp'); + expect(testApp.name).to.equal('testApp'); + }); + + it('should throw when the default app does not exist', () => { + expect(() => app()).to.throw('The default Firebase app does not exist'); + }); + + it('should throw when the specified app does not exist', () => { + expect(() => app('testApp')).to.throw('Firebase app named "testApp" does not exist'); + }); + }); + + describe('#getApps()', () => { + it('should return empty array when no apps available', () => { + const apps = getApps(); + expect(apps).to.be.empty; + }); + + it('should return a non-empty array of apps', () => { + initializeApp(mocks.appOptionsNoAuth); + initializeApp(mocks.appOptionsNoAuth, 'testApp'); + const apps = getApps(); + expect(apps.length).to.equal(2); + + const appNames = apps.map((a) => a.name); + expect(appNames).to.contain('[DEFAULT]'); + expect(appNames).to.contain('testApp'); + }); + + it('apps array is immutable', () => { + initializeApp(mocks.appOptionsNoAuth); + const apps = getApps(); + expect(apps.length).to.equal(1); + apps.push({} as any); + + expect(getApps().length).to.equal(1); + }); + }); + + describe('#deleteApp()', () => { + it('should delete the specified app', () => { + const app = initializeApp(mocks.appOptionsNoAuth); + const spy = sinon.spy(app, 'delete'); + deleteApp(app); + expect(getApps()).to.be.empty; + expect(spy.calledOnce); + }); + + it('should throw if the app is already deleted', () => { + const app = initializeApp(mocks.appOptionsNoAuth); + deleteApp(app); + expect(() => deleteApp(app)).to.throw('The default Firebase app does not exist'); + }); + + const invalidOptions: any[] = [null, NaN, 0, 1, true, false, '', [], _.noop]; + invalidOptions.forEach((invalidOption: any) => { + it('should throw given invalid app: ' + JSON.stringify(invalidOption), () => { + expect(() => { + deleteApp(invalidOption); + }).to.throw('Invalid app argument'); + }); + }); + }); +}); diff --git a/test/unit/auth/auth-api-request.spec.ts b/test/unit/auth/auth-api-request.spec.ts index ff154d3b2c..96b631356d 100644 --- a/test/unit/auth/auth-api-request.spec.ts +++ b/test/unit/auth/auth-api-request.spec.ts @@ -27,7 +27,7 @@ import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; import { deepCopy, deepExtend } from '../../../src/utils/deep-copy'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { HttpClient, HttpRequestConfig } from '../../../src/utils/api-request'; import * as validator from '../../../src/utils/validator'; import { diff --git a/test/unit/auth/auth.spec.ts b/test/unit/auth/auth.spec.ts index 26521b30cd..ac3a680d8d 100644 --- a/test/unit/auth/auth.spec.ts +++ b/test/unit/auth/auth.spec.ts @@ -29,7 +29,7 @@ import * as mocks from '../../resources/mocks'; import { Auth, TenantAwareAuth, BaseAuth } from '../../../src/auth/auth'; import { UserRecord } from '../../../src/auth/user-record'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { AuthRequestHandler, TenantAwareAuthRequestHandler, AbstractAuthRequestHandler, } from '../../../src/auth/auth-api-request'; diff --git a/test/unit/auth/tenant-manager.spec.ts b/test/unit/auth/tenant-manager.spec.ts index 9c7ef80be1..c00096da32 100644 --- a/test/unit/auth/tenant-manager.spec.ts +++ b/test/unit/auth/tenant-manager.spec.ts @@ -23,7 +23,7 @@ import * as sinonChai from 'sinon-chai'; import * as chaiAsPromised from 'chai-as-promised'; import * as mocks from '../../resources/mocks'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { AuthRequestHandler } from '../../../src/auth/auth-api-request'; import { Tenant, TenantServerResponse } from '../../../src/auth/tenant'; import { TenantManager } from '../../../src/auth/tenant-manager'; diff --git a/test/unit/auth/token-generator.spec.ts b/test/unit/auth/token-generator.spec.ts index c519c7a3ed..2653b4d36d 100644 --- a/test/unit/auth/token-generator.spec.ts +++ b/test/unit/auth/token-generator.spec.ts @@ -31,7 +31,7 @@ import { import { ServiceAccountCredential } from '../../../src/credential/credential-internal'; import { AuthorizedHttpClient, HttpClient } from '../../../src/utils/api-request'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import * as utils from '../utils'; import { FirebaseAuthError } from '../../../src/utils/error'; diff --git a/test/unit/auth/token-verifier.spec.ts b/test/unit/auth/token-verifier.spec.ts index 6b370a8bb4..76e3444c51 100644 --- a/test/unit/auth/token-verifier.spec.ts +++ b/test/unit/auth/token-verifier.spec.ts @@ -33,7 +33,7 @@ import * as verifier from '../../../src/auth/token-verifier'; import { ServiceAccountCredential } from '../../../src/credential/credential-internal'; import { AuthClientErrorCode } from '../../../src/utils/error'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { Algorithm } from 'jsonwebtoken'; chai.should(); @@ -106,7 +106,7 @@ function mockFailedFetchPublicKeys(): nock.Scope { } function createTokenVerifier( - app: FirebaseApp, + app: FirebaseApp, options: { algorithm?: Algorithm } = {} ): verifier.FirebaseTokenVerifier { const algorithm = options.algorithm || 'RS256'; diff --git a/test/unit/database/database.spec.ts b/test/unit/database/database.spec.ts index 4a4f969b1e..c946d498de 100644 --- a/test/unit/database/database.spec.ts +++ b/test/unit/database/database.spec.ts @@ -22,7 +22,7 @@ import { expect } from 'chai'; import * as sinon from 'sinon'; import * as mocks from '../../resources/mocks'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { DatabaseService } from '../../../src/database/database-internal'; import { database } from '../../../src/database/index'; import * as utils from '../utils'; diff --git a/test/unit/firebase.spec.ts b/test/unit/firebase.spec.ts index 3048121529..fa758584ec 100644 --- a/test/unit/firebase.spec.ts +++ b/test/unit/firebase.spec.ts @@ -28,7 +28,7 @@ import * as chaiAsPromised from 'chai-as-promised'; import * as mocks from '../resources/mocks'; import * as firebaseAdmin from '../../src/index'; -import { FirebaseApp, FirebaseAppInternals } from '../../src/firebase-app'; +import { FirebaseApp, FirebaseAppInternals } from '../../src/app/firebase-app'; import { RefreshTokenCredential, ServiceAccountCredential, isApplicationDefault } from '../../src/credential/credential-internal'; diff --git a/test/unit/firestore/firestore.spec.ts b/test/unit/firestore/firestore.spec.ts index 197e8dfde6..52c985360c 100644 --- a/test/unit/firestore/firestore.spec.ts +++ b/test/unit/firestore/firestore.spec.ts @@ -21,7 +21,7 @@ import * as _ from 'lodash'; import { expect } from 'chai'; import * as mocks from '../../resources/mocks'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { ComputeEngineCredential, RefreshTokenCredential } from '../../../src/credential/credential-internal'; diff --git a/test/unit/index.spec.ts b/test/unit/index.spec.ts index efbe059e96..887ccb5642 100644 --- a/test/unit/index.spec.ts +++ b/test/unit/index.spec.ts @@ -17,8 +17,9 @@ // General import './firebase.spec'; -import './firebase-app.spec'; -import './firebase-namespace.spec'; +import './app/index.spec'; +import './app/firebase-app.spec'; +import './app/firebase-namespace.spec'; // Utilities import './utils/index.spec'; diff --git a/test/unit/instance-id/instance-id-request.spec.ts b/test/unit/instance-id/instance-id-request.spec.ts index dd28f0f8ef..37c7347a0e 100644 --- a/test/unit/instance-id/instance-id-request.spec.ts +++ b/test/unit/instance-id/instance-id-request.spec.ts @@ -26,7 +26,7 @@ import * as chaiAsPromised from 'chai-as-promised'; import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { HttpClient } from '../../../src/utils/api-request'; import { FirebaseInstanceIdRequestHandler } from '../../../src/instance-id/instance-id-request-internal'; diff --git a/test/unit/instance-id/instance-id.spec.ts b/test/unit/instance-id/instance-id.spec.ts index b68f8b3ac1..a2b2650df8 100644 --- a/test/unit/instance-id/instance-id.spec.ts +++ b/test/unit/instance-id/instance-id.spec.ts @@ -28,7 +28,7 @@ import * as mocks from '../../resources/mocks'; import { InstanceId } from '../../../src/instance-id/instance-id'; import { FirebaseInstanceIdRequestHandler } from '../../../src/instance-id/instance-id-request-internal'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { FirebaseInstanceIdError, InstanceIdClientErrorCode } from '../../../src/utils/error'; chai.should(); diff --git a/test/unit/machine-learning/machine-learning-api-client.spec.ts b/test/unit/machine-learning/machine-learning-api-client.spec.ts index 3399dd0f52..1dc8a0df35 100644 --- a/test/unit/machine-learning/machine-learning-api-client.spec.ts +++ b/test/unit/machine-learning/machine-learning-api-client.spec.ts @@ -24,7 +24,7 @@ import { HttpClient } from '../../../src/utils/api-request'; import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; import { FirebaseAppError } from '../../../src/utils/error'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { getSdkVersion } from '../../../src/utils/index'; import { MachineLearningApiClient } from '../../../src/machine-learning/machine-learning-api-client'; import { machineLearning } from '../../../src/machine-learning/index'; diff --git a/test/unit/machine-learning/machine-learning.spec.ts b/test/unit/machine-learning/machine-learning.spec.ts index 96493d298b..9c8314fc03 100644 --- a/test/unit/machine-learning/machine-learning.spec.ts +++ b/test/unit/machine-learning/machine-learning.spec.ts @@ -19,7 +19,7 @@ import * as _ from 'lodash'; import * as chai from 'chai'; import * as sinon from 'sinon'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import * as mocks from '../../resources/mocks'; import { MachineLearning, Model } from '../../../src/machine-learning/machine-learning'; import { diff --git a/test/unit/messaging/messaging.spec.ts b/test/unit/messaging/messaging.spec.ts index 82f0973f67..c6c1e69fc4 100644 --- a/test/unit/messaging/messaging.spec.ts +++ b/test/unit/messaging/messaging.spec.ts @@ -27,7 +27,7 @@ import * as chaiAsPromised from 'chai-as-promised'; import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { messaging } from '../../../src/messaging/index'; import { Messaging } from '../../../src/messaging/messaging'; import { BLACKLISTED_OPTIONS_KEYS, BLACKLISTED_DATA_PAYLOAD_KEYS } from '../../../src/messaging/messaging-internal'; diff --git a/test/unit/project-management/android-app.spec.ts b/test/unit/project-management/android-app.spec.ts index 5feff560a9..1c2d88032f 100644 --- a/test/unit/project-management/android-app.spec.ts +++ b/test/unit/project-management/android-app.spec.ts @@ -19,7 +19,7 @@ import * as chai from 'chai'; import * as _ from 'lodash'; import * as sinon from 'sinon'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { AndroidApp, ShaCertificate } from '../../../src/project-management/android-app'; import { ProjectManagementRequestHandler diff --git a/test/unit/project-management/ios-app.spec.ts b/test/unit/project-management/ios-app.spec.ts index e0163d893f..53966696d1 100644 --- a/test/unit/project-management/ios-app.spec.ts +++ b/test/unit/project-management/ios-app.spec.ts @@ -19,7 +19,7 @@ import * as chai from 'chai'; import * as _ from 'lodash'; import * as sinon from 'sinon'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { IosApp } from '../../../src/project-management/ios-app'; import { ProjectManagementRequestHandler 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 f4088e0a1f..0cbd7929cb 100644 --- a/test/unit/project-management/project-management-api-request.spec.ts +++ b/test/unit/project-management/project-management-api-request.spec.ts @@ -21,7 +21,7 @@ import * as chaiAsPromised from 'chai-as-promised'; import * as _ from 'lodash'; import * as sinon from 'sinon'; import * as sinonChai from 'sinon-chai'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { ProjectManagementRequestHandler } from '../../../src/project-management/project-management-api-request-internal'; diff --git a/test/unit/project-management/project-management.spec.ts b/test/unit/project-management/project-management.spec.ts index f7837389c7..a755a5b283 100644 --- a/test/unit/project-management/project-management.spec.ts +++ b/test/unit/project-management/project-management.spec.ts @@ -19,7 +19,7 @@ import * as chai from 'chai'; import * as _ from 'lodash'; import * as sinon from 'sinon'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { AndroidApp } from '../../../src/project-management/android-app'; import { ProjectManagement } from '../../../src/project-management/project-management'; import { diff --git a/test/unit/remote-config/remote-config-api-client.spec.ts b/test/unit/remote-config/remote-config-api-client.spec.ts index c416715dcb..2d982e8808 100644 --- a/test/unit/remote-config/remote-config-api-client.spec.ts +++ b/test/unit/remote-config/remote-config-api-client.spec.ts @@ -28,7 +28,7 @@ import { HttpClient } from '../../../src/utils/api-request'; import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; import { FirebaseAppError } from '../../../src/utils/error'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { deepCopy } from '../../../src/utils/deep-copy'; import { getSdkVersion } from '../../../src/utils/index'; diff --git a/test/unit/remote-config/remote-config.spec.ts b/test/unit/remote-config/remote-config.spec.ts index 6c946f41fa..2b25a5b7bc 100644 --- a/test/unit/remote-config/remote-config.spec.ts +++ b/test/unit/remote-config/remote-config.spec.ts @@ -20,7 +20,7 @@ import * as _ from 'lodash'; import * as chai from 'chai'; import * as sinon from 'sinon'; import { RemoteConfig } from '../../../src/remote-config/remote-config'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import * as mocks from '../../resources/mocks'; import { remoteConfig } from '../../../src/remote-config/index'; import { diff --git a/test/unit/security-rules/security-rules-api-client.spec.ts b/test/unit/security-rules/security-rules-api-client.spec.ts index f0cd1c4185..8b83a46fdf 100644 --- a/test/unit/security-rules/security-rules-api-client.spec.ts +++ b/test/unit/security-rules/security-rules-api-client.spec.ts @@ -25,7 +25,7 @@ import { HttpClient } from '../../../src/utils/api-request'; import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; import { FirebaseAppError } from '../../../src/utils/error'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { getSdkVersion } from '../../../src/utils/index'; const expect = chai.expect; diff --git a/test/unit/security-rules/security-rules.spec.ts b/test/unit/security-rules/security-rules.spec.ts index fd81fa7fd2..426d46c6ae 100644 --- a/test/unit/security-rules/security-rules.spec.ts +++ b/test/unit/security-rules/security-rules.spec.ts @@ -20,7 +20,7 @@ import * as _ from 'lodash'; import * as chai from 'chai'; import * as sinon from 'sinon'; import { SecurityRules } from '../../../src/security-rules/security-rules'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import * as mocks from '../../resources/mocks'; import { SecurityRulesApiClient, RulesetContent } from '../../../src/security-rules/security-rules-api-client-internal'; import { FirebaseSecurityRulesError } from '../../../src/security-rules/security-rules-internal'; diff --git a/test/unit/storage/storage.spec.ts b/test/unit/storage/storage.spec.ts index 997d44846e..80cb49ab92 100644 --- a/test/unit/storage/storage.spec.ts +++ b/test/unit/storage/storage.spec.ts @@ -21,7 +21,7 @@ import * as _ from 'lodash'; import { expect } from 'chai'; import * as mocks from '../../resources/mocks'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { Storage } from '../../../src/storage/storage'; describe('Storage', () => { diff --git a/test/unit/utils.ts b/test/unit/utils.ts index 6eb845831a..dee46114e6 100644 --- a/test/unit/utils.ts +++ b/test/unit/utils.ts @@ -20,9 +20,9 @@ import * as sinon from 'sinon'; import * as mocks from '../resources/mocks'; -import { FirebaseNamespace } from '../../src/firebase-namespace'; +import { FirebaseNamespace } from '../../src/app/firebase-namespace'; import { AppOptions } from '../../src/firebase-namespace-api'; -import { FirebaseApp, FirebaseAppInternals, FirebaseAccessToken } from '../../src/firebase-app'; +import { FirebaseApp, FirebaseAppInternals, FirebaseAccessToken } from '../../src/app/firebase-app'; import { HttpError, HttpResponse } from '../../src/utils/api-request'; /** diff --git a/test/unit/utils/api-request.spec.ts b/test/unit/utils/api-request.spec.ts index f997cfc9dd..fd92a9c191 100644 --- a/test/unit/utils/api-request.spec.ts +++ b/test/unit/utils/api-request.spec.ts @@ -26,7 +26,7 @@ import * as chaiAsPromised from 'chai-as-promised'; import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { ApiSettings, HttpClient, HttpError, AuthorizedHttpClient, ApiCallbackFunction, HttpRequestConfig, HttpResponse, parseHttpResponse, RetryConfig, defaultRetryConfig, diff --git a/test/unit/utils/index.spec.ts b/test/unit/utils/index.spec.ts index e63993fb83..27ab60cb71 100644 --- a/test/unit/utils/index.spec.ts +++ b/test/unit/utils/index.spec.ts @@ -25,7 +25,7 @@ import { toWebSafeBase64, formatString, generateUpdateMask, } from '../../../src/utils/index'; import { isNonEmptyString } from '../../../src/utils/validator'; -import { FirebaseApp } from '../../../src/firebase-app'; +import { FirebaseApp } from '../../../src/app/firebase-app'; import { ComputeEngineCredential } from '../../../src/credential/credential-internal'; import { HttpClient } from '../../../src/utils/api-request'; import * as utils from '../utils'; diff --git a/tsconfig.json b/tsconfig.json index 67f91761f3..f70690c510 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,7 @@ //"strictPropertyInitialization": true, "lib": ["es2018"], "outDir": "lib", + "stripInternal": true, "rootDir": "." }, "files": [ From c0454a7b6683aabedb1eceb9eece8b83f2842077 Mon Sep 17 00:00:00 2001 From: Hiranya Jayathilaka Date: Wed, 13 Jan 2021 13:22:52 -0800 Subject: [PATCH 2/4] fix: Updated API report for deleteApp and getApps --- etc/firebase-admin.api.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/etc/firebase-admin.api.md b/etc/firebase-admin.api.md index cb1eb2ea4f..1d100fc9a7 100644 --- a/etc/firebase-admin.api.md +++ b/etc/firebase-admin.api.md @@ -428,7 +428,7 @@ export namespace database { } // @public (undocumented) -export function deleteApp(app: App): Promise; +export function deleteApp(appToDelete: App): Promise; // @public export interface FirebaseArrayIndexError { @@ -480,6 +480,9 @@ export namespace firestore { import setLogFunction = _firestore.setLogFunction; } +// @public (undocumented) +export function getApps(): App[]; + // @public export interface GoogleOAuthAccessToken { // (undocumented) From 3d942077307396948ca73dffe1a5aae89bea50c9 Mon Sep 17 00:00:00 2001 From: Hiranya Jayathilaka Date: Thu, 14 Jan 2021 12:50:12 -0800 Subject: [PATCH 3/4] fix: Removed delete() method from lightweight App interface --- etc/firebase-admin.api.md | 7 +++++-- src/app/core.ts | 19 ------------------- src/app/index.ts | 6 +++++- src/app/lifecycle.ts | 25 +++++++++++++++++-------- src/firebase-namespace-api.ts | 19 +++++++++++++++++++ test/unit/app/index.spec.ts | 23 +++++++++++++++-------- 6 files changed, 61 insertions(+), 38 deletions(-) diff --git a/etc/firebase-admin.api.md b/etc/firebase-admin.api.md index 1d100fc9a7..b2f107e95f 100644 --- a/etc/firebase-admin.api.md +++ b/etc/firebase-admin.api.md @@ -11,7 +11,6 @@ import * as rtdb from '@firebase/database-types'; // @public (undocumented) export interface App { - delete(): Promise; name: string; options: AppOptions; } @@ -26,6 +25,7 @@ export namespace app { auth(): auth.Auth; // (undocumented) database(url?: string): database.Database; + delete(): Promise; // (undocumented) firestore(): firestore.Firestore; // (undocumented) @@ -428,7 +428,7 @@ export namespace database { } // @public (undocumented) -export function deleteApp(appToDelete: App): Promise; +export function deleteApp(app: App): Promise; // @public export interface FirebaseArrayIndexError { @@ -480,6 +480,9 @@ export namespace firestore { import setLogFunction = _firestore.setLogFunction; } +// @public (undocumented) +export function getApp(name?: string): App; + // @public (undocumented) export function getApps(): App[]; diff --git a/src/app/core.ts b/src/app/core.ts index d377a75d2f..2f30e04365 100644 --- a/src/app/core.ts +++ b/src/app/core.ts @@ -121,23 +121,4 @@ export interface App { * ``` */ options: AppOptions; - - /** - * Renders this local `FirebaseApp` unusable and frees the resources of - * all associated services (though it does *not* clean up any backend - * resources). When running the SDK locally, this method - * must be called to ensure graceful termination of the process. - * - * @example - * ```javascript - * app.delete() - * .then(function() { - * console.log("App deleted successfully"); - * }) - * .catch(function(error) { - * console.log("Error deleting app:", error); - * }); - * ``` - */ - delete(): Promise; } diff --git a/src/app/index.ts b/src/app/index.ts index c4f3cc21dd..a12175da0a 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -14,5 +14,9 @@ * limitations under the License. */ +import { getSdkVersion } from '../utils'; + export { App, AppOptions } from './core' -export { initializeApp, app, getApps, deleteApp } from './lifecycle'; +export { initializeApp, getApp, getApps, deleteApp } from './lifecycle'; + +export const SDK_VERSION = getSdkVersion(); diff --git a/src/app/lifecycle.ts b/src/app/lifecycle.ts index 59fd59c5c2..056b190142 100644 --- a/src/app/lifecycle.ts +++ b/src/app/lifecycle.ts @@ -19,27 +19,36 @@ import { App, AppOptions } from './core'; import { FirebaseNamespace } from './firebase-namespace'; /** + * In order to maintain backward compatibility, we instantiate a default namespace instance in + * this module, and delegate all app lifecycle operations to it. In a future implementation where + * the old admin namespace is no longer supported, we should remove this, and implement app + * lifecycle management in this module itself. + * * @internal */ export const defaultNamespace = new FirebaseNamespace(); -export function app(name?: string): App { - return defaultNamespace.app(name); -} - export function initializeApp(options?: AppOptions, name?: string): App { return defaultNamespace.initializeApp(options, name); } +export function getApp(name?: string): App { + return defaultNamespace.app(name); +} + export function getApps(): App[] { return defaultNamespace.apps; } -export function deleteApp(appToDelete: App): Promise { - if (typeof appToDelete !== 'object' || appToDelete === null || !('options' in appToDelete)) { +export function deleteApp(app: App): Promise { + if (typeof app !== 'object' || app === null || !('options' in app)) { throw new FirebaseAppError(AppErrorCodes.INVALID_ARGUMENT, 'Invalid app argument.'); } - const existingApp = app(appToDelete.name); - return existingApp.delete(); + // Make sure the given app already exists. + const existingApp = getApp(app.name); + + // Delegate delete operation to the App instance itself for now. This will tear down any + // local app state, and also remove it from the global map. + return (existingApp as any).delete(); } diff --git a/src/firebase-namespace-api.ts b/src/firebase-namespace-api.ts index d39caf636f..9a56547118 100644 --- a/src/firebase-namespace-api.ts +++ b/src/firebase-namespace-api.ts @@ -131,6 +131,25 @@ export namespace app { remoteConfig(): remoteConfig.RemoteConfig; securityRules(): securityRules.SecurityRules; storage(): storage.Storage; + + /** + * Renders this local `FirebaseApp` unusable and frees the resources of + * all associated services (though it does *not* clean up any backend + * resources). When running the SDK locally, this method + * must be called to ensure graceful termination of the process. + * + * @example + * ```javascript + * app.delete() + * .then(function() { + * console.log("App deleted successfully"); + * }) + * .catch(function(error) { + * console.log("Error deleting app:", error); + * }); + * ``` + */ + delete(): Promise; } } diff --git a/test/unit/app/index.spec.ts b/test/unit/app/index.spec.ts index 08f6ee4bb2..745952c01b 100644 --- a/test/unit/app/index.spec.ts +++ b/test/unit/app/index.spec.ts @@ -23,7 +23,7 @@ import * as chaiAsPromised from 'chai-as-promised'; import * as mocks from '../../resources/mocks'; import * as sinon from 'sinon'; -import { initializeApp, app, getApps, deleteApp } from '../../../src/app/index'; +import { initializeApp, getApp, getApps, deleteApp, SDK_VERSION } from '../../../src/app/index'; chai.should(); chai.use(chaiAsPromised); @@ -91,34 +91,34 @@ describe('firebase-admin/app', () => { }); }); - describe('#app()', () => { + describe('#getApp()', () => { const invalidOptions: any[] = [null, NaN, 0, 1, true, false, '', [], _.noop]; invalidOptions.forEach((invalidOption: any) => { it('should throw given invalid app name: ' + JSON.stringify(invalidOption), () => { expect(() => { - app(invalidOption); + getApp(invalidOption); }).to.throw('Invalid Firebase app name'); }); }); it('should return default app when name not specified', () => { initializeApp(mocks.appOptionsNoAuth); - const defaulApp = app(); + const defaulApp = getApp(); expect(defaulApp.name).to.equal('[DEFAULT]'); }); it('should return named app when available', () => { initializeApp(mocks.appOptionsNoAuth, 'testApp'); - const testApp = app('testApp'); + const testApp = getApp('testApp'); expect(testApp.name).to.equal('testApp'); }); it('should throw when the default app does not exist', () => { - expect(() => app()).to.throw('The default Firebase app does not exist'); + expect(() => getApp()).to.throw('The default Firebase app does not exist'); }); it('should throw when the specified app does not exist', () => { - expect(() => app('testApp')).to.throw('Firebase app named "testApp" does not exist'); + expect(() => getApp('testApp')).to.throw('Firebase app named "testApp" does not exist'); }); }); @@ -152,7 +152,7 @@ describe('firebase-admin/app', () => { describe('#deleteApp()', () => { it('should delete the specified app', () => { const app = initializeApp(mocks.appOptionsNoAuth); - const spy = sinon.spy(app, 'delete'); + const spy = sinon.spy(app as any, 'delete'); deleteApp(app); expect(getApps()).to.be.empty; expect(spy.calledOnce); @@ -173,4 +173,11 @@ describe('firebase-admin/app', () => { }); }); }); + + describe('SDK_VERSION', () => { + it('should indicate the current version of the SDK', () => { + const { version } = require('../../../package.json'); // eslint-disable-line @typescript-eslint/no-var-requires + expect(SDK_VERSION).to.equal(version); + }); + }); }); From 9113a8cb8293bf3022f564f5daaf112fd152dfee Mon Sep 17 00:00:00 2001 From: Hiranya Jayathilaka Date: Thu, 14 Jan 2021 15:23:35 -0800 Subject: [PATCH 4/4] fix: Updated some license headers --- src/app/core.ts | 1 + src/app/index.ts | 1 + src/app/lifecycle.ts | 1 + test/unit/app/index.spec.ts | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/core.ts b/src/app/core.ts index 2f30e04365..a311907727 100644 --- a/src/app/core.ts +++ b/src/app/core.ts @@ -1,4 +1,5 @@ /*! + * @license * Copyright 2021 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/app/index.ts b/src/app/index.ts index a12175da0a..5b4125d76a 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -1,4 +1,5 @@ /*! + * @license * Copyright 2021 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/app/lifecycle.ts b/src/app/lifecycle.ts index 056b190142..8fc03b6119 100644 --- a/src/app/lifecycle.ts +++ b/src/app/lifecycle.ts @@ -1,4 +1,5 @@ /*! + * @license * Copyright 2021 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/unit/app/index.spec.ts b/test/unit/app/index.spec.ts index 745952c01b..d4da3ae4b2 100644 --- a/test/unit/app/index.spec.ts +++ b/test/unit/app/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * 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.