@splitsoftware/splitio-commons 1.2.1-rc.8 → 1.2.1-rc.9
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/cjs/sdkClient/client.js +1 -1
- package/cjs/sdkClient/clientCS.js +1 -1
- package/cjs/sdkClient/sdkClientMethodCS.js +1 -5
- package/cjs/sdkClient/sdkClientMethodCSWithTT.js +1 -9
- package/cjs/storages/inRedis/RedisAdapter.js +9 -2
- package/cjs/utils/lang/maps.js +16 -2
- package/cjs/utils/settingsValidation/index.js +20 -4
- package/esm/sdkClient/client.js +1 -1
- package/esm/sdkClient/clientCS.js +1 -1
- package/esm/sdkClient/sdkClientMethodCS.js +1 -5
- package/esm/sdkClient/sdkClientMethodCSWithTT.js +1 -9
- package/esm/storages/inRedis/RedisAdapter.js +9 -2
- package/esm/utils/lang/maps.js +14 -1
- package/esm/utils/settingsValidation/index.js +20 -4
- package/package.json +1 -1
- package/src/integrations/pluggable.ts +2 -2
- package/src/sdkClient/client.ts +1 -1
- package/src/sdkClient/clientCS.ts +1 -1
- package/src/sdkClient/sdkClientMethodCS.ts +1 -6
- package/src/sdkClient/sdkClientMethodCSWithTT.ts +2 -11
- package/src/storages/inRedis/RedisAdapter.ts +8 -2
- package/src/types.ts +1 -1
- package/src/utils/lang/maps.ts +15 -1
- package/src/utils/settingsValidation/index.ts +20 -4
- package/src/utils/settingsValidation/types.ts +3 -1
- package/types/storages/inRedis/RedisAdapter.d.ts +1 -1
- package/types/types.d.ts +1 -1
- package/types/utils/lang/maps.d.ts +7 -0
- package/types/utils/settingsValidation/types.d.ts +3 -1
package/cjs/sdkClient/client.js
CHANGED
|
@@ -20,7 +20,7 @@ function clientCSDecorator(log, client, key, trafficType) {
|
|
|
20
20
|
getTreatmentsWithConfig: clientCS.getTreatmentsWithConfig.bind(clientCS, key),
|
|
21
21
|
// Key is bound to the `track` method. Same thing happens with trafficType but only if provided
|
|
22
22
|
track: trafficType ? clientCS.track.bind(clientCS, key, trafficType) : clientCS.track.bind(clientCS, key),
|
|
23
|
-
|
|
23
|
+
isClientSide: true
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
26
|
exports.clientCSDecorator = clientCSDecorator;
|
|
@@ -19,12 +19,8 @@ var method = 'Client instantiation';
|
|
|
19
19
|
*/
|
|
20
20
|
function sdkClientMethodCSFactory(params) {
|
|
21
21
|
var storage = params.storage, syncManager = params.syncManager, sdkReadinessManager = params.sdkReadinessManager, _a = params.settings, key = _a.core.key, readyTimeout = _a.startup.readyTimeout, log = _a.log;
|
|
22
|
-
// Keeping similar behaviour as in the isomorphic JS SDK: if settings key is invalid,
|
|
23
|
-
// `false` value is used as binded key of the default client, but trafficType is ignored
|
|
24
|
-
// @TODO handle as a non-recoverable error
|
|
25
|
-
var validKey = (0, key_1.validateKey)(log, key, method);
|
|
26
22
|
var mainClientInstance = (0, clientCS_1.clientCSDecorator)(log, (0, sdkClient_1.sdkClientFactory)(params), // @ts-ignore
|
|
27
|
-
|
|
23
|
+
key);
|
|
28
24
|
var parsedDefaultKey = (0, key_2.keyParser)(key);
|
|
29
25
|
var defaultInstanceId = buildInstanceId(parsedDefaultKey);
|
|
30
26
|
// Cache instances created per factory.
|
|
@@ -21,16 +21,8 @@ var method = 'Client instantiation';
|
|
|
21
21
|
*/
|
|
22
22
|
function sdkClientMethodCSFactory(params) {
|
|
23
23
|
var storage = params.storage, syncManager = params.syncManager, sdkReadinessManager = params.sdkReadinessManager, _a = params.settings, _b = _a.core, key = _b.key, trafficType = _b.trafficType, readyTimeout = _a.startup.readyTimeout, log = _a.log;
|
|
24
|
-
// Keeping the behaviour as in the isomorphic JS SDK: if settings key or TT are invalid,
|
|
25
|
-
// `false` value is used as binded key/TT of the default client, which leads to several issues.
|
|
26
|
-
// @TODO update when supporting non-recoverable errors
|
|
27
|
-
var validKey = (0, key_1.validateKey)(log, key, method);
|
|
28
|
-
var validTrafficType;
|
|
29
|
-
if (trafficType !== undefined) {
|
|
30
|
-
validTrafficType = (0, trafficType_1.validateTrafficType)(log, trafficType, method);
|
|
31
|
-
}
|
|
32
24
|
var mainClientInstance = (0, clientCS_1.clientCSDecorator)(log, (0, sdkClient_1.sdkClientFactory)(params), // @ts-ignore
|
|
33
|
-
|
|
25
|
+
key, trafficType);
|
|
34
26
|
var parsedDefaultKey = (0, key_2.keyParser)(key);
|
|
35
27
|
var defaultInstanceId = buildInstanceId(parsedDefaultKey, trafficType);
|
|
36
28
|
// Cache instances created per factory.
|
|
@@ -146,13 +146,19 @@ var RedisAdapter = /** @class */ (function (_super) {
|
|
|
146
146
|
else { // If it IS the string URL, that'll be the first param for ioredis.
|
|
147
147
|
result.unshift(options.url);
|
|
148
148
|
}
|
|
149
|
+
if (options.connectionTimeout) {
|
|
150
|
+
(0, lang_1.merge)(opts, { connectTimeout: options.connectionTimeout });
|
|
151
|
+
}
|
|
152
|
+
if (options.tls) {
|
|
153
|
+
(0, lang_1.merge)(opts, { tls: options.tls });
|
|
154
|
+
}
|
|
149
155
|
return result;
|
|
150
156
|
};
|
|
151
157
|
/**
|
|
152
158
|
* Parses the options into what we care about.
|
|
153
159
|
*/
|
|
154
160
|
RedisAdapter._defineOptions = function (_a) {
|
|
155
|
-
var connectionTimeout = _a.connectionTimeout, operationTimeout = _a.operationTimeout, url = _a.url, host = _a.host, port = _a.port, db = _a.db, pass = _a.pass;
|
|
161
|
+
var connectionTimeout = _a.connectionTimeout, operationTimeout = _a.operationTimeout, url = _a.url, host = _a.host, port = _a.port, db = _a.db, pass = _a.pass, tls = _a.tls;
|
|
156
162
|
var parsedOptions = {
|
|
157
163
|
connectionTimeout: connectionTimeout,
|
|
158
164
|
operationTimeout: operationTimeout,
|
|
@@ -160,7 +166,8 @@ var RedisAdapter = /** @class */ (function (_super) {
|
|
|
160
166
|
host: host,
|
|
161
167
|
port: port,
|
|
162
168
|
db: db,
|
|
163
|
-
pass: pass
|
|
169
|
+
pass: pass,
|
|
170
|
+
tls: tls
|
|
164
171
|
};
|
|
165
172
|
return (0, lang_1.merge)({}, DEFAULT_OPTIONS, parsedOptions);
|
|
166
173
|
};
|
package/cjs/utils/lang/maps.js
CHANGED
|
@@ -24,7 +24,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
24
24
|
THE SOFTWARE.
|
|
25
25
|
**/
|
|
26
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
-
exports._Map = exports.MapPoly = void 0;
|
|
27
|
+
exports._Map = exports.__getMapConstructor = exports.MapPoly = void 0;
|
|
28
28
|
var MapPoly = /** @class */ (function () {
|
|
29
29
|
// unlike ES6 `Map`, it only accepts an array as first argument iterable
|
|
30
30
|
function MapPoly(entries) {
|
|
@@ -71,4 +71,18 @@ var MapPoly = /** @class */ (function () {
|
|
|
71
71
|
return MapPoly;
|
|
72
72
|
}());
|
|
73
73
|
exports.MapPoly = MapPoly;
|
|
74
|
-
|
|
74
|
+
/**
|
|
75
|
+
* return the Map constructor to use. If native Map is not available or it doesn't support the required features (e.g., IE11),
|
|
76
|
+
* a ponyfill with minimal features is returned instead.
|
|
77
|
+
*
|
|
78
|
+
* Exported for testing purposes only.
|
|
79
|
+
*/
|
|
80
|
+
function __getMapConstructor() {
|
|
81
|
+
// eslint-disable-next-line compat/compat
|
|
82
|
+
if (typeof Array.from === 'function' && typeof Map === 'function' && Map.prototype && Map.prototype.values) {
|
|
83
|
+
return Map;
|
|
84
|
+
}
|
|
85
|
+
return MapPoly;
|
|
86
|
+
}
|
|
87
|
+
exports.__getMapConstructor = __getMapConstructor;
|
|
88
|
+
exports._Map = __getMapConstructor();
|
|
@@ -6,6 +6,8 @@ var mode_1 = require("./mode");
|
|
|
6
6
|
var splitFilters_1 = require("./splitFilters");
|
|
7
7
|
var constants_1 = require("../constants");
|
|
8
8
|
var impressionsMode_1 = require("./impressionsMode");
|
|
9
|
+
var key_1 = require("../inputValidation/key");
|
|
10
|
+
var trafficType_1 = require("../inputValidation/trafficType");
|
|
9
11
|
var base = {
|
|
10
12
|
// Define which kind of object you want to retrieve from SplitFactory
|
|
11
13
|
mode: constants_1.STANDALONE_MODE,
|
|
@@ -83,7 +85,7 @@ function fromSecondsToMillis(n) {
|
|
|
83
85
|
* @param validationParams defaults and fields validators used to validate and creates a settings object from a given config
|
|
84
86
|
*/
|
|
85
87
|
function settingsValidation(config, validationParams) {
|
|
86
|
-
var defaults = validationParams.defaults, runtime = validationParams.runtime, storage = validationParams.storage, integrations = validationParams.integrations, logger = validationParams.logger, localhost = validationParams.localhost, consent = validationParams.consent;
|
|
88
|
+
var defaults = validationParams.defaults, isClientSide = validationParams.isClientSide, runtime = validationParams.runtime, storage = validationParams.storage, integrations = validationParams.integrations, logger = validationParams.logger, localhost = validationParams.localhost, consent = validationParams.consent;
|
|
87
89
|
// creates a settings object merging base, defaults and config objects.
|
|
88
90
|
var withDefaults = (0, lang_1.merge)({}, base, defaults, config);
|
|
89
91
|
// ensure a valid logger.
|
|
@@ -109,9 +111,23 @@ function settingsValidation(config, validationParams) {
|
|
|
109
111
|
// @ts-ignore, modify readonly prop
|
|
110
112
|
if (storage)
|
|
111
113
|
withDefaults.storage = storage(withDefaults);
|
|
112
|
-
//
|
|
113
|
-
if (
|
|
114
|
-
withDefaults.core.key
|
|
114
|
+
// In client-side, validate key and TT
|
|
115
|
+
if (isClientSide) {
|
|
116
|
+
var maybeKey = withDefaults.core.key;
|
|
117
|
+
// Although `key` is required in client-side, it can be omitted in LOCALHOST mode. In that case, the value `localhost_key` is used.
|
|
118
|
+
if (withDefaults.mode === constants_1.LOCALHOST_MODE && maybeKey === undefined) {
|
|
119
|
+
withDefaults.core.key = 'localhost_key';
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
// Keeping same behaviour than JS SDK: if settings key or TT are invalid,
|
|
123
|
+
// `false` value is used as binded key/TT of the default client, which leads to some issues.
|
|
124
|
+
// @ts-ignore, @TODO handle invalid keys as a non-recoverable error?
|
|
125
|
+
withDefaults.core.key = (0, key_1.validateKey)(log, maybeKey, 'Client instantiation');
|
|
126
|
+
}
|
|
127
|
+
var maybeTT = withDefaults.core.trafficType;
|
|
128
|
+
if (maybeTT !== undefined) { // @ts-ignore, assigning false
|
|
129
|
+
withDefaults.core.trafficType = (0, trafficType_1.validateTrafficType)(log, maybeTT, 'Client instantiation');
|
|
130
|
+
}
|
|
115
131
|
}
|
|
116
132
|
// Current ip/hostname information
|
|
117
133
|
// @ts-ignore, modify readonly prop
|
package/esm/sdkClient/client.js
CHANGED
|
@@ -17,6 +17,6 @@ export function clientCSDecorator(log, client, key, trafficType) {
|
|
|
17
17
|
getTreatmentsWithConfig: clientCS.getTreatmentsWithConfig.bind(clientCS, key),
|
|
18
18
|
// Key is bound to the `track` method. Same thing happens with trafficType but only if provided
|
|
19
19
|
track: trafficType ? clientCS.track.bind(clientCS, key, trafficType) : clientCS.track.bind(clientCS, key),
|
|
20
|
-
|
|
20
|
+
isClientSide: true
|
|
21
21
|
});
|
|
22
22
|
}
|
|
@@ -16,12 +16,8 @@ var method = 'Client instantiation';
|
|
|
16
16
|
*/
|
|
17
17
|
export function sdkClientMethodCSFactory(params) {
|
|
18
18
|
var storage = params.storage, syncManager = params.syncManager, sdkReadinessManager = params.sdkReadinessManager, _a = params.settings, key = _a.core.key, readyTimeout = _a.startup.readyTimeout, log = _a.log;
|
|
19
|
-
// Keeping similar behaviour as in the isomorphic JS SDK: if settings key is invalid,
|
|
20
|
-
// `false` value is used as binded key of the default client, but trafficType is ignored
|
|
21
|
-
// @TODO handle as a non-recoverable error
|
|
22
|
-
var validKey = validateKey(log, key, method);
|
|
23
19
|
var mainClientInstance = clientCSDecorator(log, sdkClientFactory(params), // @ts-ignore
|
|
24
|
-
|
|
20
|
+
key);
|
|
25
21
|
var parsedDefaultKey = keyParser(key);
|
|
26
22
|
var defaultInstanceId = buildInstanceId(parsedDefaultKey);
|
|
27
23
|
// Cache instances created per factory.
|
|
@@ -18,16 +18,8 @@ var method = 'Client instantiation';
|
|
|
18
18
|
*/
|
|
19
19
|
export function sdkClientMethodCSFactory(params) {
|
|
20
20
|
var storage = params.storage, syncManager = params.syncManager, sdkReadinessManager = params.sdkReadinessManager, _a = params.settings, _b = _a.core, key = _b.key, trafficType = _b.trafficType, readyTimeout = _a.startup.readyTimeout, log = _a.log;
|
|
21
|
-
// Keeping the behaviour as in the isomorphic JS SDK: if settings key or TT are invalid,
|
|
22
|
-
// `false` value is used as binded key/TT of the default client, which leads to several issues.
|
|
23
|
-
// @TODO update when supporting non-recoverable errors
|
|
24
|
-
var validKey = validateKey(log, key, method);
|
|
25
|
-
var validTrafficType;
|
|
26
|
-
if (trafficType !== undefined) {
|
|
27
|
-
validTrafficType = validateTrafficType(log, trafficType, method);
|
|
28
|
-
}
|
|
29
21
|
var mainClientInstance = clientCSDecorator(log, sdkClientFactory(params), // @ts-ignore
|
|
30
|
-
|
|
22
|
+
key, trafficType);
|
|
31
23
|
var parsedDefaultKey = keyParser(key);
|
|
32
24
|
var defaultInstanceId = buildInstanceId(parsedDefaultKey, trafficType);
|
|
33
25
|
// Cache instances created per factory.
|
|
@@ -143,13 +143,19 @@ var RedisAdapter = /** @class */ (function (_super) {
|
|
|
143
143
|
else { // If it IS the string URL, that'll be the first param for ioredis.
|
|
144
144
|
result.unshift(options.url);
|
|
145
145
|
}
|
|
146
|
+
if (options.connectionTimeout) {
|
|
147
|
+
merge(opts, { connectTimeout: options.connectionTimeout });
|
|
148
|
+
}
|
|
149
|
+
if (options.tls) {
|
|
150
|
+
merge(opts, { tls: options.tls });
|
|
151
|
+
}
|
|
146
152
|
return result;
|
|
147
153
|
};
|
|
148
154
|
/**
|
|
149
155
|
* Parses the options into what we care about.
|
|
150
156
|
*/
|
|
151
157
|
RedisAdapter._defineOptions = function (_a) {
|
|
152
|
-
var connectionTimeout = _a.connectionTimeout, operationTimeout = _a.operationTimeout, url = _a.url, host = _a.host, port = _a.port, db = _a.db, pass = _a.pass;
|
|
158
|
+
var connectionTimeout = _a.connectionTimeout, operationTimeout = _a.operationTimeout, url = _a.url, host = _a.host, port = _a.port, db = _a.db, pass = _a.pass, tls = _a.tls;
|
|
153
159
|
var parsedOptions = {
|
|
154
160
|
connectionTimeout: connectionTimeout,
|
|
155
161
|
operationTimeout: operationTimeout,
|
|
@@ -157,7 +163,8 @@ var RedisAdapter = /** @class */ (function (_super) {
|
|
|
157
163
|
host: host,
|
|
158
164
|
port: port,
|
|
159
165
|
db: db,
|
|
160
|
-
pass: pass
|
|
166
|
+
pass: pass,
|
|
167
|
+
tls: tls
|
|
161
168
|
};
|
|
162
169
|
return merge({}, DEFAULT_OPTIONS, parsedOptions);
|
|
163
170
|
};
|
package/esm/utils/lang/maps.js
CHANGED
|
@@ -68,4 +68,17 @@ var MapPoly = /** @class */ (function () {
|
|
|
68
68
|
return MapPoly;
|
|
69
69
|
}());
|
|
70
70
|
export { MapPoly };
|
|
71
|
-
|
|
71
|
+
/**
|
|
72
|
+
* return the Map constructor to use. If native Map is not available or it doesn't support the required features (e.g., IE11),
|
|
73
|
+
* a ponyfill with minimal features is returned instead.
|
|
74
|
+
*
|
|
75
|
+
* Exported for testing purposes only.
|
|
76
|
+
*/
|
|
77
|
+
export function __getMapConstructor() {
|
|
78
|
+
// eslint-disable-next-line compat/compat
|
|
79
|
+
if (typeof Array.from === 'function' && typeof Map === 'function' && Map.prototype && Map.prototype.values) {
|
|
80
|
+
return Map;
|
|
81
|
+
}
|
|
82
|
+
return MapPoly;
|
|
83
|
+
}
|
|
84
|
+
export var _Map = __getMapConstructor();
|
|
@@ -3,6 +3,8 @@ import { mode } from './mode';
|
|
|
3
3
|
import { validateSplitFilters } from './splitFilters';
|
|
4
4
|
import { STANDALONE_MODE, OPTIMIZED, LOCALHOST_MODE } from '../constants';
|
|
5
5
|
import { validImpressionsMode } from './impressionsMode';
|
|
6
|
+
import { validateKey } from '../inputValidation/key';
|
|
7
|
+
import { validateTrafficType } from '../inputValidation/trafficType';
|
|
6
8
|
var base = {
|
|
7
9
|
// Define which kind of object you want to retrieve from SplitFactory
|
|
8
10
|
mode: STANDALONE_MODE,
|
|
@@ -80,7 +82,7 @@ function fromSecondsToMillis(n) {
|
|
|
80
82
|
* @param validationParams defaults and fields validators used to validate and creates a settings object from a given config
|
|
81
83
|
*/
|
|
82
84
|
export function settingsValidation(config, validationParams) {
|
|
83
|
-
var defaults = validationParams.defaults, runtime = validationParams.runtime, storage = validationParams.storage, integrations = validationParams.integrations, logger = validationParams.logger, localhost = validationParams.localhost, consent = validationParams.consent;
|
|
85
|
+
var defaults = validationParams.defaults, isClientSide = validationParams.isClientSide, runtime = validationParams.runtime, storage = validationParams.storage, integrations = validationParams.integrations, logger = validationParams.logger, localhost = validationParams.localhost, consent = validationParams.consent;
|
|
84
86
|
// creates a settings object merging base, defaults and config objects.
|
|
85
87
|
var withDefaults = merge({}, base, defaults, config);
|
|
86
88
|
// ensure a valid logger.
|
|
@@ -106,9 +108,23 @@ export function settingsValidation(config, validationParams) {
|
|
|
106
108
|
// @ts-ignore, modify readonly prop
|
|
107
109
|
if (storage)
|
|
108
110
|
withDefaults.storage = storage(withDefaults);
|
|
109
|
-
//
|
|
110
|
-
if (
|
|
111
|
-
withDefaults.core.key
|
|
111
|
+
// In client-side, validate key and TT
|
|
112
|
+
if (isClientSide) {
|
|
113
|
+
var maybeKey = withDefaults.core.key;
|
|
114
|
+
// Although `key` is required in client-side, it can be omitted in LOCALHOST mode. In that case, the value `localhost_key` is used.
|
|
115
|
+
if (withDefaults.mode === LOCALHOST_MODE && maybeKey === undefined) {
|
|
116
|
+
withDefaults.core.key = 'localhost_key';
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// Keeping same behaviour than JS SDK: if settings key or TT are invalid,
|
|
120
|
+
// `false` value is used as binded key/TT of the default client, which leads to some issues.
|
|
121
|
+
// @ts-ignore, @TODO handle invalid keys as a non-recoverable error?
|
|
122
|
+
withDefaults.core.key = validateKey(log, maybeKey, 'Client instantiation');
|
|
123
|
+
}
|
|
124
|
+
var maybeTT = withDefaults.core.trafficType;
|
|
125
|
+
if (maybeTT !== undefined) { // @ts-ignore, assigning false
|
|
126
|
+
withDefaults.core.trafficType = validateTrafficType(log, maybeTT, 'Client instantiation');
|
|
127
|
+
}
|
|
112
128
|
}
|
|
113
129
|
// Current ip/hostname information
|
|
114
130
|
// @ts-ignore, modify readonly prop
|
package/package.json
CHANGED
|
@@ -29,10 +29,10 @@ export function pluggableIntegrationsManagerFactory(
|
|
|
29
29
|
|
|
30
30
|
// Exception safe methods: each integration module is responsable for handling errors
|
|
31
31
|
return {
|
|
32
|
-
handleImpression
|
|
32
|
+
handleImpression(impressionData: SplitIO.ImpressionData) {
|
|
33
33
|
listeners.forEach(listener => listener.queue({ type: SPLIT_IMPRESSION, payload: impressionData }));
|
|
34
34
|
},
|
|
35
|
-
handleEvent
|
|
35
|
+
handleEvent(eventData: SplitIO.EventData) {
|
|
36
36
|
listeners.forEach(listener => listener.queue({ type: SPLIT_EVENT, payload: eventData }));
|
|
37
37
|
}
|
|
38
38
|
};
|
package/src/sdkClient/client.ts
CHANGED
|
@@ -25,6 +25,6 @@ export function clientCSDecorator(log: ILogger, client: SplitIO.IClient, key: Sp
|
|
|
25
25
|
// Key is bound to the `track` method. Same thing happens with trafficType but only if provided
|
|
26
26
|
track: trafficType ? clientCS.track.bind(clientCS, key, trafficType) : clientCS.track.bind(clientCS, key),
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
isClientSide: true
|
|
29
29
|
}) as SplitIO.ICsClient;
|
|
30
30
|
}
|
|
@@ -23,15 +23,10 @@ const method = 'Client instantiation';
|
|
|
23
23
|
export function sdkClientMethodCSFactory(params: ISdkClientFactoryParams): (key?: SplitIO.SplitKey) => SplitIO.ICsClient {
|
|
24
24
|
const { storage, syncManager, sdkReadinessManager, settings: { core: { key }, startup: { readyTimeout }, log } } = params;
|
|
25
25
|
|
|
26
|
-
// Keeping similar behaviour as in the isomorphic JS SDK: if settings key is invalid,
|
|
27
|
-
// `false` value is used as binded key of the default client, but trafficType is ignored
|
|
28
|
-
// @TODO handle as a non-recoverable error
|
|
29
|
-
const validKey = validateKey(log, key, method);
|
|
30
|
-
|
|
31
26
|
const mainClientInstance = clientCSDecorator(
|
|
32
27
|
log,
|
|
33
28
|
sdkClientFactory(params) as SplitIO.IClient, // @ts-ignore
|
|
34
|
-
|
|
29
|
+
key
|
|
35
30
|
);
|
|
36
31
|
|
|
37
32
|
const parsedDefaultKey = keyParser(key);
|
|
@@ -25,20 +25,11 @@ const method = 'Client instantiation';
|
|
|
25
25
|
export function sdkClientMethodCSFactory(params: ISdkClientFactoryParams): (key?: SplitIO.SplitKey, trafficType?: string) => SplitIO.ICsClient {
|
|
26
26
|
const { storage, syncManager, sdkReadinessManager, settings: { core: { key, trafficType }, startup: { readyTimeout }, log } } = params;
|
|
27
27
|
|
|
28
|
-
// Keeping the behaviour as in the isomorphic JS SDK: if settings key or TT are invalid,
|
|
29
|
-
// `false` value is used as binded key/TT of the default client, which leads to several issues.
|
|
30
|
-
// @TODO update when supporting non-recoverable errors
|
|
31
|
-
const validKey = validateKey(log, key, method);
|
|
32
|
-
let validTrafficType;
|
|
33
|
-
if (trafficType !== undefined) {
|
|
34
|
-
validTrafficType = validateTrafficType(log, trafficType, method);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
28
|
const mainClientInstance = clientCSDecorator(
|
|
38
29
|
log,
|
|
39
30
|
sdkClientFactory(params) as SplitIO.IClient, // @ts-ignore
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
key,
|
|
32
|
+
trafficType
|
|
42
33
|
);
|
|
43
34
|
|
|
44
35
|
const parsedDefaultKey = keyParser(key);
|
|
@@ -164,6 +164,12 @@ export class RedisAdapter extends ioredis {
|
|
|
164
164
|
} else { // If it IS the string URL, that'll be the first param for ioredis.
|
|
165
165
|
result.unshift(options.url);
|
|
166
166
|
}
|
|
167
|
+
if (options.connectionTimeout) {
|
|
168
|
+
merge(opts, { connectTimeout: options.connectionTimeout });
|
|
169
|
+
}
|
|
170
|
+
if (options.tls) {
|
|
171
|
+
merge(opts, { tls: options.tls });
|
|
172
|
+
}
|
|
167
173
|
|
|
168
174
|
return result;
|
|
169
175
|
}
|
|
@@ -171,9 +177,9 @@ export class RedisAdapter extends ioredis {
|
|
|
171
177
|
/**
|
|
172
178
|
* Parses the options into what we care about.
|
|
173
179
|
*/
|
|
174
|
-
static _defineOptions({ connectionTimeout, operationTimeout, url, host, port, db, pass }: Record<string, any>) {
|
|
180
|
+
static _defineOptions({ connectionTimeout, operationTimeout, url, host, port, db, pass, tls }: Record<string, any>) {
|
|
175
181
|
const parsedOptions = {
|
|
176
|
-
connectionTimeout, operationTimeout, url, host, port, db, pass
|
|
182
|
+
connectionTimeout, operationTimeout, url, host, port, db, pass, tls
|
|
177
183
|
};
|
|
178
184
|
|
|
179
185
|
return merge({}, DEFAULT_OPTIONS, parsedOptions);
|
package/src/types.ts
CHANGED
|
@@ -398,7 +398,7 @@ interface IBasicClient extends IStatusInterface {
|
|
|
398
398
|
|
|
399
399
|
// Whether the client implements the client-side API, i.e, with bound key, (true), or the server-side API (false).
|
|
400
400
|
// Exposed for internal purposes only. Not considered part of the public API, and might be renamed eventually.
|
|
401
|
-
|
|
401
|
+
isClientSide: boolean
|
|
402
402
|
}
|
|
403
403
|
/**
|
|
404
404
|
* Common definitions between SDK instances for different environments interface.
|
package/src/utils/lang/maps.ts
CHANGED
|
@@ -79,4 +79,18 @@ interface IMapConstructor {
|
|
|
79
79
|
readonly prototype: IMap<any, any>;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
/**
|
|
83
|
+
* return the Map constructor to use. If native Map is not available or it doesn't support the required features (e.g., IE11),
|
|
84
|
+
* a ponyfill with minimal features is returned instead.
|
|
85
|
+
*
|
|
86
|
+
* Exported for testing purposes only.
|
|
87
|
+
*/
|
|
88
|
+
export function __getMapConstructor(): IMapConstructor {
|
|
89
|
+
// eslint-disable-next-line compat/compat
|
|
90
|
+
if (typeof Array.from === 'function' && typeof Map === 'function' && Map.prototype && Map.prototype.values) {
|
|
91
|
+
return Map;
|
|
92
|
+
}
|
|
93
|
+
return MapPoly;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const _Map = __getMapConstructor();
|
|
@@ -5,6 +5,8 @@ import { STANDALONE_MODE, OPTIMIZED, LOCALHOST_MODE } from '../constants';
|
|
|
5
5
|
import { validImpressionsMode } from './impressionsMode';
|
|
6
6
|
import { ISettingsValidationParams } from './types';
|
|
7
7
|
import { ISettings } from '../../types';
|
|
8
|
+
import { validateKey } from '../inputValidation/key';
|
|
9
|
+
import { validateTrafficType } from '../inputValidation/trafficType';
|
|
8
10
|
|
|
9
11
|
const base = {
|
|
10
12
|
// Define which kind of object you want to retrieve from SplitFactory
|
|
@@ -97,7 +99,7 @@ function fromSecondsToMillis(n: number) {
|
|
|
97
99
|
*/
|
|
98
100
|
export function settingsValidation(config: unknown, validationParams: ISettingsValidationParams) {
|
|
99
101
|
|
|
100
|
-
const { defaults, runtime, storage, integrations, logger, localhost, consent } = validationParams;
|
|
102
|
+
const { defaults, isClientSide, runtime, storage, integrations, logger, localhost, consent } = validationParams;
|
|
101
103
|
|
|
102
104
|
// creates a settings object merging base, defaults and config objects.
|
|
103
105
|
const withDefaults = merge({}, base, defaults, config) as ISettings;
|
|
@@ -129,9 +131,23 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
|
|
|
129
131
|
// @ts-ignore, modify readonly prop
|
|
130
132
|
if (storage) withDefaults.storage = storage(withDefaults);
|
|
131
133
|
|
|
132
|
-
//
|
|
133
|
-
if (
|
|
134
|
-
withDefaults.core.key
|
|
134
|
+
// In client-side, validate key and TT
|
|
135
|
+
if (isClientSide) {
|
|
136
|
+
const maybeKey = withDefaults.core.key;
|
|
137
|
+
// Although `key` is required in client-side, it can be omitted in LOCALHOST mode. In that case, the value `localhost_key` is used.
|
|
138
|
+
if (withDefaults.mode === LOCALHOST_MODE && maybeKey === undefined) {
|
|
139
|
+
withDefaults.core.key = 'localhost_key';
|
|
140
|
+
} else {
|
|
141
|
+
// Keeping same behaviour than JS SDK: if settings key or TT are invalid,
|
|
142
|
+
// `false` value is used as binded key/TT of the default client, which leads to some issues.
|
|
143
|
+
// @ts-ignore, @TODO handle invalid keys as a non-recoverable error?
|
|
144
|
+
withDefaults.core.key = validateKey(log, maybeKey, 'Client instantiation');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const maybeTT = withDefaults.core.trafficType;
|
|
148
|
+
if (maybeTT !== undefined) { // @ts-ignore, assigning false
|
|
149
|
+
withDefaults.core.trafficType = validateTrafficType(log, maybeTT, 'Client instantiation');
|
|
150
|
+
}
|
|
135
151
|
}
|
|
136
152
|
|
|
137
153
|
// Current ip/hostname information
|
|
@@ -10,7 +10,9 @@ export interface ISettingsValidationParams {
|
|
|
10
10
|
* Version and startup properties are required, because they are not defined in the base settings.
|
|
11
11
|
*/
|
|
12
12
|
defaults: Partial<ISettings> & { version: string } & { startup: ISettings['startup'] },
|
|
13
|
-
/**
|
|
13
|
+
/** If true, validates core.key and core.trafficType */
|
|
14
|
+
isClientSide?: boolean,
|
|
15
|
+
/** Define runtime values (`settings.runtime`) */
|
|
14
16
|
runtime: (settings: ISettings) => ISettings['runtime'],
|
|
15
17
|
/** Storage validator (`settings.storage`) */
|
|
16
18
|
storage?: (settings: ISettings) => ISettings['storage'],
|
|
@@ -20,5 +20,5 @@ export declare class RedisAdapter extends ioredis {
|
|
|
20
20
|
/**
|
|
21
21
|
* Parses the options into what we care about.
|
|
22
22
|
*/
|
|
23
|
-
static _defineOptions({ connectionTimeout, operationTimeout, url, host, port, db, pass }: Record<string, any>): object;
|
|
23
|
+
static _defineOptions({ connectionTimeout, operationTimeout, url, host, port, db, pass, tls }: Record<string, any>): object;
|
|
24
24
|
}
|
package/types/types.d.ts
CHANGED
|
@@ -389,7 +389,7 @@ interface IBasicClient extends IStatusInterface {
|
|
|
389
389
|
* @returns {Promise<void>}
|
|
390
390
|
*/
|
|
391
391
|
destroy(): Promise<void>;
|
|
392
|
-
|
|
392
|
+
isClientSide: boolean;
|
|
393
393
|
}
|
|
394
394
|
/**
|
|
395
395
|
* Common definitions between SDK instances for different environments interface.
|
|
@@ -44,5 +44,12 @@ interface IMapConstructor {
|
|
|
44
44
|
new <K, V>(entries?: readonly (readonly [K, V])[] | null): IMap<K, V>;
|
|
45
45
|
readonly prototype: IMap<any, any>;
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* return the Map constructor to use. If native Map is not available or it doesn't support the required features (e.g., IE11),
|
|
49
|
+
* a ponyfill with minimal features is returned instead.
|
|
50
|
+
*
|
|
51
|
+
* Exported for testing purposes only.
|
|
52
|
+
*/
|
|
53
|
+
export declare function __getMapConstructor(): IMapConstructor;
|
|
47
54
|
export declare const _Map: IMapConstructor;
|
|
48
55
|
export {};
|
|
@@ -13,7 +13,9 @@ export interface ISettingsValidationParams {
|
|
|
13
13
|
} & {
|
|
14
14
|
startup: ISettings['startup'];
|
|
15
15
|
};
|
|
16
|
-
/**
|
|
16
|
+
/** If true, validates core.key and core.trafficType */
|
|
17
|
+
isClientSide?: boolean;
|
|
18
|
+
/** Define runtime values (`settings.runtime`) */
|
|
17
19
|
runtime: (settings: ISettings) => ISettings['runtime'];
|
|
18
20
|
/** Storage validator (`settings.storage`) */
|
|
19
21
|
storage?: (settings: ISettings) => ISettings['storage'];
|