diff --git a/dist/mparticle.common.js b/dist/mparticle.common.js index 8a8c5891..36588026 100644 --- a/dist/mparticle.common.js +++ b/dist/mparticle.common.js @@ -154,13 +154,13 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; -var version = "2.28.1"; +var version = "2.28.2"; 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 },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 SDKv2NonMPIDCookieKeys:{gs:1,cu:1,l:1,globalSettings:1,currentUserMPID:1},HTTPCodes:{noHttpCoverage:-1,activeIdentityRequest:-2,activeSession:-3,validationIssue:-4,nativeIdentityRequest:-5,loggingDisabledOrMissingAPIKey:-6,tooManyRequests:429},FeatureFlags:{ReportBatching:"reportBatching",EventBatchingIntervalMillis:"eventBatchingIntervalMillis",OfflineStorage:"offlineStorage",DirectUrlRouting:"directURLRouting",CacheIdentity:"cacheIdentity",AudienceAPI:"audienceAPI"},DefaultInstance:"default_instance",CCPAPurpose:"data_sale_opt_out",IdentityMethods:{Modify:"modify",Logout:"logout",Login:"login",Identify:"identify"}};var ONE_DAY_IN_SECONDS=86400;var MILLIS_IN_ONE_SEC=1e3; -var Messages$9=Constants.Messages,createCookieString=function(a){return replaceCommasWithPipes(replaceQuotesWithApostrophes(a))},revertCookieString=function(a){return replacePipesWithCommas(replaceApostrophesWithQuotes(a))},inArray=function(a,b){var c=0;if(Array.prototype.indexOf)return 0<=a.indexOf(b,0);for(var d=a.length;c>c/4).toString(16):(c^16*Math.random()>>c/4).toString(16)},generateUniqueId=function(b){return void 0===b&&(b=""),b// if the placeholder was passed, return +var Messages$9=Constants.Messages;var HTTP_SUCCESS=200;var createCookieString=function(a){return replaceCommasWithPipes(replaceQuotesWithApostrophes(a))},revertCookieString=function(a){return replacePipesWithCommas(replaceApostrophesWithQuotes(a))},inArray=function(a,b){var c=0;if(Array.prototype.indexOf)return 0<=a.indexOf(b,0);for(var d=a.length;c>c/4).toString(16):(c^16*Math.random()>>c/4).toString(16)},generateUniqueId=function(b){return void 0===b&&(b=""),b// if the placeholder was passed, return ?generateRandomValue()// if the placeholder was passed, return :// [1e7] -> // 10000000 + // -1e3 -> // -1000 + @@ -1089,28 +1089,31 @@ Store:a._Store.serverSettings,SDKVersion:Constants.sdkVersion,SessionId:a._Store function forwardingStatsUploader(a){function b(){var b=a._Forwarders.getForwarderStatsQueue(),c=a._Persistence.forwardingStatsBatches.uploadsTable,d=Date.now();for(var e in b.length&&(c[d]={uploading:!1,data:b},a._Forwarders.setForwarderStatsQueue([])),c)(function(b){if(c.hasOwnProperty(b)&&!1===c[b].uploading){var d=function(){4===e.readyState&&(200===e.status||202===e.status?(a.Logger.verbose("Successfully sent "+e.statusText+" from server"),delete c[b]):"4"===e.status.toString()[0]?429!==e.status&&delete c[b]:c[b].uploading=!1);},e=a._Helpers.createXHR(d),f=c[b].data;c[b].uploading=!0,a._APIClient.sendBatchForwardingStatsToServer(f,e);}})(e);}this.startForwardingStatsTimer=function(){mParticle._forwardingStatsTimer=setInterval(function(){b();},a._Store.SDKConfig.forwarderStatsTimeout);};} -var _a=Constants.IdentityMethods,Identify$1=_a.Identify,Modify$2=_a.Modify,Login$1=_a.Login,Logout$1=_a.Logout;var cacheOrClearIdCache=function(a,b,c,d,e){// when parsing a response that has already been cached, simply return instead of attempting another cache +var _a=Constants.IdentityMethods,Identify$1=_a.Identify,Modify$2=_a.Modify,Login$1=_a.Login,Logout$1=_a.Logout,CACHE_HEADER="x-mp-max-age";// https://go.mparticle.com/work/SQDSDKS-6568 +// Temporary adapter to convert the XMLHttpRequest response to the IIdentityResponse interface +var xhrIdentityResponseAdapter=function(a){return a.hasOwnProperty("expireTimestamp")?a:{status:a.status,// Sometimes responseText can be an empty string, such as a 404 response +responseText:a.responseText?JSON.parse(a.responseText):{},cacheMaxAge:parseNumber((null===a||void 0===a?void 0:a.getResponseHeader(CACHE_HEADER))||""),expireTimestamp:0}};var cacheOrClearIdCache=function(a,b,c,d,e){// when parsing a response that has already been cached, simply return instead of attempting another cache if(!e){// default the expire timestamp to one day in milliseconds unless a header comes back -var f=new Date().getTime(),g=f+ONE_DAY_IN_SECONDS*MILLIS_IN_ONE_SEC;d.getAllResponseHeaders().includes("x-mp-max-age")&&(g=f+parseNumber(d.getResponseHeader("x-mp-max-age"))*MILLIS_IN_ONE_SEC),a===Login$1||a===Identify$1?cacheIdentityRequest(a,b,g,c,d):a===Modify$2||a===Logout$1?c.purge():void 0;}};var cacheIdentityRequest=function(a,b,c,d,e){var f=d.retrieve()||{},g=concatenateIdentities(a,b),h=generateHash(g),i=JSON.parse(e.responseText),j=i.mpid,k=i.is_logged_in;f[h]={responseText:JSON.stringify({mpid:j,is_logged_in:k}),status:e.status,expireTimestamp:c},d.store(f);};// We need to ensure that identities are concatenated in a deterministic way, so +var f=getExpireTimestamp(null===d||void 0===d?void 0:d.cacheMaxAge);a===Login$1||a===Identify$1?cacheIdentityRequest(a,b,f,c,d):a===Modify$2||a===Logout$1?c.purge():void 0;}};var cacheIdentityRequest=function(a,b,c,d,e){var f=e.responseText,g=e.status,h=d.retrieve()||{},i=concatenateIdentities(a,b),j=generateHash(i),k=f.mpid,l=f.is_logged_in;h[j]={responseText:JSON.stringify({mpid:k,is_logged_in:l}),status:g,expireTimestamp:c},d.store(h);};// We need to ensure that identities are concatenated in a deterministic way, so // we sort the identities based on their enum. // we create an array, set the user identity at the index of the user identity type var concatenateIdentities=function(a,b){var c="".concat(a,":").concat("device_application_stamp","=").concat(b.device_application_stamp,";"),d=Object.keys(b).length,e="";// set DAS first since it is not an official identity type if(d){var f=[];// create an array where each index is equal to the user identity type -for(var g in b)if(g==="device_application_stamp")continue;else f[Types.IdentityType.getIdentityType(g)]=b[g];e=f.reduce(function(a,b,c){var d=Types.IdentityType.getIdentityName(c);return "".concat(a).concat(d,"=").concat(b,";")},c);}return e};var hasValidCachedIdentity=function(a,b,c){// There is an edge case where multiple identity calls are taking place -// before identify fires, so there may not be a cache. See what happens when +for(var g in b)if(g==="device_application_stamp")continue;else f[Types.IdentityType.getIdentityType(g)]=b[g];e=f.reduce(function(a,b,c){var d=Types.IdentityType.getIdentityName(c);return "".concat(a).concat(d,"=").concat(b,";")},c);}return e};var hasValidCachedIdentity=function(a,b,c){// There is an edge case where multiple identity calls are taking place +// before identify fires, so there may not be a cache. See what happens when // the ? in idCache is removed to the following test -// "queued events contain login mpid instead of identify mpid when calling +// "queued events contain login mpid instead of identify mpid when calling // login immediately after mParticle initializes" var d=null===c||void 0===c?void 0:c.retrieve();// if there is no cache, then there is no valid cached identity if(!d)return !1;var e=concatenateIdentities(a,b),f=generateHash(e);// if cache doesn't have the cacheKey, there is no valid cached identity if(!d.hasOwnProperty(f))return !1;// If there is a valid cache key, compare the expireTimestamp to the current time. // If the current time is greater than the expireTimestamp, it is not a valid // cached identity. -var g=d[f].expireTimestamp;return !(ge.status))?[3/*break*/,4]:(this.logger.verbose("User Audiences successfully received"),[4/*yield*/,e.json()]);case 3:f=i.sent(),g={currentAudienceMemberships:null===f||void 0===f?void 0:f.audience_memberships};try{b(g);}catch(a){throw new Error("Error invoking callback on user audience response.")}return [3/*break*/,5];case 4:if(401===e.status)throw new Error("`HTTP error status ${userAudiencePromise.status} while retrieving User Audiences - please verify your API key.`");else if(403===e.status)throw new Error("`HTTP error status ${userAudiencePromise.status} while retrieving User Audiences - please verify your workspace is enabled for audiences.`");else// In case there is an HTTP error we did not anticipate. throw new Error("Uncaught HTTP Error ".concat(e.status,"."));case 5:return [3/*break*/,7];case 6:return h=i.sent(),this.logger.error("Error retrieving audiences. ".concat(h)),[3/*break*/,7];case 7:return [2/*return*/]}})})},a}(); @@ -1288,9 +1291,9 @@ return t._Helpers.getFeatureFlag(FeatureFlags$1.AudienceAPI)?void(null===s.audie * @method getCartProducts * @return {Array} array of cart products * @deprecated - */getCartProducts:function getCartProducts(){return t.Logger.warning("Deprecated function Identity.getCurrentUser().getCart().getCartProducts() will be removed in future releases"),t._Persistence.getCartProducts(e)}}},this.parseIdentityResponse=function(r,i,a,d,o,g,l){var u,p,y,c=t.Identity.getUser(i),I=c?c.getMPID():null,_=c?c.getUserIdentities().userIdentities:{},v={};t._Store.identityCallInFlight=!1;try{var m,S;if(t.Logger.verbose("Parsing \""+o+"\" identity response from server"),p=r.responseText?JSON.parse(r.responseText):null,t._Store.isLoggedIn=(null===(m=p)||void 0===m?void 0:m.is_logged_in)||!1,hasMPIDChanged(c,p)&&(t._Store.mpid=p.mpid,c&&t._Persistence.setLastSeenTime(i),u=!t._Persistence.getFirstSeenTime(p.mpid),t._Persistence.setFirstSeenTime(p.mpid)),200===r.status){s(CacheIdentity)&&cacheOrClearIdCache(o,g,n.idCache,r,l);var b=n.IdentityAPI.getUser(p.mpid),A=b?b.getUserIdentities().userIdentities:{};o===Modify$1?(v=t._Identity.IdentityRequest.combineUserIdentities(_,d.userIdentities),t._Store.setUserIdentities(i,v)):(o===Identify&&c&&p.mpid===I&&t._Persistence.setFirstSeenTime(p.mpid),t._Store.addMpidToSessionHistory(p.mpid,i),t._CookieSyncManager.attemptCookieSync(i,p.mpid,u),t._Persistence.swapCurrentUser(i,p.mpid,t._Store.currentSessionMPIDs),d&&!isEmpty(d.userIdentities)&&(v=n.IdentityRequest.combineUserIdentities(A,d.userIdentities)),t._Store.setUserIdentities(p.mpid,v),t._Persistence.update(),t._Store.syncPersistenceData(),t._Persistence.findPrevCookiesBasedOnUI(d),t._Store.context=p.context||t._Store.context),y=t.Identity.getCurrentUser(),tryOnUserAlias(c,y,d,t.Logger);var P=t._Persistence.getPersistence();y&&(t._Persistence.storeDataInMemory(P,y.getMPID()),n.reinitForwardersOnUserChange(c,y),n.setForwarderCallbacks(y,o));var U=getNewIdentitiesByName(v),C=o===Modify$1?_:A;// https://go.mparticle.com/work/SQDSDKS-6501 -n.sendUserIdentityChangeEvent(U,o,p.mpid,C);}if(a){var k=0===r.status?HTTPCodes$2.noHttpCoverage:r.status;t._Helpers.invokeCallback(a,k,p||null,y);}else p&&!isEmpty(p.errors)&&// https://go.mparticle.com/work/SQDSDKS-6500 -t.Logger.error("Received HTTP response code of "+r.status+" - "+p.errors[0].message);t.Logger.verbose("Successfully parsed Identity Response"),null===(S=t._APIClient)||void 0===S||S.processQueuedEvents();}catch(s){a&&t._Helpers.invokeCallback(a,r.status,p||null),t.Logger.error("Error parsing JSON response from Identity server: "+s);}},this.sendUserIdentityChangeEvent=function(e,r,s,i){if(s||r===Modify$1)// https://go.mparticle.com/work/SQDSDKS-6501 + */getCartProducts:function getCartProducts(){return t.Logger.warning("Deprecated function Identity.getCurrentUser().getCart().getCartProducts() will be removed in future releases"),t._Persistence.getCartProducts(e)}}},this.parseIdentityResponse=function(r,i,a,d,o,g,l){var u,p,y,c=t.Identity.getUser(i),I=c?c.getMPID():null,_=c?c.getUserIdentities().userIdentities:{},v={};t._Store.identityCallInFlight=!1;try{var m,S,b;if(t.Logger.verbose("Parsing \""+o+"\" identity response from server"),p=null!==(m=r.responseText)&&void 0!==m?m:null,t._Store.isLoggedIn=(null===(S=p)||void 0===S?void 0:S.is_logged_in)||!1,hasMPIDChanged(c,p)&&(t._Store.mpid=p.mpid,c&&t._Persistence.setLastSeenTime(i),u=!t._Persistence.getFirstSeenTime(p.mpid),t._Persistence.setFirstSeenTime(p.mpid)),r.status===HTTP_SUCCESS){if(s(CacheIdentity)){var A=xhrIdentityResponseAdapter(r);cacheOrClearIdCache(o,g,n.idCache,A,l);}var P=n.IdentityAPI.getUser(p.mpid),U=P?P.getUserIdentities().userIdentities:{};o===Modify$1?(v=t._Identity.IdentityRequest.combineUserIdentities(_,d.userIdentities),t._Store.setUserIdentities(i,v)):(o===Identify&&c&&p.mpid===I&&t._Persistence.setFirstSeenTime(p.mpid),t._Store.addMpidToSessionHistory(p.mpid,i),t._CookieSyncManager.attemptCookieSync(i,p.mpid,u),t._Persistence.swapCurrentUser(i,p.mpid,t._Store.currentSessionMPIDs),d&&!isEmpty(d.userIdentities)&&(v=n.IdentityRequest.combineUserIdentities(U,d.userIdentities)),t._Store.setUserIdentities(p.mpid,v),t._Persistence.update(),t._Store.syncPersistenceData(),t._Persistence.findPrevCookiesBasedOnUI(d),t._Store.context=p.context||t._Store.context),y=t.Identity.getCurrentUser(),tryOnUserAlias(c,y,d,t.Logger);var C=t._Persistence.getPersistence();y&&(t._Persistence.storeDataInMemory(C,y.getMPID()),n.reinitForwardersOnUserChange(c,y),n.setForwarderCallbacks(y,o));var k=getNewIdentitiesByName(v),f=o===Modify$1?_:U;// https://go.mparticle.com/work/SQDSDKS-6501 +n.sendUserIdentityChangeEvent(k,o,p.mpid,f);}if(a){var T=0===r.status?HTTPCodes$2.noHttpCoverage:r.status;t._Helpers.invokeCallback(a,T,p||null,y);}else p&&!isEmpty(p.errors)&&// https://go.mparticle.com/work/SQDSDKS-6500 +t.Logger.error("Received HTTP response code of "+r.status+" - "+p.errors[0].message);t.Logger.verbose("Successfully parsed Identity Response"),null===(b=t._APIClient)||void 0===b||b.processQueuedEvents();}catch(s){a&&t._Helpers.invokeCallback(a,r.status,p||null),t.Logger.error("Error parsing JSON response from Identity server: "+s);}},this.sendUserIdentityChangeEvent=function(e,r,s,i){if(s||r===Modify$1)// https://go.mparticle.com/work/SQDSDKS-6501 {// https://go.mparticle.com/work/SQDSDKS-6354 var a=this.IdentityAPI.getUser(s);for(var d in e)// Verifies a change actually happened if(i[d]!==e[d]){var o,g=!i[d],l=n.createUserIdentityChange(d,e[d],i[d],g,a);// If a new identity type was introduced when the identity changes @@ -1391,7 +1394,8 @@ var buildUrl=function(a,b,c,d){var e=d?"1":"0",f=["env=".concat(e)],g=c||{},h=g. return [2/*return*/,b]}})})};} var HTTPCodes$1=Constants.HTTPCodes,Messages$1=Constants.Messages,Modify=Constants.IdentityMethods.Modify;function IdentityAPIClient(a){this.sendAliasRequest=function(b,c){var d,e=function xhrCallback(){if(4===d.readyState){//only parse error messages from failing requests -if(a.Logger.verbose("Received "+d.statusText+" from server"),200!==d.status&&202!==d.status&&d.responseText){var b=JSON.parse(d.responseText);if(b.hasOwnProperty("message")){var e=b.message;return void a._Helpers.invokeAliasCallback(c,d.status,e)}}a._Helpers.invokeAliasCallback(c,d.status);}};if(a.Logger.verbose(Messages$1.InformationMessages.SendAliasHttp),d=a._Helpers.createXHR(e),d)try{d.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.aliasUrl,a._Store.devToken)+"/Alias"),d.send(JSON.stringify(b));}catch(b){a._Helpers.invokeAliasCallback(c,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending alias request to mParticle servers. "+b);}},this.sendIdentityRequest=function(b,c,d,e,f,g,h){var i,j,k=function xhrCallback(){4===i.readyState&&(a.Logger.verbose("Received "+i.statusText+" from server"),f(i,j,d,e,c,h,!1));};if(a.Logger.verbose(Messages$1.InformationMessages.SendIdentityBegin),!b)return void a.Logger.error(Messages$1.ErrorMessages.APIRequestEmpty);if(a.Logger.verbose(Messages$1.InformationMessages.SendIdentityHttp),i=a._Helpers.createXHR(k),i)try{a._Store.identityCallInFlight?a._Helpers.invokeCallback(d,HTTPCodes$1.activeIdentityRequest,"There is currently an Identity request processing. Please wait for this to return before requesting again"):(j=g||null,c===Modify?i.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.identityUrl)+g+"/"+c):i.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.identityUrl)+c),i.setRequestHeader("Content-Type","application/json"),i.setRequestHeader("x-mp-key",a._Store.devToken),a._Store.identityCallInFlight=!0,i.send(JSON.stringify(b)));}catch(b){a._Store.identityCallInFlight=!1,a._Helpers.invokeCallback(d,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending identity request to servers with status code "+i.status+" - "+b);}};} +if(a.Logger.verbose("Received "+d.statusText+" from server"),200!==d.status&&202!==d.status&&d.responseText){var b=JSON.parse(d.responseText);if(b.hasOwnProperty("message")){var e=b.message;return void a._Helpers.invokeAliasCallback(c,d.status,e)}}a._Helpers.invokeAliasCallback(c,d.status);}};if(a.Logger.verbose(Messages$1.InformationMessages.SendAliasHttp),d=a._Helpers.createXHR(e),d)try{d.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.aliasUrl,a._Store.devToken)+"/Alias"),d.send(JSON.stringify(b));}catch(b){a._Helpers.invokeAliasCallback(c,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending alias request to mParticle servers. "+b);}},this.sendIdentityRequest=function(b,c,d,e,f,g,h){var i,j,k=function xhrCallback(){if(4===i.readyState){a.Logger.verbose("Received "+i.statusText+" from server");// https://go.mparticle.com/work/SQDSDKS-6565 +var b=xhrIdentityResponseAdapter(i);f(b,j,d,e,c,h,!1);}};if(a.Logger.verbose(Messages$1.InformationMessages.SendIdentityBegin),!b)return void a.Logger.error(Messages$1.ErrorMessages.APIRequestEmpty);if(a.Logger.verbose(Messages$1.InformationMessages.SendIdentityHttp),i=a._Helpers.createXHR(k),i)try{a._Store.identityCallInFlight?a._Helpers.invokeCallback(d,HTTPCodes$1.activeIdentityRequest,"There is currently an Identity request processing. Please wait for this to return before requesting again"):(j=g||null,c===Modify?i.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.identityUrl)+g+"/"+c):i.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.identityUrl)+c),i.setRequestHeader("Content-Type","application/json"),i.setRequestHeader("x-mp-key",a._Store.devToken),a._Store.identityCallInFlight=!0,i.send(JSON.stringify(b)));}catch(b){a._Store.identityCallInFlight=!1,a._Helpers.invokeCallback(d,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending identity request to servers with status code "+i.status+" - "+b);}};} var Messages=Constants.Messages,HTTPCodes=Constants.HTTPCodes,FeatureFlags=Constants.FeatureFlags,ReportBatching=FeatureFlags.ReportBatching,StartingInitialization=Messages.InformationMessages.StartingInitialization;/** *

All of the following methods can be called on the primary mParticle class. In version 2.10.0, we introduced multiple instances. If you are using multiple instances (self hosted environments only), you should call these methods on each instance.

diff --git a/dist/mparticle.esm.js b/dist/mparticle.esm.js index b0908eaf..82d2f9fd 100644 --- a/dist/mparticle.esm.js +++ b/dist/mparticle.esm.js @@ -154,13 +154,13 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; -var version = "2.28.1"; +var version = "2.28.2"; 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 },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 SDKv2NonMPIDCookieKeys:{gs:1,cu:1,l:1,globalSettings:1,currentUserMPID:1},HTTPCodes:{noHttpCoverage:-1,activeIdentityRequest:-2,activeSession:-3,validationIssue:-4,nativeIdentityRequest:-5,loggingDisabledOrMissingAPIKey:-6,tooManyRequests:429},FeatureFlags:{ReportBatching:"reportBatching",EventBatchingIntervalMillis:"eventBatchingIntervalMillis",OfflineStorage:"offlineStorage",DirectUrlRouting:"directURLRouting",CacheIdentity:"cacheIdentity",AudienceAPI:"audienceAPI"},DefaultInstance:"default_instance",CCPAPurpose:"data_sale_opt_out",IdentityMethods:{Modify:"modify",Logout:"logout",Login:"login",Identify:"identify"}};var ONE_DAY_IN_SECONDS=86400;var MILLIS_IN_ONE_SEC=1e3; -var Messages$9=Constants.Messages,createCookieString=function(a){return replaceCommasWithPipes(replaceQuotesWithApostrophes(a))},revertCookieString=function(a){return replacePipesWithCommas(replaceApostrophesWithQuotes(a))},inArray=function(a,b){var c=0;if(Array.prototype.indexOf)return 0<=a.indexOf(b,0);for(var d=a.length;c>c/4).toString(16):(c^16*Math.random()>>c/4).toString(16)},generateUniqueId=function(b){return void 0===b&&(b=""),b// if the placeholder was passed, return +var Messages$9=Constants.Messages;var HTTP_SUCCESS=200;var createCookieString=function(a){return replaceCommasWithPipes(replaceQuotesWithApostrophes(a))},revertCookieString=function(a){return replacePipesWithCommas(replaceApostrophesWithQuotes(a))},inArray=function(a,b){var c=0;if(Array.prototype.indexOf)return 0<=a.indexOf(b,0);for(var d=a.length;c>c/4).toString(16):(c^16*Math.random()>>c/4).toString(16)},generateUniqueId=function(b){return void 0===b&&(b=""),b// if the placeholder was passed, return ?generateRandomValue()// if the placeholder was passed, return :// [1e7] -> // 10000000 + // -1e3 -> // -1000 + @@ -1089,28 +1089,31 @@ Store:a._Store.serverSettings,SDKVersion:Constants.sdkVersion,SessionId:a._Store function forwardingStatsUploader(a){function b(){var b=a._Forwarders.getForwarderStatsQueue(),c=a._Persistence.forwardingStatsBatches.uploadsTable,d=Date.now();for(var e in b.length&&(c[d]={uploading:!1,data:b},a._Forwarders.setForwarderStatsQueue([])),c)(function(b){if(c.hasOwnProperty(b)&&!1===c[b].uploading){var d=function(){4===e.readyState&&(200===e.status||202===e.status?(a.Logger.verbose("Successfully sent "+e.statusText+" from server"),delete c[b]):"4"===e.status.toString()[0]?429!==e.status&&delete c[b]:c[b].uploading=!1);},e=a._Helpers.createXHR(d),f=c[b].data;c[b].uploading=!0,a._APIClient.sendBatchForwardingStatsToServer(f,e);}})(e);}this.startForwardingStatsTimer=function(){mParticle._forwardingStatsTimer=setInterval(function(){b();},a._Store.SDKConfig.forwarderStatsTimeout);};} -var _a=Constants.IdentityMethods,Identify$1=_a.Identify,Modify$2=_a.Modify,Login$1=_a.Login,Logout$1=_a.Logout;var cacheOrClearIdCache=function(a,b,c,d,e){// when parsing a response that has already been cached, simply return instead of attempting another cache +var _a=Constants.IdentityMethods,Identify$1=_a.Identify,Modify$2=_a.Modify,Login$1=_a.Login,Logout$1=_a.Logout,CACHE_HEADER="x-mp-max-age";// https://go.mparticle.com/work/SQDSDKS-6568 +// Temporary adapter to convert the XMLHttpRequest response to the IIdentityResponse interface +var xhrIdentityResponseAdapter=function(a){return a.hasOwnProperty("expireTimestamp")?a:{status:a.status,// Sometimes responseText can be an empty string, such as a 404 response +responseText:a.responseText?JSON.parse(a.responseText):{},cacheMaxAge:parseNumber((null===a||void 0===a?void 0:a.getResponseHeader(CACHE_HEADER))||""),expireTimestamp:0}};var cacheOrClearIdCache=function(a,b,c,d,e){// when parsing a response that has already been cached, simply return instead of attempting another cache if(!e){// default the expire timestamp to one day in milliseconds unless a header comes back -var f=new Date().getTime(),g=f+ONE_DAY_IN_SECONDS*MILLIS_IN_ONE_SEC;d.getAllResponseHeaders().includes("x-mp-max-age")&&(g=f+parseNumber(d.getResponseHeader("x-mp-max-age"))*MILLIS_IN_ONE_SEC),a===Login$1||a===Identify$1?cacheIdentityRequest(a,b,g,c,d):a===Modify$2||a===Logout$1?c.purge():void 0;}};var cacheIdentityRequest=function(a,b,c,d,e){var f=d.retrieve()||{},g=concatenateIdentities(a,b),h=generateHash(g),i=JSON.parse(e.responseText),j=i.mpid,k=i.is_logged_in;f[h]={responseText:JSON.stringify({mpid:j,is_logged_in:k}),status:e.status,expireTimestamp:c},d.store(f);};// We need to ensure that identities are concatenated in a deterministic way, so +var f=getExpireTimestamp(null===d||void 0===d?void 0:d.cacheMaxAge);a===Login$1||a===Identify$1?cacheIdentityRequest(a,b,f,c,d):a===Modify$2||a===Logout$1?c.purge():void 0;}};var cacheIdentityRequest=function(a,b,c,d,e){var f=e.responseText,g=e.status,h=d.retrieve()||{},i=concatenateIdentities(a,b),j=generateHash(i),k=f.mpid,l=f.is_logged_in;h[j]={responseText:JSON.stringify({mpid:k,is_logged_in:l}),status:g,expireTimestamp:c},d.store(h);};// We need to ensure that identities are concatenated in a deterministic way, so // we sort the identities based on their enum. // we create an array, set the user identity at the index of the user identity type var concatenateIdentities=function(a,b){var c="".concat(a,":").concat("device_application_stamp","=").concat(b.device_application_stamp,";"),d=Object.keys(b).length,e="";// set DAS first since it is not an official identity type if(d){var f=[];// create an array where each index is equal to the user identity type -for(var g in b)if(g==="device_application_stamp")continue;else f[Types.IdentityType.getIdentityType(g)]=b[g];e=f.reduce(function(a,b,c){var d=Types.IdentityType.getIdentityName(c);return "".concat(a).concat(d,"=").concat(b,";")},c);}return e};var hasValidCachedIdentity=function(a,b,c){// There is an edge case where multiple identity calls are taking place -// before identify fires, so there may not be a cache. See what happens when +for(var g in b)if(g==="device_application_stamp")continue;else f[Types.IdentityType.getIdentityType(g)]=b[g];e=f.reduce(function(a,b,c){var d=Types.IdentityType.getIdentityName(c);return "".concat(a).concat(d,"=").concat(b,";")},c);}return e};var hasValidCachedIdentity=function(a,b,c){// There is an edge case where multiple identity calls are taking place +// before identify fires, so there may not be a cache. See what happens when // the ? in idCache is removed to the following test -// "queued events contain login mpid instead of identify mpid when calling +// "queued events contain login mpid instead of identify mpid when calling // login immediately after mParticle initializes" var d=null===c||void 0===c?void 0:c.retrieve();// if there is no cache, then there is no valid cached identity if(!d)return !1;var e=concatenateIdentities(a,b),f=generateHash(e);// if cache doesn't have the cacheKey, there is no valid cached identity if(!d.hasOwnProperty(f))return !1;// If there is a valid cache key, compare the expireTimestamp to the current time. // If the current time is greater than the expireTimestamp, it is not a valid // cached identity. -var g=d[f].expireTimestamp;return !(ge.status))?[3/*break*/,4]:(this.logger.verbose("User Audiences successfully received"),[4/*yield*/,e.json()]);case 3:f=i.sent(),g={currentAudienceMemberships:null===f||void 0===f?void 0:f.audience_memberships};try{b(g);}catch(a){throw new Error("Error invoking callback on user audience response.")}return [3/*break*/,5];case 4:if(401===e.status)throw new Error("`HTTP error status ${userAudiencePromise.status} while retrieving User Audiences - please verify your API key.`");else if(403===e.status)throw new Error("`HTTP error status ${userAudiencePromise.status} while retrieving User Audiences - please verify your workspace is enabled for audiences.`");else// In case there is an HTTP error we did not anticipate. throw new Error("Uncaught HTTP Error ".concat(e.status,"."));case 5:return [3/*break*/,7];case 6:return h=i.sent(),this.logger.error("Error retrieving audiences. ".concat(h)),[3/*break*/,7];case 7:return [2/*return*/]}})})},a}(); @@ -1288,9 +1291,9 @@ return t._Helpers.getFeatureFlag(FeatureFlags$1.AudienceAPI)?void(null===s.audie * @method getCartProducts * @return {Array} array of cart products * @deprecated - */getCartProducts:function getCartProducts(){return t.Logger.warning("Deprecated function Identity.getCurrentUser().getCart().getCartProducts() will be removed in future releases"),t._Persistence.getCartProducts(e)}}},this.parseIdentityResponse=function(r,i,a,d,o,g,l){var u,p,y,c=t.Identity.getUser(i),I=c?c.getMPID():null,_=c?c.getUserIdentities().userIdentities:{},v={};t._Store.identityCallInFlight=!1;try{var m,S;if(t.Logger.verbose("Parsing \""+o+"\" identity response from server"),p=r.responseText?JSON.parse(r.responseText):null,t._Store.isLoggedIn=(null===(m=p)||void 0===m?void 0:m.is_logged_in)||!1,hasMPIDChanged(c,p)&&(t._Store.mpid=p.mpid,c&&t._Persistence.setLastSeenTime(i),u=!t._Persistence.getFirstSeenTime(p.mpid),t._Persistence.setFirstSeenTime(p.mpid)),200===r.status){s(CacheIdentity)&&cacheOrClearIdCache(o,g,n.idCache,r,l);var b=n.IdentityAPI.getUser(p.mpid),A=b?b.getUserIdentities().userIdentities:{};o===Modify$1?(v=t._Identity.IdentityRequest.combineUserIdentities(_,d.userIdentities),t._Store.setUserIdentities(i,v)):(o===Identify&&c&&p.mpid===I&&t._Persistence.setFirstSeenTime(p.mpid),t._Store.addMpidToSessionHistory(p.mpid,i),t._CookieSyncManager.attemptCookieSync(i,p.mpid,u),t._Persistence.swapCurrentUser(i,p.mpid,t._Store.currentSessionMPIDs),d&&!isEmpty(d.userIdentities)&&(v=n.IdentityRequest.combineUserIdentities(A,d.userIdentities)),t._Store.setUserIdentities(p.mpid,v),t._Persistence.update(),t._Store.syncPersistenceData(),t._Persistence.findPrevCookiesBasedOnUI(d),t._Store.context=p.context||t._Store.context),y=t.Identity.getCurrentUser(),tryOnUserAlias(c,y,d,t.Logger);var P=t._Persistence.getPersistence();y&&(t._Persistence.storeDataInMemory(P,y.getMPID()),n.reinitForwardersOnUserChange(c,y),n.setForwarderCallbacks(y,o));var U=getNewIdentitiesByName(v),C=o===Modify$1?_:A;// https://go.mparticle.com/work/SQDSDKS-6501 -n.sendUserIdentityChangeEvent(U,o,p.mpid,C);}if(a){var k=0===r.status?HTTPCodes$2.noHttpCoverage:r.status;t._Helpers.invokeCallback(a,k,p||null,y);}else p&&!isEmpty(p.errors)&&// https://go.mparticle.com/work/SQDSDKS-6500 -t.Logger.error("Received HTTP response code of "+r.status+" - "+p.errors[0].message);t.Logger.verbose("Successfully parsed Identity Response"),null===(S=t._APIClient)||void 0===S||S.processQueuedEvents();}catch(s){a&&t._Helpers.invokeCallback(a,r.status,p||null),t.Logger.error("Error parsing JSON response from Identity server: "+s);}},this.sendUserIdentityChangeEvent=function(e,r,s,i){if(s||r===Modify$1)// https://go.mparticle.com/work/SQDSDKS-6501 + */getCartProducts:function getCartProducts(){return t.Logger.warning("Deprecated function Identity.getCurrentUser().getCart().getCartProducts() will be removed in future releases"),t._Persistence.getCartProducts(e)}}},this.parseIdentityResponse=function(r,i,a,d,o,g,l){var u,p,y,c=t.Identity.getUser(i),I=c?c.getMPID():null,_=c?c.getUserIdentities().userIdentities:{},v={};t._Store.identityCallInFlight=!1;try{var m,S,b;if(t.Logger.verbose("Parsing \""+o+"\" identity response from server"),p=null!==(m=r.responseText)&&void 0!==m?m:null,t._Store.isLoggedIn=(null===(S=p)||void 0===S?void 0:S.is_logged_in)||!1,hasMPIDChanged(c,p)&&(t._Store.mpid=p.mpid,c&&t._Persistence.setLastSeenTime(i),u=!t._Persistence.getFirstSeenTime(p.mpid),t._Persistence.setFirstSeenTime(p.mpid)),r.status===HTTP_SUCCESS){if(s(CacheIdentity)){var A=xhrIdentityResponseAdapter(r);cacheOrClearIdCache(o,g,n.idCache,A,l);}var P=n.IdentityAPI.getUser(p.mpid),U=P?P.getUserIdentities().userIdentities:{};o===Modify$1?(v=t._Identity.IdentityRequest.combineUserIdentities(_,d.userIdentities),t._Store.setUserIdentities(i,v)):(o===Identify&&c&&p.mpid===I&&t._Persistence.setFirstSeenTime(p.mpid),t._Store.addMpidToSessionHistory(p.mpid,i),t._CookieSyncManager.attemptCookieSync(i,p.mpid,u),t._Persistence.swapCurrentUser(i,p.mpid,t._Store.currentSessionMPIDs),d&&!isEmpty(d.userIdentities)&&(v=n.IdentityRequest.combineUserIdentities(U,d.userIdentities)),t._Store.setUserIdentities(p.mpid,v),t._Persistence.update(),t._Store.syncPersistenceData(),t._Persistence.findPrevCookiesBasedOnUI(d),t._Store.context=p.context||t._Store.context),y=t.Identity.getCurrentUser(),tryOnUserAlias(c,y,d,t.Logger);var C=t._Persistence.getPersistence();y&&(t._Persistence.storeDataInMemory(C,y.getMPID()),n.reinitForwardersOnUserChange(c,y),n.setForwarderCallbacks(y,o));var k=getNewIdentitiesByName(v),f=o===Modify$1?_:U;// https://go.mparticle.com/work/SQDSDKS-6501 +n.sendUserIdentityChangeEvent(k,o,p.mpid,f);}if(a){var T=0===r.status?HTTPCodes$2.noHttpCoverage:r.status;t._Helpers.invokeCallback(a,T,p||null,y);}else p&&!isEmpty(p.errors)&&// https://go.mparticle.com/work/SQDSDKS-6500 +t.Logger.error("Received HTTP response code of "+r.status+" - "+p.errors[0].message);t.Logger.verbose("Successfully parsed Identity Response"),null===(b=t._APIClient)||void 0===b||b.processQueuedEvents();}catch(s){a&&t._Helpers.invokeCallback(a,r.status,p||null),t.Logger.error("Error parsing JSON response from Identity server: "+s);}},this.sendUserIdentityChangeEvent=function(e,r,s,i){if(s||r===Modify$1)// https://go.mparticle.com/work/SQDSDKS-6501 {// https://go.mparticle.com/work/SQDSDKS-6354 var a=this.IdentityAPI.getUser(s);for(var d in e)// Verifies a change actually happened if(i[d]!==e[d]){var o,g=!i[d],l=n.createUserIdentityChange(d,e[d],i[d],g,a);// If a new identity type was introduced when the identity changes @@ -1391,7 +1394,8 @@ var buildUrl=function(a,b,c,d){var e=d?"1":"0",f=["env=".concat(e)],g=c||{},h=g. return [2/*return*/,b]}})})};} var HTTPCodes$1=Constants.HTTPCodes,Messages$1=Constants.Messages,Modify=Constants.IdentityMethods.Modify;function IdentityAPIClient(a){this.sendAliasRequest=function(b,c){var d,e=function xhrCallback(){if(4===d.readyState){//only parse error messages from failing requests -if(a.Logger.verbose("Received "+d.statusText+" from server"),200!==d.status&&202!==d.status&&d.responseText){var b=JSON.parse(d.responseText);if(b.hasOwnProperty("message")){var e=b.message;return void a._Helpers.invokeAliasCallback(c,d.status,e)}}a._Helpers.invokeAliasCallback(c,d.status);}};if(a.Logger.verbose(Messages$1.InformationMessages.SendAliasHttp),d=a._Helpers.createXHR(e),d)try{d.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.aliasUrl,a._Store.devToken)+"/Alias"),d.send(JSON.stringify(b));}catch(b){a._Helpers.invokeAliasCallback(c,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending alias request to mParticle servers. "+b);}},this.sendIdentityRequest=function(b,c,d,e,f,g,h){var i,j,k=function xhrCallback(){4===i.readyState&&(a.Logger.verbose("Received "+i.statusText+" from server"),f(i,j,d,e,c,h,!1));};if(a.Logger.verbose(Messages$1.InformationMessages.SendIdentityBegin),!b)return void a.Logger.error(Messages$1.ErrorMessages.APIRequestEmpty);if(a.Logger.verbose(Messages$1.InformationMessages.SendIdentityHttp),i=a._Helpers.createXHR(k),i)try{a._Store.identityCallInFlight?a._Helpers.invokeCallback(d,HTTPCodes$1.activeIdentityRequest,"There is currently an Identity request processing. Please wait for this to return before requesting again"):(j=g||null,c===Modify?i.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.identityUrl)+g+"/"+c):i.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.identityUrl)+c),i.setRequestHeader("Content-Type","application/json"),i.setRequestHeader("x-mp-key",a._Store.devToken),a._Store.identityCallInFlight=!0,i.send(JSON.stringify(b)));}catch(b){a._Store.identityCallInFlight=!1,a._Helpers.invokeCallback(d,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending identity request to servers with status code "+i.status+" - "+b);}};} +if(a.Logger.verbose("Received "+d.statusText+" from server"),200!==d.status&&202!==d.status&&d.responseText){var b=JSON.parse(d.responseText);if(b.hasOwnProperty("message")){var e=b.message;return void a._Helpers.invokeAliasCallback(c,d.status,e)}}a._Helpers.invokeAliasCallback(c,d.status);}};if(a.Logger.verbose(Messages$1.InformationMessages.SendAliasHttp),d=a._Helpers.createXHR(e),d)try{d.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.aliasUrl,a._Store.devToken)+"/Alias"),d.send(JSON.stringify(b));}catch(b){a._Helpers.invokeAliasCallback(c,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending alias request to mParticle servers. "+b);}},this.sendIdentityRequest=function(b,c,d,e,f,g,h){var i,j,k=function xhrCallback(){if(4===i.readyState){a.Logger.verbose("Received "+i.statusText+" from server");// https://go.mparticle.com/work/SQDSDKS-6565 +var b=xhrIdentityResponseAdapter(i);f(b,j,d,e,c,h,!1);}};if(a.Logger.verbose(Messages$1.InformationMessages.SendIdentityBegin),!b)return void a.Logger.error(Messages$1.ErrorMessages.APIRequestEmpty);if(a.Logger.verbose(Messages$1.InformationMessages.SendIdentityHttp),i=a._Helpers.createXHR(k),i)try{a._Store.identityCallInFlight?a._Helpers.invokeCallback(d,HTTPCodes$1.activeIdentityRequest,"There is currently an Identity request processing. Please wait for this to return before requesting again"):(j=g||null,c===Modify?i.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.identityUrl)+g+"/"+c):i.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.identityUrl)+c),i.setRequestHeader("Content-Type","application/json"),i.setRequestHeader("x-mp-key",a._Store.devToken),a._Store.identityCallInFlight=!0,i.send(JSON.stringify(b)));}catch(b){a._Store.identityCallInFlight=!1,a._Helpers.invokeCallback(d,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending identity request to servers with status code "+i.status+" - "+b);}};} var Messages=Constants.Messages,HTTPCodes=Constants.HTTPCodes,FeatureFlags=Constants.FeatureFlags,ReportBatching=FeatureFlags.ReportBatching,StartingInitialization=Messages.InformationMessages.StartingInitialization;/** *

All of the following methods can be called on the primary mParticle class. In version 2.10.0, we introduced multiple instances. If you are using multiple instances (self hosted environments only), you should call these methods on each instance.

diff --git a/dist/mparticle.js b/dist/mparticle.js index a6e5d204..7e16cce7 100644 --- a/dist/mparticle.js +++ b/dist/mparticle.js @@ -393,7 +393,7 @@ var mParticle = (function () { return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; - var version = "2.28.1"; + var version = "2.28.2"; var Constants = { sdkVersion: version, @@ -568,6 +568,7 @@ var mParticle = (function () { var MILLIS_IN_ONE_SEC = 1000; var Messages$9 = Constants.Messages; + var HTTP_SUCCESS = 200; var createCookieString = function createCookieString(value) { return replaceCommasWithPipes(replaceQuotesWithApostrophes(value)); }; @@ -6715,22 +6716,35 @@ var mParticle = (function () { Modify$2 = _a.Modify, Login$1 = _a.Login, Logout$1 = _a.Logout; - var cacheOrClearIdCache = function cacheOrClearIdCache(method, knownIdentities, idCache, xhr, parsingCachedResponse) { + var CACHE_HEADER = 'x-mp-max-age'; + // https://go.mparticle.com/work/SQDSDKS-6568 + // Temporary adapter to convert the XMLHttpRequest response to the IIdentityResponse interface + var xhrIdentityResponseAdapter = function xhrIdentityResponseAdapter(possiblyXhr) { + if (possiblyXhr.hasOwnProperty('expireTimestamp')) { + // If there is an `expireTimestamp`, it is an IIdentityResponse object, so just return it. This indicates it was a previously cached value. + return possiblyXhr; + } else { + // If there is no `expireTimestamp`, then it is an XHR object and needs to be parsed. + return { + status: possiblyXhr.status, + // Sometimes responseText can be an empty string, such as a 404 response + responseText: possiblyXhr.responseText ? JSON.parse(possiblyXhr.responseText) : {}, + cacheMaxAge: parseNumber((possiblyXhr === null || possiblyXhr === void 0 ? void 0 : possiblyXhr.getResponseHeader(CACHE_HEADER)) || ''), + expireTimestamp: 0 + }; + } + }; + var cacheOrClearIdCache = function cacheOrClearIdCache(method, knownIdentities, idCache, identityResponse, parsingCachedResponse) { // when parsing a response that has already been cached, simply return instead of attempting another cache if (parsingCachedResponse) { return; } - var CACHE_HEADER = 'x-mp-max-age'; // default the expire timestamp to one day in milliseconds unless a header comes back - var now = new Date().getTime(); - var expireTimestamp = now + ONE_DAY_IN_SECONDS * MILLIS_IN_ONE_SEC; - if (xhr.getAllResponseHeaders().includes(CACHE_HEADER)) { - expireTimestamp = now + parseNumber(xhr.getResponseHeader(CACHE_HEADER)) * MILLIS_IN_ONE_SEC; - } + var expireTimestamp = getExpireTimestamp(identityResponse === null || identityResponse === void 0 ? void 0 : identityResponse.cacheMaxAge); switch (method) { case Login$1: case Identify$1: - cacheIdentityRequest(method, knownIdentities, expireTimestamp, idCache, xhr); + cacheIdentityRequest(method, knownIdentities, expireTimestamp, idCache, identityResponse); break; case Modify$2: case Logout$1: @@ -6738,20 +6752,21 @@ var mParticle = (function () { break; } }; - var cacheIdentityRequest = function cacheIdentityRequest(method, identities, expireTimestamp, idCache, xhr) { + var cacheIdentityRequest = function cacheIdentityRequest(method, identities, expireTimestamp, idCache, identityResponse) { + var responseText = identityResponse.responseText, + status = identityResponse.status; var cache = idCache.retrieve() || {}; var cacheKey = concatenateIdentities(method, identities); var hashedKey = generateHash(cacheKey); - var _a = JSON.parse(xhr.responseText), - mpid = _a.mpid, - is_logged_in = _a.is_logged_in; - var cachedResponseText = { + var mpid = responseText.mpid, + is_logged_in = responseText.is_logged_in; + var cachedResponseBody = { mpid: mpid, is_logged_in: is_logged_in }; cache[hashedKey] = { - responseText: JSON.stringify(cachedResponseText), - status: xhr.status, + responseText: JSON.stringify(cachedResponseBody), + status: status, expireTimestamp: expireTimestamp }; idCache.store(cache); @@ -6783,10 +6798,10 @@ var mParticle = (function () { return concatenatedIdentities; }; var hasValidCachedIdentity = function hasValidCachedIdentity(method, proposedUserIdentities, idCache) { - // There is an edge case where multiple identity calls are taking place - // before identify fires, so there may not be a cache. See what happens when + // There is an edge case where multiple identity calls are taking place + // before identify fires, so there may not be a cache. See what happens when // the ? in idCache is removed to the following test - // "queued events contain login mpid instead of identify mpid when calling + // "queued events contain login mpid instead of identify mpid when calling // login immediately after mParticle initializes" var cache = idCache === null || idCache === void 0 ? void 0 : idCache.retrieve(); // if there is no cache, then there is no valid cached identity @@ -6814,7 +6829,11 @@ var mParticle = (function () { var hashedKey = generateHash(cacheKey); var cache = idCache.retrieve(); var cachedIdentity = cache ? cache[hashedKey] : null; - return cachedIdentity; + return { + responseText: parseIdentityResponse(cachedIdentity.responseText), + expireTimestamp: cachedIdentity.expireTimestamp, + status: cachedIdentity.status + }; }; // https://go.mparticle.com/work/SQDSDKS-6079 var createKnownIdentities = function createKnownIdentities(identityApiData, deviceId) { @@ -6849,6 +6868,15 @@ var mParticle = (function () { } return false; }; + var getExpireTimestamp = function getExpireTimestamp(maxAge) { + if (maxAge === void 0) { + maxAge = ONE_DAY_IN_SECONDS; + } + return new Date().getTime() + maxAge * MILLIS_IN_ONE_SEC; + }; + var parseIdentityResponse = function parseIdentityResponse(responseText) { + return responseText ? JSON.parse(responseText) : {}; + }; var AudienceManager = /** @class */function () { function AudienceManager(userAudienceUrl, apiKey, logger) { @@ -7833,7 +7861,7 @@ var mParticle = (function () { }; // https://go.mparticle.com/work/SQDSDKS-6355 - this.parseIdentityResponse = function (xhr, previousMPID, callback, identityApiData, method, knownIdentities, parsingCachedResponse) { + this.parseIdentityResponse = function (identityResponse, previousMPID, callback, identityApiData, method, knownIdentities, parsingCachedResponse) { var prevUser = mpInstance.Identity.getUser(previousMPID); var prevUserMPID = prevUser ? prevUser.getMPID() : null; var previousUIByName = prevUser ? prevUser.getUserIdentities().userIdentities : {}; @@ -7843,9 +7871,9 @@ var mParticle = (function () { var newIdentitiesByType = {}; mpInstance._Store.identityCallInFlight = false; try { - var _identityApiResult, _mpInstance$_APIClien; + var _identityResponse$res, _identityApiResult, _mpInstance$_APIClien; mpInstance.Logger.verbose('Parsing "' + method + '" identity response from server'); - identityApiResult = xhr.responseText ? JSON.parse(xhr.responseText) : null; + identityApiResult = (_identityResponse$res = identityResponse.responseText) !== null && _identityResponse$res !== void 0 ? _identityResponse$res : null; mpInstance._Store.isLoggedIn = ((_identityApiResult = identityApiResult) === null || _identityApiResult === void 0 ? void 0 : _identityApiResult.is_logged_in) || false; // https://go.mparticle.com/work/SQDSDKS-6504 @@ -7861,9 +7889,10 @@ var mParticle = (function () { // https://go.mparticle.com/work/SQDSDKS-6329 mpInstance._Persistence.setFirstSeenTime(identityApiResult.mpid); } - if (xhr.status === 200) { + if (identityResponse.status === HTTP_SUCCESS) { if (getFeatureFlag(CacheIdentity)) { - cacheOrClearIdCache(method, knownIdentities, self.idCache, xhr, parsingCachedResponse); + var identityResponseForCache = xhrIdentityResponseAdapter(identityResponse); + cacheOrClearIdCache(method, knownIdentities, self.idCache, identityResponseForCache, parsingCachedResponse); } var incomingUser = self.IdentityAPI.getUser(identityApiResult.mpid); var incomingUIByName = incomingUser ? incomingUser.getUserIdentities().userIdentities : {}; @@ -7912,11 +7941,11 @@ var mParticle = (function () { self.sendUserIdentityChangeEvent(newIdentitiesByName, method, identityApiResult.mpid, uiByName); } if (callback) { - var callbackCode = xhr.status === 0 ? HTTPCodes$2.noHttpCoverage : xhr.status; + var callbackCode = identityResponse.status === 0 ? HTTPCodes$2.noHttpCoverage : identityResponse.status; mpInstance._Helpers.invokeCallback(callback, callbackCode, identityApiResult || null, newUser); } else if (identityApiResult && !isEmpty(identityApiResult.errors)) { // https://go.mparticle.com/work/SQDSDKS-6500 - mpInstance.Logger.error('Received HTTP response code of ' + xhr.status + ' - ' + identityApiResult.errors[0].message); + mpInstance.Logger.error('Received HTTP response code of ' + identityResponse.status + ' - ' + identityApiResult.errors[0].message); } mpInstance.Logger.verbose('Successfully parsed Identity Response'); @@ -7924,7 +7953,7 @@ var mParticle = (function () { (_mpInstance$_APIClien = mpInstance._APIClient) === null || _mpInstance$_APIClien === void 0 || _mpInstance$_APIClien.processQueuedEvents(); } catch (e) { if (callback) { - mpInstance._Helpers.invokeCallback(callback, xhr.status, identityApiResult || null); + mpInstance._Helpers.invokeCallback(callback, identityResponse.status, identityApiResult || null); } mpInstance.Logger.error('Error parsing JSON response from Identity server: ' + e); } @@ -8896,7 +8925,10 @@ var mParticle = (function () { if (xhr.readyState === 4) { // https://go.mparticle.com/work/SQDSDKS-6368 mpInstance.Logger.verbose('Received ' + xhr.statusText + ' from server'); - parseIdentityResponse(xhr, previousMPID, callback, originalIdentityApiData, method, knownIdentities, false); + + // https://go.mparticle.com/work/SQDSDKS-6565 + var identityResponse = xhrIdentityResponseAdapter(xhr); + parseIdentityResponse(identityResponse, previousMPID, callback, originalIdentityApiData, method, knownIdentities, false); } }; mpInstance.Logger.verbose(Messages$1.InformationMessages.SendIdentityBegin);