@splitsoftware/splitio-commons 1.10.1-rc.4 → 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.
Files changed (109) hide show
  1. package/CHANGES.txt +16 -10
  2. package/cjs/evaluator/index.js +22 -3
  3. package/cjs/logger/constants.js +6 -4
  4. package/cjs/logger/messages/warn.js +5 -3
  5. package/cjs/sdkClient/client.js +19 -16
  6. package/cjs/sdkClient/clientInputValidation.js +16 -16
  7. package/cjs/sdkFactory/index.js +1 -1
  8. package/cjs/sdkManager/index.js +14 -13
  9. package/cjs/storages/KeyBuilder.js +1 -1
  10. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +3 -10
  11. package/cjs/storages/inMemory/SplitsCacheInMemory.js +2 -10
  12. package/cjs/storages/inRedis/RedisAdapter.js +32 -13
  13. package/cjs/storages/inRedis/SegmentsCacheInRedis.js +2 -2
  14. package/cjs/storages/inRedis/SplitsCacheInRedis.js +38 -22
  15. package/cjs/storages/inRedis/index.js +1 -1
  16. package/cjs/storages/pluggable/SplitsCachePluggable.js +27 -11
  17. package/cjs/storages/pluggable/index.js +1 -1
  18. package/cjs/utils/constants/index.js +16 -2
  19. package/cjs/utils/inputValidation/index.js +5 -5
  20. package/cjs/utils/inputValidation/{splitExistance.js → splitExistence.js} +3 -3
  21. package/cjs/utils/inputValidation/{trafficTypeExistance.js → trafficTypeExistence.js} +6 -6
  22. package/cjs/utils/lang/sets.js +11 -1
  23. package/cjs/utils/settingsValidation/index.js +1 -1
  24. package/cjs/utils/settingsValidation/splitFilters.js +25 -17
  25. package/esm/evaluator/index.js +23 -4
  26. package/esm/logger/constants.js +4 -2
  27. package/esm/logger/messages/warn.js +5 -3
  28. package/esm/sdkClient/client.js +20 -17
  29. package/esm/sdkClient/clientInputValidation.js +18 -18
  30. package/esm/sdkFactory/index.js +1 -1
  31. package/esm/sdkManager/index.js +11 -10
  32. package/esm/storages/KeyBuilder.js +1 -1
  33. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +4 -11
  34. package/esm/storages/inMemory/SplitsCacheInMemory.js +3 -11
  35. package/esm/storages/inRedis/RedisAdapter.js +32 -13
  36. package/esm/storages/inRedis/SegmentsCacheInRedis.js +2 -2
  37. package/esm/storages/inRedis/SplitsCacheInRedis.js +40 -24
  38. package/esm/storages/inRedis/index.js +1 -1
  39. package/esm/storages/pluggable/SplitsCachePluggable.js +29 -13
  40. package/esm/storages/pluggable/index.js +1 -1
  41. package/esm/utils/constants/index.js +14 -0
  42. package/esm/utils/inputValidation/index.js +2 -2
  43. package/esm/utils/inputValidation/{splitExistance.js → splitExistence.js} +1 -1
  44. package/esm/utils/inputValidation/{trafficTypeExistance.js → trafficTypeExistence.js} +4 -4
  45. package/esm/utils/lang/sets.js +9 -0
  46. package/esm/utils/settingsValidation/index.js +1 -1
  47. package/esm/utils/settingsValidation/splitFilters.js +17 -9
  48. package/package.json +1 -1
  49. package/src/evaluator/index.ts +28 -5
  50. package/src/logger/constants.ts +4 -2
  51. package/src/logger/messages/warn.ts +9 -7
  52. package/src/sdkClient/client.ts +18 -18
  53. package/src/sdkClient/clientInputValidation.ts +18 -18
  54. package/src/sdkFactory/index.ts +1 -1
  55. package/src/sdkFactory/types.ts +3 -7
  56. package/src/sdkManager/index.ts +14 -14
  57. package/src/storages/AbstractSplitsCacheAsync.ts +1 -1
  58. package/src/storages/AbstractSplitsCacheSync.ts +1 -1
  59. package/src/storages/KeyBuilder.ts +1 -1
  60. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +8 -15
  61. package/src/storages/inMemory/SplitsCacheInMemory.ts +6 -14
  62. package/src/storages/inRedis/EventsCacheInRedis.ts +3 -3
  63. package/src/storages/inRedis/ImpressionCountsCacheInRedis.ts +3 -3
  64. package/src/storages/inRedis/ImpressionsCacheInRedis.ts +3 -3
  65. package/src/storages/inRedis/RedisAdapter.ts +38 -16
  66. package/src/storages/inRedis/SegmentsCacheInRedis.ts +5 -5
  67. package/src/storages/inRedis/SplitsCacheInRedis.ts +49 -28
  68. package/src/storages/inRedis/TelemetryCacheInRedis.ts +2 -2
  69. package/src/storages/inRedis/UniqueKeysCacheInRedis.ts +3 -3
  70. package/src/storages/inRedis/index.ts +1 -1
  71. package/src/storages/pluggable/SplitsCachePluggable.ts +35 -13
  72. package/src/storages/pluggable/index.ts +1 -1
  73. package/src/storages/types.ts +5 -5
  74. package/src/trackers/impressionObserver/utils.ts +1 -1
  75. package/src/types.ts +0 -2
  76. package/src/utils/constants/index.ts +16 -0
  77. package/src/utils/inputValidation/index.ts +2 -2
  78. package/src/utils/inputValidation/{splitExistance.ts → splitExistence.ts} +1 -1
  79. package/src/utils/inputValidation/{trafficTypeExistance.ts → trafficTypeExistence.ts} +4 -4
  80. package/src/utils/lang/sets.ts +9 -1
  81. package/src/utils/redis/RedisMock.ts +1 -3
  82. package/src/utils/settingsValidation/index.ts +1 -1
  83. package/src/utils/settingsValidation/splitFilters.ts +19 -11
  84. package/types/evaluator/index.d.ts +1 -1
  85. package/types/logger/constants.d.ts +4 -2
  86. package/types/sdkFactory/types.d.ts +3 -3
  87. package/types/sdkManager/index.d.ts +2 -3
  88. package/types/storages/AbstractSplitsCacheAsync.d.ts +1 -1
  89. package/types/storages/AbstractSplitsCacheSync.d.ts +1 -1
  90. package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +1 -1
  91. package/types/storages/inMemory/SplitsCacheInMemory.d.ts +1 -1
  92. package/types/storages/inRedis/EventsCacheInRedis.d.ts +2 -2
  93. package/types/storages/inRedis/ImpressionCountsCacheInRedis.d.ts +3 -2
  94. package/types/storages/inRedis/ImpressionsCacheInRedis.d.ts +2 -2
  95. package/types/storages/inRedis/RedisAdapter.d.ts +1 -1
  96. package/types/storages/inRedis/SegmentsCacheInRedis.d.ts +3 -3
  97. package/types/storages/inRedis/SplitsCacheInRedis.d.ts +10 -14
  98. package/types/storages/inRedis/TelemetryCacheInRedis.d.ts +2 -2
  99. package/types/storages/inRedis/UniqueKeysCacheInRedis.d.ts +3 -2
  100. package/types/storages/pluggable/SplitsCachePluggable.d.ts +10 -9
  101. package/types/storages/types.d.ts +5 -5
  102. package/types/trackers/impressionObserver/utils.d.ts +1 -1
  103. package/types/types.d.ts +0 -2
  104. package/types/utils/constants/index.d.ts +12 -0
  105. package/types/utils/inputValidation/index.d.ts +2 -2
  106. package/types/utils/inputValidation/splitExistence.d.ts +7 -0
  107. package/types/utils/inputValidation/trafficTypeExistence.d.ts +9 -0
  108. package/types/utils/lang/sets.d.ts +1 -0
  109. package/types/utils/settingsValidation/splitFilters.d.ts +3 -2
