@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.
Files changed (76) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/coverage/clover.xml +11 -11
  3. package/coverage/coverage-final.json +2 -2
  4. package/coverage/lcov-report/index.html +7 -7
  5. package/coverage/lcov-report/lib/builder/allocator.js.html +1 -1
  6. package/coverage/lcov-report/lib/builder/index.html +1 -1
  7. package/coverage/lcov-report/lib/builder/revision.js.html +1 -1
  8. package/coverage/lcov-report/lib/builder/traffic.js.html +1 -1
  9. package/coverage/lcov-report/lib/tester/checkIfObjectsAreEqual.js.html +1 -1
  10. package/coverage/lcov-report/lib/tester/index.html +5 -5
  11. package/coverage/lcov-report/lib/tester/matrix.js.html +5 -5
  12. package/coverage/lcov-report/src/builder/allocator.ts.html +1 -1
  13. package/coverage/lcov-report/src/builder/index.html +1 -1
  14. package/coverage/lcov-report/src/builder/revision.ts.html +1 -1
  15. package/coverage/lcov-report/src/builder/traffic.ts.html +1 -1
  16. package/coverage/lcov-report/src/tester/checkIfObjectsAreEqual.ts.html +1 -1
  17. package/coverage/lcov-report/src/tester/index.html +5 -5
  18. package/coverage/lcov-report/src/tester/matrix.ts.html +5 -5
  19. package/coverage/lcov.info +30 -22
  20. package/lib/assess-distribution/index.d.ts +1 -1
  21. package/lib/assess-distribution/index.js +2 -2
  22. package/lib/assess-distribution/index.js.map +1 -1
  23. package/lib/benchmark/index.d.ts +1 -1
  24. package/lib/benchmark/index.js +2 -2
  25. package/lib/benchmark/index.js.map +1 -1
  26. package/lib/builder/buildDatafile.d.ts +1 -1
  27. package/lib/builder/buildDatafile.js +59 -40
  28. package/lib/builder/buildDatafile.js.map +1 -1
  29. package/lib/builder/buildProject.js +87 -50
  30. package/lib/builder/buildProject.js.map +1 -1
  31. package/lib/config/projectConfig.d.ts +1 -1
  32. package/lib/datasource/adapter.d.ts +3 -3
  33. package/lib/datasource/adapter.js.map +1 -1
  34. package/lib/datasource/datasource.d.ts +2 -2
  35. package/lib/datasource/datasource.js.map +1 -1
  36. package/lib/datasource/filesystemAdapter.d.ts +1 -1
  37. package/lib/datasource/filesystemAdapter.js +9 -3
  38. package/lib/datasource/filesystemAdapter.js.map +1 -1
  39. package/lib/evaluate/index.d.ts +1 -1
  40. package/lib/evaluate/index.js +10 -7
  41. package/lib/evaluate/index.js.map +1 -1
  42. package/lib/find-usage/index.js +60 -26
  43. package/lib/find-usage/index.js.map +1 -1
  44. package/lib/linter/featureSchema.d.ts +194 -5
  45. package/lib/linter/featureSchema.js +70 -60
  46. package/lib/linter/featureSchema.js.map +1 -1
  47. package/lib/linter/testSchema.d.ts +1 -1
  48. package/lib/linter/testSchema.js +16 -13
  49. package/lib/linter/testSchema.js.map +1 -1
  50. package/lib/site/generateSiteSearchIndex.js +65 -24
  51. package/lib/site/generateSiteSearchIndex.js.map +1 -1
  52. package/lib/tester/matrix.js +2 -2
  53. package/lib/tester/matrix.js.map +1 -1
  54. package/lib/tester/testFeature.d.ts +3 -4
  55. package/lib/tester/testFeature.js +1 -2
  56. package/lib/tester/testFeature.js.map +1 -1
  57. package/lib/tester/testProject.d.ts +1 -3
  58. package/lib/tester/testProject.js +28 -12
  59. package/lib/tester/testProject.js.map +1 -1
  60. package/package.json +5 -5
  61. package/src/assess-distribution/index.ts +3 -3
  62. package/src/benchmark/index.ts +3 -3
  63. package/src/builder/buildDatafile.ts +33 -8
  64. package/src/builder/buildProject.ts +72 -31
  65. package/src/config/projectConfig.ts +1 -1
  66. package/src/datasource/adapter.ts +6 -3
  67. package/src/datasource/datasource.ts +2 -2
  68. package/src/datasource/filesystemAdapter.ts +12 -4
  69. package/src/evaluate/index.ts +11 -7
  70. package/src/find-usage/index.ts +65 -29
  71. package/src/linter/featureSchema.ts +100 -82
  72. package/src/linter/testSchema.ts +21 -16
  73. package/src/site/generateSiteSearchIndex.ts +71 -24
  74. package/src/tester/matrix.ts +2 -2
  75. package/src/tester/testFeature.ts +3 -2
  76. 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[environment] = datafileContent;
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
- _b = 0, testFiles_1 = testFiles;
169
- _c.label = 7;
169
+ if (!(projectConfig.environments === false)) return [3 /*break*/, 9];
170
+ return [4 /*yield*/, datasource.readState(false)];
170
171
  case 7:
