@splitsoftware/splitio-commons 2.5.0-rc.0 → 2.5.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 (41) hide show
  1. package/CHANGES.txt +3 -3
  2. package/cjs/evaluator/convertions/index.js +9 -1
  3. package/cjs/evaluator/matchersTransform/index.js +2 -3
  4. package/cjs/sdkClient/sdkClientMethodCS.js +5 -1
  5. package/cjs/sdkFactory/index.js +8 -2
  6. package/cjs/storages/getRolloutPlan.js +69 -0
  7. package/cjs/storages/inLocalStorage/validateCache.js +2 -2
  8. package/cjs/storages/inMemory/InMemoryStorageCS.js +14 -32
  9. package/cjs/storages/setRolloutPlan.js +66 -0
  10. package/cjs/utils/inputValidation/index.js +1 -3
  11. package/cjs/utils/settingsValidation/index.js +4 -0
  12. package/esm/evaluator/convertions/index.js +7 -0
  13. package/esm/evaluator/matchersTransform/index.js +3 -4
  14. package/esm/sdkClient/sdkClientMethodCS.js +5 -1
  15. package/esm/sdkFactory/index.js +8 -2
  16. package/esm/storages/getRolloutPlan.js +65 -0
  17. package/esm/storages/inLocalStorage/validateCache.js +2 -2
  18. package/esm/storages/inMemory/InMemoryStorageCS.js +14 -32
  19. package/esm/storages/setRolloutPlan.js +61 -0
  20. package/esm/utils/inputValidation/index.js +0 -1
  21. package/esm/utils/settingsValidation/index.js +4 -0
  22. package/package.json +1 -1
  23. package/src/evaluator/convertions/index.ts +10 -0
  24. package/src/evaluator/matchersTransform/index.ts +3 -4
  25. package/src/sdkClient/sdkClientMethodCS.ts +7 -1
  26. package/src/sdkFactory/index.ts +9 -2
  27. package/src/storages/getRolloutPlan.ts +72 -0
  28. package/src/storages/inLocalStorage/validateCache.ts +2 -2
  29. package/src/storages/inMemory/InMemoryStorageCS.ts +14 -37
  30. package/src/storages/setRolloutPlan.ts +71 -0
  31. package/src/storages/types.ts +20 -2
  32. package/src/types.ts +2 -0
  33. package/src/utils/inputValidation/index.ts +0 -1
  34. package/src/utils/settingsValidation/index.ts +4 -0
  35. package/types/splitio.d.ts +30 -35
  36. package/cjs/storages/dataLoader.js +0 -109
  37. package/cjs/utils/inputValidation/preloadedData.js +0 -59
  38. package/esm/storages/dataLoader.js +0 -104
  39. package/esm/utils/inputValidation/preloadedData.js +0 -55
  40. package/src/storages/dataLoader.ts +0 -113
  41. package/src/utils/inputValidation/preloadedData.ts +0 -57
