@splitsoftware/splitio-commons 1.13.2-rc.0 → 1.13.2-rc.2
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 +1 -1
- package/cjs/evaluator/combiners/ifelseif.js +1 -1
- package/cjs/evaluator/parser/index.js +1 -2
- package/cjs/logger/messages/error.js +1 -1
- package/cjs/sdkClient/sdkClient.js +1 -6
- package/cjs/services/splitApi.js +5 -5
- package/cjs/storages/KeyBuilder.js +2 -1
- package/cjs/utils/constants/index.js +2 -1
- package/cjs/utils/settingsValidation/index.js +1 -1
- package/esm/evaluator/combiners/ifelseif.js +1 -1
- package/esm/evaluator/parser/index.js +1 -2
- package/esm/logger/messages/error.js +1 -1
- package/esm/sdkClient/sdkClient.js +1 -6
- package/esm/services/splitApi.js +6 -6
- package/esm/storages/KeyBuilder.js +2 -1
- package/esm/utils/constants/index.js +1 -0
- package/esm/utils/settingsValidation/index.js +1 -1
- package/package.json +1 -1
- package/src/evaluator/combiners/ifelseif.ts +1 -1
- package/src/evaluator/parser/index.ts +1 -2
- package/src/logger/messages/error.ts +1 -1
- package/src/sdkClient/sdkClient.ts +1 -8
- package/src/services/splitApi.ts +5 -6
- package/src/storages/KeyBuilder.ts +2 -1
- package/src/types.ts +3 -3
- package/src/utils/constants/index.ts +2 -0
- package/src/utils/settingsValidation/index.ts +1 -1
- package/types/evaluator/matchers/sember_inlist.d.ts +3 -0
- package/types/evaluator/matchers/semver_between.d.ts +3 -0
- package/types/evaluator/matchers/semver_eq.d.ts +2 -0
- package/types/evaluator/matchers/semver_gte.d.ts +2 -0
- package/types/evaluator/matchers/semver_lte.d.ts +2 -0
- package/types/types.d.ts +3 -3
- package/types/utils/constants/index.d.ts +1 -0
- package/types/utils/semVer.d.ts +22 -0
- package/types/utils/settingsValidation/logger/globalLogLevel.d.ts +8 -0
package/CHANGES.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
1.14.0 (April XX, 2024)
|
|
2
2
|
- Updated impression label to 'unsupported matcher type' when the matcher type is not supported by the SDK.
|
|
3
|
-
- Updated Split API client to
|
|
3
|
+
- Updated Split API client to include the flags spec version query parameter for the `splitChanges` endpoint.
|
|
4
4
|
|
|
5
5
|
1.13.1 (January 10, 2024)
|
|
6
6
|
- Updated client `destroy` method to release SDK key immediately and avoid unexpected warning logs when a factory is created with the same SDK key after the previous one was destroyed.
|
|
@@ -39,7 +39,7 @@ function ifElseIfCombinerContext(log, predicates) {
|
|
|
39
39
|
return computeTreatment(predicateResults);
|
|
40
40
|
}
|
|
41
41
|
// if there is none predicates, then there was an error in parsing phase
|
|
42
|
-
if (!Array.isArray(predicates) ||
|
|
42
|
+
if (!Array.isArray(predicates) || predicates.length === 0) {
|
|
43
43
|
return unexpectedInputHandler;
|
|
44
44
|
}
|
|
45
45
|
else {
|
|
@@ -30,8 +30,7 @@ function parser(log, conditions, storage) {
|
|
|
30
30
|
return Boolean(result ^ matcherDto.negate);
|
|
31
31
|
};
|
|
32
32
|
});
|
|
33
|
-
// if matcher's factory can't
|
|
34
|
-
// will be empty
|
|
33
|
+
// if matcher's factory can't instantiate the matchers, the expressions array will be empty
|
|
35
34
|
if (expressions.length === 0) {
|
|
36
35
|
// reset any data collected during parsing
|
|
37
36
|
predicates = [];
|
|
@@ -5,7 +5,7 @@ var tslib_1 = require("tslib");
|
|
|
5
5
|
var c = (0, tslib_1.__importStar)(require("../constants"));
|
|
6
6
|
exports.codesError = [
|
|
7
7
|
// evaluator
|
|
8
|
-
[c.ERROR_ENGINE_COMBINER_IFELSEIF, c.LOG_PREFIX_ENGINE_COMBINER + 'Invalid feature flag, no valid rules found'],
|
|
8
|
+
[c.ERROR_ENGINE_COMBINER_IFELSEIF, c.LOG_PREFIX_ENGINE_COMBINER + 'Invalid feature flag, no valid rules or unsupported matcher type found'],
|
|
9
9
|
// SDK
|
|
10
10
|
[c.ERROR_LOGLEVEL_INVALID, 'logger: Invalid Log Level - No changes to the logs will be applied.'],
|
|
11
11
|
[c.ERROR_CLIENT_CANNOT_GET_READY, 'The SDK will not get ready. Reason: %s'],
|
|
@@ -31,8 +31,6 @@ function sdkClientFactory(params, isSharedClient) {
|
|
|
31
31
|
function __flush() {
|
|
32
32
|
return syncManager ? syncManager.flush() : Promise.resolve();
|
|
33
33
|
}
|
|
34
|
-
// Same promise if `destroy` is called multiple times
|
|
35
|
-
var destroyPromise;
|
|
36
34
|
return (0, objectAssign_1.objectAssign)(
|
|
37
35
|
// Proto-linkage of the readiness Event Emitter
|
|
38
36
|
Object.create(sdkReadinessManager.sdkStatus),
|
|
@@ -45,8 +43,6 @@ function sdkClientFactory(params, isSharedClient) {
|
|
|
45
43
|
return __cooldown(__flush, COOLDOWN_TIME_IN_MILLIS);
|
|
46
44
|
},
|
|
47
45
|
destroy: function () {
|
|
48
|
-
if (destroyPromise)
|
|
49
|
-
return destroyPromise;
|
|
50
46
|
// Mark the SDK as destroyed immediately
|
|
51
47
|
sdkReadinessManager.readinessManager.destroy();
|
|
52
48
|
// For main client, release the SDK Key and record stat before flushing data
|
|
@@ -56,7 +52,7 @@ function sdkClientFactory(params, isSharedClient) {
|
|
|
56
52
|
}
|
|
57
53
|
// Stop background jobs
|
|
58
54
|
syncManager && syncManager.stop();
|
|
59
|
-
|
|
55
|
+
return __flush().then(function () {
|
|
60
56
|
// Cleanup event listeners
|
|
61
57
|
signalListener && signalListener.stop();
|
|
62
58
|
// @TODO stop only if last client is destroyed
|
|
@@ -65,7 +61,6 @@ function sdkClientFactory(params, isSharedClient) {
|
|
|
65
61
|
// Cleanup storage
|
|
66
62
|
return storage.destroy();
|
|
67
63
|
});
|
|
68
|
-
return destroyPromise;
|
|
69
64
|
}
|
|
70
65
|
});
|
|
71
66
|
}
|
package/cjs/services/splitApi.js
CHANGED
|
@@ -32,16 +32,16 @@ function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
32
32
|
return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
|
|
33
33
|
},
|
|
34
34
|
fetchAuth: function (userMatchingKeys) {
|
|
35
|
-
var url = urls.auth + "/v2/auth";
|
|
36
|
-
if (userMatchingKeys) { //
|
|
35
|
+
var url = urls.auth + "/v2/auth?s=" + constants_1.FLAGS_SPEC;
|
|
36
|
+
if (userMatchingKeys) { // `userMatchingKeys` is undefined in server-side
|
|
37
37
|
var queryParams = userMatchingKeys.map(userKeyToQueryParam).join('&');
|
|
38
|
-
if (queryParams)
|
|
39
|
-
url += '
|
|
38
|
+
if (queryParams)
|
|
39
|
+
url += '&' + queryParams;
|
|
40
40
|
}
|
|
41
41
|
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(constants_1.TOKEN));
|
|
42
42
|
},
|
|
43
43
|
fetchSplitChanges: function (since, noCache, till) {
|
|
44
|
-
var url = urls.sdk + "/splitChanges?
|
|
44
|
+
var url = urls.sdk + "/splitChanges?s=" + constants_1.FLAGS_SPEC + "&since=" + since + (till ? '&till=' + till : '') + (filterQueryString || '');
|
|
45
45
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(constants_1.SPLITS))
|
|
46
46
|
.catch(function (err) {
|
|
47
47
|
if (err.statusCode === 414)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getStorageHash = exports.KeyBuilder = exports.validatePrefix = void 0;
|
|
4
|
+
var constants_1 = require("../utils/constants");
|
|
4
5
|
var lang_1 = require("../utils/lang");
|
|
5
6
|
var murmur3_1 = require("../utils/murmur3/murmur3");
|
|
6
7
|
var everythingAtTheEnd = /[^.]+$/;
|
|
@@ -70,6 +71,6 @@ exports.KeyBuilder = KeyBuilder;
|
|
|
70
71
|
* The hash is in hexadecimal format (8 characters max, 32 bits).
|
|
71
72
|
*/
|
|
72
73
|
function getStorageHash(settings) {
|
|
73
|
-
return (0, murmur3_1.hash)(settings.core.authorizationKey + "::" + settings.sync.__splitFiltersValidation.queryString + "::
|
|
74
|
+
return (0, murmur3_1.hash)(settings.core.authorizationKey + "::" + settings.sync.__splitFiltersValidation.queryString + "::" + constants_1.FLAGS_SPEC).toString(16);
|
|
74
75
|
}
|
|
75
76
|
exports.getStorageHash = getStorageHash;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
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;
|
|
4
|
+
exports.FLAGS_SPEC = 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 = {
|
|
@@ -90,3 +90,4 @@ exports.NON_REQUESTED = 1;
|
|
|
90
90
|
exports.DISABLED = 0;
|
|
91
91
|
exports.ENABLED = 1;
|
|
92
92
|
exports.PAUSED = 2;
|
|
93
|
+
exports.FLAGS_SPEC = '1.1';
|
|
@@ -57,7 +57,7 @@ exports.base = {
|
|
|
57
57
|
// Telemetry Server
|
|
58
58
|
telemetry: 'https://telemetry.split.io/api',
|
|
59
59
|
},
|
|
60
|
-
// Defines which kind of storage we should
|
|
60
|
+
// Defines which kind of storage we should instantiate.
|
|
61
61
|
storage: undefined,
|
|
62
62
|
// Defines if the logs are enabled, SDK wide.
|
|
63
63
|
debug: undefined,
|
|
@@ -35,7 +35,7 @@ export function ifElseIfCombinerContext(log, predicates) {
|
|
|
35
35
|
return computeTreatment(predicateResults);
|
|
36
36
|
}
|
|
37
37
|
// if there is none predicates, then there was an error in parsing phase
|
|
38
|
-
if (!Array.isArray(predicates) ||
|
|
38
|
+
if (!Array.isArray(predicates) || predicates.length === 0) {
|
|
39
39
|
return unexpectedInputHandler;
|
|
40
40
|
}
|
|
41
41
|
else {
|
|
@@ -27,8 +27,7 @@ export function parser(log, conditions, storage) {
|
|
|
27
27
|
return Boolean(result ^ matcherDto.negate);
|
|
28
28
|
};
|
|
29
29
|
});
|
|
30
|
-
// if matcher's factory can't
|
|
31
|
-
// will be empty
|
|
30
|
+
// if matcher's factory can't instantiate the matchers, the expressions array will be empty
|
|
32
31
|
if (expressions.length === 0) {
|
|
33
32
|
// reset any data collected during parsing
|
|
34
33
|
predicates = [];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as c from '../constants';
|
|
2
2
|
export var codesError = [
|
|
3
3
|
// evaluator
|
|
4
|
-
[c.ERROR_ENGINE_COMBINER_IFELSEIF, c.LOG_PREFIX_ENGINE_COMBINER + 'Invalid feature flag, no valid rules found'],
|
|
4
|
+
[c.ERROR_ENGINE_COMBINER_IFELSEIF, c.LOG_PREFIX_ENGINE_COMBINER + 'Invalid feature flag, no valid rules or unsupported matcher type found'],
|
|
5
5
|
// SDK
|
|
6
6
|
[c.ERROR_LOGLEVEL_INVALID, 'logger: Invalid Log Level - No changes to the logs will be applied.'],
|
|
7
7
|
[c.ERROR_CLIENT_CANNOT_GET_READY, 'The SDK will not get ready. Reason: %s'],
|
|
@@ -28,8 +28,6 @@ export function sdkClientFactory(params, isSharedClient) {
|
|
|
28
28
|
function __flush() {
|
|
29
29
|
return syncManager ? syncManager.flush() : Promise.resolve();
|
|
30
30
|
}
|
|
31
|
-
// Same promise if `destroy` is called multiple times
|
|
32
|
-
var destroyPromise;
|
|
33
31
|
return objectAssign(
|
|
34
32
|
// Proto-linkage of the readiness Event Emitter
|
|
35
33
|
Object.create(sdkReadinessManager.sdkStatus),
|
|
@@ -42,8 +40,6 @@ export function sdkClientFactory(params, isSharedClient) {
|
|
|
42
40
|
return __cooldown(__flush, COOLDOWN_TIME_IN_MILLIS);
|
|
43
41
|
},
|
|
44
42
|
destroy: function () {
|
|
45
|
-
if (destroyPromise)
|
|
46
|
-
return destroyPromise;
|
|
47
43
|
// Mark the SDK as destroyed immediately
|
|
48
44
|
sdkReadinessManager.readinessManager.destroy();
|
|
49
45
|
// For main client, release the SDK Key and record stat before flushing data
|
|
@@ -53,7 +49,7 @@ export function sdkClientFactory(params, isSharedClient) {
|
|
|
53
49
|
}
|
|
54
50
|
// Stop background jobs
|
|
55
51
|
syncManager && syncManager.stop();
|
|
56
|
-
|
|
52
|
+
return __flush().then(function () {
|
|
57
53
|
// Cleanup event listeners
|
|
58
54
|
signalListener && signalListener.stop();
|
|
59
55
|
// @TODO stop only if last client is destroyed
|
|
@@ -62,7 +58,6 @@ export function sdkClientFactory(params, isSharedClient) {
|
|
|
62
58
|
// Cleanup storage
|
|
63
59
|
return storage.destroy();
|
|
64
60
|
});
|
|
65
|
-
return destroyPromise;
|
|
66
61
|
}
|
|
67
62
|
});
|
|
68
63
|
}
|
package/esm/services/splitApi.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { splitHttpClientFactory } from './splitHttpClient';
|
|
2
2
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
3
|
-
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MY_SEGMENT } from '../utils/constants';
|
|
3
|
+
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MY_SEGMENT, FLAGS_SPEC } from '../utils/constants';
|
|
4
4
|
import { ERROR_TOO_MANY_SETS } from '../logger/constants';
|
|
5
5
|
var noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
|
|
6
6
|
function userKeyToQueryParam(userKey) {
|
|
@@ -29,16 +29,16 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
29
29
|
return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
|
|
30
30
|
},
|
|
31
31
|
fetchAuth: function (userMatchingKeys) {
|
|
32
|
-
var url = urls.auth + "/v2/auth";
|
|
33
|
-
if (userMatchingKeys) { //
|
|
32
|
+
var url = urls.auth + "/v2/auth?s=" + FLAGS_SPEC;
|
|
33
|
+
if (userMatchingKeys) { // `userMatchingKeys` is undefined in server-side
|
|
34
34
|
var queryParams = userMatchingKeys.map(userKeyToQueryParam).join('&');
|
|
35
|
-
if (queryParams)
|
|
36
|
-
url += '
|
|
35
|
+
if (queryParams)
|
|
36
|
+
url += '&' + queryParams;
|
|
37
37
|
}
|
|
38
38
|
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
|
|
39
39
|
},
|
|
40
40
|
fetchSplitChanges: function (since, noCache, till) {
|
|
41
|
-
var url = urls.sdk + "/splitChanges?
|
|
41
|
+
var url = urls.sdk + "/splitChanges?s=" + FLAGS_SPEC + "&since=" + since + (till ? '&till=' + till : '') + (filterQueryString || '');
|
|
42
42
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SPLITS))
|
|
43
43
|
.catch(function (err) {
|
|
44
44
|
if (err.statusCode === 414)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FLAGS_SPEC } from '../utils/constants';
|
|
1
2
|
import { startsWith } from '../utils/lang';
|
|
2
3
|
import { hash } from '../utils/murmur3/murmur3';
|
|
3
4
|
var everythingAtTheEnd = /[^.]+$/;
|
|
@@ -66,5 +67,5 @@ export { KeyBuilder };
|
|
|
66
67
|
* The hash is in hexadecimal format (8 characters max, 32 bits).
|
|
67
68
|
*/
|
|
68
69
|
export function getStorageHash(settings) {
|
|
69
|
-
return hash(settings.core.authorizationKey + "::" + settings.sync.__splitFiltersValidation.queryString + "::
|
|
70
|
+
return hash(settings.core.authorizationKey + "::" + settings.sync.__splitFiltersValidation.queryString + "::" + FLAGS_SPEC).toString(16);
|
|
70
71
|
}
|
|
@@ -54,7 +54,7 @@ export var base = {
|
|
|
54
54
|
// Telemetry Server
|
|
55
55
|
telemetry: 'https://telemetry.split.io/api',
|
|
56
56
|
},
|
|
57
|
-
// Defines which kind of storage we should
|
|
57
|
+
// Defines which kind of storage we should instantiate.
|
|
58
58
|
storage: undefined,
|
|
59
59
|
// Defines if the logs are enabled, SDK wide.
|
|
60
60
|
debug: undefined,
|
package/package.json
CHANGED
|
@@ -50,7 +50,7 @@ export function ifElseIfCombinerContext(log: ILogger, predicates: IEvaluator[]):
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// if there is none predicates, then there was an error in parsing phase
|
|
53
|
-
if (!Array.isArray(predicates) ||
|
|
53
|
+
if (!Array.isArray(predicates) || predicates.length === 0) {
|
|
54
54
|
return unexpectedInputHandler;
|
|
55
55
|
} else {
|
|
56
56
|
return ifElseIfCombiner;
|
|
@@ -44,8 +44,7 @@ export function parser(log: ILogger, conditions: ISplitCondition[], storage: ISt
|
|
|
44
44
|
};
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
// if matcher's factory can't
|
|
48
|
-
// will be empty
|
|
47
|
+
// if matcher's factory can't instantiate the matchers, the expressions array will be empty
|
|
49
48
|
if (expressions.length === 0) {
|
|
50
49
|
// reset any data collected during parsing
|
|
51
50
|
predicates = [];
|
|
@@ -2,7 +2,7 @@ import * as c from '../constants';
|
|
|
2
2
|
|
|
3
3
|
export const codesError: [number, string][] = [
|
|
4
4
|
// evaluator
|
|
5
|
-
[c.ERROR_ENGINE_COMBINER_IFELSEIF, c.LOG_PREFIX_ENGINE_COMBINER + 'Invalid feature flag, no valid rules found'],
|
|
5
|
+
[c.ERROR_ENGINE_COMBINER_IFELSEIF, c.LOG_PREFIX_ENGINE_COMBINER + 'Invalid feature flag, no valid rules or unsupported matcher type found'],
|
|
6
6
|
// SDK
|
|
7
7
|
[c.ERROR_LOGLEVEL_INVALID, 'logger: Invalid Log Level - No changes to the logs will be applied.'],
|
|
8
8
|
[c.ERROR_CLIENT_CANNOT_GET_READY, 'The SDK will not get ready. Reason: %s'],
|
|
@@ -35,9 +35,6 @@ export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: bo
|
|
|
35
35
|
return syncManager ? syncManager.flush() : Promise.resolve();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
// Same promise if `destroy` is called multiple times
|
|
39
|
-
let destroyPromise: Promise<void> | undefined;
|
|
40
|
-
|
|
41
38
|
return objectAssign(
|
|
42
39
|
// Proto-linkage of the readiness Event Emitter
|
|
43
40
|
Object.create(sdkReadinessManager.sdkStatus) as IStatusInterface,
|
|
@@ -56,8 +53,6 @@ export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: bo
|
|
|
56
53
|
return __cooldown(__flush, COOLDOWN_TIME_IN_MILLIS);
|
|
57
54
|
},
|
|
58
55
|
destroy() {
|
|
59
|
-
if (destroyPromise) return destroyPromise;
|
|
60
|
-
|
|
61
56
|
// Mark the SDK as destroyed immediately
|
|
62
57
|
sdkReadinessManager.readinessManager.destroy();
|
|
63
58
|
|
|
@@ -70,7 +65,7 @@ export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: bo
|
|
|
70
65
|
// Stop background jobs
|
|
71
66
|
syncManager && syncManager.stop();
|
|
72
67
|
|
|
73
|
-
|
|
68
|
+
return __flush().then(() => {
|
|
74
69
|
// Cleanup event listeners
|
|
75
70
|
signalListener && signalListener.stop();
|
|
76
71
|
|
|
@@ -80,8 +75,6 @@ export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: bo
|
|
|
80
75
|
// Cleanup storage
|
|
81
76
|
return storage.destroy();
|
|
82
77
|
});
|
|
83
|
-
|
|
84
|
-
return destroyPromise;
|
|
85
78
|
}
|
|
86
79
|
}
|
|
87
80
|
);
|
package/src/services/splitApi.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { splitHttpClientFactory } from './splitHttpClient';
|
|
|
4
4
|
import { ISplitApi } from './types';
|
|
5
5
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
6
6
|
import { ITelemetryTracker } from '../trackers/types';
|
|
7
|
-
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MY_SEGMENT } from '../utils/constants';
|
|
7
|
+
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MY_SEGMENT, FLAGS_SPEC } from '../utils/constants';
|
|
8
8
|
import { ERROR_TOO_MANY_SETS } from '../logger/constants';
|
|
9
9
|
|
|
10
10
|
const noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
|
|
@@ -44,17 +44,16 @@ export function splitApiFactory(
|
|
|
44
44
|
},
|
|
45
45
|
|
|
46
46
|
fetchAuth(userMatchingKeys?: string[]) {
|
|
47
|
-
let url = `${urls.auth}/v2/auth`;
|
|
48
|
-
if (userMatchingKeys) { //
|
|
47
|
+
let url = `${urls.auth}/v2/auth?s=${FLAGS_SPEC}`;
|
|
48
|
+
if (userMatchingKeys) { // `userMatchingKeys` is undefined in server-side
|
|
49
49
|
const queryParams = userMatchingKeys.map(userKeyToQueryParam).join('&');
|
|
50
|
-
if (queryParams)
|
|
51
|
-
url += '?' + queryParams;
|
|
50
|
+
if (queryParams) url += '&' + queryParams;
|
|
52
51
|
}
|
|
53
52
|
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
|
|
54
53
|
},
|
|
55
54
|
|
|
56
55
|
fetchSplitChanges(since: number, noCache?: boolean, till?: number) {
|
|
57
|
-
const url = `${urls.sdk}/splitChanges?
|
|
56
|
+
const url = `${urls.sdk}/splitChanges?s=${FLAGS_SPEC}&since=${since}${till ? '&till=' + till : ''}${filterQueryString || ''}`;
|
|
58
57
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SPLITS))
|
|
59
58
|
.catch((err) => {
|
|
60
59
|
if (err.statusCode === 414) settings.log.error(ERROR_TOO_MANY_SETS);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ISettings } from '../types';
|
|
2
|
+
import { FLAGS_SPEC } from '../utils/constants';
|
|
2
3
|
import { startsWith } from '../utils/lang';
|
|
3
4
|
import { hash } from '../utils/murmur3/murmur3';
|
|
4
5
|
|
|
@@ -85,5 +86,5 @@ export class KeyBuilder {
|
|
|
85
86
|
* The hash is in hexadecimal format (8 characters max, 32 bits).
|
|
86
87
|
*/
|
|
87
88
|
export function getStorageHash(settings: ISettings) {
|
|
88
|
-
return hash(`${settings.core.authorizationKey}::${settings.sync.__splitFiltersValidation.queryString}
|
|
89
|
+
return hash(`${settings.core.authorizationKey}::${settings.sync.__splitFiltersValidation.queryString}::${FLAGS_SPEC}`).toString(16);
|
|
89
90
|
}
|
package/src/types.ts
CHANGED
|
@@ -353,7 +353,7 @@ interface INodeBasicSettings extends ISharedSettings {
|
|
|
353
353
|
IPAddressesEnabled?: boolean
|
|
354
354
|
},
|
|
355
355
|
/**
|
|
356
|
-
* Defines which kind of storage we should
|
|
356
|
+
* Defines which kind of storage we should instantiate.
|
|
357
357
|
* @property {Object} storage
|
|
358
358
|
*/
|
|
359
359
|
storage?: (params: any) => any,
|
|
@@ -918,7 +918,7 @@ export namespace SplitIO {
|
|
|
918
918
|
*/
|
|
919
919
|
features?: MockedFeaturesMap,
|
|
920
920
|
/**
|
|
921
|
-
* Defines which kind of storage we should
|
|
921
|
+
* Defines which kind of storage we should instantiate.
|
|
922
922
|
* @property {Object} storage
|
|
923
923
|
*/
|
|
924
924
|
storage?: (params: IStorageFactoryParams) => IStorageSync | IStorageAsync,
|
|
@@ -944,7 +944,7 @@ export namespace SplitIO {
|
|
|
944
944
|
*/
|
|
945
945
|
urls?: UrlSettings,
|
|
946
946
|
/**
|
|
947
|
-
* Defines which kind of storage we should
|
|
947
|
+
* Defines which kind of storage we should instantiate.
|
|
948
948
|
* @property {Object} storage
|
|
949
949
|
*/
|
|
950
950
|
storage?: (params: IStorageFactoryParams) => IStorageSync,
|
|
@@ -61,7 +61,7 @@ export const base = {
|
|
|
61
61
|
telemetry: 'https://telemetry.split.io/api',
|
|
62
62
|
},
|
|
63
63
|
|
|
64
|
-
// Defines which kind of storage we should
|
|
64
|
+
// Defines which kind of storage we should instantiate.
|
|
65
65
|
storage: undefined,
|
|
66
66
|
|
|
67
67
|
// Defines if the logs are enabled, SDK wide.
|
package/types/types.d.ts
CHANGED
|
@@ -347,7 +347,7 @@ interface INodeBasicSettings extends ISharedSettings {
|
|
|
347
347
|
IPAddressesEnabled?: boolean;
|
|
348
348
|
};
|
|
349
349
|
/**
|
|
350
|
-
* Defines which kind of storage we should
|
|
350
|
+
* Defines which kind of storage we should instantiate.
|
|
351
351
|
* @property {Object} storage
|
|
352
352
|
*/
|
|
353
353
|
storage?: (params: any) => any;
|
|
@@ -915,7 +915,7 @@ export declare namespace SplitIO {
|
|
|
915
915
|
*/
|
|
916
916
|
features?: MockedFeaturesMap;
|
|
917
917
|
/**
|
|
918
|
-
* Defines which kind of storage we should
|
|
918
|
+
* Defines which kind of storage we should instantiate.
|
|
919
919
|
* @property {Object} storage
|
|
920
920
|
*/
|
|
921
921
|
storage?: (params: IStorageFactoryParams) => IStorageSync | IStorageAsync;
|
|
@@ -941,7 +941,7 @@ export declare namespace SplitIO {
|
|
|
941
941
|
*/
|
|
942
942
|
urls?: UrlSettings;
|
|
943
943
|
/**
|
|
944
|
-
* Defines which kind of storage we should
|
|
944
|
+
* Defines which kind of storage we should instantiate.
|
|
945
945
|
* @property {Object} storage
|
|
946
946
|
*/
|
|
947
947
|
storage?: (params: IStorageFactoryParams) => IStorageSync;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare class Semver {
|
|
2
|
+
private _major;
|
|
3
|
+
private _minor;
|
|
4
|
+
private _patch;
|
|
5
|
+
private _preRelease;
|
|
6
|
+
private _isStable;
|
|
7
|
+
private _oVersion;
|
|
8
|
+
constructor(version: string);
|
|
9
|
+
private removeMetadataIfExists;
|
|
10
|
+
isEqualTo(toCompare: Semver): boolean;
|
|
11
|
+
isGreaterThanOrEqualTo(toCompare: Semver): boolean;
|
|
12
|
+
isLessThanOrEqualTo(toCompare: Semver): boolean;
|
|
13
|
+
isBetween(start: Semver, end: Semver): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Precedence comparision between 2 Semver objects.
|
|
16
|
+
*
|
|
17
|
+
* @return the value {@code 0} if {@code this == toCompare};
|
|
18
|
+
* a value less than {@code 0} if {@code this < toCompare}; and
|
|
19
|
+
* a value greater than {@code 0} if {@code this > toCompare}
|
|
20
|
+
*/
|
|
21
|
+
private compare;
|
|
22
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LogLevel } from '../../../types';
|
|
2
|
+
/**
|
|
3
|
+
* The debug level can be set globally via the `localStorage.splitio_debug` item in browser, or the `SPLITIO_DEBUG` env var in NodeJS.
|
|
4
|
+
* Acceptable values are: 'DEBUG', 'INFO', 'WARN', 'ERROR', 'NONE'.
|
|
5
|
+
* Other acceptable values are 'on', 'enable' and 'enabled', which are equivalent to 'DEBUG'.
|
|
6
|
+
* Any other value, like undefined, null or an invalid string, returns `undefined` and means that the global log level is not set.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getGlobalLogLevel(): LogLevel | undefined;
|