UNPKG

59.2 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var app = require('@firebase/app');
6var component = require('@firebase/component');
7var tslib = require('tslib');
8var util = require('@firebase/util');
9var idb = require('idb');
10
11var name = "@firebase/installations";
12var version = "0.5.11";
13
14/**
15 * @license
16 * Copyright 2019 Google LLC
17 *
18 * Licensed under the Apache License, Version 2.0 (the "License");
19 * you may not use this file except in compliance with the License.
20 * You may obtain a copy of the License at
21 *
22 * http://www.apache.org/licenses/LICENSE-2.0
23 *
24 * Unless required by applicable law or agreed to in writing, software
25 * distributed under the License is distributed on an "AS IS" BASIS,
26 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27 * See the License for the specific language governing permissions and
28 * limitations under the License.
29 */
30var PENDING_TIMEOUT_MS = 10000;
31var PACKAGE_VERSION = "w:" + version;
32var INTERNAL_AUTH_VERSION = 'FIS_v2';
33var INSTALLATIONS_API_URL = 'https://firebaseinstallations.googleapis.com/v1';
34var TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour
35var SERVICE = 'installations';
36var SERVICE_NAME = 'Installations';
37
38/**
39 * @license
40 * Copyright 2019 Google LLC
41 *
42 * Licensed under the Apache License, Version 2.0 (the "License");
43 * you may not use this file except in compliance with the License.
44 * You may obtain a copy of the License at
45 *
46 * http://www.apache.org/licenses/LICENSE-2.0
47 *
48 * Unless required by applicable law or agreed to in writing, software
49 * distributed under the License is distributed on an "AS IS" BASIS,
50 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
51 * See the License for the specific language governing permissions and
52 * limitations under the License.
53 */
54var _a;
55var ERROR_DESCRIPTION_MAP = (_a = {},
56 _a["missing-app-config-values" /* MISSING_APP_CONFIG_VALUES */] = 'Missing App configuration value: "{$valueName}"',
57 _a["not-registered" /* NOT_REGISTERED */] = 'Firebase Installation is not registered.',
58 _a["installation-not-found" /* INSTALLATION_NOT_FOUND */] = 'Firebase Installation not found.',
59 _a["request-failed" /* REQUEST_FAILED */] = '{$requestName} request failed with error "{$serverCode} {$serverStatus}: {$serverMessage}"',
60 _a["app-offline" /* APP_OFFLINE */] = 'Could not process request. Application offline.',
61 _a["delete-pending-registration" /* DELETE_PENDING_REGISTRATION */] = "Can't delete installation while there is a pending registration request.",
62 _a);
63var ERROR_FACTORY = new util.ErrorFactory(SERVICE, SERVICE_NAME, ERROR_DESCRIPTION_MAP);
64/** Returns true if error is a FirebaseError that is based on an error from the server. */
65function isServerError(error) {
66 return (error instanceof util.FirebaseError &&
67 error.code.includes("request-failed" /* REQUEST_FAILED */));
68}
69
70/**
71 * @license
72 * Copyright 2019 Google LLC
73 *
74 * Licensed under the Apache License, Version 2.0 (the "License");
75 * you may not use this file except in compliance with the License.
76 * You may obtain a copy of the License at
77 *
78 * http://www.apache.org/licenses/LICENSE-2.0
79 *
80 * Unless required by applicable law or agreed to in writing, software
81 * distributed under the License is distributed on an "AS IS" BASIS,
82 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83 * See the License for the specific language governing permissions and
84 * limitations under the License.
85 */
86function getInstallationsEndpoint(_a) {
87 var projectId = _a.projectId;
88 return INSTALLATIONS_API_URL + "/projects/" + projectId + "/installations";
89}
90function extractAuthTokenInfoFromResponse(response) {
91 return {
92 token: response.token,
93 requestStatus: 2 /* COMPLETED */,
94 expiresIn: getExpiresInFromResponseExpiresIn(response.expiresIn),
95 creationTime: Date.now()
96 };
97}
98function getErrorFromResponse(requestName, response) {
99 return tslib.__awaiter(this, void 0, void 0, function () {
100 var responseJson, errorData;
101 return tslib.__generator(this, function (_a) {
102 switch (_a.label) {
103 case 0: return [4 /*yield*/, response.json()];
104 case 1:
105 responseJson = _a.sent();
106 errorData = responseJson.error;
107 return [2 /*return*/, ERROR_FACTORY.create("request-failed" /* REQUEST_FAILED */, {
108 requestName: requestName,
109 serverCode: errorData.code,
110 serverMessage: errorData.message,
111 serverStatus: errorData.status
112 })];
113 }
114 });
115 });
116}
117function getHeaders(_a) {
118 var apiKey = _a.apiKey;
119 return new Headers({
120 'Content-Type': 'application/json',
121 Accept: 'application/json',
122 'x-goog-api-key': apiKey
123 });
124}
125function getHeadersWithAuth(appConfig, _a) {
126 var refreshToken = _a.refreshToken;
127 var headers = getHeaders(appConfig);
128 headers.append('Authorization', getAuthorizationHeader(refreshToken));
129 return headers;
130}
131/**
132 * Calls the passed in fetch wrapper and returns the response.
133 * If the returned response has a status of 5xx, re-runs the function once and
134 * returns the response.
135 */
136function retryIfServerError(fn) {
137 return tslib.__awaiter(this, void 0, void 0, function () {
138 var result;
139 return tslib.__generator(this, function (_a) {
140 switch (_a.label) {
141 case 0: return [4 /*yield*/, fn()];
142 case 1:
143 result = _a.sent();
144 if (result.status >= 500 && result.status < 600) {
145 // Internal Server Error. Retry request.
146 return [2 /*return*/, fn()];
147 }
148 return [2 /*return*/, result];
149 }
150 });
151 });
152}
153function getExpiresInFromResponseExpiresIn(responseExpiresIn) {
154 // This works because the server will never respond with fractions of a second.
155 return Number(responseExpiresIn.replace('s', '000'));
156}
157function getAuthorizationHeader(refreshToken) {
158 return INTERNAL_AUTH_VERSION + " " + refreshToken;
159}
160
161/**
162 * @license
163 * Copyright 2019 Google LLC
164 *
165 * Licensed under the Apache License, Version 2.0 (the "License");
166 * you may not use this file except in compliance with the License.
167 * You may obtain a copy of the License at
168 *
169 * http://www.apache.org/licenses/LICENSE-2.0
170 *
171 * Unless required by applicable law or agreed to in writing, software
172 * distributed under the License is distributed on an "AS IS" BASIS,
173 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
174 * See the License for the specific language governing permissions and
175 * limitations under the License.
176 */
177function createInstallationRequest(_a, _b) {
178 var appConfig = _a.appConfig, heartbeatServiceProvider = _a.heartbeatServiceProvider;
179 var fid = _b.fid;
180 return tslib.__awaiter(this, void 0, void 0, function () {
181 var endpoint, headers, heartbeatService, heartbeatsHeader, body, request, response, responseValue, registeredInstallationEntry;
182 return tslib.__generator(this, function (_c) {
183 switch (_c.label) {
184 case 0:
185 endpoint = getInstallationsEndpoint(appConfig);
186 headers = getHeaders(appConfig);
187 heartbeatService = heartbeatServiceProvider.getImmediate({
188 optional: true
189 });
190 if (!heartbeatService) return [3 /*break*/, 2];
191 return [4 /*yield*/, heartbeatService.getHeartbeatsHeader()];
192 case 1:
193 heartbeatsHeader = _c.sent();
194 if (heartbeatsHeader) {
195 headers.append('x-firebase-client', heartbeatsHeader);
196 }
197 _c.label = 2;
198 case 2:
199 body = {
200 fid: fid,
201 authVersion: INTERNAL_AUTH_VERSION,
202 appId: appConfig.appId,
203 sdkVersion: PACKAGE_VERSION
204 };
205 request = {
206 method: 'POST',
207 headers: headers,
208 body: JSON.stringify(body)
209 };
210 return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })];
211 case 3:
212 response = _c.sent();
213 if (!response.ok) return [3 /*break*/, 5];
214 return [4 /*yield*/, response.json()];
215 case 4:
216 responseValue = _c.sent();
217 registeredInstallationEntry = {
218 fid: responseValue.fid || fid,
219 registrationStatus: 2 /* COMPLETED */,
220 refreshToken: responseValue.refreshToken,
221 authToken: extractAuthTokenInfoFromResponse(responseValue.authToken)
222 };
223 return [2 /*return*/, registeredInstallationEntry];
224 case 5: return [4 /*yield*/, getErrorFromResponse('Create Installation', response)];
225 case 6: throw _c.sent();
226 }
227 });
228 });
229}
230
231/**
232 * @license
233 * Copyright 2019 Google LLC
234 *
235 * Licensed under the Apache License, Version 2.0 (the "License");
236 * you may not use this file except in compliance with the License.
237 * You may obtain a copy of the License at
238 *
239 * http://www.apache.org/licenses/LICENSE-2.0
240 *
241 * Unless required by applicable law or agreed to in writing, software
242 * distributed under the License is distributed on an "AS IS" BASIS,
243 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
244 * See the License for the specific language governing permissions and
245 * limitations under the License.
246 */
247/** Returns a promise that resolves after given time passes. */
248function sleep(ms) {
249 return new Promise(function (resolve) {
250 setTimeout(resolve, ms);
251 });
252}
253
254/**
255 * @license
256 * Copyright 2019 Google LLC
257 *
258 * Licensed under the Apache License, Version 2.0 (the "License");
259 * you may not use this file except in compliance with the License.
260 * You may obtain a copy of the License at
261 *
262 * http://www.apache.org/licenses/LICENSE-2.0
263 *
264 * Unless required by applicable law or agreed to in writing, software
265 * distributed under the License is distributed on an "AS IS" BASIS,
266 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
267 * See the License for the specific language governing permissions and
268 * limitations under the License.
269 */
270function bufferToBase64UrlSafe(array) {
271 var b64 = btoa(String.fromCharCode.apply(String, tslib.__spreadArray([], tslib.__read(array))));
272 return b64.replace(/\+/g, '-').replace(/\//g, '_');
273}
274
275/**
276 * @license
277 * Copyright 2019 Google LLC
278 *
279 * Licensed under the Apache License, Version 2.0 (the "License");
280 * you may not use this file except in compliance with the License.
281 * You may obtain a copy of the License at
282 *
283 * http://www.apache.org/licenses/LICENSE-2.0
284 *
285 * Unless required by applicable law or agreed to in writing, software
286 * distributed under the License is distributed on an "AS IS" BASIS,
287 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
288 * See the License for the specific language governing permissions and
289 * limitations under the License.
290 */
291var VALID_FID_PATTERN = /^[cdef][\w-]{21}$/;
292var INVALID_FID = '';
293/**
294 * Generates a new FID using random values from Web Crypto API.
295 * Returns an empty string if FID generation fails for any reason.
296 */
297function generateFid() {
298 try {
299 // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5
300 // bytes. our implementation generates a 17 byte array instead.
301 var fidByteArray = new Uint8Array(17);
302 var crypto_1 = self.crypto || self.msCrypto;
303 crypto_1.getRandomValues(fidByteArray);
304 // Replace the first 4 random bits with the constant FID header of 0b0111.
305 fidByteArray[0] = 112 + (fidByteArray[0] % 16);
306 var fid = encode(fidByteArray);
307 return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID;
308 }
309 catch (_a) {
310 // FID generation errored
311 return INVALID_FID;
312 }
313}
314/** Converts a FID Uint8Array to a base64 string representation. */
315function encode(fidByteArray) {
316 var b64String = bufferToBase64UrlSafe(fidByteArray);
317 // Remove the 23rd character that was added because of the extra 4 bits at the
318 // end of our 17 byte array, and the '=' padding.
319 return b64String.substr(0, 22);
320}
321
322/**
323 * @license
324 * Copyright 2019 Google LLC
325 *
326 * Licensed under the Apache License, Version 2.0 (the "License");
327 * you may not use this file except in compliance with the License.
328 * You may obtain a copy of the License at
329 *
330 * http://www.apache.org/licenses/LICENSE-2.0
331 *
332 * Unless required by applicable law or agreed to in writing, software
333 * distributed under the License is distributed on an "AS IS" BASIS,
334 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
335 * See the License for the specific language governing permissions and
336 * limitations under the License.
337 */
338/** Returns a string key that can be used to identify the app. */
339function getKey(appConfig) {
340 return appConfig.appName + "!" + appConfig.appId;
341}
342
343/**
344 * @license
345 * Copyright 2019 Google LLC
346 *
347 * Licensed under the Apache License, Version 2.0 (the "License");
348 * you may not use this file except in compliance with the License.
349 * You may obtain a copy of the License at
350 *
351 * http://www.apache.org/licenses/LICENSE-2.0
352 *
353 * Unless required by applicable law or agreed to in writing, software
354 * distributed under the License is distributed on an "AS IS" BASIS,
355 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
356 * See the License for the specific language governing permissions and
357 * limitations under the License.
358 */
359var fidChangeCallbacks = new Map();
360/**
361 * Calls the onIdChange callbacks with the new FID value, and broadcasts the
362 * change to other tabs.
363 */
364function fidChanged(appConfig, fid) {
365 var key = getKey(appConfig);
366 callFidChangeCallbacks(key, fid);
367 broadcastFidChange(key, fid);
368}
369function addCallback(appConfig, callback) {
370 // Open the broadcast channel if it's not already open,
371 // to be able to listen to change events from other tabs.
372 getBroadcastChannel();
373 var key = getKey(appConfig);
374 var callbackSet = fidChangeCallbacks.get(key);
375 if (!callbackSet) {
376 callbackSet = new Set();
377 fidChangeCallbacks.set(key, callbackSet);
378 }
379 callbackSet.add(callback);
380}
381function removeCallback(appConfig, callback) {
382 var key = getKey(appConfig);
383 var callbackSet = fidChangeCallbacks.get(key);
384 if (!callbackSet) {
385 return;
386 }
387 callbackSet.delete(callback);
388 if (callbackSet.size === 0) {
389 fidChangeCallbacks.delete(key);
390 }
391 // Close broadcast channel if there are no more callbacks.
392 closeBroadcastChannel();
393}
394function callFidChangeCallbacks(key, fid) {
395 var e_1, _a;
396 var callbacks = fidChangeCallbacks.get(key);
397 if (!callbacks) {
398 return;
399 }
400 try {
401 for (var callbacks_1 = tslib.__values(callbacks), callbacks_1_1 = callbacks_1.next(); !callbacks_1_1.done; callbacks_1_1 = callbacks_1.next()) {
402 var callback = callbacks_1_1.value;
403 callback(fid);
404 }
405 }
406 catch (e_1_1) { e_1 = { error: e_1_1 }; }
407 finally {
408 try {
409 if (callbacks_1_1 && !callbacks_1_1.done && (_a = callbacks_1.return)) _a.call(callbacks_1);
410 }
411 finally { if (e_1) throw e_1.error; }
412 }
413}
414function broadcastFidChange(key, fid) {
415 var channel = getBroadcastChannel();
416 if (channel) {
417 channel.postMessage({ key: key, fid: fid });
418 }
419 closeBroadcastChannel();
420}
421var broadcastChannel = null;
422/** Opens and returns a BroadcastChannel if it is supported by the browser. */
423function getBroadcastChannel() {
424 if (!broadcastChannel && 'BroadcastChannel' in self) {
425 broadcastChannel = new BroadcastChannel('[Firebase] FID Change');
426 broadcastChannel.onmessage = function (e) {
427 callFidChangeCallbacks(e.data.key, e.data.fid);
428 };
429 }
430 return broadcastChannel;
431}
432function closeBroadcastChannel() {
433 if (fidChangeCallbacks.size === 0 && broadcastChannel) {
434 broadcastChannel.close();
435 broadcastChannel = null;
436 }
437}
438
439/**
440 * @license
441 * Copyright 2019 Google LLC
442 *
443 * Licensed under the Apache License, Version 2.0 (the "License");
444 * you may not use this file except in compliance with the License.
445 * You may obtain a copy of the License at
446 *
447 * http://www.apache.org/licenses/LICENSE-2.0
448 *
449 * Unless required by applicable law or agreed to in writing, software
450 * distributed under the License is distributed on an "AS IS" BASIS,
451 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
452 * See the License for the specific language governing permissions and
453 * limitations under the License.
454 */
455var DATABASE_NAME = 'firebase-installations-database';
456var DATABASE_VERSION = 1;
457var OBJECT_STORE_NAME = 'firebase-installations-store';
458var dbPromise = null;
459function getDbPromise() {
460 if (!dbPromise) {
461 dbPromise = idb.openDB(DATABASE_NAME, DATABASE_VERSION, {
462 upgrade: function (db, oldVersion) {
463 // We don't use 'break' in this switch statement, the fall-through
464 // behavior is what we want, because if there are multiple versions between
465 // the old version and the current version, we want ALL the migrations
466 // that correspond to those versions to run, not only the last one.
467 // eslint-disable-next-line default-case
468 switch (oldVersion) {
469 case 0:
470 db.createObjectStore(OBJECT_STORE_NAME);
471 }
472 }
473 });
474 }
475 return dbPromise;
476}
477/** Assigns or overwrites the record for the given key with the given value. */
478function set(appConfig, value) {
479 return tslib.__awaiter(this, void 0, void 0, function () {
480 var key, db, tx, objectStore, oldValue;
481 return tslib.__generator(this, function (_a) {
482 switch (_a.label) {
483 case 0:
484 key = getKey(appConfig);
485 return [4 /*yield*/, getDbPromise()];
486 case 1:
487 db = _a.sent();
488 tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
489 objectStore = tx.objectStore(OBJECT_STORE_NAME);
490 return [4 /*yield*/, objectStore.get(key)];
491 case 2:
492 oldValue = (_a.sent());
493 return [4 /*yield*/, objectStore.put(value, key)];
494 case 3:
495 _a.sent();
496 return [4 /*yield*/, tx.done];
497 case 4:
498 _a.sent();
499 if (!oldValue || oldValue.fid !== value.fid) {
500 fidChanged(appConfig, value.fid);
501 }
502 return [2 /*return*/, value];
503 }
504 });
505 });
506}
507/** Removes record(s) from the objectStore that match the given key. */
508function remove(appConfig) {
509 return tslib.__awaiter(this, void 0, void 0, function () {
510 var key, db, tx;
511 return tslib.__generator(this, function (_a) {
512 switch (_a.label) {
513 case 0:
514 key = getKey(appConfig);
515 return [4 /*yield*/, getDbPromise()];
516 case 1:
517 db = _a.sent();
518 tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
519 return [4 /*yield*/, tx.objectStore(OBJECT_STORE_NAME).delete(key)];
520 case 2:
521 _a.sent();
522 return [4 /*yield*/, tx.done];
523 case 3:
524 _a.sent();
525 return [2 /*return*/];
526 }
527 });
528 });
529}
530/**
531 * Atomically updates a record with the result of updateFn, which gets
532 * called with the current value. If newValue is undefined, the record is
533 * deleted instead.
534 * @return Updated value
535 */
536function update(appConfig, updateFn) {
537 return tslib.__awaiter(this, void 0, void 0, function () {
538 var key, db, tx, store, oldValue, newValue;
539 return tslib.__generator(this, function (_a) {
540 switch (_a.label) {
541 case 0:
542 key = getKey(appConfig);
543 return [4 /*yield*/, getDbPromise()];
544 case 1:
545 db = _a.sent();
546 tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
547 store = tx.objectStore(OBJECT_STORE_NAME);
548 return [4 /*yield*/, store.get(key)];
549 case 2:
550 oldValue = (_a.sent());
551 newValue = updateFn(oldValue);
552 if (!(newValue === undefined)) return [3 /*break*/, 4];
553 return [4 /*yield*/, store.delete(key)];
554 case 3:
555 _a.sent();
556 return [3 /*break*/, 6];
557 case 4: return [4 /*yield*/, store.put(newValue, key)];
558 case 5:
559 _a.sent();
560 _a.label = 6;
561 case 6: return [4 /*yield*/, tx.done];
562 case 7:
563 _a.sent();
564 if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) {
565 fidChanged(appConfig, newValue.fid);
566 }
567 return [2 /*return*/, newValue];
568 }
569 });
570 });
571}
572
573/**
574 * @license
575 * Copyright 2019 Google LLC
576 *
577 * Licensed under the Apache License, Version 2.0 (the "License");
578 * you may not use this file except in compliance with the License.
579 * You may obtain a copy of the License at
580 *
581 * http://www.apache.org/licenses/LICENSE-2.0
582 *
583 * Unless required by applicable law or agreed to in writing, software
584 * distributed under the License is distributed on an "AS IS" BASIS,
585 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
586 * See the License for the specific language governing permissions and
587 * limitations under the License.
588 */
589/**
590 * Updates and returns the InstallationEntry from the database.
591 * Also triggers a registration request if it is necessary and possible.
592 */
593function getInstallationEntry(installations) {
594 return tslib.__awaiter(this, void 0, void 0, function () {
595 var registrationPromise, installationEntry;
596 var _a;
597 return tslib.__generator(this, function (_b) {
598 switch (_b.label) {
599 case 0: return [4 /*yield*/, update(installations.appConfig, function (oldEntry) {
600 var installationEntry = updateOrCreateInstallationEntry(oldEntry);
601 var entryWithPromise = triggerRegistrationIfNecessary(installations, installationEntry);
602 registrationPromise = entryWithPromise.registrationPromise;
603 return entryWithPromise.installationEntry;
604 })];
605 case 1:
606 installationEntry = _b.sent();
607 if (!(installationEntry.fid === INVALID_FID)) return [3 /*break*/, 3];
608 _a = {};
609 return [4 /*yield*/, registrationPromise];
610 case 2:
611 // FID generation failed. Waiting for the FID from the server.
612 return [2 /*return*/, (_a.installationEntry = _b.sent(), _a)];
613 case 3: return [2 /*return*/, {
614 installationEntry: installationEntry,
615 registrationPromise: registrationPromise
616 }];
617 }
618 });
619 });
620}
621/**
622 * Creates a new Installation Entry if one does not exist.
623 * Also clears timed out pending requests.
624 */
625function updateOrCreateInstallationEntry(oldEntry) {
626 var entry = oldEntry || {
627 fid: generateFid(),
628 registrationStatus: 0 /* NOT_STARTED */
629 };
630 return clearTimedOutRequest(entry);
631}
632/**
633 * If the Firebase Installation is not registered yet, this will trigger the
634 * registration and return an InProgressInstallationEntry.
635 *
636 * If registrationPromise does not exist, the installationEntry is guaranteed
637 * to be registered.
638 */
639function triggerRegistrationIfNecessary(installations, installationEntry) {
640 if (installationEntry.registrationStatus === 0 /* NOT_STARTED */) {
641 if (!navigator.onLine) {
642 // Registration required but app is offline.
643 var registrationPromiseWithError = Promise.reject(ERROR_FACTORY.create("app-offline" /* APP_OFFLINE */));
644 return {
645 installationEntry: installationEntry,
646 registrationPromise: registrationPromiseWithError
647 };
648 }
649 // Try registering. Change status to IN_PROGRESS.
650 var inProgressEntry = {
651 fid: installationEntry.fid,
652 registrationStatus: 1 /* IN_PROGRESS */,
653 registrationTime: Date.now()
654 };
655 var registrationPromise = registerInstallation(installations, inProgressEntry);
656 return { installationEntry: inProgressEntry, registrationPromise: registrationPromise };
657 }
658 else if (installationEntry.registrationStatus === 1 /* IN_PROGRESS */) {
659 return {
660 installationEntry: installationEntry,
661 registrationPromise: waitUntilFidRegistration(installations)
662 };
663 }
664 else {
665 return { installationEntry: installationEntry };
666 }
667}
668/** This will be executed only once for each new Firebase Installation. */
669function registerInstallation(installations, installationEntry) {
670 return tslib.__awaiter(this, void 0, void 0, function () {
671 var registeredInstallationEntry, e_1;
672 return tslib.__generator(this, function (_a) {
673 switch (_a.label) {
674 case 0:
675 _a.trys.push([0, 2, , 7]);
676 return [4 /*yield*/, createInstallationRequest(installations, installationEntry)];
677 case 1:
678 registeredInstallationEntry = _a.sent();
679 return [2 /*return*/, set(installations.appConfig, registeredInstallationEntry)];
680 case 2:
681 e_1 = _a.sent();
682 if (!(isServerError(e_1) && e_1.customData.serverCode === 409)) return [3 /*break*/, 4];
683 // Server returned a "FID can not be used" error.
684 // Generate a new ID next time.
685 return [4 /*yield*/, remove(installations.appConfig)];
686 case 3:
687 // Server returned a "FID can not be used" error.
688 // Generate a new ID next time.
689 _a.sent();
690 return [3 /*break*/, 6];
691 case 4:
692 // Registration failed. Set FID as not registered.
693 return [4 /*yield*/, set(installations.appConfig, {
694 fid: installationEntry.fid,
695 registrationStatus: 0 /* NOT_STARTED */
696 })];
697 case 5:
698 // Registration failed. Set FID as not registered.
699 _a.sent();
700 _a.label = 6;
701 case 6: throw e_1;
702 case 7: return [2 /*return*/];
703 }
704 });
705 });
706}
707/** Call if FID registration is pending in another request. */
708function waitUntilFidRegistration(installations) {
709 return tslib.__awaiter(this, void 0, void 0, function () {
710 var entry, _a, installationEntry, registrationPromise;
711 return tslib.__generator(this, function (_b) {
712 switch (_b.label) {
713 case 0: return [4 /*yield*/, updateInstallationRequest(installations.appConfig)];
714 case 1:
715 entry = _b.sent();
716 _b.label = 2;
717 case 2:
718 if (!(entry.registrationStatus === 1 /* IN_PROGRESS */)) return [3 /*break*/, 5];
719 // createInstallation request still in progress.
720 return [4 /*yield*/, sleep(100)];
721 case 3:
722 // createInstallation request still in progress.
723 _b.sent();
724 return [4 /*yield*/, updateInstallationRequest(installations.appConfig)];
725 case 4:
726 entry = _b.sent();
727 return [3 /*break*/, 2];
728 case 5:
729 if (!(entry.registrationStatus === 0 /* NOT_STARTED */)) return [3 /*break*/, 7];
730 return [4 /*yield*/, getInstallationEntry(installations)];
731 case 6:
732 _a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
733 if (registrationPromise) {
734 return [2 /*return*/, registrationPromise];
735 }
736 else {
737 // if there is no registrationPromise, entry is registered.
738 return [2 /*return*/, installationEntry];
739 }
740 case 7: return [2 /*return*/, entry];
741 }
742 });
743 });
744}
745/**
746 * Called only if there is a CreateInstallation request in progress.
747 *
748 * Updates the InstallationEntry in the DB based on the status of the
749 * CreateInstallation request.
750 *
751 * Returns the updated InstallationEntry.
752 */
753function updateInstallationRequest(appConfig) {
754 return update(appConfig, function (oldEntry) {
755 if (!oldEntry) {
756 throw ERROR_FACTORY.create("installation-not-found" /* INSTALLATION_NOT_FOUND */);
757 }
758 return clearTimedOutRequest(oldEntry);
759 });
760}
761function clearTimedOutRequest(entry) {
762 if (hasInstallationRequestTimedOut(entry)) {
763 return {
764 fid: entry.fid,
765 registrationStatus: 0 /* NOT_STARTED */
766 };
767 }
768 return entry;
769}
770function hasInstallationRequestTimedOut(installationEntry) {
771 return (installationEntry.registrationStatus === 1 /* IN_PROGRESS */ &&
772 installationEntry.registrationTime + PENDING_TIMEOUT_MS < Date.now());
773}
774
775/**
776 * @license
777 * Copyright 2019 Google LLC
778 *
779 * Licensed under the Apache License, Version 2.0 (the "License");
780 * you may not use this file except in compliance with the License.
781 * You may obtain a copy of the License at
782 *
783 * http://www.apache.org/licenses/LICENSE-2.0
784 *
785 * Unless required by applicable law or agreed to in writing, software
786 * distributed under the License is distributed on an "AS IS" BASIS,
787 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
788 * See the License for the specific language governing permissions and
789 * limitations under the License.
790 */
791function generateAuthTokenRequest(_a, installationEntry) {
792 var appConfig = _a.appConfig, heartbeatServiceProvider = _a.heartbeatServiceProvider;
793 return tslib.__awaiter(this, void 0, void 0, function () {
794 var endpoint, headers, heartbeatService, heartbeatsHeader, body, request, response, responseValue, completedAuthToken;
795 return tslib.__generator(this, function (_b) {
796 switch (_b.label) {
797 case 0:
798 endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);
799 headers = getHeadersWithAuth(appConfig, installationEntry);
800 heartbeatService = heartbeatServiceProvider.getImmediate({
801 optional: true
802 });
803 if (!heartbeatService) return [3 /*break*/, 2];
804 return [4 /*yield*/, heartbeatService.getHeartbeatsHeader()];
805 case 1:
806 heartbeatsHeader = _b.sent();
807 if (heartbeatsHeader) {
808 headers.append('x-firebase-client', heartbeatsHeader);
809 }
810 _b.label = 2;
811 case 2:
812 body = {
813 installation: {
814 sdkVersion: PACKAGE_VERSION,
815 appId: appConfig.appId
816 }
817 };
818 request = {
819 method: 'POST',
820 headers: headers,
821 body: JSON.stringify(body)
822 };
823 return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })];
824 case 3:
825 response = _b.sent();
826 if (!response.ok) return [3 /*break*/, 5];
827 return [4 /*yield*/, response.json()];
828 case 4:
829 responseValue = _b.sent();
830 completedAuthToken = extractAuthTokenInfoFromResponse(responseValue);
831 return [2 /*return*/, completedAuthToken];
832 case 5: return [4 /*yield*/, getErrorFromResponse('Generate Auth Token', response)];
833 case 6: throw _b.sent();
834 }
835 });
836 });
837}
838function getGenerateAuthTokenEndpoint(appConfig, _a) {
839 var fid = _a.fid;
840 return getInstallationsEndpoint(appConfig) + "/" + fid + "/authTokens:generate";
841}
842
843/**
844 * @license
845 * Copyright 2019 Google LLC
846 *
847 * Licensed under the Apache License, Version 2.0 (the "License");
848 * you may not use this file except in compliance with the License.
849 * You may obtain a copy of the License at
850 *
851 * http://www.apache.org/licenses/LICENSE-2.0
852 *
853 * Unless required by applicable law or agreed to in writing, software
854 * distributed under the License is distributed on an "AS IS" BASIS,
855 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
856 * See the License for the specific language governing permissions and
857 * limitations under the License.
858 */
859/**
860 * Returns a valid authentication token for the installation. Generates a new
861 * token if one doesn't exist, is expired or about to expire.
862 *
863 * Should only be called if the Firebase Installation is registered.
864 */
865function refreshAuthToken(installations, forceRefresh) {
866 if (forceRefresh === void 0) { forceRefresh = false; }
867 return tslib.__awaiter(this, void 0, void 0, function () {
868 var tokenPromise, entry, authToken, _a;
869 return tslib.__generator(this, function (_b) {
870 switch (_b.label) {
871 case 0: return [4 /*yield*/, update(installations.appConfig, function (oldEntry) {
872 if (!isEntryRegistered(oldEntry)) {
873 throw ERROR_FACTORY.create("not-registered" /* NOT_REGISTERED */);
874 }
875 var oldAuthToken = oldEntry.authToken;
876 if (!forceRefresh && isAuthTokenValid(oldAuthToken)) {
877 // There is a valid token in the DB.
878 return oldEntry;
879 }
880 else if (oldAuthToken.requestStatus === 1 /* IN_PROGRESS */) {
881 // There already is a token request in progress.
882 tokenPromise = waitUntilAuthTokenRequest(installations, forceRefresh);
883 return oldEntry;
884 }
885 else {
886 // No token or token expired.
887 if (!navigator.onLine) {
888 throw ERROR_FACTORY.create("app-offline" /* APP_OFFLINE */);
889 }
890 var inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry);
891 tokenPromise = fetchAuthTokenFromServer(installations, inProgressEntry);
892 return inProgressEntry;
893 }
894 })];
895 case 1:
896 entry = _b.sent();
897 if (!tokenPromise) return [3 /*break*/, 3];
898 return [4 /*yield*/, tokenPromise];
899 case 2:
900 _a = _b.sent();
901 return [3 /*break*/, 4];
902 case 3:
903 _a = entry.authToken;
904 _b.label = 4;
905 case 4:
906 authToken = _a;
907 return [2 /*return*/, authToken];
908 }
909 });
910 });
911}
912/**
913 * Call only if FID is registered and Auth Token request is in progress.
914 *
915 * Waits until the current pending request finishes. If the request times out,
916 * tries once in this thread as well.
917 */
918function waitUntilAuthTokenRequest(installations, forceRefresh) {
919 return tslib.__awaiter(this, void 0, void 0, function () {
920 var entry, authToken;
921 return tslib.__generator(this, function (_a) {
922 switch (_a.label) {
923 case 0: return [4 /*yield*/, updateAuthTokenRequest(installations.appConfig)];
924 case 1:
925 entry = _a.sent();
926 _a.label = 2;
927 case 2:
928 if (!(entry.authToken.requestStatus === 1 /* IN_PROGRESS */)) return [3 /*break*/, 5];
929 // generateAuthToken still in progress.
930 return [4 /*yield*/, sleep(100)];
931 case 3:
932 // generateAuthToken still in progress.
933 _a.sent();
934 return [4 /*yield*/, updateAuthTokenRequest(installations.appConfig)];
935 case 4:
936 entry = _a.sent();
937 return [3 /*break*/, 2];
938 case 5:
939 authToken = entry.authToken;
940 if (authToken.requestStatus === 0 /* NOT_STARTED */) {
941 // The request timed out or failed in a different call. Try again.
942 return [2 /*return*/, refreshAuthToken(installations, forceRefresh)];
943 }
944 else {
945 return [2 /*return*/, authToken];
946 }
947 }
948 });
949 });
950}
951/**
952 * Called only if there is a GenerateAuthToken request in progress.
953 *
954 * Updates the InstallationEntry in the DB based on the status of the
955 * GenerateAuthToken request.
956 *
957 * Returns the updated InstallationEntry.
958 */
959function updateAuthTokenRequest(appConfig) {
960 return update(appConfig, function (oldEntry) {
961 if (!isEntryRegistered(oldEntry)) {
962 throw ERROR_FACTORY.create("not-registered" /* NOT_REGISTERED */);
963 }
964 var oldAuthToken = oldEntry.authToken;
965 if (hasAuthTokenRequestTimedOut(oldAuthToken)) {
966 return tslib.__assign(tslib.__assign({}, oldEntry), { authToken: { requestStatus: 0 /* NOT_STARTED */ } });
967 }
968 return oldEntry;
969 });
970}
971function fetchAuthTokenFromServer(installations, installationEntry) {
972 return tslib.__awaiter(this, void 0, void 0, function () {
973 var authToken, updatedInstallationEntry, e_1, updatedInstallationEntry;
974 return tslib.__generator(this, function (_a) {
975 switch (_a.label) {
976 case 0:
977 _a.trys.push([0, 3, , 8]);
978 return [4 /*yield*/, generateAuthTokenRequest(installations, installationEntry)];
979 case 1:
980 authToken = _a.sent();
981 updatedInstallationEntry = tslib.__assign(tslib.__assign({}, installationEntry), { authToken: authToken });
982 return [4 /*yield*/, set(installations.appConfig, updatedInstallationEntry)];
983 case 2:
984 _a.sent();
985 return [2 /*return*/, authToken];
986 case 3:
987 e_1 = _a.sent();
988 if (!(isServerError(e_1) &&
989 (e_1.customData.serverCode === 401 || e_1.customData.serverCode === 404))) return [3 /*break*/, 5];
990 // Server returned a "FID not found" or a "Invalid authentication" error.
991 // Generate a new ID next time.
992 return [4 /*yield*/, remove(installations.appConfig)];
993 case 4:
994 // Server returned a "FID not found" or a "Invalid authentication" error.
995 // Generate a new ID next time.
996 _a.sent();
997 return [3 /*break*/, 7];
998 case 5:
999 updatedInstallationEntry = tslib.__assign(tslib.__assign({}, installationEntry), { authToken: { requestStatus: 0 /* NOT_STARTED */ } });
1000 return [4 /*yield*/, set(installations.appConfig, updatedInstallationEntry)];
1001 case 6:
1002 _a.sent();
1003 _a.label = 7;
1004 case 7: throw e_1;
1005 case 8: return [2 /*return*/];
1006 }
1007 });
1008 });
1009}
1010function isEntryRegistered(installationEntry) {
1011 return (installationEntry !== undefined &&
1012 installationEntry.registrationStatus === 2 /* COMPLETED */);
1013}
1014function isAuthTokenValid(authToken) {
1015 return (authToken.requestStatus === 2 /* COMPLETED */ &&
1016 !isAuthTokenExpired(authToken));
1017}
1018function isAuthTokenExpired(authToken) {
1019 var now = Date.now();
1020 return (now < authToken.creationTime ||
1021 authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER);
1022}
1023/** Returns an updated InstallationEntry with an InProgressAuthToken. */
1024function makeAuthTokenRequestInProgressEntry(oldEntry) {
1025 var inProgressAuthToken = {
1026 requestStatus: 1 /* IN_PROGRESS */,
1027 requestTime: Date.now()
1028 };
1029 return tslib.__assign(tslib.__assign({}, oldEntry), { authToken: inProgressAuthToken });
1030}
1031function hasAuthTokenRequestTimedOut(authToken) {
1032 return (authToken.requestStatus === 1 /* IN_PROGRESS */ &&
1033 authToken.requestTime + PENDING_TIMEOUT_MS < Date.now());
1034}
1035
1036/**
1037 * @license
1038 * Copyright 2019 Google LLC
1039 *
1040 * Licensed under the Apache License, Version 2.0 (the "License");
1041 * you may not use this file except in compliance with the License.
1042 * You may obtain a copy of the License at
1043 *
1044 * http://www.apache.org/licenses/LICENSE-2.0
1045 *
1046 * Unless required by applicable law or agreed to in writing, software
1047 * distributed under the License is distributed on an "AS IS" BASIS,
1048 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1049 * See the License for the specific language governing permissions and
1050 * limitations under the License.
1051 */
1052/**
1053 * Creates a Firebase Installation if there isn't one for the app and
1054 * returns the Installation ID.
1055 * @param installations - The `Installations` instance.
1056 *
1057 * @public
1058 */
1059function getId(installations) {
1060 return tslib.__awaiter(this, void 0, void 0, function () {
1061 var installationsImpl, _a, installationEntry, registrationPromise;
1062 return tslib.__generator(this, function (_b) {
1063 switch (_b.label) {
1064 case 0:
1065 installationsImpl = installations;
1066 return [4 /*yield*/, getInstallationEntry(installationsImpl)];
1067 case 1:
1068 _a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
1069 if (registrationPromise) {
1070 registrationPromise.catch(console.error);
1071 }
1072 else {
1073 // If the installation is already registered, update the authentication
1074 // token if needed.
1075 refreshAuthToken(installationsImpl).catch(console.error);
1076 }
1077 return [2 /*return*/, installationEntry.fid];
1078 }
1079 });
1080 });
1081}
1082
1083/**
1084 * @license
1085 * Copyright 2019 Google LLC
1086 *
1087 * Licensed under the Apache License, Version 2.0 (the "License");
1088 * you may not use this file except in compliance with the License.
1089 * You may obtain a copy of the License at
1090 *
1091 * http://www.apache.org/licenses/LICENSE-2.0
1092 *
1093 * Unless required by applicable law or agreed to in writing, software
1094 * distributed under the License is distributed on an "AS IS" BASIS,
1095 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1096 * See the License for the specific language governing permissions and
1097 * limitations under the License.
1098 */
1099/**
1100 * Returns a Firebase Installations auth token, identifying the current
1101 * Firebase Installation.
1102 * @param installations - The `Installations` instance.
1103 * @param forceRefresh - Force refresh regardless of token expiration.
1104 *
1105 * @public
1106 */
1107function getToken(installations, forceRefresh) {
1108 if (forceRefresh === void 0) { forceRefresh = false; }
1109 return tslib.__awaiter(this, void 0, void 0, function () {
1110 var installationsImpl, authToken;
1111 return tslib.__generator(this, function (_a) {
1112 switch (_a.label) {
1113 case 0:
1114 installationsImpl = installations;
1115 return [4 /*yield*/, completeInstallationRegistration(installationsImpl)];
1116 case 1:
1117 _a.sent();
1118 return [4 /*yield*/, refreshAuthToken(installationsImpl, forceRefresh)];
1119 case 2:
1120 authToken = _a.sent();
1121 return [2 /*return*/, authToken.token];
1122 }
1123 });
1124 });
1125}
1126function completeInstallationRegistration(installations) {
1127 return tslib.__awaiter(this, void 0, void 0, function () {
1128 var registrationPromise;
1129 return tslib.__generator(this, function (_a) {
1130 switch (_a.label) {
1131 case 0: return [4 /*yield*/, getInstallationEntry(installations)];
1132 case 1:
1133 registrationPromise = (_a.sent()).registrationPromise;
1134 if (!registrationPromise) return [3 /*break*/, 3];
1135 // A createInstallation request is in progress. Wait until it finishes.
1136 return [4 /*yield*/, registrationPromise];
1137 case 2:
1138 // A createInstallation request is in progress. Wait until it finishes.
1139 _a.sent();
1140 _a.label = 3;
1141 case 3: return [2 /*return*/];
1142 }
1143 });
1144 });
1145}
1146
1147/**
1148 * @license
1149 * Copyright 2019 Google LLC
1150 *
1151 * Licensed under the Apache License, Version 2.0 (the "License");
1152 * you may not use this file except in compliance with the License.
1153 * You may obtain a copy of the License at
1154 *
1155 * http://www.apache.org/licenses/LICENSE-2.0
1156 *
1157 * Unless required by applicable law or agreed to in writing, software
1158 * distributed under the License is distributed on an "AS IS" BASIS,
1159 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1160 * See the License for the specific language governing permissions and
1161 * limitations under the License.
1162 */
1163function deleteInstallationRequest(appConfig, installationEntry) {
1164 return tslib.__awaiter(this, void 0, void 0, function () {
1165 var endpoint, headers, request, response;
1166 return tslib.__generator(this, function (_a) {
1167 switch (_a.label) {
1168 case 0:
1169 endpoint = getDeleteEndpoint(appConfig, installationEntry);
1170 headers = getHeadersWithAuth(appConfig, installationEntry);
1171 request = {
1172 method: 'DELETE',
1173 headers: headers
1174 };
1175 return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })];
1176 case 1:
1177 response = _a.sent();
1178 if (!!response.ok) return [3 /*break*/, 3];
1179 return [4 /*yield*/, getErrorFromResponse('Delete Installation', response)];
1180 case 2: throw _a.sent();
1181 case 3: return [2 /*return*/];
1182 }
1183 });
1184 });
1185}
1186function getDeleteEndpoint(appConfig, _a) {
1187 var fid = _a.fid;
1188 return getInstallationsEndpoint(appConfig) + "/" + fid;
1189}
1190
1191/**
1192 * @license
1193 * Copyright 2019 Google LLC
1194 *
1195 * Licensed under the Apache License, Version 2.0 (the "License");
1196 * you may not use this file except in compliance with the License.
1197 * You may obtain a copy of the License at
1198 *
1199 * http://www.apache.org/licenses/LICENSE-2.0
1200 *
1201 * Unless required by applicable law or agreed to in writing, software
1202 * distributed under the License is distributed on an "AS IS" BASIS,
1203 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1204 * See the License for the specific language governing permissions and
1205 * limitations under the License.
1206 */
1207/**
1208 * Deletes the Firebase Installation and all associated data.
1209 * @param installations - The `Installations` instance.
1210 *
1211 * @public
1212 */
1213function deleteInstallations(installations) {
1214 return tslib.__awaiter(this, void 0, void 0, function () {
1215 var appConfig, entry;
1216 return tslib.__generator(this, function (_a) {
1217 switch (_a.label) {
1218 case 0:
1219 appConfig = installations.appConfig;
1220 return [4 /*yield*/, update(appConfig, function (oldEntry) {
1221 if (oldEntry && oldEntry.registrationStatus === 0 /* NOT_STARTED */) {
1222 // Delete the unregistered entry without sending a deleteInstallation request.
1223 return undefined;
1224 }
1225 return oldEntry;
1226 })];
1227 case 1:
1228 entry = _a.sent();
1229 if (!entry) return [3 /*break*/, 6];
1230 if (!(entry.registrationStatus === 1 /* IN_PROGRESS */)) return [3 /*break*/, 2];
1231 // Can't delete while trying to register.
1232 throw ERROR_FACTORY.create("delete-pending-registration" /* DELETE_PENDING_REGISTRATION */);
1233 case 2:
1234 if (!(entry.registrationStatus === 2 /* COMPLETED */)) return [3 /*break*/, 6];
1235 if (!!navigator.onLine) return [3 /*break*/, 3];
1236 throw ERROR_FACTORY.create("app-offline" /* APP_OFFLINE */);
1237 case 3: return [4 /*yield*/, deleteInstallationRequest(appConfig, entry)];
1238 case 4:
1239 _a.sent();
1240 return [4 /*yield*/, remove(appConfig)];
1241 case 5:
1242 _a.sent();
1243 _a.label = 6;
1244 case 6: return [2 /*return*/];
1245 }
1246 });
1247 });
1248}
1249
1250/**
1251 * @license
1252 * Copyright 2019 Google LLC
1253 *
1254 * Licensed under the Apache License, Version 2.0 (the "License");
1255 * you may not use this file except in compliance with the License.
1256 * You may obtain a copy of the License at
1257 *
1258 * http://www.apache.org/licenses/LICENSE-2.0
1259 *
1260 * Unless required by applicable law or agreed to in writing, software
1261 * distributed under the License is distributed on an "AS IS" BASIS,
1262 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1263 * See the License for the specific language governing permissions and
1264 * limitations under the License.
1265 */
1266/**
1267 * Sets a new callback that will get called when Installation ID changes.
1268 * Returns an unsubscribe function that will remove the callback when called.
1269 * @param installations - The `Installations` instance.
1270 * @param callback - The callback function that is invoked when FID changes.
1271 * @returns A function that can be called to unsubscribe.
1272 *
1273 * @public
1274 */
1275function onIdChange(installations, callback) {
1276 var appConfig = installations.appConfig;
1277 addCallback(appConfig, callback);
1278 return function () {
1279 removeCallback(appConfig, callback);
1280 };
1281}
1282
1283/**
1284 * @license
1285 * Copyright 2020 Google LLC
1286 *
1287 * Licensed under the Apache License, Version 2.0 (the "License");
1288 * you may not use this file except in compliance with the License.
1289 * You may obtain a copy of the License at
1290 *
1291 * http://www.apache.org/licenses/LICENSE-2.0
1292 *
1293 * Unless required by applicable law or agreed to in writing, software
1294 * distributed under the License is distributed on an "AS IS" BASIS,
1295 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1296 * See the License for the specific language governing permissions and
1297 * limitations under the License.
1298 */
1299/**
1300 * Returns an instance of {@link Installations} associated with the given
1301 * {@link @firebase/app#FirebaseApp} instance.
1302 * @param app - The {@link @firebase/app#FirebaseApp} instance.
1303 *
1304 * @public
1305 */
1306function getInstallations(app$1) {
1307 if (app$1 === void 0) { app$1 = app.getApp(); }
1308 var installationsImpl = app._getProvider(app$1, 'installations').getImmediate();
1309 return installationsImpl;
1310}
1311
1312/**
1313 * @license
1314 * Copyright 2019 Google LLC
1315 *
1316 * Licensed under the Apache License, Version 2.0 (the "License");
1317 * you may not use this file except in compliance with the License.
1318 * You may obtain a copy of the License at
1319 *
1320 * http://www.apache.org/licenses/LICENSE-2.0
1321 *
1322 * Unless required by applicable law or agreed to in writing, software
1323 * distributed under the License is distributed on an "AS IS" BASIS,
1324 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1325 * See the License for the specific language governing permissions and
1326 * limitations under the License.
1327 */
1328function extractAppConfig(app) {
1329 var e_1, _a;
1330 if (!app || !app.options) {
1331 throw getMissingValueError('App Configuration');
1332 }
1333 if (!app.name) {
1334 throw getMissingValueError('App Name');
1335 }
1336 // Required app config keys
1337 var configKeys = [
1338 'projectId',
1339 'apiKey',
1340 'appId'
1341 ];
1342 try {
1343 for (var configKeys_1 = tslib.__values(configKeys), configKeys_1_1 = configKeys_1.next(); !configKeys_1_1.done; configKeys_1_1 = configKeys_1.next()) {
1344 var keyName = configKeys_1_1.value;
1345 if (!app.options[keyName]) {
1346 throw getMissingValueError(keyName);
1347 }
1348 }
1349 }
1350 catch (e_1_1) { e_1 = { error: e_1_1 }; }
1351 finally {
1352 try {
1353 if (configKeys_1_1 && !configKeys_1_1.done && (_a = configKeys_1.return)) _a.call(configKeys_1);
1354 }
1355 finally { if (e_1) throw e_1.error; }
1356 }
1357 return {
1358 appName: app.name,
1359 projectId: app.options.projectId,
1360 apiKey: app.options.apiKey,
1361 appId: app.options.appId
1362 };
1363}
1364function getMissingValueError(valueName) {
1365 return ERROR_FACTORY.create("missing-app-config-values" /* MISSING_APP_CONFIG_VALUES */, {
1366 valueName: valueName
1367 });
1368}
1369
1370/**
1371 * @license
1372 * Copyright 2020 Google LLC
1373 *
1374 * Licensed under the Apache License, Version 2.0 (the "License");
1375 * you may not use this file except in compliance with the License.
1376 * You may obtain a copy of the License at
1377 *
1378 * http://www.apache.org/licenses/LICENSE-2.0
1379 *
1380 * Unless required by applicable law or agreed to in writing, software
1381 * distributed under the License is distributed on an "AS IS" BASIS,
1382 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1383 * See the License for the specific language governing permissions and
1384 * limitations under the License.
1385 */
1386var INSTALLATIONS_NAME = 'installations';
1387var INSTALLATIONS_NAME_INTERNAL = 'installations-internal';
1388var publicFactory = function (container) {
1389 var app$1 = container.getProvider('app').getImmediate();
1390 // Throws if app isn't configured properly.
1391 var appConfig = extractAppConfig(app$1);
1392 var heartbeatServiceProvider = app._getProvider(app$1, 'heartbeat');
1393 var installationsImpl = {
1394 app: app$1,
1395 appConfig: appConfig,
1396 heartbeatServiceProvider: heartbeatServiceProvider,
1397 _delete: function () { return Promise.resolve(); }
1398 };
1399 return installationsImpl;
1400};
1401var internalFactory = function (container) {
1402 var app$1 = container.getProvider('app').getImmediate();
1403 // Internal FIS instance relies on public FIS instance.
1404 var installations = app._getProvider(app$1, INSTALLATIONS_NAME).getImmediate();
1405 var installationsInternal = {
1406 getId: function () { return getId(installations); },
1407 getToken: function (forceRefresh) { return getToken(installations, forceRefresh); }
1408 };
1409 return installationsInternal;
1410};
1411function registerInstallations() {
1412 app._registerComponent(new component.Component(INSTALLATIONS_NAME, publicFactory, "PUBLIC" /* PUBLIC */));
1413 app._registerComponent(new component.Component(INSTALLATIONS_NAME_INTERNAL, internalFactory, "PRIVATE" /* PRIVATE */));
1414}
1415
1416/**
1417 * Firebase Installations
1418 *
1419 * @packageDocumentation
1420 */
1421registerInstallations();
1422app.registerVersion(name, version);
1423// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
1424app.registerVersion(name, version, 'cjs5');
1425
1426exports.deleteInstallations = deleteInstallations;
1427exports.getId = getId;
1428exports.getInstallations = getInstallations;
1429exports.getToken = getToken;
1430exports.onIdChange = onIdChange;
1431//# sourceMappingURL=index.cjs.js.map