@kubb/plugin-react-query 5.5.0 → 5.5.3

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,29 +27,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  let kubb_kit = require("kubb/kit");
28
28
  let node_path = require("node:path");
29
29
  node_path = __toESM(node_path, 1);
30
- let _kubb_plugin_ts = require("@kubb/plugin-ts");
31
30
  let kubb_jsx = require("kubb/jsx");
31
+ let _kubb_plugin_ts = require("@kubb/plugin-ts");
32
32
  let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
33
33
  let node_fs = require("node:fs");
34
34
  node_fs = __toESM(node_fs, 1);
35
- //#region ../../internals/shared/src/params.ts
36
- /**
37
- * Drops parameters that share the same name, keeping the first.
38
- *
39
- * A malformed spec can declare the same parameter name twice within one `in` location. Both would
40
- * resolve to the same output property, so emitting both would yield an object type with a duplicate
41
- * member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:
42
- * parameter names flow through unchanged, so no two distinct names ever collide here anymore.
43
- */
44
- function dedupeParams(params) {
45
- const seen = /* @__PURE__ */ new Set();
46
- return params.filter((param) => {
47
- if (seen.has(param.name)) return false;
48
- seen.add(param.name);
49
- return true;
50
- });
51
- }
52
- //#endregion
53
35
  //#region ../../internals/shared/src/operation.ts
54
36
  /**
55
37
  * Builds the `ResolverFileParams` every operation generator passes to
@@ -119,12 +101,12 @@ function getContentTypeInfo(node) {
119
101
  function getResponseContentTypeInfo(node) {
120
102
  return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? []);
121
103
  }
104
+ const requestConfigBaseType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
122
105
  function buildRequestConfigType(node) {
123
106
  const request = getContentTypeInfo(node);
124
107
  const response = getResponseContentTypeInfo(node);
125
- const configType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
126
108
  const members = [request.isMultipleContentTypes ? `request?: ${request.contentTypeUnion}` : null, response.isMultipleContentTypes ? `response?: ${response.contentTypeUnion}` : null].filter(Boolean);
127
- return members.length ? `${configType} & { contentType?: { ${members.join("; ")} } }` : configType;
109
+ return members.length ? `${requestConfigBaseType} & { contentType?: { ${members.join("; ")} } }` : requestConfigBaseType;
128
110
  }
129
111
  /**
130
112
  * Builds the `client?:` option type shared by the generated query hooks (`useQuery`,
@@ -133,7 +115,7 @@ function buildRequestConfigType(node) {
133
115
  * content type for.
134
116
  */
135
117
  function buildClientOptionType() {
136
- return `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
118
+ return requestConfigBaseType;
137
119
  }
138
120
  /**
139
121
  * Which of the grouped request options an operation carries.
@@ -193,11 +175,19 @@ const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
193
175
  function getOperationParameters(node) {
194
176
  const cached = operationParameterGroupsByNode.get(node);
195
177
  if (cached) return cached;
178
+ const group = (location) => {
179
+ const seen = /* @__PURE__ */ new Set();
180
+ return node.parameters.filter((param) => {
181
+ if (param.in !== location || seen.has(param.name)) return false;
182
+ seen.add(param.name);
183
+ return true;
184
+ });
185
+ };
196
186
  const groups = {
197
- path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
198
- query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
199
- header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
200
- cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
187
+ path: group("path"),
188
+ query: group("query"),
189
+ header: group("header"),
190
+ cookie: group("cookie")
201
191
  };
202
192
  operationParameterGroupsByNode.set(node, groups);
203
193
  return groups;
@@ -353,11 +343,11 @@ function createGroupConfig(group) {
353
343
  //#region kubb-extension.json
354
344
  var compatibility = {
355
345
  "kubb": ">=5.8.3",
356
- "node": ">=22"
346
+ "node": ">=22.12"
357
347
  };
358
348
  //#endregion
359
349
  //#region package.json
360
- var version = "5.5.0";
350
+ var version = "5.5.3";
361
351
  //#endregion
362
352
  //#region ../../internals/client/src/resolveClient.ts
363
353
  /**
@@ -401,7 +391,7 @@ const contractPlugins = [
401
391
  * @example
402
392
  * ```ts
403
393
  * resolveClient({ client: undefined, pluginNames: ['plugin-ts'] })
404
- * // { kind: 'error', message: 'No client plugin is registered…' }
394
+ * // { kind: 'error', code: 'KUBB_MISSING_DEPENDENCY', message: 'No client plugin is registered.', help: 'Add …' }
405
395
  * ```
406
396
  */
407
397
  function resolveClient(options) {
@@ -411,7 +401,9 @@ function resolveClient(options) {
411
401
  const pluginName = selectorToPlugin[client];
412
402
  if (!has(pluginName)) return {
413
403
  kind: "error",
414
- 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.`
404
+ code: kubb_kit.Diagnostics.code.missingDependency,
405
+ message: `\`client: '${client}'\` is set but \`@kubb/plugin-${client}\` is not registered in \`plugins\`.`,
406
+ help: `Add \`@kubb/plugin-${client}\` to \`plugins\`, or drop \`client\` to use a different client plugin.`
415
407
  };
416
408
  return {
417
409
  kind: "contract",
@@ -420,7 +412,9 @@ function resolveClient(options) {
420
412
  }
421
413
  if (client !== void 0) return {
422
414
  kind: "error",
423
- 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.`
415
+ code: kubb_kit.Diagnostics.code.invalidPluginOptions,
416
+ message: `Option \`client\` is ${typeof client === "string" ? `'${client}'` : String(client)}, but it must be one of 'fetch', 'axios', 'client'.`,
417
+ help: "Set `client` to one of those values, or drop it to use the registered client plugin."
424
418
  };
425
419
  const registered = contractPlugins.filter(has);
426
420
  if (registered.length === 1) return {
@@ -429,25 +423,40 @@ function resolveClient(options) {
429
423
  };
430
424
  if (registered.length > 1) return {
431
425
  kind: "error",
432
- 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.`
426
+ code: kubb_kit.Diagnostics.code.invalidPluginOptions,
427
+ message: `Multiple client plugins are registered (${registered.map((name) => `\`@kubb/${name}\``).join(", ")}) and \`client\` is not set.`,
428
+ help: "Set `client: 'fetch' | 'axios' | 'client'` to choose which client the hooks call, or register a single client plugin."
433
429
  };
434
430
  return {
435
431
  kind: "error",
436
- 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."
432
+ code: kubb_kit.Diagnostics.code.missingDependency,
433
+ message: "No client plugin is registered.",
434
+ help: "Add `@kubb/plugin-fetch`, `@kubb/plugin-axios`, or `@kubb/plugin-client` to `plugins` so the generated code has an HTTP client to call."
437
435
  };
438
436
  }
439
437
  /**
440
- * Resolves the contract client during a consumer plugin's setup hook. Extracts the plugin names
441
- * from the raw `plugins` config, applies {@link resolveClient}, and throws the diagnostic on a
442
- * misconfiguration so every consumer fails fast with the same message.
438
+ * Resolves the contract client during a consumer plugin's setup hook.
439
+ * It extracts the plugin names from the raw `plugins` config and applies {@link resolveClient}.
440
+ * On a misconfiguration it throws a config diagnostic tagged with `plugin`, so every consumer
441
+ * fails fast with the same message.
443
442
  */
444
443
  function resolveContractClient(options) {
445
- const { client, plugins = [] } = options;
444
+ const { plugin, client, plugins = [] } = options;
446
445
  const resolved = resolveClient({
447
446
  client,
448
447
  pluginNames: plugins.map((plugin) => plugin.name).filter((name) => Boolean(name))
449
448
  });
450
- if (resolved.kind === "error") throw new Error(resolved.message);
449
+ if (resolved.kind === "error") {
450
+ const { code, message, help } = resolved;
451
+ throw new kubb_kit.Diagnostics.Error({
452
+ code,
453
+ severity: "error",
454
+ message,
455
+ help,
456
+ location: { kind: "config" },
457
+ plugin
458
+ });
459
+ }
451
460
  return resolved;
452
461
  }
453
462
  //#endregion
@@ -511,12 +520,101 @@ function resolveClientOperation(options) {
511
520
  });
512
521
  }
513
522
  //#endregion
523
+ //#region ../../internals/tanstack-query/src/components/HookFile.tsx
524
+ /**
525
+ * Resolves what every TanStack hook file shares: its file, the `@kubb/plugin-ts` file and type names, banner and footer.
526
+ */
527
+ function resolveHookFile(node, ctx, options) {
528
+ const { name, output, group, contractOp, keyTypeName, extraTypeNames = [] } = options;
529
+ const { config, root, resolver } = ctx;
530
+ const pluginTs = ctx.requirePlugin(_kubb_plugin_ts.pluginTsName);
531
+ const tsResolver = ctx.driver.getResolver(_kubb_plugin_ts.pluginTsName);
532
+ const file = resolver.file({
533
+ ...operationFileEntry(node, name),
534
+ root,
535
+ output,
536
+ group: group ?? void 0
537
+ });
538
+ const fileTs = resolveDependencyOperationFile({
539
+ cache: ctx.cache,
540
+ node,
541
+ resolver: tsResolver,
542
+ root,
543
+ output: pluginTs.options?.output ?? output,
544
+ group: pluginTs.options?.group
545
+ });
546
+ const importedTypeNames = [
547
+ tsResolver.response.options(node),
548
+ ...extraTypeNames,
549
+ ...resolveOperationTypeNames(node, tsResolver, {
550
+ exclude: keyTypeName ? [keyTypeName] : void 0,
551
+ order: "body-response-first",
552
+ includeParams: false
553
+ })
554
+ ].filter((typeName) => Boolean(typeName));
555
+ const fileMeta = {
556
+ path: file.path,
557
+ baseName: file.baseName
558
+ };
559
+ return {
560
+ file,
561
+ fileTs,
562
+ tsResolver,
563
+ contractOp,
564
+ importedTypeNames,
565
+ banner: resolver.default.banner(ctx.meta, {
566
+ output,
567
+ config,
568
+ file: fileMeta
569
+ }),
570
+ footer: resolver.default.footer(ctx.meta, {
571
+ output,
572
+ config,
573
+ file: fileMeta
574
+ })
575
+ };
576
+ }
577
+ /**
578
+ * The `<File>` shell shared by the TanStack hook generators; renders `children` after the imports.
579
+ */
580
+ function HookFile({ hook, imports, children }) {
581
+ const { file, fileTs, contractOp, importedTypeNames, banner, footer } = hook;
582
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
583
+ baseName: file.baseName,
584
+ path: file.path,
585
+ meta: file.meta,
586
+ banner,
587
+ footer,
588
+ children: [
589
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
590
+ name: [contractOp.name],
591
+ root: file.path,
592
+ path: contractOp.path
593
+ }),
594
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
595
+ name: ["RequestConfig", "ResponseErrorConfig"],
596
+ root: contractOp.clientPathIsFile ? file.path : void 0,
597
+ path: contractOp.clientPath,
598
+ isTypeOnly: true
599
+ }),
600
+ imports,
601
+ fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
602
+ name: Array.from(new Set(importedTypeNames)),
603
+ root: file.path,
604
+ path: fileTs.path,
605
+ isTypeOnly: true
606
+ }),
607
+ children
608
+ ]
609
+ });
610
+ }
611
+ //#endregion
514
612
  //#region ../../internals/tanstack-query/src/utils.ts
