@splitsoftware/splitio-commons 1.10.1-rc.3 → 1.11.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 CHANGED
@@ -1,4 +1,4 @@
1
- 1.11.0 (November XX, 2023)
1
+ 1.11.0 (November 3, 2023)
2
2
  - Added support for Flag Sets on the SDK, which enables grouping feature flags and interacting with the group rather than individually (more details in our documentation):
3
3
  - Added new variations of the get treatment methods to support evaluating flags in given flag set/s.
4
4
  - getTreatmentsByFlagSet and getTreatmentsByFlagSets
@@ -6,6 +6,7 @@
6
6
  - Added a new optional Split Filter configuration option. This allows the SDK and Split services to only synchronize the flags in the specified flag sets, avoiding unused or unwanted flags from being synced on the SDK instance, bringing all the benefits from a reduced payload.
7
7
  - Note: Only applicable when the SDK is in charge of the rollout data synchronization. When not applicable, the SDK will log a warning on init.
8
8
  - Added `sets` property to the `SplitView` object returned by the `split` and `splits` methods of the SDK manager to expose flag sets on flag views.
9
+ - Bugfixing - Fixed SDK key validation in NodeJS to ensure the SDK_READY_TIMED_OUT event is emitted when a client-side type SDK key is provided instead of a server-side one (Related to issue https://github.com/splitio/javascript-client/issues/768).
9
10
 
10
11
  1.10.0 (October 20, 2023)
11
12
  - Added `defaultTreatment` property to the `SplitView` object returned by the `split` and `splits` methods of the SDK manager (Related to issue https://github.com/splitio/javascript-commons/issues/225).
@@ -68,7 +68,10 @@ function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage) {
68
68
  }
69
69
  // evaluate related features
70
70
  return (0, thenable_1.thenable)(storedFlagNames) ?
71
- storedFlagNames.then(function (splitNames) { return evaluateFeatures(log, key, (0, sets_1.setToArray)(splitNames), attributes, storage); }) :
71
+ storedFlagNames.then(function (splitNames) { return evaluateFeatures(log, key, (0, sets_1.setToArray)(splitNames), attributes, storage); })
72
+ .catch(function () {
73
+ return {};
74
+ }) :
72
75
  evaluateFeatures(log, key, (0, sets_1.setToArray)(storedFlagNames), attributes, storage);
73
76
  }
74
77
  exports.evaluateFeaturesByFlagSets = evaluateFeaturesByFlagSets;
@@ -101,7 +101,12 @@ function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
101
101
  refCount++;
102
102
  return readinessManagerFactory(EventEmitter, readyTimeout, splits);
103
103
  },
104
+ // @TODO review/remove next methods when non-recoverable errors are reworked
105
+ // Called on consumer mode, when storage fails to connect
104
106
  timeout: timeout,
107
+ // Called on 403 error (client-side SDK key on server-side), to set the SDK as destroyed for
108
+ // tracking and evaluations, while keeping event listeners to emit SDK_READY_TIMED_OUT event
109
+ setDestroyed: function () { isDestroyed = true; },
105
110
  destroy: function () {
106
111
  isDestroyed = true;
107
112
  segments.removeAllListeners();
@@ -17,7 +17,7 @@ var KeyBuilder = /** @class */ (function () {
17
17
  return this.prefix + ".trafficType." + trafficType;
18
18
  };
19
19
  KeyBuilder.prototype.buildFlagSetKey = function (flagSet) {
20
- return this.prefix + ".flagset." + flagSet;
20
+ return this.prefix + ".flagSet." + flagSet;
21
21
  };
22
22
  KeyBuilder.prototype.buildSplitKey = function (splitName) {
23
23
  return this.prefix + ".split." + splitName;
@@ -5,7 +5,6 @@ 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");
9
8
  /**
10
9
  * Discard errors for an answer of multiple operations.
11
10
  */
@@ -179,8 +178,8 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
179
178
  * @todo this is a no-op method to be implemented
180
179
  */
181
180
  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([]); });
181
+ this.log.error(constants_1.LOG_PREFIX + 'ByFlagSet/s evaluations are not supported with Redis storage yet.');
182
+ return Promise.reject();
184
183
  };
185
184
  /**
186
185
  * Check traffic type existence.
@@ -5,7 +5,6 @@ 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");
9
8
  /**
10
9
  * ISplitsCacheAsync implementation for pluggable storages.
11
10
  */
@@ -153,8 +152,8 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
153
152
  * @todo this is a no-op method to be implemented
154
153
  */
155
154
  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([]); });
155
+ this.log.error(constants_1.LOG_PREFIX + 'ByFlagSet/s evaluations are not supported with pluggable storage yet.');
156
+ return Promise.reject();
158
157
  };
