@featurevisor/core 1.5.1 → 1.7.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/.eslintcache +1 -1
- package/CHANGELOG.md +22 -0
- package/coverage/clover.xml +2 -2
- package/coverage/lcov-report/index.html +1 -1
- 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/traffic.js.html +1 -1
- package/coverage/lcov-report/lib/tester/checkIfObjectsAreEqual.js.html +1 -1
- package/coverage/lcov-report/lib/tester/index.html +1 -1
- package/coverage/lcov-report/lib/tester/matrix.js.html +1 -1
- 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/traffic.ts.html +1 -1
- package/coverage/lcov-report/src/tester/checkIfObjectsAreEqual.ts.html +1 -1
- package/coverage/lcov-report/src/tester/index.html +1 -1
- package/coverage/lcov-report/src/tester/matrix.ts.html +1 -1
- package/lib/linter/attributeSchema.d.ts +17 -2
- package/lib/linter/attributeSchema.js +13 -11
- package/lib/linter/attributeSchema.js.map +1 -1
- package/lib/linter/checkPercentageExceedingSlot.d.ts +3 -0
- package/lib/linter/checkPercentageExceedingSlot.js +86 -0
- package/lib/linter/checkPercentageExceedingSlot.js.map +1 -0
- package/lib/linter/conditionSchema.d.ts +2 -2
- package/lib/linter/conditionSchema.js +112 -57
- package/lib/linter/conditionSchema.js.map +1 -1
- package/lib/linter/featureSchema.d.ts +229 -2
- package/lib/linter/featureSchema.js +195 -139
- package/lib/linter/featureSchema.js.map +1 -1
- package/lib/linter/groupSchema.d.ts +32 -2
- package/lib/linter/groupSchema.js +28 -97
- package/lib/linter/groupSchema.js.map +1 -1
- package/lib/linter/lintProject.d.ts +5 -1
- package/lib/linter/lintProject.js +213 -139
- package/lib/linter/lintProject.js.map +1 -1
- package/lib/linter/printError.d.ts +2 -0
- package/lib/linter/printError.js +20 -0
- package/lib/linter/printError.js.map +1 -0
- package/lib/linter/segmentSchema.d.ts +14 -2
- package/lib/linter/segmentSchema.js +12 -10
- package/lib/linter/segmentSchema.js.map +1 -1
- package/lib/linter/testSchema.d.ts +90 -2
- package/lib/linter/testSchema.js +49 -38
- package/lib/linter/testSchema.js.map +1 -1
- package/lib/tester/cliFormat.d.ts +1 -0
- package/lib/tester/cliFormat.js +2 -1
- package/lib/tester/cliFormat.js.map +1 -1
- package/package.json +4 -4
- package/src/linter/attributeSchema.ts +11 -9
- package/src/linter/checkPercentageExceedingSlot.ts +41 -0
- package/src/linter/conditionSchema.ts +120 -97
- package/src/linter/featureSchema.ts +241 -177
- package/src/linter/groupSchema.ts +38 -54
- package/src/linter/lintProject.ts +233 -110
- package/src/linter/printError.ts +21 -0
- package/src/linter/segmentSchema.ts +10 -8
- package/src/linter/testSchema.ts +67 -50
- package/src/tester/cliFormat.ts +1 -0
- package/lib/linter/printJoiError.d.ts +0 -2
- package/lib/linter/printJoiError.js +0 -14
- package/lib/linter/printJoiError.js.map +0 -1
- package/src/linter/printJoiError.ts +0 -11
|
@@ -1,142 +1,248 @@
|
|
|
1
1
|
// for use in node only
|
|
2
|
-
import * as
|
|
2
|
+
import * as path from "path";
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
4
|
+
import { getAttributeZodSchema } from "./attributeSchema";
|
|
5
|
+
import { getConditionsZodSchema } from "./conditionSchema";
|
|
6
|
+
import { getSegmentZodSchema } from "./segmentSchema";
|
|
7
|
+
import { getGroupZodSchema } from "./groupSchema";
|
|
8
|
+
import { getFeatureZodSchema } from "./featureSchema";
|
|
9
|
+
import { getTestsZodSchema } from "./testSchema";
|
|
10
10
|
|
|
11
11
|
import { checkForCircularDependencyInRequired } from "./checkCircularDependency";
|
|
12
|
-
import {
|
|
12
|
+
import { checkForFeatureExceedingGroupSlotPercentage } from "./checkPercentageExceedingSlot";
|
|
13
|
+
import { printZodError } from "./printError";
|
|
13
14
|
import { Dependencies } from "../dependencies";
|
|
15
|
+
import { CLI_FORMAT_RED, CLI_FORMAT_UNDERLINE } from "../tester/cliFormat";
|
|
14
16
|
|
|
15
|
-
export
|
|
17
|
+
export interface LintProjectOptions {
|
|
18
|
+
keyPattern?: string;
|
|
19
|
+
entityType?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function lintProject(
|
|
23
|
+
deps: Dependencies,
|
|
24
|
+
options: LintProjectOptions = {},
|
|
25
|
+
): Promise<boolean> {
|
|
16
26
|
const { projectConfig, datasource } = deps;
|
|
17
27
|
|
|
18
28
|
let hasError = false;
|
|
19
29
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
30
|
+
function getFullPathFromKey(type: string, key: string, relative = false) {
|
|
31
|
+
const fileName = `${key}.${datasource.getExtension()}`;
|
|
32
|
+
let fullPath = "";
|
|
33
|
+
|
|
34
|
+
if (type === "attribute") {
|
|
35
|
+
fullPath = path.join(projectConfig.attributesDirectoryPath, fileName);
|
|
36
|
+
} else if (type === "segment") {
|
|
37
|
+
fullPath = path.join(projectConfig.segmentsDirectoryPath, fileName);
|
|
38
|
+
} else if (type === "feature") {
|
|
39
|
+
fullPath = path.join(projectConfig.featuresDirectoryPath, fileName);
|
|
40
|
+
} else if (type === "group") {
|
|
41
|
+
fullPath = path.join(projectConfig.groupsDirectoryPath, fileName);
|
|
42
|
+
} else if (type === "test") {
|
|
43
|
+
fullPath = path.join(projectConfig.testsDirectoryPath, fileName);
|
|
44
|
+
} else {
|
|
45
|
+
throw new Error(`Unknown type: ${type}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (relative) {
|
|
49
|
+
fullPath = path.relative(process.cwd(), fullPath);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return fullPath;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const keyPattern = options.keyPattern ? new RegExp(options.keyPattern) : null;
|
|
56
|
+
|
|
57
|
+
if (keyPattern) {
|
|
58
|
+
console.log("");
|
|
59
|
+
console.log(`Linting only keys matching pattern: ${keyPattern}`);
|
|
60
|
+
console.log("");
|
|
61
|
+
}
|
|
23
62
|
|
|
24
63
|
// lint attributes
|
|
25
64
|
const attributes = await datasource.listAttributes();
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
65
|
+
const attributeZodSchema = getAttributeZodSchema();
|
|
66
|
+
|
|
67
|
+
if (!options.entityType || options.entityType === "attribute") {
|
|
68
|
+
const filteredKeys = !keyPattern
|
|
69
|
+
? attributes
|
|
70
|
+
: attributes.filter((key) => keyPattern.test(key));
|
|
71
|
+
|
|
72
|
+
if (filteredKeys.length > 0) {
|
|
73
|
+
console.log(`Linting ${filteredKeys.length} attributes...\n`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
for (const key of filteredKeys) {
|
|
77
|
+
const fullPath = getFullPathFromKey("attribute", key);
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const parsed = await datasource.readAttribute(key);
|
|
81
|
+
|
|
82
|
+
const result = attributeZodSchema.safeParse(parsed);
|
|
83
|
+
|
|
84
|
+
if (!result.success) {
|
|
85
|
+
console.log(CLI_FORMAT_UNDERLINE, fullPath);
|
|
86
|
+
|
|
87
|
+
if ("error" in result) {
|
|
88
|
+
printZodError(result.error);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
hasError = true;
|
|
92
|
+
}
|
|
93
|
+
} catch (e) {
|
|
94
|
+
console.log(CLI_FORMAT_UNDERLINE, fullPath);
|
|
95
|
+
console.log("");
|
|
42
96
|
console.log(e);
|
|
43
|
-
}
|
|
44
97
|
|
|
45
|
-
|
|
98
|
+
hasError = true;
|
|
99
|
+
}
|
|
46
100
|
}
|
|
47
101
|
}
|
|
48
102
|
|
|
49
103
|
// lint segments
|
|
50
104
|
const segments = await datasource.listSegments();
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
105
|
+
const conditionsZodSchema = getConditionsZodSchema(
|
|
106
|
+
projectConfig,
|
|
107
|
+
attributes as [string, ...string[]],
|
|
108
|
+
);
|
|
109
|
+
const segmentZodSchema = getSegmentZodSchema(projectConfig, conditionsZodSchema);
|
|
110
|
+
|
|
111
|
+
if (!options.entityType || options.entityType === "segment") {
|
|
112
|
+
const filteredKeys = !keyPattern ? segments : segments.filter((key) => keyPattern.test(key));
|
|
113
|
+
|
|
114
|
+
if (filteredKeys.length > 0) {
|
|
115
|
+
console.log(`Linting ${filteredKeys.length} segments...\n`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
for (const key of filteredKeys) {
|
|
119
|
+
const fullPath = getFullPathFromKey("segment", key);
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
const parsed = await datasource.readSegment(key);
|
|
123
|
+
|
|
124
|
+
const result = segmentZodSchema.safeParse(parsed);
|
|
125
|
+
|
|
126
|
+
if (!result.success) {
|
|
127
|
+
console.log(CLI_FORMAT_UNDERLINE, fullPath);
|
|
128
|
+
|
|
129
|
+
if ("error" in result) {
|
|
130
|
+
printZodError(result.error);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
hasError = true;
|
|
134
|
+
}
|
|
135
|
+
} catch (e) {
|
|
136
|
+
console.log(CLI_FORMAT_UNDERLINE, fullPath);
|
|
137
|
+
console.log("");
|
|
68
138
|
console.log(e);
|
|
69
|
-
}
|
|
70
139
|
|
|
71
|
-
|
|
140
|
+
hasError = true;
|
|
141
|
+
}
|
|
72
142
|
}
|
|
73
143
|
}
|
|
74
144
|
|
|
75
145
|
// lint features
|
|
76
146
|
const features = await datasource.listFeatures();
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const featureJoiSchema = getFeatureJoiSchema(
|
|
147
|
+
const featureZodSchema = getFeatureZodSchema(
|
|
80
148
|
projectConfig,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
149
|
+
conditionsZodSchema,
|
|
150
|
+
attributes as [string, ...string[]],
|
|
151
|
+
segments as [string, ...string[]],
|
|
152
|
+
features as [string, ...string[]],
|
|
84
153
|
);
|
|
85
154
|
|
|
86
|
-
|
|
87
|
-
|
|
155
|
+
if (!options.entityType || options.entityType === "feature") {
|
|
156
|
+
const filteredKeys = !keyPattern ? features : features.filter((key) => keyPattern.test(key));
|
|
88
157
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
158
|
+
if (filteredKeys.length > 0) {
|
|
159
|
+
console.log(`Linting ${filteredKeys.length} features...\n`);
|
|
160
|
+
}
|
|
92
161
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
console.log("");
|
|
162
|
+
for (const key of filteredKeys) {
|
|
163
|
+
const fullPath = getFullPathFromKey("feature", key);
|
|
164
|
+
let parsed;
|
|
97
165
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
} else {
|
|
101
|
-
console.log(e);
|
|
102
|
-
}
|
|
166
|
+
try {
|
|
167
|
+
parsed = await datasource.readFeature(key);
|
|
103
168
|
|
|
104
|
-
|
|
105
|
-
}
|
|
169
|
+
const result = featureZodSchema.safeParse(parsed);
|
|
106
170
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
171
|
+
if (!result.success) {
|
|
172
|
+
console.log(CLI_FORMAT_UNDERLINE, fullPath);
|
|
173
|
+
|
|
174
|
+
if ("error" in result) {
|
|
175
|
+
printZodError(result.error);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
hasError = true;
|
|
179
|
+
}
|
|
110
180
|
} catch (e) {
|
|
111
|
-
console.log(
|
|
112
|
-
console.log("
|
|
181
|
+
console.log(CLI_FORMAT_UNDERLINE, fullPath);
|
|
182
|
+
console.log("");
|
|
183
|
+
console.log(e);
|
|
184
|
+
|
|
113
185
|
hasError = true;
|
|
114
186
|
}
|
|
187
|
+
|
|
188
|
+
if (parsed && parsed.required) {
|
|
189
|
+
try {
|
|
190
|
+
await checkForCircularDependencyInRequired(datasource, key, parsed.required);
|
|
191
|
+
} catch (e) {
|
|
192
|
+
console.log(CLI_FORMAT_UNDERLINE, fullPath);
|
|
193
|
+
console.log(CLI_FORMAT_RED, ` => Error: ${e.message}`);
|
|
194
|
+
hasError = true;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
115
197
|
}
|
|
116
198
|
}
|
|
117
199
|
|
|
118
200
|
// lint groups
|
|
119
201
|
const groups = await datasource.listGroups();
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
202
|
+
const groupZodSchema = getGroupZodSchema(projectConfig, datasource, features);
|
|
203
|
+
|
|
204
|
+
if (!options.entityType || options.entityType === "group") {
|
|
205
|
+
const filteredKeys = !keyPattern ? groups : groups.filter((key) => keyPattern.test(key));
|
|
206
|
+
|
|
207
|
+
if (filteredKeys.length > 0) {
|
|
208
|
+
console.log(`Linting ${filteredKeys.length} groups...\n`);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
for (const key of filteredKeys) {
|
|
212
|
+
const fullPath = getFullPathFromKey("group", key);
|
|
213
|
+
let parsed;
|
|
214
|
+
|
|
215
|
+
try {
|
|
216
|
+
parsed = await datasource.readGroup(key);
|
|
217
|
+
|
|
218
|
+
const result = groupZodSchema.safeParse(parsed);
|
|
219
|
+
|
|
220
|
+
if (!result.success) {
|
|
221
|
+
console.log(CLI_FORMAT_UNDERLINE, fullPath);
|
|
222
|
+
|
|
223
|
+
if ("error" in result) {
|
|
224
|
+
printZodError(result.error);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
hasError = true;
|
|
228
|
+
}
|
|
229
|
+
} catch (e) {
|
|
230
|
+
console.log(CLI_FORMAT_UNDERLINE, fullPath);
|
|
231
|
+
console.log("");
|
|
136
232
|
console.log(e);
|
|
233
|
+
|
|
234
|
+
hasError = true;
|
|
137
235
|
}
|
|
138
236
|
|
|
139
|
-
|
|
237
|
+
if (parsed) {
|
|
238
|
+
try {
|
|
239
|
+
await checkForFeatureExceedingGroupSlotPercentage(datasource, parsed, features);
|
|
240
|
+
} catch (e) {
|
|
241
|
+
console.log(CLI_FORMAT_UNDERLINE, fullPath);
|
|
242
|
+
console.log(CLI_FORMAT_RED, ` => Error: ${e.message}`);
|
|
243
|
+
hasError = true;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
140
246
|
}
|
|
141
247
|
}
|
|
142
248
|
|
|
@@ -144,29 +250,46 @@ export async function lintProject(deps: Dependencies): Promise<boolean> {
|
|
|
144
250
|
|
|
145
251
|
// lint tests
|
|
146
252
|
const tests = await datasource.listTests();
|
|
147
|
-
console.log(`\nLinting ${tests.length} tests...\n`);
|
|
148
253
|
|
|
149
|
-
const
|
|
254
|
+
const testsZodSchema = getTestsZodSchema(
|
|
150
255
|
projectConfig,
|
|
151
|
-
|
|
152
|
-
|
|
256
|
+
features as [string, ...string[]],
|
|
257
|
+
segments as [string, ...string[]],
|
|
153
258
|
);
|
|
154
259
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
260
|
+
if (!options.entityType || options.entityType === "test") {
|
|
261
|
+
const filteredKeys = !keyPattern ? tests : tests.filter((key) => keyPattern.test(key));
|
|
262
|
+
|
|
263
|
+
if (filteredKeys.length > 0) {
|
|
264
|
+
console.log(`Linting ${filteredKeys.length} tests...\n`);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
for (const key of filteredKeys) {
|
|
268
|
+
const fullPath = getFullPathFromKey("test", key);
|
|
269
|
+
|
|
270
|
+
try {
|
|
271
|
+
const parsed = await datasource.readTest(key);
|
|
272
|
+
|
|
273
|
+
const result = testsZodSchema.safeParse(parsed);
|
|
274
|
+
|
|
275
|
+
if (!result.success) {
|
|
276
|
+
console.log(CLI_FORMAT_UNDERLINE, fullPath);
|
|
277
|
+
|
|
278
|
+
if ("error" in result) {
|
|
279
|
+
printZodError(result.error);
|
|
280
|
+
|
|
281
|
+
process.exit(1);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
hasError = true;
|
|
285
|
+
}
|
|
286
|
+
} catch (e) {
|
|
287
|
+
console.log(CLI_FORMAT_UNDERLINE, fullPath);
|
|
288
|
+
console.log("");
|
|
166
289
|
console.log(e);
|
|
167
|
-
}
|
|
168
290
|
|
|
169
|
-
|
|
291
|
+
hasError = true;
|
|
292
|
+
}
|
|
170
293
|
}
|
|
171
294
|
}
|
|
172
295
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ZodError } from "zod";
|
|
2
|
+
|
|
3
|
+
import { CLI_FORMAT_RED } from "../tester/cliFormat";
|
|
4
|
+
|
|
5
|
+
export function printZodError(e: ZodError) {
|
|
6
|
+
const { issues } = e;
|
|
7
|
+
|
|
8
|
+
issues.forEach((issue) => {
|
|
9
|
+
console.error(CLI_FORMAT_RED, ` => Error: ${issue.message}`);
|
|
10
|
+
console.error(" Path:", issue.path.join("."));
|
|
11
|
+
|
|
12
|
+
const receivedValue = (issue as any).received;
|
|
13
|
+
if (typeof receivedValue !== "undefined" && receivedValue !== "undefined") {
|
|
14
|
+
console.error(" Value:", receivedValue);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (issues.length > 1) {
|
|
18
|
+
console.error("");
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { z } from "zod";
|
|
2
2
|
|
|
3
3
|
import { ProjectConfig } from "../config";
|
|
4
4
|
|
|
5
|
-
export function
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
export function getSegmentZodSchema(projectConfig: ProjectConfig, conditionsZodSchema) {
|
|
6
|
+
const segmentZodSchema = z
|
|
7
|
+
.object({
|
|
8
|
+
archived: z.boolean().optional(),
|
|
9
|
+
description: z.string(),
|
|
10
|
+
conditions: conditionsZodSchema,
|
|
11
|
+
})
|
|
12
|
+
.strict();
|
|
11
13
|
|
|
12
|
-
return
|
|
14
|
+
return segmentZodSchema;
|
|
13
15
|
}
|
package/src/linter/testSchema.ts
CHANGED
|
@@ -1,62 +1,79 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { z } from "zod";
|
|
2
2
|
|
|
3
3
|
import { ProjectConfig } from "../config";
|
|
4
4
|
|
|
5
|
-
export function
|
|
5
|
+
export function getTestsZodSchema(
|
|
6
6
|
projectConfig: ProjectConfig,
|
|
7
|
-
availableFeatureKeys: string[],
|
|
8
|
-
availableSegmentKeys: string[],
|
|
7
|
+
availableFeatureKeys: [string, ...string[]],
|
|
8
|
+
availableSegmentKeys: [string, ...string[]],
|
|
9
9
|
) {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
10
|
+
const segmentTestZodSchema = z
|
|
11
|
+
.object({
|
|
12
|
+
segment: z.string().refine(
|
|
13
|
+
(value) => availableSegmentKeys.includes(value),
|
|
14
|
+
(value) => ({
|
|
15
|
+
message: `Unknown segment "${value}"`,
|
|
16
|
+
}),
|
|
17
|
+
),
|
|
18
|
+
assertions: z.array(
|
|
19
|
+
z
|
|
20
|
+
.object({
|
|
21
|
+
matrix: z.record(z.unknown()).optional(), // @TODO: make it stricter
|
|
22
|
+
description: z.string().optional(),
|
|
23
|
+
context: z.record(z.unknown()),
|
|
24
|
+
expectedToMatch: z.boolean(),
|
|
25
|
+
})
|
|
26
|
+
.strict(),
|
|
27
|
+
),
|
|
28
|
+
})
|
|
29
|
+
.strict();
|
|
23
30
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
const featureTestZodSchema = z
|
|
32
|
+
.object({
|
|
33
|
+
feature: z.string().refine(
|
|
34
|
+
(value) => availableFeatureKeys.includes(value),
|
|
35
|
+
(value) => ({
|
|
36
|
+
message: `Unknown feature "${value}"`,
|
|
37
|
+
}),
|
|
38
|
+
),
|
|
39
|
+
assertions: z.array(
|
|
40
|
+
z
|
|
41
|
+
.object({
|
|
42
|
+
matrix: z.record(z.unknown()).optional(), // @TODO: make it stricter
|
|
43
|
+
description: z.string().optional(),
|
|
44
|
+
at: z.union([
|
|
45
|
+
z.number().min(0).max(100),
|
|
34
46
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
// because of supporting matrix
|
|
48
|
+
z.string(),
|
|
49
|
+
]),
|
|
50
|
+
environment: z.string().refine(
|
|
51
|
+
(value) => {
|
|
52
|
+
if (value.indexOf("${{") === 0) {
|
|
53
|
+
// allow unknown strings for matrix
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
44
56
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
57
|
+
// otherwise only known environments should be passed
|
|
58
|
+
if (projectConfig.environments.includes(value)) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
49
61
|
|
|
50
|
-
|
|
62
|
+
return false;
|
|
63
|
+
},
|
|
64
|
+
(value) => ({
|
|
65
|
+
message: `Unknown environment "${value}"`,
|
|
66
|
+
}),
|
|
67
|
+
),
|
|
68
|
+
context: z.record(z.unknown()),
|
|
69
|
+
expectedToBeEnabled: z.boolean(),
|
|
70
|
+
expectedVariation: z.string().optional(),
|
|
71
|
+
expectedVariables: z.record(z.unknown()).optional(),
|
|
51
72
|
})
|
|
52
|
-
.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
expectedVariables: Joi.object(),
|
|
57
|
-
}),
|
|
58
|
-
),
|
|
59
|
-
});
|
|
73
|
+
.strict(),
|
|
74
|
+
),
|
|
75
|
+
})
|
|
76
|
+
.strict();
|
|
60
77
|
|
|
61
|
-
return
|
|
78
|
+
return z.union([segmentTestZodSchema, featureTestZodSchema]);
|
|
62
79
|
}
|
package/src/tester/cliFormat.ts
CHANGED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.printJoiError = void 0;
|
|
4
|
-
function printJoiError(e) {
|
|
5
|
-
var details = e.details;
|
|
6
|
-
details.forEach(function (detail) {
|
|
7
|
-
var _a;
|
|
8
|
-
console.error(" => Error:", detail.message);
|
|
9
|
-
console.error(" => Path:", detail.path.join("."));
|
|
10
|
-
console.error(" => Value:", (_a = detail.context) === null || _a === void 0 ? void 0 : _a.value);
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
exports.printJoiError = printJoiError;
|
|
14
|
-
//# sourceMappingURL=printJoiError.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"printJoiError.js","sourceRoot":"","sources":["../../src/linter/printJoiError.ts"],"names":[],"mappings":";;;AAEA,SAAgB,aAAa,CAAC,CAAsB;IAC1C,IAAA,OAAO,GAAK,CAAC,QAAN,CAAO;IAEtB,OAAO,CAAC,OAAO,CAAC,UAAC,MAAM;;QACrB,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QAChD,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,MAAA,MAAM,CAAC,OAAO,0CAAE,KAAK,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC;AARD,sCAQC"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import * as Joi from "joi";
|
|
2
|
-
|
|
3
|
-
export function printJoiError(e: Joi.ValidationError) {
|
|
4
|
-
const { details } = e;
|
|
5
|
-
|
|
6
|
-
details.forEach((detail) => {
|
|
7
|
-
console.error(" => Error:", detail.message);
|
|
8
|
-
console.error(" => Path:", detail.path.join("."));
|
|
9
|
-
console.error(" => Value:", detail.context?.value);
|
|
10
|
-
});
|
|
11
|
-
}
|