@kubb/plugin-fetch 5.0.0-beta.84 → 5.0.0-beta.86

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
@@ -71,31 +71,6 @@ function pascalCase(text, { prefix = "", suffix = "" } = {}) {
71
71
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
72
72
  }
73
73
  //#endregion
74
- //#region ../../internals/utils/src/fs.ts
75
- /**
76
- * Builds a nested file path from a dotted name. Splits on dots that precede a letter
77
- * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
78
- * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
79
- *
80
- * Empty segments are dropped before joining. They arise when the name starts with a dot
81
- * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
82
- * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
83
- * absolute path, letting generated files escape the configured output directory.
84
- *
85
- * @example Nested path from a dotted name
86
- * `toFilePath('pet.petId') // 'pet/petId'`
87
- *
88
- * @example PascalCase the final segment
89
- * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
90
- *
91
- * @example Suffix applied to the final segment only
92
- * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
93
- */
94
- function toFilePath(name, caseLast = camelCase) {
95
- const parts = name.split(/\.(?=[a-zA-Z])/);
96
- return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
97
- }
98
- //#endregion
99
74
  //#region ../../internals/utils/src/reserved.ts
100
75
  /**
101
76
  * JavaScript and Java reserved words.
@@ -219,6 +194,23 @@ function ensureValidVarName(name) {
219
194
  return `_${name}`;
220
195
  }
221
196
  //#endregion
197
+ //#region ../../internals/utils/src/codegen.ts
198
+ /**
199
+ * Builds a JSDoc comment block from an array of lines. Returns `fallback` when there are no
200
+ * comments.
201
+ *
202
+ * @example
203
+ * ```ts
204
+ * buildJSDoc(['@type string', '@example hello'])
205
+ * // '/**\n * @type string\n * @example hello\n *\/\n '
206
+ * ```
207
+ */
208
+ function buildJSDoc(comments, options = {}) {
209
+ const { indent = " * ", suffix = "\n ", fallback = " " } = options;
210
+ if (comments.length === 0) return fallback;
211
+ return `/**\n${comments.map((c) => `${indent}${c}`).join("\n")}\n */${suffix}`;
212
+ }
213
+ //#endregion
222
214
  //#region ../../internals/utils/src/url.ts
223
215
  function transformParam(raw, casing) {
224
216
  const param = isValidVarName(raw) ? raw : camelCase(raw);
@@ -367,17 +359,45 @@ function dedupeByCasedName(params) {
367
359
  return true;
368
360
  });
369
361
  }
362
+ function buildParamsMapping(originalParams, mappedParams) {
363
+ const mapping = {};
364
+ let hasChanged = false;
365
+ originalParams.forEach((param, i) => {
366
+ const mappedName = mappedParams[i]?.name ?? param.name;
367
+ mapping[param.name] = mappedName;
368
+ if (param.name !== mappedName) hasChanged = true;
369
+ });
370
+ return hasChanged ? mapping : null;
371
+ }
372
+ function toAccess(object, name) {
373
+ return isValidVarName(name) ? `${object}.${name}` : `${object}[${JSON.stringify(name)}]`;
374
+ }
375
+ /**
376
+ * Renders the object-literal expression that renames the camelCased keys of a grouped request
377
+ * option back to the names the OpenAPI document declares, guarded so an omitted optional group
378
+ * stays omitted. Shared by the client and cypress generators, which pass a `buildParamsMapping`
379
+ * result and the source expression to read the keys from.
380
+ *
381
+ * @example
382
+ * ```ts
383
+ * buildParamsRemapExpression({ source: 'config.query', mapping: { include_deleted: 'includeDeleted' } })
384
+ * // 'config.query ? { "include_deleted": config.query.includeDeleted } : config.query'
385
+ * ```
386
+ */
387
+ function buildParamsRemapExpression({ source, mapping }) {
388
+ return `${source} ? { ${Object.entries(mapping).map(([originalName, casedName]) => `${JSON.stringify(originalName)}: ${toAccess(source, casedName)}`).join(", ")} } : ${source}`;
389
+ }
370
390
  //#endregion
