@rudderstack/analytics-js 3.11.12 → 3.11.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -341,54 +341,10 @@ const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value
341
341
  * @returns decoded string
342
342
  */const fromBase64=value=>new TextDecoder().decode(base64ToBytes(value));
343
343
 
344
- const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
345
-
346
- const JSON_STRINGIFY='JSONStringify';const BIG_INT_PLACEHOLDER='[BigInt]';const CIRCULAR_REFERENCE_PLACEHOLDER='[Circular Reference]';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
347
- // eslint-disable-next-line func-names
348
- return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
349
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
350
- // @ts-ignore-next-line
351
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return CIRCULAR_REFERENCE_PLACEHOLDER;}ancestors.push(value);return value;};};/**
352
- * Utility method for JSON stringify object excluding null values & circular references
353
- *
354
- * @param {*} value input
355
- * @param {boolean} excludeNull if it should exclude nul or not
356
- * @param {function} logger optional logger methods for warning
357
- * @returns string
358
- */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};/**
359
- * Utility method for JSON stringify object excluding null values & circular references
360
- *
361
- * @param {*} value input value
362
- * @param {boolean} excludeNull optional flag to exclude null values
363
- * @param {string[]} excludeKeys optional array of keys to exclude
364
- * @returns string
365
- */const stringifyData=(value,excludeNull=true,excludeKeys=[])=>JSON.stringify(value,(key,value)=>{if(excludeNull&&isNull(value)||excludeKeys.includes(key)){return undefined;}return value;});const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
366
- // Using a regular function to use `this` for the parent context
367
- return function replacer(key,value){if(isBigInt(value)){return BIG_INT_PLACEHOLDER;// Replace BigInt values
368
- }// `this` is the object that value is contained in, i.e., its direct parent.
369
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
370
- // @ts-ignore-next-line
371
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
372
- }// Check for circular references (if the value is already in the ancestors)
373
- if(ancestors.includes(value)){return CIRCULAR_REFERENCE_PLACEHOLDER;}// Add current value to ancestors
374
- ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
375
- const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
376
- // eslint-disable-next-line no-restricted-syntax
377
- for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
378
- const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
379
- if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
380
- * Recursively traverses an object similar to JSON.stringify,
381
- * sanitizing BigInts and circular references
382
- * @param value Input object
383
- * @param logger Logger instance
384
- * @returns Sanitized value
385
- */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
386
- const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};const tempUtil=()=>{stringifyData();};
387
-
388
344
  // if yes make them null instead of omitting in overloaded cases
389
345
  /*
390
346
  * Normalise the overloaded arguments of the page call facade
391
- */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{tempUtil();const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
347
+ */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
392
348
  // use it as name and set category to undefined
393
349
  if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
394
350
  // and set some proper defaults
@@ -463,6 +419,43 @@ const getFormattedTimestamp=date=>date.toISOString();/**
463
419
  * @returns ISO formatted timestamp string
464
420
  */const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
465
421
 
422
+ const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
423
+
424
+ const JSON_STRINGIFY='JSONStringify';const BIG_INT_PLACEHOLDER='[BigInt]';const CIRCULAR_REFERENCE_PLACEHOLDER='[Circular Reference]';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
425
+ // eslint-disable-next-line func-names
426
+ return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
427
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
428
+ // @ts-ignore-next-line
429
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return CIRCULAR_REFERENCE_PLACEHOLDER;}ancestors.push(value);return value;};};/**
430
+ * Utility method for JSON stringify object excluding null values & circular references
431
+ *
432
+ * @param {*} value input
433
+ * @param {boolean} excludeNull if it should exclude nul or not
434
+ * @param {function} logger optional logger methods for warning
435
+ * @returns string
436
+ */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
437
+ // Using a regular function to use `this` for the parent context
438
+ return function replacer(key,value){if(isBigInt(value)){return BIG_INT_PLACEHOLDER;// Replace BigInt values
439
+ }// `this` is the object that value is contained in, i.e., its direct parent.
440
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
441
+ // @ts-ignore-next-line
442
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
443
+ }// Check for circular references (if the value is already in the ancestors)
444
+ if(ancestors.includes(value)){return CIRCULAR_REFERENCE_PLACEHOLDER;}// Add current value to ancestors
445
+ ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
446
+ const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
447
+ // eslint-disable-next-line no-restricted-syntax
448
+ for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
449
+ const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
450
+ if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
451
+ * Recursively traverses an object similar to JSON.stringify,
452
+ * sanitizing BigInts and circular references
453
+ * @param value Input object
454
+ * @param logger Logger instance
455
+ * @returns Sanitized value
456
+ */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
457
+ const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
458
+
466
459
  const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
