@kubb/plugin-vue-query 5.5.0 → 5.5.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
@@ -1,27 +1,9 @@
1
- import { t as __name } from "./rolldown-runtime-C0LytTxp.js";
2
- import { Resolver, Url, addGenerator, ast, createResolver, defineExtension, defineGenerator, setMacros, setResolver, useConfig } from "kubb/kit";
1
+ import "./rolldown-runtime-C0LytTxp.js";
2
+ import { Diagnostics, Resolver, Url, addGenerator, ast, createResolver, defineExtension, defineGenerator, setMacros, setResolver, useConfig } from "kubb/kit";
3
3
  import path from "node:path";
4
4
  import { createFunctionParameter, createFunctionParameters, createObjectBindingPattern, createTypeLiteral, functionPrinter, pluginTsName } from "@kubb/plugin-ts";
5
5
  import { File, Function, Type, jsxRenderer } from "kubb/jsx";
6
6
  import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
7
- //#region ../../internals/shared/src/params.ts
8
- /**
9
- * Drops parameters that share the same name, keeping the first.
10
- *
11
- * A malformed spec can declare the same parameter name twice within one `in` location. Both would
12
- * resolve to the same output property, so emitting both would yield an object type with a duplicate
13
- * member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:
14
- * parameter names flow through unchanged, so no two distinct names ever collide here anymore.
15
- */
16
- function dedupeParams(params) {
17
- const seen = /* @__PURE__ */ new Set();
18
- return params.filter((param) => {
19
- if (seen.has(param.name)) return false;
20
- seen.add(param.name);
21
- return true;
22
- });
23
- }
24
- //#endregion
25
7
  //#region ../../internals/shared/src/operation.ts
26
8
  /**
27
9
  * Builds the `ResolverFileParams` every operation generator passes to
@@ -91,12 +73,12 @@ function getContentTypeInfo(node) {
91
73
  function getResponseContentTypeInfo(node) {
92
74
  return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? []);
93
75
  }
76
+ const requestConfigBaseType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
94
77
  function buildRequestConfigType(node) {
95
78
  const request = getContentTypeInfo(node);
96
79
  const response = getResponseContentTypeInfo(node);
97
- const configType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
98
80
  const members = [request.isMultipleContentTypes ? `request?: ${request.contentTypeUnion}` : null, response.isMultipleContentTypes ? `response?: ${response.contentTypeUnion}` : null].filter(Boolean);
99
- return members.length ? `${configType} & { contentType?: { ${members.join("; ")} } }` : configType;
81
+ return members.length ? `${requestConfigBaseType} & { contentType?: { ${members.join("; ")} } }` : requestConfigBaseType;
100
82
  }
101
83
  /**
102
84
  * Builds the `client?:` option type shared by the generated query hooks (`useQuery`,
@@ -105,7 +87,7 @@ function buildRequestConfigType(node) {
105
87
  * content type for.
106
88
  */
