@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.
Files changed (69) hide show
  1. package/CHANGES.txt +14 -0
  2. package/cjs/{utils/consent.js → consent/index.js} +1 -1
  3. package/cjs/consent/sdkUserConsent.js +58 -0
  4. package/cjs/listeners/browser.js +1 -1
  5. package/cjs/logger/constants.js +3 -2
  6. package/cjs/logger/messages/info.js +1 -0
  7. package/cjs/sdkClient/sdkClient.js +3 -3
  8. package/cjs/sdkClient/sdkClientMethodCS.js +3 -5
  9. package/cjs/sdkClient/sdkClientMethodCSWithTT.js +3 -5
  10. package/cjs/sdkFactory/index.js +3 -2
  11. package/cjs/sync/syncManagerOnline.js +1 -1
  12. package/cjs/utils/inputValidation/attributes.js +1 -1
  13. package/cjs/utils/lang/index.js +4 -2
  14. package/cjs/utils/settingsValidation/index.js +8 -6
  15. package/esm/{utils/consent.js → consent/index.js} +1 -1
  16. package/esm/consent/sdkUserConsent.js +54 -0
  17. package/esm/listeners/browser.js +1 -1
  18. package/esm/logger/constants.js +1 -0
  19. package/esm/logger/messages/info.js +1 -0
  20. package/esm/sdkClient/sdkClient.js +3 -3
  21. package/esm/sdkClient/sdkClientMethodCS.js +3 -5
  22. package/esm/sdkClient/sdkClientMethodCSWithTT.js +3 -5
  23. package/esm/sdkFactory/index.js +3 -2
  24. package/esm/sync/syncManagerOnline.js +1 -1
  25. package/esm/utils/inputValidation/attributes.js +1 -1
  26. package/esm/utils/lang/index.js +4 -2
  27. package/esm/utils/settingsValidation/index.js +8 -6
  28. package/package.json +1 -1
  29. package/src/{utils/consent.ts → consent/index.ts} +1 -1
  30. package/src/consent/sdkUserConsent.ts +58 -0
  31. package/src/evaluator/parser/index.ts +1 -1
  32. package/src/evaluator/types.ts +2 -2
  33. package/src/evaluator/value/index.ts +2 -2
  34. package/src/evaluator/value/sanitize.ts +2 -2
  35. package/src/listeners/browser.ts +1 -1
  36. package/src/logger/constants.ts +1 -0
  37. package/src/logger/messages/info.ts +1 -0
  38. package/src/sdkClient/client.ts +2 -3
  39. package/src/sdkClient/sdkClient.ts +4 -4
  40. package/src/sdkClient/sdkClientMethod.ts +2 -2
  41. package/src/sdkClient/sdkClientMethodCS.ts +4 -5
  42. package/src/sdkClient/sdkClientMethodCSWithTT.ts +4 -5
  43. package/src/sdkFactory/index.ts +3 -2
  44. package/src/sdkFactory/types.ts +13 -3
  45. package/src/sync/syncManagerOnline.ts +1 -1
  46. package/src/utils/inputValidation/attributes.ts +1 -2
  47. package/src/utils/lang/index.ts +7 -3
  48. package/src/utils/settingsValidation/index.ts +8 -6
  49. package/src/utils/settingsValidation/types.ts +4 -2
  50. package/types/consent/index.d.ts +2 -0
  51. package/types/consent/sdkUserConsent.d.ts +13 -0
  52. package/types/evaluator/types.d.ts +2 -2
  53. package/types/evaluator/value/index.d.ts +1 -1
  54. package/types/evaluator/value/sanitize.d.ts +1 -1
  55. package/types/logger/constants.d.ts +1 -0
  56. package/types/sdkClient/client.d.ts +2 -2
  57. package/types/sdkClient/sdkClient.d.ts +2 -2
  58. package/types/sdkClient/sdkClientMethod.d.ts +2 -2
  59. package/types/sdkClient/sdkClientMethodCS.d.ts +2 -2
  60. package/types/sdkClient/sdkClientMethodCSWithTT.d.ts +2 -2
  61. package/types/sdkFactory/types.d.ts +12 -3
  62. package/types/utils/lang/index.d.ts +2 -1
  63. package/types/utils/settingsValidation/types.d.ts +4 -2
  64. package/cjs/sdkClient/types.js +0 -2
  65. package/cjs/sdkFactory/userConsentProps.js +0 -37
  66. package/esm/sdkClient/types.js +0 -1
  67. package/esm/sdkFactory/userConsentProps.js +0 -33
  68. package/src/sdkClient/types.ts +0 -21
  69. 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
 
