@rudderstack/analytics-js 3.11.5 → 3.11.7
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 +19 -0
- package/dist/npm/legacy/bundled/cjs/index.cjs +48 -43
- package/dist/npm/legacy/bundled/esm/index.mjs +48 -43
- package/dist/npm/legacy/bundled/umd/index.js +48 -43
- package/dist/npm/legacy/cjs/index.cjs +48 -43
- package/dist/npm/legacy/content-script/cjs/index.cjs +48 -43
- package/dist/npm/legacy/content-script/esm/index.mjs +48 -43
- package/dist/npm/legacy/content-script/umd/index.js +48 -43
- package/dist/npm/legacy/esm/index.mjs +48 -43
- package/dist/npm/legacy/umd/index.js +48 -43
- package/dist/npm/modern/bundled/cjs/index.cjs +48 -43
- package/dist/npm/modern/bundled/esm/index.mjs +48 -43
- package/dist/npm/modern/bundled/umd/index.js +48 -43
- package/dist/npm/modern/cjs/index.cjs +47 -42
- package/dist/npm/modern/content-script/cjs/index.cjs +48 -43
- package/dist/npm/modern/content-script/esm/index.mjs +48 -43
- package/dist/npm/modern/content-script/umd/index.js +48 -43
- package/dist/npm/modern/esm/index.mjs +47 -42
- package/dist/npm/modern/umd/index.js +47 -42
- package/package.json +1 -1
@@ -294,6 +294,8 @@ const isFunction=value=>typeof value==='function'&&Boolean(value.constructor&&va
|
|
294
294
|
* @returns true if the input is an instance of Error and false otherwise
|
295
295
|
*/const isTypeOfError=obj=>obj instanceof Error;
|
296
296
|
|
297
|
+
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.`;
|
298
|
+
|
297
299
|
const getValueByPath=(obj,keyPath)=>{const pathParts=keyPath.split('.');return path(pathParts,obj);};const hasValueByPath=(obj,path)=>Boolean(getValueByPath(obj,path));const isObject=value=>typeof value==='object';/**
|
298
300
|
* Checks if the input is an object literal or built-in object type and not null
|
299
301
|
* @param value Input value
|
@@ -315,7 +317,28 @@ mergeDeepRight(mergedArray[index],value):value;});return mergedArray;};const mer
|
|
315
317
|
* A utility to recursively remove undefined and null values from an object
|
316
318
|
* @param obj input object
|
317
319
|
* @returns a new object
|
318
|
-
*/const removeUndefinedAndNullValues=obj=>{const result=pickBy(isDefinedAndNotNull,obj);Object.keys(result).forEach(key=>{const value=result[key];if(isObjectLiteralAndNotNull(value)){result[key]=removeUndefinedAndNullValues(value);}});return result;};
|
320
|
+
*/const removeUndefinedAndNullValues=obj=>{const result=pickBy(isDefinedAndNotNull,obj);Object.keys(result).forEach(key=>{const value=result[key];if(isObjectLiteralAndNotNull(value)){result[key]=removeUndefinedAndNullValues(value);}});return result;};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
|
321
|
+
// Using a regular function to use `this` for the parent context
|
322
|
+
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
323
|
+
}// `this` is the object that value is contained in, i.e., its direct parent.
|
324
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
325
|
+
// @ts-ignore-next-line
|
326
|
+
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
327
|
+
}// Check for circular references (if the value is already in the ancestors)
|
328
|
+
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
329
|
+
ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
330
|
+
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
331
|
+
// eslint-disable-next-line no-restricted-syntax
|
332
|
+
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
333
|
+
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
334
|
+
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
335
|
+
* Recursively traverses an object similar to JSON.stringify,
|
336
|
+
* sanitizing BigInts and circular references
|
337
|
+
* @param value Input object
|
338
|
+
* @param logger Logger instance
|
339
|
+
* @returns Sanitized value
|
340
|
+
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
341
|
+
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
319
342
|
|
320
343
|
const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value=>value.replace(/ {2,}/g,' ');const removeLeadingPeriod=value=>value.replace(/^\.+/,'');/**
|
321
344
|
* A function to convert values to string
|
@@ -332,69 +355,37 @@ const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value
|
|
332
355
|
* @returns base64 encoded string
|
333
356
|
*/const toBase64=value=>bytesToBase64(new TextEncoder().encode(value));
|
334
357
|
|
335
|
-
const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
|
336
|
-
|
337
|
-
const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
|
338
|
-
// eslint-disable-next-line func-names
|
339
|
-
return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
|
340
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
341
|
-
// @ts-ignore-next-line
|
342
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
|
343
|
-
* Utility method for JSON stringify object excluding null values & circular references
|
344
|
-
*
|
345
|
-
* @param {*} value input
|
346
|
-
* @param {boolean} excludeNull if it should exclude nul or not
|
347
|
-
* @param {function} logger optional logger methods for warning
|
348
|
-
* @returns string
|
349
|
-
*/const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
|
350
|
-
// Using a regular function to use `this` for the parent context
|
351
|
-
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
352
|
-
}// `this` is the object that value is contained in, i.e., its direct parent.
|
353
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
354
|
-
// @ts-ignore-next-line
|
355
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
356
|
-
}// Check for circular references (if the value is already in the ancestors)
|
357
|
-
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
358
|
-
ancestors.push(value);return value;};};/**
|
359
|
-
* Recursively traverses an object similar to JSON.stringify,
|
360
|
-
* sanitizing BigInts and circular references
|
361
|
-
* @param value Input object
|
362
|
-
* @param logger Logger instance
|
363
|
-
* @returns Sanitized value
|
364
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
365
|
-
const newValue=replacer.call(value,'',value);return newValue;};
|
366
|
-
|
367
358
|
// if yes make them null instead of omitting in overloaded cases
|
368
359
|
/*
|
369
360
|
* Normalise the overloaded arguments of the page call facade
|
370
|
-
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const
|
361
|
+
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
|
371
362
|
// use it as name and set category to undefined
|
372
|
-
if(isString(
|
363
|
+
if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
|
373
364
|
// and set some proper defaults
|
374
365
|
// Also, to clone the incoming object type arguments
|
375
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
|
376
367
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
377
368
|
* Normalise the overloaded arguments of the track call facade
|
378
|
-
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const
|
369
|
+
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:event,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.properties=undefined;payload.options=undefined;payload.callback=properties;}// Rest of the code is just to clean up undefined values
|
379
370
|
// and set some proper defaults
|
380
371
|
// Also, to clone the incoming object type arguments
|
381
372
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
382
373
|
* Normalise the overloaded arguments of the identify call facade
|
383
|
-
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const
|
374
|
+
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:userId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.userId=userId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.userId=userId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(userId)||isNull(userId)){// Explicitly set null to prevent resetting the existing value
|
384
375
|
// in the Analytics class
|
385
|
-
payload.userId=null;payload.traits=
|
376
|
+
payload.userId=null;payload.traits=userId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
386
377
|
// and set some proper defaults
|
387
378
|
// Also, to clone the incoming object type arguments
|
388
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;};/*
|
389
380
|
* Normalise the overloaded arguments of the alias call facade
|
390
|
-
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const
|
381
|
+
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:from,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.to=to;payload.from=from;payload.options=undefined;payload.callback=options;}if(isFunction(from)){payload.to=to;payload.from=undefined;payload.options=undefined;payload.callback=from;}else if(isObjectLiteralAndNotNull(from)||isNull(from)){payload.to=to;payload.from=undefined;payload.options=from;}// Rest of the code is just to clean up undefined values
|
391
382
|
// and set some proper defaults
|
392
383
|
// Also, to clone the incoming object type arguments
|
393
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;};/*
|
394
385
|
* Normalise the overloaded arguments of the group call facade
|
395
|
-
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const
|
386
|
+
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:groupId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.groupId=groupId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.groupId=groupId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(groupId)||isNull(groupId)){// Explicitly set null to prevent resetting the existing value
|
396
387
|
// in the Analytics class
|
397
|
-
payload.groupId=null;payload.traits=
|
388
|
+
payload.groupId=null;payload.traits=groupId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
398
389
|
// and set some proper defaults
|
399
390
|
// Also, to clone the incoming object type arguments
|
400
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;};
|
@@ -442,6 +433,20 @@ const getFormattedTimestamp=date=>date.toISOString();/**
|
|
442
433
|
* @returns ISO formatted timestamp string
|
443
434
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
444
435
|
|
436
|
+
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
|
437
|
+
// eslint-disable-next-line func-names
|
438
|
+
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.
|
439
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
440
|
+
// @ts-ignore-next-line
|
441
|
+
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;};};/**
|
442
|
+
* Utility method for JSON stringify object excluding null values & circular references
|
443
|
+
*
|
444
|
+
* @param {*} value input
|
445
|
+
* @param {boolean} excludeNull if it should exclude nul or not
|
446
|
+
* @param {function} logger optional logger methods for warning
|
447
|
+
* @returns string
|
448
|
+
*/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;}};
|
449
|
+
|
445
450
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
446
451
|
* Get mutated error with issue prepended to error message
|
447
452
|
* @param err Original error
|
@@ -449,7 +454,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
|
449
454
|
* @returns Instance of Error with message prepended with issue
|
450
455
|
*/const getMutatedError=(err,issue)=>{let finalError=err;if(!isTypeOfError(err)){finalError=new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}else {finalError.message=`${issue}: ${err.message}`;}return finalError;};const dispatchErrorEvent=error=>{if(isTypeOfError(error)){error.stack=`${error.stack??''}\n${MANUAL_ERROR_IDENTIFIER}`;}globalThis.dispatchEvent(new ErrorEvent('error',{error}));};
|
451
456
|
|
452
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
457
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.7';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
458
|
|
454
459
|
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
|
455
460
|
|
@@ -294,6 +294,8 @@ const isFunction=value=>typeof value==='function'&&Boolean(value.constructor&&va
|
|
294
294
|
* @returns true if the input is an instance of Error and false otherwise
|
295
295
|
*/const isTypeOfError=obj=>obj instanceof Error;
|
296
296
|
|
297
|
+
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.`;
|
298
|
+
|
297
299
|
const getValueByPath=(obj,keyPath)=>{const pathParts=keyPath.split('.');return path(pathParts,obj);};const hasValueByPath=(obj,path)=>Boolean(getValueByPath(obj,path));const isObject=value=>typeof value==='object';/**
|
298
300
|
* Checks if the input is an object literal or built-in object type and not null
|
299
301
|
* @param value Input value
|
@@ -315,7 +317,28 @@ mergeDeepRight(mergedArray[index],value):value;});return mergedArray;};const mer
|
|
315
317
|
* A utility to recursively remove undefined and null values from an object
|
316
318
|
* @param obj input object
|
317
319
|
* @returns a new object
|
318
|
-
*/const removeUndefinedAndNullValues=obj=>{const result=pickBy(isDefinedAndNotNull,obj);Object.keys(result).forEach(key=>{const value=result[key];if(isObjectLiteralAndNotNull(value)){result[key]=removeUndefinedAndNullValues(value);}});return result;};
|
320
|
+
*/const removeUndefinedAndNullValues=obj=>{const result=pickBy(isDefinedAndNotNull,obj);Object.keys(result).forEach(key=>{const value=result[key];if(isObjectLiteralAndNotNull(value)){result[key]=removeUndefinedAndNullValues(value);}});return result;};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
|
321
|
+
// Using a regular function to use `this` for the parent context
|
322
|
+
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
323
|
+
}// `this` is the object that value is contained in, i.e., its direct parent.
|
324
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
325
|
+
// @ts-ignore-next-line
|
326
|
+
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
327
|
+
}// Check for circular references (if the value is already in the ancestors)
|
328
|
+
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
329
|
+
ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
330
|
+
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
331
|
+
// eslint-disable-next-line no-restricted-syntax
|
332
|
+
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
333
|
+
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
334
|
+
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
335
|
+
* Recursively traverses an object similar to JSON.stringify,
|
336
|
+
* sanitizing BigInts and circular references
|
337
|
+
* @param value Input object
|
338
|
+
* @param logger Logger instance
|
339
|
+
* @returns Sanitized value
|
340
|
+
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
341
|
+
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
319
342
|
|
320
343
|
const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value=>value.replace(/ {2,}/g,' ');const removeLeadingPeriod=value=>value.replace(/^\.+/,'');/**
|
321
344
|
* A function to convert values to string
|
@@ -341,69 +364,37 @@ const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value
|
|
341
364
|
* @returns decoded string
|
342
365
|
*/const fromBase64=value=>new TextDecoder().decode(base64ToBytes(value));
|
343
366
|
|
344
|
-
const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
|
345
|
-
|
346
|
-
const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
|
347
|
-
// eslint-disable-next-line func-names
|
348
|
-
return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
|
349
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
350
|
-
// @ts-ignore-next-line
|
351
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
|
352
|
-
* Utility method for JSON stringify object excluding null values & circular references
|
353
|
-
*
|
354
|
-
* @param {*} value input
|
355
|
-
* @param {boolean} excludeNull if it should exclude nul or not
|
356
|
-
* @param {function} logger optional logger methods for warning
|
357
|
-
* @returns string
|
358
|
-
*/const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
|
359
|
-
// Using a regular function to use `this` for the parent context
|
360
|
-
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
361
|
-
}// `this` is the object that value is contained in, i.e., its direct parent.
|
362
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
363
|
-
// @ts-ignore-next-line
|
364
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
365
|
-
}// Check for circular references (if the value is already in the ancestors)
|
366
|
-
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
367
|
-
ancestors.push(value);return value;};};/**
|
368
|
-
* Recursively traverses an object similar to JSON.stringify,
|
369
|
-
* sanitizing BigInts and circular references
|
370
|
-
* @param value Input object
|
371
|
-
* @param logger Logger instance
|
372
|
-
* @returns Sanitized value
|
373
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
374
|
-
const newValue=replacer.call(value,'',value);return newValue;};
|
375
|
-
|
376
367
|
// if yes make them null instead of omitting in overloaded cases
|
377
368
|
/*
|
378
369
|
* Normalise the overloaded arguments of the page call facade
|
379
|
-
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const
|
370
|
+
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
|
380
371
|
// use it as name and set category to undefined
|
381
|
-
if(isString(
|
372
|
+
if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
|
382
373
|
// and set some proper defaults
|
383
374
|
// Also, to clone the incoming object type arguments
|
384
375
|
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
|
385
376
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
386
377
|
* Normalise the overloaded arguments of the track call facade
|
387
|
-
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const
|
378
|
+
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:event,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.properties=undefined;payload.options=undefined;payload.callback=properties;}// Rest of the code is just to clean up undefined values
|
388
379
|
// and set some proper defaults
|
389
380
|
// Also, to clone the incoming object type arguments
|
390
381
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
391
382
|
* Normalise the overloaded arguments of the identify call facade
|
392
|
-
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const
|
383
|
+
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:userId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.userId=userId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.userId=userId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(userId)||isNull(userId)){// Explicitly set null to prevent resetting the existing value
|
393
384
|
// in the Analytics class
|
394
|
-
payload.userId=null;payload.traits=
|
385
|
+
payload.userId=null;payload.traits=userId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
395
386
|
// and set some proper defaults
|
396
387
|
// Also, to clone the incoming object type arguments
|
397
388
|
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;};/*
|
398
389
|
* Normalise the overloaded arguments of the alias call facade
|
399
|
-
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const
|
390
|
+
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:from,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.to=to;payload.from=from;payload.options=undefined;payload.callback=options;}if(isFunction(from)){payload.to=to;payload.from=undefined;payload.options=undefined;payload.callback=from;}else if(isObjectLiteralAndNotNull(from)||isNull(from)){payload.to=to;payload.from=undefined;payload.options=from;}// Rest of the code is just to clean up undefined values
|
400
391
|
// and set some proper defaults
|
401
392
|
// Also, to clone the incoming object type arguments
|
402
393
|
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;};/*
|
403
394
|
* Normalise the overloaded arguments of the group call facade
|
404
|
-
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const
|
395
|
+
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:groupId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.groupId=groupId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.groupId=groupId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(groupId)||isNull(groupId)){// Explicitly set null to prevent resetting the existing value
|
405
396
|
// in the Analytics class
|
406
|
-
payload.groupId=null;payload.traits=
|
397
|
+
payload.groupId=null;payload.traits=groupId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
407
398
|
// and set some proper defaults
|
408
399
|
// Also, to clone the incoming object type arguments
|
409
400
|
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;};
|
@@ -451,6 +442,20 @@ const getFormattedTimestamp=date=>date.toISOString();/**
|
|
451
442
|
* @returns ISO formatted timestamp string
|
452
443
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
453
444
|
|
445
|
+
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
|
446
|
+
// eslint-disable-next-line func-names
|
447
|
+
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.
|
448
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
449
|
+
// @ts-ignore-next-line
|
450
|
+
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;};};/**
|
451
|
+
* Utility method for JSON stringify object excluding null values & circular references
|
452
|
+
*
|
453
|
+
* @param {*} value input
|
454
|
+
* @param {boolean} excludeNull if it should exclude nul or not
|
455
|
+
* @param {function} logger optional logger methods for warning
|
456
|
+
* @returns string
|
457
|
+
*/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;}};
|
458
|
+
|
454
459
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
455
460
|
* Get mutated error with issue prepended to error message
|
456
461
|
* @param err Original error
|
@@ -458,7 +463,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
|
458
463
|
* @returns Instance of Error with message prepended with issue
|
459
464
|
*/const getMutatedError=(err,issue)=>{let finalError=err;if(!isTypeOfError(err)){finalError=new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}else {finalError.message=`${issue}: ${err.message}`;}return finalError;};const dispatchErrorEvent=error=>{if(isTypeOfError(error)){error.stack=`${error.stack??''}\n${MANUAL_ERROR_IDENTIFIER}`;}globalThis.dispatchEvent(new ErrorEvent('error',{error}));};
|
460
465
|
|
461
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
466
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.7';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
467
|
|
463
468
|
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
|
464
469
|
|
@@ -706,7 +711,7 @@ const removeDuplicateSlashes=str=>str.replace(/\/{2,}/g,'/');/**
|
|
706
711
|
if(isFunction(globalThis.URL)){// eslint-disable-next-line no-new
|
707
712
|
new URL(url);}return URL_PATTERN.test(url);}catch(e){return false;}};
|
708
713
|
|
709
|
-
const isErrRetryable=details=>{let isRetryableNWFailure=false;if(details?.error&&details?.xhr){const xhrStatus=details.xhr.status;// same as in v1.1
|
714
|
+
const isErrRetryable=details=>{let isRetryableNWFailure=false;if(details?.error&&details?.xhr){const xhrStatus=getSanitizedValue(details.xhr).status;// same as in v1.1
|
710
715
|
isRetryableNWFailure=xhrStatus===429||xhrStatus>=500&&xhrStatus<600;}return isRetryableNWFailure;};
|
711
716
|
|
712
717
|
const userIdKey='rl_user_id';const userTraitsKey='rl_trait';const anonymousUserIdKey='rl_anonymous_id';const groupIdKey='rl_group_id';const groupTraitsKey='rl_group_trait';const pageInitialReferrerKey='rl_page_init_referrer';const pageInitialReferringDomainKey='rl_page_init_referring_domain';const sessionInfoKey='rl_session';const authTokenKey='rl_auth_token';const COOKIE_KEYS={userId:userIdKey,userTraits:userTraitsKey,anonymousId:anonymousUserIdKey,groupId:groupIdKey,groupTraits:groupTraitsKey,initialReferrer:pageInitialReferrerKey,initialReferringDomain:pageInitialReferringDomainKey,sessionInfo:sessionInfoKey,authToken:authTokenKey};const ENCRYPTION_PREFIX_V3='RS_ENC_v3_';
|
@@ -290,6 +290,8 @@ const isFunction=value=>typeof value==='function'&&Boolean(value.constructor&&va
|
|
290
290
|
* @returns true if the input is an instance of Error and false otherwise
|
291
291
|
*/const isTypeOfError=obj=>obj instanceof Error;
|
292
292
|
|
293
|
+
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.`;
|
294
|
+
|
293
295
|
const getValueByPath=(obj,keyPath)=>{const pathParts=keyPath.split('.');return path(pathParts,obj);};const hasValueByPath=(obj,path)=>Boolean(getValueByPath(obj,path));const isObject=value=>typeof value==='object';/**
|
294
296
|
* Checks if the input is an object literal or built-in object type and not null
|
295
297
|
* @param value Input value
|
@@ -311,7 +313,28 @@ mergeDeepRight(mergedArray[index],value):value;});return mergedArray;};const mer
|
|
311
313
|
* A utility to recursively remove undefined and null values from an object
|
312
314
|
* @param obj input object
|
313
315
|
* @returns a new object
|
314
|
-
*/const removeUndefinedAndNullValues=obj=>{const result=pickBy(isDefinedAndNotNull,obj);Object.keys(result).forEach(key=>{const value=result[key];if(isObjectLiteralAndNotNull(value)){result[key]=removeUndefinedAndNullValues(value);}});return result;};
|
316
|
+
*/const removeUndefinedAndNullValues=obj=>{const result=pickBy(isDefinedAndNotNull,obj);Object.keys(result).forEach(key=>{const value=result[key];if(isObjectLiteralAndNotNull(value)){result[key]=removeUndefinedAndNullValues(value);}});return result;};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
|
317
|
+
// Using a regular function to use `this` for the parent context
|
318
|
+
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
319
|
+
}// `this` is the object that value is contained in, i.e., its direct parent.
|
320
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
321
|
+
// @ts-ignore-next-line
|
322
|
+
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
323
|
+
}// Check for circular references (if the value is already in the ancestors)
|
324
|
+
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
325
|
+
ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
326
|
+
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
327
|
+
// eslint-disable-next-line no-restricted-syntax
|
328
|
+
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
329
|
+
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
330
|
+
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
331
|
+
* Recursively traverses an object similar to JSON.stringify,
|
332
|
+
* sanitizing BigInts and circular references
|
333
|
+
* @param value Input object
|
334
|
+
* @param logger Logger instance
|
335
|
+
* @returns Sanitized value
|
336
|
+
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
337
|
+
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
315
338
|
|
316
339
|
const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value=>value.replace(/ {2,}/g,' ');const removeLeadingPeriod=value=>value.replace(/^\.+/,'');/**
|
317
340
|
* A function to convert values to string
|
@@ -337,69 +360,37 @@ const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value
|
|
337
360
|
* @returns decoded string
|
338
361
|
*/const fromBase64=value=>new TextDecoder().decode(base64ToBytes(value));
|
339
362
|
|
340
|
-
const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
|
341
|
-
|
342
|
-
const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
|
343
|
-
// eslint-disable-next-line func-names
|
344
|
-
return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
|
345
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
346
|
-
// @ts-ignore-next-line
|
347
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
|
348
|
-
* Utility method for JSON stringify object excluding null values & circular references
|
349
|
-
*
|
350
|
-
* @param {*} value input
|
351
|
-
* @param {boolean} excludeNull if it should exclude nul or not
|
352
|
-
* @param {function} logger optional logger methods for warning
|
353
|
-
* @returns string
|
354
|
-
*/const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
|
355
|
-
// Using a regular function to use `this` for the parent context
|
356
|
-
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
357
|
-
}// `this` is the object that value is contained in, i.e., its direct parent.
|
358
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
359
|
-
// @ts-ignore-next-line
|
360
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
361
|
-
}// Check for circular references (if the value is already in the ancestors)
|
362
|
-
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
363
|
-
ancestors.push(value);return value;};};/**
|
364
|
-
* Recursively traverses an object similar to JSON.stringify,
|
365
|
-
* sanitizing BigInts and circular references
|
366
|
-
* @param value Input object
|
367
|
-
* @param logger Logger instance
|
368
|
-
* @returns Sanitized value
|
369
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
370
|
-
const newValue=replacer.call(value,'',value);return newValue;};
|
371
|
-
|
372
363
|
// if yes make them null instead of omitting in overloaded cases
|
373
364
|
/*
|
374
365
|
* Normalise the overloaded arguments of the page call facade
|
375
|
-
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const
|
366
|
+
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
|
376
367
|
// use it as name and set category to undefined
|
377
|
-
if(isString(
|
368
|
+
if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
|
378
369
|
// and set some proper defaults
|
379
370
|
// Also, to clone the incoming object type arguments
|
380
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
|
381
372
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
382
373
|
* Normalise the overloaded arguments of the track call facade
|
383
|
-
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const
|
374
|
+
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:event,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.properties=undefined;payload.options=undefined;payload.callback=properties;}// Rest of the code is just to clean up undefined values
|
384
375
|
// and set some proper defaults
|
385
376
|
// Also, to clone the incoming object type arguments
|
386
377
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
387
378
|
* Normalise the overloaded arguments of the identify call facade
|
388
|
-
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const
|
379
|
+
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:userId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.userId=userId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.userId=userId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(userId)||isNull(userId)){// Explicitly set null to prevent resetting the existing value
|
389
380
|
// in the Analytics class
|
390
|
-
payload.userId=null;payload.traits=
|
381
|
+
payload.userId=null;payload.traits=userId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
391
382
|
// and set some proper defaults
|
392
383
|
// Also, to clone the incoming object type arguments
|
393
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;};/*
|
394
385
|
* Normalise the overloaded arguments of the alias call facade
|
395
|
-
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const
|
386
|
+
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:from,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.to=to;payload.from=from;payload.options=undefined;payload.callback=options;}if(isFunction(from)){payload.to=to;payload.from=undefined;payload.options=undefined;payload.callback=from;}else if(isObjectLiteralAndNotNull(from)||isNull(from)){payload.to=to;payload.from=undefined;payload.options=from;}// Rest of the code is just to clean up undefined values
|
396
387
|
// and set some proper defaults
|
397
388
|
// Also, to clone the incoming object type arguments
|
398
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;};/*
|
399
390
|
* Normalise the overloaded arguments of the group call facade
|
400
|
-
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const
|
391
|
+
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:groupId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.groupId=groupId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.groupId=groupId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(groupId)||isNull(groupId)){// Explicitly set null to prevent resetting the existing value
|
401
392
|
// in the Analytics class
|
402
|
-
payload.groupId=null;payload.traits=
|
393
|
+
payload.groupId=null;payload.traits=groupId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
|
403
394
|
// and set some proper defaults
|
404
395
|
// Also, to clone the incoming object type arguments
|
405
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;};
|
@@ -447,6 +438,20 @@ const getFormattedTimestamp=date=>date.toISOString();/**
|
|
447
438
|
* @returns ISO formatted timestamp string
|
448
439
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
449
440
|
|
441
|
+
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
|
442
|
+
// eslint-disable-next-line func-names
|
443
|
+
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.
|
444
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
445
|
+
// @ts-ignore-next-line
|
446
|
+
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;};};/**
|
447
|
+
* Utility method for JSON stringify object excluding null values & circular references
|
448
|
+
*
|
449
|
+
* @param {*} value input
|
450
|
+
* @param {boolean} excludeNull if it should exclude nul or not
|
451
|
+
* @param {function} logger optional logger methods for warning
|
452
|
+
* @returns string
|
453
|
+
*/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;}};
|
454
|
+
|
450
455
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
451
456
|
* Get mutated error with issue prepended to error message
|
452
457
|
* @param err Original error
|
@@ -454,7 +459,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
|
454
459
|
* @returns Instance of Error with message prepended with issue
|
455
460
|
*/const getMutatedError=(err,issue)=>{let finalError=err;if(!isTypeOfError(err)){finalError=new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}else {finalError.message=`${issue}: ${err.message}`;}return finalError;};const dispatchErrorEvent=error=>{if(isTypeOfError(error)){error.stack=`${error.stack??''}\n${MANUAL_ERROR_IDENTIFIER}`;}globalThis.dispatchEvent(new ErrorEvent('error',{error}));};
|
456
461
|
|
457
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
462
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.7';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
|
458
463
|
|
459
464
|
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
|
460
465
|
|
@@ -702,7 +707,7 @@ const removeDuplicateSlashes=str=>str.replace(/\/{2,}/g,'/');/**
|
|
702
707
|
if(isFunction(globalThis.URL)){// eslint-disable-next-line no-new
|
703
708
|
new URL(url);}return URL_PATTERN.test(url);}catch(e){return false;}};
|
704
709
|
|
705
|
-
const isErrRetryable=details=>{let isRetryableNWFailure=false;if(details?.error&&details?.xhr){const xhrStatus=details.xhr.status;// same as in v1.1
|
710
|
+
const isErrRetryable=details=>{let isRetryableNWFailure=false;if(details?.error&&details?.xhr){const xhrStatus=getSanitizedValue(details.xhr).status;// same as in v1.1
|
706
711
|
isRetryableNWFailure=xhrStatus===429||xhrStatus>=500&&xhrStatus<600;}return isRetryableNWFailure;};
|
707
712
|
|
708
713
|
const userIdKey='rl_user_id';const userTraitsKey='rl_trait';const anonymousUserIdKey='rl_anonymous_id';const groupIdKey='rl_group_id';const groupTraitsKey='rl_group_trait';const pageInitialReferrerKey='rl_page_init_referrer';const pageInitialReferringDomainKey='rl_page_init_referring_domain';const sessionInfoKey='rl_session';const authTokenKey='rl_auth_token';const COOKIE_KEYS={userId:userIdKey,userTraits:userTraitsKey,anonymousId:anonymousUserIdKey,groupId:groupIdKey,groupTraits:groupTraitsKey,initialReferrer:pageInitialReferrerKey,initialReferringDomain:pageInitialReferringDomainKey,sessionInfo:sessionInfoKey,authToken:authTokenKey};const ENCRYPTION_PREFIX_V3='RS_ENC_v3_';
|