@kubb/plugin-react-query 5.0.0-beta.85 → 5.0.0-beta.87

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,6 +1,6 @@
1
1
  import "./rolldown-runtime-C0LytTxp.js";
2
+ import { Resolver, ast, createResolver, defineGenerator, definePlugin } from "kubb/kit";
2
3
  import path from "node:path";
3
- import { ast, defineGenerator, definePlugin, defineResolver } from "kubb/kit";
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";
@@ -32,31 +32,6 @@ function camelCase(text, { prefix = "", suffix = "" } = {}) {
32
32
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
33
33
  }
34
34
  //#endregion
35
- //#region ../../internals/utils/src/fs.ts
36
- /**
37
- * Builds a nested file path from a dotted name. Splits on dots that precede a letter
38
- * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
39
- * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
40
- *
41
- * Empty segments are dropped before joining. They arise when the name starts with a dot
42
- * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
43
- * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
44
- * absolute path, letting generated files escape the configured output directory.
45
- *
46
- * @example Nested path from a dotted name
47
- * `toFilePath('pet.petId') // 'pet/petId'`
48
- *
49
- * @example PascalCase the final segment
50
- * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
51
- *
52
- * @example Suffix applied to the final segment only
53
- * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
54
- */
55
- function toFilePath(name, caseLast = camelCase) {
56
- const parts = name.split(/\.(?=[a-zA-Z])/);
57
- return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
58
- }
59
- //#endregion
60
35
  //#region ../../internals/utils/src/reserved.ts
