@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
 
@@ -3435,13 +3428,11 @@ if(isString(writeKey)&&writeKey){this.defaultAnalyticsKey=writeKey;}}/**
3435
3428
  * @param dataPlaneUrl Data plane URL
3436
3429
  * @param loadOptions Additional options for loading the SDK
3437
3430
  * @returns none
3438
- */load(writeKey,dataPlaneUrl,loadOptions){try{if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);const preloadedEventsArray=this.getPreloadedEvents();// Track page loaded lifecycle event if enabled
3431
+ */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
3432
+ // as the constructor must have already pushed the events to the global buffer
3433
+ const preloadedEventsArray=getExposedGlobal(GLOBAL_PRELOAD_BUFFER);// Track page loaded lifecycle event if enabled
3439
3434
  this.trackPageLifecycleEvents(preloadedEventsArray,loadOptions);// The array will be mutated in the below method
3440
3435
  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);}}/**
3441
- * A function to get preloaded events array from global object
3442
- * @returns preloaded events array
3443
- */// eslint-disable-next-line class-methods-use-this
3444
- getPreloadedEvents(){return Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];}/**
3445
3436
  * A function to track page lifecycle events like page loaded and page unloaded
3446
3437
  * @param preloadedEventsArray
3447
3438
  * @param loadOptions
@@ -3464,11 +3455,11 @@ trackPageLoadedEvent(events,options,preloadedEventsArray){if(events.length===0||
3464
3455
  this.logger.warn(PAGE_UNLOAD_ON_BEACON_DISABLED_WARNING(RSA));}}}/**
3465
3456
  * Trigger load event in buffer queue if exists and stores the
3466
3457
  * remaining preloaded events array in global object
3467
- */triggerBufferedLoadEvent(){const preloadedEventsArray=this.getPreloadedEvents();// Get any load method call that is buffered if any
3458
+ */triggerBufferedLoadEvent(){const preloadedEventsArray=Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];// Get any load method call that is buffered if any
3468
3459
  // BTW, load method is also removed from the array
3469
3460
  // So, the Analytics object can directly consume the remaining events
3470
3461
  const loadEvent=getPreloadedLoadEvent(preloadedEventsArray);// Set the final preloaded events array in global object
3471
- setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone(preloadedEventsArray));// Process load method if present in the buffered requests
3462
+ setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone([...preloadedEventsArray]));// Process load method if present in the buffered requests
3472
3463
  if(loadEvent.length>0){// Remove the event name from the Buffered Event array and keep only arguments
3473
3464
  loadEvent.shift();// eslint-disable-next-line @typescript-eslint/ban-ts-comment
3474
3465
  // @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
 
@@ -3431,13 +3424,11 @@ if(isString(writeKey)&&writeKey){this.defaultAnalyticsKey=writeKey;}}/**
3431
3424
  * @param dataPlaneUrl Data plane URL
3432
3425
  * @param loadOptions Additional options for loading the SDK
3433
3426
  * @returns none
3434
- */load(writeKey,dataPlaneUrl,loadOptions){try{if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);const preloadedEventsArray=this.getPreloadedEvents();// Track page loaded lifecycle event if enabled
3427
+ */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
3428
+ // as the constructor must have already pushed the events to the global buffer
3429
+ const preloadedEventsArray=getExposedGlobal(GLOBAL_PRELOAD_BUFFER);// Track page loaded lifecycle event if enabled
3435
3430
  this.trackPageLifecycleEvents(preloadedEventsArray,loadOptions);// The array will be mutated in the below method
3436
3431
  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);}}/**
3437
- * A function to get preloaded events array from global object
3438
- * @returns preloaded events array
3439
- */// eslint-disable-next-line class-methods-use-this
3440
- getPreloadedEvents(){return Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];}/**
3441
3432
  * A function to track page lifecycle events like page loaded and page unloaded
3442
3433
  * @param preloadedEventsArray
3443
3434
  * @param loadOptions
@@ -3460,11 +3451,11 @@ trackPageLoadedEvent(events,options,preloadedEventsArray){if(events.length===0||
3460
3451
  this.logger.warn(PAGE_UNLOAD_ON_BEACON_DISABLED_WARNING(RSA));}}}/**
3461
3452
  * Trigger load event in buffer queue if exists and stores the
3462
3453
  * remaining preloaded events array in global object
3463
- */triggerBufferedLoadEvent(){const preloadedEventsArray=this.getPreloadedEvents();// Get any load method call that is buffered if any
3454
+ */triggerBufferedLoadEvent(){const preloadedEventsArray=Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];// Get any load method call that is buffered if any
3464
3455
  // BTW, load method is also removed from the array
3465
3456
  // So, the Analytics object can directly consume the remaining events
3466
3457
  const loadEvent=getPreloadedLoadEvent(preloadedEventsArray);// Set the final preloaded events array in global object
3467
- setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone(preloadedEventsArray));// Process load method if present in the buffered requests
3458
+ setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone([...preloadedEventsArray]));// Process load method if present in the buffered requests
3468
3459
  if(loadEvent.length>0){// Remove the event name from the Buffered Event array and keep only arguments
3469
3460
  loadEvent.shift();// eslint-disable-next-line @typescript-eslint/ban-ts-comment
3470
3461
  // @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
 
@@ -3437,13 +3430,11 @@
3437
3430
  * @param dataPlaneUrl Data plane URL
3438
3431
  * @param loadOptions Additional options for loading the SDK
3439
3432
  * @returns none
3440
- */load(writeKey,dataPlaneUrl,loadOptions){try{if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);const preloadedEventsArray=this.getPreloadedEvents();// Track page loaded lifecycle event if enabled
3433
+ */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
3434
+ // as the constructor must have already pushed the events to the global buffer
3435
+ const preloadedEventsArray=getExposedGlobal(GLOBAL_PRELOAD_BUFFER);// Track page loaded lifecycle event if enabled
3441
3436
  this.trackPageLifecycleEvents(preloadedEventsArray,loadOptions);// The array will be mutated in the below method
3442
3437
  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);}}/**
3443
- * A function to get preloaded events array from global object
3444
- * @returns preloaded events array
3445
- */// eslint-disable-next-line class-methods-use-this
3446
- getPreloadedEvents(){return Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];}/**
3447
3438
  * A function to track page lifecycle events like page loaded and page unloaded
3448
3439
  * @param preloadedEventsArray
3449
3440
  * @param loadOptions
@@ -3466,11 +3457,11 @@
3466
3457
  this.logger.warn(PAGE_UNLOAD_ON_BEACON_DISABLED_WARNING(RSA));}}}/**
3467
3458
  * Trigger load event in buffer queue if exists and stores the
3468
3459
  * remaining preloaded events array in global object
3469
- */triggerBufferedLoadEvent(){const preloadedEventsArray=this.getPreloadedEvents();// Get any load method call that is buffered if any
3460
+ */triggerBufferedLoadEvent(){const preloadedEventsArray=Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];// Get any load method call that is buffered if any
3470
3461
  // BTW, load method is also removed from the array
3471
3462
  // So, the Analytics object can directly consume the remaining events
3472
3463
  const loadEvent=getPreloadedLoadEvent(preloadedEventsArray);// Set the final preloaded events array in global object
3473
- setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone(preloadedEventsArray));// Process load method if present in the buffered requests
3464
+ setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone([...preloadedEventsArray]));// Process load method if present in the buffered requests
3474
3465
  if(loadEvent.length>0){// Remove the event name from the Buffered Event array and keep only arguments
3475
3466
  loadEvent.shift();// eslint-disable-next-line @typescript-eslint/ban-ts-comment
3476
3467
  // @ts-ignore
@@ -332,54 +332,10 @@ const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value
332
332
  * @returns base64 encoded string
333
333
  */const toBase64=value=>bytesToBase64(new TextEncoder().encode(value));
334
334
 
335
- 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.`;
336
-
337
- 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
338
- // eslint-disable-next-line func-names
339
- 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.
340
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
341
- // @ts-ignore-next-line
342
- 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;};};/**
343
- * Utility method for JSON stringify object excluding null values & circular references
344
- *
345
- * @param {*} value input
346
- * @param {boolean} excludeNull if it should exclude nul or not
347
- * @param {function} logger optional logger methods for warning
348
- * @returns string
349
- */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;}};/**
350
- * Utility method for JSON stringify object excluding null values & circular references
351
- *
352
- * @param {*} value input value
353
- * @param {boolean} excludeNull optional flag to exclude null values
354
- * @param {string[]} excludeKeys optional array of keys to exclude
355
- * @returns string
356
- */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
357
- // Using a regular function to use `this` for the parent context
358
- return function replacer(key,value){if(isBigInt(value)){return BIG_INT_PLACEHOLDER;// Replace BigInt values
359
- }// `this` is the object that value is contained in, i.e., its direct parent.
360
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
361
- // @ts-ignore-next-line
362
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
363
- }// Check for circular references (if the value is already in the ancestors)
364
- if(ancestors.includes(value)){return CIRCULAR_REFERENCE_PLACEHOLDER;}// Add current value to ancestors
365
- ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
366
- const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
367
- // eslint-disable-next-line no-restricted-syntax
368
- for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
369
- const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
370
- if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
371
- * Recursively traverses an object similar to JSON.stringify,
372
- * sanitizing BigInts and circular references
373
- * @param value Input object
374
- * @param logger Logger instance
375
- * @returns Sanitized value
376
- */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
377
- const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};const tempUtil=()=>{stringifyData();};
378
-
379
335
  // if yes make them null instead of omitting in overloaded cases
380
336
  /*
381
337
  * Normalise the overloaded arguments of the page call facade
382
- */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,
338
+ */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,
383
339
  // use it as name and set category to undefined
384
340
  if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
385
341
  // and set some proper defaults
@@ -454,6 +410,43 @@ const getFormattedTimestamp=date=>date.toISOString();/**
454
410
  * @returns ISO formatted timestamp string
455
411
  */const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
456
412
 
413
+ 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.`;
414
+
415
+ 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
416
+ // eslint-disable-next-line func-names
417
+ 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.
418
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
419
+ // @ts-ignore-next-line
420
+ 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;};};/**
421
+ * Utility method for JSON stringify object excluding null values & circular references
422
+ *
423
+ * @param {*} value input
424
+ * @param {boolean} excludeNull if it should exclude nul or not
425
+ * @param {function} logger optional logger methods for warning
426
+ * @returns string
427
+ */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
428
+ // Using a regular function to use `this` for the parent context
429
+ return function replacer(key,value){if(isBigInt(value)){return BIG_INT_PLACEHOLDER;// Replace BigInt values
430
+ }// `this` is the object that value is contained in, i.e., its direct parent.
431
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
432
+ // @ts-ignore-next-line
433
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
434
+ }// Check for circular references (if the value is already in the ancestors)
435
+ if(ancestors.includes(value)){return CIRCULAR_REFERENCE_PLACEHOLDER;}// Add current value to ancestors
436
+ ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
437
+ const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
438
+ // eslint-disable-next-line no-restricted-syntax
439
+ for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
440
+ const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
441
+ if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
442
+ * Recursively traverses an object similar to JSON.stringify,
443
+ * sanitizing BigInts and circular references
444
+ * @param value Input object
445
+ * @param logger Logger instance
446
+ * @returns Sanitized value
447
+ */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
448
+ const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
449
+
457
450
  const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
