@kubb/plugin-swr 5.4.0 → 5.4.3

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
@@ -5,10 +5,6 @@ Object.defineProperties(exports, {
5
5
  //#region \0rolldown/runtime.js
6
6
  var __create = Object.create;
7
7
  var __defProp = Object.defineProperty;
8
- var __name = (target, value) => __defProp(target, "name", {
9
- value,
10
- configurable: true
11
- });
12
8
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
9
  var __getOwnPropNames = Object.getOwnPropertyNames;
14
10
  var __getProtoOf = Object.getPrototypeOf;
@@ -34,24 +30,6 @@ node_path = __toESM(node_path, 1);
34
30
  let _kubb_plugin_ts = require("@kubb/plugin-ts");
35
31
  let kubb_jsx = require("kubb/jsx");
36
32
  let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
37
- //#region ../../internals/shared/src/params.ts
38
- /**
39
- * Drops parameters that share the same name, keeping the first.
40
- *
41
- * A malformed spec can declare the same parameter name twice within one `in` location. Both would
42
- * resolve to the same output property, so emitting both would yield an object type with a duplicate
43
- * member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:
44
- * parameter names flow through unchanged, so no two distinct names ever collide here anymore.
45
- */
46
- function dedupeParams(params) {
47
- const seen = /* @__PURE__ */ new Set();
48
- return params.filter((param) => {
49
- if (seen.has(param.name)) return false;
50
- seen.add(param.name);
51
- return true;
52
- });
53
- }
54
- //#endregion
55
33
  //#region ../../internals/shared/src/operation.ts
56
34
  /**
57
35
  * Builds the `ResolverFileParams` every operation generator passes to
@@ -121,12 +99,12 @@ function getContentTypeInfo(node) {
121
99
  function getResponseContentTypeInfo(node) {
122
100
  return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? []);
123
101
  }
102
+ const requestConfigBaseType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
124
103
  function buildRequestConfigType(node) {
125
104
  const request = getContentTypeInfo(node);
126
105
  const response = getResponseContentTypeInfo(node);
127
- const configType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
128
106
  const members = [request.isMultipleContentTypes ? `request?: ${request.contentTypeUnion}` : null, response.isMultipleContentTypes ? `response?: ${response.contentTypeUnion}` : null].filter(Boolean);
129
- return members.length ? `${configType} & { contentType?: { ${members.join("; ")} } }` : configType;
107
+ return members.length ? `${requestConfigBaseType} & { contentType?: { ${members.join("; ")} } }` : requestConfigBaseType;
130
108
  }
131
109
  /**
132
110
  * Builds the `client?:` option type shared by the generated query hooks (`useQuery`,
@@ -135,7 +113,7 @@ function buildRequestConfigType(node) {
135
113
  * content type for.
136
114
  */
137
115
  function buildClientOptionType() {
138
- return `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
116
+ return requestConfigBaseType;
139
117
  }
140
118
  /**
141
119
  * Which of the grouped request options an operation carries.
@@ -195,11 +173,19 @@ const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
195
173
  function getOperationParameters(node) {
196
174
  const cached = operationParameterGroupsByNode.get(node);
197
175
  if (cached) return cached;
176
+ const group = (location) => {
177
+ const seen = /* @__PURE__ */ new Set();
178
+ return node.parameters.filter((param) => {
179
+ if (param.in !== location || seen.has(param.name)) return false;
180
+ seen.add(param.name);
181
+ return true;
182
+ });
183
+ };
198
184
  const groups = {
199
- path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
200
- query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
201
- header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
202
- cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
185
+ path: group("path"),
186
+ query: group("query"),
187
+ header: group("header"),
188
+ cookie: group("cookie")
203
189
  };
204
190
  operationParameterGroupsByNode.set(node, groups);
205
191
  return groups;
@@ -338,11 +324,11 @@ function createGroupConfig(group) {
338
324
  //#region kubb-extension.json
339
325
  var compatibility = {
340
326
  "kubb": ">=5.8.3",
341
- "node": ">=22"
327
+ "node": ">=22.12"
342
328
  };
343
329
  //#endregion
344
330
  //#region package.json
345
- var version = "5.4.0";
331
+ var version = "5.4.3";
346
332
  //#endregion
347
333
  //#region ../../internals/client/src/resolveClient.ts
348
334
  /**
@@ -386,7 +372,7 @@ const contractPlugins = [
386
372
  * @example
387
373
  * ```ts
388
374
  * resolveClient({ client: undefined, pluginNames: ['plugin-ts'] })
389
- * // { kind: 'error', message: 'No client plugin is registered…' }
375
+ * // { kind: 'error', code: 'KUBB_MISSING_DEPENDENCY', message: 'No client plugin is registered.', help: 'Add …' }
390
376
  * ```
391
377
  */
392
378
  function resolveClient(options) {
@@ -396,7 +382,9 @@ function resolveClient(options) {
396
382
  const pluginName = selectorToPlugin[client];
397
383
  if (!has(pluginName)) return {
398
384
  kind: "error",
399
- message: `\`client: '${client}'\` is set but \`@kubb/plugin-${client}\` is not registered in \`plugins\`. Add it, or drop \`client\` to use a different client plugin.`
385
+ code: kubb_kit.Diagnostics.code.missingDependency,
386
+ message: `\`client: '${client}'\` is set but \`@kubb/plugin-${client}\` is not registered in \`plugins\`.`,
387
+ help: `Add \`@kubb/plugin-${client}\` to \`plugins\`, or drop \`client\` to use a different client plugin.`
400
388
  };
401
389
  return {
402
390
  kind: "contract",
@@ -405,7 +393,9 @@ function resolveClient(options) {
405
393
  }
406
394
  if (client !== void 0) return {
407
395
  kind: "error",
408
- message: `Option \`client\` is ${typeof client === "string" ? `'${client}'` : String(client)}, but it must be one of 'fetch', 'axios', 'client'. Drop \`client\` to use the registered client plugin.`
396
+ code: kubb_kit.Diagnostics.code.invalidPluginOptions,
397
+ message: `Option \`client\` is ${typeof client === "string" ? `'${client}'` : String(client)}, but it must be one of 'fetch', 'axios', 'client'.`,
398
+ help: "Set `client` to one of those values, or drop it to use the registered client plugin."
409
399
  };
410
400
  const registered = contractPlugins.filter(has);
411
401
  if (registered.length === 1) return {
@@ -414,25 +404,40 @@ function resolveClient(options) {
414
404
  };
415
405
  if (registered.length > 1) return {
416
406
  kind: "error",
417
- message: `Multiple client plugins are registered (${registered.map((name) => `\`@kubb/${name}\``).join(", ")}). Set \`client: 'fetch' | 'axios' | 'client'\` to choose which client the hooks call, or register a single client plugin.`
407
+ code: kubb_kit.Diagnostics.code.invalidPluginOptions,
408
+ message: `Multiple client plugins are registered (${registered.map((name) => `\`@kubb/${name}\``).join(", ")}) and \`client\` is not set.`,
409
+ help: "Set `client: 'fetch' | 'axios' | 'client'` to choose which client the hooks call, or register a single client plugin."
418
410
  };
