@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.d.ts CHANGED
@@ -441,7 +441,7 @@ declare const pluginReactQueryName = "plugin-react-query";
441
441
  * import { pluginReactQuery } from '@kubb/plugin-react-query'
442
442
  *
443
443
  * export default defineConfig({
444
- * input: { path: './petStore.yaml' },
444
+ * input: './petStore.yaml',
445
445
  * output: { path: './src/gen' },
446
446
  * plugins: [
447
447
  * pluginTs(),
package/dist/index.js CHANGED
@@ -132,6 +132,22 @@ const reservedWords = /* @__PURE__ */ new Set([
132
132
  */
133
133
  function isValidVarName(name) {
134
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) {
135
151
  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
136
152
  }
137
153
  //#endregion
@@ -327,8 +343,11 @@ function getOperationLink(node, link) {
327
343
  if (link === "urlPath") return node.path ? `{@link ${Url.toPath(node.path)}}` : null;
328
344
  return node.path ? `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}` : null;
329
345
  }
330
- function getContentTypeInfo(node) {
331
- 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) {
332
351
  const isMultipleContentTypes = contentTypes.length > 1;
333
352
  return {
334
353
  contentTypes,
@@ -338,20 +357,15 @@ function getContentTypeInfo(node) {
338
357
  hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
339
358
  };
340
359
  }
360
+ function getContentTypeInfo(node) {
361
+ return buildContentTypeInfo(node.requestBody?.content?.map((e) => e.contentType) ?? []);
362
+ }
341
363
  /**
342
364
  * The request-body counterpart for the primary success response: the content types it documents and
343
365
  * whether several are present, so the client can let a caller pick which one to accept.
344
366
  */
345
367
  function getResponseContentTypeInfo(node) {
346
- const contentTypes = getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? [];
347
- const isMultipleContentTypes = contentTypes.length > 1;
348
- return {
349
- contentTypes,
350
- isMultipleContentTypes,
351
- contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(" | ") : "",
352
- defaultContentType: contentTypes[0] ?? "application/json",
353
- hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
354
- };
368
+ return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? []);
355
369
  }
356
370
  function buildRequestConfigType(node) {
357
371
  const request = getContentTypeInfo(node);
@@ -938,6 +952,59 @@ function buildResolvedRequestParams(node) {
938
952
  if (names.length === 0) return null;
939
953
  return `{ ${names.map((name) => `${name}: typeof ${name} === 'function' ? ${name}() : ${name}`).join(", ")} }`;
940
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
+ }
941
1008
  //#endregion
942
1009
  //#region src/generators/hookOptionsGenerator.tsx
943
1010
  /**
@@ -1118,23 +1185,12 @@ function buildInfiniteQueryParamsNode(node, options) {
1118
1185
  }), optionsParam].filter((param) => param !== null) });
1119
1186
  }
1120
1187
  function InfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, initialPageParam, queryParam, customOptions }) {
1121
- const successNames = resolveSuccessNames(node, tsResolver);
1122
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1123
- const errorNames = resolveErrorNames(node, tsResolver);
1124
- const responseType = responseName;
1125
- const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1126
- const isInitialPageParamDefined = initialPageParam !== void 0 && initialPageParam !== null;
1127
- const fallbackPageParamType = typeof initialPageParam === "number" ? "number" : typeof initialPageParam === "string" ? initialPageParam.includes(" as ") ? (() => {
1128
- const parts = initialPageParam.split(" as ");
1129
- return parts[parts.length - 1] ?? "unknown";
1130
- })() : "string" : typeof initialPageParam === "boolean" ? "boolean" : "unknown";
1131
- const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
1132
- const queryParamsTypeName = rawQueryParams.length > 0 ? (() => {
1133
- const groupName = tsResolver.param.query(node, rawQueryParams[0]);
1134
- return groupName !== tsResolver.param.name(node, rawQueryParams[0]) ? groupName : null;
1135
- })() : null;
1136
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
1137
- 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
+ });
1138
1194
  const returnType = "UseInfiniteQueryResult<TData, TError> & { queryKey: TQueryKey }";
1139
1195
  const generics = [
1140
1196
  `TQueryFnData = ${responseType}`,
@@ -1188,11 +1244,7 @@ function getQueryOptionsParams(node, options) {
1188
1244
  return buildQueryOptionsParams(node, options);
1189
1245
  }
1190
1246
  function QueryOptions({ name, clientName, node, tsResolver, queryKeyName }) {
1191
- const successNames = resolveSuccessNames(node, tsResolver);
1192
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1193
- const errorNames = resolveErrorNames(node, tsResolver);
1194
- const TData = responseName;
1195
- const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1247
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1196
1248
  const queryKeyParamsNode = buildQueryKeyParams(node, { resolver: tsResolver });
1197
1249
  const queryKeyParamsCall = callPrinter$4.print(queryKeyParamsNode) ?? "";
1198
1250
  const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
@@ -1227,22 +1279,12 @@ function QueryOptions({ name, clientName, node, tsResolver, queryKeyName }) {
1227
1279
  const declarationPrinter$6 = functionPrinter({ mode: "declaration" });
1228
1280
  const callPrinter$3 = functionPrinter({ mode: "call" });
1229
1281
  function InfiniteQueryOptions({ name, clientName, initialPageParam, cursorParam, nextParam, previousParam, node, tsResolver, queryParam, queryKeyName }) {
1230
- const successNames = resolveSuccessNames(node, tsResolver);
1231
- const queryFnDataType = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1232
- const errorNames = resolveErrorNames(node, tsResolver);
1233
- const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1234
- const isInitialPageParamDefined = initialPageParam !== void 0 && initialPageParam !== null;
1235
- const fallbackPageParamType = typeof initialPageParam === "number" ? "number" : typeof initialPageParam === "string" ? initialPageParam.includes(" as ") ? (() => {
1236
- const parts = initialPageParam.split(" as ");
1237
- return parts[parts.length - 1] ?? "unknown";
1238
- })() : "string" : typeof initialPageParam === "boolean" ? "boolean" : "unknown";
1239
- const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
1240
- const queryParamsTypeName = rawQueryParams.length > 0 ? (() => {
1241
- const groupName = tsResolver.param.query(node, rawQueryParams[0]);
1242
- return groupName !== tsResolver.param.name(node, rawQueryParams[0]) ? groupName : null;
1243
- })() : null;
1244
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
1245
- 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
+ });
1246
1288
  const queryKeyParamsNode = buildQueryKeyParams(node, { resolver: tsResolver });
1247
1289
  const queryKeyParamsCall = callPrinter$3.print(queryKeyParamsNode) ?? "";
1248
1290
  const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
@@ -1325,10 +1367,7 @@ function buildMutationConfigParamsNode(node) {
1325
1367
  })] });
1326
1368
  }
1327
1369
  function MutationOptions({ name, clientName, node, tsResolver, mutationKeyName }) {
1328
- const successNames = resolveSuccessNames(node, tsResolver);
1329
- const TData = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1330
- const errorNames = resolveErrorNames(node, tsResolver);
1331
- const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1370
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1332
1371
  const configParamsNode = buildMutationConfigParamsNode(node);
1333
1372
  const paramsSignature = declarationPrinter$5.print(configParamsNode) ?? "";
1334
1373
  const groupedParam = buildGroupedRequestParam(node, { resolver: tsResolver });
@@ -1371,15 +1410,13 @@ function resolveMutationRequestType(node, resolver) {
1371
1410
  }
1372
1411
  function buildMutationParamsNode(node, options) {
1373
1412
  const { resolver } = options;
1374
- const successNames = resolveSuccessNames(node, resolver);
1375
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
1376
- const errorNames = resolveErrorNames(node, resolver);
1413
+ const { TData, TError } = buildResponseTypes(node, resolver);
1377
1414
  return createFunctionParameters({ params: [createFunctionParameter({
1378
1415
  name: "options",
1379
1416
  type: `{
1380
1417
  mutation?: UseMutationOptions<${[
1381
- responseName,
1382
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1418
+ TData,
1419
+ TError,
1383
1420
  resolveMutationRequestType(node, resolver),
1384
1421
  "TContext"
1385
1422
  ].join(", ")}> & { client?: QueryClient },
@@ -1389,12 +1426,10 @@ function buildMutationParamsNode(node, options) {
1389
1426
  })] });
1390
1427
  }
1391
1428
  function Mutation({ name, mutationOptionsName, node, tsResolver, mutationKeyName, customOptions }) {
1392
- const successNames = resolveSuccessNames(node, tsResolver);
1393
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1394
- const errorNames = resolveErrorNames(node, tsResolver);
1429
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1395
1430
  const generics = [
1396
- responseName,
1397
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1431
+ TData,
1432
+ TError,
1398
1433
  resolveMutationRequestType(node, tsResolver),
1399
1434
  "TContext"
1400
1435
  ].join(", ");
@@ -1434,15 +1469,13 @@ function Mutation({ name, mutationOptionsName, node, tsResolver, mutationKeyName
1434
1469
  const declarationPrinter$3 = functionPrinter({ mode: "declaration" });
1435
1470
  function buildQueryParamsNode(node, options) {
1436
1471
  const { resolver } = options;
1437
- const successNames = resolveSuccessNames(node, resolver);
1438
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
1439
- const errorNames = resolveErrorNames(node, resolver);
1472
+ const { TData, TError } = buildResponseTypes(node, resolver);
1440
1473
  const optionsParam = createFunctionParameter({
1441
1474
  name: "options",
1442
1475
  type: `{
1443
1476
  query?: Partial<QueryObserverOptions<${[
1444
- responseName,
1445
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1477
+ TData,
1478
+ TError,
1446
1479
  "TData",
1447
1480
  "TQueryData",
1448
1481
  "TQueryKey"
@@ -1457,11 +1490,8 @@ function buildQueryParamsNode(node, options) {
1457
1490
  }), optionsParam].filter((param) => param !== null) });
1458
1491
  }
1459
1492
  function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, customOptions }) {
1460
- const successNames = resolveSuccessNames(node, tsResolver);
1461
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1462
- const errorNames = resolveErrorNames(node, tsResolver);
1463
- const TData = responseName;
1464
- 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 }`;
1465
1495
  const generics = [
1466
1496
  `TData = ${TData}`,
1467
1497
  `TQueryData = ${TData}`,
@@ -1520,23 +1550,12 @@ function buildSuspenseInfiniteQueryParamsNode(node, options) {
1520
1550
  }), optionsParam].filter((param) => param !== null) });
1521
1551
  }
1522
1552
  function SuspenseInfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, customOptions, initialPageParam, queryParam }) {
1523
- const successNames = resolveSuccessNames(node, tsResolver);
1524
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1525
- const errorNames = resolveErrorNames(node, tsResolver);
1526
- const responseType = responseName;
1527
- const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1528
- const isInitialPageParamDefined = initialPageParam !== void 0 && initialPageParam !== null;
1529
- const fallbackPageParamType = typeof initialPageParam === "number" ? "number" : typeof initialPageParam === "string" ? initialPageParam.includes(" as ") ? (() => {
1530
- const parts = initialPageParam.split(" as ");
1531
- return parts[parts.length - 1] ?? "unknown";
1532
- })() : "string" : typeof initialPageParam === "boolean" ? "boolean" : "unknown";
1533
- const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
1534
- const queryParamsTypeName = rawQueryParams.length > 0 ? (() => {
1535
- const groupName = tsResolver.param.query(node, rawQueryParams[0]);
1536
- return groupName !== tsResolver.param.name(node, rawQueryParams[0]) ? groupName : null;
1537
- })() : null;
1538
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
1539
- 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
+ });
1540
1559
  const returnType = "UseSuspenseInfiniteQueryResult<TData, TError> & { queryKey: TQueryKey }";
1541
1560
  const generics = [
1542
1561
  `TQueryFnData = ${responseType}`,
@@ -1587,22 +1606,12 @@ function SuspenseInfiniteQuery({ name, queryKeyTypeName, queryOptionsName, query
1587
1606
  const declarationPrinter$1 = functionPrinter({ mode: "declaration" });
1588
1607
  const callPrinter = functionPrinter({ mode: "call" });
1589
1608
  function SuspenseInfiniteQueryOptions({ name, clientName, initialPageParam, cursorParam, nextParam, previousParam, node, tsResolver, queryParam, queryKeyName }) {
1590
- const successNames = resolveSuccessNames(node, tsResolver);
1591
- const queryFnDataType = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1592
- const errorNames = resolveErrorNames(node, tsResolver);
1593
- const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1594
- const isInitialPageParamDefined = initialPageParam !== void 0 && initialPageParam !== null;
1595
- const fallbackPageParamType = typeof initialPageParam === "number" ? "number" : typeof initialPageParam === "string" ? initialPageParam.includes(" as ") ? (() => {
1596
- const parts = initialPageParam.split(" as ");
1597
- return parts[parts.length - 1] ?? "unknown";
1598
- })() : "string" : typeof initialPageParam === "boolean" ? "boolean" : "unknown";
1599
- const rawQueryParams = getOperationParameters(node, { paramsCasing: "original" }).query;
1600
- const queryParamsTypeName = rawQueryParams.length > 0 ? (() => {
1601
- const groupName = tsResolver.param.query(node, rawQueryParams[0]);
1602
- return groupName !== tsResolver.param.name(node, rawQueryParams[0]) ? groupName : null;
1603
- })() : null;
1604
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
1605
- 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
+ });
1606
1615
  const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
1607
1616
  const paramsSignature = declarationPrinter$1.print(paramsNode) ?? "";
1608
1617
  const queryFnBody = `const { data } = await ${buildClientCall(node, {
@@ -1678,15 +1687,13 @@ return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${que
1678
1687
  const declarationPrinter = functionPrinter({ mode: "declaration" });
1679
1688
  function buildSuspenseQueryParamsNode(node, options) {
1680
1689
  const { resolver } = options;
1681
- const successNames = resolveSuccessNames(node, resolver);
1682
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
1683
- const errorNames = resolveErrorNames(node, resolver);
1690
+ const { TData, TError } = buildResponseTypes(node, resolver);
1684
1691
  const optionsParam = createFunctionParameter({
1685
1692
  name: "options",
1686
1693
  type: `{
1687
1694
  query?: Partial<UseSuspenseQueryOptions<${[
1688
- responseName,
1689
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1695
+ TData,
1696
+ TError,
1690
1697
  "TData",
1691
1698
  "TQueryKey"
1692
1699
  ].join(", ")}>> & { client?: QueryClient },
@@ -1700,11 +1707,8 @@ function buildSuspenseQueryParamsNode(node, options) {
1700
1707
  }), optionsParam].filter((param) => param !== null) });
1701
1708
  }
1702
1709
  function SuspenseQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, customOptions }) {
1703
- const successNames = resolveSuccessNames(node, tsResolver);
1704
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
1705
- const errorNames = resolveErrorNames(node, tsResolver);
1706
- const TData = responseName;
1707
- 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 }`;
1708
1712
  const generics = [`TData = ${TData}`, `TQueryKey extends QueryKey = ${queryKeyTypeName}`];
1709
1713
  const resolvedParams = buildResolvedRequestParams(node);
1710
1714
  const queryKeyArgs = resolvedParams ? "resolvedParams" : "";
@@ -1758,16 +1762,15 @@ const infiniteQueryGenerator = defineGenerator({
1758
1762
  const pluginTs = driver.getPlugin(pluginTsName);
1759
1763
  if (!pluginTs) return null;
1760
1764
  const tsResolver = driver.getResolver(pluginTsName);
1761
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
1762
- const queryMethods = new Set(query ? query.methods : []);
1763
- 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
+ });
1764
1769
  const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
1765
1770
  if (!isQuery || isMutation || !infiniteOptions) return null;
1766
1771
  const normalizeKey = (key) => key.replace(/\?$/, "");
1767
1772
  const queryParamKeys = getOperationParameters(node, { paramsCasing: "original" }).query.map((p) => p.name);
1768
- const hasQueryParam = infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false;
1769
- const hasCursorParam = !infiniteOptions.cursorParam || true;
1770
- if (!hasQueryParam || !hasCursorParam) return null;
1773
+ if (!(infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false)) return null;
1771
1774
  const importPath = query ? query.importPath : "@tanstack/react-query";
1772
1775
  const contractOp = resolveClientOperation({
1773
1776
  clientPlugin: { pluginName: client.pluginName },
@@ -1925,9 +1928,11 @@ const mutationGenerator = defineGenerator({
1925
1928
  const pluginTs = driver.getPlugin(pluginTsName);
1926
1929
  if (!pluginTs) return null;
1927
1930
  const tsResolver = driver.getResolver(pluginTsName);
1928
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
1929
- const queryMethods = new Set(query ? query.methods : []);
1930
- 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;
1931
1936
  const importPath = mutation ? mutation.importPath : "@tanstack/react-query";
1932
1937
  const contractOp = resolveClientOperation({
1933
1938
  clientPlugin: { pluginName: client.pluginName },
@@ -2063,9 +2068,10 @@ const queryGenerator = defineGenerator({
2063
2068
  const pluginTs = driver.getPlugin(pluginTsName);
2064
2069
  if (!pluginTs) return null;
2065
2070
  const tsResolver = driver.getResolver(pluginTsName);
2066
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
2067
- const queryMethods = new Set(query ? query.methods : []);
2068
- 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
+ });
2069
2075
  if (!isQuery || isMutation) return null;
2070
2076
  const importPath = query ? query.importPath : "@tanstack/react-query";
2071
2077
  const contractOp = resolveClientOperation({
@@ -2207,17 +2213,16 @@ const suspenseInfiniteQueryGenerator = defineGenerator({
2207
2213
  const pluginTs = driver.getPlugin(pluginTsName);
2208
2214
  if (!pluginTs) return null;
2209
2215
  const tsResolver = driver.getResolver(pluginTsName);
2210
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
2211
- const queryMethods = new Set(query ? query.methods : []);
2212
- 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
+ });
2213
2220
  const isSuspense = !!suspense;
2214
2221
  const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
2215
2222
  if (!isQuery || isMutation || !isSuspense || !infiniteOptions) return null;
2216
2223
  const normalizeKey = (key) => key.replace(/\?$/, "");
2217
2224
  const queryParamKeys = getOperationParameters(node, { paramsCasing: "original" }).query.map((p) => p.name);
2218
- const hasQueryParam = infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false;
2219
- const hasCursorParam = !infiniteOptions.cursorParam || true;
2220
- if (!hasQueryParam || !hasCursorParam) return null;
2225
+ if (!(infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false)) return null;
2221
2226
  const importPath = query ? query.importPath : "@tanstack/react-query";
2222
2227
  const contractOp = resolveClientOperation({
2223
2228
  clientPlugin: { pluginName: client.pluginName },
@@ -2375,9 +2380,10 @@ const suspenseQueryGenerator = defineGenerator({
2375
2380
  const pluginTs = driver.getPlugin(pluginTsName);
2376
2381
  if (!pluginTs) return null;
2377
2382
  const tsResolver = driver.getResolver(pluginTsName);
2378
- const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
2379
- const queryMethods = new Set(query ? query.methods : []);
2380
- 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
+ });
2381
2387
  if (!isQuery || isMutation || !!!suspense) return null;
2382
2388
  const importPath = query ? query.importPath : "@tanstack/react-query";
2383
2389
  const contractOp = resolveClientOperation({
@@ -2638,7 +2644,7 @@ const pluginReactQueryName = "plugin-react-query";
2638
2644
  * import { pluginReactQuery } from '@kubb/plugin-react-query'
2639
2645
  *
2640
2646
  * export default defineConfig({
2641
- * input: { path: './petStore.yaml' },
2647
+ * input: './petStore.yaml',
2642
2648
  * output: { path: './src/gen' },
2643
2649
  * plugins: [
2644
2650
  * pluginTs(),
@@ -2663,7 +2669,7 @@ const pluginReactQuery = definePlugin((options) => {
2663
2669
  mutationGenerator,
2664
2670
  hookOptionsGenerator,
2665
2671
  customHookOptionsFileGenerator
2666
- ].filter((generator) => Boolean(generator));
2672
+ ];
2667
2673
  const groupConfig = createGroupConfig(group);
2668
2674
  return {
2669
2675
  name: pluginReactQueryName,