@kubb/plugin-fetch 5.0.0-beta.73 → 5.0.0-beta.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.cjs +179 -120
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +179 -120
- package/dist/index.js.map +1 -1
- package/package.json +21 -21
- package/src/generators/clientGenerator.tsx +2 -1
- package/src/plugin.ts +1 -3
- package/templates/fetch.ts +53 -15
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kubb Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.cjs
CHANGED
|
@@ -34,121 +34,6 @@ let _kubb_plugin_zod = require("@kubb/plugin-zod");
|
|
|
34
34
|
let _kubb_ast_utils = require("@kubb/ast/utils");
|
|
35
35
|
let _kubb_ast_macros = require("@kubb/ast/macros");
|
|
36
36
|
let node_url = require("node:url");
|
|
37
|
-
//#region ../../internals/client/src/builders/parser.ts
|
|
38
|
-
/**
|
|
39
|
-
* Returns `true` when any direction of the parser uses zod (used for dependency checks).
|
|
40
|
-
*/
|
|
41
|
-
function isParserEnabled(parser) {
|
|
42
|
-
if (!parser) return false;
|
|
43
|
-
if (parser === "zod") return true;
|
|
44
|
-
return Boolean(parser.request || parser.response);
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Returns `'zod'` when request body parsing is enabled, `null` otherwise. The string shorthand
|
|
48
|
-
* `'zod'` validates the response only, so it does not enable request parsing.
|
|
49
|
-
*/
|
|
50
|
-
function resolveRequestParser(parser) {
|
|
51
|
-
if (!parser || parser === "zod") return null;
|
|
52
|
-
return parser.request ?? null;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Returns `'zod'` when query-parameters parsing is enabled, `null` otherwise. Only the object form
|
|
56
|
-
* `{ request: 'zod' }` enables it.
|
|
57
|
-
*/
|
|
58
|
-
function resolveQueryParamsParser(parser) {
|
|
59
|
-
if (!parser || parser === "zod") return null;
|
|
60
|
-
return parser.request ?? null;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Returns `'zod'` when response parsing is enabled, `null` otherwise. The string shorthand `'zod'`
|
|
64
|
-
* maps to response parsing.
|
|
65
|
-
*/
|
|
66
|
-
function resolveResponseParser(parser) {
|
|
67
|
-
if (!parser) return null;
|
|
68
|
-
if (parser === "zod") return "zod";
|
|
69
|
-
return parser.response ?? null;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Resolves the zod expression a generated client validates a success response with. Only success
|
|
73
|
-
* (2xx) bodies reach the parse under the throw-on-error contract, so the success-only
|
|
74
|
-
* `<operation>ResponseSchema` is used; error bodies are never zod-parsed.
|
|
75
|
-
*/
|
|
76
|
-
function buildZodResponseParse(node, zodResolver) {
|
|
77
|
-
const name = zodResolver.resolveResponseName?.(node);
|
|
78
|
-
return name ? {
|
|
79
|
-
expression: name,
|
|
80
|
-
importNames: [name]
|
|
81
|
-
} : null;
|
|
82
|
-
}
|
|
83
|
-
//#endregion
|
|
84
|
-
//#region ../../internals/client/src/builders/security.ts
|
|
85
|
-
function serializeAuth(auth) {
|
|
86
|
-
const parts = [`type: '${auth.type}'`];
|
|
87
|
-
if (auth.scheme) parts.push(`scheme: '${auth.scheme}'`);
|
|
88
|
-
if (auth.name) parts.push(`name: '${auth.name}'`);
|
|
89
|
-
if (auth.in) parts.push(`in: '${auth.in}'`);
|
|
90
|
-
return `{ ${parts.join(", ")} }`;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Maps an OpenAPI security scheme to the inline `Auth` object, or `null` when the runtime cannot
|
|
94
|
-
* place it (an unresolved `$ref`, or an `apiKey` without a name or outside `header` / `query` /
|
|
95
|
-
* `cookie`). `http` schemes other than `basic` are treated as bearer.
|
|
96
|
-
*/
|
|
97
|
-
function resolveSecurityScheme(scheme) {
|
|
98
|
-
if (!scheme || "$ref" in scheme) return null;
|
|
99
|
-
if (scheme.type === "apiKey") {
|
|
100
|
-
if (!scheme.name || scheme.in !== "header" && scheme.in !== "query" && scheme.in !== "cookie") return null;
|
|
101
|
-
return {
|
|
102
|
-
type: "apiKey",
|
|
103
|
-
name: scheme.name,
|
|
104
|
-
in: scheme.in
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
if (scheme.type === "http") return {
|
|
108
|
-
type: "http",
|
|
109
|
-
scheme: scheme.scheme?.toLowerCase() === "basic" ? "basic" : "bearer"
|
|
110
|
-
};
|
|
111
|
-
if (scheme.type === "oauth2") return { type: "oauth2" };
|
|
112
|
-
if (scheme.type === "openIdConnect") return { type: "openIdConnect" };
|
|
113
|
-
return null;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Derives the per-operation security metadata from the OpenAPI document. The operation's own
|
|
117
|
-
* `security` overrides the global `security` (an explicit empty array disables auth), and every
|
|
118
|
-
* referenced scheme is resolved from `components.securitySchemes` into a flat, de-duplicated list of
|
|
119
|
-
* `Auth` objects the runtime walks in order.
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* `getOperationSecurity({ document, method: 'POST', path: '/pet' })`
|
|
123
|
-
* `// [{ type: 'http', scheme: 'bearer' }]`
|
|
124
|
-
*/
|
|
125
|
-
function getOperationSecurity({ document, method, path }) {
|
|
126
|
-
if (!document) return void 0;
|
|
127
|
-
const requirements = (document.paths?.[path]?.[method.toLowerCase()])?.security ?? document.security;
|
|
128
|
-
if (!requirements?.length) return void 0;
|
|
129
|
-
const definitions = document.components?.securitySchemes ?? {};
|
|
130
|
-
const security = [];
|
|
131
|
-
const seen = /* @__PURE__ */ new Set();
|
|
132
|
-
for (const requirement of requirements) for (const schemeName of Object.keys(requirement)) {
|
|
133
|
-
if (seen.has(schemeName)) continue;
|
|
134
|
-
seen.add(schemeName);
|
|
135
|
-
const auth = resolveSecurityScheme(definitions[schemeName]);
|
|
136
|
-
if (auth) security.push(auth);
|
|
137
|
-
}
|
|
138
|
-
return security.length ? security : void 0;
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Serializes the per-operation security into the literal emitted on each generated call's `security`
|
|
142
|
-
* field. The runtime `resolveAuth` helper walks it, calling the configured `auth` resolver per entry.
|
|
143
|
-
*
|
|
144
|
-
* @example
|
|
145
|
-
* `buildSecurityMetadata({ security: [{ type: 'http', scheme: 'bearer' }] }) // "[{ type: 'http', scheme: 'bearer' }]"`
|
|
146
|
-
*/
|
|
147
|
-
function buildSecurityMetadata({ security }) {
|
|
148
|
-
if (!security?.length) return null;
|
|
149
|
-
return `[${security.map(serializeAuth).join(", ")}]`;
|
|
150
|
-
}
|
|
151
|
-
//#endregion
|
|
152
37
|
//#region ../../internals/utils/src/casing.ts
|
|
153
38
|
/**
|
|
154
39
|
* Shared implementation for camelCase and PascalCase conversion.
|
|
@@ -374,6 +259,17 @@ var Url = class Url {
|
|
|
374
259
|
return path.replace(/\{([^}]+)\}/g, ":$1");
|
|
375
260
|
}
|
|
376
261
|
/**
|
|
262
|
+
* Rewrites OpenAPI placeholder names while keeping the `{...}` braces, so the generated `url`
|
|
263
|
+
* literal aligns with the grouped `path` request option that the runtime client interpolates by
|
|
264
|
+
* key.
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* Url.toCasedTemplate('/projects/{project_id}', { casing: 'camelcase' }) // '/projects/{projectId}'
|
|
268
|
+
*/
|
|
269
|
+
static toCasedTemplate(path, { casing } = {}) {
|
|
270
|
+
return path.replace(/\{([^}]+)\}/g, (_, name) => `{${transformParam(name, casing)}}`);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
377
273
|
* Converts an OpenAPI/Swagger path to a TypeScript template literal string.
|
|
378
274
|
* `prefix` is prepended inside the literal, `replacer` transforms each parameter name,
|
|
379
275
|
* and `casing` controls parameter identifier casing.
|
|
@@ -483,6 +379,17 @@ function getOperationLink(node, link) {
|
|
|
483
379
|
if (link === "urlPath") return node.path ? `{@link ${Url.toPath(node.path)}}` : null;
|
|
484
380
|
return node.path ? `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}` : null;
|
|
485
381
|
}
|
|
382
|
+
function getContentTypeInfo(node) {
|
|
383
|
+
const contentTypes = node.requestBody?.content?.map((e) => e.contentType) ?? [];
|
|
384
|
+
const isMultipleContentTypes = contentTypes.length > 1;
|
|
385
|
+
return {
|
|
386
|
+
contentTypes,
|
|
387
|
+
isMultipleContentTypes,
|
|
388
|
+
contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(" | ") : "",
|
|
389
|
+
defaultContentType: contentTypes[0] ?? "application/json",
|
|
390
|
+
hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
|
|
391
|
+
};
|
|
392
|
+
}
|
|
486
393
|
function buildOperationComments(node, options = {}) {
|
|
487
394
|
const { link = "pathTemplate", linkPosition = "afterDeprecated", splitLines = false } = options;
|
|
488
395
|
const linkComment = getOperationLink(node, link);
|
|
@@ -509,6 +416,14 @@ function getOperationParameters(node, options = {}) {
|
|
|
509
416
|
cookie: params.filter((param) => param.in === "cookie")
|
|
510
417
|
};
|
|
511
418
|
}
|
|
419
|
+
function getStatusCodeNumber(statusCode) {
|
|
420
|
+
const code = Number(statusCode);
|
|
421
|
+
return Number.isNaN(code) ? null : code;
|
|
422
|
+
}
|
|
423
|
+
function isSuccessStatusCode(statusCode) {
|
|
424
|
+
const code = getStatusCodeNumber(statusCode);
|
|
425
|
+
return code !== null && code >= 200 && code < 300;
|
|
426
|
+
}
|
|
512
427
|
//#endregion
|
|
513
428
|
//#region ../../internals/shared/src/group.ts
|
|
514
429
|
/**
|
|
@@ -541,6 +456,134 @@ function createGroupConfig(group) {
|
|
|
541
456
|
};
|
|
542
457
|
}
|
|
543
458
|
//#endregion
|
|
459
|
+
//#region ../../internals/client/src/builders/parser.ts
|
|
460
|
+
/**
|
|
461
|
+
* Returns `true` when any direction of the parser uses zod (used for dependency checks).
|
|
462
|
+
*/
|
|
463
|
+
function isParserEnabled(parser) {
|
|
464
|
+
if (!parser) return false;
|
|
465
|
+
if (parser === "zod") return true;
|
|
466
|
+
return Boolean(parser.request || parser.response);
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Returns `'zod'` when request body parsing is enabled, `null` otherwise. The string shorthand
|
|
470
|
+
* `'zod'` validates the response only, so it does not enable request parsing.
|
|
471
|
+
*/
|
|
472
|
+
function resolveRequestParser(parser) {
|
|
473
|
+
if (!parser || parser === "zod") return null;
|
|
474
|
+
return parser.request ?? null;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Returns `'zod'` when query-parameters parsing is enabled, `null` otherwise. Only the object form
|
|
478
|
+
* `{ request: 'zod' }` enables it.
|
|
479
|
+
*/
|
|
480
|
+
function resolveQueryParamsParser(parser) {
|
|
481
|
+
if (!parser || parser === "zod") return null;
|
|
482
|
+
return parser.request ?? null;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Returns `'zod'` when response parsing is enabled, `null` otherwise. The string shorthand `'zod'`
|
|
486
|
+
* maps to response parsing.
|
|
487
|
+
*/
|
|
488
|
+
function resolveResponseParser(parser) {
|
|
489
|
+
if (!parser) return null;
|
|
490
|
+
if (parser === "zod") return "zod";
|
|
491
|
+
return parser.response ?? null;
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Resolves the zod expression a generated client validates a success response with. Only success
|
|
495
|
+
* (2xx) bodies reach the parse under the throw-on-error contract, so the success-only
|
|
496
|
+
* `<operation>ResponseSchema` is used; error bodies are never zod-parsed.
|
|
497
|
+
*/
|
|
498
|
+
function buildZodResponseParse(node, zodResolver) {
|
|
499
|
+
const name = zodResolver.resolveResponseName?.(node);
|
|
500
|
+
return name ? {
|
|
501
|
+
expression: name,
|
|
502
|
+
importNames: [name]
|
|
503
|
+
} : null;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Resolves the zod expression a generated client validates an error body with on the non-throw path.
|
|
507
|
+
* Uses the error-only `<operation>ErrorSchema` (the union of non-2xx statuses); returns `null` when the
|
|
508
|
+
* operation documents no error responses with a schema.
|
|
509
|
+
*/
|
|
510
|
+
function buildZodErrorParse(node, zodResolver) {
|
|
511
|
+
if (!node.responses.some((res) => !isSuccessStatusCode(res.statusCode) && res.content?.some((entry) => entry.schema))) return null;
|
|
512
|
+
const name = zodResolver.resolveErrorName?.(node);
|
|
513
|
+
return name ? {
|
|
514
|
+
expression: name,
|
|
515
|
+
importNames: [name]
|
|
516
|
+
} : null;
|
|
517
|
+
}
|
|
518
|
+
//#endregion
|
|
519
|
+
//#region ../../internals/client/src/builders/security.ts
|
|
520
|
+
function serializeAuth(auth) {
|
|
521
|
+
const parts = [`type: '${auth.type}'`];
|
|
522
|
+
if (auth.scheme) parts.push(`scheme: '${auth.scheme}'`);
|
|
523
|
+
if (auth.name) parts.push(`name: '${auth.name}'`);
|
|
524
|
+
if (auth.in) parts.push(`in: '${auth.in}'`);
|
|
525
|
+
return `{ ${parts.join(", ")} }`;
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Maps an OpenAPI security scheme to the inline `Auth` object, or `null` when the runtime cannot
|
|
529
|
+
* place it (an unresolved `$ref`, or an `apiKey` without a name or outside `header` / `query` /
|
|
530
|
+
* `cookie`). `http` schemes other than `basic` are treated as bearer.
|
|
531
|
+
*/
|
|
532
|
+
function resolveSecurityScheme(scheme) {
|
|
533
|
+
if (!scheme || "$ref" in scheme) return null;
|
|
534
|
+
if (scheme.type === "apiKey") {
|
|
535
|
+
if (!scheme.name || scheme.in !== "header" && scheme.in !== "query" && scheme.in !== "cookie") return null;
|
|
536
|
+
return {
|
|
537
|
+
type: "apiKey",
|
|
538
|
+
name: scheme.name,
|
|
539
|
+
in: scheme.in
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
if (scheme.type === "http") return {
|
|
543
|
+
type: "http",
|
|
544
|
+
scheme: scheme.scheme?.toLowerCase() === "basic" ? "basic" : "bearer"
|
|
545
|
+
};
|
|
546
|
+
if (scheme.type === "oauth2") return { type: "oauth2" };
|
|
547
|
+
if (scheme.type === "openIdConnect") return { type: "openIdConnect" };
|
|
548
|
+
return null;
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Derives the per-operation security metadata from the OpenAPI document. The operation's own
|
|
552
|
+
* `security` overrides the global `security` (an explicit empty array disables auth), and every
|
|
553
|
+
* referenced scheme is resolved from `components.securitySchemes` into a flat, de-duplicated list of
|
|
554
|
+
* `Auth` objects the runtime walks in order.
|
|
555
|
+
*
|
|
556
|
+
* @example
|
|
557
|
+
* `getOperationSecurity({ document, method: 'POST', path: '/pet' })`
|
|
558
|
+
* `// [{ type: 'http', scheme: 'bearer' }]`
|
|
559
|
+
*/
|
|
560
|
+
function getOperationSecurity({ document, method, path }) {
|
|
561
|
+
if (!document) return void 0;
|
|
562
|
+
const requirements = (document.paths?.[path]?.[method.toLowerCase()])?.security ?? document.security;
|
|
563
|
+
if (!requirements?.length) return void 0;
|
|
564
|
+
const definitions = document.components?.securitySchemes ?? {};
|
|
565
|
+
const security = [];
|
|
566
|
+
const seen = /* @__PURE__ */ new Set();
|
|
567
|
+
for (const requirement of requirements) for (const schemeName of Object.keys(requirement)) {
|
|
568
|
+
if (seen.has(schemeName)) continue;
|
|
569
|
+
seen.add(schemeName);
|
|
570
|
+
const auth = resolveSecurityScheme(definitions[schemeName]);
|
|
571
|
+
if (auth) security.push(auth);
|
|
572
|
+
}
|
|
573
|
+
return security.length ? security : void 0;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Serializes the per-operation security into the literal emitted on each generated call's `security`
|
|
577
|
+
* field. The runtime `resolveAuth` helper walks it, calling the configured `auth` resolver per entry.
|
|
578
|
+
*
|
|
579
|
+
* @example
|
|
580
|
+
* `buildSecurityMetadata({ security: [{ type: 'http', scheme: 'bearer' }] }) // "[{ type: 'http', scheme: 'bearer' }]"`
|
|
581
|
+
*/
|
|
582
|
+
function buildSecurityMetadata({ security }) {
|
|
583
|
+
if (!security?.length) return null;
|
|
584
|
+
return `[${security.map(serializeAuth).join(", ")}]`;
|
|
585
|
+
}
|
|
586
|
+
//#endregion
|
|
544
587
|
//#region ../../internals/client/src/builders/generics.ts
|
|
545
588
|
/**
|
|
546
589
|
* Builds the `RequestResult` generic arguments for one operation: the plugin-ts per-status responses
|
|
@@ -614,9 +657,13 @@ function buildParserHooks({ node, parser, zodResolver }) {
|
|
|
614
657
|
const responseParse = zodResolver && resolveResponseParser(parser) === "zod" ? buildZodResponseParse(node, zodResolver) : null;
|
|
615
658
|
const response = responseParse ? `(data: unknown) => ${responseParse.expression}.parse(data)` : null;
|
|
616
659
|
if (responseParse) importedZodNames.push(...responseParse.importNames);
|
|
660
|
+
const errorParse = zodResolver && resolveResponseParser(parser) === "zod" ? buildZodErrorParse(node, zodResolver) : null;
|
|
661
|
+
const error = errorParse ? `(data: unknown) => ${errorParse.expression}.parse(data)` : null;
|
|
662
|
+
if (errorParse) importedZodNames.push(...errorParse.importNames);
|
|
617
663
|
return {
|
|
618
664
|
request,
|
|
619
665
|
response,
|
|
666
|
+
error,
|
|
620
667
|
importedZodNames
|
|
621
668
|
};
|
|
622
669
|
}
|
|
@@ -639,13 +686,20 @@ function Operation({ name, node, tsResolver, zodResolver, parser, security, isEx
|
|
|
639
686
|
zodResolver
|
|
640
687
|
});
|
|
641
688
|
const securityLiteral = buildSecurityMetadata({ security });
|
|
642
|
-
const
|
|
689
|
+
const { defaultContentType } = getContentTypeInfo(node);
|
|
690
|
+
const contentTypeLiteral = Boolean(node.requestBody?.content?.[0]?.schema) && defaultContentType !== "application/json" ? `contentType: '${defaultContentType}'` : null;
|
|
691
|
+
const parserEntries = [
|
|
692
|
+
parsers.request ? `request: ${parsers.request}` : null,
|
|
693
|
+
parsers.response ? `response: ${parsers.response}` : null,
|
|
694
|
+
parsers.error ? `error: ${parsers.error}` : null
|
|
695
|
+
].filter(Boolean);
|
|
643
696
|
const parserLiteral = parserEntries.length ? `parser: { ${parserEntries.join(", ")} }` : null;
|
|
644
697
|
const callConfig = `{ ${[
|
|
645
698
|
`method: '${node.method.toUpperCase()}'`,
|
|
646
|
-
`url: '${node.path}'`,
|
|
699
|
+
`url: '${Url.toCasedTemplate(node.path, { casing: "camelcase" })}'`,
|
|
647
700
|
securityLiteral ? `security: ${securityLiteral}` : null,
|
|
648
701
|
parserLiteral,
|
|
702
|
+
contentTypeLiteral,
|
|
649
703
|
"...config"
|
|
650
704
|
].filter(Boolean).join(", ")} }`;
|
|
651
705
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
|
|
@@ -693,7 +747,7 @@ function buildCallConfig({ node, parser, zodResolver, security }) {
|
|
|
693
747
|
const securityLiteral = buildSecurityMetadata({ security });
|
|
694
748
|
return `{ ${[
|
|
695
749
|
`method: '${node.method.toUpperCase()}'`,
|
|
696
|
-
`url: '${node.path}'`,
|
|
750
|
+
`url: '${Url.toCasedTemplate(node.path, { casing: "camelcase" })}'`,
|
|
697
751
|
securityLiteral ? `security: ${securityLiteral}` : null,
|
|
698
752
|
parserLiteral,
|
|
699
753
|
"...config"
|
|
@@ -798,6 +852,7 @@ function resolveZodImportNames(node, zodResolver, parser) {
|
|
|
798
852
|
const { query: queryParams } = getOperationParameters(node, { paramsCasing: "original" });
|
|
799
853
|
return [
|
|
800
854
|
resolveResponseParser(parser) === "zod" ? zodResolver.resolveResponseName?.(node) : null,
|
|
855
|
+
resolveResponseParser(parser) === "zod" ? buildZodErrorParse(node, zodResolver)?.expression ?? null : null,
|
|
801
856
|
resolveRequestParser(parser) === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null,
|
|
802
857
|
resolveQueryParamsParser(parser) === "zod" && queryParams.length > 0 ? zodResolver.resolveQueryParamsName?.(node, queryParams[0]) : null
|
|
803
858
|
].filter((n) => Boolean(n));
|
|
@@ -1092,7 +1147,11 @@ const clientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1092
1147
|
const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) : null;
|
|
1093
1148
|
const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
|
|
1094
1149
|
const importedTypeNames = [tsResolver.resolveRequestConfigName(node), tsResolver.resolveResponsesName(node)];
|
|
1095
|
-
const importedZodNames = zodResolver ? [
|
|
1150
|
+
const importedZodNames = zodResolver ? [
|
|
1151
|
+
resolveResponseParser(parser) === "zod" ? zodResolver.resolveResponseName?.(node) : null,
|
|
1152
|
+
resolveResponseParser(parser) === "zod" ? buildZodErrorParse(node, zodResolver)?.expression ?? null : null,
|
|
1153
|
+
resolveRequestParser(parser) === "zod" && hasRequestBody ? zodResolver.resolveDataName?.(node) : null
|
|
1154
|
+
].filter((name) => Boolean(name)) : [];
|
|
1096
1155
|
const meta = {
|
|
1097
1156
|
name: resolver.resolveName(node.operationId),
|
|
1098
1157
|
file: resolver.resolveFile(operationFileEntry(node, node.operationId), {
|
|
@@ -1240,7 +1299,7 @@ const pluginFetch = (0, _kubb_core.definePlugin)((options) => {
|
|
|
1240
1299
|
ctx.setOptions(resolved);
|
|
1241
1300
|
ctx.setResolver(resolved.resolver);
|
|
1242
1301
|
ctx.setMacros([...defaultMacros, ...options.macros ?? []]);
|
|
1243
|
-
|
|
1302
|
+
ctx.addGenerator(...selectedGenerators);
|
|
1244
1303
|
const root = node_path.default.resolve(ctx.config.root, ctx.config.output.path);
|
|
1245
1304
|
ctx.injectFile({
|
|
1246
1305
|
baseName: "client.ts",
|