@kubb/plugin-vue-query 5.0.0-beta.94 → 5.0.0-beta.95

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
@@ -1,4 +1,4 @@
1
- import "./rolldown-runtime-C0LytTxp.js";
1
+ import { t as __name } from "./rolldown-runtime-C0LytTxp.js";
2
2
  import { Resolver, ast, createResolver, defineGenerator, definePlugin } from "kubb/kit";
3
3
  import { createFunctionParameter, createFunctionParameters, createObjectBindingPattern, createTypeLiteral, functionPrinter, pluginTsName } from "@kubb/plugin-ts";
4
4
  import { File, Function, Type, jsxRenderer } from "kubb/jsx";
@@ -30,6 +30,16 @@ function toCamelOrPascal(text, pascal) {
30
30
  function camelCase(text, { prefix = "", suffix = "" } = {}) {
31
31
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
32
32
  }
33
+ /**
34
+ * Uppercases only the first character of `text`, leaving the rest untouched.
35
+ * Unlike {@link pascalCase} it never re-splits word boundaries or strips characters.
36
+ *
37
+ * @example
38
+ * `capitalize('getPetById') // 'GetPetById'`
39
+ */
40
+ function capitalize(text) {
41
+ return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
42
+ }
33
43
  //#endregion
34
44
  //#region ../../internals/utils/src/reserved.ts
35
45
  /**
@@ -533,39 +543,12 @@ function createGroupConfig(group) {
533
543
  };
534
544
  }
535
545
  //#endregion
536
- //#region ../../internals/tanstack-query/src/components/MutationKey.tsx
537
- const declarationPrinter$7 = functionPrinter({ mode: "declaration" });
538
- const mutationKeyTransformer = ({ node }) => {
539
- if (!node.path) return [];
540
- return [`{ url: '${Url.toPath(node.path)}' }`];
541
- };
542
- function MutationKey({ name, node, transformer }) {
543
- const paramsNode = createFunctionParameters({ params: [] });
544
- const paramsSignature = declarationPrinter$7.print(paramsNode) ?? "";
545
- const keys = (transformer ?? mutationKeyTransformer)({
546
- node,
547
- casing: "camelcase"
548
- });
549
- return /* @__PURE__ */ jsx(File.Source, {
550
- name,
551
- isExportable: true,
552
- isIndexable: true,
553
- children: /* @__PURE__ */ jsx(Function.Arrow, {
554
- name,
555
- export: true,
556
- params: paramsSignature,
557
- singleLine: true,
558
- children: `[${keys.join(", ")}] as const`
559
- })
560
- });
561
- }
562
- //#endregion
563
546
  //#region ../../internals/tanstack-query/src/utils.ts
564
547
  /**
565
548
  * The grouped request options, ordered for both the destructured signature and the
566
549
  * call passed to the underlying client.
567
550
  */
