@rudderstack/analytics-js 3.11.4 → 3.11.5
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 +41 -39
- package/dist/npm/legacy/bundled/esm/index.mjs +41 -39
- package/dist/npm/legacy/bundled/umd/index.js +41 -39
- package/dist/npm/legacy/cjs/index.cjs +41 -39
- package/dist/npm/legacy/content-script/cjs/index.cjs +41 -39
- package/dist/npm/legacy/content-script/esm/index.mjs +41 -39
- package/dist/npm/legacy/content-script/umd/index.js +41 -39
- package/dist/npm/legacy/esm/index.mjs +41 -39
- package/dist/npm/legacy/umd/index.js +41 -39
- package/dist/npm/modern/bundled/cjs/index.cjs +41 -39
- package/dist/npm/modern/bundled/esm/index.mjs +41 -39
- package/dist/npm/modern/bundled/umd/index.js +41 -39
- package/dist/npm/modern/cjs/index.cjs +41 -39
- package/dist/npm/modern/content-script/cjs/index.cjs +41 -39
- package/dist/npm/modern/content-script/esm/index.mjs +41 -39
- package/dist/npm/modern/content-script/umd/index.js +41 -39
- package/dist/npm/modern/esm/index.mjs +41 -39
- package/dist/npm/modern/umd/index.js +41 -39
- package/package.json +1 -1
@@ -343,37 +343,69 @@
|
|
343
343
|
* @returns decoded string
|
344
344
|
*/const fromBase64=value=>new TextDecoder().decode(base64ToBytes(value));
|
345
345
|
|
346
|
+
const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
|
347
|
+
|
348
|
+
const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
|
349
|
+
// eslint-disable-next-line func-names
|
350
|
+
return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
|
351
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
352
|
+
// @ts-ignore-next-line
|
353
|
+
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
|
354
|
+
* Utility method for JSON stringify object excluding null values & circular references
|
355
|
+
*
|
356
|
+
* @param {*} value input
|
357
|
+
* @param {boolean} excludeNull if it should exclude nul or not
|
358
|
+
* @param {function} logger optional logger methods for warning
|
359
|
+
* @returns string
|
360
|
+
*/const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
|
361
|
+
// Using a regular function to use `this` for the parent context
|
362
|
+
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
363
|
+
}// `this` is the object that value is contained in, i.e., its direct parent.
|
364
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
365
|
+
// @ts-ignore-next-line
|
366
|
+
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
367
|
+
}// Check for circular references (if the value is already in the ancestors)
|
368
|
+
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
369
|
+
ancestors.push(value);return value;};};/**
|
370
|
+
* Recursively traverses an object similar to JSON.stringify,
|
371
|
+
* sanitizing BigInts and circular references
|
372
|
+
* @param value Input object
|
373
|
+
* @param logger Logger instance
|
374
|
+
* @returns Sanitized value
|
375
|
+
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
376
|
+
const newValue=replacer.call(value,'',value);return newValue;};
|
377
|
+
|
346
378
|
// if yes make them null instead of omitting in overloaded cases
|
347
379
|
/*
|
348
380
|
* Normalise the overloaded arguments of the page call facade
|
349
|
-
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:
|
381
|
+
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const sanitizedCategory=getSanitizedValue(category);const sanitizedName=getSanitizedValue(name);const sanitizedProperties=getSanitizedValue(properties);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={category:sanitizedCategory,name:sanitizedName,properties:sanitizedProperties,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.category=sanitizedCategory;payload.name=sanitizedName;payload.properties=sanitizedProperties;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedProperties)){payload.category=sanitizedCategory;payload.name=sanitizedName;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedProperties;}if(isFunction(sanitizedName)){payload.category=sanitizedCategory;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedName;}if(isFunction(sanitizedCategory)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedCategory;}if(isObjectLiteralAndNotNull(sanitizedCategory)){payload.name=undefined;payload.category=undefined;payload.properties=sanitizedCategory;if(!isFunction(sanitizedName)){payload.options=sanitizedName;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(sanitizedName)){payload.name=undefined;payload.properties=sanitizedName;if(!isFunction(sanitizedProperties)){payload.options=sanitizedProperties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
|
350
382
|
// use it as name and set category to undefined
|
351
|
-
if(isString(
|
383
|
+
if(isString(sanitizedCategory)&&!isString(sanitizedName)){payload.category=undefined;payload.name=sanitizedCategory;}// Rest of the code is just to clean up undefined values
|
352
384
|
// and set some proper defaults
|
353
385
|
// Also, to clone the incoming object type arguments
|
354
386
|
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
|
355
387
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
356
388
|
* Normalise the overloaded arguments of the track call facade
|
357
|
-
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:
|
389
|
+
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const sanitizedEvent=getSanitizedValue(event);const sanitizedProperties=getSanitizedValue(properties);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={name:sanitizedEvent,properties:sanitizedProperties,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.properties=sanitizedProperties;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedProperties)){payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedProperties;}// Rest of the code is just to clean up undefined values
|
358
390
|
// and set some proper defaults
|
359
391
|
// Also, to clone the incoming object type arguments
|
360
392
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
361
393
|
* Normalise the overloaded arguments of the identify call facade
|
362
|
-
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:
|
394
|
+
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const sanitizedUserId=getSanitizedValue(userId);const sanitizedTraits=getSanitizedValue(traits);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={userId:sanitizedUserId,traits:sanitizedTraits,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.userId=sanitizedUserId;payload.traits=sanitizedTraits;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedTraits)){payload.userId=sanitizedUserId;payload.traits=undefined;payload.options=undefined;payload.callback=sanitizedTraits;}if(isObjectLiteralAndNotNull(sanitizedUserId)||isNull(sanitizedUserId)){// Explicitly set null to prevent resetting the existing value
|
363
395
|
// in the Analytics class
|
364
|
-
payload.userId=null;payload.traits=
|
396
|
+
payload.userId=null;payload.traits=sanitizedUserId;if(!isFunction(sanitizedTraits)){payload.options=sanitizedTraits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
365
397
|
// and set some proper defaults
|
366
398
|
// Also, to clone the incoming object type arguments
|
367
399
|
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;};/*
|
368
400
|
* Normalise the overloaded arguments of the alias call facade
|
369
|
-
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:
|
401
|
+
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const sanitizedTo=getSanitizedValue(to);const sanitizedFrom=getSanitizedValue(from);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={to:sanitizedTo,from:sanitizedFrom,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.to=sanitizedTo;payload.from=sanitizedFrom;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedFrom)){payload.to=sanitizedTo;payload.from=undefined;payload.options=undefined;payload.callback=sanitizedFrom;}else if(isObjectLiteralAndNotNull(sanitizedFrom)||isNull(sanitizedFrom)){payload.to=sanitizedTo;payload.from=undefined;payload.options=sanitizedFrom;}// Rest of the code is just to clean up undefined values
|
370
402
|
// and set some proper defaults
|
371
403
|
// Also, to clone the incoming object type arguments
|
372
404
|
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;};/*
|
373
405
|
* Normalise the overloaded arguments of the group call facade
|
374
|
-
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:
|
406
|
+
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const sanitizedGroupId=getSanitizedValue(groupId);const sanitizedTraits=getSanitizedValue(traits);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={groupId:sanitizedGroupId,traits:sanitizedTraits,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.groupId=sanitizedGroupId;payload.traits=sanitizedTraits;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedTraits)){payload.groupId=sanitizedGroupId;payload.traits=undefined;payload.options=undefined;payload.callback=sanitizedTraits;}if(isObjectLiteralAndNotNull(sanitizedGroupId)||isNull(sanitizedGroupId)){// Explicitly set null to prevent resetting the existing value
|
375
407
|
// in the Analytics class
|
376
|
-
payload.groupId=null;payload.traits=
|
408
|
+
payload.groupId=null;payload.traits=sanitizedGroupId;if(!isFunction(sanitizedTraits)){payload.options=sanitizedTraits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
377
409
|
// and set some proper defaults
|
378
410
|
// Also, to clone the incoming object type arguments
|
379
411
|
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;};
|
@@ -421,36 +453,6 @@
|
|
421
453
|
* @returns ISO formatted timestamp string
|
422
454
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
423
455
|
|
424
|
-
const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
|
425
|
-
|
426
|
-
const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
|
427
|
-
// eslint-disable-next-line func-names
|
428
|
-
return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
|
429
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
430
|
-
// @ts-ignore-next-line
|
431
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
|
432
|
-
* Utility method for JSON stringify object excluding null values & circular references
|
433
|
-
*
|
434
|
-
* @param {*} value input
|
435
|
-
* @param {boolean} excludeNull if it should exclude nul or not
|
436
|
-
* @param {function} logger optional logger methods for warning
|
437
|
-
* @returns string
|
438
|
-
*/const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>// Using a regular function to use `this` for the parent context
|
439
|
-
function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
440
|
-
}return value;};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
441
|
-
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
442
|
-
// eslint-disable-next-line no-restricted-syntax
|
443
|
-
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
444
|
-
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
445
|
-
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
446
|
-
* Recursively traverses an object similar to JSON.stringify,
|
447
|
-
* sanitizing BigInts and circular references
|
448
|
-
* @param value Input object
|
449
|
-
* @param logger Logger instance
|
450
|
-
* @returns Sanitized value
|
451
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
452
|
-
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
453
|
-
|
454
456
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
455
457
|
* Get mutated error with issue prepended to error message
|
456
458
|
* @param err Original error
|
@@ -458,7 +460,7 @@
|
|
458
460
|
* @returns Instance of Error with message prepended with issue
|
459
461
|
*/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}));};
|
460
462
|
|
461
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
463
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.5';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
|
462
464
|
|
463
465
|
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';
|
464
466
|
|
@@ -328,37 +328,69 @@ const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value
|
|
328
328
|
* @returns base64 encoded string
|
329
329
|
*/const toBase64=value=>bytesToBase64(new TextEncoder().encode(value));
|
330
330
|
|
331
|
+
const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
|
332
|
+
|
333
|
+
const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
|
334
|
+
// eslint-disable-next-line func-names
|
335
|
+
return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
|
336
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
337
|
+
// @ts-ignore-next-line
|
338
|
+
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
|
339
|
+
* Utility method for JSON stringify object excluding null values & circular references
|
340
|
+
*
|
341
|
+
* @param {*} value input
|
342
|
+
* @param {boolean} excludeNull if it should exclude nul or not
|
343
|
+
* @param {function} logger optional logger methods for warning
|
344
|
+
* @returns string
|
345
|
+
*/const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
|
346
|
+
// Using a regular function to use `this` for the parent context
|
347
|
+
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
348
|
+
}// `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();// Remove ancestors that are no longer part of the chain
|
352
|
+
}// Check for circular references (if the value is already in the ancestors)
|
353
|
+
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
354
|
+
ancestors.push(value);return value;};};/**
|
355
|
+
* Recursively traverses an object similar to JSON.stringify,
|
356
|
+
* sanitizing BigInts and circular references
|
357
|
+
* @param value Input object
|
358
|
+
* @param logger Logger instance
|
359
|
+
* @returns Sanitized value
|
360
|
+
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
361
|
+
const newValue=replacer.call(value,'',value);return newValue;};
|
362
|
+
|
331
363
|
// if yes make them null instead of omitting in overloaded cases
|
332
364
|
/*
|
333
365
|
* Normalise the overloaded arguments of the page call facade
|
334
|
-
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:
|
366
|
+
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const sanitizedCategory=getSanitizedValue(category);const sanitizedName=getSanitizedValue(name);const sanitizedProperties=getSanitizedValue(properties);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={category:sanitizedCategory,name:sanitizedName,properties:sanitizedProperties,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.category=sanitizedCategory;payload.name=sanitizedName;payload.properties=sanitizedProperties;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedProperties)){payload.category=sanitizedCategory;payload.name=sanitizedName;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedProperties;}if(isFunction(sanitizedName)){payload.category=sanitizedCategory;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedName;}if(isFunction(sanitizedCategory)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedCategory;}if(isObjectLiteralAndNotNull(sanitizedCategory)){payload.name=undefined;payload.category=undefined;payload.properties=sanitizedCategory;if(!isFunction(sanitizedName)){payload.options=sanitizedName;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(sanitizedName)){payload.name=undefined;payload.properties=sanitizedName;if(!isFunction(sanitizedProperties)){payload.options=sanitizedProperties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
|
335
367
|
// use it as name and set category to undefined
|
336
|
-
if(isString(
|
368
|
+
if(isString(sanitizedCategory)&&!isString(sanitizedName)){payload.category=undefined;payload.name=sanitizedCategory;}// Rest of the code is just to clean up undefined values
|
337
369
|
// and set some proper defaults
|
338
370
|
// Also, to clone the incoming object type arguments
|
339
371
|
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
|
340
372
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
341
373
|
* Normalise the overloaded arguments of the track call facade
|
342
|
-
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:
|
374
|
+
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const sanitizedEvent=getSanitizedValue(event);const sanitizedProperties=getSanitizedValue(properties);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={name:sanitizedEvent,properties:sanitizedProperties,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.properties=sanitizedProperties;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedProperties)){payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedProperties;}// Rest of the code is just to clean up undefined values
|
343
375
|
// and set some proper defaults
|
344
376
|
// Also, to clone the incoming object type arguments
|
345
377
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
346
378
|
* Normalise the overloaded arguments of the identify call facade
|
347
|
-
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:
|
379
|
+
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const sanitizedUserId=getSanitizedValue(userId);const sanitizedTraits=getSanitizedValue(traits);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={userId:sanitizedUserId,traits:sanitizedTraits,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.userId=sanitizedUserId;payload.traits=sanitizedTraits;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedTraits)){payload.userId=sanitizedUserId;payload.traits=undefined;payload.options=undefined;payload.callback=sanitizedTraits;}if(isObjectLiteralAndNotNull(sanitizedUserId)||isNull(sanitizedUserId)){// Explicitly set null to prevent resetting the existing value
|
348
380
|
// in the Analytics class
|
349
|
-
payload.userId=null;payload.traits=
|
381
|
+
payload.userId=null;payload.traits=sanitizedUserId;if(!isFunction(sanitizedTraits)){payload.options=sanitizedTraits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
350
382
|
// and set some proper defaults
|
351
383
|
// Also, to clone the incoming object type arguments
|
352
384
|
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;};/*
|
353
385
|
* Normalise the overloaded arguments of the alias call facade
|
354
|
-
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:
|
386
|
+
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const sanitizedTo=getSanitizedValue(to);const sanitizedFrom=getSanitizedValue(from);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={to:sanitizedTo,from:sanitizedFrom,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.to=sanitizedTo;payload.from=sanitizedFrom;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedFrom)){payload.to=sanitizedTo;payload.from=undefined;payload.options=undefined;payload.callback=sanitizedFrom;}else if(isObjectLiteralAndNotNull(sanitizedFrom)||isNull(sanitizedFrom)){payload.to=sanitizedTo;payload.from=undefined;payload.options=sanitizedFrom;}// Rest of the code is just to clean up undefined values
|
355
387
|
// and set some proper defaults
|
356
388
|
// Also, to clone the incoming object type arguments
|
357
389
|
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;};/*
|
358
390
|
* Normalise the overloaded arguments of the group call facade
|
359
|
-
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:
|
391
|
+
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const sanitizedGroupId=getSanitizedValue(groupId);const sanitizedTraits=getSanitizedValue(traits);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={groupId:sanitizedGroupId,traits:sanitizedTraits,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.groupId=sanitizedGroupId;payload.traits=sanitizedTraits;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedTraits)){payload.groupId=sanitizedGroupId;payload.traits=undefined;payload.options=undefined;payload.callback=sanitizedTraits;}if(isObjectLiteralAndNotNull(sanitizedGroupId)||isNull(sanitizedGroupId)){// Explicitly set null to prevent resetting the existing value
|
360
392
|
// in the Analytics class
|
361
|
-
payload.groupId=null;payload.traits=
|
393
|
+
payload.groupId=null;payload.traits=sanitizedGroupId;if(!isFunction(sanitizedTraits)){payload.options=sanitizedTraits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
362
394
|
// and set some proper defaults
|
363
395
|
// Also, to clone the incoming object type arguments
|
364
396
|
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;};
|
@@ -406,36 +438,6 @@ const getFormattedTimestamp=date=>date.toISOString();/**
|
|
406
438
|
* @returns ISO formatted timestamp string
|
407
439
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
408
440
|
|
409
|
-
const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
|
410
|
-
|
411
|
-
const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
|
412
|
-
// eslint-disable-next-line func-names
|
413
|
-
return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
|
414
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
415
|
-
// @ts-ignore-next-line
|
416
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
|
417
|
-
* Utility method for JSON stringify object excluding null values & circular references
|
418
|
-
*
|
419
|
-
* @param {*} value input
|
420
|
-
* @param {boolean} excludeNull if it should exclude nul or not
|
421
|
-
* @param {function} logger optional logger methods for warning
|
422
|
-
* @returns string
|
423
|
-
*/const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>// Using a regular function to use `this` for the parent context
|
424
|
-
function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
425
|
-
}return value;};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
426
|
-
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
427
|
-
// eslint-disable-next-line no-restricted-syntax
|
428
|
-
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
429
|
-
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
430
|
-
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
431
|
-
* Recursively traverses an object similar to JSON.stringify,
|
432
|
-
* sanitizing BigInts and circular references
|
433
|
-
* @param value Input object
|
434
|
-
* @param logger Logger instance
|
435
|
-
* @returns Sanitized value
|
436
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
437
|
-
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
438
|
-
|
439
441
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
440
442
|
* Get mutated error with issue prepended to error message
|
441
443
|
* @param err Original error
|
@@ -443,7 +445,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
|
443
445
|
* @returns Instance of Error with message prepended with issue
|
444
446
|
*/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}));};
|
445
447
|
|
446
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
448
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.5';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';
|
447
449
|
|
448
450
|
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';
|
449
451
|
|
@@ -334,37 +334,69 @@
|
|
334
334
|
* @returns base64 encoded string
|
335
335
|
*/const toBase64=value=>bytesToBase64(new TextEncoder().encode(value));
|
336
336
|
|
337
|
+
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.`;
|
338
|
+
|
339
|
+
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
|
340
|
+
// eslint-disable-next-line func-names
|
341
|
+
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.
|
342
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
343
|
+
// @ts-ignore-next-line
|
344
|
+
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;};};/**
|
345
|
+
* Utility method for JSON stringify object excluding null values & circular references
|
346
|
+
*
|
347
|
+
* @param {*} value input
|
348
|
+
* @param {boolean} excludeNull if it should exclude nul or not
|
349
|
+
* @param {function} logger optional logger methods for warning
|
350
|
+
* @returns string
|
351
|
+
*/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
|
352
|
+
// Using a regular function to use `this` for the parent context
|
353
|
+
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
354
|
+
}// `this` is the object that value is contained in, i.e., its direct parent.
|
355
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
356
|
+
// @ts-ignore-next-line
|
357
|
+
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
358
|
+
}// Check for circular references (if the value is already in the ancestors)
|
359
|
+
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
360
|
+
ancestors.push(value);return value;};};/**
|
361
|
+
* Recursively traverses an object similar to JSON.stringify,
|
362
|
+
* sanitizing BigInts and circular references
|
363
|
+
* @param value Input object
|
364
|
+
* @param logger Logger instance
|
365
|
+
* @returns Sanitized value
|
366
|
+
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
367
|
+
const newValue=replacer.call(value,'',value);return newValue;};
|
368
|
+
|
337
369
|
// if yes make them null instead of omitting in overloaded cases
|
338
370
|
/*
|
339
371
|
* Normalise the overloaded arguments of the page call facade
|
340
|
-
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:
|
372
|
+
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const sanitizedCategory=getSanitizedValue(category);const sanitizedName=getSanitizedValue(name);const sanitizedProperties=getSanitizedValue(properties);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={category:sanitizedCategory,name:sanitizedName,properties:sanitizedProperties,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.category=sanitizedCategory;payload.name=sanitizedName;payload.properties=sanitizedProperties;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedProperties)){payload.category=sanitizedCategory;payload.name=sanitizedName;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedProperties;}if(isFunction(sanitizedName)){payload.category=sanitizedCategory;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedName;}if(isFunction(sanitizedCategory)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedCategory;}if(isObjectLiteralAndNotNull(sanitizedCategory)){payload.name=undefined;payload.category=undefined;payload.properties=sanitizedCategory;if(!isFunction(sanitizedName)){payload.options=sanitizedName;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(sanitizedName)){payload.name=undefined;payload.properties=sanitizedName;if(!isFunction(sanitizedProperties)){payload.options=sanitizedProperties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
|
341
373
|
// use it as name and set category to undefined
|
342
|
-
if(isString(
|
374
|
+
if(isString(sanitizedCategory)&&!isString(sanitizedName)){payload.category=undefined;payload.name=sanitizedCategory;}// Rest of the code is just to clean up undefined values
|
343
375
|
// and set some proper defaults
|
344
376
|
// Also, to clone the incoming object type arguments
|
345
377
|
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
|
346
378
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
347
379
|
* Normalise the overloaded arguments of the track call facade
|
348
|
-
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:
|
380
|
+
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const sanitizedEvent=getSanitizedValue(event);const sanitizedProperties=getSanitizedValue(properties);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={name:sanitizedEvent,properties:sanitizedProperties,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.properties=sanitizedProperties;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedProperties)){payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedProperties;}// Rest of the code is just to clean up undefined values
|
349
381
|
// and set some proper defaults
|
350
382
|
// Also, to clone the incoming object type arguments
|
351
383
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
352
384
|
* Normalise the overloaded arguments of the identify call facade
|
353
|
-
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:
|
385
|
+
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const sanitizedUserId=getSanitizedValue(userId);const sanitizedTraits=getSanitizedValue(traits);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={userId:sanitizedUserId,traits:sanitizedTraits,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.userId=sanitizedUserId;payload.traits=sanitizedTraits;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedTraits)){payload.userId=sanitizedUserId;payload.traits=undefined;payload.options=undefined;payload.callback=sanitizedTraits;}if(isObjectLiteralAndNotNull(sanitizedUserId)||isNull(sanitizedUserId)){// Explicitly set null to prevent resetting the existing value
|
354
386
|
// in the Analytics class
|
355
|
-
payload.userId=null;payload.traits=
|
387
|
+
payload.userId=null;payload.traits=sanitizedUserId;if(!isFunction(sanitizedTraits)){payload.options=sanitizedTraits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
356
388
|
// and set some proper defaults
|
357
389
|
// Also, to clone the incoming object type arguments
|
358
390
|
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;};/*
|
359
391
|
* Normalise the overloaded arguments of the alias call facade
|
360
|
-
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:
|
392
|
+
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const sanitizedTo=getSanitizedValue(to);const sanitizedFrom=getSanitizedValue(from);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={to:sanitizedTo,from:sanitizedFrom,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.to=sanitizedTo;payload.from=sanitizedFrom;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedFrom)){payload.to=sanitizedTo;payload.from=undefined;payload.options=undefined;payload.callback=sanitizedFrom;}else if(isObjectLiteralAndNotNull(sanitizedFrom)||isNull(sanitizedFrom)){payload.to=sanitizedTo;payload.from=undefined;payload.options=sanitizedFrom;}// Rest of the code is just to clean up undefined values
|
361
393
|
// and set some proper defaults
|
362
394
|
// Also, to clone the incoming object type arguments
|
363
395
|
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;};/*
|
364
396
|
* Normalise the overloaded arguments of the group call facade
|
365
|
-
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:
|
397
|
+
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const sanitizedGroupId=getSanitizedValue(groupId);const sanitizedTraits=getSanitizedValue(traits);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={groupId:sanitizedGroupId,traits:sanitizedTraits,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.groupId=sanitizedGroupId;payload.traits=sanitizedTraits;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedTraits)){payload.groupId=sanitizedGroupId;payload.traits=undefined;payload.options=undefined;payload.callback=sanitizedTraits;}if(isObjectLiteralAndNotNull(sanitizedGroupId)||isNull(sanitizedGroupId)){// Explicitly set null to prevent resetting the existing value
|
366
398
|
// in the Analytics class
|
367
|
-
payload.groupId=null;payload.traits=
|
399
|
+
payload.groupId=null;payload.traits=sanitizedGroupId;if(!isFunction(sanitizedTraits)){payload.options=sanitizedTraits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
368
400
|
// and set some proper defaults
|
369
401
|
// Also, to clone the incoming object type arguments
|
370
402
|
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;};
|
@@ -412,36 +444,6 @@
|
|
412
444
|
* @returns ISO formatted timestamp string
|
413
445
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
414
446
|
|
415
|
-
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.`;
|
416
|
-
|
417
|
-
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
|
418
|
-
// eslint-disable-next-line func-names
|
419
|
-
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.
|
420
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
421
|
-
// @ts-ignore-next-line
|
422
|
-
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;};};/**
|
423
|
-
* Utility method for JSON stringify object excluding null values & circular references
|
424
|
-
*
|
425
|
-
* @param {*} value input
|
426
|
-
* @param {boolean} excludeNull if it should exclude nul or not
|
427
|
-
* @param {function} logger optional logger methods for warning
|
428
|
-
* @returns string
|
429
|
-
*/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
|
430
|
-
function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
431
|
-
}return value;};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
432
|
-
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
433
|
-
// eslint-disable-next-line no-restricted-syntax
|
434
|
-
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
435
|
-
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
436
|
-
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
437
|
-
* Recursively traverses an object similar to JSON.stringify,
|
438
|
-
* sanitizing BigInts and circular references
|
439
|
-
* @param value Input object
|
440
|
-
* @param logger Logger instance
|
441
|
-
* @returns Sanitized value
|
442
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
443
|
-
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
444
|
-
|
445
447
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
446
448
|
* Get mutated error with issue prepended to error message
|
447
449
|
* @param err Original error
|
@@ -449,7 +451,7 @@
|
|
449
451
|
* @returns Instance of Error with message prepended with issue
|
450
452
|
*/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}));};
|
451
453
|
|
452
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
454
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.5';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
|
453
455
|
|
454
456
|
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';
|
455
457
|
|