371
391
  //#region ../../internals/shared/src/operation.ts
372
392
  /**
373
393
  * Builds the `ResolverFileParams` every operation generator passes to
374
- * `resolver.resolveFile`: a file named `name`, tagged by the operation's first
394
+ * `resolver.file`: a file named `name`, tagged by the operation's first
375
395
  * tag (or `'default'`), at the operation's path. Centralizes the entry object
376
396
  * that was repeated at dozens of call sites across the client and query plugins.
377
397
  *
378
398
  * @example
379
399
  * ```ts
380
- * resolver.resolveFile(operationFileEntry(node, node.operationId), { root, output, group })
400
+ * resolver.file(operationFileEntry(node, node.operationId), { root, output, group })
381
401
  * ```
382
402
  */
383
403
  function operationFileEntry(node, name, extname = ".ts") {
@@ -600,7 +620,7 @@ function resolveResponseValidator(validator) {
600
620
  * `<operation>ResponseSchema` is used; error bodies are never zod-parsed.
601
621
  */
602
622
  function buildZodResponseParse(node, zodResolver) {
603
- const name = zodResolver.resolveResponseName?.(node);
623
+ const name = zodResolver.response.response(node);
604
624
  return name ? {
605
625
  expression: name,
606
626
  importNames: [name]
@@ -613,7 +633,7 @@ function buildZodResponseParse(node, zodResolver) {
613
633
  */
614
634
  function buildZodErrorParse(node, zodResolver) {
615
635
  if (!node.responses.some((res) => !isSuccessStatusCode(res.statusCode) && res.content?.some((entry) => entry.schema))) return null;
616
- const name = zodResolver.resolveErrorName?.(node);
636
+ const name = zodResolver.response.error?.(node);
617
637
  return name ? {
618
638
  expression: name,
619
639
  importNames: [name]
@@ -688,6 +708,38 @@ function buildSecurityMetadata({ security }) {
688
708
  return `[${security.map(serializeAuth).join(", ")}]`;
689
709
  }
690
710
  //#endregion
711
+ //#region ../../internals/client/src/builders/paramsRemap.ts
712
+ /**
713
+ * Builds the call-config entries that rename the camelCased `query` and `headers` keys back to the
714
+ * names the OpenAPI document declares, so the wire format follows the spec while the generated
715
+ * types keep camelCase keys. Returns an empty array when no name changes. Path parameters need no
716
+ * remap because the URL template placeholders are renamed in sync with the `path` keys. Emit the
717
+ * entries after the `...config` spread so they override the camelCased groups the caller passes in.
718
+ *
719
+ * @example
720
+ * ```ts
721
+ * // a query param named include_deleted in the spec
722
+ * buildParamsRemap({ node }) // ['query: config.query ? { "include_deleted": config.query.includeDeleted } : config.query']
723
+ * ```
724
+ */
725
+ function buildParamsRemap({ node }) {
726
+ if (!kubb_kit.ast.isHttpOperationNode(node)) return [];
727
+ const original = getOperationParameters(node, { paramsCasing: "original" });
728
+ const cased = getOperationParameters(node);
729
+ const queryMapping = buildParamsMapping(original.query, cased.query);
730
+ const headerMapping = buildParamsMapping(original.header, cased.header);
731
+ const entries = [];
732
+ if (queryMapping) entries.push(`query: ${buildParamsRemapExpression({
733
+ source: "config.query",
734
+ mapping: queryMapping
735
+ })}`);
736
+ if (headerMapping) entries.push(`headers: ${buildParamsRemapExpression({
737
+ source: "config.headers",
738
+ mapping: headerMapping
739
+ })}`);
740
+ return entries;
741
+ }
742
+ //#endregion
691
743
  //#region ../../internals/client/src/builders/generics.ts
692
744
  /**
693
745
  * Builds the `RequestResult` generic arguments for one operation: the plugin-ts per-status responses
@@ -698,7 +750,7 @@ function buildSecurityMetadata({ security }) {
698
750
  * `buildRequestResultGenerics({ node, tsResolver }) // 'AddPetResponses, ThrowOnError'`
699
751
  */
700
752
  function buildRequestResultGenerics({ node, tsResolver }) {
701
- return `${tsResolver.resolveResponsesName(node)}, ThrowOnError`;
753
+ return `${tsResolver.response.responses(node)}, ThrowOnError`;
702
754
  }
703
755
  //#endregion
704
756
  //#region ../../internals/client/src/builders/returnStatement.ts
@@ -721,41 +773,42 @@ function buildReturnStatement({ node, tsResolver, callConfig }) {
721
773
  const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
722
774
  /**
723
775
  * Builds the grouped-options signature for one operation: a single `options` object whose `TData`
724
- * is the plugin-ts `<Name>RequestConfig` (carrying a literal `url`), and a `RequestResult` return type
776
+ * is the plugin-ts `<Name>Options` (carrying a literal `url`), and a `RequestResult` return type
725
777
  * keyed to the plugin-ts per-status responses record. There are no positional arguments.
726
778
  *
727
- * The generated file imports `<Name>RequestConfig` and `<Name>Responses` and uses them directly, so no
779
+ * The generated file imports `<Name>Options` and `<Name>Responses` and uses them directly, so no
728
780
  * per-operation input type has to be emitted.
729
781
  */
730
782
  function buildGroupedOptionsSignature({ node, tsResolver }) {
731
- const requestConfigName = tsResolver.resolveRequestConfigName(node);
732
- const responsesName = tsResolver.resolveResponsesName(node);
783
+ const optionsName = tsResolver.response.options(node);
784
+ const responsesName = tsResolver.response.responses(node);
733
785
  const resultGenerics = buildRequestResultGenerics({
734
786
  node,
735
787
  tsResolver
736
788
  });
737
789
  const { isOptional } = getRequestGroupOptionality(node);
738
790
  return {
739
- dataTypeName: requestConfigName,
791
+ dataTypeName: optionsName,
740
792
  paramsSignature: declarationPrinter.print((0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
741
793
  name: "options",
742
- type: `Options<${requestConfigName}, ThrowOnError>`,
794
+ type: `Options<${optionsName}, ThrowOnError>`,
743
795
  ...isOptional ? { default: "{}" } : {}
744
796
  })] })) ?? "",
745
797
  returnType: `Promise<RequestResult<${resultGenerics}>>`,
746
798
  generics: ["ThrowOnError extends boolean = true"],
747
- importedTypeNames: [requestConfigName, responsesName]
799
+ importedTypeNames: [optionsName, responsesName]
748
800
  };
749
801
  }
750
802
  //#endregion
751
803
  //#region ../../internals/client/src/builders/styles.ts
752
804
  /**
753
- * Renders a parameter name as an object-literal key, quoting it when the camelCased name is not a
754
- * bare identifier (for example a name that starts with a digit) so the emitted literal stays valid.
805
+ * Renders a parameter name as an object-literal key, quoted when it is not a bare identifier.
806
+ * Path keys are camelCased to match the URL template placeholders. Query, header, and cookie keys
807
+ * keep the spec name, matching the remapped keys the runtime serializes.
755
808
  */
756
- function toKey(name) {
757
- const cased = camelCase(name);
758
- return isValidVarName(cased) ? cased : JSON.stringify(cased);
809
+ function toKey(name, location) {
810
+ const key = location === "path" ? camelCase(name) : name;
811
+ return isValidVarName(key) ? key : JSON.stringify(key);
759
812
  }
760
813
  /**
761
814
  * Serializes one parameter's metadata into a `{ style, explode }` literal, or `null` when the
@@ -769,8 +822,9 @@ function serializeParameter(parameter) {
769
822
  return parts.length > 0 ? `{ ${parts.join(", ")} }` : null;
770
823
  }
771
824
  /**
772
- * Builds the per-operation `styles` literal from the operation's parameters, grouped by location and
773
- * keyed by the camelCased parameter name to match the generated `path` / `query` / `headers` keys.
825
+ * Builds the per-operation `styles` literal from the operation's parameters, grouped by location.
826
+ * Path entries are keyed by the camelCased name to match the URL template placeholders; query,
827
+ * header, and cookie entries keep the spec name to match the keys the runtime serializes.
774
828
  * Only parameters whose source defines `style` or `explode` are emitted, so calls without
775
829
  * serialization metadata keep the runtime defaults and existing output is unchanged. Returns `null`
776
830
  * when no parameter carries metadata.
@@ -792,7 +846,7 @@ function buildStyles({ node }) {
792
846
  for (const parameter of node.parameters) {
793
847
  const literal = serializeParameter(parameter);
794
848
  if (!literal) continue;
795
- groups[parameter.in].push(`${toKey(parameter.name)}: ${literal}`);
849
+ groups[parameter.in].push(`${toKey(parameter.name, parameter.in)}: ${literal}`);
796
850
  }
797
851
  const locations = Object.keys(groups).filter((location) => groups[location].length > 0);
798
852
  if (locations.length === 0) return null;
@@ -808,7 +862,7 @@ function buildStyles({ node }) {
808
862
  function buildValidatorHooks({ node, validator, zodResolver }) {
809
863
  const importedZodNames = [];
810
864
  const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
811
- const zodRequestName = zodResolver && resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.resolveDataName?.(node) : null;
865
+ const zodRequestName = zodResolver && resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.response.body(node) : null;
812
866
  const request = zodRequestName ?? null;
813
867
  if (zodRequestName) importedZodNames.push(zodRequestName);
814
868
  const responseParse = zodResolver && resolveResponseValidator(validator) === "zod" ? buildZodResponseParse(node, zodResolver) : null;
@@ -865,9 +919,10 @@ function Operation({ name, node, tsResolver, zodResolver, validator, security, i
865
919
  validatorLiteral,
866
920
  contentTypeLiteral,
867
921
  responseTypeLiteral,
868
- "...config"
922
+ "...config",
923
+ ...buildParamsRemap({ node })
869
924
  ].filter(Boolean).join(", ")} }`;
870
- const eventType = `SuccessOf<${tsResolver.resolveResponsesName(node)}>`;
925
+ const eventType = `SuccessOf<${tsResolver.response.responses(node)}>`;
871
926
  const returnType = eventStream ? `Promise<EventStreamResult<${eventType}>>` : signature.returnType;
872
927
  const returnStatement = eventStream ? `return toEventStream<${eventType}>(request(${callConfig}))` : buildReturnStatement({
873
928
  node,
@@ -918,7 +973,8 @@ function buildCallConfig({ node, validator, zodResolver, security }) {
918
973
  `url: '${Url.toCasedTemplate(node.path, { casing: "camelcase" })}'`,
919
974
  securityLiteral ? `security: ${securityLiteral}` : null,
920
975
  validatorLiteral,
921
- "...config"
976
+ "...config",
977
+ ...buildParamsRemap({ node })
922
978
  ].filter(Boolean).join(", ")} }`;
923
979
  }
924
980
  /**
@@ -944,7 +1000,7 @@ function buildSdkMethod({ node, name, tsResolver, zodResolver, validator, securi
944
1000
  })
945
1001
  });
946
1002
  const generics = signature.generics.length ? `<${signature.generics.join(", ")}>` : "";
947
- const jsdoc = kubb_kit.ast.buildJSDoc(buildOperationComments(node, {
1003
+ const jsdoc = buildJSDoc(buildOperationComments(node, {
948
1004
  link: "urlPath",
949
1005
  linkPosition: "beforeDeprecated",
950
1006
  splitLines: true
@@ -1014,15 +1070,15 @@ function SdkFacade({ name, isExportable = true, isIndexable = true, members, chi
1014
1070
  //#endregion
1015
1071
  //#region ../../internals/client/src/generators/sdkGenerator.tsx
1016
1072
  function resolveTypeImportNames(node, tsResolver) {
1017
- return [tsResolver.resolveRequestConfigName(node), tsResolver.resolveResponsesName(node)];
1073
+ return [tsResolver.response.options(node), tsResolver.response.responses(node)];
1018
1074
  }
1019
1075
  function resolveZodImportNames(node, zodResolver, validator) {
1020
1076
  const { query: queryParams } = getOperationParameters(node, { paramsCasing: "original" });
1021
1077
  return [
1022
- resolveResponseValidator(validator) === "zod" ? zodResolver.resolveResponseName?.(node) : null,
1078
+ resolveResponseValidator(validator) === "zod" ? zodResolver.response.response(node) : null,
1023
1079
  resolveResponseValidator(validator) === "zod" ? buildZodErrorParse(node, zodResolver)?.expression ?? null : null,
1024
- resolveRequestValidator(validator) === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null,
1025
- resolveQueryParamsValidator(validator) === "zod" && queryParams.length > 0 ? zodResolver.resolveQueryParamsName?.(node, queryParams[0]) : null
1080
+ resolveRequestValidator(validator) === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.response.body(node) : null,
1081
+ resolveQueryParamsValidator(validator) === "zod" && queryParams.length > 0 ? zodResolver.param.query(node, queryParams[0]) : null
1026
1082
  ].filter((n) => Boolean(n));
1027
1083
  }
1028
1084
  /**
@@ -1039,12 +1095,14 @@ function buildControllers(nodes, ctx) {
1039
1095
  const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) : null;
1040
1096
  const document = ctx.adapter.document;
1041
1097
  function buildOperationData(node) {
1042
- const typeFile = tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
1098
+ const typeFile = tsResolver.file({
1099
+ ...operationFileEntry(node, node.operationId),
1043
1100
  root,
1044
1101
  output: tsPluginOptions?.output ?? output,
1045
1102
  group: tsPluginOptions?.group
1046
1103
  });
1047
- const zodFile = zodResolver && pluginZod?.options ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
1104
+ const zodFile = zodResolver && pluginZod?.options ? zodResolver.file({
1105
+ ...operationFileEntry(node, node.operationId),
1048
1106
  root,
1049
1107
  output: pluginZod.options?.output ?? output,
1050
1108
  group: pluginZod.options?.group ?? void 0
@@ -1056,7 +1114,7 @@ function buildControllers(nodes, ctx) {
1056
1114
  }) : void 0;
1057
1115
  return {
1058
1116
  node,
1059
- name: resolver.resolveName(node.operationId),
1117
+ name: resolver.name(node.operationId),
1060
1118
  tsResolver,
1061
1119
  zodResolver,
1062
1120
  typeFile,
@@ -1067,12 +1125,11 @@ function buildControllers(nodes, ctx) {
1067
1125
  return nodes.reduce((acc, operationNode) => {
1068
1126
  if (!kubb_kit.ast.isHttpOperationNode(operationNode)) return acc;
1069
1127
  const tag = operationNode.tags[0];
1070
- const name = tag ? group?.name?.({ group: camelCase(tag) }) ?? resolver.resolveGroupName(tag) : resolver.resolveClassName("ApiClient");
1071
- const file = resolver.resolveFile({
1128
+ const name = tag ? group?.name?.({ group: camelCase(tag) }) ?? resolver.groupName(tag) : resolver.className("ApiClient");
1129
+ const file = resolver.file({
1072
1130
  name,
1073
1131
  extname: ".ts",
1074
- tag
1075
- }, {
1132
+ tag,
1076
1133
  root,
1077
1134
  output,
1078
1135
  group: group ?? void 0
@@ -1126,7 +1183,7 @@ function createSdkGenerator() {
1126
1183
  if (!ctx.driver.getPlugin(_kubb_plugin_ts.pluginTsName) || !sdk) return null;
1127
1184
  const controllers = buildControllers(nodes, ctx);
1128
1185
  const clientPath = node_path.default.resolve(root, ".kubb/client.ts");
1129
- const banner = (file) => resolver.resolveBanner(ctx.meta, {
1186
+ const banner = (file) => resolver.default.banner(ctx.meta, {
1130
1187
  output,
1131
1188
  config,
1132
1189
  file: {
@@ -1134,7 +1191,7 @@ function createSdkGenerator() {
1134
1191
  baseName: file.baseName
1135
1192
  }
1136
1193
  });
1137
- const footer = (file) => resolver.resolveFooter(ctx.meta, {
1194
+ const footer = (file) => resolver.default.footer(ctx.meta, {
1138
1195
  output,
1139
1196
  config,
1140
1197
  file: {
@@ -1201,28 +1258,26 @@ function createSdkGenerator() {
1201
1258
  ]
1202
1259
  }, file.path);
1203
1260
  };
1204
- if (sdk.mode === "flat") return renderClassFile(resolver.resolveClassName(sdk.name ?? "sdk"), resolver.resolveFile({
1261
+ if (sdk.mode === "flat") return renderClassFile(resolver.className(sdk.name ?? "sdk"), resolver.file({
1205
1262
  name: sdk.name ?? "sdk",
1206
- extname: ".ts"
1207
- }, {
1263
+ extname: ".ts",
1208
1264
  root,
1209
1265
  output,
1210
1266
  group: group ?? void 0
1211
1267
  }), controllers.flatMap((controller) => controller.operations));
1212
1268
  const classFiles = controllers.map(({ name, file, operations: ops }) => renderClassFile(name, file, ops));
1213
1269
  if (!sdk.name) return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx_jsx_runtime.Fragment, { children: classFiles });
1214
- const sdkFile = resolver.resolveFile({
1270
+ const sdkFile = resolver.file({
1215
1271
  name: sdk.name,
1216
- extname: ".ts"
1217
- }, {
1272
+ extname: ".ts",
1218
1273
  root,
1219
1274
  output,
1220
1275
  group: group ?? void 0
1221
1276
  });
1222
- const facadeName = resolver.resolveClassName(sdk.name);
1277
+ const facadeName = resolver.className(sdk.name);
1223
1278
  const members = controllers.map(({ name, tag }) => ({
1224
1279
  className: name,
1225
- propName: resolver.resolveClientPropertyName(tag ?? name)
1280
+ propName: resolver.propertyName(tag ?? name)
1226
1281
  }));
1227
1282
  return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [classFiles, /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
1228
1283
  baseName: sdkFile.baseName,
@@ -1262,38 +1317,27 @@ const defaultMacros = [kubb_kit.ast.macroSimplifyUnion];
1262
1317
  //#endregion
1263
1318
  //#region ../../internals/client/src/resolver.ts
1264
1319
  /**
1265
- * Default resolver shared by the client plugins. Functions and files use camelCase; classes and
1266
- * tag groups use PascalCase.
1320
+ * Default resolver shared by the client plugins. Functions and files inherit the built-in camelCase
1321
+ * `name` and `file`; classes and tag groups use PascalCase.
1267
1322
  *
1268
1323
  * @example
1269
1324
  * ```ts
1270
- * resolverClient.resolveName('show pet by id') // 'showPetById'
1271
- * resolverClient.resolveGroupName('pet') // 'PetClient'
1325
+ * resolverClient.name('show pet by id') // 'showPetById'
1326
+ * resolverClient.groupName('pet') // 'PetClient'
1272
1327
  * ```
1273
1328
  */
1274
- const resolverClient = (0, kubb_kit.defineResolver)(() => ({
1275
- name: "default",
1329
+ const resolverClient = (0, kubb_kit.createResolver)({
1276
1330
  pluginName: "plugin-contract-client",
1277
- default(name, type) {
1278
- if (type === "file") return toFilePath(name);
1279
- return ensureValidVarName(camelCase(name));
1280
- },
1281
- resolveName(name) {
1282
- return this.default(name, "function");
1283
- },
1284
- resolvePathName(name, type) {
1285
- return this.default(name, type);
1286
- },
1287
- resolveClassName(name) {
1331
+ className(name) {
1288
1332
  return ensureValidVarName(pascalCase(name));
1289
1333
  },
1290
- resolveGroupName(name) {
1334
+ groupName(name) {
1291
1335
  return ensureValidVarName(pascalCase(`${name} Client`));
1292
1336
  },
1293
- resolveClientPropertyName(name) {
1337
+ propertyName(name) {
1294
1338
  return ensureValidVarName(camelCase(name));
1295
1339
  }
1296
- }));
1340
+ });
1297
1341
  //#endregion
1298
1342
  //#region src/generators/clientGenerator.tsx
1299
1343
  /**
@@ -1314,25 +1358,28 @@ const clientGenerator = (0, kubb_kit.defineGenerator)({
1314
1358
  const pluginZod = resolveResponseValidator(validator) === "zod" || resolveRequestValidator(validator) === "zod" ? driver.getPlugin(_kubb_plugin_zod.pluginZodName) : null;
1315
1359
  const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) : null;
1316
1360
  const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
1317
- const importedTypeNames = [tsResolver.resolveRequestConfigName(node), tsResolver.resolveResponsesName(node)];
1361
+ const importedTypeNames = [tsResolver.response.options(node), tsResolver.response.responses(node)];
1318
1362
  const importedZodNames = zodResolver ? [
1319
- resolveResponseValidator(validator) === "zod" ? zodResolver.resolveResponseName?.(node) : null,
1363
+ resolveResponseValidator(validator) === "zod" ? zodResolver.response.response?.(node) : null,
1320
1364
  resolveResponseValidator(validator) === "zod" ? buildZodErrorParse(node, zodResolver)?.expression ?? null : null,
1321
- resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.resolveDataName?.(node) : null
1365
+ resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.response.body?.(node) : null
1322
1366
  ].filter((name) => Boolean(name)) : [];
1323
1367
  const meta = {
1324
- name: resolver.resolveName(node.operationId),
1325
- file: resolver.resolveFile(operationFileEntry(node, node.operationId), {
1368
+ name: resolver.name(node.operationId),
1369
+ file: resolver.file({
1370
+ ...operationFileEntry(node, node.operationId),
1326
1371
  root,
1327
1372
  output,
1328
1373
  group: group ?? void 0
1329
1374
  }),
1330
- fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
1375
+ fileTs: tsResolver.file({
1376
+ ...operationFileEntry(node, node.operationId),
1331
1377
  root,
1332
1378
  output: pluginTs.options?.output ?? output,
1333
1379
  group: pluginTs.options?.group ?? void 0
1334
1380
  }),
1335
- fileZod: zodResolver && pluginZod?.options ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
1381
+ fileZod: zodResolver && pluginZod?.options ? zodResolver.file({
1382
+ ...operationFileEntry(node, node.operationId),
1336
1383
  root,
1337
1384
  output: pluginZod.options.output ?? output,
1338
1385
  group: pluginZod.options?.group ?? void 0
@@ -1349,7 +1396,7 @@ const clientGenerator = (0, kubb_kit.defineGenerator)({
1349
1396
  baseName: meta.file.baseName,
1350
1397
  path: meta.file.path,
1351
1398
  meta: meta.file.meta,
1352
- banner: resolver.resolveBanner(ctx.meta, {
1399
+ banner: resolver.default.banner(ctx.meta, {
1353
1400
  output,
1354
1401
  config,
1355
1402
  file: {
@@ -1357,7 +1404,7 @@ const clientGenerator = (0, kubb_kit.defineGenerator)({
1357
1404
  baseName: meta.file.baseName
1358
1405
  }
1359
1406
  }),
1360
- footer: resolver.resolveFooter(ctx.meta, {
1407
+ footer: resolver.default.footer(ctx.meta, {
1361
1408
  output,
1362
1409
  config,
1363
1410
  file: {
@@ -1461,10 +1508,7 @@ const pluginFetch = (0, kubb_kit.definePlugin)((options) => {
1461
1508
  mode: sdk.mode ?? "tag",
1462
1509
  name: sdk.name
1463
1510
  } : void 0,
1464
- resolver: userResolver ? {
1465
- ...resolverClient,
1466
- ...userResolver
1467
- } : resolverClient
1511
+ resolver: userResolver ? kubb_kit.Resolver.merge(resolverClient, userResolver) : resolverClient
1468
1512
  };
1469
1513
  const selectedGenerators = resolved.sdk ? [createSdkGenerator()] : [clientGenerator];
1470
1514
  return {