@@ -1,109 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCache = exports.setCache = void 0;
4
- var sets_1 = require("../utils/lang/sets");
5
- var key_1 = require("../utils/key");
6
- /**
7
- * Sets the given synchronous storage with the provided preloaded data snapshot.
8
- * If `matchingKey` is provided, the storage is handled as a client-side storage (segments and largeSegments are instances of MySegmentsCache).
9
- * Otherwise, the storage is handled as a server-side storage (segments is an instance of SegmentsCache).
10
- */
11
- function setCache(log, preloadedData, storage, matchingKey) {
12
- // Do not load data if current preloadedData is empty
13
- if (Object.keys(preloadedData).length === 0)
14
- return;
15
- var splits = storage.splits, rbSegments = storage.rbSegments, segments = storage.segments, largeSegments = storage.largeSegments;
16
- log.debug("set cache" + (matchingKey ? " for key " + matchingKey : ''));
17
- if (splits) {
18
- splits.clear();
19
- splits.update(preloadedData.flags || [], [], preloadedData.since || -1);
20
- }
21
- if (rbSegments) {
22
- rbSegments.clear();
23
- rbSegments.update(preloadedData.rbSegments || [], [], preloadedData.rbSince || -1);
24
- }
25
- var segmentsData = preloadedData.segments || {};
26
- if (matchingKey) { // add memberships data (client-side)
27
- var memberships = preloadedData.memberships && preloadedData.memberships[matchingKey];
28
- if (!memberships && segmentsData) {
29
- memberships = {
30
- ms: {
31
- k: Object.keys(segmentsData).filter(function (segmentName) {
32
- var segmentKeys = segmentsData[segmentName];
33
- return segmentKeys.indexOf(matchingKey) > -1;
34
- }).map(function (segmentName) { return ({ n: segmentName }); })
35
- }
36
- };
37
- }
38
- if (memberships) {
39
- if (memberships.ms)
40
- segments.resetSegments(memberships.ms);
41
- if (memberships.ls && largeSegments)
42
- largeSegments.resetSegments(memberships.ls);
43
- }
44
- }
45
- else { // add segments data (server-side)
46
- Object.keys(segmentsData).forEach(function (segmentName) {
47
- var segmentKeys = segmentsData[segmentName];
48
- segments.update(segmentName, segmentKeys, [], -1);
49
- });
50
- }
51
- }
52
- exports.setCache = setCache;
53
- /**
54
- * Gets the preloaded data snapshot from the given synchronous storage.
55
- * If `keys` are provided, the memberships for those keys is returned, to protect segments data.
56
- * Otherwise, the segments data is returned.
57
- */
58
- function getCache(log, storage, keys) {
59
- log.debug("get cache" + (keys ? " for keys " + keys : ''));
60
- return {
61
- since: storage.splits.getChangeNumber(),
62
- flags: storage.splits.getAll(),
63
- rbSince: storage.rbSegments.getChangeNumber(),
64
- rbSegments: storage.rbSegments.getAll(),
65
- segments: keys ?
66
- undefined : // @ts-ignore accessing private prop
67
- Object.keys(storage.segments.segmentCache).reduce(function (prev, cur) {
68
- prev[cur] = (0, sets_1.setToArray)(storage.segments.segmentCache[cur]);
69
- return prev;
70
- }, {}),
71
- memberships: keys ?
72
- keys.reduce(function (prev, key) {
73
- if (storage.shared) {
74
- // Client-side segments
75
- // @ts-ignore accessing private prop
76
- var sharedStorage = storage.shared(key);
77
- prev[(0, key_1.getMatching)(key)] = {
78
- ms: {
79
- // @ts-ignore accessing private prop
80
- k: Object.keys(sharedStorage.segments.segmentCache).map(function (segmentName) { return ({ n: segmentName }); }),
81
- },
82
- ls: sharedStorage.largeSegments ? {
83
- // @ts-ignore accessing private prop
84
- k: Object.keys(sharedStorage.largeSegments.segmentCache).map(function (segmentName) { return ({ n: segmentName }); }),
85
- } : undefined
86
- };
87
- }
88
- else {
89
- prev[(0, key_1.getMatching)(key)] = {
90
- ms: {
91
- // Server-side segments
92
- // @ts-ignore accessing private prop
93
- k: Object.keys(storage.segments.segmentCache).reduce(function (prev, segmentName) {
94
- return storage.segments.segmentCache[segmentName].has(key) ?
95
- prev.concat({ n: segmentName }) :
96
- prev;
97
- }, [])
98
- },
99
- ls: {
100
- k: []
101
- }
102
- };
103
- }
104
- return prev;
105
- }, {}) :
106
- undefined
107
- };
108
- }
109
- exports.getCache = getCache;
@@ -1,59 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validatePreloadedData = void 0;
4
- var lang_1 = require("../lang");
5
- var split_1 = require("./split");
6
- function validateTimestampData(log, maybeTimestamp, method, item) {
7
- if ((0, lang_1.isFiniteNumber)(maybeTimestamp) && maybeTimestamp > -1)
8
- return true;
9
- log.error(method + ": preloadedData." + item + " must be a positive number.");
10
- return false;
11
- }
12
- function validateSplitsData(log, maybeSplitsData, method) {
13
- if ((0, lang_1.isObject)(maybeSplitsData)) {
14
- var splitNames = Object.keys(maybeSplitsData);
15
- if (splitNames.length === 0)
16
- log.warn(method + ": preloadedData.splitsData doesn't contain feature flag definitions.");
17
- // @TODO in the future, consider handling the possibility of having parsed definitions of splits
18
- if (splitNames.every(function (splitName) { return (0, split_1.validateSplit)(log, splitName, method) && (0, lang_1.isString)(maybeSplitsData[splitName]); }))
19
- return true;
20
- }
21
- log.error(method + ": preloadedData.splitsData must be a map of feature flag names to their stringified definitions.");
22
- return false;
23
- }
24
- function validateMySegmentsData(log, maybeMySegmentsData, method) {
25
- if ((0, lang_1.isObject)(maybeMySegmentsData)) {
26
- var userKeys = Object.keys(maybeMySegmentsData);
27
- if (userKeys.every(function (userKey) {
28
- var segmentNames = maybeMySegmentsData[userKey];
29
- // an empty list is valid
30
- return Array.isArray(segmentNames) && segmentNames.every(function (segmentName) { return (0, lang_1.isString)(segmentName); });
31
- }))
32
- return true;
33
- }
34
- log.error(method + ": preloadedData.mySegmentsData must be a map of user keys to their list of segment names.");
35
- return false;
36
- }
37
- function validateSegmentsData(log, maybeSegmentsData, method) {
38
- if ((0, lang_1.isObject)(maybeSegmentsData)) {
39
- var segmentNames = Object.keys(maybeSegmentsData);
40
- if (segmentNames.every(function (segmentName) { return (0, lang_1.isString)(maybeSegmentsData[segmentName]); }))
41
- return true;
42
- }
43
- log.error(method + ": preloadedData.segmentsData must be a map of segment names to their stringified definitions.");
44
- return false;
45
- }
46
- function validatePreloadedData(log, maybePreloadedData, method) {
47
- if (!(0, lang_1.isObject)(maybePreloadedData)) {
48
- log.error(method + ": preloadedData must be an object.");
49
- }
50
- else if (validateTimestampData(log, maybePreloadedData.lastUpdated, method, 'lastUpdated') &&
51
- validateTimestampData(log, maybePreloadedData.since, method, 'since') &&
52
- validateSplitsData(log, maybePreloadedData.splitsData, method) &&
53
- (!maybePreloadedData.mySegmentsData || validateMySegmentsData(log, maybePreloadedData.mySegmentsData, method)) &&
54
- (!maybePreloadedData.segmentsData || validateSegmentsData(log, maybePreloadedData.segmentsData, method))) {
55
- return true;
56
- }
57
- return false;
58
- }
59
- exports.validatePreloadedData = validatePreloadedData;
@@ -1,104 +0,0 @@
1
- import { setToArray } from '../utils/lang/sets';
2
- import { getMatching } from '../utils/key';
3
- /**
4
- * Sets the given synchronous storage with the provided preloaded data snapshot.
5
- * If `matchingKey` is provided, the storage is handled as a client-side storage (segments and largeSegments are instances of MySegmentsCache).
6
- * Otherwise, the storage is handled as a server-side storage (segments is an instance of SegmentsCache).
7
- */
8
- export function setCache(log, preloadedData, storage, matchingKey) {
9
- // Do not load data if current preloadedData is empty
10
- if (Object.keys(preloadedData).length === 0)
11
- return;
12
- var splits = storage.splits, rbSegments = storage.rbSegments, segments = storage.segments, largeSegments = storage.largeSegments;
13
- log.debug("set cache" + (matchingKey ? " for key " + matchingKey : ''));
14
- if (splits) {
15
- splits.clear();
16
- splits.update(preloadedData.flags || [], [], preloadedData.since || -1);
17
- }
18
- if (rbSegments) {
19
- rbSegments.clear();
20
- rbSegments.update(preloadedData.rbSegments || [], [], preloadedData.rbSince || -1);
21
- }
22
- var segmentsData = preloadedData.segments || {};
23
- if (matchingKey) { // add memberships data (client-side)
24
- var memberships = preloadedData.memberships && preloadedData.memberships[matchingKey];
25
- if (!memberships && segmentsData) {
26
- memberships = {
27
- ms: {
28
- k: Object.keys(segmentsData).filter(function (segmentName) {
29
- var segmentKeys = segmentsData[segmentName];
30
- return segmentKeys.indexOf(matchingKey) > -1;
31
- }).map(function (segmentName) { return ({ n: segmentName }); })
32
- }
33
- };
34
- }
35
- if (memberships) {
36
- if (memberships.ms)
37
- segments.resetSegments(memberships.ms);
38
- if (memberships.ls && largeSegments)
39
- largeSegments.resetSegments(memberships.ls);
40
- }
41
- }
42
- else { // add segments data (server-side)
43
- Object.keys(segmentsData).forEach(function (segmentName) {
44
- var segmentKeys = segmentsData[segmentName];
45
- segments.update(segmentName, segmentKeys, [], -1);
46
- });
47
- }
48
- }
49
- /**
50
- * Gets the preloaded data snapshot from the given synchronous storage.
51
- * If `keys` are provided, the memberships for those keys is returned, to protect segments data.
52
- * Otherwise, the segments data is returned.
53
- */
54
- export function getCache(log, storage, keys) {
55
- log.debug("get cache" + (keys ? " for keys " + keys : ''));
56
- return {
57
- since: storage.splits.getChangeNumber(),
58
- flags: storage.splits.getAll(),
59
- rbSince: storage.rbSegments.getChangeNumber(),
60
- rbSegments: storage.rbSegments.getAll(),
61
- segments: keys ?
62
- undefined : // @ts-ignore accessing private prop
63
- Object.keys(storage.segments.segmentCache).reduce(function (prev, cur) {
64
- prev[cur] = setToArray(storage.segments.segmentCache[cur]);
65
- return prev;
66
- }, {}),
67
- memberships: keys ?
68
- keys.reduce(function (prev, key) {
69
- if (storage.shared) {
70
- // Client-side segments
71
- // @ts-ignore accessing private prop
72
- var sharedStorage = storage.shared(key);
73
- prev[getMatching(key)] = {
74
- ms: {
75
- // @ts-ignore accessing private prop
76
- k: Object.keys(sharedStorage.segments.segmentCache).map(function (segmentName) { return ({ n: segmentName }); }),
77
- },
78
- ls: sharedStorage.largeSegments ? {
79
- // @ts-ignore accessing private prop
80
- k: Object.keys(sharedStorage.largeSegments.segmentCache).map(function (segmentName) { return ({ n: segmentName }); }),
81
- } : undefined
82
- };
83
- }
84
- else {
85
- prev[getMatching(key)] = {
86
- ms: {
87
- // Server-side segments
88
- // @ts-ignore accessing private prop
89
- k: Object.keys(storage.segments.segmentCache).reduce(function (prev, segmentName) {
90
- return storage.segments.segmentCache[segmentName].has(key) ?
91
- prev.concat({ n: segmentName }) :
92
- prev;
93
- }, [])
94
- },
95
- ls: {
96
- k: []
97
- }
98
- };
99
- }
100
- return prev;
101
- }, {}) :
102
- undefined
103
- };
104
- }
@@ -1,55 +0,0 @@
1
- import { isObject, isString, isFiniteNumber } from '../lang';
2
- import { validateSplit } from './split';
3
- function validateTimestampData(log, maybeTimestamp, method, item) {
4
- if (isFiniteNumber(maybeTimestamp) && maybeTimestamp > -1)
5
- return true;
6
- log.error(method + ": preloadedData." + item + " must be a positive number.");
7
- return false;
8
- }
9
- function validateSplitsData(log, maybeSplitsData, method) {
10
- if (isObject(maybeSplitsData)) {
11
- var splitNames = Object.keys(maybeSplitsData);
12
- if (splitNames.length === 0)
13
- log.warn(method + ": preloadedData.splitsData doesn't contain feature flag definitions.");
14
- // @TODO in the future, consider handling the possibility of having parsed definitions of splits
15
- if (splitNames.every(function (splitName) { return validateSplit(log, splitName, method) && isString(maybeSplitsData[splitName]); }))
16
- return true;
17
- }
18
- log.error(method + ": preloadedData.splitsData must be a map of feature flag names to their stringified definitions.");
19
- return false;
20
- }
21
- function validateMySegmentsData(log, maybeMySegmentsData, method) {
22
- if (isObject(maybeMySegmentsData)) {
23
- var userKeys = Object.keys(maybeMySegmentsData);
24
- if (userKeys.every(function (userKey) {
25
- var segmentNames = maybeMySegmentsData[userKey];
26
- // an empty list is valid
27
- return Array.isArray(segmentNames) && segmentNames.every(function (segmentName) { return isString(segmentName); });
28
- }))
29
- return true;
30
- }
31
- log.error(method + ": preloadedData.mySegmentsData must be a map of user keys to their list of segment names.");
32
- return false;
33
- }
34
- function validateSegmentsData(log, maybeSegmentsData, method) {
35
- if (isObject(maybeSegmentsData)) {
36
- var segmentNames = Object.keys(maybeSegmentsData);
37
- if (segmentNames.every(function (segmentName) { return isString(maybeSegmentsData[segmentName]); }))
38
- return true;
39
- }
40
- log.error(method + ": preloadedData.segmentsData must be a map of segment names to their stringified definitions.");
41
- return false;
42
- }
43
- export function validatePreloadedData(log, maybePreloadedData, method) {
44
- if (!isObject(maybePreloadedData)) {
45
- log.error(method + ": preloadedData must be an object.");
46
- }
47
- else if (validateTimestampData(log, maybePreloadedData.lastUpdated, method, 'lastUpdated') &&
48
- validateTimestampData(log, maybePreloadedData.since, method, 'since') &&
49
- validateSplitsData(log, maybePreloadedData.splitsData, method) &&
50
- (!maybePreloadedData.mySegmentsData || validateMySegmentsData(log, maybePreloadedData.mySegmentsData, method)) &&
51
- (!maybePreloadedData.segmentsData || validateSegmentsData(log, maybePreloadedData.segmentsData, method))) {
52
- return true;
53
- }
54
- return false;
55
- }
@@ -1,113 +0,0 @@
1
- import SplitIO from '../../types/splitio';
2
- import { IRBSegmentsCacheSync, ISegmentsCacheSync, ISplitsCacheSync, IStorageSync } from './types';
3
- import { setToArray } from '../utils/lang/sets';
4
- import { getMatching } from '../utils/key';
5
- import { IMembershipsResponse, IMySegmentsResponse, IRBSegment, ISplit } from '../dtos/types';
6
- import { ILogger } from '../logger/types';
7
-
8
- /**
9
- * Sets the given synchronous storage with the provided preloaded data snapshot.
10
- * If `matchingKey` is provided, the storage is handled as a client-side storage (segments and largeSegments are instances of MySegmentsCache).
11
- * Otherwise, the storage is handled as a server-side storage (segments is an instance of SegmentsCache).
12
- */
13
- export function setCache(log: ILogger, preloadedData: SplitIO.PreloadedData, storage: { splits?: ISplitsCacheSync, rbSegments?: IRBSegmentsCacheSync, segments: ISegmentsCacheSync, largeSegments?: ISegmentsCacheSync }, matchingKey?: string) {
14
- // Do not load data if current preloadedData is empty
15
- if (Object.keys(preloadedData).length === 0) return;
16
-
17
- const { splits, rbSegments, segments, largeSegments } = storage;
18
-
19
- log.debug(`set cache${matchingKey ? ` for key ${matchingKey}` : ''}`);
20
-
21
- if (splits) {
22
- splits.clear();
23
- splits.update(preloadedData.flags as ISplit[] || [], [], preloadedData.since || -1);
24
- }
25
-
26
- if (rbSegments) {
27
- rbSegments.clear();
28
- rbSegments.update(preloadedData.rbSegments as IRBSegment[] || [], [], preloadedData.rbSince || -1);
29
- }
30
-
31
- const segmentsData = preloadedData.segments || {};
32
- if (matchingKey) { // add memberships data (client-side)
33
- let memberships = preloadedData.memberships && preloadedData.memberships[matchingKey];
34
- if (!memberships && segmentsData) {
35
- memberships = {
36
- ms: {
37
- k: Object.keys(segmentsData).filter(segmentName => {
38
- const segmentKeys = segmentsData[segmentName];
39
- return segmentKeys.indexOf(matchingKey) > -1;
40
- }).map(segmentName => ({ n: segmentName }))
41
- }
42
- };
43
- }
44
-
45
- if (memberships) {
46
- if ((memberships as IMembershipsResponse).ms) segments.resetSegments((memberships as IMembershipsResponse).ms!);
47
- if ((memberships as IMembershipsResponse).ls && largeSegments) largeSegments.resetSegments((memberships as IMembershipsResponse).ls!);
48
- }
49
- } else { // add segments data (server-side)
50
- Object.keys(segmentsData).forEach(segmentName => {
51
- const segmentKeys = segmentsData[segmentName];
52
- segments.update(segmentName, segmentKeys, [], -1);
53
- });
54
- }
55
- }
56
-
57
- /**
58
- * Gets the preloaded data snapshot from the given synchronous storage.
59
- * If `keys` are provided, the memberships for those keys is returned, to protect segments data.
60
- * Otherwise, the segments data is returned.
61
- */
62
- export function getCache(log: ILogger, storage: IStorageSync, keys?: SplitIO.SplitKey[]): SplitIO.PreloadedData {
63
-
64
- log.debug(`get cache${keys ? ` for keys ${keys}` : ''}`);
65
-
66
- return {
67
- since: storage.splits.getChangeNumber(),
68
- flags: storage.splits.getAll(),
69
- rbSince: storage.rbSegments.getChangeNumber(),
70
- rbSegments: storage.rbSegments.getAll(),
71
- segments: keys ?
72
- undefined : // @ts-ignore accessing private prop
73
- Object.keys(storage.segments.segmentCache).reduce((prev, cur) => { // @ts-ignore accessing private prop
74
- prev[cur] = setToArray(storage.segments.segmentCache[cur] as Set<string>);
75
- return prev;
76
- }, {}),
77
- memberships: keys ?
78
- keys.reduce<Record<string, IMembershipsResponse>>((prev, key) => {
79
- if (storage.shared) {
80
- // Client-side segments
81
- // @ts-ignore accessing private prop
82
- const sharedStorage = storage.shared(key);
83
- prev[getMatching(key)] = {
84
- ms: {
85
- // @ts-ignore accessing private prop
86
- k: Object.keys(sharedStorage.segments.segmentCache).map(segmentName => ({ n: segmentName })),
87
- },
88
- ls: sharedStorage.largeSegments ? {
89
- // @ts-ignore accessing private prop
90
- k: Object.keys(sharedStorage.largeSegments.segmentCache).map(segmentName => ({ n: segmentName })),
91
- } : undefined
92
- };
93
- } else {
94
- prev[getMatching(key)] = {
95
- ms: {
96
- // Server-side segments
97
- // @ts-ignore accessing private prop
98
- k: Object.keys(storage.segments.segmentCache).reduce<IMySegmentsResponse['k']>((prev, segmentName) => { // @ts-ignore accessing private prop
99
- return storage.segments.segmentCache[segmentName].has(key) ?
100
- prev!.concat({ n: segmentName }) :
101
- prev;
102
- }, [])
103
- },
104
- ls: {
105
- k: []
106
- }
107
- };
108
- }
109
- return prev;
110
- }, {}) :
111
- undefined
112
- };
113
- }
@@ -1,57 +0,0 @@
1
- import { isObject, isString, isFiniteNumber } from '../lang';
2
- import { validateSplit } from './split';
3
- import { ILogger } from '../../logger/types';
4
-
5
- function validateTimestampData(log: ILogger, maybeTimestamp: any, method: string, item: string) {
6
- if (isFiniteNumber(maybeTimestamp) && maybeTimestamp > -1) return true;
7
- log.error(`${method}: preloadedData.${item} must be a positive number.`);
8
- return false;
9
- }
10
-
11
- function validateSplitsData(log: ILogger, maybeSplitsData: any, method: string) {
12
- if (isObject(maybeSplitsData)) {
13
- const splitNames = Object.keys(maybeSplitsData);
14
- if (splitNames.length === 0) log.warn(`${method}: preloadedData.splitsData doesn't contain feature flag definitions.`);
15
- // @TODO in the future, consider handling the possibility of having parsed definitions of splits
16
- if (splitNames.every(splitName => validateSplit(log, splitName, method) && isString(maybeSplitsData[splitName]))) return true;
17
- }
18
- log.error(`${method}: preloadedData.splitsData must be a map of feature flag names to their stringified definitions.`);
19
- return false;
20
- }
21
-
22
- function validateMySegmentsData(log: ILogger, maybeMySegmentsData: any, method: string) {
23
- if (isObject(maybeMySegmentsData)) {
24
- const userKeys = Object.keys(maybeMySegmentsData);
25
- if (userKeys.every(userKey => {
26
- const segmentNames = maybeMySegmentsData[userKey];
27
- // an empty list is valid
28
- return Array.isArray(segmentNames) && segmentNames.every(segmentName => isString(segmentName));
29
- })) return true;
30
- }
31
- log.error(`${method}: preloadedData.mySegmentsData must be a map of user keys to their list of segment names.`);
32
- return false;
33
- }
34
-
35
- function validateSegmentsData(log: ILogger, maybeSegmentsData: any, method: string) {
36
- if (isObject(maybeSegmentsData)) {
37
- const segmentNames = Object.keys(maybeSegmentsData);
38
- if (segmentNames.every(segmentName => isString(maybeSegmentsData[segmentName]))) return true;
39
- }
40
- log.error(`${method}: preloadedData.segmentsData must be a map of segment names to their stringified definitions.`);
41
- return false;
42
- }
43
-
44
- export function validatePreloadedData(log: ILogger, maybePreloadedData: any, method: string) {
45
- if (!isObject(maybePreloadedData)) {
46
- log.error(`${method}: preloadedData must be an object.`);
47
- } else if (
48
- validateTimestampData(log, maybePreloadedData.lastUpdated, method, 'lastUpdated') &&
49
- validateTimestampData(log, maybePreloadedData.since, method, 'since') &&
50
- validateSplitsData(log, maybePreloadedData.splitsData, method) &&
51
- (!maybePreloadedData.mySegmentsData || validateMySegmentsData(log, maybePreloadedData.mySegmentsData, method)) &&
52
- (!maybePreloadedData.segmentsData || validateSegmentsData(log, maybePreloadedData.segmentsData, method))
53
- ) {
54
- return true;
55
- }
56
- return false;
57
- }