@kubb/plugin-client 5.7.0-canary.20261024T190549 → 5.7.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
@@ -454,7 +454,7 @@ var compatibility = {
454
454
  };
455
455
  //#endregion
456
456
  //#region package.json
457
- var version = "5.7.0-canary.20261024T190549";
457
+ var version = "5.7.1";
458
458
  //#endregion
459
459
  //#region ../../internals/client/src/builders/validatorOptions.ts
460
460
  /**
@@ -463,7 +463,7 @@ var version = "5.7.0-canary.20261024T190549";
463
463
  function isValidatorEnabled(validator) {
464
464
  if (!validator) return false;
465
465
  if (validator === "zod") return true;
466
- return Boolean(validator.request || validator.response);
466
+ return Boolean(validator.request || validator.params || validator.response);
467
467
  }
468
468
  /**
469
469
  * Returns `'zod'` when request body parsing is enabled, `null` otherwise. The string shorthand
@@ -474,6 +474,14 @@ function resolveRequestValidator(validator) {
474
474
  return validator.request ?? null;
475
475
  }
476
476
  /**
477
+ * Returns `'zod'` when path, query, and header params parsing is enabled, `null` otherwise. Only the
478
+ * object form `{ params: 'zod' }` enables it.
479
+ */
480
+ function resolveParamsValidator(validator) {
481
+ if (!validator || validator === "zod") return null;
482
+ return validator.params ?? null;
483
+ }
484
+ /**
477
485
  * Returns `'zod'` when response parsing is enabled, `null` otherwise. The string shorthand `'zod'`
478
486
  * maps to response parsing.
479
487
  */
@@ -492,30 +500,6 @@ function buildZodErrorParse(node, zodResolver) {
492
500
  return zodResolver.response.error?.(node) || null;
493
501
  }
494
502
  //#endregion
495
- //#region ../../internals/client/src/builders/validator.ts
496
- /**
497
- * Builds the validator-hook references for one operation. Request validation runs before the send;
498
- * response validation runs on the success body only. Returns `null` references when the matching
499
- * direction is disabled or the schema is absent.
500
- */
501
- function buildValidatorHooks({ node, validator, zodResolver }) {
502
- const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
503
- const parsesResponse = zodResolver && resolveResponseValidator(validator) === "zod";
504
- const response = parsesResponse ? zodResolver.response.response(node) || null : null;
505
- const error = parsesResponse ? buildZodErrorParse(node, zodResolver) : null;
506
- const request = zodResolver && resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.response.body(node) || null : null;
507
- return {
508
- request,
509
- response,
510
- error,
511
- importedZodNames: [
512
- response,
513
- error,
514
- request
515
- ].filter((name) => Boolean(name))
516
- };
517
- }
518
- //#endregion
519
503
  //#region ../../internals/client/src/builders/security.ts