458
451
  * Get mutated error with issue prepended to error message
459
452
  * @param err Original error
@@ -461,7 +454,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
461
454
  * @returns Instance of Error with message prepended with issue
462
455
  */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}));};
463
456
 
464
- 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';
457
+ 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';
465
458
 
466
459
  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';
467
460
 
@@ -1748,13 +1741,11 @@ if(isString(writeKey)&&writeKey){this.defaultAnalyticsKey=writeKey;}}/**
1748
1741
  * @param dataPlaneUrl Data plane URL
1749
1742
  * @param loadOptions Additional options for loading the SDK
1750
1743
  * @returns none
1751
- */load(writeKey,dataPlaneUrl,loadOptions){try{if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);const preloadedEventsArray=this.getPreloadedEvents();// Track page loaded lifecycle event if enabled
1744
+ */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
1745
+ // as the constructor must have already pushed the events to the global buffer
1746
+ const preloadedEventsArray=getExposedGlobal(GLOBAL_PRELOAD_BUFFER);// Track page loaded lifecycle event if enabled
1752
1747
  this.trackPageLifecycleEvents(preloadedEventsArray,loadOptions);// The array will be mutated in the below method
1753
1748
  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);}}/**
1754
- * A function to get preloaded events array from global object
1755
- * @returns preloaded events array
1756
- */// eslint-disable-next-line class-methods-use-this
1757
- getPreloadedEvents(){return Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];}/**
1758
1749
  * A function to track page lifecycle events like page loaded and page unloaded
1759
1750
  * @param preloadedEventsArray
1760
1751
  * @param loadOptions
@@ -1777,11 +1768,11 @@ trackPageLoadedEvent(events,options,preloadedEventsArray){if(events.length===0||
1777
1768
  this.logger.warn(PAGE_UNLOAD_ON_BEACON_DISABLED_WARNING(RSA));}}}/**
1778
1769
  * Trigger load event in buffer queue if exists and stores the
1779
1770
  * remaining preloaded events array in global object
1780
- */triggerBufferedLoadEvent(){const preloadedEventsArray=this.getPreloadedEvents();// Get any load method call that is buffered if any
1771
+ */triggerBufferedLoadEvent(){const preloadedEventsArray=Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];// Get any load method call that is buffered if any
1781
1772
  // BTW, load method is also removed from the array
1782
1773
  // So, the Analytics object can directly consume the remaining events
1783
1774
  const loadEvent=getPreloadedLoadEvent(preloadedEventsArray);// Set the final preloaded events array in global object
1784
- setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone(preloadedEventsArray));// Process load method if present in the buffered requests
1775
+ setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone([...preloadedEventsArray]));// Process load method if present in the buffered requests
1785
1776
  if(loadEvent.length>0){// Remove the event name from the Buffered Event array and keep only arguments
1786
1777
  loadEvent.shift();// eslint-disable-next-line @typescript-eslint/ban-ts-comment
1787
1778
  // @ts-ignore