@firebase/installations 0.6.9 → 0.6.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -4,12 +4,11 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var app = require('@firebase/app');
6
6
  var component = require('@firebase/component');
7
- var tslib = require('tslib');
8
7
  var util = require('@firebase/util');
9
8
  var idb = require('idb');
10
9
 
11
- var name = "@firebase/installations";
12
- var version = "0.6.9";
10
+ const name = "@firebase/installations";
11
+ const version = "0.6.10";
13
12
 
14
13
  /**
15
14
  * @license
@@ -27,13 +26,13 @@ var version = "0.6.9";
27
26
  * See the License for the specific language governing permissions and
28
27
  * limitations under the License.
29
28
  */
30
- var PENDING_TIMEOUT_MS = 10000;
31
- var PACKAGE_VERSION = "w:".concat(version);
32
- var INTERNAL_AUTH_VERSION = 'FIS_v2';
33
- var INSTALLATIONS_API_URL = 'https://firebaseinstallations.googleapis.com/v1';
34
- var TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour
35
- var SERVICE = 'installations';
36
- var SERVICE_NAME = 'Installations';
29
+ const PENDING_TIMEOUT_MS = 10000;
30
+ const PACKAGE_VERSION = `w:${version}`;
31
+ const INTERNAL_AUTH_VERSION = 'FIS_v2';
32
+ const INSTALLATIONS_API_URL = 'https://firebaseinstallations.googleapis.com/v1';
33
+ const TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour
34
+ const SERVICE = 'installations';
35
+ const SERVICE_NAME = 'Installations';
37
36
 
38
37
  /**
39
38
  * @license
@@ -51,16 +50,15 @@ var SERVICE_NAME = 'Installations';
51
50
  * See the License for the specific language governing permissions and
52
51
  * limitations under the License.
53
52
  */
