diff options
| author | altaf-creator <dev@altafcreator.com> | 2025-11-16 19:08:29 +0800 |
|---|---|---|
| committer | altaf-creator <dev@altafcreator.com> | 2025-11-16 19:08:29 +0800 |
| commit | 434aa8343fdcbb4d5002f934979913c099489bee (patch) | |
| tree | 55bab4ec5a6151be57797d34f61faf5ea744471b /frontend-old/node_modules/@firebase/analytics/dist/index.cjs.js | |
| parent | 893c388d4e99442a36005e5971a87730623f946e (diff) | |
sdk, del
Diffstat (limited to 'frontend-old/node_modules/@firebase/analytics/dist/index.cjs.js')
| -rw-r--r-- | frontend-old/node_modules/@firebase/analytics/dist/index.cjs.js | 1287 |
1 files changed, 0 insertions, 1287 deletions
diff --git a/frontend-old/node_modules/@firebase/analytics/dist/index.cjs.js b/frontend-old/node_modules/@firebase/analytics/dist/index.cjs.js deleted file mode 100644 index 0d6cdfe..0000000 --- a/frontend-old/node_modules/@firebase/analytics/dist/index.cjs.js +++ /dev/null @@ -1,1287 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -var app = require('@firebase/app'); -var logger$1 = require('@firebase/logger'); -var util = require('@firebase/util'); -var component = require('@firebase/component'); -require('@firebase/installations'); - -/** - * @license - * Copyright 2019 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. - */ -/** - * Type constant for Firebase Analytics. - */ -const ANALYTICS_TYPE = 'analytics'; -// Key to attach FID to in gtag params. -const GA_FID_KEY = 'firebase_id'; -const ORIGIN_KEY = 'origin'; -const FETCH_TIMEOUT_MILLIS = 60 * 1000; -const DYNAMIC_CONFIG_URL = 'https://firebase.googleapis.com/v1alpha/projects/-/apps/{app-id}/webConfig'; -const GTAG_URL = 'https://www.googletagmanager.com/gtag/js'; - -/** - * @license - * Copyright 2019 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 logger = new logger$1.Logger('@firebase/analytics'); - -/** - * @license - * Copyright 2019 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 ERRORS = { - ["already-exists" /* AnalyticsError.ALREADY_EXISTS */]: 'A Firebase Analytics instance with the appId {$id} ' + - ' already exists. ' + - 'Only one Firebase Analytics instance can be created for each appId.', - ["already-initialized" /* AnalyticsError.ALREADY_INITIALIZED */]: 'initializeAnalytics() cannot be called again with different options than those ' + - 'it was initially called with. It can be called again with the same options to ' + - 'return the existing instance, or getAnalytics() can be used ' + - 'to get a reference to the already-initialized instance.', - ["already-initialized-settings" /* AnalyticsError.ALREADY_INITIALIZED_SETTINGS */]: 'Firebase Analytics has already been initialized.' + - 'settings() must be called before initializing any Analytics instance' + - 'or it will have no effect.', - ["interop-component-reg-failed" /* AnalyticsError.INTEROP_COMPONENT_REG_FAILED */]: 'Firebase Analytics Interop Component failed to instantiate: {$reason}', - ["invalid-analytics-context" /* AnalyticsError.INVALID_ANALYTICS_CONTEXT */]: 'Firebase Analytics is not supported in this environment. ' + - 'Wrap initialization of analytics in analytics.isSupported() ' + - 'to prevent initialization in unsupported environments. Details: {$errorInfo}', - ["indexeddb-unavailable" /* AnalyticsError.INDEXEDDB_UNAVAILABLE */]: 'IndexedDB unavailable or restricted in this environment. ' + - 'Wrap initialization of analytics in analytics.isSupported() ' + - 'to prevent initialization in unsupported environments. Details: {$errorInfo}', - ["fetch-throttle" /* AnalyticsError.FETCH_THROTTLE */]: 'The config fetch request timed out while in an exponential backoff state.' + - ' Unix timestamp in milliseconds when fetch request throttling ends: {$throttleEndTimeMillis}.', - ["config-fetch-failed" /* AnalyticsError.CONFIG_FETCH_FAILED */]: 'Dynamic config fetch failed: [{$httpStatus}] {$responseMessage}', - ["no-api-key" /* AnalyticsError.NO_API_KEY */]: 'The "apiKey" field is empty in the local Firebase config. Firebase Analytics requires this field to' + - 'contain a valid API key.', - ["no-app-id" /* 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.', - ["no-client-id" /* AnalyticsError.NO_CLIENT_ID */]: 'The "client_id" field is empty.', - ["invalid-gtag-resource" /* AnalyticsError.INVALID_GTAG_RESOURCE */]: 'Trusted Types detected an invalid gtag resource: {$gtagURL}.' -}; -const ERROR_FACTORY = new util.ErrorFactory('analytics', 'Analytics', ERRORS); - -/** - * @license - * Copyright 2019 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. - */ -/** - * Verifies and creates a TrustedScriptURL. - */ -function createGtagTrustedTypesScriptURL(url) { - if (!url.startsWith(GTAG_URL)) { - const err = ERROR_FACTORY.create("invalid-gtag-resource" /* 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. - * - * @param promises Array of promises to wait for. - */ -function promiseAllSettled(promises) { - 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}. - */ -function createTrustedTypesPolicy(policyName, policyOptions) { - // Create a TrustedTypes policy that we can use for updating src - // properties - let trustedTypesPolicy; - 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"). - */ -function insertScriptTag(dataLayerName, measurementId) { - 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 = trustedTypesPolicy - ? trustedTypesPolicy?.createScriptURL(gtagScriptURL) - : gtagScriptURL; - script.async = true; - document.head.appendChild(script); -} -/** - * Get reference to, or create, global datalayer. - * @param dataLayerName Name of datalayer (most often the default, "_dataLayer"). - */ -function getOrCreateDataLayer(dataLayerName) { - // Check for existing dataLayer and create if needed. - let dataLayer = []; - if (Array.isArray(window[dataLayerName])) { - dataLayer = window[dataLayerName]; - } - else { - window[dataLayerName] = dataLayer; - } - return dataLayer; -} -/** - * Wrapped gtag logic when gtag is called with 'config' command. - * - * @param gtagCore Basic gtag function that just appends to dataLayer. - * @param initializationPromisesMap Map of appIds to their initialization promises. - * @param dynamicConfigPromisesList Array of dynamic config fetch promises. - * @param measurementIdToAppId Map of GA measurementIDs to corresponding Firebase appId. - * @param measurementId GA Measurement ID to set config for. - * @param gtagParams Gtag config params to set. - */ -async function gtagOnConfig(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, measurementId, gtagParams) { - // If config is already fetched, we know the appId and can use it to look up what FID promise we - /// are waiting for, and wait only on that one. - const correspondingAppId = measurementIdToAppId[measurementId]; - try { - if (correspondingAppId) { - await initializationPromisesMap[correspondingAppId]; - } - else { - // If config is not fetched yet, wait for all configs (we don't know which one we need) and - // find the appId (if any) corresponding to this measurementId. If there is one, wait on - // that appId's initialization promise. If there is none, promise resolves and gtag - // call goes through. - const dynamicConfigResults = await promiseAllSettled(dynamicConfigPromisesList); - const foundConfig = dynamicConfigResults.find(config => config.measurementId === measurementId); - if (foundConfig) { - await initializationPromisesMap[foundConfig.appId]; - } - } - } - catch (e) { - logger.error(e); - } - gtagCore("config" /* GtagCommand.CONFIG */, measurementId, gtagParams); -} -/** - * Wrapped gtag logic when gtag is called with 'event' command. - * - * @param gtagCore Basic gtag function that just appends to dataLayer. - * @param initializationPromisesMap Map of appIds to their initialization promises. - * @param dynamicConfigPromisesList Array of dynamic config fetch promises. - * @param measurementId GA Measurement ID to log event to. - * @param gtagParams Params to log with this event. - */ -async function gtagOnEvent(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementId, gtagParams) { - try { - let initializationPromisesToWaitFor = []; - // If there's a 'send_to' param, check if any ID specified matches - // an initializeIds() promise we are waiting for. - if (gtagParams && gtagParams['send_to']) { - let gaSendToList = gtagParams['send_to']; - // Make it an array if is isn't, so it can be dealt with the same way. - if (!Array.isArray(gaSendToList)) { - gaSendToList = [gaSendToList]; - } - // Checking 'send_to' fields requires having all measurement ID results back from - // the dynamic config fetch. - const dynamicConfigResults = await promiseAllSettled(dynamicConfigPromisesList); - for (const sendToId of gaSendToList) { - // Any fetched dynamic measurement ID that matches this 'send_to' ID - const foundConfig = dynamicConfigResults.find(config => config.measurementId === sendToId); - const initializationPromise = foundConfig && initializationPromisesMap[foundConfig.appId]; - if (initializationPromise) { - initializationPromisesToWaitFor.push(initializationPromise); - } - else { - // Found an item in 'send_to' that is not associated - // directly with an FID, possibly a group. Empty this array, - // exit the loop early, and let it get populated below. - initializationPromisesToWaitFor = []; - break; - } - } - } - // This will be unpopulated if there was no 'send_to' field , or - // if not all entries in the 'send_to' field could be mapped to - // a FID. In these cases, wait on all pending initialization promises. - if (initializationPromisesToWaitFor.length === 0) { - /* eslint-disable-next-line @typescript-eslint/no-floating-promises */ - initializationPromisesToWaitFor = Object.values(initializationPromisesMap); - } - // Run core gtag function with args after all relevant initialization - // promises have been resolved. - await Promise.all(initializationPromisesToWaitFor); - // Workaround for http://b/141370449 - third argument cannot be undefined. - gtagCore("event" /* GtagCommand.EVENT */, measurementId, gtagParams || {}); - } - catch (e) { - logger.error(e); - } -} -/** - * Wraps a standard gtag function with extra code to wait for completion of - * relevant initialization promises before sending requests. - * - * @param gtagCore Basic gtag function that just appends to dataLayer. - * @param initializationPromisesMap Map of appIds to their initialization promises. - * @param dynamicConfigPromisesList Array of dynamic config fetch promises. - * @param measurementIdToAppId Map of GA measurementIDs to corresponding Firebase appId. - */ -function wrapGtag(gtagCore, -/** - * Allows wrapped gtag calls to wait on whichever initialization promises are required, - * depending on the contents of the gtag params' `send_to` field, if any. - */ -initializationPromisesMap, -/** - * Wrapped gtag calls sometimes require all dynamic config fetches to have returned - * before determining what initialization promises (which include FIDs) to wait for. - */ -dynamicConfigPromisesList, -/** - * Wrapped gtag config calls can narrow down which initialization promise (with FID) - * to wait for if the measurementId is already fetched, by getting the corresponding appId, - * which is the key for the initialization promises map. - */ -measurementIdToAppId) { - /** - * Wrapper around gtag that ensures FID is sent with gtag calls. - * @param command Gtag command type. - * @param idOrNameOrParams Measurement ID if command is EVENT/CONFIG, params if command is SET. - * @param gtagParams Params if event is EVENT/CONFIG. - */ - async function gtagWrapper(command, ...args) { - try { - // If event, check that relevant initialization promises have completed. - if (command === "event" /* GtagCommand.EVENT */) { - const [measurementId, gtagParams] = args; - // If EVENT, second arg must be measurementId. - await gtagOnEvent(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementId, gtagParams); - } - else if (command === "config" /* GtagCommand.CONFIG */) { - const [measurementId, gtagParams] = args; - // If CONFIG, second arg must be measurementId. - await gtagOnConfig(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, measurementId, gtagParams); - } - else if (command === "consent" /* GtagCommand.CONSENT */) { - const [consentAction, gtagParams] = args; - // consentAction can be one of 'default' or 'update'. - gtagCore("consent" /* GtagCommand.CONSENT */, consentAction, gtagParams); - } - else if (command === "get" /* GtagCommand.GET */) { - const [measurementId, fieldName, callback] = args; - gtagCore("get" /* GtagCommand.GET */, measurementId, fieldName, callback); - } - else if (command === "set" /* GtagCommand.SET */) { - const [customParams] = args; - // If SET, second arg must be params. - gtagCore("set" /* GtagCommand.SET */, customParams); - } - else { - gtagCore(command, ...args); - } - } - catch (e) { - logger.error(e); - } - } - return gtagWrapper; -} -/** - * Creates global gtag function or wraps existing one if found. - * This wrapped function attaches Firebase instance ID (FID) to gtag 'config' and - * 'event' calls that belong to the GAID associated with this Firebase instance. - * - * @param initializationPromisesMap Map of appIds to their initialization promises. - * @param dynamicConfigPromisesList Array of dynamic config fetch promises. - * @param measurementIdToAppId Map of GA measurementIDs to corresponding Firebase appId. - * @param dataLayerName Name of global GA datalayer array. - * @param gtagFunctionName Name of global gtag function ("gtag" if not user-specified). - */ -function wrapOrCreateGtag(initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, dataLayerName, gtagFunctionName) { - // Create a basic core gtag function - let gtagCore = function (..._args) { - // Must push IArguments object, not an array. - window[dataLayerName].push(arguments); - }; - // Replace it with existing one if found - if (window[gtagFunctionName] && - typeof window[gtagFunctionName] === 'function') { - // @ts-ignore - gtagCore = window[gtagFunctionName]; - } - window[gtagFunctionName] = wrapGtag(gtagCore, initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId); - return { - gtagCore, - wrappedGtag: window[gtagFunctionName] - }; -} -/** - * Returns the script tag in the DOM matching both the gtag url pattern - * and the provided data layer name. - */ -function findGtagScriptOnPage(dataLayerName) { - const scriptTags = window.document.getElementsByTagName('script'); - for (const tag of Object.values(scriptTags)) { - if (tag.src && - tag.src.includes(GTAG_URL) && - tag.src.includes(dataLayerName)) { - return tag; - } - } - return null; -} - -/** - * @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. - */ -/** - * Backoff factor for 503 errors, which we want to be conservative about - * to avoid overloading servers. Each retry interval will be - * BASE_INTERVAL_MILLIS * LONG_RETRY_FACTOR ^ retryCount, so the second one - * will be ~30 seconds (with fuzzing). - */ -const LONG_RETRY_FACTOR = 30; -/** - * Base wait interval to multiplied by backoffFactor^backoffCount. - */ -const BASE_INTERVAL_MILLIS = 1000; -/** - * Stubbable retry data storage class. - */ -class RetryData { - constructor(throttleMetadata = {}, intervalMillis = BASE_INTERVAL_MILLIS) { - this.throttleMetadata = throttleMetadata; - this.intervalMillis = intervalMillis; - } - getThrottleMetadata(appId) { - return this.throttleMetadata[appId]; - } - setThrottleMetadata(appId, metadata) { - this.throttleMetadata[appId] = metadata; - } - deleteThrottleMetadata(appId) { - delete this.throttleMetadata[appId]; - } -} -const defaultRetryData = new RetryData(); -/** - * Set GET request headers. - * @param apiKey App API key. - */ -function getHeaders(apiKey) { - return new Headers({ - Accept: 'application/json', - 'x-goog-api-key': apiKey - }); -} -/** - * Fetches dynamic config from backend. - * @param app Firebase app to fetch config for. - */ -async function fetchDynamicConfig(appFields) { - const { appId, apiKey } = appFields; - const request = { - method: 'GET', - headers: getHeaders(apiKey) - }; - const appUrl = DYNAMIC_CONFIG_URL.replace('{app-id}', appId); - const response = await fetch(appUrl, request); - if (response.status !== 200 && response.status !== 304) { - let errorMessage = ''; - try { - // Try to get any error message text from server response. - const jsonResponse = (await response.json()); - if (jsonResponse.error?.message) { - errorMessage = jsonResponse.error.message; - } - } - catch (_ignored) { } - throw ERROR_FACTORY.create("config-fetch-failed" /* AnalyticsError.CONFIG_FETCH_FAILED */, { - httpStatus: response.status, - responseMessage: errorMessage - }); - } - return response.json(); -} -/** - * Fetches dynamic config from backend, retrying if failed. - * @param app Firebase app to fetch config for. - */ -async function fetchDynamicConfigWithRetry(app, -// retryData and timeoutMillis are parameterized to allow passing a different value for testing. -retryData = defaultRetryData, timeoutMillis) { - const { appId, apiKey, measurementId } = app.options; - if (!appId) { - throw ERROR_FACTORY.create("no-app-id" /* AnalyticsError.NO_APP_ID */); - } - if (!apiKey) { - if (measurementId) { - return { - measurementId, - appId - }; - } - throw ERROR_FACTORY.create("no-api-key" /* AnalyticsError.NO_API_KEY */); - } - const throttleMetadata = retryData.getThrottleMetadata(appId) || { - backoffCount: 0, - throttleEndTimeMillis: Date.now() - }; - const signal = new AnalyticsAbortSignal(); - setTimeout(async () => { - // Note a very low delay, eg < 10ms, can elapse before listeners are initialized. - signal.abort(); - }, timeoutMillis !== undefined ? timeoutMillis : FETCH_TIMEOUT_MILLIS); - return attemptFetchDynamicConfigWithRetry({ appId, apiKey, measurementId }, throttleMetadata, signal, retryData); -} -/** - * Runs one retry attempt. - * @param appFields Necessary app config fields. - * @param throttleMetadata Ongoing metadata to determine throttling times. - * @param signal Abort signal. - */ -async function attemptFetchDynamicConfigWithRetry(appFields, { throttleEndTimeMillis, backoffCount }, signal, retryData = defaultRetryData // for testing -) { - const { appId, measurementId } = appFields; - // Starts with a (potentially zero) timeout to support resumption from stored state. - // Ensures the throttle end time is honored if the last attempt timed out. - // Note the SDK will never make a request if the fetch timeout expires at this point. - try { - await setAbortableTimeout(signal, throttleEndTimeMillis); - } - catch (e) { - if (measurementId) { - logger.warn(`Timed out fetching this Firebase app's measurement ID from the server.` + - ` Falling back to the measurement ID ${measurementId}` + - ` provided in the "measurementId" field in the local Firebase config. [${e?.message}]`); - return { appId, measurementId }; - } - throw e; - } - try { - const response = await fetchDynamicConfig(appFields); - // Note the SDK only clears throttle state if response is success or non-retriable. - retryData.deleteThrottleMetadata(appId); - return response; - } - catch (e) { - const error = e; - if (!isRetriableError(error)) { - retryData.deleteThrottleMetadata(appId); - if (measurementId) { - logger.warn(`Failed to fetch this Firebase app's measurement ID from the server.` + - ` Falling back to the measurement ID ${measurementId}` + - ` provided in the "measurementId" field in the local Firebase config. [${error?.message}]`); - return { appId, measurementId }; - } - else { - throw e; - } - } - const backoffMillis = Number(error?.customData?.httpStatus) === 503 - ? util.calculateBackoffMillis(backoffCount, retryData.intervalMillis, LONG_RETRY_FACTOR) - : util.calculateBackoffMillis(backoffCount, retryData.intervalMillis); - // Increments backoff state. - const throttleMetadata = { - throttleEndTimeMillis: Date.now() + backoffMillis, - backoffCount: backoffCount + 1 - }; - // Persists state. - retryData.setThrottleMetadata(appId, throttleMetadata); - logger.debug(`Calling attemptFetch again in ${backoffMillis} millis`); - return attemptFetchDynamicConfigWithRetry(appFields, throttleMetadata, signal, retryData); - } -} -/** - * Supports waiting on a backoff by: - * - * <ul> - * <li>Promisifying setTimeout, so we can set a timeout in our Promise chain</li> - * <li>Listening on a signal bus for abort events, just like the Fetch API</li> - * <li>Failing in the same way the Fetch API fails, so timing out a live request and a throttled - * request appear the same.</li> - * </ul> - * - * <p>Visible for testing. - */ -function setAbortableTimeout(signal, throttleEndTimeMillis) { - return new Promise((resolve, reject) => { - // Derives backoff from given end time, normalizing negative numbers to zero. - const backoffMillis = Math.max(throttleEndTimeMillis - Date.now(), 0); - const timeout = setTimeout(resolve, backoffMillis); - // Adds listener, rather than sets onabort, because signal is a shared object. - signal.addEventListener(() => { - clearTimeout(timeout); - // If the request completes before this timeout, the rejection has no effect. - reject(ERROR_FACTORY.create("fetch-throttle" /* AnalyticsError.FETCH_THROTTLE */, { - throttleEndTimeMillis - })); - }); - }); -} -/** - * Returns true if the {@link Error} indicates a fetch request may succeed later. - */ -function isRetriableError(e) { - if (!(e instanceof util.FirebaseError) || !e.customData) { - return false; - } - // Uses string index defined by ErrorData, which FirebaseError implements. - const httpStatus = Number(e.customData['httpStatus']); - return (httpStatus === 429 || - httpStatus === 500 || - httpStatus === 503 || - httpStatus === 504); -} -/** - * Shims a minimal AbortSignal (copied from Remote Config). - * - * <p>AbortController's AbortSignal conveniently decouples fetch timeout logic from other aspects - * of networking, such as retries. Firebase doesn't use AbortController enough to justify a - * polyfill recommendation, like we do with the Fetch API, but this minimal shim can easily be - * swapped out if/when we do. - */ -class AnalyticsAbortSignal { - constructor() { - this.listeners = []; - } - addEventListener(listener) { - this.listeners.push(listener); - } - abort() { - this.listeners.forEach(listener => listener()); - } -} - -/** - * @license - * Copyright 2019 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. - */ -/** - * Event parameters to set on 'gtag' during initialization. - */ -let defaultEventParametersForInit; -/** - * Logs an analytics event through the Firebase SDK. - * - * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event - * @param eventName Google Analytics event name, choose from standard list or use a custom string. - * @param eventParams Analytics event parameters. - */ -async function logEvent$1(gtagFunction, initializationPromise, eventName, eventParams, options) { - if (options && options.global) { - gtagFunction("event" /* GtagCommand.EVENT */, eventName, eventParams); - return; - } - else { - const measurementId = await initializationPromise; - const params = { - ...eventParams, - 'send_to': measurementId - }; - gtagFunction("event" /* GtagCommand.EVENT */, eventName, params); - } -} -/** - * Set screen_name parameter for this Google Analytics ID. - * - * @deprecated Use {@link logEvent} with `eventName` as 'screen_view' and add relevant `eventParams`. - * See {@link https://firebase.google.com/docs/analytics/screenviews | Track Screenviews}. - * - * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event - * @param screenName Screen name string to set. - */ -async function setCurrentScreen$1(gtagFunction, initializationPromise, screenName, options) { - if (options && options.global) { - gtagFunction("set" /* GtagCommand.SET */, { 'screen_name': screenName }); - return Promise.resolve(); - } - else { - const measurementId = await initializationPromise; - gtagFunction("config" /* GtagCommand.CONFIG */, measurementId, { - update: true, - 'screen_name': screenName - }); - } -} -/** - * Set user_id parameter for this Google Analytics ID. - * - * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event - * @param id User ID string to set - */ -async function setUserId$1(gtagFunction, initializationPromise, id, options) { - if (options && options.global) { - gtagFunction("set" /* GtagCommand.SET */, { 'user_id': id }); - return Promise.resolve(); - } - else { - const measurementId = await initializationPromise; - gtagFunction("config" /* GtagCommand.CONFIG */, measurementId, { - update: true, - 'user_id': id - }); - } -} -/** - * Set all other user properties other than user_id and screen_name. - * - * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event - * @param properties Map of user properties to set - */ -async function setUserProperties$1(gtagFunction, initializationPromise, properties, options) { - if (options && options.global) { - const flatProperties = {}; - for (const key of Object.keys(properties)) { - // use dot notation for merge behavior in gtag.js - flatProperties[`user_properties.${key}`] = properties[key]; - } - gtagFunction("set" /* GtagCommand.SET */, flatProperties); - return Promise.resolve(); - } - else { - const measurementId = await initializationPromise; - gtagFunction("config" /* GtagCommand.CONFIG */, measurementId, { - update: true, - 'user_properties': properties - }); - } -} -/** - * Retrieves a unique Google Analytics identifier for the web client. - * See {@link https://developers.google.com/analytics/devguides/collection/ga4/reference/config#client_id | client_id}. - * - * @param gtagFunction Wrapped gtag function that waits for fid to be set before sending an event - */ -async function internalGetGoogleAnalyticsClientId(gtagFunction, initializationPromise) { - const measurementId = await initializationPromise; - return new Promise((resolve, reject) => { - gtagFunction("get" /* GtagCommand.GET */, measurementId, 'client_id', (clientId) => { - if (!clientId) { - reject(ERROR_FACTORY.create("no-client-id" /* AnalyticsError.NO_CLIENT_ID */)); - } - resolve(clientId); - }); - }); -} -/** - * Set whether collection is enabled for this ID. - * - * @param enabled If true, collection is enabled for this ID. - */ -async function setAnalyticsCollectionEnabled$1(initializationPromise, enabled) { - const measurementId = await initializationPromise; - window[`ga-disable-${measurementId}`] = !enabled; -} -/** - * Consent parameters to default to during 'gtag' initialization. - */ -let defaultConsentSettingsForInit; -/** - * Sets the variable {@link defaultConsentSettingsForInit} for use in the initialization of - * analytics. - * - * @param consentSettings Maps the applicable end user consent state for gtag.js. - */ -function _setConsentDefaultForInit(consentSettings) { - defaultConsentSettingsForInit = consentSettings; -} -/** - * Sets the variable `defaultEventParametersForInit` for use in the initialization of - * analytics. - * - * @param customParams Any custom params the user may pass to gtag.js. - */ -function _setDefaultEventParametersForInit(customParams) { - defaultEventParametersForInit = customParams; -} - -/** - * @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. - */ -async function validateIndexedDB() { - if (!util.isIndexedDBAvailable()) { - logger.warn(ERROR_FACTORY.create("indexeddb-unavailable" /* AnalyticsError.INDEXEDDB_UNAVAILABLE */, { - errorInfo: 'IndexedDB is not available in this environment.' - }).message); - return false; - } - else { - try { - await util.validateIndexedDBOpenable(); - } - catch (e) { - logger.warn(ERROR_FACTORY.create("indexeddb-unavailable" /* AnalyticsError.INDEXEDDB_UNAVAILABLE */, { - errorInfo: e?.toString() - }).message); - return false; - } - } - return true; -} -/** - * Initialize the analytics instance in gtag.js by calling config command with fid. - * - * NOTE: We combine analytics initialization and setting fid together because we want fid to be - * part of the `page_view` event that's sent during the initialization - * @param app Firebase app - * @param gtagCore The gtag function that's not wrapped. - * @param dynamicConfigPromisesList Array of all dynamic config promises. - * @param measurementIdToAppId Maps measurementID to appID. - * @param installations _FirebaseInstallationsInternal instance. - * - * @returns Measurement ID. - */ -async function _initializeAnalytics(app, dynamicConfigPromisesList, measurementIdToAppId, installations, gtagCore, dataLayerName, options) { - const dynamicConfigPromise = fetchDynamicConfigWithRetry(app); - // Once fetched, map measurementIds to appId, for ease of lookup in wrapped gtag function. - dynamicConfigPromise - .then(config => { - measurementIdToAppId[config.measurementId] = config.appId; - if (app.options.measurementId && - config.measurementId !== app.options.measurementId) { - logger.warn(`The measurement ID in the local Firebase config (${app.options.measurementId})` + - ` does not match the measurement ID fetched from the server (${config.measurementId}).` + - ` To ensure analytics events are always sent to the correct Analytics property,` + - ` update the` + - ` measurement ID field in the local config or remove it from the local config.`); - } - }) - .catch(e => logger.error(e)); - // Add to list to track state of all dynamic config promises. - dynamicConfigPromisesList.push(dynamicConfigPromise); - const fidPromise = validateIndexedDB().then(envIsValid => { - if (envIsValid) { - return installations.getId(); - } - else { - return undefined; - } - }); - const [dynamicConfig, fid] = await Promise.all([ - dynamicConfigPromise, - fidPromise - ]); - // Detect if user has already put the gtag <script> tag on this page with the passed in - // data layer name. - if (!findGtagScriptOnPage(dataLayerName)) { - insertScriptTag(dataLayerName, dynamicConfig.measurementId); - } - // Detects if there are consent settings that need to be configured. - if (defaultConsentSettingsForInit) { - gtagCore("consent" /* GtagCommand.CONSENT */, 'default', defaultConsentSettingsForInit); - _setConsentDefaultForInit(undefined); - } - // This command initializes gtag.js and only needs to be called once for the entire web app, - // but since it is idempotent, we can call it multiple times. - // We keep it together with other initialization logic for better code structure. - // eslint-disable-next-line @typescript-eslint/no-explicit-any - gtagCore('js', new Date()); - // User config added first. We don't want users to accidentally overwrite - // base Firebase config properties. - const configProperties = options?.config ?? {}; - // guard against developers accidentally setting properties with prefix `firebase_` - configProperties[ORIGIN_KEY] = 'firebase'; - configProperties.update = true; - if (fid != null) { - configProperties[GA_FID_KEY] = fid; - } - // It should be the first config command called on this GA-ID - // Initialize this GA-ID and set FID on it using the gtag config API. - // Note: This will trigger a page_view event unless 'send_page_view' is set to false in - // `configProperties`. - gtagCore("config" /* GtagCommand.CONFIG */, dynamicConfig.measurementId, configProperties); - // Detects if there is data that will be set on every event logged from the SDK. - if (defaultEventParametersForInit) { - gtagCore("set" /* GtagCommand.SET */, defaultEventParametersForInit); - _setDefaultEventParametersForInit(undefined); - } - return dynamicConfig.measurementId; -} - -/** - * @license - * Copyright 2019 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. - */ -/** - * Analytics Service class. - */ -class AnalyticsService { - constructor(app) { - this.app = app; - } - _delete() { - delete initializationPromisesMap[this.app.options.appId]; - return Promise.resolve(); - } -} -/** - * Maps appId to full initialization promise. Wrapped gtag calls must wait on - * all or some of these, depending on the call's `send_to` param and the status - * of the dynamic config fetches (see below). - */ -let initializationPromisesMap = {}; -/** - * List of dynamic config fetch promises. In certain cases, wrapped gtag calls - * wait on all these to be complete in order to determine if it can selectively - * wait for only certain initialization (FID) promises or if it must wait for all. - */ -let dynamicConfigPromisesList = []; -/** - * Maps fetched measurementIds to appId. Populated when the app's dynamic config - * fetch completes. If already populated, gtag config calls can use this to - * selectively wait for only this app's initialization promise (FID) instead of all - * initialization promises. - */ -const measurementIdToAppId = {}; -/** - * Name for window global data layer array used by GA: defaults to 'dataLayer'. - */ -let dataLayerName = 'dataLayer'; -/** - * Name for window global gtag function used by GA: defaults to 'gtag'. - */ -let gtagName = 'gtag'; -/** - * Reproduction of standard gtag function or reference to existing - * gtag function on window object. - */ -let gtagCoreFunction; -/** - * Wrapper around gtag function that ensures FID is sent with all - * relevant event and config calls. - */ -let wrappedGtagFunction; -/** - * Flag to ensure page initialization steps (creation or wrapping of - * dataLayer and gtag script) are only run once per page load. - */ -let globalInitDone = false; -/** - * Configures Firebase Analytics to use custom `gtag` or `dataLayer` names. - * Intended to be used if `gtag.js` script has been installed on - * this page independently of Firebase Analytics, and is using non-default - * names for either the `gtag` function or for `dataLayer`. - * Must be called before calling `getAnalytics()` or it won't - * have any effect. - * - * @public - * - * @param options - Custom gtag and dataLayer names. - */ -function settings(options) { - if (globalInitDone) { - throw ERROR_FACTORY.create("already-initialized" /* AnalyticsError.ALREADY_INITIALIZED */); - } - if (options.dataLayerName) { - dataLayerName = options.dataLayerName; - } - if (options.gtagName) { - gtagName = options.gtagName; - } -} -/** - * Returns true if no environment mismatch is found. - * If environment mismatches are found, throws an INVALID_ANALYTICS_CONTEXT - * error that also lists details for each mismatch found. - */ -function warnOnBrowserContextMismatch() { - const mismatchedEnvMessages = []; - if (util.isBrowserExtension()) { - mismatchedEnvMessages.push('This is a browser extension environment.'); - } - if (!util.areCookiesEnabled()) { - mismatchedEnvMessages.push('Cookies are not available.'); - } - if (mismatchedEnvMessages.length > 0) { - const details = mismatchedEnvMessages - .map((message, index) => `(${index + 1}) ${message}`) - .join(' '); - const err = ERROR_FACTORY.create("invalid-analytics-context" /* AnalyticsError.INVALID_ANALYTICS_CONTEXT */, { - errorInfo: details - }); - logger.warn(err.message); - } -} -/** - * Analytics instance factory. - * @internal - */ -function factory(app, installations, options) { - warnOnBrowserContextMismatch(); - const appId = app.options.appId; - if (!appId) { - throw ERROR_FACTORY.create("no-app-id" /* AnalyticsError.NO_APP_ID */); - } - if (!app.options.apiKey) { - if (app.options.measurementId) { - logger.warn(`The "apiKey" field is empty in the local Firebase config. This is needed to fetch the latest` + - ` measurement ID for this Firebase app. Falling back to the measurement ID ${app.options.measurementId}` + - ` provided in the "measurementId" field in the local Firebase config.`); - } - else { - throw ERROR_FACTORY.create("no-api-key" /* AnalyticsError.NO_API_KEY */); - } - } - if (initializationPromisesMap[appId] != null) { - throw ERROR_FACTORY.create("already-exists" /* AnalyticsError.ALREADY_EXISTS */, { - id: appId - }); - } - if (!globalInitDone) { - // Steps here should only be done once per page: creation or wrapping - // of dataLayer and global gtag function. - getOrCreateDataLayer(dataLayerName); - const { wrappedGtag, gtagCore } = wrapOrCreateGtag(initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, dataLayerName, gtagName); - wrappedGtagFunction = wrappedGtag; - gtagCoreFunction = gtagCore; - globalInitDone = true; - } - // Async but non-blocking. - // This map reflects the completion state of all promises for each appId. - initializationPromisesMap[appId] = _initializeAnalytics(app, dynamicConfigPromisesList, measurementIdToAppId, installations, gtagCoreFunction, dataLayerName, options); - const analyticsInstance = new AnalyticsService(app); - return analyticsInstance; -} - -/* eslint-disable @typescript-eslint/no-explicit-any */ -/** - * Returns an {@link Analytics} instance for the given app. - * - * @public - * - * @param app - The {@link @firebase/app#FirebaseApp} to use. - */ -function getAnalytics(app$1 = app.getApp()) { - app$1 = util.getModularInstance(app$1); - // Dependencies - const analyticsProvider = app._getProvider(app$1, ANALYTICS_TYPE); - if (analyticsProvider.isInitialized()) { - return analyticsProvider.getImmediate(); - } - return initializeAnalytics(app$1); -} -/** - * Returns an {@link Analytics} instance for the given app. - * - * @public - * - * @param app - The {@link @firebase/app#FirebaseApp} to use. - */ -function initializeAnalytics(app$1, options = {}) { - // Dependencies - const analyticsProvider = app._getProvider(app$1, ANALYTICS_TYPE); - if (analyticsProvider.isInitialized()) { - const existingInstance = analyticsProvider.getImmediate(); - if (util.deepEqual(options, analyticsProvider.getOptions())) { - return existingInstance; - } - else { - throw ERROR_FACTORY.create("already-initialized" /* AnalyticsError.ALREADY_INITIALIZED */); - } - } - const analyticsInstance = analyticsProvider.initialize({ options }); - return analyticsInstance; -} -/** - * This is a public static method provided to users that wraps four different checks: - * - * 1. Check if it's not a browser extension environment. - * 2. Check if cookies are enabled in current browser. - * 3. Check if IndexedDB is supported by the browser environment. - * 4. Check if the current browser context is valid for using `IndexedDB.open()`. - * - * @public - * - */ -async function isSupported() { - if (util.isBrowserExtension()) { - return false; - } - if (!util.areCookiesEnabled()) { - return false; - } - if (!util.isIndexedDBAvailable()) { - return false; - } - try { - const isDBOpenable = await util.validateIndexedDBOpenable(); - return isDBOpenable; - } - catch (error) { - return false; - } -} -/** - * Use gtag `config` command to set `screen_name`. - * - * @public - * - * @deprecated Use {@link logEvent} with `eventName` as 'screen_view' and add relevant `eventParams`. - * See {@link https://firebase.google.com/docs/analytics/screenviews | Track Screenviews}. - * - * @param analyticsInstance - The {@link Analytics} instance. - * @param screenName - Screen name to set. - */ -function setCurrentScreen(analyticsInstance, screenName, options) { - analyticsInstance = util.getModularInstance(analyticsInstance); - setCurrentScreen$1(wrappedGtagFunction, initializationPromisesMap[analyticsInstance.app.options.appId], screenName, options).catch(e => logger.error(e)); -} -/** - * Retrieves a unique Google Analytics identifier for the web client. - * See {@link https://developers.google.com/analytics/devguides/collection/ga4/reference/config#client_id | client_id}. - * - * @public - * - * @param app - The {@link @firebase/app#FirebaseApp} to use. - */ -async function getGoogleAnalyticsClientId(analyticsInstance) { - analyticsInstance = util.getModularInstance(analyticsInstance); - return internalGetGoogleAnalyticsClientId(wrappedGtagFunction, initializationPromisesMap[analyticsInstance.app.options.appId]); -} -/** - * Use gtag `config` command to set `user_id`. - * - * @public - * - * @param analyticsInstance - The {@link Analytics} instance. - * @param id - User ID to set. - */ -function setUserId(analyticsInstance, id, options) { - analyticsInstance = util.getModularInstance(analyticsInstance); - setUserId$1(wrappedGtagFunction, initializationPromisesMap[analyticsInstance.app.options.appId], id, options).catch(e => logger.error(e)); -} -/** - * Use gtag `config` command to set all params specified. - * - * @public - */ -function setUserProperties(analyticsInstance, properties, options) { - analyticsInstance = util.getModularInstance(analyticsInstance); - setUserProperties$1(wrappedGtagFunction, initializationPromisesMap[analyticsInstance.app.options.appId], properties, options).catch(e => logger.error(e)); -} -/** - * Sets whether Google Analytics collection is enabled for this app on this device. - * Sets global `window['ga-disable-analyticsId'] = true;` - * - * @public - * - * @param analyticsInstance - The {@link Analytics} instance. - * @param enabled - If true, enables collection, if false, disables it. - */ -function setAnalyticsCollectionEnabled(analyticsInstance, enabled) { - analyticsInstance = util.getModularInstance(analyticsInstance); - setAnalyticsCollectionEnabled$1(initializationPromisesMap[analyticsInstance.app.options.appId], enabled).catch(e => logger.error(e)); -} -/** - * Adds data that will be set on every event logged from the SDK, including automatic ones. - * With gtag's "set" command, the values passed persist on the current page and are passed with - * all subsequent events. - * @public - * @param customParams - Any custom params the user may pass to gtag.js. - */ -function setDefaultEventParameters(customParams) { - // Check if reference to existing gtag function on window object exists - if (wrappedGtagFunction) { - wrappedGtagFunction("set" /* GtagCommand.SET */, customParams); - } - else { - _setDefaultEventParametersForInit(customParams); - } -} -/** - * Sends a Google Analytics event with given `eventParams`. This method - * automatically associates this logged event with this Firebase web - * app instance on this device. - * List of official event parameters can be found in the gtag.js - * reference documentation: - * {@link https://developers.google.com/gtagjs/reference/ga4-events - * | the GA4 reference documentation}. - * - * @public - */ -function logEvent(analyticsInstance, eventName, eventParams, options) { - analyticsInstance = util.getModularInstance(analyticsInstance); - logEvent$1(wrappedGtagFunction, initializationPromisesMap[analyticsInstance.app.options.appId], eventName, eventParams, options).catch(e => logger.error(e)); -} -/** - * Sets the applicable end user consent state for this web app across all gtag references once - * Firebase Analytics is initialized. - * - * Use the {@link ConsentSettings} to specify individual consent type values. By default consent - * types are set to "granted". - * @public - * @param consentSettings - Maps the applicable end user consent state for gtag.js. - */ -function setConsent(consentSettings) { - // Check if reference to existing gtag function on window object exists - if (wrappedGtagFunction) { - wrappedGtagFunction("consent" /* GtagCommand.CONSENT */, 'update', consentSettings); - } - else { - _setConsentDefaultForInit(consentSettings); - } -} - -const name = "@firebase/analytics"; -const version = "0.10.19"; - -/** - * The Firebase Analytics Web SDK. - * This SDK does not work in a Node.js environment. - * - * @packageDocumentation - */ -function registerAnalytics() { - app._registerComponent(new component.Component(ANALYTICS_TYPE, (container, { options: analyticsOptions }) => { - // getImmediate for FirebaseApp will always succeed - const app = container.getProvider('app').getImmediate(); - const installations = container - .getProvider('installations-internal') - .getImmediate(); - return factory(app, installations, analyticsOptions); - }, "PUBLIC" /* ComponentType.PUBLIC */)); - app._registerComponent(new component.Component('analytics-internal', internalFactory, "PRIVATE" /* ComponentType.PRIVATE */)); - app.registerVersion(name, version); - // BUILD_TARGET will be replaced by values like esm, cjs, etc during the compilation - app.registerVersion(name, version, 'cjs2020'); - function internalFactory(container) { - try { - const analytics = container.getProvider(ANALYTICS_TYPE).getImmediate(); - return { - logEvent: (eventName, eventParams, options) => logEvent(analytics, eventName, eventParams, options), - setUserProperties: (properties, options) => setUserProperties(analytics, properties, options) - }; - } - catch (e) { - throw ERROR_FACTORY.create("interop-component-reg-failed" /* AnalyticsError.INTEROP_COMPONENT_REG_FAILED */, { - reason: e - }); - } - } -} -registerAnalytics(); - -exports.getAnalytics = getAnalytics; -exports.getGoogleAnalyticsClientId = getGoogleAnalyticsClientId; -exports.initializeAnalytics = initializeAnalytics; -exports.isSupported = isSupported; -exports.logEvent = logEvent; -exports.setAnalyticsCollectionEnabled = setAnalyticsCollectionEnabled; -exports.setConsent = setConsent; -exports.setCurrentScreen = setCurrentScreen; -exports.setDefaultEventParameters = setDefaultEventParameters; -exports.setUserId = setUserId; -exports.setUserProperties = setUserProperties; -exports.settings = settings; -//# sourceMappingURL=index.cjs.js.map |
