@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
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ahmed Rowaihi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # `@ir-kit/k6-toolkit`
2
+
3
+ Programmatic toolkit for k6 workflows. One library covering the **bundle → run → sync** flow: bundle TypeScript loadtests (tsdown passthrough), spawn the k6 binary, sync the typed client from an OpenAPI spec.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install -D @ir-kit/k6-toolkit
9
+ ```
10
+
11
+ ## API
12
+
13
+ ### `bundle(opts)`
14
+
15
+ Bundles a `.ts` / `.tsx` loadtest into the single ES module k6 expects.
16
+
17
+ ```ts
18
+ import { bundle } from "@ir-kit/k6-toolkit";
19
+
20
+ await bundle({ entry: "loadtests/smoke.ts", out: ".k6/smoke.js" });
21
+ ```
22
+
23
+ ### `runK6(opts)`
24
+
25
+ Spawns the k6 binary with sensible defaults + structured output.
26
+
27
+ ```ts
28
+ import { runK6 } from "@ir-kit/k6-toolkit";
29
+
30
+ await runK6({ entry: ".k6/smoke.js", env: { BASE_URL: "https://api.example.com" } });
31
+ ```
32
+
33
+ ### `sync(opts)`
34
+
35
+ Regenerates the typed client from an OpenAPI spec — same logic as the standalone `@ir-kit/k6-gen` package, surfaced for in-process invocation.
36
+
37
+ ```ts
38
+ import { sync } from "@ir-kit/k6-toolkit";
39
+
40
+ await sync({ spec: "./openapi.yaml", output: "./src/gen" });
41
+ ```
42
+
43
+ ## CLI
44
+
45
+ The package also ships a `k6-ts` command for shell-driven workflows:
46
+
47
+ ```sh
48
+ k6-ts bundle loadtests/smoke.ts --out .k6/smoke.js
49
+ k6-ts run .k6/smoke.js
50
+ k6-ts sync ./openapi.yaml --output ./src/gen
51
+ k6-ts scaffold --spec ./openapi.yaml --tags pets --output-dir loadtests/
52
+ ```
53
+
54
+ `k6-ts sync` also accepts `-` to read the spec from stdin, so it composes cleanly with [`@ir-kit/openapi-recon`](https://github.com/ir-kit/ir-kit/tree/main/packages/openapi/recon) (HAR → spec) and similar pipes.
55
+
56
+ ## Status
57
+
58
+ `0.1.0` — first release under the `@ir-kit/*` scope. Replaces the legacy `@ahmedrowaihi/k6-toolkit` (deprecated).
59
+
60
+ ## Repo
61
+
62
+ Source at [ir-kit/ir-kit](https://github.com/ir-kit/ir-kit/tree/main/packages/k6/toolkit).
@@ -0,0 +1,15 @@
1
+ import ts from "typescript";
2
+ export interface NamedImportSpec {
3
+ name: string;
4
+ alias?: string;
5
+ typeOnly?: boolean;
6
+ }
7
+ /** `import { a, b as c } from "mod";` */
8
+ export declare function namedImport(specs: ReadonlyArray<NamedImportSpec>, moduleSpecifier: string, options?: {
9
+ typeOnly?: boolean;
10
+ }): ts.ImportDeclaration;
11
+ /** `import * as name from "mod";` (`typeOnly: true` for `import type * as name`). */
12
+ export declare function namespaceImport(name: string, moduleSpecifier: string, options?: {
13
+ typeOnly?: boolean;
14
+ }): ts.ImportDeclaration;
15
+ //# sourceMappingURL=ast-imports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast-imports.d.ts","sourceRoot":"","sources":["../src/ast-imports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAI5B,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,yCAAyC;AACzC,wBAAgB,WAAW,CACzB,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,EACrC,eAAe,EAAE,MAAM,EACvB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACnC,EAAE,CAAC,iBAAiB,CAiBtB;AAED,qFAAqF;AACrF,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,MAAM,EACvB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACnC,EAAE,CAAC,iBAAiB,CAUtB"}
@@ -0,0 +1,12 @@
1
+ import ts from "typescript";
2
+ const f = ts.factory;
3
+ /** `import { a, b as c } from "mod";` */
4
+ export function namedImport(specs, moduleSpecifier, options = {}) {
5
+ const elements = specs.map((s) => f.createImportSpecifier(s.typeOnly ?? false, s.alias ? f.createIdentifier(s.name) : undefined, f.createIdentifier(s.alias ?? s.name)));
6
+ return f.createImportDeclaration(undefined, f.createImportClause(options.typeOnly ?? false, undefined, f.createNamedImports(elements)), f.createStringLiteral(moduleSpecifier));
7
+ }
8
+ /** `import * as name from "mod";` (`typeOnly: true` for `import type * as name`). */
9
+ export function namespaceImport(name, moduleSpecifier, options = {}) {
10
+ return f.createImportDeclaration(undefined, f.createImportClause(options.typeOnly ?? false, undefined, f.createNamespaceImport(f.createIdentifier(name))), f.createStringLiteral(moduleSpecifier));
11
+ }
12
+ //# sourceMappingURL=ast-imports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast-imports.js","sourceRoot":"","sources":["../src/ast-imports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC;AAQrB,yCAAyC;AACzC,MAAM,UAAU,WAAW,CACzB,KAAqC,EACrC,eAAuB,EACvB,UAAkC,EAAE;IAEpC,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC/B,CAAC,CAAC,qBAAqB,CACrB,CAAC,CAAC,QAAQ,IAAI,KAAK,EACnB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAChD,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,CACtC,CACF,CAAC;IACF,OAAO,CAAC,CAAC,uBAAuB,CAC9B,SAAS,EACT,CAAC,CAAC,kBAAkB,CAClB,OAAO,CAAC,QAAQ,IAAI,KAAK,EACzB,SAAS,EACT,CAAC,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAC/B,EACD,CAAC,CAAC,mBAAmB,CAAC,eAAe,CAAC,CACvC,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,eAAe,CAC7B,IAAY,EACZ,eAAuB,EACvB,UAAkC,EAAE;IAEpC,OAAO,CAAC,CAAC,uBAAuB,CAC9B,SAAS,EACT,CAAC,CAAC,kBAAkB,CAClB,OAAO,CAAC,QAAQ,IAAI,KAAK,EACzB,SAAS,EACT,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAClD,EACD,CAAC,CAAC,mBAAmB,CAAC,eAAe,CAAC,CACvC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { type UserConfig } from "tsdown";
2
+ /**
3
+ * Anything tsdown's `build()` accepts. Consumers can pass plugins,
4
+ * watch, dts, target — full Rolldown surface. `entry` is required.
5
+ */
6
+ export type BundleOpts = UserConfig & {
7
+ entry: NonNullable<UserConfig["entry"]>;
8
+ };
9
+ export interface BundleResult {
10
+ /** Absolute path to the entry chunk — feed straight into `k6 run`. */
11
+ outfile: string;
12
+ /** Every chunk emitted (debug / multi-entry use cases). */
13
+ chunks: ReadonlyArray<{
14
+ fileName: string;
15
+ isEntry: boolean;
16
+ }>;
17
+ }
18
+ /**
19
+ * Bundle a k6 loadtest entry into a single ESM file the k6 binary can
20
+ * load. Defaults target k6's VM (es2022 + neutral platform + external
21
+ * `k6` / `k6/*`). All tsdown options pass through; arrays/strings in
22
+ * `external` are concatenated with the k6 defaults.
23
+ */
24
+ export declare function bundle(opts: BundleOpts): Promise<BundleResult>;
25
+ //# sourceMappingURL=bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEhD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG;IACpC,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;CACzC,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,MAAM,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC/D;AAcD;;;;;GAKG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAuBpE"}
package/dist/bundle.js ADDED
@@ -0,0 +1,60 @@
1
+ import { resolve } from "node:path";
2
+ import { build } from "tsdown";
3
+ const K6_EXTERNAL_DEFAULTS = ["k6", /^k6\//];
4
+ const DEFAULTS = {
5
+ format: "esm",
6
+ target: "es2022",
7
+ platform: "neutral",
8
+ external: [...K6_EXTERNAL_DEFAULTS],
9
+ noExternal: [/.*/],
10
+ logLevel: "error",
11
+ dts: false,
12
+ };
13
+ /**
14
+ * Bundle a k6 loadtest entry into a single ESM file the k6 binary can
15
+ * load. Defaults target k6's VM (es2022 + neutral platform + external
16
+ * `k6` / `k6/*`). All tsdown options pass through; arrays/strings in
17
+ * `external` are concatenated with the k6 defaults.
18
+ */
19
+ export async function bundle(opts) {
20
+ const merged = {
21
+ ...DEFAULTS,
22
+ ...opts,
23
+ external: mergeExternal(opts.external),
24
+ };
25
+ const [bundle] = await build(merged);
26
+ if (!bundle)
27
+ throw new Error("tsdown produced no bundle");
28
+ const entryChunk = bundle.chunks.find(isEntryChunk);
29
+ if (!entryChunk) {
30
+ throw new Error("tsdown produced no entry chunk — check your entry config");
31
+ }
32
+ const outDir = bundle.config.outDir ?? "dist";
33
+ return {
34
+ outfile: resolve(outDir, entryChunk.fileName),
35
+ chunks: bundle.chunks.map((c) => ({
36
+ fileName: c.fileName,
37
+ isEntry: isEntryChunk(c),
38
+ })),
39
+ };
40
+ }
41
+ function isEntryChunk(chunk) {
42
+ return chunk.type === "chunk" && chunk.isEntry === true;
43
+ }
44
+ function mergeExternal(user) {
45
+ if (user === undefined)
46
+ return [...K6_EXTERNAL_DEFAULTS];
47
+ if (typeof user === "function") {
48
+ return (id, parentId, isResolved) => {
49
+ for (const marker of K6_EXTERNAL_DEFAULTS) {
50
+ if (marker instanceof RegExp ? marker.test(id) : marker === id) {
51
+ return true;
52
+ }
53
+ }
54
+ return user(id, parentId, isResolved);
55
+ };
56
+ }
57
+ const userArr = Array.isArray(user) ? user : [user];
58
+ return [...K6_EXTERNAL_DEFAULTS, ...userArr];
59
+ }
60
+ //# sourceMappingURL=bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,KAAK,EAAmB,MAAM,QAAQ,CAAC;AAiBhD,MAAM,oBAAoB,GAAmC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAE7E,MAAM,QAAQ,GAAe;IAC3B,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,SAAS;IACnB,QAAQ,EAAE,CAAC,GAAG,oBAAoB,CAAC;IACnC,UAAU,EAAE,CAAC,IAAI,CAAC;IAClB,QAAQ,EAAE,OAAO;IACjB,GAAG,EAAE,KAAK;CACX,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAgB;IAC3C,MAAM,MAAM,GAAe;QACzB,GAAG,QAAQ;QACX,GAAG,IAAI;QACP,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;KACvC,CAAC;IAEF,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAE1D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACpD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC;IAC9C,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC;QAC7C,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChC,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;SACzB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,KAGrB;IACC,OAAO,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC;AAC1D,CAAC;AAED,SAAS,aAAa,CAAC,IAA4B;IACjD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,oBAAoB,CAAC,CAAC;IACzD,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE;YAClC,KAAK,MAAM,MAAM,IAAI,oBAAoB,EAAE,CAAC;gBAC1C,IAAI,MAAM,YAAY,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;oBAC/D,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QACxC,CAAC,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,oBAAoB,EAAE,GAAG,OAAO,CAAC,CAAC;AAC/C,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from "node:child_process";
3
+ import { existsSync } from "node:fs";
4
+ import { constants as osConstants } from "node:os";
5
+ import { resolve } from "node:path";
6
+ import { bundle } from "./bundle.js";
7
+ import { runScaffoldCommand } from "./scaffold/cli-handler.js";
8
+ import { runSyncCommand } from "./sync-cli.js";
9
+ const CACHE_DIR = ".k6-ts-cache";
10
+ /**
11
+ * Find the entry .ts file in the args. Walks right-to-left so the script's
12
+ * position (typically the last positional) wins over earlier flag values like
13
+ * `-e VAR=path.ts`.
14
+ */
15
+ function findTsEntry(args) {
16
+ for (let i = args.length - 1; i >= 0; i--) {
17
+ const a = args[i];
18
+ if (a.startsWith("-"))
19
+ continue;
20
+ if (a.includes("="))
21
+ continue;
22
+ if (!a.endsWith(".ts"))
23
+ continue;
24
+ if (!existsSync(resolve(a)))
25
+ continue;
26
+ return { index: i, path: a };
27
+ }
28
+ return null;
29
+ }
30
+ function signalToExitCode(signal) {
31
+ const signum = osConstants.signals[signal] ?? 1;
32
+ return 128 + signum;
33
+ }
34
+ async function main() {
35
+ const args = process.argv.slice(2);
36
+ if (args[0] === "scaffold") {
37
+ await runScaffoldCommand(args.slice(1));
38
+ return;
39
+ }
40
+ if (args[0] === "sync") {
41
+ await runSyncCommand(args.slice(1));
42
+ return;
43
+ }
44
+ let toExec = args;
45
+ const tsEntry = findTsEntry(args);
46
+ if (tsEntry) {
47
+ try {
48
+ const { outfile } = await bundle({
49
+ entry: resolve(tsEntry.path),
50
+ outDir: CACHE_DIR,
51
+ });
52
+ toExec = [
53
+ ...args.slice(0, tsEntry.index),
54
+ outfile,
55
+ ...args.slice(tsEntry.index + 1),
56
+ ];
57
+ }
58
+ catch (err) {
59
+ console.error(`k6-ts: bundle failed for ${tsEntry.path}:`, err instanceof Error ? err.message : err);
60
+ process.exit(1);
61
+ }
62
+ }
63
+ const child = spawn("k6", [...toExec], { stdio: "inherit" });
64
+ for (const sig of ["SIGINT", "SIGTERM", "SIGHUP"]) {
65
+ process.on(sig, () => {
66
+ if (!child.killed)
67
+ child.kill(sig);
68
+ });
69
+ }
70
+ child.on("error", (err) => {
71
+ if (err.code === "ENOENT") {
72
+ console.error("k6-ts: k6 binary not found on PATH. Install it from https://k6.io/docs/get-started/installation/");
73
+ process.exit(127);
74
+ }
75
+ console.error("k6-ts: failed to spawn k6:", err.message);
76
+ process.exit(1);
77
+ });
78
+ child.on("exit", (code, signal) => {
79
+ if (signal)
80
+ process.exit(signalToExitCode(signal));
81
+ process.exit(code ?? 1);
82
+ });
83
+ }
84
+ main().catch((err) => {
85
+ console.error("k6-ts:", err instanceof Error ? err.message : err);
86
+ process.exit(1);
87
+ });
88
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export { type GenerateOptions, type GenerateResult, generate, type ScaffoldOptions, } from "@ir-kit/k6-gen";
2
+ export { type BundleOpts, type BundleResult, bundle } from "./bundle.js";
3
+ export { type AuthFlavor, type InitFile, type InitOptions, type InitResult, init, } from "./init.js";
4
+ export type { OperationDiff, RenameEntry } from "./rename-report.js";
5
+ export { type RunK6Options, type RunK6Result, runK6 } from "./run.js";
6
+ export { type SyncOptions, type SyncResult, sync } from "./sync.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,QAAQ,EACR,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EACL,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,IAAI,GACL,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export { generate, } from "@ir-kit/k6-gen";
2
+ export { bundle } from "./bundle.js";
3
+ export { init, } from "./init.js";
4
+ export { runK6 } from "./run.js";
5
+ export { sync } from "./sync.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,QAAQ,GAET,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAsC,MAAM,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAKL,IAAI,GACL,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAuC,KAAK,EAAE,MAAM,UAAU,CAAC;AACtE,OAAO,EAAqC,IAAI,EAAE,MAAM,WAAW,CAAC"}
package/dist/init.d.ts ADDED
@@ -0,0 +1,50 @@
1
+ import type { GenerateOptions, GenerateResult } from "@ir-kit/k6-gen";
2
+ import { type AuthFlavor, type ScaffoldLoadtestOpts } from "./loadtest-scaffold.js";
3
+ export type { AuthFlavor } from "./loadtest-scaffold.js";
4
+ export interface InitOptions extends Pick<GenerateOptions, "input" | "normalize" | "defaultBaseUrl" | "scaffold"> {
5
+ /** Project root. Default: `process.cwd()`. */
6
+ cwd?: string;
7
+ /** Output directory for the generated client. Default: `./src/gen`. */
8
+ output?: string;
9
+ /** Where the loadtest scaffold lands. Default: `./loadtest.ts`. */
10
+ loadtestPath?: string;
11
+ /** Auth recipe wired into the scaffold. Default: `"none"`. */
12
+ auth?: AuthFlavor;
13
+ /** Env var holding the bearer token (only used when `auth === "bearer"`). */
14
+ bearerEnv?: string;
15
+ /** Header name for the API key (only used when `auth === "apiKey"`). */
16
+ apiKeyHeader?: string;
17
+ /** Env var holding the API key (only used when `auth === "apiKey"`). */
18
+ apiKeyEnv?: string;
19
+ /** Pace preset baked into the scaffold. Default: `"smoke"`. */
20
+ pace?: ScaffoldLoadtestOpts["pace"];
21
+ /** Scaffold pace duration string. Default: `"30s"`. */
22
+ duration?: string;
23
+ /**
24
+ * When set, emit `scenarios: { … }` with one entry per name instead of
25
+ * the single-pace shape. Each scenario gets its own pace + flow.
26
+ */
27
+ scenarios?: ReadonlyArray<string>;
28
+ /** Refuse to overwrite an existing loadtest file. Default: `true`. */
29
+ noOverwrite?: boolean;
30
+ /** Don't touch disk — return what would have been written. */
31
+ dryRun?: boolean;
32
+ }
33
+ export interface InitFile {
34
+ path: string;
35
+ content: string;
36
+ /** `false` when `dryRun` set or `noOverwrite` skipped the write. */
37
+ written: boolean;
38
+ }
39
+ export interface InitResult {
40
+ files: InitFile[];
41
+ generated: GenerateResult;
42
+ }
43
+ /**
44
+ * Scaffold a fresh k6 project: generate the typed client and emit a
45
+ * starter `loadtest.ts` parameterized on `auth` / `pace` / `scenarios`.
46
+ * The first param-less GET operation seeds the flow step so the file
47
+ * runs out of the box.
48
+ */
49
+ export declare function init(opts: InitOptions): Promise<InitResult>;
50
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGtE,OAAO,EACL,KAAK,UAAU,EACf,KAAK,oBAAoB,EAE1B,MAAM,wBAAwB,CAAC;AAGhC,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,WAAW,WACf,SAAQ,IAAI,CACV,eAAe,EACf,OAAO,GAAG,WAAW,GAAG,gBAAgB,GAAG,UAAU,CACtD;IACD,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACpC,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAClC,sEAAsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAsB,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CA0CjE"}
package/dist/init.js ADDED
@@ -0,0 +1,73 @@
1
+ import { existsSync } from "node:fs";
2
+ import { mkdir, writeFile } from "node:fs/promises";
3
+ import { dirname, relative, resolve } from "node:path";
4
+ import { scaffoldLoadtest, } from "./loadtest-scaffold.js";
5
+ import { sync } from "./sync.js";
6
+ /**
7
+ * Scaffold a fresh k6 project: generate the typed client and emit a
8
+ * starter `loadtest.ts` parameterized on `auth` / `pace` / `scenarios`.
9
+ * The first param-less GET operation seeds the flow step so the file
10
+ * runs out of the box.
11
+ */
12
+ export async function init(opts) {
13
+ const cwd = opts.cwd ?? process.cwd();
14
+ const output = resolve(cwd, opts.output ?? "./src/gen");
15
+ const loadtestPath = resolve(cwd, opts.loadtestPath ?? "./loadtest.ts");
16
+ const auth = opts.auth ?? "none";
17
+ const generated = await sync({
18
+ input: opts.input,
19
+ output,
20
+ cwd,
21
+ normalize: opts.normalize ?? true,
22
+ defaultBaseUrl: opts.defaultBaseUrl,
23
+ scaffold: opts.scaffold,
24
+ dryRun: opts.dryRun,
25
+ });
26
+ const content = scaffoldLoadtest({
27
+ clientImportPath: relativeClientImport(loadtestPath, output),
28
+ auth,
29
+ bearerEnv: opts.bearerEnv,
30
+ apiKeyHeader: opts.apiKeyHeader,
31
+ apiKeyEnv: opts.apiKeyEnv,
32
+ pace: opts.pace,
33
+ duration: opts.duration,
34
+ scenarios: opts.scenarios,
35
+ seedOperation: pickSeedOperation(generated.ir),
36
+ });
37
+ const exists = existsSync(loadtestPath);
38
+ const shouldSkip = exists && (opts.noOverwrite ?? true);
39
+ let written = false;
40
+ if (!opts.dryRun && !shouldSkip) {
41
+ await mkdir(dirname(loadtestPath), { recursive: true });
42
+ await writeFile(loadtestPath, content);
43
+ written = true;
44
+ }
45
+ return {
46
+ files: [{ path: loadtestPath, content, written }],
47
+ generated,
48
+ };
49
+ }
50
+ function relativeClientImport(loadtestPath, outputDir) {
51
+ const rel = relative(dirname(loadtestPath), outputDir).replaceAll("\\", "/");
52
+ return `./${rel || "."}/index.js`;
53
+ }
54
+ /** First GET op with no required path params + no required body. */
55
+ function pickSeedOperation(ir) {
56
+ const paths = ir
57
+ .paths;
58
+ if (!paths)
59
+ return undefined;
60
+ for (const pathItem of Object.values(paths)) {
61
+ const op = pathItem?.get;
62
+ if (!op?.id)
63
+ continue;
64
+ const requiredPathParams = Object.values(op.parameters?.path ?? {}).filter((p) => p.required);
65
+ if (requiredPathParams.length > 0)
66
+ continue;
67
+ if (op.body?.required)
68
+ continue;
69
+ return op.id;
70
+ }
71
+ return undefined;
72
+ }
73
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import ts from "typescript";
2
+ export type AuthFlavor = "none" | "bearer" | "basic" | "apiKey" | "session";
3
+ export interface ScaffoldLoadtestOpts {
4
+ /** Relative import path for the generated client. */
5
+ clientImportPath: string;
6
+ /** Auth recipe wired into `use: [...]`. */
7
+ auth: AuthFlavor;
8
+ /** Env var holding the bearer token (only for `auth === "bearer"`). */
9
+ bearerEnv?: string;
10
+ /** Header name for the API key (only for `auth === "apiKey"`). */
11
+ apiKeyHeader?: string;
12
+ /** Env var holding the API key (only for `auth === "apiKey"`). */
13
+ apiKeyEnv?: string;
14
+ /** k6 pace preset. Default: `"smoke"`. */
15
+ pace?: "smoke" | "load" | "stress" | "spike" | "soak";
16
+ /** Duration string passed to the pace preset. Default: `"30s"`. */
17
+ duration?: string;
18
+ /**
19
+ * Names for the `scenarios: { … }` block. When non-empty, the
20
+ * scaffold uses the multi-scenario shape (each gets its own pace +
21
+ * flow). When omitted/empty, falls back to the single-pace shape.
22
+ */
23
+ scenarios?: ReadonlyArray<string>;
24
+ /**
25
+ * Operation to seed the first flow step with. When set, the scaffold
26
+ * emits `api.<name>()` instead of an empty placeholder so new devs
27
+ * see a real call out of the box.
28
+ */
29
+ seedOperation?: string;
30
+ }
31
+ /** Render a starter `loadtest.ts` via `ts.factory` — no template strings. */
32
+ export declare function scaffoldLoadtest(opts: ScaffoldLoadtestOpts): string;
33
+ /**
34
+ * Compose the `import { defineLoadTest, flow, smoke, useAuth, batch?, ... }
35
+ * from "@ir-kit/k6"` line. Shared across both `scaffoldLoadtest` and
36
+ * `scaffoldScenario`. The caller chooses which framework symbols to add.
37
+ */
38
+ export declare function k6FrameworkImport(symbols: ReadonlyArray<string>): ts.ImportDeclaration;
39
+ /** `const auth = useAuth.<flavor>({ … });` */
40
+ export declare function authVarDecl(opts: AuthScaffoldOpts): ts.Statement;
41
+ /** Subset of opts needed to build an auth decl. */
42
+ export interface AuthScaffoldOpts {
43
+ auth: AuthFlavor;
44
+ bearerEnv?: string;
45
+ apiKeyHeader?: string;
46
+ apiKeyEnv?: string;
47
+ }
48
+ //# sourceMappingURL=loadtest-scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadtest-scaffold.d.ts","sourceRoot":"","sources":["../src/loadtest-scaffold.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAW5B,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE5E,MAAM,WAAW,oBAAoB;IACnC,qDAAqD;IACrD,gBAAgB,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,IAAI,EAAE,UAAU,CAAC;IACjB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IACtD,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAClC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAID,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAiBnE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAC7B,EAAE,CAAC,iBAAiB,CAKtB;AAED,8CAA8C;AAC9C,wBAAgB,WAAW,CAAC,IAAI,EAAE,gBAAgB,GAAG,EAAE,CAAC,SAAS,CAEhE;AAED,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}