467
460
  * Get mutated error with issue prepended to error message
468
461
  * @param err Original error
@@ -470,7 +463,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
470
463
  * @returns Instance of Error with message prepended with issue
471
464
  */const getMutatedError=(err,issue)=>{let finalError=err;if(!isTypeOfError(err)){finalError=new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}else {finalError.message=`${issue}: ${err.message}`;}return finalError;};const dispatchErrorEvent=error=>{if(isTypeOfError(error)){error.stack=`${error.stack??''}\n${MANUAL_ERROR_IDENTIFIER}`;}globalThis.dispatchEvent(new ErrorEvent('error',{error}));};
472
465
 
473
- const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.12';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';
466
+ const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.14';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';
474
467
 
475
468
  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';
476
469
 
@@ -3411,13 +3404,11 @@ if(isString(writeKey)&&writeKey){this.defaultAnalyticsKey=writeKey;}}/**
3411
3404
  * @param dataPlaneUrl Data plane URL
3412
3405
  * @param loadOptions Additional options for loading the SDK
3413
3406
  * @returns none
3414
- */load(writeKey,dataPlaneUrl,loadOptions){try{if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);const preloadedEventsArray=this.getPreloadedEvents();// Track page loaded lifecycle event if enabled
3407
+ */load(writeKey,dataPlaneUrl,loadOptions){try{if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);// Get the preloaded events array from global buffer instead of window.rudderanalytics
3408
+ // as the constructor must have already pushed the events to the global buffer
3409
+ const preloadedEventsArray=getExposedGlobal(GLOBAL_PRELOAD_BUFFER);// Track page loaded lifecycle event if enabled
3415
3410
  this.trackPageLifecycleEvents(preloadedEventsArray,loadOptions);// The array will be mutated in the below method
3416
3411
  promotePreloadedConsentEventsToTop(preloadedEventsArray);setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone(preloadedEventsArray));this.analyticsInstances[writeKey]=new Analytics();this.getAnalyticsInstance(writeKey)?.load(writeKey,dataPlaneUrl,getSanitizedValue(loadOptions));}catch(error){dispatchErrorEvent(error);}}/**
3417
- * A function to get preloaded events array from global object
3418
- * @returns preloaded events array
3419
- */// eslint-disable-next-line class-methods-use-this
3420
- getPreloadedEvents(){return Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];}/**
3421
3412
  * A function to track page lifecycle events like page loaded and page unloaded
3422
3413
  * @param preloadedEventsArray
3423
3414
  * @param loadOptions
@@ -3440,11 +3431,11 @@ trackPageLoadedEvent(events,options,preloadedEventsArray){if(events.length===0||
3440
3431
  this.logger.warn(PAGE_UNLOAD_ON_BEACON_DISABLED_WARNING(RSA));}}}/**
3441
3432
  * Trigger load event in buffer queue if exists and stores the
3442
3433
  * remaining preloaded events array in global object
3443
- */triggerBufferedLoadEvent(){const preloadedEventsArray=this.getPreloadedEvents();// Get any load method call that is buffered if any
3434
+ */triggerBufferedLoadEvent(){const preloadedEventsArray=Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];// Get any load method call that is buffered if any
3444
3435
  // BTW, load method is also removed from the array
3445
3436
  // So, the Analytics object can directly consume the remaining events
3446
3437
  const loadEvent=getPreloadedLoadEvent(preloadedEventsArray);// Set the final preloaded events array in global object
3447
- setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone(preloadedEventsArray));// Process load method if present in the buffered requests
3438
+ setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone([...preloadedEventsArray]));// Process load method if present in the buffered requests
3448
3439
  if(loadEvent.length>0){// Remove the event name from the Buffered Event array and keep only arguments
3449
3440
  loadEvent.shift();// eslint-disable-next-line @typescript-eslint/ban-ts-comment
3450
3441
  // @ts-ignore
@@ -337,54 +337,10 @@ const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value
337
337
  * @returns decoded string
338
338
  */const fromBase64=value=>new TextDecoder().decode(base64ToBytes(value));
339
339
 
340
- const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
341
-
342
- const JSON_STRINGIFY='JSONStringify';const BIG_INT_PLACEHOLDER='[BigInt]';const CIRCULAR_REFERENCE_PLACEHOLDER='[Circular Reference]';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
343
- // eslint-disable-next-line func-names
344
- return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
345
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
346
- // @ts-ignore-next-line
347
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return CIRCULAR_REFERENCE_PLACEHOLDER;}ancestors.push(value);return value;};};/**
348
- * Utility method for JSON stringify object excluding null values & circular references
349
- *
350
- * @param {*} value input
351
- * @param {boolean} excludeNull if it should exclude nul or not
352
- * @param {function} logger optional logger methods for warning
353
- * @returns string
354
- */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};/**
355
- * Utility method for JSON stringify object excluding null values & circular references
356
- *
357
- * @param {*} value input value
358
- * @param {boolean} excludeNull optional flag to exclude null values
359
- * @param {string[]} excludeKeys optional array of keys to exclude
360
- * @returns string
361
- */const stringifyData=(value,excludeNull=true,excludeKeys=[])=>JSON.stringify(value,(key,value)=>{if(excludeNull&&isNull(value)||excludeKeys.includes(key)){return undefined;}return value;});const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
362
- // Using a regular function to use `this` for the parent context
363
- return function replacer(key,value){if(isBigInt(value)){return BIG_INT_PLACEHOLDER;// Replace BigInt values
364
- }// `this` is the object that value is contained in, i.e., its direct parent.
365
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
366
- // @ts-ignore-next-line
367
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
368
- }// Check for circular references (if the value is already in the ancestors)
369
- if(ancestors.includes(value)){return CIRCULAR_REFERENCE_PLACEHOLDER;}// Add current value to ancestors
370
- ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
371
- const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
372
- // eslint-disable-next-line no-restricted-syntax
373
- for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
374
- const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
375
- if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
376
- * Recursively traverses an object similar to JSON.stringify,
377
- * sanitizing BigInts and circular references
378
- * @param value Input object
379
- * @param logger Logger instance
380
- * @returns Sanitized value
381
- */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
382
- const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};const tempUtil=()=>{stringifyData();};
383
-
384
340
  // if yes make them null instead of omitting in overloaded cases
