@splitsoftware/splitio-commons 1.5.0 → 1.5.1-rc.2
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 +5 -0
- package/cjs/listeners/browser.js +35 -15
- package/cjs/services/splitApi.js +4 -4
- package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +5 -5
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +2 -2
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +34 -34
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +4 -3
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +46 -46
- package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +82 -64
- package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +74 -58
- package/cjs/sync/streaming/UpdateWorkers/constants.js +6 -0
- package/cjs/sync/streaming/pushManager.js +6 -7
- package/cjs/sync/syncTask.js +13 -16
- package/cjs/utils/Backoff.js +3 -2
- package/esm/listeners/browser.js +35 -15
- package/esm/services/splitApi.js +4 -4
- package/esm/sync/polling/fetchers/segmentChangesFetcher.js +5 -5
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +2 -2
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +34 -34
- package/esm/sync/polling/updaters/splitChangesUpdater.js +4 -3
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +46 -47
- package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +82 -65
- package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +74 -59
- package/esm/sync/streaming/UpdateWorkers/constants.js +3 -0
- package/esm/sync/streaming/pushManager.js +6 -7
- package/esm/sync/syncTask.js +13 -16
- package/esm/utils/Backoff.js +3 -2
- package/package.json +1 -5
- package/src/listeners/browser.ts +34 -14
- package/src/logger/.DS_Store +0 -0
- package/src/services/splitApi.ts +4 -4
- package/src/services/types.ts +2 -2
- package/src/sync/polling/fetchers/segmentChangesFetcher.ts +5 -4
- package/src/sync/polling/fetchers/splitChangesFetcher.ts +2 -1
- package/src/sync/polling/fetchers/types.ts +2 -0
- package/src/sync/polling/pollingManagerCS.ts +5 -5
- package/src/sync/polling/syncTasks/mySegmentsSyncTask.ts +2 -2
- package/src/sync/polling/types.ts +14 -6
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +4 -4
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +34 -32
- package/src/sync/polling/updaters/splitChangesUpdater.ts +5 -4
- package/src/sync/streaming/SSEHandler/types.ts +0 -7
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +45 -54
- package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +78 -63
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +73 -61
- package/src/sync/streaming/UpdateWorkers/constants.ts +3 -0
- package/src/sync/streaming/UpdateWorkers/types.ts +2 -4
- package/src/sync/streaming/pushManager.ts +12 -12
- package/src/sync/streaming/types.ts +2 -2
- package/src/sync/syncTask.ts +16 -18
- package/src/utils/Backoff.ts +7 -2
- package/types/integrations/ga/GaToSplitPlugin.d.ts +3 -0
- package/types/integrations/ga/SplitToGaPlugin.d.ts +4 -0
- package/types/integrations/ga/autoRequire.d.ts +4 -0
- package/types/listeners/browser.d.ts +6 -6
- package/types/logger/browser/{DebugLogger.d.ts → debugLogger.d.ts} +0 -0
- package/types/logger/browser/{ErrorLogger.d.ts → errorLogger.d.ts} +0 -0
- package/types/logger/browser/{InfoLogger.d.ts → infoLogger.d.ts} +0 -0
- package/types/logger/browser/{WarnLogger.d.ts → warnLogger.d.ts} +0 -0
- package/types/logger/codes.d.ts +2 -0
- package/types/logger/codesConstants.d.ts +117 -0
- package/types/logger/codesConstantsBrowser.d.ts +2 -0
- package/types/logger/codesConstantsNode.d.ts +14 -0
- package/types/logger/codesDebug.d.ts +1 -0
- package/types/logger/codesDebugBrowser.d.ts +1 -0
- package/types/logger/codesDebugNode.d.ts +1 -0
- package/types/logger/codesError.d.ts +1 -0
- package/types/logger/codesErrorNode.d.ts +1 -0
- package/types/logger/codesInfo.d.ts +1 -0
- package/types/logger/codesWarn.d.ts +1 -0
- package/types/logger/codesWarnNode.d.ts +1 -0
- package/types/logger/debugLogger.d.ts +2 -0
- package/types/logger/errorLogger.d.ts +2 -0
- package/types/logger/infoLogger.d.ts +2 -0
- package/types/logger/messages/debugBrowser.d.ts +1 -0
- package/types/logger/messages/debugNode.d.ts +1 -0
- package/types/logger/messages/errorNode.d.ts +1 -0
- package/types/logger/messages/warnNode.d.ts +1 -0
- package/types/logger/noopLogger.d.ts +2 -0
- package/types/logger/warnLogger.d.ts +2 -0
- package/types/sdkFactory/userConsentProps.d.ts +6 -0
- package/types/sdkManager/sdkManagerMethod.d.ts +6 -0
- package/types/services/types.d.ts +2 -2
- package/types/storages/getRegisteredSegments.d.ts +10 -0
- package/types/storages/inMemory/index.d.ts +10 -0
- package/types/storages/parseSegments.d.ts +6 -0
- package/types/sync/polling/fetchers/types.d.ts +2 -2
- package/types/sync/polling/syncTasks/mySegmentsSyncTask.d.ts +2 -2
- package/types/sync/polling/syncTasks/splitsSyncTask.copy.d.ts +35 -0
- package/types/sync/polling/syncTasks/splitsSyncTask.morelikeoriginal.d.ts +35 -0
- package/types/sync/polling/types.d.ts +11 -6
- package/types/sync/polling/updaters/segmentChangesUpdater.d.ts +1 -1
- package/types/sync/polling/updaters/splitChangesUpdater.d.ts +1 -1
- package/types/sync/streaming/AuthClient/indexV1.d.ts +12 -0
- package/types/sync/streaming/AuthClient/indexV2.d.ts +8 -0
- package/types/sync/streaming/SSEHandler/types.d.ts +0 -4
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +3 -24
- package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +3 -23
- package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +6 -33
- package/types/sync/streaming/UpdateWorkers/constants.d.ts +3 -0
- package/types/sync/streaming/UpdateWorkers/types.d.ts +1 -2
- package/types/sync/streaming/pushManagerCS.d.ts +1 -0
- package/types/sync/streaming/pushManagerNoUsers.d.ts +13 -0
- package/types/sync/streaming/pushManagerSS.d.ts +1 -0
- package/types/sync/streaming/types.d.ts +2 -2
- package/types/sync/submitters/telemetrySyncTask.d.ts +0 -0
- package/types/sync/syncManagerFromFile.d.ts +2 -0
- package/types/sync/syncManagerFromObject.d.ts +2 -0
- package/types/sync/syncManagerOffline.d.ts +9 -0
- package/types/sync/syncTask.d.ts +2 -3
- package/types/trackers/telemetryRecorder.d.ts +0 -0
- package/types/utils/Backoff.d.ts +2 -0
- package/types/utils/EventEmitter.d.ts +4 -0
- package/types/utils/consent.d.ts +2 -0
- package/types/utils/lang/errors.d.ts +10 -0
- package/types/utils/murmur3/commons.d.ts +12 -0
- package/types/utils/settingsValidation/buildMetadata.d.ts +3 -0
- package/types/utils/settingsValidation/localhost/index.d.ts +9 -0
- package/types/utils/settingsValidation/logger.d.ts +11 -0
- package/types/utils/settingsValidation/runtime/browser.d.ts +2 -0
- package/types/utils/settingsValidation/runtime/node.d.ts +2 -0
- package/types/utils/settingsValidation/userConsent.d.ts +5 -0
- package/types/utils/timeTracker/index.d.ts +1 -70
- package/cjs/sync/offline/LocalhostFromFile.js +0 -13
- package/cjs/sync/offline/splitsParser/splitsParserFromFile.js +0 -151
- package/esm/sync/offline/LocalhostFromFile.js +0 -9
- package/esm/sync/offline/splitsParser/splitsParserFromFile.js +0 -146
- package/src/sync/offline/LocalhostFromFile.ts +0 -12
- package/src/sync/offline/splitsParser/splitsParserFromFile.ts +0 -182
package/types/sync/syncTask.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { ILogger } from '../logger/types';
|
|
2
2
|
import { ISyncTask } from './types';
|
|
3
3
|
/**
|
|
4
|
-
* Creates
|
|
5
|
-
* The task can be also executed by calling the "execute" method. Multiple
|
|
6
|
-
* For example, submitters executed on SDK destroy or full queue, while periodic execution is pending.
|
|
4
|
+
* Creates an object that handles the periodic execution of a given task via "start" and "stop" methods.
|
|
5
|
+
* The task can be also executed by calling the "execute" method. Multiple calls run sequentially to avoid race conditions (e.g., submitters executed on SDK destroy or full queue, while periodic execution is pending).
|
|
7
6
|
*
|
|
8
7
|
* @param log Logger instance.
|
|
9
8
|
* @param task Task to execute that returns a promise that NEVER REJECTS. Otherwise, periodic execution can result in Unhandled Promise Rejections.
|
|
File without changes
|
package/types/utils/Backoff.d.ts
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare class SplitError extends Error {
|
|
2
|
+
constructor(msg?: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class SplitTimeoutError extends SplitError {
|
|
5
|
+
constructor(msg?: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class SplitNetworkError extends SplitError {
|
|
8
|
+
statusCode?: number;
|
|
9
|
+
constructor(msg?: string, code?: number);
|
|
10
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function UTF16ToUTF8(key: string): string | undefined;
|
|
2
|
+
/*!
|
|
3
|
+
* +----------------------------------------------------------------------------------+
|
|
4
|
+
* | murmurHash3.js v3.0.0 (http://github.com/karanlyons/murmurHash3.js) |
|
|
5
|
+
* | A TypeScript/JavaScript implementation of MurmurHash3's hashing algorithms. |
|
|
6
|
+
* |----------------------------------------------------------------------------------|
|
|
7
|
+
* | Copyright (c) 2012-2020 Karan Lyons. Freely distributable under the MIT license. |
|
|
8
|
+
* +----------------------------------------------------------------------------------+
|
|
9
|
+
*/
|
|
10
|
+
export declare function x86Multiply(m: number, n: number): number;
|
|
11
|
+
export declare function x86Rotl(m: number, n: number): number;
|
|
12
|
+
export declare function x86Fmix(h: number): number;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ISettings } from '../../../types';
|
|
2
|
+
/**
|
|
3
|
+
* This function validates `settings.storage` object
|
|
4
|
+
*
|
|
5
|
+
* @param {any} settings config object provided by the user to initialize the sdk
|
|
6
|
+
*
|
|
7
|
+
* @returns {Object} valid storage factory. It might be the default `InMemoryStorageCSFactory` if the provided storage is invalid.
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateLocalhost(settings: ISettings): import("../../../types").SplitIO.LocalhostFactory | undefined;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ILogger } from '../../logger/types';
|
|
2
|
+
/**
|
|
3
|
+
* Validates the `log` (logger) property at config.
|
|
4
|
+
*
|
|
5
|
+
* @param settings user config object
|
|
6
|
+
* @returns the provided logger or a no-op logger if no one is provided
|
|
7
|
+
* @throws throws an error if a logger was provided but is invalid
|
|
8
|
+
*/
|
|
9
|
+
export default function logger(settings: {
|
|
10
|
+
log: unknown;
|
|
11
|
+
}): ILogger;
|
|
@@ -1,70 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { IResponse } from '../../services/types';
|
|
3
|
-
interface MetricsCollector {
|
|
4
|
-
countException(): void;
|
|
5
|
-
count(status: number): void;
|
|
6
|
-
latency(ms: number): void;
|
|
7
|
-
ready(ms: number): void;
|
|
8
|
-
getTreatment(ms: number): void;
|
|
9
|
-
getTreatments(ms: number): void;
|
|
10
|
-
getTreatmentWithConfig(ms: number): void;
|
|
11
|
-
getTreatmentsWithConfig(ms: number): void;
|
|
12
|
-
[method: string]: (ms: number) => void;
|
|
13
|
-
}
|
|
14
|
-
export declare const TrackerAPI: {
|
|
15
|
-
/**
|
|
16
|
-
* "Private" method, used to attach count/countException and stop callbacks to a promise.
|
|
17
|
-
*
|
|
18
|
-
* @param {ILogger} log - Logger.
|
|
19
|
-
* @param {Promise} promise - The promise we want to attach the callbacks.
|
|
20
|
-
* @param {string} task - The name of the task.
|
|
21
|
-
* @param {number | string} modifier - (optional) The modifier for the task, if any.
|
|
22
|
-
*/
|
|
23
|
-
__attachToPromise(log: ILogger, promise: Promise<IResponse>, task: string, collector: false | MetricsCollector, modifier?: string | number | undefined): Promise<IResponse>;
|
|
24
|
-
/**
|
|
25
|
-
* Starts tracking the time for a given task. All tasks tracked are considered "unique" because
|
|
26
|
-
* there may be multiple SDK instances tracking a "generic" task, making any task non-generic.
|
|
27
|
-
*
|
|
28
|
-
* @param {ILogger} log - Logger.
|
|
29
|
-
* @param {string} task - The task we are starting.
|
|
30
|
-
* @param {Object} collectors - The collectors map.
|
|
31
|
-
* @param {Promise} promise - (optional) The promise we are tracking.
|
|
32
|
-
* @return {Function | Promise} The stop function for this specific task or the promise received with the callbacks registered.
|
|
33
|
-
*/
|
|
34
|
-
start(log: ILogger, task: string, collectors?: Record<string, MetricsCollector> | undefined, promise?: Promise<IResponse> | undefined, now?: (() => number) | undefined): Promise<IResponse> | (() => number);
|
|
35
|
-
/**
|
|
36
|
-
* Setup the collector for a task that reports metrics.
|
|
37
|
-
*
|
|
38
|
-
* @param {string} task - The task name
|
|
39
|
-
* @param {number | string} taskUniqueId - The unique identifier for this task
|
|
40
|
-
* @param {Object} collectors - The collectors map.
|
|
41
|
-
*/
|
|
42
|
-
setCollectorForTask(task: string, taskUniqueId: number | string, collectors: Record<string, MetricsCollector>): void;
|
|
43
|
-
/**
|
|
44
|
-
* Stops the tracking of a given task.
|
|
45
|
-
*
|
|
46
|
-
* @param {ILogger} log - Logger.
|
|
47
|
-
* @param {string} task - The task we are starting.
|
|
48
|
-
* @param {number | string} modifier - (optional) The modifier for that specific task.
|
|
49
|
-
*/
|
|
50
|
-
stop(log: ILogger, task: string, modifier?: string | number | undefined): number | undefined;
|
|
51
|
-
/**
|
|
52
|
-
* The constants shortcut for the task names.
|
|
53
|
-
*/
|
|
54
|
-
TaskNames: {
|
|
55
|
-
SDK_READY: string;
|
|
56
|
-
SDK_GET_TREATMENT: string;
|
|
57
|
-
SDK_GET_TREATMENTS: string;
|
|
58
|
-
SDK_GET_TREATMENT_WITH_CONFIG: string;
|
|
59
|
-
SDK_GET_TREATMENTS_WITH_CONFIG: string;
|
|
60
|
-
SPLITS_READY: string;
|
|
61
|
-
SEGMENTS_READY: string;
|
|
62
|
-
METRICS_PUSH: string;
|
|
63
|
-
IMPRESSIONS_PUSH: string;
|
|
64
|
-
EVENTS_PUSH: string;
|
|
65
|
-
MY_SEGMENTS_FETCH: string;
|
|
66
|
-
SEGMENTS_FETCH: string;
|
|
67
|
-
SPLITS_FETCH: string;
|
|
68
|
-
};
|
|
69
|
-
};
|
|
70
|
-
export {};
|
|
1
|
+
export declare function timeTracker(now: () => number): () => () => number;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LocalhostFromFile = void 0;
|
|
4
|
-
var splitsParserFromFile_1 = require("./splitsParser/splitsParserFromFile");
|
|
5
|
-
var syncManagerOffline_1 = require("./syncManagerOffline");
|
|
6
|
-
// Singleton instance of the factory function for offline SyncManager from YAML file (a.k.a. localhostFromFile)
|
|
7
|
-
// Requires Node 'fs' and 'path' APIs.
|
|
8
|
-
var localhostFromFile = (0, syncManagerOffline_1.syncManagerOfflineFactory)(splitsParserFromFile_1.splitsParserFromFileFactory);
|
|
9
|
-
localhostFromFile.type = 'LocalhostFromFile';
|
|
10
|
-
function LocalhostFromFile() {
|
|
11
|
-
return localhostFromFile;
|
|
12
|
-
}
|
|
13
|
-
exports.LocalhostFromFile = LocalhostFromFile;
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.splitsParserFromFileFactory = void 0;
|
|
4
|
-
var tslib_1 = require("tslib");
|
|
5
|
-
/* eslint-disable no-undef */
|
|
6
|
-
// @TODO consider moving it to Node-SDK and remove js-yaml dependency from Js-commons
|
|
7
|
-
var fs_1 = (0, tslib_1.__importDefault)(require("fs"));
|
|
8
|
-
var path_1 = (0, tslib_1.__importDefault)(require("path"));
|
|
9
|
-
// @ts-ignore
|
|
10
|
-
var js_yaml_1 = (0, tslib_1.__importDefault)(require("js-yaml"));
|
|
11
|
-
var lang_1 = require("../../../utils/lang");
|
|
12
|
-
var parseCondition_1 = require("./parseCondition");
|
|
13
|
-
var logPrefix = 'sync:offline:splits-fetcher: ';
|
|
14
|
-
var DEFAULT_FILENAME = '.split';
|
|
15
|
-
function configFilesPath(configFilePath) {
|
|
16
|
-
if (configFilePath === DEFAULT_FILENAME || !(0, lang_1.isString)(configFilePath)) {
|
|
17
|
-
var root = process.env.HOME;
|
|
18
|
-
if (process.env.SPLIT_CONFIG_ROOT)
|
|
19
|
-
root = process.env.SPLIT_CONFIG_ROOT;
|
|
20
|
-
if (!root)
|
|
21
|
-
throw new Error('Missing split mock configuration root.');
|
|
22
|
-
configFilePath = path_1.default.join(root, DEFAULT_FILENAME);
|
|
23
|
-
}
|
|
24
|
-
// Validate the extensions
|
|
25
|
-
if (!((0, lang_1.endsWith)(configFilePath, '.yaml', true) || (0, lang_1.endsWith)(configFilePath, '.yml', true) || (0, lang_1.endsWith)(configFilePath, '.split', true)))
|
|
26
|
-
throw new Error("Invalid extension specified for Splits mock file. Accepted extensions are \".yml\" and \".yaml\". Your specified file is " + configFilePath);
|
|
27
|
-
if (!fs_1.default.existsSync(configFilePath))
|
|
28
|
-
throw new Error("Split configuration not found in " + configFilePath + " - Please review your Split file location.");
|
|
29
|
-
return configFilePath;
|
|
30
|
-
}
|
|
31
|
-
// This function is not pure nor meant to be. Here we apply modifications to cover
|
|
32
|
-
// for behaviour that's ensured by the BE.
|
|
33
|
-
function arrangeConditions(mocksData) {
|
|
34
|
-
// Iterate through each Split data
|
|
35
|
-
(0, lang_1.forOwn)(mocksData, function (data) {
|
|
36
|
-
var conditions = data.conditions;
|
|
37
|
-
// On the manager, as the split jsons come with all treatments on the partitions prop,
|
|
38
|
-
// we'll add all the treatments to the first condition.
|
|
39
|
-
var firstRolloutCondition = (0, lang_1.find)(conditions, function (cond) { return cond.conditionType === 'ROLLOUT'; });
|
|
40
|
-
// Malformed mocks may have
|
|
41
|
-
var treatments = (0, lang_1.uniq)(data.treatments);
|
|
42
|
-
// If they're only specifying a whitelist we add the treatments there.
|
|
43
|
-
var allTreatmentsCondition = firstRolloutCondition ? firstRolloutCondition : conditions[0];
|
|
44
|
-
var fullyAllocatedTreatment = allTreatmentsCondition.partitions[0].treatment;
|
|
45
|
-
treatments.forEach(function (treatment) {
|
|
46
|
-
if (treatment !== fullyAllocatedTreatment) {
|
|
47
|
-
allTreatmentsCondition.partitions.push({
|
|
48
|
-
treatment: treatment,
|
|
49
|
-
size: 0
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
// Don't need these anymore
|
|
54
|
-
// @ts-expect-error
|
|
55
|
-
delete data.treatments;
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
function splitsParserFromFileFactory() {
|
|
59
|
-
var previousMock = 'NO_MOCK_LOADED';
|
|
60
|
-
// Parse `.split` configuration file and return a map of "Split Objects"
|
|
61
|
-
function readSplitConfigFile(log, filePath) {
|
|
62
|
-
var SPLIT_POSITION = 0;
|
|
63
|
-
var TREATMENT_POSITION = 1;
|
|
64
|
-
var data;
|
|
65
|
-
try {
|
|
66
|
-
data = fs_1.default.readFileSync(filePath, 'utf-8');
|
|
67
|
-
}
|
|
68
|
-
catch (e) {
|
|
69
|
-
log.error(e && e.message);
|
|
70
|
-
return {};
|
|
71
|
-
}
|
|
72
|
-
if (data === previousMock)
|
|
73
|
-
return false;
|
|
74
|
-
previousMock = data;
|
|
75
|
-
var splitObjects = data.split(/\r?\n/).reduce(function (accum, line, index) {
|
|
76
|
-
var tuple = line.trim();
|
|
77
|
-
if (tuple === '' || tuple.charAt(0) === '#') {
|
|
78
|
-
log.debug(logPrefix + ("Ignoring empty line or comment at #" + index));
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
tuple = tuple.split(/\s+/);
|
|
82
|
-
if (tuple.length !== 2) {
|
|
83
|
-
log.debug(logPrefix + ("Ignoring line since it does not have exactly two columns #" + index));
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
var splitName = tuple[SPLIT_POSITION];
|
|
87
|
-
var condition = (0, parseCondition_1.parseCondition)({ treatment: tuple[TREATMENT_POSITION] });
|
|
88
|
-
accum[splitName] = { conditions: [condition], configurations: {}, trafficTypeName: 'localhost' };
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return accum;
|
|
92
|
-
}, {});
|
|
93
|
-
return splitObjects;
|
|
94
|
-
}
|
|
95
|
-
// Parse `.yml` or `.yaml` configuration files and return a map of "Split Objects"
|
|
96
|
-
function readYAMLConfigFile(log, filePath) {
|
|
97
|
-
var data = '';
|
|
98
|
-
var yamldoc = null;
|
|
99
|
-
try {
|
|
100
|
-
data = fs_1.default.readFileSync(filePath, 'utf8');
|
|
101
|
-
if (data === previousMock)
|
|
102
|
-
return false;
|
|
103
|
-
previousMock = data;
|
|
104
|
-
yamldoc = js_yaml_1.default.safeLoad(data);
|
|
105
|
-
}
|
|
106
|
-
catch (e) {
|
|
107
|
-
log.error(e);
|
|
108
|
-
return {};
|
|
109
|
-
}
|
|
110
|
-
// Each entry will be mapped to a condition, but we'll also keep the configurations map.
|
|
111
|
-
var mocksData = yamldoc.reduce(function (accum, splitEntry) {
|
|
112
|
-
var splitName = Object.keys(splitEntry)[0];
|
|
113
|
-
if (!splitName || !(0, lang_1.isString)(splitEntry[splitName].treatment))
|
|
114
|
-
log.error(logPrefix + 'Ignoring entry on YAML since the format is incorrect.');
|
|
115
|
-
var mockData = splitEntry[splitName];
|
|
116
|
-
// "Template" for each split accumulated data
|
|
117
|
-
if (!accum[splitName]) {
|
|
118
|
-
accum[splitName] = {
|
|
119
|
-
configurations: {}, conditions: [], treatments: [], trafficTypeName: 'localhost'
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
// Assign the config if there is one on the mock
|
|
123
|
-
if (mockData.config)
|
|
124
|
-
accum[splitName].configurations[mockData.treatment] = mockData.config;
|
|
125
|
-
// Parse the condition from the entry.
|
|
126
|
-
var condition = (0, parseCondition_1.parseCondition)(mockData);
|
|
127
|
-
accum[splitName].conditions[condition.conditionType === 'ROLLOUT' ? 'push' : 'unshift'](condition);
|
|
128
|
-
// Also keep track of the treatments, will be useful for manager functionality.
|
|
129
|
-
accum[splitName].treatments.push(mockData.treatment);
|
|
130
|
-
return accum;
|
|
131
|
-
}, {});
|
|
132
|
-
arrangeConditions(mocksData);
|
|
133
|
-
return mocksData;
|
|
134
|
-
}
|
|
135
|
-
// Load the content of a configuration file into an Object
|
|
136
|
-
return function splitsParserFromFile(_a) {
|
|
137
|
-
var features = _a.features, log = _a.log;
|
|
138
|
-
var filePath = configFilesPath(features);
|
|
139
|
-
var mockData;
|
|
140
|
-
// If we have a filePath, it means the extension is correct, choose the parser.
|
|
141
|
-
if ((0, lang_1.endsWith)(filePath, '.split')) {
|
|
142
|
-
log.warn(logPrefix + '.split mocks will be deprecated soon in favor of YAML files, which provide more targeting power. Take a look in our documentation.');
|
|
143
|
-
mockData = readSplitConfigFile(log, filePath);
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
mockData = readYAMLConfigFile(log, filePath);
|
|
147
|
-
}
|
|
148
|
-
return mockData;
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
exports.splitsParserFromFileFactory = splitsParserFromFileFactory;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { splitsParserFromFileFactory } from './splitsParser/splitsParserFromFile';
|
|
2
|
-
import { syncManagerOfflineFactory } from './syncManagerOffline';
|
|
3
|
-
// Singleton instance of the factory function for offline SyncManager from YAML file (a.k.a. localhostFromFile)
|
|
4
|
-
// Requires Node 'fs' and 'path' APIs.
|
|
5
|
-
var localhostFromFile = syncManagerOfflineFactory(splitsParserFromFileFactory);
|
|
6
|
-
localhostFromFile.type = 'LocalhostFromFile';
|
|
7
|
-
export function LocalhostFromFile() {
|
|
8
|
-
return localhostFromFile;
|
|
9
|
-
}
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-undef */
|
|
2
|
-
// @TODO consider moving it to Node-SDK and remove js-yaml dependency from Js-commons
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
// @ts-ignore
|
|
6
|
-
import yaml from 'js-yaml';
|
|
7
|
-
import { isString, endsWith, find, forOwn, uniq, } from '../../../utils/lang';
|
|
8
|
-
import { parseCondition } from './parseCondition';
|
|
9
|
-
var logPrefix = 'sync:offline:splits-fetcher: ';
|
|
10
|
-
var DEFAULT_FILENAME = '.split';
|
|
11
|
-
function configFilesPath(configFilePath) {
|
|
12
|
-
if (configFilePath === DEFAULT_FILENAME || !isString(configFilePath)) {
|
|
13
|
-
var root = process.env.HOME;
|
|
14
|
-
if (process.env.SPLIT_CONFIG_ROOT)
|
|
15
|
-
root = process.env.SPLIT_CONFIG_ROOT;
|
|
16
|
-
if (!root)
|
|
17
|
-
throw new Error('Missing split mock configuration root.');
|
|
18
|
-
configFilePath = path.join(root, DEFAULT_FILENAME);
|
|
19
|
-
}
|
|
20
|
-
// Validate the extensions
|
|
21
|
-
if (!(endsWith(configFilePath, '.yaml', true) || endsWith(configFilePath, '.yml', true) || endsWith(configFilePath, '.split', true)))
|
|
22
|
-
throw new Error("Invalid extension specified for Splits mock file. Accepted extensions are \".yml\" and \".yaml\". Your specified file is " + configFilePath);
|
|
23
|
-
if (!fs.existsSync(configFilePath))
|
|
24
|
-
throw new Error("Split configuration not found in " + configFilePath + " - Please review your Split file location.");
|
|
25
|
-
return configFilePath;
|
|
26
|
-
}
|
|
27
|
-
// This function is not pure nor meant to be. Here we apply modifications to cover
|
|
28
|
-
// for behaviour that's ensured by the BE.
|
|
29
|
-
function arrangeConditions(mocksData) {
|
|
30
|
-
// Iterate through each Split data
|
|
31
|
-
forOwn(mocksData, function (data) {
|
|
32
|
-
var conditions = data.conditions;
|
|
33
|
-
// On the manager, as the split jsons come with all treatments on the partitions prop,
|
|
34
|
-
// we'll add all the treatments to the first condition.
|
|
35
|
-
var firstRolloutCondition = find(conditions, function (cond) { return cond.conditionType === 'ROLLOUT'; });
|
|
36
|
-
// Malformed mocks may have
|
|
37
|
-
var treatments = uniq(data.treatments);
|
|
38
|
-
// If they're only specifying a whitelist we add the treatments there.
|
|
39
|
-
var allTreatmentsCondition = firstRolloutCondition ? firstRolloutCondition : conditions[0];
|
|
40
|
-
var fullyAllocatedTreatment = allTreatmentsCondition.partitions[0].treatment;
|
|
41
|
-
treatments.forEach(function (treatment) {
|
|
42
|
-
if (treatment !== fullyAllocatedTreatment) {
|
|
43
|
-
allTreatmentsCondition.partitions.push({
|
|
44
|
-
treatment: treatment,
|
|
45
|
-
size: 0
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
// Don't need these anymore
|
|
50
|
-
// @ts-expect-error
|
|
51
|
-
delete data.treatments;
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
export function splitsParserFromFileFactory() {
|
|
55
|
-
var previousMock = 'NO_MOCK_LOADED';
|
|
56
|
-
// Parse `.split` configuration file and return a map of "Split Objects"
|
|
57
|
-
function readSplitConfigFile(log, filePath) {
|
|
58
|
-
var SPLIT_POSITION = 0;
|
|
59
|
-
var TREATMENT_POSITION = 1;
|
|
60
|
-
var data;
|
|
61
|
-
try {
|
|
62
|
-
data = fs.readFileSync(filePath, 'utf-8');
|
|
63
|
-
}
|
|
64
|
-
catch (e) {
|
|
65
|
-
log.error(e && e.message);
|
|
66
|
-
return {};
|
|
67
|
-
}
|
|
68
|
-
if (data === previousMock)
|
|
69
|
-
return false;
|
|
70
|
-
previousMock = data;
|
|
71
|
-
var splitObjects = data.split(/\r?\n/).reduce(function (accum, line, index) {
|
|
72
|
-
var tuple = line.trim();
|
|
73
|
-
if (tuple === '' || tuple.charAt(0) === '#') {
|
|
74
|
-
log.debug(logPrefix + ("Ignoring empty line or comment at #" + index));
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
tuple = tuple.split(/\s+/);
|
|
78
|
-
if (tuple.length !== 2) {
|
|
79
|
-
log.debug(logPrefix + ("Ignoring line since it does not have exactly two columns #" + index));
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
var splitName = tuple[SPLIT_POSITION];
|
|
83
|
-
var condition = parseCondition({ treatment: tuple[TREATMENT_POSITION] });
|
|
84
|
-
accum[splitName] = { conditions: [condition], configurations: {}, trafficTypeName: 'localhost' };
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return accum;
|
|
88
|
-
}, {});
|
|
89
|
-
return splitObjects;
|
|
90
|
-
}
|
|
91
|
-
// Parse `.yml` or `.yaml` configuration files and return a map of "Split Objects"
|
|
92
|
-
function readYAMLConfigFile(log, filePath) {
|
|
93
|
-
var data = '';
|
|
94
|
-
var yamldoc = null;
|
|
95
|
-
try {
|
|
96
|
-
data = fs.readFileSync(filePath, 'utf8');
|
|
97
|
-
if (data === previousMock)
|
|
98
|
-
return false;
|
|
99
|
-
previousMock = data;
|
|
100
|
-
yamldoc = yaml.safeLoad(data);
|
|
101
|
-
}
|
|
102
|
-
catch (e) {
|
|
103
|
-
log.error(e);
|
|
104
|
-
return {};
|
|
105
|
-
}
|
|
106
|
-
// Each entry will be mapped to a condition, but we'll also keep the configurations map.
|
|
107
|
-
var mocksData = yamldoc.reduce(function (accum, splitEntry) {
|
|
108
|
-
var splitName = Object.keys(splitEntry)[0];
|
|
109
|
-
if (!splitName || !isString(splitEntry[splitName].treatment))
|
|
110
|
-
log.error(logPrefix + 'Ignoring entry on YAML since the format is incorrect.');
|
|
111
|
-
var mockData = splitEntry[splitName];
|
|
112
|
-
// "Template" for each split accumulated data
|
|
113
|
-
if (!accum[splitName]) {
|
|
114
|
-
accum[splitName] = {
|
|
115
|
-
configurations: {}, conditions: [], treatments: [], trafficTypeName: 'localhost'
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
// Assign the config if there is one on the mock
|
|
119
|
-
if (mockData.config)
|
|
120
|
-
accum[splitName].configurations[mockData.treatment] = mockData.config;
|
|
121
|
-
// Parse the condition from the entry.
|
|
122
|
-
var condition = parseCondition(mockData);
|
|
123
|
-
accum[splitName].conditions[condition.conditionType === 'ROLLOUT' ? 'push' : 'unshift'](condition);
|
|
124
|
-
// Also keep track of the treatments, will be useful for manager functionality.
|
|
125
|
-
accum[splitName].treatments.push(mockData.treatment);
|
|
126
|
-
return accum;
|
|
127
|
-
}, {});
|
|
128
|
-
arrangeConditions(mocksData);
|
|
129
|
-
return mocksData;
|
|
130
|
-
}
|
|
131
|
-
// Load the content of a configuration file into an Object
|
|
132
|
-
return function splitsParserFromFile(_a) {
|
|
133
|
-
var features = _a.features, log = _a.log;
|
|
134
|
-
var filePath = configFilesPath(features);
|
|
135
|
-
var mockData;
|
|
136
|
-
// If we have a filePath, it means the extension is correct, choose the parser.
|
|
137
|
-
if (endsWith(filePath, '.split')) {
|
|
138
|
-
log.warn(logPrefix + '.split mocks will be deprecated soon in favor of YAML files, which provide more targeting power. Take a look in our documentation.');
|
|
139
|
-
mockData = readSplitConfigFile(log, filePath);
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
mockData = readYAMLConfigFile(log, filePath);
|
|
143
|
-
}
|
|
144
|
-
return mockData;
|
|
145
|
-
};
|
|
146
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { splitsParserFromFileFactory } from './splitsParser/splitsParserFromFile';
|
|
2
|
-
import { syncManagerOfflineFactory } from './syncManagerOffline';
|
|
3
|
-
import { SplitIO } from '../../types';
|
|
4
|
-
|
|
5
|
-
// Singleton instance of the factory function for offline SyncManager from YAML file (a.k.a. localhostFromFile)
|
|
6
|
-
// Requires Node 'fs' and 'path' APIs.
|
|
7
|
-
const localhostFromFile = syncManagerOfflineFactory(splitsParserFromFileFactory) as SplitIO.LocalhostFactory;
|
|
8
|
-
localhostFromFile.type = 'LocalhostFromFile';
|
|
9
|
-
|
|
10
|
-
export function LocalhostFromFile(): SplitIO.LocalhostFactory {
|
|
11
|
-
return localhostFromFile;
|
|
12
|
-
}
|