@mparticle/web-sdk 2.36.0 → 2.38.0

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.
@@ -15,7 +15,7 @@ map:function map(a,b){var c,d,e;if(null===this)throw new TypeError(" this is nul
15
15
  filter:function filter(a/*, thisArg*/){if(void 0===this||null===this)throw new TypeError;var b=Object(this),c=b.length>>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=2<=arguments.length?arguments[1]:void 0,f=0;f<c;f++)if(f in b){var g=b[f];a.call(e,g,f,b)&&d.push(g);}return d},// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
16
16
  isArray:function isArray(a){return "[object Array]"===Object.prototype.toString.call(a)},Base64:Base64$1};
17
17
 
18
- var version = "2.36.0";
18
+ var version = "2.38.0";
19
19
 
20
20
  var Constants={sdkVersion:version,sdkVendor:"mparticle",platform:"web",Messages:{DeprecationMessages:{MethodIsDeprecatedPostfix:"is a deprecated method and will be removed in future releases",AlternativeMethodPrefix:"Please use the alternate method:"},ErrorMessages:{NoToken:"A token must be specified.",EventNameInvalidType:"Event name must be a valid string value.",EventDataInvalidType:"Event data must be a valid object hash.",LoggingDisabled:"Event logging is currently disabled.",CookieParseError:"Could not parse cookie",EventEmpty:"Event object is null or undefined, cancelling send",APIRequestEmpty:"APIRequest is null or undefined, cancelling send",NoEventType:"Event type must be specified.",TransactionIdRequired:"Transaction ID is required",TransactionRequired:"A transaction attributes object is required",PromotionIdRequired:"Promotion ID is required",BadAttribute:"Attribute value cannot be object or array",BadKey:"Key value cannot be object or array",BadLogPurchase:"Transaction attributes and a product are both required to log a purchase, https://docs.mparticle.com/?javascript#measuring-transactions",AudienceAPINotEnabled:"Your workspace is not enabled to retrieve user audiences."},InformationMessages:{CookieSearch:"Searching for cookie",CookieFound:"Cookie found, parsing values",CookieNotFound:"Cookies not found",CookieSet:"Setting cookie",CookieSync:"Performing cookie sync",SendBegin:"Starting to send event",SendIdentityBegin:"Starting to send event to identity server",SendWindowsPhone:"Sending event to Windows Phone container",SendIOS:"Calling iOS path: ",SendAndroid:"Calling Android JS interface method: ",SendHttp:"Sending event to mParticle HTTP service",SendAliasHttp:"Sending alias request to mParticle HTTP service",SendIdentityHttp:"Sending event to mParticle HTTP service",StartingNewSession:"Starting new Session",StartingLogEvent:"Starting to log event",StartingLogOptOut:"Starting to log user opt in/out",StartingEndSession:"Starting to end session",StartingInitialization:"Starting to initialize",StartingLogCommerceEvent:"Starting to log commerce event",StartingAliasRequest:"Starting to Alias MPIDs",LoadingConfig:"Loading configuration options",AbandonLogEvent:"Cannot log event, logging disabled or developer token not set",AbandonAliasUsers:"Cannot Alias Users, logging disabled or developer token not set",AbandonStartSession:"Cannot start session, logging disabled or developer token not set",AbandonEndSession:"Cannot end session, logging disabled or developer token not set",NoSessionToEnd:"Cannot end session, no active session found"},ValidationMessages:{ModifyIdentityRequestUserIdentitiesPresent:"identityRequests to modify require userIdentities to be present. Request not sent to server. Please fix and try again",IdentityRequesetInvalidKey:"There is an invalid key on your identityRequest object. It can only contain a `userIdentities` object and a `onUserAlias` function. Request not sent to server. Please fix and try again.",OnUserAliasType:"The onUserAlias value must be a function.",UserIdentities:"The userIdentities key must be an object with keys of identityTypes and values of strings. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidKey:"There is an invalid identity key on your `userIdentities` object within the identityRequest. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidValues:"All user identity values must be strings or null. Request not sent to server. Please fix and try again.",AliasMissingMpid:"Alias Request must contain both a destinationMpid and a sourceMpid",AliasNonUniqueMpid:"Alias Request's destinationMpid and sourceMpid must be unique",AliasMissingTime:"Alias Request must have both a startTime and an endTime",AliasStartBeforeEndTime:"Alias Request's endTime must be later than its startTime"}},NativeSdkPaths:{LogEvent:"logEvent",SetUserTag:"setUserTag",RemoveUserTag:"removeUserTag",SetUserAttribute:"setUserAttribute",RemoveUserAttribute:"removeUserAttribute",SetSessionAttribute:"setSessionAttribute",AddToCart:"addToCart",RemoveFromCart:"removeFromCart",ClearCart:"clearCart",LogOut:"logOut",SetUserAttributeList:"setUserAttributeList",RemoveAllUserAttributes:"removeAllUserAttributes",GetUserAttributesLists:"getUserAttributesLists",GetAllUserAttributes:"getAllUserAttributes",Identify:"identify",Logout:"logout",Login:"login",Modify:"modify",Alias:"aliasUsers",Upload:"upload"},StorageNames:{localStorageName:"mprtcl-api",localStorageNameV3:"mprtcl-v3",cookieName:"mprtcl-api",cookieNameV2:"mprtcl-v2",cookieNameV3:"mprtcl-v3",localStorageNameV4:"mprtcl-v4",localStorageProductsV4:"mprtcl-prodv4",cookieNameV4:"mprtcl-v4",currentStorageName:"mprtcl-v4",currentStorageProductsName:"mprtcl-prodv4"},DefaultConfig:{cookieDomain:null,cookieExpiration:365,logLevel:null,timeout:300,sessionTimeout:30,maxProducts:20,forwarderStatsTimeout:5e3,integrationDelayTimeout:5e3,maxCookieSize:3e3,aliasMaxWindow:90,uploadInterval:0// Maximum milliseconds in between batch uploads, below 500 will mean immediate upload. The server returns this as a string, but we are using it as a number internally
21
21
  },DefaultBaseUrls:{v1SecureServiceUrl:"jssdks.mparticle.com/v1/JS/",v2SecureServiceUrl:"jssdks.mparticle.com/v2/JS/",v3SecureServiceUrl:"jssdks.mparticle.com/v3/JS/",configUrl:"jssdkcdns.mparticle.com/JS/v2/",identityUrl:"identity.mparticle.com/v1/",aliasUrl:"jssdks.mparticle.com/v1/identity/",userAudienceUrl:"nativesdks.mparticle.com/v1/"},Base64CookieKeys:{csm:1,sa:1,ss:1,ua:1,ui:1,csd:1,ia:1,con:1},// https://go.mparticle.com/work/SQDSDKS-6039
@@ -126,7 +126,7 @@ var Messages$9=Constants.Messages,createCookieString=function(a){return replaceC
126
126
  // -1e11 -> //-100000000000,
127
127
  "".concat(1e7,"-").concat(1e3,"-").concat(4e3,"-").concat(8e3,"-").concat(1e11).replace(/[018]/g,// zeroes, ones, and eights with
128
128
  generateUniqueId// random hex digits
129
- )},getRampNumber=function(a){if(!a)return 100;var b=generateHash(a);return Math.abs(b%100)+1},isObject=function(a){var b=Object.prototype.toString.call(a);return "[object Object]"===b||"[object Error]"===b},parseNumber=function(a){if(isNaN(a)||!isFinite(a))return 0;var b=parseFloat(a);return isNaN(b)?0:b},parseStringOrNumber=function(a){return isStringOrNumber(a)?a:null},replaceCommasWithPipes=function(a){return a.replace(/,/g,"|")},replacePipesWithCommas=function(a){return a.replace(/\|/g,",")},replaceApostrophesWithQuotes=function(a){return a.replace(/\'/g,"\"")},replaceQuotesWithApostrophes=function(a){return a.replace(/\"/g,"'")},replaceMPID=function(a,b){return a.replace("%%mpid%%",b)},replaceAmpWithAmpersand=function(a){return a.replace(/&amp;/g,"&")},createCookieSyncUrl=function(a,b,c){var d=replaceAmpWithAmpersand(b),e=c?replaceAmpWithAmpersand(c):null,f=replaceMPID(d,a),g=e?replaceMPID(e,a):"";return f+encodeURIComponent(g)},returnConvertedBoolean=function(a){return "false"!==a&&"0"!==a&&!!a},decoded=function(a){return decodeURIComponent(a.replace(/\+/g," "))},converted=function(a){return 0===a.indexOf("\"")&&(a=a.slice(1,-1).replace(/\\"/g,"\"").replace(/\\\\/g,"\\")),a},isString=function(a){return "string"==typeof a},isNumber=function(a){return "number"==typeof a},isBoolean=function(a){return "boolean"==typeof a},isFunction=function(a){return "function"==typeof a},isValidCustomFlagProperty=function(a){return isNumber(a)||isString(a)||isBoolean(a)},toDataPlanSlug=function(a){// Make sure we are only acting on strings or numbers
129
+ )},getRampNumber=function(a){if(!a)return 100;var b=generateHash(a);return Math.abs(b%100)+1},isObject=function(a){var b=Object.prototype.toString.call(a);return "[object Object]"===b||"[object Error]"===b},parseNumber=function(a){if(isNaN(a)||!isFinite(a))return 0;var b=parseFloat(a);return isNaN(b)?0:b},parseSettingsString=function(a){try{return a?JSON.parse(a.replace(/&quot;/g,"\"")):[]}catch(a){throw new Error("Settings string contains invalid JSON")}},parseStringOrNumber=function(a){return isStringOrNumber(a)?a:null},replaceCommasWithPipes=function(a){return a.replace(/,/g,"|")},replacePipesWithCommas=function(a){return a.replace(/\|/g,",")},replaceApostrophesWithQuotes=function(a){return a.replace(/\'/g,"\"")},replaceQuotesWithApostrophes=function(a){return a.replace(/\"/g,"'")},replaceMPID=function(a,b){return a.replace("%%mpid%%",b)},replaceAmpWithAmpersand=function(a){return a.replace(/&amp;/g,"&")},createCookieSyncUrl=function(a,b,c){var d=replaceAmpWithAmpersand(b),e=c?replaceAmpWithAmpersand(c):null,f=replaceMPID(d,a),g=e?replaceMPID(e,a):"";return f+encodeURIComponent(g)},returnConvertedBoolean=function(a){return "false"!==a&&"0"!==a&&!!a},decoded=function(a){return decodeURIComponent(a.replace(/\+/g," "))},converted=function(a){return 0===a.indexOf("\"")&&(a=a.slice(1,-1).replace(/\\"/g,"\"").replace(/\\\\/g,"\\")),a},isString=function(a){return "string"==typeof a},isNumber=function(a){return "number"==typeof a},isBoolean=function(a){return "boolean"==typeof a},isFunction=function(a){return "function"==typeof a},isValidCustomFlagProperty=function(a){return isNumber(a)||isString(a)||isBoolean(a)},toDataPlanSlug=function(a){// Make sure we are only acting on strings or numbers
130
130
  return isStringOrNumber(a)?a.toString().toLowerCase().replace(/[^0-9a-zA-Z]+/g,"_"):""},isDataPlanSlug=function(a){return a===toDataPlanSlug(a)},isStringOrNumber=function(a){return isString(a)||isNumber(a)},isEmpty=function(a){return null==a||!(Object.keys(a)||a).length},moveElementToEnd=function(a,b){return a.slice(0,b).concat(a.slice(b+1),a[b])},queryStringParser=function(a,b){void 0===b&&(b=[]);var c,d={};if(!a)return d;if("undefined"!=typeof URL&&"undefined"!=typeof URLSearchParams){var e=new URL(a);c=new URLSearchParams(e.search);}else c=queryStringParserFallback(a);return isEmpty(b)?c.forEach(function(a,b){d[b]=a;}):b.forEach(function(a){var b=c.get(a);b&&(d[a]=b);}),d},queryStringParserFallback=function(a){var b={},c=a.split("?")[1]||"",d=c.split("&");return d.forEach(function(a){var c=a.split("="),d=c[0],e=c.slice(1),f=e.join("=");if(d&&void 0!==f)try{b[d]=decodeURIComponent(f||"");}catch(a){console.error("Failed to decode value for key ".concat(d,": ").concat(a));}}),{get:function get(a){return b[a]},forEach:function forEach(a){for(var c in b)b.hasOwnProperty(c)&&a(b[c],c);}}},getCookies=function(a){// Helper function to parse cookies from document.cookie
131
131
  var b=function parseCookies(){return "undefined"==typeof window?[]:window.document.cookie.split(";").map(function(a){return a.trim()})}();// Helper function to filter cookies by keys
132
132
  // Parse cookies from document.cookie
@@ -1417,8 +1417,17 @@ for(var e in this.clickIds)if(this.clickIds.hasOwnProperty(e)){var f=this.clickI
1417
1417
  // Rokt Manager in a "ready" state and it can begin sending data to the kit.
1418
1418
  //
1419
1419
  // https://github.com/mparticle-integrations/mparticle-javascript-integration-rokt
1420
- var RoktManager=/** @class */function(){function a(){this.kit=null,this.filters={},this.filteredUser=null,this.messageQueue=[];}return a.prototype.init=function(a,b){var c=(a||{}).userAttributeFilters;this.filters={userAttributeFilters:c,filterUserAttributes:KitFilterHelper.filterUserAttributes,filteredUser:b};},a.prototype.attachKit=function(a){this.kit=a,this.processMessageQueue();},a.prototype.selectPlacements=function(a){if(!this.isReady())return this.queueMessage({methodName:"selectPlacements",payload:a}),Promise.resolve({});try{return this.kit.selectPlacements(a)}catch(a){return Promise.reject(a instanceof Error?a:new Error("Unknown error occurred"))}},a.prototype.isReady=function(){// The Rokt Manager is ready when a kit is attached and has a launcher
1421
- return !!(this.kit&&this.kit.launcher)},a.prototype.processMessageQueue=function(){var a=this;0<this.messageQueue.length&&this.isReady()&&(this.messageQueue.forEach(function(b){return __awaiter(a,void 0,void 0,function(){return __generator(this,function(a){switch(a.label){case 0:return this.kit&&b.methodName in this.kit?[4/*yield*/,this.kit[b.methodName](b.payload)]:[3/*break*/,2];case 1:a.sent(),a.label=2;case 2:return [2/*return*/]}})})}),this.messageQueue=[]);},a.prototype.queueMessage=function(a){this.messageQueue.push(a);},a}();
1420
+ var RoktManager=/** @class */function(){function a(){this.kit=null,this.filters={},this.currentUser=null,this.filteredUser=null,this.messageQueue=[],this.sandbox=null,this.userAttributeMapping=[];}/**
1421
+ * Initializes the RoktManager with configuration settings and user data.
1422
+ *
1423
+ * @param {IKitConfigs} roktConfig - Configuration object containing user attribute filters and settings
1424
+ * @param {IMParticleUser} filteredUser - User object with filtered attributes
1425
+ * @param {IMParticleUser} currentUser - Current mParticle user object
1426
+ * @param {IRoktManagerOptions} options - Options for the RoktManager
1427
+ *
1428
+ * @throws Logs error to console if userAttributeMapping parsing fails
1429
+ */return a.prototype.init=function(a,b,c,d){var e=a||{},f=e.userAttributeFilters,g=e.settings,h=(g||{}).userAttributeMapping;try{this.userAttributeMapping=parseSettingsString(h);}catch(a){console.error("Error parsing user attribute mapping from config",a);}this.currentUser=c,this.filters={userAttributeFilters:f,filterUserAttributes:KitFilterHelper.filterUserAttributes,filteredUser:b},this.sandbox=null===d||void 0===d?void 0:d.sandbox;},a.prototype.attachKit=function(a){this.kit=a,this.processMessageQueue();},a.prototype.selectPlacements=function(a){var b;if(!this.isReady())return this.queueMessage({methodName:"selectPlacements",payload:a}),Promise.resolve({});try{var c=a.attributes,d=null!==(b=null===c||void 0===c?void 0:c.sandbox)&&void 0!==b?b:this.sandbox,e=this.mapUserAttributes(c,this.userAttributeMapping);this.setUserAttributes(e);var f=__assign(__assign({},e),null===d?{}:{sandbox:d}),g=__assign(__assign({},a),{attributes:f});return this.kit.selectPlacements(g)}catch(a){return Promise.reject(a instanceof Error?a:new Error("Unknown error occurred"))}},a.prototype.hashAttributes=function(a){if(!this.isReady())return this.queueMessage({methodName:"hashAttributes",payload:a}),Promise.resolve({});try{return this.kit.hashAttributes(a)}catch(a){return Promise.reject(a instanceof Error?a:new Error("Unknown error occurred"))}},a.prototype.isReady=function(){// The Rokt Manager is ready when a kit is attached and has a launcher
1430
+ return !!(this.kit&&this.kit.launcher)},a.prototype.setUserAttributes=function(a){var b=["sandbox"],c={};for(var d in a)a.hasOwnProperty(d)&&-1===b.indexOf(d)&&(c[d]=a[d]);try{this.currentUser.setUserAttributes(c);}catch(a){console.error("Error setting user attributes",a);}},a.prototype.mapUserAttributes=function(a,b){for(var c,d={},e=0,f=b;e<f.length;e++)c=f[e],d[c.map]=c.value;var g={};for(var h in a)if(a.hasOwnProperty(h)){var i=d[h]||h;g[i]=a[h];}return g},a.prototype.processMessageQueue=function(){var a=this;0<this.messageQueue.length&&this.isReady()&&(this.messageQueue.forEach(function(b){return __awaiter(a,void 0,void 0,function(){return __generator(this,function(a){switch(a.label){case 0:return this.kit&&b.methodName in this.kit?[4/*yield*/,this.kit[b.methodName](b.payload)]:[3/*break*/,2];case 1:a.sent(),a.label=2;case 2:return [2/*return*/]}})})}),this.messageQueue=[]);},a.prototype.queueMessage=function(a){this.messageQueue.push(a);},a}();
1422
1431
 
1423
1432
  var Messages=Constants.Messages,HTTPCodes=Constants.HTTPCodes,FeatureFlags=Constants.FeatureFlags,ReportBatching=FeatureFlags.ReportBatching,CaptureIntegrationSpecificIds=FeatureFlags.CaptureIntegrationSpecificIds,StartingInitialization=Messages.InformationMessages.StartingInitialization;/**
1424
1433
  * <p>All of the following methods can be called on the primary mParticle class. In version 2.10.0, we introduced <a href="https://docs.mparticle.com/developers/sdk/web/multiple-instances/">multiple instances</a>. If you are using multiple instances (self hosted environments only), you should call these methods on each instance.</p>
@@ -1755,8 +1764,8 @@ function completeSDKInitialization(a,b,c){var d=createKitBlocker(b,c);// Web Vie
1755
1764
  // responsible for sending events directly to mParticle's servers. The Web SDK will not initialize
1756
1765
  // persistence or Identity directly.
1757
1766
  if(c._APIClient=new APIClient(c,d),c._Forwarders=new Forwarders(c,d),c._Store.processConfig(b),c._Identity.idCache=createIdentityCache(c),removeExpiredIdentityCacheDates(c._Identity.idCache),c._Store.webviewBridgeEnabled)c._NativeSdkHelpers.initializeSessionAttributes(a);else {c._Persistence.initializeStorage(),c._Store.syncPersistenceData();// Set up user identitiy variables for later use
1758
- var e=c.Identity.getCurrentUser(),f=e?e.getMPID():null,g=e?e.getUserIdentities().userIdentities:{};c._Store.SDKConfig.identifyRequest=c._Store.hasInvalidIdentifyRequest()?{userIdentities:g}:c._Store.SDKConfig.identifyRequest,c._Helpers.getFeatureFlag(ReportBatching)&&c._ForwardingStatsUploader.startForwardingStatsTimer(),c._Helpers.getFeatureFlag(CaptureIntegrationSpecificIds)&&c._IntegrationCapture.capture();// Configure Rokt Manager with filtered user
1759
- var h=parseConfig(b,"Rokt",181);if(h){var i=h.userAttributeFilters,j=filteredMparticleUser(f,{userAttributeFilters:i},c);c._RoktManager.init(h,j);}c._Forwarders.processForwarders(b,c._APIClient.prepareForwardingStats),c._Forwarders.processPixelConfigs(b),c._SessionManager.initialize(),c._Events.logAST(),processIdentityCallback(c,e,f,g);}// We will continue to clear out the ready queue as part of the initial init flow
1767
+ var e=c.Identity.getCurrentUser(),f=e?e.getMPID():null,g=e?e.getUserIdentities().userIdentities:{};c._Store.SDKConfig.identifyRequest=c._Store.hasInvalidIdentifyRequest()?{userIdentities:g}:c._Store.SDKConfig.identifyRequest,c._Helpers.getFeatureFlag(ReportBatching)&&c._ForwardingStatsUploader.startForwardingStatsTimer(),c._Helpers.getFeatureFlag(CaptureIntegrationSpecificIds)&&c._IntegrationCapture.capture();// Configure Rokt Manager with user and filtered user
1768
+ var h=parseConfig(b,"Rokt",181);if(h){var i=h.userAttributeFilters,j=filteredMparticleUser(f,{userAttributeFilters:i},c),k={sandbox:b.isDevelopmentMode};c._RoktManager.init(h,j,e,k);}c._Forwarders.processForwarders(b,c._APIClient.prepareForwardingStats),c._Forwarders.processPixelConfigs(b),c._SessionManager.initialize(),c._Events.logAST(),processIdentityCallback(c,e,f,g);}// We will continue to clear out the ready queue as part of the initial init flow
1760
1769
  // if an identify request is unnecessary, such as if there is an existing session
1761
1770
  (c._Store.mpid&&!c._Store.identifyCalled||c._Store.webviewBridgeEnabled)&&(c._Store.isInitialized=!0,c._preInit.readyQueue=processReadyQueue(c._preInit.readyQueue)),c._Store.isFirstRun&&(c._Store.isFirstRun=!1);}// https://go.mparticle.com/work/SQDSDKS-7061
1762
1771
  function createKitBlocker(a,b){var c,d,e,f;/* There are three ways a data plan object for blocking can be passed to the SDK:
@@ -15,7 +15,7 @@ map:function map(a,b){var c,d,e;if(null===this)throw new TypeError(" this is nul
15
15
  filter:function filter(a/*, thisArg*/){if(void 0===this||null===this)throw new TypeError;var b=Object(this),c=b.length>>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=2<=arguments.length?arguments[1]:void 0,f=0;f<c;f++)if(f in b){var g=b[f];a.call(e,g,f,b)&&d.push(g);}return d},// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
