@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.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,29 @@ 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
|
+
/**
|
|
564
|
+
* The request groups a query key is built from, matching `buildQueryKeyParams`. Headers are
|
|
565
|
+
* deliberately absent: they do not identify a cache entry, so the key factory takes no parameter
|
|
566
|
+
* for an operation that only carries headers.
|
|
567
|
+
*/
|
|
568
|
+
const queryKeyGroupOrder = [
|
|
569
|
+
"path",
|
|
570
|
+
"query",
|
|
571
|
+
"body"
|
|
572
|
+
];
|
|
573
|
+
/**
|
|
701
574
|
* Build QueryKey params as the grouped `{ path, query, body }` object (NO headers, NO config),
|
|
702
575
|
* typed from the operation's `Options` minus `url`. The query key transformer reads the
|
|
703
576
|
* grouped `path`/`query`/`body` bindings.
|
|
@@ -706,11 +579,7 @@ function buildQueryKeyParams(node, options) {
|
|
|
706
579
|
const { resolver } = options;
|
|
707
580
|
const groupedParam = buildGroupedRequestParam(node, {
|
|
708
581
|
resolver,
|
|
709
|
-
keys:
|
|
710
|
-
"path",
|
|
711
|
-
"query",
|
|
712
|
-
"body"
|
|
713
|
-
]
|
|
582
|
+
keys: queryKeyGroupOrder
|
|
714
583
|
});
|
|
715
584
|
return createFunctionParameters({ params: groupedParam ? [groupedParam] : [] });
|
|
716
585
|
}
|
|
@@ -844,10 +713,12 @@ function buildMutationParamsNode(node, options) {
|
|
|
844
713
|
const { mutationKeyTypeName, mutationArgTypeName, resolver } = options;
|
|
845
714
|
const responseName = resolver.response.response(node);
|
|
846
715
|
const errorNames = resolveErrorNames(node, resolver);
|
|
716
|
+
const TData = responseName;
|
|
717
|
+
const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
|
|
847
718
|
return createFunctionParameters({ params: [createFunctionParameter({
|
|
848
719
|
name: "options",
|
|
849
720
|
type: `{
|
|
850
|
-
mutation?: SWRMutationConfiguration<${
|
|
721
|
+
mutation?: SWRMutationConfiguration<${TData}, ${TError}, ${mutationKeyTypeName} | null, ${mutationArgTypeName}> & { throwOnError?: boolean },
|
|
851
722
|
client?: ${buildRequestConfigType(node)},
|
|
852
723
|
shouldFetch?: boolean,
|
|
853
724
|
}`,
|
|
@@ -864,11 +735,10 @@ function Mutation({ name, clientName, mutationKeyName, mutationKeyTypeName, muta
|
|
|
864
735
|
const groupedParamsNode = createFunctionParameters({ params: groupedParam ? [groupedParam] : [] });
|
|
865
736
|
const argTypeBody = hasMutationParams ? tsResolver.response.options(node) : "";
|
|
866
737
|
const argBindingStr = hasMutationParams ? callPrinter$1.print(groupedParamsNode) ?? "" : "";
|
|
867
|
-
const mutationFnBody = `
|
|
738
|
+
const mutationFnBody = `return ${buildClientCall(node, {
|
|
868
739
|
clientName,
|
|
869
740
|
signal: false
|
|
870
|
-
})}
|
|
871
|
-
return data`;
|
|
741
|
+
})}.unwrap()`;
|
|
872
742
|
const generics = [
|
|
873
743
|
TData,
|
|
874
744
|
TError,
|
|
@@ -942,17 +812,20 @@ function buildQueryParamsNode(node, options) {
|
|
|
942
812
|
const { resolver } = options;
|
|
943
813
|
const responseName = resolver.response.response(node);
|
|
944
814
|
const errorNames = resolveErrorNames(node, resolver);
|
|
815
|
+
const TData = responseName;
|
|
816
|
+
const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
|
|
945
817
|
const optionsParam = createFunctionParameter({
|
|
946
818
|
name: "options",
|
|
947
819
|
type: `{
|
|
948
|
-
query?: SWRConfiguration<${[
|
|
820
|
+
query?: SWRConfiguration<${[TData, TError].join(", ")}>,
|
|
949
821
|
client?: ${buildClientOptionType()},
|
|
950
822
|
shouldFetch?: boolean,
|
|
951
823
|
immutable?: boolean
|
|
952
824
|
}`,
|
|
953
825
|
default: "{}"
|
|
954
826
|
});
|
|
955
|
-
|
|
827
|
+
const groupedParam = buildGroupedRequestParam(node, { resolver });
|
|
828
|
+
return createFunctionParameters({ params: [groupedParam, optionsParam].filter((param) => param !== null) });
|
|
956
829
|
}
|
|
957
830
|
function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver }) {
|
|
958
831
|
const responseName = tsResolver.response.response(node);
|
|
@@ -1004,11 +877,10 @@ const declarationPrinter = functionPrinter({ mode: "declaration" });
|
|
|
1004
877
|
function QueryOptions({ name, clientName, node, tsResolver }) {
|
|
1005
878
|
const paramsNode = buildQueryOptionsParams(node, { resolver: tsResolver });
|
|
1006
879
|
const paramsSignature = declarationPrinter.print(paramsNode) ?? "";
|
|
1007
|
-
const fetcherBody = `
|
|
880
|
+
const fetcherBody = `return ${buildClientCall(node, {
|
|
1008
881
|
clientName,
|
|
1009
882
|
signal: false
|
|
1010
|
-
})}
|
|
1011
|
-
return data`;
|
|
883
|
+
})}.unwrap()`;
|
|
1012
884
|
return /* @__PURE__ */ jsx(File.Source, {
|
|
1013
885
|
name,
|
|
1014
886
|
isExportable: true,
|
|
@@ -1044,16 +916,19 @@ const mutationGenerator = defineGenerator({
|
|
|
1044
916
|
const pluginTs = driver.getPlugin(pluginTsName);
|
|
1045
917
|
if (!pluginTs) return null;
|
|
1046
918
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
1047
|
-
const
|
|
1048
|
-
|
|
1049
|
-
|
|
919
|
+
const { isMutation } = classifyOperation(node, {
|
|
920
|
+
query,
|
|
921
|
+
mutation
|
|
922
|
+
});
|
|
923
|
+
if (!isMutation) return null;
|
|
1050
924
|
const importPath = mutation ? mutation.importPath : "swr/mutation";
|
|
1051
925
|
const contractOp = resolveClientOperation({
|
|
1052
926
|
clientPlugin: { pluginName: client.pluginName },
|
|
1053
927
|
driver,
|
|
1054
928
|
node,
|
|
1055
929
|
root,
|
|
1056
|
-
output
|
|
930
|
+
output,
|
|
931
|
+
cache: ctx.cache
|
|
1057
932
|
});
|
|
1058
933
|
if (!contractOp) return null;
|
|
1059
934
|
const mutationHookName = resolver.mutation.name(node);
|
|
@@ -1070,11 +945,10 @@ const mutationGenerator = defineGenerator({
|
|
|
1070
945
|
output,
|
|
1071
946
|
group
|
|
1072
947
|
}),
|
|
1073
|
-
fileTs:
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
path: node.path,
|
|
948
|
+
fileTs: resolveDependencyOperationFile({
|
|
949
|
+
cache: ctx.cache,
|
|
950
|
+
node,
|
|
951
|
+
resolver: tsResolver,
|
|
1078
952
|
root,
|
|
1079
953
|
output: pluginTs.options?.output ?? output,
|
|
1080
954
|
group: pluginTs.options?.group
|
|
@@ -1165,18 +1039,23 @@ const queryGenerator = defineGenerator({
|
|
|
1165
1039
|
operation(node, ctx) {
|
|
1166
1040
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
1167
1041
|
const { config, driver, resolver, root } = ctx;
|
|
1168
|
-
const { output, query, client, group } = ctx.options;
|
|
1042
|
+
const { output, query, mutation, client, group } = ctx.options;
|
|
1169
1043
|
const pluginTs = driver.getPlugin(pluginTsName);
|
|
1170
1044
|
if (!pluginTs) return null;
|
|
1171
1045
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
1172
|
-
|
|
1046
|
+
const { isQuery } = classifyOperation(node, {
|
|
1047
|
+
query,
|
|
1048
|
+
mutation
|
|
1049
|
+
});
|
|
1050
|
+
if (!isQuery) return null;
|
|
1173
1051
|
const importPath = query ? query.importPath : "swr";
|
|
1174
1052
|
const contractOp = resolveClientOperation({
|
|
1175
1053
|
clientPlugin: { pluginName: client.pluginName },
|
|
1176
1054
|
driver,
|
|
1177
1055
|
node,
|
|
1178
1056
|
root,
|
|
1179
|
-
output
|
|
1057
|
+
output,
|
|
1058
|
+
cache: ctx.cache
|
|
1180
1059
|
});
|
|
1181
1060
|
if (!contractOp) return null;
|
|
1182
1061
|
const queryName = resolver.query.name(node);
|
|
@@ -1193,11 +1072,10 @@ const queryGenerator = defineGenerator({
|
|
|
1193
1072
|
output,
|
|
1194
1073
|
group
|
|
1195
1074
|
}),
|
|
1196
|
-
fileTs:
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
path: node.path,
|
|
1075
|
+
fileTs: resolveDependencyOperationFile({
|
|
1076
|
+
cache: ctx.cache,
|
|
1077
|
+
node,
|
|
1078
|
+
resolver: tsResolver,
|
|
1201
1079
|
root,
|
|
1202
1080
|
output: pluginTs.options?.output ?? output,
|
|
1203
1081
|
group: pluginTs.options?.group
|