@@ -6,7 +6,7 @@ import { ILogger } from '../logger/types';
6
6
 
7
7
  export interface IDependencyMatcherValue {
8
8
  key: SplitIO.SplitKey,
9
- attributes: SplitIO.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: SplitIO.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: SplitIO.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: SplitIO.Attributes): IDependencyMatcherValue {
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: SplitIO.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
 
@@ -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 '../utils/consent';
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';
@@ -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.'],
@@ -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: IClientFactoryParams): SplitIO.IClient | SplitIO.IAsyncClient {
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 { ISdkClientFactoryParams } from './types';
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: ISdkClientFactoryParams): SplitIO.IClient | SplitIO.IAsyncClient {
12
- const { sdkReadinessManager, syncManager, storage, signalListener, settings, sharedClient } = params;
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 (!sharedClient) releaseApiKey(settings.core.authorizationKey);
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: ISdkClientFactoryParams): () => SplitIO.IClient | SplitIO.IAsyncClient {
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: ISdkClientFactoryParams): (key?: SplitIO.SplitKey) => SplitIO.ICsClient {
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, // @ts-ignore
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
- sharedClient: true
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: ISdkClientFactoryParams): (key?: SplitIO.SplitKey, trafficType?: string) => SplitIO.ICsClient {
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, // @ts-ignore
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
- sharedClient: true
90
- })) as SplitIO.IClient,
89
+ }), true) as SplitIO.IClient,
91
90
  validKey,
92
91
  validTrafficType
93
92
  );
@@ -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 clientMethod = sdkClientMethodFactory({ eventTracker, impressionsTracker, sdkReadinessManager, settings, storage, syncManager, signalListener });
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(settings, syncManager));
108
+ }, extraProps && extraProps(ctx));
108
109
  }
@@ -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: ISdkClientFactoryParams) => ({ (): SplitIO.ICsClient; (key: SplitIO.SplitKey, trafficType?: string | undefined): SplitIO.ICsClient; } | (() => SplitIO.IClient) | (() => SplitIO.IAsyncClient))
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?: (settings: ISettings, syncManager?: ISyncManager) => object
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 '../utils/consent';
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 (isObject(maybeAttrs) || maybeAttrs == undefined) // eslint-disable-line eqeqeq
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
  }
@@ -151,10 +151,14 @@ export function isNaNNumber(val: any): boolean {
151
151
  }
152
152
 
153
153
  /**
154
- * Validates if a value is an object with the Object prototype (map 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): boolean {
157
- return obj !== null && typeof obj === 'object' && obj.constructor === 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, isClientSide, runtime, storage, integrations, logger, localhost, consent } = validationParams;
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
- // In client-side, validate key and TT
135
- if (isClientSide) {
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
- const maybeTT = withDefaults.core.trafficType;
148
- if (maybeTT !== undefined) { // @ts-ignore, assigning false
149
- withDefaults.core.trafficType = validateTrafficType(log, maybeTT, 'Client instantiation');
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 and core.trafficType */
14
- isClientSide?: boolean,
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,2 @@
1
+ import { ISettings } from '../types';
2
+ export declare function isConsentGranted(settings: ISettings): boolean;
@@ -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: SplitIO.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: SplitIO.Attributes): string | number | boolean | (string | number)[] | import("../types").IDependencyMatcherValue | undefined;
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: SplitIO.Attributes): string | number | boolean | (string | number)[] | IDependencyMatcherValue | undefined;
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: IClientFactoryParams): SplitIO.IClient | SplitIO.IAsyncClient;
6
+ export declare function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | SplitIO.IAsyncClient;
@@ -1,6 +1,6 @@
1
1
  import { SplitIO } from '../types';
2
- import { ISdkClientFactoryParams } from './types';
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: ISdkClientFactoryParams): SplitIO.IClient | SplitIO.IAsyncClient;
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: ISdkClientFactoryParams): () => SplitIO.IClient | SplitIO.IAsyncClient;
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: ISdkClientFactoryParams): (key?: SplitIO.SplitKey) => SplitIO.ICsClient;
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: ISdkClientFactoryParams): (key?: SplitIO.SplitKey, trafficType?: string) => SplitIO.ICsClient;
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: ISdkClientFactoryParams) => ({
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?: (settings: ISettings, syncManager?: ISyncManager) => object;
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 with the Object prototype (map 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 and core.trafficType */
17
- isClientSide?: boolean;
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`) */
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -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;
@@ -1 +0,0 @@
1
- export {};