@kubb/plugin-vue-query 5.3.0-canary.20261012T190229 → 5.3.0

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
@@ -353,7 +353,7 @@ function createGroupConfig(group) {
353
353
  }
354
354
  //#endregion
355
355
  //#region package.json
356
- var version = "5.3.0-canary.20261012T190229";
356
+ var version = "5.3.0";
357
357
  //#endregion
358
358
  //#region ../../internals/tanstack-query/src/utils.ts
359
359
  /**
@@ -571,22 +571,61 @@ function classifyOperation(node, { query, mutation }) {
571
571
  };
572
572
  }
573
573
  /**
574
+ * Helper to define a typed page param function for `infinite.getNextPageParam` or
575
+ * `infinite.getPreviousPageParam`. Serializes the function to a string for inlining in generated code.
576
+ *
577
+ * Note: Because the function is inlined verbatim into the generated file via `.toString()`,
578
+ * it must be self-contained and cannot reference local closures or external variables from
579
+ * the config file.
580
+ */
581
+ function definePageParam(fn) {
582
+ return fn.toString();
583
+ }
584
+ /**
574
585
  * Applies the shared infinite-query defaults during plugin setup: a falsy value disables infinite
575
586
  * queries, and an object merges over `queryParam: 'id'` and `initialPageParam: 0` with the cursor
576
587
  * paths cleared.
577
588
  */
578
589
  function resolveInfiniteConfig(infinite) {
579
590
  if (!infinite) return false;
591
+ const hasExplicitInitialPageParam = infinite.hasExplicitInitialPageParam ?? infinite.initialPageParam !== void 0;
592
+ const getNextPageParam = infinite.getNextPageParam ? typeof infinite.getNextPageParam === "function" ? infinite.getNextPageParam.toString() : infinite.getNextPageParam : null;
593
+ const getPreviousPageParam = infinite.getPreviousPageParam ? typeof infinite.getPreviousPageParam === "function" ? infinite.getPreviousPageParam.toString() : infinite.getPreviousPageParam : null;
580
594
  return {
581
595
  queryParam: "id",
582
596
  initialPageParam: 0,
597
+ hasExplicitInitialPageParam,
583
598
  cursorParam: null,
584
599
  nextParam: null,
585
600
  previousParam: null,
586
- ...infinite
601
+ getNextPageParam,
602
+ getPreviousPageParam,
603
+ ...infinite,
604
+ ...getNextPageParam ? { getNextPageParam } : {},
605
+ ...getPreviousPageParam ? { getPreviousPageParam } : {}
587
606
  };
588
607
  }
