@kameleoon/javascript-sdk-core 5.16.1 → 5.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -1
- package/dist/clientConfiguration/clientConfiguration.d.ts +4 -1
- package/dist/clientConfiguration/constants.d.ts +2 -3
- package/dist/clientConfiguration/types.d.ts +5 -0
- package/dist/javascript-sdk-core-browser.cjs.js +208 -101
- package/dist/javascript-sdk-core-browser.cjs.js.map +1 -1
- package/dist/javascript-sdk-core-browser.es.js +208 -101
- package/dist/javascript-sdk-core-browser.es.js.map +1 -1
- package/dist/javascript-sdk-core.cjs.js +208 -101
- package/dist/javascript-sdk-core.cjs.js.map +1 -1
- package/dist/javascript-sdk-core.es.js +208 -101
- package/dist/javascript-sdk-core.es.js.map +1 -1
- package/dist/kameleoonClient.d.ts +2 -0
- package/dist/kameleoonData/conversion.d.ts +10 -0
- package/dist/kameleoonData/customData.d.ts +5 -0
- package/dist/kameleoonData/dataManager.d.ts +2 -2
- package/dist/kameleoonData/dataProcessor.d.ts +2 -2
- package/dist/kameleoonData/types.d.ts +5 -3
- package/dist/kameleoonData/visitProcessor.d.ts +8 -8
- package/dist/kameleoonData/visitsData.d.ts +3 -2
- package/dist/requester/constants.d.ts +1 -1
- package/dist/requester/types.d.ts +2 -2
- package/dist/requester/urlProvider.d.ts +1 -0
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/types.d.ts +13 -5
- package/dist/variationConfiguration/types.d.ts +2 -0
- package/dist/variationConfiguration/variationConfiguration.d.ts +1 -1
- package/package.json +1 -1
|
@@ -220,10 +220,17 @@ class KameleoonError extends Error {
|
|
|
220
220
|
this.message = ERROR_MESSAGES[type](secondParam, thirdParam);
|
|
221
221
|
break;
|
|
222
222
|
case exports.KameleoonException.FeatureFlagVariationNotFound:
|
|
223
|
-
case exports.KameleoonException.FeatureFlagEnvironmentDisabled:
|
|
224
223
|
case exports.KameleoonException.FeatureFlagVariableNotFound:
|
|
225
224
|
this.message = ERROR_MESSAGES[type](secondParam, thirdParam);
|
|
226
225
|
break;
|
|
226
|
+
case exports.KameleoonException.FeatureFlagEnvironmentDisabled:
|
|
227
|
+
if (thirdParam !== undefined) {
|
|
228
|
+
this.message = ERROR_MESSAGES[type](secondParam, thirdParam);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
this.message = secondParam;
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
227
234
|
case exports.KameleoonException.StorageWrite:
|
|
228
235
|
case exports.KameleoonException.JSONParse:
|
|
229
236
|
this.message = ERROR_MESSAGES[type](secondParam);
|
|
@@ -279,7 +286,7 @@ exports.RequestType = void 0;
|
|
|
279
286
|
RequestType["RemoteData"] = "remoteData";
|
|
280
287
|
})(exports.RequestType || (exports.RequestType = {}));
|
|
281
288
|
|
|
282
|
-
const NUMBER_OF_RETRIES =
|
|
289
|
+
const NUMBER_OF_RETRIES = 1;
|
|
283
290
|
exports.Header = void 0;
|
|
284
291
|
(function (Header) {
|
|
285
292
|
Header["UserAgent"] = "User-Agent";
|
|
@@ -858,6 +865,9 @@ class UrlProvider {
|
|
|
858
865
|
const currentDomain = this.domains[UrlType.DataApi];
|
|
859
866
|
this.domains[UrlType.DataApi] = currentDomain.replace(/^[^.]+/, subDomain);
|
|
860
867
|
}
|
|
868
|
+
get dataApiDomain() {
|
|
869
|
+
return this.domains[UrlType.DataApi];
|
|
870
|
+
}
|
|
861
871
|
getClientConfigurationUrl(timeStamp) {
|
|
862
872
|
this.isInitialized();
|
|
863
873
|
const baseUrl = `https://${this.domains[UrlType.ClientConfiguration]}/v3/`;
|
|
@@ -1117,6 +1127,11 @@ var ConsentType;
|
|
|
1117
1127
|
ConsentType["Required"] = "REQUIRED";
|
|
1118
1128
|
ConsentType["NotRequired"] = "NOT_REQUIRED";
|
|
1119
1129
|
})(ConsentType || (ConsentType = {}));
|
|
1130
|
+
var ConsentBlockingBehaviour;
|
|
1131
|
+
(function (ConsentBlockingBehaviour) {
|
|
1132
|
+
ConsentBlockingBehaviour["PartiallyBlocked"] = "PARTIALLY_BLOCK";
|
|
1133
|
+
ConsentBlockingBehaviour["CompletelyBlocked"] = "FULLY_BLOCK";
|
|
1134
|
+
})(ConsentBlockingBehaviour || (ConsentBlockingBehaviour = {}));
|
|
1120
1135
|
|
|
1121
1136
|
class EventManager {
|
|
1122
1137
|
addEventHandler(eventType, callback) {
|
|
@@ -1144,17 +1159,14 @@ exports.EventType = void 0;
|
|
|
1144
1159
|
EventType["ConfigurationUpdate"] = "configurationUpdate";
|
|
1145
1160
|
})(exports.EventType || (exports.EventType = {}));
|
|
1146
1161
|
|
|
1147
|
-
|
|
1148
|
-
configuration: {
|
|
1149
|
-
consentType: ConsentType.NotRequired},
|
|
1150
|
-
});
|
|
1151
|
-
const DEFAULT_CLIENT_CONFIGURATION$1 = {
|
|
1162
|
+
const DEFAULT_DATA_FILE_CONFIGURATION = {
|
|
1152
1163
|
customData: [],
|
|
1153
1164
|
featureFlags: [],
|
|
1154
1165
|
configuration: {
|
|
1155
1166
|
realTimeUpdate: false,
|
|
1156
1167
|
consentType: ConsentType.NotRequired,
|
|
1157
1168
|
dataApiDomain: 'data.kameleoon.io',
|
|
1169
|
+
consentOptOutBehavior: ConsentBlockingBehaviour.PartiallyBlocked,
|
|
1158
1170
|
},
|
|
1159
1171
|
};
|
|
1160
1172
|
|
|
@@ -1178,7 +1190,7 @@ class ClientConfiguration {
|
|
|
1178
1190
|
constructor({ updateInterval, urlProvider, storage, requester, dataManager, eventSource, externalVisitorCodeManager, eventManager, externalPackageInfo, defaultDataFile, }) {
|
|
1179
1191
|
this.updateConfigurationIntervalId = null;
|
|
1180
1192
|
this.updateType = UpdateType.Polling;
|
|
1181
|
-
this.configurationData =
|
|
1193
|
+
this.configurationData = DEFAULT_DATA_FILE_CONFIGURATION;
|
|
1182
1194
|
this.featureFlagsData = new Map();
|
|
1183
1195
|
this.isTargetedDeliveryRule = null;
|
|
1184
1196
|
this.segmentsData = null;
|
|
@@ -1187,6 +1199,7 @@ class ClientConfiguration {
|
|
|
1187
1199
|
this.mappedRules = null;
|
|
1188
1200
|
this.mappedExperiments = null;
|
|
1189
1201
|
this.usedDefaultDataFile = false;
|
|
1202
|
+
this.blockingBehaviourMode = ConsentBlockingBehaviour.PartiallyBlocked;
|
|
1190
1203
|
this.CACHE_REVALIDATE_PERIOD = 90 * exports.Milliseconds.Minute;
|
|
1191
1204
|
this.urlProvider = urlProvider;
|
|
1192
1205
|
this.requester = requester;
|
|
@@ -1361,6 +1374,9 @@ class ClientConfiguration {
|
|
|
1361
1374
|
get isConsentRequired() {
|
|
1362
1375
|
return this.configuration.consentType === ConsentType.Required;
|
|
1363
1376
|
}
|
|
1377
|
+
get consentBlockingBehaviour() {
|
|
1378
|
+
return this.blockingBehaviourMode;
|
|
1379
|
+
}
|
|
1364
1380
|
get hasAnyTargetedDeliveryRule() {
|
|
1365
1381
|
if (this.isTargetedDeliveryRule !== null) {
|
|
1366
1382
|
return this.isTargetedDeliveryRule;
|
|
@@ -1489,6 +1505,7 @@ class ClientConfiguration {
|
|
|
1489
1505
|
KameleoonLogger.info `Configuration update type was toggled to ${UpdateType[updateType]}`;
|
|
1490
1506
|
yield this.initialize();
|
|
1491
1507
|
}
|
|
1508
|
+
this.blockingBehaviourMode = this.consentBlockingBehaviourFromStr(clientConfigurationData.configuration.consentOptOutBehavior);
|
|
1492
1509
|
return buildExports.Ok(toggleUpdateType);
|
|
1493
1510
|
});
|
|
1494
1511
|
}
|
|
@@ -1595,6 +1612,14 @@ class ClientConfiguration {
|
|
|
1595
1612
|
this.visitorCodeManager.consentRequired =
|
|
1596
1613
|
this.isConsentRequired && !this.hasAnyTargetedDeliveryRule;
|
|
1597
1614
|
}
|
|
1615
|
+
consentBlockingBehaviourFromStr(str) {
|
|
1616
|
+
if (str === ConsentBlockingBehaviour.PartiallyBlocked ||
|
|
1617
|
+
str === ConsentBlockingBehaviour.CompletelyBlocked) {
|
|
1618
|
+
return str;
|
|
1619
|
+
}
|
|
1620
|
+
KameleoonLogger.error(`Unexpected consent blocking type '${str}'`);
|
|
1621
|
+
return ConsentBlockingBehaviour.PartiallyBlocked;
|
|
1622
|
+
}
|
|
1598
1623
|
}
|
|
1599
1624
|
|
|
1600
1625
|
function constructTypeMap(indexMap) {
|
|
@@ -2389,6 +2414,13 @@ let CustomData$1 = class CustomData {
|
|
|
2389
2414
|
get name() {
|
|
2390
2415
|
return this._name;
|
|
2391
2416
|
}
|
|
2417
|
+
/**
|
|
2418
|
+
* @private
|
|
2419
|
+
* @method name - an internal getter for a name of custom data
|
|
2420
|
+
* */
|
|
2421
|
+
get values() {
|
|
2422
|
+
return this.value;
|
|
2423
|
+
}
|
|
2392
2424
|
};
|
|
2393
2425
|
CustomData$1.UNDEFINED_INDEX = -1;
|
|
2394
2426
|
|
|
@@ -2406,7 +2438,7 @@ let Conversion$1 = class Conversion {
|
|
|
2406
2438
|
this.negative = negative;
|
|
2407
2439
|
this.status = exports.TrackingStatus.Unsent;
|
|
2408
2440
|
this.id = Math.floor(Math.random() * 1000000);
|
|
2409
|
-
this.
|
|
2441
|
+
this._metadata = metadata;
|
|
2410
2442
|
}
|
|
2411
2443
|
set _id(id) {
|
|
2412
2444
|
this.id = id;
|
|
@@ -2427,9 +2459,21 @@ let Conversion$1 = class Conversion {
|
|
|
2427
2459
|
? UrlParameter.Metadata + this._encodeMetadata()
|
|
2428
2460
|
: ''));
|
|
2429
2461
|
}
|
|
2462
|
+
/**
|
|
2463
|
+
* @private
|
|
2464
|
+
* @method metadata - an internal getter for a metadata of conversion
|
|
2465
|
+
* */
|
|
2430
2466
|
get _metadata() {
|
|
2431
2467
|
return this.metadata;
|
|
2432
2468
|
}
|
|
2469
|
+
/**
|
|
2470
|
+
* @private
|
|
2471
|
+
* @method metadata - an internal setter for setting metadata of conversion
|
|
2472
|
+
* @param {number} value - an index value
|
|
2473
|
+
* */
|
|
2474
|
+
set _metadata(value) {
|
|
2475
|
+
this.metadata = value;
|
|
2476
|
+
}
|
|
2433
2477
|
get data() {
|
|
2434
2478
|
var _a;
|
|
2435
2479
|
return {
|
|
@@ -2863,7 +2907,10 @@ class VisitsData {
|
|
|
2863
2907
|
constructor(visits) {
|
|
2864
2908
|
this.status = exports.TrackingStatus.Sent;
|
|
2865
2909
|
this.visits = visits;
|
|
2866
|
-
this.
|
|
2910
|
+
this._visitNumber = visits.length ? visits.length - 1 : 0;
|
|
2911
|
+
}
|
|
2912
|
+
get visitNumber() {
|
|
2913
|
+
return this._visitNumber;
|
|
2867
2914
|
}
|
|
2868
2915
|
get url() {
|
|
2869
2916
|
return '';
|
|
@@ -2871,7 +2918,7 @@ class VisitsData {
|
|
|
2871
2918
|
get data() {
|
|
2872
2919
|
return {
|
|
2873
2920
|
visits: this.visits,
|
|
2874
|
-
visitNumber: this.
|
|
2921
|
+
visitNumber: this._visitNumber,
|
|
2875
2922
|
type: exports.KameleoonData.VisitsData,
|
|
2876
2923
|
status: this.status,
|
|
2877
2924
|
};
|
|
@@ -2888,11 +2935,11 @@ class VisitsData {
|
|
|
2888
2935
|
list: this.visits,
|
|
2889
2936
|
visit,
|
|
2890
2937
|
});
|
|
2891
|
-
this.
|
|
2938
|
+
this._visitNumber = this.visits.length ? this.visits.length - 1 : 0;
|
|
2892
2939
|
}
|
|
2893
2940
|
updateVisitNumber(visitNumber) {
|
|
2894
|
-
if (visitNumber > this.
|
|
2895
|
-
this.
|
|
2941
|
+
if (visitNumber > this._visitNumber) {
|
|
2942
|
+
this._visitNumber = visitNumber;
|
|
2896
2943
|
}
|
|
2897
2944
|
}
|
|
2898
2945
|
}
|
|
@@ -3099,10 +3146,12 @@ class VisitProcessor {
|
|
|
3099
3146
|
timeLastActivity: (_a = visit.timeLastEvent) !== null && _a !== void 0 ? _a : visit.timeStarted,
|
|
3100
3147
|
};
|
|
3101
3148
|
}
|
|
3102
|
-
processVisitNumber(visit,
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3149
|
+
processVisitNumber(visit, visitOffset) {
|
|
3150
|
+
var _a, _b, _c;
|
|
3151
|
+
if (this.visitsData.visitNumber <= visitOffset &&
|
|
3152
|
+
((_a = visit.staticDataEvent) === null || _a === void 0 ? void 0 : _a.data.visitNumber)) {
|
|
3153
|
+
const visitNumber = (_c = (_b = visit.staticDataEvent) === null || _b === void 0 ? void 0 : _b.data.visitNumber) !== null && _c !== void 0 ? _c : 0;
|
|
3154
|
+
this.visitsData.updateVisitNumber(visitNumber + visitOffset);
|
|
3106
3155
|
}
|
|
3107
3156
|
}
|
|
3108
3157
|
processCbs(cbsData) {
|
|
@@ -3276,12 +3325,12 @@ class Parser {
|
|
|
3276
3325
|
}
|
|
3277
3326
|
if (currentVisit) {
|
|
3278
3327
|
visitProcessor.processVisit(currentVisit);
|
|
3279
|
-
visitProcessor.processVisitNumber(currentVisit,
|
|
3328
|
+
visitProcessor.processVisitNumber(currentVisit, 0);
|
|
3280
3329
|
}
|
|
3281
|
-
previousVisits === null || previousVisits === void 0 ? void 0 : previousVisits.forEach((visit) => {
|
|
3330
|
+
previousVisits === null || previousVisits === void 0 ? void 0 : previousVisits.forEach((visit, index) => {
|
|
3282
3331
|
visitProcessor.processVisit(visit);
|
|
3283
3332
|
visitProcessor.processVisitsData(visit);
|
|
3284
|
-
visitProcessor.processVisitNumber(visit,
|
|
3333
|
+
visitProcessor.processVisitNumber(visit, index + 1);
|
|
3285
3334
|
});
|
|
3286
3335
|
visitProcessor.processKcs(kcs);
|
|
3287
3336
|
visitProcessor.processCbs(cbs);
|
|
@@ -3522,7 +3571,7 @@ class DataProcessor {
|
|
|
3522
3571
|
this.cleanupInterval = cleanupInterval;
|
|
3523
3572
|
this.packageInfo = packageInfo;
|
|
3524
3573
|
}
|
|
3525
|
-
mutUpdateData({ infoData, visitorCode, mutData, dataItem, }) {
|
|
3574
|
+
mutUpdateData({ infoData, visitorCode, mutData, dataItem, extendTtl, }) {
|
|
3526
3575
|
let { visitorReference, data, isReference } = this.dereferenceData(mutData, visitorCode);
|
|
3527
3576
|
if (this.packageInfo.isServer &&
|
|
3528
3577
|
isReference &&
|
|
@@ -3533,9 +3582,12 @@ class DataProcessor {
|
|
|
3533
3582
|
delete mutData[visitorCode];
|
|
3534
3583
|
visitorReference = visitorCode;
|
|
3535
3584
|
}
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3585
|
+
let expirationTime;
|
|
3586
|
+
if (extendTtl) {
|
|
3587
|
+
expirationTime = this.cleanupInterval
|
|
3588
|
+
? Date.now() + this.cleanupInterval
|
|
3589
|
+
: 0;
|
|
3590
|
+
}
|
|
3539
3591
|
switch (dataItem.data.type) {
|
|
3540
3592
|
case exports.KameleoonData.CustomData: {
|
|
3541
3593
|
this.updateCustomData({
|
|
@@ -3890,13 +3942,17 @@ class DataProcessor {
|
|
|
3890
3942
|
return closestCleanupTime;
|
|
3891
3943
|
}
|
|
3892
3944
|
updateField({ key, value, data, visitorCode, expirationTime, }) {
|
|
3893
|
-
|
|
3945
|
+
var _a;
|
|
3946
|
+
const existing = data[visitorCode][key];
|
|
3947
|
+
data[visitorCode][key] = Object.assign(Object.assign({}, value), { expirationTime: (_a = expirationTime !== null && expirationTime !== void 0 ? expirationTime : (existing.expirationTime && existing.expirationTime)) !== null && _a !== void 0 ? _a : Date.now() });
|
|
3894
3948
|
}
|
|
3895
3949
|
createField({ key, value, data, visitorCode, expirationTime, }) {
|
|
3896
3950
|
data[visitorCode] = Object.assign(Object.assign({}, data[visitorCode]), { [key]: Object.assign(Object.assign({}, value), { expirationTime }) });
|
|
3897
3951
|
}
|
|
3898
3952
|
updateNestedField({ key, nestedKey, value, data, visitorCode, expirationTime, }) {
|
|
3899
|
-
|
|
3953
|
+
var _a;
|
|
3954
|
+
const existing = data[visitorCode][key][nestedKey];
|
|
3955
|
+
data[visitorCode][key][nestedKey] = Object.assign(Object.assign({}, value), { expirationTime: (_a = expirationTime !== null && expirationTime !== void 0 ? expirationTime : existing === null || existing === void 0 ? void 0 : existing.expirationTime) !== null && _a !== void 0 ? _a : Date.now() });
|
|
3900
3956
|
}
|
|
3901
3957
|
createNestedField({ key, nestedKey, value, data, visitorCode, expirationTime, }) {
|
|
3902
3958
|
var _a;
|
|
@@ -5162,15 +5218,7 @@ exports.KameleoonStorageKey = void 0;
|
|
|
5162
5218
|
KameleoonStorageKey["ForcedExperimentVariation"] = "kameleoonForcedExperimentVariation";
|
|
5163
5219
|
})(exports.KameleoonStorageKey || (exports.KameleoonStorageKey = {}));
|
|
5164
5220
|
const DEFAULT_CLIENT_CONFIGURATION = {
|
|
5165
|
-
data:
|
|
5166
|
-
customData: [],
|
|
5167
|
-
featureFlags: [],
|
|
5168
|
-
configuration: {
|
|
5169
|
-
realTimeUpdate: false,
|
|
5170
|
-
consentType: ConsentType.NotRequired,
|
|
5171
|
-
dataApiDomain: 'data.kameleoon.io',
|
|
5172
|
-
},
|
|
5173
|
-
},
|
|
5221
|
+
data: DEFAULT_DATA_FILE_CONFIGURATION,
|
|
5174
5222
|
lastUpdate: '',
|
|
5175
5223
|
};
|
|
5176
5224
|
// --- Note ---
|
|
@@ -5682,7 +5730,7 @@ class DataManager {
|
|
|
5682
5730
|
return resultData;
|
|
5683
5731
|
}
|
|
5684
5732
|
storeTrackedData(data) {
|
|
5685
|
-
this.storeData(data);
|
|
5733
|
+
this.storeData(data, false);
|
|
5686
5734
|
const infoResult = this.infoStorage.read();
|
|
5687
5735
|
if (!infoResult.ok) {
|
|
5688
5736
|
return;
|
|
@@ -5734,15 +5782,18 @@ class DataManager {
|
|
|
5734
5782
|
targetingData,
|
|
5735
5783
|
visitorCode: firstParameter,
|
|
5736
5784
|
kameleoonData: secondParameter,
|
|
5785
|
+
extendTtl: true,
|
|
5737
5786
|
});
|
|
5738
5787
|
}
|
|
5739
5788
|
else {
|
|
5740
5789
|
for (const [visitorCode, kameleoonData] of Object.entries(firstParameter)) {
|
|
5790
|
+
const extendTtl = typeof secondParameter[0] === 'boolean' ? secondParameter[0] : true;
|
|
5741
5791
|
this.mutUpdateTargetingData({
|
|
5742
5792
|
infoData,
|
|
5743
5793
|
targetingData,
|
|
5744
5794
|
visitorCode,
|
|
5745
5795
|
kameleoonData,
|
|
5796
|
+
extendTtl,
|
|
5746
5797
|
});
|
|
5747
5798
|
}
|
|
5748
5799
|
}
|
|
@@ -5859,8 +5910,8 @@ class DataManager {
|
|
|
5859
5910
|
}
|
|
5860
5911
|
return null;
|
|
5861
5912
|
}
|
|
5862
|
-
mutUpdateTargetingData({ infoData, visitorCode, kameleoonData, targetingData, }) {
|
|
5863
|
-
var _a;
|
|
5913
|
+
mutUpdateTargetingData({ infoData, visitorCode, kameleoonData, targetingData, extendTtl, }) {
|
|
5914
|
+
var _a, _b, _c;
|
|
5864
5915
|
for (const dataItem of kameleoonData) {
|
|
5865
5916
|
// process custom data
|
|
5866
5917
|
if (dataItem.data.type === exports.KameleoonData.CustomData) {
|
|
@@ -5876,16 +5927,21 @@ class DataManager {
|
|
|
5876
5927
|
}
|
|
5877
5928
|
// process metadata of conversions
|
|
5878
5929
|
if (dataItem.data.type === exports.KameleoonData.Conversion) {
|
|
5879
|
-
|
|
5930
|
+
const conversion = dataItem;
|
|
5931
|
+
if (((_b = (_a = conversion._metadata) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0) {
|
|
5932
|
+
conversion._metadata = (_c = conversion._metadata) === null || _c === void 0 ? void 0 : _c.filter((item) => this.trySetCustomDataIndexByName(item));
|
|
5933
|
+
}
|
|
5880
5934
|
}
|
|
5881
5935
|
const expirationTime = this.dataProcessor.mutUpdateData({
|
|
5882
5936
|
infoData,
|
|
5883
5937
|
visitorCode,
|
|
5884
5938
|
mutData: targetingData,
|
|
5885
5939
|
dataItem,
|
|
5940
|
+
extendTtl,
|
|
5886
5941
|
});
|
|
5887
5942
|
const nextCleanup = infoData.nextDataCleanup;
|
|
5888
|
-
if (!nextCleanup ||
|
|
5943
|
+
if (!nextCleanup ||
|
|
5944
|
+
(nextCleanup && expirationTime && expirationTime < nextCleanup)) {
|
|
5889
5945
|
infoData.nextDataCleanup = expirationTime;
|
|
5890
5946
|
}
|
|
5891
5947
|
if (dataItem.data.status === exports.TrackingStatus.Unsent) {
|
|
@@ -5917,7 +5973,9 @@ class DataManager {
|
|
|
5917
5973
|
var _a;
|
|
5918
5974
|
const { data } = customData;
|
|
5919
5975
|
const isDataValid = Boolean(data.value.length && data.value[0].length);
|
|
5920
|
-
this.trySetCustomDataIndexByName(customData)
|
|
5976
|
+
if (!this.trySetCustomDataIndexByName(customData)) {
|
|
5977
|
+
return false;
|
|
5978
|
+
}
|
|
5921
5979
|
if (data.index == CustomData$1.UNDEFINED_INDEX) {
|
|
5922
5980
|
data.index = customData.index;
|
|
5923
5981
|
}
|
|
@@ -5947,13 +6005,15 @@ class DataManager {
|
|
|
5947
6005
|
return true;
|
|
5948
6006
|
}
|
|
5949
6007
|
trySetCustomDataIndexByName(customData) {
|
|
5950
|
-
if (customData.index
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
6008
|
+
if (customData.index !== CustomData$1.UNDEFINED_INDEX)
|
|
6009
|
+
return true;
|
|
6010
|
+
if (!customData.name)
|
|
6011
|
+
return false;
|
|
6012
|
+
const cdIndex = this.customDataIndexByName.get(customData.name);
|
|
6013
|
+
if (cdIndex == null)
|
|
6014
|
+
return false;
|
|
6015
|
+
customData.index = cdIndex;
|
|
6016
|
+
return true;
|
|
5957
6017
|
}
|
|
5958
6018
|
get unsentDataVisitors() {
|
|
5959
6019
|
const infoResult = this.infoStorage.read();
|
|
@@ -7057,6 +7117,13 @@ class Hasher {
|
|
|
7057
7117
|
}
|
|
7058
7118
|
}
|
|
7059
7119
|
|
|
7120
|
+
var LegalConsent;
|
|
7121
|
+
(function (LegalConsent) {
|
|
7122
|
+
LegalConsent[LegalConsent["Unknown"] = 0] = "Unknown";
|
|
7123
|
+
LegalConsent[LegalConsent["Given"] = 1] = "Given";
|
|
7124
|
+
LegalConsent[LegalConsent["NotGiven"] = 2] = "NotGiven";
|
|
7125
|
+
})(LegalConsent || (LegalConsent = {}));
|
|
7126
|
+
|
|
7060
7127
|
class VariationConfiguration {
|
|
7061
7128
|
constructor(externalStorage, externalStorageForcedExperimentVariations, externalStorageForcedFeatureVariations, visitorCodeManager, clientConfiguration) {
|
|
7062
7129
|
this.storage = externalStorage;
|
|
@@ -7115,9 +7182,12 @@ class VariationConfiguration {
|
|
|
7115
7182
|
}
|
|
7116
7183
|
return buildExports.Ok(featureFlagVariations);
|
|
7117
7184
|
}
|
|
7118
|
-
getVariation({ visitorCode, visitorIdentifier, featureFlag, targetingData, packageInfo, clientConfiguration, dataManager, track = true, withAssignment = false, }) {
|
|
7185
|
+
getVariation({ visitorCode, visitorIdentifier, featureFlag, targetingData, packageInfo, clientConfiguration, dataManager, legalConsent, track = true, withAssignment = false, }) {
|
|
7119
7186
|
KameleoonLogger.debug `CALL: VariationConfiguration.getVariation(visitorCode: ${visitorCode}, visitorIdentifier: ${visitorIdentifier}, featureFlag: ${featureFlag}, targetingData: ${targetingData}, packageInfo: ${packageInfo}, clientConfiguration, dataManager, withAssignment: ${withAssignment})`;
|
|
7120
7187
|
const { rules, featureKey, id: featureFlagId, defaultVariationKey, } = featureFlag;
|
|
7188
|
+
const consent = clientConfiguration.isConsentRequired
|
|
7189
|
+
? legalConsent
|
|
7190
|
+
: LegalConsent.Given;
|
|
7121
7191
|
for (const rule of rules) {
|
|
7122
7192
|
const { segment, experimentId, id, exposition, respoolTime, variationByExposition, } = rule;
|
|
7123
7193
|
const forcedVariationData = this.getForcedExperimentVariation(visitorCode, rule.experimentId);
|
|
@@ -7164,6 +7234,16 @@ class VariationConfiguration {
|
|
|
7164
7234
|
});
|
|
7165
7235
|
KameleoonLogger.debug `Calculated ruleHash: ${ruleHash} for code: ${visitorIdentifier}`;
|
|
7166
7236
|
if (ruleHash <= exposition) {
|
|
7237
|
+
// Checking if the evaluation is blocked due to the consent policy
|
|
7238
|
+
if (consent == LegalConsent.NotGiven &&
|
|
7239
|
+
rule.type == RuleType.EXPERIMENTATION) {
|
|
7240
|
+
const behaviour = clientConfiguration.consentBlockingBehaviour;
|
|
7241
|
+
if (behaviour == ConsentBlockingBehaviour.PartiallyBlocked) {
|
|
7242
|
+
break;
|
|
7243
|
+
}
|
|
7244
|
+
return buildExports.Err(new KameleoonError(exports.KameleoonException.FeatureFlagEnvironmentDisabled, `Evaluation of ${rule} is blocked because consent is not provided for visitor '${visitorCode}'`));
|
|
7245
|
+
}
|
|
7246
|
+
// evaluate with CB scores if applicable
|
|
7167
7247
|
let variation = this.evaluateCBScores(rule, visitorIdentifier, targetingData);
|
|
7168
7248
|
if (!variation) {
|
|
7169
7249
|
const variationHash = Hasher.getHashDouble({
|
|
@@ -7525,7 +7605,6 @@ class KameleoonEventSource {
|
|
|
7525
7605
|
const VISITOR_CODE_LENGTH = 16;
|
|
7526
7606
|
const VISITOR_CODE_MAX_LENGTH = 255;
|
|
7527
7607
|
const DEFAULT_MAX_AGE = 60 * 60 * 24 * 365;
|
|
7528
|
-
const ZERO_MAX_AGE = 0;
|
|
7529
7608
|
const PATH = '/';
|
|
7530
7609
|
|
|
7531
7610
|
/**
|
|
@@ -7993,7 +8072,7 @@ class Tracker {
|
|
|
7993
8072
|
this.dataManager.storeTrackedData(updatedData);
|
|
7994
8073
|
}
|
|
7995
8074
|
else {
|
|
7996
|
-
this.dataManager.storeData(updatedData);
|
|
8075
|
+
this.dataManager.storeData(updatedData, false);
|
|
7997
8076
|
}
|
|
7998
8077
|
}
|
|
7999
8078
|
getUnsentVisitorData(visitorCode, isConsentProvided) {
|
|
@@ -8345,16 +8424,23 @@ class KameleoonClient {
|
|
|
8345
8424
|
const variations = new Map();
|
|
8346
8425
|
const featureFlags = this.clientConfiguration.featureFlags;
|
|
8347
8426
|
for (const featureFlag of featureFlags.values()) {
|
|
8348
|
-
|
|
8349
|
-
|
|
8350
|
-
|
|
8351
|
-
|
|
8352
|
-
|
|
8353
|
-
|
|
8354
|
-
if (
|
|
8427
|
+
try {
|
|
8428
|
+
const variation = this._getFeatureVariation({
|
|
8429
|
+
visitorCode,
|
|
8430
|
+
featureKey: featureFlag.featureKey,
|
|
8431
|
+
track,
|
|
8432
|
+
});
|
|
8433
|
+
if (variation.ok &&
|
|
8434
|
+
(!onlyActive || variation.data.key !== OFF_VARIATION_KEY)) {
|
|
8355
8435
|
variations.set(featureFlag.featureKey, variation.data);
|
|
8356
8436
|
}
|
|
8357
8437
|
}
|
|
8438
|
+
catch (err) {
|
|
8439
|
+
if (err instanceof KameleoonError &&
|
|
8440
|
+
err.type !== exports.KameleoonException.FeatureFlagEnvironmentDisabled) {
|
|
8441
|
+
throw err;
|
|
8442
|
+
}
|
|
8443
|
+
}
|
|
8358
8444
|
}
|
|
8359
8445
|
KameleoonLogger.info `RETURN: KameleoonClient.getVariations(visitorCode: ${visitorCode}, onlyActive: ${onlyActive}, track: ${track}) -> (variations: ${variations})`;
|
|
8360
8446
|
return variations;
|
|
@@ -8674,25 +8760,16 @@ class KameleoonClient {
|
|
|
8674
8760
|
path: PATH,
|
|
8675
8761
|
});
|
|
8676
8762
|
}
|
|
8677
|
-
else {
|
|
8678
|
-
if (this.visitorCodeManager.consentRequired) {
|
|
8679
|
-
setData({
|
|
8680
|
-
visitorCode: '',
|
|
8681
|
-
key: exports.KameleoonStorageKey.VisitorCode,
|
|
8682
|
-
maxAge: ZERO_MAX_AGE,
|
|
8683
|
-
path: PATH,
|
|
8684
|
-
});
|
|
8685
|
-
}
|
|
8686
|
-
}
|
|
8687
8763
|
KameleoonLogger.info `RETURN: KameleoonClient.setUserConsent(visitorCode: ${visitorCode}, consent: ${consent}, setData: ${setData})`;
|
|
8688
8764
|
}
|
|
8689
8765
|
updateConsentData(visitorCode, consent) {
|
|
8690
8766
|
const readResult = this.consentDataStorage.read();
|
|
8767
|
+
const legalConsent = consent ? LegalConsent.Given : LegalConsent.NotGiven;
|
|
8691
8768
|
if (!readResult.ok) {
|
|
8692
8769
|
if (readResult.error.type === exports.KameleoonException.StorageEmpty) {
|
|
8693
8770
|
this.consentDataStorage.write({
|
|
8694
8771
|
[visitorCode]: {
|
|
8695
|
-
consent,
|
|
8772
|
+
consent: legalConsent,
|
|
8696
8773
|
},
|
|
8697
8774
|
});
|
|
8698
8775
|
}
|
|
@@ -8700,28 +8777,36 @@ class KameleoonClient {
|
|
|
8700
8777
|
}
|
|
8701
8778
|
const data = readResult.data;
|
|
8702
8779
|
data[visitorCode] = {
|
|
8703
|
-
consent,
|
|
8780
|
+
consent: legalConsent,
|
|
8704
8781
|
};
|
|
8705
8782
|
this.consentDataStorage.write(data);
|
|
8706
8783
|
}
|
|
8784
|
+
getLegalConsent(visitorCode) {
|
|
8785
|
+
KameleoonLogger.debug `CALL: KameleoonClient.getLegalConsent(visitorCode: ${visitorCode})`;
|
|
8786
|
+
let legalConsent;
|
|
8787
|
+
const consentDataResult = this.consentDataStorage.read();
|
|
8788
|
+
legalConsent = consentDataResult.ok
|
|
8789
|
+
? this.extractLegalConsent(consentDataResult.data[visitorCode])
|
|
8790
|
+
: LegalConsent.Unknown;
|
|
8791
|
+
KameleoonLogger.debug `RETURN: KameleoonClient.getLegalConsent(visitorCode: ${visitorCode}) -> (legalConsent: ${legalConsent})`;
|
|
8792
|
+
return legalConsent;
|
|
8793
|
+
}
|
|
8794
|
+
extractLegalConsent(consentData) {
|
|
8795
|
+
if (consentData === undefined)
|
|
8796
|
+
return LegalConsent.Unknown;
|
|
8797
|
+
if (typeof consentData === 'boolean') {
|
|
8798
|
+
return consentData ? LegalConsent.Given : LegalConsent.NotGiven;
|
|
8799
|
+
}
|
|
8800
|
+
const value = consentData.consent;
|
|
8801
|
+
if (typeof value === 'boolean')
|
|
8802
|
+
return value ? LegalConsent.Given : LegalConsent.NotGiven;
|
|
8803
|
+
return value;
|
|
8804
|
+
}
|
|
8707
8805
|
_isConsentProvided(visitorCode) {
|
|
8708
8806
|
KameleoonLogger.debug `CALL: KameleoonClient._isConsentProvided(visitorCode: ${visitorCode})`;
|
|
8709
8807
|
const { isConsentRequired } = this.clientConfiguration;
|
|
8710
|
-
const
|
|
8711
|
-
|
|
8712
|
-
if (!isConsentRequired) {
|
|
8713
|
-
isConsentProvided = true;
|
|
8714
|
-
}
|
|
8715
|
-
else if (consentDataResult.ok) {
|
|
8716
|
-
const consentData = consentDataResult.data[visitorCode];
|
|
8717
|
-
// for consistency with the old data in the storage
|
|
8718
|
-
if (typeof consentData === 'boolean') {
|
|
8719
|
-
isConsentProvided = consentData;
|
|
8720
|
-
}
|
|
8721
|
-
else {
|
|
8722
|
-
isConsentProvided = consentData && consentData.consent;
|
|
8723
|
-
}
|
|
8724
|
-
}
|
|
8808
|
+
const isConsentProvided = !isConsentRequired ||
|
|
8809
|
+
this.getLegalConsent(visitorCode) == LegalConsent.Given;
|
|
8725
8810
|
KameleoonLogger.debug `RETURN: KameleoonClient._isConsentProvided(visitorCode: ${visitorCode}) -> (isConsentProvided: ${isConsentProvided})`;
|
|
8726
8811
|
return isConsentProvided;
|
|
8727
8812
|
}
|
|
@@ -8749,22 +8834,32 @@ class KameleoonClient {
|
|
|
8749
8834
|
if (!featureFlag.environmentEnabled) {
|
|
8750
8835
|
continue;
|
|
8751
8836
|
}
|
|
8752
|
-
|
|
8753
|
-
|
|
8754
|
-
|
|
8755
|
-
|
|
8756
|
-
|
|
8757
|
-
|
|
8758
|
-
if (evalExp.variationKey !== OFF_VARIATION_KEY) {
|
|
8759
|
-
activeVariations.push({
|
|
8760
|
-
variationKey: evalExp.variationKey,
|
|
8761
|
-
variationId: evalExp.variationId,
|
|
8762
|
-
experimentId: evalExp.experimentId,
|
|
8763
|
-
featureFlagId: featureFlag.id,
|
|
8764
|
-
featureKey: featureFlag.featureKey,
|
|
8765
|
-
rule: null,
|
|
8766
|
-
isTargetedRule: evalExp.ruleType === RuleType.TARGETED_DELIVERY,
|
|
8837
|
+
try {
|
|
8838
|
+
const evalExp = this._evaluate({
|
|
8839
|
+
visitorCode,
|
|
8840
|
+
featureFlag,
|
|
8841
|
+
track: false,
|
|
8842
|
+
save: false,
|
|
8767
8843
|
});
|
|
8844
|
+
if (evalExp.variationKey !== OFF_VARIATION_KEY) {
|
|
8845
|
+
activeVariations.push({
|
|
8846
|
+
variationKey: evalExp.variationKey,
|
|
8847
|
+
variationId: evalExp.variationId,
|
|
8848
|
+
experimentId: evalExp.experimentId,
|
|
8849
|
+
featureFlagId: featureFlag.id,
|
|
8850
|
+
featureKey: featureFlag.featureKey,
|
|
8851
|
+
rule: null,
|
|
8852
|
+
isTargetedRule: evalExp.ruleType === RuleType.TARGETED_DELIVERY,
|
|
8853
|
+
});
|
|
8854
|
+
}
|
|
8855
|
+
}
|
|
8856
|
+
catch (err) {
|
|
8857
|
+
if (err instanceof KameleoonError) {
|
|
8858
|
+
if (err.type != exports.KameleoonException.FeatureFlagEnvironmentDisabled) {
|
|
8859
|
+
KameleoonLogger.error `Unexpected error: ${err}`;
|
|
8860
|
+
}
|
|
8861
|
+
continue;
|
|
8862
|
+
}
|
|
8768
8863
|
}
|
|
8769
8864
|
}
|
|
8770
8865
|
KameleoonLogger.debug `RETURN: KameleoonClient._getActiveFeatureVariations(visitorCode: ${visitorCode}) -> (activeVariations: ${activeVariations})`;
|
|
@@ -8785,6 +8880,7 @@ class KameleoonClient {
|
|
|
8785
8880
|
else if (this._isVisitorNotInHoldout(visitorCode, track, save, featureFlag, visitorData) &&
|
|
8786
8881
|
this._isFFUnrestrictedByMEGroup(visitorCode, featureFlag, visitorData)) {
|
|
8787
8882
|
const visitorIdentifier = this._getCodeForHash(visitorCode, featureFlag.bucketingCustomDataIndex, visitorData);
|
|
8883
|
+
const legalConsent = this.getLegalConsent(visitorCode);
|
|
8788
8884
|
const variationData = this.variationConfiguration
|
|
8789
8885
|
.getVariation({
|
|
8790
8886
|
visitorCode,
|
|
@@ -8796,6 +8892,7 @@ class KameleoonClient {
|
|
|
8796
8892
|
clientConfiguration: this.clientConfiguration,
|
|
8797
8893
|
dataManager: this.dataManager,
|
|
8798
8894
|
packageInfo: this.externalPackageInfo,
|
|
8895
|
+
legalConsent,
|
|
8799
8896
|
})
|
|
8800
8897
|
.throw();
|
|
8801
8898
|
evalExp =
|
|
@@ -8914,6 +9011,16 @@ class KameleoonClient {
|
|
|
8914
9011
|
}
|
|
8915
9012
|
KameleoonLogger.debug `CALL: KameleoonClient._isVisitorNotInHoldout(visitorCode: ${visitorCode}, track: ${track}, save: ${save}, featureFlag: ${featureFlag}, visitorData: ${visitorData})`;
|
|
8916
9013
|
let isNotInHoldout = true;
|
|
9014
|
+
// Checking if the evaluation is blocked due to the consent policy
|
|
9015
|
+
const legalConsent = this.clientConfiguration.isConsentRequired
|
|
9016
|
+
? this.getLegalConsent(visitorCode)
|
|
9017
|
+
: LegalConsent.Given;
|
|
9018
|
+
if (legalConsent == LegalConsent.NotGiven) {
|
|
9019
|
+
const behaviour = this.clientConfiguration.consentBlockingBehaviour;
|
|
9020
|
+
if (behaviour == ConsentBlockingBehaviour.CompletelyBlocked) {
|
|
9021
|
+
throw new KameleoonError(exports.KameleoonException.FeatureFlagEnvironmentDisabled, `Evaluation of holdout is blocked because consent is not provided for visitor '${visitorCode}'`);
|
|
9022
|
+
}
|
|
9023
|
+
}
|
|
8917
9024
|
const codeForHash = this._getCodeForHash(visitorCode, featureFlag === null || featureFlag === void 0 ? void 0 : featureFlag.bucketingCustomDataIndex, visitorData);
|
|
8918
9025
|
const holdoutHash = Hasher.getHashDouble({
|
|
8919
9026
|
visitorIdentifier: codeForHash,
|