385
341
  /*
386
342
  * Normalise the overloaded arguments of the page call facade
387
- */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{tempUtil();const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
343
+ */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
388
344
  // use it as name and set category to undefined
389
345
  if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
390
346
  // and set some proper defaults
@@ -459,6 +415,43 @@ const getFormattedTimestamp=date=>date.toISOString();/**
459
415
  * @returns ISO formatted timestamp string
460
416
  */const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
461
417
 
418
+ const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
419
+
420
+ const JSON_STRINGIFY='JSONStringify';const BIG_INT_PLACEHOLDER='[BigInt]';const CIRCULAR_REFERENCE_PLACEHOLDER='[Circular Reference]';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
421
+ // eslint-disable-next-line func-names
422
+ return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
423
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
424
+ // @ts-ignore-next-line
425
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return CIRCULAR_REFERENCE_PLACEHOLDER;}ancestors.push(value);return value;};};/**
426
+ * Utility method for JSON stringify object excluding null values & circular references
427
+ *
428
+ * @param {*} value input
429
+ * @param {boolean} excludeNull if it should exclude nul or not
430
+ * @param {function} logger optional logger methods for warning
431
+ * @returns string
432
+ */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
433
+ // Using a regular function to use `this` for the parent context
434
+ return function replacer(key,value){if(isBigInt(value)){return BIG_INT_PLACEHOLDER;// Replace BigInt values
435
+ }// `this` is the object that value is contained in, i.e., its direct parent.
436
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
437
+ // @ts-ignore-next-line
438
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
439
+ }// Check for circular references (if the value is already in the ancestors)
440
+ if(ancestors.includes(value)){return CIRCULAR_REFERENCE_PLACEHOLDER;}// Add current value to ancestors
441
+ ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
442
+ const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
443
+ // eslint-disable-next-line no-restricted-syntax
444
+ for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
445
+ const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
446
+ if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
447
+ * Recursively traverses an object similar to JSON.stringify,
448
+ * sanitizing BigInts and circular references
449
+ * @param value Input object
450
+ * @param logger Logger instance
451
+ * @returns Sanitized value
452
+ */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
453
+ const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
454
+
462
455
  const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