54
- var _a;
55
- var ERROR_DESCRIPTION_MAP = (_a = {},
56
- _a["missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */] = 'Missing App configuration value: "{$valueName}"',
57
- _a["not-registered" /* ErrorCode.NOT_REGISTERED */] = 'Firebase Installation is not registered.',
58
- _a["installation-not-found" /* ErrorCode.INSTALLATION_NOT_FOUND */] = 'Firebase Installation not found.',
59
- _a["request-failed" /* ErrorCode.REQUEST_FAILED */] = '{$requestName} request failed with error "{$serverCode} {$serverStatus}: {$serverMessage}"',
60
- _a["app-offline" /* ErrorCode.APP_OFFLINE */] = 'Could not process request. Application offline.',
61
- _a["delete-pending-registration" /* ErrorCode.DELETE_PENDING_REGISTRATION */] = "Can't delete installation while there is a pending registration request.",
62
- _a);
63
- var ERROR_FACTORY = new util.ErrorFactory(SERVICE, SERVICE_NAME, ERROR_DESCRIPTION_MAP);
53
+ const ERROR_DESCRIPTION_MAP = {
54
+ ["missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */]: 'Missing App configuration value: "{$valueName}"',
55
+ ["not-registered" /* ErrorCode.NOT_REGISTERED */]: 'Firebase Installation is not registered.',
56
+ ["installation-not-found" /* ErrorCode.INSTALLATION_NOT_FOUND */]: 'Firebase Installation not found.',
57
+ ["request-failed" /* ErrorCode.REQUEST_FAILED */]: '{$requestName} request failed with error "{$serverCode} {$serverStatus}: {$serverMessage}"',
58
+ ["app-offline" /* ErrorCode.APP_OFFLINE */]: 'Could not process request. Application offline.',
59
+ ["delete-pending-registration" /* ErrorCode.DELETE_PENDING_REGISTRATION */]: "Can't delete installation while there is a pending registration request."
60
+ };
61
+ const ERROR_FACTORY = new util.ErrorFactory(SERVICE, SERVICE_NAME, ERROR_DESCRIPTION_MAP);
64
62
  /** Returns true if error is a FirebaseError that is based on an error from the server. */
65
63
  function isServerError(error) {
66
64
  return (error instanceof util.FirebaseError &&
@@ -83,9 +81,8 @@ function isServerError(error) {
83
81
  * See the License for the specific language governing permissions and
84
82
  * limitations under the License.
85
83
  */
86
- function getInstallationsEndpoint(_a) {
87
- var projectId = _a.projectId;
88
- return "".concat(INSTALLATIONS_API_URL, "/projects/").concat(projectId, "/installations");
84
+ function getInstallationsEndpoint({ projectId }) {
85
+ return `${INSTALLATIONS_API_URL}/projects/${projectId}/installations`;
89
86
  }
90
87
  function extractAuthTokenInfoFromResponse(response) {
91
88
  return {
@@ -95,36 +92,25 @@ function extractAuthTokenInfoFromResponse(response) {
95
92
  creationTime: Date.now()
96
93
  };
97
94
  }
98
- function 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" /* ErrorCode.REQUEST_FAILED */, {
108
- requestName: requestName,
109
- serverCode: errorData.code,
110
- serverMessage: errorData.message,
111
- serverStatus: errorData.status
112
- })];
113
- }
114
- });
95
+ async function getErrorFromResponse(requestName, response) {
96
+ const responseJson = await response.json();
97
+ const errorData = responseJson.error;
98
+ return ERROR_FACTORY.create("request-failed" /* ErrorCode.REQUEST_FAILED */, {
99
+ requestName,
100
+ serverCode: errorData.code,
101
+ serverMessage: errorData.message,
102
+ serverStatus: errorData.status
115
103
  });
116
104
  }
117
- function getHeaders(_a) {
118
- var apiKey = _a.apiKey;
105
+ function getHeaders({ apiKey }) {
119
106
  return new Headers({
120
107
  'Content-Type': 'application/json',
121
108
  Accept: 'application/json',
122
109
  'x-goog-api-key': apiKey
123
110
  });
124
111
  }
125
- function getHeadersWithAuth(appConfig, _a) {
126
- var refreshToken = _a.refreshToken;
127
- var headers = getHeaders(appConfig);
112
+ function getHeadersWithAuth(appConfig, { refreshToken }) {
113
+ const headers = getHeaders(appConfig);
128
114
  headers.append('Authorization', getAuthorizationHeader(refreshToken));
129
115
  return headers;
130
116
  }
@@ -133,29 +119,20 @@ function getHeadersWithAuth(appConfig, _a) {
133
119
  * If the returned response has a status of 5xx, re-runs the function once and
134
120
  * returns the response.
135
121
  */
136
- function 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
- });
122
+ async function retryIfServerError(fn) {
123
+ const result = await fn();
124
+ if (result.status >= 500 && result.status < 600) {
125
+ // Internal Server Error. Retry request.
126
+ return fn();
127
+ }
128
+ return result;
152
129
  }
153
130
  function getExpiresInFromResponseExpiresIn(responseExpiresIn) {
154
131
  // This works because the server will never respond with fractions of a second.
155
132
  return Number(responseExpiresIn.replace('s', '000'));
156
133
  }
157
134
  function getAuthorizationHeader(refreshToken) {
158
- return "".concat(INTERNAL_AUTH_VERSION, " ").concat(refreshToken);
135
+ return `${INTERNAL_AUTH_VERSION} ${refreshToken}`;
159
136
  }
160
137
 
161
138
  /**
@@ -174,58 +151,44 @@ function getAuthorizationHeader(refreshToken) {
174
151
  * See the License for the specific language governing permissions and
175
152
  * limitations under the License.
176
153
  */
177
- function 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 /* RequestStatus.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
- });
154
+ async function createInstallationRequest({ appConfig, heartbeatServiceProvider }, { fid }) {
155
+ const endpoint = getInstallationsEndpoint(appConfig);
156
+ const headers = getHeaders(appConfig);
157
+ // If heartbeat service exists, add the heartbeat string to the header.
158
+ const heartbeatService = heartbeatServiceProvider.getImmediate({
159
+ optional: true
228
160
  });
161
+ if (heartbeatService) {
162
+ const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();
163
+ if (heartbeatsHeader) {
164
+ headers.append('x-firebase-client', heartbeatsHeader);
165
+ }
166
+ }
167
+ const body = {
168
+ fid,
169
+ authVersion: INTERNAL_AUTH_VERSION,
170
+ appId: appConfig.appId,
171
+ sdkVersion: PACKAGE_VERSION
172
+ };
173
+ const request = {
174
+ method: 'POST',
175
+ headers,
176
+ body: JSON.stringify(body)
177
+ };
178
+ const response = await retryIfServerError(() => fetch(endpoint, request));
179
+ if (response.ok) {
180
+ const responseValue = await response.json();
181
+ const registeredInstallationEntry = {
182
+ fid: responseValue.fid || fid,
183
+ registrationStatus: 2 /* RequestStatus.COMPLETED */,
184
+ refreshToken: responseValue.refreshToken,
185
+ authToken: extractAuthTokenInfoFromResponse(responseValue.authToken)
186
+ };
187
+ return registeredInstallationEntry;
188
+ }
189
+ else {
190
+ throw await getErrorFromResponse('Create Installation', response);
191
+ }
229
192
  }
230
193
 
231
194
  /**
@@ -246,7 +209,7 @@ function createInstallationRequest(_a, _b) {
246
209
  */
247
210
  /** Returns a promise that resolves after given time passes. */
