@kubb/plugin-mcp 5.0.0-beta.42 → 5.0.0-beta.64

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
@@ -1,8 +1,9 @@
1
1
  import "./chunk-C0LytTxp.js";
2
2
  import path from "node:path";
3
3
  import { ast, defineGenerator, definePlugin, defineResolver } from "@kubb/core";
4
+ import { caseParams, createOperationParams } from "@kubb/ast/utils";
4
5
  import { functionPrinter, pluginTsName } from "@kubb/plugin-ts";
5
- import { Const, File, Function, jsxRendererSync } from "@kubb/renderer-jsx";
6
+ import { Const, File, Function, jsxRenderer } from "@kubb/renderer-jsx";
6
7
  import { Fragment, jsx, jsxs } from "@kubb/renderer-jsx/jsx-runtime";
7
8
  import { pluginZodName } from "@kubb/plugin-zod";
8
9
  import { pluginClientName } from "@kubb/plugin-client";
@@ -20,36 +21,45 @@ import { source as source$2 } from "@kubb/plugin-client/templates/config.source"
20
21
  function toCamelOrPascal(text, pascal) {
21
22
  return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
22
23
  if (word.length > 1 && word === word.toUpperCase()) return word;
23
- if (i === 0 && !pascal) return word.charAt(0).toLowerCase() + word.slice(1);
24
- return word.charAt(0).toUpperCase() + word.slice(1);
24
+ return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
25
25
  }).join("").replace(/[^a-zA-Z0-9]/g, "");
26
26
  }
27
27
  /**
28
- * Splits `text` on `.` and applies `transformPart` to each segment.
29
- * The last segment receives `isLast = true`, all earlier segments receive `false`.
30
- * Segments are joined with `/` to form a file path.
28
+ * Converts `text` to camelCase.
29
+ *
30
+ * @example Word boundaries
31
+ * `camelCase('hello-world') // 'helloWorld'`
31
32
  *
32
- * Only splits on dots followed by a letter so that version numbers
33
- * embedded in operationIds (e.g. `v2025.0`) are kept intact.
33
+ * @example With a prefix
34
+ * `camelCase('tag', { prefix: 'create' }) // 'createTag'`
34
35
  */