515
613
  /**
516
614
  * The grouped request options, ordered for both the destructured signature and the
517
615
  * call passed to the underlying client.
518
616
  */
519
- const requestGroupOrder$1 = [
617
+ const requestGroupOrder = [
520
618
  "path",
521
619
  "query",
522
620
  "body",
@@ -537,7 +635,7 @@ function maybeValueOrGetter(type) {
537
635
  * `MaybeRefOrGetter` per group.
538
636
  */
539
637
  function buildGroupedRequestParam(node, options) {
540
- const { resolver, keys = requestGroupOrder$1, memberTypeWrapper } = options;
638
+ const { resolver, keys = requestGroupOrder, memberTypeWrapper } = options;
541
639
  const { groups, hasRequiredPath, hasRequiredQuery, hasRequiredHeader } = getRequestGroupOptionality(node);
542
640
  const names = keys.filter((key) => groups[key]);
543
641
  if (names.length === 0) return null;
@@ -549,7 +647,7 @@ function buildGroupedRequestParam(node, options) {
549
647
  };
550
648
  const isOptional = names.every((name) => !requiredByGroup[name]);
551
649
  const optionsName = resolver.response.options(node);
552
- const omittedKeys = requestGroupOrder$1.filter((key) => !keys.includes(key));
650
+ const omittedKeys = requestGroupOrder.filter((key) => !keys.includes(key));
553
651
  const optionsType = omittedKeys.length > 0 ? `Omit<${optionsName}, ${omittedKeys.map((key) => `'${key}'`).join(" | ")}>` : optionsName;
554
652
  if (memberTypeWrapper) {
555
653
  const members = names.map((name) => ({
@@ -610,7 +708,7 @@ function buildClientCall(node, options) {
610
708
  const { groups } = getRequestGroupOptionality(node);
611
709
  return `${clientName}({ ${[
612
710
  "...config",
613
- ...requestGroupOrder$1.filter((key) => groups[key]).map((name) => unwrapName ? `${name}: ${unwrapName(name)}` : name),
711
+ ...requestGroupOrder.filter((key) => groups[key]).map((name) => unwrapName ? `${name}: ${unwrapName(name)}` : name),
614
712
  signal ? "signal: config.signal ?? signal" : null,
615
713
  "throwOnError: true"
616
714
  ].filter((part) => part !== null).join(", ")} })`;
@@ -820,16 +918,48 @@ function hasQueryKeyParams(node) {
820
918
  * grouped `path`/`query`/`body` bindings.
821
919
  */
822
920
  function buildQueryKeyParams(node, options) {
823
- const { resolver } = options;
921
+ const { resolver, memberTypeWrapper } = options;
824
922
  const groupedParam = buildGroupedRequestParam(node, {
825
923
  resolver,
826
- keys: queryKeyGroupOrder
924
+ keys: queryKeyGroupOrder,
925
+ memberTypeWrapper
827
926
  });
828
927
  return (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedParam ? [groupedParam] : [] });
829
928
  }
929
+ /**
930
+ * Builds the hook parameter list: the grouped request param (omitted when `withRequest` is `false`) then `options` typed as `optionsType`.
931
+ */
932
+ function buildHookParams(node, options) {
933
+ const { resolver, optionsType, memberTypeWrapper, withRequest = true } = options;
934
+ const optionsParam = (0, _kubb_plugin_ts.createFunctionParameter)({
935
+ name: "options",
936
+ type: optionsType,
937
+ default: "{}"
938
+ });
939
+ const groupedParam = withRequest ? buildGroupedRequestParam(node, {
940
+ resolver,
941
+ memberTypeWrapper
942
+ }) : null;
943
+ return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [groupedParam, optionsParam].filter((param) => param !== null) });
944
+ }
945
+ /**
946
+ * The `TRequest` type argument of a mutation hook: the options type when the operation takes a request, else `undefined`.
947
+ */
948
+ function resolveMutationRequestType(node, resolver) {
949
+ return buildGroupedRequestParam(node, { resolver }) ? resolver.response.options(node) : "undefined";
950
+ }
951
+ /**
952
+ * Builds the object literal that unwraps each request group's getter before it reaches `queryKey`/`queryOptions`; `null` without a request group.
953
+ */
954
+ function buildResolvedRequestParams(node) {
955
+ const groups = getRequestGroups(node);
956
+ const names = requestGroupOrder.filter((key) => groups[key]);
957
+ if (names.length === 0) return null;
958
+ return `{ ${names.map((name) => `${name}: typeof ${name} === 'function' ? ${name}() : ${name}`).join(", ")} }`;
959
+ }
830
960
  //#endregion
831
961
  //#region ../../internals/tanstack-query/src/components/InfiniteQueryOptions.tsx
832
- const declarationPrinter$7 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
962
+ const declarationPrinter$6 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
833
963
  const callPrinter$3 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
834
964
  function InfiniteQueryOptions({ name, clientName, initialPageParam, hasExplicitInitialPageParam, cursorParam, nextParam, previousParam, getNextPageParam, getPreviousPageParam, node, tsResolver, queryParam, queryKeyName, queryKeyType = "typeof queryKey", memberTypeWrapper, unwrapName, returnType = "full" }) {
835
965
  const { TData: queryFnDataType, TError: errorType } = buildResponseTypes(node, tsResolver);
@@ -849,7 +979,7 @@ function InfiniteQueryOptions({ name, clientName, initialPageParam, hasExplicitI
849
979
  resolver: tsResolver,
850
980
  memberTypeWrapper
851
981
  });
852
- const paramsSignature = declarationPrinter$7.print(paramsNode) ?? "";
982
+ const paramsSignature = declarationPrinter$6.print(paramsNode) ?? "";
853
983
  const queryFnBody = buildCallResultBody(buildClientCall(node, {
854
984
  clientName,
855
985
  signal: true,
@@ -906,20 +1036,20 @@ return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${que
906
1036
  }
907
1037
  //#endregion
908
1038
  //#region ../../internals/tanstack-query/src/components/MutationKey.tsx
909
- const declarationPrinter$6 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1039
+ const declarationPrinter$5 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
910
1040
  const mutationKeyTransformer = ({ node }) => {
911
1041
  if (!node.path) return [];
912
1042
  return [`{ url: '${kubb_kit.Url.toPath(node.path)}' }`];
913
1043
  };
914
- function MutationKey({ name, node, transformer }) {
1044
+ function MutationKey({ name, node, transformer, typeName }) {
915
1045
  const paramsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: [] });
916
- const paramsSignature = declarationPrinter$6.print(paramsNode) ?? "";
1046
+ const paramsSignature = declarationPrinter$5.print(paramsNode) ?? "";
917
1047
  const keys = (transformer ?? mutationKeyTransformer)({
918
1048
  node,
919
1049
  casing: "camelcase",
920
1050
  variant: "mutation"
921
1051
  });
922
- return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1052
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
923
1053
  name,
924
1054
  isExportable: true,
925
1055
  isIndexable: true,
@@ -930,7 +1060,17 @@ function MutationKey({ name, node, transformer }) {
930
1060
  singleLine: true,
931
1061
  children: `[${keys.join(", ")}] as const`
932
1062
  })
933
- });
1063
+ }), typeName && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1064
+ name: typeName,
1065
+ isExportable: true,
1066
+ isIndexable: true,
1067
+ isTypeOnly: true,
1068
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Type, {
1069
+ export: true,
1070
+ name: typeName,
1071
+ children: `ReturnType<typeof ${name}>`
1072
+ })
1073
+ })] });
934
1074
  }
935
1075
  //#endregion
936
1076
  //#region ../../internals/tanstack-query/src/resolver.ts
@@ -987,7 +1127,7 @@ function createMutationResolver() {
987
1127
  }
988
1128
  //#endregion
989
1129
  //#region ../../internals/tanstack-query/src/components/QueryKey.tsx
990
- const declarationPrinter$5 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1130
+ const declarationPrinter$4 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
991
1131
  const queryKeyTransformer = ({ node, variant }) => {
992
1132
  if (!node.path) return [];
993
1133
  const { path, query } = getOperationParameters(node);
@@ -1000,9 +1140,12 @@ const queryKeyTransformer = ({ node, variant }) => {
1000
1140
  if (node.requestBody?.content?.[0]?.schema) result.push("...(body !== undefined ? [body] : [])");
1001
1141
  return result;
1002
1142
  };
1003
- function QueryKey({ name, node, tsResolver, typeName, transformer, variant = "query" }) {
1004
- const paramsNode = buildQueryKeyParams(node, { resolver: tsResolver });
1005
- const paramsSignature = declarationPrinter$5.print(paramsNode) ?? "";
1143
+ function QueryKey({ name, node, tsResolver, typeName, transformer, variant = "query", memberTypeWrapper, exportType }) {
1144
+ const paramsNode = buildQueryKeyParams(node, {
1145
+ resolver: tsResolver,
1146
+ memberTypeWrapper
1147
+ });
1148
+ const paramsSignature = declarationPrinter$4.print(paramsNode) ?? "";
1006
1149
  const keys = (transformer ?? queryKeyTransformer)({
1007
1150
  node,
1008
1151
  casing: "camelcase",
@@ -1021,9 +1164,12 @@ function QueryKey({ name, node, tsResolver, typeName, transformer, variant = "qu
1021
1164
  })
1022
1165
  }), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1023
1166
  name: typeName,
1167
+ isExportable: exportType,
1168
+ isIndexable: exportType,
1024
1169
  isTypeOnly: true,
1025
1170
  children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Type, {
1026
1171
  name: typeName,
1172
+ export: exportType,
1027
1173
  children: `ReturnType<typeof ${name}>`
1028
1174
  })
1029
1175
  })] });