463
456
  * Get mutated error with issue prepended to error message
464
457
  * @param err Original error
@@ -466,7 +459,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
466
459
  * @returns Instance of Error with message prepended with issue
467
460
  */const getMutatedError=(err,issue)=>{let finalError=err;if(!isTypeOfError(err)){finalError=new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}else {finalError.message=`${issue}: ${err.message}`;}return finalError;};const dispatchErrorEvent=error=>{if(isTypeOfError(error)){error.stack=`${error.stack??''}\n${MANUAL_ERROR_IDENTIFIER}`;}globalThis.dispatchEvent(new ErrorEvent('error',{error}));};
468
461
 
469
- const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.12';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';
462
+ const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.14';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';
470
463
 
471
464
  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';
472
465
 
@@ -3407,13 +3400,11 @@ if(isString(writeKey)&&writeKey){this.defaultAnalyticsKey=writeKey;}}/**
3407
3400
  * @param dataPlaneUrl Data plane URL
3408
3401
  * @param loadOptions Additional options for loading the SDK
3409
3402
  * @returns none
3410
- */load(writeKey,dataPlaneUrl,loadOptions){try{if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);const preloadedEventsArray=this.getPreloadedEvents();// Track page loaded lifecycle event if enabled
3403
+ */load(writeKey,dataPlaneUrl,loadOptions){try{if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);// Get the preloaded events array from global buffer instead of window.rudderanalytics
3404
+ // as the constructor must have already pushed the events to the global buffer
3405
+ const preloadedEventsArray=getExposedGlobal(GLOBAL_PRELOAD_BUFFER);// Track page loaded lifecycle event if enabled
3411
3406
  this.trackPageLifecycleEvents(preloadedEventsArray,loadOptions);// The array will be mutated in the below method
3412
3407
  promotePreloadedConsentEventsToTop(preloadedEventsArray);setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone(preloadedEventsArray));this.analyticsInstances[writeKey]=new Analytics();this.getAnalyticsInstance(writeKey)?.load(writeKey,dataPlaneUrl,getSanitizedValue(loadOptions));}catch(error){dispatchErrorEvent(error);}}/**
3413
- * A function to get preloaded events array from global object
3414
- * @returns preloaded events array
3415
- */// eslint-disable-next-line class-methods-use-this
3416
- getPreloadedEvents(){return Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];}/**
3417
3408
  * A function to track page lifecycle events like page loaded and page unloaded
3418
3409
  * @param preloadedEventsArray
3419
3410
  * @param loadOptions
@@ -3436,11 +3427,11 @@ trackPageLoadedEvent(events,options,preloadedEventsArray){if(events.length===0||
3436
3427
  this.logger.warn(PAGE_UNLOAD_ON_BEACON_DISABLED_WARNING(RSA));}}}/**
3437
3428
  * Trigger load event in buffer queue if exists and stores the
3438
3429
  * remaining preloaded events array in global object
3439
- */triggerBufferedLoadEvent(){const preloadedEventsArray=this.getPreloadedEvents();// Get any load method call that is buffered if any
3430
+ */triggerBufferedLoadEvent(){const preloadedEventsArray=Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];// Get any load method call that is buffered if any
3440
3431
  // BTW, load method is also removed from the array
3441
3432
  // So, the Analytics object can directly consume the remaining events
3442
3433
  const loadEvent=getPreloadedLoadEvent(preloadedEventsArray);// Set the final preloaded events array in global object
3443
- setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone(preloadedEventsArray));// Process load method if present in the buffered requests
3434
+ setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone([...preloadedEventsArray]));// Process load method if present in the buffered requests
3444
3435
  if(loadEvent.length>0){// Remove the event name from the Buffered Event array and keep only arguments
3445
3436
  loadEvent.shift();// eslint-disable-next-line @typescript-eslint/ban-ts-comment
3446
3437
  // @ts-ignore
@@ -343,54 +343,10 @@
343
343
  * @returns decoded string
344
344
  */const fromBase64=value=>new TextDecoder().decode(base64ToBytes(value));
345
345
 
346
- const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
347
-
348
- const JSON_STRINGIFY='JSONStringify';const BIG_INT_PLACEHOLDER='[BigInt]';const CIRCULAR_REFERENCE_PLACEHOLDER='[Circular Reference]';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
349
- // eslint-disable-next-line func-names
350
- return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
351
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
352
- // @ts-ignore-next-line
353
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return CIRCULAR_REFERENCE_PLACEHOLDER;}ancestors.push(value);return value;};};/**
354
- * Utility method for JSON stringify object excluding null values & circular references
355
- *
356
- * @param {*} value input
357
- * @param {boolean} excludeNull if it should exclude nul or not
358
- * @param {function} logger optional logger methods for warning
359
- * @returns string
360
- */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};/**
361
- * Utility method for JSON stringify object excluding null values & circular references
362
- *
363
- * @param {*} value input value
364
- * @param {boolean} excludeNull optional flag to exclude null values
365
- * @param {string[]} excludeKeys optional array of keys to exclude
366
- * @returns string
367
- */const stringifyData=(value,excludeNull=true,excludeKeys=[])=>JSON.stringify(value,(key,value)=>{if(excludeNull&&isNull(value)||excludeKeys.includes(key)){return undefined;}return value;});const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
368
- // Using a regular function to use `this` for the parent context
369
- return function replacer(key,value){if(isBigInt(value)){return BIG_INT_PLACEHOLDER;// Replace BigInt values
370
- }// `this` is the object that value is contained in, i.e., its direct parent.
371
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
372
- // @ts-ignore-next-line
373
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
374
- }// Check for circular references (if the value is already in the ancestors)
375
- if(ancestors.includes(value)){return CIRCULAR_REFERENCE_PLACEHOLDER;}// Add current value to ancestors
376
- ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
377
- const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
378
- // eslint-disable-next-line no-restricted-syntax
379
- for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
380
- const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
381
- if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
382
- * Recursively traverses an object similar to JSON.stringify,
383
- * sanitizing BigInts and circular references
384
- * @param value Input object
385
- * @param logger Logger instance
386
- * @returns Sanitized value
387
- */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
388
- const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};const tempUtil=()=>{stringifyData();};
389
-
390
346
  // if yes make them null instead of omitting in overloaded cases