35
- function applyToFileParts(text, transformPart) {
36
- const parts = text.split(/\.(?=[a-zA-Z])/);
37
- return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
36
+ function camelCase(text, { prefix = "", suffix = "" } = {}) {
37
+ return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
38
38
  }
39
+ //#endregion
40
+ //#region ../../internals/utils/src/fs.ts
39
41
  /**
40
- * Converts `text` to camelCase.
41
- * When `isFile` is `true`, dot-separated segments are each cased independently and joined with `/`.
42
+ * Builds a nested file path from a dotted name. Splits on dots that precede a letter
43
+ * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
44
+ * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
42
45
  *
43
- * @example
44
- * camelCase('hello-world') // 'helloWorld'
45
- * camelCase('pet.petId', { isFile: true }) // 'pet/petId'
46
+ * Empty segments are dropped before joining. They arise when the name starts with a dot
47
+ * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
48
+ * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
49
+ * absolute path, letting generated files escape the configured output directory.
50
+ *
51
+ * @example Nested path from a dotted name
52
+ * `toFilePath('pet.petId') // 'pet/petId'`
53
+ *
54
+ * @example PascalCase the final segment
55
+ * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
56
+ *
57
+ * @example Suffix applied to the final segment only
58
+ * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
46
59
  */
47
- function camelCase(text, { isFile, prefix = "", suffix = "" } = {}) {
48
- if (isFile) return applyToFileParts(text, (part, isLast) => camelCase(part, isLast ? {
49
- prefix,
50
- suffix
51
- } : {}));
52
- return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
60
+ function toFilePath(name, caseLast = camelCase) {
61
+ const parts = name.split(/\.(?=[a-zA-Z])/);
62
+ return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
53
63
  }
54
64
  //#endregion
55
65
  //#region ../../internals/utils/src/reserved.ts
@@ -155,99 +165,80 @@ function isValidVarName(name) {
155
165
  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
156
166
  }
157
167
  //#endregion
158
- //#region ../../internals/utils/src/urlPath.ts
168
+ //#region ../../internals/utils/src/url.ts
169
+ function transformParam(raw, casing) {
170
+ const param = isValidVarName(raw) ? raw : camelCase(raw);
171
+ return casing === "camelcase" ? camelCase(param) : param;
172
+ }
173
+ function toParamsObject(path, { replacer, casing } = {}) {
174
+ const params = {};
175
+ for (const match of path.matchAll(/\{([^}]+)\}/g)) {
176
+ const param = transformParam(match[1], casing);
177
+ const key = replacer ? replacer(param) : param;
178
+ params[key] = key;
179
+ }
180
+ return Object.keys(params).length > 0 ? params : null;
181
+ }
159
182
  /**
160
- * Parses and transforms an OpenAPI/Swagger path string into various URL formats.
161
- *
162
- * @example
163
- * const p = new URLPath('/pet/{petId}')
164
- * p.URL // '/pet/:petId'
165
- * p.template // '`/pet/${petId}`'
183
+ * Helpers for OpenAPI/Swagger paths, plus a thin wrapper over the native `URL`.
166
184
  */
167
- var URLPath = class {
185
+ var Url = class Url {
168
186
  /**
169
- * The raw OpenAPI/Swagger path string, e.g. `/pet/{petId}`.
170
- */
171
- path;
172
- #options;
173
- constructor(path, options = {}) {
174
- this.path = path;
175
- this.#options = options;
176
- }
177
- /** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`.
187
+ * Reports whether `url` is a parseable absolute URL. Delegates to the native `URL.canParse`.
178
188
  *
179
189
  * @example
180
- * ```ts
181
- * new URLPath('/pet/{petId}').URL // '/pet/:petId'
182
- * ```
190
+ * Url.canParse('https://petstore.swagger.io/v2') // true
191
+ * Url.canParse('/pet/{petId}') // false
183
192
  */
184
- get URL() {
185
- return this.toURLPath();
193
+ static canParse(url, base) {
194
+ return URL.canParse(url, base);
186
195
  }
187
- /** Returns `true` when `path` is a fully-qualified URL (e.g. starts with `https://`).
196
+ /**
197
+ * Converts an OpenAPI/Swagger path to Express-style colon syntax.
188
198
  *
189
199
  * @example
190
- * ```ts
191
- * new URLPath('https://petstore.swagger.io/v2/pet').isURL // true
192
- * new URLPath('/pet/{petId}').isURL // false
193
- * ```
200
+ * Url.toPath('/pet/{petId}') // '/pet/:petId'
194
201
  */
195
- get isURL() {
196
- try {
197
- return !!new URL(this.path).href;
198
- } catch {
199
- return false;
200
- }
202
+ static toPath(path) {
203
+ return path.replace(/\{([^}]+)\}/g, ":$1");
201
204
  }
202
205
  /**
203
- * Converts the OpenAPI path to a TypeScript template literal string.
206
+ * Converts an OpenAPI/Swagger path to a TypeScript template literal string.
207
+ * `prefix` is prepended inside the literal, `replacer` transforms each parameter name,
208
+ * and `casing` controls parameter identifier casing.
204
209
  *
205
210
  * @example
206
- * new URLPath('/pet/{petId}').template // '`/pet/${petId}`'
207
- * new URLPath('/account/monetary-accountID').template // '`/account/${monetaryAccountId}`'
208
- */
209
- get template() {
210
- return this.toTemplateString();
211
- }
212
- /** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set.
211
+ * Url.toTemplateString('/pet/{petId}') // '`/pet/${petId}`'
213
212
  *
214
213
  * @example
215
- * ```ts
216
- * new URLPath('/pet/{petId}').object
217
- * // { url: '/pet/:petId', params: { petId: 'petId' } }
218
- * ```
214
+ * Url.toTemplateString('/pet/{petId}', { prefix: 'https://api' }) // '`https://api/pet/${petId}`'
219
215
  */
220
- get object() {
221
- return this.toObject();
216
+ static toTemplateString(path, { prefix, replacer, casing } = {}) {
217
+ const result = path.split(/\{([^}]+)\}/).map((part, i) => {
218
+ if (i % 2 === 0) return part;
219
+ const param = transformParam(part, casing);
220
+ return `\${${replacer ? replacer(param) : param}}`;
221
+ }).join("");
222
+ return `\`${prefix ?? ""}${result}\``;
222
223
  }
223
- /** Returns a map of path parameter names, or `null` when the path has no parameters.
224
+ /**
225
+ * Returns the path and its extracted params as a structured `URLObject`, or as a stringified
226
+ * expression when `stringify` is set.
224
227
  *
225
228
  * @example
226
- * ```ts
227
- * new URLPath('/pet/{petId}').params // { petId: 'petId' }
228
- * new URLPath('/pet').params // null
229
- * ```
230
- */
231
- get params() {
232
- return this.toParamsObject();
233
- }
234
- #transformParam(raw) {
235
- const param = isValidVarName(raw) ? raw : camelCase(raw);
236
- return this.#options.casing === "camelcase" ? camelCase(param) : param;
237
- }
238
- /**
239
- * Iterates over every `{param}` token in `path`, calling `fn` with the raw token and transformed name.
229
+ * Url.toObject('/pet/{petId}')
230
+ * // { url: '/pet/:petId', params: { petId: 'petId' } }
240
231
  */
241
- #eachParam(fn) {
242
- for (const match of this.path.matchAll(/\{([^}]+)\}/g)) {
243
- const raw = match[1];
244
- fn(raw, this.#transformParam(raw));
245
- }
246
- }
247
- toObject({ type = "path", replacer, stringify } = {}) {
232
+ static toObject(path, { type = "path", replacer, stringify, casing } = {}) {
248
233
  const object = {
249
- url: type === "path" ? this.toURLPath() : this.toTemplateString({ replacer }),
250
- params: this.toParamsObject()
234
+ url: type === "path" ? Url.toPath(path) : Url.toTemplateString(path, {
235
+ replacer,
236
+ casing
237
+ }),
238
+ params: toParamsObject(path, {
239
+ replacer,
240
+ casing
241
+ })
251
242
  };
252
243
  if (stringify) {
253
244
  if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
@@ -256,57 +247,13 @@ var URLPath = class {
256
247
  }
257
248
  return object;
258
249
  }
259
- /**
260
- * Converts the OpenAPI path to a TypeScript template literal string.
261
- * An optional `replacer` can transform each extracted parameter name before interpolation.
262
- *
263
- * @example
264
- * new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'
265
- */
266
- toTemplateString({ prefix, replacer } = {}) {
267
- const result = this.path.split(/\{([^}]+)\}/).map((part, i) => {
268
- if (i % 2 === 0) return part;
269
- const param = this.#transformParam(part);
270
- return `\${${replacer ? replacer(param) : param}}`;
271
- }).join("");
272
- return `\`${prefix ?? ""}${result}\``;
273
- }
274
- /**
275
- * Extracts all `{param}` segments from the path and returns them as a key-value map.
276
- * An optional `replacer` transforms each parameter name in both key and value positions.
277
- * Returns `undefined` when no path parameters are found.
278
- *
279
- * @example
280
- * ```ts
281
- * new URLPath('/pet/{petId}/tag/{tagId}').toParamsObject()
282
- * // { petId: 'petId', tagId: 'tagId' }
283
- * ```
284
- */
285
- toParamsObject(replacer) {
286
- const params = {};
287
- this.#eachParam((_raw, param) => {
288
- const key = replacer ? replacer(param) : param;
289
- params[key] = key;
290
- });
291
- return Object.keys(params).length > 0 ? params : null;
292
- }
293
- /** Converts the OpenAPI path to Express-style colon syntax.
294
- *
295
- * @example
296
- * ```ts
297
- * new URLPath('/pet/{petId}').toURLPath() // '/pet/:petId'
298
- * ```
299
- */
300
- toURLPath() {
301
- return this.path.replace(/\{([^}]+)\}/g, ":$1");
302
- }
303
250
  };
