@kubb/plugin-vue-query 5.0.0-beta.64 → 5.0.0-beta.73

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