419
411
  return {
420
412
  kind: "error",
421
- message: "No client plugin is registered. Add `@kubb/plugin-axios`, `@kubb/plugin-fetch`, or `@kubb/plugin-client` to `plugins` so the generated code has an HTTP client to call."
413
+ code: kubb_kit.Diagnostics.code.missingDependency,
414
+ message: "No client plugin is registered.",
415
+ help: "Add `@kubb/plugin-fetch`, `@kubb/plugin-axios`, or `@kubb/plugin-client` to `plugins` so the generated code has an HTTP client to call."
422
416
  };
423
417
  }
424
418
  /**
425
- * Resolves the contract client during a consumer plugin's setup hook. Extracts the plugin names
426
- * from the raw `plugins` config, applies {@link resolveClient}, and throws the diagnostic on a
427
- * misconfiguration so every consumer fails fast with the same message.
419
+ * Resolves the contract client during a consumer plugin's setup hook.
420
+ * It extracts the plugin names from the raw `plugins` config and applies {@link resolveClient}.
421
+ * On a misconfiguration it throws a config diagnostic tagged with `plugin`, so every consumer
422
+ * fails fast with the same message.
428
423
  */
429
424
  function resolveContractClient(options) {
430
- const { client, plugins = [] } = options;
425
+ const { plugin, client, plugins = [] } = options;
431
426
  const resolved = resolveClient({
432
427
  client,
433
428
  pluginNames: plugins.map((plugin) => plugin.name).filter((name) => Boolean(name))
434
429
  });
435
- if (resolved.kind === "error") throw new Error(resolved.message);
430
+ if (resolved.kind === "error") {
431
+ const { code, message, help } = resolved;
432
+ throw new kubb_kit.Diagnostics.Error({
433
+ code,
434
+ severity: "error",
435
+ message,
436
+ help,
437
+ location: { kind: "config" },
438
+ plugin
439
+ });
440
+ }
436
441
  return resolved;
437
442
  }
