@kubb/plugin-vue-query 5.0.0-beta.10 → 5.0.0-beta.100

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.
Files changed (41) hide show
  1. package/README.md +22 -26
  2. package/dist/index.cjs +1629 -147
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +358 -6
  5. package/dist/index.js +1600 -145
  6. package/dist/index.js.map +1 -1
  7. package/package.json +9 -32
  8. package/dist/components-B6jAb2as.js +0 -1150
  9. package/dist/components-B6jAb2as.js.map +0 -1
  10. package/dist/components-X0P-3W2G.cjs +0 -1264
  11. package/dist/components-X0P-3W2G.cjs.map +0 -1
  12. package/dist/components.cjs +0 -9
  13. package/dist/components.d.ts +0 -187
  14. package/dist/components.js +0 -2
  15. package/dist/generators-B33PbKzu.js +0 -681
  16. package/dist/generators-B33PbKzu.js.map +0 -1
  17. package/dist/generators-BE3KD0IR.cjs +0 -698
  18. package/dist/generators-BE3KD0IR.cjs.map +0 -1
  19. package/dist/generators.cjs +0 -5
  20. package/dist/generators.d.ts +0 -15
  21. package/dist/generators.js +0 -2
  22. package/dist/types-Bkm7bWT3.d.ts +0 -243
  23. package/extension.yaml +0 -732
  24. package/src/components/InfiniteQuery.tsx +0 -120
  25. package/src/components/InfiniteQueryOptions.tsx +0 -201
  26. package/src/components/Mutation.tsx +0 -148
  27. package/src/components/MutationKey.tsx +0 -1
  28. package/src/components/Query.tsx +0 -119
  29. package/src/components/QueryKey.tsx +0 -51
  30. package/src/components/QueryOptions.tsx +0 -134
  31. package/src/components/index.ts +0 -7
  32. package/src/generators/index.ts +0 -3
  33. package/src/generators/infiniteQueryGenerator.tsx +0 -194
  34. package/src/generators/mutationGenerator.tsx +0 -153
  35. package/src/generators/queryGenerator.tsx +0 -179
  36. package/src/index.ts +0 -2
  37. package/src/plugin.ts +0 -167
  38. package/src/resolvers/resolverVueQuery.ts +0 -65
  39. package/src/types.ts +0 -245
  40. package/src/utils.ts +0 -49
  41. /package/dist/{chunk--u3MIqq1.js → rolldown-runtime-C0LytTxp.js} +0 -0
package/dist/index.cjs CHANGED
@@ -2,149 +2,1653 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_components = require("./components-X0P-3W2G.cjs");
6
- const require_generators = require("./generators-BE3KD0IR.cjs");
5
+ //#region \0rolldown/runtime.js
6
+ var __create = Object.create;
7
+ var __defProp = Object.defineProperty;
8
+ var __name = (target, value) => __defProp(target, "name", {
9
+ value,
10
+ configurable: true
11
+ });
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
18
+ key = keys[i];
19
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
20
+ get: ((k) => from[k]).bind(null, key),
21
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
22
+ });
23
+ }
24
+ return to;
25
+ };
26
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
27
+ value: mod,
28
+ enumerable: true
29
+ }) : target, mod));
30
+ //#endregion
31
+ let kubb_kit = require("kubb/kit");
7
32
  let node_path = require("node:path");
8
- node_path = require_components.__toESM(node_path, 1);
9
- let _kubb_core = require("@kubb/core");
10
- let _kubb_plugin_client = require("@kubb/plugin-client");
11
- let _kubb_plugin_client_templates_clients_axios_source = require("@kubb/plugin-client/templates/clients/axios.source");
12
- let _kubb_plugin_client_templates_clients_fetch_source = require("@kubb/plugin-client/templates/clients/fetch.source");
13
- let _kubb_plugin_client_templates_config_source = require("@kubb/plugin-client/templates/config.source");
33
+ node_path = __toESM(node_path, 1);
14
34
  let _kubb_plugin_ts = require("@kubb/plugin-ts");