61
36
  /**
62
37
  * JavaScript and Java reserved words.
@@ -157,9 +132,42 @@ const reservedWords = /* @__PURE__ */ new Set([
157
132
  */
158
133
  function isValidVarName(name) {
159
134
  if (!name || reservedWords.has(name)) return false;
135
+ return isIdentifier(name);
136
+ }
137
+ /**
138
+ * Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
139
+ *
140
+ * Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
141
+ * even though they are not valid variable names, so use this (not {@link isValidVarName}) when
142
+ * deciding whether an object key needs quoting.
143
+ *
144
+ * @example
145
+ * ```ts
146
+ * isIdentifier('name') // true
147
+ * isIdentifier('x-total')// false
148
+ * ```
149
+ */
150
+ function isIdentifier(name) {
160
151
  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
161
152
  }
162
153
  //#endregion
154
+ //#region ../../internals/utils/src/strings.ts
155
+ /**
156
+ * Renders a dotted path or string array as an optional-chaining accessor expression rooted at
157
+ * `accessor`. Returns `null` for an empty path.
158
+ *
159
+ * @example
160
+ * ```ts
161
+ * getNestedAccessor('pagination.next.id', 'lastPage')
162
+ * // "lastPage?.['pagination']?.['next']?.['id']"
163
+ * ```
164
+ */
165
+ function getNestedAccessor(param, accessor) {
166
+ const parts = Array.isArray(param) ? param : param.split(".");
167
+ if (parts.length === 0 || parts.length === 1 && parts[0] === "") return null;
168
+ return `${accessor}?.['${`${parts.join("']?.['")}']`}`;
169
+ }
170
+ //#endregion
163
171
  //#region ../../internals/utils/src/url.ts
164
172
  function transformParam(raw, casing) {
165
173
  const param = isValidVarName(raw) ? raw : camelCase(raw);
@@ -312,13 +320,13 @@ function dedupeByCasedName(params) {
312
320
  //#region ../../internals/shared/src/operation.ts
313
321
  /**
314
322
  * Builds the `ResolverFileParams` every operation generator passes to
315
- * `resolver.resolveFile`: a file named `name`, tagged by the operation's first
323
+ * `resolver.file`: a file named `name`, tagged by the operation's first
316
324
  * tag (or `'default'`), at the operation's path. Centralizes the entry object
317
325
  * that was repeated at dozens of call sites across the client and query plugins.
318
326
  *
319
327
  * @example
320
328
  * ```ts
321
- * resolver.resolveFile(operationFileEntry(node, node.operationId), { root, output, group })
329
+ * resolver.file(operationFileEntry(node, node.operationId), { root, output, group })
322
330
  * ```
323
331
  */
324
332
  function operationFileEntry(node, name, extname = ".ts") {
@@ -335,8 +343,11 @@ function getOperationLink(node, link) {
335
343
  if (link === "urlPath") return node.path ? `{@link ${Url.toPath(node.path)}}` : null;
336
344
  return node.path ? `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}` : null;
337
345
  }
338
- function getContentTypeInfo(node) {
339
- const contentTypes = node.requestBody?.content?.map((e) => e.contentType) ?? [];
346
+ /**
347
+ * Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several
348
+ * are present and the union, default, and form-data flags the client uses to pick one.
349
+ */
350
+ function buildContentTypeInfo(contentTypes) {
340
351
  const isMultipleContentTypes = contentTypes.length > 1;
341
352
  return {
342
353
  contentTypes,
@@ -346,20 +357,15 @@ function getContentTypeInfo(node) {
346
357
  hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
347
358
  };
348
359
  }
360
+ function getContentTypeInfo(node) {
361
+ return buildContentTypeInfo(node.requestBody?.content?.map((e) => e.contentType) ?? []);
362
+ }
349
363
  /**
350
364
  * The request-body counterpart for the primary success response: the content types it documents and
351
365
  * whether several are present, so the client can let a caller pick which one to accept.
352
366
  */
353
367
  function getResponseContentTypeInfo(node) {
354
- const contentTypes = getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? [];
355
- const isMultipleContentTypes = contentTypes.length > 1;
356
- return {
357
- contentTypes,
358
- isMultipleContentTypes,
359
- contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(" | ") : "",
360
- defaultContentType: contentTypes[0] ?? "application/json",
361
- hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
362
- };
368
+ return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? []);
363
369
  }
364
370
  function buildRequestConfigType(node) {
365
371
  const request = getContentTypeInfo(node);
@@ -456,13 +462,13 @@ function getPrimarySuccessResponse(node) {
456
462
  return getOperationSuccessResponses(node)[0] ?? null;
457
463
  }
458
464
  function resolveErrorNames(node, resolver) {
459
- return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
465
+ return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode));
460
466
  }
461
467
  function resolveSuccessNames(node, resolver) {
462
- return node.responses.filter((response) => isSuccessStatusCode(response.statusCode)).map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
468
+ return node.responses.filter((response) => isSuccessStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode));
463
469
  }
464
470
  function resolveStatusCodeNames(node, resolver) {
465
- return node.responses.map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
471
+ return node.responses.map((response) => resolver.response.status(node, response.statusCode));
466
472
  }
467
473
  const typeNamesByResolver = /* @__PURE__ */ new WeakMap();
468
474
  function resolveOperationTypeNames(node, resolver, options = {}) {
@@ -479,11 +485,11 @@ function resolveOperationTypeNames(node, resolver, options = {}) {
479
485
  const responseStatusNames = options.responseStatusNames === "error" ? resolveErrorNames(node, resolver) : options.responseStatusNames === false ? [] : resolveStatusCodeNames(node, resolver);
480
486
  const exclude = new Set(options.exclude ?? []);
481
487
  const paramNames = options.includeParams === false ? [] : [
482
- ...path.map((param) => resolver.resolvePathParamsName(node, param)),
483
- ...query.map((param) => resolver.resolveQueryParamsName(node, param)),
484
- ...header.map((param) => resolver.resolveHeaderParamsName(node, param))
488
+ ...path.map((param) => resolver.param.path(node, param)),
489
+ ...query.map((param) => resolver.param.query(node, param)),
490
+ ...header.map((param) => resolver.param.headers(node, param))
485
491
  ];
486
- const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null, resolver.resolveResponseName(node)];
492
+ const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.response.body(node) : null, resolver.response.response(node)];
487
493
  const result = (options.order === "body-response-first" ? [
488
494
  ...bodyAndResponseNames,
489
495
  ...paramNames,
@@ -607,15 +613,15 @@ function resolveClientOperation(options) {
607
613
  const { clientPlugin, driver, node, root, output } = options;
608
614
  if (!clientPlugin) return null;
609
615
  const resolver = driver.getResolver(clientPlugin.pluginName);
610
- if (!resolver) return null;
611
616
  const plugin = driver.getPlugin(clientPlugin.pluginName);
612
- const file = resolver.resolveFile(operationFileEntry(node, node.operationId), {
617
+ const file = resolver.file({
618
+ ...operationFileEntry(node, node.operationId),
613
619
  root,
614
620
  output: plugin?.options?.output ?? output,
615
621
  group: plugin?.options?.group ?? void 0
616
622
  });
617
623
  return {
618
- name: resolver.resolveName(node.operationId),
624
+ name: resolver.name(node.operationId),
619
625
  path: file.path,
620
626
  clientPath: path.resolve(root, ".kubb/client.ts")
621
627
  };
@@ -665,12 +671,12 @@ function maybeValueOrGetter(type) {
665
671
  /**
666
672
  * Builds the grouped `{ path, query, body, headers }` parameter that mirrors the client
667
673
  * function signature. Only the groups the operation carries are emitted, typed from the
668
- * operation's `RequestConfig`. `keys` narrows the emitted groups, used by the query key which
674
+ * operation's `Options`. `keys` narrows the emitted groups, used by the query key which
669
675
  * never carries `headers`.
670
676
  *
671
- * By default the whole group is typed as the single `RequestConfig` reference. When
677
+ * By default the whole group is typed as the single `Options` reference. When
672
678
  * `memberTypeWrapper` is set, each group is emitted as its own member typed from the matching
673
- * `RequestConfig['<group>']` slice and wrapped, used by vue-query to apply
679
+ * `Options['<group>']` slice and wrapped, used by vue-query to apply
674
680
  * `MaybeRefOrGetter` per group.
675
681
  */
676
682
  function buildGroupedRequestParam(node, options) {
@@ -685,13 +691,13 @@ function buildGroupedRequestParam(node, options) {
685
691
  headers: hasRequiredHeader
686
692
  };
687
693
  const isOptional = names.every((name) => !requiredByGroup[name]);
688
- const requestConfigName = resolver.resolveRequestConfigName(node);
694
+ const optionsName = resolver.response.options(node);
689
695
  const omittedKeys = requestGroupOrder$1.filter((key) => !keys.includes(key));
690
- const requestConfigType = omittedKeys.length > 0 ? `Omit<${requestConfigName}, ${omittedKeys.map((key) => `'${key}'`).join(" | ")}>` : requestConfigName;
696
+ const optionsType = omittedKeys.length > 0 ? `Omit<${optionsName}, ${omittedKeys.map((key) => `'${key}'`).join(" | ")}>` : optionsName;
691
697
  if (memberTypeWrapper) {
692
698
  const members = names.map((name) => ({
693
699
  name,
694
- type: memberTypeWrapper(`${requestConfigType}['${name}']`),
700
+ type: memberTypeWrapper(`${optionsType}['${name}']`),
695
701
  optional: !requiredByGroup[name]
696
702
  }));
697
703
  return createFunctionParameter({
@@ -703,7 +709,7 @@ function buildGroupedRequestParam(node, options) {
703
709
  }
704
710
  return createFunctionParameter({
705
711
  name: createObjectBindingPattern({ elements: names.map((name) => ({ name })) }),
706
- type: requestConfigType,
712
+ type: optionsType,
707
713
  optional: false,
708
714
  ...isOptional ? { default: "{}" } : {}
709
715
  });
@@ -771,7 +777,7 @@ function resolveOperationOverrides(node, override) {
771
777
  }
772
778
  /**
773
779
  * Build QueryKey params as the grouped `{ path, query, body }` object (NO headers, NO config),
774
- * typed from the operation's `RequestConfig` minus `url`. The query key transformer reads the
780
+ * typed from the operation's `Options` minus `url`. The query key transformer reads the
775
781
  * grouped `path`/`query`/`body` bindings.
776
782
  */
777
783
  function buildQueryKeyParams(node, options) {
@@ -843,19 +849,18 @@ const customHookOptionsFileGenerator = defineGenerator({
843
849
  const { output, customOptions, query, group } = ctx.options;
844
850
  if (!customOptions) return null;
845
851
  const { importPath, name } = customOptions;
846
- const hookOptionsName = resolver.resolveHookOptionsName();
847
- const customHookOptionsName = resolver.resolveCustomHookOptionsName();
852
+ const hookOptionsName = resolver.hook.optionsName();
853
+ const customHookOptionsName = resolver.hook.customOptionsName();
848
854
  const reactQueryImportPath = query ? query.importPath : "@tanstack/react-query";
849
855
  let hookFilePath;
850
856
  const firstNode = nodes[0];
851
857
  if (firstNode) {
852
- const hookName = resolver.resolveQueryName(firstNode);
853
- hookFilePath = resolver.resolveFile({
858
+ const hookName = resolver.query.name(firstNode);
859
+ hookFilePath = resolver.file({
854
860
  name: hookName,
855
861
  extname: ".ts",
856
862
  tag: firstNode.tags[0] ?? "default",
857
- path: firstNode.path
858
- }, {
863
+ path: firstNode.path,
859
864
  root,
860
865
  output,
861
866
  group: group ?? void 0
@@ -947,6 +952,59 @@ function buildResolvedRequestParams(node) {
947
952
  if (names.length === 0) return null;
948
953
  return `{ ${names.map((name) => `${name}: typeof ${name} === 'function' ? ${name}() : ${name}`).join(", ")} }`;
949
954
  }
955
+ /**
956
+ * Classifies an operation as a query or a mutation from the resolved `query` / `mutation` method lists.
957
+ * `query: false` still marks the operation as a query so the query-family generators keep matching it,
958
+ * and a method already claimed by `query` never counts as a mutation.
959
+ */
960
+ function classifyOperation(node, { query, mutation }) {
961
+ const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
962
+ const queryMethods = new Set(query ? query.methods : []);
963
+ return {
964
+ isQuery,
965
+ isMutation: mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase())
966
+ };
967
+ }
968
+ /**
969
+ * Builds the `TData` / `TError` type expressions shared by every generated hook, joining the resolved
970
+ * success responses into `TData` and wrapping the error responses in `ResponseErrorConfig<...>`.
971
+ */
972
+ function buildResponseTypes(node, resolver) {
973
+ const successNames = resolveSuccessNames(node, resolver);
974
+ const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
975
+ const errorNames = resolveErrorNames(node, resolver);
976
+ return {
977
+ TData: responseName,
978
+ TError: `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`
979
+ };
980
+ }
981
+ function resolveFallbackPageParamType(initialPageParam) {
982
+ if (typeof initialPageParam === "number") return "number";
983
+ if (typeof initialPageParam === "boolean") return "boolean";
984
+ if (typeof initialPageParam !== "string") return "unknown";
985
+ if (!initialPageParam.includes(" as ")) return "string";
986
+ return initialPageParam.split(" as ").at(-1) ?? "unknown";
987
+ }
988
+ /**
989
+ * Resolves the `TPageParam` generic for the infinite-query hooks. Prefers the type read from the
990
+ * configured `queryParam` on the operation's query object, and falls back to the type inferred from
991
+ * `initialPageParam` when that parameter type is unavailable. Also returns the query params type name
992
+ * so callers can reuse it when rewriting the paginated request.
993
+ */
994
+ function resolvePageParamType(node, { resolver, initialPageParam, queryParam }) {
995
+ const firstQueryParam = getOperationParameters(node, { paramsCasing: "original" }).query[0];
996
+ const groupName = firstQueryParam ? resolver.param.query(node, firstQueryParam) : null;
997
+ const queryParamsTypeName = groupName !== (firstQueryParam ? resolver.param.name(node, firstQueryParam) : null) ? groupName : null;
998
+ const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
999
+ if (!queryParamType) return {
1000
+ queryParamsTypeName,
1001
+ pageParamType: resolveFallbackPageParamType(initialPageParam)
1002
+ };
1003
+ return {
1004
+ queryParamsTypeName,
1005
+ pageParamType: initialPageParam !== void 0 && initialPageParam !== null ? `NonNullable<${queryParamType}>` : queryParamType
1006
+ };
1007
+ }
950
1008
  //#endregion
951
1009
  //#region src/generators/hookOptionsGenerator.tsx
952
1010
  /**
@@ -962,11 +1020,10 @@ const hookOptionsGenerator = defineGenerator({
962
1020
  const { resolver, config, root } = ctx;
963
1021
  const { output, customOptions, query, mutation, suspense, infinite, group, override, hooks } = ctx.options;
964
1022
  if (!customOptions || !hooks) return null;
965
- const name = resolver.resolveHookOptionsName();
966
- const resolvedFile = resolver.resolveFile({
1023
+ const name = resolver.hook.optionsName();
1024
+ const resolvedFile = resolver.file({
967
1025
  name,
968
- extname: ".ts"
969
- }, {
1026
+ extname: ".ts",
970
1027
  root,
971
1028
  output,
972
1029
  group: group ?? void 0
@@ -991,9 +1048,10 @@ const hookOptionsGenerator = defineGenerator({
991
1048
  const isSuspenseOp = !!suspense;
992
1049
  const isInfiniteOp = !!nodeInfiniteOptions;
993
1050
  if (isQueryOp) {
994
- const queryOptionsName = resolver.resolveQueryOptionsName(node);
995
- const queryHookName = resolver.resolveQueryName(node);
996
- const queryHookFile = resolver.resolveFile(operationFileEntry(node, queryHookName), {
1051
+ const queryOptionsName = resolver.query.optionsName(node);
1052
+ const queryHookName = resolver.query.name(node);
1053
+ const queryHookFile = resolver.file({
1054
+ ...operationFileEntry(node, queryHookName),
997
1055
  root,
998
1056
  output,
999
1057
  group: group ?? void 0
@@ -1005,9 +1063,10 @@ const hookOptionsGenerator = defineGenerator({
1005
1063
  }));
1006
1064
  hookOptions[queryHookName] = `Partial<ReturnType<typeof ${queryOptionsName}>>`;
1007
1065
  if (isSuspenseOp) {
1008
- const suspenseOptionsName = resolver.resolveSuspenseQueryOptionsName(node);
1009
- const suspenseHookName = resolver.resolveSuspenseQueryName(node);
1010
- const suspenseHookFile = resolver.resolveFile(operationFileEntry(node, suspenseHookName), {
1066
+ const suspenseOptionsName = resolver.suspenseQuery.optionsName(node);
1067
+ const suspenseHookName = resolver.suspenseQuery.name(node);
1068
+ const suspenseHookFile = resolver.file({
1069
+ ...operationFileEntry(node, suspenseHookName),
1011
1070
  root,
1012
1071
  output,
1013
1072
  group: group ?? void 0
@@ -1023,9 +1082,10 @@ const hookOptionsGenerator = defineGenerator({
1023
1082
  const normalizeKey = (key) => key.replace(/\?$/, "");
1024
1083
  const queryParamKeys = getOperationParameters(node, { paramsCasing: "original" }).query.map((p) => p.name);
1025
1084
  if (nodeInfiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === nodeInfiniteOptions.queryParam) : false) {
1026
- const infiniteOptionsName = resolver.resolveInfiniteQueryOptionsName(node);
1027
- const infiniteHookName = resolver.resolveInfiniteQueryName(node);
1028
- const infiniteHookFile = resolver.resolveFile(operationFileEntry(node, infiniteHookName), {
1085
+ const infiniteOptionsName = resolver.infiniteQuery.optionsName(node);
1086
+ const infiniteHookName = resolver.infiniteQuery.name(node);
1087
+ const infiniteHookFile = resolver.file({
1088
+ ...operationFileEntry(node, infiniteHookName),
1029
1089
  root,
1030
1090
  output,
1031
1091
  group: group ?? void 0
@@ -1037,9 +1097,10 @@ const hookOptionsGenerator = defineGenerator({
1037
1097
  }));
1038
1098
  hookOptions[infiniteHookName] = `Partial<ReturnType<typeof ${infiniteOptionsName}>>`;
1039
1099
  if (isSuspenseOp) {
1040
- const suspenseInfiniteOptionsName = resolver.resolveSuspenseInfiniteQueryOptionsName(node);
1041
- const suspenseInfiniteHookName = resolver.resolveSuspenseInfiniteQueryName(node);
1042
- const suspenseInfiniteHookFile = resolver.resolveFile(operationFileEntry(node, suspenseInfiniteHookName), {
1100
+ const suspenseInfiniteOptionsName = resolver.suspenseInfiniteQuery.optionsName(node);
1101
+ const suspenseInfiniteHookName = resolver.suspenseInfiniteQuery.name(node);
1102
+ const suspenseInfiniteHookFile = resolver.file({
1103
+ ...operationFileEntry(node, suspenseInfiniteHookName),
1043
1104
  root,
1044
1105
  output,
1045
1106
  group: group ?? void 0
@@ -1055,9 +1116,10 @@ const hookOptionsGenerator = defineGenerator({
1055
1116
  }
1056
1117
  }
1057
1118
  if (isMutationOp) {
1058
- const mutationOptionsName = resolver.resolveMutationOptionsName(node);
1059
- const mutationHookName = resolver.resolveMutationName(node);
1060
- const mutationHookFile = resolver.resolveFile(operationFileEntry(node, mutationHookName), {
1119
+ const mutationOptionsName = resolver.mutation.optionsName(node);
1120
+ const mutationHookName = resolver.mutation.name(node);
1121
+ const mutationHookFile = resolver.file({
1122
+ ...operationFileEntry(node, mutationHookName),
1061
1123
  root,
1062
1124
  output,
1063
1125
  group: group ?? void 0
@@ -1074,7 +1136,7 @@ const hookOptionsGenerator = defineGenerator({
1074
1136
  baseName: hookOptionsFile.baseName,
1075
1137
  path: hookOptionsFile.path,
1076
1138
  meta: hookOptionsFile.meta,
1077
- banner: resolver.resolveBanner(ctx.meta, {
1139
+ banner: resolver.default.banner(ctx.meta, {
1078
1140
  output,
1079
1141
  config,
1080
1142
  file: {
@@ -1082,7 +1144,7 @@ const hookOptionsGenerator = defineGenerator({
1082
1144
  baseName: hookOptionsFile.baseName
1083
1145
  }
1084
1146
  }),
1085
- footer: resolver.resolveFooter(ctx.meta, {
1147
+ footer: resolver.default.footer(ctx.meta, {
1086
1148
  output,
1087
1149
  config,
1088
1150
  file: {
@@ -1123,23 +1185,12 @@ function buildInfiniteQueryParamsNode(node, options) {
1123
1185
  }), optionsParam].filter((param) => param !== null) });
1124
1186
  }
1125
1187
  function InfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, initialPageParam, queryParam, customOptions }) {
1126
- const successNames = resolveSuccessNames(node, tsResolver);
1127
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
1128
- const errorNames = resolveErrorNames(node, tsResolver);
1129
- const responseType = responseName;
1130
- const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1131
- const isInitialPageParamDefined = initialPageParam !== void 0 && initialPageParam !== null;
1132
- const fallbackPageParamType = typeof initialPageParam === "number" ? "number" : typeof initialPageParam === "string" ? initialPageParam.includes(" as ") ? (() => {
1133
- const parts = initialPageParam.split(" as ");
1134
- return parts[parts.length - 1] ?? "unknown";
1135
- })() : "string" : typeof initialPageParam === "boolean" ? "boolean" : "unknown";
1136
- const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
1137
- const queryParamsTypeName = rawQueryParams.length > 0 ? (() => {
1138
- const groupName = tsResolver.resolveQueryParamsName(node, rawQueryParams[0]);
1139
- return groupName !== tsResolver.resolveParamName(node, rawQueryParams[0]) ? groupName : null;
1140
- })() : null;
1141
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
1142
- const pageParamType = queryParamType ? isInitialPageParamDefined ? `NonNullable<${queryParamType}>` : queryParamType : fallbackPageParamType;
1188
+ const { TData: responseType, TError: errorType } = buildResponseTypes(node, tsResolver);
1189
+ const { pageParamType } = resolvePageParamType(node, {
1190
+ resolver: tsResolver,
1191
+ initialPageParam,
1192
+ queryParam
1193
+ });
1143
1194
  const returnType = "UseInfiniteQueryResult<TData, TError> & { queryKey: TQueryKey }";
1144
1195
  const generics = [
1145
1196
  `TQueryFnData = ${responseType}`,
@@ -1193,11 +1244,7 @@ function getQueryOptionsParams(node, options) {
1193
1244
  return buildQueryOptionsParams(node, options);
1194
1245
  }
1195
1246
  function QueryOptions({ name, clientName, node, tsResolver, queryKeyName }) {
1196
- const successNames = resolveSuccessNames(node, tsResolver);
1197
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
1198
- const errorNames = resolveErrorNames(node, tsResolver);
1199
- const TData = responseName;
1200
- const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1247
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1201
1248
  const queryKeyParamsNode = buildQueryKeyParams(node, { resolver: tsResolver });
1202
1249
  const queryKeyParamsCall = callPrinter$4.print(queryKeyParamsNode) ?? "";
1203
1250
  const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
@@ -1232,22 +1279,12 @@ function QueryOptions({ name, clientName, node, tsResolver, queryKeyName }) {
1232
1279
  const declarationPrinter$6 = functionPrinter({ mode: "declaration" });
1233
1280
  const callPrinter$3 = functionPrinter({ mode: "call" });
1234
1281
  function InfiniteQueryOptions({ name, clientName, initialPageParam, cursorParam, nextParam, previousParam, node, tsResolver, queryParam, queryKeyName }) {
1235
- const successNames = resolveSuccessNames(node, tsResolver);
1236
- const queryFnDataType = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
1237
- const errorNames = resolveErrorNames(node, tsResolver);
1238
- const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1239
- const isInitialPageParamDefined = initialPageParam !== void 0 && initialPageParam !== null;
1240
- const fallbackPageParamType = typeof initialPageParam === "number" ? "number" : typeof initialPageParam === "string" ? initialPageParam.includes(" as ") ? (() => {
1241
- const parts = initialPageParam.split(" as ");
1242
- return parts[parts.length - 1] ?? "unknown";
1243
- })() : "string" : typeof initialPageParam === "boolean" ? "boolean" : "unknown";
1244
- const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
1245
- const queryParamsTypeName = rawQueryParams.length > 0 ? (() => {
1246
- const groupName = tsResolver.resolveQueryParamsName(node, rawQueryParams[0]);
1247
- return groupName !== tsResolver.resolveParamName(node, rawQueryParams[0]) ? groupName : null;
1248
- })() : null;
1249
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
1250
- const pageParamType = queryParamType ? isInitialPageParamDefined ? `NonNullable<${queryParamType}>` : queryParamType : fallbackPageParamType;
1282
+ const { TData: queryFnDataType, TError: errorType } = buildResponseTypes(node, tsResolver);
1283
+ const { queryParamsTypeName, pageParamType } = resolvePageParamType(node, {
1284
+ resolver: tsResolver,
1285
+ initialPageParam,
1286
+ queryParam
1287
+ });
1251
1288
  const queryKeyParamsNode = buildQueryKeyParams(node, { resolver: tsResolver });
1252
1289
  const queryKeyParamsCall = callPrinter$3.print(queryKeyParamsNode) ?? "";
1253
1290
  const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
@@ -1260,8 +1297,8 @@ function InfiniteQueryOptions({ name, clientName, initialPageParam, cursorParam,
1260
1297
  const hasNewParams = nextParam != null || previousParam != null;
1261
1298
  const [getNextPageParamExpr, getPreviousPageParamExpr] = (() => {
1262
1299
  if (hasNewParams) {
1263
- const nextAccessor = nextParam ? ast.getNestedAccessor(nextParam, "lastPage") : null;
1264
- const prevAccessor = previousParam ? ast.getNestedAccessor(previousParam, "firstPage") : null;
1300
+ const nextAccessor = nextParam ? getNestedAccessor(nextParam, "lastPage") : null;
1301
+ const prevAccessor = previousParam ? getNestedAccessor(previousParam, "firstPage") : null;
1265
1302
  return [nextAccessor ? `getNextPageParam: (lastPage) => ${nextAccessor}` : null, prevAccessor ? `getPreviousPageParam: (firstPage) => ${prevAccessor}` : null];
1266
1303
  }
1267
1304
  if (cursorParam) return [`getNextPageParam: (lastPage) => lastPage['${cursorParam}']`, `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`];
@@ -1330,16 +1367,13 @@ function buildMutationConfigParamsNode(node) {
1330
1367
  })] });
1331
1368
  }
1332
1369
  function MutationOptions({ name, clientName, node, tsResolver, mutationKeyName }) {
1333
- const successNames = resolveSuccessNames(node, tsResolver);
1334
- const TData = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
1335
- const errorNames = resolveErrorNames(node, tsResolver);
1336
- const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1370
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1337
1371
  const configParamsNode = buildMutationConfigParamsNode(node);
1338
1372
  const paramsSignature = declarationPrinter$5.print(configParamsNode) ?? "";
1339
1373
  const groupedParam = buildGroupedRequestParam(node, { resolver: tsResolver });
1340
1374
  const hasMutationParams = groupedParam !== null;
1341
1375
  const groupedParamsNode = createFunctionParameters({ params: groupedParam ? [groupedParam] : [] });
1342
- const TRequest = hasMutationParams ? tsResolver.resolveRequestConfigName(node) : "undefined";
1376
+ const TRequest = hasMutationParams ? tsResolver.response.options(node) : "undefined";
1343
1377
  const argBindingStr = hasMutationParams ? callPrinter$2.print(groupedParamsNode) ?? "" : "_";
1344
1378
  const mutationFnBody = `const { data } = await ${buildClientCall(node, {
1345
1379
  clientName,
@@ -1372,19 +1406,17 @@ function MutationOptions({ name, clientName, node, tsResolver, mutationKeyName }
1372
1406
  const declarationPrinter$4 = functionPrinter({ mode: "declaration" });
1373
1407
  const callPrinter$1 = functionPrinter({ mode: "call" });
1374
1408
  function resolveMutationRequestType(node, resolver) {
1375
- return buildGroupedRequestParam(node, { resolver }) ? resolver.resolveRequestConfigName(node) : "undefined";
1409
+ return buildGroupedRequestParam(node, { resolver }) ? resolver.response.options(node) : "undefined";
1376
1410
  }
1377
1411
  function buildMutationParamsNode(node, options) {
1378
1412
  const { resolver } = options;
1379
- const successNames = resolveSuccessNames(node, resolver);
1380
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.resolveResponseName(node);
1381
- const errorNames = resolveErrorNames(node, resolver);
1413
+ const { TData, TError } = buildResponseTypes(node, resolver);
1382
1414
  return createFunctionParameters({ params: [createFunctionParameter({
1383
1415
  name: "options",
1384
1416
  type: `{
1385
1417
  mutation?: UseMutationOptions<${[
1386
- responseName,
1387
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1418
+ TData,
1419
+ TError,
1388
1420
  resolveMutationRequestType(node, resolver),
1389
1421
  "TContext"
1390
1422
  ].join(", ")}> & { client?: QueryClient },
@@ -1394,12 +1426,10 @@ function buildMutationParamsNode(node, options) {
1394
1426
  })] });
1395
1427
  }
1396
1428
  function Mutation({ name, mutationOptionsName, node, tsResolver, mutationKeyName, customOptions }) {
1397
- const successNames = resolveSuccessNames(node, tsResolver);
1398
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
1399
- const errorNames = resolveErrorNames(node, tsResolver);
1429
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1400
1430
  const generics = [
1401
- responseName,
1402
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1431
+ TData,
1432
+ TError,
1403
1433
  resolveMutationRequestType(node, tsResolver),
1404
1434
  "TContext"
1405
1435
  ].join(", ");
@@ -1439,15 +1469,13 @@ function Mutation({ name, mutationOptionsName, node, tsResolver, mutationKeyName
1439
1469
  const declarationPrinter$3 = functionPrinter({ mode: "declaration" });
1440
1470
  function buildQueryParamsNode(node, options) {
1441
1471
  const { resolver } = options;
1442
- const successNames = resolveSuccessNames(node, resolver);
1443
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.resolveResponseName(node);
1444
- const errorNames = resolveErrorNames(node, resolver);
1472
+ const { TData, TError } = buildResponseTypes(node, resolver);
1445
1473
  const optionsParam = createFunctionParameter({
1446
1474
  name: "options",
1447
1475
  type: `{
1448
1476
  query?: Partial<QueryObserverOptions<${[
1449
- responseName,
1450
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1477
+ TData,
1478
+ TError,
1451
1479
  "TData",
1452
1480
  "TQueryData",
1453
1481
  "TQueryKey"
@@ -1462,11 +1490,8 @@ function buildQueryParamsNode(node, options) {
1462
1490
  }), optionsParam].filter((param) => param !== null) });
1463
1491
  }
1464
1492
  function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, customOptions }) {
1465
- const successNames = resolveSuccessNames(node, tsResolver);
1466
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
1467
- const errorNames = resolveErrorNames(node, tsResolver);
1468
- const TData = responseName;
1469
- const returnType = `UseQueryResult<TData, ${`ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`}> & { queryKey: TQueryKey }`;
1493
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1494
+ const returnType = `UseQueryResult<TData, ${TError}> & { queryKey: TQueryKey }`;
1470
1495
  const generics = [
1471
1496
  `TData = ${TData}`,
1472
1497
  `TQueryData = ${TData}`,
@@ -1525,23 +1550,12 @@ function buildSuspenseInfiniteQueryParamsNode(node, options) {
1525
1550
  }), optionsParam].filter((param) => param !== null) });
1526
1551
  }
1527
1552
  function SuspenseInfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, customOptions, initialPageParam, queryParam }) {
1528
- const successNames = resolveSuccessNames(node, tsResolver);
1529
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
1530
- const errorNames = resolveErrorNames(node, tsResolver);
1531
- const responseType = responseName;
1532
- const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1533
- const isInitialPageParamDefined = initialPageParam !== void 0 && initialPageParam !== null;
1534
- const fallbackPageParamType = typeof initialPageParam === "number" ? "number" : typeof initialPageParam === "string" ? initialPageParam.includes(" as ") ? (() => {
1535
- const parts = initialPageParam.split(" as ");
1536
- return parts[parts.length - 1] ?? "unknown";
1537
- })() : "string" : typeof initialPageParam === "boolean" ? "boolean" : "unknown";
1538
- const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
1539
- const queryParamsTypeName = rawQueryParams.length > 0 ? (() => {
1540
- const groupName = tsResolver.resolveQueryParamsName(node, rawQueryParams[0]);
1541
- return groupName !== tsResolver.resolveParamName(node, rawQueryParams[0]) ? groupName : null;
1542
- })() : null;
1543
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
1544
- const pageParamType = queryParamType ? isInitialPageParamDefined ? `NonNullable<${queryParamType}>` : queryParamType : fallbackPageParamType;
1553
+ const { TData: responseType, TError: errorType } = buildResponseTypes(node, tsResolver);
1554
+ const { pageParamType } = resolvePageParamType(node, {
1555
+ resolver: tsResolver,
1556
+ initialPageParam,
1557
+ queryParam
1558
+ });
1545
1559
  const returnType = "UseSuspenseInfiniteQueryResult<TData, TError> & { queryKey: TQueryKey }";
1546
1560
  const generics = [
1547
1561
  `TQueryFnData = ${responseType}`,
@@ -1592,22 +1606,12 @@ function SuspenseInfiniteQuery({ name, queryKeyTypeName, queryOptionsName, query
1592
1606
  const declarationPrinter$1 = functionPrinter({ mode: "declaration" });
1593
1607
  const callPrinter = functionPrinter({ mode: "call" });
1594
1608
  function SuspenseInfiniteQueryOptions({ name, clientName, initialPageParam, cursorParam, nextParam, previousParam, node, tsResolver, queryParam, queryKeyName }) {
1595
- const successNames = resolveSuccessNames(node, tsResolver);
1596
- const queryFnDataType = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
1597
- const errorNames = resolveErrorNames(node, tsResolver);
1598
- const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1599
- const isInitialPageParamDefined = initialPageParam !== void 0 && initialPageParam !== null;
1600
- const fallbackPageParamType = typeof initialPageParam === "number" ? "number" : typeof initialPageParam === "string" ? initialPageParam.includes(" as ") ? (() => {
1601
- const parts = initialPageParam.split(" as ");
1602
- return parts[parts.length - 1] ?? "unknown";
1603
- })() : "string" : typeof initialPageParam === "boolean" ? "boolean" : "unknown";
1604
- const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
1605
- const queryParamsTypeName = rawQueryParams.length > 0 ? (() => {
1606
- const groupName = tsResolver.resolveQueryParamsName(node, rawQueryParams[0]);
1607
- return groupName !== tsResolver.resolveParamName(node, rawQueryParams[0]) ? groupName : null;
1608
- })() : null;
1609
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
1610
- const pageParamType = queryParamType ? isInitialPageParamDefined ? `NonNullable<${queryParamType}>` : queryParamType : fallbackPageParamType;
1609
+ const { TData: queryFnDataType, TError: errorType } = buildResponseTypes(node, tsResolver);
1610
+ const { queryParamsTypeName, pageParamType } = resolvePageParamType(node, {
1611
+ resolver: tsResolver,
1612
+ initialPageParam,
1613
+ queryParam
1614
+ });
1611
1615
  const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
1612
1616
  const paramsSignature = declarationPrinter$1.print(paramsNode) ?? "";
1613
1617
  const queryFnBody = `const { data } = await ${buildClientCall(node, {
@@ -1620,8 +1624,8 @@ function SuspenseInfiniteQueryOptions({ name, clientName, initialPageParam, curs
1620
1624
  const hasNewParams = nextParam != null || previousParam != null;
1621
1625
  const [getNextPageParamExpr, getPreviousPageParamExpr] = (() => {
1622
1626
  if (hasNewParams) {
1623
- const nextAccessor = nextParam ? ast.getNestedAccessor(nextParam, "lastPage") : null;
1624
- const prevAccessor = previousParam ? ast.getNestedAccessor(previousParam, "firstPage") : null;
1627
+ const nextAccessor = nextParam ? getNestedAccessor(nextParam, "lastPage") : null;
1628
+ const prevAccessor = previousParam ? getNestedAccessor(previousParam, "firstPage") : null;
1625
1629
  return [nextAccessor ? `getNextPageParam: (lastPage) => ${nextAccessor}` : null, prevAccessor ? `getPreviousPageParam: (firstPage) => ${prevAccessor}` : null];
1626
1630
  }
1627
1631
  if (cursorParam) return [`getNextPageParam: (lastPage) => lastPage['${cursorParam}']`, `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`];
@@ -1683,15 +1687,13 @@ return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${que
1683
1687
  const declarationPrinter = functionPrinter({ mode: "declaration" });
1684
1688
  function buildSuspenseQueryParamsNode(node, options) {
1685
1689
  const { resolver } = options;
1686
- const successNames = resolveSuccessNames(node, resolver);
1687
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.resolveResponseName(node);
1688
- const errorNames = resolveErrorNames(node, resolver);
1690
+ const { TData, TError } = buildResponseTypes(node, resolver);
1689
1691
  const optionsParam = createFunctionParameter({
1690
1692
  name: "options",
1691
1693
  type: `{
1692
1694
  query?: Partial<UseSuspenseQueryOptions<${[
1693
- responseName,
1694
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1695
+ TData,
1696
+ TError,
1695
1697
  "TData",
1696
1698
  "TQueryKey"
1697
1699
  ].join(", ")}>> & { client?: QueryClient },
@@ -1705,11 +1707,8 @@ function buildSuspenseQueryParamsNode(node, options) {
1705
1707
  }), optionsParam].filter((param) => param !== null) });
1706
1708
  }
1707
1709
  function SuspenseQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, customOptions }) {
1708
- const successNames = resolveSuccessNames(node, tsResolver);
1709
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
1710
- const errorNames = resolveErrorNames(node, tsResolver);
1711
- const TData = responseName;
1712
- const returnType = `UseSuspenseQueryResult<TData, ${`ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`}> & { queryKey: TQueryKey }`;
1710
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1711
+ const returnType = `UseSuspenseQueryResult<TData, ${TError}> & { queryKey: TQueryKey }`;
1713
1712
  const generics = [`TData = ${TData}`, `TQueryKey extends QueryKey = ${queryKeyTypeName}`];
1714
1713
  const resolvedParams = buildResolvedRequestParams(node);
1715
1714
  const queryKeyArgs = resolvedParams ? "resolvedParams" : "";
@@ -1763,16 +1762,15 @@ const infiniteQueryGenerator = defineGenerator({
1763
1762
  const pluginTs = driver.getPlugin(pluginTsName);
1764
1763
  if (!pluginTs) return null;
1765
1764
  const tsResolver = driver.getResolver(pluginTsName);
1766
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
1767
- const queryMethods = new Set(query ? query.methods : []);
1768
- const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
1765
+ const { isQuery, isMutation } = classifyOperation(node, {
1766
+ query,
1767
+ mutation
1768
+ });
1769
1769
  const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
1770
1770
  if (!isQuery || isMutation || !infiniteOptions) return null;
1771
1771
  const normalizeKey = (key) => key.replace(/\?$/, "");
1772
1772
  const queryParamKeys = getOperationParameters(node, { paramsCasing: "original" }).query.map((p) => p.name);
1773
- const hasQueryParam = infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false;
1774
- const hasCursorParam = !infiniteOptions.cursorParam || true;
1775
- if (!hasQueryParam || !hasCursorParam) return null;
1773
+ if (!(infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false)) return null;
1776
1774
  const importPath = query ? query.importPath : "@tanstack/react-query";
1777
1775
  const contractOp = resolveClientOperation({
1778
1776
  clientPlugin: { pluginName: client.pluginName },
@@ -1782,26 +1780,28 @@ const infiniteQueryGenerator = defineGenerator({
1782
1780
  output
1783
1781
  });
1784
1782
  if (!contractOp) return null;
1785
- const queryName = resolver.resolveInfiniteQueryName(node);
1786
- const queryOptionsName = resolver.resolveInfiniteQueryOptionsName(node);
1787
- const queryKeyName = resolver.resolveInfiniteQueryKeyName(node);
1788
- const queryKeyTypeName = resolver.resolveInfiniteQueryKeyTypeName(node);
1783
+ const queryName = resolver.infiniteQuery.name(node);
1784
+ const queryOptionsName = resolver.infiniteQuery.optionsName(node);
1785
+ const queryKeyName = resolver.infiniteQuery.keyName(node);
1786
+ const queryKeyTypeName = resolver.infiniteQuery.keyTypeName(node);
1789
1787
  const meta = {
1790
- file: resolver.resolveFile(operationFileEntry(node, queryName), {
1788
+ file: resolver.file({
1789
+ ...operationFileEntry(node, queryName),
1791
1790
  root,
1792
1791
  output,
1793
1792
  group: group ?? void 0
1794
1793
  }),
1795
- fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
1794
+ fileTs: tsResolver.file({
1795
+ ...operationFileEntry(node, node.operationId),
1796
1796
  root,
1797
1797
  output: pluginTs.options?.output ?? output,
1798
1798
  group: pluginTs.options?.group ?? void 0
1799
1799
  })
1800
1800
  };
1801
1801
  const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
1802
- const queryParamsTypeName = rawQueryParams.length > 0 && tsResolver.resolveQueryParamsName(node, rawQueryParams[0]) !== tsResolver.resolveParamName(node, rawQueryParams[0]) ? tsResolver.resolveQueryParamsName(node, rawQueryParams[0]) : null;
1802
+ const queryParamsTypeName = rawQueryParams.length > 0 && tsResolver.param.query(node, rawQueryParams[0]) !== tsResolver.param.name(node, rawQueryParams[0]) ? tsResolver.param.query(node, rawQueryParams[0]) : null;
1803
1803
  const importedTypeNames = [
1804
- tsResolver.resolveRequestConfigName(node),
1804
+ tsResolver.response.options(node),
1805
1805
  queryParamsTypeName,
1806
1806
  ...resolveOperationTypeNames(node, tsResolver, {
1807
1807
  exclude: [queryKeyTypeName],
@@ -1814,7 +1814,7 @@ const infiniteQueryGenerator = defineGenerator({
1814
1814
  baseName: meta.file.baseName,
1815
1815
  path: meta.file.path,
1816
1816
  meta: meta.file.meta,
1817
- banner: resolver.resolveBanner(ctx.meta, {
1817
+ banner: resolver.default.banner(ctx.meta, {
1818
1818
  output,
1819
1819
  config,
1820
1820
  file: {
@@ -1822,7 +1822,7 @@ const infiniteQueryGenerator = defineGenerator({
1822
1822
  baseName: meta.file.baseName
1823
1823
  }
1824
1824
  }),
1825
- footer: resolver.resolveFooter(ctx.meta, {
1825
+ footer: resolver.default.footer(ctx.meta, {
1826
1826
  output,
1827
1827
  config,
1828
1828
  file: {
@@ -1928,9 +1928,11 @@ const mutationGenerator = defineGenerator({
1928
1928
  const pluginTs = driver.getPlugin(pluginTsName);
1929
1929
  if (!pluginTs) return null;
1930
1930
  const tsResolver = driver.getResolver(pluginTsName);
1931
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
1932
- const queryMethods = new Set(query ? query.methods : []);
1933
- if (!(mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase()))) return null;
1931
+ const { isMutation } = classifyOperation(node, {
1932
+ query,
1933
+ mutation
1934
+ });
1935
+ if (!isMutation) return null;
1934
1936
  const importPath = mutation ? mutation.importPath : "@tanstack/react-query";
1935
1937
  const contractOp = resolveClientOperation({
1936
1938
  clientPlugin: { pluginName: client.pluginName },
@@ -1940,23 +1942,25 @@ const mutationGenerator = defineGenerator({
1940
1942
  output
1941
1943
  });
1942
1944
  if (!contractOp) return null;
1943
- const mutationHookName = resolver.resolveMutationName(node);
1944
- const mutationTypeName = resolver.resolveMutationTypeName(node);
1945
- const mutationOptionsName = resolver.resolveMutationOptionsName(node);
1946
- const mutationKeyName = resolver.resolveMutationKeyName(node);
1945
+ const mutationHookName = resolver.mutation.name(node);
1946
+ const mutationTypeName = resolver.mutation.typeName(node);
1947
+ const mutationOptionsName = resolver.mutation.optionsName(node);
1948
+ const mutationKeyName = resolver.mutation.keyName(node);
1947
1949
  const meta = {
1948
- file: resolver.resolveFile(operationFileEntry(node, mutationHookName), {
1950
+ file: resolver.file({
1951
+ ...operationFileEntry(node, mutationHookName),
1949
1952
  root,
1950
1953
  output,
1951
1954
  group: group ?? void 0
1952
1955
  }),
1953
- fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
1956
+ fileTs: tsResolver.file({
1957
+ ...operationFileEntry(node, node.operationId),
1954
1958
  root,
1955
1959
  output: pluginTs.options?.output ?? output,
1956
1960
  group: pluginTs.options?.group ?? void 0
1957
1961
  })
1958
1962
  };
1959
- const importedTypeNames = [tsResolver.resolveRequestConfigName(node), ...resolveOperationTypeNames(node, tsResolver, {
1963
+ const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
1960
1964
  order: "body-response-first",
1961
1965
  includeParams: false
1962
1966
  })].filter((name) => Boolean(name));
@@ -1965,7 +1969,7 @@ const mutationGenerator = defineGenerator({
1965
1969
  baseName: meta.file.baseName,
1966
1970
  path: meta.file.path,
1967
1971
  meta: meta.file.meta,
1968
- banner: resolver.resolveBanner(ctx.meta, {
1972
+ banner: resolver.default.banner(ctx.meta, {
1969
1973
  output,
1970
1974
  config,
1971
1975
  file: {
@@ -1973,7 +1977,7 @@ const mutationGenerator = defineGenerator({
1973
1977
  baseName: meta.file.baseName
1974
1978
  }
1975
1979
  }),
1976
- footer: resolver.resolveFooter(ctx.meta, {
1980
+ footer: resolver.default.footer(ctx.meta, {
1977
1981
  output,
1978
1982
  config,
1979
1983
  file: {
@@ -2064,9 +2068,10 @@ const queryGenerator = defineGenerator({
2064
2068
  const pluginTs = driver.getPlugin(pluginTsName);
2065
2069
  if (!pluginTs) return null;
2066
2070
  const tsResolver = driver.getResolver(pluginTsName);
2067
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
2068
- const queryMethods = new Set(query ? query.methods : []);
2069
- const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
2071
+ const { isQuery, isMutation } = classifyOperation(node, {
2072
+ query,
2073
+ mutation
2074
+ });
2070
2075
  if (!isQuery || isMutation) return null;
2071
2076
  const importPath = query ? query.importPath : "@tanstack/react-query";
2072
2077
  const contractOp = resolveClientOperation({
@@ -2077,23 +2082,25 @@ const queryGenerator = defineGenerator({
2077
2082
  output
2078
2083
  });
2079
2084
  if (!contractOp) return null;
2080
- const queryName = resolver.resolveQueryName(node);
2081
- const queryOptionsName = resolver.resolveQueryOptionsName(node);
2082
- const queryKeyName = resolver.resolveQueryKeyName(node);
2083
- const queryKeyTypeName = resolver.resolveQueryKeyTypeName(node);
2085
+ const queryName = resolver.query.name(node);
2086
+ const queryOptionsName = resolver.query.optionsName(node);
2087
+ const queryKeyName = resolver.query.keyName(node);
2088
+ const queryKeyTypeName = resolver.query.keyTypeName(node);
2084
2089
  const meta = {
2085
- file: resolver.resolveFile(operationFileEntry(node, queryName), {
2090
+ file: resolver.file({
2091
+ ...operationFileEntry(node, queryName),
2086
2092
  root,
2087
2093
  output,
2088
2094
  group: group ?? void 0
2089
2095
  }),
2090
- fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
2096
+ fileTs: tsResolver.file({
2097
+ ...operationFileEntry(node, node.operationId),
2091
2098
  root,
2092
2099
  output: pluginTs.options?.output ?? output,
2093
2100
  group: pluginTs.options?.group ?? void 0
2094
2101
  })
2095
2102
  };
2096
- const importedTypeNames = [tsResolver.resolveRequestConfigName(node), ...resolveOperationTypeNames(node, tsResolver, {
2103
+ const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
2097
2104
  exclude: [queryKeyTypeName],
2098
2105
  order: "body-response-first",
2099
2106
  includeParams: false
@@ -2103,7 +2110,7 @@ const queryGenerator = defineGenerator({
2103
2110
  baseName: meta.file.baseName,
2104
2111
  path: meta.file.path,
2105
2112
  meta: meta.file.meta,
2106
- banner: resolver.resolveBanner(ctx.meta, {
2113
+ banner: resolver.default.banner(ctx.meta, {
2107
2114
  output,
2108
2115
  config,
2109
2116
  file: {
@@ -2111,7 +2118,7 @@ const queryGenerator = defineGenerator({
2111
2118
  baseName: meta.file.baseName
2112
2119
  }
2113
2120
  }),
2114
- footer: resolver.resolveFooter(ctx.meta, {
2121
+ footer: resolver.default.footer(ctx.meta, {
2115
2122
  output,
2116
2123
  config,
2117
2124
  file: {
@@ -2206,17 +2213,16 @@ const suspenseInfiniteQueryGenerator = defineGenerator({
2206
2213
  const pluginTs = driver.getPlugin(pluginTsName);
2207
2214
  if (!pluginTs) return null;
2208
2215
  const tsResolver = driver.getResolver(pluginTsName);
2209
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
2210
- const queryMethods = new Set(query ? query.methods : []);
2211
- const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
2216
+ const { isQuery, isMutation } = classifyOperation(node, {
2217
+ query,
2218
+ mutation
2219
+ });
2212
2220
  const isSuspense = !!suspense;
2213
2221
  const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
2214
2222
  if (!isQuery || isMutation || !isSuspense || !infiniteOptions) return null;
2215
2223
  const normalizeKey = (key) => key.replace(/\?$/, "");
2216
2224
  const queryParamKeys = getOperationParameters(node, { paramsCasing: "original" }).query.map((p) => p.name);
2217
- const hasQueryParam = infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false;
2218
- const hasCursorParam = !infiniteOptions.cursorParam || true;
2219
- if (!hasQueryParam || !hasCursorParam) return null;
2225
+ if (!(infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false)) return null;
2220
2226
  const importPath = query ? query.importPath : "@tanstack/react-query";
2221
2227
  const contractOp = resolveClientOperation({
2222
2228
  clientPlugin: { pluginName: client.pluginName },
@@ -2226,26 +2232,28 @@ const suspenseInfiniteQueryGenerator = defineGenerator({
2226
2232
  output
2227
2233
  });
2228
2234
  if (!contractOp) return null;
2229
- const queryName = resolver.resolveSuspenseInfiniteQueryName(node);
2230
- const queryOptionsName = resolver.resolveSuspenseInfiniteQueryOptionsName(node);
2231
- const queryKeyName = resolver.resolveSuspenseInfiniteQueryKeyName(node);
2232
- const queryKeyTypeName = resolver.resolveSuspenseInfiniteQueryKeyTypeName(node);
2235
+ const queryName = resolver.suspenseInfiniteQuery.name(node);
2236
+ const queryOptionsName = resolver.suspenseInfiniteQuery.optionsName(node);
2237
+ const queryKeyName = resolver.suspenseInfiniteQuery.keyName(node);
2238
+ const queryKeyTypeName = resolver.suspenseInfiniteQuery.keyTypeName(node);
2233
2239
  const meta = {
2234
- file: resolver.resolveFile(operationFileEntry(node, queryName), {
2240
+ file: resolver.file({
2241
+ ...operationFileEntry(node, queryName),
2235
2242
  root,
2236
2243
  output,
2237
2244
  group: group ?? void 0
2238
2245
  }),
2239
- fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
2246
+ fileTs: tsResolver.file({
2247
+ ...operationFileEntry(node, node.operationId),
2240
2248
  root,
2241
2249
  output: pluginTs.options?.output ?? output,
2242
2250
  group: pluginTs.options?.group ?? void 0
2243
2251
  })
2244
2252
  };
2245
2253
  const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
2246
- const queryParamsTypeName = rawQueryParams.length > 0 && tsResolver.resolveQueryParamsName(node, rawQueryParams[0]) !== tsResolver.resolveParamName(node, rawQueryParams[0]) ? tsResolver.resolveQueryParamsName(node, rawQueryParams[0]) : null;
2254
+ const queryParamsTypeName = rawQueryParams.length > 0 && tsResolver.param.query(node, rawQueryParams[0]) !== tsResolver.param.name(node, rawQueryParams[0]) ? tsResolver.param.query(node, rawQueryParams[0]) : null;
2247
2255
  const importedTypeNames = [
2248
- tsResolver.resolveRequestConfigName(node),
2256
+ tsResolver.response.options(node),
2249
2257
  queryParamsTypeName,
2250
2258
  ...resolveOperationTypeNames(node, tsResolver, {
2251
2259
  order: "body-response-first",
@@ -2257,7 +2265,7 @@ const suspenseInfiniteQueryGenerator = defineGenerator({
2257
2265
  baseName: meta.file.baseName,
2258
2266
  path: meta.file.path,
2259
2267
  meta: meta.file.meta,
2260
- banner: resolver.resolveBanner(ctx.meta, {
2268
+ banner: resolver.default.banner(ctx.meta, {
2261
2269
  output,
2262
2270
  config,
2263
2271
  file: {
@@ -2265,7 +2273,7 @@ const suspenseInfiniteQueryGenerator = defineGenerator({
2265
2273
  baseName: meta.file.baseName
2266
2274
  }
2267
2275
  }),
2268
- footer: resolver.resolveFooter(ctx.meta, {
2276
+ footer: resolver.default.footer(ctx.meta, {
2269
2277
  output,
2270
2278
  config,
2271
2279
  file: {
@@ -2372,9 +2380,10 @@ const suspenseQueryGenerator = defineGenerator({
2372
2380
  const pluginTs = driver.getPlugin(pluginTsName);
2373
2381
  if (!pluginTs) return null;
2374
2382
  const tsResolver = driver.getResolver(pluginTsName);
2375
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
2376
- const queryMethods = new Set(query ? query.methods : []);
2377
- const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
2383
+ const { isQuery, isMutation } = classifyOperation(node, {
2384
+ query,
2385
+ mutation
2386
+ });
2378
2387
  if (!isQuery || isMutation || !!!suspense) return null;
2379
2388
  const importPath = query ? query.importPath : "@tanstack/react-query";
2380
2389
  const contractOp = resolveClientOperation({
@@ -2385,23 +2394,25 @@ const suspenseQueryGenerator = defineGenerator({
2385
2394
  output
2386
2395
  });
2387
2396
  if (!contractOp) return null;
2388
- const queryName = resolver.resolveSuspenseQueryName(node);
2389
- const queryOptionsName = resolver.resolveSuspenseQueryOptionsName(node);
2390
- const queryKeyName = resolver.resolveSuspenseQueryKeyName(node);
2391
- const queryKeyTypeName = resolver.resolveSuspenseQueryKeyTypeName(node);
2397
+ const queryName = resolver.suspenseQuery.name(node);
2398
+ const queryOptionsName = resolver.suspenseQuery.optionsName(node);
2399
+ const queryKeyName = resolver.suspenseQuery.keyName(node);
2400
+ const queryKeyTypeName = resolver.suspenseQuery.keyTypeName(node);
2392
2401
  const meta = {
2393
- file: resolver.resolveFile(operationFileEntry(node, queryName), {
2402
+ file: resolver.file({
2403
+ ...operationFileEntry(node, queryName),
2394
2404
  root,
2395
2405
  output,
2396
2406
  group: group ?? void 0
2397
2407
  }),
2398
- fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
2408
+ fileTs: tsResolver.file({
2409
+ ...operationFileEntry(node, node.operationId),
2399
2410
  root,
2400
2411
  output: pluginTs.options?.output ?? output,
2401
2412
  group: pluginTs.options?.group ?? void 0
2402
2413
  })
2403
2414
  };
2404
- const importedTypeNames = [tsResolver.resolveRequestConfigName(node), ...resolveOperationTypeNames(node, tsResolver, {
2415
+ const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
2405
2416
  exclude: [queryKeyTypeName],
2406
2417
  order: "body-response-first",
2407
2418
  includeParams: false
@@ -2411,7 +2422,7 @@ const suspenseQueryGenerator = defineGenerator({
2411
2422
  baseName: meta.file.baseName,
2412
2423
  path: meta.file.path,
2413
2424
  meta: meta.file.meta,
2414
- banner: resolver.resolveBanner(ctx.meta, {
2425
+ banner: resolver.default.banner(ctx.meta, {
2415
2426
  output,
2416
2427
  config,
2417
2428
  file: {
@@ -2419,7 +2430,7 @@ const suspenseQueryGenerator = defineGenerator({
2419
2430
  baseName: meta.file.baseName
2420
2431
  }
2421
2432
  }),
2422
- footer: resolver.resolveFooter(ctx.meta, {
2433
+ footer: resolver.default.footer(ctx.meta, {
2423
2434
  output,
2424
2435
  config,
2425
2436
  file: {
@@ -2507,110 +2518,112 @@ function capitalize(name) {
2507
2518
  * `useFooSuspense`, `useFooInfinite`, ...) and its companion helpers
2508
2519
  * (`fooQueryKey`, `fooQueryOptions`).
2509
2520
  *
2510
- * Functions and files use camelCase; hooks get the `use` prefix; suspense and
2511
- * infinite variants are suffixed with `Suspense`/`Infinite`.
2521
+ * Functions and files use the built-in camelCase casing; hooks get the `use`
2522
+ * prefix; suspense and infinite variants are suffixed with `Suspense`/`Infinite`.
2512
2523
  *
2513
2524
  * @example Resolve hook and helper names
2514
2525
  * ```ts
2515
2526
  * import { resolverReactQuery } from '@kubb/plugin-react-query'
2516
2527
  *
2517
- * resolverReactQuery.resolveQueryName(operationNode) // 'useGetPetById'
2518
- * resolverReactQuery.resolveMutationName(operationNode) // 'useUpdatePet'
2519
- * resolverReactQuery.resolveQueryKeyName(operationNode) // 'getPetByIdQueryKey'
2520
- * resolverReactQuery.resolveQueryOptionsName(operationNode) // 'getPetByIdQueryOptions'
2528
+ * resolverReactQuery.query.name(operationNode) // 'useGetPetById'
2529
+ * resolverReactQuery.mutation.name(operationNode) // 'useUpdatePet'
2530
+ * resolverReactQuery.query.keyName(operationNode) // 'getPetByIdQueryKey'
2531
+ * resolverReactQuery.query.optionsName(operationNode) // 'getPetByIdQueryOptions'
2521
2532
  * ```
2522
2533
  */
2523
- const resolverReactQuery = defineResolver(() => ({
2524
- name: "default",
2534
+ const resolverReactQuery = createResolver({
2525
2535
  pluginName: "plugin-react-query",
2526
- default(name, type) {
2527
- return type === "file" ? toFilePath(name) : camelCase(name);
2528
- },
2529
- resolveName(name) {
2530
- return this.default(name, "function");
2531
- },
2532
- resolvePathName(name, type) {
2533
- return this.default(name, type);
2534
- },
2535
- resolveQueryName(node) {
2536
- return `use${capitalize(this.resolveName(node.operationId))}`;
2537
- },
2538
- resolveSuspenseQueryName(node) {
2539
- return `use${capitalize(this.resolveName(node.operationId))}Suspense`;
2540
- },
2541
- resolveInfiniteQueryName(node) {
2542
- return `use${capitalize(this.resolveName(node.operationId))}Infinite`;
2543
- },
2544
- resolveSuspenseInfiniteQueryName(node) {
2545
- return `use${capitalize(this.resolveName(node.operationId))}SuspenseInfinite`;
2546
- },
2547
- resolveMutationName(node) {
2548
- return `use${capitalize(this.resolveName(node.operationId))}`;
2549
- },
2550
- resolveQueryOptionsName(node) {
2551
- return `${this.resolveName(node.operationId)}QueryOptions`;
2552
- },
2553
- resolveSuspenseQueryOptionsName(node) {
2554
- return `${this.resolveName(node.operationId)}SuspenseQueryOptions`;
2555
- },
2556
- resolveInfiniteQueryOptionsName(node) {
2557
- return `${this.resolveName(node.operationId)}InfiniteQueryOptions`;
2558
- },
2559
- resolveSuspenseInfiniteQueryOptionsName(node) {
2560
- return `${this.resolveName(node.operationId)}SuspenseInfiniteQueryOptions`;
2561
- },
2562
- resolveMutationOptionsName(node) {
2563
- return `${this.resolveName(node.operationId)}MutationOptions`;
2564
- },
2565
- resolveQueryKeyName(node) {
2566
- return `${this.resolveName(node.operationId)}QueryKey`;
2567
- },
2568
- resolveSuspenseQueryKeyName(node) {
2569
- return `${this.resolveName(node.operationId)}SuspenseQueryKey`;
2570
- },
2571
- resolveInfiniteQueryKeyName(node) {
2572
- return `${this.resolveName(node.operationId)}InfiniteQueryKey`;
2573
- },
2574
- resolveSuspenseInfiniteQueryKeyName(node) {
2575
- return `${this.resolveName(node.operationId)}SuspenseInfiniteQueryKey`;
2576
- },
2577
- resolveMutationKeyName(node) {
2578
- return `${this.resolveName(node.operationId)}MutationKey`;
2579
- },
2580
- resolveQueryKeyTypeName(node) {
2581
- return `${capitalize(this.resolveName(node.operationId))}QueryKey`;
2582
- },
2583
- resolveSuspenseQueryKeyTypeName(node) {
2584
- return `${capitalize(this.resolveName(node.operationId))}SuspenseQueryKey`;
2585
- },
2586
- resolveInfiniteQueryKeyTypeName(node) {
2587
- return `${capitalize(this.resolveName(node.operationId))}InfiniteQueryKey`;
2588
- },
2589
- resolveSuspenseInfiniteQueryKeyTypeName(node) {
2590
- return `${capitalize(this.resolveName(node.operationId))}SuspenseInfiniteQueryKey`;
2591
- },
2592
- resolveMutationTypeName(node) {
2593
- return capitalize(this.resolveName(node.operationId));
2594
- },
2595
- resolveClientName(node) {
2596
- return this.resolveName(node.operationId);
2536
+ query: {
2537
+ name(node) {
2538
+ return `use${capitalize(this.name(node.operationId))}`;
2539
+ },
2540
+ optionsName(node) {
2541
+ return `${this.name(node.operationId)}QueryOptions`;
2542
+ },
2543
+ keyName(node) {
2544
+ return `${this.name(node.operationId)}QueryKey`;
2545
+ },
2546
+ keyTypeName(node) {
2547
+ return `${capitalize(this.name(node.operationId))}QueryKey`;
2548
+ },
2549
+ clientName(node) {
2550
+ return this.name(node.operationId);
2551
+ }
2597
2552
  },
2598
- resolveSuspenseClientName(node) {
2599
- return `${this.resolveName(node.operationId)}Suspense`;
2553
+ suspenseQuery: {
2554
+ name(node) {
2555
+ return `use${capitalize(this.name(node.operationId))}Suspense`;
2556
+ },
2557
+ optionsName(node) {
2558
+ return `${this.name(node.operationId)}SuspenseQueryOptions`;
2559
+ },
2560
+ keyName(node) {
2561
+ return `${this.name(node.operationId)}SuspenseQueryKey`;
2562
+ },
2563
+ keyTypeName(node) {
2564
+ return `${capitalize(this.name(node.operationId))}SuspenseQueryKey`;
2565
+ },
2566
+ clientName(node) {
2567
+ return `${this.name(node.operationId)}Suspense`;
2568
+ }
2600
2569
  },
2601
- resolveInfiniteClientName(node) {
2602
- return `${this.resolveName(node.operationId)}Infinite`;
2570
+ infiniteQuery: {
2571
+ name(node) {
2572
+ return `use${capitalize(this.name(node.operationId))}Infinite`;
2573
+ },
2574
+ optionsName(node) {
2575
+ return `${this.name(node.operationId)}InfiniteQueryOptions`;
2576
+ },
2577
+ keyName(node) {
2578
+ return `${this.name(node.operationId)}InfiniteQueryKey`;
2579
+ },
2580
+ keyTypeName(node) {
2581
+ return `${capitalize(this.name(node.operationId))}InfiniteQueryKey`;
2582
+ },
2583
+ clientName(node) {
2584
+ return `${this.name(node.operationId)}Infinite`;
2585
+ }
2603
2586
  },
2604
- resolveSuspenseInfiniteClientName(node) {
2605
- return `${this.resolveName(node.operationId)}SuspenseInfinite`;
2587
+ suspenseInfiniteQuery: {
2588
+ name(node) {
2589
+ return `use${capitalize(this.name(node.operationId))}SuspenseInfinite`;
2590
+ },
2591
+ optionsName(node) {
2592
+ return `${this.name(node.operationId)}SuspenseInfiniteQueryOptions`;
2593
+ },
2594
+ keyName(node) {
2595
+ return `${this.name(node.operationId)}SuspenseInfiniteQueryKey`;
2596
+ },
2597
+ keyTypeName(node) {
2598
+ return `${capitalize(this.name(node.operationId))}SuspenseInfiniteQueryKey`;
2599
+ },
2600
+ clientName(node) {
2601
+ return `${this.name(node.operationId)}SuspenseInfinite`;
2602
+ }
2606
2603
  },
2607
- resolveHookOptionsName() {
2608
- return "HookOptions";
2604
+ mutation: {
2605
+ name(node) {
2606
+ return `use${capitalize(this.name(node.operationId))}`;
2607
+ },
2608
+ optionsName(node) {
2609
+ return `${this.name(node.operationId)}MutationOptions`;
2610
+ },
2611
+ keyName(node) {
2612
+ return `${this.name(node.operationId)}MutationKey`;
2613
+ },
2614
+ typeName(node) {
2615
+ return capitalize(this.name(node.operationId));
2616
+ }
2609
2617
  },
2610
- resolveCustomHookOptionsName() {
2611
- return "getCustomHookOptions";
2618
+ hook: {
2619
+ optionsName() {
2620
+ return "HookOptions";
2621
+ },
2622
+ customOptionsName() {
2623
+ return "getCustomHookOptions";
2624
+ }
2612
2625
  }
2613
- }));
2626
+ });
2614
2627
  //#endregion
2615
2628
  //#region src/plugin.ts
2616
2629
  /**
@@ -2656,17 +2669,14 @@ const pluginReactQuery = definePlugin((options) => {
2656
2669
  mutationGenerator,
2657
2670
  hookOptionsGenerator,
2658
2671
  customHookOptionsFileGenerator
2659
- ].filter((generator) => Boolean(generator));
2672
+ ];
2660
2673
  const groupConfig = createGroupConfig(group);
2661
2674
  return {
2662
2675
  name: pluginReactQueryName,
2663
2676
  options,
2664
2677
  dependencies: [pluginTsName],
2665
2678
  hooks: { "kubb:plugin:setup"(ctx) {
2666
- const resolver = userResolver ? {
2667
- ...resolverReactQuery,
2668
- ...userResolver
2669
- } : resolverReactQuery;
2679
+ const resolver = userResolver ? Resolver.merge(resolverReactQuery, userResolver) : resolverReactQuery;
2670
2680
  const resolvedClient = resolveClient({
2671
2681
  client,
2672
2682
  pluginNames: (ctx.config.plugins ?? []).map((p) => p.name).filter((name) => Boolean(name))