@tlog/cli 0.1.3

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 (40) hide show
  1. package/README.md +307 -0
  2. package/bin/.gitkeep +0 -0
  3. package/bin/tlog.js +4 -0
  4. package/dist/commands/delete.d.ts +8 -0
  5. package/dist/commands/delete.d.ts.map +1 -0
  6. package/dist/commands/delete.js +104 -0
  7. package/dist/commands/delete.js.map +1 -0
  8. package/dist/commands/init-template.d.ts +12 -0
  9. package/dist/commands/init-template.d.ts.map +1 -0
  10. package/dist/commands/init-template.js +168 -0
  11. package/dist/commands/init-template.js.map +1 -0
  12. package/dist/commands/related.d.ts +13 -0
  13. package/dist/commands/related.d.ts.map +1 -0
  14. package/dist/commands/related.js +193 -0
  15. package/dist/commands/related.js.map +1 -0
  16. package/dist/commands/stats.d.ts +8 -0
  17. package/dist/commands/stats.d.ts.map +1 -0
  18. package/dist/commands/stats.js +62 -0
  19. package/dist/commands/stats.js.map +1 -0
  20. package/dist/commands/suite-case.d.ts +20 -0
  21. package/dist/commands/suite-case.d.ts.map +1 -0
  22. package/dist/commands/suite-case.js +83 -0
  23. package/dist/commands/suite-case.js.map +1 -0
  24. package/dist/commands/update.d.ts +33 -0
  25. package/dist/commands/update.d.ts.map +1 -0
  26. package/dist/commands/update.js +159 -0
  27. package/dist/commands/update.js.map +1 -0
  28. package/dist/commands/validate-list.d.ts +36 -0
  29. package/dist/commands/validate-list.d.ts.map +1 -0
  30. package/dist/commands/validate-list.js +270 -0
  31. package/dist/commands/validate-list.js.map +1 -0
  32. package/dist/core.d.ts +30 -0
  33. package/dist/core.d.ts.map +1 -0
  34. package/dist/core.js +143 -0
  35. package/dist/core.js.map +1 -0
  36. package/dist/index.d.ts +4 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +218 -0
  39. package/dist/index.js.map +1 -0
  40. package/package.json +39 -0
