@featurevisor/core 1.30.1 → 1.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/coverage/clover.xml +11 -11
- package/coverage/coverage-final.json +2 -2
- package/coverage/lcov-report/index.html +7 -7
- package/coverage/lcov-report/lib/builder/allocator.js.html +1 -1
- package/coverage/lcov-report/lib/builder/index.html +1 -1
- package/coverage/lcov-report/lib/builder/revision.js.html +1 -1
- package/coverage/lcov-report/lib/builder/traffic.js.html +1 -1
- package/coverage/lcov-report/lib/tester/checkIfObjectsAreEqual.js.html +1 -1
- package/coverage/lcov-report/lib/tester/index.html +5 -5
- package/coverage/lcov-report/lib/tester/matrix.js.html +5 -5
- package/coverage/lcov-report/src/builder/allocator.ts.html +1 -1
- package/coverage/lcov-report/src/builder/index.html +1 -1
- package/coverage/lcov-report/src/builder/revision.ts.html +1 -1
- package/coverage/lcov-report/src/builder/traffic.ts.html +1 -1
- package/coverage/lcov-report/src/tester/checkIfObjectsAreEqual.ts.html +1 -1
- package/coverage/lcov-report/src/tester/index.html +5 -5
- package/coverage/lcov-report/src/tester/matrix.ts.html +5 -5
- package/coverage/lcov.info +30 -22
- package/lib/assess-distribution/index.d.ts +1 -1
- package/lib/assess-distribution/index.js +2 -2
- package/lib/assess-distribution/index.js.map +1 -1
- package/lib/benchmark/index.d.ts +1 -1
- package/lib/benchmark/index.js +2 -2
- package/lib/benchmark/index.js.map +1 -1
- package/lib/builder/buildDatafile.d.ts +1 -1
- package/lib/builder/buildDatafile.js +59 -40
- package/lib/builder/buildDatafile.js.map +1 -1
- package/lib/builder/buildProject.js +87 -50
- package/lib/builder/buildProject.js.map +1 -1
- package/lib/config/projectConfig.d.ts +1 -1
- package/lib/datasource/adapter.d.ts +3 -3
- package/lib/datasource/adapter.js.map +1 -1
- package/lib/datasource/datasource.d.ts +2 -2
- package/lib/datasource/datasource.js.map +1 -1
- package/lib/datasource/filesystemAdapter.d.ts +1 -1
- package/lib/datasource/filesystemAdapter.js +9 -3
- package/lib/datasource/filesystemAdapter.js.map +1 -1
- package/lib/evaluate/index.d.ts +1 -1
- package/lib/evaluate/index.js +10 -7
- package/lib/evaluate/index.js.map +1 -1
- package/lib/find-usage/index.js +60 -26
- package/lib/find-usage/index.js.map +1 -1
- package/lib/linter/featureSchema.d.ts +194 -5
- package/lib/linter/featureSchema.js +70 -60
- package/lib/linter/featureSchema.js.map +1 -1
- package/lib/linter/testSchema.d.ts +1 -1
- package/lib/linter/testSchema.js +16 -13
- package/lib/linter/testSchema.js.map +1 -1
- package/lib/site/generateSiteSearchIndex.js +65 -24
- package/lib/site/generateSiteSearchIndex.js.map +1 -1
- package/lib/tester/matrix.js +2 -2
- package/lib/tester/matrix.js.map +1 -1
- package/lib/tester/testFeature.d.ts +3 -4
- package/lib/tester/testFeature.js +1 -2
- package/lib/tester/testFeature.js.map +1 -1
- package/lib/tester/testProject.d.ts +1 -3
- package/lib/tester/testProject.js +28 -12
- package/lib/tester/testProject.js.map +1 -1
- package/package.json +5 -5
- package/src/assess-distribution/index.ts +3 -3
- package/src/benchmark/index.ts +3 -3
- package/src/builder/buildDatafile.ts +33 -8
- package/src/builder/buildProject.ts +72 -31
- package/src/config/projectConfig.ts +1 -1
- package/src/datasource/adapter.ts +6 -3
- package/src/datasource/datasource.ts +2 -2
- package/src/datasource/filesystemAdapter.ts +12 -4
- package/src/evaluate/index.ts +11 -7
- package/src/find-usage/index.ts +65 -29
- package/src/linter/featureSchema.ts +100 -82
- package/src/linter/testSchema.ts +21 -16
- package/src/site/generateSiteSearchIndex.ts +71 -24
- package/src/tester/matrix.ts +2 -2
- package/src/tester/testFeature.ts +3 -2
- package/src/tester/testProject.ts +27 -8
|
@@ -113,7 +113,7 @@ function executeTest(testFile, deps, options, patterns, datafileContentByEnviron
|
|
|
113
113
|
}
|
|
114
114
|
function testProject(deps_1) {
|
|
115
115
|
return __awaiter(this, arguments, void 0, function (deps, options) {
|
|
116
|
-
var projectConfig, datasource, hasError, testFiles, startTime, patterns, passedTestsCount, failedTestsCount, passedAssertionsCount, failedAssertionsCount, datafileContentByEnvironment, _i, _a, environment, existingState, datafileContent, _b, testFiles_1, testFile, executionResult, diffInMs, testSpecsMessage, testAssertionsMessage;
|
|
116
|
+
var projectConfig, datasource, hasError, testFiles, startTime, patterns, passedTestsCount, failedTestsCount, passedAssertionsCount, failedAssertionsCount, datafileContentByEnvironment, _i, _a, environment, existingState, datafileContent, existingState, datafileContent, _b, testFiles_1, testFile, executionResult, diffInMs, testSpecsMessage, testAssertionsMessage;
|
|
117
117
|
if (options === void 0) { options = {}; }
|
|
118
118
|
return __generator(this, function (_c) {
|
|
119
119
|
switch (_c.label) {
|
|
@@ -142,7 +142,8 @@ function testProject(deps_1) {
|
|
|
142
142
|
failedTestsCount = 0;
|
|
143
143
|
passedAssertionsCount = 0;
|
|
144
144
|
failedAssertionsCount = 0;
|
|
145
|
-
datafileContentByEnvironment =
|
|
145
|
+
datafileContentByEnvironment = new Map();
|
|
146
|
+
if (!Array.isArray(projectConfig.environments)) return [3 /*break*/, 6];
|
|
146
147
|
_i = 0, _a = projectConfig.environments;
|
|
147
148
|
_c.label = 2;
|
|
148
149
|
case 2:
|
|
@@ -159,22 +160,37 @@ function testProject(deps_1) {
|
|
|
159
160
|
}, existingState)];
|
|
160
161
|
case 4:
|
|
161
162
|
datafileContent = _c.sent();
|
|
162
|
-
datafileContentByEnvironment
|
|
163
|
+
datafileContentByEnvironment.set(environment, datafileContent);
|
|
163
164
|
_c.label = 5;
|
|
164
165
|
case 5:
|
|
165
166
|
_i++;
|
|
166
167
|
return [3 /*break*/, 2];
|
|
167
168
|
case 6:
|
|
168
|
-
|
|
169
|
-
|
|
169
|
+
if (!(projectConfig.environments === false)) return [3 /*break*/, 9];
|
|
170
|
+
return [4 /*yield*/, datasource.readState(false)];
|
|
170
171
|
case 7:
|
|
171
|
-
|
|
172
|
+
existingState = _c.sent();
|
|
173
|
+
return [4 /*yield*/, (0, builder_1.buildDatafile)(projectConfig, datasource, {
|
|
174
|
+
schemaVersion: options.schemaVersion || config_1.SCHEMA_VERSION,
|
|
175
|
+
revision: "include-all-features",
|
|
176
|
+
environment: false,
|
|
177
|
+
inflate: options.inflate,
|
|
178
|
+
}, existingState)];
|
|
179
|
+
case 8:
|
|
180
|
+
datafileContent = _c.sent();
|
|
181
|
+
datafileContentByEnvironment.set(false, datafileContent);
|
|
182
|
+
_c.label = 9;
|
|
183
|
+
case 9:
|
|
184
|
+
_b = 0, testFiles_1 = testFiles;
|
|
185
|
+
_c.label = 10;
|
|
186
|
+
case 10:
|
|
187
|
+
if (!(_b < testFiles_1.length)) return [3 /*break*/, 13];
|
|
172
188
|
testFile = testFiles_1[_b];
|
|
173
189
|
return [4 /*yield*/, executeTest(testFile, deps, options, patterns, datafileContentByEnvironment)];
|
|
174
|
-
case
|
|
190
|
+
case 11:
|
|
175
191
|
executionResult = _c.sent();
|
|
176
192
|
if (!executionResult) {
|
|
177
|
-
return [3 /*break*/,
|
|
193
|
+
return [3 /*break*/, 12];
|
|
178
194
|
}
|
|
179
195
|
if (executionResult.passed) {
|
|
180
196
|
passedTestsCount += 1;
|
|
@@ -185,11 +201,11 @@ function testProject(deps_1) {
|
|
|
185
201
|
}
|
|
186
202
|
passedAssertionsCount += executionResult.assertionsCount.passed;
|
|
187
203
|
failedAssertionsCount += executionResult.assertionsCount.failed;
|
|
188
|
-
_c.label =
|
|
189
|
-
case
|
|
204
|
+
_c.label = 12;
|
|
205
|
+
case 12:
|
|
190
206
|
_b++;
|
|
191
|
-
return [3 /*break*/,
|
|
192
|
-
case
|
|
207
|
+
return [3 /*break*/, 10];
|
|
208
|
+
case 13:
|
|
193
209
|
diffInMs = Date.now() - startTime;
|
|
194
210
|
if (options.onlyFailures !== true || hasError) {
|
|
195
211
|
console.log("\n---");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testProject.js","sourceRoot":"","sources":["../../src/tester/testProject.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"testProject.js","sourceRoot":"","sources":["../../src/tester/testProject.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@featurevisor/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.32.0",
|
|
4
4
|
"description": "Core package of Featurevisor for Node.js usage",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
},
|
|
41
41
|
"license": "MIT",
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@featurevisor/sdk": "1.
|
|
44
|
-
"@featurevisor/site": "1.
|
|
45
|
-
"@featurevisor/types": "1.
|
|
43
|
+
"@featurevisor/sdk": "1.32.0",
|
|
44
|
+
"@featurevisor/site": "1.32.0",
|
|
45
|
+
"@featurevisor/types": "1.32.0",
|
|
46
46
|
"axios": "^1.3.4",
|
|
47
47
|
"js-yaml": "^4.1.0",
|
|
48
48
|
"mkdirp": "^2.1.3",
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"@types/js-yaml": "^4.0.5",
|
|
55
55
|
"@types/tar": "^6.1.4"
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "c360fac0c91b586847633c2d41cf5e4d6922a9b8"
|
|
58
58
|
}
|
|
@@ -67,7 +67,7 @@ function createContext(providedContext: Context, populateUuid?: AttributeKey[]):
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
export interface AssessDistributionOptions {
|
|
70
|
-
environment
|
|
70
|
+
environment?: string;
|
|
71
71
|
feature: FeatureKey;
|
|
72
72
|
context: Context;
|
|
73
73
|
n: number;
|
|
@@ -88,14 +88,14 @@ export async function assessDistribution(deps: Dependencies, options: AssessDist
|
|
|
88
88
|
*/
|
|
89
89
|
const datafileBuildStart = Date.now();
|
|
90
90
|
console.log(`\n\nBuilding datafile containing all features for "${options.environment}"...`);
|
|
91
|
-
const existingState = await datasource.readState(options.environment);
|
|
91
|
+
const existingState = await datasource.readState(options.environment || false);
|
|
92
92
|
const datafileContent = await buildDatafile(
|
|
93
93
|
projectConfig,
|
|
94
94
|
datasource,
|
|
95
95
|
{
|
|
96
96
|
schemaVersion: options.schemaVersion || SCHEMA_VERSION,
|
|
97
97
|
revision: "include-all-features",
|
|
98
|
-
environment: options.environment,
|
|
98
|
+
environment: options.environment || false,
|
|
99
99
|
inflate: options.inflate,
|
|
100
100
|
},
|
|
101
101
|
existingState,
|
package/src/benchmark/index.ts
CHANGED
|
@@ -77,7 +77,7 @@ export function benchmarkFeatureVariable(
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export interface BenchmarkOptions {
|
|
80
|
-
environment
|
|
80
|
+
environment?: string;
|
|
81
81
|
feature: string;
|
|
82
82
|
n: number;
|
|
83
83
|
context: Record<string, unknown>;
|
|
@@ -100,14 +100,14 @@ export async function benchmarkFeature(
|
|
|
100
100
|
|
|
101
101
|
console.log(`Building datafile containing all features for "${options.environment}"...`);
|
|
102
102
|
const datafileBuildStart = Date.now();
|
|
103
|
-
const existingState = await datasource.readState(options.environment);
|
|
103
|
+
const existingState = await datasource.readState(options.environment || false);
|
|
104
104
|
const datafileContent = await buildDatafile(
|
|
105
105
|
projectConfig,
|
|
106
106
|
datasource,
|
|
107
107
|
{
|
|
108
108
|
schemaVersion: options.schemaVersion || SCHEMA_VERSION,
|
|
109
109
|
revision: "include-all-features",
|
|
110
|
-
environment: options.environment,
|
|
110
|
+
environment: options.environment || false,
|
|
111
111
|
inflate: options.inflate,
|
|
112
112
|
},
|
|
113
113
|
existingState,
|
|
@@ -19,6 +19,9 @@ import {
|
|
|
19
19
|
FeatureKey,
|
|
20
20
|
Allocation,
|
|
21
21
|
VariableSchema,
|
|
22
|
+
Expose,
|
|
23
|
+
Rule,
|
|
24
|
+
Force,
|
|
22
25
|
} from "@featurevisor/types";
|
|
23
26
|
|
|
24
27
|
import { ProjectConfig, SCHEMA_VERSION } from "../config";
|
|
@@ -66,7 +69,7 @@ export async function getCustomDatafile(options: CustomDatafileOptions): Promise
|
|
|
66
69
|
export interface BuildOptions {
|
|
67
70
|
schemaVersion: string;
|
|
68
71
|
revision: string;
|
|
69
|
-
environment: string;
|
|
72
|
+
environment: string | false;
|
|
70
73
|
tag?: string;
|
|
71
74
|
features?: FeatureKey[];
|
|
72
75
|
inflate?: number;
|
|
@@ -112,19 +115,33 @@ export async function buildDatafile(
|
|
|
112
115
|
continue;
|
|
113
116
|
}
|
|
114
117
|
|
|
115
|
-
|
|
118
|
+
let expose: Expose | undefined;
|
|
119
|
+
let rules: Rule[];
|
|
120
|
+
let force: Force[] | undefined;
|
|
121
|
+
|
|
122
|
+
if (options.environment && parsedFeature.environments) {
|
|
123
|
+
expose = parsedFeature.environments[options.environment].expose;
|
|
124
|
+
rules = parsedFeature.environments[options.environment].rules;
|
|
125
|
+
force = parsedFeature.environments[options.environment].force;
|
|
126
|
+
} else {
|
|
127
|
+
expose = parsedFeature.expose;
|
|
128
|
+
rules = parsedFeature.rules as Rule[];
|
|
129
|
+
force = parsedFeature.force;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (expose === false) {
|
|
116
133
|
continue;
|
|
117
134
|
}
|
|
118
135
|
|
|
119
|
-
if (Array.isArray(
|
|
120
|
-
const exposeTags =
|
|
136
|
+
if (Array.isArray(expose)) {
|
|
137
|
+
const exposeTags = expose;
|
|
121
138
|
|
|
122
139
|
if (options.tag && exposeTags.indexOf(options.tag) === -1) {
|
|
123
140
|
continue;
|
|
124
141
|
}
|
|
125
142
|
}
|
|
126
143
|
|
|
127
|
-
for (const parsedRule of
|
|
144
|
+
for (const parsedRule of rules) {
|
|
128
145
|
const extractedSegmentKeys = extractSegmentKeysFromGroupSegments(parsedRule.segments);
|
|
129
146
|
extractedSegmentKeys.forEach((segmentKey) => segmentKeysUsedByTag.add(segmentKey));
|
|
130
147
|
}
|
|
@@ -200,7 +217,7 @@ export async function buildDatafile(
|
|
|
200
217
|
: undefined,
|
|
201
218
|
traffic: getTraffic(
|
|
202
219
|
parsedFeature.variations,
|
|
203
|
-
|
|
220
|
+
rules,
|
|
204
221
|
existingState.features[featureKey],
|
|
205
222
|
featureRanges.get(featureKey) || [],
|
|
206
223
|
).map((t: Traffic) => {
|
|
@@ -253,8 +270,8 @@ export async function buildDatafile(
|
|
|
253
270
|
});
|
|
254
271
|
}
|
|
255
272
|
|
|
256
|
-
if (
|
|
257
|
-
feature.force =
|
|
273
|
+
if (force) {
|
|
274
|
+
feature.force = force;
|
|
258
275
|
|
|
259
276
|
feature.force?.forEach((f) => {
|
|
260
277
|
if (f.segments) {
|
|
@@ -395,6 +412,14 @@ export async function buildDatafile(
|
|
|
395
412
|
}, {});
|
|
396
413
|
|
|
397
414
|
datafileContentV2.features = features.reduce((acc, feature) => {
|
|
415
|
+
if (Array.isArray(feature.variablesSchema)) {
|
|
416
|
+
feature.variablesSchema = feature.variablesSchema.reduce((vAcc, variableSchema) => {
|
|
417
|
+
vAcc[variableSchema.key] = variableSchema;
|
|
418
|
+
|
|
419
|
+
return vAcc;
|
|
420
|
+
}, {});
|
|
421
|
+
}
|
|
422
|
+
|
|
398
423
|
acc[feature.key] = feature;
|
|
399
424
|
return acc;
|
|
400
425
|
}, {});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { SCHEMA_VERSION } from "../config";
|
|
1
|
+
import { SCHEMA_VERSION, ProjectConfig } from "../config";
|
|
2
|
+
import { Datasource } from "../datasource";
|
|
2
3
|
|
|
3
4
|
import { getNextRevision } from "./revision";
|
|
4
5
|
import { buildDatafile, getCustomDatafile } from "./buildDatafile";
|
|
@@ -19,6 +20,58 @@ export interface BuildCLIOptions {
|
|
|
19
20
|
datafilesDir?: string;
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
async function buildForEnvironment({
|
|
24
|
+
projectConfig,
|
|
25
|
+
datasource,
|
|
26
|
+
nextRevision,
|
|
27
|
+
environment,
|
|
28
|
+
tags,
|
|
29
|
+
cliOptions,
|
|
30
|
+
}: {
|
|
31
|
+
projectConfig: ProjectConfig;
|
|
32
|
+
datasource: Datasource;
|
|
33
|
+
nextRevision: string;
|
|
34
|
+
environment: string | false;
|
|
35
|
+
tags: string[];
|
|
36
|
+
cliOptions: BuildCLIOptions;
|
|
37
|
+
}) {
|
|
38
|
+
console.log(`\nBuilding datafiles for environment: ${environment}`);
|
|
39
|
+
|
|
40
|
+
const existingState = await datasource.readState(environment);
|
|
41
|
+
|
|
42
|
+
for (const tag of tags) {
|
|
43
|
+
console.log(`\n => Tag: ${tag}`);
|
|
44
|
+
|
|
45
|
+
const datafileContent = await buildDatafile(
|
|
46
|
+
projectConfig,
|
|
47
|
+
datasource,
|
|
48
|
+
{
|
|
49
|
+
schemaVersion: cliOptions.schemaVersion || SCHEMA_VERSION,
|
|
50
|
+
revision: nextRevision,
|
|
51
|
+
environment: environment,
|
|
52
|
+
tag: tag,
|
|
53
|
+
inflate: cliOptions.inflate,
|
|
54
|
+
},
|
|
55
|
+
existingState,
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
// write datafile for environment/tag
|
|
59
|
+
await datasource.writeDatafile(datafileContent, {
|
|
60
|
+
environment,
|
|
61
|
+
tag,
|
|
62
|
+
datafilesDir: cliOptions.datafilesDir,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (typeof cliOptions.stateFiles === "undefined" || cliOptions.stateFiles) {
|
|
67
|
+
// write state for environment
|
|
68
|
+
await datasource.writeState(environment, existingState);
|
|
69
|
+
|
|
70
|
+
// write revision
|
|
71
|
+
await datasource.writeRevision(nextRevision);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
22
75
|
export async function buildProject(deps: Dependencies, cliOptions: BuildCLIOptions = {}) {
|
|
23
76
|
const { projectConfig, datasource } = deps;
|
|
24
77
|
|
|
@@ -63,42 +116,30 @@ export async function buildProject(deps: Dependencies, cliOptions: BuildCLIOptio
|
|
|
63
116
|
const nextRevision =
|
|
64
117
|
(cliOptions.revision && cliOptions.revision.toString()) || getNextRevision(currentRevision);
|
|
65
118
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
for (const tag of tags) {
|
|
72
|
-
console.log(`\n => Tag: ${tag}`);
|
|
73
|
-
|
|
74
|
-
const datafileContent = await buildDatafile(
|
|
119
|
+
// with environments
|
|
120
|
+
if (Array.isArray(environments)) {
|
|
121
|
+
for (const environment of environments) {
|
|
122
|
+
await buildForEnvironment({
|
|
75
123
|
projectConfig,
|
|
76
124
|
datasource,
|
|
77
|
-
|
|
78
|
-
schemaVersion: cliOptions.schemaVersion || SCHEMA_VERSION,
|
|
79
|
-
revision: nextRevision,
|
|
80
|
-
environment: environment,
|
|
81
|
-
tag: tag,
|
|
82
|
-
inflate: cliOptions.inflate,
|
|
83
|
-
},
|
|
84
|
-
existingState,
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
// write datafile for environment/tag
|
|
88
|
-
await datasource.writeDatafile(datafileContent, {
|
|
125
|
+
nextRevision,
|
|
89
126
|
environment,
|
|
90
|
-
|
|
91
|
-
|
|
127
|
+
tags,
|
|
128
|
+
cliOptions,
|
|
92
129
|
});
|
|
93
130
|
}
|
|
131
|
+
}
|
|
94
132
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
133
|
+
// no environment
|
|
134
|
+
if (environments === false) {
|
|
135
|
+
await buildForEnvironment({
|
|
136
|
+
projectConfig,
|
|
137
|
+
datasource,
|
|
138
|
+
nextRevision,
|
|
139
|
+
environment: false,
|
|
140
|
+
tags,
|
|
141
|
+
cliOptions,
|
|
142
|
+
});
|
|
102
143
|
}
|
|
103
144
|
|
|
104
145
|
console.log("\nLatest revision:", nextRevision);
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from "@featurevisor/types";
|
|
10
10
|
|
|
11
11
|
export interface DatafileOptions {
|
|
12
|
-
environment: EnvironmentKey;
|
|
12
|
+
environment: EnvironmentKey | false;
|
|
13
13
|
tag: string;
|
|
14
14
|
datafilesDir?: string;
|
|
15
15
|
}
|
|
@@ -23,8 +23,11 @@ export abstract class Adapter {
|
|
|
23
23
|
abstract deleteEntity(entityType: EntityType, entityKey: string): Promise<void>;
|
|
24
24
|
|
|
25
25
|
// state
|
|
26
|
-
abstract readState(environment: EnvironmentKey): Promise<ExistingState>;
|
|
27
|
-
abstract writeState(
|
|
26
|
+
abstract readState(environment: EnvironmentKey | false): Promise<ExistingState>;
|
|
27
|
+
abstract writeState(
|
|
28
|
+
environment: EnvironmentKey | false,
|
|
29
|
+
existingState: ExistingState,
|
|
30
|
+
): Promise<void>;
|
|
28
31
|
|
|
29
32
|
// datafile
|
|
30
33
|
abstract readDatafile(options: DatafileOptions): Promise<DatafileContent>;
|
|
@@ -35,11 +35,11 @@ export class Datasource {
|
|
|
35
35
|
/**
|
|
36
36
|
* State
|
|
37
37
|
*/
|
|
38
|
-
readState(environment: EnvironmentKey): Promise<ExistingState> {
|
|
38
|
+
readState(environment: EnvironmentKey | false): Promise<ExistingState> {
|
|
39
39
|
return this.adapter.readState(environment);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
writeState(environment: EnvironmentKey, existingState: ExistingState) {
|
|
42
|
+
writeState(environment: EnvironmentKey | false, existingState: ExistingState) {
|
|
43
43
|
return this.adapter.writeState(environment, existingState);
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -23,9 +23,11 @@ const commitRegex = /^commit (\w+)\nAuthor: (.+) <(.+)>\nDate: (.+)\n\n(.+)/gm
|
|
|
23
23
|
|
|
24
24
|
export function getExistingStateFilePath(
|
|
25
25
|
projectConfig: ProjectConfig,
|
|
26
|
-
environment: EnvironmentKey,
|
|
26
|
+
environment: EnvironmentKey | false,
|
|
27
27
|
): string {
|
|
28
|
-
|
|
28
|
+
const fileName = environment ? `existing-state-${environment}.json` : `existing-state.json`;
|
|
29
|
+
|
|
30
|
+
return path.join(projectConfig.stateDirectoryPath, fileName);
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
export function getRevisionFilePath(projectConfig: ProjectConfig): string {
|
|
@@ -185,7 +187,11 @@ export class FilesystemAdapter extends Adapter {
|
|
|
185
187
|
const fileName = `datafile-tag-${options.tag}.json`;
|
|
186
188
|
const dir = options.datafilesDir || this.config.outputDirectoryPath;
|
|
187
189
|
|
|
188
|
-
|
|
190
|
+
if (options.environment) {
|
|
191
|
+
return path.join(dir, options.environment, fileName);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return path.join(dir, fileName);
|
|
189
195
|
}
|
|
190
196
|
|
|
191
197
|
async readDatafile(options: DatafileOptions): Promise<DatafileContent> {
|
|
@@ -199,7 +205,9 @@ export class FilesystemAdapter extends Adapter {
|
|
|
199
205
|
async writeDatafile(datafileContent: DatafileContent, options: DatafileOptions): Promise<void> {
|
|
200
206
|
const dir = options.datafilesDir || this.config.outputDirectoryPath;
|
|
201
207
|
|
|
202
|
-
const outputEnvironmentDirPath =
|
|
208
|
+
const outputEnvironmentDirPath = options.environment
|
|
209
|
+
? path.join(dir, options.environment)
|
|
210
|
+
: dir;
|
|
203
211
|
mkdirp.sync(outputEnvironmentDirPath);
|
|
204
212
|
|
|
205
213
|
const outputFilePath = this.getDatafilePath(options);
|
package/src/evaluate/index.ts
CHANGED
|
@@ -50,7 +50,7 @@ function printHeader(message: string) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export interface EvaluateOptions {
|
|
53
|
-
environment
|
|
53
|
+
environment?: string;
|
|
54
54
|
feature: string;
|
|
55
55
|
context: Record<string, unknown>;
|
|
56
56
|
print?: boolean;
|
|
@@ -69,14 +69,14 @@ export interface Log {
|
|
|
69
69
|
export async function evaluateFeature(deps: Dependencies, options: EvaluateOptions) {
|
|
70
70
|
const { datasource, projectConfig } = deps;
|
|
71
71
|
|
|
72
|
-
const existingState = await datasource.readState(options.environment);
|
|
72
|
+
const existingState = await datasource.readState(options.environment || false);
|
|
73
73
|
const datafileContent = await buildDatafile(
|
|
74
74
|
projectConfig,
|
|
75
75
|
datasource,
|
|
76
76
|
{
|
|
77
77
|
schemaVersion: options.schemaVersion || SCHEMA_VERSION,
|
|
78
78
|
revision: "include-all-features",
|
|
79
|
-
environment: options.environment,
|
|
79
|
+
environment: options.environment || false,
|
|
80
80
|
inflate: options.inflate,
|
|
81
81
|
},
|
|
82
82
|
existingState,
|
|
@@ -110,17 +110,21 @@ export async function evaluateFeature(deps: Dependencies, options: EvaluateOptio
|
|
|
110
110
|
|
|
111
111
|
const feature = f.getFeature(options.feature);
|
|
112
112
|
if (feature?.variablesSchema) {
|
|
113
|
-
feature.variablesSchema
|
|
113
|
+
const variableKeys = Array.isArray(feature.variablesSchema)
|
|
114
|
+
? feature.variablesSchema
|
|
115
|
+
: Object.keys(feature.variablesSchema);
|
|
116
|
+
|
|
117
|
+
variableKeys.forEach((variableKey) => {
|
|
114
118
|
const variableEvaluation = f.evaluateVariable(
|
|
115
119
|
options.feature,
|
|
116
|
-
|
|
120
|
+
variableKey,
|
|
117
121
|
options.context as Context,
|
|
118
122
|
);
|
|
119
123
|
|
|
120
|
-
variableEvaluationLogs[
|
|
124
|
+
variableEvaluationLogs[variableKey] = [...logs];
|
|
121
125
|
logs = [];
|
|
122
126
|
|
|
123
|
-
variableEvaluations[
|
|
127
|
+
variableEvaluations[variableKey] = variableEvaluation;
|
|
124
128
|
});
|
|
125
129
|
}
|
|
126
130
|
|
package/src/find-usage/index.ts
CHANGED
|
@@ -52,34 +52,70 @@ export async function findAllUsageInFeatures(deps: Dependencies): Promise<UsageI
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
// variable overrides inside variations
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
55
|
+
if (feature.variations) {
|
|
56
|
+
feature.variations.forEach((variation) => {
|
|
57
|
+
if (variation.variables) {
|
|
58
|
+
variation.variables.forEach((variable) => {
|
|
59
|
+
if (variable.overrides) {
|
|
60
|
+
variable.overrides.forEach((override) => {
|
|
61
|
+
if (override.segments) {
|
|
62
|
+
extractSegmentKeysFromGroupSegments(override.segments).forEach((segmentKey) =>
|
|
63
|
+
usageInFeatures[featureKey].segments.add(segmentKey),
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (override.conditions) {
|
|
68
|
+
extractAttributeKeysFromConditions(override.conditions).forEach((attributeKey) =>
|
|
69
|
+
usageInFeatures[featureKey].attributes.add(attributeKey),
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// with environments
|
|
80
|
+
if (Array.isArray(projectConfig.environments)) {
|
|
81
|
+
projectConfig.environments.forEach((environment) => {
|
|
82
|
+
if (!feature.environments) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// force
|
|
87
|
+
if (feature.environments[environment].force) {
|
|
88
|
+
feature.environments[environment].force?.forEach((force) => {
|
|
89
|
+
if (force.segments) {
|
|
90
|
+
extractSegmentKeysFromGroupSegments(force.segments).forEach((segmentKey) =>
|
|
91
|
+
usageInFeatures[featureKey].segments.add(segmentKey),
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (force.conditions) {
|
|
96
|
+
extractAttributeKeysFromConditions(force.conditions).forEach((attributeKey) =>
|
|
97
|
+
usageInFeatures[featureKey].attributes.add(attributeKey),
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
79
102
|
|
|
103
|
+
// rules
|
|
104
|
+
if (feature.environments[environment].rules) {
|
|
105
|
+
feature.environments[environment].rules?.forEach((rule) => {
|
|
106
|
+
extractSegmentKeysFromGroupSegments(rule.segments).forEach((segmentKey) =>
|
|
107
|
+
usageInFeatures[featureKey].segments.add(segmentKey),
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// no environments
|
|
115
|
+
if (projectConfig.environments === false) {
|
|
80
116
|
// force
|
|
81
|
-
if (feature.
|
|
82
|
-
feature.
|
|
117
|
+
if (feature.force) {
|
|
118
|
+
feature.force.forEach((force) => {
|
|
83
119
|
if (force.segments) {
|
|
84
120
|
extractSegmentKeysFromGroupSegments(force.segments).forEach((segmentKey) =>
|
|
85
121
|
usageInFeatures[featureKey].segments.add(segmentKey),
|
|
@@ -95,14 +131,14 @@ export async function findAllUsageInFeatures(deps: Dependencies): Promise<UsageI
|
|
|
95
131
|
}
|
|
96
132
|
|
|
97
133
|
// rules
|
|
98
|
-
if (feature.
|
|
99
|
-
feature.
|
|
134
|
+
if (feature.rules) {
|
|
135
|
+
feature.rules.forEach((rule) => {
|
|
100
136
|
extractSegmentKeysFromGroupSegments(rule.segments).forEach((segmentKey) =>
|
|
101
137
|
usageInFeatures[featureKey].segments.add(segmentKey),
|
|
102
138
|
);
|
|
103
139
|
});
|
|
104
140
|
}
|
|
105
|
-
}
|
|
141
|
+
}
|
|
106
142
|
}
|
|
107
143
|
|
|
108
144
|
return usageInFeatures;
|