@splitsoftware/splitio-commons 1.11.0 → 1.12.0-rc.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/CHANGES.txt +15 -9
- package/cjs/evaluator/index.js +19 -3
- package/cjs/logger/constants.js +6 -4
- package/cjs/logger/messages/warn.js +5 -3
- package/cjs/sdkClient/client.js +19 -16
- package/cjs/sdkClient/clientInputValidation.js +16 -16
- package/cjs/sdkFactory/index.js +1 -1
- package/cjs/sdkManager/index.js +14 -13
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +3 -10
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +2 -10
- package/cjs/storages/inRedis/RedisAdapter.js +32 -13
- package/cjs/storages/inRedis/SegmentsCacheInRedis.js +2 -2
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +39 -22
- package/cjs/storages/inRedis/index.js +1 -1
- package/cjs/storages/pluggable/SplitsCachePluggable.js +28 -11
- package/cjs/storages/pluggable/index.js +1 -1
- package/cjs/utils/constants/index.js +16 -2
- package/cjs/utils/inputValidation/index.js +5 -5
- package/cjs/utils/inputValidation/{splitExistance.js → splitExistence.js} +3 -3
- package/cjs/utils/inputValidation/{trafficTypeExistance.js → trafficTypeExistence.js} +6 -6
- package/cjs/utils/lang/sets.js +11 -1
- package/cjs/utils/settingsValidation/index.js +1 -1
- package/cjs/utils/settingsValidation/splitFilters.js +25 -17
- package/esm/evaluator/index.js +20 -4
- package/esm/logger/constants.js +4 -2
- package/esm/logger/messages/warn.js +5 -3
- package/esm/sdkClient/client.js +20 -17
- package/esm/sdkClient/clientInputValidation.js +18 -18
- package/esm/sdkFactory/index.js +1 -1
- package/esm/sdkManager/index.js +11 -10
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +4 -11
- package/esm/storages/inMemory/SplitsCacheInMemory.js +3 -11
- package/esm/storages/inRedis/RedisAdapter.js +32 -13
- package/esm/storages/inRedis/SegmentsCacheInRedis.js +2 -2
- package/esm/storages/inRedis/SplitsCacheInRedis.js +40 -23
- package/esm/storages/inRedis/index.js +1 -1
- package/esm/storages/pluggable/SplitsCachePluggable.js +29 -12
- package/esm/storages/pluggable/index.js +1 -1
- package/esm/utils/constants/index.js +14 -0
- package/esm/utils/inputValidation/index.js +2 -2
- package/esm/utils/inputValidation/{splitExistance.js → splitExistence.js} +1 -1
- package/esm/utils/inputValidation/{trafficTypeExistance.js → trafficTypeExistence.js} +4 -4
- package/esm/utils/lang/sets.js +9 -0
- package/esm/utils/settingsValidation/index.js +1 -1
- package/esm/utils/settingsValidation/splitFilters.js +17 -9
- package/package.json +1 -1
- package/src/evaluator/index.ts +24 -4
- package/src/logger/constants.ts +4 -2
- package/src/logger/messages/warn.ts +9 -7
- package/src/sdkClient/client.ts +18 -18
- package/src/sdkClient/clientInputValidation.ts +18 -18
- package/src/sdkFactory/index.ts +1 -1
- package/src/sdkFactory/types.ts +3 -7
- package/src/sdkManager/index.ts +14 -14
- package/src/storages/AbstractSplitsCacheAsync.ts +1 -1
- package/src/storages/AbstractSplitsCacheSync.ts +1 -1
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +8 -15
- package/src/storages/inMemory/SplitsCacheInMemory.ts +6 -14
- package/src/storages/inRedis/EventsCacheInRedis.ts +3 -3
- package/src/storages/inRedis/ImpressionCountsCacheInRedis.ts +3 -3
- package/src/storages/inRedis/ImpressionsCacheInRedis.ts +3 -3
- package/src/storages/inRedis/RedisAdapter.ts +38 -16
- package/src/storages/inRedis/SegmentsCacheInRedis.ts +5 -5
- package/src/storages/inRedis/SplitsCacheInRedis.ts +49 -28
- package/src/storages/inRedis/TelemetryCacheInRedis.ts +2 -2
- package/src/storages/inRedis/UniqueKeysCacheInRedis.ts +3 -3
- package/src/storages/inRedis/index.ts +1 -1
- package/src/storages/pluggable/SplitsCachePluggable.ts +35 -13
- package/src/storages/pluggable/index.ts +1 -1
- package/src/storages/types.ts +5 -5
- package/src/trackers/impressionObserver/utils.ts +1 -1
- package/src/types.ts +0 -2
- package/src/utils/constants/index.ts +16 -0
- package/src/utils/inputValidation/index.ts +2 -2
- package/src/utils/inputValidation/{splitExistance.ts → splitExistence.ts} +1 -1
- package/src/utils/inputValidation/{trafficTypeExistance.ts → trafficTypeExistence.ts} +4 -4
- package/src/utils/lang/sets.ts +9 -1
- package/src/utils/redis/RedisMock.ts +1 -3
- package/src/utils/settingsValidation/index.ts +1 -1
- package/src/utils/settingsValidation/splitFilters.ts +19 -11
- package/types/evaluator/index.d.ts +1 -1
- package/types/logger/constants.d.ts +4 -2
- package/types/sdkClient/identity.d.ts +6 -0
- package/types/sdkFactory/types.d.ts +3 -3
- package/types/sdkManager/index.d.ts +2 -3
- package/types/storages/AbstractSplitsCacheAsync.d.ts +1 -1
- package/types/storages/AbstractSplitsCacheSync.d.ts +1 -1
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +1 -1
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +1 -1
- package/types/storages/inRedis/EventsCacheInRedis.d.ts +2 -2
- package/types/storages/inRedis/ImpressionCountsCacheInRedis.d.ts +3 -2
- package/types/storages/inRedis/ImpressionsCacheInRedis.d.ts +2 -2
- package/types/storages/inRedis/RedisAdapter.d.ts +1 -1
- package/types/storages/inRedis/SegmentsCacheInRedis.d.ts +3 -3
- package/types/storages/inRedis/SplitsCacheInRedis.d.ts +10 -14
- package/types/storages/inRedis/TelemetryCacheInRedis.d.ts +2 -2
- package/types/storages/inRedis/{uniqueKeysCacheInRedis.d.ts → UniqueKeysCacheInRedis.d.ts} +3 -2
- package/types/storages/pluggable/SplitsCachePluggable.d.ts +10 -9
- package/types/storages/types.d.ts +5 -5
- package/types/trackers/impressionObserver/utils.d.ts +1 -1
- package/types/types.d.ts +0 -2
- package/types/utils/constants/index.d.ts +12 -0
- package/types/utils/inputValidation/index.d.ts +2 -2
- package/types/utils/inputValidation/sdkKey.d.ts +7 -0
- package/types/utils/inputValidation/splitExistence.d.ts +7 -0
- package/types/utils/inputValidation/trafficTypeExistence.d.ts +9 -0
- package/types/utils/lang/sets.d.ts +1 -0
- package/types/utils/settingsValidation/splitFilters.d.ts +3 -2
- package/types/myLogger.d.ts +0 -5
- package/types/sdkClient/types.d.ts +0 -18
- package/types/storages/inMemory/CountsCacheInMemory.d.ts +0 -20
- package/types/storages/inMemory/LatenciesCacheInMemory.d.ts +0 -20
- package/types/storages/inRedis/CountsCacheInRedis.d.ts +0 -9
- package/types/storages/inRedis/LatenciesCacheInRedis.d.ts +0 -9
- package/types/storages/metadataBuilder.d.ts +0 -3
- package/types/sync/offline/LocalhostFromFile.d.ts +0 -2
- package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +0 -2
- package/types/sync/offline/updaters/splitChangesUpdater.d.ts +0 -0
- package/types/sync/submitters/eventsSyncTask.d.ts +0 -8
- package/types/sync/submitters/impressionCountsSubmitterInRedis.d.ts +0 -5
- package/types/sync/submitters/impressionCountsSyncTask.d.ts +0 -13
- package/types/sync/submitters/impressionsSyncTask.d.ts +0 -14
- package/types/sync/submitters/metricsSyncTask.d.ts +0 -12
- package/types/sync/submitters/submitterSyncTask.d.ts +0 -10
- package/types/sync/submitters/uniqueKeysSubmitterInRedis.d.ts +0 -5
- package/types/sync/syncTaskComposite.d.ts +0 -5
- package/types/trackers/filter/bloomFilter.d.ts +0 -10
- package/types/trackers/filter/dictionaryFilter.d.ts +0 -8
- package/types/trackers/filter/types.d.ts +0 -5
- package/types/utils/timeTracker/index.d.ts +0 -70
- /package/types/storages/inMemory/{uniqueKeysCacheInMemory.d.ts → UniqueKeysCacheInMemory.d.ts} +0 -0
- /package/types/storages/inMemory/{uniqueKeysCacheInMemoryCS.d.ts → UniqueKeysCacheInMemoryCS.d.ts} +0 -0
|
@@ -54,9 +54,9 @@ var SegmentsCacheInRedis = /** @class */ (function () {
|
|
|
54
54
|
SegmentsCacheInRedis.prototype.getRegisteredSegments = function () {
|
|
55
55
|
return this.redis.smembers(this.keys.buildRegisteredSegmentsKey());
|
|
56
56
|
};
|
|
57
|
-
// @TODO remove
|
|
57
|
+
// @TODO remove or implement. It is not being used.
|
|
58
58
|
SegmentsCacheInRedis.prototype.clear = function () {
|
|
59
|
-
return
|
|
59
|
+
return Promise.resolve();
|
|
60
60
|
};
|
|
61
61
|
return SegmentsCacheInRedis;
|
|
62
62
|
}());
|
|
@@ -5,6 +5,7 @@ var tslib_1 = require("tslib");
|
|
|
5
5
|
var lang_1 = require("../../utils/lang");
|
|
6
6
|
var constants_1 = require("./constants");
|
|
7
7
|
var AbstractSplitsCacheAsync_1 = require("../AbstractSplitsCacheAsync");
|
|
8
|
+
var sets_1 = require("../../utils/lang/sets");
|
|
8
9
|
/**
|
|
9
10
|
* Discard errors for an answer of multiple operations.
|
|
10
11
|
*/
|
|
@@ -21,11 +22,12 @@ function processPipelineAnswer(results) {
|
|
|
21
22
|
*/
|
|
22
23
|
var SplitsCacheInRedis = /** @class */ (function (_super) {
|
|
23
24
|
(0, tslib_1.__extends)(SplitsCacheInRedis, _super);
|
|
24
|
-
function SplitsCacheInRedis(log, keys, redis) {
|
|
25
|
+
function SplitsCacheInRedis(log, keys, redis, splitFiltersValidation) {
|
|
25
26
|
var _this = _super.call(this) || this;
|
|
26
27
|
_this.log = log;
|
|
27
28
|
_this.redis = redis;
|
|
28
29
|
_this.keys = keys;
|
|
30
|
+
_this.flagSetsFilter = splitFiltersValidation ? splitFiltersValidation.groupedFilters.bySet : [];
|
|
29
31
|
// There is no need to listen for redis 'error' event, because in that case ioredis calls will be rejected and handled by redis storage adapters.
|
|
30
32
|
// But it is done just to avoid getting the ioredis message `Unhandled error event`.
|
|
31
33
|
_this.redis.on('error', function (e) {
|
|
@@ -48,6 +50,18 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
|
|
|
48
50
|
var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
|
|
49
51
|
return this.redis.incr(ttKey);
|
|
50
52
|
};
|
|
53
|
+
SplitsCacheInRedis.prototype._updateFlagSets = function (featureFlagName, flagSetsOfRemovedFlag, flagSetsOfAddedFlag) {
|
|
54
|
+
var _this = this;
|
|
55
|
+
var removeFromFlagSets = (0, sets_1.returnDifference)(flagSetsOfRemovedFlag, flagSetsOfAddedFlag);
|
|
56
|
+
var addToFlagSets = (0, sets_1.returnDifference)(flagSetsOfAddedFlag, flagSetsOfRemovedFlag);
|
|
57
|
+
if (this.flagSetsFilter.length > 0) {
|
|
58
|
+
addToFlagSets = addToFlagSets.filter(function (flagSet) {
|
|
59
|
+
return _this.flagSetsFilter.some(function (filterFlagSet) { return filterFlagSet === flagSet; });
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
var items = [featureFlagName];
|
|
63
|
+
return Promise.all((0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], removeFromFlagSets.map(function (flagSetName) { return _this.redis.srem(_this.keys.buildFlagSetKey(flagSetName), items); }), true), addToFlagSets.map(function (flagSetName) { return _this.redis.sadd(_this.keys.buildFlagSetKey(flagSetName), items); }), true));
|
|
64
|
+
};
|
|
51
65
|
/**
|
|
52
66
|
* Add a given split.
|
|
53
67
|
* The returned promise is resolved when the operation success
|
|
@@ -57,16 +71,16 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
|
|
|
57
71
|
var _this = this;
|
|
58
72
|
var splitKey = this.keys.buildSplitKey(name);
|
|
59
73
|
return this.redis.get(splitKey).then(function (splitFromStorage) {
|
|
60
|
-
// handling parsing
|
|
61
|
-
var parsedPreviousSplit,
|
|
74
|
+
// handling parsing error
|
|
75
|
+
var parsedPreviousSplit, stringifiedNewSplit;
|
|
62
76
|
try {
|
|
63
77
|
parsedPreviousSplit = splitFromStorage ? JSON.parse(splitFromStorage) : undefined;
|
|
64
|
-
|
|
78
|
+
stringifiedNewSplit = JSON.stringify(split);
|
|
65
79
|
}
|
|
66
80
|
catch (e) {
|
|
67
81
|
throw new Error('Error parsing feature flag definition: ' + e);
|
|
68
82
|
}
|
|
69
|
-
return _this.redis.set(splitKey,
|
|
83
|
+
return _this.redis.set(splitKey, stringifiedNewSplit).then(function () {
|
|
70
84
|
// avoid unnecessary increment/decrement operations
|
|
71
85
|
if (parsedPreviousSplit && parsedPreviousSplit.trafficTypeName === split.trafficTypeName)
|
|
72
86
|
return;
|
|
@@ -75,7 +89,7 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
|
|
|
75
89
|
if (parsedPreviousSplit)
|
|
76
90
|
return _this._decrementCounts(parsedPreviousSplit);
|
|
77
91
|
});
|
|
78
|
-
});
|
|
92
|
+
}).then(function () { return _this._updateFlagSets(name, parsedPreviousSplit && parsedPreviousSplit.sets, split.sets); });
|
|
79
93
|
}).then(function () { return true; });
|
|
80
94
|
};
|
|
81
95
|
/**
|
|
@@ -96,8 +110,9 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
|
|
|
96
110
|
var _this = this;
|
|
97
111
|
return this.getSplit(name).then(function (split) {
|
|
98
112
|
if (split) {
|
|
99
|
-
_this._decrementCounts(split);
|
|
113
|
+
return _this._decrementCounts(split).then(function () { return _this._updateFlagSets(name, split.sets); });
|
|
100
114
|
}
|
|
115
|
+
}).then(function () {
|
|
101
116
|
return _this.redis.del(_this.keys.buildSplitKey(name));
|
|
102
117
|
});
|
|
103
118
|
};
|
|
@@ -172,14 +187,20 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
|
|
|
172
187
|
return this.redis.keys(this.keys.searchPatternForSplitKeys()).then(function (listOfKeys) { return listOfKeys.map(_this.keys.extractKey); });
|
|
173
188
|
};
|
|
174
189
|
/**
|
|
175
|
-
* Get list of
|
|
176
|
-
* The returned promise is resolved with the list of
|
|
177
|
-
* or rejected if
|
|
178
|
-
* @todo this is a no-op method to be implemented
|
|
190
|
+
* Get list of feature flag names related to a given list of flag set names.
|
|
191
|
+
* The returned promise is resolved with the list of feature flag names per flag set,
|
|
192
|
+
* or rejected if the pipelined redis operation fails (e.g., timeout).
|
|
179
193
|
*/
|
|
180
|
-
SplitsCacheInRedis.prototype.getNamesByFlagSets = function () {
|
|
181
|
-
|
|
182
|
-
return
|
|
194
|
+
SplitsCacheInRedis.prototype.getNamesByFlagSets = function (flagSets) {
|
|
195
|
+
var _this = this;
|
|
196
|
+
return this.redis.pipeline(flagSets.map(function (flagSet) { return ['smembers', _this.keys.buildFlagSetKey(flagSet)]; })).exec()
|
|
197
|
+
.then(function (results) { return results.map(function (_a, index) {
|
|
198
|
+
var e = _a[0], value = _a[1];
|
|
199
|
+
if (e === null)
|
|
200
|
+
return value;
|
|
201
|
+
_this.log.error(constants_1.LOG_PREFIX + ("Could not read result from get members of flag set " + flagSets[index] + " due to an error: " + e));
|
|
202
|
+
}); })
|
|
203
|
+
.then(function (namesByFlagSets) { return namesByFlagSets.map(function (namesByFlagSet) { return new sets_1._Set(namesByFlagSet); }); });
|
|
183
204
|
};
|
|
184
205
|
/**
|
|
185
206
|
* Check traffic type existence.
|
|
@@ -196,24 +217,20 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
|
|
|
196
217
|
return false; // if entry doesn't exist, means that TT doesn't exist
|
|
197
218
|
ttCount = parseInt(ttCount, 10);
|
|
198
219
|
if (!(0, lang_1.isFiniteNumber)(ttCount) || ttCount < 0) {
|
|
199
|
-
_this.log.info(constants_1.LOG_PREFIX + ("Could not validate traffic type
|
|
220
|
+
_this.log.info(constants_1.LOG_PREFIX + ("Could not validate traffic type existence of " + trafficType + " due to data corruption of some sorts."));
|
|
200
221
|
return false;
|
|
201
222
|
}
|
|
202
223
|
return ttCount > 0;
|
|
203
224
|
})
|
|
204
225
|
.catch(function (e) {
|
|
205
|
-
_this.log.error(constants_1.LOG_PREFIX + ("Could not validate traffic type
|
|
226
|
+
_this.log.error(constants_1.LOG_PREFIX + ("Could not validate traffic type existence of " + trafficType + " due to an error: " + e + "."));
|
|
206
227
|
// If there is an error, bypass the validation so the event can get tracked.
|
|
207
228
|
return true;
|
|
208
229
|
});
|
|
209
230
|
};
|
|
210
|
-
|
|
211
|
-
* Delete everything in the current database.
|
|
212
|
-
*
|
|
213
|
-
* @NOTE documentation says it never fails.
|
|
214
|
-
*/
|
|
231
|
+
// @TODO remove or implement. It is not being used.
|
|
215
232
|
SplitsCacheInRedis.prototype.clear = function () {
|
|
216
|
-
return
|
|
233
|
+
return Promise.resolve();
|
|
217
234
|
};
|
|
218
235
|
/**
|
|
219
236
|
* Fetches multiple splits definitions.
|
|
@@ -39,7 +39,7 @@ function InRedisStorage(options) {
|
|
|
39
39
|
telemetry.recordConfig();
|
|
40
40
|
});
|
|
41
41
|
return {
|
|
42
|
-
splits: new SplitsCacheInRedis_1.SplitsCacheInRedis(log, keys, redisClient),
|
|
42
|
+
splits: new SplitsCacheInRedis_1.SplitsCacheInRedis(log, keys, redisClient, settings.sync.__splitFiltersValidation),
|
|
43
43
|
segments: new SegmentsCacheInRedis_1.SegmentsCacheInRedis(log, keys, redisClient),
|
|
44
44
|
impressions: new ImpressionsCacheInRedis_1.ImpressionsCacheInRedis(log, keys.buildImpressionsKey(), redisClient, metadata),
|
|
45
45
|
impressionCounts: impressionCountsCache,
|
|
@@ -5,6 +5,7 @@ var tslib_1 = require("tslib");
|
|
|
5
5
|
var lang_1 = require("../../utils/lang");
|
|
6
6
|
var constants_1 = require("./constants");
|
|
7
7
|
var AbstractSplitsCacheAsync_1 = require("../AbstractSplitsCacheAsync");
|
|
8
|
+
var sets_1 = require("../../utils/lang/sets");
|
|
8
9
|
/**
|
|
9
10
|
* ISplitsCacheAsync implementation for pluggable storages.
|
|
10
11
|
*/
|
|
@@ -16,11 +17,12 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
|
|
|
16
17
|
* @param keys Key builder.
|
|
17
18
|
* @param wrapper Adapted wrapper storage.
|
|
18
19
|
*/
|
|
19
|
-
function SplitsCachePluggable(log, keys, wrapper) {
|
|
20
|
+
function SplitsCachePluggable(log, keys, wrapper, splitFiltersValidation) {
|
|
20
21
|
var _this = _super.call(this) || this;
|
|
21
22
|
_this.log = log;
|
|
22
23
|
_this.keys = keys;
|
|
23
24
|
_this.wrapper = wrapper;
|
|
25
|
+
_this.flagSetsFilter = splitFiltersValidation ? splitFiltersValidation.groupedFilters.bySet : [];
|
|
24
26
|
return _this;
|
|
25
27
|
}
|
|
26
28
|
SplitsCachePluggable.prototype._decrementCounts = function (split) {
|
|
@@ -35,6 +37,18 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
|
|
|
35
37
|
var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
|
|
36
38
|
return this.wrapper.incr(ttKey);
|
|
37
39
|
};
|
|
40
|
+
SplitsCachePluggable.prototype._updateFlagSets = function (featureFlagName, flagSetsOfRemovedFlag, flagSetsOfAddedFlag) {
|
|
41
|
+
var _this = this;
|
|
42
|
+
var removeFromFlagSets = (0, sets_1.returnDifference)(flagSetsOfRemovedFlag, flagSetsOfAddedFlag);
|
|
43
|
+
var addToFlagSets = (0, sets_1.returnDifference)(flagSetsOfAddedFlag, flagSetsOfRemovedFlag);
|
|
44
|
+
if (this.flagSetsFilter.length > 0) {
|
|
45
|
+
addToFlagSets = addToFlagSets.filter(function (flagSet) {
|
|
46
|
+
return _this.flagSetsFilter.some(function (filterFlagSet) { return filterFlagSet === flagSet; });
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
var items = [featureFlagName];
|
|
50
|
+
return Promise.all((0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], removeFromFlagSets.map(function (flagSetName) { return _this.wrapper.removeItems(_this.keys.buildFlagSetKey(flagSetName), items); }), true), addToFlagSets.map(function (flagSetName) { return _this.wrapper.addItems(_this.keys.buildFlagSetKey(flagSetName), items); }), true));
|
|
51
|
+
};
|
|
38
52
|
/**
|
|
39
53
|
* Add a given split.
|
|
40
54
|
* The returned promise is resolved when the operation success
|
|
@@ -62,7 +76,7 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
|
|
|
62
76
|
if (parsedPreviousSplit)
|
|
63
77
|
return _this._decrementCounts(parsedPreviousSplit);
|
|
64
78
|
});
|
|
65
|
-
});
|
|
79
|
+
}).then(function () { return _this._updateFlagSets(name, parsedPreviousSplit && parsedPreviousSplit.sets, split.sets); });
|
|
66
80
|
}).then(function () { return true; });
|
|
67
81
|
};
|
|
68
82
|
/**
|
|
@@ -83,8 +97,9 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
|
|
|
83
97
|
var _this = this;
|
|
84
98
|
return this.getSplit(name).then(function (split) {
|
|
85
99
|
if (split) {
|
|
86
|
-
_this._decrementCounts(split);
|
|
100
|
+
return _this._decrementCounts(split).then(function () { return _this._updateFlagSets(name, split.sets); });
|
|
87
101
|
}
|
|
102
|
+
}).then(function () {
|
|
88
103
|
return _this.wrapper.del(_this.keys.buildSplitKey(name));
|
|
89
104
|
});
|
|
90
105
|
};
|
|
@@ -146,14 +161,16 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
|
|
|
146
161
|
return this.wrapper.getKeysByPrefix(this.keys.buildSplitKeyPrefix()).then(function (listOfKeys) { return listOfKeys.map(_this.keys.extractKey); });
|
|
147
162
|
};
|
|
148
163
|
/**
|
|
149
|
-
* Get list of
|
|
150
|
-
* The returned promise is resolved with the list of
|
|
151
|
-
*
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
164
|
+
* Get list of feature flag names related to a given list of flag set names.
|
|
165
|
+
* The returned promise is resolved with the list of feature flag names per flag set.
|
|
166
|
+
* It never rejects (If there is a wrapper error for some flag set, an empty set is returned for it).
|
|
167
|
+
*/
|
|
168
|
+
SplitsCachePluggable.prototype.getNamesByFlagSets = function (flagSets) {
|
|
169
|
+
var _this = this;
|
|
170
|
+
return Promise.all(flagSets.map(function (flagSet) {
|
|
171
|
+
var flagSetKey = _this.keys.buildFlagSetKey(flagSet);
|
|
172
|
+
return _this.wrapper.getItems(flagSetKey).catch(function () { return []; });
|
|
173
|
+
})).then(function (namesByFlagSets) { return namesByFlagSets.map(function (namesByFlagSet) { return new sets_1._Set(namesByFlagSet); }); });
|
|
157
174
|
};
|
|
158
175
|
/**
|
|
159
176
|
* Check traffic type existence.
|
|
@@ -92,7 +92,7 @@ function PluggableStorage(options) {
|
|
|
92
92
|
return e; // Propagate error for shared clients
|
|
93
93
|
});
|
|
94
94
|
return {
|
|
95
|
-
splits: new SplitsCachePluggable_1.SplitsCachePluggable(log, keys, wrapper),
|
|
95
|
+
splits: new SplitsCachePluggable_1.SplitsCachePluggable(log, keys, wrapper, settings.sync.__splitFiltersValidation),
|
|
96
96
|
segments: new SegmentsCachePluggable_1.SegmentsCachePluggable(log, keys, wrapper),
|
|
97
97
|
impressions: isPartialConsumer ? new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(impressionsQueueSize) : new ImpressionsCachePluggable_1.ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
|
|
98
98
|
impressionCounts: impressionCountsCache,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.PAUSED = exports.ENABLED = exports.DISABLED = exports.NON_REQUESTED = exports.REQUESTED = exports.POLLING = exports.STREAMING = exports.AUTH_REJECTION = exports.SYNC_MODE_UPDATE = exports.ABLY_ERROR = exports.TOKEN_REFRESH = exports.SSE_CONNECTION_ERROR = exports.STREAMING_STATUS = void 0;
|
|
3
|
+
exports.MY_SEGMENT = exports.SEGMENT = exports.TOKEN = exports.TELEMETRY = exports.EVENTS = exports.IMPRESSIONS_COUNT = exports.IMPRESSIONS = exports.SPLITS = exports.NONE_ENUM = exports.DEBUG_ENUM = exports.OPTIMIZED_ENUM = exports.CONSUMER_PARTIAL_ENUM = exports.CONSUMER_ENUM = exports.STANDALONE_ENUM = exports.DEDUPED = exports.DROPPED = exports.QUEUED = exports.NAMES_FN_LABEL = exports.SPLITS_FN_LABEL = exports.SPLIT_FN_LABEL = exports.TRACK_FN_LABEL = exports.GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS = exports.GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET = exports.GET_TREATMENTS_BY_FLAG_SETS = exports.GET_TREATMENTS_BY_FLAG_SET = exports.GET_TREATMENTS_WITH_CONFIG = exports.GET_TREATMENT_WITH_CONFIG = exports.GET_TREATMENTS = exports.GET_TREATMENT = exports.CONSENT_UNKNOWN = exports.CONSENT_DECLINED = exports.CONSENT_GRANTED = exports.STORAGE_PLUGGABLE = exports.STORAGE_REDIS = exports.STORAGE_LOCALSTORAGE = exports.STORAGE_MEMORY = exports.CONSUMER_PARTIAL_MODE = exports.CONSUMER_MODE = exports.PRODUCER_MODE = exports.STANDALONE_MODE = exports.LOCALHOST_MODE = exports.NONE = exports.OPTIMIZED = exports.DEBUG = exports.SPLIT_EVENT = exports.SPLIT_IMPRESSION = exports.NA = exports.UNKNOWN = exports.CONTROL_WITH_CONFIG = exports.CONTROL = void 0;
|
|
4
|
+
exports.PAUSED = exports.ENABLED = exports.DISABLED = exports.NON_REQUESTED = exports.REQUESTED = exports.POLLING = exports.STREAMING = exports.AUTH_REJECTION = exports.SYNC_MODE_UPDATE = exports.ABLY_ERROR = exports.TOKEN_REFRESH = exports.SSE_CONNECTION_ERROR = exports.STREAMING_STATUS = exports.OCCUPANCY_SEC = exports.OCCUPANCY_PRI = exports.CONNECTION_ESTABLISHED = exports.TRACK = exports.TREATMENTS_WITH_CONFIG_BY_FLAGSETS = exports.TREATMENTS_WITH_CONFIG_BY_FLAGSET = exports.TREATMENTS_BY_FLAGSETS = exports.TREATMENTS_BY_FLAGSET = exports.TREATMENTS_WITH_CONFIG = exports.TREATMENT_WITH_CONFIG = exports.TREATMENTS = exports.TREATMENT = void 0;
|
|
5
5
|
// Special treatments
|
|
6
6
|
exports.CONTROL = 'control';
|
|
7
7
|
exports.CONTROL_WITH_CONFIG = {
|
|
@@ -33,6 +33,20 @@ exports.STORAGE_PLUGGABLE = 'PLUGGABLE';
|
|
|
33
33
|
exports.CONSENT_GRANTED = 'GRANTED'; // The user has granted consent for tracking events and impressions
|
|
34
34
|
exports.CONSENT_DECLINED = 'DECLINED'; // The user has declined consent for tracking events and impressions
|
|
35
35
|
exports.CONSENT_UNKNOWN = 'UNKNOWN'; // The user has neither granted nor declined consent for tracking events and impressions
|
|
36
|
+
// Client method names
|
|
37
|
+
exports.GET_TREATMENT = 'getTreatment';
|
|
38
|
+
exports.GET_TREATMENTS = 'getTreatments';
|
|
39
|
+
exports.GET_TREATMENT_WITH_CONFIG = 'getTreatmentWithConfig';
|
|
40
|
+
exports.GET_TREATMENTS_WITH_CONFIG = 'getTreatmentsWithConfig';
|
|
41
|
+
exports.GET_TREATMENTS_BY_FLAG_SET = 'getTreatmentsByFlagSet';
|
|
42
|
+
exports.GET_TREATMENTS_BY_FLAG_SETS = 'getTreatmentsByFlagSets';
|
|
43
|
+
exports.GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET = 'getTreatmentsWithConfigByFlagSet';
|
|
44
|
+
exports.GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS = 'getTreatmentsWithConfigByFlagSets';
|
|
45
|
+
exports.TRACK_FN_LABEL = 'track';
|
|
46
|
+
// Manager method names
|
|
47
|
+
exports.SPLIT_FN_LABEL = 'split';
|
|
48
|
+
exports.SPLITS_FN_LABEL = 'splits';
|
|
49
|
+
exports.NAMES_FN_LABEL = 'names';
|
|
36
50
|
// Telemetry
|
|
37
51
|
exports.QUEUED = 0;
|
|
38
52
|
exports.DROPPED = 1;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validatePreloadedData = exports.
|
|
3
|
+
exports.validatePreloadedData = exports.validateTrafficTypeExistence = exports.validateSplitExistence = exports.validateIfOperational = exports.validateIfNotDestroyed = exports.validateTrafficType = exports.validateSplits = exports.validateSplit = exports.validateKey = exports.validateEventProperties = exports.validateEventValue = exports.validateEvent = exports.validateAttributes = exports.releaseApiKey = exports.validateAndTrackApiKey = exports.validateApiKey = void 0;
|
|
4
4
|
var apiKey_1 = require("./apiKey");
|
|
5
5
|
Object.defineProperty(exports, "validateApiKey", { enumerable: true, get: function () { return apiKey_1.validateApiKey; } });
|
|
6
6
|
Object.defineProperty(exports, "validateAndTrackApiKey", { enumerable: true, get: function () { return apiKey_1.validateAndTrackApiKey; } });
|
|
@@ -24,9 +24,9 @@ Object.defineProperty(exports, "validateTrafficType", { enumerable: true, get: f
|
|
|
24
24
|
var isOperational_1 = require("./isOperational");
|
|
25
25
|
Object.defineProperty(exports, "validateIfNotDestroyed", { enumerable: true, get: function () { return isOperational_1.validateIfNotDestroyed; } });
|
|
26
26
|
Object.defineProperty(exports, "validateIfOperational", { enumerable: true, get: function () { return isOperational_1.validateIfOperational; } });
|
|
27
|
-
var
|
|
28
|
-
Object.defineProperty(exports, "
|
|
29
|
-
var
|
|
30
|
-
Object.defineProperty(exports, "
|
|
27
|
+
var splitExistence_1 = require("./splitExistence");
|
|
28
|
+
Object.defineProperty(exports, "validateSplitExistence", { enumerable: true, get: function () { return splitExistence_1.validateSplitExistence; } });
|
|
29
|
+
var trafficTypeExistence_1 = require("./trafficTypeExistence");
|
|
30
|
+
Object.defineProperty(exports, "validateTrafficTypeExistence", { enumerable: true, get: function () { return trafficTypeExistence_1.validateTrafficTypeExistence; } });
|
|
31
31
|
var preloadedData_1 = require("./preloadedData");
|
|
32
32
|
Object.defineProperty(exports, "validatePreloadedData", { enumerable: true, get: function () { return preloadedData_1.validatePreloadedData; } });
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.validateSplitExistence = void 0;
|
|
4
4
|
var labels_1 = require("../labels");
|
|
5
5
|
var constants_1 = require("../../logger/constants");
|
|
6
6
|
/**
|
|
7
7
|
* This is defined here and in this format mostly because of the logger and the fact that it's considered a validation at product level.
|
|
8
8
|
* But it's not going to run on the input validation layer. In any case, the most compeling reason to use it as we do is to avoid going to Redis and get a split twice.
|
|
9
9
|
*/
|
|
10
|
-
function
|
|
10
|
+
function validateSplitExistence(log, readinessManager, splitName, labelOrSplitObj, method) {
|
|
11
11
|
if (readinessManager.isReady()) { // Only if it's ready we validate this, otherwise it may just be that the SDK is not ready yet.
|
|
12
12
|
if (labelOrSplitObj === labels_1.SPLIT_NOT_FOUND || labelOrSplitObj == null) {
|
|
13
13
|
log.warn(constants_1.WARN_NOT_EXISTENT_SPLIT, [method, splitName]);
|
|
@@ -16,4 +16,4 @@ function validateSplitExistance(log, readinessManager, splitName, labelOrSplitOb
|
|
|
16
16
|
}
|
|
17
17
|
return true;
|
|
18
18
|
}
|
|
19
|
-
exports.
|
|
19
|
+
exports.validateSplitExistence = validateSplitExistence;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.validateTrafficTypeExistence = void 0;
|
|
4
4
|
var thenable_1 = require("../promise/thenable");
|
|
5
5
|
var constants_1 = require("../constants");
|
|
6
6
|
var constants_2 = require("../../logger/constants");
|
|
7
|
-
function
|
|
7
|
+
function logTTExistenceWarning(log, maybeTT, method) {
|
|
8
8
|
log.warn(constants_2.WARN_NOT_EXISTENT_TT, [method, maybeTT]);
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Separated from the previous method since on some cases it'll be async.
|
|
12
12
|
*/
|
|
13
|
-
function
|
|
13
|
+
function validateTrafficTypeExistence(log, readinessManager, splitsCache, mode, maybeTT, method) {
|
|
14
14
|
// If not ready or in localhost mode, we won't run the validation
|
|
15
15
|
if (!readinessManager.isReady() || mode === constants_1.LOCALHOST_MODE)
|
|
16
16
|
return true;
|
|
@@ -18,14 +18,14 @@ function validateTrafficTypeExistance(log, readinessManager, splitsCache, mode,
|
|
|
18
18
|
if ((0, thenable_1.thenable)(res)) {
|
|
19
19
|
return res.then(function (isValid) {
|
|
20
20
|
if (!isValid)
|
|
21
|
-
|
|
21
|
+
logTTExistenceWarning(log, maybeTT, method);
|
|
22
22
|
return isValid; // propagate result
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
26
|
if (!res)
|
|
27
|
-
|
|
27
|
+
logTTExistenceWarning(log, maybeTT, method);
|
|
28
28
|
return res;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
exports.
|
|
31
|
+
exports.validateTrafficTypeExistence = validateTrafficTypeExistence;
|
package/cjs/utils/lang/sets.js
CHANGED
|
@@ -24,7 +24,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
24
24
|
THE SOFTWARE.
|
|
25
25
|
**/
|
|
26
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
-
exports.returnSetsUnion = exports._Set = exports.__getSetConstructor = exports.setToArray = exports.SetPoly = void 0;
|
|
27
|
+
exports.returnDifference = exports.returnSetsUnion = exports._Set = exports.__getSetConstructor = exports.setToArray = exports.SetPoly = void 0;
|
|
28
28
|
var SetPoly = /** @class */ (function () {
|
|
29
29
|
// unlike ES6 `Set`, it only accepts an array as first argument iterable
|
|
30
30
|
function SetPoly(values) {
|
|
@@ -108,3 +108,13 @@ function returnSetsUnion(set, set2) {
|
|
|
108
108
|
return result;
|
|
109
109
|
}
|
|
110
110
|
exports.returnSetsUnion = returnSetsUnion;
|
|
111
|
+
function returnDifference(list, list2) {
|
|
112
|
+
if (list === void 0) { list = []; }
|
|
113
|
+
if (list2 === void 0) { list2 = []; }
|
|
114
|
+
var result = new exports._Set(list);
|
|
115
|
+
list2.forEach(function (item) {
|
|
116
|
+
result.delete(item);
|
|
117
|
+
});
|
|
118
|
+
return setToArray(result);
|
|
119
|
+
}
|
|
120
|
+
exports.returnDifference = returnDifference;
|
|
@@ -179,7 +179,7 @@ function settingsValidation(config, validationParams) {
|
|
|
179
179
|
withDefaults.sync.enabled = true;
|
|
180
180
|
}
|
|
181
181
|
// validate the `splitFilters` settings and parse splits query
|
|
182
|
-
var splitFiltersValidation = (0, splitFilters_1.validateSplitFilters)(log, withDefaults.sync.splitFilters);
|
|
182
|
+
var splitFiltersValidation = (0, splitFilters_1.validateSplitFilters)(log, withDefaults.sync.splitFilters, withDefaults.mode);
|
|
183
183
|
withDefaults.sync.splitFilters = splitFiltersValidation.validFilters;
|
|
184
184
|
withDefaults.sync.__splitFiltersValidation = splitFiltersValidation;
|
|
185
185
|
// ensure a valid user consent value
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.validateFlagSets = exports.validateSplitFilters = void 0;
|
|
4
|
+
var constants_1 = require("../constants");
|
|
4
5
|
var splits_1 = require("../inputValidation/splits");
|
|
5
|
-
var
|
|
6
|
+
var constants_2 = require("../../logger/constants");
|
|
6
7
|
var objectAssign_1 = require("../lang/objectAssign");
|
|
7
8
|
var lang_1 = require("../lang");
|
|
8
9
|
// Split filters metadata.
|
|
@@ -44,10 +45,10 @@ function validateFilterType(maybeFilterType) {
|
|
|
44
45
|
*/
|
|
45
46
|
function validateSplitFilter(log, type, values, maxLength) {
|
|
46
47
|
// validate and remove invalid and duplicated values
|
|
47
|
-
var result = (0, splits_1.validateSplits)(log, values,
|
|
48
|
+
var result = (0, splits_1.validateSplits)(log, values, constants_2.LOG_PREFIX_SETTINGS, type + " filter", type + " filter value");
|
|
48
49
|
if (result) {
|
|
49
50
|
if (type === 'bySet') {
|
|
50
|
-
result = sanitizeFlagSets(log, result);
|
|
51
|
+
result = sanitizeFlagSets(log, result, constants_2.LOG_PREFIX_SETTINGS);
|
|
51
52
|
}
|
|
52
53
|
// check max length
|
|
53
54
|
if (result.length > maxLength)
|
|
@@ -80,7 +81,7 @@ function queryStringBuilder(groupedFilters) {
|
|
|
80
81
|
return queryParams.length > 0 ? '&' + queryParams.join('&') : null;
|
|
81
82
|
}
|
|
82
83
|
/**
|
|
83
|
-
* Sanitizes set names list taking
|
|
84
|
+
* Sanitizes set names list taking into account:
|
|
84
85
|
* - It should be lowercase
|
|
85
86
|
* - Must adhere the following regular expression /^[a-z0-9][_a-z0-9]{0,49}$/ that means
|
|
86
87
|
* - must start with a letter or number
|
|
@@ -90,20 +91,21 @@ function queryStringBuilder(groupedFilters) {
|
|
|
90
91
|
*
|
|
91
92
|
* @param {ILogger} log
|
|
92
93
|
* @param {string[]} flagSets
|
|
94
|
+
* @param {string} method
|
|
93
95
|
* @returns sanitized list of set names
|
|
94
96
|
*/
|
|
95
|
-
function sanitizeFlagSets(log, flagSets) {
|
|
97
|
+
function sanitizeFlagSets(log, flagSets, method) {
|
|
96
98
|
var sanitizedSets = flagSets
|
|
97
99
|
.map(function (flagSet) {
|
|
98
100
|
if (CAPITAL_LETTERS_REGEX.test(flagSet)) {
|
|
99
|
-
log.warn(
|
|
101
|
+
log.warn(constants_2.WARN_LOWERCASE_FLAGSET, [method, flagSet]);
|
|
100
102
|
flagSet = flagSet.toLowerCase();
|
|
101
103
|
}
|
|
102
104
|
return flagSet;
|
|
103
105
|
})
|
|
104
106
|
.filter(function (flagSet) {
|
|
105
107
|
if (!VALID_FLAGSET_REGEX.test(flagSet)) {
|
|
106
|
-
log.warn(
|
|
108
|
+
log.warn(constants_2.WARN_INVALID_FLAGSET, [method, flagSet, VALID_FLAGSET_REGEX, flagSet]);
|
|
107
109
|
return false;
|
|
108
110
|
}
|
|
109
111
|
if (typeof flagSet !== 'string')
|
|
@@ -120,6 +122,7 @@ function configuredFilter(validFilters, filterType) {
|
|
|
120
122
|
*
|
|
121
123
|
* @param {ILogger} log logger
|
|
122
124
|
* @param {any} maybeSplitFilters split filters configuration param provided by the user
|
|
125
|
+
* @param {string} mode settings mode
|
|
123
126
|
* @returns it returns an object with the following properties:
|
|
124
127
|
* - `validFilters`: the validated `splitFilters` configuration object defined by the user.
|
|
125
128
|
* - `queryString`: the parsed split filter query. it is null if all filters are invalid or all values in filters are invalid.
|
|
@@ -127,7 +130,7 @@ function configuredFilter(validFilters, filterType) {
|
|
|
127
130
|
*
|
|
128
131
|
* @throws Error if the some of the grouped list of values per filter exceeds the max allowed length
|
|
129
132
|
*/
|
|
130
|
-
function validateSplitFilters(log, maybeSplitFilters) {
|
|
133
|
+
function validateSplitFilters(log, maybeSplitFilters, mode) {
|
|
131
134
|
// Validation result schema
|
|
132
135
|
var res = {
|
|
133
136
|
validFilters: [],
|
|
@@ -137,9 +140,14 @@ function validateSplitFilters(log, maybeSplitFilters) {
|
|
|
137
140
|
// do nothing if `splitFilters` param is not a non-empty array or mode is not STANDALONE
|
|
138
141
|
if (!maybeSplitFilters)
|
|
139
142
|
return res;
|
|
143
|
+
// Warn depending on the mode
|
|
144
|
+
if (mode === constants_1.CONSUMER_MODE || mode === constants_1.CONSUMER_PARTIAL_MODE) {
|
|
145
|
+
log.warn(constants_2.WARN_SPLITS_FILTER_IGNORED);
|
|
146
|
+
return res;
|
|
147
|
+
}
|
|
140
148
|
// Check collection type
|
|
141
149
|
if (!Array.isArray(maybeSplitFilters) || maybeSplitFilters.length === 0) {
|
|
142
|
-
log.warn(
|
|
150
|
+
log.warn(constants_2.WARN_SPLITS_FILTER_EMPTY);
|
|
143
151
|
return res;
|
|
144
152
|
}
|
|
145
153
|
// Validate filters and group their values by filter type inside `groupedFilters` object
|
|
@@ -149,7 +157,7 @@ function validateSplitFilters(log, maybeSplitFilters) {
|
|
|
149
157
|
return true;
|
|
150
158
|
}
|
|
151
159
|
else {
|
|
152
|
-
log.warn(
|
|
160
|
+
log.warn(constants_2.WARN_SPLITS_FILTER_INVALID, [index]);
|
|
153
161
|
}
|
|
154
162
|
return false;
|
|
155
163
|
});
|
|
@@ -163,27 +171,27 @@ function validateSplitFilters(log, maybeSplitFilters) {
|
|
|
163
171
|
// Clean all filters if set filter is present
|
|
164
172
|
if (setFilter) {
|
|
165
173
|
if (configuredFilter(res.validFilters, 'byName') || configuredFilter(res.validFilters, 'byPrefix'))
|
|
166
|
-
log.error(
|
|
174
|
+
log.error(constants_2.ERROR_SETS_FILTER_EXCLUSIVE);
|
|
167
175
|
(0, objectAssign_1.objectAssign)(res.groupedFilters, { byName: [], byPrefix: [] });
|
|
168
176
|
}
|
|
169
177
|
// build query string
|
|
170
178
|
res.queryString = queryStringBuilder(res.groupedFilters);
|
|
171
|
-
log.debug(
|
|
179
|
+
log.debug(constants_2.SETTINGS_SPLITS_FILTER, [res.queryString]);
|
|
172
180
|
return res;
|
|
173
181
|
}
|
|
174
182
|
exports.validateSplitFilters = validateSplitFilters;
|
|
175
|
-
function
|
|
183
|
+
function validateFlagSets(log, method, flagSets, flagSetsInConfig) {
|
|
176
184
|
var sets = (0, splits_1.validateSplits)(log, flagSets, method, 'flag sets', 'flag set');
|
|
177
|
-
var toReturn = sets ? sanitizeFlagSets(log, sets) : [];
|
|
185
|
+
var toReturn = sets ? sanitizeFlagSets(log, sets, method) : [];
|
|
178
186
|
if (flagSetsInConfig.length > 0) {
|
|
179
187
|
toReturn = toReturn.filter(function (flagSet) {
|
|
180
188
|
if (flagSetsInConfig.indexOf(flagSet) > -1) {
|
|
181
189
|
return true;
|
|
182
190
|
}
|
|
183
|
-
log.warn(
|
|
191
|
+
log.warn(constants_2.WARN_FLAGSET_NOT_CONFIGURED, [method, flagSet]);
|
|
184
192
|
return false;
|
|
185
193
|
});
|
|
186
194
|
}
|
|
187
195
|
return toReturn;
|
|
188
196
|
}
|
|
189
|
-
exports.
|
|
197
|
+
exports.validateFlagSets = validateFlagSets;
|
package/esm/evaluator/index.js
CHANGED
|
@@ -2,7 +2,8 @@ import { Engine } from './Engine';
|
|
|
2
2
|
import { thenable } from '../utils/promise/thenable';
|
|
3
3
|
import * as LabelsConstants from '../utils/labels';
|
|
4
4
|
import { CONTROL } from '../utils/constants';
|
|
5
|
-
import { setToArray } from '../utils/lang/sets';
|
|
5
|
+
import { setToArray, returnSetsUnion, _Set } from '../utils/lang/sets';
|
|
6
|
+
import { WARN_FLAGSET_WITHOUT_FLAGS } from '../logger/constants';
|
|
6
7
|
var treatmentException = {
|
|
7
8
|
treatment: CONTROL,
|
|
8
9
|
label: LabelsConstants.EXCEPTION,
|
|
@@ -50,8 +51,23 @@ export function evaluateFeatures(log, key, splitNames, attributes, storage) {
|
|
|
50
51
|
}) :
|
|
51
52
|
getEvaluations(log, splitNames, parsedSplits, key, attributes, storage);
|
|
52
53
|
}
|
|
53
|
-
export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage) {
|
|
54
|
+
export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, method) {
|
|
54
55
|
var storedFlagNames;
|
|
56
|
+
function evaluate(featureFlagsByFlagSets) {
|
|
57
|
+
var featureFlags = new _Set();
|
|
58
|
+
for (var i = 0; i < flagSets.length; i++) {
|
|
59
|
+
var featureFlagByFlagSet = featureFlagsByFlagSets[i];
|
|
60
|
+
if (featureFlagByFlagSet.size) {
|
|
61
|
+
featureFlags = returnSetsUnion(featureFlags, featureFlagByFlagSet);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
log.warn(WARN_FLAGSET_WITHOUT_FLAGS, [method, flagSets[i]]);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return featureFlags.size ?
|
|
68
|
+
evaluateFeatures(log, key, setToArray(featureFlags), attributes, storage) :
|
|
69
|
+
{};
|
|
70
|
+
}
|
|
55
71
|
// get features by flag sets
|
|
56
72
|
try {
|
|
57
73
|
storedFlagNames = storage.splits.getNamesByFlagSets(flagSets);
|
|
@@ -62,11 +78,11 @@ export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, stora
|
|
|
62
78
|
}
|
|
63
79
|
// evaluate related features
|
|
64
80
|
return thenable(storedFlagNames) ?
|
|
65
|
-
storedFlagNames.then(function (
|
|
81
|
+
storedFlagNames.then(function (storedFlagNames) { return evaluate(storedFlagNames); })
|
|
66
82
|
.catch(function () {
|
|
67
83
|
return {};
|
|
68
84
|
}) :
|
|
69
|
-
|
|
85
|
+
evaluate(storedFlagNames);
|
|
70
86
|
}
|
|
71
87
|
function getEvaluation(log, splitJSON, key, attributes, storage) {
|
|
72
88
|
var evaluation = {
|
package/esm/logger/constants.js
CHANGED
|
@@ -89,14 +89,16 @@ export var WARN_NOT_EXISTENT_SPLIT = 215;
|
|
|
89
89
|
export var WARN_LOWERCASE_TRAFFIC_TYPE = 216;
|
|
90
90
|
export var WARN_NOT_EXISTENT_TT = 217;
|
|
91
91
|
export var WARN_INTEGRATION_INVALID = 218;
|
|
92
|
+
export var WARN_SPLITS_FILTER_IGNORED = 219;
|
|
92
93
|
export var WARN_SPLITS_FILTER_INVALID = 220;
|
|
93
94
|
export var WARN_SPLITS_FILTER_EMPTY = 221;
|
|
94
95
|
export var WARN_SDK_KEY = 222;
|
|
95
96
|
export var STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = 223;
|
|
96
97
|
export var STREAMING_PARSING_SPLIT_UPDATE = 224;
|
|
97
|
-
export var
|
|
98
|
-
export var
|
|
98
|
+
export var WARN_INVALID_FLAGSET = 225;
|
|
99
|
+
export var WARN_LOWERCASE_FLAGSET = 226;
|
|
99
100
|
export var WARN_FLAGSET_NOT_CONFIGURED = 227;
|
|
101
|
+
export var WARN_FLAGSET_WITHOUT_FLAGS = 228;
|
|
100
102
|
export var ERROR_ENGINE_COMBINER_IFELSEIF = 300;
|
|
101
103
|
export var ERROR_LOGLEVEL_INVALID = 301;
|
|
102
104
|
export var ERROR_CLIENT_LISTENER = 302;
|
|
@@ -23,14 +23,16 @@ export var codesWarn = codesError.concat([
|
|
|
23
23
|
[c.WARN_NOT_EXISTENT_SPLIT, '%s: feature flag "%s" does not exist in this environment. Please double check what feature flags exist in the Split user interface.'],
|
|
24
24
|
[c.WARN_LOWERCASE_TRAFFIC_TYPE, '%s: traffic_type_name should be all lowercase - converting string to lowercase.'],
|
|
25
25
|
[c.WARN_NOT_EXISTENT_TT, '%s: traffic type "%s" does not have any corresponding feature flag in this environment, make sure you\'re tracking your events to a valid traffic type defined in the Split user interface.'],
|
|
26
|
-
[c.WARN_FLAGSET_NOT_CONFIGURED, '%s:
|
|
26
|
+
[c.WARN_FLAGSET_NOT_CONFIGURED, '%s: you passed %s which is not part of the configured FlagSetsFilter, ignoring Flag Set.'],
|
|
27
27
|
// initialization / settings validation
|
|
28
28
|
[c.WARN_INTEGRATION_INVALID, c.LOG_PREFIX_SETTINGS + ': %s integration item(s) at settings is invalid. %s'],
|
|
29
|
+
[c.WARN_SPLITS_FILTER_IGNORED, c.LOG_PREFIX_SETTINGS + ': feature flag filters are not applicable for Consumer modes where the SDK does not keep rollout data in sync. Filters were discarded'],
|
|
29
30
|
[c.WARN_SPLITS_FILTER_INVALID, c.LOG_PREFIX_SETTINGS + ': feature flag filter at position %s is invalid. It must be an object with a valid filter type ("bySet", "byName" or "byPrefix") and a list of "values".'],
|
|
30
31
|
[c.WARN_SPLITS_FILTER_EMPTY, c.LOG_PREFIX_SETTINGS + ': feature flag filter configuration must be a non-empty array of filter objects.'],
|
|
31
32
|
[c.WARN_SDK_KEY, c.LOG_PREFIX_SETTINGS + ': You already have %s. We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing it throughout your application'],
|
|
32
33
|
[c.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching MySegments due to an error processing %s notification: %s'],
|
|
33
34
|
[c.STREAMING_PARSING_SPLIT_UPDATE, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching SplitChanges due to an error processing SPLIT_UPDATE notification: %s'],
|
|
34
|
-
[c.
|
|
35
|
-
[c.
|
|
35
|
+
[c.WARN_INVALID_FLAGSET, '%s: you passed %s, flag set must adhere to the regular expressions %s. This means a flag set must start with a letter or number, be in lowercase, alphanumeric and have a max length of 50 characters. %s was discarded.'],
|
|
36
|
+
[c.WARN_LOWERCASE_FLAGSET, '%s: flag set %s should be all lowercase - converting string to lowercase.'],
|
|
37
|
+
[c.WARN_FLAGSET_WITHOUT_FLAGS, '%s: you passed %s flag set that does not contain cached feature flag names. Please double check what flag sets are in use in the Split user interface.'],
|
|
36
38
|
]);
|