248
211
  function sleep(ms) {
249
- return new Promise(function (resolve) {
212
+ return new Promise(resolve => {
250
213
  setTimeout(resolve, ms);
251
214
  });
252
215
  }
@@ -268,7 +231,7 @@ function sleep(ms) {
268
231
  * limitations under the License.
269
232
  */
270
233
  function bufferToBase64UrlSafe(array) {
271
- var b64 = btoa(String.fromCharCode.apply(String, tslib.__spreadArray([], tslib.__read(array), false)));
234
+ const b64 = btoa(String.fromCharCode(...array));
272
235
  return b64.replace(/\+/g, '-').replace(/\//g, '_');
273
236
  }
274
237
 
@@ -288,8 +251,8 @@ function bufferToBase64UrlSafe(array) {
288
251
  * See the License for the specific language governing permissions and
289
252
  * limitations under the License.
290
253
  */
291
- var VALID_FID_PATTERN = /^[cdef][\w-]{21}$/;
292
- var INVALID_FID = '';
254
+ const VALID_FID_PATTERN = /^[cdef][\w-]{21}$/;
255
+ const INVALID_FID = '';
293
256
  /**
294
257
  * Generates a new FID using random values from Web Crypto API.
295
258
  * Returns an empty string if FID generation fails for any reason.
@@ -298,12 +261,12 @@ function generateFid() {
298
261
  try {
299
262
  // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5
300
263
  // 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);
264
+ const fidByteArray = new Uint8Array(17);
265
+ const crypto = self.crypto || self.msCrypto;
266
+ crypto.getRandomValues(fidByteArray);
304
267
  // 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);
268
+ fidByteArray[0] = 0b01110000 + (fidByteArray[0] % 0b00010000);
269
+ const fid = encode(fidByteArray);
307
270
  return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID;
308
271
  }
309
272
  catch (_a) {
@@ -313,7 +276,7 @@ function generateFid() {
313
276
  }
314
277
  /** Converts a FID Uint8Array to a base64 string representation. */
315
278
  function encode(fidByteArray) {
316
- var b64String = bufferToBase64UrlSafe(fidByteArray);
279
+ const b64String = bufferToBase64UrlSafe(fidByteArray);
317
280
  // Remove the 23rd character that was added because of the extra 4 bits at the
318
281
  // end of our 17 byte array, and the '=' padding.
319
282
  return b64String.substr(0, 22);
@@ -337,7 +300,7 @@ function encode(fidByteArray) {
337
300
  */
338
301
  /** Returns a string key that can be used to identify the app. */
339
302
  function getKey(appConfig) {
340
- return "".concat(appConfig.appName, "!").concat(appConfig.appId);
303
+ return `${appConfig.appName}!${appConfig.appId}`;
341
304
  }
342
305
 
343
306
  /**
@@ -356,13 +319,13 @@ function getKey(appConfig) {
356
319
  * See the License for the specific language governing permissions and
357
320
  * limitations under the License.
358
321
  */
359
- var fidChangeCallbacks = new Map();
322
+ const fidChangeCallbacks = new Map();
360
323
  /**
361
324
  * Calls the onIdChange callbacks with the new FID value, and broadcasts the
362
325
  * change to other tabs.
363
326
  */
364
327
  function fidChanged(appConfig, fid) {
365
- var key = getKey(appConfig);
328
+ const key = getKey(appConfig);
366
329
  callFidChangeCallbacks(key, fid);
367
330
  broadcastFidChange(key, fid);
368
331
  }
@@ -370,8 +333,8 @@ function addCallback(appConfig, callback) {
370
333
  // Open the broadcast channel if it's not already open,
371
334
  // to be able to listen to change events from other tabs.
372
335
  getBroadcastChannel();
373
- var key = getKey(appConfig);
374
- var callbackSet = fidChangeCallbacks.get(key);
336
+ const key = getKey(appConfig);
337
+ let callbackSet = fidChangeCallbacks.get(key);
375
338
  if (!callbackSet) {
376
339
  callbackSet = new Set();
377
340
  fidChangeCallbacks.set(key, callbackSet);
@@ -379,8 +342,8 @@ function addCallback(appConfig, callback) {
379
342
  callbackSet.add(callback);
380
343
  }
381
344
  function removeCallback(appConfig, callback) {
382
- var key = getKey(appConfig);
383
- var callbackSet = fidChangeCallbacks.get(key);
345
+ const key = getKey(appConfig);
346
+ const callbackSet = fidChangeCallbacks.get(key);
384
347
  if (!callbackSet) {
385
348
  return;
386
349
  }
@@ -392,38 +355,27 @@ function removeCallback(appConfig, callback) {
392
355
  closeBroadcastChannel();
393
356
  }
394
357
  function callFidChangeCallbacks(key, fid) {
395
- var e_1, _a;
396
- var callbacks = fidChangeCallbacks.get(key);
358
+ const callbacks = fidChangeCallbacks.get(key);
397
359
  if (!callbacks) {
398
360
  return;
399
361
  }
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; }
362
+ for (const callback of callbacks) {
363
+ callback(fid);
412
364
  }
413
365
  }
414
366
  function broadcastFidChange(key, fid) {
415
- var channel = getBroadcastChannel();
367
+ const channel = getBroadcastChannel();
416
368
  if (channel) {
417
- channel.postMessage({ key: key, fid: fid });
369
+ channel.postMessage({ key, fid });
418
370
  }
419
371
  closeBroadcastChannel();
420
372
  }
421
- var broadcastChannel = null;
373
+ let broadcastChannel = null;
422
374
  /** Opens and returns a BroadcastChannel if it is supported by the browser. */
423
375
  function getBroadcastChannel() {
424
376
  if (!broadcastChannel && 'BroadcastChannel' in self) {
425
377
  broadcastChannel = new BroadcastChannel('[Firebase] FID Change');
426
- broadcastChannel.onmessage = function (e) {
378
+ broadcastChannel.onmessage = e => {
427
379
  callFidChangeCallbacks(e.data.key, e.data.fid);
428
380
  };
429
381
  }
@@ -452,14 +404,14 @@ function closeBroadcastChannel() {
452
404
  * See the License for the specific language governing permissions and
453
405
  * limitations under the License.
454
406
  */
455
- var DATABASE_NAME = 'firebase-installations-database';
456
- var DATABASE_VERSION = 1;
457
- var OBJECT_STORE_NAME = 'firebase-installations-store';
458
- var dbPromise = null;
407
+ const DATABASE_NAME = 'firebase-installations-database';
408
+ const DATABASE_VERSION = 1;
409
+ const OBJECT_STORE_NAME = 'firebase-installations-store';
410
+ let dbPromise = null;
459
411
  function getDbPromise() {
460
412
  if (!dbPromise) {
461
413
  dbPromise = idb.openDB(DATABASE_NAME, DATABASE_VERSION, {
462
- upgrade: function (db, oldVersion) {
414
+ upgrade: (db, oldVersion) => {
463
415
  // We don't use 'break' in this switch statement, the fall-through
464
416
  // behavior is what we want, because if there are multiple versions between
465
417
  // the old version and the current version, we want ALL the migrations
@@ -475,57 +427,26 @@ function getDbPromise() {
475
427
  return dbPromise;
476
428
  }
477
429
  /** Assigns or overwrites the record for the given key with the given value. */
478
- function 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
- });
430
+ async function set(appConfig, value) {
431
+ const key = getKey(appConfig);
432
+ const db = await getDbPromise();
433
+ const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
434
+ const objectStore = tx.objectStore(OBJECT_STORE_NAME);
435
+ const oldValue = (await objectStore.get(key));
436
+ await objectStore.put(value, key);
437
+ await tx.done;
438
+ if (!oldValue || oldValue.fid !== value.fid) {
439
+ fidChanged(appConfig, value.fid);
440
+ }
441
+ return value;
506
442
  }
507
443
  /** Removes record(s) from the objectStore that match the given key. */
508
- function 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
- });
444
+ async function remove(appConfig) {
445
+ const key = getKey(appConfig);
446
+ const db = await getDbPromise();
447
+ const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
448
+ await tx.objectStore(OBJECT_STORE_NAME).delete(key);
449
+ await tx.done;
529
450
  }
530
451
  /**
531
452
  * Atomically updates a record with the result of updateFn, which gets
@@ -533,41 +454,24 @@ function remove(appConfig) {
533
454
  * deleted instead.
534
455
  * @return Updated value
535
456
  */
536
- function 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
- });
457
+ async function update(appConfig, updateFn) {
458
+ const key = getKey(appConfig);
459
+ const db = await getDbPromise();
460
+ const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
461
+ const store = tx.objectStore(OBJECT_STORE_NAME);
462
+ const oldValue = (await store.get(key));
463
+ const newValue = updateFn(oldValue);
464
+ if (newValue === undefined) {
465
+ await store.delete(key);
466
+ }
467
+ else {
468
+ await store.put(newValue, key);
469
+ }
470
+ await tx.done;
471
+ if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) {
472
+ fidChanged(appConfig, newValue.fid);
473
+ }
474
+ return newValue;
571
475
  }
572
476
 
573
477
  /**
@@ -590,40 +494,29 @@ function update(appConfig, updateFn) {
590
494
  * Updates and returns the InstallationEntry from the database.
591
495
  * Also triggers a registration request if it is necessary and possible.
592
496
  */
593
- function 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
- });
497
+ async function getInstallationEntry(installations) {
498
+ let registrationPromise;
499
+ const installationEntry = await update(installations.appConfig, oldEntry => {
500
+ const installationEntry = updateOrCreateInstallationEntry(oldEntry);
501
+ const entryWithPromise = triggerRegistrationIfNecessary(installations, installationEntry);
502
+ registrationPromise = entryWithPromise.registrationPromise;
503
+ return entryWithPromise.installationEntry;
619
504
  });
505
+ if (installationEntry.fid === INVALID_FID) {
506
+ // FID generation failed. Waiting for the FID from the server.
507
+ return { installationEntry: await registrationPromise };
508
+ }
509
+ return {
510
+ installationEntry,
511
+ registrationPromise
512
+ };
620
513
  }
621
514
  /**
622
515
  * Creates a new Installation Entry if one does not exist.
623
516
  * Also clears timed out pending requests.
624
517
  */
625
518
  function updateOrCreateInstallationEntry(oldEntry) {
626
- var entry = oldEntry || {
519
+ const entry = oldEntry || {
627
520
  fid: generateFid(),
628
521
  registrationStatus: 0 /* RequestStatus.NOT_STARTED */
629
522
  };
@@ -640,107 +533,76 @@ function triggerRegistrationIfNecessary(installations, installationEntry) {
640
533
  if (installationEntry.registrationStatus === 0 /* RequestStatus.NOT_STARTED */) {
641
534
  if (!navigator.onLine) {
642
535
  // Registration required but app is offline.
643
- var registrationPromiseWithError = Promise.reject(ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */));
536
+ const registrationPromiseWithError = Promise.reject(ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */));
644
537
  return {
645
- installationEntry: installationEntry,
538
+ installationEntry,
646
539
  registrationPromise: registrationPromiseWithError
647
540
  };
648
541
  }
649
542
  // Try registering. Change status to IN_PROGRESS.
650
- var inProgressEntry = {
543
+ const inProgressEntry = {
651
544
  fid: installationEntry.fid,
652
545
  registrationStatus: 1 /* RequestStatus.IN_PROGRESS */,
653
546
  registrationTime: Date.now()
654
547
  };
655
- var registrationPromise = registerInstallation(installations, inProgressEntry);
656
- return { installationEntry: inProgressEntry, registrationPromise: registrationPromise };
548
+ const registrationPromise = registerInstallation(installations, inProgressEntry);
549
+ return { installationEntry: inProgressEntry, registrationPromise };
657
550
  }
658
551
  else if (installationEntry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */) {
659
552
  return {
660
- installationEntry: installationEntry,
553
+ installationEntry,
661
554
  registrationPromise: waitUntilFidRegistration(installations)
662
555
  };
663
556
  }
664
557
  else {
665
- return { installationEntry: installationEntry };
558
+ return { installationEntry };
666
559
  }
667
560
  }
668
561
  /** This will be executed only once for each new Firebase Installation. */
669
- function 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 cannot 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 cannot 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 /* RequestStatus.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
- });
562
+ async function registerInstallation(installations, installationEntry) {
563
+ try {
564
+ const registeredInstallationEntry = await createInstallationRequest(installations, installationEntry);
565
+ return set(installations.appConfig, registeredInstallationEntry);
566
+ }
567
+ catch (e) {
568
+ if (isServerError(e) && e.customData.serverCode === 409) {
569
+ // Server returned a "FID cannot be used" error.
570
+ // Generate a new ID next time.
571
+ await remove(installations.appConfig);
572
+ }
573
+ else {
574
+ // Registration failed. Set FID as not registered.
575
+ await set(installations.appConfig, {
576
+ fid: installationEntry.fid,
577
+ registrationStatus: 0 /* RequestStatus.NOT_STARTED */
578
+ });
579
+ }
580
+ throw e;
581
+ }
706
582
  }
707
583
  /** Call if FID registration is pending in another request. */
708
- function 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 /* RequestStatus.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 /* RequestStatus.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
- });
584
+ async function waitUntilFidRegistration(installations) {
585
+ // Unfortunately, there is no way of reliably observing when a value in
586
+ // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),
587
+ // so we need to poll.
588
+ let entry = await updateInstallationRequest(installations.appConfig);
589
+ while (entry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */) {
590
+ // createInstallation request still in progress.
591
+ await sleep(100);
592
+ entry = await updateInstallationRequest(installations.appConfig);
593
+ }
594
+ if (entry.registrationStatus === 0 /* RequestStatus.NOT_STARTED */) {
595
+ // The request timed out or failed in a different call. Try again.
596
+ const { installationEntry, registrationPromise } = await getInstallationEntry(installations);
597
+ if (registrationPromise) {
598
+ return registrationPromise;
599
+ }
600
+ else {
601
+ // if there is no registrationPromise, entry is registered.
602
+ return installationEntry;
603
+ }
604
+ }
605
+ return entry;
744
606
  }
745
607
  /**
746
608
  * Called only if there is a CreateInstallation request in progress.
@@ -751,7 +613,7 @@ function waitUntilFidRegistration(installations) {
751
613
  * Returns the updated InstallationEntry.
752
614
  */
753
615
  function updateInstallationRequest(appConfig) {
754
- return update(appConfig, function (oldEntry) {
616
+ return update(appConfig, oldEntry => {
755
617
  if (!oldEntry) {
756
618
  throw ERROR_FACTORY.create("installation-not-found" /* ErrorCode.INSTALLATION_NOT_FOUND */);
757
619
  }
@@ -788,56 +650,42 @@ function hasInstallationRequestTimedOut(installationEntry) {
788
650
  * See the License for the specific language governing permissions and
789
651
  * limitations under the License.
790
652
  */
791
- function 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
- });
653
+ async function generateAuthTokenRequest({ appConfig, heartbeatServiceProvider }, installationEntry) {
654
+ const endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);
655
+ const headers = getHeadersWithAuth(appConfig, installationEntry);
656
+ // If heartbeat service exists, add the heartbeat string to the header.
657
+ const heartbeatService = heartbeatServiceProvider.getImmediate({
658
+ optional: true
836
659
  });
660
+ if (heartbeatService) {
661
+ const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();
662
+ if (heartbeatsHeader) {
663
+ headers.append('x-firebase-client', heartbeatsHeader);
664
+ }
665
+ }
666
+ const body = {
667
+ installation: {
668
+ sdkVersion: PACKAGE_VERSION,
669
+ appId: appConfig.appId
670
+ }
671
+ };
672
+ const request = {
673
+ method: 'POST',
674
+ headers,
675
+ body: JSON.stringify(body)
676
+ };
677
+ const response = await retryIfServerError(() => fetch(endpoint, request));
678
+ if (response.ok) {
679
+ const responseValue = await response.json();
680
+ const completedAuthToken = extractAuthTokenInfoFromResponse(responseValue);
681
+ return completedAuthToken;
682
+ }
683
+ else {
684
+ throw await getErrorFromResponse('Generate Auth Token', response);
685
+ }
837
686
  }
838
- function getGenerateAuthTokenEndpoint(appConfig, _a) {
839
- var fid = _a.fid;
840
- return "".concat(getInstallationsEndpoint(appConfig), "/").concat(fid, "/authTokens:generate");
687
+ function getGenerateAuthTokenEndpoint(appConfig, { fid }) {
688
+ return `${getInstallationsEndpoint(appConfig)}/${fid}/authTokens:generate`;
841
689
  }
842
690
 
843
691
  /**
@@ -862,52 +710,36 @@ function getGenerateAuthTokenEndpoint(appConfig, _a) {
862
710
  *
863
711
  * Should only be called if the Firebase Installation is registered.
864
712
  */
865
- function 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" /* ErrorCode.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 /* RequestStatus.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" /* ErrorCode.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];
713
+ async function refreshAuthToken(installations, forceRefresh = false) {
714
+ let tokenPromise;
715
+ const entry = await update(installations.appConfig, oldEntry => {
716
+ if (!isEntryRegistered(oldEntry)) {
717
+ throw ERROR_FACTORY.create("not-registered" /* ErrorCode.NOT_REGISTERED */);
718
+ }
719
+ const oldAuthToken = oldEntry.authToken;
720
+ if (!forceRefresh && isAuthTokenValid(oldAuthToken)) {
721
+ // There is a valid token in the DB.
722
+ return oldEntry;
723
+ }
724
+ else if (oldAuthToken.requestStatus === 1 /* RequestStatus.IN_PROGRESS */) {
725
+ // There already is a token request in progress.
726
+ tokenPromise = waitUntilAuthTokenRequest(installations, forceRefresh);
727
+ return oldEntry;
728
+ }
729
+ else {
730
+ // No token or token expired.
731
+ if (!navigator.onLine) {
732
+ throw ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */);
908
733
  }
909
- });
734
+ const inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry);
735
+ tokenPromise = fetchAuthTokenFromServer(installations, inProgressEntry);
736
+ return inProgressEntry;
737
+ }
910
738
  });
