@rudderstack/analytics-js 3.2.2 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/npm/index.d.ts +2 -1
- package/dist/npm/legacy/cjs/index.js +263 -301
- package/dist/npm/legacy/esm/index.js +263 -301
- package/dist/npm/legacy/umd/index.js +263 -301
- package/dist/npm/modern/bundled/cjs/index.js +100 -93
- package/dist/npm/modern/bundled/esm/index.js +100 -93
- package/dist/npm/modern/bundled/umd/index.js +100 -93
- package/dist/npm/modern/cjs/index.js +95 -87
- package/dist/npm/modern/content-script/cjs/index.js +94 -86
- package/dist/npm/modern/content-script/esm/index.js +94 -86
- package/dist/npm/modern/content-script/umd/index.js +94 -86
- package/dist/npm/modern/esm/index.js +95 -87
- package/dist/npm/modern/umd/index.js +95 -87
- package/package.json +2 -60
@@ -380,7 +380,7 @@
|
|
380
380
|
|
381
381
|
const CAPABILITIES_MANAGER='CapabilitiesManager';const CONFIG_MANAGER='ConfigManager';const EVENT_MANAGER='EventManager';const PLUGINS_MANAGER='PluginsManager';const USER_SESSION_MANAGER='UserSessionManager';const ERROR_HANDLER='ErrorHandler';const PLUGIN_ENGINE='PluginEngine';const STORE_MANAGER='StoreManager';const READY_API='readyApi';const EVENT_REPOSITORY='EventRepository';const EXTERNAL_SRC_LOADER='ExternalSrcLoader';const HTTP_CLIENT='HttpClient';const RS_APP='RudderStackApplication';const ANALYTICS_CORE='AnalyticsCore';
|
382
382
|
|
383
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.
|
383
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.3.0';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
|
384
384
|
|
385
385
|
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
|
386
386
|
|
@@ -463,7 +463,7 @@
|
|
463
463
|
* @param {*} extraAttributes key/value pair with html attributes to add in html tag [optional]
|
464
464
|
*
|
465
465
|
* @returns HTMLScriptElement
|
466
|
-
*/const createScriptElement=(url,id,async=true,onload=null,onerror=null,extraAttributes={})=>{const scriptElement=document.createElement('script');scriptElement.type='text/javascript';scriptElement.onload=onload;scriptElement.onerror=onerror;scriptElement.src=url;scriptElement.id=id;scriptElement.async=async;
|
466
|
+
*/const createScriptElement=(url,id,async=true,onload=null,onerror=null,extraAttributes={})=>{const scriptElement=document.createElement('script');scriptElement.type='text/javascript';scriptElement.onload=onload;scriptElement.onerror=onerror;scriptElement.src=url;scriptElement.id=id;scriptElement.async=async;Object.keys(extraAttributes).forEach(attributeName=>{scriptElement.setAttribute(attributeName,extraAttributes[attributeName]);});scriptElement.setAttribute('data-loader',EXTERNAL_SOURCE_LOAD_ORIGIN);return scriptElement;};/**
|
467
467
|
* Add script DOM element to DOM
|
468
468
|
*
|
469
469
|
* @param {*} newScriptElement the script element to add
|
@@ -519,11 +519,20 @@
|
|
519
519
|
// default is v3
|
520
520
|
const SUPPORTED_STORAGE_TYPES=['localStorage','memoryStorage','cookieStorage','sessionStorage','none'];const DEFAULT_STORAGE_TYPE='cookieStorage';
|
521
521
|
|
522
|
-
const SOURCE_CONFIG_OPTION_ERROR=`"getSourceConfig" must be a function. Please make sure that it is defined and returns a valid source configuration object.`;const INTG_CDN_BASE_URL_ERROR=`Failed to load the SDK as the CDN base URL for integrations is not valid.`;const PLUGINS_CDN_BASE_URL_ERROR=`Failed to load the SDK as the CDN base URL for plugins is not valid.`;const DATA_PLANE_URL_ERROR=`Failed to load the SDK as the data plane URL could not be determined. Please check that the data plane URL is set correctly and try again.`;const SOURCE_CONFIG_RESOLUTION_ERROR=`Unable to process/parse source configuration response.`;const XHR_PAYLOAD_PREP_ERROR=`Failed to prepare data for the request.`;const EVENT_OBJECT_GENERATION_ERROR=`Failed to generate the event object.`;const PLUGIN_EXT_POINT_MISSING_ERROR=`Failed to invoke plugin because the extension point name is missing.`;const PLUGIN_EXT_POINT_INVALID_ERROR=`Failed to invoke plugin because the extension point name is invalid.`;// ERROR
|
523
|
-
const UNSUPPORTED_CONSENT_MANAGER_ERROR=(context,selectedConsentManager,consentManagersToPluginNameMap)=>`${context}${LOG_CONTEXT_SEPARATOR}The consent manager "${selectedConsentManager}" is not supported. Please choose one of the following supported consent managers: "${Object.keys(consentManagersToPluginNameMap)}".`;const REPORTING_PLUGIN_INIT_FAILURE_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to initialize the error reporting plugin.`;const NOTIFY_FAILURE_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to notify the error.`;const PLUGIN_NAME_MISSING_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin name is missing.`;const PLUGIN_ALREADY_EXISTS_ERROR=(context,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" already exists.`;const PLUGIN_NOT_FOUND_ERROR=(context,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" not found.`;const PLUGIN_ENGINE_BUG_ERROR=(context,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" not found in plugins but found in byName. This indicates a bug in the plugin engine. Please report this issue to the development team.`;const PLUGIN_DEPS_ERROR=(context,pluginName,notExistDeps)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" could not be loaded because some of its dependencies "${notExistDeps}" do not exist.`;const PLUGIN_INVOCATION_ERROR=(context,extPoint,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to invoke the "${extPoint}" extension point of plugin "${pluginName}".`;const STORAGE_UNAVAILABILITY_ERROR_PREFIX=(context,storageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The "${storageType}" storage type is `;const SOURCE_CONFIG_FETCH_ERROR=reason=>`Failed to fetch the source config. Reason: ${reason}`;const WRITE_KEY_VALIDATION_ERROR=writeKey=>`The write key "${writeKey}" is invalid. It must be a non-empty string. Please check that the write key is correct and try again.`;const DATA_PLANE_URL_VALIDATION_ERROR=dataPlaneUrl=>`The data plane URL "${dataPlaneUrl}" is invalid. It must be a valid URL string. Please check that the data plane URL is correct and try again.`;const READY_API_CALLBACK_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}The callback is not a function.`;const XHR_DELIVERY_ERROR=(prefix,status,statusText,url)=>`${prefix} with status: ${status}, ${statusText} for URL: ${url}.`;const XHR_REQUEST_ERROR=(prefix,e,url)=>`${prefix} due to timeout or no connection (${e?e.type:''}) for URL: ${url}.`;const XHR_SEND_ERROR=(prefix,url)=>`${prefix} for URL: ${url}`;const STORE_DATA_SAVE_ERROR=key=>`Failed to save the value for "${key}" to storage`;const STORE_DATA_FETCH_ERROR=key=>`Failed to retrieve or parse data for "${key}" from storage`;const DATA_SERVER_REQUEST_FAIL_ERROR=status=>`The server responded with status ${status} while setting the cookies. As a fallback, the cookies will be set client side.`;const FAILED_SETTING_COOKIE_FROM_SERVER_ERROR=key=>`The server failed to set the ${key} cookie. As a fallback, the cookies will be set client side.`;const
|
524
|
-
const STORAGE_TYPE_VALIDATION_WARNING=(context,storageType,defaultStorageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage type "${storageType}" is not supported. Please choose one of the following supported types: "${SUPPORTED_STORAGE_TYPES}". The default type "${defaultStorageType}" will be used instead.`;const UNSUPPORTED_ERROR_REPORTING_PROVIDER_WARNING=(context,selectedErrorReportingProvider,errorReportingProvidersToPluginNameMap,defaultProvider)=>`${context}${LOG_CONTEXT_SEPARATOR}The error reporting provider "${selectedErrorReportingProvider}" is not supported. Please choose one of the following supported providers: "${Object.keys(errorReportingProvidersToPluginNameMap)}". The default provider "${defaultProvider}" will be used instead.`;const UNSUPPORTED_STORAGE_ENCRYPTION_VERSION_WARNING=(context,selectedStorageEncryptionVersion,storageEncryptionVersionsToPluginNameMap,defaultVersion)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage encryption version "${selectedStorageEncryptionVersion}" is not supported. Please choose one of the following supported versions: "${Object.keys(storageEncryptionVersionsToPluginNameMap)}". The default version "${defaultVersion}" will be used instead.`;const STORAGE_DATA_MIGRATION_OVERRIDE_WARNING=(context,storageEncryptionVersion,defaultVersion)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage data migration has been disabled because the configured storage encryption version (${storageEncryptionVersion}) is not the latest (${defaultVersion}). To enable storage data migration, please update the storage encryption version to the latest version.`;const UNSUPPORTED_RESIDENCY_SERVER_REGION_WARNING=(context,selectedResidencyServerRegion,defaultRegion)=>`${context}${LOG_CONTEXT_SEPARATOR}The residency server region "${selectedResidencyServerRegion}" is not supported. Please choose one of the following supported regions: "US, EU". The default region "${defaultRegion}" will be used instead.`;const RESERVED_KEYWORD_WARNING=(context,property,parentKeyPath,reservedElements)=>`${context}${LOG_CONTEXT_SEPARATOR}The "${property}" property defined under "${parentKeyPath}" is a reserved keyword. Please choose a different property name to avoid conflicts with reserved keywords (${reservedElements}).`;const UNSUPPORTED_BEACON_API_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The Beacon API is not supported by your browser. The events will be sent using XHR instead.`;const TIMEOUT_NOT_NUMBER_WARNING=(context,timeout,defaultValue)=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value "${timeout}" is not a number. The default timeout of ${defaultValue} ms will be used instead.`;const TIMEOUT_ZERO_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value is 0, which disables the automatic session tracking feature. If you want to enable session tracking, please provide a positive integer value for the timeout.`;const TIMEOUT_NOT_RECOMMENDED_WARNING=(context,timeout,minTimeout)=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value ${timeout} ms is less than the recommended minimum of ${minTimeout} ms. Please consider increasing the timeout value to ensure optimal performance and reliability.`;const INVALID_SESSION_ID_WARNING=(context,sessionId,minSessionIdLength)=>`${context}${LOG_CONTEXT_SEPARATOR}The provided session ID (${sessionId}) is either invalid, not a positive integer, or not at least "${minSessionIdLength}" digits long. A new session ID will be auto-generated instead.`;const STORAGE_QUOTA_EXCEEDED_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The storage is either full or unavailable, so the data will not be persisted. Switching to in-memory storage.`;const STORAGE_UNAVAILABLE_WARNING=(context,entry,selectedStorageType,finalStorageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage type "${selectedStorageType}" is not available for entry "${entry}". The SDK will initialize the entry with "${finalStorageType}" storage type instead.`;const WRITE_KEY_NOT_A_STRING_ERROR=(context,writeKey)=>`${context}${LOG_CONTEXT_SEPARATOR}The write key "${writeKey}" is not a string. Please check that the write key is correct and try again.`;const EMPTY_GROUP_CALL_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}The group() method must be called with at least one argument.`;const READY_CALLBACK_INVOKE_ERROR=`Failed to invoke the ready callback`;const API_CALLBACK_INVOKE_ERROR=`API Callback Invocation Failed`;const NATIVE_DEST_PLUGIN_INITIALIZE_ERROR=`NativeDestinationQueuePlugin initialization failed`;const DATAPLANE_PLUGIN_INITIALIZE_ERROR=`XhrQueuePlugin initialization failed`;const DMT_PLUGIN_INITIALIZE_ERROR=`DeviceModeTransformationPlugin initialization failed`;const NATIVE_DEST_PLUGIN_ENQUEUE_ERROR=`NativeDestinationQueuePlugin event enqueue failed`;const DATAPLANE_PLUGIN_ENQUEUE_ERROR=`XhrQueuePlugin event enqueue failed`;const INVALID_CONFIG_URL_WARNING=(context,configUrl)=>`${context}${LOG_CONTEXT_SEPARATOR}The provided config URL "${configUrl}" is invalid. Using the default
|
525
|
-
|
526
|
-
const CDN_INT_DIR='js-integrations';const CDN_PLUGINS_DIR='plugins';
|
522
|
+
const SOURCE_CONFIG_OPTION_ERROR=`"getSourceConfig" must be a function. Please make sure that it is defined and returns a valid source configuration object.`;const INTG_CDN_BASE_URL_ERROR=`Failed to load the SDK as the CDN base URL for integrations is not valid.`;const PLUGINS_CDN_BASE_URL_ERROR=`Failed to load the SDK as the CDN base URL for plugins is not valid.`;const DATA_PLANE_URL_ERROR=`Failed to load the SDK as the data plane URL could not be determined. Please check that the data plane URL is set correctly and try again.`;const SOURCE_CONFIG_RESOLUTION_ERROR=`Unable to process/parse source configuration response.`;const SOURCE_DISABLED_ERROR=`The source is disabled. Please enable the source in the dashboard to send events.`;const XHR_PAYLOAD_PREP_ERROR=`Failed to prepare data for the request.`;const EVENT_OBJECT_GENERATION_ERROR=`Failed to generate the event object.`;const PLUGIN_EXT_POINT_MISSING_ERROR=`Failed to invoke plugin because the extension point name is missing.`;const PLUGIN_EXT_POINT_INVALID_ERROR=`Failed to invoke plugin because the extension point name is invalid.`;// ERROR
|
523
|
+
const UNSUPPORTED_CONSENT_MANAGER_ERROR=(context,selectedConsentManager,consentManagersToPluginNameMap)=>`${context}${LOG_CONTEXT_SEPARATOR}The consent manager "${selectedConsentManager}" is not supported. Please choose one of the following supported consent managers: "${Object.keys(consentManagersToPluginNameMap)}".`;const REPORTING_PLUGIN_INIT_FAILURE_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to initialize the error reporting plugin.`;const NOTIFY_FAILURE_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to notify the error.`;const PLUGIN_NAME_MISSING_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin name is missing.`;const PLUGIN_ALREADY_EXISTS_ERROR=(context,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" already exists.`;const PLUGIN_NOT_FOUND_ERROR=(context,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" not found.`;const PLUGIN_ENGINE_BUG_ERROR=(context,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" not found in plugins but found in byName. This indicates a bug in the plugin engine. Please report this issue to the development team.`;const PLUGIN_DEPS_ERROR=(context,pluginName,notExistDeps)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" could not be loaded because some of its dependencies "${notExistDeps}" do not exist.`;const PLUGIN_INVOCATION_ERROR=(context,extPoint,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to invoke the "${extPoint}" extension point of plugin "${pluginName}".`;const STORAGE_UNAVAILABILITY_ERROR_PREFIX=(context,storageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The "${storageType}" storage type is `;const SOURCE_CONFIG_FETCH_ERROR=reason=>`Failed to fetch the source config. Reason: ${reason}`;const WRITE_KEY_VALIDATION_ERROR=writeKey=>`The write key "${writeKey}" is invalid. It must be a non-empty string. Please check that the write key is correct and try again.`;const DATA_PLANE_URL_VALIDATION_ERROR=dataPlaneUrl=>`The data plane URL "${dataPlaneUrl}" is invalid. It must be a valid URL string. Please check that the data plane URL is correct and try again.`;const READY_API_CALLBACK_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}The callback is not a function.`;const XHR_DELIVERY_ERROR=(prefix,status,statusText,url)=>`${prefix} with status: ${status}, ${statusText} for URL: ${url}.`;const XHR_REQUEST_ERROR=(prefix,e,url)=>`${prefix} due to timeout or no connection (${e?e.type:''}) for URL: ${url}.`;const XHR_SEND_ERROR=(prefix,url)=>`${prefix} for URL: ${url}`;const STORE_DATA_SAVE_ERROR=key=>`Failed to save the value for "${key}" to storage`;const STORE_DATA_FETCH_ERROR=key=>`Failed to retrieve or parse data for "${key}" from storage`;const DATA_SERVER_REQUEST_FAIL_ERROR=status=>`The server responded with status ${status} while setting the cookies. As a fallback, the cookies will be set client side.`;const FAILED_SETTING_COOKIE_FROM_SERVER_ERROR=key=>`The server failed to set the ${key} cookie. As a fallback, the cookies will be set client side.`;const FAILED_SETTING_COOKIE_FROM_SERVER_GLOBAL_ERROR=`Failed to set/remove cookies via server. As a fallback, the cookies will be managed client side.`;// WARNING
|
524
|
+
const STORAGE_TYPE_VALIDATION_WARNING=(context,storageType,defaultStorageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage type "${storageType}" is not supported. Please choose one of the following supported types: "${SUPPORTED_STORAGE_TYPES}". The default type "${defaultStorageType}" will be used instead.`;const UNSUPPORTED_ERROR_REPORTING_PROVIDER_WARNING=(context,selectedErrorReportingProvider,errorReportingProvidersToPluginNameMap,defaultProvider)=>`${context}${LOG_CONTEXT_SEPARATOR}The error reporting provider "${selectedErrorReportingProvider}" is not supported. Please choose one of the following supported providers: "${Object.keys(errorReportingProvidersToPluginNameMap)}". The default provider "${defaultProvider}" will be used instead.`;const UNSUPPORTED_STORAGE_ENCRYPTION_VERSION_WARNING=(context,selectedStorageEncryptionVersion,storageEncryptionVersionsToPluginNameMap,defaultVersion)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage encryption version "${selectedStorageEncryptionVersion}" is not supported. Please choose one of the following supported versions: "${Object.keys(storageEncryptionVersionsToPluginNameMap)}". The default version "${defaultVersion}" will be used instead.`;const STORAGE_DATA_MIGRATION_OVERRIDE_WARNING=(context,storageEncryptionVersion,defaultVersion)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage data migration has been disabled because the configured storage encryption version (${storageEncryptionVersion}) is not the latest (${defaultVersion}). To enable storage data migration, please update the storage encryption version to the latest version.`;const UNSUPPORTED_RESIDENCY_SERVER_REGION_WARNING=(context,selectedResidencyServerRegion,defaultRegion)=>`${context}${LOG_CONTEXT_SEPARATOR}The residency server region "${selectedResidencyServerRegion}" is not supported. Please choose one of the following supported regions: "US, EU". The default region "${defaultRegion}" will be used instead.`;const RESERVED_KEYWORD_WARNING=(context,property,parentKeyPath,reservedElements)=>`${context}${LOG_CONTEXT_SEPARATOR}The "${property}" property defined under "${parentKeyPath}" is a reserved keyword. Please choose a different property name to avoid conflicts with reserved keywords (${reservedElements}).`;const UNSUPPORTED_BEACON_API_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The Beacon API is not supported by your browser. The events will be sent using XHR instead.`;const TIMEOUT_NOT_NUMBER_WARNING=(context,timeout,defaultValue)=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value "${timeout}" is not a number. The default timeout of ${defaultValue} ms will be used instead.`;const TIMEOUT_ZERO_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value is 0, which disables the automatic session tracking feature. If you want to enable session tracking, please provide a positive integer value for the timeout.`;const TIMEOUT_NOT_RECOMMENDED_WARNING=(context,timeout,minTimeout)=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value ${timeout} ms is less than the recommended minimum of ${minTimeout} ms. Please consider increasing the timeout value to ensure optimal performance and reliability.`;const INVALID_SESSION_ID_WARNING=(context,sessionId,minSessionIdLength)=>`${context}${LOG_CONTEXT_SEPARATOR}The provided session ID (${sessionId}) is either invalid, not a positive integer, or not at least "${minSessionIdLength}" digits long. A new session ID will be auto-generated instead.`;const STORAGE_QUOTA_EXCEEDED_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The storage is either full or unavailable, so the data will not be persisted. Switching to in-memory storage.`;const STORAGE_UNAVAILABLE_WARNING=(context,entry,selectedStorageType,finalStorageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage type "${selectedStorageType}" is not available for entry "${entry}". The SDK will initialize the entry with "${finalStorageType}" storage type instead.`;const WRITE_KEY_NOT_A_STRING_ERROR=(context,writeKey)=>`${context}${LOG_CONTEXT_SEPARATOR}The write key "${writeKey}" is not a string. Please check that the write key is correct and try again.`;const EMPTY_GROUP_CALL_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}The group() method must be called with at least one argument.`;const READY_CALLBACK_INVOKE_ERROR=`Failed to invoke the ready callback`;const API_CALLBACK_INVOKE_ERROR=`API Callback Invocation Failed`;const NATIVE_DEST_PLUGIN_INITIALIZE_ERROR=`NativeDestinationQueuePlugin initialization failed`;const DATAPLANE_PLUGIN_INITIALIZE_ERROR=`XhrQueuePlugin initialization failed`;const DMT_PLUGIN_INITIALIZE_ERROR=`DeviceModeTransformationPlugin initialization failed`;const NATIVE_DEST_PLUGIN_ENQUEUE_ERROR=`NativeDestinationQueuePlugin event enqueue failed`;const DATAPLANE_PLUGIN_ENQUEUE_ERROR=`XhrQueuePlugin event enqueue failed`;const INVALID_CONFIG_URL_WARNING=(context,configUrl)=>`${context}${LOG_CONTEXT_SEPARATOR}The provided source config URL "${configUrl}" is invalid. Using the default source config URL instead.`;const POLYFILL_SCRIPT_LOAD_ERROR=(scriptId,url)=>`Failed to load the polyfill script with ID "${scriptId}" from URL ${url}.`;const COOKIE_DATA_ENCODING_ERROR=`Failed to encode the cookie data.`;const UNSUPPORTED_PRE_CONSENT_STORAGE_STRATEGY=(context,selectedStrategy,defaultStrategy)=>`${context}${LOG_CONTEXT_SEPARATOR}The pre-consent storage strategy "${selectedStrategy}" is not supported. Please choose one of the following supported strategies: "none, session, anonymousId". The default strategy "${defaultStrategy}" will be used instead.`;const UNSUPPORTED_PRE_CONSENT_EVENTS_DELIVERY_TYPE=(context,selectedDeliveryType,defaultDeliveryType)=>`${context}${LOG_CONTEXT_SEPARATOR}The pre-consent events delivery type "${selectedDeliveryType}" is not supported. Please choose one of the following supported types: "immediate, buffer". The default type "${defaultDeliveryType}" will be used instead.`;const generateMisconfiguredPluginsWarning=(context,configurationStatus,missingPlugins,shouldAddMissingPlugins)=>{const isSinglePlugin=missingPlugins.length===1;const pluginsString=isSinglePlugin?` '${missingPlugins[0]}' plugin was`:` ['${missingPlugins.join("', '")}'] plugins were`;const baseWarning=`${context}${LOG_CONTEXT_SEPARATOR}${configurationStatus}, but${pluginsString} not configured to load.`;if(shouldAddMissingPlugins){return `${baseWarning} So, ${isSinglePlugin?'the plugin':'those plugins'} will be loaded automatically.`;}return `${baseWarning} Ignore if this was intentional. Otherwise, consider adding ${isSinglePlugin?'it':'them'} to the 'plugins' load API option.`;};const INVALID_POLYFILL_URL_WARNING=(context,customPolyfillUrl)=>`${context}${LOG_CONTEXT_SEPARATOR}The provided polyfill URL "${customPolyfillUrl}" is invalid. The default polyfill URL will be used instead.`;// DEBUG
|
525
|
+
|
526
|
+
const CDN_INT_DIR='js-integrations';const CDN_PLUGINS_DIR='plugins';const URL_PATTERN=new RegExp('^(https?:\\/\\/)'+// protocol
|
527
|
+
'('+'((([a-zA-Z\\d]([a-zA-Z\\d-]*[a-zA-Z\\d])*)\\.)+[a-zA-Z]{2,}|'+// domain name
|
528
|
+
'localhost|'+// localhost
|
529
|
+
'((25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9]?)\\.){3}'+// OR IP (v4) address first 3 octets
|
530
|
+
'(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9]?))'+// last octet of IP address
|
531
|
+
')'+'(\\:\\d+)?'+// port
|
532
|
+
'(\\/[-a-zA-Z\\d%_.~+]*)*'+// path
|
533
|
+
'(\\?[;&a-zA-Z\\d%_.~+=-]*)?'+// query string
|
534
|
+
'(\\#[-a-zA-Z\\d_]*)?$')// fragment locator
|
535
|
+
;
|
527
536
|
|
528
537
|
const BUILD_TYPE='modern';const SDK_CDN_BASE_URL='https://cdn.rudderlabs.com';const CDN_ARCH_VERSION_DIR='v3';const DEST_SDK_BASE_URL=`${SDK_CDN_BASE_URL}/${CDN_ARCH_VERSION_DIR}/${BUILD_TYPE}/${CDN_INT_DIR}`;const PLUGINS_BASE_URL=`${SDK_CDN_BASE_URL}/${CDN_ARCH_VERSION_DIR}/${BUILD_TYPE}/${CDN_PLUGINS_DIR}`;const DEFAULT_CONFIG_BE_URL='https://api.rudderstack.com';
|
529
538
|
|
@@ -547,7 +556,7 @@
|
|
547
556
|
|
548
557
|
const metricsState={retries:d$1(0),dropped:d$1(0),sent:d$1(0),queued:d$1(0),triggered:d$1(0)};
|
549
558
|
|
550
|
-
const contextState={app:d$1({name:APP_NAME,namespace:APP_NAMESPACE,version:APP_VERSION}),traits:d$1(null),library:d$1({name:APP_NAME,version:APP_VERSION,snippetVersion:globalThis.RudderSnippetVersion}),userAgent:d$1(''),device:d$1(null),network:d$1(null),os:d$1({name:'',version:''}),locale:d$1(null),screen:d$1({density:0,width:0,height:0,innerWidth:0,innerHeight:0}),'ua-ch':d$1(undefined),timezone:d$1(undefined)};
|
559
|
+
const contextState={app:d$1({name:APP_NAME,namespace:APP_NAMESPACE,version:APP_VERSION,installType:MODULE_TYPE}),traits:d$1(null),library:d$1({name:APP_NAME,version:APP_VERSION,snippetVersion:globalThis.RudderSnippetVersion}),userAgent:d$1(''),device:d$1(null),network:d$1(null),os:d$1({name:'',version:''}),locale:d$1(null),screen:d$1({density:0,width:0,height:0,innerWidth:0,innerHeight:0}),'ua-ch':d$1(undefined),timezone:d$1(undefined)};
|
551
560
|
|
552
561
|
const nativeDestinationsState={configuredDestinations:d$1([]),activeDestinations:d$1([]),loadOnlyIntegrations:d$1({}),failedDestinations:d$1([]),loadIntegration:d$1(true),initializedDestinations:d$1([]),clientDestinationsReady:d$1(false),integrationsConfig:d$1({})};
|
553
562
|
|
@@ -633,7 +642,14 @@
|
|
633
642
|
|
634
643
|
const COOKIE_STORAGE='cookieStorage';const LOCAL_STORAGE='localStorage';const SESSION_STORAGE='sessionStorage';const MEMORY_STORAGE='memoryStorage';const NO_STORAGE='none';
|
635
644
|
|
636
|
-
const removeDuplicateSlashes=str=>str.replace(/\/{2,}/g,'/')
|
645
|
+
const removeDuplicateSlashes=str=>str.replace(/\/{2,}/g,'/');/**
|
646
|
+
* Checks if provided url is valid or not
|
647
|
+
* @param url
|
648
|
+
* @returns true if `url` is valid and false otherwise
|
649
|
+
*/const isValidURL=url=>{if(!isString(url)){return false;}try{// If URL is supported by the browser, we can use it to validate the URL
|
650
|
+
// Otherwise, we can at least check if the URL matches the pattern
|
651
|
+
if(isFunction(globalThis.URL)){// eslint-disable-next-line no-new
|
652
|
+
new URL(url);}return URL_PATTERN.test(url);}catch(e){return false;}};
|
637
653
|
|
638
654
|
function random(len){return crypto.getRandomValues(new Uint8Array(len));}
|
639
655
|
|
@@ -803,7 +819,7 @@
|
|
803
819
|
// It'll be updated to the latest timestamp during actual delivery
|
804
820
|
event.sentAt=getCurrentTimeFormatted();validateEventPayloadSize(event,logger);eventsQueue.addItem({event});}}});
|
805
821
|
|
806
|
-
const BUGSNAG_API_KEY_VALIDATION_ERROR=apiKey=>`The Bugsnag API key (${apiKey}) is invalid or not provided.`;const BUGSNAG_SDK_LOAD_TIMEOUT_ERROR=timeout=>`A timeout ${timeout} ms occurred while trying to load the Bugsnag SDK.`;const BUGSNAG_SDK_LOAD_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to load the Bugsnag SDK.`;
|
822
|
+
const BUGSNAG_API_KEY_VALIDATION_ERROR=apiKey=>`The Bugsnag API key (${apiKey}) is invalid or not provided.`;const BUGSNAG_SDK_LOAD_TIMEOUT_ERROR=timeout=>`A timeout ${timeout} ms occurred while trying to load the Bugsnag SDK.`;const BUGSNAG_SDK_LOAD_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to load the Bugsnag SDK.`;const FAILED_TO_FILTER_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to filter the error.`;
|
807
823
|
|
808
824
|
const BUGSNAG_LIB_INSTANCE_GLOBAL_KEY_NAME='bugsnag';// For version 6 and below
|
809
825
|
const BUGSNAG_LIB_V7_INSTANCE_GLOBAL_KEY_NAME='Bugsnag';const GLOBAL_LIBRARY_OBJECT_NAMES=[BUGSNAG_LIB_V7_INSTANCE_GLOBAL_KEY_NAME,BUGSNAG_LIB_INSTANCE_GLOBAL_KEY_NAME];const BUGSNAG_CDN_URL='https://d2wy8f7a9ursnm.cloudfront.net/v6/bugsnag.min.js';const ERROR_REPORT_PROVIDER_NAME_BUGSNAG='rs-bugsnag';// This API key token is parsed in the CI pipeline
|
@@ -822,19 +838,18 @@
|
|
822
838
|
let version=globalLibInstance?._client?._notifier?.version;// For versions older than 7
|
823
839
|
if(!version){const tempInstance=globalLibInstance({apiKey:API_KEY,releaseStage:'version-test',// eslint-disable-next-line func-names, object-shorthand
|
824
840
|
beforeSend:function(){return false;}});version=tempInstance.notifier?.version;}return version&&version.charAt(0)===BUGSNAG_VALID_MAJOR_VERSION;};const isRudderSDKError=event=>{const errorOrigin=event.stacktrace?.[0]?.file;if(!errorOrigin||typeof errorOrigin!=='string'){return false;}// Prefix folder for all the destination SDK scripts
|
825
|
-
const isDestinationIntegrationBundle=errorOrigin.includes(CDN_INT_DIR);const srcFileName=errorOrigin.substring(errorOrigin.lastIndexOf('/')+1);return isDestinationIntegrationBundle||SDK_FILE_NAME_PREFIXES().some(prefix=>srcFileName.startsWith(prefix)&&srcFileName.endsWith('.js'));};const enhanceErrorEventMutator=
|
841
|
+
const isDestinationIntegrationBundle=errorOrigin.includes(CDN_INT_DIR);const srcFileName=errorOrigin.substring(errorOrigin.lastIndexOf('/')+1);return isDestinationIntegrationBundle||SDK_FILE_NAME_PREFIXES().some(prefix=>srcFileName.startsWith(prefix)&&srcFileName.endsWith('.js'));};const enhanceErrorEventMutator=event=>{event.updateMetaData('source',{snippetVersion:globalThis.RudderSnippetVersion});const{errorMessage}=event;// eslint-disable-next-line no-param-reassign
|
826
842
|
event.context=errorMessage;// Hack for easily grouping the script load errors
|
827
843
|
// on the dashboard
|
828
844
|
if(errorMessage.includes('error in script loading')){// eslint-disable-next-line no-param-reassign
|
829
845
|
event.context='Script load failures';}// eslint-disable-next-line no-param-reassign
|
830
|
-
event.severity='error';};const onError=
|
831
|
-
if(!isRudderSDKError(event)){return false;}enhanceErrorEventMutator(event
|
846
|
+
event.severity='error';};const onError=logger=>event=>{try{// Discard the event if it's not originated at the SDK
|
847
|
+
if(!isRudderSDKError(event)){return false;}enhanceErrorEventMutator(event);return true;}catch{logger?.error(FAILED_TO_FILTER_ERROR(BUGSNAG_PLUGIN));// Drop the error event if it couldn't be filtered as
|
832
848
|
// it is most likely a non-SDK error
|
833
|
-
return false;}};
|
834
|
-
metaData:{SDK:{name:'JS',installType:'npm'}},beforeSend:onError(state),autoCaptureSessions:false,// auto capture sessions is disabled
|
849
|
+
return false;}};const getReleaseStage=()=>{const host=globalThis.location.hostname;return host&&DEV_HOSTS.includes(host)?'development':'production';};const getGlobalBugsnagLibInstance=()=>globalThis[BUGSNAG_LIB_INSTANCE_GLOBAL_KEY_NAME];const getNewClient=(state,logger)=>{const globalBugsnagLibInstance=getGlobalBugsnagLibInstance();const clientConfig={apiKey:API_KEY,appVersion:state.context.app.value.version,metaData:{SDK:{name:'JS',installType:state.context.app.value.installType}},beforeSend:onError(logger),autoCaptureSessions:false,// auto capture sessions is disabled
|
835
850
|
collectUserIp:false,// collecting user's IP is disabled
|
836
851
|
// enabledBreadcrumbTypes: ['error', 'log', 'user'], // for v7 and above
|
837
|
-
maxEvents:100,maxBreadcrumbs:40,releaseStage:getReleaseStage(),user:{id:state.lifecycle.writeKey.value},logger,networkBreadcrumbsEnabled:false};const client=globalBugsnagLibInstance(clientConfig);return client;};const isApiKeyValid=apiKey=>{const isAPIKeyValid=!(apiKey.startsWith('{{')||apiKey.endsWith('}}')||apiKey.length===0);return isAPIKeyValid;};const loadBugsnagSDK=(externalSrcLoader,logger)=>{const isNotLoaded=GLOBAL_LIBRARY_OBJECT_NAMES.every(globalKeyName=>!globalThis[globalKeyName]);if(!isNotLoaded){return;}externalSrcLoader.loadJSFile({url:BUGSNAG_CDN_URL,id:ERROR_REPORT_PROVIDER_NAME_BUGSNAG,callback:id=>{if(!id){logger?.error(BUGSNAG_SDK_LOAD_ERROR(BUGSNAG_PLUGIN));}}});};const initBugsnagClient=(state,promiseResolve,promiseReject,logger,time=0)=>{const globalBugsnagLibInstance=getGlobalBugsnagLibInstance();if(typeof globalBugsnagLibInstance==='function'){if(isValidVersion(globalBugsnagLibInstance)){const client=getNewClient(state,logger);promiseResolve(client);}}else if(time>=MAX_WAIT_FOR_SDK_LOAD_MS){promiseReject(new Error(BUGSNAG_SDK_LOAD_TIMEOUT_ERROR(MAX_WAIT_FOR_SDK_LOAD_MS)));}else {// Try to initialize the client after a delay
|
852
|
+
maxEvents:100,maxBreadcrumbs:40,releaseStage:getReleaseStage(),user:{id:state.source.value?.id||state.lifecycle.writeKey.value},logger,networkBreadcrumbsEnabled:false};const client=globalBugsnagLibInstance(clientConfig);return client;};const isApiKeyValid=apiKey=>{const isAPIKeyValid=!(apiKey.startsWith('{{')||apiKey.endsWith('}}')||apiKey.length===0);return isAPIKeyValid;};const loadBugsnagSDK=(externalSrcLoader,logger)=>{const isNotLoaded=GLOBAL_LIBRARY_OBJECT_NAMES.every(globalKeyName=>!globalThis[globalKeyName]);if(!isNotLoaded){return;}externalSrcLoader.loadJSFile({url:BUGSNAG_CDN_URL,id:ERROR_REPORT_PROVIDER_NAME_BUGSNAG,callback:id=>{if(!id){logger?.error(BUGSNAG_SDK_LOAD_ERROR(BUGSNAG_PLUGIN));}}});};const initBugsnagClient=(state,promiseResolve,promiseReject,logger,time=0)=>{const globalBugsnagLibInstance=getGlobalBugsnagLibInstance();if(typeof globalBugsnagLibInstance==='function'){if(isValidVersion(globalBugsnagLibInstance)){const client=getNewClient(state,logger);promiseResolve(client);}}else if(time>=MAX_WAIT_FOR_SDK_LOAD_MS){promiseReject(new Error(BUGSNAG_SDK_LOAD_TIMEOUT_ERROR(MAX_WAIT_FOR_SDK_LOAD_MS)));}else {// Try to initialize the client after a delay
|
838
853
|
globalThis.setTimeout(initBugsnagClient,SDK_LOAD_POLL_INTERVAL_MS,state,promiseResolve,promiseReject,logger,time+SDK_LOAD_POLL_INTERVAL_MS);}};const getAppStateForMetadata=state=>{const stateStr=stringifyWithoutCircular(state,false,APP_STATE_EXCLUDE_KEYS);return stateStr!==null?JSON.parse(stateStr):undefined;};
|
839
854
|
|
840
855
|
const pluginName$d='Bugsnag';const Bugsnag=()=>({name:pluginName$d,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$d];},errorReportingProvider:{init:(state,externalSrcLoader,logger)=>new Promise((resolve,reject)=>{// If API key token is not parsed or invalid, don't proceed to initialize the client
|
@@ -2321,7 +2336,7 @@
|
|
2321
2336
|
*/ // eslint-disable-next-line class-methods-use-this
|
2322
2337
|
getPluginsToLoadBasedOnConfig(){// This contains the default plugins if load option has been omitted by user
|
2323
2338
|
let pluginsToLoadFromConfig=state.plugins.pluginsToLoadFromConfig.value;if(!pluginsToLoadFromConfig){return [];}const pluginGroupsToProcess=[{configurationStatus:()=>isDefined(state.dataPlaneEvents.eventsQueuePluginName.value),configurationStatusStr:'Data plane events delivery is enabled',activePluginName:state.dataPlaneEvents.eventsQueuePluginName.value,supportedPlugins:Object.values(DataPlaneEventsTransportToPluginNameMap),shouldAddMissingPlugins:true},{configurationStatus:()=>isDefined(state.reporting.errorReportingProviderPluginName.value),configurationStatusStr:'Error reporting is enabled',activePluginName:state.reporting.errorReportingProviderPluginName.value,basePlugins:['ErrorReporting'],supportedPlugins:Object.values(ErrorReportingProvidersToPluginNameMap)},{configurationStatus:()=>getNonCloudDestinations(state.nativeDestinations.configuredDestinations.value).length>0,configurationStatusStr:'Device mode destinations are connected to the source',supportedPlugins:['DeviceModeDestinations','NativeDestinationQueue']},{configurationStatus:()=>getNonCloudDestinations(state.nativeDestinations.configuredDestinations.value).some(destination=>destination.shouldApplyDeviceModeTransformation),configurationStatusStr:'Device mode transformations are enabled for at least one destination',supportedPlugins:['DeviceModeTransformation']},{configurationStatus:()=>isDefined(state.consents.activeConsentManagerPluginName.value),configurationStatusStr:'Consent management is enabled',activePluginName:state.consents.activeConsentManagerPluginName.value,supportedPlugins:Object.values(ConsentManagersToPluginNameMap)},{configurationStatus:()=>isDefined(state.storage.encryptionPluginName.value),configurationStatusStr:'Storage encryption is enabled',activePluginName:state.storage.encryptionPluginName.value,supportedPlugins:Object.values(StorageEncryptionVersionsToPluginNameMap)},{configurationStatus:()=>state.storage.migrate.value,configurationStatusStr:'Storage migration is enabled',supportedPlugins:['StorageMigrator']}];const addMissingPlugins=false;pluginGroupsToProcess.forEach(group=>{if(group.configurationStatus()){pluginsToLoadFromConfig=pluginsToLoadFromConfig.filter(group.activePluginName?pluginName=>!(pluginName!==group.activePluginName&&group.supportedPlugins.includes(pluginName)):pluginName=>isDefined(pluginName)// pass through
|
2324
|
-
);this.addMissingPlugins(group,addMissingPlugins,pluginsToLoadFromConfig);}else {pluginsToLoadFromConfig=pluginsToLoadFromConfig.filter(group.basePlugins!==undefined?pluginName=>!(group.basePlugins.includes(pluginName)||group.supportedPlugins.includes(pluginName)):pluginName=>!group.supportedPlugins.includes(pluginName));}});return [...Object.keys(getMandatoryPluginsMap()),...pluginsToLoadFromConfig];}addMissingPlugins(group,addMissingPlugins,pluginsToLoadFromConfig){const shouldAddMissingPlugins=group.shouldAddMissingPlugins||addMissingPlugins;let pluginsToConfigure;if(group.activePluginName){pluginsToConfigure=[...(group.basePlugins||[]),group.activePluginName];}else {pluginsToConfigure=[...group.supportedPlugins];}const missingPlugins=pluginsToConfigure.filter(pluginName=>!pluginsToLoadFromConfig.includes(pluginName));if(missingPlugins.length>0){if(shouldAddMissingPlugins){pluginsToLoadFromConfig.push(...missingPlugins);}this.logger?.warn(
|
2339
|
+
);this.addMissingPlugins(group,addMissingPlugins,pluginsToLoadFromConfig);}else {pluginsToLoadFromConfig=pluginsToLoadFromConfig.filter(group.basePlugins!==undefined?pluginName=>!(group.basePlugins.includes(pluginName)||group.supportedPlugins.includes(pluginName)):pluginName=>!group.supportedPlugins.includes(pluginName));}});return [...Object.keys(getMandatoryPluginsMap()),...pluginsToLoadFromConfig];}addMissingPlugins(group,addMissingPlugins,pluginsToLoadFromConfig){const shouldAddMissingPlugins=group.shouldAddMissingPlugins||addMissingPlugins;let pluginsToConfigure;if(group.activePluginName){pluginsToConfigure=[...(group.basePlugins||[]),group.activePluginName];}else {pluginsToConfigure=[...group.supportedPlugins];}const missingPlugins=pluginsToConfigure.filter(pluginName=>!pluginsToLoadFromConfig.includes(pluginName));if(missingPlugins.length>0){if(shouldAddMissingPlugins){pluginsToLoadFromConfig.push(...missingPlugins);}this.logger?.warn(generateMisconfiguredPluginsWarning(PLUGINS_MANAGER,group.configurationStatusStr,missingPlugins,shouldAddMissingPlugins));}}/**
|
2325
2340
|
* Determine the list of plugins that should be activated
|
2326
2341
|
*/setActivePlugins(){const pluginsToLoad=this.getPluginsToLoadBasedOnConfig();// Merging available mandatory and optional plugin name list
|
2327
2342
|
const availablePlugins=[...Object.keys(pluginsInventory),...pluginNamesList];const activePlugins=[];const failedPlugins=[];pluginsToLoad.forEach(pluginName=>{if(availablePlugins.includes(pluginName)){activePlugins.push(pluginName);}else {failedPlugins.push(pluginName);}});if(failedPlugins.length>0){this.onError(new Error(`Ignoring loading of unknown plugins: ${failedPlugins.join(',')}. Mandatory plugins: ${Object.keys(getMandatoryPluginsMap()).join(',')}. Load option plugins: ${state.plugins.pluginsToLoadFromConfig.value.join(',')}`));}r(()=>{state.plugins.totalPluginsToLoad.value=pluginsToLoad.length;state.plugins.activePlugins.value=activePlugins;state.plugins.failedPlugins.value=failedPlugins;});}/**
|
@@ -2352,7 +2367,7 @@
|
|
2352
2367
|
* this is not supported by our sourceConfig API
|
2353
2368
|
*/const xhrRequest=(options,timeout=DEFAULT_XHR_TIMEOUT_MS,logger)=>new Promise((resolve,reject)=>{let payload;if(options.sendRawData===true){payload=options.data;}else {payload=stringifyWithoutCircular(options.data,false,[],logger);if(isNull(payload)){reject({error:new Error(XHR_PAYLOAD_PREP_ERROR),undefined,options});// return and don't process further if the payload could not be stringified
|
2354
2369
|
return;}}const xhr=new XMLHttpRequest();// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
2355
|
-
const xhrReject=e=>{reject({error:new Error(XHR_DELIVERY_ERROR(FAILED_REQUEST_ERR_MSG_PREFIX,xhr.status,xhr.statusText,options.url)),xhr,options});};const xhrError=e=>{reject({error:new Error(XHR_REQUEST_ERROR(FAILED_REQUEST_ERR_MSG_PREFIX,e,options.url)),xhr,options});};xhr.ontimeout=xhrError;xhr.onerror=xhrError;xhr.onload=()=>{if(xhr.status>=200&&xhr.status<400){resolve({response:xhr.responseText,xhr,options});}else {xhrReject();}};xhr.open(options.method,options.url)
|
2370
|
+
const xhrReject=e=>{reject({error:new Error(XHR_DELIVERY_ERROR(FAILED_REQUEST_ERR_MSG_PREFIX,xhr.status,xhr.statusText,options.url)),xhr,options});};const xhrError=e=>{reject({error:new Error(XHR_REQUEST_ERROR(FAILED_REQUEST_ERR_MSG_PREFIX,e,options.url)),xhr,options});};xhr.ontimeout=xhrError;xhr.onerror=xhrError;xhr.onload=()=>{if(xhr.status>=200&&xhr.status<400){resolve({response:xhr.responseText,xhr,options});}else {xhrReject();}};xhr.open(options.method,options.url);if(options.withCredentials===true){xhr.withCredentials=true;}// The timeout property may be set only in the time interval between a call to the open method
|
2356
2371
|
// and the first call to the send method in legacy browsers
|
2357
2372
|
xhr.timeout=timeout;Object.keys(options.headers).forEach(headerName=>{if(options.headers[headerName]){xhr.setRequestHeader(headerName,options.headers[headerName]);}});try{xhr.send(payload);}catch(err){reject({error:getMutatedError(err,XHR_SEND_ERROR(FAILED_REQUEST_ERR_MSG_PREFIX,options.url)),xhr,options});}});
|
2358
2373
|
|
@@ -2447,7 +2462,7 @@
|
|
2447
2462
|
if(cookie(cname)){// Remove cookie from domain
|
2448
2463
|
cookie(cname,null,opts);return domain;}}return '';};
|
2449
2464
|
|
2450
|
-
const getDefaultCookieOptions=()=>{const topDomain
|
2465
|
+
const getDefaultCookieOptions=()=>{const topDomain=`.${domain(globalThis.location.href)}`;return {maxage:DEFAULT_COOKIE_MAX_AGE_MS,path:'/',domain:!topDomain||topDomain==='.'?undefined:topDomain,samesite:'Lax',enabled:true};};const getDefaultLocalStorageOptions=()=>({enabled:true});const getDefaultSessionStorageOptions=()=>({enabled:true});const getDefaultInMemoryStorageOptions=()=>({enabled:true});
|
2451
2466
|
|
2452
2467
|
/**
|
2453
2468
|
* A storage utility to persist values in cookies via Storage interface
|
@@ -2564,20 +2579,30 @@
|
|
2564
2579
|
* Handle errors
|
2565
2580
|
*/onError(error){if(this.hasErrorHandler){this.errorHandler?.onError(error,STORE_MANAGER);}else {throw error;}}}
|
2566
2581
|
|
2582
|
+
const validateWriteKey=writeKey=>{if(!isString(writeKey)||writeKey.trim().length===0){throw new Error(WRITE_KEY_VALIDATION_ERROR(writeKey));}};const validateDataPlaneUrl=dataPlaneUrl=>{if(!isValidURL(dataPlaneUrl)){throw new Error(DATA_PLANE_URL_VALIDATION_ERROR(dataPlaneUrl));}};const validateLoadArgs=(writeKey,dataPlaneUrl)=>{validateWriteKey(writeKey);validateDataPlaneUrl(dataPlaneUrl);};const isValidSourceConfig=res=>isObjectLiteralAndNotNull(res)&&isObjectLiteralAndNotNull(res.source)&&!isNullOrUndefined(res.source.id)&&isObjectLiteralAndNotNull(res.source.config)&&Array.isArray(res.source.destinations);const isValidStorageType=storageType=>typeof storageType==='string'&&SUPPORTED_STORAGE_TYPES.includes(storageType);const getTopDomainUrl=url=>{// Create a URL object
|
2583
|
+
const urlObj=new URL(url);// Extract the host and protocol
|
2584
|
+
const{host,protocol}=urlObj;// Split the host into parts
|
2585
|
+
const parts=host.split('.');let topDomain;// Handle different cases, especially for co.uk or similar TLDs
|
2586
|
+
if(parts.length>2){// Join the last two parts for the top-level domain
|
2587
|
+
topDomain=`${parts[parts.length-2]}.${parts[parts.length-1]}`;}else {// If only two parts or less, return as it is
|
2588
|
+
topDomain=host;}return `${protocol}//${topDomain}`;};const getDataServiceUrl=endpoint=>{const url=getTopDomainUrl(window.location.href);const formattedEndpoint=endpoint.startsWith('/')?endpoint.substring(1):endpoint;return `${url}/${formattedEndpoint}`;};
|
2589
|
+
|
2590
|
+
/**
|
2591
|
+
* A function to filter enabled destinations and map to required properties only
|
2592
|
+
* @param destinations
|
2593
|
+
*
|
2594
|
+
* @returns Destination[]
|
2595
|
+
*/const filterEnabledDestination=destinations=>{const nativeDestinations=[];destinations.forEach(destination=>{if(destination.enabled&&!destination.deleted){nativeDestinations.push({id:destination.id,displayName:destination.destinationDefinition.displayName,config:destination.config,shouldApplyDeviceModeTransformation:destination.shouldApplyDeviceModeTransformation||false,propagateEventsUntransformedOnError:destination.propagateEventsUntransformedOnError||false,userFriendlyId:`${destination.destinationDefinition.displayName.replaceAll(' ','-')}___${destination.id}`});}});return nativeDestinations;};
|
2596
|
+
|
2567
2597
|
/**
|
2568
2598
|
* Removes trailing slash from url
|
2569
2599
|
* @param url
|
2570
2600
|
* @returns url
|
2571
|
-
*/const removeTrailingSlashes=url=>url
|
2572
|
-
* Checks if provided url is valid or not
|
2573
|
-
* @param url
|
2574
|
-
* @returns true if `url` is valid and false otherwise
|
2575
|
-
*/const isValidUrl=url=>{try{const validUrl=new URL(url);return Boolean(validUrl);}catch(err){return false;}};/**
|
2601
|
+
*/const removeTrailingSlashes=url=>url?.endsWith('/')?removeTrailingSlashes(url.substring(0,url.length-1)):url;const getDomain=url=>{try{const urlObj=new URL(url);return urlObj.host;}catch(error){return null;}};/**
|
2576
2602
|
* Get the referring domain from the referrer URL
|
2577
2603
|
* @param referrer Page referrer
|
2578
2604
|
* @returns Page referring domain
|
2579
|
-
*/const getReferringDomain=referrer=>
|
2580
|
-
}return referringDomain;};/**
|
2605
|
+
*/const getReferringDomain=referrer=>getDomain(referrer)??'';/**
|
2581
2606
|
* Extracts UTM parameters from the URL
|
2582
2607
|
* @param url Page URL
|
2583
2608
|
* @returns UTM parameters
|
@@ -2590,51 +2615,11 @@
|
|
2590
2615
|
*/const getUrlWithoutHash=url=>{let urlWithoutHash=url;try{const urlObj=new URL(url);urlWithoutHash=urlObj.origin+urlObj.pathname+urlObj.search;}catch(error){// Do nothing
|
2591
2616
|
}return urlWithoutHash;};
|
2592
2617
|
|
2593
|
-
const validateWriteKey=writeKey=>{if(!isString(writeKey)||writeKey.trim().length===0){throw new Error(WRITE_KEY_VALIDATION_ERROR(writeKey));}};const validateDataPlaneUrl=dataPlaneUrl=>{if(dataPlaneUrl&&!isValidUrl(dataPlaneUrl)){throw new Error(DATA_PLANE_URL_VALIDATION_ERROR(dataPlaneUrl));}};const validateLoadArgs=(writeKey,dataPlaneUrl)=>{validateWriteKey(writeKey);validateDataPlaneUrl(dataPlaneUrl);};const isValidSourceConfig=res=>isObjectLiteralAndNotNull(res)&&isObjectLiteralAndNotNull(res.source)&&!isNullOrUndefined(res.source.id)&&isObjectLiteralAndNotNull(res.source.config)&&Array.isArray(res.source.destinations);const isValidStorageType=storageType=>typeof storageType==='string'&&SUPPORTED_STORAGE_TYPES.includes(storageType);const getTopDomainUrl=url=>{// Create a URL object
|
2594
|
-
const urlObj=new URL(url);// Extract the hostname and protocol
|
2595
|
-
const{hostname,protocol}=urlObj;// Split the hostname into parts
|
2596
|
-
const parts=hostname.split('.');let topDomain;// Handle different cases, especially for co.uk or similar TLDs
|
2597
|
-
if(parts.length>2){// Join the last two parts for the top-level domain
|
2598
|
-
topDomain=`${parts[parts.length-2]}.${parts[parts.length-1]}`;}else {// If only two parts or less, return as it is
|
2599
|
-
topDomain=hostname;}return `${protocol}//${topDomain}`;};const getDataServiceUrl=endpoint=>{const url=getTopDomainUrl(window.location.href);const formattedEndpoint=endpoint.startsWith('/')?endpoint.substring(1):endpoint;return `${url}/${formattedEndpoint}`;};
|
2600
|
-
|
2601
|
-
/**
|
2602
|
-
* Plugins to be loaded in the plugins loadOption is not defined
|
2603
|
-
*/const defaultOptionalPluginsList=['BeaconQueue','Bugsnag','CustomConsentManager','DeviceModeDestinations','DeviceModeTransformation','ErrorReporting','ExternalAnonymousId','GoogleLinker','KetchConsentManager','NativeDestinationQueue','OneTrustConsentManager','StorageEncryption','StorageEncryptionLegacy','StorageMigrator','XhrQueue'];
|
2604
|
-
|
2605
|
-
/**
|
2606
|
-
* A function to check given value is a number or not
|
2607
|
-
* @param num input value
|
2608
|
-
* @returns boolean
|
2609
|
-
*/const isNumber=num=>typeof num==='number'&&!Number.isNaN(num);/**
|
2610
|
-
* A function to check given number has minimum length or not
|
2611
|
-
* @param minimumLength minimum length
|
2612
|
-
* @param num input number
|
2613
|
-
* @returns boolean
|
2614
|
-
*/const hasMinLength=(minimumLength,num)=>num.toString().length>=minimumLength;/**
|
2615
|
-
* A function to check given value is a positive integer or not
|
2616
|
-
* @param num input value
|
2617
|
-
* @returns boolean
|
2618
|
-
*/const isPositiveInteger=num=>isNumber(num)&&num>=0&&Number.isInteger(num);
|
2619
|
-
|
2620
|
-
const normalizeLoadOptions=(loadOptionsFromState,loadOptions)=>{// TODO: Maybe add warnings for invalid values
|
2621
|
-
const normalizedLoadOpts=clone(loadOptions);if(!isString(normalizedLoadOpts.setCookieDomain)){delete normalizedLoadOpts.setCookieDomain;}const cookieSameSiteValues=['Strict','Lax','None'];if(!cookieSameSiteValues.includes(normalizedLoadOpts.sameSiteCookie)){delete normalizedLoadOpts.sameSiteCookie;}normalizedLoadOpts.secureCookie=normalizedLoadOpts.secureCookie===true;const uaChTrackLevels=['none','default','full'];if(!uaChTrackLevels.includes(normalizedLoadOpts.uaChTrackLevel)){delete normalizedLoadOpts.uaChTrackLevel;}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.integrations)){delete normalizedLoadOpts.integrations;}normalizedLoadOpts.plugins=normalizedLoadOpts.plugins??defaultOptionalPluginsList;normalizedLoadOpts.useGlobalIntegrationsConfigInEvents=normalizedLoadOpts.useGlobalIntegrationsConfigInEvents===true;normalizedLoadOpts.bufferDataPlaneEventsUntilReady=normalizedLoadOpts.bufferDataPlaneEventsUntilReady===true;normalizedLoadOpts.sendAdblockPage=normalizedLoadOpts.sendAdblockPage===true;normalizedLoadOpts.useServerSideCookies=normalizedLoadOpts.useServerSideCookies===true;if(normalizedLoadOpts.dataServiceEndpoint&&typeof normalizedLoadOpts.dataServiceEndpoint!=='string'){delete normalizedLoadOpts.dataServiceEndpoint;}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.sendAdblockPageOptions)){delete normalizedLoadOpts.sendAdblockPageOptions;}if(!isDefined(normalizedLoadOpts.loadIntegration)){delete normalizedLoadOpts.loadIntegration;}else {normalizedLoadOpts.loadIntegration=normalizedLoadOpts.loadIntegration===true;}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.storage)){delete normalizedLoadOpts.storage;}else {normalizedLoadOpts.storage=removeUndefinedAndNullValues(normalizedLoadOpts.storage);normalizedLoadOpts.storage.migrate=normalizedLoadOpts.storage?.migrate===true;}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.beaconQueueOptions)){delete normalizedLoadOpts.beaconQueueOptions;}else {normalizedLoadOpts.beaconQueueOptions=removeUndefinedAndNullValues(normalizedLoadOpts.beaconQueueOptions);}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.destinationsQueueOptions)){delete normalizedLoadOpts.destinationsQueueOptions;}else {normalizedLoadOpts.destinationsQueueOptions=removeUndefinedAndNullValues(normalizedLoadOpts.destinationsQueueOptions);}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.queueOptions)){delete normalizedLoadOpts.queueOptions;}else {normalizedLoadOpts.queueOptions=removeUndefinedAndNullValues(normalizedLoadOpts.queueOptions);}normalizedLoadOpts.lockIntegrationsVersion=normalizedLoadOpts.lockIntegrationsVersion===true;if(!isNumber(normalizedLoadOpts.dataPlaneEventsBufferTimeout)){delete normalizedLoadOpts.dataPlaneEventsBufferTimeout;}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.storage?.cookie)){delete normalizedLoadOpts.storage?.cookie;}else {normalizedLoadOpts.storage.cookie=removeUndefinedAndNullValues(normalizedLoadOpts.storage?.cookie);}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.preConsent)){delete normalizedLoadOpts.preConsent;}else {normalizedLoadOpts.preConsent=removeUndefinedAndNullValues(normalizedLoadOpts.preConsent);}const mergedLoadOptions=mergeDeepRight(loadOptionsFromState,normalizedLoadOpts);return mergedLoadOptions;};const getSourceConfigURL=(configUrl,writeKey,lockIntegrationsVersion,logger)=>{const defSearchParams=new URLSearchParams({p:MODULE_TYPE,v:APP_VERSION,build:BUILD_TYPE,writeKey,lockIntegrationsVersion:lockIntegrationsVersion.toString()});let origin=DEFAULT_CONFIG_BE_URL;let searchParams=defSearchParams;let pathname='/sourceConfig/';let hash='';// Ideally, this check is not required but URL polyfill
|
2622
|
-
// doesn't seem to throw errors for empty URLs
|
2623
|
-
// TODO: Need to improve this check to find out if the URL is valid or not
|
2624
|
-
if(configUrl){try{const configUrlInstance=new URL(configUrl);if(!removeTrailingSlashes(configUrlInstance.pathname).endsWith('/sourceConfig')){configUrlInstance.pathname=`${removeTrailingSlashes(configUrlInstance.pathname)}/sourceConfig/`;}configUrlInstance.pathname=removeDuplicateSlashes(configUrlInstance.pathname);defSearchParams.forEach((value,key)=>{if(configUrlInstance.searchParams.get(key)===null){configUrlInstance.searchParams.set(key,value);}});origin=configUrlInstance.origin;pathname=configUrlInstance.pathname;searchParams=configUrlInstance.searchParams;hash=configUrlInstance.hash;}catch(err){logger?.warn(INVALID_CONFIG_URL_WARNING(CONFIG_MANAGER,configUrl));}}return `${origin}${pathname}?${searchParams}${hash}`;};
|
2625
|
-
|
2626
|
-
/**
|
2627
|
-
* A function to filter enabled destinations and map to required properties only
|
2628
|
-
* @param destinations
|
2629
|
-
*
|
2630
|
-
* @returns Destination[]
|
2631
|
-
*/const filterEnabledDestination=destinations=>{const nativeDestinations=[];destinations.forEach(destination=>{if(destination.enabled&&!destination.deleted){nativeDestinations.push({id:destination.id,displayName:destination.destinationDefinition.displayName,config:destination.config,shouldApplyDeviceModeTransformation:destination.shouldApplyDeviceModeTransformation||false,propagateEventsUntransformedOnError:destination.propagateEventsUntransformedOnError||false,userFriendlyId:`${destination.destinationDefinition.displayName.replaceAll(' ','-')}___${destination.id}`});}});return nativeDestinations;};
|
2632
|
-
|
2633
2618
|
const DEFAULT_REGION='US';/**
|
2634
2619
|
* A function to get url from source config response
|
2635
2620
|
* @param {array} urls An array of objects containing urls
|
2636
2621
|
* @returns
|
2637
|
-
*/const getDefaultUrlOfRegion=urls=>{let url;if(Array.isArray(urls)&&urls.length>0){const obj=urls.find(elem=>elem.default===true);if(obj&&
|
2622
|
+
*/const getDefaultUrlOfRegion=urls=>{let url;if(Array.isArray(urls)&&urls.length>0){const obj=urls.find(elem=>elem.default===true);if(obj&&isValidURL(obj.url)){return obj.url;}}return url;};const validateResidencyServerRegion=(residencyServerRegion,logger)=>{const residencyServerRegions=['US','EU'];if(residencyServerRegion&&!residencyServerRegions.includes(residencyServerRegion)){logger?.warn(UNSUPPORTED_RESIDENCY_SERVER_REGION_WARNING(CONFIG_MANAGER,residencyServerRegion,DEFAULT_REGION));return undefined;}return residencyServerRegion;};/**
|
2638
2623
|
* A function to determine the dataPlaneUrl
|
2639
2624
|
* @param {Object} dataplanes An object containing dataPlaneUrl for different region
|
2640
2625
|
* @param {String} serverUrl dataPlaneUrl provided in the load call
|
@@ -2680,7 +2665,7 @@
|
|
2680
2665
|
enabled=enabled&&Boolean(consentManagerPluginName);return {provider,consentManagerPluginName,initialized,enabled,consentsData};};
|
2681
2666
|
|
2682
2667
|
/**
|
2683
|
-
* Determines the SDK
|
2668
|
+
* Determines the SDK URL
|
2684
2669
|
* @returns sdkURL
|
2685
2670
|
*/const getSDKUrl=()=>{const scripts=document.getElementsByTagName('script');const sdkFileNameRegex=/(?:^|\/)rsa(\.min)?\.js$/;// eslint-disable-next-line no-restricted-syntax
|
2686
2671
|
for(const script of scripts){const src=script.getAttribute('src');if(src&&sdkFileNameRegex.test(src)){return src;}}return undefined;};/**
|
@@ -2689,9 +2674,11 @@
|
|
2689
2674
|
* @param logger Logger instance
|
2690
2675
|
*/const updateReportingState=(res,logger)=>{state.reporting.isErrorReportingEnabled.value=isErrorReportingEnabled(res.source.config)&&!isSDKRunningInChromeExtension();state.reporting.isMetricsReportingEnabled.value=isMetricsReportingEnabled(res.source.config);if(state.reporting.isErrorReportingEnabled.value){const errReportingProvider=getErrorReportingProviderNameFromConfig(res.source.config);// Get the corresponding plugin name of the selected error reporting provider from the supported error reporting providers
|
2691
2676
|
const errReportingProviderPlugin=errReportingProvider?ErrorReportingProvidersToPluginNameMap[errReportingProvider]:undefined;if(!isUndefined(errReportingProvider)&&!errReportingProviderPlugin){// set the default error reporting provider
|
2692
|
-
logger?.warn(UNSUPPORTED_ERROR_REPORTING_PROVIDER_WARNING(CONFIG_MANAGER,errReportingProvider,ErrorReportingProvidersToPluginNameMap,DEFAULT_ERROR_REPORTING_PROVIDER));}state.reporting.errorReportingProviderPluginName.value=errReportingProviderPlugin??ErrorReportingProvidersToPluginNameMap[DEFAULT_ERROR_REPORTING_PROVIDER];}};const updateStorageStateFromLoadOptions=logger=>{const
|
2677
|
+
logger?.warn(UNSUPPORTED_ERROR_REPORTING_PROVIDER_WARNING(CONFIG_MANAGER,errReportingProvider,ErrorReportingProvidersToPluginNameMap,DEFAULT_ERROR_REPORTING_PROVIDER));}state.reporting.errorReportingProviderPluginName.value=errReportingProviderPlugin??ErrorReportingProvidersToPluginNameMap[DEFAULT_ERROR_REPORTING_PROVIDER];}};const updateStorageStateFromLoadOptions=logger=>{const{useServerSideCookies,dataServiceEndpoint,storage:storageOptsFromLoad}=state.loadOptions.value;let storageType=storageOptsFromLoad?.type;if(isDefined(storageType)&&!isValidStorageType(storageType)){logger?.warn(STORAGE_TYPE_VALIDATION_WARNING(CONFIG_MANAGER,storageType,DEFAULT_STORAGE_TYPE));storageType=DEFAULT_STORAGE_TYPE;}let storageEncryptionVersion=storageOptsFromLoad?.encryption?.version;const encryptionPluginName=storageEncryptionVersion&&StorageEncryptionVersionsToPluginNameMap[storageEncryptionVersion];if(!isUndefined(storageEncryptionVersion)&&isUndefined(encryptionPluginName)){// set the default encryption plugin
|
2693
2678
|
logger?.warn(UNSUPPORTED_STORAGE_ENCRYPTION_VERSION_WARNING(CONFIG_MANAGER,storageEncryptionVersion,StorageEncryptionVersionsToPluginNameMap,DEFAULT_STORAGE_ENCRYPTION_VERSION));storageEncryptionVersion=DEFAULT_STORAGE_ENCRYPTION_VERSION;}else if(isUndefined(storageEncryptionVersion)){storageEncryptionVersion=DEFAULT_STORAGE_ENCRYPTION_VERSION;}// Allow migration only if the configured encryption version is the default encryption version
|
2694
|
-
const configuredMigrationValue=storageOptsFromLoad?.migrate;const finalMigrationVal=configuredMigrationValue&&storageEncryptionVersion===DEFAULT_STORAGE_ENCRYPTION_VERSION;if(configuredMigrationValue===true&&finalMigrationVal!==configuredMigrationValue){logger?.warn(STORAGE_DATA_MIGRATION_OVERRIDE_WARNING(CONFIG_MANAGER,storageEncryptionVersion,DEFAULT_STORAGE_ENCRYPTION_VERSION));}r(()=>{state.storage.type.value=storageType;
|
2679
|
+
const configuredMigrationValue=storageOptsFromLoad?.migrate;const finalMigrationVal=configuredMigrationValue&&storageEncryptionVersion===DEFAULT_STORAGE_ENCRYPTION_VERSION;if(configuredMigrationValue===true&&finalMigrationVal!==configuredMigrationValue){logger?.warn(STORAGE_DATA_MIGRATION_OVERRIDE_WARNING(CONFIG_MANAGER,storageEncryptionVersion,DEFAULT_STORAGE_ENCRYPTION_VERSION));}r(()=>{state.storage.type.value=storageType;let cookieOptions=storageOptsFromLoad?.cookie??{};if(useServerSideCookies){state.serverCookies.isEnabledServerSideCookies.value=useServerSideCookies;const dataServiceUrl=getDataServiceUrl(dataServiceEndpoint??DEFAULT_DATA_SERVICE_ENDPOINT);if(isValidURL(dataServiceUrl)){state.serverCookies.dataServiceUrl.value=removeTrailingSlashes(dataServiceUrl);const curHost=getDomain(window.location.href);const dataServiceHost=getDomain(dataServiceUrl);// If the current host is different from the data service host, then it is a cross-site request
|
2680
|
+
// For server-side cookies to work, we need to set the SameSite=None and Secure attributes
|
2681
|
+
if(curHost!==dataServiceHost){cookieOptions={...cookieOptions,samesite:'None',secure:true};}}else {state.serverCookies.isEnabledServerSideCookies.value=false;}}state.storage.cookie.value=cookieOptions;state.storage.encryptionPluginName.value=StorageEncryptionVersionsToPluginNameMap[storageEncryptionVersion];state.storage.migrate.value=finalMigrationVal;});};const updateConsentsStateFromLoadOptions=logger=>{const{provider,consentManagerPluginName,initialized,enabled,consentsData}=getConsentManagementData(state.loadOptions.value.consentManagement,logger);// Pre-consent
|
2695
2682
|
const preConsentOpts=state.loadOptions.value.preConsent;let storageStrategy=preConsentOpts?.storage?.strategy??DEFAULT_PRE_CONSENT_STORAGE_STRATEGY;const StorageStrategies=['none','session','anonymousId'];if(isDefined(storageStrategy)&&!StorageStrategies.includes(storageStrategy)){storageStrategy=DEFAULT_PRE_CONSENT_STORAGE_STRATEGY;logger?.warn(UNSUPPORTED_PRE_CONSENT_STORAGE_STRATEGY(CONFIG_MANAGER,preConsentOpts?.storage?.strategy,DEFAULT_PRE_CONSENT_STORAGE_STRATEGY));}let eventsDeliveryType=preConsentOpts?.events?.delivery??DEFAULT_PRE_CONSENT_EVENTS_DELIVERY_TYPE;const deliveryTypes=['immediate','buffer'];if(isDefined(eventsDeliveryType)&&!deliveryTypes.includes(eventsDeliveryType)){eventsDeliveryType=DEFAULT_PRE_CONSENT_EVENTS_DELIVERY_TYPE;logger?.warn(UNSUPPORTED_PRE_CONSENT_EVENTS_DELIVERY_TYPE(CONFIG_MANAGER,preConsentOpts?.events?.delivery,DEFAULT_PRE_CONSENT_EVENTS_DELIVERY_TYPE));}r(()=>{state.consents.activeConsentManagerPluginName.value=consentManagerPluginName;state.consents.initialized.value=initialized;state.consents.enabled.value=enabled;state.consents.data.value=consentsData;state.consents.provider.value=provider;state.consents.preConsent.value={// Only enable pre-consent if it is explicitly enabled and
|
2696
2683
|
// if it is not already initialized and
|
2697
2684
|
// if consent management is enabled
|
@@ -2700,7 +2687,7 @@
|
|
2700
2687
|
* @param resp Source config response
|
2701
2688
|
* @param logger Logger instance
|
2702
2689
|
*/const updateConsentsState=resp=>{let resolutionStrategy=state.consents.resolutionStrategy.value;let cmpMetadata;if(isObjectLiteralAndNotNull(resp.consentManagementMetadata)){if(state.consents.provider.value){resolutionStrategy=resp.consentManagementMetadata.providers.find(p=>p.provider===state.consents.provider.value)?.resolutionStrategy??state.consents.resolutionStrategy.value;}cmpMetadata=resp.consentManagementMetadata;}// If the provider is custom, then the resolution strategy is not applicable
|
2703
|
-
if(state.consents.provider.value==='custom'){resolutionStrategy=undefined;}r(()=>{state.consents.metadata.value=clone(cmpMetadata);state.consents.resolutionStrategy.value=resolutionStrategy;});};const updateDataPlaneEventsStateFromLoadOptions=logger=>{if(state.dataPlaneEvents.deliveryEnabled.value){const defaultEventsQueuePluginName='XhrQueue';let eventsQueuePluginName=defaultEventsQueuePluginName;if(state.loadOptions.value.useBeacon){if(state.capabilities.isBeaconAvailable.value){eventsQueuePluginName='BeaconQueue';}else {eventsQueuePluginName=defaultEventsQueuePluginName;logger?.warn(UNSUPPORTED_BEACON_API_WARNING(CONFIG_MANAGER));}}r(()=>{state.dataPlaneEvents.eventsQueuePluginName.value=eventsQueuePluginName;});}};
|
2690
|
+
if(state.consents.provider.value==='custom'){resolutionStrategy=undefined;}r(()=>{state.consents.metadata.value=clone(cmpMetadata);state.consents.resolutionStrategy.value=resolutionStrategy;});};const updateDataPlaneEventsStateFromLoadOptions=logger=>{if(state.dataPlaneEvents.deliveryEnabled.value){const defaultEventsQueuePluginName='XhrQueue';let eventsQueuePluginName=defaultEventsQueuePluginName;if(state.loadOptions.value.useBeacon){if(state.capabilities.isBeaconAvailable.value){eventsQueuePluginName='BeaconQueue';}else {eventsQueuePluginName=defaultEventsQueuePluginName;logger?.warn(UNSUPPORTED_BEACON_API_WARNING(CONFIG_MANAGER));}}r(()=>{state.dataPlaneEvents.eventsQueuePluginName.value=eventsQueuePluginName;});}};const getSourceConfigURL=(configUrl,writeKey,lockIntegrationsVersion,logger)=>{const defSearchParams=new URLSearchParams({p:MODULE_TYPE,v:APP_VERSION,build:BUILD_TYPE,writeKey,lockIntegrationsVersion:lockIntegrationsVersion.toString()});let origin=DEFAULT_CONFIG_BE_URL;let searchParams=defSearchParams;let pathname='/sourceConfig/';let hash='';if(isValidURL(configUrl)){const configUrlInstance=new URL(configUrl);if(!removeTrailingSlashes(configUrlInstance.pathname).endsWith('/sourceConfig')){configUrlInstance.pathname=`${removeTrailingSlashes(configUrlInstance.pathname)}/sourceConfig/`;}configUrlInstance.pathname=removeDuplicateSlashes(configUrlInstance.pathname);defSearchParams.forEach((value,key)=>{if(configUrlInstance.searchParams.get(key)===null){configUrlInstance.searchParams.set(key,value);}});origin=configUrlInstance.origin;pathname=configUrlInstance.pathname;searchParams=configUrlInstance.searchParams;hash=configUrlInstance.hash;}else {logger?.warn(INVALID_CONFIG_URL_WARNING(CONFIG_MANAGER,configUrl));}return `${origin}${pathname}?${searchParams}${hash}`;};
|
2704
2691
|
|
2705
2692
|
/**
|
2706
2693
|
* A function that determines integration SDK loading path
|
@@ -2709,30 +2696,31 @@
|
|
2709
2696
|
* @param customIntegrationsCDNPath
|
2710
2697
|
* @returns
|
2711
2698
|
*/const getIntegrationsCDNPath=(requiredVersion,lockIntegrationsVersion,customIntegrationsCDNPath)=>{let integrationsCDNPath='';// Get the CDN base URL from the user provided URL if any
|
2712
|
-
if(customIntegrationsCDNPath){integrationsCDNPath=removeTrailingSlashes(customIntegrationsCDNPath);if(!integrationsCDNPath
|
2713
|
-
const sdkURL=getSDKUrl();integrationsCDNPath=sdkURL
|
2699
|
+
if(customIntegrationsCDNPath){integrationsCDNPath=removeTrailingSlashes(customIntegrationsCDNPath);if(!integrationsCDNPath||!isValidURL(integrationsCDNPath)){throw new Error(INTG_CDN_BASE_URL_ERROR);}return integrationsCDNPath;}// Get the base path from the SDK script tag src attribute or use the default path
|
2700
|
+
const sdkURL=getSDKUrl();integrationsCDNPath=sdkURL?sdkURL.split('/').slice(0,-1).concat(CDN_INT_DIR).join('/'):DEST_SDK_BASE_URL;// If version is not locked it will always get the latest version of the integrations
|
2714
2701
|
if(lockIntegrationsVersion){integrationsCDNPath=integrationsCDNPath.replace(CDN_ARCH_VERSION_DIR,requiredVersion);}return integrationsCDNPath;};/**
|
2715
2702
|
* A function that determines plugins SDK loading path
|
2716
2703
|
* @param customPluginsCDNPath
|
2717
2704
|
* @returns
|
2718
2705
|
*/const getPluginsCDNPath=customPluginsCDNPath=>{let pluginsCDNPath='';// Get the CDN base URL from the user provided URL if any
|
2719
|
-
if(customPluginsCDNPath){pluginsCDNPath=removeTrailingSlashes(customPluginsCDNPath);if(!pluginsCDNPath
|
2720
|
-
const sdkURL=getSDKUrl();pluginsCDNPath=sdkURL
|
2706
|
+
if(customPluginsCDNPath){pluginsCDNPath=removeTrailingSlashes(customPluginsCDNPath);if(!pluginsCDNPath||!isValidURL(pluginsCDNPath)){throw new Error(PLUGINS_CDN_BASE_URL_ERROR);}return pluginsCDNPath;}// Get the base path from the SDK script tag src attribute or use the default path
|
2707
|
+
const sdkURL=getSDKUrl();pluginsCDNPath=sdkURL?sdkURL.split('/').slice(0,-1).concat(CDN_PLUGINS_DIR).join('/'):PLUGINS_BASE_URL;return pluginsCDNPath;};
|
2721
2708
|
|
2722
2709
|
class ConfigManager{hasErrorHandler=false;constructor(httpClient,errorHandler,logger){this.errorHandler=errorHandler;this.logger=logger;this.httpClient=httpClient;this.hasErrorHandler=Boolean(this.errorHandler);this.onError=this.onError.bind(this);this.processConfig=this.processConfig.bind(this);}attachEffects(){E(()=>{this.logger?.setMinLogLevel(state.lifecycle.logLevel.value);});}/**
|
2723
2710
|
* A function to validate, construct and store loadOption, lifecycle, source and destination
|
2724
2711
|
* config related information in global state
|
2725
2712
|
*/init(){this.attachEffects();validateLoadArgs(state.lifecycle.writeKey.value,state.lifecycle.dataPlaneUrl.value);const lockIntegrationsVersion=state.loadOptions.value.lockIntegrationsVersion;// determine the path to fetch integration SDK from
|
2726
2713
|
const intgCdnUrl=getIntegrationsCDNPath(APP_VERSION,lockIntegrationsVersion,state.loadOptions.value.destSDKBaseURL);// determine the path to fetch remote plugins from
|
2727
|
-
const pluginsCDNPath=getPluginsCDNPath(state.loadOptions.value.pluginsSDKBaseURL);updateStorageStateFromLoadOptions(this.logger);updateConsentsStateFromLoadOptions(this.logger);updateDataPlaneEventsStateFromLoadOptions(this.logger);const{
|
2728
|
-
r(()=>{state.lifecycle.integrationsCDNPath.value=intgCdnUrl;state.lifecycle.pluginsCDNPath.value=pluginsCDNPath;if(logLevel){state.lifecycle.logLevel.value=logLevel;}state.lifecycle.sourceConfigUrl.value=getSourceConfigURL(configUrl,state.lifecycle.writeKey.value,lockIntegrationsVersion,this.logger);
|
2714
|
+
const pluginsCDNPath=getPluginsCDNPath(state.loadOptions.value.pluginsSDKBaseURL);updateStorageStateFromLoadOptions(this.logger);updateConsentsStateFromLoadOptions(this.logger);updateDataPlaneEventsStateFromLoadOptions(this.logger);const{logLevel,configUrl}=state.loadOptions.value;// set application lifecycle state in global state
|
2715
|
+
r(()=>{state.lifecycle.integrationsCDNPath.value=intgCdnUrl;state.lifecycle.pluginsCDNPath.value=pluginsCDNPath;if(logLevel){state.lifecycle.logLevel.value=logLevel;}state.lifecycle.sourceConfigUrl.value=getSourceConfigURL(configUrl,state.lifecycle.writeKey.value,lockIntegrationsVersion,this.logger);});this.getConfig();}/**
|
2729
2716
|
* Handle errors
|
2730
2717
|
*/onError(error,customMessage,shouldAlwaysThrow){if(this.hasErrorHandler){this.errorHandler?.onError(error,CONFIG_MANAGER,customMessage,shouldAlwaysThrow);}else {throw error;}}/**
|
2731
2718
|
* A callback function that is executed once we fetch the source config response.
|
2732
2719
|
* Use to construct and store information that are dependent on the sourceConfig.
|
2733
2720
|
*/processConfig(response,details){// TODO: add retry logic with backoff based on rejectionDetails.xhr.status
|
2734
2721
|
// We can use isErrRetryable utility method
|
2735
|
-
if(!response){this.onError(SOURCE_CONFIG_FETCH_ERROR(details?.error));return;}let res;try{if(isString(response)){res=JSON.parse(response);}else {res=response;}}catch(err){this.onError(err,SOURCE_CONFIG_RESOLUTION_ERROR,true);return;}if(!isValidSourceConfig(res)){this.onError(new Error(SOURCE_CONFIG_RESOLUTION_ERROR),undefined,true);return;}//
|
2722
|
+
if(!response){this.onError(SOURCE_CONFIG_FETCH_ERROR(details?.error));return;}let res;try{if(isString(response)){res=JSON.parse(response);}else {res=response;}}catch(err){this.onError(err,SOURCE_CONFIG_RESOLUTION_ERROR,true);return;}if(!isValidSourceConfig(res)){this.onError(new Error(SOURCE_CONFIG_RESOLUTION_ERROR),undefined,true);return;}// Log error and abort if source is disabled
|
2723
|
+
if(res.source.enabled===false){this.logger?.error(SOURCE_DISABLED_ERROR);return;}// set the values in state for reporting slice
|
2736
2724
|
updateReportingState(res,this.logger);// determine the dataPlane url
|
2737
2725
|
const dataPlaneUrl=resolveDataPlaneUrl(res.source.dataplanes,state.lifecycle.dataPlaneUrl.value,state.loadOptions.value.residencyServer,this.logger);if(!dataPlaneUrl){this.onError(new Error(DATA_PLANE_URL_ERROR),undefined,true);return;}const nativeDestinations=res.source.destinations.length>0?filterEnabledDestination(res.source.destinations):[];// set in the state --> source, destination, lifecycle, reporting
|
2738
2726
|
r(()=>{// set source related information in state
|
@@ -2744,8 +2732,8 @@
|
|
2744
2732
|
* A function to fetch source config either from /sourceConfig endpoint
|
2745
2733
|
* or from getSourceConfig load option
|
2746
2734
|
* @returns
|
2747
|
-
*/getConfig(){const sourceConfigFunc=state.loadOptions.value.getSourceConfig;if(sourceConfigFunc){if(!isFunction(sourceConfigFunc)){throw new Error(SOURCE_CONFIG_OPTION_ERROR);}//
|
2748
|
-
const res=sourceConfigFunc();if(res instanceof Promise){res.then(pRes=>this.processConfig(pRes)).catch(err=>{this.onError(err,'SourceConfig');});}else {this.processConfig(res);}}else {//
|
2735
|
+
*/getConfig(){const sourceConfigFunc=state.loadOptions.value.getSourceConfig;if(sourceConfigFunc){if(!isFunction(sourceConfigFunc)){throw new Error(SOURCE_CONFIG_OPTION_ERROR);}// Fetch source config from the function
|
2736
|
+
const res=sourceConfigFunc();if(res instanceof Promise){res.then(pRes=>this.processConfig(pRes)).catch(err=>{this.onError(err,'SourceConfig');});}else {this.processConfig(res);}}else {// Fetch source configuration from the configured URL
|
2749
2737
|
this.httpClient.getAsyncData({url:state.lifecycle.sourceConfigUrl.value,options:{headers:{'Content-Type':undefined}},callback:this.processConfig});}}}
|
2750
2738
|
|
2751
2739
|
/**
|
@@ -2767,8 +2755,8 @@
|
|
2767
2755
|
const matchedArr=userAgent.match(/(chrome)\/([\w.]+)/i);if(matchedArr){userAgent=`${userAgent} Brave/${matchedArr[2]}`;}}return userAgent;};const getLanguage=()=>{if(isUndefined(globalThis.navigator)){return null;}return globalThis.navigator.language??globalThis.navigator.browserLanguage;};/**
|
2768
2756
|
* Default page properties
|
2769
2757
|
* @returns Default page properties
|
2770
|
-
*/const getDefaultPageProperties=()=>{const canonicalUrl=getCanonicalUrl();let path=globalThis.location.pathname;const{href:tabUrl}=globalThis.location;let pageUrl=tabUrl;const{search}=globalThis.location;// If valid canonical
|
2771
|
-
if(canonicalUrl){try{const urlObj=new URL(canonicalUrl);// If existing, query params of canonical
|
2758
|
+
*/const getDefaultPageProperties=()=>{const canonicalUrl=getCanonicalUrl();let path=globalThis.location.pathname;const{href:tabUrl}=globalThis.location;let pageUrl=tabUrl;const{search}=globalThis.location;// If valid canonical URL is provided use this as page URL.
|
2759
|
+
if(canonicalUrl){try{const urlObj=new URL(canonicalUrl);// If existing, query params of canonical URL will be used instead of the location.search ones
|
2772
2760
|
if(urlObj.search===''){pageUrl=canonicalUrl+search;}else {pageUrl=canonicalUrl;}path=urlObj.pathname;}catch(err){// Do nothing
|
2773
2761
|
}}const url=getUrlWithoutHash(pageUrl);const{title}=document;const referrer=getReferrer();return {path,referrer,referring_domain:getReferringDomain(referrer),search,title,url,tab_url:tabUrl};};
|
2774
2762
|
|
@@ -2784,10 +2772,10 @@
|
|
2784
2772
|
state.context.userAgent.value=getUserAgent();state.context.locale.value=getLanguage();state.context.screen.value=getScreenDetails();state.context.timezone.value=getTimezone();if(hasUAClientHints()){getUserAgentClientHint(uach=>{state.context['ua-ch'].value=uach;},state.loadOptions.value.uaChTrackLevel);}});// Ad blocker detection
|
2785
2773
|
E(()=>{if(state.loadOptions.value.sendAdblockPage===true&&state.lifecycle.sourceConfigUrl.value!==undefined){detectAdBlockers(this.errorHandler,this.logger);}});}/**
|
2786
2774
|
* Detect if polyfills are required and then load script from polyfill URL
|
2787
|
-
*/prepareBrowserCapabilities(){state.capabilities.isLegacyDOM.value=isLegacyJSEngine();
|
2775
|
+
*/prepareBrowserCapabilities(){state.capabilities.isLegacyDOM.value=isLegacyJSEngine();const customPolyfillUrl=state.loadOptions.value.polyfillURL;let polyfillUrl=POLYFILL_URL;if(isDefinedAndNotNull(customPolyfillUrl)){if(isValidURL(customPolyfillUrl)){polyfillUrl=customPolyfillUrl;}else {this.logger?.warn(INVALID_POLYFILL_URL_WARNING(CAPABILITIES_MANAGER,customPolyfillUrl));}}const shouldLoadPolyfill=state.loadOptions.value.polyfillIfRequired&&state.capabilities.isLegacyDOM.value&&isValidURL(polyfillUrl);if(shouldLoadPolyfill){const isDefaultPolyfillService=polyfillUrl!==state.loadOptions.value.polyfillURL;if(isDefaultPolyfillService){// write key specific callback
|
2788
2776
|
// NOTE: we're not putting this into RudderStackGlobals as providing the property path to the callback function in the polyfill URL is not possible
|
2789
2777
|
const polyfillCallbackName=`RS_polyfillCallback_${state.lifecycle.writeKey.value}`;const polyfillCallback=()=>{this.onReady();// Remove the entry from window so we don't leave room for calling it again
|
2790
|
-
delete globalThis[polyfillCallbackName];};globalThis[polyfillCallbackName]=polyfillCallback;polyfillUrl=`${polyfillUrl}&callback=${polyfillCallbackName}`;}this.externalSrcLoader
|
2778
|
+
delete globalThis[polyfillCallbackName];};globalThis[polyfillCallbackName]=polyfillCallback;polyfillUrl=`${polyfillUrl}&callback=${polyfillCallbackName}`;}this.externalSrcLoader.loadJSFile({url:polyfillUrl,id:POLYFILL_SCRIPT_ID,async:true,timeout:POLYFILL_LOAD_TIMEOUT,callback:scriptId=>{if(!scriptId){this.onError(new Error(POLYFILL_SCRIPT_LOAD_ERROR(POLYFILL_SCRIPT_ID,polyfillUrl)));}else if(!isDefaultPolyfillService){this.onReady();}}});}else {this.onReady();}}/**
|
2791
2779
|
* Attach listeners to window to observe event that update capabilities state values
|
2792
2780
|
*/attachWindowListeners(){globalThis.addEventListener('offline',()=>{state.capabilities.isOnline.value=false;});globalThis.addEventListener('online',()=>{state.capabilities.isOnline.value=true;});globalThis.addEventListener('resize',debounce(()=>{state.context.screen.value=getScreenDetails();},this));}/**
|
2793
2781
|
* Set the lifecycle status to next phase
|
@@ -2803,6 +2791,21 @@
|
|
2803
2791
|
const CONTEXT_RESERVED_ELEMENTS=['library','consentManagement','userAgent','ua-ch','screen'];// Reserved elements in the standard RudderStack event spec
|
2804
2792
|
const RESERVED_ELEMENTS=['id','anonymous_id','user_id','sent_at','timestamp','received_at','original_timestamp','event','event_text','channel','context_ip','context_request_ip','context_passed_ip','group_id','previous_id'];
|
2805
2793
|
|
2794
|
+
/**
|
2795
|
+
* A function to check given value is a number or not
|
2796
|
+
* @param num input value
|
2797
|
+
* @returns boolean
|
2798
|
+
*/const isNumber=num=>typeof num==='number'&&!Number.isNaN(num);/**
|
2799
|
+
* A function to check given number has minimum length or not
|
2800
|
+
* @param minimumLength minimum length
|
2801
|
+
* @param num input number
|
2802
|
+
* @returns boolean
|
2803
|
+
*/const hasMinLength=(minimumLength,num)=>num.toString().length>=minimumLength;/**
|
2804
|
+
* A function to check given value is a positive integer or not
|
2805
|
+
* @param num input value
|
2806
|
+
* @returns boolean
|
2807
|
+
*/const isPositiveInteger=num=>isNumber(num)&&num>=0&&Number.isInteger(num);
|
2808
|
+
|
2806
2809
|
const MIN_SESSION_ID_LENGTH=10;/**
|
2807
2810
|
* A function to validate current session and return true/false depending on that
|
2808
2811
|
* @returns boolean
|
@@ -2834,12 +2837,12 @@
|
|
2834
2837
|
* To get the page properties for context object
|
2835
2838
|
* @param pageProps Page properties
|
2836
2839
|
* @returns page properties object for context
|
2837
|
-
*/const getContextPageProperties=pageProps=>{// Need to get updated page details on each event as an event to notify on SPA
|
2840
|
+
*/const getContextPageProperties=pageProps=>{// Need to get updated page details on each event as an event to notify on SPA URL changes does not seem to exist
|
2838
2841
|
const curPageProps=getDefaultPageProperties();const ctxPageProps={};Object.keys(curPageProps).forEach(key=>{ctxPageProps[key]=pageProps?.[key]||curPageProps[key];});ctxPageProps.initial_referrer=pageProps?.initial_referrer||state.session.initialReferrer.value;ctxPageProps.initial_referring_domain=pageProps?.initial_referring_domain||state.session.initialReferringDomain.value;return ctxPageProps;};/**
|
2839
2842
|
* Add any missing default page properties using values from options and defaults
|
2840
2843
|
* @param properties Input page properties
|
2841
2844
|
* @param options API options
|
2842
|
-
*/const getUpdatedPageProperties=(properties,options)=>{const optionsPageProps=options?.page||{};const pageProps=properties;// Need to get updated page details on each event as an event to notify on SPA
|
2845
|
+
*/const getUpdatedPageProperties=(properties,options)=>{const optionsPageProps=options?.page||{};const pageProps=properties;// Need to get updated page details on each event as an event to notify on SPA URL changes does not seem to exist
|
2843
2846
|
const curPageProps=getDefaultPageProperties();Object.keys(curPageProps).forEach(key=>{if(isUndefined(pageProps[key])){pageProps[key]=optionsPageProps[key]||curPageProps[key];}});if(isUndefined(pageProps.initial_referrer)){pageProps.initial_referrer=optionsPageProps.initial_referrer||state.session.initialReferrer.value;}if(isUndefined(pageProps.initial_referring_domain)){pageProps.initial_referring_domain=optionsPageProps.initial_referring_domain||state.session.initialReferringDomain.value;}return pageProps;};/**
|
2844
2847
|
* Utility to check for reserved keys in the input object
|
2845
2848
|
* @param obj Generic object
|
@@ -2961,26 +2964,23 @@
|
|
2961
2964
|
* @param cookieData
|
2962
2965
|
* @param store
|
2963
2966
|
* @returns
|
2964
|
-
*/getEncryptedCookieData(cookieData,store){const encryptedCookieData=[];cookieData.forEach(e=>{const encryptedValue=
|
2967
|
+
*/getEncryptedCookieData(cookieData,store){const encryptedCookieData=[];cookieData.forEach(e=>{const encryptedValue=store?.encrypt(stringifyWithoutCircular(e.value,false,[],this.logger));if(isDefinedAndNotNull(encryptedValue)){encryptedCookieData.push({name:e.name,value:encryptedValue});}});return encryptedCookieData;}/**
|
2965
2968
|
* A function that makes request to data service to set the cookie
|
2966
2969
|
* @param encryptedCookieData
|
2967
2970
|
* @param callback
|
2968
|
-
*/makeRequestToSetCookie(encryptedCookieData,callback){this.httpClient?.getAsyncData({url:state.serverCookies.dataServiceUrl.value,options:{method:'POST',data:stringifyWithoutCircular({reqType:'setCookies',workspaceId:state.source.value?.workspaceId,data:{options:{maxAge:state.storage.cookie.value?.maxage,path:state.storage.cookie.value?.path,domain:state.storage.cookie.value?.domain,sameSite:state.storage.cookie.value?.samesite,secure:state.storage.cookie.value?.secure,expires:state.storage.cookie.value?.expires},cookies:encryptedCookieData}}),sendRawData:true},isRawResponse:true,callback});}/**
|
2971
|
+
*/makeRequestToSetCookie(encryptedCookieData,callback){this.httpClient?.getAsyncData({url:state.serverCookies.dataServiceUrl.value,options:{method:'POST',data:stringifyWithoutCircular({reqType:'setCookies',workspaceId:state.source.value?.workspaceId,data:{options:{maxAge:state.storage.cookie.value?.maxage,path:state.storage.cookie.value?.path,domain:state.storage.cookie.value?.domain,sameSite:state.storage.cookie.value?.samesite,secure:state.storage.cookie.value?.secure,expires:state.storage.cookie.value?.expires},cookies:encryptedCookieData}}),sendRawData:true,withCredentials:true},isRawResponse:true,callback});}/**
|
2969
2972
|
* A function to make an external request to set the cookie from server side
|
2970
2973
|
* @param key cookie name
|
2971
2974
|
* @param value encrypted cookie value
|
2972
2975
|
*/setServerSideCookie(cookieData,cb,store){try{// encrypt cookies values
|
2973
2976
|
const encryptedCookieData=this.getEncryptedCookieData(cookieData,store);if(encryptedCookieData.length>0){// make request to data service to set the cookie from server side
|
2974
|
-
this.makeRequestToSetCookie(encryptedCookieData,(res,details)=>{if(details?.xhr?.status===200){cookieData.forEach(each=>{const cookieValue=store?.get(each.name);
|
2977
|
+
this.makeRequestToSetCookie(encryptedCookieData,(res,details)=>{if(details?.xhr?.status===200){cookieData.forEach(each=>{const cookieValue=store?.get(each.name);const before=stringifyWithoutCircular(each.value,false,[]);const after=stringifyWithoutCircular(cookieValue,false,[]);if(after!==before){this.logger?.debug('Cookie value sent to server side',before);this.logger?.debug('Cookie value set from server side',after);this.logger?.error(FAILED_SETTING_COOKIE_FROM_SERVER_ERROR(each.name));if(cb){cb(each.name,each.value);}}});}else {this.logger?.error(DATA_SERVER_REQUEST_FAIL_ERROR(details?.xhr?.status));cookieData.forEach(each=>{if(cb){cb(each.name,each.value);}});}});}}catch(e){this.onError(e,FAILED_SETTING_COOKIE_FROM_SERVER_GLOBAL_ERROR);cookieData.forEach(each=>{if(cb){cb(each.name,each.value);}});}}/**
|
2975
2978
|
* A function to sync values in storage
|
2976
2979
|
* @param sessionKey
|
2977
2980
|
* @param value
|
2978
2981
|
*/syncValueToStorage(sessionKey,value){const entries=state.storage.entries.value;const storageType=entries[sessionKey]?.type;if(isStorageTypeValidForStoringData(storageType)){const curStore=this.storeManager?.getStore(storageClientDataStoreNameMap[storageType]);const key=entries[sessionKey]?.key;if(value&&(isString(value)||isNonEmptyObject(value))){// if useServerSideCookies load option is set to true
|
2979
2982
|
// set the cookie from server side
|
2980
|
-
if(state.serverCookies.isEnabledServerSideCookies.value&&storageType===COOKIE_STORAGE){this.setServerSideCookie([{name:key,value}],(cookieName,cookieValue)=>{curStore?.set(cookieName,cookieValue);},curStore);}else {curStore?.set(key,value);}}else
|
2981
|
-
// TODO: Test cookies set from server side can be cleared from client side
|
2982
|
-
// and make appropriate changes.
|
2983
|
-
this.setServerSideCookie([{name:key,value:''}],undefined,curStore);}else {curStore?.remove(key);}}}/**
|
2983
|
+
if(state.serverCookies.isEnabledServerSideCookies.value&&storageType===COOKIE_STORAGE){this.setServerSideCookie([{name:key,value}],(cookieName,cookieValue)=>{curStore?.set(cookieName,cookieValue);},curStore);}else {curStore?.set(key,value);}}else {curStore?.remove(key);}}}/**
|
2984
2984
|
* Function to update storage whenever state value changes
|
2985
2985
|
*/registerEffects(){// This will work as long as the user session entry key names are same as the state keys
|
2986
2986
|
USER_SESSION_KEYS.forEach(sessionKey=>{E(()=>{this.syncValueToStorage(sessionKey,state.session[sessionKey].value);});});}/**
|
@@ -3076,6 +3076,13 @@
|
|
3076
3076
|
* @param userId
|
3077
3077
|
*/setAuthToken(token){state.session.authToken.value=this.isPersistenceEnabledForStorageEntry('authToken')&&token?token:DEFAULT_USER_SESSION_VALUES.authToken;}}
|
3078
3078
|
|
3079
|
+
/**
|
3080
|
+
* Plugins to be loaded in the plugins loadOption is not defined
|
3081
|
+
*/const defaultOptionalPluginsList=['BeaconQueue','Bugsnag','CustomConsentManager','DeviceModeDestinations','DeviceModeTransformation','ErrorReporting','ExternalAnonymousId','GoogleLinker','KetchConsentManager','NativeDestinationQueue','OneTrustConsentManager','StorageEncryption','StorageEncryptionLegacy','StorageMigrator','XhrQueue'];
|
3082
|
+
|
3083
|
+
const normalizeLoadOptions=(loadOptionsFromState,loadOptions)=>{// TODO: Maybe add warnings for invalid values
|
3084
|
+
const normalizedLoadOpts=clone(loadOptions);if(!isString(normalizedLoadOpts.setCookieDomain)){delete normalizedLoadOpts.setCookieDomain;}const cookieSameSiteValues=['Strict','Lax','None'];if(!cookieSameSiteValues.includes(normalizedLoadOpts.sameSiteCookie)){delete normalizedLoadOpts.sameSiteCookie;}normalizedLoadOpts.secureCookie=normalizedLoadOpts.secureCookie===true;const uaChTrackLevels=['none','default','full'];if(!uaChTrackLevels.includes(normalizedLoadOpts.uaChTrackLevel)){delete normalizedLoadOpts.uaChTrackLevel;}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.integrations)){delete normalizedLoadOpts.integrations;}normalizedLoadOpts.plugins=normalizedLoadOpts.plugins??defaultOptionalPluginsList;normalizedLoadOpts.useGlobalIntegrationsConfigInEvents=normalizedLoadOpts.useGlobalIntegrationsConfigInEvents===true;normalizedLoadOpts.bufferDataPlaneEventsUntilReady=normalizedLoadOpts.bufferDataPlaneEventsUntilReady===true;normalizedLoadOpts.sendAdblockPage=normalizedLoadOpts.sendAdblockPage===true;normalizedLoadOpts.useServerSideCookies=normalizedLoadOpts.useServerSideCookies===true;if(normalizedLoadOpts.dataServiceEndpoint&&typeof normalizedLoadOpts.dataServiceEndpoint!=='string'){delete normalizedLoadOpts.dataServiceEndpoint;}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.sendAdblockPageOptions)){delete normalizedLoadOpts.sendAdblockPageOptions;}if(!isDefined(normalizedLoadOpts.loadIntegration)){delete normalizedLoadOpts.loadIntegration;}else {normalizedLoadOpts.loadIntegration=normalizedLoadOpts.loadIntegration===true;}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.storage)){delete normalizedLoadOpts.storage;}else {normalizedLoadOpts.storage=removeUndefinedAndNullValues(normalizedLoadOpts.storage);normalizedLoadOpts.storage.migrate=normalizedLoadOpts.storage?.migrate===true;}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.beaconQueueOptions)){delete normalizedLoadOpts.beaconQueueOptions;}else {normalizedLoadOpts.beaconQueueOptions=removeUndefinedAndNullValues(normalizedLoadOpts.beaconQueueOptions);}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.destinationsQueueOptions)){delete normalizedLoadOpts.destinationsQueueOptions;}else {normalizedLoadOpts.destinationsQueueOptions=removeUndefinedAndNullValues(normalizedLoadOpts.destinationsQueueOptions);}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.queueOptions)){delete normalizedLoadOpts.queueOptions;}else {normalizedLoadOpts.queueOptions=removeUndefinedAndNullValues(normalizedLoadOpts.queueOptions);}normalizedLoadOpts.lockIntegrationsVersion=normalizedLoadOpts.lockIntegrationsVersion===true;if(!isNumber(normalizedLoadOpts.dataPlaneEventsBufferTimeout)){delete normalizedLoadOpts.dataPlaneEventsBufferTimeout;}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.storage?.cookie)){delete normalizedLoadOpts.storage?.cookie;}else {normalizedLoadOpts.storage.cookie=removeUndefinedAndNullValues(normalizedLoadOpts.storage?.cookie);}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.preConsent)){delete normalizedLoadOpts.preConsent;}else {normalizedLoadOpts.preConsent=removeUndefinedAndNullValues(normalizedLoadOpts.preConsent);}const mergedLoadOptions=mergeDeepRight(loadOptionsFromState,normalizedLoadOpts);return mergedLoadOptions;};
|
3085
|
+
|
3079
3086
|
const DATA_PLANE_QUEUE_EXT_POINT_PREFIX='dataplaneEventsQueue';const DESTINATIONS_QUEUE_EXT_POINT_PREFIX='destinationsEventsQueue';const DMT_EXT_POINT_PREFIX='transformEvent';
|
3080
3087
|
|
3081
3088
|
/**
|