@kubb/plugin-vue-query 5.3.0-canary.20261012T190229 → 5.3.1
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/OVERVIEW.md +18 -0
- package/dist/index.cjs +87 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +45 -1
- package/dist/index.js +87 -25
- package/dist/index.js.map +1 -1
- package/kubb-extension.json +208 -0
- package/package.json +12 -9
package/OVERVIEW.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Vue Query
|
|
2
|
+
|
|
3
|
+
Generates TanStack Query helpers for Vue from your OpenAPI spec. By default you get `queryOptions` factories with their query and mutation keys. Set `hooks: true` to also get `useQuery`, `useInfiniteQuery`, and `useMutation` composables with reactive parameters.
|
|
4
|
+
|
|
5
|
+
The plugin ships no HTTP client. Each helper calls a function generated by a client plugin.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
- Add `@kubb/plugin-ts` and a client plugin: `@kubb/plugin-fetch` or `@kubb/plugin-axios`.
|
|
10
|
+
- Install `@tanstack/vue-query` v5 or higher in the app that uses the generated code.
|
|
11
|
+
- Configure validation on the client plugin, not here.
|
|
12
|
+
|
|
13
|
+
## Options worth knowing
|
|
14
|
+
|
|
15
|
+
- `client` picks `fetch` or `axios` when both client plugins are registered. A single client is detected automatically.
|
|
16
|
+
- `hooks` adds the `use*` composables on top of the option factories.
|
|
17
|
+
- `infinite` adds infinite queries for pagination. Set `infinite.queryParam` to the query parameter that holds the page cursor.
|
|
18
|
+
- `query` and `mutation` set which HTTP methods become queries (`GET`) and mutations (`POST`, `PUT`, `PATCH`, `DELETE`), and where the TanStack Query runtime is imported from. Set either to `false` to skip it.
|
package/dist/index.cjs
CHANGED
|
@@ -352,8 +352,14 @@ function createGroupConfig(group) {
|
|
|
352
352
|
};
|
|
353
353
|
}
|
|
354
354
|
//#endregion
|
|
355
|
+
//#region kubb-extension.json
|
|
356
|
+
var compatibility = {
|
|
357
|
+
"kubb": ">=5.8.0",
|
|
358
|
+
"node": ">=22"
|
|
359
|
+
};
|
|
360
|
+
//#endregion
|
|
355
361
|
//#region package.json
|
|
356
|
-
var version = "5.3.
|
|
362
|
+
var version = "5.3.1";
|
|
357
363
|
//#endregion
|
|
358
364
|
//#region ../../internals/tanstack-query/src/utils.ts
|
|
359
365
|
/**
|
|
@@ -571,22 +577,61 @@ function classifyOperation(node, { query, mutation }) {
|
|
|
571
577
|
};
|
|
572
578
|
}
|
|
573
579
|
/**
|
|
580
|
+
* Helper to define a typed page param function for `infinite.getNextPageParam` or
|
|
581
|
+
* `infinite.getPreviousPageParam`. Serializes the function to a string for inlining in generated code.
|
|
582
|
+
*
|
|
583
|
+
* Note: Because the function is inlined verbatim into the generated file via `.toString()`,
|
|
584
|
+
* it must be self-contained and cannot reference local closures or external variables from
|
|
585
|
+
* the config file.
|
|
586
|
+
*/
|
|
587
|
+
function definePageParam(fn) {
|
|
588
|
+
return fn.toString();
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
574
591
|
* Applies the shared infinite-query defaults during plugin setup: a falsy value disables infinite
|
|
575
592
|
* queries, and an object merges over `queryParam: 'id'` and `initialPageParam: 0` with the cursor
|
|
576
593
|
* paths cleared.
|
|
577
594
|
*/
|
|
578
595
|
function resolveInfiniteConfig(infinite) {
|
|
579
596
|
if (!infinite) return false;
|
|
597
|
+
const hasExplicitInitialPageParam = infinite.hasExplicitInitialPageParam ?? infinite.initialPageParam !== void 0;
|
|
598
|
+
const getNextPageParam = infinite.getNextPageParam ? typeof infinite.getNextPageParam === "function" ? infinite.getNextPageParam.toString() : infinite.getNextPageParam : null;
|
|
599
|
+
const getPreviousPageParam = infinite.getPreviousPageParam ? typeof infinite.getPreviousPageParam === "function" ? infinite.getPreviousPageParam.toString() : infinite.getPreviousPageParam : null;
|
|
580
600
|
return {
|
|
581
601
|
queryParam: "id",
|
|
582
602
|
initialPageParam: 0,
|
|
603
|
+
hasExplicitInitialPageParam,
|
|
583
604
|
cursorParam: null,
|
|
584
605
|
nextParam: null,
|
|
585
606
|
previousParam: null,
|
|
586
|
-
|
|
607
|
+
getNextPageParam,
|
|
608
|
+
getPreviousPageParam,
|
|
609
|
+
...infinite,
|
|
610
|
+
...getNextPageParam ? { getNextPageParam } : {},
|
|
611
|
+
...getPreviousPageParam ? { getPreviousPageParam } : {}
|
|
587
612
|
};
|
|
588
613
|
}
|
|
589
614
|
/**
|
|
615
|
+
* Whether the infinite hook for `node` should be generated: the operation takes the configured
|
|
616
|
+
* `queryParam`.
|
|
617
|
+
*/
|
|
618
|
+
function matchesInfinite(node, infinite) {
|
|
619
|
+
if (!infinite.queryParam) return false;
|
|
620
|
+
return getOperationParameters(node).query.some((param) => param.name.replace(/\?$/, "") === infinite.queryParam);
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Warning for an infinite hook that falls back to the built-in page params on a response that
|
|
624
|
+
* isn't an array. Those params only stop on an empty array, so `hasNextPage` never turns false.
|
|
625
|
+
*/
|
|
626
|
+
function getDefaultPageParamsWarning(node, infinite) {
|
|
627
|
+
if (!(infinite.getNextPageParam == null && infinite.getPreviousPageParam == null && infinite.nextParam == null && infinite.previousParam == null && !infinite.cursorParam)) return null;
|
|
628
|
+
const content = getPrimarySuccessResponse(node)?.content;
|
|
629
|
+
let resolved = (content?.find((item) => item.contentType?.includes("json")) ?? content?.[0])?.schema;
|
|
630
|
+
while (resolved?.type === "ref" || resolved?.type === "intersection" && resolved.members?.length === 1) resolved = resolved.type === "ref" ? resolved.schema : resolved.members?.[0];
|
|
631
|
+
if (!resolved || resolved.type === "array") return null;
|
|
632
|
+
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.`;
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
590
635
|
* The request groups a query key is built from, matching `buildQueryKeyParams`. Headers are
|
|
591
636
|
* deliberately absent: they do not identify a cache entry, so the key factory takes no parameter
|
|
592
637
|
* for an operation that only carries headers.
|
|
@@ -600,7 +645,7 @@ const queryKeyGroupOrder = [
|
|
|
600
645
|
//#region ../../internals/tanstack-query/src/components/InfiniteQueryOptions.tsx
|
|
601
646
|
const declarationPrinter$7 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
602
647
|
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" }) {
|
|
648
|
+
function InfiniteQueryOptions$1({ name, clientName, initialPageParam, hasExplicitInitialPageParam, cursorParam, nextParam, previousParam, getNextPageParam, getPreviousPageParam, node, tsResolver, queryParam, queryKeyName, queryKeyType = "typeof queryKey", memberTypeWrapper, unwrapName, returnType = "full" }) {
|
|
604
649
|
const { TData: queryFnDataType, TError: errorType } = buildResponseTypes(node, tsResolver);
|
|
605
650
|
const { queryParamsTypeName, pageParamType } = resolvePageParamType(node, {
|
|
606
651
|
resolver: tsResolver,
|
|
@@ -624,18 +669,25 @@ function InfiniteQueryOptions$1({ name, clientName, initialPageParam, cursorPara
|
|
|
624
669
|
signal: true,
|
|
625
670
|
unwrapName
|
|
626
671
|
}), { returnType });
|
|
627
|
-
const
|
|
628
|
-
const
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
672
|
+
const initialPageParamLiteral = typeof initialPageParam === "string" || typeof initialPageParam === "object" && initialPageParam !== null ? JSON.stringify(initialPageParam) : String(initialPageParam === void 0 ? 0 : initialPageParam);
|
|
673
|
+
const serializedGetNextPageParam = typeof getNextPageParam === "function" ? getNextPageParam.toString() : getNextPageParam;
|
|
674
|
+
const getNextPageParamExpr = (() => {
|
|
675
|
+
if (serializedGetNextPageParam) return `getNextPageParam: ${serializedGetNextPageParam}`;
|
|
676
|
+
if (nextParam) return `getNextPageParam: (lastPage) => ${getNestedAccessor(nextParam, "lastPage")}`;
|
|
677
|
+
if (cursorParam) return `getNextPageParam: (lastPage) => lastPage['${cursorParam}']`;
|
|
678
|
+
return "getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage) && lastPage.length === 0 ? undefined : lastPageParam + 1";
|
|
679
|
+
})();
|
|
680
|
+
const serializedGetPreviousPageParam = typeof getPreviousPageParam === "function" ? getPreviousPageParam.toString() : getPreviousPageParam;
|
|
681
|
+
const defaultPreviousThreshold = hasExplicitInitialPageParam ? initialPageParamLiteral : "1";
|
|
682
|
+
const getPreviousPageParamExpr = (() => {
|
|
683
|
+
if (serializedGetPreviousPageParam) return `getPreviousPageParam: ${serializedGetPreviousPageParam}`;
|
|
684
|
+
if (previousParam) return `getPreviousPageParam: (firstPage) => ${getNestedAccessor(previousParam, "firstPage")}`;
|
|
685
|
+
if (cursorParam) return `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`;
|
|
686
|
+
if (serializedGetNextPageParam || nextParam) return null;
|
|
687
|
+
return `getPreviousPageParam: (_firstPage, _allPages, firstPageParam) => firstPageParam <= ${defaultPreviousThreshold} ? undefined : firstPageParam - 1`;
|
|
636
688
|
})();
|
|
637
689
|
const queryOptionsArr = [
|
|
638
|
-
`initialPageParam: ${
|
|
690
|
+
`initialPageParam: ${initialPageParamLiteral}`,
|
|
639
691
|
getNextPageParamExpr,
|
|
640
692
|
getPreviousPageParamExpr
|
|
641
693
|
].filter(Boolean);
|
|
@@ -1225,21 +1277,28 @@ function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, t
|
|
|
1225
1277
|
const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
|
|
1226
1278
|
name: "vue-query-infinite",
|
|
1227
1279
|
renderer: kubb_jsx.jsxRenderer,
|
|
1280
|
+
match(node, ctx) {
|
|
1281
|
+
const operationNode = node;
|
|
1282
|
+
if (!kubb_kit.ast.isHttpOperationNode(operationNode)) return false;
|
|
1283
|
+
const { query, mutation, infinite, hooks } = ctx.options;
|
|
1284
|
+
const { isQuery, isMutation } = classifyOperation(operationNode, {
|
|
1285
|
+
query,
|
|
1286
|
+
mutation
|
|
1287
|
+
});
|
|
1288
|
+
const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
|
|
1289
|
+
if (!isQuery || isMutation || !infiniteOptions || !hooks) return false;
|
|
1290
|
+
return matchesInfinite(operationNode, infiniteOptions);
|
|
1291
|
+
},
|
|
1228
1292
|
operation(node, ctx) {
|
|
1229
1293
|
if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
|
|
1230
1294
|
const { config, driver, resolver, root } = ctx;
|
|
1231
|
-
const { output, query,
|
|
1295
|
+
const { output, query, infinite, client, group } = ctx.options;
|
|
1296
|
+
const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
|
|
1297
|
+
if (!infiniteOptions) return null;
|
|
1298
|
+
const pageParamsWarning = getDefaultPageParamsWarning(node, infiniteOptions);
|
|
1299
|
+
if (pageParamsWarning) ctx.warn(pageParamsWarning);
|
|
1232
1300
|
const pluginTs = ctx.requirePlugin(_kubb_plugin_ts.pluginTsName);
|
|
1233
1301
|
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
1302
|
const importPath = query ? query.importPath : "@tanstack/vue-query";
|
|
1244
1303
|
const contractOp = resolveClientOperation({
|
|
1245
1304
|
clientPlugin: { pluginName: client.pluginName },
|
|
@@ -1358,7 +1417,10 @@ const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1358
1417
|
cursorParam: infiniteOptions.cursorParam,
|
|
1359
1418
|
nextParam: infiniteOptions.nextParam,
|
|
1360
1419
|
previousParam: infiniteOptions.previousParam,
|
|
1420
|
+
getNextPageParam: infiniteOptions.getNextPageParam,
|
|
1421
|
+
getPreviousPageParam: infiniteOptions.getPreviousPageParam,
|
|
1361
1422
|
initialPageParam: infiniteOptions.initialPageParam,
|
|
1423
|
+
hasExplicitInitialPageParam: infiniteOptions.hasExplicitInitialPageParam,
|
|
1362
1424
|
queryParam: infiniteOptions.queryParam,
|
|
1363
1425
|
returnType: contractOp.returnType
|
|
1364
1426
|
}),
|
|
@@ -1741,7 +1803,7 @@ const pluginVueQuery = (0, kubb_kit.definePlugin)({
|
|
|
1741
1803
|
meta: {
|
|
1742
1804
|
name: pluginVueQueryName,
|
|
1743
1805
|
version,
|
|
1744
|
-
compatibility
|
|
1806
|
+
compatibility
|
|
1745
1807
|
},
|
|
1746
1808
|
dependencies: { [_kubb_plugin_ts.pluginTsName]: {} },
|
|
1747
1809
|
setup(options) {
|
|
@@ -1775,6 +1837,7 @@ const pluginVueQuery = (0, kubb_kit.definePlugin)({
|
|
|
1775
1837
|
});
|
|
1776
1838
|
//#endregion
|
|
1777
1839
|
exports.default = pluginVueQuery;
|
|
1840
|
+
exports.definePageParam = definePageParam;
|
|
1778
1841
|
exports.pluginVueQuery = pluginVueQuery;
|
|
1779
1842
|
exports.pluginVueQueryName = pluginVueQueryName;
|
|
1780
1843
|
exports.resolverVueQuery = resolverVueQuery;
|