@kubb/plugin-fetch 5.0.0-beta.95 → 5.0.0-beta.98

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
@@ -27,8 +27,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  let node_path = require("node:path");
28
28
  node_path = __toESM(node_path, 1);
29
29
  let kubb_kit = require("kubb/kit");
30
- let kubb_jsx = require("kubb/jsx");
31
30
  let _kubb_plugin_ts = require("@kubb/plugin-ts");
31
+ let kubb_jsx = require("kubb/jsx");
32
32
  let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
33
33
  let _kubb_plugin_zod = require("@kubb/plugin-zod");
34
34
  let node_url = require("node:url");
@@ -594,64 +594,65 @@ function createGroupConfig(group) {
594
594
  };
595
595
  }
596
596
  //#endregion
597
- //#region ../../internals/client/src/builders/validatorOptions.ts
598
- /**
599
- * Returns `true` when any direction of the validator uses zod (used for dependency checks).
600
- */
601
- function isValidatorEnabled(validator) {
602
- if (!validator) return false;
603
- if (validator === "zod") return true;
604
- return Boolean(validator.request || validator.response);
605
- }
606
- /**
607
- * Returns `'zod'` when request body parsing is enabled, `null` otherwise. The string shorthand
608
- * `'zod'` validates the response only, so it does not enable request parsing.
609
- */
610
- function resolveRequestValidator(validator) {
611
- if (!validator || validator === "zod") return null;
612
- return validator.request ?? null;
613
- }
614
- /**
615
- * Returns `'zod'` when query-parameters parsing is enabled, `null` otherwise. Only the object form
616
- * `{ request: 'zod' }` enables it.
617
- */
618
- function resolveQueryParamsValidator(validator) {
619
- if (!validator || validator === "zod") return null;
620
- return validator.request ?? null;
621
- }
597
+ //#region ../../internals/client/src/builders/paramsRemap.ts
622
598
  /**
623
- * Returns `'zod'` when response parsing is enabled, `null` otherwise. The string shorthand `'zod'`
624
- * maps to response parsing.
599
+ * Builds the call-config entries that rename the camelCased `query` and `headers` keys back to the
600
+ * names the OpenAPI document declares, so the wire format follows the spec while the generated
601
+ * types keep camelCase keys. Returns an empty array when no name changes. Path parameters need no
602
+ * remap because the URL template placeholders are renamed in sync with the `path` keys. Emit the
603
+ * entries after the `...config` spread so they override the camelCased groups the caller passes in.
604
+ *
605
+ * @example
606
+ * ```ts
607
+ * // a query param named include_deleted in the spec
608
+ * buildParamsRemap({ node }) // ['query: config.query ? { "include_deleted": config.query.includeDeleted } : config.query']
609
+ * ```
625
610
  */
