@kubb/plugin-client 6.1.0-canary.20261109T175349 → 6.1.0-canary.20261109T175913

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
@@ -521,7 +521,7 @@ var compatibility = {
521
521
  "node": ">=22.22"
522
522
  };
523
523
  // package.json
524
- var version = "6.1.0-canary.20261109T175349";
524
+ var version = "6.1.0-canary.20261109T175913";
525
525
  // ../../internals/client/src/builders/validatorOptions.ts
526
526
  /**
527
527
  * Returns `true` when any direction of the validator uses zod (used for dependency checks).
@@ -557,22 +557,19 @@ function resolveResponseValidator(validator) {
557
557
  return validator.response ?? null;
558
558
  }
559
559
  /**
560
- * Resolves the zod schema name a generated client validates an error body with on the non-throw path.
561
- * Uses the error-only `<operation>ErrorSchema` (the union of non-2xx statuses); returns `null` when the
562
- * operation documents no error responses with a schema.
560
+ * Builds the `validator.error` map of a call, one plugin-zod `<operation>StatusNNNSchema` per non-2xx response with a
561
+ * schema, such as `{ 404: getPetStatus404Schema, '5XX': getPetStatus5XXSchema }`. Returns `null` without one.
563
562
  */
564
563
  function buildZodErrorParse(node, zodResolver) {
565
- if (!getErrorStatusCodes(node).length) return null;
566
- return zodResolver.response.error?.(node) || null;
567
- }
568
- /** Prints the statuses `<operation>ErrorSchema` covers, such as `[404, '5XX']`, or `null` when a `default` response covers them all. */
569
- function buildErrorStatusLiteral(node) {
570
- const statusCodes = getErrorStatusCodes(node);
571
- if (!statusCodes.length || statusCodes.includes("default")) return null;
572
- return `[${statusCodes.map((statusCode) => /^\d+$/.test(statusCode) ? statusCode : stringify(statusCode)).join(", ")}]`;
573
- }
574
- function getErrorStatusCodes(node) {
575
- return node.responses.filter((res) => !isSuccessStatusCode(res.statusCode) && res.content?.some((entry) => entry.schema)).map((res) => String(res.statusCode));
564
+ const entries = node.responses.filter((res) => !isSuccessStatusCode(res.statusCode) && res.content?.some((entry) => entry.schema)).map((res) => ({
565
+ key: String(res.statusCode),
566
+ name: zodResolver.response.status(node, res.statusCode)
567
+ }));
568
+ if (!entries.length) return null;
569
+ return {
570
+ literal: `{ ${entries.map(({ key, name }) => `${/^\d+$/.test(key) ? key : stringify(key)}: ${name}`).join(", ")} }`,
571
+ names: entries.map(({ name }) => name)
572
+ };
576
573
  }
577
574
  // ../../internals/client/src/builders/generics.ts
578
575
  /**
@@ -777,8 +774,7 @@ function buildValidatorHooks({ node, validator, zodResolver }) {
777
774
  const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
778
775
  const parsesResponse = zodResolver && resolveResponseValidator(validator) === "zod";
779
776
  const response = parsesResponse ? zodResolver.response.response(node) || null : null;
780
- const error = parsesResponse ? buildZodErrorParse(node, zodResolver) : null;
781
- const errorStatus = error ? buildErrorStatusLiteral(node) : null;
777
+ const errorParse = parsesResponse ? buildZodErrorParse(node, zodResolver) : null;
782
778
  const request = zodResolver && resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.response.body(node) || null : null;
783
779
  const paramGroups = getOperationParameters(node);
784
780
  const resolveParamsName = (kind, params) => zodResolver && resolveParamsValidator(validator) === "zod" && params.length > 0 ? zodResolver.param[kind](node, params[0]) : null;
@@ -788,7 +784,7 @@ function buildValidatorHooks({ node, validator, zodResolver }) {
788
784
  const cookies = resolveParamsName("cookies", paramGroups.cookie);
789
785
  const importedZodNames = [
790
786
  response,
791
- error,
787
+ ...errorParse?.names ?? [],
792
788
  request,
793
789
  path,
794
790
  query,
@@ -802,17 +798,17 @@ function buildValidatorHooks({ node, validator, zodResolver }) {
802
798
  headers: headers ? `toHeadersStandardSchema(${headers}, ${headers}.shape)` : null,
803
799
  cookies,
804
800
  response,
805
- error,
806
- errorStatus,
801
+ error: errorParse?.literal ?? null,
807
802
  importedZodNames
808
803
  };
809
804
  }
810
805
  /**
811
806
  * Prints the `validator: { … }` entry of a call config from the hooks named in `keys`, or `null` when none is set.
807
+ * The entry spreads `config.validator` last, so a per-call hook overrides the generated one for its key only.
812
808
  */
