@kubb/plugin-client 5.0.0-beta.42 → 5.0.0-beta.64
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/dist/clients/axios.cjs.map +1 -1
- package/dist/clients/axios.js.map +1 -1
- package/dist/clients/fetch.cjs.map +1 -1
- package/dist/clients/fetch.js.map +1 -1
- package/dist/index.cjs +439 -383
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +60 -25
- package/dist/index.js +435 -383
- package/dist/index.js.map +1 -1
- package/dist/templates/clients/axios.source.cjs.map +1 -1
- package/dist/templates/clients/axios.source.js.map +1 -1
- package/dist/templates/clients/fetch.source.cjs.map +1 -1
- package/dist/templates/clients/fetch.source.js.map +1 -1
- package/dist/templates/config.source.cjs.map +1 -1
- package/dist/templates/config.source.js.map +1 -1
- package/package.json +10 -18
- package/extension.yaml +0 -1267
- package/src/clients/axios.ts +0 -113
- package/src/clients/fetch.ts +0 -201
- package/src/components/ClassClient.tsx +0 -137
- package/src/components/Client.tsx +0 -273
- package/src/components/Operations.tsx +0 -29
- package/src/components/StaticClassClient.tsx +0 -129
- package/src/components/Url.tsx +0 -91
- package/src/components/WrapperClient.tsx +0 -33
- package/src/functionParams.ts +0 -118
- package/src/generators/classClientGenerator.tsx +0 -253
- package/src/generators/clientGenerator.tsx +0 -127
- package/src/generators/groupedClientGenerator.tsx +0 -82
- package/src/generators/operationsGenerator.tsx +0 -34
- package/src/generators/staticClassClientGenerator.tsx +0 -232
- package/src/index.ts +0 -9
- package/src/plugin.ts +0 -160
- package/src/resolvers/resolverClient.ts +0 -45
- package/src/templates/clients/axios.source.ts +0 -4
- package/src/templates/clients/fetch.source.ts +0 -4
- package/src/templates/config.source.ts +0 -4
- package/src/types.ts +0 -268
- package/src/utils.ts +0 -159
package/dist/index.js
CHANGED
|
@@ -4,8 +4,9 @@ import { source as source$1 } from "./templates/clients/fetch.source.js";
|
|
|
4
4
|
import { source as source$2 } from "./templates/config.source.js";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { ast, defineGenerator, definePlugin, defineResolver } from "@kubb/core";
|
|
7
|
+
import { buildJSDoc, caseParams, createOperationParams, stringify } from "@kubb/ast/utils";
|
|
7
8
|
import { functionPrinter, pluginTsName } from "@kubb/plugin-ts";
|
|
8
|
-
import { Const, File, Function,
|
|
9
|
+
import { Const, File, Function, jsxRenderer } from "@kubb/renderer-jsx";
|
|
9
10
|
import { Fragment, jsx, jsxs } from "@kubb/renderer-jsx/jsx-runtime";
|
|
10
11
|
import { pluginZodName } from "@kubb/plugin-zod";
|
|
11
12
|
//#region ../../internals/utils/src/casing.ts
|
|
@@ -19,68 +20,57 @@ import { pluginZodName } from "@kubb/plugin-zod";
|
|
|
19
20
|
function toCamelOrPascal(text, pascal) {
|
|
20
21
|
return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
|
|
21
22
|
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
22
|
-
|
|
23
|
-
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
23
|
+
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
24
24
|
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
|
-
* Splits `text` on `.` and applies `transformPart` to each segment.
|
|
28
|
-
* The last segment receives `isLast = true`, all earlier segments receive `false`.
|
|
29
|
-
* Segments are joined with `/` to form a file path.
|
|
30
|
-
*
|
|
31
|
-
* Only splits on dots followed by a letter so that version numbers
|
|
32
|
-
* embedded in operationIds (e.g. `v2025.0`) are kept intact.
|
|
33
|
-
*/
|
|
34
|
-
function applyToFileParts(text, transformPart) {
|
|
35
|
-
const parts = text.split(/\.(?=[a-zA-Z])/);
|
|
36
|
-
return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
27
|
* Converts `text` to camelCase.
|
|
40
|
-
* When `isFile` is `true`, dot-separated segments are each cased independently and joined with `/`.
|
|
41
28
|
*
|
|
42
|
-
* @example
|
|
43
|
-
* camelCase('hello-world')
|
|
44
|
-
*
|
|
29
|
+
* @example Word boundaries
|
|
30
|
+
* `camelCase('hello-world') // 'helloWorld'`
|
|
31
|
+
*
|
|
32
|
+
* @example With a prefix
|
|
33
|
+
* `camelCase('tag', { prefix: 'create' }) // 'createTag'`
|
|
45
34
|
*/
|
|
46
|
-
function camelCase(text, {
|
|
47
|
-
if (isFile) return applyToFileParts(text, (part, isLast) => camelCase(part, isLast ? {
|
|
48
|
-
prefix,
|
|
49
|
-
suffix
|
|
50
|
-
} : {}));
|
|
35
|
+
function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
51
36
|
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
52
37
|
}
|
|
53
38
|
/**
|
|
54
39
|
* Converts `text` to PascalCase.
|
|
55
|
-
* When `isFile` is `true`, the last dot-separated segment is PascalCased and earlier segments are camelCased.
|
|
56
40
|
*
|
|
57
|
-
* @example
|
|
58
|
-
* pascalCase('hello-world')
|
|
59
|
-
*
|
|
41
|
+
* @example Word boundaries
|
|
42
|
+
* `pascalCase('hello-world') // 'HelloWorld'`
|
|
43
|
+
*
|
|
44
|
+
* @example With a suffix
|
|
45
|
+
* `pascalCase('tag', { suffix: 'schema' }) // 'TagSchema'`
|
|
60
46
|
*/
|
|
61
|
-
function pascalCase(text, {
|
|
62
|
-
if (isFile) return applyToFileParts(text, (part, isLast) => isLast ? pascalCase(part, {
|
|
63
|
-
prefix,
|
|
64
|
-
suffix
|
|
65
|
-
}) : camelCase(part));
|
|
47
|
+
function pascalCase(text, { prefix = "", suffix = "" } = {}) {
|
|
66
48
|
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
|
|
67
49
|
}
|
|
68
50
|
//#endregion
|
|
69
|
-
//#region ../../internals/utils/src/
|
|
51
|
+
//#region ../../internals/utils/src/fs.ts
|
|
70
52
|
/**
|
|
71
|
-
* Builds a
|
|
72
|
-
*
|
|
53
|
+
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
54
|
+
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
55
|
+
* every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
|
|
73
56
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
57
|
+
* Empty segments are dropped before joining. They arise when the name starts with a dot
|
|
58
|
+
* followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
|
|
59
|
+
* an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
|
|
60
|
+
* absolute path, letting generated files escape the configured output directory.
|
|
61
|
+
*
|
|
62
|
+
* @example Nested path from a dotted name
|
|
63
|
+
* `toFilePath('pet.petId') // 'pet/petId'`
|
|
64
|
+
*
|
|
65
|
+
* @example PascalCase the final segment
|
|
66
|
+
* `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
|
|
67
|
+
*
|
|
68
|
+
* @example Suffix applied to the final segment only
|
|
69
|
+
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
79
70
|
*/
|
|
80
|
-
function
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
return `/**\n${comments.map((c) => `${indent}${c}`).join("\n")}\n */${suffix}`;
|
|
71
|
+
function toFilePath(name, caseLast = camelCase) {
|
|
72
|
+
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
73
|
+
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
84
74
|
}
|
|
85
75
|
//#endregion
|
|
86
76
|
//#region ../../internals/utils/src/reserved.ts
|
|
@@ -206,99 +196,83 @@ function ensureValidVarName(name) {
|
|
|
206
196
|
return `_${name}`;
|
|
207
197
|
}
|
|
208
198
|
//#endregion
|
|
209
|
-
//#region ../../internals/utils/src/
|
|
199
|
+
//#region ../../internals/utils/src/url.ts
|
|
200
|
+
function transformParam(raw, casing) {
|
|
201
|
+
const param = isValidVarName(raw) ? raw : camelCase(raw);
|
|
202
|
+
return casing === "camelcase" ? camelCase(param) : param;
|
|
203
|
+
}
|
|
204
|
+
function toParamsObject(path, { replacer, casing } = {}) {
|
|
205
|
+
const params = {};
|
|
206
|
+
for (const match of path.matchAll(/\{([^}]+)\}/g)) {
|
|
207
|
+
const param = transformParam(match[1], casing);
|
|
208
|
+
const key = replacer ? replacer(param) : param;
|
|
209
|
+
params[key] = key;
|
|
210
|
+
}
|
|
211
|
+
return Object.keys(params).length > 0 ? params : null;
|
|
212
|
+
}
|
|
210
213
|
/**
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
* @example
|
|
214
|
-
* const p = new URLPath('/pet/{petId}')
|
|
215
|
-
* p.URL // '/pet/:petId'
|
|
216
|
-
* p.template // '`/pet/${petId}`'
|
|
214
|
+
* Helpers for OpenAPI/Swagger paths, plus a thin wrapper over the native `URL`.
|
|
217
215
|
*/
|
|
218
|
-
var
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
*/
|
|
222
|
-
path;
|
|
223
|
-
#options;
|
|
224
|
-
constructor(path, options = {}) {
|
|
225
|
-
this.path = path;
|
|
226
|
-
this.#options = options;
|
|
216
|
+
var Url$1 = class Url$1 {
|
|
217
|
+
static {
|
|
218
|
+
__name(this, "Url");
|
|
227
219
|
}
|
|
228
|
-
/**
|
|
220
|
+
/**
|
|
221
|
+
* Reports whether `url` is a parseable absolute URL. Delegates to the native `URL.canParse`.
|
|
229
222
|
*
|
|
230
223
|
* @example
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
* ```
|
|
224
|
+
* Url.canParse('https://petstore.swagger.io/v2') // true
|
|
225
|
+
* Url.canParse('/pet/{petId}') // false
|
|
234
226
|
*/
|
|
235
|
-
|
|
236
|
-
return
|
|
227
|
+
static canParse(url, base) {
|
|
228
|
+
return URL.canParse(url, base);
|
|
237
229
|
}
|
|
238
|
-
/**
|
|
230
|
+
/**
|
|
231
|
+
* Converts an OpenAPI/Swagger path to Express-style colon syntax.
|
|
239
232
|
*
|
|
240
233
|
* @example
|
|
241
|
-
*
|
|
242
|
-
* new URLPath('https://petstore.swagger.io/v2/pet').isURL // true
|
|
243
|
-
* new URLPath('/pet/{petId}').isURL // false
|
|
244
|
-
* ```
|
|
234
|
+
* Url.toPath('/pet/{petId}') // '/pet/:petId'
|
|
245
235
|
*/
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
return !!new URL(this.path).href;
|
|
249
|
-
} catch {
|
|
250
|
-
return false;
|
|
251
|
-
}
|
|
236
|
+
static toPath(path) {
|
|
237
|
+
return path.replace(/\{([^}]+)\}/g, ":$1");
|
|
252
238
|
}
|
|
253
239
|
/**
|
|
254
|
-
* Converts
|
|
240
|
+
* Converts an OpenAPI/Swagger path to a TypeScript template literal string.
|
|
241
|
+
* `prefix` is prepended inside the literal, `replacer` transforms each parameter name,
|
|
242
|
+
* and `casing` controls parameter identifier casing.
|
|
255
243
|
*
|
|
256
244
|
* @example
|
|
257
|
-
*
|
|
258
|
-
* new URLPath('/account/monetary-accountID').template // '`/account/${monetaryAccountId}`'
|
|
259
|
-
*/
|
|
260
|
-
get template() {
|
|
261
|
-
return this.toTemplateString();
|
|
262
|
-
}
|
|
263
|
-
/** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set.
|
|
245
|
+
* Url.toTemplateString('/pet/{petId}') // '`/pet/${petId}`'
|
|
264
246
|
*
|
|
265
247
|
* @example
|
|
266
|
-
*
|
|
267
|
-
* new URLPath('/pet/{petId}').object
|
|
268
|
-
* // { url: '/pet/:petId', params: { petId: 'petId' } }
|
|
269
|
-
* ```
|
|
248
|
+
* Url.toTemplateString('/pet/{petId}', { prefix: 'https://api' }) // '`https://api/pet/${petId}`'
|
|
270
249
|
*/
|
|
271
|
-
|
|
272
|
-
|
|
250
|
+
static toTemplateString(path, { prefix, replacer, casing } = {}) {
|
|
251
|
+
const result = path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
252
|
+
if (i % 2 === 0) return part;
|
|
253
|
+
const param = transformParam(part, casing);
|
|
254
|
+
return `\${${replacer ? replacer(param) : param}}`;
|
|
255
|
+
}).join("");
|
|
256
|
+
return `\`${prefix ?? ""}${result}\``;
|
|
273
257
|
}
|
|
274
|
-
/**
|
|
258
|
+
/**
|
|
259
|
+
* Returns the path and its extracted params as a structured `URLObject`, or as a stringified
|
|
260
|
+
* expression when `stringify` is set.
|
|
275
261
|
*
|
|
276
262
|
* @example
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
* new URLPath('/pet').params // null
|
|
280
|
-
* ```
|
|
281
|
-
*/
|
|
282
|
-
get params() {
|
|
283
|
-
return this.toParamsObject();
|
|
284
|
-
}
|
|
285
|
-
#transformParam(raw) {
|
|
286
|
-
const param = isValidVarName(raw) ? raw : camelCase(raw);
|
|
287
|
-
return this.#options.casing === "camelcase" ? camelCase(param) : param;
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Iterates over every `{param}` token in `path`, calling `fn` with the raw token and transformed name.
|
|
263
|
+
* Url.toObject('/pet/{petId}')
|
|
264
|
+
* // { url: '/pet/:petId', params: { petId: 'petId' } }
|
|
291
265
|
*/
|
|
292
|
-
|
|
293
|
-
for (const match of this.path.matchAll(/\{([^}]+)\}/g)) {
|
|
294
|
-
const raw = match[1];
|
|
295
|
-
fn(raw, this.#transformParam(raw));
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
toObject({ type = "path", replacer, stringify } = {}) {
|
|
266
|
+
static toObject(path, { type = "path", replacer, stringify, casing } = {}) {
|
|
299
267
|
const object = {
|
|
300
|
-
url: type === "path" ?
|
|
301
|
-
|
|
268
|
+
url: type === "path" ? Url$1.toPath(path) : Url$1.toTemplateString(path, {
|
|
269
|
+
replacer,
|
|
270
|
+
casing
|
|
271
|
+
}),
|
|
272
|
+
params: toParamsObject(path, {
|
|
273
|
+
replacer,
|
|
274
|
+
casing
|
|
275
|
+
})
|
|
302
276
|
};
|
|
303
277
|
if (stringify) {
|
|
304
278
|
if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
|
|
@@ -307,50 +281,6 @@ var URLPath = class {
|
|
|
307
281
|
}
|
|
308
282
|
return object;
|
|
309
283
|
}
|
|
310
|
-
/**
|
|
311
|
-
* Converts the OpenAPI path to a TypeScript template literal string.
|
|
312
|
-
* An optional `replacer` can transform each extracted parameter name before interpolation.
|
|
313
|
-
*
|
|
314
|
-
* @example
|
|
315
|
-
* new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'
|
|
316
|
-
*/
|
|
317
|
-
toTemplateString({ prefix, replacer } = {}) {
|
|
318
|
-
const result = this.path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
319
|
-
if (i % 2 === 0) return part;
|
|
320
|
-
const param = this.#transformParam(part);
|
|
321
|
-
return `\${${replacer ? replacer(param) : param}}`;
|
|
322
|
-
}).join("");
|
|
323
|
-
return `\`${prefix ?? ""}${result}\``;
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* Extracts all `{param}` segments from the path and returns them as a key-value map.
|
|
327
|
-
* An optional `replacer` transforms each parameter name in both key and value positions.
|
|
328
|
-
* Returns `undefined` when no path parameters are found.
|
|
329
|
-
*
|
|
330
|
-
* @example
|
|
331
|
-
* ```ts
|
|
332
|
-
* new URLPath('/pet/{petId}/tag/{tagId}').toParamsObject()
|
|
333
|
-
* // { petId: 'petId', tagId: 'tagId' }
|
|
334
|
-
* ```
|
|
335
|
-
*/
|
|
336
|
-
toParamsObject(replacer) {
|
|
337
|
-
const params = {};
|
|
338
|
-
this.#eachParam((_raw, param) => {
|
|
339
|
-
const key = replacer ? replacer(param) : param;
|
|
340
|
-
params[key] = key;
|
|
341
|
-
});
|
|
342
|
-
return Object.keys(params).length > 0 ? params : null;
|
|
343
|
-
}
|
|
344
|
-
/** Converts the OpenAPI path to Express-style colon syntax.
|
|
345
|
-
*
|
|
346
|
-
* @example
|
|
347
|
-
* ```ts
|
|
348
|
-
* new URLPath('/pet/{petId}').toURLPath() // '/pet/:petId'
|
|
349
|
-
* ```
|
|
350
|
-
*/
|
|
351
|
-
toURLPath() {
|
|
352
|
-
return this.path.replace(/\{([^}]+)\}/g, ":$1");
|
|
353
|
-
}
|
|
354
284
|
};
|
|
355
285
|
//#endregion
|
|
356
286
|
//#region ../../internals/shared/src/operation.ts
|
|
@@ -376,7 +306,7 @@ function operationFileEntry(node, name, extname = ".ts") {
|
|
|
376
306
|
function getOperationLink(node, link) {
|
|
377
307
|
if (!link) return null;
|
|
378
308
|
if (typeof link === "function") return link(node) ?? null;
|
|
379
|
-
if (link === "urlPath") return node.path ? `{@link ${
|
|
309
|
+
if (link === "urlPath") return node.path ? `{@link ${Url$1.toPath(node.path)}}` : null;
|
|
380
310
|
return node.path ? `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}` : null;
|
|
381
311
|
}
|
|
382
312
|
function getContentTypeInfo(node) {
|
|
@@ -429,7 +359,7 @@ function buildOperationComments(node, options = {}) {
|
|
|
429
359
|
return filteredComments.flatMap((text) => text.split(/\r?\n/).map((line) => line.trim())).filter((comment) => Boolean(comment));
|
|
430
360
|
}
|
|
431
361
|
function getOperationParameters(node, options = {}) {
|
|
432
|
-
const params =
|
|
362
|
+
const params = caseParams(node.parameters, options.paramsCasing);
|
|
433
363
|
return {
|
|
434
364
|
path: params.filter((param) => param.in === "path"),
|
|
435
365
|
query: params.filter((param) => param.in === "query"),
|
|
@@ -467,6 +397,19 @@ function resolveSuccessNames(node, resolver) {
|
|
|
467
397
|
function resolveStatusCodeNames(node, resolver) {
|
|
468
398
|
return node.responses.map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
|
|
469
399
|
}
|
|
400
|
+
/**
|
|
401
|
+
* Builds the discriminated union type string for `dataReturnType: 'full'` return shapes.
|
|
402
|
+
* Each member is `{ status: N; data: StatusNType; statusText: string }`.
|
|
403
|
+
*/
|
|
404
|
+
function buildStatusUnionType(node, resolver) {
|
|
405
|
+
const members = node.responses.map((r) => {
|
|
406
|
+
const typeName = resolver.resolveResponseStatusName(node, r.statusCode);
|
|
407
|
+
const statusCode = Number.parseInt(r.statusCode, 10);
|
|
408
|
+
return `{ status: ${Number.isNaN(statusCode) ? "number" : String(statusCode)}; data: ${typeName}; statusText: string }`;
|
|
409
|
+
});
|
|
410
|
+
if (members.length === 1) return members[0];
|
|
411
|
+
return `(${members.join(" | ")})`;
|
|
412
|
+
}
|
|
470
413
|
const typeNamesByResolver = /* @__PURE__ */ new WeakMap();
|
|
471
414
|
function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
472
415
|
const cacheKey = `${node.operationId}\0${options.paramsCasing ?? ""}\0${options.order ?? ""}\0${options.responseStatusNames ?? ""}\0${(options.exclude ?? []).join(",")}`;
|
|
@@ -506,26 +449,24 @@ function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
|
506
449
|
* shared default naming so every plugin groups output consistently:
|
|
507
450
|
*
|
|
508
451
|
* - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).
|
|
509
|
-
* - other groups use
|
|
452
|
+
* - other groups use the camelCased group (`pet store` → `petStore`).
|
|
510
453
|
*
|
|
511
454
|
* A user-provided `group.name` always wins over the default namer, so callers stay in
|
|
512
455
|
* control of their output folders. Returns `null` when grouping is disabled, matching the
|
|
513
456
|
* per-plugin convention.
|
|
514
457
|
*
|
|
515
458
|
* @param group - The user-supplied group option, or `undefined` to disable grouping.
|
|
516
|
-
* @param options.suffix - Appended to non-`path` group names, e.g. `'Controller'` or `'Requests'`.
|
|
517
459
|
*
|
|
518
460
|
* @example
|
|
519
461
|
* ```ts
|
|
520
|
-
* createGroupConfig(group
|
|
521
|
-
* createGroupConfig(group, { suffix: 'Requests' }) // plugin-cypress, plugin-mcp
|
|
462
|
+
* createGroupConfig(group) // shared across every plugin
|
|
522
463
|
* ```
|
|
523
464
|
*/
|
|
524
|
-
function createGroupConfig(group
|
|
465
|
+
function createGroupConfig(group) {
|
|
525
466
|
if (!group) return null;
|
|
526
467
|
const defaultName = (ctx) => {
|
|
527
468
|
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
528
|
-
return
|
|
469
|
+
return camelCase(ctx.group);
|
|
529
470
|
};
|
|
530
471
|
return {
|
|
531
472
|
...group,
|
|
@@ -551,43 +492,52 @@ const callPrinter = functionPrinter({ mode: "call" });
|
|
|
551
492
|
function isGroup(spec) {
|
|
552
493
|
return "children" in spec;
|
|
553
494
|
}
|
|
554
|
-
function
|
|
555
|
-
return
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
495
|
+
function groupEntries(group) {
|
|
496
|
+
return Object.entries(group.children).filter(([, child]) => child != null);
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Assembles a destructured group parameter from a binding pattern and an optional
|
|
500
|
+
* type literal. Built directly because `createFunctionParameter({ properties })`
|
|
501
|
+
* requires every member to carry a type, while these groups also hold untyped,
|
|
502
|
+
* value-only call entries.
|
|
503
|
+
*/
|
|
504
|
+
function createGroupParam(elements, members, default_) {
|
|
505
|
+
return {
|
|
506
|
+
kind: "FunctionParameter",
|
|
507
|
+
name: ast.factory.createObjectBindingPattern({ elements }),
|
|
508
|
+
type: members.length ? ast.factory.createTypeLiteral({ members }) : void 0,
|
|
509
|
+
default: default_,
|
|
510
|
+
optional: false
|
|
511
|
+
};
|
|
559
512
|
}
|
|
560
513
|
function createDeclarationLeaf(name, spec) {
|
|
561
|
-
if (spec.default !== void 0) return ast.createFunctionParameter({
|
|
514
|
+
if (spec.default !== void 0) return ast.factory.createFunctionParameter({
|
|
562
515
|
name,
|
|
563
|
-
type:
|
|
516
|
+
type: spec.type,
|
|
564
517
|
default: spec.default,
|
|
565
518
|
rest: spec.mode === "inlineSpread"
|
|
566
519
|
});
|
|
567
|
-
return ast.createFunctionParameter({
|
|
520
|
+
return ast.factory.createFunctionParameter({
|
|
568
521
|
name,
|
|
569
|
-
type:
|
|
522
|
+
type: spec.type,
|
|
570
523
|
optional: !!spec.optional,
|
|
571
524
|
rest: spec.mode === "inlineSpread"
|
|
572
525
|
});
|
|
573
526
|
}
|
|
574
527
|
function createDeclarationParam(name, spec) {
|
|
575
|
-
if (isGroup(spec))
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
528
|
+
if (isGroup(spec)) {
|
|
529
|
+
const entries = groupEntries(spec);
|
|
530
|
+
return createGroupParam(entries.map(([childName]) => ({ name: childName })), entries.filter(([, child]) => child.type).map(([childName, child]) => ({
|
|
531
|
+
name: childName,
|
|
532
|
+
type: child.type,
|
|
533
|
+
optional: !!child.optional || child.default !== void 0
|
|
534
|
+
})), spec.default);
|
|
535
|
+
}
|
|
580
536
|
return createDeclarationLeaf(name, spec);
|
|
581
537
|
}
|
|
582
538
|
function createCallParam(name, spec) {
|
|
583
|
-
if (isGroup(spec)) return
|
|
584
|
-
|
|
585
|
-
properties: Object.entries(spec.children).filter(([, child]) => child != null).map(([childName, child]) => ast.createFunctionParameter({
|
|
586
|
-
name: child?.mode === "inlineSpread" ? spec.mode === "inlineSpread" ? child.value ?? childName : `...${child.value ?? childName}` : child?.value ? `${childName}: ${child.value}` : childName,
|
|
587
|
-
rest: spec.mode === "inlineSpread" && child?.mode === "inlineSpread"
|
|
588
|
-
}))
|
|
589
|
-
});
|
|
590
|
-
return ast.createFunctionParameter({
|
|
539
|
+
if (isGroup(spec)) return createGroupParam(groupEntries(spec).map(([childName, child]) => ({ name: child.mode === "inlineSpread" ? spec.mode === "inlineSpread" ? child.value ?? childName : `...${child.value ?? childName}` : child.value ? `${childName}: ${child.value}` : childName })), []);
|
|
540
|
+
return ast.factory.createFunctionParameter({
|
|
591
541
|
name: spec.value ?? name,
|
|
592
542
|
rest: spec.mode === "inlineSpread"
|
|
593
543
|
});
|
|
@@ -600,23 +550,159 @@ function createFunctionParams(params) {
|
|
|
600
550
|
const entries = Object.entries(params).filter(([, spec]) => spec != null);
|
|
601
551
|
return {
|
|
602
552
|
toConstructor() {
|
|
603
|
-
return declarationPrinter$4.print(ast.createFunctionParameters({ params: entries.map(([name, spec]) => createDeclarationParam(name, spec)) })) ?? "";
|
|
553
|
+
return declarationPrinter$4.print(ast.factory.createFunctionParameters({ params: entries.map(([name, spec]) => createDeclarationParam(name, spec)) })) ?? "";
|
|
604
554
|
},
|
|
605
555
|
toCall() {
|
|
606
|
-
return callPrinter.print(ast.createFunctionParameters({ params: entries.map(([name, spec]) => createCallParam(name, spec)) })) ?? "";
|
|
556
|
+
return callPrinter.print(ast.factory.createFunctionParameters({ params: entries.map(([name, spec]) => createCallParam(name, spec)) })) ?? "";
|
|
607
557
|
}
|
|
608
558
|
};
|
|
609
559
|
}
|
|
610
560
|
//#endregion
|
|
561
|
+
//#region src/utils.ts
|
|
562
|
+
/**
|
|
563
|
+
* Returns `true` when any direction of the parser uses Zod (used for dependency checks).
|
|
564
|
+
*/
|
|
565
|
+
function isParserEnabled(parser) {
|
|
566
|
+
if (!parser) return false;
|
|
567
|
+
if (parser === "zod") return true;
|
|
568
|
+
return !!(parser.request || parser.response);
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Returns `'zod'` when request body parsing is enabled, `null` otherwise.
|
|
572
|
+
* The string shorthand `'zod'` also enables request body parsing (existing behavior).
|
|
573
|
+
*/
|
|
574
|
+
function resolveRequestParser(parser) {
|
|
575
|
+
if (!parser) return null;
|
|
576
|
+
if (parser === "zod") return "zod";
|
|
577
|
+
return parser.request ?? null;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Returns `'zod'` when query-parameters parsing is enabled, `null` otherwise.
|
|
581
|
+
* Only the object form `{ request: 'zod' }` enables query-params parsing.
|
|
582
|
+
* The string shorthand `'zod'` does not, preserving its existing behavior.
|
|
583
|
+
*/
|
|
584
|
+
function resolveQueryParamsParser(parser) {
|
|
585
|
+
if (!parser || parser === "zod") return null;
|
|
586
|
+
return parser.request ?? null;
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Returns `'zod'` when response-direction parsing is enabled, `null` otherwise.
|
|
590
|
+
* `parser: 'zod'` (string shorthand) maps to response parsing and returns `'zod'`.
|
|
591
|
+
*/
|
|
592
|
+
function resolveResponseParser(parser) {
|
|
593
|
+
if (!parser) return null;
|
|
594
|
+
if (parser === "zod") return "zod";
|
|
595
|
+
return parser.response ?? null;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Builds HTTP headers array for a client request.
|
|
599
|
+
* Includes Content-Type (if not default) and spreads header parameters if present.
|
|
600
|
+
*/
|
|
601
|
+
function buildHeaders(contentType, hasHeaderParams) {
|
|
602
|
+
return [contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` : null, hasHeaderParams ? "...headers" : null].filter(Boolean);
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Returns the generic type arguments — response, error, and request body — for a generated
|
|
606
|
+
* client call.
|
|
607
|
+
*
|
|
608
|
+
* When `dataReturnType` is `'full'`, the response generic widens to a union of all documented
|
|
609
|
+
* status types. When `parser` is `'zod'` and a request body schema exists, the request type
|
|
610
|
+
* uses `z.output<typeof schema>` to reflect post-transform types (e.g. date coercion).
|
|
611
|
+
*/
|
|
612
|
+
function buildGenerics(node, tsResolver, options = {}) {
|
|
613
|
+
const allStatusNames = node.responses.map((r) => tsResolver.resolveResponseStatusName(node, r.statusCode));
|
|
614
|
+
const successNames = resolveSuccessNames(node, tsResolver);
|
|
615
|
+
const responseName = options.dataReturnType === "full" ? allStatusNames.length > 0 ? allStatusNames.join(" | ") : tsResolver.resolveResponseName(node) : successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
|
|
616
|
+
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : null;
|
|
617
|
+
const errorNames = node.responses.filter((r) => Number.parseInt(r.statusCode, 10) >= 400).map((r) => tsResolver.resolveResponseStatusName(node, r.statusCode));
|
|
618
|
+
const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
|
|
619
|
+
const zodRequestName = options.parser === "zod" && options.zodResolver && node.requestBody?.content?.[0]?.schema ? options.zodResolver.resolveDataName?.(node) ?? null : null;
|
|
620
|
+
return [
|
|
621
|
+
responseName,
|
|
622
|
+
TError,
|
|
623
|
+
zodRequestName ? `z.output<typeof ${zodRequestName}>` : requestName || "unknown"
|
|
624
|
+
].filter(Boolean);
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Builds the parameters object for a class-based client method.
|
|
628
|
+
* Includes URL, method, base URL, headers, and request/response data.
|
|
629
|
+
*/
|
|
630
|
+
function buildClassClientParams({ node, url, baseURL, tsResolver, isFormData, isMultipleContentTypes, hasFormData, headers, zodQueryParamsName }) {
|
|
631
|
+
const { query: queryParams } = getOperationParameters(node);
|
|
632
|
+
const queryParamsName = queryParams.length > 0 ? tsResolver.resolveQueryParamsName(node, queryParams[0]) : null;
|
|
633
|
+
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : null;
|
|
634
|
+
const responseType = getResponseType(node);
|
|
635
|
+
return createFunctionParams({ config: {
|
|
636
|
+
mode: "object",
|
|
637
|
+
children: {
|
|
638
|
+
requestConfig: { mode: "inlineSpread" },
|
|
639
|
+
method: { value: JSON.stringify(ast.isHttpOperationNode(node) ? node.method.toUpperCase() : "") },
|
|
640
|
+
url: { value: url },
|
|
641
|
+
baseURL: baseURL ? { value: JSON.stringify(baseURL) } : null,
|
|
642
|
+
params: queryParamsName ? zodQueryParamsName ? { value: "requestParams" } : {} : null,
|
|
643
|
+
data: requestName ? { value: isMultipleContentTypes && hasFormData ? "contentType === 'multipart/form-data' ? formData as FormData : requestData" : isFormData ? "formData as FormData" : "requestData" } : null,
|
|
644
|
+
contentType: isMultipleContentTypes ? {} : null,
|
|
645
|
+
responseType: responseType ? { value: JSON.stringify(responseType) } : null,
|
|
646
|
+
headers: headers.length ? { value: `{ ${headers.join(", ")}, ...requestConfig.headers }` } : null
|
|
647
|
+
}
|
|
648
|
+
} });
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Builds the request data parsing line for client methods.
|
|
652
|
+
* Applies Zod validation when `parser.request === 'zod'`, otherwise assigns data directly.
|
|
653
|
+
*/
|
|
654
|
+
function buildRequestDataLine({ parser, node, zodResolver }) {
|
|
655
|
+
const requestParser = resolveRequestParser(parser);
|
|
656
|
+
const zodRequestName = zodResolver && requestParser === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null;
|
|
657
|
+
if (requestParser === "zod" && zodRequestName) return `const requestData = ${zodRequestName}.parse(data)`;
|
|
658
|
+
if (node.requestBody?.content?.[0]?.schema) return "const requestData = data";
|
|
659
|
+
return "";
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Builds the query parameters parsing line for client methods.
|
|
663
|
+
* Returns an empty string when no query params exist or query-params parsing is not enabled.
|
|
664
|
+
* Only the object form `parser: { request: 'zod' }` triggers this. `parser: 'zod'` does not.
|
|
665
|
+
*/
|
|
666
|
+
function buildQueryParamsLine({ parser, node, zodResolver }) {
|
|
667
|
+
if (resolveQueryParamsParser(parser) !== "zod" || !zodResolver) return "";
|
|
668
|
+
const { query: queryParams } = getOperationParameters(node);
|
|
669
|
+
if (queryParams.length === 0) return "";
|
|
670
|
+
const zodQueryParamsName = zodResolver.resolveQueryParamsName?.(node, queryParams[0]);
|
|
671
|
+
if (!zodQueryParamsName) return "";
|
|
672
|
+
return `const requestParams = ${zodQueryParamsName}.parse(params)`;
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Builds the form data conversion line for file upload requests.
|
|
676
|
+
* Returns empty string if not applicable.
|
|
677
|
+
*/
|
|
678
|
+
function buildFormDataLine(isFormData, hasRequest) {
|
|
679
|
+
return isFormData && hasRequest ? "const formData = buildFormData(requestData)" : "";
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* Builds the return statement for a client method.
|
|
683
|
+
* When `dataReturnType` is `'full'`, casts the response to the status-discriminated union type.
|
|
684
|
+
* When `parser.response` is `'zod'`, pipes the response body through the Zod schema before returning.
|
|
685
|
+
*/
|
|
686
|
+
function buildReturnStatement({ dataReturnType, parser, node, zodResolver, tsResolver }) {
|
|
687
|
+
const responseParser = resolveResponseParser(parser);
|
|
688
|
+
const zodResponseName = zodResolver && responseParser === "zod" ? zodResolver.resolveResponseName?.(node) : null;
|
|
689
|
+
if (dataReturnType === "full" && tsResolver) {
|
|
690
|
+
const unionType = buildStatusUnionType(node, tsResolver);
|
|
691
|
+
if (responseParser === "zod" && zodResponseName) return `return {...res, data: ${zodResponseName}.parse(res.data)} as ${unionType}`;
|
|
692
|
+
return `return res as ${unionType}`;
|
|
693
|
+
}
|
|
694
|
+
if (dataReturnType === "data" && responseParser === "zod" && zodResponseName) return `return ${zodResponseName}.parse(res.data)`;
|
|
695
|
+
return "return res.data";
|
|
696
|
+
}
|
|
697
|
+
//#endregion
|
|
611
698
|
//#region src/components/Url.tsx
|
|
612
699
|
const declarationPrinter$3 = functionPrinter({ mode: "declaration" });
|
|
613
700
|
function buildUrlParamsNode({ paramsType, paramsCasing, pathParamsType, node, tsResolver }) {
|
|
614
|
-
|
|
701
|
+
return createOperationParams({
|
|
615
702
|
...node,
|
|
616
703
|
parameters: node.parameters.filter((p) => p.in === "path"),
|
|
617
704
|
requestBody: void 0
|
|
618
|
-
}
|
|
619
|
-
return ast.createOperationParams(urlNode, {
|
|
705
|
+
}, {
|
|
620
706
|
paramsType: paramsType === "object" ? "object" : "inline",
|
|
621
707
|
pathParamsType: paramsType === "object" ? "object" : pathParamsType === "object" ? "object" : "inline",
|
|
622
708
|
paramsCasing,
|
|
@@ -625,7 +711,6 @@ function buildUrlParamsNode({ paramsType, paramsCasing, pathParamsType, node, ts
|
|
|
625
711
|
}
|
|
626
712
|
function Url({ name, isExportable = true, isIndexable = true, baseURL, paramsType, paramsCasing, pathParamsType, node, tsResolver }) {
|
|
627
713
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
628
|
-
const path = new URLPath(node.path);
|
|
629
714
|
const paramsNode = buildUrlParamsNode({
|
|
630
715
|
paramsType,
|
|
631
716
|
paramsCasing,
|
|
@@ -650,7 +735,7 @@ function Url({ name, isExportable = true, isIndexable = true, baseURL, paramsTyp
|
|
|
650
735
|
pathParamsMapping && Object.keys(pathParamsMapping).length > 0 && /* @__PURE__ */ jsx("br", {}),
|
|
651
736
|
/* @__PURE__ */ jsx(Const, {
|
|
652
737
|
name: "res",
|
|
653
|
-
children: `{ method: '${node.method.toUpperCase()}', url: ${
|
|
738
|
+
children: `{ method: '${node.method.toUpperCase()}', url: ${Url$1.toTemplateString(node.path, { prefix: baseURL })} as const }`
|
|
654
739
|
}),
|
|
655
740
|
/* @__PURE__ */ jsx("br", {}),
|
|
656
741
|
"return res"
|
|
@@ -662,24 +747,20 @@ function Url({ name, isExportable = true, isIndexable = true, baseURL, paramsTyp
|
|
|
662
747
|
//#region src/components/Client.tsx
|
|
663
748
|
const declarationPrinter$2 = functionPrinter({ mode: "declaration" });
|
|
664
749
|
function buildClientParamsNode({ paramsType, paramsCasing, pathParamsType, node, tsResolver, isConfigurable }) {
|
|
665
|
-
return
|
|
750
|
+
return createOperationParams(node, {
|
|
666
751
|
paramsType,
|
|
667
752
|
pathParamsType: paramsType === "object" ? "object" : pathParamsType === "object" ? "object" : "inline",
|
|
668
753
|
paramsCasing,
|
|
669
754
|
resolver: tsResolver,
|
|
670
|
-
extraParams: [...isConfigurable ? [ast.createFunctionParameter({
|
|
755
|
+
extraParams: [...isConfigurable ? [ast.factory.createFunctionParameter({
|
|
671
756
|
name: "config",
|
|
672
|
-
type:
|
|
673
|
-
variant: "reference",
|
|
674
|
-
name: buildRequestConfigType(node, tsResolver)
|
|
675
|
-
}),
|
|
757
|
+
type: buildRequestConfigType(node, tsResolver),
|
|
676
758
|
default: "{}"
|
|
677
759
|
})] : []]
|
|
678
760
|
});
|
|
679
761
|
}
|
|
680
762
|
function Client({ name, isExportable = true, isIndexable = true, returnType, baseURL, dataReturnType, parser, paramsType, paramsCasing, pathParamsType, node, tsResolver, zodResolver, urlName, children, isConfigurable = true }) {
|
|
681
763
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
682
|
-
const path = new URLPath(node.path);
|
|
683
764
|
const { defaultContentType: contentType, isMultipleContentTypes, hasFormData } = getContentTypeInfo(node);
|
|
684
765
|
const isFormData = !isMultipleContentTypes && contentType === "multipart/form-data";
|
|
685
766
|
const responseType = getResponseType(node);
|
|
@@ -693,16 +774,22 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
|
|
|
693
774
|
const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
|
|
694
775
|
const queryParamsName = originalQueryParams.length > 0 ? tsResolver.resolveQueryParamsName(node, originalQueryParams[0]) : null;
|
|
695
776
|
const headerParamsName = originalHeaderParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, originalHeaderParams[0]) : null;
|
|
696
|
-
const
|
|
697
|
-
const
|
|
777
|
+
const requestParser = resolveRequestParser(parser);
|
|
778
|
+
const responseParser = resolveResponseParser(parser);
|
|
779
|
+
const zodResponseName = zodResolver && responseParser === "zod" ? zodResolver.resolveResponseName?.(node) : null;
|
|
780
|
+
const zodRequestName = zodResolver && requestParser === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null;
|
|
781
|
+
const queryParamsParser = resolveQueryParamsParser(parser);
|
|
782
|
+
const zodQueryParamsName = zodResolver && queryParamsParser === "zod" && originalQueryParams.length > 0 ? zodResolver.resolveQueryParamsName?.(node, originalQueryParams[0]) : null;
|
|
698
783
|
const errorNames = node.responses.filter((r) => {
|
|
699
784
|
return Number.parseInt(r.statusCode, 10) >= 400;
|
|
700
785
|
}).map((r) => tsResolver.resolveResponseStatusName(node, r.statusCode));
|
|
701
786
|
const headers = [!isMultipleContentTypes && contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` : null, headerParamsName ? headerParamsMapping ? "...mappedHeaders" : "...headers" : null].filter(Boolean);
|
|
787
|
+
const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
|
|
788
|
+
const allStatusNames = node.responses.map((r) => tsResolver.resolveResponseStatusName(node, r.statusCode));
|
|
702
789
|
const generics = [
|
|
703
|
-
responseName,
|
|
704
|
-
|
|
705
|
-
requestName || "unknown"
|
|
790
|
+
dataReturnType === "full" ? allStatusNames.length > 0 ? allStatusNames.join(" | ") : responseName : responseName,
|
|
791
|
+
TError,
|
|
792
|
+
parser === "zod" && zodRequestName ? `z.output<typeof ${zodRequestName}>` : requestName || "unknown"
|
|
706
793
|
].filter(Boolean);
|
|
707
794
|
const paramsNode = buildClientParamsNode({
|
|
708
795
|
paramsType,
|
|
@@ -724,22 +811,23 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
|
|
|
724
811
|
const clientParams = createFunctionParams({ config: {
|
|
725
812
|
mode: "object",
|
|
726
813
|
children: {
|
|
727
|
-
method: { value:
|
|
728
|
-
url: { value: urlName ? `${urlName}(${urlParamsCall}).url.toString()` : path
|
|
814
|
+
method: { value: stringify(node.method.toUpperCase()) },
|
|
815
|
+
url: { value: urlName ? `${urlName}(${urlParamsCall}).url.toString()` : Url$1.toTemplateString(node.path) },
|
|
729
816
|
baseURL: baseURL && !urlName ? { value: `\`${baseURL}\`` } : null,
|
|
730
|
-
params: queryParamsName ? queryParamsMapping ? { value: "mappedParams" } : {} : null,
|
|
817
|
+
params: queryParamsName ? zodQueryParamsName ? { value: "requestParams" } : queryParamsMapping ? { value: "mappedParams" } : {} : null,
|
|
731
818
|
data: requestName ? { value: isMultipleContentTypes && hasFormData ? "contentType === 'multipart/form-data' ? formData as FormData : requestData" : isFormData ? "formData as FormData" : "requestData" } : null,
|
|
732
819
|
contentType: isConfigurable && isMultipleContentTypes ? {} : null,
|
|
733
|
-
responseType: responseType ? { value:
|
|
820
|
+
responseType: responseType ? { value: stringify(responseType) } : null,
|
|
734
821
|
requestConfig: isConfigurable ? { mode: "inlineSpread" } : null,
|
|
735
822
|
headers: headers.length ? { value: isConfigurable ? `{ ${headers.join(", ")}, ...requestConfig.headers }` : `{ ${headers.join(", ")} }` } : null
|
|
736
823
|
}
|
|
737
824
|
} });
|
|
825
|
+
const statusUnionType = dataReturnType === "full" ? buildStatusUnionType(node, tsResolver) : null;
|
|
738
826
|
const childrenElement = children ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
739
|
-
dataReturnType === "full" &&
|
|
740
|
-
dataReturnType === "
|
|
741
|
-
dataReturnType === "
|
|
742
|
-
dataReturnType === "data" &&
|
|
827
|
+
dataReturnType === "full" && responseParser === "zod" && zodResponseName && statusUnionType && `return {...res, data: ${zodResponseName}.parse(res.data)} as ${statusUnionType}`,
|
|
828
|
+
dataReturnType === "full" && responseParser !== "zod" && statusUnionType && `return res as ${statusUnionType}`,
|
|
829
|
+
dataReturnType === "data" && responseParser === "zod" && zodResponseName && `return ${zodResponseName}.parse(res.data)`,
|
|
830
|
+
dataReturnType === "data" && responseParser !== "zod" && "return res.data"
|
|
743
831
|
] });
|
|
744
832
|
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("br", {}), /* @__PURE__ */ jsx(File.Source, {
|
|
745
833
|
name,
|
|
@@ -757,23 +845,14 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
|
|
|
757
845
|
}) },
|
|
758
846
|
returnType,
|
|
759
847
|
children: [
|
|
760
|
-
isConfigurable ? `const { client: request = client, ${isMultipleContentTypes ? `contentType = ${
|
|
761
|
-
/* @__PURE__ */ jsx("br", {}),
|
|
848
|
+
isConfigurable ? `const { client: request = client, ${isMultipleContentTypes ? `contentType = ${stringify(contentType)}, ` : ""}...requestConfig } = config` : "",
|
|
762
849
|
/* @__PURE__ */ jsx("br", {}),
|
|
763
850
|
pathParamsMapping && Object.entries(pathParamsMapping).filter(([originalName, camelCaseName]) => isValidVarName(originalName) && originalName !== camelCaseName).map(([originalName, camelCaseName]) => `const ${originalName} = ${camelCaseName}`).join("\n"),
|
|
764
|
-
pathParamsMapping && /* @__PURE__ */
|
|
765
|
-
queryParamsMapping && queryParamsName && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
] }),
|
|
770
|
-
headerParamsMapping && headerParamsName && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
771
|
-
`const mappedHeaders = headers ? { ${Object.entries(headerParamsMapping).map(([originalName, camelCaseName]) => `"${originalName}": headers.${camelCaseName}`).join(", ")} } : undefined`,
|
|
772
|
-
/* @__PURE__ */ jsx("br", {}),
|
|
773
|
-
/* @__PURE__ */ jsx("br", {})
|
|
774
|
-
] }),
|
|
775
|
-
parser === "zod" && zodRequestName ? `const requestData = ${zodRequestName}.parse(data)` : requestName && "const requestData = data",
|
|
776
|
-
/* @__PURE__ */ jsx("br", {}),
|
|
851
|
+
pathParamsMapping && /* @__PURE__ */ jsx("br", {}),
|
|
852
|
+
queryParamsMapping && queryParamsName && /* @__PURE__ */ jsxs(Fragment, { children: [`const mappedParams = params ? { ${Object.entries(queryParamsMapping).map(([originalName, camelCaseName]) => `"${originalName}": params.${camelCaseName}`).join(", ")} } : undefined`, /* @__PURE__ */ jsx("br", {})] }),
|
|
853
|
+
headerParamsMapping && headerParamsName && /* @__PURE__ */ jsxs(Fragment, { children: [`const mappedHeaders = headers ? { ${Object.entries(headerParamsMapping).map(([originalName, camelCaseName]) => `"${originalName}": headers.${camelCaseName}`).join(", ")} } : undefined`, /* @__PURE__ */ jsx("br", {})] }),
|
|
854
|
+
requestParser === "zod" && zodRequestName ? `const requestData = ${zodRequestName}.parse(data)` : requestName && "const requestData = data",
|
|
855
|
+
zodQueryParamsName && `const requestParams = ${zodQueryParamsName}.parse(params)`,
|
|
777
856
|
(isFormData || isMultipleContentTypes && hasFormData) && requestName && "const formData = buildFormData(requestData)",
|
|
778
857
|
/* @__PURE__ */ jsx("br", {}),
|
|
779
858
|
isConfigurable ? `const res = await request<${generics.join(", ")}>(${clientParams.toCall()})` : `const res = await client<${generics.join(", ")}>(${clientParams.toCall()})`,
|
|
@@ -784,93 +863,20 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
|
|
|
784
863
|
})] });
|
|
785
864
|
}
|
|
786
865
|
//#endregion
|
|
787
|
-
//#region src/utils.ts
|
|
788
|
-
/**
|
|
789
|
-
* Builds HTTP headers array for a client request.
|
|
790
|
-
* Includes Content-Type (if not default) and spreads header parameters if present.
|
|
791
|
-
*/
|
|
792
|
-
function buildHeaders(contentType, hasHeaderParams) {
|
|
793
|
-
return [contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` : null, hasHeaderParams ? "...headers" : null].filter(Boolean);
|
|
794
|
-
}
|
|
795
|
-
/**
|
|
796
|
-
* Builds TypeScript generic parameters for a client method.
|
|
797
|
-
* Includes response type, error type, and optional request type.
|
|
798
|
-
*/
|
|
799
|
-
function buildGenerics(node, tsResolver) {
|
|
800
|
-
const successNames = resolveSuccessNames(node, tsResolver);
|
|
801
|
-
const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
|
|
802
|
-
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : null;
|
|
803
|
-
const errorNames = node.responses.filter((r) => Number.parseInt(r.statusCode, 10) >= 400).map((r) => tsResolver.resolveResponseStatusName(node, r.statusCode));
|
|
804
|
-
return [
|
|
805
|
-
responseName,
|
|
806
|
-
`ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
|
|
807
|
-
requestName || "unknown"
|
|
808
|
-
].filter(Boolean);
|
|
809
|
-
}
|
|
810
|
-
/**
|
|
811
|
-
* Builds the parameters object for a class-based client method.
|
|
812
|
-
* Includes URL, method, base URL, headers, and request/response data.
|
|
813
|
-
*/
|
|
814
|
-
function buildClassClientParams({ node, path, baseURL, tsResolver, isFormData, isMultipleContentTypes, hasFormData, headers }) {
|
|
815
|
-
const { query: queryParams } = getOperationParameters(node);
|
|
816
|
-
const queryParamsName = queryParams.length > 0 ? tsResolver.resolveQueryParamsName(node, queryParams[0]) : null;
|
|
817
|
-
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : null;
|
|
818
|
-
const responseType = getResponseType(node);
|
|
819
|
-
return createFunctionParams({ config: {
|
|
820
|
-
mode: "object",
|
|
821
|
-
children: {
|
|
822
|
-
requestConfig: { mode: "inlineSpread" },
|
|
823
|
-
method: { value: JSON.stringify(ast.isHttpOperationNode(node) ? node.method.toUpperCase() : "") },
|
|
824
|
-
url: { value: path.template },
|
|
825
|
-
baseURL: baseURL ? { value: JSON.stringify(baseURL) } : null,
|
|
826
|
-
params: queryParamsName ? {} : null,
|
|
827
|
-
data: requestName ? { value: isMultipleContentTypes && hasFormData ? "contentType === 'multipart/form-data' ? formData as FormData : requestData" : isFormData ? "formData as FormData" : "requestData" } : null,
|
|
828
|
-
contentType: isMultipleContentTypes ? {} : null,
|
|
829
|
-
responseType: responseType ? { value: JSON.stringify(responseType) } : null,
|
|
830
|
-
headers: headers.length ? { value: `{ ${headers.join(", ")}, ...requestConfig.headers }` } : null
|
|
831
|
-
}
|
|
832
|
-
} });
|
|
833
|
-
}
|
|
834
|
-
/**
|
|
835
|
-
* Builds the request data parsing line for client methods.
|
|
836
|
-
* Applies Zod validation if configured, otherwise uses data directly.
|
|
837
|
-
*/
|
|
838
|
-
function buildRequestDataLine({ parser, node, zodResolver }) {
|
|
839
|
-
const zodRequestName = zodResolver && parser === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null;
|
|
840
|
-
if (parser === "zod" && zodRequestName) return `const requestData = ${zodRequestName}.parse(data)`;
|
|
841
|
-
if (node.requestBody?.content?.[0]?.schema) return "const requestData = data";
|
|
842
|
-
return "";
|
|
843
|
-
}
|
|
844
|
-
/**
|
|
845
|
-
* Builds the form data conversion line for file upload requests.
|
|
846
|
-
* Returns empty string if not applicable.
|
|
847
|
-
*/
|
|
848
|
-
function buildFormDataLine(isFormData, hasRequest) {
|
|
849
|
-
return isFormData && hasRequest ? "const formData = buildFormData(requestData)" : "";
|
|
850
|
-
}
|
|
851
|
-
/**
|
|
852
|
-
* Builds the return statement for a client method.
|
|
853
|
-
* Applies Zod validation to response data if configured, otherwise returns raw response.
|
|
854
|
-
*/
|
|
855
|
-
function buildReturnStatement({ dataReturnType, parser, node, zodResolver }) {
|
|
856
|
-
const zodResponseName = zodResolver && parser === "zod" ? zodResolver.resolveResponseName?.(node) : null;
|
|
857
|
-
if (dataReturnType === "full" && parser === "zod" && zodResponseName) return `return {...res, data: ${zodResponseName}.parse(res.data)}`;
|
|
858
|
-
if (dataReturnType === "data" && parser === "zod" && zodResponseName) return `return ${zodResponseName}.parse(res.data)`;
|
|
859
|
-
if (dataReturnType === "full" && parser !== "zod") return "return res";
|
|
860
|
-
return "return res.data";
|
|
861
|
-
}
|
|
862
|
-
//#endregion
|
|
863
866
|
//#region src/components/ClassClient.tsx
|
|
864
867
|
const declarationPrinter$1 = functionPrinter({ mode: "declaration" });
|
|
865
868
|
function generateMethod$1({ node, name, tsResolver, zodResolver, baseURL, dataReturnType, parser, paramsType, paramsCasing, pathParamsType }) {
|
|
866
869
|
if (!ast.isHttpOperationNode(node)) return "";
|
|
867
|
-
const path = new URLPath(node.path, { casing: paramsCasing });
|
|
868
870
|
const { defaultContentType: contentType, isMultipleContentTypes, hasFormData } = getContentTypeInfo(node);
|
|
869
871
|
const isFormData = !isMultipleContentTypes && contentType === "multipart/form-data";
|
|
870
872
|
const { header: headerParams } = getOperationParameters(node);
|
|
871
873
|
const headerParamsName = headerParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, headerParams[0]) : null;
|
|
872
874
|
const headers = isMultipleContentTypes ? headerParamsName ? ["...headers"] : [] : buildHeaders(contentType, !!headerParamsName);
|
|
873
|
-
const generics = buildGenerics(node, tsResolver
|
|
875
|
+
const generics = buildGenerics(node, tsResolver, {
|
|
876
|
+
dataReturnType,
|
|
877
|
+
zodResolver,
|
|
878
|
+
parser
|
|
879
|
+
});
|
|
874
880
|
const paramsNode = buildClientParamsNode({
|
|
875
881
|
paramsType,
|
|
876
882
|
paramsCasing,
|
|
@@ -880,15 +886,18 @@ function generateMethod$1({ node, name, tsResolver, zodResolver, baseURL, dataRe
|
|
|
880
886
|
isConfigurable: true
|
|
881
887
|
});
|
|
882
888
|
const paramsSignature = declarationPrinter$1.print(paramsNode) ?? "";
|
|
889
|
+
const { query: queryParams } = getOperationParameters(node);
|
|
890
|
+
const zodQueryParamsName = zodResolver && resolveQueryParamsParser(parser) === "zod" && queryParams.length > 0 ? zodResolver.resolveQueryParamsName?.(node, queryParams[0]) : null;
|
|
883
891
|
const clientParams = buildClassClientParams({
|
|
884
892
|
node,
|
|
885
|
-
path,
|
|
893
|
+
url: Url$1.toTemplateString(node.path, { casing: paramsCasing }),
|
|
886
894
|
baseURL,
|
|
887
895
|
tsResolver,
|
|
888
896
|
isFormData,
|
|
889
897
|
isMultipleContentTypes,
|
|
890
898
|
hasFormData,
|
|
891
|
-
headers
|
|
899
|
+
headers,
|
|
900
|
+
zodQueryParamsName
|
|
892
901
|
});
|
|
893
902
|
const jsdoc = buildJSDoc(buildOperationComments(node, {
|
|
894
903
|
link: "urlPath",
|
|
@@ -900,17 +909,24 @@ function generateMethod$1({ node, name, tsResolver, zodResolver, baseURL, dataRe
|
|
|
900
909
|
node,
|
|
901
910
|
zodResolver
|
|
902
911
|
});
|
|
912
|
+
const queryParamsLine = buildQueryParamsLine({
|
|
913
|
+
parser,
|
|
914
|
+
node,
|
|
915
|
+
zodResolver
|
|
916
|
+
});
|
|
903
917
|
const formDataLine = buildFormDataLine(isFormData || isMultipleContentTypes && hasFormData, !!node.requestBody?.content?.[0]?.schema);
|
|
904
918
|
const returnStatement = buildReturnStatement({
|
|
905
919
|
dataReturnType,
|
|
906
920
|
parser,
|
|
907
921
|
node,
|
|
908
|
-
zodResolver
|
|
922
|
+
zodResolver,
|
|
923
|
+
tsResolver
|
|
909
924
|
});
|
|
910
925
|
return `${jsdoc}async ${name}(${paramsSignature}) {\n${[
|
|
911
|
-
`const { client: request = client, ${isMultipleContentTypes ? `contentType = ${
|
|
926
|
+
`const { client: request = client, ${isMultipleContentTypes ? `contentType = ${stringify(contentType)}, ` : ""}...requestConfig } = mergeConfig(this.#config, config)`,
|
|
912
927
|
"",
|
|
913
928
|
requestDataLine,
|
|
929
|
+
queryParamsLine,
|
|
914
930
|
formDataLine,
|
|
915
931
|
`const res = await request<${generics.join(", ")}>(${clientParams.toCall()})`,
|
|
916
932
|
returnStatement
|
|
@@ -968,8 +984,13 @@ function resolveTypeImportNames$1(node, tsResolver) {
|
|
|
968
984
|
return resolveOperationTypeNames(node, tsResolver, { order: "body-response-first" });
|
|
969
985
|
}
|
|
970
986
|
__name(resolveTypeImportNames$1, "resolveTypeImportNames");
|
|
971
|
-
function resolveZodImportNames$1(node, zodResolver) {
|
|
972
|
-
|
|
987
|
+
function resolveZodImportNames$1(node, zodResolver, parser) {
|
|
988
|
+
const { query: queryParams } = getOperationParameters(node);
|
|
989
|
+
return [
|
|
990
|
+
resolveResponseParser(parser) === "zod" ? zodResolver.resolveResponseName?.(node) : null,
|
|
991
|
+
resolveRequestParser(parser) === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null,
|
|
992
|
+
resolveQueryParamsParser(parser) === "zod" && queryParams.length > 0 ? zodResolver.resolveQueryParamsName?.(node, queryParams[0]) : null
|
|
993
|
+
].filter((n) => Boolean(n));
|
|
973
994
|
}
|
|
974
995
|
__name(resolveZodImportNames$1, "resolveZodImportNames");
|
|
975
996
|
/**
|
|
@@ -979,7 +1000,7 @@ __name(resolveZodImportNames$1, "resolveZodImportNames");
|
|
|
979
1000
|
*/
|
|
980
1001
|
const classClientGenerator = defineGenerator({
|
|
981
1002
|
name: "classClient",
|
|
982
|
-
renderer:
|
|
1003
|
+
renderer: jsxRenderer,
|
|
983
1004
|
operations(nodes, ctx) {
|
|
984
1005
|
const { config, driver, resolver, root } = ctx;
|
|
985
1006
|
const { output, group, dataReturnType, paramsCasing, paramsType, pathParamsType, parser, importPath, sdk } = ctx.options;
|
|
@@ -988,7 +1009,7 @@ const classClientGenerator = defineGenerator({
|
|
|
988
1009
|
if (!pluginTs) return null;
|
|
989
1010
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
990
1011
|
const tsPluginOptions = pluginTs.options;
|
|
991
|
-
const pluginZod = parser
|
|
1012
|
+
const pluginZod = isParserEnabled(parser) ? driver.getPlugin(pluginZodName) : null;
|
|
992
1013
|
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
|
|
993
1014
|
function buildOperationData(node) {
|
|
994
1015
|
const typeFile = tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
|
|
@@ -1013,7 +1034,7 @@ const classClientGenerator = defineGenerator({
|
|
|
1013
1034
|
const controllers = nodes.reduce((acc, operationNode) => {
|
|
1014
1035
|
if (!ast.isHttpOperationNode(operationNode)) return acc;
|
|
1015
1036
|
const tag = operationNode.tags[0];
|
|
1016
|
-
const groupName = tag ? group?.name?.({ group: camelCase(tag) }) ?? resolver.resolveGroupName(tag) : resolver.
|
|
1037
|
+
const groupName = tag ? group?.name?.({ group: camelCase(tag) }) ?? resolver.resolveGroupName(tag) : resolver.resolveClassName("Client");
|
|
1017
1038
|
if (!tag && !group) {
|
|
1018
1039
|
const name = resolver.resolveClassName("ApiClient");
|
|
1019
1040
|
const file = resolver.resolveFile({
|
|
@@ -1080,7 +1101,7 @@ const classClientGenerator = defineGenerator({
|
|
|
1080
1101
|
const zodFilesByPath = /* @__PURE__ */ new Map();
|
|
1081
1102
|
ops.forEach((op) => {
|
|
1082
1103
|
if (!op.zodFile || !zodResolver) return;
|
|
1083
|
-
const names = resolveZodImportNames$1(op.node, zodResolver);
|
|
1104
|
+
const names = resolveZodImportNames$1(op.node, zodResolver, parser);
|
|
1084
1105
|
if (!zodImportsByFile.has(op.zodFile.path)) zodImportsByFile.set(op.zodFile.path, /* @__PURE__ */ new Set());
|
|
1085
1106
|
const imports = zodImportsByFile.get(op.zodFile.path);
|
|
1086
1107
|
names.forEach((n) => {
|
|
@@ -1095,7 +1116,7 @@ const classClientGenerator = defineGenerator({
|
|
|
1095
1116
|
}
|
|
1096
1117
|
const files = controllers.map(({ name, file, operations: ops }) => {
|
|
1097
1118
|
const { typeImportsByFile, typeFilesByPath } = collectTypeImports(ops);
|
|
1098
|
-
const { zodImportsByFile, zodFilesByPath } = parser
|
|
1119
|
+
const { zodImportsByFile, zodFilesByPath } = isParserEnabled(parser) ? collectZodImports(ops) : {
|
|
1099
1120
|
zodImportsByFile: /* @__PURE__ */ new Map(),
|
|
1100
1121
|
zodFilesByPath: /* @__PURE__ */ new Map()
|
|
1101
1122
|
};
|
|
@@ -1166,6 +1187,11 @@ const classClientGenerator = defineGenerator({
|
|
|
1166
1187
|
root: file.path,
|
|
1167
1188
|
path: path.resolve(root, ".kubb/config.ts")
|
|
1168
1189
|
}),
|
|
1190
|
+
parser === "zod" && zodResolver && ops.some((op) => op.node.requestBody?.content?.[0]?.schema != null) && /* @__PURE__ */ jsx(File.Import, {
|
|
1191
|
+
name: ["z"],
|
|
1192
|
+
path: "zod",
|
|
1193
|
+
isTypeOnly: true
|
|
1194
|
+
}),
|
|
1169
1195
|
Array.from(typeImportsByFile.entries()).map(([filePath, importSet]) => {
|
|
1170
1196
|
const typeFile = typeFilesByPath.get(filePath);
|
|
1171
1197
|
if (!typeFile) return null;
|
|
@@ -1178,7 +1204,7 @@ const classClientGenerator = defineGenerator({
|
|
|
1178
1204
|
isTypeOnly: true
|
|
1179
1205
|
}, filePath);
|
|
1180
1206
|
}),
|
|
1181
|
-
parser
|
|
1207
|
+
isParserEnabled(parser) && Array.from(zodImportsByFile.entries()).map(([filePath, importSet]) => {
|
|
1182
1208
|
const zodFile = zodFilesByPath.get(filePath);
|
|
1183
1209
|
if (!zodFile) return null;
|
|
1184
1210
|
const importNames = Array.from(importSet).filter(Boolean);
|
|
@@ -1269,7 +1295,7 @@ const classClientGenerator = defineGenerator({
|
|
|
1269
1295
|
*/
|
|
1270
1296
|
const clientGenerator = defineGenerator({
|
|
1271
1297
|
name: "client",
|
|
1272
|
-
renderer:
|
|
1298
|
+
renderer: jsxRenderer,
|
|
1273
1299
|
operation(node, ctx) {
|
|
1274
1300
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
1275
1301
|
const { config, driver, resolver, root } = ctx;
|
|
@@ -1278,10 +1304,16 @@ const clientGenerator = defineGenerator({
|
|
|
1278
1304
|
const pluginTs = driver.getPlugin(pluginTsName);
|
|
1279
1305
|
if (!pluginTs) return null;
|
|
1280
1306
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
1281
|
-
const pluginZod = parser
|
|
1307
|
+
const pluginZod = isParserEnabled(parser) ? driver.getPlugin(pluginZodName) : null;
|
|
1282
1308
|
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
|
|
1283
1309
|
const importedTypeNames = resolveOperationTypeNames(node, tsResolver, { paramsCasing });
|
|
1284
|
-
const
|
|
1310
|
+
const { query: queryParams } = getOperationParameters(node);
|
|
1311
|
+
const importedZodNames = zodResolver ? [
|
|
1312
|
+
resolveResponseParser(parser) === "zod" ? zodResolver.resolveResponseName?.(node) : null,
|
|
1313
|
+
resolveRequestParser(parser) === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null,
|
|
1314
|
+
resolveQueryParamsParser(parser) === "zod" && queryParams.length > 0 ? zodResolver.resolveQueryParamsName?.(node, queryParams[0]) : null
|
|
1315
|
+
].filter((name) => Boolean(name)) : [];
|
|
1316
|
+
const zodRequestName = zodResolver && parser === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) ?? null : null;
|
|
1285
1317
|
const meta = {
|
|
1286
1318
|
name: resolver.resolveName(node.operationId),
|
|
1287
1319
|
urlName: resolver.resolveUrlName(node),
|
|
@@ -1353,6 +1385,11 @@ const clientGenerator = defineGenerator({
|
|
|
1353
1385
|
root: meta.file.path,
|
|
1354
1386
|
path: path.resolve(root, ".kubb/config.ts")
|
|
1355
1387
|
}),
|
|
1388
|
+
zodRequestName && /* @__PURE__ */ jsx(File.Import, {
|
|
1389
|
+
name: ["z"],
|
|
1390
|
+
path: "zod",
|
|
1391
|
+
isTypeOnly: true
|
|
1392
|
+
}),
|
|
1356
1393
|
meta.fileZod && importedZodNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
|
|
1357
1394
|
name: importedZodNames,
|
|
1358
1395
|
root: meta.file.path,
|
|
@@ -1402,7 +1439,7 @@ const clientGenerator = defineGenerator({
|
|
|
1402
1439
|
*/
|
|
1403
1440
|
const groupedClientGenerator = defineGenerator({
|
|
1404
1441
|
name: "groupedClient",
|
|
1405
|
-
renderer:
|
|
1442
|
+
renderer: jsxRenderer,
|
|
1406
1443
|
operations(nodes, ctx) {
|
|
1407
1444
|
const { config, resolver, root } = ctx;
|
|
1408
1445
|
const { output, group } = ctx.options;
|
|
@@ -1485,29 +1522,7 @@ const groupedClientGenerator = defineGenerator({
|
|
|
1485
1522
|
}
|
|
1486
1523
|
});
|
|
1487
1524
|
//#endregion
|
|
1488
|
-
//#region src/
|
|
1489
|
-
function Operations({ name, nodes }) {
|
|
1490
|
-
const operationsObject = {};
|
|
1491
|
-
nodes.forEach((node) => {
|
|
1492
|
-
if (!ast.isHttpOperationNode(node)) return;
|
|
1493
|
-
operationsObject[node.operationId] = {
|
|
1494
|
-
path: new URLPath(node.path).URL,
|
|
1495
|
-
method: node.method.toLowerCase()
|
|
1496
|
-
};
|
|
1497
|
-
});
|
|
1498
|
-
return /* @__PURE__ */ jsx(File.Source, {
|
|
1499
|
-
name,
|
|
1500
|
-
isExportable: true,
|
|
1501
|
-
isIndexable: true,
|
|
1502
|
-
children: /* @__PURE__ */ jsx(Const, {
|
|
1503
|
-
name,
|
|
1504
|
-
export: true,
|
|
1505
|
-
children: JSON.stringify(operationsObject, void 0, 2)
|
|
1506
|
-
})
|
|
1507
|
-
});
|
|
1508
|
-
}
|
|
1509
|
-
//#endregion
|
|
1510
|
-
//#region src/generators/operationsGenerator.tsx
|
|
1525
|
+
//#region src/generators/operationsGenerator.ts
|
|
1511
1526
|
/**
|
|
1512
1527
|
* Generates an `operations.ts` file that re-exports every operation grouped
|
|
1513
1528
|
* by HTTP method. Enabled when `pluginClient({ operations: true })`. Useful
|
|
@@ -1516,7 +1531,6 @@ function Operations({ name, nodes }) {
|
|
|
1516
1531
|
*/
|
|
1517
1532
|
const operationsGenerator = defineGenerator({
|
|
1518
1533
|
name: "client",
|
|
1519
|
-
renderer: jsxRendererSync,
|
|
1520
1534
|
operations(nodes, ctx) {
|
|
1521
1535
|
const { config, resolver, root } = ctx;
|
|
1522
1536
|
const { output, group } = ctx.options;
|
|
@@ -1529,7 +1543,15 @@ const operationsGenerator = defineGenerator({
|
|
|
1529
1543
|
output,
|
|
1530
1544
|
group: group ?? void 0
|
|
1531
1545
|
});
|
|
1532
|
-
|
|
1546
|
+
const operationsObject = {};
|
|
1547
|
+
for (const node of nodes) {
|
|
1548
|
+
if (!ast.isHttpOperationNode(node)) continue;
|
|
1549
|
+
operationsObject[node.operationId] = {
|
|
1550
|
+
path: Url$1.toPath(node.path),
|
|
1551
|
+
method: node.method.toLowerCase()
|
|
1552
|
+
};
|
|
1553
|
+
}
|
|
1554
|
+
return [ast.factory.createFile({
|
|
1533
1555
|
baseName: file.baseName,
|
|
1534
1556
|
path: file.path,
|
|
1535
1557
|
meta: file.meta,
|
|
@@ -1549,11 +1571,17 @@ const operationsGenerator = defineGenerator({
|
|
|
1549
1571
|
baseName: file.baseName
|
|
1550
1572
|
}
|
|
1551
1573
|
}),
|
|
1552
|
-
|
|
1574
|
+
sources: [ast.factory.createSource({
|
|
1553
1575
|
name,
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1576
|
+
isExportable: true,
|
|
1577
|
+
isIndexable: true,
|
|
1578
|
+
nodes: [ast.factory.createConst({
|
|
1579
|
+
name,
|
|
1580
|
+
export: true,
|
|
1581
|
+
nodes: [ast.factory.createText(JSON.stringify(operationsObject, void 0, 2))]
|
|
1582
|
+
})]
|
|
1583
|
+
})]
|
|
1584
|
+
})];
|
|
1557
1585
|
}
|
|
1558
1586
|
});
|
|
1559
1587
|
//#endregion
|
|
@@ -1561,13 +1589,16 @@ const operationsGenerator = defineGenerator({
|
|
|
1561
1589
|
const declarationPrinter = functionPrinter({ mode: "declaration" });
|
|
1562
1590
|
function generateMethod({ node, name, tsResolver, zodResolver, baseURL, dataReturnType, parser, paramsType, paramsCasing, pathParamsType }) {
|
|
1563
1591
|
if (!ast.isHttpOperationNode(node)) return "";
|
|
1564
|
-
const path = new URLPath(node.path, { casing: paramsCasing });
|
|
1565
1592
|
const { defaultContentType: contentType, isMultipleContentTypes, hasFormData } = getContentTypeInfo(node);
|
|
1566
1593
|
const isFormData = !isMultipleContentTypes && contentType === "multipart/form-data";
|
|
1567
1594
|
const { header: headerParams } = getOperationParameters(node);
|
|
1568
1595
|
const headerParamsName = headerParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, headerParams[0]) : null;
|
|
1569
1596
|
const headers = isMultipleContentTypes ? headerParamsName ? ["...headers"] : [] : buildHeaders(contentType, !!headerParamsName);
|
|
1570
|
-
const generics = buildGenerics(node, tsResolver
|
|
1597
|
+
const generics = buildGenerics(node, tsResolver, {
|
|
1598
|
+
dataReturnType,
|
|
1599
|
+
zodResolver,
|
|
1600
|
+
parser
|
|
1601
|
+
});
|
|
1571
1602
|
const paramsNode = buildClientParamsNode({
|
|
1572
1603
|
paramsType,
|
|
1573
1604
|
paramsCasing,
|
|
@@ -1577,15 +1608,18 @@ function generateMethod({ node, name, tsResolver, zodResolver, baseURL, dataRetu
|
|
|
1577
1608
|
isConfigurable: true
|
|
1578
1609
|
});
|
|
1579
1610
|
const paramsSignature = declarationPrinter.print(paramsNode) ?? "";
|
|
1611
|
+
const { query: queryParams } = getOperationParameters(node);
|
|
1612
|
+
const zodQueryParamsName = zodResolver && resolveQueryParamsParser(parser) === "zod" && queryParams.length > 0 ? zodResolver.resolveQueryParamsName?.(node, queryParams[0]) : null;
|
|
1580
1613
|
const clientParams = buildClassClientParams({
|
|
1581
1614
|
node,
|
|
1582
|
-
path,
|
|
1615
|
+
url: Url$1.toTemplateString(node.path, { casing: paramsCasing }),
|
|
1583
1616
|
baseURL,
|
|
1584
1617
|
tsResolver,
|
|
1585
1618
|
isFormData,
|
|
1586
1619
|
isMultipleContentTypes,
|
|
1587
1620
|
hasFormData,
|
|
1588
|
-
headers
|
|
1621
|
+
headers,
|
|
1622
|
+
zodQueryParamsName
|
|
1589
1623
|
});
|
|
1590
1624
|
const jsdoc = buildJSDoc(buildOperationComments(node, {
|
|
1591
1625
|
link: "urlPath",
|
|
@@ -1597,17 +1631,24 @@ function generateMethod({ node, name, tsResolver, zodResolver, baseURL, dataRetu
|
|
|
1597
1631
|
node,
|
|
1598
1632
|
zodResolver
|
|
1599
1633
|
});
|
|
1634
|
+
const queryParamsLine = buildQueryParamsLine({
|
|
1635
|
+
parser,
|
|
1636
|
+
node,
|
|
1637
|
+
zodResolver
|
|
1638
|
+
});
|
|
1600
1639
|
const formDataLine = buildFormDataLine(isFormData || isMultipleContentTypes && hasFormData, !!node.requestBody?.content?.[0]?.schema);
|
|
1601
1640
|
const returnStatement = buildReturnStatement({
|
|
1602
1641
|
dataReturnType,
|
|
1603
1642
|
parser,
|
|
1604
1643
|
node,
|
|
1605
|
-
zodResolver
|
|
1644
|
+
zodResolver,
|
|
1645
|
+
tsResolver
|
|
1606
1646
|
});
|
|
1607
1647
|
return `${jsdoc} static async ${name}(${paramsSignature}) {\n${[
|
|
1608
|
-
`const { client: request = client, ${isMultipleContentTypes ? `contentType = ${
|
|
1648
|
+
`const { client: request = client, ${isMultipleContentTypes ? `contentType = ${stringify(contentType)}, ` : ""}...requestConfig } = mergeConfig(this.#config, config)`,
|
|
1609
1649
|
"",
|
|
1610
1650
|
requestDataLine,
|
|
1651
|
+
queryParamsLine,
|
|
1611
1652
|
formDataLine,
|
|
1612
1653
|
`const res = await request<${generics.join(", ")}>(${clientParams.toCall()})`,
|
|
1613
1654
|
returnStatement
|
|
@@ -1638,8 +1679,13 @@ function StaticClassClient({ name, isExportable = true, isIndexable = true, oper
|
|
|
1638
1679
|
function resolveTypeImportNames(node, tsResolver) {
|
|
1639
1680
|
return resolveOperationTypeNames(node, tsResolver, { order: "body-response-first" });
|
|
1640
1681
|
}
|
|
1641
|
-
function resolveZodImportNames(node, zodResolver) {
|
|
1642
|
-
|
|
1682
|
+
function resolveZodImportNames(node, zodResolver, parser) {
|
|
1683
|
+
const { query: queryParams } = getOperationParameters(node);
|
|
1684
|
+
return [
|
|
1685
|
+
resolveResponseParser(parser) === "zod" ? zodResolver.resolveResponseName?.(node) : null,
|
|
1686
|
+
resolveRequestParser(parser) === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null,
|
|
1687
|
+
resolveQueryParamsParser(parser) === "zod" && queryParams.length > 0 ? zodResolver.resolveQueryParamsName?.(node, queryParams[0]) : null
|
|
1688
|
+
].filter((n) => Boolean(n));
|
|
1643
1689
|
}
|
|
1644
1690
|
/**
|
|
1645
1691
|
* Built-in `operations` generator for `@kubb/plugin-client` when
|
|
@@ -1649,7 +1695,7 @@ function resolveZodImportNames(node, zodResolver) {
|
|
|
1649
1695
|
*/
|
|
1650
1696
|
const staticClassClientGenerator = defineGenerator({
|
|
1651
1697
|
name: "staticClassClient",
|
|
1652
|
-
renderer:
|
|
1698
|
+
renderer: jsxRenderer,
|
|
1653
1699
|
operations(nodes, ctx) {
|
|
1654
1700
|
const { config, driver, resolver, root } = ctx;
|
|
1655
1701
|
const { output, group, dataReturnType, paramsCasing, paramsType, pathParamsType, parser, importPath } = ctx.options;
|
|
@@ -1658,7 +1704,7 @@ const staticClassClientGenerator = defineGenerator({
|
|
|
1658
1704
|
if (!pluginTs) return null;
|
|
1659
1705
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
1660
1706
|
const tsPluginOptions = pluginTs.options;
|
|
1661
|
-
const pluginZod = parser
|
|
1707
|
+
const pluginZod = isParserEnabled(parser) ? driver.getPlugin(pluginZodName) : null;
|
|
1662
1708
|
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
|
|
1663
1709
|
function buildOperationData(node) {
|
|
1664
1710
|
const typeFile = tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
|
|
@@ -1683,7 +1729,7 @@ const staticClassClientGenerator = defineGenerator({
|
|
|
1683
1729
|
const controllers = nodes.reduce((acc, operationNode) => {
|
|
1684
1730
|
if (!ast.isHttpOperationNode(operationNode)) return acc;
|
|
1685
1731
|
const tag = operationNode.tags[0];
|
|
1686
|
-
const groupName = tag ? group?.name?.({ group: camelCase(tag) }) ?? resolver.resolveGroupName(tag) : resolver.
|
|
1732
|
+
const groupName = tag ? group?.name?.({ group: camelCase(tag) }) ?? resolver.resolveGroupName(tag) : resolver.resolveClassName("Client");
|
|
1687
1733
|
if (!tag && !group) {
|
|
1688
1734
|
const name = resolver.resolveClassName("ApiClient");
|
|
1689
1735
|
const file = resolver.resolveFile({
|
|
@@ -1748,7 +1794,7 @@ const staticClassClientGenerator = defineGenerator({
|
|
|
1748
1794
|
const zodFilesByPath = /* @__PURE__ */ new Map();
|
|
1749
1795
|
ops.forEach((op) => {
|
|
1750
1796
|
if (!op.zodFile || !zodResolver) return;
|
|
1751
|
-
const names = resolveZodImportNames(op.node, zodResolver);
|
|
1797
|
+
const names = resolveZodImportNames(op.node, zodResolver, parser);
|
|
1752
1798
|
if (!zodImportsByFile.has(op.zodFile.path)) zodImportsByFile.set(op.zodFile.path, /* @__PURE__ */ new Set());
|
|
1753
1799
|
const imports = zodImportsByFile.get(op.zodFile.path);
|
|
1754
1800
|
names.forEach((n) => {
|
|
@@ -1763,7 +1809,7 @@ const staticClassClientGenerator = defineGenerator({
|
|
|
1763
1809
|
}
|
|
1764
1810
|
return /* @__PURE__ */ jsx(Fragment, { children: controllers.map(({ name, file, operations: ops }) => {
|
|
1765
1811
|
const { typeImportsByFile, typeFilesByPath } = collectTypeImports(ops);
|
|
1766
|
-
const { zodImportsByFile, zodFilesByPath } = parser
|
|
1812
|
+
const { zodImportsByFile, zodFilesByPath } = isParserEnabled(parser) ? collectZodImports(ops) : {
|
|
1767
1813
|
zodImportsByFile: /* @__PURE__ */ new Map(),
|
|
1768
1814
|
zodFilesByPath: /* @__PURE__ */ new Map()
|
|
1769
1815
|
};
|
|
@@ -1834,6 +1880,11 @@ const staticClassClientGenerator = defineGenerator({
|
|
|
1834
1880
|
root: file.path,
|
|
1835
1881
|
path: path.resolve(root, ".kubb/config.ts")
|
|
1836
1882
|
}),
|
|
1883
|
+
parser === "zod" && zodResolver && ops.some((op) => op.node.requestBody?.content?.[0]?.schema != null) && /* @__PURE__ */ jsx(File.Import, {
|
|
1884
|
+
name: ["z"],
|
|
1885
|
+
path: "zod",
|
|
1886
|
+
isTypeOnly: true
|
|
1887
|
+
}),
|
|
1837
1888
|
Array.from(typeImportsByFile.entries()).map(([filePath, importSet]) => {
|
|
1838
1889
|
const typeFile = typeFilesByPath.get(filePath);
|
|
1839
1890
|
if (!typeFile) return null;
|
|
@@ -1846,7 +1897,7 @@ const staticClassClientGenerator = defineGenerator({
|
|
|
1846
1897
|
isTypeOnly: true
|
|
1847
1898
|
}, filePath);
|
|
1848
1899
|
}),
|
|
1849
|
-
parser
|
|
1900
|
+
isParserEnabled(parser) && Array.from(zodImportsByFile.entries()).map(([filePath, importSet]) => {
|
|
1850
1901
|
const zodFile = zodFilesByPath.get(filePath);
|
|
1851
1902
|
if (!zodFile) return null;
|
|
1852
1903
|
const importNames = Array.from(importSet).filter(Boolean);
|
|
@@ -1885,6 +1936,7 @@ const staticClassClientGenerator = defineGenerator({
|
|
|
1885
1936
|
*
|
|
1886
1937
|
* resolverClient.default('list pets', 'function') // 'listPets'
|
|
1887
1938
|
* resolverClient.resolveClassName('pet') // 'Pet'
|
|
1939
|
+
* resolverClient.resolveGroupName('pet') // 'PetClient'
|
|
1888
1940
|
* resolverClient.resolveUrlName(operationNode) // 'getShowPetByIdUrl'
|
|
1889
1941
|
* ```
|
|
1890
1942
|
*/
|
|
@@ -1892,8 +1944,8 @@ const resolverClient = defineResolver(() => ({
|
|
|
1892
1944
|
name: "default",
|
|
1893
1945
|
pluginName: "plugin-client",
|
|
1894
1946
|
default(name, type) {
|
|
1895
|
-
|
|
1896
|
-
return
|
|
1947
|
+
if (type === "file") return toFilePath(name);
|
|
1948
|
+
return ensureValidVarName(camelCase(name));
|
|
1897
1949
|
},
|
|
1898
1950
|
resolveName(name) {
|
|
1899
1951
|
return this.default(name, "function");
|
|
@@ -1905,7 +1957,7 @@ const resolverClient = defineResolver(() => ({
|
|
|
1905
1957
|
return ensureValidVarName(pascalCase(name));
|
|
1906
1958
|
},
|
|
1907
1959
|
resolveGroupName(name) {
|
|
1908
|
-
return ensureValidVarName(pascalCase(name));
|
|
1960
|
+
return ensureValidVarName(pascalCase(`${name} Client`));
|
|
1909
1961
|
},
|
|
1910
1962
|
resolveClientPropertyName(name) {
|
|
1911
1963
|
return ensureValidVarName(camelCase(name));
|
|
@@ -1950,19 +2002,19 @@ const pluginClientName = "plugin-client";
|
|
|
1950
2002
|
const pluginClient = definePlugin((options) => {
|
|
1951
2003
|
const { output = {
|
|
1952
2004
|
path: "clients",
|
|
1953
|
-
|
|
1954
|
-
}, group, exclude = [], include, override = [], urlType = false, dataReturnType = "data", paramsType = "inline", pathParamsType = paramsType === "object" ? "object" : options.pathParamsType || "inline", operations = false, paramsCasing, clientType = options.sdk ? "class" : "function", parser = false, client = "axios", importPath, bundle = false, sdk, baseURL, resolver: userResolver,
|
|
2005
|
+
barrel: { type: "named" }
|
|
2006
|
+
}, group, exclude = [], include, override = [], urlType = false, dataReturnType = "data", paramsType = "inline", pathParamsType = paramsType === "object" ? "object" : options.pathParamsType || "inline", operations = false, paramsCasing, clientType = options.sdk ? "class" : "function", parser = false, client = "axios", importPath, bundle = false, sdk, baseURL, resolver: userResolver, macros: userMacros } = options;
|
|
1955
2007
|
const resolvedImportPath = importPath ?? (!bundle ? `@kubb/plugin-client/clients/${client}` : void 0);
|
|
1956
2008
|
const selectedGenerators = options.generators ?? [
|
|
1957
2009
|
clientType === "staticClass" ? staticClassClientGenerator : clientType === "class" ? classClientGenerator : clientGenerator,
|
|
1958
2010
|
group && clientType === "function" ? groupedClientGenerator : null,
|
|
1959
2011
|
operations ? operationsGenerator : null
|
|
1960
2012
|
].filter((x) => Boolean(x));
|
|
1961
|
-
const groupConfig = createGroupConfig(group
|
|
2013
|
+
const groupConfig = createGroupConfig(group);
|
|
1962
2014
|
return {
|
|
1963
2015
|
name: pluginClientName,
|
|
1964
2016
|
options,
|
|
1965
|
-
dependencies: [pluginTsName, parser
|
|
2017
|
+
dependencies: [pluginTsName, isParserEnabled(parser) ? pluginZodName : null].filter((dependency) => Boolean(dependency)),
|
|
1966
2018
|
hooks: { "kubb:plugin:setup"(ctx) {
|
|
1967
2019
|
const resolver = userResolver ? {
|
|
1968
2020
|
...resolverClient,
|
|
@@ -1989,7 +2041,7 @@ const pluginClient = definePlugin((options) => {
|
|
|
1989
2041
|
resolver
|
|
1990
2042
|
});
|
|
1991
2043
|
ctx.setResolver(resolver);
|
|
1992
|
-
if (
|
|
2044
|
+
if (userMacros?.length) ctx.setMacros(userMacros);
|
|
1993
2045
|
for (const gen of selectedGenerators) ctx.addGenerator(gen);
|
|
1994
2046
|
const root = path.resolve(ctx.config.root, ctx.config.output.path);
|
|
1995
2047
|
if (!resolvedImportPath?.startsWith(".")) {
|
|
@@ -1997,21 +2049,21 @@ const pluginClient = definePlugin((options) => {
|
|
|
1997
2049
|
ctx.injectFile({
|
|
1998
2050
|
baseName: "client.ts",
|
|
1999
2051
|
path: path.resolve(root, ".kubb/client.ts"),
|
|
2000
|
-
sources: [ast.createSource({
|
|
2052
|
+
sources: [ast.factory.createSource({
|
|
2001
2053
|
name: "client",
|
|
2002
|
-
nodes: isInlineSource ? [ast.createText(client === "fetch" ? source$1 : source)] : [],
|
|
2054
|
+
nodes: isInlineSource ? [ast.factory.createText(client === "fetch" ? source$1 : source)] : [],
|
|
2003
2055
|
isExportable: true,
|
|
2004
2056
|
isIndexable: true
|
|
2005
2057
|
})],
|
|
2006
|
-
exports: !isInlineSource && resolvedImportPath ? [ast.createExport({ path: resolvedImportPath })] : []
|
|
2058
|
+
exports: !isInlineSource && resolvedImportPath ? [ast.factory.createExport({ path: resolvedImportPath })] : []
|
|
2007
2059
|
});
|
|
2008
2060
|
}
|
|
2009
2061
|
ctx.injectFile({
|
|
2010
2062
|
baseName: "config.ts",
|
|
2011
2063
|
path: path.resolve(root, ".kubb/config.ts"),
|
|
2012
|
-
sources: [ast.createSource({
|
|
2064
|
+
sources: [ast.factory.createSource({
|
|
2013
2065
|
name: "config",
|
|
2014
|
-
nodes: [ast.createText(source$2)],
|
|
2066
|
+
nodes: [ast.factory.createText(source$2)],
|
|
2015
2067
|
isExportable: false,
|
|
2016
2068
|
isIndexable: false
|
|
2017
2069
|
})]
|
|
@@ -2020,6 +2072,6 @@ const pluginClient = definePlugin((options) => {
|
|
|
2020
2072
|
};
|
|
2021
2073
|
});
|
|
2022
2074
|
//#endregion
|
|
2023
|
-
export { Client, classClientGenerator, clientGenerator, pluginClient as default, pluginClient, groupedClientGenerator, operationsGenerator, pluginClientName, resolverClient, staticClassClientGenerator };
|
|
2075
|
+
export { Client, classClientGenerator, clientGenerator, pluginClient as default, pluginClient, groupedClientGenerator, isParserEnabled, operationsGenerator, pluginClientName, resolveQueryParamsParser, resolveRequestParser, resolveResponseParser, resolverClient, staticClassClientGenerator };
|
|
2024
2076
|
|
|
2025
2077
|
//# sourceMappingURL=index.js.map
|