391
347
  /*
392
348
  * Normalise the overloaded arguments of the page call facade
393
- */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{tempUtil();const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
349
+ */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
394
350
  // use it as name and set category to undefined
395
351
  if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
396
352
  // and set some proper defaults
@@ -465,6 +421,43 @@
465
421
  * @returns ISO formatted timestamp string
466
422
  */const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
467
423
 
424
+ const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
425
+
426
+ const JSON_STRINGIFY='JSONStringify';const BIG_INT_PLACEHOLDER='[BigInt]';const CIRCULAR_REFERENCE_PLACEHOLDER='[Circular Reference]';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
427
+ // eslint-disable-next-line func-names
428
+ return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
429
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
430
+ // @ts-ignore-next-line
431
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return CIRCULAR_REFERENCE_PLACEHOLDER;}ancestors.push(value);return value;};};/**
432
+ * Utility method for JSON stringify object excluding null values & circular references
433
+ *
434
+ * @param {*} value input
435
+ * @param {boolean} excludeNull if it should exclude nul or not
436
+ * @param {function} logger optional logger methods for warning
437
+ * @returns string
438
+ */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
439
+ // Using a regular function to use `this` for the parent context
440
+ return function replacer(key,value){if(isBigInt(value)){return BIG_INT_PLACEHOLDER;// Replace BigInt values
441
+ }// `this` is the object that value is contained in, i.e., its direct parent.
442
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
443
+ // @ts-ignore-next-line
444
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
445
+ }// Check for circular references (if the value is already in the ancestors)
446
+ if(ancestors.includes(value)){return CIRCULAR_REFERENCE_PLACEHOLDER;}// Add current value to ancestors
447
+ ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
448
+ const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
449
+ // eslint-disable-next-line no-restricted-syntax
450
+ for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
451
+ const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
452
+ if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
453
+ * Recursively traverses an object similar to JSON.stringify,
454
+ * sanitizing BigInts and circular references
455
+ * @param value Input object
456
+ * @param logger Logger instance
457
+ * @returns Sanitized value
458
+ */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
459
+ const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
460
+
468
461
  const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
