@kubb/plugin-fetch 5.1.0-canary.20260824T161549 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +100 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +100 -51
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/plugin.ts +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { t as __name } from "./rolldown-runtime-C0LytTxp.js";
|
|
2
2
|
import { Exclude, Group, Include, Output, OutputOptions, Override, PluginFactoryOptions, Resolver, ResolverPatch, ast } from "kubb/kit";
|
|
3
|
-
import "@kubb/plugin-ts";
|
|
4
3
|
import "kubb/jsx";
|
|
5
4
|
import "@kubb/plugin-zod";
|
|
6
5
|
//#region ../../internals/client/src/types.d.ts
|
package/dist/index.js
CHANGED
|
@@ -440,15 +440,15 @@ function createGroupConfig(group) {
|
|
|
440
440
|
//#endregion
|
|
441
441
|
//#region ../../internals/client/src/builders/generics.ts
|
|
442
442
|
/**
|
|
443
|
-
* Builds the `RequestResult` generic arguments for one operation: the
|
|
444
|
-
*
|
|
443
|
+
* Builds the `RequestResult` generic arguments for one operation: the per-status responses record
|
|
444
|
+
* plus the per-call `ThrowOnError` flag. `SuccessOf` / `ErrorOf` split the record inside the
|
|
445
445
|
* runtime, so this only names the record and threads `ThrowOnError`.
|
|
446
446
|
*
|
|
447
447
|
* @example
|
|
448
|
-
* `buildRequestResultGenerics({ node,
|
|
448
|
+
* `buildRequestResultGenerics({ node, types }) // 'AddPetResponses, ThrowOnError'`
|
|
449
449
|
*/
|
|
450
|
-
function buildRequestResultGenerics({ node,
|
|
451
|
-
return `${
|
|
450
|
+
function buildRequestResultGenerics({ node, types }) {
|
|
451
|
+
return `${types.response.responses(node)}, ThrowOnError`;
|
|
452
452
|
}
|
|
453
453
|
//#endregion
|
|
454
454
|
//#region ../../internals/client/src/builders/returnStatement.ts
|
|
@@ -460,10 +460,10 @@ function buildRequestResultGenerics({ node, tsResolver }) {
|
|
|
460
460
|
* @example
|
|
461
461
|
* `return request({ method: 'POST', url: '/pet', ...config }) as Promise<RequestResult<AddPetResponses, ThrowOnError>>`
|
|
462
462
|
*/
|
|
463
|
-
function buildReturnStatement({ node,
|
|
463
|
+
function buildReturnStatement({ node, types, callConfig }) {
|
|
464
464
|
return `return request(${callConfig}) as Promise<RequestResult<${buildRequestResultGenerics({
|
|
465
465
|
node,
|
|
466
|
-
|
|
466
|
+
types
|
|
467
467
|
})}>>`;
|
|
468
468
|
}
|
|
469
469
|
//#endregion
|
|
@@ -539,30 +539,28 @@ function buildSecurityMetadata({ security }) {
|
|
|
539
539
|
const declarationPrinter = functionPrinter({ mode: "declaration" });
|
|
540
540
|
/**
|
|
541
541
|
* Builds the grouped-options signature for one operation: a single `options` object whose `TData`
|
|
542
|
-
* is the
|
|
543
|
-
*
|
|
542
|
+
* is the `<Name>Options` type, and a `RequestResult` return type keyed to the per-status responses
|
|
543
|
+
* record. There are no positional arguments.
|
|
544
544
|
*
|
|
545
545
|
* The generated file imports `<Name>Options` and `<Name>Responses` and uses them directly, so no
|
|
546
|
-
* per-operation input type has to be emitted.
|
|
546
|
+
* per-operation input type has to be emitted. Both names come from `types`, which is `plugin-ts` or
|
|
547
|
+
* `plugin-zod`'s inferred types (see `resolveOperationTypes`).
|
|
547
548
|
*/
|
|
548
|
-
function buildGroupedOptionsSignature({ node,
|
|
549
|
-
const optionsName =
|
|
550
|
-
const responsesName = tsResolver.response.responses(node);
|
|
549
|
+
function buildGroupedOptionsSignature({ node, types }) {
|
|
550
|
+
const optionsName = types.response.options(node);
|
|
551
551
|
const resultGenerics = buildRequestResultGenerics({
|
|
552
552
|
node,
|
|
553
|
-
|
|
553
|
+
types
|
|
554
554
|
});
|
|
555
555
|
const { isOptional } = getRequestGroupOptionality(node);
|
|
556
556
|
return {
|
|
557
|
-
dataTypeName: optionsName,
|
|
558
557
|
paramsSignature: declarationPrinter.print(createFunctionParameters({ params: [createFunctionParameter({
|
|
559
558
|
name: "options",
|
|
560
559
|
type: `Options<${optionsName}, ThrowOnError>`,
|
|
561
560
|
...isOptional ? { default: "{}" } : {}
|
|
562
561
|
})] })) ?? "",
|
|
563
562
|
returnType: `Promise<RequestResult<${resultGenerics}>>`,
|
|
564
|
-
generics: ["ThrowOnError extends boolean = true"]
|
|
565
|
-
importedTypeNames: [optionsName, responsesName]
|
|
563
|
+
generics: ["ThrowOnError extends boolean = true"]
|
|
566
564
|
};
|
|
567
565
|
}
|
|
568
566
|
//#endregion
|
|
@@ -681,15 +679,15 @@ function buildCallConfig({ node, validator, zodResolver, security }) {
|
|
|
681
679
|
* returns the `RequestResult`. A per-call `options.client` still overrides the instance client, so
|
|
682
680
|
* one operation can be routed to a different environment without a new instance.
|
|
683
681
|
*/
|
|
684
|
-
function buildSdkMethod({ node, name,
|
|
682
|
+
function buildSdkMethod({ node, name, types, zodResolver, validator, security }) {
|
|
685
683
|
if (!ast.isHttpOperationNode(node)) return "";
|
|
686
684
|
const signature = buildGroupedOptionsSignature({
|
|
687
685
|
node,
|
|
688
|
-
|
|
686
|
+
types
|
|
689
687
|
});
|
|
690
688
|
const returnStatement = buildReturnStatement({
|
|
691
689
|
node,
|
|
692
|
-
|
|
690
|
+
types,
|
|
693
691
|
callConfig: buildCallConfig({
|
|
694
692
|
node,
|
|
695
693
|
validator,
|
|
@@ -770,11 +768,11 @@ function buildStyles({ node }) {
|
|
|
770
768
|
* single `options` object to the resolved client and returns the `RequestResult`. The type, signature,
|
|
771
769
|
* and call config are built with the AST factory, and only the jsx-renderer emits the source.
|
|
772
770
|
*/
|
|
773
|
-
function Operation({ name, node,
|
|
771
|
+
function Operation({ name, node, types, zodResolver, validator, security, isExportable = true, isIndexable = true }) {
|
|
774
772
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
775
773
|
const signature = buildGroupedOptionsSignature({
|
|
776
774
|
node,
|
|
777
|
-
|
|
775
|
+
types
|
|
778
776
|
});
|
|
779
777
|
const validators = buildValidatorHooks({
|
|
780
778
|
node,
|
|
@@ -806,11 +804,11 @@ function Operation({ name, node, tsResolver, zodResolver, validator, security, i
|
|
|
806
804
|
responseTypeLiteral,
|
|
807
805
|
"...config"
|
|
808
806
|
].filter(Boolean).join(", ")} }`;
|
|
809
|
-
const eventType = `SuccessOf<${
|
|
807
|
+
const eventType = `SuccessOf<${types.response.responses(node)}>`;
|
|
810
808
|
const returnType = eventStream ? `Promise<EventStreamResult<${eventType}>>` : signature.returnType;
|
|
811
809
|
const returnStatement = eventStream ? `return toEventStream<${eventType}>(request(${callConfig}))` : buildReturnStatement({
|
|
812
810
|
node,
|
|
813
|
-
|
|
811
|
+
types,
|
|
814
812
|
callConfig
|
|
815
813
|
});
|
|
816
814
|
return /* @__PURE__ */ jsx(File.Source, {
|
|
@@ -845,10 +843,10 @@ function Operation({ name, node, tsResolver, zodResolver, validator, security, i
|
|
|
845
843
|
* still overrides the instance client for a one-off call.
|
|
846
844
|
*/
|
|
847
845
|
function SdkClient({ name, isExportable = true, isIndexable = true, operations, validator, children }) {
|
|
848
|
-
const methods = operations.map(({ node, name: methodName,
|
|
846
|
+
const methods = operations.map(({ node, name: methodName, types, zodResolver, security }) => buildSdkMethod({
|
|
849
847
|
node,
|
|
850
848
|
name: methodName,
|
|
851
|
-
|
|
849
|
+
types,
|
|
852
850
|
zodResolver,
|
|
853
851
|
validator,
|
|
854
852
|
security
|
|
@@ -868,6 +866,53 @@ function SdkClient({ name, isExportable = true, isIndexable = true, operations,
|
|
|
868
866
|
});
|
|
869
867
|
}
|
|
870
868
|
//#endregion
|
|
869
|
+
//#region ../../internals/client/src/resolveOperationTypes.ts
|
|
870
|
+
/**
|
|
871
|
+
* Warning a client generator reports when neither plugin can supply the operation types, so the
|
|
872
|
+
* pipeline says why nothing was generated instead of silently emitting no files.
|
|
873
|
+
*/
|
|
874
|
+
const MISSING_OPERATION_TYPES_WARNING = "Skipped: no operation types available. Add `pluginTs()`, or `pluginZod({ inferred: true })` to type the client from its zod schemas.";
|
|
875
|
+
/**
|
|
876
|
+
* Picks the plugin a generated client takes its `Options` and `Responses` types from.
|
|
877
|
+
*
|
|
878
|
+
* `plugin-ts` wins whenever it is in the pipeline, so existing configs keep the types they generate
|
|
879
|
+
* today. Without it, `pluginZod({ inferred: true })` takes over: its inferred options and responses
|
|
880
|
+
* types are built from the same shared schemas as the `plugin-ts` ones, so a client typed off
|
|
881
|
+
* `z.infer` carries what the codecs decode to (a `Temporal` instance, a `Date`) rather than the raw
|
|
882
|
+
* wire type. Returns `null` when neither is available, leaving the caller nothing to type against.
|
|
883
|
+
*
|
|
884
|
+
* @example
|
|
885
|
+
* ```ts
|
|
886
|
+
* const types = resolveOperationTypes(ctx.driver)
|
|
887
|
+
* if (!types) return null
|
|
888
|
+
* types.response.options(node) // 'GetPetByIdOptions', or 'GetPetByIdOptionsSchemaType' from zod
|
|
889
|
+
* ```
|
|
890
|
+
*/
|
|
891
|
+
function resolveOperationTypes(driver) {
|
|
892
|
+
const pluginTs = driver.getPlugin(pluginTsName);
|
|
893
|
+
if (pluginTs) {
|
|
894
|
+
const resolver = driver.getResolver(pluginTsName);
|
|
895
|
+
return {
|
|
896
|
+
response: resolver.response,
|
|
897
|
+
resolver,
|
|
898
|
+
output: pluginTs.options?.output,
|
|
899
|
+
group: pluginTs.options?.group
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
const pluginZod = driver.getPlugin(pluginZodName);
|
|
903
|
+
if (!pluginZod?.options?.inferred) return null;
|
|
904
|
+
const resolver = driver.getResolver(pluginZodName);
|
|
905
|
+
return {
|
|
906
|
+
response: {
|
|
907
|
+
options: resolver.response.options,
|
|
908
|
+
responses: (node) => resolver.schema.type(resolver.response.responses(node))
|
|
909
|
+
},
|
|
910
|
+
resolver,
|
|
911
|
+
output: pluginZod.options.output,
|
|
912
|
+
group: pluginZod.options.group
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
//#endregion
|
|
871
916
|
//#region ../../internals/client/src/generators/clientGenerator.tsx
|
|
872
917
|
/**
|
|
873
918
|
* Builds the built-in per-operation generator shared by the client plugins (`@kubb/plugin-fetch`,
|
|
@@ -884,13 +929,15 @@ function createClientGenerator(name) {
|
|
|
884
929
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
885
930
|
const { config, driver, resolver, root } = ctx;
|
|
886
931
|
const { output, validator, group } = ctx.options;
|
|
887
|
-
const
|
|
888
|
-
if (!
|
|
889
|
-
|
|
932
|
+
const types = resolveOperationTypes(driver);
|
|
933
|
+
if (!types) {
|
|
934
|
+
ctx.warn(MISSING_OPERATION_TYPES_WARNING);
|
|
935
|
+
return null;
|
|
936
|
+
}
|
|
890
937
|
const pluginZod = resolveResponseValidator(validator) === "zod" || resolveRequestValidator(validator) === "zod" ? driver.getPlugin(pluginZodName) : null;
|
|
891
938
|
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
|
|
892
939
|
const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
|
|
893
|
-
const importedTypeNames = [
|
|
940
|
+
const importedTypeNames = [types.response.options(node), types.response.responses(node)];
|
|
894
941
|
const importedZodNames = zodResolver ? [
|
|
895
942
|
resolveResponseValidator(validator) === "zod" ? zodResolver.response.response?.(node) : null,
|
|
896
943
|
resolveResponseValidator(validator) === "zod" ? buildZodErrorParse(node, zodResolver)?.expression ?? null : null,
|
|
@@ -904,13 +951,13 @@ function createClientGenerator(name) {
|
|
|
904
951
|
output,
|
|
905
952
|
group: group ?? void 0
|
|
906
953
|
}),
|
|
907
|
-
|
|
954
|
+
fileTypes: resolveDependencyOperationFile({
|
|
908
955
|
cache: ctx.cache,
|
|
909
956
|
node,
|
|
910
|
-
resolver:
|
|
957
|
+
resolver: types.resolver,
|
|
911
958
|
root,
|
|
912
|
-
output:
|
|
913
|
-
group:
|
|
959
|
+
output: types.output ?? output,
|
|
960
|
+
group: types.group
|
|
914
961
|
}),
|
|
915
962
|
fileZod: zodResolver && pluginZod?.options ? zodResolver.file({
|
|
916
963
|
...operationFileEntry(node, node.operationId),
|
|
@@ -962,10 +1009,10 @@ function createClientGenerator(name) {
|
|
|
962
1009
|
path: clientPath,
|
|
963
1010
|
isTypeOnly: true
|
|
964
1011
|
}),
|
|
965
|
-
meta.
|
|
1012
|
+
meta.fileTypes && importedTypeNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
|
|
966
1013
|
name: Array.from(new Set(importedTypeNames)),
|
|
967
1014
|
root: meta.file.path,
|
|
968
|
-
path: meta.
|
|
1015
|
+
path: meta.fileTypes.path,
|
|
969
1016
|
isTypeOnly: true
|
|
970
1017
|
}),
|
|
971
1018
|
meta.fileZod && importedZodNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
|
|
@@ -976,7 +1023,7 @@ function createClientGenerator(name) {
|
|
|
976
1023
|
/* @__PURE__ */ jsx(Operation, {
|
|
977
1024
|
name: meta.name,
|
|
978
1025
|
node,
|
|
979
|
-
|
|
1026
|
+
types,
|
|
980
1027
|
zodResolver,
|
|
981
1028
|
validator,
|
|
982
1029
|
security
|
|
@@ -1012,8 +1059,8 @@ function SdkFacade({ name, isExportable = true, isIndexable = true, members, chi
|
|
|
1012
1059
|
}
|
|
1013
1060
|
//#endregion
|
|
1014
1061
|
//#region ../../internals/client/src/generators/sdkGenerator.tsx
|
|
1015
|
-
function resolveTypeImportNames(node,
|
|
1016
|
-
return [
|
|
1062
|
+
function resolveTypeImportNames(node, types) {
|
|
1063
|
+
return [types.response.options(node), types.response.responses(node)];
|
|
1017
1064
|
}
|
|
1018
1065
|
function resolveZodImportNames(node, zodResolver, validator) {
|
|
1019
1066
|
const { query: queryParams } = getOperationParameters(node);
|
|
@@ -1028,21 +1075,18 @@ function resolveZodImportNames(node, zodResolver, validator) {
|
|
|
1028
1075
|
* Groups operations into one controller per tag. Operations without a tag fall back to a single
|
|
1029
1076
|
* `Client`/`ApiClient` controller, matching the resolver's default naming.
|
|
1030
1077
|
*/
|
|
1031
|
-
function buildControllers(nodes, ctx) {
|
|
1078
|
+
function buildControllers(nodes, ctx, types) {
|
|
1032
1079
|
const { driver, resolver, root } = ctx;
|
|
1033
1080
|
const { output, group, validator } = ctx.options;
|
|
1034
|
-
const pluginTs = driver.getPlugin(pluginTsName);
|
|
1035
|
-
const tsResolver = driver.getResolver(pluginTsName);
|
|
1036
|
-
const tsPluginOptions = pluginTs.options;
|
|
1037
1081
|
const pluginZod = isValidatorEnabled(validator) ? driver.getPlugin(pluginZodName) : null;
|
|
1038
1082
|
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
|
|
1039
1083
|
const document = ctx.adapter.document;
|
|
1040
1084
|
function buildOperationData(node) {
|
|
1041
|
-
const typeFile =
|
|
1085
|
+
const typeFile = types.resolver.file({
|
|
1042
1086
|
...operationFileEntry(node, node.operationId),
|
|
1043
1087
|
root,
|
|
1044
|
-
output:
|
|
1045
|
-
group:
|
|
1088
|
+
output: types.output ?? output,
|
|
1089
|
+
group: types.group
|
|
1046
1090
|
});
|
|
1047
1091
|
const zodFile = zodResolver && pluginZod?.options ? zodResolver.file({
|
|
1048
1092
|
...operationFileEntry(node, node.operationId),
|
|
@@ -1058,7 +1102,7 @@ function buildControllers(nodes, ctx) {
|
|
|
1058
1102
|
return {
|
|
1059
1103
|
node,
|
|
1060
1104
|
name: resolver.name(node.operationId),
|
|
1061
|
-
|
|
1105
|
+
types,
|
|
1062
1106
|
zodResolver,
|
|
1063
1107
|
typeFile,
|
|
1064
1108
|
zodFile,
|
|
@@ -1123,8 +1167,13 @@ function createSdkGenerator() {
|
|
|
1123
1167
|
operations(nodes, ctx) {
|
|
1124
1168
|
const { config, resolver, root } = ctx;
|
|
1125
1169
|
const { output, group, validator, sdk } = ctx.options;
|
|
1126
|
-
if (!
|
|
1127
|
-
const
|
|
1170
|
+
if (!sdk) return null;
|
|
1171
|
+
const types = resolveOperationTypes(ctx.driver);
|
|
1172
|
+
if (!types) {
|
|
1173
|
+
ctx.warn(MISSING_OPERATION_TYPES_WARNING);
|
|
1174
|
+
return null;
|
|
1175
|
+
}
|
|
1176
|
+
const controllers = buildControllers(nodes, ctx, types);
|
|
1128
1177
|
const clientPath = path.resolve(root, ".kubb/client.ts");
|
|
1129
1178
|
const banner = (file) => resolver.default.banner(ctx.meta, {
|
|
1130
1179
|
output,
|
|
@@ -1145,7 +1194,7 @@ function createSdkGenerator() {
|
|
|
1145
1194
|
const renderClassFile = (className, file, ops) => {
|
|
1146
1195
|
const { namesByPath: typeNamesByPath, filesByPath: typeFilesByPath } = collectImportsByFile(ops, (op) => ({
|
|
1147
1196
|
file: op.typeFile,
|
|
1148
|
-
names: resolveTypeImportNames(op.node, op.
|
|
1197
|
+
names: resolveTypeImportNames(op.node, op.types)
|
|
1149
1198
|
}));
|
|
1150
1199
|
const { namesByPath: zodNamesByPath, filesByPath: zodFilesByPath } = isValidatorEnabled(validator) ? collectImportsByFile(ops, (op) => ({
|
|
1151
1200
|
file: op.zodFile,
|
|
@@ -1352,7 +1401,7 @@ const pluginFetch = definePlugin((options) => {
|
|
|
1352
1401
|
return {
|
|
1353
1402
|
name: pluginFetchName,
|
|
1354
1403
|
options,
|
|
1355
|
-
dependencies: [pluginTsName,
|
|
1404
|
+
dependencies: [pluginTsName, pluginZodName],
|
|
1356
1405
|
hooks: { "kubb:plugin:setup"(ctx) {
|
|
1357
1406
|
ctx.setOptions(resolved);
|
|
1358
1407
|
ctx.setResolver(resolved.resolver);
|