@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.
- package/LICENSE.md +21 -0
- package/README.md +62 -0
- package/dist/ast-imports.d.ts +15 -0
- package/dist/ast-imports.d.ts.map +1 -0
- package/dist/ast-imports.js +12 -0
- package/dist/ast-imports.js.map +1 -0
- package/dist/bundle.d.ts +25 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +60 -0
- package/dist/bundle.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +88 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +50 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +73 -0
- package/dist/init.js.map +1 -0
- package/dist/loadtest-scaffold.d.ts +48 -0
- package/dist/loadtest-scaffold.d.ts.map +1 -0
- package/dist/loadtest-scaffold.js +121 -0
- package/dist/loadtest-scaffold.js.map +1 -0
- package/dist/operation-map.d.ts +6 -0
- package/dist/operation-map.d.ts.map +1 -0
- package/dist/operation-map.js +27 -0
- package/dist/operation-map.js.map +1 -0
- package/dist/print.d.ts +4 -0
- package/dist/print.d.ts.map +1 -0
- package/dist/print.js +14 -0
- package/dist/print.js.map +1 -0
- package/dist/rename-report.d.ts +26 -0
- package/dist/rename-report.d.ts.map +1 -0
- package/dist/rename-report.js +30 -0
- package/dist/rename-report.js.map +1 -0
- package/dist/run.d.ts +27 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +30 -0
- package/dist/run.js.map +1 -0
- package/dist/scaffold/ast-helpers.d.ts +10 -0
- package/dist/scaffold/ast-helpers.d.ts.map +1 -0
- package/dist/scaffold/ast-helpers.js +21 -0
- package/dist/scaffold/ast-helpers.js.map +1 -0
- package/dist/scaffold/chains.d.ts +10 -0
- package/dist/scaffold/chains.d.ts.map +1 -0
- package/dist/scaffold/chains.js +92 -0
- package/dist/scaffold/chains.js.map +1 -0
- package/dist/scaffold/cli-handler.d.ts +4 -0
- package/dist/scaffold/cli-handler.d.ts.map +1 -0
- package/dist/scaffold/cli-handler.js +204 -0
- package/dist/scaffold/cli-handler.js.map +1 -0
- package/dist/scaffold/scenario.d.ts +34 -0
- package/dist/scaffold/scenario.d.ts.map +1 -0
- package/dist/scaffold/scenario.js +67 -0
- package/dist/scaffold/scenario.js.map +1 -0
- package/dist/scaffold/spec-tags.d.ts +15 -0
- package/dist/scaffold/spec-tags.d.ts.map +1 -0
- package/dist/scaffold/spec-tags.js +23 -0
- package/dist/scaffold/spec-tags.js.map +1 -0
- package/dist/scaffold/wizard.d.ts +25 -0
- package/dist/scaffold/wizard.d.ts.map +1 -0
- package/dist/scaffold/wizard.js +156 -0
- package/dist/scaffold/wizard.js.map +1 -0
- package/dist/snapshot.d.ts +6 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +35 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/spawn-k6.d.ts +30 -0
- package/dist/spawn-k6.d.ts.map +1 -0
- package/dist/spawn-k6.js +46 -0
- package/dist/spawn-k6.js.map +1 -0
- package/dist/sync-cli.d.ts +2 -0
- package/dist/sync-cli.d.ts.map +1 -0
- package/dist/sync-cli.js +137 -0
- package/dist/sync-cli.js.map +1 -0
- package/dist/sync.d.ts +23 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +37 -0
- package/dist/sync.js.map +1 -0
- 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"}
|
package/dist/bundle.d.ts
ADDED
|
@@ -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 @@
|
|
|
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
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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 @@
|
|
|
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
|
package/dist/init.js.map
ADDED
|
@@ -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"}
|