UNPKG

12.2 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var firebase = require('firebase');
6var request = require('request');
7var util = require('@firebase/util');
8var logger = require('@firebase/logger');
9var grpc = require('@grpc/grpc-js');
10var protoLoader = require('@grpc/proto-loader');
11var path = require('path');
12var component = require('@firebase/component');
13
14/*! *****************************************************************************
15Copyright (c) Microsoft Corporation. All rights reserved.
16Licensed under the Apache License, Version 2.0 (the "License"); you may not use
17this file except in compliance with the License. You may obtain a copy of the
18License at http://www.apache.org/licenses/LICENSE-2.0
19
20THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
22WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
23MERCHANTABLITY OR NON-INFRINGEMENT.
24
25See the Apache Version 2.0 License for specific language governing permissions
26and limitations under the License.
27***************************************************************************** */
28
29function __awaiter(thisArg, _arguments, P, generator) {
30 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
31 return new (P || (P = Promise))(function (resolve, reject) {
32 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
33 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
34 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
35 step((generator = generator.apply(thisArg, _arguments || [])).next());
36 });
37}
38
39function __generator(thisArg, body) {
40 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
41 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
42 function verb(n) { return function (v) { return step([n, v]); }; }
43 function step(op) {
44 if (f) throw new TypeError("Generator is already executing.");
45 while (_) try {
46 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
47 if (y = 0, t) op = [op[0] & 2, t.value];
48 switch (op[0]) {
49 case 0: case 1: t = op; break;
50 case 4: _.label++; return { value: op[1], done: false };
51 case 5: _.label++; y = op[1]; op = [0]; continue;
52 case 7: op = _.ops.pop(); _.trys.pop(); continue;
53 default:
54 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
55 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
56 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
57 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
58 if (t[2]) _.ops.pop();
59 _.trys.pop(); continue;
60 }
61 op = body.call(thisArg, _);
62 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
63 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
64 }
65}
66
67/**
68 * @license
69 * Copyright 2018 Google LLC
70 *
71 * Licensed under the Apache License, Version 2.0 (the "License");
72 * you may not use this file except in compliance with the License.
73 * You may obtain a copy of the License at
74 *
75 * http://www.apache.org/licenses/LICENSE-2.0
76 *
77 * Unless required by applicable law or agreed to in writing, software
78 * distributed under the License is distributed on an "AS IS" BASIS,
79 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80 * See the License for the specific language governing permissions and
81 * limitations under the License.
82 */
83var PROTO_ROOT = path.resolve(__dirname, "src/protos" );
84var PROTO_FILE = path.resolve(PROTO_ROOT, 'google/firestore/emulator/v1/firestore_emulator.proto');
85var PKG_DEF = protoLoader.loadSync(PROTO_FILE, { includeDirs: [PROTO_ROOT] });
86var PROTOS = grpc.loadPackageDefinition(PKG_DEF);
87var EMULATOR = PROTOS['google']['firestore']['emulator']['v1'];
88/** If this environment variable is set, use it for the database emulator's address. */
89var DATABASE_ADDRESS_ENV = 'FIREBASE_DATABASE_EMULATOR_ADDRESS';
90/** The default address for the local database emulator. */
91var DATABASE_ADDRESS_DEFAULT = 'localhost:9000';
92/** The actual address for the database emulator */
93var DATABASE_ADDRESS = process.env[DATABASE_ADDRESS_ENV] || DATABASE_ADDRESS_DEFAULT;
94/** If any of environment variable is set, use it for the Firestore emulator. */
95var FIRESTORE_ADDRESS_ENVS = [
96 'FIRESTORE_EMULATOR_HOST',
97 'FIREBASE_FIRESTORE_EMULATOR_ADDRESS'
98];
99/** The default address for the local Firestore emulator. */
100var FIRESTORE_ADDRESS_DEFAULT = 'localhost:8080';
101/** The actual address for the Firestore emulator */
102var FIRESTORE_ADDRESS = FIRESTORE_ADDRESS_ENVS.reduce(function (addr, name) { return process.env[name] || addr; }, FIRESTORE_ADDRESS_DEFAULT);
103/** Passing this in tells the emulator to treat you as an admin. */
104var ADMIN_TOKEN = 'owner';
105/** Create an unsecured JWT for the given auth payload. See https://tools.ietf.org/html/rfc7519#section-6. */
106function createUnsecuredJwt(auth) {
107 // Unsecured JWTs use "none" as the algorithm.
108 var header = {
109 alg: 'none',
110 kid: 'fakekid'
111 };
112 // Ensure that the auth payload has a value for 'iat'.
113 auth.iat = auth.iat || 0;
114 // Use `uid` field as a backup when `sub` is missing.
115 auth.sub = auth.sub || auth.uid;
116 if (!auth.sub) {
117 throw new Error("auth must be an object with a 'sub' or 'uid' field");
118 }
119 // Unsecured JWTs use the empty string as a signature.
120 var signature = '';
121 return [
122 util.base64.encodeString(JSON.stringify(header), /*webSafe=*/ false),
123 util.base64.encodeString(JSON.stringify(auth), /*webSafe=*/ false),
124 signature
125 ].join('.');
126}
127function apps() {
128 return firebase.apps;
129}
130/** Construct an App authenticated with options.auth. */
131function initializeTestApp(options) {
132 return initializeApp(options.auth ? createUnsecuredJwt(options.auth) : undefined, options.databaseName, options.projectId);
133}
134/** Construct an App authenticated as an admin user. */
135function initializeAdminApp(options) {
136 return initializeApp(ADMIN_TOKEN, options.databaseName, options.projectId);
137}
138function initializeApp(accessToken, databaseName, projectId) {
139 var _this = this;
140 var appOptions = {};
141 if (databaseName) {
142 appOptions['databaseURL'] = "http://" + DATABASE_ADDRESS + "?ns=" + databaseName;
143 }
144 if (projectId) {
145 appOptions['projectId'] = projectId;
146 }
147 var appName = 'app-' + new Date().getTime() + '-' + Math.random();
148 var app = firebase.initializeApp(appOptions, appName);
149 if (accessToken) {
150 var mockAuthComponent = new component.Component('auth-internal', function () {
151 return ({
152 getToken: function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
153 return [2 /*return*/, ({ accessToken: accessToken })];
154 }); }); },
155 getUid: function () { return null; },
156 addAuthTokenListener: function (listener) {
157 // Call listener once immediately with predefined accessToken.
158 listener(accessToken);
159 },
160 removeAuthTokenListener: function () { }
161 });
162 }, "PRIVATE" /* PRIVATE */);
163 app._addOrOverwriteComponent(mockAuthComponent);
164 }
165 if (databaseName) {
166 // Toggle network connectivity to force a reauthentication attempt.
167 // This mitigates a minor race condition where the client can send the
168 // first database request before authenticating.
169 app.database().goOffline();
170 app.database().goOnline();
171 }
172 if (projectId) {
173 app.firestore().settings({
174 host: FIRESTORE_ADDRESS,
175 ssl: false
176 });
177 }
178 /**
179 Mute warnings for the previously-created database and whatever other
180 objects were just created.
181 */
182 logger.setLogLevel(logger.LogLevel.ERROR);
183 return app;
184}
185function loadDatabaseRules(options) {
186 if (!options.databaseName) {
187 throw Error('databaseName not specified');
188 }
189 if (!options.rules) {
190 throw Error('must provide rules to loadDatabaseRules');
191 }
192 return new Promise(function (resolve, reject) {
193 request.put({
194 uri: "http://" + DATABASE_ADDRESS + "/.settings/rules.json?ns=" + options.databaseName,
195 headers: { Authorization: 'Bearer owner' },
196 body: options.rules
197 }, function (err, resp, body) {
198 if (err) {
199 reject(err);
200 }
201 else if (resp.statusCode !== 200) {
202 reject(JSON.parse(body).error);
203 }
204 else {
205 resolve();
206 }
207 });
208 });
209}
210function loadFirestoreRules(options) {
211 if (!options.projectId) {
212 throw new Error('projectId not specified');
213 }
214 if (!options.rules) {
215 throw new Error('must provide rules to loadFirestoreRules');
216 }
217 var client = new EMULATOR.FirestoreEmulator(FIRESTORE_ADDRESS, grpc.credentials.createInsecure());
218 return new Promise(function (resolve, reject) {
219 client.setSecurityRules({
220 project: "projects/" + options.projectId,
221 rules: { files: [{ content: options.rules }] }
222 },
223 // @ts-ignore Defined in protobuf.
224 function (err, resp) {
225 if (err) {
226 reject(err);
227 }
228 else {
229 resolve(resp);
230 }
231 });
232 });
233}
234function clearFirestoreData(options) {
235 if (!options.projectId) {
236 throw new Error('projectId not specified');
237 }
238 var client = new EMULATOR.FirestoreEmulator(FIRESTORE_ADDRESS, grpc.credentials.createInsecure(), {
239 // As with 'loadFirestoreRules', cap how much backoff gRPC will perform.
240 'grpc.initial_reconnect_backoff_ms': 100,
241 'grpc.max_reconnect_backoff_ms': 100
242 });
243 return new Promise(function (resolve, reject) {
244 client.clearData({
245 database: "projects/" + options.projectId + "/databases/(default)"
246 },
247 // @ts-ignore Defined in protobuf.
248 function (err, resp) {
249 if (err) {
250 reject(err);
251 }
252 else {
253 resolve(resp);
254 }
255 });
256 });
257}
258function assertFails(pr) {
259 return pr.then(function (v) {
260 return Promise.reject(new Error('Expected request to fail, but it succeeded.'));
261 }, function (err) { return err; });
262}
263function assertSucceeds(pr) {
264 return pr;
265}
266
267Object.defineProperty(exports, 'database', {
268 enumerable: true,
269 get: function () {
270 return firebase.database;
271 }
272});
273Object.defineProperty(exports, 'firestore', {
274 enumerable: true,
275 get: function () {
276 return firebase.firestore;
277 }
278});
279exports.apps = apps;
280exports.assertFails = assertFails;
281exports.assertSucceeds = assertSucceeds;
282exports.clearFirestoreData = clearFirestoreData;
283exports.initializeAdminApp = initializeAdminApp;
284exports.initializeTestApp = initializeTestApp;
285exports.loadDatabaseRules = loadDatabaseRules;
286exports.loadFirestoreRules = loadFirestoreRules;
287//# sourceMappingURL=index.cjs.js.map