@kubb/plugin-react-query 5.7.0-canary.20261025T201031 → 5.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- //#region \0rolldown/runtime.js
5
+ // \0rolldown/runtime.js
6
6
  var __create = Object.create;
7
7
  var __defProp = Object.defineProperty;
8
8
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -23,7 +23,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  value: mod,
24
24
  enumerable: true
25
25
  }) : target, mod));
26
- //#endregion
27
26
  let kubb_kit = require("kubb/kit");
28
27
  let node_path = require("node:path");
29
28
  node_path = __toESM(node_path, 1);
@@ -33,7 +32,7 @@ let _kubb_plugin_ts = require("@kubb/plugin-ts");
33
32
  let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
34
33
  let node_fs = require("node:fs");
35
34
  node_fs = __toESM(node_fs, 1);
36
- //#region ../../internals/shared/src/operation.ts
35
+ // ../../internals/shared/src/operation.ts
37
36
  /**
38
37
  * Builds the `ResolverFileParams` every operation generator passes to
39
38
  * `resolver.file`: a file named `name`, tagged by the operation's first
@@ -102,6 +101,24 @@ function getContentTypeInfo(node) {
102
101
  function getResponseContentTypeInfo(node) {
103
102
  return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? []);
104
103
  }
104
+ /**
105
+ * Reads the single base content type of an operation's primary success response, lowercased and
106
+ * stripped of any `; charset=...` suffix. Returns `undefined` when the response declares zero or
107
+ * more than one content type, since neither case has a single type to act on.
108
+ */
109
+ function getPrimarySuccessContentType(node) {
110
+ const contentTypes = getPrimarySuccessResponse(node)?.content?.map((entry) => entry.contentType) ?? [];
111
+ if (contentTypes.length !== 1) return void 0;
112
+ return contentTypes[0].split(";")[0].trim().toLowerCase();
113
+ }
114
+ /**
115
+ * Whether an operation streams its primary success response as Server-Sent Events
116
+ * (`text/event-stream`). The client generator uses this to return a typed event stream instead of a
117
+ * one-shot `RequestResult`.
118
+ */
119
+ function isEventStream(node) {
120
+ return getPrimarySuccessContentType(node) === "text/event-stream";
121
+ }
105
122
  const requestConfigBaseType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
