@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.js CHANGED
@@ -428,7 +428,7 @@ var compatibility = {
428
428
  };
429
429
  //#endregion
430
430
  //#region package.json
431
- var version = "5.7.0-canary.20261024T190549";
431
+ var version = "5.7.1";
432
432
  //#endregion
433
433
  //#region ../../internals/client/src/builders/validatorOptions.ts
434
434
  /**
@@ -437,7 +437,7 @@ var version = "5.7.0-canary.20261024T190549";
437
437
  function isValidatorEnabled(validator) {
438
438
  if (!validator) return false;
439
439
  if (validator === "zod") return true;
440
- return Boolean(validator.request || validator.response);
440
+ return Boolean(validator.request || validator.params || validator.response);
441
441
  }
442
442
  /**
443
443
  * Returns `'zod'` when request body parsing is enabled, `null` otherwise. The string shorthand
@@ -448,6 +448,14 @@ function resolveRequestValidator(validator) {
448
448
  return validator.request ?? null;
449
449
  }
450
450
  /**
451
+ * Returns `'zod'` when path, query, and header params parsing is enabled, `null` otherwise. Only the
452
+ * object form `{ params: 'zod' }` enables it.
453
+ */
454
+ function resolveParamsValidator(validator) {
455
+ if (!validator || validator === "zod") return null;
456
+ return validator.params ?? null;
457
+ }
458
+ /**
451
459
  * Returns `'zod'` when response parsing is enabled, `null` otherwise. The string shorthand `'zod'`
452
460
  * maps to response parsing.
453
461
  */
@@ -466,30 +474,6 @@ function buildZodErrorParse(node, zodResolver) {
466
474
  return zodResolver.response.error?.(node) || null;
467
475
  }
468
476
  //#endregion
469
- //#region ../../internals/client/src/builders/validator.ts
470
- /**
471
- * Builds the validator-hook references for one operation. Request validation runs before the send;
472
- * response validation runs on the success body only. Returns `null` references when the matching
473
- * direction is disabled or the schema is absent.
474
- */
475
- function buildValidatorHooks({ node, validator, zodResolver }) {
476
- const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
477
- const parsesResponse = zodResolver && resolveResponseValidator(validator) === "zod";
478
- const response = parsesResponse ? zodResolver.response.response(node) || null : null;
479
- const error = parsesResponse ? buildZodErrorParse(node, zodResolver) : null;
480
- const request = zodResolver && resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.response.body(node) || null : null;
481
- return {
482
- request,
483
- response,
484
- error,
485
- importedZodNames: [
486
- response,
487
- error,
488
- request
489
- ].filter((name) => Boolean(name))
490
- };
491
- }
492
- //#endregion
493
477
  //#region ../../internals/client/src/builders/security.ts
