@splitsoftware/splitio-commons 1.2.1-rc.9 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.txt +14 -0
- package/cjs/{utils/consent.js → consent/index.js} +1 -1
- package/cjs/consent/sdkUserConsent.js +58 -0
- package/cjs/listeners/browser.js +1 -1
- package/cjs/logger/constants.js +3 -2
- package/cjs/logger/messages/info.js +1 -0
- package/cjs/sdkClient/sdkClient.js +3 -3
- package/cjs/sdkClient/sdkClientMethodCS.js +3 -5
- package/cjs/sdkClient/sdkClientMethodCSWithTT.js +3 -5
- package/cjs/sdkFactory/index.js +3 -2
- package/cjs/sync/syncManagerOnline.js +1 -1
- package/cjs/utils/inputValidation/attributes.js +1 -1
- package/cjs/utils/lang/index.js +4 -2
- package/cjs/utils/settingsValidation/index.js +8 -6
- package/esm/{utils/consent.js → consent/index.js} +1 -1
- package/esm/consent/sdkUserConsent.js +54 -0
- package/esm/listeners/browser.js +1 -1
- package/esm/logger/constants.js +1 -0
- package/esm/logger/messages/info.js +1 -0
- package/esm/sdkClient/sdkClient.js +3 -3
- package/esm/sdkClient/sdkClientMethodCS.js +3 -5
- package/esm/sdkClient/sdkClientMethodCSWithTT.js +3 -5
- package/esm/sdkFactory/index.js +3 -2
- package/esm/sync/syncManagerOnline.js +1 -1
- package/esm/utils/inputValidation/attributes.js +1 -1
- package/esm/utils/lang/index.js +4 -2
- package/esm/utils/settingsValidation/index.js +8 -6
- package/package.json +1 -1
- package/src/{utils/consent.ts → consent/index.ts} +1 -1
- package/src/consent/sdkUserConsent.ts +58 -0
- package/src/evaluator/parser/index.ts +1 -1
- package/src/evaluator/types.ts +2 -2
- package/src/evaluator/value/index.ts +2 -2
- package/src/evaluator/value/sanitize.ts +2 -2
- package/src/listeners/browser.ts +1 -1
- package/src/logger/constants.ts +1 -0
- package/src/logger/messages/info.ts +1 -0
- package/src/sdkClient/client.ts +2 -3
- package/src/sdkClient/sdkClient.ts +4 -4
- package/src/sdkClient/sdkClientMethod.ts +2 -2
- package/src/sdkClient/sdkClientMethodCS.ts +4 -5
- package/src/sdkClient/sdkClientMethodCSWithTT.ts +4 -5
- package/src/sdkFactory/index.ts +3 -2
- package/src/sdkFactory/types.ts +13 -3
- package/src/sync/syncManagerOnline.ts +1 -1
- package/src/utils/inputValidation/attributes.ts +1 -2
- package/src/utils/lang/index.ts +7 -3
- package/src/utils/settingsValidation/index.ts +8 -6
- package/src/utils/settingsValidation/types.ts +4 -2
- package/types/consent/index.d.ts +2 -0
- package/types/consent/sdkUserConsent.d.ts +13 -0
- package/types/evaluator/types.d.ts +2 -2
- package/types/evaluator/value/index.d.ts +1 -1
- package/types/evaluator/value/sanitize.d.ts +1 -1
- package/types/logger/constants.d.ts +1 -0
- package/types/sdkClient/client.d.ts +2 -2
- package/types/sdkClient/sdkClient.d.ts +2 -2
- package/types/sdkClient/sdkClientMethod.d.ts +2 -2
- package/types/sdkClient/sdkClientMethodCS.d.ts +2 -2
- package/types/sdkClient/sdkClientMethodCSWithTT.d.ts +2 -2
- package/types/sdkFactory/types.d.ts +12 -3
- package/types/utils/lang/index.d.ts +2 -1
- package/types/utils/settingsValidation/types.d.ts +4 -2
- package/cjs/sdkClient/types.js +0 -2
- package/cjs/sdkFactory/userConsentProps.js +0 -37
- package/esm/sdkClient/types.js +0 -1
- package/esm/sdkFactory/userConsentProps.js +0 -33
- package/src/sdkClient/types.ts +0 -21
- package/src/sdkFactory/userConsentProps.ts +0 -40
package/CHANGES.txt
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
1.3.0 (April 6, 2022)
|
|
2
|
+
- Added user consent feature to allow delaying or disabling the data tracking from SDK until user consent is explicitly granted or declined. Read more in our docs.
|
|
3
|
+
- Added `scheduler.impressionsQueueSize` property to SDK configuration to limit the amount of impressions tracked in memory. Read more in our docs.
|
|
4
|
+
- Added support to accept TLS configuration options to the Redis storage in NodeJS. Read more in our docs.
|
|
5
|
+
- Updated format for MySegments keys in LocalStorage, keeping backwards compatibility (issue https://github.com/splitio/javascript-client/issues/638).
|
|
6
|
+
- Updated some modules due to general polishing and refactors, including updates in some log messages.
|
|
7
|
+
- Updated some dependencies for vulnerability fixes.
|
|
8
|
+
- Bugfixing - Updated internal isObject utility function, to avoid unexpected behaviors on frameworks and libraries that uses multiple VM contexts, like NuxtJS dev server.
|
|
9
|
+
- Bugfixing - Fixed validation of `core.key` SDK configuration param, to parse it into a string and log a warning when passing a number (Related to issue https://github.com/splitio/react-native-client/issues/19).
|
|
10
|
+
- Bugfixing - Fixed validation of `sync.impressionsMode` SDK configuration param, to avoid an exception on SplitFactory instantiation when passing a non-string value.
|
|
11
|
+
- Bugfixing - Fixed an issue with `connectionTimeout` options params of Redis storage, that was being ignored and not passed down to the underlying ioredis client.
|
|
12
|
+
- Bugfixing - Fixed streaming synchronization issue with multiple clients.
|
|
13
|
+
- Bugfixing - Fixed issue with internal Map ponyfill that results in logger not working properly on IE11 browser.
|
|
14
|
+
|
|
1
15
|
1.2.0 (January 19, 2022)
|
|
2
16
|
- Added support to SDK clients on browser to optionally bind attributes to the client, keeping these loaded within the SDK along with the user ID, for easier usage when requesting flag.
|
|
3
17
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isConsentGranted = void 0;
|
|
4
|
-
var constants_1 = require("
|
|
4
|
+
var constants_1 = require("../utils/constants");
|
|
5
5
|
function isConsentGranted(settings) {
|
|
6
6
|
var userConsent = settings.userConsent;
|
|
7
7
|
// undefined userConsent is handled as granted (default)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createUserConsentAPI = void 0;
|
|
4
|
+
var constants_1 = require("../logger/constants");
|
|
5
|
+
var index_1 = require("./index");
|
|
6
|
+
var constants_2 = require("../utils/constants");
|
|
7
|
+
var lang_1 = require("../utils/lang");
|
|
8
|
+
// User consent enum
|
|
9
|
+
var ConsentStatus = {
|
|
10
|
+
GRANTED: constants_2.CONSENT_GRANTED,
|
|
11
|
+
DECLINED: constants_2.CONSENT_DECLINED,
|
|
12
|
+
UNKNOWN: constants_2.CONSENT_UNKNOWN,
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* The public user consent API exposed via SplitFactory, used to control if the SDK tracks and sends impressions and events or not.
|
|
16
|
+
*/
|
|
17
|
+
function createUserConsentAPI(params) {
|
|
18
|
+
var settings = params.settings, log = params.settings.log, syncManager = params.syncManager, _a = params.storage, events = _a.events, impressions = _a.impressions, impressionCounts = _a.impressionCounts;
|
|
19
|
+
if (!(0, index_1.isConsentGranted)(settings))
|
|
20
|
+
log.info(constants_1.USER_CONSENT_INITIAL, [settings.userConsent]);
|
|
21
|
+
return {
|
|
22
|
+
setStatus: function (consent) {
|
|
23
|
+
var _a, _b;
|
|
24
|
+
// validate input param
|
|
25
|
+
if (!(0, lang_1.isBoolean)(consent)) {
|
|
26
|
+
log.warn(constants_1.ERROR_NOT_BOOLEAN, ['setUserConsent']);
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
var newConsentStatus = consent ? constants_2.CONSENT_GRANTED : constants_2.CONSENT_DECLINED;
|
|
30
|
+
if (settings.userConsent !== newConsentStatus) {
|
|
31
|
+
log.info(constants_1.USER_CONSENT_UPDATED, [settings.userConsent, newConsentStatus]); // @ts-ignore, modify readonly prop
|
|
32
|
+
settings.userConsent = newConsentStatus;
|
|
33
|
+
if (consent) { // resumes submitters if transitioning to GRANTED
|
|
34
|
+
(_a = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _a === void 0 ? void 0 : _a.start();
|
|
35
|
+
}
|
|
36
|
+
else { // pauses submitters and drops tracked data if transitioning to DECLINED
|
|
37
|
+
(_b = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _b === void 0 ? void 0 : _b.stop();
|
|
38
|
+
// @ts-ignore, clear method is present in storage for standalone and partial consumer mode
|
|
39
|
+
if (events.clear)
|
|
40
|
+
events.clear(); // @ts-ignore
|
|
41
|
+
if (impressions.clear)
|
|
42
|
+
impressions.clear();
|
|
43
|
+
if (impressionCounts)
|
|
44
|
+
impressionCounts.clear();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
log.info(constants_1.USER_CONSENT_NOT_UPDATED, [newConsentStatus]);
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
},
|
|
52
|
+
getStatus: function () {
|
|
53
|
+
return settings.userConsent;
|
|
54
|
+
},
|
|
55
|
+
Status: ConsentStatus
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
exports.createUserConsentAPI = createUserConsentAPI;
|
package/cjs/listeners/browser.js
CHANGED
|
@@ -6,7 +6,7 @@ var impressionCountsSyncTask_1 = require("../sync/submitters/impressionCountsSyn
|
|
|
6
6
|
var constants_1 = require("../utils/constants");
|
|
7
7
|
var objectAssign_1 = require("../utils/lang/objectAssign");
|
|
8
8
|
var constants_2 = require("../logger/constants");
|
|
9
|
-
var consent_1 = require("../
|
|
9
|
+
var consent_1 = require("../consent");
|
|
10
10
|
// 'unload' event is used instead of 'beforeunload', since 'unload' is not a cancelable event, so no other listeners can stop the event from occurring.
|
|
11
11
|
var UNLOAD_DOM_EVENT = 'unload';
|
|
12
12
|
var EVENT_NAME = 'for unload page event.';
|
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 = exports.ERROR_SIZE_EXCEEDED = void 0;
|
|
4
|
+
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_INITIAL = 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 = exports.ERROR_NOT_PLAIN_OBJECT = 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.
|
|
@@ -74,6 +74,7 @@ exports.EVENTS_TRACKER_SUCCESS = 120;
|
|
|
74
74
|
exports.IMPRESSIONS_TRACKER_SUCCESS = 121;
|
|
75
75
|
exports.USER_CONSENT_UPDATED = 122;
|
|
76
76
|
exports.USER_CONSENT_NOT_UPDATED = 123;
|
|
77
|
+
exports.USER_CONSENT_INITIAL = 124;
|
|
77
78
|
exports.ENGINE_VALUE_INVALID = 200;
|
|
78
79
|
exports.ENGINE_VALUE_NO_ATTRIBUTES = 201;
|
|
79
80
|
exports.CLIENT_NO_LISTENER = 202;
|
|
@@ -18,6 +18,7 @@ exports.codesInfo = warn_1.codesWarn.concat([
|
|
|
18
18
|
[c.IMPRESSIONS_TRACKER_SUCCESS, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Successfully stored %s impression(s).'],
|
|
19
19
|
[c.USER_CONSENT_UPDATED, 'setUserConsent: consent status changed from %s to %s.'],
|
|
20
20
|
[c.USER_CONSENT_NOT_UPDATED, 'setUserConsent: call had no effect because it was the current consent status (%s).'],
|
|
21
|
+
[c.USER_CONSENT_INITIAL, 'Starting the SDK with %s user consent. No data will be sent.'],
|
|
21
22
|
// synchronizer
|
|
22
23
|
[c.POLLING_SMART_PAUSING, c.LOG_PREFIX_SYNC_POLLING + 'Turning segments data polling %s.'],
|
|
23
24
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
|
@@ -8,8 +8,8 @@ var clientInputValidation_1 = require("./clientInputValidation");
|
|
|
8
8
|
/**
|
|
9
9
|
* Creates an Sdk client, i.e., a base client with status and destroy interface
|
|
10
10
|
*/
|
|
11
|
-
function sdkClientFactory(params) {
|
|
12
|
-
var sdkReadinessManager = params.sdkReadinessManager, syncManager = params.syncManager, storage = params.storage, signalListener = params.signalListener, settings = params.settings
|
|
11
|
+
function sdkClientFactory(params, isSharedClient) {
|
|
12
|
+
var sdkReadinessManager = params.sdkReadinessManager, syncManager = params.syncManager, storage = params.storage, signalListener = params.signalListener, settings = params.settings;
|
|
13
13
|
return (0, objectAssign_1.objectAssign)(
|
|
14
14
|
// Proto-linkage of the readiness Event Emitter
|
|
15
15
|
Object.create(sdkReadinessManager.sdkStatus),
|
|
@@ -26,7 +26,7 @@ function sdkClientFactory(params) {
|
|
|
26
26
|
sdkReadinessManager.readinessManager.destroy();
|
|
27
27
|
signalListener && signalListener.stop();
|
|
28
28
|
// Release the API Key if it is the main client
|
|
29
|
-
if (!
|
|
29
|
+
if (!isSharedClient)
|
|
30
30
|
(0, apiKey_1.releaseApiKey)(settings.core.authorizationKey);
|
|
31
31
|
// Cleanup storage
|
|
32
32
|
return storage.destroy();
|
|
@@ -19,8 +19,7 @@ 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
|
-
var mainClientInstance = (0, clientCS_1.clientCSDecorator)(log, (0, sdkClient_1.sdkClientFactory)(params),
|
|
23
|
-
key);
|
|
22
|
+
var mainClientInstance = (0, clientCS_1.clientCSDecorator)(log, (0, sdkClient_1.sdkClientFactory)(params), key);
|
|
24
23
|
var parsedDefaultKey = (0, key_2.keyParser)(key);
|
|
25
24
|
var defaultInstanceId = buildInstanceId(parsedDefaultKey);
|
|
26
25
|
// Cache instances created per factory.
|
|
@@ -58,9 +57,8 @@ function sdkClientMethodCSFactory(params) {
|
|
|
58
57
|
sdkReadinessManager: sharedSdkReadiness_1,
|
|
59
58
|
storage: sharedStorage || storage,
|
|
60
59
|
syncManager: sharedSyncManager,
|
|
61
|
-
signalListener: undefined,
|
|
62
|
-
|
|
63
|
-
})), validKey);
|
|
60
|
+
signalListener: undefined, // only the main client "destroy" method stops the signal listener
|
|
61
|
+
}), true), validKey);
|
|
64
62
|
sharedSyncManager && sharedSyncManager.start();
|
|
65
63
|
log.info(constants_1.NEW_SHARED_CLIENT);
|
|
66
64
|
}
|
|
@@ -21,8 +21,7 @@ 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
|
-
var mainClientInstance = (0, clientCS_1.clientCSDecorator)(log, (0, sdkClient_1.sdkClientFactory)(params),
|
|
25
|
-
key, trafficType);
|
|
24
|
+
var mainClientInstance = (0, clientCS_1.clientCSDecorator)(log, (0, sdkClient_1.sdkClientFactory)(params), key, trafficType);
|
|
26
25
|
var parsedDefaultKey = (0, key_2.keyParser)(key);
|
|
27
26
|
var defaultInstanceId = buildInstanceId(parsedDefaultKey, trafficType);
|
|
28
27
|
// Cache instances created per factory.
|
|
@@ -67,9 +66,8 @@ function sdkClientMethodCSFactory(params) {
|
|
|
67
66
|
sdkReadinessManager: sharedSdkReadiness_1,
|
|
68
67
|
storage: sharedStorage || storage,
|
|
69
68
|
syncManager: sharedSyncManager,
|
|
70
|
-
signalListener: undefined,
|
|
71
|
-
|
|
72
|
-
})), validKey, validTrafficType);
|
|
69
|
+
signalListener: undefined, // only the main client "destroy" method stops the signal listener
|
|
70
|
+
}), true), validKey, validTrafficType);
|
|
73
71
|
sharedSyncManager && sharedSyncManager.start();
|
|
74
72
|
log.info(constants_1.NEW_SHARED_CLIENT);
|
|
75
73
|
}
|
package/cjs/sdkFactory/index.js
CHANGED
|
@@ -64,7 +64,8 @@ function sdkFactory(params) {
|
|
|
64
64
|
// signal listener
|
|
65
65
|
var signalListener = SignalListener && new SignalListener(syncManager, settings, storage, splitApi);
|
|
66
66
|
// Sdk client and manager
|
|
67
|
-
var
|
|
67
|
+
var ctx = { eventTracker: eventTracker, impressionsTracker: impressionsTracker, sdkReadinessManager: sdkReadinessManager, settings: settings, storage: storage, syncManager: syncManager, signalListener: signalListener };
|
|
68
|
+
var clientMethod = sdkClientMethodFactory(ctx);
|
|
68
69
|
var managerInstance = sdkManagerFactory(log, storage.splits, sdkReadinessManager);
|
|
69
70
|
syncManager && syncManager.start();
|
|
70
71
|
signalListener && signalListener.start();
|
|
@@ -81,6 +82,6 @@ function sdkFactory(params) {
|
|
|
81
82
|
// Logger wrapper API
|
|
82
83
|
Logger: (0, sdkLogger_1.createLoggerAPI)(settings.log),
|
|
83
84
|
settings: settings,
|
|
84
|
-
}, extraProps && extraProps(
|
|
85
|
+
}, extraProps && extraProps(ctx));
|
|
85
86
|
}
|
|
86
87
|
exports.sdkFactory = sdkFactory;
|
|
@@ -4,7 +4,7 @@ exports.syncManagerOnlineFactory = void 0;
|
|
|
4
4
|
var submitterManager_1 = require("./submitters/submitterManager");
|
|
5
5
|
var constants_1 = require("./streaming/constants");
|
|
6
6
|
var constants_2 = require("../logger/constants");
|
|
7
|
-
var consent_1 = require("../
|
|
7
|
+
var consent_1 = require("../consent");
|
|
8
8
|
/**
|
|
9
9
|
* Online SyncManager factory.
|
|
10
10
|
* Can be used for server-side API, and client-side API with or without multiple clients.
|
|
@@ -6,7 +6,7 @@ var attribute_1 = require("./attribute");
|
|
|
6
6
|
var constants_1 = require("../../logger/constants");
|
|
7
7
|
function validateAttributes(log, maybeAttrs, method) {
|
|
8
8
|
// Attributes are optional
|
|
9
|
-
if ((0, lang_1.isObject)(maybeAttrs)
|
|
9
|
+
if (maybeAttrs == undefined || (0, lang_1.isObject)(maybeAttrs)) // eslint-disable-line eqeqeq
|
|
10
10
|
return maybeAttrs;
|
|
11
11
|
log.error(constants_1.ERROR_NOT_PLAIN_OBJECT, [method, 'attributes']);
|
|
12
12
|
return false;
|
package/cjs/utils/lang/index.js
CHANGED
|
@@ -154,10 +154,12 @@ function isNaNNumber(val) {
|
|
|
154
154
|
}
|
|
155
155
|
exports.isNaNNumber = isNaNNumber;
|
|
156
156
|
/**
|
|
157
|
-
* Validates if a value is an object
|
|
157
|
+
* Validates if a value is an object created by the Object constructor (plain object).
|
|
158
|
+
* It checks `constructor.name` to avoid false negatives when validating values on a separate VM context, which has its own global built-ins.
|
|
158
159
|
*/
|
|
159
160
|
function isObject(obj) {
|
|
160
|
-
return obj !== null && typeof obj === 'object' && obj.constructor === Object
|
|
161
|
+
return obj !== null && typeof obj === 'object' && (obj.constructor === Object ||
|
|
162
|
+
(obj.constructor != null && obj.constructor.name === 'Object'));
|
|
161
163
|
}
|
|
162
164
|
exports.isObject = isObject;
|
|
163
165
|
/**
|
|
@@ -85,7 +85,7 @@ function fromSecondsToMillis(n) {
|
|
|
85
85
|
* @param validationParams defaults and fields validators used to validate and creates a settings object from a given config
|
|
86
86
|
*/
|
|
87
87
|
function settingsValidation(config, validationParams) {
|
|
88
|
-
var defaults = validationParams.defaults,
|
|
88
|
+
var defaults = validationParams.defaults, runtime = validationParams.runtime, storage = validationParams.storage, integrations = validationParams.integrations, logger = validationParams.logger, localhost = validationParams.localhost, consent = validationParams.consent;
|
|
89
89
|
// creates a settings object merging base, defaults and config objects.
|
|
90
90
|
var withDefaults = (0, lang_1.merge)({}, base, defaults, config);
|
|
91
91
|
// ensure a valid logger.
|
|
@@ -111,8 +111,8 @@ function settingsValidation(config, validationParams) {
|
|
|
111
111
|
// @ts-ignore, modify readonly prop
|
|
112
112
|
if (storage)
|
|
113
113
|
withDefaults.storage = storage(withDefaults);
|
|
114
|
-
//
|
|
115
|
-
if (
|
|
114
|
+
// Validate key and TT (for client-side)
|
|
115
|
+
if (validationParams.acceptKey) {
|
|
116
116
|
var maybeKey = withDefaults.core.key;
|
|
117
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
118
|
if (withDefaults.mode === constants_1.LOCALHOST_MODE && maybeKey === undefined) {
|
|
@@ -124,9 +124,11 @@ function settingsValidation(config, validationParams) {
|
|
|
124
124
|
// @ts-ignore, @TODO handle invalid keys as a non-recoverable error?
|
|
125
125
|
withDefaults.core.key = (0, key_1.validateKey)(log, maybeKey, 'Client instantiation');
|
|
126
126
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
if (validationParams.acceptTT) {
|
|
128
|
+
var maybeTT = withDefaults.core.trafficType;
|
|
129
|
+
if (maybeTT !== undefined) { // @ts-ignore
|
|
130
|
+
withDefaults.core.trafficType = (0, trafficType_1.validateTrafficType)(log, maybeTT, 'Client instantiation');
|
|
131
|
+
}
|
|
130
132
|
}
|
|
131
133
|
}
|
|
132
134
|
// Current ip/hostname information
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ERROR_NOT_BOOLEAN, USER_CONSENT_UPDATED, USER_CONSENT_NOT_UPDATED, USER_CONSENT_INITIAL } from '../logger/constants';
|
|
2
|
+
import { isConsentGranted } from './index';
|
|
3
|
+
import { CONSENT_GRANTED, CONSENT_DECLINED, CONSENT_UNKNOWN } from '../utils/constants';
|
|
4
|
+
import { isBoolean } from '../utils/lang';
|
|
5
|
+
// User consent enum
|
|
6
|
+
var ConsentStatus = {
|
|
7
|
+
GRANTED: CONSENT_GRANTED,
|
|
8
|
+
DECLINED: CONSENT_DECLINED,
|
|
9
|
+
UNKNOWN: CONSENT_UNKNOWN,
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* The public user consent API exposed via SplitFactory, used to control if the SDK tracks and sends impressions and events or not.
|
|
13
|
+
*/
|
|
14
|
+
export function createUserConsentAPI(params) {
|
|
15
|
+
var settings = params.settings, log = params.settings.log, syncManager = params.syncManager, _a = params.storage, events = _a.events, impressions = _a.impressions, impressionCounts = _a.impressionCounts;
|
|
16
|
+
if (!isConsentGranted(settings))
|
|
17
|
+
log.info(USER_CONSENT_INITIAL, [settings.userConsent]);
|
|
18
|
+
return {
|
|
19
|
+
setStatus: function (consent) {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
// validate input param
|
|
22
|
+
if (!isBoolean(consent)) {
|
|
23
|
+
log.warn(ERROR_NOT_BOOLEAN, ['setUserConsent']);
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
var newConsentStatus = consent ? CONSENT_GRANTED : CONSENT_DECLINED;
|
|
27
|
+
if (settings.userConsent !== newConsentStatus) {
|
|
28
|
+
log.info(USER_CONSENT_UPDATED, [settings.userConsent, newConsentStatus]); // @ts-ignore, modify readonly prop
|
|
29
|
+
settings.userConsent = newConsentStatus;
|
|
30
|
+
if (consent) { // resumes submitters if transitioning to GRANTED
|
|
31
|
+
(_a = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _a === void 0 ? void 0 : _a.start();
|
|
32
|
+
}
|
|
33
|
+
else { // pauses submitters and drops tracked data if transitioning to DECLINED
|
|
34
|
+
(_b = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _b === void 0 ? void 0 : _b.stop();
|
|
35
|
+
// @ts-ignore, clear method is present in storage for standalone and partial consumer mode
|
|
36
|
+
if (events.clear)
|
|
37
|
+
events.clear(); // @ts-ignore
|
|
38
|
+
if (impressions.clear)
|
|
39
|
+
impressions.clear();
|
|
40
|
+
if (impressionCounts)
|
|
41
|
+
impressionCounts.clear();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
log.info(USER_CONSENT_NOT_UPDATED, [newConsentStatus]);
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
},
|
|
49
|
+
getStatus: function () {
|
|
50
|
+
return settings.userConsent;
|
|
51
|
+
},
|
|
52
|
+
Status: ConsentStatus
|
|
53
|
+
};
|
|
54
|
+
}
|
package/esm/listeners/browser.js
CHANGED
|
@@ -3,7 +3,7 @@ import { fromImpressionCountsCollector } from '../sync/submitters/impressionCoun
|
|
|
3
3
|
import { OPTIMIZED, DEBUG } from '../utils/constants';
|
|
4
4
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
5
5
|
import { CLEANUP_REGISTERING, CLEANUP_DEREGISTERING } from '../logger/constants';
|
|
6
|
-
import { isConsentGranted } from '../
|
|
6
|
+
import { isConsentGranted } from '../consent';
|
|
7
7
|
// 'unload' event is used instead of 'beforeunload', since 'unload' is not a cancelable event, so no other listeners can stop the event from occurring.
|
|
8
8
|
var UNLOAD_DOM_EVENT = 'unload';
|
|
9
9
|
var EVENT_NAME = 'for unload page event.';
|
package/esm/logger/constants.js
CHANGED
|
@@ -69,6 +69,7 @@ export var EVENTS_TRACKER_SUCCESS = 120;
|
|
|
69
69
|
export var IMPRESSIONS_TRACKER_SUCCESS = 121;
|
|
70
70
|
export var USER_CONSENT_UPDATED = 122;
|
|
71
71
|
export var USER_CONSENT_NOT_UPDATED = 123;
|
|
72
|
+
export var USER_CONSENT_INITIAL = 124;
|
|
72
73
|
export var ENGINE_VALUE_INVALID = 200;
|
|
73
74
|
export var ENGINE_VALUE_NO_ATTRIBUTES = 201;
|
|
74
75
|
export var CLIENT_NO_LISTENER = 202;
|
|
@@ -14,6 +14,7 @@ export var codesInfo = codesWarn.concat([
|
|
|
14
14
|
[c.IMPRESSIONS_TRACKER_SUCCESS, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Successfully stored %s impression(s).'],
|
|
15
15
|
[c.USER_CONSENT_UPDATED, 'setUserConsent: consent status changed from %s to %s.'],
|
|
16
16
|
[c.USER_CONSENT_NOT_UPDATED, 'setUserConsent: call had no effect because it was the current consent status (%s).'],
|
|
17
|
+
[c.USER_CONSENT_INITIAL, 'Starting the SDK with %s user consent. No data will be sent.'],
|
|
17
18
|
// synchronizer
|
|
18
19
|
[c.POLLING_SMART_PAUSING, c.LOG_PREFIX_SYNC_POLLING + 'Turning segments data polling %s.'],
|
|
19
20
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
|
@@ -5,8 +5,8 @@ import { clientInputValidationDecorator } from './clientInputValidation';
|
|
|
5
5
|
/**
|
|
6
6
|
* Creates an Sdk client, i.e., a base client with status and destroy interface
|
|
7
7
|
*/
|
|
8
|
-
export function sdkClientFactory(params) {
|
|
9
|
-
var sdkReadinessManager = params.sdkReadinessManager, syncManager = params.syncManager, storage = params.storage, signalListener = params.signalListener, settings = params.settings
|
|
8
|
+
export function sdkClientFactory(params, isSharedClient) {
|
|
9
|
+
var sdkReadinessManager = params.sdkReadinessManager, syncManager = params.syncManager, storage = params.storage, signalListener = params.signalListener, settings = params.settings;
|
|
10
10
|
return objectAssign(
|
|
11
11
|
// Proto-linkage of the readiness Event Emitter
|
|
12
12
|
Object.create(sdkReadinessManager.sdkStatus),
|
|
@@ -23,7 +23,7 @@ export function sdkClientFactory(params) {
|
|
|
23
23
|
sdkReadinessManager.readinessManager.destroy();
|
|
24
24
|
signalListener && signalListener.stop();
|
|
25
25
|
// Release the API Key if it is the main client
|
|
26
|
-
if (!
|
|
26
|
+
if (!isSharedClient)
|
|
27
27
|
releaseApiKey(settings.core.authorizationKey);
|
|
28
28
|
// Cleanup storage
|
|
29
29
|
return storage.destroy();
|
|
@@ -16,8 +16,7 @@ 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
|
-
var mainClientInstance = clientCSDecorator(log, sdkClientFactory(params),
|
|
20
|
-
key);
|
|
19
|
+
var mainClientInstance = clientCSDecorator(log, sdkClientFactory(params), key);
|
|
21
20
|
var parsedDefaultKey = keyParser(key);
|
|
22
21
|
var defaultInstanceId = buildInstanceId(parsedDefaultKey);
|
|
23
22
|
// Cache instances created per factory.
|
|
@@ -55,9 +54,8 @@ export function sdkClientMethodCSFactory(params) {
|
|
|
55
54
|
sdkReadinessManager: sharedSdkReadiness_1,
|
|
56
55
|
storage: sharedStorage || storage,
|
|
57
56
|
syncManager: sharedSyncManager,
|
|
58
|
-
signalListener: undefined,
|
|
59
|
-
|
|
60
|
-
})), validKey);
|
|
57
|
+
signalListener: undefined, // only the main client "destroy" method stops the signal listener
|
|
58
|
+
}), true), validKey);
|
|
61
59
|
sharedSyncManager && sharedSyncManager.start();
|
|
62
60
|
log.info(NEW_SHARED_CLIENT);
|
|
63
61
|
}
|
|
@@ -18,8 +18,7 @@ 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
|
-
var mainClientInstance = clientCSDecorator(log, sdkClientFactory(params),
|
|
22
|
-
key, trafficType);
|
|
21
|
+
var mainClientInstance = clientCSDecorator(log, sdkClientFactory(params), key, trafficType);
|
|
23
22
|
var parsedDefaultKey = keyParser(key);
|
|
24
23
|
var defaultInstanceId = buildInstanceId(parsedDefaultKey, trafficType);
|
|
25
24
|
// Cache instances created per factory.
|
|
@@ -64,9 +63,8 @@ export function sdkClientMethodCSFactory(params) {
|
|
|
64
63
|
sdkReadinessManager: sharedSdkReadiness_1,
|
|
65
64
|
storage: sharedStorage || storage,
|
|
66
65
|
syncManager: sharedSyncManager,
|
|
67
|
-
signalListener: undefined,
|
|
68
|
-
|
|
69
|
-
})), validKey, validTrafficType);
|
|
66
|
+
signalListener: undefined, // only the main client "destroy" method stops the signal listener
|
|
67
|
+
}), true), validKey, validTrafficType);
|
|
70
68
|
sharedSyncManager && sharedSyncManager.start();
|
|
71
69
|
log.info(NEW_SHARED_CLIENT);
|
|
72
70
|
}
|
package/esm/sdkFactory/index.js
CHANGED
|
@@ -61,7 +61,8 @@ export function sdkFactory(params) {
|
|
|
61
61
|
// signal listener
|
|
62
62
|
var signalListener = SignalListener && new SignalListener(syncManager, settings, storage, splitApi);
|
|
63
63
|
// Sdk client and manager
|
|
64
|
-
var
|
|
64
|
+
var ctx = { eventTracker: eventTracker, impressionsTracker: impressionsTracker, sdkReadinessManager: sdkReadinessManager, settings: settings, storage: storage, syncManager: syncManager, signalListener: signalListener };
|
|
65
|
+
var clientMethod = sdkClientMethodFactory(ctx);
|
|
65
66
|
var managerInstance = sdkManagerFactory(log, storage.splits, sdkReadinessManager);
|
|
66
67
|
syncManager && syncManager.start();
|
|
67
68
|
signalListener && signalListener.start();
|
|
@@ -78,5 +79,5 @@ export function sdkFactory(params) {
|
|
|
78
79
|
// Logger wrapper API
|
|
79
80
|
Logger: createLoggerAPI(settings.log),
|
|
80
81
|
settings: settings,
|
|
81
|
-
}, extraProps && extraProps(
|
|
82
|
+
}, extraProps && extraProps(ctx));
|
|
82
83
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { submitterManagerFactory } from './submitters/submitterManager';
|
|
2
2
|
import { PUSH_SUBSYSTEM_UP, PUSH_SUBSYSTEM_DOWN } from './streaming/constants';
|
|
3
3
|
import { SYNC_START_POLLING, SYNC_CONTINUE_POLLING, SYNC_STOP_POLLING } from '../logger/constants';
|
|
4
|
-
import { isConsentGranted } from '../
|
|
4
|
+
import { isConsentGranted } from '../consent';
|
|
5
5
|
/**
|
|
6
6
|
* Online SyncManager factory.
|
|
7
7
|
* Can be used for server-side API, and client-side API with or without multiple clients.
|
|
@@ -3,7 +3,7 @@ import { validateAttribute } from './attribute';
|
|
|
3
3
|
import { ERROR_NOT_PLAIN_OBJECT } from '../../logger/constants';
|
|
4
4
|
export function validateAttributes(log, maybeAttrs, method) {
|
|
5
5
|
// Attributes are optional
|
|
6
|
-
if (
|
|
6
|
+
if (maybeAttrs == undefined || isObject(maybeAttrs)) // eslint-disable-line eqeqeq
|
|
7
7
|
return maybeAttrs;
|
|
8
8
|
log.error(ERROR_NOT_PLAIN_OBJECT, [method, 'attributes']);
|
|
9
9
|
return false;
|
package/esm/utils/lang/index.js
CHANGED
|
@@ -141,10 +141,12 @@ export function isNaNNumber(val) {
|
|
|
141
141
|
return val !== val;
|
|
142
142
|
}
|
|
143
143
|
/**
|
|
144
|
-
* Validates if a value is an object
|
|
144
|
+
* Validates if a value is an object created by the Object constructor (plain object).
|
|
145
|
+
* It checks `constructor.name` to avoid false negatives when validating values on a separate VM context, which has its own global built-ins.
|
|
145
146
|
*/
|
|
146
147
|
export function isObject(obj) {
|
|
147
|
-
return obj !== null && typeof obj === 'object' && obj.constructor === Object
|
|
148
|
+
return obj !== null && typeof obj === 'object' && (obj.constructor === Object ||
|
|
149
|
+
(obj.constructor != null && obj.constructor.name === 'Object'));
|
|
148
150
|
}
|
|
149
151
|
/**
|
|
150
152
|
* Checks if a given value is a string.
|
|
@@ -82,7 +82,7 @@ function fromSecondsToMillis(n) {
|
|
|
82
82
|
* @param validationParams defaults and fields validators used to validate and creates a settings object from a given config
|
|
83
83
|
*/
|
|
84
84
|
export function settingsValidation(config, validationParams) {
|
|
85
|
-
var defaults = validationParams.defaults,
|
|
85
|
+
var defaults = validationParams.defaults, runtime = validationParams.runtime, storage = validationParams.storage, integrations = validationParams.integrations, logger = validationParams.logger, localhost = validationParams.localhost, consent = validationParams.consent;
|
|
86
86
|
// creates a settings object merging base, defaults and config objects.
|
|
87
87
|
var withDefaults = merge({}, base, defaults, config);
|
|
88
88
|
// ensure a valid logger.
|
|
@@ -108,8 +108,8 @@ export function settingsValidation(config, validationParams) {
|
|
|
108
108
|
// @ts-ignore, modify readonly prop
|
|
109
109
|
if (storage)
|
|
110
110
|
withDefaults.storage = storage(withDefaults);
|
|
111
|
-
//
|
|
112
|
-
if (
|
|
111
|
+
// Validate key and TT (for client-side)
|
|
112
|
+
if (validationParams.acceptKey) {
|
|
113
113
|
var maybeKey = withDefaults.core.key;
|
|
114
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
115
|
if (withDefaults.mode === LOCALHOST_MODE && maybeKey === undefined) {
|
|
@@ -121,9 +121,11 @@ export function settingsValidation(config, validationParams) {
|
|
|
121
121
|
// @ts-ignore, @TODO handle invalid keys as a non-recoverable error?
|
|
122
122
|
withDefaults.core.key = validateKey(log, maybeKey, 'Client instantiation');
|
|
123
123
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
if (validationParams.acceptTT) {
|
|
125
|
+
var maybeTT = withDefaults.core.trafficType;
|
|
126
|
+
if (maybeTT !== undefined) { // @ts-ignore
|
|
127
|
+
withDefaults.core.trafficType = validateTrafficType(log, maybeTT, 'Client instantiation');
|
|
128
|
+
}
|
|
127
129
|
}
|
|
128
130
|
}
|
|
129
131
|
// Current ip/hostname information
|
package/package.json
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ERROR_NOT_BOOLEAN, USER_CONSENT_UPDATED, USER_CONSENT_NOT_UPDATED, USER_CONSENT_INITIAL } from '../logger/constants';
|
|
2
|
+
import { isConsentGranted } from './index';
|
|
3
|
+
import { CONSENT_GRANTED, CONSENT_DECLINED, CONSENT_UNKNOWN } from '../utils/constants';
|
|
4
|
+
import { isBoolean } from '../utils/lang';
|
|
5
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
6
|
+
|
|
7
|
+
// User consent enum
|
|
8
|
+
const ConsentStatus = {
|
|
9
|
+
GRANTED: CONSENT_GRANTED,
|
|
10
|
+
DECLINED: CONSENT_DECLINED,
|
|
11
|
+
UNKNOWN: CONSENT_UNKNOWN,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The public user consent API exposed via SplitFactory, used to control if the SDK tracks and sends impressions and events or not.
|
|
16
|
+
*/
|
|
17
|
+
export function createUserConsentAPI(params: ISdkFactoryContext) {
|
|
18
|
+
const { settings, settings: { log }, syncManager, storage: { events, impressions, impressionCounts } } = params;
|
|
19
|
+
|
|
20
|
+
if (!isConsentGranted(settings)) log.info(USER_CONSENT_INITIAL, [settings.userConsent]);
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
setStatus(consent: unknown) {
|
|
24
|
+
// validate input param
|
|
25
|
+
if (!isBoolean(consent)) {
|
|
26
|
+
log.warn(ERROR_NOT_BOOLEAN, ['setUserConsent']);
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const newConsentStatus = consent ? CONSENT_GRANTED : CONSENT_DECLINED;
|
|
31
|
+
|
|
32
|
+
if (settings.userConsent !== newConsentStatus) {
|
|
33
|
+
log.info(USER_CONSENT_UPDATED, [settings.userConsent, newConsentStatus]); // @ts-ignore, modify readonly prop
|
|
34
|
+
settings.userConsent = newConsentStatus;
|
|
35
|
+
|
|
36
|
+
if (consent) { // resumes submitters if transitioning to GRANTED
|
|
37
|
+
syncManager?.submitter?.start();
|
|
38
|
+
} else { // pauses submitters and drops tracked data if transitioning to DECLINED
|
|
39
|
+
syncManager?.submitter?.stop();
|
|
40
|
+
// @ts-ignore, clear method is present in storage for standalone and partial consumer mode
|
|
41
|
+
if (events.clear) events.clear(); // @ts-ignore
|
|
42
|
+
if (impressions.clear) impressions.clear();
|
|
43
|
+
if (impressionCounts) impressionCounts.clear();
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
log.info(USER_CONSENT_NOT_UPDATED, [newConsentStatus]);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return true;
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
getStatus() {
|
|
53
|
+
return settings.userConsent;
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
Status: ConsentStatus
|
|
57
|
+
};
|
|
58
|
+
}
|