@@ -1127,30 +1273,6 @@ const customHookOptionsFileGenerator = (0, kubb_kit.defineGenerator)({
1127
1273
  }
1128
1274
  });
1129
1275
  //#endregion
1130
- //#region src/utils.ts
1131
- const requestGroupOrder = [
1132
- "path",
1133
- "query",
1134
- "body",
1135
- "headers"
1136
- ];
1137
- /**
1138
- * Builds the object literal that resolves each request group to a concrete value, unwrapping a getter
1139
- * once before the value reaches the plain `queryKey`/`queryOptions` helpers. A getter must never reach a
1140
- * React Query key, which is hashed structurally. Returns `null` when the operation carries no request group.
1141
- *
1142
- * @example
1143
- * ```ts
1144
- * buildResolvedRequestParams(node) // { path: typeof path === 'function' ? path() : path }
1145
- * ```
1146
- */
1147
- function buildResolvedRequestParams(node) {
1148
- const groups = getRequestGroups(node);
1149
- const names = requestGroupOrder.filter((key) => groups[key]);
1150
- if (names.length === 0) return null;
1151
- return `{ ${names.map((name) => `${name}: typeof ${name} === 'function' ? ${name}() : ${name}`).join(", ")} }`;
1152
- }
1153
- //#endregion
1154
1276
  //#region src/generators/hookOptionsGenerator.tsx
