@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
@@ -296,6 +296,8 @@
|
|
296
296
|
* @returns true if the input is an instance of Error and false otherwise
|
297
297
|
*/const isTypeOfError=obj=>obj instanceof Error;
|
298
298
|
|
299
|
+
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.`;
|
300
|
+
|
299
301
|
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';/**
|
300
302
|
* Checks if the input is an object literal or built-in object type and not null
|
301
303
|
* @param value Input value
|
@@ -317,7 +319,28 @@
|
|
317
319
|
* A utility to recursively remove undefined and null values from an object
|
318
320
|
* @param obj input object
|
319
321
|
* @returns a new object
|
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;};
|
322
|
+
*/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
|
323
|
+
// Using a regular function to use `this` for the parent context
|
324
|
+
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
325
|
+
}// `this` is the object that value is contained in, i.e., its direct parent.
|
326
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
327
|
+
// @ts-ignore-next-line
|
328
|
+
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
329
|
+
}// Check for circular references (if the value is already in the ancestors)
|
330
|
+
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
331
|
+
ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
332
|
+
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
333
|
+
// eslint-disable-next-line no-restricted-syntax
|
334
|
+
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
335
|
+
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
336
|
+
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
337
|
+
* Recursively traverses an object similar to JSON.stringify,
|
338
|
+
* sanitizing BigInts and circular references
|
339
|
+
* @param value Input object
|
340
|
+
* @param logger Logger instance
|
341
|
+
* @returns Sanitized value
|
342
|
+
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
343
|
+
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
321
344
|
|
322
345
|
const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value=>value.replace(/ {2,}/g,' ');const removeLeadingPeriod=value=>value.replace(/^\.+/,'');/**
|
323
346
|
* A function to convert values to string
|
@@ -343,69 +366,37 @@
|
|
343
366
|
* @returns decoded string
|
344
367
|
*/const fromBase64=value=>new TextDecoder().decode(base64ToBytes(value));
|
345
368
|
|
346
|
-
const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
|
347
|
-
|
348
|
-
const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
|
349
|
-
// eslint-disable-next-line func-names
|
350
|
-
return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
|
351
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
352
|
-
// @ts-ignore-next-line
|
353
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
|
354
|
-
* Utility method for JSON stringify object excluding null values & circular references
|
355
|
-
*
|
356
|
-
* @param {*} value input
|
357
|
-
* @param {boolean} excludeNull if it should exclude nul or not
|
358
|
-
* @param {function} logger optional logger methods for warning
|
359
|
-
* @returns string
|
360
|
-
*/const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
|
361
|
-
// Using a regular function to use `this` for the parent context
|
362
|
-
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
363
|
-
}// `this` is the object that value is contained in, i.e., its direct parent.
|
364
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
365
|
-
// @ts-ignore-next-line
|
366
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
367
|
-
}// Check for circular references (if the value is already in the ancestors)
|
368
|
-
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
369
|
-
ancestors.push(value);return value;};};/**
|
370
|
-
* Recursively traverses an object similar to JSON.stringify,
|
371
|
-
* sanitizing BigInts and circular references
|
372
|
-
* @param value Input object
|
373
|
-
* @param logger Logger instance
|
374
|
-
* @returns Sanitized value
|
375
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
376
|
-
const newValue=replacer.call(value,'',value);return newValue;};
|
377
|
-
|
378
369
|
// if yes make them null instead of omitting in overloaded cases
|
379
370
|
/*
|
380
371
|
* Normalise the overloaded arguments of the page call facade
|
381
|
-
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const
|
372
|
+
*/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,
|
382
373
|
// use it as name and set category to undefined
|
383
|
-
if(isString(
|
374
|
+
if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// 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
|
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
|
387
378
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
388
379
|
* Normalise the overloaded arguments of the track call facade
|
389
|
-
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const
|
380
|
+
*/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
|
390
381
|
// and set some proper defaults
|
391
382
|
// Also, to clone the incoming object type arguments
|
392
383
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
393
384
|
* Normalise the overloaded arguments of the identify call facade
|
394
|
-
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const
|
385
|
+
*/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
|
395
386
|
// in the Analytics class
|
396
|
-
payload.userId=null;payload.traits=
|
387
|
+
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
|
397
388
|
// and set some proper defaults
|
398
389
|
// Also, to clone the incoming object type arguments
|
399
390
|
payload.userId=tryStringify(payload.userId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
400
391
|
* Normalise the overloaded arguments of the alias call facade
|
401
|
-
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const
|
392
|
+
*/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
|
402
393
|
// and set some proper defaults
|
403
394
|
// Also, to clone the incoming object type arguments
|
404
395
|
if(isDefined(payload.to)){payload.to=tryStringify(payload.to);}if(isDefined(payload.from)){payload.from=tryStringify(payload.from);}else {payload.from=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
405
396
|
* Normalise the overloaded arguments of the group call facade
|
406
|
-
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const
|
397
|
+
*/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
|
407
398
|
// in the Analytics class
|
408
|
-
payload.groupId=null;payload.traits=
|
399
|
+
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
|
409
400
|
// and set some proper defaults
|
410
401
|
// Also, to clone the incoming object type arguments
|
411
402
|
payload.groupId=tryStringify(payload.groupId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};
|
@@ -453,6 +444,20 @@
|
|
453
444
|
* @returns ISO formatted timestamp string
|
454
445
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
455
446
|
|
447
|
+
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
|
448
|
+
// eslint-disable-next-line func-names
|
449
|
+
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.
|
450
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
451
|
+
// @ts-ignore-next-line
|
452
|
+
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;};};/**
|
453
|
+
* Utility method for JSON stringify object excluding null values & circular references
|
454
|
+
*
|
455
|
+
* @param {*} value input
|
456
|
+
* @param {boolean} excludeNull if it should exclude nul or not
|
457
|
+
* @param {function} logger optional logger methods for warning
|
458
|
+
* @returns string
|
459
|
+
*/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;}};
|
460
|
+
|
456
461
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
457
462
|
* Get mutated error with issue prepended to error message
|
458
463
|
* @param err Original error
|
@@ -460,7 +465,7 @@
|
|
460
465
|
* @returns Instance of Error with message prepended with issue
|
461
466
|
*/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}));};
|
462
467
|
|
463
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
468
|
+
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';
|
464
469
|
|
465
470
|
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';
|
466
471
|
|
@@ -708,7 +713,7 @@
|
|
708
713
|
if(isFunction(globalThis.URL)){// eslint-disable-next-line no-new
|
709
714
|
new URL(url);}return URL_PATTERN.test(url);}catch(e){return false;}};
|
710
715
|
|
711
|
-
const isErrRetryable=details=>{let isRetryableNWFailure=false;if(details?.error&&details?.xhr){const xhrStatus=details.xhr.status;// same as in v1.1
|
716
|
+
const isErrRetryable=details=>{let isRetryableNWFailure=false;if(details?.error&&details?.xhr){const xhrStatus=getSanitizedValue(details.xhr).status;// same as in v1.1
|
712
717
|
isRetryableNWFailure=xhrStatus===429||xhrStatus>=500&&xhrStatus<600;}return isRetryableNWFailure;};
|
713
718
|
|
714
719
|
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
|
@@ -328,69 +351,37 @@ const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value
|
|
328
351
|
* @returns base64 encoded string
|
329
352
|
*/const toBase64=value=>bytesToBase64(new TextEncoder().encode(value));
|
330
353
|
|
331
|
-
const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
|
332
|
-
|
333
|
-
const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
|
334
|
-
// eslint-disable-next-line func-names
|
335
|
-
return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
|
336
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
337
|
-
// @ts-ignore-next-line
|
338
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
|
339
|
-
* Utility method for JSON stringify object excluding null values & circular references
|
340
|
-
*
|
341
|
-
* @param {*} value input
|
342
|
-
* @param {boolean} excludeNull if it should exclude nul or not
|
343
|
-
* @param {function} logger optional logger methods for warning
|
344
|
-
* @returns string
|
345
|
-
*/const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
|
346
|
-
// Using a regular function to use `this` for the parent context
|
347
|
-
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
348
|
-
}// `this` is the object that value is contained in, i.e., its direct parent.
|
349
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
350
|
-
// @ts-ignore-next-line
|
351
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
352
|
-
}// Check for circular references (if the value is already in the ancestors)
|
353
|
-
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
354
|
-
ancestors.push(value);return value;};};/**
|
355
|
-
* Recursively traverses an object similar to JSON.stringify,
|
356
|
-
* sanitizing BigInts and circular references
|
357
|
-
* @param value Input object
|
358
|
-
* @param logger Logger instance
|
359
|
-
* @returns Sanitized value
|
360
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
361
|
-
const newValue=replacer.call(value,'',value);return newValue;};
|
362
|
-
|
363
354
|
// if yes make them null instead of omitting in overloaded cases
|
364
355
|
/*
|
365
356
|
* Normalise the overloaded arguments of the page call facade
|
366
|
-
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const
|
357
|
+
*/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,
|
367
358
|
// use it as name and set category to undefined
|
368
|
-
if(isString(
|
359
|
+
if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
|
369
360
|
// and set some proper defaults
|
370
361
|
// Also, to clone the incoming object type arguments
|
371
362
|
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
|
372
363
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
373
364
|
* Normalise the overloaded arguments of the track call facade
|
374
|
-
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const
|
365
|
+
*/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
|
375
366
|
// and set some proper defaults
|
376
367
|
// Also, to clone the incoming object type arguments
|
377
368
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
378
369
|
* Normalise the overloaded arguments of the identify call facade
|
379
|
-
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const
|
370
|
+
*/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
|
380
371
|
// in the Analytics class
|
381
|
-
payload.userId=null;payload.traits=
|
372
|
+
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
|
382
373
|
// and set some proper defaults
|
383
374
|
// Also, to clone the incoming object type arguments
|
384
375
|
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;};/*
|
385
376
|
* Normalise the overloaded arguments of the alias call facade
|
386
|
-
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const
|
377
|
+
*/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
|
387
378
|
// and set some proper defaults
|
388
379
|
// Also, to clone the incoming object type arguments
|
389
380
|
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;};/*
|
390
381
|
* Normalise the overloaded arguments of the group call facade
|
391
|
-
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const
|
382
|
+
*/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
|
392
383
|
// in the Analytics class
|
393
|
-
payload.groupId=null;payload.traits=
|
384
|
+
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
|
394
385
|
// and set some proper defaults
|
395
386
|
// Also, to clone the incoming object type arguments
|
396
387
|
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;};
|
@@ -438,6 +429,20 @@ const getFormattedTimestamp=date=>date.toISOString();/**
|
|
438
429
|
* @returns ISO formatted timestamp string
|
439
430
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
440
431
|
|
432
|
+
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
|
433
|
+
// eslint-disable-next-line func-names
|
434
|
+
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.
|
435
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
436
|
+
// @ts-ignore-next-line
|
437
|
+
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;};};/**
|
438
|
+
* Utility method for JSON stringify object excluding null values & circular references
|
439
|
+
*
|
440
|
+
* @param {*} value input
|
441
|
+
* @param {boolean} excludeNull if it should exclude nul or not
|
442
|
+
* @param {function} logger optional logger methods for warning
|
443
|
+
* @returns string
|
444
|
+
*/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;}};
|
445
|
+
|
441
446
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
442
447
|
* Get mutated error with issue prepended to error message
|
443
448
|
* @param err Original error
|
@@ -445,7 +450,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
|
445
450
|
* @returns Instance of Error with message prepended with issue
|
446
451
|
*/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}));};
|
447
452
|
|
448
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
453
|
+
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';
|
449
454
|
|
450
455
|
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';
|
451
456
|
|
@@ -296,6 +296,8 @@
|
|
296
296
|
* @returns true if the input is an instance of Error and false otherwise
|
297
297
|
*/const isTypeOfError=obj=>obj instanceof Error;
|
298
298
|
|
299
|
+
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.`;
|
300
|
+
|
299
301
|
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';/**
|
300
302
|
* Checks if the input is an object literal or built-in object type and not null
|
301
303
|
* @param value Input value
|
@@ -317,7 +319,28 @@
|
|
317
319
|
* A utility to recursively remove undefined and null values from an object
|
318
320
|
* @param obj input object
|
319
321
|
* @returns a new object
|
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;};
|
322
|
+
*/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
|
323
|
+
// Using a regular function to use `this` for the parent context
|
324
|
+
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
325
|
+
}// `this` is the object that value is contained in, i.e., its direct parent.
|
326
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
327
|
+
// @ts-ignore-next-line
|
328
|
+
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
329
|
+
}// Check for circular references (if the value is already in the ancestors)
|
330
|
+
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
331
|
+
ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
|
332
|
+
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
|
333
|
+
// eslint-disable-next-line no-restricted-syntax
|
334
|
+
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
|
335
|
+
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
|
336
|
+
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
|
337
|
+
* Recursively traverses an object similar to JSON.stringify,
|
338
|
+
* sanitizing BigInts and circular references
|
339
|
+
* @param value Input object
|
340
|
+
* @param logger Logger instance
|
341
|
+
* @returns Sanitized value
|
342
|
+
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
343
|
+
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
|
321
344
|
|
322
345
|
const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value=>value.replace(/ {2,}/g,' ');const removeLeadingPeriod=value=>value.replace(/^\.+/,'');/**
|
323
346
|
* A function to convert values to string
|
@@ -334,69 +357,37 @@
|
|
334
357
|
* @returns base64 encoded string
|
335
358
|
*/const toBase64=value=>bytesToBase64(new TextEncoder().encode(value));
|
336
359
|
|
337
|
-
const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
|
338
|
-
|
339
|
-
const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
|
340
|
-
// eslint-disable-next-line func-names
|
341
|
-
return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
|
342
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
343
|
-
// @ts-ignore-next-line
|
344
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
|
345
|
-
* Utility method for JSON stringify object excluding null values & circular references
|
346
|
-
*
|
347
|
-
* @param {*} value input
|
348
|
-
* @param {boolean} excludeNull if it should exclude nul or not
|
349
|
-
* @param {function} logger optional logger methods for warning
|
350
|
-
* @returns string
|
351
|
-
*/const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
|
352
|
-
// Using a regular function to use `this` for the parent context
|
353
|
-
return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
|
354
|
-
}// `this` is the object that value is contained in, i.e., its direct parent.
|
355
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
356
|
-
// @ts-ignore-next-line
|
357
|
-
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
|
358
|
-
}// Check for circular references (if the value is already in the ancestors)
|
359
|
-
if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
|
360
|
-
ancestors.push(value);return value;};};/**
|
361
|
-
* Recursively traverses an object similar to JSON.stringify,
|
362
|
-
* sanitizing BigInts and circular references
|
363
|
-
* @param value Input object
|
364
|
-
* @param logger Logger instance
|
365
|
-
* @returns Sanitized value
|
366
|
-
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
|
367
|
-
const newValue=replacer.call(value,'',value);return newValue;};
|
368
|
-
|
369
360
|
// if yes make them null instead of omitting in overloaded cases
|
370
361
|
/*
|
371
362
|
* Normalise the overloaded arguments of the page call facade
|
372
|
-
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const
|
363
|
+
*/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,
|
373
364
|
// use it as name and set category to undefined
|
374
|
-
if(isString(
|
365
|
+
if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
|
375
366
|
// and set some proper defaults
|
376
367
|
// Also, to clone the incoming object type arguments
|
377
368
|
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
|
378
369
|
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
|
379
370
|
* Normalise the overloaded arguments of the track call facade
|
380
|
-
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const
|
371
|
+
*/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
|
381
372
|
// and set some proper defaults
|
382
373
|
// Also, to clone the incoming object type arguments
|
383
374
|
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
|
384
375
|
* Normalise the overloaded arguments of the identify call facade
|
385
|
-
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const
|
376
|
+
*/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
|
386
377
|
// in the Analytics class
|
387
|
-
payload.userId=null;payload.traits=
|
378
|
+
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
|
388
379
|
// and set some proper defaults
|
389
380
|
// Also, to clone the incoming object type arguments
|
390
381
|
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;};/*
|
391
382
|
* Normalise the overloaded arguments of the alias call facade
|
392
|
-
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const
|
383
|
+
*/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
|
393
384
|
// and set some proper defaults
|
394
385
|
// Also, to clone the incoming object type arguments
|
395
386
|
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;};/*
|
396
387
|
* Normalise the overloaded arguments of the group call facade
|
397
|
-
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const
|
388
|
+
*/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
|
398
389
|
// in the Analytics class
|
399
|
-
payload.groupId=null;payload.traits=
|
390
|
+
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
|
400
391
|
// and set some proper defaults
|
401
392
|
// Also, to clone the incoming object type arguments
|
402
393
|
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;};
|
@@ -444,6 +435,20 @@
|
|
444
435
|
* @returns ISO formatted timestamp string
|
445
436
|
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
|
446
437
|
|
438
|
+
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
|
439
|
+
// eslint-disable-next-line func-names
|
440
|
+
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.
|
441
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
442
|
+
// @ts-ignore-next-line
|
443
|
+
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;};};/**
|
444
|
+
* Utility method for JSON stringify object excluding null values & circular references
|
445
|
+
*
|
446
|
+
* @param {*} value input
|
447
|
+
* @param {boolean} excludeNull if it should exclude nul or not
|
448
|
+
* @param {function} logger optional logger methods for warning
|
449
|
+
* @returns string
|
450
|
+
*/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;}};
|
451
|
+
|
447
452
|
const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
|
448
453
|
* Get mutated error with issue prepended to error message
|
449
454
|
* @param err Original error
|
@@ -451,7 +456,7 @@
|
|
451
456
|
* @returns Instance of Error with message prepended with issue
|
452
457
|
*/const getMutatedError=(err,issue)=>{let finalError=err;if(!isTypeOfError(err)){finalError=new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}else {finalError.message=`${issue}: ${err.message}`;}return finalError;};const dispatchErrorEvent=error=>{if(isTypeOfError(error)){error.stack=`${error.stack??''}\n${MANUAL_ERROR_IDENTIFIER}`;}globalThis.dispatchEvent(new ErrorEvent('error',{error}));};
|
453
458
|
|
454
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.
|
459
|
+
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';
|
455
460
|
|
456
461
|
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
|
457
462
|
|