106
123
  function buildRequestConfigType(node) {
107
124
  const request = getContentTypeInfo(node);
@@ -193,6 +210,22 @@ function getOperationParameters(node) {
193
210
  operationParameterGroupsByNode.set(node, groups);
194
211
  return groups;
195
212
  }
213
+ /**
214
+ * Builds the combined `{ body, path, query, headers }` options object schema for an operation,
215
+ * referencing the already-resolved body and grouped param names. Shared by `@kubb/plugin-ts`'s
216
+ * `Options` type and `@kubb/plugin-zod`'s inferred options schema, so both printers emit the same
217
+ * shape from the same inputs. `primitive: 'object'` is a no-op for the TS printer and tells the Zod
218
+ * printer to emit `z.object(…)` rather than a record.
219
+ */
220
+ function hasRequestContentTypeChoice(node) {
221
+ return (node.requestBody?.content ?? []).filter((entry) => entry.schema).length > 1;
222
+ }
223
+ /**
224
+ * Casts a call argument to the client's parameter type; a `'plain'` client is non-generic.
225
+ */
226
+ function castToClientOptions(callArg, clientName, returnType = "full") {
227
+ return `${callArg} as Parameters<typeof ${clientName}${returnType === "plain" ? "" : "<true>"}>[0]`;
228
+ }
196
229
  function getStatusCodeNumber(statusCode) {
197
230
  const code = Number(statusCode);
198
231
  return Number.isNaN(code) ? null : code;
@@ -223,88 +256,184 @@ function resolveSuccessNames(node, resolver) {
223
256
  function resolveStatusCodeNames(node, resolver) {
224
257
  return node.responses.map((response) => resolver.response.status(node, response.statusCode));
225
258
  }
226
- const typeNamesByResolver = /* @__PURE__ */ new WeakMap();
259
+ /**
260
+ * Lists the type names an operation's types file declares, computed once per resolver and `options` so every
261
+ * dependent reads the same list.
262
+ */
227
263
  function resolveOperationTypeNames(node, resolver, options = {}) {
228
- const cacheKey = `${node.operationId}\0${options.order ?? ""}\0${options.responseStatusNames ?? ""}\0${options.includeParams === false ? "noparams" : ""}\0${(options.exclude ?? []).join(",")}`;
229
- let byResolver = typeNamesByResolver.get(resolver);
230
- if (byResolver) {
231
- const cached = byResolver.get(cacheKey);
232
- if (cached) return cached;
233
- } else {
234
- byResolver = /* @__PURE__ */ new Map();
235
- typeNamesByResolver.set(resolver, byResolver);
236
- }
237
- const { path, query, header } = getOperationParameters(node);
238
- const responseStatusNames = options.responseStatusNames === "error" ? resolveErrorNames(node, resolver) : options.responseStatusNames === false ? [] : resolveStatusCodeNames(node, resolver);
239
- const exclude = new Set(options.exclude ?? []);
240
- const paramNames = options.includeParams === false ? [] : [
241
- ...path.map((param) => resolver.param.path(node, param)),
242
- ...query.map((param) => resolver.param.query(node, param)),
243
- ...header.map((param) => resolver.param.headers(node, param))
244
- ];
245
- const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.response.body(node) : null, resolver.response.response(node)];
246
- const result = (options.order === "body-response-first" ? [
247
- ...bodyAndResponseNames,
248
- ...paramNames,
249
- ...responseStatusNames
250
- ] : [
251
- ...paramNames,
252
- ...bodyAndResponseNames,
253
- ...responseStatusNames
254
- ]).filter((name) => Boolean(name) && !exclude.has(name));
255
- byResolver.set(cacheKey, result);
256
- return result;
264
+ const key = `${node.operationId}\0${options.order ?? ""}\0${options.responseStatusNames ?? ""}\0${options.includeParams === false ? "noparams" : ""}\0${(options.exclude ?? []).join(",")}`;
265
+ return resolver.memo(`operationTypeNames:${key}`, () => {
266
+ const { path, query, header } = getOperationParameters(node);
267
+ const responseStatusNames = options.responseStatusNames === "error" ? resolveErrorNames(node, resolver) : options.responseStatusNames === false ? [] : resolveStatusCodeNames(node, resolver);
268
+ const exclude = new Set(options.exclude ?? []);
269
+ const paramNames = options.includeParams === false ? [] : [
270
+ ...path.map((param) => resolver.param.path(node, param)),
271
+ ...query.map((param) => resolver.param.query(node, param)),
272
+ ...header.map((param) => resolver.param.headers(node, param))
273
+ ];
274
+ const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.response.body(node) : null, resolver.response.response(node)];
275
+ return (options.order === "body-response-first" ? [
276
+ ...bodyAndResponseNames,
277
+ ...paramNames,
278
+ ...responseStatusNames
279
+ ] : [
280
+ ...paramNames,
281
+ ...bodyAndResponseNames,
282
+ ...responseStatusNames
283
+ ]).filter((name) => Boolean(name) && !exclude.has(name));
284
+ });
257
285
  }
258
- //#endregion
259
- //#region ../../internals/utils/src/casing.ts
286
+ // ../../internals/utils/src/casing.ts
260
287
  /**
261
- * Shared implementation for camelCase and PascalCase conversion.
262
- * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
263
- * and capitalizes each word according to `pascal`.
288
+ * Uppercases only the first character of `text`, leaving the rest untouched.
289
+ * Unlike `pascalCase` it never re-splits word boundaries or strips characters.
264
290
  *
265
- * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
266
- */
267
- function convert(text, pascal) {
268
- 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) => {
269
- if (word.length > 1 && word === word.toUpperCase()) return word;
270
- return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
271
- }).join("").replace(/[^a-zA-Z0-9]/g, "");
272
- }
273
- const cache = /* @__PURE__ */ new Map();
274
- const cacheLimit = 1e4;
275
- function toCamelOrPascal(text, pascal) {
276
- const key = `${pascal ? "P" : "c"}${text}`;
277
- const cached = cache.get(key);
278
- if (cached !== void 0) return cached;
279
- const result = convert(text, pascal);
280
- if (cache.size >= cacheLimit) cache.clear();
281
- cache.set(key, result);
282
- return result;
291
+ * @example
292
+ * `capitalize('getPetById') // 'GetPetById'`
293
+ */
294
+ function capitalize(text) {
295
+ return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
283
296
  }
297
+ // ../../internals/utils/src/reserved.ts
284
298
  /**
285
- * Converts `text` to camelCase.
299
+ * JavaScript and Java reserved words.
300
+ * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
301
+ */
302
+ const reservedWords = /* @__PURE__ */ new Set([
303
+ "abstract",
304
+ "arguments",
305
+ "await",
306
+ "boolean",
307
+ "break",
308
+ "byte",
309
+ "case",
310
+ "catch",
311
+ "char",
312
+ "class",
313
+ "const",
314
+ "continue",
315
+ "debugger",
316
+ "default",
317
+ "delete",
318
+ "do",
319
+ "double",
320
+ "else",
321
+ "enum",
322
+ "eval",
323
+ "export",
324
+ "extends",
325
+ "false",
326
+ "final",
327
+ "finally",
328
+ "float",
329
+ "for",
330
+ "function",
331
+ "goto",
332
+ "if",
333
+ "implements",
334
+ "import",
335
+ "in",
336
+ "instanceof",
337
+ "int",
338
+ "interface",
339
+ "let",
340
+ "long",
341
+ "native",
342
+ "new",
343
+ "null",
344
+ "package",
345
+ "private",
346
+ "protected",
347
+ "public",
348
+ "return",
349
+ "short",
350
+ "static",
351
+ "super",
352
+ "switch",
353
+ "synchronized",
354
+ "this",
355
+ "throw",
356
+ "throws",
357
+ "transient",
358
+ "true",
359
+ "try",
360
+ "typeof",
361
+ "var",
362
+ "void",
363
+ "volatile",
364
+ "while",
365
+ "with",
366
+ "yield",
367
+ "Array",
368
+ "Date",
369
+ "hasOwnProperty",
370
+ "Infinity",
371
+ "isFinite",
372
+ "isNaN",
373
+ "isPrototypeOf",
374
+ "length",
375
+ "Math",
376
+ "name",
377
+ "NaN",
378
+ "Number",
379
+ "Object",
380
+ "prototype",
381
+ "String",
382
+ "toString",
383
+ "undefined",
384
+ "valueOf"
385
+ ]);
386
+ /**
387
+ * Returns `true` when `name` is a syntactically valid JavaScript variable name.
286
388
  *
287
- * @example Word boundaries
288
- * `camelCase('hello-world') // 'helloWorld'`
389
+ * @example
390
+ * ```ts
391
+ * isValidVarName('status') // true
392
+ * isValidVarName('class') // false (reserved word)
393
+ * isValidVarName('42foo') // false (starts with digit)
394
+ * ```
395
+ */
396
+ function isValidVarName(name) {
397
+ if (!name || reservedWords.has(name)) return false;
398
+ return isIdentifier(name);
399
+ }
400
+ /**
401
+ * Returns `name` when it's a syntactically valid JavaScript variable name,
402
+ * otherwise prefixes it with `_` so the result is a valid identifier.
289
403
  *
290
- * @example With a prefix
291
- * `camelCase('tag', { prefix: 'create' }) // 'createTag'`
404
+ * Useful for sanitizing OpenAPI schema names or operation IDs that start with
405
+ * a digit (e.g. `409`, `504AccountCancel`) before using them as exported
406
+ * variable, type, or function names.
407
+ *
408
+ * @example
409
+ * ```ts
410
+ * ensureValidVarName('409') // '_409'
411
+ * ensureValidVarName('504AccountCancel') // '_504AccountCancel'
412
+ * ensureValidVarName('Pet') // 'Pet'
413
+ * ensureValidVarName('class') // '_class'
414
+ * ```
292
415
  */
293
- function camelCase(text, { prefix = "", suffix = "" } = {}) {
294
- return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
416
+ function ensureValidVarName(name) {
417
+ if (!name || isValidVarName(name)) return name;
418
+ return `_${name}`;
295
419
  }
296
420
  /**
297
- * Uppercases only the first character of `text`, leaving the rest untouched.
298
- * Unlike {@link pascalCase} it never re-splits word boundaries or strips characters.
421
+ * Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
422
+ *
423
+ * Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
424
+ * even though they are not valid variable names, so use this (not {@link isValidVarName}) when
425
+ * deciding whether an object key needs quoting.
299
426
  *
300
427
  * @example
301
- * `capitalize('getPetById') // 'GetPetById'`
428
+ * ```ts
429
+ * isIdentifier('name') // true
430
+ * isIdentifier('x-total')// false
431
+ * ```
302
432
  */
303
- function capitalize(text) {
304
- return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
433
+ function isIdentifier(name) {
434
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
305
435
  }
306
- //#endregion
307
- //#region ../../internals/utils/src/strings.ts
436
+ // ../../internals/utils/src/strings.ts
308
437
  /**
309
438
  * Renders a dotted path or string array as an optional-chaining accessor expression rooted at
310
439
  * `accessor`. Returns `null` for an empty path.
@@ -320,8 +449,32 @@ function getNestedAccessor(param, accessor) {
320
449
  if (parts.length === 0 || parts.length === 1 && parts[0] === "") return null;
321
450
  return `${accessor}?.['${`${parts.join("']?.['")}']`}`;
322
451
  }
323
- //#endregion
324
- //#region ../../internals/shared/src/group.ts
452
+ // ../../internals/shared/src/resolver.ts
453
+ /**
454
+ * The shared top-level `name` of the operation plugins, computed once per operation name and build.
455
+ */
456
+ function resolveOperationName(name) {
457
+ return this.memo(`operation:${name}`, () => ensureValidVarName((0, kubb_kit.camelCase)(name)));
458
+ }
459
+ /**
460
+ * Builds the allocation key for a declaration an operation owns. `scope` names which declaration
461
+ * it is, so two of them never share an allocation even when a custom resolver gives both the same
462
+ * name. Leave `scope` empty for the operation's own declaration.
463
+ *
464
+ * @example
465
+ * ```ts
466
+ * resolver.resolveName({ key: operationKey(node, 'response', 'status', 404), name })
467
+ * ```
468
+ */
469
+ function operationKey(node, ...scope) {
470
+ return [
471
+ "operation",
472
+ node.method,
473
+ node.path,
474
+ ...scope.map(String)
475
+ ];
476
+ }
477
+ // ../../internals/shared/src/group.ts
325
478
  /**
326
479
  * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
327
480
  * shared default naming so every plugin groups output consistently:
@@ -344,24 +497,21 @@ function createGroupConfig(group) {
344
497
  if (!group) return null;
345
498
  const defaultName = (ctx) => {
346
499
  if (group.type === "path") return `${ctx.group.split("/")[1]}`;
347
- return camelCase(ctx.group);
500
+ return (0, kubb_kit.camelCase)(ctx.group);
348
501
  };
349
502
  return {
350
503
  ...group,
351
504
  name: group.name ? group.name : defaultName
352
505
  };
353
506
  }
354
- //#endregion
355
- //#region kubb-extension.json
507
+ // kubb-extension.json
356
508
  var compatibility = {
357
- "kubb": ">=5.8.3",
509
+ "kubb": ">=5.14.6",
358
510
  "node": ">=22.22"
359
511
  };
360
- //#endregion
361
- //#region package.json
362
- var version = "5.7.0-canary.20261025T201031";
363
- //#endregion
364
- //#region ../../internals/client/src/resolveOperationTypes.ts
512
+ // package.json
513
+ var version = "5.7.1";
514
+ // ../../internals/client/src/resolveOperationTypes.ts
365
515
  /**
366
516
  * A `plugin-ts` shaped resolver whose operation type names point at the types `pluginZod({ inferred })`
367
517
  * exports next to each schema, so code written against `plugin-ts` names picks up the zod types.
@@ -371,6 +521,7 @@ function toZodTypeResolver(resolver) {
371
521
  return {
372
522
  ...resolver,
373
523
  file: resolver.file.bind(resolver),
524
+ memo: (key, compute) => resolver.memo(`zodTypes:${key}`, compute),
374
525
  param: {
375
526
  name: (node, p) => type(resolver.param.name(node, p)),
376
527
  path: (node, p) => type(resolver.param.path(node, p)),
@@ -427,8 +578,7 @@ function resolveOperationTypes(driver, pluginName) {
427
578
  group: pluginZod.options.group ?? void 0
428
579
  };
429
580
  }
430
- //#endregion
431
- //#region ../../internals/client/src/resolveClient.ts
581
+ // ../../internals/client/src/resolveClient.ts
432
582
  /**
433
583
  * Resolves which client plugin a consumer (react-query, vue-query, swr, mcp) should call for an
434
584
  * operation, shared so the selection rules and diagnostics stay in one place.
@@ -538,8 +688,7 @@ function resolveContractClient(options) {
538
688
  }
539
689
  return resolved;
540
690
  }
541
- //#endregion
542
- //#region ../../internals/client/src/resolveClientOperation.ts
691
+ // ../../internals/client/src/resolveClientOperation.ts
543
692
  function isRelativeImport(importPath) {
544
693
  return importPath.startsWith(".");
545
694
  }
@@ -586,8 +735,12 @@ function resolveClientOperation(options) {
586
735
  group: operationOptions.group ?? void 0
587
736
  });
588
737
  const { importPath } = operationOptions;
738
+ const name = resolver.name(node.operationId);
589
739
  return {
590
- name: resolver.name(node.operationId),
740
+ name: resolver.resolveName({
741
+ key: operationKey(node),
742
+ name
743
+ }),
591
744
  path: file.path,
592
745
  clientPath: importPath === void 0 ? node_path.default.resolve(root, ".kubb/client.ts") : resolveImportPath({
593
746
  importPath,
@@ -598,8 +751,7 @@ function resolveClientOperation(options) {
598
751
  };
599
752
  });
600
753
  }
601
- //#endregion
602
- //#region ../../internals/tanstack-query/src/components/HookFile.tsx
754
+ // ../../internals/tanstack-query/src/components/HookFile.tsx
603
755
  /**
604
756
  * Resolves what every TanStack hook file shares: its file, the operation types file and names (`@kubb/plugin-ts`, or
605
757
  * `pluginZod({ inferred: 'codec' })`), banner and footer.
@@ -688,8 +840,7 @@ function HookFile({ hook, imports, children }) {
688
840
  ]
689
841
  });
690
842
  }
691
- //#endregion
692
- //#region ../../internals/tanstack-query/src/utils.ts
843
+ // ../../internals/tanstack-query/src/utils.ts
693
844
  /**
694
845
  * The grouped request options, ordered for both the destructured signature and the
695
846
  * call passed to the underlying client.
@@ -715,7 +866,7 @@ function maybeValueOrGetter(type) {
715
866
  * `MaybeRefOrGetter` per group.
716
867
  */
717
868
  function buildGroupedRequestParam(node, options) {
718
- const { resolver, keys = requestGroupOrder, memberTypeWrapper } = options;
869
+ const { resolver, keys = requestGroupOrder, memberTypeWrapper, withContentType = false } = options;
719
870
  const { groups, hasRequiredPath, hasRequiredQuery, hasRequiredHeader } = getRequestGroupOptionality(node);
720
871
  const names = keys.filter((key) => groups[key]);
721
872
  if (names.length === 0) return null;
@@ -727,6 +878,11 @@ function buildGroupedRequestParam(node, options) {
727
878
  };
728
879
  const isOptional = names.every((name) => !requiredByGroup[name]);
729
880
  const optionsName = resolver.response.options(node);
881
+ if (withContentType && hasRequestContentTypeChoice(node)) return (0, _kubb_plugin_ts.createFunctionParameter)({
882
+ name: "variables",
883
+ type: optionsName,
884
+ optional: false
885
+ });
730
886
  const omittedKeys = requestGroupOrder.filter((key) => !keys.includes(key));
731
887
  const optionsType = omittedKeys.length > 0 ? `Omit<${optionsName}, ${omittedKeys.map((key) => `'${key}'`).join(" | ")}>` : optionsName;
732
888
  if (memberTypeWrapper) {
@@ -784,14 +940,17 @@ function buildQueryOptionsParams(node, options) {
784
940
  * ```
785
941
  */
786
942
  function buildClientCall(node, options) {
787
- const { clientName, signal = false, unwrapName } = options;
943
+ const { clientName, signal = false, unwrapName, withContentType = false, returnType = "full" } = options;
788
944
  const { groups } = getRequestGroupOptionality(node);
789
- return `${clientName}({ ${[
945
+ const names = requestGroupOrder.filter((key) => groups[key]);
946
+ const args = [
790
947
  "...config",
791
- ...requestGroupOrder.filter((key) => groups[key]).map((name) => unwrapName ? `${name}: ${unwrapName(name)}` : name),
948
+ ...withContentType && hasRequestContentTypeChoice(node) ? ["...variables"] : names.map((name) => unwrapName ? `${name}: ${unwrapName(name)}` : name),
792
949
  signal ? "signal: config.signal ?? signal" : null,
793
950
  "throwOnError: true"
794
- ].filter((part) => part !== null).join(", ")} })`;
951
+ ].filter((part) => part !== null);
952
+ if (withContentType && hasRequestContentTypeChoice(node)) return `${clientName}(${castToClientOptions(`{ ${args.join(", ")} }`, clientName, returnType)})`;
953
+ return `${clientName}({ ${args.join(", ")} })`;
795
954
  }
796
955
  /**
797
956
  * Builds the query/mutation body that resolves a `buildClientCall` expression down to the bare
@@ -887,9 +1046,14 @@ function resolveMutationConfig(mutation, options) {
887
1046
  /**
888
1047
  * Classifies an operation as a query or a mutation from the resolved `query` / `mutation` method lists.
889
1048
  * Disabled query and mutation configs do not claim operations, and a method already claimed by an
890
- * enabled query config never counts as a mutation.
1049
+ * enabled query config never counts as a mutation. Event streams are consumed through the client
1050
+ * directly, so they do not generate query or mutation hooks.
891
1051
  */
892
1052
  function classifyOperation(node, { query, mutation }) {
1053
+ if (isEventStream(node)) return {
1054
+ isQuery: false,
1055
+ isMutation: false
1056
+ };
893
1057
  const isQuery = !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
894
1058
  const queryMethods = new Set(query ? query.methods : []);
895
1059
  return {
@@ -1042,8 +1206,7 @@ function buildResolvedRequestParams(node) {
1042
1206
  if (names.length === 0) return null;
1043
1207
  return `{ ${names.map((name) => `${name}: typeof ${name} === 'function' ? ${name}() : ${name}`).join(", ")} }`;
1044
1208
  }
1045
- //#endregion
1046
- //#region ../../internals/tanstack-query/src/components/InfiniteQueryOptions.tsx
1209
+ // ../../internals/tanstack-query/src/components/InfiniteQueryOptions.tsx
1047
1210
  const declarationPrinter$6 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1048
1211
  const callPrinter$3 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
1049
1212
  function InfiniteQueryOptions({ name, clientName, initialPageParam, hasExplicitInitialPageParam, cursorParam, nextParam, previousParam, getNextPageParam, getPreviousPageParam, node, tsResolver, queryParam, queryKeyName, queryKeyType = "typeof queryKey", memberTypeWrapper, unwrapName, returnType = "full" }) {
@@ -1119,8 +1282,7 @@ return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${que
1119
1282
  })
1120
1283
  });
1121
1284
  }
1122
- //#endregion
1123
- //#region ../../internals/tanstack-query/src/components/MutationKey.tsx
1285
+ // ../../internals/tanstack-query/src/components/MutationKey.tsx
1124
1286
  const declarationPrinter$5 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1125
1287
  /**
1126
1288
  * Default `mutationKey` builder. Call it from a custom builder to extend the default key.
@@ -1167,8 +1329,7 @@ function MutationKey({ name, node, transformer, typeName }) {
1167
1329
  })
1168
1330
  })] });
1169
1331
  }
1170
- //#endregion
1171
- //#region ../../internals/tanstack-query/src/resolver.ts
1332
+ // ../../internals/tanstack-query/src/resolver.ts
1172
1333
  /**
1173
1334
  * Builds the shared query namespace for a variant. Spread the result into
1174
1335
  * `createResolver` once per variant the plugin supports.
@@ -1184,19 +1345,39 @@ function MutationKey({ name, node, transformer, typeName }) {
1184
1345
  function createQueryResolver(variant = "") {
1185
1346
  return {
1186
1347
  name(node) {
1187
- return `use${capitalize(this.name(node.operationId))}${variant}`;
1348
+ const name = `use${capitalize(this.name(node.operationId))}${variant}`;
1349
+ return this.resolveName({
1350
+ key: operationKey(node, "query", variant, "name"),
1351
+ name
1352
+ });
1188
1353
  },
1189
1354
  optionsName(node) {
1190
- return `${this.name(node.operationId)}${variant}QueryOptions`;
1355
+ const name = `${this.name(node.operationId)}${variant}QueryOptions`;
1356
+ return this.resolveName({
1357
+ key: operationKey(node, "query", variant, "optionsName"),
1358
+ name
1359
+ });
1191
1360
  },
1192
1361
  keyName(node) {
1193
- return `${this.name(node.operationId)}${variant}QueryKey`;
1362
+ const name = `${this.name(node.operationId)}${variant}QueryKey`;
1363
+ return this.resolveName({
1364
+ key: operationKey(node, "query", variant, "keyName"),
1365
+ name
1366
+ });
1194
1367
  },
1195
1368
  keyTypeName(node) {
1196
- return `${capitalize(this.name(node.operationId))}${variant}QueryKey`;
1369
+ const name = `${capitalize(this.name(node.operationId))}${variant}QueryKey`;
1370
+ return this.resolveName({
1371
+ key: operationKey(node, "query", variant, "keyTypeName"),
1372
+ name
1373
+ });
1197
1374
  },
1198
1375
  clientName(node) {
1199
- return `${this.name(node.operationId)}${variant}`;
1376
+ const name = `${this.name(node.operationId)}${variant}`;
1377
+ return this.resolveName({
1378
+ key: operationKey(node, "query", variant, "clientName"),
1379
+ name
1380
+ });
1200
1381
  }
1201
1382
  };
1202
1383
  }
@@ -1213,15 +1394,22 @@ function createQueryResolver(variant = "") {
1213
1394
  function createMutationResolver() {
1214
1395
  return {
1215
1396
  name(node) {
1216
- return `use${capitalize(this.name(node.operationId))}`;
1397
+ const name = `use${capitalize(this.name(node.operationId))}`;
1398
+ return this.resolveName({
1399
+ key: operationKey(node, "mutation", "name"),
1400
+ name
1401
+ });
1217
1402
  },
1218
1403
  keyName(node) {
1219
- return `${this.name(node.operationId)}MutationKey`;
1404
+ const name = `${this.name(node.operationId)}MutationKey`;
1405
+ return this.resolveName({
1406
+ key: operationKey(node, "mutation", "keyName"),
1407
+ name
1408
+ });
1220
1409
  }
1221
1410
  };
1222
1411
  }
1223
- //#endregion
1224
- //#region ../../internals/tanstack-query/src/components/QueryKey.tsx
1412
+ // ../../internals/tanstack-query/src/components/QueryKey.tsx
1225
1413
  const declarationPrinter$4 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1226
1414
  /**
1227
1415
  * Default `queryKey` builder. Call it from a custom builder to extend the default key.
@@ -1279,8 +1467,7 @@ function QueryKey({ name, node, tsResolver, typeName, transformer, variant = "qu
1279
1467
  })
1280
1468
  })] });
1281
1469
  }
1282
- //#endregion
1283
- //#region src/generators/customHookOptionsFileGenerator.tsx
1470
+ // src/generators/customHookOptionsFileGenerator.tsx
1284
1471
  /**
1285
1472
  * Scaffolds the user-editable `useCustomHookOptions` file when
1286
1473
  * `pluginReactQuery({ customOptions: { ... }, hooks: true })` is configured. The file is
@@ -1377,8 +1564,7 @@ const customHookOptionsFileGenerator = (0, kubb_kit.defineGenerator)({
1377
1564
  });
1378
1565
  }
1379
1566
  });
1380
- //#endregion
1381
- //#region src/generators/hookOptionsGenerator.tsx
1567
+ // src/generators/hookOptionsGenerator.tsx
1382
1568
  /**
1383
1569
  * Emits the `HookOptions` type used by `customOptions`. Enabled when
1384
1570
  * `pluginReactQuery({ customOptions: { ... } })`. The generated type lists
@@ -1537,8 +1723,7 @@ const hookOptionsGenerator = (0, kubb_kit.defineGenerator)({
1537
1723
  });
1538
1724
  }
1539
1725
  });
1540
- //#endregion
1541
- //#region src/components/Query.tsx
1726
+ // src/components/Query.tsx
1542
1727
  const declarationPrinter$3 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1543
1728
  const OBSERVER_OPTIONS_NAMES = {
1544
1729
  infinite: {
@@ -1648,8 +1833,7 @@ function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, t
1648
1833
  })
1649
1834
  });
1650
1835
  }
1651
- //#endregion
1652
- //#region src/components/QueryOptions.tsx
1836
+ // src/components/QueryOptions.tsx
1653
1837
  const declarationPrinter$2 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1654
1838
  const callPrinter$2 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
1655
1839
  function QueryOptions({ name, clientName, node, tsResolver, queryKeyName, returnType = "full" }) {
@@ -1682,8 +1866,7 @@ function QueryOptions({ name, clientName, node, tsResolver, queryKeyName, return
1682
1866
  })
1683
1867
  });
1684
1868
  }
1685
- //#endregion
1686
- //#region src/generators/createQueryGenerator.tsx
1869
+ // src/generators/createQueryGenerator.tsx
1687
1870
  const OBSERVER_IMPORTS = {
1688
1871
  query: ["QueryObserverOptions", "UseQueryResult"],
1689
1872
  suspenseQuery: ["UseSuspenseQueryOptions", "UseSuspenseQueryResult"],
@@ -1842,8 +2025,7 @@ function createQueryGenerator({ name, variant }) {
1842
2025
  }
1843
2026
  });
1844
2027
  }
1845
- //#endregion
1846
- //#region src/generators/infiniteQueryGenerator.tsx
2028
+ // src/generators/infiniteQueryGenerator.tsx
1847
2029
  /**
1848
2030
  * Built-in generator for `useInfiniteQuery` hooks. Enabled when
1849
2031
  * `pluginReactQuery({ infinite: { ... }, hooks: true })`. Emits one
@@ -1855,8 +2037,7 @@ const infiniteQueryGenerator = createQueryGenerator({
1855
2037
  name: "react-infinite-query",
1856
2038
  variant: "infiniteQuery"
1857
2039
  });
1858
- //#endregion
1859
- //#region src/components/MutationOptions.tsx
2040
+ // src/components/MutationOptions.tsx
1860
2041
  const declarationPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1861
2042
  const callPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
1862
2043
  function buildMutationConfigParamsNode(node) {
@@ -1870,14 +2051,19 @@ function MutationOptions({ name, clientName, node, tsResolver, mutationKeyName,
1870
2051
  const { TData, TError } = buildResponseTypes(node, tsResolver);
1871
2052
  const configParamsNode = buildMutationConfigParamsNode(node);
1872
2053
  const paramsSignature = declarationPrinter$1.print(configParamsNode) ?? "";
1873
- const groupedParam = buildGroupedRequestParam(node, { resolver: tsResolver });
2054
+ const groupedParam = buildGroupedRequestParam(node, {
2055
+ resolver: tsResolver,
2056
+ withContentType: true
2057
+ });
1874
2058
  const hasMutationParams = groupedParam !== null;
1875
2059
  const groupedParamsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedParam ? [groupedParam] : [] });
1876
2060
  const TRequest = hasMutationParams ? tsResolver.response.options(node) : "undefined";
1877
2061
  const argBindingStr = hasMutationParams ? callPrinter$1.print(groupedParamsNode) ?? "" : "_";
1878
2062
  const mutationFnBody = buildCallResultBody(buildClientCall(node, {
1879
2063
  clientName,
1880
- signal: false
2064
+ signal: false,
2065
+ withContentType: true,
2066
+ returnType
1881
2067
  }), { returnType });
1882
2068
  return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1883
2069
  name,
@@ -1900,8 +2086,7 @@ function MutationOptions({ name, clientName, node, tsResolver, mutationKeyName,
1900
2086
  })
1901
2087
  });
1902
2088
  }
1903
- //#endregion
1904
- //#region src/components/Mutation.tsx
2089
+ // src/components/Mutation.tsx
1905
2090
  const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
1906
2091
  const callPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
1907
2092
  function buildMutationParamsNode(node, options) {
@@ -1960,8 +2145,7 @@ function Mutation({ name, mutationOptionsName, node, tsResolver, mutationKeyName
1960
2145
  })
1961
2146
  });
1962
2147
  }
1963
- //#endregion
1964
- //#region src/generators/mutationGenerator.tsx
2148
+ // src/generators/mutationGenerator.tsx
1965
2149
  /**
1966
2150
  * Built-in generator for `useMutation` hooks. Emits one `useFooMutation` hook
1967
2151
  * per POST/PUT/DELETE operation (configurable via `mutation.methods`) plus
@@ -2054,8 +2238,7 @@ const mutationGenerator = (0, kubb_kit.defineGenerator)({
2054
2238
  });
2055
2239
  }
2056
2240
  });
2057
- //#endregion
2058
- //#region src/generators/queryGenerator.tsx
2241
+ // src/generators/queryGenerator.tsx
2059
2242
  /**
2060
2243
  * Built-in generator for `useQuery` hooks. Emits one `useFooQuery` hook per
2061
2244
  * GET and QUERY operation (configurable via `query.methods`) plus the matching
@@ -2065,8 +2248,7 @@ const queryGenerator = createQueryGenerator({
2065
2248
  name: "react-query",
2066
2249
  variant: "query"
2067
2250
  });
2068
- //#endregion
2069
- //#region src/generators/suspenseInfiniteQueryGenerator.tsx
2251
+ // src/generators/suspenseInfiniteQueryGenerator.tsx
2070
2252
  /**
2071
2253
  * Built-in generator for `useSuspenseInfiniteQuery` hooks. Enabled when
2072
2254
  * `suspense`, `infinite`, and `hooks` are all configured. Combines suspense
@@ -2077,8 +2259,7 @@ const suspenseInfiniteQueryGenerator = createQueryGenerator({
2077
2259
  name: "react-suspense-infinite-query",
2078
2260
  variant: "suspenseInfiniteQuery"
2079
2261
  });
2080
- //#endregion
2081
- //#region src/generators/suspenseQueryGenerator.tsx
2262
+ // src/generators/suspenseQueryGenerator.tsx
2082
2263
  /**
2083
2264
  * Built-in generator for `useSuspenseQuery` hooks. Enabled when
2084
2265
  * `pluginReactQuery({ suspense: {}, hooks: true })`. Emits one
@@ -2090,15 +2271,14 @@ const suspenseQueryGenerator = createQueryGenerator({
2090
2271
  name: "react-suspense-query",
2091
2272
  variant: "suspenseQuery"
2092
2273
  });
2093
- //#endregion
2094
- //#region src/resolvers/resolverReactQuery.ts
2274
+ // src/resolvers/resolverReactQuery.ts
2095
2275
  /**
2096
2276
  * Default resolver used by `@kubb/plugin-react-query`. Decides the names and
2097
2277
  * file paths for every generated TanStack Query hook (`useFoo`,
2098
2278
  * `useFooSuspense`, `useFooInfinite`, ...) and its companion helpers
2099
2279
  * (`fooQueryKey`, `fooQueryOptions`).
2100
2280
  *
2101
- * Functions and files use the built-in camelCase casing; hooks get the `use`
2281
+ * Functions use safe camelCase identifiers; hooks get the `use`
2102
2282
  * prefix; suspense and infinite variants are suffixed with `Suspense`/`Infinite`.
2103
2283
  *
2104
2284
  * @example Resolve hook and helper names
@@ -2113,6 +2293,7 @@ const suspenseQueryGenerator = createQueryGenerator({
2113
2293
  */
2114
2294
  const resolverReactQuery = (0, kubb_kit.createResolver)({
2115
2295
  pluginName: "plugin-react-query",
2296
+ name: resolveOperationName,
2116
2297
  query: createQueryResolver(),
2117
2298
  suspenseQuery: createQueryResolver("Suspense"),
2118
2299
  infiniteQuery: createQueryResolver("Infinite"),
@@ -2120,23 +2301,36 @@ const resolverReactQuery = (0, kubb_kit.createResolver)({
2120
2301
  mutation: {
2121
2302
  ...createMutationResolver(),
2122
2303
  optionsName(node) {
2123
- return `${this.name(node.operationId)}MutationOptions`;
2304
+ const name = `${this.name(node.operationId)}MutationOptions`;
2305
+ return this.resolveName({
2306
+ key: operationKey(node, "mutation", "optionsName"),
2307
+ name
2308
+ });
2124
2309
  },
2125
2310
  typeName(node) {
2126
- return capitalize(this.name(node.operationId));
2311
+ const name = capitalize(this.name(node.operationId));
2312
+ return this.resolveName({
2313
+ key: operationKey(node, "mutation", "typeName"),
2314
+ name
2315
+ });
2127
2316
  }
2128
2317
  },
2129
2318
  hook: {
2130
2319
  optionsName() {
2131
- return "HookOptions";
2320
+ return this.resolveName({
2321
+ key: ["hook", "options"],
2322
+ name: "HookOptions"
2323
+ });
2132
2324
  },
2133
2325
  customOptionsName() {
2134
- return "getCustomHookOptions";
2326
+ return this.resolveName({
2327
+ key: ["hook", "custom-options"],
2328
+ name: "getCustomHookOptions"
2329
+ });
2135
2330
  }
2136
2331
  }
2137
2332
  });
2138
- //#endregion
2139
- //#region src/plugin.ts
2333
+ // src/plugin.ts
2140
2334
  /**
2141
2335
  * Canonical plugin name for `@kubb/plugin-react-query`. Used for driver lookups
2142
2336
  * and cross-plugin dependency references.
@@ -2210,7 +2404,6 @@ const pluginReactQuery = (0, kubb_kit.defineExtension)({
2210
2404
  };
2211
2405
  }
2212
2406
  });
2213
- //#endregion
2214
2407
  exports.default = pluginReactQuery;
2215
2408
  exports.definePageParam = definePageParam;
2216
2409
  exports.mutationKeyTransformer = mutationKeyTransformer;