@kubb/plugin-swr 5.0.0-beta.99 → 5.0.0
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 +144 -270
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +141 -267
- package/dist/index.js.map +1 -1
- package/package.json +5 -8
package/dist/index.js
CHANGED
|
@@ -1,232 +1,9 @@
|
|
|
1
1
|
import { t as __name } from "./rolldown-runtime-C0LytTxp.js";
|
|
2
|
+
import { Resolver, Url, ast, createResolver, defineGenerator, definePlugin } from "kubb/kit";
|
|
2
3
|
import path from "node:path";
|
|
3
|
-
import { Resolver, ast, createResolver, defineGenerator, definePlugin } from "kubb/kit";
|
|
4
4
|
import { createFunctionParameter, createFunctionParameters, createObjectBindingPattern, createTypeLiteral, functionPrinter, pluginTsName } from "@kubb/plugin-ts";
|
|
5
5
|
import { File, Function, Type, jsxRenderer } from "kubb/jsx";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
|
|
7
|
-
//#region ../../internals/utils/src/casing.ts
|
|
8
|
-
/**
|
|
9
|
-
* Shared implementation for camelCase and PascalCase conversion.
|
|
10
|
-
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
11
|
-
* and capitalizes each word according to `pascal`.
|
|
12
|
-
*
|
|
13
|
-
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
14
|
-
*/
|
|
15
|
-
function toCamelOrPascal(text, pascal) {
|
|
16
|
-
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) => {
|
|
17
|
-
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
18
|
-
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
19
|
-
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Converts `text` to camelCase.
|
|
23
|
-
*
|
|
24
|
-
* @example Word boundaries
|
|
25
|
-
* `camelCase('hello-world') // 'helloWorld'`
|
|
26
|
-
*
|
|
27
|
-
* @example With a prefix
|
|
28
|
-
* `camelCase('tag', { prefix: 'create' }) // 'createTag'`
|
|
29
|
-
*/
|
|
30
|
-
function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
31
|
-
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Uppercases only the first character of `text`, leaving the rest untouched.
|
|
35
|
-
* Unlike {@link pascalCase} it never re-splits word boundaries or strips characters.
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* `capitalize('getPetById') // 'GetPetById'`
|
|
39
|
-
*/
|
|
40
|
-
function capitalize(text) {
|
|
41
|
-
return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
|
|
42
|
-
}
|
|
43
|
-
//#endregion
|
|
44
|
-
//#region ../../internals/utils/src/reserved.ts
|
|
45
|
-
/**
|
|
46
|
-
* JavaScript and Java reserved words.
|
|
47
|
-
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
48
|
-
*/
|
|
49
|
-
const reservedWords = /* @__PURE__ */ new Set([
|
|
50
|
-
"abstract",
|
|
51
|
-
"arguments",
|
|
52
|
-
"boolean",
|
|
53
|
-
"break",
|
|
54
|
-
"byte",
|
|
55
|
-
"case",
|
|
56
|
-
"catch",
|
|
57
|
-
"char",
|
|
58
|
-
"class",
|
|
59
|
-
"const",
|
|
60
|
-
"continue",
|
|
61
|
-
"debugger",
|
|
62
|
-
"default",
|
|
63
|
-
"delete",
|
|
64
|
-
"do",
|
|
65
|
-
"double",
|
|
66
|
-
"else",
|
|
67
|
-
"enum",
|
|
68
|
-
"eval",
|
|
69
|
-
"export",
|
|
70
|
-
"extends",
|
|
71
|
-
"false",
|
|
72
|
-
"final",
|
|
73
|
-
"finally",
|
|
74
|
-
"float",
|
|
75
|
-
"for",
|
|
76
|
-
"function",
|
|
77
|
-
"goto",
|
|
78
|
-
"if",
|
|
79
|
-
"implements",
|
|
80
|
-
"import",
|
|
81
|
-
"in",
|
|
82
|
-
"instanceof",
|
|
83
|
-
"int",
|
|
84
|
-
"interface",
|
|
85
|
-
"let",
|
|
86
|
-
"long",
|
|
87
|
-
"native",
|
|
88
|
-
"new",
|
|
89
|
-
"null",
|
|
90
|
-
"package",
|
|
91
|
-
"private",
|
|
92
|
-
"protected",
|
|
93
|
-
"public",
|
|
94
|
-
"return",
|
|
95
|
-
"short",
|
|
96
|
-
"static",
|
|
97
|
-
"super",
|
|
98
|
-
"switch",
|
|
99
|
-
"synchronized",
|
|
100
|
-
"this",
|
|
101
|
-
"throw",
|
|
102
|
-
"throws",
|
|
103
|
-
"transient",
|
|
104
|
-
"true",
|
|
105
|
-
"try",
|
|
106
|
-
"typeof",
|
|
107
|
-
"var",
|
|
108
|
-
"void",
|
|
109
|
-
"volatile",
|
|
110
|
-
"while",
|
|
111
|
-
"with",
|
|
112
|
-
"yield",
|
|
113
|
-
"Array",
|
|
114
|
-
"Date",
|
|
115
|
-
"hasOwnProperty",
|
|
116
|
-
"Infinity",
|
|
117
|
-
"isFinite",
|
|
118
|
-
"isNaN",
|
|
119
|
-
"isPrototypeOf",
|
|
120
|
-
"length",
|
|
121
|
-
"Math",
|
|
122
|
-
"name",
|
|
123
|
-
"NaN",
|
|
124
|
-
"Number",
|
|
125
|
-
"Object",
|
|
126
|
-
"prototype",
|
|
127
|
-
"String",
|
|
128
|
-
"toString",
|
|
129
|
-
"undefined",
|
|
130
|
-
"valueOf"
|
|
131
|
-
]);
|
|
132
|
-
/**
|
|
133
|
-
* Returns `true` when `name` is a syntactically valid JavaScript variable name.
|
|
134
|
-
*
|
|
135
|
-
* @example
|
|
136
|
-
* ```ts
|
|
137
|
-
* isValidVarName('status') // true
|
|
138
|
-
* isValidVarName('class') // false (reserved word)
|
|
139
|
-
* isValidVarName('42foo') // false (starts with digit)
|
|
140
|
-
* ```
|
|
141
|
-
*/
|
|
142
|
-
function isValidVarName(name) {
|
|
143
|
-
if (!name || reservedWords.has(name)) return false;
|
|
144
|
-
return isIdentifier(name);
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
|
|
148
|
-
*
|
|
149
|
-
* Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
|
|
150
|
-
* even though they are not valid variable names, so use this (not {@link isValidVarName}) when
|
|
151
|
-
* deciding whether an object key needs quoting.
|
|
152
|
-
*
|
|
153
|
-
* @example
|
|
154
|
-
* ```ts
|
|
155
|
-
* isIdentifier('name') // true
|
|
156
|
-
* isIdentifier('x-total')// false
|
|
157
|
-
* ```
|
|
158
|
-
*/
|
|
159
|
-
function isIdentifier(name) {
|
|
160
|
-
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
161
|
-
}
|
|
162
|
-
//#endregion
|
|
163
|
-
//#region ../../internals/utils/src/url.ts
|
|
164
|
-
/**
|
|
165
|
-
* Keeps the OpenAPI parameter name as-is when it is already a valid JS identifier, and
|
|
166
|
-
* camelCases it only enough to become one otherwise (for example a hyphenated path segment).
|
|
167
|
-
*/
|
|
168
|
-
function transformParam(raw) {
|
|
169
|
-
return isValidVarName(raw) ? raw : camelCase(raw);
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Helpers for OpenAPI/Swagger paths.
|
|
173
|
-
*/
|
|
174
|
-
var Url = class Url {
|
|
175
|
-
/**
|
|
176
|
-
* Converts an OpenAPI/Swagger path to Express-style colon syntax.
|
|
177
|
-
*
|
|
178
|
-
* @example
|
|
179
|
-
* Url.toPath('/pet/{petId}') // '/pet/:petId'
|
|
180
|
-
*/
|
|
181
|
-
static toPath(path) {
|
|
182
|
-
return path.replace(/\{([^}]+)\}/g, ":$1");
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Rewrites OpenAPI placeholder names while keeping the `{...}` braces, so the generated `url`
|
|
186
|
-
* literal aligns with the grouped `path` request option that the runtime client interpolates by
|
|
187
|
-
* key.
|
|
188
|
-
*
|
|
189
|
-
* @example
|
|
190
|
-
* Url.toSafeTemplate('/user/{monetary-account-id}') // '/user/{monetaryAccountId}'
|
|
191
|
-
*/
|
|
192
|
-
static toSafeTemplate(path) {
|
|
193
|
-
return path.replace(/\{([^}]+)\}/g, (_, name) => `{${transformParam(name)}}`);
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Converts an OpenAPI/Swagger path to a TypeScript template literal string.
|
|
197
|
-
* `prefix` is prepended inside the literal, and `replacer` transforms each parameter name.
|
|
198
|
-
*
|
|
199
|
-
* @example
|
|
200
|
-
* Url.toTemplateString('/pet/{petId}') // '`/pet/${petId}`'
|
|
201
|
-
*
|
|
202
|
-
* @example
|
|
203
|
-
* Url.toTemplateString('/pet/{petId}', { prefix: 'https://api' }) // '`https://api/pet/${petId}`'
|
|
204
|
-
*/
|
|
205
|
-
static toTemplateString(path, { prefix, replacer } = {}) {
|
|
206
|
-
const result = path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
207
|
-
if (i % 2 === 0) return part;
|
|
208
|
-
const param = transformParam(part);
|
|
209
|
-
return `\${${replacer ? replacer(param) : param}}`;
|
|
210
|
-
}).join("");
|
|
211
|
-
return `\`${prefix ?? ""}${result}\``;
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Converts an OpenAPI/Swagger path to a template literal that reads each parameter off the
|
|
215
|
-
* grouped `path` request option, e.g. `/pet/{petId}` becomes `` `/pet/${path.petId}` ``. Parameter
|
|
216
|
-
* names match the generated `path` type, and `prefix` is prepended inside the literal. Shared by
|
|
217
|
-
* the client and cypress generators that pass a grouped `path` object.
|
|
218
|
-
*
|
|
219
|
-
* @example
|
|
220
|
-
* Url.toGroupedTemplateString('/pet/{petId}') // '`/pet/${path.petId}`'
|
|
221
|
-
*/
|
|
222
|
-
static toGroupedTemplateString(path, { prefix } = {}) {
|
|
223
|
-
return Url.toTemplateString(path, {
|
|
224
|
-
prefix,
|
|
225
|
-
replacer: (name) => `path.${name}`
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
//#endregion
|
|
230
7
|
//#region ../../internals/shared/src/params.ts
|
|
231
8
|
/**
|
|
232
9
|
* Drops parameters that share the same name, keeping the first.
|
|
@@ -265,11 +42,30 @@ function operationFileEntry(node, name, extname = ".ts") {
|
|
|
265
42
|
path: node.path
|
|
266
43
|
};
|
|
267
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Resolves a dependency plugin's generated file for `node.operationId`, cached in `cache` (the
|
|
47
|
+
* current node's `ctx.cache`) under the resolver's own plugin name. Several dependents reading the
|
|
48
|
+
* same dependency for the same operation in one pass (a query plugin's several hook generators, the
|
|
49
|
+
* MCP handler, ...) share one computed name and path instead of each calling `resolver.file` again.
|
|
50
|
+
*
|
|
51
|
+
* @example Cache `plugin-ts`'s file for the current operation
|
|
52
|
+
* ```ts
|
|
53
|
+
* const fileTs = resolveDependencyOperationFile({ cache: ctx.cache, node, resolver: tsResolver, root, output })
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
function resolveDependencyOperationFile(options) {
|
|
57
|
+
const { cache, node, resolver, root, output, group } = options;
|
|
58
|
+
return cache.ensureItem(`${resolver.pluginName}:operationFile`, () => resolver.file({
|
|
59
|
+
...operationFileEntry(node, node.operationId),
|
|
60
|
+
root,
|
|
61
|
+
output,
|
|
62
|
+
group: group ?? void 0
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
268
65
|
function getOperationLink(node, link) {
|
|
269
66
|
if (!link) return null;
|
|
270
67
|
if (typeof link === "function") return link(node) ?? null;
|
|
271
|
-
|
|
272
|
-
return node.path ? `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}` : null;
|
|
68
|
+
return node.path ? `{@link ${Url.toPath(node.path)}}` : null;
|
|
273
69
|
}
|
|
274
70
|
/**
|
|
275
71
|
* Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several
|
|
@@ -359,16 +155,24 @@ function buildOperationComments(node, options = {}) {
|
|
|
359
155
|
if (!splitLines) return filteredComments;
|
|
360
156
|
return filteredComments.flatMap((text) => text.split(/\r?\n/).map((line) => line.trim())).filter((comment) => Boolean(comment));
|
|
361
157
|
}
|
|
158
|
+
const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
|
|
159
|
+
/**
|
|
160
|
+
* Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each
|
|
161
|
+
* group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance
|
|
162
|
+
* (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the
|
|
163
|
+
* same parameters once per plugin.
|
|
164
|
+
*/
|
|
362
165
|
function getOperationParameters(node) {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
})),
|
|
166
|
+
const cached = operationParameterGroupsByNode.get(node);
|
|
167
|
+
if (cached) return cached;
|
|
168
|
+
const groups = {
|
|
169
|
+
path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
|
|
368
170
|
query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
|
|
369
171
|
header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
|
|
370
172
|
cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
|
|
371
173
|
};
|
|
174
|
+
operationParameterGroupsByNode.set(node, groups);
|
|
175
|
+
return groups;
|
|
372
176
|
}
|
|
373
177
|
function getStatusCodeNumber(statusCode) {
|
|
374
178
|
const code = Number(statusCode);
|
|
@@ -430,6 +234,43 @@ function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
|
430
234
|
return result;
|
|
431
235
|
}
|
|
432
236
|
//#endregion
|
|
237
|
+
//#region ../../internals/utils/src/casing.ts
|
|
238
|
+
/**
|
|
239
|
+
* Shared implementation for camelCase and PascalCase conversion.
|
|
240
|
+
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
241
|
+
* and capitalizes each word according to `pascal`.
|
|
242
|
+
*
|
|
243
|
+
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
244
|
+
*/
|
|
245
|
+
function toCamelOrPascal(text, pascal) {
|
|
246
|
+
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) => {
|
|
247
|
+
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
248
|
+
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
249
|
+
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Converts `text` to camelCase.
|
|
253
|
+
*
|
|
254
|
+
* @example Word boundaries
|
|
255
|
+
* `camelCase('hello-world') // 'helloWorld'`
|
|
256
|
+
*
|
|
257
|
+
* @example With a prefix
|
|
258
|
+
* `camelCase('tag', { prefix: 'create' }) // 'createTag'`
|
|
259
|
+
*/
|
|
260
|
+
function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
261
|
+
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Uppercases only the first character of `text`, leaving the rest untouched.
|
|
265
|
+
* Unlike {@link pascalCase} it never re-splits word boundaries or strips characters.
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* `capitalize('getPetById') // 'GetPetById'`
|
|
269
|
+
*/
|
|
270
|
+
function capitalize(text) {
|
|
271
|
+
return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
|
|
272
|
+
}
|
|
273
|
+
//#endregion
|
|
433
274
|
//#region ../../internals/shared/src/group.ts
|
|
434
275
|
/**
|
|
435
276
|
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
@@ -549,23 +390,30 @@ function resolveContractClient(options) {
|
|
|
549
390
|
* (plugin-fetch or plugin-axios). Returns `null` when no contract plugin is in play (the inline
|
|
550
391
|
* path). The plugin injects `.kubb/client.ts` at the global output root, the same path consumers
|
|
551
392
|
* read `RequestConfig` / `ResponseErrorConfig` from.
|
|
393
|
+
*
|
|
394
|
+
* The result is cached in the current node's `cache` (`ctx.cache`) under the client plugin's name,
|
|
395
|
+
* so several dependents reading the same client plugin for one operation in a single pass
|
|
396
|
+
* (react-query's query/mutation/infinite generators, vue-query, swr, the MCP handler, ...) share
|
|
397
|
+
* one computed result instead of each re-deriving the name and path.
|
|
552
398
|
*/
|
|
553
399
|
function resolveClientOperation(options) {
|
|
554
|
-
const { clientPlugin, driver, node, root, output } = options;
|
|
400
|
+
const { clientPlugin, driver, node, root, output, cache } = options;
|
|
555
401
|
if (!clientPlugin) return null;
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
402
|
+
return cache.ensureItem(`${clientPlugin.pluginName}:clientOperation`, () => {
|
|
403
|
+
const resolver = driver.getResolver(clientPlugin.pluginName);
|
|
404
|
+
const plugin = driver.getPlugin(clientPlugin.pluginName);
|
|
405
|
+
const file = resolver.file({
|
|
406
|
+
...operationFileEntry(node, node.operationId),
|
|
407
|
+
root,
|
|
408
|
+
output: plugin?.options?.output ?? output,
|
|
409
|
+
group: plugin?.options?.group ?? void 0
|
|
410
|
+
});
|
|
411
|
+
return {
|
|
412
|
+
name: resolver.name(node.operationId),
|
|
413
|
+
path: file.path,
|
|
414
|
+
clientPath: path.resolve(root, ".kubb/client.ts")
|
|
415
|
+
};
|
|
563
416
|
});
|
|
564
|
-
return {
|
|
565
|
-
name: resolver.name(node.operationId),
|
|
566
|
-
path: file.path,
|
|
567
|
-
clientPath: path.resolve(root, ".kubb/client.ts")
|
|
568
|
-
};
|
|
569
417
|
}
|
|
570
418
|
//#endregion
|
|
571
419
|
//#region ../../internals/tanstack-query/src/utils.ts
|
|
@@ -633,14 +481,16 @@ function buildGroupedRequestParam(node, options) {
|
|
|
633
481
|
*/
|
|
634
482
|
function buildQueryOptionsParams(node, options) {
|
|
635
483
|
const { resolver, memberTypeWrapper } = options;
|
|
636
|
-
|
|
484
|
+
const groupedParam = buildGroupedRequestParam(node, {
|
|
637
485
|
resolver,
|
|
638
486
|
memberTypeWrapper
|
|
639
|
-
})
|
|
487
|
+
});
|
|
488
|
+
const configParam = createFunctionParameter({
|
|
640
489
|
name: "config",
|
|
641
490
|
type: `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`,
|
|
642
491
|
default: "{}"
|
|
643
|
-
})
|
|
492
|
+
});
|
|
493
|
+
return createFunctionParameters({ params: [groupedParam, configParam].filter((param) => param !== null) });
|
|
644
494
|
}
|
|
645
495
|
/**
|
|
646
496
|
* Builds the call to a client `<op>` function inside a query/mutation hook body. The function takes
|
|
@@ -698,6 +548,19 @@ function resolveMutationConfig(mutation, options) {
|
|
|
698
548
|
};
|
|
699
549
|
}
|
|
700
550
|
/**
|
|
551
|
+
* Classifies an operation as a query or a mutation from the resolved `query` / `mutation` method lists.
|
|
552
|
+
* `query: false` still marks the operation as a query so the query-family generators keep matching it,
|
|
553
|
+
* and a method already claimed by `query` never counts as a mutation.
|
|
554
|
+
*/
|
|
555
|
+
function classifyOperation(node, { query, mutation }) {
|
|
556
|
+
const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
|
|
557
|
+
const queryMethods = new Set(query ? query.methods : []);
|
|
558
|
+
return {
|
|
559
|
+
isQuery,
|
|
560
|
+
isMutation: mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase())
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
701
564
|
* Build QueryKey params as the grouped `{ path, query, body }` object (NO headers, NO config),
|
|
702
565
|
* typed from the operation's `Options` minus `url`. The query key transformer reads the
|
|
703
566
|
* grouped `path`/`query`/`body` bindings.
|
|
@@ -844,10 +707,12 @@ function buildMutationParamsNode(node, options) {
|
|
|
844
707
|
const { mutationKeyTypeName, mutationArgTypeName, resolver } = options;
|
|
845
708
|
const responseName = resolver.response.response(node);
|
|
846
709
|
const errorNames = resolveErrorNames(node, resolver);
|
|
710
|
+
const TData = responseName;
|
|
711
|
+
const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
|
|
847
712
|
return createFunctionParameters({ params: [createFunctionParameter({
|
|
848
713
|
name: "options",
|
|
849
714
|
type: `{
|
|
850
|
-
mutation?: SWRMutationConfiguration<${
|
|
715
|
+
mutation?: SWRMutationConfiguration<${TData}, ${TError}, ${mutationKeyTypeName} | null, ${mutationArgTypeName}> & { throwOnError?: boolean },
|
|
851
716
|
client?: ${buildRequestConfigType(node)},
|
|
852
717
|
shouldFetch?: boolean,
|
|
853
718
|
}`,
|
|
@@ -942,17 +807,20 @@ function buildQueryParamsNode(node, options) {
|
|
|
942
807
|
const { resolver } = options;
|
|
943
808
|
const responseName = resolver.response.response(node);
|
|
944
809
|
const errorNames = resolveErrorNames(node, resolver);
|
|
810
|
+
const TData = responseName;
|
|
811
|
+
const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
|
|
945
812
|
const optionsParam = createFunctionParameter({
|
|
946
813
|
name: "options",
|
|
947
814
|
type: `{
|
|
948
|
-
query?: SWRConfiguration<${[
|
|
815
|
+
query?: SWRConfiguration<${[TData, TError].join(", ")}>,
|
|
949
816
|
client?: ${buildClientOptionType()},
|
|
950
817
|
shouldFetch?: boolean,
|
|
951
818
|
immutable?: boolean
|
|
952
819
|
}`,
|
|
953
820
|
default: "{}"
|
|
954
821
|
});
|
|
955
|
-
|
|
822
|
+
const groupedParam = buildGroupedRequestParam(node, { resolver });
|
|
823
|
+
return createFunctionParameters({ params: [groupedParam, optionsParam].filter((param) => param !== null) });
|
|
956
824
|
}
|
|
957
825
|
function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver }) {
|
|
958
826
|
const responseName = tsResolver.response.response(node);
|
|
@@ -1044,16 +912,19 @@ const mutationGenerator = defineGenerator({
|
|
|
1044
912
|
const pluginTs = driver.getPlugin(pluginTsName);
|
|
1045
913
|
if (!pluginTs) return null;
|
|
1046
914
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
1047
|
-
const
|
|
1048
|
-
|
|
1049
|
-
|
|
915
|
+
const { isMutation } = classifyOperation(node, {
|
|
916
|
+
query,
|
|
917
|
+
mutation
|
|
918
|
+
});
|
|
919
|
+
if (!isMutation) return null;
|
|
1050
920
|
const importPath = mutation ? mutation.importPath : "swr/mutation";
|
|
1051
921
|
const contractOp = resolveClientOperation({
|
|
1052
922
|
clientPlugin: { pluginName: client.pluginName },
|
|
1053
923
|
driver,
|
|
1054
924
|
node,
|
|
1055
925
|
root,
|
|
1056
|
-
output
|
|
926
|
+
output,
|
|
927
|
+
cache: ctx.cache
|
|
1057
928
|
});
|
|
1058
929
|
if (!contractOp) return null;
|
|
1059
930
|
const mutationHookName = resolver.mutation.name(node);
|
|
@@ -1070,11 +941,10 @@ const mutationGenerator = defineGenerator({
|
|
|
1070
941
|
output,
|
|
1071
942
|
group
|
|
1072
943
|
}),
|
|
1073
|
-
fileTs:
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
path: node.path,
|
|
944
|
+
fileTs: resolveDependencyOperationFile({
|
|
945
|
+
cache: ctx.cache,
|
|
946
|
+
node,
|
|
947
|
+
resolver: tsResolver,
|
|
1078
948
|
root,
|
|
1079
949
|
output: pluginTs.options?.output ?? output,
|
|
1080
950
|
group: pluginTs.options?.group
|
|
@@ -1165,18 +1035,23 @@ const queryGenerator = defineGenerator({
|
|
|
1165
1035
|
operation(node, ctx) {
|
|
1166
1036
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
1167
1037
|
const { config, driver, resolver, root } = ctx;
|
|
1168
|
-
const { output, query, client, group } = ctx.options;
|
|
1038
|
+
const { output, query, mutation, client, group } = ctx.options;
|
|
1169
1039
|
const pluginTs = driver.getPlugin(pluginTsName);
|
|
1170
1040
|
if (!pluginTs) return null;
|
|
1171
1041
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
1172
|
-
|
|
1042
|
+
const { isQuery } = classifyOperation(node, {
|
|
1043
|
+
query,
|
|
1044
|
+
mutation
|
|
1045
|
+
});
|
|
1046
|
+
if (!isQuery) return null;
|
|
1173
1047
|
const importPath = query ? query.importPath : "swr";
|
|
1174
1048
|
const contractOp = resolveClientOperation({
|
|
1175
1049
|
clientPlugin: { pluginName: client.pluginName },
|
|
1176
1050
|
driver,
|
|
1177
1051
|
node,
|
|
1178
1052
|
root,
|
|
1179
|
-
output
|
|
1053
|
+
output,
|
|
1054
|
+
cache: ctx.cache
|
|
1180
1055
|
});
|
|
1181
1056
|
if (!contractOp) return null;
|
|
1182
1057
|
const queryName = resolver.query.name(node);
|
|
@@ -1193,11 +1068,10 @@ const queryGenerator = defineGenerator({
|
|
|
1193
1068
|
output,
|
|
1194
1069
|
group
|
|
1195
1070
|
}),
|
|
1196
|
-
fileTs:
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
path: node.path,
|
|
1071
|
+
fileTs: resolveDependencyOperationFile({
|
|
1072
|
+
cache: ctx.cache,
|
|
1073
|
+
node,
|
|
1074
|
+
resolver: tsResolver,
|
|
1201
1075
|
root,
|
|
1202
1076
|
output: pluginTs.options?.output ?? output,
|
|
1203
1077
|
group: pluginTs.options?.group
|