@mparticle/web-sdk 2.79.3 → 2.80.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.
- package/dist/mparticle.common.js +146 -87
- package/dist/mparticle.esm.js +146 -87
- package/dist/mparticle.js +1427 -1251
- package/dist/types/src/pageViewTracker.d.ts +12 -5
- package/dist/types/src/persistence.d.ts +3 -44
- package/dist/types/src/persistence.interfaces.d.ts +10 -10
- package/dist/types/src/sdkRuntimeModels.d.ts +1 -0
- package/dist/types/src/store.d.ts +1 -0
- package/package.json +1 -1
- package/src/events.ts +9 -1
- package/src/pageViewTracker.ts +176 -42
- package/src/persistence.interfaces.ts +10 -10
- package/src/persistence.ts +1210 -0
- package/src/sdkRuntimeModels.ts +1 -0
- package/src/store.ts +1 -0
- package/src/persistence.js +0 -985
package/dist/mparticle.js
CHANGED
|
@@ -204,7 +204,7 @@ var mParticle = (function () {
|
|
|
204
204
|
Base64: Base64$1
|
|
205
205
|
};
|
|
206
206
|
|
|
207
|
-
var version = "2.
|
|
207
|
+
var version = "2.80.0";
|
|
208
208
|
|
|
209
209
|
var Constants = {
|
|
210
210
|
sdkVersion: version,
|
|
@@ -5605,90 +5605,101 @@ var mParticle = (function () {
|
|
|
5605
5605
|
Base64CookieKeys = Constants.Base64CookieKeys,
|
|
5606
5606
|
SDKv2NonMPIDCookieKeys = Constants.SDKv2NonMPIDCookieKeys,
|
|
5607
5607
|
StorageNames = Constants.StorageNames;
|
|
5608
|
+
function getMParticleManager() {
|
|
5609
|
+
return window.mParticle;
|
|
5610
|
+
}
|
|
5608
5611
|
function _Persistence(mpInstance) {
|
|
5609
5612
|
var self = this;
|
|
5610
|
-
|
|
5611
5613
|
// https://go.mparticle.com/work/SQDSDKS-5022
|
|
5612
5614
|
this.useLocalStorage = function () {
|
|
5613
5615
|
return !mpInstance._Store.SDKConfig.useCookieStorage && mpInstance._Store.isLocalStorageAvailable;
|
|
5614
5616
|
};
|
|
5617
|
+
function setFirstRunFromExistingData(localStorageData, cookies) {
|
|
5618
|
+
if (!localStorageData && !cookies) {
|
|
5619
|
+
mpInstance._Store.isFirstRun = true;
|
|
5620
|
+
mpInstance._Store.mpid = 0;
|
|
5621
|
+
return;
|
|
5622
|
+
}
|
|
5623
|
+
mpInstance._Store.isFirstRun = false;
|
|
5624
|
+
}
|
|
5625
|
+
function mergeStorageSources(localStorageData, cookies) {
|
|
5626
|
+
if (localStorageData && cookies) {
|
|
5627
|
+
// https://go.mparticle.com/work/SQDSDKS-6047
|
|
5628
|
+
return extend(false, localStorageData, cookies);
|
|
5629
|
+
}
|
|
5630
|
+
return localStorageData || cookies;
|
|
5631
|
+
}
|
|
5632
|
+
// For migrating from localStorage to cookies -- If an instance switches from
|
|
5633
|
+
// localStorage to cookies, then no mParticle cookie exists yet and there is
|
|
5634
|
+
// localStorage. Get the localStorage, set them to cookies, then delete the
|
|
5635
|
+
// localStorage item.
|
|
5636
|
+
function migrateLocalStorageToCookies(storage, localStorageData, cookies) {
|
|
5637
|
+
var allData;
|
|
5638
|
+
if (localStorageData) {
|
|
5639
|
+
allData = mergeStorageSources(localStorageData, cookies);
|
|
5640
|
+
storage.removeItem(mpInstance._Store.storageName);
|
|
5641
|
+
} else if (cookies) {
|
|
5642
|
+
allData = cookies;
|
|
5643
|
+
}
|
|
5644
|
+
self.storeDataInMemory(allData);
|
|
5645
|
+
return allData;
|
|
5646
|
+
}
|
|
5647
|
+
// For migrating from cookie to localStorage -- If an instance is newly
|
|
5648
|
+
// switching from cookies to localStorage, then no mParticle localStorage
|
|
5649
|
+
// exists yet and there are cookies. Get the cookies, set them to
|
|
5650
|
+
// localStorage, then delete the cookies.
|
|
5651
|
+
function migrateCookiesToLocalStorage(localStorageData, cookies) {
|
|
5652
|
+
if (!cookies) {
|
|
5653
|
+
self.storeDataInMemory(localStorageData);
|
|
5654
|
+
return;
|
|
5655
|
+
}
|
|
5656
|
+
var allData = mergeStorageSources(localStorageData, cookies);
|
|
5657
|
+
self.storeDataInMemory(allData);
|
|
5658
|
+
self.expireCookies(mpInstance._Store.storageName);
|
|
5659
|
+
return allData;
|
|
5660
|
+
}
|
|
5661
|
+
function loadPersistenceIntoMemory(localStorageData, cookies) {
|
|
5662
|
+
if (!mpInstance._Store.isLocalStorageAvailable) {
|
|
5663
|
+
self.storeDataInMemory(cookies);
|
|
5664
|
+
return;
|
|
5665
|
+
}
|
|
5666
|
+
if (mpInstance._Store.SDKConfig.useCookieStorage) {
|
|
5667
|
+
return migrateLocalStorageToCookies(window.localStorage, localStorageData, cookies);
|
|
5668
|
+
}
|
|
5669
|
+
return migrateCookiesToLocalStorage(localStorageData, cookies);
|
|
5670
|
+
}
|
|
5671
|
+
function copyNonCurrentUserMpids(allData) {
|
|
5672
|
+
for (var key in allData) {
|
|
5673
|
+
if (allData.hasOwnProperty(key) && !SDKv2NonMPIDCookieKeys[key]) {
|
|
5674
|
+
mpInstance._Store.nonCurrentUserMPIDs[key] = allData[key];
|
|
5675
|
+
}
|
|
5676
|
+
}
|
|
5677
|
+
}
|
|
5678
|
+
function clearCorruptStorage() {
|
|
5679
|
+
if (self.useLocalStorage() && mpInstance._Store.isLocalStorageAvailable) {
|
|
5680
|
+
localStorage.removeItem(mpInstance._Store.storageName);
|
|
5681
|
+
return;
|
|
5682
|
+
}
|
|
5683
|
+
self.expireCookies(mpInstance._Store.storageName);
|
|
5684
|
+
}
|
|
5615
5685
|
this.initializeStorage = function () {
|
|
5616
5686
|
try {
|
|
5617
|
-
var
|
|
5618
|
-
|
|
5619
|
-
cookies = self.getCookie(),
|
|
5620
|
-
allData;
|
|
5621
|
-
|
|
5687
|
+
var localStorageData = self.getLocalStorage();
|
|
5688
|
+
var cookies = self.getCookie();
|
|
5622
5689
|
// https://go.mparticle.com/work/SQDSDKS-6045
|
|
5623
|
-
|
|
5624
|
-
if (!localStorageData && !cookies) {
|
|
5625
|
-
mpInstance._Store.isFirstRun = true;
|
|
5626
|
-
mpInstance._Store.mpid = 0;
|
|
5627
|
-
} else {
|
|
5628
|
-
mpInstance._Store.isFirstRun = false;
|
|
5629
|
-
}
|
|
5630
|
-
|
|
5690
|
+
setFirstRunFromExistingData(localStorageData, cookies);
|
|
5631
5691
|
// https://go.mparticle.com/work/SQDSDKS-6045
|
|
5632
5692
|
if (!mpInstance._Store.isLocalStorageAvailable) {
|
|
5633
5693
|
mpInstance._Store.SDKConfig.useCookieStorage = true;
|
|
5634
5694
|
}
|
|
5635
|
-
|
|
5636
|
-
// https://go.mparticle.com/work/SQDSDKS-6046
|
|
5637
|
-
if (mpInstance._Store.isLocalStorageAvailable) {
|
|
5638
|
-
storage = window.localStorage;
|
|
5639
|
-
if (mpInstance._Store.SDKConfig.useCookieStorage) {
|
|
5640
|
-
// For migrating from localStorage to cookies -- If an instance switches from localStorage to cookies, then
|
|
5641
|
-
// no mParticle cookie exists yet and there is localStorage. Get the localStorage, set them to cookies, then delete the localStorage item.
|
|
5642
|
-
if (localStorageData) {
|
|
5643
|
-
if (cookies) {
|
|
5644
|
-
// https://go.mparticle.com/work/SQDSDKS-6047
|
|
5645
|
-
allData = extend(false, localStorageData, cookies);
|
|
5646
|
-
} else {
|
|
5647
|
-
allData = localStorageData;
|
|
5648
|
-
}
|
|
5649
|
-
storage.removeItem(mpInstance._Store.storageName);
|
|
5650
|
-
} else if (cookies) {
|
|
5651
|
-
allData = cookies;
|
|
5652
|
-
}
|
|
5653
|
-
self.storeDataInMemory(allData);
|
|
5654
|
-
} else {
|
|
5655
|
-
// For migrating from cookie to localStorage -- If an instance is newly switching from cookies to localStorage, then
|
|
5656
|
-
// no mParticle localStorage exists yet and there are cookies. Get the cookies, set them to localStorage, then delete the cookies.
|
|
5657
|
-
if (cookies) {
|
|
5658
|
-
if (localStorageData) {
|
|
5659
|
-
// https://go.mparticle.com/work/SQDSDKS-6047
|
|
5660
|
-
allData = extend(false, localStorageData, cookies);
|
|
5661
|
-
} else {
|
|
5662
|
-
allData = cookies;
|
|
5663
|
-
}
|
|
5664
|
-
self.storeDataInMemory(allData);
|
|
5665
|
-
self.expireCookies(mpInstance._Store.storageName);
|
|
5666
|
-
} else {
|
|
5667
|
-
self.storeDataInMemory(localStorageData);
|
|
5668
|
-
}
|
|
5669
|
-
}
|
|
5670
|
-
} else {
|
|
5671
|
-
self.storeDataInMemory(cookies);
|
|
5672
|
-
}
|
|
5673
|
-
|
|
5674
5695
|
// https://go.mparticle.com/work/SQDSDKS-6046
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
if (allData.hasOwnProperty(key)) {
|
|
5678
|
-
if (!SDKv2NonMPIDCookieKeys[key]) {
|
|
5679
|
-
mpInstance._Store.nonCurrentUserMPIDs[key] = allData[key];
|
|
5680
|
-
}
|
|
5681
|
-
}
|
|
5682
|
-
}
|
|
5696
|
+
var allData = loadPersistenceIntoMemory(localStorageData, cookies);
|
|
5697
|
+
copyNonCurrentUserMpids(allData);
|
|
5683
5698
|
self.update();
|
|
5684
5699
|
} catch (e) {
|
|
5685
5700
|
// If cookies or local storage is corrupt, we want to remove it
|
|
5686
5701
|
// so that in the future, initializeStorage will work
|
|
5687
|
-
|
|
5688
|
-
localStorage.removeItem(mpInstance._Store.storageName);
|
|
5689
|
-
} else {
|
|
5690
|
-
self.expireCookies(mpInstance._Store.storageName);
|
|
5691
|
-
}
|
|
5702
|
+
clearCorruptStorage();
|
|
5692
5703
|
mpInstance.Logger.error('Error initializing storage: ' + e);
|
|
5693
5704
|
}
|
|
5694
5705
|
};
|
|
@@ -5700,86 +5711,83 @@ var mParticle = (function () {
|
|
|
5700
5711
|
self.setLocalStorage();
|
|
5701
5712
|
}
|
|
5702
5713
|
};
|
|
5703
|
-
|
|
5714
|
+
function applyEmptyPersistenceDefaults() {
|
|
5715
|
+
mpInstance.Logger.verbose(Messages$4.InformationMessages.CookieNotFound);
|
|
5716
|
+
mpInstance._Store.clientId = mpInstance._Store.clientId || mpInstance._Helpers.generateUniqueId();
|
|
5717
|
+
mpInstance._Store.deviceId = mpInstance._Store.deviceId || mpInstance._Helpers.generateUniqueId();
|
|
5718
|
+
}
|
|
5719
|
+
function hydrateStoreFromPersistence(obj, currentMPID) {
|
|
5720
|
+
// Set MPID first, then change object to match MPID data
|
|
5721
|
+
if (currentMPID) {
|
|
5722
|
+
mpInstance._Store.mpid = currentMPID;
|
|
5723
|
+
} else {
|
|
5724
|
+
mpInstance._Store.mpid = obj.cu || 0;
|
|
5725
|
+
}
|
|
5726
|
+
obj.gs = obj.gs || {};
|
|
5727
|
+
mpInstance._Store.sessionId = obj.gs.sid || mpInstance._Store.sessionId;
|
|
5728
|
+
mpInstance._Store.isEnabled = typeof obj.gs.ie !== 'undefined' ? obj.gs.ie : mpInstance._Store.isEnabled;
|
|
5729
|
+
mpInstance._Store.sessionAttributes = obj.gs.sa || mpInstance._Store.sessionAttributes;
|
|
5730
|
+
mpInstance._Store.localSessionAttributes = obj.gs.lsa || mpInstance._Store.localSessionAttributes;
|
|
5731
|
+
mpInstance._Store.serverSettings = obj.gs.ss || mpInstance._Store.serverSettings;
|
|
5732
|
+
mpInstance._Store.devToken = mpInstance._Store.devToken || obj.gs.dt;
|
|
5733
|
+
mpInstance._Store.SDKConfig.appVersion = mpInstance._Store.SDKConfig.appVersion || obj.gs.av;
|
|
5734
|
+
mpInstance._Store.clientId = obj.gs.cgid || mpInstance._Store.clientId || mpInstance._Helpers.generateUniqueId();
|
|
5735
|
+
// For most persistence values, we prioritize localstorage/cookie values over
|
|
5736
|
+
// Store. However, we allow device ID to be overriden via a config value and
|
|
5737
|
+
// thus the priority of the deviceId value is
|
|
5738
|
+
// 1. value passed via config.deviceId
|
|
5739
|
+
// 2. previous value in persistence
|
|
5740
|
+
// 3. generate new guid
|
|
5741
|
+
mpInstance._Store.deviceId = mpInstance._Store.deviceId || obj.gs.das || mpInstance._Helpers.generateUniqueId();
|
|
5742
|
+
mpInstance._Store.integrationAttributes = obj.gs.ia || {};
|
|
5743
|
+
mpInstance._Store.context = obj.gs.c || mpInstance._Store.context;
|
|
5744
|
+
mpInstance._Store.currentSessionMPIDs = obj.gs.csm || mpInstance._Store.currentSessionMPIDs;
|
|
5745
|
+
mpInstance._Store.isLoggedIn = obj.l === true;
|
|
5746
|
+
if (obj.gs.les) {
|
|
5747
|
+
mpInstance._Store.dateLastEventSent = new Date(obj.gs.les);
|
|
5748
|
+
}
|
|
5749
|
+
mpInstance._Store.sessionStartDate = obj.gs.ssd ? new Date(obj.gs.ssd) : new Date();
|
|
5750
|
+
if (currentMPID) {
|
|
5751
|
+
obj = obj[currentMPID];
|
|
5752
|
+
} else {
|
|
5753
|
+
obj = obj[obj.cu];
|
|
5754
|
+
}
|
|
5755
|
+
}
|
|
5704
5756
|
// https://go.mparticle.com/work/SQDSDKS-6045
|
|
5705
5757
|
this.storeDataInMemory = function (obj, currentMPID) {
|
|
5706
5758
|
try {
|
|
5707
5759
|
if (!obj) {
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
mpInstance._Store.deviceId = mpInstance._Store.deviceId || mpInstance._Helpers.generateUniqueId();
|
|
5711
|
-
} else {
|
|
5712
|
-
// Set MPID first, then change object to match MPID data
|
|
5713
|
-
if (currentMPID) {
|
|
5714
|
-
mpInstance._Store.mpid = currentMPID;
|
|
5715
|
-
} else {
|
|
5716
|
-
mpInstance._Store.mpid = obj.cu || 0;
|
|
5717
|
-
}
|
|
5718
|
-
obj.gs = obj.gs || {};
|
|
5719
|
-
mpInstance._Store.sessionId = obj.gs.sid || mpInstance._Store.sessionId;
|
|
5720
|
-
mpInstance._Store.isEnabled = typeof obj.gs.ie !== 'undefined' ? obj.gs.ie : mpInstance._Store.isEnabled;
|
|
5721
|
-
mpInstance._Store.sessionAttributes = obj.gs.sa || mpInstance._Store.sessionAttributes;
|
|
5722
|
-
mpInstance._Store.localSessionAttributes = obj.gs.lsa || mpInstance._Store.localSessionAttributes;
|
|
5723
|
-
mpInstance._Store.serverSettings = obj.gs.ss || mpInstance._Store.serverSettings;
|
|
5724
|
-
mpInstance._Store.devToken = mpInstance._Store.devToken || obj.gs.dt;
|
|
5725
|
-
mpInstance._Store.SDKConfig.appVersion = mpInstance._Store.SDKConfig.appVersion || obj.gs.av;
|
|
5726
|
-
mpInstance._Store.clientId = obj.gs.cgid || mpInstance._Store.clientId || mpInstance._Helpers.generateUniqueId();
|
|
5727
|
-
|
|
5728
|
-
// For most persistence values, we prioritize localstorage/cookie values over
|
|
5729
|
-
// Store. However, we allow device ID to be overriden via a config value and
|
|
5730
|
-
// thus the priority of the deviceId value is
|
|
5731
|
-
// 1. value passed via config.deviceId
|
|
5732
|
-
// 2. previous value in persistence
|
|
5733
|
-
// 3. generate new guid
|
|
5734
|
-
mpInstance._Store.deviceId = mpInstance._Store.deviceId || obj.gs.das || mpInstance._Helpers.generateUniqueId();
|
|
5735
|
-
mpInstance._Store.integrationAttributes = obj.gs.ia || {};
|
|
5736
|
-
mpInstance._Store.context = obj.gs.c || mpInstance._Store.context;
|
|
5737
|
-
mpInstance._Store.currentSessionMPIDs = obj.gs.csm || mpInstance._Store.currentSessionMPIDs;
|
|
5738
|
-
mpInstance._Store.isLoggedIn = obj.l === true;
|
|
5739
|
-
if (obj.gs.les) {
|
|
5740
|
-
mpInstance._Store.dateLastEventSent = new Date(obj.gs.les);
|
|
5741
|
-
}
|
|
5742
|
-
if (obj.gs.ssd) {
|
|
5743
|
-
mpInstance._Store.sessionStartDate = new Date(obj.gs.ssd);
|
|
5744
|
-
} else {
|
|
5745
|
-
mpInstance._Store.sessionStartDate = new Date();
|
|
5746
|
-
}
|
|
5747
|
-
if (currentMPID) {
|
|
5748
|
-
obj = obj[currentMPID];
|
|
5749
|
-
} else {
|
|
5750
|
-
obj = obj[obj.cu];
|
|
5751
|
-
}
|
|
5760
|
+
applyEmptyPersistenceDefaults();
|
|
5761
|
+
return;
|
|
5752
5762
|
}
|
|
5763
|
+
hydrateStoreFromPersistence(obj, currentMPID);
|
|
5753
5764
|
} catch (e) {
|
|
5754
5765
|
mpInstance.Logger.error(Messages$4.ErrorMessages.CookieParseError);
|
|
5755
5766
|
}
|
|
5756
5767
|
};
|
|
5757
|
-
|
|
5758
5768
|
// https://go.mparticle.com/work/SQDSDKS-5022
|
|
5759
5769
|
this.determineLocalStorageAvailability = function (storage) {
|
|
5760
|
-
var
|
|
5761
|
-
if (
|
|
5762
|
-
|
|
5770
|
+
var mParticleManager = getMParticleManager();
|
|
5771
|
+
if (mParticleManager === null || mParticleManager === void 0 ? void 0 : mParticleManager._forceNoLocalStorage) {
|
|
5772
|
+
return false;
|
|
5763
5773
|
}
|
|
5764
5774
|
try {
|
|
5765
5775
|
storage.setItem('mparticle', 'test');
|
|
5766
|
-
result = storage.getItem('mparticle') === 'test';
|
|
5776
|
+
var result = storage.getItem('mparticle') === 'test';
|
|
5767
5777
|
storage.removeItem('mparticle');
|
|
5768
|
-
return result && storage;
|
|
5778
|
+
return Boolean(result && storage);
|
|
5769
5779
|
} catch (e) {
|
|
5770
5780
|
return false;
|
|
5771
5781
|
}
|
|
5772
5782
|
};
|
|
5773
|
-
|
|
5774
5783
|
// https://go.mparticle.com/work/SQDSDKS-6021
|
|
5775
5784
|
this.setLocalStorage = function () {
|
|
5776
|
-
var
|
|
5785
|
+
var _a;
|
|
5777
5786
|
if (!mpInstance._Store.isLocalStorageAvailable) {
|
|
5778
5787
|
return;
|
|
5779
5788
|
}
|
|
5780
|
-
|
|
5781
5789
|
// Block mprtcl-v4 localStorage when noFunctional is true
|
|
5782
|
-
if ((
|
|
5790
|
+
if ((_a = mpInstance._CookieConsentManager) === null || _a === void 0 ? void 0 : _a.getNoFunctional()) {
|
|
5783
5791
|
return;
|
|
5784
5792
|
}
|
|
5785
5793
|
var key = mpInstance._Store.storageName,
|
|
@@ -5829,16 +5837,16 @@ var mParticle = (function () {
|
|
|
5829
5837
|
if (!mpInstance._Store.isLocalStorageAvailable) {
|
|
5830
5838
|
return null;
|
|
5831
5839
|
}
|
|
5832
|
-
var key = mpInstance._Store.storageName
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5840
|
+
var key = mpInstance._Store.storageName;
|
|
5841
|
+
var decodedPersistence = self.decodePersistence(window.localStorage.getItem(key));
|
|
5842
|
+
if (!decodedPersistence) {
|
|
5843
|
+
return null;
|
|
5844
|
+
}
|
|
5845
|
+
var parsedPersistence = JSON.parse(decodedPersistence);
|
|
5846
|
+
var obj = {};
|
|
5847
|
+
for (var key_1 in parsedPersistence) {
|
|
5848
|
+
if (parsedPersistence.hasOwnProperty(key_1)) {
|
|
5849
|
+
obj[key_1] = parsedPersistence[key_1];
|
|
5842
5850
|
}
|
|
5843
5851
|
}
|
|
5844
5852
|
if (Object.keys(obj).length) {
|
|
@@ -5846,9 +5854,6 @@ var mParticle = (function () {
|
|
|
5846
5854
|
}
|
|
5847
5855
|
return null;
|
|
5848
5856
|
};
|
|
5849
|
-
function removeLocalStorage(localStorageName) {
|
|
5850
|
-
localStorage.removeItem(localStorageName);
|
|
5851
|
-
}
|
|
5852
5857
|
this.expireCookies = function (cookieName) {
|
|
5853
5858
|
var date = new Date(),
|
|
5854
5859
|
expires,
|
|
@@ -5903,13 +5908,12 @@ var mParticle = (function () {
|
|
|
5903
5908
|
return null;
|
|
5904
5909
|
}
|
|
5905
5910
|
};
|
|
5906
|
-
|
|
5907
5911
|
// https://go.mparticle.com/work/SQDSDKS-5022
|
|
5908
5912
|
// https://go.mparticle.com/work/SQDSDKS-6021
|
|
5909
5913
|
this.setCookie = function () {
|
|
5910
|
-
var
|
|
5914
|
+
var _a;
|
|
5911
5915
|
// Block mprtcl-v4 cookies when noFunctional is true
|
|
5912
|
-
if ((
|
|
5916
|
+
if ((_a = mpInstance._CookieConsentManager) === null || _a === void 0 ? void 0 : _a.getNoFunctional()) {
|
|
5913
5917
|
return;
|
|
5914
5918
|
}
|
|
5915
5919
|
var mpid,
|
|
@@ -5920,7 +5924,7 @@ var mParticle = (function () {
|
|
|
5920
5924
|
var date = new Date(),
|
|
5921
5925
|
key = mpInstance._Store.storageName,
|
|
5922
5926
|
cookies = self.getCookie() || {},
|
|
5923
|
-
expires = new Date(date.getTime() + mpInstance._Store.SDKConfig.cookieExpiration * 24 * 60 * 60 * 1000).
|
|
5927
|
+
expires = new Date(date.getTime() + mpInstance._Store.SDKConfig.cookieExpiration * 24 * 60 * 60 * 1000).toUTCString(),
|
|
5924
5928
|
cookieDomain,
|
|
5925
5929
|
domain,
|
|
5926
5930
|
encodedCookiesWithExpirationAndPath;
|
|
@@ -5947,7 +5951,6 @@ var mParticle = (function () {
|
|
|
5947
5951
|
mpInstance.Logger.verbose(Messages$4.InformationMessages.CookieSet);
|
|
5948
5952
|
window.document.cookie = encodeURIComponent(key) + '=' + encodedCookiesWithExpirationAndPath;
|
|
5949
5953
|
};
|
|
5950
|
-
|
|
5951
5954
|
/* This function determines if a cookie is greater than the configured maxCookieSize.
|
|
5952
5955
|
- If it is, we remove an MPID and its associated UI/UA/CSD from the cookie.
|
|
5953
5956
|
- Once removed, check size, and repeat.
|
|
@@ -5959,171 +5962,258 @@ var mParticle = (function () {
|
|
|
5959
5962
|
b. Then remove MPIDs based on order in currentSessionMPIDs array, which
|
|
5960
5963
|
stores MPIDs based on earliest login.
|
|
5961
5964
|
*/
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
if (encodedCookiesWithExpirationAndPath.length > maxCookieSize) {
|
|
5971
|
-
if (!SDKv2NonMPIDCookieKeys[key] && key !== persistence.cu) {
|
|
5972
|
-
delete persistence[key];
|
|
5973
|
-
}
|
|
5974
|
-
}
|
|
5975
|
-
}
|
|
5965
|
+
function isEncodedCookieTooLarge(encoded, maxCookieSize) {
|
|
5966
|
+
return encoded.length > maxCookieSize;
|
|
5967
|
+
}
|
|
5968
|
+
function removeUnsessionedMpidsWhenOversized(persistence, expires, domain, maxCookieSize) {
|
|
5969
|
+
var encodedCookiesWithExpirationAndPath;
|
|
5970
|
+
for (var key in persistence) {
|
|
5971
|
+
if (!persistence.hasOwnProperty(key)) {
|
|
5972
|
+
continue;
|
|
5976
5973
|
}
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
for (var potentialMPID in persistence) {
|
|
5981
|
-
if (persistence.hasOwnProperty(potentialMPID)) {
|
|
5982
|
-
if (!SDKv2NonMPIDCookieKeys[potentialMPID] && potentialMPID !== persistence.cu) {
|
|
5983
|
-
MPIDsOnCookie[potentialMPID] = 1;
|
|
5984
|
-
}
|
|
5985
|
-
}
|
|
5974
|
+
encodedCookiesWithExpirationAndPath = createFullEncodedCookie(persistence, expires, domain);
|
|
5975
|
+
if (!isEncodedCookieTooLarge(encodedCookiesWithExpirationAndPath, maxCookieSize)) {
|
|
5976
|
+
continue;
|
|
5986
5977
|
}
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
for (var mpid in MPIDsOnCookie) {
|
|
5990
|
-
encodedCookiesWithExpirationAndPath = createFullEncodedCookie(persistence, expires, domain);
|
|
5991
|
-
if (encodedCookiesWithExpirationAndPath.length > maxCookieSize) {
|
|
5992
|
-
if (MPIDsOnCookie.hasOwnProperty(mpid)) {
|
|
5993
|
-
if (currentSessionMPIDs.indexOf(mpid) === -1) {
|
|
5994
|
-
delete persistence[mpid];
|
|
5995
|
-
}
|
|
5996
|
-
}
|
|
5997
|
-
}
|
|
5998
|
-
}
|
|
5978
|
+
if (SDKv2NonMPIDCookieKeys[key] || key === persistence.cu) {
|
|
5979
|
+
continue;
|
|
5999
5980
|
}
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
5981
|
+
delete persistence[key];
|
|
5982
|
+
}
|
|
5983
|
+
return encodedCookiesWithExpirationAndPath;
|
|
5984
|
+
}
|
|
5985
|
+
function collectRemovableMpids(persistence) {
|
|
5986
|
+
var MPIDsOnCookie = {};
|
|
5987
|
+
for (var potentialMPID in persistence) {
|
|
5988
|
+
if (!persistence.hasOwnProperty(potentialMPID)) {
|
|
5989
|
+
continue;
|
|
5990
|
+
}
|
|
5991
|
+
if (SDKv2NonMPIDCookieKeys[potentialMPID] || potentialMPID === persistence.cu) {
|
|
5992
|
+
continue;
|
|
5993
|
+
}
|
|
5994
|
+
MPIDsOnCookie[potentialMPID] = 1;
|
|
5995
|
+
}
|
|
5996
|
+
return MPIDsOnCookie;
|
|
5997
|
+
}
|
|
5998
|
+
function removeMpidsNotInCurrentSession(persistence, MPIDsOnCookie, currentSessionMPIDs, expires, domain, maxCookieSize) {
|
|
5999
|
+
var encodedCookiesWithExpirationAndPath;
|
|
6000
|
+
for (var mpid in MPIDsOnCookie) {
|
|
6001
|
+
encodedCookiesWithExpirationAndPath = createFullEncodedCookie(persistence, expires, domain);
|
|
6002
|
+
if (!isEncodedCookieTooLarge(encodedCookiesWithExpirationAndPath, maxCookieSize)) {
|
|
6003
|
+
continue;
|
|
6004
|
+
}
|
|
6005
|
+
if (!MPIDsOnCookie.hasOwnProperty(mpid)) {
|
|
6006
|
+
continue;
|
|
6007
|
+
}
|
|
6008
|
+
if (currentSessionMPIDs.indexOf(mpid) === -1) {
|
|
6009
|
+
delete persistence[mpid];
|
|
6010
|
+
}
|
|
6011
|
+
}
|
|
6012
|
+
return encodedCookiesWithExpirationAndPath;
|
|
6013
|
+
}
|
|
6014
|
+
function logAndRemoveOversizedMpid(persistence, MPIDtoRemove, maxCookieSize) {
|
|
6015
|
+
if (persistence[MPIDtoRemove]) {
|
|
6016
|
+
mpInstance.Logger.verbose('Size of new encoded cookie is larger than maxCookieSize setting of ' + maxCookieSize + '. Removing from cookie the earliest logged in MPID containing: ' + JSON.stringify(persistence[MPIDtoRemove], null, 2));
|
|
6017
|
+
delete persistence[MPIDtoRemove];
|
|
6018
|
+
return;
|
|
6019
|
+
}
|
|
6020
|
+
mpInstance.Logger.error('Unable to save MPID data to cookies because the resulting encoded cookie is larger than the maxCookieSize setting of ' + maxCookieSize + '. We recommend using a maxCookieSize of 1500.');
|
|
6021
|
+
}
|
|
6022
|
+
function removeCurrentSessionMpidsByAge(persistence, currentSessionMPIDs, expires, domain, maxCookieSize) {
|
|
6023
|
+
var encodedCookiesWithExpirationAndPath;
|
|
6024
|
+
for (var i = 0; i < currentSessionMPIDs.length; i++) {
|
|
6025
|
+
encodedCookiesWithExpirationAndPath = createFullEncodedCookie(persistence, expires, domain);
|
|
6026
|
+
if (!isEncodedCookieTooLarge(encodedCookiesWithExpirationAndPath, maxCookieSize)) {
|
|
6027
|
+
break;
|
|
6014
6028
|
}
|
|
6029
|
+
logAndRemoveOversizedMpid(persistence, currentSessionMPIDs[i], maxCookieSize);
|
|
6015
6030
|
}
|
|
6016
6031
|
return encodedCookiesWithExpirationAndPath;
|
|
6032
|
+
}
|
|
6033
|
+
this.reduceAndEncodePersistence = function (persistence, expires, domain, maxCookieSize) {
|
|
6034
|
+
var currentSessionMPIDs = persistence.gs.csm ? persistence.gs.csm : [];
|
|
6035
|
+
if (!currentSessionMPIDs.length) {
|
|
6036
|
+
return removeUnsessionedMpidsWhenOversized(persistence, expires, domain, maxCookieSize);
|
|
6037
|
+
}
|
|
6038
|
+
var MPIDsOnCookie = collectRemovableMpids(persistence);
|
|
6039
|
+
if (Object.keys(MPIDsOnCookie).length) {
|
|
6040
|
+
removeMpidsNotInCurrentSession(persistence, MPIDsOnCookie, currentSessionMPIDs, expires, domain, maxCookieSize);
|
|
6041
|
+
}
|
|
6042
|
+
return removeCurrentSessionMpidsByAge(persistence, currentSessionMPIDs, expires, domain, maxCookieSize);
|
|
6017
6043
|
};
|
|
6018
6044
|
function createFullEncodedCookie(persistence, expires, domain) {
|
|
6019
6045
|
return self.encodePersistence(JSON.stringify(persistence)) + ';expires=' + expires + ';path=/' + domain;
|
|
6020
6046
|
}
|
|
6021
|
-
|
|
6022
|
-
var
|
|
6047
|
+
function cookieUiMatchesRequestedIdentity(cookieUIs, requestedIdentityType, requestedValue) {
|
|
6048
|
+
for (var cookieUIType in cookieUIs) {
|
|
6049
|
+
if (requestedIdentityType === cookieUIType && requestedValue === cookieUIs[cookieUIType]) {
|
|
6050
|
+
return true;
|
|
6051
|
+
}
|
|
6052
|
+
}
|
|
6053
|
+
return false;
|
|
6054
|
+
}
|
|
6055
|
+
function findMpidForRequestedIdentity(persistence, requestedIdentityType, requestedValue) {
|
|
6023
6056
|
var matchedUser;
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6057
|
+
for (var key in persistence) {
|
|
6058
|
+
// any value in persistence that has an MPID key will be an MPID to search through
|
|
6059
|
+
// other keys on the cookie are currentSessionMPIDs and currentMPID which should not be searched
|
|
6060
|
+
if (!persistence[key].mpid) {
|
|
6061
|
+
continue;
|
|
6062
|
+
}
|
|
6063
|
+
if (cookieUiMatchesRequestedIdentity(persistence[key].ui, requestedIdentityType, requestedValue)) {
|
|
6064
|
+
matchedUser = key;
|
|
6065
|
+
}
|
|
6066
|
+
}
|
|
6067
|
+
return matchedUser;
|
|
6068
|
+
}
|
|
6069
|
+
function findMpidMatchingIdentities(persistence, identityApiData) {
|
|
6070
|
+
var matchedUser;
|
|
6071
|
+
for (var requestedIdentityType in identityApiData.userIdentities) {
|
|
6072
|
+
if (!persistence || !Object.keys(persistence).length) {
|
|
6073
|
+
continue;
|
|
6074
|
+
}
|
|
6075
|
+
var match = findMpidForRequestedIdentity(persistence, requestedIdentityType, identityApiData.userIdentities[requestedIdentityType]);
|
|
6076
|
+
if (match) {
|
|
6077
|
+
matchedUser = match;
|
|
6041
6078
|
}
|
|
6042
6079
|
}
|
|
6080
|
+
return matchedUser;
|
|
6081
|
+
}
|
|
6082
|
+
this.findPrevCookiesBasedOnUI = function (identityApiData) {
|
|
6083
|
+
var persistence = mpInstance._Persistence.getPersistence();
|
|
6084
|
+
if (!identityApiData) {
|
|
6085
|
+
return;
|
|
6086
|
+
}
|
|
6087
|
+
var matchedUser = findMpidMatchingIdentities(persistence, identityApiData);
|
|
6043
6088
|
if (matchedUser) {
|
|
6044
6089
|
self.storeDataInMemory(persistence, matchedUser);
|
|
6045
6090
|
}
|
|
6046
6091
|
};
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6092
|
+
function isNonEmptyArrayOrObject(value) {
|
|
6093
|
+
if (Array.isArray(value)) {
|
|
6094
|
+
return value.length > 0;
|
|
6095
|
+
}
|
|
6096
|
+
if (!mpInstance._Helpers.isObject(value)) {
|
|
6097
|
+
return false;
|
|
6098
|
+
}
|
|
6099
|
+
return Object.keys(value).length > 0;
|
|
6100
|
+
}
|
|
6101
|
+
function encodeGsBase64Field(gs, key) {
|
|
6102
|
+
if (!gs[key] || !isNonEmptyArrayOrObject(gs[key])) {
|
|
6103
|
+
delete gs[key];
|
|
6104
|
+
return;
|
|
6105
|
+
}
|
|
6106
|
+
gs[key] = Base64.encode(JSON.stringify(gs[key]));
|
|
6107
|
+
}
|
|
6108
|
+
function encodeGlobalSettings(gs) {
|
|
6109
|
+
for (var key in gs) {
|
|
6110
|
+
if (!gs.hasOwnProperty(key)) {
|
|
6111
|
+
continue;
|
|
6112
|
+
}
|
|
6113
|
+
if (Base64CookieKeys[key]) {
|
|
6114
|
+
encodeGsBase64Field(gs, key);
|
|
6115
|
+
continue;
|
|
6116
|
+
}
|
|
6117
|
+
if (key === 'ie') {
|
|
6118
|
+
gs[key] = gs[key] ? 1 : 0;
|
|
6119
|
+
continue;
|
|
6120
|
+
}
|
|
6121
|
+
if (!gs[key]) {
|
|
6122
|
+
delete gs[key];
|
|
6123
|
+
}
|
|
6124
|
+
}
|
|
6125
|
+
}
|
|
6126
|
+
function encodeMpidBase64Field(container, key) {
|
|
6127
|
+
var value = container[key];
|
|
6128
|
+
if (mpInstance._Helpers.isObject(value) && Object.keys(value).length) {
|
|
6129
|
+
container[key] = Base64.encode(JSON.stringify(value));
|
|
6130
|
+
return;
|
|
6131
|
+
}
|
|
6132
|
+
delete container[key];
|
|
6133
|
+
}
|
|
6134
|
+
function encodeMpidRecord(record) {
|
|
6135
|
+
for (var key in record) {
|
|
6136
|
+
if (!record.hasOwnProperty(key)) {
|
|
6137
|
+
continue;
|
|
6138
|
+
}
|
|
6139
|
+
if (Base64CookieKeys[key]) {
|
|
6140
|
+
encodeMpidBase64Field(record, key);
|
|
6067
6141
|
}
|
|
6068
6142
|
}
|
|
6143
|
+
}
|
|
6144
|
+
function encodeMpidRecords(persistence) {
|
|
6069
6145
|
for (var mpid in persistence) {
|
|
6070
|
-
if (persistence.hasOwnProperty(mpid)) {
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
if (mpInstance._Helpers.isObject(persistence[mpid][key]) && Object.keys(persistence[mpid][key]).length) {
|
|
6076
|
-
persistence[mpid][key] = Base64.encode(JSON.stringify(persistence[mpid][key]));
|
|
6077
|
-
} else {
|
|
6078
|
-
delete persistence[mpid][key];
|
|
6079
|
-
}
|
|
6080
|
-
}
|
|
6081
|
-
}
|
|
6082
|
-
}
|
|
6083
|
-
}
|
|
6146
|
+
if (!persistence.hasOwnProperty(mpid)) {
|
|
6147
|
+
continue;
|
|
6148
|
+
}
|
|
6149
|
+
if (SDKv2NonMPIDCookieKeys[mpid]) {
|
|
6150
|
+
continue;
|
|
6084
6151
|
}
|
|
6152
|
+
encodeMpidRecord(persistence[mpid]);
|
|
6085
6153
|
}
|
|
6154
|
+
}
|
|
6155
|
+
this.encodePersistence = function (persistenceString) {
|
|
6156
|
+
var persistence = JSON.parse(persistenceString);
|
|
6157
|
+
encodeGlobalSettings(persistence.gs);
|
|
6158
|
+
encodeMpidRecords(persistence);
|
|
6086
6159
|
return createCookieString(JSON.stringify(persistence));
|
|
6087
6160
|
};
|
|
6088
|
-
|
|
6161
|
+
function decodeGlobalSettings(gs) {
|
|
6162
|
+
for (var key in gs) {
|
|
6163
|
+
if (!gs.hasOwnProperty(key)) {
|
|
6164
|
+
continue;
|
|
6165
|
+
}
|
|
6166
|
+
if (Base64CookieKeys[key]) {
|
|
6167
|
+
gs[key] = JSON.parse(Base64.decode(gs[key]));
|
|
6168
|
+
continue;
|
|
6169
|
+
}
|
|
6170
|
+
if (key === 'ie') {
|
|
6171
|
+
gs[key] = Boolean(gs[key]);
|
|
6172
|
+
}
|
|
6173
|
+
}
|
|
6174
|
+
}
|
|
6175
|
+
function decodeMpidRecord(record) {
|
|
6176
|
+
for (var key in record) {
|
|
6177
|
+
if (!record.hasOwnProperty(key)) {
|
|
6178
|
+
continue;
|
|
6179
|
+
}
|
|
6180
|
+
if (!Base64CookieKeys[key]) {
|
|
6181
|
+
continue;
|
|
6182
|
+
}
|
|
6183
|
+
if (record[key].length) {
|
|
6184
|
+
record[key] = JSON.parse(Base64.decode(record[key]));
|
|
6185
|
+
}
|
|
6186
|
+
}
|
|
6187
|
+
}
|
|
6188
|
+
function decodeMpidRecords(persistence) {
|
|
6189
|
+
for (var mpid in persistence) {
|
|
6190
|
+
if (!persistence.hasOwnProperty(mpid)) {
|
|
6191
|
+
continue;
|
|
6192
|
+
}
|
|
6193
|
+
if (!SDKv2NonMPIDCookieKeys[mpid]) {
|
|
6194
|
+
decodeMpidRecord(persistence[mpid]);
|
|
6195
|
+
continue;
|
|
6196
|
+
}
|
|
6197
|
+
if (mpid === 'l') {
|
|
6198
|
+
persistence[mpid] = Boolean(persistence[mpid]);
|
|
6199
|
+
}
|
|
6200
|
+
}
|
|
6201
|
+
}
|
|
6089
6202
|
// TODO: This should actually be decodePersistenceString or
|
|
6090
6203
|
// we should refactor this to take a string and return an object
|
|
6091
|
-
this.decodePersistence = function (
|
|
6204
|
+
this.decodePersistence = function (persistenceString) {
|
|
6092
6205
|
try {
|
|
6093
|
-
if (
|
|
6094
|
-
|
|
6095
|
-
if (mpInstance._Helpers.isObject(persistence) && Object.keys(persistence).length) {
|
|
6096
|
-
for (var key in persistence.gs) {
|
|
6097
|
-
if (persistence.gs.hasOwnProperty(key)) {
|
|
6098
|
-
if (Base64CookieKeys[key]) {
|
|
6099
|
-
persistence.gs[key] = JSON.parse(Base64.decode(persistence.gs[key]));
|
|
6100
|
-
} else if (key === 'ie') {
|
|
6101
|
-
persistence.gs[key] = Boolean(persistence.gs[key]);
|
|
6102
|
-
}
|
|
6103
|
-
}
|
|
6104
|
-
}
|
|
6105
|
-
for (var mpid in persistence) {
|
|
6106
|
-
if (persistence.hasOwnProperty(mpid)) {
|
|
6107
|
-
if (!SDKv2NonMPIDCookieKeys[mpid]) {
|
|
6108
|
-
for (key in persistence[mpid]) {
|
|
6109
|
-
if (persistence[mpid].hasOwnProperty(key)) {
|
|
6110
|
-
if (Base64CookieKeys[key]) {
|
|
6111
|
-
if (persistence[mpid][key].length) {
|
|
6112
|
-
persistence[mpid][key] = JSON.parse(Base64.decode(persistence[mpid][key]));
|
|
6113
|
-
}
|
|
6114
|
-
}
|
|
6115
|
-
}
|
|
6116
|
-
}
|
|
6117
|
-
} else if (mpid === 'l') {
|
|
6118
|
-
persistence[mpid] = Boolean(persistence[mpid]);
|
|
6119
|
-
}
|
|
6120
|
-
}
|
|
6121
|
-
}
|
|
6122
|
-
}
|
|
6123
|
-
return JSON.stringify(persistence);
|
|
6206
|
+
if (!persistenceString) {
|
|
6207
|
+
return;
|
|
6124
6208
|
}
|
|
6209
|
+
var persistence = JSON.parse(revertCookieString(persistenceString));
|
|
6210
|
+
if (mpInstance._Helpers.isObject(persistence) && Object.keys(persistence).length) {
|
|
6211
|
+
decodeGlobalSettings(persistence.gs);
|
|
6212
|
+
decodeMpidRecords(persistence);
|
|
6213
|
+
}
|
|
6214
|
+
return JSON.stringify(persistence);
|
|
6125
6215
|
} catch (e) {
|
|
6126
|
-
mpInstance.Logger.error('Problem with decoding cookie'
|
|
6216
|
+
mpInstance.Logger.error('Problem with decoding cookie');
|
|
6127
6217
|
}
|
|
6128
6218
|
};
|
|
6129
6219
|
this.getCookieDomain = function () {
|
|
@@ -6138,7 +6228,6 @@ var mParticle = (function () {
|
|
|
6138
6228
|
}
|
|
6139
6229
|
}
|
|
6140
6230
|
};
|
|
6141
|
-
|
|
6142
6231
|
// This function loops through the parts of a full hostname, attempting to set a cookie on that domain. It will set a cookie at the highest level possible.
|
|
6143
6232
|
// For example subdomain.domain.co.uk would try the following combinations:
|
|
6144
6233
|
// "co.uk" -> fail
|
|
@@ -6184,18 +6273,17 @@ var mParticle = (function () {
|
|
|
6184
6273
|
}
|
|
6185
6274
|
}
|
|
6186
6275
|
};
|
|
6187
|
-
|
|
6188
6276
|
// https://go.mparticle.com/work/SQDSDKS-6021
|
|
6189
6277
|
this.savePersistence = function (persistence) {
|
|
6190
|
-
var
|
|
6278
|
+
var _a;
|
|
6191
6279
|
// Block mprtcl-v4 persistence when noFunctional is true
|
|
6192
|
-
if ((
|
|
6280
|
+
if ((_a = mpInstance._CookieConsentManager) === null || _a === void 0 ? void 0 : _a.getNoFunctional()) {
|
|
6193
6281
|
return;
|
|
6194
6282
|
}
|
|
6195
6283
|
var encodedPersistence = self.encodePersistence(JSON.stringify(persistence)),
|
|
6196
6284
|
date = new Date(),
|
|
6197
6285
|
key = mpInstance._Store.storageName,
|
|
6198
|
-
expires = new Date(date.getTime() + mpInstance._Store.SDKConfig.cookieExpiration * 24 * 60 * 60 * 1000).
|
|
6286
|
+
expires = new Date(date.getTime() + mpInstance._Store.SDKConfig.cookieExpiration * 24 * 60 * 60 * 1000).toUTCString(),
|
|
6199
6287
|
cookieDomain = self.getCookieDomain(),
|
|
6200
6288
|
domain;
|
|
6201
6289
|
if (cookieDomain === '') {
|
|
@@ -6231,7 +6319,6 @@ var mParticle = (function () {
|
|
|
6231
6319
|
return null;
|
|
6232
6320
|
}
|
|
6233
6321
|
};
|
|
6234
|
-
|
|
6235
6322
|
/**
|
|
6236
6323
|
* set the "first seen" time for a user. the time will only be set once for a given
|
|
6237
6324
|
* mpid after which subsequent calls will be ignored
|
|
@@ -6255,7 +6342,6 @@ var mParticle = (function () {
|
|
|
6255
6342
|
}
|
|
6256
6343
|
}
|
|
6257
6344
|
};
|
|
6258
|
-
|
|
6259
6345
|
/**
|
|
6260
6346
|
* returns the "last seen" time for a user. If the mpid represents the current user, the
|
|
6261
6347
|
* return value will always be the current time, otherwise it will be to stored "last seen"
|
|
@@ -6304,13 +6390,13 @@ var mParticle = (function () {
|
|
|
6304
6390
|
self.expireCookies(StorageNames.cookieNameV3);
|
|
6305
6391
|
self.expireCookies(StorageNames.cookieNameV4);
|
|
6306
6392
|
self.expireCookies(mpInstance._Store.storageName);
|
|
6307
|
-
|
|
6393
|
+
var mParticleManager = getMParticleManager();
|
|
6394
|
+
if (mParticleManager === null || mParticleManager === void 0 ? void 0 : mParticleManager._isTestEnv) {
|
|
6308
6395
|
var testWorkspaceToken = 'abcdef';
|
|
6309
|
-
|
|
6396
|
+
localStorage.removeItem(mpInstance._Helpers.createMainStorageName(testWorkspaceToken));
|
|
6310
6397
|
self.expireCookies(mpInstance._Helpers.createMainStorageName(testWorkspaceToken));
|
|
6311
6398
|
}
|
|
6312
6399
|
};
|
|
6313
|
-
|
|
6314
6400
|
// https://go.mparticle.com/work/SQDSDKS-6045
|
|
6315
6401
|
// Forwarder Batching Code
|
|
6316
6402
|
this.forwardingStatsBatches = {
|
|
@@ -6319,266 +6405,689 @@ var mParticle = (function () {
|
|
|
6319
6405
|
};
|
|
6320
6406
|
}
|
|
6321
6407
|
|
|
6322
|
-
var
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6408
|
+
var HISTORY_METHODS = ['pushState', 'replaceState'];
|
|
6409
|
+
var WRAPPED_MARKER = '__mpApvWrapped__';
|
|
6410
|
+
// All APV state hangs off one window key, and it is the public debugging
|
|
6411
|
+
// contract: `window.__mpApv__` is what you inspect in a console to see whether
|
|
6412
|
+
// tracking is live.
|
|
6413
|
+
//
|
|
6414
|
+
// It lives on `window` rather than in module scope because Next.js re-executes
|
|
6415
|
+
// the SDK bundle on every SPA navigation: module-level state is reset each time,
|
|
6416
|
+
// but `window` persists for the lifetime of the tab.
|
|
6417
|
+
//
|
|
6418
|
+
// One object rather than a key per flag, so resetting is a single reassignment.
|
|
6419
|
+
// Nothing has to be deleted, and there is no ordering in which half the state
|
|
6420
|
+
// survives the reset.
|
|
6421
|
+
var WIN_APV_KEY = '__mpApv__';
|
|
6422
|
+
// The query params an auto page view may carry. An allowlist, not a denylist:
|
|
6423
|
+
// partner URLs routinely hold order ids, email addresses and session tokens, and
|
|
6424
|
+
// none of those should reach the event stream because someone forgot to exclude
|
|
6425
|
+
// them. Anything absent from this list is dropped.
|
|
6426
|
+
//
|
|
6427
|
+
// SECURITY: `code`, `state` and `nonce` are the OAuth 2.0 / OIDC authorization
|
|
6428
|
+
// code and the CSRF/replay tokens. They are credentials until redeemed, and
|
|
6429
|
+
// attaching them here persists them in the event store and forwards them to
|
|
6430
|
+
// every configured kit. They are on the list by explicit product decision —
|
|
6431
|
+
// deleting that line is the whole of the fix if that decision is revisited.
|
|
6432
|
+
var ALLOWED_QUERY_PARAMS = [
|
|
6433
|
+
// Campaign attribution
|
|
6434
|
+
'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'utm_id',
|
|
6435
|
+
// Ad-network click ids
|
|
6436
|
+
'gclid', 'gbraid', 'wbraid', 'fbclid', 'msclkid', 'ttclid', 'twclid', 'li_fat_id', 'dclid',
|
|
6437
|
+
// OAuth / OIDC — see the SECURITY note above
|
|
6438
|
+
'client_id', 'redirect_uri', 'response_type', 'scope', 'state', 'code', 'nonce',
|
|
6439
|
+
// Pagination and search
|
|
6440
|
+
'page', 'limit', 'offset', 'cursor', 'per_page', 'q', 'search',
|
|
6441
|
+
// Referral
|
|
6442
|
+
'ref', 'referrer'];
|
|
6443
|
+
// ---------------------------------------------------------------------------
|
|
6444
|
+
// Pure helpers. No `this`, no globals, no side effects — callable and assertable
|
|
6445
|
+
// on their own, which is where the interesting rules live.
|
|
6446
|
+
// ---------------------------------------------------------------------------
|
|
6447
|
+
// Pulls the allowlisted query params off a URL. Delegates to the SDK's own
|
|
6448
|
+
// parser, which lowercases keys (so `?UTM_Source=` and `?utm_source=` land on one
|
|
6449
|
+
// attribute), drops empty values, and carries the fallback for browsers without
|
|
6450
|
+
// URLSearchParams. Tolerates an empty href, so SSR yields no params rather than
|
|
6451
|
+
// throwing.
|
|
6452
|
+
var allowedQueryParams = function allowedQueryParams(href) {
|
|
6453
|
+
return queryStringParser(href, ALLOWED_QUERY_PARAMS);
|
|
6454
|
+
};
|
|
6455
|
+
// The captured params, in allowlist order. Ordering comes from the constant
|
|
6456
|
+
// rather than a sort: it is deterministic without needing a comparator, and it
|
|
6457
|
+
// does not depend on the object's insertion order, so reordering the query string
|
|
6458
|
+
// cannot produce a different key.
|
|
6459
|
+
var capturedNames = function capturedNames(params) {
|
|
6460
|
+
return ALLOWED_QUERY_PARAMS.filter(function (name) {
|
|
6461
|
+
return name in params;
|
|
6462
|
+
});
|
|
6463
|
+
};
|
|
6464
|
+
// The dedup key: pathname plus the allowlisted params in a fixed order, so that
|
|
6465
|
+
// reordering the query string is not a new page. Params outside the allowlist
|
|
6466
|
+
// never make it into `page.params` and so cannot key a view — nor can the hash.
|
|
6467
|
+
//
|
|
6468
|
+
// Values are re-encoded because queryStringParser hands them back DECODED. A
|
|
6469
|
+
// value holding the pair delimiters would otherwise serialize exactly like two
|
|
6470
|
+
// separate params — `{q: 'a&search=b'}` and `{q: 'a', search: 'b'}` both becoming
|
|
6471
|
+
// `q=a&search=b` — and dedup would treat a real navigation between them as the
|
|
6472
|
+
// same page and drop the view. `q`, `search` and `redirect_uri` carry `&` and `=`
|
|
6473
|
+
// routinely, so this is reachable rather than theoretical.
|
|
6474
|
+
var pageKey = function pageKey(page) {
|
|
6475
|
+
var query = capturedNames(page.params).map(function (name) {
|
|
6476
|
+
return "".concat(name, "=").concat(encodeURIComponent(page.params[name]));
|
|
6477
|
+
}).join('&');
|
|
6478
|
+
return query ? "".concat(page.path, "?").concat(query) : page.path;
|
|
6479
|
+
};
|
|
6480
|
+
// Dedup keys on the pageKey above: a change to any captured param is a new page
|
|
6481
|
+
// (`?page=2` is a distinct pagination view), while a hash-only change, or a
|
|
6482
|
+
// change confined to params we do not capture, is the same page.
|
|
6483
|
+
var isNewPage = function isNewPage(lastKey, candidateKey) {
|
|
6484
|
+
return candidateKey !== lastKey;
|
|
6485
|
+
};
|
|
6486
|
+
var supportsHistoryTracking = function supportsHistoryTracking(win) {
|
|
6487
|
+
return !!win && win.history !== undefined && typeof win.history.pushState === 'function' && typeof win.addEventListener === 'function';
|
|
6488
|
+
};
|
|
6489
|
+
// Mirrors the event shape of the public mParticle.logPageView(), but carries the
|
|
6490
|
+
// path and query params captured when the navigation was accepted rather than the
|
|
6491
|
+
// live location.
|
|
6492
|
+
var buildPageViewEvent = function buildPageViewEvent(_a) {
|
|
6493
|
+
var params = _a.params,
|
|
6494
|
+
hostname = _a.hostname,
|
|
6495
|
+
title = _a.title,
|
|
6496
|
+
path = _a.path;
|
|
6497
|
+
return {
|
|
6498
|
+
messageType: MessageType$1.PageView,
|
|
6499
|
+
name: 'PageView',
|
|
6500
|
+
// Params spread first, then the core fields by name, so a core field always
|
|
6501
|
+
// wins. No allowlist entry collides with hostname/title/path today; naming
|
|
6502
|
+
// them here is what keeps a later addition from silently overwriting one.
|
|
6503
|
+
data: __assign(__assign({}, params), {
|
|
6504
|
+
hostname: hostname,
|
|
6505
|
+
title: title,
|
|
6506
|
+
path: path
|
|
6507
|
+
}),
|
|
6508
|
+
eventType: EventType.Unknown
|
|
6378
6509
|
};
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6510
|
+
};
|
|
6511
|
+
// ---------------------------------------------------------------------------
|
|
6512
|
+
// Window-scoped APV state. Every read and write goes through these helpers, so
|
|
6513
|
+
// neither the tracker nor mp-instance touches `window` directly and
|
|
6514
|
+
// `typeof window` is checked in exactly one place.
|
|
6515
|
+
// ---------------------------------------------------------------------------
|
|
6516
|
+
var apvWindow = function apvWindow() {
|
|
6517
|
+
return typeof window === 'undefined' ? null : window;
|
|
6518
|
+
};
|
|
6519
|
+
var freshState = function freshState() {
|
|
6520
|
+
return {
|
|
6521
|
+
initialPageViewFired: false
|
|
6385
6522
|
};
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6523
|
+
};
|
|
6524
|
+
// Reads tolerate absent state, so a read never mutates `window`. Only the
|
|
6525
|
+
// writers below create it.
|
|
6526
|
+
var readState = function readState() {
|
|
6527
|
+
var win = apvWindow();
|
|
6528
|
+
return win ? win[WIN_APV_KEY] : undefined;
|
|
6529
|
+
};
|
|
6530
|
+
var writeState = function writeState() {
|
|
6531
|
+
var win = apvWindow();
|
|
6532
|
+
if (!win) {
|
|
6533
|
+
return null;
|
|
6534
|
+
}
|
|
6535
|
+
if (!win[WIN_APV_KEY]) {
|
|
6536
|
+
win[WIN_APV_KEY] = freshState();
|
|
6537
|
+
}
|
|
6538
|
+
return win[WIN_APV_KEY];
|
|
6539
|
+
};
|
|
6540
|
+
var getActiveTracker = function getActiveTracker() {
|
|
6541
|
+
var state = readState();
|
|
6542
|
+
return state ? state.tracker : undefined;
|
|
6543
|
+
};
|
|
6544
|
+
var hasInitialPageViewFired = function hasInitialPageViewFired() {
|
|
6545
|
+
var state = readState();
|
|
6546
|
+
return !!(state && state.initialPageViewFired);
|
|
6547
|
+
};
|
|
6548
|
+
var markInitialPageViewFired = function markInitialPageViewFired() {
|
|
6549
|
+
var state = writeState();
|
|
6550
|
+
if (state) {
|
|
6551
|
+
state.initialPageViewFired = true;
|
|
6552
|
+
}
|
|
6553
|
+
};
|
|
6554
|
+
// Returns the page to its pre-APV state: stops the active tracker (restoring the
|
|
6555
|
+
// history methods it patched), then swaps in fresh state. The state object is the
|
|
6556
|
+
// authoritative handle, so this reaches trackers whose owning module is gone.
|
|
6557
|
+
var resetPageViewTracking = function resetPageViewTracking() {
|
|
6558
|
+
var win = apvWindow();
|
|
6559
|
+
if (!win) {
|
|
6560
|
+
return;
|
|
6561
|
+
}
|
|
6562
|
+
var active = getActiveTracker();
|
|
6563
|
+
if (active) {
|
|
6564
|
+
active.teardown();
|
|
6565
|
+
}
|
|
6566
|
+
// One reassignment replaces every flag at once, so nothing can be left behind
|
|
6567
|
+
// whatever shape the previous state was in.
|
|
6568
|
+
win[WIN_APV_KEY] = freshState();
|
|
6569
|
+
};
|
|
6570
|
+
var setActiveTracker = function setActiveTracker(tracker) {
|
|
6571
|
+
var state = writeState();
|
|
6572
|
+
if (state) {
|
|
6573
|
+
state.tracker = tracker;
|
|
6574
|
+
}
|
|
6575
|
+
};
|
|
6576
|
+
var clearActiveTracker = function clearActiveTracker(tracker) {
|
|
6577
|
+
var state = readState();
|
|
6578
|
+
if (state && state.tracker === tracker) {
|
|
6579
|
+
state.tracker = undefined;
|
|
6580
|
+
}
|
|
6581
|
+
};
|
|
6582
|
+
var currentPage = function currentPage() {
|
|
6583
|
+
return {
|
|
6584
|
+
path: window.location.pathname,
|
|
6585
|
+
params: allowedQueryParams(getHref())
|
|
6393
6586
|
};
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6587
|
+
};
|
|
6588
|
+
// Log-safe description of a page: the path, plus the NAMES of the captured
|
|
6589
|
+
// params. Values are deliberately omitted — verbose logging goes to the console,
|
|
6590
|
+
// and session-replay tooling ships console output off-domain, which is not a
|
|
6591
|
+
// place for an OAuth code or a consumer's search terms.
|
|
6592
|
+
// Only reachable before init() assigns lastPage, which is ahead of any navigation
|
|
6593
|
+
// handler being able to run, so this returns nothing rather than a sentinel.
|
|
6594
|
+
var describePage = function describePage(page) {
|
|
6595
|
+
if (!page) {
|
|
6596
|
+
return '';
|
|
6597
|
+
}
|
|
6598
|
+
var names = capturedNames(page.params);
|
|
6599
|
+
return names.length ? "".concat(page.path, " (params: ").concat(names.join(), ")") : page.path;
|
|
6600
|
+
};
|
|
6601
|
+
// ---------------------------------------------------------------------------
|
|
6602
|
+
// History patching
|
|
6603
|
+
// ---------------------------------------------------------------------------
|
|
6604
|
+
// Wraps pushState/replaceState so `onNavigate` runs after the real method, and
|
|
6605
|
+
// returns the single function that undoes it — or null when nothing was
|
|
6606
|
+
// installed (history is already wrapped, or a frozen/sealed History rejected the
|
|
6607
|
+
// assignment). Handing back one undo closure keeps the wrapper and original
|
|
6608
|
+
// references out of the tracker entirely: there is no half-patched state for a
|
|
6609
|
+
// caller to inspect, and no way to restore the wrong pair.
|
|
6610
|
+
var patchHistory = function patchHistory(onNavigate, log) {
|
|
6611
|
+
if (window.history.pushState[WRAPPED_MARKER]) {
|
|
6612
|
+
log('[patch] history already wrapped, skipping to avoid double-wrap — STACKED WRAPPER DETECTED');
|
|
6613
|
+
return null;
|
|
6614
|
+
}
|
|
6615
|
+
var originals = {};
|
|
6616
|
+
var wrappers = {};
|
|
6617
|
+
HISTORY_METHODS.forEach(function (name) {
|
|
6618
|
+
var original = window.history[name];
|
|
6619
|
+
originals[name] = original;
|
|
6620
|
+
var wrapper = function wrapper() {
|
|
6621
|
+
var args = [];
|
|
6622
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
6623
|
+
args[_i] = arguments[_i];
|
|
6624
|
+
}
|
|
6625
|
+
var result = original.apply(this, args);
|
|
6626
|
+
onNavigate(name);
|
|
6627
|
+
return result;
|
|
6628
|
+
};
|
|
6629
|
+
Object.defineProperty(wrapper, WRAPPED_MARKER, {
|
|
6630
|
+
value: true,
|
|
6631
|
+
enumerable: false
|
|
6397
6632
|
});
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6633
|
+
wrappers[name] = wrapper;
|
|
6634
|
+
});
|
|
6635
|
+
// Restore per method: a third party may have patched one of the two on top of
|
|
6636
|
+
// ours after we installed. Clobbering theirs would break their tracking, so
|
|
6637
|
+
// leave anything that is no longer ours in place.
|
|
6638
|
+
var restore = function restore() {
|
|
6639
|
+
return HISTORY_METHODS.forEach(function (name) {
|
|
6640
|
+
if (window.history[name] === wrappers[name]) {
|
|
6641
|
+
window.history[name] = originals[name];
|
|
6642
|
+
log("[teardown] restored original ".concat(name));
|
|
6643
|
+
} else {
|
|
6644
|
+
log("[teardown] ".concat(name, " no longer ours; leaving in place, gating callback to no-op"));
|
|
6645
|
+
}
|
|
6408
6646
|
});
|
|
6409
6647
|
};
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
event.EventName += mpInstance._Ecommerce.getProductActionEventName(Types.ProductActionType.Checkout);
|
|
6414
|
-
event.EventCategory = Types.CommerceEventType.ProductCheckout;
|
|
6415
|
-
event.ProductAction = {
|
|
6416
|
-
ProductActionType: Types.ProductActionType.Checkout,
|
|
6417
|
-
CheckoutStep: step,
|
|
6418
|
-
CheckoutOptions: option,
|
|
6419
|
-
ProductList: []
|
|
6420
|
-
};
|
|
6421
|
-
self.logCommerceEvent(event, attrs);
|
|
6422
|
-
}
|
|
6423
|
-
};
|
|
6424
|
-
this.logProductActionEvent = function (productActionType, product, customAttrs, customFlags, transactionAttributes, options) {
|
|
6425
|
-
var event = mpInstance._Ecommerce.createCommerceEventObject(customFlags, options);
|
|
6426
|
-
var productList = Array.isArray(product) ? product : [product];
|
|
6427
|
-
productList.forEach(function (product) {
|
|
6428
|
-
if (product.TotalAmount) {
|
|
6429
|
-
product.TotalAmount = mpInstance._Ecommerce.sanitizeAmount(product.TotalAmount, 'TotalAmount');
|
|
6430
|
-
}
|
|
6431
|
-
if (product.Position) {
|
|
6432
|
-
product.Position = mpInstance._Ecommerce.sanitizeAmount(product.Position, 'Position');
|
|
6433
|
-
}
|
|
6434
|
-
if (product.Price) {
|
|
6435
|
-
product.Price = mpInstance._Ecommerce.sanitizeAmount(product.Price, 'Price');
|
|
6436
|
-
}
|
|
6437
|
-
if (product.Quantity) {
|
|
6438
|
-
product.Quantity = mpInstance._Ecommerce.sanitizeAmount(product.Quantity, 'Quantity');
|
|
6439
|
-
}
|
|
6648
|
+
try {
|
|
6649
|
+
HISTORY_METHODS.forEach(function (name) {
|
|
6650
|
+
window.history[name] = wrappers[name];
|
|
6440
6651
|
});
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
};
|
|
6448
|
-
if (Types.ProductActionType.isRoktCommerceType(productActionType)) {
|
|
6449
|
-
event.CustomFlags = event.CustomFlags || {};
|
|
6450
|
-
event.CustomFlags['Rokt.CommerceEventType'] = Types.ProductActionType.getExpansionName(productActionType);
|
|
6451
|
-
}
|
|
6452
|
-
if (mpInstance._Helpers.isObject(transactionAttributes)) {
|
|
6453
|
-
mpInstance._Ecommerce.convertTransactionAttributesToProductAction(transactionAttributes, event.ProductAction);
|
|
6454
|
-
}
|
|
6455
|
-
self.logCommerceEvent(event, customAttrs, options);
|
|
6652
|
+
} catch (e) {
|
|
6653
|
+
log("[error] failed to patch history methods (frozen/sealed), rolling back: ".concat(e));
|
|
6654
|
+
try {
|
|
6655
|
+
restore();
|
|
6656
|
+
} catch (restoreError) {
|
|
6657
|
+
log("[error] failed to restore history methods after patch failure: ".concat(restoreError));
|
|
6456
6658
|
}
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6659
|
+
return null;
|
|
6660
|
+
}
|
|
6661
|
+
return restore;
|
|
6662
|
+
};
|
|
6663
|
+
// ---------------------------------------------------------------------------
|
|
6664
|
+
// Tracker
|
|
6665
|
+
// ---------------------------------------------------------------------------
|
|
6666
|
+
var PageViewTracker = /** @class */function () {
|
|
6667
|
+
function PageViewTracker(mpInstance) {
|
|
6668
|
+
this.lastPage = null;
|
|
6669
|
+
this.active = false;
|
|
6670
|
+
this.pendingNavigations = [];
|
|
6671
|
+
this.undoHistoryPatch = null;
|
|
6672
|
+
this.popStateListener = null;
|
|
6673
|
+
this.mpInstance = mpInstance;
|
|
6674
|
+
}
|
|
6675
|
+
Object.defineProperty(PageViewTracker.prototype, "isActive", {
|
|
6676
|
+
// True while this tracker owns the history patch and is listening for
|
|
6677
|
+
// navigations. Flips to false on teardown, including the teardown a
|
|
6678
|
+
// successor tracker performs during a handoff. Read-only, and the one thing
|
|
6679
|
+
// worth checking on `window.__mpApv__.tracker` from a console.
|
|
6680
|
+
get: function get() {
|
|
6681
|
+
return this.active;
|
|
6682
|
+
},
|
|
6683
|
+
enumerable: false,
|
|
6684
|
+
configurable: true
|
|
6685
|
+
});
|
|
6686
|
+
PageViewTracker.prototype.init = function () {
|
|
6687
|
+
var _this = this;
|
|
6688
|
+
this.log('[init] PageViewTracker Init');
|
|
6689
|
+
if (!supportsHistoryTracking(apvWindow())) {
|
|
6690
|
+
this.log('[init] unsupported environment (no History API), not starting');
|
|
6691
|
+
return;
|
|
6692
|
+
}
|
|
6693
|
+
// Take over from whichever tracker is currently active: one left behind by
|
|
6694
|
+
// a previous module load, or this same tracker on a repeat
|
|
6695
|
+
// mParticle.init(). Their pending navigations are transferred rather than
|
|
6696
|
+
// dropped — a route change may have queued a deferred fire that has not
|
|
6697
|
+
// flushed yet, and dropping it loses a page view entirely.
|
|
6698
|
+
var active = getActiveTracker();
|
|
6699
|
+
var inheritedPages = this.retire(active);
|
|
6700
|
+
if (this.active && active !== this) {
|
|
6701
|
+
inheritedPages = inheritedPages.concat(this.retire(this));
|
|
6469
6702
|
}
|
|
6703
|
+
this.active = true;
|
|
6704
|
+
this.lastPage = currentPage();
|
|
6705
|
+
this.log("[init] seeded lastPage: ".concat(describePage(this.lastPage)));
|
|
6706
|
+
this.undoHistoryPatch = patchHistory(function (source) {
|
|
6707
|
+
return _this.safeHandleNavigation(source);
|
|
6708
|
+
}, function (message) {
|
|
6709
|
+
return _this.log(message);
|
|
6710
|
+
});
|
|
6711
|
+
this.popStateListener = function () {
|
|
6712
|
+
return _this.safeHandleNavigation('popstate');
|
|
6713
|
+
};
|
|
6714
|
+
window.addEventListener('popstate', this.popStateListener);
|
|
6715
|
+
setActiveTracker(this);
|
|
6716
|
+
this.log('[init] patched pushState/replaceState + listening for popstate');
|
|
6717
|
+
inheritedPages.forEach(function (page) {
|
|
6718
|
+
return _this.scheduleFire(page);
|
|
6719
|
+
});
|
|
6470
6720
|
};
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6721
|
+
PageViewTracker.prototype.teardown = function () {
|
|
6722
|
+
// Discard pending deferred fires (e.g. AutoLogPageView switched off on
|
|
6723
|
+
// re-init). A handoff calls takePendingNavigations() first, so by this
|
|
6724
|
+
// point those paths are already transferred rather than dropped.
|
|
6725
|
+
this.takePendingNavigations();
|
|
6726
|
+
if (this.popStateListener) {
|
|
6727
|
+
window.removeEventListener('popstate', this.popStateListener);
|
|
6728
|
+
this.popStateListener = null;
|
|
6475
6729
|
}
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
event.EventCategory = Types.CommerceEventType.ProductRefund;
|
|
6480
|
-
event.ProductAction = {
|
|
6481
|
-
ProductActionType: Types.ProductActionType.Refund
|
|
6482
|
-
};
|
|
6483
|
-
event.ProductAction.ProductList = mpInstance._Ecommerce.buildProductList(event, product);
|
|
6484
|
-
mpInstance._Ecommerce.convertTransactionAttributesToProductAction(transactionAttributes, event.ProductAction);
|
|
6485
|
-
self.logCommerceEvent(event, attrs);
|
|
6730
|
+
if (this.undoHistoryPatch) {
|
|
6731
|
+
this.undoHistoryPatch();
|
|
6732
|
+
this.undoHistoryPatch = null;
|
|
6486
6733
|
}
|
|
6734
|
+
this.active = false;
|
|
6735
|
+
clearActiveTracker(this);
|
|
6487
6736
|
};
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
PromotionActionType: promotionType,
|
|
6495
|
-
PromotionList: Array.isArray(promotion) ? promotion : [promotion]
|
|
6496
|
-
};
|
|
6497
|
-
self.logCommerceEvent(event, attrs, eventOptions);
|
|
6737
|
+
// Stops the outgoing tracker and returns the pages it had queued so this
|
|
6738
|
+
// tracker can re-schedule them once it is active. Private, but reachable
|
|
6739
|
+
// across instances: the handoff protocol stays internal to the class.
|
|
6740
|
+
PageViewTracker.prototype.retire = function (outgoing) {
|
|
6741
|
+
if (!outgoing) {
|
|
6742
|
+
return [];
|
|
6498
6743
|
}
|
|
6744
|
+
this.log(outgoing === this ? '[init] retiring this tracker for a repeat mParticle.init() — transferring pending navigations and tearing down' : '[init] retiring a tracker from a previous module load — transferring pending navigations and tearing down');
|
|
6745
|
+
var pages = outgoing.takePendingNavigations();
|
|
6746
|
+
outgoing.teardown();
|
|
6747
|
+
return pages;
|
|
6499
6748
|
};
|
|
6500
|
-
this
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6749
|
+
// Cancels this tracker's deferred fires and hands back their captured pages.
|
|
6750
|
+
PageViewTracker.prototype.takePendingNavigations = function () {
|
|
6751
|
+
var pending = this.pendingNavigations;
|
|
6752
|
+
this.pendingNavigations = [];
|
|
6753
|
+
pending.forEach(function (_a) {
|
|
6754
|
+
var timeoutId = _a.timeoutId;
|
|
6755
|
+
return clearTimeout(timeoutId);
|
|
6756
|
+
});
|
|
6757
|
+
return pending.map(function (_a) {
|
|
6758
|
+
var page = _a.page;
|
|
6759
|
+
return page;
|
|
6760
|
+
});
|
|
6761
|
+
};
|
|
6762
|
+
PageViewTracker.prototype.safeHandleNavigation = function (source) {
|
|
6763
|
+
// An orphaned wrapper still calls in: teardown can only restore a history
|
|
6764
|
+
// method that is still ours, so one a third party patched over stays
|
|
6765
|
+
// installed and keeps firing at a dead tracker. Bail before touching
|
|
6766
|
+
// lastPath or queueing a fire the flush would just abort. Guarding here
|
|
6767
|
+
// rather than at each wrapper also covers the popstate path.
|
|
6768
|
+
if (!this.active) {
|
|
6769
|
+
return;
|
|
6770
|
+
}
|
|
6771
|
+
try {
|
|
6772
|
+
this.handleNavigation(source);
|
|
6773
|
+
} catch (e) {
|
|
6774
|
+
this.log("[error] navigation handler threw (".concat(source, "), page view skipped: ").concat(e));
|
|
6516
6775
|
}
|
|
6517
6776
|
};
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
if (commerceEvent.ProductAction && commerceEvent.EventCategory === null) {
|
|
6525
|
-
mpInstance.Logger.error('Commerce event not sent. The mParticle.ProductActionType you passed was invalid. Re-check your code.');
|
|
6777
|
+
PageViewTracker.prototype.handleNavigation = function (source) {
|
|
6778
|
+
var candidate = currentPage();
|
|
6779
|
+
var lastKey = this.lastPage ? pageKey(this.lastPage) : null;
|
|
6780
|
+
this.log("[detect] navigation signal (source: ".concat(source, ", candidate: ").concat(describePage(candidate), ", last: ").concat(describePage(this.lastPage), ")"));
|
|
6781
|
+
if (!isNewPage(lastKey, pageKey(candidate))) {
|
|
6782
|
+
this.log("[dedupe] page unchanged, skipping (source: ".concat(source, ", page: ").concat(describePage(candidate), ")"));
|
|
6526
6783
|
return;
|
|
6527
6784
|
}
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6785
|
+
this.log("[accept] page changed, scheduling fire (source: ".concat(source, ", from: ").concat(describePage(this.lastPage), ", to: ").concat(describePage(candidate), ")"));
|
|
6786
|
+
this.lastPage = candidate;
|
|
6787
|
+
this.scheduleFire(candidate);
|
|
6788
|
+
};
|
|
6789
|
+
// Deferred by a macrotask so the router's post-navigation render commit has a
|
|
6790
|
+
// chance to update document.title before the event is built. The path and
|
|
6791
|
+
// query params are snapshotted now because they are already settled, whereas a
|
|
6792
|
+
// same-tick navigation would overwrite window.location before the flush reads
|
|
6793
|
+
// it.
|
|
6794
|
+
PageViewTracker.prototype.scheduleFire = function (page) {
|
|
6795
|
+
var _this = this;
|
|
6796
|
+
var timeoutId = setTimeout(function () {
|
|
6797
|
+
_this.pendingNavigations = _this.pendingNavigations.filter(function (p) {
|
|
6798
|
+
return p.timeoutId !== timeoutId;
|
|
6799
|
+
});
|
|
6800
|
+
if (!_this.active) {
|
|
6801
|
+
_this.log('[defer] fire aborted, tracker inactive (torn down before flush)');
|
|
6802
|
+
return;
|
|
6541
6803
|
}
|
|
6542
|
-
mpInstance.
|
|
6543
|
-
|
|
6544
|
-
|
|
6804
|
+
_this.mpInstance._SessionManager.resetSessionTimer();
|
|
6805
|
+
_this.firePageView(page);
|
|
6806
|
+
}, 0);
|
|
6807
|
+
this.pendingNavigations.push({
|
|
6808
|
+
page: page,
|
|
6809
|
+
timeoutId: timeoutId
|
|
6810
|
+
});
|
|
6811
|
+
};
|
|
6812
|
+
PageViewTracker.prototype.firePageView = function (page) {
|
|
6813
|
+
var title = window.document.title;
|
|
6814
|
+
var event = buildPageViewEvent(__assign(__assign({}, page), {
|
|
6815
|
+
hostname: window.location.hostname,
|
|
6816
|
+
title: title
|
|
6817
|
+
}));
|
|
6818
|
+
this.log("[fire] deferred flush -> _Events.logEvent(PageView) (page: ".concat(describePage(page), ", title: ").concat(title, ")"));
|
|
6819
|
+
this.mpInstance._Events.logEvent(event);
|
|
6820
|
+
};
|
|
6821
|
+
PageViewTracker.prototype.log = function (message) {
|
|
6822
|
+
this.mpInstance.Logger.verbose("mParticle APV: ".concat(message));
|
|
6823
|
+
};
|
|
6824
|
+
return PageViewTracker;
|
|
6825
|
+
}();
|
|
6826
|
+
|
|
6827
|
+
var Messages$3 = Constants.Messages;
|
|
6828
|
+
function Events(mpInstance) {
|
|
6829
|
+
var self = this;
|
|
6830
|
+
this.logEvent = function (event, options) {
|
|
6831
|
+
mpInstance.Logger.verbose(Messages$3.InformationMessages.StartingLogEvent + ': ' + event.name);
|
|
6832
|
+
if (mpInstance._Helpers.canLog()) {
|
|
6833
|
+
var uploadObject = mpInstance._ServerModel.createEventObject(event);
|
|
6834
|
+
mpInstance._APIClient.sendEventToServer(uploadObject, options);
|
|
6545
6835
|
} else {
|
|
6546
6836
|
mpInstance.Logger.verbose(Messages$3.InformationMessages.AbandonLogEvent);
|
|
6547
6837
|
}
|
|
6548
6838
|
};
|
|
6549
|
-
this.
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
mpInstance.Logger.verbose('DOM event triggered, handling event');
|
|
6560
|
-
self.logEvent({
|
|
6561
|
-
messageType: Types.MessageType.PageEvent,
|
|
6562
|
-
name: typeof eventName === 'function' ? eventName(element) : eventName,
|
|
6563
|
-
data: typeof data === 'function' ? data(element) : data,
|
|
6564
|
-
eventType: eventType || Types.EventType.Other
|
|
6565
|
-
});
|
|
6566
|
-
// TODO: Handle middle-clicks and special keys (ctrl, alt, etc)
|
|
6567
|
-
if (element.href && element.target !== '_blank' || element.submit) {
|
|
6568
|
-
// Give xmlhttprequest enough time to execute before navigating a link or submitting form
|
|
6569
|
-
if (e.preventDefault) {
|
|
6570
|
-
e.preventDefault();
|
|
6571
|
-
} else {
|
|
6572
|
-
e.returnValue = false;
|
|
6573
|
-
}
|
|
6574
|
-
setTimeout(timeoutHandler, mpInstance._Store.SDKConfig.timeout);
|
|
6839
|
+
this.startTracking = function (callback) {
|
|
6840
|
+
if (!mpInstance._Store.isTracking) {
|
|
6841
|
+
if ('geolocation' in navigator) {
|
|
6842
|
+
mpInstance._Store.watchPositionId = navigator.geolocation.watchPosition(successTracking, errorTracking);
|
|
6843
|
+
}
|
|
6844
|
+
} else {
|
|
6845
|
+
var position = {
|
|
6846
|
+
coords: {
|
|
6847
|
+
latitude: mpInstance._Store.currentPosition.lat,
|
|
6848
|
+
longitude: mpInstance._Store.currentPosition.lng
|
|
6575
6849
|
}
|
|
6576
|
-
}
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
mpInstance.
|
|
6581
|
-
|
|
6850
|
+
};
|
|
6851
|
+
triggerCallback(callback, position);
|
|
6852
|
+
}
|
|
6853
|
+
function successTracking(position) {
|
|
6854
|
+
mpInstance._Store.currentPosition = {
|
|
6855
|
+
lat: position.coords.latitude,
|
|
6856
|
+
lng: position.coords.longitude
|
|
6857
|
+
};
|
|
6858
|
+
triggerCallback(callback, position);
|
|
6859
|
+
// prevents callback from being fired multiple times
|
|
6860
|
+
callback = null;
|
|
6861
|
+
mpInstance._Store.isTracking = true;
|
|
6862
|
+
}
|
|
6863
|
+
function errorTracking() {
|
|
6864
|
+
triggerCallback(callback);
|
|
6865
|
+
// prevents callback from being fired multiple times
|
|
6866
|
+
callback = null;
|
|
6867
|
+
mpInstance._Store.isTracking = false;
|
|
6868
|
+
}
|
|
6869
|
+
function triggerCallback(callback, position) {
|
|
6870
|
+
if (callback) {
|
|
6871
|
+
try {
|
|
6872
|
+
if (position) {
|
|
6873
|
+
callback(position);
|
|
6874
|
+
} else {
|
|
6875
|
+
callback();
|
|
6876
|
+
}
|
|
6877
|
+
} catch (e) {
|
|
6878
|
+
mpInstance.Logger.error('Error invoking the callback passed to startTrackingLocation.');
|
|
6879
|
+
mpInstance.Logger.error(e);
|
|
6880
|
+
}
|
|
6881
|
+
}
|
|
6882
|
+
}
|
|
6883
|
+
};
|
|
6884
|
+
this.stopTracking = function () {
|
|
6885
|
+
if (mpInstance._Store.isTracking) {
|
|
6886
|
+
navigator.geolocation.clearWatch(mpInstance._Store.watchPositionId);
|
|
6887
|
+
mpInstance._Store.currentPosition = null;
|
|
6888
|
+
mpInstance._Store.isTracking = false;
|
|
6889
|
+
}
|
|
6890
|
+
};
|
|
6891
|
+
this.logOptOut = function () {
|
|
6892
|
+
mpInstance.Logger.verbose(Messages$3.InformationMessages.StartingLogOptOut);
|
|
6893
|
+
var event = mpInstance._ServerModel.createEventObject({
|
|
6894
|
+
messageType: Types.MessageType.OptOut,
|
|
6895
|
+
eventType: Types.EventType.Other
|
|
6896
|
+
});
|
|
6897
|
+
mpInstance._APIClient.sendEventToServer(event);
|
|
6898
|
+
};
|
|
6899
|
+
this.logAST = function () {
|
|
6900
|
+
self.logEvent({
|
|
6901
|
+
messageType: Types.MessageType.AppStateTransition
|
|
6902
|
+
});
|
|
6903
|
+
};
|
|
6904
|
+
// The auto page view for the landing page. The SPA navigations that follow it
|
|
6905
|
+
// come from PageViewTracker instead, so both emitters attach the same
|
|
6906
|
+
// allowlisted query params — and this is the one that matters for campaign
|
|
6907
|
+
// attribution, since utm_*/gclid live on the entry URL.
|
|
6908
|
+
this.logPageView = function () {
|
|
6909
|
+
self.logEvent({
|
|
6910
|
+
messageType: Types.MessageType.PageView,
|
|
6911
|
+
name: 'PageView',
|
|
6912
|
+
data: __assign(__assign({}, allowedQueryParams(getHref())), {
|
|
6913
|
+
hostname: window.location.hostname,
|
|
6914
|
+
title: window.document.title
|
|
6915
|
+
}),
|
|
6916
|
+
eventType: Types.EventType.Unknown
|
|
6917
|
+
});
|
|
6918
|
+
};
|
|
6919
|
+
this.logCheckoutEvent = function (step, option, attrs, customFlags) {
|
|
6920
|
+
var event = mpInstance._Ecommerce.createCommerceEventObject(customFlags);
|
|
6921
|
+
if (event) {
|
|
6922
|
+
event.EventName += mpInstance._Ecommerce.getProductActionEventName(Types.ProductActionType.Checkout);
|
|
6923
|
+
event.EventCategory = Types.CommerceEventType.ProductCheckout;
|
|
6924
|
+
event.ProductAction = {
|
|
6925
|
+
ProductActionType: Types.ProductActionType.Checkout,
|
|
6926
|
+
CheckoutStep: step,
|
|
6927
|
+
CheckoutOptions: option,
|
|
6928
|
+
ProductList: []
|
|
6929
|
+
};
|
|
6930
|
+
self.logCommerceEvent(event, attrs);
|
|
6931
|
+
}
|
|
6932
|
+
};
|
|
6933
|
+
this.logProductActionEvent = function (productActionType, product, customAttrs, customFlags, transactionAttributes, options) {
|
|
6934
|
+
var event = mpInstance._Ecommerce.createCommerceEventObject(customFlags, options);
|
|
6935
|
+
var productList = Array.isArray(product) ? product : [product];
|
|
6936
|
+
productList.forEach(function (product) {
|
|
6937
|
+
if (product.TotalAmount) {
|
|
6938
|
+
product.TotalAmount = mpInstance._Ecommerce.sanitizeAmount(product.TotalAmount, 'TotalAmount');
|
|
6939
|
+
}
|
|
6940
|
+
if (product.Position) {
|
|
6941
|
+
product.Position = mpInstance._Ecommerce.sanitizeAmount(product.Position, 'Position');
|
|
6942
|
+
}
|
|
6943
|
+
if (product.Price) {
|
|
6944
|
+
product.Price = mpInstance._Ecommerce.sanitizeAmount(product.Price, 'Price');
|
|
6945
|
+
}
|
|
6946
|
+
if (product.Quantity) {
|
|
6947
|
+
product.Quantity = mpInstance._Ecommerce.sanitizeAmount(product.Quantity, 'Quantity');
|
|
6948
|
+
}
|
|
6949
|
+
});
|
|
6950
|
+
if (event) {
|
|
6951
|
+
event.EventCategory = mpInstance._Ecommerce.convertProductActionToEventType(productActionType);
|
|
6952
|
+
event.EventName += mpInstance._Ecommerce.getProductActionEventName(productActionType);
|
|
6953
|
+
event.ProductAction = {
|
|
6954
|
+
ProductActionType: productActionType,
|
|
6955
|
+
ProductList: productList
|
|
6956
|
+
};
|
|
6957
|
+
if (Types.ProductActionType.isRoktCommerceType(productActionType)) {
|
|
6958
|
+
event.CustomFlags = event.CustomFlags || {};
|
|
6959
|
+
event.CustomFlags['Rokt.CommerceEventType'] = Types.ProductActionType.getExpansionName(productActionType);
|
|
6960
|
+
}
|
|
6961
|
+
if (mpInstance._Helpers.isObject(transactionAttributes)) {
|
|
6962
|
+
mpInstance._Ecommerce.convertTransactionAttributesToProductAction(transactionAttributes, event.ProductAction);
|
|
6963
|
+
}
|
|
6964
|
+
self.logCommerceEvent(event, customAttrs, options);
|
|
6965
|
+
}
|
|
6966
|
+
};
|
|
6967
|
+
this.logPurchaseEvent = function (transactionAttributes, product, attrs, customFlags) {
|
|
6968
|
+
var event = mpInstance._Ecommerce.createCommerceEventObject(customFlags);
|
|
6969
|
+
if (event) {
|
|
6970
|
+
event.EventName += mpInstance._Ecommerce.getProductActionEventName(Types.ProductActionType.Purchase);
|
|
6971
|
+
event.EventCategory = Types.CommerceEventType.ProductPurchase;
|
|
6972
|
+
event.ProductAction = {
|
|
6973
|
+
ProductActionType: Types.ProductActionType.Purchase
|
|
6974
|
+
};
|
|
6975
|
+
event.ProductAction.ProductList = mpInstance._Ecommerce.buildProductList(event, product);
|
|
6976
|
+
mpInstance._Ecommerce.convertTransactionAttributesToProductAction(transactionAttributes, event.ProductAction);
|
|
6977
|
+
self.logCommerceEvent(event, attrs);
|
|
6978
|
+
}
|
|
6979
|
+
};
|
|
6980
|
+
this.logRefundEvent = function (transactionAttributes, product, attrs, customFlags) {
|
|
6981
|
+
if (!transactionAttributes) {
|
|
6982
|
+
mpInstance.Logger.error(Messages$3.ErrorMessages.TransactionRequired);
|
|
6983
|
+
return;
|
|
6984
|
+
}
|
|
6985
|
+
var event = mpInstance._Ecommerce.createCommerceEventObject(customFlags);
|
|
6986
|
+
if (event) {
|
|
6987
|
+
event.EventName += mpInstance._Ecommerce.getProductActionEventName(Types.ProductActionType.Refund);
|
|
6988
|
+
event.EventCategory = Types.CommerceEventType.ProductRefund;
|
|
6989
|
+
event.ProductAction = {
|
|
6990
|
+
ProductActionType: Types.ProductActionType.Refund
|
|
6991
|
+
};
|
|
6992
|
+
event.ProductAction.ProductList = mpInstance._Ecommerce.buildProductList(event, product);
|
|
6993
|
+
mpInstance._Ecommerce.convertTransactionAttributesToProductAction(transactionAttributes, event.ProductAction);
|
|
6994
|
+
self.logCommerceEvent(event, attrs);
|
|
6995
|
+
}
|
|
6996
|
+
};
|
|
6997
|
+
this.logPromotionEvent = function (promotionType, promotion, attrs, customFlags, eventOptions) {
|
|
6998
|
+
var event = mpInstance._Ecommerce.createCommerceEventObject(customFlags);
|
|
6999
|
+
if (event) {
|
|
7000
|
+
event.EventName += mpInstance._Ecommerce.getPromotionActionEventName(promotionType);
|
|
7001
|
+
event.EventCategory = mpInstance._Ecommerce.convertPromotionActionToEventType(promotionType);
|
|
7002
|
+
event.PromotionAction = {
|
|
7003
|
+
PromotionActionType: promotionType,
|
|
7004
|
+
PromotionList: Array.isArray(promotion) ? promotion : [promotion]
|
|
7005
|
+
};
|
|
7006
|
+
self.logCommerceEvent(event, attrs, eventOptions);
|
|
7007
|
+
}
|
|
7008
|
+
};
|
|
7009
|
+
this.logImpressionEvent = function (impression, attrs, customFlags, options) {
|
|
7010
|
+
var event = mpInstance._Ecommerce.createCommerceEventObject(customFlags);
|
|
7011
|
+
if (event) {
|
|
7012
|
+
event.EventName += 'Impression';
|
|
7013
|
+
event.EventCategory = Types.CommerceEventType.ProductImpression;
|
|
7014
|
+
if (!Array.isArray(impression)) {
|
|
7015
|
+
impression = [impression];
|
|
7016
|
+
}
|
|
7017
|
+
event.ProductImpressions = [];
|
|
7018
|
+
impression.forEach(function (impression) {
|
|
7019
|
+
event.ProductImpressions.push({
|
|
7020
|
+
ProductImpressionList: impression.Name,
|
|
7021
|
+
ProductList: Array.isArray(impression.Product) ? impression.Product : [impression.Product]
|
|
7022
|
+
});
|
|
7023
|
+
});
|
|
7024
|
+
self.logCommerceEvent(event, attrs, options);
|
|
7025
|
+
}
|
|
7026
|
+
};
|
|
7027
|
+
this.logCommerceEvent = function (commerceEvent, attrs, options) {
|
|
7028
|
+
mpInstance.Logger.verbose(Messages$3.InformationMessages.StartingLogCommerceEvent);
|
|
7029
|
+
// If a developer typos the ProductActionType, the event category will be
|
|
7030
|
+
// null, resulting in kit forwarding errors on the server.
|
|
7031
|
+
// The check for `ProductAction` is required to denote that these are
|
|
7032
|
+
// ProductAction events, and not impression or promotions
|
|
7033
|
+
if (commerceEvent.ProductAction && commerceEvent.EventCategory === null) {
|
|
7034
|
+
mpInstance.Logger.error('Commerce event not sent. The mParticle.ProductActionType you passed was invalid. Re-check your code.');
|
|
7035
|
+
return;
|
|
7036
|
+
}
|
|
7037
|
+
var sanitizedAttrs = mpInstance._Helpers.sanitizeAttributes(attrs, commerceEvent.EventName);
|
|
7038
|
+
if (mpInstance._Helpers.canLog()) {
|
|
7039
|
+
if (mpInstance._Store.webviewBridgeEnabled) {
|
|
7040
|
+
// Don't send shopping cart to parent sdks
|
|
7041
|
+
commerceEvent.ShoppingCart = {};
|
|
7042
|
+
}
|
|
7043
|
+
if (sanitizedAttrs) {
|
|
7044
|
+
commerceEvent.EventAttributes = sanitizedAttrs;
|
|
7045
|
+
}
|
|
7046
|
+
// When no transaction total (Revenue) was provided, derive it from
|
|
7047
|
+
// the products, shipping, and tax.
|
|
7048
|
+
if (commerceEvent.ProductAction) {
|
|
7049
|
+
mpInstance._Ecommerce.calculateProductActionTotalAmount(commerceEvent.ProductAction);
|
|
7050
|
+
}
|
|
7051
|
+
mpInstance._APIClient.sendEventToServer(commerceEvent, options);
|
|
7052
|
+
// https://go.mparticle.com/work/SQDSDKS-6038
|
|
7053
|
+
mpInstance._Persistence.update();
|
|
7054
|
+
} else {
|
|
7055
|
+
mpInstance.Logger.verbose(Messages$3.InformationMessages.AbandonLogEvent);
|
|
7056
|
+
}
|
|
7057
|
+
};
|
|
7058
|
+
this.addEventHandler = function (domEvent, selector, eventName, data, eventType) {
|
|
7059
|
+
var elements = [],
|
|
7060
|
+
handler = function handler(e) {
|
|
7061
|
+
var timeoutHandler = function timeoutHandler() {
|
|
7062
|
+
if (element.href) {
|
|
7063
|
+
window.location.href = element.href;
|
|
7064
|
+
} else if (element.submit) {
|
|
7065
|
+
element.submit();
|
|
7066
|
+
}
|
|
7067
|
+
};
|
|
7068
|
+
mpInstance.Logger.verbose('DOM event triggered, handling event');
|
|
7069
|
+
self.logEvent({
|
|
7070
|
+
messageType: Types.MessageType.PageEvent,
|
|
7071
|
+
name: typeof eventName === 'function' ? eventName(element) : eventName,
|
|
7072
|
+
data: typeof data === 'function' ? data(element) : data,
|
|
7073
|
+
eventType: eventType || Types.EventType.Other
|
|
7074
|
+
});
|
|
7075
|
+
// TODO: Handle middle-clicks and special keys (ctrl, alt, etc)
|
|
7076
|
+
if (element.href && element.target !== '_blank' || element.submit) {
|
|
7077
|
+
// Give xmlhttprequest enough time to execute before navigating a link or submitting form
|
|
7078
|
+
if (e.preventDefault) {
|
|
7079
|
+
e.preventDefault();
|
|
7080
|
+
} else {
|
|
7081
|
+
e.returnValue = false;
|
|
7082
|
+
}
|
|
7083
|
+
setTimeout(timeoutHandler, mpInstance._Store.SDKConfig.timeout);
|
|
7084
|
+
}
|
|
7085
|
+
},
|
|
7086
|
+
element,
|
|
7087
|
+
i;
|
|
7088
|
+
if (!selector) {
|
|
7089
|
+
mpInstance.Logger.error("Can't bind event, selector is required");
|
|
7090
|
+
return;
|
|
6582
7091
|
}
|
|
6583
7092
|
// Handle a css selector string or a dom element
|
|
6584
7093
|
if (typeof selector === 'string') {
|
|
@@ -10764,766 +11273,433 @@ var mParticle = (function () {
|
|
|
10764
11273
|
enrichedAttributes.email = finalUserIdentities.email;
|
|
10765
11274
|
}
|
|
10766
11275
|
// Propagate emailsha256 from current user identities if not already in attributes
|
|
10767
|
-
if (isValidHashedEmailIdentityType) {
|
|
10768
|
-
hashedEmail = finalUserIdentities[this.mappedEmailShaIdentityType];
|
|
10769
|
-
if (hashedEmail && !enrichedAttributes.emailsha256 && !enrichedAttributes[this.mappedEmailShaIdentityType]) {
|
|
10770
|
-
enrichedAttributes.emailsha256 = hashedEmail;
|
|
10771
|
-
}
|
|
10772
|
-
}
|
|
10773
|
-
if (!enrichedAttributes[PASSBACK_CONVERSION_TRACKING_ID]) {
|
|
10774
|
-
(_p = this.integrationCapture) === null || _p === void 0 ? void 0 : _p.capture();
|
|
10775
|
-
capturedAttrs = (_q = this.integrationCapture) === null || _q === void 0 ? void 0 : _q.getClickIdsAsIntegrationAttributes();
|
|
10776
|
-
passbackId = (_r = capturedAttrs === null || capturedAttrs === void 0 ? void 0 : capturedAttrs[PARTNER_MODULE_IDS.Rokt]) === null || _r === void 0 ? void 0 : _r[PASSBACK_CONVERSION_TRACKING_ID];
|
|
10777
|
-
if (passbackId) {
|
|
10778
|
-
enrichedAttributes[PASSBACK_CONVERSION_TRACKING_ID] = passbackId;
|
|
10779
|
-
}
|
|
10780
|
-
}
|
|
10781
|
-
this.filters.filteredUser = this.currentUser || this.filters.filteredUser || null;
|
|
10782
|
-
enrichedOptions = __assign(__assign({}, options), {
|
|
10783
|
-
attributes: enrichedAttributes
|
|
10784
|
-
});
|
|
10785
|
-
return [2 /*return*/, this.kit.selectPlacements(enrichedOptions)];
|
|
10786
|
-
} catch (error) {
|
|
10787
|
-
return [2 /*return*/, Promise.reject(error instanceof Error ? error : new Error('Unknown error occurred'))];
|
|
10788
|
-
}
|
|
10789
|
-
return [2 /*return*/];
|
|
10790
|
-
});
|
|
10791
|
-
});
|
|
10792
|
-
};
|
|
10793
|
-
/**
|
|
10794
|
-
* Hashes attributes and returns both original and hashed versions
|
|
10795
|
-
* with Rokt-compatible key names (like emailsha256, mobilesha256)
|
|
10796
|
-
*
|
|
10797
|
-
*
|
|
10798
|
-
* @param {RoktAttributes} attributes - Attributes to hash
|
|
10799
|
-
* @returns {Promise<RoktAttributes>} Object with both original and hashed attributes
|
|
10800
|
-
*
|
|
10801
|
-
*/
|
|
10802
|
-
RoktManager.prototype.hashAttributes = function (attributes) {
|
|
10803
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
10804
|
-
var keys, hashPromises, results, hashedAttributes, _i, results_1, _a, key, attributeValue, hashedValue, error_1;
|
|
10805
|
-
var _this = this;
|
|
10806
|
-
return __generator(this, function (_b) {
|
|
10807
|
-
switch (_b.label) {
|
|
10808
|
-
case 0:
|
|
10809
|
-
_b.trys.push([0, 2,, 3]);
|
|
10810
|
-
if (!attributes || _typeof$1(attributes) !== 'object') {
|
|
10811
|
-
return [2 /*return*/, {}];
|
|
10812
|
-
}
|
|
10813
|
-
keys = Object.keys(attributes);
|
|
10814
|
-
if (keys.length === 0) {
|
|
10815
|
-
return [2 /*return*/, {}];
|
|
10816
|
-
}
|
|
10817
|
-
hashPromises = keys.map(function (key) {
|
|
10818
|
-
return __awaiter(_this, void 0, void 0, function () {
|
|
10819
|
-
var attributeValue, hashedValue;
|
|
10820
|
-
return __generator(this, function (_a) {
|
|
10821
|
-
switch (_a.label) {
|
|
10822
|
-
case 0:
|
|
10823
|
-
attributeValue = attributes[key];
|
|
10824
|
-
return [4 /*yield*/, this.hashSha256(attributeValue)];
|
|
10825
|
-
case 1:
|
|
10826
|
-
hashedValue = _a.sent();
|
|
10827
|
-
return [2 /*return*/, {
|
|
10828
|
-
key: key,
|
|
10829
|
-
attributeValue: attributeValue,
|
|
10830
|
-
hashedValue: hashedValue
|
|
10831
|
-
}];
|
|
10832
|
-
}
|
|
10833
|
-
});
|
|
10834
|
-
});
|
|
10835
|
-
});
|
|
10836
|
-
return [4 /*yield*/, Promise.all(hashPromises)];
|
|
10837
|
-
case 1:
|
|
10838
|
-
results = _b.sent();
|
|
10839
|
-
hashedAttributes = {};
|
|
10840
|
-
for (_i = 0, results_1 = results; _i < results_1.length; _i++) {
|
|
10841
|
-
_a = results_1[_i], key = _a.key, attributeValue = _a.attributeValue, hashedValue = _a.hashedValue;
|
|
10842
|
-
hashedAttributes[key] = attributeValue;
|
|
10843
|
-
if (hashedValue) {
|
|
10844
|
-
hashedAttributes["".concat(key, "sha256")] = hashedValue;
|
|
10845
|
-
}
|
|
10846
|
-
}
|
|
10847
|
-
return [2 /*return*/, hashedAttributes];
|
|
10848
|
-
case 2:
|
|
10849
|
-
error_1 = _b.sent();
|
|
10850
|
-
this.logger.error("Failed to hashAttributes, returning an empty object: ".concat(getErrorMessage(error_1)));
|
|
10851
|
-
return [2 /*return*/, {}];
|
|
10852
|
-
case 3:
|
|
10853
|
-
return [2 /*return*/];
|
|
10854
|
-
}
|
|
10855
|
-
});
|
|
10856
|
-
});
|
|
10857
|
-
};
|
|
10858
|
-
|
|
10859
|
-
RoktManager.prototype.setExtensionData = function (extensionData) {
|
|
10860
|
-
if (!this.isReady()) {
|
|
10861
|
-
this.deferredCall('setExtensionData', extensionData);
|
|
10862
|
-
return;
|
|
10863
|
-
}
|
|
10864
|
-
try {
|
|
10865
|
-
this.kit.setExtensionData(extensionData);
|
|
10866
|
-
} catch (error) {
|
|
10867
|
-
throw new Error('Error setting extension data: ' + getErrorMessage(error));
|
|
10868
|
-
}
|
|
10869
|
-
};
|
|
10870
|
-
RoktManager.prototype.use = function (name) {
|
|
10871
|
-
if (!this.isReady()) {
|
|
10872
|
-
return this.deferredCall('use', name);
|
|
10873
|
-
}
|
|
10874
|
-
try {
|
|
10875
|
-
return this.kit.use(name);
|
|
10876
|
-
} catch (error) {
|
|
10877
|
-
return Promise.reject(error instanceof Error ? error : new Error('Error using extension: ' + name));
|
|
10878
|
-
}
|
|
10879
|
-
};
|
|
10880
|
-
RoktManager.prototype.onShoppableAdsReady = function (callback) {
|
|
10881
|
-
if (!this.kit || !this.isShoppableAdsLoaded) {
|
|
10882
|
-
this.deferredCall('onShoppableAdsReady', callback);
|
|
10883
|
-
return;
|
|
10884
|
-
}
|
|
10885
|
-
try {
|
|
10886
|
-
this.kit.onShoppableAdsReady(callback);
|
|
10887
|
-
} catch (error) {
|
|
10888
|
-
this.logger.error("Failed to register onShoppableAdsReady callback: ".concat(getErrorMessage(error)));
|
|
10889
|
-
}
|
|
10890
|
-
};
|
|
10891
|
-
RoktManager.prototype.flushOnShoppableAdsReadyMessageQueue = function (kit) {
|
|
10892
|
-
var _this = this;
|
|
10893
|
-
this.kit = kit;
|
|
10894
|
-
this.messageQueue.forEach(function (message, key) {
|
|
10895
|
-
var _a;
|
|
10896
|
-
if (message.methodName === ON_SHOPPABLE_ADS_READY_METHOD) {
|
|
10897
|
-
try {
|
|
10898
|
-
kit.onShoppableAdsReady(message.payload);
|
|
10899
|
-
} catch (e) {
|
|
10900
|
-
(_a = _this.logger) === null || _a === void 0 ? void 0 : _a.error('RoktManager: Error flushing onShoppableAdsReady: ' + e);
|
|
10901
|
-
}
|
|
10902
|
-
_this.messageQueue["delete"](key);
|
|
10903
|
-
}
|
|
10904
|
-
});
|
|
10905
|
-
this.isShoppableAdsLoaded = true;
|
|
10906
|
-
};
|
|
10907
|
-
/**
|
|
10908
|
-
* Hashes an attribute using SHA-256
|
|
10909
|
-
*
|
|
10910
|
-
* @param {string | number | boolean | undefined | null} attribute - The value to hash
|
|
10911
|
-
* @returns {Promise<string | undefined | null>} SHA-256 hashed value or undefined/null
|
|
10912
|
-
*
|
|
10913
|
-
*/
|
|
10914
|
-
RoktManager.prototype.hashSha256 = function (attribute) {
|
|
10915
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
10916
|
-
var normalizedValue, error_2;
|
|
10917
|
-
return __generator(this, function (_a) {
|
|
10918
|
-
switch (_a.label) {
|
|
10919
|
-
case 0:
|
|
10920
|
-
if (attribute === null || attribute === undefined) {
|
|
10921
|
-
this.logger.warning("hashSha256 received null/undefined as input");
|
|
10922
|
-
return [2 /*return*/, attribute];
|
|
10923
|
-
}
|
|
10924
|
-
_a.label = 1;
|
|
10925
|
-
case 1:
|
|
10926
|
-
_a.trys.push([1, 3,, 4]);
|
|
10927
|
-
normalizedValue = String(attribute).trim().toLocaleLowerCase();
|
|
10928
|
-
return [4 /*yield*/, this.sha256Hex(normalizedValue)];
|
|
10929
|
-
case 2:
|
|
10930
|
-
return [2 /*return*/, _a.sent()];
|
|
10931
|
-
case 3:
|
|
10932
|
-
error_2 = _a.sent();
|
|
10933
|
-
this.logger.error("Failed to hashSha256, returning undefined: ".concat(getErrorMessage(error_2)));
|
|
10934
|
-
return [2 /*return*/, undefined];
|
|
10935
|
-
case 4:
|
|
10936
|
-
return [2 /*return*/];
|
|
10937
|
-
}
|
|
10938
|
-
});
|
|
10939
|
-
});
|
|
10940
|
-
};
|
|
10941
|
-
|
|
10942
|
-
RoktManager.prototype.getLocalSessionAttributes = function () {
|
|
10943
|
-
return this.store.getLocalSessionAttributes();
|
|
10944
|
-
};
|
|
10945
|
-
RoktManager.prototype.setLocalSessionAttribute = function (key, value) {
|
|
10946
|
-
this.store.setLocalSessionAttribute(key, value);
|
|
10947
|
-
};
|
|
10948
|
-
RoktManager.prototype.isReady = function () {
|
|
10949
|
-
// The Rokt Manager is ready when a kit is attached and has a launcher
|
|
10950
|
-
return Boolean(this.kit && this.kit.launcher);
|
|
10951
|
-
};
|
|
10952
|
-
RoktManager.prototype.setUserAttributes = function (attributes) {
|
|
10953
|
-
var reservedAttributes = ['sandbox'];
|
|
10954
|
-
var filteredAttributes = {};
|
|
10955
|
-
for (var key in attributes) {
|
|
10956
|
-
if (attributes.hasOwnProperty(key) && reservedAttributes.indexOf(key) === -1) {
|
|
10957
|
-
var value = attributes[key];
|
|
10958
|
-
filteredAttributes[key] = Array.isArray(value) ? JSON.stringify(value) : value;
|
|
10959
|
-
}
|
|
10960
|
-
}
|
|
10961
|
-
try {
|
|
10962
|
-
this.currentUser.setUserAttributes(filteredAttributes);
|
|
10963
|
-
} catch (error) {
|
|
10964
|
-
this.logger.error('Error setting user attributes: ' + error);
|
|
10965
|
-
}
|
|
10966
|
-
};
|
|
10967
|
-
RoktManager.prototype.mapPlacementAttributes = function (attributes, placementAttributesMapping) {
|
|
10968
|
-
var mappingLookup = {};
|
|
10969
|
-
for (var _i = 0, placementAttributesMapping_1 = placementAttributesMapping; _i < placementAttributesMapping_1.length; _i++) {
|
|
10970
|
-
var mapping = placementAttributesMapping_1[_i];
|
|
10971
|
-
mappingLookup[mapping.map] = mapping.value;
|
|
10972
|
-
}
|
|
10973
|
-
var mappedAttributes = {};
|
|
10974
|
-
for (var key in attributes) {
|
|
10975
|
-
if (attributes.hasOwnProperty(key)) {
|
|
10976
|
-
var newKey = mappingLookup[key] || key;
|
|
10977
|
-
mappedAttributes[newKey] = attributes[key];
|
|
10978
|
-
}
|
|
10979
|
-
}
|
|
10980
|
-
return mappedAttributes;
|
|
10981
|
-
};
|
|
10982
|
-
RoktManager.prototype.onIdentityComplete = function () {
|
|
10983
|
-
if (this.isReady()) {
|
|
10984
|
-
this.currentUser = this.identityService.getCurrentUser();
|
|
10985
|
-
// Process any queued selectPlacements calls that were waiting for identity
|
|
10986
|
-
this.processMessageQueue();
|
|
10987
|
-
}
|
|
10988
|
-
};
|
|
10989
|
-
RoktManager.prototype.processMessageQueue = function () {
|
|
10990
|
-
var _this = this;
|
|
10991
|
-
var _a;
|
|
10992
|
-
if (!this.isReady() || this.messageQueue.size === 0) {
|
|
10993
|
-
return;
|
|
10994
|
-
}
|
|
10995
|
-
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.verbose("RoktManager: Processing ".concat(this.messageQueue.size, " queued messages"));
|
|
10996
|
-
var messagesToProcess = Array.from(this.messageQueue.values());
|
|
10997
|
-
// Clear the queue immediately to prevent re-processing
|
|
10998
|
-
this.messageQueue.clear();
|
|
10999
|
-
messagesToProcess.forEach(function (message) {
|
|
11000
|
-
var _a, _b, _c, _d;
|
|
11001
|
-
if (!(message.methodName in _this) || !isFunction(_this[message.methodName])) {
|
|
11002
|
-
(_a = _this.logger) === null || _a === void 0 ? void 0 : _a.error("RoktManager: Method ".concat(message.methodName, " not found"));
|
|
11003
|
-
return;
|
|
11004
|
-
}
|
|
11005
|
-
if ((_b = _this.logger) === null || _b === void 0 ? void 0 : _b.isVerbose()) {
|
|
11006
|
-
var payloadToLog = obfuscateDevData(message.payload, (_d = (_c = _this.store) === null || _c === void 0 ? void 0 : _c.SDKConfig) === null || _d === void 0 ? void 0 : _d.isDevelopmentMode);
|
|
11007
|
-
_this.logger.verbose("RoktManager: Processing queued message: ".concat(message.methodName, " with payload: ").concat(JSON.stringify(payloadToLog)));
|
|
11008
|
-
}
|
|
11009
|
-
// Capture resolve/reject functions before async processing
|
|
11010
|
-
var resolve = message.resolve;
|
|
11011
|
-
var reject = message.reject;
|
|
11012
|
-
var handleError = function handleError(error) {
|
|
11013
|
-
var _a;
|
|
11014
|
-
(_a = _this.logger) === null || _a === void 0 ? void 0 : _a.error("RoktManager: Error processing message '".concat(message.methodName, "': ").concat(getErrorMessage(error)));
|
|
11015
|
-
if (reject) {
|
|
11016
|
-
reject(error);
|
|
11017
|
-
}
|
|
11018
|
-
};
|
|
11019
|
-
try {
|
|
11020
|
-
var result = _this[message.methodName](message.payload);
|
|
11021
|
-
// Handle both sync and async methods
|
|
11022
|
-
Promise.resolve(result).then(function (resolvedResult) {
|
|
11023
|
-
if (resolve) {
|
|
11024
|
-
resolve(resolvedResult);
|
|
11025
|
-
}
|
|
11026
|
-
})["catch"](handleError);
|
|
11027
|
-
} catch (error) {
|
|
11028
|
-
handleError(error);
|
|
11029
|
-
}
|
|
11030
|
-
});
|
|
11031
|
-
};
|
|
11032
|
-
RoktManager.prototype.queueMessage = function (message) {
|
|
11033
|
-
this.messageQueue.set(message.messageId, message);
|
|
11034
|
-
};
|
|
11035
|
-
RoktManager.prototype.deferredCall = function (methodName, payload) {
|
|
11036
|
-
var _this = this;
|
|
11037
|
-
return new Promise(function (resolve, reject) {
|
|
11038
|
-
var messageId = "".concat(methodName, "_").concat(generateUniqueId());
|
|
11039
|
-
_this.queueMessage({
|
|
11040
|
-
messageId: messageId,
|
|
11041
|
-
methodName: methodName,
|
|
11042
|
-
payload: payload,
|
|
11043
|
-
resolve: resolve,
|
|
11044
|
-
reject: reject
|
|
11045
|
-
});
|
|
11046
|
-
});
|
|
11047
|
-
};
|
|
11048
|
-
/**
|
|
11049
|
-
* Hashes a string input using SHA-256 and returns the hex digest
|
|
11050
|
-
* Uses the Web Crypto API for secure hashing
|
|
11051
|
-
*
|
|
11052
|
-
* @param {string} input - The string to hash
|
|
11053
|
-
* @returns {Promise<string>} The SHA-256 hash as a hexadecimal string
|
|
11054
|
-
*/
|
|
11055
|
-
RoktManager.prototype.sha256Hex = function (input) {
|
|
11056
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
11057
|
-
var encoder, encodedInput, digest;
|
|
11058
|
-
return __generator(this, function (_a) {
|
|
11059
|
-
switch (_a.label) {
|
|
11060
|
-
case 0:
|
|
11061
|
-
encoder = new TextEncoder();
|
|
11062
|
-
encodedInput = encoder.encode(input);
|
|
11063
|
-
return [4 /*yield*/, crypto.subtle.digest('SHA-256', encodedInput)];
|
|
11064
|
-
case 1:
|
|
11065
|
-
digest = _a.sent();
|
|
11066
|
-
return [2 /*return*/, this.arrayBufferToHex(digest)];
|
|
11067
|
-
}
|
|
11068
|
-
});
|
|
11069
|
-
});
|
|
11070
|
-
};
|
|
11071
|
-
/**
|
|
11072
|
-
* Converts an ArrayBuffer to a hexadecimal string representation
|
|
11073
|
-
* Each byte is converted to a 2-character hex string with leading zeros
|
|
11074
|
-
*
|
|
11075
|
-
* @param {ArrayBuffer} buffer - The buffer to convert
|
|
11076
|
-
* @returns {string} The hexadecimal string representation
|
|
11077
|
-
*/
|
|
11078
|
-
RoktManager.prototype.arrayBufferToHex = function (buffer) {
|
|
11079
|
-
var bytes = new Uint8Array(buffer);
|
|
11080
|
-
var hexString = '';
|
|
11081
|
-
for (var i = 0; i < bytes.length; i++) {
|
|
11082
|
-
var hexByte = bytes[i].toString(16).padStart(2, '0');
|
|
11083
|
-
hexString += hexByte;
|
|
11084
|
-
}
|
|
11085
|
-
return hexString;
|
|
11086
|
-
};
|
|
11087
|
-
/**
|
|
11088
|
-
* Checks if an identity value has changed by comparing current and new values
|
|
11089
|
-
*
|
|
11090
|
-
* @param {string | undefined} currentValue - The current identity value
|
|
11091
|
-
* @param {string | undefined} newValue - The new identity value to compare against
|
|
11092
|
-
* @returns {boolean} True if the identity has changed (new value exists and differs from current), false otherwise
|
|
11093
|
-
*/
|
|
11094
|
-
RoktManager.prototype.hasIdentityChanged = function (currentValue, newValue) {
|
|
11095
|
-
if (!newValue) {
|
|
11096
|
-
return false;
|
|
11097
|
-
}
|
|
11098
|
-
if (!currentValue) {
|
|
11099
|
-
return true; // New value exists but no current value
|
|
11100
|
-
}
|
|
11101
|
-
|
|
11102
|
-
if (currentValue !== newValue) {
|
|
11103
|
-
return true; // Values are different
|
|
11104
|
-
}
|
|
11105
|
-
|
|
11106
|
-
return false; // Values are the same
|
|
11107
|
-
};
|
|
11108
|
-
|
|
11109
|
-
return RoktManager;
|
|
11110
|
-
}();
|
|
11111
|
-
|
|
11112
|
-
/**
|
|
11113
|
-
* CookieConsentManager handles storage and access of consent flags (noFunctional, noTargeting)
|
|
11114
|
-
* that are passed via launcherOptions during SDK initialization.
|
|
11115
|
-
*
|
|
11116
|
-
* These flags allow Rokt integration to respect user privacy choices.
|
|
11117
|
-
*
|
|
11118
|
-
* Default behavior: Both flags default to false, meaning all features are allowed
|
|
11119
|
-
* unless explicitly opted out by the user.
|
|
11120
|
-
*/
|
|
11121
|
-
var CookieConsentManager = /** @class */function () {
|
|
11122
|
-
function CookieConsentManager(flags) {
|
|
11123
|
-
this.flags = flags;
|
|
11124
|
-
this.flags = {
|
|
11125
|
-
noFunctional: flags.noFunctional === true,
|
|
11126
|
-
noTargeting: flags.noTargeting === true
|
|
11127
|
-
};
|
|
11128
|
-
}
|
|
11129
|
-
/**
|
|
11130
|
-
* Returns true if third-party targeting is disabled.
|
|
11131
|
-
* Targeting is allowed when noTargeting is false (default).
|
|
11132
|
-
*/
|
|
11133
|
-
CookieConsentManager.prototype.getNoTargeting = function () {
|
|
11134
|
-
return this.flags.noTargeting;
|
|
11135
|
-
};
|
|
11136
|
-
/**
|
|
11137
|
-
* Returns true if functional tracking is disabled.
|
|
11138
|
-
* Functional tracking is allowed when noFunctional is false (default).
|
|
11139
|
-
*/
|
|
11140
|
-
CookieConsentManager.prototype.getNoFunctional = function () {
|
|
11141
|
-
return this.flags.noFunctional;
|
|
11142
|
-
};
|
|
11143
|
-
CookieConsentManager.prototype.syncNoTargetingAttribute = function (user) {
|
|
11144
|
-
if (!user) return;
|
|
11145
|
-
if (this.flags.noTargeting) {
|
|
11146
|
-
user.setUserAttribute(NO_TARGETING_ATTRIBUTE, true);
|
|
11147
|
-
} else if (user.getAllUserAttributes().hasOwnProperty(NO_TARGETING_ATTRIBUTE)) {
|
|
11148
|
-
user.removeUserAttribute(NO_TARGETING_ATTRIBUTE);
|
|
11149
|
-
}
|
|
11150
|
-
};
|
|
11151
|
-
return CookieConsentManager;
|
|
11152
|
-
}();
|
|
11153
|
-
|
|
11154
|
-
var ErrorReportingDispatcher = /** @class */function () {
|
|
11155
|
-
function ErrorReportingDispatcher() {
|
|
11156
|
-
this.services = [];
|
|
11157
|
-
}
|
|
11158
|
-
ErrorReportingDispatcher.prototype.register = function (service) {
|
|
11159
|
-
this.services.push(service);
|
|
11160
|
-
};
|
|
11161
|
-
ErrorReportingDispatcher.prototype.report = function (error) {
|
|
11162
|
-
var _this = this;
|
|
11163
|
-
this.services.forEach(function (s) {
|
|
11164
|
-
var _a;
|
|
11165
|
-
try {
|
|
11166
|
-
s.report(error);
|
|
11167
|
-
} catch (e) {
|
|
11168
|
-
(_a = _this.logger) === null || _a === void 0 ? void 0 : _a.error('Error in ErrorReportingService: ' + e);
|
|
11169
|
-
}
|
|
11170
|
-
});
|
|
11171
|
-
};
|
|
11172
|
-
return ErrorReportingDispatcher;
|
|
11173
|
-
}();
|
|
11174
|
-
|
|
11175
|
-
var LoggingDispatcher = /** @class */function () {
|
|
11176
|
-
function LoggingDispatcher() {
|
|
11177
|
-
this.services = [];
|
|
11178
|
-
}
|
|
11179
|
-
LoggingDispatcher.prototype.register = function (service) {
|
|
11180
|
-
this.services.push(service);
|
|
11181
|
-
};
|
|
11182
|
-
LoggingDispatcher.prototype.log = function (entry) {
|
|
11183
|
-
var _this = this;
|
|
11184
|
-
this.services.forEach(function (s) {
|
|
11185
|
-
var _a;
|
|
11186
|
-
try {
|
|
11187
|
-
s.log(entry);
|
|
11188
|
-
} catch (e) {
|
|
11189
|
-
(_a = _this.logger) === null || _a === void 0 ? void 0 : _a.error('Error in LoggingService: ' + e);
|
|
11190
|
-
}
|
|
11191
|
-
});
|
|
11192
|
-
};
|
|
11193
|
-
return LoggingDispatcher;
|
|
11194
|
-
}();
|
|
11195
|
-
|
|
11196
|
-
var HISTORY_METHODS = ['pushState', 'replaceState'];
|
|
11197
|
-
var WRAPPED_MARKER = '__mpApvWrapped__';
|
|
11198
|
-
// All APV state hangs off one window key, and it is the public debugging
|
|
11199
|
-
// contract: `window.__mpApv__` is what you inspect in a console to see whether
|
|
11200
|
-
// tracking is live.
|
|
11201
|
-
//
|
|
11202
|
-
// It lives on `window` rather than in module scope because Next.js re-executes
|
|
11203
|
-
// the SDK bundle on every SPA navigation: module-level state is reset each time,
|
|
11204
|
-
// but `window` persists for the lifetime of the tab.
|
|
11205
|
-
//
|
|
11206
|
-
// One object rather than a key per flag, so resetting is a single reassignment.
|
|
11207
|
-
// Nothing has to be deleted, and there is no ordering in which half the state
|
|
11208
|
-
// survives the reset.
|
|
11209
|
-
var WIN_APV_KEY = '__mpApv__';
|
|
11210
|
-
// ---------------------------------------------------------------------------
|
|
11211
|
-
// Pure helpers. No `this`, no globals, no side effects — callable and assertable
|
|
11212
|
-
// on their own, which is where the interesting rules live.
|
|
11213
|
-
// ---------------------------------------------------------------------------
|
|
11214
|
-
// Dedup keys on pathname only: a query-string- or hash-only change is the same
|
|
11215
|
-
// page and must not fire a view.
|
|
11216
|
-
var isNewPage = function isNewPage(lastPath, candidatePath) {
|
|
11217
|
-
return candidatePath !== lastPath;
|
|
11218
|
-
};
|
|
11219
|
-
var supportsHistoryTracking = function supportsHistoryTracking(win) {
|
|
11220
|
-
return !!win && win.history !== undefined && typeof win.history.pushState === 'function' && typeof win.addEventListener === 'function';
|
|
11221
|
-
};
|
|
11222
|
-
// Mirrors the event shape of the public mParticle.logPageView(), but carries the
|
|
11223
|
-
// path captured when the navigation was accepted rather than the live location.
|
|
11224
|
-
var buildPageViewEvent = function buildPageViewEvent(data) {
|
|
11225
|
-
return {
|
|
11226
|
-
messageType: MessageType$1.PageView,
|
|
11227
|
-
name: 'PageView',
|
|
11228
|
-
data: __assign({}, data),
|
|
11229
|
-
eventType: EventType.Unknown
|
|
11230
|
-
};
|
|
11231
|
-
};
|
|
11232
|
-
// ---------------------------------------------------------------------------
|
|
11233
|
-
// Window-scoped APV state. Every read and write goes through these helpers, so
|
|
11234
|
-
// neither the tracker nor mp-instance touches `window` directly and
|
|
11235
|
-
// `typeof window` is checked in exactly one place.
|
|
11236
|
-
// ---------------------------------------------------------------------------
|
|
11237
|
-
var apvWindow = function apvWindow() {
|
|
11238
|
-
return typeof window === 'undefined' ? null : window;
|
|
11239
|
-
};
|
|
11240
|
-
var freshState = function freshState() {
|
|
11241
|
-
return {
|
|
11242
|
-
initialPageViewFired: false
|
|
11243
|
-
};
|
|
11244
|
-
};
|
|
11245
|
-
// Reads tolerate absent state, so a read never mutates `window`. Only the
|
|
11246
|
-
// writers below create it.
|
|
11247
|
-
var readState = function readState() {
|
|
11248
|
-
var win = apvWindow();
|
|
11249
|
-
return win ? win[WIN_APV_KEY] : undefined;
|
|
11250
|
-
};
|
|
11251
|
-
var writeState = function writeState() {
|
|
11252
|
-
var win = apvWindow();
|
|
11253
|
-
if (!win) {
|
|
11254
|
-
return null;
|
|
11255
|
-
}
|
|
11256
|
-
if (!win[WIN_APV_KEY]) {
|
|
11257
|
-
win[WIN_APV_KEY] = freshState();
|
|
11258
|
-
}
|
|
11259
|
-
return win[WIN_APV_KEY];
|
|
11260
|
-
};
|
|
11261
|
-
var getActiveTracker = function getActiveTracker() {
|
|
11262
|
-
var state = readState();
|
|
11263
|
-
return state ? state.tracker : undefined;
|
|
11264
|
-
};
|
|
11265
|
-
var hasInitialPageViewFired = function hasInitialPageViewFired() {
|
|
11266
|
-
var state = readState();
|
|
11267
|
-
return !!(state && state.initialPageViewFired);
|
|
11268
|
-
};
|
|
11269
|
-
var markInitialPageViewFired = function markInitialPageViewFired() {
|
|
11270
|
-
var state = writeState();
|
|
11271
|
-
if (state) {
|
|
11272
|
-
state.initialPageViewFired = true;
|
|
11273
|
-
}
|
|
11274
|
-
};
|
|
11275
|
-
// Returns the page to its pre-APV state: stops the active tracker (restoring the
|
|
11276
|
-
// history methods it patched), then swaps in fresh state. The state object is the
|
|
11277
|
-
// authoritative handle, so this reaches trackers whose owning module is gone.
|
|
11278
|
-
var resetPageViewTracking = function resetPageViewTracking() {
|
|
11279
|
-
var win = apvWindow();
|
|
11280
|
-
if (!win) {
|
|
11281
|
-
return;
|
|
11282
|
-
}
|
|
11283
|
-
var active = getActiveTracker();
|
|
11284
|
-
if (active) {
|
|
11285
|
-
active.teardown();
|
|
11286
|
-
}
|
|
11287
|
-
// One reassignment replaces every flag at once, so nothing can be left behind
|
|
11288
|
-
// whatever shape the previous state was in.
|
|
11289
|
-
win[WIN_APV_KEY] = freshState();
|
|
11290
|
-
};
|
|
11291
|
-
var setActiveTracker = function setActiveTracker(tracker) {
|
|
11292
|
-
var state = writeState();
|
|
11293
|
-
if (state) {
|
|
11294
|
-
state.tracker = tracker;
|
|
11295
|
-
}
|
|
11296
|
-
};
|
|
11297
|
-
var clearActiveTracker = function clearActiveTracker(tracker) {
|
|
11298
|
-
var state = readState();
|
|
11299
|
-
if (state && state.tracker === tracker) {
|
|
11300
|
-
state.tracker = undefined;
|
|
11301
|
-
}
|
|
11302
|
-
};
|
|
11303
|
-
var currentPathname = function currentPathname() {
|
|
11304
|
-
return window.location.pathname;
|
|
11305
|
-
};
|
|
11306
|
-
// ---------------------------------------------------------------------------
|
|
11307
|
-
// History patching
|
|
11308
|
-
// ---------------------------------------------------------------------------
|
|
11309
|
-
// Wraps pushState/replaceState so `onNavigate` runs after the real method, and
|
|
11310
|
-
// returns the single function that undoes it — or null when nothing was
|
|
11311
|
-
// installed (history is already wrapped, or a frozen/sealed History rejected the
|
|
11312
|
-
// assignment). Handing back one undo closure keeps the wrapper and original
|
|
11313
|
-
// references out of the tracker entirely: there is no half-patched state for a
|
|
11314
|
-
// caller to inspect, and no way to restore the wrong pair.
|
|
11315
|
-
var patchHistory = function patchHistory(onNavigate, log) {
|
|
11316
|
-
if (window.history.pushState[WRAPPED_MARKER]) {
|
|
11317
|
-
log('[patch] history already wrapped, skipping to avoid double-wrap — STACKED WRAPPER DETECTED');
|
|
11318
|
-
return null;
|
|
11319
|
-
}
|
|
11320
|
-
var originals = {};
|
|
11321
|
-
var wrappers = {};
|
|
11322
|
-
HISTORY_METHODS.forEach(function (name) {
|
|
11323
|
-
var original = window.history[name];
|
|
11324
|
-
originals[name] = original;
|
|
11325
|
-
var wrapper = function wrapper() {
|
|
11326
|
-
var args = [];
|
|
11327
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
11328
|
-
args[_i] = arguments[_i];
|
|
11329
|
-
}
|
|
11330
|
-
var result = original.apply(this, args);
|
|
11331
|
-
onNavigate(name);
|
|
11332
|
-
return result;
|
|
11333
|
-
};
|
|
11334
|
-
Object.defineProperty(wrapper, WRAPPED_MARKER, {
|
|
11335
|
-
value: true,
|
|
11336
|
-
enumerable: false
|
|
11337
|
-
});
|
|
11338
|
-
wrappers[name] = wrapper;
|
|
11339
|
-
});
|
|
11340
|
-
// Restore per method: a third party may have patched one of the two on top of
|
|
11341
|
-
// ours after we installed. Clobbering theirs would break their tracking, so
|
|
11342
|
-
// leave anything that is no longer ours in place.
|
|
11343
|
-
var restore = function restore() {
|
|
11344
|
-
return HISTORY_METHODS.forEach(function (name) {
|
|
11345
|
-
if (window.history[name] === wrappers[name]) {
|
|
11346
|
-
window.history[name] = originals[name];
|
|
11347
|
-
log("[teardown] restored original ".concat(name));
|
|
11348
|
-
} else {
|
|
11349
|
-
log("[teardown] ".concat(name, " no longer ours; leaving in place, gating callback to no-op"));
|
|
11350
|
-
}
|
|
11276
|
+
if (isValidHashedEmailIdentityType) {
|
|
11277
|
+
hashedEmail = finalUserIdentities[this.mappedEmailShaIdentityType];
|
|
11278
|
+
if (hashedEmail && !enrichedAttributes.emailsha256 && !enrichedAttributes[this.mappedEmailShaIdentityType]) {
|
|
11279
|
+
enrichedAttributes.emailsha256 = hashedEmail;
|
|
11280
|
+
}
|
|
11281
|
+
}
|
|
11282
|
+
if (!enrichedAttributes[PASSBACK_CONVERSION_TRACKING_ID]) {
|
|
11283
|
+
(_p = this.integrationCapture) === null || _p === void 0 ? void 0 : _p.capture();
|
|
11284
|
+
capturedAttrs = (_q = this.integrationCapture) === null || _q === void 0 ? void 0 : _q.getClickIdsAsIntegrationAttributes();
|
|
11285
|
+
passbackId = (_r = capturedAttrs === null || capturedAttrs === void 0 ? void 0 : capturedAttrs[PARTNER_MODULE_IDS.Rokt]) === null || _r === void 0 ? void 0 : _r[PASSBACK_CONVERSION_TRACKING_ID];
|
|
11286
|
+
if (passbackId) {
|
|
11287
|
+
enrichedAttributes[PASSBACK_CONVERSION_TRACKING_ID] = passbackId;
|
|
11288
|
+
}
|
|
11289
|
+
}
|
|
11290
|
+
this.filters.filteredUser = this.currentUser || this.filters.filteredUser || null;
|
|
11291
|
+
enrichedOptions = __assign(__assign({}, options), {
|
|
11292
|
+
attributes: enrichedAttributes
|
|
11293
|
+
});
|
|
11294
|
+
return [2 /*return*/, this.kit.selectPlacements(enrichedOptions)];
|
|
11295
|
+
} catch (error) {
|
|
11296
|
+
return [2 /*return*/, Promise.reject(error instanceof Error ? error : new Error('Unknown error occurred'))];
|
|
11297
|
+
}
|
|
11298
|
+
return [2 /*return*/];
|
|
11299
|
+
});
|
|
11351
11300
|
});
|
|
11352
11301
|
};
|
|
11353
|
-
|
|
11354
|
-
|
|
11355
|
-
|
|
11302
|
+
/**
|
|
11303
|
+
* Hashes attributes and returns both original and hashed versions
|
|
11304
|
+
* with Rokt-compatible key names (like emailsha256, mobilesha256)
|
|
11305
|
+
*
|
|
11306
|
+
*
|
|
11307
|
+
* @param {RoktAttributes} attributes - Attributes to hash
|
|
11308
|
+
* @returns {Promise<RoktAttributes>} Object with both original and hashed attributes
|
|
11309
|
+
*
|
|
11310
|
+
*/
|
|
11311
|
+
RoktManager.prototype.hashAttributes = function (attributes) {
|
|
11312
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
11313
|
+
var keys, hashPromises, results, hashedAttributes, _i, results_1, _a, key, attributeValue, hashedValue, error_1;
|
|
11314
|
+
var _this = this;
|
|
11315
|
+
return __generator(this, function (_b) {
|
|
11316
|
+
switch (_b.label) {
|
|
11317
|
+
case 0:
|
|
11318
|
+
_b.trys.push([0, 2,, 3]);
|
|
11319
|
+
if (!attributes || _typeof$1(attributes) !== 'object') {
|
|
11320
|
+
return [2 /*return*/, {}];
|
|
11321
|
+
}
|
|
11322
|
+
keys = Object.keys(attributes);
|
|
11323
|
+
if (keys.length === 0) {
|
|
11324
|
+
return [2 /*return*/, {}];
|
|
11325
|
+
}
|
|
11326
|
+
hashPromises = keys.map(function (key) {
|
|
11327
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
11328
|
+
var attributeValue, hashedValue;
|
|
11329
|
+
return __generator(this, function (_a) {
|
|
11330
|
+
switch (_a.label) {
|
|
11331
|
+
case 0:
|
|
11332
|
+
attributeValue = attributes[key];
|
|
11333
|
+
return [4 /*yield*/, this.hashSha256(attributeValue)];
|
|
11334
|
+
case 1:
|
|
11335
|
+
hashedValue = _a.sent();
|
|
11336
|
+
return [2 /*return*/, {
|
|
11337
|
+
key: key,
|
|
11338
|
+
attributeValue: attributeValue,
|
|
11339
|
+
hashedValue: hashedValue
|
|
11340
|
+
}];
|
|
11341
|
+
}
|
|
11342
|
+
});
|
|
11343
|
+
});
|
|
11344
|
+
});
|
|
11345
|
+
return [4 /*yield*/, Promise.all(hashPromises)];
|
|
11346
|
+
case 1:
|
|
11347
|
+
results = _b.sent();
|
|
11348
|
+
hashedAttributes = {};
|
|
11349
|
+
for (_i = 0, results_1 = results; _i < results_1.length; _i++) {
|
|
11350
|
+
_a = results_1[_i], key = _a.key, attributeValue = _a.attributeValue, hashedValue = _a.hashedValue;
|
|
11351
|
+
hashedAttributes[key] = attributeValue;
|
|
11352
|
+
if (hashedValue) {
|
|
11353
|
+
hashedAttributes["".concat(key, "sha256")] = hashedValue;
|
|
11354
|
+
}
|
|
11355
|
+
}
|
|
11356
|
+
return [2 /*return*/, hashedAttributes];
|
|
11357
|
+
case 2:
|
|
11358
|
+
error_1 = _b.sent();
|
|
11359
|
+
this.logger.error("Failed to hashAttributes, returning an empty object: ".concat(getErrorMessage(error_1)));
|
|
11360
|
+
return [2 /*return*/, {}];
|
|
11361
|
+
case 3:
|
|
11362
|
+
return [2 /*return*/];
|
|
11363
|
+
}
|
|
11364
|
+
});
|
|
11356
11365
|
});
|
|
11357
|
-
}
|
|
11358
|
-
|
|
11366
|
+
};
|
|
11367
|
+
|
|
11368
|
+
RoktManager.prototype.setExtensionData = function (extensionData) {
|
|
11369
|
+
if (!this.isReady()) {
|
|
11370
|
+
this.deferredCall('setExtensionData', extensionData);
|
|
11371
|
+
return;
|
|
11372
|
+
}
|
|
11359
11373
|
try {
|
|
11360
|
-
|
|
11361
|
-
} catch (
|
|
11362
|
-
|
|
11374
|
+
this.kit.setExtensionData(extensionData);
|
|
11375
|
+
} catch (error) {
|
|
11376
|
+
throw new Error('Error setting extension data: ' + getErrorMessage(error));
|
|
11363
11377
|
}
|
|
11364
|
-
|
|
11365
|
-
|
|
11366
|
-
|
|
11367
|
-
|
|
11368
|
-
|
|
11369
|
-
|
|
11370
|
-
|
|
11371
|
-
|
|
11372
|
-
|
|
11373
|
-
|
|
11374
|
-
|
|
11375
|
-
|
|
11376
|
-
this.
|
|
11377
|
-
|
|
11378
|
-
this.mpInstance = mpInstance;
|
|
11379
|
-
}
|
|
11380
|
-
Object.defineProperty(PageViewTracker.prototype, "isActive", {
|
|
11381
|
-
// True while this tracker owns the history patch and is listening for
|
|
11382
|
-
// navigations. Flips to false on teardown, including the teardown a
|
|
11383
|
-
// successor tracker performs during a handoff. Read-only, and the one thing
|
|
11384
|
-
// worth checking on `window.__mpApv__.tracker` from a console.
|
|
11385
|
-
get: function get() {
|
|
11386
|
-
return this.active;
|
|
11387
|
-
},
|
|
11388
|
-
enumerable: false,
|
|
11389
|
-
configurable: true
|
|
11390
|
-
});
|
|
11391
|
-
PageViewTracker.prototype.init = function () {
|
|
11392
|
-
var _this = this;
|
|
11393
|
-
this.log('[init] PageViewTracker Init');
|
|
11394
|
-
if (!supportsHistoryTracking(apvWindow())) {
|
|
11395
|
-
this.log('[init] unsupported environment (no History API), not starting');
|
|
11378
|
+
};
|
|
11379
|
+
RoktManager.prototype.use = function (name) {
|
|
11380
|
+
if (!this.isReady()) {
|
|
11381
|
+
return this.deferredCall('use', name);
|
|
11382
|
+
}
|
|
11383
|
+
try {
|
|
11384
|
+
return this.kit.use(name);
|
|
11385
|
+
} catch (error) {
|
|
11386
|
+
return Promise.reject(error instanceof Error ? error : new Error('Error using extension: ' + name));
|
|
11387
|
+
}
|
|
11388
|
+
};
|
|
11389
|
+
RoktManager.prototype.onShoppableAdsReady = function (callback) {
|
|
11390
|
+
if (!this.kit || !this.isShoppableAdsLoaded) {
|
|
11391
|
+
this.deferredCall('onShoppableAdsReady', callback);
|
|
11396
11392
|
return;
|
|
11397
11393
|
}
|
|
11398
|
-
|
|
11399
|
-
|
|
11400
|
-
|
|
11401
|
-
|
|
11402
|
-
// flushed yet, and dropping it loses a page view entirely.
|
|
11403
|
-
var active = getActiveTracker();
|
|
11404
|
-
var inheritedPaths = this.retire(active);
|
|
11405
|
-
if (this.active && active !== this) {
|
|
11406
|
-
inheritedPaths = inheritedPaths.concat(this.retire(this));
|
|
11394
|
+
try {
|
|
11395
|
+
this.kit.onShoppableAdsReady(callback);
|
|
11396
|
+
} catch (error) {
|
|
11397
|
+
this.logger.error("Failed to register onShoppableAdsReady callback: ".concat(getErrorMessage(error)));
|
|
11407
11398
|
}
|
|
11408
|
-
|
|
11409
|
-
|
|
11410
|
-
|
|
11411
|
-
this.
|
|
11412
|
-
|
|
11413
|
-
|
|
11414
|
-
|
|
11399
|
+
};
|
|
11400
|
+
RoktManager.prototype.flushOnShoppableAdsReadyMessageQueue = function (kit) {
|
|
11401
|
+
var _this = this;
|
|
11402
|
+
this.kit = kit;
|
|
11403
|
+
this.messageQueue.forEach(function (message, key) {
|
|
11404
|
+
var _a;
|
|
11405
|
+
if (message.methodName === ON_SHOPPABLE_ADS_READY_METHOD) {
|
|
11406
|
+
try {
|
|
11407
|
+
kit.onShoppableAdsReady(message.payload);
|
|
11408
|
+
} catch (e) {
|
|
11409
|
+
(_a = _this.logger) === null || _a === void 0 ? void 0 : _a.error('RoktManager: Error flushing onShoppableAdsReady: ' + e);
|
|
11410
|
+
}
|
|
11411
|
+
_this.messageQueue["delete"](key);
|
|
11412
|
+
}
|
|
11415
11413
|
});
|
|
11416
|
-
this.
|
|
11417
|
-
|
|
11418
|
-
|
|
11419
|
-
|
|
11420
|
-
|
|
11421
|
-
|
|
11422
|
-
|
|
11423
|
-
|
|
11414
|
+
this.isShoppableAdsLoaded = true;
|
|
11415
|
+
};
|
|
11416
|
+
/**
|
|
11417
|
+
* Hashes an attribute using SHA-256
|
|
11418
|
+
*
|
|
11419
|
+
* @param {string | number | boolean | undefined | null} attribute - The value to hash
|
|
11420
|
+
* @returns {Promise<string | undefined | null>} SHA-256 hashed value or undefined/null
|
|
11421
|
+
*
|
|
11422
|
+
*/
|
|
11423
|
+
RoktManager.prototype.hashSha256 = function (attribute) {
|
|
11424
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
11425
|
+
var normalizedValue, error_2;
|
|
11426
|
+
return __generator(this, function (_a) {
|
|
11427
|
+
switch (_a.label) {
|
|
11428
|
+
case 0:
|
|
11429
|
+
if (attribute === null || attribute === undefined) {
|
|
11430
|
+
this.logger.warning("hashSha256 received null/undefined as input");
|
|
11431
|
+
return [2 /*return*/, attribute];
|
|
11432
|
+
}
|
|
11433
|
+
_a.label = 1;
|
|
11434
|
+
case 1:
|
|
11435
|
+
_a.trys.push([1, 3,, 4]);
|
|
11436
|
+
normalizedValue = String(attribute).trim().toLocaleLowerCase();
|
|
11437
|
+
return [4 /*yield*/, this.sha256Hex(normalizedValue)];
|
|
11438
|
+
case 2:
|
|
11439
|
+
return [2 /*return*/, _a.sent()];
|
|
11440
|
+
case 3:
|
|
11441
|
+
error_2 = _a.sent();
|
|
11442
|
+
this.logger.error("Failed to hashSha256, returning undefined: ".concat(getErrorMessage(error_2)));
|
|
11443
|
+
return [2 /*return*/, undefined];
|
|
11444
|
+
case 4:
|
|
11445
|
+
return [2 /*return*/];
|
|
11446
|
+
}
|
|
11447
|
+
});
|
|
11424
11448
|
});
|
|
11425
11449
|
};
|
|
11426
|
-
|
|
11427
|
-
|
|
11428
|
-
|
|
11429
|
-
|
|
11430
|
-
|
|
11431
|
-
|
|
11432
|
-
|
|
11433
|
-
|
|
11450
|
+
|
|
11451
|
+
RoktManager.prototype.getLocalSessionAttributes = function () {
|
|
11452
|
+
return this.store.getLocalSessionAttributes();
|
|
11453
|
+
};
|
|
11454
|
+
RoktManager.prototype.setLocalSessionAttribute = function (key, value) {
|
|
11455
|
+
this.store.setLocalSessionAttribute(key, value);
|
|
11456
|
+
};
|
|
11457
|
+
RoktManager.prototype.isReady = function () {
|
|
11458
|
+
// The Rokt Manager is ready when a kit is attached and has a launcher
|
|
11459
|
+
return Boolean(this.kit && this.kit.launcher);
|
|
11460
|
+
};
|
|
11461
|
+
RoktManager.prototype.setUserAttributes = function (attributes) {
|
|
11462
|
+
var reservedAttributes = ['sandbox'];
|
|
11463
|
+
var filteredAttributes = {};
|
|
11464
|
+
for (var key in attributes) {
|
|
11465
|
+
if (attributes.hasOwnProperty(key) && reservedAttributes.indexOf(key) === -1) {
|
|
11466
|
+
var value = attributes[key];
|
|
11467
|
+
filteredAttributes[key] = Array.isArray(value) ? JSON.stringify(value) : value;
|
|
11468
|
+
}
|
|
11469
|
+
}
|
|
11470
|
+
try {
|
|
11471
|
+
this.currentUser.setUserAttributes(filteredAttributes);
|
|
11472
|
+
} catch (error) {
|
|
11473
|
+
this.logger.error('Error setting user attributes: ' + error);
|
|
11474
|
+
}
|
|
11475
|
+
};
|
|
11476
|
+
RoktManager.prototype.mapPlacementAttributes = function (attributes, placementAttributesMapping) {
|
|
11477
|
+
var mappingLookup = {};
|
|
11478
|
+
for (var _i = 0, placementAttributesMapping_1 = placementAttributesMapping; _i < placementAttributesMapping_1.length; _i++) {
|
|
11479
|
+
var mapping = placementAttributesMapping_1[_i];
|
|
11480
|
+
mappingLookup[mapping.map] = mapping.value;
|
|
11434
11481
|
}
|
|
11435
|
-
|
|
11436
|
-
|
|
11437
|
-
|
|
11482
|
+
var mappedAttributes = {};
|
|
11483
|
+
for (var key in attributes) {
|
|
11484
|
+
if (attributes.hasOwnProperty(key)) {
|
|
11485
|
+
var newKey = mappingLookup[key] || key;
|
|
11486
|
+
mappedAttributes[newKey] = attributes[key];
|
|
11487
|
+
}
|
|
11438
11488
|
}
|
|
11439
|
-
|
|
11440
|
-
clearActiveTracker(this);
|
|
11489
|
+
return mappedAttributes;
|
|
11441
11490
|
};
|
|
11442
|
-
|
|
11443
|
-
|
|
11444
|
-
|
|
11445
|
-
|
|
11446
|
-
|
|
11447
|
-
return [];
|
|
11491
|
+
RoktManager.prototype.onIdentityComplete = function () {
|
|
11492
|
+
if (this.isReady()) {
|
|
11493
|
+
this.currentUser = this.identityService.getCurrentUser();
|
|
11494
|
+
// Process any queued selectPlacements calls that were waiting for identity
|
|
11495
|
+
this.processMessageQueue();
|
|
11448
11496
|
}
|
|
11449
|
-
this.log(outgoing === this ? '[init] retiring this tracker for a repeat mParticle.init() — transferring pending navigations and tearing down' : '[init] retiring a tracker from a previous module load — transferring pending navigations and tearing down');
|
|
11450
|
-
var paths = outgoing.takePendingNavigations();
|
|
11451
|
-
outgoing.teardown();
|
|
11452
|
-
return paths;
|
|
11453
11497
|
};
|
|
11454
|
-
|
|
11455
|
-
|
|
11456
|
-
var
|
|
11457
|
-
this.
|
|
11458
|
-
|
|
11459
|
-
|
|
11498
|
+
RoktManager.prototype.processMessageQueue = function () {
|
|
11499
|
+
var _this = this;
|
|
11500
|
+
var _a;
|
|
11501
|
+
if (!this.isReady() || this.messageQueue.size === 0) {
|
|
11502
|
+
return;
|
|
11503
|
+
}
|
|
11504
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.verbose("RoktManager: Processing ".concat(this.messageQueue.size, " queued messages"));
|
|
11505
|
+
var messagesToProcess = Array.from(this.messageQueue.values());
|
|
11506
|
+
// Clear the queue immediately to prevent re-processing
|
|
11507
|
+
this.messageQueue.clear();
|
|
11508
|
+
messagesToProcess.forEach(function (message) {
|
|
11509
|
+
var _a, _b, _c, _d;
|
|
11510
|
+
if (!(message.methodName in _this) || !isFunction(_this[message.methodName])) {
|
|
11511
|
+
(_a = _this.logger) === null || _a === void 0 ? void 0 : _a.error("RoktManager: Method ".concat(message.methodName, " not found"));
|
|
11512
|
+
return;
|
|
11513
|
+
}
|
|
11514
|
+
if ((_b = _this.logger) === null || _b === void 0 ? void 0 : _b.isVerbose()) {
|
|
11515
|
+
var payloadToLog = obfuscateDevData(message.payload, (_d = (_c = _this.store) === null || _c === void 0 ? void 0 : _c.SDKConfig) === null || _d === void 0 ? void 0 : _d.isDevelopmentMode);
|
|
11516
|
+
_this.logger.verbose("RoktManager: Processing queued message: ".concat(message.methodName, " with payload: ").concat(JSON.stringify(payloadToLog)));
|
|
11517
|
+
}
|
|
11518
|
+
// Capture resolve/reject functions before async processing
|
|
11519
|
+
var resolve = message.resolve;
|
|
11520
|
+
var reject = message.reject;
|
|
11521
|
+
var handleError = function handleError(error) {
|
|
11522
|
+
var _a;
|
|
11523
|
+
(_a = _this.logger) === null || _a === void 0 ? void 0 : _a.error("RoktManager: Error processing message '".concat(message.methodName, "': ").concat(getErrorMessage(error)));
|
|
11524
|
+
if (reject) {
|
|
11525
|
+
reject(error);
|
|
11526
|
+
}
|
|
11527
|
+
};
|
|
11528
|
+
try {
|
|
11529
|
+
var result = _this[message.methodName](message.payload);
|
|
11530
|
+
// Handle both sync and async methods
|
|
11531
|
+
Promise.resolve(result).then(function (resolvedResult) {
|
|
11532
|
+
if (resolve) {
|
|
11533
|
+
resolve(resolvedResult);
|
|
11534
|
+
}
|
|
11535
|
+
})["catch"](handleError);
|
|
11536
|
+
} catch (error) {
|
|
11537
|
+
handleError(error);
|
|
11538
|
+
}
|
|
11460
11539
|
});
|
|
11461
|
-
|
|
11462
|
-
|
|
11540
|
+
};
|
|
11541
|
+
RoktManager.prototype.queueMessage = function (message) {
|
|
11542
|
+
this.messageQueue.set(message.messageId, message);
|
|
11543
|
+
};
|
|
11544
|
+
RoktManager.prototype.deferredCall = function (methodName, payload) {
|
|
11545
|
+
var _this = this;
|
|
11546
|
+
return new Promise(function (resolve, reject) {
|
|
11547
|
+
var messageId = "".concat(methodName, "_").concat(generateUniqueId());
|
|
11548
|
+
_this.queueMessage({
|
|
11549
|
+
messageId: messageId,
|
|
11550
|
+
methodName: methodName,
|
|
11551
|
+
payload: payload,
|
|
11552
|
+
resolve: resolve,
|
|
11553
|
+
reject: reject
|
|
11554
|
+
});
|
|
11463
11555
|
});
|
|
11464
11556
|
};
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
|
|
11469
|
-
|
|
11470
|
-
|
|
11471
|
-
|
|
11472
|
-
|
|
11557
|
+
/**
|
|
11558
|
+
* Hashes a string input using SHA-256 and returns the hex digest
|
|
11559
|
+
* Uses the Web Crypto API for secure hashing
|
|
11560
|
+
*
|
|
11561
|
+
* @param {string} input - The string to hash
|
|
11562
|
+
* @returns {Promise<string>} The SHA-256 hash as a hexadecimal string
|
|
11563
|
+
*/
|
|
11564
|
+
RoktManager.prototype.sha256Hex = function (input) {
|
|
11565
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
11566
|
+
var encoder, encodedInput, digest;
|
|
11567
|
+
return __generator(this, function (_a) {
|
|
11568
|
+
switch (_a.label) {
|
|
11569
|
+
case 0:
|
|
11570
|
+
encoder = new TextEncoder();
|
|
11571
|
+
encodedInput = encoder.encode(input);
|
|
11572
|
+
return [4 /*yield*/, crypto.subtle.digest('SHA-256', encodedInput)];
|
|
11573
|
+
case 1:
|
|
11574
|
+
digest = _a.sent();
|
|
11575
|
+
return [2 /*return*/, this.arrayBufferToHex(digest)];
|
|
11576
|
+
}
|
|
11577
|
+
});
|
|
11578
|
+
});
|
|
11579
|
+
};
|
|
11580
|
+
/**
|
|
11581
|
+
* Converts an ArrayBuffer to a hexadecimal string representation
|
|
11582
|
+
* Each byte is converted to a 2-character hex string with leading zeros
|
|
11583
|
+
*
|
|
11584
|
+
* @param {ArrayBuffer} buffer - The buffer to convert
|
|
11585
|
+
* @returns {string} The hexadecimal string representation
|
|
11586
|
+
*/
|
|
11587
|
+
RoktManager.prototype.arrayBufferToHex = function (buffer) {
|
|
11588
|
+
var bytes = new Uint8Array(buffer);
|
|
11589
|
+
var hexString = '';
|
|
11590
|
+
for (var i = 0; i < bytes.length; i++) {
|
|
11591
|
+
var hexByte = bytes[i].toString(16).padStart(2, '0');
|
|
11592
|
+
hexString += hexByte;
|
|
11473
11593
|
}
|
|
11474
|
-
|
|
11475
|
-
|
|
11476
|
-
|
|
11477
|
-
|
|
11594
|
+
return hexString;
|
|
11595
|
+
};
|
|
11596
|
+
/**
|
|
11597
|
+
* Checks if an identity value has changed by comparing current and new values
|
|
11598
|
+
*
|
|
11599
|
+
* @param {string | undefined} currentValue - The current identity value
|
|
11600
|
+
* @param {string | undefined} newValue - The new identity value to compare against
|
|
11601
|
+
* @returns {boolean} True if the identity has changed (new value exists and differs from current), false otherwise
|
|
11602
|
+
*/
|
|
11603
|
+
RoktManager.prototype.hasIdentityChanged = function (currentValue, newValue) {
|
|
11604
|
+
if (!newValue) {
|
|
11605
|
+
return false;
|
|
11606
|
+
}
|
|
11607
|
+
if (!currentValue) {
|
|
11608
|
+
return true; // New value exists but no current value
|
|
11609
|
+
}
|
|
11610
|
+
|
|
11611
|
+
if (currentValue !== newValue) {
|
|
11612
|
+
return true; // Values are different
|
|
11478
11613
|
}
|
|
11614
|
+
|
|
11615
|
+
return false; // Values are the same
|
|
11479
11616
|
};
|
|
11480
|
-
|
|
11481
|
-
|
|
11482
|
-
|
|
11483
|
-
|
|
11484
|
-
|
|
11485
|
-
|
|
11617
|
+
|
|
11618
|
+
return RoktManager;
|
|
11619
|
+
}();
|
|
11620
|
+
|
|
11621
|
+
/**
|
|
11622
|
+
* CookieConsentManager handles storage and access of consent flags (noFunctional, noTargeting)
|
|
11623
|
+
* that are passed via launcherOptions during SDK initialization.
|
|
11624
|
+
*
|
|
11625
|
+
* These flags allow Rokt integration to respect user privacy choices.
|
|
11626
|
+
*
|
|
11627
|
+
* Default behavior: Both flags default to false, meaning all features are allowed
|
|
11628
|
+
* unless explicitly opted out by the user.
|
|
11629
|
+
*/
|
|
11630
|
+
var CookieConsentManager = /** @class */function () {
|
|
11631
|
+
function CookieConsentManager(flags) {
|
|
11632
|
+
this.flags = flags;
|
|
11633
|
+
this.flags = {
|
|
11634
|
+
noFunctional: flags.noFunctional === true,
|
|
11635
|
+
noTargeting: flags.noTargeting === true
|
|
11636
|
+
};
|
|
11637
|
+
}
|
|
11638
|
+
/**
|
|
11639
|
+
* Returns true if third-party targeting is disabled.
|
|
11640
|
+
* Targeting is allowed when noTargeting is false (default).
|
|
11641
|
+
*/
|
|
11642
|
+
CookieConsentManager.prototype.getNoTargeting = function () {
|
|
11643
|
+
return this.flags.noTargeting;
|
|
11644
|
+
};
|
|
11645
|
+
/**
|
|
11646
|
+
* Returns true if functional tracking is disabled.
|
|
11647
|
+
* Functional tracking is allowed when noFunctional is false (default).
|
|
11648
|
+
*/
|
|
11649
|
+
CookieConsentManager.prototype.getNoFunctional = function () {
|
|
11650
|
+
return this.flags.noFunctional;
|
|
11651
|
+
};
|
|
11652
|
+
CookieConsentManager.prototype.syncNoTargetingAttribute = function (user) {
|
|
11653
|
+
if (!user) return;
|
|
11654
|
+
if (this.flags.noTargeting) {
|
|
11655
|
+
user.setUserAttribute(NO_TARGETING_ATTRIBUTE, true);
|
|
11656
|
+
} else if (user.getAllUserAttributes().hasOwnProperty(NO_TARGETING_ATTRIBUTE)) {
|
|
11657
|
+
user.removeUserAttribute(NO_TARGETING_ATTRIBUTE);
|
|
11486
11658
|
}
|
|
11487
|
-
this.log("[accept] pathname changed, scheduling fire (source: ".concat(source, ", from: ").concat(this.lastPath, ", to: ").concat(candidatePath, ")"));
|
|
11488
|
-
this.lastPath = candidatePath;
|
|
11489
|
-
this.scheduleFire(candidatePath);
|
|
11490
11659
|
};
|
|
11491
|
-
|
|
11492
|
-
|
|
11493
|
-
|
|
11494
|
-
|
|
11495
|
-
|
|
11660
|
+
return CookieConsentManager;
|
|
11661
|
+
}();
|
|
11662
|
+
|
|
11663
|
+
var ErrorReportingDispatcher = /** @class */function () {
|
|
11664
|
+
function ErrorReportingDispatcher() {
|
|
11665
|
+
this.services = [];
|
|
11666
|
+
}
|
|
11667
|
+
ErrorReportingDispatcher.prototype.register = function (service) {
|
|
11668
|
+
this.services.push(service);
|
|
11669
|
+
};
|
|
11670
|
+
ErrorReportingDispatcher.prototype.report = function (error) {
|
|
11496
11671
|
var _this = this;
|
|
11497
|
-
|
|
11498
|
-
|
|
11499
|
-
|
|
11500
|
-
|
|
11501
|
-
|
|
11502
|
-
_this.
|
|
11503
|
-
return;
|
|
11672
|
+
this.services.forEach(function (s) {
|
|
11673
|
+
var _a;
|
|
11674
|
+
try {
|
|
11675
|
+
s.report(error);
|
|
11676
|
+
} catch (e) {
|
|
11677
|
+
(_a = _this.logger) === null || _a === void 0 ? void 0 : _a.error('Error in ErrorReportingService: ' + e);
|
|
11504
11678
|
}
|
|
11505
|
-
_this.mpInstance._SessionManager.resetSessionTimer();
|
|
11506
|
-
_this.firePageView(path);
|
|
11507
|
-
}, 0);
|
|
11508
|
-
this.pendingNavigations.push({
|
|
11509
|
-
path: path,
|
|
11510
|
-
timeoutId: timeoutId
|
|
11511
11679
|
});
|
|
11512
11680
|
};
|
|
11513
|
-
|
|
11514
|
-
|
|
11515
|
-
|
|
11516
|
-
|
|
11517
|
-
|
|
11518
|
-
|
|
11519
|
-
|
|
11520
|
-
|
|
11521
|
-
this.
|
|
11681
|
+
return ErrorReportingDispatcher;
|
|
11682
|
+
}();
|
|
11683
|
+
|
|
11684
|
+
var LoggingDispatcher = /** @class */function () {
|
|
11685
|
+
function LoggingDispatcher() {
|
|
11686
|
+
this.services = [];
|
|
11687
|
+
}
|
|
11688
|
+
LoggingDispatcher.prototype.register = function (service) {
|
|
11689
|
+
this.services.push(service);
|
|
11522
11690
|
};
|
|
11523
|
-
|
|
11524
|
-
|
|
11691
|
+
LoggingDispatcher.prototype.log = function (entry) {
|
|
11692
|
+
var _this = this;
|
|
11693
|
+
this.services.forEach(function (s) {
|
|
11694
|
+
var _a;
|
|
11695
|
+
try {
|
|
11696
|
+
s.log(entry);
|
|
11697
|
+
} catch (e) {
|
|
11698
|
+
(_a = _this.logger) === null || _a === void 0 ? void 0 : _a.error('Error in LoggingService: ' + e);
|
|
11699
|
+
}
|
|
11700
|
+
});
|
|
11525
11701
|
};
|
|
11526
|
-
return
|
|
11702
|
+
return LoggingDispatcher;
|
|
11527
11703
|
}();
|
|
11528
11704
|
|
|
11529
11705
|
var Messages = Constants.Messages,
|