15
- let _kubb_plugin_zod = require("@kubb/plugin-zod");
16
- //#region src/resolvers/resolverVueQuery.ts
17
- function capitalize(name) {
18
- return `${name.charAt(0).toUpperCase()}${name.slice(1)}`;
35
+ let kubb_jsx = require("kubb/jsx");
36
+ let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
37
+ //#region ../../internals/shared/src/params.ts
38
+ /**
39
+ * Drops parameters that share the same name, keeping the first.
40
+ *
41
+ * A malformed spec can declare the same parameter name twice within one `in` location. Both would
42
+ * resolve to the same output property, so emitting both would yield an object type with a duplicate
43
+ * member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:
44
+ * parameter names flow through unchanged, so no two distinct names ever collide here anymore.
45
+ */
46
+ function dedupeParams(params) {
47
+ const seen = /* @__PURE__ */ new Set();
48
+ return params.filter((param) => {
49
+ if (seen.has(param.name)) return false;
50
+ seen.add(param.name);
51
+ return true;
52
+ });
53
+ }
54
+ //#endregion
55
+ //#region ../../internals/shared/src/operation.ts
56
+ /**
57
+ * Builds the `ResolverFileParams` every operation generator passes to
58
+ * `resolver.file`: a file named `name`, tagged by the operation's first
59
+ * tag (or `'default'`), at the operation's path. Centralizes the entry object
60
+ * that was repeated at dozens of call sites across the client and query plugins.
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * resolver.file(operationFileEntry(node, node.operationId), { root, output, group })
65
+ * ```
66
+ */
67
+ function operationFileEntry(node, name, extname = ".ts") {
68
+ return {
69
+ name,
70
+ extname,
71
+ tag: node.tags[0] ?? "default",
72
+ path: node.path
73
+ };
74
+ }
75
+ function getOperationLink(node, link) {
76
+ if (!link) return null;
77
+ if (typeof link === "function") return link(node) ?? null;
78
+ return node.path ? `{@link ${kubb_kit.Url.toPath(node.path)}}` : null;
79
+ }
80
+ /**
81
+ * Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several
82
+ * are present and the union, default, and form-data flags the client uses to pick one.
83
+ */
84
+ function buildContentTypeInfo(contentTypes) {
85
+ const isMultipleContentTypes = contentTypes.length > 1;
86
+ return {
87
+ contentTypes,
88
+ isMultipleContentTypes,
89
+ contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(" | ") : "",
90
+ defaultContentType: contentTypes[0] ?? "application/json",
91
+ hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
92
+ };
93
+ }
94
+ function getContentTypeInfo(node) {
95
+ return buildContentTypeInfo(node.requestBody?.content?.map((e) => e.contentType) ?? []);
96
+ }
97
+ /**
98
+ * The request-body counterpart for the primary success response: the content types it documents and
99
+ * whether several are present, so the client can let a caller pick which one to accept.
100
+ */
101
+ function getResponseContentTypeInfo(node) {
102
+ return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? []);
103
+ }
104
+ function buildRequestConfigType(node) {
105
+ const request = getContentTypeInfo(node);
106
+ const response = getResponseContentTypeInfo(node);
107
+ const configType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
108
+ const members = [request.isMultipleContentTypes ? `request?: ${request.contentTypeUnion}` : null, response.isMultipleContentTypes ? `response?: ${response.contentTypeUnion}` : null].filter(Boolean);
109
+ return members.length ? `${configType} & { contentType?: { ${members.join("; ")} } }` : configType;
110
+ }
111
+ /**
112
+ * Builds the `client?:` option type shared by the generated query hooks (`useQuery`,
113
+ * `useInfiniteQuery`, `useSWR`, ...). Unlike {@link buildRequestConfigType}, it never adds a
114
+ * `contentType?:` member: query hooks wrap GET operations, which carry no request body to select a
115
+ * content type for.
116
+ */
117
+ function buildClientOptionType() {
118
+ return `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
119
+ }
120
+ /**
121
+ * Which of the grouped request options an operation carries.
122
+ */
123
+ function getRequestGroups(node) {
124
+ const { path, query, header } = getOperationParameters(node);
125
+ return {
126
+ path: path.length > 0,
127
+ query: query.length > 0,
128
+ body: Boolean(node.requestBody?.content?.[0]?.schema),
129
+ headers: header.length > 0
130
+ };
131
+ }
132
+ /**
133
+ * Resolves which grouped request options an operation carries together with whether each group
134
+ * holds a required member. The grouped parameter stays optional only when nothing inside it is
135
+ * required, matching the generated `RequestConfig` type.
136
+ */
137
+ function getRequestGroupOptionality(node) {
138
+ const groups = getRequestGroups(node);
139
+ const { path, query, header } = getOperationParameters(node);
140
+ const hasRequiredPath = path.some((param) => param.required);
141
+ const hasRequiredQuery = query.some((param) => param.required);
142
+ const hasRequiredHeader = header.some((param) => param.required);
143
+ return {
144
+ groups,
145
+ hasRequiredPath,
146
+ hasRequiredQuery,
147
+ hasRequiredHeader,
148
+ isOptional: !hasRequiredPath && !hasRequiredQuery && !hasRequiredHeader && !groups.body
149
+ };
150
+ }
151
+ function buildOperationComments(node, options = {}) {
152
+ const { link = "pathTemplate", linkPosition = "afterDeprecated", splitLines = false } = options;
153
+ const linkComment = getOperationLink(node, link);
154
+ const filteredComments = (linkPosition === "beforeDeprecated" ? [
155
+ node.description && `@description ${node.description}`,
156
+ node.summary && `@summary ${node.summary}`,
157
+ linkComment,
158
+ node.deprecated && "@deprecated"
159
+ ] : [
160
+ node.description && `@description ${node.description}`,
161
+ node.summary && `@summary ${node.summary}`,
162
+ node.deprecated && "@deprecated",
163
+ linkComment
164
+ ]).filter((comment) => Boolean(comment));
165
+ if (!splitLines) return filteredComments;
166
+ return filteredComments.flatMap((text) => text.split(/\r?\n/).map((line) => line.trim())).filter((comment) => Boolean(comment));
167
+ }
168
+ function getOperationParameters(node) {
169
+ return {
170
+ path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
171
+ query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
172
+ header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
173
+ cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
174
+ };
175
+ }
176
+ function getStatusCodeNumber(statusCode) {
177
+ const code = Number(statusCode);
178
+ return Number.isNaN(code) ? null : code;
179
+ }
180
+ function isSuccessStatusCode(statusCode) {
181
+ const code = getStatusCodeNumber(statusCode);
182
+ return code !== null && code >= 200 && code < 300;
183
+ }
184
+ function isErrorStatusCode(statusCode) {
185
+ const code = getStatusCodeNumber(statusCode);
186
+ return code !== null && code >= 400;
187
+ }
188
+ function getSuccessResponses(responses) {
189
+ return responses.filter((response) => isSuccessStatusCode(response.statusCode));
190
+ }
191
+ function getOperationSuccessResponses(node) {
192
+ return getSuccessResponses(node.responses);
193
+ }
194
+ function getPrimarySuccessResponse(node) {
195
+ return getOperationSuccessResponses(node)[0] ?? null;
196
+ }
197
+ function resolveErrorNames(node, resolver) {
198
+ return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode));
199
+ }
200
+ function resolveSuccessNames(node, resolver) {
201
+ return node.responses.filter((response) => isSuccessStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode));
202
+ }
203
+ function resolveStatusCodeNames(node, resolver) {
204
+ return node.responses.map((response) => resolver.response.status(node, response.statusCode));
205
+ }
206
+ const typeNamesByResolver = /* @__PURE__ */ new WeakMap();
207
+ function resolveOperationTypeNames(node, resolver, options = {}) {
208
+ const cacheKey = `${node.operationId}\0${options.order ?? ""}\0${options.responseStatusNames ?? ""}\0${options.includeParams === false ? "noparams" : ""}\0${(options.exclude ?? []).join(",")}`;
209
+ let byResolver = typeNamesByResolver.get(resolver);
210
+ if (byResolver) {
211
+ const cached = byResolver.get(cacheKey);
212
+ if (cached) return cached;
213
+ } else {
214
+ byResolver = /* @__PURE__ */ new Map();
215
+ typeNamesByResolver.set(resolver, byResolver);
216
+ }
217
+ const { path, query, header } = getOperationParameters(node);
218
+ const responseStatusNames = options.responseStatusNames === "error" ? resolveErrorNames(node, resolver) : options.responseStatusNames === false ? [] : resolveStatusCodeNames(node, resolver);
219
+ const exclude = new Set(options.exclude ?? []);
220
+ const paramNames = options.includeParams === false ? [] : [
221
+ ...path.map((param) => resolver.param.path(node, param)),
222
+ ...query.map((param) => resolver.param.query(node, param)),
223
+ ...header.map((param) => resolver.param.headers(node, param))
224
+ ];
225
+ const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.response.body(node) : null, resolver.response.response(node)];
226
+ const result = (options.order === "body-response-first" ? [
227
+ ...bodyAndResponseNames,
228
+ ...paramNames,
229
+ ...responseStatusNames
230
+ ] : [
231
+ ...paramNames,
232
+ ...bodyAndResponseNames,
233
+ ...responseStatusNames
234
+ ]).filter((name) => Boolean(name) && !exclude.has(name));
235
+ byResolver.set(cacheKey, result);
236
+ return result;
237
+ }
238
+ //#endregion
239
+ //#region ../../internals/utils/src/casing.ts
240
+ /**
241
+ * Shared implementation for camelCase and PascalCase conversion.
242
+ * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
243
+ * and capitalizes each word according to `pascal`.
244
+ *
245
+ * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
246
+ */
247
+ function toCamelOrPascal(text, pascal) {
248
+ return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
249
+ if (word.length > 1 && word === word.toUpperCase()) return word;
250
+ return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
251
+ }).join("").replace(/[^a-zA-Z0-9]/g, "");
252
+ }
253
+ /**
254
+ * Converts `text` to camelCase.
255
+ *
256
+ * @example Word boundaries
257
+ * `camelCase('hello-world') // 'helloWorld'`
258
+ *
259
+ * @example With a prefix
260
+ * `camelCase('tag', { prefix: 'create' }) // 'createTag'`
261
+ */
262
+ function camelCase(text, { prefix = "", suffix = "" } = {}) {
263
+ return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
264
+ }
265
+ /**
266
+ * Uppercases only the first character of `text`, leaving the rest untouched.
267
+ * Unlike {@link pascalCase} it never re-splits word boundaries or strips characters.
268
+ *
269
+ * @example
270
+ * `capitalize('getPetById') // 'GetPetById'`
271
+ */
272
+ function capitalize(text) {
273
+ return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
274
+ }
275
+ //#endregion
276
+ //#region ../../internals/utils/src/strings.ts
277
+ /**
278
+ * Renders a dotted path or string array as an optional-chaining accessor expression rooted at
279
+ * `accessor`. Returns `null` for an empty path.
280
+ *
281
+ * @example
282
+ * ```ts
283
+ * getNestedAccessor('pagination.next.id', 'lastPage')
284
+ * // "lastPage?.['pagination']?.['next']?.['id']"
285
+ * ```
286
+ */
287
+ function getNestedAccessor(param, accessor) {
288
+ const parts = Array.isArray(param) ? param : param.split(".");
289
+ if (parts.length === 0 || parts.length === 1 && parts[0] === "") return null;
290
+ return `${accessor}?.['${`${parts.join("']?.['")}']`}`;
291
+ }
292
+ //#endregion
293
+ //#region ../../internals/shared/src/group.ts
294
+ /**
295
+ * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
296
+ * shared default naming so every plugin groups output consistently:
297
+ *
298
+ * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).
299
+ * - other groups use the camelCased group (`pet store` → `petStore`).
300
+ *
301
+ * A user-provided `group.name` always wins over the default namer, so callers stay in
302
+ * control of their output folders. Returns `null` when grouping is disabled, matching the
303
+ * per-plugin convention.
304
+ *
305
+ * @param group - The user-supplied group option, or `undefined` to disable grouping.
306
+ *
307
+ * @example
308
+ * ```ts
309
+ * createGroupConfig(group) // shared across every plugin
310
+ * ```
311
+ */
312
+ function createGroupConfig(group) {
313
+ if (!group) return null;
314
+ const defaultName = (ctx) => {
315
+ if (group.type === "path") return `${ctx.group.split("/")[1]}`;
316
+ return camelCase(ctx.group);
317
+ };
318
+ return {
319
+ ...group,
320
+ name: group.name ? group.name : defaultName
321
+ };
322
+ }
323
+ //#endregion
324
+ //#region ../../internals/tanstack-query/src/utils.ts
325
+ /**
326
+ * The grouped request options, ordered for both the destructured signature and the
327
+ * call passed to the underlying client.
328
+ */
329
+ const requestGroupOrder = [
330
+ "path",
331
+ "query",
332
+ "body",
333
+ "headers"
334
+ ];
335
+ /**
336
+ * Widens a request-group member type so a generated TanStack hook accepts either the value or a
337
+ * deferred value. Both plugins apply this through the `memberTypeWrapper` of `buildGroupedRequestParam`;
338
+ * they only differ in how the deferred form is later resolved.
339
+ *
340
+ * `maybeRefOrGetter` is used by vue-query, which keeps the ref/getter live and unwraps it lazily with
341
+ * `toValue` because vue-query keys are reactive. `maybeValueOrGetter` is used by react-query, which
342
+ * resolves the getter once at the hook boundary and forwards a plain value because React Query hashes
343
+ * keys structurally and cannot hold a function.
344
+ */
345
+ function maybeRefOrGetter(type) {
346
+ return `MaybeRefOrGetter<${type}>`;
347
+ }
348
+ /**
349
+ * Builds the grouped `{ path, query, body, headers }` parameter that mirrors the client
350
+ * function signature. Only the groups the operation carries are emitted, typed from the
351
+ * operation's `Options`. `keys` narrows the emitted groups, used by the query key which
352
+ * never carries `headers`.
353
+ *
354
+ * By default the whole group is typed as the single `Options` reference. When
355
+ * `memberTypeWrapper` is set, each group is emitted as its own member typed from the matching
356
+ * `Options['<group>']` slice and wrapped, used by vue-query to apply
357
+ * `MaybeRefOrGetter` per group.
358
+ */
359
+ function buildGroupedRequestParam(node, options) {
360
+ const { resolver, keys = requestGroupOrder, memberTypeWrapper } = options;
361
+ const { groups, hasRequiredPath, hasRequiredQuery, hasRequiredHeader } = getRequestGroupOptionality(node);
362
+ const names = keys.filter((key) => groups[key]);
363
+ if (names.length === 0) return null;
364
+ const requiredByGroup = {
365
+ path: hasRequiredPath,
366
+ query: hasRequiredQuery,
367
+ body: groups.body,
368
+ headers: hasRequiredHeader
369
+ };
370
+ const isOptional = names.every((name) => !requiredByGroup[name]);
371
+ const optionsName = resolver.response.options(node);
372
+ const omittedKeys = requestGroupOrder.filter((key) => !keys.includes(key));
373
+ const optionsType = omittedKeys.length > 0 ? `Omit<${optionsName}, ${omittedKeys.map((key) => `'${key}'`).join(" | ")}>` : optionsName;
374
+ if (memberTypeWrapper) {
375
+ const members = names.map((name) => ({
376
+ name,
377
+ type: memberTypeWrapper(`${optionsType}['${name}']`),
378
+ optional: !requiredByGroup[name]
379
+ }));
380
+ return (0, _kubb_plugin_ts.createFunctionParameter)({
381
+ name: (0, _kubb_plugin_ts.createObjectBindingPattern)({ elements: names.map((name) => ({ name })) }),
382
+ type: (0, _kubb_plugin_ts.createTypeLiteral)({ members }),
383
+ optional: false,
384
+ ...isOptional ? { default: "{}" } : {}
385
+ });
386
+ }
387
+ return (0, _kubb_plugin_ts.createFunctionParameter)({
388
+ name: (0, _kubb_plugin_ts.createObjectBindingPattern)({ elements: names.map((name) => ({ name })) }),
389
+ type: optionsType,
390
+ optional: false,
391
+ ...isOptional ? { default: "{}" } : {}
392
+ });
393
+ }
394
+ /**
395
+ * Builds the shared `({ path, query, body, headers }, config = {})` parameter list for a
396
+ * TanStack query-options function. The leading parameter mirrors the client signature, and the
397
+ * trailing `config` is a partial `RequestConfig` minus the grouped data-shape keys, which are passed
398
+ * explicitly. Framework plugins wrap the result when needed, for example vue-query applies `MaybeRefOrGetter`.
399
+ */
400
+ function buildQueryOptionsParams(node, options) {
401
+ const { resolver, memberTypeWrapper } = options;
402
+ return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [buildGroupedRequestParam(node, {
403
+ resolver,
404
+ memberTypeWrapper
405
+ }), (0, _kubb_plugin_ts.createFunctionParameter)({
406
+ name: "config",
407
+ type: `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`,
408
+ default: "{}"
409
+ })].filter((param) => param !== null) });
410
+ }
411
+ /**
412
+ * Builds the call to a client `<op>` function inside a query/mutation hook body. The function takes
413
+ * a single grouped options object, so the operation's request groups are passed as
414
+ * shorthand alongside the spread `config`, with `throwOnError: true` pinned last so a caller's config
415
+ * can't flip the query's error semantics. Queries thread the TanStack `signal`; mutations omit it.
416
+ *
417
+ * When `unwrapName` is set, each request group is passed as an explicit member unwrapped through it,
418
+ * used by vue-query to resolve refs and getters with `toValue(...)` at call time.
419
+ *
420
+ * @example
421
+ * ```ts
422
+ * buildClientCall(node, { clientName: 'getPetById', signal: true })
423
+ * // getPetById({ path, ...config, signal: config.signal ?? signal, throwOnError: true })
424
+ * ```
425
+ */
426
+ function buildClientCall(node, options) {
427
+ const { clientName, signal = false, unwrapName } = options;
428
+ const { groups } = getRequestGroupOptionality(node);
429
+ return `${clientName}({ ${[
430
+ "...config",
431
+ ...requestGroupOrder.filter((key) => groups[key]).map((name) => unwrapName ? `${name}: ${unwrapName(name)}` : name),
432
+ signal ? "signal: config.signal ?? signal" : null,
433
+ "throwOnError: true"
434
+ ].filter((part) => part !== null).join(", ")} })`;
435
+ }
436
+ /**
437
+ * Builds the `TData` / `TError` type expressions shared by every generated hook, joining the resolved
438
+ * success responses into `TData` and wrapping the error responses in `ResponseErrorConfig<...>`.
439
+ */
440
+ function buildResponseTypes(node, resolver) {
441
+ const successNames = resolveSuccessNames(node, resolver);
442
+ const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
443
+ const errorNames = resolveErrorNames(node, resolver);
444
+ return {
445
+ TData: responseName,
446
+ TError: `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`
447
+ };
448
+ }
449
+ function resolveFallbackPageParamType(initialPageParam) {
450
+ if (typeof initialPageParam === "number") return "number";
451
+ if (typeof initialPageParam === "boolean") return "boolean";
452
+ if (typeof initialPageParam !== "string") return "unknown";
453
+ if (!initialPageParam.includes(" as ")) return "string";
454
+ return initialPageParam.split(" as ").at(-1) ?? "unknown";
455
+ }
456
+ /**
457
+ * Resolves the `TPageParam` generic for the infinite-query hooks. Prefers the type read from the
458
+ * configured `queryParam` on the operation's query object, and falls back to the type inferred from
459
+ * `initialPageParam` when that parameter type is unavailable. Also returns the query params type name
460
+ * so callers can reuse it when rewriting the paginated request.
461
+ */
462
+ function resolvePageParamType(node, { resolver, initialPageParam, queryParam }) {
463
+ const firstQueryParam = getOperationParameters(node).query[0];
464
+ const groupName = firstQueryParam ? resolver.param.query(node, firstQueryParam) : null;
465
+ const queryParamsTypeName = groupName !== (firstQueryParam ? resolver.param.name(node, firstQueryParam) : null) ? groupName : null;
466
+ const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
467
+ if (!queryParamType) return {
468
+ queryParamsTypeName,
469
+ pageParamType: resolveFallbackPageParamType(initialPageParam)
470
+ };
471
+ return {
472
+ queryParamsTypeName,
473
+ pageParamType: initialPageParam !== void 0 && initialPageParam !== null ? `NonNullable<${queryParamType}>` : queryParamType
474
+ };
475
+ }
476
+ /**
477
+ * Applies the shared query defaults during plugin setup: `false` disables query generation, and an
478
+ * object merges over `methods: ['GET']` and the plugin's runtime `importPath`.
479
+ */
480
+ function resolveQueryConfig(query, options) {
481
+ if (query === false) return false;
482
+ return {
483
+ importPath: options.importPath,
484
+ methods: ["GET"],
485
+ ...query
486
+ };
487
+ }
488
+ /**
489
+ * Applies the shared mutation defaults during plugin setup: `false` disables mutation generation,
490
+ * and an object merges over `methods: ['POST', 'PUT', 'PATCH', 'DELETE']` and the plugin's runtime
491
+ * `importPath`.
492
+ */
493
+ function resolveMutationConfig(mutation, options) {
494
+ if (mutation === false) return false;
495
+ return {
496
+ importPath: options.importPath,
497
+ methods: [
498
+ "POST",
499
+ "PUT",
500
+ "PATCH",
501
+ "DELETE"
502
+ ],
503
+ ...mutation
504
+ };
505
+ }
506
+ /**
507
+ * Applies the shared infinite-query defaults during plugin setup: a falsy value disables infinite
508
+ * queries, and an object merges over `queryParam: 'id'` and `initialPageParam: 0` with the cursor
509
+ * paths cleared.
510
+ */
511
+ function resolveInfiniteConfig(infinite) {
512
+ if (!infinite) return false;
513
+ return {
514
+ queryParam: "id",
515
+ initialPageParam: 0,
516
+ cursorParam: null,
517
+ nextParam: null,
518
+ previousParam: null,
519
+ ...infinite
520
+ };
521
+ }
522
+ //#endregion
523
+ //#region ../../internals/tanstack-query/src/components/InfiniteQueryOptions.tsx
524
+ const declarationPrinter$7 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
525
+ const callPrinter$4 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
526
+ function InfiniteQueryOptions$1({ name, clientName, initialPageParam, cursorParam, nextParam, previousParam, node, tsResolver, queryParam, queryKeyName, queryKeyType = "typeof queryKey", memberTypeWrapper, unwrapName }) {
527
+ const { TData: queryFnDataType, TError: errorType } = buildResponseTypes(node, tsResolver);
528
+ const { queryParamsTypeName, pageParamType } = resolvePageParamType(node, {
529
+ resolver: tsResolver,
530
+ initialPageParam,
531
+ queryParam
532
+ });
533
+ const groupedKeyParam = buildGroupedRequestParam(node, {
534
+ resolver: tsResolver,
535
+ keys: [
536
+ "path",
537
+ "query",
538
+ "body"
539
+ ],
540
+ memberTypeWrapper
541
+ });
542
+ const queryKeyParamsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedKeyParam ? [groupedKeyParam] : [] });
543
+ const queryKeyParamsCall = callPrinter$4.print(queryKeyParamsNode) ?? "";
544
+ const paramsNode = buildQueryOptionsParams(node, {
545
+ resolver: tsResolver,
546
+ memberTypeWrapper
547
+ });
548
+ const paramsSignature = declarationPrinter$7.print(paramsNode) ?? "";
549
+ const queryFnBody = `const { data } = await ${buildClientCall(node, {
550
+ clientName,
551
+ signal: true,
552
+ unwrapName
553
+ })}
554
+ return data`;
555
+ const hasNewParams = nextParam != null || previousParam != null;
556
+ const [getNextPageParamExpr, getPreviousPageParamExpr] = (() => {
557
+ if (hasNewParams) {
558
+ const nextAccessor = nextParam ? getNestedAccessor(nextParam, "lastPage") : null;
559
+ const prevAccessor = previousParam ? getNestedAccessor(previousParam, "firstPage") : null;
560
+ return [nextAccessor ? `getNextPageParam: (lastPage) => ${nextAccessor}` : null, prevAccessor ? `getPreviousPageParam: (firstPage) => ${prevAccessor}` : null];
561
+ }
562
+ if (cursorParam) return [`getNextPageParam: (lastPage) => lastPage['${cursorParam}']`, `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`];
563
+ return ["getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage) && lastPage.length === 0 ? undefined : lastPageParam + 1", "getPreviousPageParam: (_firstPage, _allPages, firstPageParam) => firstPageParam <= 1 ? undefined : firstPageParam - 1"];
564
+ })();
565
+ const queryOptionsArr = [
566
+ `initialPageParam: ${typeof initialPageParam === "string" ? JSON.stringify(initialPageParam) : initialPageParam}`,
567
+ getNextPageParamExpr,
568
+ getPreviousPageParamExpr
569
+ ].filter(Boolean);
570
+ const infiniteOverrideParams = queryParam && queryParamsTypeName ? `query = {
571
+ ...(query ?? {}),
572
+ ['${queryParam}']: pageParam as unknown as ${queryParamsTypeName}['${queryParam}'],
573
+ } as ${queryParamsTypeName}` : "";
574
+ const queryFnArgs = infiniteOverrideParams ? "{ signal, pageParam }" : "{ signal }";
575
+ const queryFnStatements = infiniteOverrideParams ? `${infiniteOverrideParams}\n ${queryFnBody}` : queryFnBody;
576
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
577
+ name,
578
+ isExportable: true,
579
+ isIndexable: true,
580
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
581
+ name,
582
+ export: true,
583
+ params: paramsSignature,
584
+ children: `
585
+ const queryKey = ${queryKeyName}(${queryKeyParamsCall})
586
+ return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${queryFnDataType}>, ${queryKeyType}, ${pageParamType}>({
587
+ queryKey,
588
+ queryFn: async (${queryFnArgs}) => {
589
+ ${queryFnStatements}
590
+ },
591
+ ${queryOptionsArr.join(",\n ")}
592
+ })
593
+ `
594
+ })
595
+ });
596
+ }
597
+ __name(InfiniteQueryOptions$1, "InfiniteQueryOptions");
598
+ //#endregion
599
+ //#region ../../internals/tanstack-query/src/components/MutationKey.tsx
600
+ const declarationPrinter$6 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
601
+ const mutationKeyTransformer = ({ node }) => {
602
+ if (!node.path) return [];
603
+ return [`{ url: '${kubb_kit.Url.toPath(node.path)}' }`];
604
+ };
605
+ function MutationKey({ name, node, transformer }) {
606
+ const paramsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: [] });
607
+ const paramsSignature = declarationPrinter$6.print(paramsNode) ?? "";
608
+ const keys = (transformer ?? mutationKeyTransformer)({
609
+ node,
610
+ casing: "camelcase"
611
+ });
612
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
613
+ name,
614
+ isExportable: true,
615
+ isIndexable: true,
616
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function.Arrow, {
617
+ name,
618
+ export: true,
619
+ params: paramsSignature,
620
+ singleLine: true,
621
+ children: `[${keys.join(", ")}] as const`
622
+ })
623
+ });
624
+ }
625
+ //#endregion
626
+ //#region ../../internals/tanstack-query/src/resolver.ts
627
+ /**
628
+ * Builds the shared query namespace for a variant. Spread the result into
629
+ * `createResolver` once per variant the plugin supports.
630
+ *
631
+ * @example
632
+ * ```ts
633
+ * createResolver<PluginReactQuery>({
634
+ * query: createQueryResolver(),
635
+ * suspenseQuery: createQueryResolver('Suspense'),
636
+ * })
637
+ * ```
638
+ */
639
+ function createQueryResolver(variant = "") {
640
+ return {
641
+ name(node) {
642
+ return `use${capitalize(this.name(node.operationId))}${variant}`;
643
+ },
644
+ optionsName(node) {
645
+ return `${this.name(node.operationId)}${variant}QueryOptions`;
646
+ },
647
+ keyName(node) {
648
+ return `${this.name(node.operationId)}${variant}QueryKey`;
649
+ },
650
+ keyTypeName(node) {
651
+ return `${capitalize(this.name(node.operationId))}${variant}QueryKey`;
652
+ },
653
+ clientName(node) {
654
+ return `${this.name(node.operationId)}${variant}`;
655
+ }
656
+ };
657
+ }
658
+ /**
659
+ * Builds the shared mutation namespace. Spread the result into
660
+ * `createResolver` and add plugin-specific methods (`optionsName`,
661
+ * `typeName`, `argTypeName`) next to it.
662
+ *
663
+ * @example
664
+ * ```ts
665
+ * createResolver<PluginSwr>({ mutation: { ...createMutationResolver(), argTypeName(node) {...} } })
666
+ * ```
667
+ */
668
+ function createMutationResolver() {
669
+ return {
670
+ name(node) {
671
+ return `use${capitalize(this.name(node.operationId))}`;
672
+ },
673
+ keyName(node) {
674
+ return `${this.name(node.operationId)}MutationKey`;
675
+ }
676
+ };
19
677
  }
