@mparticle/web-sdk 3.11.1 → 3.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mparticle.js CHANGED
@@ -204,7 +204,7 @@ var mParticle = (function () {
204
204
  Base64: Base64$1
205
205
  };
206
206
 
207
- var version = "3.11.1";
207
+ var version = "3.12.1";
208
208
 
209
209
  var Constants = {
210
210
  sdkVersion: version,
@@ -4156,7 +4156,7 @@ var mParticle = (function () {
4156
4156
  return false;
4157
4157
  };
4158
4158
  this.isBridgeV1Available = function () {
4159
- if (mpInstance._Store.SDKConfig.useNativeSdk || window.mParticleAndroid || mpInstance._Store.SDKConfig.isIOS) {
4159
+ if (mpInstance._Store.SDKConfig.useNativeSdk || getAndroidBridge(androidBridgeNameBase) || mpInstance._Store.SDKConfig.isIOS) {
4160
4160
  return true;
4161
4161
  }
4162
4162
  return false;
@@ -4176,9 +4176,10 @@ var mParticle = (function () {
4176
4176
  }
4177
4177
  };
4178
4178
  this.sendViaBridgeV1 = function (path, value) {
4179
- if (window.mParticleAndroid && window.mParticleAndroid.hasOwnProperty(path)) {
4179
+ var androidBridge = getAndroidBridge(androidBridgeNameBase);
4180
+ if (androidBridge && androidBridge.hasOwnProperty(path)) {
4180
4181
  mpInstance.Logger.verbose(Messages$8.InformationMessages.SendAndroid + path);
4181
- window.mParticleAndroid[path](value);
4182
+ androidBridge[path](value);
4182
4183
  } else if (mpInstance._Store.SDKConfig.isIOS) {
4183
4184
  mpInstance.Logger.verbose(Messages$8.InformationMessages.SendIOS + path);
4184
4185
  self.sendViaIframeToIOS(path, value);
@@ -5667,9 +5668,9 @@ var mParticle = (function () {
5667
5668
  function migrateCookiesToLocalStorage(localStorageData, cookies) {
5668
5669
  if (!cookies) {
5669
5670
  self.storeDataInMemory(localStorageData);
5670
- return;
5671
+ return undefined;
5671
5672
  }
5672
- var allData = mergeStorageSources(localStorageData, cookies);
5673
+ var allData = localStorageData || cookies;
5673
5674
  self.storeDataInMemory(allData);
5674
5675
  self.expireCookies(mpInstance._Store.storageName);
5675
5676
  return allData;
@@ -5691,17 +5692,20 @@ var mParticle = (function () {
5691
5692
  }
5692
5693
  }
5693
5694
  }
5694
- function clearCorruptStorage() {
5695
+ function clearCorruptStorage(cookieWasLoaded) {
5695
5696
  if (self.useLocalStorage() && mpInstance._Store.isLocalStorageAvailable) {
5696
- localStorage.removeItem(mpInstance._Store.storageName);
5697
+ if (!cookieWasLoaded) {
5698
+ localStorage.removeItem(mpInstance._Store.storageName);
5699
+ }
5697
5700
  return;
5698
5701
  }
5699
5702
  self.expireCookies(mpInstance._Store.storageName);
5700
5703
  }
5701
5704
  this.initializeStorage = function () {
5705
+ var cookies = null;
5702
5706
  try {
5703
5707
  var localStorageData = self.getLocalStorage();
5704
- var cookies = self.getCookie();
5708
+ cookies = self.getCookie();
5705
5709
  // https://go.mparticle.com/work/SQDSDKS-6045
5706
5710
  setFirstRunFromExistingData(localStorageData, cookies);
5707
5711
  // https://go.mparticle.com/work/SQDSDKS-6045
@@ -5715,7 +5719,7 @@ var mParticle = (function () {
5715
5719
  } catch (e) {
5716
5720
  // If cookies or local storage is corrupt, we want to remove it
5717
5721
  // so that in the future, initializeStorage will work
5718
- clearCorruptStorage();
5722
+ clearCorruptStorage(Boolean(cookies));
5719
5723
  mpInstance.Logger.error('Error initializing storage: ' + e);
5720
5724
  }
5721
5725
  };
@@ -5892,8 +5896,7 @@ var mParticle = (function () {
5892
5896
  l,
5893
5897
  parts,
5894
5898
  name,
5895
- cookie,
5896
- result = key ? undefined : {};
5899
+ cookie;
5897
5900
  mpInstance.Logger.verbose(Messages$4.InformationMessages.CookieSearch);
5898
5901
  try {
5899
5902
  cookies = window.document.cookie.split('; ');
@@ -5910,19 +5913,15 @@ var mParticle = (function () {
5910
5913
  mpInstance.Logger.verbose('Unable to parse cookie: ' + name + '. Skipping.');
5911
5914
  }
5912
5915
  if (key && key === name) {
5913
- result = mpInstance._Helpers.converted(cookie);
5914
- break;
5915
- }
5916
- if (!key) {
5917
- result[name] = mpInstance._Helpers.converted(cookie);
5916
+ var decodedPersistence = self.decodePersistence(mpInstance._Helpers.converted(cookie));
5917
+ var persistence = decodedPersistence ? JSON.parse(decodedPersistence) : null;
5918
+ if (mpInstance._Helpers.isObject(persistence)) {
5919
+ mpInstance.Logger.verbose(Messages$4.InformationMessages.CookieFound);
5920
+ return persistence;
5921
+ }
5918
5922
  }
5919
5923
  }
5920
- if (result) {
5921
- mpInstance.Logger.verbose(Messages$4.InformationMessages.CookieFound);
5922
- return JSON.parse(self.decodePersistence(result));
5923
- } else {
5924
- return null;
5925
- }
5924
+ return null;
5926
5925
  };
5927
5926
  // https://go.mparticle.com/work/SQDSDKS-5022
5928
5927
  // https://go.mparticle.com/work/SQDSDKS-6021
@@ -6064,51 +6063,6 @@ var mParticle = (function () {
6064
6063
  function createFullEncodedCookie(persistence, expires, domain) {
6065
6064
  return self.encodePersistence(JSON.stringify(persistence)) + ';expires=' + expires + ';path=/' + domain;
6066
6065
  }
6067
- function cookieUiMatchesRequestedIdentity(cookieUIs, requestedIdentityType, requestedValue) {
6068
- for (var cookieUIType in cookieUIs) {
6069
- if (requestedIdentityType === cookieUIType && requestedValue === cookieUIs[cookieUIType]) {
6070
- return true;
6071
- }
6072
- }
6073
- return false;
6074
- }
6075
- function findMpidForRequestedIdentity(persistence, requestedIdentityType, requestedValue) {
6076
- var matchedUser;
6077
- for (var key in persistence) {
6078
- // any value in persistence that has an MPID key will be an MPID to search through
6079
- // other keys on the cookie are currentSessionMPIDs and currentMPID which should not be searched
6080
- if (!mpInstance._Helpers.isObject(persistence[key]) || !persistence[key].mpid) {
6081
- continue;
6082
- }
6083
- if (cookieUiMatchesRequestedIdentity(persistence[key].ui, requestedIdentityType, requestedValue)) {
6084
- matchedUser = key;
6085
- }
6086
- }
6087
- return matchedUser;
6088
- }
6089
- function findMpidMatchingIdentities(persistence, identityApiData) {
6090
- var matchedUser;
6091
- for (var requestedIdentityType in identityApiData.userIdentities) {
6092
- if (!persistence || !Object.keys(persistence).length) {
6093
- continue;
6094
- }
6095
- var match = findMpidForRequestedIdentity(persistence, requestedIdentityType, identityApiData.userIdentities[requestedIdentityType]);
6096
- if (match) {
6097
- matchedUser = match;
6098
- }
6099
- }
6100
- return matchedUser;
6101
- }
6102
- this.findPrevCookiesBasedOnUI = function (identityApiData) {
6103
- var persistence = mpInstance._Persistence.getPersistence();
6104
- if (!identityApiData) {
6105
- return;
6106
- }
6107
- var matchedUser = findMpidMatchingIdentities(persistence, identityApiData);
6108
- if (matchedUser) {
6109
- self.storeDataInMemory(persistence, matchedUser);
6110
- }
6111
- };
6112
6066
  function isNonEmptyArrayOrObject(value) {
6113
6067
  if (Array.isArray(value)) {
6114
6068
  return value.length > 0;
@@ -6216,8 +6170,6 @@ var mParticle = (function () {
6216
6170
  continue;
6217
6171
  }
6218
6172
  if (!SDKv2NonMPIDCookieKeys[mpid]) {
6219
- // Written as an object by encodeMpidRecords, then read as one by
6220
- // findMpidForRequestedIdentity and copied by copyNonCurrentUserMpids.
6221
6173
  if (!mpInstance._Helpers.isObject(persistence[mpid])) {
6222
6174
  delete persistence[mpid];
6223
6175
  continue;
@@ -7145,7 +7097,7 @@ var mParticle = (function () {
7145
7097
  };
7146
7098
  this.addEventHandler = function (domEvent, selector, eventName, data, eventType) {
7147
7099
  var elements = [],
7148
- handler = function handler(e) {
7100
+ handler = function handler(e, element) {
7149
7101
  var timeoutHandler = function timeoutHandler() {
7150
7102
  if (element.href) {
7151
7103
  window.location.href = element.href;
@@ -7171,7 +7123,6 @@ var mParticle = (function () {
7171
7123
  setTimeout(timeoutHandler, mpInstance._Store.SDKConfig.timeout);
7172
7124
  }
7173
7125
  },
7174
- element,
7175
7126
  i;
7176
7127
  if (!selector) {
7177
7128
  mpInstance.Logger.error("Can't bind event, selector is required");
@@ -7185,18 +7136,24 @@ var mParticle = (function () {
7185
7136
  }
7186
7137
  if (elements.length) {
7187
7138
  mpInstance.Logger.verbose('Found ' + elements.length + ' element' + (elements.length > 1 ? 's' : '') + ', attaching event handlers');
7188
- for (i = 0; i < elements.length; i++) {
7189
- element = elements[i];
7139
+ var _loop_1 = function _loop_1() {
7140
+ var element = elements[i];
7141
+ var elementHandler = function elementHandler(e) {
7142
+ handler(e, element);
7143
+ };
7190
7144
  if (element.addEventListener) {
7191
7145
  // Modern browsers
7192
- element.addEventListener(domEvent, handler, false);
7146
+ element.addEventListener(domEvent, elementHandler, false);
7193
7147
  } else if (element.attachEvent) {
7194
7148
  // IE < 9
7195
- element.attachEvent('on' + domEvent, handler);
7149
+ element.attachEvent('on' + domEvent, elementHandler);
7196
7150
  } else {
7197
7151
  // All other browsers
7198
- element['on' + domEvent] = handler;
7152
+ element['on' + domEvent] = elementHandler;
7199
7153
  }
7154
+ };
7155
+ for (i = 0; i < elements.length; i++) {
7156
+ _loop_1();
7200
7157
  }
7201
7158
  } else {
7202
7159
  mpInstance.Logger.verbose('No elements found');
@@ -9095,7 +9052,6 @@ var mParticle = (function () {
9095
9052
  mpInstance._Store.setUserIdentities(identityApiResult.mpid, newIdentitiesByType);
9096
9053
  mpInstance._Persistence.update();
9097
9054
  mpInstance._Store.syncPersistenceData();
9098
- mpInstance._Persistence.findPrevCookiesBasedOnUI(identityApiData);
9099
9055
  // https://go.mparticle.com/work/SQDSDKS-6357
9100
9056
  mpInstance._Store.context = identityApiResult.context || mpInstance._Store.context;
9101
9057
  }
@@ -9371,23 +9327,34 @@ var mParticle = (function () {
9371
9327
  },
9372
9328
  fromMinifiedJsonObject: function fromMinifiedJsonObject(json) {
9373
9329
  var state = self.createConsentState();
9374
- if (json.gdpr) {
9330
+ if (!isObject(json)) {
9331
+ return state;
9332
+ }
9333
+ if (isObject(json.gdpr)) {
9375
9334
  for (var purpose in json.gdpr) {
9376
9335
  if (hasOwnProp(json.gdpr, purpose)) {
9377
- var gdprConsent = self.createPrivacyConsent(json.gdpr[purpose].c, json.gdpr[purpose].ts, json.gdpr[purpose].d, json.gdpr[purpose].l, json.gdpr[purpose].h);
9378
- state.addGDPRConsentState(purpose, gdprConsent);
9336
+ state.addGDPRConsentState(purpose, privacyConsentFromMinifiedJson(json.gdpr[purpose]));
9379
9337
  }
9380
9338
  }
9381
9339
  }
9382
- if (json.ccpa) {
9340
+ if (isObject(json.ccpa)) {
9383
9341
  if (hasOwnProp(json.ccpa, CCPAPurpose)) {
9384
- var ccpaConsent = self.createPrivacyConsent(json.ccpa[CCPAPurpose].c, json.ccpa[CCPAPurpose].ts, json.ccpa[CCPAPurpose].d, json.ccpa[CCPAPurpose].l, json.ccpa[CCPAPurpose].h);
9385
- state.setCCPAConsentState(ccpaConsent);
9342
+ state.setCCPAConsentState(privacyConsentFromMinifiedJson(json.ccpa[CCPAPurpose]));
9386
9343
  }
9387
9344
  }
9388
9345
  return state;
9389
9346
  }
9390
9347
  };
9348
+ function privacyConsentFromMinifiedJson(minifiedConsent) {
9349
+ if (!isObject(minifiedConsent)) {
9350
+ return null;
9351
+ }
9352
+ var timestampIsObject = _typeof(minifiedConsent.ts) === 'object' && minifiedConsent.ts !== null;
9353
+ if (timestampIsObject) {
9354
+ return null;
9355
+ }
9356
+ return self.createPrivacyConsent(minifiedConsent.c, minifiedConsent.ts, minifiedConsent.d, minifiedConsent.l, minifiedConsent.h);
9357
+ }
9391
9358
  // TODO: Refactor this method into a constructor
9392
9359
  this.createConsentState = function (consentState) {
9393
9360
  var gdpr = {};
@@ -9537,6 +9504,19 @@ var mParticle = (function () {
9537
9504
  PromotionAction: "promotion_action",
9538
9505
  ProductImpression: "product_impression"
9539
9506
  };
9507
+ var withNoChange = function withNoChange(event) {
9508
+ return event;
9509
+ };
9510
+ var withoutUserAttributes = function withoutUserAttributes(event) {
9511
+ return __assign(__assign({}, event), {
9512
+ UserAttributes: {}
9513
+ });
9514
+ };
9515
+ var withoutUserIdentities = function withoutUserIdentities(event) {
9516
+ return __assign(__assign({}, event), {
9517
+ UserIdentities: []
9518
+ });
9519
+ };
9540
9520
  /*
9541
9521
  inspiration from https://github.com/mParticle/data-planning-node/blob/master/src/data_planning/data_plan_event_validator.ts
9542
9522
  but modified to only include commerce events, custom events, screen views, and removes validation
@@ -9795,26 +9775,41 @@ var mParticle = (function () {
9795
9775
  then product attributes if applicable, then user attributes,
9796
9776
  then the user identities
9797
9777
  */
9778
+ if (event) {
9779
+ event = this.applyBlockingStep('the event and its attributes', this.transformEventAndEventAttributes, event, withNoChange);
9780
+ }
9781
+ if (event && event.EventDataType === Types.MessageType.Commerce) {
9782
+ event = this.applyBlockingStep('product attributes', this.transformProductAttributes, event, withNoChange);
9783
+ }
9784
+ if (event) {
9785
+ event = this.applyBlockingStep('user attributes', this.transformUserAttributes, event, withoutUserAttributes);
9786
+ event = this.applyBlockingStep('user identities', this.transformUserIdentities, event, withoutUserIdentities);
9787
+ }
9788
+ return event;
9789
+ };
9790
+ KitBlocker.prototype.applyBlockingStep = function (filteredData, step, event, onFailure) {
9798
9791
  try {
9799
- if (event) {
9800
- event = this.transformEventAndEventAttributes(event);
9801
- }
9802
- if (event && event.EventDataType === Types.MessageType.Commerce) {
9803
- event = this.transformProductAttributes(event);
9804
- }
9805
- if (event) {
9806
- event = this.transformUserAttributes(event);
9807
- event = this.transformUserIdentities(event);
9808
- }
9809
- return event;
9810
- } catch (e) {
9811
- return event;
9792
+ return step.call(this, event);
9793
+ } catch (stepError) {
9794
+ var fallbackEvent = onFailure(event);
9795
+ this.reportFailedStep(filteredData, stepError);
9796
+ return fallbackEvent;
9797
+ }
9798
+ };
9799
+ KitBlocker.prototype.reportFailedStep = function (filteredData, stepError) {
9800
+ try {
9801
+ this.mpInstance.Logger.error('Kit blocking could not filter ' + filteredData + ': ' + stepError);
9802
+ } catch (_a) {
9803
+ // Best-effort: a logger or error value that throws must not stop the remaining steps.
9812
9804
  }
9813
9805
  };
9814
9806
  KitBlocker.prototype.transformEventAndEventAttributes = function (event) {
9815
9807
  var _a;
9816
9808
  var clonedEvent = __assign({}, event);
9817
9809
  var baseEvent = convertEvent(clonedEvent);
9810
+ if (!baseEvent) {
9811
+ return clonedEvent;
9812
+ }
9818
9813
  var matchKey = this.getMatchKey(baseEvent);
9819
9814
  var matchedEvent = this.dataPlanMatchLookups[matchKey];
9820
9815
  if (this.blockEvents) {
@@ -9913,18 +9908,16 @@ var mParticle = (function () {
9913
9908
  KitBlocker.prototype.transformUserAttributes = function (event) {
9914
9909
  var clonedEvent = __assign({}, event);
9915
9910
  if (this.blockUserAttributes) {
9916
- /*
9917
- If the user attribute is not found in the matchedAttributes
9918
- then remove it from event.UserAttributes as it is blocked
9919
- */
9920
9911
  var matchedAttributes = this.dataPlanMatchLookups['user_attributes'];
9921
- if (this.mpInstance._Helpers.isObject(matchedAttributes)) {
9912
+ if (this.mpInstance._Helpers.isObject(matchedAttributes) && clonedEvent.UserAttributes) {
9913
+ var plannedUserAttributes = {};
9922
9914
  for (var _i = 0, _a = Object.keys(clonedEvent.UserAttributes); _i < _a.length; _i++) {
9923
9915
  var ua = _a[_i];
9924
- if (!matchedAttributes[ua]) {
9925
- delete clonedEvent.UserAttributes[ua];
9916
+ if (matchedAttributes[ua] === true) {
9917
+ plannedUserAttributes[ua] = clonedEvent.UserAttributes[ua];
9926
9918
  }
9927
9919
  }
9920
+ clonedEvent.UserAttributes = plannedUserAttributes;
9928
9921
  }
9929
9922
  }
9930
9923
  return clonedEvent;
@@ -9976,23 +9969,14 @@ var mParticle = (function () {
9976
9969
  KitBlocker.prototype.transformUserIdentities = function (event) {
9977
9970
  var _this = this;
9978
9971
  var _a;
9979
- /*
9980
- If the user identity is not found in matchedIdentities
9981
- then remove it from event.UserIdentities as it is blocked.
9982
- event.UserIdentities is of type [{Identity: 'id1', Type: 7}, ...]
9983
- and so to compare properly in matchedIdentities, each Type needs
9984
- to be converted to an identityName
9985
- */
9986
9972
  var clonedEvent = __assign({}, event);
9987
9973
  if (this.blockUserIdentities) {
9988
9974
  var matchedIdentities_1 = this.dataPlanMatchLookups['user_identities'];
9989
9975
  if (this.mpInstance._Helpers.isObject(matchedIdentities_1)) {
9990
9976
  if ((_a = clonedEvent === null || clonedEvent === void 0 ? void 0 : clonedEvent.UserIdentities) === null || _a === void 0 ? void 0 : _a.length) {
9991
- clonedEvent.UserIdentities.forEach(function (uiByType, i) {
9977
+ clonedEvent.UserIdentities = clonedEvent.UserIdentities.filter(function (uiByType) {
9992
9978
  var identityName = Types.IdentityType.getIdentityName(_this.mpInstance._Helpers.parseNumber(uiByType.Type));
9993
- if (!matchedIdentities_1[identityName]) {
9994
- clonedEvent.UserIdentities.splice(i, 1);
9995
- }
9979
+ return matchedIdentities_1[identityName];
9996
9980
  });
9997
9981
  }
9998
9982
  }
@@ -10819,7 +10803,7 @@ var mParticle = (function () {
10819
10803
  RoktManager.prototype.selectPlacements = function (options) {
10820
10804
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
10821
10805
  return __awaiter(this, void 0, void 0, function () {
10822
- var attributes, sandboxValue, mappedAttributes, attributesToLog, currentUserIdentities, currentEmail, newEmail, currentHashedEmail, newHashedEmail, isValidHashedEmailIdentityType, emailChanged, hashedEmailChanged, newIdentities, msg, msg, finalUserIdentities, timeOnSite, totalTimeOnSite, enrichedAttributes, hashedEmail, capturedAttrs, passbackId, enrichedOptions;
10806
+ var attributes, sandboxValue, mappedAttributes, attributesToLog, currentUserIdentities, currentEmail, newEmail, currentHashedEmail, newHashedEmail, isValidHashedEmailIdentityType, emailChanged, hashedEmailChanged, newIdentities_1, msg, msg, userAttributes_1, finalUserIdentities, timeOnSite, totalTimeOnSite, enrichedAttributes, hashedEmail, capturedAttrs, passbackId, enrichedOptions;
10823
10807
  var _this = this;
10824
10808
  return __generator(this, function (_s) {
10825
10809
  (_a = this.captureTiming) === null || _a === void 0 ? void 0 : _a.call(this, PerformanceMarkType.JointSdkSelectPlacements);
@@ -10848,9 +10832,9 @@ var mParticle = (function () {
10848
10832
  }
10849
10833
  emailChanged = this.hasIdentityChanged(currentEmail, newEmail);
10850
10834
  hashedEmailChanged = this.hasIdentityChanged(currentHashedEmail, newHashedEmail);
10851
- newIdentities = {};
10835
+ newIdentities_1 = {};
10852
10836
  if (emailChanged) {
10853
- newIdentities.email = newEmail;
10837
+ newIdentities_1.email = newEmail;
10854
10838
  if (newEmail) {
10855
10839
  msg = 'Email mismatch detected. Current email differs from email passed to selectPlacements call. Proceeding to call identify with email from selectPlacements call. Please verify your implementation.';
10856
10840
  this.logger.warning(msg);
@@ -10862,7 +10846,7 @@ var mParticle = (function () {
10862
10846
  }
10863
10847
  }
10864
10848
  if (hashedEmailChanged) {
10865
- newIdentities[this.mappedEmailShaIdentityType] = newHashedEmail;
10849
+ newIdentities_1[this.mappedEmailShaIdentityType] = newHashedEmail;
10866
10850
  msg = 'emailsha256 mismatch detected. Current mParticle hashedEmail differs from hashedEmail passed to selectPlacements call. Proceeding to call identify with hashedEmail from selectPlacements call. Please verify your implementation.';
10867
10851
  this.logger.warning(msg);
10868
10852
  (_j = this.errorReporter) === null || _j === void 0 ? void 0 : _j.report({
@@ -10871,16 +10855,21 @@ var mParticle = (function () {
10871
10855
  severity: WSDKErrorSeverity.WARNING
10872
10856
  });
10873
10857
  }
10874
- if (!isEmpty(newIdentities)) {
10858
+ userAttributes_1 = this.toUserAttributes(mappedAttributes);
10859
+ if (isEmpty(newIdentities_1)) {
10860
+ this.setUserAttributes(this.currentUser, userAttributes_1);
10861
+ } else {
10875
10862
  // Fire-and-forget identify — best-effort, does not block selectPlacements
10876
10863
  try {
10877
10864
  this.identityService.identify({
10878
- userIdentities: __assign(__assign({}, currentUserIdentities), newIdentities)
10865
+ userIdentities: __assign(__assign({}, currentUserIdentities), newIdentities_1)
10879
10866
  }, function (result) {
10867
+ var _a;
10880
10868
  var httpCode = Number(result === null || result === void 0 ? void 0 : result.httpCode);
10881
10869
  if (httpCode && (httpCode >= 400 || httpCode < 0)) {
10882
10870
  _this.logger.error('Background identify failed with HTTP ' + httpCode);
10883
10871
  }
10872
+ _this.setUserAttributes((_a = result === null || result === void 0 ? void 0 : result.getUser) === null || _a === void 0 ? void 0 : _a.call(result), userAttributes_1, newIdentities_1);
10884
10873
  // Drain any selectPlacements calls that were deferred while
10885
10874
  // identify was in-flight. By the time this callback fires,
10886
10875
  // identityCallInFlight has already been reset to false.
@@ -10888,10 +10877,10 @@ var mParticle = (function () {
10888
10877
  });
10889
10878
  } catch (error) {
10890
10879
  this.logger.error('Background identify threw an error: ' + getErrorMessage(error));
10880
+ this.setUserAttributes(this.identityService.getCurrentUser(), userAttributes_1, newIdentities_1);
10891
10881
  }
10892
10882
  }
10893
- finalUserIdentities = __assign(__assign({}, currentUserIdentities), newIdentities);
10894
- this.setUserAttributes(mappedAttributes);
10883
+ finalUserIdentities = __assign(__assign({}, currentUserIdentities), newIdentities_1);
10895
10884
  timeOnSite = (_l = (_k = this.store) === null || _k === void 0 ? void 0 : _k.getTimeOnSite) === null || _l === void 0 ? void 0 : _l.call(_k);
10896
10885
  totalTimeOnSite = (_o = (_m = this.store) === null || _m === void 0 ? void 0 : _m.getTotalTimeOnSite) === null || _o === void 0 ? void 0 : _o.call(_m);
10897
10886
  enrichedAttributes = __assign(__assign(__assign(__assign({}, mappedAttributes), sandboxValue !== null ? {
@@ -11142,7 +11131,7 @@ var mParticle = (function () {
11142
11131
  // The Rokt Manager is ready when a kit is attached and has a launcher
11143
11132
  return Boolean(this.kit && this.kit.launcher);
11144
11133
  };
11145
- RoktManager.prototype.setUserAttributes = function (attributes) {
11134
+ RoktManager.prototype.toUserAttributes = function (attributes) {
11146
11135
  var reservedAttributes = ['sandbox'];
11147
11136
  var filteredAttributes = {};
11148
11137
  for (var key in attributes) {
@@ -11151,12 +11140,33 @@ var mParticle = (function () {
11151
11140
  filteredAttributes[key] = Array.isArray(value) ? JSON.stringify(value) : value;
11152
11141
  }
11153
11142
  }
11143
+ return filteredAttributes;
11144
+ };
11145
+ RoktManager.prototype.setUserAttributes = function (user, userAttributes, identitiesUserMustNotContradict) {
11146
+ if (identitiesUserMustNotContradict === void 0) {
11147
+ identitiesUserMustNotContradict = {};
11148
+ }
11149
+ if (!user) {
11150
+ this.logger.warning('selectPlacements attributes were not set because there is no user to set them on.');
11151
+ return;
11152
+ }
11154
11153
  try {
11155
- this.currentUser.setUserAttributes(filteredAttributes);
11154
+ if (this.hasContradictingIdentity(user, identitiesUserMustNotContradict)) {
11155
+ this.logger.warning('selectPlacements attributes were not set because identify did not resolve to a user with the passed email or hashed email.');
11156
+ return;
11157
+ }
11158
+ user.setUserAttributes(userAttributes);
11156
11159
  } catch (error) {
11157
11160
  this.logger.error('Error setting user attributes: ' + error);
11158
11161
  }
11159
11162
  };
11163
+ RoktManager.prototype.hasContradictingIdentity = function (user, identities) {
11164
+ return Object.keys(identities).some(function (identityType) {
11165
+ var _a, _b;
11166
+ var userValue = (_b = (_a = user.getUserIdentities()) === null || _a === void 0 ? void 0 : _a.userIdentities) === null || _b === void 0 ? void 0 : _b[identityType];
11167
+ return Boolean(userValue) && userValue !== identities[identityType];
11168
+ });
11169
+ };
11160
11170
  RoktManager.prototype.mapPlacementAttributes = function (attributes, placementAttributesMapping) {
11161
11171
  var mappingLookup = {};
11162
11172
  for (var _i = 0, placementAttributesMapping_1 = placementAttributesMapping; _i < placementAttributesMapping_1.length; _i++) {
@@ -25,6 +25,8 @@ export default class KitBlocker {
25
25
  getMatchKey(eventToMatch: BaseEvent): string | null;
26
26
  getProductAttributeMatchKey(eventToMatch: BaseEvent): string | null;
27
27
  createBlockedEvent(event: SDKEvent): SDKEvent;
28
+ applyBlockingStep(filteredData: string, step: (event: SDKEvent) => SDKEvent, event: SDKEvent, onFailure: (event: SDKEvent) => SDKEvent): SDKEvent;
29
+ reportFailedStep(filteredData: string, stepError: unknown): void;
28
30
  transformEventAndEventAttributes(event: SDKEvent): SDKEvent;
29
31
  transformProductAttributes(event: SDKEvent): SDKEvent;
30
32
  transformUserAttributes(event: SDKEvent): {
@@ -1,4 +1,4 @@
1
- import { IdentityApiData, MPID, Product, UserIdentities } from '@mparticle/web-sdk';
1
+ import { MPID, Product, UserIdentities } from '@mparticle/web-sdk';
2
2
  import { IForwardingStatsData } from './apiClient';
3
3
  import { IntegrationAttributes, ServerSettings, SessionAttributes, LocalSessionAttributes } from './store';
4
4
  import { Dictionary } from './utils';
@@ -52,7 +52,6 @@ export interface IPersistence {
52
52
  getCookie(): IPersistenceMinified | null;
53
53
  setCookie(): void;
54
54
  reduceAndEncodePersistence(persistence: IPersistenceMinified, expires: string, domain: string, maxCookieSize: number): string;
55
- findPrevCookiesBasedOnUI(identityApiData: IdentityApiData): void;
56
55
  encodePersistence(persistence: string): string;
57
56
  decodePersistence(persistenceString: string | null): string | void;
58
57
  getCookieDomain(): string;
@@ -174,7 +174,9 @@ export default class RoktManager {
174
174
  getLocalSessionAttributes(): LocalSessionAttributes;
175
175
  setLocalSessionAttribute(key: string, value: AttributeValue): void;
176
176
  isReady(): boolean;
177
+ private toUserAttributes;
177
178
  private setUserAttributes;
179
+ private hasContradictingIdentity;
178
180
  private mapPlacementAttributes;
179
181
  onIdentityComplete(): void;
180
182
  processMessageQueue(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mparticle/web-sdk",
3
- "version": "3.11.1",
3
+ "version": "3.12.1",
4
4
  "description": "mParticle core SDK for web applications",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -86,6 +86,9 @@
86
86
  "gts:fix": "gts fix",
87
87
  "prettier": "node_modules/.bin/prettier --check \"**/*.js\"",
88
88
  "typecheck:v3-candidate": "tsc -p tsconfig.candidate.json",
89
+ "typecheck:v3-release": "tsc -p tsconfig.v3-release.json",
90
+ "package:v3-candidate": "npm run typecheck:v3-candidate && node --experimental-strip-types scripts/package-v3-candidate.ts",
91
+ "check:v3-candidate": "node --experimental-strip-types scripts/check-v3-candidate.ts",
89
92
  "uglify": "npx uglify-js dist/mparticle.js --output dist/mparticle.min.js",
90
93
  "gzip": "gzip -c dist/mparticle.min.js > dist/mparticle.min.js.gz",
91
94
  "bundle": "npm run uglify && npm run gzip",
package/src/consent.ts CHANGED
@@ -285,37 +285,52 @@ export default function Consent(this: IConsent, mpInstance: IMParticleWebSDKInst
285
285
 
286
286
  fromMinifiedJsonObject(json: IMinifiedConsentJSONObject): ConsentState {
287
287
  const state: ConsentState = self.createConsentState();
288
- if (json.gdpr) {
288
+ if (!isObject(json)) {
289
+ return state;
290
+ }
291
+ if (isObject(json.gdpr)) {
289
292
  for (const purpose in json.gdpr) {
290
293
  if (hasOwnProp(json.gdpr, purpose)) {
291
- const gdprConsent = self.createPrivacyConsent(
292
- json.gdpr[purpose].c,
293
- json.gdpr[purpose].ts,
294
- json.gdpr[purpose].d,
295
- json.gdpr[purpose].l,
296
- json.gdpr[purpose].h
294
+ state.addGDPRConsentState(
295
+ purpose,
296
+ privacyConsentFromMinifiedJson(json.gdpr[purpose])
297
297
  );
298
- state.addGDPRConsentState(purpose, gdprConsent);
299
298
  }
300
299
  }
301
300
  }
302
301
 
303
- if (json.ccpa) {
302
+ if (isObject(json.ccpa)) {
304
303
  if (hasOwnProp(json.ccpa, CCPAPurpose)) {
305
- const ccpaConsent = self.createPrivacyConsent(
306
- json.ccpa[CCPAPurpose].c,
307
- json.ccpa[CCPAPurpose].ts,
308
- json.ccpa[CCPAPurpose].d,
309
- json.ccpa[CCPAPurpose].l,
310
- json.ccpa[CCPAPurpose].h
304
+ state.setCCPAConsentState(
305
+ privacyConsentFromMinifiedJson(json.ccpa[CCPAPurpose])
311
306
  );
312
- state.setCCPAConsentState(ccpaConsent);
313
307
  }
314
308
  }
315
309
  return state;
316
310
  },
317
311
  };
318
312
 
313
+ function privacyConsentFromMinifiedJson(
314
+ minifiedConsent: IPrivacyV2DTO
315
+ ): PrivacyConsentState | null {
316
+ if (!isObject(minifiedConsent)) {
317
+ return null;
318
+ }
319
+ const timestampIsObject =
320
+ typeof minifiedConsent.ts === 'object' &&
321
+ minifiedConsent.ts !== null;
322
+ if (timestampIsObject) {
323
+ return null;
324
+ }
325
+ return self.createPrivacyConsent(
326
+ minifiedConsent.c,
327
+ minifiedConsent.ts,
328
+ minifiedConsent.d,
329
+ minifiedConsent.l,
330
+ minifiedConsent.h
331
+ );
332
+ }
333
+
319
334
  // TODO: Refactor this method into a constructor
320
335
  this.createConsentState = function(
321
336
  this: ConsentState,
package/src/events.ts CHANGED
@@ -402,7 +402,7 @@ export default function Events(
402
402
  eventType: valueof<typeof EventType>
403
403
  ): void {
404
404
  let elements: ArrayLike<Element> | Element[] = [],
405
- handler = function(e: Event): void {
405
+ handler = function(e: Event, element: DOMHandlerElement): void {
406
406
  const timeoutHandler = function(): void {
407
407
  if (element.href) {
408
408
  window.location.href = element.href;
@@ -447,7 +447,6 @@ export default function Events(
447
447
  );
448
448
  }
449
449
  },
450
- element: DOMHandlerElement,
451
450
  i: number;
452
451
 
453
452
  if (!selector) {
@@ -472,17 +471,20 @@ export default function Events(
472
471
  );
473
472
 
474
473
  for (i = 0; i < elements.length; i++) {
475
- element = elements[i] as DOMHandlerElement;
474
+ const element = elements[i] as DOMHandlerElement;
475
+ const elementHandler = function(e: Event): void {
476
+ handler(e, element);
477
+ };
476
478
 
477
479
  if (element.addEventListener) {
478
480
  // Modern browsers
479
- element.addEventListener(domEvent, handler, false);
481
+ element.addEventListener(domEvent, elementHandler, false);
480
482
  } else if (element.attachEvent) {
481
483
  // IE < 9
482
- element.attachEvent('on' + domEvent, handler);
484
+ element.attachEvent('on' + domEvent, elementHandler);
483
485
  } else {
484
486
  // All other browsers
485
- (element as any)['on' + domEvent] = handler;
487
+ (element as any)['on' + domEvent] = elementHandler;
486
488
  }
487
489
  }
488
490
  } else {