739
+ const authToken = tokenPromise
740
+ ? await tokenPromise
741
+ : entry.authToken;
742
+ return authToken;
911
743
  }
912
744
  /**
913
745
  * Call only if FID is registered and Auth Token request is in progress.
@@ -915,38 +747,24 @@ function refreshAuthToken(installations, forceRefresh) {
915
747
  * Waits until the current pending request finishes. If the request times out,
916
748
  * tries once in this thread as well.
917
749
  */
918
- function 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 /* RequestStatus.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 /* RequestStatus.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
- });
750
+ async function waitUntilAuthTokenRequest(installations, forceRefresh) {
751
+ // Unfortunately, there is no way of reliably observing when a value in
752
+ // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),
753
+ // so we need to poll.
754
+ let entry = await updateAuthTokenRequest(installations.appConfig);
755
+ while (entry.authToken.requestStatus === 1 /* RequestStatus.IN_PROGRESS */) {
756
+ // generateAuthToken still in progress.
757
+ await sleep(100);
758
+ entry = await updateAuthTokenRequest(installations.appConfig);
759
+ }
760
+ const authToken = entry.authToken;
761
+ if (authToken.requestStatus === 0 /* RequestStatus.NOT_STARTED */) {
762
+ // The request timed out or failed in a different call. Try again.
763
+ return refreshAuthToken(installations, forceRefresh);
764
+ }
765
+ else {
766
+ return authToken;
767
+ }
950
768
  }
