@kubb/plugin-react-query 5.3.0-canary.20261012T181005 → 5.4.0-canary.20261013T065217

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
@@ -351,7 +351,7 @@ function createGroupConfig(group) {
351
351
  }
352
352
  //#endregion
353
353
  //#region package.json
354
- var version = "5.3.0-canary.20261012T181005";
354
+ var version = "5.4.0-canary.20261013T065217";
355
355
  //#endregion
356
356
  //#region ../../internals/client/src/resolveClient.ts
357
357
  /**
@@ -691,21 +691,60 @@ function classifyOperation(node, { query, mutation }) {
691
691
  };
692
692
  }
693
693
  /**
694
+ * Helper to define a typed page param function for `infinite.getNextPageParam` or
695
+ * `infinite.getPreviousPageParam`. Serializes the function to a string for inlining in generated code.
696
+ *
697
+ * Note: Because the function is inlined verbatim into the generated file via `.toString()`,
698
+ * it must be self-contained and cannot reference local closures or external variables from
699
+ * the config file.
700
+ */
701
+ function definePageParam(fn) {
702
+ return fn.toString();
703
+ }
704
+ /**
694
705
  * Applies the shared infinite-query defaults during plugin setup: a falsy value disables infinite
695
706
  * queries, and an object merges over `queryParam: 'id'` and `initialPageParam: 0` with the cursor
696
707
  * paths cleared.
697
708
  */
698
709
  function resolveInfiniteConfig(infinite) {
699
710
  if (!infinite) return false;
711
+ const hasExplicitInitialPageParam = infinite.hasExplicitInitialPageParam ?? infinite.initialPageParam !== void 0;
712
+ const getNextPageParam = infinite.getNextPageParam ? typeof infinite.getNextPageParam === "function" ? infinite.getNextPageParam.toString() : infinite.getNextPageParam : null;
713
+ const getPreviousPageParam = infinite.getPreviousPageParam ? typeof infinite.getPreviousPageParam === "function" ? infinite.getPreviousPageParam.toString() : infinite.getPreviousPageParam : null;
700
714
  return {
701
715
  queryParam: "id",
702
716
  initialPageParam: 0,
717
+ hasExplicitInitialPageParam,
703
718
  cursorParam: null,
704
719
  nextParam: null,
705
720
  previousParam: null,
706
- ...infinite
721
+ getNextPageParam,
722
+ getPreviousPageParam,
723
+ ...infinite,
724
+ ...getNextPageParam ? { getNextPageParam } : {},
725
+ ...getPreviousPageParam ? { getPreviousPageParam } : {}
707
726
  };
708
727
  }