1155
1277
  /**
1156
1278
  * Emits the `HookOptions` type used by `customOptions`. Enabled when
@@ -1187,9 +1309,10 @@ const hookOptionsGenerator = (0, kubb_kit.defineGenerator)({
1187
1309
  const nodeMutation = "mutation" in opOverrides ? opOverrides.mutation : mutation;
1188
1310
  const nodeInfinite = "infinite" in opOverrides ? opOverrides.infinite : infinite;
1189
1311
  const nodeInfiniteOptions = nodeInfinite && typeof nodeInfinite === "object" ? nodeInfinite : null;
1190
- const isQueryOp = nodeQuery === false ? !!query && query.methods.some((m) => node.method.toLowerCase() === m.toLowerCase()) : !!nodeQuery && nodeQuery.methods.some((m) => node.method.toLowerCase() === m.toLowerCase());
1191
- const nodeQueryMethods = new Set(nodeQuery ? nodeQuery.methods : []);
1192
- const isMutationOp = nodeMutation !== false && !isQueryOp && (nodeMutation ? nodeMutation.methods : []).some((m) => !nodeQueryMethods.has(m) && node.method.toLowerCase() === m.toLowerCase());
1312
+ const { isQuery: isQueryOp, isMutation: isMutationOp } = classifyOperation(node, {
1313
+ query: nodeQuery === false ? query : nodeQuery,
1314
+ mutation: nodeMutation
1315
+ });
1193
1316
  const isSuspenseOp = !!suspense;
1194
1317
  const isInfiniteOp = !!nodeInfiniteOptions;
1195
1318
  if (isQueryOp) {
@@ -1224,9 +1347,7 @@ const hookOptionsGenerator = (0, kubb_kit.defineGenerator)({
1224
1347
  hookOptions[suspenseHookName] = `Partial<ReturnType<typeof ${suspenseOptionsName}>>`;
1225
1348
  }
1226
1349
  if (isInfiniteOp) {
1227
- const normalizeKey = (key) => key.replace(/\?$/, "");
1228
- const queryParamKeys = getOperationParameters(node).query.map((p) => p.name);
1229
- if (nodeInfiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === nodeInfiniteOptions.queryParam) : false) {
1350
+ if (matchesInfinite(node, nodeInfiniteOptions)) {
1230
1351
  const infiniteOptionsName = resolver.infiniteQuery.optionsName(node);
1231
1352
  const infiniteHookName = resolver.infiniteQuery.name(node);
1232
1353
  const infiniteHookFile = resolver.file({
@@ -1312,50 +1433,87 @@ const hookOptionsGenerator = (0, kubb_kit.defineGenerator)({
1312
1433
  }
1313
1434
  });
1314
1435
  //#endregion
1315
- //#region src/components/InfiniteQuery.tsx
1316
- const declarationPrinter$4 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1317
- function buildInfiniteQueryParamsNode(node, options) {
1318
- const { resolver, pageParamGeneric, observerOptionsName } = options;
1319
- const optionsParam = (0, _kubb_plugin_ts.createFunctionParameter)({
1320
- name: "options",
1321
- type: `{
1322
- query?: Partial<${observerOptionsName}<TQueryFnData, TError, TData, TQueryKey, ${pageParamGeneric}>> & { client?: QueryClient },
1323
- client?: ${buildClientOptionType()}
1324
- }`,
1325
- default: "{}"
1326
- });
1327
- const groupedParam = buildGroupedRequestParam(node, {
1328
- resolver,
1329
- memberTypeWrapper: maybeValueOrGetter
1330
- });
1331
- return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [groupedParam, optionsParam].filter((param) => param !== null) });
1436
+ //#region src/components/Query.tsx
1437
+ const declarationPrinter$3 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1438
+ const OBSERVER_OPTIONS_NAMES = {
1439
+ infinite: {
1440
+ suspense: "UseSuspenseInfiniteQueryOptions",
1441
+ standard: "InfiniteQueryObserverOptions"
1442
+ },
1443
+ plain: {
1444
+ suspense: "UseSuspenseQueryOptions",
1445
+ standard: "QueryObserverOptions"
1446
+ }
1447
+ };
1448
+ function buildHookTypes({ node, tsResolver, infinite, suspense, TData, TError, queryKeyTypeName, observerOptionsName, resultTypeName }) {
1449
+ if (infinite) {
1450
+ const { pageParamType } = resolvePageParamType(node, {
1451
+ resolver: tsResolver,
1452
+ initialPageParam: infinite.initialPageParam,
1453
+ queryParam: infinite.queryParam
1454
+ });
1455
+ return {
1456
+ generics: [
1457
+ `TQueryFnData = ${TData}`,
1458
+ `TError = ${TError}`,
1459
+ "TData = InfiniteData<TQueryFnData>",
1460
+ `TQueryKey extends QueryKey = ${queryKeyTypeName}`,
1461
+ `TPageParam = ${pageParamType}`
1462
+ ],
1463
+ observerOptionsType: `${observerOptionsName}<TQueryFnData, TError, TData, TQueryKey, TPageParam>`,
1464
+ returnType: `${resultTypeName}<TData, TError> & { queryKey: TQueryKey }`
1465
+ };
1466
+ }
1467
+ return {
1468
+ generics: suspense ? [`TData = ${TData}`, `TQueryKey extends QueryKey = ${queryKeyTypeName}`] : [
1469
+ `TData = ${TData}`,
1470
+ `TQueryData = ${TData}`,
1471
+ `TQueryKey extends QueryKey = ${queryKeyTypeName}`
1472
+ ],
1473
+ observerOptionsType: `${observerOptionsName}<${(suspense ? [
1474
+ TData,
1475
+ TError,
1476
+ "TData",
1477
+ "TQueryKey"
1478
+ ] : [
1479
+ TData,
1480
+ TError,
1481
+ "TData",
1482
+ "TQueryData",
1483
+ "TQueryKey"
1484
+ ]).join(", ")}>`,
1485
+ returnType: `${resultTypeName}<TData, ${TError}> & { queryKey: TQueryKey }`
1486
+ };
1332
1487
  }
1333
- function InfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, initialPageParam, queryParam, customOptions, suspense }) {
1334
- const { TData: responseType, TError: errorType } = buildResponseTypes(node, tsResolver);
1335
- const { pageParamType } = resolvePageParamType(node, {
1336
- resolver: tsResolver,
1337
- initialPageParam,
1338
- queryParam
1488
+ function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, customOptions, suspense, infinite }) {
1489
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1490
+ const prefix = suspense ? "UseSuspense" : "Use";
1491
+ const hookName = `${suspense ? "useSuspense" : "use"}${infinite ? "InfiniteQuery" : "Query"}`;
1492
+ const observerOptionsName = OBSERVER_OPTIONS_NAMES[infinite ? "infinite" : "plain"][suspense ? "suspense" : "standard"];
1493
+ const { generics, observerOptionsType, returnType } = buildHookTypes({
1494
+ node,
1495
+ tsResolver,
1496
+ infinite,
1497
+ suspense,
1498
+ TData,
1499
+ TError,
1500
+ queryKeyTypeName,
1501
+ observerOptionsName,
1502
+ resultTypeName: `${prefix}${infinite ? "Infinite" : ""}QueryResult`
1339
1503
  });
1340
- const hookName = suspense ? "useSuspenseInfiniteQuery" : "useInfiniteQuery";
1341
- const observerOptionsName = suspense ? "UseSuspenseInfiniteQueryOptions" : "InfiniteQueryObserverOptions";
1342
- const returnType = `${suspense ? "UseSuspenseInfiniteQueryResult" : "UseInfiniteQueryResult"}<TData, TError> & { queryKey: TQueryKey }`;
1343
- const generics = [
1344
- `TQueryFnData = ${responseType}`,
1345
- `TError = ${errorType}`,
1346
- "TData = InfiniteData<TQueryFnData>",
1347
- `TQueryKey extends QueryKey = ${queryKeyTypeName}`,
1348
- `TPageParam = ${pageParamType}`
1349
- ];
1504
+ const castType = infinite ? observerOptionsType : observerOptionsName;
1350
1505
  const resolvedParams = buildResolvedRequestParams(node);
1351
1506
  const queryKeyArgs = resolvedParams && hasQueryKeyParams(node) ? "resolvedParams" : "";
1352
1507
  const queryOptionsArgs = resolvedParams ? "resolvedParams, config" : "config";
1353
- const paramsNode = buildInfiniteQueryParamsNode(node, {
1508
+ const paramsNode = buildHookParams(node, {
1354
1509
  resolver: tsResolver,
1355
- pageParamGeneric: "TPageParam",
1356
- observerOptionsName
1510
+ memberTypeWrapper: maybeValueOrGetter,
1511
+ optionsType: `{
1512
+ query?: Partial<${observerOptionsType}> & { client?: QueryClient },
1513
+ client?: ${buildClientOptionType()}
1514
+ }`
1357
1515
  });
1358
- const paramsSignature = declarationPrinter$4.print(paramsNode) ?? "";
1516
+ const paramsSignature = declarationPrinter$3.print(paramsNode) ?? "";
1359
1517
  return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1360
1518
  name,
1361
1519
  isExportable: true,
@@ -1376,7 +1534,7 @@ function InfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName,
1376
1534
  ...${queryOptionsName}(${queryOptionsArgs}),${customOptions ? "\n ...customOptions," : ""}
1377
1535
  ...resolvedOptions,
1378
1536
  queryKey,
1379
- } as unknown as ${observerOptionsName}<TQueryFnData, TError, TData, TQueryKey, TPageParam>, queryClient) as ${returnType}
1537
+ } as unknown as ${castType}, queryClient) as ${returnType}
1380
1538
 
1381
1539
  queryResult.queryKey = queryKey as TQueryKey
1382
1540
 
@@ -1386,9 +1544,216 @@ function InfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName,
1386
1544
  });
1387
1545
  }
1388
1546
  //#endregion
1389
- //#region src/components/MutationOptions.tsx
1390
- const declarationPrinter$3 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1547
+ //#region src/components/QueryOptions.tsx
1548
+ const declarationPrinter$2 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1391
1549
  const callPrinter$2 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
1550
+ function QueryOptions({ name, clientName, node, tsResolver, queryKeyName, returnType = "full" }) {
1551
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1552
+ const queryKeyParamsNode = buildQueryKeyParams(node, { resolver: tsResolver });
1553
+ const queryKeyParamsCall = callPrinter$2.print(queryKeyParamsNode) ?? "";
1554
+ const paramsNode = buildQueryOptionsParams(node, { resolver: tsResolver });
1555
+ const paramsSignature = declarationPrinter$2.print(paramsNode) ?? "";
1556
+ const queryFnBody = buildCallResultBody(buildClientCall(node, {
1557
+ clientName,
1558
+ signal: true
1559
+ }), { returnType });
1560
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1561
+ name,
1562
+ isExportable: true,
1563
+ isIndexable: true,
1564
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
1565
+ name,
1566
+ export: true,
1567
+ params: paramsSignature,
1568
+ children: `
1569
+ const queryKey = ${queryKeyName}(${queryKeyParamsCall})
1570
+ return queryOptions<${TData}, ${TError}, ${TData}, typeof queryKey>({
1571
+ queryKey,
1572
+ queryFn: async ({ signal }) => {
1573
+ ${queryFnBody}
1574
+ },
1575
+ })
1576
+ `
1577
+ })
1578
+ });
1579
+ }
1580
+ //#endregion
1581
+ //#region src/generators/createQueryGenerator.tsx
1582
+ const OBSERVER_IMPORTS = {
1583
+ query: ["QueryObserverOptions", "UseQueryResult"],
1584
+ suspenseQuery: ["UseSuspenseQueryOptions", "UseSuspenseQueryResult"],
1585
+ infiniteQuery: ["InfiniteQueryObserverOptions", "UseInfiniteQueryResult"],
1586
+ suspenseInfiniteQuery: ["UseSuspenseInfiniteQueryOptions", "UseSuspenseInfiniteQueryResult"]
1587
+ };
1588
+ /**
1589
+ * Builds the generator for one `useQuery` flavor. `variant` picks the resolver namespace
1590
+ * (`resolver.query`, `resolver.suspenseQuery`, ...), the TanStack hook, and the options it needs.
1591
+ */
1592
+ function createQueryGenerator({ name, variant }) {
1593
+ const suspense = variant === "suspenseQuery" || variant === "suspenseInfiniteQuery";
1594
+ const infinite = variant === "infiniteQuery" || variant === "suspenseInfiniteQuery";
1595
+ const hookImport = `use${suspense ? "Suspense" : ""}${infinite ? "InfiniteQuery" : "Query"}`;
1596
+ const observerImports = OBSERVER_IMPORTS[variant];
1597
+ return (0, kubb_kit.defineGenerator)({
1598
+ name,
1599
+ renderer: kubb_jsx.jsxRenderer,
1600
+ match(node, ctx) {
1601
+ const operationNode = node;
1602
+ if (!kubb_kit.ast.isHttpOperationNode(operationNode)) return false;
1603
+ const { query, mutation, infinite: infiniteConfig, suspense: suspenseConfig, hooks } = ctx.options;
1604
+ const { isQuery, isMutation } = classifyOperation(operationNode, {
1605
+ query,
1606
+ mutation
1607
+ });
1608
+ if (!isQuery || isMutation) return false;
1609
+ if (suspense && !suspenseConfig) return false;
1610
+ if (variant === "query") return true;
1611
+ if (!hooks) return false;
1612
+ if (!infinite) return true;
1613
+ const infiniteOptions = infiniteConfig && typeof infiniteConfig === "object" ? infiniteConfig : null;
1614
+ return !!infiniteOptions && matchesInfinite(operationNode, infiniteOptions);
1615
+ },
1616
+ operation(node, ctx) {
1617
+ if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
1618
+ const { driver, resolver, root } = ctx;
1619
+ const { output, query, infinite: infiniteConfig, client, group, customOptions, hooks } = ctx.options;
1620
+ const infiniteOptions = infinite && infiniteConfig && typeof infiniteConfig === "object" ? infiniteConfig : null;
1621
+ if (infinite && !infiniteOptions) return null;
1622
+ if (variant === "infiniteQuery" && infiniteOptions) {
1623
+ const pageParamsWarning = getDefaultPageParamsWarning(node, infiniteOptions);
1624
+ if (pageParamsWarning) ctx.warn(pageParamsWarning);
1625
+ }
1626
+ const contractOp = resolveClientOperation({
1627
+ clientPlugin: { pluginName: client.pluginName },
1628
+ driver,
1629
+ node,
1630
+ root,
1631
+ output,
1632
+ cache: ctx.cache
1633
+ });
1634
+ if (!contractOp) return null;
1635
+ const importPath = query ? query.importPath : "@tanstack/react-query";
1636
+ const variantResolver = resolver[variant];
1637
+ const queryName = variantResolver.name(node);
1638
+ const queryOptionsName = variantResolver.optionsName(node);
1639
+ const queryKeyName = variantResolver.keyName(node);
1640
+ const queryKeyTypeName = variantResolver.keyTypeName(node);
1641
+ const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1642
+ const hook = resolveHookFile(node, ctx, {
1643
+ name: queryName,
1644
+ output,
1645
+ group,
1646
+ contractOp,
1647
+ keyTypeName: queryKeyTypeName,
1648
+ extraTypeNames: infiniteOptions ? [resolvePageParamType(node, {
1649
+ resolver: tsResolver,
1650
+ initialPageParam: infiniteOptions.initialPageParam,
1651
+ queryParam: infiniteOptions.queryParam
1652
+ }).queryParamsTypeName] : []
1653
+ });
1654
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(HookFile, {
1655
+ hook,
1656
+ imports: customOptions && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1657
+ name: [customOptions.name],
1658
+ path: customOptions.importPath
1659
+ }),
1660
+ children: [
1661
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryKey, {
1662
+ name: queryKeyName,
1663
+ typeName: queryKeyTypeName,
1664
+ node,
1665
+ tsResolver: hook.tsResolver,
1666
+ transformer: ctx.options.queryKey,
1667
+ variant
1668
+ }),
1669
+ infiniteOptions ? /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [
1670
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1671
+ name: ["InfiniteData"],
1672
+ isTypeOnly: true,
1673
+ path: importPath
1674
+ }),
1675
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1676
+ name: ["infiniteQueryOptions"],
1677
+ path: importPath
1678
+ }),
1679
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(InfiniteQueryOptions, {
1680
+ name: queryOptionsName,
1681
+ clientName: contractOp.name,
1682
+ queryKeyName,
1683
+ node,
1684
+ tsResolver: hook.tsResolver,
1685
+ cursorParam: infiniteOptions.cursorParam,
1686
+ nextParam: infiniteOptions.nextParam,
1687
+ previousParam: infiniteOptions.previousParam,
1688
+ getNextPageParam: infiniteOptions.getNextPageParam,
1689
+ getPreviousPageParam: infiniteOptions.getPreviousPageParam,
1690
+ initialPageParam: infiniteOptions.initialPageParam,
1691
+ hasExplicitInitialPageParam: infiniteOptions.hasExplicitInitialPageParam,
1692
+ queryParam: infiniteOptions.queryParam,
1693
+ returnType: contractOp.returnType
1694
+ })
1695
+ ] }) : /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1696
+ name: ["queryOptions"],
1697
+ path: importPath
1698
+ }), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryOptions, {
1699
+ name: queryOptionsName,
1700
+ clientName: contractOp.name,
1701
+ queryKeyName,
1702
+ node,
1703
+ tsResolver: hook.tsResolver,
1704
+ returnType: contractOp.returnType
1705
+ })] }),
1706
+ (variant !== "query" || query && hooks) && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [
1707
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1708
+ name: [hookImport],
1709
+ path: importPath
1710
+ }),
1711
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1712
+ name: [
1713
+ "QueryKey",
1714
+ "QueryClient",
1715
+ ...observerImports
1716
+ ],
1717
+ path: importPath,
1718
+ isTypeOnly: true
1719
+ }),
1720
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Query, {
1721
+ name: queryName,
1722
+ queryOptionsName,
1723
+ queryKeyName,
1724
+ queryKeyTypeName,
1725
+ node,
1726
+ tsResolver: hook.tsResolver,
1727
+ customOptions,
1728
+ suspense,
1729
+ infinite: infiniteOptions ? {
1730
+ initialPageParam: infiniteOptions.initialPageParam,
1731
+ queryParam: infiniteOptions.queryParam
1732
+ } : void 0
1733
+ })
1734
+ ] })
1735
+ ]
1736
+ });
1737
+ }
1738
+ });
1739
+ }
1740
+ //#endregion
1741
+ //#region src/generators/infiniteQueryGenerator.tsx
1742
+ /**
1743
+ * Built-in generator for `useInfiniteQuery` hooks. Enabled when
1744
+ * `pluginReactQuery({ infinite: { ... }, hooks: true })`. Emits one
1745
+ * `useFooInfiniteQuery` hook per query operation, wiring the configured
1746
+ * `nextParam` / `previousParam` paths into TanStack Query's cursor-based
1747
+ * pagination.
1748
+ */
1749
+ const infiniteQueryGenerator = createQueryGenerator({
1750
+ name: "react-infinite-query",
1751
+ variant: "infiniteQuery"
1752
+ });
1753
+ //#endregion
1754
+ //#region src/components/MutationOptions.tsx
1755
+ const declarationPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1756
+ const callPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
1392
1757
  function buildMutationConfigParamsNode(node) {
1393
1758
  return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
1394
1759
  name: "config",
@@ -1399,12 +1764,12 @@ function buildMutationConfigParamsNode(node) {
1399
1764
  function MutationOptions({ name, clientName, node, tsResolver, mutationKeyName, returnType = "full" }) {
1400
1765
  const { TData, TError } = buildResponseTypes(node, tsResolver);
1401
1766
  const configParamsNode = buildMutationConfigParamsNode(node);
1402
- const paramsSignature = declarationPrinter$3.print(configParamsNode) ?? "";
1767
+ const paramsSignature = declarationPrinter$1.print(configParamsNode) ?? "";
1403
1768
  const groupedParam = buildGroupedRequestParam(node, { resolver: tsResolver });
1404
1769
  const hasMutationParams = groupedParam !== null;
1405
1770
  const groupedParamsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedParam ? [groupedParam] : [] });
1406
1771
  const TRequest = hasMutationParams ? tsResolver.response.options(node) : "undefined";
1407
- const argBindingStr = hasMutationParams ? callPrinter$2.print(groupedParamsNode) ?? "" : "_";
1772
+ const argBindingStr = hasMutationParams ? callPrinter$1.print(groupedParamsNode) ?? "" : "_";
1408
1773
  const mutationFnBody = buildCallResultBody(buildClientCall(node, {
1409
1774
  clientName,
1410
1775
  signal: false
@@ -1432,28 +1797,24 @@ function MutationOptions({ name, clientName, node, tsResolver, mutationKeyName,
1432
1797
  }
1433
1798
  //#endregion
1434
1799
  //#region src/components/Mutation.tsx
1435
- const declarationPrinter$2 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1436
- const callPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
1437
- function resolveMutationRequestType(node, resolver) {
1438
- return buildGroupedRequestParam(node, { resolver }) ? resolver.response.options(node) : "undefined";
1439
- }
1800
+ const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1801
+ const callPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
1440
1802
  function buildMutationParamsNode(node, options) {
1441
1803
  const { resolver } = options;
1442
1804
  const { TData, TError } = buildResponseTypes(node, resolver);
1443
- const generics = [
1444
- TData,
1445
- TError,
1446
- resolveMutationRequestType(node, resolver),
1447
- "TContext"
1448
- ].join(", ");
1449
- return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
1450
- name: "options",
1451
- type: `{
1452
- mutation?: UseMutationOptions<${generics}> & { client?: QueryClient },
1805
+ return buildHookParams(node, {
1806
+ resolver,
1807
+ withRequest: false,
1808
+ optionsType: `{
1809
+ mutation?: UseMutationOptions<${[
1810
+ TData,
1811
+ TError,
1812
+ resolveMutationRequestType(node, resolver),
1813
+ "TContext"
1814
+ ].join(", ")}> & { client?: QueryClient },
1453
1815
  client?: ${buildRequestConfigType(node)},
1454
- }`,
1455
- default: "{}"
1456
- })] });
1816
+ }`
1817
+ });
1457
1818
  }
1458
1819
  function Mutation({ name, mutationOptionsName, node, tsResolver, mutationKeyName, customOptions }) {
1459
1820
  const { TData, TError } = buildResponseTypes(node, tsResolver);
@@ -1465,9 +1826,9 @@ function Mutation({ name, mutationOptionsName, node, tsResolver, mutationKeyName
1465
1826
  ].join(", ");
1466
1827
  const returnType = `UseMutationResult<${generics}>`;
1467
1828
  const mutationOptionsConfigNode = buildMutationConfigParamsNode(node);
1468
- const mutationOptionsParamsCall = callPrinter$1.print(mutationOptionsConfigNode) ?? "";
1829
+ const mutationOptionsParamsCall = callPrinter.print(mutationOptionsConfigNode) ?? "";
1469
1830
  const paramsNode = buildMutationParamsNode(node, { resolver: tsResolver });
1470
- const paramsSignature = declarationPrinter$2.print(paramsNode) ?? "";
1831
+ const paramsSignature = declarationPrinter.print(paramsNode) ?? "";
1471
1832
  return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1472
1833
  name,
1473
1834
  isExportable: true,
@@ -1495,301 +1856,6 @@ function Mutation({ name, mutationOptionsName, node, tsResolver, mutationKeyName
1495
1856
  });
1496
1857
  }
1497
1858
  //#endregion
1498
- //#region src/components/Query.tsx
1499
- const declarationPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1500
- function buildQueryParamsNode(node, options) {
1501
- const { resolver, observerOptionsType } = options;
1502
- const optionsParam = (0, _kubb_plugin_ts.createFunctionParameter)({
1503
- name: "options",
1504
- type: `{
1505
- query?: Partial<${observerOptionsType}> & { client?: QueryClient },
1506
- client?: ${buildClientOptionType()}
1507
- }`,
1508
- default: "{}"
1509
- });
1510
- const groupedParam = buildGroupedRequestParam(node, {
1511
- resolver,
1512
- memberTypeWrapper: maybeValueOrGetter
1513
- });
1514
- return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [groupedParam, optionsParam].filter((param) => param !== null) });
1515
- }
1516
- function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, customOptions, suspense }) {
1517
- const { TData, TError } = buildResponseTypes(node, tsResolver);
1518
- const hookName = suspense ? "useSuspenseQuery" : "useQuery";
1519
- const observerOptionsName = suspense ? "UseSuspenseQueryOptions" : "QueryObserverOptions";
1520
- const observerOptionsType = suspense ? `${observerOptionsName}<${[
1521
- TData,
1522
- TError,
1523
- "TData",
1524
- "TQueryKey"
1525
- ].join(", ")}>` : `${observerOptionsName}<${[
1526
- TData,
1527
- TError,
1528
- "TData",
1529
- "TQueryData",
1530
- "TQueryKey"
1531
- ].join(", ")}>`;
1532
- const returnType = `${suspense ? "UseSuspenseQueryResult" : "UseQueryResult"}<TData, ${TError}> & { queryKey: TQueryKey }`;
1533
- const generics = suspense ? [`TData = ${TData}`, `TQueryKey extends QueryKey = ${queryKeyTypeName}`] : [
1534
- `TData = ${TData}`,
1535
- `TQueryData = ${TData}`,
1536
- `TQueryKey extends QueryKey = ${queryKeyTypeName}`
1537
- ];
1538
- const resolvedParams = buildResolvedRequestParams(node);
1539
- const queryKeyArgs = resolvedParams && hasQueryKeyParams(node) ? "resolvedParams" : "";
1540
- const queryOptionsArgs = resolvedParams ? "resolvedParams, config" : "config";
1541
- const paramsNode = buildQueryParamsNode(node, {
1542
- resolver: tsResolver,
1543
- observerOptionsType
1544
- });
1545
- const paramsSignature = declarationPrinter$1.print(paramsNode) ?? "";
1546
- return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1547
- name,
1548
- isExportable: true,
1549
- isIndexable: true,
1550
- children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
1551
- name,
1552
- export: true,
1553
- generics: generics.join(", "),
1554
- params: paramsSignature,
1555
- returnType: void 0,
1556
- JSDoc: { comments: buildOperationComments(node) },
1557
- children: `
1558
- const { query: queryConfig = {}, client: config = {} } = options ?? {}
1559
- const { client: queryClient, ...resolvedOptions } = queryConfig${resolvedParams ? `\n const resolvedParams = ${resolvedParams}` : ""}
1560
- const queryKey = resolvedOptions?.queryKey ?? ${queryKeyName}(${queryKeyArgs})${customOptions ? `\n const customOptions = ${customOptions.name}({ hookName: '${name}', operationId: '${node.operationId}' })` : ""}
1561
-
1562
- const queryResult = ${hookName}({
1563
- ...${queryOptionsName}(${queryOptionsArgs}),${customOptions ? "\n ...customOptions," : ""}
1564
- ...resolvedOptions,
1565
- queryKey,
1566
- } as unknown as ${observerOptionsName}, queryClient) as ${returnType}
1567
-
1568
- queryResult.queryKey = queryKey as TQueryKey
1569
-
1570
- return queryResult
1571
- `
1572
- })
1573
- });
1574
- }
1575
- //#endregion
1576
- //#region src/components/QueryOptions.tsx
1577
- const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1578
- const callPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
1579
- function QueryOptions({ name, clientName, node, tsResolver, queryKeyName, returnType = "full" }) {
1580
- const { TData, TError } = buildResponseTypes(node, tsResolver);
1581
- const queryKeyParamsNode = buildQueryKeyParams(node, { resolver: tsResolver });
1582
- const queryKeyParamsCall = callPrinter.print(queryKeyParamsNode) ?? "";
1583
- const paramsNode = buildQueryOptionsParams(node, { resolver: tsResolver });
1584
- const paramsSignature = declarationPrinter.print(paramsNode) ?? "";
1585
- const queryFnBody = buildCallResultBody(buildClientCall(node, {
1586
- clientName,
1587
- signal: true
1588
- }), { returnType });
1589
- return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1590
- name,
1591
- isExportable: true,
1592
- isIndexable: true,
1593
- children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
1594
- name,
1595
- export: true,
1596
- params: paramsSignature,
1597
- children: `
1598
- const queryKey = ${queryKeyName}(${queryKeyParamsCall})
1599
- return queryOptions<${TData}, ${TError}, ${TData}, typeof queryKey>({
1600
- queryKey,
1601
- queryFn: async ({ signal }) => {
1602
- ${queryFnBody}
1603
- },
1604
- })
1605
- `
1606
- })
1607
- });
1608
- }
1609
- //#endregion
1610
- //#region src/generators/infiniteQueryGenerator.tsx
1611
- /**
1612
- * Built-in generator for `useInfiniteQuery` hooks. Enabled when
1613
- * `pluginReactQuery({ infinite: { ... }, hooks: true })`. Emits one
1614
- * `useFooInfiniteQuery` hook per query operation, wiring the configured
1615
- * `nextParam` / `previousParam` paths into TanStack Query's cursor-based
1616
- * pagination.
1617
- */
1618
- const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
1619
- name: "react-infinite-query",
1620
- renderer: kubb_jsx.jsxRenderer,
1621
- match(node, ctx) {
1622
- const operationNode = node;
1623
- if (!kubb_kit.ast.isHttpOperationNode(operationNode)) return false;
1624
- const { query, mutation, infinite, hooks } = ctx.options;
1625
- const { isQuery, isMutation } = classifyOperation(operationNode, {
1626
- query,
1627
- mutation
1628
- });
1629
- const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
1630
- if (!isQuery || isMutation || !infiniteOptions || !hooks) return false;
1631
- return matchesInfinite(operationNode, infiniteOptions);
1632
- },
1633
- operation(node, ctx) {
1634
- if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
1635
- const { config, driver, resolver, root } = ctx;
1636
- const { output, query, infinite, client, group, customOptions } = ctx.options;
1637
- const pluginTs = ctx.requirePlugin(_kubb_plugin_ts.pluginTsName);
1638
- const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1639
- const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
1640
- if (!infiniteOptions) return null;
1641
- const pageParamsWarning = getDefaultPageParamsWarning(node, infiniteOptions);
1642
- if (pageParamsWarning) ctx.warn(pageParamsWarning);
1643
- const importPath = query ? query.importPath : "@tanstack/react-query";
1644
- const contractOp = resolveClientOperation({
1645
- clientPlugin: { pluginName: client.pluginName },
1646
- driver,
1647
- node,
1648
- root,
1649
- output,
1650
- cache: ctx.cache
1651
- });
1652
- if (!contractOp) return null;
1653
- const queryName = resolver.infiniteQuery.name(node);
1654
- const queryOptionsName = resolver.infiniteQuery.optionsName(node);
1655
- const queryKeyName = resolver.infiniteQuery.keyName(node);
1656
- const queryKeyTypeName = resolver.infiniteQuery.keyTypeName(node);
1657
- const meta = {
1658
- file: resolver.file({
1659
- ...operationFileEntry(node, queryName),
1660
- root,
1661
- output,
1662
- group: group ?? void 0
1663
- }),
1664
- fileTs: resolveDependencyOperationFile({
1665
- cache: ctx.cache,
1666
- node,
1667
- resolver: tsResolver,
1668
- root,
1669
- output: pluginTs.options?.output ?? output,
1670
- group: pluginTs.options?.group
1671
- })
1672
- };
1673
- const { queryParamsTypeName } = resolvePageParamType(node, {
1674
- resolver: tsResolver,
1675
- initialPageParam: infiniteOptions.initialPageParam,
1676
- queryParam: infiniteOptions.queryParam
1677
- });
1678
- const importedTypeNames = [
1679
- tsResolver.response.options(node),
1680
- queryParamsTypeName,
1681
- ...resolveOperationTypeNames(node, tsResolver, {
1682
- exclude: [queryKeyTypeName],
1683
- order: "body-response-first",
1684
- includeParams: false
1685
- })
1686
- ].filter((name) => Boolean(name));
1687
- const calledClientName = contractOp.name;
1688
- return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
1689
- baseName: meta.file.baseName,
1690
- path: meta.file.path,
1691
- meta: meta.file.meta,
1692
- banner: resolver.default.banner(ctx.meta, {
1693
- output,
1694
- config,
1695
- file: {
1696
- path: meta.file.path,
1697
- baseName: meta.file.baseName
1698
- }
1699
- }),
1700
- footer: resolver.default.footer(ctx.meta, {
1701
- output,
1702
- config,
1703
- file: {
1704
- path: meta.file.path,
1705
- baseName: meta.file.baseName
1706
- }
1707
- }),
1708
- children: [
1709
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1710
- name: [contractOp.name],
1711
- root: meta.file.path,
1712
- path: contractOp.path
1713
- }),
1714
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1715
- name: ["RequestConfig", "ResponseErrorConfig"],
1716
- root: contractOp.clientPathIsFile ? meta.file.path : void 0,
1717
- path: contractOp.clientPath,
1718
- isTypeOnly: true
1719
- }),
1720
- customOptions && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1721
- name: [customOptions.name],
1722
- path: customOptions.importPath
1723
- }),
1724
- meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1725
- name: Array.from(new Set(importedTypeNames)),
1726
- root: meta.file.path,
1727
- path: meta.fileTs.path,
1728
- isTypeOnly: true
1729
- }),
1730
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryKey, {
1731
- name: queryKeyName,
1732
- typeName: queryKeyTypeName,
1733
- node,
1734
- tsResolver,
1735
- transformer: ctx.options.queryKey,
1736
- variant: "infiniteQuery"
1737
- }),
1738
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1739
- name: ["InfiniteData"],
1740
- isTypeOnly: true,
1741
- path: importPath
1742
- }),
1743
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1744
- name: ["infiniteQueryOptions"],
1745
- path: importPath
1746
- }),
1747
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(InfiniteQueryOptions, {
1748
- name: queryOptionsName,
1749
- clientName: calledClientName,
1750
- queryKeyName,
1751
- node,
1752
- tsResolver,
1753
- cursorParam: infiniteOptions.cursorParam,
1754
- nextParam: infiniteOptions.nextParam,
1755
- previousParam: infiniteOptions.previousParam,
1756
- getNextPageParam: infiniteOptions.getNextPageParam,
1757
- getPreviousPageParam: infiniteOptions.getPreviousPageParam,
1758
- initialPageParam: infiniteOptions.initialPageParam,
1759
- hasExplicitInitialPageParam: infiniteOptions.hasExplicitInitialPageParam,
1760
- queryParam: infiniteOptions.queryParam,
1761
- returnType: contractOp.returnType
1762
- }),
1763
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1764
- name: ["useInfiniteQuery"],
1765
- path: importPath
1766
- }),
1767
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1768
- name: [
1769
- "QueryKey",
1770
- "QueryClient",
1771
- "InfiniteQueryObserverOptions",
1772
- "UseInfiniteQueryResult"
1773
- ],
1774
- path: importPath,
1775
- isTypeOnly: true
1776
- }),
1777
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(InfiniteQuery, {
1778
- name: queryName,
1779
- queryOptionsName,
1780
- queryKeyName,
1781
- queryKeyTypeName,
1782
- node,
1783
- tsResolver,
1784
- initialPageParam: infiniteOptions.initialPageParam,
1785
- queryParam: infiniteOptions.queryParam,
1786
- customOptions
1787
- })
1788
- ]
1789
- });
1790
- }
1791
- });
1792
- //#endregion
1793
1859
  //#region src/generators/mutationGenerator.tsx