951
769
  /**
952
770
  * Called only if there is a GenerateAuthToken request in progress.
@@ -957,55 +775,37 @@ function waitUntilAuthTokenRequest(installations, forceRefresh) {
957
775
  * Returns the updated InstallationEntry.
958
776
  */
959
777
  function updateAuthTokenRequest(appConfig) {
960
- return update(appConfig, function (oldEntry) {
778
+ return update(appConfig, oldEntry => {
961
779
  if (!isEntryRegistered(oldEntry)) {
962
780
  throw ERROR_FACTORY.create("not-registered" /* ErrorCode.NOT_REGISTERED */);
963
781
  }
964
- var oldAuthToken = oldEntry.authToken;
782
+ const oldAuthToken = oldEntry.authToken;
965
783
  if (hasAuthTokenRequestTimedOut(oldAuthToken)) {
966
- return tslib.__assign(tslib.__assign({}, oldEntry), { authToken: { requestStatus: 0 /* RequestStatus.NOT_STARTED */ } });
784
+ return Object.assign(Object.assign({}, oldEntry), { authToken: { requestStatus: 0 /* RequestStatus.NOT_STARTED */ } });
967
785
  }
968
786
  return oldEntry;
969
787
  });
970
788
  }
971
- function 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 /* RequestStatus.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
- });
789
+ async function fetchAuthTokenFromServer(installations, installationEntry) {
790
+ try {
791
+ const authToken = await generateAuthTokenRequest(installations, installationEntry);
792
+ const updatedInstallationEntry = Object.assign(Object.assign({}, installationEntry), { authToken });
793
+ await set(installations.appConfig, updatedInstallationEntry);
794
+ return authToken;
795
+ }
796
+ catch (e) {
797
+ if (isServerError(e) &&
798
+ (e.customData.serverCode === 401 || e.customData.serverCode === 404)) {
799
+ // Server returned a "FID not found" or a "Invalid authentication" error.
800
+ // Generate a new ID next time.
801
+ await remove(installations.appConfig);
802
+ }
803
+ else {
804
+ const updatedInstallationEntry = Object.assign(Object.assign({}, installationEntry), { authToken: { requestStatus: 0 /* RequestStatus.NOT_STARTED */ } });
805
+ await set(installations.appConfig, updatedInstallationEntry);
806
+ }
807
+ throw e;
808
+ }
1009
809
  }
