@kubb/plugin-react-query 5.0.0-alpha.9 → 5.0.0-beta.100
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/LICENSE +17 -10
- package/README.md +38 -93
- package/dist/index.cjs +2317 -149
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +494 -6
- package/dist/index.js +2283 -143
- package/dist/index.js.map +1 -1
- package/package.json +47 -75
- package/dist/components-BHQT9ZLc.cjs +0 -1634
- package/dist/components-BHQT9ZLc.cjs.map +0 -1
- package/dist/components-CpyHYGOw.js +0 -1520
- package/dist/components-CpyHYGOw.js.map +0 -1
- package/dist/components.cjs +0 -13
- package/dist/components.d.ts +0 -398
- package/dist/components.js +0 -2
- package/dist/generators-DP07m3rH.cjs +0 -1469
- package/dist/generators-DP07m3rH.cjs.map +0 -1
- package/dist/generators-DkQwKTc2.js +0 -1427
- package/dist/generators-DkQwKTc2.js.map +0 -1
- package/dist/generators.cjs +0 -9
- package/dist/generators.d.ts +0 -523
- package/dist/generators.js +0 -2
- package/dist/types-D5S7Ny9r.d.ts +0 -270
- package/src/components/InfiniteQuery.tsx +0 -220
- package/src/components/InfiniteQueryOptions.tsx +0 -289
- package/src/components/Mutation.tsx +0 -158
- package/src/components/MutationKey.tsx +0 -1
- package/src/components/MutationOptions.tsx +0 -122
- package/src/components/Query.tsx +0 -194
- package/src/components/QueryKey.tsx +0 -1
- package/src/components/QueryOptions.tsx +0 -181
- package/src/components/SuspenseInfiniteQuery.tsx +0 -220
- package/src/components/SuspenseInfiniteQueryOptions.tsx +0 -289
- package/src/components/SuspenseQuery.tsx +0 -204
- package/src/components/index.ts +0 -11
- package/src/generators/customHookOptionsFileGenerator.tsx +0 -98
- package/src/generators/hookOptionsGenerator.tsx +0 -196
- package/src/generators/index.ts +0 -7
- package/src/generators/infiniteQueryGenerator.tsx +0 -214
- package/src/generators/mutationGenerator.tsx +0 -195
- package/src/generators/queryGenerator.tsx +0 -194
- package/src/generators/suspenseInfiniteQueryGenerator.tsx +0 -202
- package/src/generators/suspenseQueryGenerator.tsx +0 -207
- package/src/index.ts +0 -2
- package/src/plugin.ts +0 -239
- package/src/types.ts +0 -205
- /package/dist/{chunk--u3MIqq1.js → rolldown-runtime-C0LytTxp.js} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -1,168 +1,2336 @@
|
|
|
1
|
-
Object.
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
//#region \0rolldown/runtime.js
|
|
6
|
+
var __create = Object.create;
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
11
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
14
|
+
key = keys[i];
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
16
|
+
get: ((k) => from[k]).bind(null, key),
|
|
17
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
//#endregion
|
|
27
|
+
let kubb_kit = require("kubb/kit");
|
|
4
28
|
let node_path = require("node:path");
|
|
5
|
-
node_path =
|
|
6
|
-
let _kubb_core = require("@kubb/core");
|
|
7
|
-
let _kubb_plugin_client = require("@kubb/plugin-client");
|
|
8
|
-
let _kubb_plugin_client_templates_clients_axios_source = require("@kubb/plugin-client/templates/clients/axios.source");
|
|
9
|
-
let _kubb_plugin_client_templates_clients_fetch_source = require("@kubb/plugin-client/templates/clients/fetch.source");
|
|
10
|
-
let _kubb_plugin_client_templates_config_source = require("@kubb/plugin-client/templates/config.source");
|
|
11
|
-
let _kubb_plugin_oas = require("@kubb/plugin-oas");
|
|
29
|
+
node_path = __toESM(node_path, 1);
|
|
12
30
|
let _kubb_plugin_ts = require("@kubb/plugin-ts");
|
|
13
|
-
let
|
|
31
|
+
let kubb_jsx = require("kubb/jsx");
|
|
32
|
+
let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
|
|
33
|
+
let node_fs = require("node:fs");
|
|
34
|
+
node_fs = __toESM(node_fs, 1);
|
|
35
|
+
//#region ../../internals/shared/src/params.ts
|
|
36
|
+
/**
|
|
37
|
+
* Drops parameters that share the same name, keeping the first.
|
|
38
|
+
*
|
|
39
|
+
* A malformed spec can declare the same parameter name twice within one `in` location. Both would
|
|
40
|
+
* resolve to the same output property, so emitting both would yield an object type with a duplicate
|
|
41
|
+
* member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:
|
|
42
|
+
* parameter names flow through unchanged, so no two distinct names ever collide here anymore.
|
|
43
|
+
*/
|
|
44
|
+
function dedupeParams(params) {
|
|
45
|
+
const seen = /* @__PURE__ */ new Set();
|
|
46
|
+
return params.filter((param) => {
|
|
47
|
+
if (seen.has(param.name)) return false;
|
|
48
|
+
seen.add(param.name);
|
|
49
|
+
return true;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region ../../internals/shared/src/operation.ts
|
|
54
|
+
/**
|
|
55
|
+
* Builds the `ResolverFileParams` every operation generator passes to
|
|
56
|
+
* `resolver.file`: a file named `name`, tagged by the operation's first
|
|
57
|
+
* tag (or `'default'`), at the operation's path. Centralizes the entry object
|
|
58
|
+
* that was repeated at dozens of call sites across the client and query plugins.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* resolver.file(operationFileEntry(node, node.operationId), { root, output, group })
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
function operationFileEntry(node, name, extname = ".ts") {
|
|
66
|
+
return {
|
|
67
|
+
name,
|
|
68
|
+
extname,
|
|
69
|
+
tag: node.tags[0] ?? "default",
|
|
70
|
+
path: node.path
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function getOperationLink(node, link) {
|
|
74
|
+
if (!link) return null;
|
|
75
|
+
if (typeof link === "function") return link(node) ?? null;
|
|
76
|
+
return node.path ? `{@link ${kubb_kit.Url.toPath(node.path)}}` : null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several
|
|
80
|
+
* are present and the union, default, and form-data flags the client uses to pick one.
|
|
81
|
+
*/
|
|
82
|
+
function buildContentTypeInfo(contentTypes) {
|
|
83
|
+
const isMultipleContentTypes = contentTypes.length > 1;
|
|
84
|
+
return {
|
|
85
|
+
contentTypes,
|
|
86
|
+
isMultipleContentTypes,
|
|
87
|
+
contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(" | ") : "",
|
|
88
|
+
defaultContentType: contentTypes[0] ?? "application/json",
|
|
89
|
+
hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function getContentTypeInfo(node) {
|
|
93
|
+
return buildContentTypeInfo(node.requestBody?.content?.map((e) => e.contentType) ?? []);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The request-body counterpart for the primary success response: the content types it documents and
|
|
97
|
+
* whether several are present, so the client can let a caller pick which one to accept.
|
|
98
|
+
*/
|
|
99
|
+
function getResponseContentTypeInfo(node) {
|
|
100
|
+
return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? []);
|
|
101
|
+
}
|
|
102
|
+
function buildRequestConfigType(node) {
|
|
103
|
+
const request = getContentTypeInfo(node);
|
|
104
|
+
const response = getResponseContentTypeInfo(node);
|
|
105
|
+
const configType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
|
|
106
|
+
const members = [request.isMultipleContentTypes ? `request?: ${request.contentTypeUnion}` : null, response.isMultipleContentTypes ? `response?: ${response.contentTypeUnion}` : null].filter(Boolean);
|
|
107
|
+
return members.length ? `${configType} & { contentType?: { ${members.join("; ")} } }` : configType;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Builds the `client?:` option type shared by the generated query hooks (`useQuery`,
|
|
111
|
+
* `useInfiniteQuery`, `useSWR`, ...). Unlike {@link buildRequestConfigType}, it never adds a
|
|
112
|
+
* `contentType?:` member: query hooks wrap GET operations, which carry no request body to select a
|
|
113
|
+
* content type for.
|
|
114
|
+
*/
|
|
115
|
+
function buildClientOptionType() {
|
|
116
|
+
return `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Which of the grouped request options an operation carries.
|
|
120
|
+
*/
|
|
121
|
+
function getRequestGroups(node) {
|
|
122
|
+
const { path, query, header } = getOperationParameters(node);
|
|
123
|
+
return {
|
|
124
|
+
path: path.length > 0,
|
|
125
|
+
query: query.length > 0,
|
|
126
|
+
body: Boolean(node.requestBody?.content?.[0]?.schema),
|
|
127
|
+
headers: header.length > 0
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Resolves which grouped request options an operation carries together with whether each group
|
|
132
|
+
* holds a required member. The grouped parameter stays optional only when nothing inside it is
|
|
133
|
+
* required, matching the generated `RequestConfig` type.
|
|
134
|
+
*/
|
|
135
|
+
function getRequestGroupOptionality(node) {
|
|
136
|
+
const groups = getRequestGroups(node);
|
|
137
|
+
const { path, query, header } = getOperationParameters(node);
|
|
138
|
+
const hasRequiredPath = path.some((param) => param.required);
|
|
139
|
+
const hasRequiredQuery = query.some((param) => param.required);
|
|
140
|
+
const hasRequiredHeader = header.some((param) => param.required);
|
|
141
|
+
return {
|
|
142
|
+
groups,
|
|
143
|
+
hasRequiredPath,
|
|
144
|
+
hasRequiredQuery,
|
|
145
|
+
hasRequiredHeader,
|
|
146
|
+
isOptional: !hasRequiredPath && !hasRequiredQuery && !hasRequiredHeader && !groups.body
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function buildOperationComments(node, options = {}) {
|
|
150
|
+
const { link = "pathTemplate", linkPosition = "afterDeprecated", splitLines = false } = options;
|
|
151
|
+
const linkComment = getOperationLink(node, link);
|
|
152
|
+
const filteredComments = (linkPosition === "beforeDeprecated" ? [
|
|
153
|
+
node.description && `@description ${node.description}`,
|
|
154
|
+
node.summary && `@summary ${node.summary}`,
|
|
155
|
+
linkComment,
|
|
156
|
+
node.deprecated && "@deprecated"
|
|
157
|
+
] : [
|
|
158
|
+
node.description && `@description ${node.description}`,
|
|
159
|
+
node.summary && `@summary ${node.summary}`,
|
|
160
|
+
node.deprecated && "@deprecated",
|
|
161
|
+
linkComment
|
|
162
|
+
]).filter((comment) => Boolean(comment));
|
|
163
|
+
if (!splitLines) return filteredComments;
|
|
164
|
+
return filteredComments.flatMap((text) => text.split(/\r?\n/).map((line) => line.trim())).filter((comment) => Boolean(comment));
|
|
165
|
+
}
|
|
166
|
+
function getOperationParameters(node) {
|
|
167
|
+
return {
|
|
168
|
+
path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
|
|
169
|
+
query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
|
|
170
|
+
header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
|
|
171
|
+
cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function getStatusCodeNumber(statusCode) {
|
|
175
|
+
const code = Number(statusCode);
|
|
176
|
+
return Number.isNaN(code) ? null : code;
|
|
177
|
+
}
|
|
178
|
+
function isSuccessStatusCode(statusCode) {
|
|
179
|
+
const code = getStatusCodeNumber(statusCode);
|
|
180
|
+
return code !== null && code >= 200 && code < 300;
|
|
181
|
+
}
|
|
182
|
+
function isErrorStatusCode(statusCode) {
|
|
183
|
+
const code = getStatusCodeNumber(statusCode);
|
|
184
|
+
return code !== null && code >= 400;
|
|
185
|
+
}
|
|
186
|
+
function getSuccessResponses(responses) {
|
|
187
|
+
return responses.filter((response) => isSuccessStatusCode(response.statusCode));
|
|
188
|
+
}
|
|
189
|
+
function getOperationSuccessResponses(node) {
|
|
190
|
+
return getSuccessResponses(node.responses);
|
|
191
|
+
}
|
|
192
|
+
function getPrimarySuccessResponse(node) {
|
|
193
|
+
return getOperationSuccessResponses(node)[0] ?? null;
|
|
194
|
+
}
|
|
195
|
+
function resolveErrorNames(node, resolver) {
|
|
196
|
+
return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode));
|
|
197
|
+
}
|
|
198
|
+
function resolveSuccessNames(node, resolver) {
|
|
199
|
+
return node.responses.filter((response) => isSuccessStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode));
|
|
200
|
+
}
|
|
201
|
+
function resolveStatusCodeNames(node, resolver) {
|
|
202
|
+
return node.responses.map((response) => resolver.response.status(node, response.statusCode));
|
|
203
|
+
}
|
|
204
|
+
const typeNamesByResolver = /* @__PURE__ */ new WeakMap();
|
|
205
|
+
function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
206
|
+
const cacheKey = `${node.operationId}\0${options.order ?? ""}\0${options.responseStatusNames ?? ""}\0${options.includeParams === false ? "noparams" : ""}\0${(options.exclude ?? []).join(",")}`;
|
|
207
|
+
let byResolver = typeNamesByResolver.get(resolver);
|
|
208
|
+
if (byResolver) {
|
|
209
|
+
const cached = byResolver.get(cacheKey);
|
|
210
|
+
if (cached) return cached;
|
|
211
|
+
} else {
|
|
212
|
+
byResolver = /* @__PURE__ */ new Map();
|
|
213
|
+
typeNamesByResolver.set(resolver, byResolver);
|
|
214
|
+
}
|
|
215
|
+
const { path, query, header } = getOperationParameters(node);
|
|
216
|
+
const responseStatusNames = options.responseStatusNames === "error" ? resolveErrorNames(node, resolver) : options.responseStatusNames === false ? [] : resolveStatusCodeNames(node, resolver);
|
|
217
|
+
const exclude = new Set(options.exclude ?? []);
|
|
218
|
+
const paramNames = options.includeParams === false ? [] : [
|
|
219
|
+
...path.map((param) => resolver.param.path(node, param)),
|
|
220
|
+
...query.map((param) => resolver.param.query(node, param)),
|
|
221
|
+
...header.map((param) => resolver.param.headers(node, param))
|
|
222
|
+
];
|
|
223
|
+
const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.response.body(node) : null, resolver.response.response(node)];
|
|
224
|
+
const result = (options.order === "body-response-first" ? [
|
|
225
|
+
...bodyAndResponseNames,
|
|
226
|
+
...paramNames,
|
|
227
|
+
...responseStatusNames
|
|
228
|
+
] : [
|
|
229
|
+
...paramNames,
|
|
230
|
+
...bodyAndResponseNames,
|
|
231
|
+
...responseStatusNames
|
|
232
|
+
]).filter((name) => Boolean(name) && !exclude.has(name));
|
|
233
|
+
byResolver.set(cacheKey, result);
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
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
|
|
274
|
+
//#region ../../internals/utils/src/strings.ts
|
|
275
|
+
/**
|
|
276
|
+
* Renders a dotted path or string array as an optional-chaining accessor expression rooted at
|
|
277
|
+
* `accessor`. Returns `null` for an empty path.
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* ```ts
|
|
281
|
+
* getNestedAccessor('pagination.next.id', 'lastPage')
|
|
282
|
+
* // "lastPage?.['pagination']?.['next']?.['id']"
|
|
283
|
+
* ```
|
|
284
|
+
*/
|
|
285
|
+
function getNestedAccessor(param, accessor) {
|
|
286
|
+
const parts = Array.isArray(param) ? param : param.split(".");
|
|
287
|
+
if (parts.length === 0 || parts.length === 1 && parts[0] === "") return null;
|
|
288
|
+
return `${accessor}?.['${`${parts.join("']?.['")}']`}`;
|
|
289
|
+
}
|
|
290
|
+
//#endregion
|
|
291
|
+
//#region ../../internals/shared/src/group.ts
|
|
292
|
+
/**
|
|
293
|
+
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
294
|
+
* shared default naming so every plugin groups output consistently:
|
|
295
|
+
*
|
|
296
|
+
* - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).
|
|
297
|
+
* - other groups use the camelCased group (`pet store` → `petStore`).
|
|
298
|
+
*
|
|
299
|
+
* A user-provided `group.name` always wins over the default namer, so callers stay in
|
|
300
|
+
* control of their output folders. Returns `null` when grouping is disabled, matching the
|
|
301
|
+
* per-plugin convention.
|
|
302
|
+
*
|
|
303
|
+
* @param group - The user-supplied group option, or `undefined` to disable grouping.
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```ts
|
|
307
|
+
* createGroupConfig(group) // shared across every plugin
|
|
308
|
+
* ```
|
|
309
|
+
*/
|
|
310
|
+
function createGroupConfig(group) {
|
|
311
|
+
if (!group) return null;
|
|
312
|
+
const defaultName = (ctx) => {
|
|
313
|
+
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
314
|
+
return camelCase(ctx.group);
|
|
315
|
+
};
|
|
316
|
+
return {
|
|
317
|
+
...group,
|
|
318
|
+
name: group.name ? group.name : defaultName
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
//#endregion
|
|
322
|
+
//#region ../../internals/client/src/resolveClient.ts
|
|
323
|
+
/**
|
|
324
|
+
* Resolves which client plugin a consumer (react-query, vue-query, swr, mcp) should call for an
|
|
325
|
+
* operation, shared so the selection rules and diagnostics stay in one place.
|
|
326
|
+
*
|
|
327
|
+
* Every client runtime lives in a dedicated client plugin, so a consumer always calls a registered
|
|
328
|
+
* contract client plugin (plugin-fetch or plugin-axios) and never emits its own inline client:
|
|
329
|
+
*
|
|
330
|
+
* - `contract` — a registered contract client plugin owns the `<op>` functions and the consumer
|
|
331
|
+
* imports and calls them.
|
|
332
|
+
* - `error` — no client plugin is registered, several are registered without a selector, or the
|
|
333
|
+
* requested one is missing.
|
|
334
|
+
*
|
|
335
|
+
* The `client` string selects explicitly (`'fetch'` / `'axios'`); when it is unset a lone registered
|
|
336
|
+
* contract client plugin is picked up automatically.
|
|
337
|
+
*/
|
|
338
|
+
const pluginFetchName = "plugin-fetch";
|
|
339
|
+
const pluginAxiosName = "plugin-axios";
|
|
340
|
+
const selectorToPlugin = {
|
|
341
|
+
fetch: pluginFetchName,
|
|
342
|
+
axios: pluginAxiosName
|
|
343
|
+
};
|
|
344
|
+
const contractPlugins = [pluginFetchName, pluginAxiosName];
|
|
345
|
+
/**
|
|
346
|
+
* Applies the `client` resolution rules. See the module comment for the strategy shape.
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```ts
|
|
350
|
+
* resolveClient({ client: 'fetch', pluginNames: ['plugin-ts', 'plugin-fetch'] })
|
|
351
|
+
* // { kind: 'contract', pluginName: 'plugin-fetch' }
|
|
352
|
+
* ```
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* ```ts
|
|
356
|
+
* resolveClient({ client: undefined, pluginNames: ['plugin-ts'] })
|
|
357
|
+
* // { kind: 'error', message: 'No client plugin is registered…' }
|
|
358
|
+
* ```
|
|
359
|
+
*/
|
|
360
|
+
function resolveClient(options) {
|
|
361
|
+
const { client, pluginNames } = options;
|
|
362
|
+
const has = (name) => pluginNames.includes(name);
|
|
363
|
+
if (client === "fetch" || client === "axios") {
|
|
364
|
+
const pluginName = selectorToPlugin[client];
|
|
365
|
+
if (!has(pluginName)) return {
|
|
366
|
+
kind: "error",
|
|
367
|
+
message: `\`client: '${client}'\` is set but \`@kubb/plugin-${client}\` is not registered in \`plugins\`. Add it, or drop \`client\` to use a different client plugin.`
|
|
368
|
+
};
|
|
369
|
+
return {
|
|
370
|
+
kind: "contract",
|
|
371
|
+
pluginName
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
const registered = contractPlugins.filter(has);
|
|
375
|
+
if (registered.length === 1) return {
|
|
376
|
+
kind: "contract",
|
|
377
|
+
pluginName: registered[0]
|
|
378
|
+
};
|
|
379
|
+
if (registered.length > 1) return {
|
|
380
|
+
kind: "error",
|
|
381
|
+
message: `Multiple client plugins are registered (${registered.map((name) => `\`@kubb/${name}\``).join(", ")}). Set \`client: 'fetch' | 'axios'\` to choose which client the hooks call, or register a single client plugin.`
|
|
382
|
+
};
|
|
383
|
+
return {
|
|
384
|
+
kind: "error",
|
|
385
|
+
message: "No client plugin is registered. Add `@kubb/plugin-axios` or `@kubb/plugin-fetch` to `plugins` so the generated code has an HTTP client to call."
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Resolves the contract client during a consumer plugin's setup hook. Extracts the plugin names
|
|
390
|
+
* from the raw `plugins` config, applies {@link resolveClient}, and throws the diagnostic on a
|
|
391
|
+
* misconfiguration so every consumer fails fast with the same message.
|
|
392
|
+
*/
|
|
393
|
+
function resolveContractClient(options) {
|
|
394
|
+
const { client, plugins = [] } = options;
|
|
395
|
+
const resolved = resolveClient({
|
|
396
|
+
client,
|
|
397
|
+
pluginNames: plugins.map((plugin) => plugin.name).filter((name) => Boolean(name))
|
|
398
|
+
});
|
|
399
|
+
if (resolved.kind === "error") throw new Error(resolved.message);
|
|
400
|
+
return resolved;
|
|
401
|
+
}
|
|
402
|
+
//#endregion
|
|
403
|
+
//#region ../../internals/client/src/resolveClientOperation.ts
|
|
404
|
+
/**
|
|
405
|
+
* Resolves the contract client `<op>` a consumer (query hook, MCP handler) imports, by looking up
|
|
406
|
+
* the registered contract client plugin's resolver and output. Works for any contract client plugin
|
|
407
|
+
* (plugin-fetch or plugin-axios). Returns `null` when no contract plugin is in play (the inline
|
|
408
|
+
* path). The plugin injects `.kubb/client.ts` at the global output root, the same path consumers
|
|
409
|
+
* read `RequestConfig` / `ResponseErrorConfig` from.
|
|
410
|
+
*/
|
|
411
|
+
function resolveClientOperation(options) {
|
|
412
|
+
const { clientPlugin, driver, node, root, output } = options;
|
|
413
|
+
if (!clientPlugin) return null;
|
|
414
|
+
const resolver = driver.getResolver(clientPlugin.pluginName);
|
|
415
|
+
const plugin = driver.getPlugin(clientPlugin.pluginName);
|
|
416
|
+
const file = resolver.file({
|
|
417
|
+
...operationFileEntry(node, node.operationId),
|
|
418
|
+
root,
|
|
419
|
+
output: plugin?.options?.output ?? output,
|
|
420
|
+
group: plugin?.options?.group ?? void 0
|
|
421
|
+
});
|
|
422
|
+
return {
|
|
423
|
+
name: resolver.name(node.operationId),
|
|
424
|
+
path: file.path,
|
|
425
|
+
clientPath: node_path.default.resolve(root, ".kubb/client.ts")
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
//#endregion
|
|
429
|
+
//#region ../../internals/tanstack-query/src/utils.ts
|
|
430
|
+
/**
|
|
431
|
+
* The grouped request options, ordered for both the destructured signature and the
|
|
432
|
+
* call passed to the underlying client.
|
|
433
|
+
*/
|
|
434
|
+
const requestGroupOrder$1 = [
|
|
435
|
+
"path",
|
|
436
|
+
"query",
|
|
437
|
+
"body",
|
|
438
|
+
"headers"
|
|
439
|
+
];
|
|
440
|
+
function maybeValueOrGetter(type) {
|
|
441
|
+
return `${type} | (() => ${type})`;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Builds the grouped `{ path, query, body, headers }` parameter that mirrors the client
|
|
445
|
+
* function signature. Only the groups the operation carries are emitted, typed from the
|
|
446
|
+
* operation's `Options`. `keys` narrows the emitted groups, used by the query key which
|
|
447
|
+
* never carries `headers`.
|
|
448
|
+
*
|
|
449
|
+
* By default the whole group is typed as the single `Options` reference. When
|
|
450
|
+
* `memberTypeWrapper` is set, each group is emitted as its own member typed from the matching
|
|
451
|
+
* `Options['<group>']` slice and wrapped, used by vue-query to apply
|
|
452
|
+
* `MaybeRefOrGetter` per group.
|
|
453
|
+
*/
|
|
454
|
+
function buildGroupedRequestParam(node, options) {
|
|
455
|
+
const { resolver, keys = requestGroupOrder$1, memberTypeWrapper } = options;
|
|
456
|
+
const { groups, hasRequiredPath, hasRequiredQuery, hasRequiredHeader } = getRequestGroupOptionality(node);
|
|
457
|
+
const names = keys.filter((key) => groups[key]);
|
|
458
|
+
if (names.length === 0) return null;
|
|
459
|
+
const requiredByGroup = {
|
|
460
|
+
path: hasRequiredPath,
|
|
461
|
+
query: hasRequiredQuery,
|
|
462
|
+
body: groups.body,
|
|
463
|
+
headers: hasRequiredHeader
|
|
464
|
+
};
|
|
465
|
+
const isOptional = names.every((name) => !requiredByGroup[name]);
|
|
466
|
+
const optionsName = resolver.response.options(node);
|
|
467
|
+
const omittedKeys = requestGroupOrder$1.filter((key) => !keys.includes(key));
|
|
468
|
+
const optionsType = omittedKeys.length > 0 ? `Omit<${optionsName}, ${omittedKeys.map((key) => `'${key}'`).join(" | ")}>` : optionsName;
|
|
469
|
+
if (memberTypeWrapper) {
|
|
470
|
+
const members = names.map((name) => ({
|
|
471
|
+
name,
|
|
472
|
+
type: memberTypeWrapper(`${optionsType}['${name}']`),
|
|
473
|
+
optional: !requiredByGroup[name]
|
|
474
|
+
}));
|
|
475
|
+
return (0, _kubb_plugin_ts.createFunctionParameter)({
|
|
476
|
+
name: (0, _kubb_plugin_ts.createObjectBindingPattern)({ elements: names.map((name) => ({ name })) }),
|
|
477
|
+
type: (0, _kubb_plugin_ts.createTypeLiteral)({ members }),
|
|
478
|
+
optional: false,
|
|
479
|
+
...isOptional ? { default: "{}" } : {}
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
return (0, _kubb_plugin_ts.createFunctionParameter)({
|
|
483
|
+
name: (0, _kubb_plugin_ts.createObjectBindingPattern)({ elements: names.map((name) => ({ name })) }),
|
|
484
|
+
type: optionsType,
|
|
485
|
+
optional: false,
|
|
486
|
+
...isOptional ? { default: "{}" } : {}
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Builds the shared `({ path, query, body, headers }, config = {})` parameter list for a
|
|
491
|
+
* TanStack query-options function. The leading parameter mirrors the client signature, and the
|
|
492
|
+
* trailing `config` is a partial `RequestConfig` minus the grouped data-shape keys, which are passed
|
|
493
|
+
* explicitly. Framework plugins wrap the result when needed, for example vue-query applies `MaybeRefOrGetter`.
|
|
494
|
+
*/
|
|
495
|
+
function buildQueryOptionsParams(node, options) {
|
|
496
|
+
const { resolver, memberTypeWrapper } = options;
|
|
497
|
+
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [buildGroupedRequestParam(node, {
|
|
498
|
+
resolver,
|
|
499
|
+
memberTypeWrapper
|
|
500
|
+
}), (0, _kubb_plugin_ts.createFunctionParameter)({
|
|
501
|
+
name: "config",
|
|
502
|
+
type: `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`,
|
|
503
|
+
default: "{}"
|
|
504
|
+
})].filter((param) => param !== null) });
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Builds the call to a client `<op>` function inside a query/mutation hook body. The function takes
|
|
508
|
+
* a single grouped options object, so the operation's request groups are passed as
|
|
509
|
+
* shorthand alongside the spread `config`, with `throwOnError: true` pinned last so a caller's config
|
|
510
|
+
* can't flip the query's error semantics. Queries thread the TanStack `signal`; mutations omit it.
|
|
511
|
+
*
|
|
512
|
+
* When `unwrapName` is set, each request group is passed as an explicit member unwrapped through it,
|
|
513
|
+
* used by vue-query to resolve refs and getters with `toValue(...)` at call time.
|
|
514
|
+
*
|
|
515
|
+
* @example
|
|
516
|
+
* ```ts
|
|
517
|
+
* buildClientCall(node, { clientName: 'getPetById', signal: true })
|
|
518
|
+
* // getPetById({ path, ...config, signal: config.signal ?? signal, throwOnError: true })
|
|
519
|
+
* ```
|
|
520
|
+
*/
|
|
521
|
+
function buildClientCall(node, options) {
|
|
522
|
+
const { clientName, signal = false, unwrapName } = options;
|
|
523
|
+
const { groups } = getRequestGroupOptionality(node);
|
|
524
|
+
return `${clientName}({ ${[
|
|
525
|
+
"...config",
|
|
526
|
+
...requestGroupOrder$1.filter((key) => groups[key]).map((name) => unwrapName ? `${name}: ${unwrapName(name)}` : name),
|
|
527
|
+
signal ? "signal: config.signal ?? signal" : null,
|
|
528
|
+
"throwOnError: true"
|
|
529
|
+
].filter((part) => part !== null).join(", ")} })`;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Builds the `TData` / `TError` type expressions shared by every generated hook, joining the resolved
|
|
533
|
+
* success responses into `TData` and wrapping the error responses in `ResponseErrorConfig<...>`.
|
|
534
|
+
*/
|
|
535
|
+
function buildResponseTypes(node, resolver) {
|
|
536
|
+
const successNames = resolveSuccessNames(node, resolver);
|
|
537
|
+
const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
|
|
538
|
+
const errorNames = resolveErrorNames(node, resolver);
|
|
539
|
+
return {
|
|
540
|
+
TData: responseName,
|
|
541
|
+
TError: `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
function resolveFallbackPageParamType(initialPageParam) {
|
|
545
|
+
if (typeof initialPageParam === "number") return "number";
|
|
546
|
+
if (typeof initialPageParam === "boolean") return "boolean";
|
|
547
|
+
if (typeof initialPageParam !== "string") return "unknown";
|
|
548
|
+
if (!initialPageParam.includes(" as ")) return "string";
|
|
549
|
+
return initialPageParam.split(" as ").at(-1) ?? "unknown";
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Resolves the `TPageParam` generic for the infinite-query hooks. Prefers the type read from the
|
|
553
|
+
* configured `queryParam` on the operation's query object, and falls back to the type inferred from
|
|
554
|
+
* `initialPageParam` when that parameter type is unavailable. Also returns the query params type name
|
|
555
|
+
* so callers can reuse it when rewriting the paginated request.
|
|
556
|
+
*/
|
|
557
|
+
function resolvePageParamType(node, { resolver, initialPageParam, queryParam }) {
|
|
558
|
+
const firstQueryParam = getOperationParameters(node).query[0];
|
|
559
|
+
const groupName = firstQueryParam ? resolver.param.query(node, firstQueryParam) : null;
|
|
560
|
+
const queryParamsTypeName = groupName !== (firstQueryParam ? resolver.param.name(node, firstQueryParam) : null) ? groupName : null;
|
|
561
|
+
const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
|
|
562
|
+
if (!queryParamType) return {
|
|
563
|
+
queryParamsTypeName,
|
|
564
|
+
pageParamType: resolveFallbackPageParamType(initialPageParam)
|
|
565
|
+
};
|
|
566
|
+
return {
|
|
567
|
+
queryParamsTypeName,
|
|
568
|
+
pageParamType: initialPageParam !== void 0 && initialPageParam !== null ? `NonNullable<${queryParamType}>` : queryParamType
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Applies the shared query defaults during plugin setup: `false` disables query generation, and an
|
|
573
|
+
* object merges over `methods: ['GET']` and the plugin's runtime `importPath`.
|
|
574
|
+
*/
|
|
575
|
+
function resolveQueryConfig(query, options) {
|
|
576
|
+
if (query === false) return false;
|
|
577
|
+
return {
|
|
578
|
+
importPath: options.importPath,
|
|
579
|
+
methods: ["GET"],
|
|
580
|
+
...query
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Applies the shared mutation defaults during plugin setup: `false` disables mutation generation,
|
|
585
|
+
* and an object merges over `methods: ['POST', 'PUT', 'PATCH', 'DELETE']` and the plugin's runtime
|
|
586
|
+
* `importPath`.
|
|
587
|
+
*/
|
|
588
|
+
function resolveMutationConfig(mutation, options) {
|
|
589
|
+
if (mutation === false) return false;
|
|
590
|
+
return {
|
|
591
|
+
importPath: options.importPath,
|
|
592
|
+
methods: [
|
|
593
|
+
"POST",
|
|
594
|
+
"PUT",
|
|
595
|
+
"PATCH",
|
|
596
|
+
"DELETE"
|
|
597
|
+
],
|
|
598
|
+
...mutation
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Applies the shared infinite-query defaults during plugin setup: a falsy value disables infinite
|
|
603
|
+
* queries, and an object merges over `queryParam: 'id'` and `initialPageParam: 0` with the cursor
|
|
604
|
+
* paths cleared.
|
|
605
|
+
*/
|
|
606
|
+
function resolveInfiniteConfig(infinite) {
|
|
607
|
+
if (!infinite) return false;
|
|
608
|
+
return {
|
|
609
|
+
queryParam: "id",
|
|
610
|
+
initialPageParam: 0,
|
|
611
|
+
cursorParam: null,
|
|
612
|
+
nextParam: null,
|
|
613
|
+
previousParam: null,
|
|
614
|
+
...infinite
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
function matchesPattern(node, ov) {
|
|
618
|
+
const { type, pattern } = ov;
|
|
619
|
+
const matches = (value) => typeof pattern === "string" ? value === pattern : pattern.test(value);
|
|
620
|
+
if (type === "operationId") return matches(node.operationId);
|
|
621
|
+
if (type === "tag") return node.tags.some((t) => matches(t));
|
|
622
|
+
if (type === "path") return node.path !== void 0 && matches(node.path);
|
|
623
|
+
if (type === "method") return node.method !== void 0 && matches(node.method);
|
|
624
|
+
return false;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Resolves per-operation overrides (first matching override wins).
|
|
628
|
+
*
|
|
629
|
+
* @example
|
|
630
|
+
* ```ts
|
|
631
|
+
* const opts = resolveOperationOverrides(node, override)
|
|
632
|
+
* const queryOpts = 'query' in opts ? opts.query : defaultQuery
|
|
633
|
+
* ```
|
|
634
|
+
*/
|
|
635
|
+
function resolveOperationOverrides(node, override) {
|
|
636
|
+
if (!override) return {};
|
|
637
|
+
return override.find((ov) => matchesPattern(node, ov))?.options ?? {};
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Build QueryKey params as the grouped `{ path, query, body }` object (NO headers, NO config),
|
|
641
|
+
* typed from the operation's `Options` minus `url`. The query key transformer reads the
|
|
642
|
+
* grouped `path`/`query`/`body` bindings.
|
|
643
|
+
*/
|
|
644
|
+
function buildQueryKeyParams(node, options) {
|
|
645
|
+
const { resolver } = options;
|
|
646
|
+
const groupedParam = buildGroupedRequestParam(node, {
|
|
647
|
+
resolver,
|
|
648
|
+
keys: [
|
|
649
|
+
"path",
|
|
650
|
+
"query",
|
|
651
|
+
"body"
|
|
652
|
+
]
|
|
653
|
+
});
|
|
654
|
+
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedParam ? [groupedParam] : [] });
|
|
655
|
+
}
|
|
656
|
+
//#endregion
|
|
657
|
+
//#region ../../internals/tanstack-query/src/components/InfiniteQueryOptions.tsx
|
|
658
|
+
const declarationPrinter$7 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
659
|
+
const callPrinter$3 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
|
|
660
|
+
function InfiniteQueryOptions({ name, clientName, initialPageParam, cursorParam, nextParam, previousParam, node, tsResolver, queryParam, queryKeyName, queryKeyType = "typeof queryKey", memberTypeWrapper, unwrapName }) {
|
|
661
|
+
const { TData: queryFnDataType, TError: errorType } = buildResponseTypes(node, tsResolver);
|
|
662
|
+
const { queryParamsTypeName, pageParamType } = resolvePageParamType(node, {
|
|
663
|
+
resolver: tsResolver,
|
|
664
|
+
initialPageParam,
|
|
665
|
+
queryParam
|
|
666
|
+
});
|
|
667
|
+
const groupedKeyParam = buildGroupedRequestParam(node, {
|
|
668
|
+
resolver: tsResolver,
|
|
669
|
+
keys: [
|
|
670
|
+
"path",
|
|
671
|
+
"query",
|
|
672
|
+
"body"
|
|
673
|
+
],
|
|
674
|
+
memberTypeWrapper
|
|
675
|
+
});
|
|
676
|
+
const queryKeyParamsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedKeyParam ? [groupedKeyParam] : [] });
|
|
677
|
+
const queryKeyParamsCall = callPrinter$3.print(queryKeyParamsNode) ?? "";
|
|
678
|
+
const paramsNode = buildQueryOptionsParams(node, {
|
|
679
|
+
resolver: tsResolver,
|
|
680
|
+
memberTypeWrapper
|
|
681
|
+
});
|
|
682
|
+
const paramsSignature = declarationPrinter$7.print(paramsNode) ?? "";
|
|
683
|
+
const queryFnBody = `const { data } = await ${buildClientCall(node, {
|
|
684
|
+
clientName,
|
|
685
|
+
signal: true,
|
|
686
|
+
unwrapName
|
|
687
|
+
})}
|
|
688
|
+
return data`;
|
|
689
|
+
const hasNewParams = nextParam != null || previousParam != null;
|
|
690
|
+
const [getNextPageParamExpr, getPreviousPageParamExpr] = (() => {
|
|
691
|
+
if (hasNewParams) {
|
|
692
|
+
const nextAccessor = nextParam ? getNestedAccessor(nextParam, "lastPage") : null;
|
|
693
|
+
const prevAccessor = previousParam ? getNestedAccessor(previousParam, "firstPage") : null;
|
|
694
|
+
return [nextAccessor ? `getNextPageParam: (lastPage) => ${nextAccessor}` : null, prevAccessor ? `getPreviousPageParam: (firstPage) => ${prevAccessor}` : null];
|
|
695
|
+
}
|
|
696
|
+
if (cursorParam) return [`getNextPageParam: (lastPage) => lastPage['${cursorParam}']`, `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`];
|
|
697
|
+
return ["getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage) && lastPage.length === 0 ? undefined : lastPageParam + 1", "getPreviousPageParam: (_firstPage, _allPages, firstPageParam) => firstPageParam <= 1 ? undefined : firstPageParam - 1"];
|
|
698
|
+
})();
|
|
699
|
+
const queryOptionsArr = [
|
|
700
|
+
`initialPageParam: ${typeof initialPageParam === "string" ? JSON.stringify(initialPageParam) : initialPageParam}`,
|
|
701
|
+
getNextPageParamExpr,
|
|
702
|
+
getPreviousPageParamExpr
|
|
703
|
+
].filter(Boolean);
|
|
704
|
+
const infiniteOverrideParams = queryParam && queryParamsTypeName ? `query = {
|
|
705
|
+
...(query ?? {}),
|
|
706
|
+
['${queryParam}']: pageParam as unknown as ${queryParamsTypeName}['${queryParam}'],
|
|
707
|
+
} as ${queryParamsTypeName}` : "";
|
|
708
|
+
const queryFnArgs = infiniteOverrideParams ? "{ signal, pageParam }" : "{ signal }";
|
|
709
|
+
const queryFnStatements = infiniteOverrideParams ? `${infiniteOverrideParams}\n ${queryFnBody}` : queryFnBody;
|
|
710
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
711
|
+
name,
|
|
712
|
+
isExportable: true,
|
|
713
|
+
isIndexable: true,
|
|
714
|
+
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
|
|
715
|
+
name,
|
|
716
|
+
export: true,
|
|
717
|
+
params: paramsSignature,
|
|
718
|
+
children: `
|
|
719
|
+
const queryKey = ${queryKeyName}(${queryKeyParamsCall})
|
|
720
|
+
return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${queryFnDataType}>, ${queryKeyType}, ${pageParamType}>({
|
|
721
|
+
queryKey,
|
|
722
|
+
queryFn: async (${queryFnArgs}) => {
|
|
723
|
+
${queryFnStatements}
|
|
724
|
+
},
|
|
725
|
+
${queryOptionsArr.join(",\n ")}
|
|
726
|
+
})
|
|
727
|
+
`
|
|
728
|
+
})
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
//#endregion
|
|
732
|
+
//#region ../../internals/tanstack-query/src/components/MutationKey.tsx
|
|
733
|
+
const declarationPrinter$6 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
734
|
+
const mutationKeyTransformer = ({ node }) => {
|
|
735
|
+
if (!node.path) return [];
|
|
736
|
+
return [`{ url: '${kubb_kit.Url.toPath(node.path)}' }`];
|
|
737
|
+
};
|
|
738
|
+
function MutationKey({ name, node, transformer }) {
|
|
739
|
+
const paramsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: [] });
|
|
740
|
+
const paramsSignature = declarationPrinter$6.print(paramsNode) ?? "";
|
|
741
|
+
const keys = (transformer ?? mutationKeyTransformer)({
|
|
742
|
+
node,
|
|
743
|
+
casing: "camelcase"
|
|
744
|
+
});
|
|
745
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
746
|
+
name,
|
|
747
|
+
isExportable: true,
|
|
748
|
+
isIndexable: true,
|
|
749
|
+
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function.Arrow, {
|
|
750
|
+
name,
|
|
751
|
+
export: true,
|
|
752
|
+
params: paramsSignature,
|
|
753
|
+
singleLine: true,
|
|
754
|
+
children: `[${keys.join(", ")}] as const`
|
|
755
|
+
})
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
//#endregion
|
|
759
|
+
//#region ../../internals/tanstack-query/src/resolver.ts
|
|
760
|
+
/**
|
|
761
|
+
* Builds the shared query namespace for a variant. Spread the result into
|
|
762
|
+
* `createResolver` once per variant the plugin supports.
|
|
763
|
+
*
|
|
764
|
+
* @example
|
|
765
|
+
* ```ts
|
|
766
|
+
* createResolver<PluginReactQuery>({
|
|
767
|
+
* query: createQueryResolver(),
|
|
768
|
+
* suspenseQuery: createQueryResolver('Suspense'),
|
|
769
|
+
* })
|
|
770
|
+
* ```
|
|
771
|
+
*/
|
|
772
|
+
function createQueryResolver(variant = "") {
|
|
773
|
+
return {
|
|
774
|
+
name(node) {
|
|
775
|
+
return `use${capitalize(this.name(node.operationId))}${variant}`;
|
|
776
|
+
},
|
|
777
|
+
optionsName(node) {
|
|
778
|
+
return `${this.name(node.operationId)}${variant}QueryOptions`;
|
|
779
|
+
},
|
|
780
|
+
keyName(node) {
|
|
781
|
+
return `${this.name(node.operationId)}${variant}QueryKey`;
|
|
782
|
+
},
|
|
783
|
+
keyTypeName(node) {
|
|
784
|
+
return `${capitalize(this.name(node.operationId))}${variant}QueryKey`;
|
|
785
|
+
},
|
|
786
|
+
clientName(node) {
|
|
787
|
+
return `${this.name(node.operationId)}${variant}`;
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Builds the shared mutation namespace. Spread the result into
|
|
793
|
+
* `createResolver` and add plugin-specific methods (`optionsName`,
|
|
794
|
+
* `typeName`, `argTypeName`) next to it.
|
|
795
|
+
*
|
|
796
|
+
* @example
|
|
797
|
+
* ```ts
|
|
798
|
+
* createResolver<PluginSwr>({ mutation: { ...createMutationResolver(), argTypeName(node) {...} } })
|
|
799
|
+
* ```
|
|
800
|
+
*/
|
|
801
|
+
function createMutationResolver() {
|
|
802
|
+
return {
|
|
803
|
+
name(node) {
|
|
804
|
+
return `use${capitalize(this.name(node.operationId))}`;
|
|
805
|
+
},
|
|
806
|
+
keyName(node) {
|
|
807
|
+
return `${this.name(node.operationId)}MutationKey`;
|
|
808
|
+
}
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
//#endregion
|
|
812
|
+
//#region ../../internals/tanstack-query/src/components/QueryKey.tsx
|
|
813
|
+
const declarationPrinter$5 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
814
|
+
const queryKeyTransformer = ({ node }) => {
|
|
815
|
+
if (!node.path) return [];
|
|
816
|
+
const hasPathParams = getOperationParameters(node).path.length > 0;
|
|
817
|
+
const hasQueryParams = getOperationParameters(node).query.length > 0;
|
|
818
|
+
const hasRequestBody = !!node.requestBody?.content?.[0]?.schema;
|
|
819
|
+
return [
|
|
820
|
+
hasPathParams ? `{ url: '${kubb_kit.Url.toPath(node.path)}', params: path }` : `{ url: '${kubb_kit.Url.toPath(node.path)}' }`,
|
|
821
|
+
hasQueryParams ? "...(query ? [query] : [])" : null,
|
|
822
|
+
hasRequestBody ? "...(body ? [body] : [])" : null
|
|
823
|
+
].filter(Boolean);
|
|
824
|
+
};
|
|
825
|
+
function QueryKey({ name, node, tsResolver, typeName, transformer }) {
|
|
826
|
+
const paramsNode = buildQueryKeyParams(node, { resolver: tsResolver });
|
|
827
|
+
const paramsSignature = declarationPrinter$5.print(paramsNode) ?? "";
|
|
828
|
+
const keys = (transformer ?? queryKeyTransformer)({
|
|
829
|
+
node,
|
|
830
|
+
casing: "camelcase"
|
|
831
|
+
});
|
|
832
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
833
|
+
name,
|
|
834
|
+
isExportable: true,
|
|
835
|
+
isIndexable: true,
|
|
836
|
+
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function.Arrow, {
|
|
837
|
+
name,
|
|
838
|
+
export: true,
|
|
839
|
+
params: paramsSignature,
|
|
840
|
+
singleLine: true,
|
|
841
|
+
children: `[${keys.join(", ")}] as const`
|
|
842
|
+
})
|
|
843
|
+
}), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
844
|
+
name: typeName,
|
|
845
|
+
isTypeOnly: true,
|
|
846
|
+
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Type, {
|
|
847
|
+
name: typeName,
|
|
848
|
+
children: `ReturnType<typeof ${name}>`
|
|
849
|
+
})
|
|
850
|
+
})] });
|
|
851
|
+
}
|
|
852
|
+
//#endregion
|
|
853
|
+
//#region src/generators/customHookOptionsFileGenerator.tsx
|
|
854
|
+
/**
|
|
855
|
+
* Scaffolds the user-editable `useCustomHookOptions` file when
|
|
856
|
+
* `pluginReactQuery({ customOptions: { ... } })` is configured. The file is
|
|
857
|
+
* only created when it does not already exist, so user edits persist across
|
|
858
|
+
* regeneration.
|
|
859
|
+
*/
|
|
860
|
+
const customHookOptionsFileGenerator = (0, kubb_kit.defineGenerator)({
|
|
861
|
+
name: "react-query-custom-hook-options-file",
|
|
862
|
+
renderer: kubb_jsx.jsxRenderer,
|
|
863
|
+
operations(nodes, ctx) {
|
|
864
|
+
const { resolver, root } = ctx;
|
|
865
|
+
const { output, customOptions, query, group } = ctx.options;
|
|
866
|
+
if (!customOptions) return null;
|
|
867
|
+
const { importPath, name } = customOptions;
|
|
868
|
+
const hookOptionsName = resolver.hook.optionsName();
|
|
869
|
+
const customHookOptionsName = resolver.hook.customOptionsName();
|
|
870
|
+
const reactQueryImportPath = query ? query.importPath : "@tanstack/react-query";
|
|
871
|
+
let hookFilePath;
|
|
872
|
+
const firstNode = nodes[0];
|
|
873
|
+
if (firstNode) {
|
|
874
|
+
const hookName = resolver.query.name(firstNode);
|
|
875
|
+
hookFilePath = resolver.file({
|
|
876
|
+
name: hookName,
|
|
877
|
+
extname: ".ts",
|
|
878
|
+
tag: firstNode.tags[0] ?? "default",
|
|
879
|
+
path: firstNode.path,
|
|
880
|
+
root,
|
|
881
|
+
output,
|
|
882
|
+
group: group ?? void 0
|
|
883
|
+
}).path;
|
|
884
|
+
} else hookFilePath = node_path.default.resolve(root, "index.ts");
|
|
885
|
+
const ensureExtension = (filePath, extname) => {
|
|
886
|
+
if (node_path.default.extname(filePath) === "") return filePath + extname;
|
|
887
|
+
return filePath;
|
|
888
|
+
};
|
|
889
|
+
const basePath = node_path.default.dirname(hookFilePath);
|
|
890
|
+
const actualFilePath = ensureExtension(importPath, ".ts");
|
|
891
|
+
const file = {
|
|
892
|
+
baseName: node_path.default.basename(actualFilePath),
|
|
893
|
+
name: node_path.default.basename(actualFilePath, node_path.default.extname(actualFilePath)),
|
|
894
|
+
path: node_path.default.resolve(basePath, actualFilePath)
|
|
895
|
+
};
|
|
896
|
+
if (node_fs.default.existsSync(file.path)) return null;
|
|
897
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
|
|
898
|
+
baseName: file.baseName,
|
|
899
|
+
path: file.path,
|
|
900
|
+
children: [
|
|
901
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
902
|
+
name: ["QueryClient"],
|
|
903
|
+
path: reactQueryImportPath,
|
|
904
|
+
isTypeOnly: true
|
|
905
|
+
}),
|
|
906
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
907
|
+
name: ["useQueryClient"],
|
|
908
|
+
path: reactQueryImportPath
|
|
909
|
+
}),
|
|
910
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
911
|
+
name: [hookOptionsName],
|
|
912
|
+
root: file.path,
|
|
913
|
+
path: node_path.default.resolve(root, "./index.ts")
|
|
914
|
+
}),
|
|
915
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File.Source, {
|
|
916
|
+
name: file.name,
|
|
917
|
+
isExportable: true,
|
|
918
|
+
isIndexable: true,
|
|
919
|
+
children: [/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
|
|
920
|
+
name: customHookOptionsName,
|
|
921
|
+
params: "{ queryClient }: { queryClient: QueryClient }",
|
|
922
|
+
returnType: `Partial<${hookOptionsName}>`,
|
|
923
|
+
children: `return {
|
|
924
|
+
// TODO: Define custom hook options here
|
|
925
|
+
// Example:
|
|
926
|
+
// useUpdatePetHook: {
|
|
927
|
+
// onSuccess: () => {
|
|
928
|
+
// void queryClient.invalidateQueries({ queryKey: ['pet'] })
|
|
929
|
+
// }
|
|
930
|
+
// }
|
|
931
|
+
}`
|
|
932
|
+
}), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
|
|
933
|
+
name,
|
|
934
|
+
generics: `T extends keyof ${hookOptionsName}`,
|
|
935
|
+
params: "{ hookName, operationId }: { hookName: T, operationId: string }",
|
|
936
|
+
returnType: `${hookOptionsName}[T]`,
|
|
937
|
+
export: true,
|
|
938
|
+
children: `const queryClient = useQueryClient()
|
|
939
|
+
const customOptions = ${customHookOptionsName}({ queryClient })
|
|
940
|
+
return customOptions[hookName] ?? {}`
|
|
941
|
+
})]
|
|
942
|
+
})
|
|
943
|
+
]
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
});
|
|
947
|
+
//#endregion
|
|
948
|
+
//#region src/utils.ts
|
|
949
|
+
const requestGroupOrder = [
|
|
950
|
+
"path",
|
|
951
|
+
"query",
|
|
952
|
+
"body",
|
|
953
|
+
"headers"
|
|
954
|
+
];
|
|
955
|
+
/**
|
|
956
|
+
* Builds the object literal that resolves each request group to a concrete value, unwrapping a getter
|
|
957
|
+
* once before the value reaches the plain `queryKey`/`queryOptions` helpers. A getter must never reach a
|
|
958
|
+
* React Query key, which is hashed structurally. Returns `null` when the operation carries no request group.
|
|
959
|
+
*
|
|
960
|
+
* @example
|
|
961
|
+
* ```ts
|
|
962
|
+
* buildResolvedRequestParams(node) // { path: typeof path === 'function' ? path() : path }
|
|
963
|
+
* ```
|
|
964
|
+
*/
|
|
965
|
+
function buildResolvedRequestParams(node) {
|
|
966
|
+
const groups = getRequestGroups(node);
|
|
967
|
+
const names = requestGroupOrder.filter((key) => groups[key]);
|
|
968
|
+
if (names.length === 0) return null;
|
|
969
|
+
return `{ ${names.map((name) => `${name}: typeof ${name} === 'function' ? ${name}() : ${name}`).join(", ")} }`;
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* Classifies an operation as a query or a mutation from the resolved `query` / `mutation` method lists.
|
|
973
|
+
* `query: false` still marks the operation as a query so the query-family generators keep matching it,
|
|
974
|
+
* and a method already claimed by `query` never counts as a mutation.
|
|
975
|
+
*/
|
|
976
|
+
function classifyOperation(node, { query, mutation }) {
|
|
977
|
+
const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
|
|
978
|
+
const queryMethods = new Set(query ? query.methods : []);
|
|
979
|
+
return {
|
|
980
|
+
isQuery,
|
|
981
|
+
isMutation: mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase())
|
|
982
|
+
};
|
|
983
|
+
}
|
|
984
|
+
//#endregion
|
|
985
|
+
//#region src/generators/hookOptionsGenerator.tsx
|
|
986
|
+
/**
|
|
987
|
+
* Emits the `HookOptions` type used by `customOptions`. Enabled when
|
|
988
|
+
* `pluginReactQuery({ customOptions: { ... } })`. The generated type lists
|
|
989
|
+
* every hook keyed by name so user-supplied options stay in sync with the
|
|
990
|
+
* generated hooks at compile time.
|
|
991
|
+
*/
|
|
992
|
+
const hookOptionsGenerator = (0, kubb_kit.defineGenerator)({
|
|
993
|
+
name: "react-query-hook-options",
|
|
994
|
+
renderer: kubb_jsx.jsxRenderer,
|
|
995
|
+
operations(nodes, ctx) {
|
|
996
|
+
const { resolver, config, root } = ctx;
|
|
997
|
+
const { output, customOptions, query, mutation, suspense, infinite, group, override, hooks } = ctx.options;
|
|
998
|
+
if (!customOptions || !hooks) return null;
|
|
999
|
+
const name = resolver.hook.optionsName();
|
|
1000
|
+
const resolvedFile = resolver.file({
|
|
1001
|
+
name,
|
|
1002
|
+
extname: ".ts",
|
|
1003
|
+
root,
|
|
1004
|
+
output,
|
|
1005
|
+
group: group ?? void 0
|
|
1006
|
+
});
|
|
1007
|
+
const hookOptionsFile = {
|
|
1008
|
+
...resolvedFile,
|
|
1009
|
+
baseName: `${name}.ts`,
|
|
1010
|
+
path: resolvedFile.path.replace(/[^/\\]+\.ts$/, `${name}.ts`)
|
|
1011
|
+
};
|
|
1012
|
+
const imports = [];
|
|
1013
|
+
const hookOptions = {};
|
|
1014
|
+
for (const node of nodes) {
|
|
1015
|
+
if (!kubb_kit.ast.isHttpOperationNode(node)) continue;
|
|
1016
|
+
const opOverrides = resolveOperationOverrides(node, override);
|
|
1017
|
+
const nodeQuery = "query" in opOverrides ? opOverrides.query : query;
|
|
1018
|
+
const nodeMutation = "mutation" in opOverrides ? opOverrides.mutation : mutation;
|
|
1019
|
+
const nodeInfinite = "infinite" in opOverrides ? opOverrides.infinite : infinite;
|
|
1020
|
+
const nodeInfiniteOptions = nodeInfinite && typeof nodeInfinite === "object" ? nodeInfinite : null;
|
|
1021
|
+
const isQueryOp = nodeQuery === false ? !!query && query.methods.some((m) => node.method.toLowerCase() === m.toLowerCase()) : !!nodeQuery && nodeQuery.methods.some((m) => node.method.toLowerCase() === m.toLowerCase());
|
|
1022
|
+
const nodeQueryMethods = new Set(nodeQuery ? nodeQuery.methods : []);
|
|
1023
|
+
const isMutationOp = nodeMutation !== false && !isQueryOp && (nodeMutation ? nodeMutation.methods : []).some((m) => !nodeQueryMethods.has(m) && node.method.toLowerCase() === m.toLowerCase());
|
|
1024
|
+
const isSuspenseOp = !!suspense;
|
|
1025
|
+
const isInfiniteOp = !!nodeInfiniteOptions;
|
|
1026
|
+
if (isQueryOp) {
|
|
1027
|
+
const queryOptionsName = resolver.query.optionsName(node);
|
|
1028
|
+
const queryHookName = resolver.query.name(node);
|
|
1029
|
+
const queryHookFile = resolver.file({
|
|
1030
|
+
...operationFileEntry(node, queryHookName),
|
|
1031
|
+
root,
|
|
1032
|
+
output,
|
|
1033
|
+
group: group ?? void 0
|
|
1034
|
+
});
|
|
1035
|
+
imports.push(/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1036
|
+
name: [queryOptionsName],
|
|
1037
|
+
root: hookOptionsFile.path,
|
|
1038
|
+
path: queryHookFile.path
|
|
1039
|
+
}));
|
|
1040
|
+
hookOptions[queryHookName] = `Partial<ReturnType<typeof ${queryOptionsName}>>`;
|
|
1041
|
+
if (isSuspenseOp) {
|
|
1042
|
+
const suspenseOptionsName = resolver.suspenseQuery.optionsName(node);
|
|
1043
|
+
const suspenseHookName = resolver.suspenseQuery.name(node);
|
|
1044
|
+
const suspenseHookFile = resolver.file({
|
|
1045
|
+
...operationFileEntry(node, suspenseHookName),
|
|
1046
|
+
root,
|
|
1047
|
+
output,
|
|
1048
|
+
group: group ?? void 0
|
|
1049
|
+
});
|
|
1050
|
+
imports.push(/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1051
|
+
name: [suspenseOptionsName],
|
|
1052
|
+
root: hookOptionsFile.path,
|
|
1053
|
+
path: suspenseHookFile.path
|
|
1054
|
+
}));
|
|
1055
|
+
hookOptions[suspenseHookName] = `Partial<ReturnType<typeof ${suspenseOptionsName}>>`;
|
|
1056
|
+
}
|
|
1057
|
+
if (isInfiniteOp) {
|
|
1058
|
+
const normalizeKey = (key) => key.replace(/\?$/, "");
|
|
1059
|
+
const queryParamKeys = getOperationParameters(node).query.map((p) => p.name);
|
|
1060
|
+
if (nodeInfiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === nodeInfiniteOptions.queryParam) : false) {
|
|
1061
|
+
const infiniteOptionsName = resolver.infiniteQuery.optionsName(node);
|
|
1062
|
+
const infiniteHookName = resolver.infiniteQuery.name(node);
|
|
1063
|
+
const infiniteHookFile = resolver.file({
|
|
1064
|
+
...operationFileEntry(node, infiniteHookName),
|
|
1065
|
+
root,
|
|
1066
|
+
output,
|
|
1067
|
+
group: group ?? void 0
|
|
1068
|
+
});
|
|
1069
|
+
imports.push(/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1070
|
+
name: [infiniteOptionsName],
|
|
1071
|
+
root: hookOptionsFile.path,
|
|
1072
|
+
path: infiniteHookFile.path
|
|
1073
|
+
}));
|
|
1074
|
+
hookOptions[infiniteHookName] = `Partial<ReturnType<typeof ${infiniteOptionsName}>>`;
|
|
1075
|
+
if (isSuspenseOp) {
|
|
1076
|
+
const suspenseInfiniteOptionsName = resolver.suspenseInfiniteQuery.optionsName(node);
|
|
1077
|
+
const suspenseInfiniteHookName = resolver.suspenseInfiniteQuery.name(node);
|
|
1078
|
+
const suspenseInfiniteHookFile = resolver.file({
|
|
1079
|
+
...operationFileEntry(node, suspenseInfiniteHookName),
|
|
1080
|
+
root,
|
|
1081
|
+
output,
|
|
1082
|
+
group: group ?? void 0
|
|
1083
|
+
});
|
|
1084
|
+
imports.push(/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1085
|
+
name: [suspenseInfiniteOptionsName],
|
|
1086
|
+
root: hookOptionsFile.path,
|
|
1087
|
+
path: suspenseInfiniteHookFile.path
|
|
1088
|
+
}));
|
|
1089
|
+
hookOptions[suspenseInfiniteHookName] = `Partial<ReturnType<typeof ${suspenseInfiniteOptionsName}>>`;
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
if (isMutationOp) {
|
|
1095
|
+
const mutationOptionsName = resolver.mutation.optionsName(node);
|
|
1096
|
+
const mutationHookName = resolver.mutation.name(node);
|
|
1097
|
+
const mutationHookFile = resolver.file({
|
|
1098
|
+
...operationFileEntry(node, mutationHookName),
|
|
1099
|
+
root,
|
|
1100
|
+
output,
|
|
1101
|
+
group: group ?? void 0
|
|
1102
|
+
});
|
|
1103
|
+
imports.push(/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1104
|
+
name: [mutationOptionsName],
|
|
1105
|
+
root: hookOptionsFile.path,
|
|
1106
|
+
path: mutationHookFile.path
|
|
1107
|
+
}));
|
|
1108
|
+
hookOptions[mutationHookName] = `Partial<ReturnType<typeof ${mutationOptionsName}>>`;
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
|
|
1112
|
+
baseName: hookOptionsFile.baseName,
|
|
1113
|
+
path: hookOptionsFile.path,
|
|
1114
|
+
meta: hookOptionsFile.meta,
|
|
1115
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1116
|
+
output,
|
|
1117
|
+
config,
|
|
1118
|
+
file: {
|
|
1119
|
+
path: hookOptionsFile.path,
|
|
1120
|
+
baseName: hookOptionsFile.baseName
|
|
1121
|
+
}
|
|
1122
|
+
}),
|
|
1123
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1124
|
+
output,
|
|
1125
|
+
config,
|
|
1126
|
+
file: {
|
|
1127
|
+
path: hookOptionsFile.path,
|
|
1128
|
+
baseName: hookOptionsFile.baseName
|
|
1129
|
+
}
|
|
1130
|
+
}),
|
|
1131
|
+
children: [imports, /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
1132
|
+
name,
|
|
1133
|
+
isExportable: true,
|
|
1134
|
+
isIndexable: true,
|
|
1135
|
+
isTypeOnly: true,
|
|
1136
|
+
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Type, {
|
|
1137
|
+
export: true,
|
|
1138
|
+
name,
|
|
1139
|
+
children: `{ ${Object.keys(hookOptions).map((key) => `${JSON.stringify(key)}: ${hookOptions[key]}`).join(", ")} }`
|
|
1140
|
+
})
|
|
1141
|
+
})]
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
});
|
|
1145
|
+
//#endregion
|
|
1146
|
+
//#region src/components/InfiniteQuery.tsx
|
|
1147
|
+
const declarationPrinter$4 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
1148
|
+
function buildInfiniteQueryParamsNode(node, options) {
|
|
1149
|
+
const { resolver, pageParamGeneric, observerOptionsName } = options;
|
|
1150
|
+
const optionsParam = (0, _kubb_plugin_ts.createFunctionParameter)({
|
|
1151
|
+
name: "options",
|
|
1152
|
+
type: `{
|
|
1153
|
+
query?: Partial<${observerOptionsName}<TQueryFnData, TError, TData, TQueryKey, ${pageParamGeneric}>> & { client?: QueryClient },
|
|
1154
|
+
client?: ${buildClientOptionType()}
|
|
1155
|
+
}`,
|
|
1156
|
+
default: "{}"
|
|
1157
|
+
});
|
|
1158
|
+
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [buildGroupedRequestParam(node, {
|
|
1159
|
+
resolver,
|
|
1160
|
+
memberTypeWrapper: maybeValueOrGetter
|
|
1161
|
+
}), optionsParam].filter((param) => param !== null) });
|
|
1162
|
+
}
|
|
1163
|
+
function InfiniteQuery({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, initialPageParam, queryParam, customOptions, suspense }) {
|
|
1164
|
+
const { TData: responseType, TError: errorType } = buildResponseTypes(node, tsResolver);
|
|
1165
|
+
const { pageParamType } = resolvePageParamType(node, {
|
|
1166
|
+
resolver: tsResolver,
|
|
1167
|
+
initialPageParam,
|
|
1168
|
+
queryParam
|
|
1169
|
+
});
|
|
1170
|
+
const hookName = suspense ? "useSuspenseInfiniteQuery" : "useInfiniteQuery";
|
|
1171
|
+
const observerOptionsName = suspense ? "UseSuspenseInfiniteQueryOptions" : "InfiniteQueryObserverOptions";
|
|
1172
|
+
const returnType = `${suspense ? "UseSuspenseInfiniteQueryResult" : "UseInfiniteQueryResult"}<TData, TError> & { queryKey: TQueryKey }`;
|
|
1173
|
+
const generics = [
|
|
1174
|
+
`TQueryFnData = ${responseType}`,
|
|
1175
|
+
`TError = ${errorType}`,
|
|
1176
|
+
"TData = InfiniteData<TQueryFnData>",
|
|
1177
|
+
`TQueryKey extends QueryKey = ${queryKeyTypeName}`,
|
|
1178
|
+
`TPageParam = ${pageParamType}`
|
|
1179
|
+
];
|
|
1180
|
+
const resolvedParams = buildResolvedRequestParams(node);
|
|
1181
|
+
const queryKeyArgs = resolvedParams ? "resolvedParams" : "";
|
|
1182
|
+
const queryOptionsArgs = resolvedParams ? "resolvedParams, config" : "config";
|
|
1183
|
+
const paramsNode = buildInfiniteQueryParamsNode(node, {
|
|
1184
|
+
resolver: tsResolver,
|
|
1185
|
+
pageParamGeneric: "TPageParam",
|
|
1186
|
+
observerOptionsName
|
|
1187
|
+
});
|
|
1188
|
+
const paramsSignature = declarationPrinter$4.print(paramsNode) ?? "";
|
|
1189
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
1190
|
+
name,
|
|
1191
|
+
isExportable: true,
|
|
1192
|
+
isIndexable: true,
|
|
1193
|
+
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
|
|
1194
|
+
name,
|
|
1195
|
+
export: true,
|
|
1196
|
+
generics: generics.join(", "),
|
|
1197
|
+
params: paramsSignature,
|
|
1198
|
+
returnType: void 0,
|
|
1199
|
+
JSDoc: { comments: buildOperationComments(node) },
|
|
1200
|
+
children: `
|
|
1201
|
+
const { query: queryConfig = {}, client: config = {} } = options ?? {}
|
|
1202
|
+
const { client: queryClient, ...resolvedOptions } = queryConfig${resolvedParams ? `\n const resolvedParams = ${resolvedParams}` : ""}
|
|
1203
|
+
const queryKey = resolvedOptions?.queryKey ?? ${queryKeyName}(${queryKeyArgs})${customOptions ? `\n const customOptions = ${customOptions.name}({ hookName: '${name}', operationId: '${node.operationId}' })` : ""}
|
|
1204
|
+
|
|
1205
|
+
const queryResult = ${hookName}({
|
|
1206
|
+
...${queryOptionsName}(${queryOptionsArgs}),${customOptions ? "\n ...customOptions," : ""}
|
|
1207
|
+
...resolvedOptions,
|
|
1208
|
+
queryKey,
|
|
1209
|
+
} as unknown as ${observerOptionsName}<TQueryFnData, TError, TData, TQueryKey, TPageParam>, queryClient) as ${returnType}
|
|
1210
|
+
|
|
1211
|
+
queryResult.queryKey = queryKey as TQueryKey
|
|
1212
|
+
|
|
1213
|
+
return queryResult
|
|
1214
|
+
`
|
|
1215
|
+
})
|
|
1216
|
+
});
|
|
1217
|
+
}
|
|
1218
|
+
//#endregion
|
|
1219
|
+
//#region src/components/MutationOptions.tsx
|
|
1220
|
+
const declarationPrinter$3 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
1221
|
+
const callPrinter$2 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
|
|
1222
|
+
function buildMutationConfigParamsNode(node) {
|
|
1223
|
+
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
|
|
1224
|
+
name: "config",
|
|
1225
|
+
type: buildRequestConfigType(node),
|
|
1226
|
+
default: "{}"
|
|
1227
|
+
})] });
|
|
1228
|
+
}
|
|
1229
|
+
function MutationOptions({ name, clientName, node, tsResolver, mutationKeyName }) {
|
|
1230
|
+
const { TData, TError } = buildResponseTypes(node, tsResolver);
|
|
1231
|
+
const configParamsNode = buildMutationConfigParamsNode(node);
|
|
1232
|
+
const paramsSignature = declarationPrinter$3.print(configParamsNode) ?? "";
|
|
1233
|
+
const groupedParam = buildGroupedRequestParam(node, { resolver: tsResolver });
|
|
1234
|
+
const hasMutationParams = groupedParam !== null;
|
|
1235
|
+
const groupedParamsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedParam ? [groupedParam] : [] });
|
|
1236
|
+
const TRequest = hasMutationParams ? tsResolver.response.options(node) : "undefined";
|
|
1237
|
+
const argBindingStr = hasMutationParams ? callPrinter$2.print(groupedParamsNode) ?? "" : "_";
|
|
1238
|
+
const mutationFnBody = `const { data } = await ${buildClientCall(node, {
|
|
1239
|
+
clientName,
|
|
1240
|
+
signal: false
|
|
1241
|
+
})}
|
|
1242
|
+
return data`;
|
|
1243
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
1244
|
+
name,
|
|
1245
|
+
isExportable: true,
|
|
1246
|
+
isIndexable: true,
|
|
1247
|
+
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
|
|
1248
|
+
name,
|
|
1249
|
+
export: true,
|
|
1250
|
+
params: paramsSignature,
|
|
1251
|
+
generics: ["TContext = unknown"],
|
|
1252
|
+
children: `
|
|
1253
|
+
const mutationKey = ${mutationKeyName}()
|
|
1254
|
+
return mutationOptions<${TData}, ${TError}, ${TRequest}, TContext>({
|
|
1255
|
+
mutationKey,
|
|
1256
|
+
mutationFn: async(${argBindingStr}) => {
|
|
1257
|
+
${mutationFnBody}
|
|
1258
|
+
},
|
|
1259
|
+
})
|
|
1260
|
+
`
|
|
1261
|
+
})
|
|
1262
|
+
});
|
|
1263
|
+
}
|
|
1264
|
+
//#endregion
|
|
1265
|
+
//#region src/components/Mutation.tsx
|
|
1266
|
+
const declarationPrinter$2 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
1267
|
+
const callPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
|
|
1268
|
+
function resolveMutationRequestType(node, resolver) {
|
|
1269
|
+
return buildGroupedRequestParam(node, { resolver }) ? resolver.response.options(node) : "undefined";
|
|
1270
|
+
}
|
|
1271
|
+
function buildMutationParamsNode(node, options) {
|
|
1272
|
+
const { resolver } = options;
|
|
1273
|
+
const { TData, TError } = buildResponseTypes(node, resolver);
|
|
1274
|
+
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
|
|
1275
|
+
name: "options",
|
|
1276
|
+
type: `{
|
|
1277
|
+
mutation?: UseMutationOptions<${[
|
|
1278
|
+
TData,
|
|
1279
|
+
TError,
|
|
1280
|
+
resolveMutationRequestType(node, resolver),
|
|
1281
|
+
"TContext"
|
|
1282
|
+
].join(", ")}> & { client?: QueryClient },
|
|
1283
|
+
client?: ${buildRequestConfigType(node)},
|
|
1284
|
+
}`,
|
|
1285
|
+
default: "{}"
|
|
1286
|
+
})] });
|
|
1287
|
+
}
|
|
1288
|
+
function Mutation({ name, mutationOptionsName, node, tsResolver, mutationKeyName, customOptions }) {
|
|
1289
|
+
const { TData, TError } = buildResponseTypes(node, tsResolver);
|
|
1290
|
+
const generics = [
|
|
1291
|
+
TData,
|
|
1292
|
+
TError,
|
|
1293
|
+
resolveMutationRequestType(node, tsResolver),
|
|
1294
|
+
"TContext"
|
|
1295
|
+
].join(", ");
|
|
1296
|
+
const returnType = `UseMutationResult<${generics}>`;
|
|
1297
|
+
const mutationOptionsConfigNode = buildMutationConfigParamsNode(node);
|
|
1298
|
+
const mutationOptionsParamsCall = callPrinter$1.print(mutationOptionsConfigNode) ?? "";
|
|
1299
|
+
const paramsNode = buildMutationParamsNode(node, { resolver: tsResolver });
|
|
1300
|
+
const paramsSignature = declarationPrinter$2.print(paramsNode) ?? "";
|
|
1301
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
1302
|
+
name,
|
|
1303
|
+
isExportable: true,
|
|
1304
|
+
isIndexable: true,
|
|
1305
|
+
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
|
|
1306
|
+
name,
|
|
1307
|
+
export: true,
|
|
1308
|
+
params: paramsSignature,
|
|
1309
|
+
JSDoc: { comments: buildOperationComments(node) },
|
|
1310
|
+
generics: ["TContext"],
|
|
1311
|
+
children: `
|
|
1312
|
+
const { mutation = {}, client: config = {} } = options ?? {}
|
|
1313
|
+
const { client: queryClient, ...mutationOptions } = mutation;
|
|
1314
|
+
const mutationKey = mutationOptions.mutationKey ?? ${mutationKeyName}()
|
|
1315
|
+
|
|
1316
|
+
const baseOptions = ${mutationOptionsName}(${mutationOptionsParamsCall}) as UseMutationOptions<${generics}>${customOptions ? `\n const customOptions = ${customOptions.name}({ hookName: '${name}', operationId: '${node.operationId}' }) as UseMutationOptions<${generics}>` : ""}
|
|
1317
|
+
|
|
1318
|
+
return useMutation<${generics}>({
|
|
1319
|
+
...baseOptions,${customOptions ? "\n ...customOptions," : ""}
|
|
1320
|
+
mutationKey,
|
|
1321
|
+
...mutationOptions,
|
|
1322
|
+
}, queryClient) as ${returnType}
|
|
1323
|
+
`
|
|
1324
|
+
})
|
|
1325
|
+
});
|
|
1326
|
+
}
|
|
1327
|
+
//#endregion
|
|
1328
|
+
//#region src/components/Query.tsx
|
|
1329
|
+
const declarationPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
1330
|
+
function buildQueryParamsNode(node, options) {
|
|
1331
|
+
const { resolver, observerOptionsType } = options;
|
|
1332
|
+
const optionsParam = (0, _kubb_plugin_ts.createFunctionParameter)({
|
|
1333
|
+
name: "options",
|
|
1334
|
+
type: `{
|
|
1335
|
+
query?: Partial<${observerOptionsType}> & { client?: QueryClient },
|
|
1336
|
+
client?: ${buildClientOptionType()}
|
|
1337
|
+
}`,
|
|
1338
|
+
default: "{}"
|
|
1339
|
+
});
|
|
1340
|
+
return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [buildGroupedRequestParam(node, {
|
|
1341
|
+
resolver,
|
|
1342
|
+
memberTypeWrapper: maybeValueOrGetter
|
|
1343
|
+
}), optionsParam].filter((param) => param !== null) });
|
|
1344
|
+
}
|
|
1345
|
+
function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver, customOptions, suspense }) {
|
|
1346
|
+
const { TData, TError } = buildResponseTypes(node, tsResolver);
|
|
1347
|
+
const hookName = suspense ? "useSuspenseQuery" : "useQuery";
|
|
1348
|
+
const observerOptionsName = suspense ? "UseSuspenseQueryOptions" : "QueryObserverOptions";
|
|
1349
|
+
const observerOptionsType = suspense ? `${observerOptionsName}<${[
|
|
1350
|
+
TData,
|
|
1351
|
+
TError,
|
|
1352
|
+
"TData",
|
|
1353
|
+
"TQueryKey"
|
|
1354
|
+
].join(", ")}>` : `${observerOptionsName}<${[
|
|
1355
|
+
TData,
|
|
1356
|
+
TError,
|
|
1357
|
+
"TData",
|
|
1358
|
+
"TQueryData",
|
|
1359
|
+
"TQueryKey"
|
|
1360
|
+
].join(", ")}>`;
|
|
1361
|
+
const returnType = `${suspense ? "UseSuspenseQueryResult" : "UseQueryResult"}<TData, ${TError}> & { queryKey: TQueryKey }`;
|
|
1362
|
+
const generics = suspense ? [`TData = ${TData}`, `TQueryKey extends QueryKey = ${queryKeyTypeName}`] : [
|
|
1363
|
+
`TData = ${TData}`,
|
|
1364
|
+
`TQueryData = ${TData}`,
|
|
1365
|
+
`TQueryKey extends QueryKey = ${queryKeyTypeName}`
|
|
1366
|
+
];
|
|
1367
|
+
const resolvedParams = buildResolvedRequestParams(node);
|
|
1368
|
+
const queryKeyArgs = resolvedParams ? "resolvedParams" : "";
|
|
1369
|
+
const queryOptionsArgs = resolvedParams ? "resolvedParams, config" : "config";
|
|
1370
|
+
const paramsNode = buildQueryParamsNode(node, {
|
|
1371
|
+
resolver: tsResolver,
|
|
1372
|
+
observerOptionsType
|
|
1373
|
+
});
|
|
1374
|
+
const paramsSignature = declarationPrinter$1.print(paramsNode) ?? "";
|
|
1375
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
1376
|
+
name,
|
|
1377
|
+
isExportable: true,
|
|
1378
|
+
isIndexable: true,
|
|
1379
|
+
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
|
|
1380
|
+
name,
|
|
1381
|
+
export: true,
|
|
1382
|
+
generics: generics.join(", "),
|
|
1383
|
+
params: paramsSignature,
|
|
1384
|
+
returnType: void 0,
|
|
1385
|
+
JSDoc: { comments: buildOperationComments(node) },
|
|
1386
|
+
children: `
|
|
1387
|
+
const { query: queryConfig = {}, client: config = {} } = options ?? {}
|
|
1388
|
+
const { client: queryClient, ...resolvedOptions } = queryConfig${resolvedParams ? `\n const resolvedParams = ${resolvedParams}` : ""}
|
|
1389
|
+
const queryKey = resolvedOptions?.queryKey ?? ${queryKeyName}(${queryKeyArgs})${customOptions ? `\n const customOptions = ${customOptions.name}({ hookName: '${name}', operationId: '${node.operationId}' })` : ""}
|
|
1390
|
+
|
|
1391
|
+
const queryResult = ${hookName}({
|
|
1392
|
+
...${queryOptionsName}(${queryOptionsArgs}),${customOptions ? "\n ...customOptions," : ""}
|
|
1393
|
+
...resolvedOptions,
|
|
1394
|
+
queryKey,
|
|
1395
|
+
} as unknown as ${observerOptionsName}, queryClient) as ${returnType}
|
|
1396
|
+
|
|
1397
|
+
queryResult.queryKey = queryKey as TQueryKey
|
|
1398
|
+
|
|
1399
|
+
return queryResult
|
|
1400
|
+
`
|
|
1401
|
+
})
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1404
|
+
//#endregion
|
|
1405
|
+
//#region src/components/QueryOptions.tsx
|
|
1406
|
+
const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
1407
|
+
const callPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
|
|
1408
|
+
function getQueryOptionsParams(node, options) {
|
|
1409
|
+
return buildQueryOptionsParams(node, options);
|
|
1410
|
+
}
|
|
1411
|
+
function QueryOptions({ name, clientName, node, tsResolver, queryKeyName }) {
|
|
1412
|
+
const { TData, TError } = buildResponseTypes(node, tsResolver);
|
|
1413
|
+
const queryKeyParamsNode = buildQueryKeyParams(node, { resolver: tsResolver });
|
|
1414
|
+
const queryKeyParamsCall = callPrinter.print(queryKeyParamsNode) ?? "";
|
|
1415
|
+
const paramsNode = getQueryOptionsParams(node, { resolver: tsResolver });
|
|
1416
|
+
const paramsSignature = declarationPrinter.print(paramsNode) ?? "";
|
|
1417
|
+
const queryFnBody = `const { data } = await ${buildClientCall(node, {
|
|
1418
|
+
clientName,
|
|
1419
|
+
signal: true
|
|
1420
|
+
})}
|
|
1421
|
+
return data`;
|
|
1422
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
1423
|
+
name,
|
|
1424
|
+
isExportable: true,
|
|
1425
|
+
isIndexable: true,
|
|
1426
|
+
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
|
|
1427
|
+
name,
|
|
1428
|
+
export: true,
|
|
1429
|
+
params: paramsSignature,
|
|
1430
|
+
children: `
|
|
1431
|
+
const queryKey = ${queryKeyName}(${queryKeyParamsCall})
|
|
1432
|
+
return queryOptions<${TData}, ${TError}, ${TData}, typeof queryKey>({
|
|
1433
|
+
queryKey,
|
|
1434
|
+
queryFn: async ({ signal }) => {
|
|
1435
|
+
${queryFnBody}
|
|
1436
|
+
},
|
|
1437
|
+
})
|
|
1438
|
+
`
|
|
1439
|
+
})
|
|
1440
|
+
});
|
|
1441
|
+
}
|
|
1442
|
+
//#endregion
|
|
1443
|
+
//#region src/generators/infiniteQueryGenerator.tsx
|
|
1444
|
+
/**
|
|
1445
|
+
* Built-in generator for `useInfiniteQuery` hooks. Enabled when
|
|
1446
|
+
* `pluginReactQuery({ infinite: { ... }, hooks: true })`. Emits one
|
|
1447
|
+
* `useFooInfiniteQuery` hook per query operation, wiring the configured
|
|
1448
|
+
* `nextParam` / `previousParam` paths into TanStack Query's cursor-based
|
|
1449
|
+
* pagination.
|
|
1450
|
+
*/
|
|
1451
|
+
const infiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
|
|
1452
|
+
name: "react-infinite-query",
|
|
1453
|
+
renderer: kubb_jsx.jsxRenderer,
|
|
1454
|
+
operation(node, ctx) {
|
|
1455
|
+
if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
|
|
1456
|
+
const { config, driver, resolver, root } = ctx;
|
|
1457
|
+
const { output, query, mutation, infinite, client, group, customOptions, hooks } = ctx.options;
|
|
1458
|
+
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
1459
|
+
if (!pluginTs) return null;
|
|
1460
|
+
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
1461
|
+
const { isQuery, isMutation } = classifyOperation(node, {
|
|
1462
|
+
query,
|
|
1463
|
+
mutation
|
|
1464
|
+
});
|
|
1465
|
+
const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
|
|
1466
|
+
if (!isQuery || isMutation || !infiniteOptions || !hooks) return null;
|
|
1467
|
+
const normalizeKey = (key) => key.replace(/\?$/, "");
|
|
1468
|
+
const queryParamKeys = getOperationParameters(node).query.map((p) => p.name);
|
|
1469
|
+
if (!(infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false)) return null;
|
|
1470
|
+
const importPath = query ? query.importPath : "@tanstack/react-query";
|
|
1471
|
+
const contractOp = resolveClientOperation({
|
|
1472
|
+
clientPlugin: { pluginName: client.pluginName },
|
|
1473
|
+
driver,
|
|
1474
|
+
node,
|
|
1475
|
+
root,
|
|
1476
|
+
output
|
|
1477
|
+
});
|
|
1478
|
+
if (!contractOp) return null;
|
|
1479
|
+
const queryName = resolver.infiniteQuery.name(node);
|
|
1480
|
+
const queryOptionsName = resolver.infiniteQuery.optionsName(node);
|
|
1481
|
+
const queryKeyName = resolver.infiniteQuery.keyName(node);
|
|
1482
|
+
const queryKeyTypeName = resolver.infiniteQuery.keyTypeName(node);
|
|
1483
|
+
const meta = {
|
|
1484
|
+
file: resolver.file({
|
|
1485
|
+
...operationFileEntry(node, queryName),
|
|
1486
|
+
root,
|
|
1487
|
+
output,
|
|
1488
|
+
group: group ?? void 0
|
|
1489
|
+
}),
|
|
1490
|
+
fileTs: tsResolver.file({
|
|
1491
|
+
...operationFileEntry(node, node.operationId),
|
|
1492
|
+
root,
|
|
1493
|
+
output: pluginTs.options?.output ?? output,
|
|
1494
|
+
group: pluginTs.options?.group ?? void 0
|
|
1495
|
+
})
|
|
1496
|
+
};
|
|
1497
|
+
const rawQueryParams = getOperationParameters(node).query;
|
|
1498
|
+
const queryParamsTypeName = rawQueryParams.length > 0 && tsResolver.param.query(node, rawQueryParams[0]) !== tsResolver.param.name(node, rawQueryParams[0]) ? tsResolver.param.query(node, rawQueryParams[0]) : null;
|
|
1499
|
+
const importedTypeNames = [
|
|
1500
|
+
tsResolver.response.options(node),
|
|
1501
|
+
queryParamsTypeName,
|
|
1502
|
+
...resolveOperationTypeNames(node, tsResolver, {
|
|
1503
|
+
exclude: [queryKeyTypeName],
|
|
1504
|
+
order: "body-response-first",
|
|
1505
|
+
includeParams: false
|
|
1506
|
+
})
|
|
1507
|
+
].filter((name) => Boolean(name));
|
|
1508
|
+
const calledClientName = contractOp.name;
|
|
1509
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
|
|
1510
|
+
baseName: meta.file.baseName,
|
|
1511
|
+
path: meta.file.path,
|
|
1512
|
+
meta: meta.file.meta,
|
|
1513
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1514
|
+
output,
|
|
1515
|
+
config,
|
|
1516
|
+
file: {
|
|
1517
|
+
path: meta.file.path,
|
|
1518
|
+
baseName: meta.file.baseName
|
|
1519
|
+
}
|
|
1520
|
+
}),
|
|
1521
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1522
|
+
output,
|
|
1523
|
+
config,
|
|
1524
|
+
file: {
|
|
1525
|
+
path: meta.file.path,
|
|
1526
|
+
baseName: meta.file.baseName
|
|
1527
|
+
}
|
|
1528
|
+
}),
|
|
1529
|
+
children: [
|
|
1530
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1531
|
+
name: [contractOp.name],
|
|
1532
|
+
root: meta.file.path,
|
|
1533
|
+
path: contractOp.path
|
|
1534
|
+
}),
|
|
1535
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1536
|
+
name: ["RequestConfig", "ResponseErrorConfig"],
|
|
1537
|
+
root: meta.file.path,
|
|
1538
|
+
path: contractOp.clientPath,
|
|
1539
|
+
isTypeOnly: true
|
|
1540
|
+
}),
|
|
1541
|
+
customOptions && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1542
|
+
name: [customOptions.name],
|
|
1543
|
+
path: customOptions.importPath
|
|
1544
|
+
}),
|
|
1545
|
+
meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1546
|
+
name: Array.from(new Set(importedTypeNames)),
|
|
1547
|
+
root: meta.file.path,
|
|
1548
|
+
path: meta.fileTs.path,
|
|
1549
|
+
isTypeOnly: true
|
|
1550
|
+
}),
|
|
1551
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryKey, {
|
|
1552
|
+
name: queryKeyName,
|
|
1553
|
+
typeName: queryKeyTypeName,
|
|
1554
|
+
node,
|
|
1555
|
+
tsResolver,
|
|
1556
|
+
transformer: ctx.options.queryKey
|
|
1557
|
+
}),
|
|
1558
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1559
|
+
name: ["InfiniteData"],
|
|
1560
|
+
isTypeOnly: true,
|
|
1561
|
+
path: importPath
|
|
1562
|
+
}),
|
|
1563
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1564
|
+
name: ["infiniteQueryOptions"],
|
|
1565
|
+
path: importPath
|
|
1566
|
+
}),
|
|
1567
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(InfiniteQueryOptions, {
|
|
1568
|
+
name: queryOptionsName,
|
|
1569
|
+
clientName: calledClientName,
|
|
1570
|
+
queryKeyName,
|
|
1571
|
+
node,
|
|
1572
|
+
tsResolver,
|
|
1573
|
+
cursorParam: infiniteOptions.cursorParam,
|
|
1574
|
+
nextParam: infiniteOptions.nextParam,
|
|
1575
|
+
previousParam: infiniteOptions.previousParam,
|
|
1576
|
+
initialPageParam: infiniteOptions.initialPageParam,
|
|
1577
|
+
queryParam: infiniteOptions.queryParam
|
|
1578
|
+
}),
|
|
1579
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1580
|
+
name: ["useInfiniteQuery"],
|
|
1581
|
+
path: importPath
|
|
1582
|
+
}),
|
|
1583
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1584
|
+
name: [
|
|
1585
|
+
"QueryKey",
|
|
1586
|
+
"QueryClient",
|
|
1587
|
+
"InfiniteQueryObserverOptions",
|
|
1588
|
+
"UseInfiniteQueryResult"
|
|
1589
|
+
],
|
|
1590
|
+
path: importPath,
|
|
1591
|
+
isTypeOnly: true
|
|
1592
|
+
}),
|
|
1593
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(InfiniteQuery, {
|
|
1594
|
+
name: queryName,
|
|
1595
|
+
queryOptionsName,
|
|
1596
|
+
queryKeyName,
|
|
1597
|
+
queryKeyTypeName,
|
|
1598
|
+
node,
|
|
1599
|
+
tsResolver,
|
|
1600
|
+
initialPageParam: infiniteOptions.initialPageParam,
|
|
1601
|
+
queryParam: infiniteOptions.queryParam,
|
|
1602
|
+
customOptions
|
|
1603
|
+
})
|
|
1604
|
+
]
|
|
1605
|
+
});
|
|
1606
|
+
}
|
|
1607
|
+
});
|
|
1608
|
+
//#endregion
|
|
1609
|
+
//#region src/generators/mutationGenerator.tsx
|
|
1610
|
+
/**
|
|
1611
|
+
* Built-in generator for `useMutation` hooks. Emits one `useFooMutation` hook
|
|
1612
|
+
* per POST/PUT/DELETE operation (configurable via `mutation.methods`) plus
|
|
1613
|
+
* the matching `fooMutationKey` / `fooMutationOptions` helpers.
|
|
1614
|
+
*/
|
|
1615
|
+
const mutationGenerator = (0, kubb_kit.defineGenerator)({
|
|
1616
|
+
name: "react-query-mutation",
|
|
1617
|
+
renderer: kubb_jsx.jsxRenderer,
|
|
1618
|
+
operation(node, ctx) {
|
|
1619
|
+
if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
|
|
1620
|
+
const { config, driver, resolver, root } = ctx;
|
|
1621
|
+
const { output, query, mutation, client, group, customOptions, hooks } = ctx.options;
|
|
1622
|
+
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
1623
|
+
if (!pluginTs) return null;
|
|
1624
|
+
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
1625
|
+
const { isMutation } = classifyOperation(node, {
|
|
1626
|
+
query,
|
|
1627
|
+
mutation
|
|
1628
|
+
});
|
|
1629
|
+
if (!isMutation) return null;
|
|
1630
|
+
const importPath = mutation ? mutation.importPath : "@tanstack/react-query";
|
|
1631
|
+
const contractOp = resolveClientOperation({
|
|
1632
|
+
clientPlugin: { pluginName: client.pluginName },
|
|
1633
|
+
driver,
|
|
1634
|
+
node,
|
|
1635
|
+
root,
|
|
1636
|
+
output
|
|
1637
|
+
});
|
|
1638
|
+
if (!contractOp) return null;
|
|
1639
|
+
const mutationHookName = resolver.mutation.name(node);
|
|
1640
|
+
const mutationTypeName = resolver.mutation.typeName(node);
|
|
1641
|
+
const mutationOptionsName = resolver.mutation.optionsName(node);
|
|
1642
|
+
const mutationKeyName = resolver.mutation.keyName(node);
|
|
1643
|
+
const meta = {
|
|
1644
|
+
file: resolver.file({
|
|
1645
|
+
...operationFileEntry(node, mutationHookName),
|
|
1646
|
+
root,
|
|
1647
|
+
output,
|
|
1648
|
+
group: group ?? void 0
|
|
1649
|
+
}),
|
|
1650
|
+
fileTs: tsResolver.file({
|
|
1651
|
+
...operationFileEntry(node, node.operationId),
|
|
1652
|
+
root,
|
|
1653
|
+
output: pluginTs.options?.output ?? output,
|
|
1654
|
+
group: pluginTs.options?.group ?? void 0
|
|
1655
|
+
})
|
|
1656
|
+
};
|
|
1657
|
+
const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
|
|
1658
|
+
order: "body-response-first",
|
|
1659
|
+
includeParams: false
|
|
1660
|
+
})].filter((name) => Boolean(name));
|
|
1661
|
+
const calledClientName = contractOp.name;
|
|
1662
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
|
|
1663
|
+
baseName: meta.file.baseName,
|
|
1664
|
+
path: meta.file.path,
|
|
1665
|
+
meta: meta.file.meta,
|
|
1666
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1667
|
+
output,
|
|
1668
|
+
config,
|
|
1669
|
+
file: {
|
|
1670
|
+
path: meta.file.path,
|
|
1671
|
+
baseName: meta.file.baseName
|
|
1672
|
+
}
|
|
1673
|
+
}),
|
|
1674
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1675
|
+
output,
|
|
1676
|
+
config,
|
|
1677
|
+
file: {
|
|
1678
|
+
path: meta.file.path,
|
|
1679
|
+
baseName: meta.file.baseName
|
|
1680
|
+
}
|
|
1681
|
+
}),
|
|
1682
|
+
children: [
|
|
1683
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1684
|
+
name: [contractOp.name],
|
|
1685
|
+
root: meta.file.path,
|
|
1686
|
+
path: contractOp.path
|
|
1687
|
+
}),
|
|
1688
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1689
|
+
name: ["RequestConfig", "ResponseErrorConfig"],
|
|
1690
|
+
root: meta.file.path,
|
|
1691
|
+
path: contractOp.clientPath,
|
|
1692
|
+
isTypeOnly: true
|
|
1693
|
+
}),
|
|
1694
|
+
customOptions && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1695
|
+
name: [customOptions.name],
|
|
1696
|
+
path: customOptions.importPath
|
|
1697
|
+
}),
|
|
1698
|
+
meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1699
|
+
name: Array.from(new Set(importedTypeNames)),
|
|
1700
|
+
root: meta.file.path,
|
|
1701
|
+
path: meta.fileTs.path,
|
|
1702
|
+
isTypeOnly: true
|
|
1703
|
+
}),
|
|
1704
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(MutationKey, {
|
|
1705
|
+
name: mutationKeyName,
|
|
1706
|
+
node,
|
|
1707
|
+
transformer: ctx.options.mutationKey
|
|
1708
|
+
}),
|
|
1709
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1710
|
+
name: ["mutationOptions"],
|
|
1711
|
+
path: importPath
|
|
1712
|
+
}),
|
|
1713
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(MutationOptions, {
|
|
1714
|
+
name: mutationOptionsName,
|
|
1715
|
+
clientName: calledClientName,
|
|
1716
|
+
mutationKeyName,
|
|
1717
|
+
node,
|
|
1718
|
+
tsResolver
|
|
1719
|
+
}),
|
|
1720
|
+
mutation && hooks && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [
|
|
1721
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1722
|
+
name: ["useMutation"],
|
|
1723
|
+
path: importPath
|
|
1724
|
+
}),
|
|
1725
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1726
|
+
name: [
|
|
1727
|
+
"UseMutationOptions",
|
|
1728
|
+
"UseMutationResult",
|
|
1729
|
+
"QueryClient"
|
|
1730
|
+
],
|
|
1731
|
+
path: importPath,
|
|
1732
|
+
isTypeOnly: true
|
|
1733
|
+
}),
|
|
1734
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Mutation, {
|
|
1735
|
+
name: mutationHookName,
|
|
1736
|
+
typeName: mutationTypeName,
|
|
1737
|
+
mutationOptionsName,
|
|
1738
|
+
mutationKeyName,
|
|
1739
|
+
node,
|
|
1740
|
+
tsResolver,
|
|
1741
|
+
customOptions
|
|
1742
|
+
})
|
|
1743
|
+
] })
|
|
1744
|
+
]
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1747
|
+
});
|
|
1748
|
+
//#endregion
|
|
1749
|
+
//#region src/generators/queryGenerator.tsx
|
|
1750
|
+
/**
|
|
1751
|
+
* Built-in generator for `useQuery` hooks. Emits one `useFooQuery` hook per
|
|
1752
|
+
* GET operation (configurable via `query.methods`) plus the matching
|
|
1753
|
+
* `fooQueryKey` / `fooQueryOptions` helpers.
|
|
1754
|
+
*/
|
|
1755
|
+
const queryGenerator = (0, kubb_kit.defineGenerator)({
|
|
1756
|
+
name: "react-query",
|
|
1757
|
+
renderer: kubb_jsx.jsxRenderer,
|
|
1758
|
+
operation(node, ctx) {
|
|
1759
|
+
if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
|
|
1760
|
+
const { config, driver, resolver, root } = ctx;
|
|
1761
|
+
const { output, query, mutation, client, group, customOptions, hooks } = ctx.options;
|
|
1762
|
+
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
1763
|
+
if (!pluginTs) return null;
|
|
1764
|
+
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
1765
|
+
const { isQuery, isMutation } = classifyOperation(node, {
|
|
1766
|
+
query,
|
|
1767
|
+
mutation
|
|
1768
|
+
});
|
|
1769
|
+
if (!isQuery || isMutation) return null;
|
|
1770
|
+
const importPath = query ? query.importPath : "@tanstack/react-query";
|
|
1771
|
+
const contractOp = resolveClientOperation({
|
|
1772
|
+
clientPlugin: { pluginName: client.pluginName },
|
|
1773
|
+
driver,
|
|
1774
|
+
node,
|
|
1775
|
+
root,
|
|
1776
|
+
output
|
|
1777
|
+
});
|
|
1778
|
+
if (!contractOp) return null;
|
|
1779
|
+
const queryName = resolver.query.name(node);
|
|
1780
|
+
const queryOptionsName = resolver.query.optionsName(node);
|
|
1781
|
+
const queryKeyName = resolver.query.keyName(node);
|
|
1782
|
+
const queryKeyTypeName = resolver.query.keyTypeName(node);
|
|
1783
|
+
const meta = {
|
|
1784
|
+
file: resolver.file({
|
|
1785
|
+
...operationFileEntry(node, queryName),
|
|
1786
|
+
root,
|
|
1787
|
+
output,
|
|
1788
|
+
group: group ?? void 0
|
|
1789
|
+
}),
|
|
1790
|
+
fileTs: tsResolver.file({
|
|
1791
|
+
...operationFileEntry(node, node.operationId),
|
|
1792
|
+
root,
|
|
1793
|
+
output: pluginTs.options?.output ?? output,
|
|
1794
|
+
group: pluginTs.options?.group ?? void 0
|
|
1795
|
+
})
|
|
1796
|
+
};
|
|
1797
|
+
const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
|
|
1798
|
+
exclude: [queryKeyTypeName],
|
|
1799
|
+
order: "body-response-first",
|
|
1800
|
+
includeParams: false
|
|
1801
|
+
})].filter((name) => Boolean(name));
|
|
1802
|
+
const calledClientName = contractOp.name;
|
|
1803
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
|
|
1804
|
+
baseName: meta.file.baseName,
|
|
1805
|
+
path: meta.file.path,
|
|
1806
|
+
meta: meta.file.meta,
|
|
1807
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1808
|
+
output,
|
|
1809
|
+
config,
|
|
1810
|
+
file: {
|
|
1811
|
+
path: meta.file.path,
|
|
1812
|
+
baseName: meta.file.baseName
|
|
1813
|
+
}
|
|
1814
|
+
}),
|
|
1815
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1816
|
+
output,
|
|
1817
|
+
config,
|
|
1818
|
+
file: {
|
|
1819
|
+
path: meta.file.path,
|
|
1820
|
+
baseName: meta.file.baseName
|
|
1821
|
+
}
|
|
1822
|
+
}),
|
|
1823
|
+
children: [
|
|
1824
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1825
|
+
name: [contractOp.name],
|
|
1826
|
+
root: meta.file.path,
|
|
1827
|
+
path: contractOp.path
|
|
1828
|
+
}),
|
|
1829
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1830
|
+
name: ["RequestConfig", "ResponseErrorConfig"],
|
|
1831
|
+
root: meta.file.path,
|
|
1832
|
+
path: contractOp.clientPath,
|
|
1833
|
+
isTypeOnly: true
|
|
1834
|
+
}),
|
|
1835
|
+
customOptions && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1836
|
+
name: [customOptions.name],
|
|
1837
|
+
path: customOptions.importPath
|
|
1838
|
+
}),
|
|
1839
|
+
meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1840
|
+
name: Array.from(new Set(importedTypeNames)),
|
|
1841
|
+
root: meta.file.path,
|
|
1842
|
+
path: meta.fileTs.path,
|
|
1843
|
+
isTypeOnly: true
|
|
1844
|
+
}),
|
|
1845
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryKey, {
|
|
1846
|
+
name: queryKeyName,
|
|
1847
|
+
typeName: queryKeyTypeName,
|
|
1848
|
+
node,
|
|
1849
|
+
tsResolver,
|
|
1850
|
+
transformer: ctx.options.queryKey
|
|
1851
|
+
}),
|
|
1852
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1853
|
+
name: ["queryOptions"],
|
|
1854
|
+
path: importPath
|
|
1855
|
+
}),
|
|
1856
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryOptions, {
|
|
1857
|
+
name: queryOptionsName,
|
|
1858
|
+
clientName: calledClientName,
|
|
1859
|
+
queryKeyName,
|
|
1860
|
+
node,
|
|
1861
|
+
tsResolver
|
|
1862
|
+
}),
|
|
1863
|
+
query && hooks && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [
|
|
1864
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1865
|
+
name: ["useQuery"],
|
|
1866
|
+
path: importPath
|
|
1867
|
+
}),
|
|
1868
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1869
|
+
name: [
|
|
1870
|
+
"QueryKey",
|
|
1871
|
+
"QueryClient",
|
|
1872
|
+
"QueryObserverOptions",
|
|
1873
|
+
"UseQueryResult"
|
|
1874
|
+
],
|
|
1875
|
+
path: importPath,
|
|
1876
|
+
isTypeOnly: true
|
|
1877
|
+
}),
|
|
1878
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Query, {
|
|
1879
|
+
name: queryName,
|
|
1880
|
+
queryOptionsName,
|
|
1881
|
+
queryKeyName,
|
|
1882
|
+
queryKeyTypeName,
|
|
1883
|
+
node,
|
|
1884
|
+
tsResolver,
|
|
1885
|
+
customOptions
|
|
1886
|
+
})
|
|
1887
|
+
] })
|
|
1888
|
+
]
|
|
1889
|
+
});
|
|
1890
|
+
}
|
|
1891
|
+
});
|
|
1892
|
+
//#endregion
|
|
1893
|
+
//#region src/generators/suspenseInfiniteQueryGenerator.tsx
|
|
1894
|
+
/**
|
|
1895
|
+
* Built-in generator for `useSuspenseInfiniteQuery` hooks. Enabled when
|
|
1896
|
+
* `suspense`, `infinite`, and `hooks` are all configured. Combines suspense
|
|
1897
|
+
* semantics with cursor-based pagination. Handlers throw promises while
|
|
1898
|
+
* loading and pull additional pages on demand.
|
|
1899
|
+
*/
|
|
1900
|
+
const suspenseInfiniteQueryGenerator = (0, kubb_kit.defineGenerator)({
|
|
1901
|
+
name: "react-suspense-infinite-query",
|
|
1902
|
+
renderer: kubb_jsx.jsxRenderer,
|
|
1903
|
+
operation(node, ctx) {
|
|
1904
|
+
if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
|
|
1905
|
+
const { config, driver, resolver, root } = ctx;
|
|
1906
|
+
const { output, query, mutation, infinite, suspense, client, group, customOptions, hooks } = ctx.options;
|
|
1907
|
+
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
1908
|
+
if (!pluginTs) return null;
|
|
1909
|
+
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
1910
|
+
const { isQuery, isMutation } = classifyOperation(node, {
|
|
1911
|
+
query,
|
|
1912
|
+
mutation
|
|
1913
|
+
});
|
|
1914
|
+
const isSuspense = !!suspense;
|
|
1915
|
+
const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
|
|
1916
|
+
if (!isQuery || isMutation || !isSuspense || !infiniteOptions || !hooks) return null;
|
|
1917
|
+
const normalizeKey = (key) => key.replace(/\?$/, "");
|
|
1918
|
+
const queryParamKeys = getOperationParameters(node).query.map((p) => p.name);
|
|
1919
|
+
if (!(infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false)) return null;
|
|
1920
|
+
const importPath = query ? query.importPath : "@tanstack/react-query";
|
|
1921
|
+
const contractOp = resolveClientOperation({
|
|
1922
|
+
clientPlugin: { pluginName: client.pluginName },
|
|
1923
|
+
driver,
|
|
1924
|
+
node,
|
|
1925
|
+
root,
|
|
1926
|
+
output
|
|
1927
|
+
});
|
|
1928
|
+
if (!contractOp) return null;
|
|
1929
|
+
const queryName = resolver.suspenseInfiniteQuery.name(node);
|
|
1930
|
+
const queryOptionsName = resolver.suspenseInfiniteQuery.optionsName(node);
|
|
1931
|
+
const queryKeyName = resolver.suspenseInfiniteQuery.keyName(node);
|
|
1932
|
+
const queryKeyTypeName = resolver.suspenseInfiniteQuery.keyTypeName(node);
|
|
1933
|
+
const meta = {
|
|
1934
|
+
file: resolver.file({
|
|
1935
|
+
...operationFileEntry(node, queryName),
|
|
1936
|
+
root,
|
|
1937
|
+
output,
|
|
1938
|
+
group: group ?? void 0
|
|
1939
|
+
}),
|
|
1940
|
+
fileTs: tsResolver.file({
|
|
1941
|
+
...operationFileEntry(node, node.operationId),
|
|
1942
|
+
root,
|
|
1943
|
+
output: pluginTs.options?.output ?? output,
|
|
1944
|
+
group: pluginTs.options?.group ?? void 0
|
|
1945
|
+
})
|
|
1946
|
+
};
|
|
1947
|
+
const rawQueryParams = getOperationParameters(node).query;
|
|
1948
|
+
const queryParamsTypeName = rawQueryParams.length > 0 && tsResolver.param.query(node, rawQueryParams[0]) !== tsResolver.param.name(node, rawQueryParams[0]) ? tsResolver.param.query(node, rawQueryParams[0]) : null;
|
|
1949
|
+
const importedTypeNames = [
|
|
1950
|
+
tsResolver.response.options(node),
|
|
1951
|
+
queryParamsTypeName,
|
|
1952
|
+
...resolveOperationTypeNames(node, tsResolver, {
|
|
1953
|
+
order: "body-response-first",
|
|
1954
|
+
includeParams: false
|
|
1955
|
+
})
|
|
1956
|
+
].filter((name) => Boolean(name));
|
|
1957
|
+
const calledClientName = contractOp.name;
|
|
1958
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
|
|
1959
|
+
baseName: meta.file.baseName,
|
|
1960
|
+
path: meta.file.path,
|
|
1961
|
+
meta: meta.file.meta,
|
|
1962
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1963
|
+
output,
|
|
1964
|
+
config,
|
|
1965
|
+
file: {
|
|
1966
|
+
path: meta.file.path,
|
|
1967
|
+
baseName: meta.file.baseName
|
|
1968
|
+
}
|
|
1969
|
+
}),
|
|
1970
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1971
|
+
output,
|
|
1972
|
+
config,
|
|
1973
|
+
file: {
|
|
1974
|
+
path: meta.file.path,
|
|
1975
|
+
baseName: meta.file.baseName
|
|
1976
|
+
}
|
|
1977
|
+
}),
|
|
1978
|
+
children: [
|
|
1979
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1980
|
+
name: [contractOp.name],
|
|
1981
|
+
root: meta.file.path,
|
|
1982
|
+
path: contractOp.path
|
|
1983
|
+
}),
|
|
1984
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1985
|
+
name: ["RequestConfig", "ResponseErrorConfig"],
|
|
1986
|
+
root: meta.file.path,
|
|
1987
|
+
path: contractOp.clientPath,
|
|
1988
|
+
isTypeOnly: true
|
|
1989
|
+
}),
|
|
1990
|
+
customOptions && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1991
|
+
name: [customOptions.name],
|
|
1992
|
+
path: customOptions.importPath
|
|
1993
|
+
}),
|
|
1994
|
+
meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
1995
|
+
name: Array.from(new Set(importedTypeNames)),
|
|
1996
|
+
root: meta.file.path,
|
|
1997
|
+
path: meta.fileTs.path,
|
|
1998
|
+
isTypeOnly: true
|
|
1999
|
+
}),
|
|
2000
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryKey, {
|
|
2001
|
+
name: queryKeyName,
|
|
2002
|
+
typeName: queryKeyTypeName,
|
|
2003
|
+
node,
|
|
2004
|
+
tsResolver,
|
|
2005
|
+
transformer: ctx.options.queryKey
|
|
2006
|
+
}),
|
|
2007
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
2008
|
+
name: ["InfiniteData"],
|
|
2009
|
+
isTypeOnly: true,
|
|
2010
|
+
path: importPath
|
|
2011
|
+
}),
|
|
2012
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
2013
|
+
name: ["infiniteQueryOptions"],
|
|
2014
|
+
path: importPath
|
|
2015
|
+
}),
|
|
2016
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(InfiniteQueryOptions, {
|
|
2017
|
+
name: queryOptionsName,
|
|
2018
|
+
clientName: calledClientName,
|
|
2019
|
+
queryKeyName,
|
|
2020
|
+
node,
|
|
2021
|
+
tsResolver,
|
|
2022
|
+
cursorParam: infiniteOptions.cursorParam,
|
|
2023
|
+
nextParam: infiniteOptions.nextParam,
|
|
2024
|
+
previousParam: infiniteOptions.previousParam,
|
|
2025
|
+
initialPageParam: infiniteOptions.initialPageParam,
|
|
2026
|
+
queryParam: infiniteOptions.queryParam
|
|
2027
|
+
}),
|
|
2028
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
2029
|
+
name: ["useSuspenseInfiniteQuery"],
|
|
2030
|
+
path: importPath
|
|
2031
|
+
}),
|
|
2032
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
2033
|
+
name: [
|
|
2034
|
+
"QueryKey",
|
|
2035
|
+
"QueryClient",
|
|
2036
|
+
"UseSuspenseInfiniteQueryOptions",
|
|
2037
|
+
"UseSuspenseInfiniteQueryResult"
|
|
2038
|
+
],
|
|
2039
|
+
path: importPath,
|
|
2040
|
+
isTypeOnly: true
|
|
2041
|
+
}),
|
|
2042
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(InfiniteQuery, {
|
|
2043
|
+
name: queryName,
|
|
2044
|
+
queryOptionsName,
|
|
2045
|
+
queryKeyName,
|
|
2046
|
+
queryKeyTypeName,
|
|
2047
|
+
node,
|
|
2048
|
+
tsResolver,
|
|
2049
|
+
initialPageParam: infiniteOptions.initialPageParam,
|
|
2050
|
+
queryParam: infiniteOptions.queryParam,
|
|
2051
|
+
customOptions,
|
|
2052
|
+
suspense: true
|
|
2053
|
+
})
|
|
2054
|
+
]
|
|
2055
|
+
});
|
|
2056
|
+
}
|
|
2057
|
+
});
|
|
2058
|
+
//#endregion
|
|
2059
|
+
//#region src/generators/suspenseQueryGenerator.tsx
|
|
2060
|
+
/**
|
|
2061
|
+
* Built-in generator for `useSuspenseQuery` hooks. Enabled when
|
|
2062
|
+
* `pluginReactQuery({ suspense: {}, hooks: true })`. Emits one
|
|
2063
|
+
* `useFooSuspenseQuery` hook per query operation. Suspense queries throw
|
|
2064
|
+
* promises while loading and require a `<Suspense>` boundary in the React
|
|
2065
|
+
* tree. TanStack Query v5+ only.
|
|
2066
|
+
*/
|
|
2067
|
+
const suspenseQueryGenerator = (0, kubb_kit.defineGenerator)({
|
|
2068
|
+
name: "react-suspense-query",
|
|
2069
|
+
renderer: kubb_jsx.jsxRenderer,
|
|
2070
|
+
operation(node, ctx) {
|
|
2071
|
+
if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
|
|
2072
|
+
const { config, driver, resolver, root } = ctx;
|
|
2073
|
+
const { output, query, mutation, suspense, client, group, customOptions, hooks } = ctx.options;
|
|
2074
|
+
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
2075
|
+
if (!pluginTs) return null;
|
|
2076
|
+
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
2077
|
+
const { isQuery, isMutation } = classifyOperation(node, {
|
|
2078
|
+
query,
|
|
2079
|
+
mutation
|
|
2080
|
+
});
|
|
2081
|
+
if (!isQuery || isMutation || !!!suspense || !hooks) return null;
|
|
2082
|
+
const importPath = query ? query.importPath : "@tanstack/react-query";
|
|
2083
|
+
const contractOp = resolveClientOperation({
|
|
2084
|
+
clientPlugin: { pluginName: client.pluginName },
|
|
2085
|
+
driver,
|
|
2086
|
+
node,
|
|
2087
|
+
root,
|
|
2088
|
+
output
|
|
2089
|
+
});
|
|
2090
|
+
if (!contractOp) return null;
|
|
2091
|
+
const queryName = resolver.suspenseQuery.name(node);
|
|
2092
|
+
const queryOptionsName = resolver.suspenseQuery.optionsName(node);
|
|
2093
|
+
const queryKeyName = resolver.suspenseQuery.keyName(node);
|
|
2094
|
+
const queryKeyTypeName = resolver.suspenseQuery.keyTypeName(node);
|
|
2095
|
+
const meta = {
|
|
2096
|
+
file: resolver.file({
|
|
2097
|
+
...operationFileEntry(node, queryName),
|
|
2098
|
+
root,
|
|
2099
|
+
output,
|
|
2100
|
+
group: group ?? void 0
|
|
2101
|
+
}),
|
|
2102
|
+
fileTs: tsResolver.file({
|
|
2103
|
+
...operationFileEntry(node, node.operationId),
|
|
2104
|
+
root,
|
|
2105
|
+
output: pluginTs.options?.output ?? output,
|
|
2106
|
+
group: pluginTs.options?.group ?? void 0
|
|
2107
|
+
})
|
|
2108
|
+
};
|
|
2109
|
+
const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
|
|
2110
|
+
exclude: [queryKeyTypeName],
|
|
2111
|
+
order: "body-response-first",
|
|
2112
|
+
includeParams: false
|
|
2113
|
+
})].filter((name) => Boolean(name));
|
|
2114
|
+
const calledClientName = contractOp.name;
|
|
2115
|
+
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
|
|
2116
|
+
baseName: meta.file.baseName,
|
|
2117
|
+
path: meta.file.path,
|
|
2118
|
+
meta: meta.file.meta,
|
|
2119
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
2120
|
+
output,
|
|
2121
|
+
config,
|
|
2122
|
+
file: {
|
|
2123
|
+
path: meta.file.path,
|
|
2124
|
+
baseName: meta.file.baseName
|
|
2125
|
+
}
|
|
2126
|
+
}),
|
|
2127
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
2128
|
+
output,
|
|
2129
|
+
config,
|
|
2130
|
+
file: {
|
|
2131
|
+
path: meta.file.path,
|
|
2132
|
+
baseName: meta.file.baseName
|
|
2133
|
+
}
|
|
2134
|
+
}),
|
|
2135
|
+
children: [
|
|
2136
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
2137
|
+
name: [contractOp.name],
|
|
2138
|
+
root: meta.file.path,
|
|
2139
|
+
path: contractOp.path
|
|
2140
|
+
}),
|
|
2141
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
2142
|
+
name: ["RequestConfig", "ResponseErrorConfig"],
|
|
2143
|
+
root: meta.file.path,
|
|
2144
|
+
path: contractOp.clientPath,
|
|
2145
|
+
isTypeOnly: true
|
|
2146
|
+
}),
|
|
2147
|
+
customOptions && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
2148
|
+
name: [customOptions.name],
|
|
2149
|
+
path: customOptions.importPath
|
|
2150
|
+
}),
|
|
2151
|
+
meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
2152
|
+
name: Array.from(new Set(importedTypeNames)),
|
|
2153
|
+
root: meta.file.path,
|
|
2154
|
+
path: meta.fileTs.path,
|
|
2155
|
+
isTypeOnly: true
|
|
2156
|
+
}),
|
|
2157
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryKey, {
|
|
2158
|
+
name: queryKeyName,
|
|
2159
|
+
typeName: queryKeyTypeName,
|
|
2160
|
+
node,
|
|
2161
|
+
tsResolver,
|
|
2162
|
+
transformer: ctx.options.queryKey
|
|
2163
|
+
}),
|
|
2164
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
2165
|
+
name: ["queryOptions"],
|
|
2166
|
+
path: importPath
|
|
2167
|
+
}),
|
|
2168
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryOptions, {
|
|
2169
|
+
name: queryOptionsName,
|
|
2170
|
+
clientName: calledClientName,
|
|
2171
|
+
queryKeyName,
|
|
2172
|
+
node,
|
|
2173
|
+
tsResolver
|
|
2174
|
+
}),
|
|
2175
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
2176
|
+
name: ["useSuspenseQuery"],
|
|
2177
|
+
path: importPath
|
|
2178
|
+
}),
|
|
2179
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
2180
|
+
name: [
|
|
2181
|
+
"QueryKey",
|
|
2182
|
+
"QueryClient",
|
|
2183
|
+
"UseSuspenseQueryOptions",
|
|
2184
|
+
"UseSuspenseQueryResult"
|
|
2185
|
+
],
|
|
2186
|
+
path: importPath,
|
|
2187
|
+
isTypeOnly: true
|
|
2188
|
+
}),
|
|
2189
|
+
/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Query, {
|
|
2190
|
+
name: queryName,
|
|
2191
|
+
queryOptionsName,
|
|
2192
|
+
queryKeyName,
|
|
2193
|
+
queryKeyTypeName,
|
|
2194
|
+
node,
|
|
2195
|
+
tsResolver,
|
|
2196
|
+
customOptions,
|
|
2197
|
+
suspense: true
|
|
2198
|
+
})
|
|
2199
|
+
]
|
|
2200
|
+
});
|
|
2201
|
+
}
|
|
2202
|
+
});
|
|
2203
|
+
//#endregion
|
|
2204
|
+
//#region src/resolvers/resolverReactQuery.ts
|
|
2205
|
+
/**
|
|
2206
|
+
* Default resolver used by `@kubb/plugin-react-query`. Decides the names and
|
|
2207
|
+
* file paths for every generated TanStack Query hook (`useFoo`,
|
|
2208
|
+
* `useFooSuspense`, `useFooInfinite`, ...) and its companion helpers
|
|
2209
|
+
* (`fooQueryKey`, `fooQueryOptions`).
|
|
2210
|
+
*
|
|
2211
|
+
* Functions and files use the built-in camelCase casing; hooks get the `use`
|
|
2212
|
+
* prefix; suspense and infinite variants are suffixed with `Suspense`/`Infinite`.
|
|
2213
|
+
*
|
|
2214
|
+
* @example Resolve hook and helper names
|
|
2215
|
+
* ```ts
|
|
2216
|
+
* import { resolverReactQuery } from '@kubb/plugin-react-query'
|
|
2217
|
+
*
|
|
2218
|
+
* resolverReactQuery.query.name(operationNode) // 'useGetPetById'
|
|
2219
|
+
* resolverReactQuery.mutation.name(operationNode) // 'useUpdatePet'
|
|
2220
|
+
* resolverReactQuery.query.keyName(operationNode) // 'getPetByIdQueryKey'
|
|
2221
|
+
* resolverReactQuery.query.optionsName(operationNode) // 'getPetByIdQueryOptions'
|
|
2222
|
+
* ```
|
|
2223
|
+
*/
|
|
2224
|
+
const resolverReactQuery = (0, kubb_kit.createResolver)({
|
|
2225
|
+
pluginName: "plugin-react-query",
|
|
2226
|
+
query: createQueryResolver(),
|
|
2227
|
+
suspenseQuery: createQueryResolver("Suspense"),
|
|
2228
|
+
infiniteQuery: createQueryResolver("Infinite"),
|
|
2229
|
+
suspenseInfiniteQuery: createQueryResolver("SuspenseInfinite"),
|
|
2230
|
+
mutation: {
|
|
2231
|
+
...createMutationResolver(),
|
|
2232
|
+
optionsName(node) {
|
|
2233
|
+
return `${this.name(node.operationId)}MutationOptions`;
|
|
2234
|
+
},
|
|
2235
|
+
typeName(node) {
|
|
2236
|
+
return capitalize(this.name(node.operationId));
|
|
2237
|
+
}
|
|
2238
|
+
},
|
|
2239
|
+
hook: {
|
|
2240
|
+
optionsName() {
|
|
2241
|
+
return "HookOptions";
|
|
2242
|
+
},
|
|
2243
|
+
customOptionsName() {
|
|
2244
|
+
return "getCustomHookOptions";
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
});
|
|
2248
|
+
//#endregion
|
|
14
2249
|
//#region src/plugin.ts
|
|
2250
|
+
/**
|
|
2251
|
+
* Canonical plugin name for `@kubb/plugin-react-query`. Used for driver lookups
|
|
2252
|
+
* and cross-plugin dependency references.
|
|
2253
|
+
*/
|
|
15
2254
|
const pluginReactQueryName = "plugin-react-query";
|
|
16
|
-
|
|
2255
|
+
/**
|
|
2256
|
+
* Generates one TanStack Query hook per OpenAPI operation for React. Queries
|
|
2257
|
+
* become `useFoo`, with `useFooSuspense` and `useFooInfinite` variants.
|
|
2258
|
+
* Mutations become `useFoo`. Each hook is fully typed: query keys, input
|
|
2259
|
+
* variables, response data, and error shape all come from the spec.
|
|
2260
|
+
*
|
|
2261
|
+
* @example
|
|
2262
|
+
* ```ts
|
|
2263
|
+
* import { defineConfig } from 'kubb/config'
|
|
2264
|
+
* import { pluginTs } from '@kubb/plugin-ts'
|
|
2265
|
+
* import { pluginReactQuery } from '@kubb/plugin-react-query'
|
|
2266
|
+
*
|
|
2267
|
+
* export default defineConfig({
|
|
2268
|
+
* input: './petStore.yaml',
|
|
2269
|
+
* output: { path: './src/gen' },
|
|
2270
|
+
* plugins: [
|
|
2271
|
+
* pluginTs(),
|
|
2272
|
+
* pluginReactQuery({
|
|
2273
|
+
* output: { path: './hooks' },
|
|
2274
|
+
* suspense: {},
|
|
2275
|
+
* }),
|
|
2276
|
+
* ],
|
|
2277
|
+
* })
|
|
2278
|
+
* ```
|
|
2279
|
+
*/
|
|
2280
|
+
const pluginReactQuery = (0, kubb_kit.definePlugin)((options) => {
|
|
17
2281
|
const { output = {
|
|
18
2282
|
path: "hooks",
|
|
19
|
-
|
|
20
|
-
}, group, exclude = [], include, override = [],
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const
|
|
2283
|
+
barrel: { type: "named" }
|
|
2284
|
+
}, group, exclude = [], include, override = [], suspense = false, infinite = false, mutation = {}, query = {}, mutationKey = mutationKeyTransformer, queryKey = queryKeyTransformer, customOptions, hooks = false, client, resolver: userResolver, macros: userMacros } = options;
|
|
2285
|
+
const selectedGenerators = [
|
|
2286
|
+
queryGenerator,
|
|
2287
|
+
suspenseQueryGenerator,
|
|
2288
|
+
infiniteQueryGenerator,
|
|
2289
|
+
suspenseInfiniteQueryGenerator,
|
|
2290
|
+
mutationGenerator,
|
|
2291
|
+
hookOptionsGenerator,
|
|
2292
|
+
customHookOptionsFileGenerator
|
|
2293
|
+
];
|
|
2294
|
+
const groupConfig = createGroupConfig(group);
|
|
31
2295
|
return {
|
|
32
2296
|
name: pluginReactQueryName,
|
|
33
|
-
options
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
query: query === false ? false : {
|
|
56
|
-
methods: ["get"],
|
|
57
|
-
importPath: "@tanstack/react-query",
|
|
58
|
-
...query
|
|
59
|
-
},
|
|
60
|
-
mutationKey,
|
|
61
|
-
mutation: mutation === false ? false : {
|
|
62
|
-
methods: [
|
|
63
|
-
"post",
|
|
64
|
-
"put",
|
|
65
|
-
"patch",
|
|
66
|
-
"delete"
|
|
67
|
-
],
|
|
68
|
-
importPath: "@tanstack/react-query",
|
|
69
|
-
...mutation
|
|
70
|
-
},
|
|
71
|
-
customOptions: customOptions ? {
|
|
72
|
-
name: "useCustomHookOptions",
|
|
73
|
-
...customOptions
|
|
74
|
-
} : void 0,
|
|
75
|
-
paramsType,
|
|
76
|
-
pathParamsType,
|
|
77
|
-
parser,
|
|
78
|
-
paramsCasing,
|
|
79
|
-
group
|
|
80
|
-
},
|
|
81
|
-
pre: [
|
|
82
|
-
_kubb_plugin_oas.pluginOasName,
|
|
83
|
-
_kubb_plugin_ts.pluginTsName,
|
|
84
|
-
parser === "zod" ? _kubb_plugin_zod.pluginZodName : void 0
|
|
85
|
-
].filter(Boolean),
|
|
86
|
-
resolvePath(baseName, pathMode, options) {
|
|
87
|
-
const root = node_path.default.resolve(this.config.root, this.config.output.path);
|
|
88
|
-
if ((pathMode ?? (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path))) === "single")
|
|
89
|
-
/**
|
|
90
|
-
* when output is a file then we will always append to the same file(output file), see fileManager.addOrAppend
|
|
91
|
-
* Other plugins then need to call addOrAppend instead of just add from the fileManager class
|
|
92
|
-
*/
|
|
93
|
-
return node_path.default.resolve(root, output.path);
|
|
94
|
-
if (group && (options?.group?.path || options?.group?.tag)) {
|
|
95
|
-
const groupName = group?.name ? group.name : (ctx) => {
|
|
96
|
-
if (group?.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
97
|
-
return `${require_components.camelCase(ctx.group)}Controller`;
|
|
98
|
-
};
|
|
99
|
-
return node_path.default.resolve(root, output.path, groupName({ group: group.type === "path" ? options.group.path : options.group.tag }), baseName);
|
|
100
|
-
}
|
|
101
|
-
return node_path.default.resolve(root, output.path, baseName);
|
|
102
|
-
},
|
|
103
|
-
resolveName(name, type) {
|
|
104
|
-
let resolvedName = require_components.camelCase(name);
|
|
105
|
-
if (type === "file" || type === "function") resolvedName = require_components.camelCase(name, { isFile: type === "file" });
|
|
106
|
-
if (type === "type") resolvedName = require_components.pascalCase(name);
|
|
107
|
-
if (type) return transformers?.name?.(resolvedName, type) || resolvedName;
|
|
108
|
-
return resolvedName;
|
|
109
|
-
},
|
|
110
|
-
async install() {
|
|
111
|
-
const root = node_path.default.resolve(this.config.root, this.config.output.path);
|
|
112
|
-
const mode = (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path));
|
|
113
|
-
const oas = await this.getOas();
|
|
114
|
-
const baseURL = await this.getBaseURL();
|
|
115
|
-
if (baseURL) this.plugin.options.client.baseURL = baseURL;
|
|
116
|
-
const hasClientPlugin = !!this.driver.getPluginByName(_kubb_plugin_client.pluginClientName);
|
|
117
|
-
if (this.plugin.options.client.bundle && !hasClientPlugin && !this.plugin.options.client.importPath) await this.upsertFile({
|
|
118
|
-
baseName: "fetch.ts",
|
|
119
|
-
path: node_path.default.resolve(root, ".kubb/fetch.ts"),
|
|
120
|
-
sources: [{
|
|
121
|
-
name: "fetch",
|
|
122
|
-
value: this.plugin.options.client.client === "fetch" ? _kubb_plugin_client_templates_clients_fetch_source.source : _kubb_plugin_client_templates_clients_axios_source.source,
|
|
123
|
-
isExportable: true,
|
|
124
|
-
isIndexable: true
|
|
125
|
-
}],
|
|
126
|
-
imports: [],
|
|
127
|
-
exports: []
|
|
128
|
-
});
|
|
129
|
-
if (!hasClientPlugin) await this.upsertFile({
|
|
130
|
-
baseName: "config.ts",
|
|
131
|
-
path: node_path.default.resolve(root, ".kubb/config.ts"),
|
|
132
|
-
sources: [{
|
|
133
|
-
name: "config",
|
|
134
|
-
value: _kubb_plugin_client_templates_config_source.source,
|
|
135
|
-
isExportable: false,
|
|
136
|
-
isIndexable: false
|
|
137
|
-
}],
|
|
138
|
-
imports: [],
|
|
139
|
-
exports: []
|
|
140
|
-
});
|
|
141
|
-
const files = await new _kubb_plugin_oas.OperationGenerator(this.plugin.options, {
|
|
142
|
-
fabric: this.fabric,
|
|
143
|
-
oas,
|
|
144
|
-
driver: this.driver,
|
|
145
|
-
events: this.events,
|
|
146
|
-
plugin: this.plugin,
|
|
147
|
-
contentType,
|
|
2297
|
+
options,
|
|
2298
|
+
dependencies: [_kubb_plugin_ts.pluginTsName],
|
|
2299
|
+
hooks: { "kubb:plugin:setup"(ctx) {
|
|
2300
|
+
const resolver = userResolver ? kubb_kit.Resolver.merge(resolverReactQuery, userResolver) : resolverReactQuery;
|
|
2301
|
+
ctx.setOptions({
|
|
2302
|
+
output,
|
|
2303
|
+
client: resolveContractClient({
|
|
2304
|
+
client,
|
|
2305
|
+
plugins: ctx.config.plugins
|
|
2306
|
+
}),
|
|
2307
|
+
queryKey,
|
|
2308
|
+
query: resolveQueryConfig(query, { importPath: "@tanstack/react-query" }),
|
|
2309
|
+
mutationKey,
|
|
2310
|
+
mutation: resolveMutationConfig(mutation, { importPath: "@tanstack/react-query" }),
|
|
2311
|
+
infinite: resolveInfiniteConfig(infinite),
|
|
2312
|
+
suspense,
|
|
2313
|
+
customOptions: customOptions ? {
|
|
2314
|
+
name: "useCustomHookOptions",
|
|
2315
|
+
...customOptions
|
|
2316
|
+
} : null,
|
|
2317
|
+
hooks,
|
|
2318
|
+
group: groupConfig,
|
|
148
2319
|
exclude,
|
|
149
2320
|
include,
|
|
150
2321
|
override,
|
|
151
|
-
|
|
152
|
-
}).build(...generators);
|
|
153
|
-
await this.upsertFile(...files);
|
|
154
|
-
const barrelFiles = await (0, _kubb_core.getBarrelFiles)(this.fabric.files, {
|
|
155
|
-
type: output.barrelType ?? "named",
|
|
156
|
-
root,
|
|
157
|
-
output,
|
|
158
|
-
meta: { pluginName: this.plugin.name }
|
|
2322
|
+
resolver
|
|
159
2323
|
});
|
|
160
|
-
|
|
161
|
-
|
|
2324
|
+
ctx.setResolver(resolver);
|
|
2325
|
+
if (userMacros?.length) ctx.setMacros(userMacros);
|
|
2326
|
+
ctx.addGenerator(...selectedGenerators);
|
|
2327
|
+
} }
|
|
162
2328
|
};
|
|
163
2329
|
});
|
|
164
2330
|
//#endregion
|
|
2331
|
+
exports.default = pluginReactQuery;
|
|
165
2332
|
exports.pluginReactQuery = pluginReactQuery;
|
|
166
2333
|
exports.pluginReactQueryName = pluginReactQueryName;
|
|
2334
|
+
exports.resolverReactQuery = resolverReactQuery;
|
|
167
2335
|
|
|
168
2336
|
//# sourceMappingURL=index.cjs.map
|