469
462
  * Get mutated error with issue prepended to error message
470
463
  * @param err Original error
@@ -472,7 +465,7 @@
472
465
  * @returns Instance of Error with message prepended with issue
473
466
  */const getMutatedError=(err,issue)=>{let finalError=err;if(!isTypeOfError(err)){finalError=new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}else {finalError.message=`${issue}: ${err.message}`;}return finalError;};const dispatchErrorEvent=error=>{if(isTypeOfError(error)){error.stack=`${error.stack??''}\n${MANUAL_ERROR_IDENTIFIER}`;}globalThis.dispatchEvent(new ErrorEvent('error',{error}));};
474
467
 
475
- const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.12';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';
468
+ const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.14';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';
476
469
 
477
470
  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';
478
471
 
@@ -3413,13 +3406,11 @@
3413
3406
  * @param dataPlaneUrl Data plane URL
3414
3407
  * @param loadOptions Additional options for loading the SDK
3415
3408
  * @returns none
3416
- */load(writeKey,dataPlaneUrl,loadOptions){try{if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);const preloadedEventsArray=this.getPreloadedEvents();// Track page loaded lifecycle event if enabled
3409
+ */load(writeKey,dataPlaneUrl,loadOptions){try{if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);// Get the preloaded events array from global buffer instead of window.rudderanalytics
3410
+ // as the constructor must have already pushed the events to the global buffer
3411
+ const preloadedEventsArray=getExposedGlobal(GLOBAL_PRELOAD_BUFFER);// Track page loaded lifecycle event if enabled
3417
3412
  this.trackPageLifecycleEvents(preloadedEventsArray,loadOptions);// The array will be mutated in the below method
3418
3413
  promotePreloadedConsentEventsToTop(preloadedEventsArray);setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone(preloadedEventsArray));this.analyticsInstances[writeKey]=new Analytics();this.getAnalyticsInstance(writeKey)?.load(writeKey,dataPlaneUrl,getSanitizedValue(loadOptions));}catch(error){dispatchErrorEvent(error);}}/**
3419
- * A function to get preloaded events array from global object
3420
- * @returns preloaded events array
3421
- */// eslint-disable-next-line class-methods-use-this
3422
- getPreloadedEvents(){return Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];}/**
3423
3414
  * A function to track page lifecycle events like page loaded and page unloaded
3424
3415
  * @param preloadedEventsArray
3425
3416
  * @param loadOptions
@@ -3442,11 +3433,11 @@
3442
3433
  this.logger.warn(PAGE_UNLOAD_ON_BEACON_DISABLED_WARNING(RSA));}}}/**
3443
3434
  * Trigger load event in buffer queue if exists and stores the
3444
3435
  * remaining preloaded events array in global object
3445
- */triggerBufferedLoadEvent(){const preloadedEventsArray=this.getPreloadedEvents();// Get any load method call that is buffered if any
3436
+ */triggerBufferedLoadEvent(){const preloadedEventsArray=Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];// Get any load method call that is buffered if any
3446
3437
  // BTW, load method is also removed from the array
3447
3438
  // So, the Analytics object can directly consume the remaining events
3448
3439
  const loadEvent=getPreloadedLoadEvent(preloadedEventsArray);// Set the final preloaded events array in global object
3449
- setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone(preloadedEventsArray));// Process load method if present in the buffered requests
3440
+ setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone([...preloadedEventsArray]));// Process load method if present in the buffered requests
3450
3441
  if(loadEvent.length>0){// Remove the event name from the Buffered Event array and keep only arguments
3451
3442
  loadEvent.shift();// eslint-disable-next-line @typescript-eslint/ban-ts-comment
3452
3443
  // @ts-ignore
@@ -328,54 +328,10 @@ const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value
328
328
  * @returns base64 encoded string
329
329
  */const toBase64=value=>bytesToBase64(new TextEncoder().encode(value));
330
330
 
331
- const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
332
-
333
- const JSON_STRINGIFY='JSONStringify';const BIG_INT_PLACEHOLDER='[BigInt]';const CIRCULAR_REFERENCE_PLACEHOLDER='[Circular Reference]';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
334
- // eslint-disable-next-line func-names
335
- return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
336
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
337
- // @ts-ignore-next-line
338
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return CIRCULAR_REFERENCE_PLACEHOLDER;}ancestors.push(value);return value;};};/**
339
- * Utility method for JSON stringify object excluding null values & circular references
340
- *
341
- * @param {*} value input
342
- * @param {boolean} excludeNull if it should exclude nul or not
343
- * @param {function} logger optional logger methods for warning
344
- * @returns string
345
- */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};/**
346
- * Utility method for JSON stringify object excluding null values & circular references
347
- *
348
- * @param {*} value input value
349
- * @param {boolean} excludeNull optional flag to exclude null values
350
- * @param {string[]} excludeKeys optional array of keys to exclude
351
- * @returns string
352
- */const stringifyData=(value,excludeNull=true,excludeKeys=[])=>JSON.stringify(value,(key,value)=>{if(excludeNull&&isNull(value)||excludeKeys.includes(key)){return undefined;}return value;});const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
353
- // Using a regular function to use `this` for the parent context
354
- return function replacer(key,value){if(isBigInt(value)){return BIG_INT_PLACEHOLDER;// Replace BigInt values
355
- }// `this` is the object that value is contained in, i.e., its direct parent.
356
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
357
- // @ts-ignore-next-line
358
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
359
- }// Check for circular references (if the value is already in the ancestors)
360
- if(ancestors.includes(value)){return CIRCULAR_REFERENCE_PLACEHOLDER;}// Add current value to ancestors
361
- ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
362
- const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
363
- // eslint-disable-next-line no-restricted-syntax
364
- for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
365
- const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
366
- if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
367
- * Recursively traverses an object similar to JSON.stringify,
368
- * sanitizing BigInts and circular references
369
- * @param value Input object
370
- * @param logger Logger instance
371
- * @returns Sanitized value
372
- */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
373
- const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};const tempUtil=()=>{stringifyData();};
374
-
375
331
  // if yes make them null instead of omitting in overloaded cases