1010
810
  function isEntryRegistered(installationEntry) {
1011
811
  return (installationEntry !== undefined &&
@@ -1016,17 +816,17 @@ function isAuthTokenValid(authToken) {
1016
816
  !isAuthTokenExpired(authToken));
1017
817
  }
1018
818
  function isAuthTokenExpired(authToken) {
1019
- var now = Date.now();
819
+ const now = Date.now();
1020
820
  return (now < authToken.creationTime ||
1021
821
  authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER);
1022
822
  }
1023
823
  /** Returns an updated InstallationEntry with an InProgressAuthToken. */
1024
824
  function makeAuthTokenRequestInProgressEntry(oldEntry) {
1025
- var inProgressAuthToken = {
825
+ const inProgressAuthToken = {
1026
826
  requestStatus: 1 /* RequestStatus.IN_PROGRESS */,
1027
827
  requestTime: Date.now()
1028
828
  };
1029
- return tslib.__assign(tslib.__assign({}, oldEntry), { authToken: inProgressAuthToken });
829
+ return Object.assign(Object.assign({}, oldEntry), { authToken: inProgressAuthToken });
1030
830
  }
1031
831
  function hasAuthTokenRequestTimedOut(authToken) {
1032
832
  return (authToken.requestStatus === 1 /* RequestStatus.IN_PROGRESS */ &&
@@ -1056,28 +856,18 @@ function hasAuthTokenRequestTimedOut(authToken) {
1056
856
  *
1057
857
  * @public
1058
858
  */
1059
- function 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
- });
859
+ async function getId(installations) {
860
+ const installationsImpl = installations;
861
+ const { installationEntry, registrationPromise } = await getInstallationEntry(installationsImpl);
862
+ if (registrationPromise) {
863
+ registrationPromise.catch(console.error);
864
+ }
865
+ else {
866
+ // If the installation is already registered, update the authentication
867
+ // token if needed.
868
+ refreshAuthToken(installationsImpl).catch(console.error);
869
+ }
870
+ return installationEntry.fid;
1081
871
  }
1082
872
 
1083
873
  /**
@@ -1104,44 +894,20 @@ function getId(installations) {
1104
894
  *
1105
895
  * @public
1106
896
  */
1107
- function 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
- });
897
+ async function getToken(installations, forceRefresh = false) {
898
+ const installationsImpl = installations;
899
+ await completeInstallationRegistration(installationsImpl);
900
+ // At this point we either have a Registered Installation in the DB, or we've
901
+ // already thrown an error.
902
+ const authToken = await refreshAuthToken(installationsImpl, forceRefresh);
903
+ return authToken.token;
1125
904
  }
1126
- function 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
- });
905
+ async function completeInstallationRegistration(installations) {
906
+ const { registrationPromise } = await getInstallationEntry(installations);
907
+ if (registrationPromise) {
908
+ // A createInstallation request is in progress. Wait until it finishes.
909
+ await registrationPromise;
910
+ }
1145
911
  }