728
+ /**
729
+ * Whether the infinite hook for `node` should be generated: the operation takes the configured
730
+ * `queryParam`.
731
+ */
732
+ function matchesInfinite(node, infinite) {
733
+ if (!infinite.queryParam) return false;
734
+ return getOperationParameters(node).query.some((param) => param.name.replace(/\?$/, "") === infinite.queryParam);
735
+ }
736
+ /**
737
+ * Warning for an infinite hook that falls back to the built-in page params on a response that
738
+ * isn't an array. Those params only stop on an empty array, so `hasNextPage` never turns false.
739
+ */
740
+ function getDefaultPageParamsWarning(node, infinite) {
741
+ if (!(infinite.getNextPageParam == null && infinite.getPreviousPageParam == null && infinite.nextParam == null && infinite.previousParam == null && !infinite.cursorParam)) return null;
742
+ const content = getPrimarySuccessResponse(node)?.content;
743
+ let resolved = (content?.find((item) => item.contentType?.includes("json")) ?? content?.[0])?.schema;
744
+ while (resolved?.type === "ref" || resolved?.type === "intersection" && resolved.members?.length === 1) resolved = resolved.type === "ref" ? resolved.schema : resolved.members?.[0];
745
+ if (!resolved || resolved.type === "array") return null;
746
+ return `${node.operationId}: the default infinite page params expect an array response and never end for this one. Set \`infinite.getNextPageParam\` (or \`nextParam\`) to read the next page from the response.`;
747
+ }
709
748
  function matchesPattern(node, ov) {
710
749
  const { type, pattern } = ov;
711
750
  const matches = (value) => typeof pattern === "string" ? value === pattern : pattern.test(value);
@@ -763,7 +802,7 @@ function buildQueryKeyParams(node, options) {
763
802
  //#region ../../internals/tanstack-query/src/components/InfiniteQueryOptions.tsx
764
803
  const declarationPrinter$7 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
765
804
  const callPrinter$3 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
766
- function InfiniteQueryOptions({ name, clientName, initialPageParam, cursorParam, nextParam, previousParam, node, tsResolver, queryParam, queryKeyName, queryKeyType = "typeof queryKey", memberTypeWrapper, unwrapName, returnType = "full" }) {
805
+ function InfiniteQueryOptions({ name, clientName, initialPageParam, hasExplicitInitialPageParam, cursorParam, nextParam, previousParam, getNextPageParam, getPreviousPageParam, node, tsResolver, queryParam, queryKeyName, queryKeyType = "typeof queryKey", memberTypeWrapper, unwrapName, returnType = "full" }) {
767
806
  const { TData: queryFnDataType, TError: errorType } = buildResponseTypes(node, tsResolver);
768
807
  const { queryParamsTypeName, pageParamType } = resolvePageParamType(node, {
769
808
  resolver: tsResolver,
@@ -787,18 +826,25 @@ function InfiniteQueryOptions({ name, clientName, initialPageParam, cursorParam,
787
826
  signal: true,
788
827
  unwrapName
789
828
  }), { returnType });
790
- const hasNewParams = nextParam != null || previousParam != null;
791
- const [getNextPageParamExpr, getPreviousPageParamExpr] = (() => {
792
- if (hasNewParams) {
793
- const nextAccessor = nextParam ? getNestedAccessor(nextParam, "lastPage") : null;
794
- const prevAccessor = previousParam ? getNestedAccessor(previousParam, "firstPage") : null;
795
- return [nextAccessor ? `getNextPageParam: (lastPage) => ${nextAccessor}` : null, prevAccessor ? `getPreviousPageParam: (firstPage) => ${prevAccessor}` : null];
796
- }
797
- if (cursorParam) return [`getNextPageParam: (lastPage) => lastPage['${cursorParam}']`, `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`];
798
- return ["getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage) && lastPage.length === 0 ? undefined : lastPageParam + 1", "getPreviousPageParam: (_firstPage, _allPages, firstPageParam) => firstPageParam <= 1 ? undefined : firstPageParam - 1"];
829
+ const initialPageParamLiteral = typeof initialPageParam === "string" || typeof initialPageParam === "object" && initialPageParam !== null ? JSON.stringify(initialPageParam) : String(initialPageParam === void 0 ? 0 : initialPageParam);
830
+ const serializedGetNextPageParam = typeof getNextPageParam === "function" ? getNextPageParam.toString() : getNextPageParam;
831
+ const getNextPageParamExpr = (() => {
832
+ if (serializedGetNextPageParam) return `getNextPageParam: ${serializedGetNextPageParam}`;
833
+ if (nextParam) return `getNextPageParam: (lastPage) => ${getNestedAccessor(nextParam, "lastPage")}`;
834
+ if (cursorParam) return `getNextPageParam: (lastPage) => lastPage['${cursorParam}']`;
835
+ return "getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage) && lastPage.length === 0 ? undefined : lastPageParam + 1";
836
+ })();
837
+ const serializedGetPreviousPageParam = typeof getPreviousPageParam === "function" ? getPreviousPageParam.toString() : getPreviousPageParam;
838
+ const defaultPreviousThreshold = hasExplicitInitialPageParam ? initialPageParamLiteral : "1";
839
+ const getPreviousPageParamExpr = (() => {
840
+ if (serializedGetPreviousPageParam) return `getPreviousPageParam: ${serializedGetPreviousPageParam}`;
841
+ if (previousParam) return `getPreviousPageParam: (firstPage) => ${getNestedAccessor(previousParam, "firstPage")}`;
842
+ if (cursorParam) return `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`;
843
+ if (serializedGetNextPageParam || nextParam) return null;
844
+ return `getPreviousPageParam: (_firstPage, _allPages, firstPageParam) => firstPageParam <= ${defaultPreviousThreshold} ? undefined : firstPageParam - 1`;
799
845
  })();
800
846
  const queryOptionsArr = [
801
- `initialPageParam: ${typeof initialPageParam === "string" ? JSON.stringify(initialPageParam) : initialPageParam}`,
847
+ `initialPageParam: ${initialPageParamLiteral}`,
802
848
  getNextPageParamExpr,
803
849
  getPreviousPageParamExpr
804
850
  ].filter(Boolean);
@@ -1549,8 +1595,7 @@ const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
1549
1595
  });
1550
1596
  const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
1551
1597
  if (!isQuery || isMutation || !infiniteOptions || !hooks) return false;
1552
- const queryParamKeys = getOperationParameters(operationNode).query.map((p) => p.name);
1553
- return infiniteOptions.queryParam ? queryParamKeys.includes(infiniteOptions.queryParam) || queryParamKeys.includes(`${infiniteOptions.queryParam}?`) : false;
1598
+ return matchesInfinite(operationNode, infiniteOptions);
1554
1599
  },
1555
1600
  operation(node, ctx) {
1556
1601
  if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
@@ -1560,6 +1605,8 @@ const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
1560
1605
  const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1561
1606
  const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
1562
1607
  if (!infiniteOptions) return null;
1608
+ const pageParamsWarning = getDefaultPageParamsWarning(node, infiniteOptions);
1609
+ if (pageParamsWarning) ctx.warn(pageParamsWarning);
1563
1610
  const importPath = query ? query.importPath : "@tanstack/react-query";
1564
1611
  const contractOp = resolveClientOperation({
1565
1612
  clientPlugin: { pluginName: client.pluginName },
@@ -1673,7 +1720,10 @@ const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
1673
1720
  cursorParam: infiniteOptions.cursorParam,
1674
1721
  nextParam: infiniteOptions.nextParam,
1675
1722
  previousParam: infiniteOptions.previousParam,
1723
+ getNextPageParam: infiniteOptions.getNextPageParam,
1724
+ getPreviousPageParam: infiniteOptions.getPreviousPageParam,
1676
1725
  initialPageParam: infiniteOptions.initialPageParam,
1726
+ hasExplicitInitialPageParam: infiniteOptions.hasExplicitInitialPageParam,
1677
1727
  queryParam: infiniteOptions.queryParam,
1678
1728
  returnType: contractOp.returnType
1679
1729
  }),
@@ -2027,8 +2077,7 @@ const suspenseInfiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
2027
2077
  });
2028
2078
  const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
2029
2079
  if (!isQuery || isMutation || !suspense || !infiniteOptions || !hooks) return false;
2030
- const queryParamKeys = getOperationParameters(operationNode).query.map((p) => p.name);
2031
- return infiniteOptions.queryParam ? queryParamKeys.includes(infiniteOptions.queryParam) || queryParamKeys.includes(`${infiniteOptions.queryParam}?`) : false;
2080
+ return matchesInfinite(operationNode, infiniteOptions);
2032
2081
  },
2033
2082
  operation(node, ctx) {
2034
2083
  if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
@@ -2068,12 +2117,16 @@ const suspenseInfiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
2068
2117
  group: pluginTs.options?.group
2069
2118
  })
2070
2119
  };
