@kubb/plugin-fetch 5.0.0-beta.85 → 5.0.0-beta.87

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.
@@ -196,7 +171,7 @@ const reservedWords = /* @__PURE__ */ new Set([
196
171
  */
197
172
  function isValidVarName(name) {
198
173
  if (!name || reservedWords.has(name)) return false;
199
- return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
174
+ return isIdentifier(name);
200
175
  }
201
176
  /**
202
177
  * Returns `name` when it's a syntactically valid JavaScript variable name,
@@ -218,6 +193,39 @@ function ensureValidVarName(name) {
218
193
  if (!name || isValidVarName(name)) return name;
219
194
  return `_${name}`;
220
195
  }
196
+ /**
197
+ * Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
198
+ *
199
+ * Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
200
+ * even though they are not valid variable names, so use this (not {@link isValidVarName}) when
201
+ * deciding whether an object key needs quoting.
202
+ *
203
+ * @example
204
+ * ```ts
205
+ * isIdentifier('name') // true
206
+ * isIdentifier('x-total')// false
207
+ * ```
208
+ */
209
+ function isIdentifier(name) {
210
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
211
+ }
212
+ //#endregion
213
+ //#region ../../internals/utils/src/codegen.ts
214
+ /**
215
+ * Builds a JSDoc comment block from an array of lines. Returns `fallback` when there are no
216
+ * comments.
217
+ *
218
+ * @example
219
+ * ```ts
220
+ * buildJSDoc(['@type string', '@example hello'])
221
+ * // '/**\n * @type string\n * @example hello\n *\/\n '
222
+ * ```
223
+ */
224
+ function buildJSDoc(comments, options = {}) {
225
+ const { indent = " * ", suffix = "\n ", fallback = " " } = options;
226
+ if (comments.length === 0) return fallback;
227
+ return `/**\n${comments.map((c) => `${indent}${c}`).join("\n")}\n */${suffix}`;
228
+ }
221
229
  //#endregion
222
230
  //#region ../../internals/utils/src/url.ts
223
231
  function transformParam(raw, casing) {
@@ -399,13 +407,13 @@ function buildParamsRemapExpression({ source, mapping }) {
399
407
  //#region ../../internals/shared/src/operation.ts
400
408
  /**
401
409
  * Builds the `ResolverFileParams` every operation generator passes to
402
- * `resolver.resolveFile`: a file named `name`, tagged by the operation's first
410
+ * `resolver.file`: a file named `name`, tagged by the operation's first
403
411
  * tag (or `'default'`), at the operation's path. Centralizes the entry object
404
412
  * that was repeated at dozens of call sites across the client and query plugins.
405
413
  *
406
414
  * @example
407
415
  * ```ts
408
- * resolver.resolveFile(operationFileEntry(node, node.operationId), { root, output, group })
416
+ * resolver.file(operationFileEntry(node, node.operationId), { root, output, group })
409
417
  * ```
410
418
  */
411
419
  function operationFileEntry(node, name, extname = ".ts") {
@@ -422,8 +430,11 @@ function getOperationLink(node, link) {
422
430
  if (link === "urlPath") return node.path ? `{@link ${Url.toPath(node.path)}}` : null;
423
431
  return node.path ? `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}` : null;
424
432
  }
425
- function getContentTypeInfo(node) {
426
- const contentTypes = node.requestBody?.content?.map((e) => e.contentType) ?? [];
433
+ /**
434
+ * Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several
435
+ * are present and the union, default, and form-data flags the client uses to pick one.
436
+ */
437
+ function buildContentTypeInfo(contentTypes) {
427
438
  const isMultipleContentTypes = contentTypes.length > 1;
428
439
  return {
429
440
  contentTypes,
@@ -433,20 +444,15 @@ function getContentTypeInfo(node) {
433
444
  hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
434
445
  };
435
446
  }
447
+ function getContentTypeInfo(node) {
448
+ return buildContentTypeInfo(node.requestBody?.content?.map((e) => e.contentType) ?? []);
449
+ }
436
450
  /**
437
451
  * The request-body counterpart for the primary success response: the content types it documents and
438
452
  * whether several are present, so the client can let a caller pick which one to accept.
439
453
  */
440
454
  function getResponseContentTypeInfo(node) {
441
- const contentTypes = getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? [];
442
- const isMultipleContentTypes = contentTypes.length > 1;
443
- return {
444
- contentTypes,
445
- isMultipleContentTypes,
446
- contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(" | ") : "",
447
- defaultContentType: contentTypes[0] ?? "application/json",
448
- hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
449
- };
455
+ return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? []);
450
456
  }
451
457
  /**
452
458
  * Reads the single base content type of an operation's primary success response, lowercased and
@@ -628,7 +634,7 @@ function resolveResponseValidator(validator) {
628
634
  * `<operation>ResponseSchema` is used; error bodies are never zod-parsed.
629
635
  */
630
636
  function buildZodResponseParse(node, zodResolver) {
631
- const name = zodResolver.resolveResponseName?.(node);
637
+ const name = zodResolver.response.response(node);
632
638
  return name ? {
633
639
  expression: name,
634
640
  importNames: [name]
@@ -641,7 +647,7 @@ function buildZodResponseParse(node, zodResolver) {
641
647
  */
642
648
  function buildZodErrorParse(node, zodResolver) {
643
649
  if (!node.responses.some((res) => !isSuccessStatusCode(res.statusCode) && res.content?.some((entry) => entry.schema))) return null;
644
- const name = zodResolver.resolveErrorName?.(node);
650
+ const name = zodResolver.response.error?.(node);
645
651
  return name ? {
646
652
  expression: name,
647
653
  importNames: [name]
@@ -758,7 +764,7 @@ function buildParamsRemap({ node }) {
758
764
  * `buildRequestResultGenerics({ node, tsResolver }) // 'AddPetResponses, ThrowOnError'`
759
765
  */
760
766
  function buildRequestResultGenerics({ node, tsResolver }) {
761
- return `${tsResolver.resolveResponsesName(node)}, ThrowOnError`;
767
+ return `${tsResolver.response.responses(node)}, ThrowOnError`;
762
768
  }
763
769
  //#endregion
764
770
  //#region ../../internals/client/src/builders/returnStatement.ts
@@ -781,30 +787,30 @@ function buildReturnStatement({ node, tsResolver, callConfig }) {
781
787
  const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
782
788
  /**
783
789
  * Builds the grouped-options signature for one operation: a single `options` object whose `TData`
784
- * is the plugin-ts `<Name>RequestConfig` (carrying a literal `url`), and a `RequestResult` return type
790
+ * is the plugin-ts `<Name>Options` (carrying a literal `url`), and a `RequestResult` return type
785
791
  * keyed to the plugin-ts per-status responses record. There are no positional arguments.
786
792
  *
787
- * The generated file imports `<Name>RequestConfig` and `<Name>Responses` and uses them directly, so no
793
+ * The generated file imports `<Name>Options` and `<Name>Responses` and uses them directly, so no
788
794
  * per-operation input type has to be emitted.
789
795
  */
790
796
  function buildGroupedOptionsSignature({ node, tsResolver }) {
791
- const requestConfigName = tsResolver.resolveRequestConfigName(node);
792
- const responsesName = tsResolver.resolveResponsesName(node);
797
+ const optionsName = tsResolver.response.options(node);
798
+ const responsesName = tsResolver.response.responses(node);
793
799
  const resultGenerics = buildRequestResultGenerics({
794
800
  node,
795
801
  tsResolver
796
802
  });
797
803
  const { isOptional } = getRequestGroupOptionality(node);
798
804
  return {
799
- dataTypeName: requestConfigName,
805
+ dataTypeName: optionsName,
800
806
  paramsSignature: declarationPrinter.print((0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
801
807
  name: "options",
802
- type: `Options<${requestConfigName}, ThrowOnError>`,
808
+ type: `Options<${optionsName}, ThrowOnError>`,
803
809
  ...isOptional ? { default: "{}" } : {}
804
810
  })] })) ?? "",
805
811
  returnType: `Promise<RequestResult<${resultGenerics}>>`,
806
812
  generics: ["ThrowOnError extends boolean = true"],
807
- importedTypeNames: [requestConfigName, responsesName]
813
+ importedTypeNames: [optionsName, responsesName]
808
814
  };
809
815
  }
810
816
  //#endregion
@@ -870,7 +876,7 @@ function buildStyles({ node }) {
870
876
  function buildValidatorHooks({ node, validator, zodResolver }) {
871
877
  const importedZodNames = [];
872
878
  const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
873
- const zodRequestName = zodResolver && resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.resolveDataName?.(node) : null;
879
+ const zodRequestName = zodResolver && resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.response.body(node) : null;
874
880
  const request = zodRequestName ?? null;
875
881
  if (zodRequestName) importedZodNames.push(zodRequestName);
876
882
  const responseParse = zodResolver && resolveResponseValidator(validator) === "zod" ? buildZodResponseParse(node, zodResolver) : null;
@@ -930,7 +936,7 @@ function Operation({ name, node, tsResolver, zodResolver, validator, security, i
930
936
  "...config",
931
937
  ...buildParamsRemap({ node })
932
938
  ].filter(Boolean).join(", ")} }`;
933
- const eventType = `SuccessOf<${tsResolver.resolveResponsesName(node)}>`;
939
+ const eventType = `SuccessOf<${tsResolver.response.responses(node)}>`;
934
940
  const returnType = eventStream ? `Promise<EventStreamResult<${eventType}>>` : signature.returnType;
935
941
  const returnStatement = eventStream ? `return toEventStream<${eventType}>(request(${callConfig}))` : buildReturnStatement({
936
942
  node,
@@ -1008,7 +1014,7 @@ function buildSdkMethod({ node, name, tsResolver, zodResolver, validator, securi
1008
1014
  })
1009
1015
  });
1010
1016
  const generics = signature.generics.length ? `<${signature.generics.join(", ")}>` : "";
1011
- const jsdoc = kubb_kit.ast.buildJSDoc(buildOperationComments(node, {
1017
+ const jsdoc = buildJSDoc(buildOperationComments(node, {
1012
1018
  link: "urlPath",
1013
1019
  linkPosition: "beforeDeprecated",
1014
1020
  splitLines: true
@@ -1078,15 +1084,15 @@ function SdkFacade({ name, isExportable = true, isIndexable = true, members, chi
1078
1084
  //#endregion
1079
1085
  //#region ../../internals/client/src/generators/sdkGenerator.tsx
1080
1086
  function resolveTypeImportNames(node, tsResolver) {
1081
- return [tsResolver.resolveRequestConfigName(node), tsResolver.resolveResponsesName(node)];
1087
+ return [tsResolver.response.options(node), tsResolver.response.responses(node)];
1082
1088
  }
1083
1089
  function resolveZodImportNames(node, zodResolver, validator) {
1084
1090
  const { query: queryParams } = getOperationParameters(node, { paramsCasing: "original" });
1085
1091
  return [
1086
- resolveResponseValidator(validator) === "zod" ? zodResolver.resolveResponseName?.(node) : null,
1092
+ resolveResponseValidator(validator) === "zod" ? zodResolver.response.response(node) : null,
1087
1093
  resolveResponseValidator(validator) === "zod" ? buildZodErrorParse(node, zodResolver)?.expression ?? null : null,
1088
- resolveRequestValidator(validator) === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null,
1089
- resolveQueryParamsValidator(validator) === "zod" && queryParams.length > 0 ? zodResolver.resolveQueryParamsName?.(node, queryParams[0]) : null
1094
+ resolveRequestValidator(validator) === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.response.body(node) : null,
1095
+ resolveQueryParamsValidator(validator) === "zod" && queryParams.length > 0 ? zodResolver.param.query(node, queryParams[0]) : null
1090
1096
  ].filter((n) => Boolean(n));
1091
1097
  }
1092
1098
  /**
@@ -1103,12 +1109,14 @@ function buildControllers(nodes, ctx) {
1103
1109
  const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) : null;
1104
1110
  const document = ctx.adapter.document;
1105
1111
  function buildOperationData(node) {
1106
- const typeFile = tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
1112
+ const typeFile = tsResolver.file({
1113
+ ...operationFileEntry(node, node.operationId),
1107
1114
  root,
1108
1115
  output: tsPluginOptions?.output ?? output,
1109
1116
  group: tsPluginOptions?.group
1110
1117
  });
1111
- const zodFile = zodResolver && pluginZod?.options ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
1118
+ const zodFile = zodResolver && pluginZod?.options ? zodResolver.file({
1119
+ ...operationFileEntry(node, node.operationId),
1112
1120
  root,
1113
1121
  output: pluginZod.options?.output ?? output,
1114
1122
  group: pluginZod.options?.group ?? void 0
@@ -1120,7 +1128,7 @@ function buildControllers(nodes, ctx) {
1120
1128
  }) : void 0;
1121
1129
  return {
1122
1130
  node,
1123
- name: resolver.resolveName(node.operationId),
1131
+ name: resolver.name(node.operationId),
1124
1132
  tsResolver,
1125
1133
  zodResolver,
1126
1134
  typeFile,
@@ -1131,12 +1139,11 @@ function buildControllers(nodes, ctx) {
1131
1139
  return nodes.reduce((acc, operationNode) => {
1132
1140
  if (!kubb_kit.ast.isHttpOperationNode(operationNode)) return acc;
1133
1141
  const tag = operationNode.tags[0];
1134
- const name = tag ? group?.name?.({ group: camelCase(tag) }) ?? resolver.resolveGroupName(tag) : resolver.resolveClassName("ApiClient");
1135
- const file = resolver.resolveFile({
1142
+ const name = tag ? group?.name?.({ group: camelCase(tag) }) ?? resolver.groupName(tag) : resolver.className("ApiClient");
1143
+ const file = resolver.file({
1136
1144
  name,
1137
1145
  extname: ".ts",
1138
- tag
1139
- }, {
1146
+ tag,
1140
1147
  root,
1141
1148
  output,
1142
1149
  group: group ?? void 0
@@ -1190,7 +1197,7 @@ function createSdkGenerator() {
1190
1197
  if (!ctx.driver.getPlugin(_kubb_plugin_ts.pluginTsName) || !sdk) return null;
1191
1198
  const controllers = buildControllers(nodes, ctx);
1192
1199
  const clientPath = node_path.default.resolve(root, ".kubb/client.ts");
1193
- const banner = (file) => resolver.resolveBanner(ctx.meta, {
1200
+ const banner = (file) => resolver.default.banner(ctx.meta, {
1194
1201
  output,
1195
1202
  config,
1196
1203
  file: {
@@ -1198,7 +1205,7 @@ function createSdkGenerator() {
1198
1205
  baseName: file.baseName
1199
1206
  }
1200
1207
  });
1201
- const footer = (file) => resolver.resolveFooter(ctx.meta, {
1208
+ const footer = (file) => resolver.default.footer(ctx.meta, {
1202
1209
  output,
1203
1210
  config,
1204
1211
  file: {
@@ -1265,28 +1272,26 @@ function createSdkGenerator() {
1265
1272
  ]
1266
1273
  }, file.path);
1267
1274
  };
1268
- if (sdk.mode === "flat") return renderClassFile(resolver.resolveClassName(sdk.name ?? "sdk"), resolver.resolveFile({
1275
+ if (sdk.mode === "flat") return renderClassFile(resolver.className(sdk.name ?? "sdk"), resolver.file({
1269
1276
  name: sdk.name ?? "sdk",
1270
- extname: ".ts"
1271
- }, {
1277
+ extname: ".ts",
1272
1278
  root,
1273
1279
  output,
1274
1280
  group: group ?? void 0
1275
1281
  }), controllers.flatMap((controller) => controller.operations));
1276
1282
  const classFiles = controllers.map(({ name, file, operations: ops }) => renderClassFile(name, file, ops));
1277
1283
  if (!sdk.name) return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx_jsx_runtime.Fragment, { children: classFiles });
1278
- const sdkFile = resolver.resolveFile({
1284
+ const sdkFile = resolver.file({
1279
1285
  name: sdk.name,
1280
- extname: ".ts"
1281
- }, {
1286
+ extname: ".ts",
1282
1287
  root,
1283
1288
  output,
1284
1289
  group: group ?? void 0
1285
1290
  });
1286
- const facadeName = resolver.resolveClassName(sdk.name);
1291
+ const facadeName = resolver.className(sdk.name);
1287
1292
  const members = controllers.map(({ name, tag }) => ({
1288
1293
  className: name,
1289
- propName: resolver.resolveClientPropertyName(tag ?? name)
1294
+ propName: resolver.propertyName(tag ?? name)
1290
1295
  }));
1291
1296
  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, {
1292
1297
  baseName: sdkFile.baseName,
@@ -1326,38 +1331,27 @@ const defaultMacros = [kubb_kit.ast.macroSimplifyUnion];
1326
1331
  //#endregion
1327
1332
  //#region ../../internals/client/src/resolver.ts
1328
1333
  /**
1329
- * Default resolver shared by the client plugins. Functions and files use camelCase; classes and
1330
- * tag groups use PascalCase.
1334
+ * Default resolver shared by the client plugins. Functions and files inherit the built-in camelCase
1335
+ * `name` and `file`; classes and tag groups use PascalCase.
1331
1336
  *
1332
1337
  * @example
1333
1338
  * ```ts
1334
- * resolverClient.resolveName('show pet by id') // 'showPetById'
1335
- * resolverClient.resolveGroupName('pet') // 'PetClient'
1339
+ * resolverClient.name('show pet by id') // 'showPetById'
1340
+ * resolverClient.groupName('pet') // 'PetClient'
1336
1341
  * ```
1337
1342
  */
1338
- const resolverClient = (0, kubb_kit.defineResolver)(() => ({
1339
- name: "default",
1343
+ const resolverClient = (0, kubb_kit.createResolver)({
1340
1344
  pluginName: "plugin-contract-client",
1341
- default(name, type) {
1342
- if (type === "file") return toFilePath(name);
1343
- return ensureValidVarName(camelCase(name));
1344
- },
1345
- resolveName(name) {
1346
- return this.default(name, "function");
1347
- },
1348
- resolvePathName(name, type) {
1349
- return this.default(name, type);
1350
- },
1351
- resolveClassName(name) {
1345
+ className(name) {
1352
1346
  return ensureValidVarName(pascalCase(name));
1353
1347
  },
1354
- resolveGroupName(name) {
1348
+ groupName(name) {
1355
1349
  return ensureValidVarName(pascalCase(`${name} Client`));
1356
1350
  },
1357
- resolveClientPropertyName(name) {
1351
+ propertyName(name) {
1358
1352
  return ensureValidVarName(camelCase(name));
1359
1353
  }
1360
- }));
1354
+ });
1361
1355
  //#endregion
1362
1356
  //#region src/generators/clientGenerator.tsx
1363
1357
  /**
@@ -1378,25 +1372,28 @@ const clientGenerator = (0, kubb_kit.defineGenerator)({
1378
1372
  const pluginZod = resolveResponseValidator(validator) === "zod" || resolveRequestValidator(validator) === "zod" ? driver.getPlugin(_kubb_plugin_zod.pluginZodName) : null;
1379
1373
  const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) : null;
1380
1374
  const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema);
1381
- const importedTypeNames = [tsResolver.resolveRequestConfigName(node), tsResolver.resolveResponsesName(node)];
1375
+ const importedTypeNames = [tsResolver.response.options(node), tsResolver.response.responses(node)];
1382
1376
  const importedZodNames = zodResolver ? [
1383
- resolveResponseValidator(validator) === "zod" ? zodResolver.resolveResponseName?.(node) : null,
1377
+ resolveResponseValidator(validator) === "zod" ? zodResolver.response.response?.(node) : null,
1384
1378
  resolveResponseValidator(validator) === "zod" ? buildZodErrorParse(node, zodResolver)?.expression ?? null : null,
1385
- resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.resolveDataName?.(node) : null
1379
+ resolveRequestValidator(validator) === "zod" && hasRequestBody ? zodResolver.response.body?.(node) : null
1386
1380
  ].filter((name) => Boolean(name)) : [];
1387
1381
  const meta = {
1388
- name: resolver.resolveName(node.operationId),
1389
- file: resolver.resolveFile(operationFileEntry(node, node.operationId), {
1382
+ name: resolver.name(node.operationId),
1383
+ file: resolver.file({
1384
+ ...operationFileEntry(node, node.operationId),
1390
1385
  root,
1391
1386
  output,
1392
1387
  group: group ?? void 0
1393
1388
  }),
1394
- fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
1389
+ fileTs: tsResolver.file({
1390
+ ...operationFileEntry(node, node.operationId),
1395
1391
  root,
1396
1392
  output: pluginTs.options?.output ?? output,
1397
1393
  group: pluginTs.options?.group ?? void 0
1398
1394
  }),
1399
- fileZod: zodResolver && pluginZod?.options ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
1395
+ fileZod: zodResolver && pluginZod?.options ? zodResolver.file({
1396
+ ...operationFileEntry(node, node.operationId),
1400
1397
  root,
1401
1398
  output: pluginZod.options.output ?? output,
1402
1399
  group: pluginZod.options?.group ?? void 0
@@ -1413,7 +1410,7 @@ const clientGenerator = (0, kubb_kit.defineGenerator)({
1413
1410
  baseName: meta.file.baseName,
1414
1411
  path: meta.file.path,
1415
1412
  meta: meta.file.meta,
1416
- banner: resolver.resolveBanner(ctx.meta, {
1413
+ banner: resolver.default.banner(ctx.meta, {
1417
1414
  output,
1418
1415
  config,
1419
1416
  file: {
@@ -1421,7 +1418,7 @@ const clientGenerator = (0, kubb_kit.defineGenerator)({
1421
1418
  baseName: meta.file.baseName
1422
1419
  }
1423
1420
  }),
1424
- footer: resolver.resolveFooter(ctx.meta, {
1421
+ footer: resolver.default.footer(ctx.meta, {
1425
1422
  output,
1426
1423
  config,
1427
1424
  file: {
@@ -1525,10 +1522,7 @@ const pluginFetch = (0, kubb_kit.definePlugin)((options) => {
1525
1522
  mode: sdk.mode ?? "tag",
1526
1523
  name: sdk.name
1527
1524
  } : void 0,
1528
- resolver: userResolver ? {
1529
- ...resolverClient,
1530
- ...userResolver
1531
- } : resolverClient
1525
+ resolver: userResolver ? kubb_kit.Resolver.merge(resolverClient, userResolver) : resolverClient
1532
1526
  };
1533
1527
  const selectedGenerators = resolved.sdk ? [createSdkGenerator()] : [clientGenerator];
1534
1528
  return {