1146
912
 
1147
913
  /**
@@ -1160,32 +926,20 @@ function completeInstallationRegistration(installations) {
1160
926
  * See the License for the specific language governing permissions and
1161
927
  * limitations under the License.
1162
928
  */
1163
- function 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
- });
929
+ async function deleteInstallationRequest(appConfig, installationEntry) {
930
+ const endpoint = getDeleteEndpoint(appConfig, installationEntry);
931
+ const headers = getHeadersWithAuth(appConfig, installationEntry);
932
+ const request = {
933
+ method: 'DELETE',
934
+ headers
935
+ };
936
+ const response = await retryIfServerError(() => fetch(endpoint, request));
937
+ if (!response.ok) {
938
+ throw await getErrorFromResponse('Delete Installation', response);
939
+ }
1185
940
  }
1186
- function getDeleteEndpoint(appConfig, _a) {
1187
- var fid = _a.fid;
1188
- return "".concat(getInstallationsEndpoint(appConfig), "/").concat(fid);
941
+ function getDeleteEndpoint(appConfig, { fid }) {
942
+ return `${getInstallationsEndpoint(appConfig)}/${fid}`;
1189
943
  }
1190
944
 
1191
945
  /**
@@ -1210,41 +964,30 @@ function getDeleteEndpoint(appConfig, _a) {
1210
964
  *
1211
965
  * @public
1212
966
  */
1213
- function 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 /* RequestStatus.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 /* RequestStatus.IN_PROGRESS */)) return [3 /*break*/, 2];
1231
- // Can't delete while trying to register.
1232
- throw ERROR_FACTORY.create("delete-pending-registration" /* ErrorCode.DELETE_PENDING_REGISTRATION */);
1233
- case 2:
1234
- if (!(entry.registrationStatus === 2 /* RequestStatus.COMPLETED */)) return [3 /*break*/, 6];
1235
- if (!!navigator.onLine) return [3 /*break*/, 3];
1236
- throw ERROR_FACTORY.create("app-offline" /* ErrorCode.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
- });
967
+ async function deleteInstallations(installations) {
968
+ const { appConfig } = installations;
969
+ const entry = await update(appConfig, oldEntry => {
970
+ if (oldEntry && oldEntry.registrationStatus === 0 /* RequestStatus.NOT_STARTED */) {
971
+ // Delete the unregistered entry without sending a deleteInstallation request.
972
+ return undefined;
973
+ }
974
+ return oldEntry;
1247
975
  });
976
+ if (entry) {
977
+ if (entry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */) {
978
+ // Can't delete while trying to register.
979
+ throw ERROR_FACTORY.create("delete-pending-registration" /* ErrorCode.DELETE_PENDING_REGISTRATION */);
980
+ }
981
+ else if (entry.registrationStatus === 2 /* RequestStatus.COMPLETED */) {
982
+ if (!navigator.onLine) {
983
+ throw ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */);
984
+ }
985
+ else {
986
+ await deleteInstallationRequest(appConfig, entry);
987
+ await remove(appConfig);
988
+ }
989
+ }
990
+ }
1248
991
  }
