@firebase/installations
Advanced tools
Comparing version 0.6.9-canary.2e2804139 to 0.6.9-canary.479226bf3
@@ -7,3 +7,3 @@ import { _getProvider, getApp, _registerComponent, registerVersion } from '@firebase/app'; | ||
const name = "@firebase/installations"; | ||
const version = "0.6.9-canary.2e2804139"; | ||
const version = "0.6.9-canary.479226bf3"; | ||
@@ -1152,3 +1152,3 @@ /** | ||
registerVersion(name, version); | ||
// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation | ||
// BUILD_TARGET will be replaced by values like esm2017, cjs2017, etc during the compilation | ||
registerVersion(name, version, 'esm2017'); | ||
@@ -1155,0 +1155,0 @@ |
@@ -7,8 +7,7 @@ 'use strict'; | ||
var component = require('@firebase/component'); | ||
var tslib = require('tslib'); | ||
var util = require('@firebase/util'); | ||
var idb = require('idb'); | ||
var name = "@firebase/installations"; | ||
var version = "0.6.9-canary.2e2804139"; | ||
const name = "@firebase/installations"; | ||
const version = "0.6.9-canary.479226bf3"; | ||
@@ -31,9 +30,9 @@ /** | ||
*/ | ||
var PENDING_TIMEOUT_MS = 10000; | ||
var PACKAGE_VERSION = "w:".concat(version); | ||
var INTERNAL_AUTH_VERSION = 'FIS_v2'; | ||
var INSTALLATIONS_API_URL = 'https://firebaseinstallations.googleapis.com/v1'; | ||
var TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour | ||
var SERVICE = 'installations'; | ||
var SERVICE_NAME = 'Installations'; | ||
const PENDING_TIMEOUT_MS = 10000; | ||
const PACKAGE_VERSION = `w:${version}`; | ||
const INTERNAL_AUTH_VERSION = 'FIS_v2'; | ||
const INSTALLATIONS_API_URL = 'https://firebaseinstallations.googleapis.com/v1'; | ||
const TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour | ||
const SERVICE = 'installations'; | ||
const SERVICE_NAME = 'Installations'; | ||
@@ -56,12 +55,11 @@ /** | ||
*/ | ||
var _a; | ||
var ERROR_DESCRIPTION_MAP = (_a = {}, | ||
_a["missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */] = 'Missing App configuration value: "{$valueName}"', | ||
_a["not-registered" /* ErrorCode.NOT_REGISTERED */] = 'Firebase Installation is not registered.', | ||
_a["installation-not-found" /* ErrorCode.INSTALLATION_NOT_FOUND */] = 'Firebase Installation not found.', | ||
_a["request-failed" /* ErrorCode.REQUEST_FAILED */] = '{$requestName} request failed with error "{$serverCode} {$serverStatus}: {$serverMessage}"', | ||
_a["app-offline" /* ErrorCode.APP_OFFLINE */] = 'Could not process request. Application offline.', | ||
_a["delete-pending-registration" /* ErrorCode.DELETE_PENDING_REGISTRATION */] = "Can't delete installation while there is a pending registration request.", | ||
_a); | ||
var ERROR_FACTORY = new util.ErrorFactory(SERVICE, SERVICE_NAME, ERROR_DESCRIPTION_MAP); | ||
const ERROR_DESCRIPTION_MAP = { | ||
["missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */]: 'Missing App configuration value: "{$valueName}"', | ||
["not-registered" /* ErrorCode.NOT_REGISTERED */]: 'Firebase Installation is not registered.', | ||
["installation-not-found" /* ErrorCode.INSTALLATION_NOT_FOUND */]: 'Firebase Installation not found.', | ||
["request-failed" /* ErrorCode.REQUEST_FAILED */]: '{$requestName} request failed with error "{$serverCode} {$serverStatus}: {$serverMessage}"', | ||
["app-offline" /* ErrorCode.APP_OFFLINE */]: 'Could not process request. Application offline.', | ||
["delete-pending-registration" /* ErrorCode.DELETE_PENDING_REGISTRATION */]: "Can't delete installation while there is a pending registration request." | ||
}; | ||
const ERROR_FACTORY = new util.ErrorFactory(SERVICE, SERVICE_NAME, ERROR_DESCRIPTION_MAP); | ||
/** Returns true if error is a FirebaseError that is based on an error from the server. */ | ||
@@ -89,5 +87,4 @@ function isServerError(error) { | ||
*/ | ||
function getInstallationsEndpoint(_a) { | ||
var projectId = _a.projectId; | ||
return "".concat(INSTALLATIONS_API_URL, "/projects/").concat(projectId, "/installations"); | ||
function getInstallationsEndpoint({ projectId }) { | ||
return `${INSTALLATIONS_API_URL}/projects/${projectId}/installations`; | ||
} | ||
@@ -102,23 +99,13 @@ function extractAuthTokenInfoFromResponse(response) { | ||
} | ||
function getErrorFromResponse(requestName, response) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var responseJson, errorData; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, response.json()]; | ||
case 1: | ||
responseJson = _a.sent(); | ||
errorData = responseJson.error; | ||
return [2 /*return*/, ERROR_FACTORY.create("request-failed" /* ErrorCode.REQUEST_FAILED */, { | ||
requestName: requestName, | ||
serverCode: errorData.code, | ||
serverMessage: errorData.message, | ||
serverStatus: errorData.status | ||
})]; | ||
} | ||
}); | ||
async function getErrorFromResponse(requestName, response) { | ||
const responseJson = await response.json(); | ||
const errorData = responseJson.error; | ||
return ERROR_FACTORY.create("request-failed" /* ErrorCode.REQUEST_FAILED */, { | ||
requestName, | ||
serverCode: errorData.code, | ||
serverMessage: errorData.message, | ||
serverStatus: errorData.status | ||
}); | ||
} | ||
function getHeaders(_a) { | ||
var apiKey = _a.apiKey; | ||
function getHeaders({ apiKey }) { | ||
return new Headers({ | ||
@@ -130,5 +117,4 @@ 'Content-Type': 'application/json', | ||
} | ||
function getHeadersWithAuth(appConfig, _a) { | ||
var refreshToken = _a.refreshToken; | ||
var headers = getHeaders(appConfig); | ||
function getHeadersWithAuth(appConfig, { refreshToken }) { | ||
const headers = getHeaders(appConfig); | ||
headers.append('Authorization', getAuthorizationHeader(refreshToken)); | ||
@@ -142,18 +128,9 @@ return headers; | ||
*/ | ||
function retryIfServerError(fn) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var result; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, fn()]; | ||
case 1: | ||
result = _a.sent(); | ||
if (result.status >= 500 && result.status < 600) { | ||
// Internal Server Error. Retry request. | ||
return [2 /*return*/, fn()]; | ||
} | ||
return [2 /*return*/, result]; | ||
} | ||
}); | ||
}); | ||
async function retryIfServerError(fn) { | ||
const result = await fn(); | ||
if (result.status >= 500 && result.status < 600) { | ||
// Internal Server Error. Retry request. | ||
return fn(); | ||
} | ||
return result; | ||
} | ||
@@ -165,3 +142,3 @@ function getExpiresInFromResponseExpiresIn(responseExpiresIn) { | ||
function getAuthorizationHeader(refreshToken) { | ||
return "".concat(INTERNAL_AUTH_VERSION, " ").concat(refreshToken); | ||
return `${INTERNAL_AUTH_VERSION} ${refreshToken}`; | ||
} | ||
@@ -185,54 +162,40 @@ | ||
*/ | ||
function createInstallationRequest(_a, _b) { | ||
var appConfig = _a.appConfig, heartbeatServiceProvider = _a.heartbeatServiceProvider; | ||
var fid = _b.fid; | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var endpoint, headers, heartbeatService, heartbeatsHeader, body, request, response, responseValue, registeredInstallationEntry; | ||
return tslib.__generator(this, function (_c) { | ||
switch (_c.label) { | ||
case 0: | ||
endpoint = getInstallationsEndpoint(appConfig); | ||
headers = getHeaders(appConfig); | ||
heartbeatService = heartbeatServiceProvider.getImmediate({ | ||
optional: true | ||
}); | ||
if (!heartbeatService) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, heartbeatService.getHeartbeatsHeader()]; | ||
case 1: | ||
heartbeatsHeader = _c.sent(); | ||
if (heartbeatsHeader) { | ||
headers.append('x-firebase-client', heartbeatsHeader); | ||
} | ||
_c.label = 2; | ||
case 2: | ||
body = { | ||
fid: fid, | ||
authVersion: INTERNAL_AUTH_VERSION, | ||
appId: appConfig.appId, | ||
sdkVersion: PACKAGE_VERSION | ||
}; | ||
request = { | ||
method: 'POST', | ||
headers: headers, | ||
body: JSON.stringify(body) | ||
}; | ||
return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })]; | ||
case 3: | ||
response = _c.sent(); | ||
if (!response.ok) return [3 /*break*/, 5]; | ||
return [4 /*yield*/, response.json()]; | ||
case 4: | ||
responseValue = _c.sent(); | ||
registeredInstallationEntry = { | ||
fid: responseValue.fid || fid, | ||
registrationStatus: 2 /* RequestStatus.COMPLETED */, | ||
refreshToken: responseValue.refreshToken, | ||
authToken: extractAuthTokenInfoFromResponse(responseValue.authToken) | ||
}; | ||
return [2 /*return*/, registeredInstallationEntry]; | ||
case 5: return [4 /*yield*/, getErrorFromResponse('Create Installation', response)]; | ||
case 6: throw _c.sent(); | ||
} | ||
}); | ||
async function createInstallationRequest({ appConfig, heartbeatServiceProvider }, { fid }) { | ||
const endpoint = getInstallationsEndpoint(appConfig); | ||
const headers = getHeaders(appConfig); | ||
// If heartbeat service exists, add the heartbeat string to the header. | ||
const heartbeatService = heartbeatServiceProvider.getImmediate({ | ||
optional: true | ||
}); | ||
if (heartbeatService) { | ||
const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader(); | ||
if (heartbeatsHeader) { | ||
headers.append('x-firebase-client', heartbeatsHeader); | ||
} | ||
} | ||
const body = { | ||
fid, | ||
authVersion: INTERNAL_AUTH_VERSION, | ||
appId: appConfig.appId, | ||
sdkVersion: PACKAGE_VERSION | ||
}; | ||
const request = { | ||
method: 'POST', | ||
headers, | ||
body: JSON.stringify(body) | ||
}; | ||
const response = await retryIfServerError(() => fetch(endpoint, request)); | ||
if (response.ok) { | ||
const responseValue = await response.json(); | ||
const registeredInstallationEntry = { | ||
fid: responseValue.fid || fid, | ||
registrationStatus: 2 /* RequestStatus.COMPLETED */, | ||
refreshToken: responseValue.refreshToken, | ||
authToken: extractAuthTokenInfoFromResponse(responseValue.authToken) | ||
}; | ||
return registeredInstallationEntry; | ||
} | ||
else { | ||
throw await getErrorFromResponse('Create Installation', response); | ||
} | ||
} | ||
@@ -258,3 +221,3 @@ | ||
function sleep(ms) { | ||
return new Promise(function (resolve) { | ||
return new Promise(resolve => { | ||
setTimeout(resolve, ms); | ||
@@ -281,3 +244,3 @@ }); | ||
function bufferToBase64UrlSafe(array) { | ||
var b64 = btoa(String.fromCharCode.apply(String, tslib.__spreadArray([], tslib.__read(array), false))); | ||
const b64 = btoa(String.fromCharCode(...array)); | ||
return b64.replace(/\+/g, '-').replace(/\//g, '_'); | ||
@@ -302,4 +265,4 @@ } | ||
*/ | ||
var VALID_FID_PATTERN = /^[cdef][\w-]{21}$/; | ||
var INVALID_FID = ''; | ||
const VALID_FID_PATTERN = /^[cdef][\w-]{21}$/; | ||
const INVALID_FID = ''; | ||
/** | ||
@@ -313,8 +276,8 @@ * Generates a new FID using random values from Web Crypto API. | ||
// bytes. our implementation generates a 17 byte array instead. | ||
var fidByteArray = new Uint8Array(17); | ||
var crypto_1 = self.crypto || self.msCrypto; | ||
crypto_1.getRandomValues(fidByteArray); | ||
const fidByteArray = new Uint8Array(17); | ||
const crypto = self.crypto || self.msCrypto; | ||
crypto.getRandomValues(fidByteArray); | ||
// Replace the first 4 random bits with the constant FID header of 0b0111. | ||
fidByteArray[0] = 112 + (fidByteArray[0] % 16); | ||
var fid = encode(fidByteArray); | ||
fidByteArray[0] = 0b01110000 + (fidByteArray[0] % 0b00010000); | ||
const fid = encode(fidByteArray); | ||
return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID; | ||
@@ -329,3 +292,3 @@ } | ||
function encode(fidByteArray) { | ||
var b64String = bufferToBase64UrlSafe(fidByteArray); | ||
const b64String = bufferToBase64UrlSafe(fidByteArray); | ||
// Remove the 23rd character that was added because of the extra 4 bits at the | ||
@@ -354,3 +317,3 @@ // end of our 17 byte array, and the '=' padding. | ||
function getKey(appConfig) { | ||
return "".concat(appConfig.appName, "!").concat(appConfig.appId); | ||
return `${appConfig.appName}!${appConfig.appId}`; | ||
} | ||
@@ -374,3 +337,3 @@ | ||
*/ | ||
var fidChangeCallbacks = new Map(); | ||
const fidChangeCallbacks = new Map(); | ||
/** | ||
@@ -381,3 +344,3 @@ * Calls the onIdChange callbacks with the new FID value, and broadcasts the | ||
function fidChanged(appConfig, fid) { | ||
var key = getKey(appConfig); | ||
const key = getKey(appConfig); | ||
callFidChangeCallbacks(key, fid); | ||
@@ -390,4 +353,4 @@ broadcastFidChange(key, fid); | ||
getBroadcastChannel(); | ||
var key = getKey(appConfig); | ||
var callbackSet = fidChangeCallbacks.get(key); | ||
const key = getKey(appConfig); | ||
let callbackSet = fidChangeCallbacks.get(key); | ||
if (!callbackSet) { | ||
@@ -400,4 +363,4 @@ callbackSet = new Set(); | ||
function removeCallback(appConfig, callback) { | ||
var key = getKey(appConfig); | ||
var callbackSet = fidChangeCallbacks.get(key); | ||
const key = getKey(appConfig); | ||
const callbackSet = fidChangeCallbacks.get(key); | ||
if (!callbackSet) { | ||
@@ -414,29 +377,18 @@ return; | ||
function callFidChangeCallbacks(key, fid) { | ||
var e_1, _a; | ||
var callbacks = fidChangeCallbacks.get(key); | ||
const callbacks = fidChangeCallbacks.get(key); | ||
if (!callbacks) { | ||
return; | ||
} | ||
try { | ||
for (var callbacks_1 = tslib.__values(callbacks), callbacks_1_1 = callbacks_1.next(); !callbacks_1_1.done; callbacks_1_1 = callbacks_1.next()) { | ||
var callback = callbacks_1_1.value; | ||
callback(fid); | ||
} | ||
for (const callback of callbacks) { | ||
callback(fid); | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (callbacks_1_1 && !callbacks_1_1.done && (_a = callbacks_1.return)) _a.call(callbacks_1); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
} | ||
function broadcastFidChange(key, fid) { | ||
var channel = getBroadcastChannel(); | ||
const channel = getBroadcastChannel(); | ||
if (channel) { | ||
channel.postMessage({ key: key, fid: fid }); | ||
channel.postMessage({ key, fid }); | ||
} | ||
closeBroadcastChannel(); | ||
} | ||
var broadcastChannel = null; | ||
let broadcastChannel = null; | ||
/** Opens and returns a BroadcastChannel if it is supported by the browser. */ | ||
@@ -446,3 +398,3 @@ function getBroadcastChannel() { | ||
broadcastChannel = new BroadcastChannel('[Firebase] FID Change'); | ||
broadcastChannel.onmessage = function (e) { | ||
broadcastChannel.onmessage = e => { | ||
callFidChangeCallbacks(e.data.key, e.data.fid); | ||
@@ -476,10 +428,10 @@ }; | ||
*/ | ||
var DATABASE_NAME = 'firebase-installations-database'; | ||
var DATABASE_VERSION = 1; | ||
var OBJECT_STORE_NAME = 'firebase-installations-store'; | ||
var dbPromise = null; | ||
const DATABASE_NAME = 'firebase-installations-database'; | ||
const DATABASE_VERSION = 1; | ||
const OBJECT_STORE_NAME = 'firebase-installations-store'; | ||
let dbPromise = null; | ||
function getDbPromise() { | ||
if (!dbPromise) { | ||
dbPromise = idb.openDB(DATABASE_NAME, DATABASE_VERSION, { | ||
upgrade: function (db, oldVersion) { | ||
upgrade: (db, oldVersion) => { | ||
// We don't use 'break' in this switch statement, the fall-through | ||
@@ -500,53 +452,22 @@ // behavior is what we want, because if there are multiple versions between | ||
/** Assigns or overwrites the record for the given key with the given value. */ | ||
function set(appConfig, value) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var key, db, tx, objectStore, oldValue; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
key = getKey(appConfig); | ||
return [4 /*yield*/, getDbPromise()]; | ||
case 1: | ||
db = _a.sent(); | ||
tx = db.transaction(OBJECT_STORE_NAME, 'readwrite'); | ||
objectStore = tx.objectStore(OBJECT_STORE_NAME); | ||
return [4 /*yield*/, objectStore.get(key)]; | ||
case 2: | ||
oldValue = (_a.sent()); | ||
return [4 /*yield*/, objectStore.put(value, key)]; | ||
case 3: | ||
_a.sent(); | ||
return [4 /*yield*/, tx.done]; | ||
case 4: | ||
_a.sent(); | ||
if (!oldValue || oldValue.fid !== value.fid) { | ||
fidChanged(appConfig, value.fid); | ||
} | ||
return [2 /*return*/, value]; | ||
} | ||
}); | ||
}); | ||
async function set(appConfig, value) { | ||
const key = getKey(appConfig); | ||
const db = await getDbPromise(); | ||
const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite'); | ||
const objectStore = tx.objectStore(OBJECT_STORE_NAME); | ||
const oldValue = (await objectStore.get(key)); | ||
await objectStore.put(value, key); | ||
await tx.done; | ||
if (!oldValue || oldValue.fid !== value.fid) { | ||
fidChanged(appConfig, value.fid); | ||
} | ||
return value; | ||
} | ||
/** Removes record(s) from the objectStore that match the given key. */ | ||
function remove(appConfig) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var key, db, tx; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
key = getKey(appConfig); | ||
return [4 /*yield*/, getDbPromise()]; | ||
case 1: | ||
db = _a.sent(); | ||
tx = db.transaction(OBJECT_STORE_NAME, 'readwrite'); | ||
return [4 /*yield*/, tx.objectStore(OBJECT_STORE_NAME).delete(key)]; | ||
case 2: | ||
_a.sent(); | ||
return [4 /*yield*/, tx.done]; | ||
case 3: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
async function remove(appConfig) { | ||
const key = getKey(appConfig); | ||
const db = await getDbPromise(); | ||
const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite'); | ||
await tx.objectStore(OBJECT_STORE_NAME).delete(key); | ||
await tx.done; | ||
} | ||
@@ -559,37 +480,20 @@ /** | ||
*/ | ||
function update(appConfig, updateFn) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var key, db, tx, store, oldValue, newValue; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
key = getKey(appConfig); | ||
return [4 /*yield*/, getDbPromise()]; | ||
case 1: | ||
db = _a.sent(); | ||
tx = db.transaction(OBJECT_STORE_NAME, 'readwrite'); | ||
store = tx.objectStore(OBJECT_STORE_NAME); | ||
return [4 /*yield*/, store.get(key)]; | ||
case 2: | ||
oldValue = (_a.sent()); | ||
newValue = updateFn(oldValue); | ||
if (!(newValue === undefined)) return [3 /*break*/, 4]; | ||
return [4 /*yield*/, store.delete(key)]; | ||
case 3: | ||
_a.sent(); | ||
return [3 /*break*/, 6]; | ||
case 4: return [4 /*yield*/, store.put(newValue, key)]; | ||
case 5: | ||
_a.sent(); | ||
_a.label = 6; | ||
case 6: return [4 /*yield*/, tx.done]; | ||
case 7: | ||
_a.sent(); | ||
if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) { | ||
fidChanged(appConfig, newValue.fid); | ||
} | ||
return [2 /*return*/, newValue]; | ||
} | ||
}); | ||
}); | ||
async function update(appConfig, updateFn) { | ||
const key = getKey(appConfig); | ||
const db = await getDbPromise(); | ||
const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite'); | ||
const store = tx.objectStore(OBJECT_STORE_NAME); | ||
const oldValue = (await store.get(key)); | ||
const newValue = updateFn(oldValue); | ||
if (newValue === undefined) { | ||
await store.delete(key); | ||
} | ||
else { | ||
await store.put(newValue, key); | ||
} | ||
await tx.done; | ||
if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) { | ||
fidChanged(appConfig, newValue.fid); | ||
} | ||
return newValue; | ||
} | ||
@@ -617,29 +521,18 @@ | ||
*/ | ||
function getInstallationEntry(installations) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var registrationPromise, installationEntry; | ||
var _a; | ||
return tslib.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: return [4 /*yield*/, update(installations.appConfig, function (oldEntry) { | ||
var installationEntry = updateOrCreateInstallationEntry(oldEntry); | ||
var entryWithPromise = triggerRegistrationIfNecessary(installations, installationEntry); | ||
registrationPromise = entryWithPromise.registrationPromise; | ||
return entryWithPromise.installationEntry; | ||
})]; | ||
case 1: | ||
installationEntry = _b.sent(); | ||
if (!(installationEntry.fid === INVALID_FID)) return [3 /*break*/, 3]; | ||
_a = {}; | ||
return [4 /*yield*/, registrationPromise]; | ||
case 2: | ||
// FID generation failed. Waiting for the FID from the server. | ||
return [2 /*return*/, (_a.installationEntry = _b.sent(), _a)]; | ||
case 3: return [2 /*return*/, { | ||
installationEntry: installationEntry, | ||
registrationPromise: registrationPromise | ||
}]; | ||
} | ||
}); | ||
async function getInstallationEntry(installations) { | ||
let registrationPromise; | ||
const installationEntry = await update(installations.appConfig, oldEntry => { | ||
const installationEntry = updateOrCreateInstallationEntry(oldEntry); | ||
const entryWithPromise = triggerRegistrationIfNecessary(installations, installationEntry); | ||
registrationPromise = entryWithPromise.registrationPromise; | ||
return entryWithPromise.installationEntry; | ||
}); | ||
if (installationEntry.fid === INVALID_FID) { | ||
// FID generation failed. Waiting for the FID from the server. | ||
return { installationEntry: await registrationPromise }; | ||
} | ||
return { | ||
installationEntry, | ||
registrationPromise | ||
}; | ||
} | ||
@@ -651,3 +544,3 @@ /** | ||
function updateOrCreateInstallationEntry(oldEntry) { | ||
var entry = oldEntry || { | ||
const entry = oldEntry || { | ||
fid: generateFid(), | ||
@@ -669,5 +562,5 @@ registrationStatus: 0 /* RequestStatus.NOT_STARTED */ | ||
// Registration required but app is offline. | ||
var registrationPromiseWithError = Promise.reject(ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */)); | ||
const registrationPromiseWithError = Promise.reject(ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */)); | ||
return { | ||
installationEntry: installationEntry, | ||
installationEntry, | ||
registrationPromise: registrationPromiseWithError | ||
@@ -677,3 +570,3 @@ }; | ||
// Try registering. Change status to IN_PROGRESS. | ||
var inProgressEntry = { | ||
const inProgressEntry = { | ||
fid: installationEntry.fid, | ||
@@ -683,8 +576,8 @@ registrationStatus: 1 /* RequestStatus.IN_PROGRESS */, | ||
}; | ||
var registrationPromise = registerInstallation(installations, inProgressEntry); | ||
return { installationEntry: inProgressEntry, registrationPromise: registrationPromise }; | ||
const registrationPromise = registerInstallation(installations, inProgressEntry); | ||
return { installationEntry: inProgressEntry, registrationPromise }; | ||
} | ||
else if (installationEntry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */) { | ||
return { | ||
installationEntry: installationEntry, | ||
installationEntry, | ||
registrationPromise: waitUntilFidRegistration(installations) | ||
@@ -694,81 +587,50 @@ }; | ||
else { | ||
return { installationEntry: installationEntry }; | ||
return { installationEntry }; | ||
} | ||
} | ||
/** This will be executed only once for each new Firebase Installation. */ | ||
function registerInstallation(installations, installationEntry) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var registeredInstallationEntry, e_1; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 7]); | ||
return [4 /*yield*/, createInstallationRequest(installations, installationEntry)]; | ||
case 1: | ||
registeredInstallationEntry = _a.sent(); | ||
return [2 /*return*/, set(installations.appConfig, registeredInstallationEntry)]; | ||
case 2: | ||
e_1 = _a.sent(); | ||
if (!(isServerError(e_1) && e_1.customData.serverCode === 409)) return [3 /*break*/, 4]; | ||
// Server returned a "FID cannot be used" error. | ||
// Generate a new ID next time. | ||
return [4 /*yield*/, remove(installations.appConfig)]; | ||
case 3: | ||
// Server returned a "FID cannot be used" error. | ||
// Generate a new ID next time. | ||
_a.sent(); | ||
return [3 /*break*/, 6]; | ||
case 4: | ||
// Registration failed. Set FID as not registered. | ||
return [4 /*yield*/, set(installations.appConfig, { | ||
fid: installationEntry.fid, | ||
registrationStatus: 0 /* RequestStatus.NOT_STARTED */ | ||
})]; | ||
case 5: | ||
// Registration failed. Set FID as not registered. | ||
_a.sent(); | ||
_a.label = 6; | ||
case 6: throw e_1; | ||
case 7: return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
async function registerInstallation(installations, installationEntry) { | ||
try { | ||
const registeredInstallationEntry = await createInstallationRequest(installations, installationEntry); | ||
return set(installations.appConfig, registeredInstallationEntry); | ||
} | ||
catch (e) { | ||
if (isServerError(e) && e.customData.serverCode === 409) { | ||
// Server returned a "FID cannot be used" error. | ||
// Generate a new ID next time. | ||
await remove(installations.appConfig); | ||
} | ||
else { | ||
// Registration failed. Set FID as not registered. | ||
await set(installations.appConfig, { | ||
fid: installationEntry.fid, | ||
registrationStatus: 0 /* RequestStatus.NOT_STARTED */ | ||
}); | ||
} | ||
throw e; | ||
} | ||
} | ||
/** Call if FID registration is pending in another request. */ | ||
function waitUntilFidRegistration(installations) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var entry, _a, installationEntry, registrationPromise; | ||
return tslib.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: return [4 /*yield*/, updateInstallationRequest(installations.appConfig)]; | ||
case 1: | ||
entry = _b.sent(); | ||
_b.label = 2; | ||
case 2: | ||
if (!(entry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */)) return [3 /*break*/, 5]; | ||
// createInstallation request still in progress. | ||
return [4 /*yield*/, sleep(100)]; | ||
case 3: | ||
// createInstallation request still in progress. | ||
_b.sent(); | ||
return [4 /*yield*/, updateInstallationRequest(installations.appConfig)]; | ||
case 4: | ||
entry = _b.sent(); | ||
return [3 /*break*/, 2]; | ||
case 5: | ||
if (!(entry.registrationStatus === 0 /* RequestStatus.NOT_STARTED */)) return [3 /*break*/, 7]; | ||
return [4 /*yield*/, getInstallationEntry(installations)]; | ||
case 6: | ||
_a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise; | ||
if (registrationPromise) { | ||
return [2 /*return*/, registrationPromise]; | ||
} | ||
else { | ||
// if there is no registrationPromise, entry is registered. | ||
return [2 /*return*/, installationEntry]; | ||
} | ||
case 7: return [2 /*return*/, entry]; | ||
} | ||
}); | ||
}); | ||
async function waitUntilFidRegistration(installations) { | ||
// Unfortunately, there is no way of reliably observing when a value in | ||
// IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers), | ||
// so we need to poll. | ||
let entry = await updateInstallationRequest(installations.appConfig); | ||
while (entry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */) { | ||
// createInstallation request still in progress. | ||
await sleep(100); | ||
entry = await updateInstallationRequest(installations.appConfig); | ||
} | ||
if (entry.registrationStatus === 0 /* RequestStatus.NOT_STARTED */) { | ||
// The request timed out or failed in a different call. Try again. | ||
const { installationEntry, registrationPromise } = await getInstallationEntry(installations); | ||
if (registrationPromise) { | ||
return registrationPromise; | ||
} | ||
else { | ||
// if there is no registrationPromise, entry is registered. | ||
return installationEntry; | ||
} | ||
} | ||
return entry; | ||
} | ||
@@ -784,3 +646,3 @@ /** | ||
function updateInstallationRequest(appConfig) { | ||
return update(appConfig, function (oldEntry) { | ||
return update(appConfig, oldEntry => { | ||
if (!oldEntry) { | ||
@@ -822,52 +684,38 @@ throw ERROR_FACTORY.create("installation-not-found" /* ErrorCode.INSTALLATION_NOT_FOUND */); | ||
*/ | ||
function generateAuthTokenRequest(_a, installationEntry) { | ||
var appConfig = _a.appConfig, heartbeatServiceProvider = _a.heartbeatServiceProvider; | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var endpoint, headers, heartbeatService, heartbeatsHeader, body, request, response, responseValue, completedAuthToken; | ||
return tslib.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry); | ||
headers = getHeadersWithAuth(appConfig, installationEntry); | ||
heartbeatService = heartbeatServiceProvider.getImmediate({ | ||
optional: true | ||
}); | ||
if (!heartbeatService) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, heartbeatService.getHeartbeatsHeader()]; | ||
case 1: | ||
heartbeatsHeader = _b.sent(); | ||
if (heartbeatsHeader) { | ||
headers.append('x-firebase-client', heartbeatsHeader); | ||
} | ||
_b.label = 2; | ||
case 2: | ||
body = { | ||
installation: { | ||
sdkVersion: PACKAGE_VERSION, | ||
appId: appConfig.appId | ||
} | ||
}; | ||
request = { | ||
method: 'POST', | ||
headers: headers, | ||
body: JSON.stringify(body) | ||
}; | ||
return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })]; | ||
case 3: | ||
response = _b.sent(); | ||
if (!response.ok) return [3 /*break*/, 5]; | ||
return [4 /*yield*/, response.json()]; | ||
case 4: | ||
responseValue = _b.sent(); | ||
completedAuthToken = extractAuthTokenInfoFromResponse(responseValue); | ||
return [2 /*return*/, completedAuthToken]; | ||
case 5: return [4 /*yield*/, getErrorFromResponse('Generate Auth Token', response)]; | ||
case 6: throw _b.sent(); | ||
} | ||
}); | ||
async function generateAuthTokenRequest({ appConfig, heartbeatServiceProvider }, installationEntry) { | ||
const endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry); | ||
const headers = getHeadersWithAuth(appConfig, installationEntry); | ||
// If heartbeat service exists, add the heartbeat string to the header. | ||
const heartbeatService = heartbeatServiceProvider.getImmediate({ | ||
optional: true | ||
}); | ||
if (heartbeatService) { | ||
const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader(); | ||
if (heartbeatsHeader) { | ||
headers.append('x-firebase-client', heartbeatsHeader); | ||
} | ||
} | ||
const body = { | ||
installation: { | ||
sdkVersion: PACKAGE_VERSION, | ||
appId: appConfig.appId | ||
} | ||
}; | ||
const request = { | ||
method: 'POST', | ||
headers, | ||
body: JSON.stringify(body) | ||
}; | ||
const response = await retryIfServerError(() => fetch(endpoint, request)); | ||
if (response.ok) { | ||
const responseValue = await response.json(); | ||
const completedAuthToken = extractAuthTokenInfoFromResponse(responseValue); | ||
return completedAuthToken; | ||
} | ||
else { | ||
throw await getErrorFromResponse('Generate Auth Token', response); | ||
} | ||
} | ||
function getGenerateAuthTokenEndpoint(appConfig, _a) { | ||
var fid = _a.fid; | ||
return "".concat(getInstallationsEndpoint(appConfig), "/").concat(fid, "/authTokens:generate"); | ||
function getGenerateAuthTokenEndpoint(appConfig, { fid }) { | ||
return `${getInstallationsEndpoint(appConfig)}/${fid}/authTokens:generate`; | ||
} | ||
@@ -897,48 +745,32 @@ | ||
*/ | ||
function refreshAuthToken(installations, forceRefresh) { | ||
if (forceRefresh === void 0) { forceRefresh = false; } | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var tokenPromise, entry, authToken, _a; | ||
return tslib.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: return [4 /*yield*/, update(installations.appConfig, function (oldEntry) { | ||
if (!isEntryRegistered(oldEntry)) { | ||
throw ERROR_FACTORY.create("not-registered" /* ErrorCode.NOT_REGISTERED */); | ||
} | ||
var oldAuthToken = oldEntry.authToken; | ||
if (!forceRefresh && isAuthTokenValid(oldAuthToken)) { | ||
// There is a valid token in the DB. | ||
return oldEntry; | ||
} | ||
else if (oldAuthToken.requestStatus === 1 /* RequestStatus.IN_PROGRESS */) { | ||
// There already is a token request in progress. | ||
tokenPromise = waitUntilAuthTokenRequest(installations, forceRefresh); | ||
return oldEntry; | ||
} | ||
else { | ||
// No token or token expired. | ||
if (!navigator.onLine) { | ||
throw ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */); | ||
} | ||
var inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry); | ||
tokenPromise = fetchAuthTokenFromServer(installations, inProgressEntry); | ||
return inProgressEntry; | ||
} | ||
})]; | ||
case 1: | ||
entry = _b.sent(); | ||
if (!tokenPromise) return [3 /*break*/, 3]; | ||
return [4 /*yield*/, tokenPromise]; | ||
case 2: | ||
_a = _b.sent(); | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
_a = entry.authToken; | ||
_b.label = 4; | ||
case 4: | ||
authToken = _a; | ||
return [2 /*return*/, authToken]; | ||
async function refreshAuthToken(installations, forceRefresh = false) { | ||
let tokenPromise; | ||
const entry = await update(installations.appConfig, oldEntry => { | ||
if (!isEntryRegistered(oldEntry)) { | ||
throw ERROR_FACTORY.create("not-registered" /* ErrorCode.NOT_REGISTERED */); | ||
} | ||
const oldAuthToken = oldEntry.authToken; | ||
if (!forceRefresh && isAuthTokenValid(oldAuthToken)) { | ||
// There is a valid token in the DB. | ||
return oldEntry; | ||
} | ||
else if (oldAuthToken.requestStatus === 1 /* RequestStatus.IN_PROGRESS */) { | ||
// There already is a token request in progress. | ||
tokenPromise = waitUntilAuthTokenRequest(installations, forceRefresh); | ||
return oldEntry; | ||
} | ||
else { | ||
// No token or token expired. | ||
if (!navigator.onLine) { | ||
throw ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */); | ||
} | ||
}); | ||
const inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry); | ||
tokenPromise = fetchAuthTokenFromServer(installations, inProgressEntry); | ||
return inProgressEntry; | ||
} | ||
}); | ||
const authToken = tokenPromise | ||
? await tokenPromise | ||
: entry.authToken; | ||
return authToken; | ||
} | ||
@@ -951,34 +783,20 @@ /** | ||
*/ | ||
function waitUntilAuthTokenRequest(installations, forceRefresh) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var entry, authToken; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, updateAuthTokenRequest(installations.appConfig)]; | ||
case 1: | ||
entry = _a.sent(); | ||
_a.label = 2; | ||
case 2: | ||
if (!(entry.authToken.requestStatus === 1 /* RequestStatus.IN_PROGRESS */)) return [3 /*break*/, 5]; | ||
// generateAuthToken still in progress. | ||
return [4 /*yield*/, sleep(100)]; | ||
case 3: | ||
// generateAuthToken still in progress. | ||
_a.sent(); | ||
return [4 /*yield*/, updateAuthTokenRequest(installations.appConfig)]; | ||
case 4: | ||
entry = _a.sent(); | ||
return [3 /*break*/, 2]; | ||
case 5: | ||
authToken = entry.authToken; | ||
if (authToken.requestStatus === 0 /* RequestStatus.NOT_STARTED */) { | ||
// The request timed out or failed in a different call. Try again. | ||
return [2 /*return*/, refreshAuthToken(installations, forceRefresh)]; | ||
} | ||
else { | ||
return [2 /*return*/, authToken]; | ||
} | ||
} | ||
}); | ||
}); | ||
async function waitUntilAuthTokenRequest(installations, forceRefresh) { | ||
// Unfortunately, there is no way of reliably observing when a value in | ||
// IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers), | ||
// so we need to poll. | ||
let entry = await updateAuthTokenRequest(installations.appConfig); | ||
while (entry.authToken.requestStatus === 1 /* RequestStatus.IN_PROGRESS */) { | ||
// generateAuthToken still in progress. | ||
await sleep(100); | ||
entry = await updateAuthTokenRequest(installations.appConfig); | ||
} | ||
const authToken = entry.authToken; | ||
if (authToken.requestStatus === 0 /* RequestStatus.NOT_STARTED */) { | ||
// The request timed out or failed in a different call. Try again. | ||
return refreshAuthToken(installations, forceRefresh); | ||
} | ||
else { | ||
return authToken; | ||
} | ||
} | ||
@@ -994,9 +812,9 @@ /** | ||
function updateAuthTokenRequest(appConfig) { | ||
return update(appConfig, function (oldEntry) { | ||
return update(appConfig, oldEntry => { | ||
if (!isEntryRegistered(oldEntry)) { | ||
throw ERROR_FACTORY.create("not-registered" /* ErrorCode.NOT_REGISTERED */); | ||
} | ||
var oldAuthToken = oldEntry.authToken; | ||
const oldAuthToken = oldEntry.authToken; | ||
if (hasAuthTokenRequestTimedOut(oldAuthToken)) { | ||
return tslib.__assign(tslib.__assign({}, oldEntry), { authToken: { requestStatus: 0 /* RequestStatus.NOT_STARTED */ } }); | ||
return Object.assign(Object.assign({}, oldEntry), { authToken: { requestStatus: 0 /* RequestStatus.NOT_STARTED */ } }); | ||
} | ||
@@ -1006,40 +824,22 @@ return oldEntry; | ||
} | ||
function fetchAuthTokenFromServer(installations, installationEntry) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var authToken, updatedInstallationEntry, e_1, updatedInstallationEntry; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 3, , 8]); | ||
return [4 /*yield*/, generateAuthTokenRequest(installations, installationEntry)]; | ||
case 1: | ||
authToken = _a.sent(); | ||
updatedInstallationEntry = tslib.__assign(tslib.__assign({}, installationEntry), { authToken: authToken }); | ||
return [4 /*yield*/, set(installations.appConfig, updatedInstallationEntry)]; | ||
case 2: | ||
_a.sent(); | ||
return [2 /*return*/, authToken]; | ||
case 3: | ||
e_1 = _a.sent(); | ||
if (!(isServerError(e_1) && | ||
(e_1.customData.serverCode === 401 || e_1.customData.serverCode === 404))) return [3 /*break*/, 5]; | ||
// Server returned a "FID not found" or a "Invalid authentication" error. | ||
// Generate a new ID next time. | ||
return [4 /*yield*/, remove(installations.appConfig)]; | ||
case 4: | ||
// Server returned a "FID not found" or a "Invalid authentication" error. | ||
// Generate a new ID next time. | ||
_a.sent(); | ||
return [3 /*break*/, 7]; | ||
case 5: | ||
updatedInstallationEntry = tslib.__assign(tslib.__assign({}, installationEntry), { authToken: { requestStatus: 0 /* RequestStatus.NOT_STARTED */ } }); | ||
return [4 /*yield*/, set(installations.appConfig, updatedInstallationEntry)]; | ||
case 6: | ||
_a.sent(); | ||
_a.label = 7; | ||
case 7: throw e_1; | ||
case 8: return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
async function fetchAuthTokenFromServer(installations, installationEntry) { | ||
try { | ||
const authToken = await generateAuthTokenRequest(installations, installationEntry); | ||
const updatedInstallationEntry = Object.assign(Object.assign({}, installationEntry), { authToken }); | ||
await set(installations.appConfig, updatedInstallationEntry); | ||
return authToken; | ||
} | ||
catch (e) { | ||
if (isServerError(e) && | ||
(e.customData.serverCode === 401 || e.customData.serverCode === 404)) { | ||
// Server returned a "FID not found" or a "Invalid authentication" error. | ||
// Generate a new ID next time. | ||
await remove(installations.appConfig); | ||
} | ||
else { | ||
const updatedInstallationEntry = Object.assign(Object.assign({}, installationEntry), { authToken: { requestStatus: 0 /* RequestStatus.NOT_STARTED */ } }); | ||
await set(installations.appConfig, updatedInstallationEntry); | ||
} | ||
throw e; | ||
} | ||
} | ||
@@ -1055,3 +855,3 @@ function isEntryRegistered(installationEntry) { | ||
function isAuthTokenExpired(authToken) { | ||
var now = Date.now(); | ||
const now = Date.now(); | ||
return (now < authToken.creationTime || | ||
@@ -1062,7 +862,7 @@ authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER); | ||
function makeAuthTokenRequestInProgressEntry(oldEntry) { | ||
var inProgressAuthToken = { | ||
const inProgressAuthToken = { | ||
requestStatus: 1 /* RequestStatus.IN_PROGRESS */, | ||
requestTime: Date.now() | ||
}; | ||
return tslib.__assign(tslib.__assign({}, oldEntry), { authToken: inProgressAuthToken }); | ||
return Object.assign(Object.assign({}, oldEntry), { authToken: inProgressAuthToken }); | ||
} | ||
@@ -1097,24 +897,14 @@ function hasAuthTokenRequestTimedOut(authToken) { | ||
*/ | ||
function getId(installations) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var installationsImpl, _a, installationEntry, registrationPromise; | ||
return tslib.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
installationsImpl = installations; | ||
return [4 /*yield*/, getInstallationEntry(installationsImpl)]; | ||
case 1: | ||
_a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise; | ||
if (registrationPromise) { | ||
registrationPromise.catch(console.error); | ||
} | ||
else { | ||
// If the installation is already registered, update the authentication | ||
// token if needed. | ||
refreshAuthToken(installationsImpl).catch(console.error); | ||
} | ||
return [2 /*return*/, installationEntry.fid]; | ||
} | ||
}); | ||
}); | ||
async function getId(installations) { | ||
const installationsImpl = installations; | ||
const { installationEntry, registrationPromise } = await getInstallationEntry(installationsImpl); | ||
if (registrationPromise) { | ||
registrationPromise.catch(console.error); | ||
} | ||
else { | ||
// If the installation is already registered, update the authentication | ||
// token if needed. | ||
refreshAuthToken(installationsImpl).catch(console.error); | ||
} | ||
return installationEntry.fid; | ||
} | ||
@@ -1146,40 +936,16 @@ | ||
*/ | ||
function getToken(installations, forceRefresh) { | ||
if (forceRefresh === void 0) { forceRefresh = false; } | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var installationsImpl, authToken; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
installationsImpl = installations; | ||
return [4 /*yield*/, completeInstallationRegistration(installationsImpl)]; | ||
case 1: | ||
_a.sent(); | ||
return [4 /*yield*/, refreshAuthToken(installationsImpl, forceRefresh)]; | ||
case 2: | ||
authToken = _a.sent(); | ||
return [2 /*return*/, authToken.token]; | ||
} | ||
}); | ||
}); | ||
async function getToken(installations, forceRefresh = false) { | ||
const installationsImpl = installations; | ||
await completeInstallationRegistration(installationsImpl); | ||
// At this point we either have a Registered Installation in the DB, or we've | ||
// already thrown an error. | ||
const authToken = await refreshAuthToken(installationsImpl, forceRefresh); | ||
return authToken.token; | ||
} | ||
function completeInstallationRegistration(installations) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var registrationPromise; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, getInstallationEntry(installations)]; | ||
case 1: | ||
registrationPromise = (_a.sent()).registrationPromise; | ||
if (!registrationPromise) return [3 /*break*/, 3]; | ||
// A createInstallation request is in progress. Wait until it finishes. | ||
return [4 /*yield*/, registrationPromise]; | ||
case 2: | ||
// A createInstallation request is in progress. Wait until it finishes. | ||
_a.sent(); | ||
_a.label = 3; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
async function completeInstallationRegistration(installations) { | ||
const { registrationPromise } = await getInstallationEntry(installations); | ||
if (registrationPromise) { | ||
// A createInstallation request is in progress. Wait until it finishes. | ||
await registrationPromise; | ||
} | ||
} | ||
@@ -1203,28 +969,16 @@ | ||
*/ | ||
function deleteInstallationRequest(appConfig, installationEntry) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var endpoint, headers, request, response; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
endpoint = getDeleteEndpoint(appConfig, installationEntry); | ||
headers = getHeadersWithAuth(appConfig, installationEntry); | ||
request = { | ||
method: 'DELETE', | ||
headers: headers | ||
}; | ||
return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })]; | ||
case 1: | ||
response = _a.sent(); | ||
if (!!response.ok) return [3 /*break*/, 3]; | ||
return [4 /*yield*/, getErrorFromResponse('Delete Installation', response)]; | ||
case 2: throw _a.sent(); | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
async function deleteInstallationRequest(appConfig, installationEntry) { | ||
const endpoint = getDeleteEndpoint(appConfig, installationEntry); | ||
const headers = getHeadersWithAuth(appConfig, installationEntry); | ||
const request = { | ||
method: 'DELETE', | ||
headers | ||
}; | ||
const response = await retryIfServerError(() => fetch(endpoint, request)); | ||
if (!response.ok) { | ||
throw await getErrorFromResponse('Delete Installation', response); | ||
} | ||
} | ||
function getDeleteEndpoint(appConfig, _a) { | ||
var fid = _a.fid; | ||
return "".concat(getInstallationsEndpoint(appConfig), "/").concat(fid); | ||
function getDeleteEndpoint(appConfig, { fid }) { | ||
return `${getInstallationsEndpoint(appConfig)}/${fid}`; | ||
} | ||
@@ -1254,37 +1008,26 @@ | ||
*/ | ||
function deleteInstallations(installations) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var appConfig, entry; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
appConfig = installations.appConfig; | ||
return [4 /*yield*/, update(appConfig, function (oldEntry) { | ||
if (oldEntry && oldEntry.registrationStatus === 0 /* RequestStatus.NOT_STARTED */) { | ||
// Delete the unregistered entry without sending a deleteInstallation request. | ||
return undefined; | ||
} | ||
return oldEntry; | ||
})]; | ||
case 1: | ||
entry = _a.sent(); | ||
if (!entry) return [3 /*break*/, 6]; | ||
if (!(entry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */)) return [3 /*break*/, 2]; | ||
// Can't delete while trying to register. | ||
throw ERROR_FACTORY.create("delete-pending-registration" /* ErrorCode.DELETE_PENDING_REGISTRATION */); | ||
case 2: | ||
if (!(entry.registrationStatus === 2 /* RequestStatus.COMPLETED */)) return [3 /*break*/, 6]; | ||
if (!!navigator.onLine) return [3 /*break*/, 3]; | ||
throw ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */); | ||
case 3: return [4 /*yield*/, deleteInstallationRequest(appConfig, entry)]; | ||
case 4: | ||
_a.sent(); | ||
return [4 /*yield*/, remove(appConfig)]; | ||
case 5: | ||
_a.sent(); | ||
_a.label = 6; | ||
case 6: return [2 /*return*/]; | ||
async function deleteInstallations(installations) { | ||
const { appConfig } = installations; | ||
const entry = await update(appConfig, oldEntry => { | ||
if (oldEntry && oldEntry.registrationStatus === 0 /* RequestStatus.NOT_STARTED */) { | ||
// Delete the unregistered entry without sending a deleteInstallation request. | ||
return undefined; | ||
} | ||
return oldEntry; | ||
}); | ||
if (entry) { | ||
if (entry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */) { | ||
// Can't delete while trying to register. | ||
throw ERROR_FACTORY.create("delete-pending-registration" /* ErrorCode.DELETE_PENDING_REGISTRATION */); | ||
} | ||
else if (entry.registrationStatus === 2 /* RequestStatus.COMPLETED */) { | ||
if (!navigator.onLine) { | ||
throw ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */); | ||
} | ||
}); | ||
}); | ||
else { | ||
await deleteInstallationRequest(appConfig, entry); | ||
await remove(appConfig); | ||
} | ||
} | ||
} | ||
} | ||
@@ -1318,5 +1061,5 @@ | ||
function onIdChange(installations, callback) { | ||
var appConfig = installations.appConfig; | ||
const { appConfig } = installations; | ||
addCallback(appConfig, callback); | ||
return function () { | ||
return () => { | ||
removeCallback(appConfig, callback); | ||
@@ -1349,5 +1092,4 @@ }; | ||
*/ | ||
function getInstallations(app$1) { | ||
if (app$1 === void 0) { app$1 = app.getApp(); } | ||
var installationsImpl = app._getProvider(app$1, 'installations').getImmediate(); | ||
function getInstallations(app$1 = app.getApp()) { | ||
const installationsImpl = app._getProvider(app$1, 'installations').getImmediate(); | ||
return installationsImpl; | ||
@@ -1373,3 +1115,2 @@ } | ||
function extractAppConfig(app) { | ||
var e_1, _a; | ||
if (!app || !app.options) { | ||
@@ -1382,3 +1123,3 @@ throw getMissingValueError('App Configuration'); | ||
// Required app config keys | ||
var configKeys = [ | ||
const configKeys = [ | ||
'projectId', | ||
@@ -1388,17 +1129,7 @@ 'apiKey', | ||
]; | ||
try { | ||
for (var configKeys_1 = tslib.__values(configKeys), configKeys_1_1 = configKeys_1.next(); !configKeys_1_1.done; configKeys_1_1 = configKeys_1.next()) { | ||
var keyName = configKeys_1_1.value; | ||
if (!app.options[keyName]) { | ||
throw getMissingValueError(keyName); | ||
} | ||
for (const keyName of configKeys) { | ||
if (!app.options[keyName]) { | ||
throw getMissingValueError(keyName); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (configKeys_1_1 && !configKeys_1_1.done && (_a = configKeys_1.return)) _a.call(configKeys_1); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
return { | ||
@@ -1413,3 +1144,3 @@ appName: app.name, | ||
return ERROR_FACTORY.create("missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */, { | ||
valueName: valueName | ||
valueName | ||
}); | ||
@@ -1434,24 +1165,24 @@ } | ||
*/ | ||
var INSTALLATIONS_NAME = 'installations'; | ||
var INSTALLATIONS_NAME_INTERNAL = 'installations-internal'; | ||
var publicFactory = function (container) { | ||
var app$1 = container.getProvider('app').getImmediate(); | ||
const INSTALLATIONS_NAME = 'installations'; | ||
const INSTALLATIONS_NAME_INTERNAL = 'installations-internal'; | ||
const publicFactory = (container) => { | ||
const app$1 = container.getProvider('app').getImmediate(); | ||
// Throws if app isn't configured properly. | ||
var appConfig = extractAppConfig(app$1); | ||
var heartbeatServiceProvider = app._getProvider(app$1, 'heartbeat'); | ||
var installationsImpl = { | ||
const appConfig = extractAppConfig(app$1); | ||
const heartbeatServiceProvider = app._getProvider(app$1, 'heartbeat'); | ||
const installationsImpl = { | ||
app: app$1, | ||
appConfig: appConfig, | ||
heartbeatServiceProvider: heartbeatServiceProvider, | ||
_delete: function () { return Promise.resolve(); } | ||
appConfig, | ||
heartbeatServiceProvider, | ||
_delete: () => Promise.resolve() | ||
}; | ||
return installationsImpl; | ||
}; | ||
var internalFactory = function (container) { | ||
var app$1 = container.getProvider('app').getImmediate(); | ||
const internalFactory = (container) => { | ||
const app$1 = container.getProvider('app').getImmediate(); | ||
// Internal FIS instance relies on public FIS instance. | ||
var installations = app._getProvider(app$1, INSTALLATIONS_NAME).getImmediate(); | ||
var installationsInternal = { | ||
getId: function () { return getId(installations); }, | ||
getToken: function (forceRefresh) { return getToken(installations, forceRefresh); } | ||
const installations = app._getProvider(app$1, INSTALLATIONS_NAME).getImmediate(); | ||
const installationsInternal = { | ||
getId: () => getId(installations), | ||
getToken: (forceRefresh) => getToken(installations, forceRefresh) | ||
}; | ||
@@ -1473,4 +1204,4 @@ return installationsInternal; | ||
app.registerVersion(name, version); | ||
// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation | ||
app.registerVersion(name, version, 'cjs5'); | ||
// BUILD_TARGET will be replaced by values like esm2017, cjs2017, etc during the compilation | ||
app.registerVersion(name, version, 'cjs2017'); | ||
@@ -1477,0 +1208,0 @@ exports.deleteInstallations = deleteInstallations; |
{ | ||
"name": "@firebase/installations", | ||
"version": "0.6.9-canary.2e2804139", | ||
"version": "0.6.9-canary.479226bf3", | ||
"author": "Firebase <firebase-support@google.com> (https://firebase.google.com/)", | ||
@@ -8,3 +8,2 @@ "main": "dist/index.cjs.js", | ||
"browser": "dist/esm/index.esm2017.js", | ||
"esm5": "dist/esm/index.esm.js", | ||
"exports": { | ||
@@ -14,3 +13,2 @@ ".": { | ||
"require": "./dist/index.cjs.js", | ||
"esm5": "./dist/esm/index.esm.js", | ||
"default": "./dist/esm/index.esm2017.js" | ||
@@ -56,3 +54,3 @@ }, | ||
"devDependencies": { | ||
"@firebase/app": "0.10.13-canary.2e2804139", | ||
"@firebase/app": "0.10.13-canary.479226bf3", | ||
"rollup": "2.79.1", | ||
@@ -67,7 +65,7 @@ "@rollup/plugin-commonjs": "21.1.0", | ||
"peerDependencies": { | ||
"@firebase/app": "0.10.13-canary.2e2804139" | ||
"@firebase/app": "0.10.13-canary.479226bf3" | ||
}, | ||
"dependencies": { | ||
"@firebase/util": "1.10.0-canary.2e2804139", | ||
"@firebase/component": "0.6.9-canary.2e2804139", | ||
"@firebase/util": "1.10.0-canary.479226bf3", | ||
"@firebase/component": "0.6.9-canary.479226bf3", | ||
"idb": "7.1.1", | ||
@@ -74,0 +72,0 @@ "tslib": "^2.1.0" |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
2
6
342698
103
4640
+ Added@firebase/app@0.10.13-canary.479226bf3(transitive)
+ Added@firebase/component@0.6.9-canary.479226bf3(transitive)
+ Added@firebase/logger@0.4.2-canary.479226bf3(transitive)
+ Added@firebase/util@1.10.0-canary.479226bf3(transitive)
- Removed@firebase/app@0.10.13-canary.2e2804139(transitive)
- Removed@firebase/component@0.6.9-canary.2e2804139(transitive)
- Removed@firebase/logger@0.4.2-canary.2e2804139(transitive)
- Removed@firebase/util@1.10.0-canary.2e2804139(transitive)