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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -5,8 +5,7 @@ import { File, Function, Type, jsxRenderer } from "kubb/jsx";
5
5
  import { createFunctionParameter, createFunctionParameters, createObjectBindingPattern, createTypeLiteral, functionPrinter, pluginTsName } from "@kubb/plugin-ts";
6
6
  import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
7
7
  import fs from "node:fs";
8
- //#endregion
9
- //#region ../../internals/shared/src/operation.ts
8
+ // ../../internals/shared/src/operation.ts
10
9
  /**
11
10
  * Builds the `ResolverFileParams` every operation generator passes to
12
11
  * `resolver.file`: a file named `name`, tagged by the operation's first
@@ -75,6 +74,24 @@ function getContentTypeInfo(node) {
75
74
  function getResponseContentTypeInfo(node) {
76
75
  return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? []);
77
76
  }
77
+ /**
78
+ * Reads the single base content type of an operation's primary success response, lowercased and
79
+ * stripped of any `; charset=...` suffix. Returns `undefined` when the response declares zero or
80
+ * more than one content type, since neither case has a single type to act on.
81
+ */
82
+ function getPrimarySuccessContentType(node) {
83
+ const contentTypes = getPrimarySuccessResponse(node)?.content?.map((entry) => entry.contentType) ?? [];
84
+ if (contentTypes.length !== 1) return void 0;
85
+ return contentTypes[0].split(";")[0].trim().toLowerCase();
86
+ }
87
+ /**
88
+ * Whether an operation streams its primary success response as Server-Sent Events
89
+ * (`text/event-stream`). The client generator uses this to return a typed event stream instead of a
90
+ * one-shot `RequestResult`.
91
+ */
92
+ function isEventStream(node) {
93
+ return getPrimarySuccessContentType(node) === "text/event-stream";
94
+ }
78
95
  const requestConfigBaseType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