494
478
  function serializeAuth(auth) {
495
479
  const parts = [`type: '${auth.type}'`];
@@ -562,6 +546,49 @@ function buildSecurityMetadata({ security }) {
562
546
  return `[${security.map(serializeAuth).join(", ")}]`;
563
547
  }
564
548
  //#endregion
549
+ //#region ../../internals/client/src/builders/validator.ts
550
+ /**
551
+ * Builds the validator-hook references for one operation. Request body and params validation run before the send.
552
+ * Response validation runs on the success body only. Returns `null` references when the matching
553
+ * direction is disabled or the schema is absent.
554
+ */
555
+ function buildValidatorHooks({ node, validator, zodResolver }) {
556
+ const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
557
+ const parsesResponse = zodResolver && resolveResponseValidator(validator) === "zod";
558
+ const response = parsesResponse ? zodResolver.response.response(node) || null : null;
559
+ const error = parsesResponse ? buildZodErrorParse(node, zodResolver) : null;
560
+ const request = zodResolver && resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.response.body(node) || null : null;
561
+ const paramGroups = getOperationParameters(node);
562
+ const resolveParamsName = (kind, params) => zodResolver && resolveParamsValidator(validator) === "zod" && params.length > 0 ? zodResolver.param[kind](node, params[0]) : null;
563
+ const path = resolveParamsName("path", paramGroups.path);
564
+ const query = resolveParamsName("query", paramGroups.query);
565
+ const headers = resolveParamsName("headers", paramGroups.header);
566
+ const importedZodNames = [
567
+ response,
568
+ error,
569
+ request,
570
+ path,
571
+ query,
572
+ headers
573
+ ].filter((name) => Boolean(name));
574
+ return {
575
+ request,
576
+ path,
577
+ query,
578
+ headers: headers ? `toHeadersStandardSchema(${headers}, ${headers}.shape)` : null,
579
+ response,
580
+ error,
581
+ importedZodNames
582
+ };
583
+ }
584
+ /**
585
+ * Prints the `validator: { … }` entry of a call config from the hooks named in `keys`, or `null` when none is set.
586
+ */
587
+ function buildValidatorLiteral(hooks, keys) {
588
+ const entries = keys.flatMap((key) => hooks?.[key] ? [`${key}: ${hooks[key]}`] : []);
589
+ return entries.length ? `validator: { ${entries.join(", ")} }` : null;
590
+ }
591
+ //#endregion
565
592
  //#region ../../internals/client/src/builders/contentType.ts
566
593
  /**
567
594
  * Builds the `contentType` entry baked into the call config, or `null` for the JSON default.
@@ -766,12 +793,14 @@ function Operation({ name, node, types, zodResolver, validator, returnType, thro
766
793
  const eventStream = isEventStream(node);
767
794
  const responseType = getResponseType(node);
768
795
  const responseTypeLiteral = responseType ? `responseType: '${responseType}'` : null;
769
- const validatorEntries = [
770
- validators.request ? `request: ${validators.request}` : null,
771
- validators.response ? `response: ${validators.response}` : null,
772
- validators.error ? `error: ${validators.error}` : null
773
- ].filter(Boolean);
774
- const validatorLiteral = validatorEntries.length ? `validator: { ${validatorEntries.join(", ")} }` : null;
796
+ const validatorLiteral = buildValidatorLiteral(validators, [
797
+ "request",
798
+ "path",
799
+ "query",
800
+ "headers",
801
+ "response",
802
+ "error"
803
+ ]);
775
804
  const callConfig = `{ ${[
776
805
  `method: '${node.method.toUpperCase()}'`,
777
806
  `url: '${node.path}'`,
@@ -818,14 +847,35 @@ function Operation({ name, node, types, zodResolver, validator, returnType, thro
818
847
  //#endregion
819
848
  //#region ../../internals/client/src/resolveOperationTypes.ts
820
849
  /**
821
- * Picks the plugin a generated client takes its `Options` and `Responses` types from.
850
+ * A `plugin-ts` shaped resolver whose operation type names point at the types `pluginZod({ inferred })`
851
+ * exports next to each schema, so code written against `plugin-ts` names picks up the zod types.
852
+ */
853
+ function toZodTypeResolver(resolver) {
854
+ const type = (name) => resolver.schema.type(name);
855
+ return {
856
+ ...resolver,
857
+ file: resolver.file.bind(resolver),
858
+ param: {
859
+ name: (node, p) => type(resolver.param.name(node, p)),
860
+ path: (node, p) => type(resolver.param.path(node, p)),
861
+ query: (node, p) => type(resolver.param.query(node, p)),
862
+ headers: (node, p) => type(resolver.param.headers(node, p))
863
+ },
864
+ response: {
865
+ body: (node) => type(resolver.response.body(node)),
866
+ status: (node, statusCode) => type(resolver.response.status(node, statusCode)),
867
+ response: (node) => type(resolver.response.response(node)),
868
+ responses: (node) => type(resolver.response.responses(node)),
869
+ options: (node) => resolver.response.options(node)
870
+ }
871
+ };
872
+ }
873
+ /**
874
+ * Picks the plugin generated clients, query hooks, and MCP handlers take their operation types from.
822
875
  *
823
- * `plugin-ts` wins whenever it is in the pipeline, so existing configs keep the types they generate
824
- * today. Without it, `pluginZod({ inferred: true })` takes over: its inferred options and responses
825
- * types are built from the same shared schemas as the `plugin-ts` ones, so a client typed off
826
- * `z.infer` carries what the codecs decode to (a `Temporal` instance, a `Date`) rather than the raw
827
- * wire type. Throws `KUBB_MISSING_DEPENDENCY` for `pluginName` when neither is available, since the
828
- * client has nothing to type against.
876
+ * `pluginZod({ inferred: 'codec' })` wins, so a codec param takes its domain value. Otherwise `plugin-ts`
877
+ * wins when it is in the pipeline, and without it any `pluginZod({ inferred })`. Throws
878
+ * `KUBB_MISSING_DEPENDENCY` for `pluginName` when neither is available.
829
879
  *
830
880
  * @example
831
881
  * ```ts
@@ -835,16 +885,16 @@ function Operation({ name, node, types, zodResolver, validator, returnType, thro
835
885
  */
836
886
  function resolveOperationTypes(driver, pluginName) {
837
887
  const pluginTs = driver.getPlugin(pluginTsName);
838
- if (pluginTs) {
888
+ const pluginZod = driver.getPlugin(pluginZodName);
889
+ if (pluginTs && pluginZod?.options?.inferred !== "codec") {
839
890
  const resolver = driver.getResolver(pluginTsName);
840
891
  return {
841
892
  response: resolver.response,
842
893
  resolver,
843
894
  output: pluginTs.options?.output,
844
- group: pluginTs.options?.group
895
+ group: pluginTs.options?.group ?? void 0
845
896
  };
846
897
  }
847
- const pluginZod = driver.getPlugin(pluginZodName);
848
898
  if (!pluginZod?.options?.inferred) throw new Diagnostics.Error({
849
899
  code: Diagnostics.code.missingDependency,
850
900
  severity: "error",
@@ -853,15 +903,12 @@ function resolveOperationTypes(driver, pluginName) {
853
903
  location: { kind: "config" },
854
904
  plugin: pluginName
855
905
  });
856
- const resolver = driver.getResolver(pluginZodName);
906
+ const resolver = toZodTypeResolver(driver.getResolver(pluginZodName));
857
907
  return {
858
- response: {
859
- options: resolver.response.options,
860
- responses: (node) => resolver.schema.type(resolver.response.responses(node))
861
- },
908
+ response: resolver.response,
862
909
  resolver,
863
910
  output: pluginZod.options.output,
864
- group: pluginZod.options.group
911
+ group: pluginZod.options.group ?? void 0
865
912
  };
866
913
  }
867
914
  //#endregion
@@ -883,14 +930,15 @@ function createClientGenerator(name, resolveClientPath) {
883
930
  const { config, driver, resolver, root } = ctx;
884
931
  const { output, validator, returnType, throwOnErrorDefault, group } = ctx.options;
885
932
  const types = resolveOperationTypes(driver, ctx.plugin.name);
886
- const pluginZod = resolveResponseValidator(validator) === "zod" || resolveRequestValidator(validator) === "zod" ? driver.getPlugin(pluginZodName) : null;
933
+ const pluginZod = isValidatorEnabled(validator) ? driver.getPlugin(pluginZodName) : null;
887
934
  const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
888
935
  const importedTypeNames = [types.response.options(node), types.response.responses(node)];
889
- const importedZodNames = buildValidatorHooks({
936
+ const validatorHooks = buildValidatorHooks({
890
937
  node,
891
938
  validator,
892
939
  zodResolver
893
- }).importedZodNames;
940
+ });
941
+ const importedZodNames = validatorHooks.importedZodNames;
894
942
  const meta = {
895
943
  name: resolver.name(node.operationId),
896
944
  file: resolver.file({
@@ -922,6 +970,7 @@ function createClientGenerator(name, resolveClientPath) {
922
970
  const customClientPath = resolveClientPath?.(ctx.options, root);
923
971
  const clientPath = customClientPath ?? path.resolve(root, ".kubb/client.ts");
924
972
  const clientRoot = customClientPath === void 0 ? meta.file.path : void 0;
973
+ const standardSchemaPath = customClientPath ?? path.resolve(root, ".kubb/standardSchema.ts");
925
974
  const eventStream = isEventStream(node);
926
975
  const clientValueImports = (() => {
927
976
  if (eventStream) return ["client", "toEventStream"];
@@ -986,6 +1035,11 @@ function createClientGenerator(name, resolveClientPath) {
986
1035
  root: meta.file.path,
987
1036
  path: meta.fileZod.path
988
1037
  }),
1038
+ validatorHooks.headers && /* @__PURE__ */ jsx(File.Import, {
1039
+ name: ["toHeadersStandardSchema"],
1040
+ root: clientRoot,
1041
+ path: standardSchemaPath
1042
+ }),
989
1043
  /* @__PURE__ */ jsx(Operation, {
990
1044
  name: meta.name,
991
1045
  node,