304
251
  //#endregion
305
252
  //#region ../../internals/shared/src/operation.ts
306
253
  function getOperationLink(node, link) {
307
254
  if (!link) return null;
308
255
  if (typeof link === "function") return link(node) ?? null;
309
- if (link === "urlPath") return node.path ? `{@link ${new URLPath(node.path).URL}}` : null;
256
+ if (link === "urlPath") return node.path ? `{@link ${Url.toPath(node.path)}}` : null;
310
257
  return node.path ? `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}` : null;
311
258
  }
312
259
  function buildOperationComments(node, options = {}) {
@@ -327,7 +274,7 @@ function buildOperationComments(node, options = {}) {
327
274
  return filteredComments.flatMap((text) => text.split(/\r?\n/).map((line) => line.trim())).filter((comment) => Boolean(comment));
328
275
  }
329
276
  function getOperationParameters(node, options = {}) {
330
- const params = ast.caseParams(node.parameters, options.paramsCasing);
277
+ const params = caseParams(node.parameters, options.paramsCasing);
331
278
  return {
332
279
  path: params.filter((param) => param.in === "path"),
333
280
  query: params.filter((param) => param.in === "query"),
@@ -396,26 +343,24 @@ function findSuccessStatusCode(responses) {
396
343
  * shared default naming so every plugin groups output consistently:
397
344
  *
398
345
  * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).
399
- * - other groups use `${camelCase(group)}${suffix}` (e.g. `petController`).
346
+ * - other groups use the camelCased group (`pet store` → `petStore`).
400
347
  *
401
348
  * A user-provided `group.name` always wins over the default namer, so callers stay in
402
349
  * control of their output folders. Returns `null` when grouping is disabled, matching the
403
350
  * per-plugin convention.
404
351
  *
405
352
  * @param group - The user-supplied group option, or `undefined` to disable grouping.
406
- * @param options.suffix - Appended to non-`path` group names, e.g. `'Controller'` or `'Requests'`.
407
353
  *
408
354
  * @example
409
355
  * ```ts
410
- * createGroupConfig(group, { suffix: 'Controller' }) // plugin-ts, plugin-client, …
411
- * createGroupConfig(group, { suffix: 'Requests' }) // plugin-cypress, plugin-mcp
356
+ * createGroupConfig(group) // shared across every plugin
412
357
  * ```
413
358
  */
414
- function createGroupConfig(group, options) {
359
+ function createGroupConfig(group) {
415
360
  if (!group) return null;
416
361
  const defaultName = (ctx) => {
417
362
  if (group.type === "path") return `${ctx.group.split("/")[1]}`;
418
- return `${camelCase(ctx.group)}${options.suffix}`;
363
+ return camelCase(ctx.group);
419
364
  };
420
365
  return {
421
366
  ...group,
@@ -452,7 +397,6 @@ function buildRemappingCode(mapping, varName, sourceName) {
452
397
  const declarationPrinter = functionPrinter({ mode: "declaration" });
453
398
  function McpHandler({ name, node, resolver, baseURL, dataReturnType, paramsCasing }) {
454
399
  if (!ast.isHttpOperationNode(node)) return null;
455
- const urlPath = new URLPath(node.path);
456
400
  const contentType = node.requestBody?.content?.[0]?.contentType;
457
401
  const isFormData = contentType === "multipart/form-data";
458
402
  const { query: queryParams, header: headerParams } = getOperationParameters(node, { paramsCasing });
@@ -465,7 +409,7 @@ function McpHandler({ name, node, resolver, baseURL, dataReturnType, paramsCasin
465
409
  `ResponseErrorConfig<${errorResponses.length > 0 ? errorResponses.join(" | ") : "Error"}>`,
466
410
  requestName || "unknown"
467
411
  ].filter(Boolean);
468
- const paramsNode = ast.createOperationParams(node, {
412
+ const paramsNode = createOperationParams(node, {
469
413
  paramsType: "object",
470
414
  pathParamsType: "inline",
471
415
  resolver,
@@ -480,28 +424,20 @@ function McpHandler({ name, node, resolver, baseURL, dataReturnType, paramsCasin
480
424
  const headers = [headerParams.length ? headerParamsMapping ? "...mappedHeaders" : "...headers" : null, contentTypeHeader].filter(Boolean);
481
425
  const fetchConfig = [];
482
426
  fetchConfig.push(`method: ${JSON.stringify(node.method.toUpperCase())}`);
483
- fetchConfig.push(`url: ${urlPath.template}`);
427
+ fetchConfig.push(`url: ${Url.toTemplateString(node.path)}`);
484
428
  if (baseURL) fetchConfig.push(`baseURL: \`${baseURL}\``);
485
429
  if (queryParams.length) fetchConfig.push(queryParamsMapping ? "params: mappedParams" : "params");
486
430
  if (requestName) fetchConfig.push(`data: ${isFormData ? "formData as FormData" : "requestData"}`);
487
431
  if (headers.length) fetchConfig.push(`headers: { ${headers.join(", ")} }`);
488
- const callToolResult = dataReturnType === "data" ? `return {
489
- content: [
490
- {
491
- type: 'text',
492
- text: JSON.stringify(res.data)
493
- }
494
- ],
495
- structuredContent: { data: res.data }
496
- }` : `return {
497
- content: [
498
- {
499
- type: 'text',
500
- text: JSON.stringify(res)
501
- }
502
- ],
503
- structuredContent: { data: res.data }
504
- }`;
432
+ const callToolResult = `return {
433
+ content: [
434
+ {
435
+ type: 'text',
436
+ text: JSON.stringify(${dataReturnType === "data" ? "res.data" : "res"})
437
+ }
438
+ ],
439
+ structuredContent: { data: res.data }
440
+ }`;
505
441
  return /* @__PURE__ */ jsx(File.Source, {
506
442
  name,
507
443
  isExportable: true,
@@ -575,7 +511,7 @@ function zodExprFromSchemaNode(schema) {
575
511
  }
576
512
  //#endregion
577
513
  //#region src/components/Server.tsx
578
- const keysPrinter = functionPrinter({ mode: "keys" });
514
+ const keysPrinter = functionPrinter({ mode: "call" });
579
515
  function Server({ name, serverName, serverVersion, paramsCasing, operations }) {
580
516
  const registrations = operations.map(({ tool, mcp, zod, node }) => {
581
517
  const { path: pathParams } = getOperationParameters(node, { paramsCasing });
@@ -602,10 +538,11 @@ function Server({ name, serverName, serverVersion, paramsCasing, operations }) {
602
538
  });
603
539
  otherEntries.sort((a, b) => a.key.localeCompare(b.key));
604
540
  const entries = [...pathEntries, ...otherEntries];
605
- const paramsNode = entries.length ? ast.createFunctionParameters({ params: [ast.createParameterGroup({ properties: entries.map((e) => ast.createFunctionParameter({
606
- name: e.key,
541
+ const paramsNode = entries.length ? ast.factory.createFunctionParameters({ params: [{
542
+ kind: "FunctionParameter",
543
+ name: ast.factory.createObjectBindingPattern({ elements: entries.map((e) => ({ name: e.key })) }),
607
544
  optional: false
608
- })) })] }) : null;
545
+ }] }) : null;
609
546
  const destructured = paramsNode ? keysPrinter.print(paramsNode) ?? "" : "";
610
547
  const inputSchema = entries.length ? `{ ${entries.map((e) => `${e.key}: ${e.value}`).join(", ")} }` : null;
611
548
  const outputSchema = zod.responseName;
@@ -676,7 +613,7 @@ return server`
676
613
  */
677
614
  const mcpGenerator = defineGenerator({
678
615
  name: "mcp",
679
- renderer: jsxRendererSync,
616
+ renderer: jsxRenderer,
680
617
  operation(node, ctx) {
681
618
  if (!ast.isHttpOperationNode(node)) return null;
682
619
  const { resolver, driver, root } = ctx;
@@ -806,7 +743,7 @@ const mcpGenerator = defineGenerator({
806
743
  */
807
744
  const serverGenerator = defineGenerator({
808
745
  name: "operations",
809
- renderer: jsxRendererSync,
746
+ renderer: jsxRenderer,
810
747
  operations(nodes, ctx) {
811
748
  const { config, resolver, plugin, driver, root } = ctx;
812
749
  const { output, paramsCasing, group } = ctx.options;
@@ -974,7 +911,7 @@ const resolverMcp = defineResolver(() => ({
974
911
  name: "default",
975
912
  pluginName: "plugin-mcp",
976
913
  default(name, type) {
977
- if (type === "file") return camelCase(name, { isFile: true });
914
+ if (type === "file") return toFilePath(name);
978
915
  return camelCase(name, { suffix: "handler" });
979
916
  },
980
917
  resolveName(name) {
@@ -1025,11 +962,11 @@ const pluginMcpName = "plugin-mcp";
1025
962
  const pluginMcp = definePlugin((options) => {
1026
963
  const { output = {
1027
964
  path: "mcp",
1028
- barrelType: "named"
1029
- }, group, exclude = [], include, override = [], paramsCasing, client, resolver: userResolver, transformer: userTransformer, generators: userGenerators = [] } = options;
965
+ barrel: { type: "named" }
966
+ }, group, exclude = [], include, override = [], paramsCasing, client, resolver: userResolver, macros: userMacros, generators: userGenerators = [] } = options;
1030
967
  const clientName = client?.client ?? "axios";
1031
968
  const clientImportPath = client?.importPath ?? (!client?.bundle ? `@kubb/plugin-client/clients/${clientName}` : void 0);
1032
- const groupConfig = createGroupConfig(group, { suffix: "Requests" });
969
+ const groupConfig = createGroupConfig(group);
1033
970
  return {
1034
971
  name: pluginMcpName,
1035
972
  options,
@@ -1058,7 +995,7 @@ const pluginMcp = definePlugin((options) => {
1058
995
  resolver
1059
996
  });
1060
997
  ctx.setResolver(resolver);
1061
- if (userTransformer) ctx.setTransformer(userTransformer);
998
+ if (userMacros?.length) ctx.setMacros(userMacros);
1062
999
  ctx.addGenerator(mcpGenerator);
1063
1000
  ctx.addGenerator(serverGenerator);
1064
1001
  for (const gen of userGenerators) ctx.addGenerator(gen);
@@ -1067,9 +1004,9 @@ const pluginMcp = definePlugin((options) => {
1067
1004
  if (client?.bundle && !hasClientPlugin && !clientImportPath) ctx.injectFile({
1068
1005
  baseName: "client.ts",
1069
1006
  path: path.resolve(root, ".kubb/client.ts"),
1070
- sources: [ast.createSource({
1007
+ sources: [ast.factory.createSource({
1071
1008
  name: "client",
1072
- nodes: [ast.createText(clientName === "fetch" ? source$1 : source)],
1009
+ nodes: [ast.factory.createText(clientName === "fetch" ? source$1 : source)],
1073
1010
  isExportable: true,
1074
1011
  isIndexable: true
1075
1012
  })]
@@ -1077,9 +1014,9 @@ const pluginMcp = definePlugin((options) => {
1077
1014
  if (!hasClientPlugin) ctx.injectFile({
1078
1015
  baseName: "config.ts",
1079
1016
  path: path.resolve(root, ".kubb/config.ts"),
1080
- sources: [ast.createSource({
1017
+ sources: [ast.factory.createSource({
1081
1018
  name: "config",
1082
- nodes: [ast.createText(source$2)],
1019
+ nodes: [ast.factory.createText(source$2)],
1083
1020
  isExportable: false,
1084
1021
  isIndexable: false
1085
1022
  })]