@kubb/plugin-vue-query 5.0.0-beta.99 → 5.1.0-canary.20260819T202658
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 +205 -325
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +202 -322
- package/dist/index.js.map +1 -1
- package/package.json +8 -11
package/dist/index.cjs
CHANGED
|
@@ -23,257 +23,17 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
23
23
|
}
|
|
24
24
|
return to;
|
|
25
25
|
};
|
|
26
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
26
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
27
27
|
value: mod,
|
|
28
28
|
enumerable: true
|
|
29
29
|
}) : target, mod));
|
|
30
30
|
//#endregion
|
|
31
|
+
let kubb_kit = require("kubb/kit");
|
|
31
32
|
let node_path = require("node:path");
|
|
32
33
|
node_path = __toESM(node_path, 1);
|
|
33
|
-
let kubb_kit = require("kubb/kit");
|
|
34
34
|
let _kubb_plugin_ts = require("@kubb/plugin-ts");
|
|
35
35
|
let kubb_jsx = require("kubb/jsx");
|
|
36
36
|
let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
|
|
37
|
-
//#region ../../internals/utils/src/casing.ts
|
|
38
|
-
/**
|
|
39
|
-
* Shared implementation for camelCase and PascalCase conversion.
|
|
40
|
-
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
41
|
-
* and capitalizes each word according to `pascal`.
|
|
42
|
-
*
|
|
43
|
-
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
44
|
-
*/
|
|
45
|
-
function toCamelOrPascal(text, pascal) {
|
|
46
|
-
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) => {
|
|
47
|
-
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
48
|
-
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
49
|
-
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Converts `text` to camelCase.
|
|
53
|
-
*
|
|
54
|
-
* @example Word boundaries
|
|
55
|
-
* `camelCase('hello-world') // 'helloWorld'`
|
|
56
|
-
*
|
|
57
|
-
* @example With a prefix
|
|
58
|
-
* `camelCase('tag', { prefix: 'create' }) // 'createTag'`
|
|
59
|
-
*/
|
|
60
|
-
function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
61
|
-
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Uppercases only the first character of `text`, leaving the rest untouched.
|
|
65
|
-
* Unlike {@link pascalCase} it never re-splits word boundaries or strips characters.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* `capitalize('getPetById') // 'GetPetById'`
|
|
69
|
-
*/
|
|
70
|
-
function capitalize(text) {
|
|
71
|
-
return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
|
|
72
|
-
}
|
|
73
|
-
//#endregion
|
|
74
|
-
//#region ../../internals/utils/src/reserved.ts
|
|
75
|
-
/**
|
|
76
|
-
* JavaScript and Java reserved words.
|
|
77
|
-
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
78
|
-
*/
|
|
79
|
-
const reservedWords = /* @__PURE__ */ new Set([
|
|
80
|
-
"abstract",
|
|
81
|
-
"arguments",
|
|
82
|
-
"boolean",
|
|
83
|
-
"break",
|
|
84
|
-
"byte",
|
|
85
|
-
"case",
|
|
86
|
-
"catch",
|
|
87
|
-
"char",
|
|
88
|
-
"class",
|
|
89
|
-
"const",
|
|
90
|
-
"continue",
|
|
91
|
-
"debugger",
|
|
92
|
-
"default",
|
|
93
|
-
"delete",
|
|
94
|
-
"do",
|
|
95
|
-
"double",
|
|
96
|
-
"else",
|
|
97
|
-
"enum",
|
|
98
|
-
"eval",
|
|
99
|
-
"export",
|
|
100
|
-
"extends",
|
|
101
|
-
"false",
|
|
102
|
-
"final",
|
|
103
|
-
"finally",
|
|
104
|
-
"float",
|
|
105
|
-
"for",
|
|
106
|
-
"function",
|
|
107
|
-
"goto",
|
|
108
|
-
"if",
|
|
109
|
-
"implements",
|
|
110
|
-
"import",
|
|
111
|
-
"in",
|
|
112
|
-
"instanceof",
|
|
113
|
-
"int",
|
|
114
|
-
"interface",
|
|
115
|
-
"let",
|
|
116
|
-
"long",
|
|
117
|
-
"native",
|
|
118
|
-
"new",
|
|
119
|
-
"null",
|
|
120
|
-
"package",
|
|
121
|
-
"private",
|
|
122
|
-
"protected",
|
|
123
|
-
"public",
|
|
124
|
-
"return",
|
|
125
|
-
"short",
|
|
126
|
-
"static",
|
|
127
|
-
"super",
|
|
128
|
-
"switch",
|
|
129
|
-
"synchronized",
|
|
130
|
-
"this",
|
|
131
|
-
"throw",
|
|
132
|
-
"throws",
|
|
133
|
-
"transient",
|
|
134
|
-
"true",
|
|
135
|
-
"try",
|
|
136
|
-
"typeof",
|
|
137
|
-
"var",
|
|
138
|
-
"void",
|
|
139
|
-
"volatile",
|
|
140
|
-
"while",
|
|
141
|
-
"with",
|
|
142
|
-
"yield",
|
|
143
|
-
"Array",
|
|
144
|
-
"Date",
|
|
145
|
-
"hasOwnProperty",
|
|
146
|
-
"Infinity",
|
|
147
|
-
"isFinite",
|
|
148
|
-
"isNaN",
|
|
149
|
-
"isPrototypeOf",
|
|
150
|
-
"length",
|
|
151
|
-
"Math",
|
|
152
|
-
"name",
|
|
153
|
-
"NaN",
|
|
154
|
-
"Number",
|
|
155
|
-
"Object",
|
|
156
|
-
"prototype",
|
|
157
|
-
"String",
|
|
158
|
-
"toString",
|
|
159
|
-
"undefined",
|
|
160
|
-
"valueOf"
|
|
161
|
-
]);
|
|
162
|
-
/**
|
|
163
|
-
* Returns `true` when `name` is a syntactically valid JavaScript variable name.
|
|
164
|
-
*
|
|
165
|
-
* @example
|
|
166
|
-
* ```ts
|
|
167
|
-
* isValidVarName('status') // true
|
|
168
|
-
* isValidVarName('class') // false (reserved word)
|
|
169
|
-
* isValidVarName('42foo') // false (starts with digit)
|
|
170
|
-
* ```
|
|
171
|
-
*/
|
|
172
|
-
function isValidVarName(name) {
|
|
173
|
-
if (!name || reservedWords.has(name)) return false;
|
|
174
|
-
return isIdentifier(name);
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
|
|
178
|
-
*
|
|
179
|
-
* Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
|
|
180
|
-
* even though they are not valid variable names, so use this (not {@link isValidVarName}) when
|
|
181
|
-
* deciding whether an object key needs quoting.
|
|
182
|
-
*
|
|
183
|
-
* @example
|
|
184
|
-
* ```ts
|
|
185
|
-
* isIdentifier('name') // true
|
|
186
|
-
* isIdentifier('x-total')// false
|
|
187
|
-
* ```
|
|
188
|
-
*/
|
|
189
|
-
function isIdentifier(name) {
|
|
190
|
-
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
191
|
-
}
|
|
192
|
-
//#endregion
|
|
193
|
-
//#region ../../internals/utils/src/strings.ts
|
|
194
|
-
/**
|
|
195
|
-
* Renders a dotted path or string array as an optional-chaining accessor expression rooted at
|
|
196
|
-
* `accessor`. Returns `null` for an empty path.
|
|
197
|
-
*
|
|
198
|
-
* @example
|
|
199
|
-
* ```ts
|
|
200
|
-
* getNestedAccessor('pagination.next.id', 'lastPage')
|
|
201
|
-
* // "lastPage?.['pagination']?.['next']?.['id']"
|
|
202
|
-
* ```
|
|
203
|
-
*/
|
|
204
|
-
function getNestedAccessor(param, accessor) {
|
|
205
|
-
const parts = Array.isArray(param) ? param : param.split(".");
|
|
206
|
-
if (parts.length === 0 || parts.length === 1 && parts[0] === "") return null;
|
|
207
|
-
return `${accessor}?.['${`${parts.join("']?.['")}']`}`;
|
|
208
|
-
}
|
|
209
|
-
//#endregion
|
|
210
|
-
//#region ../../internals/utils/src/url.ts
|
|
211
|
-
/**
|
|
212
|
-
* Keeps the OpenAPI parameter name as-is when it is already a valid JS identifier, and
|
|
213
|
-
* camelCases it only enough to become one otherwise (for example a hyphenated path segment).
|
|
214
|
-
*/
|
|
215
|
-
function transformParam(raw) {
|
|
216
|
-
return isValidVarName(raw) ? raw : camelCase(raw);
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Helpers for OpenAPI/Swagger paths.
|
|
220
|
-
*/
|
|
221
|
-
var Url = class Url {
|
|
222
|
-
/**
|
|
223
|
-
* Converts an OpenAPI/Swagger path to Express-style colon syntax.
|
|
224
|
-
*
|
|
225
|
-
* @example
|
|
226
|
-
* Url.toPath('/pet/{petId}') // '/pet/:petId'
|
|
227
|
-
*/
|
|
228
|
-
static toPath(path) {
|
|
229
|
-
return path.replace(/\{([^}]+)\}/g, ":$1");
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Rewrites OpenAPI placeholder names while keeping the `{...}` braces, so the generated `url`
|
|
233
|
-
* literal aligns with the grouped `path` request option that the runtime client interpolates by
|
|
234
|
-
* key.
|
|
235
|
-
*
|
|
236
|
-
* @example
|
|
237
|
-
* Url.toSafeTemplate('/user/{monetary-account-id}') // '/user/{monetaryAccountId}'
|
|
238
|
-
*/
|
|
239
|
-
static toSafeTemplate(path) {
|
|
240
|
-
return path.replace(/\{([^}]+)\}/g, (_, name) => `{${transformParam(name)}}`);
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* Converts an OpenAPI/Swagger path to a TypeScript template literal string.
|
|
244
|
-
* `prefix` is prepended inside the literal, and `replacer` transforms each parameter name.
|
|
245
|
-
*
|
|
246
|
-
* @example
|
|
247
|
-
* Url.toTemplateString('/pet/{petId}') // '`/pet/${petId}`'
|
|
248
|
-
*
|
|
249
|
-
* @example
|
|
250
|
-
* Url.toTemplateString('/pet/{petId}', { prefix: 'https://api' }) // '`https://api/pet/${petId}`'
|
|
251
|
-
*/
|
|
252
|
-
static toTemplateString(path, { prefix, replacer } = {}) {
|
|
253
|
-
const result = path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
254
|
-
if (i % 2 === 0) return part;
|
|
255
|
-
const param = transformParam(part);
|
|
256
|
-
return `\${${replacer ? replacer(param) : param}}`;
|
|
257
|
-
}).join("");
|
|
258
|
-
return `\`${prefix ?? ""}${result}\``;
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Converts an OpenAPI/Swagger path to a template literal that reads each parameter off the
|
|
262
|
-
* grouped `path` request option, e.g. `/pet/{petId}` becomes `` `/pet/${path.petId}` ``. Parameter
|
|
263
|
-
* names match the generated `path` type, and `prefix` is prepended inside the literal. Shared by
|
|
264
|
-
* the client and cypress generators that pass a grouped `path` object.
|
|
265
|
-
*
|
|
266
|
-
* @example
|
|
267
|
-
* Url.toGroupedTemplateString('/pet/{petId}') // '`/pet/${path.petId}`'
|
|
268
|
-
*/
|
|
269
|
-
static toGroupedTemplateString(path, { prefix } = {}) {
|
|
270
|
-
return Url.toTemplateString(path, {
|
|
271
|
-
prefix,
|
|
272
|
-
replacer: (name) => `path.${name}`
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
};
|
|
276
|
-
//#endregion
|
|
277
37
|
//#region ../../internals/shared/src/params.ts
|
|
278
38
|
/**
|
|
279
39
|
* Drops parameters that share the same name, keeping the first.
|
|
@@ -312,11 +72,30 @@ function operationFileEntry(node, name, extname = ".ts") {
|
|
|
312
72
|
path: node.path
|
|
313
73
|
};
|
|
314
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Resolves a dependency plugin's generated file for `node.operationId`, cached in `cache` (the
|
|
77
|
+
* current node's `ctx.cache`) under the resolver's own plugin name. Several dependents reading the
|
|
78
|
+
* same dependency for the same operation in one pass (a query plugin's several hook generators, the
|
|
79
|
+
* MCP handler, ...) share one computed name and path instead of each calling `resolver.file` again.
|
|
80
|
+
*
|
|
81
|
+
* @example Cache `plugin-ts`'s file for the current operation
|
|
82
|
+
* ```ts
|
|
83
|
+
* const fileTs = resolveDependencyOperationFile({ cache: ctx.cache, node, resolver: tsResolver, root, output })
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
function resolveDependencyOperationFile(options) {
|
|
87
|
+
const { cache, node, resolver, root, output, group } = options;
|
|
88
|
+
return cache.ensureItem(`${resolver.pluginName}:operationFile`, () => resolver.file({
|
|
89
|
+
...operationFileEntry(node, node.operationId),
|
|
90
|
+
root,
|
|
91
|
+
output,
|
|
92
|
+
group: group ?? void 0
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
315
95
|
function getOperationLink(node, link) {
|
|
316
96
|
if (!link) return null;
|
|
317
97
|
if (typeof link === "function") return link(node) ?? null;
|
|
318
|
-
|
|
319
|
-
return node.path ? `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}` : null;
|
|
98
|
+
return node.path ? `{@link ${kubb_kit.Url.toPath(node.path)}}` : null;
|
|
320
99
|
}
|
|
321
100
|
/**
|
|
322
101
|
* Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several
|
|
@@ -406,16 +185,24 @@ function buildOperationComments(node, options = {}) {
|
|
|
406
185
|
if (!splitLines) return filteredComments;
|
|
407
186
|
return filteredComments.flatMap((text) => text.split(/\r?\n/).map((line) => line.trim())).filter((comment) => Boolean(comment));
|
|
408
187
|
}
|
|
188
|
+
const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
|
|
189
|
+
/**
|
|
190
|
+
* Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each
|
|
191
|
+
* group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance
|
|
192
|
+
* (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the
|
|
193
|
+
* same parameters once per plugin.
|
|
194
|
+
*/
|
|
409
195
|
function getOperationParameters(node) {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
})),
|
|
196
|
+
const cached = operationParameterGroupsByNode.get(node);
|
|
197
|
+
if (cached) return cached;
|
|
198
|
+
const groups = {
|
|
199
|
+
path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
|
|
415
200
|
query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
|
|
416
201
|
header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
|
|
417
202
|
cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
|
|
418
203
|
};
|
|
204
|
+
operationParameterGroupsByNode.set(node, groups);
|
|
205
|
+
return groups;
|
|
419
206
|
}
|
|
420
207
|
function getStatusCodeNumber(statusCode) {
|
|
421
208
|
const code = Number(statusCode);
|
|
@@ -480,6 +267,60 @@ function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
|
480
267
|
return result;
|
|
481
268
|
}
|
|
482
269
|
//#endregion
|
|
270
|
+
//#region ../../internals/utils/src/casing.ts
|
|
271
|
+
/**
|
|
272
|
+
* Shared implementation for camelCase and PascalCase conversion.
|
|
273
|
+
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
274
|
+
* and capitalizes each word according to `pascal`.
|
|
275
|
+
*
|
|
276
|
+
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
277
|
+
*/
|
|
278
|
+
function toCamelOrPascal(text, pascal) {
|
|
279
|
+
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) => {
|
|
280
|
+
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
281
|
+
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
282
|
+
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Converts `text` to camelCase.
|
|
286
|
+
*
|
|
287
|
+
* @example Word boundaries
|
|
288
|
+
* `camelCase('hello-world') // 'helloWorld'`
|
|
289
|
+
*
|
|
290
|
+
* @example With a prefix
|
|
291
|
+
* `camelCase('tag', { prefix: 'create' }) // 'createTag'`
|
|
292
|
+
*/
|
|
293
|
+
function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
294
|
+
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Uppercases only the first character of `text`, leaving the rest untouched.
|
|
298
|
+
* Unlike {@link pascalCase} it never re-splits word boundaries or strips characters.
|
|
299
|
+
*
|
|
300
|
+
* @example
|
|
301
|
+
* `capitalize('getPetById') // 'GetPetById'`
|
|
302
|
+
*/
|
|
303
|
+
function capitalize(text) {
|
|
304
|
+
return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
|
|
305
|
+
}
|
|
306
|
+
//#endregion
|
|
307
|
+
//#region ../../internals/utils/src/strings.ts
|
|
308
|
+
/**
|
|
309
|
+
* Renders a dotted path or string array as an optional-chaining accessor expression rooted at
|
|
310
|
+
* `accessor`. Returns `null` for an empty path.
|
|
311
|
+
*
|
|
312
|
+
* @example
|
|
313
|
+
* ```ts
|
|
314
|
+
* getNestedAccessor('pagination.next.id', 'lastPage')
|
|
315
|
+
* // "lastPage?.['pagination']?.['next']?.['id']"
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
318
|
+
function getNestedAccessor(param, accessor) {
|
|
319
|
+
const parts = Array.isArray(param) ? param : param.split(".");
|
|
320
|
+
if (parts.length === 0 || parts.length === 1 && parts[0] === "") return null;
|
|
321
|
+
return `${accessor}?.['${`${parts.join("']?.['")}']`}`;
|
|
322
|
+
}
|
|
323
|
+
//#endregion
|
|
483
324
|
//#region ../../internals/shared/src/group.ts
|
|
484
325
|
/**
|
|
485
326
|
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
@@ -589,14 +430,16 @@ function buildGroupedRequestParam(node, options) {
|
|
|
589
430
|
*/
|
|
590
431
|
function buildQueryOptionsParams(node, options) {
|
|
591
432
|
const { resolver, memberTypeWrapper } = options;
|
|
592
|
-
|
|
433
|
+
const groupedParam = buildGroupedRequestParam(node, {
|
|
593
434
|
resolver,
|
|
594
435
|
memberTypeWrapper
|
|
595
|
-
})
|
|
436
|
+
});
|
|
437
|
+
const configParam = (0, _kubb_plugin_ts.createFunctionParameter)({
|
|
596
438
|
name: "config",
|
|
597
439
|
type: `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`,
|
|
598
440
|
default: "{}"
|
|
599
|
-
})
|
|
441
|
+
});
|
|
442
|
+
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [groupedParam, configParam].filter((param) => param !== null) });
|
|
600
443
|
}
|
|
601
444
|
/**
|
|
602
445
|
* Builds the call to a client `<op>` function inside a query/mutation hook body. The function takes
|
|
@@ -694,6 +537,19 @@ function resolveMutationConfig(mutation, options) {
|
|
|
694
537
|
};
|
|
695
538
|
}
|
|
696
539
|
/**
|
|
540
|
+
* Classifies an operation as a query or a mutation from the resolved `query` / `mutation` method lists.
|
|
541
|
+
* `query: false` still marks the operation as a query so the query-family generators keep matching it,
|
|
542
|
+
* and a method already claimed by `query` never counts as a mutation.
|
|
543
|
+
*/
|
|
544
|
+
function classifyOperation(node, { query, mutation }) {
|
|
545
|
+
const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
|
|
546
|
+
const queryMethods = new Set(query ? query.methods : []);
|
|
547
|
+
return {
|
|
548
|
+
isQuery,
|
|
549
|
+
isMutation: mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase())
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
697
553
|
* Applies the shared infinite-query defaults during plugin setup: a falsy value disables infinite
|
|
698
554
|
* queries, and an object merges over `queryParam: 'id'` and `initialPageParam: 0` with the cursor
|
|
699
555
|
* paths cleared.
|
|
@@ -790,7 +646,7 @@ __name(InfiniteQueryOptions$1, "InfiniteQueryOptions");
|
|
|
790
646
|
const declarationPrinter$6 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
791
647
|
const mutationKeyTransformer = ({ node }) => {
|
|
792
648
|
if (!node.path) return [];
|
|
793
|
-
return [`{ url: '${Url.toPath(node.path)}' }`];
|
|
649
|
+
return [`{ url: '${kubb_kit.Url.toPath(node.path)}' }`];
|
|
794
650
|
};
|
|
795
651
|
function MutationKey({ name, node, transformer }) {
|
|
796
652
|
const paramsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: [] });
|
|
@@ -872,7 +728,7 @@ const queryKeyTransformer = ({ node }) => {
|
|
|
872
728
|
const hasQueryParams = getOperationParameters(node).query.length > 0;
|
|
873
729
|
const hasRequestBody = !!node.requestBody?.content?.[0]?.schema;
|
|
874
730
|
return [
|
|
875
|
-
hasPathParams ? `{ url: '${Url.toPath(node.path)}', params: path }` : `{ url: '${Url.toPath(node.path)}' }`,
|
|
731
|
+
hasPathParams ? `{ url: '${kubb_kit.Url.toPath(node.path)}', params: path }` : `{ url: '${kubb_kit.Url.toPath(node.path)}' }`,
|
|
876
732
|
hasQueryParams ? "...(query ? [query] : [])" : null,
|
|
877
733
|
hasRequestBody ? "...(body ? [body] : [])" : null
|
|
878
734
|
].filter(Boolean);
|
|
@@ -966,23 +822,30 @@ function resolveContractClient(options) {
|
|
|
966
822
|
* (plugin-fetch or plugin-axios). Returns `null` when no contract plugin is in play (the inline
|
|
967
823
|
* path). The plugin injects `.kubb/client.ts` at the global output root, the same path consumers
|
|
968
824
|
* read `RequestConfig` / `ResponseErrorConfig` from.
|
|
825
|
+
*
|
|
826
|
+
* The result is cached in the current node's `cache` (`ctx.cache`) under the client plugin's name,
|
|
827
|
+
* so several dependents reading the same client plugin for one operation in a single pass
|
|
828
|
+
* (react-query's query/mutation/infinite generators, vue-query, swr, the MCP handler, ...) share
|
|
829
|
+
* one computed result instead of each re-deriving the name and path.
|
|
969
830
|
*/
|
|
970
831
|
function resolveClientOperation(options) {
|
|
971
|
-
const { clientPlugin, driver, node, root, output } = options;
|
|
832
|
+
const { clientPlugin, driver, node, root, output, cache } = options;
|
|
972
833
|
if (!clientPlugin) return null;
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
834
|
+
return cache.ensureItem(`${clientPlugin.pluginName}:clientOperation`, () => {
|
|
835
|
+
const resolver = driver.getResolver(clientPlugin.pluginName);
|
|
836
|
+
const plugin = driver.getPlugin(clientPlugin.pluginName);
|
|
837
|
+
const file = resolver.file({
|
|
838
|
+
...operationFileEntry(node, node.operationId),
|
|
839
|
+
root,
|
|
840
|
+
output: plugin?.options?.output ?? output,
|
|
841
|
+
group: plugin?.options?.group ?? void 0
|
|
842
|
+
});
|
|
843
|
+
return {
|
|
844
|
+
name: resolver.name(node.operationId),
|
|
845
|
+
path: file.path,
|
|
846
|
+
clientPath: node_path.default.resolve(root, ".kubb/client.ts")
|
|
847
|
+
};
|
|
980
848
|
});
|
|
981
|
-
return {
|
|
982
|
-
name: resolver.name(node.operationId),
|
|
983
|
-
path: file.path,
|
|
984
|
-
clientPath: node_path.default.resolve(root, ".kubb/client.ts")
|
|
985
|
-
};
|
|
986
849
|
}
|
|
987
850
|
//#endregion
|
|
988
851
|
//#region src/utils.ts
|
|
@@ -1106,10 +969,11 @@ function buildInfiniteQueryParamsNode(node, options) {
|
|
|
1106
969
|
}`,
|
|
1107
970
|
default: "{}"
|
|
1108
971
|
});
|
|
1109
|
-
|
|
972
|
+
const groupedParam = buildGroupedRequestParam(node, {
|
|
1110
973
|
resolver,
|
|
1111
974
|
memberTypeWrapper: maybeRefOrGetter
|
|
1112
|
-
})
|
|
975
|
+
});
|
|
976
|
+
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [groupedParam, optionsParam].filter((param) => param !== null) });
|
|
1113
977
|
}
|
|
1114
978
|
function InfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver }) {
|
|
1115
979
|
const { TData, TError } = buildResponseTypes(node, tsResolver);
|
|
@@ -1178,13 +1042,14 @@ function resolveMutationRequestType(node, resolver) {
|
|
|
1178
1042
|
function buildMutationParamsNode(node, options) {
|
|
1179
1043
|
const { resolver } = options;
|
|
1180
1044
|
const { TData, TError } = buildResponseTypes(node, resolver);
|
|
1045
|
+
const TRequest = resolveMutationRequestType(node, resolver);
|
|
1181
1046
|
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
|
|
1182
1047
|
name: "options",
|
|
1183
1048
|
type: `{
|
|
1184
1049
|
mutation?: MutationObserverOptions<${[
|
|
1185
1050
|
TData,
|
|
1186
1051
|
TError,
|
|
1187
|
-
|
|
1052
|
+
TRequest,
|
|
1188
1053
|
"TContext"
|
|
1189
1054
|
].join(", ")}> & { client?: QueryClient },
|
|
1190
1055
|
client?: ${buildRequestConfigType(node)},
|
|
@@ -1258,10 +1123,11 @@ function buildQueryParamsNode(node, options) {
|
|
|
1258
1123
|
}`,
|
|
1259
1124
|
default: "{}"
|
|
1260
1125
|
});
|
|
1261
|
-
|
|
1126
|
+
const groupedParam = buildGroupedRequestParam(node, {
|
|
1262
1127
|
resolver,
|
|
1263
1128
|
memberTypeWrapper: maybeRefOrGetter
|
|
1264
|
-
})
|
|
1129
|
+
});
|
|
1130
|
+
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [groupedParam, optionsParam].filter((param) => param !== null) });
|
|
1265
1131
|
}
|
|
1266
1132
|
function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver }) {
|
|
1267
1133
|
const { TData, TError } = buildResponseTypes(node, tsResolver);
|
|
@@ -1309,9 +1175,9 @@ function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, t
|
|
|
1309
1175
|
//#region src/generators/infiniteQueryGenerator.tsx
|
|
1310
1176
|
/**
|
|
1311
1177
|
* Built-in generator for `useInfiniteQuery` composables. Enabled when
|
|
1312
|
-
* `pluginVueQuery({ infinite: { ... } })`. Emits one
|
|
1313
|
-
* composable per query operation, wiring the
|
|
1314
|
-
* TanStack Query's cursor-based pagination.
|
|
1178
|
+
* `pluginVueQuery({ infinite: { ... }, hooks: true })`. Emits one
|
|
1179
|
+
* `useFooInfiniteQuery` composable per query operation, wiring the
|
|
1180
|
+
* configured cursor path into TanStack Query's cursor-based pagination.
|
|
1315
1181
|
*/
|
|
1316
1182
|
const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
|
|
1317
1183
|
name: "vue-query-infinite",
|
|
@@ -1323,11 +1189,12 @@ const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1323
1189
|
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
1324
1190
|
if (!pluginTs) return null;
|
|
1325
1191
|
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
1326
|
-
const isQuery
|
|
1327
|
-
|
|
1328
|
-
|
|
1192
|
+
const { isQuery, isMutation } = classifyOperation(node, {
|
|
1193
|
+
query,
|
|
1194
|
+
mutation
|
|
1195
|
+
});
|
|
1329
1196
|
const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
|
|
1330
|
-
if (!isQuery || isMutation || !infiniteOptions) return null;
|
|
1197
|
+
if (!isQuery || isMutation || !infiniteOptions || !hooks) return null;
|
|
1331
1198
|
const normalizeKey = (key) => key.replace(/\?$/, "");
|
|
1332
1199
|
const queryParamKeys = getOperationParameters(node).query.map((p) => p.name);
|
|
1333
1200
|
if (!(infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false)) return null;
|
|
@@ -1337,7 +1204,8 @@ const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1337
1204
|
driver,
|
|
1338
1205
|
node,
|
|
1339
1206
|
root,
|
|
1340
|
-
output
|
|
1207
|
+
output,
|
|
1208
|
+
cache: ctx.cache
|
|
1341
1209
|
});
|
|
1342
1210
|
if (!contractOp) return null;
|
|
1343
1211
|
const queryName = resolver.infiniteQuery.name(node);
|
|
@@ -1351,15 +1219,20 @@ const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1351
1219
|
output,
|
|
1352
1220
|
group: group ?? void 0
|
|
1353
1221
|
}),
|
|
1354
|
-
fileTs:
|
|
1355
|
-
|
|
1222
|
+
fileTs: resolveDependencyOperationFile({
|
|
1223
|
+
cache: ctx.cache,
|
|
1224
|
+
node,
|
|
1225
|
+
resolver: tsResolver,
|
|
1356
1226
|
root,
|
|
1357
1227
|
output: pluginTs.options?.output ?? output,
|
|
1358
|
-
group: pluginTs.options?.group
|
|
1228
|
+
group: pluginTs.options?.group
|
|
1359
1229
|
})
|
|
1360
1230
|
};
|
|
1361
|
-
const
|
|
1362
|
-
|
|
1231
|
+
const { queryParamsTypeName } = resolvePageParamType(node, {
|
|
1232
|
+
resolver: tsResolver,
|
|
1233
|
+
initialPageParam: infiniteOptions.initialPageParam,
|
|
1234
|
+
queryParam: infiniteOptions.queryParam
|
|
1235
|
+
});
|
|
1363
1236
|
const importedTypeNames = [
|
|
1364
1237
|
tsResolver.response.options(node),
|
|
1365
1238
|
queryParamsTypeName,
|
|
@@ -1445,32 +1318,30 @@ const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1445
1318
|
initialPageParam: infiniteOptions.initialPageParam,
|
|
1446
1319
|
queryParam: infiniteOptions.queryParam
|
|
1447
1320
|
}),
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
})
|
|
1473
|
-
] })
|
|
1321
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1322
|
+
name: ["useInfiniteQuery"],
|
|
1323
|
+
path: importPath
|
|
1324
|
+
}),
|
|
1325
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1326
|
+
name: [
|
|
1327
|
+
"QueryKey",
|
|
1328
|
+
"QueryClient",
|
|
1329
|
+
"UseInfiniteQueryOptions",
|
|
1330
|
+
"UseInfiniteQueryReturnType"
|
|
1331
|
+
],
|
|
1332
|
+
path: importPath,
|
|
1333
|
+
isTypeOnly: true
|
|
1334
|
+
}),
|
|
1335
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(InfiniteQuery, {
|
|
1336
|
+
name: queryName,
|
|
1337
|
+
queryOptionsName,
|
|
1338
|
+
queryKeyName,
|
|
1339
|
+
queryKeyTypeName,
|
|
1340
|
+
node,
|
|
1341
|
+
tsResolver,
|
|
1342
|
+
initialPageParam: infiniteOptions.initialPageParam,
|
|
1343
|
+
queryParam: infiniteOptions.queryParam
|
|
1344
|
+
})
|
|
1474
1345
|
]
|
|
1475
1346
|
});
|
|
1476
1347
|
}
|
|
@@ -1492,16 +1363,19 @@ const mutationGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1492
1363
|
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
1493
1364
|
if (!pluginTs) return null;
|
|
1494
1365
|
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
1495
|
-
const
|
|
1496
|
-
|
|
1497
|
-
|
|
1366
|
+
const { isMutation } = classifyOperation(node, {
|
|
1367
|
+
query,
|
|
1368
|
+
mutation
|
|
1369
|
+
});
|
|
1370
|
+
if (!isMutation) return null;
|
|
1498
1371
|
const importPath = mutation ? mutation.importPath : "@tanstack/vue-query";
|
|
1499
1372
|
const contractOp = resolveClientOperation({
|
|
1500
1373
|
clientPlugin: { pluginName: client.pluginName },
|
|
1501
1374
|
driver,
|
|
1502
1375
|
node,
|
|
1503
1376
|
root,
|
|
1504
|
-
output
|
|
1377
|
+
output,
|
|
1378
|
+
cache: ctx.cache
|
|
1505
1379
|
});
|
|
1506
1380
|
if (!contractOp) return null;
|
|
1507
1381
|
const mutationHookName = resolver.mutation.name(node);
|
|
@@ -1514,11 +1388,13 @@ const mutationGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1514
1388
|
output,
|
|
1515
1389
|
group: group ?? void 0
|
|
1516
1390
|
}),
|
|
1517
|
-
fileTs:
|
|
1518
|
-
|
|
1391
|
+
fileTs: resolveDependencyOperationFile({
|
|
1392
|
+
cache: ctx.cache,
|
|
1393
|
+
node,
|
|
1394
|
+
resolver: tsResolver,
|
|
1519
1395
|
root,
|
|
1520
1396
|
output: pluginTs.options?.output ?? output,
|
|
1521
|
-
group: pluginTs.options?.group
|
|
1397
|
+
group: pluginTs.options?.group
|
|
1522
1398
|
})
|
|
1523
1399
|
};
|
|
1524
1400
|
const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
|
|
@@ -1620,9 +1496,10 @@ const queryGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1620
1496
|
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
1621
1497
|
if (!pluginTs) return null;
|
|
1622
1498
|
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
1623
|
-
const isQuery
|
|
1624
|
-
|
|
1625
|
-
|
|
1499
|
+
const { isQuery, isMutation } = classifyOperation(node, {
|
|
1500
|
+
query,
|
|
1501
|
+
mutation
|
|
1502
|
+
});
|
|
1626
1503
|
if (!isQuery || isMutation) return null;
|
|
1627
1504
|
const importPath = query ? query.importPath : "@tanstack/vue-query";
|
|
1628
1505
|
const contractOp = resolveClientOperation({
|
|
@@ -1630,7 +1507,8 @@ const queryGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1630
1507
|
driver,
|
|
1631
1508
|
node,
|
|
1632
1509
|
root,
|
|
1633
|
-
output
|
|
1510
|
+
output,
|
|
1511
|
+
cache: ctx.cache
|
|
1634
1512
|
});
|
|
1635
1513
|
if (!contractOp) return null;
|
|
1636
1514
|
const queryName = resolver.query.name(node);
|
|
@@ -1644,11 +1522,13 @@ const queryGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1644
1522
|
output,
|
|
1645
1523
|
group: group ?? void 0
|
|
1646
1524
|
}),
|
|
1647
|
-
fileTs:
|
|
1648
|
-
|
|
1525
|
+
fileTs: resolveDependencyOperationFile({
|
|
1526
|
+
cache: ctx.cache,
|
|
1527
|
+
node,
|
|
1528
|
+
resolver: tsResolver,
|
|
1649
1529
|
root,
|
|
1650
1530
|
output: pluginTs.options?.output ?? output,
|
|
1651
|
-
group: pluginTs.options?.group
|
|
1531
|
+
group: pluginTs.options?.group
|
|
1652
1532
|
})
|
|
1653
1533
|
};
|
|
1654
1534
|
const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
|