678
+ (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
679
+ const queryKeyTransformer = ({ node }) => {
680
+ if (!node.path) return [];
681
+ const hasPathParams = getOperationParameters(node).path.length > 0;
682
+ const hasQueryParams = getOperationParameters(node).query.length > 0;
683
+ const hasRequestBody = !!node.requestBody?.content?.[0]?.schema;
684
+ return [
685
+ hasPathParams ? `{ url: '${kubb_kit.Url.toPath(node.path)}', params: path }` : `{ url: '${kubb_kit.Url.toPath(node.path)}' }`,
686
+ hasQueryParams ? "...(query ? [query] : [])" : null,
687
+ hasRequestBody ? "...(body ? [body] : [])" : null
688
+ ].filter(Boolean);
689
+ };
690
+ //#endregion
691
+ //#region ../../internals/client/src/resolveClient.ts
20
692
  /**
21
- * Naming convention resolver for Vue Query plugin.
693
+ * Resolves which client plugin a consumer (react-query, vue-query, swr, mcp) should call for an
694
+ * operation, shared so the selection rules and diagnostics stay in one place.
22
695
  *
23
- * Provides default naming helpers using camelCase for functions and file paths.
696
+ * Every client runtime lives in a dedicated client plugin, so a consumer always calls a registered
697
+ * contract client plugin (plugin-fetch or plugin-axios) and never emits its own inline client:
698
+ *
699
+ * - `contract` — a registered contract client plugin owns the `<op>` functions and the consumer
700
+ * imports and calls them.
701
+ * - `error` — no client plugin is registered, several are registered without a selector, or the
702
+ * requested one is missing.
703
+ *
704
+ * The `client` string selects explicitly (`'fetch'` / `'axios'`); when it is unset a lone registered
705
+ * contract client plugin is picked up automatically.
24
706
  */
25
- const resolverVueQuery = (0, _kubb_core.defineResolver)(() => ({
26
- name: "default",
707
+ const pluginFetchName = "plugin-fetch";
708
+ const pluginAxiosName = "plugin-axios";
709
+ const selectorToPlugin = {
710
+ fetch: pluginFetchName,
711
+ axios: pluginAxiosName
712
+ };
713
+ const contractPlugins = [pluginFetchName, pluginAxiosName];
714
+ /**
715
+ * Applies the `client` resolution rules. See the module comment for the strategy shape.
716
+ *
717
+ * @example
718
+ * ```ts
719
+ * resolveClient({ client: 'fetch', pluginNames: ['plugin-ts', 'plugin-fetch'] })
720
+ * // { kind: 'contract', pluginName: 'plugin-fetch' }
721
+ * ```
722
+ *
723
+ * @example
724
+ * ```ts
725
+ * resolveClient({ client: undefined, pluginNames: ['plugin-ts'] })
726
+ * // { kind: 'error', message: 'No client plugin is registered…' }
727
+ * ```
728
+ */
729
+ function resolveClient(options) {
730
+ const { client, pluginNames } = options;
731
+ const has = (name) => pluginNames.includes(name);
732
+ if (client === "fetch" || client === "axios") {
733
+ const pluginName = selectorToPlugin[client];
734
+ if (!has(pluginName)) return {
735
+ kind: "error",
736
+ message: `\`client: '${client}'\` is set but \`@kubb/plugin-${client}\` is not registered in \`plugins\`. Add it, or drop \`client\` to use a different client plugin.`
737
+ };
738
+ return {
739
+ kind: "contract",
740
+ pluginName
741
+ };
742
+ }
743
+ const registered = contractPlugins.filter(has);
744
+ if (registered.length === 1) return {
745
+ kind: "contract",
746
+ pluginName: registered[0]
747
+ };
748
+ if (registered.length > 1) return {
749
+ kind: "error",
750
+ message: `Multiple client plugins are registered (${registered.map((name) => `\`@kubb/${name}\``).join(", ")}). Set \`client: 'fetch' | 'axios'\` to choose which client the hooks call, or register a single client plugin.`
751
+ };
752
+ return {
753
+ kind: "error",
754
+ message: "No client plugin is registered. Add `@kubb/plugin-axios` or `@kubb/plugin-fetch` to `plugins` so the generated code has an HTTP client to call."
755
+ };
756
+ }
757
+ /**
758
+ * Resolves the contract client during a consumer plugin's setup hook. Extracts the plugin names
759
+ * from the raw `plugins` config, applies {@link resolveClient}, and throws the diagnostic on a
760
+ * misconfiguration so every consumer fails fast with the same message.
761
+ */
762
+ function resolveContractClient(options) {
763
+ const { client, plugins = [] } = options;
764
+ const resolved = resolveClient({
765
+ client,
766
+ pluginNames: plugins.map((plugin) => plugin.name).filter((name) => Boolean(name))
767
+ });
768
+ if (resolved.kind === "error") throw new Error(resolved.message);
769
+ return resolved;
770
+ }
771
+ //#endregion
772
+ //#region ../../internals/client/src/resolveClientOperation.ts
773
+ /**
774
+ * Resolves the contract client `<op>` a consumer (query hook, MCP handler) imports, by looking up
775
+ * the registered contract client plugin's resolver and output. Works for any contract client plugin
776
+ * (plugin-fetch or plugin-axios). Returns `null` when no contract plugin is in play (the inline
777
+ * path). The plugin injects `.kubb/client.ts` at the global output root, the same path consumers
778
+ * read `RequestConfig` / `ResponseErrorConfig` from.
779
+ */
780
+ function resolveClientOperation(options) {
781
+ const { clientPlugin, driver, node, root, output } = options;
782
+ if (!clientPlugin) return null;
783
+ const resolver = driver.getResolver(clientPlugin.pluginName);
784
+ const plugin = driver.getPlugin(clientPlugin.pluginName);
785
+ const file = resolver.file({
786
+ ...operationFileEntry(node, node.operationId),
787
+ root,
788
+ output: plugin?.options?.output ?? output,
789
+ group: plugin?.options?.group ?? void 0
790
+ });
791
+ return {
792
+ name: resolver.name(node.operationId),
793
+ path: file.path,
794
+ clientPath: node_path.default.resolve(root, ".kubb/client.ts")
795
+ };
796
+ }
797
+ //#endregion
798
+ //#region src/utils.ts
799
+ /**
800
+ * Builds the call to a contract client `<op>` function inside a vue-query composable body. The
801
+ * function takes a single grouped options object, so `config` is spread first, then the operation's
802
+ * request groups are unwrapped with `toValue()`, then the abort `signal` for queries, with
803
+ * `throwOnError: true` pinned last so a caller's config can't flip the query's error semantics.
804
+ * Mutations omit the `signal`.
805
+ */
806
+ function buildVueClientCall(node, options) {
807
+ return buildClientCall(node, {
808
+ ...options,
809
+ unwrapName: (name) => `toValue(${name})`
810
+ });
811
+ }
812
+ //#endregion
813
+ //#region src/components/QueryKey.tsx
814
+ const declarationPrinter$4 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
815
+ function buildQueryKeyParamsNode(node, options) {
816
+ const groupedParam = buildGroupedRequestParam(node, {
817
+ resolver: options.resolver,
818
+ keys: [
819
+ "path",
820
+ "query",
821
+ "body"
822
+ ],
823
+ memberTypeWrapper: maybeRefOrGetter
824
+ });
825
+ return (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedParam ? [groupedParam] : [] });
826
+ }
827
+ function QueryKey({ name, node, tsResolver, typeName, transformer }) {
828
+ const paramsNode = buildQueryKeyParamsNode(node, { resolver: tsResolver });
829
+ const paramsSignature = declarationPrinter$4.print(paramsNode) ?? "";
830
+ const keys = (transformer ?? queryKeyTransformer)({
831
+ node,
832
+ casing: "camelcase"
833
+ });
834
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
835
+ name,
836
+ isExportable: true,
837
+ isIndexable: true,
838
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function.Arrow, {
839
+ name,
840
+ export: true,
841
+ params: paramsSignature,
842
+ singleLine: true,
843
+ children: `[${keys.join(", ")}] as const`
844
+ })
845
+ }), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
846
+ name: typeName,
847
+ isExportable: true,
848
+ isIndexable: true,
849
+ isTypeOnly: true,
850
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Type, {
851
+ name: typeName,
852
+ export: true,
853
+ children: `ReturnType<typeof ${name}>`
854
+ })
855
+ })] });
856
+ }
857
+ //#endregion
858
+ //#region src/components/QueryOptions.tsx
859
+ const declarationPrinter$3 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
860
+ const callPrinter$3 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
861
+ function getQueryOptionsParams(node, options) {
862
+ return buildQueryOptionsParams(node, {
863
+ resolver: options.resolver,
864
+ memberTypeWrapper: maybeRefOrGetter
865
+ });
866
+ }
867
+ function QueryOptions({ name, clientName, node, tsResolver, queryKeyName }) {
868
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
869
+ const queryKeyParamsNode = buildQueryKeyParamsNode(node, { resolver: tsResolver });
870
+ const queryKeyParamsCall = callPrinter$3.print(queryKeyParamsNode) ?? "";
871
+ const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
872
+ const paramsSignature = declarationPrinter$3.print(paramsNode) ?? "";
873
+ const queryFnBody = `const { data } = await ${buildVueClientCall(node, {
874
+ clientName,
875
+ signal: true
876
+ })}
877
+ return data`;
878
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
879
+ name,
880
+ isExportable: true,
881
+ isIndexable: true,
882
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
883
+ name,
884
+ export: true,
885
+ params: paramsSignature,
886
+ children: `
887
+ const queryKey = ${queryKeyName}(${queryKeyParamsCall})
888
+ return queryOptions<${TData}, ${TError}, ${TData}>({
889
+ queryKey,
890
+ queryFn: async ({ signal }) => {
891
+ ${queryFnBody}
892
+ },
893
+ })
894
+ `
895
+ })
896
+ });
897
+ }
898
+ //#endregion
899
+ //#region src/components/InfiniteQuery.tsx
900
+ const declarationPrinter$2 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
901
+ const callPrinter$2 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
902
+ function buildInfiniteQueryParamsNode(node, options) {
903
+ const { resolver } = options;
904
+ const { TData, TError } = buildResponseTypes(node, resolver);
905
+ const optionsParam = (0, _kubb_plugin_ts.createFunctionParameter)({
906
+ name: "options",
907
+ type: `{
908
+ query?: Partial<UseInfiniteQueryOptions<${[
909
+ TData,
910
+ TError,
911
+ "TQueryData",
912
+ "TQueryKey",
913
+ "TQueryData"
914
+ ].join(", ")}>> & { client?: QueryClient },
915
+ client?: ${buildClientOptionType()}
916
+ }`,
917
+ default: "{}"
918
+ });
919
+ return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [buildGroupedRequestParam(node, {
920
+ resolver,
921
+ memberTypeWrapper: maybeRefOrGetter
922
+ }), optionsParam].filter((param) => param !== null) });
923
+ }
924
+ function InfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver }) {
925
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
926
+ const returnType = `UseInfiniteQueryReturnType<${["TData", TError].join(", ")}> & { queryKey: TQueryKey }`;
927
+ const generics = [
928
+ `TData = InfiniteData<${TData}>`,
929
+ `TQueryData = ${TData}`,
930
+ `TQueryKey extends QueryKey = ${queryKeyTypeName}`
931
+ ];
932
+ const queryKeyParamsNode = buildQueryKeyParamsNode(node, { resolver: tsResolver });
933
+ const queryKeyParamsCall = callPrinter$2.print(queryKeyParamsNode) ?? "";
934
+ const queryOptionsParamsNode = getQueryOptionsParams(node, { resolver: tsResolver });
935
+ const queryOptionsParamsCall = callPrinter$2.print(queryOptionsParamsNode) ?? "";
936
+ const paramsNode = buildInfiniteQueryParamsNode(node, { resolver: tsResolver });
937
+ const paramsSignature = declarationPrinter$2.print(paramsNode) ?? "";
938
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
939
+ name,
940
+ isExportable: true,
941
+ isIndexable: true,
942
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
943
+ name,
944
+ export: true,
945
+ generics: generics.join(", "),
946
+ params: paramsSignature,
947
+ JSDoc: { comments: buildOperationComments(node) },
948
+ children: `
949
+ const { query: queryConfig = {}, client: config = {} } = options ?? {}
950
+ const { client: queryClient, ...resolvedOptions } = queryConfig
951
+ const queryKey = (resolvedOptions && 'queryKey' in resolvedOptions ? toValue(resolvedOptions.queryKey) : undefined) ?? ${queryKeyName}(${queryKeyParamsCall})
952
+
953
+ const queryResult = useInfiniteQuery({
954
+ ...${queryOptionsName}(${queryOptionsParamsCall}),
955
+ ...resolvedOptions,
956
+ queryKey
957
+ } as unknown as UseInfiniteQueryOptions<${TData}, ${TError}, ${TData}, TQueryKey, ${TData}>, toValue(queryClient)) as ${returnType}
958
+
959
+ queryResult.queryKey = queryKey as TQueryKey
960
+
961
+ return queryResult
962
+ `
963
+ })
964
+ });
965
+ }
966
+ //#endregion
967
+ //#region src/components/InfiniteQueryOptions.tsx
968
+ /**
969
+ * The vue-query flavor of the shared `infiniteQueryOptions` component: request groups accept
970
+ * `MaybeRefOrGetter` values, are unwrapped with `toValue(...)` in the client call, and the emitted
971
+ * `TQueryKey` generic is the imported `QueryKey` type instead of `typeof queryKey`.
972
+ */
973
+ function InfiniteQueryOptions(props) {
974
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(InfiniteQueryOptions$1, {
975
+ ...props,
976
+ queryKeyType: "QueryKey",
977
+ memberTypeWrapper: maybeRefOrGetter,
978
+ unwrapName: (name) => `toValue(${name})`
979
+ });
980
+ }
981
+ //#endregion
982
+ //#region src/components/Mutation.tsx
983
+ const declarationPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
984
+ const callPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
985
+ function resolveMutationRequestType(node, resolver) {
986
+ return buildGroupedRequestParam(node, { resolver }) ? resolver.response.options(node) : "undefined";
987
+ }
988
+ function buildMutationParamsNode(node, options) {
989
+ const { resolver } = options;
990
+ const { TData, TError } = buildResponseTypes(node, resolver);
991
+ return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
992
+ name: "options",
993
+ type: `{
994
+ mutation?: MutationObserverOptions<${[
995
+ TData,
996
+ TError,
997
+ resolveMutationRequestType(node, resolver),
998
+ "TContext"
999
+ ].join(", ")}> & { client?: QueryClient },
1000
+ client?: ${buildRequestConfigType(node)},
1001
+ }`,
1002
+ default: "{}"
1003
+ })] });
1004
+ }
1005
+ function Mutation({ name, clientName, node, tsResolver, mutationKeyName }) {
1006
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1007
+ const groupedParam = buildGroupedRequestParam(node, { resolver: tsResolver });
1008
+ const hasMutationParams = groupedParam !== null;
1009
+ const groupedParamsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedParam ? [groupedParam] : [] });
1010
+ const argBindingStr = hasMutationParams ? callPrinter$1.print(groupedParamsNode) ?? "" : "";
1011
+ const mutationFnBody = `const { data } = await ${buildVueClientCall(node, {
1012
+ clientName,
1013
+ signal: false
1014
+ })}
1015
+ return data`;
1016
+ const generics = [
1017
+ TData,
1018
+ TError,
1019
+ resolveMutationRequestType(node, tsResolver),
1020
+ "TContext"
1021
+ ].join(", ");
1022
+ const paramsNode = buildMutationParamsNode(node, { resolver: tsResolver });
1023
+ const paramsSignature = declarationPrinter$1.print(paramsNode) ?? "";
1024
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1025
+ name,
1026
+ isExportable: true,
1027
+ isIndexable: true,
1028
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
1029
+ name,
1030
+ export: true,
1031
+ params: paramsSignature,
1032
+ JSDoc: { comments: buildOperationComments(node) },
1033
+ generics: ["TContext"],
1034
+ children: `
1035
+ const { mutation = {}, client: config = {} } = options ?? {}
1036
+ const { client: queryClient, ...mutationOptions } = mutation;
1037
+ const mutationKey = mutationOptions?.mutationKey ?? ${mutationKeyName}()
1038
+
1039
+ return useMutation<${generics}>({
1040
+ mutationFn: async(${argBindingStr}) => {
1041
+ ${mutationFnBody}
1042
+ },
1043
+ mutationKey,
1044
+ ...mutationOptions
1045
+ }, queryClient)
1046
+ `
1047
+ })
1048
+ });
1049
+ }
1050
+ //#endregion
1051
+ //#region src/components/Query.tsx
1052
+ const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1053
+ const callPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
1054
+ function buildQueryParamsNode(node, options) {
1055
+ const { resolver } = options;
1056
+ const { TData, TError } = buildResponseTypes(node, resolver);
1057
+ const optionsParam = (0, _kubb_plugin_ts.createFunctionParameter)({
1058
+ name: "options",
1059
+ type: `{
1060
+ query?: Partial<UseQueryOptions<${[
1061
+ TData,
1062
+ TError,
1063
+ "TData",
1064
+ "TQueryData",
1065
+ "TQueryKey"
1066
+ ].join(", ")}>> & { client?: QueryClient },
1067
+ client?: ${buildClientOptionType()}
1068
+ }`,
1069
+ default: "{}"
1070
+ });
1071
+ return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [buildGroupedRequestParam(node, {
1072
+ resolver,
1073
+ memberTypeWrapper: maybeRefOrGetter
1074
+ }), optionsParam].filter((param) => param !== null) });
1075
+ }
1076
+ function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver }) {
1077
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
1078
+ const returnType = `UseQueryReturnType<${["TData", TError].join(", ")}> & { queryKey: TQueryKey }`;
1079
+ const generics = [
1080
+ `TData = ${TData}`,
1081
+ `TQueryData = ${TData}`,
1082
+ `TQueryKey extends QueryKey = ${queryKeyTypeName}`
1083
+ ];
1084
+ const queryKeyParamsNode = buildQueryKeyParamsNode(node, { resolver: tsResolver });
1085
+ const queryKeyParamsCall = callPrinter.print(queryKeyParamsNode) ?? "";
1086
+ const queryOptionsParamsNode = getQueryOptionsParams(node, { resolver: tsResolver });
1087
+ const queryOptionsParamsCall = callPrinter.print(queryOptionsParamsNode) ?? "";
1088
+ const paramsNode = buildQueryParamsNode(node, { resolver: tsResolver });
1089
+ const paramsSignature = declarationPrinter.print(paramsNode) ?? "";
1090
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1091
+ name,
1092
+ isExportable: true,
1093
+ isIndexable: true,
1094
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
1095
+ name,
1096
+ export: true,
1097
+ generics: generics.join(", "),
1098
+ params: paramsSignature,
1099
+ JSDoc: { comments: buildOperationComments(node) },
1100
+ children: `
1101
+ const { query: queryConfig = {}, client: config = {} } = options ?? {}
1102
+ const { client: queryClient, ...resolvedOptions } = queryConfig
1103
+ const queryKey = (resolvedOptions && 'queryKey' in resolvedOptions ? toValue(resolvedOptions.queryKey) : undefined) ?? ${queryKeyName}(${queryKeyParamsCall})
1104
+
1105
+ const queryResult = useQuery({
1106
+ ...${queryOptionsName}(${queryOptionsParamsCall}),
1107
+ ...resolvedOptions,
1108
+ queryKey
1109
+ } as unknown as UseQueryOptions<${TData}, ${TError}, TData, ${TData}, TQueryKey>, toValue(queryClient)) as ${returnType}
1110
+
1111
+ queryResult.queryKey = queryKey as TQueryKey
1112
+
1113
+ return queryResult
1114
+ `
1115
+ })
1116
+ });
1117
+ }
1118
+ //#endregion
1119
+ //#region src/generators/infiniteQueryGenerator.tsx
1120
+ /**
1121
+ * Built-in generator for `useInfiniteQuery` composables. Enabled when
1122
+ * `pluginVueQuery({ infinite: { ... }, hooks: true })`. Emits one
1123
+ * `useFooInfiniteQuery` composable per query operation, wiring the
1124
+ * configured cursor path into TanStack Query's cursor-based pagination.
1125
+ */
1126
+ const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
1127
+ name: "vue-query-infinite",
1128
+ renderer: kubb_jsx.jsxRenderer,
1129
+ operation(node, ctx) {
1130
+ if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
1131
+ const { config, driver, resolver, root } = ctx;
1132
+ const { output, query, mutation, infinite, client, group, hooks } = ctx.options;
1133
+ const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
1134
+ if (!pluginTs) return null;
1135
+ const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1136
+ const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
1137
+ const queryMethods = new Set(query ? query.methods : []);
1138
+ const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
1139
+ const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
1140
+ if (!isQuery || isMutation || !infiniteOptions || !hooks) return null;
1141
+ const normalizeKey = (key) => key.replace(/\?$/, "");
1142
+ const queryParamKeys = getOperationParameters(node).query.map((p) => p.name);
1143
+ if (!(infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false)) return null;
1144
+ const importPath = query ? query.importPath : "@tanstack/vue-query";
1145
+ const contractOp = resolveClientOperation({
1146
+ clientPlugin: { pluginName: client.pluginName },
1147
+ driver,
1148
+ node,
1149
+ root,
1150
+ output
1151
+ });
1152
+ if (!contractOp) return null;
1153
+ const queryName = resolver.infiniteQuery.name(node);
1154
+ const queryOptionsName = resolver.infiniteQuery.optionsName(node);
1155
+ const queryKeyName = resolver.infiniteQuery.keyName(node);
1156
+ const queryKeyTypeName = resolver.infiniteQuery.keyTypeName(node);
1157
+ const meta = {
1158
+ file: resolver.file({
1159
+ ...operationFileEntry(node, queryName),
1160
+ root,
1161
+ output,
1162
+ group: group ?? void 0
1163
+ }),
1164
+ fileTs: tsResolver.file({
1165
+ ...operationFileEntry(node, node.operationId),
1166
+ root,
1167
+ output: pluginTs.options?.output ?? output,
1168
+ group: pluginTs.options?.group ?? void 0
1169
+ })
1170
+ };
1171
+ const rawQueryParams = getOperationParameters(node).query;
1172
+ const queryParamsTypeName = rawQueryParams.length > 0 && tsResolver.param.query(node, rawQueryParams[0]) !== tsResolver.param.name(node, rawQueryParams[0]) ? tsResolver.param.query(node, rawQueryParams[0]) : null;
1173
+ const importedTypeNames = [
1174
+ tsResolver.response.options(node),
1175
+ queryParamsTypeName,
1176
+ ...resolveOperationTypeNames(node, tsResolver, {
1177
+ exclude: [queryKeyTypeName],
1178
+ order: "body-response-first",
1179
+ includeParams: false
1180
+ })
1181
+ ].filter((name) => Boolean(name));
1182
+ const calledClientName = contractOp.name;
1183
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
1184
+ baseName: meta.file.baseName,
1185
+ path: meta.file.path,
1186
+ meta: meta.file.meta,
1187
+ banner: resolver.default.banner(ctx.meta, {
1188
+ output,
1189
+ config,
1190
+ file: {
1191
+ path: meta.file.path,
1192
+ baseName: meta.file.baseName
1193
+ }
1194
+ }),
1195
+ footer: resolver.default.footer(ctx.meta, {
1196
+ output,
1197
+ config,
1198
+ file: {
1199
+ path: meta.file.path,
1200
+ baseName: meta.file.baseName
1201
+ }
1202
+ }),
1203
+ children: [
1204
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1205
+ name: [contractOp.name],
1206
+ root: meta.file.path,
1207
+ path: contractOp.path
1208
+ }),
1209
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1210
+ name: ["RequestConfig", "ResponseErrorConfig"],
1211
+ root: meta.file.path,
1212
+ path: contractOp.clientPath,
1213
+ isTypeOnly: true
1214
+ }),
1215
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1216
+ name: ["toValue"],
1217
+ path: "vue"
1218
+ }),
1219
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1220
+ name: ["MaybeRefOrGetter"],
1221
+ path: "vue",
1222
+ isTypeOnly: true
1223
+ }),
1224
+ meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1225
+ name: Array.from(new Set(importedTypeNames)),
1226
+ root: meta.file.path,
1227
+ path: meta.fileTs.path,
1228
+ isTypeOnly: true
1229
+ }),
1230
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryKey, {
1231
+ name: queryKeyName,
1232
+ typeName: queryKeyTypeName,
1233
+ node,
1234
+ tsResolver,
1235
+ transformer: ctx.options.queryKey
1236
+ }),
1237
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1238
+ name: ["InfiniteData"],
1239
+ isTypeOnly: true,
1240
+ path: importPath
1241
+ }),
1242
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1243
+ name: ["infiniteQueryOptions"],
1244
+ path: importPath
1245
+ }),
1246
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(InfiniteQueryOptions, {
1247
+ name: queryOptionsName,
1248
+ clientName: calledClientName,
1249
+ queryKeyName,
1250
+ node,
1251
+ tsResolver,
1252
+ cursorParam: infiniteOptions.cursorParam,
1253
+ nextParam: infiniteOptions.nextParam,
1254
+ previousParam: infiniteOptions.previousParam,
1255
+ initialPageParam: infiniteOptions.initialPageParam,
1256
+ queryParam: infiniteOptions.queryParam
1257
+ }),
1258
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1259
+ name: ["useInfiniteQuery"],
1260
+ path: importPath
1261
+ }),
1262
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1263
+ name: [
1264
+ "QueryKey",
1265
+ "QueryClient",
1266
+ "UseInfiniteQueryOptions",
1267
+ "UseInfiniteQueryReturnType"
1268
+ ],
1269
+ path: importPath,
1270
+ isTypeOnly: true
1271
+ }),
1272
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(InfiniteQuery, {
1273
+ name: queryName,
1274
+ queryOptionsName,
1275
+ queryKeyName,
1276
+ queryKeyTypeName,
1277
+ node,
1278
+ tsResolver,
1279
+ initialPageParam: infiniteOptions.initialPageParam,
1280
+ queryParam: infiniteOptions.queryParam
1281
+ })
1282
+ ]
1283
+ });
1284
+ }
1285
+ });
1286
+ //#endregion
1287
+ //#region src/generators/mutationGenerator.tsx
1288
+ /**
1289
+ * Built-in generator for `useMutation` composables. Emits one
1290
+ * `useFooMutation` composable per POST/PUT/DELETE operation (configurable
1291
+ * via `mutation.methods`) plus the matching `fooMutationKey` helper.
1292
+ */
1293
+ const mutationGenerator = (0, kubb_kit.defineGenerator)({
1294
+ name: "vue-query-mutation",
1295
+ renderer: kubb_jsx.jsxRenderer,
1296
+ operation(node, ctx) {
1297
+ if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
1298
+ const { config, driver, resolver, root } = ctx;
1299
+ const { output, query, mutation, client, group, hooks } = ctx.options;
1300
+ const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
1301
+ if (!pluginTs) return null;
1302
+ const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1303
+ const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
1304
+ const queryMethods = new Set(query ? query.methods : []);
1305
+ if (!(mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase()))) return null;
1306
+ const importPath = mutation ? mutation.importPath : "@tanstack/vue-query";
1307
+ const contractOp = resolveClientOperation({
1308
+ clientPlugin: { pluginName: client.pluginName },
1309
+ driver,
1310
+ node,
1311
+ root,
1312
+ output
1313
+ });
1314
+ if (!contractOp) return null;
1315
+ const mutationHookName = resolver.mutation.name(node);
1316
+ const mutationTypeName = resolver.mutation.typeName(node);
1317
+ const mutationKeyName = resolver.mutation.keyName(node);
1318
+ const meta = {
1319
+ file: resolver.file({
1320
+ ...operationFileEntry(node, mutationHookName),
1321
+ root,
1322
+ output,
1323
+ group: group ?? void 0
1324
+ }),
1325
+ fileTs: tsResolver.file({
1326
+ ...operationFileEntry(node, node.operationId),
1327
+ root,
1328
+ output: pluginTs.options?.output ?? output,
1329
+ group: pluginTs.options?.group ?? void 0
1330
+ })
1331
+ };
1332
+ const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
1333
+ order: "body-response-first",
1334
+ includeParams: false
1335
+ })].filter((name) => Boolean(name));
1336
+ const calledClientName = contractOp.name;
1337
+ const groups = getRequestGroups(node);
1338
+ const hasRequestGroups = groups.path || groups.query || groups.body || groups.headers;
1339
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
1340
+ baseName: meta.file.baseName,
1341
+ path: meta.file.path,
1342
+ meta: meta.file.meta,
1343
+ banner: resolver.default.banner(ctx.meta, {
1344
+ output,
1345
+ config,
1346
+ file: {
1347
+ path: meta.file.path,
1348
+ baseName: meta.file.baseName
1349
+ }
1350
+ }),
1351
+ footer: resolver.default.footer(ctx.meta, {
1352
+ output,
1353
+ config,
1354
+ file: {
1355
+ path: meta.file.path,
1356
+ baseName: meta.file.baseName
1357
+ }
1358
+ }),
1359
+ children: [
1360
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1361
+ name: [contractOp.name],
1362
+ root: meta.file.path,
1363
+ path: contractOp.path
1364
+ }),
1365
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1366
+ name: ["RequestConfig", "ResponseErrorConfig"],
1367
+ root: meta.file.path,
1368
+ path: contractOp.clientPath,
1369
+ isTypeOnly: true
1370
+ }),
1371
+ hasRequestGroups && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1372
+ name: ["toValue"],
1373
+ path: "vue"
1374
+ }),
1375
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1376
+ name: ["MaybeRefOrGetter"],
1377
+ path: "vue",
1378
+ isTypeOnly: true
1379
+ }),
1380
+ meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1381
+ name: Array.from(new Set(importedTypeNames)),
1382
+ root: meta.file.path,
1383
+ path: meta.fileTs.path,
1384
+ isTypeOnly: true
1385
+ }),
1386
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(MutationKey, {
1387
+ name: mutationKeyName,
1388
+ node,
1389
+ transformer: ctx.options.mutationKey
1390
+ }),
1391
+ mutation && hooks && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [
1392
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1393
+ name: ["useMutation"],
1394
+ path: importPath
1395
+ }),
1396
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1397
+ name: ["MutationObserverOptions", "QueryClient"],
1398
+ path: importPath,
1399
+ isTypeOnly: true
1400
+ }),
1401
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Mutation, {
1402
+ name: mutationHookName,
1403
+ clientName: calledClientName,
1404
+ typeName: mutationTypeName,
1405
+ node,
1406
+ tsResolver,
1407
+ mutationKeyName
1408
+ })
1409
+ ] })
1410
+ ]
1411
+ });
1412
+ }
1413
+ });
1414
+ //#endregion
1415
+ //#region src/generators/queryGenerator.tsx
1416
+ /**
1417
+ * Built-in generator for `useQuery` composables. Emits one `useFooQuery`
1418
+ * composable per GET operation (configurable via `query.methods`) plus the
1419
+ * matching `fooQueryKey` / `fooQueryOptions` helpers.
1420
+ */
1421
+ const queryGenerator = (0, kubb_kit.defineGenerator)({
1422
+ name: "vue-query",
1423
+ renderer: kubb_jsx.jsxRenderer,
1424
+ operation(node, ctx) {
1425
+ if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
1426
+ const { config, driver, resolver, root } = ctx;
1427
+ const { output, query, mutation, client, group, hooks } = ctx.options;
1428
+ const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
1429
+ if (!pluginTs) return null;
1430
+ const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1431
+ const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
1432
+ const queryMethods = new Set(query ? query.methods : []);
1433
+ const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
1434
+ if (!isQuery || isMutation) return null;
1435
+ const importPath = query ? query.importPath : "@tanstack/vue-query";
1436
+ const contractOp = resolveClientOperation({
1437
+ clientPlugin: { pluginName: client.pluginName },
1438
+ driver,
1439
+ node,
1440
+ root,
1441
+ output
1442
+ });
1443
+ if (!contractOp) return null;
1444
+ const queryName = resolver.query.name(node);
1445
+ const queryOptionsName = resolver.query.optionsName(node);
1446
+ const queryKeyName = resolver.query.keyName(node);
1447
+ const queryKeyTypeName = resolver.query.keyTypeName(node);
1448
+ const meta = {
1449
+ file: resolver.file({
1450
+ ...operationFileEntry(node, queryName),
1451
+ root,
1452
+ output,
1453
+ group: group ?? void 0
1454
+ }),
1455
+ fileTs: tsResolver.file({
1456
+ ...operationFileEntry(node, node.operationId),
1457
+ root,
1458
+ output: pluginTs.options?.output ?? output,
1459
+ group: pluginTs.options?.group ?? void 0
1460
+ })
1461
+ };
1462
+ const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
1463
+ exclude: [queryKeyTypeName],
1464
+ order: "body-response-first",
1465
+ includeParams: false
1466
+ })].filter((name) => Boolean(name));
1467
+ const calledClientName = contractOp.name;
1468
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
1469
+ baseName: meta.file.baseName,
1470
+ path: meta.file.path,
1471
+ meta: meta.file.meta,
1472
+ banner: resolver.default.banner(ctx.meta, {
1473
+ output,
1474
+ config,
1475
+ file: {
1476
+ path: meta.file.path,
1477
+ baseName: meta.file.baseName
1478
+ }
1479
+ }),
1480
+ footer: resolver.default.footer(ctx.meta, {
1481
+ output,
1482
+ config,
1483
+ file: {
1484
+ path: meta.file.path,
1485
+ baseName: meta.file.baseName
1486
+ }
1487
+ }),
1488
+ children: [
1489
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1490
+ name: [contractOp.name],
1491
+ root: meta.file.path,
1492
+ path: contractOp.path
1493
+ }),
1494
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1495
+ name: ["RequestConfig", "ResponseErrorConfig"],
1496
+ root: meta.file.path,
1497
+ path: contractOp.clientPath,
1498
+ isTypeOnly: true
1499
+ }),
1500
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1501
+ name: ["toValue"],
1502
+ path: "vue"
1503
+ }),
1504
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1505
+ name: ["MaybeRefOrGetter"],
1506
+ path: "vue",
1507
+ isTypeOnly: true
1508
+ }),
1509
+ meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1510
+ name: Array.from(new Set(importedTypeNames)),
1511
+ root: meta.file.path,
1512
+ path: meta.fileTs.path,
1513
+ isTypeOnly: true
1514
+ }),
1515
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryKey, {
1516
+ name: queryKeyName,
1517
+ typeName: queryKeyTypeName,
1518
+ node,
1519
+ tsResolver,
1520
+ transformer: ctx.options.queryKey
1521
+ }),
1522
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1523
+ name: ["queryOptions"],
1524
+ path: importPath
1525
+ }),
1526
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryOptions, {
1527
+ name: queryOptionsName,
1528
+ clientName: calledClientName,
1529
+ queryKeyName,
1530
+ node,
1531
+ tsResolver
1532
+ }),
1533
+ query && hooks && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [
1534
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1535
+ name: ["useQuery"],
1536
+ path: importPath
1537
+ }),
1538
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1539
+ name: [
1540
+ "QueryKey",
1541
+ "QueryClient",
1542
+ "UseQueryOptions",
1543
+ "UseQueryReturnType"
1544
+ ],
1545
+ path: importPath,
1546
+ isTypeOnly: true
1547
+ }),
1548
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Query, {
1549
+ name: queryName,
1550
+ queryOptionsName,
1551
+ queryKeyName,
1552
+ queryKeyTypeName,
1553
+ node,
1554
+ tsResolver
1555
+ })
1556
+ ] })
1557
+ ]
1558
+ });
1559
+ }
1560
+ });
1561
+ //#endregion
1562
+ //#region src/resolvers/resolverVueQuery.ts
1563
+ /**
1564
+ * Default resolver used by `@kubb/plugin-vue-query`. Decides the names and
1565
+ * file paths for every generated TanStack Query composable (`useFoo`,
1566
+ * `useFooInfinite`) and its companion helpers.
1567
+ *
1568
+ * The `default` helpers are supplied by `createResolver`. Functions and files use camelCase;
1569
+ * composables get the `use` prefix. Operation-specific naming is grouped under the `query`,
1570
+ * `infiniteQuery`, and `mutation` namespaces.
1571
+ *
1572
+ * @example Resolve composable and helper names
1573
+ * ```ts
1574
+ * import { resolverVueQuery } from '@kubb/plugin-vue-query'
1575
+ *
1576
+ * resolverVueQuery.query.name(operationNode) // 'useGetPetById'
1577
+ * resolverVueQuery.query.keyName(operationNode) // 'getPetByIdQueryKey'
1578
+ * resolverVueQuery.query.optionsName(operationNode) // 'getPetByIdQueryOptions'
1579
+ * ```
1580
+ */
1581
+ const resolverVueQuery = (0, kubb_kit.createResolver)({
27
1582
  pluginName: "plugin-vue-query",
28
- default(name, type) {
29
- return require_components.camelCase(name, { isFile: type === "file" });
30
- },
31
- resolveName(name) {
32
- return this.default(name, "function");
33
- },
34
- resolvePathName(name, type) {
35
- return this.default(name, type);
36
- },
37
- resolveQueryName(node) {
38
- return `use${capitalize(this.resolveName(node.operationId))}`;
39
- },
40
- resolveInfiniteQueryName(node) {
41
- return `use${capitalize(this.resolveName(node.operationId))}Infinite`;
42
- },
43
- resolveMutationName(node) {
44
- return `use${capitalize(this.resolveName(node.operationId))}`;
45
- },
46
- resolveQueryOptionsName(node) {
47
- return `${this.resolveName(node.operationId)}QueryOptions`;
48
- },
49
- resolveInfiniteQueryOptionsName(node) {
50
- return `${this.resolveName(node.operationId)}InfiniteQueryOptions`;
51
- },
52
- resolveQueryKeyName(node) {
53
- return `${this.resolveName(node.operationId)}QueryKey`;
54
- },
55
- resolveInfiniteQueryKeyName(node) {
56
- return `${this.resolveName(node.operationId)}InfiniteQueryKey`;
57
- },
58
- resolveMutationKeyName(node) {
59
- return `${this.resolveName(node.operationId)}MutationKey`;
60
- },
61
- resolveQueryKeyTypeName(node) {
62
- return `${capitalize(this.resolveName(node.operationId))}QueryKey`;
63
- },
64
- resolveInfiniteQueryKeyTypeName(node) {
65
- return `${capitalize(this.resolveName(node.operationId))}InfiniteQueryKey`;
66
- },
67
- resolveMutationTypeName(node) {
68
- return capitalize(this.resolveName(node.operationId));
69
- },
70
- resolveClientName(node) {
71
- return this.resolveName(node.operationId);
72
- },
73
- resolveInfiniteClientName(node) {
74
- return `${this.resolveName(node.operationId)}Infinite`;
1583
+ query: createQueryResolver(),
1584
+ infiniteQuery: createQueryResolver("Infinite"),
1585
+ mutation: {
1586
+ ...createMutationResolver(),
1587
+ typeName(node) {
1588
+ return capitalize(this.name(node.operationId));
1589
+ }
75
1590
  }
76
- }));
1591
+ });
77
1592
  //#endregion