813
809
  function buildValidatorLiteral(hooks, keys) {
814
810
  const entries = keys.flatMap((key) => hooks?.[key] ? [`${key}: ${hooks[key]}`] : []);
815
- return entries.length ? `validator: { ${entries.join(", ")} }` : null;
811
+ return entries.length ? `validator: { ${entries.join(", ")}, ...config.validator }` : null;
816
812
  }
817
813
  // ../../internals/client/src/builders/contentType.ts
818
814
  /**
@@ -865,13 +861,13 @@ function serializeParameter(parameter) {
865
861
  return parts.length > 0 ? `{ ${parts.join(", ")} }` : null;
866
862
  }
867
863
  /**
868
- * Serializes the `encoding` of the request body's default content type into a `{ property: { ... } }`
869
- * literal, or `null` when it carries none. Only an operation with a single request content type
864
+ * Serializes the `encoding` of the request body's default content type into `property: { ... }`
865
+ * entries, empty when it carries none. Only an operation with a single request content type
870
866
  * emits it, because the runtime applies `styles.body` to whichever type the caller selects.
871
867
  */
872
868
  function serializeBodyEncoding(node) {
873
869
  const content = node.requestBody?.content;
874
- const entries = Object.entries(content?.length === 1 ? content[0]?.encoding ?? {} : {}).map(([property, { contentType, style, explode, allowReserved }]) => {
870
+ return Object.entries(content?.length === 1 ? content[0]?.encoding ?? {} : {}).map(([property, { contentType, style, explode, allowReserved }]) => {
875
871
  const parts = [
876
872
  style && `style: ${JSON.stringify(style)}`,
877
873
  explode !== void 0 && `explode: ${explode}`,
@@ -880,7 +876,6 @@ function serializeBodyEncoding(node) {
880
876
  ].filter(Boolean);
881
877
  return `${isValidVarName(property) ? property : JSON.stringify(property)}: { ${parts.join(", ")} }`;
882
878
  });
883
- return entries.length > 0 ? `body: { ${entries.join(", ")} }` : null;
884
879
  }
885
880
  /**
886
881
  * Builds the per-operation `styles` literal from the operation's parameters, grouped by location.
@@ -890,26 +885,31 @@ function serializeBodyEncoding(node) {
890
885
  * is unchanged. A form request body adds a `body` group keyed by property name from its `encoding`.
891
886
  * Returns `null` when nothing carries metadata.
892
887
  *
888
+ * With `merge`, the literal spreads `config.styles` per parameter, so a per-call entry overrides the generated one for
889
+ * that parameter and leaves the others in place.
890
+ *
893
891
  * @example
894
892
  * ```ts
895
893
  * // a path param with { style: 'matrix', explode: true } and a query param with { explode: false }
896
894
  * buildStyles({ node }) // "{ path: { id: { style: 'matrix', explode: true } }, query: { tags: { explode: false } } }"
897
895
  * ```
898
896
  */
899
- function buildStyles({ node }) {
897
+ function buildStyles({ node, merge }) {
900
898
  if (!ast.isHttpOperationNode(node)) return null;
901
899
  const groups = {
902
900
  path: [],
903
901
  query: [],
904
902
  header: [],
905
- cookie: []
903
+ cookie: [],
904
+ body: serializeBodyEncoding(node)
906
905
  };
907
906
  for (const [location, parameters] of Object.entries(getOperationParameters(node))) for (const parameter of parameters) {
908
907
  const literal = serializeParameter(parameter);
909
908
  if (literal) groups[location].push(`${toKey(parameter.name)}: ${literal}`);
910
909
  }
911
- const entries = [...Object.keys(groups).filter((location) => groups[location].length > 0).map((location) => `${location}: { ${groups[location].join(", ")} }`), serializeBodyEncoding(node)].filter(Boolean);
912
- return entries.length > 0 ? `{ ${entries.join(", ")} }` : null;
910
+ const entries = Object.entries(groups).filter(([, items]) => items.length > 0).map(([location, items]) => `${location}: { ${(merge ? [...items, `...config.styles?.${location}`] : items).join(", ")} }`);
911
+ if (entries.length === 0) return null;
912
+ return `{ ${(merge ? ["...config.styles", ...entries] : entries).join(", ")} }`;
913
913
  }
914
914
  // ../../internals/client/src/builders/callConfig.ts
915
915
  /**
@@ -925,7 +925,9 @@ function buildResponseTypeLiteral(node) {
925
925
  }
926
926
  /**
927
927
  * Builds the call config literal a generated operation forwards to the client, shared by the standalone
928
- * functions and the SDK methods. The `throwOnError` fallback is applied after the `...config` spread.
928
+ * functions and the SDK methods. The `validator` and `throwOnError` entries come after the `...config` spread, so a
929
+ * per-call `validator` is merged per key with the generated one instead of replacing it. `styles` is merged the same
930
+ * way, per parameter, unless `returnType` is `'plain'`.
929
931
  *
930
932
  * `mergeContentType` is `true` when the caller must destructure `contentType` from `options`, and
931
933
  * `eventStream` is `true` when the operation streams `text/event-stream` or JSON Lines. Unless `returnType` is `'plain'`, a
@@ -934,16 +936,20 @@ function buildResponseTypeLiteral(node) {
934
936
  function buildCallConfig({ node, validatorHooks, security, throwOnErrorDefault, returnType }) {
935
937
  const eventStream = isEventStream(node);
936
938
  const securityLiteral = buildSecurityMetadata({ security });
937
- const stylesLiteral = buildStyles({ node });
939
+ const ownRuntime = returnType !== "plain";
940
+ const stylesLiteral = buildStyles({
941
+ node,
942
+ merge: ownRuntime
943
+ });
944
+ const styles = stylesLiteral ? `styles: ${stylesLiteral}` : null;
938
945
  const validatorLiteral = buildValidatorLiteral(validatorHooks, [
939
946
  "request",
940
947
  "path",
941
948
  "query",
942
949
  "headers",
943
950
  "cookies",
944
- ...eventStream && returnType !== "plain" ? [] : ["response"],
945
- "error",
946
- "errorStatus"
951
+ ...eventStream && ownRuntime ? [] : ["response"],
952
+ "error"
947
953
  ]);
948
954
  const { literal: contentTypeLiteral, merge: mergeContentType } = buildContentType({ node });
949
955
  return {
@@ -951,11 +957,12 @@ function buildCallConfig({ node, validatorHooks, security, throwOnErrorDefault,
951
957
  `method: '${node.method.toUpperCase()}'`,
952
958
  `url: '${node.path}'`,
953
959
  securityLiteral ? `security: ${securityLiteral}` : null,
954
- stylesLiteral ? `styles: ${stylesLiteral}` : null,
955
- validatorLiteral,
960
+ ownRuntime ? null : styles,
956
961
  contentTypeLiteral,
957
962
  buildResponseTypeLiteral(node),
958
963
  "...config",
964
+ ownRuntime ? styles : null,
965
+ validatorLiteral,
959
966
  `throwOnError: config.throwOnError ?? ${throwOnErrorDefault}`
960
967
  ].filter(Boolean).join(", ")} }`,
961
968
  mergeContentType,