@spartaficial/openapi-to-k6 0.0.0-stage → 1.0.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.
@@ -0,0 +1,131 @@
1
+ /*!
2
+ * Copyright (c) 2026 Spartaficial - Cerios. All rights reserved.
3
+ * Proprietary software, licensed not sold. Unauthorized use, redistribution or
4
+ * circumvention of licensing is prohibited. See LICENSE for details.
5
+ */
6
+ import { Params, Params as Params$1, RequestBody, Response } from "k6/http";
7
+ /**
8
+ * K6 service result type - combines HTTP response with parsed data and status check result
9
+ * Used as return type for service methods
10
+ *
11
+ * @template T - The type of the parsed response data (from generated types)
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * // Service method returns K6ServiceResult<User>
16
+ * const result = service.getUserById("123");
17
+ * if (result.ok) {
18
+ * console.log(result.data.name); // data is typed as User
19
+ * } else {
20
+ * console.log(`Request failed with status: ${result.response.status}`);
21
+ * }
22
+ * ```
23
+ */
24
+ export interface K6ServiceResult<T> {
25
+ /** The raw K6 HTTP response */
26
+ response: Response;
27
+ /** The parsed response data */
28
+ data: T;
29
+ /** Whether the status code check passed */
30
+ ok: boolean;
31
+ }
32
+ /**
33
+ * Query string parameters
34
+ * Supports primitives, arrays, or undefined values
35
+ */
36
+ export type QueryParams = Record<string, string | number | boolean | string[] | number[] | boolean[] | Record<string, string | number | boolean | null | undefined> | undefined | null>;
37
+ /**
38
+ * Serialization styles OpenAPI defines for query parameters
39
+ */
40
+ export type QueryParameterStyle = "form" | "spaceDelimited" | "pipeDelimited" | "deepObject";
41
+ /**
42
+ * How a single parameter should be serialized
43
+ */
44
+ export interface ParameterSerialization {
45
+ style: QueryParameterStyle;
46
+ explode: boolean;
47
+ /**
48
+ * Leave RFC 3986 reserved characters unencoded in the value
49
+ *
50
+ * @default false
51
+ */
52
+ allowReserved?: boolean;
53
+ }
54
+ /**
55
+ * Per-parameter serialization, keyed by parameter name. Generated clients pass entries only
56
+ * for parameters that deviate from the OpenAPI default (form with explode: true).
57
+ */
58
+ export type ParameterSerializationMap = Record<string, ParameterSerialization>;
59
+ /**
60
+ * Merges request parameters with common parameters
61
+ * Request-specific parameters take precedence over common parameters
62
+ *
63
+ * Deep-merges nested object properties: headers, tags, cookies
64
+ *
65
+ * @param requestParams - Request-specific K6 parameters
66
+ * @param commonParams - Common K6 parameters set on the client
67
+ * @returns Merged parameters with request params taking precedence
68
+ */
69
+ export declare function mergeRequestParameters(requestParams: Params$1, commonParams: Params$1): Params$1;
70
+ /**
71
+ * Builds query string from parameters object
72
+ *
73
+ * Honours OpenAPI style/explode per parameter. Omitting `serializations` means the OpenAPI
74
+ * default, `form` with `explode: true`, which serializes arrays as repeated keys.
75
+ *
76
+ * @param params - Query parameters object
77
+ * @param serializations - Per-parameter style/explode, for parameters that deviate from the default
78
+ * @returns Query string starting with '?' or empty string if no params
79
+ */
80
+ export declare function buildQueryString(params?: QueryParams, serializations?: ParameterSerializationMap): string;
81
+ /**
82
+ * Cleans a base URL by removing trailing slashes
83
+ *
84
+ * @param baseUrl - The base URL to clean
85
+ * @returns URL without trailing slashes
86
+ */
87
+ export declare function cleanBaseUrl(baseUrl: string): string;
88
+ /**
89
+ * Safely formats a K6 response body for logging purposes.
90
+ * - null: returns "null"
91
+ * - string: returned as-is
92
+ * - ArrayBuffer: returns "[ArrayBuffer: N bytes]"
93
+ *
94
+ * @param body - The response body (string | ArrayBuffer | null)
95
+ * @returns A string representation safe for use in template literals
96
+ */
97
+ export declare function formatResponseBody(body: string | ArrayBuffer | null): string;
98
+ /**
99
+ * Serializes a request body for K6 HTTP requests.
100
+ * - null/undefined: passed through as-is
101
+ * - string: passed through as-is (already serialized)
102
+ * - ArrayBuffer: passed through as-is (binary data)
103
+ * - FileData (K6 type with 'data' property): passed through as-is
104
+ * - objects under a form or multipart content type: passed through for K6 to encode
105
+ * - other objects: JSON.stringify'd
106
+ *
107
+ * @param body - The request body to serialize
108
+ * @param contentType - The declared request content type, if any
109
+ * @returns Serialized body suitable for K6 http.request
110
+ */
111
+ export declare function serializeBody(body: unknown, contentType?: string): RequestBody | null | undefined;
112
+ /**
113
+ * Serialization styles OpenAPI defines for path parameters
114
+ */
115
+ export type PathParameterStyle = "simple" | "label" | "matrix";
116
+ /**
117
+ * How a single path parameter should be serialized
118
+ */
119
+ export interface PathParameterSerialization {
120
+ style: PathParameterStyle;
121
+ explode: boolean;
122
+ }
123
+ /**
124
+ * Serialize a path parameter into the text that replaces its {placeholder}
125
+ *
126
+ * Deliberate copy of `serializePathParam` in
127
+ * packages/openapi-core/src/utils/param-serialization.ts. This module ships standalone and must not import openapi-core. The shared table in
128
+ * fixtures/param-serialization-cases.ts is asserted from both, so the copies cannot drift.
129
+ */
130
+ export declare function serializePathParam(name: string, value: unknown, serialization?: PathParameterSerialization): string;
131
+ export type { Params };
@@ -0,0 +1,131 @@
1
+ /*!
2
+ * Copyright (c) 2026 Spartaficial - Cerios. All rights reserved.
3
+ * Proprietary software, licensed not sold. Unauthorized use, redistribution or
4
+ * circumvention of licensing is prohibited. See LICENSE for details.
5
+ */
6
+ import { Params, Params as Params$1, RequestBody, Response } from "k6/http";
7
+ /**
8
+ * K6 service result type - combines HTTP response with parsed data and status check result
9
+ * Used as return type for service methods
10
+ *
11
+ * @template T - The type of the parsed response data (from generated types)
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * // Service method returns K6ServiceResult<User>
16
+ * const result = service.getUserById("123");
17
+ * if (result.ok) {
18
+ * console.log(result.data.name); // data is typed as User
19
+ * } else {
20
+ * console.log(`Request failed with status: ${result.response.status}`);
21
+ * }
22
+ * ```
23
+ */
24
+ export interface K6ServiceResult<T> {
25
+ /** The raw K6 HTTP response */
26
+ response: Response;
27
+ /** The parsed response data */
28
+ data: T;
29
+ /** Whether the status code check passed */
30
+ ok: boolean;
31
+ }
32
+ /**
33
+ * Query string parameters
34
+ * Supports primitives, arrays, or undefined values
35
+ */
36
+ export type QueryParams = Record<string, string | number | boolean | string[] | number[] | boolean[] | Record<string, string | number | boolean | null | undefined> | undefined | null>;
37
+ /**
38
+ * Serialization styles OpenAPI defines for query parameters
39
+ */
40
+ export type QueryParameterStyle = "form" | "spaceDelimited" | "pipeDelimited" | "deepObject";
41
+ /**
42
+ * How a single parameter should be serialized
43
+ */
44
+ export interface ParameterSerialization {
45
+ style: QueryParameterStyle;
46
+ explode: boolean;
47
+ /**
48
+ * Leave RFC 3986 reserved characters unencoded in the value
49
+ *
50
+ * @default false
51
+ */
52
+ allowReserved?: boolean;
53
+ }
54
+ /**
55
+ * Per-parameter serialization, keyed by parameter name. Generated clients pass entries only
56
+ * for parameters that deviate from the OpenAPI default (form with explode: true).
57
+ */
58
+ export type ParameterSerializationMap = Record<string, ParameterSerialization>;
59
+ /**
60
+ * Merges request parameters with common parameters
61
+ * Request-specific parameters take precedence over common parameters
62
+ *
63
+ * Deep-merges nested object properties: headers, tags, cookies
64
+ *
65
+ * @param requestParams - Request-specific K6 parameters
66
+ * @param commonParams - Common K6 parameters set on the client
67
+ * @returns Merged parameters with request params taking precedence
68
+ */
69
+ export declare function mergeRequestParameters(requestParams: Params$1, commonParams: Params$1): Params$1;
70
+ /**
71
+ * Builds query string from parameters object
72
+ *
73
+ * Honours OpenAPI style/explode per parameter. Omitting `serializations` means the OpenAPI
74
+ * default, `form` with `explode: true`, which serializes arrays as repeated keys.
75
+ *
76
+ * @param params - Query parameters object
77
+ * @param serializations - Per-parameter style/explode, for parameters that deviate from the default
78
+ * @returns Query string starting with '?' or empty string if no params
79
+ */
80
+ export declare function buildQueryString(params?: QueryParams, serializations?: ParameterSerializationMap): string;
81
+ /**
82
+ * Cleans a base URL by removing trailing slashes
83
+ *
84
+ * @param baseUrl - The base URL to clean
85
+ * @returns URL without trailing slashes
86
+ */
87
+ export declare function cleanBaseUrl(baseUrl: string): string;
88
+ /**
89
+ * Safely formats a K6 response body for logging purposes.
90
+ * - null: returns "null"
91
+ * - string: returned as-is
92
+ * - ArrayBuffer: returns "[ArrayBuffer: N bytes]"
93
+ *
94
+ * @param body - The response body (string | ArrayBuffer | null)
95
+ * @returns A string representation safe for use in template literals
96
+ */
97
+ export declare function formatResponseBody(body: string | ArrayBuffer | null): string;
98
+ /**
99
+ * Serializes a request body for K6 HTTP requests.
100
+ * - null/undefined: passed through as-is
101
+ * - string: passed through as-is (already serialized)
102
+ * - ArrayBuffer: passed through as-is (binary data)
103
+ * - FileData (K6 type with 'data' property): passed through as-is
104
+ * - objects under a form or multipart content type: passed through for K6 to encode
105
+ * - other objects: JSON.stringify'd
106
+ *
107
+ * @param body - The request body to serialize
108
+ * @param contentType - The declared request content type, if any
109
+ * @returns Serialized body suitable for K6 http.request
110
+ */
111
+ export declare function serializeBody(body: unknown, contentType?: string): RequestBody | null | undefined;
112
+ /**
113
+ * Serialization styles OpenAPI defines for path parameters
114
+ */
115
+ export type PathParameterStyle = "simple" | "label" | "matrix";
116
+ /**
117
+ * How a single path parameter should be serialized
118
+ */
119
+ export interface PathParameterSerialization {
120
+ style: PathParameterStyle;
121
+ explode: boolean;
122
+ }
123
+ /**
124
+ * Serialize a path parameter into the text that replaces its {placeholder}
125
+ *
126
+ * Deliberate copy of `serializePathParam` in
127
+ * packages/openapi-core/src/utils/param-serialization.ts. This module ships standalone and must not import openapi-core. The shared table in
128
+ * fixtures/param-serialization-cases.ts is asserted from both, so the copies cannot drift.
129
+ */
130
+ export declare function serializePathParam(name: string, value: unknown, serialization?: PathParameterSerialization): string;
131
+ export type { Params };
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Copyright (c) 2026 Spartaficial - Cerios. All rights reserved.
3
+ * Proprietary software, licensed not sold. Unauthorized use, redistribution or
4
+ * circumvention of licensing is prohibited. See LICENSE for details.
5
+ */
6
+ function e(e,t){return{...t,...e,cookies:{...t?.cookies,...e?.cookies},headers:{...t?.headers,...e?.headers},tags:{...t?.tags,...e?.tags}}}function t(e){return encodeURIComponent(e).replace(/%20/g,`+`)}function n(e){return[...e].map(e=>`:/?#[]@!$&'()*+,;=`.includes(e)?e:t(e)).join(``)}const r={form:`,`,spaceDelimited:` `,pipeDelimited:`|`,deepObject:`,`},i={style:`form`,explode:!0};function a(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function o(e,t,n){if(t==null)return[];let{style:o,explode:s}=n??i;if(Array.isArray(t)){let n=t.filter(e=>e!=null);return s?n.map(t=>[e,String(t)]):n.length===0?[]:[[e,n.map(e=>String(e)).join(r[o])]]}if(a(t)){let n=Object.entries(t).filter(([,e])=>e!=null);return o===`deepObject`?n.map(([t,n])=>[`${e}[${t}]`,String(n)]):s?n.map(([e,t])=>[e,String(t)]):n.length===0?[]:[[e,n.flatMap(([e,t])=>[e,String(t)]).join(r[o])]]}return[[e,String(t)]]}function s(e,r){if(!e||Object.keys(e).length===0)return``;let i=[];for(let[a,s]of Object.entries(e)){let e=r?.[a]?.allowReserved??!1;for(let[c,l]of o(a,s,r?.[a])){let r=e?n(l):t(l);i.push(`${t(c)}=${r}`)}}let a=i.join(`&`);return a?`?${a}`:``}function c(e){return e.replace(/\/+$/,``)}function l(e){return typeof e==`object`&&!!e&&`data`in e}function u(e){return e===null?`null`:typeof e==`string`?e:`[ArrayBuffer: ${e.byteLength} bytes]`}const d=[`application/x-www-form-urlencoded`,`multipart/form-data`];function f(e,t){if(e==null||typeof e==`string`||e instanceof ArrayBuffer||l(e))return e;let n=t?.toLowerCase().split(`;`)[0].trim();return n&&d.includes(n)?e:JSON.stringify(e)}const p={style:`simple`,explode:!1};function m(e,t,n){if(t==null)return``;let{style:r,explode:i}=n??p,a=e=>encodeURIComponent(String(e)),o=r===`label`?`.`:r===`matrix`?`;${e}=`:``;if(Array.isArray(t)){let n=t.filter(e=>e!=null);return n.length===0?r===`matrix`?`;${e}=`:o:i?r===`label`?`.${n.map(a).join(`.`)}`:r===`matrix`?n.map(t=>`;${e}=${a(t)}`).join(``):n.map(a).join(`,`):`${o}${n.map(a).join(`,`)}`}if(typeof t==`object`){let n=Object.entries(t).filter(([,e])=>e!=null);if(n.length===0)return r===`matrix`?`;${e}=`:o;if(i){let e=n.map(([e,t])=>`${a(e)}=${a(t)}`);return r===`label`?`.${e.join(`.`)}`:r===`matrix`?`;${e.join(`;`)}`:e.join(`,`)}return`${o}${n.flatMap(([e,t])=>[a(e),a(t)]).join(`,`)}`}return`${o}${a(t)}`}export{s as buildQueryString,c as cleanBaseUrl,u as formatResponseBody,e as mergeRequestParameters,f as serializeBody,m as serializePathParam};
package/package.json CHANGED
@@ -1,6 +1,101 @@
1
1
  {
2
- "name": "@spartaficial/openapi-to-k6",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "@spartaficial/openapi-to-k6",
3
+ "version": "1.0.0",
4
+ "description": "Generate type-safe K6 HTTP clients from OpenAPI specifications with TypeScript types",
5
+ "keywords": [
6
+ "api-client",
7
+ "cerios",
8
+ "generator",
9
+ "k6",
10
+ "load-testing",
11
+ "openapi",
12
+ "performance-testing",
13
+ "typescript"
14
+ ],
15
+ "homepage": "https://spartaficial.dev/",
16
+ "bugs": {
17
+ "url": "https://github.com/Spartaficial/openapi-codegen-support/issues"
18
+ },
19
+ "license": "SEE LICENSE IN LICENSE",
20
+ "author": "Ronald Veth - Cerios",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/Spartaficial/openapi-codegen.git",
24
+ "directory": "packages/openapi-to-k6"
25
+ },
26
+ "bin": {
27
+ "openapi-to-k6": "./dist/cli.cjs"
28
+ },
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "type": "commonjs",
33
+ "sideEffects": false,
34
+ "main": "./dist/index.cjs",
35
+ "module": "./dist/index.mjs",
36
+ "types": "./dist/index.d.cts",
37
+ "typesVersions": {
38
+ "*": {
39
+ "runtime": [
40
+ "./dist/runtime.d.cts"
41
+ ]
42
+ }
43
+ },
44
+ "exports": {
45
+ ".": {
46
+ "import": {
47
+ "types": "./dist/index.d.mts",
48
+ "default": "./dist/index.mjs"
49
+ },
50
+ "require": {
51
+ "types": "./dist/index.d.cts",
52
+ "default": "./dist/index.cjs"
53
+ }
54
+ },
55
+ "./runtime": {
56
+ "import": {
57
+ "types": "./dist/runtime.d.mts",
58
+ "default": "./dist/runtime.mjs"
59
+ },
60
+ "require": {
61
+ "types": "./dist/runtime.d.cts",
62
+ "default": "./dist/runtime.cjs"
63
+ }
64
+ },
65
+ "./package.json": "./package.json"
66
+ },
67
+ "publishConfig": {
68
+ "access": "public"
69
+ },
70
+ "scripts": {
71
+ "build": "tsdown && tsx ../../scripts/obfuscate-dist.ts && tsx ../../scripts/add-banner.ts",
72
+ "check-exports": "attw --pack . && publint",
73
+ "compile": "tsc --noEmit",
74
+ "dev": "tsdown --watch",
75
+ "test": "vitest run",
76
+ "test:coverage": "vitest run --coverage"
77
+ },
78
+ "dependencies": {
79
+ "@spartaficial/openapi-core": "^1.0.0",
80
+ "@spartaficial/openapi-to-typescript": "^1.0.0",
81
+ "commander": "^15.1.0",
82
+ "prompts": "^2.4.2",
83
+ "zod": "^4.6.7"
84
+ },
85
+ "devDependencies": {
86
+ "@arethetypeswrong/cli": "^0.18.5",
87
+ "@types/k6": "^2.3.1",
88
+ "@types/node": "^26.6.6",
89
+ "@types/prompts": "^2.4.9",
90
+ "publint": "^0.3.25",
91
+ "tsdown": "^0.23.7",
92
+ "typescript": "^7.0.2",
93
+ "vitest": "^5.1.0"
94
+ },
95
+ "peerDependencies": {
96
+ "@types/k6": ">=0.52.0"
97
+ },
98
+ "engines": {
99
+ "node": "^22.18.0 || >=24"
100
+ }
101
+ }