@kubb/plugin-client 5.0.0-beta.22 → 5.0.0-beta.25
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/fetch.cjs.map +1 -1
- package/dist/clients/fetch.d.ts +1 -1
- package/dist/clients/fetch.js.map +1 -1
- package/dist/index.cjs +135 -88
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +125 -65
- package/dist/index.js +135 -88
- package/dist/index.js.map +1 -1
- package/dist/templates/clients/fetch.source.cjs +1 -1
- package/dist/templates/clients/fetch.source.js +1 -1
- package/extension.yaml +774 -260
- package/package.json +6 -6
- package/src/clients/fetch.ts +1 -1
- package/src/components/ClassClient.tsx +3 -3
- package/src/components/Client.tsx +17 -17
- package/src/components/StaticClassClient.tsx +3 -3
- package/src/components/Url.tsx +1 -1
- package/src/functionParams.ts +8 -8
- package/src/generators/classClientGenerator.tsx +16 -11
- package/src/generators/clientGenerator.tsx +16 -8
- package/src/generators/groupedClientGenerator.tsx +9 -3
- package/src/generators/operationsGenerator.tsx +7 -1
- package/src/generators/staticClassClientGenerator.tsx +16 -10
- package/src/plugin.ts +24 -11
- package/src/resolvers/resolverClient.ts +10 -4
- package/src/types.ts +66 -53
- package/src/utils.ts +14 -14
package/dist/index.js
CHANGED
|
@@ -251,12 +251,12 @@ var URLPath = class {
|
|
|
251
251
|
get object() {
|
|
252
252
|
return this.toObject();
|
|
253
253
|
}
|
|
254
|
-
/** Returns a map of path parameter names, or `
|
|
254
|
+
/** Returns a map of path parameter names, or `null` when the path has no parameters.
|
|
255
255
|
*
|
|
256
256
|
* @example
|
|
257
257
|
* ```ts
|
|
258
258
|
* new URLPath('/pet/{petId}').params // { petId: 'petId' }
|
|
259
|
-
* new URLPath('/pet').params //
|
|
259
|
+
* new URLPath('/pet').params // null
|
|
260
260
|
* ```
|
|
261
261
|
*/
|
|
262
262
|
get params() {
|
|
@@ -319,7 +319,7 @@ var URLPath = class {
|
|
|
319
319
|
const key = replacer ? replacer(param) : param;
|
|
320
320
|
params[key] = key;
|
|
321
321
|
});
|
|
322
|
-
return Object.keys(params).length > 0 ? params :
|
|
322
|
+
return Object.keys(params).length > 0 ? params : null;
|
|
323
323
|
}
|
|
324
324
|
/** Converts the OpenAPI path to Express-style colon syntax.
|
|
325
325
|
*
|
|
@@ -335,9 +335,9 @@ var URLPath = class {
|
|
|
335
335
|
//#endregion
|
|
336
336
|
//#region ../../internals/shared/src/operation.ts
|
|
337
337
|
function getOperationLink(node, link) {
|
|
338
|
-
if (!link) return;
|
|
339
|
-
if (typeof link === "function") return link(node);
|
|
340
|
-
if (link === "urlPath") return node.path ? `{@link ${new URLPath(node.path).URL}}` :
|
|
338
|
+
if (!link) return null;
|
|
339
|
+
if (typeof link === "function") return link(node) ?? null;
|
|
340
|
+
if (link === "urlPath") return node.path ? `{@link ${new URLPath(node.path).URL}}` : null;
|
|
341
341
|
return `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}`;
|
|
342
342
|
}
|
|
343
343
|
function getContentTypeInfo(node) {
|
|
@@ -352,9 +352,9 @@ function getContentTypeInfo(node) {
|
|
|
352
352
|
};
|
|
353
353
|
}
|
|
354
354
|
function buildRequestConfigType(node, resolver) {
|
|
355
|
-
const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) :
|
|
355
|
+
const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null;
|
|
356
356
|
const { isMultipleContentTypes, contentTypeUnion } = getContentTypeInfo(node);
|
|
357
|
-
return `${requestName ? `Partial<RequestConfig<${requestName}>>` : "Partial<RequestConfig>"} & { ${["client?: Client", isMultipleContentTypes ? `contentType?: ${contentTypeUnion}` :
|
|
357
|
+
return `${requestName ? `Partial<RequestConfig<${requestName}>>` : "Partial<RequestConfig>"} & { ${["client?: Client", isMultipleContentTypes ? `contentType?: ${contentTypeUnion}` : null].filter(Boolean).join("; ")} }`;
|
|
358
358
|
}
|
|
359
359
|
function buildOperationComments(node, options = {}) {
|
|
360
360
|
const { link = "pathTemplate", linkPosition = "afterDeprecated", splitLines = false } = options;
|
|
@@ -384,11 +384,11 @@ function getOperationParameters(node, options = {}) {
|
|
|
384
384
|
}
|
|
385
385
|
function getStatusCodeNumber(statusCode) {
|
|
386
386
|
const code = Number(statusCode);
|
|
387
|
-
return Number.isNaN(code) ?
|
|
387
|
+
return Number.isNaN(code) ? null : code;
|
|
388
388
|
}
|
|
389
389
|
function isErrorStatusCode(statusCode) {
|
|
390
390
|
const code = getStatusCodeNumber(statusCode);
|
|
391
|
-
return code !==
|
|
391
|
+
return code !== null && code >= 400;
|
|
392
392
|
}
|
|
393
393
|
function resolveErrorNames(node, resolver) {
|
|
394
394
|
return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
|
|
@@ -415,7 +415,7 @@ function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
|
415
415
|
...query.map((param) => resolver.resolveQueryParamsName(node, param)),
|
|
416
416
|
...header.map((param) => resolver.resolveHeaderParamsName(node, param))
|
|
417
417
|
];
|
|
418
|
-
const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) :
|
|
418
|
+
const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null, resolver.resolveResponseName(node)];
|
|
419
419
|
const result = (options.order === "body-response-first" ? [
|
|
420
420
|
...bodyAndResponseNames,
|
|
421
421
|
...paramNames,
|
|
@@ -438,7 +438,7 @@ function buildParamsMapping(originalParams, mappedParams) {
|
|
|
438
438
|
mapping[param.name] = mappedName;
|
|
439
439
|
if (param.name !== mappedName) hasChanged = true;
|
|
440
440
|
});
|
|
441
|
-
return hasChanged ? mapping :
|
|
441
|
+
return hasChanged ? mapping : null;
|
|
442
442
|
}
|
|
443
443
|
//#endregion
|
|
444
444
|
//#region src/functionParams.ts
|
|
@@ -451,18 +451,18 @@ function createType(type) {
|
|
|
451
451
|
return type ? ast.createParamsType({
|
|
452
452
|
variant: "reference",
|
|
453
453
|
name: type
|
|
454
|
-
}) :
|
|
454
|
+
}) : null;
|
|
455
455
|
}
|
|
456
456
|
function createDeclarationLeaf(name, spec) {
|
|
457
457
|
if (spec.default !== void 0) return ast.createFunctionParameter({
|
|
458
458
|
name,
|
|
459
|
-
type: createType(spec.type),
|
|
459
|
+
type: createType(spec.type) ?? void 0,
|
|
460
460
|
default: spec.default,
|
|
461
461
|
rest: spec.mode === "inlineSpread"
|
|
462
462
|
});
|
|
463
463
|
return ast.createFunctionParameter({
|
|
464
464
|
name,
|
|
465
|
-
type: createType(spec.type),
|
|
465
|
+
type: createType(spec.type) ?? void 0,
|
|
466
466
|
optional: !!spec.optional,
|
|
467
467
|
rest: spec.mode === "inlineSpread"
|
|
468
468
|
});
|
|
@@ -471,14 +471,14 @@ function createDeclarationParam(name, spec) {
|
|
|
471
471
|
if (isGroup(spec)) return ast.createParameterGroup({
|
|
472
472
|
inline: spec.mode === "inlineSpread",
|
|
473
473
|
default: spec.default,
|
|
474
|
-
properties: Object.entries(spec.children).filter(([, child]) => child
|
|
474
|
+
properties: Object.entries(spec.children).filter(([, child]) => child != null).map(([childName, child]) => createDeclarationLeaf(childName, child))
|
|
475
475
|
});
|
|
476
476
|
return createDeclarationLeaf(name, spec);
|
|
477
477
|
}
|
|
478
478
|
function createCallParam(name, spec) {
|
|
479
479
|
if (isGroup(spec)) return ast.createParameterGroup({
|
|
480
480
|
inline: spec.mode === "inlineSpread",
|
|
481
|
-
properties: Object.entries(spec.children).filter(([, child]) => child
|
|
481
|
+
properties: Object.entries(spec.children).filter(([, child]) => child != null).map(([childName, child]) => ast.createFunctionParameter({
|
|
482
482
|
name: child?.mode === "inlineSpread" ? spec.mode === "inlineSpread" ? child.value ?? childName : `...${child.value ?? childName}` : child?.value ? `${childName}: ${child.value}` : childName,
|
|
483
483
|
rest: spec.mode === "inlineSpread" && child?.mode === "inlineSpread"
|
|
484
484
|
}))
|
|
@@ -493,7 +493,7 @@ function createCallParam(name, spec) {
|
|
|
493
493
|
* Returns utilities to output constructor signatures (`toConstructor()`) or call expressions (`toCall()`).
|
|
494
494
|
*/
|
|
495
495
|
function createFunctionParams(params) {
|
|
496
|
-
const entries = Object.entries(params).filter(([, spec]) => spec
|
|
496
|
+
const entries = Object.entries(params).filter(([, spec]) => spec != null);
|
|
497
497
|
return {
|
|
498
498
|
toConstructor() {
|
|
499
499
|
return declarationPrinter$4.print(ast.createFunctionParameters({ params: entries.map(([name, spec]) => createDeclarationParam(name, spec)) })) ?? "";
|
|
@@ -531,7 +531,7 @@ function Url({ name, isExportable = true, isIndexable = true, baseURL, paramsTyp
|
|
|
531
531
|
const paramsSignature = declarationPrinter$3.print(paramsNode) ?? "";
|
|
532
532
|
const { path: originalPathParams } = getOperationParameters(node);
|
|
533
533
|
const { path: casedPathParams } = getOperationParameters(node, { paramsCasing });
|
|
534
|
-
const pathParamsMapping = paramsCasing ? buildParamsMapping(originalPathParams, casedPathParams) :
|
|
534
|
+
const pathParamsMapping = paramsCasing ? buildParamsMapping(originalPathParams, casedPathParams) : null;
|
|
535
535
|
return /* @__PURE__ */ jsx(File.Source, {
|
|
536
536
|
name,
|
|
537
537
|
isExportable,
|
|
@@ -578,19 +578,19 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
|
|
|
578
578
|
const isFormData = !isMultipleContentTypes && contentType === "multipart/form-data";
|
|
579
579
|
const { path: originalPathParams, query: originalQueryParams, header: originalHeaderParams } = getOperationParameters(node);
|
|
580
580
|
const { path: casedPathParams, query: casedQueryParams, header: casedHeaderParams } = getOperationParameters(node, { paramsCasing });
|
|
581
|
-
const pathParamsMapping = paramsCasing && !urlName ? buildParamsMapping(originalPathParams, casedPathParams) :
|
|
582
|
-
const queryParamsMapping = paramsCasing ? buildParamsMapping(originalQueryParams, casedQueryParams) :
|
|
583
|
-
const headerParamsMapping = paramsCasing ? buildParamsMapping(originalHeaderParams, casedHeaderParams) :
|
|
584
|
-
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) :
|
|
581
|
+
const pathParamsMapping = paramsCasing && !urlName ? buildParamsMapping(originalPathParams, casedPathParams) : null;
|
|
582
|
+
const queryParamsMapping = paramsCasing ? buildParamsMapping(originalQueryParams, casedQueryParams) : null;
|
|
583
|
+
const headerParamsMapping = paramsCasing ? buildParamsMapping(originalHeaderParams, casedHeaderParams) : null;
|
|
584
|
+
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : null;
|
|
585
585
|
const responseName = tsResolver.resolveResponseName(node);
|
|
586
|
-
const queryParamsName = originalQueryParams.length > 0 ? tsResolver.resolveQueryParamsName(node, originalQueryParams[0]) :
|
|
587
|
-
const headerParamsName = originalHeaderParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, originalHeaderParams[0]) :
|
|
588
|
-
const zodResponseName = zodResolver && parser === "zod" ? zodResolver.resolveResponseName?.(node) :
|
|
589
|
-
const zodRequestName = zodResolver && parser === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) :
|
|
586
|
+
const queryParamsName = originalQueryParams.length > 0 ? tsResolver.resolveQueryParamsName(node, originalQueryParams[0]) : null;
|
|
587
|
+
const headerParamsName = originalHeaderParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, originalHeaderParams[0]) : null;
|
|
588
|
+
const zodResponseName = zodResolver && parser === "zod" ? zodResolver.resolveResponseName?.(node) : null;
|
|
589
|
+
const zodRequestName = zodResolver && parser === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null;
|
|
590
590
|
const errorNames = node.responses.filter((r) => {
|
|
591
591
|
return Number.parseInt(r.statusCode, 10) >= 400;
|
|
592
592
|
}).map((r) => tsResolver.resolveResponseStatusName(node, r.statusCode));
|
|
593
|
-
const headers = [!isMultipleContentTypes && contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` :
|
|
593
|
+
const headers = [!isMultipleContentTypes && contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` : null, headerParamsName ? headerParamsMapping ? "...mappedHeaders" : "...headers" : null].filter(Boolean);
|
|
594
594
|
const generics = [
|
|
595
595
|
responseName,
|
|
596
596
|
`ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
|
|
@@ -618,12 +618,12 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
|
|
|
618
618
|
children: {
|
|
619
619
|
method: { value: JSON.stringify(node.method.toUpperCase()) },
|
|
620
620
|
url: { value: urlName ? `${urlName}(${urlParamsCall}).url.toString()` : path.template },
|
|
621
|
-
baseURL: baseURL && !urlName ? { value: `\`${baseURL}\`` } :
|
|
622
|
-
params: queryParamsName ? queryParamsMapping ? { value: "mappedParams" } : {} :
|
|
623
|
-
data: requestName ? { value: isMultipleContentTypes && hasFormData ? "contentType === 'multipart/form-data' ? formData as FormData : requestData" : isFormData ? "formData as FormData" : "requestData" } :
|
|
624
|
-
contentType: isConfigurable && isMultipleContentTypes ? {} :
|
|
625
|
-
requestConfig: isConfigurable ? { mode: "inlineSpread" } :
|
|
626
|
-
headers: headers.length ? { value: isConfigurable ? `{ ${headers.join(", ")}, ...requestConfig.headers }` : `{ ${headers.join(", ")} }` } :
|
|
621
|
+
baseURL: baseURL && !urlName ? { value: `\`${baseURL}\`` } : null,
|
|
622
|
+
params: queryParamsName ? queryParamsMapping ? { value: "mappedParams" } : {} : null,
|
|
623
|
+
data: requestName ? { value: isMultipleContentTypes && hasFormData ? "contentType === 'multipart/form-data' ? formData as FormData : requestData" : isFormData ? "formData as FormData" : "requestData" } : null,
|
|
624
|
+
contentType: isConfigurable && isMultipleContentTypes ? {} : null,
|
|
625
|
+
requestConfig: isConfigurable ? { mode: "inlineSpread" } : null,
|
|
626
|
+
headers: headers.length ? { value: isConfigurable ? `{ ${headers.join(", ")}, ...requestConfig.headers }` : `{ ${headers.join(", ")} }` } : null
|
|
627
627
|
}
|
|
628
628
|
} });
|
|
629
629
|
const childrenElement = children ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -681,7 +681,7 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
|
|
|
681
681
|
* Includes Content-Type (if not default) and spreads header parameters if present.
|
|
682
682
|
*/
|
|
683
683
|
function buildHeaders(contentType, hasHeaderParams) {
|
|
684
|
-
return [contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` :
|
|
684
|
+
return [contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` : null, hasHeaderParams ? "...headers" : null].filter(Boolean);
|
|
685
685
|
}
|
|
686
686
|
/**
|
|
687
687
|
* Builds TypeScript generic parameters for a client method.
|
|
@@ -689,7 +689,7 @@ function buildHeaders(contentType, hasHeaderParams) {
|
|
|
689
689
|
*/
|
|
690
690
|
function buildGenerics(node, tsResolver) {
|
|
691
691
|
const responseName = tsResolver.resolveResponseName(node);
|
|
692
|
-
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) :
|
|
692
|
+
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : null;
|
|
693
693
|
const errorNames = node.responses.filter((r) => Number.parseInt(r.statusCode, 10) >= 400).map((r) => tsResolver.resolveResponseStatusName(node, r.statusCode));
|
|
694
694
|
return [
|
|
695
695
|
responseName,
|
|
@@ -703,19 +703,19 @@ function buildGenerics(node, tsResolver) {
|
|
|
703
703
|
*/
|
|
704
704
|
function buildClassClientParams({ node, path, baseURL, tsResolver, isFormData, isMultipleContentTypes, hasFormData, headers }) {
|
|
705
705
|
const { query: queryParams } = getOperationParameters(node);
|
|
706
|
-
const queryParamsName = queryParams.length > 0 ? tsResolver.resolveQueryParamsName(node, queryParams[0]) :
|
|
707
|
-
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) :
|
|
706
|
+
const queryParamsName = queryParams.length > 0 ? tsResolver.resolveQueryParamsName(node, queryParams[0]) : null;
|
|
707
|
+
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : null;
|
|
708
708
|
return createFunctionParams({ config: {
|
|
709
709
|
mode: "object",
|
|
710
710
|
children: {
|
|
711
711
|
requestConfig: { mode: "inlineSpread" },
|
|
712
712
|
method: { value: JSON.stringify(node.method.toUpperCase()) },
|
|
713
713
|
url: { value: path.template },
|
|
714
|
-
baseURL: baseURL ? { value: JSON.stringify(baseURL) } :
|
|
715
|
-
params: queryParamsName ? {} :
|
|
716
|
-
data: requestName ? { value: isMultipleContentTypes && hasFormData ? "contentType === 'multipart/form-data' ? formData as FormData : requestData" : isFormData ? "formData as FormData" : "requestData" } :
|
|
717
|
-
contentType: isMultipleContentTypes ? {} :
|
|
718
|
-
headers: headers.length ? { value: `{ ${headers.join(", ")}, ...requestConfig.headers }` } :
|
|
714
|
+
baseURL: baseURL ? { value: JSON.stringify(baseURL) } : null,
|
|
715
|
+
params: queryParamsName ? {} : null,
|
|
716
|
+
data: requestName ? { value: isMultipleContentTypes && hasFormData ? "contentType === 'multipart/form-data' ? formData as FormData : requestData" : isFormData ? "formData as FormData" : "requestData" } : null,
|
|
717
|
+
contentType: isMultipleContentTypes ? {} : null,
|
|
718
|
+
headers: headers.length ? { value: `{ ${headers.join(", ")}, ...requestConfig.headers }` } : null
|
|
719
719
|
}
|
|
720
720
|
} });
|
|
721
721
|
}
|
|
@@ -724,7 +724,7 @@ function buildClassClientParams({ node, path, baseURL, tsResolver, isFormData, i
|
|
|
724
724
|
* Applies Zod validation if configured, otherwise uses data directly.
|
|
725
725
|
*/
|
|
726
726
|
function buildRequestDataLine({ parser, node, zodResolver }) {
|
|
727
|
-
const zodRequestName = zodResolver && parser === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) :
|
|
727
|
+
const zodRequestName = zodResolver && parser === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null;
|
|
728
728
|
if (parser === "zod" && zodRequestName) return `const requestData = ${zodRequestName}.parse(data)`;
|
|
729
729
|
if (node.requestBody?.content?.[0]?.schema) return "const requestData = data";
|
|
730
730
|
return "";
|
|
@@ -741,7 +741,7 @@ function buildFormDataLine(isFormData, hasRequest) {
|
|
|
741
741
|
* Applies Zod validation to response data if configured, otherwise returns raw response.
|
|
742
742
|
*/
|
|
743
743
|
function buildReturnStatement({ dataReturnType, parser, node, zodResolver }) {
|
|
744
|
-
const zodResponseName = zodResolver && parser === "zod" ? zodResolver.resolveResponseName?.(node) :
|
|
744
|
+
const zodResponseName = zodResolver && parser === "zod" ? zodResolver.resolveResponseName?.(node) : null;
|
|
745
745
|
if (dataReturnType === "full" && parser === "zod" && zodResponseName) return `return {...res, data: ${zodResponseName}.parse(res.data)}`;
|
|
746
746
|
if (dataReturnType === "data" && parser === "zod" && zodResponseName) return `return ${zodResponseName}.parse(res.data)`;
|
|
747
747
|
if (dataReturnType === "full" && parser === "client") return "return res";
|
|
@@ -755,7 +755,7 @@ function generateMethod$1({ node, name, tsResolver, zodResolver, baseURL, dataRe
|
|
|
755
755
|
const { defaultContentType: contentType, isMultipleContentTypes, hasFormData } = getContentTypeInfo(node);
|
|
756
756
|
const isFormData = !isMultipleContentTypes && contentType === "multipart/form-data";
|
|
757
757
|
const { header: headerParams } = getOperationParameters(node);
|
|
758
|
-
const headerParamsName = headerParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, headerParams[0]) :
|
|
758
|
+
const headerParamsName = headerParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, headerParams[0]) : null;
|
|
759
759
|
const headers = isMultipleContentTypes ? headerParamsName ? ["...headers"] : [] : buildHeaders(contentType, !!headerParamsName);
|
|
760
760
|
const generics = buildGenerics(node, tsResolver);
|
|
761
761
|
const paramsNode = buildClientParamsNode({
|
|
@@ -856,9 +856,14 @@ function resolveTypeImportNames$1(node, tsResolver) {
|
|
|
856
856
|
}
|
|
857
857
|
__name(resolveTypeImportNames$1, "resolveTypeImportNames");
|
|
858
858
|
function resolveZodImportNames$1(node, zodResolver) {
|
|
859
|
-
return [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) :
|
|
859
|
+
return [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null].filter((n) => Boolean(n));
|
|
860
860
|
}
|
|
861
861
|
__name(resolveZodImportNames$1, "resolveZodImportNames");
|
|
862
|
+
/**
|
|
863
|
+
* Built-in `operations` generator for `@kubb/plugin-client` when
|
|
864
|
+
* `clientType: 'class'`. Emits one class per tag, with one instance method
|
|
865
|
+
* per operation and a shared constructor for request configuration.
|
|
866
|
+
*/
|
|
862
867
|
const classClientGenerator = defineGenerator({
|
|
863
868
|
name: "classClient",
|
|
864
869
|
renderer: jsxRendererSync,
|
|
@@ -870,8 +875,8 @@ const classClientGenerator = defineGenerator({
|
|
|
870
875
|
if (!pluginTs) return null;
|
|
871
876
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
872
877
|
const tsPluginOptions = pluginTs.options;
|
|
873
|
-
const pluginZod = parser === "zod" ? driver.getPlugin(pluginZodName) :
|
|
874
|
-
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) :
|
|
878
|
+
const pluginZod = parser === "zod" ? driver.getPlugin(pluginZodName) : null;
|
|
879
|
+
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
|
|
875
880
|
function buildOperationData(node) {
|
|
876
881
|
const typeFile = tsResolver.resolveFile({
|
|
877
882
|
name: node.operationId,
|
|
@@ -891,8 +896,8 @@ const classClientGenerator = defineGenerator({
|
|
|
891
896
|
}, {
|
|
892
897
|
root,
|
|
893
898
|
output: pluginZod.options?.output ?? output,
|
|
894
|
-
group: pluginZod.options?.group
|
|
895
|
-
}) :
|
|
899
|
+
group: pluginZod.options?.group ?? void 0
|
|
900
|
+
}) : null;
|
|
896
901
|
return {
|
|
897
902
|
node,
|
|
898
903
|
name: resolver.resolveName(node.operationId),
|
|
@@ -913,7 +918,7 @@ const classClientGenerator = defineGenerator({
|
|
|
913
918
|
}, {
|
|
914
919
|
root,
|
|
915
920
|
output,
|
|
916
|
-
group
|
|
921
|
+
group: group ?? void 0
|
|
917
922
|
});
|
|
918
923
|
const operationData = buildOperationData(operationNode);
|
|
919
924
|
const previous = acc.find((item) => item.file.path === file.path);
|
|
@@ -935,7 +940,7 @@ const classClientGenerator = defineGenerator({
|
|
|
935
940
|
}, {
|
|
936
941
|
root,
|
|
937
942
|
output,
|
|
938
|
-
group
|
|
943
|
+
group: group ?? void 0
|
|
939
944
|
});
|
|
940
945
|
const operationData = buildOperationData(operationNode);
|
|
941
946
|
const previous = acc.find((item) => item.file.path === file.path);
|
|
@@ -1092,7 +1097,7 @@ const classClientGenerator = defineGenerator({
|
|
|
1092
1097
|
}, {
|
|
1093
1098
|
root,
|
|
1094
1099
|
output,
|
|
1095
|
-
group
|
|
1100
|
+
group: group ?? void 0
|
|
1096
1101
|
});
|
|
1097
1102
|
files.push(/* @__PURE__ */ jsxs(File, {
|
|
1098
1103
|
baseName: sdkFile.baseName,
|
|
@@ -1137,6 +1142,11 @@ const classClientGenerator = defineGenerator({
|
|
|
1137
1142
|
});
|
|
1138
1143
|
//#endregion
|
|
1139
1144
|
//#region src/generators/clientGenerator.tsx
|
|
1145
|
+
/**
|
|
1146
|
+
* Built-in operation generator for `@kubb/plugin-client`. Emits one async
|
|
1147
|
+
* function per OpenAPI operation, plus the matching URL helper. Used when
|
|
1148
|
+
* `clientType: 'function'` (the default).
|
|
1149
|
+
*/
|
|
1140
1150
|
const clientGenerator = defineGenerator({
|
|
1141
1151
|
name: "client",
|
|
1142
1152
|
renderer: jsxRendererSync,
|
|
@@ -1147,10 +1157,10 @@ const clientGenerator = defineGenerator({
|
|
|
1147
1157
|
const pluginTs = driver.getPlugin(pluginTsName);
|
|
1148
1158
|
if (!pluginTs) return null;
|
|
1149
1159
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
1150
|
-
const pluginZod = parser === "zod" ? driver.getPlugin(pluginZodName) :
|
|
1151
|
-
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) :
|
|
1160
|
+
const pluginZod = parser === "zod" ? driver.getPlugin(pluginZodName) : null;
|
|
1161
|
+
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
|
|
1152
1162
|
const importedTypeNames = resolveOperationTypeNames(node, tsResolver, { paramsCasing });
|
|
1153
|
-
const importedZodNames = zodResolver && parser === "zod" ? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) :
|
|
1163
|
+
const importedZodNames = zodResolver && parser === "zod" ? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null].filter((name) => Boolean(name)) : [];
|
|
1154
1164
|
const meta = {
|
|
1155
1165
|
name: resolver.resolveName(node.operationId),
|
|
1156
1166
|
urlName: resolver.resolveUrlName(node),
|
|
@@ -1162,7 +1172,7 @@ const clientGenerator = defineGenerator({
|
|
|
1162
1172
|
}, {
|
|
1163
1173
|
root,
|
|
1164
1174
|
output,
|
|
1165
|
-
group
|
|
1175
|
+
group: group ?? void 0
|
|
1166
1176
|
}),
|
|
1167
1177
|
fileTs: tsResolver.resolveFile({
|
|
1168
1178
|
name: node.operationId,
|
|
@@ -1172,7 +1182,7 @@ const clientGenerator = defineGenerator({
|
|
|
1172
1182
|
}, {
|
|
1173
1183
|
root,
|
|
1174
1184
|
output: pluginTs.options?.output ?? output,
|
|
1175
|
-
group: pluginTs.options?.group
|
|
1185
|
+
group: pluginTs.options?.group ?? void 0
|
|
1176
1186
|
}),
|
|
1177
1187
|
fileZod: zodResolver && pluginZod?.options ? zodResolver.resolveFile({
|
|
1178
1188
|
name: node.operationId,
|
|
@@ -1182,8 +1192,8 @@ const clientGenerator = defineGenerator({
|
|
|
1182
1192
|
}, {
|
|
1183
1193
|
root,
|
|
1184
1194
|
output: pluginZod.options.output ?? output,
|
|
1185
|
-
group: pluginZod.options?.group
|
|
1186
|
-
}) :
|
|
1195
|
+
group: pluginZod.options?.group ?? void 0
|
|
1196
|
+
}) : null
|
|
1187
1197
|
};
|
|
1188
1198
|
const hasFormData = node.requestBody?.content?.some((e) => e.contentType === "multipart/form-data") ?? false;
|
|
1189
1199
|
return /* @__PURE__ */ jsxs(File, {
|
|
@@ -1270,6 +1280,12 @@ const clientGenerator = defineGenerator({
|
|
|
1270
1280
|
});
|
|
1271
1281
|
//#endregion
|
|
1272
1282
|
//#region src/generators/groupedClientGenerator.tsx
|
|
1283
|
+
/**
|
|
1284
|
+
* Emits one aggregate file per tag/group when `group` is configured. Each
|
|
1285
|
+
* file re-exports every client function for that group, so callers can
|
|
1286
|
+
* `import { petController } from './gen/clients'` instead of importing
|
|
1287
|
+
* each operation individually.
|
|
1288
|
+
*/
|
|
1273
1289
|
const groupedClientGenerator = defineGenerator({
|
|
1274
1290
|
name: "groupedClient",
|
|
1275
1291
|
renderer: jsxRendererSync,
|
|
@@ -1279,7 +1295,7 @@ const groupedClientGenerator = defineGenerator({
|
|
|
1279
1295
|
return /* @__PURE__ */ jsx(Fragment, { children: nodes.reduce((acc, operationNode) => {
|
|
1280
1296
|
if (group?.type === "tag") {
|
|
1281
1297
|
const tag = operationNode.tags[0];
|
|
1282
|
-
const name = tag ? group?.name?.({ group: camelCase(tag) }) :
|
|
1298
|
+
const name = tag ? group?.name?.({ group: camelCase(tag) }) : null;
|
|
1283
1299
|
if (!tag || !name) return acc;
|
|
1284
1300
|
const file = resolver.resolveFile({
|
|
1285
1301
|
name,
|
|
@@ -1288,7 +1304,7 @@ const groupedClientGenerator = defineGenerator({
|
|
|
1288
1304
|
}, {
|
|
1289
1305
|
root,
|
|
1290
1306
|
output,
|
|
1291
|
-
group
|
|
1307
|
+
group: group ?? void 0
|
|
1292
1308
|
});
|
|
1293
1309
|
const clientFile = resolver.resolveFile({
|
|
1294
1310
|
name: operationNode.operationId,
|
|
@@ -1298,7 +1314,7 @@ const groupedClientGenerator = defineGenerator({
|
|
|
1298
1314
|
}, {
|
|
1299
1315
|
root,
|
|
1300
1316
|
output,
|
|
1301
|
-
group
|
|
1317
|
+
group: group ?? void 0
|
|
1302
1318
|
});
|
|
1303
1319
|
const client = {
|
|
1304
1320
|
name: resolver.resolveName(operationNode.operationId),
|
|
@@ -1367,6 +1383,12 @@ function Operations({ name, nodes }) {
|
|
|
1367
1383
|
}
|
|
1368
1384
|
//#endregion
|
|
1369
1385
|
//#region src/generators/operationsGenerator.tsx
|
|
1386
|
+
/**
|
|
1387
|
+
* Generates an `operations.ts` file that re-exports every operation grouped
|
|
1388
|
+
* by HTTP method. Enabled when `pluginClient({ operations: true })`. Useful
|
|
1389
|
+
* for building meta-tooling on top of the generated client (route
|
|
1390
|
+
* registries, API explorers).
|
|
1391
|
+
*/
|
|
1370
1392
|
const operationsGenerator = defineGenerator({
|
|
1371
1393
|
name: "client",
|
|
1372
1394
|
renderer: jsxRendererSync,
|
|
@@ -1380,7 +1402,7 @@ const operationsGenerator = defineGenerator({
|
|
|
1380
1402
|
}, {
|
|
1381
1403
|
root,
|
|
1382
1404
|
output,
|
|
1383
|
-
group
|
|
1405
|
+
group: group ?? void 0
|
|
1384
1406
|
});
|
|
1385
1407
|
return /* @__PURE__ */ jsx(File, {
|
|
1386
1408
|
baseName: file.baseName,
|
|
@@ -1409,7 +1431,7 @@ function generateMethod({ node, name, tsResolver, zodResolver, baseURL, dataRetu
|
|
|
1409
1431
|
const { defaultContentType: contentType, isMultipleContentTypes, hasFormData } = getContentTypeInfo(node);
|
|
1410
1432
|
const isFormData = !isMultipleContentTypes && contentType === "multipart/form-data";
|
|
1411
1433
|
const { header: headerParams } = getOperationParameters(node);
|
|
1412
|
-
const headerParamsName = headerParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, headerParams[0]) :
|
|
1434
|
+
const headerParamsName = headerParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, headerParams[0]) : null;
|
|
1413
1435
|
const headers = isMultipleContentTypes ? headerParamsName ? ["...headers"] : [] : buildHeaders(contentType, !!headerParamsName);
|
|
1414
1436
|
const generics = buildGenerics(node, tsResolver);
|
|
1415
1437
|
const paramsNode = buildClientParamsNode({
|
|
@@ -1483,8 +1505,14 @@ function resolveTypeImportNames(node, tsResolver) {
|
|
|
1483
1505
|
return resolveOperationTypeNames(node, tsResolver, { order: "body-response-first" });
|
|
1484
1506
|
}
|
|
1485
1507
|
function resolveZodImportNames(node, zodResolver) {
|
|
1486
|
-
return [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) :
|
|
1508
|
+
return [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null].filter((n) => Boolean(n));
|
|
1487
1509
|
}
|
|
1510
|
+
/**
|
|
1511
|
+
* Built-in `operations` generator for `@kubb/plugin-client` when
|
|
1512
|
+
* `clientType: 'staticClass'`. Emits one class per tag, with a static method
|
|
1513
|
+
* per operation so callers can use `Pet.getPetById(...)` without
|
|
1514
|
+
* instantiating the class.
|
|
1515
|
+
*/
|
|
1488
1516
|
const staticClassClientGenerator = defineGenerator({
|
|
1489
1517
|
name: "staticClassClient",
|
|
1490
1518
|
renderer: jsxRendererSync,
|
|
@@ -1496,8 +1524,8 @@ const staticClassClientGenerator = defineGenerator({
|
|
|
1496
1524
|
if (!pluginTs) return null;
|
|
1497
1525
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
1498
1526
|
const tsPluginOptions = pluginTs.options;
|
|
1499
|
-
const pluginZod = parser === "zod" ? driver.getPlugin(pluginZodName) :
|
|
1500
|
-
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) :
|
|
1527
|
+
const pluginZod = parser === "zod" ? driver.getPlugin(pluginZodName) : null;
|
|
1528
|
+
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
|
|
1501
1529
|
function buildOperationData(node) {
|
|
1502
1530
|
const typeFile = tsResolver.resolveFile({
|
|
1503
1531
|
name: node.operationId,
|
|
@@ -1517,8 +1545,8 @@ const staticClassClientGenerator = defineGenerator({
|
|
|
1517
1545
|
}, {
|
|
1518
1546
|
root,
|
|
1519
1547
|
output: pluginZod.options?.output ?? output,
|
|
1520
|
-
group: pluginZod.options?.group
|
|
1521
|
-
}) :
|
|
1548
|
+
group: pluginZod.options?.group ?? void 0
|
|
1549
|
+
}) : null;
|
|
1522
1550
|
return {
|
|
1523
1551
|
node,
|
|
1524
1552
|
name: resolver.resolveName(node.operationId),
|
|
@@ -1539,7 +1567,7 @@ const staticClassClientGenerator = defineGenerator({
|
|
|
1539
1567
|
}, {
|
|
1540
1568
|
root,
|
|
1541
1569
|
output,
|
|
1542
|
-
group
|
|
1570
|
+
group: group ?? void 0
|
|
1543
1571
|
});
|
|
1544
1572
|
const operationData = buildOperationData(operationNode);
|
|
1545
1573
|
const previous = acc.find((item) => item.file.path === file.path);
|
|
@@ -1560,7 +1588,7 @@ const staticClassClientGenerator = defineGenerator({
|
|
|
1560
1588
|
}, {
|
|
1561
1589
|
root,
|
|
1562
1590
|
output,
|
|
1563
|
-
group
|
|
1591
|
+
group: group ?? void 0
|
|
1564
1592
|
});
|
|
1565
1593
|
const operationData = buildOperationData(operationNode);
|
|
1566
1594
|
const previous = acc.find((item) => item.file.path === file.path);
|
|
@@ -1714,12 +1742,18 @@ const staticClassClientGenerator = defineGenerator({
|
|
|
1714
1742
|
//#endregion
|
|
1715
1743
|
//#region src/resolvers/resolverClient.ts
|
|
1716
1744
|
/**
|
|
1717
|
-
*
|
|
1745
|
+
* Default resolver used by `@kubb/plugin-client`. Decides the names and file
|
|
1746
|
+
* paths for every generated client function or class. Functions and files use
|
|
1747
|
+
* camelCase; classes and tag groups use PascalCase.
|
|
1718
1748
|
*
|
|
1719
|
-
*
|
|
1749
|
+
* @example Resolve client function and class names
|
|
1750
|
+
* ```ts
|
|
1751
|
+
* import { resolverClient } from '@kubb/plugin-client'
|
|
1720
1752
|
*
|
|
1721
|
-
*
|
|
1722
|
-
*
|
|
1753
|
+
* resolverClient.default('list pets', 'function') // 'listPets'
|
|
1754
|
+
* resolverClient.resolveClassName('pet') // 'Pet'
|
|
1755
|
+
* resolverClient.resolveUrlName(operationNode) // 'getShowPetByIdUrl'
|
|
1756
|
+
* ```
|
|
1723
1757
|
*/
|
|
1724
1758
|
const resolverClient = defineResolver(() => ({
|
|
1725
1759
|
name: "default",
|
|
@@ -1750,19 +1784,32 @@ const resolverClient = defineResolver(() => ({
|
|
|
1750
1784
|
//#endregion
|
|
1751
1785
|
//#region src/plugin.ts
|
|
1752
1786
|
/**
|
|
1753
|
-
* Canonical plugin name for `@kubb/plugin-client
|
|
1787
|
+
* Canonical plugin name for `@kubb/plugin-client`. Used for driver lookups and
|
|
1788
|
+
* cross-plugin dependency references.
|
|
1754
1789
|
*/
|
|
1755
1790
|
const pluginClientName = "plugin-client";
|
|
1756
1791
|
/**
|
|
1757
|
-
* Generates
|
|
1758
|
-
*
|
|
1759
|
-
*
|
|
1792
|
+
* Generates one HTTP client function per OpenAPI operation. Each function has
|
|
1793
|
+
* typed path params, query params, body, and response, so callers use the API
|
|
1794
|
+
* like any other typed function. Ships with `axios` and `fetch` runtimes; bring
|
|
1795
|
+
* your own by setting `importPath`.
|
|
1760
1796
|
*
|
|
1761
|
-
* @example
|
|
1797
|
+
* @example
|
|
1762
1798
|
* ```ts
|
|
1763
|
-
* import
|
|
1799
|
+
* import { defineConfig } from 'kubb'
|
|
1800
|
+
* import { pluginTs } from '@kubb/plugin-ts'
|
|
1801
|
+
* import { pluginClient } from '@kubb/plugin-client'
|
|
1802
|
+
*
|
|
1764
1803
|
* export default defineConfig({
|
|
1765
|
-
*
|
|
1804
|
+
* input: { path: './petStore.yaml' },
|
|
1805
|
+
* output: { path: './src/gen' },
|
|
1806
|
+
* plugins: [
|
|
1807
|
+
* pluginTs(),
|
|
1808
|
+
* pluginClient({
|
|
1809
|
+
* output: { path: './clients' },
|
|
1810
|
+
* client: 'fetch',
|
|
1811
|
+
* }),
|
|
1812
|
+
* ],
|
|
1766
1813
|
* })
|
|
1767
1814
|
* ```
|
|
1768
1815
|
*/
|
|
@@ -1774,8 +1821,8 @@ const pluginClient = definePlugin((options) => {
|
|
|
1774
1821
|
const resolvedImportPath = importPath ?? (!bundle ? `@kubb/plugin-client/clients/${client}` : void 0);
|
|
1775
1822
|
const selectedGenerators = options.generators ?? [
|
|
1776
1823
|
clientType === "staticClass" ? staticClassClientGenerator : clientType === "class" ? classClientGenerator : clientGenerator,
|
|
1777
|
-
group && clientType === "function" ? groupedClientGenerator :
|
|
1778
|
-
operations ? operationsGenerator :
|
|
1824
|
+
group && clientType === "function" ? groupedClientGenerator : null,
|
|
1825
|
+
operations ? operationsGenerator : null
|
|
1779
1826
|
].filter((x) => Boolean(x));
|
|
1780
1827
|
const groupConfig = group ? {
|
|
1781
1828
|
...group,
|
|
@@ -1783,11 +1830,11 @@ const pluginClient = definePlugin((options) => {
|
|
|
1783
1830
|
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
1784
1831
|
return `${camelCase(ctx.group)}Controller`;
|
|
1785
1832
|
}
|
|
1786
|
-
} :
|
|
1833
|
+
} : null;
|
|
1787
1834
|
return {
|
|
1788
1835
|
name: pluginClientName,
|
|
1789
1836
|
options,
|
|
1790
|
-
dependencies: [pluginTsName, parser === "zod" ? pluginZodName :
|
|
1837
|
+
dependencies: [pluginTsName, parser === "zod" ? pluginZodName : null].filter((dependency) => Boolean(dependency)),
|
|
1791
1838
|
hooks: { "kubb:plugin:setup"(ctx) {
|
|
1792
1839
|
const resolver = userResolver ? {
|
|
1793
1840
|
...resolverClient,
|