UNPKG

7.06 kBJavaScriptView Raw
1/*! firebase-admin v12.0.0 */
2"use strict";
3/*!
4 * @license
5 * Copyright 2021 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19Object.defineProperty(exports, "__esModule", { value: true });
20exports.FIREBASE_CONFIG_VAR = exports.deleteApp = exports.getApps = exports.getApp = exports.initializeApp = exports.defaultAppStore = exports.AppStore = void 0;
21const fs = require("fs");
22const validator = require("../utils/validator");
23const error_1 = require("../utils/error");
24const credential_internal_1 = require("./credential-internal");
25const firebase_app_1 = require("./firebase-app");
26const DEFAULT_APP_NAME = '[DEFAULT]';
27class AppStore {
28 constructor() {
29 this.appStore = new Map();
30 }
31 initializeApp(options, appName = DEFAULT_APP_NAME) {
32 if (typeof options === 'undefined') {
33 options = loadOptionsFromEnvVar();
34 options.credential = (0, credential_internal_1.getApplicationDefault)();
35 }
36 if (typeof appName !== 'string' || appName === '') {
37 throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_NAME, `Invalid Firebase app name "${appName}" provided. App name must be a non-empty string.`);
38 }
39 else if (this.appStore.has(appName)) {
40 if (appName === DEFAULT_APP_NAME) {
41 throw new error_1.FirebaseAppError(error_1.AppErrorCodes.DUPLICATE_APP, 'The default Firebase app already exists. This means you called initializeApp() ' +
42 'more than once without providing an app name as the second argument. In most cases ' +
43 'you only need to call initializeApp() once. But if you do want to initialize ' +
44 'multiple apps, pass a second argument to initializeApp() to give each app a unique ' +
45 'name.');
46 }
47 else {
48 throw new error_1.FirebaseAppError(error_1.AppErrorCodes.DUPLICATE_APP, `Firebase app named "${appName}" already exists. This means you called initializeApp() ` +
49 'more than once with the same app name as the second argument. Make sure you provide a ' +
50 'unique name every time you call initializeApp().');
51 }
52 }
53 const app = new firebase_app_1.FirebaseApp(options, appName, this);
54 this.appStore.set(app.name, app);
55 return app;
56 }
57 getApp(appName = DEFAULT_APP_NAME) {
58 if (typeof appName !== 'string' || appName === '') {
59 throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_NAME, `Invalid Firebase app name "${appName}" provided. App name must be a non-empty string.`);
60 }
61 else if (!this.appStore.has(appName)) {
62 let errorMessage = (appName === DEFAULT_APP_NAME)
63 ? 'The default Firebase app does not exist. ' : `Firebase app named "${appName}" does not exist. `;
64 errorMessage += 'Make sure you call initializeApp() before using any of the Firebase services.';
65 throw new error_1.FirebaseAppError(error_1.AppErrorCodes.NO_APP, errorMessage);
66 }
67 return this.appStore.get(appName);
68 }
69 getApps() {
70 // Return a copy so the caller cannot mutate the array
71 return Array.from(this.appStore.values());
72 }
73 deleteApp(app) {
74 if (typeof app !== 'object' || app === null || !('options' in app)) {
75 throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_ARGUMENT, 'Invalid app argument.');
76 }
77 // Make sure the given app already exists.
78 const existingApp = getApp(app.name);
79 // Delegate delete operation to the App instance itself. That will also remove the App
80 // instance from the AppStore.
81 return existingApp.delete();
82 }
83 clearAllApps() {
84 const promises = [];
85 this.getApps().forEach((app) => {
86 promises.push(this.deleteApp(app));
87 });
88 return Promise.all(promises).then();
89 }
90 /**
91 * Removes the specified App instance from the store. This is currently called by the
92 * {@link FirebaseApp.delete} method. Can be removed once the app deletion is handled
93 * entirely by the {@link deleteApp} top-level function.
94 */
95 removeApp(appName) {
96 this.appStore.delete(appName);
97 }
98}
99exports.AppStore = AppStore;
100exports.defaultAppStore = new AppStore();
101function initializeApp(options, appName = DEFAULT_APP_NAME) {
102 return exports.defaultAppStore.initializeApp(options, appName);
103}
104exports.initializeApp = initializeApp;
105function getApp(appName = DEFAULT_APP_NAME) {
106 return exports.defaultAppStore.getApp(appName);
107}
108exports.getApp = getApp;
109function getApps() {
110 return exports.defaultAppStore.getApps();
111}
112exports.getApps = getApps;
113/**
114 * Renders this given `App` unusable and frees the resources of
115 * all associated services (though it does *not* clean up any backend
116 * resources). When running the SDK locally, this method
117 * must be called to ensure graceful termination of the process.
118 *
119 * @example
120 * ```javascript
121 * deleteApp(app)
122 * .then(function() {
123 * console.log("App deleted successfully");
124 * })
125 * .catch(function(error) {
126 * console.log("Error deleting app:", error);
127 * });
128 * ```
129 */
130function deleteApp(app) {
131 return exports.defaultAppStore.deleteApp(app);
132}
133exports.deleteApp = deleteApp;
134/**
135 * Constant holding the environment variable name with the default config.
136 * If the environment variable contains a string that starts with '{' it will be parsed as JSON,
137 * otherwise it will be assumed to be pointing to a file.
138 */
139exports.FIREBASE_CONFIG_VAR = 'FIREBASE_CONFIG';
140/**
141 * Parse the file pointed to by the FIREBASE_CONFIG_VAR, if it exists.
142 * Or if the FIREBASE_CONFIG_ENV contains a valid JSON object, parse it directly.
143 * If the environment variable contains a string that starts with '{' it will be parsed as JSON,
144 * otherwise it will be assumed to be pointing to a file.
145 */
146function loadOptionsFromEnvVar() {
147 const config = process.env[exports.FIREBASE_CONFIG_VAR];
148 if (!validator.isNonEmptyString(config)) {
149 return {};
150 }
151 try {
152 const contents = config.startsWith('{') ? config : fs.readFileSync(config, 'utf8');
153 return JSON.parse(contents);
154 }
155 catch (error) {
156 // Throw a nicely formed error message if the file contents cannot be parsed
157 throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_OPTIONS, 'Failed to parse app options file: ' + error);
158 }
159}