438
443
  //#endregion
@@ -496,6 +501,95 @@ function resolveClientOperation(options) {
496
501
  });
497
502
  }
498
503
  //#endregion
504
+ //#region ../../internals/tanstack-query/src/components/HookFile.tsx
505
+ /**
506
+ * Resolves what every TanStack hook file shares: its file, the `@kubb/plugin-ts` file and type names, banner and footer.
507
+ */
508
+ function resolveHookFile(node, ctx, options) {
509
+ const { name, output, group, contractOp, keyTypeName, extraTypeNames = [] } = options;
510
+ const { config, root, resolver } = ctx;
511
+ const pluginTs = ctx.requirePlugin(_kubb_plugin_ts.pluginTsName);
512
+ const tsResolver = ctx.driver.getResolver(_kubb_plugin_ts.pluginTsName);
513
+ const file = resolver.file({
514
+ ...operationFileEntry(node, name),
515
+ root,
516
+ output,
517
+ group: group ?? void 0
518
+ });
519
+ const fileTs = resolveDependencyOperationFile({
520
+ cache: ctx.cache,
521
+ node,
522
+ resolver: tsResolver,
523
+ root,
524
+ output: pluginTs.options?.output ?? output,
525
+ group: pluginTs.options?.group
526
+ });
527
+ const importedTypeNames = [
528
+ tsResolver.response.options(node),
529
+ ...extraTypeNames,
530
+ ...resolveOperationTypeNames(node, tsResolver, {
531
+ exclude: keyTypeName ? [keyTypeName] : void 0,
532
+ order: "body-response-first",
533
+ includeParams: false
534
+ })
535
+ ].filter((typeName) => Boolean(typeName));
536
+ const fileMeta = {
537
+ path: file.path,
538
+ baseName: file.baseName
539
+ };
540
+ return {
541
+ file,
542
+ fileTs,
543
+ tsResolver,
544
+ contractOp,
545
+ importedTypeNames,
546
+ banner: resolver.default.banner(ctx.meta, {
547
+ output,
548
+ config,
549
+ file: fileMeta
550
+ }),
551
+ footer: resolver.default.footer(ctx.meta, {
552
+ output,
553
+ config,
554
+ file: fileMeta
555
+ })
556
+ };
557
+ }
558
+ /**
559
+ * The `<File>` shell shared by the TanStack hook generators; renders `children` after the imports.
560
+ */
561
+ function HookFile({ hook, imports, children }) {
562
+ const { file, fileTs, contractOp, importedTypeNames, banner, footer } = hook;
563
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
564
+ baseName: file.baseName,
565
+ path: file.path,
566
+ meta: file.meta,
567
+ banner,
568
+ footer,
569
+ children: [
570
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
571
+ name: [contractOp.name],
572
+ root: file.path,
573
+ path: contractOp.path
574
+ }),
575
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
576
+ name: ["RequestConfig", "ResponseErrorConfig"],
577
+ root: contractOp.clientPathIsFile ? file.path : void 0,
578
+ path: contractOp.clientPath,
579
+ isTypeOnly: true
580
+ }),
581
+ imports,
582
+ fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
583
+ name: Array.from(new Set(importedTypeNames)),
584
+ root: file.path,
585
+ path: fileTs.path,
586
+ isTypeOnly: true
587
+ }),
588
+ children
589
+ ]
590
+ });
591
+ }
592
+ //#endregion
499
593
  //#region ../../internals/tanstack-query/src/utils.ts