1249
992
 
1250
993
  /**
@@ -1273,9 +1016,9 @@ function deleteInstallations(installations) {
1273
1016
  * @public
1274
1017
  */
1275
1018
  function onIdChange(installations, callback) {
1276
- var appConfig = installations.appConfig;
1019
+ const { appConfig } = installations;
1277
1020
  addCallback(appConfig, callback);
1278
- return function () {
1021
+ return () => {
1279
1022
  removeCallback(appConfig, callback);
1280
1023
  };
1281
1024
  }
@@ -1303,9 +1046,8 @@ function onIdChange(installations, callback) {
1303
1046
  *
1304
1047
  * @public
1305
1048
  */
1306
- function getInstallations(app$1) {
1307
- if (app$1 === void 0) { app$1 = app.getApp(); }
1308
- var installationsImpl = app._getProvider(app$1, 'installations').getImmediate();
1049
+ function getInstallations(app$1 = app.getApp()) {
1050
+ const installationsImpl = app._getProvider(app$1, 'installations').getImmediate();
1309
1051
  return installationsImpl;
1310
1052
  }
1311
1053
 
@@ -1326,7 +1068,6 @@ function getInstallations(app$1) {
1326
1068
  * limitations under the License.
1327
1069
  */
1328
1070
  function extractAppConfig(app) {
1329
- var e_1, _a;
1330
1071
  if (!app || !app.options) {
1331
1072
  throw getMissingValueError('App Configuration');
1332
1073
  }
@@ -1334,25 +1075,15 @@ function extractAppConfig(app) {
1334
1075
  throw getMissingValueError('App Name');
1335
1076
  }
1336
1077
  // Required app config keys
1337
- var configKeys = [
1078
+ const configKeys = [
1338
1079
  'projectId',
1339
1080
  'apiKey',
1340
1081
  'appId'
1341
1082
  ];
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);
1083
+ for (const keyName of configKeys) {
1084
+ if (!app.options[keyName]) {
1085
+ throw getMissingValueError(keyName);
1354
1086
  }
1355
- finally { if (e_1) throw e_1.error; }
1356
1087
  }
1357
1088
  return {
1358
1089
  appName: app.name,
@@ -1363,7 +1094,7 @@ function extractAppConfig(app) {
1363
1094
  }
1364
1095
  function getMissingValueError(valueName) {
1365
1096
  return ERROR_FACTORY.create("missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */, {
1366
- valueName: valueName
1097
+ valueName
1367
1098
  });
1368
1099
  }
1369
1100
 
@@ -1383,28 +1114,28 @@ function getMissingValueError(valueName) {
1383
1114
  * See the License for the specific language governing permissions and
1384
1115
  * limitations under the License.
1385
1116
  */
1386
- var INSTALLATIONS_NAME = 'installations';
1387
- var INSTALLATIONS_NAME_INTERNAL = 'installations-internal';
1388
- var publicFactory = function (container) {
1389
- var app$1 = container.getProvider('app').getImmediate();
1117
+ const INSTALLATIONS_NAME = 'installations';
1118
+ const INSTALLATIONS_NAME_INTERNAL = 'installations-internal';
1119
+ const publicFactory = (container) => {
1120
+ const app$1 = container.getProvider('app').getImmediate();
1390
1121
  // Throws if app isn't configured properly.
1391
- var appConfig = extractAppConfig(app$1);
1392
- var heartbeatServiceProvider = app._getProvider(app$1, 'heartbeat');
1393
- var installationsImpl = {
1122
+ const appConfig = extractAppConfig(app$1);
1123
+ const heartbeatServiceProvider = app._getProvider(app$1, 'heartbeat');
1124
+ const installationsImpl = {
1394
1125
  app: app$1,
1395
- appConfig: appConfig,
1396
- heartbeatServiceProvider: heartbeatServiceProvider,
1397
- _delete: function () { return Promise.resolve(); }
1126
+ appConfig,
1127
+ heartbeatServiceProvider,
1128
+ _delete: () => Promise.resolve()
1398
1129
  };
1399
1130
  return installationsImpl;
1400
1131
  };
1401
- var internalFactory = function (container) {
1402
- var app$1 = container.getProvider('app').getImmediate();
1132
+ const internalFactory = (container) => {
1133
+ const app$1 = container.getProvider('app').getImmediate();
1403
1134
  // 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); }
1135
+ const installations = app._getProvider(app$1, INSTALLATIONS_NAME).getImmediate();
1136
+ const installationsInternal = {
1137
+ getId: () => getId(installations),
1138
+ getToken: (forceRefresh) => getToken(installations, forceRefresh)
1408
1139
  };
1409
1140
  return installationsInternal;
1410
1141
  };
@@ -1421,8 +1152,8 @@ function registerInstallations() {
1421
1152
  */
1422
1153
  registerInstallations();
1423
1154
  app.registerVersion(name, version);
1424
- // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
1425
- app.registerVersion(name, version, 'cjs5');
1155
+ // BUILD_TARGET will be replaced by values like esm2017, cjs2017, etc during the compilation
1156
+ app.registerVersion(name, version, 'cjs2017');
1426
1157
 
1427
1158
  exports.deleteInstallations = deleteInstallations;
1428
1159
  exports.getId = getId;