589
608
  /**
609
+ * Whether the infinite hook for `node` should be generated: the operation takes the configured
610
+ * `queryParam`.
611
+ */
612
+ function matchesInfinite(node, infinite) {
613
+ if (!infinite.queryParam) return false;
614
+ return getOperationParameters(node).query.some((param) => param.name.replace(/\?$/, "") === infinite.queryParam);
615
+ }
616
+ /**
617
+ * Warning for an infinite hook that falls back to the built-in page params on a response that
618
+ * isn't an array. Those params only stop on an empty array, so `hasNextPage` never turns false.
619
+ */
620
+ function getDefaultPageParamsWarning(node, infinite) {
621
+ if (!(infinite.getNextPageParam == null && infinite.getPreviousPageParam == null && infinite.nextParam == null && infinite.previousParam == null && !infinite.cursorParam)) return null;
622
+ const content = getPrimarySuccessResponse(node)?.content;
623
+ let resolved = (content?.find((item) => item.contentType?.includes("json")) ?? content?.[0])?.schema;
624
+ while (resolved?.type === "ref" || resolved?.type === "intersection" && resolved.members?.length === 1) resolved = resolved.type === "ref" ? resolved.schema : resolved.members?.[0];
625
+ if (!resolved || resolved.type === "array") return null;
626
+ 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.`;
627
+ }
628
+ /**
590
629
  * The request groups a query key is built from, matching `buildQueryKeyParams`. Headers are
591
630
  * deliberately absent: they do not identify a cache entry, so the key factory takes no parameter
592
631
  * for an operation that only carries headers.
@@ -600,7 +639,7 @@ const queryKeyGroupOrder = [
600
639
  //#region ../../internals/tanstack-query/src/components/InfiniteQueryOptions.tsx
601
640
  const declarationPrinter$7 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
602
641
  const callPrinter$4 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
603
- function InfiniteQueryOptions$1({ name, clientName, initialPageParam, cursorParam, nextParam, previousParam, node, tsResolver, queryParam, queryKeyName, queryKeyType = "typeof queryKey", memberTypeWrapper, unwrapName, returnType = "full" }) {
642
+ function InfiniteQueryOptions$1({ name, clientName, initialPageParam, hasExplicitInitialPageParam, cursorParam, nextParam, previousParam, getNextPageParam, getPreviousPageParam, node, tsResolver, queryParam, queryKeyName, queryKeyType = "typeof queryKey", memberTypeWrapper, unwrapName, returnType = "full" }) {
604
643
  const { TData: queryFnDataType, TError: errorType } = buildResponseTypes(node, tsResolver);
605
644
  const { queryParamsTypeName, pageParamType } = resolvePageParamType(node, {
606
645
  resolver: tsResolver,
@@ -624,18 +663,25 @@ function InfiniteQueryOptions$1({ name, clientName, initialPageParam, cursorPara
624
663
  signal: true,
625
664
  unwrapName
626
665
  }), { returnType });
627
- const hasNewParams = nextParam != null || previousParam != null;
628
- const [getNextPageParamExpr, getPreviousPageParamExpr] = (() => {
629
- if (hasNewParams) {
630
- const nextAccessor = nextParam ? getNestedAccessor(nextParam, "lastPage") : null;
631
- const prevAccessor = previousParam ? getNestedAccessor(previousParam, "firstPage") : null;
632
- return [nextAccessor ? `getNextPageParam: (lastPage) => ${nextAccessor}` : null, prevAccessor ? `getPreviousPageParam: (firstPage) => ${prevAccessor}` : null];
633
- }
634
- if (cursorParam) return [`getNextPageParam: (lastPage) => lastPage['${cursorParam}']`, `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`];
635
- return ["getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage) && lastPage.length === 0 ? undefined : lastPageParam + 1", "getPreviousPageParam: (_firstPage, _allPages, firstPageParam) => firstPageParam <= 1 ? undefined : firstPageParam - 1"];
666
+ const initialPageParamLiteral = typeof initialPageParam === "string" || typeof initialPageParam === "object" && initialPageParam !== null ? JSON.stringify(initialPageParam) : String(initialPageParam === void 0 ? 0 : initialPageParam);
667
+ const serializedGetNextPageParam = typeof getNextPageParam === "function" ? getNextPageParam.toString() : getNextPageParam;
668
+ const getNextPageParamExpr = (() => {
669
+ if (serializedGetNextPageParam) return `getNextPageParam: ${serializedGetNextPageParam}`;
670
+ if (nextParam) return `getNextPageParam: (lastPage) => ${getNestedAccessor(nextParam, "lastPage")}`;
671
+ if (cursorParam) return `getNextPageParam: (lastPage) => lastPage['${cursorParam}']`;
672
+ return "getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage) && lastPage.length === 0 ? undefined : lastPageParam + 1";
673
+ })();
674
+ const serializedGetPreviousPageParam = typeof getPreviousPageParam === "function" ? getPreviousPageParam.toString() : getPreviousPageParam;
675
+ const defaultPreviousThreshold = hasExplicitInitialPageParam ? initialPageParamLiteral : "1";
676
+ const getPreviousPageParamExpr = (() => {
677
+ if (serializedGetPreviousPageParam) return `getPreviousPageParam: ${serializedGetPreviousPageParam}`;
678
+ if (previousParam) return `getPreviousPageParam: (firstPage) => ${getNestedAccessor(previousParam, "firstPage")}`;
679
+ if (cursorParam) return `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`;
680
+ if (serializedGetNextPageParam || nextParam) return null;
681
+ return `getPreviousPageParam: (_firstPage, _allPages, firstPageParam) => firstPageParam <= ${defaultPreviousThreshold} ? undefined : firstPageParam - 1`;
636
682
  })();
637
683
  const queryOptionsArr = [
638
- `initialPageParam: ${typeof initialPageParam === "string" ? JSON.stringify(initialPageParam) : initialPageParam}`,
684
+ `initialPageParam: ${initialPageParamLiteral}`,
639
685
  getNextPageParamExpr,
640
686
  getPreviousPageParamExpr
641
687
  ].filter(Boolean);
@@ -1225,21 +1271,28 @@ function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, t
1225
1271
  const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
1226
1272
  name: "vue-query-infinite",
1227
1273
  renderer: kubb_jsx.jsxRenderer,
1274
+ match(node, ctx) {
1275
+ const operationNode = node;
1276
+ if (!kubb_kit.ast.isHttpOperationNode(operationNode)) return false;
1277
+ const { query, mutation, infinite, hooks } = ctx.options;
1278
+ const { isQuery, isMutation } = classifyOperation(operationNode, {
1279
+ query,
1280
+ mutation
1281
+ });
1282
+ const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
1283
+ if (!isQuery || isMutation || !infiniteOptions || !hooks) return false;
1284
+ return matchesInfinite(operationNode, infiniteOptions);
1285
+ },
1228
1286
  operation(node, ctx) {
1229
1287
  if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
1230
1288
  const { config, driver, resolver, root } = ctx;
1231
- const { output, query, mutation, infinite, client, group, hooks } = ctx.options;
1289
+ const { output, query, infinite, client, group } = ctx.options;
1290
+ const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
1291
+ if (!infiniteOptions) return null;
1292
+ const pageParamsWarning = getDefaultPageParamsWarning(node, infiniteOptions);
1293
+ if (pageParamsWarning) ctx.warn(pageParamsWarning);
1232
1294
  const pluginTs = ctx.requirePlugin(_kubb_plugin_ts.pluginTsName);
1233
1295
  const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1234
- const { isQuery, isMutation } = classifyOperation(node, {
1235
- query,
1236
- mutation
1237
- });
1238
- const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
1239
- if (!isQuery || isMutation || !infiniteOptions || !hooks) return null;
1240
- const normalizeKey = (key) => key.replace(/\?$/, "");
1241
- const queryParamKeys = getOperationParameters(node).query.map((p) => p.name);
1242
- if (!(infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false)) return null;
1243
1296
  const importPath = query ? query.importPath : "@tanstack/vue-query";
1244
1297
  const contractOp = resolveClientOperation({
1245
1298
  clientPlugin: { pluginName: client.pluginName },
@@ -1358,7 +1411,10 @@ const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
1358
1411
  cursorParam: infiniteOptions.cursorParam,
1359
1412
  nextParam: infiniteOptions.nextParam,
1360
1413
  previousParam: infiniteOptions.previousParam,
1414
+ getNextPageParam: infiniteOptions.getNextPageParam,
1415
+ getPreviousPageParam: infiniteOptions.getPreviousPageParam,
1361
1416
  initialPageParam: infiniteOptions.initialPageParam,
1417
+ hasExplicitInitialPageParam: infiniteOptions.hasExplicitInitialPageParam,
1362
1418
  queryParam: infiniteOptions.queryParam,
1363
1419
  returnType: contractOp.returnType
1364
1420
  }),
@@ -1775,6 +1831,7 @@ const pluginVueQuery = (0, kubb_kit.definePlugin)({
1775
1831
  });
1776
1832
  //#endregion
1777
1833
  exports.default = pluginVueQuery;
1834
+ exports.definePageParam = definePageParam;
1778
1835
  exports.pluginVueQuery = pluginVueQuery;
1779
1836
  exports.pluginVueQueryName = pluginVueQueryName;
1780
1837
  exports.resolverVueQuery = resolverVueQuery;