79
96
  function buildRequestConfigType(node) {
80
97
  const request = getContentTypeInfo(node);
@@ -166,6 +183,22 @@ function getOperationParameters(node) {
166
183
  operationParameterGroupsByNode.set(node, groups);
167
184
  return groups;
168
185
  }
186
+ /**
187
+ * Builds the combined `{ body, path, query, headers }` options object schema for an operation,
188
+ * referencing the already-resolved body and grouped param names. Shared by `@kubb/plugin-ts`'s
189
+ * `Options` type and `@kubb/plugin-zod`'s inferred options schema, so both printers emit the same
190
+ * shape from the same inputs. `primitive: 'object'` is a no-op for the TS printer and tells the Zod
191
+ * printer to emit `z.object(…)` rather than a record.
192
+ */
193
+ function hasRequestContentTypeChoice(node) {
194
+ return (node.requestBody?.content ?? []).filter((entry) => entry.schema).length > 1;
195
+ }
196
+ /**
197
+ * Casts a call argument to the client's parameter type; a `'plain'` client is non-generic.
198
+ */
199
+ function castToClientOptions(callArg, clientName, returnType = "full") {
200
+ return `${callArg} as Parameters<typeof ${clientName}${returnType === "plain" ? "" : "<true>"}>[0]`;
201
+ }
169
202
  function getStatusCodeNumber(statusCode) {
170
203
  const code = Number(statusCode);
171
204
  return Number.isNaN(code) ? null : code;
@@ -228,8 +261,7 @@ function resolveOperationTypeNames(node, resolver, options = {}) {
228
261
  byResolver.set(cacheKey, result);
229
262
  return result;
230
263
  }
231
- //#endregion
232
- //#region ../../internals/utils/src/casing.ts
264
+ // ../../internals/utils/src/casing.ts
233
265
  /**
234
266
  * Shared implementation for camelCase and PascalCase conversion.
235
267
  * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
@@ -276,8 +308,146 @@ function camelCase(text, { prefix = "", suffix = "" } = {}) {
276
308
  function capitalize(text) {
277
309
  return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
278
310
  }
279
- //#endregion
280
- //#region ../../internals/utils/src/strings.ts
311
+ // ../../internals/utils/src/reserved.ts
312
+ /**
313
+ * JavaScript and Java reserved words.
314
+ * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
315
+ */
316
+ const reservedWords = /* @__PURE__ */ new Set([
317
+ "abstract",
318
+ "arguments",
319
+ "await",
320
+ "boolean",
321
+ "break",
322
+ "byte",
323
+ "case",
324
+ "catch",
325
+ "char",
326
+ "class",
327
+ "const",
328
+ "continue",
329
+ "debugger",
330
+ "default",
331
+ "delete",
332
+ "do",
333
+ "double",
334
+ "else",
335
+ "enum",
336
+ "eval",
337
+ "export",
338
+ "extends",
339
+ "false",
340
+ "final",
341
+ "finally",
342
+ "float",
343
+ "for",
344
+ "function",
345
+ "goto",
346
+ "if",
347
+ "implements",
348
+ "import",
349
+ "in",
350
+ "instanceof",
351
+ "int",
352
+ "interface",
353
+ "let",
354
+ "long",
355
+ "native",
356
+ "new",
357
+ "null",
358
+ "package",
359
+ "private",
360
+ "protected",
361
+ "public",
362
+ "return",
363
+ "short",
364
+ "static",
365
+ "super",
366
+ "switch",
367
+ "synchronized",
368
+ "this",
369
+ "throw",
370
+ "throws",
371
+ "transient",
372
+ "true",
373
+ "try",
374
+ "typeof",
375
+ "var",
376
+ "void",
377
+ "volatile",
378
+ "while",
379
+ "with",
380
+ "yield",
381
+ "Array",
382
+ "Date",
383
+ "hasOwnProperty",
384
+ "Infinity",
385
+ "isFinite",
386
+ "isNaN",
387
+ "isPrototypeOf",
388
+ "length",
389
+ "Math",
390
+ "name",
391
+ "NaN",
392
+ "Number",
393
+ "Object",
394
+ "prototype",
395
+ "String",
396
+ "toString",
397
+ "undefined",
398
+ "valueOf"
399
+ ]);
400
+ /**
401
+ * Returns `true` when `name` is a syntactically valid JavaScript variable name.
402
+ *
403
+ * @example
404
+ * ```ts
405
+ * isValidVarName('status') // true
406
+ * isValidVarName('class') // false (reserved word)
407
+ * isValidVarName('42foo') // false (starts with digit)
408
+ * ```
409
+ */
410
+ function isValidVarName(name) {
411
+ if (!name || reservedWords.has(name)) return false;
412
+ return isIdentifier(name);
413
+ }
414
+ /**
415
+ * Returns `name` when it's a syntactically valid JavaScript variable name,
416
+ * otherwise prefixes it with `_` so the result is a valid identifier.
417
+ *
418
+ * Useful for sanitizing OpenAPI schema names or operation IDs that start with
419
+ * a digit (e.g. `409`, `504AccountCancel`) before using them as exported
420
+ * variable, type, or function names.
421
+ *
422
+ * @example
423
+ * ```ts
424
+ * ensureValidVarName('409') // '_409'
425
+ * ensureValidVarName('504AccountCancel') // '_504AccountCancel'
426
+ * ensureValidVarName('Pet') // 'Pet'
427
+ * ensureValidVarName('class') // '_class'
428
+ * ```
429
+ */
430
+ function ensureValidVarName(name) {
431
+ if (!name || isValidVarName(name)) return name;
432
+ return `_${name}`;
433
+ }
434
+ /**
435
+ * Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
436
+ *
437
+ * Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
438
+ * even though they are not valid variable names, so use this (not {@link isValidVarName}) when
439
+ * deciding whether an object key needs quoting.
440
+ *
441
+ * @example
442
+ * ```ts
443
+ * isIdentifier('name') // true
444
+ * isIdentifier('x-total')// false
445
+ * ```
446
+ */
447
+ function isIdentifier(name) {
448
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
449
+ }
450
+ // ../../internals/utils/src/strings.ts
281
451
  /**
282
452
  * Renders a dotted path or string array as an optional-chaining accessor expression rooted at
283
453
  * `accessor`. Returns `null` for an empty path.
@@ -293,8 +463,29 @@ function getNestedAccessor(param, accessor) {
293
463
  if (parts.length === 0 || parts.length === 1 && parts[0] === "") return null;
294
464
  return `${accessor}?.['${`${parts.join("']?.['")}']`}`;
295
465
  }
296
- //#endregion
297
- //#region ../../internals/shared/src/group.ts
466
+ // ../../internals/shared/src/resolver.ts
467
+ function resolveOperationName(name) {
468
+ return ensureValidVarName(camelCase(name));
469
+ }
470
+ /**
471
+ * Builds the allocation key for a declaration an operation owns. `scope` names which declaration
472
+ * it is, so two of them never share an allocation even when a custom resolver gives both the same
473
+ * name. Leave `scope` empty for the operation's own declaration.
474
+ *
475
+ * @example
476
+ * ```ts
477
+ * resolver.resolveName({ key: operationKey(node, 'response', 'status', 404), name })
478
+ * ```
479
+ */
480
+ function operationKey(node, ...scope) {
481
+ return [
482
+ "operation",
483
+ node.method,
484
+ node.path,
485
+ ...scope.map(String)
486
+ ];
487
+ }
488
+ // ../../internals/shared/src/group.ts
298
489
  /**
299
490
  * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
300
491
  * shared default naming so every plugin groups output consistently:
@@ -324,17 +515,14 @@ function createGroupConfig(group) {
324
515
  name: group.name ? group.name : defaultName
325
516
  };
326
517
  }
327
- //#endregion
328
- //#region kubb-extension.json
518
+ // kubb-extension.json
329
519
  var compatibility = {
330
- "kubb": ">=5.8.3",
520
+ "kubb": ">=5.14.6",
331
521
  "node": ">=22.22"
332
522
  };
333
- //#endregion
334
- //#region package.json
335
- var version = "5.7.0-canary.20261025T201031";
336
- //#endregion
337
- //#region ../../internals/client/src/resolveOperationTypes.ts
523
+ // package.json
524
+ var version = "5.7.0";
525
+ // ../../internals/client/src/resolveOperationTypes.ts
338
526
  /**
339
527
  * A `plugin-ts` shaped resolver whose operation type names point at the types `pluginZod({ inferred })`
340
528
  * exports next to each schema, so code written against `plugin-ts` names picks up the zod types.
@@ -400,8 +588,7 @@ function resolveOperationTypes(driver, pluginName) {
400
588
  group: pluginZod.options.group ?? void 0
401
589
  };
402
590
  }
403
- //#endregion
404
- //#region ../../internals/client/src/resolveClient.ts
591
+ // ../../internals/client/src/resolveClient.ts
405
592
  /**
406
593
  * Resolves which client plugin a consumer (react-query, vue-query, swr, mcp) should call for an
407
594
  * operation, shared so the selection rules and diagnostics stay in one place.
@@ -511,8 +698,7 @@ function resolveContractClient(options) {
511
698
  }
512
699
  return resolved;
513
700
  }
514
- //#endregion
515
- //#region ../../internals/client/src/resolveClientOperation.ts
701
+ // ../../internals/client/src/resolveClientOperation.ts
516
702
  function isRelativeImport(importPath) {
517
703
  return importPath.startsWith(".");
518
704
  }
@@ -559,8 +745,12 @@ function resolveClientOperation(options) {
559
745
  group: operationOptions.group ?? void 0
560
746
  });
561
747
  const { importPath } = operationOptions;
748
+ const name = resolver.name(node.operationId);
562
749
  return {
563
- name: resolver.name(node.operationId),
750
+ name: resolver.resolveName({
751
+ key: operationKey(node),
752
+ name
753
+ }),
564
754
  path: file.path,
565
755
  clientPath: importPath === void 0 ? path.resolve(root, ".kubb/client.ts") : resolveImportPath({
566
756
  importPath,
@@ -571,8 +761,7 @@ function resolveClientOperation(options) {
571
761
  };
572
762
  });
573
763
  }
574
- //#endregion
575
- //#region ../../internals/tanstack-query/src/components/HookFile.tsx
764
+ // ../../internals/tanstack-query/src/components/HookFile.tsx
576
765
  /**
577
766
  * Resolves what every TanStack hook file shares: its file, the operation types file and names (`@kubb/plugin-ts`, or
578
767
  * `pluginZod({ inferred: 'codec' })`), banner and footer.
@@ -661,8 +850,7 @@ function HookFile({ hook, imports, children }) {
661
850
  ]
662
851
  });
663
852
  }
664
- //#endregion
665
- //#region ../../internals/tanstack-query/src/utils.ts
853
+ // ../../internals/tanstack-query/src/utils.ts
666
854
  /**
667
855
  * The grouped request options, ordered for both the destructured signature and the
668
856
  * call passed to the underlying client.
@@ -688,7 +876,7 @@ function maybeValueOrGetter(type) {
688
876
  * `MaybeRefOrGetter` per group.
689
877
  */
690
878
  function buildGroupedRequestParam(node, options) {
691
- const { resolver, keys = requestGroupOrder, memberTypeWrapper } = options;
879
+ const { resolver, keys = requestGroupOrder, memberTypeWrapper, withContentType = false } = options;
692
880
  const { groups, hasRequiredPath, hasRequiredQuery, hasRequiredHeader } = getRequestGroupOptionality(node);
693
881
  const names = keys.filter((key) => groups[key]);
694
882
  if (names.length === 0) return null;
@@ -700,6 +888,11 @@ function buildGroupedRequestParam(node, options) {
700
888
  };
701
889
  const isOptional = names.every((name) => !requiredByGroup[name]);
702
890
  const optionsName = resolver.response.options(node);
891
+ if (withContentType && hasRequestContentTypeChoice(node)) return createFunctionParameter({
892
+ name: "variables",
893
+ type: optionsName,
894
+ optional: false
895
+ });
703
896
  const omittedKeys = requestGroupOrder.filter((key) => !keys.includes(key));
704
897
  const optionsType = omittedKeys.length > 0 ? `Omit<${optionsName}, ${omittedKeys.map((key) => `'${key}'`).join(" | ")}>` : optionsName;
705
898
  if (memberTypeWrapper) {
@@ -757,14 +950,17 @@ function buildQueryOptionsParams(node, options) {
757
950
  * ```
758
951
  */
759
952
  function buildClientCall(node, options) {
760
- const { clientName, signal = false, unwrapName } = options;
953
+ const { clientName, signal = false, unwrapName, withContentType = false, returnType = "full" } = options;
761
954
  const { groups } = getRequestGroupOptionality(node);
762
- return `${clientName}({ ${[
955
+ const names = requestGroupOrder.filter((key) => groups[key]);
956
+ const args = [
763
957
  "...config",
764
- ...requestGroupOrder.filter((key) => groups[key]).map((name) => unwrapName ? `${name}: ${unwrapName(name)}` : name),
958
+ ...withContentType && hasRequestContentTypeChoice(node) ? ["...variables"] : names.map((name) => unwrapName ? `${name}: ${unwrapName(name)}` : name),
765
959
  signal ? "signal: config.signal ?? signal" : null,
766
960
  "throwOnError: true"
767
- ].filter((part) => part !== null).join(", ")} })`;
961
+ ].filter((part) => part !== null);
962
+ if (withContentType && hasRequestContentTypeChoice(node)) return `${clientName}(${castToClientOptions(`{ ${args.join(", ")} }`, clientName, returnType)})`;
963
+ return `${clientName}({ ${args.join(", ")} })`;
768
964
  }
769
965
  /**
770
966
  * Builds the query/mutation body that resolves a `buildClientCall` expression down to the bare
@@ -860,9 +1056,14 @@ function resolveMutationConfig(mutation, options) {
860
1056
  /**
861
1057
  * Classifies an operation as a query or a mutation from the resolved `query` / `mutation` method lists.
862
1058
  * Disabled query and mutation configs do not claim operations, and a method already claimed by an
863
- * enabled query config never counts as a mutation.
1059
+ * enabled query config never counts as a mutation. Event streams are consumed through the client
1060
+ * directly, so they do not generate query or mutation hooks.
864
1061
  */
865
1062
  function classifyOperation(node, { query, mutation }) {
1063
+ if (isEventStream(node)) return {
1064
+ isQuery: false,
1065
+ isMutation: false
1066
+ };
866
1067
  const isQuery = !!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase());
867
1068
  const queryMethods = new Set(query ? query.methods : []);
868
1069
  return {
@@ -1015,8 +1216,7 @@ function buildResolvedRequestParams(node) {
1015
1216
  if (names.length === 0) return null;
1016
1217
  return `{ ${names.map((name) => `${name}: typeof ${name} === 'function' ? ${name}() : ${name}`).join(", ")} }`;
1017
1218
  }
1018
- //#endregion
1019
- //#region ../../internals/tanstack-query/src/components/InfiniteQueryOptions.tsx
1219
+ // ../../internals/tanstack-query/src/components/InfiniteQueryOptions.tsx
1020
1220
  const declarationPrinter$6 = functionPrinter({ mode: "declaration" });
1021
1221
  const callPrinter$3 = functionPrinter({ mode: "call" });
1022
1222
  function InfiniteQueryOptions({ name, clientName, initialPageParam, hasExplicitInitialPageParam, cursorParam, nextParam, previousParam, getNextPageParam, getPreviousPageParam, node, tsResolver, queryParam, queryKeyName, queryKeyType = "typeof queryKey", memberTypeWrapper, unwrapName, returnType = "full" }) {
@@ -1092,8 +1292,7 @@ return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${que
1092
1292
  })
1093
1293
  });
1094
1294
  }
1095
- //#endregion
1096
- //#region ../../internals/tanstack-query/src/components/MutationKey.tsx
1295
+ // ../../internals/tanstack-query/src/components/MutationKey.tsx
1097
1296
  const declarationPrinter$5 = functionPrinter({ mode: "declaration" });
1098
1297
  /**
1099
1298
  * Default `mutationKey` builder. Call it from a custom builder to extend the default key.
@@ -1140,8 +1339,7 @@ function MutationKey({ name, node, transformer, typeName }) {
1140
1339
  })
1141
1340
  })] });
1142
1341
  }
1143
- //#endregion
1144
- //#region ../../internals/tanstack-query/src/resolver.ts
1342
+ // ../../internals/tanstack-query/src/resolver.ts
1145
1343
  /**
1146
1344
  * Builds the shared query namespace for a variant. Spread the result into
1147
1345
  * `createResolver` once per variant the plugin supports.
@@ -1157,19 +1355,39 @@ function MutationKey({ name, node, transformer, typeName }) {
1157
1355
  function createQueryResolver(variant = "") {
1158
1356
  return {
1159
1357
  name(node) {
1160
- return `use${capitalize(this.name(node.operationId))}${variant}`;
1358
+ const name = `use${capitalize(this.name(node.operationId))}${variant}`;
1359
+ return this.resolveName({
1360
+ key: operationKey(node, "query", variant, "name"),
1361
+ name
1362
+ });
1161
1363
  },
1162
1364
  optionsName(node) {
1163
- return `${this.name(node.operationId)}${variant}QueryOptions`;
1365
+ const name = `${this.name(node.operationId)}${variant}QueryOptions`;
1366
+ return this.resolveName({
1367
+ key: operationKey(node, "query", variant, "optionsName"),
1368
+ name
1369
+ });
1164
1370
  },
1165
1371
  keyName(node) {
1166
- return `${this.name(node.operationId)}${variant}QueryKey`;
1372
+ const name = `${this.name(node.operationId)}${variant}QueryKey`;
1373
+ return this.resolveName({
1374
+ key: operationKey(node, "query", variant, "keyName"),
1375
+ name
1376
+ });
1167
1377
  },
1168
1378
  keyTypeName(node) {
1169
- return `${capitalize(this.name(node.operationId))}${variant}QueryKey`;
1379
+ const name = `${capitalize(this.name(node.operationId))}${variant}QueryKey`;
1380
+ return this.resolveName({
1381
+ key: operationKey(node, "query", variant, "keyTypeName"),
1382
+ name
1383
+ });
1170
1384
  },
1171
1385
  clientName(node) {
1172
- return `${this.name(node.operationId)}${variant}`;
1386
+ const name = `${this.name(node.operationId)}${variant}`;
1387
+ return this.resolveName({
1388
+ key: operationKey(node, "query", variant, "clientName"),
1389
+ name
1390
+ });
1173
1391
  }
1174
1392
  };
1175
1393
  }
@@ -1186,15 +1404,22 @@ function createQueryResolver(variant = "") {
1186
1404
  function createMutationResolver() {
1187
1405
  return {
1188
1406
  name(node) {
1189
- return `use${capitalize(this.name(node.operationId))}`;
1407
+ const name = `use${capitalize(this.name(node.operationId))}`;
1408
+ return this.resolveName({
1409
+ key: operationKey(node, "mutation", "name"),
1410
+ name
1411
+ });
1190
1412
  },
1191
1413
  keyName(node) {
1192
- return `${this.name(node.operationId)}MutationKey`;
1414
+ const name = `${this.name(node.operationId)}MutationKey`;
1415
+ return this.resolveName({
1416
+ key: operationKey(node, "mutation", "keyName"),
1417
+ name
1418
+ });
1193
1419
  }
1194
1420
  };
1195
1421
  }
1196
- //#endregion
1197
- //#region ../../internals/tanstack-query/src/components/QueryKey.tsx
1422
+ // ../../internals/tanstack-query/src/components/QueryKey.tsx
1198
1423
  const declarationPrinter$4 = functionPrinter({ mode: "declaration" });
1199
1424
  /**
1200
1425
  * Default `queryKey` builder. Call it from a custom builder to extend the default key.
@@ -1252,8 +1477,7 @@ function QueryKey({ name, node, tsResolver, typeName, transformer, variant = "qu
1252
1477
  })
1253
1478
  })] });
1254
1479
  }
1255
- //#endregion
1256
- //#region src/generators/customHookOptionsFileGenerator.tsx
1480
+ // src/generators/customHookOptionsFileGenerator.tsx
1257
1481
  /**
1258
1482
  * Scaffolds the user-editable `useCustomHookOptions` file when
1259
1483
  * `pluginReactQuery({ customOptions: { ... }, hooks: true })` is configured. The file is
@@ -1350,8 +1574,7 @@ const customHookOptionsFileGenerator = defineGenerator({
1350
1574
  });
1351
1575
  }
1352
1576
  });
1353
- //#endregion
1354
- //#region src/generators/hookOptionsGenerator.tsx
1577
+ // src/generators/hookOptionsGenerator.tsx
1355
1578
  /**
1356
1579
  * Emits the `HookOptions` type used by `customOptions`. Enabled when
1357
1580
  * `pluginReactQuery({ customOptions: { ... } })`. The generated type lists
@@ -1510,8 +1733,7 @@ const hookOptionsGenerator = defineGenerator({
1510
1733
  });
1511
1734
  }
1512
1735
  });
1513
- //#endregion
1514
- //#region src/components/Query.tsx
1736
+ // src/components/Query.tsx
1515
1737
  const declarationPrinter$3 = functionPrinter({ mode: "declaration" });
1516
1738
  const OBSERVER_OPTIONS_NAMES = {
1517
1739
  infinite: {
@@ -1621,8 +1843,7 @@ function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, t
1621
1843
  })
1622
1844
  });
1623
1845
  }
1624
- //#endregion
1625
- //#region src/components/QueryOptions.tsx
1846
+ // src/components/QueryOptions.tsx
1626
1847
  const declarationPrinter$2 = functionPrinter({ mode: "declaration" });
1627
1848
  const callPrinter$2 = functionPrinter({ mode: "call" });
1628
1849
  function QueryOptions({ name, clientName, node, tsResolver, queryKeyName, returnType = "full" }) {
@@ -1655,8 +1876,7 @@ function QueryOptions({ name, clientName, node, tsResolver, queryKeyName, return
1655
1876
  })
1656
1877
  });
1657
1878
  }
1658
- //#endregion
1659
- //#region src/generators/createQueryGenerator.tsx
1879
+ // src/generators/createQueryGenerator.tsx
1660
1880
  const OBSERVER_IMPORTS = {
1661
1881
  query: ["QueryObserverOptions", "UseQueryResult"],
1662
1882
  suspenseQuery: ["UseSuspenseQueryOptions", "UseSuspenseQueryResult"],
@@ -1815,8 +2035,7 @@ function createQueryGenerator({ name, variant }) {
1815
2035
  }
1816
2036
  });
1817
2037
  }
1818
- //#endregion
1819
- //#region src/generators/infiniteQueryGenerator.tsx
2038
+ // src/generators/infiniteQueryGenerator.tsx
1820
2039
  /**
1821
2040
  * Built-in generator for `useInfiniteQuery` hooks. Enabled when
1822
2041
  * `pluginReactQuery({ infinite: { ... }, hooks: true })`. Emits one
@@ -1828,8 +2047,7 @@ const infiniteQueryGenerator = createQueryGenerator({
1828
2047
  name: "react-infinite-query",
1829
2048
  variant: "infiniteQuery"
1830
2049
  });
1831
- //#endregion
1832
- //#region src/components/MutationOptions.tsx
2050
+ // src/components/MutationOptions.tsx
1833
2051
  const declarationPrinter$1 = functionPrinter({ mode: "declaration" });
1834
2052
  const callPrinter$1 = functionPrinter({ mode: "call" });
1835
2053
  function buildMutationConfigParamsNode(node) {
@@ -1843,14 +2061,19 @@ function MutationOptions({ name, clientName, node, tsResolver, mutationKeyName,
1843
2061
  const { TData, TError } = buildResponseTypes(node, tsResolver);
1844
2062
  const configParamsNode = buildMutationConfigParamsNode(node);
1845
2063
  const paramsSignature = declarationPrinter$1.print(configParamsNode) ?? "";
1846
- const groupedParam = buildGroupedRequestParam(node, { resolver: tsResolver });
2064
+ const groupedParam = buildGroupedRequestParam(node, {
2065
+ resolver: tsResolver,
2066
+ withContentType: true
2067
+ });
1847
2068
  const hasMutationParams = groupedParam !== null;
1848
2069
  const groupedParamsNode = createFunctionParameters({ params: groupedParam ? [groupedParam] : [] });
1849
2070
  const TRequest = hasMutationParams ? tsResolver.response.options(node) : "undefined";
1850
2071
  const argBindingStr = hasMutationParams ? callPrinter$1.print(groupedParamsNode) ?? "" : "_";
1851
2072
  const mutationFnBody = buildCallResultBody(buildClientCall(node, {
1852
2073
  clientName,
1853
- signal: false
2074
+ signal: false,
2075
+ withContentType: true,
2076
+ returnType
1854
2077
  }), { returnType });
1855
2078
  return /* @__PURE__ */ jsx(File.Source, {
1856
2079
  name,
@@ -1873,8 +2096,7 @@ function MutationOptions({ name, clientName, node, tsResolver, mutationKeyName,
1873
2096
  })
1874
2097
  });
1875
2098
  }
1876
- //#endregion
1877
- //#region src/components/Mutation.tsx
2099
+ // src/components/Mutation.tsx
1878
2100
  const declarationPrinter = functionPrinter({ mode: "declaration" });
1879
2101
  const callPrinter = functionPrinter({ mode: "call" });
1880
2102
  function buildMutationParamsNode(node, options) {
@@ -1933,8 +2155,7 @@ function Mutation({ name, mutationOptionsName, node, tsResolver, mutationKeyName
1933
2155
  })
1934
2156
  });
1935
2157
  }
1936
- //#endregion
1937
- //#region src/generators/mutationGenerator.tsx
2158
+ // src/generators/mutationGenerator.tsx
1938
2159
  /**
1939
2160
  * Built-in generator for `useMutation` hooks. Emits one `useFooMutation` hook
1940
2161
  * per POST/PUT/DELETE operation (configurable via `mutation.methods`) plus
@@ -2027,8 +2248,7 @@ const mutationGenerator = defineGenerator({
2027
2248
  });
2028
2249
  }
2029
2250
  });
2030
- //#endregion
2031
- //#region src/generators/queryGenerator.tsx
2251
+ // src/generators/queryGenerator.tsx
2032
2252
  /**
2033
2253
  * Built-in generator for `useQuery` hooks. Emits one `useFooQuery` hook per
2034
2254
  * GET and QUERY operation (configurable via `query.methods`) plus the matching
@@ -2038,8 +2258,7 @@ const queryGenerator = createQueryGenerator({
2038
2258
  name: "react-query",
2039
2259
  variant: "query"
2040
2260
  });
2041
- //#endregion
2042
- //#region src/generators/suspenseInfiniteQueryGenerator.tsx
2261
+ // src/generators/suspenseInfiniteQueryGenerator.tsx
2043
2262
  /**
2044
2263
  * Built-in generator for `useSuspenseInfiniteQuery` hooks. Enabled when
2045
2264
  * `suspense`, `infinite`, and `hooks` are all configured. Combines suspense
@@ -2050,8 +2269,7 @@ const suspenseInfiniteQueryGenerator = createQueryGenerator({
2050
2269
  name: "react-suspense-infinite-query",
2051
2270
  variant: "suspenseInfiniteQuery"
2052
2271
  });
2053
- //#endregion
2054
- //#region src/generators/suspenseQueryGenerator.tsx
2272
+ // src/generators/suspenseQueryGenerator.tsx
2055
2273
  /**
2056
2274
  * Built-in generator for `useSuspenseQuery` hooks. Enabled when
2057
2275
  * `pluginReactQuery({ suspense: {}, hooks: true })`. Emits one
@@ -2063,15 +2281,14 @@ const suspenseQueryGenerator = createQueryGenerator({
2063
2281
  name: "react-suspense-query",
2064
2282
  variant: "suspenseQuery"
2065
2283
  });
2066
- //#endregion
2067
- //#region src/resolvers/resolverReactQuery.ts
2284
+ // src/resolvers/resolverReactQuery.ts
2068
2285
  /**
2069
2286
  * Default resolver used by `@kubb/plugin-react-query`. Decides the names and
2070
2287
  * file paths for every generated TanStack Query hook (`useFoo`,
2071
2288
  * `useFooSuspense`, `useFooInfinite`, ...) and its companion helpers
2072
2289
  * (`fooQueryKey`, `fooQueryOptions`).
2073
2290
  *
2074
- * Functions and files use the built-in camelCase casing; hooks get the `use`
2291
+ * Functions use safe camelCase identifiers; hooks get the `use`
2075
2292
  * prefix; suspense and infinite variants are suffixed with `Suspense`/`Infinite`.
2076
2293
  *
2077
2294
  * @example Resolve hook and helper names
@@ -2086,6 +2303,7 @@ const suspenseQueryGenerator = createQueryGenerator({
2086
2303
  */
2087
2304
  const resolverReactQuery = createResolver({
2088
2305
  pluginName: "plugin-react-query",
2306
+ name: resolveOperationName,
2089
2307
  query: createQueryResolver(),
2090
2308
  suspenseQuery: createQueryResolver("Suspense"),
2091
2309
  infiniteQuery: createQueryResolver("Infinite"),
@@ -2093,23 +2311,36 @@ const resolverReactQuery = createResolver({
2093
2311
  mutation: {
2094
2312
  ...createMutationResolver(),
2095
2313
  optionsName(node) {
2096
- return `${this.name(node.operationId)}MutationOptions`;
2314
+ const name = `${this.name(node.operationId)}MutationOptions`;
2315
+ return this.resolveName({
2316
+ key: operationKey(node, "mutation", "optionsName"),
2317
+ name
2318
+ });
2097
2319
  },
2098
2320
  typeName(node) {
2099
- return capitalize(this.name(node.operationId));
2321
+ const name = capitalize(this.name(node.operationId));
2322
+ return this.resolveName({
2323
+ key: operationKey(node, "mutation", "typeName"),
2324
+ name
2325
+ });
2100
2326
  }
2101
2327
  },
2102
2328
  hook: {
2103
2329
  optionsName() {
2104
- return "HookOptions";
2330
+ return this.resolveName({
2331
+ key: ["hook", "options"],
2332
+ name: "HookOptions"
2333
+ });
2105
2334
  },
2106
2335
  customOptionsName() {
2107
- return "getCustomHookOptions";
2336
+ return this.resolveName({
2337
+ key: ["hook", "custom-options"],
2338
+ name: "getCustomHookOptions"
2339
+ });
2108
2340
  }
2109
2341
  }
2110
2342
  });
2111
- //#endregion
2112
- //#region src/plugin.ts
2343
+ // src/plugin.ts
2113
2344
  /**
2114
2345
  * Canonical plugin name for `@kubb/plugin-react-query`. Used for driver lookups
2115
2346
  * and cross-plugin dependency references.
@@ -2183,7 +2414,6 @@ const pluginReactQuery = defineExtension({
2183
2414
  };
2184
2415
  }
2185
2416
  });
2186
- //#endregion
2187
2417
  export { pluginReactQuery as default, pluginReactQuery, definePageParam, mutationKeyTransformer, pluginReactQueryName, queryKeyTransformer, resolverReactQuery };
2188
2418
 
2189
2419
  //# sourceMappingURL=index.js.map