1794
1860
  /**
1795
1861
  * Built-in generator for `useMutation` hooks. Emits one `useFooMutation` hook
@@ -1810,10 +1876,8 @@ const mutationGenerator = (0, kubb_kit.defineGenerator)({
1810
1876
  },
1811
1877
  operation(node, ctx) {
1812
1878
  if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
1813
- const { config, driver, resolver, root } = ctx;
1879
+ const { driver, resolver, root } = ctx;
1814
1880
  const { output, mutation, client, group, customOptions, hooks } = ctx.options;
1815
- const pluginTs = ctx.requirePlugin(_kubb_plugin_ts.pluginTsName);
1816
- const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1817
1881
  const importPath = mutation ? mutation.importPath : "@tanstack/react-query";
1818
1882
  const contractOp = resolveClientOperation({
1819
1883
  clientPlugin: { pluginName: client.pluginName },
@@ -1825,72 +1889,22 @@ const mutationGenerator = (0, kubb_kit.defineGenerator)({
1825
1889
  });
1826
1890
  if (!contractOp) return null;
1827
1891
  const mutationHookName = resolver.mutation.name(node);
1828
- const mutationTypeName = resolver.mutation.typeName(node);
1829
1892
  const mutationOptionsName = resolver.mutation.optionsName(node);
1830
1893
  const mutationKeyName = resolver.mutation.keyName(node);
1831
- const meta = {
1832
- file: resolver.file({
1833
- ...operationFileEntry(node, mutationHookName),
1834
- root,
1835
- output,
1836
- group: group ?? void 0
1837
- }),
1838
- fileTs: resolveDependencyOperationFile({
1839
- cache: ctx.cache,
1840
- node,
1841
- resolver: tsResolver,
1842
- root,
1843
- output: pluginTs.options?.output ?? output,
1844
- group: pluginTs.options?.group
1845
- })
1846
- };
1847
- const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
1848
- order: "body-response-first",
1849
- includeParams: false
1850
- })].filter((name) => Boolean(name));
1851
- const calledClientName = contractOp.name;
1852
- return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
1853
- baseName: meta.file.baseName,
1854
- path: meta.file.path,
1855
- meta: meta.file.meta,
1856
- banner: resolver.default.banner(ctx.meta, {
1857
- output,
1858
- config,
1859
- file: {
1860
- path: meta.file.path,
1861
- baseName: meta.file.baseName
1862
- }
1863
- }),
1864
- footer: resolver.default.footer(ctx.meta, {
1865
- output,
1866
- config,
1867
- file: {
1868
- path: meta.file.path,
1869
- baseName: meta.file.baseName
1870
- }
1894
+ const hook = resolveHookFile(node, ctx, {
1895
+ name: mutationHookName,
1896
+ output,
1897
+ group,
1898
+ contractOp
1899
+ });
1900
+ const { tsResolver } = hook;
1901
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(HookFile, {
1902
+ hook,
1903
+ imports: customOptions && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1904
+ name: [customOptions.name],
1905
+ path: customOptions.importPath
1871
1906
  }),
1872
1907
  children: [
1873
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1874
- name: [contractOp.name],
1875
- root: meta.file.path,
1876
- path: contractOp.path
1877
- }),
1878
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1879
- name: ["RequestConfig", "ResponseErrorConfig"],
1880
- root: contractOp.clientPathIsFile ? meta.file.path : void 0,
1881
- path: contractOp.clientPath,
1882
- isTypeOnly: true
1883
- }),
1884
- customOptions && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1885
- name: [customOptions.name],
1886
- path: customOptions.importPath
1887
- }),
1888
- meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1889
- name: Array.from(new Set(importedTypeNames)),
1890
- root: meta.file.path,
1891
- path: meta.fileTs.path,
1892
- isTypeOnly: true
1893
- }),
1894
1908
  /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(MutationKey, {
1895
1909
  name: mutationKeyName,
1896
1910
  node,
@@ -1902,7 +1916,7 @@ const mutationGenerator = (0, kubb_kit.defineGenerator)({
1902
1916
  }),
1903
1917
  /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(MutationOptions, {
1904
1918
  name: mutationOptionsName,
1905
- clientName: calledClientName,
1919
+ clientName: contractOp.name,
1906
1920
  mutationKeyName,
1907
1921
  node,
1908
1922
  tsResolver,
@@ -1924,7 +1938,6 @@ const mutationGenerator = (0, kubb_kit.defineGenerator)({
1924
1938
  }),
1925
1939
  /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Mutation, {
1926
1940
  name: mutationHookName,
1927
- typeName: mutationTypeName,
1928
1941
  mutationOptionsName,
1929
1942
  mutationKeyName,
1930
1943
  node,
@@ -1943,151 +1956,9 @@ const mutationGenerator = (0, kubb_kit.defineGenerator)({
1943
1956
  * GET and QUERY operation (configurable via `query.methods`) plus the matching
1944
1957
  * `fooQueryKey` / `fooQueryOptions` helpers.
1945
1958
  */
