@kubb/plugin-react-query 5.0.0-beta.4 → 5.0.0-beta.56

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.
Files changed (49) hide show
  1. package/README.md +38 -91
  2. package/dist/{components-DTGLu4UV.js → components-DL0Cai7l.js} +570 -514
  3. package/dist/components-DL0Cai7l.js.map +1 -0
  4. package/dist/{components-dAKJEn9b.cjs → components-yMQOuFmI.cjs} +600 -514
  5. package/dist/components-yMQOuFmI.cjs.map +1 -0
  6. package/dist/components.cjs +1 -1
  7. package/dist/components.d.ts +5 -77
  8. package/dist/components.js +1 -1
  9. package/dist/{generators-C_fbcjpG.js → generators-BG-Vcvfg.js} +444 -597
  10. package/dist/generators-BG-Vcvfg.js.map +1 -0
  11. package/dist/{generators-CWEQsdO9.cjs → generators-zGKP8yII.cjs} +442 -595
  12. package/dist/generators-zGKP8yII.cjs.map +1 -0
  13. package/dist/generators.cjs +1 -1
  14. package/dist/generators.d.ts +49 -10
  15. package/dist/generators.js +1 -1
  16. package/dist/index.cjs +201 -28
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.ts +32 -4
  19. package/dist/index.js +203 -30
  20. package/dist/index.js.map +1 -1
  21. package/dist/types-X7D0NSvJ.d.ts +396 -0
  22. package/package.json +18 -27
  23. package/src/components/InfiniteQuery.tsx +27 -17
  24. package/src/components/InfiniteQueryOptions.tsx +60 -81
  25. package/src/components/Mutation.tsx +39 -20
  26. package/src/components/MutationOptions.tsx +15 -14
  27. package/src/components/Query.tsx +18 -15
  28. package/src/components/QueryOptions.tsx +20 -56
  29. package/src/components/SuspenseInfiniteQuery.tsx +22 -17
  30. package/src/components/SuspenseInfiniteQueryOptions.tsx +51 -76
  31. package/src/components/SuspenseQuery.tsx +13 -15
  32. package/src/generators/customHookOptionsFileGenerator.tsx +16 -12
  33. package/src/generators/hookOptionsGenerator.tsx +42 -49
  34. package/src/generators/infiniteQueryGenerator.tsx +55 -80
  35. package/src/generators/mutationGenerator.tsx +54 -66
  36. package/src/generators/queryGenerator.tsx +52 -65
  37. package/src/generators/suspenseInfiniteQueryGenerator.tsx +50 -67
  38. package/src/generators/suspenseQueryGenerator.tsx +54 -78
  39. package/src/plugin.ts +47 -33
  40. package/src/resolvers/resolverReactQuery.ts +104 -8
  41. package/src/types.ts +202 -68
  42. package/src/utils.ts +11 -33
  43. package/dist/components-DTGLu4UV.js.map +0 -1
  44. package/dist/components-dAKJEn9b.cjs.map +0 -1
  45. package/dist/generators-CWEQsdO9.cjs.map +0 -1
  46. package/dist/generators-C_fbcjpG.js.map +0 -1
  47. package/dist/types-DfaFRSBf.d.ts +0 -284
  48. package/extension.yaml +0 -938
  49. /package/dist/{chunk--u3MIqq1.js → chunk-C0LytTxp.js} +0 -0
@@ -1,30 +1,36 @@
1
- import "./chunk--u3MIqq1.js";
2
- import { a as Mutation, c as InfiniteQuery, d as transformName, f as QueryKey, i as Query, l as QueryOptions, n as SuspenseInfiniteQueryOptions, o as MutationOptions, p as MutationKey, r as SuspenseInfiniteQuery, s as InfiniteQueryOptions, t as SuspenseQuery, u as resolveOperationOverrides } from "./components-DTGLu4UV.js";
1
+ import "./chunk-C0LytTxp.js";
2
+ import { _ as operationFileEntry, a as Mutation, c as InfiniteQuery, f as resolveOperationOverrides, g as getOperationParameters, i as Query, l as QueryOptions, m as MutationKey, n as SuspenseInfiniteQueryOptions, o as MutationOptions, p as resolveZodSchemaNames, r as SuspenseInfiniteQuery, s as InfiniteQueryOptions, t as SuspenseQuery, u as QueryKey, v as resolveOperationTypeNames } from "./components-DL0Cai7l.js";
3
3
  import path from "node:path";
4
4
  import { ast, defineGenerator } from "@kubb/core";
5
- import { Client, pluginClientName } from "@kubb/plugin-client";
5
+ import { Client, isParserEnabled, pluginClientName } from "@kubb/plugin-client";
6
6
  import { pluginTsName } from "@kubb/plugin-ts";
7
7
  import { pluginZodName } from "@kubb/plugin-zod";
8
8
  import { File, Function, Type, jsxRenderer } from "@kubb/renderer-jsx";
9
9
  import { Fragment, jsx, jsxs } from "@kubb/renderer-jsx/jsx-runtime";
10
10
  import fs from "node:fs";
11
- import { difference } from "remeda";
12
11
  //#region src/generators/customHookOptionsFileGenerator.tsx
