@kubb/plugin-react-query 5.0.0-beta.86 → 5.0.0-beta.94

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
@@ -159,6 +159,22 @@ const reservedWords = /* @__PURE__ */ new Set([
159
159
  */
160
160
  function isValidVarName(name) {
161
161
  if (!name || reservedWords.has(name)) return false;
162
+ return isIdentifier(name);
163
+ }
164
+ /**
165
+ * Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
166
+ *
167
+ * Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
168
+ * even though they are not valid variable names, so use this (not {@link isValidVarName}) when
169
+ * deciding whether an object key needs quoting.
170
+ *
171
+ * @example
172
+ * ```ts
173
+ * isIdentifier('name') // true
174
+ * isIdentifier('x-total')// false
175
+ * ```
176
+ */
177
+ function isIdentifier(name) {
162
178
  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
163
179
  }
164
180
  //#endregion
@@ -354,8 +370,11 @@ function getOperationLink(node, link) {
354
370
  if (link === "urlPath") return node.path ? `{@link ${Url.toPath(node.path)}}` : null;
355
371
  return node.path ? `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}` : null;
356
372
  }
357
- function getContentTypeInfo(node) {
358
- const contentTypes = node.requestBody?.content?.map((e) => e.contentType) ?? [];
373
+ /**
374
+ * Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several
375
+ * are present and the union, default, and form-data flags the client uses to pick one.
376
+ */
377
+ function buildContentTypeInfo(contentTypes) {
359
378
  const isMultipleContentTypes = contentTypes.length > 1;
360
379
  return {
361
380
  contentTypes,
@@ -365,20 +384,15 @@ function getContentTypeInfo(node) {
365
384
  hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
366
385
  };
367
386
  }
387
+ function getContentTypeInfo(node) {
388
+ return buildContentTypeInfo(node.requestBody?.content?.map((e) => e.contentType) ?? []);
389
+ }
368
390
  /**
369
391
  * The request-body counterpart for the primary success response: the content types it documents and
370
392
  * whether several are present, so the client can let a caller pick which one to accept.
371
393
  */
372
394
  function getResponseContentTypeInfo(node) {
373
- const contentTypes = getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? [];
374
- const isMultipleContentTypes = contentTypes.length > 1;
375
- return {
376
- contentTypes,
377
- isMultipleContentTypes,
378
- contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(" | ") : "",
379
- defaultContentType: contentTypes[0] ?? "application/json",
380
- hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
381
- };
395
+ return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? []);
382
396
  }
383
397
  function buildRequestConfigType(node) {
384
398
  const request = getContentTypeInfo(node);
@@ -965,6 +979,59 @@ function buildResolvedRequestParams(node) {
965
979
  if (names.length === 0) return null;
966
980
  return `{ ${names.map((name) => `${name}: typeof ${name} === 'function' ? ${name}() : ${name}`).join(", ")} }`;
967
981
  }
982
+ /**
983
+ * Classifies an operation as a query or a mutation from the resolved `query` / `mutation` method lists.
984
+ * `query: false` still marks the operation as a query so the query-family generators keep matching it,
985
+ * and a method already claimed by `query` never counts as a mutation.
986
+ */
987
+ function classifyOperation(node, { query, mutation }) {
988
+ const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
989
+ const queryMethods = new Set(query ? query.methods : []);
990
+ return {
991
+ isQuery,
992
+ isMutation: mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase())
993
+ };
994
+ }
995
+ /**
996
+ * Builds the `TData` / `TError` type expressions shared by every generated hook, joining the resolved
997
+ * success responses into `TData` and wrapping the error responses in `ResponseErrorConfig<...>`.
998
+ */
999
+ function buildResponseTypes(node, resolver) {
1000
+ const successNames = resolveSuccessNames(node, resolver);
1001
+ const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
1002
+ const errorNames = resolveErrorNames(node, resolver);
1003
+ return {
1004
+ TData: responseName,
1005
+ TError: `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`
1006
+ };
1007
+ }
1008
+ function resolveFallbackPageParamType(initialPageParam) {
1009
+ if (typeof initialPageParam === "number") return "number";
1010
+ if (typeof initialPageParam === "boolean") return "boolean";
1011
+ if (typeof initialPageParam !== "string") return "unknown";
1012
+ if (!initialPageParam.includes(" as ")) return "string";
1013
+ return initialPageParam.split(" as ").at(-1) ?? "unknown";
1014
+ }
1015
+ /**
1016
+ * Resolves the `TPageParam` generic for the infinite-query hooks. Prefers the type read from the
1017
+ * configured `queryParam` on the operation's query object, and falls back to the type inferred from
1018
+ * `initialPageParam` when that parameter type is unavailable. Also returns the query params type name
1019
+ * so callers can reuse it when rewriting the paginated request.
1020
+ */
1021
+ function resolvePageParamType(node, { resolver, initialPageParam, queryParam }) {
1022
+ const firstQueryParam = getOperationParameters(node, { paramsCasing: "original" }).query[0];
1023
+ const groupName = firstQueryParam ? resolver.param.query(node, firstQueryParam) : null;
1024
+ const queryParamsTypeName = groupName !== (firstQueryParam ? resolver.param.name(node, firstQueryParam) : null) ? groupName : null;
1025
+ const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
1026
+ if (!queryParamType) return {
1027
+ queryParamsTypeName,
1028
+ pageParamType: resolveFallbackPageParamType(initialPageParam)
1029
+ };
1030
+ return {
1031
+ queryParamsTypeName,
1032
+ pageParamType: initialPageParam !== void 0 && initialPageParam !== null ? `NonNullable<${queryParamType}>` : queryParamType
1033
+ };
1034
+ }
968
1035
  //#endregion
969
1036
  //#region src/generators/hookOptionsGenerator.tsx
970
1037
  /**
@@ -1145,23 +1212,12 @@ function buildInfiniteQueryParamsNode(node, options) {
1145
1212
  }), optionsParam].filter((param) => param !== null) });
1146
1213
  }
1147
1214
  function InfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, initialPageParam, queryParam, customOptions }) {
1148
- const successNames = resolveSuccessNames(node, tsResolver);
1149
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1150
- const errorNames = resolveErrorNames(node, tsResolver);
1151
- const responseType = responseName;
1152
- const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1153
- const isInitialPageParamDefined = initialPageParam !== void 0 && initialPageParam !== null;
1154
- const fallbackPageParamType = typeof initialPageParam === "number" ? "number" : typeof initialPageParam === "string" ? initialPageParam.includes(" as ") ? (() => {
1155
- const parts = initialPageParam.split(" as ");
1156
- return parts[parts.length - 1] ?? "unknown";
1157
- })() : "string" : typeof initialPageParam === "boolean" ? "boolean" : "unknown";
1158
- const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
1159
- const queryParamsTypeName = rawQueryParams.length > 0 ? (() => {
1160
- const groupName = tsResolver.param.query(node, rawQueryParams[0]);
1161
- return groupName !== tsResolver.param.name(node, rawQueryParams[0]) ? groupName : null;
1162
- })() : null;
1163
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
1164
- const pageParamType = queryParamType ? isInitialPageParamDefined ? `NonNullable<${queryParamType}>` : queryParamType : fallbackPageParamType;
1215
+ const { TData: responseType, TError: errorType } = buildResponseTypes(node, tsResolver);
1216
+ const { pageParamType } = resolvePageParamType(node, {
1217
+ resolver: tsResolver,
1218
+ initialPageParam,
1219
+ queryParam
1220
+ });
1165
1221
  const returnType = "UseInfiniteQueryResult<TData, TError> & { queryKey: TQueryKey }";
1166
1222
  const generics = [
1167
1223
  `TQueryFnData = ${responseType}`,
@@ -1215,11 +1271,7 @@ function getQueryOptionsParams(node, options) {
1215
1271
  return buildQueryOptionsParams(node, options);
1216
1272
  }
1217
1273
  function QueryOptions({ name, clientName, node, tsResolver, queryKeyName }) {
1218
- const successNames = resolveSuccessNames(node, tsResolver);
1219
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1220
- const errorNames = resolveErrorNames(node, tsResolver);
1221
- const TData = responseName;
1222
- const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1274
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1223
1275
  const queryKeyParamsNode = buildQueryKeyParams(node, { resolver: tsResolver });
1224
1276
  const queryKeyParamsCall = callPrinter$4.print(queryKeyParamsNode) ?? "";
1225
1277
  const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
@@ -1254,22 +1306,12 @@ function QueryOptions({ name, clientName, node, tsResolver, queryKeyName }) {
1254
1306
  const declarationPrinter$6 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1255
1307
  const callPrinter$3 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
1256
1308
  function InfiniteQueryOptions({ name, clientName, initialPageParam, cursorParam, nextParam, previousParam, node, tsResolver, queryParam, queryKeyName }) {
1257
- const successNames = resolveSuccessNames(node, tsResolver);
1258
- const queryFnDataType = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1259
- const errorNames = resolveErrorNames(node, tsResolver);
1260
- const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1261
- const isInitialPageParamDefined = initialPageParam !== void 0 && initialPageParam !== null;
1262
- const fallbackPageParamType = typeof initialPageParam === "number" ? "number" : typeof initialPageParam === "string" ? initialPageParam.includes(" as ") ? (() => {
1263
- const parts = initialPageParam.split(" as ");
1264
- return parts[parts.length - 1] ?? "unknown";
1265
- })() : "string" : typeof initialPageParam === "boolean" ? "boolean" : "unknown";
1266
- const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
1267
- const queryParamsTypeName = rawQueryParams.length > 0 ? (() => {
1268
- const groupName = tsResolver.param.query(node, rawQueryParams[0]);
1269
- return groupName !== tsResolver.param.name(node, rawQueryParams[0]) ? groupName : null;
1270
- })() : null;
1271
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
1272
- const pageParamType = queryParamType ? isInitialPageParamDefined ? `NonNullable<${queryParamType}>` : queryParamType : fallbackPageParamType;
1309
+ const { TData: queryFnDataType, TError: errorType } = buildResponseTypes(node, tsResolver);
1310
+ const { queryParamsTypeName, pageParamType } = resolvePageParamType(node, {
1311
+ resolver: tsResolver,
1312
+ initialPageParam,
1313
+ queryParam
1314
+ });
1273
1315
  const queryKeyParamsNode = buildQueryKeyParams(node, { resolver: tsResolver });
1274
1316
  const queryKeyParamsCall = callPrinter$3.print(queryKeyParamsNode) ?? "";
1275
1317
  const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
@@ -1352,10 +1394,7 @@ function buildMutationConfigParamsNode(node) {
1352
1394
  })] });
1353
1395
  }
1354
1396
  function MutationOptions({ name, clientName, node, tsResolver, mutationKeyName }) {
1355
- const successNames = resolveSuccessNames(node, tsResolver);
1356
- const TData = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1357
- const errorNames = resolveErrorNames(node, tsResolver);
1358
- const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1397
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1359
1398
  const configParamsNode = buildMutationConfigParamsNode(node);
1360
1399
  const paramsSignature = declarationPrinter$5.print(configParamsNode) ?? "";
1361
1400
  const groupedParam = buildGroupedRequestParam(node, { resolver: tsResolver });
@@ -1398,15 +1437,13 @@ function resolveMutationRequestType(node, resolver) {
1398
1437
  }
1399
1438
  function buildMutationParamsNode(node, options) {
1400
1439
  const { resolver } = options;
1401
- const successNames = resolveSuccessNames(node, resolver);
1402
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
1403
- const errorNames = resolveErrorNames(node, resolver);
1440
+ const { TData, TError } = buildResponseTypes(node, resolver);
1404
1441
  return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
1405
1442
  name: "options",
1406
1443
  type: `{
1407
1444
  mutation?: UseMutationOptions<${[
1408
- responseName,
1409
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1445
+ TData,
1446
+ TError,
1410
1447
  resolveMutationRequestType(node, resolver),
1411
1448
  "TContext"
1412
1449
  ].join(", ")}> & { client?: QueryClient },
@@ -1416,12 +1453,10 @@ function buildMutationParamsNode(node, options) {
1416
1453
  })] });
1417
1454
  }
1418
1455
  function Mutation({ name, mutationOptionsName, node, tsResolver, mutationKeyName, customOptions }) {
1419
- const successNames = resolveSuccessNames(node, tsResolver);
1420
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1421
- const errorNames = resolveErrorNames(node, tsResolver);
1456
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1422
1457
  const generics = [
1423
- responseName,
1424
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1458
+ TData,
1459
+ TError,
1425
1460
  resolveMutationRequestType(node, tsResolver),
1426
1461
  "TContext"
1427
1462
  ].join(", ");
@@ -1461,15 +1496,13 @@ function Mutation({ name, mutationOptionsName, node, tsResolver, mutationKeyName
1461
1496
  const declarationPrinter$3 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1462
1497
  function buildQueryParamsNode(node, options) {
1463
1498
  const { resolver } = options;
1464
- const successNames = resolveSuccessNames(node, resolver);
1465
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
1466
- const errorNames = resolveErrorNames(node, resolver);
1499
+ const { TData, TError } = buildResponseTypes(node, resolver);
1467
1500
  const optionsParam = (0, _kubb_plugin_ts.createFunctionParameter)({
1468
1501
  name: "options",
1469
1502
  type: `{
1470
1503
  query?: Partial<QueryObserverOptions<${[
1471
- responseName,
1472
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1504
+ TData,
1505
+ TError,
1473
1506
  "TData",
1474
1507
  "TQueryData",
1475
1508
  "TQueryKey"
@@ -1484,11 +1517,8 @@ function buildQueryParamsNode(node, options) {
1484
1517
  }), optionsParam].filter((param) => param !== null) });
1485
1518
  }
1486
1519
  function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, customOptions }) {
1487
- const successNames = resolveSuccessNames(node, tsResolver);
1488
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1489
- const errorNames = resolveErrorNames(node, tsResolver);
1490
- const TData = responseName;
1491
- const returnType = `UseQueryResult<TData, ${`ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`}> & { queryKey: TQueryKey }`;
1520
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1521
+ const returnType = `UseQueryResult<TData, ${TError}> & { queryKey: TQueryKey }`;
1492
1522
  const generics = [
1493
1523
  `TData = ${TData}`,
1494
1524
  `TQueryData = ${TData}`,
@@ -1547,23 +1577,12 @@ function buildSuspenseInfiniteQueryParamsNode(node, options) {
1547
1577
  }), optionsParam].filter((param) => param !== null) });
1548
1578
  }
1549
1579
  function SuspenseInfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, customOptions, initialPageParam, queryParam }) {
1550
- const successNames = resolveSuccessNames(node, tsResolver);
1551
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1552
- const errorNames = resolveErrorNames(node, tsResolver);
1553
- const responseType = responseName;
1554
- const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1555
- const isInitialPageParamDefined = initialPageParam !== void 0 && initialPageParam !== null;
1556
- const fallbackPageParamType = typeof initialPageParam === "number" ? "number" : typeof initialPageParam === "string" ? initialPageParam.includes(" as ") ? (() => {
1557
- const parts = initialPageParam.split(" as ");
1558
- return parts[parts.length - 1] ?? "unknown";
1559
- })() : "string" : typeof initialPageParam === "boolean" ? "boolean" : "unknown";
1560
- const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
1561
- const queryParamsTypeName = rawQueryParams.length > 0 ? (() => {
1562
- const groupName = tsResolver.param.query(node, rawQueryParams[0]);
1563
- return groupName !== tsResolver.param.name(node, rawQueryParams[0]) ? groupName : null;
1564
- })() : null;
1565
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
1566
- const pageParamType = queryParamType ? isInitialPageParamDefined ? `NonNullable<${queryParamType}>` : queryParamType : fallbackPageParamType;
1580
+ const { TData: responseType, TError: errorType } = buildResponseTypes(node, tsResolver);
1581
+ const { pageParamType } = resolvePageParamType(node, {
1582
+ resolver: tsResolver,
1583
+ initialPageParam,
1584
+ queryParam
1585
+ });
1567
1586
  const returnType = "UseSuspenseInfiniteQueryResult<TData, TError> & { queryKey: TQueryKey }";
1568
1587
  const generics = [
1569
1588
  `TQueryFnData = ${responseType}`,
@@ -1614,22 +1633,12 @@ function SuspenseInfiniteQuery({ name, queryKeyTypeName, queryOptionsName, query
1614
1633
  const declarationPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1615
1634
  const callPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
1616
1635
  function SuspenseInfiniteQueryOptions({ name, clientName, initialPageParam, cursorParam, nextParam, previousParam, node, tsResolver, queryParam, queryKeyName }) {
1617
- const successNames = resolveSuccessNames(node, tsResolver);
1618
- const queryFnDataType = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1619
- const errorNames = resolveErrorNames(node, tsResolver);
1620
- const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1621
- const isInitialPageParamDefined = initialPageParam !== void 0 && initialPageParam !== null;
1622
- const fallbackPageParamType = typeof initialPageParam === "number" ? "number" : typeof initialPageParam === "string" ? initialPageParam.includes(" as ") ? (() => {
1623
- const parts = initialPageParam.split(" as ");
1624
- return parts[parts.length - 1] ?? "unknown";
1625
- })() : "string" : typeof initialPageParam === "boolean" ? "boolean" : "unknown";
1626
- const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
1627
- const queryParamsTypeName = rawQueryParams.length > 0 ? (() => {
1628
- const groupName = tsResolver.param.query(node, rawQueryParams[0]);
1629
- return groupName !== tsResolver.param.name(node, rawQueryParams[0]) ? groupName : null;
1630
- })() : null;
1631
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
1632
- const pageParamType = queryParamType ? isInitialPageParamDefined ? `NonNullable<${queryParamType}>` : queryParamType : fallbackPageParamType;
1636
+ const { TData: queryFnDataType, TError: errorType } = buildResponseTypes(node, tsResolver);
1637
+ const { queryParamsTypeName, pageParamType } = resolvePageParamType(node, {
1638
+ resolver: tsResolver,
1639
+ initialPageParam,
1640
+ queryParam
1641
+ });
1633
1642
  const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
1634
1643
  const paramsSignature = declarationPrinter$1.print(paramsNode) ?? "";
1635
1644
  const queryFnBody = `const { data } = await ${buildClientCall(node, {
@@ -1705,15 +1714,13 @@ return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${que
1705
1714
  const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1706
1715
  function buildSuspenseQueryParamsNode(node, options) {
1707
1716
  const { resolver } = options;
1708
- const successNames = resolveSuccessNames(node, resolver);
1709
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
1710
- const errorNames = resolveErrorNames(node, resolver);
1717
+ const { TData, TError } = buildResponseTypes(node, resolver);
1711
1718
  const optionsParam = (0, _kubb_plugin_ts.createFunctionParameter)({
1712
1719
  name: "options",
1713
1720
  type: `{
1714
1721
  query?: Partial<UseSuspenseQueryOptions<${[
1715
- responseName,
1716
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1722
+ TData,
1723
+ TError,
1717
1724
  "TData",
1718
1725
  "TQueryKey"
1719
1726
  ].join(", ")}>> & { client?: QueryClient },
@@ -1727,11 +1734,8 @@ function buildSuspenseQueryParamsNode(node, options) {
1727
1734
  }), optionsParam].filter((param) => param !== null) });
1728
1735
  }
1729
1736
  function SuspenseQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, customOptions }) {
1730
- const successNames = resolveSuccessNames(node, tsResolver);
1731
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1732
- const errorNames = resolveErrorNames(node, tsResolver);
1733
- const TData = responseName;
1734
- const returnType = `UseSuspenseQueryResult<TData, ${`ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`}> & { queryKey: TQueryKey }`;
1737
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1738
+ const returnType = `UseSuspenseQueryResult<TData, ${TError}> & { queryKey: TQueryKey }`;
1735
1739
  const generics = [`TData = ${TData}`, `TQueryKey extends QueryKey = ${queryKeyTypeName}`];
1736
1740
  const resolvedParams = buildResolvedRequestParams(node);
1737
1741
  const queryKeyArgs = resolvedParams ? "resolvedParams" : "";
@@ -1785,16 +1789,15 @@ const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
1785
1789
  const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
1786
1790
  if (!pluginTs) return null;
1787
1791
  const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1788
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
1789
- const queryMethods = new Set(query ? query.methods : []);
1790
- const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
1792
+ const { isQuery, isMutation } = classifyOperation(node, {
1793
+ query,
1794
+ mutation
1795
+ });
1791
1796
  const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
1792
1797
  if (!isQuery || isMutation || !infiniteOptions) return null;
1793
1798
  const normalizeKey = (key) => key.replace(/\?$/, "");
1794
1799
  const queryParamKeys = getOperationParameters(node, { paramsCasing: "original" }).query.map((p) => p.name);
1795
- const hasQueryParam = infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false;
1796
- const hasCursorParam = !infiniteOptions.cursorParam || true;
1797
- if (!hasQueryParam || !hasCursorParam) return null;
1800
+ if (!(infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false)) return null;
1798
1801
  const importPath = query ? query.importPath : "@tanstack/react-query";
1799
1802
  const contractOp = resolveClientOperation({
1800
1803
  clientPlugin: { pluginName: client.pluginName },
@@ -1952,9 +1955,11 @@ const mutationGenerator = (0, kubb_kit.defineGenerator)({
1952
1955
  const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
1953
1956
  if (!pluginTs) return null;
1954
1957
  const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1955
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
1956
- const queryMethods = new Set(query ? query.methods : []);
1957
- if (!(mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase()))) return null;
1958
+ const { isMutation } = classifyOperation(node, {
1959
+ query,
1960
+ mutation
1961
+ });
1962
+ if (!isMutation) return null;
1958
1963
  const importPath = mutation ? mutation.importPath : "@tanstack/react-query";
1959
1964
  const contractOp = resolveClientOperation({
1960
1965
  clientPlugin: { pluginName: client.pluginName },
@@ -2090,9 +2095,10 @@ const queryGenerator = (0, kubb_kit.defineGenerator)({
2090
2095
  const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
2091
2096
  if (!pluginTs) return null;
2092
2097
  const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
2093
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
2094
- const queryMethods = new Set(query ? query.methods : []);
2095
- const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
2098
+ const { isQuery, isMutation } = classifyOperation(node, {
2099
+ query,
2100
+ mutation
2101
+ });
2096
2102
  if (!isQuery || isMutation) return null;
2097
2103
  const importPath = query ? query.importPath : "@tanstack/react-query";
2098
2104
  const contractOp = resolveClientOperation({
@@ -2234,17 +2240,16 @@ const suspenseInfiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
2234
2240
  const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
2235
2241
  if (!pluginTs) return null;
2236
2242
  const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
2237
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
2238
- const queryMethods = new Set(query ? query.methods : []);
2239
- const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
2243
+ const { isQuery, isMutation } = classifyOperation(node, {
2244
+ query,
2245
+ mutation
2246
+ });
2240
2247
  const isSuspense = !!suspense;
2241
2248
  const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
2242
2249
  if (!isQuery || isMutation || !isSuspense || !infiniteOptions) return null;
2243
2250
  const normalizeKey = (key) => key.replace(/\?$/, "");
2244
2251
  const queryParamKeys = getOperationParameters(node, { paramsCasing: "original" }).query.map((p) => p.name);
2245
- const hasQueryParam = infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false;
2246
- const hasCursorParam = !infiniteOptions.cursorParam || true;
2247
- if (!hasQueryParam || !hasCursorParam) return null;
2252
+ if (!(infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false)) return null;
2248
2253
  const importPath = query ? query.importPath : "@tanstack/react-query";
2249
2254
  const contractOp = resolveClientOperation({
2250
2255
  clientPlugin: { pluginName: client.pluginName },
@@ -2402,9 +2407,10 @@ const suspenseQueryGenerator = (0, kubb_kit.defineGenerator)({
2402
2407
  const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
2403
2408
  if (!pluginTs) return null;
2404
2409
  const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
2405
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
2406
- const queryMethods = new Set(query ? query.methods : []);
2407
- const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
2410
+ const { isQuery, isMutation } = classifyOperation(node, {
2411
+ query,
2412
+ mutation
2413
+ });
2408
2414
  if (!isQuery || isMutation || !!!suspense) return null;
2409
2415
  const importPath = query ? query.importPath : "@tanstack/react-query";
2410
2416
  const contractOp = resolveClientOperation({
@@ -2665,7 +2671,7 @@ const pluginReactQueryName = "plugin-react-query";
2665
2671
  * import { pluginReactQuery } from '@kubb/plugin-react-query'
2666
2672
  *
2667
2673
  * export default defineConfig({
2668
- * input: { path: './petStore.yaml' },
2674
+ * input: './petStore.yaml',
2669
2675
  * output: { path: './src/gen' },
2670
2676
  * plugins: [
2671
2677
  * pluginTs(),
@@ -2690,7 +2696,7 @@ const pluginReactQuery = (0, kubb_kit.definePlugin)((options) => {
2690
2696
  mutationGenerator,
2691
2697
  hookOptionsGenerator,
2692
2698
  customHookOptionsFileGenerator
2693
- ].filter((generator) => Boolean(generator));
2699
+ ];
2694
2700
  const groupConfig = createGroupConfig(group);
2695
2701
  return {
2696
2702
  name: pluginReactQueryName,