626
- function resolveResponseValidator(validator) {
627
- if (!validator) return null;
628
- if (validator === "zod") return "zod";
629
- return validator.response ?? null;
611
+ function buildParamsRemap({ node }) {
612
+ if (!kubb_kit.ast.isHttpOperationNode(node)) return [];
613
+ const original = getOperationParameters(node, { paramsCasing: "original" });
614
+ const cased = getOperationParameters(node);
615
+ const queryMapping = buildParamsMapping(original.query, cased.query);
616
+ const headerMapping = buildParamsMapping(original.header, cased.header);
617
+ const entries = [];
618
+ if (queryMapping) entries.push(`query: ${buildParamsRemapExpression({
619
+ source: "config.query",
620
+ mapping: queryMapping
621
+ })}`);
622
+ if (headerMapping) entries.push(`headers: ${buildParamsRemapExpression({
623
+ source: "config.headers",
624
+ mapping: headerMapping
625
+ })}`);
626
+ return entries;
630
627
  }
628
+ //#endregion
629
+ //#region ../../internals/client/src/builders/generics.ts
631
630
  /**
632
- * Resolves the zod expression a generated client validates a success response with. Only success
633
- * (2xx) bodies reach the parse under the throw-on-error contract, so the success-only
634
- * `<operation>ResponseSchema` is used; error bodies are never zod-parsed.
631
+ * Builds the `RequestResult` generic arguments for one operation: the plugin-ts per-status responses
632
+ * record plus the per-call `ThrowOnError` flag. `SuccessOf` / `ErrorOf` split the record inside the
633
+ * runtime, so this only names the record and threads `ThrowOnError`.
634
+ *
635
+ * @example
636
+ * `buildRequestResultGenerics({ node, tsResolver }) // 'AddPetResponses, ThrowOnError'`
635
637
  */
636
- function buildZodResponseParse(node, zodResolver) {
637
- const name = zodResolver.response.response(node);
638
- return name ? {
639
- expression: name,
640
- importNames: [name]
641
- } : null;
638
+ function buildRequestResultGenerics({ node, tsResolver }) {
639
+ return `${tsResolver.response.responses(node)}, ThrowOnError`;
642
640
  }
641
+ //#endregion
642
+ //#region ../../internals/client/src/builders/returnStatement.ts
643
643
  /**
644
- * Resolves the zod expression a generated client validates an error body with on the non-throw path.
645
- * Uses the error-only `<operation>ErrorSchema` (the union of non-2xx statuses); returns `null` when the
646
- * operation documents no error responses with a schema.
644
+ * Builds the return statement of a generated operation function. The runtime call already resolves
645
+ * to `{ data, error, request, response }`; the generated code forwards that result and casts it to
646
+ * the operation's `RequestResult`, which carries the `throwOnError` discrimination.
647
+ *
648
+ * @example
649
+ * `return request({ method: 'POST', url: '/pet', ...config }) as Promise<RequestResult<AddPetResponses, ThrowOnError>>`
647
650
  */
648
- function buildZodErrorParse(node, zodResolver) {
649
- if (!node.responses.some((res) => !isSuccessStatusCode(res.statusCode) && res.content?.some((entry) => entry.schema))) return null;
650
- const name = zodResolver.response.error?.(node);
651
- return name ? {
652
- expression: name,
653
- importNames: [name]
654
- } : null;
651
+ function buildReturnStatement({ node, tsResolver, callConfig }) {
652
+ return `return request(${callConfig}) as Promise<RequestResult<${buildRequestResultGenerics({
653
+ node,
654
+ tsResolver
655
+ })}>>`;
655
656
  }
656
657
  //#endregion
657
658
  //#region ../../internals/client/src/builders/security.ts
@@ -722,67 +723,6 @@ function buildSecurityMetadata({ security }) {
722
723
  return `[${security.map(serializeAuth).join(", ")}]`;
723
724
  }
724
725
  //#endregion
725
- //#region ../../internals/client/src/builders/paramsRemap.ts
726
- /**
727
- * Builds the call-config entries that rename the camelCased `query` and `headers` keys back to the
728
- * names the OpenAPI document declares, so the wire format follows the spec while the generated
729
- * types keep camelCase keys. Returns an empty array when no name changes. Path parameters need no
730
- * remap because the URL template placeholders are renamed in sync with the `path` keys. Emit the
731
- * entries after the `...config` spread so they override the camelCased groups the caller passes in.
732
- *
733
- * @example
734
- * ```ts
735
- * // a query param named include_deleted in the spec
736
- * buildParamsRemap({ node }) // ['query: config.query ? { "include_deleted": config.query.includeDeleted } : config.query']
737
- * ```
738
- */
739
- function buildParamsRemap({ node }) {
740
- if (!kubb_kit.ast.isHttpOperationNode(node)) return [];
741
- const original = getOperationParameters(node, { paramsCasing: "original" });
742
- const cased = getOperationParameters(node);
743
- const queryMapping = buildParamsMapping(original.query, cased.query);
744
- const headerMapping = buildParamsMapping(original.header, cased.header);
745
- const entries = [];
746
- if (queryMapping) entries.push(`query: ${buildParamsRemapExpression({
747
- source: "config.query",
748
- mapping: queryMapping
749
- })}`);
750
- if (headerMapping) entries.push(`headers: ${buildParamsRemapExpression({
751
- source: "config.headers",
752
- mapping: headerMapping
753
- })}`);
754
- return entries;
755
- }
756
- //#endregion
757
- //#region ../../internals/client/src/builders/generics.ts
758
- /**
759
- * Builds the `RequestResult` generic arguments for one operation: the plugin-ts per-status responses
760
- * record plus the per-call `ThrowOnError` flag. `SuccessOf` / `ErrorOf` split the record inside the
761
- * runtime, so this only names the record and threads `ThrowOnError`.
762
- *
763
- * @example
764
- * `buildRequestResultGenerics({ node, tsResolver }) // 'AddPetResponses, ThrowOnError'`
765
- */
766
- function buildRequestResultGenerics({ node, tsResolver }) {
767
- return `${tsResolver.response.responses(node)}, ThrowOnError`;
768
- }
769
- //#endregion
770
- //#region ../../internals/client/src/builders/returnStatement.ts
771
- /**
772
- * Builds the return statement of a generated operation function. The runtime call already resolves
773
- * to `{ data, error, request, response }`; the generated code forwards that result and casts it to
774
- * the operation's `RequestResult`, which carries the `throwOnError` discrimination.
775
- *
776
- * @example
777
- * `return request({ method: 'POST', url: '/pet', ...config }) as Promise<RequestResult<AddPetResponses, ThrowOnError>>`
778
- */
779
- function buildReturnStatement({ node, tsResolver, callConfig }) {
780
- return `return request(${callConfig}) as Promise<RequestResult<${buildRequestResultGenerics({
781
- node,
782
- tsResolver
783
- })}>>`;
784
- }
785
- //#endregion
786
726
  //#region ../../internals/client/src/builders/signature.ts
787
727
  const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
788
728
  /**
@@ -814,6 +754,152 @@ function buildGroupedOptionsSignature({ node, tsResolver }) {
814
754
  };
815
755
  }
816
756
  //#endregion
757
+ //#region ../../internals/client/src/builders/validatorOptions.ts
758
+ /**
759
+ * Returns `true` when any direction of the validator uses zod (used for dependency checks).
760
+ */
761
+ function isValidatorEnabled(validator) {
762
+ if (!validator) return false;
763
+ if (validator === "zod") return true;
764
+ return Boolean(validator.request || validator.response);
765
+ }
766
+ /**
767
+ * Returns `'zod'` when request body parsing is enabled, `null` otherwise. The string shorthand
768
+ * `'zod'` validates the response only, so it does not enable request parsing.
769
+ */
770
+ function resolveRequestValidator(validator) {
771
+ if (!validator || validator === "zod") return null;
772
+ return validator.request ?? null;
773
+ }
774
+ /**
775
+ * Returns `'zod'` when query-parameters parsing is enabled, `null` otherwise. Only the object form
776
+ * `{ request: 'zod' }` enables it.
777
+ */
778
+ function resolveQueryParamsValidator(validator) {
779
+ if (!validator || validator === "zod") return null;
780
+ return validator.request ?? null;
781
+ }
782
+ /**
783
+ * Returns `'zod'` when response parsing is enabled, `null` otherwise. The string shorthand `'zod'`
784
+ * maps to response parsing.
785
+ */
786
+ function resolveResponseValidator(validator) {
787
+ if (!validator) return null;
788
+ if (validator === "zod") return "zod";
789
+ return validator.response ?? null;
790
+ }
791
+ /**
792
+ * Resolves the zod expression a generated client validates a success response with. Only success
793
+ * (2xx) bodies reach the parse under the throw-on-error contract, so the success-only
794
+ * `<operation>ResponseSchema` is used; error bodies are never zod-parsed.
795
+ */
796
+ function buildZodResponseParse(node, zodResolver) {
797
+ const name = zodResolver.response.response(node);
798
+ return name ? {
799
+ expression: name,
800
+ importNames: [name]
801
+ } : null;
802
+ }
803
+ /**
804
+ * Resolves the zod expression a generated client validates an error body with on the non-throw path.
805
+ * Uses the error-only `<operation>ErrorSchema` (the union of non-2xx statuses); returns `null` when the
806
+ * operation documents no error responses with a schema.
807
+ */
808
+ function buildZodErrorParse(node, zodResolver) {
809
+ if (!node.responses.some((res) => !isSuccessStatusCode(res.statusCode) && res.content?.some((entry) => entry.schema))) return null;
810
+ const name = zodResolver.response.error?.(node);
811
+ return name ? {
812
+ expression: name,
813
+ importNames: [name]
814
+ } : null;
815
+ }
816
+ //#endregion
817
+ //#region ../../internals/client/src/builders/validator.ts
818
+ /**
819
+ * Builds the validator-hook references for one operation. Request validation runs before the send;
820
+ * response validation runs on the success body only. Returns `null` references when the matching
821
+ * direction is disabled or the schema is absent.
822
+ */
823
+ function buildValidatorHooks({ node, validator, zodResolver }) {
824
+ const importedZodNames = [];
825
+ const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
826
+ const zodRequestName = zodResolver && resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.response.body(node) : null;
827
+ const request = zodRequestName ?? null;
828
+ if (zodRequestName) importedZodNames.push(zodRequestName);
829
+ const responseParse = zodResolver && resolveResponseValidator(validator) === "zod" ? buildZodResponseParse(node, zodResolver) : null;
830
+ const response = responseParse ? responseParse.expression : null;
831
+ if (responseParse) importedZodNames.push(...responseParse.importNames);
832
+ const errorParse = zodResolver && resolveResponseValidator(validator) === "zod" ? buildZodErrorParse(node, zodResolver) : null;
833
+ const error = errorParse ? errorParse.expression : null;
834
+ if (errorParse) importedZodNames.push(...errorParse.importNames);
835
+ return {
836
+ request,
837
+ response,
838
+ error,
839
+ importedZodNames
840
+ };
841
+ }
842
+ //#endregion
843
+ //#region ../../internals/client/src/builders/sdkMethod.ts
844
+ /**
845
+ * Builds the call config literal forwarded to the contract client, mirroring the shared `Operation`
846
+ * component: `{ method, url, security?, validator?, ...config }`. The `...config` spread carries every
847
+ * per-call field (including `throwOnError`), so the method stays a thin wrapper over the contract.
848
+ */
849
+ function buildCallConfig({ node, validator, zodResolver, security }) {
850
+ const validators = buildValidatorHooks({
851
+ node,
852
+ validator,
853
+ zodResolver
854
+ });
855
+ const validatorEntries = [validators.request ? `request: ${validators.request}` : null, validators.response ? `response: ${validators.response}` : null].filter(Boolean);
856
+ const validatorLiteral = validatorEntries.length ? `validator: { ${validatorEntries.join(", ")} }` : null;
857
+ const securityLiteral = buildSecurityMetadata({ security });
858
+ return `{ ${[
859
+ `method: '${node.method.toUpperCase()}'`,
860
+ `url: '${Url.toCasedTemplate(node.path, { casing: "camelcase" })}'`,
861
+ securityLiteral ? `security: ${securityLiteral}` : null,
862
+ validatorLiteral,
863
+ "...config",
864
+ ...buildParamsRemap({ node })
865
+ ].filter(Boolean).join(", ")} }`;
866
+ }
867
+ /**
868
+ * Builds a single instance method for a generated SDK class. The body forwards the single grouped
869
+ * `options` object to the instance's own client (`this.client`, built once in the constructor) and
870
+ * returns the `RequestResult`. A per-call `options.client` still overrides the instance client, so
871
+ * one operation can be routed to a different environment without a new instance.
872
+ */
873
+ function buildSdkMethod({ node, name, tsResolver, zodResolver, validator, security }) {
874
+ if (!kubb_kit.ast.isHttpOperationNode(node)) return "";
875
+ const signature = buildGroupedOptionsSignature({
876
+ node,
877
+ tsResolver
878
+ });
879
+ const returnStatement = buildReturnStatement({
880
+ node,
881
+ tsResolver,
882
+ callConfig: buildCallConfig({
883
+ node,
884
+ validator,
885
+ zodResolver,
886
+ security
887
+ })
888
+ });
889
+ const generics = signature.generics.length ? `<${signature.generics.join(", ")}>` : "";
890
+ const jsdoc = buildJSDoc(buildOperationComments(node, {
891
+ link: "urlPath",
892
+ linkPosition: "beforeDeprecated",
893
+ splitLines: true
894
+ }));
895
+ const methodBody = [
896
+ "const { client: request = this.client, ...config } = options",
897
+ "",
898
+ returnStatement
899
+ ].map((line) => line ? ` ${line}` : "").join("\n");
900
+ return `${jsdoc} public ${name}${generics}(${signature.paramsSignature}): ${signature.returnType} {\n${methodBody}\n }`;
901
+ }
902
+ //#endregion
817
903
  //#region ../../internals/client/src/builders/styles.ts
818
904
  /**
819
905
  * Renders a parameter name as an object-literal key, quoted when it is not a bare identifier.
@@ -867,32 +953,6 @@ function buildStyles({ node }) {
867
953
  return `{ ${locations.map((location) => `${location}: { ${groups[location].join(", ")} }`).join(", ")} }`;
868
954
  }
869
955
  //#endregion
870
- //#region ../../internals/client/src/builders/validator.ts
871
- /**
872
- * Builds the validator-hook references for one operation. Request validation runs before the send;
873
- * response validation runs on the success body only. Returns `null` references when the matching
874
- * direction is disabled or the schema is absent.
875
- */
876
- function buildValidatorHooks({ node, validator, zodResolver }) {
877
- const importedZodNames = [];
878
- const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
879
- const zodRequestName = zodResolver && resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.response.body(node) : null;
880
- const request = zodRequestName ?? null;
881
- if (zodRequestName) importedZodNames.push(zodRequestName);
882
- const responseParse = zodResolver && resolveResponseValidator(validator) === "zod" ? buildZodResponseParse(node, zodResolver) : null;
883
- const response = responseParse ? responseParse.expression : null;
884
- if (responseParse) importedZodNames.push(...responseParse.importNames);
885
- const errorParse = zodResolver && resolveResponseValidator(validator) === "zod" ? buildZodErrorParse(node, zodResolver) : null;
886
- const error = errorParse ? errorParse.expression : null;
887
- if (errorParse) importedZodNames.push(...errorParse.importNames);
888
- return {
889
- request,
890
- response,
891
- error,
892
- importedZodNames
893
- };
894
- }
895
- //#endregion
896
956
  //#region ../../internals/client/src/components/Operation.tsx
897
957
  /**
898
958
  * Renders one client operation: the grouped `<Name>Request` type and the function that forwards a
@@ -967,66 +1027,6 @@ function Operation({ name, node, tsResolver, zodResolver, validator, security, i
967
1027
  });
968
1028
  }
969
1029
  //#endregion
970
- //#region ../../internals/client/src/builders/sdkMethod.ts
971
- /**
972
- * Builds the call config literal forwarded to the contract client, mirroring the shared `Operation`
973
- * component: `{ method, url, security?, validator?, ...config }`. The `...config` spread carries every
974
- * per-call field (including `throwOnError`), so the method stays a thin wrapper over the contract.
975
- */
976
- function buildCallConfig({ node, validator, zodResolver, security }) {
977
- const validators = buildValidatorHooks({
978
- node,
979
- validator,
980
- zodResolver
981
- });
982
- const validatorEntries = [validators.request ? `request: ${validators.request}` : null, validators.response ? `response: ${validators.response}` : null].filter(Boolean);
983
- const validatorLiteral = validatorEntries.length ? `validator: { ${validatorEntries.join(", ")} }` : null;
984
- const securityLiteral = buildSecurityMetadata({ security });
985
- return `{ ${[
986
- `method: '${node.method.toUpperCase()}'`,
987
- `url: '${Url.toCasedTemplate(node.path, { casing: "camelcase" })}'`,
988
- securityLiteral ? `security: ${securityLiteral}` : null,
989
- validatorLiteral,
990
- "...config",
991
- ...buildParamsRemap({ node })
992
- ].filter(Boolean).join(", ")} }`;
993
- }
994
- /**
995
- * Builds a single instance method for a generated SDK class. The body forwards the single grouped
996
- * `options` object to the instance's own client (`this.client`, built once in the constructor) and
997
- * returns the `RequestResult`. A per-call `options.client` still overrides the instance client, so
998
- * one operation can be routed to a different environment without a new instance.
999
- */
1000
- function buildSdkMethod({ node, name, tsResolver, zodResolver, validator, security }) {
1001
- if (!kubb_kit.ast.isHttpOperationNode(node)) return "";
1002
- const signature = buildGroupedOptionsSignature({
1003
- node,
1004
- tsResolver
1005
- });
1006
- const returnStatement = buildReturnStatement({
1007
- node,
1008
- tsResolver,
1009
- callConfig: buildCallConfig({
1010
- node,
1011
- validator,
1012
- zodResolver,
1013
- security
1014
- })
1015
- });
1016
- const generics = signature.generics.length ? `<${signature.generics.join(", ")}>` : "";
1017
- const jsdoc = buildJSDoc(buildOperationComments(node, {
1018
- link: "urlPath",
1019
- linkPosition: "beforeDeprecated",
1020
- splitLines: true
1021
- }));
1022
- const methodBody = [
1023
- "const { client: request = this.client, ...config } = options",
1024
- "",
1025
- returnStatement
1026
- ].map((line) => line ? ` ${line}` : "").join("\n");
1027
- return `${jsdoc} public ${name}${generics}(${signature.paramsSignature}): ${signature.returnType} {\n${methodBody}\n }`;
1028
- }
1029
- //#endregion
1030
1030
  //#region ../../internals/client/src/components/SdkClient.tsx
1031
1031
  /**
1032
1032
  * Renders one instance class per tag with one method per operation. The constructor takes a client