1946
- const queryGenerator = (0, kubb_kit.defineGenerator)({
1959
+ const queryGenerator = createQueryGenerator({
1947
1960
  name: "react-query",
1948
- renderer: kubb_jsx.jsxRenderer,
1949
- match(node, ctx) {
1950
- const operationNode = node;
1951
- if (!kubb_kit.ast.isHttpOperationNode(operationNode)) return false;
1952
- const { query, mutation } = ctx.options;
1953
- const { isQuery, isMutation } = classifyOperation(operationNode, {
1954
- query,
1955
- mutation
1956
- });
1957
- return isQuery && !isMutation;
1958
- },
1959
- operation(node, ctx) {
1960
- if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
1961
- const { config, driver, resolver, root } = ctx;
1962
- const { output, query, client, group, customOptions, hooks } = ctx.options;
1963
- const pluginTs = ctx.requirePlugin(_kubb_plugin_ts.pluginTsName);
1964
- const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1965
- const importPath = query ? query.importPath : "@tanstack/react-query";
1966
- const contractOp = resolveClientOperation({
1967
- clientPlugin: { pluginName: client.pluginName },
1968
- driver,
1969
- node,
1970
- root,
1971
- output,
1972
- cache: ctx.cache
1973
- });
1974
- if (!contractOp) return null;
1975
- const queryName = resolver.query.name(node);
1976
- const queryOptionsName = resolver.query.optionsName(node);
1977
- const queryKeyName = resolver.query.keyName(node);
1978
- const queryKeyTypeName = resolver.query.keyTypeName(node);
1979
- const meta = {
1980
- file: resolver.file({
1981
- ...operationFileEntry(node, queryName),
1982
- root,
1983
- output,
1984
- group: group ?? void 0
1985
- }),
1986
- fileTs: resolveDependencyOperationFile({
1987
- cache: ctx.cache,
1988
- node,
1989
- resolver: tsResolver,
1990
- root,
1991
- output: pluginTs.options?.output ?? output,
1992
- group: pluginTs.options?.group
1993
- })
1994
- };
1995
- const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
1996
- exclude: [queryKeyTypeName],
1997
- order: "body-response-first",
1998
- includeParams: false
1999
- })].filter((name) => Boolean(name));
2000
- const calledClientName = contractOp.name;
2001
- return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
2002
- baseName: meta.file.baseName,
2003
- path: meta.file.path,
2004
- meta: meta.file.meta,
2005
- banner: resolver.default.banner(ctx.meta, {
2006
- output,
2007
- config,
2008
- file: {
2009
- path: meta.file.path,
2010
- baseName: meta.file.baseName
2011
- }
2012
- }),
2013
- footer: resolver.default.footer(ctx.meta, {
2014
- output,
2015
- config,
2016
- file: {
2017
- path: meta.file.path,
2018
- baseName: meta.file.baseName
2019
- }
2020
- }),
2021
- children: [
2022
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2023
- name: [contractOp.name],
2024
- root: meta.file.path,
2025
- path: contractOp.path
2026
- }),
2027
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2028
- name: ["RequestConfig", "ResponseErrorConfig"],
2029
- root: contractOp.clientPathIsFile ? meta.file.path : void 0,
2030
- path: contractOp.clientPath,
2031
- isTypeOnly: true
2032
- }),
2033
- customOptions && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2034
- name: [customOptions.name],
2035
- path: customOptions.importPath
2036
- }),
2037
- meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2038
- name: Array.from(new Set(importedTypeNames)),
2039
- root: meta.file.path,
2040
- path: meta.fileTs.path,
2041
- isTypeOnly: true
2042
- }),
2043
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryKey, {
2044
- name: queryKeyName,
2045
- typeName: queryKeyTypeName,
2046
- node,
2047
- tsResolver,
2048
- transformer: ctx.options.queryKey,
2049
- variant: "query"
2050
- }),
2051
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2052
- name: ["queryOptions"],
2053
- path: importPath
2054
- }),
2055
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryOptions, {
2056
- name: queryOptionsName,
2057
- clientName: calledClientName,
2058
- queryKeyName,
2059
- node,
2060
- tsResolver,
2061
- returnType: contractOp.returnType
2062
- }),
2063
- query && hooks && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [
2064
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2065
- name: ["useQuery"],
2066
- path: importPath
2067
- }),
2068
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2069
- name: [
2070
- "QueryKey",
2071
- "QueryClient",
2072
- "QueryObserverOptions",
2073
- "UseQueryResult"
2074
- ],
2075
- path: importPath,
2076
- isTypeOnly: true
2077
- }),
2078
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Query, {
2079
- name: queryName,
2080
- queryOptionsName,
2081
- queryKeyName,
2082
- queryKeyTypeName,
2083
- node,
2084
- tsResolver,
2085
- customOptions
2086
- })
2087
- ] })
2088
- ]
2089
- });
2090
- }
1961
+ variant: "query"
2091
1962
  });
