@rudderstack/analytics-js 3.11.3 → 3.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/npm/legacy/bundled/cjs/index.cjs +39 -39
- package/dist/npm/legacy/bundled/esm/index.mjs +39 -39
- package/dist/npm/legacy/bundled/umd/index.js +39 -39
- package/dist/npm/legacy/cjs/index.cjs +39 -39
- package/dist/npm/legacy/content-script/cjs/index.cjs +39 -39
- package/dist/npm/legacy/content-script/esm/index.mjs +39 -39
- package/dist/npm/legacy/content-script/umd/index.js +39 -39
- package/dist/npm/legacy/esm/index.mjs +39 -39
- package/dist/npm/legacy/umd/index.js +39 -39
- package/dist/npm/modern/bundled/cjs/index.cjs +39 -39
- package/dist/npm/modern/bundled/esm/index.mjs +39 -39
- package/dist/npm/modern/bundled/umd/index.js +39 -39
- package/dist/npm/modern/cjs/index.cjs +39 -39
- package/dist/npm/modern/content-script/cjs/index.cjs +39 -39
- package/dist/npm/modern/content-script/esm/index.mjs +39 -39
- package/dist/npm/modern/content-script/umd/index.js +39 -39
- package/dist/npm/modern/esm/index.mjs +39 -39
- package/dist/npm/modern/umd/index.js +39 -39
- package/package.json +1 -1
@@ -332,67 +332,37 @@ 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 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]';}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;}};const getReplacer=logger=>// Using a regular function to use `this` for the parent context
|
350
|
-
function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
351
|
-
}return value;};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
352
|
-
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
353
|
-
// eslint-disable-next-line no-restricted-syntax
|
354
|
-
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
355
|
-
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
356
|
-
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
357
|
-
* Recursively traverses an object similar to JSON.stringify,
|
358
|
-
* sanitizing BigInts and circular references
|
359
|
-
* @param value Input object
|
360
|
-
* @param logger Logger instance
|
361
|
-
* @returns Sanitized value
|
362
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
363
|
-
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
364
|
-
|
365
335
|
// if yes make them null instead of omitting in overloaded cases
|
366
336
|
/*
|
367
337
|
* Normalise the overloaded arguments of the page call facade
|
368
|
-
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const
|
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,
|
369
339
|
// use it as name and set category to undefined
|
370
|
-
if(isString(
|
340
|
+
if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
|
371
341
|
// and set some proper defaults
|
372
342
|
// Also, to clone the incoming object type arguments
|
373
343
|
if(!isDefined(payload.category)){payload.category=undefined;}if(!isDefined(payload.name)){payload.name=undefined;}payload.properties=payload.properties?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}const nameForProperties=isString(payload.name)?payload.name:payload.properties.name;const categoryForProperties=isString(payload.category)?payload.category:payload.properties.category;// add name and category to properties
|
374
344
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
375
345
|
* Normalise the overloaded arguments of the track call facade
|
376
|
-
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const
|
346
|
+
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:event,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.properties=undefined;payload.options=undefined;payload.callback=properties;}// Rest of the code is just to clean up undefined values
|
377
347
|
// and set some proper defaults
|
378
348
|
// Also, to clone the incoming object type arguments
|
379
349
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
380
350
|
* Normalise the overloaded arguments of the identify call facade
|
381
|
-
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const
|
351
|
+
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:userId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.userId=userId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.userId=userId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(userId)||isNull(userId)){// Explicitly set null to prevent resetting the existing value
|
382
352
|
// in the Analytics class
|
383
|
-
payload.userId=null;payload.traits=
|
353
|
+
payload.userId=null;payload.traits=userId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
384
354
|
// and set some proper defaults
|
385
355
|
// Also, to clone the incoming object type arguments
|
386
356
|
payload.userId=tryStringify(payload.userId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
387
357
|
* Normalise the overloaded arguments of the alias call facade
|
388
|
-
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const
|
358
|
+
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:from,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.to=to;payload.from=from;payload.options=undefined;payload.callback=options;}if(isFunction(from)){payload.to=to;payload.from=undefined;payload.options=undefined;payload.callback=from;}else if(isObjectLiteralAndNotNull(from)||isNull(from)){payload.to=to;payload.from=undefined;payload.options=from;}// Rest of the code is just to clean up undefined values
|
389
359
|
// and set some proper defaults
|
390
360
|
// Also, to clone the incoming object type arguments
|
391
361
|
if(isDefined(payload.to)){payload.to=tryStringify(payload.to);}if(isDefined(payload.from)){payload.from=tryStringify(payload.from);}else {payload.from=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
392
362
|
* Normalise the overloaded arguments of the group call facade
|
393
|
-
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const
|
363
|
+
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:groupId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.groupId=groupId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.groupId=groupId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(groupId)||isNull(groupId)){// Explicitly set null to prevent resetting the existing value
|
394
364
|
// in the Analytics class
|
395
|
-
payload.groupId=null;payload.traits=
|
365
|
+
payload.groupId=null;payload.traits=groupId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
396
366
|
// and set some proper defaults
|
397
367
|
// Also, to clone the incoming object type arguments
|
398
368
|
payload.groupId=tryStringify(payload.groupId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};
|
@@ -440,6 +410,36 @@ const getFormattedTimestamp=date=>date.toISOString();/**
|
|
440
410
|
* @returns ISO formatted timestamp string
|
441
411
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
442
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 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]';}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=>// Using a regular function to use `this` for the parent context
|
428
|
+
function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
429
|
+
}return value;};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
430
|
+
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
431
|
+
// eslint-disable-next-line no-restricted-syntax
|
432
|
+
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
433
|
+
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
434
|
+
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
435
|
+
* Recursively traverses an object similar to JSON.stringify,
|
436
|
+
* sanitizing BigInts and circular references
|
437
|
+
* @param value Input object
|
438
|
+
* @param logger Logger instance
|
439
|
+
* @returns Sanitized value
|
440
|
+
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
441
|
+
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
442
|
+
|
443
443
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
444
444
|
* Get mutated error with issue prepended to error message
|
445
445
|
* @param err Original error
|
@@ -447,7 +447,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
|
447
447
|
* @returns Instance of Error with message prepended with issue
|
448
448
|
*/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}));};
|
449
449
|
|
450
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
450
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.4';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';
|
451
451
|
|
452
452
|
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';
|
453
453
|
|
@@ -341,67 +341,37 @@ 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 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]';}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;}};const getReplacer=logger=>// Using a regular function to use `this` for the parent context
|
359
|
-
function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
360
|
-
}return value;};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
361
|
-
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
362
|
-
// eslint-disable-next-line no-restricted-syntax
|
363
|
-
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
364
|
-
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
365
|
-
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
366
|
-
* Recursively traverses an object similar to JSON.stringify,
|
367
|
-
* sanitizing BigInts and circular references
|
368
|
-
* @param value Input object
|
369
|
-
* @param logger Logger instance
|
370
|
-
* @returns Sanitized value
|
371
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
372
|
-
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
373
|
-
|
374
344
|
// if yes make them null instead of omitting in overloaded cases
|
375
345
|
/*
|
376
346
|
* Normalise the overloaded arguments of the page call facade
|
377
|
-
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const
|
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,
|
378
348
|
// use it as name and set category to undefined
|
379
|
-
if(isString(
|
349
|
+
if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
|
380
350
|
// and set some proper defaults
|
381
351
|
// Also, to clone the incoming object type arguments
|
382
352
|
if(!isDefined(payload.category)){payload.category=undefined;}if(!isDefined(payload.name)){payload.name=undefined;}payload.properties=payload.properties?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}const nameForProperties=isString(payload.name)?payload.name:payload.properties.name;const categoryForProperties=isString(payload.category)?payload.category:payload.properties.category;// add name and category to properties
|
383
353
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
384
354
|
* Normalise the overloaded arguments of the track call facade
|
385
|
-
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const
|
355
|
+
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:event,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.properties=undefined;payload.options=undefined;payload.callback=properties;}// Rest of the code is just to clean up undefined values
|
386
356
|
// and set some proper defaults
|
387
357
|
// Also, to clone the incoming object type arguments
|
388
358
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
389
359
|
* Normalise the overloaded arguments of the identify call facade
|
390
|
-
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const
|
360
|
+
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:userId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.userId=userId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.userId=userId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(userId)||isNull(userId)){// Explicitly set null to prevent resetting the existing value
|
391
361
|
// in the Analytics class
|
392
|
-
payload.userId=null;payload.traits=
|
362
|
+
payload.userId=null;payload.traits=userId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
393
363
|
// and set some proper defaults
|
394
364
|
// Also, to clone the incoming object type arguments
|
395
365
|
payload.userId=tryStringify(payload.userId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
396
366
|
* Normalise the overloaded arguments of the alias call facade
|
397
|
-
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const
|
367
|
+
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:from,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.to=to;payload.from=from;payload.options=undefined;payload.callback=options;}if(isFunction(from)){payload.to=to;payload.from=undefined;payload.options=undefined;payload.callback=from;}else if(isObjectLiteralAndNotNull(from)||isNull(from)){payload.to=to;payload.from=undefined;payload.options=from;}// Rest of the code is just to clean up undefined values
|
398
368
|
// and set some proper defaults
|
399
369
|
// Also, to clone the incoming object type arguments
|
400
370
|
if(isDefined(payload.to)){payload.to=tryStringify(payload.to);}if(isDefined(payload.from)){payload.from=tryStringify(payload.from);}else {payload.from=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
401
371
|
* Normalise the overloaded arguments of the group call facade
|
402
|
-
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const
|
372
|
+
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:groupId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.groupId=groupId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.groupId=groupId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(groupId)||isNull(groupId)){// Explicitly set null to prevent resetting the existing value
|
403
373
|
// in the Analytics class
|
404
|
-
payload.groupId=null;payload.traits=
|
374
|
+
payload.groupId=null;payload.traits=groupId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
405
375
|
// and set some proper defaults
|
406
376
|
// Also, to clone the incoming object type arguments
|
407
377
|
payload.groupId=tryStringify(payload.groupId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};
|
@@ -449,6 +419,36 @@ const getFormattedTimestamp=date=>date.toISOString();/**
|
|
449
419
|
* @returns ISO formatted timestamp string
|
450
420
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
451
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 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]';}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=>// Using a regular function to use `this` for the parent context
|
437
|
+
function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
438
|
+
}return value;};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
439
|
+
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
440
|
+
// eslint-disable-next-line no-restricted-syntax
|
441
|
+
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
442
|
+
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
443
|
+
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
444
|
+
* Recursively traverses an object similar to JSON.stringify,
|
445
|
+
* sanitizing BigInts and circular references
|
446
|
+
* @param value Input object
|
447
|
+
* @param logger Logger instance
|
448
|
+
* @returns Sanitized value
|
449
|
+
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
450
|
+
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
451
|
+
|
452
452
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
453
453
|
* Get mutated error with issue prepended to error message
|
454
454
|
* @param err Original error
|
@@ -456,7 +456,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
|
456
456
|
* @returns Instance of Error with message prepended with issue
|
457
457
|
*/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}));};
|
458
458
|
|
459
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
459
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.4';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';
|
460
460
|
|
461
461
|
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';
|
462
462
|
|
@@ -337,67 +337,37 @@ 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 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]';}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;}};const getReplacer=logger=>// Using a regular function to use `this` for the parent context
|
355
|
-
function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
356
|
-
}return value;};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
357
|
-
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
358
|
-
// eslint-disable-next-line no-restricted-syntax
|
359
|
-
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
360
|
-
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
361
|
-
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
362
|
-
* Recursively traverses an object similar to JSON.stringify,
|
363
|
-
* sanitizing BigInts and circular references
|
364
|
-
* @param value Input object
|
365
|
-
* @param logger Logger instance
|
366
|
-
* @returns Sanitized value
|
367
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
368
|
-
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
369
|
-
|
370
340
|
// if yes make them null instead of omitting in overloaded cases
|
371
341
|
/*
|
372
342
|
* Normalise the overloaded arguments of the page call facade
|
373
|
-
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const
|
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,
|
374
344
|
// use it as name and set category to undefined
|
375
|
-
if(isString(
|
345
|
+
if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
|
376
346
|
// and set some proper defaults
|
377
347
|
// Also, to clone the incoming object type arguments
|
378
348
|
if(!isDefined(payload.category)){payload.category=undefined;}if(!isDefined(payload.name)){payload.name=undefined;}payload.properties=payload.properties?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}const nameForProperties=isString(payload.name)?payload.name:payload.properties.name;const categoryForProperties=isString(payload.category)?payload.category:payload.properties.category;// add name and category to properties
|
379
349
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
380
350
|
* Normalise the overloaded arguments of the track call facade
|
381
|
-
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const
|
351
|
+
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:event,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.properties=undefined;payload.options=undefined;payload.callback=properties;}// Rest of the code is just to clean up undefined values
|
382
352
|
// and set some proper defaults
|
383
353
|
// Also, to clone the incoming object type arguments
|
384
354
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
385
355
|
* Normalise the overloaded arguments of the identify call facade
|
386
|
-
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const
|
356
|
+
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:userId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.userId=userId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.userId=userId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(userId)||isNull(userId)){// Explicitly set null to prevent resetting the existing value
|
387
357
|
// in the Analytics class
|
388
|
-
payload.userId=null;payload.traits=
|
358
|
+
payload.userId=null;payload.traits=userId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
389
359
|
// and set some proper defaults
|
390
360
|
// Also, to clone the incoming object type arguments
|
391
361
|
payload.userId=tryStringify(payload.userId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
392
362
|
* Normalise the overloaded arguments of the alias call facade
|
393
|
-
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const
|
363
|
+
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:from,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.to=to;payload.from=from;payload.options=undefined;payload.callback=options;}if(isFunction(from)){payload.to=to;payload.from=undefined;payload.options=undefined;payload.callback=from;}else if(isObjectLiteralAndNotNull(from)||isNull(from)){payload.to=to;payload.from=undefined;payload.options=from;}// Rest of the code is just to clean up undefined values
|
394
364
|
// and set some proper defaults
|
395
365
|
// Also, to clone the incoming object type arguments
|
396
366
|
if(isDefined(payload.to)){payload.to=tryStringify(payload.to);}if(isDefined(payload.from)){payload.from=tryStringify(payload.from);}else {payload.from=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
397
367
|
* Normalise the overloaded arguments of the group call facade
|
398
|
-
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const
|
368
|
+
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:groupId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.groupId=groupId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.groupId=groupId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(groupId)||isNull(groupId)){// Explicitly set null to prevent resetting the existing value
|
399
369
|
// in the Analytics class
|
400
|
-
payload.groupId=null;payload.traits=
|
370
|
+
payload.groupId=null;payload.traits=groupId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
401
371
|
// and set some proper defaults
|
402
372
|
// Also, to clone the incoming object type arguments
|
403
373
|
payload.groupId=tryStringify(payload.groupId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};
|
@@ -445,6 +415,36 @@ const getFormattedTimestamp=date=>date.toISOString();/**
|
|
445
415
|
* @returns ISO formatted timestamp string
|
446
416
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
447
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 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]';}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=>// Using a regular function to use `this` for the parent context
|
433
|
+
function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
434
|
+
}return value;};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
435
|
+
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
436
|
+
// eslint-disable-next-line no-restricted-syntax
|
437
|
+
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
438
|
+
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
439
|
+
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
440
|
+
* Recursively traverses an object similar to JSON.stringify,
|
441
|
+
* sanitizing BigInts and circular references
|
442
|
+
* @param value Input object
|
443
|
+
* @param logger Logger instance
|
444
|
+
* @returns Sanitized value
|
445
|
+
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
446
|
+
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
447
|
+
|
448
448
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
449
449
|
* Get mutated error with issue prepended to error message
|
450
450
|
* @param err Original error
|
@@ -452,7 +452,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
|
452
452
|
* @returns Instance of Error with message prepended with issue
|
453
453
|
*/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}));};
|
454
454
|
|
455
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
455
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.4';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';
|
456
456
|
|
457
457
|
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';
|
458
458
|
|