package/README.md ADDED
@@ -0,0 +1,307 @@
1
+ # @tlog/cli
2
+
3
+ `tlog` is a YAML-first test management CLI.
4
+
5
+ It helps you bootstrap a test workspace, create suites/cases, validate schema consistency, and manage related links from the terminal.
6
+
7
+ ## Install
8
+
9
+ ### Option 1: Global install (recommended for daily use)
10
+
11
+ ```bash
12
+ npm install -g @tlog/cli
13
+ ```
14
+
15
+ Check installation:
16
+
17
+ ```bash
18
+ tlog --version
19
+ tlog --help
20
+ ```
21
+
22
+ ### Option 2: Run without installing globally
23
+
24
+ ```bash
25
+ npx @tlog/cli --help
26
+ ```
27
+
28
+ ## Quick Start
29
+
30
+ This is the fastest path from an empty repo to usable test files.
31
+
32
+ 1. Initialize a workspace directory (recommended: always pass `--output`; default is `tests`).
33
+
34
+ ```bash
35
+ tlog init --output tests
36
+ ```
37
+
38
+ 2. Create your first suite.
39
+
40
+ ```bash
41
+ tlog suite create --id auth --title "Authentication"
42
+ ```
43
+
44
+ 3. Create your first case in that suite.
45
+
46
+ ```bash
47
+ tlog case create --suite-dir tests/auth --id login-success --title "User can log in"
48
+ ```
49
+
50
+ 4. Validate everything.
51
+
52
+ ```bash
53
+ tlog validate
54
+ ```
55
+
56
+ Expected structure after steps 1-3:
57
+
58
+ ```text
59
+ tests/
60
+ ├─ index.yaml
61
+ ├─ default-case.testcase.yaml
62
+ └─ auth/
63
+ ├─ index.yaml
64
+ └─ login-success.testcase.yaml
65
+ ```
66
+
67
+ Need command-level help?
68
+
69
+ ```bash
70
+ tlog --help
71
+ tlog suite --help
72
+ tlog case --help
73
+ tlog related --help
74
+ ```
75
+
76
+ ## Core Concepts
77
+
78
+ - `suite`: represented by `index.yaml` (or `*.suite.yaml` in broader ecosystem usage).
79
+ - `case`: represented by `*.testcase.yaml`.
80
+ - IDs must match `^[A-Za-z0-9_-]+$`.
81
+ - By default, most commands search under `tests/`.
82
+
83
+ ## Deep Dive: `init`
84
+
85
+ `init` creates a ready-to-use base workspace.
86
+
87
+ ### Recommended usage (explicit output directory)
88
+
89
+ ```bash
90
+ tlog init --output tests
91
+ ```
92
+
93
+ Creates:
94
+
95
+ - `tests/index.yaml`
96
+ - `tests/default-case.testcase.yaml`
97
+
98
+ (`--output` is optional; if omitted, `tests` is used.)
99
+
100
+ ### Use a custom output directory
101
+
102
+ ```bash
103
+ tlog init --output qa-tests
104
+ ```
105
+
106
+ ### Initialize from a local template directory
107
+
108
+ ```bash
109
+ tlog init --template templates/default --output tests
110
+ ```
111
+
112
+ Template requirements:
113
+
114
+ - Must contain `index.yaml`.
115
+ - May include one or more case YAML files; the first one is used as the case template.
116
+ - Template must pass schema validation.
117
+
118
+ ### Preview changes before writing files
119
+
120
+ ```bash
121
+ tlog init --dry-run
122
+ ```
123
+
124
+ ### Machine-readable output
125
+
126
+ ```bash
127
+ tlog init --json
128
+ ```
129
+
130
+ ## Deep Dive: `suite create` and `case create`
131
+
132
+ Creation commands are designed to be strict and predictable.
133
+
134
+ ### `suite create`
135
+
136
+ ```bash
137
+ tlog suite create \
138
+ --id auth \
139
+ --title "Authentication" \
140
+ --dir tests \
141
+ --owners qa-team,backend \
142
+ --tags smoke,critical \
143
+ --scheduled-start 2026-02-01 \
144
+ --scheduled-end 2026-02-15
145
+ ```
146
+
147
+ Behavior:
148
+
149
+ - Creates suite directory: `tests/<id>/`
150
+ - Writes suite file: `tests/<id>/index.yaml`
151
+ - Rejects duplicate IDs across YAML files under `--dir`
152
+ - Rejects invalid IDs
153
+
154
+ ### `case create`
155
+
156
+ ```bash
157
+ tlog case create \
158
+ --suite-dir tests/auth \
159
+ --id login-success \
160
+ --title "User can log in" \
161
+ --status todo \
162
+ --tags smoke,auth
163
+ ```
164
+
165
+ Behavior:
166
+
167
+ - Writes case file: `<suite-dir>/<id>.testcase.yaml`
168
+ - Verifies `--suite-dir` exists
169
+ - Rejects duplicate IDs (searched in parent root of the suite directory)
170
+ - Supports status: `todo | doing | done | null`
171
+
172
+ ## Template Workflow (Reusable Bootstrap)
173
+
174
+ Create a reusable template from defaults:
175
+
176
+ ```bash
177
+ tlog template --output templates/default
178
+ ```
179
+
180
+ Extract template from existing test directory:
181
+
182
+ ```bash
183
+ tlog template --from tests --output templates/team-standard
184
+ ```
185
+
186
+ List available templates:
187
+
188
+ ```bash
189
+ tlog list templates --dir templates --format text
190
+ ```
191
+
192
+ ## Command Reference
193
+
194
+ ### Global options
195
+
196
+ - `--dry-run`: preview without writing files
197
+ - `--json`: force JSON output
198
+ - `--yes`: skip confirmation prompts (mainly for delete flows)
199
+
200
+ ### Workspace bootstrap
201
+
202
+ - `tlog init [--template <dir>] [--output <dir>]`
203
+ - `tlog template [--from <dir>] [--output <dir>]`
204
+
205
+ ### Suite commands
206
+
207
+ - `tlog suite create --id <id> --title <title> [--dir <dir>] [--owners <a,b>] [--tags <a,b>] [--scheduled-start <YYYY-MM-DD>] [--scheduled-end <YYYY-MM-DD>]`
208
+ - `tlog suite update --id <id> [--dir <dir>] [--title <title>] [--description <text>] [--tags <a,b>] [--owners <a,b>] [--related <a,b>] [--remarks <a,b>] [--scoped <true|false>] [--scheduled-start <YYYY-MM-DD>] [--scheduled-end <YYYY-MM-DD>] [--actual-start <YYYY-MM-DD>] [--actual-end <YYYY-MM-DD>]`
209
+ - `tlog suite delete --id <id> [--dir <dir>] [--yes]`
210
+ - `tlog suite stats --id <id> [--dir <dir>] [--format <text|json>]`
211
+ - `tlog suite list [--dir <dir>] [--id <pattern>] [--format <text|json|csv>] [--output <path>]`
212
+
213
+ ### Case commands
214
+
215
+ - `tlog case create --suite-dir <dir> --id <id> --title <title> [--status <todo|doing|done|null>] [--tags <a,b>]`
216
+ - `tlog case update --id <id> [--dir <dir>] [--status <todo|doing|done|null>] [--tags <a,b>] [--description <text>] [--operations <a,b>] [--related <a,b>] [--remarks <a,b>] [--scoped <true|false>] [--completed-day <YYYY-MM-DD|null>] [--tests-file <path>] [--issues-file <path>]`
217
+ - `tlog case delete --id <id> [--dir <dir>] [--yes]`
218
+ - `tlog case list [--dir <dir>] [--id <pattern>] [--tag <tag>] [--owners <a,b>] [--scoped-only] [--issue-has <keyword>] [--issue-status <open|doing|resolved|pending>] [--status <todo|doing|done|null>] [--format <text|json|csv>] [--output <path>]`
219
+
220
+ ### Related link commands
221
+
222
+ - `tlog related sync [--dir <dir>] [--id <id>]`
223
+ - `tlog related list --id <id> [--dir <dir>] [--format <text|json|csv>]`
224
+
225
+ ### Validation and listing
226
+
227
+ - `tlog validate [--dir <dir>] [--fail-on-warning] [--watch] [--watch-interval <ms>] [--format <text|json>]`
228
+ - `tlog list templates [--dir <dir>] [--format <text|json|csv>] [--output <path>]`
229
+
230
+ ## Practical Usage Patterns
231
+
232
+ ### 1) CI-friendly validation
233
+
234
+ ```bash
235
+ tlog validate --dir tests --format json --fail-on-warning
236
+ ```
237
+
238
+ - Exit code is non-zero on validation failure.
239
+ - Useful for pull request gates.
240
+
241
+ ### 2) Bulk case filtering and export
242
+
243
+ ```bash
244
+ tlog case list --dir tests --status doing --format csv --output reports/doing-cases.csv
245
+ ```
246
+
247
+ ### 3) Safe delete with explicit confirmation skip
248
+
249
+ ```bash
250
+ tlog case delete --dir tests --id login-success --yes
251
+ ```
252
+
253
+ Delete behavior:
254
+
255
+ - Files are moved to `.tlog-trash/` (near the root directory parent), not immediately hard-deleted.
256
+
257
+ ## JSON Output Contract
258
+
259
+ Success shape:
260
+
261
+ ```json
262
+ {
263
+ "ok": true,
264
+ "command": "suite create",
265
+ "data": {
266
+ "id": "auth",
267
+ "path": "tests/auth/index.yaml",
268
+ "dryRun": false
269
+ }
270
+ }
271
+ ```
272
+
273
+ Failure shape:
274
+
275
+ ```json
276
+ {
277
+ "ok": false,
278
+ "command": "suite create",
279
+ "error": {
280
+ "message": "ID already exists: auth",
281
+ "details": ["tests/auth/index.yaml"]
282
+ }
283
+ }
284
+ ```
285
+
286
+ ## Troubleshooting
287
+
288
+ ### `ID already exists`
289
+
290
+ - IDs are unique across YAML files under the search root.
291
+ - Use `tlog suite list` / `tlog case list` to find conflicts.
292
+
293
+ ### `... not found`
294
+
295
+ - Confirm your `--dir` or `--suite-dir` path.
296
+ - Default root is `tests` for most commands.
297
+
298
+ ### Validation errors on update
299
+
300
+ - `suite update` and `case update` validate before writing.
301
+ - Check reported `path: message` details and retry.
302
+
303
+ ## Version
304
+
305
+ ```bash
306
+ tlog --version
307
+ ```
package/bin/.gitkeep ADDED
File without changes
package/bin/tlog.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from "../dist/index.js";
3
+
4
+ runCli(process.argv);
@@ -0,0 +1,8 @@
1
+ import { type GlobalOptions } from "../core.js";
2
+ export interface DeleteOptions {
3
+ dir: string;
4
+ id: string;
5
+ }
6
+ export declare function runSuiteDelete(cwd: string, options: DeleteOptions, globalOptions: GlobalOptions): void;
7
+ export declare function runCaseDelete(cwd: string, options: DeleteOptions, globalOptions: GlobalOptions): void;
8
+ //# sourceMappingURL=delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAEjH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;CACZ;AAoDD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CAiCtG;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CAgCrG"}
@@ -0,0 +1,104 @@
1
+ import { mkdirSync, readFileSync, readSync, renameSync } from "node:fs";
2
+ import { basename, dirname, join, resolve } from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ import { detectEntityType, normalizeTlogPath, parseYaml } from "@tlog/shared";
5
+ import { CliError, emitSuccess, ensureDirectory, formatOf, walkYamlFiles } from "../core.js";
6
+ function findById(rootDir, id, type) {
7
+ const matches = walkYamlFiles(rootDir).filter((path) => {
8
+ if (detectEntityType(path) !== type) {
9
+ return false;
10
+ }
11
+ try {
12
+ const raw = parseYaml(readFileSync(path, "utf8"));
13
+ return raw.id === id;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ });
19
+ if (matches.length === 0) {
20
+ throw new CliError(`${type} not found: ${id}`);
21
+ }
22
+ if (matches.length > 1) {
23
+ throw new CliError(`Multiple ${type} entries found for id: ${id}`, {
24
+ details: matches.map((item) => normalizeTlogPath(item))
25
+ });
26
+ }
27
+ return matches[0];
28
+ }
29
+ function confirm(prompt) {
30
+ if (!process.stdin.isTTY) {
31
+ return false;
32
+ }
33
+ process.stdout.write(`${prompt} [y/N]: `);
34
+ const buffer = Buffer.alloc(32);
35
+ const bytes = readSync(process.stdin.fd, buffer, 0, buffer.length, null);
36
+ const input = buffer.toString("utf8", 0, bytes).trim().toLowerCase();
37
+ return input === "y" || input === "yes";
38
+ }
39
+ function ensureInsideRoot(rootDir, targetPath) {
40
+ const normalizedRoot = normalizeTlogPath(resolve(rootDir));
41
+ const normalizedTarget = normalizeTlogPath(resolve(targetPath));
42
+ if (!normalizedTarget.startsWith(`${normalizedRoot}/`) && normalizedTarget !== normalizedRoot) {
43
+ throw new CliError(`Target is outside root directory: ${normalizedTarget}`);
44
+ }
45
+ }
46
+ function moveToTrash(trashBaseDir, sourcePath) {
47
+ const trashDir = join(trashBaseDir, ".tlog-trash");
48
+ mkdirSync(trashDir, { recursive: true });
49
+ const target = join(trashDir, `${Date.now()}-${randomUUID()}-${basename(sourcePath)}`);
50
+ renameSync(sourcePath, target);
51
+ return target;
52
+ }
53
+ export function runSuiteDelete(cwd, options, globalOptions) {
54
+ const format = formatOf(globalOptions);
55
+ const rootDir = resolve(cwd, options.dir);
56
+ const trashBaseDir = dirname(rootDir);
57
+ ensureDirectory(rootDir, "Suite search directory does not exist");
58
+ const suitePath = findById(rootDir, options.id, "suite");
59
+ const targetPath = dirname(suitePath);
60
+ ensureInsideRoot(rootDir, targetPath);
61
+ if (!globalOptions.yes) {
62
+ const accepted = confirm(`Delete suite ${options.id}?`);
63
+ if (!accepted) {
64
+ throw new CliError("Delete cancelled. Re-run with --yes to skip confirmation.");
65
+ }
66
+ }
67
+ const trashPath = normalizeTlogPath(join(trashBaseDir, ".tlog-trash", "<generated>"));
68
+ let movedTo = null;
69
+ if (!globalOptions.dryRun) {
70
+ movedTo = normalizeTlogPath(moveToTrash(trashBaseDir, targetPath));
71
+ }
72
+ emitSuccess("suite delete", {
73
+ id: options.id,
74
+ path: normalizeTlogPath(targetPath),
75
+ dryRun: globalOptions.dryRun,
76
+ movedTo: movedTo ?? trashPath
77
+ }, format, [`${globalOptions.dryRun ? "Would delete" : "Deleted"}: ${normalizeTlogPath(targetPath)}`]);
78
+ }
79
+ export function runCaseDelete(cwd, options, globalOptions) {
80
+ const format = formatOf(globalOptions);
81
+ const rootDir = resolve(cwd, options.dir);
82
+ const trashBaseDir = dirname(rootDir);
83
+ ensureDirectory(rootDir, "Case search directory does not exist");
84
+ const targetPath = findById(rootDir, options.id, "case");
85
+ ensureInsideRoot(rootDir, targetPath);
86
+ if (!globalOptions.yes) {
87
+ const accepted = confirm(`Delete case ${options.id}?`);
88
+ if (!accepted) {
89
+ throw new CliError("Delete cancelled. Re-run with --yes to skip confirmation.");
90
+ }
91
+ }
92
+ const trashPath = normalizeTlogPath(join(trashBaseDir, ".tlog-trash", "<generated>"));
93
+ let movedTo = null;
94
+ if (!globalOptions.dryRun) {
95
+ movedTo = normalizeTlogPath(moveToTrash(trashBaseDir, targetPath));
96
+ }
97
+ emitSuccess("case delete", {
98
+ id: options.id,
99
+ path: normalizeTlogPath(targetPath),
100
+ dryRun: globalOptions.dryRun,
101
+ movedTo: movedTo ?? trashPath
102
+ }, format, [`${globalOptions.dryRun ? "Would delete" : "Deleted"}: ${normalizeTlogPath(targetPath)}`]);
103
+ }
104
+ //# sourceMappingURL=delete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type GlobalOptions } from "../core.js";
2
+ export interface InitOptions {
3
+ output: string;
4
+ template?: string;
5
+ }
6
+ export interface TemplateOptions {
7
+ from?: string;
8
+ output: string;
9
+ }
10
+ export declare function runInit(cwd: string, options: InitOptions, globalOptions: GlobalOptions): void;
11
+ export declare function runTemplate(cwd: string, options: TemplateOptions, globalOptions: GlobalOptions): void;
12
+ //# sourceMappingURL=init-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-template.d.ts","sourceRoot":"","sources":["../../src/commands/init-template.ts"],"names":[],"mappings":"AAWA,OAAO,EAAoD,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAElG,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAuED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CAiE7F;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CAuErG"}
@@ -0,0 +1,168 @@
1
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join, normalize, resolve } from "node:path";
3
+ import { buildDefaultCase, buildDefaultSuite, parseYaml, stringifyYaml, validateTemplate } from "@tlog/shared";
4
+ import { CliError, emitSuccess, ensureDirectory, formatOf } from "../core.js";
5
+ function normalizeTemplateCase(input) {
6
+ const issues = Array.isArray(input.issues)
7
+ ? input.issues.map((issue) => {
8
+ if (!issue || typeof issue !== "object") {
9
+ return issue;
10
+ }
11
+ const source = issue;
12
+ const normalized = { ...source };
13
+ if (!("detectedDay" in normalized)) {
14
+ normalized.detectedDay = null;
15
+ }
16
+ if (!("completedDay" in normalized)) {
17
+ normalized.completedDay = null;
18
+ }
19
+ return normalized;
20
+ })
21
+ : input.issues;
22
+ return {
23
+ ...input,
24
+ issues
25
+ };
26
+ }
27
+ function createDefaultTemplateData() {
28
+ const suite = buildDefaultSuite({ id: "default", title: "Default Suite", description: "tlog test suite" });
29
+ const testCase = buildDefaultCase({ id: "default-case", title: "Default Case", status: "todo" });
30
+ return { suite, testCase };
31
+ }
32
+ function safePath(path) {
33
+ return normalize(path).split("\\").join("/");
34
+ }
35
+ function readTemplateDirectory(templateDir) {
36
+ const indexPath = join(templateDir, "index.yaml");
37
+ if (!existsSync(indexPath)) {
38
+ throw new CliError("Template is missing required file", {
39
+ details: [safePath(indexPath)]
40
+ });
41
+ }
42
+ const template = {
43
+ suite: parseYamlFile(indexPath),
44
+ testCase: {}
45
+ };
46
+ const yamlFiles = readdirSync(templateDir).filter((name) => name.endsWith(".yaml") && name !== "index.yaml");
47
+ if (yamlFiles.length > 0) {
48
+ const firstCase = join(templateDir, yamlFiles[0]);
49
+ template.testCase = normalizeTemplateCase(parseYamlFile(firstCase));
50
+ }
51
+ return template;
52
+ }
53
+ function parseYamlFile(path) {
54
+ const source = readFileSync(path, "utf8");
55
+ return parseYaml(source);
56
+ }
57
+ export function runInit(cwd, options, globalOptions) {
58
+ const format = formatOf(globalOptions);
59
+ const outputDir = resolve(cwd, options.output);
60
+ const indexPath = join(outputDir, "index.yaml");
61
+ const casePath = join(outputDir, "default-case.testcase.yaml");
62
+ const defaults = createDefaultTemplateData();
63
+ let suite = defaults.suite;
64
+ let testCase = defaults.testCase;
65
+ if (options.template) {
66
+ const templateDir = resolve(cwd, options.template);
67
+ ensureDirectory(templateDir, "Template directory does not exist");
68
+ const template = readTemplateDirectory(templateDir);
69
+ const validation = validateTemplate(template);
70
+ if (!validation.valid) {
71
+ throw new CliError("Invalid template", { details: validation.errors });
72
+ }
73
+ suite = {
74
+ ...suite,
75
+ ...template.suite,
76
+ duration: template.suite.duration ?? suite.duration
77
+ };
78
+ testCase = {
79
+ ...testCase,
80
+ ...template.testCase,
81
+ tests: template.testCase.tests ?? testCase.tests,
82
+ issues: template.testCase.issues ?? testCase.issues
83
+ };
84
+ }
85
+ const alreadyExists = [indexPath, casePath].filter((path) => existsSync(path));
86
+ if (alreadyExists.length > 0) {
87
+ throw new CliError("Target files already exist", {
88
+ details: alreadyExists.map((path) => safePath(path))
89
+ });
90
+ }
91
+ const files = [
92
+ { path: indexPath, content: stringifyYaml(suite) },
93
+ { path: casePath, content: stringifyYaml(testCase) }
94
+ ];
95
+ if (!globalOptions.dryRun) {
96
+ mkdirSync(outputDir, { recursive: true });
97
+ for (const file of files) {
98
+ writeFileSync(file.path, file.content, "utf8");
99
+ }
100
+ }
101
+ emitSuccess("init", {
102
+ output: safePath(outputDir),
103
+ dryRun: globalOptions.dryRun,
104
+ files: files.map((file) => safePath(file.path))
105
+ }, format, [
106
+ `Initialized: ${safePath(outputDir)}`,
107
+ ...files.map((file) => `${globalOptions.dryRun ? "Would create" : "Created"}: ${safePath(file.path)}`)
108
+ ]);
109
+ }
110
+ export function runTemplate(cwd, options, globalOptions) {
111
+ const format = formatOf(globalOptions);
112
+ const outputDir = resolve(cwd, options.output);
113
+ const indexPath = join(outputDir, "index.yaml");
114
+ const casePath = join(outputDir, "sample.testcase.yaml");
115
+ if (existsSync(indexPath) || existsSync(casePath)) {
116
+ throw new CliError("Output already has template files", {
117
+ details: [safePath(indexPath), safePath(casePath)].filter((path) => existsSync(path))
118
+ });
119
+ }
120
+ let suite = buildDefaultSuite({ id: "template-suite", title: "Template Suite" });
121
+ let testCase = buildDefaultCase({ id: "template-case", title: "Template Case" });
122
+ if (options.from) {
123
+ const sourceDir = resolve(cwd, options.from);
124
+ ensureDirectory(sourceDir, "Source directory does not exist");
125
+ const fromIndex = join(sourceDir, "index.yaml");
126
+ if (!existsSync(fromIndex)) {
127
+ throw new CliError("Source is missing required file", {
128
+ details: [safePath(fromIndex)]
129
+ });
130
+ }
131
+ const extracted = readTemplateDirectory(sourceDir);
132
+ const validation = validateTemplate({ suite: extracted.suite, testCase: extracted.testCase });
133
+ if (!validation.valid) {
134
+ throw new CliError("Source template is invalid", { details: validation.errors });
135
+ }
136
+ suite = {
137
+ ...suite,
138
+ ...extracted.suite,
139
+ duration: extracted.suite.duration ?? suite.duration
140
+ };
141
+ testCase = {
142
+ ...testCase,
143
+ ...extracted.testCase,
144
+ tests: extracted.testCase.tests ?? testCase.tests,
145
+ issues: extracted.testCase.issues ?? testCase.issues
146
+ };
147
+ }
148
+ const files = [
149
+ { path: indexPath, content: stringifyYaml(suite) },
150
+ { path: casePath, content: stringifyYaml(testCase) }
151
+ ];
152
+ if (!globalOptions.dryRun) {
153
+ mkdirSync(outputDir, { recursive: true });
154
+ for (const file of files) {
155
+ writeFileSync(file.path, file.content, "utf8");
156
+ }
157
+ }
158
+ emitSuccess("template", {
159
+ output: safePath(outputDir),
160
+ from: options.from ? safePath(resolve(cwd, options.from)) : null,
161
+ dryRun: globalOptions.dryRun,
162
+ files: files.map((file) => safePath(file.path))
163
+ }, format, [
164
+ `${globalOptions.dryRun ? "Preview" : "Created"} template: ${safePath(outputDir)}`,
165
+ ...files.map((file) => `${globalOptions.dryRun ? "Would create" : "Created"}: ${safePath(file.path)}`)
166
+ ]);
167
+ }
168
+ //# sourceMappingURL=init-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-template.js","sourceRoot":"","sources":["../../src/commands/init-template.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type GlobalOptions } from "../core.js";
2
+ export interface RelatedSyncOptions {
3
+ dir: string;
4
+ id?: string;
5
+ }
6
+ export interface RelatedListOptions {
7
+ dir: string;
8
+ id: string;
9
+ format?: string;
10
+ }
11
+ export declare function runRelatedSync(cwd: string, options: RelatedSyncOptions, globalOptions: GlobalOptions): void;
12
+ export declare function runRelatedList(cwd: string, options: RelatedListOptions, globalOptions: GlobalOptions): void;
13
+ //# sourceMappingURL=related.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"related.d.ts","sourceRoot":"","sources":["../../src/commands/related.ts"],"names":[],"mappings":"AAWA,OAAO,EAAmE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAUjH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAkCD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CA8G3G;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CAoE3G"}