@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
|
@@ -31,7 +31,7 @@ export function parser(log: ILogger, conditions: ISplitCondition[], storage: ISt
|
|
|
31
31
|
const matcher = matcherFactory(log, matcherDto, storage);
|
|
32
32
|
|
|
33
33
|
// Evaluator function.
|
|
34
|
-
return (key: string, attributes: SplitIO.Attributes, splitEvaluator: ISplitEvaluator) => {
|
|
34
|
+
return (key: string, attributes: SplitIO.Attributes | undefined, splitEvaluator: ISplitEvaluator) => {
|
|
35
35
|
const value = sanitizeValue(log, key, matcherDto, attributes);
|
|
36
36
|
const result = value !== undefined && matcher ? matcher(value, splitEvaluator) : false;
|
|
37
37
|
|
package/src/evaluator/types.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { ILogger } from '../logger/types';
|
|
|
6
6
|
|
|
7
7
|
export interface IDependencyMatcherValue {
|
|
8
8
|
key: SplitIO.SplitKey,
|
|
9
|
-
attributes
|
|
9
|
+
attributes?: SplitIO.Attributes
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export interface IMatcherDto {
|
|
@@ -27,7 +27,7 @@ export interface IEvaluation {
|
|
|
27
27
|
|
|
28
28
|
export type IEvaluationResult = IEvaluation & { treatment: string }
|
|
29
29
|
|
|
30
|
-
export type ISplitEvaluator = (log: ILogger, key: SplitIO.SplitKey, splitName: string, attributes: SplitIO.Attributes, storage: IStorageSync | IStorageAsync) => MaybeThenable<IEvaluation>
|
|
30
|
+
export type ISplitEvaluator = (log: ILogger, key: SplitIO.SplitKey, splitName: string, attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync) => MaybeThenable<IEvaluation>
|
|
31
31
|
|
|
32
32
|
export type IEvaluator = (key: SplitIO.SplitKey, seed: number, trafficAllocation?: number, trafficAllocationSeed?: number, attributes?: SplitIO.Attributes, splitEvaluator?: ISplitEvaluator) => MaybeThenable<IEvaluation | undefined>
|
|
33
33
|
|
|
@@ -4,7 +4,7 @@ import { ILogger } from '../../logger/types';
|
|
|
4
4
|
import { sanitize } from './sanitize';
|
|
5
5
|
import { ENGINE_VALUE, ENGINE_VALUE_NO_ATTRIBUTES, ENGINE_VALUE_INVALID } from '../../logger/constants';
|
|
6
6
|
|
|
7
|
-
function parseValue(log: ILogger, key: string, attributeName: string | null, attributes
|
|
7
|
+
function parseValue(log: ILogger, key: string, attributeName: string | null, attributes?: SplitIO.Attributes) {
|
|
8
8
|
let value = undefined;
|
|
9
9
|
if (attributeName) {
|
|
10
10
|
if (attributes) {
|
|
@@ -23,7 +23,7 @@ function parseValue(log: ILogger, key: string, attributeName: string | null, att
|
|
|
23
23
|
/**
|
|
24
24
|
* Defines value to be matched (key / attribute).
|
|
25
25
|
*/
|
|
26
|
-
export function sanitizeValue(log: ILogger, key: string, matcherDto: IMatcherDto, attributes
|
|
26
|
+
export function sanitizeValue(log: ILogger, key: string, matcherDto: IMatcherDto, attributes?: SplitIO.Attributes) {
|
|
27
27
|
const attributeName = matcherDto.attribute;
|
|
28
28
|
const valueToMatch = parseValue(log, key, attributeName, attributes);
|
|
29
29
|
const sanitizedValue = sanitize(log, matcherDto.type, valueToMatch, matcherDto.dataType, attributes);
|
|
@@ -41,7 +41,7 @@ function sanitizeBoolean(val: any): boolean | undefined {
|
|
|
41
41
|
return undefined;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function dependencyProcessor(sanitizedValue: string, attributes
|
|
44
|
+
function dependencyProcessor(sanitizedValue: string, attributes?: SplitIO.Attributes): IDependencyMatcherValue {
|
|
45
45
|
return {
|
|
46
46
|
key: sanitizedValue,
|
|
47
47
|
attributes
|
|
@@ -69,7 +69,7 @@ function getProcessingFunction(matcherTypeID: number, dataType: string) {
|
|
|
69
69
|
/**
|
|
70
70
|
* Sanitize matcher value
|
|
71
71
|
*/
|
|
72
|
-
export function sanitize(log: ILogger, matcherTypeID: number, value: string | number | boolean | Array<string | number> | undefined, dataType: string, attributes
|
|
72
|
+
export function sanitize(log: ILogger, matcherTypeID: number, value: string | number | boolean | Array<string | number> | undefined, dataType: string, attributes?: SplitIO.Attributes) {
|
|
73
73
|
const processor = getProcessingFunction(matcherTypeID, dataType);
|
|
74
74
|
let sanitizedValue: string | number | boolean | Array<string | number> | IDependencyMatcherValue | undefined;
|
|
75
75
|
|
package/src/listeners/browser.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { OPTIMIZED, DEBUG } from '../utils/constants';
|
|
|
11
11
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
12
12
|
import { CLEANUP_REGISTERING, CLEANUP_DEREGISTERING } from '../logger/constants';
|
|
13
13
|
import { ISyncManager } from '../sync/types';
|
|
14
|
-
import { isConsentGranted } from '../
|
|
14
|
+
import { isConsentGranted } from '../consent';
|
|
15
15
|
|
|
16
16
|
// 'unload' event is used instead of 'beforeunload', since 'unload' is not a cancelable event, so no other listeners can stop the event from occurring.
|
|
17
17
|
const UNLOAD_DOM_EVENT = 'unload';
|
package/src/logger/constants.ts
CHANGED
|
@@ -70,6 +70,7 @@ export const EVENTS_TRACKER_SUCCESS = 120;
|
|
|
70
70
|
export const IMPRESSIONS_TRACKER_SUCCESS = 121;
|
|
71
71
|
export const USER_CONSENT_UPDATED = 122;
|
|
72
72
|
export const USER_CONSENT_NOT_UPDATED = 123;
|
|
73
|
+
export const USER_CONSENT_INITIAL = 124;
|
|
73
74
|
|
|
74
75
|
export const ENGINE_VALUE_INVALID = 200;
|
|
75
76
|
export const ENGINE_VALUE_NO_ATTRIBUTES = 201;
|
|
@@ -16,6 +16,7 @@ export const codesInfo: [number, string][] = codesWarn.concat([
|
|
|
16
16
|
[c.IMPRESSIONS_TRACKER_SUCCESS, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Successfully stored %s impression(s).'],
|
|
17
17
|
[c.USER_CONSENT_UPDATED, 'setUserConsent: consent status changed from %s to %s.'],
|
|
18
18
|
[c.USER_CONSENT_NOT_UPDATED, 'setUserConsent: call had no effect because it was the current consent status (%s).'],
|
|
19
|
+
[c.USER_CONSENT_INITIAL, 'Starting the SDK with %s user consent. No data will be sent.'],
|
|
19
20
|
|
|
20
21
|
// synchronizer
|
|
21
22
|
[c.POLLING_SMART_PAUSING, c.LOG_PREFIX_SYNC_POLLING + 'Turning segments data polling %s.'],
|
package/src/sdkClient/client.ts
CHANGED
|
@@ -5,17 +5,16 @@ import { validateSplitExistance } from '../utils/inputValidation/splitExistance'
|
|
|
5
5
|
import { validateTrafficTypeExistance } from '../utils/inputValidation/trafficTypeExistance';
|
|
6
6
|
import { SDK_NOT_READY } from '../utils/labels';
|
|
7
7
|
import { CONTROL } from '../utils/constants';
|
|
8
|
-
import { IClientFactoryParams } from './types';
|
|
9
8
|
import { IEvaluationResult } from '../evaluator/types';
|
|
10
9
|
import { SplitIO, ImpressionDTO } from '../types';
|
|
11
10
|
import { IMPRESSION, IMPRESSION_QUEUEING } from '../logger/constants';
|
|
12
|
-
|
|
11
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
13
12
|
|
|
14
13
|
/**
|
|
15
14
|
* Creator of base client with getTreatments and track methods.
|
|
16
15
|
*/
|
|
17
16
|
// @TODO missing time tracking to collect telemetry
|
|
18
|
-
export function clientFactory(params:
|
|
17
|
+
export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | SplitIO.IAsyncClient {
|
|
19
18
|
const { sdkReadinessManager: { readinessManager }, storage, settings, impressionsTracker, eventTracker } = params;
|
|
20
19
|
const { log, mode } = settings;
|
|
21
20
|
|
|
@@ -3,13 +3,13 @@ import { IStatusInterface, SplitIO } from '../types';
|
|
|
3
3
|
import { releaseApiKey } from '../utils/inputValidation/apiKey';
|
|
4
4
|
import { clientFactory } from './client';
|
|
5
5
|
import { clientInputValidationDecorator } from './clientInputValidation';
|
|
6
|
-
import {
|
|
6
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Creates an Sdk client, i.e., a base client with status and destroy interface
|
|
10
10
|
*/
|
|
11
|
-
export function sdkClientFactory(params:
|
|
12
|
-
const { sdkReadinessManager, syncManager, storage, signalListener, settings
|
|
11
|
+
export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: boolean): SplitIO.IClient | SplitIO.IAsyncClient {
|
|
12
|
+
const { sdkReadinessManager, syncManager, storage, signalListener, settings } = params;
|
|
13
13
|
|
|
14
14
|
return objectAssign(
|
|
15
15
|
// Proto-linkage of the readiness Event Emitter
|
|
@@ -35,7 +35,7 @@ export function sdkClientFactory(params: ISdkClientFactoryParams): SplitIO.IClie
|
|
|
35
35
|
signalListener && signalListener.stop();
|
|
36
36
|
|
|
37
37
|
// Release the API Key if it is the main client
|
|
38
|
-
if (!
|
|
38
|
+
if (!isSharedClient) releaseApiKey(settings.core.authorizationKey);
|
|
39
39
|
|
|
40
40
|
// Cleanup storage
|
|
41
41
|
return storage.destroy();
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { ISdkClientFactoryParams } from './types';
|
|
2
1
|
import { SplitIO } from '../types';
|
|
3
2
|
import { sdkClientFactory } from './sdkClient';
|
|
4
3
|
import { RETRIEVE_CLIENT_DEFAULT } from '../logger/constants';
|
|
4
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Factory of client method for server-side SDKs (ISDK and IAsyncSDK)
|
|
8
8
|
*/
|
|
9
|
-
export function sdkClientMethodFactory(params:
|
|
9
|
+
export function sdkClientMethodFactory(params: ISdkFactoryContext): () => SplitIO.IClient | SplitIO.IAsyncClient {
|
|
10
10
|
const log = params.settings.log;
|
|
11
11
|
const clientInstance = sdkClientFactory(params);
|
|
12
12
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { clientCSDecorator } from './clientCS';
|
|
2
|
-
import { ISdkClientFactoryParams } from './types';
|
|
3
2
|
import { SplitIO } from '../types';
|
|
4
3
|
import { validateKey } from '../utils/inputValidation/key';
|
|
5
4
|
import { getMatching, keyParser } from '../utils/key';
|
|
@@ -8,6 +7,7 @@ import { ISyncManagerCS } from '../sync/types';
|
|
|
8
7
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
9
8
|
import { RETRIEVE_CLIENT_DEFAULT, NEW_SHARED_CLIENT, RETRIEVE_CLIENT_EXISTING } from '../logger/constants';
|
|
10
9
|
import { SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
|
|
10
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
11
11
|
|
|
12
12
|
function buildInstanceId(key: SplitIO.SplitKey) {
|
|
13
13
|
// @ts-ignore
|
|
@@ -20,12 +20,12 @@ const method = 'Client instantiation';
|
|
|
20
20
|
* Factory of client method for the client-side API variant where TT is ignored and thus
|
|
21
21
|
* clients don't have a binded TT for the track method.
|
|
22
22
|
*/
|
|
23
|
-
export function sdkClientMethodCSFactory(params:
|
|
23
|
+
export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey) => SplitIO.ICsClient {
|
|
24
24
|
const { storage, syncManager, sdkReadinessManager, settings: { core: { key }, startup: { readyTimeout }, log } } = params;
|
|
25
25
|
|
|
26
26
|
const mainClientInstance = clientCSDecorator(
|
|
27
27
|
log,
|
|
28
|
-
sdkClientFactory(params) as SplitIO.IClient,
|
|
28
|
+
sdkClientFactory(params) as SplitIO.IClient,
|
|
29
29
|
key
|
|
30
30
|
);
|
|
31
31
|
|
|
@@ -76,8 +76,7 @@ export function sdkClientMethodCSFactory(params: ISdkClientFactoryParams): (key?
|
|
|
76
76
|
storage: sharedStorage || storage,
|
|
77
77
|
syncManager: sharedSyncManager,
|
|
78
78
|
signalListener: undefined, // only the main client "destroy" method stops the signal listener
|
|
79
|
-
|
|
80
|
-
})) as SplitIO.IClient,
|
|
79
|
+
}), true) as SplitIO.IClient,
|
|
81
80
|
validKey
|
|
82
81
|
);
|
|
83
82
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { clientCSDecorator } from './clientCS';
|
|
2
|
-
import { ISdkClientFactoryParams } from './types';
|
|
3
2
|
import { SplitIO } from '../types';
|
|
4
3
|
import { validateKey } from '../utils/inputValidation/key';
|
|
5
4
|
import { validateTrafficType } from '../utils/inputValidation/trafficType';
|
|
@@ -9,6 +8,7 @@ import { ISyncManagerCS } from '../sync/types';
|
|
|
9
8
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
10
9
|
import { RETRIEVE_CLIENT_DEFAULT, NEW_SHARED_CLIENT, RETRIEVE_CLIENT_EXISTING } from '../logger/constants';
|
|
11
10
|
import { SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
|
|
11
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
12
12
|
|
|
13
13
|
function buildInstanceId(key: SplitIO.SplitKey, trafficType?: string) {
|
|
14
14
|
// @ts-ignore
|
|
@@ -22,12 +22,12 @@ const method = 'Client instantiation';
|
|
|
22
22
|
* where clients can have a binded TT for the track method, which is provided via the settings
|
|
23
23
|
* (default client) or the client method (shared clients).
|
|
24
24
|
*/
|
|
25
|
-
export function sdkClientMethodCSFactory(params:
|
|
25
|
+
export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey, trafficType?: string) => SplitIO.ICsClient {
|
|
26
26
|
const { storage, syncManager, sdkReadinessManager, settings: { core: { key, trafficType }, startup: { readyTimeout }, log } } = params;
|
|
27
27
|
|
|
28
28
|
const mainClientInstance = clientCSDecorator(
|
|
29
29
|
log,
|
|
30
|
-
sdkClientFactory(params) as SplitIO.IClient,
|
|
30
|
+
sdkClientFactory(params) as SplitIO.IClient,
|
|
31
31
|
key,
|
|
32
32
|
trafficType
|
|
33
33
|
);
|
|
@@ -86,8 +86,7 @@ export function sdkClientMethodCSFactory(params: ISdkClientFactoryParams): (key?
|
|
|
86
86
|
storage: sharedStorage || storage,
|
|
87
87
|
syncManager: sharedSyncManager,
|
|
88
88
|
signalListener: undefined, // only the main client "destroy" method stops the signal listener
|
|
89
|
-
|
|
90
|
-
})) as SplitIO.IClient,
|
|
89
|
+
}), true) as SplitIO.IClient,
|
|
91
90
|
validKey,
|
|
92
91
|
validTrafficType
|
|
93
92
|
);
|
package/src/sdkFactory/index.ts
CHANGED
|
@@ -81,7 +81,8 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
|
|
|
81
81
|
const signalListener = SignalListener && new SignalListener(syncManager, settings, storage, splitApi);
|
|
82
82
|
|
|
83
83
|
// Sdk client and manager
|
|
84
|
-
const
|
|
84
|
+
const ctx = { eventTracker, impressionsTracker, sdkReadinessManager, settings, storage, syncManager, signalListener };
|
|
85
|
+
const clientMethod = sdkClientMethodFactory(ctx);
|
|
85
86
|
const managerInstance = sdkManagerFactory(log, storage.splits, sdkReadinessManager);
|
|
86
87
|
|
|
87
88
|
syncManager && syncManager.start();
|
|
@@ -104,5 +105,5 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
|
|
|
104
105
|
Logger: createLoggerAPI(settings.log),
|
|
105
106
|
|
|
106
107
|
settings,
|
|
107
|
-
}, extraProps && extraProps(
|
|
108
|
+
}, extraProps && extraProps(ctx));
|
|
108
109
|
}
|
package/src/sdkFactory/types.ts
CHANGED
|
@@ -2,13 +2,23 @@ import { IIntegrationManager, IIntegrationFactoryParams } from '../integrations/
|
|
|
2
2
|
import { ISignalListener } from '../listeners/types';
|
|
3
3
|
import { ILogger } from '../logger/types';
|
|
4
4
|
import { ISdkReadinessManager } from '../readiness/types';
|
|
5
|
-
import { ISdkClientFactoryParams } from '../sdkClient/types';
|
|
6
5
|
import { IFetch, ISplitApi, IEventSourceConstructor } from '../services/types';
|
|
7
6
|
import { IStorageAsync, IStorageSync, ISplitsCacheSync, ISplitsCacheAsync, IStorageFactoryParams } from '../storages/types';
|
|
8
7
|
import { ISyncManager, ISyncManagerFactoryParams } from '../sync/types';
|
|
9
8
|
import { IImpressionObserver } from '../trackers/impressionObserver/types';
|
|
9
|
+
import { IImpressionsTracker, IEventTracker } from '../trackers/types';
|
|
10
10
|
import { SplitIO, ISettings, IEventEmitter } from '../types';
|
|
11
11
|
|
|
12
|
+
export interface ISdkFactoryContext {
|
|
13
|
+
storage: IStorageSync | IStorageAsync,
|
|
14
|
+
sdkReadinessManager: ISdkReadinessManager,
|
|
15
|
+
settings: ISettings
|
|
16
|
+
impressionsTracker: IImpressionsTracker,
|
|
17
|
+
eventTracker: IEventTracker,
|
|
18
|
+
signalListener?: ISignalListener
|
|
19
|
+
syncManager?: ISyncManager,
|
|
20
|
+
}
|
|
21
|
+
|
|
12
22
|
/**
|
|
13
23
|
* Environment related dependencies.
|
|
14
24
|
* These getters are called a fixed number of times per factory instantiation.
|
|
@@ -53,7 +63,7 @@ export interface ISdkFactoryParams {
|
|
|
53
63
|
|
|
54
64
|
// Sdk client method factory (ISDK::client method).
|
|
55
65
|
// It Allows to distinguish SDK clients with the client-side API (`ICsSDK`) or server-side API (`ISDK` or `IAsyncSDK`).
|
|
56
|
-
sdkClientMethodFactory: (params:
|
|
66
|
+
sdkClientMethodFactory: (params: ISdkFactoryContext) => ({ (): SplitIO.ICsClient; (key: SplitIO.SplitKey, trafficType?: string | undefined): SplitIO.ICsClient; } | (() => SplitIO.IClient) | (() => SplitIO.IAsyncClient))
|
|
57
67
|
|
|
58
68
|
// Optional signal listener constructor. Used to handle special app states, like shutdown, app paused or resumed.
|
|
59
69
|
// Pass only if `syncManager` (used by Node listener) and `splitApi` (used by Browser listener) are passed.
|
|
@@ -70,5 +80,5 @@ export interface ISdkFactoryParams {
|
|
|
70
80
|
impressionsObserverFactory?: () => IImpressionObserver
|
|
71
81
|
|
|
72
82
|
// Optional function to assign additional properties to the factory instance
|
|
73
|
-
extraProps?: (
|
|
83
|
+
extraProps?: (params: ISdkFactoryContext) => object
|
|
74
84
|
}
|
|
@@ -6,7 +6,7 @@ import { IPushManager } from './streaming/types';
|
|
|
6
6
|
import { IPollingManager, IPollingManagerCS } from './polling/types';
|
|
7
7
|
import { PUSH_SUBSYSTEM_UP, PUSH_SUBSYSTEM_DOWN } from './streaming/constants';
|
|
8
8
|
import { SYNC_START_POLLING, SYNC_CONTINUE_POLLING, SYNC_STOP_POLLING } from '../logger/constants';
|
|
9
|
-
import { isConsentGranted } from '../
|
|
9
|
+
import { isConsentGranted } from '../consent';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Online SyncManager factory.
|
|
@@ -6,7 +6,7 @@ import { ERROR_NOT_PLAIN_OBJECT } from '../../logger/constants';
|
|
|
6
6
|
|
|
7
7
|
export function validateAttributes(log: ILogger, maybeAttrs: any, method: string): SplitIO.Attributes | undefined | false {
|
|
8
8
|
// Attributes are optional
|
|
9
|
-
if (
|
|
9
|
+
if (maybeAttrs == undefined || isObject(maybeAttrs)) // eslint-disable-line eqeqeq
|
|
10
10
|
return maybeAttrs;
|
|
11
11
|
|
|
12
12
|
log.error(ERROR_NOT_PLAIN_OBJECT, [method, 'attributes']);
|
|
@@ -23,5 +23,4 @@ export function validateAttributesDeep(log: ILogger, maybeAttributes: Record<str
|
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
return result;
|
|
26
|
-
|
|
27
26
|
}
|
package/src/utils/lang/index.ts
CHANGED
|
@@ -151,10 +151,14 @@ export function isNaNNumber(val: any): boolean {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
/**
|
|
154
|
-
* Validates if a value is an object
|
|
154
|
+
* Validates if a value is an object created by the Object constructor (plain object).
|
|
155
|
+
* It checks `constructor.name` to avoid false negatives when validating values on a separate VM context, which has its own global built-ins.
|
|
155
156
|
*/
|
|
156
|
-
export function isObject(obj: any)
|
|
157
|
-
return obj !== null && typeof obj === 'object' &&
|
|
157
|
+
export function isObject(obj: any) {
|
|
158
|
+
return obj !== null && typeof obj === 'object' && (
|
|
159
|
+
obj.constructor === Object ||
|
|
160
|
+
(obj.constructor != null && obj.constructor.name === 'Object')
|
|
161
|
+
);
|
|
158
162
|
}
|
|
159
163
|
|
|
160
164
|
/**
|
|
@@ -99,7 +99,7 @@ function fromSecondsToMillis(n: number) {
|
|
|
99
99
|
*/
|
|
100
100
|
export function settingsValidation(config: unknown, validationParams: ISettingsValidationParams) {
|
|
101
101
|
|
|
102
|
-
const { defaults,
|
|
102
|
+
const { defaults, runtime, storage, integrations, logger, localhost, consent } = validationParams;
|
|
103
103
|
|
|
104
104
|
// creates a settings object merging base, defaults and config objects.
|
|
105
105
|
const withDefaults = merge({}, base, defaults, config) as ISettings;
|
|
@@ -131,8 +131,8 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
|
|
|
131
131
|
// @ts-ignore, modify readonly prop
|
|
132
132
|
if (storage) withDefaults.storage = storage(withDefaults);
|
|
133
133
|
|
|
134
|
-
//
|
|
135
|
-
if (
|
|
134
|
+
// Validate key and TT (for client-side)
|
|
135
|
+
if (validationParams.acceptKey) {
|
|
136
136
|
const maybeKey = withDefaults.core.key;
|
|
137
137
|
// Although `key` is required in client-side, it can be omitted in LOCALHOST mode. In that case, the value `localhost_key` is used.
|
|
138
138
|
if (withDefaults.mode === LOCALHOST_MODE && maybeKey === undefined) {
|
|
@@ -144,9 +144,11 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
|
|
|
144
144
|
withDefaults.core.key = validateKey(log, maybeKey, 'Client instantiation');
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
if (validationParams.acceptTT) {
|
|
148
|
+
const maybeTT = withDefaults.core.trafficType;
|
|
149
|
+
if (maybeTT !== undefined) { // @ts-ignore
|
|
150
|
+
withDefaults.core.trafficType = validateTrafficType(log, maybeTT, 'Client instantiation');
|
|
151
|
+
}
|
|
150
152
|
}
|
|
151
153
|
}
|
|
152
154
|
|
|
@@ -10,8 +10,10 @@ export interface ISettingsValidationParams {
|
|
|
10
10
|
* Version and startup properties are required, because they are not defined in the base settings.
|
|
11
11
|
*/
|
|
12
12
|
defaults: Partial<ISettings> & { version: string } & { startup: ISettings['startup'] },
|
|
13
|
-
/** If true, validates core.key
|
|
14
|
-
|
|
13
|
+
/** If true, validates core.key */
|
|
14
|
+
acceptKey?: boolean,
|
|
15
|
+
/** If true, validates core.trafficType */
|
|
16
|
+
acceptTT?: boolean,
|
|
15
17
|
/** Define runtime values (`settings.runtime`) */
|
|
16
18
|
runtime: (settings: ISettings) => ISettings['runtime'],
|
|
17
19
|
/** Storage validator (`settings.storage`) */
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
2
|
+
/**
|
|
3
|
+
* The public user consent API exposed via SplitFactory, used to control if the SDK tracks and sends impressions and events or not.
|
|
4
|
+
*/
|
|
5
|
+
export declare function createUserConsentAPI(params: ISdkFactoryContext): {
|
|
6
|
+
setStatus(consent: unknown): boolean;
|
|
7
|
+
getStatus(): import("../types").ConsentStatus | undefined;
|
|
8
|
+
Status: {
|
|
9
|
+
GRANTED: string;
|
|
10
|
+
DECLINED: string;
|
|
11
|
+
UNKNOWN: string;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
@@ -5,7 +5,7 @@ import { SplitIO } from '../types';
|
|
|
5
5
|
import { ILogger } from '../logger/types';
|
|
6
6
|
export interface IDependencyMatcherValue {
|
|
7
7
|
key: SplitIO.SplitKey;
|
|
8
|
-
attributes
|
|
8
|
+
attributes?: SplitIO.Attributes;
|
|
9
9
|
}
|
|
10
10
|
export interface IMatcherDto {
|
|
11
11
|
type: number;
|
|
@@ -23,6 +23,6 @@ export interface IEvaluation {
|
|
|
23
23
|
export declare type IEvaluationResult = IEvaluation & {
|
|
24
24
|
treatment: string;
|
|
25
25
|
};
|
|
26
|
-
export declare type ISplitEvaluator = (log: ILogger, key: SplitIO.SplitKey, splitName: string, attributes: SplitIO.Attributes, storage: IStorageSync | IStorageAsync) => MaybeThenable<IEvaluation>;
|
|
26
|
+
export declare type ISplitEvaluator = (log: ILogger, key: SplitIO.SplitKey, splitName: string, attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync) => MaybeThenable<IEvaluation>;
|
|
27
27
|
export declare type IEvaluator = (key: SplitIO.SplitKey, seed: number, trafficAllocation?: number, trafficAllocationSeed?: number, attributes?: SplitIO.Attributes, splitEvaluator?: ISplitEvaluator) => MaybeThenable<IEvaluation | undefined>;
|
|
28
28
|
export declare type IMatcher = (...args: any) => MaybeThenable<boolean>;
|
|
@@ -4,4 +4,4 @@ import { ILogger } from '../../logger/types';
|
|
|
4
4
|
/**
|
|
5
5
|
* Defines value to be matched (key / attribute).
|
|
6
6
|
*/
|
|
7
|
-
export declare function sanitizeValue(log: ILogger, key: string, matcherDto: IMatcherDto, attributes
|
|
7
|
+
export declare function sanitizeValue(log: ILogger, key: string, matcherDto: IMatcherDto, attributes?: SplitIO.Attributes): string | number | boolean | (string | number)[] | import("../types").IDependencyMatcherValue | undefined;
|
|
@@ -4,4 +4,4 @@ import { ILogger } from '../../logger/types';
|
|
|
4
4
|
/**
|
|
5
5
|
* Sanitize matcher value
|
|
6
6
|
*/
|
|
7
|
-
export declare function sanitize(log: ILogger, matcherTypeID: number, value: string | number | boolean | Array<string | number> | undefined, dataType: string, attributes
|
|
7
|
+
export declare function sanitize(log: ILogger, matcherTypeID: number, value: string | number | boolean | Array<string | number> | undefined, dataType: string, attributes?: SplitIO.Attributes): string | number | boolean | (string | number)[] | IDependencyMatcherValue | undefined;
|
|
@@ -69,6 +69,7 @@ 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
71
|
export declare const USER_CONSENT_NOT_UPDATED = 123;
|
|
72
|
+
export declare const USER_CONSENT_INITIAL = 124;
|
|
72
73
|
export declare const ENGINE_VALUE_INVALID = 200;
|
|
73
74
|
export declare const ENGINE_VALUE_NO_ATTRIBUTES = 201;
|
|
74
75
|
export declare const CLIENT_NO_LISTENER = 202;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { IClientFactoryParams } from './types';
|
|
2
1
|
import { SplitIO } from '../types';
|
|
2
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
3
3
|
/**
|
|
4
4
|
* Creator of base client with getTreatments and track methods.
|
|
5
5
|
*/
|
|
6
|
-
export declare function clientFactory(params:
|
|
6
|
+
export declare function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | SplitIO.IAsyncClient;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SplitIO } from '../types';
|
|
2
|
-
import {
|
|
2
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
3
3
|
/**
|
|
4
4
|
* Creates an Sdk client, i.e., a base client with status and destroy interface
|
|
5
5
|
*/
|
|
6
|
-
export declare function sdkClientFactory(params:
|
|
6
|
+
export declare function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: boolean): SplitIO.IClient | SplitIO.IAsyncClient;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ISdkClientFactoryParams } from './types';
|
|
2
1
|
import { SplitIO } from '../types';
|
|
2
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
3
3
|
/**
|
|
4
4
|
* Factory of client method for server-side SDKs (ISDK and IAsyncSDK)
|
|
5
5
|
*/
|
|
6
|
-
export declare function sdkClientMethodFactory(params:
|
|
6
|
+
export declare function sdkClientMethodFactory(params: ISdkFactoryContext): () => SplitIO.IClient | SplitIO.IAsyncClient;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ISdkClientFactoryParams } from './types';
|
|
2
1
|
import { SplitIO } from '../types';
|
|
2
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
3
3
|
/**
|
|
4
4
|
* Factory of client method for the client-side API variant where TT is ignored and thus
|
|
5
5
|
* clients don't have a binded TT for the track method.
|
|
6
6
|
*/
|
|
7
|
-
export declare function sdkClientMethodCSFactory(params:
|
|
7
|
+
export declare function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey) => SplitIO.ICsClient;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ISdkClientFactoryParams } from './types';
|
|
2
1
|
import { SplitIO } from '../types';
|
|
2
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
3
3
|
/**
|
|
4
4
|
* Factory of client method for the client-side (browser) variant of the Isomorphic JS SDK,
|
|
5
5
|
* where clients can have a binded TT for the track method, which is provided via the settings
|
|
6
6
|
* (default client) or the client method (shared clients).
|
|
7
7
|
*/
|
|
8
|
-
export declare function sdkClientMethodCSFactory(params:
|
|
8
|
+
export declare function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey, trafficType?: string) => SplitIO.ICsClient;
|
|
@@ -2,12 +2,21 @@ import { IIntegrationManager, IIntegrationFactoryParams } from '../integrations/
|
|
|
2
2
|
import { ISignalListener } from '../listeners/types';
|
|
3
3
|
import { ILogger } from '../logger/types';
|
|
4
4
|
import { ISdkReadinessManager } from '../readiness/types';
|
|
5
|
-
import { ISdkClientFactoryParams } from '../sdkClient/types';
|
|
6
5
|
import { IFetch, ISplitApi, IEventSourceConstructor } from '../services/types';
|
|
7
6
|
import { IStorageAsync, IStorageSync, ISplitsCacheSync, ISplitsCacheAsync, IStorageFactoryParams } from '../storages/types';
|
|
8
7
|
import { ISyncManager, ISyncManagerFactoryParams } from '../sync/types';
|
|
9
8
|
import { IImpressionObserver } from '../trackers/impressionObserver/types';
|
|
9
|
+
import { IImpressionsTracker, IEventTracker } from '../trackers/types';
|
|
10
10
|
import { SplitIO, ISettings, IEventEmitter } from '../types';
|
|
11
|
+
export interface ISdkFactoryContext {
|
|
12
|
+
storage: IStorageSync | IStorageAsync;
|
|
13
|
+
sdkReadinessManager: ISdkReadinessManager;
|
|
14
|
+
settings: ISettings;
|
|
15
|
+
impressionsTracker: IImpressionsTracker;
|
|
16
|
+
eventTracker: IEventTracker;
|
|
17
|
+
signalListener?: ISignalListener;
|
|
18
|
+
syncManager?: ISyncManager;
|
|
19
|
+
}
|
|
11
20
|
/**
|
|
12
21
|
* Environment related dependencies.
|
|
13
22
|
* These getters are called a fixed number of times per factory instantiation.
|
|
@@ -28,7 +37,7 @@ export interface ISdkFactoryParams {
|
|
|
28
37
|
splitApiFactory?: (settings: ISettings, platform: IPlatform) => ISplitApi;
|
|
29
38
|
syncManagerFactory?: (params: ISyncManagerFactoryParams) => ISyncManager;
|
|
30
39
|
sdkManagerFactory: (log: ILogger, splits: ISplitsCacheSync | ISplitsCacheAsync, sdkReadinessManager: ISdkReadinessManager) => SplitIO.IManager | SplitIO.IAsyncManager;
|
|
31
|
-
sdkClientMethodFactory: (params:
|
|
40
|
+
sdkClientMethodFactory: (params: ISdkFactoryContext) => ({
|
|
32
41
|
(): SplitIO.ICsClient;
|
|
33
42
|
(key: SplitIO.SplitKey, trafficType?: string | undefined): SplitIO.ICsClient;
|
|
34
43
|
} | (() => SplitIO.IClient) | (() => SplitIO.IAsyncClient));
|
|
@@ -38,5 +47,5 @@ export interface ISdkFactoryParams {
|
|
|
38
47
|
serviceApi: ISplitApi | undefined) => ISignalListener;
|
|
39
48
|
integrationsManagerFactory?: (params: IIntegrationFactoryParams) => IIntegrationManager | undefined;
|
|
40
49
|
impressionsObserverFactory?: () => IImpressionObserver;
|
|
41
|
-
extraProps?: (
|
|
50
|
+
extraProps?: (params: ISdkFactoryContext) => object;
|
|
42
51
|
}
|
|
@@ -55,7 +55,8 @@ export declare function isIntegerNumber(val: any): boolean;
|
|
|
55
55
|
*/
|
|
56
56
|
export declare function isNaNNumber(val: any): boolean;
|
|
57
57
|
/**
|
|
58
|
-
* Validates if a value is an object
|
|
58
|
+
* Validates if a value is an object created by the Object constructor (plain object).
|
|
59
|
+
* It checks `constructor.name` to avoid false negatives when validating values on a separate VM context, which has its own global built-ins.
|
|
59
60
|
*/
|
|
60
61
|
export declare function isObject(obj: any): boolean;
|
|
61
62
|
/**
|
|
@@ -13,8 +13,10 @@ export interface ISettingsValidationParams {
|
|
|
13
13
|
} & {
|
|
14
14
|
startup: ISettings['startup'];
|
|
15
15
|
};
|
|
16
|
-
/** If true, validates core.key
|
|
17
|
-
|
|
16
|
+
/** If true, validates core.key */
|
|
17
|
+
acceptKey?: boolean;
|
|
18
|
+
/** If true, validates core.trafficType */
|
|
19
|
+
acceptTT?: boolean;
|
|
18
20
|
/** Define runtime values (`settings.runtime`) */
|
|
19
21
|
runtime: (settings: ISettings) => ISettings['runtime'];
|
|
20
22
|
/** Storage validator (`settings.storage`) */
|
package/cjs/sdkClient/types.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.userConsentProps = void 0;
|
|
4
|
-
var constants_1 = require("../logger/constants");
|
|
5
|
-
var constants_2 = require("../utils/constants");
|
|
6
|
-
var lang_1 = require("../utils/lang");
|
|
7
|
-
// Extend client-side factory instances with user consent getter/setter
|
|
8
|
-
function userConsentProps(settings, syncManager) {
|
|
9
|
-
var log = settings.log;
|
|
10
|
-
return {
|
|
11
|
-
setUserConsent: function (consent) {
|
|
12
|
-
var _a, _b;
|
|
13
|
-
// validate input param
|
|
14
|
-
if (!(0, lang_1.isBoolean)(consent)) {
|
|
15
|
-
log.warn(constants_1.ERROR_NOT_BOOLEAN, ['setUserConsent']);
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
var newConsentStatus = consent ? constants_2.CONSENT_GRANTED : constants_2.CONSENT_DECLINED;
|
|
19
|
-
if (settings.userConsent !== newConsentStatus) { // @ts-ignore, modify readonly prop
|
|
20
|
-
settings.userConsent = newConsentStatus;
|
|
21
|
-
if (consent)
|
|
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
|
|
23
|
-
else
|
|
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]);
|
|
29
|
-
}
|
|
30
|
-
return true;
|
|
31
|
-
},
|
|
32
|
-
getUserConsent: function () {
|
|
33
|
-
return settings.userConsent;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
exports.userConsentProps = userConsentProps;
|
package/esm/sdkClient/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|