@fromeroc9/testform 1.0.2 → 1.0.4

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 (50) hide show
  1. package/dist/action/index.js +1 -1
  2. package/dist/action.js +60 -0
  3. package/dist/adapters/github.js +467 -0
  4. package/dist/adapters/resources.js +363 -0
  5. package/dist/cli/index.js +3 -3
  6. package/dist/commands/apply.js +390 -0
  7. package/dist/commands/destroy.js +85 -0
  8. package/dist/commands/diff.js +131 -0
  9. package/dist/commands/fmt.js +166 -0
  10. package/dist/commands/force-unlock.js +55 -0
  11. package/dist/commands/generate.js +143 -0
  12. package/dist/commands/graph.js +159 -0
  13. package/dist/commands/import.js +222 -0
  14. package/dist/commands/init.js +167 -0
  15. package/dist/commands/login.js +71 -0
  16. package/dist/commands/logout.js +20 -0
  17. package/dist/commands/plan.js +250 -0
  18. package/dist/commands/refresh.js +165 -0
  19. package/dist/commands/report.js +724 -0
  20. package/dist/commands/show.js +61 -0
  21. package/dist/commands/state.js +197 -0
  22. package/dist/commands/taint.js +49 -0
  23. package/dist/commands/validate.js +128 -0
  24. package/dist/commands/workspace.js +102 -0
  25. package/dist/const.js +105 -0
  26. package/dist/core/backends/azurerm.js +201 -0
  27. package/dist/core/backends/backend.js +2 -0
  28. package/dist/core/backends/gcs.js +200 -0
  29. package/dist/core/backends/local.js +162 -0
  30. package/dist/core/backends/s3.js +224 -0
  31. package/dist/core/command-context.js +59 -0
  32. package/dist/core/config.js +131 -0
  33. package/dist/core/credentials.js +53 -0
  34. package/dist/core/parser.js +62 -0
  35. package/dist/core/parsers/base-parser.js +215 -0
  36. package/dist/core/parsers/testcase-parser.js +115 -0
  37. package/dist/core/parsers/testplan-parser.js +41 -0
  38. package/dist/core/parsers/testrun-parser.js +43 -0
  39. package/dist/core/policy.js +341 -0
  40. package/dist/core/prompt.js +109 -0
  41. package/dist/core/state.js +185 -0
  42. package/dist/core/utils.js +94 -0
  43. package/dist/core/variables.js +108 -0
  44. package/dist/core/workspace.js +56 -0
  45. package/dist/help.js +797 -0
  46. package/dist/index.js +650 -0
  47. package/dist/logger.js +134 -0
  48. package/dist/notify.js +36 -0
  49. package/dist/types.js +2 -0
  50. package/package.json +2 -2