171
- if (!(_b < testFiles_1.length)) return [3 /*break*/, 10];
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 8:
190
+ case 11:
175
191
  executionResult = _c.sent();
176
192
  if (!executionResult) {
177
- return [3 /*break*/, 9];
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 = 9;
189
- case 9:
204
+ _c.label = 12;
205
+ case 12:
190
206
  _b++;
191
- return [3 /*break*/, 7];
192
- case 10:
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":"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"}
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.30.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.30.1",
44
- "@featurevisor/site": "1.29.2",
45
- "@featurevisor/types": "1.29.2",
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": "8dc524c8a2a2ccb85661177e37ef1aff7cab8273"
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: string;
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,
@@ -77,7 +77,7 @@ export function benchmarkFeatureVariable(
77
77
  }
78
78
 
79
79
  export interface BenchmarkOptions {
80
- environment: string;
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
- if (parsedFeature.environments[options.environment].expose === false) {
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(parsedFeature.environments[options.environment].expose)) {
120
- const exposeTags = parsedFeature.environments[options.environment].expose as string[];
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 parsedFeature.environments[options.environment].rules) {
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
- parsedFeature.environments[options.environment].rules,
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 (parsedFeature.environments[options.environment].force) {
257
- feature.force = parsedFeature.environments[options.environment].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
- for (const environment of environments) {
67
- console.log(`\nBuilding datafiles for environment: ${environment}`);
68
-
69
- const existingState = await datasource.readState(environment);
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
- tag,
91
- datafilesDir: cliOptions.datafilesDir,
127
+ tags,
128
+ cliOptions,
92
129
  });
93
130
  }
131
+ }
94
132
 
95
- if (typeof cliOptions.stateFiles === "undefined" || cliOptions.stateFiles) {
96
- // write state for environment
97
- await datasource.writeState(environment, existingState);
98
-
99
- // write revision
100
- await datasource.writeRevision(nextRevision);
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);
@@ -39,7 +39,7 @@ export interface ProjectConfig {
39
39
  outputDirectoryPath: string;
40
40
  siteExportDirectoryPath: string;
41
41
 
42
- environments: string[];
42
+ environments: string[] | false;
43
43
  tags: string[];
44
44
 
45
45
  adapter: any; // @TODO: type this properly later
@@ -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(environment: EnvironmentKey, existingState: ExistingState): Promise<void>;
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
- return path.join(projectConfig.stateDirectoryPath, `existing-state-${environment}.json`);
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
- return path.join(dir, options.environment, fileName);
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 = path.join(dir, options.environment);
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);
@@ -50,7 +50,7 @@ function printHeader(message: string) {
50
50
  }
51
51
 
52
52
  export interface EvaluateOptions {
53
- environment: string;
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.forEach((v) => {
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
- v.key,
120
+ variableKey,
117
121
  options.context as Context,
118
122
  );
119
123
 
120
- variableEvaluationLogs[v.key] = [...logs];
124
+ variableEvaluationLogs[variableKey] = [...logs];
121
125
  logs = [];
122
126
 
123
- variableEvaluations[v.key] = variableEvaluation;
127
+ variableEvaluations[variableKey] = variableEvaluation;
124
128
  });
125
129
  }
126
130
 
@@ -52,34 +52,70 @@ export async function findAllUsageInFeatures(deps: Dependencies): Promise<UsageI
52
52
  }
53
53
 
54
54
  // variable overrides inside variations
55
- projectConfig.environments.forEach((environment) => {
56
- if (feature.variations) {
57
- feature.variations.forEach((variation) => {
58
- if (variation.variables) {
59
- variation.variables.forEach((variable) => {
60
- if (variable.overrides) {
61
- variable.overrides.forEach((override) => {
62
- if (override.segments) {
63
- extractSegmentKeysFromGroupSegments(override.segments).forEach((segmentKey) =>
64
- usageInFeatures[featureKey].segments.add(segmentKey),
65
- );
66
- }
67
-
68
- if (override.conditions) {
69
- extractAttributeKeysFromConditions(override.conditions).forEach(
70
- (attributeKey) => usageInFeatures[featureKey].attributes.add(attributeKey),
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.environments[environment].force) {
82
- feature.environments[environment].force?.forEach((force) => {
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.environments[environment].rules) {
99
- feature.environments[environment].rules?.forEach((rule) => {
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;