@@ -9,7 +9,8 @@ var thenable_1 = require("../../utils/promise/thenable");
9
9
  var timeout_1 = require("../../utils/promise/timeout");
10
10
  var LOG_PREFIX = 'storage:redis-adapter: ';
11
11
  // If we ever decide to fully wrap every method, there's a Commander.getBuiltinCommands from ioredis.
12
- var METHODS_TO_PROMISE_WRAP = ['set', 'exec', 'del', 'get', 'keys', 'sadd', 'srem', 'sismember', 'smembers', 'incr', 'rpush', 'pipeline', 'expire', 'mget', 'lrange', 'ltrim', 'hset'];
12
+ var METHODS_TO_PROMISE_WRAP = ['set', 'exec', 'del', 'get', 'keys', 'sadd', 'srem', 'sismember', 'smembers', 'incr', 'rpush', 'expire', 'mget', 'lrange', 'ltrim', 'hset', 'hincrby', 'popNRaw'];
13
+ var METHODS_TO_PROMISE_WRAP_EXEC = ['pipeline'];
13
14
  // Not part of the settings since it'll vary on each storage. We should be removing storage specific logic from elsewhere.
14
15
  var DEFAULT_OPTIONS = {
15
16
  connectionTimeout: 10000,
@@ -27,6 +28,7 @@ var DEFAULT_LIBRARY_OPTIONS = {
27
28
  var RedisAdapter = /** @class */ (function (_super) {
28
29
  (0, tslib_1.__extends)(RedisAdapter, _super);
29
30
  function RedisAdapter(log, storageSettings) {
31
+ if (storageSettings === void 0) { storageSettings = {}; }
30
32
  var _this = this;
31
33
  var options = RedisAdapter._defineOptions(storageSettings);
32
34
  // Call the ioredis constructor
@@ -58,14 +60,15 @@ var RedisAdapter = /** @class */ (function (_super) {
58
60
  };
59
61
  RedisAdapter.prototype._setTimeoutWrappers = function () {
60
62
  var instance = this;
61
- METHODS_TO_PROMISE_WRAP.forEach(function (method) {
62
- var originalMethod = instance[method];
63
- instance[method] = function () {
63
+ var wrapCommand = function (originalMethod, methodName) {
64
+ // The value of "this" in this function should be the instance actually executing the method. It might be the instance referred (the base one)
65
+ // or it can be the instance of a Pipeline object.
66
+ return function () {
64
67
  var params = arguments;
68
+ var caller = this;
65
69
  function commandWrapper() {
66
- instance.log.debug(LOG_PREFIX + ("Executing " + method + "."));
67
- // Return original method
68
- var result = originalMethod.apply(instance, params);
70
+ instance.log.debug(LOG_PREFIX + "Executing " + methodName + ".");
71
+ var result = originalMethod.apply(caller, params);
69
72
  if ((0, thenable_1.thenable)(result)) {
70
73
  // For handling pending commands on disconnect, add to the set and remove once finished.
71
74
  // On sync commands there's no need, only thenables.
@@ -76,7 +79,7 @@ var RedisAdapter = /** @class */ (function (_super) {
76
79
  // Both success and error remove from queue.
77
80
  result.then(cleanUpRunningCommandsCb, cleanUpRunningCommandsCb);
78
81
  return (0, timeout_1.timeout)(instance._options.operationTimeout, result).catch(function (err) {
79
- instance.log.error(LOG_PREFIX + (method + " operation threw an error or exceeded configured timeout of " + instance._options.operationTimeout + "ms. Message: " + err));
82
+ instance.log.error("" + LOG_PREFIX + methodName + " operation threw an error or exceeded configured timeout of " + instance._options.operationTimeout + "ms. Message: " + err);
80
83
  // Handling is not the adapter responsibility.
81
84
  throw err;
82
85
  });
@@ -84,12 +87,12 @@ var RedisAdapter = /** @class */ (function (_super) {
84
87
  return result;
85
88
  }
86
89
  if (instance._notReadyCommandsQueue) {
87
- return new Promise(function (res, rej) {
90
+ return new Promise(function (resolve, reject) {
88
91
  instance._notReadyCommandsQueue.unshift({
89
- resolve: res,
90
- reject: rej,
92
+ resolve: resolve,
93
+ reject: reject,
91
94
  command: commandWrapper,
92
- name: method.toUpperCase()
95
+ name: methodName.toUpperCase()
93
96
  });
94
97
  });
95
98
  }
@@ -97,6 +100,22 @@ var RedisAdapter = /** @class */ (function (_super) {
97
100
  return commandWrapper();
98
101
  }
99
102
  };
103
+ };
104
+ // Wrap regular async methods to track timeouts and queue when Redis is not yet executing commands.
105
+ METHODS_TO_PROMISE_WRAP.forEach(function (methodName) {
106
+ var originalFn = instance[methodName];
107
+ instance[methodName] = wrapCommand(originalFn, methodName);
108
+ });
109
+ // Special handling for pipeline~like methods. We need to wrap the async trigger, which is exec, but return the Pipeline right away.
110
+ METHODS_TO_PROMISE_WRAP_EXEC.forEach(function (methodName) {
111
+ var originalFn = instance[methodName];
112
+ // "First level wrapper" to handle the sync execution and wrap async, queueing later if applicable.
113
+ instance[methodName] = function () {
114
+ var res = originalFn.apply(instance, arguments);
115
+ var originalExec = res.exec;
116
+ res.exec = wrapCommand(originalExec, methodName + '.exec').bind(res);
117
+ return res;
118
+ };
100
119
  });
101
120
  };
102
121
  RedisAdapter.prototype._setDisconnectWrapper = function () {
@@ -107,7 +126,7 @@ var RedisAdapter = /** @class */ (function (_super) {
107
126
  for (var _i = 0; _i < arguments.length; _i++) {
108
127
  params[_i] = arguments[_i];
109
128
  }
110
- setTimeout(function deferedDisconnect() {
129
+ setTimeout(function deferredDisconnect() {
111
130
  if (instance._runningCommands.size > 0) {
112
131
  instance.log.info(LOG_PREFIX + ("Attempting to disconnect but there are " + instance._runningCommands.size + " commands still waiting for resolution. Defering disconnection until those finish."));
113
132
  Promise.all((0, sets_1.setToArray)(instance._runningCommands))
@@ -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/review. It is not being used.
57
+ // @TODO remove or implement. It is not being used.
58
58
  SegmentsCacheInRedis.prototype.clear = function () {
59
- return this.redis.flushdb().then(function (status) { return status === 'OK'; });
59
+ return Promise.resolve();
60
60
  };
61
61
  return SegmentsCacheInRedis;
62
62
  }());
@@ -22,11 +22,12 @@ function processPipelineAnswer(results) {
22
22
  */
23
23
  var SplitsCacheInRedis = /** @class */ (function (_super) {
24
24
  (0, tslib_1.__extends)(SplitsCacheInRedis, _super);
25
- function SplitsCacheInRedis(log, keys, redis) {
25
+ function SplitsCacheInRedis(log, keys, redis, splitFiltersValidation) {
26
26
  var _this = _super.call(this) || this;
27
27
  _this.log = log;
28
28
  _this.redis = redis;
29
29
  _this.keys = keys;
30
+ _this.flagSetsFilter = splitFiltersValidation ? splitFiltersValidation.groupedFilters.bySet : [];
30
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.
31
32
  // But it is done just to avoid getting the ioredis message `Unhandled error event`.
32
33
  _this.redis.on('error', function (e) {
@@ -49,6 +50,18 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
49
50
  var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
50
51
  return this.redis.incr(ttKey);
51
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
+ };
52
65
  /**
53
66
  * Add a given split.
54
67
  * The returned promise is resolved when the operation success
@@ -58,16 +71,16 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
58
71
  var _this = this;
59
72
  var splitKey = this.keys.buildSplitKey(name);
60
73
  return this.redis.get(splitKey).then(function (splitFromStorage) {
61
- // handling parsing errors
62
- var parsedPreviousSplit, newStringifiedSplit;
74
+ // handling parsing error
75
+ var parsedPreviousSplit, stringifiedNewSplit;
63
76
  try {
64
77
  parsedPreviousSplit = splitFromStorage ? JSON.parse(splitFromStorage) : undefined;
65
- newStringifiedSplit = JSON.stringify(split);
78
+ stringifiedNewSplit = JSON.stringify(split);
66
79
  }
67
80
  catch (e) {
68
81
  throw new Error('Error parsing feature flag definition: ' + e);
69
82
  }
70
- return _this.redis.set(splitKey, newStringifiedSplit).then(function () {
83
+ return _this.redis.set(splitKey, stringifiedNewSplit).then(function () {
71
84
  // avoid unnecessary increment/decrement operations
72
85
  if (parsedPreviousSplit && parsedPreviousSplit.trafficTypeName === split.trafficTypeName)
73
86
  return;
@@ -76,7 +89,7 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
76
89
  if (parsedPreviousSplit)
77
90
  return _this._decrementCounts(parsedPreviousSplit);
78
91
  });
79
- });
92
+ }).then(function () { return _this._updateFlagSets(name, parsedPreviousSplit && parsedPreviousSplit.sets, split.sets); });
80
93
  }).then(function () { return true; });
81
94
  };
82
95
  /**
@@ -97,8 +110,9 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
97
110
  var _this = this;
98
111
  return this.getSplit(name).then(function (split) {
99
112
  if (split) {
100
- _this._decrementCounts(split);
113
+ return _this._decrementCounts(split).then(function () { return _this._updateFlagSets(name, split.sets); });
101
114
  }
115
+ }).then(function () {
102
116
  return _this.redis.del(_this.keys.buildSplitKey(name));
103
117
  });
104
118
  };
@@ -173,14 +187,20 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
173
187
  return this.redis.keys(this.keys.searchPatternForSplitKeys()).then(function (listOfKeys) { return listOfKeys.map(_this.keys.extractKey); });
174
188
  };
175
189
  /**
176
- * Get list of split names related to a given flag set names list.
177
- * The returned promise is resolved with the list of split names,
178
- * or rejected if wrapper operation fails.
179
- * @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).
180
193
  */
181
- SplitsCacheInRedis.prototype.getNamesByFlagSets = function () {
182
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
183
- return new Promise(function (flagSets) { return new sets_1._Set([]); });
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); }); });
184
204
  };
185
205
  /**
186
206
  * Check traffic type existence.
@@ -197,24 +217,20 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
197
217
  return false; // if entry doesn't exist, means that TT doesn't exist
198
218
  ttCount = parseInt(ttCount, 10);
199
219
  if (!(0, lang_1.isFiniteNumber)(ttCount) || ttCount < 0) {
200
- _this.log.info(constants_1.LOG_PREFIX + ("Could not validate traffic type existance of " + trafficType + " due to data corruption of some sorts."));
220
+ _this.log.info(constants_1.LOG_PREFIX + ("Could not validate traffic type existence of " + trafficType + " due to data corruption of some sorts."));
201
221
  return false;
202
222
  }
203
223
  return ttCount > 0;
204
224
  })
205
225
  .catch(function (e) {
206
- _this.log.error(constants_1.LOG_PREFIX + ("Could not validate traffic type existance of " + trafficType + " due to an error: " + e + "."));
226
+ _this.log.error(constants_1.LOG_PREFIX + ("Could not validate traffic type existence of " + trafficType + " due to an error: " + e + "."));
207
227
  // If there is an error, bypass the validation so the event can get tracked.
208
228
  return true;
209
229
  });
210
230
  };
211
- /**
212
- * Delete everything in the current database.
213
- *
214
- * @NOTE documentation says it never fails.
215
- */
231
+ // @TODO remove or implement. It is not being used.
216
232
  SplitsCacheInRedis.prototype.clear = function () {
217
- return this.redis.flushdb().then(function (status) { return status === 'OK'; });
233
+ return Promise.resolve();
218
234
  };
219
235
  /**
220
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,
@@ -17,11 +17,12 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
17
17
  * @param keys Key builder.
18
18
  * @param wrapper Adapted wrapper storage.
19
19
  */
20
- function SplitsCachePluggable(log, keys, wrapper) {
20
+ function SplitsCachePluggable(log, keys, wrapper, splitFiltersValidation) {
21
21
  var _this = _super.call(this) || this;
22
22
  _this.log = log;
23
23
  _this.keys = keys;
24
24
  _this.wrapper = wrapper;
25
+ _this.flagSetsFilter = splitFiltersValidation ? splitFiltersValidation.groupedFilters.bySet : [];
25
26
  return _this;
26
27
  }
27
28
  SplitsCachePluggable.prototype._decrementCounts = function (split) {
@@ -36,6 +37,18 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
36
37
  var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
37
38
  return this.wrapper.incr(ttKey);
38
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
+ };
39
52
  /**
40
53
  * Add a given split.
41
54
  * The returned promise is resolved when the operation success
@@ -63,7 +76,7 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
63
76
  if (parsedPreviousSplit)
64
77
  return _this._decrementCounts(parsedPreviousSplit);
65
78
  });
66
- });
79
+ }).then(function () { return _this._updateFlagSets(name, parsedPreviousSplit && parsedPreviousSplit.sets, split.sets); });
67
80
  }).then(function () { return true; });
68
81
  };
69
82
  /**
@@ -84,8 +97,9 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
84
97
  var _this = this;
85
98
  return this.getSplit(name).then(function (split) {
86
99
  if (split) {
87
- _this._decrementCounts(split);
100
+ return _this._decrementCounts(split).then(function () { return _this._updateFlagSets(name, split.sets); });
88
101
  }
102
+ }).then(function () {
89
103
  return _this.wrapper.del(_this.keys.buildSplitKey(name));
90
104
  });
91
105
  };
@@ -147,14 +161,16 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
147
161
  return this.wrapper.getKeysByPrefix(this.keys.buildSplitKeyPrefix()).then(function (listOfKeys) { return listOfKeys.map(_this.keys.extractKey); });
148
162
  };
149
163
  /**
150
- * Get list of split names related to a given flag set names list.
151
- * The returned promise is resolved with the list of split names,
152
- * or rejected if wrapper operation fails.
153
- * @todo this is a no-op method to be implemented
154
- */
155
- SplitsCachePluggable.prototype.getNamesByFlagSets = function () {
156
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
157
- return new Promise(function (flagSets) { return new sets_1._Set([]); });
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); }); });
158
174
  };
159
175
  /**
160
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.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 = 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.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 = 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.validateTrafficTypeExistance = exports.validateSplitExistance = 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;
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 splitExistance_1 = require("./splitExistance");
28
- Object.defineProperty(exports, "validateSplitExistance", { enumerable: true, get: function () { return splitExistance_1.validateSplitExistance; } });
29
- var trafficTypeExistance_1 = require("./trafficTypeExistance");
30
- Object.defineProperty(exports, "validateTrafficTypeExistance", { enumerable: true, get: function () { return trafficTypeExistance_1.validateTrafficTypeExistance; } });
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.validateSplitExistance = void 0;
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 validateSplitExistance(log, readinessManager, splitName, labelOrSplitObj, method) {
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.validateSplitExistance = validateSplitExistance;
19
+ exports.validateSplitExistence = validateSplitExistence;
@@ -1,16 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateTrafficTypeExistance = void 0;
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 logTTExistanceWarning(log, maybeTT, method) {
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 validateTrafficTypeExistance(log, readinessManager, splitsCache, mode, maybeTT, method) {
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
- logTTExistanceWarning(log, maybeTT, method);
21
+ logTTExistenceWarning(log, maybeTT, method);
22
22
  return isValid; // propagate result
23
23
  });
24
24
  }
25
25
  else {
26
26
  if (!res)
27
- logTTExistanceWarning(log, maybeTT, method);
27
+ logTTExistenceWarning(log, maybeTT, method);
28
28
  return res;
29
29
  }
30
30
  }
31
- exports.validateTrafficTypeExistance = validateTrafficTypeExistance;
31
+ exports.validateTrafficTypeExistence = validateTrafficTypeExistence;
@@ -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.flagSetsAreValid = exports.validateSplitFilters = void 0;
3
+ exports.validateFlagSets = exports.validateSplitFilters = void 0;
4
+ var constants_1 = require("../constants");
4
5
  var splits_1 = require("../inputValidation/splits");
5
- var constants_1 = require("../../logger/constants");
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, constants_1.LOG_PREFIX_SETTINGS, type + " filter", type + " filter value");
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 in account:
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(constants_1.WARN_SPLITS_FILTER_LOWERCASE_SET, [flagSet]);
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(constants_1.WARN_SPLITS_FILTER_INVALID_SET, [flagSet, VALID_FLAGSET_REGEX, flagSet]);
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(constants_1.WARN_SPLITS_FILTER_EMPTY);
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(constants_1.WARN_SPLITS_FILTER_INVALID, [index]);
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(constants_1.ERROR_SETS_FILTER_EXCLUSIVE);
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(constants_1.SETTINGS_SPLITS_FILTER, [res.queryString]);
179
+ log.debug(constants_2.SETTINGS_SPLITS_FILTER, [res.queryString]);
172
180
  return res;
173
181
  }
174
182
  exports.validateSplitFilters = validateSplitFilters;
175
- function flagSetsAreValid(log, method, flagSets, flagSetsInConfig) {
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(constants_1.WARN_FLAGSET_NOT_CONFIGURED, [method, flagSet]);
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.flagSetsAreValid = flagSetsAreValid;
197
+ exports.validateFlagSets = validateFlagSets;