@kubb/plugin-fetch 5.1.0-canary.20260824T161549 → 5.1.1

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 CHANGED
@@ -466,15 +466,15 @@ function createGroupConfig(group) {
466
466
  //#endregion
467
467
  //#region ../../internals/client/src/builders/generics.ts
468
468
  /**
469
- * Builds the `RequestResult` generic arguments for one operation: the plugin-ts per-status responses
470
- * record plus the per-call `ThrowOnError` flag. `SuccessOf` / `ErrorOf` split the record inside the
469
+ * Builds the `RequestResult` generic arguments for one operation: the per-status responses record
470
+ * plus the per-call `ThrowOnError` flag. `SuccessOf` / `ErrorOf` split the record inside the
471
471
  * runtime, so this only names the record and threads `ThrowOnError`.
472
472
  *
473
473
  * @example
474
- * `buildRequestResultGenerics({ node, tsResolver }) // 'AddPetResponses, ThrowOnError'`
474
+ * `buildRequestResultGenerics({ node, types }) // 'AddPetResponses, ThrowOnError'`
475
475
  */
476
- function buildRequestResultGenerics({ node, tsResolver }) {
477
- return `${tsResolver.response.responses(node)}, ThrowOnError`;
476
+ function buildRequestResultGenerics({ node, types }) {
477
+ return `${types.response.responses(node)}, ThrowOnError`;
478
478
  }
479
479
  //#endregion
480
480
  //#region ../../internals/client/src/builders/returnStatement.ts
@@ -486,10 +486,10 @@ function buildRequestResultGenerics({ node, tsResolver }) {
486
486
  * @example
487
487
  * `return request({ method: 'POST', url: '/pet', ...config }) as Promise<RequestResult<AddPetResponses, ThrowOnError>>`
488
488
  */
489
- function buildReturnStatement({ node, tsResolver, callConfig }) {
489
+ function buildReturnStatement({ node, types, callConfig }) {
490
490
  return `return request(${callConfig}) as Promise<RequestResult<${buildRequestResultGenerics({
491
491
  node,
492
- tsResolver
492
+ types
493
493
  })}>>`;
494
494
  }
495
495
  //#endregion
@@ -565,30 +565,28 @@ function buildSecurityMetadata({ security }) {
565
565
  const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
566
566
  /**
567
567
  * Builds the grouped-options signature for one operation: a single `options` object whose `TData`
568
- * is the plugin-ts `<Name>Options` (carrying a literal `url`), and a `RequestResult` return type
569
- * keyed to the plugin-ts per-status responses record. There are no positional arguments.
568
+ * is the `<Name>Options` type, and a `RequestResult` return type keyed to the per-status responses
569
+ * record. There are no positional arguments.
570
570
  *
571
571
  * The generated file imports `<Name>Options` and `<Name>Responses` and uses them directly, so no
572
- * per-operation input type has to be emitted.
572
+ * per-operation input type has to be emitted. Both names come from `types`, which is `plugin-ts` or
573
+ * `plugin-zod`'s inferred types (see `resolveOperationTypes`).
573
574
  */
574
- function buildGroupedOptionsSignature({ node, tsResolver }) {
575
- const optionsName = tsResolver.response.options(node);
576
- const responsesName = tsResolver.response.responses(node);
575
+ function buildGroupedOptionsSignature({ node, types }) {
576
+ const optionsName = types.response.options(node);
577
577
  const resultGenerics = buildRequestResultGenerics({
578
578
  node,
579
- tsResolver
579
+ types
580
580
  });
581
581
  const { isOptional } = getRequestGroupOptionality(node);
582
582
  return {
583
- dataTypeName: optionsName,
584
583
  paramsSignature: declarationPrinter.print((0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
585
584
  name: "options",
586
585
  type: `Options<${optionsName}, ThrowOnError>`,
587
586
  ...isOptional ? { default: "{}" } : {}
588
587
  })] })) ?? "",
589
588
  returnType: `Promise<RequestResult<${resultGenerics}>>`,
590
- generics: ["ThrowOnError extends boolean = true"],
591
- importedTypeNames: [optionsName, responsesName]
589
+ generics: ["ThrowOnError extends boolean = true"]
592
590
  };
593
591
  }
594
592
  //#endregion
@@ -707,15 +705,15 @@ function buildCallConfig({ node, validator, zodResolver, security }) {
707
705
  * returns the `RequestResult`. A per-call `options.client` still overrides the instance client, so
708
706
  * one operation can be routed to a different environment without a new instance.
709
707
  */
710
- function buildSdkMethod({ node, name, tsResolver, zodResolver, validator, security }) {
708
+ function buildSdkMethod({ node, name, types, zodResolver, validator, security }) {
711
709
  if (!kubb_kit.ast.isHttpOperationNode(node)) return "";
712
710
  const signature = buildGroupedOptionsSignature({
713
711
  node,
714
- tsResolver
712
+ types
715
713
  });
716
714
  const returnStatement = buildReturnStatement({
717
715
  node,
718
- tsResolver,
716
+ types,
719
717
  callConfig: buildCallConfig({
720
718
  node,
721
719
  validator,
@@ -796,11 +794,11 @@ function buildStyles({ node }) {
796
794
  * single `options` object to the resolved client and returns the `RequestResult`. The type, signature,
797
795
  * and call config are built with the AST factory, and only the jsx-renderer emits the source.
798
796
  */
799
- function Operation({ name, node, tsResolver, zodResolver, validator, security, isExportable = true, isIndexable = true }) {
797
+ function Operation({ name, node, types, zodResolver, validator, security, isExportable = true, isIndexable = true }) {
800
798
  if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
801
799
  const signature = buildGroupedOptionsSignature({
802
800
  node,
803
- tsResolver
801
+ types
804
802
  });
805
803
  const validators = buildValidatorHooks({
806
804
  node,
@@ -832,11 +830,11 @@ function Operation({ name, node, tsResolver, zodResolver, validator, security, i
832
830
  responseTypeLiteral,
833
831
  "...config"
834
832
  ].filter(Boolean).join(", ")} }`;
835
- const eventType = `SuccessOf<${tsResolver.response.responses(node)}>`;
833
+ const eventType = `SuccessOf<${types.response.responses(node)}>`;
836
834
  const returnType = eventStream ? `Promise<EventStreamResult<${eventType}>>` : signature.returnType;
837
835
  const returnStatement = eventStream ? `return toEventStream<${eventType}>(request(${callConfig}))` : buildReturnStatement({
838
836
  node,
839
- tsResolver,
837
+ types,
840
838
  callConfig
841
839
  });
842
840
  return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
@@ -871,10 +869,10 @@ function Operation({ name, node, tsResolver, zodResolver, validator, security, i
871
869
  * still overrides the instance client for a one-off call.
872
870
  */
873
871
  function SdkClient({ name, isExportable = true, isIndexable = true, operations, validator, children }) {
874
- const methods = operations.map(({ node, name: methodName, tsResolver, zodResolver, security }) => buildSdkMethod({
872
+ const methods = operations.map(({ node, name: methodName, types, zodResolver, security }) => buildSdkMethod({
875
873
  node,
876
874
  name: methodName,
877
- tsResolver,
875
+ types,
878
876
  zodResolver,
879
877
  validator,
880
878
  security
@@ -894,6 +892,53 @@ function SdkClient({ name, isExportable = true, isIndexable = true, operations,
894
892
  });
895
893
  }
896
894
  //#endregion
895
+ //#region ../../internals/client/src/resolveOperationTypes.ts
896
+ /**
897
+ * Warning a client generator reports when neither plugin can supply the operation types, so the
898
+ * pipeline says why nothing was generated instead of silently emitting no files.
899
+ */
900
+ const MISSING_OPERATION_TYPES_WARNING = "Skipped: no operation types available. Add `pluginTs()`, or `pluginZod({ inferred: true })` to type the client from its zod schemas.";
901
+ /**
902
+ * Picks the plugin a generated client takes its `Options` and `Responses` types from.
903
+ *
904
+ * `plugin-ts` wins whenever it is in the pipeline, so existing configs keep the types they generate
905
+ * today. Without it, `pluginZod({ inferred: true })` takes over: its inferred options and responses
906
+ * types are built from the same shared schemas as the `plugin-ts` ones, so a client typed off
907
+ * `z.infer` carries what the codecs decode to (a `Temporal` instance, a `Date`) rather than the raw
908
+ * wire type. Returns `null` when neither is available, leaving the caller nothing to type against.
909
+ *
910
+ * @example
911
+ * ```ts
912
+ * const types = resolveOperationTypes(ctx.driver)
913
+ * if (!types) return null
914
+ * types.response.options(node) // 'GetPetByIdOptions', or 'GetPetByIdOptionsSchemaType' from zod
915
+ * ```
916
+ */
917
+ function resolveOperationTypes(driver) {
918
+ const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
919
+ if (pluginTs) {
920
+ const resolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
921
+ return {
922
+ response: resolver.response,
923
+ resolver,
924
+ output: pluginTs.options?.output,
925
+ group: pluginTs.options?.group
926
+ };
927
+ }
928
+ const pluginZod = driver.getPlugin(_kubb_plugin_zod.pluginZodName);
929
+ if (!pluginZod?.options?.inferred) return null;
930
+ const resolver = driver.getResolver(_kubb_plugin_zod.pluginZodName);
931
+ return {
932
+ response: {
933
+ options: resolver.response.options,
934
+ responses: (node) => resolver.schema.type(resolver.response.responses(node))
935
+ },
936
+ resolver,
937
+ output: pluginZod.options.output,
938
+ group: pluginZod.options.group
939
+ };
940
+ }
941
+ //#endregion
897
942
  //#region ../../internals/client/src/generators/clientGenerator.tsx
898
943
  /**
899
944
  * Builds the built-in per-operation generator shared by the client plugins (`@kubb/plugin-fetch`,
@@ -910,13 +955,15 @@ function createClientGenerator(name) {
910
955
  if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
911
956
  const { config, driver, resolver, root } = ctx;
912
957
  const { output, validator, group } = ctx.options;
913
- const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
914
- if (!pluginTs) return null;
915
- const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
958
+ const types = resolveOperationTypes(driver);
959
+ if (!types) {
960
+ ctx.warn(MISSING_OPERATION_TYPES_WARNING);
961
+ return null;
962
+ }
916
963
  const pluginZod = resolveResponseValidator(validator) === "zod" || resolveRequestValidator(validator) === "zod" ? driver.getPlugin(_kubb_plugin_zod.pluginZodName) : null;
917
964
  const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) : null;
918
965
  const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
919
- const importedTypeNames = [tsResolver.response.options(node), tsResolver.response.responses(node)];
966
+ const importedTypeNames = [types.response.options(node), types.response.responses(node)];
920
967
  const importedZodNames = zodResolver ? [
921
968
  resolveResponseValidator(validator) === "zod" ? zodResolver.response.response?.(node) : null,
922
969
  resolveResponseValidator(validator) === "zod" ? buildZodErrorParse(node, zodResolver)?.expression ?? null : null,
@@ -930,13 +977,13 @@ function createClientGenerator(name) {
930
977
  output,
931
978
  group: group ?? void 0
932
979
  }),
933
- fileTs: resolveDependencyOperationFile({
980
+ fileTypes: resolveDependencyOperationFile({
934
981
  cache: ctx.cache,
935
982
  node,
936
- resolver: tsResolver,
983
+ resolver: types.resolver,
937
984
  root,
938
- output: pluginTs.options?.output ?? output,
939
- group: pluginTs.options?.group
985
+ output: types.output ?? output,
986
+ group: types.group
940
987
  }),
941
988
  fileZod: zodResolver && pluginZod?.options ? zodResolver.file({
942
989
  ...operationFileEntry(node, node.operationId),
@@ -988,10 +1035,10 @@ function createClientGenerator(name) {
988
1035
  path: clientPath,
989
1036
  isTypeOnly: true
990
1037
  }),
991
- meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1038
+ meta.fileTypes && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
992
1039
  name: Array.from(new Set(importedTypeNames)),
993
1040
  root: meta.file.path,
994
- path: meta.fileTs.path,
1041
+ path: meta.fileTypes.path,
995
1042
  isTypeOnly: true
996
1043
  }),
997
1044
  meta.fileZod && importedZodNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
@@ -1002,7 +1049,7 @@ function createClientGenerator(name) {
1002
1049
  /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Operation, {
1003
1050
  name: meta.name,
1004
1051
  node,
1005
- tsResolver,
1052
+ types,
1006
1053
  zodResolver,
1007
1054
  validator,
1008
1055
  security
@@ -1038,8 +1085,8 @@ function SdkFacade({ name, isExportable = true, isIndexable = true, members, chi
1038
1085
  }
1039
1086
  //#endregion
1040
1087
  //#region ../../internals/client/src/generators/sdkGenerator.tsx
1041
- function resolveTypeImportNames(node, tsResolver) {
1042
- return [tsResolver.response.options(node), tsResolver.response.responses(node)];
1088
+ function resolveTypeImportNames(node, types) {
1089
+ return [types.response.options(node), types.response.responses(node)];
1043
1090
  }
1044
1091
  function resolveZodImportNames(node, zodResolver, validator) {
1045
1092
  const { query: queryParams } = getOperationParameters(node);
@@ -1054,21 +1101,18 @@ function resolveZodImportNames(node, zodResolver, validator) {
1054
1101
  * Groups operations into one controller per tag. Operations without a tag fall back to a single
1055
1102
  * `Client`/`ApiClient` controller, matching the resolver's default naming.
1056
1103
  */
1057
- function buildControllers(nodes, ctx) {
1104
+ function buildControllers(nodes, ctx, types) {
1058
1105
  const { driver, resolver, root } = ctx;
1059
1106
  const { output, group, validator } = ctx.options;
1060
- const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
1061
- const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1062
- const tsPluginOptions = pluginTs.options;
1063
1107
  const pluginZod = isValidatorEnabled(validator) ? driver.getPlugin(_kubb_plugin_zod.pluginZodName) : null;
1064
1108
  const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) : null;
1065
1109
  const document = ctx.adapter.document;
1066
1110
  function buildOperationData(node) {
1067
- const typeFile = tsResolver.file({
1111
+ const typeFile = types.resolver.file({
1068
1112
  ...operationFileEntry(node, node.operationId),
1069
1113
  root,
1070
- output: tsPluginOptions?.output ?? output,
1071
- group: tsPluginOptions?.group
1114
+ output: types.output ?? output,
1115
+ group: types.group
1072
1116
  });
1073
1117
  const zodFile = zodResolver && pluginZod?.options ? zodResolver.file({
1074
1118
  ...operationFileEntry(node, node.operationId),
@@ -1084,7 +1128,7 @@ function buildControllers(nodes, ctx) {
1084
1128
  return {
1085
1129
  node,
1086
1130
  name: resolver.name(node.operationId),
1087
- tsResolver,
1131
+ types,
1088
1132
  zodResolver,
1089
1133
  typeFile,
1090
1134
  zodFile,
@@ -1149,8 +1193,13 @@ function createSdkGenerator() {
1149
1193
  operations(nodes, ctx) {
1150
1194
  const { config, resolver, root } = ctx;
1151
1195
  const { output, group, validator, sdk } = ctx.options;
1152
- if (!ctx.driver.getPlugin(_kubb_plugin_ts.pluginTsName) || !sdk) return null;
1153
- const controllers = buildControllers(nodes, ctx);
1196
+ if (!sdk) return null;
1197
+ const types = resolveOperationTypes(ctx.driver);
1198
+ if (!types) {
1199
+ ctx.warn(MISSING_OPERATION_TYPES_WARNING);
1200
+ return null;
1201
+ }
1202
+ const controllers = buildControllers(nodes, ctx, types);
1154
1203
  const clientPath = node_path.default.resolve(root, ".kubb/client.ts");
1155
1204
  const banner = (file) => resolver.default.banner(ctx.meta, {
1156
1205
  output,
@@ -1171,7 +1220,7 @@ function createSdkGenerator() {
1171
1220
  const renderClassFile = (className, file, ops) => {
1172
1221
  const { namesByPath: typeNamesByPath, filesByPath: typeFilesByPath } = collectImportsByFile(ops, (op) => ({
1173
1222
  file: op.typeFile,
1174
- names: resolveTypeImportNames(op.node, op.tsResolver)
1223
+ names: resolveTypeImportNames(op.node, op.types)
1175
1224
  }));
1176
1225
  const { namesByPath: zodNamesByPath, filesByPath: zodFilesByPath } = isValidatorEnabled(validator) ? collectImportsByFile(ops, (op) => ({
1177
1226
  file: op.zodFile,
@@ -1378,7 +1427,7 @@ const pluginFetch = (0, kubb_kit.definePlugin)((options) => {
1378
1427
  return {
1379
1428
  name: pluginFetchName,
1380
1429
  options,
1381
- dependencies: [_kubb_plugin_ts.pluginTsName, isValidatorEnabled(resolved.validator) ? _kubb_plugin_zod.pluginZodName : null].filter((dependency) => Boolean(dependency)),
1430
+ dependencies: [_kubb_plugin_ts.pluginTsName, _kubb_plugin_zod.pluginZodName],
1382
1431
  hooks: { "kubb:plugin:setup"(ctx) {
1383
1432
  ctx.setOptions(resolved);
1384
1433
  ctx.setResolver(resolved.resolver);