2092
1963
  //#endregion
2093
1964
  //#region src/generators/suspenseInfiniteQueryGenerator.tsx
@@ -2097,178 +1968,9 @@ const queryGenerator = (0, kubb_kit.defineGenerator)({
2097
1968
  * semantics with cursor-based pagination. Handlers throw promises while
2098
1969
  * loading and pull additional pages on demand.
2099
1970
  */
2100
- const suspenseInfiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
1971
+ const suspenseInfiniteQueryGenerator = createQueryGenerator({
2101
1972
  name: "react-suspense-infinite-query",
2102
- renderer: kubb_jsx.jsxRenderer,
2103
- match(node, ctx) {
2104
- const operationNode = node;
2105
- if (!kubb_kit.ast.isHttpOperationNode(operationNode)) return false;
2106
- const { query, mutation, infinite, suspense, hooks } = ctx.options;
2107
- const { isQuery, isMutation } = classifyOperation(operationNode, {
2108
- query,
2109
- mutation
2110
- });
2111
- const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
2112
- if (!isQuery || isMutation || !suspense || !infiniteOptions || !hooks) return false;
2113
- return matchesInfinite(operationNode, infiniteOptions);
2114
- },
2115
- operation(node, ctx) {
2116
- if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
2117
- const { config, driver, resolver, root } = ctx;
2118
- const { output, query, infinite, client, group, customOptions } = ctx.options;
2119
- const pluginTs = ctx.requirePlugin(_kubb_plugin_ts.pluginTsName);
2120
- const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
2121
- const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
2122
- if (!infiniteOptions) return null;
2123
- const importPath = query ? query.importPath : "@tanstack/react-query";
2124
- const contractOp = resolveClientOperation({
2125
- clientPlugin: { pluginName: client.pluginName },
2126
- driver,
2127
- node,
2128
- root,
2129
- output,
2130
- cache: ctx.cache
2131
- });
2132
- if (!contractOp) return null;
2133
- const queryName = resolver.suspenseInfiniteQuery.name(node);
2134
- const queryOptionsName = resolver.suspenseInfiniteQuery.optionsName(node);
2135
- const queryKeyName = resolver.suspenseInfiniteQuery.keyName(node);
2136
- const queryKeyTypeName = resolver.suspenseInfiniteQuery.keyTypeName(node);
2137
- const meta = {
2138
- file: resolver.file({
2139
- ...operationFileEntry(node, queryName),
2140
- root,
2141
- output,
2142
- group: group ?? void 0
2143
- }),
2144
- fileTs: resolveDependencyOperationFile({
2145
- cache: ctx.cache,
2146
- node,
2147
- resolver: tsResolver,
2148
- root,
2149
- output: pluginTs.options?.output ?? output,
2150
- group: pluginTs.options?.group
2151
- })
2152
- };
2153
- const { queryParamsTypeName } = resolvePageParamType(node, {
2154
- resolver: tsResolver,
2155
- initialPageParam: infiniteOptions.initialPageParam,
2156
- queryParam: infiniteOptions.queryParam
2157
- });
2158
- const importedTypeNames = [
2159
- tsResolver.response.options(node),
2160
- queryParamsTypeName,
2161
- ...resolveOperationTypeNames(node, tsResolver, {
2162
- exclude: [queryKeyTypeName],
2163
- order: "body-response-first",
2164
- includeParams: false
2165
- })
2166
- ].filter((name) => Boolean(name));
2167
- const calledClientName = contractOp.name;
2168
- return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
2169
- baseName: meta.file.baseName,
2170
- path: meta.file.path,
2171
- meta: meta.file.meta,
2172
- banner: resolver.default.banner(ctx.meta, {
2173
- output,
2174
- config,
2175
- file: {
2176
- path: meta.file.path,
2177
- baseName: meta.file.baseName
2178
- }
2179
- }),
2180
- footer: resolver.default.footer(ctx.meta, {
2181
- output,
2182
- config,
2183
- file: {
2184
- path: meta.file.path,
2185
- baseName: meta.file.baseName
2186
- }
2187
- }),
2188
- children: [
2189
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2190
- name: [contractOp.name],
2191
- root: meta.file.path,
2192
- path: contractOp.path
2193
- }),
2194
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2195
- name: ["RequestConfig", "ResponseErrorConfig"],
2196
- root: contractOp.clientPathIsFile ? meta.file.path : void 0,
2197
- path: contractOp.clientPath,
2198
- isTypeOnly: true
2199
- }),
2200
- customOptions && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2201
- name: [customOptions.name],
2202
- path: customOptions.importPath
2203
- }),
2204
- meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2205
- name: Array.from(new Set(importedTypeNames)),
2206
- root: meta.file.path,
2207
- path: meta.fileTs.path,
2208
- isTypeOnly: true
2209
- }),
2210
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryKey, {
2211
- name: queryKeyName,
2212
- typeName: queryKeyTypeName,
2213
- node,
2214
- tsResolver,
2215
- transformer: ctx.options.queryKey,
2216
- variant: "suspenseInfiniteQuery"
2217
- }),
2218
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2219
- name: ["InfiniteData"],
2220
- isTypeOnly: true,
2221
- path: importPath
2222
- }),
2223
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2224
- name: ["infiniteQueryOptions"],
2225
- path: importPath
2226
- }),
2227
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(InfiniteQueryOptions, {
2228
- name: queryOptionsName,
2229
- clientName: calledClientName,
2230
- queryKeyName,
2231
- node,
2232
- tsResolver,
2233
- cursorParam: infiniteOptions.cursorParam,
2234
- nextParam: infiniteOptions.nextParam,
2235
- previousParam: infiniteOptions.previousParam,
2236
- getNextPageParam: infiniteOptions.getNextPageParam,
2237
- getPreviousPageParam: infiniteOptions.getPreviousPageParam,
2238
- initialPageParam: infiniteOptions.initialPageParam,
2239
- hasExplicitInitialPageParam: infiniteOptions.hasExplicitInitialPageParam,
2240
- queryParam: infiniteOptions.queryParam,
2241
- returnType: contractOp.returnType
2242
- }),
2243
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2244
- name: ["useSuspenseInfiniteQuery"],
2245
- path: importPath
2246
- }),
2247
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2248
- name: [
2249
- "QueryKey",
2250
- "QueryClient",
2251
- "UseSuspenseInfiniteQueryOptions",
2252
- "UseSuspenseInfiniteQueryResult"
2253
- ],
2254
- path: importPath,
2255
- isTypeOnly: true
2256
- }),
2257
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(InfiniteQuery, {
2258
- name: queryName,
2259
- queryOptionsName,
2260
- queryKeyName,
2261
- queryKeyTypeName,
2262
- node,
2263
- tsResolver,
2264
- initialPageParam: infiniteOptions.initialPageParam,
2265
- queryParam: infiniteOptions.queryParam,
2266
- customOptions,
2267
- suspense: true
2268
- })
2269
- ]
2270
- });
2271
- }
1973
+ variant: "suspenseInfiniteQuery"
2272
1974
  });