12
+ /**
13
+ * Scaffolds the user-editable `useCustomHookOptions` file when
14
+ * `pluginReactQuery({ customOptions: { ... } })` is configured. The file is
15
+ * only created when it does not already exist, so user edits persist across
16
+ * regeneration.
17
+ */
13
18
  const customHookOptionsFileGenerator = defineGenerator({
14
19
  name: "react-query-custom-hook-options-file",
15
20
  renderer: jsxRenderer,
16
21
  operations(nodes, ctx) {
17
22
  const { resolver, config, root } = ctx;
18
- const { output, customOptions, query, group, transformers } = ctx.options;
23
+ const { output, customOptions, query, group } = ctx.options;
19
24
  if (!customOptions) return null;
20
25
  const override = output.override ?? config.output.override ?? false;
21
26
  const { importPath, name } = customOptions;
27
+ const hookOptionsName = resolver.resolveHookOptionsName();
28
+ const customHookOptionsName = resolver.resolveCustomHookOptionsName();
22
29
  const reactQueryImportPath = query ? query.importPath : "@tanstack/react-query";
23
- const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
24
30
  let hookFilePath;
25
31
  const firstNode = nodes[0];
26
32
  if (firstNode) {
27
- const hookName = transformName(`use${capitalize(resolver.resolveName(firstNode.operationId))}`, "function", transformers);
33
+ const hookName = resolver.resolveQueryName(firstNode);
28
34
  hookFilePath = resolver.resolveFile({
29
35
  name: hookName,
30
36
  extname: ".ts",
@@ -33,7 +39,7 @@ const customHookOptionsFileGenerator = defineGenerator({
33
39
  }, {
34
40
  root,
35
41
  output,
36
- group
42
+ group: group ?? void 0
37
43
  }).path;
38
44
  } else hookFilePath = path.resolve(root, "index.ts");
39
45
  const ensureExtension = (filePath, extname) => {
@@ -62,7 +68,7 @@ const customHookOptionsFileGenerator = defineGenerator({
62
68
  path: reactQueryImportPath
63
69
  }),
64
70
  /* @__PURE__ */ jsx(File.Import, {
65
- name: ["HookOptions"],
71
+ name: [hookOptionsName],
66
72
  root: file.path,
67
73
  path: path.resolve(root, "./index.ts")
68
74
  }),
@@ -71,9 +77,9 @@ const customHookOptionsFileGenerator = defineGenerator({
71
77
  isExportable: true,
72
78
  isIndexable: true,
73
79
  children: [/* @__PURE__ */ jsx(Function, {
74
- name: "getCustomHookOptions",
80
+ name: customHookOptionsName,
75
81
  params: "{ queryClient }: { queryClient: QueryClient }",
76
- returnType: "Partial<HookOptions>",
82
+ returnType: `Partial<${hookOptionsName}>`,
77
83
  children: `return {
78
84
  // TODO: Define custom hook options here
79
85
  // Example:
@@ -85,12 +91,12 @@ const customHookOptionsFileGenerator = defineGenerator({
85
91
  }`
86
92
  }), /* @__PURE__ */ jsx(Function, {
87
93
  name,
88
- generics: "T extends keyof HookOptions",
94
+ generics: `T extends keyof ${hookOptionsName}`,
89
95
  params: "{ hookName, operationId }: { hookName: T, operationId: string }",
90
- returnType: "HookOptions[T]",
96
+ returnType: `${hookOptionsName}[T]`,
91
97
  export: true,
92
98
  children: `const queryClient = useQueryClient()
93
- const customOptions = getCustomHookOptions({ queryClient })
99
+ const customOptions = ${customHookOptionsName}({ queryClient })
94
100
  return customOptions[hookName] ?? {}`
95
101
  })]
96
102
  })
@@ -100,52 +106,54 @@ const customHookOptionsFileGenerator = defineGenerator({
100
106
  });
101
107
  //#endregion
102
108
  //#region src/generators/hookOptionsGenerator.tsx
109
+ /**
110
+ * Emits the `HookOptions` type used by `customOptions`. Enabled when
111
+ * `pluginReactQuery({ customOptions: { ... } })`. The generated type lists
112
+ * every hook keyed by name so user-supplied options stay in sync with the
113
+ * generated hooks at compile time.
114
+ */
103
115
  const hookOptionsGenerator = defineGenerator({
104
116
  name: "react-query-hook-options",
105
117
  renderer: jsxRenderer,
106
118
  operations(nodes, ctx) {
107
- const { resolver, config, root, adapter } = ctx;
108
- const { output, customOptions, query, mutation, suspense, infinite, group, transformers, override } = ctx.options;
119
+ const { resolver, config, root } = ctx;
120
+ const { output, customOptions, query, mutation, suspense, infinite, group, override } = ctx.options;
109
121
  if (!customOptions) return null;
122
+ const name = resolver.resolveHookOptionsName();
110
123
  const resolvedFile = resolver.resolveFile({
111
- name: "HookOptions",
124
+ name,
112
125
  extname: ".ts"
113
126
  }, {
114
127
  root,
115
128
  output,
116
- group
129
+ group: group ?? void 0
117
130
  });
118
131
  const hookOptionsFile = {
119
132
  ...resolvedFile,
120
- baseName: "HookOptions.ts",
121
- path: resolvedFile.path.replace(/hookOptions\.ts$/, "HookOptions.ts")
133
+ baseName: `${name}.ts`,
134
+ path: resolvedFile.path.replace(/[^/\\]+\.ts$/, `${name}.ts`)
122
135
  };
123
- const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
124
136
  const imports = [];
125
137
  const hookOptions = {};
126
138
  for (const node of nodes) {
127
- const baseName = resolver.resolveName(node.operationId);
139
+ if (!ast.isHttpOperationNode(node)) continue;
128
140
  const opOverrides = resolveOperationOverrides(node, override);
129
141
  const nodeQuery = "query" in opOverrides ? opOverrides.query : query;
130
142
  const nodeMutation = "mutation" in opOverrides ? opOverrides.mutation : mutation;
131
143
  const nodeInfinite = "infinite" in opOverrides ? opOverrides.infinite : infinite;
132
- const nodeInfiniteOptions = nodeInfinite && typeof nodeInfinite === "object" ? nodeInfinite : void 0;
144
+ const nodeInfiniteOptions = nodeInfinite && typeof nodeInfinite === "object" ? nodeInfinite : null;
133
145
  const isQueryOp = nodeQuery === false ? !!query && query.methods.some((m) => node.method.toLowerCase() === m.toLowerCase()) : !!nodeQuery && nodeQuery.methods.some((m) => node.method.toLowerCase() === m.toLowerCase());
134
- const isMutationOp = nodeMutation !== false && !isQueryOp && difference(nodeMutation ? nodeMutation.methods : [], nodeQuery ? nodeQuery.methods : []).some((m) => node.method.toLowerCase() === m.toLowerCase());
146
+ const nodeQueryMethods = new Set(nodeQuery ? nodeQuery.methods : []);
147
+ const isMutationOp = nodeMutation !== false && !isQueryOp && (nodeMutation ? nodeMutation.methods : []).some((m) => !nodeQueryMethods.has(m) && node.method.toLowerCase() === m.toLowerCase());
135
148
  const isSuspenseOp = !!suspense;
136
149
  const isInfiniteOp = !!nodeInfiniteOptions;
137
150
  if (isQueryOp) {
138
- const queryOptionsName = transformName(`${baseName}QueryOptions`, "function", transformers);
139
- const queryHookName = transformName(`use${capitalize(baseName)}`, "function", transformers);
140
- const queryHookFile = resolver.resolveFile({
141
- name: queryHookName,
142
- extname: ".ts",
143
- tag: node.tags[0] ?? "default",
144
- path: node.path
145
- }, {
151
+ const queryOptionsName = resolver.resolveQueryOptionsName(node);
152
+ const queryHookName = resolver.resolveQueryName(node);
153
+ const queryHookFile = resolver.resolveFile(operationFileEntry(node, queryHookName), {
146
154
  root,
147
155
  output,
148
- group
156
+ group: group ?? void 0
149
157
  });
150
158
  imports.push(/* @__PURE__ */ jsx(File.Import, {
151
159
  name: [queryOptionsName],
@@ -154,17 +162,12 @@ const hookOptionsGenerator = defineGenerator({
154
162
  }));
155
163
  hookOptions[queryHookName] = `Partial<ReturnType<typeof ${queryOptionsName}>>`;
156
164
  if (isSuspenseOp) {
157
- const suspenseOptionsName = transformName(`${baseName}SuspenseQueryOptions`, "function", transformers);
158
- const suspenseHookName = transformName(`use${capitalize(baseName)}Suspense`, "function", transformers);
159
- const suspenseHookFile = resolver.resolveFile({
160
- name: suspenseHookName,
161
- extname: ".ts",
162
- tag: node.tags[0] ?? "default",
163
- path: node.path
164
- }, {
165
+ const suspenseOptionsName = resolver.resolveSuspenseQueryOptionsName(node);
166
+ const suspenseHookName = resolver.resolveSuspenseQueryName(node);
167
+ const suspenseHookFile = resolver.resolveFile(operationFileEntry(node, suspenseHookName), {
165
168
  root,
166
169
  output,
167
- group
170
+ group: group ?? void 0
168
171
  });
169
172
  imports.push(/* @__PURE__ */ jsx(File.Import, {
170
173
  name: [suspenseOptionsName],
@@ -175,19 +178,14 @@ const hookOptionsGenerator = defineGenerator({
175
178
  }
176
179
  if (isInfiniteOp) {
177
180
  const normalizeKey = (key) => key.replace(/\?$/, "");
178
- const queryParamKeys = node.parameters.filter((p) => p.in === "query").map((p) => p.name);
181
+ const queryParamKeys = getOperationParameters(node).query.map((p) => p.name);
179
182
  if (nodeInfiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === nodeInfiniteOptions.queryParam) : false) {
180
- const infiniteOptionsName = transformName(`${baseName}InfiniteQueryOptions`, "function", transformers);
181
- const infiniteHookName = transformName(`use${capitalize(baseName)}Infinite`, "function", transformers);
182
- const infiniteHookFile = resolver.resolveFile({
183
- name: infiniteHookName,
184
- extname: ".ts",
185
- tag: node.tags[0] ?? "default",
186
- path: node.path
187
- }, {
183
+ const infiniteOptionsName = resolver.resolveInfiniteQueryOptionsName(node);
184
+ const infiniteHookName = resolver.resolveInfiniteQueryName(node);
185
+ const infiniteHookFile = resolver.resolveFile(operationFileEntry(node, infiniteHookName), {
188
186
  root,
189
187
  output,
190
- group
188
+ group: group ?? void 0
191
189
  });
192
190
  imports.push(/* @__PURE__ */ jsx(File.Import, {
193
191
  name: [infiniteOptionsName],
@@ -196,17 +194,12 @@ const hookOptionsGenerator = defineGenerator({
196
194
  }));
197
195
  hookOptions[infiniteHookName] = `Partial<ReturnType<typeof ${infiniteOptionsName}>>`;
198
196
  if (isSuspenseOp) {
199
- const suspenseInfiniteOptionsName = transformName(`${baseName}SuspenseInfiniteQueryOptions`, "function", transformers);
200
- const suspenseInfiniteHookName = transformName(`use${capitalize(baseName)}SuspenseInfinite`, "function", transformers);
201
- const suspenseInfiniteHookFile = resolver.resolveFile({
202
- name: suspenseInfiniteHookName,
203
- extname: ".ts",
204
- tag: node.tags[0] ?? "default",
205
- path: node.path
206
- }, {
197
+ const suspenseInfiniteOptionsName = resolver.resolveSuspenseInfiniteQueryOptionsName(node);
198
+ const suspenseInfiniteHookName = resolver.resolveSuspenseInfiniteQueryName(node);
199
+ const suspenseInfiniteHookFile = resolver.resolveFile(operationFileEntry(node, suspenseInfiniteHookName), {
207
200
  root,
208
201
  output,
209
- group
202
+ group: group ?? void 0
210
203
  });
211
204
  imports.push(/* @__PURE__ */ jsx(File.Import, {
212
205
  name: [suspenseInfiniteOptionsName],
@@ -219,17 +212,12 @@ const hookOptionsGenerator = defineGenerator({
219
212
  }
220
213
  }
221
214
  if (isMutationOp) {
222
- const mutationOptionsName = transformName(`${baseName}MutationOptions`, "function", transformers);
223
- const mutationHookName = transformName(`use${capitalize(baseName)}`, "function", transformers);
224
- const mutationHookFile = resolver.resolveFile({
225
- name: mutationHookName,
226
- extname: ".ts",
227
- tag: node.tags[0] ?? "default",
228
- path: node.path
229
- }, {
215
+ const mutationOptionsName = resolver.resolveMutationOptionsName(node);
216
+ const mutationHookName = resolver.resolveMutationName(node);
217
+ const mutationHookFile = resolver.resolveFile(operationFileEntry(node, mutationHookName), {
230
218
  root,
231
219
  output,
232
- group
220
+ group: group ?? void 0
233
221
  });
234
222
  imports.push(/* @__PURE__ */ jsx(File.Import, {
235
223
  name: [mutationOptionsName],
@@ -239,18 +227,25 @@ const hookOptionsGenerator = defineGenerator({
239
227
  hookOptions[mutationHookName] = `Partial<ReturnType<typeof ${mutationOptionsName}>>`;
240
228
  }
241
229
  }
242
- const name = "HookOptions";
243
230
  return /* @__PURE__ */ jsxs(File, {
244
231
  baseName: hookOptionsFile.baseName,
245
232
  path: hookOptionsFile.path,
246
233
  meta: hookOptionsFile.meta,
247
- banner: resolver.resolveBanner(adapter.inputNode, {
234
+ banner: resolver.resolveBanner(ctx.meta, {
248
235
  output,
249
- config
236
+ config,
237
+ file: {
238
+ path: hookOptionsFile.path,
239
+ baseName: hookOptionsFile.baseName
240
+ }
250
241
  }),
251
- footer: resolver.resolveFooter(adapter.inputNode, {
242
+ footer: resolver.resolveFooter(ctx.meta, {
252
243
  output,
253
- config
244
+ config,
245
+ file: {
246
+ path: hookOptionsFile.path,
247
+ baseName: hookOptionsFile.baseName
248
+ }
254
249
  }),
255
250
  children: [imports, /* @__PURE__ */ jsx(File.Source, {
256
251
  name,
@@ -268,153 +263,123 @@ const hookOptionsGenerator = defineGenerator({
268
263
  });
269
264
  //#endregion
270
265
  //#region src/generators/infiniteQueryGenerator.tsx
266
+ /**
267
+ * Built-in generator for `useInfiniteQuery` hooks. Enabled when
268
+ * `pluginReactQuery({ infinite: { ... } })`. Emits one `useFooInfiniteQuery`
269
+ * hook per query operation, wiring the configured `nextParam` /
270
+ * `previousParam` paths into TanStack Query's cursor-based pagination.
271
+ */
271
272
  const infiniteQueryGenerator = defineGenerator({
272
273
  name: "react-infinite-query",
273
274
  renderer: jsxRenderer,
274
275
  operation(node, ctx) {
275
- const { adapter, config, driver, resolver, root } = ctx;
276
- const { output, query, mutation, infinite, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, transformers, customOptions } = ctx.options;
276
+ if (!ast.isHttpOperationNode(node)) return null;
277
+ const { config, driver, resolver, root } = ctx;
278
+ const { output, query, mutation, infinite, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, customOptions } = ctx.options;
277
279
  const pluginTs = driver.getPlugin(pluginTsName);
278
280
  if (!pluginTs) return null;
279
281
  const tsResolver = driver.getResolver(pluginTsName);
280
282
  const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
281
- const isMutation = mutation !== false && !isQuery && difference(mutation ? mutation.methods : [], query ? query.methods : []).some((method) => node.method.toLowerCase() === method.toLowerCase());
282
- const infiniteOptions = infinite && typeof infinite === "object" ? infinite : void 0;
283
+ const queryMethods = new Set(query ? query.methods : []);
284
+ const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
285
+ const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
283
286
  if (!isQuery || isMutation || !infiniteOptions) return null;
284
287
  const normalizeKey = (key) => key.replace(/\?$/, "");
285
- const queryParamKeys = node.parameters.filter((p) => p.in === "query").map((p) => p.name);
288
+ const queryParamKeys = getOperationParameters(node).query.map((p) => p.name);
286
289
  const hasQueryParam = infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false;
287
290
  const hasCursorParam = !infiniteOptions.cursorParam || true;
288
291
  if (!hasQueryParam || !hasCursorParam) return null;
289
292
  const importPath = query ? query.importPath : "@tanstack/react-query";
290
- const baseName = resolver.resolveName(node.operationId);
291
- const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
292
- const queryName = transformName(`use${capitalize(baseName)}Infinite`, "function", transformers);
293
- const queryOptionsName = transformName(`${baseName}InfiniteQueryOptions`, "function", transformers);
294
- const queryKeyName = transformName(`${baseName}InfiniteQueryKey`, "const", transformers);
295
- const queryKeyTypeName = transformName(`${capitalize(baseName)}InfiniteQueryKey`, "type", transformers);
296
- const clientBaseName = transformName(`${baseName}Infinite`, "function", transformers);
293
+ const queryName = resolver.resolveInfiniteQueryName(node);
294
+ const queryOptionsName = resolver.resolveInfiniteQueryOptionsName(node);
295
+ const queryKeyName = resolver.resolveInfiniteQueryKeyName(node);
296
+ const queryKeyTypeName = resolver.resolveInfiniteQueryKeyTypeName(node);
297
+ const clientBaseName = resolver.resolveInfiniteClientName(node);
297
298
  const meta = {
298
- file: resolver.resolveFile({
299
- name: queryName,
300
- extname: ".ts",
301
- tag: node.tags[0] ?? "default",
302
- path: node.path
303
- }, {
299
+ file: resolver.resolveFile(operationFileEntry(node, queryName), {
304
300
  root,
305
301
  output,
306
- group
302
+ group: group ?? void 0
307
303
  }),
308
- fileTs: tsResolver.resolveFile({
309
- name: node.operationId,
310
- extname: ".ts",
311
- tag: node.tags[0] ?? "default",
312
- path: node.path
313
- }, {
304
+ fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
314
305
  root,
315
306
  output: pluginTs.options?.output ?? output,
316
- group: pluginTs.options?.group
307
+ group: pluginTs.options?.group ?? void 0
317
308
  })
318
309
  };
319
- const casedParams = ast.caseParams(node.parameters, paramsCasing);
320
- const pathParams = casedParams.filter((p) => p.in === "path");
321
- const queryParams = casedParams.filter((p) => p.in === "query");
322
- const headerParams = casedParams.filter((p) => p.in === "header");
323
- const importedTypeNames = [
324
- node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : void 0,
325
- tsResolver.resolveResponseName(node),
326
- ...pathParams.map((p) => tsResolver.resolvePathParamsName(node, p)),
327
- ...queryParams.map((p) => tsResolver.resolveQueryParamsName(node, p)),
328
- ...headerParams.map((p) => tsResolver.resolveHeaderParamsName(node, p)),
329
- ...node.responses.map((res) => tsResolver.resolveResponseStatusName(node, res.statusCode))
330
- ].filter((name) => !!name && name !== queryKeyTypeName);
331
- const pluginZod = parser === "zod" ? driver.getPlugin(pluginZodName) : void 0;
332
- const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : void 0;
333
- const fileZod = zodResolver ? zodResolver.resolveFile({
334
- name: node.operationId,
335
- extname: ".ts",
336
- tag: node.tags[0] ?? "default",
337
- path: node.path
338
- }, {
310
+ const importedTypeNames = resolveOperationTypeNames(node, tsResolver, {
311
+ paramsCasing,
312
+ exclude: [queryKeyTypeName],
313
+ order: "body-response-first"
314
+ });
315
+ const pluginZod = isParserEnabled(parser) ? driver.getPlugin(pluginZodName) : null;
316
+ const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
317
+ const fileZod = zodResolver ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
339
318
  root,
340
319
  output: pluginZod?.options?.output ?? output,
341
- group: pluginZod?.options?.group
342
- }) : void 0;
343
- const zodSchemaNames = zodResolver && parser === "zod" ? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : void 0].filter(Boolean) : [];
320
+ group: pluginZod?.options?.group ?? void 0
321
+ }) : null;
322
+ const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, parser);
344
323
  const clientPlugin = driver.getPlugin(pluginClientName);
345
324
  const shouldUseClientPlugin = clientPlugin?.name === pluginClientName && clientOptions.clientType !== "class";
346
- const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : void 0;
347
- const clientFile = shouldUseClientPlugin ? clientResolver?.resolveFile({
348
- name: node.operationId,
349
- extname: ".ts",
350
- tag: node.tags[0] ?? "default",
351
- path: node.path
352
- }, {
325
+ const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : null;
326
+ const clientFile = shouldUseClientPlugin ? clientResolver?.resolveFile(operationFileEntry(node, node.operationId), {
353
327
  root,
354
328
  output: clientPlugin?.options?.output ?? output,
355
- group: clientPlugin?.options?.group
356
- }) : void 0;
329
+ group: clientPlugin?.options?.group ?? void 0
330
+ }) : null;
357
331
  const resolvedClientName = shouldUseClientPlugin ? clientResolver?.resolveName(node.operationId) ?? clientBaseName : clientBaseName;
358
332
  return /* @__PURE__ */ jsxs(File, {
359
333
  baseName: meta.file.baseName,
360
334
  path: meta.file.path,
361
335
  meta: meta.file.meta,
362
- banner: resolver.resolveBanner(adapter.inputNode, {
336
+ banner: resolver.resolveBanner(ctx.meta, {
363
337
  output,
364
- config
338
+ config,
339
+ file: {
340
+ path: meta.file.path,
341
+ baseName: meta.file.baseName
342
+ }
365
343
  }),
366
- footer: resolver.resolveFooter(adapter.inputNode, {
344
+ footer: resolver.resolveFooter(ctx.meta, {
367
345
  output,
368
- config
346
+ config,
347
+ file: {
348
+ path: meta.file.path,
349
+ baseName: meta.file.baseName
350
+ }
369
351
  }),
370
352
  children: [
371
- parser === "zod" && fileZod && zodSchemaNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
353
+ fileZod && zodSchemaNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
372
354
  name: zodSchemaNames,
373
355
  root: meta.file.path,
374
356
  path: fileZod.path
375
357
  }),
376
- clientOptions.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [
377
- !shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
378
- name: "fetch",
379
- path: clientOptions.importPath
380
- }),
381
- /* @__PURE__ */ jsx(File.Import, {
382
- name: [
383
- "Client",
384
- "RequestConfig",
385
- "ResponseErrorConfig"
386
- ],
387
- path: clientOptions.importPath,
388
- isTypeOnly: true
389
- }),
390
- clientOptions.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
391
- name: ["ResponseConfig"],
392
- path: clientOptions.importPath,
393
- isTypeOnly: true
394
- })
395
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
396
- !shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
397
- name: ["fetch"],
398
- root: meta.file.path,
399
- path: path.resolve(root, ".kubb/fetch.ts")
400
- }),
401
- /* @__PURE__ */ jsx(File.Import, {
402
- name: [
403
- "Client",
404
- "RequestConfig",
405
- "ResponseErrorConfig"
406
- ],
407
- root: meta.file.path,
408
- path: path.resolve(root, ".kubb/fetch.ts"),
409
- isTypeOnly: true
410
- }),
411
- clientOptions.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
412
- name: ["ResponseConfig"],
413
- root: meta.file.path,
414
- path: path.resolve(root, ".kubb/fetch.ts"),
415
- isTypeOnly: true
416
- })
417
- ] }),
358
+ clientOptions.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
359
+ name: "client",
360
+ path: clientOptions.importPath
361
+ }), /* @__PURE__ */ jsx(File.Import, {
362
+ name: [
363
+ "Client",
364
+ "RequestConfig",
365
+ "ResponseErrorConfig"
366
+ ],
367
+ path: clientOptions.importPath,
368
+ isTypeOnly: true
369
+ })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
370
+ name: ["client"],
371
+ root: meta.file.path,
372
+ path: path.resolve(root, ".kubb/client.ts")
373
+ }), /* @__PURE__ */ jsx(File.Import, {
374
+ name: [
375
+ "Client",
376
+ "RequestConfig",
377
+ "ResponseErrorConfig"
378
+ ],
379
+ root: meta.file.path,
380
+ path: path.resolve(root, ".kubb/client.ts"),
381
+ isTypeOnly: true
382
+ })] }),
418
383
  shouldUseClientPlugin && clientFile && /* @__PURE__ */ jsx(File.Import, {
419
384
  name: [resolvedClientName],
420
385
  root: meta.file.path,
@@ -516,156 +481,129 @@ const infiniteQueryGenerator = defineGenerator({
516
481
  });
517
482
  //#endregion
518
483
  //#region src/generators/mutationGenerator.tsx
484
+ /**
485
+ * Built-in generator for `useMutation` hooks. Emits one `useFooMutation` hook
486
+ * per POST/PUT/DELETE operation (configurable via `mutation.methods`) plus
487
+ * the matching `fooMutationKey` / `fooMutationOptions` helpers.
488
+ */
519
489
  const mutationGenerator = defineGenerator({
520
490
  name: "react-query-mutation",
521
491
  renderer: jsxRenderer,
522
492
  operation(node, ctx) {
523
- const { adapter, config, driver, resolver, root } = ctx;
524
- const { output, query, mutation, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, transformers, customOptions } = ctx.options;
493
+ if (!ast.isHttpOperationNode(node)) return null;
494
+ const { config, driver, resolver, root } = ctx;
495
+ const { output, query, mutation, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, customOptions } = ctx.options;
525
496
  const pluginTs = driver.getPlugin(pluginTsName);
526
497
  if (!pluginTs) return null;
527
498
  const tsResolver = driver.getResolver(pluginTsName);
528
499
  const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
529
- if (!(mutation !== false && !isQuery && difference(mutation ? mutation.methods : [], query ? query.methods : []).some((method) => node.method.toLowerCase() === method.toLowerCase()))) return null;
500
+ const queryMethods = new Set(query ? query.methods : []);
501
+ if (!(mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase()))) return null;
530
502
  const importPath = mutation ? mutation.importPath : "@tanstack/react-query";
531
- const baseName = resolver.resolveName(node.operationId);
532
- const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
533
- const mutationHookName = transformName(`use${capitalize(baseName)}`, "function", transformers);
534
- const mutationTypeName = transformName(`${capitalize(baseName)}`, "type", transformers);
535
- const mutationOptionsName = transformName(`${baseName}MutationOptions`, "function", transformers);
536
- const mutationKeyName = transformName(`${baseName}MutationKey`, "const", transformers);
537
- const clientName = transformName(baseName, "function", transformers);
503
+ const mutationHookName = resolver.resolveMutationName(node);
504
+ const mutationTypeName = resolver.resolveMutationTypeName(node);
505
+ const mutationOptionsName = resolver.resolveMutationOptionsName(node);
506
+ const mutationKeyName = resolver.resolveMutationKeyName(node);
507
+ const clientName = resolver.resolveClientName(node);
538
508
  const meta = {
539
- file: resolver.resolveFile({
540
- name: mutationHookName,
541
- extname: ".ts",
542
- tag: node.tags[0] ?? "default",
543
- path: node.path
544
- }, {
509
+ file: resolver.resolveFile(operationFileEntry(node, mutationHookName), {
545
510
  root,
546
511
  output,
547
- group
512
+ group: group ?? void 0
548
513
  }),
549
- fileTs: tsResolver.resolveFile({
550
- name: node.operationId,
551
- extname: ".ts",
552
- tag: node.tags[0] ?? "default",
553
- path: node.path
554
- }, {
514
+ fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
555
515
  root,
556
516
  output: pluginTs.options?.output ?? output,
557
- group: pluginTs.options?.group
517
+ group: pluginTs.options?.group ?? void 0
558
518
  })
559
519
  };
560
- const casedParams = ast.caseParams(node.parameters, paramsCasing);
561
- const pathParams = casedParams.filter((p) => p.in === "path");
562
- const queryParams = casedParams.filter((p) => p.in === "query");
563
- const headerParams = casedParams.filter((p) => p.in === "header");
564
- const importedTypeNames = [
565
- node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : void 0,
566
- tsResolver.resolveResponseName(node),
567
- ...pathParams.map((p) => tsResolver.resolvePathParamsName(node, p)),
568
- ...queryParams.map((p) => tsResolver.resolveQueryParamsName(node, p)),
569
- ...headerParams.map((p) => tsResolver.resolveHeaderParamsName(node, p)),
570
- ...node.responses.map((res) => tsResolver.resolveResponseStatusName(node, res.statusCode))
571
- ].filter((name) => !!name);
572
- const pluginZod = parser === "zod" ? driver.getPlugin(pluginZodName) : void 0;
573
- const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : void 0;
574
- const fileZod = zodResolver ? zodResolver.resolveFile({
575
- name: node.operationId,
576
- extname: ".ts",
577
- tag: node.tags[0] ?? "default",
578
- path: node.path
579
- }, {
520
+ const importedTypeNames = resolveOperationTypeNames(node, tsResolver, {
521
+ paramsCasing,
522
+ order: "body-response-first"
523
+ });
524
+ const pluginZod = isParserEnabled(parser) ? driver.getPlugin(pluginZodName) : null;
525
+ const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
526
+ const fileZod = zodResolver ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
580
527
  root,
581
528
  output: pluginZod?.options?.output ?? output,
582
- group: pluginZod?.options?.group
583
- }) : void 0;
584
- const zodSchemaNames = zodResolver && parser === "zod" ? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : void 0].filter(Boolean) : [];
529
+ group: pluginZod?.options?.group ?? void 0
530
+ }) : null;
531
+ const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, parser);
585
532
  const clientPlugin = driver.getPlugin(pluginClientName);
586
533
  const shouldUseClientPlugin = clientPlugin?.name === pluginClientName && clientOptions.clientType !== "class";
587
- const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : void 0;
588
- const clientFile = shouldUseClientPlugin ? clientResolver?.resolveFile({
589
- name: node.operationId,
590
- extname: ".ts",
591
- tag: node.tags[0] ?? "default",
592
- path: node.path
593
- }, {
534
+ const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : null;
535
+ const clientFile = shouldUseClientPlugin ? clientResolver?.resolveFile(operationFileEntry(node, node.operationId), {
594
536
  root,
595
537
  output: clientPlugin?.options?.output ?? output,
596
- group: clientPlugin?.options?.group
597
- }) : void 0;
538
+ group: clientPlugin?.options?.group ?? void 0
539
+ }) : null;
598
540
  const resolvedClientName = shouldUseClientPlugin ? clientResolver?.resolveName(node.operationId) ?? clientName : clientName;
599
541
  return /* @__PURE__ */ jsxs(File, {
600
542
  baseName: meta.file.baseName,
601
543
  path: meta.file.path,
602
544
  meta: meta.file.meta,
603
- banner: resolver.resolveBanner(adapter.inputNode, {
545
+ banner: resolver.resolveBanner(ctx.meta, {
604
546
  output,
605
- config
547
+ config,
548
+ file: {
549
+ path: meta.file.path,
550
+ baseName: meta.file.baseName
551
+ }
606
552
  }),
607
- footer: resolver.resolveFooter(adapter.inputNode, {
553
+ footer: resolver.resolveFooter(ctx.meta, {
608
554
  output,
609
- config
555
+ config,
556
+ file: {
557
+ path: meta.file.path,
558
+ baseName: meta.file.baseName
559
+ }
610
560
  }),
611
561
  children: [
612
- parser === "zod" && fileZod && zodSchemaNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
562
+ fileZod && zodSchemaNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
613
563
  name: zodSchemaNames,
614
564
  root: meta.file.path,
615
565
  path: fileZod.path
616
566
  }),
617
- clientOptions.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [
618
- !shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
619
- name: "fetch",
620
- path: clientOptions.importPath
621
- }),
622
- /* @__PURE__ */ jsx(File.Import, {
623
- name: [
624
- "Client",
625
- "RequestConfig",
626
- "ResponseErrorConfig"
627
- ],
628
- path: clientOptions.importPath,
629
- isTypeOnly: true
630
- }),
631
- clientOptions.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
632
- name: ["ResponseConfig"],
633
- path: clientOptions.importPath,
634
- isTypeOnly: true
635
- })
636
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
637
- !shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
638
- name: ["fetch"],
639
- root: meta.file.path,
640
- path: path.resolve(root, ".kubb/fetch.ts")
641
- }),
642
- /* @__PURE__ */ jsx(File.Import, {
643
- name: [
644
- "Client",
645
- "RequestConfig",
646
- "ResponseErrorConfig"
647
- ],
648
- root: meta.file.path,
649
- path: path.resolve(root, ".kubb/fetch.ts"),
650
- isTypeOnly: true
651
- }),
652
- clientOptions.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
653
- name: ["ResponseConfig"],
654
- root: meta.file.path,
655
- path: path.resolve(root, ".kubb/fetch.ts"),
656
- isTypeOnly: true
657
- })
658
- ] }),
567
+ clientOptions.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
568
+ name: "client",
569
+ path: clientOptions.importPath
570
+ }), /* @__PURE__ */ jsx(File.Import, {
571
+ name: [
572
+ "Client",
573
+ "RequestConfig",
574
+ "ResponseErrorConfig"
575
+ ],
576
+ path: clientOptions.importPath,
577
+ isTypeOnly: true
578
+ })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
579
+ name: ["client"],
580
+ root: meta.file.path,
581
+ path: path.resolve(root, ".kubb/client.ts")
582
+ }), /* @__PURE__ */ jsx(File.Import, {
583
+ name: [
584
+ "Client",
585
+ "RequestConfig",
586
+ "ResponseErrorConfig"
587
+ ],
588
+ root: meta.file.path,
589
+ path: path.resolve(root, ".kubb/client.ts"),
590
+ isTypeOnly: true
591
+ })] }),
659
592
  shouldUseClientPlugin && clientFile && /* @__PURE__ */ jsx(File.Import, {
660
593
  name: [resolvedClientName],
661
594
  root: meta.file.path,
662
595
  path: clientFile.path
663
596
  }),
664
- !shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
597
+ !shouldUseClientPlugin && node.requestBody?.content?.some((e) => e.contentType === "multipart/form-data") && /* @__PURE__ */ jsx(File.Import, {
665
598
  name: ["buildFormData"],
666
599
  root: meta.file.path,
667
600
  path: path.resolve(root, ".kubb/config.ts")
668
601
  }),
602
+ !shouldUseClientPlugin && parser === "zod" && zodResolver && node.requestBody?.content?.[0]?.schema && /* @__PURE__ */ jsx(File.Import, {
603
+ name: ["z"],
604
+ path: "zod",
605
+ isTypeOnly: true
606
+ }),
669
607
  customOptions && /* @__PURE__ */ jsx(File.Import, {
670
608
  name: [customOptions.name],
671
609
  path: customOptions.importPath
@@ -743,147 +681,116 @@ const mutationGenerator = defineGenerator({
743
681
  });
744
682
  //#endregion
745
683
  //#region src/generators/queryGenerator.tsx
684
+ /**
685
+ * Built-in generator for `useQuery` hooks. Emits one `useFooQuery` hook per
686
+ * GET operation (configurable via `query.methods`) plus the matching
687
+ * `fooQueryKey` / `fooQueryOptions` helpers.
688
+ */
746
689
  const queryGenerator = defineGenerator({
747
690
  name: "react-query",
748
691
  renderer: jsxRenderer,
749
692
  operation(node, ctx) {
750
- const { adapter, config, driver, resolver, root } = ctx;
751
- const { output, query, mutation, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, transformers, customOptions } = ctx.options;
693
+ if (!ast.isHttpOperationNode(node)) return null;
694
+ const { config, driver, resolver, root } = ctx;
695
+ const { output, query, mutation, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, customOptions } = ctx.options;
752
696
  const pluginTs = driver.getPlugin(pluginTsName);
753
697
  if (!pluginTs) return null;
754
698
  const tsResolver = driver.getResolver(pluginTsName);
755
699
  const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
756
- const isMutation = mutation !== false && !isQuery && difference(mutation ? mutation.methods : [], query ? query.methods : []).some((method) => node.method.toLowerCase() === method.toLowerCase());
700
+ const queryMethods = new Set(query ? query.methods : []);
701
+ const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
757
702
  if (!isQuery || isMutation) return null;
758
703
  const importPath = query ? query.importPath : "@tanstack/react-query";
759
- const baseName = resolver.resolveName(node.operationId);
760
- const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
761
- const queryName = transformName(`use${capitalize(baseName)}`, "function", transformers);
762
- const queryOptionsName = transformName(`${baseName}QueryOptions`, "function", transformers);
763
- const queryKeyName = transformName(`${baseName}QueryKey`, "const", transformers);
764
- const queryKeyTypeName = transformName(`${capitalize(baseName)}QueryKey`, "type", transformers);
765
- const clientName = transformName(baseName, "function", transformers);
704
+ const queryName = resolver.resolveQueryName(node);
705
+ const queryOptionsName = resolver.resolveQueryOptionsName(node);
706
+ const queryKeyName = resolver.resolveQueryKeyName(node);
707
+ const queryKeyTypeName = resolver.resolveQueryKeyTypeName(node);
708
+ const clientName = resolver.resolveClientName(node);
766
709
  const meta = {
767
- file: resolver.resolveFile({
768
- name: queryName,
769
- extname: ".ts",
770
- tag: node.tags[0] ?? "default",
771
- path: node.path
772
- }, {
710
+ file: resolver.resolveFile(operationFileEntry(node, queryName), {
773
711
  root,
774
712
  output,
775
- group
713
+ group: group ?? void 0
776
714
  }),
777
- fileTs: tsResolver.resolveFile({
778
- name: node.operationId,
779
- extname: ".ts",
780
- tag: node.tags[0] ?? "default",
781
- path: node.path
782
- }, {
715
+ fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
783
716
  root,
784
717
  output: pluginTs.options?.output ?? output,
785
- group: pluginTs.options?.group
718
+ group: pluginTs.options?.group ?? void 0
786
719
  })
787
720
  };
788
- const casedParams = ast.caseParams(node.parameters, paramsCasing);
789
- const pathParams = casedParams.filter((p) => p.in === "path");
790
- const queryParams = casedParams.filter((p) => p.in === "query");
791
- const headerParams = casedParams.filter((p) => p.in === "header");
792
- const importedTypeNames = [
793
- node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : void 0,
794
- tsResolver.resolveResponseName(node),
795
- ...pathParams.map((p) => tsResolver.resolvePathParamsName(node, p)),
796
- ...queryParams.map((p) => tsResolver.resolveQueryParamsName(node, p)),
797
- ...headerParams.map((p) => tsResolver.resolveHeaderParamsName(node, p)),
798
- ...node.responses.map((res) => tsResolver.resolveResponseStatusName(node, res.statusCode))
799
- ].filter((name) => !!name && name !== queryKeyTypeName);
800
- const pluginZod = parser === "zod" ? driver.getPlugin(pluginZodName) : void 0;
801
- const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : void 0;
802
- const fileZod = zodResolver ? zodResolver.resolveFile({
803
- name: node.operationId,
804
- extname: ".ts",
805
- tag: node.tags[0] ?? "default",
806
- path: node.path
807
- }, {
721
+ const importedTypeNames = resolveOperationTypeNames(node, tsResolver, {
722
+ paramsCasing,
723
+ exclude: [queryKeyTypeName],
724
+ order: "body-response-first"
725
+ });
726
+ const pluginZod = isParserEnabled(parser) ? driver.getPlugin(pluginZodName) : null;
727
+ const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
728
+ const fileZod = zodResolver ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
808
729
  root,
809
730
  output: pluginZod?.options?.output ?? output,
810
- group: pluginZod?.options?.group
811
- }) : void 0;
812
- const zodSchemaNames = zodResolver && parser === "zod" ? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : void 0].filter(Boolean) : [];
731
+ group: pluginZod?.options?.group ?? void 0
732
+ }) : null;
733
+ const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, parser);
813
734
  const clientPlugin = driver.getPlugin(pluginClientName);
814
735
  const shouldUseClientPlugin = clientPlugin?.name === pluginClientName && clientOptions.clientType !== "class";
815
- const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : void 0;
816
- const clientFile = shouldUseClientPlugin ? clientResolver?.resolveFile({
817
- name: node.operationId,
818
- extname: ".ts",
819
- tag: node.tags[0] ?? "default",
820
- path: node.path
821
- }, {
736
+ const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : null;
737
+ const clientFile = shouldUseClientPlugin ? clientResolver?.resolveFile(operationFileEntry(node, node.operationId), {
822
738
  root,
823
739
  output: clientPlugin?.options?.output ?? output,
824
- group: clientPlugin?.options?.group
825
- }) : void 0;
740
+ group: clientPlugin?.options?.group ?? void 0
741
+ }) : null;
826
742
  const resolvedClientName = shouldUseClientPlugin ? clientResolver?.resolveName(node.operationId) ?? clientName : clientName;
827
743
  return /* @__PURE__ */ jsxs(File, {
828
744
  baseName: meta.file.baseName,
829
745
  path: meta.file.path,
830
746
  meta: meta.file.meta,
831
- banner: resolver.resolveBanner(adapter.inputNode, {
747
+ banner: resolver.resolveBanner(ctx.meta, {
832
748
  output,
833
- config
749
+ config,
750
+ file: {
751
+ path: meta.file.path,
752
+ baseName: meta.file.baseName
753
+ }
834
754
  }),
835
- footer: resolver.resolveFooter(adapter.inputNode, {
755
+ footer: resolver.resolveFooter(ctx.meta, {
836
756
  output,
837
- config
757
+ config,
758
+ file: {
759
+ path: meta.file.path,
760
+ baseName: meta.file.baseName
761
+ }
838
762
  }),
839
763
  children: [
840
- parser === "zod" && fileZod && zodSchemaNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
764
+ fileZod && zodSchemaNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
841
765
  name: zodSchemaNames,
842
766
  root: meta.file.path,
843
767
  path: fileZod.path
844
768
  }),
845
- clientOptions.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [
846
- !shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
847
- name: "fetch",
848
- path: clientOptions.importPath
849
- }),
850
- /* @__PURE__ */ jsx(File.Import, {
851
- name: [
852
- "Client",
853
- "RequestConfig",
854
- "ResponseErrorConfig"
855
- ],
856
- path: clientOptions.importPath,
857
- isTypeOnly: true
858
- }),
859
- clientOptions.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
860
- name: ["ResponseConfig"],
861
- path: clientOptions.importPath,
862
- isTypeOnly: true
863
- })
864
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
865
- !shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
866
- name: ["fetch"],
867
- root: meta.file.path,
868
- path: path.resolve(root, ".kubb/fetch.ts")
869
- }),
870
- /* @__PURE__ */ jsx(File.Import, {
871
- name: [
872
- "Client",
873
- "RequestConfig",
874
- "ResponseErrorConfig"
875
- ],
876
- root: meta.file.path,
877
- path: path.resolve(root, ".kubb/fetch.ts"),
878
- isTypeOnly: true
879
- }),
880
- clientOptions.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
881
- name: ["ResponseConfig"],
882
- root: meta.file.path,
883
- path: path.resolve(root, ".kubb/fetch.ts"),
884
- isTypeOnly: true
885
- })
886
- ] }),
769
+ clientOptions.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
770
+ name: "client",
771
+ path: clientOptions.importPath
772
+ }), /* @__PURE__ */ jsx(File.Import, {
773
+ name: [
774
+ "Client",
775
+ "RequestConfig",
776
+ "ResponseErrorConfig"
777
+ ],
778
+ path: clientOptions.importPath,
779
+ isTypeOnly: true
780
+ })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
781
+ name: ["client"],
782
+ root: meta.file.path,
783
+ path: path.resolve(root, ".kubb/client.ts")
784
+ }), /* @__PURE__ */ jsx(File.Import, {
785
+ name: [
786
+ "Client",
787
+ "RequestConfig",
788
+ "ResponseErrorConfig"
789
+ ],
790
+ root: meta.file.path,
791
+ path: path.resolve(root, ".kubb/client.ts"),
792
+ isTypeOnly: true
793
+ })] }),
887
794
  shouldUseClientPlugin && clientFile && /* @__PURE__ */ jsx(File.Import, {
888
795
  name: [resolvedClientName],
889
796
  root: meta.file.path,
@@ -975,154 +882,123 @@ const queryGenerator = defineGenerator({
975
882
  });
976
883
  //#endregion
977
884
  //#region src/generators/suspenseInfiniteQueryGenerator.tsx
885
+ /**
886
+ * Built-in generator for `useSuspenseInfiniteQuery` hooks. Enabled when both
887
+ * `suspense` and `infinite` are configured. Combines suspense semantics with
888
+ * cursor-based pagination — handlers throw promises while loading and pull
889
+ * additional pages on demand.
890
+ */
978
891
  const suspenseInfiniteQueryGenerator = defineGenerator({
979
892
  name: "react-suspense-infinite-query",
980
893
  renderer: jsxRenderer,
981
894
  operation(node, ctx) {
982
- const { adapter, config, driver, resolver, root } = ctx;
983
- const { output, query, mutation, infinite, suspense, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, transformers, customOptions } = ctx.options;
895
+ if (!ast.isHttpOperationNode(node)) return null;
896
+ const { config, driver, resolver, root } = ctx;
897
+ const { output, query, mutation, infinite, suspense, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, customOptions } = ctx.options;
984
898
  const pluginTs = driver.getPlugin(pluginTsName);
985
899
  if (!pluginTs) return null;
986
900
  const tsResolver = driver.getResolver(pluginTsName);
987
901
  const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
988
- const isMutation = mutation !== false && !isQuery && difference(mutation ? mutation.methods : [], query ? query.methods : []).some((method) => node.method.toLowerCase() === method.toLowerCase());
902
+ const queryMethods = new Set(query ? query.methods : []);
903
+ const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
989
904
  const isSuspense = !!suspense;
990
- const infiniteOptions = infinite && typeof infinite === "object" ? infinite : void 0;
905
+ const infiniteOptions = infinite && typeof infinite === "object" ? infinite : null;
991
906
  if (!isQuery || isMutation || !isSuspense || !infiniteOptions) return null;
992
907
  const normalizeKey = (key) => key.replace(/\?$/, "");
993
- const queryParamKeys = node.parameters.filter((p) => p.in === "query").map((p) => p.name);
908
+ const queryParamKeys = getOperationParameters(node).query.map((p) => p.name);
994
909
  const hasQueryParam = infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false;
995
910
  const hasCursorParam = !infiniteOptions.cursorParam || true;
996
911
  if (!hasQueryParam || !hasCursorParam) return null;
997
912
  const importPath = query ? query.importPath : "@tanstack/react-query";
998
- const baseName = resolver.resolveName(node.operationId);
999
- const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
1000
- const queryName = transformName(`use${capitalize(baseName)}SuspenseInfinite`, "function", transformers);
1001
- const queryOptionsName = transformName(`${baseName}SuspenseInfiniteQueryOptions`, "function", transformers);
1002
- const queryKeyName = transformName(`${baseName}SuspenseInfiniteQueryKey`, "const", transformers);
1003
- const queryKeyTypeName = transformName(`${capitalize(baseName)}SuspenseInfiniteQueryKey`, "type", transformers);
1004
- const clientBaseName = transformName(`${baseName}SuspenseInfinite`, "function", transformers);
913
+ const queryName = resolver.resolveSuspenseInfiniteQueryName(node);
914
+ const queryOptionsName = resolver.resolveSuspenseInfiniteQueryOptionsName(node);
915
+ const queryKeyName = resolver.resolveSuspenseInfiniteQueryKeyName(node);
916
+ const queryKeyTypeName = resolver.resolveSuspenseInfiniteQueryKeyTypeName(node);
917
+ const clientBaseName = resolver.resolveSuspenseInfiniteClientName(node);
1005
918
  const meta = {
1006
- file: resolver.resolveFile({
1007
- name: queryName,
1008
- extname: ".ts",
1009
- tag: node.tags[0] ?? "default",
1010
- path: node.path
1011
- }, {
919
+ file: resolver.resolveFile(operationFileEntry(node, queryName), {
1012
920
  root,
1013
921
  output,
1014
- group
922
+ group: group ?? void 0
1015
923
  }),
1016
- fileTs: tsResolver.resolveFile({
1017
- name: node.operationId,
1018
- extname: ".ts",
1019
- tag: node.tags[0] ?? "default",
1020
- path: node.path
1021
- }, {
924
+ fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
1022
925
  root,
1023
926
  output: pluginTs.options?.output ?? output,
1024
- group: pluginTs.options?.group
927
+ group: pluginTs.options?.group ?? void 0
1025
928
  })
1026
929
  };
1027
- const casedParams = ast.caseParams(node.parameters, paramsCasing);
1028
- const pathParams = casedParams.filter((p) => p.in === "path");
1029
- const queryParams = casedParams.filter((p) => p.in === "query");
1030
- const headerParams = casedParams.filter((p) => p.in === "header");
1031
- const importedTypeNames = [
1032
- node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : void 0,
1033
- tsResolver.resolveResponseName(node),
1034
- ...pathParams.map((p) => tsResolver.resolvePathParamsName(node, p)),
1035
- ...queryParams.map((p) => tsResolver.resolveQueryParamsName(node, p)),
1036
- ...headerParams.map((p) => tsResolver.resolveHeaderParamsName(node, p)),
1037
- ...node.responses.map((res) => tsResolver.resolveResponseStatusName(node, res.statusCode))
1038
- ].filter(Boolean);
1039
- const pluginZod = parser === "zod" ? driver.getPlugin(pluginZodName) : void 0;
1040
- const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : void 0;
1041
- const fileZod = zodResolver ? zodResolver.resolveFile({
1042
- name: node.operationId,
1043
- extname: ".ts",
1044
- tag: node.tags[0] ?? "default",
1045
- path: node.path
1046
- }, {
930
+ const importedTypeNames = resolveOperationTypeNames(node, tsResolver, {
931
+ paramsCasing,
932
+ order: "body-response-first"
933
+ });
934
+ const pluginZod = isParserEnabled(parser) ? driver.getPlugin(pluginZodName) : null;
935
+ const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
936
+ const fileZod = zodResolver ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
1047
937
  root,
1048
938
  output: pluginZod?.options?.output ?? output,
1049
- group: pluginZod?.options?.group
1050
- }) : void 0;
1051
- const zodSchemaNames = zodResolver && parser === "zod" ? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : void 0].filter(Boolean) : [];
939
+ group: pluginZod?.options?.group ?? void 0
940
+ }) : null;
941
+ const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, parser);
1052
942
  const clientPlugin = driver.getPlugin(pluginClientName);
1053
943
  const shouldUseClientPlugin = clientPlugin?.name === pluginClientName && clientOptions.clientType !== "class";
1054
- const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : void 0;
1055
- const clientFile = shouldUseClientPlugin ? clientResolver?.resolveFile({
1056
- name: node.operationId,
1057
- extname: ".ts",
1058
- tag: node.tags[0] ?? "default",
1059
- path: node.path
1060
- }, {
944
+ const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : null;
945
+ const clientFile = shouldUseClientPlugin ? clientResolver?.resolveFile(operationFileEntry(node, node.operationId), {
1061
946
  root,
1062
947
  output: clientPlugin?.options?.output ?? output,
1063
- group: clientPlugin?.options?.group
1064
- }) : void 0;
948
+ group: clientPlugin?.options?.group ?? void 0
949
+ }) : null;
1065
950
  const resolvedClientName = shouldUseClientPlugin ? clientResolver?.resolveName(node.operationId) ?? clientBaseName : clientBaseName;
1066
951
  return /* @__PURE__ */ jsxs(File, {
1067
952
  baseName: meta.file.baseName,
1068
953
  path: meta.file.path,
1069
954
  meta: meta.file.meta,
1070
- banner: resolver.resolveBanner(adapter.inputNode, {
955
+ banner: resolver.resolveBanner(ctx.meta, {
1071
956
  output,
1072
- config
957
+ config,
958
+ file: {
959
+ path: meta.file.path,
960
+ baseName: meta.file.baseName
961
+ }
1073
962
  }),
1074
- footer: resolver.resolveFooter(adapter.inputNode, {
963
+ footer: resolver.resolveFooter(ctx.meta, {
1075
964
  output,
1076
- config
965
+ config,
966
+ file: {
967
+ path: meta.file.path,
968
+ baseName: meta.file.baseName
969
+ }
1077
970
  }),
1078
971
  children: [
1079
- parser === "zod" && fileZod && zodSchemaNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
972
+ fileZod && zodSchemaNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
1080
973
  name: zodSchemaNames,
1081
974
  root: meta.file.path,
1082
975
  path: fileZod.path
1083
976
  }),
1084
- clientOptions.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [
1085
- !shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
1086
- name: "fetch",
1087
- path: clientOptions.importPath
1088
- }),
1089
- /* @__PURE__ */ jsx(File.Import, {
1090
- name: [
1091
- "Client",
1092
- "RequestConfig",
1093
- "ResponseErrorConfig"
1094
- ],
1095
- path: clientOptions.importPath,
1096
- isTypeOnly: true
1097
- }),
1098
- clientOptions.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
1099
- name: ["ResponseConfig"],
1100
- path: clientOptions.importPath,
1101
- isTypeOnly: true
1102
- })
1103
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1104
- !shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
1105
- name: ["fetch"],
1106
- root: meta.file.path,
1107
- path: path.resolve(root, ".kubb/fetch.ts")
1108
- }),
1109
- /* @__PURE__ */ jsx(File.Import, {
1110
- name: [
1111
- "Client",
1112
- "RequestConfig",
1113
- "ResponseErrorConfig"
1114
- ],
1115
- root: meta.file.path,
1116
- path: path.resolve(root, ".kubb/fetch.ts"),
1117
- isTypeOnly: true
1118
- }),
1119
- clientOptions.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
1120
- name: ["ResponseConfig"],
1121
- root: meta.file.path,
1122
- path: path.resolve(root, ".kubb/fetch.ts"),
1123
- isTypeOnly: true
1124
- })
1125
- ] }),
977
+ clientOptions.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
978
+ name: "client",
979
+ path: clientOptions.importPath
980
+ }), /* @__PURE__ */ jsx(File.Import, {
981
+ name: [
982
+ "Client",
983
+ "RequestConfig",
984
+ "ResponseErrorConfig"
985
+ ],
986
+ path: clientOptions.importPath,
987
+ isTypeOnly: true
988
+ })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
989
+ name: ["client"],
990
+ root: meta.file.path,
991
+ path: path.resolve(root, ".kubb/client.ts")
992
+ }), /* @__PURE__ */ jsx(File.Import, {
993
+ name: [
994
+ "Client",
995
+ "RequestConfig",
996
+ "ResponseErrorConfig"
997
+ ],
998
+ root: meta.file.path,
999
+ path: path.resolve(root, ".kubb/client.ts"),
1000
+ isTypeOnly: true
1001
+ })] }),
1126
1002
  shouldUseClientPlugin && clientFile && /* @__PURE__ */ jsx(File.Import, {
1127
1003
  name: [resolvedClientName],
1128
1004
  root: meta.file.path,
@@ -1224,147 +1100,117 @@ const suspenseInfiniteQueryGenerator = defineGenerator({
1224
1100
  });
1225
1101
  //#endregion
1226
1102
  //#region src/generators/suspenseQueryGenerator.tsx
1103
+ /**
1104
+ * Built-in generator for `useSuspenseQuery` hooks. Enabled when
1105
+ * `pluginReactQuery({ suspense: {} })`. Emits one `useFooSuspenseQuery` hook
1106
+ * per query operation. Suspense queries throw promises while loading and
1107
+ * require a `<Suspense>` boundary in the React tree. TanStack Query v5+ only.
1108
+ */
1227
1109
  const suspenseQueryGenerator = defineGenerator({
1228
1110
  name: "react-suspense-query",
1229
1111
  renderer: jsxRenderer,
1230
1112
  operation(node, ctx) {
1231
- const { adapter, config, driver, resolver, root } = ctx;
1232
- const { output, query, mutation, suspense, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, transformers, customOptions } = ctx.options;
1113
+ if (!ast.isHttpOperationNode(node)) return null;
1114
+ const { config, driver, resolver, root } = ctx;
1115
+ const { output, query, mutation, suspense, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, customOptions } = ctx.options;
1233
1116
  const pluginTs = driver.getPlugin(pluginTsName);
1234
1117
  if (!pluginTs) return null;
1235
1118
  const tsResolver = driver.getResolver(pluginTsName);
1236
1119
  const isQuery = query === false || !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
1237
- const isMutation = mutation !== false && !isQuery && difference(mutation ? mutation.methods : [], query ? query.methods : []).some((method) => node.method.toLowerCase() === method.toLowerCase());
1120
+ const queryMethods = new Set(query ? query.methods : []);
1121
+ const isMutation = mutation !== false && !isQuery && (mutation ? mutation.methods : []).some((method) => !queryMethods.has(method) && node.method.toLowerCase() === method.toLowerCase());
1238
1122
  if (!isQuery || isMutation || !!!suspense) return null;
1239
1123
  const importPath = query ? query.importPath : "@tanstack/react-query";
1240
- const baseName = resolver.resolveName(node.operationId);
1241
- const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
1242
- const queryName = transformName(`use${capitalize(baseName)}Suspense`, "function", transformers);
1243
- const queryOptionsName = transformName(`${baseName}SuspenseQueryOptions`, "function", transformers);
1244
- const queryKeyName = transformName(`${baseName}SuspenseQueryKey`, "const", transformers);
1245
- const queryKeyTypeName = transformName(`${capitalize(baseName)}SuspenseQueryKey`, "type", transformers);
1246
- const clientName = transformName(`${baseName}Suspense`, "function", transformers);
1124
+ const queryName = resolver.resolveSuspenseQueryName(node);
1125
+ const queryOptionsName = resolver.resolveSuspenseQueryOptionsName(node);
1126
+ const queryKeyName = resolver.resolveSuspenseQueryKeyName(node);
1127
+ const queryKeyTypeName = resolver.resolveSuspenseQueryKeyTypeName(node);
1128
+ const clientName = resolver.resolveSuspenseClientName(node);
1247
1129
  const meta = {
1248
- file: resolver.resolveFile({
1249
- name: queryName,
1250
- extname: ".ts",
1251
- tag: node.tags[0] ?? "default",
1252
- path: node.path
1253
- }, {
1130
+ file: resolver.resolveFile(operationFileEntry(node, queryName), {
1254
1131
  root,
1255
1132
  output,
1256
- group
1133
+ group: group ?? void 0
1257
1134
  }),
1258
- fileTs: tsResolver.resolveFile({
1259
- name: node.operationId,
1260
- extname: ".ts",
1261
- tag: node.tags[0] ?? "default",
1262
- path: node.path
1263
- }, {
1135
+ fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
1264
1136
  root,
1265
1137
  output: pluginTs.options?.output ?? output,
1266
- group: pluginTs.options?.group
1138
+ group: pluginTs.options?.group ?? void 0
1267
1139
  })
1268
1140
  };
1269
- const casedParams = ast.caseParams(node.parameters, paramsCasing);
1270
- const pathParams = casedParams.filter((p) => p.in === "path");
1271
- const queryParams = casedParams.filter((p) => p.in === "query");
1272
- const headerParams = casedParams.filter((p) => p.in === "header");
1273
- const importedTypeNames = [
1274
- node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : void 0,
1275
- tsResolver.resolveResponseName(node),
1276
- ...pathParams.map((p) => tsResolver.resolvePathParamsName(node, p)),
1277
- ...queryParams.map((p) => tsResolver.resolveQueryParamsName(node, p)),
1278
- ...headerParams.map((p) => tsResolver.resolveHeaderParamsName(node, p)),
1279
- ...node.responses.map((res) => tsResolver.resolveResponseStatusName(node, res.statusCode))
1280
- ].filter((name) => !!name && name !== queryKeyTypeName);
1281
- const pluginZod = parser === "zod" ? driver.getPlugin(pluginZodName) : void 0;
1282
- const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : void 0;
1283
- const fileZod = zodResolver ? zodResolver.resolveFile({
1284
- name: node.operationId,
1285
- extname: ".ts",
1286
- tag: node.tags[0] ?? "default",
1287
- path: node.path
1288
- }, {
1141
+ const importedTypeNames = resolveOperationTypeNames(node, tsResolver, {
1142
+ paramsCasing,
1143
+ exclude: [queryKeyTypeName],
1144
+ order: "body-response-first"
1145
+ });
1146
+ const pluginZod = isParserEnabled(parser) ? driver.getPlugin(pluginZodName) : null;
1147
+ const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
1148
+ const fileZod = zodResolver ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
1289
1149
  root,
1290
1150
  output: pluginZod?.options?.output ?? output,
1291
- group: pluginZod?.options?.group
1292
- }) : void 0;
1293
- const zodSchemaNames = zodResolver && parser === "zod" ? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : void 0].filter(Boolean) : [];
1151
+ group: pluginZod?.options?.group ?? void 0
1152
+ }) : null;
1153
+ const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, parser);
1294
1154
  const clientPlugin = driver.getPlugin(pluginClientName);
1295
1155
  const shouldUseClientPlugin = clientPlugin?.name === pluginClientName && clientOptions.clientType !== "class";
1296
- const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : void 0;
1297
- const clientFile = shouldUseClientPlugin ? clientResolver?.resolveFile({
1298
- name: node.operationId,
1299
- extname: ".ts",
1300
- tag: node.tags[0] ?? "default",
1301
- path: node.path
1302
- }, {
1156
+ const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : null;
1157
+ const clientFile = shouldUseClientPlugin ? clientResolver?.resolveFile(operationFileEntry(node, node.operationId), {
1303
1158
  root,
1304
1159
  output: clientPlugin?.options?.output ?? output,
1305
- group: clientPlugin?.options?.group
1306
- }) : void 0;
1160
+ group: clientPlugin?.options?.group ?? void 0
1161
+ }) : null;
1307
1162
  const resolvedClientName = shouldUseClientPlugin ? clientResolver?.resolveName(node.operationId) ?? clientName : clientName;
1308
1163
  return /* @__PURE__ */ jsxs(File, {
1309
1164
  baseName: meta.file.baseName,
1310
1165
  path: meta.file.path,
1311
1166
  meta: meta.file.meta,
1312
- banner: resolver.resolveBanner(adapter.inputNode, {
1167
+ banner: resolver.resolveBanner(ctx.meta, {
1313
1168
  output,
1314
- config
1169
+ config,
1170
+ file: {
1171
+ path: meta.file.path,
1172
+ baseName: meta.file.baseName
1173
+ }
1315
1174
  }),
1316
- footer: resolver.resolveFooter(adapter.inputNode, {
1175
+ footer: resolver.resolveFooter(ctx.meta, {
1317
1176
  output,
1318
- config
1177
+ config,
1178
+ file: {
1179
+ path: meta.file.path,
1180
+ baseName: meta.file.baseName
1181
+ }
1319
1182
  }),
1320
1183
  children: [
1321
- parser === "zod" && fileZod && zodSchemaNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
1184
+ fileZod && zodSchemaNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
1322
1185
  name: zodSchemaNames,
1323
1186
  root: meta.file.path,
1324
1187
  path: fileZod.path
1325
1188
  }),
1326
- clientOptions.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [
1327
- !shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
1328
- name: "fetch",
1329
- path: clientOptions.importPath
1330
- }),
1331
- /* @__PURE__ */ jsx(File.Import, {
1332
- name: [
1333
- "Client",
1334
- "RequestConfig",
1335
- "ResponseErrorConfig"
1336
- ],
1337
- path: clientOptions.importPath,
1338
- isTypeOnly: true
1339
- }),
1340
- clientOptions.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
1341
- name: ["ResponseConfig"],
1342
- path: clientOptions.importPath,
1343
- isTypeOnly: true
1344
- })
1345
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1346
- !shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
1347
- name: ["fetch"],
1348
- root: meta.file.path,
1349
- path: path.resolve(root, ".kubb/fetch.ts")
1350
- }),
1351
- /* @__PURE__ */ jsx(File.Import, {
1352
- name: [
1353
- "Client",
1354
- "RequestConfig",
1355
- "ResponseErrorConfig"
1356
- ],
1357
- root: meta.file.path,
1358
- path: path.resolve(root, ".kubb/fetch.ts"),
1359
- isTypeOnly: true
1360
- }),
1361
- clientOptions.dataReturnType === "full" && /* @__PURE__ */ jsx(File.Import, {
1362
- name: ["ResponseConfig"],
1363
- root: meta.file.path,
1364
- path: path.resolve(root, ".kubb/fetch.ts"),
1365
- isTypeOnly: true
1366
- })
1367
- ] }),
1189
+ clientOptions.importPath ? /* @__PURE__ */ jsxs(Fragment, { children: [!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
1190
+ name: "client",
1191
+ path: clientOptions.importPath
1192
+ }), /* @__PURE__ */ jsx(File.Import, {
1193
+ name: [
1194
+ "Client",
1195
+ "RequestConfig",
1196
+ "ResponseErrorConfig"
1197
+ ],
1198
+ path: clientOptions.importPath,
1199
+ isTypeOnly: true
1200
+ })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [!shouldUseClientPlugin && /* @__PURE__ */ jsx(File.Import, {
1201
+ name: ["client"],
1202
+ root: meta.file.path,
1203
+ path: path.resolve(root, ".kubb/client.ts")
1204
+ }), /* @__PURE__ */ jsx(File.Import, {
1205
+ name: [
1206
+ "Client",
1207
+ "RequestConfig",
1208
+ "ResponseErrorConfig"
1209
+ ],
1210
+ root: meta.file.path,
1211
+ path: path.resolve(root, ".kubb/client.ts"),
1212
+ isTypeOnly: true
1213
+ })] }),
1368
1214
  shouldUseClientPlugin && clientFile && /* @__PURE__ */ jsx(File.Import, {
1369
1215
  name: [resolvedClientName],
1370
1216
  root: meta.file.path,
@@ -1419,7 +1265,8 @@ const suspenseQueryGenerator = defineGenerator({
1419
1265
  paramsCasing,
1420
1266
  paramsType,
1421
1267
  pathParamsType,
1422
- dataReturnType: clientOptions.dataReturnType || "data"
1268
+ dataReturnType: clientOptions.dataReturnType || "data",
1269
+ suspense: true
1423
1270
  }),
1424
1271
  suspense && /* @__PURE__ */ jsxs(Fragment, { children: [
1425
1272
  /* @__PURE__ */ jsx(File.Import, {
@@ -1457,4 +1304,4 @@ const suspenseQueryGenerator = defineGenerator({
1457
1304
  //#endregion
1458
1305
  export { infiniteQueryGenerator as a, mutationGenerator as i, suspenseInfiniteQueryGenerator as n, hookOptionsGenerator as o, queryGenerator as r, customHookOptionsFileGenerator as s, suspenseQueryGenerator as t };
1459
1306
 
1460
- //# sourceMappingURL=generators-C_fbcjpG.js.map
1307
+ //# sourceMappingURL=generators-BG-Vcvfg.js.map