107
89
  function buildClientOptionType() {
108
- return `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
90
+ return requestConfigBaseType;
109
91
  }
110
92
  /**
111
93
  * Which of the grouped request options an operation carries.
@@ -165,11 +147,19 @@ const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
165
147
  function getOperationParameters(node) {
166
148
  const cached = operationParameterGroupsByNode.get(node);
167
149
  if (cached) return cached;
150
+ const group = (location) => {
151
+ const seen = /* @__PURE__ */ new Set();
152
+ return node.parameters.filter((param) => {
153
+ if (param.in !== location || seen.has(param.name)) return false;
154
+ seen.add(param.name);
155
+ return true;
156
+ });
157
+ };
168
158
  const groups = {
169
- path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
170
- query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
171
- header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
172
- cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
159
+ path: group("path"),
160
+ query: group("query"),
161
+ header: group("header"),
162
+ cookie: group("cookie")
173
163
  };
174
164
  operationParameterGroupsByNode.set(node, groups);
175
165
  return groups;
@@ -329,7 +319,96 @@ var compatibility = {
329
319
  };
330
320
  //#endregion
331
321
  //#region package.json
332
- var version = "5.5.0";
322
+ var version = "5.5.1";
323
+ //#endregion
324
+ //#region ../../internals/tanstack-query/src/components/HookFile.tsx
325
+ /**
326
+ * Resolves what every TanStack hook file shares: its file, the `@kubb/plugin-ts` file and type names, banner and footer.
327
+ */
328
+ function resolveHookFile(node, ctx, options) {
329
+ const { name, output, group, contractOp, keyTypeName, extraTypeNames = [] } = options;
330
+ const { config, root, resolver } = ctx;
331
+ const pluginTs = ctx.requirePlugin(pluginTsName);
332
+ const tsResolver = ctx.driver.getResolver(pluginTsName);
333
+ const file = resolver.file({
334
+ ...operationFileEntry(node, name),
335
+ root,
336
+ output,
337
+ group: group ?? void 0
338
+ });
339
+ const fileTs = resolveDependencyOperationFile({
340
+ cache: ctx.cache,
341
+ node,
342
+ resolver: tsResolver,
343
+ root,
344
+ output: pluginTs.options?.output ?? output,
345
+ group: pluginTs.options?.group
346
+ });
347
+ const importedTypeNames = [
348
+ tsResolver.response.options(node),
349
+ ...extraTypeNames,
350
+ ...resolveOperationTypeNames(node, tsResolver, {
351
+ exclude: keyTypeName ? [keyTypeName] : void 0,
352
+ order: "body-response-first",
353
+ includeParams: false
354
+ })
355
+ ].filter((typeName) => Boolean(typeName));
356
+ const fileMeta = {
357
+ path: file.path,
358
+ baseName: file.baseName
359
+ };
360
+ return {
361
+ file,
362
+ fileTs,
363
+ tsResolver,
364
+ contractOp,
365
+ importedTypeNames,
366
+ banner: resolver.default.banner(ctx.meta, {
367
+ output,
368
+ config,
369
+ file: fileMeta
370
+ }),
371
+ footer: resolver.default.footer(ctx.meta, {
372
+ output,
373
+ config,
374
+ file: fileMeta
375
+ })
376
+ };
377
+ }
378
+ /**
379
+ * The `<File>` shell shared by the TanStack hook generators; renders `children` after the imports.
380
+ */
381
+ function HookFile({ hook, imports, children }) {
382
+ const { file, fileTs, contractOp, importedTypeNames, banner, footer } = hook;
383
+ return /* @__PURE__ */ jsxs(File, {
384
+ baseName: file.baseName,
385
+ path: file.path,
386
+ meta: file.meta,
387
+ banner,
388
+ footer,
389
+ children: [
390
+ /* @__PURE__ */ jsx(File.Import, {
391
+ name: [contractOp.name],
392
+ root: file.path,
393
+ path: contractOp.path
394
+ }),
395
+ /* @__PURE__ */ jsx(File.Import, {
396
+ name: ["RequestConfig", "ResponseErrorConfig"],
397
+ root: contractOp.clientPathIsFile ? file.path : void 0,
398
+ path: contractOp.clientPath,
399
+ isTypeOnly: true
400
+ }),
401
+ imports,
402
+ fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
403
+ name: Array.from(new Set(importedTypeNames)),
404
+ root: file.path,
405
+ path: fileTs.path,
406
+ isTypeOnly: true
407
+ }),
408
+ children
409
+ ]
410
+ });
411
+ }
333
412
  //#endregion
334
413
  //#region ../../internals/tanstack-query/src/utils.ts
335
414
  /**
@@ -614,11 +693,47 @@ const queryKeyGroupOrder = [
614
693
  "query",
615
694
  "body"
616
695
  ];
696
+ /**
697
+ * Build QueryKey params as the grouped `{ path, query, body }` object (NO headers, NO config),
698
+ * typed from the operation's `Options` minus `url`. The query key transformer reads the
699
+ * grouped `path`/`query`/`body` bindings.
700
+ */
701
+ function buildQueryKeyParams(node, options) {
702
+ const { resolver, memberTypeWrapper } = options;
703
+ const groupedParam = buildGroupedRequestParam(node, {
704
+ resolver,
705
+ keys: queryKeyGroupOrder,
706
+ memberTypeWrapper
707
+ });
708
+ return createFunctionParameters({ params: groupedParam ? [groupedParam] : [] });
709
+ }
710
+ /**
711
+ * Builds the hook parameter list: the grouped request param (omitted when `withRequest` is `false`) then `options` typed as `optionsType`.
712
+ */
713
+ function buildHookParams(node, options) {
714
+ const { resolver, optionsType, memberTypeWrapper, withRequest = true } = options;
715
+ const optionsParam = createFunctionParameter({
716
+ name: "options",
717
+ type: optionsType,
718
+ default: "{}"
719
+ });
720
+ const groupedParam = withRequest ? buildGroupedRequestParam(node, {
721
+ resolver,
722
+ memberTypeWrapper
723
+ }) : null;
724
+ return createFunctionParameters({ params: [groupedParam, optionsParam].filter((param) => param !== null) });
725
+ }
726
+ /**
727
+ * The `TRequest` type argument of a mutation hook: the options type when the operation takes a request, else `undefined`.
728
+ */
729
+ function resolveMutationRequestType(node, resolver) {
730
+ return buildGroupedRequestParam(node, { resolver }) ? resolver.response.options(node) : "undefined";
731
+ }
617
732
  //#endregion
618
733
  //#region ../../internals/tanstack-query/src/components/InfiniteQueryOptions.tsx
619
- const declarationPrinter$7 = functionPrinter({ mode: "declaration" });
620
- const callPrinter$4 = functionPrinter({ mode: "call" });
621
- function InfiniteQueryOptions$1({ name, clientName, initialPageParam, hasExplicitInitialPageParam, cursorParam, nextParam, previousParam, getNextPageParam, getPreviousPageParam, node, tsResolver, queryParam, queryKeyName, queryKeyType = "typeof queryKey", memberTypeWrapper, unwrapName, returnType = "full" }) {
734
+ const declarationPrinter$5 = functionPrinter({ mode: "declaration" });
735
+ const callPrinter$3 = functionPrinter({ mode: "call" });
736
+ function InfiniteQueryOptions({ name, clientName, initialPageParam, hasExplicitInitialPageParam, cursorParam, nextParam, previousParam, getNextPageParam, getPreviousPageParam, node, tsResolver, queryParam, queryKeyName, queryKeyType = "typeof queryKey", memberTypeWrapper, unwrapName, returnType = "full" }) {
622
737
  const { TData: queryFnDataType, TError: errorType } = buildResponseTypes(node, tsResolver);
623
738
  const { queryParamsTypeName, pageParamType } = resolvePageParamType(node, {
624
739
  resolver: tsResolver,
@@ -631,12 +746,12 @@ function InfiniteQueryOptions$1({ name, clientName, initialPageParam, hasExplici
631
746
  memberTypeWrapper
632
747
  });
633
748
  const queryKeyParamsNode = createFunctionParameters({ params: groupedKeyParam ? [groupedKeyParam] : [] });
634
- const queryKeyParamsCall = callPrinter$4.print(queryKeyParamsNode) ?? "";
749
+ const queryKeyParamsCall = callPrinter$3.print(queryKeyParamsNode) ?? "";
635
750
  const paramsNode = buildQueryOptionsParams(node, {
636
751
  resolver: tsResolver,
637
752
  memberTypeWrapper
638
753
  });
639
- const paramsSignature = declarationPrinter$7.print(paramsNode) ?? "";
754
+ const paramsSignature = declarationPrinter$5.print(paramsNode) ?? "";
640
755
  const queryFnBody = buildCallResultBody(buildClientCall(node, {
641
756
  clientName,
642
757
  signal: true,
@@ -691,23 +806,22 @@ return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${que
691
806
  })
692
807
  });
693
808
  }
694
- __name(InfiniteQueryOptions$1, "InfiniteQueryOptions");
695
809
  //#endregion
696
810
  //#region ../../internals/tanstack-query/src/components/MutationKey.tsx
697
- const declarationPrinter$6 = functionPrinter({ mode: "declaration" });
811
+ const declarationPrinter$4 = functionPrinter({ mode: "declaration" });
698
812
  const mutationKeyTransformer = ({ node }) => {
699
813
  if (!node.path) return [];
700
814
  return [`{ url: '${Url.toPath(node.path)}' }`];
701
815
  };
702
- function MutationKey({ name, node, transformer }) {
816
+ function MutationKey({ name, node, transformer, typeName }) {
703
817
  const paramsNode = createFunctionParameters({ params: [] });
704
- const paramsSignature = declarationPrinter$6.print(paramsNode) ?? "";
818
+ const paramsSignature = declarationPrinter$4.print(paramsNode) ?? "";
705
819
  const keys = (transformer ?? mutationKeyTransformer)({
706
820
  node,
707
821
  casing: "camelcase",
708
822
  variant: "mutation"
709
823
  });
710
- return /* @__PURE__ */ jsx(File.Source, {
824
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(File.Source, {
711
825
  name,
712
826
  isExportable: true,
713
827
  isIndexable: true,
@@ -718,7 +832,17 @@ function MutationKey({ name, node, transformer }) {
718
832
  singleLine: true,
719
833
  children: `[${keys.join(", ")}] as const`
720
834
  })
721
- });
835
+ }), typeName && /* @__PURE__ */ jsx(File.Source, {
836
+ name: typeName,
837
+ isExportable: true,
838
+ isIndexable: true,
839
+ isTypeOnly: true,
840
+ children: /* @__PURE__ */ jsx(Type, {
841
+ export: true,
842
+ name: typeName,
843
+ children: `ReturnType<typeof ${name}>`
844
+ })
845
+ })] });
722
846
  }
723
847
  //#endregion
724
848
  //#region ../../internals/tanstack-query/src/resolver.ts
@@ -773,7 +897,9 @@ function createMutationResolver() {
773
897
  }
774
898
  };
775
899
  }
776
- functionPrinter({ mode: "declaration" });
900
+ //#endregion
901
+ //#region ../../internals/tanstack-query/src/components/QueryKey.tsx
902
+ const declarationPrinter$3 = functionPrinter({ mode: "declaration" });
777
903
  const queryKeyTransformer = ({ node, variant }) => {
778
904
  if (!node.path) return [];
779
905
  const { path, query } = getOperationParameters(node);
@@ -786,6 +912,40 @@ const queryKeyTransformer = ({ node, variant }) => {
786
912
  if (node.requestBody?.content?.[0]?.schema) result.push("...(body !== undefined ? [body] : [])");
787
913
  return result;
788
914
  };
915
+ function QueryKey({ name, node, tsResolver, typeName, transformer, variant = "query", memberTypeWrapper, exportType }) {
916
+ const paramsNode = buildQueryKeyParams(node, {
917
+ resolver: tsResolver,
918
+ memberTypeWrapper
919
+ });
920
+ const paramsSignature = declarationPrinter$3.print(paramsNode) ?? "";
921
+ const keys = (transformer ?? queryKeyTransformer)({
922
+ node,
923
+ casing: "camelcase",
924
+ variant
925
+ });
926
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(File.Source, {
927
+ name,
928
+ isExportable: true,
929
+ isIndexable: true,
930
+ children: /* @__PURE__ */ jsx(Function.Arrow, {
931
+ name,
932
+ export: true,
933
+ params: paramsSignature,
934
+ singleLine: true,
935
+ children: `[${keys.join(", ")}] as const`
936
+ })
937
+ }), /* @__PURE__ */ jsx(File.Source, {
938
+ name: typeName,
939
+ isExportable: exportType,
940
+ isIndexable: exportType,
941
+ isTypeOnly: true,
942
+ children: /* @__PURE__ */ jsx(Type, {
943
+ name: typeName,
944
+ export: exportType,
945
+ children: `ReturnType<typeof ${name}>`
946
+ })
947
+ })] });
948
+ }
789
949
  //#endregion
790
950
  //#region ../../internals/client/src/resolveClient.ts
791
951
  /**
@@ -829,7 +989,7 @@ const contractPlugins = [
829
989
  * @example
830
990
  * ```ts
831
991
  * resolveClient({ client: undefined, pluginNames: ['plugin-ts'] })
832
- * // { kind: 'error', message: 'No client plugin is registered…' }
992
+ * // { kind: 'error', code: 'KUBB_MISSING_DEPENDENCY', message: 'No client plugin is registered.', help: 'Add …' }
833
993
  * ```
834
994
  */
835
995
  function resolveClient(options) {
@@ -839,7 +999,9 @@ function resolveClient(options) {
839
999
  const pluginName = selectorToPlugin[client];
840
1000
  if (!has(pluginName)) return {
841
1001
  kind: "error",
842
- message: `\`client: '${client}'\` is set but \`@kubb/plugin-${client}\` is not registered in \`plugins\`. Add it, or drop \`client\` to use a different client plugin.`
1002
+ code: Diagnostics.code.missingDependency,
1003
+ message: `\`client: '${client}'\` is set but \`@kubb/plugin-${client}\` is not registered in \`plugins\`.`,
1004
+ help: `Add \`@kubb/plugin-${client}\` to \`plugins\`, or drop \`client\` to use a different client plugin.`
843
1005
  };
