@firebase/firestore
Version:
The Cloud Firestore component of the Firebase JS SDK.
1,375 lines (1,298 loc) • 305 kB
JavaScript
import { _isFirebaseServerApp as t, _getProvider, getApp as e, _removeServiceInstance as r, _registerComponent as n, registerVersion as i, SDK_VERSION as s } from "@firebase/app";
import { Component as o } from "@firebase/component";
import { Logger as a, LogLevel as u } from "@firebase/logger";
import { FirebaseError as _, isCloudWorkstation as c, base64 as l, DecodeBase64StringError as h, getDefaultEmulatorHostnameAndPort as d, pingServer as f, updateEmulatorBanner as E, deepEqual as m, createMockUserToken as T, getModularInstance as A } from "@firebase/util";
import { Integer as P } from "@firebase/webchannel-wrapper/bloom-blob";
const R = "4.7.17";
/**
* @license
* Copyright 2017 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.
*/
/**
* Simple wrapper around a nullable UID. Mostly exists to make code more
* readable.
*/ class User {
constructor(t) {
this.uid = t;
}
isAuthenticated() {
return null != this.uid;
}
/**
* Returns a key representing this user, suitable for inclusion in a
* dictionary.
*/ toKey() {
return this.isAuthenticated() ? "uid:" + this.uid : "anonymous-user";
}
isEqual(t) {
return t.uid === this.uid;
}
}
/** A user with a null UID. */ User.UNAUTHENTICATED = new User(null),
// TODO(mikelehen): Look into getting a proper uid-equivalent for
// non-FirebaseAuth providers.
User.GOOGLE_CREDENTIALS = new User("google-credentials-uid"), User.FIRST_PARTY = new User("first-party-uid"),
User.MOCK_USER = new User("mock-user");
/**
* @license
* Copyright 2017 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.
*/
let I = "11.9.0";
/**
* @license
* Copyright 2017 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.
*/
const V = new a("@firebase/firestore");
/**
* Sets the verbosity of Cloud Firestore logs (debug, error, or silent).
*
* @param logLevel - The verbosity you set for activity and error logging. Can
* be any of the following values:
*
* <ul>
* <li>`debug` for the most verbose logging level, primarily for
* debugging.</li>
* <li>`error` to log errors only.</li>
* <li><code>`silent` to turn off logging.</li>
* </ul>
*/ function setLogLevel(t) {
V.setLogLevel(t);
}
function __PRIVATE_logDebug(t, ...e) {
if (V.logLevel <= u.DEBUG) {
const r = e.map(__PRIVATE_argToString);
V.debug(`Firestore (${I}): ${t}`, ...r);
}
}
function __PRIVATE_logError(t, ...e) {
if (V.logLevel <= u.ERROR) {
const r = e.map(__PRIVATE_argToString);
V.error(`Firestore (${I}): ${t}`, ...r);
}
}
/**
* @internal
*/ function __PRIVATE_logWarn(t, ...e) {
if (V.logLevel <= u.WARN) {
const r = e.map(__PRIVATE_argToString);
V.warn(`Firestore (${I}): ${t}`, ...r);
}
}
/**
* Converts an additional log parameter to a string representation.
*/ function __PRIVATE_argToString(t) {
if ("string" == typeof t) return t;
try {
/**
* @license
* Copyright 2020 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.
*/
/** Formats an object as a JSON string, suitable for logging. */
return function __PRIVATE_formatJSON(t) {
return JSON.stringify(t);
}(t);
} catch (e) {
// Converting to JSON failed, just log the object directly
return t;
}
}
/**
* @license
* Copyright 2017 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.
*/ function fail(t, e, r) {
let n = "Unexpected state";
"string" == typeof e ? n = e : r = e, __PRIVATE__fail(t, n, r);
}
function __PRIVATE__fail(t, e, r) {
// Log the failure in addition to throw an exception, just in case the
// exception is swallowed.
let n = `FIRESTORE (${I}) INTERNAL ASSERTION FAILED: ${e} (ID: ${t.toString(16)})`;
if (void 0 !== r) try {
n += " CONTEXT: " + JSON.stringify(r);
} catch (t) {
n += " CONTEXT: " + r;
}
// NOTE: We don't use FirestoreError here because these are internal failures
// that cannot be handled by the user. (Also it would create a circular
// dependency between the error and assert modules which doesn't work.)
throw __PRIVATE_logError(n), new Error(n);
}
function __PRIVATE_hardAssert(t, e, r, n) {
let i = "Unexpected state";
"string" == typeof r ? i = r : n = r, t || __PRIVATE__fail(e, i, n);
}
/**
* Casts `obj` to `T`. In non-production builds, verifies that `obj` is an
* instance of `T` before casting.
*/ function __PRIVATE_debugCast(t,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
e) {
return t;
}
/**
* @license
* Copyright 2017 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.
*/ const p = "ok", y = "cancelled", g = "unknown", w = "invalid-argument", F = "deadline-exceeded", v = "not-found", D = "already-exists", b = "permission-denied", C = "unauthenticated", S = "resource-exhausted", N = "failed-precondition", O = "aborted", q = "out-of-range", B = "unimplemented", $ = "internal", Q = "unavailable", L = "data-loss";
/** An error returned by a Firestore operation. */ class FirestoreError extends _ {
/** @hideconstructor */
constructor(
/**
* The backend error code associated with this error.
*/
t,
/**
* A custom error description.
*/
e) {
super(t, e), this.code = t, this.message = e,
// HACK: We write a toString property directly because Error is not a real
// class and so inheritance does not work correctly. We could alternatively
// do the same "back-door inheritance" trick that FirebaseError does.
this.toString = () => `${this.name}: [code=${this.code}]: ${this.message}`;
}
}
/**
* @license
* Copyright 2017 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.
*/ class __PRIVATE_Deferred {
constructor() {
this.promise = new Promise(((t, e) => {
this.resolve = t, this.reject = e;
}));
}
}
/**
* @license
* Copyright 2017 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.
*/ class __PRIVATE_OAuthToken {
constructor(t, e) {
this.user = e, this.type = "OAuth", this.headers = new Map, this.headers.set("Authorization", `Bearer ${t}`);
}
}
/**
* A CredentialsProvider that always yields an empty token.
* @internal
*/ class __PRIVATE_EmptyAuthCredentialsProvider {
getToken() {
return Promise.resolve(null);
}
invalidateToken() {}
start(t, e) {
// Fire with initial user.
t.enqueueRetryable((() => e(User.UNAUTHENTICATED)));
}
shutdown() {}
}
/**
* A CredentialsProvider that always returns a constant token. Used for
* emulator token mocking.
*/ class __PRIVATE_EmulatorAuthCredentialsProvider {
constructor(t) {
this.token = t,
/**
* Stores the listener registered with setChangeListener()
* This isn't actually necessary since the UID never changes, but we use this
* to verify the listen contract is adhered to in tests.
*/
this.changeListener = null;
}
getToken() {
return Promise.resolve(this.token);
}
invalidateToken() {}
start(t, e) {
this.changeListener = e,
// Fire with initial user.
t.enqueueRetryable((() => e(this.token.user)));
}
shutdown() {
this.changeListener = null;
}
}
/** Credential provider for the Lite SDK. */ class __PRIVATE_LiteAuthCredentialsProvider {
constructor(t) {
this.auth = null, t.onInit((t => {
this.auth = t;
}));
}
getToken() {
return this.auth ? this.auth.getToken().then((t => t ? (__PRIVATE_hardAssert("string" == typeof t.accessToken, 42297, {
t: t
}), new __PRIVATE_OAuthToken(t.accessToken, new User(this.auth.getUid()))) : null)) : Promise.resolve(null);
}
invalidateToken() {}
start(t, e) {}
shutdown() {}
}
/*
* FirstPartyToken provides a fresh token each time its value
* is requested, because if the token is too old, requests will be rejected.
* Technically this may no longer be necessary since the SDK should gracefully
* recover from unauthenticated errors (see b/33147818 for context), but it's
* safer to keep the implementation as-is.
*/ class __PRIVATE_FirstPartyToken {
constructor(t, e, r) {
this.i = t, this.o = e, this.u = r, this.type = "FirstParty", this.user = User.FIRST_PARTY,
this.l = new Map;
}
/**
* Gets an authorization token, using a provided factory function, or return
* null.
*/ h() {
return this.u ? this.u() : null;
}
get headers() {
this.l.set("X-Goog-AuthUser", this.i);
// Use array notation to prevent minification
const t = this.h();
return t && this.l.set("Authorization", t), this.o && this.l.set("X-Goog-Iam-Authorization-Token", this.o),
this.l;
}
}
/*
* Provides user credentials required for the Firestore JavaScript SDK
* to authenticate the user, using technique that is only available
* to applications hosted by Google.
*/ class __PRIVATE_FirstPartyAuthCredentialsProvider {
constructor(t, e, r) {
this.i = t, this.o = e, this.u = r;
}
getToken() {
return Promise.resolve(new __PRIVATE_FirstPartyToken(this.i, this.o, this.u));
}
start(t, e) {
// Fire with initial uid.
t.enqueueRetryable((() => e(User.FIRST_PARTY)));
}
shutdown() {}
invalidateToken() {}
}
class AppCheckToken {
constructor(t) {
this.value = t, this.type = "AppCheck", this.headers = new Map, t && t.length > 0 && this.headers.set("x-firebase-appcheck", this.value);
}
}
/** AppCheck token provider for the Lite SDK. */ class __PRIVATE_LiteAppCheckTokenProvider {
constructor(e, r) {
this.m = r, this.appCheck = null, this.T = null, t(e) && e.settings.appCheckToken && (this.T = e.settings.appCheckToken),
r.onInit((t => {
this.appCheck = t;
}));
}
getToken() {
return this.T ? Promise.resolve(new AppCheckToken(this.T)) : this.appCheck ? this.appCheck.getToken().then((t => t ? (__PRIVATE_hardAssert("string" == typeof t.token, 3470, {
tokenResult: t
}), new AppCheckToken(t.token)) : null)) : Promise.resolve(null);
}
invalidateToken() {}
start(t, e) {}
shutdown() {}
}
/**
* Builds a CredentialsProvider depending on the type of
* the credentials passed in.
*/
/**
* @license
* Copyright 2017 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.
*/
class DatabaseInfo {
/**
* Constructs a DatabaseInfo using the provided host, databaseId and
* persistenceKey.
*
* @param databaseId - The database to use.
* @param appId - The Firebase App Id.
* @param persistenceKey - A unique identifier for this Firestore's local
* storage (used in conjunction with the databaseId).
* @param host - The Firestore backend host to connect to.
* @param ssl - Whether to use SSL when connecting.
* @param forceLongPolling - Whether to use the forceLongPolling option
* when using WebChannel as the network transport.
* @param autoDetectLongPolling - Whether to use the detectBufferingProxy
* option when using WebChannel as the network transport.
* @param longPollingOptions Options that configure long-polling.
* @param useFetchStreams Whether to use the Fetch API instead of
* XMLHTTPRequest
*/
constructor(t, e, r, n, i, s, o, a, u, _) {
this.databaseId = t, this.appId = e, this.persistenceKey = r, this.host = n, this.ssl = i,
this.forceLongPolling = s, this.autoDetectLongPolling = o, this.longPollingOptions = a,
this.useFetchStreams = u, this.isUsingEmulator = _;
}
}
/** The default database name for a project. */ const k = "(default)";
/**
* Represents the database ID a Firestore client is associated with.
* @internal
*/ class DatabaseId {
constructor(t, e) {
this.projectId = t, this.database = e || k;
}
static empty() {
return new DatabaseId("", "");
}
get isDefaultDatabase() {
return this.database === k;
}
isEqual(t) {
return t instanceof DatabaseId && t.projectId === this.projectId && t.database === this.database;
}
}
/**
* @license
* Copyright 2020 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.
*/
/**
* Generates `nBytes` of random bytes.
*
* If `nBytes < 0` , an error will be thrown.
*/
function __PRIVATE_randomBytes(t) {
// Polyfills for IE and WebWorker by using `self` and `msCrypto` when `crypto` is not available.
const e =
// eslint-disable-next-line @typescript-eslint/no-explicit-any
"undefined" != typeof self && (self.crypto || self.msCrypto), r = new Uint8Array(t);
if (e && "function" == typeof e.getRandomValues) e.getRandomValues(r); else
// Falls back to Math.random
for (let e = 0; e < t; e++) r[e] = Math.floor(256 * Math.random());
return r;
}
/**
* @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.
*/
/**
* An instance of the Platform's 'TextEncoder' implementation.
*/
/**
* @license
* Copyright 2017 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.
*/
/**
* A utility class for generating unique alphanumeric IDs of a specified length.
*
* @internal
* Exported internally for testing purposes.
*/
class __PRIVATE_AutoId {
static newId() {
// Alphanumeric characters
const t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", e = 62 * Math.floor(256 / 62);
// The largest byte value that is a multiple of `char.length`.
let r = "";
for (;r.length < 20; ) {
const n = __PRIVATE_randomBytes(40);
for (let i = 0; i < n.length; ++i)
// Only accept values that are [0, maxMultiple), this ensures they can
// be evenly mapped to indices of `chars` via a modulo operation.
r.length < 20 && n[i] < e && (r += t.charAt(n[i] % 62));
}
return r;
}
}
function __PRIVATE_primitiveComparator(t, e) {
return t < e ? -1 : t > e ? 1 : 0;
}
/** Compare strings in UTF-8 encoded byte order */ function __PRIVATE_compareUtf8Strings(t, e) {
let r = 0;
for (;r < t.length && r < e.length; ) {
const n = t.codePointAt(r), i = e.codePointAt(r);
if (n !== i) {
if (n < 128 && i < 128)
// ASCII comparison
return __PRIVATE_primitiveComparator(n, i);
{
// Lazy instantiate TextEncoder
const s = new TextEncoder, o = __PRIVATE_compareByteArrays(s.encode(__PRIVATE_getUtf8SafeSubstring(t, r)), s.encode(__PRIVATE_getUtf8SafeSubstring(e, r)));
// UTF-8 encode the character at index i for byte comparison.
return 0 !== o ? o : __PRIVATE_primitiveComparator(n, i);
}
}
// Increment by 2 for surrogate pairs, 1 otherwise
r += n > 65535 ? 2 : 1;
}
// Compare lengths if all characters are equal
return __PRIVATE_primitiveComparator(t.length, e.length);
}
function __PRIVATE_getUtf8SafeSubstring(t, e) {
return t.codePointAt(e) > 65535 ? t.substring(e, e + 2) : t.substring(e, e + 1);
}
function __PRIVATE_compareByteArrays(t, e) {
for (let r = 0; r < t.length && r < e.length; ++r) if (t[r] !== e[r]) return __PRIVATE_primitiveComparator(t[r], e[r]);
return __PRIVATE_primitiveComparator(t.length, e.length);
}
/** Helper to compare arrays using isEqual(). */ function __PRIVATE_arrayEquals(t, e, r) {
return t.length === e.length && t.every(((t, n) => r(t, e[n])));
}
/**
* @license
* Copyright 2017 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.
*/ const U = "__name__";
/**
* Path represents an ordered sequence of string segments.
*/ class BasePath {
constructor(t, e, r) {
void 0 === e ? e = 0 : e > t.length && fail(637, {
offset: e,
range: t.length
}), void 0 === r ? r = t.length - e : r > t.length - e && fail(1746, {
length: r,
range: t.length - e
}), this.segments = t, this.offset = e, this.len = r;
}
get length() {
return this.len;
}
isEqual(t) {
return 0 === BasePath.comparator(this, t);
}
child(t) {
const e = this.segments.slice(this.offset, this.limit());
return t instanceof BasePath ? t.forEach((t => {
e.push(t);
})) : e.push(t), this.construct(e);
}
/** The index of one past the last segment of the path. */ limit() {
return this.offset + this.length;
}
popFirst(t) {
return t = void 0 === t ? 1 : t, this.construct(this.segments, this.offset + t, this.length - t);
}
popLast() {
return this.construct(this.segments, this.offset, this.length - 1);
}
firstSegment() {
return this.segments[this.offset];
}
lastSegment() {
return this.get(this.length - 1);
}
get(t) {
return this.segments[this.offset + t];
}
isEmpty() {
return 0 === this.length;
}
isPrefixOf(t) {
if (t.length < this.length) return !1;
for (let e = 0; e < this.length; e++) if (this.get(e) !== t.get(e)) return !1;
return !0;
}
isImmediateParentOf(t) {
if (this.length + 1 !== t.length) return !1;
for (let e = 0; e < this.length; e++) if (this.get(e) !== t.get(e)) return !1;
return !0;
}
forEach(t) {
for (let e = this.offset, r = this.limit(); e < r; e++) t(this.segments[e]);
}
toArray() {
return this.segments.slice(this.offset, this.limit());
}
/**
* Compare 2 paths segment by segment, prioritizing numeric IDs
* (e.g., "__id123__") in numeric ascending order, followed by string
* segments in lexicographical order.
*/ static comparator(t, e) {
const r = Math.min(t.length, e.length);
for (let n = 0; n < r; n++) {
const r = BasePath.compareSegments(t.get(n), e.get(n));
if (0 !== r) return r;
}
return __PRIVATE_primitiveComparator(t.length, e.length);
}
static compareSegments(t, e) {
const r = BasePath.isNumericId(t), n = BasePath.isNumericId(e);
return r && !n ? -1 : !r && n ? 1 : r && n ? BasePath.extractNumericId(t).compare(BasePath.extractNumericId(e)) : __PRIVATE_compareUtf8Strings(t, e);
}
// Checks if a segment is a numeric ID (starts with "__id" and ends with "__").
static isNumericId(t) {
return t.startsWith("__id") && t.endsWith("__");
}
static extractNumericId(t) {
return P.fromString(t.substring(4, t.length - 2));
}
}
/**
* A slash-separated path for navigating resources (documents and collections)
* within Firestore.
*
* @internal
*/ class ResourcePath extends BasePath {
construct(t, e, r) {
return new ResourcePath(t, e, r);
}
canonicalString() {
// NOTE: The client is ignorant of any path segments containing escape
// sequences (e.g. __id123__) and just passes them through raw (they exist
// for legacy reasons and should not be used frequently).
return this.toArray().join("/");
}
toString() {
return this.canonicalString();
}
/**
* Returns a string representation of this path
* where each path segment has been encoded with
* `encodeURIComponent`.
*/ toUriEncodedString() {
return this.toArray().map(encodeURIComponent).join("/");
}
/**
* Creates a resource path from the given slash-delimited string. If multiple
* arguments are provided, all components are combined. Leading and trailing
* slashes from all components are ignored.
*/ static fromString(...t) {
// NOTE: The client is ignorant of any path segments containing escape
// sequences (e.g. __id123__) and just passes them through raw (they exist
// for legacy reasons and should not be used frequently).
const e = [];
for (const r of t) {
if (r.indexOf("//") >= 0) throw new FirestoreError(w, `Invalid segment (${r}). Paths must not contain // in them.`);
// Strip leading and trailing slashed.
e.push(...r.split("/").filter((t => t.length > 0)));
}
return new ResourcePath(e);
}
static emptyPath() {
return new ResourcePath([]);
}
}
const M = /^[_a-zA-Z][_a-zA-Z0-9]*$/;
/**
* A dot-separated path for navigating sub-objects within a document.
* @internal
*/ class FieldPath$1 extends BasePath {
construct(t, e, r) {
return new FieldPath$1(t, e, r);
}
/**
* Returns true if the string could be used as a segment in a field path
* without escaping.
*/ static isValidIdentifier(t) {
return M.test(t);
}
canonicalString() {
return this.toArray().map((t => (t = t.replace(/\\/g, "\\\\").replace(/`/g, "\\`"),
FieldPath$1.isValidIdentifier(t) || (t = "`" + t + "`"), t))).join(".");
}
toString() {
return this.canonicalString();
}
/**
* Returns true if this field references the key of a document.
*/ isKeyField() {
return 1 === this.length && this.get(0) === U;
}
/**
* The field designating the key of a document.
*/ static keyField() {
return new FieldPath$1([ U ]);
}
/**
* Parses a field string from the given server-formatted string.
*
* - Splitting the empty string is not allowed (for now at least).
* - Empty segments within the string (e.g. if there are two consecutive
* separators) are not allowed.
*
* TODO(b/37244157): we should make this more strict. Right now, it allows
* non-identifier path components, even if they aren't escaped.
*/ static fromServerFormat(t) {
const e = [];
let r = "", n = 0;
const __PRIVATE_addCurrentSegment = () => {
if (0 === r.length) throw new FirestoreError(w, `Invalid field path (${t}). Paths must not be empty, begin with '.', end with '.', or contain '..'`);
e.push(r), r = "";
};
let i = !1;
for (;n < t.length; ) {
const e = t[n];
if ("\\" === e) {
if (n + 1 === t.length) throw new FirestoreError(w, "Path has trailing escape character: " + t);
const e = t[n + 1];
if ("\\" !== e && "." !== e && "`" !== e) throw new FirestoreError(w, "Path has invalid escape sequence: " + t);
r += e, n += 2;
} else "`" === e ? (i = !i, n++) : "." !== e || i ? (r += e, n++) : (__PRIVATE_addCurrentSegment(),
n++);
}
if (__PRIVATE_addCurrentSegment(), i) throw new FirestoreError(w, "Unterminated ` in path: " + t);
return new FieldPath$1(e);
}
static emptyPath() {
return new FieldPath$1([]);
}
}
/**
* @license
* Copyright 2017 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.
*/
/**
* @internal
*/ class DocumentKey {
constructor(t) {
this.path = t;
}
static fromPath(t) {
return new DocumentKey(ResourcePath.fromString(t));
}
static fromName(t) {
return new DocumentKey(ResourcePath.fromString(t).popFirst(5));
}
static empty() {
return new DocumentKey(ResourcePath.emptyPath());
}
get collectionGroup() {
return this.path.popLast().lastSegment();
}
/** Returns true if the document is in the specified collectionId. */ hasCollectionId(t) {
return this.path.length >= 2 && this.path.get(this.path.length - 2) === t;
}
/** Returns the collection group (i.e. the name of the parent collection) for this key. */ getCollectionGroup() {
return this.path.get(this.path.length - 2);
}
/** Returns the fully qualified path to the parent collection. */ getCollectionPath() {
return this.path.popLast();
}
isEqual(t) {
return null !== t && 0 === ResourcePath.comparator(this.path, t.path);
}
toString() {
return this.path.toString();
}
static comparator(t, e) {
return ResourcePath.comparator(t.path, e.path);
}
static isDocumentKey(t) {
return t.length % 2 == 0;
}
/**
* Creates and returns a new document key with the given segments.
*
* @param segments - The segments of the path to the document
* @returns A new instance of DocumentKey
*/ static fromSegments(t) {
return new DocumentKey(new ResourcePath(t.slice()));
}
}
/**
* @license
* Copyright 2017 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.
*/ function __PRIVATE_validateNonEmptyArgument(t, e, r) {
if (!r) throw new FirestoreError(w, `Function ${t}() cannot be called with an empty ${e}.`);
}
/**
* Validates that two boolean options are not set at the same time.
* @internal
*/
/**
* Validates that `path` refers to a document (indicated by the fact it contains
* an even numbers of segments).
*/
function __PRIVATE_validateDocumentPath(t) {
if (!DocumentKey.isDocumentKey(t)) throw new FirestoreError(w, `Invalid document reference. Document references must have an even number of segments, but ${t} has ${t.length}.`);
}
/**
* Validates that `path` refers to a collection (indicated by the fact it
* contains an odd numbers of segments).
*/ function __PRIVATE_validateCollectionPath(t) {
if (DocumentKey.isDocumentKey(t)) throw new FirestoreError(w, `Invalid collection reference. Collection references must have an odd number of segments, but ${t} has ${t.length}.`);
}
/**
* Returns true if it's a non-null object without a custom prototype
* (i.e. excludes Array, Date, etc.).
*/
/** Returns a string describing the type / value of the provided input. */
function __PRIVATE_valueDescription(t) {
if (void 0 === t) return "undefined";
if (null === t) return "null";
if ("string" == typeof t) return t.length > 20 && (t = `${t.substring(0, 20)}...`),
JSON.stringify(t);
if ("number" == typeof t || "boolean" == typeof t) return "" + t;
if ("object" == typeof t) {
if (t instanceof Array) return "an array";
{
const e =
/** try to get the constructor name for an object. */
function __PRIVATE_tryGetCustomObjectType(t) {
if (t.constructor) return t.constructor.name;
return null;
}
/**
* Casts `obj` to `T`, optionally unwrapping Compat types to expose the
* underlying instance. Throws if `obj` is not an instance of `T`.
*
* This cast is used in the Lite and Full SDK to verify instance types for
* arguments passed to the public API.
* @internal
*/ (t);
return e ? `a custom ${e} object` : "an object";
}
}
return "function" == typeof t ? "a function" : fail(12329, {
type: typeof t
});
}
function __PRIVATE_cast(t,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
e) {
if ("_delegate" in t && (
// Unwrap Compat types
// eslint-disable-next-line @typescript-eslint/no-explicit-any
t = t._delegate), !(t instanceof e)) {
if (e.name === t.constructor.name) throw new FirestoreError(w, "Type does not match the expected instance. Did you pass a reference from a different Firestore SDK?");
{
const r = __PRIVATE_valueDescription(t);
throw new FirestoreError(w, `Expected type '${e.name}', but it was: ${r}`);
}
}
return t;
}
function __PRIVATE_validatePositiveNumber(t, e) {
if (e <= 0) throw new FirestoreError(w, `Function ${t}() requires a positive number, but it was: ${e}.`);
}
/**
* @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.
*/
/**
* Compares two `ExperimentalLongPollingOptions` objects for equality.
*/
/**
* Creates and returns a new `ExperimentalLongPollingOptions` with the same
* option values as the given instance.
*/
function __PRIVATE_cloneLongPollingOptions(t) {
const e = {};
return void 0 !== t.timeoutSeconds && (e.timeoutSeconds = t.timeoutSeconds), e;
}
/**
* @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.
*/
/**
* The value returned from the most recent invocation of
* `generateUniqueDebugId()`, or null if it has never been invoked.
*/ let x = null;
/**
* Generates and returns an initial value for `lastUniqueDebugId`.
*
* The returned value is randomly selected from a range of integers that are
* represented as 8 hexadecimal digits. This means that (within reason) any
* numbers generated by incrementing the returned number by 1 will also be
* represented by 8 hexadecimal digits. This leads to all "IDs" having the same
* length when converted to a hexadecimal string, making reading logs containing
* these IDs easier to follow. And since the return value is randomly selected
* it will help to differentiate between logs from different executions.
*/
/**
* Generates and returns a unique ID as a hexadecimal string.
*
* The returned ID is intended to be used in debug logging messages to help
* correlate log messages that may be spatially separated in the logs, but
* logically related. For example, a network connection could include the same
* "debug ID" string in all of its log messages to help trace a specific
* connection over time.
*
* @return the 10-character generated ID (e.g. "0xa1b2c3d4").
*/
function __PRIVATE_generateUniqueDebugId() {
return null === x ? x = function __PRIVATE_generateInitialUniqueDebugId() {
return 268435456 + Math.round(2147483648 * Math.random());
}() : x++, "0x" + x.toString(16);
}
/**
* @license
* Copyright 2017 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.
*/
/**
* Returns whether a variable is either undefined or null.
*/ function __PRIVATE_isNullOrUndefined(t) {
return null == t;
}
/** Returns whether the value represents -0. */ function __PRIVATE_isNegativeZero(t) {
// Detect if the value is -0.0. Based on polyfill from
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
return 0 === t && 1 / t == -1 / 0;
}
/**
* Returns whether a value is an integer and in the safe integer range
* @param value - The value to test for being an integer and in the safe range
*/
/**
* @license
* Copyright 2020 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.
*/
const j = "RestConnection", z = {
BatchGetDocuments: "batchGet",
Commit: "commit",
RunQuery: "runQuery",
RunAggregationQuery: "runAggregationQuery"
};
/**
* Maps RPC names to the corresponding REST endpoint name.
*
* We use array notation to avoid mangling.
*/
/**
* Base class for all Rest-based connections to the backend (WebChannel and
* HTTP).
*/
class __PRIVATE_RestConnection {
get A() {
// Both `invokeRPC()` and `invokeStreamingRPC()` use their `path` arguments to determine
// where to run the query, and expect the `request` to NOT specify the "path".
return !1;
}
constructor(t) {
this.databaseInfo = t, this.databaseId = t.databaseId;
const e = t.ssl ? "https" : "http", r = encodeURIComponent(this.databaseId.projectId), n = encodeURIComponent(this.databaseId.database);
this.P = e + "://" + t.host, this.R = `projects/${r}/databases/${n}`, this.I = this.databaseId.database === k ? `project_id=${r}` : `project_id=${r}&database_id=${n}`;
}
V(t, e, r, n, i) {
const s = __PRIVATE_generateUniqueDebugId(), o = this.p(t, e.toUriEncodedString());
__PRIVATE_logDebug(j, `Sending RPC '${t}' ${s}:`, o, r);
const a = {
"google-cloud-resource-prefix": this.R,
"x-goog-request-params": this.I
};
this.F(a, n, i);
const {host: u} = new URL(o), _ = c(u);
return this.v(t, o, a, r, _).then((e => (__PRIVATE_logDebug(j, `Received RPC '${t}' ${s}: `, e),
e)), (e => {
throw __PRIVATE_logWarn(j, `RPC '${t}' ${s} failed with error: `, e, "url: ", o, "request:", r),
e;
}));
}
D(t, e, r, n, i, s) {
// The REST API automatically aggregates all of the streamed results, so we
// can just use the normal invoke() method.
return this.V(t, e, r, n, i);
}
/**
* Modifies the headers for a request, adding any authorization token if
* present and any additional headers for the request.
*/ F(t, e, r) {
t["X-Goog-Api-Client"] =
// SDK_VERSION is updated to different value at runtime depending on the entry point,
// so we need to get its value when we need it in a function.
function __PRIVATE_getGoogApiClientValue() {
return "gl-js/ fire/" + I;
}(),
// Content-Type: text/plain will avoid preflight requests which might
// mess with CORS and redirects by proxies. If we add custom headers
// we will need to change this code to potentially use the $httpOverwrite
// parameter supported by ESF to avoid triggering preflight requests.
t["Content-Type"] = "text/plain", this.databaseInfo.appId && (t["X-Firebase-GMPID"] = this.databaseInfo.appId),
e && e.headers.forEach(((e, r) => t[r] = e)), r && r.headers.forEach(((e, r) => t[r] = e));
}
p(t, e) {
const r = z[t];
return `${this.P}/v1/${e}:${r}`;
}
/**
* Closes and cleans up any resources associated with the connection. This
* implementation is a no-op because there are no resources associated
* with the RestConnection that need to be cleaned up.
*/ terminate() {
// No-op
}
}
/**
* @license
* Copyright 2017 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.
*/
/**
* Error Codes describing the different ways GRPC can fail. These are copied
* directly from GRPC's sources here:
*
* https://github.com/grpc/grpc/blob/bceec94ea4fc5f0085d81235d8e1c06798dc341a/include/grpc%2B%2B/impl/codegen/status_code_enum.h
*
* Important! The names of these identifiers matter because the string forms
* are used for reverse lookups from the webchannel stream. Do NOT change the
* names of these identifiers or change this into a const enum.
*/ var W, K;
/**
* Converts an HTTP Status Code to the equivalent error code.
*
* @param status - An HTTP Status Code, like 200, 404, 503, etc.
* @returns The equivalent Code. Unknown status codes are mapped to
* Code.UNKNOWN.
*/
function __PRIVATE_mapCodeFromHttpStatus(t) {
if (void 0 === t) return __PRIVATE_logError("RPC_ERROR", "HTTP error has no status"),
g;
// The canonical error codes for Google APIs [1] specify mapping onto HTTP
// status codes but the mapping is not bijective. In each case of ambiguity
// this function chooses a primary error.
// [1]
// https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
switch (t) {
case 200:
// OK
return p;
case 400:
// Bad Request
return N;
// Other possibilities based on the forward mapping
// return Code.INVALID_ARGUMENT;
// return Code.OUT_OF_RANGE;
case 401:
// Unauthorized
return C;
case 403:
// Forbidden
return b;
case 404:
// Not Found
return v;
case 409:
// Conflict
return O;
// Other possibilities:
// return Code.ALREADY_EXISTS;
case 416:
// Range Not Satisfiable
return q;
case 429:
// Too Many Requests
return S;
case 499:
// Client Closed Request
return y;
case 500:
// Internal Server Error
return g;
// Other possibilities:
// return Code.INTERNAL;
// return Code.DATA_LOSS;
case 501:
// Unimplemented
return B;
case 503:
// Service Unavailable
return Q;
case 504:
// Gateway Timeout
return F;
default:
return t >= 200 && t < 300 ? p : t >= 400 && t < 500 ? N : t >= 500 && t < 600 ? $ : g;
}
}
/**
* @license
* Copyright 2020 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.
*/
/**
* A Rest-based connection that relies on the native HTTP stack
* (e.g. `fetch` or a polyfill).
*/ (K = W || (W = {}))[K.OK = 0] = "OK", K[K.CANCELLED = 1] = "CANCELLED", K[K.UNKNOWN = 2] = "UNKNOWN",
K[K.INVALID_ARGUMENT = 3] = "INVALID_ARGUMENT", K[K.DEADLINE_EXCEEDED = 4] = "DEADLINE_EXCEEDED",
K[K.NOT_FOUND = 5] = "NOT_FOUND", K[K.ALREADY_EXISTS = 6] = "ALREADY_EXISTS", K[K.PERMISSION_DENIED = 7] = "PERMISSION_DENIED",
K[K.UNAUTHENTICATED = 16] = "UNAUTHENTICATED", K[K.RESOURCE_EXHAUSTED = 8] = "RESOURCE_EXHAUSTED",
K[K.FAILED_PRECONDITION = 9] = "FAILED_PRECONDITION", K[K.ABORTED = 10] = "ABORTED",
K[K.OUT_OF_RANGE = 11] = "OUT_OF_RANGE", K[K.UNIMPLEMENTED = 12] = "UNIMPLEMENTED",
K[K.INTERNAL = 13] = "INTERNAL", K[K.UNAVAILABLE = 14] = "UNAVAILABLE", K[K.DATA_LOSS = 15] = "DATA_LOSS";
class __PRIVATE_FetchConnection extends __PRIVATE_RestConnection {
C(t, e) {
throw new Error("Not supported by FetchConnection");
}
async v(t, e, r, n, i) {
var s;
const o = JSON.stringify(n);
let a;
try {
const t = {
method: "POST",
headers: r,
body: o
};
i && (t.credentials = "include"), a = await fetch(e, t);
} catch (t) {
const e = t;
throw new FirestoreError(__PRIVATE_mapCodeFromHttpStatus(e.status), "Request failed with error: " + e.statusText);
}
if (!a.ok) {
let t = await a.json();
Array.isArray(t) && (t = t[0]);
const e = null === (s = null == t ? void 0 : t.error) || void 0 === s ? void 0 : s.message;
throw new FirestoreError(__PRIVATE_mapCodeFromHttpStatus(a.status), `Request failed with error: ${null != e ? e : a.statusText}`);
}
return a.json();
}
}
/**
* @license
* Copyright 2020 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.
*/
/** Initializes the HTTP connection for the REST API. */
/**
* @license
* Copyright 2023 Google LLC
*
* Licensed und