@rudderstack/analytics-js 3.11.0 → 3.11.1
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 +46 -46
- package/dist/npm/legacy/bundled/esm/index.mjs +46 -46
- package/dist/npm/legacy/bundled/umd/index.js +46 -46
- package/dist/npm/legacy/cjs/index.cjs +46 -46
- package/dist/npm/legacy/content-script/cjs/index.cjs +46 -46
- package/dist/npm/legacy/content-script/esm/index.mjs +46 -46
- package/dist/npm/legacy/content-script/umd/index.js +46 -46
- package/dist/npm/legacy/esm/index.mjs +46 -46
- package/dist/npm/legacy/umd/index.js +46 -46
- package/dist/npm/modern/bundled/cjs/index.cjs +46 -46
- package/dist/npm/modern/bundled/esm/index.mjs +46 -46
- package/dist/npm/modern/bundled/umd/index.js +46 -46
- package/dist/npm/modern/cjs/index.cjs +46 -46
- package/dist/npm/modern/content-script/cjs/index.cjs +46 -46
- package/dist/npm/modern/content-script/esm/index.mjs +46 -46
- package/dist/npm/modern/content-script/umd/index.js +46 -46
- package/dist/npm/modern/esm/index.mjs +46 -46
- package/dist/npm/modern/umd/index.js +46 -46
- package/package.json +1 -1
@@ -332,74 +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=>{const ancestors=[];// Array to track ancestor objects
|
350
|
-
// Using a regular function to use `this` for the parent context
|
351
|
-
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
352
|
-
}// `this` is the object that value is contained in, i.e., its direct parent.
|
353
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
354
|
-
// @ts-ignore-next-line
|
355
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
356
|
-
}// Check for circular references (if the value is already in the ancestors)
|
357
|
-
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
358
|
-
ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
359
|
-
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
360
|
-
// eslint-disable-next-line no-restricted-syntax
|
361
|
-
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
362
|
-
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
363
|
-
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
364
|
-
* Recursively traverses an object similar to JSON.stringify,
|
365
|
-
* sanitizing BigInts and circular references
|
366
|
-
* @param value Input object
|
367
|
-
* @param logger Logger instance
|
368
|
-
* @returns Sanitized value
|
369
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
370
|
-
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
371
|
-
|
372
335
|
// if yes make them null instead of omitting in overloaded cases
|
373
336
|
/*
|
374
337
|
* Normalise the overloaded arguments of the page call facade
|
375
|
-
*/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,
|
376
339
|
// use it as name and set category to undefined
|
377
|
-
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
|
378
341
|
// and set some proper defaults
|
379
342
|
// Also, to clone the incoming object type arguments
|
380
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
|
381
344
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
382
345
|
* Normalise the overloaded arguments of the track call facade
|
383
|
-
*/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
|
384
347
|
// and set some proper defaults
|
385
348
|
// Also, to clone the incoming object type arguments
|
386
349
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
387
350
|
* Normalise the overloaded arguments of the identify call facade
|
388
|
-
*/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
|
389
352
|
// in the Analytics class
|
390
|
-
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
|
391
354
|
// and set some proper defaults
|
392
355
|
// Also, to clone the incoming object type arguments
|
393
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;};/*
|
394
357
|
* Normalise the overloaded arguments of the alias call facade
|
395
|
-
*/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
|
396
359
|
// and set some proper defaults
|
397
360
|
// Also, to clone the incoming object type arguments
|
398
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;};/*
|
399
362
|
* Normalise the overloaded arguments of the group call facade
|
400
|
-
*/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
|
401
364
|
// in the Analytics class
|
402
|
-
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
|
403
366
|
// and set some proper defaults
|
404
367
|
// Also, to clone the incoming object type arguments
|
405
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;};
|
@@ -447,6 +410,43 @@ const getFormattedTimestamp=date=>date.toISOString();/**
|
|
447
410
|
* @returns ISO formatted timestamp string
|
448
411
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
449
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=>{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 '[BigInt]';// 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]';}// 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
|
+
|
450
450
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
451
451
|
* Get mutated error with issue prepended to error message
|
452
452
|
* @param err Original error
|
@@ -454,7 +454,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
|
454
454
|
* @returns Instance of Error with message prepended with issue
|
455
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}));};
|
456
456
|
|
457
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
457
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.1';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';
|
458
458
|
|
459
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';
|
460
460
|
|
@@ -341,74 +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=>{const ancestors=[];// Array to track ancestor objects
|
359
|
-
// Using a regular function to use `this` for the parent context
|
360
|
-
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
361
|
-
}// `this` is the object that value is contained in, i.e., its direct parent.
|
362
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
363
|
-
// @ts-ignore-next-line
|
364
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
365
|
-
}// Check for circular references (if the value is already in the ancestors)
|
366
|
-
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
367
|
-
ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
368
|
-
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
369
|
-
// eslint-disable-next-line no-restricted-syntax
|
370
|
-
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
371
|
-
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
372
|
-
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
373
|
-
* Recursively traverses an object similar to JSON.stringify,
|
374
|
-
* sanitizing BigInts and circular references
|
375
|
-
* @param value Input object
|
376
|
-
* @param logger Logger instance
|
377
|
-
* @returns Sanitized value
|
378
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
379
|
-
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
380
|
-
|
381
344
|
// if yes make them null instead of omitting in overloaded cases
|
382
345
|
/*
|
383
346
|
* Normalise the overloaded arguments of the page call facade
|
384
|
-
*/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,
|
385
348
|
// use it as name and set category to undefined
|
386
|
-
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
|
387
350
|
// and set some proper defaults
|
388
351
|
// Also, to clone the incoming object type arguments
|
389
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
|
390
353
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
391
354
|
* Normalise the overloaded arguments of the track call facade
|
392
|
-
*/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
|
393
356
|
// and set some proper defaults
|
394
357
|
// Also, to clone the incoming object type arguments
|
395
358
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
396
359
|
* Normalise the overloaded arguments of the identify call facade
|
397
|
-
*/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
|
398
361
|
// in the Analytics class
|
399
|
-
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
|
400
363
|
// and set some proper defaults
|
401
364
|
// Also, to clone the incoming object type arguments
|
402
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;};/*
|
403
366
|
* Normalise the overloaded arguments of the alias call facade
|
404
|
-
*/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
|
405
368
|
// and set some proper defaults
|
406
369
|
// Also, to clone the incoming object type arguments
|
407
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;};/*
|
408
371
|
* Normalise the overloaded arguments of the group call facade
|
409
|
-
*/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
|
410
373
|
// in the Analytics class
|
411
|
-
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
|
412
375
|
// and set some proper defaults
|
413
376
|
// Also, to clone the incoming object type arguments
|
414
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;};
|
@@ -456,6 +419,43 @@ const getFormattedTimestamp=date=>date.toISOString();/**
|
|
456
419
|
* @returns ISO formatted timestamp string
|
457
420
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
458
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=>{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 '[BigInt]';// 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]';}// 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
|
+
|
459
459
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
460
460
|
* Get mutated error with issue prepended to error message
|
461
461
|
* @param err Original error
|
@@ -463,7 +463,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
|
463
463
|
* @returns Instance of Error with message prepended with issue
|
464
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}));};
|
465
465
|
|
466
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
466
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.1';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';
|
467
467
|
|
468
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';
|
469
469
|
|
@@ -337,74 +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=>{const ancestors=[];// Array to track ancestor objects
|
355
|
-
// Using a regular function to use `this` for the parent context
|
356
|
-
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
357
|
-
}// `this` is the object that value is contained in, i.e., its direct parent.
|
358
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
359
|
-
// @ts-ignore-next-line
|
360
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
361
|
-
}// Check for circular references (if the value is already in the ancestors)
|
362
|
-
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
363
|
-
ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
364
|
-
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
365
|
-
// eslint-disable-next-line no-restricted-syntax
|
366
|
-
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
367
|
-
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
368
|
-
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
369
|
-
* Recursively traverses an object similar to JSON.stringify,
|
370
|
-
* sanitizing BigInts and circular references
|
371
|
-
* @param value Input object
|
372
|
-
* @param logger Logger instance
|
373
|
-
* @returns Sanitized value
|
374
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
375
|
-
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
376
|
-
|
377
340
|
// if yes make them null instead of omitting in overloaded cases
|
378
341
|
/*
|
379
342
|
* Normalise the overloaded arguments of the page call facade
|
380
|
-
*/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,
|
381
344
|
// use it as name and set category to undefined
|
382
|
-
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
|
383
346
|
// and set some proper defaults
|
384
347
|
// Also, to clone the incoming object type arguments
|
385
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
|
386
349
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
387
350
|
* Normalise the overloaded arguments of the track call facade
|
388
|
-
*/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
|
389
352
|
// and set some proper defaults
|
390
353
|
// Also, to clone the incoming object type arguments
|
391
354
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
392
355
|
* Normalise the overloaded arguments of the identify call facade
|
393
|
-
*/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
|
394
357
|
// in the Analytics class
|
395
|
-
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
|
396
359
|
// and set some proper defaults
|
397
360
|
// Also, to clone the incoming object type arguments
|
398
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;};/*
|
399
362
|
* Normalise the overloaded arguments of the alias call facade
|
400
|
-
*/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
|
401
364
|
// and set some proper defaults
|
402
365
|
// Also, to clone the incoming object type arguments
|
403
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;};/*
|
404
367
|
* Normalise the overloaded arguments of the group call facade
|
405
|
-
*/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
|
406
369
|
// in the Analytics class
|
407
|
-
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
|
408
371
|
// and set some proper defaults
|
409
372
|
// Also, to clone the incoming object type arguments
|
410
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;};
|
@@ -452,6 +415,43 @@ const getFormattedTimestamp=date=>date.toISOString();/**
|
|
452
415
|
* @returns ISO formatted timestamp string
|
453
416
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
454
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=>{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 '[BigInt]';// 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]';}// 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
|
+
|
455
455
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
456
456
|
* Get mutated error with issue prepended to error message
|
457
457
|
* @param err Original error
|
@@ -459,7 +459,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
|
459
459
|
* @returns Instance of Error with message prepended with issue
|
460
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}));};
|
461
461
|
|
462
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
462
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.1';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';
|
463
463
|
|
464
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';
|
465
465
|
|