500
594
  /**
501
595
  * The grouped request options, ordered for both the destructured signature and the
@@ -618,6 +712,19 @@ function buildCallResultBody(call, options = {}) {
618
712
  return `return ${call}.unwrap()`;
619
713
  }
620
714
  /**
715
+ * Builds the `TData` / `TError` type expressions shared by every generated hook, joining the resolved
716
+ * success responses into `TData` and wrapping the error responses in `ResponseErrorConfig<...>`.
717
+ */
718
+ function buildResponseTypes(node, resolver) {
719
+ const successNames = resolveSuccessNames(node, resolver);
720
+ const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
721
+ const errorNames = resolveErrorNames(node, resolver);
722
+ return {
723
+ TData: responseName,
724
+ TError: `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`
725
+ };
726
+ }
727
+ /**
621
728
  * Applies the shared query defaults during plugin setup: `false` disables query generation, and an
622
729
  * object merges over `methods: ['GET', 'QUERY']` and the plugin's runtime `importPath`. QUERY
623
730
  * (RFC 10008) is a safe, idempotent read that carries its input in the body, so it is a query too.
@@ -677,13 +784,30 @@ const queryKeyGroupOrder = [
677
784
  * grouped `path`/`query`/`body` bindings.
678
785
  */
679
786
  function buildQueryKeyParams(node, options) {
680
- const { resolver } = options;
787
+ const { resolver, memberTypeWrapper } = options;
681
788
  const groupedParam = buildGroupedRequestParam(node, {
682
789
  resolver,
683
- keys: queryKeyGroupOrder
790
+ keys: queryKeyGroupOrder,
791
+ memberTypeWrapper
684
792
  });
685
793
  return (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedParam ? [groupedParam] : [] });
686
794
  }
795
+ /**
796
+ * Builds the hook parameter list: the grouped request param (omitted when `withRequest` is `false`) then `options` typed as `optionsType`.
797
+ */
798
+ function buildHookParams(node, options) {
799
+ const { resolver, optionsType, memberTypeWrapper, withRequest = true } = options;
800
+ const optionsParam = (0, _kubb_plugin_ts.createFunctionParameter)({
801
+ name: "options",
802
+ type: optionsType,
803
+ default: "{}"
804
+ });
805
+ const groupedParam = withRequest ? buildGroupedRequestParam(node, {
806
+ resolver,
807
+ memberTypeWrapper
808
+ }) : null;
809
+ return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [groupedParam, optionsParam].filter((param) => param !== null) });
810
+ }
687
811
  //#endregion
688
812
  //#region ../../internals/tanstack-query/src/components/MutationKey.tsx
689
813
  const declarationPrinter$4 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
@@ -691,7 +815,7 @@ const mutationKeyTransformer = ({ node }) => {
691
815
  if (!node.path) return [];
692
816
  return [`{ url: '${kubb_kit.Url.toPath(node.path)}' }`];
693
817
  };
694
- function MutationKey$1({ name, node, transformer }) {
818
+ function MutationKey({ name, node, transformer, typeName }) {
695
819
  const paramsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: [] });
696
820
  const paramsSignature = declarationPrinter$4.print(paramsNode) ?? "";
697
821
  const keys = (transformer ?? mutationKeyTransformer)({
@@ -699,7 +823,7 @@ function MutationKey$1({ name, node, transformer }) {
699
823
  casing: "camelcase",
700
824
  variant: "mutation"
701
825
  });
702
- return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
826
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
703
827
  name,
704
828
  isExportable: true,
705
829
  isIndexable: true,
@@ -710,9 +834,18 @@ function MutationKey$1({ name, node, transformer }) {
710
834
  singleLine: true,
711
835
  children: `[${keys.join(", ")}] as const`
712
836
  })
713
- });
837
+ }), typeName && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
838
+ name: typeName,
839
+ isExportable: true,
840
+ isIndexable: true,
841
+ isTypeOnly: true,
842
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Type, {
843
+ export: true,
844
+ name: typeName,
845
+ children: `ReturnType<typeof ${name}>`
846
+ })
847
+ })] });
714
848
  }
715
- __name(MutationKey$1, "MutationKey");
716
849
  //#endregion
717
850
  //#region ../../internals/tanstack-query/src/resolver.ts
