GSI - Employe Self Service Mobile
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1093 lines
41 KiB

2 months ago
  1. import { Component, ComponentContainer } from '@firebase/component';
  2. import { __values, __assign, __awaiter, __generator, __spreadArray, __read } from 'tslib';
  3. import { Logger, setUserLogHandler, setLogLevel as setLogLevel$1 } from '@firebase/logger';
  4. import { ErrorFactory, getDefaultAppConfig, deepEqual, FirebaseError, base64urlEncodeWithoutPadding, isIndexedDBAvailable, validateIndexedDBOpenable } from '@firebase/util';
  5. export { FirebaseError } from '@firebase/util';
  6. import { openDB } from 'idb';
  7. /**
  8. * @license
  9. * Copyright 2019 Google LLC
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. */
  23. var PlatformLoggerServiceImpl = /** @class */ (function () {
  24. function PlatformLoggerServiceImpl(container) {
  25. this.container = container;
  26. }
  27. // In initial implementation, this will be called by installations on
  28. // auth token refresh, and installations will send this string.
  29. PlatformLoggerServiceImpl.prototype.getPlatformInfoString = function () {
  30. var providers = this.container.getProviders();
  31. // Loop through providers and get library/version pairs from any that are
  32. // version components.
  33. return providers
  34. .map(function (provider) {
  35. if (isVersionServiceProvider(provider)) {
  36. var service = provider.getImmediate();
  37. return "".concat(service.library, "/").concat(service.version);
  38. }
  39. else {
  40. return null;
  41. }
  42. })
  43. .filter(function (logString) { return logString; })
  44. .join(' ');
  45. };
  46. return PlatformLoggerServiceImpl;
  47. }());
  48. /**
  49. *
  50. * @param provider check if this provider provides a VersionService
  51. *
  52. * NOTE: Using Provider<'app-version'> is a hack to indicate that the provider
  53. * provides VersionService. The provider is not necessarily a 'app-version'
  54. * provider.
  55. */
  56. function isVersionServiceProvider(provider) {
  57. var component = provider.getComponent();
  58. return (component === null || component === void 0 ? void 0 : component.type) === "VERSION" /* ComponentType.VERSION */;
  59. }
  60. var name$o = "@firebase/app";
  61. var version$1 = "0.9.1";
  62. /**
  63. * @license
  64. * Copyright 2019 Google LLC
  65. *
  66. * Licensed under the Apache License, Version 2.0 (the "License");
  67. * you may not use this file except in compliance with the License.
  68. * You may obtain a copy of the License at
  69. *
  70. * http://www.apache.org/licenses/LICENSE-2.0
  71. *
  72. * Unless required by applicable law or agreed to in writing, software
  73. * distributed under the License is distributed on an "AS IS" BASIS,
  74. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  75. * See the License for the specific language governing permissions and
  76. * limitations under the License.
  77. */
  78. var logger = new Logger('@firebase/app');
  79. var name$n = "@firebase/app-compat";
  80. var name$m = "@firebase/analytics-compat";
  81. var name$l = "@firebase/analytics";
  82. var name$k = "@firebase/app-check-compat";
  83. var name$j = "@firebase/app-check";
  84. var name$i = "@firebase/auth";
  85. var name$h = "@firebase/auth-compat";
  86. var name$g = "@firebase/database";
  87. var name$f = "@firebase/database-compat";
  88. var name$e = "@firebase/functions";
  89. var name$d = "@firebase/functions-compat";
  90. var name$c = "@firebase/installations";
  91. var name$b = "@firebase/installations-compat";
  92. var name$a = "@firebase/messaging";
  93. var name$9 = "@firebase/messaging-compat";
  94. var name$8 = "@firebase/performance";
  95. var name$7 = "@firebase/performance-compat";
  96. var name$6 = "@firebase/remote-config";
  97. var name$5 = "@firebase/remote-config-compat";
  98. var name$4 = "@firebase/storage";
  99. var name$3 = "@firebase/storage-compat";
  100. var name$2 = "@firebase/firestore";
  101. var name$1 = "@firebase/firestore-compat";
  102. var name = "firebase";
  103. var version = "9.16.0";
  104. /**
  105. * @license
  106. * Copyright 2019 Google LLC
  107. *
  108. * Licensed under the Apache License, Version 2.0 (the "License");
  109. * you may not use this file except in compliance with the License.
  110. * You may obtain a copy of the License at
  111. *
  112. * http://www.apache.org/licenses/LICENSE-2.0
  113. *
  114. * Unless required by applicable law or agreed to in writing, software
  115. * distributed under the License is distributed on an "AS IS" BASIS,
  116. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  117. * See the License for the specific language governing permissions and
  118. * limitations under the License.
  119. */
  120. var _a$1;
  121. /**
  122. * The default app name
  123. *
  124. * @internal
  125. */
  126. var DEFAULT_ENTRY_NAME = '[DEFAULT]';
  127. var PLATFORM_LOG_STRING = (_a$1 = {},
  128. _a$1[name$o] = 'fire-core',
  129. _a$1[name$n] = 'fire-core-compat',
  130. _a$1[name$l] = 'fire-analytics',
  131. _a$1[name$m] = 'fire-analytics-compat',
  132. _a$1[name$j] = 'fire-app-check',
  133. _a$1[name$k] = 'fire-app-check-compat',
  134. _a$1[name$i] = 'fire-auth',
  135. _a$1[name$h] = 'fire-auth-compat',
  136. _a$1[name$g] = 'fire-rtdb',
  137. _a$1[name$f] = 'fire-rtdb-compat',
  138. _a$1[name$e] = 'fire-fn',
  139. _a$1[name$d] = 'fire-fn-compat',
  140. _a$1[name$c] = 'fire-iid',
  141. _a$1[name$b] = 'fire-iid-compat',
  142. _a$1[name$a] = 'fire-fcm',
  143. _a$1[name$9] = 'fire-fcm-compat',
  144. _a$1[name$8] = 'fire-perf',
  145. _a$1[name$7] = 'fire-perf-compat',
  146. _a$1[name$6] = 'fire-rc',
  147. _a$1[name$5] = 'fire-rc-compat',
  148. _a$1[name$4] = 'fire-gcs',
  149. _a$1[name$3] = 'fire-gcs-compat',
  150. _a$1[name$2] = 'fire-fst',
  151. _a$1[name$1] = 'fire-fst-compat',
  152. _a$1['fire-js'] = 'fire-js',
  153. _a$1[name] = 'fire-js-all',
  154. _a$1);
  155. /**
  156. * @license
  157. * Copyright 2019 Google LLC
  158. *
  159. * Licensed under the Apache License, Version 2.0 (the "License");
  160. * you may not use this file except in compliance with the License.
  161. * You may obtain a copy of the License at
  162. *
  163. * http://www.apache.org/licenses/LICENSE-2.0
  164. *
  165. * Unless required by applicable law or agreed to in writing, software
  166. * distributed under the License is distributed on an "AS IS" BASIS,
  167. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  168. * See the License for the specific language governing permissions and
  169. * limitations under the License.
  170. */
  171. /**
  172. * @internal
  173. */
  174. var _apps = new Map();
  175. /**
  176. * Registered components.
  177. *
  178. * @internal
  179. */
  180. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  181. var _components = new Map();
  182. /**
  183. * @param component - the component being added to this app's container
  184. *
  185. * @internal
  186. */
  187. function _addComponent(app, component) {
  188. try {
  189. app.container.addComponent(component);
  190. }
  191. catch (e) {
  192. logger.debug("Component ".concat(component.name, " failed to register with FirebaseApp ").concat(app.name), e);
  193. }
  194. }
  195. /**
  196. *
  197. * @internal
  198. */
  199. function _addOrOverwriteComponent(app, component) {
  200. app.container.addOrOverwriteComponent(component);
  201. }
  202. /**
  203. *
  204. * @param component - the component to register
  205. * @returns whether or not the component is registered successfully
  206. *
  207. * @internal
  208. */
  209. function _registerComponent(component) {
  210. var e_1, _a;
  211. var componentName = component.name;
  212. if (_components.has(componentName)) {
  213. logger.debug("There were multiple attempts to register component ".concat(componentName, "."));
  214. return false;
  215. }
  216. _components.set(componentName, component);
  217. try {
  218. // add the component to existing app instances
  219. for (var _b = __values(_apps.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
  220. var app = _c.value;
  221. _addComponent(app, component);
  222. }
  223. }
  224. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  225. finally {
  226. try {
  227. if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
  228. }
  229. finally { if (e_1) throw e_1.error; }
  230. }
  231. return true;
  232. }
  233. /**
  234. *
  235. * @param app - FirebaseApp instance
  236. * @param name - service name
  237. *
  238. * @returns the provider for the service with the matching name
  239. *
  240. * @internal
  241. */
  242. function _getProvider(app, name) {
  243. var heartbeatController = app.container
  244. .getProvider('heartbeat')
  245. .getImmediate({ optional: true });
  246. if (heartbeatController) {
  247. void heartbeatController.triggerHeartbeat();
  248. }
  249. return app.container.getProvider(name);
  250. }
  251. /**
  252. *
  253. * @param app - FirebaseApp instance
  254. * @param name - service name
  255. * @param instanceIdentifier - service instance identifier in case the service supports multiple instances
  256. *
  257. * @internal
  258. */
  259. function _removeServiceInstance(app, name, instanceIdentifier) {
  260. if (instanceIdentifier === void 0) { instanceIdentifier = DEFAULT_ENTRY_NAME; }
  261. _getProvider(app, name).clearInstance(instanceIdentifier);
  262. }
  263. /**
  264. * Test only
  265. *
  266. * @internal
  267. */
  268. function _clearComponents() {
  269. _components.clear();
  270. }
  271. /**
  272. * @license
  273. * Copyright 2019 Google LLC
  274. *
  275. * Licensed under the Apache License, Version 2.0 (the "License");
  276. * you may not use this file except in compliance with the License.
  277. * You may obtain a copy of the License at
  278. *
  279. * http://www.apache.org/licenses/LICENSE-2.0
  280. *
  281. * Unless required by applicable law or agreed to in writing, software
  282. * distributed under the License is distributed on an "AS IS" BASIS,
  283. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  284. * See the License for the specific language governing permissions and
  285. * limitations under the License.
  286. */
  287. var _a;
  288. var ERRORS = (_a = {},
  289. _a["no-app" /* AppError.NO_APP */] = "No Firebase App '{$appName}' has been created - " +
  290. 'call Firebase App.initializeApp()',
  291. _a["bad-app-name" /* AppError.BAD_APP_NAME */] = "Illegal App name: '{$appName}",
  292. _a["duplicate-app" /* AppError.DUPLICATE_APP */] = "Firebase App named '{$appName}' already exists with different options or config",
  293. _a["app-deleted" /* AppError.APP_DELETED */] = "Firebase App named '{$appName}' already deleted",
  294. _a["no-options" /* AppError.NO_OPTIONS */] = 'Need to provide options, when not being deployed to hosting via source.',
  295. _a["invalid-app-argument" /* AppError.INVALID_APP_ARGUMENT */] = 'firebase.{$appName}() takes either no argument or a ' +
  296. 'Firebase App instance.',
  297. _a["invalid-log-argument" /* AppError.INVALID_LOG_ARGUMENT */] = 'First argument to `onLog` must be null or a function.',
  298. _a["idb-open" /* AppError.IDB_OPEN */] = 'Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.',
  299. _a["idb-get" /* AppError.IDB_GET */] = 'Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.',
  300. _a["idb-set" /* AppError.IDB_WRITE */] = 'Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.',
  301. _a["idb-delete" /* AppError.IDB_DELETE */] = 'Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.',
  302. _a);
  303. var ERROR_FACTORY = new ErrorFactory('app', 'Firebase', ERRORS);
  304. /**
  305. * @license
  306. * Copyright 2019 Google LLC
  307. *
  308. * Licensed under the Apache License, Version 2.0 (the "License");
  309. * you may not use this file except in compliance with the License.
  310. * You may obtain a copy of the License at
  311. *
  312. * http://www.apache.org/licenses/LICENSE-2.0
  313. *
  314. * Unless required by applicable law or agreed to in writing, software
  315. * distributed under the License is distributed on an "AS IS" BASIS,
  316. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  317. * See the License for the specific language governing permissions and
  318. * limitations under the License.
  319. */
  320. var FirebaseAppImpl = /** @class */ (function () {
  321. function FirebaseAppImpl(options, config, container) {
  322. var _this = this;
  323. this._isDeleted = false;
  324. this._options = __assign({}, options);
  325. this._config = __assign({}, config);
  326. this._name = config.name;
  327. this._automaticDataCollectionEnabled =
  328. config.automaticDataCollectionEnabled;
  329. this._container = container;
  330. this.container.addComponent(new Component('app', function () { return _this; }, "PUBLIC" /* ComponentType.PUBLIC */));
  331. }
  332. Object.defineProperty(FirebaseAppImpl.prototype, "automaticDataCollectionEnabled", {
  333. get: function () {
  334. this.checkDestroyed();
  335. return this._automaticDataCollectionEnabled;
  336. },
  337. set: function (val) {
  338. this.checkDestroyed();
  339. this._automaticDataCollectionEnabled = val;
  340. },
  341. enumerable: false,
  342. configurable: true
  343. });
  344. Object.defineProperty(FirebaseAppImpl.prototype, "name", {
  345. get: function () {
  346. this.checkDestroyed();
  347. return this._name;
  348. },
  349. enumerable: false,
  350. configurable: true
  351. });
  352. Object.defineProperty(FirebaseAppImpl.prototype, "options", {
  353. get: function () {
  354. this.checkDestroyed();
  355. return this._options;
  356. },
  357. enumerable: false,
  358. configurable: true
  359. });
  360. Object.defineProperty(FirebaseAppImpl.prototype, "config", {
  361. get: function () {
  362. this.checkDestroyed();
  363. return this._config;
  364. },
  365. enumerable: false,
  366. configurable: true
  367. });
  368. Object.defineProperty(FirebaseAppImpl.prototype, "container", {
  369. get: function () {
  370. return this._container;
  371. },
  372. enumerable: false,
  373. configurable: true
  374. });
  375. Object.defineProperty(FirebaseAppImpl.prototype, "isDeleted", {
  376. get: function () {
  377. return this._isDeleted;
  378. },
  379. set: function (val) {
  380. this._isDeleted = val;
  381. },
  382. enumerable: false,
  383. configurable: true
  384. });
  385. /**
  386. * This function will throw an Error if the App has already been deleted -
  387. * use before performing API actions on the App.
  388. */
  389. FirebaseAppImpl.prototype.checkDestroyed = function () {
  390. if (this.isDeleted) {
  391. throw ERROR_FACTORY.create("app-deleted" /* AppError.APP_DELETED */, { appName: this._name });
  392. }
  393. };
  394. return FirebaseAppImpl;
  395. }());
  396. /**
  397. * @license
  398. * Copyright 2019 Google LLC
  399. *
  400. * Licensed under the Apache License, Version 2.0 (the "License");
  401. * you may not use this file except in compliance with the License.
  402. * You may obtain a copy of the License at
  403. *
  404. * http://www.apache.org/licenses/LICENSE-2.0
  405. *
  406. * Unless required by applicable law or agreed to in writing, software
  407. * distributed under the License is distributed on an "AS IS" BASIS,
  408. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  409. * See the License for the specific language governing permissions and
  410. * limitations under the License.
  411. */
  412. /**
  413. * The current SDK version.
  414. *
  415. * @public
  416. */
  417. var SDK_VERSION = version;
  418. function initializeApp(_options, rawConfig) {
  419. var e_1, _a;
  420. if (rawConfig === void 0) { rawConfig = {}; }
  421. var options = _options;
  422. if (typeof rawConfig !== 'object') {
  423. var name_1 = rawConfig;
  424. rawConfig = { name: name_1 };
  425. }
  426. var config = __assign({ name: DEFAULT_ENTRY_NAME, automaticDataCollectionEnabled: false }, rawConfig);
  427. var name = config.name;
  428. if (typeof name !== 'string' || !name) {
  429. throw ERROR_FACTORY.create("bad-app-name" /* AppError.BAD_APP_NAME */, {
  430. appName: String(name)
  431. });
  432. }
  433. options || (options = getDefaultAppConfig());
  434. if (!options) {
  435. throw ERROR_FACTORY.create("no-options" /* AppError.NO_OPTIONS */);
  436. }
  437. var existingApp = _apps.get(name);
  438. if (existingApp) {
  439. // return the existing app if options and config deep equal the ones in the existing app.
  440. if (deepEqual(options, existingApp.options) &&
  441. deepEqual(config, existingApp.config)) {
  442. return existingApp;
  443. }
  444. else {
  445. throw ERROR_FACTORY.create("duplicate-app" /* AppError.DUPLICATE_APP */, { appName: name });
  446. }
  447. }
  448. var container = new ComponentContainer(name);
  449. try {
  450. for (var _b = __values(_components.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
  451. var component = _c.value;
  452. container.addComponent(component);
  453. }
  454. }
  455. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  456. finally {
  457. try {
  458. if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
  459. }
  460. finally { if (e_1) throw e_1.error; }
  461. }
  462. var newApp = new FirebaseAppImpl(options, config, container);
  463. _apps.set(name, newApp);
  464. return newApp;
  465. }
  466. /**
  467. * Retrieves a {@link @firebase/app#FirebaseApp} instance.
  468. *
  469. * When called with no arguments, the default app is returned. When an app name
  470. * is provided, the app corresponding to that name is returned.
  471. *
  472. * An exception is thrown if the app being retrieved has not yet been
  473. * initialized.
  474. *
  475. * @example
  476. * ```javascript
  477. * // Return the default app
  478. * const app = getApp();
  479. * ```
  480. *
  481. * @example
  482. * ```javascript
  483. * // Return a named app
  484. * const otherApp = getApp("otherApp");
  485. * ```
  486. *
  487. * @param name - Optional name of the app to return. If no name is
  488. * provided, the default is `"[DEFAULT]"`.
  489. *
  490. * @returns The app corresponding to the provided app name.
  491. * If no app name is provided, the default app is returned.
  492. *
  493. * @public
  494. */
  495. function getApp(name) {
  496. if (name === void 0) { name = DEFAULT_ENTRY_NAME; }
  497. var app = _apps.get(name);
  498. if (!app && name === DEFAULT_ENTRY_NAME) {
  499. return initializeApp();
  500. }
  501. if (!app) {
  502. throw ERROR_FACTORY.create("no-app" /* AppError.NO_APP */, { appName: name });
  503. }
  504. return app;
  505. }
  506. /**
  507. * A (read-only) array of all initialized apps.
  508. * @public
  509. */
  510. function getApps() {
  511. return Array.from(_apps.values());
  512. }
  513. /**
  514. * Renders this app unusable and frees the resources of all associated
  515. * services.
  516. *
  517. * @example
  518. * ```javascript
  519. * deleteApp(app)
  520. * .then(function() {
  521. * console.log("App deleted successfully");
  522. * })
  523. * .catch(function(error) {
  524. * console.log("Error deleting app:", error);
  525. * });
  526. * ```
  527. *
  528. * @public
  529. */
  530. function deleteApp(app) {
  531. return __awaiter(this, void 0, void 0, function () {
  532. var name;
  533. return __generator(this, function (_a) {
  534. switch (_a.label) {
  535. case 0:
  536. name = app.name;
  537. if (!_apps.has(name)) return [3 /*break*/, 2];
  538. _apps.delete(name);
  539. return [4 /*yield*/, Promise.all(app.container
  540. .getProviders()
  541. .map(function (provider) { return provider.delete(); }))];
  542. case 1:
  543. _a.sent();
  544. app.isDeleted = true;
  545. _a.label = 2;
  546. case 2: return [2 /*return*/];
  547. }
  548. });
  549. });
  550. }
  551. /**
  552. * Registers a library's name and version for platform logging purposes.
  553. * @param library - Name of 1p or 3p library (e.g. firestore, angularfire)
  554. * @param version - Current version of that library.
  555. * @param variant - Bundle variant, e.g., node, rn, etc.
  556. *
  557. * @public
  558. */
  559. function registerVersion(libraryKeyOrName, version, variant) {
  560. var _a;
  561. // TODO: We can use this check to whitelist strings when/if we set up
  562. // a good whitelist system.
  563. var library = (_a = PLATFORM_LOG_STRING[libraryKeyOrName]) !== null && _a !== void 0 ? _a : libraryKeyOrName;
  564. if (variant) {
  565. library += "-".concat(variant);
  566. }
  567. var libraryMismatch = library.match(/\s|\//);
  568. var versionMismatch = version.match(/\s|\//);
  569. if (libraryMismatch || versionMismatch) {
  570. var warning = [
  571. "Unable to register library \"".concat(library, "\" with version \"").concat(version, "\":")
  572. ];
  573. if (libraryMismatch) {
  574. warning.push("library name \"".concat(library, "\" contains illegal characters (whitespace or \"/\")"));
  575. }
  576. if (libraryMismatch && versionMismatch) {
  577. warning.push('and');
  578. }
  579. if (versionMismatch) {
  580. warning.push("version name \"".concat(version, "\" contains illegal characters (whitespace or \"/\")"));
  581. }
  582. logger.warn(warning.join(' '));
  583. return;
  584. }
  585. _registerComponent(new Component("".concat(library, "-version"), function () { return ({ library: library, version: version }); }, "VERSION" /* ComponentType.VERSION */));
  586. }
  587. /**
  588. * Sets log handler for all Firebase SDKs.
  589. * @param logCallback - An optional custom log handler that executes user code whenever
  590. * the Firebase SDK makes a logging call.
  591. *
  592. * @public
  593. */
  594. function onLog(logCallback, options) {
  595. if (logCallback !== null && typeof logCallback !== 'function') {
  596. throw ERROR_FACTORY.create("invalid-log-argument" /* AppError.INVALID_LOG_ARGUMENT */);
  597. }
  598. setUserLogHandler(logCallback, options);
  599. }
  600. /**
  601. * Sets log level for all Firebase SDKs.
  602. *
  603. * All of the log types above the current log level are captured (i.e. if
  604. * you set the log level to `info`, errors are logged, but `debug` and
  605. * `verbose` logs are not).
  606. *
  607. * @public
  608. */
  609. function setLogLevel(logLevel) {
  610. setLogLevel$1(logLevel);
  611. }
  612. /**
  613. * @license
  614. * Copyright 2021 Google LLC
  615. *
  616. * Licensed under the Apache License, Version 2.0 (the "License");
  617. * you may not use this file except in compliance with the License.
  618. * You may obtain a copy of the License at
  619. *
  620. * http://www.apache.org/licenses/LICENSE-2.0
  621. *
  622. * Unless required by applicable law or agreed to in writing, software
  623. * distributed under the License is distributed on an "AS IS" BASIS,
  624. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  625. * See the License for the specific language governing permissions and
  626. * limitations under the License.
  627. */
  628. var DB_NAME = 'firebase-heartbeat-database';
  629. var DB_VERSION = 1;
  630. var STORE_NAME = 'firebase-heartbeat-store';
  631. var dbPromise = null;
  632. function getDbPromise() {
  633. if (!dbPromise) {
  634. dbPromise = openDB(DB_NAME, DB_VERSION, {
  635. upgrade: function (db, oldVersion) {
  636. // We don't use 'break' in this switch statement, the fall-through
  637. // behavior is what we want, because if there are multiple versions between
  638. // the old version and the current version, we want ALL the migrations
  639. // that correspond to those versions to run, not only the last one.
  640. // eslint-disable-next-line default-case
  641. switch (oldVersion) {
  642. case 0:
  643. db.createObjectStore(STORE_NAME);
  644. }
  645. }
  646. }).catch(function (e) {
  647. throw ERROR_FACTORY.create("idb-open" /* AppError.IDB_OPEN */, {
  648. originalErrorMessage: e.message
  649. });
  650. });
  651. }
  652. return dbPromise;
  653. }
  654. function readHeartbeatsFromIndexedDB(app) {
  655. return __awaiter(this, void 0, void 0, function () {
  656. var db, e_1, idbGetError;
  657. return __generator(this, function (_a) {
  658. switch (_a.label) {
  659. case 0:
  660. _a.trys.push([0, 2, , 3]);
  661. return [4 /*yield*/, getDbPromise()];
  662. case 1:
  663. db = _a.sent();
  664. return [2 /*return*/, db
  665. .transaction(STORE_NAME)
  666. .objectStore(STORE_NAME)
  667. .get(computeKey(app))];
  668. case 2:
  669. e_1 = _a.sent();
  670. if (e_1 instanceof FirebaseError) {
  671. logger.warn(e_1.message);
  672. }
  673. else {
  674. idbGetError = ERROR_FACTORY.create("idb-get" /* AppError.IDB_GET */, {
  675. originalErrorMessage: e_1 === null || e_1 === void 0 ? void 0 : e_1.message
  676. });
  677. logger.warn(idbGetError.message);
  678. }
  679. return [3 /*break*/, 3];
  680. case 3: return [2 /*return*/];
  681. }
  682. });
  683. });
  684. }
  685. function writeHeartbeatsToIndexedDB(app, heartbeatObject) {
  686. return __awaiter(this, void 0, void 0, function () {
  687. var db, tx, objectStore, e_2, idbGetError;
  688. return __generator(this, function (_a) {
  689. switch (_a.label) {
  690. case 0:
  691. _a.trys.push([0, 3, , 4]);
  692. return [4 /*yield*/, getDbPromise()];
  693. case 1:
  694. db = _a.sent();
  695. tx = db.transaction(STORE_NAME, 'readwrite');
  696. objectStore = tx.objectStore(STORE_NAME);
  697. return [4 /*yield*/, objectStore.put(heartbeatObject, computeKey(app))];
  698. case 2:
  699. _a.sent();
  700. return [2 /*return*/, tx.done];
  701. case 3:
  702. e_2 = _a.sent();
  703. if (e_2 instanceof FirebaseError) {
  704. logger.warn(e_2.message);
  705. }
  706. else {
  707. idbGetError = ERROR_FACTORY.create("idb-set" /* AppError.IDB_WRITE */, {
  708. originalErrorMessage: e_2 === null || e_2 === void 0 ? void 0 : e_2.message
  709. });
  710. logger.warn(idbGetError.message);
  711. }
  712. return [3 /*break*/, 4];
  713. case 4: return [2 /*return*/];
  714. }
  715. });
  716. });
  717. }
  718. function computeKey(app) {
  719. return "".concat(app.name, "!").concat(app.options.appId);
  720. }
  721. /**
  722. * @license
  723. * Copyright 2021 Google LLC
  724. *
  725. * Licensed under the Apache License, Version 2.0 (the "License");
  726. * you may not use this file except in compliance with the License.
  727. * You may obtain a copy of the License at
  728. *
  729. * http://www.apache.org/licenses/LICENSE-2.0
  730. *
  731. * Unless required by applicable law or agreed to in writing, software
  732. * distributed under the License is distributed on an "AS IS" BASIS,
  733. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  734. * See the License for the specific language governing permissions and
  735. * limitations under the License.
  736. */
  737. var MAX_HEADER_BYTES = 1024;
  738. // 30 days
  739. var STORED_HEARTBEAT_RETENTION_MAX_MILLIS = 30 * 24 * 60 * 60 * 1000;
  740. var HeartbeatServiceImpl = /** @class */ (function () {
  741. function HeartbeatServiceImpl(container) {
  742. var _this = this;
  743. this.container = container;
  744. /**
  745. * In-memory cache for heartbeats, used by getHeartbeatsHeader() to generate
  746. * the header string.
  747. * Stores one record per date. This will be consolidated into the standard
  748. * format of one record per user agent string before being sent as a header.
  749. * Populated from indexedDB when the controller is instantiated and should
  750. * be kept in sync with indexedDB.
  751. * Leave public for easier testing.
  752. */
  753. this._heartbeatsCache = null;
  754. var app = this.container.getProvider('app').getImmediate();
  755. this._storage = new HeartbeatStorageImpl(app);
  756. this._heartbeatsCachePromise = this._storage.read().then(function (result) {
  757. _this._heartbeatsCache = result;
  758. return result;
  759. });
  760. }
  761. /**
  762. * Called to report a heartbeat. The function will generate
  763. * a HeartbeatsByUserAgent object, update heartbeatsCache, and persist it
  764. * to IndexedDB.
  765. * Note that we only store one heartbeat per day. So if a heartbeat for today is
  766. * already logged, subsequent calls to this function in the same day will be ignored.
  767. */
  768. HeartbeatServiceImpl.prototype.triggerHeartbeat = function () {
  769. return __awaiter(this, void 0, void 0, function () {
  770. var platformLogger, agent, date, _a;
  771. return __generator(this, function (_b) {
  772. switch (_b.label) {
  773. case 0:
  774. platformLogger = this.container
  775. .getProvider('platform-logger')
  776. .getImmediate();
  777. agent = platformLogger.getPlatformInfoString();
  778. date = getUTCDateString();
  779. if (!(this._heartbeatsCache === null)) return [3 /*break*/, 2];
  780. _a = this;
  781. return [4 /*yield*/, this._heartbeatsCachePromise];
  782. case 1:
  783. _a._heartbeatsCache = _b.sent();
  784. _b.label = 2;
  785. case 2:
  786. // Do not store a heartbeat if one is already stored for this day
  787. // or if a header has already been sent today.
  788. if (this._heartbeatsCache.lastSentHeartbeatDate === date ||
  789. this._heartbeatsCache.heartbeats.some(function (singleDateHeartbeat) { return singleDateHeartbeat.date === date; })) {
  790. return [2 /*return*/];
  791. }
  792. else {
  793. // There is no entry for this date. Create one.
  794. this._heartbeatsCache.heartbeats.push({ date: date, agent: agent });
  795. }
  796. // Remove entries older than 30 days.
  797. this._heartbeatsCache.heartbeats = this._heartbeatsCache.heartbeats.filter(function (singleDateHeartbeat) {
  798. var hbTimestamp = new Date(singleDateHeartbeat.date).valueOf();
  799. var now = Date.now();
  800. return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS;
  801. });
  802. return [2 /*return*/, this._storage.overwrite(this._heartbeatsCache)];
  803. }
  804. });
  805. });
  806. };
  807. /**
  808. * Returns a base64 encoded string which can be attached to the heartbeat-specific header directly.
  809. * It also clears all heartbeats from memory as well as in IndexedDB.
  810. *
  811. * NOTE: Consuming product SDKs should not send the header if this method
  812. * returns an empty string.
  813. */
  814. HeartbeatServiceImpl.prototype.getHeartbeatsHeader = function () {
  815. return __awaiter(this, void 0, void 0, function () {
  816. var date, _a, heartbeatsToSend, unsentEntries, headerString;
  817. return __generator(this, function (_b) {
  818. switch (_b.label) {
  819. case 0:
  820. if (!(this._heartbeatsCache === null)) return [3 /*break*/, 2];
  821. return [4 /*yield*/, this._heartbeatsCachePromise];
  822. case 1:
  823. _b.sent();
  824. _b.label = 2;
  825. case 2:
  826. // If it's still null or the array is empty, there is no data to send.
  827. if (this._heartbeatsCache === null ||
  828. this._heartbeatsCache.heartbeats.length === 0) {
  829. return [2 /*return*/, ''];
  830. }
  831. date = getUTCDateString();
  832. _a = extractHeartbeatsForHeader(this._heartbeatsCache.heartbeats), heartbeatsToSend = _a.heartbeatsToSend, unsentEntries = _a.unsentEntries;
  833. headerString = base64urlEncodeWithoutPadding(JSON.stringify({ version: 2, heartbeats: heartbeatsToSend }));
  834. // Store last sent date to prevent another being logged/sent for the same day.
  835. this._heartbeatsCache.lastSentHeartbeatDate = date;
  836. if (!(unsentEntries.length > 0)) return [3 /*break*/, 4];
  837. // Store any unsent entries if they exist.
  838. this._heartbeatsCache.heartbeats = unsentEntries;
  839. // This seems more likely than emptying the array (below) to lead to some odd state
  840. // since the cache isn't empty and this will be called again on the next request,
  841. // and is probably safest if we await it.
  842. return [4 /*yield*/, this._storage.overwrite(this._heartbeatsCache)];
  843. case 3:
  844. // This seems more likely than emptying the array (below) to lead to some odd state
  845. // since the cache isn't empty and this will be called again on the next request,
  846. // and is probably safest if we await it.
  847. _b.sent();
  848. return [3 /*break*/, 5];
  849. case 4:
  850. this._heartbeatsCache.heartbeats = [];
  851. // Do not wait for this, to reduce latency.
  852. void this._storage.overwrite(this._heartbeatsCache);
  853. _b.label = 5;
  854. case 5: return [2 /*return*/, headerString];
  855. }
  856. });
  857. });
  858. };
  859. return HeartbeatServiceImpl;
  860. }());
  861. function getUTCDateString() {
  862. var today = new Date();
  863. // Returns date format 'YYYY-MM-DD'
  864. return today.toISOString().substring(0, 10);
  865. }
  866. function extractHeartbeatsForHeader(heartbeatsCache, maxSize) {
  867. var e_1, _a;
  868. if (maxSize === void 0) { maxSize = MAX_HEADER_BYTES; }
  869. // Heartbeats grouped by user agent in the standard format to be sent in
  870. // the header.
  871. var heartbeatsToSend = [];
  872. // Single date format heartbeats that are not sent.
  873. var unsentEntries = heartbeatsCache.slice();
  874. var _loop_1 = function (singleDateHeartbeat) {
  875. // Look for an existing entry with the same user agent.
  876. var heartbeatEntry = heartbeatsToSend.find(function (hb) { return hb.agent === singleDateHeartbeat.agent; });
  877. if (!heartbeatEntry) {
  878. // If no entry for this user agent exists, create one.
  879. heartbeatsToSend.push({
  880. agent: singleDateHeartbeat.agent,
  881. dates: [singleDateHeartbeat.date]
  882. });
  883. if (countBytes(heartbeatsToSend) > maxSize) {
  884. // If the header would exceed max size, remove the added heartbeat
  885. // entry and stop adding to the header.
  886. heartbeatsToSend.pop();
  887. return "break";
  888. }
  889. }
  890. else {
  891. heartbeatEntry.dates.push(singleDateHeartbeat.date);
  892. // If the header would exceed max size, remove the added date
  893. // and stop adding to the header.
  894. if (countBytes(heartbeatsToSend) > maxSize) {
  895. heartbeatEntry.dates.pop();
  896. return "break";
  897. }
  898. }
  899. // Pop unsent entry from queue. (Skipped if adding the entry exceeded
  900. // quota and the loop breaks early.)
  901. unsentEntries = unsentEntries.slice(1);
  902. };
  903. try {
  904. for (var heartbeatsCache_1 = __values(heartbeatsCache), heartbeatsCache_1_1 = heartbeatsCache_1.next(); !heartbeatsCache_1_1.done; heartbeatsCache_1_1 = heartbeatsCache_1.next()) {
  905. var singleDateHeartbeat = heartbeatsCache_1_1.value;
  906. var state_1 = _loop_1(singleDateHeartbeat);
  907. if (state_1 === "break")
  908. break;
  909. }
  910. }
  911. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  912. finally {
  913. try {
  914. if (heartbeatsCache_1_1 && !heartbeatsCache_1_1.done && (_a = heartbeatsCache_1.return)) _a.call(heartbeatsCache_1);
  915. }
  916. finally { if (e_1) throw e_1.error; }
  917. }
  918. return {
  919. heartbeatsToSend: heartbeatsToSend,
  920. unsentEntries: unsentEntries
  921. };
  922. }
  923. var HeartbeatStorageImpl = /** @class */ (function () {
  924. function HeartbeatStorageImpl(app) {
  925. this.app = app;
  926. this._canUseIndexedDBPromise = this.runIndexedDBEnvironmentCheck();
  927. }
  928. HeartbeatStorageImpl.prototype.runIndexedDBEnvironmentCheck = function () {
  929. return __awaiter(this, void 0, void 0, function () {
  930. return __generator(this, function (_a) {
  931. if (!isIndexedDBAvailable()) {
  932. return [2 /*return*/, false];
  933. }
  934. else {
  935. return [2 /*return*/, validateIndexedDBOpenable()
  936. .then(function () { return true; })
  937. .catch(function () { return false; })];
  938. }
  939. });
  940. });
  941. };
  942. /**
  943. * Read all heartbeats.
  944. */
  945. HeartbeatStorageImpl.prototype.read = function () {
  946. return __awaiter(this, void 0, void 0, function () {
  947. var canUseIndexedDB, idbHeartbeatObject;
  948. return __generator(this, function (_a) {
  949. switch (_a.label) {
  950. case 0: return [4 /*yield*/, this._canUseIndexedDBPromise];
  951. case 1:
  952. canUseIndexedDB = _a.sent();
  953. if (!!canUseIndexedDB) return [3 /*break*/, 2];
  954. return [2 /*return*/, { heartbeats: [] }];
  955. case 2: return [4 /*yield*/, readHeartbeatsFromIndexedDB(this.app)];
  956. case 3:
  957. idbHeartbeatObject = _a.sent();
  958. return [2 /*return*/, idbHeartbeatObject || { heartbeats: [] }];
  959. }
  960. });
  961. });
  962. };
  963. // overwrite the storage with the provided heartbeats
  964. HeartbeatStorageImpl.prototype.overwrite = function (heartbeatsObject) {
  965. var _a;
  966. return __awaiter(this, void 0, void 0, function () {
  967. var canUseIndexedDB, existingHeartbeatsObject;
  968. return __generator(this, function (_b) {
  969. switch (_b.label) {
  970. case 0: return [4 /*yield*/, this._canUseIndexedDBPromise];
  971. case 1:
  972. canUseIndexedDB = _b.sent();
  973. if (!!canUseIndexedDB) return [3 /*break*/, 2];
  974. return [2 /*return*/];
  975. case 2: return [4 /*yield*/, this.read()];
  976. case 3:
  977. existingHeartbeatsObject = _b.sent();
  978. return [2 /*return*/, writeHeartbeatsToIndexedDB(this.app, {
  979. lastSentHeartbeatDate: (_a = heartbeatsObject.lastSentHeartbeatDate) !== null && _a !== void 0 ? _a : existingHeartbeatsObject.lastSentHeartbeatDate,
  980. heartbeats: heartbeatsObject.heartbeats
  981. })];
  982. }
  983. });
  984. });
  985. };
  986. // add heartbeats
  987. HeartbeatStorageImpl.prototype.add = function (heartbeatsObject) {
  988. var _a;
  989. return __awaiter(this, void 0, void 0, function () {
  990. var canUseIndexedDB, existingHeartbeatsObject;
  991. return __generator(this, function (_b) {
  992. switch (_b.label) {
  993. case 0: return [4 /*yield*/, this._canUseIndexedDBPromise];
  994. case 1:
  995. canUseIndexedDB = _b.sent();
  996. if (!!canUseIndexedDB) return [3 /*break*/, 2];
  997. return [2 /*return*/];
  998. case 2: return [4 /*yield*/, this.read()];
  999. case 3:
  1000. existingHeartbeatsObject = _b.sent();
  1001. return [2 /*return*/, writeHeartbeatsToIndexedDB(this.app, {
  1002. lastSentHeartbeatDate: (_a = heartbeatsObject.lastSentHeartbeatDate) !== null && _a !== void 0 ? _a : existingHeartbeatsObject.lastSentHeartbeatDate,
  1003. heartbeats: __spreadArray(__spreadArray([], __read(existingHeartbeatsObject.heartbeats), false), __read(heartbeatsObject.heartbeats), false)
  1004. })];
  1005. }
  1006. });
  1007. });
  1008. };
  1009. return HeartbeatStorageImpl;
  1010. }());
  1011. /**
  1012. * Calculate bytes of a HeartbeatsByUserAgent array after being wrapped
  1013. * in a platform logging header JSON object, stringified, and converted
  1014. * to base 64.
  1015. */
  1016. function countBytes(heartbeatsCache) {
  1017. // base64 has a restricted set of characters, all of which should be 1 byte.
  1018. return base64urlEncodeWithoutPadding(
  1019. // heartbeatsCache wrapper properties
  1020. JSON.stringify({ version: 2, heartbeats: heartbeatsCache })).length;
  1021. }
  1022. /**
  1023. * @license
  1024. * Copyright 2019 Google LLC
  1025. *
  1026. * Licensed under the Apache License, Version 2.0 (the "License");
  1027. * you may not use this file except in compliance with the License.
  1028. * You may obtain a copy of the License at
  1029. *
  1030. * http://www.apache.org/licenses/LICENSE-2.0
  1031. *
  1032. * Unless required by applicable law or agreed to in writing, software
  1033. * distributed under the License is distributed on an "AS IS" BASIS,
  1034. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1035. * See the License for the specific language governing permissions and
  1036. * limitations under the License.
  1037. */
  1038. function registerCoreComponents(variant) {
  1039. _registerComponent(new Component('platform-logger', function (container) { return new PlatformLoggerServiceImpl(container); }, "PRIVATE" /* ComponentType.PRIVATE */));
  1040. _registerComponent(new Component('heartbeat', function (container) { return new HeartbeatServiceImpl(container); }, "PRIVATE" /* ComponentType.PRIVATE */));
  1041. // Register `app` package.
  1042. registerVersion(name$o, version$1, variant);
  1043. // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
  1044. registerVersion(name$o, version$1, 'esm5');
  1045. // Register platform SDK identifier (no version).
  1046. registerVersion('fire-js', '');
  1047. }
  1048. /**
  1049. * Firebase App
  1050. *
  1051. * @remarks This package coordinates the communication between the different Firebase components
  1052. * @packageDocumentation
  1053. */
  1054. registerCoreComponents('');
  1055. export { SDK_VERSION, DEFAULT_ENTRY_NAME as _DEFAULT_ENTRY_NAME, _addComponent, _addOrOverwriteComponent, _apps, _clearComponents, _components, _getProvider, _registerComponent, _removeServiceInstance, deleteApp, getApp, getApps, initializeApp, onLog, registerVersion, setLogLevel };
  1056. //# sourceMappingURL=index.esm5.js.map