@splitsoftware/splitio-commons 1.2.1-rc.5 → 1.2.1-rc.6
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/logger/constants.js +3 -2
- package/cjs/logger/messages/debug.js +3 -3
- package/cjs/logger/messages/error.js +2 -2
- package/cjs/logger/messages/info.js +4 -3
- package/cjs/sdkFactory/userConsentProps.js +11 -8
- package/cjs/storages/KeyBuilder.js +1 -5
- package/cjs/sync/submitters/eventsSyncTask.js +8 -1
- package/cjs/utils/lang/index.js +8 -1
- package/cjs/utils/settingsValidation/consent.js +2 -2
- package/cjs/utils/settingsValidation/impressionsMode.js +2 -2
- package/esm/logger/constants.js +1 -0
- package/esm/logger/messages/debug.js +3 -3
- package/esm/logger/messages/error.js +2 -2
- package/esm/logger/messages/info.js +4 -3
- package/esm/sdkFactory/userConsentProps.js +12 -9
- package/esm/storages/KeyBuilder.js +2 -6
- package/esm/sync/submitters/eventsSyncTask.js +8 -1
- package/esm/utils/lang/index.js +6 -0
- package/esm/utils/settingsValidation/consent.js +2 -2
- package/esm/utils/settingsValidation/impressionsMode.js +2 -2
- package/package.json +1 -1
- package/src/logger/constants.ts +1 -0
- package/src/logger/messages/debug.ts +3 -3
- package/src/logger/messages/error.ts +2 -2
- package/src/logger/messages/info.ts +4 -3
- package/src/sdkFactory/userConsentProps.ts +12 -9
- package/src/storages/KeyBuilder.ts +2 -6
- package/src/sync/submitters/eventsSyncTask.ts +8 -1
- package/src/utils/lang/index.ts +8 -1
- package/src/utils/settingsValidation/consent.ts +2 -1
- package/src/utils/settingsValidation/impressionsMode.ts +2 -1
- package/types/logger/constants.d.ts +1 -0
- package/types/utils/lang/index.d.ts +4 -0
package/cjs/logger/constants.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SYNC_SPLITS_FETCH_RETRY = exports.POLLING_STOP = exports.POLLING_START = exports.POLLING_SMART_PAUSING = exports.NEW_FACTORY = exports.NEW_SHARED_CLIENT = exports.IMPRESSION_QUEUEING = exports.IMPRESSION = exports.CLIENT_READY = exports.CLIENT_READY_FROM_CACHE = exports.SETTINGS_SPLITS_FILTER = exports.SYNC_TASK_STOP = exports.SYNC_TASK_EXECUTE = exports.SYNC_TASK_START = exports.STREAMING_NEW_MESSAGE = exports.SYNC_SPLITS_SEGMENTS = exports.SYNC_SPLITS_REMOVED = exports.SYNC_SPLITS_NEW = exports.SYNC_SPLITS_FETCH = exports.SYNC_OFFLINE_DATA = exports.RETRIEVE_MANAGER = exports.RETRIEVE_CLIENT_EXISTING = exports.RETRIEVE_CLIENT_DEFAULT = exports.CLEANUP_DEREGISTERING = exports.CLEANUP_REGISTERING = exports.ENGINE_SANITIZE = exports.ENGINE_VALUE = exports.ENGINE_MATCHER_WHITELIST = exports.ENGINE_MATCHER_STARTS_WITH = exports.ENGINE_MATCHER_STRING_INVALID = exports.ENGINE_MATCHER_STRING = exports.ENGINE_MATCHER_SEGMENT = exports.ENGINE_MATCHER_PART_OF = exports.ENGINE_MATCHER_LESS = exports.ENGINE_MATCHER_GREATER = exports.ENGINE_MATCHER_ENDS_WITH = exports.ENGINE_MATCHER_EQUAL_TO_SET = exports.ENGINE_MATCHER_EQUAL = exports.ENGINE_MATCHER_DEPENDENCY_PRE = exports.ENGINE_MATCHER_DEPENDENCY = exports.ENGINE_MATCHER_CONTAINS_STRING = exports.ENGINE_MATCHER_CONTAINS_ANY = exports.ENGINE_MATCHER_CONTAINS_ALL = exports.ENGINE_MATCHER_BOOLEAN = exports.ENGINE_MATCHER_BETWEEN = exports.ENGINE_MATCHER_ALL = exports.ENGINE_BUCKET = exports.ENGINE_COMBINER_IFELSEIF_NO_TREATMENT = exports.ENGINE_COMBINER_IFELSEIF = exports.ENGINE_COMBINER_AND = void 0;
|
|
4
|
-
exports.
|
|
5
|
-
exports.LOG_PREFIX_CLEANUP = exports.LOG_PREFIX_EVENTS_TRACKER = exports.LOG_PREFIX_IMPRESSIONS_TRACKER = exports.LOG_PREFIX_SYNC_SUBMITTERS = exports.LOG_PREFIX_SYNC_POLLING = exports.LOG_PREFIX_SYNC_MYSEGMENTS = exports.LOG_PREFIX_SYNC_SEGMENTS = exports.LOG_PREFIX_SYNC_SPLITS = exports.LOG_PREFIX_SYNC_STREAMING = exports.LOG_PREFIX_SYNC_OFFLINE = exports.LOG_PREFIX_SYNC_MANAGER = exports.LOG_PREFIX_SYNC = exports.LOG_PREFIX_ENGINE_VALUE = exports.LOG_PREFIX_ENGINE_MATCHER = exports.LOG_PREFIX_ENGINE_COMBINER = exports.LOG_PREFIX_ENGINE = exports.LOG_PREFIX_INSTANTIATION = exports.LOG_PREFIX_SETTINGS = exports.ERROR_NOT_BOOLEAN = exports.ERROR_STORAGE_INVALID = exports.ERROR_LOCALHOST_MODULE_REQUIRED = exports.ERROR_HTTP = exports.ERROR_INVALID_CONFIG_PARAM = exports.ERROR_EMPTY_ARRAY = exports.ERROR_EMPTY = exports.ERROR_INVALID = exports.ERROR_INVALID_KEY_OBJECT = exports.ERROR_TOO_LONG = exports.ERROR_NULL = exports.ERROR_CLIENT_DESTROYED = exports.ERROR_NOT_FINITE = void 0;
|
|
4
|
+
exports.ERROR_NOT_PLAIN_OBJECT = exports.ERROR_EVENT_TYPE_FORMAT = exports.ERROR_EVENTS_TRACKER = exports.ERROR_IMPRESSIONS_LISTENER = exports.ERROR_IMPRESSIONS_TRACKER = exports.ERROR_STREAMING_AUTH = exports.ERROR_STREAMING_SSE = exports.ERROR_SYNC_OFFLINE_LOADING = exports.ERROR_CLIENT_CANNOT_GET_READY = exports.ERROR_CLIENT_LISTENER = exports.ERROR_LOGLEVEL_INVALID = exports.ERROR_ENGINE_COMBINER_IFELSEIF = exports.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = exports.WARN_API_KEY = exports.WARN_SPLITS_FILTER_EMPTY = exports.WARN_SPLITS_FILTER_INVALID = exports.WARN_SPLITS_FILTER_IGNORED = exports.WARN_INTEGRATION_INVALID = exports.WARN_NOT_EXISTENT_TT = exports.WARN_LOWERCASE_TRAFFIC_TYPE = exports.WARN_NOT_EXISTENT_SPLIT = exports.WARN_TRIMMING = exports.WARN_CONVERTING = exports.WARN_TRIMMING_PROPERTIES = exports.WARN_SETTING_NULL = exports.SUBMITTERS_PUSH_RETRY = exports.SUBMITTERS_PUSH_FAILS = exports.STREAMING_FALLBACK = exports.STREAMING_PARSING_MESSAGE_FAILS = exports.STREAMING_PARSING_ERROR_FAILS = exports.SYNC_SPLITS_FETCH_FAILS = exports.SYNC_MYSEGMENTS_FETCH_RETRY = exports.CLIENT_NOT_READY = exports.CLIENT_NO_LISTENER = exports.ENGINE_VALUE_NO_ATTRIBUTES = exports.ENGINE_VALUE_INVALID = exports.USER_CONSENT_NOT_UPDATED = exports.USER_CONSENT_UPDATED = exports.IMPRESSIONS_TRACKER_SUCCESS = exports.EVENTS_TRACKER_SUCCESS = exports.SYNC_STOP_POLLING = exports.SYNC_CONTINUE_POLLING = exports.SYNC_START_POLLING = exports.SUBMITTERS_PUSH = exports.SUBMITTERS_PUSH_FULL_QUEUE = exports.STREAMING_DISCONNECTING = exports.STREAMING_DISABLED = exports.STREAMING_CONNECTING = exports.STREAMING_RECONNECT = exports.STREAMING_REFRESH_TOKEN = void 0;
|
|
5
|
+
exports.LOG_PREFIX_CLEANUP = exports.LOG_PREFIX_EVENTS_TRACKER = exports.LOG_PREFIX_IMPRESSIONS_TRACKER = exports.LOG_PREFIX_SYNC_SUBMITTERS = exports.LOG_PREFIX_SYNC_POLLING = exports.LOG_PREFIX_SYNC_MYSEGMENTS = exports.LOG_PREFIX_SYNC_SEGMENTS = exports.LOG_PREFIX_SYNC_SPLITS = exports.LOG_PREFIX_SYNC_STREAMING = exports.LOG_PREFIX_SYNC_OFFLINE = exports.LOG_PREFIX_SYNC_MANAGER = exports.LOG_PREFIX_SYNC = exports.LOG_PREFIX_ENGINE_VALUE = exports.LOG_PREFIX_ENGINE_MATCHER = exports.LOG_PREFIX_ENGINE_COMBINER = exports.LOG_PREFIX_ENGINE = exports.LOG_PREFIX_INSTANTIATION = exports.LOG_PREFIX_SETTINGS = exports.ERROR_NOT_BOOLEAN = exports.ERROR_STORAGE_INVALID = exports.ERROR_LOCALHOST_MODULE_REQUIRED = exports.ERROR_HTTP = exports.ERROR_INVALID_CONFIG_PARAM = exports.ERROR_EMPTY_ARRAY = exports.ERROR_EMPTY = exports.ERROR_INVALID = exports.ERROR_INVALID_KEY_OBJECT = exports.ERROR_TOO_LONG = exports.ERROR_NULL = exports.ERROR_CLIENT_DESTROYED = exports.ERROR_NOT_FINITE = exports.ERROR_SIZE_EXCEEDED = void 0;
|
|
6
6
|
/**
|
|
7
7
|
* Message codes used to trim string log messages from commons and client-side API modules,
|
|
8
8
|
* in order to reduce the minimal SDK size for Browser and eventually other client-side environments.
|
|
@@ -73,6 +73,7 @@ exports.SYNC_STOP_POLLING = 119;
|
|
|
73
73
|
exports.EVENTS_TRACKER_SUCCESS = 120;
|
|
74
74
|
exports.IMPRESSIONS_TRACKER_SUCCESS = 121;
|
|
75
75
|
exports.USER_CONSENT_UPDATED = 122;
|
|
76
|
+
exports.USER_CONSENT_NOT_UPDATED = 123;
|
|
76
77
|
exports.ENGINE_VALUE_INVALID = 200;
|
|
77
78
|
exports.ENGINE_VALUE_NO_ATTRIBUTES = 201;
|
|
78
79
|
exports.CLIENT_NO_LISTENER = 202;
|
|
@@ -34,9 +34,9 @@ exports.codesDebug = info_1.codesInfo.concat([
|
|
|
34
34
|
// SDK
|
|
35
35
|
[c.CLEANUP_REGISTERING, c.LOG_PREFIX_CLEANUP + 'Registering cleanup handler %s'],
|
|
36
36
|
[c.CLEANUP_DEREGISTERING, c.LOG_PREFIX_CLEANUP + 'Deregistering cleanup handler %s'],
|
|
37
|
-
[c.RETRIEVE_CLIENT_DEFAULT, '
|
|
38
|
-
[c.RETRIEVE_CLIENT_EXISTING, '
|
|
39
|
-
[c.RETRIEVE_MANAGER, '
|
|
37
|
+
[c.RETRIEVE_CLIENT_DEFAULT, 'Retrieving default SDK client.'],
|
|
38
|
+
[c.RETRIEVE_CLIENT_EXISTING, 'Retrieving existing SDK client.'],
|
|
39
|
+
[c.RETRIEVE_MANAGER, 'Retrieving manager instance.'],
|
|
40
40
|
// synchronizer
|
|
41
41
|
[c.SYNC_OFFLINE_DATA, c.LOG_PREFIX_SYNC_OFFLINE + 'Splits data: \n%s'],
|
|
42
42
|
[c.SYNC_SPLITS_FETCH, c.LOG_PREFIX_SYNC_SPLITS + 'Spin up split update using since = %s'],
|
|
@@ -8,7 +8,7 @@ exports.codesError = [
|
|
|
8
8
|
[c.ERROR_ENGINE_COMBINER_IFELSEIF, c.LOG_PREFIX_ENGINE_COMBINER + 'Invalid Split, no valid rules found'],
|
|
9
9
|
// SDK
|
|
10
10
|
[c.ERROR_LOGLEVEL_INVALID, 'logger: Invalid Log Level - No changes to the logs will be applied.'],
|
|
11
|
-
[c.ERROR_CLIENT_CANNOT_GET_READY, '
|
|
11
|
+
[c.ERROR_CLIENT_CANNOT_GET_READY, 'The SDK will not get ready. Reason: %s'],
|
|
12
12
|
[c.ERROR_IMPRESSIONS_TRACKER, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Could not store impressions bulk with %s impression(s). Error: %s'],
|
|
13
13
|
[c.ERROR_IMPRESSIONS_LISTENER, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Impression listener logImpression method threw: %s.'],
|
|
14
14
|
[c.ERROR_EVENTS_TRACKER, c.LOG_PREFIX_EVENTS_TRACKER + 'Failed to queue %s'],
|
|
@@ -31,7 +31,7 @@ exports.codesError = [
|
|
|
31
31
|
[c.ERROR_INVALID, '%s: you passed an invalid %s. It must be a non-empty string.'],
|
|
32
32
|
[c.ERROR_EMPTY, '%s: you passed an empty %s. It must be a non-empty string.'],
|
|
33
33
|
[c.ERROR_EMPTY_ARRAY, '%s: %s must be a non-empty array.'],
|
|
34
|
-
[c.ERROR_NOT_BOOLEAN, '%s:
|
|
34
|
+
[c.ERROR_NOT_BOOLEAN, '%s: provided param must be a boolean value.'],
|
|
35
35
|
// initialization / settings validation
|
|
36
36
|
[c.ERROR_INVALID_CONFIG_PARAM, c.LOG_PREFIX_SETTINGS + ': you passed an invalid "%s" config param. It should be one of the following values: %s. Defaulting to "%s".'],
|
|
37
37
|
[c.ERROR_LOCALHOST_MODULE_REQUIRED, c.LOG_PREFIX_SETTINGS + ': an invalid value was received for "sync.localhostMode" config. A valid entity should be provided for localhost mode.'],
|
|
@@ -12,11 +12,12 @@ exports.codesInfo = warn_1.codesWarn.concat([
|
|
|
12
12
|
// SDK
|
|
13
13
|
[c.IMPRESSION, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Split: %s. Key: %s. Evaluation: %s. Label: %s'],
|
|
14
14
|
[c.IMPRESSION_QUEUEING, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Queueing corresponding impression.'],
|
|
15
|
-
[c.NEW_SHARED_CLIENT, '
|
|
16
|
-
[c.NEW_FACTORY, '
|
|
15
|
+
[c.NEW_SHARED_CLIENT, 'New shared client instance created.'],
|
|
16
|
+
[c.NEW_FACTORY, 'New Split SDK instance created.'],
|
|
17
17
|
[c.EVENTS_TRACKER_SUCCESS, c.LOG_PREFIX_EVENTS_TRACKER + 'Successfully queued %s'],
|
|
18
18
|
[c.IMPRESSIONS_TRACKER_SUCCESS, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Successfully stored %s impression(s).'],
|
|
19
|
-
[c.USER_CONSENT_UPDATED, '
|
|
19
|
+
[c.USER_CONSENT_UPDATED, 'setUserConsent: consent status changed from %s to %s.'],
|
|
20
|
+
[c.USER_CONSENT_NOT_UPDATED, 'setUserConsent: call had no effect because it was the current consent status (%s).'],
|
|
20
21
|
// synchronizer
|
|
21
22
|
[c.POLLING_SMART_PAUSING, c.LOG_PREFIX_SYNC_POLLING + 'Turning segments data polling %s.'],
|
|
22
23
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.userConsentProps = void 0;
|
|
4
4
|
var constants_1 = require("../logger/constants");
|
|
5
5
|
var constants_2 = require("../utils/constants");
|
|
6
|
+
var lang_1 = require("../utils/lang");
|
|
6
7
|
// Extend client-side factory instances with user consent getter/setter
|
|
7
8
|
function userConsentProps(settings, syncManager) {
|
|
8
9
|
var log = settings.log;
|
|
@@ -10,19 +11,21 @@ function userConsentProps(settings, syncManager) {
|
|
|
10
11
|
setUserConsent: function (consent) {
|
|
11
12
|
var _a, _b;
|
|
12
13
|
// validate input param
|
|
13
|
-
if (
|
|
14
|
-
log.
|
|
14
|
+
if (!(0, lang_1.isBoolean)(consent)) {
|
|
15
|
+
log.warn(constants_1.ERROR_NOT_BOOLEAN, ['setUserConsent']);
|
|
15
16
|
return false;
|
|
16
17
|
}
|
|
17
18
|
var newConsentStatus = consent ? constants_2.CONSENT_GRANTED : constants_2.CONSENT_DECLINED;
|
|
18
|
-
if (settings.userConsent !== newConsentStatus) {
|
|
19
|
-
|
|
19
|
+
if (settings.userConsent !== newConsentStatus) { // @ts-ignore, modify readonly prop
|
|
20
|
+
settings.userConsent = newConsentStatus;
|
|
20
21
|
if (consent)
|
|
21
|
-
(_a = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _a === void 0 ? void 0 : _a.start();
|
|
22
|
+
(_a = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _a === void 0 ? void 0 : _a.start(); // resumes submitters if transitioning to GRANTED
|
|
22
23
|
else
|
|
23
|
-
(_b = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _b === void 0 ? void 0 : _b.stop();
|
|
24
|
-
log.info(constants_1.USER_CONSENT_UPDATED, [settings.userConsent, newConsentStatus]);
|
|
25
|
-
|
|
24
|
+
(_b = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _b === void 0 ? void 0 : _b.stop(); // pauses submitters if transitioning to DECLINED
|
|
25
|
+
log.info(constants_1.USER_CONSENT_UPDATED, [settings.userConsent, newConsentStatus]);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
log.info(constants_1.USER_CONSENT_NOT_UPDATED, [newConsentStatus]);
|
|
26
29
|
}
|
|
27
30
|
return true;
|
|
28
31
|
},
|
|
@@ -5,11 +5,7 @@ var lang_1 = require("../utils/lang");
|
|
|
5
5
|
var everythingAtTheEnd = /[^.]+$/;
|
|
6
6
|
var DEFAULT_PREFIX = 'SPLITIO';
|
|
7
7
|
function validatePrefix(prefix) {
|
|
8
|
-
return prefix
|
|
9
|
-
(0, lang_1.endsWith)(prefix, '.' + DEFAULT_PREFIX) ?
|
|
10
|
-
prefix : // suffix already appended
|
|
11
|
-
prefix + '.' + DEFAULT_PREFIX : // append suffix
|
|
12
|
-
DEFAULT_PREFIX; // use default prefix if none is provided
|
|
8
|
+
return prefix ? prefix + '.SPLITIO' : 'SPLITIO';
|
|
13
9
|
}
|
|
14
10
|
exports.validatePrefix = validatePrefix;
|
|
15
11
|
var KeyBuilder = /** @class */ (function () {
|
|
@@ -10,18 +10,25 @@ var DATA_NAME = 'events';
|
|
|
10
10
|
function eventsSyncTaskFactory(log, postEventsBulk, eventsCache, eventsPushRate, eventsFirstPushWindow, latencyTracker) {
|
|
11
11
|
// don't retry events.
|
|
12
12
|
var syncTask = (0, submitterSyncTask_1.submitterSyncTaskFactory)(log, postEventsBulk, eventsCache, eventsPushRate, DATA_NAME, latencyTracker);
|
|
13
|
-
// Set a timer for the first push of events
|
|
13
|
+
// Set a timer for the first push window of events.
|
|
14
|
+
// Not implemented in the base submitter or sync task, since this feature is only used by the events submitter.
|
|
14
15
|
if (eventsFirstPushWindow > 0) {
|
|
16
|
+
var running_1 = false;
|
|
15
17
|
var stopEventPublisherTimeout_1;
|
|
16
18
|
var originalStart_1 = syncTask.start;
|
|
17
19
|
syncTask.start = function () {
|
|
20
|
+
running_1 = true;
|
|
18
21
|
stopEventPublisherTimeout_1 = setTimeout(originalStart_1, eventsFirstPushWindow);
|
|
19
22
|
};
|
|
20
23
|
var originalStop_1 = syncTask.stop;
|
|
21
24
|
syncTask.stop = function () {
|
|
25
|
+
running_1 = false;
|
|
22
26
|
clearTimeout(stopEventPublisherTimeout_1);
|
|
23
27
|
originalStop_1();
|
|
24
28
|
};
|
|
29
|
+
syncTask.isRunning = function () {
|
|
30
|
+
return running_1;
|
|
31
|
+
};
|
|
25
32
|
}
|
|
26
33
|
// register events submitter to be executed when events cache is full
|
|
27
34
|
eventsCache.setOnFullQueueCb(function () {
|
package/cjs/utils/lang/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.uniqueId = exports.uniqAsStrings = exports.uniq = exports.toString = exports.toNumber = exports.startsWith = exports.merge = exports.isString = exports.isObject = exports.isNaNNumber = exports.isIntegerNumber = exports.isFiniteNumber = exports.isBoolean = exports.groupBy = exports.get = exports.forOwn = exports.findIndex = exports.find = exports.endsWith = void 0;
|
|
3
|
+
exports.uniqueId = exports.uniqAsStrings = exports.uniq = exports.toString = exports.toNumber = exports.startsWith = exports.merge = exports.stringToUpperCase = exports.isString = exports.isObject = exports.isNaNNumber = exports.isIntegerNumber = exports.isFiniteNumber = exports.isBoolean = exports.groupBy = exports.get = exports.forOwn = exports.findIndex = exports.find = exports.endsWith = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
/**
|
|
6
6
|
* Checks if the target string ends with the sub string.
|
|
@@ -167,6 +167,13 @@ function isString(val) {
|
|
|
167
167
|
return typeof val === 'string' || val instanceof String;
|
|
168
168
|
}
|
|
169
169
|
exports.isString = isString;
|
|
170
|
+
/**
|
|
171
|
+
* String sanitizer. Returns the provided value converted to uppercase if it is a string.
|
|
172
|
+
*/
|
|
173
|
+
function stringToUpperCase(val) {
|
|
174
|
+
return isString(val) ? val.toUpperCase() : val;
|
|
175
|
+
}
|
|
176
|
+
exports.stringToUpperCase = stringToUpperCase;
|
|
170
177
|
/**
|
|
171
178
|
* Deep copy version of Object.assign using recursion.
|
|
172
179
|
* There are some assumptions here. It's for internal use and we don't need verbose errors
|
|
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.validateConsent = void 0;
|
|
4
4
|
var constants_1 = require("../../logger/constants");
|
|
5
5
|
var constants_2 = require("../constants");
|
|
6
|
+
var lang_1 = require("../lang");
|
|
6
7
|
var userConsentValues = [constants_2.CONSENT_DECLINED, constants_2.CONSENT_GRANTED, constants_2.CONSENT_UNKNOWN];
|
|
7
8
|
function validateConsent(_a) {
|
|
8
9
|
var userConsent = _a.userConsent, log = _a.log;
|
|
9
|
-
|
|
10
|
-
userConsent = userConsent.toUpperCase();
|
|
10
|
+
userConsent = (0, lang_1.stringToUpperCase)(userConsent);
|
|
11
11
|
if (userConsentValues.indexOf(userConsent) > -1)
|
|
12
12
|
return userConsent;
|
|
13
13
|
log.error(constants_1.ERROR_INVALID_CONFIG_PARAM, ['userConsent', userConsentValues, constants_2.CONSENT_GRANTED]);
|
|
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.validImpressionsMode = void 0;
|
|
4
4
|
var constants_1 = require("../../logger/constants");
|
|
5
5
|
var constants_2 = require("../constants");
|
|
6
|
+
var lang_1 = require("../lang");
|
|
6
7
|
function validImpressionsMode(log, impressionsMode) {
|
|
7
|
-
|
|
8
|
-
impressionsMode = impressionsMode.toUpperCase();
|
|
8
|
+
impressionsMode = (0, lang_1.stringToUpperCase)(impressionsMode);
|
|
9
9
|
if ([constants_2.DEBUG, constants_2.OPTIMIZED].indexOf(impressionsMode) > -1)
|
|
10
10
|
return impressionsMode;
|
|
11
11
|
log.error(constants_1.ERROR_INVALID_CONFIG_PARAM, ['impressionsMode', [constants_2.DEBUG, constants_2.OPTIMIZED], constants_2.OPTIMIZED]);
|
package/esm/logger/constants.js
CHANGED
|
@@ -68,6 +68,7 @@ export var SYNC_STOP_POLLING = 119;
|
|
|
68
68
|
export var EVENTS_TRACKER_SUCCESS = 120;
|
|
69
69
|
export var IMPRESSIONS_TRACKER_SUCCESS = 121;
|
|
70
70
|
export var USER_CONSENT_UPDATED = 122;
|
|
71
|
+
export var USER_CONSENT_NOT_UPDATED = 123;
|
|
71
72
|
export var ENGINE_VALUE_INVALID = 200;
|
|
72
73
|
export var ENGINE_VALUE_NO_ATTRIBUTES = 201;
|
|
73
74
|
export var CLIENT_NO_LISTENER = 202;
|
|
@@ -30,9 +30,9 @@ export var codesDebug = codesInfo.concat([
|
|
|
30
30
|
// SDK
|
|
31
31
|
[c.CLEANUP_REGISTERING, c.LOG_PREFIX_CLEANUP + 'Registering cleanup handler %s'],
|
|
32
32
|
[c.CLEANUP_DEREGISTERING, c.LOG_PREFIX_CLEANUP + 'Deregistering cleanup handler %s'],
|
|
33
|
-
[c.RETRIEVE_CLIENT_DEFAULT, '
|
|
34
|
-
[c.RETRIEVE_CLIENT_EXISTING, '
|
|
35
|
-
[c.RETRIEVE_MANAGER, '
|
|
33
|
+
[c.RETRIEVE_CLIENT_DEFAULT, 'Retrieving default SDK client.'],
|
|
34
|
+
[c.RETRIEVE_CLIENT_EXISTING, 'Retrieving existing SDK client.'],
|
|
35
|
+
[c.RETRIEVE_MANAGER, 'Retrieving manager instance.'],
|
|
36
36
|
// synchronizer
|
|
37
37
|
[c.SYNC_OFFLINE_DATA, c.LOG_PREFIX_SYNC_OFFLINE + 'Splits data: \n%s'],
|
|
38
38
|
[c.SYNC_SPLITS_FETCH, c.LOG_PREFIX_SYNC_SPLITS + 'Spin up split update using since = %s'],
|
|
@@ -4,7 +4,7 @@ export var codesError = [
|
|
|
4
4
|
[c.ERROR_ENGINE_COMBINER_IFELSEIF, c.LOG_PREFIX_ENGINE_COMBINER + 'Invalid Split, no valid rules found'],
|
|
5
5
|
// SDK
|
|
6
6
|
[c.ERROR_LOGLEVEL_INVALID, 'logger: Invalid Log Level - No changes to the logs will be applied.'],
|
|
7
|
-
[c.ERROR_CLIENT_CANNOT_GET_READY, '
|
|
7
|
+
[c.ERROR_CLIENT_CANNOT_GET_READY, 'The SDK will not get ready. Reason: %s'],
|
|
8
8
|
[c.ERROR_IMPRESSIONS_TRACKER, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Could not store impressions bulk with %s impression(s). Error: %s'],
|
|
9
9
|
[c.ERROR_IMPRESSIONS_LISTENER, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Impression listener logImpression method threw: %s.'],
|
|
10
10
|
[c.ERROR_EVENTS_TRACKER, c.LOG_PREFIX_EVENTS_TRACKER + 'Failed to queue %s'],
|
|
@@ -27,7 +27,7 @@ export var codesError = [
|
|
|
27
27
|
[c.ERROR_INVALID, '%s: you passed an invalid %s. It must be a non-empty string.'],
|
|
28
28
|
[c.ERROR_EMPTY, '%s: you passed an empty %s. It must be a non-empty string.'],
|
|
29
29
|
[c.ERROR_EMPTY_ARRAY, '%s: %s must be a non-empty array.'],
|
|
30
|
-
[c.ERROR_NOT_BOOLEAN, '%s:
|
|
30
|
+
[c.ERROR_NOT_BOOLEAN, '%s: provided param must be a boolean value.'],
|
|
31
31
|
// initialization / settings validation
|
|
32
32
|
[c.ERROR_INVALID_CONFIG_PARAM, c.LOG_PREFIX_SETTINGS + ': you passed an invalid "%s" config param. It should be one of the following values: %s. Defaulting to "%s".'],
|
|
33
33
|
[c.ERROR_LOCALHOST_MODULE_REQUIRED, c.LOG_PREFIX_SETTINGS + ': an invalid value was received for "sync.localhostMode" config. A valid entity should be provided for localhost mode.'],
|
|
@@ -8,11 +8,12 @@ export var codesInfo = codesWarn.concat([
|
|
|
8
8
|
// SDK
|
|
9
9
|
[c.IMPRESSION, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Split: %s. Key: %s. Evaluation: %s. Label: %s'],
|
|
10
10
|
[c.IMPRESSION_QUEUEING, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Queueing corresponding impression.'],
|
|
11
|
-
[c.NEW_SHARED_CLIENT, '
|
|
12
|
-
[c.NEW_FACTORY, '
|
|
11
|
+
[c.NEW_SHARED_CLIENT, 'New shared client instance created.'],
|
|
12
|
+
[c.NEW_FACTORY, 'New Split SDK instance created.'],
|
|
13
13
|
[c.EVENTS_TRACKER_SUCCESS, c.LOG_PREFIX_EVENTS_TRACKER + 'Successfully queued %s'],
|
|
14
14
|
[c.IMPRESSIONS_TRACKER_SUCCESS, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Successfully stored %s impression(s).'],
|
|
15
|
-
[c.USER_CONSENT_UPDATED, '
|
|
15
|
+
[c.USER_CONSENT_UPDATED, 'setUserConsent: consent status changed from %s to %s.'],
|
|
16
|
+
[c.USER_CONSENT_NOT_UPDATED, 'setUserConsent: call had no effect because it was the current consent status (%s).'],
|
|
16
17
|
// synchronizer
|
|
17
18
|
[c.POLLING_SMART_PAUSING, c.LOG_PREFIX_SYNC_POLLING + 'Turning segments data polling %s.'],
|
|
18
19
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { ERROR_NOT_BOOLEAN, USER_CONSENT_UPDATED } from '../logger/constants';
|
|
1
|
+
import { ERROR_NOT_BOOLEAN, USER_CONSENT_UPDATED, USER_CONSENT_NOT_UPDATED } from '../logger/constants';
|
|
2
2
|
import { CONSENT_GRANTED, CONSENT_DECLINED } from '../utils/constants';
|
|
3
|
+
import { isBoolean } from '../utils/lang';
|
|
3
4
|
// Extend client-side factory instances with user consent getter/setter
|
|
4
5
|
export function userConsentProps(settings, syncManager) {
|
|
5
6
|
var log = settings.log;
|
|
@@ -7,19 +8,21 @@ export function userConsentProps(settings, syncManager) {
|
|
|
7
8
|
setUserConsent: function (consent) {
|
|
8
9
|
var _a, _b;
|
|
9
10
|
// validate input param
|
|
10
|
-
if (
|
|
11
|
-
log.
|
|
11
|
+
if (!isBoolean(consent)) {
|
|
12
|
+
log.warn(ERROR_NOT_BOOLEAN, ['setUserConsent']);
|
|
12
13
|
return false;
|
|
13
14
|
}
|
|
14
15
|
var newConsentStatus = consent ? CONSENT_GRANTED : CONSENT_DECLINED;
|
|
15
|
-
if (settings.userConsent !== newConsentStatus) {
|
|
16
|
-
|
|
16
|
+
if (settings.userConsent !== newConsentStatus) { // @ts-ignore, modify readonly prop
|
|
17
|
+
settings.userConsent = newConsentStatus;
|
|
17
18
|
if (consent)
|
|
18
|
-
(_a = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _a === void 0 ? void 0 : _a.start();
|
|
19
|
+
(_a = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _a === void 0 ? void 0 : _a.start(); // resumes submitters if transitioning to GRANTED
|
|
19
20
|
else
|
|
20
|
-
(_b = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _b === void 0 ? void 0 : _b.stop();
|
|
21
|
-
log.info(USER_CONSENT_UPDATED, [settings.userConsent, newConsentStatus]);
|
|
22
|
-
|
|
21
|
+
(_b = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _b === void 0 ? void 0 : _b.stop(); // pauses submitters if transitioning to DECLINED
|
|
22
|
+
log.info(USER_CONSENT_UPDATED, [settings.userConsent, newConsentStatus]);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
log.info(USER_CONSENT_NOT_UPDATED, [newConsentStatus]);
|
|
23
26
|
}
|
|
24
27
|
return true;
|
|
25
28
|
},
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { startsWith } from '../utils/lang';
|
|
2
2
|
var everythingAtTheEnd = /[^.]+$/;
|
|
3
3
|
var DEFAULT_PREFIX = 'SPLITIO';
|
|
4
4
|
export function validatePrefix(prefix) {
|
|
5
|
-
return prefix
|
|
6
|
-
endsWith(prefix, '.' + DEFAULT_PREFIX) ?
|
|
7
|
-
prefix : // suffix already appended
|
|
8
|
-
prefix + '.' + DEFAULT_PREFIX : // append suffix
|
|
9
|
-
DEFAULT_PREFIX; // use default prefix if none is provided
|
|
5
|
+
return prefix ? prefix + '.SPLITIO' : 'SPLITIO';
|
|
10
6
|
}
|
|
11
7
|
var KeyBuilder = /** @class */ (function () {
|
|
12
8
|
function KeyBuilder(prefix) {
|
|
@@ -7,18 +7,25 @@ var DATA_NAME = 'events';
|
|
|
7
7
|
export function eventsSyncTaskFactory(log, postEventsBulk, eventsCache, eventsPushRate, eventsFirstPushWindow, latencyTracker) {
|
|
8
8
|
// don't retry events.
|
|
9
9
|
var syncTask = submitterSyncTaskFactory(log, postEventsBulk, eventsCache, eventsPushRate, DATA_NAME, latencyTracker);
|
|
10
|
-
// Set a timer for the first push of events
|
|
10
|
+
// Set a timer for the first push window of events.
|
|
11
|
+
// Not implemented in the base submitter or sync task, since this feature is only used by the events submitter.
|
|
11
12
|
if (eventsFirstPushWindow > 0) {
|
|
13
|
+
var running_1 = false;
|
|
12
14
|
var stopEventPublisherTimeout_1;
|
|
13
15
|
var originalStart_1 = syncTask.start;
|
|
14
16
|
syncTask.start = function () {
|
|
17
|
+
running_1 = true;
|
|
15
18
|
stopEventPublisherTimeout_1 = setTimeout(originalStart_1, eventsFirstPushWindow);
|
|
16
19
|
};
|
|
17
20
|
var originalStop_1 = syncTask.stop;
|
|
18
21
|
syncTask.stop = function () {
|
|
22
|
+
running_1 = false;
|
|
19
23
|
clearTimeout(stopEventPublisherTimeout_1);
|
|
20
24
|
originalStop_1();
|
|
21
25
|
};
|
|
26
|
+
syncTask.isRunning = function () {
|
|
27
|
+
return running_1;
|
|
28
|
+
};
|
|
22
29
|
}
|
|
23
30
|
// register events submitter to be executed when events cache is full
|
|
24
31
|
eventsCache.setOnFullQueueCb(function () {
|
package/esm/utils/lang/index.js
CHANGED
|
@@ -152,6 +152,12 @@ export function isObject(obj) {
|
|
|
152
152
|
export function isString(val) {
|
|
153
153
|
return typeof val === 'string' || val instanceof String;
|
|
154
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* String sanitizer. Returns the provided value converted to uppercase if it is a string.
|
|
157
|
+
*/
|
|
158
|
+
export function stringToUpperCase(val) {
|
|
159
|
+
return isString(val) ? val.toUpperCase() : val;
|
|
160
|
+
}
|
|
155
161
|
/**
|
|
156
162
|
* Deep copy version of Object.assign using recursion.
|
|
157
163
|
* There are some assumptions here. It's for internal use and we don't need verbose errors
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ERROR_INVALID_CONFIG_PARAM } from '../../logger/constants';
|
|
2
2
|
import { CONSENT_DECLINED, CONSENT_GRANTED, CONSENT_UNKNOWN } from '../constants';
|
|
3
|
+
import { stringToUpperCase } from '../lang';
|
|
3
4
|
var userConsentValues = [CONSENT_DECLINED, CONSENT_GRANTED, CONSENT_UNKNOWN];
|
|
4
5
|
export function validateConsent(_a) {
|
|
5
6
|
var userConsent = _a.userConsent, log = _a.log;
|
|
6
|
-
|
|
7
|
-
userConsent = userConsent.toUpperCase();
|
|
7
|
+
userConsent = stringToUpperCase(userConsent);
|
|
8
8
|
if (userConsentValues.indexOf(userConsent) > -1)
|
|
9
9
|
return userConsent;
|
|
10
10
|
log.error(ERROR_INVALID_CONFIG_PARAM, ['userConsent', userConsentValues, CONSENT_GRANTED]);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ERROR_INVALID_CONFIG_PARAM } from '../../logger/constants';
|
|
2
2
|
import { DEBUG, OPTIMIZED } from '../constants';
|
|
3
|
+
import { stringToUpperCase } from '../lang';
|
|
3
4
|
export function validImpressionsMode(log, impressionsMode) {
|
|
4
|
-
|
|
5
|
-
impressionsMode = impressionsMode.toUpperCase();
|
|
5
|
+
impressionsMode = stringToUpperCase(impressionsMode);
|
|
6
6
|
if ([DEBUG, OPTIMIZED].indexOf(impressionsMode) > -1)
|
|
7
7
|
return impressionsMode;
|
|
8
8
|
log.error(ERROR_INVALID_CONFIG_PARAM, ['impressionsMode', [DEBUG, OPTIMIZED], OPTIMIZED]);
|
package/package.json
CHANGED
package/src/logger/constants.ts
CHANGED
|
@@ -69,6 +69,7 @@ export const SYNC_STOP_POLLING = 119;
|
|
|
69
69
|
export const EVENTS_TRACKER_SUCCESS = 120;
|
|
70
70
|
export const IMPRESSIONS_TRACKER_SUCCESS = 121;
|
|
71
71
|
export const USER_CONSENT_UPDATED = 122;
|
|
72
|
+
export const USER_CONSENT_NOT_UPDATED = 123;
|
|
72
73
|
|
|
73
74
|
export const ENGINE_VALUE_INVALID = 200;
|
|
74
75
|
export const ENGINE_VALUE_NO_ATTRIBUTES = 201;
|
|
@@ -31,9 +31,9 @@ export const codesDebug: [number, string][] = codesInfo.concat([
|
|
|
31
31
|
// SDK
|
|
32
32
|
[c.CLEANUP_REGISTERING, c.LOG_PREFIX_CLEANUP + 'Registering cleanup handler %s'],
|
|
33
33
|
[c.CLEANUP_DEREGISTERING, c.LOG_PREFIX_CLEANUP + 'Deregistering cleanup handler %s'],
|
|
34
|
-
[c.RETRIEVE_CLIENT_DEFAULT, '
|
|
35
|
-
[c.RETRIEVE_CLIENT_EXISTING, '
|
|
36
|
-
[c.RETRIEVE_MANAGER, '
|
|
34
|
+
[c.RETRIEVE_CLIENT_DEFAULT, 'Retrieving default SDK client.'],
|
|
35
|
+
[c.RETRIEVE_CLIENT_EXISTING, 'Retrieving existing SDK client.'],
|
|
36
|
+
[c.RETRIEVE_MANAGER, 'Retrieving manager instance.'],
|
|
37
37
|
// synchronizer
|
|
38
38
|
[c.SYNC_OFFLINE_DATA, c.LOG_PREFIX_SYNC_OFFLINE + 'Splits data: \n%s'],
|
|
39
39
|
[c.SYNC_SPLITS_FETCH, c.LOG_PREFIX_SYNC_SPLITS + 'Spin up split update using since = %s'],
|
|
@@ -5,7 +5,7 @@ export const codesError: [number, string][] = [
|
|
|
5
5
|
[c.ERROR_ENGINE_COMBINER_IFELSEIF, c.LOG_PREFIX_ENGINE_COMBINER + 'Invalid Split, no valid rules found'],
|
|
6
6
|
// SDK
|
|
7
7
|
[c.ERROR_LOGLEVEL_INVALID, 'logger: Invalid Log Level - No changes to the logs will be applied.'],
|
|
8
|
-
[c.ERROR_CLIENT_CANNOT_GET_READY, '
|
|
8
|
+
[c.ERROR_CLIENT_CANNOT_GET_READY, 'The SDK will not get ready. Reason: %s'],
|
|
9
9
|
[c.ERROR_IMPRESSIONS_TRACKER, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Could not store impressions bulk with %s impression(s). Error: %s'],
|
|
10
10
|
[c.ERROR_IMPRESSIONS_LISTENER, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Impression listener logImpression method threw: %s.'],
|
|
11
11
|
[c.ERROR_EVENTS_TRACKER, c.LOG_PREFIX_EVENTS_TRACKER + 'Failed to queue %s'],
|
|
@@ -28,7 +28,7 @@ export const codesError: [number, string][] = [
|
|
|
28
28
|
[c.ERROR_INVALID, '%s: you passed an invalid %s. It must be a non-empty string.'],
|
|
29
29
|
[c.ERROR_EMPTY, '%s: you passed an empty %s. It must be a non-empty string.'],
|
|
30
30
|
[c.ERROR_EMPTY_ARRAY, '%s: %s must be a non-empty array.'],
|
|
31
|
-
[c.ERROR_NOT_BOOLEAN, '%s:
|
|
31
|
+
[c.ERROR_NOT_BOOLEAN, '%s: provided param must be a boolean value.'],
|
|
32
32
|
// initialization / settings validation
|
|
33
33
|
[c.ERROR_INVALID_CONFIG_PARAM, c.LOG_PREFIX_SETTINGS + ': you passed an invalid "%s" config param. It should be one of the following values: %s. Defaulting to "%s".'],
|
|
34
34
|
[c.ERROR_LOCALHOST_MODULE_REQUIRED, c.LOG_PREFIX_SETTINGS + ': an invalid value was received for "sync.localhostMode" config. A valid entity should be provided for localhost mode.'],
|
|
@@ -10,11 +10,12 @@ export const codesInfo: [number, string][] = codesWarn.concat([
|
|
|
10
10
|
// SDK
|
|
11
11
|
[c.IMPRESSION, c.LOG_PREFIX_IMPRESSIONS_TRACKER +'Split: %s. Key: %s. Evaluation: %s. Label: %s'],
|
|
12
12
|
[c.IMPRESSION_QUEUEING, c.LOG_PREFIX_IMPRESSIONS_TRACKER +'Queueing corresponding impression.'],
|
|
13
|
-
[c.NEW_SHARED_CLIENT, '
|
|
14
|
-
[c.NEW_FACTORY, '
|
|
13
|
+
[c.NEW_SHARED_CLIENT, 'New shared client instance created.'],
|
|
14
|
+
[c.NEW_FACTORY, 'New Split SDK instance created.'],
|
|
15
15
|
[c.EVENTS_TRACKER_SUCCESS, c.LOG_PREFIX_EVENTS_TRACKER + 'Successfully queued %s'],
|
|
16
16
|
[c.IMPRESSIONS_TRACKER_SUCCESS, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Successfully stored %s impression(s).'],
|
|
17
|
-
[c.USER_CONSENT_UPDATED, '
|
|
17
|
+
[c.USER_CONSENT_UPDATED, 'setUserConsent: consent status changed from %s to %s.'],
|
|
18
|
+
[c.USER_CONSENT_NOT_UPDATED, 'setUserConsent: call had no effect because it was the current consent status (%s).'],
|
|
18
19
|
|
|
19
20
|
// synchronizer
|
|
20
21
|
[c.POLLING_SMART_PAUSING, c.LOG_PREFIX_SYNC_POLLING + 'Turning segments data polling %s.'],
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { ERROR_NOT_BOOLEAN, USER_CONSENT_UPDATED } from '../logger/constants';
|
|
1
|
+
import { ERROR_NOT_BOOLEAN, USER_CONSENT_UPDATED, USER_CONSENT_NOT_UPDATED } from '../logger/constants';
|
|
2
2
|
import { ISyncManager } from '../sync/types';
|
|
3
3
|
import { ISettings } from '../types';
|
|
4
4
|
import { CONSENT_GRANTED, CONSENT_DECLINED } from '../utils/constants';
|
|
5
|
+
import { isBoolean } from '../utils/lang';
|
|
5
6
|
|
|
6
7
|
// Extend client-side factory instances with user consent getter/setter
|
|
7
8
|
export function userConsentProps(settings: ISettings, syncManager?: ISyncManager) {
|
|
@@ -11,20 +12,22 @@ export function userConsentProps(settings: ISettings, syncManager?: ISyncManager
|
|
|
11
12
|
return {
|
|
12
13
|
setUserConsent(consent: unknown) {
|
|
13
14
|
// validate input param
|
|
14
|
-
if (
|
|
15
|
-
log.
|
|
15
|
+
if (!isBoolean(consent)) {
|
|
16
|
+
log.warn(ERROR_NOT_BOOLEAN, ['setUserConsent']);
|
|
16
17
|
return false;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
const newConsentStatus = consent ? CONSENT_GRANTED : CONSENT_DECLINED;
|
|
20
21
|
|
|
21
|
-
if (settings.userConsent !== newConsentStatus) {
|
|
22
|
-
// resume/pause submitters
|
|
23
|
-
if (consent) syncManager?.submitter?.start();
|
|
24
|
-
else syncManager?.submitter?.stop();
|
|
25
|
-
|
|
26
|
-
log.info(USER_CONSENT_UPDATED, [settings.userConsent, newConsentStatus]); // @ts-ignore, modify readonly prop
|
|
22
|
+
if (settings.userConsent !== newConsentStatus) { // @ts-ignore, modify readonly prop
|
|
27
23
|
settings.userConsent = newConsentStatus;
|
|
24
|
+
|
|
25
|
+
if (consent) syncManager?.submitter?.start(); // resumes submitters if transitioning to GRANTED
|
|
26
|
+
else syncManager?.submitter?.stop(); // pauses submitters if transitioning to DECLINED
|
|
27
|
+
|
|
28
|
+
log.info(USER_CONSENT_UPDATED, [settings.userConsent, newConsentStatus]);
|
|
29
|
+
} else {
|
|
30
|
+
log.info(USER_CONSENT_NOT_UPDATED, [newConsentStatus]);
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
return true;
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { startsWith } from '../utils/lang';
|
|
2
2
|
|
|
3
3
|
const everythingAtTheEnd = /[^.]+$/;
|
|
4
4
|
|
|
5
5
|
const DEFAULT_PREFIX = 'SPLITIO';
|
|
6
6
|
|
|
7
7
|
export function validatePrefix(prefix: unknown) {
|
|
8
|
-
return prefix
|
|
9
|
-
endsWith(prefix, '.' + DEFAULT_PREFIX) ?
|
|
10
|
-
prefix : // suffix already appended
|
|
11
|
-
prefix + '.' + DEFAULT_PREFIX : // append suffix
|
|
12
|
-
DEFAULT_PREFIX; // use default prefix if none is provided
|
|
8
|
+
return prefix ? prefix + '.SPLITIO' : 'SPLITIO';
|
|
13
9
|
}
|
|
14
10
|
|
|
15
11
|
export class KeyBuilder {
|
|
@@ -22,18 +22,25 @@ export function eventsSyncTaskFactory(
|
|
|
22
22
|
// don't retry events.
|
|
23
23
|
const syncTask = submitterSyncTaskFactory(log, postEventsBulk, eventsCache, eventsPushRate, DATA_NAME, latencyTracker);
|
|
24
24
|
|
|
25
|
-
// Set a timer for the first push of events
|
|
25
|
+
// Set a timer for the first push window of events.
|
|
26
|
+
// Not implemented in the base submitter or sync task, since this feature is only used by the events submitter.
|
|
26
27
|
if (eventsFirstPushWindow > 0) {
|
|
28
|
+
let running = false;
|
|
27
29
|
let stopEventPublisherTimeout: ReturnType<typeof setTimeout>;
|
|
28
30
|
const originalStart = syncTask.start;
|
|
29
31
|
syncTask.start = () => {
|
|
32
|
+
running = true;
|
|
30
33
|
stopEventPublisherTimeout = setTimeout(originalStart, eventsFirstPushWindow);
|
|
31
34
|
};
|
|
32
35
|
const originalStop = syncTask.stop;
|
|
33
36
|
syncTask.stop = () => {
|
|
37
|
+
running = false;
|
|
34
38
|
clearTimeout(stopEventPublisherTimeout);
|
|
35
39
|
originalStop();
|
|
36
40
|
};
|
|
41
|
+
syncTask.isRunning = () => {
|
|
42
|
+
return running;
|
|
43
|
+
};
|
|
37
44
|
}
|
|
38
45
|
|
|
39
46
|
// register events submitter to be executed when events cache is full
|
package/src/utils/lang/index.ts
CHANGED
|
@@ -89,7 +89,7 @@ export function get(obj: any, prop: any, val: any): any {
|
|
|
89
89
|
/**
|
|
90
90
|
* Parses an array into a map of different arrays, grouping by the specified prop value.
|
|
91
91
|
*/
|
|
92
|
-
export function groupBy<T extends Record<string, any
|
|
92
|
+
export function groupBy<T extends Record<string, any>>(source: T[], prop: string): Record<string, T[]> {
|
|
93
93
|
const map: Record<string, any[]> = {};
|
|
94
94
|
|
|
95
95
|
if (Array.isArray(source) && isString(prop)) {
|
|
@@ -164,6 +164,13 @@ export function isString(val: any): val is string {
|
|
|
164
164
|
return typeof val === 'string' || val instanceof String;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
/**
|
|
168
|
+
* String sanitizer. Returns the provided value converted to uppercase if it is a string.
|
|
169
|
+
*/
|
|
170
|
+
export function stringToUpperCase(val: any) {
|
|
171
|
+
return isString(val) ? val.toUpperCase() : val;
|
|
172
|
+
}
|
|
173
|
+
|
|
167
174
|
/**
|
|
168
175
|
* Deep copy version of Object.assign using recursion.
|
|
169
176
|
* There are some assumptions here. It's for internal use and we don't need verbose errors
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { ERROR_INVALID_CONFIG_PARAM } from '../../logger/constants';
|
|
2
2
|
import { ILogger } from '../../logger/types';
|
|
3
3
|
import { CONSENT_DECLINED, CONSENT_GRANTED, CONSENT_UNKNOWN } from '../constants';
|
|
4
|
+
import { stringToUpperCase } from '../lang';
|
|
4
5
|
|
|
5
6
|
const userConsentValues = [CONSENT_DECLINED, CONSENT_GRANTED, CONSENT_UNKNOWN];
|
|
6
7
|
|
|
7
8
|
export function validateConsent({ userConsent, log }: { userConsent: any, log: ILogger }) {
|
|
8
|
-
|
|
9
|
+
userConsent = stringToUpperCase(userConsent);
|
|
9
10
|
|
|
10
11
|
if (userConsentValues.indexOf(userConsent) > -1) return userConsent;
|
|
11
12
|
|
|
@@ -2,9 +2,10 @@ import { ERROR_INVALID_CONFIG_PARAM } from '../../logger/constants';
|
|
|
2
2
|
import { ILogger } from '../../logger/types';
|
|
3
3
|
import { SplitIO } from '../../types';
|
|
4
4
|
import { DEBUG, OPTIMIZED } from '../constants';
|
|
5
|
+
import { stringToUpperCase } from '../lang';
|
|
5
6
|
|
|
6
7
|
export function validImpressionsMode(log: ILogger, impressionsMode: any): SplitIO.ImpressionsMode {
|
|
7
|
-
|
|
8
|
+
impressionsMode = stringToUpperCase(impressionsMode);
|
|
8
9
|
|
|
9
10
|
if ([DEBUG, OPTIMIZED].indexOf(impressionsMode) > -1) return impressionsMode;
|
|
10
11
|
|
|
@@ -68,6 +68,7 @@ export declare const SYNC_STOP_POLLING = 119;
|
|
|
68
68
|
export declare const EVENTS_TRACKER_SUCCESS = 120;
|
|
69
69
|
export declare const IMPRESSIONS_TRACKER_SUCCESS = 121;
|
|
70
70
|
export declare const USER_CONSENT_UPDATED = 122;
|
|
71
|
+
export declare const USER_CONSENT_NOT_UPDATED = 123;
|
|
71
72
|
export declare const ENGINE_VALUE_INVALID = 200;
|
|
72
73
|
export declare const ENGINE_VALUE_NO_ATTRIBUTES = 201;
|
|
73
74
|
export declare const CLIENT_NO_LISTENER = 202;
|
|
@@ -62,6 +62,10 @@ export declare function isObject(obj: any): boolean;
|
|
|
62
62
|
* Checks if a given value is a string.
|
|
63
63
|
*/
|
|
64
64
|
export declare function isString(val: any): val is string;
|
|
65
|
+
/**
|
|
66
|
+
* String sanitizer. Returns the provided value converted to uppercase if it is a string.
|
|
67
|
+
*/
|
|
68
|
+
export declare function stringToUpperCase(val: any): any;
|
|
65
69
|
/**
|
|
66
70
|
* Deep copy version of Object.assign using recursion.
|
|
67
71
|
* There are some assumptions here. It's for internal use and we don't need verbose errors
|