718
851
  /**
@@ -781,8 +914,11 @@ const queryKeyTransformer = ({ node, variant }) => {
781
914
  if (node.requestBody?.content?.[0]?.schema) result.push("...(body !== undefined ? [body] : [])");
782
915
  return result;
783
916
  };
784
- function QueryKey({ name, node, tsResolver, typeName, transformer, variant = "query" }) {
785
- const paramsNode = buildQueryKeyParams(node, { resolver: tsResolver });
917
+ function QueryKey({ name, node, tsResolver, typeName, transformer, variant = "query", memberTypeWrapper, exportType }) {
918
+ const paramsNode = buildQueryKeyParams(node, {
919
+ resolver: tsResolver,
920
+ memberTypeWrapper
921
+ });
786
922
  const paramsSignature = declarationPrinter$3.print(paramsNode) ?? "";
787
923
  const keys = (transformer ?? queryKeyTransformer)({
788
924
  node,
@@ -802,9 +938,12 @@ function QueryKey({ name, node, tsResolver, typeName, transformer, variant = "qu
802
938
  })
803
939
  }), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
804
940
  name: typeName,
941
+ isExportable: exportType,
942
+ isIndexable: exportType,
805
943
  isTypeOnly: true,
806
944
  children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Type, {
807
945
  name: typeName,
946
+ export: exportType,
808
947
  children: `ReturnType<typeof ${name}>`
809
948
  })
810
949
  })] });
@@ -815,11 +954,7 @@ const declarationPrinter$2 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "decla
815
954
  const callPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
816
955
  function buildMutationParamsNode(node, options) {
817
956
  const { mutationKeyTypeName, mutationArgTypeName, resolver } = options;
818
- const successNames = resolveSuccessNames(node, resolver);
819
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
820
- const errorNames = resolveErrorNames(node, resolver);
821
- const TData = responseName;
822
- const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
957
+ const { TData, TError } = buildResponseTypes(node, resolver);
823
958
  return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
824
959
  name: "options",
825
960
  type: `{
@@ -831,11 +966,7 @@ function buildMutationParamsNode(node, options) {
831
966
  })] });
832
967
  }
833
968
  function Mutation({ name, clientName, mutationKeyName, mutationKeyTypeName, mutationArgTypeName, node, tsResolver, returnType = "full" }) {
834
- const successNames = resolveSuccessNames(node, tsResolver);
835
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
836
- const errorNames = resolveErrorNames(node, tsResolver);
837
- const TData = responseName;
838
- const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
969
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
839
970
  const groupedParam = buildGroupedRequestParam(node, { resolver: tsResolver });
840
971
  const hasMutationParams = groupedParam !== null;
841
972
  const groupedParamsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedParam ? [groupedParam] : [] });
@@ -892,62 +1023,99 @@ function Mutation({ name, clientName, mutationKeyName, mutationKeyTypeName, muta
892
1023
  })] });
893
1024
  }
894
1025
  //#endregion
895
- //#region src/components/MutationKey.tsx
896
- function MutationKey({ name, typeName, node, transformer }) {
897
- return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(MutationKey$1, {
898
- name,
899
- node,
900
- transformer
901
- }), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
902
- name: typeName,
903
- isExportable: true,
904
- isIndexable: true,
905
- isTypeOnly: true,
906
- children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Type, {
907
- export: true,
908
- name: typeName,
909
- children: `ReturnType<typeof ${name}>`
910
- })
911
- })] });
912
- }
1026
+ //#region src/generators/mutationGenerator.tsx
1027
+ /**
1028
+ * Built-in generator for `useSWRMutation` hooks. Emits one `useFooMutation` hook
1029
+ * per POST/PUT/DELETE operation (configurable via `mutation.methods`) plus
1030
+ * the matching `fooMutationKey` helper.
1031
+ */
1032
+ const mutationGenerator = (0, kubb_kit.defineGenerator)({
1033
+ name: "swr-mutation",
1034
+ renderer: kubb_jsx.jsxRenderer,
1035
+ operation(node, ctx) {
1036
+ if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
1037
+ const { driver, resolver, root } = ctx;
1038
+ const { output, query, mutation, client, group } = ctx.options;
1039
+ const { isMutation } = classifyOperation(node, {
1040
+ query,
1041
+ mutation
1042
+ });
1043
+ if (!isMutation) return null;
1044
+ const importPath = mutation ? mutation.importPath : "swr/mutation";
1045
+ const contractOp = resolveClientOperation({
1046
+ clientPlugin: { pluginName: client.pluginName },
1047
+ driver,
1048
+ node,
1049
+ root,
1050
+ output,
1051
+ cache: ctx.cache
1052
+ });
1053
+ if (!contractOp) return null;
1054
+ const mutationHookName = resolver.mutation.name(node);
1055
+ const mutationKeyName = resolver.mutation.keyName(node);
1056
+ const mutationKeyTypeName = resolver.mutation.keyTypeName(node);
1057
+ const mutationArgTypeName = resolver.mutation.argTypeName(node);
1058
+ const hook = resolveHookFile(node, ctx, {
1059
+ name: mutationHookName,
1060
+ output,
1061
+ group,
1062
+ contractOp
1063
+ });
1064
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(HookFile, {
1065
+ hook,
1066
+ children: [/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(MutationKey, {
1067
+ name: mutationKeyName,
1068
+ typeName: mutationKeyTypeName,
1069
+ node,
1070
+ transformer: ctx.options.mutationKey
1071
+ }), mutation && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [
1072
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1073
+ name: "useSWRMutation",
1074
+ path: importPath
1075
+ }),
1076
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1077
+ name: ["SWRMutationConfiguration"],
1078
+ path: importPath,
1079
+ isTypeOnly: true
1080
+ }),
1081
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Mutation, {
1082
+ name: mutationHookName,
1083
+ clientName: contractOp.name,
1084
+ mutationKeyName,
1085
+ mutationKeyTypeName,
1086
+ mutationArgTypeName,
1087
+ node,
1088
+ tsResolver: hook.tsResolver,
1089
+ returnType: contractOp.returnType
1090
+ })
1091
+ ] })]
1092
+ });
1093
+ }
1094
+ });
913
1095
  //#endregion
