From 4cf1388d68ef7f77b7401e12e9a46e04f8af208e Mon Sep 17 00:00:00 2001 From: dwyfrequency Date: Tue, 21 Feb 2023 20:37:46 -0500 Subject: [PATCH 01/26] Initial fix for Trusted Types failures --- packages/analytics/src/helpers.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/analytics/src/helpers.ts b/packages/analytics/src/helpers.ts index 1fb8a38319c..f940f9e18dd 100644 --- a/packages/analytics/src/helpers.ts +++ b/packages/analytics/src/helpers.ts @@ -28,6 +28,14 @@ import { logger } from './logger'; // Possible parameter types for gtag 'event' and 'config' commands type GtagConfigOrEventParams = ControlParams & EventParams & CustomParams; +// Create a TrustedTypes policy that we use for scripts +let _ttPolicy: Partial; +if (window.trustedTypes) { + _ttPolicy = window.trustedTypes.createPolicy('firebase-js-sdk-policy', { + createScriptURL: (url: string) => url + }); +} + /** * Makeshift polyfill for Promise.allSettled(). Resolves when all promises * have either resolved or rejected. @@ -51,7 +59,12 @@ export function insertScriptTag( const script = document.createElement('script'); // We are not providing an analyticsId in the URL because it would trigger a `page_view` // without fid. We will initialize ga-id using gtag (config) command together with fid. - script.src = `${GTAG_URL}?l=${dataLayerName}&id=${measurementId}`; + + const gtagScriptURL = `${GTAG_URL}?l=${dataLayerName}&id=${measurementId}`; + (script.src as string | TrustedScriptURL) = _ttPolicy + ? (_ttPolicy as TrustedTypePolicy)?.createScriptURL(gtagScriptURL) + : gtagScriptURL; + script.async = true; document.head.appendChild(script); } From 9222f5e92463b63717592e4a8f0b6ede1d3ac567 Mon Sep 17 00:00:00 2001 From: dwyfrequency Date: Wed, 22 Feb 2023 11:50:21 -0500 Subject: [PATCH 02/26] Add Trusted-Types --- package.json | 1 + yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/package.json b/package.json index 66ab898df71..dfb8a595bc5 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "@types/sinon": "9.0.11", "@types/sinon-chai": "3.2.9", "@types/tmp": "0.2.3", + "@types/trusted-types": "2.0.3", "@types/yargs": "17.0.13", "@typescript-eslint/eslint-plugin": "5.43.0", "@typescript-eslint/eslint-plugin-tslint": "5.43.0", diff --git a/yarn.lock b/yarn.lock index bf7b1824e23..1eb35921c1b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3703,6 +3703,11 @@ resolved "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz#8f80dd965ad81f3e1bc26d6f5c727e132721ff40" integrity sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg== +"@types/trusted-types@2.0.3": + version "2.0.3" + resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz#a136f83b0758698df454e328759dbd3d44555311" + integrity sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g== + "@types/vinyl@^2.0.4": version "2.0.6" resolved "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.6.tgz#b2d134603557a7c3d2b5d3dc23863ea2b5eb29b0" From ac387acc1dc66f4e96708656196a81462ffdf4b0 Mon Sep 17 00:00:00 2001 From: dwyfrequency Date: Wed, 22 Feb 2023 18:16:44 -0500 Subject: [PATCH 03/26] Sanitize input --- packages/analytics/src/errors.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/analytics/src/errors.ts b/packages/analytics/src/errors.ts index 98293447c65..eacda193573 100644 --- a/packages/analytics/src/errors.ts +++ b/packages/analytics/src/errors.ts @@ -27,7 +27,8 @@ export const enum AnalyticsError { FETCH_THROTTLE = 'fetch-throttle', CONFIG_FETCH_FAILED = 'config-fetch-failed', NO_API_KEY = 'no-api-key', - NO_APP_ID = 'no-app-id' + NO_APP_ID = 'no-app-id', + INVALID_GTAG_RESOURCE = 'invalid-gtag-resource' } const ERRORS: ErrorMap = { @@ -64,7 +65,9 @@ const ERRORS: ErrorMap = { 'contain a valid API key.', [AnalyticsError.NO_APP_ID]: 'The "appId" field is empty in the local Firebase config. Firebase Analytics requires this field to' + - 'contain a valid app ID.' + 'contain a valid app ID.', + [AnalyticsError.INVALID_GTAG_RESOURCE]: + 'Trusted Types detected an invalid gtag resource: {$gtagURL}.' }; interface ErrorParams { @@ -77,6 +80,7 @@ interface ErrorParams { }; [AnalyticsError.INVALID_ANALYTICS_CONTEXT]: { errorInfo: string }; [AnalyticsError.INDEXEDDB_UNAVAILABLE]: { errorInfo: string }; + [AnalyticsError.INVALID_GTAG_RESOURCE]: { gtagURL: string }; } export const ERROR_FACTORY = new ErrorFactory( From 53781ab4d6385d695537d20ed6227fa3443436e5 Mon Sep 17 00:00:00 2001 From: dwyfrequency Date: Mon, 27 Feb 2023 12:43:21 -0500 Subject: [PATCH 04/26] Add check for gtag url and log error if not found --- packages/analytics/src/helpers.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/analytics/src/helpers.ts b/packages/analytics/src/helpers.ts index f940f9e18dd..4a2b11eff1a 100644 --- a/packages/analytics/src/helpers.ts +++ b/packages/analytics/src/helpers.ts @@ -24,6 +24,7 @@ import { import { DynamicConfig, DataLayer, Gtag, MinimalDynamicConfig } from './types'; import { GtagCommand, GTAG_URL } from './constants'; import { logger } from './logger'; +import { AnalyticsError, ERROR_FACTORY } from './errors'; // Possible parameter types for gtag 'event' and 'config' commands type GtagConfigOrEventParams = ControlParams & EventParams & CustomParams; @@ -32,7 +33,17 @@ type GtagConfigOrEventParams = ControlParams & EventParams & CustomParams; let _ttPolicy: Partial; if (window.trustedTypes) { _ttPolicy = window.trustedTypes.createPolicy('firebase-js-sdk-policy', { - createScriptURL: (url: string) => url + createScriptURL: (url: string) => { + if (!url.startsWith(GTAG_URL)) { + console.error('Unknown gtag resource!', url); + const err = ERROR_FACTORY.create(AnalyticsError.INVALID_GTAG_RESOURCE, { + gtagURL: url + }); + logger.warn(err.message); + return ''; + } + return url; + } }); } From 6c30bd62ec7ca3adc31ad411cae30da5a44d1b72 Mon Sep 17 00:00:00 2001 From: dwyfrequency Date: Wed, 8 Mar 2023 17:30:16 -0500 Subject: [PATCH 05/26] Add test and exported function --- packages/analytics/src/helpers.test.ts | 33 ++++++++++++++++++++++++-- packages/analytics/src/helpers.ts | 27 ++++++++++++--------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/packages/analytics/src/helpers.test.ts b/packages/analytics/src/helpers.test.ts index 1175ff0f61e..3ccc25a727c 100644 --- a/packages/analytics/src/helpers.test.ts +++ b/packages/analytics/src/helpers.test.ts @@ -24,9 +24,10 @@ import { insertScriptTag, wrapOrCreateGtag, findGtagScriptOnPage, - promiseAllSettled + promiseAllSettled, + createGtagTrustedTypesScriptURL } from './helpers'; -import { GtagCommand } from './constants'; +import { GtagCommand, GTAG_URL } from './constants'; import { Deferred } from '@firebase/util'; import { ConsentSettings } from './public-types'; import { removeGtagScripts } from '../testing/gtag-script-util'; @@ -46,6 +47,34 @@ const fakeDynamicConfig: DynamicConfig = { }; const fakeDynamicConfigPromises = [Promise.resolve(fakeDynamicConfig)]; +describe('Trusted Types policies and functions', () => { + const ttStub = stub( + window.trustedTypes as TrustedTypePolicyFactory, + 'createPolicy' + ).returns({ + createScriptURL: (s: string) => s + } as any); + + it('Verify trustedTypes is called if the API is available', () => { + expect(ttStub).to.be.called; + }); + + it('createGtagTrustedTypesScriptURL verifies gtag URL base exists when a URL is provided', () => { + expect(createGtagTrustedTypesScriptURL(GTAG_URL)).to.equal(GTAG_URL); + }); + + it('createGtagTrustedTypesScriptURL rejects URLs with non-gtag base', () => { + const NON_GTAG_URL = 'http://iamnotgtag.com'; + const consoleErrorStub = stub(console, 'error'); + + expect(createGtagTrustedTypesScriptURL(NON_GTAG_URL)).to.equal(''); + expect(consoleErrorStub).to.be.calledWith( + 'Unknown gtag resource!', + NON_GTAG_URL + ); + }); +}); + describe('Gtag wrapping functions', () => { afterEach(() => { removeGtagScripts(); diff --git a/packages/analytics/src/helpers.ts b/packages/analytics/src/helpers.ts index 4a2b11eff1a..5ae695fe17b 100644 --- a/packages/analytics/src/helpers.ts +++ b/packages/analytics/src/helpers.ts @@ -33,20 +33,25 @@ type GtagConfigOrEventParams = ControlParams & EventParams & CustomParams; let _ttPolicy: Partial; if (window.trustedTypes) { _ttPolicy = window.trustedTypes.createPolicy('firebase-js-sdk-policy', { - createScriptURL: (url: string) => { - if (!url.startsWith(GTAG_URL)) { - console.error('Unknown gtag resource!', url); - const err = ERROR_FACTORY.create(AnalyticsError.INVALID_GTAG_RESOURCE, { - gtagURL: url - }); - logger.warn(err.message); - return ''; - } - return url; - } + createScriptURL: createGtagTrustedTypesScriptURL }); } +/** + * Verifies and creates a TrustedScriptURL. + */ +export function createGtagTrustedTypesScriptURL(url: string): string { + if (!url.startsWith(GTAG_URL)) { + console.error('Unknown gtag resource!', url); + const err = ERROR_FACTORY.create(AnalyticsError.INVALID_GTAG_RESOURCE, { + gtagURL: url + }); + logger.warn(err.message); + return ''; + } + return url; +} + /** * Makeshift polyfill for Promise.allSettled(). Resolves when all promises * have either resolved or rejected. From 39a6958938d7219722fc1bfaa2fdcc2b39da2cec Mon Sep 17 00:00:00 2001 From: dwyfrequency Date: Thu, 9 Mar 2023 13:42:07 -0500 Subject: [PATCH 06/26] Add changeset --- .changeset/tasty-cooks-leave.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tasty-cooks-leave.md diff --git a/.changeset/tasty-cooks-leave.md b/.changeset/tasty-cooks-leave.md new file mode 100644 index 00000000000..69dbdd34e43 --- /dev/null +++ b/.changeset/tasty-cooks-leave.md @@ -0,0 +1,5 @@ +--- +'@firebase/analytics': patch +--- + +Use the Trusted Types API when composing the gtag URL. From 86c0f2c0ad3555c07ef643b9524a77f12a8e06db Mon Sep 17 00:00:00 2001 From: dwyfrequency Date: Thu, 9 Mar 2023 16:42:13 -0500 Subject: [PATCH 07/26] Update comment --- packages/analytics/src/helpers.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/analytics/src/helpers.ts b/packages/analytics/src/helpers.ts index 5ae695fe17b..210257b96a2 100644 --- a/packages/analytics/src/helpers.ts +++ b/packages/analytics/src/helpers.ts @@ -29,7 +29,8 @@ import { AnalyticsError, ERROR_FACTORY } from './errors'; // Possible parameter types for gtag 'event' and 'config' commands type GtagConfigOrEventParams = ControlParams & EventParams & CustomParams; -// Create a TrustedTypes policy that we use for scripts +// Create a TrustedTypes policy that we can use for updating src +// properties let _ttPolicy: Partial; if (window.trustedTypes) { _ttPolicy = window.trustedTypes.createPolicy('firebase-js-sdk-policy', { From dc7b7f17b4041e8561e97f95fe839bd56c31694a Mon Sep 17 00:00:00 2001 From: dwyfrequency Date: Tue, 21 Mar 2023 16:50:54 -0400 Subject: [PATCH 08/26] Created function to create policy --- packages/analytics/src/helpers.test.ts | 76 +++++++++++++++++++------- packages/analytics/src/helpers.ts | 44 +++++++++++---- 2 files changed, 88 insertions(+), 32 deletions(-) diff --git a/packages/analytics/src/helpers.test.ts b/packages/analytics/src/helpers.test.ts index 3ccc25a727c..ff5d15006bd 100644 --- a/packages/analytics/src/helpers.test.ts +++ b/packages/analytics/src/helpers.test.ts @@ -25,7 +25,8 @@ import { wrapOrCreateGtag, findGtagScriptOnPage, promiseAllSettled, - createGtagTrustedTypesScriptURL + createGtagTrustedTypesScriptURL, + createTrustedTypesPolicy } from './helpers'; import { GtagCommand, GTAG_URL } from './constants'; import { Deferred } from '@firebase/util'; @@ -48,30 +49,63 @@ const fakeDynamicConfig: DynamicConfig = { const fakeDynamicConfigPromises = [Promise.resolve(fakeDynamicConfig)]; describe('Trusted Types policies and functions', () => { - const ttStub = stub( - window.trustedTypes as TrustedTypePolicyFactory, - 'createPolicy' - ).returns({ - createScriptURL: (s: string) => s - } as any); - - it('Verify trustedTypes is called if the API is available', () => { - expect(ttStub).to.be.called; - }); + describe('Trusted types exists', () => { + let ttStub: SinonStub; + + beforeEach(() => { + ttStub = stub( + window.trustedTypes as TrustedTypePolicyFactory, + 'createPolicy' + ).returns({ + createScriptURL: (s: string) => s + } as any); + }); + + afterEach(() => { + removeGtagScripts(); + ttStub.restore(); + }); + + it('Verify trustedTypes is called if the API is available', () => { + const trustedTypesPolicy = createTrustedTypesPolicy( + 'firebase-js-sdk-policy', + { + createScriptURL: createGtagTrustedTypesScriptURL + } + ); - it('createGtagTrustedTypesScriptURL verifies gtag URL base exists when a URL is provided', () => { - expect(createGtagTrustedTypesScriptURL(GTAG_URL)).to.equal(GTAG_URL); + expect(ttStub).to.be.called; + expect(trustedTypesPolicy).not.to.be.undefined; + }); + + it('createGtagTrustedTypesScriptURL verifies gtag URL base exists when a URL is provided', () => { + expect(createGtagTrustedTypesScriptURL(GTAG_URL)).to.equal(GTAG_URL); + }); + + it('createGtagTrustedTypesScriptURL rejects URLs with non-gtag base', () => { + const NON_GTAG_URL = 'http://iamnotgtag.com'; + const consoleErrorStub = stub(console, 'error'); + + expect(createGtagTrustedTypesScriptURL(NON_GTAG_URL)).to.equal(''); + expect(consoleErrorStub).to.be.calledWith( + 'Unknown gtag resource!', + NON_GTAG_URL + ); + }); }); - it('createGtagTrustedTypesScriptURL rejects URLs with non-gtag base', () => { - const NON_GTAG_URL = 'http://iamnotgtag.com'; - const consoleErrorStub = stub(console, 'error'); + describe('Trusted types does not exist', () => { + it('Verify trustedTypes functions are not called if the API is not available', () => { + delete window.trustedTypes; + const trustedTypesPolicy = createTrustedTypesPolicy( + 'firebase-js-sdk-policy', + { + createScriptURL: createGtagTrustedTypesScriptURL + } + ); - expect(createGtagTrustedTypesScriptURL(NON_GTAG_URL)).to.equal(''); - expect(consoleErrorStub).to.be.calledWith( - 'Unknown gtag resource!', - NON_GTAG_URL - ); + expect(trustedTypesPolicy).to.be.undefined; + }); }); }); diff --git a/packages/analytics/src/helpers.ts b/packages/analytics/src/helpers.ts index 210257b96a2..5cf4850928e 100644 --- a/packages/analytics/src/helpers.ts +++ b/packages/analytics/src/helpers.ts @@ -29,15 +29,6 @@ import { AnalyticsError, ERROR_FACTORY } from './errors'; // Possible parameter types for gtag 'event' and 'config' commands type GtagConfigOrEventParams = ControlParams & EventParams & CustomParams; -// Create a TrustedTypes policy that we can use for updating src -// properties -let _ttPolicy: Partial; -if (window.trustedTypes) { - _ttPolicy = window.trustedTypes.createPolicy('firebase-js-sdk-policy', { - createScriptURL: createGtagTrustedTypesScriptURL - }); -} - /** * Verifies and creates a TrustedScriptURL. */ @@ -65,6 +56,30 @@ export function promiseAllSettled( return Promise.all(promises.map(promise => promise.catch(e => e))); } +/** + * Creates a TrustedTypePolicy object that implements the rules passed as policyOptions. + * + * @param policyName A string containing the name of the policy + * @param policyOptions Object containing implementations of instance methods for TrustedTypesPolicy, see {@link https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicy#instance_methods + * | the TrustedTypePolicy reference documentation}. + * @returns + */ +export function createTrustedTypesPolicy( + policyName: string, + policyOptions: Partial +): Partial | undefined { + // Create a TrustedTypes policy that we can use for updating src + // properties + let trustedTypesPolicy: Partial | undefined; + if (window.trustedTypes) { + trustedTypesPolicy = window.trustedTypes.createPolicy( + policyName, + policyOptions + ); + } + return trustedTypesPolicy; +} + /** * Inserts gtag script tag into the page to asynchronously download gtag. * @param dataLayerName Name of datalayer (most often the default, "_dataLayer"). @@ -73,13 +88,20 @@ export function insertScriptTag( dataLayerName: string, measurementId: string ): void { + const trustedTypesPolicy = createTrustedTypesPolicy( + 'firebase-js-sdk-policy', + { + createScriptURL: createGtagTrustedTypesScriptURL + } + ); + const script = document.createElement('script'); // We are not providing an analyticsId in the URL because it would trigger a `page_view` // without fid. We will initialize ga-id using gtag (config) command together with fid. const gtagScriptURL = `${GTAG_URL}?l=${dataLayerName}&id=${measurementId}`; - (script.src as string | TrustedScriptURL) = _ttPolicy - ? (_ttPolicy as TrustedTypePolicy)?.createScriptURL(gtagScriptURL) + (script.src as string | TrustedScriptURL) = trustedTypesPolicy + ? (trustedTypesPolicy as TrustedTypePolicy)?.createScriptURL(gtagScriptURL) : gtagScriptURL; script.async = true; From 80ae05ef92447c07f5d2e91f055e1b74d24a562c Mon Sep 17 00:00:00 2001 From: dwyfrequency Date: Tue, 21 Mar 2023 17:11:42 -0400 Subject: [PATCH 09/26] Stub logger instead of console.log --- packages/analytics/src/helpers.test.ts | 15 ++++++++++----- packages/analytics/src/helpers.ts | 1 - 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/analytics/src/helpers.test.ts b/packages/analytics/src/helpers.test.ts index ff5d15006bd..98df87b6c04 100644 --- a/packages/analytics/src/helpers.test.ts +++ b/packages/analytics/src/helpers.test.ts @@ -32,6 +32,8 @@ import { GtagCommand, GTAG_URL } from './constants'; import { Deferred } from '@firebase/util'; import { ConsentSettings } from './public-types'; import { removeGtagScripts } from '../testing/gtag-script-util'; +import { logger } from './logger'; +import { AnalyticsError, ERROR_FACTORY } from './errors'; const fakeMeasurementId = 'abcd-efgh-ijkl'; const fakeAppId = 'my-test-app-1234'; @@ -84,13 +86,16 @@ describe('Trusted Types policies and functions', () => { it('createGtagTrustedTypesScriptURL rejects URLs with non-gtag base', () => { const NON_GTAG_URL = 'http://iamnotgtag.com'; - const consoleErrorStub = stub(console, 'error'); + const loggerWarnStub = stub(logger, 'warn'); + const errorMessage = ERROR_FACTORY.create( + AnalyticsError.INVALID_GTAG_RESOURCE, + { + gtagURL: NON_GTAG_URL + } + ).message; expect(createGtagTrustedTypesScriptURL(NON_GTAG_URL)).to.equal(''); - expect(consoleErrorStub).to.be.calledWith( - 'Unknown gtag resource!', - NON_GTAG_URL - ); + expect(loggerWarnStub).to.be.calledWith(errorMessage); }); }); diff --git a/packages/analytics/src/helpers.ts b/packages/analytics/src/helpers.ts index 5cf4850928e..1f2630c96b6 100644 --- a/packages/analytics/src/helpers.ts +++ b/packages/analytics/src/helpers.ts @@ -34,7 +34,6 @@ type GtagConfigOrEventParams = ControlParams & EventParams & CustomParams; */ export function createGtagTrustedTypesScriptURL(url: string): string { if (!url.startsWith(GTAG_URL)) { - console.error('Unknown gtag resource!', url); const err = ERROR_FACTORY.create(AnalyticsError.INVALID_GTAG_RESOURCE, { gtagURL: url }); From ff564c76a4cd2e6413284f7170fb27fdb0c1e8dc Mon Sep 17 00:00:00 2001 From: dwyfrequency Date: Wed, 22 Mar 2023 12:18:56 -0400 Subject: [PATCH 10/26] Remove returns keyword in function docstring --- packages/analytics/src/helpers.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/analytics/src/helpers.ts b/packages/analytics/src/helpers.ts index 1f2630c96b6..e926c14a725 100644 --- a/packages/analytics/src/helpers.ts +++ b/packages/analytics/src/helpers.ts @@ -61,7 +61,6 @@ export function promiseAllSettled( * @param policyName A string containing the name of the policy * @param policyOptions Object containing implementations of instance methods for TrustedTypesPolicy, see {@link https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicy#instance_methods * | the TrustedTypePolicy reference documentation}. - * @returns */ export function createTrustedTypesPolicy( policyName: string, From 5316071e9a4a1c90a29bc2fdeee1997ec1ba8e94 Mon Sep 17 00:00:00 2001 From: Mark Duckworth <1124037+MarkDuckworth@users.noreply.github.com> Date: Tue, 14 Mar 2023 09:18:55 -0600 Subject: [PATCH 11/26] Updated the changeset for OR queries to be more descriptive (#7121) * Updated change set to match Android release notes. --- .changeset/sweet-rats-compete.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/sweet-rats-compete.md b/.changeset/sweet-rats-compete.md index 0c10ba8bac5..46cf4a61ddf 100644 --- a/.changeset/sweet-rats-compete.md +++ b/.changeset/sweet-rats-compete.md @@ -3,4 +3,4 @@ 'firebase': minor --- -OR Query public API +Add support for disjunctions in queries (OR queries). From cc8281625910ab77db1f0e66909518db532131aa Mon Sep 17 00:00:00 2001 From: wu-hui <53845758+wu-hui@users.noreply.github.com> Date: Wed, 15 Mar 2023 12:49:25 -0400 Subject: [PATCH 12/26] New way to config Firestore SDK Cache. (#7015) * New way to config Firestore SDK Cache. * fixups * Fix some test failures * Fixing dts file * Add public comments * API report * Create brown-beers-tease.md * warning messages and more tests * Addressing comments * Update API reports * Fix provider test failure for node w/o indexeddb * Fix node memory test * rename cache to localCache * Update API reports * Tech writer review * yarn docgen * auth change * Update API reports * docgen devsite * Fix changeset * Another auth change * more devsite fix * Update API reports * Rename indexeddb to persistent --------- Co-authored-by: wu-hui --- .changeset/brown-beers-tease.md | 5 + common/api-review/firestore.api.md | 58 +++- docs-devsite/firestore_.firestoresettings.md | 19 +- docs-devsite/firestore_.md | 113 ++++++- docs-devsite/firestore_.memorylocalcache.md | 35 ++ .../firestore_.persistentcachesettings.md | 48 +++ .../firestore_.persistentlocalcache.md | 35 ++ ...firestore_.persistentmultipletabmanager.md | 33 ++ .../firestore_.persistentsingletabmanager.md | 33 ++ ...ore_.persistentsingletabmanagersettings.md | 35 ++ packages/firestore/src/api.ts | 15 + packages/firestore/src/api/cache_config.ts | 302 ++++++++++++++++++ packages/firestore/src/api/database.ts | 99 +++--- .../firestore/src/api/index_configuration.ts | 23 +- packages/firestore/src/api/settings.ts | 17 + .../firestore/src/core/firestore_client.ts | 144 +++++++-- packages/firestore/src/lite-api/settings.ts | 5 + .../test/integration/api/database.test.ts | 1 + .../test/integration/api/provider.test.ts | 37 ++- .../test/integration/api/validation.test.ts | 4 +- .../integration/browser/indexeddb.test.ts | 12 +- .../test/integration/util/helpers.ts | 12 +- .../unit/local/local_store_indexeddb.test.ts | 5 + 23 files changed, 992 insertions(+), 98 deletions(-) create mode 100644 .changeset/brown-beers-tease.md create mode 100644 docs-devsite/firestore_.memorylocalcache.md create mode 100644 docs-devsite/firestore_.persistentcachesettings.md create mode 100644 docs-devsite/firestore_.persistentlocalcache.md create mode 100644 docs-devsite/firestore_.persistentmultipletabmanager.md create mode 100644 docs-devsite/firestore_.persistentsingletabmanager.md create mode 100644 docs-devsite/firestore_.persistentsingletabmanagersettings.md create mode 100644 packages/firestore/src/api/cache_config.ts diff --git a/.changeset/brown-beers-tease.md b/.changeset/brown-beers-tease.md new file mode 100644 index 00000000000..e0e8e7adc9e --- /dev/null +++ b/.changeset/brown-beers-tease.md @@ -0,0 +1,5 @@ +--- +"@firebase/firestore": minor +--- + +Introduces a new way to config Firestore SDK Cache. diff --git a/common/api-review/firestore.api.md b/common/api-review/firestore.api.md index 077e0e4426f..905629f870a 100644 --- a/common/api-review/firestore.api.md +++ b/common/api-review/firestore.api.md @@ -163,10 +163,10 @@ export class DocumentSnapshot { export { EmulatorMockTokenOptions } -// @public +// @public @deprecated export function enableIndexedDbPersistence(firestore: Firestore, persistenceSettings?: PersistenceSettings): Promise; -// @public +// @public @deprecated export function enableMultiTabIndexedDbPersistence(firestore: Firestore): Promise; // @public @@ -219,6 +219,9 @@ export class FirestoreError extends FirebaseError { // @public export type FirestoreErrorCode = 'cancelled' | 'unknown' | 'invalid-argument' | 'deadline-exceeded' | 'not-found' | 'already-exists' | 'permission-denied' | 'resource-exhausted' | 'failed-precondition' | 'aborted' | 'out-of-range' | 'unimplemented' | 'internal' | 'unavailable' | 'data-loss' | 'unauthenticated'; +// @public +export type FirestoreLocalCache = MemoryLocalCache | PersistentLocalCache; + // @public export interface FirestoreSettings { cacheSizeBytes?: number; @@ -226,6 +229,7 @@ export interface FirestoreSettings { experimentalForceLongPolling?: boolean; host?: string; ignoreUndefinedProperties?: boolean; + localCache?: FirestoreLocalCache; ssl?: boolean; } @@ -327,6 +331,15 @@ export interface LoadBundleTaskProgress { export { LogLevel } +// @public +export interface MemoryLocalCache { + // (undocumented) + kind: 'memory'; +} + +// @public +export function memoryLocalCache(): MemoryLocalCache; + // @public export function namedQuery(firestore: Firestore, name: string): Promise; @@ -404,6 +417,47 @@ export interface PersistenceSettings { forceOwnership?: boolean; } +// @public +export interface PersistentCacheSettings { + cacheSizeBytes?: number; + tabManager?: PersistentTabManager; +} + +// @public +export interface PersistentLocalCache { + // (undocumented) + kind: 'persistent'; +} + +// @public +export function persistentLocalCache(settings?: PersistentCacheSettings): PersistentLocalCache; + +// @public +export interface PersistentMultipleTabManager { + // (undocumented) + kind: 'PersistentMultipleTab'; +} + +// @public +export function persistentMultipleTabManager(): PersistentMultipleTabManager; + +// @public +export interface PersistentSingleTabManager { + // (undocumented) + kind: 'persistentSingleTab'; +} + +// @public +export function persistentSingleTabManager(settings: PersistentSingleTabManagerSettings | undefined): PersistentSingleTabManager; + +// @public +export interface PersistentSingleTabManagerSettings { + forceOwnership?: boolean; +} + +// @public +export type PersistentTabManager = PersistentSingleTabManager | PersistentMultipleTabManager; + // @public export type Primitive = string | number | boolean | undefined | null; diff --git a/docs-devsite/firestore_.firestoresettings.md b/docs-devsite/firestore_.firestoresettings.md index 96fe454cb77..8e6da365f46 100644 --- a/docs-devsite/firestore_.firestoresettings.md +++ b/docs-devsite/firestore_.firestoresettings.md @@ -22,15 +22,18 @@ export declare interface FirestoreSettings | Property | Type | Description | | --- | --- | --- | -| [cacheSizeBytes](./firestore_.firestoresettings.md#firestoresettingscachesizebytes) | number | An approximate cache size threshold for the on-disk data. If the cache grows beyond this size, Firestore will start removing data that hasn't been recently used. The size is not a guarantee that the cache will stay below that size, only that if the cache exceeds the given size, cleanup will be attempted.The default value is 40 MB. The threshold must be set to at least 1 MB, and can be set to CACHE_SIZE_UNLIMITED to disable garbage collection. | +| [cacheSizeBytes](./firestore_.firestoresettings.md#firestoresettingscachesizebytes) | number | NOTE: This field will be deprecated in a future major release. Use cache field instead to specify cache size, and other cache configurations.An approximate cache size threshold for the on-disk data. If the cache grows beyond this size, Firestore will start removing data that hasn't been recently used. The size is not a guarantee that the cache will stay below that size, only that if the cache exceeds the given size, cleanup will be attempted.The default value is 40 MB. The threshold must be set to at least 1 MB, and can be set to CACHE_SIZE_UNLIMITED to disable garbage collection. | | [experimentalAutoDetectLongPolling](./firestore_.firestoresettings.md#firestoresettingsexperimentalautodetectlongpolling) | boolean | Configures the SDK's underlying transport (WebChannel) to automatically detect if long-polling should be used. This is very similar to experimentalForceLongPolling, but only uses long-polling if required.This setting will likely be enabled by default in future releases and cannot be combined with experimentalForceLongPolling. | | [experimentalForceLongPolling](./firestore_.firestoresettings.md#firestoresettingsexperimentalforcelongpolling) | boolean | Forces the SDK’s underlying network transport (WebChannel) to use long-polling. Each response from the backend will be closed immediately after the backend sends data (by default responses are kept open in case the backend has more data to send). This avoids incompatibility issues with certain proxies, antivirus software, etc. that incorrectly buffer traffic indefinitely. Use of this option will cause some performance degradation though.This setting cannot be used with experimentalAutoDetectLongPolling and may be removed in a future release. If you find yourself using it to work around a specific network reliability issue, please tell us about it in https://github.com/firebase/firebase-js-sdk/issues/1674. | | [host](./firestore_.firestoresettings.md#firestoresettingshost) | string | The hostname to connect to. | | [ignoreUndefinedProperties](./firestore_.firestoresettings.md#firestoresettingsignoreundefinedproperties) | boolean | Whether to skip nested properties that are set to undefined during object serialization. If set to true, these properties are skipped and not written to Firestore. If set to false or omitted, the SDK throws an exception when it encounters properties of type undefined. | +| [localCache](./firestore_.firestoresettings.md#firestoresettingslocalcache) | [FirestoreLocalCache](./firestore_.md#firestorelocalcache) | Specifies the cache used by the SDK. Availabe options are MemoryLocalCache and IndexedDbLocalCache, each with different configuration options.When unspecified, MemoryLocalCache will be used by default.NOTE: setting this field and cacheSizeBytes at the same time will throw exception during SDK initialization. Instead, using the configuration in the FirestoreLocalCache object to specify the cache size. | | [ssl](./firestore_.firestoresettings.md#firestoresettingsssl) | boolean | Whether to use SSL when connecting. | ## FirestoreSettings.cacheSizeBytes +NOTE: This field will be deprecated in a future major release. Use `cache` field instead to specify cache size, and other cache configurations. + An approximate cache size threshold for the on-disk data. If the cache grows beyond this size, Firestore will start removing data that hasn't been recently used. The size is not a guarantee that the cache will stay below that size, only that if the cache exceeds the given size, cleanup will be attempted. The default value is 40 MB. The threshold must be set to at least 1 MB, and can be set to `CACHE_SIZE_UNLIMITED` to disable garbage collection. @@ -85,6 +88,20 @@ Whether to skip nested properties that are set to `undefined` during object seri ignoreUndefinedProperties?: boolean; ``` +## FirestoreSettings.localCache + +Specifies the cache used by the SDK. Availabe options are `MemoryLocalCache` and `IndexedDbLocalCache`, each with different configuration options. + +When unspecified, `MemoryLocalCache` will be used by default. + +NOTE: setting this field and `cacheSizeBytes` at the same time will throw exception during SDK initialization. Instead, using the configuration in the `FirestoreLocalCache` object to specify the cache size. + +Signature: + +```typescript +localCache?: FirestoreLocalCache; +``` + ## FirestoreSettings.ssl Whether to use SSL when connecting. diff --git a/docs-devsite/firestore_.md b/docs-devsite/firestore_.md index 9351f162119..365635c434d 100644 --- a/docs-devsite/firestore_.md +++ b/docs-devsite/firestore_.md @@ -33,7 +33,7 @@ https://github.com/firebase/firebase-js-sdk | [onSnapshotsInSync(firestore, observer)](./firestore_.md#onsnapshotsinsync) | Attaches a listener for a snapshots-in-sync event. The snapshots-in-sync event indicates that all listeners affected by a given change have fired, even if a single server-generated change affects multiple listeners.NOTE: The snapshots-in-sync event only indicates that listeners are in sync with each other, but does not relate to whether those snapshots are in sync with the server. Use SnapshotMetadata in the individual listeners to determine if a snapshot is from the cache or the server. | | [onSnapshotsInSync(firestore, onSync)](./firestore_.md#onsnapshotsinsync) | Attaches a listener for a snapshots-in-sync event. The snapshots-in-sync event indicates that all listeners affected by a given change have fired, even if a single server-generated change affects multiple listeners.NOTE: The snapshots-in-sync event only indicates that listeners are in sync with each other, but does not relate to whether those snapshots are in sync with the server. Use SnapshotMetadata in the individual listeners to determine if a snapshot is from the cache or the server. | | [runTransaction(firestore, updateFunction, options)](./firestore_.md#runtransaction) | Executes the given updateFunction and then attempts to commit the changes applied within the transaction. If any document read within the transaction has changed, Cloud Firestore retries the updateFunction. If it fails to commit after 5 attempts, the transaction fails.The maximum number of writes allowed in a single transaction is 500. | -| [setIndexConfiguration(firestore, configuration)](./firestore_.md#setindexconfiguration) | (BETA) Configures indexing for local query execution. Any previous index configuration is overridden. The Promise resolves once the index configuration has been persisted.The index entries themselves are created asynchronously. You can continue to use queries that require indexing even if the indices are not yet available. Query execution will automatically start using the index once the index entries have been written.Indexes are only supported with IndexedDb persistence. Invoke either enableIndexedDbPersistence() or enableMultiTabIndexedDbPersistence() before setting an index configuration. If IndexedDb is not enabled, any index configuration is ignored. | +| [setIndexConfiguration(firestore, configuration)](./firestore_.md#setindexconfiguration) | (BETA) Configures indexing for local query execution. Any previous index configuration is overridden. The Promise resolves once the index configuration has been persisted.The index entries themselves are created asynchronously. You can continue to use queries that require indexing even if the indices are not yet available. Query execution will automatically start using the index once the index entries have been written.Indexes are only supported with IndexedDb persistence. If IndexedDb is not enabled, any index configuration is ignored. | | [setIndexConfiguration(firestore, json)](./firestore_.md#setindexconfiguration) | (BETA) Configures indexing for local query execution. Any previous index configuration is overridden. The Promise resolves once the index configuration has been persisted.The index entries themselves are created asynchronously. You can continue to use queries that require indexing even if the indices are not yet available. Query execution will automatically start using the index once the index entries have been written.Indexes are only supported with IndexedDb persistence. Invoke either enableIndexedDbPersistence() or enableMultiTabIndexedDbPersistence() before setting an index configuration. If IndexedDb is not enabled, any index configuration is ignored.The method accepts the JSON format exported by the Firebase CLI (firebase firestore:indexes). If the JSON format is invalid, this method throws an error. | | [terminate(firestore)](./firestore_.md#terminate) | Terminates the provided [Firestore](./firestore_.firestore.md#firestore_class) instance.After calling terminate() only the clearIndexedDbPersistence() function may be used. Any other function will throw a FirestoreError.To restart after termination, create a new instance of FirebaseFirestore with [getFirestore()](./firestore_.md#getfirestore).Termination does not cancel any pending writes, and any promises that are awaiting a response from the server will not be resolved. If you have persistence enabled, the next time you start this instance, it will resume sending these writes to the server.Note: Under normal circumstances, calling terminate() is not required. This function is useful only when you want to force this instance to release all of its resources or in combination with clearIndexedDbPersistence() to ensure that all local state is destroyed between test runs. | | [waitForPendingWrites(firestore)](./firestore_.md#waitforpendingwrites) | Waits until all currently pending writes for the active user have been acknowledged by the backend.The returned promise resolves immediately if there are no outstanding writes. Otherwise, the promise waits for all previously issued writes (including those written in a previous app session), but it does not wait for writes that were added after the function is called. If you want to wait for additional writes, call waitForPendingWrites() again.Any outstanding waitForPendingWrites() promises are rejected during user changes. | @@ -42,6 +42,8 @@ https://github.com/firebase/firebase-js-sdk | [deleteField()](./firestore_.md#deletefield) | Returns a sentinel for use with [updateDoc()](./firestore_lite.md#updatedoc) or [setDoc()](./firestore_lite.md#setdoc) with {merge: true} to mark a field for deletion. | | [documentId()](./firestore_.md#documentid) | Returns a special sentinel FieldPath to refer to the ID of a document. It can be used in queries to sort or filter by the document ID. | | [getFirestore()](./firestore_.md#getfirestore) | Returns the existing default [Firestore](./firestore_.firestore.md#firestore_class) instance that is associated with the default [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface). If no instance exists, initializes a new instance with default settings. | +| [memoryLocalCache()](./firestore_.md#memorylocalcache) | Creates an instance of MemoryLocalCache. The instance can be set to FirestoreSettings.cache to tell the SDK which cache layer to use. | +| [persistentMultipleTabManager()](./firestore_.md#persistentmultipletabmanager) | Creates an instance of PersistentMultipleTabManager. | | [serverTimestamp()](./firestore_.md#servertimestamp) | Returns a sentinel used with [setDoc()](./firestore_lite.md#setdoc) or [updateDoc()](./firestore_lite.md#updatedoc) to include a server-generated timestamp in the written data. | | function(elements...) | | [arrayRemove(elements)](./firestore_.md#arrayremove) | Returns a special value that can be used with [setDoc()](./firestore_.md#setdoc) or that tells the server to remove the given elements from any array value that already exists on the server. All instances of each element specified will be removed from the array. If the field being modified is not already an array it will be overwritten with an empty array. | @@ -98,6 +100,9 @@ https://github.com/firebase/firebase-js-sdk | [setDoc(reference, data, options)](./firestore_.md#setdoc) | Writes to the document referred to by the specified DocumentReference. If the document does not yet exist, it will be created. If you provide merge or mergeFields, the provided data can be merged into an existing document. | | [updateDoc(reference, data)](./firestore_.md#updatedoc) | Updates fields in the document referred to by the specified DocumentReference. The update will fail if applied to a document that does not exist. | | [updateDoc(reference, field, value, moreFieldsAndValues)](./firestore_.md#updatedoc) | Updates fields in the document referred to by the specified DocumentReference The update will fail if applied to a document that does not exist.Nested fields can be updated by providing dot-separated field path strings or by providing FieldPath objects. | +| function(settings...) | +| [persistentLocalCache(settings)](./firestore_.md#persistentlocalcache) | Creates an instance of PersistentLocalCache. The instance can be set to FirestoreSettings.cache to tell the SDK which cache layer to use. | +| [persistentSingleTabManager(settings)](./firestore_.md#persistentsingletabmanager) | Creates an instance of PersistentSingleTabManager. | | function(snapshot...) | | [endAt(snapshot)](./firestore_.md#endat) | Creates a [QueryEndAtConstraint](./firestore_.queryendatconstraint.md#queryendatconstraint_class) that modifies the result set to end at the provided document (inclusive). The end position is relative to the order of the query. The document must contain all of the fields provided in the orderBy of the query. | | [endBefore(snapshot)](./firestore_.md#endbefore) | Creates a [QueryEndAtConstraint](./firestore_.queryendatconstraint.md#queryendatconstraint_class) that modifies the result set to end before the provided document (exclusive). The end position is relative to the order of the query. The document must contain all of the fields provided in the orderBy of the query. | @@ -148,7 +153,13 @@ https://github.com/firebase/firebase-js-sdk | [IndexConfiguration](./firestore_.indexconfiguration.md#indexconfiguration_interface) | (BETA) A list of Firestore indexes to speed up local query execution.See [JSON Format](https://firebase.google.com/docs/reference/firestore/indexes/#json_format) for a description of the format of the index definition. | | [IndexField](./firestore_.indexfield.md#indexfield_interface) | (BETA) A single field element in an index configuration. | | [LoadBundleTaskProgress](./firestore_.loadbundletaskprogress.md#loadbundletaskprogress_interface) | Represents a progress update or a final state from loading bundles. | +| [MemoryLocalCache](./firestore_.memorylocalcache.md#memorylocalcache_interface) | Provides an in-memory cache to the SDK. This is the default cache unless explicitly configured otherwise.To use, create an instance using the factory function , then set the instance to FirestoreSettings.cache and call initializeFirestore using the settings object. | | [PersistenceSettings](./firestore_.persistencesettings.md#persistencesettings_interface) | Settings that can be passed to enableIndexedDbPersistence() to configure Firestore persistence. | +| [PersistentCacheSettings](./firestore_.persistentcachesettings.md#persistentcachesettings_interface) | An settings object to configure an PersistentLocalCache instance. | +| [PersistentLocalCache](./firestore_.persistentlocalcache.md#persistentlocalcache_interface) | Provides a persistent cache backed by IndexedDb to the SDK.To use, create an instance using the factory function , then set the instance to FirestoreSettings.cache and call initializeFirestore using the settings object. | +| [PersistentMultipleTabManager](./firestore_.persistentmultipletabmanager.md#persistentmultipletabmanager_interface) | A tab manager supportting multiple tabs. SDK will synchronize queries and mutations done across all tabs using the SDK. | +| [PersistentSingleTabManager](./firestore_.persistentsingletabmanager.md#persistentsingletabmanager_interface) | A tab manager supportting only one tab, no synchronization will be performed across tabs. | +| [PersistentSingleTabManagerSettings](./firestore_.persistentsingletabmanagersettings.md#persistentsingletabmanagersettings_interface) | Type to configure an PersistentSingleTabManager instace. | | [SnapshotListenOptions](./firestore_.snapshotlistenoptions.md#snapshotlistenoptions_interface) | An options object that can be passed to [onSnapshot()](./firestore_.md#onsnapshot) and [QuerySnapshot.docChanges()](./firestore_.querysnapshot.md#querysnapshotdocchanges) to control which types of changes to include in the result set. | | [SnapshotOptions](./firestore_.snapshotoptions.md#snapshotoptions_interface) | Options that configure how data is retrieved from a DocumentSnapshot (for example the desired behavior for server timestamps that have not yet been set to their final value). | | [TransactionOptions](./firestore_.transactionoptions.md#transactionoptions_interface) | Options to customize transaction behavior. | @@ -170,9 +181,11 @@ https://github.com/firebase/firebase-js-sdk | [ChildUpdateFields](./firestore_.md#childupdatefields) | Helper for calculating the nested fields for a given type T1. This is needed to distribute union types such as undefined | {...} (happens for optional props) or {a: A} | {b: B}.In this use case, V is used to distribute the union types of T[K] on Record, since T[K] is evaluated as an expression and not distributed.See https://www.typescriptlang.org/docs/handbook/advanced-types.html\#distributive-conditional-types | | [DocumentChangeType](./firestore_.md#documentchangetype) | The type of a DocumentChange may be 'added', 'removed', or 'modified'. | | [FirestoreErrorCode](./firestore_.md#firestoreerrorcode) | The set of Firestore status codes. The codes are the same at the ones exposed by gRPC here: https://github.com/grpc/grpc/blob/master/doc/statuscodes.mdPossible values: - 'cancelled': The operation was cancelled (typically by the caller). - 'unknown': Unknown error or an error from a different error domain. - 'invalid-argument': Client specified an invalid argument. Note that this differs from 'failed-precondition'. 'invalid-argument' indicates arguments that are problematic regardless of the state of the system (e.g. an invalid field name). - 'deadline-exceeded': Deadline expired before operation could complete. For operations that change the state of the system, this error may be returned even if the operation has completed successfully. For example, a successful response from a server could have been delayed long enough for the deadline to expire. - 'not-found': Some requested document was not found. - 'already-exists': Some document that we attempted to create already exists. - 'permission-denied': The caller does not have permission to execute the specified operation. - 'resource-exhausted': Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space. - 'failed-precondition': Operation was rejected because the system is not in a state required for the operation's execution. - 'aborted': The operation was aborted, typically due to a concurrency issue like transaction aborts, etc. - 'out-of-range': Operation was attempted past the valid range. - 'unimplemented': Operation is not implemented or not supported/enabled. - 'internal': Internal errors. Means some invariants expected by underlying system has been broken. If you see one of these errors, something is very broken. - 'unavailable': The service is currently unavailable. This is most likely a transient condition and may be corrected by retrying with a backoff. - 'data-loss': Unrecoverable data loss or corruption. - 'unauthenticated': The request does not have valid authentication credentials for the operation. | +| [FirestoreLocalCache](./firestore_.md#firestorelocalcache) | Union type from all supported SDK cache layer. | | [NestedUpdateFields](./firestore_.md#nestedupdatefields) | For each field (e.g. 'bar'), find all nested keys (e.g. {'bar.baz': T1, 'bar.qux': T2}). Intersect them together to make a single map containing all possible keys that are all marked as optional | | [OrderByDirection](./firestore_.md#orderbydirection) | The direction of a [orderBy()](./firestore_.md#orderby) clause is specified as 'desc' or 'asc' (descending or ascending). | | [PartialWithFieldValue](./firestore_.md#partialwithfieldvalue) | Similar to Typescript's Partial<T>, but allows nested fields to be omitted and FieldValues to be passed in as property values. | +| [PersistentTabManager](./firestore_.md#persistenttabmanager) | A union of all avaialbe tab managers. | | [Primitive](./firestore_.md#primitive) | Primitive types. | | [QueryConstraintType](./firestore_.md#queryconstrainttype) | Describes the different query constraints available in this SDK. | | [QueryFilterConstraint](./firestore_.md#queryfilterconstraint) | QueryFilterConstraint is a helper union type that represents [QueryFieldFilterConstraint](./firestore_.queryfieldfilterconstraint.md#queryfieldfilterconstraint_class) and [QueryCompositeFilterConstraint](./firestore_.querycompositefilterconstraint.md#querycompositefilterconstraint_class). | @@ -386,6 +399,11 @@ If the final path has an odd number of segments and does not point to a document ## enableIndexedDbPersistence() +> Warning: This API is now obsolete. +> +> This function will be removed in a future major release. Instead, set `FirestoreSettings.cache` to an instance of `IndexedDbLocalCache` to turn on IndexedDb cache. Calling this function when `FirestoreSettings.cache` is already specified will throw an exception. +> + Attempts to enable persistent storage, if possible. Must be called before any other functions (other than [initializeFirestore()](./firestore_.md#initializefirestore), [getFirestore()](./firestore_.md#getfirestore) or [clearIndexedDbPersistence()](./firestore_.md#clearindexeddbpersistence). @@ -417,6 +435,11 @@ A `Promise` that represents successfully enabling persistent storage. ## enableMultiTabIndexedDbPersistence() +> Warning: This API is now obsolete. +> +> This function will be removed in a future major release. Instead, set `FirestoreSettings.cache` to an instance of `IndexedDbLocalCache` to turn on indexeddb cache. Calling this function when `FirestoreSettings.cache` is already specified will throw an exception. +> + Attempts to enable multi-tab persistent storage, if possible. If enabled across all tabs, all operations share access to local persistence, including shared execution of queries and latency-compensated local document updates across all connected instances. If this fails, `enableMultiTabIndexedDbPersistence()` will reject the promise it returns. Note that even after this failure, the [Firestore](./firestore_.firestore.md#firestore_class) instance will remain usable, however offline persistence will be disabled. @@ -602,7 +625,7 @@ Configures indexing for local query execution. Any previous index configuration The index entries themselves are created asynchronously. You can continue to use queries that require indexing even if the indices are not yet available. Query execution will automatically start using the index once the index entries have been written. -Indexes are only supported with IndexedDb persistence. Invoke either `enableIndexedDbPersistence()` or `enableMultiTabIndexedDbPersistence()` before setting an index configuration. If IndexedDb is not enabled, any index configuration is ignored. +Indexes are only supported with IndexedDb persistence. If IndexedDb is not enabled, any index configuration is ignored. Signature: @@ -784,6 +807,32 @@ export declare function getFirestore(): Firestore; The [Firestore](./firestore_.firestore.md#firestore_class) instance of the provided app. +## memoryLocalCache() + +Creates an instance of `MemoryLocalCache`. The instance can be set to `FirestoreSettings.cache` to tell the SDK which cache layer to use. + +Signature: + +```typescript +export declare function memoryLocalCache(): MemoryLocalCache; +``` +Returns: + +[MemoryLocalCache](./firestore_.memorylocalcache.md#memorylocalcache_interface) + +## persistentMultipleTabManager() + +Creates an instance of `PersistentMultipleTabManager`. + +Signature: + +```typescript +export declare function persistentMultipleTabManager(): PersistentMultipleTabManager; +``` +Returns: + +[PersistentMultipleTabManager](./firestore_.persistentmultipletabmanager.md#persistentmultipletabmanager_interface) + ## serverTimestamp() Returns a sentinel used with [setDoc()](./firestore_lite.md#setdoc) or [updateDoc()](./firestore_lite.md#updatedoc) to include a server-generated timestamp in the written data. @@ -1905,6 +1954,46 @@ Promise<void> A `Promise` resolved once the data has been successfully written to the backend (note that it won't resolve while you're offline). +## persistentLocalCache() + +Creates an instance of `PersistentLocalCache`. The instance can be set to `FirestoreSettings.cache` to tell the SDK which cache layer to use. + +Signature: + +```typescript +export declare function persistentLocalCache(settings?: PersistentCacheSettings): PersistentLocalCache; +``` + +### Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| settings | [PersistentCacheSettings](./firestore_.persistentcachesettings.md#persistentcachesettings_interface) | | + +Returns: + +[PersistentLocalCache](./firestore_.persistentlocalcache.md#persistentlocalcache_interface) + +## persistentSingleTabManager() + +Creates an instance of `PersistentSingleTabManager`. + +Signature: + +```typescript +export declare function persistentSingleTabManager(settings: PersistentSingleTabManagerSettings | undefined): PersistentSingleTabManager; +``` + +### Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| settings | [PersistentSingleTabManagerSettings](./firestore_.persistentsingletabmanagersettings.md#persistentsingletabmanagersettings_interface) \| undefined | Configures the created tab manager. | + +Returns: + +[PersistentSingleTabManager](./firestore_.persistentsingletabmanager.md#persistentsingletabmanager_interface) + ## endAt() Creates a [QueryEndAtConstraint](./firestore_.queryendatconstraint.md#queryendatconstraint_class) that modifies the result set to end at the provided document (inclusive). The end position is relative to the order of the query. The document must contain all of the fields provided in the orderBy of the query. @@ -2073,6 +2162,16 @@ Possible values: - 'cancelled': The operation was cancelled (typically by the ca export declare type FirestoreErrorCode = 'cancelled' | 'unknown' | 'invalid-argument' | 'deadline-exceeded' | 'not-found' | 'already-exists' | 'permission-denied' | 'resource-exhausted' | 'failed-precondition' | 'aborted' | 'out-of-range' | 'unimplemented' | 'internal' | 'unavailable' | 'data-loss' | 'unauthenticated'; ``` +## FirestoreLocalCache + +Union type from all supported SDK cache layer. + +Signature: + +```typescript +export declare type FirestoreLocalCache = MemoryLocalCache | PersistentLocalCache; +``` + ## NestedUpdateFields For each field (e.g. 'bar'), find all nested keys (e.g. {'bar.baz': T1, 'bar.qux': T2}). Intersect them together to make a single map containing all possible keys that are all marked as optional @@ -2107,6 +2206,16 @@ export declare type PartialWithFieldValue = Partial | (T extends Primitive } : never); ``` +## PersistentTabManager + +A union of all avaialbe tab managers. + +Signature: + +```typescript +export declare type PersistentTabManager = PersistentSingleTabManager | PersistentMultipleTabManager; +``` + ## Primitive Primitive types. diff --git a/docs-devsite/firestore_.memorylocalcache.md b/docs-devsite/firestore_.memorylocalcache.md new file mode 100644 index 00000000000..92b7d3a2c72 --- /dev/null +++ b/docs-devsite/firestore_.memorylocalcache.md @@ -0,0 +1,35 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# MemoryLocalCache interface +Provides an in-memory cache to the SDK. This is the default cache unless explicitly configured otherwise. + +To use, create an instance using the factory function , then set the instance to `FirestoreSettings.cache` and call `initializeFirestore` using the settings object. + +Signature: + +```typescript +export declare interface MemoryLocalCache +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [kind](./firestore_.memorylocalcache.md#memorylocalcachekind) | 'memory' | | + +## MemoryLocalCache.kind + +Signature: + +```typescript +kind: 'memory'; +``` diff --git a/docs-devsite/firestore_.persistentcachesettings.md b/docs-devsite/firestore_.persistentcachesettings.md new file mode 100644 index 00000000000..dd491918894 --- /dev/null +++ b/docs-devsite/firestore_.persistentcachesettings.md @@ -0,0 +1,48 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# PersistentCacheSettings interface +An settings object to configure an `PersistentLocalCache` instance. + +Signature: + +```typescript +export declare interface PersistentCacheSettings +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [cacheSizeBytes](./firestore_.persistentcachesettings.md#persistentcachesettingscachesizebytes) | number | An approximate cache size threshold for the on-disk data. If the cache grows beyond this size, Firestore will start removing data that hasn't been recently used. The SDK does not guarantee that the cache will stay below that size, only that if the cache exceeds the given size, cleanup will be attempted.The default value is 40 MB. The threshold must be set to at least 1 MB, and can be set to CACHE_SIZE_UNLIMITED to disable garbage collection. | +| [tabManager](./firestore_.persistentcachesettings.md#persistentcachesettingstabmanager) | [PersistentTabManager](./firestore_.md#persistenttabmanager) | Specifies how multiple tabs/windows will be managed by the SDK. | + +## PersistentCacheSettings.cacheSizeBytes + +An approximate cache size threshold for the on-disk data. If the cache grows beyond this size, Firestore will start removing data that hasn't been recently used. The SDK does not guarantee that the cache will stay below that size, only that if the cache exceeds the given size, cleanup will be attempted. + +The default value is 40 MB. The threshold must be set to at least 1 MB, and can be set to `CACHE_SIZE_UNLIMITED` to disable garbage collection. + +Signature: + +```typescript +cacheSizeBytes?: number; +``` + +## PersistentCacheSettings.tabManager + +Specifies how multiple tabs/windows will be managed by the SDK. + +Signature: + +```typescript +tabManager?: PersistentTabManager; +``` diff --git a/docs-devsite/firestore_.persistentlocalcache.md b/docs-devsite/firestore_.persistentlocalcache.md new file mode 100644 index 00000000000..48d876d15bd --- /dev/null +++ b/docs-devsite/firestore_.persistentlocalcache.md @@ -0,0 +1,35 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# PersistentLocalCache interface +Provides a persistent cache backed by IndexedDb to the SDK. + +To use, create an instance using the factory function , then set the instance to `FirestoreSettings.cache` and call `initializeFirestore` using the settings object. + +Signature: + +```typescript +export declare interface PersistentLocalCache +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [kind](./firestore_.persistentlocalcache.md#persistentlocalcachekind) | 'persistent' | | + +## PersistentLocalCache.kind + +Signature: + +```typescript +kind: 'persistent'; +``` diff --git a/docs-devsite/firestore_.persistentmultipletabmanager.md b/docs-devsite/firestore_.persistentmultipletabmanager.md new file mode 100644 index 00000000000..b0c21b378a1 --- /dev/null +++ b/docs-devsite/firestore_.persistentmultipletabmanager.md @@ -0,0 +1,33 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# PersistentMultipleTabManager interface +A tab manager supportting multiple tabs. SDK will synchronize queries and mutations done across all tabs using the SDK. + +Signature: + +```typescript +export declare interface PersistentMultipleTabManager +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [kind](./firestore_.persistentmultipletabmanager.md#persistentmultipletabmanagerkind) | 'PersistentMultipleTab' | | + +## PersistentMultipleTabManager.kind + +Signature: + +```typescript +kind: 'PersistentMultipleTab'; +``` diff --git a/docs-devsite/firestore_.persistentsingletabmanager.md b/docs-devsite/firestore_.persistentsingletabmanager.md new file mode 100644 index 00000000000..ee130b6fc6a --- /dev/null +++ b/docs-devsite/firestore_.persistentsingletabmanager.md @@ -0,0 +1,33 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# PersistentSingleTabManager interface +A tab manager supportting only one tab, no synchronization will be performed across tabs. + +Signature: + +```typescript +export declare interface PersistentSingleTabManager +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [kind](./firestore_.persistentsingletabmanager.md#persistentsingletabmanagerkind) | 'persistentSingleTab' | | + +## PersistentSingleTabManager.kind + +Signature: + +```typescript +kind: 'persistentSingleTab'; +``` diff --git a/docs-devsite/firestore_.persistentsingletabmanagersettings.md b/docs-devsite/firestore_.persistentsingletabmanagersettings.md new file mode 100644 index 00000000000..de5ddc71b5c --- /dev/null +++ b/docs-devsite/firestore_.persistentsingletabmanagersettings.md @@ -0,0 +1,35 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# PersistentSingleTabManagerSettings interface +Type to configure an `PersistentSingleTabManager` instace. + +Signature: + +```typescript +export declare interface PersistentSingleTabManagerSettings +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [forceOwnership](./firestore_.persistentsingletabmanagersettings.md#persistentsingletabmanagersettingsforceownership) | boolean | Whether to force-enable persistent (IndexedDB) cache for the client. This cannot be used with multi-tab synchronization and is primarily intended for use with Web Workers. Setting this to true will enable IndexedDB, but cause other tabs using IndexedDB cache to fail. | + +## PersistentSingleTabManagerSettings.forceOwnership + +Whether to force-enable persistent (IndexedDB) cache for the client. This cannot be used with multi-tab synchronization and is primarily intended for use with Web Workers. Setting this to `true` will enable IndexedDB, but cause other tabs using IndexedDB cache to fail. + +Signature: + +```typescript +forceOwnership?: boolean; +``` diff --git a/packages/firestore/src/api.ts b/packages/firestore/src/api.ts index 93da0b1ee08..807e5dcd647 100644 --- a/packages/firestore/src/api.ts +++ b/packages/firestore/src/api.ts @@ -34,6 +34,21 @@ export { AggregateType } from './lite-api/aggregate_types'; +export { + FirestoreLocalCache, + PersistentLocalCache, + PersistentMultipleTabManager, + persistentLocalCache, + persistentMultipleTabManager, + PersistentCacheSettings, + persistentSingleTabManager, + PersistentSingleTabManager, + PersistentSingleTabManagerSettings, + MemoryLocalCache, + memoryLocalCache, + PersistentTabManager +} from './api/cache_config'; + export { FieldPath, documentId } from './api/field_path'; export { diff --git a/packages/firestore/src/api/cache_config.ts b/packages/firestore/src/api/cache_config.ts new file mode 100644 index 00000000000..a6e05bc6d7f --- /dev/null +++ b/packages/firestore/src/api/cache_config.ts @@ -0,0 +1,302 @@ +/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + IndexedDbOfflineComponentProvider, + MemoryOfflineComponentProvider, + MultiTabOfflineComponentProvider, + OfflineComponentProvider, + OnlineComponentProvider +} from '../core/component_provider'; + +/* eslint @typescript-eslint/consistent-type-definitions: ["error", "type"] */ +/** + * Provides an in-memory cache to the SDK. This is the default cache unless explicitly + * configured otherwise. + * + * To use, create an instance using the factory function {@link memoryLocalCache()}, then + * set the instance to `FirestoreSettings.cache` and call `initializeFirestore` using + * the settings object. + */ +export type MemoryLocalCache = { + kind: 'memory'; + /** + * @internal + */ + _onlineComponentProvider: OnlineComponentProvider; + /** + * @internal + */ + _offlineComponentProvider: MemoryOfflineComponentProvider; +}; + +class MemoryLocalCacheImpl implements MemoryLocalCache { + kind: 'memory' = 'memory'; + /** + * @internal + */ + _onlineComponentProvider: OnlineComponentProvider; + /** + * @internal + */ + _offlineComponentProvider: MemoryOfflineComponentProvider; + + constructor() { + this._onlineComponentProvider = new OnlineComponentProvider(); + this._offlineComponentProvider = new MemoryOfflineComponentProvider(); + } + + toJSON(): {} { + return { kind: this.kind }; + } +} + +/** + * Provides a persistent cache backed by IndexedDb to the SDK. + * + * To use, create an instance using the factory function {@link persistentLocalCache()}, then + * set the instance to `FirestoreSettings.cache` and call `initializeFirestore` using + * the settings object. + */ +export type PersistentLocalCache = { + kind: 'persistent'; + /** + * @internal + */ + _onlineComponentProvider: OnlineComponentProvider; + /** + * @internal + */ + _offlineComponentProvider: OfflineComponentProvider; +}; + +class PersistentLocalCacheImpl implements PersistentLocalCache { + kind: 'persistent' = 'persistent'; + /** + * @internal + */ + _onlineComponentProvider: OnlineComponentProvider; + /** + * @internal + */ + _offlineComponentProvider: OfflineComponentProvider; + + constructor(settings: PersistentCacheSettings | undefined) { + let tabManager: PersistentTabManager; + if (settings?.tabManager) { + settings.tabManager._initialize(settings); + tabManager = settings.tabManager; + } else { + tabManager = persistentSingleTabManager(undefined); + tabManager._initialize(settings); + } + this._onlineComponentProvider = tabManager._onlineComponentProvider!; + this._offlineComponentProvider = tabManager._offlineComponentProvider!; + } + + toJSON(): {} { + return { kind: this.kind }; + } +} + +/** + * Union type from all supported SDK cache layer. + */ +export type FirestoreLocalCache = MemoryLocalCache | PersistentLocalCache; + +/** + * Creates an instance of `MemoryLocalCache`. The instance can be set to + * `FirestoreSettings.cache` to tell the SDK which cache layer to use. + */ +export function memoryLocalCache(): MemoryLocalCache { + return new MemoryLocalCacheImpl(); +} + +/** + * An settings object to configure an `PersistentLocalCache` instance. + */ +export type PersistentCacheSettings = { + /** + * An approximate cache size threshold for the on-disk data. If the cache + * grows beyond this size, Firestore will start removing data that hasn't been + * recently used. The SDK does not guarantee that the cache will stay below + * that size, only that if the cache exceeds the given size, cleanup will be + * attempted. + * + * The default value is 40 MB. The threshold must be set to at least 1 MB, and + * can be set to `CACHE_SIZE_UNLIMITED` to disable garbage collection. + */ + cacheSizeBytes?: number; + + /** + * Specifies how multiple tabs/windows will be managed by the SDK. + */ + tabManager?: PersistentTabManager; +}; + +/** + * Creates an instance of `PersistentLocalCache`. The instance can be set to + * `FirestoreSettings.cache` to tell the SDK which cache layer to use. + */ +export function persistentLocalCache( + settings?: PersistentCacheSettings +): PersistentLocalCache { + return new PersistentLocalCacheImpl(settings); +} + +/** + * A tab manager supportting only one tab, no synchronization will be + * performed across tabs. + */ +export type PersistentSingleTabManager = { + kind: 'persistentSingleTab'; + /** + * @internal + */ + _initialize: ( + settings: Omit | undefined + ) => void; + /** + * @internal + */ + _onlineComponentProvider?: OnlineComponentProvider; + /** + * @internal + */ + _offlineComponentProvider?: OfflineComponentProvider; +}; + +class SingleTabManagerImpl implements PersistentSingleTabManager { + kind: 'persistentSingleTab' = 'persistentSingleTab'; + + /** + * @internal + */ + _onlineComponentProvider?: OnlineComponentProvider; + /** + * @internal + */ + _offlineComponentProvider?: OfflineComponentProvider; + + constructor(private forceOwnership?: boolean) {} + + toJSON(): {} { + return { kind: this.kind }; + } + + /** + * @internal + */ + _initialize( + settings: Omit | undefined + ): void { + this._onlineComponentProvider = new OnlineComponentProvider(); + this._offlineComponentProvider = new IndexedDbOfflineComponentProvider( + this._onlineComponentProvider, + settings?.cacheSizeBytes, + this.forceOwnership + ); + } +} + +/** + * A tab manager supportting multiple tabs. SDK will synchronize queries and + * mutations done across all tabs using the SDK. + */ +export type PersistentMultipleTabManager = { + kind: 'PersistentMultipleTab'; + /** + * @internal + */ + _initialize: (settings: Omit) => void; + /** + * @internal + */ + _onlineComponentProvider?: OnlineComponentProvider; + /** + * @internal + */ + + _offlineComponentProvider?: OfflineComponentProvider; +}; + +class MultiTabManagerImpl implements PersistentMultipleTabManager { + kind: 'PersistentMultipleTab' = 'PersistentMultipleTab'; + + /** + * @internal + */ + _onlineComponentProvider?: OnlineComponentProvider; + /** + * @internal + */ + _offlineComponentProvider?: OfflineComponentProvider; + + toJSON(): {} { + return { kind: this.kind }; + } + + /** + * @internal + */ + _initialize( + settings: Omit | undefined + ): void { + this._onlineComponentProvider = new OnlineComponentProvider(); + this._offlineComponentProvider = new MultiTabOfflineComponentProvider( + this._onlineComponentProvider, + settings?.cacheSizeBytes + ); + } +} + +/** + * A union of all avaialbe tab managers. + */ +export type PersistentTabManager = + | PersistentSingleTabManager + | PersistentMultipleTabManager; + +/** + * Type to configure an `PersistentSingleTabManager` instace. + */ +export type PersistentSingleTabManagerSettings = { + /** + * Whether to force-enable persistent (IndexedDB) cache for the client. This + * cannot be used with multi-tab synchronization and is primarily intended for + * use with Web Workers. Setting this to `true` will enable IndexedDB, but cause + * other tabs using IndexedDB cache to fail. + */ + forceOwnership?: boolean; +}; +/** + * Creates an instance of `PersistentSingleTabManager`. + * + * @param settings Configures the created tab manager. + */ +export function persistentSingleTabManager( + settings: PersistentSingleTabManagerSettings | undefined +): PersistentSingleTabManager { + return new SingleTabManagerImpl(settings?.forceOwnership); +} + +/** + * Creates an instance of `PersistentMultipleTabManager`. + */ +export function persistentMultipleTabManager(): PersistentMultipleTabManager { + return new MultiTabManagerImpl(); +} diff --git a/packages/firestore/src/api/database.ts b/packages/firestore/src/api/database.ts index 29cca7e68ca..93aab4880d9 100644 --- a/packages/firestore/src/api/database.ts +++ b/packages/firestore/src/api/database.ts @@ -32,6 +32,7 @@ import { } from '../core/component_provider'; import { DatabaseId, DEFAULT_DATABASE_NAME } from '../core/database_info'; import { + canFallbackFromIndexedDbError, FirestoreClient, firestoreClientDisableNetwork, firestoreClientEnableNetwork, @@ -75,11 +76,6 @@ declare module '@firebase/component' { } } -/** DOMException error code constants. */ -const DOM_EXCEPTION_INVALID_STATE = 11; -const DOM_EXCEPTION_ABORTED = 20; -const DOM_EXCEPTION_QUOTA_EXCEEDED = 22; - /** * Constant used to indicate the LRU garbage collection should be disabled. * Set this value as the `cacheSizeBytes` on the settings passed to the @@ -171,6 +167,17 @@ export function initializeFirestore( } } + if ( + settings.cacheSizeBytes !== undefined && + settings.localCache !== undefined + ) { + throw new FirestoreError( + Code.INVALID_ARGUMENT, + `cache and cacheSizeBytes cannot be specified at the same time as cacheSizeBytes will` + + `be deprecated. Instead, specify the cache size in the cache object` + ); + } + if ( settings.cacheSizeBytes !== undefined && settings.cacheSizeBytes !== CACHE_SIZE_UNLIMITED && @@ -283,6 +290,16 @@ export function configureFirestore(firestore: Firestore): void { firestore._queue, databaseInfo ); + if ( + settings.cache?._offlineComponentProvider && + settings.cache?._onlineComponentProvider + ) { + firestore._firestoreClient._uninitializedComponentsProvider = { + _offlineKind: settings.cache.kind, + _offline: settings.cache._offlineComponentProvider, + _online: settings.cache._onlineComponentProvider + }; + } } /** @@ -307,6 +324,10 @@ export function configureFirestore(firestore: Firestore): void { * @param persistenceSettings - Optional settings object to configure * persistence. * @returns A `Promise` that represents successfully enabling persistent storage. + * @deprecated This function will be removed in a future major release. Instead, set + * `FirestoreSettings.cache` to an instance of `IndexedDbLocalCache` to + * turn on IndexedDb cache. Calling this function when `FirestoreSettings.cache` + * is already specified will throw an exception. */ export function enableIndexedDbPersistence( firestore: Firestore, @@ -316,6 +337,17 @@ export function enableIndexedDbPersistence( verifyNotInitialized(firestore); const client = ensureFirestoreConfigured(firestore); + if (client._uninitializedComponentsProvider) { + throw new FirestoreError( + Code.FAILED_PRECONDITION, + 'SDK cache is already specified.' + ); + } + + logWarn( + 'enableIndexedDbPersistence() will be deprecated in the future, ' + + 'you can use `FirestoreSettings.cache` instead.' + ); const settings = firestore._freezeSettings(); const onlineComponentProvider = new OnlineComponentProvider(); @@ -352,6 +384,10 @@ export function enableIndexedDbPersistence( * @param firestore - The {@link Firestore} instance to enable persistence for. * @returns A `Promise` that represents successfully enabling persistent * storage. + * @deprecated This function will be removed in a future major release. Instead, set + * `FirestoreSettings.cache` to an instance of `IndexedDbLocalCache` to + * turn on indexeddb cache. Calling this function when `FirestoreSettings.cache` + * is already specified will throw an exception. */ export function enableMultiTabIndexedDbPersistence( firestore: Firestore @@ -360,6 +396,17 @@ export function enableMultiTabIndexedDbPersistence( verifyNotInitialized(firestore); const client = ensureFirestoreConfigured(firestore); + if (client._uninitializedComponentsProvider) { + throw new FirestoreError( + Code.FAILED_PRECONDITION, + 'SDK cache is already specified.' + ); + } + + logWarn( + 'enableMultiTabIndexedDbPersistence() will be deprecated in the future, ' + + 'you can use `FirestoreSettings.cache` instead.' + ); const settings = firestore._freezeSettings(); const onlineComponentProvider = new OnlineComponentProvider(); @@ -398,8 +445,8 @@ function setPersistenceProviders( throw error; } logWarn( - 'Error enabling offline persistence. Falling back to ' + - 'persistence disabled: ' + + 'Error enabling indexeddb cache. Falling back to ' + + 'memory cache: ' + error ); persistenceResult.reject(error); @@ -408,44 +455,6 @@ function setPersistenceProviders( .then(() => persistenceResult.promise); } -/** - * Decides whether the provided error allows us to gracefully disable - * persistence (as opposed to crashing the client). - */ -function canFallbackFromIndexedDbError( - error: FirestoreError | DOMException -): boolean { - if (error.name === 'FirebaseError') { - return ( - error.code === Code.FAILED_PRECONDITION || - error.code === Code.UNIMPLEMENTED - ); - } else if ( - typeof DOMException !== 'undefined' && - error instanceof DOMException - ) { - // There are a few known circumstances where we can open IndexedDb but - // trying to read/write will fail (e.g. quota exceeded). For - // well-understood cases, we attempt to detect these and then gracefully - // fall back to memory persistence. - // NOTE: Rather than continue to add to this list, we could decide to - // always fall back, with the risk that we might accidentally hide errors - // representing actual SDK bugs. - return ( - // When the browser is out of quota we could get either quota exceeded - // or an aborted error depending on whether the error happened during - // schema migration. - error.code === DOM_EXCEPTION_QUOTA_EXCEEDED || - error.code === DOM_EXCEPTION_ABORTED || - // Firefox Private Browsing mode disables IndexedDb and returns - // INVALID_STATE for any usage. - error.code === DOM_EXCEPTION_INVALID_STATE - ); - } - - return true; -} - /** * Clears the persistent storage. This includes pending writes and cached * documents. diff --git a/packages/firestore/src/api/index_configuration.ts b/packages/firestore/src/api/index_configuration.ts index 9ea31a28db1..94754636176 100644 --- a/packages/firestore/src/api/index_configuration.ts +++ b/packages/firestore/src/api/index_configuration.ts @@ -15,9 +15,8 @@ * limitations under the License. */ -import { getLocalStore } from '../core/firestore_client'; +import { firestoreClientSetIndexConfiguration } from '../core/firestore_client'; import { fieldPathFromDotSeparatedString } from '../lite-api/user_data_reader'; -import { localStoreConfigureFieldIndexes } from '../local/local_store_impl'; import { FieldIndex, IndexKind, @@ -97,10 +96,8 @@ export interface IndexConfiguration { * Query execution will automatically start using the index once the index * entries have been written. * - * Indexes are only supported with IndexedDb persistence. Invoke either - * `enableIndexedDbPersistence()` or `enableMultiTabIndexedDbPersistence()` - * before setting an index configuration. If IndexedDb is not enabled, any - * index configuration is ignored. + * Indexes are only supported with IndexedDb persistence. If IndexedDb is not + * enabled, any index configuration is ignored. * * @param firestore - The {@link Firestore} instance to configure indexes for. * @param configuration -The index definition. @@ -151,17 +148,17 @@ export function setIndexConfiguration( ): Promise { firestore = cast(firestore, Firestore); const client = ensureFirestoreConfigured(firestore); - - // PORTING NOTE: We don't return an error if the user has not enabled - // persistence since `enableIndexeddbPersistence()` can fail on the Web. - if (!client.offlineComponents?.indexBackfillerScheduler) { + if ( + !client._uninitializedComponentsProvider || + client._uninitializedComponentsProvider?._offlineKind === 'memory' + ) { + // PORTING NOTE: We don't return an error if the user has not enabled + // persistence since `enableIndexeddbPersistence()` can fail on the Web. logWarn('Cannot enable indexes when persistence is disabled'); return Promise.resolve(); } const parsedIndexes = parseIndexes(jsonOrConfiguration); - return getLocalStore(client).then(localStore => - localStoreConfigureFieldIndexes(localStore, parsedIndexes) - ); + return firestoreClientSetIndexConfiguration(client, parsedIndexes); } export function parseIndexes( diff --git a/packages/firestore/src/api/settings.ts b/packages/firestore/src/api/settings.ts index f6e92854495..0a9dc9d7ebe 100644 --- a/packages/firestore/src/api/settings.ts +++ b/packages/firestore/src/api/settings.ts @@ -17,6 +17,8 @@ import { FirestoreSettings as LiteSettings } from '../lite-api/settings'; +import { FirestoreLocalCache } from './cache_config'; + export { DEFAULT_HOST } from '../lite-api/settings'; /** @@ -39,6 +41,9 @@ export interface PersistenceSettings { */ export interface FirestoreSettings extends LiteSettings { /** + * NOTE: This field will be deprecated in a future major release. Use `cache` field + * instead to specify cache size, and other cache configurations. + * * An approximate cache size threshold for the on-disk data. If the cache * grows beyond this size, Firestore will start removing data that hasn't been * recently used. The size is not a guarantee that the cache will stay below @@ -50,6 +55,18 @@ export interface FirestoreSettings extends LiteSettings { */ cacheSizeBytes?: number; + /** + * Specifies the cache used by the SDK. Availabe options are `MemoryLocalCache` + * and `IndexedDbLocalCache`, each with different configuration options. + * + * When unspecified, `MemoryLocalCache` will be used by default. + * + * NOTE: setting this field and `cacheSizeBytes` at the same time will throw + * exception during SDK initialization. Instead, using the configuration in + * the `FirestoreLocalCache` object to specify the cache size. + */ + localCache?: FirestoreLocalCache; + /** * Forces the SDK’s underlying network transport (WebChannel) to use * long-polling. Each response from the backend will be closed immediately diff --git a/packages/firestore/src/core/firestore_client.ts b/packages/firestore/src/core/firestore_client.ts index ae96b64fa6e..2d69b322db7 100644 --- a/packages/firestore/src/core/firestore_client.ts +++ b/packages/firestore/src/core/firestore_client.ts @@ -25,6 +25,7 @@ import { import { User } from '../auth/user'; import { LocalStore } from '../local/local_store'; import { + localStoreConfigureFieldIndexes, localStoreExecuteQuery, localStoreGetNamedQuery, localStoreHandleUserChange, @@ -33,6 +34,7 @@ import { import { Persistence } from '../local/persistence'; import { Document } from '../model/document'; import { DocumentKey } from '../model/document_key'; +import { FieldIndex } from '../model/field_index'; import { Mutation } from '../model/mutation'; import { ObjectValue } from '../model/object_value'; import { toByteStreamReader } from '../platform/byte_stream_reader'; @@ -53,7 +55,7 @@ import { AsyncQueue, wrapInUserErrorIfRecoverable } from '../util/async_queue'; import { BundleReader } from '../util/bundle_reader'; import { newBundleReader } from '../util/bundle_reader_impl'; import { Code, FirestoreError } from '../util/error'; -import { logDebug } from '../util/log'; +import { logDebug, logWarn } from '../util/log'; import { AutoId } from '../util/misc'; import { Deferred } from '../util/promise'; @@ -94,10 +96,15 @@ import { ViewSnapshot } from './view_snapshot'; const LOG_TAG = 'FirestoreClient'; export const MAX_CONCURRENT_LIMBO_RESOLUTIONS = 100; +/** DOMException error code constants. */ +const DOM_EXCEPTION_INVALID_STATE = 11; +const DOM_EXCEPTION_ABORTED = 20; +const DOM_EXCEPTION_QUOTA_EXCEEDED = 22; + /** - * FirestoreClient is a top-level class that constructs and owns all of the - * pieces of the client SDK architecture. It is responsible for creating the - * async queue that is shared by all of the other components in the system. + * FirestoreClient is a top-level class that constructs and owns all of the // + * pieces of the client SDK architecture. It is responsible for creating the // + * async queue that is shared by all of the other components in the system. // */ export class FirestoreClient { private user = User.UNAUTHENTICATED; @@ -108,9 +115,14 @@ export class FirestoreClient { appCheckToken: string, user: User ) => Promise = () => Promise.resolve(); + _uninitializedComponentsProvider?: { + _offline: OfflineComponentProvider; + _offlineKind: 'memory' | 'persistent'; + _online: OnlineComponentProvider; + }; - offlineComponents?: OfflineComponentProvider; - onlineComponents?: OnlineComponentProvider; + _offlineComponents?: OfflineComponentProvider; + _onlineComponents?: OnlineComponentProvider; constructor( private authCredentials: CredentialsProvider, @@ -160,8 +172,8 @@ export class FirestoreClient { } /** - * Checks that the client has not been terminated. Ensures that other methods on - * this class cannot be called after the client is terminated. + * Checks that the client has not been terminated. Ensures that other methods on // + * this class cannot be called after the client is terminated. // */ verifyNotTerminated(): void { if (this.asyncQueue.isShuttingDown) { @@ -177,11 +189,11 @@ export class FirestoreClient { const deferred = new Deferred(); this.asyncQueue.enqueueAndForgetEvenWhileRestricted(async () => { try { - if (this.onlineComponents) { - await this.onlineComponents.terminate(); + if (this._onlineComponents) { + await this._onlineComponents.terminate(); } - if (this.offlineComponents) { - await this.offlineComponents.terminate(); + if (this._offlineComponents) { + await this._offlineComponents.terminate(); } // The credentials provider must be terminated after shutting down the @@ -229,7 +241,7 @@ export async function setOfflineComponentProvider( client.terminate() ); - client.offlineComponents = offlineComponentProvider; + client._offlineComponents = offlineComponentProvider; } export async function setOnlineComponentProvider( @@ -254,32 +266,102 @@ export async function setOnlineComponentProvider( client.setAppCheckTokenChangeListener((_, user) => remoteStoreHandleCredentialChange(onlineComponentProvider.remoteStore, user) ); - client.onlineComponents = onlineComponentProvider; + client._onlineComponents = onlineComponentProvider; +} + +/** + * Decides whether the provided error allows us to gracefully disable + * persistence (as opposed to crashing the client). + */ +export function canFallbackFromIndexedDbError( + error: FirestoreError | DOMException +): boolean { + if (error.name === 'FirebaseError') { + return ( + error.code === Code.FAILED_PRECONDITION || + error.code === Code.UNIMPLEMENTED + ); + } else if ( + typeof DOMException !== 'undefined' && + error instanceof DOMException + ) { + // There are a few known circumstances where we can open IndexedDb but + // trying to read/write will fail (e.g. quota exceeded). For + // well-understood cases, we attempt to detect these and then gracefully + // fall back to memory persistence. + // NOTE: Rather than continue to add to this list, we could decide to + // always fall back, with the risk that we might accidentally hide errors + // representing actual SDK bugs. + return ( + // When the browser is out of quota we could get either quota exceeded + // or an aborted error depending on whether the error happened during + // schema migration. + error.code === DOM_EXCEPTION_QUOTA_EXCEEDED || + error.code === DOM_EXCEPTION_ABORTED || + // Firefox Private Browsing mode disables IndexedDb and returns + // INVALID_STATE for any usage. + error.code === DOM_EXCEPTION_INVALID_STATE + ); + } + + return true; } async function ensureOfflineComponents( client: FirestoreClient ): Promise { - if (!client.offlineComponents) { - logDebug(LOG_TAG, 'Using default OfflineComponentProvider'); - await setOfflineComponentProvider( - client, - new MemoryOfflineComponentProvider() - ); + if (!client._offlineComponents) { + if (client._uninitializedComponentsProvider) { + logDebug(LOG_TAG, 'Using user provided OfflineComponentProvider'); + try { + await setOfflineComponentProvider( + client, + client._uninitializedComponentsProvider._offline + ); + } catch (e) { + const error = e as FirestoreError | DOMException; + if (!canFallbackFromIndexedDbError(error)) { + throw error; + } + logWarn( + 'Error using user provided cache. Falling back to ' + + 'memory cache: ' + + error + ); + await setOfflineComponentProvider( + client, + new MemoryOfflineComponentProvider() + ); + } + } else { + logDebug(LOG_TAG, 'Using default OfflineComponentProvider'); + await setOfflineComponentProvider( + client, + new MemoryOfflineComponentProvider() + ); + } } - return client.offlineComponents!; + return client._offlineComponents!; } async function ensureOnlineComponents( client: FirestoreClient ): Promise { - if (!client.onlineComponents) { - logDebug(LOG_TAG, 'Using default OnlineComponentProvider'); - await setOnlineComponentProvider(client, new OnlineComponentProvider()); + if (!client._onlineComponents) { + if (client._uninitializedComponentsProvider) { + logDebug(LOG_TAG, 'Using user provided OnlineComponentProvider'); + await setOnlineComponentProvider( + client, + client._uninitializedComponentsProvider._online + ); + } else { + logDebug(LOG_TAG, 'Using default OnlineComponentProvider'); + await setOnlineComponentProvider(client, new OnlineComponentProvider()); + } } - return client.onlineComponents!; + return client._onlineComponents!; } function getPersistence(client: FirestoreClient): Promise { @@ -744,3 +826,15 @@ function createBundleReader( } return newBundleReader(toByteStreamReader(content), serializer); } + +export function firestoreClientSetIndexConfiguration( + client: FirestoreClient, + indexes: FieldIndex[] +): Promise { + return client.asyncQueue.enqueue(async () => { + return localStoreConfigureFieldIndexes( + await getLocalStore(client), + indexes + ); + }); +} diff --git a/packages/firestore/src/lite-api/settings.ts b/packages/firestore/src/lite-api/settings.ts index 3743cc344d0..5f395846720 100644 --- a/packages/firestore/src/lite-api/settings.ts +++ b/packages/firestore/src/lite-api/settings.ts @@ -15,6 +15,7 @@ * limitations under the License. */ +import { FirestoreLocalCache } from '../api/cache_config'; import { CredentialsSettings } from '../api/credentials'; import { LRU_COLLECTION_DISABLED, @@ -60,6 +61,8 @@ export interface PrivateSettings extends FirestoreSettings { experimentalAutoDetectLongPolling?: boolean; // Used in firestore@exp useFetchStreams?: boolean; + + localCache?: FirestoreLocalCache; } /** @@ -83,6 +86,7 @@ export class FirestoreSettingsImpl { readonly ignoreUndefinedProperties: boolean; readonly useFetchStreams: boolean; + readonly cache?: FirestoreLocalCache; // Can be a google-auth-library or gapi client. // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -105,6 +109,7 @@ export class FirestoreSettingsImpl { this.credentials = settings.credentials; this.ignoreUndefinedProperties = !!settings.ignoreUndefinedProperties; + this.cache = settings.localCache; if (settings.cacheSizeBytes === undefined) { this.cacheSizeBytes = LRU_DEFAULT_CACHE_SIZE_BYTES; diff --git a/packages/firestore/test/integration/api/database.test.ts b/packages/firestore/test/integration/api/database.test.ts index 5f3e2dc6c61..174048020e6 100644 --- a/packages/firestore/test/integration/api/database.test.ts +++ b/packages/firestore/test/integration/api/database.test.ts @@ -1214,6 +1214,7 @@ apiDescribe('Database', (persistence: boolean) => { 'cannot clear persistence if the client has been initialized', async () => { await withTestDoc(persistence, async (docRef, firestore) => { + await setDoc(docRef, {}); const expectedError = 'Persistence can only be cleared before a Firestore instance is ' + 'initialized or after it is terminated.'; diff --git a/packages/firestore/test/integration/api/provider.test.ts b/packages/firestore/test/integration/api/provider.test.ts index ffcd0e7f350..04a148bf987 100644 --- a/packages/firestore/test/integration/api/provider.test.ts +++ b/packages/firestore/test/integration/api/provider.test.ts @@ -25,7 +25,11 @@ import { initializeFirestore, Firestore, terminate, - getDoc + getDoc, + enableIndexedDbPersistence, + setDoc, + memoryLocalCache, + getDocFromCache } from '../util/firebase_export'; import { DEFAULT_SETTINGS } from '../util/settings'; @@ -120,6 +124,37 @@ describe('Firestore Provider', () => { expect(fs1).to.be.equal(fs2); }); + it('can still use enableIndexedDbPersistence()', async () => { + const app = initializeApp( + { apiKey: 'fake-api-key', projectId: 'test-project' }, + 'test-use-enablePersistence' + ); + const db = initializeFirestore(app, DEFAULT_SETTINGS); + // eslint-disable-next-line @typescript-eslint/no-floating-promises + expect(enableIndexedDbPersistence(db)).to.be.rejected; + + // SDK still functions. + // eslint-disable-next-line @typescript-eslint/no-floating-promises + setDoc(doc(db, 'coll/doc'), { field: 'foo' }); + expect((await getDocFromCache(doc(db, 'coll/doc'))).data()).to.deep.equal({ + field: 'foo' + }); + }); + + it('cannot mix enableIndexedDbPersistence() and settings.cache', async () => { + const app = initializeApp( + { apiKey: 'fake-api-key', projectId: 'test-project' }, + 'test-cannot-mix' + ); + const db = initializeFirestore(app, { + ...DEFAULT_SETTINGS, + localCache: memoryLocalCache() + }); + expect(() => enableIndexedDbPersistence(db)).to.throw( + 'SDK cache is already specified.' + ); + }); + it('cannot use once terminated', () => { const app = initializeApp( { apiKey: 'fake-api-key', projectId: 'test-project' }, diff --git a/packages/firestore/test/integration/api/validation.test.ts b/packages/firestore/test/integration/api/validation.test.ts index 8ec14d1ae3e..f422eb4ad07 100644 --- a/packages/firestore/test/integration/api/validation.test.ts +++ b/packages/firestore/test/integration/api/validation.test.ts @@ -240,9 +240,7 @@ apiDescribe('Validation:', (persistence: boolean) => { doc(db, 'foo/bar'); } expect(() => enableIndexedDbPersistence(db)).to.throw( - 'Firestore has already been started and persistence can no ' + - 'longer be enabled. You can only enable persistence before ' + - 'calling any other methods on a Firestore object.' + 'SDK cache is already specified.' ); } ); diff --git a/packages/firestore/test/integration/browser/indexeddb.test.ts b/packages/firestore/test/integration/browser/indexeddb.test.ts index a63d5178118..b00fd7fbb83 100644 --- a/packages/firestore/test/integration/browser/indexeddb.test.ts +++ b/packages/firestore/test/integration/browser/indexeddb.test.ts @@ -26,7 +26,7 @@ import { } from '../util/firebase_export'; import { isPersistenceAvailable, withTestDb } from '../util/helpers'; -describe('where persistence is unsupported, enablePersistence', () => { +describe('where indexeddb is not available: ', () => { // Only test on platforms where persistence is *not* available (e.g. Edge, // Node.JS). if (isPersistenceAvailable()) { @@ -61,4 +61,14 @@ describe('where persistence is unsupported, enablePersistence', () => { ); }); }); + + it('fails back to memory cache with initializeFirestore too', () => { + // withTestDb will fail the test if persistence is requested but it fails + // so we'll enable persistence here instead. + return withTestDb(/* persistence= */ true, db => { + // Do the set immediately without waiting on the promise. + const testDoc = doc(collection(db, 'test-collection')); + return setDoc(testDoc, { foo: 'bar' }); + }); + }); }); diff --git a/packages/firestore/test/integration/util/helpers.ts b/packages/firestore/test/integration/util/helpers.ts index 79dbacaafa0..2d579afeb5f 100644 --- a/packages/firestore/test/integration/util/helpers.ts +++ b/packages/firestore/test/integration/util/helpers.ts @@ -23,8 +23,8 @@ import { DocumentReference, Firestore, terminate, + persistentLocalCache, clearIndexedDbPersistence, - enableIndexedDbPersistence, CollectionReference, DocumentData, QuerySnapshot, @@ -184,10 +184,11 @@ export async function withTestDbsSettings( const dbs: Firestore[] = []; for (let i = 0; i < numDbs; i++) { - const db = newTestFirestore(newTestApp(projectId), settings); + const newSettings = { ...settings }; if (persistence) { - await enableIndexedDbPersistence(db); + newSettings.localCache = persistentLocalCache(); } + const db = newTestFirestore(newTestApp(projectId), newSettings); dbs.push(db); } @@ -218,10 +219,11 @@ export async function withNamedTestDbsOrSkipUnlessUsingEmulator( const app = newTestApp(DEFAULT_PROJECT_ID); const dbs: Firestore[] = []; for (const dbName of dbNames) { - const db = newTestFirestore(app, DEFAULT_SETTINGS, dbName); + const newSettings = { ...DEFAULT_SETTINGS }; if (persistence) { - await enableIndexedDbPersistence(db); + newSettings.localCache = persistentLocalCache(); } + const db = newTestFirestore(app, newSettings, dbName); dbs.push(db); } diff --git a/packages/firestore/test/unit/local/local_store_indexeddb.test.ts b/packages/firestore/test/unit/local/local_store_indexeddb.test.ts index f10fa13c1d7..530ca40b5e4 100644 --- a/packages/firestore/test/unit/local/local_store_indexeddb.test.ts +++ b/packages/firestore/test/unit/local/local_store_indexeddb.test.ts @@ -15,6 +15,7 @@ * limitations under the License. */ +import { isIndexedDBAvailable } from '@firebase/util'; import { expect } from 'chai'; import { serverTimestamp, Timestamp } from '../../../src'; @@ -188,6 +189,10 @@ class AsyncLocalStoreTester { } describe('LocalStore w/ IndexedDB Persistence (Non generic)', () => { + if (!isIndexedDBAvailable()) { + return; + } + let persistence: Persistence; let test: AsyncLocalStoreTester; From f8437f5f19461defb416b1d436b87173299ab881 Mon Sep 17 00:00:00 2001 From: wu-hui <53845758+wu-hui@users.noreply.github.com> Date: Wed, 15 Mar 2023 13:10:55 -0400 Subject: [PATCH 13/26] Enable bundle spec tests for ios (#7096) --- packages/firestore/test/unit/specs/bundle_spec.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firestore/test/unit/specs/bundle_spec.test.ts b/packages/firestore/test/unit/specs/bundle_spec.test.ts index 3efa1be4d63..51fb3c3970a 100644 --- a/packages/firestore/test/unit/specs/bundle_spec.test.ts +++ b/packages/firestore/test/unit/specs/bundle_spec.test.ts @@ -85,7 +85,7 @@ function bundleWithDocumentAndQuery( ); } -describeSpec('Bundles:', ['no-ios'], () => { +describeSpec('Bundles:', [], () => { specTest('Newer docs from bundles should overwrite cache', [], () => { const query1 = query('collection'); const docA = doc('collection/a', 1000, { value: 'a' }); From 715ee9bc4ed7e8cd92829c708708e8863082fe33 Mon Sep 17 00:00:00 2001 From: wu-hui <53845758+wu-hui@users.noreply.github.com> Date: Wed, 15 Mar 2023 13:27:12 -0400 Subject: [PATCH 14/26] Add a TODO (#7103) --- packages/firestore/src/local/local_store_impl.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/firestore/src/local/local_store_impl.ts b/packages/firestore/src/local/local_store_impl.ts index ae1760f5930..447a982e7ea 100644 --- a/packages/firestore/src/local/local_store_impl.ts +++ b/packages/firestore/src/local/local_store_impl.ts @@ -875,6 +875,10 @@ export async function localStoreNotifyLocalViewChanges( ); localStoreImpl.targetDataByTarget = localStoreImpl.targetDataByTarget.insert(targetId, updatedTargetData); + + // TODO(b/272564316): Apply the optimization done on other platforms. + // This is a problem for web because saving the updated targetData from + // non-primary client conflicts with what primary client saved. } } } From 8bad12dbe908b9b559904ffea3e46307734b08ad Mon Sep 17 00:00:00 2001 From: "Nhien (Ricky) Lam" <62775270+NhienLam@users.noreply.github.com> Date: Thu, 16 Mar 2023 10:10:18 -0700 Subject: [PATCH 15/26] Change _fail to use NETWORK_REQUEST_FAILED (#7125) * Change _fail to use NETWORK_REQUEST_FAILED * Add changeset * Check if network error is propagated in error message --- .changeset/sixty-buckets-repeat.md | 5 ++++ packages/auth/src/api/index.test.ts | 40 ++++++++++++++--------------- packages/auth/src/api/index.ts | 5 +++- 3 files changed, 29 insertions(+), 21 deletions(-) create mode 100644 .changeset/sixty-buckets-repeat.md diff --git a/.changeset/sixty-buckets-repeat.md b/.changeset/sixty-buckets-repeat.md new file mode 100644 index 00000000000..40591209839 --- /dev/null +++ b/.changeset/sixty-buckets-repeat.md @@ -0,0 +1,5 @@ +--- +'@firebase/auth': patch +--- + +Modify \_fail to use AuthErrorCode.NETWORK_REQUEST_FAILED diff --git a/packages/auth/src/api/index.test.ts b/packages/auth/src/api/index.test.ts index 579f6c5e8ad..af3b61610d2 100644 --- a/packages/auth/src/api/index.test.ts +++ b/packages/auth/src/api/index.test.ts @@ -308,26 +308,6 @@ describe('api/_performApiRequest', () => { }); }); - context('with non-Firebase Errors', () => { - afterEach(mockFetch.tearDown); - - it('should handle non-FirebaseErrors', async () => { - mockFetch.setUpWithOverride(() => { - return new Promise((_, reject) => reject(new Error('error'))); - }); - const promise = _performApiRequest( - auth, - HttpMethod.POST, - Endpoint.SIGN_UP, - request - ); - await expect(promise).to.be.rejectedWith( - FirebaseError, - 'auth/internal-error' - ); - }); - }); - context('with network issues', () => { afterEach(mockFetch.tearDown); @@ -365,6 +345,26 @@ describe('api/_performApiRequest', () => { expect(clock.clearTimeout).to.have.been.called; clock.restore(); }); + + it('should handle network failure', async () => { + mockFetch.setUpWithOverride(() => { + return new Promise((_, reject) => + reject(new Error('network error')) + ); + }); + const promise = _performApiRequest( + auth, + HttpMethod.POST, + Endpoint.SIGN_UP, + request + ); + await expect(promise) + .to.be.rejectedWith(FirebaseError, 'auth/network-request-failed') + .eventually.with.nested.property( + 'customData.message', + 'Error: network error' + ); + }); }); context('edgcase error mapping', () => { diff --git a/packages/auth/src/api/index.ts b/packages/auth/src/api/index.ts index 0194c43d9a5..6c9d775d243 100644 --- a/packages/auth/src/api/index.ts +++ b/packages/auth/src/api/index.ts @@ -181,7 +181,10 @@ export async function _performFetchWithErrorHandling( if (e instanceof FirebaseError) { throw e; } - _fail(auth, AuthErrorCode.INTERNAL_ERROR, { 'message': String(e) }); + // Changing this to a different error code will log user out when there is a network error + // because we treat any error other than NETWORK_REQUEST_FAILED as token is invalid. + // https://github.com/firebase/firebase-js-sdk/blob/4fbc73610d70be4e0852e7de63a39cb7897e8546/packages/auth/src/core/auth/auth_impl.ts#L309-L316 + _fail(auth, AuthErrorCode.NETWORK_REQUEST_FAILED, { 'message': String(e) }); } } From 1794678ac8f0e4a3efc26cc730e14124d4bc76cd Mon Sep 17 00:00:00 2001 From: Denver Coneybeare Date: Thu, 16 Mar 2023 14:25:34 -0400 Subject: [PATCH 16/26] firestore: verify DOMException exists before using it in when base64 decoding (#7130) --- .changeset/friendly-ads-yell.md | 6 ++++++ packages/firestore/src/platform/browser/base64.ts | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changeset/friendly-ads-yell.md diff --git a/.changeset/friendly-ads-yell.md b/.changeset/friendly-ads-yell.md new file mode 100644 index 00000000000..2da2f6dede1 --- /dev/null +++ b/.changeset/friendly-ads-yell.md @@ -0,0 +1,6 @@ +--- +'@firebase/firestore': patch +'firebase': patch +--- + +Check that DOMException exists before referencing it, to fix react-native, which was broken by https://github.com/firebase/firebase-js-sdk/pull/7019 in v9.17.2. diff --git a/packages/firestore/src/platform/browser/base64.ts b/packages/firestore/src/platform/browser/base64.ts index 4cbbfe6ced9..26235a36a19 100644 --- a/packages/firestore/src/platform/browser/base64.ts +++ b/packages/firestore/src/platform/browser/base64.ts @@ -22,7 +22,10 @@ export function decodeBase64(encoded: string): string { try { return atob(encoded); } catch (e) { - if (e instanceof DOMException) { + // Check that `DOMException` is defined before using it to avoid + // "ReferenceError: Property 'DOMException' doesn't exist" in react-native. + // (https://github.com/firebase/firebase-js-sdk/issues/7115) + if (typeof DOMException !== 'undefined' && e instanceof DOMException) { throw new Base64DecodeError('Invalid base64 string: ' + e); } else { throw e; From c3f3f619877e1098fcf0a3866311e0259a25f05b Mon Sep 17 00:00:00 2001 From: Google Open Source Bot <26440463+google-oss-bot@users.noreply.github.com> Date: Thu, 16 Mar 2023 14:16:37 -0700 Subject: [PATCH 17/26] Version Packages (#7123) Co-authored-by: github-actions[bot] --- .changeset/blue-eels-warn.md | 6 ------ .changeset/chilled-buckets-sneeze.md | 6 ------ .changeset/fluffy-seas-behave.md | 5 ----- .changeset/sweet-rats-compete.md | 6 ------ integration/compat-interop/package.json | 8 ++++---- integration/firebase/package.json | 2 +- integration/firestore/package.json | 4 ++-- integration/messaging/package.json | 2 +- packages/analytics-compat/package.json | 2 +- packages/analytics/package.json | 2 +- packages/app-check-compat/package.json | 2 +- packages/app-check/package.json | 2 +- packages/app-compat/CHANGELOG.md | 7 +++++++ packages/app-compat/package.json | 4 ++-- packages/app/CHANGELOG.md | 6 ++++++ packages/app/package.json | 2 +- packages/auth-compat/CHANGELOG.md | 7 +++++++ packages/auth-compat/package.json | 6 +++--- packages/auth/CHANGELOG.md | 6 ++++++ packages/auth/package.json | 4 ++-- packages/database-compat/package.json | 2 +- packages/database/package.json | 2 +- packages/firebase/CHANGELOG.md | 20 ++++++++++++++++++++ packages/firebase/package.json | 14 +++++++------- packages/firestore-compat/CHANGELOG.md | 7 +++++++ packages/firestore-compat/package.json | 6 +++--- packages/firestore/CHANGELOG.md | 12 ++++++++++++ packages/firestore/package.json | 8 ++++---- packages/functions-compat/package.json | 2 +- packages/functions/package.json | 2 +- packages/installations-compat/package.json | 2 +- packages/installations/package.json | 2 +- packages/messaging-compat/package.json | 2 +- packages/messaging/package.json | 2 +- packages/performance-compat/package.json | 2 +- packages/performance/package.json | 2 +- packages/remote-config-compat/package.json | 2 +- packages/remote-config/package.json | 2 +- packages/storage-compat/package.json | 4 ++-- packages/storage/package.json | 4 ++-- packages/template/package.json | 2 +- repo-scripts/size-analysis/package.json | 2 +- 42 files changed, 117 insertions(+), 75 deletions(-) delete mode 100644 .changeset/blue-eels-warn.md delete mode 100644 .changeset/chilled-buckets-sneeze.md delete mode 100644 .changeset/fluffy-seas-behave.md delete mode 100644 .changeset/sweet-rats-compete.md diff --git a/.changeset/blue-eels-warn.md b/.changeset/blue-eels-warn.md deleted file mode 100644 index 1e963c7e68e..00000000000 --- a/.changeset/blue-eels-warn.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@firebase/firestore': patch -'firebase': patch ---- - -Improved debug logging of networking abstractions diff --git a/.changeset/chilled-buckets-sneeze.md b/.changeset/chilled-buckets-sneeze.md deleted file mode 100644 index d485e384f70..00000000000 --- a/.changeset/chilled-buckets-sneeze.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@firebase/firestore': patch -'firebase': patch ---- - -Check navigator.userAgent, in addition to navigator.appVersion, when determining whether to work around an IndexedDb bug in Safari. diff --git a/.changeset/fluffy-seas-behave.md b/.changeset/fluffy-seas-behave.md deleted file mode 100644 index 073429be5d8..00000000000 --- a/.changeset/fluffy-seas-behave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@firebase/auth": patch ---- - -Explicitly set createdAt and lastLoginAt when cloning UserImpl diff --git a/.changeset/sweet-rats-compete.md b/.changeset/sweet-rats-compete.md deleted file mode 100644 index 46cf4a61ddf..00000000000 --- a/.changeset/sweet-rats-compete.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@firebase/firestore": minor -'firebase': minor ---- - -Add support for disjunctions in queries (OR queries). diff --git a/integration/compat-interop/package.json b/integration/compat-interop/package.json index 928d6cfd004..c64c27b5828 100644 --- a/integration/compat-interop/package.json +++ b/integration/compat-interop/package.json @@ -8,12 +8,12 @@ "test:debug": "karma start --browsers Chrome --auto-watch" }, "dependencies": { - "@firebase/app": "0.9.4", - "@firebase/app-compat": "0.2.4", + "@firebase/app": "0.9.5", + "@firebase/app-compat": "0.2.5", "@firebase/analytics": "0.9.4", "@firebase/analytics-compat": "0.2.4", - "@firebase/auth": "0.21.4", - "@firebase/auth-compat": "0.3.4", + "@firebase/auth": "0.21.5", + "@firebase/auth-compat": "0.3.5", "@firebase/functions": "0.9.4", "@firebase/functions-compat": "0.3.4", "@firebase/messaging": "0.12.4", diff --git a/integration/firebase/package.json b/integration/firebase/package.json index 4b1a38417ac..6d626452d21 100644 --- a/integration/firebase/package.json +++ b/integration/firebase/package.json @@ -7,7 +7,7 @@ "test:ci": "node ../../scripts/run_tests_in_ci.js -s test" }, "devDependencies": { - "firebase": "9.17.2", + "firebase": "9.18.0", "@types/chai": "4.3.4", "@types/mocha": "9.1.1", "chai": "4.3.7", diff --git a/integration/firestore/package.json b/integration/firestore/package.json index f81affb9d0e..82822838fe2 100644 --- a/integration/firestore/package.json +++ b/integration/firestore/package.json @@ -15,8 +15,8 @@ "test:memory:debug": "yarn build:memory; karma start --auto-watch --browsers Chrome" }, "dependencies": { - "@firebase/app": "0.9.4", - "@firebase/firestore": "3.8.4" + "@firebase/app": "0.9.5", + "@firebase/firestore": "3.9.0" }, "devDependencies": { "@types/mocha": "9.1.1", diff --git a/integration/messaging/package.json b/integration/messaging/package.json index 426cae8f075..cbf8cd3c7c3 100644 --- a/integration/messaging/package.json +++ b/integration/messaging/package.json @@ -9,7 +9,7 @@ "test:manual": "mocha --exit" }, "devDependencies": { - "firebase": "9.17.2", + "firebase": "9.18.0", "chai": "4.3.7", "chromedriver": "98.0.1", "express": "4.18.2", diff --git a/packages/analytics-compat/package.json b/packages/analytics-compat/package.json index a2d917e063f..0a6d79b9554 100644 --- a/packages/analytics-compat/package.json +++ b/packages/analytics-compat/package.json @@ -24,7 +24,7 @@ "@firebase/app-compat": "0.x" }, "devDependencies": { - "@firebase/app-compat": "0.2.4", + "@firebase/app-compat": "0.2.5", "rollup": "2.79.1", "@rollup/plugin-json": "4.1.0", "rollup-plugin-typescript2": "0.31.2", diff --git a/packages/analytics/package.json b/packages/analytics/package.json index db9245c8ffb..a454897b01e 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -48,7 +48,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app": "0.9.4", + "@firebase/app": "0.9.5", "rollup": "2.79.1", "@rollup/plugin-commonjs": "21.1.0", "@rollup/plugin-json": "4.1.0", diff --git a/packages/app-check-compat/package.json b/packages/app-check-compat/package.json index fb08cdbbc0e..ab0a4458409 100644 --- a/packages/app-check-compat/package.json +++ b/packages/app-check-compat/package.json @@ -44,7 +44,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app-compat": "0.2.4", + "@firebase/app-compat": "0.2.5", "rollup": "2.79.1", "@rollup/plugin-commonjs": "21.1.0", "@rollup/plugin-json": "4.1.0", diff --git a/packages/app-check/package.json b/packages/app-check/package.json index c08557700b6..94c1974990f 100644 --- a/packages/app-check/package.json +++ b/packages/app-check/package.json @@ -45,7 +45,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app": "0.9.4", + "@firebase/app": "0.9.5", "rollup": "2.79.1", "@rollup/plugin-commonjs": "21.1.0", "@rollup/plugin-json": "4.1.0", diff --git a/packages/app-compat/CHANGELOG.md b/packages/app-compat/CHANGELOG.md index 3ebb05d3da4..d6c87c586ed 100644 --- a/packages/app-compat/CHANGELOG.md +++ b/packages/app-compat/CHANGELOG.md @@ -1,5 +1,12 @@ # @firebase/app-compat +## 0.2.5 + +### Patch Changes + +- Updated dependencies []: + - @firebase/app@0.9.5 + ## 0.2.4 ### Patch Changes diff --git a/packages/app-compat/package.json b/packages/app-compat/package.json index d46a19a45ce..d8e916a13fb 100644 --- a/packages/app-compat/package.json +++ b/packages/app-compat/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/app-compat", - "version": "0.2.4", + "version": "0.2.5", "description": "The primary entrypoint to the Firebase JS SDK", "author": "Firebase (https://firebase.google.com/)", "main": "dist/index.cjs.js", @@ -40,7 +40,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@firebase/app": "0.9.4", + "@firebase/app": "0.9.5", "@firebase/util": "1.9.3", "@firebase/logger": "0.4.0", "@firebase/component": "0.6.4", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index fec4909d1a0..93dc61c41fd 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,11 @@ # @firebase/app +## 0.9.5 + +### Patch Changes + +- Update SDK_VERSION. + ## 0.9.4 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 463aa8bce44..6bea73e091a 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/app", - "version": "0.9.4", + "version": "0.9.5", "description": "The primary entrypoint to the Firebase JS SDK", "author": "Firebase (https://firebase.google.com/)", "main": "dist/index.cjs.js", diff --git a/packages/auth-compat/CHANGELOG.md b/packages/auth-compat/CHANGELOG.md index f389f1a0124..5dc40123e2c 100644 --- a/packages/auth-compat/CHANGELOG.md +++ b/packages/auth-compat/CHANGELOG.md @@ -1,5 +1,12 @@ # @firebase/auth-compat +## 0.3.5 + +### Patch Changes + +- Updated dependencies [[`e0b677e70`](https://github.com/firebase/firebase-js-sdk/commit/e0b677e70ed2fd9e488737c77ebe2fc65d3a0822)]: + - @firebase/auth@0.21.5 + ## 0.3.4 ### Patch Changes diff --git a/packages/auth-compat/package.json b/packages/auth-compat/package.json index 2253abb9007..030bbed1f6b 100644 --- a/packages/auth-compat/package.json +++ b/packages/auth-compat/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/auth-compat", - "version": "0.3.4", + "version": "0.3.5", "description": "FirebaseAuth compatibility package that uses API style compatible with Firebase@8 and prior versions", "author": "Firebase (https://firebase.google.com/)", "main": "dist/index.node.cjs.js", @@ -50,7 +50,7 @@ "@firebase/app-compat": "0.x" }, "dependencies": { - "@firebase/auth": "0.21.4", + "@firebase/auth": "0.21.5", "@firebase/auth-types": "0.12.0", "@firebase/component": "0.6.4", "@firebase/util": "1.9.3", @@ -59,7 +59,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app-compat": "0.2.4", + "@firebase/app-compat": "0.2.5", "@rollup/plugin-json": "4.1.0", "rollup": "2.79.1", "rollup-plugin-replace": "2.2.0", diff --git a/packages/auth/CHANGELOG.md b/packages/auth/CHANGELOG.md index f734331449f..027b6bce09c 100644 --- a/packages/auth/CHANGELOG.md +++ b/packages/auth/CHANGELOG.md @@ -1,5 +1,11 @@ # @firebase/auth +## 0.21.5 + +### Patch Changes + +- [`e0b677e70`](https://github.com/firebase/firebase-js-sdk/commit/e0b677e70ed2fd9e488737c77ebe2fc65d3a0822) [#7066](https://github.com/firebase/firebase-js-sdk/pull/7066) - Explicitly set createdAt and lastLoginAt when cloning UserImpl + ## 0.21.4 ### Patch Changes diff --git a/packages/auth/package.json b/packages/auth/package.json index 0f5ddf521bf..9eac3e524b4 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/auth", - "version": "0.21.4", + "version": "0.21.5", "description": "The Firebase Authenticaton component of the Firebase JS SDK.", "author": "Firebase (https://firebase.google.com/)", "main": "dist/node/index.js", @@ -118,7 +118,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app": "0.9.4", + "@firebase/app": "0.9.5", "@rollup/plugin-json": "4.1.0", "@rollup/plugin-strip": "2.1.0", "chromedriver": "98.0.1", diff --git a/packages/database-compat/package.json b/packages/database-compat/package.json index 1d9ffb23b3c..1b1066618ac 100644 --- a/packages/database-compat/package.json +++ b/packages/database-compat/package.json @@ -58,7 +58,7 @@ "tslib": "^2.1.0" }, "devDependencies": { - "@firebase/app-compat": "0.2.4", + "@firebase/app-compat": "0.2.5", "typescript": "4.7.4" }, "repository": { diff --git a/packages/database/package.json b/packages/database/package.json index 7b6b7bb4221..1ebd14ea6c5 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -57,7 +57,7 @@ "tslib": "^2.1.0" }, "devDependencies": { - "@firebase/app": "0.9.4", + "@firebase/app": "0.9.5", "rollup": "2.79.1", "rollup-plugin-typescript2": "0.31.2", "typescript": "4.7.4" diff --git a/packages/firebase/CHANGELOG.md b/packages/firebase/CHANGELOG.md index 5b745562e87..66ff15fac6e 100644 --- a/packages/firebase/CHANGELOG.md +++ b/packages/firebase/CHANGELOG.md @@ -1,5 +1,25 @@ # firebase +## 9.18.0 + +### Minor Changes + +- [`5ba524313`](https://github.com/firebase/firebase-js-sdk/commit/5ba524313bdeddb012c44b1b1161c9229396b195) [#7053](https://github.com/firebase/firebase-js-sdk/pull/7053) - Add support for disjunctions in queries (OR queries). + +### Patch Changes + +- [`e2bf2eca2`](https://github.com/firebase/firebase-js-sdk/commit/e2bf2eca21308670c73d6c642a88c06f0b87d44a) [#7076](https://github.com/firebase/firebase-js-sdk/pull/7076) - Improved debug logging of networking abstractions + +- [`5099f0f60`](https://github.com/firebase/firebase-js-sdk/commit/5099f0f60a5198b48942e8b2a574505432bdc213) [#6899](https://github.com/firebase/firebase-js-sdk/pull/6899) (fixes [#6509](https://github.com/firebase/firebase-js-sdk/issues/6509)) - Check navigator.userAgent, in addition to navigator.appVersion, when determining whether to work around an IndexedDb bug in Safari. + +- Updated dependencies [[`e2bf2eca2`](https://github.com/firebase/firebase-js-sdk/commit/e2bf2eca21308670c73d6c642a88c06f0b87d44a), [`5099f0f60`](https://github.com/firebase/firebase-js-sdk/commit/5099f0f60a5198b48942e8b2a574505432bdc213), [`e0b677e70`](https://github.com/firebase/firebase-js-sdk/commit/e0b677e70ed2fd9e488737c77ebe2fc65d3a0822), [`5ba524313`](https://github.com/firebase/firebase-js-sdk/commit/5ba524313bdeddb012c44b1b1161c9229396b195)]: + - @firebase/firestore@3.9.0 + - @firebase/app@0.9.5 + - @firebase/auth@0.21.5 + - @firebase/firestore-compat@0.3.5 + - @firebase/app-compat@0.2.5 + - @firebase/auth-compat@0.3.5 + ## 9.17.2 ### Patch Changes diff --git a/packages/firebase/package.json b/packages/firebase/package.json index 03643b024ff..d5d22508b11 100644 --- a/packages/firebase/package.json +++ b/packages/firebase/package.json @@ -1,6 +1,6 @@ { "name": "firebase", - "version": "9.17.2", + "version": "9.18.0", "description": "Firebase JavaScript library for web and Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", @@ -373,15 +373,15 @@ "test:ci": "echo 'No test suite for firebase wrapper'" }, "dependencies": { - "@firebase/app": "0.9.4", - "@firebase/app-compat": "0.2.4", + "@firebase/app": "0.9.5", + "@firebase/app-compat": "0.2.5", "@firebase/app-types": "0.9.0", - "@firebase/auth": "0.21.4", - "@firebase/auth-compat": "0.3.4", + "@firebase/auth": "0.21.5", + "@firebase/auth-compat": "0.3.5", "@firebase/database": "0.14.4", "@firebase/database-compat": "0.3.4", - "@firebase/firestore": "3.8.4", - "@firebase/firestore-compat": "0.3.4", + "@firebase/firestore": "3.9.0", + "@firebase/firestore-compat": "0.3.5", "@firebase/functions": "0.9.4", "@firebase/functions-compat": "0.3.4", "@firebase/installations": "0.6.4", diff --git a/packages/firestore-compat/CHANGELOG.md b/packages/firestore-compat/CHANGELOG.md index f17a107ddc9..2b1f69b230b 100644 --- a/packages/firestore-compat/CHANGELOG.md +++ b/packages/firestore-compat/CHANGELOG.md @@ -1,5 +1,12 @@ # @firebase/firestore-compat +## 0.3.5 + +### Patch Changes + +- Updated dependencies [[`e2bf2eca2`](https://github.com/firebase/firebase-js-sdk/commit/e2bf2eca21308670c73d6c642a88c06f0b87d44a), [`5099f0f60`](https://github.com/firebase/firebase-js-sdk/commit/5099f0f60a5198b48942e8b2a574505432bdc213), [`5ba524313`](https://github.com/firebase/firebase-js-sdk/commit/5ba524313bdeddb012c44b1b1161c9229396b195)]: + - @firebase/firestore@3.9.0 + ## 0.3.4 ### Patch Changes diff --git a/packages/firestore-compat/package.json b/packages/firestore-compat/package.json index 87eccd2eb0a..31a45517c5e 100644 --- a/packages/firestore-compat/package.json +++ b/packages/firestore-compat/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/firestore-compat", - "version": "0.3.4", + "version": "0.3.5", "description": "The Cloud Firestore component of the Firebase JS SDK.", "author": "Firebase (https://firebase.google.com/)", "main": "dist/index.node.cjs.js", @@ -48,13 +48,13 @@ }, "dependencies": { "@firebase/component": "0.6.4", - "@firebase/firestore": "3.8.4", + "@firebase/firestore": "3.9.0", "@firebase/util": "1.9.3", "@firebase/firestore-types": "2.5.1", "tslib": "^2.1.0" }, "devDependencies": { - "@firebase/app-compat": "0.2.4", + "@firebase/app-compat": "0.2.5", "@types/eslint": "7.29.0", "rollup": "2.79.1", "rollup-plugin-sourcemaps": "0.6.3", diff --git a/packages/firestore/CHANGELOG.md b/packages/firestore/CHANGELOG.md index 787be89b251..5999b6468ee 100644 --- a/packages/firestore/CHANGELOG.md +++ b/packages/firestore/CHANGELOG.md @@ -1,5 +1,17 @@ # @firebase/firestore +## 3.9.0 + +### Minor Changes + +- [`5ba524313`](https://github.com/firebase/firebase-js-sdk/commit/5ba524313bdeddb012c44b1b1161c9229396b195) [#7053](https://github.com/firebase/firebase-js-sdk/pull/7053) - Add support for disjunctions in queries (OR queries). + +### Patch Changes + +- [`e2bf2eca2`](https://github.com/firebase/firebase-js-sdk/commit/e2bf2eca21308670c73d6c642a88c06f0b87d44a) [#7076](https://github.com/firebase/firebase-js-sdk/pull/7076) - Improved debug logging of networking abstractions + +- [`5099f0f60`](https://github.com/firebase/firebase-js-sdk/commit/5099f0f60a5198b48942e8b2a574505432bdc213) [#6899](https://github.com/firebase/firebase-js-sdk/pull/6899) (fixes [#6509](https://github.com/firebase/firebase-js-sdk/issues/6509)) - Check navigator.userAgent, in addition to navigator.appVersion, when determining whether to work around an IndexedDb bug in Safari. + ## 3.8.4 ### Patch Changes diff --git a/packages/firestore/package.json b/packages/firestore/package.json index 7f83d260f40..7603de17d6c 100644 --- a/packages/firestore/package.json +++ b/packages/firestore/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/firestore", - "version": "3.8.4", + "version": "3.9.0", "engines": { "node": ">=10.10.0" }, @@ -103,9 +103,9 @@ "@firebase/app": "0.x" }, "devDependencies": { - "@firebase/app": "0.9.4", - "@firebase/app-compat": "0.2.4", - "@firebase/auth": "0.21.4", + "@firebase/app": "0.9.5", + "@firebase/app-compat": "0.2.5", + "@firebase/auth": "0.21.5", "@rollup/plugin-alias": "3.1.9", "@rollup/plugin-json": "4.1.0", "@types/eslint": "7.29.0", diff --git a/packages/functions-compat/package.json b/packages/functions-compat/package.json index c54b1cc46fa..6bac274d7c6 100644 --- a/packages/functions-compat/package.json +++ b/packages/functions-compat/package.json @@ -31,7 +31,7 @@ "@firebase/app-compat": "0.x" }, "devDependencies": { - "@firebase/app-compat": "0.2.4", + "@firebase/app-compat": "0.2.5", "rollup": "2.79.1", "@rollup/plugin-json": "4.1.0", "rollup-plugin-typescript2": "0.31.2", diff --git a/packages/functions/package.json b/packages/functions/package.json index 02a40f1df0f..7493b77d3b5 100644 --- a/packages/functions/package.json +++ b/packages/functions/package.json @@ -50,7 +50,7 @@ "@firebase/app": "0.x" }, "devDependencies": { - "@firebase/app": "0.9.4", + "@firebase/app": "0.9.5", "rollup": "2.79.1", "@rollup/plugin-json": "4.1.0", "rollup-plugin-typescript2": "0.31.2", diff --git a/packages/installations-compat/package.json b/packages/installations-compat/package.json index 7ee2f6cc7bd..774c21d5e8c 100644 --- a/packages/installations-compat/package.json +++ b/packages/installations-compat/package.json @@ -45,7 +45,7 @@ "url": "https://github.com/firebase/firebase-js-sdk/issues" }, "devDependencies": { - "@firebase/app-compat": "0.2.4", + "@firebase/app-compat": "0.2.5", "rollup": "2.79.1", "@rollup/plugin-commonjs": "21.1.0", "@rollup/plugin-json": "4.1.0", diff --git a/packages/installations/package.json b/packages/installations/package.json index e7c180d2c2b..98b8fced7a5 100644 --- a/packages/installations/package.json +++ b/packages/installations/package.json @@ -50,7 +50,7 @@ "url": "https://github.com/firebase/firebase-js-sdk/issues" }, "devDependencies": { - "@firebase/app": "0.9.4", + "@firebase/app": "0.9.5", "rollup": "2.79.1", "@rollup/plugin-commonjs": "21.1.0", "@rollup/plugin-json": "4.1.0", diff --git a/packages/messaging-compat/package.json b/packages/messaging-compat/package.json index 509ca1fd0d2..ed4e324d958 100644 --- a/packages/messaging-compat/package.json +++ b/packages/messaging-compat/package.json @@ -45,7 +45,7 @@ "tslib": "^2.1.0" }, "devDependencies": { - "@firebase/app-compat": "0.2.4", + "@firebase/app-compat": "0.2.5", "@rollup/plugin-json": "4.1.0", "rollup-plugin-typescript2": "0.31.2", "ts-essentials": "9.3.0", diff --git a/packages/messaging/package.json b/packages/messaging/package.json index f552c2d14dd..af77e9f645f 100644 --- a/packages/messaging/package.json +++ b/packages/messaging/package.json @@ -61,7 +61,7 @@ "tslib": "^2.1.0" }, "devDependencies": { - "@firebase/app": "0.9.4", + "@firebase/app": "0.9.5", "rollup": "2.79.1", "rollup-plugin-typescript2": "0.31.2", "@rollup/plugin-json": "4.1.0", diff --git a/packages/performance-compat/package.json b/packages/performance-compat/package.json index 842ce2de1ed..f5b67f4063a 100644 --- a/packages/performance-compat/package.json +++ b/packages/performance-compat/package.json @@ -52,7 +52,7 @@ "rollup-plugin-replace": "2.2.0", "rollup-plugin-typescript2": "0.31.2", "typescript": "4.7.4", - "@firebase/app-compat": "0.2.4" + "@firebase/app-compat": "0.2.5" }, "repository": { "directory": "packages/performance-compat", diff --git a/packages/performance/package.json b/packages/performance/package.json index 3d7317015ca..d2445641ef6 100644 --- a/packages/performance/package.json +++ b/packages/performance/package.json @@ -47,7 +47,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app": "0.9.4", + "@firebase/app": "0.9.5", "rollup": "2.79.1", "@rollup/plugin-json": "4.1.0", "rollup-plugin-typescript2": "0.31.2", diff --git a/packages/remote-config-compat/package.json b/packages/remote-config-compat/package.json index 7838c7aff0b..5d2d91be6e6 100644 --- a/packages/remote-config-compat/package.json +++ b/packages/remote-config-compat/package.json @@ -51,7 +51,7 @@ "rollup-plugin-replace": "2.2.0", "rollup-plugin-typescript2": "0.31.2", "typescript": "4.7.4", - "@firebase/app-compat": "0.2.4" + "@firebase/app-compat": "0.2.5" }, "repository": { "directory": "packages/remote-config-compat", diff --git a/packages/remote-config/package.json b/packages/remote-config/package.json index 960e7b4542d..b5135c502e0 100644 --- a/packages/remote-config/package.json +++ b/packages/remote-config/package.json @@ -49,7 +49,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app": "0.9.4", + "@firebase/app": "0.9.5", "rollup": "2.79.1", "rollup-plugin-typescript2": "0.31.2", "typescript": "4.7.4" diff --git a/packages/storage-compat/package.json b/packages/storage-compat/package.json index 9bcb93e84a8..03117fc77bb 100644 --- a/packages/storage-compat/package.json +++ b/packages/storage-compat/package.json @@ -45,8 +45,8 @@ "tslib": "^2.1.0" }, "devDependencies": { - "@firebase/app-compat": "0.2.4", - "@firebase/auth-compat": "0.3.4", + "@firebase/app-compat": "0.2.5", + "@firebase/auth-compat": "0.3.5", "rollup": "2.79.1", "@rollup/plugin-json": "4.1.0", "rollup-plugin-typescript2": "0.31.2", diff --git a/packages/storage/package.json b/packages/storage/package.json index efb3ca2c9d9..23b5421642e 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -55,8 +55,8 @@ "@firebase/app": "0.x" }, "devDependencies": { - "@firebase/app": "0.9.4", - "@firebase/auth": "0.21.4", + "@firebase/app": "0.9.5", + "@firebase/auth": "0.21.5", "rollup": "2.79.1", "@rollup/plugin-alias": "3.1.9", "@rollup/plugin-json": "4.1.0", diff --git a/packages/template/package.json b/packages/template/package.json index 5300fa69fa1..d42012e56bc 100644 --- a/packages/template/package.json +++ b/packages/template/package.json @@ -49,7 +49,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@firebase/app": "0.9.4", + "@firebase/app": "0.9.5", "rollup": "2.79.1", "rollup-plugin-typescript2": "0.31.2", "typescript": "4.7.4" diff --git a/repo-scripts/size-analysis/package.json b/repo-scripts/size-analysis/package.json index c5b7c9de79e..6985d6644c5 100644 --- a/repo-scripts/size-analysis/package.json +++ b/repo-scripts/size-analysis/package.json @@ -42,7 +42,7 @@ "license": "Apache-2.0", "devDependencies": { "@firebase/logger": "0.4.0", - "@firebase/app": "0.9.4" + "@firebase/app": "0.9.5" }, "repository": { "directory": "repo-scripts/size-analysis", From 54035e6e022cb1f3df3bbeb0fedd5f9040ba96e6 Mon Sep 17 00:00:00 2001 From: Mila <107142260+milaGGL@users.noreply.github.com> Date: Thu, 16 Mar 2023 20:31:17 -0700 Subject: [PATCH 18/26] remove gapi.auth fall back option for getAuthToken() (#7100) --- .changeset/plenty-radios-look.md | 6 ++++ packages/firestore/src/api/credentials.ts | 37 +++++------------------ 2 files changed, 13 insertions(+), 30 deletions(-) create mode 100644 .changeset/plenty-radios-look.md diff --git a/.changeset/plenty-radios-look.md b/.changeset/plenty-radios-look.md new file mode 100644 index 00000000000..f8d34fd34b6 --- /dev/null +++ b/.changeset/plenty-radios-look.md @@ -0,0 +1,6 @@ +--- +'@firebase/firestore': patch +'firebase': patch +--- + +Remove the deprecated gapi.auth from FirstPartyToken. diff --git a/packages/firestore/src/api/credentials.ts b/packages/firestore/src/api/credentials.ts index 7ee1ca941b1..f8af49696cb 100644 --- a/packages/firestore/src/api/credentials.ts +++ b/packages/firestore/src/api/credentials.ts @@ -41,8 +41,7 @@ export type AuthTokenFactory = () => string; export interface FirstPartyCredentialsSettings { // These are external types. Prevent minification. - ['type']: 'gapi'; - ['client']: unknown; + ['type']: 'firstParty'; ['sessionIndex']: string; ['iamToken']: string | null; ['authTokenFactory']: AuthTokenFactory | null; @@ -379,15 +378,6 @@ export class FirebaseAuthCredentialsProvider } } -// Manual type definition for the subset of Gapi we use. -interface Gapi { - auth: { - getAuthHeaderValueForFirstParty: ( - userIdentifiers: Array<{ [key: string]: string }> - ) => string | null; - }; -} - /* * FirstPartyToken provides a fresh token each time its value * is requested, because if the token is too old, requests will be rejected. @@ -401,28 +391,20 @@ export class FirstPartyToken implements Token { private _headers = new Map(); constructor( - private readonly gapi: Gapi | null, private readonly sessionIndex: string, private readonly iamToken: string | null, private readonly authTokenFactory: AuthTokenFactory | null ) {} - /** Gets an authorization token, using a provided factory function, or falling back to First Party GAPI. */ + /** + * Gets an authorization token, using a provided factory function, or return + * null. + */ private getAuthToken(): string | null { if (this.authTokenFactory) { return this.authTokenFactory(); } else { - // Make sure this really is a Gapi client. - hardAssert( - !!( - typeof this.gapi === 'object' && - this.gapi !== null && - this.gapi['auth'] && - this.gapi['auth']['getAuthHeaderValueForFirstParty'] - ), - 'unexpected gapi interface' - ); - return this.gapi!['auth']['getAuthHeaderValueForFirstParty']([]); + return null; } } @@ -450,7 +432,6 @@ export class FirstPartyAuthCredentialsProvider implements CredentialsProvider { constructor( - private gapi: Gapi | null, private sessionIndex: string, private iamToken: string | null, private authTokenFactory: AuthTokenFactory | null @@ -459,7 +440,6 @@ export class FirstPartyAuthCredentialsProvider getToken(): Promise { return Promise.resolve( new FirstPartyToken( - this.gapi, this.sessionIndex, this.iamToken, this.authTokenFactory @@ -668,12 +648,9 @@ export function makeAuthCredentialsProvider( if (!credentials) { return new EmptyAuthCredentialsProvider(); } - switch (credentials['type']) { - case 'gapi': - const client = credentials['client'] as Gapi; + case 'firstParty': return new FirstPartyAuthCredentialsProvider( - client, credentials['sessionIndex'] || '0', credentials['iamToken'] || null, credentials['authTokenFactory'] || null From e755eae957b2533c375a9209fd99b311c86a6ce1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Mar 2023 11:09:37 -0700 Subject: [PATCH 19/26] Update dependency simple-git to v3.16.0 [SECURITY] (#6986) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index d755cf672c9..ad3dd89e986 100644 --- a/package.json +++ b/package.json @@ -141,7 +141,7 @@ "protractor": "5.4.2", "request": "2.88.2", "semver": "7.3.8", - "simple-git": "3.15.1", + "simple-git": "3.16.0", "sinon": "9.2.4", "sinon-chai": "3.7.0", "source-map-loader": "1.1.3", diff --git a/yarn.lock b/yarn.lock index 51ab488ff0a..b55df34dc8a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15623,10 +15623,10 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.4.tgz#366a4684d175b9cab2081e3681fda3747b6c51d7" integrity sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q== -simple-git@3.15.1: - version "3.15.1" - resolved "https://registry.npmjs.org/simple-git/-/simple-git-3.15.1.tgz#57f595682cb0c2475d5056da078a05c8715a25ef" - integrity sha512-73MVa5984t/JP4JcQt0oZlKGr42ROYWC3BcUZfuHtT3IHKPspIvL0cZBnvPXF7LL3S/qVeVHVdYYmJ3LOTw4Rg== +simple-git@3.16.0: + version "3.16.0" + resolved "https://registry.npmjs.org/simple-git/-/simple-git-3.16.0.tgz#421773e24680f5716999cc4a1d60127b4b6a9dec" + integrity sha512-zuWYsOLEhbJRWVxpjdiXl6eyAyGo/KzVW+KFhhw9MqEEJttcq+32jTWSGyxTdf9e/YCohxRE+9xpWFj9FdiJNw== dependencies: "@kwsites/file-exists" "^1.1.1" "@kwsites/promise-deferred" "^1.1.1" From f8334aef7230b398f630e4eec5186b4ea88f73f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Mar 2023 11:10:44 -0700 Subject: [PATCH 20/26] Update dependency webpack to v5.76.0 [SECURITY] (#7127) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- e2e/package.json | 2 +- e2e/yarn.lock | 769 +++++++++++++++++++++++------------------------ 2 files changed, 369 insertions(+), 402 deletions(-) diff --git a/e2e/package.json b/e2e/package.json index 5bd0ff6a071..ab708590571 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -35,7 +35,7 @@ "karma-typescript-es6-transform": "5.5.3", "mocha": "9.2.2", "typescript": "4.7.4", - "webpack": "5.75.0", + "webpack": "5.76.0", "webpack-cli": "4.10.0", "webpack-dev-server": "4.11.1" } diff --git a/e2e/yarn.lock b/e2e/yarn.lock index 83cee91277f..92b3439c7fa 100644 --- a/e2e/yarn.lock +++ b/e2e/yarn.lock @@ -1825,394 +1825,384 @@ resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz#90420f9f9c6d3987f176a19a7d8e764271a2f55d" integrity sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g== -"@firebase/analytics-compat@0.1.13": - version "0.1.13" - resolved "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.1.13.tgz#61e1d6f9e4d033c3ed9943d91530eb3e0f382f92" - integrity sha512-QC1DH/Dwc8fBihn0H+jocBWyE17GF1fOCpCrpAiQ2u16F/NqsVDVG4LjIqdhq963DXaXneNY7oDwa25Up682AA== - dependencies: - "@firebase/analytics" "0.8.0" - "@firebase/analytics-types" "0.7.0" - "@firebase/component" "0.5.17" - "@firebase/util" "1.6.3" +"@firebase/analytics-compat@0.2.3": + version "0.2.3" + resolved "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.3.tgz#ed60472dcd2bfa3f2fa7a5478b63bb7aece652ed" + integrity sha512-HmvbB4GMgh8AUlIDIo/OuFENLCGRXxMvtOueK+m8+DcfqBvG+mkii0Mi9ovo0TnMM62cy3oBYG7PHdjIQNLSLA== + dependencies: + "@firebase/analytics" "0.9.3" + "@firebase/analytics-types" "0.8.0" + "@firebase/component" "0.6.3" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/analytics-types@0.7.0": - version "0.7.0" - resolved "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.7.0.tgz#91960e7c87ce8bf18cf8dd9e55ccbf5dc3989b5d" - integrity sha512-DNE2Waiwy5+zZnCfintkDtBfaW6MjIG883474v6Z0K1XZIvl76cLND4iv0YUb48leyF+PJK1KO2XrgHb/KpmhQ== - -"@firebase/analytics@0.8.0": +"@firebase/analytics-types@0.8.0": version "0.8.0" - resolved "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.8.0.tgz#b5d595082f57d33842b1fd9025d88f83065e87fe" - integrity sha512-wkcwainNm8Cu2xkJpDSHfhBSdDJn86Q1TZNmLWc67VrhZUHXIKXxIqb65/tNUVE+I8+sFiDDNwA+9R3MqTQTaA== + resolved "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.0.tgz#551e744a29adbc07f557306530a2ec86add6d410" + integrity sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw== + +"@firebase/analytics@0.9.3": + version "0.9.3" + resolved "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.9.3.tgz#ae653a6c6bcd667efd1d3cc5207e3e621d737028" + integrity sha512-XdYHBi6RvHYVAHGyLxXX0uRPwZmGeqw1JuWS1rMEeRF/jvbxnrL81kcFAHZVRkEvG9bXAJgL2fX9wmDo3e622w== dependencies: - "@firebase/component" "0.5.17" - "@firebase/installations" "0.5.12" - "@firebase/logger" "0.3.3" - "@firebase/util" "1.6.3" + "@firebase/component" "0.6.3" + "@firebase/installations" "0.6.3" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/app-check-compat@0.2.12": - version "0.2.12" - resolved "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.2.12.tgz#e30b2395e3d30f8cfcf3554fc87875f82c1aa086" - integrity sha512-GFppNLlUyMN9Iq31ME/+GkjRVKlc+MeanzUKQ9UaR73ZsYH3oX3Ja+xjoYgixaVJDDG+ofBYR7ZXTkkQdSR/pw== - dependencies: - "@firebase/app-check" "0.5.12" - "@firebase/app-check-types" "0.4.0" - "@firebase/component" "0.5.17" - "@firebase/logger" "0.3.3" - "@firebase/util" "1.6.3" +"@firebase/app-check-compat@0.3.3": + version "0.3.3" + resolved "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.3.tgz#a1d594ec722fa81f7e11977b407a187e8afdb19a" + integrity sha512-25AQ4W7WUL8OWas40GsABuNU622Dm1ojbfeZ03uKtLj5Af7FerJ25u7zkgm+11pc6rpr5v8E5oxEG9vmNRndEA== + dependencies: + "@firebase/app-check" "0.6.3" + "@firebase/app-check-types" "0.5.0" + "@firebase/component" "0.6.3" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/app-check-interop-types@0.1.0": - version "0.1.0" - resolved "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.1.0.tgz#83afd9d41f99166c2bdb2d824e5032e9edd8fe53" - integrity sha512-uZfn9s4uuRsaX5Lwx+gFP3B6YsyOKUE+Rqa6z9ojT4VSRAsZFko9FRn6OxQUA1z5t5d08fY4pf+/+Dkd5wbdbA== +"@firebase/app-check-interop-types@0.2.0": + version "0.2.0" + resolved "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.2.0.tgz#9106270114ca4e7732457e8319333866a26285d8" + integrity sha512-+3PQIeX6/eiVK+x/yg8r6xTNR97fN7MahFDm+jiQmDjcyvSefoGuTTNQuuMScGyx3vYUBeZn+Cp9kC0yY/9uxQ== -"@firebase/app-check-types@0.4.0": - version "0.4.0" - resolved "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.4.0.tgz#7007a9d1d720db20bcf466fe6785c96feaa0a82d" - integrity sha512-SsWafqMABIOu7zLgWbmwvHGOeQQVQlwm42kwwubsmfLmL4Sf5uGpBfDhQ0CAkpi7bkJ/NwNFKafNDL9prRNP0Q== +"@firebase/app-check-types@0.5.0": + version "0.5.0" + resolved "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.0.tgz#1b02826213d7ce6a1cf773c329b46ea1c67064f4" + integrity sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ== -"@firebase/app-check@0.5.12": - version "0.5.12" - resolved "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.5.12.tgz#82f305cc01bfe4d32c35e425941b2eca2ce9f089" - integrity sha512-l+MmvupSGT/F+I5ei7XjhEfpoL4hLVJr0vUwcG5NEf2hAkQnySli9fnbl9fZu1BJaQ2kthrMmtg1gcbcM9BUCQ== +"@firebase/app-check@0.6.3": + version "0.6.3" + resolved "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.6.3.tgz#221060e5e0eac1e20ee724478b61e89ad6e8420a" + integrity sha512-T9f9ceFLs7x4D2T6whu5a6j7B3qPuYHiZHZxW6DkMh/FoMmRA4/q/HVyu01i9+LyJJx2Xdo6eCcj6ofs9YZjqA== dependencies: - "@firebase/component" "0.5.17" - "@firebase/logger" "0.3.3" - "@firebase/util" "1.6.3" + "@firebase/component" "0.6.3" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/app-compat@0.1.31": - version "0.1.31" - resolved "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.1.31.tgz#a52b3cc34d2dd8b790a48eaefbf05ce0f3b20be4" - integrity sha512-oH3F4Pf0/Q0WTyNynMlaoM1qjUTTu7ofDdAWUOgr9BH9gftIClqeCulltXSQH3DO3XUE61pIIpIakAWQ7zzumA== +"@firebase/app-compat@0.2.3": + version "0.2.3" + resolved "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.3.tgz#a31c823d415c041591ee8c355776cd5bca7ef6e2" + integrity sha512-sX6rD1KFX6K2CuCnQvc9jZLOgAFZ+sv2jKKahIl4SbTM561D682B8n4Jtx/SgDrvcTVTdb05g4NhZOws9hxYxA== dependencies: - "@firebase/app" "0.7.30" - "@firebase/component" "0.5.17" - "@firebase/logger" "0.3.3" - "@firebase/util" "1.6.3" + "@firebase/app" "0.9.3" + "@firebase/component" "0.6.3" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/app-types@0.7.0": - version "0.7.0" - resolved "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz#c9e16d1b8bed1a991840b8d2a725fb58d0b5899f" - integrity sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg== +"@firebase/app-types@0.9.0": + version "0.9.0" + resolved "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz#35b5c568341e9e263b29b3d2ba0e9cfc9ec7f01e" + integrity sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q== -"@firebase/app@0.7.30": - version "0.7.30" - resolved "https://registry.npmjs.org/@firebase/app/-/app-0.7.30.tgz#20cba8f01540c7dcc072726d4f8ac745837457f4" - integrity sha512-uJRMShpCWCrW6eO+/UuN0ExgztPMpK/w/AUryHJh7Ll4lFkc71pqE9P/XlfE+XXi0zkWoXVgPeLAQDkUJwgmMA== +"@firebase/app@0.9.3": + version "0.9.3" + resolved "https://registry.npmjs.org/@firebase/app/-/app-0.9.3.tgz#6a9c9b2544fa9a50ad8f405355896c54339c228b" + integrity sha512-G79JUceVDaHRZ4WkA11GyVldVXhdyRJRwWVQFFvAAVfQJLvy2TA6lQjeUn28F6FmeUWxDGwPC30bxCRWq7Op8Q== dependencies: - "@firebase/component" "0.5.17" - "@firebase/logger" "0.3.3" - "@firebase/util" "1.6.3" + "@firebase/component" "0.6.3" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.2" idb "7.0.1" tslib "^2.1.0" -"@firebase/auth-compat@0.2.18": - version "0.2.18" - resolved "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.2.18.tgz#c7bb254fbb23447069f81abb15f96e91de40b285" - integrity sha512-Fw2PJS0G/tGrfyEBcYJQ42sfy5+sANrK5xd7tuzgV7zLFW5rYkHUIZngXjuOBwLOcfO2ixa/FavfeJle3oJ38Q== +"@firebase/auth-compat@0.3.3": + version "0.3.3" + resolved "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.3.3.tgz#e52f654e3f14b81cecb2fe252e564778fbba0a47" + integrity sha512-9asUuGtkzUVELH3LYXdiom1nVVV9bqEPqzHohanoofHL/oVTNcHZ4AQ5CXjNATfb6c1WH32U+nEuPiYg26UUIw== dependencies: - "@firebase/auth" "0.20.5" - "@firebase/auth-types" "0.11.0" - "@firebase/component" "0.5.17" - "@firebase/util" "1.6.3" + "@firebase/auth" "0.21.3" + "@firebase/auth-types" "0.12.0" + "@firebase/component" "0.6.3" + "@firebase/util" "1.9.2" node-fetch "2.6.7" - selenium-webdriver "4.1.2" tslib "^2.1.0" -"@firebase/auth-interop-types@0.1.6": - version "0.1.6" - resolved "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz#5ce13fc1c527ad36f1bb1322c4492680a6cf4964" - integrity sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g== - -"@firebase/auth-types@0.11.0": - version "0.11.0" - resolved "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.11.0.tgz#b9c73c60ca07945b3bbd7a097633e5f78fa9e886" - integrity sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw== - -"@firebase/auth@0.20.5": - version "0.20.5" - resolved "https://registry.npmjs.org/@firebase/auth/-/auth-0.20.5.tgz#a2e6c6b593d8f9cf8276a7d1f8ab5b055d65cc50" - integrity sha512-SbKj7PCAuL0lXEToUOoprc1im2Lr/bzOePXyPC7WWqVgdVBt0qovbfejlzKYwJLHUAPg9UW1y3XYe3IlbXr77w== - dependencies: - "@firebase/component" "0.5.17" - "@firebase/logger" "0.3.3" - "@firebase/util" "1.6.3" +"@firebase/auth-interop-types@0.2.1": + version "0.2.1" + resolved "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz#78884f24fa539e34a06c03612c75f222fcc33742" + integrity sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg== + +"@firebase/auth-types@0.12.0": + version "0.12.0" + resolved "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz#f28e1b68ac3b208ad02a15854c585be6da3e8e79" + integrity sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA== + +"@firebase/auth@0.21.3": + version "0.21.3" + resolved "https://registry.npmjs.org/@firebase/auth/-/auth-0.21.3.tgz#277a3bf4b09db1b5dd471970cecd844d1835dcbf" + integrity sha512-HPbcwgArLBVTowFcn4qaQr6LCx7BidI9yrQ5MRbQNv4PsgK/3UGpzCYaNPPbvgr9fe+0jNdJO+uC0+dk4xIzCQ== + dependencies: + "@firebase/component" "0.6.3" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.2" node-fetch "2.6.7" - selenium-webdriver "4.1.2" tslib "^2.1.0" -"@firebase/component@0.5.17": - version "0.5.17" - resolved "https://registry.npmjs.org/@firebase/component/-/component-0.5.17.tgz#89291f378714df05d44430c524708669380d8ea6" - integrity sha512-mTM5CBSIlmI+i76qU4+DhuExnWtzcPS3cVgObA3VAjliPPr3GrUlTaaa8KBGfxsD27juQxMsYA0TvCR5X+GQ3Q== +"@firebase/component@0.6.3": + version "0.6.3" + resolved "https://registry.npmjs.org/@firebase/component/-/component-0.6.3.tgz#2baea3fa37861eef314a612eba194b0ff7c7ac11" + integrity sha512-rnhq5SOsB5nuJphZF50iwqnBiuuyg9kdnlUn1rBrKfu7/cUVJZF5IG1cWrL0rXXyiZW1WBI/J2pmTvVO8dStGQ== dependencies: - "@firebase/util" "1.6.3" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/database-compat@0.2.4": - version "0.2.4" - resolved "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.2.4.tgz#4e72dfa477011f69595fec80a9b688e3ea672d2f" - integrity sha512-VtsGixO5mTjNMJn6PwxAJEAR70fj+3blCXIdQKel3q+eYGZAfdqxox1+tzZDnf9NWBJpaOgAHPk3JVDxEo9NFQ== - dependencies: - "@firebase/component" "0.5.17" - "@firebase/database" "0.13.4" - "@firebase/database-types" "0.9.12" - "@firebase/logger" "0.3.3" - "@firebase/util" "1.6.3" +"@firebase/database-compat@0.3.3": + version "0.3.3" + resolved "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.3.3.tgz#4668e32527f57c1dde6cb03f5fde81eb04503ad4" + integrity sha512-r+L9jTbvsnb7sD+xz6UKU39DgBWqB2pyjzPNdBeriGC9Ssa2MAZe0bIqjCQg51RRXYc/aa/zK1Q2/4uesZeVgQ== + dependencies: + "@firebase/component" "0.6.3" + "@firebase/database" "0.14.3" + "@firebase/database-types" "0.10.3" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/database-types@0.9.12": - version "0.9.12" - resolved "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.12.tgz#517844fc7723494a7bf33c906a9c6b2dc7f3c9bb" - integrity sha512-FP4UYx1/bIOYSbTFmKajKKaEjXZKCQFUNZNIxaiCEZmsXb4vt0PJAmBufJf6LJLsaXNoywkcTyPYwjsotviyxg== +"@firebase/database-types@0.10.3": + version "0.10.3" + resolved "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.10.3.tgz#f057e150b8c2aff0c623162abef139ff5df9bfd2" + integrity sha512-Hu34CDhHYZsd2eielr0jeaWrTJk8Hz0nd7WsnYDnXtQX4i49ppgPesUzPdXVBdIBLJmT0ZZRvT7qWHknkOT+zg== dependencies: - "@firebase/app-types" "0.7.0" - "@firebase/util" "1.6.3" + "@firebase/app-types" "0.9.0" + "@firebase/util" "1.9.2" -"@firebase/database@0.13.4": - version "0.13.4" - resolved "https://registry.npmjs.org/@firebase/database/-/database-0.13.4.tgz#9b95968932a2c0e16f5dc995370262d366e0a469" - integrity sha512-NW7bOoiaC4sJCj6DY/m9xHoFNa0CK32YPMCh6FiMweLCDQbOZM8Ql/Kn6yyuxCb7K7ypz9eSbRlCWQJsJRQjhg== +"@firebase/database@0.14.3": + version "0.14.3" + resolved "https://registry.npmjs.org/@firebase/database/-/database-0.14.3.tgz#0ddd92e5eeef2dbebefd55ce78b39472a57dd5d3" + integrity sha512-J76W6N7JiVkLaAtPyjaGRkrsIu9pi6iZikuGGtGjqvV19vkn7oiL4Hbo5uTYCMd4waTUWoL9iI08eX184W+5GQ== dependencies: - "@firebase/auth-interop-types" "0.1.6" - "@firebase/component" "0.5.17" - "@firebase/logger" "0.3.3" - "@firebase/util" "1.6.3" + "@firebase/auth-interop-types" "0.2.1" + "@firebase/component" "0.6.3" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.2" faye-websocket "0.11.4" tslib "^2.1.0" -"@firebase/firestore-compat@0.1.23": - version "0.1.23" - resolved "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.1.23.tgz#e941fa10f3eeca615df119470103fb4656842eef" - integrity sha512-QfcuyMAavp//fQnjSfCEpnbWi7spIdKaXys1kOLu7395fLr+U6ykmto1HUMCSz8Yus9cEr/03Ujdi2SUl2GUAA== +"@firebase/firestore-compat@0.3.3": + version "0.3.3" + resolved "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.3.tgz#2fedc13e6242aa98a78cfb710242721d9822c1da" + integrity sha512-fMTsSC0s2cF5w2+JoB0dWD/o4kXtLrUCPGnZPuz4S0bqTN2t0vHr3gdAsQLtnadgwB78ACtinYmf4Udwx7TzDg== dependencies: - "@firebase/component" "0.5.17" - "@firebase/firestore" "3.4.14" - "@firebase/firestore-types" "2.5.0" - "@firebase/util" "1.6.3" + "@firebase/component" "0.6.3" + "@firebase/firestore" "3.8.3" + "@firebase/firestore-types" "2.5.1" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/firestore-types@2.5.0": - version "2.5.0" - resolved "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-2.5.0.tgz#16fca40b6980fdb000de86042d7a96635f2bcdd7" - integrity sha512-I6c2m1zUhZ5SH0cWPmINabDyH5w0PPFHk2UHsjBpKdZllzJZ2TwTkXbDtpHUZNmnc/zAa0WNMNMvcvbb/xJLKA== - -"@firebase/firestore@3.4.14": - version "3.4.14" - resolved "https://registry.npmjs.org/@firebase/firestore/-/firestore-3.4.14.tgz#864a56e70b3fd8f0274d3497ed67fabf5b38fdb2" - integrity sha512-F4Pqd5OUBtJaAWWC39C0vrMLIdZtx7jsO7sARFHSiOZY/8bikfH9YovIRkpxk7OSs3HT/SgVdK0B1vISGNSnJA== - dependencies: - "@firebase/component" "0.5.17" - "@firebase/logger" "0.3.3" - "@firebase/util" "1.6.3" - "@firebase/webchannel-wrapper" "0.6.2" - "@grpc/grpc-js" "^1.3.2" +"@firebase/firestore-types@2.5.1": + version "2.5.1" + resolved "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-2.5.1.tgz#464b2ee057956599ca34de50eae957c30fdbabb7" + integrity sha512-xG0CA6EMfYo8YeUxC8FeDzf6W3FX1cLlcAGBYV6Cku12sZRI81oWcu61RSKM66K6kUENP+78Qm8mvroBcm1whw== + +"@firebase/firestore@3.8.3": + version "3.8.3" + resolved "https://registry.npmjs.org/@firebase/firestore/-/firestore-3.8.3.tgz#8305113b9535747f982b585b0dd72e85122b5b89" + integrity sha512-4xR3Mqj95bxHg3hZnz0O+LQrHkjq+siT2y+B9da6u68qJ8bzzT42JaFgd1vifhbBpVbBzpFaS2RuCq2E+kGv9g== + dependencies: + "@firebase/component" "0.6.3" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.2" + "@firebase/webchannel-wrapper" "0.9.0" + "@grpc/grpc-js" "~1.7.0" "@grpc/proto-loader" "^0.6.13" node-fetch "2.6.7" tslib "^2.1.0" -"@firebase/functions-compat@0.2.4": - version "0.2.4" - resolved "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.2.4.tgz#afa5d8eefe6d51c7b89e44d9262700b68fbcb73f" - integrity sha512-Crfn6il1yXGuXkjSd8nKrqR4XxPvuP19g64bXpM6Ix67qOkQg676kyOuww0FF17xN0NSXHfG8Pyf+CUrx8wJ5g== +"@firebase/functions-compat@0.3.3": + version "0.3.3" + resolved "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.3.tgz#530c30b4dfea14e71657f780d2c281e16209aed7" + integrity sha512-UIAJ2gzNq0p/61cXqkpi9DnlQt0hdlGqgmL5an7KuJth2Iv5uGpKg/+OapAZxPuiUNZgTEyZDB7kNBHvnxWq5w== dependencies: - "@firebase/component" "0.5.17" - "@firebase/functions" "0.8.4" - "@firebase/functions-types" "0.5.0" - "@firebase/util" "1.6.3" + "@firebase/component" "0.6.3" + "@firebase/functions" "0.9.3" + "@firebase/functions-types" "0.6.0" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/functions-types@0.5.0": - version "0.5.0" - resolved "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.5.0.tgz#b50ba95ccce9e96f7cda453228ffe1684645625b" - integrity sha512-qza0M5EwX+Ocrl1cYI14zoipUX4gI/Shwqv0C1nB864INAD42Dgv4v94BCyxGHBg2kzlWy8PNafdP7zPO8aJQA== - -"@firebase/functions@0.8.4": - version "0.8.4" - resolved "https://registry.npmjs.org/@firebase/functions/-/functions-0.8.4.tgz#a9b7a10314f286df1ded87d8546fb8d9107a9c06" - integrity sha512-o1bB0xMyQKe+b246zGnjwHj4R6BH4mU2ZrSaa/3QvTpahUQ3hqYfkZPLOXCU7+vEFxHb3Hd4UUjkFhxoAcPqLA== - dependencies: - "@firebase/app-check-interop-types" "0.1.0" - "@firebase/auth-interop-types" "0.1.6" - "@firebase/component" "0.5.17" - "@firebase/messaging-interop-types" "0.1.0" - "@firebase/util" "1.6.3" +"@firebase/functions-types@0.6.0": + version "0.6.0" + resolved "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.0.tgz#ccd7000dc6fc668f5acb4e6a6a042a877a555ef2" + integrity sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw== + +"@firebase/functions@0.9.3": + version "0.9.3" + resolved "https://registry.npmjs.org/@firebase/functions/-/functions-0.9.3.tgz#9ef33efcd38b0235e84ae472d9b51597efe3f871" + integrity sha512-tPJgYY2ROQSYuzvgxZRoHeDj+Ic07/bWHwaftgTriawtupmFOkt5iikuhJSJUhaOpFh9TB335OvCXJw1N+BIlQ== + dependencies: + "@firebase/app-check-interop-types" "0.2.0" + "@firebase/auth-interop-types" "0.2.1" + "@firebase/component" "0.6.3" + "@firebase/messaging-interop-types" "0.2.0" + "@firebase/util" "1.9.2" node-fetch "2.6.7" tslib "^2.1.0" -"@firebase/installations-compat@0.1.12": - version "0.1.12" - resolved "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.1.12.tgz#d0394127f71aff596cb8bb607840095d1617246e" - integrity sha512-BIhFpWIn/GkuOa+jnXkp3SDJT2RLYJF6MWpinHIBKFJs7MfrgYZ3zQ1AlhobDEql+bkD1dK4dB5sNcET2T+EyA== +"@firebase/installations-compat@0.2.3": + version "0.2.3" + resolved "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.3.tgz#42b05f4e5204c354e0fa059378402bd47635e5bf" + integrity sha512-K9rKM/ym06lkpaKz7bMLxzHK/HEk65XfLJBV+dJkIuWeO0EqqC9VFGrpWAo0QmgC4BqbU58T6VBbzoJjb0gaFw== dependencies: - "@firebase/component" "0.5.17" - "@firebase/installations" "0.5.12" - "@firebase/installations-types" "0.4.0" - "@firebase/util" "1.6.3" + "@firebase/component" "0.6.3" + "@firebase/installations" "0.6.3" + "@firebase/installations-types" "0.5.0" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/installations-types@0.4.0": - version "0.4.0" - resolved "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.4.0.tgz#256782ff9adfb390ac658c25bc32f89635ddce7c" - integrity sha512-nXxWKQDvBGctuvsizbUEJKfxXU9WAaDhon+j0jpjIfOJkvkj3YHqlLB/HeYjpUn85Pb22BjplpTnDn4Gm9pc3A== +"@firebase/installations-types@0.5.0": + version "0.5.0" + resolved "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.0.tgz#2adad64755cd33648519b573ec7ec30f21fb5354" + integrity sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg== -"@firebase/installations@0.5.12": - version "0.5.12" - resolved "https://registry.npmjs.org/@firebase/installations/-/installations-0.5.12.tgz#1d5764aa6f0b73d9d6d1a81a07eab5cd71a5ea27" - integrity sha512-Zq43fCE0PB5tGJ3ojzx5RNQzKdej1188qgAk22rwjuhP7npaG/PlJqDG1/V0ZjTLRePZ1xGrfXSPlA17c/vtNw== +"@firebase/installations@0.6.3": + version "0.6.3" + resolved "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.3.tgz#b833cf12ac63666246a57100dbdd669fb76a23aa" + integrity sha512-20JFWm+tweNoRjRbz8/Y4I7O5pUJGZsFKCkLl1qNxfNYECSfrZUuozIDJDZC/MeVn5+kB9CwjThDlgQEPrfLdg== dependencies: - "@firebase/component" "0.5.17" - "@firebase/util" "1.6.3" + "@firebase/component" "0.6.3" + "@firebase/util" "1.9.2" idb "7.0.1" tslib "^2.1.0" -"@firebase/logger@0.3.3": - version "0.3.3" - resolved "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.3.tgz#0f724b1e0b166d17ac285aac5c8ec14d136beed4" - integrity sha512-POTJl07jOKTOevLXrTvJD/VZ0M6PnJXflbAh5J9VGkmtXPXNG6MdZ9fmRgqYhXKTaDId6AQenQ262uwgpdtO0Q== +"@firebase/logger@0.4.0": + version "0.4.0" + resolved "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz#15ecc03c452525f9d47318ad9491b81d1810f113" + integrity sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA== dependencies: tslib "^2.1.0" -"@firebase/messaging-compat@0.1.16": - version "0.1.16" - resolved "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.1.16.tgz#4fe4e2c1b496e62f63e815cb242a2ab323cd7899" - integrity sha512-uG7rWcXJzU8vvlEBFpwG1ndw/GURrrmKcwsHopEWbsPGjMRaVWa7XrdKbvIR7IZohqPzcC/V9L8EeqF4Q4lz8w== +"@firebase/messaging-compat@0.2.3": + version "0.2.3" + resolved "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.3.tgz#2d222e4078643e49a708b61b6d0e51edc2bc73bd" + integrity sha512-MmuuohXV2YRzIoJmDngI5qqO/cF2q7SdAaw7k4r61W3ReJy7x4/rtqrIvwNVhM6X/X8NFGBbsYKsCfRHWjFdkg== dependencies: - "@firebase/component" "0.5.17" - "@firebase/messaging" "0.9.16" - "@firebase/util" "1.6.3" + "@firebase/component" "0.6.3" + "@firebase/messaging" "0.12.3" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/messaging-interop-types@0.1.0": - version "0.1.0" - resolved "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.1.0.tgz#bdac02dd31edd5cb9eec37b1db698ea5e2c1a631" - integrity sha512-DbvUl/rXAZpQeKBnwz0NYY5OCqr2nFA0Bj28Fmr3NXGqR4PAkfTOHuQlVtLO1Nudo3q0HxAYLa68ZDAcuv2uKQ== - -"@firebase/messaging@0.9.16": - version "0.9.16" - resolved "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.9.16.tgz#96b57ebbb054e57f78585f85f59d521c5ba5cd85" - integrity sha512-Yl9gGrAvJF6C1gg3+Cr2HxlL6APsDEkrorkFafmSP1l+rg1epZKoOAcKJbSF02Vtb50wfb9FqGGy8tzodgETxg== - dependencies: - "@firebase/component" "0.5.17" - "@firebase/installations" "0.5.12" - "@firebase/messaging-interop-types" "0.1.0" - "@firebase/util" "1.6.3" +"@firebase/messaging-interop-types@0.2.0": + version "0.2.0" + resolved "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz#6056f8904a696bf0f7fdcf5f2ca8f008e8f6b064" + integrity sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ== + +"@firebase/messaging@0.12.3": + version "0.12.3" + resolved "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.3.tgz#3fd521e31deb9b81ec6316062deb1dcc8198d038" + integrity sha512-a3ZKcGDiV2sKmQDB56PpgL1yjFxXCtff2+v1grnAZZ4GnfNQ74t2EHCbmgY7xRX7ThzMqug54oxhuk4ur0MIoA== + dependencies: + "@firebase/component" "0.6.3" + "@firebase/installations" "0.6.3" + "@firebase/messaging-interop-types" "0.2.0" + "@firebase/util" "1.9.2" idb "7.0.1" tslib "^2.1.0" -"@firebase/performance-compat@0.1.12": - version "0.1.12" - resolved "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.1.12.tgz#ac50b0cd29bf7f5e1e33c640dba25e2f8db95f0b" - integrity sha512-IBORzUeGY1MGdZnsix9Mu5z4+C3WHIwalu0usxvygL0EZKHztGG8bppYPGH/b5vvg8QyHs9U+Pn1Ot2jZhffQQ== - dependencies: - "@firebase/component" "0.5.17" - "@firebase/logger" "0.3.3" - "@firebase/performance" "0.5.12" - "@firebase/performance-types" "0.1.0" - "@firebase/util" "1.6.3" +"@firebase/performance-compat@0.2.3": + version "0.2.3" + resolved "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.3.tgz#f3939bedc2017a95772fde64a72e97fe4b184268" + integrity sha512-I3rqZsIhauXn4iApfj1ttKQdlti/r8OZBG4YK10vxKSdhAzTIDWDKEsdoCXvvKLwplcMv36sM3WPAPGQLqY5MQ== + dependencies: + "@firebase/component" "0.6.3" + "@firebase/logger" "0.4.0" + "@firebase/performance" "0.6.3" + "@firebase/performance-types" "0.2.0" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/performance-types@0.1.0": - version "0.1.0" - resolved "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.1.0.tgz#5e6efa9dc81860aee2cb7121b39ae8fa137e69fc" - integrity sha512-6p1HxrH0mpx+622Ql6fcxFxfkYSBpE3LSuwM7iTtYU2nw91Hj6THC8Bc8z4nboIq7WvgsT/kOTYVVZzCSlXl8w== - -"@firebase/performance@0.5.12": - version "0.5.12" - resolved "https://registry.npmjs.org/@firebase/performance/-/performance-0.5.12.tgz#4eae3eb91eeffb29b996e7908172052d4a901856" - integrity sha512-MPVTkOkGrm2SMQgI1FPNBm85y2pPqlPb6VDjIMCWkVpAr6G1IZzUT24yEMySRcIlK/Hh7/Qu1Nu5ASRzRuX6+Q== - dependencies: - "@firebase/component" "0.5.17" - "@firebase/installations" "0.5.12" - "@firebase/logger" "0.3.3" - "@firebase/util" "1.6.3" +"@firebase/performance-types@0.2.0": + version "0.2.0" + resolved "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.0.tgz#400685f7a3455970817136d9b48ce07a4b9562ff" + integrity sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA== + +"@firebase/performance@0.6.3": + version "0.6.3" + resolved "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.3.tgz#663c468dc4d62b6e211938377e21a01854803646" + integrity sha512-NQmQN6Ete7i9jz1mzULJZEGvsOmwwdUy6vpqnhUxSFMYPnlBKjX+yypCUUJDDN5zff5+kfwSD1qCyUAaS0xWUA== + dependencies: + "@firebase/component" "0.6.3" + "@firebase/installations" "0.6.3" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/polyfill@0.3.36": - version "0.3.36" - resolved "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.36.tgz#c057cce6748170f36966b555749472b25efdb145" - integrity sha512-zMM9oSJgY6cT2jx3Ce9LYqb0eIpDE52meIzd/oe/y70F+v9u1LDqk5kUF5mf16zovGBWMNFmgzlsh6Wj0OsFtg== - dependencies: - core-js "3.6.5" - promise-polyfill "8.1.3" - whatwg-fetch "2.0.4" - -"@firebase/remote-config-compat@0.1.12": - version "0.1.12" - resolved "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.1.12.tgz#7606752d7bfe2701d58568345ca536beda14ee53" - integrity sha512-Yz7Gtb2rLa7ykXZX9DnSTId8CXd++jFFLW3foUImrYwJEtWgLJc7gwkRfd1M73IlKGNuQAY+DpUNF0n1dLbecA== - dependencies: - "@firebase/component" "0.5.17" - "@firebase/logger" "0.3.3" - "@firebase/remote-config" "0.3.11" - "@firebase/remote-config-types" "0.2.0" - "@firebase/util" "1.6.3" +"@firebase/remote-config-compat@0.2.3": + version "0.2.3" + resolved "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.3.tgz#b0c0ef9978186bc58b262a39b9a41ec1bf819df3" + integrity sha512-w/ZL03YgYaXq03xIRyJ5oPhXZi6iDsY/v0J9Y7I7SqxCYytEnHVrL9nvBqd9R94y5LRAVNPCLokJeeizaUz4VQ== + dependencies: + "@firebase/component" "0.6.3" + "@firebase/logger" "0.4.0" + "@firebase/remote-config" "0.4.3" + "@firebase/remote-config-types" "0.3.0" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/remote-config-types@0.2.0": - version "0.2.0" - resolved "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.2.0.tgz#1e2759fc01f20b58c564db42196f075844c3d1fd" - integrity sha512-hqK5sCPeZvcHQ1D6VjJZdW6EexLTXNMJfPdTwbD8NrXUw6UjWC4KWhLK/TSlL0QPsQtcKRkaaoP+9QCgKfMFPw== - -"@firebase/remote-config@0.3.11": - version "0.3.11" - resolved "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.3.11.tgz#93c82b5944a20c027f4ee82c145813ca96b430bb" - integrity sha512-qA84dstrvVpO7rWT/sb2CLv1kjHVmz59SRFPKohJJYFBcPOGK4Pe4FWWhKAE9yg1Gnl0qYAGkahOwNawq3vE0g== - dependencies: - "@firebase/component" "0.5.17" - "@firebase/installations" "0.5.12" - "@firebase/logger" "0.3.3" - "@firebase/util" "1.6.3" +"@firebase/remote-config-types@0.3.0": + version "0.3.0" + resolved "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.0.tgz#689900dcdb3e5c059e8499b29db393e4e51314b4" + integrity sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA== + +"@firebase/remote-config@0.4.3": + version "0.4.3" + resolved "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.3.tgz#85c4934d093a4c7b8a336af70ada83e936347a2b" + integrity sha512-Q6d4jBWZoNt6SYq87bjtDGUHFkKwAmGnNjWyRjl14AZqE1ilgd9NZHmutharlYJ3LvxMsid80HdK5SgGEpIPfg== + dependencies: + "@firebase/component" "0.6.3" + "@firebase/installations" "0.6.3" + "@firebase/logger" "0.4.0" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/storage-compat@0.1.17": - version "0.1.17" - resolved "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.1.17.tgz#da721071e006d066fb9b1cff69481bd59a02346b" - integrity sha512-nOYmnpI0gwoz5nROseMi9WbmHGf+xumfsOvdPyMZAjy0VqbDnpKIwmTUZQBdR+bLuB5oIkHQsvw9nbb1SH+PzQ== +"@firebase/storage-compat@0.3.1": + version "0.3.1" + resolved "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.1.tgz#b8536c3a435f8ce5eb07796ca10fda16896a9bae" + integrity sha512-6HaTvWsT5Yy3j4UpCZpMcFUYEkJ2XYWukdyTl02u6VjSBRLvkhOXPzEfMvgVWqhnF/rYVfPdjrZ904wk5OxtmQ== dependencies: - "@firebase/component" "0.5.17" - "@firebase/storage" "0.9.9" - "@firebase/storage-types" "0.6.0" - "@firebase/util" "1.6.3" + "@firebase/component" "0.6.3" + "@firebase/storage" "0.11.1" + "@firebase/storage-types" "0.8.0" + "@firebase/util" "1.9.2" tslib "^2.1.0" -"@firebase/storage-types@0.6.0": - version "0.6.0" - resolved "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.6.0.tgz#0b1af64a2965af46fca138e5b70700e9b7e6312a" - integrity sha512-1LpWhcCb1ftpkP/akhzjzeFxgVefs6eMD2QeKiJJUGH1qOiows2w5o0sKCUSQrvrRQS1lz3SFGvNR1Ck/gqxeA== +"@firebase/storage-types@0.8.0": + version "0.8.0" + resolved "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.0.tgz#f1e40a5361d59240b6e84fac7fbbbb622bfaf707" + integrity sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg== -"@firebase/storage@0.9.9": - version "0.9.9" - resolved "https://registry.npmjs.org/@firebase/storage/-/storage-0.9.9.tgz#3d0080dd130bc3315731483384a7ef7c00f76e22" - integrity sha512-Zch7srLT2SIh9y2nCVv/4Kne0HULn7OPkmreY70BJTUJ+g5WLRjggBq6x9fV5ls9V38iqMWfn4prxzX8yIc08A== +"@firebase/storage@0.11.1": + version "0.11.1" + resolved "https://registry.npmjs.org/@firebase/storage/-/storage-0.11.1.tgz#602ddb7bce77077800a46bcdfa76f36d7a265c51" + integrity sha512-Xv8EG2j52ugF2xayBz26U9J0VBXHXPMVxSN+ph3R3BSoHxvMLaPu+qUYKHavSt+zbcgPH2GyBhrCdJK6SaDFPA== dependencies: - "@firebase/component" "0.5.17" - "@firebase/util" "1.6.3" + "@firebase/component" "0.6.3" + "@firebase/util" "1.9.2" node-fetch "2.6.7" tslib "^2.1.0" -"@firebase/util@1.6.3": - version "1.6.3" - resolved "https://registry.npmjs.org/@firebase/util/-/util-1.6.3.tgz#76128c1b5684c031823e95f6c08a7fb8560655c6" - integrity sha512-FujteO6Zjv6v8A4HS+t7c+PjU0Kaxj+rOnka0BsI/twUaCC9t8EQPmXpWZdk7XfszfahJn2pqsflUWUhtUkRlg== +"@firebase/util@1.9.2": + version "1.9.2" + resolved "https://registry.npmjs.org/@firebase/util/-/util-1.9.2.tgz#f5e9e393c5bae3547b9c823ee12076be1e23b1e2" + integrity sha512-9l0uMGPGw3GsoD5khjMmYCCcMq/OR/OOSViiWMN+s2Q0pxM+fYzrii1H+r8qC/uoMjSVXomjLZt0vZIyryCqtQ== dependencies: tslib "^2.1.0" -"@firebase/webchannel-wrapper@0.6.2": - version "0.6.2" - resolved "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.6.2.tgz#6d05fa126104c9907573364dc04147b89b530e15" - integrity sha512-zThUKcqIU6utWzM93uEvhlh8qj8A5LMPFJPvk/ODb+8GSSif19xM2Lw1M2ijyBy8+6skSkQBbavPzOU5Oh/8tQ== +"@firebase/webchannel-wrapper@0.9.0": + version "0.9.0" + resolved "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.9.0.tgz#9340bce56560a8bdba1d25d6281d4bfc397450dc" + integrity sha512-BpiZLBWdLFw+qFel9p3Zs1jD6QmH7Ii4aTDu6+vx8ShdidChZUXqDhYJly4ZjSgQh54miXbBgBrk0S+jTIh/Qg== -"@grpc/grpc-js@^1.3.2": - version "1.3.5" - resolved "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.5.tgz#0cfecfbfd5b7723064db1b7b7109678fbd6ce424" - integrity sha512-V29L2QNKkLWM3bcJfVFMSo+Z7kkO8A1s7MAfdzBXLYEC1PE5/M0n1iXBDiD5aUtyVLh5GILcbme2bGtIHl0FMQ== +"@grpc/grpc-js@~1.7.0": + version "1.7.3" + resolved "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.7.3.tgz#f2ea79f65e31622d7f86d4b4c9ae38f13ccab99a" + integrity sha512-H9l79u4kJ2PVSxUNA08HMYAnUBLj9v6KjYQ7SQ71hOZcEXhShE/y5iQCesP8+6/Ik/7i2O0a10bPquIcYfufog== dependencies: + "@grpc/proto-loader" "^0.7.0" "@types/node" ">=12.12.47" "@grpc/proto-loader@^0.6.13": @@ -2226,6 +2216,17 @@ protobufjs "^6.11.3" yargs "^16.2.0" +"@grpc/proto-loader@^0.7.0": + version "0.7.5" + resolved "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.5.tgz#ee9e7488fa585dc6b0f7fe88cd39723a3e64c906" + integrity sha512-mfcTuMbFowq1wh/Rn5KQl6qb95M21Prej3bewD9dUQMurYGVckGO/Pbe2Ocwto6sD05b/mxZLspvqwx60xO2Rg== + dependencies: + "@types/long" "^4.0.1" + lodash.camelcase "^4.3.0" + long "^4.0.0" + protobufjs "^7.0.0" + yargs "^16.2.0" + "@istanbuljs/schema@^0.1.2": version "0.1.3" resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" @@ -3462,11 +3463,6 @@ core-js-compat@^3.25.1: dependencies: browserslist "^4.21.4" -core-js@3.6.5: - version "3.6.5" - resolved "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" - integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== - core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -4023,38 +4019,37 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" -firebase@9.9.2: - version "9.9.2" - resolved "https://registry.npmjs.org/firebase/-/firebase-9.9.2.tgz#00cbf5912a27b233875626f5e7346ecc582ddabb" - integrity sha512-zhWUEyBQbwWhLEYhULwZ0A6eRuHP/EP2bpwASpHkI1QQgO1GVqkyCZEpp/feGSDve0COhv9oWC1wOuAzrQrV6g== - dependencies: - "@firebase/analytics" "0.8.0" - "@firebase/analytics-compat" "0.1.13" - "@firebase/app" "0.7.30" - "@firebase/app-check" "0.5.12" - "@firebase/app-check-compat" "0.2.12" - "@firebase/app-compat" "0.1.31" - "@firebase/app-types" "0.7.0" - "@firebase/auth" "0.20.5" - "@firebase/auth-compat" "0.2.18" - "@firebase/database" "0.13.4" - "@firebase/database-compat" "0.2.4" - "@firebase/firestore" "3.4.14" - "@firebase/firestore-compat" "0.1.23" - "@firebase/functions" "0.8.4" - "@firebase/functions-compat" "0.2.4" - "@firebase/installations" "0.5.12" - "@firebase/installations-compat" "0.1.12" - "@firebase/messaging" "0.9.16" - "@firebase/messaging-compat" "0.1.16" - "@firebase/performance" "0.5.12" - "@firebase/performance-compat" "0.1.12" - "@firebase/polyfill" "0.3.36" - "@firebase/remote-config" "0.3.11" - "@firebase/remote-config-compat" "0.1.12" - "@firebase/storage" "0.9.9" - "@firebase/storage-compat" "0.1.17" - "@firebase/util" "1.6.3" +firebase@9.17.1: + version "9.17.1" + resolved "https://registry.npmjs.org/firebase/-/firebase-9.17.1.tgz#91c56fe9d9bf5ed1c405030e4fe8133c6069fd40" + integrity sha512-MSZaTRaaRLgDFLqoEnoPYK8zkLwQNvYeLZ3YSKdcQxG8hDifNO22ywS1cSA1ZCGHlQeOsDtfDwBejKcANf/RQw== + dependencies: + "@firebase/analytics" "0.9.3" + "@firebase/analytics-compat" "0.2.3" + "@firebase/app" "0.9.3" + "@firebase/app-check" "0.6.3" + "@firebase/app-check-compat" "0.3.3" + "@firebase/app-compat" "0.2.3" + "@firebase/app-types" "0.9.0" + "@firebase/auth" "0.21.3" + "@firebase/auth-compat" "0.3.3" + "@firebase/database" "0.14.3" + "@firebase/database-compat" "0.3.3" + "@firebase/firestore" "3.8.3" + "@firebase/firestore-compat" "0.3.3" + "@firebase/functions" "0.9.3" + "@firebase/functions-compat" "0.3.3" + "@firebase/installations" "0.6.3" + "@firebase/installations-compat" "0.2.3" + "@firebase/messaging" "0.12.3" + "@firebase/messaging-compat" "0.2.3" + "@firebase/performance" "0.6.3" + "@firebase/performance-compat" "0.2.3" + "@firebase/remote-config" "0.4.3" + "@firebase/remote-config-compat" "0.2.3" + "@firebase/storage" "0.11.1" + "@firebase/storage-compat" "0.3.1" + "@firebase/util" "1.9.2" flat@^5.0.2: version "5.0.2" @@ -4391,11 +4386,6 @@ ieee754@^1.1.13: resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -immediate@~3.0.5: - version "3.0.6" - resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" - integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= - import-local@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" @@ -4735,16 +4725,6 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jszip@^3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/jszip/-/jszip-3.6.0.tgz#839b72812e3f97819cc13ac4134ffced95dd6af9" - integrity sha512-jgnQoG9LKnWO3mnVNBnfhkh0QknICd1FGSrXcgrl67zioyJ4wgx25o9ZqwNtrROSflGBCGYnJfjrIyRIby1OoQ== - dependencies: - lie "~3.3.0" - pako "~1.0.2" - readable-stream "~2.3.6" - set-immediate-shim "~1.0.1" - karma-chrome-launcher@3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz#baca9cc071b1562a1db241827257bfe5cab597ea" @@ -4862,13 +4842,6 @@ kind-of@^6.0.2: resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -lie@~3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" - integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== - dependencies: - immediate "~3.0.5" - loader-runner@^4.2.0: version "4.2.0" resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" @@ -4952,6 +4925,11 @@ long@^4.0.0: resolved "https://registry.npmjs.org/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== +long@^5.0.0: + version "5.2.1" + resolved "https://registry.npmjs.org/long/-/long-5.2.1.tgz#e27595d0083d103d2fa2c20c7699f8e0c92b897f" + integrity sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A== + loupe@^2.3.1: version "2.3.4" resolved "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" @@ -5369,7 +5347,7 @@ pad@^3.2.0: dependencies: wcwidth "^1.0.1" -pako@~1.0.2, pako@~1.0.5: +pako@~1.0.5: version "1.0.11" resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== @@ -5468,11 +5446,6 @@ process@^0.11.10: resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= -promise-polyfill@8.1.3: - version "8.1.3" - resolved "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.3.tgz#8c99b3cf53f3a91c68226ffde7bde81d7f904116" - integrity sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g== - protobufjs@^6.11.3: version "6.11.3" resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74" @@ -5492,6 +5465,24 @@ protobufjs@^6.11.3: "@types/node" ">=13.7.0" long "^4.0.0" +protobufjs@^7.0.0: + version "7.2.2" + resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.2.tgz#2af401d8c547b9476fb37ffc65782cf302342ca3" + integrity sha512-++PrQIjrom+bFDPpfmqXfAGSQs40116JRrqqyf53dymUMvvb5d/LMRyicRoF1AUKoXVS1/IgJXlEgcpr4gTF3Q== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/node" ">=13.7.0" + long "^5.0.0" + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -5589,7 +5580,7 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" -readable-stream@^2.0.1, readable-stream@~2.3.6: +readable-stream@^2.0.1: version "2.3.7" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -5828,19 +5819,10 @@ select-hose@^2.0.0: resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= -selenium-webdriver@4.1.2: - version "4.1.2" - resolved "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.1.2.tgz#d463b4335632d2ea41a9e988e435a55dc41f5314" - integrity sha512-e4Ap8vQvhipgBB8Ry9zBiKGkU6kHKyNnWiavGGLKkrdW81Zv7NVMtFOL/j3yX0G8QScM7XIXijKssNd4EUxSOw== - dependencies: - jszip "^3.6.0" - tmp "^0.2.1" - ws ">=7.4.6" - -selfsigned@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" - integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== +selfsigned@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" + integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== dependencies: node-forge "^1" @@ -5903,11 +5885,6 @@ serve-static@1.15.0: parseurl "~1.3.3" send "0.18.0" -set-immediate-shim@~1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= - setimmediate@^1.0.4: version "1.0.5" resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -6470,10 +6447,10 @@ webpack-dev-middleware@^5.3.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@4.10.0: - version "4.10.0" - resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.10.0.tgz#de270d0009eba050546912be90116e7fd740a9ca" - integrity sha512-7dezwAs+k6yXVFZ+MaL8VnE+APobiO3zvpp3rBHe/HmWQ+avwh0Q3d0xxacOiBybZZ3syTZw9HXzpa3YNbAZDQ== +webpack-dev-server@4.11.1: + version "4.11.1" + resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz#ae07f0d71ca0438cf88446f09029b92ce81380b5" + integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" @@ -6498,7 +6475,7 @@ webpack-dev-server@4.10.0: p-retry "^4.5.0" rimraf "^3.0.2" schema-utils "^4.0.0" - selfsigned "^2.0.1" + selfsigned "^2.1.1" serve-index "^1.9.1" sockjs "^0.3.24" spdy "^4.0.2" @@ -6518,10 +6495,10 @@ webpack-sources@^3.2.3: resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@5.75.0: - version "5.75.0" - resolved "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz#1e440468647b2505860e94c9ff3e44d5b582c152" - integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ== +webpack@5.76.0: + version "5.76.0" + resolved "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c" + integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" @@ -6562,11 +6539,6 @@ websocket-extensions@>=0.1.1: resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== -whatwg-fetch@2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" - integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== - whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" @@ -6637,11 +6609,6 @@ wrappy@1: resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@>=7.4.6: - version "7.5.3" - resolved "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" - integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== - ws@^8.4.2: version "8.6.0" resolved "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz#e5e9f1d9e7ff88083d0c0dd8281ea662a42c9c23" From be8b26523414e3c317369547d1c21341eeabbfc1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Mar 2023 12:23:09 -0700 Subject: [PATCH 21/26] chore(deps): update endbug/add-and-commit action to v9 (#6425) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/update-api-reports.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-api-reports.yml b/.github/workflows/update-api-reports.yml index da09152d3c2..f566337600d 100644 --- a/.github/workflows/update-api-reports.yml +++ b/.github/workflows/update-api-reports.yml @@ -27,7 +27,7 @@ jobs: run: yarn build id: update-api-reports - name: Commit & Push changes - uses: EndBug/add-and-commit@v7 + uses: EndBug/add-and-commit@v9 with: add: 'common/api-review/*' message: 'Update API reports' From cc3c93a43fd34b428a84226470e60639875413bb Mon Sep 17 00:00:00 2001 From: Christina Holland Date: Mon, 20 Mar 2023 11:26:59 -0700 Subject: [PATCH 22/26] Add changeset (#7137) --- .changeset/brown-beers-tease.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/brown-beers-tease.md b/.changeset/brown-beers-tease.md index e0e8e7adc9e..f22213b3489 100644 --- a/.changeset/brown-beers-tease.md +++ b/.changeset/brown-beers-tease.md @@ -1,5 +1,6 @@ --- "@firebase/firestore": minor +"firebase": minor --- Introduces a new way to config Firestore SDK Cache. From b26c07257eb54c74ca573cf82e2de03a0fa3dd7a Mon Sep 17 00:00:00 2001 From: Denver Coneybeare Date: Mon, 20 Mar 2023 18:39:54 -0400 Subject: [PATCH 23/26] Firestore: query.test.ts: add a test that resumes a query with existence filter (#7134) --- .../test/integration/api/query.test.ts | 57 +++++++++++++++++++ .../test/integration/util/helpers.ts | 37 ++++++++++-- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/packages/firestore/test/integration/api/query.test.ts b/packages/firestore/test/integration/api/query.test.ts index bec924e3fb9..cd401b28d68 100644 --- a/packages/firestore/test/integration/api/query.test.ts +++ b/packages/firestore/test/integration/api/query.test.ts @@ -47,6 +47,7 @@ import { Query, query, QuerySnapshot, + runTransaction, setDoc, startAfter, startAt, @@ -2059,6 +2060,62 @@ apiDescribe('Queries', (persistence: boolean) => { }); }); }); + + it('resuming a query should use existence filter to detect deletes', async () => { + // Prepare the names and contents of the 100 documents to create. + const testDocs: { [key: string]: object } = {}; + for (let i = 0; i < 100; i++) { + testDocs['doc' + (1000 + i)] = { key: 42 }; + } + + return withTestCollection(persistence, testDocs, async (coll, db) => { + // Run a query to populate the local cache with the 100 documents and a + // resume token. + const snapshot1 = await getDocs(coll); + expect(snapshot1.size, 'snapshot1.size').to.equal(100); + const createdDocuments = snapshot1.docs.map(snapshot => snapshot.ref); + + // Delete 50 of the 100 documents. Do this in a transaction, rather than + // deleteDoc(), to avoid affecting the local cache. + const deletedDocumentIds = new Set(); + await runTransaction(db, async txn => { + for (let i = 0; i < createdDocuments.length; i += 2) { + const documentToDelete = createdDocuments[i]; + txn.delete(documentToDelete); + deletedDocumentIds.add(documentToDelete.id); + } + }); + + // Wait for 10 seconds, during which Watch will stop tracking the query + // and will send an existence filter rather than "delete" events when the + // query is resumed. + await new Promise(resolve => setTimeout(resolve, 10000)); + + // Resume the query and save the resulting snapshot for verification. + const snapshot2 = await getDocs(coll); + + // Verify that the snapshot from the resumed query contains the expected + // documents; that is, that it contains the 50 documents that were _not_ + // deleted. + // TODO(b/270731363): Remove the "if" condition below once the + // Firestore Emulator is fixed to send an existence filter. At the time of + // writing, the Firestore emulator fails to send an existence filter, + // resulting in the client including the deleted documents in the snapshot + // of the resumed query. + if (!(USE_EMULATOR && snapshot2.size === 100)) { + const actualDocumentIds = snapshot2.docs + .map(documentSnapshot => documentSnapshot.ref.id) + .sort(); + const expectedDocumentIds = createdDocuments + .filter(documentRef => !deletedDocumentIds.has(documentRef.id)) + .map(documentRef => documentRef.id) + .sort(); + expect(actualDocumentIds, 'snapshot2.docs').to.deep.equal( + expectedDocumentIds + ); + } + }); + }).timeout('90s'); }); function verifyDocumentChange( diff --git a/packages/firestore/test/integration/util/helpers.ts b/packages/firestore/test/integration/util/helpers.ts index 2d579afeb5f..5cd73532d5c 100644 --- a/packages/firestore/test/integration/util/helpers.ts +++ b/packages/firestore/test/integration/util/helpers.ts @@ -32,7 +32,9 @@ import { PrivateSettings, SnapshotListenOptions, newTestFirestore, - newTestApp + newTestApp, + writeBatch, + WriteBatch } from './firebase_export'; import { ALT_PROJECT_ID, @@ -317,11 +319,34 @@ export function withTestCollectionSettings( const collectionId = 'test-collection-' + doc(collection(testDb, 'x')).id; const testCollection = collection(testDb, collectionId); const setupCollection = collection(setupDb, collectionId); - const sets: Array> = []; - Object.keys(docs).forEach(key => { - sets.push(setDoc(doc(setupCollection, key), docs[key])); - }); - return Promise.all(sets).then(() => fn(testCollection, testDb)); + + const writeBatchCommits: Array> = []; + let writeBatch_: WriteBatch | null = null; + let writeBatchSize = 0; + + for (const key of Object.keys(docs)) { + if (writeBatch_ === null) { + writeBatch_ = writeBatch(setupDb); + } + + writeBatch_.set(doc(setupCollection, key), docs[key]); + writeBatchSize++; + + // Write batches are capped at 500 writes. Use 400 just to be safe. + if (writeBatchSize === 400) { + writeBatchCommits.push(writeBatch_.commit()); + writeBatch_ = null; + writeBatchSize = 0; + } + } + + if (writeBatch_ !== null) { + writeBatchCommits.push(writeBatch_.commit()); + } + + return Promise.all(writeBatchCommits).then(() => + fn(testCollection, testDb) + ); } ); } From 8a1f7a46ca476d58322ac3fad4e0557dfd4b799c Mon Sep 17 00:00:00 2001 From: Christina Holland Date: Tue, 21 Mar 2023 13:03:50 -0700 Subject: [PATCH 24/26] Unmangle a switch variable for Closure (#7136) --- packages/firebase/compat/rollup.config.js | 5 ++++- packages/firestore/rollup.shared.js | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/firebase/compat/rollup.config.js b/packages/firebase/compat/rollup.config.js index e7b05d2e2d8..4b481b93b1f 100644 --- a/packages/firebase/compat/rollup.config.js +++ b/packages/firebase/compat/rollup.config.js @@ -31,7 +31,10 @@ import { emitModulePackageFile } from '../../../scripts/build/rollup_emit_module const external = Object.keys(pkg.dependencies || {}); const uglifyOptions = { - mangle: true, + mangle: { + // Hack for a bug in Closure regarding switch block scope + reserved: ['__PRIVATE_lastReasonableEscapeIndex'] + }, webkit: true // Necessary to avoid https://bugs.webkit.org/show_bug.cgi?id=223533 }; diff --git a/packages/firestore/rollup.shared.js b/packages/firestore/rollup.shared.js index 42836f0aa2e..3f37106344c 100644 --- a/packages/firestore/rollup.shared.js +++ b/packages/firestore/rollup.shared.js @@ -150,8 +150,10 @@ const manglePrivatePropertiesOptions = { // This can be removed if the problem in the downstream library is fixed // or if terser's mangler provides an option to avoid mangling everything // that isn't a property. + // `lastReasonableEscapeIndex` was causing problems in a switch statement + // due to a Closure bug. // See issue: https://github.com/firebase/firebase-js-sdk/issues/5384 - reserved: ['_getProvider'], + reserved: ['_getProvider', '__PRIVATE_lastReasonableEscapeIndex'], properties: { regex: /^__PRIVATE_/, // All JS Keywords are reserved. Although this should be taken cared of by From ee6cc363b26421c4e35501c76f3efedf755efff8 Mon Sep 17 00:00:00 2001 From: dwyfrequency Date: Wed, 22 Feb 2023 11:50:21 -0500 Subject: [PATCH 25/26] Remove dependency merge conflicts. --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index ad3dd89e986..e84be0212e2 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "@types/tmp": "0.2.3", "@types/trusted-types": "2.0.3", "@types/yargs": "17.0.22", + "@types/trusted-types": "2.0.3", "@typescript-eslint/eslint-plugin": "5.43.0", "@typescript-eslint/eslint-plugin-tslint": "5.43.0", "@typescript-eslint/parser": "5.43.0", From 62f0a42e5697dc8eba59b5f9e833bab44ec1f2d9 Mon Sep 17 00:00:00 2001 From: dwyfrequency Date: Thu, 23 Mar 2023 11:33:59 -0400 Subject: [PATCH 26/26] Remove duplicate types package --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index e84be0212e2..f2968c9d201 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,6 @@ "@types/sinon": "9.0.11", "@types/sinon-chai": "3.2.9", "@types/tmp": "0.2.3", - "@types/trusted-types": "2.0.3", "@types/yargs": "17.0.22", "@types/trusted-types": "2.0.3", "@typescript-eslint/eslint-plugin": "5.43.0",