2071
- const rawQueryParams = getOperationParameters(node).query;
2072
- const queryParamsTypeName = rawQueryParams.length > 0 && tsResolver.param.query(node, rawQueryParams[0]) !== tsResolver.param.name(node, rawQueryParams[0]) ? tsResolver.param.query(node, rawQueryParams[0]) : null;
2120
+ const { queryParamsTypeName } = resolvePageParamType(node, {
2121
+ resolver: tsResolver,
2122
+ initialPageParam: infiniteOptions.initialPageParam,
2123
+ queryParam: infiniteOptions.queryParam
2124
+ });
2073
2125
  const importedTypeNames = [
2074
2126
  tsResolver.response.options(node),
2075
2127
  queryParamsTypeName,
2076
2128
  ...resolveOperationTypeNames(node, tsResolver, {
2129
+ exclude: [queryKeyTypeName],
2077
2130
  order: "body-response-first",
2078
2131
  includeParams: false
2079
2132
  })
@@ -2147,7 +2200,10 @@ const suspenseInfiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
2147
2200
  cursorParam: infiniteOptions.cursorParam,
2148
2201
  nextParam: infiniteOptions.nextParam,
2149
2202
  previousParam: infiniteOptions.previousParam,
2203
+ getNextPageParam: infiniteOptions.getNextPageParam,
2204
+ getPreviousPageParam: infiniteOptions.getPreviousPageParam,
2150
2205
  initialPageParam: infiniteOptions.initialPageParam,
2206
+ hasExplicitInitialPageParam: infiniteOptions.hasExplicitInitialPageParam,
2151
2207
  queryParam: infiniteOptions.queryParam,
2152
2208
  returnType: contractOp.returnType
2153
2209
  }),
