@kubb/plugin-fetch 5.0.0-beta.84 → 5.0.0-beta.86
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/index.cjs +148 -104
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -19
- package/dist/index.js +149 -105
- package/dist/index.js.map +1 -1
- package/package.json +6 -7
- package/src/generators/clientGenerator.tsx +11 -9
- package/src/plugin.ts +3 -3
package/dist/index.cjs
CHANGED
|
@@ -71,31 +71,6 @@ function pascalCase(text, { prefix = "", suffix = "" } = {}) {
|
|
|
71
71
|
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
|
|
72
72
|
}
|
|
73
73
|
//#endregion
|
|
74
|
-
//#region ../../internals/utils/src/fs.ts
|
|
75
|
-
/**
|
|
76
|
-
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
77
|
-
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
78
|
-
* every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
|
|
79
|
-
*
|
|
80
|
-
* Empty segments are dropped before joining. They arise when the name starts with a dot
|
|
81
|
-
* followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
|
|
82
|
-
* an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
|
|
83
|
-
* absolute path, letting generated files escape the configured output directory.
|
|
84
|
-
*
|
|
85
|
-
* @example Nested path from a dotted name
|
|
86
|
-
* `toFilePath('pet.petId') // 'pet/petId'`
|
|
87
|
-
*
|
|
88
|
-
* @example PascalCase the final segment
|
|
89
|
-
* `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
|
|
90
|
-
*
|
|
91
|
-
* @example Suffix applied to the final segment only
|
|
92
|
-
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
93
|
-
*/
|
|
94
|
-
function toFilePath(name, caseLast = camelCase) {
|
|
95
|
-
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
96
|
-
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
97
|
-
}
|
|
98
|
-
//#endregion
|
|
99
74
|
//#region ../../internals/utils/src/reserved.ts
|
|
100
75
|
/**
|
|
101
76
|
* JavaScript and Java reserved words.
|
|
@@ -219,6 +194,23 @@ function ensureValidVarName(name) {
|
|
|
219
194
|
return `_${name}`;
|
|
220
195
|
}
|
|
221
196
|
//#endregion
|
|
197
|
+
//#region ../../internals/utils/src/codegen.ts
|
|
198
|
+
/**
|
|
199
|
+
* Builds a JSDoc comment block from an array of lines. Returns `fallback` when there are no
|
|
200
|
+
* comments.
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```ts
|
|
204
|
+
* buildJSDoc(['@type string', '@example hello'])
|
|
205
|
+
* // '/**\n * @type string\n * @example hello\n *\/\n '
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
function buildJSDoc(comments, options = {}) {
|
|
209
|
+
const { indent = " * ", suffix = "\n ", fallback = " " } = options;
|
|
210
|
+
if (comments.length === 0) return fallback;
|
|
211
|
+
return `/**\n${comments.map((c) => `${indent}${c}`).join("\n")}\n */${suffix}`;
|
|
212
|
+
}
|
|
213
|
+
//#endregion
|
|
222
214
|
//#region ../../internals/utils/src/url.ts
|
|
223
215
|
function transformParam(raw, casing) {
|
|
224
216
|
const param = isValidVarName(raw) ? raw : camelCase(raw);
|
|
@@ -367,17 +359,45 @@ function dedupeByCasedName(params) {
|
|
|
367
359
|
return true;
|
|
368
360
|
});
|
|
369
361
|
}
|
|
362
|
+
function buildParamsMapping(originalParams, mappedParams) {
|
|
363
|
+
const mapping = {};
|
|
364
|
+
let hasChanged = false;
|
|
365
|
+
originalParams.forEach((param, i) => {
|
|
366
|
+
const mappedName = mappedParams[i]?.name ?? param.name;
|
|
367
|
+
mapping[param.name] = mappedName;
|
|
368
|
+
if (param.name !== mappedName) hasChanged = true;
|
|
369
|
+
});
|
|
370
|
+
return hasChanged ? mapping : null;
|
|
371
|
+
}
|
|
372
|
+
function toAccess(object, name) {
|
|
373
|
+
return isValidVarName(name) ? `${object}.${name}` : `${object}[${JSON.stringify(name)}]`;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Renders the object-literal expression that renames the camelCased keys of a grouped request
|
|
377
|
+
* option back to the names the OpenAPI document declares, guarded so an omitted optional group
|
|
378
|
+
* stays omitted. Shared by the client and cypress generators, which pass a `buildParamsMapping`
|
|
379
|
+
* result and the source expression to read the keys from.
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* ```ts
|
|
383
|
+
* buildParamsRemapExpression({ source: 'config.query', mapping: { include_deleted: 'includeDeleted' } })
|
|
384
|
+
* // 'config.query ? { "include_deleted": config.query.includeDeleted } : config.query'
|
|
385
|
+
* ```
|
|
386
|
+
*/
|
|
387
|
+
function buildParamsRemapExpression({ source, mapping }) {
|
|
388
|
+
return `${source} ? { ${Object.entries(mapping).map(([originalName, casedName]) => `${JSON.stringify(originalName)}: ${toAccess(source, casedName)}`).join(", ")} } : ${source}`;
|
|
389
|
+
}
|
|
370
390
|
//#endregion
|
|
371
391
|
//#region ../../internals/shared/src/operation.ts
|
|
372
392
|
/**
|
|
373
393
|
* Builds the `ResolverFileParams` every operation generator passes to
|
|
374
|
-
* `resolver.
|
|
394
|
+
* `resolver.file`: a file named `name`, tagged by the operation's first
|
|
375
395
|
* tag (or `'default'`), at the operation's path. Centralizes the entry object
|
|
376
396
|
* that was repeated at dozens of call sites across the client and query plugins.
|
|
377
397
|
*
|
|
378
398
|
* @example
|
|
379
399
|
* ```ts
|
|
380
|
-
* resolver.
|
|
400
|
+
* resolver.file(operationFileEntry(node, node.operationId), { root, output, group })
|
|
381
401
|
* ```
|
|
382
402
|
*/
|
|
383
403
|
function operationFileEntry(node, name, extname = ".ts") {
|
|
@@ -600,7 +620,7 @@ function resolveResponseValidator(validator) {
|
|
|
600
620
|
* `<operation>ResponseSchema` is used; error bodies are never zod-parsed.
|
|
601
621
|
*/
|
|
602
622
|
function buildZodResponseParse(node, zodResolver) {
|
|
603
|
-
const name = zodResolver.
|
|
623
|
+
const name = zodResolver.response.response(node);
|
|
604
624
|
return name ? {
|
|
605
625
|
expression: name,
|
|
606
626
|
importNames: [name]
|
|
@@ -613,7 +633,7 @@ function buildZodResponseParse(node, zodResolver) {
|
|
|
613
633
|
*/
|
|
614
634
|
function buildZodErrorParse(node, zodResolver) {
|
|
615
635
|
if (!node.responses.some((res) => !isSuccessStatusCode(res.statusCode) && res.content?.some((entry) => entry.schema))) return null;
|
|
616
|
-
const name = zodResolver.
|
|
636
|
+
const name = zodResolver.response.error?.(node);
|
|
617
637
|
return name ? {
|
|
618
638
|
expression: name,
|
|
619
639
|
importNames: [name]
|
|
@@ -688,6 +708,38 @@ function buildSecurityMetadata({ security }) {
|
|
|
688
708
|
return `[${security.map(serializeAuth).join(", ")}]`;
|
|
689
709
|
}
|
|
690
710
|
//#endregion
|
|
711
|
+
//#region ../../internals/client/src/builders/paramsRemap.ts
|
|
712
|
+
/**
|
|
713
|
+
* Builds the call-config entries that rename the camelCased `query` and `headers` keys back to the
|
|
714
|
+
* names the OpenAPI document declares, so the wire format follows the spec while the generated
|
|
715
|
+
* types keep camelCase keys. Returns an empty array when no name changes. Path parameters need no
|
|
716
|
+
* remap because the URL template placeholders are renamed in sync with the `path` keys. Emit the
|
|
717
|
+
* entries after the `...config` spread so they override the camelCased groups the caller passes in.
|
|
718
|
+
*
|
|
719
|
+
* @example
|
|
720
|
+
* ```ts
|
|
721
|
+
* // a query param named include_deleted in the spec
|
|
722
|
+
* buildParamsRemap({ node }) // ['query: config.query ? { "include_deleted": config.query.includeDeleted } : config.query']
|
|
723
|
+
* ```
|
|
724
|
+
*/
|
|
725
|
+
function buildParamsRemap({ node }) {
|
|
726
|
+
if (!kubb_kit.ast.isHttpOperationNode(node)) return [];
|
|
727
|
+
const original = getOperationParameters(node, { paramsCasing: "original" });
|
|
728
|
+
const cased = getOperationParameters(node);
|
|
729
|
+
const queryMapping = buildParamsMapping(original.query, cased.query);
|
|
730
|
+
const headerMapping = buildParamsMapping(original.header, cased.header);
|
|
731
|
+
const entries = [];
|
|
732
|
+
if (queryMapping) entries.push(`query: ${buildParamsRemapExpression({
|
|
733
|
+
source: "config.query",
|
|
734
|
+
mapping: queryMapping
|
|
735
|
+
})}`);
|
|
736
|
+
if (headerMapping) entries.push(`headers: ${buildParamsRemapExpression({
|
|
737
|
+
source: "config.headers",
|
|
738
|
+
mapping: headerMapping
|
|
739
|
+
})}`);
|
|
740
|
+
return entries;
|
|
741
|
+
}
|
|
742
|
+
//#endregion
|
|
691
743
|
//#region ../../internals/client/src/builders/generics.ts
|
|
692
744
|
/**
|
|
693
745
|
* Builds the `RequestResult` generic arguments for one operation: the plugin-ts per-status responses
|
|
@@ -698,7 +750,7 @@ function buildSecurityMetadata({ security }) {
|
|
|
698
750
|
* `buildRequestResultGenerics({ node, tsResolver }) // 'AddPetResponses, ThrowOnError'`
|
|
699
751
|
*/
|
|
700
752
|
function buildRequestResultGenerics({ node, tsResolver }) {
|
|
701
|
-
return `${tsResolver.
|
|
753
|
+
return `${tsResolver.response.responses(node)}, ThrowOnError`;
|
|
702
754
|
}
|
|
703
755
|
//#endregion
|
|
704
756
|
//#region ../../internals/client/src/builders/returnStatement.ts
|
|
@@ -721,41 +773,42 @@ function buildReturnStatement({ node, tsResolver, callConfig }) {
|
|
|
721
773
|
const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
722
774
|
/**
|
|
723
775
|
* Builds the grouped-options signature for one operation: a single `options` object whose `TData`
|
|
724
|
-
* is the plugin-ts `<Name>
|
|
776
|
+
* is the plugin-ts `<Name>Options` (carrying a literal `url`), and a `RequestResult` return type
|
|
725
777
|
* keyed to the plugin-ts per-status responses record. There are no positional arguments.
|
|
726
778
|
*
|
|
727
|
-
* The generated file imports `<Name>
|
|
779
|
+
* The generated file imports `<Name>Options` and `<Name>Responses` and uses them directly, so no
|
|
728
780
|
* per-operation input type has to be emitted.
|
|
729
781
|
*/
|
|
730
782
|
function buildGroupedOptionsSignature({ node, tsResolver }) {
|
|
731
|
-
const
|
|
732
|
-
const responsesName = tsResolver.
|
|
783
|
+
const optionsName = tsResolver.response.options(node);
|
|
784
|
+
const responsesName = tsResolver.response.responses(node);
|
|
733
785
|
const resultGenerics = buildRequestResultGenerics({
|
|
734
786
|
node,
|
|
735
787
|
tsResolver
|
|
736
788
|
});
|
|
737
789
|
const { isOptional } = getRequestGroupOptionality(node);
|
|
738
790
|
return {
|
|
739
|
-
dataTypeName:
|
|
791
|
+
dataTypeName: optionsName,
|
|
740
792
|
paramsSignature: declarationPrinter.print((0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
|
|
741
793
|
name: "options",
|
|
742
|
-
type: `Options<${
|
|
794
|
+
type: `Options<${optionsName}, ThrowOnError>`,
|
|
743
795
|
...isOptional ? { default: "{}" } : {}
|
|
744
796
|
})] })) ?? "",
|
|
745
797
|
returnType: `Promise<RequestResult<${resultGenerics}>>`,
|
|
746
798
|
generics: ["ThrowOnError extends boolean = true"],
|
|
747
|
-
importedTypeNames: [
|
|
799
|
+
importedTypeNames: [optionsName, responsesName]
|
|
748
800
|
};
|
|
749
801
|
}
|
|
750
802
|
//#endregion
|
|
751
803
|
//#region ../../internals/client/src/builders/styles.ts
|
|
752
804
|
/**
|
|
753
|
-
* Renders a parameter name as an object-literal key,
|
|
754
|
-
*
|
|
805
|
+
* Renders a parameter name as an object-literal key, quoted when it is not a bare identifier.
|
|
806
|
+
* Path keys are camelCased to match the URL template placeholders. Query, header, and cookie keys
|
|
807
|
+
* keep the spec name, matching the remapped keys the runtime serializes.
|
|
755
808
|
*/
|
|
756
|
-
function toKey(name) {
|
|
757
|
-
const
|
|
758
|
-
return isValidVarName(
|
|
809
|
+
function toKey(name, location) {
|
|
810
|
+
const key = location === "path" ? camelCase(name) : name;
|
|
811
|
+
return isValidVarName(key) ? key : JSON.stringify(key);
|
|
759
812
|
}
|
|
760
813
|
/**
|
|
761
814
|
* Serializes one parameter's metadata into a `{ style, explode }` literal, or `null` when the
|
|
@@ -769,8 +822,9 @@ function serializeParameter(parameter) {
|
|
|
769
822
|
return parts.length > 0 ? `{ ${parts.join(", ")} }` : null;
|
|
770
823
|
}
|
|
771
824
|
/**
|
|
772
|
-
* Builds the per-operation `styles` literal from the operation's parameters, grouped by location
|
|
773
|
-
* keyed by the camelCased
|
|
825
|
+
* Builds the per-operation `styles` literal from the operation's parameters, grouped by location.
|
|
826
|
+
* Path entries are keyed by the camelCased name to match the URL template placeholders; query,
|
|
827
|
+
* header, and cookie entries keep the spec name to match the keys the runtime serializes.
|
|
774
828
|
* Only parameters whose source defines `style` or `explode` are emitted, so calls without
|
|
775
829
|
* serialization metadata keep the runtime defaults and existing output is unchanged. Returns `null`
|
|
776
830
|
* when no parameter carries metadata.
|
|
@@ -792,7 +846,7 @@ function buildStyles({ node }) {
|
|
|
792
846
|
for (const parameter of node.parameters) {
|
|
793
847
|
const literal = serializeParameter(parameter);
|
|
794
848
|
if (!literal) continue;
|
|
795
|
-
groups[parameter.in].push(`${toKey(parameter.name)}: ${literal}`);
|
|
849
|
+
groups[parameter.in].push(`${toKey(parameter.name, parameter.in)}: ${literal}`);
|
|
796
850
|
}
|
|
797
851
|
const locations = Object.keys(groups).filter((location) => groups[location].length > 0);
|
|
798
852
|
if (locations.length === 0) return null;
|
|
@@ -808,7 +862,7 @@ function buildStyles({ node }) {
|
|
|
808
862
|
function buildValidatorHooks({ node, validator, zodResolver }) {
|
|
809
863
|
const importedZodNames = [];
|
|
810
864
|
const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
|
|
811
|
-
const zodRequestName = zodResolver && resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.
|
|
865
|
+
const zodRequestName = zodResolver && resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.response.body(node) : null;
|
|
812
866
|
const request = zodRequestName ?? null;
|
|
813
867
|
if (zodRequestName) importedZodNames.push(zodRequestName);
|
|
814
868
|
const responseParse = zodResolver && resolveResponseValidator(validator) === "zod" ? buildZodResponseParse(node, zodResolver) : null;
|
|
@@ -865,9 +919,10 @@ function Operation({ name, node, tsResolver, zodResolver, validator, security, i
|
|
|
865
919
|
validatorLiteral,
|
|
866
920
|
contentTypeLiteral,
|
|
867
921
|
responseTypeLiteral,
|
|
868
|
-
"...config"
|
|
922
|
+
"...config",
|
|
923
|
+
...buildParamsRemap({ node })
|
|
869
924
|
].filter(Boolean).join(", ")} }`;
|
|
870
|
-
const eventType = `SuccessOf<${tsResolver.
|
|
925
|
+
const eventType = `SuccessOf<${tsResolver.response.responses(node)}>`;
|
|
871
926
|
const returnType = eventStream ? `Promise<EventStreamResult<${eventType}>>` : signature.returnType;
|
|
872
927
|
const returnStatement = eventStream ? `return toEventStream<${eventType}>(request(${callConfig}))` : buildReturnStatement({
|
|
873
928
|
node,
|
|
@@ -918,7 +973,8 @@ function buildCallConfig({ node, validator, zodResolver, security }) {
|
|
|
918
973
|
`url: '${Url.toCasedTemplate(node.path, { casing: "camelcase" })}'`,
|
|
919
974
|
securityLiteral ? `security: ${securityLiteral}` : null,
|
|
920
975
|
validatorLiteral,
|
|
921
|
-
"...config"
|
|
976
|
+
"...config",
|
|
977
|
+
...buildParamsRemap({ node })
|
|
922
978
|
].filter(Boolean).join(", ")} }`;
|
|
923
979
|
}
|
|
924
980
|
/**
|
|
@@ -944,7 +1000,7 @@ function buildSdkMethod({ node, name, tsResolver, zodResolver, validator, securi
|
|
|
944
1000
|
})
|
|
945
1001
|
});
|
|
946
1002
|
const generics = signature.generics.length ? `<${signature.generics.join(", ")}>` : "";
|
|
947
|
-
const jsdoc =
|
|
1003
|
+
const jsdoc = buildJSDoc(buildOperationComments(node, {
|
|
948
1004
|
link: "urlPath",
|
|
949
1005
|
linkPosition: "beforeDeprecated",
|
|
950
1006
|
splitLines: true
|
|
@@ -1014,15 +1070,15 @@ function SdkFacade({ name, isExportable = true, isIndexable = true, members, chi
|
|
|
1014
1070
|
//#endregion
|
|
1015
1071
|
//#region ../../internals/client/src/generators/sdkGenerator.tsx
|
|
1016
1072
|
function resolveTypeImportNames(node, tsResolver) {
|
|
1017
|
-
return [tsResolver.
|
|
1073
|
+
return [tsResolver.response.options(node), tsResolver.response.responses(node)];
|
|
1018
1074
|
}
|
|
1019
1075
|
function resolveZodImportNames(node, zodResolver, validator) {
|
|
1020
1076
|
const { query: queryParams } = getOperationParameters(node, { paramsCasing: "original" });
|
|
1021
1077
|
return [
|
|
1022
|
-
resolveResponseValidator(validator) === "zod" ? zodResolver.
|
|
1078
|
+
resolveResponseValidator(validator) === "zod" ? zodResolver.response.response(node) : null,
|
|
1023
1079
|
resolveResponseValidator(validator) === "zod" ? buildZodErrorParse(node, zodResolver)?.expression ?? null : null,
|
|
1024
|
-
resolveRequestValidator(validator) === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.
|
|
1025
|
-
resolveQueryParamsValidator(validator) === "zod" && queryParams.length > 0 ? zodResolver.
|
|
1080
|
+
resolveRequestValidator(validator) === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.response.body(node) : null,
|
|
1081
|
+
resolveQueryParamsValidator(validator) === "zod" && queryParams.length > 0 ? zodResolver.param.query(node, queryParams[0]) : null
|
|
1026
1082
|
].filter((n) => Boolean(n));
|
|
1027
1083
|
}
|
|
1028
1084
|
/**
|
|
@@ -1039,12 +1095,14 @@ function buildControllers(nodes, ctx) {
|
|
|
1039
1095
|
const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) : null;
|
|
1040
1096
|
const document = ctx.adapter.document;
|
|
1041
1097
|
function buildOperationData(node) {
|
|
1042
|
-
const typeFile = tsResolver.
|
|
1098
|
+
const typeFile = tsResolver.file({
|
|
1099
|
+
...operationFileEntry(node, node.operationId),
|
|
1043
1100
|
root,
|
|
1044
1101
|
output: tsPluginOptions?.output ?? output,
|
|
1045
1102
|
group: tsPluginOptions?.group
|
|
1046
1103
|
});
|
|
1047
|
-
const zodFile = zodResolver && pluginZod?.options ? zodResolver.
|
|
1104
|
+
const zodFile = zodResolver && pluginZod?.options ? zodResolver.file({
|
|
1105
|
+
...operationFileEntry(node, node.operationId),
|
|
1048
1106
|
root,
|
|
1049
1107
|
output: pluginZod.options?.output ?? output,
|
|
1050
1108
|
group: pluginZod.options?.group ?? void 0
|
|
@@ -1056,7 +1114,7 @@ function buildControllers(nodes, ctx) {
|
|
|
1056
1114
|
}) : void 0;
|
|
1057
1115
|
return {
|
|
1058
1116
|
node,
|
|
1059
|
-
name: resolver.
|
|
1117
|
+
name: resolver.name(node.operationId),
|
|
1060
1118
|
tsResolver,
|
|
1061
1119
|
zodResolver,
|
|
1062
1120
|
typeFile,
|
|
@@ -1067,12 +1125,11 @@ function buildControllers(nodes, ctx) {
|
|
|
1067
1125
|
return nodes.reduce((acc, operationNode) => {
|
|
1068
1126
|
if (!kubb_kit.ast.isHttpOperationNode(operationNode)) return acc;
|
|
1069
1127
|
const tag = operationNode.tags[0];
|
|
1070
|
-
const name = tag ? group?.name?.({ group: camelCase(tag) }) ?? resolver.
|
|
1071
|
-
const file = resolver.
|
|
1128
|
+
const name = tag ? group?.name?.({ group: camelCase(tag) }) ?? resolver.groupName(tag) : resolver.className("ApiClient");
|
|
1129
|
+
const file = resolver.file({
|
|
1072
1130
|
name,
|
|
1073
1131
|
extname: ".ts",
|
|
1074
|
-
tag
|
|
1075
|
-
}, {
|
|
1132
|
+
tag,
|
|
1076
1133
|
root,
|
|
1077
1134
|
output,
|
|
1078
1135
|
group: group ?? void 0
|
|
@@ -1126,7 +1183,7 @@ function createSdkGenerator() {
|
|
|
1126
1183
|
if (!ctx.driver.getPlugin(_kubb_plugin_ts.pluginTsName) || !sdk) return null;
|
|
1127
1184
|
const controllers = buildControllers(nodes, ctx);
|
|
1128
1185
|
const clientPath = node_path.default.resolve(root, ".kubb/client.ts");
|
|
1129
|
-
const banner = (file) => resolver.
|
|
1186
|
+
const banner = (file) => resolver.default.banner(ctx.meta, {
|
|
1130
1187
|
output,
|
|
1131
1188
|
config,
|
|
1132
1189
|
file: {
|
|
@@ -1134,7 +1191,7 @@ function createSdkGenerator() {
|
|
|
1134
1191
|
baseName: file.baseName
|
|
1135
1192
|
}
|
|
1136
1193
|
});
|
|
1137
|
-
const footer = (file) => resolver.
|
|
1194
|
+
const footer = (file) => resolver.default.footer(ctx.meta, {
|
|
1138
1195
|
output,
|
|
1139
1196
|
config,
|
|
1140
1197
|
file: {
|
|
@@ -1201,28 +1258,26 @@ function createSdkGenerator() {
|
|
|
1201
1258
|
]
|
|
1202
1259
|
}, file.path);
|
|
1203
1260
|
};
|
|
1204
|
-
if (sdk.mode === "flat") return renderClassFile(resolver.
|
|
1261
|
+
if (sdk.mode === "flat") return renderClassFile(resolver.className(sdk.name ?? "sdk"), resolver.file({
|
|
1205
1262
|
name: sdk.name ?? "sdk",
|
|
1206
|
-
extname: ".ts"
|
|
1207
|
-
}, {
|
|
1263
|
+
extname: ".ts",
|
|
1208
1264
|
root,
|
|
1209
1265
|
output,
|
|
1210
1266
|
group: group ?? void 0
|
|
1211
1267
|
}), controllers.flatMap((controller) => controller.operations));
|
|
1212
1268
|
const classFiles = controllers.map(({ name, file, operations: ops }) => renderClassFile(name, file, ops));
|
|
1213
1269
|
if (!sdk.name) return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx_jsx_runtime.Fragment, { children: classFiles });
|
|
1214
|
-
const sdkFile = resolver.
|
|
1270
|
+
const sdkFile = resolver.file({
|
|
1215
1271
|
name: sdk.name,
|
|
1216
|
-
extname: ".ts"
|
|
1217
|
-
}, {
|
|
1272
|
+
extname: ".ts",
|
|
1218
1273
|
root,
|
|
1219
1274
|
output,
|
|
1220
1275
|
group: group ?? void 0
|
|
1221
1276
|
});
|
|
1222
|
-
const facadeName = resolver.
|
|
1277
|
+
const facadeName = resolver.className(sdk.name);
|
|
1223
1278
|
const members = controllers.map(({ name, tag }) => ({
|
|
1224
1279
|
className: name,
|
|
1225
|
-
propName: resolver.
|
|
1280
|
+
propName: resolver.propertyName(tag ?? name)
|
|
1226
1281
|
}));
|
|
1227
1282
|
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [classFiles, /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
|
|
1228
1283
|
baseName: sdkFile.baseName,
|
|
@@ -1262,38 +1317,27 @@ const defaultMacros = [kubb_kit.ast.macroSimplifyUnion];
|
|
|
1262
1317
|
//#endregion
|
|
1263
1318
|
//#region ../../internals/client/src/resolver.ts
|
|
1264
1319
|
/**
|
|
1265
|
-
* Default resolver shared by the client plugins. Functions and files
|
|
1266
|
-
* tag groups use PascalCase.
|
|
1320
|
+
* Default resolver shared by the client plugins. Functions and files inherit the built-in camelCase
|
|
1321
|
+
* `name` and `file`; classes and tag groups use PascalCase.
|
|
1267
1322
|
*
|
|
1268
1323
|
* @example
|
|
1269
1324
|
* ```ts
|
|
1270
|
-
* resolverClient.
|
|
1271
|
-
* resolverClient.
|
|
1325
|
+
* resolverClient.name('show pet by id') // 'showPetById'
|
|
1326
|
+
* resolverClient.groupName('pet') // 'PetClient'
|
|
1272
1327
|
* ```
|
|
1273
1328
|
*/
|
|
1274
|
-
const resolverClient = (0, kubb_kit.
|
|
1275
|
-
name: "default",
|
|
1329
|
+
const resolverClient = (0, kubb_kit.createResolver)({
|
|
1276
1330
|
pluginName: "plugin-contract-client",
|
|
1277
|
-
|
|
1278
|
-
if (type === "file") return toFilePath(name);
|
|
1279
|
-
return ensureValidVarName(camelCase(name));
|
|
1280
|
-
},
|
|
1281
|
-
resolveName(name) {
|
|
1282
|
-
return this.default(name, "function");
|
|
1283
|
-
},
|
|
1284
|
-
resolvePathName(name, type) {
|
|
1285
|
-
return this.default(name, type);
|
|
1286
|
-
},
|
|
1287
|
-
resolveClassName(name) {
|
|
1331
|
+
className(name) {
|
|
1288
1332
|
return ensureValidVarName(pascalCase(name));
|
|
1289
1333
|
},
|
|
1290
|
-
|
|
1334
|
+
groupName(name) {
|
|
1291
1335
|
return ensureValidVarName(pascalCase(`${name} Client`));
|
|
1292
1336
|
},
|
|
1293
|
-
|
|
1337
|
+
propertyName(name) {
|
|
1294
1338
|
return ensureValidVarName(camelCase(name));
|
|
1295
1339
|
}
|
|
1296
|
-
})
|
|
1340
|
+
});
|
|
1297
1341
|
//#endregion
|
|
1298
1342
|
//#region src/generators/clientGenerator.tsx
|
|
1299
1343
|
/**
|
|
@@ -1314,25 +1358,28 @@ const clientGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1314
1358
|
const pluginZod = resolveResponseValidator(validator) === "zod" || resolveRequestValidator(validator) === "zod" ? driver.getPlugin(_kubb_plugin_zod.pluginZodName) : null;
|
|
1315
1359
|
const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) : null;
|
|
1316
1360
|
const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
|
|
1317
|
-
const importedTypeNames = [tsResolver.
|
|
1361
|
+
const importedTypeNames = [tsResolver.response.options(node), tsResolver.response.responses(node)];
|
|
1318
1362
|
const importedZodNames = zodResolver ? [
|
|
1319
|
-
resolveResponseValidator(validator) === "zod" ? zodResolver.
|
|
1363
|
+
resolveResponseValidator(validator) === "zod" ? zodResolver.response.response?.(node) : null,
|
|
1320
1364
|
resolveResponseValidator(validator) === "zod" ? buildZodErrorParse(node, zodResolver)?.expression ?? null : null,
|
|
1321
|
-
resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.
|
|
1365
|
+
resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.response.body?.(node) : null
|
|
1322
1366
|
].filter((name) => Boolean(name)) : [];
|
|
1323
1367
|
const meta = {
|
|
1324
|
-
name: resolver.
|
|
1325
|
-
file: resolver.
|
|
1368
|
+
name: resolver.name(node.operationId),
|
|
1369
|
+
file: resolver.file({
|
|
1370
|
+
...operationFileEntry(node, node.operationId),
|
|
1326
1371
|
root,
|
|
1327
1372
|
output,
|
|
1328
1373
|
group: group ?? void 0
|
|
1329
1374
|
}),
|
|
1330
|
-
fileTs: tsResolver.
|
|
1375
|
+
fileTs: tsResolver.file({
|
|
1376
|
+
...operationFileEntry(node, node.operationId),
|
|
1331
1377
|
root,
|
|
1332
1378
|
output: pluginTs.options?.output ?? output,
|
|
1333
1379
|
group: pluginTs.options?.group ?? void 0
|
|
1334
1380
|
}),
|
|
1335
|
-
fileZod: zodResolver && pluginZod?.options ? zodResolver.
|
|
1381
|
+
fileZod: zodResolver && pluginZod?.options ? zodResolver.file({
|
|
1382
|
+
...operationFileEntry(node, node.operationId),
|
|
1336
1383
|
root,
|
|
1337
1384
|
output: pluginZod.options.output ?? output,
|
|
1338
1385
|
group: pluginZod.options?.group ?? void 0
|
|
@@ -1349,7 +1396,7 @@ const clientGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1349
1396
|
baseName: meta.file.baseName,
|
|
1350
1397
|
path: meta.file.path,
|
|
1351
1398
|
meta: meta.file.meta,
|
|
1352
|
-
banner: resolver.
|
|
1399
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1353
1400
|
output,
|
|
1354
1401
|
config,
|
|
1355
1402
|
file: {
|
|
@@ -1357,7 +1404,7 @@ const clientGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1357
1404
|
baseName: meta.file.baseName
|
|
1358
1405
|
}
|
|
1359
1406
|
}),
|
|
1360
|
-
footer: resolver.
|
|
1407
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1361
1408
|
output,
|
|
1362
1409
|
config,
|
|
1363
1410
|
file: {
|
|
@@ -1461,10 +1508,7 @@ const pluginFetch = (0, kubb_kit.definePlugin)((options) => {
|
|
|
1461
1508
|
mode: sdk.mode ?? "tag",
|
|
1462
1509
|
name: sdk.name
|
|
1463
1510
|
} : void 0,
|
|
1464
|
-
resolver: userResolver ?
|
|
1465
|
-
...resolverClient,
|
|
1466
|
-
...userResolver
|
|
1467
|
-
} : resolverClient
|
|
1511
|
+
resolver: userResolver ? kubb_kit.Resolver.merge(resolverClient, userResolver) : resolverClient
|
|
1468
1512
|
};
|
|
1469
1513
|
const selectedGenerators = resolved.sdk ? [createSdkGenerator()] : [clientGenerator];
|
|
1470
1514
|
return {
|