@kubb/plugin-swr 5.0.0-beta.99 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +159 -281
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +156 -278
- package/dist/index.js.map +1 -1
- package/package.json +16 -8
package/dist/index.cjs
CHANGED
|
@@ -23,240 +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/url.ts
|
|
194
|
-
/**
|
|
195
|
-
* Keeps the OpenAPI parameter name as-is when it is already a valid JS identifier, and
|
|
196
|
-
* camelCases it only enough to become one otherwise (for example a hyphenated path segment).
|
|
197
|
-
*/
|
|
198
|
-
function transformParam(raw) {
|
|
199
|
-
return isValidVarName(raw) ? raw : camelCase(raw);
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Helpers for OpenAPI/Swagger paths.
|
|
203
|
-
*/
|
|
204
|
-
var Url = class Url {
|
|
205
|
-
/**
|
|
206
|
-
* Converts an OpenAPI/Swagger path to Express-style colon syntax.
|
|
207
|
-
*
|
|
208
|
-
* @example
|
|
209
|
-
* Url.toPath('/pet/{petId}') // '/pet/:petId'
|
|
210
|
-
*/
|
|
211
|
-
static toPath(path) {
|
|
212
|
-
return path.replace(/\{([^}]+)\}/g, ":$1");
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Rewrites OpenAPI placeholder names while keeping the `{...}` braces, so the generated `url`
|
|
216
|
-
* literal aligns with the grouped `path` request option that the runtime client interpolates by
|
|
217
|
-
* key.
|
|
218
|
-
*
|
|
219
|
-
* @example
|
|
220
|
-
* Url.toSafeTemplate('/user/{monetary-account-id}') // '/user/{monetaryAccountId}'
|
|
221
|
-
*/
|
|
222
|
-
static toSafeTemplate(path) {
|
|
223
|
-
return path.replace(/\{([^}]+)\}/g, (_, name) => `{${transformParam(name)}}`);
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Converts an OpenAPI/Swagger path to a TypeScript template literal string.
|
|
227
|
-
* `prefix` is prepended inside the literal, and `replacer` transforms each parameter name.
|
|
228
|
-
*
|
|
229
|
-
* @example
|
|
230
|
-
* Url.toTemplateString('/pet/{petId}') // '`/pet/${petId}`'
|
|
231
|
-
*
|
|
232
|
-
* @example
|
|
233
|
-
* Url.toTemplateString('/pet/{petId}', { prefix: 'https://api' }) // '`https://api/pet/${petId}`'
|
|
234
|
-
*/
|
|
235
|
-
static toTemplateString(path, { prefix, replacer } = {}) {
|
|
236
|
-
const result = path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
237
|
-
if (i % 2 === 0) return part;
|
|
238
|
-
const param = transformParam(part);
|
|
239
|
-
return `\${${replacer ? replacer(param) : param}}`;
|
|
240
|
-
}).join("");
|
|
241
|
-
return `\`${prefix ?? ""}${result}\``;
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Converts an OpenAPI/Swagger path to a template literal that reads each parameter off the
|
|
245
|
-
* grouped `path` request option, e.g. `/pet/{petId}` becomes `` `/pet/${path.petId}` ``. Parameter
|
|
246
|
-
* names match the generated `path` type, and `prefix` is prepended inside the literal. Shared by
|
|
247
|
-
* the client and cypress generators that pass a grouped `path` object.
|
|
248
|
-
*
|
|
249
|
-
* @example
|
|
250
|
-
* Url.toGroupedTemplateString('/pet/{petId}') // '`/pet/${path.petId}`'
|
|
251
|
-
*/
|
|
252
|
-
static toGroupedTemplateString(path, { prefix } = {}) {
|
|
253
|
-
return Url.toTemplateString(path, {
|
|
254
|
-
prefix,
|
|
255
|
-
replacer: (name) => `path.${name}`
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
//#endregion
|
|
260
37
|
//#region ../../internals/shared/src/params.ts
|
|
261
38
|
/**
|
|
262
39
|
* Drops parameters that share the same name, keeping the first.
|
|
@@ -295,11 +72,30 @@ function operationFileEntry(node, name, extname = ".ts") {
|
|
|
295
72
|
path: node.path
|
|
296
73
|
};
|
|
297
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
|
+
}
|
|
298
95
|
function getOperationLink(node, link) {
|
|
299
96
|
if (!link) return null;
|
|
300
97
|
if (typeof link === "function") return link(node) ?? null;
|
|
301
|
-
|
|
302
|
-
return node.path ? `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}` : null;
|
|
98
|
+
return node.path ? `{@link ${kubb_kit.Url.toPath(node.path)}}` : null;
|
|
303
99
|
}
|
|
304
100
|
/**
|
|
305
101
|
* Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several
|
|
@@ -389,16 +185,24 @@ function buildOperationComments(node, options = {}) {
|
|
|
389
185
|
if (!splitLines) return filteredComments;
|
|
390
186
|
return filteredComments.flatMap((text) => text.split(/\r?\n/).map((line) => line.trim())).filter((comment) => Boolean(comment));
|
|
391
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
|
+
*/
|
|
392
195
|
function getOperationParameters(node) {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
})),
|
|
196
|
+
const cached = operationParameterGroupsByNode.get(node);
|
|
197
|
+
if (cached) return cached;
|
|
198
|
+
const groups = {
|
|
199
|
+
path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
|
|
398
200
|
query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
|
|
399
201
|
header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
|
|
400
202
|
cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
|
|
401
203
|
};
|
|
204
|
+
operationParameterGroupsByNode.set(node, groups);
|
|
205
|
+
return groups;
|
|
402
206
|
}
|
|
403
207
|
function getStatusCodeNumber(statusCode) {
|
|
404
208
|
const code = Number(statusCode);
|
|
@@ -460,6 +264,43 @@ function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
|
460
264
|
return result;
|
|
461
265
|
}
|
|
462
266
|
//#endregion
|
|
267
|
+
//#region ../../internals/utils/src/casing.ts
|
|
268
|
+
/**
|
|
269
|
+
* Shared implementation for camelCase and PascalCase conversion.
|
|
270
|
+
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
271
|
+
* and capitalizes each word according to `pascal`.
|
|
272
|
+
*
|
|
273
|
+
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
274
|
+
*/
|
|
275
|
+
function toCamelOrPascal(text, pascal) {
|
|
276
|
+
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) => {
|
|
277
|
+
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
278
|
+
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
279
|
+
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Converts `text` to camelCase.
|
|
283
|
+
*
|
|
284
|
+
* @example Word boundaries
|
|
285
|
+
* `camelCase('hello-world') // 'helloWorld'`
|
|
286
|
+
*
|
|
287
|
+
* @example With a prefix
|
|
288
|
+
* `camelCase('tag', { prefix: 'create' }) // 'createTag'`
|
|
289
|
+
*/
|
|
290
|
+
function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
291
|
+
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Uppercases only the first character of `text`, leaving the rest untouched.
|
|
295
|
+
* Unlike {@link pascalCase} it never re-splits word boundaries or strips characters.
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* `capitalize('getPetById') // 'GetPetById'`
|
|
299
|
+
*/
|
|
300
|
+
function capitalize(text) {
|
|
301
|
+
return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
|
|
302
|
+
}
|
|
303
|
+
//#endregion
|
|
463
304
|
//#region ../../internals/shared/src/group.ts
|
|
464
305
|
/**
|
|
465
306
|
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
@@ -579,23 +420,30 @@ function resolveContractClient(options) {
|
|
|
579
420
|
* (plugin-fetch or plugin-axios). Returns `null` when no contract plugin is in play (the inline
|
|
580
421
|
* path). The plugin injects `.kubb/client.ts` at the global output root, the same path consumers
|
|
581
422
|
* read `RequestConfig` / `ResponseErrorConfig` from.
|
|
423
|
+
*
|
|
424
|
+
* The result is cached in the current node's `cache` (`ctx.cache`) under the client plugin's name,
|
|
425
|
+
* so several dependents reading the same client plugin for one operation in a single pass
|
|
426
|
+
* (react-query's query/mutation/infinite generators, vue-query, swr, the MCP handler, ...) share
|
|
427
|
+
* one computed result instead of each re-deriving the name and path.
|
|
582
428
|
*/
|
|
583
429
|
function resolveClientOperation(options) {
|
|
584
|
-
const { clientPlugin, driver, node, root, output } = options;
|
|
430
|
+
const { clientPlugin, driver, node, root, output, cache } = options;
|
|
585
431
|
if (!clientPlugin) return null;
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
432
|
+
return cache.ensureItem(`${clientPlugin.pluginName}:clientOperation`, () => {
|
|
433
|
+
const resolver = driver.getResolver(clientPlugin.pluginName);
|
|
434
|
+
const plugin = driver.getPlugin(clientPlugin.pluginName);
|
|
435
|
+
const file = resolver.file({
|
|
436
|
+
...operationFileEntry(node, node.operationId),
|
|
437
|
+
root,
|
|
438
|
+
output: plugin?.options?.output ?? output,
|
|
439
|
+
group: plugin?.options?.group ?? void 0
|
|
440
|
+
});
|
|
441
|
+
return {
|
|
442
|
+
name: resolver.name(node.operationId),
|
|
443
|
+
path: file.path,
|
|
444
|
+
clientPath: node_path.default.resolve(root, ".kubb/client.ts")
|
|
445
|
+
};
|
|
593
446
|
});
|
|
594
|
-
return {
|
|
595
|
-
name: resolver.name(node.operationId),
|
|
596
|
-
path: file.path,
|
|
597
|
-
clientPath: node_path.default.resolve(root, ".kubb/client.ts")
|
|
598
|
-
};
|
|
599
447
|
}
|
|
600
448
|
//#endregion
|
|
601
449
|
//#region ../../internals/tanstack-query/src/utils.ts
|
|
@@ -663,14 +511,16 @@ function buildGroupedRequestParam(node, options) {
|
|
|
663
511
|
*/
|
|
664
512
|
function buildQueryOptionsParams(node, options) {
|
|
665
513
|
const { resolver, memberTypeWrapper } = options;
|
|
666
|
-
|
|
514
|
+
const groupedParam = buildGroupedRequestParam(node, {
|
|
667
515
|
resolver,
|
|
668
516
|
memberTypeWrapper
|
|
669
|
-
})
|
|
517
|
+
});
|
|
518
|
+
const configParam = (0, _kubb_plugin_ts.createFunctionParameter)({
|
|
670
519
|
name: "config",
|
|
671
520
|
type: `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`,
|
|
672
521
|
default: "{}"
|
|
673
|
-
})
|
|
522
|
+
});
|
|
523
|
+
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [groupedParam, configParam].filter((param) => param !== null) });
|
|
674
524
|
}
|
|
675
525
|
/**
|
|
676
526
|
* Builds the call to a client `<op>` function inside a query/mutation hook body. The function takes
|
|
@@ -728,6 +578,29 @@ function resolveMutationConfig(mutation, options) {
|
|
|
728
578
|
};
|
|
729
579
|
}
|
|
730
580
|
/**
|
|
581
|
+
* Classifies an operation as a query or a mutation from the resolved `query` / `mutation` method lists.
|
|
582
|
+
* `query: false` still marks the operation as a query so the query-family generators keep matching it,
|
|
583
|
+
* and a method already claimed by `query` never counts as a mutation.
|
|
584
|
+
*/
|
|
585
|
+
function classifyOperation(node, { query, mutation }) {
|
|
586
|
+
const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
|
|
587
|
+
const queryMethods = new Set(query ? query.methods : []);
|
|
588
|
+
return {
|
|
589
|
+
isQuery,
|
|
590
|
+
isMutation: mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase())
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* The request groups a query key is built from, matching `buildQueryKeyParams`. Headers are
|
|
595
|
+
* deliberately absent: they do not identify a cache entry, so the key factory takes no parameter
|
|
596
|
+
* for an operation that only carries headers.
|
|
597
|
+
*/
|
|
598
|
+
const queryKeyGroupOrder = [
|
|
599
|
+
"path",
|
|
600
|
+
"query",
|
|
601
|
+
"body"
|
|
602
|
+
];
|
|
603
|
+
/**
|
|
731
604
|
* Build QueryKey params as the grouped `{ path, query, body }` object (NO headers, NO config),
|
|
732
605
|
* typed from the operation's `Options` minus `url`. The query key transformer reads the
|
|
733
606
|
* grouped `path`/`query`/`body` bindings.
|
|
@@ -736,11 +609,7 @@ function buildQueryKeyParams(node, options) {
|
|
|
736
609
|
const { resolver } = options;
|
|
737
610
|
const groupedParam = buildGroupedRequestParam(node, {
|
|
738
611
|
resolver,
|
|
739
|
-
keys:
|
|
740
|
-
"path",
|
|
741
|
-
"query",
|
|
742
|
-
"body"
|
|
743
|
-
]
|
|
612
|
+
keys: queryKeyGroupOrder
|
|
744
613
|
});
|
|
745
614
|
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedParam ? [groupedParam] : [] });
|
|
746
615
|
}
|
|
@@ -749,7 +618,7 @@ function buildQueryKeyParams(node, options) {
|
|
|
749
618
|
const declarationPrinter$4 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
750
619
|
const mutationKeyTransformer = ({ node }) => {
|
|
751
620
|
if (!node.path) return [];
|
|
752
|
-
return [`{ url: '${Url.toPath(node.path)}' }`];
|
|
621
|
+
return [`{ url: '${kubb_kit.Url.toPath(node.path)}' }`];
|
|
753
622
|
};
|
|
754
623
|
function MutationKey$1({ name, node, transformer }) {
|
|
755
624
|
const paramsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: [] });
|
|
@@ -834,7 +703,7 @@ const queryKeyTransformer = ({ node }) => {
|
|
|
834
703
|
const hasQueryParams = getOperationParameters(node).query.length > 0;
|
|
835
704
|
const hasRequestBody = !!node.requestBody?.content?.[0]?.schema;
|
|
836
705
|
return [
|
|
837
|
-
hasPathParams ? `{ url: '${Url.toPath(node.path)}', params: path }` : `{ url: '${Url.toPath(node.path)}' }`,
|
|
706
|
+
hasPathParams ? `{ url: '${kubb_kit.Url.toPath(node.path)}', params: path }` : `{ url: '${kubb_kit.Url.toPath(node.path)}' }`,
|
|
838
707
|
hasQueryParams ? "...(query ? [query] : [])" : null,
|
|
839
708
|
hasRequestBody ? "...(body ? [body] : [])" : null
|
|
840
709
|
].filter(Boolean);
|
|
@@ -874,10 +743,12 @@ function buildMutationParamsNode(node, options) {
|
|
|
874
743
|
const { mutationKeyTypeName, mutationArgTypeName, resolver } = options;
|
|
875
744
|
const responseName = resolver.response.response(node);
|
|
876
745
|
const errorNames = resolveErrorNames(node, resolver);
|
|
746
|
+
const TData = responseName;
|
|
747
|
+
const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
|
|
877
748
|
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
|
|
878
749
|
name: "options",
|
|
879
750
|
type: `{
|
|
880
|
-
mutation?: SWRMutationConfiguration<${
|
|
751
|
+
mutation?: SWRMutationConfiguration<${TData}, ${TError}, ${mutationKeyTypeName} | null, ${mutationArgTypeName}> & { throwOnError?: boolean },
|
|
881
752
|
client?: ${buildRequestConfigType(node)},
|
|
882
753
|
shouldFetch?: boolean,
|
|
883
754
|
}`,
|
|
@@ -894,11 +765,10 @@ function Mutation({ name, clientName, mutationKeyName, mutationKeyTypeName, muta
|
|
|
894
765
|
const groupedParamsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedParam ? [groupedParam] : [] });
|
|
895
766
|
const argTypeBody = hasMutationParams ? tsResolver.response.options(node) : "";
|
|
896
767
|
const argBindingStr = hasMutationParams ? callPrinter$1.print(groupedParamsNode) ?? "" : "";
|
|
897
|
-
const mutationFnBody = `
|
|
768
|
+
const mutationFnBody = `return ${buildClientCall(node, {
|
|
898
769
|
clientName,
|
|
899
770
|
signal: false
|
|
900
|
-
})}
|
|
901
|
-
return data`;
|
|
771
|
+
})}.unwrap()`;
|
|
902
772
|
const generics = [
|
|
903
773
|
TData,
|
|
904
774
|
TError,
|
|
@@ -972,17 +842,20 @@ function buildQueryParamsNode(node, options) {
|
|
|
972
842
|
const { resolver } = options;
|
|
973
843
|
const responseName = resolver.response.response(node);
|
|
974
844
|
const errorNames = resolveErrorNames(node, resolver);
|
|
845
|
+
const TData = responseName;
|
|
846
|
+
const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
|
|
975
847
|
const optionsParam = (0, _kubb_plugin_ts.createFunctionParameter)({
|
|
976
848
|
name: "options",
|
|
977
849
|
type: `{
|
|
978
|
-
query?: SWRConfiguration<${[
|
|
850
|
+
query?: SWRConfiguration<${[TData, TError].join(", ")}>,
|
|
979
851
|
client?: ${buildClientOptionType()},
|
|
980
852
|
shouldFetch?: boolean,
|
|
981
853
|
immutable?: boolean
|
|
982
854
|
}`,
|
|
983
855
|
default: "{}"
|
|
984
856
|
});
|
|
985
|
-
|
|
857
|
+
const groupedParam = buildGroupedRequestParam(node, { resolver });
|
|
858
|
+
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [groupedParam, optionsParam].filter((param) => param !== null) });
|
|
986
859
|
}
|
|
987
860
|
function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver }) {
|
|
988
861
|
const responseName = tsResolver.response.response(node);
|
|
@@ -1034,11 +907,10 @@ const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declara
|
|
|
1034
907
|
function QueryOptions({ name, clientName, node, tsResolver }) {
|
|
1035
908
|
const paramsNode = buildQueryOptionsParams(node, { resolver: tsResolver });
|
|
1036
909
|
const paramsSignature = declarationPrinter.print(paramsNode) ?? "";
|
|
1037
|
-
const fetcherBody = `
|
|
910
|
+
const fetcherBody = `return ${buildClientCall(node, {
|
|
1038
911
|
clientName,
|
|
1039
912
|
signal: false
|
|
1040
|
-
})}
|
|
1041
|
-
return data`;
|
|
913
|
+
})}.unwrap()`;
|
|
1042
914
|
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
1043
915
|
name,
|
|
1044
916
|
isExportable: true,
|
|
@@ -1074,16 +946,19 @@ const mutationGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1074
946
|
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
1075
947
|
if (!pluginTs) return null;
|
|
1076
948
|
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
1077
|
-
const
|
|
1078
|
-
|
|
1079
|
-
|
|
949
|
+
const { isMutation } = classifyOperation(node, {
|
|
950
|
+
query,
|
|
951
|
+
mutation
|
|
952
|
+
});
|
|
953
|
+
if (!isMutation) return null;
|
|
1080
954
|
const importPath = mutation ? mutation.importPath : "swr/mutation";
|
|
1081
955
|
const contractOp = resolveClientOperation({
|
|
1082
956
|
clientPlugin: { pluginName: client.pluginName },
|
|
1083
957
|
driver,
|
|
1084
958
|
node,
|
|
1085
959
|
root,
|
|
1086
|
-
output
|
|
960
|
+
output,
|
|
961
|
+
cache: ctx.cache
|
|
1087
962
|
});
|
|
1088
963
|
if (!contractOp) return null;
|
|
1089
964
|
const mutationHookName = resolver.mutation.name(node);
|
|
@@ -1100,11 +975,10 @@ const mutationGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1100
975
|
output,
|
|
1101
976
|
group
|
|
1102
977
|
}),
|
|
1103
|
-
fileTs:
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
path: node.path,
|
|
978
|
+
fileTs: resolveDependencyOperationFile({
|
|
979
|
+
cache: ctx.cache,
|
|
980
|
+
node,
|
|
981
|
+
resolver: tsResolver,
|
|
1108
982
|
root,
|
|
1109
983
|
output: pluginTs.options?.output ?? output,
|
|
1110
984
|
group: pluginTs.options?.group
|
|
@@ -1195,18 +1069,23 @@ const queryGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1195
1069
|
operation(node, ctx) {
|
|
1196
1070
|
if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
|
|
1197
1071
|
const { config, driver, resolver, root } = ctx;
|
|
1198
|
-
const { output, query, client, group } = ctx.options;
|
|
1072
|
+
const { output, query, mutation, client, group } = ctx.options;
|
|
1199
1073
|
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
1200
1074
|
if (!pluginTs) return null;
|
|
1201
1075
|
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
1202
|
-
|
|
1076
|
+
const { isQuery } = classifyOperation(node, {
|
|
1077
|
+
query,
|
|
1078
|
+
mutation
|
|
1079
|
+
});
|
|
1080
|
+
if (!isQuery) return null;
|
|
1203
1081
|
const importPath = query ? query.importPath : "swr";
|
|
1204
1082
|
const contractOp = resolveClientOperation({
|
|
1205
1083
|
clientPlugin: { pluginName: client.pluginName },
|
|
1206
1084
|
driver,
|
|
1207
1085
|
node,
|
|
1208
1086
|
root,
|
|
1209
|
-
output
|
|
1087
|
+
output,
|
|
1088
|
+
cache: ctx.cache
|
|
1210
1089
|
});
|
|
1211
1090
|
if (!contractOp) return null;
|
|
1212
1091
|
const queryName = resolver.query.name(node);
|
|
@@ -1223,11 +1102,10 @@ const queryGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1223
1102
|
output,
|
|
1224
1103
|
group
|
|
1225
1104
|
}),
|
|
1226
|
-
fileTs:
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
path: node.path,
|
|
1105
|
+
fileTs: resolveDependencyOperationFile({
|
|
1106
|
+
cache: ctx.cache,
|
|
1107
|
+
node,
|
|
1108
|
+
resolver: tsResolver,
|
|
1231
1109
|
root,
|
|
1232
1110
|
output: pluginTs.options?.output ?? output,
|
|
1233
1111
|
group: pluginTs.options?.group
|