844
1006
  return {
845
1007
  kind: "contract",
@@ -848,7 +1010,9 @@ function resolveClient(options) {
848
1010
  }
849
1011
  if (client !== void 0) return {
850
1012
  kind: "error",
851
- message: `Option \`client\` is ${typeof client === "string" ? `'${client}'` : String(client)}, but it must be one of 'fetch', 'axios', 'client'. Drop \`client\` to use the registered client plugin.`
1013
+ code: Diagnostics.code.invalidPluginOptions,
1014
+ message: `Option \`client\` is ${typeof client === "string" ? `'${client}'` : String(client)}, but it must be one of 'fetch', 'axios', 'client'.`,
1015
+ help: "Set `client` to one of those values, or drop it to use the registered client plugin."
852
1016
  };
853
1017
  const registered = contractPlugins.filter(has);
854
1018
  if (registered.length === 1) return {
@@ -857,25 +1021,40 @@ function resolveClient(options) {
857
1021
  };
858
1022
  if (registered.length > 1) return {
859
1023
  kind: "error",
860
- message: `Multiple client plugins are registered (${registered.map((name) => `\`@kubb/${name}\``).join(", ")}). Set \`client: 'fetch' | 'axios' | 'client'\` to choose which client the hooks call, or register a single client plugin.`
1024
+ code: Diagnostics.code.invalidPluginOptions,
1025
+ message: `Multiple client plugins are registered (${registered.map((name) => `\`@kubb/${name}\``).join(", ")}) and \`client\` is not set.`,
1026
+ help: "Set `client: 'fetch' | 'axios' | 'client'` to choose which client the hooks call, or register a single client plugin."
861
1027
  };
862
1028
  return {
863
1029
  kind: "error",
864
- message: "No client plugin is registered. Add `@kubb/plugin-axios`, `@kubb/plugin-fetch`, or `@kubb/plugin-client` to `plugins` so the generated code has an HTTP client to call."
1030
+ code: Diagnostics.code.missingDependency,
1031
+ message: "No client plugin is registered.",
1032
+ help: "Add `@kubb/plugin-fetch`, `@kubb/plugin-axios`, or `@kubb/plugin-client` to `plugins` so the generated code has an HTTP client to call."
865
1033
  };
866
1034
  }
867
1035
  /**
868
- * Resolves the contract client during a consumer plugin's setup hook. Extracts the plugin names
869
- * from the raw `plugins` config, applies {@link resolveClient}, and throws the diagnostic on a
870
- * misconfiguration so every consumer fails fast with the same message.
1036
+ * Resolves the contract client during a consumer plugin's setup hook.
1037
+ * It extracts the plugin names from the raw `plugins` config and applies {@link resolveClient}.
1038
+ * On a misconfiguration it throws a config diagnostic tagged with `plugin`, so every consumer
1039
+ * fails fast with the same message.
871
1040
  */
872
1041
  function resolveContractClient(options) {
873
- const { client, plugins = [] } = options;
1042
+ const { plugin, client, plugins = [] } = options;
874
1043
  const resolved = resolveClient({
875
1044
  client,
876
1045
  pluginNames: plugins.map((plugin) => plugin.name).filter((name) => Boolean(name))
877
1046
  });
878
- if (resolved.kind === "error") throw new Error(resolved.message);
1047
+ if (resolved.kind === "error") {
1048
+ const { code, message, help } = resolved;
1049
+ throw new Diagnostics.Error({
1050
+ code,
1051
+ severity: "error",
1052
+ message,
1053
+ help,
1054
+ location: { kind: "config" },
1055
+ plugin
1056
+ });
1057
+ }
879
1058
  return resolved;
880
1059
  }
881
1060
  //#endregion
@@ -939,66 +1118,9 @@ function resolveClientOperation(options) {
939
1118
  });
940
1119
  }
941
1120
  //#endregion
942
- //#region src/utils.ts
943
- /**
944
- * Builds the call to a contract client `<op>` function inside a vue-query composable body. The
945
- * function takes a single grouped options object, so `config` is spread first, then the operation's
946
- * request groups are unwrapped with `toValue()`, then the abort `signal` for queries, with
947
- * `throwOnError: true` pinned last so a caller's config can't flip the query's error semantics.
948
- * Mutations omit the `signal`.
949
- */
950
- function buildVueClientCall(node, options) {
951
- return buildClientCall(node, {
952
- ...options,
953
- unwrapName: (name) => `toValue(${name})`
954
- });
955
- }
956
- //#endregion
957
- //#region src/components/QueryKey.tsx
958
- const declarationPrinter$4 = functionPrinter({ mode: "declaration" });
959
- function buildQueryKeyParamsNode(node, options) {
960
- const groupedParam = buildGroupedRequestParam(node, {
961
- resolver: options.resolver,
962
- keys: queryKeyGroupOrder,
963
- memberTypeWrapper: maybeRefOrGetter
964
- });
965
- return createFunctionParameters({ params: groupedParam ? [groupedParam] : [] });
966
- }
967
- function QueryKey({ name, node, tsResolver, typeName, transformer, variant = "query" }) {
968
- const paramsNode = buildQueryKeyParamsNode(node, { resolver: tsResolver });
969
- const paramsSignature = declarationPrinter$4.print(paramsNode) ?? "";
970
- const keys = (transformer ?? queryKeyTransformer)({
971
- node,
972
- casing: "camelcase",
973
- variant
974
- });
975
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(File.Source, {
976
- name,
977
- isExportable: true,
978
- isIndexable: true,
979
- children: /* @__PURE__ */ jsx(Function.Arrow, {
980
- name,
981
- export: true,
982
- params: paramsSignature,
983
- singleLine: true,
984
- children: `[${keys.join(", ")}] as const`
985
- })
986
- }), /* @__PURE__ */ jsx(File.Source, {
987
- name: typeName,
988
- isExportable: true,
989
- isIndexable: true,
990
- isTypeOnly: true,
991
- children: /* @__PURE__ */ jsx(Type, {
992
- name: typeName,
993
- export: true,
994
- children: `ReturnType<typeof ${name}>`
995
- })
996
- })] });
997
- }
998
- //#endregion
999
1121
  //#region src/components/QueryOptions.tsx