package/dist/index.js ADDED
@@ -0,0 +1,650 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.main = void 0;
8
+ const arg_1 = __importDefault(require("arg"));
9
+ const chalk_1 = require("chalk");
10
+ const node_process_1 = require("node:process");
11
+ const path_1 = require("path");
12
+ // Import commands
13
+ const init_1 = require("./commands/init");
14
+ const plan_1 = require("./commands/plan");
15
+ const validate_1 = require("./commands/validate");
16
+ const apply_1 = require("./commands/apply");
17
+ const destroy_1 = require("./commands/destroy");
18
+ const show_1 = require("./commands/show");
19
+ const refresh_1 = require("./commands/refresh");
20
+ const diff_1 = require("./commands/diff");
21
+ const import_1 = require("./commands/import");
22
+ const force_unlock_1 = require("./commands/force-unlock");
23
+ const state_1 = require("./commands/state");
24
+ const taint_1 = require("./commands/taint");
25
+ const graph_1 = require("./commands/graph");
26
+ const fmt_1 = require("./commands/fmt");
27
+ const login_1 = require("./commands/login");
28
+ const logout_1 = require("./commands/logout");
29
+ const workspace_1 = require("./commands/workspace");
30
+ const report_1 = require("./commands/report");
31
+ const generate_1 = require("./commands/generate");
32
+ const variables_1 = require("./core/variables");
33
+ const notify_1 = require("./notify");
34
+ const chalk_2 = __importDefault(require("chalk"));
35
+ const logger_1 = require("./logger");
36
+ const const_1 = require("./const");
37
+ const help_1 = require("./help");
38
+ function compareVersions(a, b) {
39
+ const pa = a.split('.').map((v) => Number(v));
40
+ const pb = b.split('.').map((v) => Number(v));
41
+ const size = Math.max(pa.length, pb.length);
42
+ for (let i = 0; i < size; i++) {
43
+ const av = pa.at(i) ?? 0;
44
+ const bv = pb.at(i) ?? 0;
45
+ if (av > bv)
46
+ return 1;
47
+ if (av < bv)
48
+ return -1;
49
+ }
50
+ return 0;
51
+ }
52
+ function printVersion(detailed = false) {
53
+ const latestVersion = process.env.TESTSTATE_LATEST_VERSION;
54
+ const platformArch = `${node_process_1.platform}_${node_process_1.arch}`;
55
+ console.log((0, chalk_1.cyan)(`${const_1.TITLE_APP} v${const_1.VERSION_CLI}`));
56
+ console.log(`on ${platformArch}`);
57
+ if (detailed) {
58
+ console.log(`+ Config Version: ${const_1.VERSION_CONFIG} (${const_1.FILE_CONFIG})`);
59
+ console.log(`+ State Version: ${const_1.VERSION_STATE} (${const_1.FILE_STATE})`);
60
+ }
61
+ if (latestVersion && compareVersions(const_1.VERSION_CLI, latestVersion) < 0) {
62
+ console.log('');
63
+ console.log(`Your version of ${const_1.TITLE_APP} is out of date! The latest version`);
64
+ console.log(`is ${latestVersion}. You can update from your release source.`);
65
+ }
66
+ }
67
+ function printTooManyArgsForInit() {
68
+ logger_1.logger.error('Too many command line arguments. Did you mean to use -chdir?');
69
+ }
70
+ function ensureNoPositionalArgs(command, args) {
71
+ if (args.length > 0) {
72
+ logger_1.logger.error(`Too many command line arguments\n\nTo specify a working directory for the ${command}, use the global -chdir flag.`);
73
+ }
74
+ }
75
+ function isScopeToken(value) {
76
+ if (!value)
77
+ return false;
78
+ return [
79
+ 'testcase',
80
+ 'testrun',
81
+ 'testplan',
82
+ ].includes(value.toLowerCase());
83
+ }
84
+ function normalizeLongFlags(rawArgs) {
85
+ const longFlags = new Set([
86
+ 'chdir',
87
+ 'scope',
88
+ 'help',
89
+ 'verbose',
90
+ 'version',
91
+ 'auto-approve',
92
+ 'out',
93
+ 'lock',
94
+ 'lock-timeout',
95
+ 'input',
96
+ 'var',
97
+ 'var-file',
98
+ 'no-color',
99
+ 'json',
100
+ 'detailed-exitcode',
101
+ 'state',
102
+ 'backup',
103
+ 'target',
104
+ 'destroy',
105
+ 'refresh',
106
+ 'refresh-only',
107
+ 'force',
108
+ 'check',
109
+ 'list',
110
+ 'write',
111
+ 'diff',
112
+ 'recursive',
113
+ 'plan',
114
+ 'draw-cycles',
115
+ 'type',
116
+ 'module-depth',
117
+ 'allow-missing',
118
+ 'ignore-remote-version',
119
+ 'backend',
120
+ 'backend-config',
121
+ 'force-copy',
122
+ 'from-module',
123
+ 'get',
124
+ 'plugin-dir',
125
+ 'reconfigure',
126
+ 'lockfile',
127
+ 'test-directory',
128
+ 'set-status',
129
+ 'set-state',
130
+ 'replace',
131
+ 'compact-warnings',
132
+ 'generate-config-out',
133
+ 'parallelism',
134
+ 'no-tests',
135
+ 'query',
136
+ 'state-out',
137
+ 'config',
138
+ 'taint',
139
+ 'untaint',
140
+ 'workspace',
141
+ 'report',
142
+ 'format',
143
+ 'filter',
144
+ 'id',
145
+ 'dry-run',
146
+ 'apply',
147
+ 'field',
148
+ 'rule'
149
+ ]);
150
+ return rawArgs.map((arg) => {
151
+ const match = arg.match(/^-([a-z][a-z-]*)(=.*)?$/i);
152
+ if (!match)
153
+ return arg;
154
+ const flag = match[1].toLowerCase();
155
+ const suffix = match[2] || '';
156
+ if (!longFlags.has(flag))
157
+ return arg;
158
+ return `--${flag}${suffix}`;
159
+ });
160
+ }
161
+ const booleanFlags = new Set([
162
+ '--help',
163
+ '--verbose',
164
+ '--version',
165
+ '--auto-approve',
166
+ '--lock',
167
+ '--input',
168
+ '--no-color',
169
+ '--json',
170
+ '--detailed-exitcode',
171
+ '--destroy',
172
+ '--refresh',
173
+ '--refresh-only',
174
+ '--force',
175
+ '--check',
176
+ '--list',
177
+ '--write',
178
+ '--diff',
179
+ '--recursive',
180
+ '--draw-cycles',
181
+ '--allow-missing',
182
+ '--ignore-remote-version',
183
+ '--backend',
184
+ '--reconfigure',
185
+ '--migrate-state',
186
+ '--compact-warnings',
187
+ '--no-tests',
188
+ '--dry-run',
189
+ '--apply'
190
+ ]);
191
+ const main = async () => {
192
+ let argv;
193
+ try {
194
+ const rawArgs = normalizeLongFlags(process.argv.slice(2));
195
+ const booleanOverrides = new Map();
196
+ const filteredArgs = [];
197
+ for (const argOption of rawArgs) {
198
+ const match = argOption.match(/^(--[a-z][a-z-]*)=(true|false)$/i);
199
+ if (match && booleanFlags.has(match[1])) {
200
+ booleanOverrides.set(match[1], match[2].toLowerCase() === 'true');
201
+ }
202
+ else {
203
+ filteredArgs.push(argOption);
204
+ }
205
+ }
206
+ argv = (0, arg_1.default)({
207
+ '--chdir': String,
208
+ '--projectId': String,
209
+ '--scope': String,
210
+ '--out': String,
211
+ '--lock-timeout': String,
212
+ '--var': [String],
213
+ '--var-file': [String],
214
+ '--state': String,
215
+ '--backup': String,
216
+ '--target': [String],
217
+ '--plan': String,
218
+ '--type': String,
219
+ '--module-depth': String,
220
+ '--backend-config': [String],
221
+ '--test-directory': String,
222
+ '--set-status': [String],
223
+ '--set-state': [String],
224
+ '--replace': [String],
225
+ '--parallelism': String,
226
+ '--state-out': String,
227
+ '--config': String,
228
+ '--taint': [String],
229
+ '--untaint': [String],
230
+ '--workspace': String,
231
+ '--report': String,
232
+ '--format': String,
233
+ '--filter': [String],
234
+ '--id': String,
235
+ '--field': [String],
236
+ '--rule': [String],
237
+ '--help': Boolean,
238
+ '--verbose': Boolean,
239
+ '--version': Boolean,
240
+ '--auto-approve': Boolean,
241
+ '--lock': Boolean,
242
+ '--input': Boolean,
243
+ '--no-color': Boolean,
244
+ '--json': Boolean,
245
+ '--detailed-exitcode': Boolean,
246
+ '--destroy': Boolean,
247
+ '--refresh': Boolean,
248
+ '--refresh-only': Boolean,
249
+ '--force': Boolean,
250
+ '--check': Boolean,
251
+ '--list': Boolean,
252
+ '--write': Boolean,
253
+ '--diff': Boolean,
254
+ '--apply': Boolean,
255
+ '--recursive': Boolean,
256
+ '--draw-cycles': Boolean,
257
+ '--allow-missing': Boolean,
258
+ '--ignore-remote-version': Boolean,
259
+ '--backend': Boolean,
260
+ '--reconfigure': Boolean,
261
+ '--migrate-state': Boolean,
262
+ '--compact-warnings': Boolean,
263
+ '--no-tests': Boolean,
264
+ '--dry-run': Boolean,
265
+ '-C': '--chdir',
266
+ '-s': '--scope',
267
+ '-h': '--help',
268
+ '-v': '--verbose',
269
+ '-a': '--auto-approve',
270
+ '-o': '--out',
271
+ }, { argv: filteredArgs });
272
+ Object.assign(argv, Object.fromEntries(booleanOverrides));
273
+ }
274
+ catch (err) {
275
+ if (err.code === 'ARG_UNKNOWN_OPTION') {
276
+ console.error(`\x1b[31mError: ${err.message}\x1b[0m\n`);
277
+ console.log(`Usage: ${const_1.TITLE_CLI} [global options] <subcommand> [args]\nRun '${const_1.TITLE_CLI} --help' for more information.`);
278
+ process.exit(1);
279
+ }
280
+ throw err;
281
+ }
282
+ const args = argv._.map(String);
283
+ if (argv['--version']) {
284
+ printVersion(false);
285
+ process.exit(0);
286
+ }
287
+ const rawArgs = argv._;
288
+ const commandRaw = rawArgs[0];
289
+ const commandArgsRaw = rawArgs.slice(1);
290
+ if (argv['--help']) {
291
+ if (commandRaw) {
292
+ let helpKey = commandRaw;
293
+ if (commandRaw === 'state' && commandArgsRaw.length > 0) {
294
+ helpKey = `state ${commandArgsRaw[0]}`;
295
+ }
296
+ const cmdHelp = (0, help_1.getCommandHelp)(helpKey);
297
+ if (cmdHelp) {
298
+ console.log(cmdHelp);
299
+ }
300
+ else {
301
+ console.log(`Unknown command: ${helpKey}\n\n${help_1.HELP_GLOBAL}`);
302
+ }
303
+ }
304
+ else {
305
+ console.log(help_1.HELP_GLOBAL);
306
+ }
307
+ process.exit(0);
308
+ }
309
+ if (!commandRaw) {
310
+ console.log(help_1.HELP_GLOBAL);
311
+ process.exit(0);
312
+ }
313
+ let command = commandRaw.toLowerCase();
314
+ let commandArgs = commandArgsRaw;
315
+ let scopeArg = String((argv['--scope'] ?? 'testcase') || 'testcase');
316
+ const workDir = String(argv['--chdir'] || '.');
317
+ const variableParser = new variables_1.VariableParser(argv['--var'], argv['--var-file'], workDir);
318
+ if (argv['--no-color']) {
319
+ chalk_2.default.level = 0;
320
+ }
321
+ // Supports: testcase plan ... (scope-first style)
322
+ if (isScopeToken(command) && args[1]) {
323
+ scopeArg = command;
324
+ command = args[1].toLowerCase();
325
+ commandArgs = args.slice(2);
326
+ }
327
+ if (!workDir) {
328
+ printTooManyArgsForInit();
329
+ process.exit(1);
330
+ }
331
+ const verbose = Boolean(argv['--verbose'] || argv['--verbose']);
332
+ const scope = scopeArg;
333
+ if (command === 'version') {
334
+ printVersion(true);
335
+ process.exit(process.exitCode || 0);
336
+ }
337
+ if (command === 'init') {
338
+ if (commandArgs.length > 0) {
339
+ printTooManyArgsForInit();
340
+ }
341
+ await (0, init_1.initCmd)({
342
+ dir: workDir,
343
+ verbose,
344
+ backendConfigRaw: argv['--backend-config'],
345
+ lock: argv['--lock'] ?? true,
346
+ lockTimeout: argv['--lock-timeout'] ?? '0s',
347
+ reconfigure: argv['--reconfigure'],
348
+ migrateState: argv['--migrate-state'],
349
+ backendEnabled: argv['--backend'] ?? true,
350
+ isJson: argv['--json'],
351
+ inputEnabled: argv['--input'] ?? true
352
+ });
353
+ process.exit(process.exitCode || 0);
354
+ }
355
+ if (command === 'validate') {
356
+ const validateDir = commandArgs.length > 0 ? commandArgs[0] : workDir;
357
+ if (commandArgs.length > 1) {
358
+ logger_1.logger.error(`Too many command line arguments\n\nExpected at most one positional argument.`);
359
+ }
360
+ await (0, validate_1.validateCmd)({
361
+ targetPath: validateDir,
362
+ verbose,
363
+ scope,
364
+ variables: variableParser,
365
+ isJson: argv['--json'],
366
+ testDirectory: argv['--test-directory'],
367
+ noTests: argv['--no-tests'],
368
+ query: argv['--query']
369
+ });
370
+ process.exit(process.exitCode || 0);
371
+ }
372
+ if (command === 'plan') {
373
+ ensureNoPositionalArgs(command, commandArgs);
374
+ await (0, plan_1.planCmd)({
375
+ dir: workDir,
376
+ verbose,
377
+ scope,
378
+ outPath: argv['--out'],
379
+ lock: argv['--lock'] ?? true,
380
+ lockTimeout: argv['--lock-timeout'] ?? '0s',
381
+ variables: variableParser,
382
+ isJson: argv['--json'],
383
+ detailedExitCode: argv['--detailed-exitcode'],
384
+ statePath: argv['--state'],
385
+ backupPath: argv['--backup'],
386
+ target: argv['--target'],
387
+ destroyPlan: argv['--destroy'],
388
+ refresh: argv['--refresh'] ?? true,
389
+ refreshOnly: argv['--refresh-only'],
390
+ replaceTargets: argv['--replace'],
391
+ parallelism: argv['--parallelism'],
392
+ compactWarnings: argv['--compact-warnings'] ?? false,
393
+ testDirectory: argv['--test-directory']
394
+ });
395
+ process.exit(process.exitCode || 0);
396
+ }
397
+ if (command === 'apply') {
398
+ let planFile = undefined;
399
+ if (commandArgs.length === 1) {
400
+ planFile = commandArgs[0];
401
+ }
402
+ else if (commandArgs.length > 1) {
403
+ logger_1.logger.error(`Too many command line arguments\n\nExpected at most one positional argument.`);
404
+ }
405
+ await (0, apply_1.applyCmd)({
406
+ dir: workDir,
407
+ autoApprove: Boolean(argv['--auto-approve'] || argv['--auto-approve']), // (Keeping the original logic from index.ts, though redundant)
408
+ verbose,
409
+ scope,
410
+ planFile,
411
+ lock: argv['--lock'] ?? true,
412
+ lockTimeout: argv['--lock-timeout'] ?? '0s',
413
+ input: argv['--input'] ?? true,
414
+ variables: variableParser,
415
+ statePath: argv['--state'],
416
+ backupPath: argv['--backup'],
417
+ target: argv['--target'],
418
+ refresh: argv['--refresh'] ?? true,
419
+ refreshOnly: argv['--refresh-only'],
420
+ setStatus: argv['--set-status']?.[0] || argv['--set-state']?.[0],
421
+ replaceTargets: argv['--replace'],
422
+ parallelism: argv['--parallelism'],
423
+ compactWarnings: argv['--compact-warnings'] ?? false,
424
+ testDirectory: argv['--test-directory']
425
+ });
426
+ process.exit(process.exitCode || 0);
427
+ }
428
+ if (command === 'destroy') {
429
+ ensureNoPositionalArgs(command, commandArgs);
430
+ await (0, destroy_1.destroyCmd)({
431
+ dir: workDir,
432
+ verbose,
433
+ scope,
434
+ lock: argv['--lock'] ?? true,
435
+ lockTimeout: argv['--lock-timeout'] ?? '0s',
436
+ input: argv['--input'] ?? true,
437
+ statePath: argv['--state'],
438
+ backupPath: argv['--backup']
439
+ });
440
+ process.exit(process.exitCode || 0);
441
+ }
442
+ if (command === 'show') {
443
+ const path = commandArgs[0];
444
+ await (0, show_1.showCmd)({
445
+ path,
446
+ isJson: argv['--json'],
447
+ verbose,
448
+ dir: String(argv['--chdir'] || '.'),
449
+ statePath: argv['--state'],
450
+ backupPath: argv['--backup']
451
+ });
452
+ process.exit(process.exitCode || 0);
453
+ }
454
+ if (command === 'refresh') {
455
+ ensureNoPositionalArgs(command, commandArgs);
456
+ await (0, refresh_1.refreshCmd)({
457
+ dir: workDir,
458
+ verbose,
459
+ scope,
460
+ lock: argv['--lock'] ?? true,
461
+ lockTimeout: argv['--lock-timeout'] ?? '0s',
462
+ statePath: argv['--state'],
463
+ backupPath: argv['--backup'],
464
+ parallelismRaw: argv['--parallelism'],
465
+ compactWarnings: argv['--compact-warnings'] ?? false
466
+ });
467
+ process.exit(process.exitCode || 0);
468
+ }
469
+ if (command === 'diff') {
470
+ ensureNoPositionalArgs(command, commandArgs);
471
+ await (0, diff_1.diffCmd)({
472
+ dir: workDir,
473
+ verbose,
474
+ scope
475
+ });
476
+ process.exit(0);
477
+ }
478
+ if (command === 'import') {
479
+ if (commandArgs.length !== 2) {
480
+ logger_1.logger.error(`Usage: ${const_1.TITLE_CLI} import [options] ADDR ISSUE_NUMBER`);
481
+ process.exit(1);
482
+ }
483
+ const identityArg = commandArgs[0];
484
+ const issueNumber = commandArgs[1];
485
+ await (0, import_1.importCmd)({
486
+ dir: workDir,
487
+ scope,
488
+ identityArg,
489
+ issueNumber,
490
+ lock: argv['--lock'] ?? true,
491
+ lockTimeout: argv['--lock-timeout'] ?? '0s',
492
+ statePath: argv['--state'],
493
+ backupPath: argv['--backup']
494
+ });
495
+ process.exit(process.exitCode || 0);
496
+ }
497
+ if (command === 'state') {
498
+ if (commandArgs.length === 0) {
499
+ console.log((0, help_1.getCommandHelp)('state'));
500
+ process.exit(1);
501
+ }
502
+ const stateSubCommand = commandArgs[0];
503
+ const stateArgs = commandArgs.slice(1);
504
+ await (0, state_1.stateCmd)({
505
+ dir: workDir,
506
+ action: stateSubCommand,
507
+ args: stateArgs,
508
+ statePath: argv['--state'],
509
+ backupPath: argv['--backup'],
510
+ isJson: argv['--json'],
511
+ id: argv['--id'],
512
+ dryRun: argv['--dry-run'],
513
+ force: argv['--force']
514
+ });
515
+ process.exit(process.exitCode || 0);
516
+ }
517
+ if (command === 'taint' || command === 'untaint') {
518
+ if (commandArgs.length === 0) {
519
+ logger_1.logger.error(`Usage: ${const_1.TITLE_CLI} ${command} [options] name`);
520
+ process.exit(1);
521
+ }
522
+ await (0, taint_1.taintCmd)({
523
+ dir: workDir,
524
+ action: command,
525
+ identityRaw: commandArgs[0],
526
+ statePath: argv['--state'],
527
+ backupPath: argv['--backup'],
528
+ allowMissing: argv['--allow-missing'],
529
+ lock: argv['--lock'] ?? true,
530
+ lockTimeout: argv['--lock-timeout'] ?? '0s'
531
+ });
532
+ process.exit(process.exitCode || 0);
533
+ }
534
+ if (command === 'workspace') {
535
+ await (0, workspace_1.workspaceCmd)({ dir: workDir, verbose, args: commandArgs });
536
+ process.exit(process.exitCode || 0);
537
+ }
538
+ if (command === 'force-unlock') {
539
+ if (commandArgs.length !== 1) {
540
+ logger_1.logger.error(`Usage: ${const_1.TITLE_CLI} force-unlock [options] LOCK_ID`);
541
+ process.exit(1);
542
+ }
543
+ await (0, force_unlock_1.forceUnlockCmd)({
544
+ dir: workDir,
545
+ lockId: commandArgs[0],
546
+ force: argv['--force'],
547
+ statePath: argv['--state']
548
+ });
549
+ process.exit(process.exitCode || 0);
550
+ }
551
+ if (command === 'graph') {
552
+ if (argv['--help']) {
553
+ const { HELP_GRAPH } = require('./help');
554
+ console.log(HELP_GRAPH);
555
+ process.exit(0);
556
+ }
557
+ ensureNoPositionalArgs(command, commandArgs);
558
+ await (0, graph_1.graphCmd)({
559
+ dir: workDir,
560
+ scope,
561
+ drawCycles: argv['--draw-cycles']
562
+ });
563
+ process.exit(process.exitCode || 0);
564
+ }
565
+ if (command === 'report') {
566
+ const type = commandArgs.length > 0 ? commandArgs[0] : 'raw';
567
+ await (0, report_1.reportCmd)({
568
+ dir: workDir,
569
+ type,
570
+ format: argv['--format'] || 'md',
571
+ filter: argv['--filter'] || [],
572
+ fields: argv['--field'] || [],
573
+ apply: argv['--apply'],
574
+ out: argv['--out'],
575
+ statePath: argv['--state']
576
+ });
577
+ process.exit(0);
578
+ }
579
+ if (command === 'generate') {
580
+ let genScope = undefined;
581
+ let titleArg = undefined;
582
+ const hasScopeFlag = Object.prototype.hasOwnProperty.call(argv, '--scope');
583
+ if (commandArgs.length > 0) {
584
+ // First argument could be scope or title
585
+ const first = commandArgs[0].toLowerCase();
586
+ if (['testcase', 'testrun', 'testplan'].includes(first)) {
587
+ genScope = first;
588
+ titleArg = commandArgs.slice(1).join(' ');
589
+ }
590
+ else {
591
+ titleArg = commandArgs.join(' ');
592
+ }
593
+ }
594
+ if (!genScope && hasScopeFlag) {
595
+ genScope = String(argv['--scope']);
596
+ }
597
+ if (!genScope) {
598
+ logger_1.logger.error(`Usage: testform generate <scope> [title]\n\nYou must specify the scope either as the first argument or using the -scope flag (e.g., -scope=testrun).`);
599
+ process.exit(1);
600
+ }
601
+ if (!['testcase', 'testrun', 'testplan'].includes(genScope)) {
602
+ logger_1.logger.error(`Invalid scope '${genScope}'. Must be one of: testcase, testrun, testplan.`);
603
+ process.exit(1);
604
+ }
605
+ if (!titleArg)
606
+ titleArg = undefined; // empty string to undefined
607
+ await (0, generate_1.generateCmd)({
608
+ dir: workDir,
609
+ scope: genScope,
610
+ title: titleArg,
611
+ rules: argv['--rule'] || []
612
+ });
613
+ process.exit(process.exitCode || 0);
614
+ }
615
+ if (command === 'fmt') {
616
+ const testDir = argv['--test-directory'] ? (0, path_1.resolve)(workDir, argv['--test-directory']) : workDir;
617
+ const targetDir = commandArgs.length > 0 ? (0, path_1.resolve)(workDir, commandArgs[0]) : testDir;
618
+ await (0, fmt_1.fmtCmd)({
619
+ dir: targetDir,
620
+ check: argv['--check'],
621
+ list: argv['--list'] ?? true,
622
+ write: argv['--write'] ?? true,
623
+ recursive: argv['--recursive']
624
+ });
625
+ process.exit(process.exitCode || 0);
626
+ }
627
+ if (command === 'login') {
628
+ const hostname = commandArgs.length > 0 ? commandArgs[0] : 'github.com';
629
+ await (0, login_1.loginCmd)({ hostname });
630
+ process.exit(process.exitCode || 0);
631
+ }
632
+ if (command === 'logout') {
633
+ const hostname = commandArgs.length > 0 ? commandArgs[0] : 'github.com';
634
+ await (0, logout_1.logoutCmd)({ hostname });
635
+ process.exit(process.exitCode || 0);
636
+ }
637
+ console.log(help_1.HELP_GLOBAL);
638
+ process.exit(1);
639
+ };
640
+ exports.main = main;
641
+ if (require.main === module || !module.parent) {
642
+ main().catch((err) => {
643
+ // console.error(err.stack);
644
+ notify_1.notify.push({
645
+ type: 'error',
646
+ title: err.name,
647
+ detail: [err.message]
648
+ });
649
+ });
650
+ }