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