@@ -2416,23 +2472,23 @@ const pluginReactQuery = (0, kubb_kit.definePlugin)({
2416
2472
  meta: {
2417
2473
  name: pluginReactQueryName,
2418
2474
  version,
2419
- compatibility: { kubb: ">=5.7.0" }
2475
+ compatibility: { kubb: ">=5.8.0" }
2420
2476
  },
2421
2477
  dependencies: { [_kubb_plugin_ts.pluginTsName]: {} },
2422
- setup(options, kubb) {
2478
+ setup(options) {
2423
2479
  const { output = {
2424
2480
  path: "hooks",
2425
2481
  barrel: { type: "named" }
2426
2482
  }, group, exclude = [], include, override = [], suspense = false, infinite = false, mutation = {}, query = {}, mutationKey = mutationKeyTransformer, queryKey = queryKeyTransformer, customOptions, hooks = false, client, resolver: userResolver, macros: userMacros } = options;
2427
2483
  const resolver = userResolver ? kubb_kit.Resolver.merge(resolverReactQuery, userResolver) : resolverReactQuery;
2428
- kubb.setResolver(resolver);
2429
- if (userMacros?.length) kubb.setMacros(userMacros);
2430
- kubb.addGenerator(queryGenerator, suspenseQueryGenerator, infiniteQueryGenerator, suspenseInfiniteQueryGenerator, mutationGenerator, hookOptionsGenerator, customHookOptionsFileGenerator);
2484
+ (0, kubb_kit.setResolver)(resolver);
2485
+ if (userMacros?.length) (0, kubb_kit.setMacros)(userMacros);
2486
+ (0, kubb_kit.addGenerator)(queryGenerator, suspenseQueryGenerator, infiniteQueryGenerator, suspenseInfiniteQueryGenerator, mutationGenerator, hookOptionsGenerator, customHookOptionsFileGenerator);
2431
2487
  return {
2432
2488
  output,
2433
2489
  client: resolveContractClient({
2434
2490
  client,
2435
- plugins: kubb.config.plugins
2491
+ plugins: (0, kubb_kit.useConfig)().plugins
2436
2492
  }),
2437
2493
  queryKey,
2438
2494
  query: resolveQueryConfig(query, { importPath: "@tanstack/react-query" }),
@@ -2455,6 +2511,7 @@ const pluginReactQuery = (0, kubb_kit.definePlugin)({
2455
2511
  });
2456
2512
  //#endregion
2457
2513
  exports.default = pluginReactQuery;
2514
+ exports.definePageParam = definePageParam;
2458
2515
  exports.pluginReactQuery = pluginReactQuery;
2459
2516
  exports.pluginReactQueryName = pluginReactQueryName;
2460
2517
  exports.resolverReactQuery = resolverReactQuery;