376
332
  /*
377
333
  * Normalise the overloaded arguments of the page call facade
378
- */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{tempUtil();const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
334
+ */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
379
335
  // use it as name and set category to undefined
380
336
  if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
381
337
  // and set some proper defaults
@@ -450,6 +406,43 @@ const getFormattedTimestamp=date=>date.toISOString();/**
450
406
  * @returns ISO formatted timestamp string
451
407
  */const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
452
408
 
409
+ const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
410
+
411
+ const JSON_STRINGIFY='JSONStringify';const BIG_INT_PLACEHOLDER='[BigInt]';const CIRCULAR_REFERENCE_PLACEHOLDER='[Circular Reference]';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
412
+ // eslint-disable-next-line func-names
413
+ return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
414
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
415
+ // @ts-ignore-next-line
416
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return CIRCULAR_REFERENCE_PLACEHOLDER;}ancestors.push(value);return value;};};/**
417
+ * Utility method for JSON stringify object excluding null values & circular references
418
+ *
419
+ * @param {*} value input
420
+ * @param {boolean} excludeNull if it should exclude nul or not
421
+ * @param {function} logger optional logger methods for warning
422
+ * @returns string
423
+ */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
424
+ // Using a regular function to use `this` for the parent context
425
+ return function replacer(key,value){if(isBigInt(value)){return BIG_INT_PLACEHOLDER;// Replace BigInt values
426
+ }// `this` is the object that value is contained in, i.e., its direct parent.
427
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
428
+ // @ts-ignore-next-line
429
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
430
+ }// Check for circular references (if the value is already in the ancestors)
431
+ if(ancestors.includes(value)){return CIRCULAR_REFERENCE_PLACEHOLDER;}// Add current value to ancestors
432
+ ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
433
+ const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
434
+ // eslint-disable-next-line no-restricted-syntax
435
+ for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
436
+ const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
437
+ if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
438
+ * Recursively traverses an object similar to JSON.stringify,
439
+ * sanitizing BigInts and circular references
440
+ * @param value Input object
441
+ * @param logger Logger instance
442
+ * @returns Sanitized value
443
+ */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
444
+ const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
445
+
453
446
  const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