159
158
  /**
160
159
  * Check traffic type existence.
@@ -83,7 +83,7 @@ function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segments, read
83
83
  // If the operation is forbidden, it may be due to permissions. Destroy the SDK instance.
84
84
  // @TODO although factory status is destroyed, synchronization is not stopped
85
85
  if (readiness)
86
- readiness.destroy();
86
+ readiness.setDestroyed();
87
87
  log.error(constants_2.LOG_PREFIX_INSTANTIATION + ": you passed a client-side type authorizationKey, please grab an SDK Key from the Split user interface that is of type server-side.");
88
88
  }
89
89
  else {
@@ -62,7 +62,10 @@ export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, stora
62
62
  }
63
63
  // evaluate related features
64
64
  return thenable(storedFlagNames) ?
65
- storedFlagNames.then(function (splitNames) { return evaluateFeatures(log, key, setToArray(splitNames), attributes, storage); }) :
65
+ storedFlagNames.then(function (splitNames) { return evaluateFeatures(log, key, setToArray(splitNames), attributes, storage); })
66
+ .catch(function () {
67
+ return {};
68
+ }) :
66
69
  evaluateFeatures(log, key, setToArray(storedFlagNames), attributes, storage);
67
70
  }
68
71
  function getEvaluation(log, splitJSON, key, attributes, storage) {
@@ -98,7 +98,12 @@ export function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
98
98
  refCount++;
99
99
  return readinessManagerFactory(EventEmitter, readyTimeout, splits);
100
100
  },
101
+ // @TODO review/remove next methods when non-recoverable errors are reworked
102
+ // Called on consumer mode, when storage fails to connect
101
103
  timeout: timeout,
104
+ // Called on 403 error (client-side SDK key on server-side), to set the SDK as destroyed for
105
+ // tracking and evaluations, while keeping event listeners to emit SDK_READY_TIMED_OUT event
106
+ setDestroyed: function () { isDestroyed = true; },
102
107
  destroy: function () {
103
108
  isDestroyed = true;
104
109
  segments.removeAllListeners();
@@ -13,7 +13,7 @@ var KeyBuilder = /** @class */ (function () {
13
13
  return this.prefix + ".trafficType." + trafficType;
14
14
  };
15
15
  KeyBuilder.prototype.buildFlagSetKey = function (flagSet) {
16
- return this.prefix + ".flagset." + flagSet;
16
+ return this.prefix + ".flagSet." + flagSet;
17
17
  };
18
18
  KeyBuilder.prototype.buildSplitKey = function (splitName) {
19
19
  return this.prefix + ".split." + splitName;
@@ -2,7 +2,6 @@ import { __extends } 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 } from '../../utils/lang/sets';
6
5
  /**
7
6
  * Discard errors for an answer of multiple operations.
8
7
  */
@@ -176,8 +175,8 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
176
175
  * @todo this is a no-op method to be implemented
177
176
  */
178
177
  SplitsCacheInRedis.prototype.getNamesByFlagSets = function () {
179
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
180
- return new Promise(function (flagSets) { return new _Set([]); });
178
+ this.log.error(LOG_PREFIX + 'ByFlagSet/s evaluations are not supported with Redis storage yet.');
179
+ return Promise.reject();
181
180
  };
182
181
  /**
183
182
  * Check traffic type existence.
@@ -2,7 +2,6 @@ import { __extends } 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 } from '../../utils/lang/sets';
6
5
  /**
7
6
  * ISplitsCacheAsync implementation for pluggable storages.
8
7
  */
@@ -150,8 +149,8 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
150
149
  * @todo this is a no-op method to be implemented
151
150
  */
152
151
  SplitsCachePluggable.prototype.getNamesByFlagSets = function () {
153
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
154
- return new Promise(function (flagSets) { return new _Set([]); });
152
+ this.log.error(LOG_PREFIX + 'ByFlagSet/s evaluations are not supported with pluggable storage yet.');
153
+ return Promise.reject();
155
154
  };
156
155
  /**
157
156
  * Check traffic type existence.
@@ -80,7 +80,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
80
80
  // If the operation is forbidden, it may be due to permissions. Destroy the SDK instance.
81
81
  // @TODO although factory status is destroyed, synchronization is not stopped
82
82
  if (readiness)
83
- readiness.destroy();
83
+ readiness.setDestroyed();
84
84
  log.error(LOG_PREFIX_INSTANTIATION + ": you passed a client-side type authorizationKey, please grab an SDK Key from the Split user interface that is of type server-side.");
85
85
  }
86
86
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splitsoftware/splitio-commons",
3
- "version": "1.10.1-rc.3",
3
+ "version": "1.11.0",
4
4
  "description": "Split Javascript SDK common components",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",
@@ -94,7 +94,7 @@ export function evaluateFeaturesByFlagSets(
94
94
  flagSets: string[],
95
95
  attributes: SplitIO.Attributes | undefined,
96
96
  storage: IStorageSync | IStorageAsync,
97
- ): MaybeThenable<Record<string,IEvaluationResult>> {
97
+ ): MaybeThenable<Record<string, IEvaluationResult>> {
98
98
  let storedFlagNames: MaybeThenable<ISet<string>>;
99
99
 
100
100
  // get features by flag sets
@@ -107,7 +107,10 @@ export function evaluateFeaturesByFlagSets(
107
107
 
108
108
  // evaluate related features
109
109
  return thenable(storedFlagNames) ?
110
- storedFlagNames.then((splitNames) => evaluateFeatures(log, key, setToArray(splitNames), attributes, storage)) :
110
+ storedFlagNames.then((splitNames) => evaluateFeatures(log, key, setToArray(splitNames), attributes, storage))
111
+ .catch(() => {
112
+ return {};
113
+ }) :
111
114
  evaluateFeatures(log, key, setToArray(storedFlagNames), attributes, storage);
112
115
  }
113
116
 
@@ -112,7 +112,12 @@ export function readinessManagerFactory(
112
112
  return readinessManagerFactory(EventEmitter, readyTimeout, splits);
113
113
  },
114
114
 
115
+ // @TODO review/remove next methods when non-recoverable errors are reworked
116
+ // Called on consumer mode, when storage fails to connect
115
117
  timeout,
118
+ // Called on 403 error (client-side SDK key on server-side), to set the SDK as destroyed for
119
+ // tracking and evaluations, while keeping event listeners to emit SDK_READY_TIMED_OUT event
120
+ setDestroyed() { isDestroyed = true; },
116
121
 
117
122
  destroy() {
118
123
  isDestroyed = true;
@@ -55,6 +55,7 @@ export interface IReadinessManager {
55
55
  isOperational(): boolean,
56
56
 
57
57
  timeout(): void,
58
+ setDestroyed(): void,
58
59
  destroy(): void,
59
60
 
60
61
  /** for client-side */
@@ -21,7 +21,7 @@ export class KeyBuilder {
21
21
  }
22
22
 
23
23
  buildFlagSetKey(flagSet: string) {
24
- return `${this.prefix}.flagset.${flagSet}`;
24
+ return `${this.prefix}.flagSet.${flagSet}`;
25
25
  }
26
26
 
27
27
  buildSplitKey(splitName: string) {
@@ -5,7 +5,7 @@ import { ILogger } from '../../logger/types';
5
5
  import { LOG_PREFIX } from './constants';
6
6
  import { ISplit } from '../../dtos/types';
7
7
  import { AbstractSplitsCacheAsync } from '../AbstractSplitsCacheAsync';
8
- import { ISet, _Set } from '../../utils/lang/sets';
8
+ import { ISet } from '../../utils/lang/sets';
9
9
 
10
10
  /**
11
11
  * Discard errors for an answer of multiple operations.
@@ -196,8 +196,8 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
196
196
  * @todo this is a no-op method to be implemented
197
197
  */
198
198
  getNamesByFlagSets(): Promise<ISet<string>> {
199
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
200
- return new Promise(flagSets => new _Set([]));
199
+ this.log.error(LOG_PREFIX + 'ByFlagSet/s evaluations are not supported with Redis storage yet.');
200
+ return Promise.reject();
201
201
  }
202
202
 
203
203
  /**
@@ -5,7 +5,7 @@ import { ILogger } from '../../logger/types';
5
5
  import { ISplit } from '../../dtos/types';
6
6
  import { LOG_PREFIX } from './constants';
7
7
  import { AbstractSplitsCacheAsync } from '../AbstractSplitsCacheAsync';
8
- import { ISet, _Set } from '../../utils/lang/sets';
8
+ import { ISet } from '../../utils/lang/sets';
9
9
 
10
10
  /**
11
11
  * ISplitsCacheAsync implementation for pluggable storages.
@@ -162,8 +162,8 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
162
162
  * @todo this is a no-op method to be implemented
163
163
  */
164
164
  getNamesByFlagSets(): Promise<ISet<string>> {
165
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
166
- return new Promise(flagSets => new _Set([]));
165
+ this.log.error(LOG_PREFIX + 'ByFlagSet/s evaluations are not supported with pluggable storage yet.');
166
+ return Promise.reject();
167
167
  }
168
168
 
169
169
  /**
@@ -96,7 +96,7 @@ export function segmentChangesUpdaterFactory(
96
96
  if (error && error.statusCode === 403) {
97
97
  // If the operation is forbidden, it may be due to permissions. Destroy the SDK instance.
98
98
  // @TODO although factory status is destroyed, synchronization is not stopped
99
- if (readiness) readiness.destroy();
99
+ if (readiness) readiness.setDestroyed();
100
100
  log.error(`${LOG_PREFIX_INSTANTIATION}: you passed a client-side type authorizationKey, please grab an SDK Key from the Split user interface that is of type server-side.`);
101
101
  } else {
102
102
  log.warn(`${LOG_PREFIX_SYNC_SEGMENTS}Error while doing fetch of segments. ${error}`);
@@ -42,6 +42,7 @@ export interface IReadinessManager {
42
42
  isDestroyed(): boolean;
43
43
  isOperational(): boolean;
44
44
  timeout(): void;
45
+ setDestroyed(): void;
45
46
  destroy(): void;
46
47
  /** for client-side */
47
48
  shared(readyTimeout?: number): IReadinessManager;