914
1096
  //#region src/components/Query.tsx
915
1097
  const declarationPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
916
1098
  const callPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
917
- function buildQueryParamsNode(node, options) {
918
- const { resolver } = options;
919
- const successNames = resolveSuccessNames(node, resolver);
920
- const responseName = successNames.length > 0 ? successNames.join(" | ") : resolver.response.response(node);
921
- const errorNames = resolveErrorNames(node, resolver);
922
- const TData = responseName;
923
- const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
924
- const optionsParam = (0, _kubb_plugin_ts.createFunctionParameter)({
925
- name: "options",
926
- type: `{
927
- query?: SWRConfiguration<${[TData, TError].join(", ")}>,
928
- client?: ${buildClientOptionType()},
929
- shouldFetch?: boolean,
930
- immutable?: boolean
931
- }`,
932
- default: "{}"
933
- });
934
- const groupedParam = buildGroupedRequestParam(node, { resolver });
935
- return (0, _kubb_plugin_ts.createFunctionParameters)({ params: [groupedParam, optionsParam].filter((param) => param !== null) });
936
- }
937
1099
  function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, node, tsResolver }) {
938
- const successNames = resolveSuccessNames(node, tsResolver);
939
- const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.response.response(node);
940
- const errorNames = resolveErrorNames(node, tsResolver);
1100
+ const { TData, TError } = buildResponseTypes(node, tsResolver);
941
1101
  const generics = [
942
- responseName,
943
- `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
1102
+ TData,
1103
+ TError,
944
1104
  `${queryKeyTypeName} | null`
945
1105
  ];
946
1106
  const queryKeyParamsNode = buildQueryKeyParams(node, { resolver: tsResolver });
947
1107
  const queryKeyParamsCall = callPrinter.print(queryKeyParamsNode) ?? "";
948
1108
  const queryOptionsParamsNode = buildQueryOptionsParams(node, { resolver: tsResolver });
949
1109
  const queryOptionsParamsCall = callPrinter.print(queryOptionsParamsNode) ?? "";
950
- const paramsNode = buildQueryParamsNode(node, { resolver: tsResolver });
1110
+ const paramsNode = buildHookParams(node, {
1111
+ resolver: tsResolver,
1112
+ optionsType: `{
1113
+ query?: SWRConfiguration<${[TData, TError].join(", ")}>,
1114
+ client?: ${buildClientOptionType()},
1115
+ shouldFetch?: boolean,
1116
+ immutable?: boolean
1117
+ }`
1118
+ });
951
1119
  const paramsSignature = declarationPrinter$1.print(paramsNode) ?? "";
952
1120
  return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
953
1121
  name,
@@ -1008,134 +1176,6 @@ function QueryOptions({ name, clientName, node, tsResolver, returnType = "full"
1008
1176
  });
1009
1177
  }
1010
1178
  //#endregion
1011
- //#region src/generators/mutationGenerator.tsx
1012
- /**
1013
- * Built-in generator for `useSWRMutation` hooks. Emits one `useFooMutation` hook
1014
- * per POST/PUT/DELETE operation (configurable via `mutation.methods`) plus
1015
- * the matching `fooMutationKey` helper.
1016
- */
1017
- const mutationGenerator = (0, kubb_kit.defineGenerator)({
1018
- name: "swr-mutation",
1019
- renderer: kubb_jsx.jsxRenderer,
1020
- operation(node, ctx) {
1021
- if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
1022
- const { config, driver, resolver, root } = ctx;
1023
- const { output, query, mutation, client, group } = ctx.options;
1024
- const pluginTs = ctx.requirePlugin(_kubb_plugin_ts.pluginTsName);
1025
- const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1026
- const { isMutation } = classifyOperation(node, {
1027
- query,
1028
- mutation
1029
- });
1030
- if (!isMutation) return null;
1031
- const importPath = mutation ? mutation.importPath : "swr/mutation";
1032
- const contractOp = resolveClientOperation({
1033
- clientPlugin: { pluginName: client.pluginName },
1034
- driver,
1035
- node,
1036
- root,
1037
- output,
1038
- cache: ctx.cache
1039
- });
1040
- if (!contractOp) return null;
1041
- const mutationHookName = resolver.mutation.name(node);
1042
- const mutationKeyName = resolver.mutation.keyName(node);
1043
- const mutationKeyTypeName = resolver.mutation.keyTypeName(node);
1044
- const mutationArgTypeName = resolver.mutation.argTypeName(node);
1045
- const meta = {
1046
- file: resolver.file({
1047
- name: mutationHookName,
1048
- extname: ".ts",
1049
- tag: node.tags[0] ?? "default",
1050
- path: node.path,
1051
- root,
1052
- output,
1053
- group
1054
- }),
1055
- fileTs: resolveDependencyOperationFile({
1056
- cache: ctx.cache,
1057
- node,
1058
- resolver: tsResolver,
1059
- root,
1060
- output: pluginTs.options?.output ?? output,
1061
- group: pluginTs.options?.group
1062
- })
1063
- };
1064
- const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
1065
- order: "body-response-first",
1066
- includeParams: false
1067
- })].filter((name) => Boolean(name));
1068
- const calledClientName = contractOp.name;
1069
- return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
1070
- baseName: meta.file.baseName,
1071
- path: meta.file.path,
1072
- meta: meta.file.meta,
1073
- banner: resolver.default.banner(ctx.meta, {
1074
- output,
1075
- config,
1076
- file: {
1077
- path: meta.file.path,
1078
- baseName: meta.file.baseName
1079
- }
1080
- }),
1081
- footer: resolver.default.footer(ctx.meta, {
1082
- output,
1083
- config,
1084
- file: {
1085
- path: meta.file.path,
1086
- baseName: meta.file.baseName
1087
- }
1088
- }),
1089
- children: [
1090
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1091
- name: [contractOp.name],
1092
- root: meta.file.path,
1093
- path: contractOp.path
1094
- }),
1095
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1096
- name: ["RequestConfig", "ResponseErrorConfig"],
1097
- root: contractOp.clientPathIsFile ? meta.file.path : void 0,
1098
- path: contractOp.clientPath,
1099
- isTypeOnly: true
1100
- }),
1101
- meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1102
- name: Array.from(new Set(importedTypeNames)),
1103
- root: meta.file.path,
1104
- path: meta.fileTs.path,
1105
- isTypeOnly: true
1106
- }),
1107
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(MutationKey, {
1108
- name: mutationKeyName,
1109
- typeName: mutationKeyTypeName,
1110
- node,
1111
- transformer: ctx.options.mutationKey
1112
- }),
1113
- mutation && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [
1114
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1115
- name: "useSWRMutation",
1116
- path: importPath
1117
- }),
1118
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1119
- name: ["SWRMutationConfiguration"],
1120
- path: importPath,
1121
- isTypeOnly: true
1122
- }),
1123
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Mutation, {
1124
- name: mutationHookName,
1125
- clientName: calledClientName,
1126
- mutationKeyName,
1127
- mutationKeyTypeName,
1128
- mutationArgTypeName,
1129
- node,
1130
- tsResolver,
1131
- returnType: contractOp.returnType
1132
- })
1133
- ] })
1134
- ]
1135
- });
1136
- }
1137
- });
1138
- //#endregion
1139
1179
  //#region src/generators/queryGenerator.tsx
1140
1180
  /**
1141
1181
  * Built-in generator for `useSWR` hooks. Emits one `useFoo` hook per read operation plus the
@@ -1146,10 +1186,8 @@ const queryGenerator = (0, kubb_kit.defineGenerator)({
1146
1186
  renderer: kubb_jsx.jsxRenderer,
1147
1187
  operation(node, ctx) {
1148
1188
  if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
1149
- const { config, driver, resolver, root } = ctx;
1189
+ const { driver, resolver, root } = ctx;
1150
1190
  const { output, query, mutation, client, group } = ctx.options;
1151
- const pluginTs = ctx.requirePlugin(_kubb_plugin_ts.pluginTsName);
1152
- const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
1153
1191
  const { isQuery } = classifyOperation(node, {
1154
1192
  query,
1155
1193
  mutation
@@ -1169,69 +1207,17 @@ const queryGenerator = (0, kubb_kit.defineGenerator)({
1169
1207
  const queryOptionsName = resolver.query.optionsName(node);
1170
1208
  const queryKeyName = resolver.query.keyName(node);
1171
1209
  const queryKeyTypeName = resolver.query.keyTypeName(node);
1172
- const meta = {
1173
- file: resolver.file({
1174
- name: queryName,
1175
- extname: ".ts",
1176
- tag: node.tags[0] ?? "default",
1177
- path: node.path,
1178
- root,
1179
- output,
1180
- group
1181
- }),
1182
- fileTs: resolveDependencyOperationFile({
1183
- cache: ctx.cache,
1184
- node,
1185
- resolver: tsResolver,
1186
- root,
1187
- output: pluginTs.options?.output ?? output,
1188
- group: pluginTs.options?.group
1189
- })
1190
- };
1191
- const importedTypeNames = [tsResolver.response.options(node), ...resolveOperationTypeNames(node, tsResolver, {
1192
- exclude: [queryKeyTypeName],
1193
- order: "body-response-first",
1194
- includeParams: false
1195
- })].filter((name) => Boolean(name));
1196
- const calledClientName = contractOp.name;
1197
- return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
1198
- baseName: meta.file.baseName,
1199
- path: meta.file.path,
1200
- meta: meta.file.meta,
1201
- banner: resolver.default.banner(ctx.meta, {
1202
- output,
1203
- config,
1204
- file: {
1205
- path: meta.file.path,
1206
- baseName: meta.file.baseName
1207
- }
1208
- }),
1209
- footer: resolver.default.footer(ctx.meta, {
1210
- output,
1211
- config,
1212
- file: {
1213
- path: meta.file.path,
1214
- baseName: meta.file.baseName
1215
- }
1216
- }),
1210
+ const hook = resolveHookFile(node, ctx, {
1211
+ name: queryName,
1212
+ output,
1213
+ group,
1214
+ contractOp,
1215
+ keyTypeName: queryKeyTypeName
1216
+ });
1217
+ const { tsResolver } = hook;
1218
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(HookFile, {
1219
+ hook,
1217
1220
  children: [
1218
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1219
- name: [contractOp.name],
1220
- root: meta.file.path,
1221
- path: contractOp.path
1222
- }),
1223
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1224
- name: ["RequestConfig", "ResponseErrorConfig"],
1225
- root: contractOp.clientPathIsFile ? meta.file.path : void 0,
1226
- path: contractOp.clientPath,
1227
- isTypeOnly: true
1228
- }),
1229
- meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1230
- name: Array.from(new Set(importedTypeNames)),
1231
- root: meta.file.path,
1232
- path: meta.fileTs.path,
1233
- isTypeOnly: true
1234
- }),
1235
1221
  /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryKey, {
1236
1222
  name: queryKeyName,
1237
1223
  typeName: queryKeyTypeName,
@@ -1242,7 +1228,7 @@ const queryGenerator = (0, kubb_kit.defineGenerator)({
1242
1228
  }),
1243
1229
  /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(QueryOptions, {
1244
1230
  name: queryOptionsName,
1245
- clientName: calledClientName,
1231
+ clientName: contractOp.name,
1246
1232
  node,
1247
1233
  tsResolver,
1248
1234
  returnType: contractOp.returnType
@@ -1349,6 +1335,7 @@ const pluginSwr = (0, kubb_kit.defineExtension)({
1349
1335
  return {
1350
1336
  output,
1351
1337
  client: resolveContractClient({
1338
+ plugin: pluginSwrName,
1352
1339
  client,
1353
1340
  plugins: (0, kubb_kit.useConfig)().plugins
1354
1341
  }),