rtgl 0.0.38 → 1.0.0-rc1
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/cli.js +67 -16
- package/package.json +2 -2
package/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { build, scaffold, watch, examples } from "@rettangoli/fe/cli";
|
|
3
|
+
import { build, check, scaffold, watch, examples } from "@rettangoli/fe/cli";
|
|
4
4
|
import { generate, report, accept } from "@rettangoli/vt/cli";
|
|
5
5
|
import { buildSite, watchSite, screenshotCommand, initSite } from "@rettangoli/sites/cli";
|
|
6
6
|
import { buildSvg } from "@rettangoli/ui/cli";
|
|
@@ -25,11 +25,14 @@ function readConfig() {
|
|
|
25
25
|
const configContent = readFileSync(configPath, "utf8");
|
|
26
26
|
return yaml.load(configContent);
|
|
27
27
|
} catch (error) {
|
|
28
|
-
|
|
29
|
-
return null;
|
|
28
|
+
throw new Error(`Error reading config file "${configPath}": ${error.message}`);
|
|
30
29
|
}
|
|
31
30
|
}
|
|
32
31
|
|
|
32
|
+
function collectValues(value, previous = []) {
|
|
33
|
+
return [...previous, value];
|
|
34
|
+
}
|
|
35
|
+
|
|
33
36
|
const program = new Command();
|
|
34
37
|
|
|
35
38
|
program
|
|
@@ -103,6 +106,41 @@ Examples:
|
|
|
103
106
|
build(options);
|
|
104
107
|
});
|
|
105
108
|
|
|
109
|
+
feCommand
|
|
110
|
+
.command("check")
|
|
111
|
+
.description("Validate frontend component file contracts")
|
|
112
|
+
.option("--format <format>", "Output format: text or json", "text")
|
|
113
|
+
.addHelpText(
|
|
114
|
+
"after",
|
|
115
|
+
`
|
|
116
|
+
|
|
117
|
+
Examples:
|
|
118
|
+
$ rettangoli fe check
|
|
119
|
+
$ rettangoli fe check --format json
|
|
120
|
+
`,
|
|
121
|
+
)
|
|
122
|
+
.action((options) => {
|
|
123
|
+
const config = readConfig();
|
|
124
|
+
|
|
125
|
+
if (!config) {
|
|
126
|
+
throw new Error("rettangoli.config.yaml not found");
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!config.fe?.dirs?.length) {
|
|
130
|
+
throw new Error("fe.dirs not found or empty in config");
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const missingDirs = config.fe.dirs.filter(
|
|
134
|
+
(dir) => !existsSync(resolve(process.cwd(), dir)),
|
|
135
|
+
);
|
|
136
|
+
if (missingDirs.length > 0) {
|
|
137
|
+
throw new Error(`Directories do not exist: ${missingDirs.join(", ")}`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
options.dirs = config.fe.dirs;
|
|
141
|
+
check(options);
|
|
142
|
+
});
|
|
143
|
+
|
|
106
144
|
feCommand
|
|
107
145
|
.command("scaffold")
|
|
108
146
|
.description("Scaffold UI components")
|
|
@@ -195,10 +233,14 @@ vtCommand
|
|
|
195
233
|
.command("generate")
|
|
196
234
|
.description("Generate visualizations")
|
|
197
235
|
.option("--skip-screenshots", "Skip screenshot generation")
|
|
198
|
-
.option("--
|
|
199
|
-
.option("--
|
|
200
|
-
.option("--wait-event <name>", "Custom event name to
|
|
201
|
-
.
|
|
236
|
+
.option("--concurrency <number>", "Number of parallel capture workers", parseInt)
|
|
237
|
+
.option("--timeout <ms>", "Global capture timeout in ms", parseInt)
|
|
238
|
+
.option("--wait-event <name>", "Custom event name to mark page ready (uses event wait strategy)")
|
|
239
|
+
.option("--folder <path>", "Run only specs under folder prefix (repeatable)", collectValues, [])
|
|
240
|
+
.option("--group <section-key>", "Run only one section key from vt.sections (repeatable)", collectValues, [])
|
|
241
|
+
.option("--item <spec-path>", "Run only one spec path relative to vt/specs (repeatable)", collectValues, [])
|
|
242
|
+
.option("--headed", "Run Playwright in headed mode")
|
|
243
|
+
.action(async (options) => {
|
|
202
244
|
console.log(`rtgl v${packageJson.version}`);
|
|
203
245
|
const config = readConfig();
|
|
204
246
|
|
|
@@ -208,17 +250,23 @@ vtCommand
|
|
|
208
250
|
|
|
209
251
|
// Use vt.path from config, default to 'vt'
|
|
210
252
|
options.vtPath = config.vt?.path || "vt";
|
|
253
|
+
if (options.headed) {
|
|
254
|
+
options.headless = false;
|
|
255
|
+
}
|
|
211
256
|
|
|
212
|
-
generate(options);
|
|
257
|
+
await generate(options);
|
|
213
258
|
});
|
|
214
259
|
|
|
215
260
|
vtCommand
|
|
216
261
|
.command("report")
|
|
217
262
|
.description("Create reports")
|
|
218
|
-
.option("--compare-method <method>", "Comparison method: pixelmatch or md5"
|
|
219
|
-
.option("--color-threshold <number>", "Color threshold for pixelmatch (0-1)", parseFloat
|
|
220
|
-
.option("--diff-threshold <number>", "Max diff pixels percentage to pass (0-100)", parseFloat
|
|
221
|
-
.
|
|
263
|
+
.option("--compare-method <method>", "Comparison method: pixelmatch or md5")
|
|
264
|
+
.option("--color-threshold <number>", "Color threshold for pixelmatch (0-1)", parseFloat)
|
|
265
|
+
.option("--diff-threshold <number>", "Max diff pixels percentage to pass (0-100)", parseFloat)
|
|
266
|
+
.option("--folder <path>", "Compare only screenshots under folder prefix (repeatable)", collectValues, [])
|
|
267
|
+
.option("--group <section-key>", "Compare only one section key from vt.sections (repeatable)", collectValues, [])
|
|
268
|
+
.option("--item <spec-path>", "Compare only one spec path relative to vt/specs (repeatable)", collectValues, [])
|
|
269
|
+
.action(async (options) => {
|
|
222
270
|
const config = readConfig();
|
|
223
271
|
|
|
224
272
|
if (!config) {
|
|
@@ -226,18 +274,21 @@ vtCommand
|
|
|
226
274
|
}
|
|
227
275
|
|
|
228
276
|
const vtPath = config.vt?.path || "vt";
|
|
229
|
-
report({
|
|
277
|
+
await report({
|
|
230
278
|
vtPath,
|
|
231
279
|
compareMethod: options.compareMethod,
|
|
232
280
|
colorThreshold: options.colorThreshold,
|
|
233
281
|
diffThreshold: options.diffThreshold,
|
|
282
|
+
folder: options.folder,
|
|
283
|
+
group: options.group,
|
|
284
|
+
item: options.item,
|
|
234
285
|
});
|
|
235
286
|
});
|
|
236
287
|
|
|
237
288
|
vtCommand
|
|
238
289
|
.command("accept")
|
|
239
290
|
.description("Accept changes")
|
|
240
|
-
.action(() => {
|
|
291
|
+
.action(async () => {
|
|
241
292
|
const config = readConfig();
|
|
242
293
|
|
|
243
294
|
if (!config) {
|
|
@@ -245,7 +296,7 @@ vtCommand
|
|
|
245
296
|
}
|
|
246
297
|
|
|
247
298
|
const vtPath = config.vt?.path || "vt";
|
|
248
|
-
accept({ vtPath });
|
|
299
|
+
await accept({ vtPath });
|
|
249
300
|
});
|
|
250
301
|
|
|
251
302
|
const sitesCommand = program.command("sites").description("Rettangoli Sites");
|
|
@@ -349,4 +400,4 @@ Examples:
|
|
|
349
400
|
buildSvg(options);
|
|
350
401
|
});
|
|
351
402
|
|
|
352
|
-
program.
|
|
403
|
+
await program.parseAsync();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rtgl",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0-rc1",
|
|
4
4
|
"description": "CLI tool for Rettangoli - A frontend framework and development toolkit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"js-yaml": "^4.1.0",
|
|
50
50
|
"@rettangoli/fe": "0.0.14",
|
|
51
51
|
"@rettangoli/sites": "0.2.7",
|
|
52
|
-
"@rettangoli/vt": "0.0
|
|
52
|
+
"@rettangoli/vt": "1.0.0-rc1",
|
|
53
53
|
"@rettangoli/ui": "0.1.31"
|
|
54
54
|
}
|
|
55
55
|
}
|