1000
- const declarationPrinter$3 = functionPrinter({ mode: "declaration" });
1001
- const callPrinter$3 = functionPrinter({ mode: "call" });
1122
+ const declarationPrinter$2 = functionPrinter({ mode: "declaration" });
1123
+ const callPrinter$2 = functionPrinter({ mode: "call" });
1002
1124
  function getQueryOptionsParams(node, options) {
1003
1125
  return buildQueryOptionsParams(node, {
1004
1126
  resolver: options.resolver,
@@ -1007,13 +1129,17 @@ function getQueryOptionsParams(node, options) {
1007
1129
  }
1008
1130
  function QueryOptions({ name, clientName, node, tsResolver, queryKeyName, returnType = "full" }) {
1009
1131
  const { TData, TError } = buildResponseTypes(node, tsResolver);
1010
- const queryKeyParamsNode = buildQueryKeyParamsNode(node, { resolver: tsResolver });
1011
- const queryKeyParamsCall = callPrinter$3.print(queryKeyParamsNode) ?? "";
1132
+ const queryKeyParamsNode = buildQueryKeyParams(node, {
1133
+ resolver: tsResolver,
1134
+ memberTypeWrapper: maybeRefOrGetter
1135
+ });
1136
+ const queryKeyParamsCall = callPrinter$2.print(queryKeyParamsNode) ?? "";
1012
1137
  const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
1013
- const paramsSignature = declarationPrinter$3.print(paramsNode) ?? "";
1014
- const queryFnBody = buildCallResultBody(buildVueClientCall(node, {
1138
+ const paramsSignature = declarationPrinter$2.print(paramsNode) ?? "";
1139
+ const queryFnBody = buildCallResultBody(buildClientCall(node, {
1015
1140
  clientName,
1016
- signal: true
1141
+ signal: true,
1142
+ unwrapName: (name) => `toValue(${name})`
1017
1143
  }), { returnType });
1018
1144
  return /* @__PURE__ */ jsx(File.Source, {
1019
1145
  name,
@@ -1036,201 +1162,61 @@ function QueryOptions({ name, clientName, node, tsResolver, queryKeyName, return
1036
1162
  });
1037
1163
  }
1038
1164
  //#endregion
1039
- //#region src/components/InfiniteQuery.tsx
1040
- const declarationPrinter$2 = functionPrinter({ mode: "declaration" });
1041
- const callPrinter$2 = functionPrinter({ mode: "call" });
1042
- function buildInfiniteQueryParamsNode(node, options) {
1043
- const { resolver } = options;
1044
- const { TData, TError } = buildResponseTypes(node, resolver);
1045
- const optionsParam = createFunctionParameter({
1046
- name: "options",
1047
- type: `{
1048
- query?: Partial<UseInfiniteQueryOptions<${[
1049
- TData,
1050
- TError,
1051
- "TQueryData",
1052
- "TQueryKey",
1053
- "TQueryData"
1054
- ].join(", ")}>> & { client?: QueryClient },
1055
- client?: ${buildClientOptionType()}
1056
- }`,
1057
- default: "{}"
1058
- });
1059
- const groupedParam = buildGroupedRequestParam(node, {
1060
- resolver,
1061
- memberTypeWrapper: maybeRefOrGetter
1062
- });
1063
- return createFunctionParameters({ params: [groupedParam, optionsParam].filter((param) => param !== null) });
1064
- }
1065
- function InfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver }) {
1165
+ //#region src/components/Query.tsx
1166
+ const declarationPrinter$1 = functionPrinter({ mode: "declaration" });
1167
+ const callPrinter$1 = functionPrinter({ mode: "call" });
1168
+ function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, infinite }) {
1066
1169
  const { TData, TError } = buildResponseTypes(node, tsResolver);
1067
- const returnType = `UseInfiniteQueryReturnType<${["TData", TError].join(", ")}> & { queryKey: TQueryKey }`;
1170
+ const optionsName = infinite ? "UseInfiniteQueryOptions" : "UseQueryOptions";
1171
+ const hookName = infinite ? "useInfiniteQuery" : "useQuery";
1172
+ const returnType = `${infinite ? "UseInfiniteQueryReturnType" : "UseQueryReturnType"}<${["TData", TError].join(", ")}> & { queryKey: TQueryKey }`;
1068
1173
  const generics = [
1069
- `TData = InfiniteData<${TData}>`,
1174
+ infinite ? `TData = InfiniteData<${TData}>` : `TData = ${TData}`,
1070
1175
  `TQueryData = ${TData}`,
1071
1176
  `TQueryKey extends QueryKey = ${queryKeyTypeName}`
1072
1177
  ];
1073
- const queryKeyParamsNode = buildQueryKeyParamsNode(node, { resolver: tsResolver });
1074
- const queryKeyParamsCall = callPrinter$2.print(queryKeyParamsNode) ?? "";
1075
- const queryOptionsParamsNode = getQueryOptionsParams(node, { resolver: tsResolver });
1076
- const queryOptionsParamsCall = callPrinter$2.print(queryOptionsParamsNode) ?? "";
1077
- const paramsNode = buildInfiniteQueryParamsNode(node, { resolver: tsResolver });
1078
- const paramsSignature = declarationPrinter$2.print(paramsNode) ?? "";
1079
- return /* @__PURE__ */ jsx(File.Source, {
1080
- name,
1081
- isExportable: true,
1082
- isIndexable: true,
1083
- children: /* @__PURE__ */ jsx(Function, {
1084
- name,
1085
- export: true,
1086
- generics: generics.join(", "),
1087
- params: paramsSignature,
1088
- JSDoc: { comments: buildOperationComments(node) },
1089
- children: `
1090
- const { query: queryConfig = {}, client: config = {} } = options ?? {}
1091
- const { client: queryClient, ...resolvedOptions } = queryConfig
1092
- const queryKey = (resolvedOptions && 'queryKey' in resolvedOptions ? toValue(resolvedOptions.queryKey) : undefined) ?? ${queryKeyName}(${queryKeyParamsCall})
1093
-
1094
- const queryResult = useInfiniteQuery({
1095
- ...${queryOptionsName}(${queryOptionsParamsCall}),
1096
- ...resolvedOptions,
1097
- queryKey
1098
- } as unknown as UseInfiniteQueryOptions<${TData}, ${TError}, ${TData}, TQueryKey, ${TData}>, toValue(queryClient)) as ${returnType}
1099
-
1100
- queryResult.queryKey = queryKey as TQueryKey
1101
-
1102
- return queryResult
1103
- `
1104
- })
1105
- });
1106
- }
1107
- //#endregion
1108
- //#region src/components/InfiniteQueryOptions.tsx
1109
- /**
1110
- * The vue-query flavor of the shared `infiniteQueryOptions` component: request groups accept
1111
- * `MaybeRefOrGetter` values, are unwrapped with `toValue(...)` in the client call, and the emitted
1112
- * `TQueryKey` generic is the imported `QueryKey` type instead of `typeof queryKey`.
1113
- */
1114
- function InfiniteQueryOptions(props) {
1115
- return /* @__PURE__ */ jsx(InfiniteQueryOptions$1, {
1116
- ...props,
1117
- queryKeyType: "QueryKey",
1118
- memberTypeWrapper: maybeRefOrGetter,
1119
- unwrapName: (name) => `toValue(${name})`
1120
- });
1121
- }
1122
- //#endregion
1123
- //#region src/components/Mutation.tsx
1124
- const declarationPrinter$1 = functionPrinter({ mode: "declaration" });
1125
- const callPrinter$1 = functionPrinter({ mode: "call" });
1126
- function resolveMutationRequestType(node, resolver) {
1127
- return buildGroupedRequestParam(node, { resolver }) ? resolver.response.options(node) : "undefined";
1128
- }
1129
- function buildMutationParamsNode(node, options) {
1130
- const { resolver } = options;
1131
- const { TData, TError } = buildResponseTypes(node, resolver);
1132
- const TRequest = resolveMutationRequestType(node, resolver);
1133
- return createFunctionParameters({ params: [createFunctionParameter({
1134
- name: "options",
1135
- type: `{
1136
- mutation?: MutationObserverOptions<${[
1137
- TData,
1138
- TError,
1139
- TRequest,
1140
- "TContext"
1141
- ].join(", ")}> & { client?: QueryClient },
1142
- client?: ${buildRequestConfigType(node)},
1143
- }`,
1144
- default: "{}"
1145
- })] });
1146
- }
1147
- function Mutation({ name, clientName, node, tsResolver, mutationKeyName, returnType = "full" }) {
1148
- const { TData, TError } = buildResponseTypes(node, tsResolver);
1149
- const groupedParam = buildGroupedRequestParam(node, { resolver: tsResolver });
1150
- const hasMutationParams = groupedParam !== null;
1151
- const groupedParamsNode = createFunctionParameters({ params: groupedParam ? [groupedParam] : [] });
1152
- const argBindingStr = hasMutationParams ? callPrinter$1.print(groupedParamsNode) ?? "" : "";
1153
- const TRequest = resolveMutationRequestType(node, tsResolver);
1154
- const mutationFnBody = buildCallResultBody(buildClientCall(node, {
1155
- clientName,
1156
- signal: false,
1157
- unwrapName: (name) => `toValue<${TRequest}['${name}']>(${name})`
1158
- }), { returnType });
1159
- const generics = [
1178
+ const optionsGenerics = infinite ? [
1160
1179
  TData,
1161
1180
  TError,
1162
- TRequest,
1163
- "TContext"
1164
- ].join(", ");
1165
- const paramsNode = buildMutationParamsNode(node, { resolver: tsResolver });
1166
- const paramsSignature = declarationPrinter$1.print(paramsNode) ?? "";
1167
- return /* @__PURE__ */ jsx(File.Source, {
1168
- name,
1169
- isExportable: true,
1170
- isIndexable: true,
1171
- children: /* @__PURE__ */ jsx(Function, {
1172
- name,
1173
- export: true,
1174
- params: paramsSignature,
1175
- JSDoc: { comments: buildOperationComments(node) },
1176
- generics: ["TContext"],
1177
- children: `
1178
- const { mutation = {}, client: config = {} } = options ?? {}
1179
- const { client: queryClient, ...mutationOptions } = mutation;
1180
- const mutationKey = mutationOptions?.mutationKey ?? ${mutationKeyName}()
1181
-
1182
- return useMutation<${generics}>({
1183
- mutationFn: async(${argBindingStr}) => {
1184
- ${mutationFnBody}
1185
- },
1186
- mutationKey,
1187
- ...mutationOptions
1188
- }, queryClient)
1189
- `
1190
- })
1191
- });
1192
- }
1193
- //#endregion
1194
- //#region src/components/Query.tsx
1195
- const declarationPrinter = functionPrinter({ mode: "declaration" });
1196
- const callPrinter = functionPrinter({ mode: "call" });
1197
- function buildQueryParamsNode(node, options) {
1198
- const { resolver } = options;
1199
- const { TData, TError } = buildResponseTypes(node, resolver);
1200
- const optionsParam = createFunctionParameter({
1201
- name: "options",
1202
- type: `{
1203
- query?: Partial<UseQueryOptions<${[
1204
- TData,
1205
- TError,
1206
- "TData",
1207
- "TQueryData",
1208
- "TQueryKey"
1209
- ].join(", ")}>> & { client?: QueryClient },
1210
- client?: ${buildClientOptionType()}
1211
- }`,
1212
- default: "{}"
1213
- });
1214
- const groupedParam = buildGroupedRequestParam(node, {
1215
- resolver,
1181
+ "TQueryData",
1182
+ "TQueryKey",
1183
+ "TQueryData"
1184
+ ] : [
1185
+ TData,
1186
+ TError,
1187
+ "TData",
1188
+ "TQueryData",
1189
+ "TQueryKey"
1190
+ ];
1191
+ const castGenerics = infinite ? [
1192
+ TData,
1193
+ TError,
1194
+ TData,
1195
+ "TQueryKey",
1196
+ TData
1197
+ ] : [
1198
+ TData,
1199
+ TError,
1200
+ "TData",
1201
+ TData,
1202
+ "TQueryKey"
1203
+ ];
1204
+ const queryKeyParamsNode = buildQueryKeyParams(node, {
1205
+ resolver: tsResolver,
1216
1206
  memberTypeWrapper: maybeRefOrGetter
1217
1207
  });
1218
- return createFunctionParameters({ params: [groupedParam, optionsParam].filter((param) => param !== null) });
1219
- }
1220
- function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver }) {
1221
- const { TData, TError } = buildResponseTypes(node, tsResolver);
1222
- const returnType = `UseQueryReturnType<${["TData", TError].join(", ")}> & { queryKey: TQueryKey }`;
1223
- const generics = [
1224
- `TData = ${TData}`,
1225
- `TQueryData = ${TData}`,
1226
- `TQueryKey extends QueryKey = ${queryKeyTypeName}`
1227
- ];
1228
- const queryKeyParamsNode = buildQueryKeyParamsNode(node, { resolver: tsResolver });
1229
- const queryKeyParamsCall = callPrinter.print(queryKeyParamsNode) ?? "";
1208
+ const queryKeyParamsCall = callPrinter$1.print(queryKeyParamsNode) ?? "";
1230
1209
  const queryOptionsParamsNode = getQueryOptionsParams(node, { resolver: tsResolver });
1231
- const queryOptionsParamsCall = callPrinter.print(queryOptionsParamsNode) ?? "";
1232
- const paramsNode = buildQueryParamsNode(node, { resolver: tsResolver });
1233
- const paramsSignature = declarationPrinter.print(paramsNode) ?? "";
1210
+ const queryOptionsParamsCall = callPrinter$1.print(queryOptionsParamsNode) ?? "";
1211
+ const paramsNode = buildHookParams(node, {
1212
+ resolver: tsResolver,
1213
+ memberTypeWrapper: maybeRefOrGetter,
1214
+ optionsType: `{
1215
+ query?: Partial<${optionsName}<${optionsGenerics.join(", ")}>> & { client?: QueryClient },
1216
+ client?: ${buildClientOptionType()}
1217
+ }`
1218
+ });
1219
+ const paramsSignature = declarationPrinter$1.print(paramsNode) ?? "";
1234
1220
  return /* @__PURE__ */ jsx(File.Source, {
1235
1221
  name,
1236
1222
  isExportable: true,
@@ -1246,11 +1232,11 @@ function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, t
1246
1232
  const { client: queryClient, ...resolvedOptions } = queryConfig
1247
1233
  const queryKey = (resolvedOptions && 'queryKey' in resolvedOptions ? toValue(resolvedOptions.queryKey) : undefined) ?? ${queryKeyName}(${queryKeyParamsCall})
1248
1234
 
1249
- const queryResult = useQuery({
1235
+ const queryResult = ${hookName}({
1250
1236
  ...${queryOptionsName}(${queryOptionsParamsCall}),
1251
1237
  ...resolvedOptions,
1252
1238
  queryKey
1253
- } as unknown as UseQueryOptions<${TData}, ${TError}, TData, ${TData}, TQueryKey>, toValue(queryClient)) as ${returnType}
1239
+ } as unknown as ${optionsName}<${castGenerics.join(", ")}>, toValue(queryClient)) as ${returnType}
1254
1240
 
1255
1241
  queryResult.queryKey = queryKey as TQueryKey
1256
1242
 
@@ -1284,14 +1270,12 @@ const infiniteQueryGenerator = defineGenerator({
1284
1270
  },
1285
1271
  operation(node, ctx) {
1286
1272
  if (!ast.isHttpOperationNode(node)) return null;
1287
- const { config, driver, resolver, root } = ctx;
1273
+ const { driver, resolver, root } = ctx;
1288
1274
  const { output, query, infinite, client, group } = ctx.options;
1289
1275
  const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
1290
1276
  if (!infiniteOptions) return null;
1291
1277
  const pageParamsWarning = getDefaultPageParamsWarning(node, infiniteOptions);
1292
1278
  if (pageParamsWarning) ctx.warn(pageParamsWarning);
1293
- const pluginTs = ctx.requirePlugin(pluginTsName);
1294
- const tsResolver = driver.getResolver(pluginTsName);
1295
1279
  const importPath = query ? query.importPath : "@tanstack/vue-query";
1296
1280
  const contractOp = resolveClientOperation({
1297
1281
  clientPlugin: { pluginName: client.pluginName },
@@ -1306,91 +1290,39 @@ const infiniteQueryGenerator = defineGenerator({
1306
1290
  const queryOptionsName = resolver.infiniteQuery.optionsName(node);
1307
1291
  const queryKeyName = resolver.infiniteQuery.keyName(node);
1308
1292
  const queryKeyTypeName = resolver.infiniteQuery.keyTypeName(node);
1309
- const meta = {
1310
- file: resolver.file({
1311
- ...operationFileEntry(node, queryName),
1312
- root,
1313
- output,
1314
- group: group ?? void 0
1315
- }),
1316
- fileTs: resolveDependencyOperationFile({
1317
- cache: ctx.cache,
1318
- node,
1319
- resolver: tsResolver,
1320
- root,
1321
- output: pluginTs.options?.output ?? output,
1322
- group: pluginTs.options?.group
1323
- })
1324
- };
1325
- const { queryParamsTypeName } = resolvePageParamType(node, {
1326
- resolver: tsResolver,
1327
- initialPageParam: infiniteOptions.initialPageParam,
1328
- queryParam: infiniteOptions.queryParam
1293
+ const hook = resolveHookFile(node, ctx, {
1294
+ name: queryName,
1295
+ output,
1296
+ group,
1297
+ contractOp,
1298
+ keyTypeName: queryKeyTypeName,
1299
+ extraTypeNames: [resolvePageParamType(node, {
1300
+ resolver: ctx.driver.getResolver(pluginTsName),
1301
+ initialPageParam: infiniteOptions.initialPageParam,
1302
+ queryParam: infiniteOptions.queryParam
1303
+ }).queryParamsTypeName]
1329
1304
  });
1330
- const importedTypeNames = [
1331
- tsResolver.response.options(node),
1332
- queryParamsTypeName,
1333
- ...resolveOperationTypeNames(node, tsResolver, {
1334
- exclude: [queryKeyTypeName],
1335
- order: "body-response-first",
1336
- includeParams: false
1337
- })
1338
- ].filter((name) => Boolean(name));
1339
- const calledClientName = contractOp.name;
1340
- return /* @__PURE__ */ jsxs(File, {
1341
- baseName: meta.file.baseName,
1342
- path: meta.file.path,
1343
- meta: meta.file.meta,
1344
- banner: resolver.default.banner(ctx.meta, {
1345
- output,
1346
- config,
1347
- file: {
1348
- path: meta.file.path,
1349
- baseName: meta.file.baseName
1350
- }
1351
- }),
1352
- footer: resolver.default.footer(ctx.meta, {
1353
- output,
1354
- config,
1355
- file: {
1356
- path: meta.file.path,
1357
- baseName: meta.file.baseName
1358
- }
1359
- }),
1305
+ const { tsResolver } = hook;
1306
+ return /* @__PURE__ */ jsxs(HookFile, {
1307
+ hook,
1308
+ imports: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(File.Import, {
1309
+ name: ["toValue"],
1310
+ path: "vue"
1311
+ }), /* @__PURE__ */ jsx(File.Import, {
1312
+ name: ["MaybeRefOrGetter"],
1313
+ path: "vue",
1314
+ isTypeOnly: true
1315
+ })] }),
1360
1316
  children: [
1361
- /* @__PURE__ */ jsx(File.Import, {
1362
- name: [contractOp.name],
1363
- root: meta.file.path,
1364
- path: contractOp.path
1365
- }),
1366
- /* @__PURE__ */ jsx(File.Import, {
1367
- name: ["RequestConfig", "ResponseErrorConfig"],
1368
- root: contractOp.clientPathIsFile ? meta.file.path : void 0,
1369
- path: contractOp.clientPath,
1370
- isTypeOnly: true
1371
- }),
1372
- /* @__PURE__ */ jsx(File.Import, {
1373
- name: ["toValue"],
1374
- path: "vue"
1375
- }),
1376
- /* @__PURE__ */ jsx(File.Import, {
1377
- name: ["MaybeRefOrGetter"],
1378
- path: "vue",
1379
- isTypeOnly: true
1380
- }),
1381
- meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
1382
- name: Array.from(new Set(importedTypeNames)),
1383
- root: meta.file.path,
1384
- path: meta.fileTs.path,
1385
- isTypeOnly: true
1386
- }),
1387
1317
  /* @__PURE__ */ jsx(QueryKey, {
1388
1318
  name: queryKeyName,
1389
1319
  typeName: queryKeyTypeName,
1390
1320
  node,
1391
1321
  tsResolver,
1392
1322
  transformer: ctx.options.queryKey,
1393
- variant: "infiniteQuery"
1323
+ variant: "infiniteQuery",
1324
+ memberTypeWrapper: maybeRefOrGetter,
1325
+ exportType: true
1394
1326
  }),
1395
1327
  /* @__PURE__ */ jsx(File.Import, {
1396
1328
  name: ["InfiniteData"],
@@ -1403,7 +1335,7 @@ const infiniteQueryGenerator = defineGenerator({
1403
1335
  }),
1404
1336
  /* @__PURE__ */ jsx(InfiniteQueryOptions, {
1405
1337
  name: queryOptionsName,
1406
- clientName: calledClientName,
1338
+ clientName: contractOp.name,
1407
1339
  queryKeyName,
1408
1340
  node,
1409
1341
  tsResolver,
@@ -1415,7 +1347,10 @@ const infiniteQueryGenerator = defineGenerator({
1415
1347
  initialPageParam: infiniteOptions.initialPageParam,
1416
1348
  hasExplicitInitialPageParam: infiniteOptions.hasExplicitInitialPageParam,
1417
1349
  queryParam: infiniteOptions.queryParam,
1418
- returnType: contractOp.returnType
1350
+ returnType: contractOp.returnType,
1351
+ queryKeyType: "QueryKey",
1352
+ memberTypeWrapper: maybeRefOrGetter,
1353
+ unwrapName: (name) => `toValue(${name})`
1419
1354
  }),
1420
1355
  /* @__PURE__ */ jsx(File.Import, {
1421
1356
  name: ["useInfiniteQuery"],
@@ -1431,21 +1366,87 @@ const infiniteQueryGenerator = defineGenerator({
1431
1366
  path: importPath,
1432
1367
  isTypeOnly: true
1433
1368
  }),
1434
- /* @__PURE__ */ jsx(InfiniteQuery, {
1369
+ /* @__PURE__ */ jsx(Query, {
1435
1370
  name: queryName,
1436
1371
  queryOptionsName,
1437
1372
  queryKeyName,
1438
1373
  queryKeyTypeName,
1439
1374
  node,
1440
1375
  tsResolver,
1441
- initialPageParam: infiniteOptions.initialPageParam,
1442
- queryParam: infiniteOptions.queryParam
1376
+ infinite: true
1443
1377
  })
1444
1378
  ]
1445
1379
  });
1446
1380
  }
1447
1381
  });
1448
1382
  //#endregion
1383
+ //#region src/components/Mutation.tsx
1384
+ const declarationPrinter = functionPrinter({ mode: "declaration" });
1385
+ const callPrinter = functionPrinter({ mode: "call" });
1386
+ function buildMutationParamsNode(node, options) {
1387
+ const { resolver } = options;
1388
+ const { TData, TError } = buildResponseTypes(node, resolver);
1389
+ return buildHookParams(node, {
1390
+ resolver,
1391
+ withRequest: false,
1392
+ optionsType: `{
1393
+ mutation?: MutationObserverOptions<${[
1394
+ TData,
1395
+ TError,
1396
+ resolveMutationRequestType(node, resolver),
1397
+ "TContext"
1398
+ ].join(", ")}> & { client?: QueryClient },
1399
+ client?: ${buildRequestConfigType(node)},
1400
+ }`
1401
+ });
1402
+ }
1403
+ function Mutation({ name, clientName, node, tsResolver, mutationKeyName, returnType = "full" }) {
1404
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1405
+ const groupedParam = buildGroupedRequestParam(node, { resolver: tsResolver });
1406
+ const hasMutationParams = groupedParam !== null;
1407
+ const groupedParamsNode = createFunctionParameters({ params: groupedParam ? [groupedParam] : [] });
1408
+ const argBindingStr = hasMutationParams ? callPrinter.print(groupedParamsNode) ?? "" : "";
1409
+ const TRequest = resolveMutationRequestType(node, tsResolver);
1410
+ const mutationFnBody = buildCallResultBody(buildClientCall(node, {
1411
+ clientName,
1412
+ signal: false,
1413
+ unwrapName: (name) => `toValue<${TRequest}['${name}']>(${name})`
1414
+ }), { returnType });
1415
+ const generics = [
1416
+ TData,
1417
+ TError,
1418
+ TRequest,
1419
+ "TContext"
1420
+ ].join(", ");
1421
+ const paramsNode = buildMutationParamsNode(node, { resolver: tsResolver });
1422
+ const paramsSignature = declarationPrinter.print(paramsNode) ?? "";
1423
+ return /* @__PURE__ */ jsx(File.Source, {
1424
+ name,
1425
+ isExportable: true,
1426
+ isIndexable: true,
1427
+ children: /* @__PURE__ */ jsx(Function, {
1428
+ name,
1429
+ export: true,
1430
+ params: paramsSignature,
1431
+ JSDoc: { comments: buildOperationComments(node) },
1432
+ generics: ["TContext"],
1433
+ children: `
1434
+ const { mutation = {}, client: config = {} } = options ?? {}
1435
+ const { client: queryClient, ...mutationOptions } = mutation;
1436
+ const mutationKey = mutationOptions?.mutationKey ?? ${mutationKeyName}()
1437
+
1438
+ return useMutation<${generics}>({
1439
+ mutationFn: async(${argBindingStr}) => {
1440
+ ${mutationFnBody}
1441
+ },
1442
+ mutationKey,
1443
+ ...mutationOptions
1444
+ }, queryClient)
1445
+ `
1446
+ })
1447
+ });
1448
+ }
1449
+ //#endregion
1449
1450
  //#region src/generators/mutationGenerator.tsx
1450
1451
  /**
1451
1452
  * Built-in generator for `useMutation` composables. Emits one
@@ -1457,10 +1458,8 @@ const mutationGenerator = defineGenerator({
1457
1458
  renderer: jsxRenderer,
1458
1459
  operation(node, ctx) {
1459
1460
  if (!ast.isHttpOperationNode(node)) return null;
1460
- const { config, driver, resolver, root } = ctx;
1461
+ const { driver, resolver, root } = ctx;
1461
1462
  const { output, query, mutation, client, group, hooks } = ctx.options;
1462
- const pluginTs = ctx.requirePlugin(pluginTsName);
1463
- const tsResolver = driver.getResolver(pluginTsName);
1464
1463
  const { isMutation } = classifyOperation(node, {
1465
1464
  query,
1466
1465
  mutation
@@ -1477,104 +1476,48 @@ const mutationGenerator = defineGenerator({
1477
1476
  });
1478
1477
  if (!contractOp) return null;
1479
1478
  const mutationHookName = resolver.mutation.name(node);
1480
- const mutationTypeName = resolver.mutation.typeName(node);
1481
1479
  const mutationKeyName = resolver.mutation.keyName(node);
1482
- const meta = {
1483
- file: resolver.file({
1484
- ...operationFileEntry(node, mutationHookName),
1485
- root,
1486
- output,
1487
- group: group ?? void 0
1488
- }),
1489
- fileTs: resolveDependencyOperationFile({
1490
- cache: ctx.cache,
1491
- node,
1492
- resolver: tsResolver,
1493
- root,
1494
- output: pluginTs.options?.output ?? output,
1495
- group: pluginTs.options?.group
1496
- })
1497
- };
1498
- const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
1499
- order: "body-response-first",
1500
- includeParams: false
1501
- })].filter((name) => Boolean(name));
1502
- const calledClientName = contractOp.name;
1480
+ const hook = resolveHookFile(node, ctx, {
1481
+ name: mutationHookName,
1482
+ output,
1483
+ group,
1484
+ contractOp
1485
+ });
1503
1486
  const groups = getRequestGroups(node);
1504
1487
  const hasRequestGroups = groups.path || groups.query || groups.body || groups.headers;
1505
- return /* @__PURE__ */ jsxs(File, {
1506
- baseName: meta.file.baseName,
1507
- path: meta.file.path,
1508
- meta: meta.file.meta,
1509
- banner: resolver.default.banner(ctx.meta, {
1510
- output,
1511
- config,
1512
- file: {
1513
- path: meta.file.path,
1514
- baseName: meta.file.baseName
1515
- }
1516
- }),
1517
- footer: resolver.default.footer(ctx.meta, {
1518
- output,
1519
- config,
1520
- file: {
1521
- path: meta.file.path,
1522
- baseName: meta.file.baseName
1523
- }
1524
- }),
1525
- children: [
1526
- /* @__PURE__ */ jsx(File.Import, {
1527
- name: [contractOp.name],
1528
- root: meta.file.path,
1529
- path: contractOp.path
1530
- }),
1488
+ return /* @__PURE__ */ jsxs(HookFile, {
1489
+ hook,
1490
+ imports: /* @__PURE__ */ jsxs(Fragment, { children: [hasRequestGroups && /* @__PURE__ */ jsx(File.Import, {
1491
+ name: ["toValue"],
1492
+ path: "vue"
1493
+ }), /* @__PURE__ */ jsx(File.Import, {
1494
+ name: ["MaybeRefOrGetter"],
1495
+ path: "vue",
1496
+ isTypeOnly: true
1497
+ })] }),
1498
+ children: [/* @__PURE__ */ jsx(MutationKey, {
1499
+ name: mutationKeyName,
1500
+ node,
1501
+ transformer: ctx.options.mutationKey
1502
+ }), mutation && hooks && /* @__PURE__ */ jsxs(Fragment, { children: [
1531
1503
  /* @__PURE__ */ jsx(File.Import, {
1532
- name: ["RequestConfig", "ResponseErrorConfig"],
1533
- root: contractOp.clientPathIsFile ? meta.file.path : void 0,
1534
- path: contractOp.clientPath,
1535
- isTypeOnly: true
1536
- }),
1537
- hasRequestGroups && /* @__PURE__ */ jsx(File.Import, {
1538
- name: ["toValue"],
1539
- path: "vue"
1504
+ name: ["useMutation"],
1505
+ path: importPath
1540
1506
  }),
1541
1507
  /* @__PURE__ */ jsx(File.Import, {
1542
- name: ["MaybeRefOrGetter"],
1543
- path: "vue",
1544
- isTypeOnly: true
1545
- }),
1546
- meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
1547
- name: Array.from(new Set(importedTypeNames)),
1548
- root: meta.file.path,
1549
- path: meta.fileTs.path,
1508
+ name: ["MutationObserverOptions", "QueryClient"],
1509
+ path: importPath,
1550
1510
  isTypeOnly: true
1551
1511
  }),
1552
- /* @__PURE__ */ jsx(MutationKey, {
1553
- name: mutationKeyName,
1512
+ /* @__PURE__ */ jsx(Mutation, {
1513
+ name: mutationHookName,
1514
+ clientName: contractOp.name,
1554
1515
  node,
1555
- transformer: ctx.options.mutationKey
1556
- }),
1557
- mutation && hooks && /* @__PURE__ */ jsxs(Fragment, { children: [
1558
- /* @__PURE__ */ jsx(File.Import, {
1559
- name: ["useMutation"],
1560
- path: importPath
1561
- }),
1562
- /* @__PURE__ */ jsx(File.Import, {
1563
- name: ["MutationObserverOptions", "QueryClient"],
1564
- path: importPath,
1565
- isTypeOnly: true
1566
- }),
1567
- /* @__PURE__ */ jsx(Mutation, {
1568
- name: mutationHookName,
1569
- clientName: calledClientName,
1570
- typeName: mutationTypeName,
1571
- node,
1572
- tsResolver,
1573
- mutationKeyName,
1574
- returnType: contractOp.returnType
1575
- })
1576
- ] })
1577
- ]
1516
+ tsResolver: hook.tsResolver,
1517
+ mutationKeyName,
1518
+ returnType: contractOp.returnType
1519
+ })
1520
+ ] })]
1578
1521
  });
1579
1522
  }
1580
1523
  });
@@ -1590,10 +1533,8 @@ const queryGenerator = defineGenerator({
1590
1533
  renderer: jsxRenderer,
1591
1534
  operation(node, ctx) {
1592
1535
  if (!ast.isHttpOperationNode(node)) return null;
1593
- const { config, driver, resolver, root } = ctx;
1536
+ const { driver, resolver, root } = ctx;
1594
1537
  const { output, query, mutation, client, group, hooks } = ctx.options;
1595
- const pluginTs = ctx.requirePlugin(pluginTsName);
1596
- const tsResolver = driver.getResolver(pluginTsName);
1597
1538
  const { isQuery, isMutation } = classifyOperation(node, {
1598
1539
  query,
1599
1540
  mutation
@@ -1613,82 +1554,34 @@ const queryGenerator = defineGenerator({
1613
1554
  const queryOptionsName = resolver.query.optionsName(node);
1614
1555
  const queryKeyName = resolver.query.keyName(node);
1615
1556
  const queryKeyTypeName = resolver.query.keyTypeName(node);
1616
- const meta = {
1617
- file: resolver.file({
1618
- ...operationFileEntry(node, queryName),
1619
- root,
1620
- output,
1621
- group: group ?? void 0
1622
- }),
1623
- fileTs: resolveDependencyOperationFile({
1624
- cache: ctx.cache,
1625
- node,
1626
- resolver: tsResolver,
1627
- root,
1628
- output: pluginTs.options?.output ?? output,
1629
- group: pluginTs.options?.group
1630
- })
1631
- };
1632
- const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
1633
- exclude: [queryKeyTypeName],
1634
- order: "body-response-first",
1635
- includeParams: false
1636
- })].filter((name) => Boolean(name));
1637
- const calledClientName = contractOp.name;
1638
- return /* @__PURE__ */ jsxs(File, {
1639
- baseName: meta.file.baseName,
1640
- path: meta.file.path,
1641
- meta: meta.file.meta,
1642
- banner: resolver.default.banner(ctx.meta, {
1643
- output,
1644
- config,
1645
- file: {
1646
- path: meta.file.path,
1647
- baseName: meta.file.baseName
1648
- }
1649
- }),
1650
- footer: resolver.default.footer(ctx.meta, {
1651
- output,
1652
- config,
1653
- file: {
1654
- path: meta.file.path,
1655
- baseName: meta.file.baseName
1656
- }
1657
- }),
1557
+ const hook = resolveHookFile(node, ctx, {
1558
+ name: queryName,
1559
+ output,
1560
+ group,
1561
+ contractOp,
1562
+ keyTypeName: queryKeyTypeName
1563
+ });
1564
+ const { tsResolver } = hook;
1565
+ return /* @__PURE__ */ jsxs(HookFile, {
1566
+ hook,
1567
+ imports: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(File.Import, {
1568
+ name: ["toValue"],
1569
+ path: "vue"
1570
+ }), /* @__PURE__ */ jsx(File.Import, {
1571
+ name: ["MaybeRefOrGetter"],
1572
+ path: "vue",
1573
+ isTypeOnly: true
1574
+ })] }),
1658
1575
  children: [
1659
- /* @__PURE__ */ jsx(File.Import, {
1660
- name: [contractOp.name],
1661
- root: meta.file.path,
1662
- path: contractOp.path
1663
- }),
1664
- /* @__PURE__ */ jsx(File.Import, {
1665
- name: ["RequestConfig", "ResponseErrorConfig"],
1666
- root: contractOp.clientPathIsFile ? meta.file.path : void 0,
1667
- path: contractOp.clientPath,
1668
- isTypeOnly: true
1669
- }),
1670
- /* @__PURE__ */ jsx(File.Import, {
1671
- name: ["toValue"],
1672
- path: "vue"
1673
- }),
1674
- /* @__PURE__ */ jsx(File.Import, {
1675
- name: ["MaybeRefOrGetter"],
1676
- path: "vue",
1677
- isTypeOnly: true
1678
- }),
1679
- meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
1680
- name: Array.from(new Set(importedTypeNames)),
1681
- root: meta.file.path,
1682
- path: meta.fileTs.path,
1683
- isTypeOnly: true
1684
- }),
1685
1576
  /* @__PURE__ */ jsx(QueryKey, {
1686
1577
  name: queryKeyName,
1687
1578
  typeName: queryKeyTypeName,
1688
1579
  node,
1689
1580
  tsResolver,
1690
1581
  transformer: ctx.options.queryKey,
1691
- variant: "query"
1582
+ variant: "query",
1583
+ memberTypeWrapper: maybeRefOrGetter,
1584
+ exportType: true
1692
1585
  }),
1693
1586
  /* @__PURE__ */ jsx(File.Import, {
1694
1587
  name: ["queryOptions"],
@@ -1696,7 +1589,7 @@ const queryGenerator = defineGenerator({
1696
1589
  }),
1697
1590
  /* @__PURE__ */ jsx(QueryOptions, {
1698
1591
  name: queryOptionsName,
1699
- clientName: calledClientName,
1592
+ clientName: contractOp.name,
1700
1593
  queryKeyName,
1701
1594
  node,
1702
1595
  tsResolver,
@@ -1812,6 +1705,7 @@ const pluginVueQuery = defineExtension({
1812
1705
  return {
1813
1706
  output,
1814
1707
  client: resolveContractClient({
1708
+ plugin: pluginVueQueryName,
1815
1709
  client,
1816
1710
  plugins: useConfig().plugins
1817
1711
  }),