568
- const requestGroupOrder$1 = [
551
+ const requestGroupOrder = [
569
552
  "path",
570
553
  "query",
571
554
  "body",
@@ -596,7 +579,7 @@ function maybeRefOrGetter(type) {
596
579
  * `MaybeRefOrGetter` per group.
597
580
  */
598
581
  function buildGroupedRequestParam(node, options) {
599
- const { resolver, keys = requestGroupOrder$1, memberTypeWrapper } = options;
582
+ const { resolver, keys = requestGroupOrder, memberTypeWrapper } = options;
600
583
  const { groups, hasRequiredPath, hasRequiredQuery, hasRequiredHeader } = getRequestGroupOptionality(node);
601
584
  const names = keys.filter((key) => groups[key]);
602
585
  if (names.length === 0) return null;
@@ -608,7 +591,7 @@ function buildGroupedRequestParam(node, options) {
608
591
  };
609
592
  const isOptional = names.every((name) => !requiredByGroup[name]);
610
593
  const optionsName = resolver.response.options(node);
611
- const omittedKeys = requestGroupOrder$1.filter((key) => !keys.includes(key));
594
+ const omittedKeys = requestGroupOrder.filter((key) => !keys.includes(key));
612
595
  const optionsType = omittedKeys.length > 0 ? `Omit<${optionsName}, ${omittedKeys.map((key) => `'${key}'`).join(" | ")}>` : optionsName;
613
596
  if (memberTypeWrapper) {
614
597
  const members = names.map((name) => ({
@@ -647,6 +630,273 @@ function buildQueryOptionsParams(node, options) {
647
630
  default: "{}"
648
631
  })].filter((param) => param !== null) });
649
632
  }
633
+ /**
634
+ * Builds the call to a client `<op>` function inside a query/mutation hook body. The function takes
635
+ * a single grouped options object, so the operation's request groups are passed as
636
+ * shorthand alongside the spread `config`, with `throwOnError: true` pinned last so a caller's config
637
+ * can't flip the query's error semantics. Queries thread the TanStack `signal`; mutations omit it.
638
+ *
639
+ * When `unwrapName` is set, each request group is passed as an explicit member unwrapped through it,
640
+ * used by vue-query to resolve refs and getters with `toValue(...)` at call time.
641
+ *
642
+ * @example
643
+ * ```ts
644
+ * buildClientCall(node, { clientName: 'getPetById', signal: true })
645
+ * // getPetById({ path, ...config, signal: config.signal ?? signal, throwOnError: true })
646
+ * ```
647
+ */
648
+ function buildClientCall(node, options) {
649
+ const { clientName, signal = false, unwrapName } = options;
650
+ const { groups } = getRequestGroupOptionality(node);
651
+ return `${clientName}({ ${[
652
+ "...config",
653
+ ...requestGroupOrder.filter((key) => groups[key]).map((name) => unwrapName ? `${name}: ${unwrapName(name)}` : name),
654
+ signal ? "signal: config.signal ?? signal" : null,
655
+ "throwOnError: true"
656
+ ].filter((part) => part !== null).join(", ")} })`;
657
+ }
658
+ /**
659
+ * Builds the `TData` / `TError` type expressions shared by every generated hook, joining the resolved
660
+ * success responses into `TData` and wrapping the error responses in `ResponseErrorConfig<...>`.
661
+ */
662
+ function buildResponseTypes(node, resolver) {
663
+ const successNames = resolveSuccessNames(node, resolver);
664
+ const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
665
+ const errorNames = resolveErrorNames(node, resolver);
666
+ return {
667
+ TData: responseName,
668
+ TError: `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`
669
+ };
670
+ }
671
+ function resolveFallbackPageParamType(initialPageParam) {
672
+ if (typeof initialPageParam === "number") return "number";
673
+ if (typeof initialPageParam === "boolean") return "boolean";
674
+ if (typeof initialPageParam !== "string") return "unknown";
675
+ if (!initialPageParam.includes(" as ")) return "string";
676
+ return initialPageParam.split(" as ").at(-1) ?? "unknown";
677
+ }
678
+ /**
679
+ * Resolves the `TPageParam` generic for the infinite-query hooks. Prefers the type read from the
680
+ * configured `queryParam` on the operation's query object, and falls back to the type inferred from
681
+ * `initialPageParam` when that parameter type is unavailable. Also returns the query params type name
682
+ * so callers can reuse it when rewriting the paginated request.
683
+ */
684
+ function resolvePageParamType(node, { resolver, initialPageParam, queryParam }) {
685
+ const firstQueryParam = getOperationParameters(node, { paramsCasing: "original" }).query[0];
686
+ const groupName = firstQueryParam ? resolver.param.query(node, firstQueryParam) : null;
687
+ const queryParamsTypeName = groupName !== (firstQueryParam ? resolver.param.name(node, firstQueryParam) : null) ? groupName : null;
688
+ const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
689
+ if (!queryParamType) return {
690
+ queryParamsTypeName,
691
+ pageParamType: resolveFallbackPageParamType(initialPageParam)
692
+ };
693
+ return {
694
+ queryParamsTypeName,
695
+ pageParamType: initialPageParam !== void 0 && initialPageParam !== null ? `NonNullable<${queryParamType}>` : queryParamType
696
+ };
697
+ }
698
+ /**
699
+ * Applies the shared query defaults during plugin setup: `false` disables query generation, and an
700
+ * object merges over `methods: ['GET']` and the plugin's runtime `importPath`.
701
+ */
702
+ function resolveQueryConfig(query, options) {
703
+ if (query === false) return false;
704
+ return {
705
+ importPath: options.importPath,
706
+ methods: ["GET"],
707
+ ...query
708
+ };
709
+ }
710
+ /**
711
+ * Applies the shared mutation defaults during plugin setup: `false` disables mutation generation,
712
+ * and an object merges over `methods: ['POST', 'PUT', 'PATCH', 'DELETE']` and the plugin's runtime
713
+ * `importPath`.
714
+ */
715
+ function resolveMutationConfig(mutation, options) {
716
+ if (mutation === false) return false;
717
+ return {
718
+ importPath: options.importPath,
719
+ methods: [
720
+ "POST",
721
+ "PUT",
722
+ "PATCH",
723
+ "DELETE"
724
+ ],
725
+ ...mutation
726
+ };
727
+ }
728
+ /**
729
+ * Applies the shared infinite-query defaults during plugin setup: a falsy value disables infinite
730
+ * queries, and an object merges over `queryParam: 'id'` and `initialPageParam: 0` with the cursor
731
+ * paths cleared.
732
+ */
733
+ function resolveInfiniteConfig(infinite) {
734
+ if (!infinite) return false;
735
+ return {
736
+ queryParam: "id",
737
+ initialPageParam: 0,
738
+ cursorParam: null,
739
+ nextParam: null,
740
+ previousParam: null,
741
+ ...infinite
742
+ };
743
+ }
744
+ //#endregion
745
+ //#region ../../internals/tanstack-query/src/components/InfiniteQueryOptions.tsx
746
+ const declarationPrinter$7 = functionPrinter({ mode: "declaration" });
747
+ const callPrinter$4 = functionPrinter({ mode: "call" });
748
+ function InfiniteQueryOptions$1({ name, clientName, initialPageParam, cursorParam, nextParam, previousParam, node, tsResolver, queryParam, queryKeyName, queryKeyType = "typeof queryKey", memberTypeWrapper, unwrapName }) {
749
+ const { TData: queryFnDataType, TError: errorType } = buildResponseTypes(node, tsResolver);
750
+ const { queryParamsTypeName, pageParamType } = resolvePageParamType(node, {
751
+ resolver: tsResolver,
752
+ initialPageParam,
753
+ queryParam
754
+ });
755
+ const groupedKeyParam = buildGroupedRequestParam(node, {
756
+ resolver: tsResolver,
757
+ keys: [
758
+ "path",
759
+ "query",
760
+ "body"
761
+ ],
762
+ memberTypeWrapper
763
+ });
764
+ const queryKeyParamsNode = createFunctionParameters({ params: groupedKeyParam ? [groupedKeyParam] : [] });
765
+ const queryKeyParamsCall = callPrinter$4.print(queryKeyParamsNode) ?? "";
766
+ const paramsNode = buildQueryOptionsParams(node, {
767
+ resolver: tsResolver,
768
+ memberTypeWrapper
769
+ });
770
+ const paramsSignature = declarationPrinter$7.print(paramsNode) ?? "";
771
+ const queryFnBody = `const { data } = await ${buildClientCall(node, {
772
+ clientName,
773
+ signal: true,
774
+ unwrapName
775
+ })}
776
+ return data`;
777
+ const hasNewParams = nextParam != null || previousParam != null;
778
+ const [getNextPageParamExpr, getPreviousPageParamExpr] = (() => {
779
+ if (hasNewParams) {
780
+ const nextAccessor = nextParam ? getNestedAccessor(nextParam, "lastPage") : null;
781
+ const prevAccessor = previousParam ? getNestedAccessor(previousParam, "firstPage") : null;
782
+ return [nextAccessor ? `getNextPageParam: (lastPage) => ${nextAccessor}` : null, prevAccessor ? `getPreviousPageParam: (firstPage) => ${prevAccessor}` : null];
783
+ }
784
+ if (cursorParam) return [`getNextPageParam: (lastPage) => lastPage['${cursorParam}']`, `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`];
785
+ return ["getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage) && lastPage.length === 0 ? undefined : lastPageParam + 1", "getPreviousPageParam: (_firstPage, _allPages, firstPageParam) => firstPageParam <= 1 ? undefined : firstPageParam - 1"];
786
+ })();
787
+ const queryOptionsArr = [
788
+ `initialPageParam: ${typeof initialPageParam === "string" ? JSON.stringify(initialPageParam) : initialPageParam}`,
789
+ getNextPageParamExpr,
790
+ getPreviousPageParamExpr
791
+ ].filter(Boolean);
792
+ const infiniteOverrideParams = queryParam && queryParamsTypeName ? `query = {
793
+ ...(query ?? {}),
794
+ ['${queryParam}']: pageParam as unknown as ${queryParamsTypeName}['${queryParam}'],
795
+ } as ${queryParamsTypeName}` : "";
796
+ const queryFnArgs = infiniteOverrideParams ? "{ signal, pageParam }" : "{ signal }";
797
+ const queryFnStatements = infiniteOverrideParams ? `${infiniteOverrideParams}\n ${queryFnBody}` : queryFnBody;
798
+ return /* @__PURE__ */ jsx(File.Source, {
799
+ name,
800
+ isExportable: true,
801
+ isIndexable: true,
802
+ children: /* @__PURE__ */ jsx(Function, {
803
+ name,
804
+ export: true,
805
+ params: paramsSignature,
806
+ children: `
807
+ const queryKey = ${queryKeyName}(${queryKeyParamsCall})
808
+ return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${queryFnDataType}>, ${queryKeyType}, ${pageParamType}>({
809
+ queryKey,
810
+ queryFn: async (${queryFnArgs}) => {
811
+ ${queryFnStatements}
812
+ },
813
+ ${queryOptionsArr.join(",\n ")}
814
+ })
815
+ `
816
+ })
817
+ });
818
+ }
819
+ __name(InfiniteQueryOptions$1, "InfiniteQueryOptions");
820
+ //#endregion
821
+ //#region ../../internals/tanstack-query/src/components/MutationKey.tsx
822
+ const declarationPrinter$6 = functionPrinter({ mode: "declaration" });
823
+ const mutationKeyTransformer = ({ node }) => {
824
+ if (!node.path) return [];
825
+ return [`{ url: '${Url.toPath(node.path)}' }`];
826
+ };
827
+ function MutationKey({ name, node, transformer }) {
828
+ const paramsNode = createFunctionParameters({ params: [] });
829
+ const paramsSignature = declarationPrinter$6.print(paramsNode) ?? "";
830
+ const keys = (transformer ?? mutationKeyTransformer)({
831
+ node,
832
+ casing: "camelcase"
833
+ });
834
+ return /* @__PURE__ */ jsx(File.Source, {
835
+ name,
836
+ isExportable: true,
837
+ isIndexable: true,
838
+ children: /* @__PURE__ */ jsx(Function.Arrow, {
839
+ name,
840
+ export: true,
841
+ params: paramsSignature,
842
+ singleLine: true,
843
+ children: `[${keys.join(", ")}] as const`
844
+ })
845
+ });
846
+ }
847
+ //#endregion
848
+ //#region ../../internals/tanstack-query/src/resolver.ts
849
+ /**
850
+ * Builds the shared query namespace for a variant. Spread the result into
851
+ * `createResolver` once per variant the plugin supports.
852
+ *
853
+ * @example
854
+ * ```ts
855
+ * createResolver<PluginReactQuery>({
856
+ * query: createQueryResolver(),
857
+ * suspenseQuery: createQueryResolver('Suspense'),
858
+ * })
859
+ * ```
860
+ */
861
+ function createQueryResolver(variant = "") {
862
+ return {
863
+ name(node) {
864
+ return `use${capitalize(this.name(node.operationId))}${variant}`;
865
+ },
866
+ optionsName(node) {
867
+ return `${this.name(node.operationId)}${variant}QueryOptions`;
868
+ },
869
+ keyName(node) {
870
+ return `${this.name(node.operationId)}${variant}QueryKey`;
871
+ },
872
+ keyTypeName(node) {
873
+ return `${capitalize(this.name(node.operationId))}${variant}QueryKey`;
874
+ },
875
+ clientName(node) {
876
+ return `${this.name(node.operationId)}${variant}`;
877
+ }
878
+ };
879
+ }
880
+ /**
881
+ * Builds the shared mutation namespace. Spread the result into
882
+ * `createResolver` and add plugin-specific methods (`optionsName`,
883
+ * `typeName`, `argTypeName`) next to it.
884
+ *
885
+ * @example
886
+ * ```ts
887
+ * createResolver<PluginSwr>({ mutation: { ...createMutationResolver(), argTypeName(node) {...} } })
888
+ * ```
889
+ */
890
+ function createMutationResolver() {
891
+ return {
892
+ name(node) {
893
+ return `use${capitalize(this.name(node.operationId))}`;
894
+ },
895
+ keyName(node) {
896
+ return `${this.name(node.operationId)}MutationKey`;
897
+ }
898
+ };
899
+ }
650
900
  functionPrinter({ mode: "declaration" });
651
901
  const queryKeyTransformer = ({ node }) => {
652
902
  if (!node.path) return [];
@@ -726,6 +976,20 @@ function resolveClient(options) {
726
976
  message: "No client plugin is registered. Add `@kubb/plugin-axios` or `@kubb/plugin-fetch` to `plugins` so the generated code has an HTTP client to call."
727
977
  };
728
978
  }
979
+ /**
980
+ * Resolves the contract client during a consumer plugin's setup hook. Extracts the plugin names
981
+ * from the raw `plugins` config, applies {@link resolveClient}, and throws the diagnostic on a
982
+ * misconfiguration so every consumer fails fast with the same message.
983
+ */
984
+ function resolveContractClient(options) {
985
+ const { client, plugins = [] } = options;
986
+ const resolved = resolveClient({
987
+ client,
988
+ pluginNames: plugins.map((plugin) => plugin.name).filter((name) => Boolean(name))
989
+ });
990
+ if (resolved.kind === "error") throw new Error(resolved.message);
991
+ return resolved;
992
+ }
729
993
  //#endregion
730
994
  //#region ../../internals/client/src/resolveClientOperation.ts
731
995
  /**
@@ -754,12 +1018,6 @@ function resolveClientOperation(options) {
754
1018
  }
755
1019
  //#endregion
756
1020
  //#region src/utils.ts
757
- const requestGroupOrder = [
758
- "path",
759
- "query",
760
- "body",
761
- "headers"
762
- ];
763
1021
  /**
764
1022
  * Builds the call to a contract client `<op>` function inside a vue-query composable body. The
765
1023
  * function takes a single grouped options object, so `config` is spread first, then the operation's
@@ -768,18 +1026,14 @@ const requestGroupOrder = [
768
1026
  * Mutations omit the `signal`.
769
1027
  */
770
1028
  function buildVueClientCall(node, options) {
771
- const { clientName, signal = false } = options;
772
- const groups = getRequestGroups(node);
773
- return `${clientName}({ ${[
774
- "...config",
775
- ...requestGroupOrder.filter((key) => groups[key]).map((name) => `${name}: toValue(${name})`),
776
- signal ? "signal: config.signal ?? signal" : null,
777
- "throwOnError: true"
778
- ].filter((part) => part !== null).join(", ")} })`;
1029
+ return buildClientCall(node, {
1030
+ ...options,
1031
+ unwrapName: (name) => `toValue(${name})`
1032
+ });
779
1033
  }
780
1034
  //#endregion
781
1035
  //#region src/components/QueryKey.tsx
782
- const declarationPrinter$5 = functionPrinter({ mode: "declaration" });
1036
+ const declarationPrinter$4 = functionPrinter({ mode: "declaration" });
783
1037
  function buildQueryKeyParamsNode(node, options) {
784
1038
  const groupedParam = buildGroupedRequestParam(node, {
785
1039
  resolver: options.resolver,
@@ -794,7 +1048,7 @@ function buildQueryKeyParamsNode(node, options) {
794
1048
  }
795
1049
  function QueryKey({ name, node, tsResolver, typeName, transformer }) {
796
1050
  const paramsNode = buildQueryKeyParamsNode(node, { resolver: tsResolver });
797
- const paramsSignature = declarationPrinter$5.print(paramsNode) ?? "";
1051
+ const paramsSignature = declarationPrinter$4.print(paramsNode) ?? "";
798
1052
  const keys = (transformer ?? queryKeyTransformer)({
799
1053
  node,
800
1054
  casing: "camelcase"
@@ -824,8 +1078,8 @@ function QueryKey({ name, node, tsResolver, typeName, transformer }) {
824
1078
  }
825
1079
  //#endregion
826
1080
  //#region src/components/QueryOptions.tsx
827
- const declarationPrinter$4 = functionPrinter({ mode: "declaration" });
828
- const callPrinter$4 = functionPrinter({ mode: "call" });
1081
+ const declarationPrinter$3 = functionPrinter({ mode: "declaration" });
1082
+ const callPrinter$3 = functionPrinter({ mode: "call" });
829
1083
  function getQueryOptionsParams(node, options) {
830
1084
  return buildQueryOptionsParams(node, {
831
1085
  resolver: options.resolver,
@@ -833,15 +1087,11 @@ function getQueryOptionsParams(node, options) {
833
1087
  });
834
1088
  }
835
1089
  function QueryOptions({ name, clientName, node, tsResolver, queryKeyName }) {
836
- const successNames = resolveSuccessNames(node, tsResolver);
837
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
838
- const errorNames = resolveErrorNames(node, tsResolver);
839
- const TData = responseName;
840
- const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1090
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
841
1091
  const queryKeyParamsNode = buildQueryKeyParamsNode(node, { resolver: tsResolver });
842
- const queryKeyParamsCall = callPrinter$4.print(queryKeyParamsNode) ?? "";
1092
+ const queryKeyParamsCall = callPrinter$3.print(queryKeyParamsNode) ?? "";
843
1093
  const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
844
- const paramsSignature = declarationPrinter$4.print(paramsNode) ?? "";
1094
+ const paramsSignature = declarationPrinter$3.print(paramsNode) ?? "";
845
1095
  const queryFnBody = `const { data } = await ${buildVueClientCall(node, {
846
1096
  clientName,
847
1097
  signal: true
@@ -869,19 +1119,17 @@ function QueryOptions({ name, clientName, node, tsResolver, queryKeyName }) {
869
1119
  }
870
1120
  //#endregion
871
1121
  //#region src/components/InfiniteQuery.tsx
872
- const declarationPrinter$3 = functionPrinter({ mode: "declaration" });
873
- const callPrinter$3 = functionPrinter({ mode: "call" });
1122
+ const declarationPrinter$2 = functionPrinter({ mode: "declaration" });
1123
+ const callPrinter$2 = functionPrinter({ mode: "call" });
874
1124
  function buildInfiniteQueryParamsNode(node, options) {
875
1125
  const { resolver } = options;
876
- const successNames = resolveSuccessNames(node, resolver);
877
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
878
- const errorNames = resolveErrorNames(node, resolver);
1126
+ const { TData, TError } = buildResponseTypes(node, resolver);
879
1127
  const optionsParam = createFunctionParameter({
880
1128
  name: "options",
881
1129
  type: `{
882
1130
  query?: Partial<UseInfiniteQueryOptions<${[
883
- responseName,
884
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1131
+ TData,
1132
+ TError,
885
1133
  "TQueryData",
886
1134
  "TQueryKey",
887
1135
  "TQueryData"
@@ -896,11 +1144,7 @@ function buildInfiniteQueryParamsNode(node, options) {
896
1144
  }), optionsParam].filter((param) => param !== null) });
897
1145
  }
898
1146
  function InfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver }) {
899
- const successNames = resolveSuccessNames(node, tsResolver);
900
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
901
- const errorNames = resolveErrorNames(node, tsResolver);
902
- const TData = responseName;
903
- const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1147
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
904
1148
  const returnType = `UseInfiniteQueryReturnType<${["TData", TError].join(", ")}> & { queryKey: TQueryKey }`;
905
1149
  const generics = [
906
1150
  `TData = InfiniteData<${TData}>`,
@@ -908,11 +1152,11 @@ function InfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName,
908
1152
  `TQueryKey extends QueryKey = ${queryKeyTypeName}`
909
1153
  ];
910
1154
  const queryKeyParamsNode = buildQueryKeyParamsNode(node, { resolver: tsResolver });
911
- const queryKeyParamsCall = callPrinter$3.print(queryKeyParamsNode) ?? "";
1155
+ const queryKeyParamsCall = callPrinter$2.print(queryKeyParamsNode) ?? "";
912
1156
  const queryOptionsParamsNode = getQueryOptionsParams(node, { resolver: tsResolver });
913
- const queryOptionsParamsCall = callPrinter$3.print(queryOptionsParamsNode) ?? "";
1157
+ const queryOptionsParamsCall = callPrinter$2.print(queryOptionsParamsNode) ?? "";
914
1158
  const paramsNode = buildInfiniteQueryParamsNode(node, { resolver: tsResolver });
915
- const paramsSignature = declarationPrinter$3.print(paramsNode) ?? "";
1159
+ const paramsSignature = declarationPrinter$2.print(paramsNode) ?? "";
916
1160
  return /* @__PURE__ */ jsx(File.Source, {
917
1161
  name,
918
1162
  isExportable: true,
@@ -943,93 +1187,17 @@ function InfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName,
943
1187
  }
944
1188
  //#endregion
945
1189
  //#region src/components/InfiniteQueryOptions.tsx
946
- const declarationPrinter$2 = functionPrinter({ mode: "declaration" });
947
- const callPrinter$2 = functionPrinter({ mode: "call" });
948
- function InfiniteQueryOptions({ name, clientName, initialPageParam, cursorParam, nextParam, previousParam, node, tsResolver, queryParam, queryKeyName }) {
949
- const successNames = resolveSuccessNames(node, tsResolver);
950
- const queryFnDataType = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
951
- const errorNames = resolveErrorNames(node, tsResolver);
952
- const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
953
- const isInitialPageParamDefined = initialPageParam !== void 0 && initialPageParam !== null;
954
- const fallbackPageParamType = typeof initialPageParam === "number" ? "number" : typeof initialPageParam === "string" ? initialPageParam.includes(" as ") ? (() => {
955
- const parts = initialPageParam.split(" as ");
956
- return parts[parts.length - 1] ?? "unknown";
957
- })() : "string" : typeof initialPageParam === "boolean" ? "boolean" : "unknown";
958
- const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
959
- const queryParamsTypeName = rawQueryParams.length > 0 ? (() => {
960
- const groupName = tsResolver.param.query(node, rawQueryParams[0]);
961
- return groupName !== tsResolver.param.name(node, rawQueryParams[0]) ? groupName : null;
962
- })() : null;
963
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
964
- const pageParamType = queryParamType ? isInitialPageParamDefined ? `NonNullable<${queryParamType}>` : queryParamType : fallbackPageParamType;
965
- const queryKeyParamsNode = buildQueryKeyParamsNode(node, { resolver: tsResolver });
966
- const queryKeyParamsCall = callPrinter$2.print(queryKeyParamsNode) ?? "";
967
- const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
968
- const paramsSignature = declarationPrinter$2.print(paramsNode) ?? "";
969
- const queryFnBody = `const { data } = await ${buildVueClientCall(node, {
970
- clientName,
971
- signal: true
972
- })}
973
- return data`;
974
- const hasNewParams = nextParam != null || previousParam != null;
975
- const [getNextPageParamExpr, getPreviousPageParamExpr] = (() => {
976
- if (hasNewParams) {
977
- const nextAccessor = nextParam ? getNestedAccessor(nextParam, "lastPage") : null;
978
- const prevAccessor = previousParam ? getNestedAccessor(previousParam, "firstPage") : null;
979
- return [nextAccessor ? `getNextPageParam: (lastPage) => ${nextAccessor}` : null, prevAccessor ? `getPreviousPageParam: (firstPage) => ${prevAccessor}` : null];
980
- }
981
- if (cursorParam) return [`getNextPageParam: (lastPage) => lastPage['${cursorParam}']`, `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`];
982
- return ["getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage) && lastPage.length === 0 ? undefined : lastPageParam + 1", "getPreviousPageParam: (_firstPage, _allPages, firstPageParam) => firstPageParam <= 1 ? undefined : firstPageParam - 1"];
983
- })();
984
- const queryOptionsArr = [
985
- `initialPageParam: ${typeof initialPageParam === "string" ? JSON.stringify(initialPageParam) : initialPageParam}`,
986
- getNextPageParamExpr,
987
- getPreviousPageParamExpr
988
- ].filter(Boolean);
989
- const infiniteOverrideParams = queryParam && queryParamsTypeName ? `query = {
990
- ...(query ?? {}),
991
- ['${queryParam}']: pageParam as unknown as ${queryParamsTypeName}['${queryParam}'],
992
- } as ${queryParamsTypeName}` : "";
993
- if (infiniteOverrideParams) return /* @__PURE__ */ jsx(File.Source, {
994
- name,
995
- isExportable: true,
996
- isIndexable: true,
997
- children: /* @__PURE__ */ jsx(Function, {
998
- name,
999
- export: true,
1000
- params: paramsSignature,
1001
- children: `
1002
- const queryKey = ${queryKeyName}(${queryKeyParamsCall})
1003
- return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${queryFnDataType}>, QueryKey, ${pageParamType}>({
1004
- queryKey,
1005
- queryFn: async ({ signal, pageParam }) => {
1006
- ${infiniteOverrideParams}
1007
- ${queryFnBody}
1008
- },
1009
- ${queryOptionsArr.join(",\n ")}
1010
- })
1011
- `
1012
- })
1013
- });
1014
- return /* @__PURE__ */ jsx(File.Source, {
1015
- name,
1016
- isExportable: true,
1017
- isIndexable: true,
1018
- children: /* @__PURE__ */ jsx(Function, {
1019
- name,
1020
- export: true,
1021
- params: paramsSignature,
1022
- children: `
1023
- const queryKey = ${queryKeyName}(${queryKeyParamsCall})
1024
- return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${queryFnDataType}>, QueryKey, ${pageParamType}>({
1025
- queryKey,
1026
- queryFn: async ({ signal }) => {
1027
- ${queryFnBody}
1028
- },
1029
- ${queryOptionsArr.join(",\n ")}
1030
- })
1031
- `
1032
- })
1190
+ /**
1191
+ * The vue-query flavor of the shared `infiniteQueryOptions` component: request groups accept
1192
+ * `MaybeRefOrGetter` values, are unwrapped with `toValue(...)` in the client call, and the emitted
1193
+ * `TQueryKey` generic is the imported `QueryKey` type instead of `typeof queryKey`.
1194
+ */
1195
+ function InfiniteQueryOptions(props) {
1196
+ return /* @__PURE__ */ jsx(InfiniteQueryOptions$1, {
1197
+ ...props,
1198
+ queryKeyType: "QueryKey",
1199
+ memberTypeWrapper: maybeRefOrGetter,
1200
+ unwrapName: (name) => `toValue(${name})`
1033
1201
  });
1034
1202
  }
1035
1203
  //#endregion
@@ -1041,15 +1209,13 @@ function resolveMutationRequestType(node, resolver) {
1041
1209
  }
1042
1210
  function buildMutationParamsNode(node, options) {
1043
1211
  const { resolver } = options;
1044
- const successNames = resolveSuccessNames(node, resolver);
1045
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
1046
- const errorNames = resolveErrorNames(node, resolver);
1212
+ const { TData, TError } = buildResponseTypes(node, resolver);
1047
1213
  return createFunctionParameters({ params: [createFunctionParameter({
1048
1214
  name: "options",
1049
1215
  type: `{
1050
1216
  mutation?: MutationObserverOptions<${[
1051
- responseName,
1052
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1217
+ TData,
1218
+ TError,
1053
1219
  resolveMutationRequestType(node, resolver),
1054
1220
  "TContext"
1055
1221
  ].join(", ")}> & { client?: QueryClient },
@@ -1059,11 +1225,7 @@ function buildMutationParamsNode(node, options) {
1059
1225
  })] });
1060
1226
  }
1061
1227
  function Mutation({ name, clientName, node, tsResolver, mutationKeyName }) {
1062
- const successNames = resolveSuccessNames(node, tsResolver);
1063
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1064
- const errorNames = resolveErrorNames(node, tsResolver);
1065
- const TData = responseName;
1066
- const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1228
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1067
1229
  const groupedParam = buildGroupedRequestParam(node, { resolver: tsResolver });
1068
1230
  const hasMutationParams = groupedParam !== null;
1069
1231
  const groupedParamsNode = createFunctionParameters({ params: groupedParam ? [groupedParam] : [] });
@@ -1113,15 +1275,13 @@ const declarationPrinter = functionPrinter({ mode: "declaration" });
1113
1275
  const callPrinter = functionPrinter({ mode: "call" });
1114
1276
  function buildQueryParamsNode(node, options) {
1115
1277
  const { resolver } = options;
1116
- const successNames = resolveSuccessNames(node, resolver);
1117
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
1118
- const errorNames = resolveErrorNames(node, resolver);
1278
+ const { TData, TError } = buildResponseTypes(node, resolver);
1119
1279
  const optionsParam = createFunctionParameter({
1120
1280
  name: "options",
1121
1281
  type: `{
1122
1282
  query?: Partial<UseQueryOptions<${[
1123
- responseName,
1124
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1283
+ TData,
1284
+ TError,
1125
1285
  "TData",
1126
1286
  "TQueryData",
1127
1287
  "TQueryKey"
@@ -1136,11 +1296,7 @@ function buildQueryParamsNode(node, options) {
1136
1296
  }), optionsParam].filter((param) => param !== null) });
1137
1297
  }
1138
1298
  function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver }) {
1139
- const successNames = resolveSuccessNames(node, tsResolver);
1140
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1141
- const errorNames = resolveErrorNames(node, tsResolver);
1142
- const TData = responseName;
1143
- const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1299
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1144
1300
  const returnType = `UseQueryReturnType<${["TData", TError].join(", ")}> & { queryKey: TQueryKey }`;
1145
1301
  const generics = [
1146
1302
  `TData = ${TData}`,
@@ -1628,9 +1784,6 @@ const queryGenerator = defineGenerator({
1628
1784
  });
1629
1785
  //#endregion
1630
1786
  //#region src/resolvers/resolverVueQuery.ts
1631
- function capitalize(name) {
1632
- return `${name.charAt(0).toUpperCase()}${name.slice(1)}`;
1633
- }
1634
1787
  /**
1635
1788
  * Default resolver used by `@kubb/plugin-vue-query`. Decides the names and
1636
1789
  * file paths for every generated TanStack Query composable (`useFoo`,
@@ -1651,47 +1804,10 @@ function capitalize(name) {
1651
1804
  */
1652
1805
  const resolverVueQuery = createResolver({
1653
1806
  pluginName: "plugin-vue-query",
1654
- query: {
1655
- name(node) {
1656
- return `use${capitalize(this.name(node.operationId))}`;
1657
- },
1658
- keyName(node) {
1659
- return `${this.name(node.operationId)}QueryKey`;
1660
- },
1661
- keyTypeName(node) {
1662
- return `${capitalize(this.name(node.operationId))}QueryKey`;
1663
- },
1664
- optionsName(node) {
1665
- return `${this.name(node.operationId)}QueryOptions`;
1666
- },
1667
- clientName(node) {
1668
- return this.name(node.operationId);
1669
- }
1670
- },
1671
- infiniteQuery: {
1672
- name(node) {
1673
- return `use${capitalize(this.name(node.operationId))}Infinite`;
1674
- },
1675
- keyName(node) {
1676
- return `${this.name(node.operationId)}InfiniteQueryKey`;
1677
- },
1678
- keyTypeName(node) {
1679
- return `${capitalize(this.name(node.operationId))}InfiniteQueryKey`;
1680
- },
1681
- optionsName(node) {
1682
- return `${this.name(node.operationId)}InfiniteQueryOptions`;
1683
- },
1684
- clientName(node) {
1685
- return `${this.name(node.operationId)}Infinite`;
1686
- }
1687
- },
1807
+ query: createQueryResolver(),
1808
+ infiniteQuery: createQueryResolver("Infinite"),
1688
1809
  mutation: {
1689
- name(node) {
1690
- return `use${capitalize(this.name(node.operationId))}`;
1691
- },
1692
- keyName(node) {
1693
- return `${this.name(node.operationId)}MutationKey`;
1694
- },
1810
+ ...createMutationResolver(),
1695
1811
  typeName(node) {
1696
1812
  return capitalize(this.name(node.operationId));
1697
1813
  }
@@ -1745,43 +1861,17 @@ const pluginVueQuery = definePlugin((options) => {
1745
1861
  dependencies: [pluginTsName],
1746
1862
  hooks: { "kubb:plugin:setup"(ctx) {
1747
1863
  const resolver = userResolver ? Resolver.merge(resolverVueQuery, userResolver) : resolverVueQuery;
1748
- const resolvedClient = resolveClient({
1749
- client,
1750
- pluginNames: (ctx.config.plugins ?? []).map((p) => p.name).filter((name) => Boolean(name))
1751
- });
1752
- if (resolvedClient.kind === "error") throw new Error(resolvedClient.message);
1753
- const resolvedClientDescriptor = {
1754
- kind: "contract",
1755
- pluginName: resolvedClient.pluginName
1756
- };
1757
1864
  ctx.setOptions({
1758
1865
  output,
1759
- client: resolvedClientDescriptor,
1866
+ client: resolveContractClient({
1867
+ client,
1868
+ plugins: ctx.config.plugins
1869
+ }),
1760
1870
  queryKey,
1761
- query: query === false ? false : {
1762
- importPath: "@tanstack/vue-query",
1763
- methods: ["GET"],
1764
- ...query
1765
- },
1871
+ query: resolveQueryConfig(query, { importPath: "@tanstack/vue-query" }),
1766
1872
  mutationKey,
1767
- mutation: mutation === false ? false : {
1768
- importPath: "@tanstack/vue-query",
1769
- methods: [
1770
- "POST",
1771
- "PUT",
1772
- "PATCH",
1773
- "DELETE"
1774
- ],
1775
- ...mutation
1776
- },
1777
- infinite: infinite ? {
1778
- queryParam: "id",
1779
- initialPageParam: 0,
1780
- cursorParam: null,
1781
- nextParam: null,
1782
- previousParam: null,
1783
- ...infinite
1784
- } : false,
1873
+ mutation: resolveMutationConfig(mutation, { importPath: "@tanstack/vue-query" }),
1874
+ infinite: resolveInfiniteConfig(infinite),
1785
1875
  hooks,
1786
1876
  group: groupConfig,
1787
1877
  exclude,
@@ -1796,6 +1886,6 @@ const pluginVueQuery = definePlugin((options) => {
1796
1886
  };
1797
1887
  });
1798
1888
  //#endregion
1799
- export { pluginVueQuery as default, pluginVueQuery, pluginVueQueryName };
1889
+ export { pluginVueQuery as default, pluginVueQuery, pluginVueQueryName, resolverVueQuery };
1800
1890
 
1801
1891
  //# sourceMappingURL=index.js.map