@ir-kit/k6-toolkit 0.1.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 (83) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +62 -0
  3. package/dist/ast-imports.d.ts +15 -0
  4. package/dist/ast-imports.d.ts.map +1 -0
  5. package/dist/ast-imports.js +12 -0
  6. package/dist/ast-imports.js.map +1 -0
  7. package/dist/bundle.d.ts +25 -0
  8. package/dist/bundle.d.ts.map +1 -0
  9. package/dist/bundle.js +60 -0
  10. package/dist/bundle.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +88 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/index.d.ts +7 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +6 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/init.d.ts +50 -0
  20. package/dist/init.d.ts.map +1 -0
  21. package/dist/init.js +73 -0
  22. package/dist/init.js.map +1 -0
  23. package/dist/loadtest-scaffold.d.ts +48 -0
  24. package/dist/loadtest-scaffold.d.ts.map +1 -0
  25. package/dist/loadtest-scaffold.js +121 -0
  26. package/dist/loadtest-scaffold.js.map +1 -0
  27. package/dist/operation-map.d.ts +6 -0
  28. package/dist/operation-map.d.ts.map +1 -0
  29. package/dist/operation-map.js +27 -0
  30. package/dist/operation-map.js.map +1 -0
  31. package/dist/print.d.ts +4 -0
  32. package/dist/print.d.ts.map +1 -0
  33. package/dist/print.js +14 -0
  34. package/dist/print.js.map +1 -0
  35. package/dist/rename-report.d.ts +26 -0
  36. package/dist/rename-report.d.ts.map +1 -0
  37. package/dist/rename-report.js +30 -0
  38. package/dist/rename-report.js.map +1 -0
  39. package/dist/run.d.ts +27 -0
  40. package/dist/run.d.ts.map +1 -0
  41. package/dist/run.js +30 -0
  42. package/dist/run.js.map +1 -0
  43. package/dist/scaffold/ast-helpers.d.ts +10 -0
  44. package/dist/scaffold/ast-helpers.d.ts.map +1 -0
  45. package/dist/scaffold/ast-helpers.js +21 -0
  46. package/dist/scaffold/ast-helpers.js.map +1 -0
  47. package/dist/scaffold/chains.d.ts +10 -0
  48. package/dist/scaffold/chains.d.ts.map +1 -0
  49. package/dist/scaffold/chains.js +92 -0
  50. package/dist/scaffold/chains.js.map +1 -0
  51. package/dist/scaffold/cli-handler.d.ts +4 -0
  52. package/dist/scaffold/cli-handler.d.ts.map +1 -0
  53. package/dist/scaffold/cli-handler.js +204 -0
  54. package/dist/scaffold/cli-handler.js.map +1 -0
  55. package/dist/scaffold/scenario.d.ts +34 -0
  56. package/dist/scaffold/scenario.d.ts.map +1 -0
  57. package/dist/scaffold/scenario.js +67 -0
  58. package/dist/scaffold/scenario.js.map +1 -0
  59. package/dist/scaffold/spec-tags.d.ts +15 -0
  60. package/dist/scaffold/spec-tags.d.ts.map +1 -0
  61. package/dist/scaffold/spec-tags.js +23 -0
  62. package/dist/scaffold/spec-tags.js.map +1 -0
  63. package/dist/scaffold/wizard.d.ts +25 -0
  64. package/dist/scaffold/wizard.d.ts.map +1 -0
  65. package/dist/scaffold/wizard.js +156 -0
  66. package/dist/scaffold/wizard.js.map +1 -0
  67. package/dist/snapshot.d.ts +6 -0
  68. package/dist/snapshot.d.ts.map +1 -0
  69. package/dist/snapshot.js +35 -0
  70. package/dist/snapshot.js.map +1 -0
  71. package/dist/spawn-k6.d.ts +30 -0
  72. package/dist/spawn-k6.d.ts.map +1 -0
  73. package/dist/spawn-k6.js +46 -0
  74. package/dist/spawn-k6.js.map +1 -0
  75. package/dist/sync-cli.d.ts +2 -0
  76. package/dist/sync-cli.d.ts.map +1 -0
  77. package/dist/sync-cli.js +137 -0
  78. package/dist/sync-cli.js.map +1 -0
  79. package/dist/sync.d.ts +23 -0
  80. package/dist/sync.d.ts.map +1 -0
  81. package/dist/sync.js +37 -0
  82. package/dist/sync.js.map +1 -0
  83. package/package.json +71 -0
