@mparticle/web-sdk 3.6.2 → 3.8.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 +63 -42
- package/dist/mparticle.esm.js +63 -42
- package/dist/mparticle.js +204 -90
- package/dist/types/src/events.interfaces.d.ts +2 -1
- package/dist/types/src/integrationCapture.d.ts +3 -0
- package/dist/types/src/pageViewTracker.d.ts +9 -2
- package/dist/types/src/types.d.ts +1 -0
- package/dist/types/src/utils.d.ts +4 -3
- package/package.json +1 -1
- package/src/consent.ts +3 -3
- package/src/cookieConsentManager.ts +2 -3
- package/src/cookieSyncManager.ts +82 -69
- package/src/events.interfaces.ts +2 -1
- package/src/events.ts +7 -2
- package/src/filteredMparticleUser.ts +18 -10
- package/src/forwarders.ts +2 -2
- package/src/helpers.ts +9 -1
- package/src/identity-utils.ts +2 -3
- package/src/identity.ts +29 -11
- package/src/integrationCapture.ts +59 -0
- package/src/mp-instance.ts +4 -2
- package/src/pageViewTracker.ts +27 -1
- package/src/persistence.ts +3 -3
- package/src/store.ts +1 -1
- package/src/types.ts +14 -0
- package/src/utils.ts +29 -10
package/dist/mparticle.js
CHANGED
|
@@ -204,7 +204,7 @@ var mParticle = (function () {
|
|
|
204
204
|
Base64: Base64$1
|
|
205
205
|
};
|
|
206
206
|
|
|
207
|
-
var version = "3.
|
|
207
|
+
var version = "3.8.0";
|
|
208
208
|
|
|
209
209
|
var Constants = {
|
|
210
210
|
sdkVersion: version,
|
|
@@ -547,7 +547,7 @@ var mParticle = (function () {
|
|
|
547
547
|
var findKeyInObject = function findKeyInObject(obj, key) {
|
|
548
548
|
if (key && obj) {
|
|
549
549
|
for (var prop in obj) {
|
|
550
|
-
if (obj
|
|
550
|
+
if (hasOwnProp(obj, prop) && prop.toLowerCase() === key.toLowerCase()) {
|
|
551
551
|
return prop;
|
|
552
552
|
}
|
|
553
553
|
}
|
|
@@ -704,10 +704,14 @@ var mParticle = (function () {
|
|
|
704
704
|
'/': '_',
|
|
705
705
|
'=': ''
|
|
706
706
|
};
|
|
707
|
+
// btoa is defined only over Latin-1 and throws InvalidCharacterError above U+00FF
|
|
708
|
+
var isLatin1 = function isLatin1(value) {
|
|
709
|
+
return !/[^\u0000-\u00ff]/.test(value);
|
|
710
|
+
};
|
|
707
711
|
var toWebSafeBase64 = function toWebSafeBase64(value) {
|
|
708
|
-
return btoa(value).replace(/[+/=]/g, function (c) {
|
|
712
|
+
return isLatin1(value) ? btoa(value).replace(/[+/=]/g, function (c) {
|
|
709
713
|
return WEB_SAFE_BASE64_REPLACEMENTS[c];
|
|
710
|
-
});
|
|
714
|
+
}) : undefined;
|
|
711
715
|
};
|
|
712
716
|
// FIXME: REFACTOR for V3
|
|
713
717
|
// only used in store.js to sanitize server-side formatting of
|
|
@@ -773,6 +777,23 @@ var mParticle = (function () {
|
|
|
773
777
|
var hasOwnProp = function hasOwnProp(obj, key) {
|
|
774
778
|
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
775
779
|
};
|
|
780
|
+
// Assigning `__proto__` replaces the target's prototype instead of adding an own
|
|
781
|
+
// property; `constructor` is reserved alongside it by the stored-record contract.
|
|
782
|
+
// `prototype` is deliberately absent: isValidKeyValue accepts it, so setUserAttribute
|
|
783
|
+
// persists it and the getters must hand it back.
|
|
784
|
+
var isReservedStoredPropertyName = function isReservedStoredPropertyName(name) {
|
|
785
|
+
return name === '__proto__' || name === 'constructor';
|
|
786
|
+
};
|
|
787
|
+
// extend's historical set, which additionally refuses `prototype` when merging.
|
|
788
|
+
var isUncopyableMergeName = function isUncopyableMergeName(name) {
|
|
789
|
+
return isReservedStoredPropertyName(name) || name === 'prototype';
|
|
790
|
+
};
|
|
791
|
+
// Kit-facing copies stay compatible with conventional own-property iteration, such as
|
|
792
|
+
// attributes.hasOwnProperty(key), which is the one read pattern an attribute of that name
|
|
793
|
+
// interferes with. The public getters keep the name; only this filter drops it.
|
|
794
|
+
var isReservedKitPropertyName = function isReservedKitPropertyName(name) {
|
|
795
|
+
return isReservedStoredPropertyName(name) || name === 'hasOwnProperty';
|
|
796
|
+
};
|
|
776
797
|
var queryStringParser = function queryStringParser(url, keys) {
|
|
777
798
|
if (keys === void 0) {
|
|
778
799
|
keys = [];
|
|
@@ -877,7 +898,7 @@ var mParticle = (function () {
|
|
|
877
898
|
var filtered = {};
|
|
878
899
|
if (!isEmpty(dictionary)) {
|
|
879
900
|
for (var key in dictionary) {
|
|
880
|
-
if (dictionary
|
|
901
|
+
if (hasOwnProp(dictionary, key) && !isReservedKitPropertyName(key)) {
|
|
881
902
|
var hashedKey = hashFn(key);
|
|
882
903
|
if (!inArray(filterList, hashedKey)) {
|
|
883
904
|
filtered[key] = dictionary[key];
|
|
@@ -1013,7 +1034,7 @@ var mParticle = (function () {
|
|
|
1013
1034
|
for (; i < length; i++) {
|
|
1014
1035
|
if ((options = args[i]) != null) {
|
|
1015
1036
|
for (name in options) {
|
|
1016
|
-
if (name
|
|
1037
|
+
if (isUncopyableMergeName(name)) {
|
|
1017
1038
|
continue;
|
|
1018
1039
|
}
|
|
1019
1040
|
if (!Object.prototype.hasOwnProperty.call(options, name)) {
|
|
@@ -1484,6 +1505,17 @@ var mParticle = (function () {
|
|
|
1484
1505
|
JointSdkSelectPlacements: 'mp:jointSdkSelectPlacements',
|
|
1485
1506
|
JointSdkRoktKitInit: 'mp:jointSdkRoktKitInit'
|
|
1486
1507
|
};
|
|
1508
|
+
// A stored `ui` key is the decimal string of an IdentityType; anything else was
|
|
1509
|
+
// not written by this SDK. The round-trip comparison is load bearing: parseNumber
|
|
1510
|
+
// returns 0 for any non-numeric key and IdentityType.Other is 0, so after parsing
|
|
1511
|
+
// alone a stored "hasOwnProperty" is indistinguishable from a genuine Other entry.
|
|
1512
|
+
function getIdentityTypeFromStoredKey(key) {
|
|
1513
|
+
var identityType = parseNumber(key);
|
|
1514
|
+
if (String(identityType) !== key || !IdentityType.isValid(identityType)) {
|
|
1515
|
+
return null;
|
|
1516
|
+
}
|
|
1517
|
+
return identityType;
|
|
1518
|
+
}
|
|
1487
1519
|
var Types = {
|
|
1488
1520
|
MessageType: MessageType$1,
|
|
1489
1521
|
EventType: EventType,
|
|
@@ -3462,8 +3494,7 @@ var mParticle = (function () {
|
|
|
3462
3494
|
}
|
|
3463
3495
|
var cacheKey = concatenateIdentities(method, proposedUserIdentities);
|
|
3464
3496
|
var hashedKey = generateHash(cacheKey);
|
|
3465
|
-
|
|
3466
|
-
if (!cache.hasOwnProperty(hashedKey)) {
|
|
3497
|
+
if (!hasOwnProp(cache, hashedKey)) {
|
|
3467
3498
|
return false;
|
|
3468
3499
|
}
|
|
3469
3500
|
// If there is a valid cache key, compare the expireTimestamp to the current time.
|
|
@@ -3925,7 +3956,9 @@ var mParticle = (function () {
|
|
|
3925
3956
|
}
|
|
3926
3957
|
return mostRecentUser || null;
|
|
3927
3958
|
} else {
|
|
3928
|
-
|
|
3959
|
+
var currentUser = mParticleUser || mpInstance.Identity.getCurrentUser();
|
|
3960
|
+
var userDidNotChange = (currentUser === null || currentUser === void 0 ? void 0 : currentUser.getMPID()) === previousMpid;
|
|
3961
|
+
return userDidNotChange ? null : mpInstance.Identity.getUser(previousMpid);
|
|
3929
3962
|
}
|
|
3930
3963
|
}
|
|
3931
3964
|
});
|
|
@@ -4223,57 +4256,65 @@ var mParticle = (function () {
|
|
|
4223
4256
|
}
|
|
4224
4257
|
pixelConfigurations.forEach(function (pixelSettings) {
|
|
4225
4258
|
var _a, _b, _c;
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4259
|
+
try {
|
|
4260
|
+
// set requiresConsent to false to start each additional pixel configuration
|
|
4261
|
+
// set to true only if filteringConsenRuleValues.values.length exists
|
|
4262
|
+
var requiresConsent = false;
|
|
4263
|
+
// Filtering rules as defined in UI
|
|
4264
|
+
var filteringConsentRuleValues = pixelSettings.filteringConsentRuleValues,
|
|
4265
|
+
pixelUrl = pixelSettings.pixelUrl,
|
|
4266
|
+
redirectUrl = pixelSettings.redirectUrl,
|
|
4267
|
+
moduleId = pixelSettings.moduleId,
|
|
4268
|
+
settings = pixelSettings.settings,
|
|
4269
|
+
// Tells you how often we should do a cookie sync (in days)
|
|
4270
|
+
frequencyCap = pixelSettings.frequencyCap;
|
|
4271
|
+
var values = (filteringConsentRuleValues || {}).values;
|
|
4272
|
+
if (isEmpty(pixelUrl)) {
|
|
4273
|
+
return;
|
|
4274
|
+
}
|
|
4275
|
+
if (!isEmpty(values)) {
|
|
4276
|
+
requiresConsent = true;
|
|
4277
|
+
}
|
|
4278
|
+
// If MPID is new to cookies, we should not try to perform the cookie sync
|
|
4279
|
+
// because a cookie sync can only occur once a user either consents or doesn't.
|
|
4280
|
+
// we should not check if it's enabled if the user has a blank consent
|
|
4281
|
+
if (requiresConsent && mpidIsNotInCookies) {
|
|
4282
|
+
return;
|
|
4283
|
+
}
|
|
4284
|
+
// For Rokt, block cookie sync when noTargeting privacy flag is true
|
|
4285
|
+
if (moduleId === PARTNER_MODULE_IDS.Rokt && mpInstance._CookieConsentManager.getNoTargeting()) {
|
|
4286
|
+
return;
|
|
4287
|
+
}
|
|
4288
|
+
var isEnabledForUserConsent = mpInstance._Consent.isEnabledForUserConsent;
|
|
4289
|
+
if (!isEnabledForUserConsent(filteringConsentRuleValues, mpInstance.Identity.getCurrentUser())) {
|
|
4290
|
+
return;
|
|
4291
|
+
}
|
|
4292
|
+
var cookieSyncDates = (_b = (_a = persistence[mpid]) === null || _a === void 0 ? void 0 : _a.csd) !== null && _b !== void 0 ? _b : {};
|
|
4293
|
+
var lastSyncDateForModule = cookieSyncDates[moduleId] || null;
|
|
4294
|
+
if (!isLastSyncDateExpired(frequencyCap, lastSyncDateForModule)) {
|
|
4295
|
+
return;
|
|
4296
|
+
}
|
|
4297
|
+
// The Trade Desk requires a URL parameter for GDPR enabled users.
|
|
4298
|
+
// It is optional but to simplify the code, we add it for all Trade
|
|
4299
|
+
// // Desk cookie syncs.
|
|
4300
|
+
var domain = moduleId === PARTNER_MODULE_IDS.TradeDesk ? window.location.hostname : undefined;
|
|
4301
|
+
// Google Marketing Platform accepts a web-safe base64-encoded MPID via the
|
|
4302
|
+
// `google_hm` query parameter, but only for accounts provisioned for Google
|
|
4303
|
+
// Hosted Matching — Google returns errors otherwise. It is therefore gated
|
|
4304
|
+
// behind the opt-in `enableHmTag` setting (off by default), which the server
|
|
4305
|
+
// delivers as the string 'True' when the UI toggle is enabled.
|
|
4306
|
+
var enableHmTag = ((_c = settings === null || settings === void 0 ? void 0 : settings.enableHmTag) === null || _c === void 0 ? void 0 : _c.toLowerCase()) === 'true';
|
|
4307
|
+
var isDoubleClickModule = moduleId === PARTNER_MODULE_IDS.DoubleclickDFP;
|
|
4308
|
+
var usesHostedMatching = isDoubleClickModule && enableHmTag;
|
|
4309
|
+
var base64Mpid = usesHostedMatching ? toWebSafeBase64(mpid) : undefined;
|
|
4310
|
+
if (usesHostedMatching && !base64Mpid) {
|
|
4311
|
+
mpInstance.Logger.warning('Unable to base64 encode the current MPID; omitting the google_hm parameter from this cookie sync');
|
|
4312
|
+
}
|
|
4313
|
+
var fullUrl = createCookieSyncUrl(mpid, pixelUrl, redirectUrl, domain, base64Mpid);
|
|
4314
|
+
self.performCookieSync(fullUrl, moduleId.toString(), mpid, cookieSyncDates);
|
|
4315
|
+
} catch (e) {
|
|
4316
|
+
mpInstance.Logger.error('Error performing cookie sync: ' + e);
|
|
4262
4317
|
}
|
|
4263
|
-
// The Trade Desk requires a URL parameter for GDPR enabled users.
|
|
4264
|
-
// It is optional but to simplify the code, we add it for all Trade
|
|
4265
|
-
// // Desk cookie syncs.
|
|
4266
|
-
var domain = moduleId === PARTNER_MODULE_IDS.TradeDesk ? window.location.hostname : undefined;
|
|
4267
|
-
// Google Marketing Platform accepts a web-safe base64-encoded MPID via the
|
|
4268
|
-
// `google_hm` query parameter, but only for accounts provisioned for Google
|
|
4269
|
-
// Hosted Matching — Google returns errors otherwise. It is therefore gated
|
|
4270
|
-
// behind the opt-in `enableHmTag` setting (off by default), which the server
|
|
4271
|
-
// delivers as the string 'True' when the UI toggle is enabled.
|
|
4272
|
-
var enableHmTag = ((_c = settings === null || settings === void 0 ? void 0 : settings.enableHmTag) === null || _c === void 0 ? void 0 : _c.toLowerCase()) === 'true';
|
|
4273
|
-
var isDoubleClickModule = moduleId === PARTNER_MODULE_IDS.DoubleclickDFP;
|
|
4274
|
-
var base64Mpid = isDoubleClickModule && enableHmTag ? toWebSafeBase64(mpid) : undefined;
|
|
4275
|
-
var fullUrl = createCookieSyncUrl(mpid, pixelUrl, redirectUrl, domain, base64Mpid);
|
|
4276
|
-
self.performCookieSync(fullUrl, moduleId.toString(), mpid, cookieSyncDates);
|
|
4277
4318
|
});
|
|
4278
4319
|
};
|
|
4279
4320
|
// Private
|
|
@@ -5259,7 +5300,7 @@ var mParticle = (function () {
|
|
|
5259
5300
|
}
|
|
5260
5301
|
_this.syncPersistenceData();
|
|
5261
5302
|
if (_this.persistenceData) {
|
|
5262
|
-
if (_this.persistenceData[mpid]) {
|
|
5303
|
+
if (isObject(_this.persistenceData[mpid])) {
|
|
5263
5304
|
_this.persistenceData[mpid][key] = value;
|
|
5264
5305
|
} else {
|
|
5265
5306
|
_this.persistenceData[mpid] = (_a = {}, _a[key] = value, _a);
|
|
@@ -6237,7 +6278,7 @@ var mParticle = (function () {
|
|
|
6237
6278
|
if (csd) {
|
|
6238
6279
|
var persistence = self.getPersistence();
|
|
6239
6280
|
if (persistence) {
|
|
6240
|
-
if (persistence[mpid]) {
|
|
6281
|
+
if (mpInstance._Helpers.isObject(persistence[mpid])) {
|
|
6241
6282
|
persistence[mpid].csd = csd;
|
|
6242
6283
|
} else {
|
|
6243
6284
|
persistence[mpid] = {
|
|
@@ -6318,7 +6359,7 @@ var mParticle = (function () {
|
|
|
6318
6359
|
}
|
|
6319
6360
|
var persistence = self.getPersistence();
|
|
6320
6361
|
if (persistence) {
|
|
6321
|
-
if (!persistence[mpid]) {
|
|
6362
|
+
if (!mpInstance._Helpers.isObject(persistence[mpid])) {
|
|
6322
6363
|
persistence[mpid] = {};
|
|
6323
6364
|
}
|
|
6324
6365
|
if (!persistence[mpid].fst) {
|
|
@@ -6356,7 +6397,7 @@ var mParticle = (function () {
|
|
|
6356
6397
|
time = new Date().getTime();
|
|
6357
6398
|
}
|
|
6358
6399
|
var persistence = self.getPersistence();
|
|
6359
|
-
if (persistence && persistence[mpid]) {
|
|
6400
|
+
if (persistence && mpInstance._Helpers.isObject(persistence[mpid])) {
|
|
6360
6401
|
persistence[mpid].lst = time;
|
|
6361
6402
|
self.savePersistence(persistence);
|
|
6362
6403
|
}
|
|
@@ -6445,6 +6486,14 @@ var mParticle = (function () {
|
|
|
6445
6486
|
var allowedQueryParams = function allowedQueryParams(href) {
|
|
6446
6487
|
return queryStringParser(href, ALLOWED_QUERY_PARAMS);
|
|
6447
6488
|
};
|
|
6489
|
+
var AUTO_PAGE_VIEW_ATTRIBUTE = 'is_auto_page_view';
|
|
6490
|
+
// Absent rather than false on a manual page view, so the attribute is only ever
|
|
6491
|
+
// added by the automatic emitters. Shared by both of them so the key and that
|
|
6492
|
+
// rule have one definition instead of two that can drift.
|
|
6493
|
+
var autoPageViewAttribute = function autoPageViewAttribute(isAutoPageView) {
|
|
6494
|
+
var _a;
|
|
6495
|
+
return isAutoPageView ? (_a = {}, _a[AUTO_PAGE_VIEW_ATTRIBUTE] = true, _a) : {};
|
|
6496
|
+
};
|
|
6448
6497
|
// The captured params, in allowlist order. Ordering comes from the constant
|
|
6449
6498
|
// rather than a sort: it is deterministic without needing a comparator, and it
|
|
6450
6499
|
// does not depend on the object's insertion order, so reordering the query string
|
|
@@ -6492,18 +6541,19 @@ var mParticle = (function () {
|
|
|
6492
6541
|
var params = _a.params,
|
|
6493
6542
|
hostname = _a.hostname,
|
|
6494
6543
|
title = _a.title,
|
|
6495
|
-
path = _a.path
|
|
6544
|
+
path = _a.path,
|
|
6545
|
+
isAutoPageView = _a.isAutoPageView;
|
|
6496
6546
|
return {
|
|
6497
6547
|
messageType: MessageType$1.PageView,
|
|
6498
6548
|
name: 'PageView',
|
|
6499
6549
|
// Params spread first, then the core fields by name, so a core field always
|
|
6500
6550
|
// wins. No allowlist entry collides with hostname/title/path today; naming
|
|
6501
6551
|
// them here is what keeps a later addition from silently overwriting one.
|
|
6502
|
-
data: __assign(__assign({}, params), {
|
|
6552
|
+
data: __assign(__assign(__assign({}, params), {
|
|
6503
6553
|
hostname: hostname,
|
|
6504
6554
|
title: title,
|
|
6505
6555
|
path: path
|
|
6506
|
-
}),
|
|
6556
|
+
}), autoPageViewAttribute(isAutoPageView)),
|
|
6507
6557
|
eventType: EventType.Unknown
|
|
6508
6558
|
};
|
|
6509
6559
|
};
|
|
@@ -6663,13 +6713,14 @@ var mParticle = (function () {
|
|
|
6663
6713
|
// Tracker
|
|
6664
6714
|
// ---------------------------------------------------------------------------
|
|
6665
6715
|
var PageViewTracker = /** @class */function () {
|
|
6666
|
-
function PageViewTracker(mpInstance) {
|
|
6716
|
+
function PageViewTracker(mpInstance, options) {
|
|
6667
6717
|
this.lastPage = null;
|
|
6668
6718
|
this.active = false;
|
|
6669
6719
|
this.pendingNavigations = [];
|
|
6670
6720
|
this.undoHistoryPatch = null;
|
|
6671
6721
|
this.popStateListener = null;
|
|
6672
6722
|
this.mpInstance = mpInstance;
|
|
6723
|
+
this.isAutoPageView = !!(options && options.isAutoPageView);
|
|
6673
6724
|
}
|
|
6674
6725
|
Object.defineProperty(PageViewTracker.prototype, "isActive", {
|
|
6675
6726
|
// True while this tracker owns the history patch and is listening for
|
|
@@ -6812,7 +6863,8 @@ var mParticle = (function () {
|
|
|
6812
6863
|
var title = window.document.title;
|
|
6813
6864
|
var event = buildPageViewEvent(__assign(__assign({}, page), {
|
|
6814
6865
|
hostname: window.location.hostname,
|
|
6815
|
-
title: title
|
|
6866
|
+
title: title,
|
|
6867
|
+
isAutoPageView: this.isAutoPageView
|
|
6816
6868
|
}));
|
|
6817
6869
|
this.log("[fire] deferred flush -> _Events.logEvent(PageView) (page: ".concat(describePage(page), ", title: ").concat(title, ")"));
|
|
6818
6870
|
this.mpInstance._Events.logEvent(event);
|
|
@@ -6904,14 +6956,14 @@ var mParticle = (function () {
|
|
|
6904
6956
|
// come from PageViewTracker instead, so both emitters attach the same
|
|
6905
6957
|
// allowlisted query params — and this is the one that matters for campaign
|
|
6906
6958
|
// attribution, since utm_*/gclid live on the entry URL.
|
|
6907
|
-
this.logPageView = function () {
|
|
6959
|
+
this.logPageView = function (options) {
|
|
6908
6960
|
self.logEvent({
|
|
6909
6961
|
messageType: Types.MessageType.PageView,
|
|
6910
6962
|
name: 'PageView',
|
|
6911
|
-
data: __assign(__assign({}, allowedQueryParams(getHref())), {
|
|
6963
|
+
data: __assign(__assign(__assign({}, allowedQueryParams(getHref())), {
|
|
6912
6964
|
hostname: window.location.hostname,
|
|
6913
6965
|
title: window.document.title
|
|
6914
|
-
}),
|
|
6966
|
+
}), autoPageViewAttribute(options && options.isAutoPageView)),
|
|
6915
6967
|
eventType: Types.EventType.Unknown
|
|
6916
6968
|
});
|
|
6917
6969
|
};
|
|
@@ -7095,7 +7147,7 @@ var mParticle = (function () {
|
|
|
7095
7147
|
return userAttributesCopy;
|
|
7096
7148
|
}
|
|
7097
7149
|
for (var prop in userAttributes) {
|
|
7098
|
-
if (!userAttributes
|
|
7150
|
+
if (!hasOwnProp(userAttributes, prop) || isReservedStoredPropertyName(prop) || !isAttributeKeyAllowed(kitBlocker, prop)) {
|
|
7099
7151
|
continue;
|
|
7100
7152
|
}
|
|
7101
7153
|
userAttributesCopy[prop] = copyUserAttributeValue(userAttributes[prop]);
|
|
@@ -7105,21 +7157,27 @@ var mParticle = (function () {
|
|
|
7105
7157
|
function buildUserAttributeLists(userAttributes, kitBlocker) {
|
|
7106
7158
|
var userAttributesLists = {};
|
|
7107
7159
|
for (var key in userAttributes) {
|
|
7108
|
-
if (!userAttributes
|
|
7160
|
+
if (!hasOwnProp(userAttributes, key) || isReservedStoredPropertyName(key) || !Array.isArray(userAttributes[key]) || !isAttributeKeyAllowed(kitBlocker, key)) {
|
|
7109
7161
|
continue;
|
|
7110
7162
|
}
|
|
7111
7163
|
userAttributesLists[key] = userAttributes[key].slice();
|
|
7112
7164
|
}
|
|
7113
7165
|
return userAttributesLists;
|
|
7114
7166
|
}
|
|
7115
|
-
function buildFilteredUserIdentities(identities, kitBlocker
|
|
7167
|
+
function buildFilteredUserIdentities(identities, kitBlocker) {
|
|
7116
7168
|
var currentUserIdentities = {};
|
|
7117
7169
|
var identitiesByType = identities;
|
|
7118
7170
|
for (var identityType in identitiesByType) {
|
|
7119
|
-
if (!identitiesByType
|
|
7171
|
+
if (!hasOwnProp(identitiesByType, identityType)) {
|
|
7172
|
+
continue;
|
|
7173
|
+
}
|
|
7174
|
+
var storedIdentityType = getIdentityTypeFromStoredKey(identityType);
|
|
7175
|
+
// Must be `=== null`: IdentityType.Other is 0, so a falsy check would
|
|
7176
|
+
// drop a valid stored Other identity.
|
|
7177
|
+
if (storedIdentityType === null) {
|
|
7120
7178
|
continue;
|
|
7121
7179
|
}
|
|
7122
|
-
var identityName = Types.IdentityType.getIdentityName(
|
|
7180
|
+
var identityName = Types.IdentityType.getIdentityName(storedIdentityType);
|
|
7123
7181
|
if (!isIdentityAllowed(kitBlocker, identityName)) {
|
|
7124
7182
|
continue;
|
|
7125
7183
|
}
|
|
@@ -7134,7 +7192,7 @@ var mParticle = (function () {
|
|
|
7134
7192
|
}
|
|
7135
7193
|
return {
|
|
7136
7194
|
getUserIdentities: function getUserIdentities() {
|
|
7137
|
-
var currentUserIdentities = buildFilteredUserIdentities(mpInstance._Store.getUserIdentities(mpid), kitBlocker
|
|
7195
|
+
var currentUserIdentities = buildFilteredUserIdentities(mpInstance._Store.getUserIdentities(mpid), kitBlocker);
|
|
7138
7196
|
currentUserIdentities = mpInstance._Helpers.filterUserIdentitiesForForwarders(currentUserIdentities, forwarder.userIdentityFilters);
|
|
7139
7197
|
return {
|
|
7140
7198
|
userIdentities: currentUserIdentities
|
|
@@ -7245,7 +7303,7 @@ var mParticle = (function () {
|
|
|
7245
7303
|
}
|
|
7246
7304
|
function userAttributesMatchFilter(userAttributes, filterObject) {
|
|
7247
7305
|
for (var attrName in userAttributes) {
|
|
7248
|
-
if (!userAttributes
|
|
7306
|
+
if (!hasOwnProp(userAttributes, attrName)) {
|
|
7249
7307
|
continue;
|
|
7250
7308
|
}
|
|
7251
7309
|
var attrHash = KitFilterHelper.hashAttributeConditionalForwarding(attrName);
|
|
@@ -8596,9 +8654,16 @@ var mParticle = (function () {
|
|
|
8596
8654
|
var currentUserIdentities = {};
|
|
8597
8655
|
var identities = mpInstance._Store.getUserIdentities(mpid);
|
|
8598
8656
|
for (var identityType in identities) {
|
|
8599
|
-
if (identities
|
|
8600
|
-
|
|
8657
|
+
if (!hasOwnProp(identities, identityType)) {
|
|
8658
|
+
continue;
|
|
8601
8659
|
}
|
|
8660
|
+
var storedIdentityType = getIdentityTypeFromStoredKey(identityType);
|
|
8661
|
+
// Must be `=== null`: IdentityType.Other is 0, so a falsy
|
|
8662
|
+
// check would drop a valid stored Other identity.
|
|
8663
|
+
if (storedIdentityType === null) {
|
|
8664
|
+
continue;
|
|
8665
|
+
}
|
|
8666
|
+
currentUserIdentities[Types.IdentityType.getIdentityName(storedIdentityType)] = identities[identityType];
|
|
8602
8667
|
}
|
|
8603
8668
|
return {
|
|
8604
8669
|
userIdentities: currentUserIdentities
|
|
@@ -8727,7 +8792,7 @@ var mParticle = (function () {
|
|
|
8727
8792
|
}
|
|
8728
8793
|
var deletedUAKeyCopy = userAttributes[key] ? userAttributes[key].toString() : null;
|
|
8729
8794
|
delete userAttributes[key];
|
|
8730
|
-
if (cookies && cookies[mpid]) {
|
|
8795
|
+
if (cookies && isObject(cookies[mpid])) {
|
|
8731
8796
|
cookies[mpid].ua = userAttributes;
|
|
8732
8797
|
mpInstance._Persistence.savePersistence(cookies);
|
|
8733
8798
|
}
|
|
@@ -8810,7 +8875,7 @@ var mParticle = (function () {
|
|
|
8810
8875
|
mpInstance._Forwarders.initForwarders(self.IdentityAPI.getCurrentUser().getUserIdentities().userIdentities, mpInstance._APIClient.prepareForwardingStats);
|
|
8811
8876
|
if (userAttributes) {
|
|
8812
8877
|
for (var prop in userAttributes) {
|
|
8813
|
-
if (userAttributes
|
|
8878
|
+
if (hasOwnProp(userAttributes, prop)) {
|
|
8814
8879
|
mpInstance._Forwarders.handleForwarderUserAttributes('removeUserAttribute', prop, null);
|
|
8815
8880
|
}
|
|
8816
8881
|
this.removeUserAttribute(prop);
|
|
@@ -8828,7 +8893,7 @@ var mParticle = (function () {
|
|
|
8828
8893
|
var userAttributesLists = {};
|
|
8829
8894
|
userAttributes = this.getAllUserAttributes();
|
|
8830
8895
|
for (var key in userAttributes) {
|
|
8831
|
-
if (userAttributes
|
|
8896
|
+
if (hasOwnProp(userAttributes, key) && !isReservedStoredPropertyName(key) && Array.isArray(userAttributes[key])) {
|
|
8832
8897
|
userAttributesLists[key] = userAttributes[key].slice();
|
|
8833
8898
|
}
|
|
8834
8899
|
}
|
|
@@ -8845,7 +8910,7 @@ var mParticle = (function () {
|
|
|
8845
8910
|
var userAttributes = getUserAttributes(mpid);
|
|
8846
8911
|
if (userAttributes) {
|
|
8847
8912
|
for (var prop in userAttributes) {
|
|
8848
|
-
if (userAttributes
|
|
8913
|
+
if (hasOwnProp(userAttributes, prop) && !isReservedStoredPropertyName(prop)) {
|
|
8849
8914
|
var attrValue = userAttributes[prop];
|
|
8850
8915
|
if (Array.isArray(attrValue)) {
|
|
8851
8916
|
userAttributesCopy[prop] = attrValue.slice();
|
|
@@ -8984,7 +9049,7 @@ var mParticle = (function () {
|
|
|
8984
9049
|
}
|
|
8985
9050
|
if (callback) {
|
|
8986
9051
|
var callbackCode = identityResponse.status === 0 ? HTTPCodes$2.noHttpCoverage : identityResponse.status;
|
|
8987
|
-
mpInstance._Helpers.invokeCallback(callback, callbackCode, identityApiResult || null, newUser);
|
|
9052
|
+
mpInstance._Helpers.invokeCallback(callback, callbackCode, identityApiResult || null, newUser, previousMPID);
|
|
8988
9053
|
} else if (identityApiResult && !isEmpty(identityApiResult.errors)) {
|
|
8989
9054
|
// https://go.mparticle.com/work/SQDSDKS-6500
|
|
8990
9055
|
mpInstance.Logger.error('Received HTTP response code of ' + identityResponse.status + ' - ' + identityApiResult.errors[0].message);
|
|
@@ -9236,14 +9301,14 @@ var mParticle = (function () {
|
|
|
9236
9301
|
var state = self.createConsentState();
|
|
9237
9302
|
if (json.gdpr) {
|
|
9238
9303
|
for (var purpose in json.gdpr) {
|
|
9239
|
-
if (json.gdpr
|
|
9304
|
+
if (hasOwnProp(json.gdpr, purpose)) {
|
|
9240
9305
|
var gdprConsent = self.createPrivacyConsent(json.gdpr[purpose].c, json.gdpr[purpose].ts, json.gdpr[purpose].d, json.gdpr[purpose].l, json.gdpr[purpose].h);
|
|
9241
9306
|
state.addGDPRConsentState(purpose, gdprConsent);
|
|
9242
9307
|
}
|
|
9243
9308
|
}
|
|
9244
9309
|
}
|
|
9245
9310
|
if (json.ccpa) {
|
|
9246
|
-
if (json.ccpa
|
|
9311
|
+
if (hasOwnProp(json.ccpa, CCPAPurpose)) {
|
|
9247
9312
|
var ccpaConsent = self.createPrivacyConsent(json.ccpa[CCPAPurpose].c, json.ccpa[CCPAPurpose].ts, json.ccpa[CCPAPurpose].d, json.ccpa[CCPAPurpose].l, json.ccpa[CCPAPurpose].h);
|
|
9248
9313
|
state.setCCPAConsentState(ccpaConsent);
|
|
9249
9314
|
}
|
|
@@ -10268,6 +10333,17 @@ var mParticle = (function () {
|
|
|
10268
10333
|
mappedKey: 'SnapchatConversions.ClickId',
|
|
10269
10334
|
output: IntegrationOutputs.CUSTOM_FLAGS
|
|
10270
10335
|
},
|
|
10336
|
+
// Pinterest
|
|
10337
|
+
// https://developers.pinterest.com/docs/track-conversions/track-conversions-in-the-api/
|
|
10338
|
+
// https://help.pinterest.com/en/business/article/pinterest-tag-parameters-and-cookies
|
|
10339
|
+
epik: {
|
|
10340
|
+
mappedKey: 'Pinterest.click_id',
|
|
10341
|
+
output: IntegrationOutputs.CUSTOM_FLAGS
|
|
10342
|
+
},
|
|
10343
|
+
_epik: {
|
|
10344
|
+
mappedKey: 'Pinterest.click_id',
|
|
10345
|
+
output: IntegrationOutputs.CUSTOM_FLAGS
|
|
10346
|
+
},
|
|
10271
10347
|
// Snapchat
|
|
10272
10348
|
// https://developers.snap.com/api/marketing-api/Conversions-API/UsingTheAPI#sending-click-id
|
|
10273
10349
|
_scid: {
|
|
@@ -10311,6 +10387,7 @@ var mParticle = (function () {
|
|
|
10311
10387
|
var queryParams = this.captureQueryParams() || {};
|
|
10312
10388
|
var cookies = this.captureCookies() || {};
|
|
10313
10389
|
var localStorage = this.captureLocalStorage() || {};
|
|
10390
|
+
this.applyPinterestRules(queryParams, localStorage, cookies);
|
|
10314
10391
|
// Facebook Rules
|
|
10315
10392
|
// Exclude _fbc if fbclid is present
|
|
10316
10393
|
// https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/fbp-and-fbc#retrieve-from-fbclid-url-query-parameter
|
|
@@ -10438,6 +10515,39 @@ var mParticle = (function () {
|
|
|
10438
10515
|
}
|
|
10439
10516
|
return mappedClickIds;
|
|
10440
10517
|
};
|
|
10518
|
+
IntegrationCapture.prototype.normalizePinterestClickId = function (clickIds) {
|
|
10519
|
+
// Deterministic tie-breaker when both aliases are present in the same source:
|
|
10520
|
+
// keep _epik and drop epik.
|
|
10521
|
+
if (!isEmpty(clickIds === null || clickIds === void 0 ? void 0 : clickIds['_epik']) && !isEmpty(clickIds === null || clickIds === void 0 ? void 0 : clickIds['epik'])) {
|
|
10522
|
+
delete clickIds['epik'];
|
|
10523
|
+
}
|
|
10524
|
+
};
|
|
10525
|
+
IntegrationCapture.prototype.hasPinterestAlias = function (clickIds) {
|
|
10526
|
+
return !isEmpty(clickIds === null || clickIds === void 0 ? void 0 : clickIds['epik']) || !isEmpty(clickIds === null || clickIds === void 0 ? void 0 : clickIds['_epik']);
|
|
10527
|
+
};
|
|
10528
|
+
IntegrationCapture.prototype.applyPinterestRules = function (queryParams, localStorage, cookies) {
|
|
10529
|
+
var _a, _b;
|
|
10530
|
+
this.normalizePinterestClickId(queryParams);
|
|
10531
|
+
this.normalizePinterestClickId(localStorage);
|
|
10532
|
+
this.normalizePinterestClickId(cookies);
|
|
10533
|
+
// Cross-source precedence: query params > localStorage > cookies.
|
|
10534
|
+
// Within the same source, prefer _epik when both aliases are present.
|
|
10535
|
+
if (this.hasPinterestAlias(queryParams) || this.hasPinterestAlias(localStorage) || this.hasPinterestAlias(cookies)) {
|
|
10536
|
+
(_a = this.clickIds) === null || _a === void 0 ? true : delete _a['epik'];
|
|
10537
|
+
(_b = this.clickIds) === null || _b === void 0 ? true : delete _b['_epik'];
|
|
10538
|
+
}
|
|
10539
|
+
if (this.hasPinterestAlias(queryParams)) {
|
|
10540
|
+
delete cookies['epik'];
|
|
10541
|
+
delete cookies['_epik'];
|
|
10542
|
+
delete localStorage['epik'];
|
|
10543
|
+
delete localStorage['_epik'];
|
|
10544
|
+
return;
|
|
10545
|
+
}
|
|
10546
|
+
if (this.hasPinterestAlias(localStorage)) {
|
|
10547
|
+
delete cookies['epik'];
|
|
10548
|
+
delete cookies['_epik'];
|
|
10549
|
+
}
|
|
10550
|
+
};
|
|
10441
10551
|
IntegrationCapture.prototype.applyProcessors = function (clickIds, url, timestamp) {
|
|
10442
10552
|
var _a;
|
|
10443
10553
|
var processedClickIds = {};
|
|
@@ -11134,7 +11244,7 @@ var mParticle = (function () {
|
|
|
11134
11244
|
if (!user) return;
|
|
11135
11245
|
if (this.flags.noTargeting) {
|
|
11136
11246
|
user.setUserAttribute(NO_TARGETING_ATTRIBUTE, true);
|
|
11137
|
-
} else if (user.getAllUserAttributes()
|
|
11247
|
+
} else if (hasOwnProp(user.getAllUserAttributes(), NO_TARGETING_ATTRIBUTE)) {
|
|
11138
11248
|
user.removeUserAttribute(NO_TARGETING_ATTRIBUTE);
|
|
11139
11249
|
}
|
|
11140
11250
|
};
|
|
@@ -12175,7 +12285,9 @@ var mParticle = (function () {
|
|
|
12175
12285
|
if (getFeatureFlag(AutoLogPageView)) {
|
|
12176
12286
|
if (!mpInstance._PageViewTracker) {
|
|
12177
12287
|
mpInstance.Logger.verbose('mParticle APV: [sdk-init] creating new PageViewTracker for this instance');
|
|
12178
|
-
mpInstance._PageViewTracker = new PageViewTracker(mpInstance
|
|
12288
|
+
mpInstance._PageViewTracker = new PageViewTracker(mpInstance, {
|
|
12289
|
+
isAutoPageView: true
|
|
12290
|
+
});
|
|
12179
12291
|
}
|
|
12180
12292
|
// The initial page view fires once per hard page load, not once per
|
|
12181
12293
|
// init(): the window flag survives the module re-evaluation Next.js
|
|
@@ -12185,7 +12297,9 @@ var mParticle = (function () {
|
|
|
12185
12297
|
mpInstance.Logger.verbose('mParticle APV: [sdk-init] initial page view already logged this page load, skipping');
|
|
12186
12298
|
} else {
|
|
12187
12299
|
markInitialPageViewFired();
|
|
12188
|
-
mpInstance._Events.logPageView(
|
|
12300
|
+
mpInstance._Events.logPageView({
|
|
12301
|
+
isAutoPageView: true
|
|
12302
|
+
});
|
|
12189
12303
|
}
|
|
12190
12304
|
mpInstance._PageViewTracker.init();
|
|
12191
12305
|
} else if (mpInstance._PageViewTracker) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Callback, SDKEventAttrs, SDKEventOptions, TransactionAttributes } from '@mparticle/web-sdk';
|
|
2
2
|
import { BaseEvent, SDKEvent, SDKEventCustomFlags, SDKImpression, SDKProduct, SDKPromotion } from './sdkRuntimeModels';
|
|
3
|
+
import { IPageViewOptions } from './pageViewTracker';
|
|
3
4
|
import { valueof } from './utils';
|
|
4
5
|
import { EventType, ProductActionType, PromotionActionType } from './types';
|
|
5
6
|
type EventHandlerFunction<T> = (element: HTMLLinkElement | HTMLFormElement) => T;
|
|
@@ -10,7 +11,7 @@ export interface IEvents {
|
|
|
10
11
|
logEvent(event: BaseEvent, eventOptions?: SDKEventOptions): void;
|
|
11
12
|
logImpressionEvent(impression: SDKImpression | SDKImpression[], attrs?: SDKEventAttrs, customFlags?: SDKEventCustomFlags, eventOptions?: SDKEventOptions): void;
|
|
12
13
|
logOptOut(): void;
|
|
13
|
-
logPageView(): void;
|
|
14
|
+
logPageView(options?: IPageViewOptions): void;
|
|
14
15
|
logProductActionEvent(productActionType: valueof<typeof ProductActionType>, product: SDKProduct | SDKProduct[], attrs?: SDKEventAttrs, customFlags?: SDKEventCustomFlags, transactionAttributes?: TransactionAttributes, eventOptions?: SDKEventOptions): void;
|
|
15
16
|
logPromotionEvent(promotionType: valueof<typeof PromotionActionType>, promotion: SDKPromotion | SDKPromotion[], attrs?: SDKEventAttrs, customFlags?: SDKEventCustomFlags, eventOptions?: SDKEventOptions): void;
|
|
16
17
|
logPurchaseEvent(transactionAttributes: TransactionAttributes, product: SDKProduct | SDKProduct[], attrs?: SDKEventAttrs, customFlags?: SDKEventCustomFlags): void;
|
|
@@ -65,6 +65,9 @@ export default class IntegrationCapture {
|
|
|
65
65
|
*/
|
|
66
66
|
getClickIdsAsIntegrationAttributes(): IntegrationAttributes;
|
|
67
67
|
private getClickIds;
|
|
68
|
+
private normalizePinterestClickId;
|
|
69
|
+
private hasPinterestAlias;
|
|
70
|
+
private applyPinterestRules;
|
|
68
71
|
private applyProcessors;
|
|
69
72
|
private filterMappings;
|
|
70
73
|
/**
|
|
@@ -12,12 +12,18 @@ interface IPageSnapshot {
|
|
|
12
12
|
interface IPageViewData extends IPageSnapshot {
|
|
13
13
|
hostname: string;
|
|
14
14
|
title: string;
|
|
15
|
+
isAutoPageView?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface IPageViewOptions {
|
|
18
|
+
isAutoPageView?: boolean;
|
|
15
19
|
}
|
|
16
20
|
export declare const allowedQueryParams: (href: string) => Dictionary<string>;
|
|
21
|
+
export declare const AUTO_PAGE_VIEW_ATTRIBUTE = "is_auto_page_view";
|
|
22
|
+
export declare const autoPageViewAttribute: (isAutoPageView?: boolean) => Dictionary<boolean>;
|
|
17
23
|
export declare const pageKey: (page: IPageSnapshot) => string;
|
|
18
24
|
export declare const isNewPage: (lastKey: string | null, candidateKey: string) => boolean;
|
|
19
25
|
export declare const supportsHistoryTracking: (win: Window | null) => boolean;
|
|
20
|
-
export declare const buildPageViewEvent: ({ params, hostname, title, path, }: IPageViewData) => BaseEvent;
|
|
26
|
+
export declare const buildPageViewEvent: ({ params, hostname, title, path, isAutoPageView, }: IPageViewData) => BaseEvent;
|
|
21
27
|
export declare const getActiveTracker: () => PageViewTracker | undefined;
|
|
22
28
|
export declare const hasInitialPageViewFired: () => boolean;
|
|
23
29
|
export declare const markInitialPageViewFired: () => void;
|
|
@@ -30,7 +36,8 @@ export declare class PageViewTracker {
|
|
|
30
36
|
private pendingNavigations;
|
|
31
37
|
private undoHistoryPatch;
|
|
32
38
|
private popStateListener;
|
|
33
|
-
|
|
39
|
+
private readonly isAutoPageView;
|
|
40
|
+
constructor(mpInstance: IMParticleWebSDKInstance, options?: IPageViewOptions);
|
|
34
41
|
get isActive(): boolean;
|
|
35
42
|
init(): void;
|
|
36
43
|
teardown(): void;
|
|
@@ -99,6 +99,7 @@ export declare const PerformanceMarkType: {
|
|
|
99
99
|
};
|
|
100
100
|
export declare function getMessageTypeFromEventType(eventType: string): number;
|
|
101
101
|
export declare function getEventCategoryFromCustomEventType(customEventType: string): number;
|
|
102
|
+
export declare function getIdentityTypeFromStoredKey(key: string): number | null;
|
|
102
103
|
export declare function getIdentityTypeFromBatchKey(key: string): number;
|
|
103
104
|
declare const _default: {
|
|
104
105
|
readonly MessageType: {
|