@splitsoftware/splitio-commons 1.11.0 → 1.12.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
|
@@ -36,7 +36,7 @@ export function InRedisStorage(options) {
|
|
|
36
36
|
telemetry.recordConfig();
|
|
37
37
|
});
|
|
38
38
|
return {
|
|
39
|
-
splits: new SplitsCacheInRedis(log, keys, redisClient),
|
|
39
|
+
splits: new SplitsCacheInRedis(log, keys, redisClient, settings.sync.__splitFiltersValidation),
|
|
40
40
|
segments: new SegmentsCacheInRedis(log, keys, redisClient),
|
|
41
41
|
impressions: new ImpressionsCacheInRedis(log, keys.buildImpressionsKey(), redisClient, metadata),
|
|
42
42
|
impressionCounts: impressionCountsCache,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { __extends } from "tslib";
|
|
1
|
+
import { __extends, __spreadArray } from "tslib";
|
|
2
2
|
import { isFiniteNumber, isNaNNumber } from '../../utils/lang';
|
|
3
3
|
import { LOG_PREFIX } from './constants';
|
|
4
4
|
import { AbstractSplitsCacheAsync } from '../AbstractSplitsCacheAsync';
|
|
5
|
+
import { _Set, returnDifference } from '../../utils/lang/sets';
|
|
5
6
|
/**
|
|
6
7
|
* ISplitsCacheAsync implementation for pluggable storages.
|
|
7
8
|
*/
|
|
@@ -13,11 +14,12 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
|
|
|
13
14
|
* @param keys Key builder.
|
|
14
15
|
* @param wrapper Adapted wrapper storage.
|
|
15
16
|
*/
|
|
16
|
-
function SplitsCachePluggable(log, keys, wrapper) {
|
|
17
|
+
function SplitsCachePluggable(log, keys, wrapper, splitFiltersValidation) {
|
|
17
18
|
var _this = _super.call(this) || this;
|
|
18
19
|
_this.log = log;
|
|
19
20
|
_this.keys = keys;
|
|
20
21
|
_this.wrapper = wrapper;
|
|
22
|
+
_this.flagSetsFilter = splitFiltersValidation ? splitFiltersValidation.groupedFilters.bySet : [];
|
|
21
23
|
return _this;
|
|
22
24
|
}
|
|
23
25
|
SplitsCachePluggable.prototype._decrementCounts = function (split) {
|
|
@@ -32,6 +34,18 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
|
|
|
32
34
|
var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
|
|
33
35
|
return this.wrapper.incr(ttKey);
|
|
34
36
|
};
|
|
37
|
+
SplitsCachePluggable.prototype._updateFlagSets = function (featureFlagName, flagSetsOfRemovedFlag, flagSetsOfAddedFlag) {
|
|
38
|
+
var _this = this;
|
|
39
|
+
var removeFromFlagSets = returnDifference(flagSetsOfRemovedFlag, flagSetsOfAddedFlag);
|
|
40
|
+
var addToFlagSets = returnDifference(flagSetsOfAddedFlag, flagSetsOfRemovedFlag);
|
|
41
|
+
if (this.flagSetsFilter.length > 0) {
|
|
42
|
+
addToFlagSets = addToFlagSets.filter(function (flagSet) {
|
|
43
|
+
return _this.flagSetsFilter.some(function (filterFlagSet) { return filterFlagSet === flagSet; });
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
var items = [featureFlagName];
|
|
47
|
+
return Promise.all(__spreadArray(__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));
|
|
48
|
+
};
|
|
35
49
|
/**
|
|
36
50
|
* Add a given split.
|
|
37
51
|
* The returned promise is resolved when the operation success
|
|
@@ -59,7 +73,7 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
|
|
|
59
73
|
if (parsedPreviousSplit)
|
|
60
74
|
return _this._decrementCounts(parsedPreviousSplit);
|
|
61
75
|
});
|
|
62
|
-
});
|
|
76
|
+
}).then(function () { return _this._updateFlagSets(name, parsedPreviousSplit && parsedPreviousSplit.sets, split.sets); });
|
|
63
77
|
}).then(function () { return true; });
|
|
64
78
|
};
|
|
65
79
|
/**
|
|
@@ -80,8 +94,9 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
|
|
|
80
94
|
var _this = this;
|
|
81
95
|
return this.getSplit(name).then(function (split) {
|
|
82
96
|
if (split) {
|
|
83
|
-
_this._decrementCounts(split);
|
|
97
|
+
return _this._decrementCounts(split).then(function () { return _this._updateFlagSets(name, split.sets); });
|
|
84
98
|
}
|
|
99
|
+
}).then(function () {
|
|
85
100
|
return _this.wrapper.del(_this.keys.buildSplitKey(name));
|
|
86
101
|
});
|
|
87
102
|
};
|
|
@@ -143,14 +158,16 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
|
|
|
143
158
|
return this.wrapper.getKeysByPrefix(this.keys.buildSplitKeyPrefix()).then(function (listOfKeys) { return listOfKeys.map(_this.keys.extractKey); });
|
|
144
159
|
};
|
|
145
160
|
/**
|
|
146
|
-
* Get list of
|
|
147
|
-
* The returned promise is resolved with the list of
|
|
148
|
-
*
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
161
|
+
* Get list of feature flag names related to a given list of flag set names.
|
|
162
|
+
* The returned promise is resolved with the list of feature flag names per flag set.
|
|
163
|
+
* It never rejects (If there is a wrapper error for some flag set, an empty set is returned for it).
|
|
164
|
+
*/
|
|
165
|
+
SplitsCachePluggable.prototype.getNamesByFlagSets = function (flagSets) {
|
|
166
|
+
var _this = this;
|
|
167
|
+
return Promise.all(flagSets.map(function (flagSet) {
|
|
168
|
+
var flagSetKey = _this.keys.buildFlagSetKey(flagSet);
|
|
169
|
+
return _this.wrapper.getItems(flagSetKey).catch(function () { return []; });
|
|
170
|
+
})).then(function (namesByFlagSets) { return namesByFlagSets.map(function (namesByFlagSet) { return new _Set(namesByFlagSet); }); });
|
|
154
171
|
};
|
|
155
172
|
/**
|
|
156
173
|
* Check traffic type existence.
|
|
@@ -89,7 +89,7 @@ export function PluggableStorage(options) {
|
|
|
89
89
|
return e; // Propagate error for shared clients
|
|
90
90
|
});
|
|
91
91
|
return {
|
|
92
|
-
splits: new SplitsCachePluggable(log, keys, wrapper),
|
|
92
|
+
splits: new SplitsCachePluggable(log, keys, wrapper, settings.sync.__splitFiltersValidation),
|
|
93
93
|
segments: new SegmentsCachePluggable(log, keys, wrapper),
|
|
94
94
|
impressions: isPartialConsumer ? new ImpressionsCacheInMemory(impressionsQueueSize) : new ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
|
|
95
95
|
impressionCounts: impressionCountsCache,
|
|
@@ -29,6 +29,20 @@ export var STORAGE_PLUGGABLE = 'PLUGGABLE';
|
|
|
29
29
|
export var CONSENT_GRANTED = 'GRANTED'; // The user has granted consent for tracking events and impressions
|
|
30
30
|
export var CONSENT_DECLINED = 'DECLINED'; // The user has declined consent for tracking events and impressions
|
|
31
31
|
export var CONSENT_UNKNOWN = 'UNKNOWN'; // The user has neither granted nor declined consent for tracking events and impressions
|
|
32
|
+
// Client method names
|
|
33
|
+
export var GET_TREATMENT = 'getTreatment';
|
|
34
|
+
export var GET_TREATMENTS = 'getTreatments';
|
|
35
|
+
export var GET_TREATMENT_WITH_CONFIG = 'getTreatmentWithConfig';
|
|
36
|
+
export var GET_TREATMENTS_WITH_CONFIG = 'getTreatmentsWithConfig';
|
|
37
|
+
export var GET_TREATMENTS_BY_FLAG_SET = 'getTreatmentsByFlagSet';
|
|
38
|
+
export var GET_TREATMENTS_BY_FLAG_SETS = 'getTreatmentsByFlagSets';
|
|
39
|
+
export var GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET = 'getTreatmentsWithConfigByFlagSet';
|
|
40
|
+
export var GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS = 'getTreatmentsWithConfigByFlagSets';
|
|
41
|
+
export var TRACK_FN_LABEL = 'track';
|
|
42
|
+
// Manager method names
|
|
43
|
+
export var SPLIT_FN_LABEL = 'split';
|
|
44
|
+
export var SPLITS_FN_LABEL = 'splits';
|
|
45
|
+
export var NAMES_FN_LABEL = 'names';
|
|
32
46
|
// Telemetry
|
|
33
47
|
export var QUEUED = 0;
|
|
34
48
|
export var DROPPED = 1;
|
|
@@ -8,6 +8,6 @@ export { validateSplit } from './split';
|
|
|
8
8
|
export { validateSplits } from './splits';
|
|
9
9
|
export { validateTrafficType } from './trafficType';
|
|
10
10
|
export { validateIfNotDestroyed, validateIfOperational } from './isOperational';
|
|
11
|
-
export {
|
|
12
|
-
export {
|
|
11
|
+
export { validateSplitExistence } from './splitExistence';
|
|
12
|
+
export { validateTrafficTypeExistence } from './trafficTypeExistence';
|
|
13
13
|
export { validatePreloadedData } from './preloadedData';
|
|
@@ -4,7 +4,7 @@ import { WARN_NOT_EXISTENT_SPLIT } from '../../logger/constants';
|
|
|
4
4
|
* 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.
|
|
5
5
|
* 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.
|
|
6
6
|
*/
|
|
7
|
-
export function
|
|
7
|
+
export function validateSplitExistence(log, readinessManager, splitName, labelOrSplitObj, method) {
|
|
8
8
|
if (readinessManager.isReady()) { // Only if it's ready we validate this, otherwise it may just be that the SDK is not ready yet.
|
|
9
9
|
if (labelOrSplitObj === SPLIT_NOT_FOUND || labelOrSplitObj == null) {
|
|
10
10
|
log.warn(WARN_NOT_EXISTENT_SPLIT, [method, splitName]);
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { thenable } from '../promise/thenable';
|
|
2
2
|
import { LOCALHOST_MODE } from '../constants';
|
|
3
3
|
import { WARN_NOT_EXISTENT_TT } from '../../logger/constants';
|
|
4
|
-
function
|
|
4
|
+
function logTTExistenceWarning(log, maybeTT, method) {
|
|
5
5
|
log.warn(WARN_NOT_EXISTENT_TT, [method, maybeTT]);
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
8
|
* Separated from the previous method since on some cases it'll be async.
|
|
9
9
|
*/
|
|
10
|
-
export function
|
|
10
|
+
export function validateTrafficTypeExistence(log, readinessManager, splitsCache, mode, maybeTT, method) {
|
|
11
11
|
// If not ready or in localhost mode, we won't run the validation
|
|
12
12
|
if (!readinessManager.isReady() || mode === LOCALHOST_MODE)
|
|
13
13
|
return true;
|
|
@@ -15,13 +15,13 @@ export function validateTrafficTypeExistance(log, readinessManager, splitsCache,
|
|
|
15
15
|
if (thenable(res)) {
|
|
16
16
|
return res.then(function (isValid) {
|
|
17
17
|
if (!isValid)
|
|
18
|
-
|
|
18
|
+
logTTExistenceWarning(log, maybeTT, method);
|
|
19
19
|
return isValid; // propagate result
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
22
|
else {
|
|
23
23
|
if (!res)
|
|
24
|
-
|
|
24
|
+
logTTExistenceWarning(log, maybeTT, method);
|
|
25
25
|
return res;
|
|
26
26
|
}
|
|
27
27
|
}
|
package/esm/utils/lang/sets.js
CHANGED
|
@@ -102,3 +102,12 @@ export function returnSetsUnion(set, set2) {
|
|
|
102
102
|
});
|
|
103
103
|
return result;
|
|
104
104
|
}
|
|
105
|
+
export function returnDifference(list, list2) {
|
|
106
|
+
if (list === void 0) { list = []; }
|
|
107
|
+
if (list2 === void 0) { list2 = []; }
|
|
108
|
+
var result = new _Set(list);
|
|
109
|
+
list2.forEach(function (item) {
|
|
110
|
+
result.delete(item);
|
|
111
|
+
});
|
|
112
|
+
return setToArray(result);
|
|
113
|
+
}
|
|
@@ -176,7 +176,7 @@ export function settingsValidation(config, validationParams) {
|
|
|
176
176
|
withDefaults.sync.enabled = true;
|
|
177
177
|
}
|
|
178
178
|
// validate the `splitFilters` settings and parse splits query
|
|
179
|
-
var splitFiltersValidation = validateSplitFilters(log, withDefaults.sync.splitFilters);
|
|
179
|
+
var splitFiltersValidation = validateSplitFilters(log, withDefaults.sync.splitFilters, withDefaults.mode);
|
|
180
180
|
withDefaults.sync.splitFilters = splitFiltersValidation.validFilters;
|
|
181
181
|
withDefaults.sync.__splitFiltersValidation = splitFiltersValidation;
|
|
182
182
|
// ensure a valid user consent value
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { CONSUMER_MODE, CONSUMER_PARTIAL_MODE } from '../constants';
|
|
1
2
|
import { validateSplits } from '../inputValidation/splits';
|
|
2
|
-
import { WARN_SPLITS_FILTER_EMPTY, WARN_SPLITS_FILTER_INVALID, SETTINGS_SPLITS_FILTER, LOG_PREFIX_SETTINGS, ERROR_SETS_FILTER_EXCLUSIVE,
|
|
3
|
+
import { WARN_SPLITS_FILTER_IGNORED, WARN_SPLITS_FILTER_EMPTY, WARN_SPLITS_FILTER_INVALID, SETTINGS_SPLITS_FILTER, LOG_PREFIX_SETTINGS, ERROR_SETS_FILTER_EXCLUSIVE, WARN_LOWERCASE_FLAGSET, WARN_INVALID_FLAGSET, WARN_FLAGSET_NOT_CONFIGURED } from '../../logger/constants';
|
|
3
4
|
import { objectAssign } from '../lang/objectAssign';
|
|
4
5
|
import { find, uniq } from '../lang';
|
|
5
6
|
// Split filters metadata.
|
|
@@ -44,7 +45,7 @@ function validateSplitFilter(log, type, values, maxLength) {
|
|
|
44
45
|
var result = validateSplits(log, values, LOG_PREFIX_SETTINGS, type + " filter", type + " filter value");
|
|
45
46
|
if (result) {
|
|
46
47
|
if (type === 'bySet') {
|
|
47
|
-
result = sanitizeFlagSets(log, result);
|
|
48
|
+
result = sanitizeFlagSets(log, result, LOG_PREFIX_SETTINGS);
|
|
48
49
|
}
|
|
49
50
|
// check max length
|
|
50
51
|
if (result.length > maxLength)
|
|
@@ -77,7 +78,7 @@ function queryStringBuilder(groupedFilters) {
|
|
|
77
78
|
return queryParams.length > 0 ? '&' + queryParams.join('&') : null;
|
|
78
79
|
}
|
|
79
80
|
/**
|
|
80
|
-
* Sanitizes set names list taking
|
|
81
|
+
* Sanitizes set names list taking into account:
|
|
81
82
|
* - It should be lowercase
|
|
82
83
|
* - Must adhere the following regular expression /^[a-z0-9][_a-z0-9]{0,49}$/ that means
|
|
83
84
|
* - must start with a letter or number
|
|
@@ -87,20 +88,21 @@ function queryStringBuilder(groupedFilters) {
|
|
|
87
88
|
*
|
|
88
89
|
* @param {ILogger} log
|
|
89
90
|
* @param {string[]} flagSets
|
|
91
|
+
* @param {string} method
|
|
90
92
|
* @returns sanitized list of set names
|
|
91
93
|
*/
|
|
92
|
-
function sanitizeFlagSets(log, flagSets) {
|
|
94
|
+
function sanitizeFlagSets(log, flagSets, method) {
|
|
93
95
|
var sanitizedSets = flagSets
|
|
94
96
|
.map(function (flagSet) {
|
|
95
97
|
if (CAPITAL_LETTERS_REGEX.test(flagSet)) {
|
|
96
|
-
log.warn(
|
|
98
|
+
log.warn(WARN_LOWERCASE_FLAGSET, [method, flagSet]);
|
|
97
99
|
flagSet = flagSet.toLowerCase();
|
|
98
100
|
}
|
|
99
101
|
return flagSet;
|
|
100
102
|
})
|
|
101
103
|
.filter(function (flagSet) {
|
|
102
104
|
if (!VALID_FLAGSET_REGEX.test(flagSet)) {
|
|
103
|
-
log.warn(
|
|
105
|
+
log.warn(WARN_INVALID_FLAGSET, [method, flagSet, VALID_FLAGSET_REGEX, flagSet]);
|
|
104
106
|
return false;
|
|
105
107
|
}
|
|
106
108
|
if (typeof flagSet !== 'string')
|
|
@@ -117,6 +119,7 @@ function configuredFilter(validFilters, filterType) {
|
|
|
117
119
|
*
|
|
118
120
|
* @param {ILogger} log logger
|
|
119
121
|
* @param {any} maybeSplitFilters split filters configuration param provided by the user
|
|
122
|
+
* @param {string} mode settings mode
|
|
120
123
|
* @returns it returns an object with the following properties:
|
|
121
124
|
* - `validFilters`: the validated `splitFilters` configuration object defined by the user.
|
|
122
125
|
* - `queryString`: the parsed split filter query. it is null if all filters are invalid or all values in filters are invalid.
|
|
@@ -124,7 +127,7 @@ function configuredFilter(validFilters, filterType) {
|
|
|
124
127
|
*
|
|
125
128
|
* @throws Error if the some of the grouped list of values per filter exceeds the max allowed length
|
|
126
129
|
*/
|
|
127
|
-
export function validateSplitFilters(log, maybeSplitFilters) {
|
|
130
|
+
export function validateSplitFilters(log, maybeSplitFilters, mode) {
|
|
128
131
|
// Validation result schema
|
|
129
132
|
var res = {
|
|
130
133
|
validFilters: [],
|
|
@@ -134,6 +137,11 @@ export function validateSplitFilters(log, maybeSplitFilters) {
|
|
|
134
137
|
// do nothing if `splitFilters` param is not a non-empty array or mode is not STANDALONE
|
|
135
138
|
if (!maybeSplitFilters)
|
|
136
139
|
return res;
|
|
140
|
+
// Warn depending on the mode
|
|
141
|
+
if (mode === CONSUMER_MODE || mode === CONSUMER_PARTIAL_MODE) {
|
|
142
|
+
log.warn(WARN_SPLITS_FILTER_IGNORED);
|
|
143
|
+
return res;
|
|
144
|
+
}
|
|
137
145
|
// Check collection type
|
|
138
146
|
if (!Array.isArray(maybeSplitFilters) || maybeSplitFilters.length === 0) {
|
|
139
147
|
log.warn(WARN_SPLITS_FILTER_EMPTY);
|
|
@@ -168,9 +176,9 @@ export function validateSplitFilters(log, maybeSplitFilters) {
|
|
|
168
176
|
log.debug(SETTINGS_SPLITS_FILTER, [res.queryString]);
|
|
169
177
|
return res;
|
|
170
178
|
}
|
|
171
|
-
export function
|
|
179
|
+
export function validateFlagSets(log, method, flagSets, flagSetsInConfig) {
|
|
172
180
|
var sets = validateSplits(log, flagSets, method, 'flag sets', 'flag set');
|
|
173
|
-
var toReturn = sets ? sanitizeFlagSets(log, sets) : [];
|
|
181
|
+
var toReturn = sets ? sanitizeFlagSets(log, sets, method) : [];
|
|
174
182
|
if (flagSetsInConfig.length > 0) {
|
|
175
183
|
toReturn = toReturn.filter(function (flagSet) {
|
|
176
184
|
if (flagSetsInConfig.indexOf(flagSet) > -1) {
|
package/package.json
CHANGED
package/src/evaluator/index.ts
CHANGED
|
@@ -7,7 +7,8 @@ import { IStorageAsync, IStorageSync } from '../storages/types';
|
|
|
7
7
|
import { IEvaluationResult } from './types';
|
|
8
8
|
import { SplitIO } from '../types';
|
|
9
9
|
import { ILogger } from '../logger/types';
|
|
10
|
-
import { ISet, setToArray } from '../utils/lang/sets';
|
|
10
|
+
import { ISet, setToArray, returnSetsUnion, _Set } from '../utils/lang/sets';
|
|
11
|
+
import { WARN_FLAGSET_WITHOUT_FLAGS } from '../logger/constants';
|
|
11
12
|
|
|
12
13
|
const treatmentException = {
|
|
13
14
|
treatment: CONTROL,
|
|
@@ -94,8 +95,27 @@ export function evaluateFeaturesByFlagSets(
|
|
|
94
95
|
flagSets: string[],
|
|
95
96
|
attributes: SplitIO.Attributes | undefined,
|
|
96
97
|
storage: IStorageSync | IStorageAsync,
|
|
98
|
+
method: string,
|
|
97
99
|
): MaybeThenable<Record<string, IEvaluationResult>> {
|
|
98
|
-
let storedFlagNames: MaybeThenable<ISet<string
|
|
100
|
+
let storedFlagNames: MaybeThenable<ISet<string>[]>;
|
|
101
|
+
|
|
102
|
+
function evaluate(
|
|
103
|
+
featureFlagsByFlagSets: ISet<string>[],
|
|
104
|
+
) {
|
|
105
|
+
let featureFlags = new _Set();
|
|
106
|
+
for (let i = 0; i < flagSets.length; i++) {
|
|
107
|
+
const featureFlagByFlagSet = featureFlagsByFlagSets[i];
|
|
108
|
+
if (featureFlagByFlagSet.size) {
|
|
109
|
+
featureFlags = returnSetsUnion(featureFlags, featureFlagByFlagSet);
|
|
110
|
+
} else {
|
|
111
|
+
log.warn(WARN_FLAGSET_WITHOUT_FLAGS, [method, flagSets[i]]);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return featureFlags.size ?
|
|
116
|
+
evaluateFeatures(log, key, setToArray(featureFlags), attributes, storage) :
|
|
117
|
+
{};
|
|
118
|
+
}
|
|
99
119
|
|
|
100
120
|
// get features by flag sets
|
|
101
121
|
try {
|
|
@@ -107,11 +127,11 @@ export function evaluateFeaturesByFlagSets(
|
|
|
107
127
|
|
|
108
128
|
// evaluate related features
|
|
109
129
|
return thenable(storedFlagNames) ?
|
|
110
|
-
storedFlagNames.then((
|
|
130
|
+
storedFlagNames.then((storedFlagNames) => evaluate(storedFlagNames))
|
|
111
131
|
.catch(() => {
|
|
112
132
|
return {};
|
|
113
133
|
}) :
|
|
114
|
-
|
|
134
|
+
evaluate(storedFlagNames);
|
|
115
135
|
}
|
|
116
136
|
|
|
117
137
|
function getEvaluation(
|
package/src/logger/constants.ts
CHANGED
|
@@ -91,14 +91,16 @@ export const WARN_NOT_EXISTENT_SPLIT = 215;
|
|
|
91
91
|
export const WARN_LOWERCASE_TRAFFIC_TYPE = 216;
|
|
92
92
|
export const WARN_NOT_EXISTENT_TT = 217;
|
|
93
93
|
export const WARN_INTEGRATION_INVALID = 218;
|
|
94
|
+
export const WARN_SPLITS_FILTER_IGNORED = 219;
|
|
94
95
|
export const WARN_SPLITS_FILTER_INVALID = 220;
|
|
95
96
|
export const WARN_SPLITS_FILTER_EMPTY = 221;
|
|
96
97
|
export const WARN_SDK_KEY = 222;
|
|
97
98
|
export const STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = 223;
|
|
98
99
|
export const STREAMING_PARSING_SPLIT_UPDATE = 224;
|
|
99
|
-
export const
|
|
100
|
-
export const
|
|
100
|
+
export const WARN_INVALID_FLAGSET = 225;
|
|
101
|
+
export const WARN_LOWERCASE_FLAGSET = 226;
|
|
101
102
|
export const WARN_FLAGSET_NOT_CONFIGURED = 227;
|
|
103
|
+
export const WARN_FLAGSET_WITHOUT_FLAGS = 228;
|
|
102
104
|
|
|
103
105
|
export const ERROR_ENGINE_COMBINER_IFELSEIF = 300;
|
|
104
106
|
export const ERROR_LOGLEVEL_INVALID = 301;
|
|
@@ -24,15 +24,17 @@ export const codesWarn: [number, string][] = codesError.concat([
|
|
|
24
24
|
[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.'],
|
|
25
25
|
[c.WARN_LOWERCASE_TRAFFIC_TYPE, '%s: traffic_type_name should be all lowercase - converting string to lowercase.'],
|
|
26
26
|
[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.'],
|
|
27
|
-
[c.WARN_FLAGSET_NOT_CONFIGURED, '%s:
|
|
27
|
+
[c.WARN_FLAGSET_NOT_CONFIGURED, '%s: you passed %s which is not part of the configured FlagSetsFilter, ignoring Flag Set.'],
|
|
28
28
|
// initialization / settings validation
|
|
29
|
-
[c.WARN_INTEGRATION_INVALID, c.LOG_PREFIX_SETTINGS+': %s integration item(s) at settings is invalid. %s'],
|
|
30
|
-
[c.
|
|
31
|
-
[c.
|
|
32
|
-
[c.
|
|
29
|
+
[c.WARN_INTEGRATION_INVALID, c.LOG_PREFIX_SETTINGS + ': %s integration item(s) at settings is invalid. %s'],
|
|
30
|
+
[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'],
|
|
31
|
+
[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".'],
|
|
32
|
+
[c.WARN_SPLITS_FILTER_EMPTY, c.LOG_PREFIX_SETTINGS + ': feature flag filter configuration must be a non-empty array of filter objects.'],
|
|
33
|
+
[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'],
|
|
33
34
|
|
|
34
35
|
[c.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching MySegments due to an error processing %s notification: %s'],
|
|
35
36
|
[c.STREAMING_PARSING_SPLIT_UPDATE, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching SplitChanges due to an error processing SPLIT_UPDATE notification: %s'],
|
|
36
|
-
[c.
|
|
37
|
-
[c.
|
|
37
|
+
[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.'],
|
|
38
|
+
[c.WARN_LOWERCASE_FLAGSET, '%s: flag set %s should be all lowercase - converting string to lowercase.'],
|
|
39
|
+
[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.'],
|
|
38
40
|
]);
|
package/src/sdkClient/client.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { evaluateFeature, evaluateFeatures, evaluateFeaturesByFlagSets } from '../evaluator';
|
|
2
2
|
import { thenable } from '../utils/promise/thenable';
|
|
3
3
|
import { getMatching, getBucketing } from '../utils/key';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { validateSplitExistence } from '../utils/inputValidation/splitExistence';
|
|
5
|
+
import { validateTrafficTypeExistence } from '../utils/inputValidation/trafficTypeExistence';
|
|
6
6
|
import { SDK_NOT_READY } from '../utils/labels';
|
|
7
|
-
import { CONTROL, TREATMENT, TREATMENTS, TREATMENT_WITH_CONFIG, TREATMENTS_WITH_CONFIG, TRACK, TREATMENTS_WITH_CONFIG_BY_FLAGSETS, TREATMENTS_BY_FLAGSETS, TREATMENTS_BY_FLAGSET, TREATMENTS_WITH_CONFIG_BY_FLAGSET } from '../utils/constants';
|
|
7
|
+
import { CONTROL, TREATMENT, TREATMENTS, TREATMENT_WITH_CONFIG, TREATMENTS_WITH_CONFIG, TRACK, TREATMENTS_WITH_CONFIG_BY_FLAGSETS, TREATMENTS_BY_FLAGSETS, TREATMENTS_BY_FLAGSET, TREATMENTS_WITH_CONFIG_BY_FLAGSET, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENT_WITH_CONFIG, GET_TREATMENT, GET_TREATMENTS, TRACK_FN_LABEL } from '../utils/constants';
|
|
8
8
|
import { IEvaluationResult } from '../evaluator/types';
|
|
9
9
|
import { SplitIO, ImpressionDTO } from '../types';
|
|
10
10
|
import { IMPRESSION, IMPRESSION_QUEUEING } from '../logger/constants';
|
|
@@ -29,12 +29,12 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
29
29
|
const { sdkReadinessManager: { readinessManager }, storage, settings, impressionsTracker, eventTracker, telemetryTracker } = params;
|
|
30
30
|
const { log, mode } = settings;
|
|
31
31
|
|
|
32
|
-
function getTreatment(key: SplitIO.SplitKey, featureFlagName: string, attributes: SplitIO.Attributes | undefined, withConfig = false) {
|
|
32
|
+
function getTreatment(key: SplitIO.SplitKey, featureFlagName: string, attributes: SplitIO.Attributes | undefined, withConfig = false, methodName = GET_TREATMENT) {
|
|
33
33
|
const stopTelemetryTracker = telemetryTracker.trackEval(withConfig ? TREATMENT_WITH_CONFIG : TREATMENT);
|
|
34
34
|
|
|
35
35
|
const wrapUp = (evaluationResult: IEvaluationResult) => {
|
|
36
36
|
const queue: ImpressionDTO[] = [];
|
|
37
|
-
const treatment = processEvaluation(evaluationResult, featureFlagName, key, attributes, withConfig,
|
|
37
|
+
const treatment = processEvaluation(evaluationResult, featureFlagName, key, attributes, withConfig, methodName, queue);
|
|
38
38
|
impressionsTracker.track(queue, attributes);
|
|
39
39
|
|
|
40
40
|
stopTelemetryTracker(queue[0] && queue[0].label);
|
|
@@ -51,17 +51,17 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
function getTreatmentWithConfig(key: SplitIO.SplitKey, featureFlagName: string, attributes: SplitIO.Attributes | undefined) {
|
|
54
|
-
return getTreatment(key, featureFlagName, attributes, true);
|
|
54
|
+
return getTreatment(key, featureFlagName, attributes, true, GET_TREATMENT_WITH_CONFIG);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
function getTreatments(key: SplitIO.SplitKey, featureFlagNames: string[], attributes: SplitIO.Attributes | undefined, withConfig = false) {
|
|
57
|
+
function getTreatments(key: SplitIO.SplitKey, featureFlagNames: string[], attributes: SplitIO.Attributes | undefined, withConfig = false, methodName = GET_TREATMENTS) {
|
|
58
58
|
const stopTelemetryTracker = telemetryTracker.trackEval(withConfig ? TREATMENTS_WITH_CONFIG : TREATMENTS);
|
|
59
59
|
|
|
60
60
|
const wrapUp = (evaluationResults: Record<string, IEvaluationResult>) => {
|
|
61
61
|
const queue: ImpressionDTO[] = [];
|
|
62
62
|
const treatments: Record<string, SplitIO.Treatment | SplitIO.TreatmentWithConfig> = {};
|
|
63
63
|
Object.keys(evaluationResults).forEach(featureFlagName => {
|
|
64
|
-
treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, attributes, withConfig,
|
|
64
|
+
treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, attributes, withConfig, methodName, queue);
|
|
65
65
|
});
|
|
66
66
|
impressionsTracker.track(queue, attributes);
|
|
67
67
|
|
|
@@ -79,18 +79,18 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
function getTreatmentsWithConfig(key: SplitIO.SplitKey, featureFlagNames: string[], attributes: SplitIO.Attributes | undefined) {
|
|
82
|
-
return getTreatments(key, featureFlagNames, attributes, true);
|
|
82
|
+
return getTreatments(key, featureFlagNames, attributes, true, GET_TREATMENTS_WITH_CONFIG);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
function getTreatmentsByFlagSets(key: SplitIO.SplitKey, flagSetNames: string[], attributes: SplitIO.Attributes | undefined, withConfig = false, method: Method = TREATMENTS_BY_FLAGSETS) {
|
|
85
|
+
function getTreatmentsByFlagSets(key: SplitIO.SplitKey, flagSetNames: string[], attributes: SplitIO.Attributes | undefined, withConfig = false, method: Method = TREATMENTS_BY_FLAGSETS, methodName = GET_TREATMENTS_BY_FLAG_SETS) {
|
|
86
86
|
const stopTelemetryTracker = telemetryTracker.trackEval(method);
|
|
87
87
|
|
|
88
|
-
const wrapUp = (evaluationResults: Record<string,IEvaluationResult>) => {
|
|
88
|
+
const wrapUp = (evaluationResults: Record<string, IEvaluationResult>) => {
|
|
89
89
|
const queue: ImpressionDTO[] = [];
|
|
90
90
|
const treatments: Record<string, SplitIO.Treatment | SplitIO.TreatmentWithConfig> = {};
|
|
91
91
|
const evaluations = evaluationResults;
|
|
92
92
|
Object.keys(evaluations).forEach(featureFlagName => {
|
|
93
|
-
treatments[featureFlagName] = processEvaluation(evaluations[featureFlagName], featureFlagName, key, attributes, withConfig,
|
|
93
|
+
treatments[featureFlagName] = processEvaluation(evaluations[featureFlagName], featureFlagName, key, attributes, withConfig, methodName, queue);
|
|
94
94
|
});
|
|
95
95
|
impressionsTracker.track(queue, attributes);
|
|
96
96
|
|
|
@@ -99,22 +99,22 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
99
99
|
};
|
|
100
100
|
|
|
101
101
|
const evaluations = readinessManager.isReady() || readinessManager.isReadyFromCache() ?
|
|
102
|
-
evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage) :
|
|
102
|
+
evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage, methodName) :
|
|
103
103
|
isStorageSync(settings) ? {} : Promise.resolve({}); // Promisify if async
|
|
104
104
|
|
|
105
105
|
return thenable(evaluations) ? evaluations.then((res) => wrapUp(res)) : wrapUp(evaluations);
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
function getTreatmentsWithConfigByFlagSets(key: SplitIO.SplitKey, flagSetNames: string[], attributes: SplitIO.Attributes | undefined) {
|
|
109
|
-
return getTreatmentsByFlagSets(key, flagSetNames, attributes, true, TREATMENTS_WITH_CONFIG_BY_FLAGSETS);
|
|
109
|
+
return getTreatmentsByFlagSets(key, flagSetNames, attributes, true, TREATMENTS_WITH_CONFIG_BY_FLAGSETS, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
function getTreatmentsByFlagSet(key: SplitIO.SplitKey, flagSetName: string, attributes: SplitIO.Attributes | undefined) {
|
|
113
|
-
return getTreatmentsByFlagSets(key, [flagSetName], attributes, false, TREATMENTS_BY_FLAGSET);
|
|
113
|
+
return getTreatmentsByFlagSets(key, [flagSetName], attributes, false, TREATMENTS_BY_FLAGSET, GET_TREATMENTS_BY_FLAG_SET);
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
function getTreatmentsWithConfigByFlagSet(key: SplitIO.SplitKey, flagSetName: string, attributes: SplitIO.Attributes | undefined) {
|
|
117
|
-
return getTreatmentsByFlagSets(key, [flagSetName], attributes, true, TREATMENTS_WITH_CONFIG_BY_FLAGSET);
|
|
117
|
+
return getTreatmentsByFlagSets(key, [flagSetName], attributes, true, TREATMENTS_WITH_CONFIG_BY_FLAGSET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
// Internal function
|
|
@@ -133,7 +133,7 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
133
133
|
const { treatment, label, changeNumber, config = null } = evaluation;
|
|
134
134
|
log.info(IMPRESSION, [featureFlagName, matchingKey, treatment, label]);
|
|
135
135
|
|
|
136
|
-
if (
|
|
136
|
+
if (validateSplitExistence(log, readinessManager, featureFlagName, label, invokingMethodName)) {
|
|
137
137
|
log.info(IMPRESSION_QUEUEING);
|
|
138
138
|
queue.push({
|
|
139
139
|
feature: featureFlagName,
|
|
@@ -171,7 +171,7 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
171
171
|
};
|
|
172
172
|
|
|
173
173
|
// This may be async but we only warn, we don't actually care if it is valid or not in terms of queueing the event.
|
|
174
|
-
|
|
174
|
+
validateTrafficTypeExistence(log, readinessManager, storage.splits, mode, trafficTypeName, TRACK_FN_LABEL);
|
|
175
175
|
|
|
176
176
|
const result = eventTracker.track(eventData, size);
|
|
177
177
|
|