@@ -0,0 +1,204 @@
1
+ import { existsSync, mkdirSync, statSync, writeFileSync } from "node:fs";
2
+ import { dirname, relative, resolve } from "node:path";
3
+ import { intro, log, outro } from "@clack/prompts";
4
+ import { loadSpec } from "@ir-kit/openapi-tools";
5
+ import { parseSpec } from "@ir-kit/openapi-tools/parse";
6
+ import { scaffoldScenario, } from "./scenario.js";
7
+ import { readSpecOperations } from "./spec-tags.js";
8
+ import { confirmOverwrite, runScenarioWizard } from "./wizard.js";
9
+ const HELP = `
10
+ k6-ts scaffold — generate scenario files from your OpenAPI spec.
11
+
12
+ USAGE
13
+ k6-ts scaffold # interactive wizard
14
+ k6-ts scaffold list-ops [--json] # discover ops (grouped by tag)
15
+ k6-ts scaffold [flags…] # flag-driven, single scenario
16
+ k6-ts scaffold --tags <a,b,c> [flags…] # batch — one scenario per tag
17
+
18
+ REQUIRED (flag mode)
19
+ --name <slug> Scenario name (used for filename + step label)
20
+ --ops <a,b,c> Comma-separated operation IDs
21
+
22
+ OPTIONAL
23
+ --spec <path-or-url> OpenAPI spec. Default: ./openapi.yaml
24
+ --client-import <path> Import path for the generated client.
25
+ Default: ./src/gen/index.js
26
+ --chain sequential|batch Default: sequential
27
+ --pace smoke|load|stress|spike|soak Default: smoke
28
+ --duration <duration> Default: 30s (or 1h for soak)
29
+ --auth none|bearer|basic|apiKey|session|digest|ntlm Default: none
30
+ --output <file> Where to write (single scenario)
31
+ --output-dir <dir> Where to write (batch mode)
32
+ --force Overwrite without prompting
33
+ --help Show this help
34
+
35
+ BATCH MODE (--tags)
36
+ Generates one scenario file per tag, named after the tag. Each picks all
37
+ operations carrying that tag with sensible defaults (smoke, sequential).
38
+ `.trim();
39
+ function parseArgs(argv) {
40
+ if (argv[0] === "list-ops") {
41
+ return {
42
+ kind: "list-ops",
43
+ spec: pickFlag(argv, "--spec") ?? "./openapi.yaml",
44
+ json: argv.includes("--json"),
45
+ };
46
+ }
47
+ return {
48
+ kind: "flags",
49
+ name: pickFlag(argv, "--name"),
50
+ ops: pickFlag(argv, "--ops"),
51
+ tags: pickFlag(argv, "--tags"),
52
+ spec: pickFlag(argv, "--spec") ?? "./openapi.yaml",
53
+ clientImport: pickFlag(argv, "--client-import") ?? "./src/gen/index.js",
54
+ chain: pickFlag(argv, "--chain") ?? "sequential",
55
+ pace: pickFlag(argv, "--pace") ?? "smoke",
56
+ duration: pickFlag(argv, "--duration"),
57
+ auth: pickFlag(argv, "--auth") ?? "none",
58
+ output: pickFlag(argv, "--output"),
59
+ outputDir: pickFlag(argv, "--output-dir"),
60
+ force: argv.includes("--force"),
61
+ showHelp: argv.includes("--help") || argv.includes("-h"),
62
+ };
63
+ }
64
+ function pickFlag(argv, name) {
65
+ const i = argv.indexOf(name);
66
+ if (i === -1)
67
+ return undefined;
68
+ return argv[i + 1];
69
+ }
70
+ export async function runScaffoldCommand(argv) {
71
+ const parsed = parseArgs(argv);
72
+ if (parsed.kind === "flags" && parsed.showHelp) {
73
+ console.log(HELP);
74
+ return;
75
+ }
76
+ // list-ops subcommand — no I/O beyond stdout
77
+ if (parsed.kind === "list-ops") {
78
+ await listOps(parsed);
79
+ return;
80
+ }
81
+ const spec = await loadAndIndexSpec(parsed.spec);
82
+ // Batch mode: --tags <a,b,c>
83
+ if (parsed.tags) {
84
+ await scaffoldByTags(spec, parsed);
85
+ return;
86
+ }
87
+ // Flag mode (non-interactive): --name + --ops required
88
+ if (parsed.name && parsed.ops) {
89
+ await scaffoldFromFlags(spec, parsed);
90
+ return;
91
+ }
92
+ // Interactive — no name/ops/tags
93
+ await scaffoldInteractive(spec, parsed);
94
+ }
95
+ async function loadAndIndexSpec(specPath) {
96
+ const bundled = await loadSpec({ input: specPath, normalize: true });
97
+ const ir = parseSpec(bundled);
98
+ return readSpecOperations(ir.paths);
99
+ }
100
+ async function listOps(parsed) {
101
+ const spec = await loadAndIndexSpec(parsed.spec);
102
+ if (parsed.json) {
103
+ const byTag = {};
104
+ for (const [tag, ops] of spec.byTag) {
105
+ byTag[tag] = ops.map((o) => o.id);
106
+ }
107
+ console.log(JSON.stringify({ byTag, total: spec.all.length }, null, 2));
108
+ return;
109
+ }
110
+ for (const [tag, ops] of spec.byTag) {
111
+ console.log(`\n${tag} (${ops.length} ops)`);
112
+ for (const op of ops) {
113
+ console.log(` ${op.method.toUpperCase().padEnd(6)} ${op.path} · ${op.id}`);
114
+ }
115
+ }
116
+ console.log(`\n${spec.all.length} total ops`);
117
+ }
118
+ async function scaffoldFromFlags(spec, parsed) {
119
+ const opIds = parsed
120
+ .ops.split(",")
121
+ .map((s) => s.trim())
122
+ .filter(Boolean);
123
+ const ops = opIds
124
+ .map((id) => spec.byId.get(id))
125
+ .filter((o) => Boolean(o));
126
+ if (ops.length !== opIds.length) {
127
+ const missing = opIds.filter((id) => !spec.byId.has(id));
128
+ console.error(`k6-ts scaffold: unknown operationId(s): ${missing.join(", ")}`);
129
+ process.exit(2);
130
+ }
131
+ const slug = parsed.name.trim().replace(/[^a-zA-Z0-9-]+/g, "-");
132
+ const output = parsed.output ?? `${parsed.outputDir ?? "./loadtests"}/${slug}.ts`;
133
+ const scaffold = {
134
+ clientImportPath: parsed.clientImport,
135
+ pace: parsed.pace,
136
+ duration: parsed.duration,
137
+ ops,
138
+ chain: parsed.chain,
139
+ auth: { auth: parsed.auth },
140
+ };
141
+ await writeScenario(output, scaffold, parsed.force);
142
+ console.log(`Wrote ${relative(process.cwd(), output)}`);
143
+ }
144
+ async function scaffoldByTags(spec, parsed) {
145
+ const tags = parsed
146
+ .tags.split(",")
147
+ .map((s) => s.trim())
148
+ .filter(Boolean);
149
+ const outputDir = parsed.outputDir ?? "./loadtests";
150
+ const force = parsed.force;
151
+ for (const tag of tags) {
152
+ const ops = spec.byTag.get(tag);
153
+ if (!ops || ops.length === 0) {
154
+ console.error(`k6-ts scaffold: no operations under tag "${tag}"`);
155
+ continue;
156
+ }
157
+ const slug = tag.replace(/[^a-zA-Z0-9-]+/g, "-");
158
+ const output = `${outputDir}/${slug}.ts`;
159
+ await writeScenario(output, {
160
+ clientImportPath: parsed.clientImport,
161
+ pace: parsed.pace,
162
+ duration: parsed.duration,
163
+ ops,
164
+ chain: parsed.chain,
165
+ auth: { auth: parsed.auth },
166
+ }, force);
167
+ console.log(`Wrote ${relative(process.cwd(), output)} (${ops.length} ops)`);
168
+ }
169
+ }
170
+ async function scaffoldInteractive(spec, parsed) {
171
+ intro("k6-ts scaffold");
172
+ const result = await runScenarioWizard(spec, {
173
+ clientImportPath: parsed.clientImport,
174
+ outputDir: parsed.outputDir ?? "./loadtests",
175
+ });
176
+ if (!result)
177
+ return;
178
+ await writeScenario(result.outputPath, result.scaffold, parsed.force);
179
+ outro([
180
+ `Wrote ${relative(process.cwd(), result.outputPath)}`,
181
+ `Run it: k6-ts run ${relative(process.cwd(), result.outputPath)}`,
182
+ ].join("\n"));
183
+ }
184
+ async function writeScenario(output, scaffold, force) {
185
+ const absolute = resolve(output);
186
+ if (existsSync(absolute) && !force) {
187
+ const ok = await confirmOverwrite(relative(process.cwd(), absolute));
188
+ if (!ok) {
189
+ log.warn(`Skipped ${relative(process.cwd(), absolute)}`);
190
+ return;
191
+ }
192
+ }
193
+ const content = scaffoldScenario(scaffold);
194
+ mkdirSync(dirname(absolute), { recursive: true });
195
+ writeFileSync(absolute, content, "utf8");
196
+ ensureFile(absolute);
197
+ }
198
+ function ensureFile(absolute) {
199
+ const s = statSync(absolute);
200
+ if (!s.isFile())
201
+ throw new Error(`expected a file at ${absolute}`);
202
+ }
203
+ export { HELP as SCAFFOLD_HELP };
204
+ //# sourceMappingURL=cli-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-handler.js","sourceRoot":"","sources":["../../src/scaffold/cli-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { WalkedOperation } from "@ir-kit/k6-gen";
2
+ import { type AuthFlavor, type AuthScaffoldOpts } from "../loadtest-scaffold.js";
3
+ import { type ChainMode } from "./chains.js";
4
+ export type PacePreset = "smoke" | "load" | "stress" | "spike" | "soak";
5
+ export interface ScaffoldScenarioOpts {
6
+ /** Relative import path for the generated client (`./src/gen/index.js`). */
7
+ clientImportPath: string;
8
+ /** Pace preset selector. */
9
+ pace: PacePreset;
10
+ /** Duration string passed to the pace preset. Default `"30s"`. */
11
+ duration?: string;
12
+ /** Operations to compose into a flow. Empty → placeholder `flow().step("health", ...)`. */
13
+ ops: ReadonlyArray<WalkedOperation>;
14
+ /** How to compose the ops. */
15
+ chain: ChainMode;
16
+ /** Pass/fail thresholds. */
17
+ budgets?: {
18
+ p95?: string;
19
+ p99?: string;
20
+ errors?: string;
21
+ /** Per-operation budgets keyed by operationId. */
22
+ ops?: Record<string, {
23
+ p95?: string;
24
+ p99?: string;
25
+ errors?: string;
26
+ }>;
27
+ };
28
+ /** Auth recipe. Omit / "none" → no auth. */
29
+ auth?: AuthScaffoldOpts;
30
+ }
31
+ /** Render a complete standalone scenario `.ts` file as a string. */
32
+ export declare function scaffoldScenario(opts: ScaffoldScenarioOpts): string;
33
+ export type { AuthFlavor };
34
+ //# sourceMappingURL=scenario.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenario.d.ts","sourceRoot":"","sources":["../../src/scaffold/scenario.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAItD,OAAO,EACL,KAAK,UAAU,EACf,KAAK,gBAAgB,EAGtB,MAAM,yBAAyB,CAAC;AAQjC,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAIlE,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAExE,MAAM,WAAW,oBAAoB;IACnC,4EAA4E;IAC5E,gBAAgB,EAAE,MAAM,CAAC;IACzB,4BAA4B;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,GAAG,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IACpC,8BAA8B;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,4BAA4B;IAC5B,OAAO,CAAC,EAAE;QACR,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,kDAAkD;QAClD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACvE,CAAC;IACF,4CAA4C;IAC5C,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAkBnE;AAgFD,YAAY,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,67 @@
1
+ import ts from "typescript";
2
+ import { namespaceImport } from "../ast-imports.js";
3
+ import { authVarDecl, k6FrameworkImport, } from "../loadtest-scaffold.js";
4
+ import { printStatements } from "../print.js";
5
+ import { defaultExportProp, objLit, reExportConst, varConst, } from "./ast-helpers.js";
6
+ import { buildFlowExpression } from "./chains.js";
7
+ const f = ts.factory;
8
+ /** Render a complete standalone scenario `.ts` file as a string. */
9
+ export function scaffoldScenario(opts) {
10
+ const symbols = ["defineLoadTest", "flow", opts.pace];
11
+ if (opts.chain === "batch" && opts.ops.length > 1)
12
+ symbols.push("batch");
13
+ if (opts.auth && opts.auth.auth !== "none")
14
+ symbols.push("useAuth");
15
+ const stmts = [
16
+ k6FrameworkImport(symbols),
17
+ namespaceImport("api", opts.clientImportPath),
18
+ ];
19
+ const hasAuth = opts.auth && opts.auth.auth !== "none";
20
+ if (hasAuth)
21
+ stmts.push(authVarDecl(opts.auth));
22
+ stmts.push(loadtestDecl(opts, hasAuth ?? false));
23
+ stmts.push(reExportConst("options", "lt", "options"));
24
+ stmts.push(defaultExportProp("lt", "default"));
25
+ return printStatements(stmts);
26
+ }
27
+ function loadtestDecl(opts, hasAuth) {
28
+ const props = [];
29
+ if (hasAuth) {
30
+ props.push(f.createPropertyAssignment("use", f.createArrayLiteralExpression([f.createIdentifier("auth")])));
31
+ }
32
+ props.push(scenarioEntry(opts.pace, opts.duration ?? "30s"));
33
+ props.push(budgetsEntry(opts.budgets));
34
+ props.push(f.createPropertyAssignment("flow", buildFlowExpression(opts.ops, opts.chain)));
35
+ return varConst("lt", f.createCallExpression(f.createIdentifier("defineLoadTest"), undefined, [
36
+ f.createObjectLiteralExpression(props, true),
37
+ ]));
38
+ }
39
+ function scenarioEntry(pace, duration) {
40
+ return f.createPropertyAssignment("scenario", f.createCallExpression(f.createIdentifier(pace), undefined, [
41
+ objLit({ duration: f.createStringLiteral(duration) }),
42
+ ]));
43
+ }
44
+ function budgetsEntry(budgets) {
45
+ const top = {
46
+ p95: f.createStringLiteral(budgets?.p95 ?? "500ms"),
47
+ errors: f.createStringLiteral(budgets?.errors ?? "1%"),
48
+ };
49
+ if (budgets?.p99)
50
+ top.p99 = f.createStringLiteral(budgets.p99);
51
+ const opsEntries = Object.entries(budgets?.ops ?? {});
52
+ if (opsEntries.length > 0) {
53
+ top.ops = f.createObjectLiteralExpression(opsEntries.map(([opId, b]) => f.createPropertyAssignment(opId, opBudgetObj(b))), true);
54
+ }
55
+ return f.createPropertyAssignment("budgets", objLit(top, true));
56
+ }
57
+ function opBudgetObj(b) {
58
+ const props = {};
59
+ if (b.p95)
60
+ props.p95 = f.createStringLiteral(b.p95);
61
+ if (b.p99)
62
+ props.p99 = f.createStringLiteral(b.p99);
63
+ if (b.errors)
64
+ props.errors = f.createStringLiteral(b.errors);
65
+ return objLit(props);
66
+ }
67
+ //# sourceMappingURL=scenario.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenario.js","sourceRoot":"","sources":["../../src/scaffold/scenario.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { type WalkedOperation } from "@ir-kit/k6-gen";
2
+ import type { IR } from "@ir-kit/openapi-tools";
3
+ /** Tag-bucketed view of a spec's operations — `"_untagged"` collects ops with no tag. */
4
+ export interface SpecOperations {
5
+ /** Tag name → ops; ops are also referenced by `byId`. */
6
+ byTag: ReadonlyMap<string, ReadonlyArray<WalkedOperation>>;
7
+ /** Operation ID → op. Flat lookup for the wizard / flag mode. */
8
+ byId: ReadonlyMap<string, WalkedOperation>;
9
+ /** Every op in spec order. */
10
+ all: ReadonlyArray<WalkedOperation>;
11
+ }
12
+ declare const UNTAGGED = "_untagged";
13
+ export declare function readSpecOperations(paths: IR.PathsObject | undefined): SpecOperations;
14
+ export { UNTAGGED };
15
+ //# sourceMappingURL=spec-tags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-tags.d.ts","sourceRoot":"","sources":["../../src/scaffold/spec-tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAkB,MAAM,gBAAgB,CAAC;AACtE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAEhD,yFAAyF;AACzF,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC;IAC3D,iEAAiE;IACjE,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC3C,8BAA8B;IAC9B,GAAG,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;CACrC;AAED,QAAA,MAAM,QAAQ,cAAc,CAAC;AAE7B,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,EAAE,CAAC,WAAW,GAAG,SAAS,GAChC,cAAc,CAoBhB;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { walkOperations } from "@ir-kit/k6-gen";
2
+ const UNTAGGED = "_untagged";
3
+ export function readSpecOperations(paths) {
4
+ const byTag = new Map();
5
+ const byId = new Map();
6
+ const all = [];
7
+ for (const op of walkOperations(paths)) {
8
+ all.push(op);
9
+ byId.set(op.id, op);
10
+ const tags = op.tags.length > 0 ? op.tags : [UNTAGGED];
11
+ for (const tag of tags) {
12
+ let bucket = byTag.get(tag);
13
+ if (!bucket) {
14
+ bucket = [];
15
+ byTag.set(tag, bucket);
16
+ }
17
+ bucket.push(op);
18
+ }
19
+ }
20
+ return { byTag, byId, all };
21
+ }
22
+ export { UNTAGGED };
23
+ //# sourceMappingURL=spec-tags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-tags.js","sourceRoot":"","sources":["../../src/scaffold/spec-tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAatE,MAAM,QAAQ,GAAG,WAAW,CAAC;AAE7B,MAAM,UAAU,kBAAkB,CAChC,KAAiC;IAEjC,MAAM,KAAK,GAAG,IAAI,GAAG,EAA6B,CAAC;IACnD,MAAM,IAAI,GAAG,IAAI,GAAG,EAA2B,CAAC;IAChD,MAAM,GAAG,GAAsB,EAAE,CAAC;IAElC,KAAK,MAAM,EAAE,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACpB,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACvD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,GAAG,EAAE,CAAC;gBACZ,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACzB,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AAC9B,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { ScaffoldScenarioOpts } from "./scenario.js";
2
+ import { type SpecOperations } from "./spec-tags.js";
3
+ /**
4
+ * Wizard answers — a fully-resolved scaffold config ready for `scaffoldScenario`
5
+ * plus the filesystem target (output path).
6
+ */
7
+ export interface WizardResult {
8
+ outputPath: string;
9
+ scaffold: ScaffoldScenarioOpts;
10
+ }
11
+ /**
12
+ * Prompt the user through scenario authoring. Returns `null` if cancelled.
13
+ * Reuses `SpecOperations` for op discovery so the same source-of-truth feeds
14
+ * the CLI's `list-ops` subcommand.
15
+ */
16
+ export declare function runScenarioWizard(spec: SpecOperations, defaults: {
17
+ clientImportPath: string;
18
+ outputDir: string;
19
+ }): Promise<WizardResult | null>;
20
+ /**
21
+ * Confirm-overwrite prompt — shared by wizard and flag-mode CLI so a single
22
+ * UX rules them both. Returns `true` to proceed.
23
+ */
24
+ export declare function confirmOverwrite(path: string): Promise<boolean>;
25
+ //# sourceMappingURL=wizard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../../src/scaffold/wizard.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAc,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,KAAK,cAAc,EAAY,MAAM,gBAAgB,CAAC;AAE/D;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,oBAAoB,CAAC;CAChC;AAQD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE;IACR,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,GACA,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAkI9B;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOrE"}
@@ -0,0 +1,156 @@
1
+ import { cancel, confirm, isCancel, multiselect, select, text, } from "@clack/prompts";
2
+ import { UNTAGGED } from "./spec-tags.js";
3
+ /** Bail-out helper. */
4
+ function bail() {
5
+ cancel("Aborted.");
6
+ return null;
7
+ }
8
+ /**
9
+ * Prompt the user through scenario authoring. Returns `null` if cancelled.
10
+ * Reuses `SpecOperations` for op discovery so the same source-of-truth feeds
11
+ * the CLI's `list-ops` subcommand.
12
+ */
13
+ export async function runScenarioWizard(spec, defaults) {
14
+ const tagOptions = Array.from(spec.byTag.entries()).map(([tag, ops]) => ({
15
+ value: tag,
16
+ label: `${tag === UNTAGGED ? "(untagged)" : tag} — ${ops.length} op${ops.length === 1 ? "" : "s"}`,
17
+ }));
18
+ tagOptions.push({ value: "__manual__", label: "Pick ops manually" });
19
+ const tagPick = await select({
20
+ message: "Which group should this scenario cover?",
21
+ options: tagOptions,
22
+ });
23
+ if (isCancel(tagPick))
24
+ return bail();
25
+ let ops;
26
+ if (tagPick === "__manual__") {
27
+ const opOptions = spec.all.map((op) => ({
28
+ value: op.id,
29
+ label: `${op.method.toUpperCase()} ${op.path} · ${op.id}`,
30
+ }));
31
+ const picked = (await multiselect({
32
+ message: "Which ops? (space toggles, enter confirms)",
33
+ options: opOptions,
34
+ required: true,
35
+ }));
36
+ if (isCancel(picked))
37
+ return bail();
38
+ ops = picked
39
+ .map((id) => spec.byId.get(id))
40
+ .filter((o) => o !== undefined);
41
+ }
42
+ else {
43
+ const tagOps = spec.byTag.get(tagPick) ?? [];
44
+ const opOptions = tagOps.map((op) => ({
45
+ value: op.id,
46
+ label: `${op.method.toUpperCase()} ${op.path} · ${op.id}`,
47
+ }));
48
+ const picked = (await multiselect({
49
+ message: `Ops from "${tagPick}" — keep them all or narrow?`,
50
+ options: opOptions,
51
+ initialValues: tagOps.map((o) => o.id),
52
+ required: true,
53
+ }));
54
+ if (isCancel(picked))
55
+ return bail();
56
+ ops = picked
57
+ .map((id) => spec.byId.get(id))
58
+ .filter((o) => o !== undefined);
59
+ }
60
+ const defaultName = tagPick === "__manual__" ? "scenario" : `${tagPick}-flow`;
61
+ const name = (await text({
62
+ message: "Scenario name?",
63
+ initialValue: defaultName,
64
+ validate: (v) => (v && v.trim().length ? undefined : "Required"),
65
+ }));
66
+ if (isCancel(name))
67
+ return bail();
68
+ const chain = (await select({
69
+ message: "How should they compose?",
70
+ options: [
71
+ {
72
+ value: "sequential",
73
+ label: "Sequential — chain step outputs (CRUD-style)",
74
+ },
75
+ {
76
+ value: "batch",
77
+ label: "Parallel fan-out — flow().batch() with async ops",
78
+ },
79
+ ],
80
+ initialValue: "sequential",
81
+ }));
82
+ if (isCancel(chain))
83
+ return bail();
84
+ const pace = (await select({
85
+ message: "Pace preset?",
86
+ options: [
87
+ { value: "smoke", label: "smoke 1 VU × 30s — CI sanity" },
88
+ { value: "load", label: "load ramp to target VUs — steady state" },
89
+ {
90
+ value: "stress",
91
+ label: "stress climb to ceiling — find breaking point",
92
+ },
93
+ { value: "spike", label: "spike baseline → peak → recover" },
94
+ { value: "soak", label: "soak long-haul — leak detection" },
95
+ ],
96
+ initialValue: "smoke",
97
+ }));
98
+ if (isCancel(pace))
99
+ return bail();
100
+ const duration = (await text({
101
+ message: "Duration?",
102
+ initialValue: pace === "soak" ? "1h" : "30s",
103
+ }));
104
+ if (isCancel(duration))
105
+ return bail();
106
+ const auth = (await select({
107
+ message: "Auth?",
108
+ options: [
109
+ { value: "none", label: "None" },
110
+ { value: "bearer", label: "Bearer (API_TOKEN env)" },
111
+ { value: "basic", label: "Basic (API_USER / API_PASS env)" },
112
+ { value: "apiKey", label: "API key header (X-API-Key / API_KEY env)" },
113
+ { value: "session", label: "Session cookie (fill signIn yourself)" },
114
+ { value: "digest", label: "HTTP Digest (API_USER / API_PASS env)" },
115
+ { value: "ntlm", label: "NTLM (API_USER / API_PASS env)" },
116
+ ],
117
+ initialValue: "none",
118
+ }));
119
+ if (isCancel(auth))
120
+ return bail();
121
+ const slug = String(name)
122
+ .trim()
123
+ .replace(/[^a-zA-Z0-9-]+/g, "-");
124
+ const outputPath = (await text({
125
+ message: "Output path?",
126
+ initialValue: `${defaults.outputDir}/${slug}.ts`,
127
+ }));
128
+ if (isCancel(outputPath))
129
+ return bail();
130
+ const authOpts = { auth: auth };
131
+ return {
132
+ outputPath: outputPath,
133
+ scaffold: {
134
+ clientImportPath: defaults.clientImportPath,
135
+ pace: pace,
136
+ duration: duration,
137
+ ops,
138
+ chain: chain,
139
+ auth: authOpts,
140
+ },
141
+ };
142
+ }
143
+ /**
144
+ * Confirm-overwrite prompt — shared by wizard and flag-mode CLI so a single
145
+ * UX rules them both. Returns `true` to proceed.
146
+ */
147
+ export async function confirmOverwrite(path) {
148
+ const ok = await confirm({
149
+ message: `${path} already exists — overwrite?`,
150
+ initialValue: false,
151
+ });
152
+ if (isCancel(ok))
153
+ return false;
154
+ return Boolean(ok);
155
+ }
156
+ //# sourceMappingURL=wizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../src/scaffold/wizard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { OperationMap } from "./operation-map.js";
2
+ export declare const SNAPSHOT_FILENAME = ".k6-spec-snapshot.json";
3
+ export declare function loadSnapshotOps(path: string): Promise<OperationMap | null>;
4
+ /** Persist the current op map for the next sync to diff against. */
5
+ export declare function writeSnapshotOps(path: string, ops: OperationMap): Promise<void>;
6
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAO1D,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA0B9B;AAED,oEAAoE;AACpE,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,IAAI,CAAC,CAOf"}
@@ -0,0 +1,35 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { dirname } from "node:path";
3
+ export const SNAPSHOT_FILENAME = ".k6-spec-snapshot.json";
4
+ export async function loadSnapshotOps(path) {
5
+ let raw;
6
+ try {
7
+ raw = await readFile(path, "utf8");
8
+ }
9
+ catch (err) {
10
+ if (err.code === "ENOENT")
11
+ return null;
12
+ throw new Error(`Failed to read snapshot at ${path}: ${err.message}`);
13
+ }
14
+ let data;
15
+ try {
16
+ data = JSON.parse(raw);
17
+ }
18
+ catch (err) {
19
+ throw new Error(`Malformed snapshot at ${path}: ${err.message}. Delete the file to regenerate.`);
20
+ }
21
+ if (data?.v !== 1 || !data.operations) {
22
+ throw new Error(`Unrecognized snapshot schema at ${path} (expected v=1). Delete the file to regenerate.`);
23
+ }
24
+ return new Map(Object.entries(data.operations));
25
+ }
26
+ /** Persist the current op map for the next sync to diff against. */
27
+ export async function writeSnapshotOps(path, ops) {
28
+ await mkdir(dirname(path), { recursive: true });
29
+ const payload = {
30
+ v: 1,
31
+ operations: Object.fromEntries(ops),
32
+ };
33
+ await writeFile(path, JSON.stringify(payload, null, 2));
34
+ }
35
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,CAAC,MAAM,iBAAiB,GAAG,wBAAwB,CAAC;AAO1D,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAY;IAEZ,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAClE,MAAM,IAAI,KAAK,CACb,8BAA8B,IAAI,KAAM,GAAa,CAAC,OAAO,EAAE,CAChE,CAAC;IACJ,CAAC;IAED,IAAI,IAAmB,CAAC;IACxB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,yBAAyB,IAAI,KAAM,GAAa,CAAC,OAAO,kCAAkC,CAC3F,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CACb,mCAAmC,IAAI,iDAAiD,CACzF,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAY,EACZ,GAAiB;IAEjB,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,OAAO,GAAkB;QAC7B,CAAC,EAAE,CAAC;QACJ,UAAU,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC;KACpC,CAAC;IACF,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC"}