2273
1975
  //#endregion
2274
1976
  //#region src/generators/suspenseQueryGenerator.tsx
@@ -2279,150 +1981,9 @@ const suspenseInfiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
2279
1981
  * promises while loading and require a `<Suspense>` boundary in the React
2280
1982
  * tree. TanStack Query v5+ only.
2281
1983
  */
2282
- const suspenseQueryGenerator = (0, kubb_kit.defineGenerator)({
1984
+ const suspenseQueryGenerator = createQueryGenerator({
2283
1985
  name: "react-suspense-query",
2284
- renderer: kubb_jsx.jsxRenderer,
2285
- match(node, ctx) {
2286
- const operationNode = node;
2287
- if (!kubb_kit.ast.isHttpOperationNode(operationNode)) return false;
2288
- const { query, mutation, suspense, hooks } = ctx.options;
2289
- const { isQuery, isMutation } = classifyOperation(operationNode, {
2290
- query,
2291
- mutation
2292
- });
2293
- return isQuery && !isMutation && !!suspense && hooks;
2294
- },
2295
- operation(node, ctx) {
2296
- if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
2297
- const { config, driver, resolver, root } = ctx;
2298
- const { output, query, client, group, customOptions } = ctx.options;
2299
- const pluginTs = ctx.requirePlugin(_kubb_plugin_ts.pluginTsName);
2300
- const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
2301
- const importPath = query ? query.importPath : "@tanstack/react-query";
2302
- const contractOp = resolveClientOperation({
2303
- clientPlugin: { pluginName: client.pluginName },
2304
- driver,
2305
- node,
2306
- root,
2307
- output,
2308
- cache: ctx.cache
2309
- });
2310
- if (!contractOp) return null;
2311
- const queryName = resolver.suspenseQuery.name(node);
2312
- const queryOptionsName = resolver.suspenseQuery.optionsName(node);
2313
- const queryKeyName = resolver.suspenseQuery.keyName(node);
2314
- const queryKeyTypeName = resolver.suspenseQuery.keyTypeName(node);
2315
- const meta = {
2316
- file: resolver.file({
2317
- ...operationFileEntry(node, queryName),
2318
- root,
2319
- output,
2320
- group: group ?? void 0
2321
- }),
2322
- fileTs: resolveDependencyOperationFile({
2323
- cache: ctx.cache,
2324
- node,
2325
- resolver: tsResolver,
2326
- root,
2327
- output: pluginTs.options?.output ?? output,
2328
- group: pluginTs.options?.group
2329
- })
2330
- };
2331
- const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
2332
- exclude: [queryKeyTypeName],
2333
- order: "body-response-first",
2334
- includeParams: false
2335
- })].filter((name) => Boolean(name));
2336
- const calledClientName = contractOp.name;
2337
- return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
2338
- baseName: meta.file.baseName,
2339
- path: meta.file.path,
2340
- meta: meta.file.meta,
2341
- banner: resolver.default.banner(ctx.meta, {
2342
- output,
2343
- config,
2344
- file: {
2345
- path: meta.file.path,
2346
- baseName: meta.file.baseName
2347
- }
2348
- }),
2349
- footer: resolver.default.footer(ctx.meta, {
2350
- output,
2351
- config,
2352
- file: {
2353
- path: meta.file.path,
2354
- baseName: meta.file.baseName
2355
- }
2356
- }),
2357
- children: [
2358
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2359
- name: [contractOp.name],
2360
- root: meta.file.path,
2361
- path: contractOp.path
2362
- }),
2363
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2364
- name: ["RequestConfig", "ResponseErrorConfig"],
2365
- root: contractOp.clientPathIsFile ? meta.file.path : void 0,
2366
- path: contractOp.clientPath,
2367
- isTypeOnly: true
2368
- }),
2369
- customOptions && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2370
- name: [customOptions.name],
2371
- path: customOptions.importPath
2372
- }),
2373
- meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2374
- name: Array.from(new Set(importedTypeNames)),
2375
- root: meta.file.path,
2376
- path: meta.fileTs.path,
2377
- isTypeOnly: true
2378
- }),
2379
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryKey, {
2380
- name: queryKeyName,
2381
- typeName: queryKeyTypeName,
2382
- node,
2383
- tsResolver,
2384
- transformer: ctx.options.queryKey,
2385
- variant: "suspenseQuery"
2386
- }),
2387
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2388
- name: ["queryOptions"],
2389
- path: importPath
2390
- }),
2391
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryOptions, {
2392
- name: queryOptionsName,
2393
- clientName: calledClientName,
2394
- queryKeyName,
2395
- node,
2396
- tsResolver,
2397
- returnType: contractOp.returnType
2398
- }),
2399
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2400
- name: ["useSuspenseQuery"],
2401
- path: importPath
2402
- }),
2403
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
2404
- name: [
2405
- "QueryKey",
2406
- "QueryClient",
2407
- "UseSuspenseQueryOptions",
2408
- "UseSuspenseQueryResult"
2409
- ],
2410
- path: importPath,
2411
- isTypeOnly: true
2412
- }),
2413
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Query, {
2414
- name: queryName,
2415
- queryOptionsName,
2416
- queryKeyName,
2417
- queryKeyTypeName,
2418
- node,
2419
- tsResolver,
2420
- customOptions,
2421
- suspense: true
2422
- })
2423
- ]
2424
- });
2425
- }
1986
+ variant: "suspenseQuery"
2426
1987
  });
2427
1988
  //#endregion
2428
1989
  //#region src/resolvers/resolverReactQuery.ts
@@ -2521,6 +2082,7 @@ const pluginReactQuery = (0, kubb_kit.defineExtension)({
2521
2082
  return {
2522
2083
  output,
2523
2084
  client: resolveContractClient({
2085
+ plugin: pluginReactQueryName,
2524
2086
  client,
2525
2087
  plugins: (0, kubb_kit.useConfig)().plugins
2526
2088
  }),