78
1593
  //#region src/plugin.ts
1594
+ /**
1595
+ * Canonical plugin name for `@kubb/plugin-vue-query`. Used for driver lookups
1596
+ * and cross-plugin dependency references.
1597
+ */
79
1598
  const pluginVueQueryName = "plugin-vue-query";
80
- const pluginVueQuery = (0, _kubb_core.definePlugin)((options) => {
1599
+ /**
1600
+ * Generates one TanStack Query composable per OpenAPI operation for Vue's
1601
+ * Composition API. Queries become `useFoo` (and optionally
1602
+ * `useFooInfinite`). Mutations become `useFoo` as well. Each composable
1603
+ * is fully typed end to end.
1604
+ *
1605
+ * @example
1606
+ * ```ts
1607
+ * import { defineConfig } from 'kubb/config'
1608
+ * import { pluginTs } from '@kubb/plugin-ts'
1609
+ * import { pluginVueQuery } from '@kubb/plugin-vue-query'
1610
+ *
1611
+ * export default defineConfig({
1612
+ * input: './petStore.yaml',
1613
+ * output: { path: './src/gen' },
1614
+ * plugins: [
1615
+ * pluginTs(),
1616
+ * pluginVueQuery({
1617
+ * output: { path: './hooks' },
1618
+ * }),
1619
+ * ],
1620
+ * })
1621
+ * ```
1622
+ */
1623
+ const pluginVueQuery = (0, kubb_kit.definePlugin)((options) => {
81
1624
  const { output = {
82
1625
  path: "hooks",
83
- barrelType: "named"
84
- }, group, exclude = [], include, override = [], parser = "client", infinite = false, paramsType = "inline", pathParamsType = paramsType === "object" ? "object" : options.pathParamsType || "inline", mutation = {}, query = {}, mutationKey = require_components.mutationKeyTransformer, queryKey = require_components.queryKeyTransformer, paramsCasing, client, resolver: userResolver, transformer: userTransformer, generators: userGenerators = [] } = options;
85
- const clientName = client?.client ?? "axios";
86
- const clientImportPath = client?.importPath ?? (!client?.bundle ? `@kubb/plugin-client/clients/${clientName}` : void 0);
87
- const selectedGenerators = options.generators ?? [
88
- require_generators.queryGenerator,
89
- require_generators.infiniteQueryGenerator,
90
- require_generators.mutationGenerator
91
- ].filter((generator) => Boolean(generator));
92
- const groupConfig = group ? {
93
- ...group,
94
- name: group.name ? group.name : (ctx) => {
95
- if (group.type === "path") return `${ctx.group.split("/")[1]}`;
96
- return `${require_components.camelCase(ctx.group)}Controller`;
97
- }
98
- } : void 0;
1626
+ barrel: { type: "named" }
1627
+ }, group, exclude = [], include, override = [], infinite = false, mutation = {}, query = {}, mutationKey = mutationKeyTransformer, queryKey = queryKeyTransformer, hooks = false, client, resolver: userResolver, macros: userMacros } = options;
1628
+ const selectedGenerators = [
1629
+ queryGenerator,
1630
+ infiniteQueryGenerator,
1631
+ mutationGenerator
1632
+ ];
1633
+ const groupConfig = createGroupConfig(group);
99
1634
  return {
100
1635
  name: pluginVueQueryName,
101
1636
  options,
102
- dependencies: [_kubb_plugin_ts.pluginTsName, parser === "zod" ? _kubb_plugin_zod.pluginZodName : void 0].filter((dependency) => Boolean(dependency)),
1637
+ dependencies: [_kubb_plugin_ts.pluginTsName],
103
1638
  hooks: { "kubb:plugin:setup"(ctx) {
104
- const resolver = userResolver ? {
105
- ...resolverVueQuery,
106
- ...userResolver
107
- } : resolverVueQuery;
1639
+ const resolver = userResolver ? kubb_kit.Resolver.merge(resolverVueQuery, userResolver) : resolverVueQuery;
108
1640
  ctx.setOptions({
109
1641
  output,
110
- client: {
111
- bundle: client?.bundle,
112
- baseURL: client?.baseURL,
113
- client: clientName,
114
- clientType: client?.clientType ?? "function",
115
- importPath: clientImportPath,
116
- dataReturnType: client?.dataReturnType ?? "data",
117
- paramsCasing
118
- },
1642
+ client: resolveContractClient({
1643
+ client,
1644
+ plugins: ctx.config.plugins
1645
+ }),
119
1646
  queryKey,
120
- query: query === false ? false : {
121
- importPath: "@tanstack/vue-query",
122
- methods: ["get"],
123
- ...query
124
- },
1647
+ query: resolveQueryConfig(query, { importPath: "@tanstack/vue-query" }),
125
1648
  mutationKey,
126
- mutation: mutation === false ? false : {
127
- importPath: "@tanstack/vue-query",
128
- methods: [
129
- "post",
130
- "put",
131
- "patch",
132
- "delete"
133
- ],
134
- ...mutation
135
- },
136
- infinite: infinite ? {
137
- queryParam: "id",
138
- initialPageParam: 0,
139
- cursorParam: void 0,
140
- nextParam: void 0,
141
- previousParam: void 0,
142
- ...infinite
143
- } : false,
144
- parser,
145
- paramsType,
146
- pathParamsType,
147
- paramsCasing,
1649
+ mutation: resolveMutationConfig(mutation, { importPath: "@tanstack/vue-query" }),
1650
+ infinite: resolveInfiniteConfig(infinite),
1651
+ hooks,
148
1652
  group: groupConfig,
149
1653
  exclude,
150
1654
  include,
@@ -152,31 +1656,8 @@ const pluginVueQuery = (0, _kubb_core.definePlugin)((options) => {
152
1656
  resolver
153
1657
  });
154
1658
  ctx.setResolver(resolver);
155
- if (userTransformer) ctx.setTransformer(userTransformer);
156
- for (const gen of selectedGenerators) ctx.addGenerator(gen);
157
- for (const gen of userGenerators) ctx.addGenerator(gen);
158
- const root = node_path.default.resolve(ctx.config.root, ctx.config.output.path);
159
- const hasClientPlugin = !!ctx.config.plugins?.some((p) => p.name === _kubb_plugin_client.pluginClientName);
160
- if (client?.bundle && !hasClientPlugin && !clientImportPath) ctx.injectFile({
161
- baseName: "fetch.ts",
162
- path: node_path.default.resolve(root, ".kubb/fetch.ts"),
163
- sources: [_kubb_core.ast.createSource({
164
- name: "fetch",
165
- nodes: [_kubb_core.ast.createText(clientName === "fetch" ? _kubb_plugin_client_templates_clients_fetch_source.source : _kubb_plugin_client_templates_clients_axios_source.source)],
166
- isExportable: true,
167
- isIndexable: true
168
- })]
169
- });
170
- if (!hasClientPlugin) ctx.injectFile({
171
- baseName: "config.ts",
172
- path: node_path.default.resolve(root, ".kubb/config.ts"),
173
- sources: [_kubb_core.ast.createSource({
174
- name: "config",
175
- nodes: [_kubb_core.ast.createText(_kubb_plugin_client_templates_config_source.source)],
176
- isExportable: false,
177
- isIndexable: false
178
- })]
179
- });
1659
+ if (userMacros?.length) ctx.setMacros(userMacros);
1660
+ ctx.addGenerator(...selectedGenerators);
180
1661
  } }
181
1662
  };
182
1663
  });
@@ -184,5 +1665,6 @@ const pluginVueQuery = (0, _kubb_core.definePlugin)((options) => {
184
1665
  exports.default = pluginVueQuery;
185
1666
  exports.pluginVueQuery = pluginVueQuery;
186
1667
  exports.pluginVueQueryName = pluginVueQueryName;
1668
+ exports.resolverVueQuery = resolverVueQuery;
187
1669
 
188
1670
  //# sourceMappingURL=index.cjs.map