@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
|
@@ -249,10 +249,17 @@ class KameleoonError extends Error {
|
|
|
249
249
|
this.message = ERROR_MESSAGES[type](secondParam, thirdParam);
|
|
250
250
|
break;
|
|
251
251
|
case exports.KameleoonException.FeatureFlagVariationNotFound:
|
|
252
|
-
case exports.KameleoonException.FeatureFlagEnvironmentDisabled:
|
|
253
252
|
case exports.KameleoonException.FeatureFlagVariableNotFound:
|
|
254
253
|
this.message = ERROR_MESSAGES[type](secondParam, thirdParam);
|
|
255
254
|
break;
|
|
255
|
+
case exports.KameleoonException.FeatureFlagEnvironmentDisabled:
|
|
256
|
+
if (thirdParam !== undefined) {
|
|
257
|
+
this.message = ERROR_MESSAGES[type](secondParam, thirdParam);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
this.message = secondParam;
|
|
261
|
+
}
|
|
262
|
+
break;
|
|
256
263
|
case exports.KameleoonException.StorageWrite:
|
|
257
264
|
case exports.KameleoonException.JSONParse:
|
|
258
265
|
this.message = ERROR_MESSAGES[type](secondParam);
|
|
@@ -308,7 +315,7 @@ exports.RequestType = void 0;
|
|
|
308
315
|
RequestType["RemoteData"] = "remoteData";
|
|
309
316
|
})(exports.RequestType || (exports.RequestType = {}));
|
|
310
317
|
|
|
311
|
-
const NUMBER_OF_RETRIES =
|
|
318
|
+
const NUMBER_OF_RETRIES = 1;
|
|
312
319
|
exports.Header = void 0;
|
|
313
320
|
(function (Header) {
|
|
314
321
|
Header["UserAgent"] = "User-Agent";
|
|
@@ -887,6 +894,9 @@ class UrlProvider {
|
|
|
887
894
|
const currentDomain = this.domains[UrlType.DataApi];
|
|
888
895
|
this.domains[UrlType.DataApi] = currentDomain.replace(/^[^.]+/, subDomain);
|
|
889
896
|
}
|
|
897
|
+
get dataApiDomain() {
|
|
898
|
+
return this.domains[UrlType.DataApi];
|
|
899
|
+
}
|
|
890
900
|
getClientConfigurationUrl(timeStamp) {
|
|
891
901
|
this.isInitialized();
|
|
892
902
|
const baseUrl = `https://${this.domains[UrlType.ClientConfiguration]}/v3/`;
|
|
@@ -1146,6 +1156,11 @@ var ConsentType;
|
|
|
1146
1156
|
ConsentType["Required"] = "REQUIRED";
|
|
1147
1157
|
ConsentType["NotRequired"] = "NOT_REQUIRED";
|
|
1148
1158
|
})(ConsentType || (ConsentType = {}));
|
|
1159
|
+
var ConsentBlockingBehaviour;
|
|
1160
|
+
(function (ConsentBlockingBehaviour) {
|
|
1161
|
+
ConsentBlockingBehaviour["PartiallyBlocked"] = "PARTIALLY_BLOCK";
|
|
1162
|
+
ConsentBlockingBehaviour["CompletelyBlocked"] = "FULLY_BLOCK";
|
|
1163
|
+
})(ConsentBlockingBehaviour || (ConsentBlockingBehaviour = {}));
|
|
1149
1164
|
|
|
1150
1165
|
class EventManager {
|
|
1151
1166
|
addEventHandler(eventType, callback) {
|
|
@@ -1173,17 +1188,14 @@ exports.EventType = void 0;
|
|
|
1173
1188
|
EventType["ConfigurationUpdate"] = "configurationUpdate";
|
|
1174
1189
|
})(exports.EventType || (exports.EventType = {}));
|
|
1175
1190
|
|
|
1176
|
-
|
|
1177
|
-
configuration: {
|
|
1178
|
-
consentType: ConsentType.NotRequired},
|
|
1179
|
-
});
|
|
1180
|
-
const DEFAULT_CLIENT_CONFIGURATION$1 = {
|
|
1191
|
+
const DEFAULT_DATA_FILE_CONFIGURATION = {
|
|
1181
1192
|
customData: [],
|
|
1182
1193
|
featureFlags: [],
|
|
1183
1194
|
configuration: {
|
|
1184
1195
|
realTimeUpdate: false,
|
|
1185
1196
|
consentType: ConsentType.NotRequired,
|
|
1186
1197
|
dataApiDomain: 'data.kameleoon.io',
|
|
1198
|
+
consentOptOutBehavior: ConsentBlockingBehaviour.PartiallyBlocked,
|
|
1187
1199
|
},
|
|
1188
1200
|
};
|
|
1189
1201
|
|
|
@@ -1207,7 +1219,7 @@ class ClientConfiguration {
|
|
|
1207
1219
|
constructor({ updateInterval, urlProvider, storage, requester, dataManager, eventSource, externalVisitorCodeManager, eventManager, externalPackageInfo, defaultDataFile, }) {
|
|
1208
1220
|
this.updateConfigurationIntervalId = null;
|
|
1209
1221
|
this.updateType = UpdateType.Polling;
|
|
1210
|
-
this.configurationData =
|
|
1222
|
+
this.configurationData = DEFAULT_DATA_FILE_CONFIGURATION;
|
|
1211
1223
|
this.featureFlagsData = new Map();
|
|
1212
1224
|
this.isTargetedDeliveryRule = null;
|
|
1213
1225
|
this.segmentsData = null;
|
|
@@ -1216,6 +1228,7 @@ class ClientConfiguration {
|
|
|
1216
1228
|
this.mappedRules = null;
|
|
1217
1229
|
this.mappedExperiments = null;
|
|
1218
1230
|
this.usedDefaultDataFile = false;
|
|
1231
|
+
this.blockingBehaviourMode = ConsentBlockingBehaviour.PartiallyBlocked;
|
|
1219
1232
|
this.CACHE_REVALIDATE_PERIOD = 90 * exports.Milliseconds.Minute;
|
|
1220
1233
|
this.urlProvider = urlProvider;
|
|
1221
1234
|
this.requester = requester;
|
|
@@ -1390,6 +1403,9 @@ class ClientConfiguration {
|
|
|
1390
1403
|
get isConsentRequired() {
|
|
1391
1404
|
return this.configuration.consentType === ConsentType.Required;
|
|
1392
1405
|
}
|
|
1406
|
+
get consentBlockingBehaviour() {
|
|
1407
|
+
return this.blockingBehaviourMode;
|
|
1408
|
+
}
|
|
1393
1409
|
get hasAnyTargetedDeliveryRule() {
|
|
1394
1410
|
if (this.isTargetedDeliveryRule !== null) {
|
|
1395
1411
|
return this.isTargetedDeliveryRule;
|
|
@@ -1518,6 +1534,7 @@ class ClientConfiguration {
|
|
|
1518
1534
|
KameleoonLogger.info `Configuration update type was toggled to ${UpdateType[updateType]}`;
|
|
1519
1535
|
yield this.initialize();
|
|
1520
1536
|
}
|
|
1537
|
+
this.blockingBehaviourMode = this.consentBlockingBehaviourFromStr(clientConfigurationData.configuration.consentOptOutBehavior);
|
|
1521
1538
|
return buildExports.Ok(toggleUpdateType);
|
|
1522
1539
|
});
|
|
1523
1540
|
}
|
|
@@ -1624,6 +1641,14 @@ class ClientConfiguration {
|
|
|
1624
1641
|
this.visitorCodeManager.consentRequired =
|
|
1625
1642
|
this.isConsentRequired && !this.hasAnyTargetedDeliveryRule;
|
|
1626
1643
|
}
|
|
1644
|
+
consentBlockingBehaviourFromStr(str) {
|
|
1645
|
+
if (str === ConsentBlockingBehaviour.PartiallyBlocked ||
|
|
1646
|
+
str === ConsentBlockingBehaviour.CompletelyBlocked) {
|
|
1647
|
+
return str;
|
|
1648
|
+
}
|
|
1649
|
+
KameleoonLogger.error(`Unexpected consent blocking type '${str}'`);
|
|
1650
|
+
return ConsentBlockingBehaviour.PartiallyBlocked;
|
|
1651
|
+
}
|
|
1627
1652
|
}
|
|
1628
1653
|
|
|
1629
1654
|
function constructTypeMap(indexMap) {
|
|
@@ -2418,6 +2443,13 @@ let CustomData$1 = class CustomData {
|
|
|
2418
2443
|
get name() {
|
|
2419
2444
|
return this._name;
|
|
2420
2445
|
}
|
|
2446
|
+
/**
|
|
2447
|
+
* @private
|
|
2448
|
+
* @method name - an internal getter for a name of custom data
|
|
2449
|
+
* */
|
|
2450
|
+
get values() {
|
|
2451
|
+
return this.value;
|
|
2452
|
+
}
|
|
2421
2453
|
};
|
|
2422
2454
|
CustomData$1.UNDEFINED_INDEX = -1;
|
|
2423
2455
|
|
|
@@ -2435,7 +2467,7 @@ let Conversion$1 = class Conversion {
|
|
|
2435
2467
|
this.negative = negative;
|
|
2436
2468
|
this.status = exports.TrackingStatus.Unsent;
|
|
2437
2469
|
this.id = Math.floor(Math.random() * 1000000);
|
|
2438
|
-
this.
|
|
2470
|
+
this._metadata = metadata;
|
|
2439
2471
|
}
|
|
2440
2472
|
set _id(id) {
|
|
2441
2473
|
this.id = id;
|
|
@@ -2456,9 +2488,21 @@ let Conversion$1 = class Conversion {
|
|
|
2456
2488
|
? UrlParameter.Metadata + this._encodeMetadata()
|
|
2457
2489
|
: ''));
|
|
2458
2490
|
}
|
|
2491
|
+
/**
|
|
2492
|
+
* @private
|
|
2493
|
+
* @method metadata - an internal getter for a metadata of conversion
|
|
2494
|
+
* */
|
|
2459
2495
|
get _metadata() {
|
|
2460
2496
|
return this.metadata;
|
|
2461
2497
|
}
|
|
2498
|
+
/**
|
|
2499
|
+
* @private
|
|
2500
|
+
* @method metadata - an internal setter for setting metadata of conversion
|
|
2501
|
+
* @param {number} value - an index value
|
|
2502
|
+
* */
|
|
2503
|
+
set _metadata(value) {
|
|
2504
|
+
this.metadata = value;
|
|
2505
|
+
}
|
|
2462
2506
|
get data() {
|
|
2463
2507
|
var _a;
|
|
2464
2508
|
return {
|
|
@@ -2892,7 +2936,10 @@ class VisitsData {
|
|
|
2892
2936
|
constructor(visits) {
|
|
2893
2937
|
this.status = exports.TrackingStatus.Sent;
|
|
2894
2938
|
this.visits = visits;
|
|
2895
|
-
this.
|
|
2939
|
+
this._visitNumber = visits.length ? visits.length - 1 : 0;
|
|
2940
|
+
}
|
|
2941
|
+
get visitNumber() {
|
|
2942
|
+
return this._visitNumber;
|
|
2896
2943
|
}
|
|
2897
2944
|
get url() {
|
|
2898
2945
|
return '';
|
|
@@ -2900,7 +2947,7 @@ class VisitsData {
|
|
|
2900
2947
|
get data() {
|
|
2901
2948
|
return {
|
|
2902
2949
|
visits: this.visits,
|
|
2903
|
-
visitNumber: this.
|
|
2950
|
+
visitNumber: this._visitNumber,
|
|
2904
2951
|
type: exports.KameleoonData.VisitsData,
|
|
2905
2952
|
status: this.status,
|
|
2906
2953
|
};
|
|
@@ -2917,11 +2964,11 @@ class VisitsData {
|
|
|
2917
2964
|
list: this.visits,
|
|
2918
2965
|
visit,
|
|
2919
2966
|
});
|
|
2920
|
-
this.
|
|
2967
|
+
this._visitNumber = this.visits.length ? this.visits.length - 1 : 0;
|
|
2921
2968
|
}
|
|
2922
2969
|
updateVisitNumber(visitNumber) {
|
|
2923
|
-
if (visitNumber > this.
|
|
2924
|
-
this.
|
|
2970
|
+
if (visitNumber > this._visitNumber) {
|
|
2971
|
+
this._visitNumber = visitNumber;
|
|
2925
2972
|
}
|
|
2926
2973
|
}
|
|
2927
2974
|
}
|
|
@@ -3128,10 +3175,12 @@ class VisitProcessor {
|
|
|
3128
3175
|
timeLastActivity: (_a = visit.timeLastEvent) !== null && _a !== void 0 ? _a : visit.timeStarted,
|
|
3129
3176
|
};
|
|
3130
3177
|
}
|
|
3131
|
-
processVisitNumber(visit,
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3178
|
+
processVisitNumber(visit, visitOffset) {
|
|
3179
|
+
var _a, _b, _c;
|
|
3180
|
+
if (this.visitsData.visitNumber <= visitOffset &&
|
|
3181
|
+
((_a = visit.staticDataEvent) === null || _a === void 0 ? void 0 : _a.data.visitNumber)) {
|
|
3182
|
+
const visitNumber = (_c = (_b = visit.staticDataEvent) === null || _b === void 0 ? void 0 : _b.data.visitNumber) !== null && _c !== void 0 ? _c : 0;
|
|
3183
|
+
this.visitsData.updateVisitNumber(visitNumber + visitOffset);
|
|
3135
3184
|
}
|
|
3136
3185
|
}
|
|
3137
3186
|
processCbs(cbsData) {
|
|
@@ -3305,12 +3354,12 @@ class Parser {
|
|
|
3305
3354
|
}
|
|
3306
3355
|
if (currentVisit) {
|
|
3307
3356
|
visitProcessor.processVisit(currentVisit);
|
|
3308
|
-
visitProcessor.processVisitNumber(currentVisit,
|
|
3357
|
+
visitProcessor.processVisitNumber(currentVisit, 0);
|
|
3309
3358
|
}
|
|
3310
|
-
previousVisits === null || previousVisits === void 0 ? void 0 : previousVisits.forEach((visit) => {
|
|
3359
|
+
previousVisits === null || previousVisits === void 0 ? void 0 : previousVisits.forEach((visit, index) => {
|
|
3311
3360
|
visitProcessor.processVisit(visit);
|
|
3312
3361
|
visitProcessor.processVisitsData(visit);
|
|
3313
|
-
visitProcessor.processVisitNumber(visit,
|
|
3362
|
+
visitProcessor.processVisitNumber(visit, index + 1);
|
|
3314
3363
|
});
|
|
3315
3364
|
visitProcessor.processKcs(kcs);
|
|
3316
3365
|
visitProcessor.processCbs(cbs);
|
|
@@ -3551,7 +3600,7 @@ class DataProcessor {
|
|
|
3551
3600
|
this.cleanupInterval = cleanupInterval;
|
|
3552
3601
|
this.packageInfo = packageInfo;
|
|
3553
3602
|
}
|
|
3554
|
-
mutUpdateData({ infoData, visitorCode, mutData, dataItem, }) {
|
|
3603
|
+
mutUpdateData({ infoData, visitorCode, mutData, dataItem, extendTtl, }) {
|
|
3555
3604
|
let { visitorReference, data, isReference } = this.dereferenceData(mutData, visitorCode);
|
|
3556
3605
|
if (this.packageInfo.isServer &&
|
|
3557
3606
|
isReference &&
|
|
@@ -3562,9 +3611,12 @@ class DataProcessor {
|
|
|
3562
3611
|
delete mutData[visitorCode];
|
|
3563
3612
|
visitorReference = visitorCode;
|
|
3564
3613
|
}
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3614
|
+
let expirationTime;
|
|
3615
|
+
if (extendTtl) {
|
|
3616
|
+
expirationTime = this.cleanupInterval
|
|
3617
|
+
? Date.now() + this.cleanupInterval
|
|
3618
|
+
: 0;
|
|
3619
|
+
}
|
|
3568
3620
|
switch (dataItem.data.type) {
|
|
3569
3621
|
case exports.KameleoonData.CustomData: {
|
|
3570
3622
|
this.updateCustomData({
|
|
@@ -3919,13 +3971,17 @@ class DataProcessor {
|
|
|
3919
3971
|
return closestCleanupTime;
|
|
3920
3972
|
}
|
|
3921
3973
|
updateField({ key, value, data, visitorCode, expirationTime, }) {
|
|
3922
|
-
|
|
3974
|
+
var _a;
|
|
3975
|
+
const existing = data[visitorCode][key];
|
|
3976
|
+
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() });
|
|
3923
3977
|
}
|
|
3924
3978
|
createField({ key, value, data, visitorCode, expirationTime, }) {
|
|
3925
3979
|
data[visitorCode] = Object.assign(Object.assign({}, data[visitorCode]), { [key]: Object.assign(Object.assign({}, value), { expirationTime }) });
|
|
3926
3980
|
}
|
|
3927
3981
|
updateNestedField({ key, nestedKey, value, data, visitorCode, expirationTime, }) {
|
|
3928
|
-
|
|
3982
|
+
var _a;
|
|
3983
|
+
const existing = data[visitorCode][key][nestedKey];
|
|
3984
|
+
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() });
|
|
3929
3985
|
}
|
|
3930
3986
|
createNestedField({ key, nestedKey, value, data, visitorCode, expirationTime, }) {
|
|
3931
3987
|
var _a;
|
|
@@ -5191,15 +5247,7 @@ exports.KameleoonStorageKey = void 0;
|
|
|
5191
5247
|
KameleoonStorageKey["ForcedExperimentVariation"] = "kameleoonForcedExperimentVariation";
|
|
5192
5248
|
})(exports.KameleoonStorageKey || (exports.KameleoonStorageKey = {}));
|
|
5193
5249
|
const DEFAULT_CLIENT_CONFIGURATION = {
|
|
5194
|
-
data:
|
|
5195
|
-
customData: [],
|
|
5196
|
-
featureFlags: [],
|
|
5197
|
-
configuration: {
|
|
5198
|
-
realTimeUpdate: false,
|
|
5199
|
-
consentType: ConsentType.NotRequired,
|
|
5200
|
-
dataApiDomain: 'data.kameleoon.io',
|
|
5201
|
-
},
|
|
5202
|
-
},
|
|
5250
|
+
data: DEFAULT_DATA_FILE_CONFIGURATION,
|
|
5203
5251
|
lastUpdate: '',
|
|
5204
5252
|
};
|
|
5205
5253
|
// --- Note ---
|
|
@@ -5711,7 +5759,7 @@ class DataManager {
|
|
|
5711
5759
|
return resultData;
|
|
5712
5760
|
}
|
|
5713
5761
|
storeTrackedData(data) {
|
|
5714
|
-
this.storeData(data);
|
|
5762
|
+
this.storeData(data, false);
|
|
5715
5763
|
const infoResult = this.infoStorage.read();
|
|
5716
5764
|
if (!infoResult.ok) {
|
|
5717
5765
|
return;
|
|
@@ -5763,15 +5811,18 @@ class DataManager {
|
|
|
5763
5811
|
targetingData,
|
|
5764
5812
|
visitorCode: firstParameter,
|
|
5765
5813
|
kameleoonData: secondParameter,
|
|
5814
|
+
extendTtl: true,
|
|
5766
5815
|
});
|
|
5767
5816
|
}
|
|
5768
5817
|
else {
|
|
5769
5818
|
for (const [visitorCode, kameleoonData] of Object.entries(firstParameter)) {
|
|
5819
|
+
const extendTtl = typeof secondParameter[0] === 'boolean' ? secondParameter[0] : true;
|
|
5770
5820
|
this.mutUpdateTargetingData({
|
|
5771
5821
|
infoData,
|
|
5772
5822
|
targetingData,
|
|
5773
5823
|
visitorCode,
|
|
5774
5824
|
kameleoonData,
|
|
5825
|
+
extendTtl,
|
|
5775
5826
|
});
|
|
5776
5827
|
}
|
|
5777
5828
|
}
|
|
@@ -5888,8 +5939,8 @@ class DataManager {
|
|
|
5888
5939
|
}
|
|
5889
5940
|
return null;
|
|
5890
5941
|
}
|
|
5891
|
-
mutUpdateTargetingData({ infoData, visitorCode, kameleoonData, targetingData, }) {
|
|
5892
|
-
var _a;
|
|
5942
|
+
mutUpdateTargetingData({ infoData, visitorCode, kameleoonData, targetingData, extendTtl, }) {
|
|
5943
|
+
var _a, _b, _c;
|
|
5893
5944
|
for (const dataItem of kameleoonData) {
|
|
5894
5945
|
// process custom data
|
|
5895
5946
|
if (dataItem.data.type === exports.KameleoonData.CustomData) {
|
|
@@ -5905,16 +5956,21 @@ class DataManager {
|
|
|
5905
5956
|
}
|
|
5906
5957
|
// process metadata of conversions
|
|
5907
5958
|
if (dataItem.data.type === exports.KameleoonData.Conversion) {
|
|
5908
|
-
|
|
5959
|
+
const conversion = dataItem;
|
|
5960
|
+
if (((_b = (_a = conversion._metadata) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0) {
|
|
5961
|
+
conversion._metadata = (_c = conversion._metadata) === null || _c === void 0 ? void 0 : _c.filter((item) => this.trySetCustomDataIndexByName(item));
|
|
5962
|
+
}
|
|
5909
5963
|
}
|
|
5910
5964
|
const expirationTime = this.dataProcessor.mutUpdateData({
|
|
5911
5965
|
infoData,
|
|
5912
5966
|
visitorCode,
|
|
5913
5967
|
mutData: targetingData,
|
|
5914
5968
|
dataItem,
|
|
5969
|
+
extendTtl,
|
|
5915
5970
|
});
|
|
5916
5971
|
const nextCleanup = infoData.nextDataCleanup;
|
|
5917
|
-
if (!nextCleanup ||
|
|
5972
|
+
if (!nextCleanup ||
|
|
5973
|
+
(nextCleanup && expirationTime && expirationTime < nextCleanup)) {
|
|
5918
5974
|
infoData.nextDataCleanup = expirationTime;
|
|
5919
5975
|
}
|
|
5920
5976
|
if (dataItem.data.status === exports.TrackingStatus.Unsent) {
|
|
@@ -5946,7 +6002,9 @@ class DataManager {
|
|
|
5946
6002
|
var _a;
|
|
5947
6003
|
const { data } = customData;
|
|
5948
6004
|
const isDataValid = Boolean(data.value.length && data.value[0].length);
|
|
5949
|
-
this.trySetCustomDataIndexByName(customData)
|
|
6005
|
+
if (!this.trySetCustomDataIndexByName(customData)) {
|
|
6006
|
+
return false;
|
|
6007
|
+
}
|
|
5950
6008
|
if (data.index == CustomData$1.UNDEFINED_INDEX) {
|
|
5951
6009
|
data.index = customData.index;
|
|
5952
6010
|
}
|
|
@@ -5976,13 +6034,15 @@ class DataManager {
|
|
|
5976
6034
|
return true;
|
|
5977
6035
|
}
|
|
5978
6036
|
trySetCustomDataIndexByName(customData) {
|
|
5979
|
-
if (customData.index
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
6037
|
+
if (customData.index !== CustomData$1.UNDEFINED_INDEX)
|
|
6038
|
+
return true;
|
|
6039
|
+
if (!customData.name)
|
|
6040
|
+
return false;
|
|
6041
|
+
const cdIndex = this.customDataIndexByName.get(customData.name);
|
|
6042
|
+
if (cdIndex == null)
|
|
6043
|
+
return false;
|
|
6044
|
+
customData.index = cdIndex;
|
|
6045
|
+
return true;
|
|
5986
6046
|
}
|
|
5987
6047
|
get unsentDataVisitors() {
|
|
5988
6048
|
const infoResult = this.infoStorage.read();
|
|
@@ -7095,6 +7155,13 @@ class Hasher {
|
|
|
7095
7155
|
}
|
|
7096
7156
|
}
|
|
7097
7157
|
|
|
7158
|
+
var LegalConsent;
|
|
7159
|
+
(function (LegalConsent) {
|
|
7160
|
+
LegalConsent[LegalConsent["Unknown"] = 0] = "Unknown";
|
|
7161
|
+
LegalConsent[LegalConsent["Given"] = 1] = "Given";
|
|
7162
|
+
LegalConsent[LegalConsent["NotGiven"] = 2] = "NotGiven";
|
|
7163
|
+
})(LegalConsent || (LegalConsent = {}));
|
|
7164
|
+
|
|
7098
7165
|
class VariationConfiguration {
|
|
7099
7166
|
constructor(externalStorage, externalStorageForcedExperimentVariations, externalStorageForcedFeatureVariations, visitorCodeManager, clientConfiguration) {
|
|
7100
7167
|
this.storage = externalStorage;
|
|
@@ -7153,9 +7220,12 @@ class VariationConfiguration {
|
|
|
7153
7220
|
}
|
|
7154
7221
|
return buildExports.Ok(featureFlagVariations);
|
|
7155
7222
|
}
|
|
7156
|
-
getVariation({ visitorCode, visitorIdentifier, featureFlag, targetingData, packageInfo, clientConfiguration, dataManager, track = true, withAssignment = false, }) {
|
|
7223
|
+
getVariation({ visitorCode, visitorIdentifier, featureFlag, targetingData, packageInfo, clientConfiguration, dataManager, legalConsent, track = true, withAssignment = false, }) {
|
|
7157
7224
|
KameleoonLogger.debug `CALL: VariationConfiguration.getVariation(visitorCode: ${visitorCode}, visitorIdentifier: ${visitorIdentifier}, featureFlag: ${featureFlag}, targetingData: ${targetingData}, packageInfo: ${packageInfo}, clientConfiguration, dataManager, withAssignment: ${withAssignment})`;
|
|
7158
7225
|
const { rules, featureKey, id: featureFlagId, defaultVariationKey, } = featureFlag;
|
|
7226
|
+
const consent = clientConfiguration.isConsentRequired
|
|
7227
|
+
? legalConsent
|
|
7228
|
+
: LegalConsent.Given;
|
|
7159
7229
|
for (const rule of rules) {
|
|
7160
7230
|
const { segment, experimentId, id, exposition, respoolTime, variationByExposition, } = rule;
|
|
7161
7231
|
const forcedVariationData = this.getForcedExperimentVariation(visitorCode, rule.experimentId);
|
|
@@ -7202,6 +7272,16 @@ class VariationConfiguration {
|
|
|
7202
7272
|
});
|
|
7203
7273
|
KameleoonLogger.debug `Calculated ruleHash: ${ruleHash} for code: ${visitorIdentifier}`;
|
|
7204
7274
|
if (ruleHash <= exposition) {
|
|
7275
|
+
// Checking if the evaluation is blocked due to the consent policy
|
|
7276
|
+
if (consent == LegalConsent.NotGiven &&
|
|
7277
|
+
rule.type == RuleType.EXPERIMENTATION) {
|
|
7278
|
+
const behaviour = clientConfiguration.consentBlockingBehaviour;
|
|
7279
|
+
if (behaviour == ConsentBlockingBehaviour.PartiallyBlocked) {
|
|
7280
|
+
break;
|
|
7281
|
+
}
|
|
7282
|
+
return buildExports.Err(new KameleoonError(exports.KameleoonException.FeatureFlagEnvironmentDisabled, `Evaluation of ${rule} is blocked because consent is not provided for visitor '${visitorCode}'`));
|
|
7283
|
+
}
|
|
7284
|
+
// evaluate with CB scores if applicable
|
|
7205
7285
|
let variation = this.evaluateCBScores(rule, visitorIdentifier, targetingData);
|
|
7206
7286
|
if (!variation) {
|
|
7207
7287
|
const variationHash = Hasher.getHashDouble({
|
|
@@ -7563,7 +7643,6 @@ class KameleoonEventSource {
|
|
|
7563
7643
|
const VISITOR_CODE_LENGTH = 16;
|
|
7564
7644
|
const VISITOR_CODE_MAX_LENGTH = 255;
|
|
7565
7645
|
const DEFAULT_MAX_AGE = 60 * 60 * 24 * 365;
|
|
7566
|
-
const ZERO_MAX_AGE = 0;
|
|
7567
7646
|
const PATH = '/';
|
|
7568
7647
|
|
|
7569
7648
|
/**
|
|
@@ -8031,7 +8110,7 @@ class Tracker {
|
|
|
8031
8110
|
this.dataManager.storeTrackedData(updatedData);
|
|
8032
8111
|
}
|
|
8033
8112
|
else {
|
|
8034
|
-
this.dataManager.storeData(updatedData);
|
|
8113
|
+
this.dataManager.storeData(updatedData, false);
|
|
8035
8114
|
}
|
|
8036
8115
|
}
|
|
8037
8116
|
getUnsentVisitorData(visitorCode, isConsentProvided) {
|
|
@@ -8383,16 +8462,23 @@ class KameleoonClient {
|
|
|
8383
8462
|
const variations = new Map();
|
|
8384
8463
|
const featureFlags = this.clientConfiguration.featureFlags;
|
|
8385
8464
|
for (const featureFlag of featureFlags.values()) {
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
8390
|
-
|
|
8391
|
-
|
|
8392
|
-
if (
|
|
8465
|
+
try {
|
|
8466
|
+
const variation = this._getFeatureVariation({
|
|
8467
|
+
visitorCode,
|
|
8468
|
+
featureKey: featureFlag.featureKey,
|
|
8469
|
+
track,
|
|
8470
|
+
});
|
|
8471
|
+
if (variation.ok &&
|
|
8472
|
+
(!onlyActive || variation.data.key !== OFF_VARIATION_KEY)) {
|
|
8393
8473
|
variations.set(featureFlag.featureKey, variation.data);
|
|
8394
8474
|
}
|
|
8395
8475
|
}
|
|
8476
|
+
catch (err) {
|
|
8477
|
+
if (err instanceof KameleoonError &&
|
|
8478
|
+
err.type !== exports.KameleoonException.FeatureFlagEnvironmentDisabled) {
|
|
8479
|
+
throw err;
|
|
8480
|
+
}
|
|
8481
|
+
}
|
|
8396
8482
|
}
|
|
8397
8483
|
KameleoonLogger.info `RETURN: KameleoonClient.getVariations(visitorCode: ${visitorCode}, onlyActive: ${onlyActive}, track: ${track}) -> (variations: ${variations})`;
|
|
8398
8484
|
return variations;
|
|
@@ -8712,25 +8798,16 @@ class KameleoonClient {
|
|
|
8712
8798
|
path: PATH,
|
|
8713
8799
|
});
|
|
8714
8800
|
}
|
|
8715
|
-
else {
|
|
8716
|
-
if (this.visitorCodeManager.consentRequired) {
|
|
8717
|
-
setData({
|
|
8718
|
-
visitorCode: '',
|
|
8719
|
-
key: exports.KameleoonStorageKey.VisitorCode,
|
|
8720
|
-
maxAge: ZERO_MAX_AGE,
|
|
8721
|
-
path: PATH,
|
|
8722
|
-
});
|
|
8723
|
-
}
|
|
8724
|
-
}
|
|
8725
8801
|
KameleoonLogger.info `RETURN: KameleoonClient.setUserConsent(visitorCode: ${visitorCode}, consent: ${consent}, setData: ${setData})`;
|
|
8726
8802
|
}
|
|
8727
8803
|
updateConsentData(visitorCode, consent) {
|
|
8728
8804
|
const readResult = this.consentDataStorage.read();
|
|
8805
|
+
const legalConsent = consent ? LegalConsent.Given : LegalConsent.NotGiven;
|
|
8729
8806
|
if (!readResult.ok) {
|
|
8730
8807
|
if (readResult.error.type === exports.KameleoonException.StorageEmpty) {
|
|
8731
8808
|
this.consentDataStorage.write({
|
|
8732
8809
|
[visitorCode]: {
|
|
8733
|
-
consent,
|
|
8810
|
+
consent: legalConsent,
|
|
8734
8811
|
},
|
|
8735
8812
|
});
|
|
8736
8813
|
}
|
|
@@ -8738,28 +8815,36 @@ class KameleoonClient {
|
|
|
8738
8815
|
}
|
|
8739
8816
|
const data = readResult.data;
|
|
8740
8817
|
data[visitorCode] = {
|
|
8741
|
-
consent,
|
|
8818
|
+
consent: legalConsent,
|
|
8742
8819
|
};
|
|
8743
8820
|
this.consentDataStorage.write(data);
|
|
8744
8821
|
}
|
|
8822
|
+
getLegalConsent(visitorCode) {
|
|
8823
|
+
KameleoonLogger.debug `CALL: KameleoonClient.getLegalConsent(visitorCode: ${visitorCode})`;
|
|
8824
|
+
let legalConsent;
|
|
8825
|
+
const consentDataResult = this.consentDataStorage.read();
|
|
8826
|
+
legalConsent = consentDataResult.ok
|
|
8827
|
+
? this.extractLegalConsent(consentDataResult.data[visitorCode])
|
|
8828
|
+
: LegalConsent.Unknown;
|
|
8829
|
+
KameleoonLogger.debug `RETURN: KameleoonClient.getLegalConsent(visitorCode: ${visitorCode}) -> (legalConsent: ${legalConsent})`;
|
|
8830
|
+
return legalConsent;
|
|
8831
|
+
}
|
|
8832
|
+
extractLegalConsent(consentData) {
|
|
8833
|
+
if (consentData === undefined)
|
|
8834
|
+
return LegalConsent.Unknown;
|
|
8835
|
+
if (typeof consentData === 'boolean') {
|
|
8836
|
+
return consentData ? LegalConsent.Given : LegalConsent.NotGiven;
|
|
8837
|
+
}
|
|
8838
|
+
const value = consentData.consent;
|
|
8839
|
+
if (typeof value === 'boolean')
|
|
8840
|
+
return value ? LegalConsent.Given : LegalConsent.NotGiven;
|
|
8841
|
+
return value;
|
|
8842
|
+
}
|
|
8745
8843
|
_isConsentProvided(visitorCode) {
|
|
8746
8844
|
KameleoonLogger.debug `CALL: KameleoonClient._isConsentProvided(visitorCode: ${visitorCode})`;
|
|
8747
8845
|
const { isConsentRequired } = this.clientConfiguration;
|
|
8748
|
-
const
|
|
8749
|
-
|
|
8750
|
-
if (!isConsentRequired) {
|
|
8751
|
-
isConsentProvided = true;
|
|
8752
|
-
}
|
|
8753
|
-
else if (consentDataResult.ok) {
|
|
8754
|
-
const consentData = consentDataResult.data[visitorCode];
|
|
8755
|
-
// for consistency with the old data in the storage
|
|
8756
|
-
if (typeof consentData === 'boolean') {
|
|
8757
|
-
isConsentProvided = consentData;
|
|
8758
|
-
}
|
|
8759
|
-
else {
|
|
8760
|
-
isConsentProvided = consentData && consentData.consent;
|
|
8761
|
-
}
|
|
8762
|
-
}
|
|
8846
|
+
const isConsentProvided = !isConsentRequired ||
|
|
8847
|
+
this.getLegalConsent(visitorCode) == LegalConsent.Given;
|
|
8763
8848
|
KameleoonLogger.debug `RETURN: KameleoonClient._isConsentProvided(visitorCode: ${visitorCode}) -> (isConsentProvided: ${isConsentProvided})`;
|
|
8764
8849
|
return isConsentProvided;
|
|
8765
8850
|
}
|
|
@@ -8787,22 +8872,32 @@ class KameleoonClient {
|
|
|
8787
8872
|
if (!featureFlag.environmentEnabled) {
|
|
8788
8873
|
continue;
|
|
8789
8874
|
}
|
|
8790
|
-
|
|
8791
|
-
|
|
8792
|
-
|
|
8793
|
-
|
|
8794
|
-
|
|
8795
|
-
|
|
8796
|
-
if (evalExp.variationKey !== OFF_VARIATION_KEY) {
|
|
8797
|
-
activeVariations.push({
|
|
8798
|
-
variationKey: evalExp.variationKey,
|
|
8799
|
-
variationId: evalExp.variationId,
|
|
8800
|
-
experimentId: evalExp.experimentId,
|
|
8801
|
-
featureFlagId: featureFlag.id,
|
|
8802
|
-
featureKey: featureFlag.featureKey,
|
|
8803
|
-
rule: null,
|
|
8804
|
-
isTargetedRule: evalExp.ruleType === RuleType.TARGETED_DELIVERY,
|
|
8875
|
+
try {
|
|
8876
|
+
const evalExp = this._evaluate({
|
|
8877
|
+
visitorCode,
|
|
8878
|
+
featureFlag,
|
|
8879
|
+
track: false,
|
|
8880
|
+
save: false,
|
|
8805
8881
|
});
|
|
8882
|
+
if (evalExp.variationKey !== OFF_VARIATION_KEY) {
|
|
8883
|
+
activeVariations.push({
|
|
8884
|
+
variationKey: evalExp.variationKey,
|
|
8885
|
+
variationId: evalExp.variationId,
|
|
8886
|
+
experimentId: evalExp.experimentId,
|
|
8887
|
+
featureFlagId: featureFlag.id,
|
|
8888
|
+
featureKey: featureFlag.featureKey,
|
|
8889
|
+
rule: null,
|
|
8890
|
+
isTargetedRule: evalExp.ruleType === RuleType.TARGETED_DELIVERY,
|
|
8891
|
+
});
|
|
8892
|
+
}
|
|
8893
|
+
}
|
|
8894
|
+
catch (err) {
|
|
8895
|
+
if (err instanceof KameleoonError) {
|
|
8896
|
+
if (err.type != exports.KameleoonException.FeatureFlagEnvironmentDisabled) {
|
|
8897
|
+
KameleoonLogger.error `Unexpected error: ${err}`;
|
|
8898
|
+
}
|
|
8899
|
+
continue;
|
|
8900
|
+
}
|
|
8806
8901
|
}
|
|
8807
8902
|
}
|
|
8808
8903
|
KameleoonLogger.debug `RETURN: KameleoonClient._getActiveFeatureVariations(visitorCode: ${visitorCode}) -> (activeVariations: ${activeVariations})`;
|
|
@@ -8823,6 +8918,7 @@ class KameleoonClient {
|
|
|
8823
8918
|
else if (this._isVisitorNotInHoldout(visitorCode, track, save, featureFlag, visitorData) &&
|
|
8824
8919
|
this._isFFUnrestrictedByMEGroup(visitorCode, featureFlag, visitorData)) {
|
|
8825
8920
|
const visitorIdentifier = this._getCodeForHash(visitorCode, featureFlag.bucketingCustomDataIndex, visitorData);
|
|
8921
|
+
const legalConsent = this.getLegalConsent(visitorCode);
|
|
8826
8922
|
const variationData = this.variationConfiguration
|
|
8827
8923
|
.getVariation({
|
|
8828
8924
|
visitorCode,
|
|
@@ -8834,6 +8930,7 @@ class KameleoonClient {
|
|
|
8834
8930
|
clientConfiguration: this.clientConfiguration,
|
|
8835
8931
|
dataManager: this.dataManager,
|
|
8836
8932
|
packageInfo: this.externalPackageInfo,
|
|
8933
|
+
legalConsent,
|
|
8837
8934
|
})
|
|
8838
8935
|
.throw();
|
|
8839
8936
|
evalExp =
|
|
@@ -8952,6 +9049,16 @@ class KameleoonClient {
|
|
|
8952
9049
|
}
|
|
8953
9050
|
KameleoonLogger.debug `CALL: KameleoonClient._isVisitorNotInHoldout(visitorCode: ${visitorCode}, track: ${track}, save: ${save}, featureFlag: ${featureFlag}, visitorData: ${visitorData})`;
|
|
8954
9051
|
let isNotInHoldout = true;
|
|
9052
|
+
// Checking if the evaluation is blocked due to the consent policy
|
|
9053
|
+
const legalConsent = this.clientConfiguration.isConsentRequired
|
|
9054
|
+
? this.getLegalConsent(visitorCode)
|
|
9055
|
+
: LegalConsent.Given;
|
|
9056
|
+
if (legalConsent == LegalConsent.NotGiven) {
|
|
9057
|
+
const behaviour = this.clientConfiguration.consentBlockingBehaviour;
|
|
9058
|
+
if (behaviour == ConsentBlockingBehaviour.CompletelyBlocked) {
|
|
9059
|
+
throw new KameleoonError(exports.KameleoonException.FeatureFlagEnvironmentDisabled, `Evaluation of holdout is blocked because consent is not provided for visitor '${visitorCode}'`);
|
|
9060
|
+
}
|
|
9061
|
+
}
|
|
8955
9062
|
const codeForHash = this._getCodeForHash(visitorCode, featureFlag === null || featureFlag === void 0 ? void 0 : featureFlag.bucketingCustomDataIndex, visitorData);
|
|
8956
9063
|
const holdoutHash = Hasher.getHashDouble({
|
|
8957
9064
|
visitorIdentifier: codeForHash,
|