454
447
  * Get mutated error with issue prepended to error message
455
448
  * @param err Original error
@@ -457,7 +450,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
457
450
  * @returns Instance of Error with message prepended with issue
458
451
  */const getMutatedError=(err,issue)=>{let finalError=err;if(!isTypeOfError(err)){finalError=new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}else {finalError.message=`${issue}: ${err.message}`;}return finalError;};const dispatchErrorEvent=error=>{if(isTypeOfError(error)){error.stack=`${error.stack??''}\n${MANUAL_ERROR_IDENTIFIER}`;}globalThis.dispatchEvent(new ErrorEvent('error',{error}));};
459
452
 
460
- const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.12';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';
453
+ const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.14';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';
461
454
 
462
455
  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';
463
456
 
@@ -1744,13 +1737,11 @@ if(isString(writeKey)&&writeKey){this.defaultAnalyticsKey=writeKey;}}/**
1744
1737
  * @param dataPlaneUrl Data plane URL
1745
1738
  * @param loadOptions Additional options for loading the SDK
1746
1739
  * @returns none
1747
- */load(writeKey,dataPlaneUrl,loadOptions){try{if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);const preloadedEventsArray=this.getPreloadedEvents();// Track page loaded lifecycle event if enabled
1740
+ */load(writeKey,dataPlaneUrl,loadOptions){try{if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);// Get the preloaded events array from global buffer instead of window.rudderanalytics
1741
+ // as the constructor must have already pushed the events to the global buffer
1742
+ const preloadedEventsArray=getExposedGlobal(GLOBAL_PRELOAD_BUFFER);// Track page loaded lifecycle event if enabled
1748
1743
  this.trackPageLifecycleEvents(preloadedEventsArray,loadOptions);// The array will be mutated in the below method
1749
1744
  promotePreloadedConsentEventsToTop(preloadedEventsArray);setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone(preloadedEventsArray));this.analyticsInstances[writeKey]=new Analytics();this.getAnalyticsInstance(writeKey)?.load(writeKey,dataPlaneUrl,getSanitizedValue(loadOptions));}catch(error){dispatchErrorEvent(error);}}/**
1750
- * A function to get preloaded events array from global object
1751
- * @returns preloaded events array
1752
- */// eslint-disable-next-line class-methods-use-this
1753
- getPreloadedEvents(){return Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];}/**
1754
1745
  * A function to track page lifecycle events like page loaded and page unloaded
1755
1746
  * @param preloadedEventsArray
1756
1747
  * @param loadOptions
@@ -1773,11 +1764,11 @@ trackPageLoadedEvent(events,options,preloadedEventsArray){if(events.length===0||
1773
1764
  this.logger.warn(PAGE_UNLOAD_ON_BEACON_DISABLED_WARNING(RSA));}}}/**
1774
1765
  * Trigger load event in buffer queue if exists and stores the
1775
1766
  * remaining preloaded events array in global object
1776
- */triggerBufferedLoadEvent(){const preloadedEventsArray=this.getPreloadedEvents();// Get any load method call that is buffered if any
1767
+ */triggerBufferedLoadEvent(){const preloadedEventsArray=Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];// Get any load method call that is buffered if any
1777
1768
  // BTW, load method is also removed from the array
1778
1769
  // So, the Analytics object can directly consume the remaining events
1779
1770
  const loadEvent=getPreloadedLoadEvent(preloadedEventsArray);// Set the final preloaded events array in global object
1780
- setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone(preloadedEventsArray));// Process load method if present in the buffered requests
1771
+ setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone([...preloadedEventsArray]));// Process load method if present in the buffered requests
1781
1772
  if(loadEvent.length>0){// Remove the event name from the Buffered Event array and keep only arguments
1782
1773
  loadEvent.shift();// eslint-disable-next-line @typescript-eslint/ban-ts-comment
1783
1774
  // @ts-ignore