@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.cjs +116 -179
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -14
- package/dist/index.js +117 -180
- package/dist/index.js.map +1 -1
- package/package.json +10 -18
- package/extension.yaml +0 -943
- package/src/components/McpHandler.tsx +0 -168
- package/src/components/Server.tsx +0 -159
- package/src/generators/mcpGenerator.tsx +0 -89
- package/src/generators/serverGenerator.tsx +0 -149
- package/src/index.ts +0 -11
- package/src/plugin.ts +0 -142
- package/src/resolvers/resolverMcp.ts +0 -35
- package/src/types.ts +0 -94
- package/src/utils.ts +0 -48
package/dist/index.cjs
CHANGED
|
@@ -28,6 +28,7 @@ let node_path = require("node:path");
|
|
|
28
28
|
let node_path$1 = __toESM(node_path, 1);
|
|
29
29
|
node_path = __toESM(node_path);
|
|
30
30
|
let _kubb_core = require("@kubb/core");
|
|
31
|
+
let _kubb_ast_utils = require("@kubb/ast/utils");
|
|
31
32
|
let _kubb_plugin_ts = require("@kubb/plugin-ts");
|
|
32
33
|
let _kubb_renderer_jsx = require("@kubb/renderer-jsx");
|
|
33
34
|
let _kubb_renderer_jsx_jsx_runtime = require("@kubb/renderer-jsx/jsx-runtime");
|
|
@@ -47,36 +48,45 @@ let _kubb_plugin_client_templates_config_source = require("@kubb/plugin-client/t
|
|
|
47
48
|
function toCamelOrPascal(text, pascal) {
|
|
48
49
|
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) => {
|
|
49
50
|
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
50
|
-
|
|
51
|
-
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
51
|
+
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
52
52
|
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
55
|
+
* Converts `text` to camelCase.
|
|
56
|
+
*
|
|
57
|
+
* @example Word boundaries
|
|
58
|
+
* `camelCase('hello-world') // 'helloWorld'`
|
|
58
59
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
60
|
+
* @example With a prefix
|
|
61
|
+
* `camelCase('tag', { prefix: 'create' }) // 'createTag'`
|
|
61
62
|
*/
|
|
62
|
-
function
|
|
63
|
-
|
|
64
|
-
return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
|
|
63
|
+
function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
64
|
+
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
65
65
|
}
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region ../../internals/utils/src/fs.ts
|
|
66
68
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
+
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
70
|
+
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
71
|
+
* every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
|
|
69
72
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
+
* Empty segments are dropped before joining. They arise when the name starts with a dot
|
|
74
|
+
* followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
|
|
75
|
+
* an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
|
|
76
|
+
* absolute path, letting generated files escape the configured output directory.
|
|
77
|
+
*
|
|
78
|
+
* @example Nested path from a dotted name
|
|
79
|
+
* `toFilePath('pet.petId') // 'pet/petId'`
|
|
80
|
+
*
|
|
81
|
+
* @example PascalCase the final segment
|
|
82
|
+
* `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
|
|
83
|
+
*
|
|
84
|
+
* @example Suffix applied to the final segment only
|
|
85
|
+
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
73
86
|
*/
|
|
74
|
-
function
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
suffix
|
|
78
|
-
} : {}));
|
|
79
|
-
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
87
|
+
function toFilePath(name, caseLast = camelCase) {
|
|
88
|
+
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
89
|
+
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
80
90
|
}
|
|
81
91
|
//#endregion
|
|
82
92
|
//#region ../../internals/utils/src/reserved.ts
|
|
@@ -182,99 +192,80 @@ function isValidVarName(name) {
|
|
|
182
192
|
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
183
193
|
}
|
|
184
194
|
//#endregion
|
|
185
|
-
//#region ../../internals/utils/src/
|
|
195
|
+
//#region ../../internals/utils/src/url.ts
|
|
196
|
+
function transformParam(raw, casing) {
|
|
197
|
+
const param = isValidVarName(raw) ? raw : camelCase(raw);
|
|
198
|
+
return casing === "camelcase" ? camelCase(param) : param;
|
|
199
|
+
}
|
|
200
|
+
function toParamsObject(path, { replacer, casing } = {}) {
|
|
201
|
+
const params = {};
|
|
202
|
+
for (const match of path.matchAll(/\{([^}]+)\}/g)) {
|
|
203
|
+
const param = transformParam(match[1], casing);
|
|
204
|
+
const key = replacer ? replacer(param) : param;
|
|
205
|
+
params[key] = key;
|
|
206
|
+
}
|
|
207
|
+
return Object.keys(params).length > 0 ? params : null;
|
|
208
|
+
}
|
|
186
209
|
/**
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* @example
|
|
190
|
-
* const p = new URLPath('/pet/{petId}')
|
|
191
|
-
* p.URL // '/pet/:petId'
|
|
192
|
-
* p.template // '`/pet/${petId}`'
|
|
210
|
+
* Helpers for OpenAPI/Swagger paths, plus a thin wrapper over the native `URL`.
|
|
193
211
|
*/
|
|
194
|
-
var
|
|
212
|
+
var Url = class Url {
|
|
195
213
|
/**
|
|
196
|
-
*
|
|
197
|
-
*/
|
|
198
|
-
path;
|
|
199
|
-
#options;
|
|
200
|
-
constructor(path, options = {}) {
|
|
201
|
-
this.path = path;
|
|
202
|
-
this.#options = options;
|
|
203
|
-
}
|
|
204
|
-
/** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`.
|
|
214
|
+
* Reports whether `url` is a parseable absolute URL. Delegates to the native `URL.canParse`.
|
|
205
215
|
*
|
|
206
216
|
* @example
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
* ```
|
|
217
|
+
* Url.canParse('https://petstore.swagger.io/v2') // true
|
|
218
|
+
* Url.canParse('/pet/{petId}') // false
|
|
210
219
|
*/
|
|
211
|
-
|
|
212
|
-
return
|
|
220
|
+
static canParse(url, base) {
|
|
221
|
+
return URL.canParse(url, base);
|
|
213
222
|
}
|
|
214
|
-
/**
|
|
223
|
+
/**
|
|
224
|
+
* Converts an OpenAPI/Swagger path to Express-style colon syntax.
|
|
215
225
|
*
|
|
216
226
|
* @example
|
|
217
|
-
*
|
|
218
|
-
* new URLPath('https://petstore.swagger.io/v2/pet').isURL // true
|
|
219
|
-
* new URLPath('/pet/{petId}').isURL // false
|
|
220
|
-
* ```
|
|
227
|
+
* Url.toPath('/pet/{petId}') // '/pet/:petId'
|
|
221
228
|
*/
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
return !!new URL(this.path).href;
|
|
225
|
-
} catch {
|
|
226
|
-
return false;
|
|
227
|
-
}
|
|
229
|
+
static toPath(path) {
|
|
230
|
+
return path.replace(/\{([^}]+)\}/g, ":$1");
|
|
228
231
|
}
|
|
229
232
|
/**
|
|
230
|
-
* Converts
|
|
233
|
+
* Converts an OpenAPI/Swagger path to a TypeScript template literal string.
|
|
234
|
+
* `prefix` is prepended inside the literal, `replacer` transforms each parameter name,
|
|
235
|
+
* and `casing` controls parameter identifier casing.
|
|
231
236
|
*
|
|
232
237
|
* @example
|
|
233
|
-
*
|
|
234
|
-
* new URLPath('/account/monetary-accountID').template // '`/account/${monetaryAccountId}`'
|
|
235
|
-
*/
|
|
236
|
-
get template() {
|
|
237
|
-
return this.toTemplateString();
|
|
238
|
-
}
|
|
239
|
-
/** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set.
|
|
238
|
+
* Url.toTemplateString('/pet/{petId}') // '`/pet/${petId}`'
|
|
240
239
|
*
|
|
241
240
|
* @example
|
|
242
|
-
*
|
|
243
|
-
* new URLPath('/pet/{petId}').object
|
|
244
|
-
* // { url: '/pet/:petId', params: { petId: 'petId' } }
|
|
245
|
-
* ```
|
|
241
|
+
* Url.toTemplateString('/pet/{petId}', { prefix: 'https://api' }) // '`https://api/pet/${petId}`'
|
|
246
242
|
*/
|
|
247
|
-
|
|
248
|
-
|
|
243
|
+
static toTemplateString(path, { prefix, replacer, casing } = {}) {
|
|
244
|
+
const result = path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
245
|
+
if (i % 2 === 0) return part;
|
|
246
|
+
const param = transformParam(part, casing);
|
|
247
|
+
return `\${${replacer ? replacer(param) : param}}`;
|
|
248
|
+
}).join("");
|
|
249
|
+
return `\`${prefix ?? ""}${result}\``;
|
|
249
250
|
}
|
|
250
|
-
/**
|
|
251
|
+
/**
|
|
252
|
+
* Returns the path and its extracted params as a structured `URLObject`, or as a stringified
|
|
253
|
+
* expression when `stringify` is set.
|
|
251
254
|
*
|
|
252
255
|
* @example
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
* new URLPath('/pet').params // null
|
|
256
|
-
* ```
|
|
257
|
-
*/
|
|
258
|
-
get params() {
|
|
259
|
-
return this.toParamsObject();
|
|
260
|
-
}
|
|
261
|
-
#transformParam(raw) {
|
|
262
|
-
const param = isValidVarName(raw) ? raw : camelCase(raw);
|
|
263
|
-
return this.#options.casing === "camelcase" ? camelCase(param) : param;
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Iterates over every `{param}` token in `path`, calling `fn` with the raw token and transformed name.
|
|
256
|
+
* Url.toObject('/pet/{petId}')
|
|
257
|
+
* // { url: '/pet/:petId', params: { petId: 'petId' } }
|
|
267
258
|
*/
|
|
268
|
-
|
|
269
|
-
for (const match of this.path.matchAll(/\{([^}]+)\}/g)) {
|
|
270
|
-
const raw = match[1];
|
|
271
|
-
fn(raw, this.#transformParam(raw));
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
toObject({ type = "path", replacer, stringify } = {}) {
|
|
259
|
+
static toObject(path, { type = "path", replacer, stringify, casing } = {}) {
|
|
275
260
|
const object = {
|
|
276
|
-
url: type === "path" ?
|
|
277
|
-
|
|
261
|
+
url: type === "path" ? Url.toPath(path) : Url.toTemplateString(path, {
|
|
262
|
+
replacer,
|
|
263
|
+
casing
|
|
264
|
+
}),
|
|
265
|
+
params: toParamsObject(path, {
|
|
266
|
+
replacer,
|
|
267
|
+
casing
|
|
268
|
+
})
|
|
278
269
|
};
|
|
279
270
|
if (stringify) {
|
|
280
271
|
if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
|
|
@@ -283,57 +274,13 @@ var URLPath = class {
|
|
|
283
274
|
}
|
|
284
275
|
return object;
|
|
285
276
|
}
|
|
286
|
-
/**
|
|
287
|
-
* Converts the OpenAPI path to a TypeScript template literal string.
|
|
288
|
-
* An optional `replacer` can transform each extracted parameter name before interpolation.
|
|
289
|
-
*
|
|
290
|
-
* @example
|
|
291
|
-
* new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'
|
|
292
|
-
*/
|
|
293
|
-
toTemplateString({ prefix, replacer } = {}) {
|
|
294
|
-
const result = this.path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
295
|
-
if (i % 2 === 0) return part;
|
|
296
|
-
const param = this.#transformParam(part);
|
|
297
|
-
return `\${${replacer ? replacer(param) : param}}`;
|
|
298
|
-
}).join("");
|
|
299
|
-
return `\`${prefix ?? ""}${result}\``;
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Extracts all `{param}` segments from the path and returns them as a key-value map.
|
|
303
|
-
* An optional `replacer` transforms each parameter name in both key and value positions.
|
|
304
|
-
* Returns `undefined` when no path parameters are found.
|
|
305
|
-
*
|
|
306
|
-
* @example
|
|
307
|
-
* ```ts
|
|
308
|
-
* new URLPath('/pet/{petId}/tag/{tagId}').toParamsObject()
|
|
309
|
-
* // { petId: 'petId', tagId: 'tagId' }
|
|
310
|
-
* ```
|
|
311
|
-
*/
|
|
312
|
-
toParamsObject(replacer) {
|
|
313
|
-
const params = {};
|
|
314
|
-
this.#eachParam((_raw, param) => {
|
|
315
|
-
const key = replacer ? replacer(param) : param;
|
|
316
|
-
params[key] = key;
|
|
317
|
-
});
|
|
318
|
-
return Object.keys(params).length > 0 ? params : null;
|
|
319
|
-
}
|
|
320
|
-
/** Converts the OpenAPI path to Express-style colon syntax.
|
|
321
|
-
*
|
|
322
|
-
* @example
|
|
323
|
-
* ```ts
|
|
324
|
-
* new URLPath('/pet/{petId}').toURLPath() // '/pet/:petId'
|
|
325
|
-
* ```
|
|
326
|
-
*/
|
|
327
|
-
toURLPath() {
|
|
328
|
-
return this.path.replace(/\{([^}]+)\}/g, ":$1");
|
|
329
|
-
}
|
|
330
277
|
};
|
|
331
278
|
//#endregion
|
|
332
279
|
//#region ../../internals/shared/src/operation.ts
|
|
333
280
|
function getOperationLink(node, link) {
|
|
334
281
|
if (!link) return null;
|
|
335
282
|
if (typeof link === "function") return link(node) ?? null;
|
|
336
|
-
if (link === "urlPath") return node.path ? `{@link ${
|
|
283
|
+
if (link === "urlPath") return node.path ? `{@link ${Url.toPath(node.path)}}` : null;
|
|
337
284
|
return node.path ? `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}` : null;
|
|
338
285
|
}
|
|
339
286
|
function buildOperationComments(node, options = {}) {
|
|
@@ -354,7 +301,7 @@ function buildOperationComments(node, options = {}) {
|
|
|
354
301
|
return filteredComments.flatMap((text) => text.split(/\r?\n/).map((line) => line.trim())).filter((comment) => Boolean(comment));
|
|
355
302
|
}
|
|
356
303
|
function getOperationParameters(node, options = {}) {
|
|
357
|
-
const params =
|
|
304
|
+
const params = (0, _kubb_ast_utils.caseParams)(node.parameters, options.paramsCasing);
|
|
358
305
|
return {
|
|
359
306
|
path: params.filter((param) => param.in === "path"),
|
|
360
307
|
query: params.filter((param) => param.in === "query"),
|
|
@@ -423,26 +370,24 @@ function findSuccessStatusCode(responses) {
|
|
|
423
370
|
* shared default naming so every plugin groups output consistently:
|
|
424
371
|
*
|
|
425
372
|
* - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).
|
|
426
|
-
* - other groups use
|
|
373
|
+
* - other groups use the camelCased group (`pet store` → `petStore`).
|
|
427
374
|
*
|
|
428
375
|
* A user-provided `group.name` always wins over the default namer, so callers stay in
|
|
429
376
|
* control of their output folders. Returns `null` when grouping is disabled, matching the
|
|
430
377
|
* per-plugin convention.
|
|
431
378
|
*
|
|
432
379
|
* @param group - The user-supplied group option, or `undefined` to disable grouping.
|
|
433
|
-
* @param options.suffix - Appended to non-`path` group names, e.g. `'Controller'` or `'Requests'`.
|
|
434
380
|
*
|
|
435
381
|
* @example
|
|
436
382
|
* ```ts
|
|
437
|
-
* createGroupConfig(group
|
|
438
|
-
* createGroupConfig(group, { suffix: 'Requests' }) // plugin-cypress, plugin-mcp
|
|
383
|
+
* createGroupConfig(group) // shared across every plugin
|
|
439
384
|
* ```
|
|
440
385
|
*/
|
|
441
|
-
function createGroupConfig(group
|
|
386
|
+
function createGroupConfig(group) {
|
|
442
387
|
if (!group) return null;
|
|
443
388
|
const defaultName = (ctx) => {
|
|
444
389
|
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
445
|
-
return
|
|
390
|
+
return camelCase(ctx.group);
|
|
446
391
|
};
|
|
447
392
|
return {
|
|
448
393
|
...group,
|
|
@@ -479,7 +424,6 @@ function buildRemappingCode(mapping, varName, sourceName) {
|
|
|
479
424
|
const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
480
425
|
function McpHandler({ name, node, resolver, baseURL, dataReturnType, paramsCasing }) {
|
|
481
426
|
if (!_kubb_core.ast.isHttpOperationNode(node)) return null;
|
|
482
|
-
const urlPath = new URLPath(node.path);
|
|
483
427
|
const contentType = node.requestBody?.content?.[0]?.contentType;
|
|
484
428
|
const isFormData = contentType === "multipart/form-data";
|
|
485
429
|
const { query: queryParams, header: headerParams } = getOperationParameters(node, { paramsCasing });
|
|
@@ -492,7 +436,7 @@ function McpHandler({ name, node, resolver, baseURL, dataReturnType, paramsCasin
|
|
|
492
436
|
`ResponseErrorConfig<${errorResponses.length > 0 ? errorResponses.join(" | ") : "Error"}>`,
|
|
493
437
|
requestName || "unknown"
|
|
494
438
|
].filter(Boolean);
|
|
495
|
-
const paramsNode =
|
|
439
|
+
const paramsNode = (0, _kubb_ast_utils.createOperationParams)(node, {
|
|
496
440
|
paramsType: "object",
|
|
497
441
|
pathParamsType: "inline",
|
|
498
442
|
resolver,
|
|
@@ -507,28 +451,20 @@ function McpHandler({ name, node, resolver, baseURL, dataReturnType, paramsCasin
|
|
|
507
451
|
const headers = [headerParams.length ? headerParamsMapping ? "...mappedHeaders" : "...headers" : null, contentTypeHeader].filter(Boolean);
|
|
508
452
|
const fetchConfig = [];
|
|
509
453
|
fetchConfig.push(`method: ${JSON.stringify(node.method.toUpperCase())}`);
|
|
510
|
-
fetchConfig.push(`url: ${
|
|
454
|
+
fetchConfig.push(`url: ${Url.toTemplateString(node.path)}`);
|
|
511
455
|
if (baseURL) fetchConfig.push(`baseURL: \`${baseURL}\``);
|
|
512
456
|
if (queryParams.length) fetchConfig.push(queryParamsMapping ? "params: mappedParams" : "params");
|
|
513
457
|
if (requestName) fetchConfig.push(`data: ${isFormData ? "formData as FormData" : "requestData"}`);
|
|
514
458
|
if (headers.length) fetchConfig.push(`headers: { ${headers.join(", ")} }`);
|
|
515
|
-
const callToolResult =
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
content: [
|
|
525
|
-
{
|
|
526
|
-
type: 'text',
|
|
527
|
-
text: JSON.stringify(res)
|
|
528
|
-
}
|
|
529
|
-
],
|
|
530
|
-
structuredContent: { data: res.data }
|
|
531
|
-
}`;
|
|
459
|
+
const callToolResult = `return {
|
|
460
|
+
content: [
|
|
461
|
+
{
|
|
462
|
+
type: 'text',
|
|
463
|
+
text: JSON.stringify(${dataReturnType === "data" ? "res.data" : "res"})
|
|
464
|
+
}
|
|
465
|
+
],
|
|
466
|
+
structuredContent: { data: res.data }
|
|
467
|
+
}`;
|
|
532
468
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
|
|
533
469
|
name,
|
|
534
470
|
isExportable: true,
|
|
@@ -602,7 +538,7 @@ function zodExprFromSchemaNode(schema) {
|
|
|
602
538
|
}
|
|
603
539
|
//#endregion
|
|
604
540
|
//#region src/components/Server.tsx
|
|
605
|
-
const keysPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "
|
|
541
|
+
const keysPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
|
|
606
542
|
function Server({ name, serverName, serverVersion, paramsCasing, operations }) {
|
|
607
543
|
const registrations = operations.map(({ tool, mcp, zod, node }) => {
|
|
608
544
|
const { path: pathParams } = getOperationParameters(node, { paramsCasing });
|
|
@@ -629,10 +565,11 @@ function Server({ name, serverName, serverVersion, paramsCasing, operations }) {
|
|
|
629
565
|
});
|
|
630
566
|
otherEntries.sort((a, b) => a.key.localeCompare(b.key));
|
|
631
567
|
const entries = [...pathEntries, ...otherEntries];
|
|
632
|
-
const paramsNode = entries.length ? _kubb_core.ast.createFunctionParameters({ params: [
|
|
633
|
-
|
|
568
|
+
const paramsNode = entries.length ? _kubb_core.ast.factory.createFunctionParameters({ params: [{
|
|
569
|
+
kind: "FunctionParameter",
|
|
570
|
+
name: _kubb_core.ast.factory.createObjectBindingPattern({ elements: entries.map((e) => ({ name: e.key })) }),
|
|
634
571
|
optional: false
|
|
635
|
-
}
|
|
572
|
+
}] }) : null;
|
|
636
573
|
const destructured = paramsNode ? keysPrinter.print(paramsNode) ?? "" : "";
|
|
637
574
|
const inputSchema = entries.length ? `{ ${entries.map((e) => `${e.key}: ${e.value}`).join(", ")} }` : null;
|
|
638
575
|
const outputSchema = zod.responseName;
|
|
@@ -703,7 +640,7 @@ return server`
|
|
|
703
640
|
*/
|
|
704
641
|
const mcpGenerator = (0, _kubb_core.defineGenerator)({
|
|
705
642
|
name: "mcp",
|
|
706
|
-
renderer: _kubb_renderer_jsx.
|
|
643
|
+
renderer: _kubb_renderer_jsx.jsxRenderer,
|
|
707
644
|
operation(node, ctx) {
|
|
708
645
|
if (!_kubb_core.ast.isHttpOperationNode(node)) return null;
|
|
709
646
|
const { resolver, driver, root } = ctx;
|
|
@@ -833,7 +770,7 @@ const mcpGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
833
770
|
*/
|
|
834
771
|
const serverGenerator = (0, _kubb_core.defineGenerator)({
|
|
835
772
|
name: "operations",
|
|
836
|
-
renderer: _kubb_renderer_jsx.
|
|
773
|
+
renderer: _kubb_renderer_jsx.jsxRenderer,
|
|
837
774
|
operations(nodes, ctx) {
|
|
838
775
|
const { config, resolver, plugin, driver, root } = ctx;
|
|
839
776
|
const { output, paramsCasing, group } = ctx.options;
|
|
@@ -1001,7 +938,7 @@ const resolverMcp = (0, _kubb_core.defineResolver)(() => ({
|
|
|
1001
938
|
name: "default",
|
|
1002
939
|
pluginName: "plugin-mcp",
|
|
1003
940
|
default(name, type) {
|
|
1004
|
-
if (type === "file") return
|
|
941
|
+
if (type === "file") return toFilePath(name);
|
|
1005
942
|
return camelCase(name, { suffix: "handler" });
|
|
1006
943
|
},
|
|
1007
944
|
resolveName(name) {
|
|
@@ -1052,11 +989,11 @@ const pluginMcpName = "plugin-mcp";
|
|
|
1052
989
|
const pluginMcp = (0, _kubb_core.definePlugin)((options) => {
|
|
1053
990
|
const { output = {
|
|
1054
991
|
path: "mcp",
|
|
1055
|
-
|
|
1056
|
-
}, group, exclude = [], include, override = [], paramsCasing, client, resolver: userResolver,
|
|
992
|
+
barrel: { type: "named" }
|
|
993
|
+
}, group, exclude = [], include, override = [], paramsCasing, client, resolver: userResolver, macros: userMacros, generators: userGenerators = [] } = options;
|
|
1057
994
|
const clientName = client?.client ?? "axios";
|
|
1058
995
|
const clientImportPath = client?.importPath ?? (!client?.bundle ? `@kubb/plugin-client/clients/${clientName}` : void 0);
|
|
1059
|
-
const groupConfig = createGroupConfig(group
|
|
996
|
+
const groupConfig = createGroupConfig(group);
|
|
1060
997
|
return {
|
|
1061
998
|
name: pluginMcpName,
|
|
1062
999
|
options,
|
|
@@ -1085,7 +1022,7 @@ const pluginMcp = (0, _kubb_core.definePlugin)((options) => {
|
|
|
1085
1022
|
resolver
|
|
1086
1023
|
});
|
|
1087
1024
|
ctx.setResolver(resolver);
|
|
1088
|
-
if (
|
|
1025
|
+
if (userMacros?.length) ctx.setMacros(userMacros);
|
|
1089
1026
|
ctx.addGenerator(mcpGenerator);
|
|
1090
1027
|
ctx.addGenerator(serverGenerator);
|
|
1091
1028
|
for (const gen of userGenerators) ctx.addGenerator(gen);
|
|
@@ -1094,9 +1031,9 @@ const pluginMcp = (0, _kubb_core.definePlugin)((options) => {
|
|
|
1094
1031
|
if (client?.bundle && !hasClientPlugin && !clientImportPath) ctx.injectFile({
|
|
1095
1032
|
baseName: "client.ts",
|
|
1096
1033
|
path: node_path$1.default.resolve(root, ".kubb/client.ts"),
|
|
1097
|
-
sources: [_kubb_core.ast.createSource({
|
|
1034
|
+
sources: [_kubb_core.ast.factory.createSource({
|
|
1098
1035
|
name: "client",
|
|
1099
|
-
nodes: [_kubb_core.ast.createText(clientName === "fetch" ? _kubb_plugin_client_templates_clients_fetch_source.source : _kubb_plugin_client_templates_clients_axios_source.source)],
|
|
1036
|
+
nodes: [_kubb_core.ast.factory.createText(clientName === "fetch" ? _kubb_plugin_client_templates_clients_fetch_source.source : _kubb_plugin_client_templates_clients_axios_source.source)],
|
|
1100
1037
|
isExportable: true,
|
|
1101
1038
|
isIndexable: true
|
|
1102
1039
|
})]
|
|
@@ -1104,9 +1041,9 @@ const pluginMcp = (0, _kubb_core.definePlugin)((options) => {
|
|
|
1104
1041
|
if (!hasClientPlugin) ctx.injectFile({
|
|
1105
1042
|
baseName: "config.ts",
|
|
1106
1043
|
path: node_path$1.default.resolve(root, ".kubb/config.ts"),
|
|
1107
|
-
sources: [_kubb_core.ast.createSource({
|
|
1044
|
+
sources: [_kubb_core.ast.factory.createSource({
|
|
1108
1045
|
name: "config",
|
|
1109
|
-
nodes: [_kubb_core.ast.createText(_kubb_plugin_client_templates_config_source.source)],
|
|
1046
|
+
nodes: [_kubb_core.ast.factory.createText(_kubb_plugin_client_templates_config_source.source)],
|
|
1110
1047
|
isExportable: false,
|
|
1111
1048
|
isIndexable: false
|
|
1112
1049
|
})]
|