16
16
  isArray:function isArray(a){return "[object Array]"===Object.prototype.toString.call(a)},Base64:Base64$1};
17
17
 
18
- var version = "2.36.0";
18
+ var version = "2.38.0";
19
19
 
20
20
  var Constants={sdkVersion:version,sdkVendor:"mparticle",platform:"web",Messages:{DeprecationMessages:{MethodIsDeprecatedPostfix:"is a deprecated method and will be removed in future releases",AlternativeMethodPrefix:"Please use the alternate method:"},ErrorMessages:{NoToken:"A token must be specified.",EventNameInvalidType:"Event name must be a valid string value.",EventDataInvalidType:"Event data must be a valid object hash.",LoggingDisabled:"Event logging is currently disabled.",CookieParseError:"Could not parse cookie",EventEmpty:"Event object is null or undefined, cancelling send",APIRequestEmpty:"APIRequest is null or undefined, cancelling send",NoEventType:"Event type must be specified.",TransactionIdRequired:"Transaction ID is required",TransactionRequired:"A transaction attributes object is required",PromotionIdRequired:"Promotion ID is required",BadAttribute:"Attribute value cannot be object or array",BadKey:"Key value cannot be object or array",BadLogPurchase:"Transaction attributes and a product are both required to log a purchase, https://docs.mparticle.com/?javascript#measuring-transactions",AudienceAPINotEnabled:"Your workspace is not enabled to retrieve user audiences."},InformationMessages:{CookieSearch:"Searching for cookie",CookieFound:"Cookie found, parsing values",CookieNotFound:"Cookies not found",CookieSet:"Setting cookie",CookieSync:"Performing cookie sync",SendBegin:"Starting to send event",SendIdentityBegin:"Starting to send event to identity server",SendWindowsPhone:"Sending event to Windows Phone container",SendIOS:"Calling iOS path: ",SendAndroid:"Calling Android JS interface method: ",SendHttp:"Sending event to mParticle HTTP service",SendAliasHttp:"Sending alias request to mParticle HTTP service",SendIdentityHttp:"Sending event to mParticle HTTP service",StartingNewSession:"Starting new Session",StartingLogEvent:"Starting to log event",StartingLogOptOut:"Starting to log user opt in/out",StartingEndSession:"Starting to end session",StartingInitialization:"Starting to initialize",StartingLogCommerceEvent:"Starting to log commerce event",StartingAliasRequest:"Starting to Alias MPIDs",LoadingConfig:"Loading configuration options",AbandonLogEvent:"Cannot log event, logging disabled or developer token not set",AbandonAliasUsers:"Cannot Alias Users, logging disabled or developer token not set",AbandonStartSession:"Cannot start session, logging disabled or developer token not set",AbandonEndSession:"Cannot end session, logging disabled or developer token not set",NoSessionToEnd:"Cannot end session, no active session found"},ValidationMessages:{ModifyIdentityRequestUserIdentitiesPresent:"identityRequests to modify require userIdentities to be present. Request not sent to server. Please fix and try again",IdentityRequesetInvalidKey:"There is an invalid key on your identityRequest object. It can only contain a `userIdentities` object and a `onUserAlias` function. Request not sent to server. Please fix and try again.",OnUserAliasType:"The onUserAlias value must be a function.",UserIdentities:"The userIdentities key must be an object with keys of identityTypes and values of strings. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidKey:"There is an invalid identity key on your `userIdentities` object within the identityRequest. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidValues:"All user identity values must be strings or null. Request not sent to server. Please fix and try again.",AliasMissingMpid:"Alias Request must contain both a destinationMpid and a sourceMpid",AliasNonUniqueMpid:"Alias Request's destinationMpid and sourceMpid must be unique",AliasMissingTime:"Alias Request must have both a startTime and an endTime",AliasStartBeforeEndTime:"Alias Request's endTime must be later than its startTime"}},NativeSdkPaths:{LogEvent:"logEvent",SetUserTag:"setUserTag",RemoveUserTag:"removeUserTag",SetUserAttribute:"setUserAttribute",RemoveUserAttribute:"removeUserAttribute",SetSessionAttribute:"setSessionAttribute",AddToCart:"addToCart",RemoveFromCart:"removeFromCart",ClearCart:"clearCart",LogOut:"logOut",SetUserAttributeList:"setUserAttributeList",RemoveAllUserAttributes:"removeAllUserAttributes",GetUserAttributesLists:"getUserAttributesLists",GetAllUserAttributes:"getAllUserAttributes",Identify:"identify",Logout:"logout",Login:"login",Modify:"modify",Alias:"aliasUsers",Upload:"upload"},StorageNames:{localStorageName:"mprtcl-api",localStorageNameV3:"mprtcl-v3",cookieName:"mprtcl-api",cookieNameV2:"mprtcl-v2",cookieNameV3:"mprtcl-v3",localStorageNameV4:"mprtcl-v4",localStorageProductsV4:"mprtcl-prodv4",cookieNameV4:"mprtcl-v4",currentStorageName:"mprtcl-v4",currentStorageProductsName:"mprtcl-prodv4"},DefaultConfig:{cookieDomain:null,cookieExpiration:365,logLevel:null,timeout:300,sessionTimeout:30,maxProducts:20,forwarderStatsTimeout:5e3,integrationDelayTimeout:5e3,maxCookieSize:3e3,aliasMaxWindow:90,uploadInterval:0// Maximum milliseconds in between batch uploads, below 500 will mean immediate upload. The server returns this as a string, but we are using it as a number internally
21
21
  },DefaultBaseUrls:{v1SecureServiceUrl:"jssdks.mparticle.com/v1/JS/",v2SecureServiceUrl:"jssdks.mparticle.com/v2/JS/",v3SecureServiceUrl:"jssdks.mparticle.com/v3/JS/",configUrl:"jssdkcdns.mparticle.com/JS/v2/",identityUrl:"identity.mparticle.com/v1/",aliasUrl:"jssdks.mparticle.com/v1/identity/",userAudienceUrl:"nativesdks.mparticle.com/v1/"},Base64CookieKeys:{csm:1,sa:1,ss:1,ua:1,ui:1,csd:1,ia:1,con:1},// https://go.mparticle.com/work/SQDSDKS-6039
@@ -126,7 +126,7 @@ var Messages$9=Constants.Messages,createCookieString=function(a){return replaceC
126
126
  // -1e11 -> //-100000000000,
127
127
  "".concat(1e7,"-").concat(1e3,"-").concat(4e3,"-").concat(8e3,"-").concat(1e11).replace(/[018]/g,// zeroes, ones, and eights with
128
128
  generateUniqueId// random hex digits
129
- )},getRampNumber=function(a){if(!a)return 100;var b=generateHash(a);return Math.abs(b%100)+1},isObject=function(a){var b=Object.prototype.toString.call(a);return "[object Object]"===b||"[object Error]"===b},parseNumber=function(a){if(isNaN(a)||!isFinite(a))return 0;var b=parseFloat(a);return isNaN(b)?0:b},parseStringOrNumber=function(a){return isStringOrNumber(a)?a:null},replaceCommasWithPipes=function(a){return a.replace(/,/g,"|")},replacePipesWithCommas=function(a){return a.replace(/\|/g,",")},replaceApostrophesWithQuotes=function(a){return a.replace(/\'/g,"\"")},replaceQuotesWithApostrophes=function(a){return a.replace(/\"/g,"'")},replaceMPID=function(a,b){return a.replace("%%mpid%%",b)},replaceAmpWithAmpersand=function(a){return a.replace(/&amp;/g,"&")},createCookieSyncUrl=function(a,b,c){var d=replaceAmpWithAmpersand(b),e=c?replaceAmpWithAmpersand(c):null,f=replaceMPID(d,a),g=e?replaceMPID(e,a):"";return f+encodeURIComponent(g)},returnConvertedBoolean=function(a){return "false"!==a&&"0"!==a&&!!a},decoded=function(a){return decodeURIComponent(a.replace(/\+/g," "))},converted=function(a){return 0===a.indexOf("\"")&&(a=a.slice(1,-1).replace(/\\"/g,"\"").replace(/\\\\/g,"\\")),a},isString=function(a){return "string"==typeof a},isNumber=function(a){return "number"==typeof a},isBoolean=function(a){return "boolean"==typeof a},isFunction=function(a){return "function"==typeof a},isValidCustomFlagProperty=function(a){return isNumber(a)||isString(a)||isBoolean(a)},toDataPlanSlug=function(a){// Make sure we are only acting on strings or numbers
129
+ )},getRampNumber=function(a){if(!a)return 100;var b=generateHash(a);return Math.abs(b%100)+1},isObject=function(a){var b=Object.prototype.toString.call(a);return "[object Object]"===b||"[object Error]"===b},parseNumber=function(a){if(isNaN(a)||!isFinite(a))return 0;var b=parseFloat(a);return isNaN(b)?0:b},parseSettingsString=function(a){try{return a?JSON.parse(a.replace(/&quot;/g,"\"")):[]}catch(a){throw new Error("Settings string contains invalid JSON")}},parseStringOrNumber=function(a){return isStringOrNumber(a)?a:null},replaceCommasWithPipes=function(a){return a.replace(/,/g,"|")},replacePipesWithCommas=function(a){return a.replace(/\|/g,",")},replaceApostrophesWithQuotes=function(a){return a.replace(/\'/g,"\"")},replaceQuotesWithApostrophes=function(a){return a.replace(/\"/g,"'")},replaceMPID=function(a,b){return a.replace("%%mpid%%",b)},replaceAmpWithAmpersand=function(a){return a.replace(/&amp;/g,"&")},createCookieSyncUrl=function(a,b,c){var d=replaceAmpWithAmpersand(b),e=c?replaceAmpWithAmpersand(c):null,f=replaceMPID(d,a),g=e?replaceMPID(e,a):"";return f+encodeURIComponent(g)},returnConvertedBoolean=function(a){return "false"!==a&&"0"!==a&&!!a},decoded=function(a){return decodeURIComponent(a.replace(/\+/g," "))},converted=function(a){return 0===a.indexOf("\"")&&(a=a.slice(1,-1).replace(/\\"/g,"\"").replace(/\\\\/g,"\\")),a},isString=function(a){return "string"==typeof a},isNumber=function(a){return "number"==typeof a},isBoolean=function(a){return "boolean"==typeof a},isFunction=function(a){return "function"==typeof a},isValidCustomFlagProperty=function(a){return isNumber(a)||isString(a)||isBoolean(a)},toDataPlanSlug=function(a){// Make sure we are only acting on strings or numbers
130
130
  return isStringOrNumber(a)?a.toString().toLowerCase().replace(/[^0-9a-zA-Z]+/g,"_"):""},isDataPlanSlug=function(a){return a===toDataPlanSlug(a)},isStringOrNumber=function(a){return isString(a)||isNumber(a)},isEmpty=function(a){return null==a||!(Object.keys(a)||a).length},moveElementToEnd=function(a,b){return a.slice(0,b).concat(a.slice(b+1),a[b])},queryStringParser=function(a,b){void 0===b&&(b=[]);var c,d={};if(!a)return d;if("undefined"!=typeof URL&&"undefined"!=typeof URLSearchParams){var e=new URL(a);c=new URLSearchParams(e.search);}else c=queryStringParserFallback(a);return isEmpty(b)?c.forEach(function(a,b){d[b]=a;}):b.forEach(function(a){var b=c.get(a);b&&(d[a]=b);}),d},queryStringParserFallback=function(a){var b={},c=a.split("?")[1]||"",d=c.split("&");return d.forEach(function(a){var c=a.split("="),d=c[0],e=c.slice(1),f=e.join("=");if(d&&void 0!==f)try{b[d]=decodeURIComponent(f||"");}catch(a){console.error("Failed to decode value for key ".concat(d,": ").concat(a));}}),{get:function get(a){return b[a]},forEach:function forEach(a){for(var c in b)b.hasOwnProperty(c)&&a(b[c],c);}}},getCookies=function(a){// Helper function to parse cookies from document.cookie
131
131
  var b=function parseCookies(){return "undefined"==typeof window?[]:window.document.cookie.split(";").map(function(a){return a.trim()})}();// Helper function to filter cookies by keys
132
132
  // Parse cookies from document.cookie
@@ -1417,8 +1417,17 @@ for(var e in this.clickIds)if(this.clickIds.hasOwnProperty(e)){var f=this.clickI
1417
1417
  // Rokt Manager in a "ready" state and it can begin sending data to the kit.
1418
1418
  //
1419
1419
  // https://github.com/mparticle-integrations/mparticle-javascript-integration-rokt
1420
- var RoktManager=/** @class */function(){function a(){this.kit=null,this.filters={},this.filteredUser=null,this.messageQueue=[];}return a.prototype.init=function(a,b){var c=(a||{}).userAttributeFilters;this.filters={userAttributeFilters:c,filterUserAttributes:KitFilterHelper.filterUserAttributes,filteredUser:b};},a.prototype.attachKit=function(a){this.kit=a,this.processMessageQueue();},a.prototype.selectPlacements=function(a){if(!this.isReady())return this.queueMessage({methodName:"selectPlacements",payload:a}),Promise.resolve({});try{return this.kit.selectPlacements(a)}catch(a){return Promise.reject(a instanceof Error?a:new Error("Unknown error occurred"))}},a.prototype.isReady=function(){// The Rokt Manager is ready when a kit is attached and has a launcher
1421
- return !!(this.kit&&this.kit.launcher)},a.prototype.processMessageQueue=function(){var a=this;0<this.messageQueue.length&&this.isReady()&&(this.messageQueue.forEach(function(b){return __awaiter(a,void 0,void 0,function(){return __generator(this,function(a){switch(a.label){case 0:return this.kit&&b.methodName in this.kit?[4/*yield*/,this.kit[b.methodName](b.payload)]:[3/*break*/,2];case 1:a.sent(),a.label=2;case 2:return [2/*return*/]}})})}),this.messageQueue=[]);},a.prototype.queueMessage=function(a){this.messageQueue.push(a);},a}();
1420
+ var RoktManager=/** @class */function(){function a(){this.kit=null,this.filters={},this.currentUser=null,this.filteredUser=null,this.messageQueue=[],this.sandbox=null,this.userAttributeMapping=[];}/**
1421
+ * Initializes the RoktManager with configuration settings and user data.
1422
+ *
1423
+ * @param {IKitConfigs} roktConfig - Configuration object containing user attribute filters and settings
1424
+ * @param {IMParticleUser} filteredUser - User object with filtered attributes
1425
+ * @param {IMParticleUser} currentUser - Current mParticle user object
1426
+ * @param {IRoktManagerOptions} options - Options for the RoktManager
1427
+ *
1428
+ * @throws Logs error to console if userAttributeMapping parsing fails
1429
+ */return a.prototype.init=function(a,b,c,d){var e=a||{},f=e.userAttributeFilters,g=e.settings,h=(g||{}).userAttributeMapping;try{this.userAttributeMapping=parseSettingsString(h);}catch(a){console.error("Error parsing user attribute mapping from config",a);}this.currentUser=c,this.filters={userAttributeFilters:f,filterUserAttributes:KitFilterHelper.filterUserAttributes,filteredUser:b},this.sandbox=null===d||void 0===d?void 0:d.sandbox;},a.prototype.attachKit=function(a){this.kit=a,this.processMessageQueue();},a.prototype.selectPlacements=function(a){var b;if(!this.isReady())return this.queueMessage({methodName:"selectPlacements",payload:a}),Promise.resolve({});try{var c=a.attributes,d=null!==(b=null===c||void 0===c?void 0:c.sandbox)&&void 0!==b?b:this.sandbox,e=this.mapUserAttributes(c,this.userAttributeMapping);this.setUserAttributes(e);var f=__assign(__assign({},e),null===d?{}:{sandbox:d}),g=__assign(__assign({},a),{attributes:f});return this.kit.selectPlacements(g)}catch(a){return Promise.reject(a instanceof Error?a:new Error("Unknown error occurred"))}},a.prototype.hashAttributes=function(a){if(!this.isReady())return this.queueMessage({methodName:"hashAttributes",payload:a}),Promise.resolve({});try{return this.kit.hashAttributes(a)}catch(a){return Promise.reject(a instanceof Error?a:new Error("Unknown error occurred"))}},a.prototype.isReady=function(){// The Rokt Manager is ready when a kit is attached and has a launcher
1430
+ return !!(this.kit&&this.kit.launcher)},a.prototype.setUserAttributes=function(a){var b=["sandbox"],c={};for(var d in a)a.hasOwnProperty(d)&&-1===b.indexOf(d)&&(c[d]=a[d]);try{this.currentUser.setUserAttributes(c);}catch(a){console.error("Error setting user attributes",a);}},a.prototype.mapUserAttributes=function(a,b){for(var c,d={},e=0,f=b;e<f.length;e++)c=f[e],d[c.map]=c.value;var g={};for(var h in a)if(a.hasOwnProperty(h)){var i=d[h]||h;g[i]=a[h];}return g},a.prototype.processMessageQueue=function(){var a=this;0<this.messageQueue.length&&this.isReady()&&(this.messageQueue.forEach(function(b){return __awaiter(a,void 0,void 0,function(){return __generator(this,function(a){switch(a.label){case 0:return this.kit&&b.methodName in this.kit?[4/*yield*/,this.kit[b.methodName](b.payload)]:[3/*break*/,2];case 1:a.sent(),a.label=2;case 2:return [2/*return*/]}})})}),this.messageQueue=[]);},a.prototype.queueMessage=function(a){this.messageQueue.push(a);},a}();
1422
1431
 
1423
1432
  var Messages=Constants.Messages,HTTPCodes=Constants.HTTPCodes,FeatureFlags=Constants.FeatureFlags,ReportBatching=FeatureFlags.ReportBatching,CaptureIntegrationSpecificIds=FeatureFlags.CaptureIntegrationSpecificIds,StartingInitialization=Messages.InformationMessages.StartingInitialization;/**
1424
1433
  * <p>All of the following methods can be called on the primary mParticle class. In version 2.10.0, we introduced <a href="https://docs.mparticle.com/developers/sdk/web/multiple-instances/">multiple instances</a>. If you are using multiple instances (self hosted environments only), you should call these methods on each instance.</p>
@@ -1755,8 +1764,8 @@ function completeSDKInitialization(a,b,c){var d=createKitBlocker(b,c);// Web Vie
1755
1764
  // responsible for sending events directly to mParticle's servers. The Web SDK will not initialize
1756
1765
  // persistence or Identity directly.
1757
1766
  if(c._APIClient=new APIClient(c,d),c._Forwarders=new Forwarders(c,d),c._Store.processConfig(b),c._Identity.idCache=createIdentityCache(c),removeExpiredIdentityCacheDates(c._Identity.idCache),c._Store.webviewBridgeEnabled)c._NativeSdkHelpers.initializeSessionAttributes(a);else {c._Persistence.initializeStorage(),c._Store.syncPersistenceData();// Set up user identitiy variables for later use
1758
- var e=c.Identity.getCurrentUser(),f=e?e.getMPID():null,g=e?e.getUserIdentities().userIdentities:{};c._Store.SDKConfig.identifyRequest=c._Store.hasInvalidIdentifyRequest()?{userIdentities:g}:c._Store.SDKConfig.identifyRequest,c._Helpers.getFeatureFlag(ReportBatching)&&c._ForwardingStatsUploader.startForwardingStatsTimer(),c._Helpers.getFeatureFlag(CaptureIntegrationSpecificIds)&&c._IntegrationCapture.capture();// Configure Rokt Manager with filtered user
1759
- var h=parseConfig(b,"Rokt",181);if(h){var i=h.userAttributeFilters,j=filteredMparticleUser(f,{userAttributeFilters:i},c);c._RoktManager.init(h,j);}c._Forwarders.processForwarders(b,c._APIClient.prepareForwardingStats),c._Forwarders.processPixelConfigs(b),c._SessionManager.initialize(),c._Events.logAST(),processIdentityCallback(c,e,f,g);}// We will continue to clear out the ready queue as part of the initial init flow
1767
+ var e=c.Identity.getCurrentUser(),f=e?e.getMPID():null,g=e?e.getUserIdentities().userIdentities:{};c._Store.SDKConfig.identifyRequest=c._Store.hasInvalidIdentifyRequest()?{userIdentities:g}:c._Store.SDKConfig.identifyRequest,c._Helpers.getFeatureFlag(ReportBatching)&&c._ForwardingStatsUploader.startForwardingStatsTimer(),c._Helpers.getFeatureFlag(CaptureIntegrationSpecificIds)&&c._IntegrationCapture.capture();// Configure Rokt Manager with user and filtered user
1768
+ var h=parseConfig(b,"Rokt",181);if(h){var i=h.userAttributeFilters,j=filteredMparticleUser(f,{userAttributeFilters:i},c),k={sandbox:b.isDevelopmentMode};c._RoktManager.init(h,j,e,k);}c._Forwarders.processForwarders(b,c._APIClient.prepareForwardingStats),c._Forwarders.processPixelConfigs(b),c._SessionManager.initialize(),c._Events.logAST(),processIdentityCallback(c,e,f,g);}// We will continue to clear out the ready queue as part of the initial init flow
1760
1769
  // if an identify request is unnecessary, such as if there is an existing session
1761
1770
  (c._Store.mpid&&!c._Store.identifyCalled||c._Store.webviewBridgeEnabled)&&(c._Store.isInitialized=!0,c._preInit.readyQueue=processReadyQueue(c._preInit.readyQueue)),c._Store.isFirstRun&&(c._Store.isFirstRun=!1);}// https://go.mparticle.com/work/SQDSDKS-7061
1762
1771
  function createKitBlocker(a,b){var c,d,e,f;/* There are three ways a data plan object for blocking can be passed to the SDK:
package/dist/mparticle.js CHANGED
@@ -203,7 +203,7 @@ var mParticle = (function () {
203
203
  Base64: Base64$1
204
204
  };
205
205
 
206
- var version = "2.36.0";
206
+ var version = "2.38.0";
207
207
 
208
208
  var Constants = {
209
209
  sdkVersion: version,
@@ -600,6 +600,13 @@ var mParticle = (function () {
600
600
  var floatValue = parseFloat(value);
601
601
  return isNaN(floatValue) ? 0 : floatValue;
602
602
  };
603
+ var parseSettingsString = function parseSettingsString(settingsString) {
604
+ try {
605
+ return settingsString ? JSON.parse(settingsString.replace(/&quot;/g, '"')) : [];
606
+ } catch (error) {
607
+ throw new Error('Settings string contains invalid JSON');
608
+ }
609
+ };
603
610
  var parseStringOrNumber = function parseStringOrNumber(value) {
604
611
  if (isStringOrNumber(value)) {
605
612
  return value;
@@ -9643,22 +9650,46 @@ var mParticle = (function () {
9643
9650
  function RoktManager() {
9644
9651
  this.kit = null;
9645
9652
  this.filters = {};
9653
+ this.currentUser = null;
9646
9654
  this.filteredUser = null;
9647
9655
  this.messageQueue = [];
9656
+ this.sandbox = null;
9657
+ this.userAttributeMapping = [];
9648
9658
  }
9649
- RoktManager.prototype.init = function (roktConfig, filteredUser) {
9650
- var userAttributeFilters = (roktConfig || {}).userAttributeFilters;
9659
+ /**
9660
+ * Initializes the RoktManager with configuration settings and user data.
9661
+ *
9662
+ * @param {IKitConfigs} roktConfig - Configuration object containing user attribute filters and settings
9663
+ * @param {IMParticleUser} filteredUser - User object with filtered attributes
9664
+ * @param {IMParticleUser} currentUser - Current mParticle user object
9665
+ * @param {IRoktManagerOptions} options - Options for the RoktManager
9666
+ *
9667
+ * @throws Logs error to console if userAttributeMapping parsing fails
9668
+ */
9669
+ RoktManager.prototype.init = function (roktConfig, filteredUser, currentUser, options) {
9670
+ var _a = roktConfig || {},
9671
+ userAttributeFilters = _a.userAttributeFilters,
9672
+ settings = _a.settings;
9673
+ var userAttributeMapping = (settings || {}).userAttributeMapping;
9674
+ try {
9675
+ this.userAttributeMapping = parseSettingsString(userAttributeMapping);
9676
+ } catch (error) {
9677
+ console.error('Error parsing user attribute mapping from config', error);
9678
+ }
9679
+ this.currentUser = currentUser;
9651
9680
  this.filters = {
9652
9681
  userAttributeFilters: userAttributeFilters,
9653
9682
  filterUserAttributes: KitFilterHelper.filterUserAttributes,
9654
9683
  filteredUser: filteredUser
9655
9684
  };
9685
+ this.sandbox = options === null || options === void 0 ? void 0 : options.sandbox;
9656
9686
  };
9657
9687
  RoktManager.prototype.attachKit = function (kit) {
9658
9688
  this.kit = kit;
9659
9689
  this.processMessageQueue();
9660
9690
  };
9661
9691
  RoktManager.prototype.selectPlacements = function (options) {
9692
+ var _a;
9662
9693
  if (!this.isReady()) {
9663
9694
  this.queueMessage({
9664
9695
  methodName: 'selectPlacements',
@@ -9667,7 +9698,31 @@ var mParticle = (function () {
9667
9698
  return Promise.resolve({});
9668
9699
  }
9669
9700
  try {
9670
- return this.kit.selectPlacements(options);
9701
+ var attributes = options.attributes;
9702
+ var sandboxValue = (_a = attributes === null || attributes === void 0 ? void 0 : attributes.sandbox) !== null && _a !== void 0 ? _a : this.sandbox;
9703
+ var mappedAttributes = this.mapUserAttributes(attributes, this.userAttributeMapping);
9704
+ this.setUserAttributes(mappedAttributes);
9705
+ var enrichedAttributes = __assign(__assign({}, mappedAttributes), sandboxValue !== null ? {
9706
+ sandbox: sandboxValue
9707
+ } : {});
9708
+ var enrichedOptions = __assign(__assign({}, options), {
9709
+ attributes: enrichedAttributes
9710
+ });
9711
+ return this.kit.selectPlacements(enrichedOptions);
9712
+ } catch (error) {
9713
+ return Promise.reject(error instanceof Error ? error : new Error('Unknown error occurred'));
9714
+ }
9715
+ };
9716
+ RoktManager.prototype.hashAttributes = function (attributes) {
9717
+ if (!this.isReady()) {
9718
+ this.queueMessage({
9719
+ methodName: 'hashAttributes',
9720
+ payload: attributes
9721
+ });
9722
+ return Promise.resolve({});
9723
+ }
9724
+ try {
9725
+ return this.kit.hashAttributes(attributes);
9671
9726
  } catch (error) {
9672
9727
  return Promise.reject(error instanceof Error ? error : new Error('Unknown error occurred'));
9673
9728
  }
@@ -9676,6 +9731,35 @@ var mParticle = (function () {
9676
9731
  // The Rokt Manager is ready when a kit is attached and has a launcher
9677
9732
  return Boolean(this.kit && this.kit.launcher);
9678
9733
  };
9734
+ RoktManager.prototype.setUserAttributes = function (attributes) {
9735
+ var reservedAttributes = ['sandbox'];
9736
+ var filteredAttributes = {};
9737
+ for (var key in attributes) {
9738
+ if (attributes.hasOwnProperty(key) && reservedAttributes.indexOf(key) === -1) {
9739
+ filteredAttributes[key] = attributes[key];
9740
+ }
9741
+ }
9742
+ try {
9743
+ this.currentUser.setUserAttributes(filteredAttributes);
9744
+ } catch (error) {
9745
+ console.error('Error setting user attributes', error);
9746
+ }
9747
+ };
9748
+ RoktManager.prototype.mapUserAttributes = function (attributes, userAttributeMapping) {
9749
+ var mappingLookup = {};
9750
+ for (var _i = 0, userAttributeMapping_1 = userAttributeMapping; _i < userAttributeMapping_1.length; _i++) {
9751
+ var mapping = userAttributeMapping_1[_i];
9752
+ mappingLookup[mapping.map] = mapping.value;
9753
+ }
9754
+ var mappedAttributes = {};
9755
+ for (var key in attributes) {
9756
+ if (attributes.hasOwnProperty(key)) {
9757
+ var newKey = mappingLookup[key] || key;
9758
+ mappedAttributes[newKey] = attributes[key];
9759
+ }
9760
+ }
9761
+ return mappedAttributes;
9762
+ };
9679
9763
  RoktManager.prototype.processMessageQueue = function () {
9680
9764
  var _this = this;
9681
9765
  if (this.messageQueue.length > 0 && this.isReady()) {
@@ -10675,14 +10759,17 @@ var mParticle = (function () {
10675
10759
  if (mpInstance._Helpers.getFeatureFlag(CaptureIntegrationSpecificIds)) {
10676
10760
  mpInstance._IntegrationCapture.capture();
10677
10761
  }
10678
- // Configure Rokt Manager with filtered user
10762
+ // Configure Rokt Manager with user and filtered user
10679
10763
  var roktConfig = parseConfig(config, 'Rokt', 181);
10680
10764
  if (roktConfig) {
10681
10765
  var userAttributeFilters = roktConfig.userAttributeFilters;
10682
10766
  var roktFilteredUser = filteredMparticleUser(currentUserMPID, {
10683
10767
  userAttributeFilters: userAttributeFilters
10684
10768
  }, mpInstance);
10685
- mpInstance._RoktManager.init(roktConfig, roktFilteredUser);
10769
+ var roktOptions = {
10770
+ sandbox: config.isDevelopmentMode
10771
+ };
10772
+ mpInstance._RoktManager.init(roktConfig, roktFilteredUser, currentUser, roktOptions);
10686
10773
  }
10687
10774
  mpInstance._Forwarders.processForwarders(config, mpInstance._APIClient.prepareForwardingStats);
10688
10775
  mpInstance._Forwarders.processPixelConfigs(config);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mparticle/web-sdk",
3
- "version": "2.36.0",
3
+ "version": "2.38.0",
4
4
  "description": "mParticle core SDK for web applications",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -49,7 +49,7 @@ import { IECommerce } from './ecommerce.interfaces';
49
49
  import { INativeSdkHelpers } from './nativeSdkHelpers.interfaces';
50
50
  import { IPersistence } from './persistence.interfaces';
51
51
  import ForegroundTimer from './foregroundTimeTracker';
52
- import RoktManager from './roktManager';
52
+ import RoktManager, { IRoktManagerOptions } from './roktManager';
53
53
  import filteredMparticleUser from './filteredMparticleUser';
54
54
 
55
55
  export interface IErrorLogMessage {
@@ -1394,7 +1394,7 @@ function completeSDKInitialization(apiKey, config, mpInstance) {
1394
1394
  mpInstance._IntegrationCapture.capture();
1395
1395
  }
1396
1396
 
1397
- // Configure Rokt Manager with filtered user
1397
+ // Configure Rokt Manager with user and filtered user
1398
1398
  const roktConfig: IKitConfigs = parseConfig(config, 'Rokt', 181);
1399
1399
  if (roktConfig) {
1400
1400
  const { userAttributeFilters } = roktConfig;
@@ -1403,7 +1403,10 @@ function completeSDKInitialization(apiKey, config, mpInstance) {
1403
1403
  { userAttributeFilters },
1404
1404
  mpInstance
1405
1405
  );
1406
- mpInstance._RoktManager.init(roktConfig, roktFilteredUser);
1406
+ const roktOptions: IRoktManagerOptions = {
1407
+ sandbox: config.isDevelopmentMode,
1408
+ };
1409
+ mpInstance._RoktManager.init(roktConfig, roktFilteredUser, currentUser, roktOptions);
1407
1410
  }
1408
1411
 
1409
1412
  mpInstance._Forwarders.processForwarders(
@@ -2,7 +2,7 @@ import { IKitConfigs } from "./configAPIClient";
2
2
  import { UserAttributeFilters } from "./forwarders.interfaces";
3
3
  import { IMParticleUser } from "./identity-user-interfaces";
4
4
  import KitFilterHelper from "./kitFilterHelper";
5
- import { Dictionary } from "./utils";
5
+ import { Dictionary, parseSettingsString } from "./utils";
6
6
 
7
7
  // https://docs.rokt.com/developers/integration-guides/web/library/attributes
8
8
  export interface IRoktPartnerAttributes {
@@ -24,6 +24,7 @@ export interface IRoktSelection {
24
24
 
25
25
  export interface IRoktLauncher {
26
26
  selectPlacements: (options: IRoktSelectPlacementsOptions) => Promise<IRoktSelection>;
27
+ hashAttributes: (attributes: IRoktPartnerAttributes) => Promise<Record<string, string>>;
27
28
  }
28
29
 
29
30
  export interface IRoktMessage {
@@ -43,6 +44,11 @@ export interface IRoktKit {
43
44
  launcher: IRoktLauncher | null;
44
45
  userAttributes: Dictionary<string>;
45
46
  selectPlacements: (options: IRoktSelectPlacementsOptions) => Promise<IRoktSelection>;
47
+ hashAttributes: (attributes: IRoktPartnerAttributes) => Promise<Record<string, string>>;
48
+ }
49
+
50
+ export interface IRoktManagerOptions {
51
+ sandbox?: boolean;
46
52
  }
47
53
 
48
54
  // The purpose of this class is to create a link between the Core mParticle SDK and the
@@ -58,17 +64,41 @@ export default class RoktManager {
58
64
  public kit: IRoktKit = null;
59
65
  public filters: RoktKitFilterSettings = {};
60
66
 
67
+ private currentUser: IMParticleUser | null = null;
61
68
  private filteredUser: IMParticleUser | null = null;
62
69
  private messageQueue: IRoktMessage[] = [];
70
+ private sandbox: boolean | null = null;
71
+ private userAttributeMapping: Dictionary<string>[] = [];
72
+
73
+ /**
74
+ * Initializes the RoktManager with configuration settings and user data.
75
+ *
76
+ * @param {IKitConfigs} roktConfig - Configuration object containing user attribute filters and settings
77
+ * @param {IMParticleUser} filteredUser - User object with filtered attributes
78
+ * @param {IMParticleUser} currentUser - Current mParticle user object
79
+ * @param {IRoktManagerOptions} options - Options for the RoktManager
80
+ *
81
+ * @throws Logs error to console if userAttributeMapping parsing fails
82
+ */
83
+ public init(roktConfig: IKitConfigs, filteredUser: IMParticleUser, currentUser: IMParticleUser, options?: IRoktManagerOptions): void {
84
+ const { userAttributeFilters, settings } = roktConfig || {};
85
+ const { userAttributeMapping } = settings || {};
63
86
 
64
- public init(roktConfig: IKitConfigs, filteredUser?: IMParticleUser): void {
65
- const { userAttributeFilters } = roktConfig || {};
87
+ try {
88
+ this.userAttributeMapping = parseSettingsString(userAttributeMapping);
89
+ } catch (error) {
90
+ console.error('Error parsing user attribute mapping from config', error);
91
+ }
92
+
93
+ this.currentUser = currentUser;
66
94
 
67
95
  this.filters = {
68
96
  userAttributeFilters,
69
97
  filterUserAttributes: KitFilterHelper.filterUserAttributes,
70
98
  filteredUser: filteredUser,
71
99
  };
100
+
101
+ this.sandbox = options?.sandbox;
72
102
  }
73
103
 
74
104
  public attachKit(kit: IRoktKit): void {
@@ -86,7 +116,39 @@ export default class RoktManager {
86
116
  }
87
117
 
88
118
  try {
89
- return this.kit.selectPlacements(options);
119
+ const { attributes } = options;
120
+ const sandboxValue = attributes?.sandbox ?? this.sandbox;
121
+ const mappedAttributes = this.mapUserAttributes(attributes, this.userAttributeMapping);
122
+
123
+ this.setUserAttributes(mappedAttributes);
124
+
125
+ const enrichedAttributes = {
126
+ ...mappedAttributes,
127
+ ...(sandboxValue !== null ? { sandbox: sandboxValue } : {}),
128
+ };
129
+
130
+ const enrichedOptions = {
131
+ ...options,
132
+ attributes: enrichedAttributes,
133
+ };
134
+
135
+ return this.kit.selectPlacements(enrichedOptions);
136
+ } catch (error) {
137
+ return Promise.reject(error instanceof Error ? error : new Error('Unknown error occurred'));
138
+ }
139
+ }
140
+
141
+ public hashAttributes(attributes: IRoktPartnerAttributes): Promise<Record<string, string>> {
142
+ if (!this.isReady()) {
143
+ this.queueMessage({
144
+ methodName: 'hashAttributes',
145
+ payload: attributes,
146
+ });
147
+ return Promise.resolve({} as Record<string, string>);
148
+ }
149
+
150
+ try {
151
+ return this.kit.hashAttributes(attributes);
90
152
  } catch (error) {
91
153
  return Promise.reject(error instanceof Error ? error : new Error('Unknown error occurred'));
92
154
  }
@@ -97,6 +159,39 @@ export default class RoktManager {
97
159
  return Boolean(this.kit && this.kit.launcher);
98
160
  }
99
161
 
162
+ private setUserAttributes(attributes: IRoktPartnerAttributes): void {
163
+ const reservedAttributes = ['sandbox'];
164
+ const filteredAttributes = {};
165
+
166
+ for (const key in attributes) {
167
+ if (attributes.hasOwnProperty(key) && reservedAttributes.indexOf(key) === -1) {
168
+ filteredAttributes[key] = attributes[key];
169
+ }
170
+ }
171
+
172
+ try {
173
+ this.currentUser.setUserAttributes(filteredAttributes);
174
+ } catch (error) {
175
+ console.error('Error setting user attributes', error);
176
+ }
177
+ }
178
+
179
+ private mapUserAttributes(attributes: IRoktPartnerAttributes, userAttributeMapping: Dictionary<string>[]): IRoktPartnerAttributes {
180
+ const mappingLookup: { [key: string]: string } = {};
181
+ for (const mapping of userAttributeMapping) {
182
+ mappingLookup[mapping.map] = mapping.value;
183
+ }
184
+
185
+ const mappedAttributes: IRoktPartnerAttributes = {};
186
+ for (const key in attributes) {
187
+ if (attributes.hasOwnProperty(key)) {
188
+ const newKey = mappingLookup[key] || key;
189
+ mappedAttributes[newKey] = attributes[key];
190
+ }
191
+ }
192
+ return mappedAttributes;
193
+ }
194
+
100
195
  private processMessageQueue(): void {
101
196
  if (this.messageQueue.length > 0 && this.isReady()) {
102
197
  this.messageQueue.forEach(async (message) => {
package/src/utils.ts CHANGED
@@ -160,6 +160,14 @@ const parseNumber = (value: string | number): number => {
160
160
  return isNaN(floatValue) ? 0 : floatValue;
161
161
  };
162
162
 
163
+ const parseSettingsString = (settingsString: string): Dictionary<string>[] => {
164
+ try {
165
+ return settingsString ? JSON.parse(settingsString.replace(/&quot;/g, '"')) : [];
166
+ } catch (error) {
167
+ throw new Error('Settings string contains invalid JSON');
168
+ }
169
+ };
170
+
163
171
  const parseStringOrNumber = (
164
172
  value: string | number
165
173
  ): string | number | null => {
@@ -412,6 +420,7 @@ export {
412
420
  isStringOrNumber,
413
421
  parseConfig,
414
422
  parseNumber,
423
+ parseSettingsString,
415
424
  parseStringOrNumber,
416
425
  replaceCommasWithPipes,
417
426
  replacePipesWithCommas,