520
504
  function serializeAuth(auth) {
521
505
  const parts = [`type: '${auth.type}'`];
@@ -588,6 +572,49 @@ function buildSecurityMetadata({ security }) {
588
572
  return `[${security.map(serializeAuth).join(", ")}]`;
589
573
  }
590
574
  //#endregion
575
+ //#region ../../internals/client/src/builders/validator.ts
576
+ /**
577
+ * Builds the validator-hook references for one operation. Request body and params validation run before the send.
578
+ * Response validation runs on the success body only. Returns `null` references when the matching
579
+ * direction is disabled or the schema is absent.
580
+ */
581
+ function buildValidatorHooks({ node, validator, zodResolver }) {
582
+ const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
583
+ const parsesResponse = zodResolver && resolveResponseValidator(validator) === "zod";
584
+ const response = parsesResponse ? zodResolver.response.response(node) || null : null;
585
+ const error = parsesResponse ? buildZodErrorParse(node, zodResolver) : null;
586
+ const request = zodResolver && resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.response.body(node) || null : null;
587
+ const paramGroups = getOperationParameters(node);
588
+ const resolveParamsName = (kind, params) => zodResolver && resolveParamsValidator(validator) === "zod" && params.length > 0 ? zodResolver.param[kind](node, params[0]) : null;
589
+ const path = resolveParamsName("path", paramGroups.path);
590
+ const query = resolveParamsName("query", paramGroups.query);
591
+ const headers = resolveParamsName("headers", paramGroups.header);
592
+ const importedZodNames = [
593
+ response,
594
+ error,
595
+ request,
596
+ path,
597
+ query,
598
+ headers
599
+ ].filter((name) => Boolean(name));
600
+ return {
601
+ request,
602
+ path,
603
+ query,
604
+ headers: headers ? `toHeadersStandardSchema(${headers}, ${headers}.shape)` : null,
605
+ response,
606
+ error,
607
+ importedZodNames
608
+ };
609
+ }
610
+ /**
611
+ * Prints the `validator: { … }` entry of a call config from the hooks named in `keys`, or `null` when none is set.
612
+ */
613
+ function buildValidatorLiteral(hooks, keys) {
614
+ const entries = keys.flatMap((key) => hooks?.[key] ? [`${key}: ${hooks[key]}`] : []);
615
+ return entries.length ? `validator: { ${entries.join(", ")} }` : null;
616
+ }
617
+ //#endregion
591
618
  //#region ../../internals/client/src/builders/contentType.ts
592
619
  /**
593
620
  * Builds the `contentType` entry baked into the call config, or `null` for the JSON default.
@@ -792,12 +819,14 @@ function Operation({ name, node, types, zodResolver, validator, returnType, thro
792
819
  const eventStream = isEventStream(node);
793
820
  const responseType = getResponseType(node);
794
821
  const responseTypeLiteral = responseType ? `responseType: '${responseType}'` : null;
795
- const validatorEntries = [
796
- validators.request ? `request: ${validators.request}` : null,
797
- validators.response ? `response: ${validators.response}` : null,
798
- validators.error ? `error: ${validators.error}` : null
799
- ].filter(Boolean);
800
- const validatorLiteral = validatorEntries.length ? `validator: { ${validatorEntries.join(", ")} }` : null;
822
+ const validatorLiteral = buildValidatorLiteral(validators, [
823
+ "request",
824
+ "path",
825
+ "query",
826
+ "headers",
827
+ "response",
828
+ "error"
829
+ ]);
801
830
  const callConfig = `{ ${[
802
831
  `method: '${node.method.toUpperCase()}'`,
803
832
  `url: '${node.path}'`,
@@ -844,14 +873,35 @@ function Operation({ name, node, types, zodResolver, validator, returnType, thro
844
873
  //#endregion
845
874
  //#region ../../internals/client/src/resolveOperationTypes.ts
846
875
  /**
847
- * Picks the plugin a generated client takes its `Options` and `Responses` types from.
876
+ * A `plugin-ts` shaped resolver whose operation type names point at the types `pluginZod({ inferred })`
877
+ * exports next to each schema, so code written against `plugin-ts` names picks up the zod types.
878
+ */
879
+ function toZodTypeResolver(resolver) {
880
+ const type = (name) => resolver.schema.type(name);
881
+ return {
882
+ ...resolver,
883
+ file: resolver.file.bind(resolver),
884
+ param: {
885
+ name: (node, p) => type(resolver.param.name(node, p)),
886
+ path: (node, p) => type(resolver.param.path(node, p)),
887
+ query: (node, p) => type(resolver.param.query(node, p)),
888
+ headers: (node, p) => type(resolver.param.headers(node, p))
889
+ },
890
+ response: {
891
+ body: (node) => type(resolver.response.body(node)),
892
+ status: (node, statusCode) => type(resolver.response.status(node, statusCode)),
893
+ response: (node) => type(resolver.response.response(node)),
894
+ responses: (node) => type(resolver.response.responses(node)),
895
+ options: (node) => resolver.response.options(node)
896
+ }
897
+ };
898
+ }
899
+ /**
900
+ * Picks the plugin generated clients, query hooks, and MCP handlers take their operation types from.
848
901
  *
849
- * `plugin-ts` wins whenever it is in the pipeline, so existing configs keep the types they generate
850
- * today. Without it, `pluginZod({ inferred: true })` takes over: its inferred options and responses
851
- * types are built from the same shared schemas as the `plugin-ts` ones, so a client typed off
852
- * `z.infer` carries what the codecs decode to (a `Temporal` instance, a `Date`) rather than the raw
853
- * wire type. Throws `KUBB_MISSING_DEPENDENCY` for `pluginName` when neither is available, since the
854
- * client has nothing to type against.
902
+ * `pluginZod({ inferred: 'codec' })` wins, so a codec param takes its domain value. Otherwise `plugin-ts`
903
+ * wins when it is in the pipeline, and without it any `pluginZod({ inferred })`. Throws
904
+ * `KUBB_MISSING_DEPENDENCY` for `pluginName` when neither is available.
855
905
  *
856
906
  * @example
857
907
  * ```ts
@@ -861,16 +911,16 @@ function Operation({ name, node, types, zodResolver, validator, returnType, thro
861
911
  */
862
912
  function resolveOperationTypes(driver, pluginName) {
863
913
  const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
864
- if (pluginTs) {
914
+ const pluginZod = driver.getPlugin(_kubb_plugin_zod.pluginZodName);
915
+ if (pluginTs && pluginZod?.options?.inferred !== "codec") {
865
916
  const resolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
866
917
  return {
867
918
  response: resolver.response,
868
919
  resolver,
869
920
  output: pluginTs.options?.output,
870
- group: pluginTs.options?.group
921
+ group: pluginTs.options?.group ?? void 0
871
922
  };
872
923
  }
873
- const pluginZod = driver.getPlugin(_kubb_plugin_zod.pluginZodName);
874
924
  if (!pluginZod?.options?.inferred) throw new kubb_kit.Diagnostics.Error({
875
925
  code: kubb_kit.Diagnostics.code.missingDependency,
876
926
  severity: "error",
@@ -879,15 +929,12 @@ function resolveOperationTypes(driver, pluginName) {
879
929
  location: { kind: "config" },
880
930
  plugin: pluginName
881
931
  });
882
- const resolver = driver.getResolver(_kubb_plugin_zod.pluginZodName);
932
+ const resolver = toZodTypeResolver(driver.getResolver(_kubb_plugin_zod.pluginZodName));
883
933
  return {
884
- response: {
885
- options: resolver.response.options,
886
- responses: (node) => resolver.schema.type(resolver.response.responses(node))
887
- },
934
+ response: resolver.response,
888
935
  resolver,
889
936
  output: pluginZod.options.output,
890
- group: pluginZod.options.group
937
+ group: pluginZod.options.group ?? void 0
891
938
  };
892
939
  }
893
940
  //#endregion
@@ -909,14 +956,15 @@ function createClientGenerator(name, resolveClientPath) {
909
956
  const { config, driver, resolver, root } = ctx;
910
957
  const { output, validator, returnType, throwOnErrorDefault, group } = ctx.options;
911
958
  const types = resolveOperationTypes(driver, ctx.plugin.name);
912
- const pluginZod = resolveResponseValidator(validator) === "zod" || resolveRequestValidator(validator) === "zod" ? driver.getPlugin(_kubb_plugin_zod.pluginZodName) : null;
959
+ const pluginZod = isValidatorEnabled(validator) ? driver.getPlugin(_kubb_plugin_zod.pluginZodName) : null;
913
960
  const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) : null;
914
961
  const importedTypeNames = [types.response.options(node), types.response.responses(node)];
915
- const importedZodNames = buildValidatorHooks({
962
+ const validatorHooks = buildValidatorHooks({
916
963
  node,
917
964
  validator,
918
965
  zodResolver
919
- }).importedZodNames;
966
+ });
967
+ const importedZodNames = validatorHooks.importedZodNames;
920
968
  const meta = {
921
969
  name: resolver.name(node.operationId),
922
970
  file: resolver.file({
@@ -948,6 +996,7 @@ function createClientGenerator(name, resolveClientPath) {
948
996
  const customClientPath = resolveClientPath?.(ctx.options, root);
949
997
  const clientPath = customClientPath ?? node_path.default.resolve(root, ".kubb/client.ts");
950
998
  const clientRoot = customClientPath === void 0 ? meta.file.path : void 0;
999
+ const standardSchemaPath = customClientPath ?? node_path.default.resolve(root, ".kubb/standardSchema.ts");
951
1000
  const eventStream = isEventStream(node);
952
1001
  const clientValueImports = (() => {
953
1002
  if (eventStream) return ["client", "toEventStream"];
@@ -1012,6 +1061,11 @@ function createClientGenerator(name, resolveClientPath) {
1012
1061
  root: meta.file.path,
1013
1062
  path: meta.fileZod.path
1014
1063
  }),
1064
+ validatorHooks.headers && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1065
+ name: ["toHeadersStandardSchema"],
1066
+ root: clientRoot,
1067
+ path: standardSchemaPath
1068
+ }),
1015
1069
  /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Operation, {
1016
1070
  name: meta.name,
1017
1071
  node,