@kubb/plugin-mcp 5.0.0-beta.64 → 5.0.0-beta.74
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/README.md +2 -2
- package/dist/index.cjs +297 -264
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +126 -119
- package/dist/index.js +297 -263
- package/dist/index.js.map +1 -1
- package/package.json +10 -11
- /package/dist/{chunk-C0LytTxp.js → rolldown-runtime-C0LytTxp.js} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -25,18 +25,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
}) : target, mod));
|
|
26
26
|
//#endregion
|
|
27
27
|
let node_path = require("node:path");
|
|
28
|
-
|
|
29
|
-
node_path = __toESM(node_path);
|
|
28
|
+
node_path = __toESM(node_path, 1);
|
|
30
29
|
let _kubb_core = require("@kubb/core");
|
|
31
|
-
let _kubb_ast_utils = require("@kubb/ast/utils");
|
|
32
|
-
let _kubb_plugin_ts = require("@kubb/plugin-ts");
|
|
33
30
|
let _kubb_renderer_jsx = require("@kubb/renderer-jsx");
|
|
34
31
|
let _kubb_renderer_jsx_jsx_runtime = require("@kubb/renderer-jsx/jsx-runtime");
|
|
32
|
+
let _kubb_plugin_ts = require("@kubb/plugin-ts");
|
|
35
33
|
let _kubb_plugin_zod = require("@kubb/plugin-zod");
|
|
36
|
-
let _kubb_plugin_client = require("@kubb/plugin-client");
|
|
37
|
-
let _kubb_plugin_client_templates_clients_axios_source = require("@kubb/plugin-client/templates/clients/axios.source");
|
|
38
|
-
let _kubb_plugin_client_templates_clients_fetch_source = require("@kubb/plugin-client/templates/clients/fetch.source");
|
|
39
|
-
let _kubb_plugin_client_templates_config_source = require("@kubb/plugin-client/templates/config.source");
|
|
40
34
|
//#region ../../internals/utils/src/casing.ts
|
|
41
35
|
/**
|
|
42
36
|
* Shared implementation for camelCase and PascalCase conversion.
|
|
@@ -249,6 +243,22 @@ var Url = class Url {
|
|
|
249
243
|
return `\`${prefix ?? ""}${result}\``;
|
|
250
244
|
}
|
|
251
245
|
/**
|
|
246
|
+
* Converts an OpenAPI/Swagger path to a template literal that reads each parameter off the
|
|
247
|
+
* grouped `path` request option, e.g. `/pet/{petId}` becomes `` `/pet/${path.petId}` ``. Parameter
|
|
248
|
+
* names are camelCased to match the generated `path` type, and `prefix` is prepended inside the
|
|
249
|
+
* literal. Shared by the client and cypress generators that pass a grouped `path` object.
|
|
250
|
+
*
|
|
251
|
+
* @example
|
|
252
|
+
* Url.toGroupedTemplateString('/pet/{petId}') // '`/pet/${path.petId}`'
|
|
253
|
+
*/
|
|
254
|
+
static toGroupedTemplateString(path, { prefix } = {}) {
|
|
255
|
+
return Url.toTemplateString(path, {
|
|
256
|
+
prefix,
|
|
257
|
+
casing: "camelcase",
|
|
258
|
+
replacer: (name) => `path.${name}`
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
252
262
|
* Returns the path and its extracted params as a structured `URLObject`, or as a stringified
|
|
253
263
|
* expression when `stringify` is set.
|
|
254
264
|
*
|
|
@@ -276,13 +286,121 @@ var Url = class Url {
|
|
|
276
286
|
}
|
|
277
287
|
};
|
|
278
288
|
//#endregion
|
|
289
|
+
//#region ../../internals/shared/src/params.ts
|
|
290
|
+
const caseParamsCache = /* @__PURE__ */ new WeakMap();
|
|
291
|
+
/**
|
|
292
|
+
* Applies camelCase to parameter names and returns a new array without mutating the input.
|
|
293
|
+
*
|
|
294
|
+
* Run it before handing parameters to schema builders so output property keys get the right casing
|
|
295
|
+
* while `OperationNode.parameters` stays intact for other consumers. When `casing` is unset, the
|
|
296
|
+
* original array is returned unchanged. Results are cached per input array.
|
|
297
|
+
*/
|
|
298
|
+
function caseParams(params, casing) {
|
|
299
|
+
if (!casing) return params;
|
|
300
|
+
const cached = caseParamsCache.get(params);
|
|
301
|
+
if (cached) return cached;
|
|
302
|
+
const result = params.map((param) => ({
|
|
303
|
+
...param,
|
|
304
|
+
name: camelCase(param.name)
|
|
305
|
+
}));
|
|
306
|
+
caseParamsCache.set(params, result);
|
|
307
|
+
return result;
|
|
308
|
+
}
|
|
309
|
+
//#endregion
|
|
279
310
|
//#region ../../internals/shared/src/operation.ts
|
|
311
|
+
/**
|
|
312
|
+
* Builds the `ResolverFileParams` every operation generator passes to
|
|
313
|
+
* `resolver.resolveFile`: a file named `name`, tagged by the operation's first
|
|
314
|
+
* tag (or `'default'`), at the operation's path. Centralizes the entry object
|
|
315
|
+
* that was repeated at dozens of call sites across the client and query plugins.
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```ts
|
|
319
|
+
* resolver.resolveFile(operationFileEntry(node, node.operationId), { root, output, group })
|
|
320
|
+
* ```
|
|
321
|
+
*/
|
|
322
|
+
function operationFileEntry(node, name, extname = ".ts") {
|
|
323
|
+
return {
|
|
324
|
+
name,
|
|
325
|
+
extname,
|
|
326
|
+
tag: node.tags[0] ?? "default",
|
|
327
|
+
path: node.path
|
|
328
|
+
};
|
|
329
|
+
}
|
|
280
330
|
function getOperationLink(node, link) {
|
|
281
331
|
if (!link) return null;
|
|
282
332
|
if (typeof link === "function") return link(node) ?? null;
|
|
283
333
|
if (link === "urlPath") return node.path ? `{@link ${Url.toPath(node.path)}}` : null;
|
|
284
334
|
return node.path ? `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}` : null;
|
|
285
335
|
}
|
|
336
|
+
function getContentTypeInfo(node) {
|
|
337
|
+
const contentTypes = node.requestBody?.content?.map((e) => e.contentType) ?? [];
|
|
338
|
+
const isMultipleContentTypes = contentTypes.length > 1;
|
|
339
|
+
return {
|
|
340
|
+
contentTypes,
|
|
341
|
+
isMultipleContentTypes,
|
|
342
|
+
contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(" | ") : "",
|
|
343
|
+
defaultContentType: contentTypes[0] ?? "application/json",
|
|
344
|
+
hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
function buildRequestConfigType(node) {
|
|
348
|
+
const { isMultipleContentTypes, contentTypeUnion } = getContentTypeInfo(node);
|
|
349
|
+
const configType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
|
|
350
|
+
const contentTypeProp = isMultipleContentTypes ? `contentType?: ${contentTypeUnion}` : null;
|
|
351
|
+
return contentTypeProp ? `${configType} & { ${contentTypeProp} }` : configType;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Which of the grouped request options an operation carries.
|
|
355
|
+
*/
|
|
356
|
+
function getRequestGroups(node) {
|
|
357
|
+
const { path, query, header } = getOperationParameters(node);
|
|
358
|
+
return {
|
|
359
|
+
path: path.length > 0,
|
|
360
|
+
query: query.length > 0,
|
|
361
|
+
body: Boolean(node.requestBody?.content?.[0]?.schema),
|
|
362
|
+
headers: header.length > 0
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Resolves which grouped request options an operation carries together with whether each group
|
|
367
|
+
* holds a required member. The grouped parameter stays optional only when nothing inside it is
|
|
368
|
+
* required, matching the generated `RequestConfig` type.
|
|
369
|
+
*/
|
|
370
|
+
function getRequestGroupOptionality(node) {
|
|
371
|
+
const groups = getRequestGroups(node);
|
|
372
|
+
const { path, query, header } = getOperationParameters(node);
|
|
373
|
+
const hasRequiredPath = path.some((param) => param.required);
|
|
374
|
+
const hasRequiredQuery = query.some((param) => param.required);
|
|
375
|
+
const hasRequiredHeader = header.some((param) => param.required);
|
|
376
|
+
return {
|
|
377
|
+
groups,
|
|
378
|
+
hasRequiredPath,
|
|
379
|
+
hasRequiredQuery,
|
|
380
|
+
hasRequiredHeader,
|
|
381
|
+
isOptional: !hasRequiredPath && !hasRequiredQuery && !hasRequiredHeader && !groups.body
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Builds the grouped `{ path, query, body, headers }` parameter for a generated client
|
|
386
|
+
* function, typed from the operation's `RequestConfig` (minus `url`). Only the groups the
|
|
387
|
+
* operation actually has are destructured. The trailing `config` parameter carries the
|
|
388
|
+
* runtime `RequestConfig` overrides plus `client`.
|
|
389
|
+
*/
|
|
390
|
+
function buildRequestParamsSignature(node, resolver, options = {}) {
|
|
391
|
+
const { isConfigurable = true } = options;
|
|
392
|
+
const { groups, isOptional } = getRequestGroupOptionality(node);
|
|
393
|
+
const names = [
|
|
394
|
+
"path",
|
|
395
|
+
"query",
|
|
396
|
+
"body",
|
|
397
|
+
"headers"
|
|
398
|
+
].filter((key) => groups[key]);
|
|
399
|
+
return {
|
|
400
|
+
signature: [names.length > 0 ? `{ ${names.join(", ")} }: ${resolver.resolveRequestConfigName(node)}${isOptional ? " = {}" : ""}` : null, isConfigurable ? `config: ${buildRequestConfigType(node)} = {}` : null].filter(Boolean).join(", "),
|
|
401
|
+
groups
|
|
402
|
+
};
|
|
403
|
+
}
|
|
286
404
|
function buildOperationComments(node, options = {}) {
|
|
287
405
|
const { link = "pathTemplate", linkPosition = "afterDeprecated", splitLines = false } = options;
|
|
288
406
|
const linkComment = getOperationLink(node, link);
|
|
@@ -301,7 +419,7 @@ function buildOperationComments(node, options = {}) {
|
|
|
301
419
|
return filteredComments.flatMap((text) => text.split(/\r?\n/).map((line) => line.trim())).filter((comment) => Boolean(comment));
|
|
302
420
|
}
|
|
303
421
|
function getOperationParameters(node, options = {}) {
|
|
304
|
-
const params =
|
|
422
|
+
const params = caseParams(node.parameters, options.paramsCasing === "original" ? void 0 : "camelcase");
|
|
305
423
|
return {
|
|
306
424
|
path: params.filter((param) => param.in === "path"),
|
|
307
425
|
query: params.filter((param) => param.in === "query"),
|
|
@@ -317,48 +435,6 @@ function isSuccessStatusCode(statusCode) {
|
|
|
317
435
|
const code = getStatusCodeNumber(statusCode);
|
|
318
436
|
return code !== null && code >= 200 && code < 300;
|
|
319
437
|
}
|
|
320
|
-
function isErrorStatusCode(statusCode) {
|
|
321
|
-
const code = getStatusCodeNumber(statusCode);
|
|
322
|
-
return code !== null && code >= 400;
|
|
323
|
-
}
|
|
324
|
-
function resolveErrorNames(node, resolver) {
|
|
325
|
-
return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
|
|
326
|
-
}
|
|
327
|
-
function resolveStatusCodeNames(node, resolver) {
|
|
328
|
-
return node.responses.map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
|
|
329
|
-
}
|
|
330
|
-
const typeNamesByResolver = /* @__PURE__ */ new WeakMap();
|
|
331
|
-
function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
332
|
-
const cacheKey = `${node.operationId}\0${options.paramsCasing ?? ""}\0${options.order ?? ""}\0${options.responseStatusNames ?? ""}\0${(options.exclude ?? []).join(",")}`;
|
|
333
|
-
let byResolver = typeNamesByResolver.get(resolver);
|
|
334
|
-
if (byResolver) {
|
|
335
|
-
const cached = byResolver.get(cacheKey);
|
|
336
|
-
if (cached) return cached;
|
|
337
|
-
} else {
|
|
338
|
-
byResolver = /* @__PURE__ */ new Map();
|
|
339
|
-
typeNamesByResolver.set(resolver, byResolver);
|
|
340
|
-
}
|
|
341
|
-
const { path, query, header } = getOperationParameters(node, { paramsCasing: options.paramsCasing });
|
|
342
|
-
const responseStatusNames = options.responseStatusNames === "error" ? resolveErrorNames(node, resolver) : options.responseStatusNames === false ? [] : resolveStatusCodeNames(node, resolver);
|
|
343
|
-
const exclude = new Set(options.exclude ?? []);
|
|
344
|
-
const paramNames = [
|
|
345
|
-
...path.map((param) => resolver.resolvePathParamsName(node, param)),
|
|
346
|
-
...query.map((param) => resolver.resolveQueryParamsName(node, param)),
|
|
347
|
-
...header.map((param) => resolver.resolveHeaderParamsName(node, param))
|
|
348
|
-
];
|
|
349
|
-
const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null, resolver.resolveResponseName(node)];
|
|
350
|
-
const result = (options.order === "body-response-first" ? [
|
|
351
|
-
...bodyAndResponseNames,
|
|
352
|
-
...paramNames,
|
|
353
|
-
...responseStatusNames
|
|
354
|
-
] : [
|
|
355
|
-
...paramNames,
|
|
356
|
-
...bodyAndResponseNames,
|
|
357
|
-
...responseStatusNames
|
|
358
|
-
]).filter((name) => Boolean(name) && !exclude.has(name));
|
|
359
|
-
byResolver.set(cacheKey, result);
|
|
360
|
-
return result;
|
|
361
|
-
}
|
|
362
438
|
function findSuccessStatusCode(responses) {
|
|
363
439
|
for (const response of responses) if (isSuccessStatusCode(response.statusCode)) return response.statusCode;
|
|
364
440
|
return null;
|
|
@@ -395,76 +471,19 @@ function createGroupConfig(group) {
|
|
|
395
471
|
};
|
|
396
472
|
}
|
|
397
473
|
//#endregion
|
|
398
|
-
//#region ../../internals/shared/src/params.ts
|
|
399
|
-
function buildParamsMapping(originalParams, mappedParams) {
|
|
400
|
-
const mapping = {};
|
|
401
|
-
let hasChanged = false;
|
|
402
|
-
originalParams.forEach((param, i) => {
|
|
403
|
-
const mappedName = mappedParams[i]?.name ?? param.name;
|
|
404
|
-
mapping[param.name] = mappedName;
|
|
405
|
-
if (param.name !== mappedName) hasChanged = true;
|
|
406
|
-
});
|
|
407
|
-
return hasChanged ? mapping : null;
|
|
408
|
-
}
|
|
409
|
-
function buildTransformedParamsMapping(params, transformName) {
|
|
410
|
-
if (!params.length) return null;
|
|
411
|
-
return buildParamsMapping(params, params.map((param) => ({
|
|
412
|
-
...param,
|
|
413
|
-
name: transformName(param.name)
|
|
414
|
-
})));
|
|
415
|
-
}
|
|
416
|
-
//#endregion
|
|
417
474
|
//#region src/components/McpHandler.tsx
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
function McpHandler({ name, node, resolver, baseURL, dataReturnType, paramsCasing }) {
|
|
475
|
+
const requestGroupOrder = [
|
|
476
|
+
"path",
|
|
477
|
+
"query",
|
|
478
|
+
"headers",
|
|
479
|
+
"body"
|
|
480
|
+
];
|
|
481
|
+
function McpHandler({ name, clientName, node, resolver }) {
|
|
426
482
|
if (!_kubb_core.ast.isHttpOperationNode(node)) return null;
|
|
427
|
-
const
|
|
428
|
-
const
|
|
429
|
-
const
|
|
430
|
-
const
|
|
431
|
-
const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null;
|
|
432
|
-
const responseName = resolver.resolveResponseName(node);
|
|
433
|
-
const errorResponses = node.responses.filter((r) => Number(r.statusCode) >= 400).map((r) => resolver.resolveResponseStatusName(node, r.statusCode));
|
|
434
|
-
const generics = [
|
|
435
|
-
responseName,
|
|
436
|
-
`ResponseErrorConfig<${errorResponses.length > 0 ? errorResponses.join(" | ") : "Error"}>`,
|
|
437
|
-
requestName || "unknown"
|
|
438
|
-
].filter(Boolean);
|
|
439
|
-
const paramsNode = (0, _kubb_ast_utils.createOperationParams)(node, {
|
|
440
|
-
paramsType: "object",
|
|
441
|
-
pathParamsType: "inline",
|
|
442
|
-
resolver,
|
|
443
|
-
paramsCasing
|
|
444
|
-
});
|
|
445
|
-
const baseParamsSignature = declarationPrinter.print(paramsNode) ?? "";
|
|
446
|
-
const paramsSignature = baseParamsSignature ? `${baseParamsSignature}, request: RequestHandlerExtra<ServerRequest, ServerNotification>` : "request: RequestHandlerExtra<ServerRequest, ServerNotification>";
|
|
447
|
-
const pathParamsMapping = paramsCasing ? buildTransformedParamsMapping(originalPathParams, camelCase) : null;
|
|
448
|
-
const queryParamsMapping = paramsCasing ? buildTransformedParamsMapping(originalQueryParams, camelCase) : null;
|
|
449
|
-
const headerParamsMapping = paramsCasing ? buildTransformedParamsMapping(originalHeaderParams, camelCase) : null;
|
|
450
|
-
const contentTypeHeader = contentType && contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` : null;
|
|
451
|
-
const headers = [headerParams.length ? headerParamsMapping ? "...mappedHeaders" : "...headers" : null, contentTypeHeader].filter(Boolean);
|
|
452
|
-
const fetchConfig = [];
|
|
453
|
-
fetchConfig.push(`method: ${JSON.stringify(node.method.toUpperCase())}`);
|
|
454
|
-
fetchConfig.push(`url: ${Url.toTemplateString(node.path)}`);
|
|
455
|
-
if (baseURL) fetchConfig.push(`baseURL: \`${baseURL}\``);
|
|
456
|
-
if (queryParams.length) fetchConfig.push(queryParamsMapping ? "params: mappedParams" : "params");
|
|
457
|
-
if (requestName) fetchConfig.push(`data: ${isFormData ? "formData as FormData" : "requestData"}`);
|
|
458
|
-
if (headers.length) fetchConfig.push(`headers: { ${headers.join(", ")} }`);
|
|
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
|
-
}`;
|
|
483
|
+
const { signature, groups } = buildRequestParamsSignature(node, resolver, { isConfigurable: false });
|
|
484
|
+
const paramsSignature = [signature, "request: RequestHandlerExtra<ServerRequest, ServerNotification>"].filter(Boolean).join(", ");
|
|
485
|
+
const callArgs = requestGroupOrder.filter((key) => groups[key]);
|
|
486
|
+
const callConfig = callArgs.length ? `{ ${callArgs.join(", ")} }` : "{}";
|
|
468
487
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
|
|
469
488
|
name,
|
|
470
489
|
isExportable: true,
|
|
@@ -477,28 +496,17 @@ function McpHandler({ name, node, resolver, baseURL, dataReturnType, paramsCasin
|
|
|
477
496
|
JSDoc: { comments: buildOperationComments(node) },
|
|
478
497
|
returnType: "Promise<CallToolResult>",
|
|
479
498
|
children: [
|
|
480
|
-
|
|
481
|
-
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
|
|
482
|
-
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
|
|
483
|
-
pathParamsMapping && Object.entries(pathParamsMapping).filter(([originalName, camelCaseName]) => originalName !== camelCaseName && isValidVarName(originalName)).map(([originalName, camelCaseName]) => `const ${originalName} = ${camelCaseName}`).join("\n"),
|
|
484
|
-
pathParamsMapping && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}), /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {})] }),
|
|
485
|
-
queryParamsMapping && queryParams.length > 0 && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
|
|
486
|
-
buildRemappingCode(queryParamsMapping, "mappedParams", "params"),
|
|
487
|
-
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
|
|
488
|
-
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {})
|
|
489
|
-
] }),
|
|
490
|
-
headerParamsMapping && headerParams.length > 0 && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
|
|
491
|
-
buildRemappingCode(headerParamsMapping, "mappedHeaders", "headers"),
|
|
492
|
-
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
|
|
493
|
-
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {})
|
|
494
|
-
] }),
|
|
495
|
-
requestName && "const requestData = data",
|
|
496
|
-
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
|
|
497
|
-
isFormData && requestName && "const formData = buildFormData(requestData)",
|
|
499
|
+
`const res = await ${clientName}(${callConfig})`,
|
|
498
500
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
|
|
499
|
-
`
|
|
500
|
-
|
|
501
|
-
|
|
501
|
+
`return {
|
|
502
|
+
content: [
|
|
503
|
+
{
|
|
504
|
+
type: 'text',
|
|
505
|
+
text: JSON.stringify(res.data)
|
|
506
|
+
}
|
|
507
|
+
],
|
|
508
|
+
structuredContent: { data: res.data }
|
|
509
|
+
}`
|
|
502
510
|
]
|
|
503
511
|
})
|
|
504
512
|
});
|
|
@@ -539,37 +547,36 @@ function zodExprFromSchemaNode(schema) {
|
|
|
539
547
|
//#endregion
|
|
540
548
|
//#region src/components/Server.tsx
|
|
541
549
|
const keysPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
|
|
542
|
-
function Server({ name, serverName, serverVersion,
|
|
550
|
+
function Server({ name, serverName, serverVersion, operations }) {
|
|
543
551
|
const registrations = operations.map(({ tool, mcp, zod, node }) => {
|
|
544
|
-
const { path: pathParams } = getOperationParameters(node
|
|
545
|
-
const
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
+
const { path: pathParams } = getOperationParameters(node);
|
|
553
|
+
const entries = [];
|
|
554
|
+
if (pathParams.length) {
|
|
555
|
+
const pathFields = pathParams.map((p) => {
|
|
556
|
+
const zodParam = zod.pathParams.find((zp) => zp.name === p.name);
|
|
557
|
+
return `${JSON.stringify(p.name)}: ${zodParam ? zodParam.schemaName : zodExprFromSchemaNode(p.schema)}`;
|
|
558
|
+
}).join(", ");
|
|
559
|
+
entries.push({
|
|
560
|
+
key: "path",
|
|
561
|
+
value: `z.object({ ${pathFields} })`
|
|
552
562
|
});
|
|
553
563
|
}
|
|
554
|
-
if (zod.
|
|
555
|
-
key: "
|
|
556
|
-
value: zod.requestName
|
|
557
|
-
});
|
|
558
|
-
if (zod.queryParams) otherEntries.push({
|
|
559
|
-
key: "params",
|
|
564
|
+
if (zod.queryParams) entries.push({
|
|
565
|
+
key: "query",
|
|
560
566
|
value: zodGroupExpr(zod.queryParams)
|
|
561
567
|
});
|
|
562
|
-
if (zod.headerParams)
|
|
568
|
+
if (zod.headerParams) entries.push({
|
|
563
569
|
key: "headers",
|
|
564
570
|
value: zodGroupExpr(zod.headerParams)
|
|
565
571
|
});
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
572
|
+
if (zod.requestName) entries.push({
|
|
573
|
+
key: "body",
|
|
574
|
+
value: zod.requestName
|
|
575
|
+
});
|
|
576
|
+
const paramsNode = entries.length ? (0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
|
|
577
|
+
name: (0, _kubb_plugin_ts.createObjectBindingPattern)({ elements: entries.map((e) => ({ name: e.key })) }),
|
|
571
578
|
optional: false
|
|
572
|
-
}] }) : null;
|
|
579
|
+
})] }) : null;
|
|
573
580
|
const destructured = paramsNode ? keysPrinter.print(paramsNode) ?? "" : "";
|
|
574
581
|
const inputSchema = entries.length ? `{ ${entries.map((e) => `${e.key}: ${e.value}`).join(", ")} }` : null;
|
|
575
582
|
const outputSchema = zod.responseName;
|
|
@@ -631,12 +638,105 @@ return server`
|
|
|
631
638
|
});
|
|
632
639
|
}
|
|
633
640
|
//#endregion
|
|
641
|
+
//#region ../../internals/client/src/resolveClient.ts
|
|
642
|
+
/**
|
|
643
|
+
* Resolves which client plugin a consumer (react-query, vue-query, swr, mcp) should call for an
|
|
644
|
+
* operation, shared so the selection rules and diagnostics stay in one place.
|
|
645
|
+
*
|
|
646
|
+
* Every client runtime lives in a dedicated client plugin, so a consumer always calls a registered
|
|
647
|
+
* contract client plugin (plugin-fetch or plugin-axios) and never emits its own inline client:
|
|
648
|
+
*
|
|
649
|
+
* - `contract` — a registered contract client plugin owns the `<op>` functions and the consumer
|
|
650
|
+
* imports and calls them.
|
|
651
|
+
* - `error` — no client plugin is registered, several are registered without a selector, or the
|
|
652
|
+
* requested one is missing.
|
|
653
|
+
*
|
|
654
|
+
* The `client` string selects explicitly (`'fetch'` / `'axios'`); when it is unset a lone registered
|
|
655
|
+
* contract client plugin is picked up automatically.
|
|
656
|
+
*/
|
|
657
|
+
const pluginFetchName = "plugin-fetch";
|
|
658
|
+
const pluginAxiosName = "plugin-axios";
|
|
659
|
+
const selectorToPlugin = {
|
|
660
|
+
fetch: pluginFetchName,
|
|
661
|
+
axios: pluginAxiosName
|
|
662
|
+
};
|
|
663
|
+
const contractPlugins = [pluginFetchName, pluginAxiosName];
|
|
664
|
+
/**
|
|
665
|
+
* Applies the `client` resolution rules. See the module comment for the strategy shape.
|
|
666
|
+
*
|
|
667
|
+
* @example
|
|
668
|
+
* ```ts
|
|
669
|
+
* resolveClient({ client: 'fetch', pluginNames: ['plugin-ts', 'plugin-fetch'] })
|
|
670
|
+
* // { kind: 'contract', pluginName: 'plugin-fetch' }
|
|
671
|
+
* ```
|
|
672
|
+
*
|
|
673
|
+
* @example
|
|
674
|
+
* ```ts
|
|
675
|
+
* resolveClient({ client: undefined, pluginNames: ['plugin-ts'] })
|
|
676
|
+
* // { kind: 'error', message: 'No client plugin is registered…' }
|
|
677
|
+
* ```
|
|
678
|
+
*/
|
|
679
|
+
function resolveClient(options) {
|
|
680
|
+
const { client, pluginNames } = options;
|
|
681
|
+
const has = (name) => pluginNames.includes(name);
|
|
682
|
+
if (client === "fetch" || client === "axios") {
|
|
683
|
+
const pluginName = selectorToPlugin[client];
|
|
684
|
+
if (!has(pluginName)) return {
|
|
685
|
+
kind: "error",
|
|
686
|
+
message: `\`client: '${client}'\` is set but \`@kubb/plugin-${client}\` is not registered in \`plugins\`. Add it, or drop \`client\` to use a different client plugin.`
|
|
687
|
+
};
|
|
688
|
+
return {
|
|
689
|
+
kind: "contract",
|
|
690
|
+
pluginName
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
const registered = contractPlugins.filter(has);
|
|
694
|
+
if (registered.length === 1) return {
|
|
695
|
+
kind: "contract",
|
|
696
|
+
pluginName: registered[0]
|
|
697
|
+
};
|
|
698
|
+
if (registered.length > 1) return {
|
|
699
|
+
kind: "error",
|
|
700
|
+
message: `Multiple client plugins are registered (${registered.map((name) => `\`@kubb/${name}\``).join(", ")}). Set \`client: 'fetch' | 'axios'\` to choose which client the hooks call, or register a single client plugin.`
|
|
701
|
+
};
|
|
702
|
+
return {
|
|
703
|
+
kind: "error",
|
|
704
|
+
message: "No client plugin is registered. Add `@kubb/plugin-axios` or `@kubb/plugin-fetch` to `plugins` so the generated code has an HTTP client to call."
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
//#endregion
|
|
708
|
+
//#region ../../internals/client/src/resolveClientOperation.ts
|
|
709
|
+
/**
|
|
710
|
+
* Resolves the contract client `<op>` a consumer (query hook, MCP handler) imports, by looking up
|
|
711
|
+
* the registered contract client plugin's resolver and output. Works for any contract client plugin
|
|
712
|
+
* (plugin-fetch or plugin-axios). Returns `null` when no contract plugin is in play (the inline
|
|
713
|
+
* path). The plugin injects `.kubb/client.ts` at the global output root, the same path consumers
|
|
714
|
+
* read `RequestConfig` / `ResponseErrorConfig` from.
|
|
715
|
+
*/
|
|
716
|
+
function resolveClientOperation(options) {
|
|
717
|
+
const { clientPlugin, driver, node, root, output } = options;
|
|
718
|
+
if (!clientPlugin) return null;
|
|
719
|
+
const resolver = driver.getResolver(clientPlugin.pluginName);
|
|
720
|
+
if (!resolver) return null;
|
|
721
|
+
const plugin = driver.getPlugin(clientPlugin.pluginName);
|
|
722
|
+
const file = resolver.resolveFile(operationFileEntry(node, node.operationId), {
|
|
723
|
+
root,
|
|
724
|
+
output: plugin?.options?.output ?? output,
|
|
725
|
+
group: plugin?.options?.group ?? void 0
|
|
726
|
+
});
|
|
727
|
+
return {
|
|
728
|
+
name: resolver.resolveName(node.operationId),
|
|
729
|
+
path: file.path,
|
|
730
|
+
clientPath: node_path.default.resolve(root, ".kubb/client.ts")
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
//#endregion
|
|
634
734
|
//#region src/generators/mcpGenerator.tsx
|
|
635
735
|
/**
|
|
636
736
|
* Built-in operation generator for `@kubb/plugin-mcp`. Emits one MCP tool
|
|
637
|
-
* handler per OpenAPI operation
|
|
638
|
-
*
|
|
639
|
-
*
|
|
737
|
+
* handler per OpenAPI operation. The handler takes the grouped `{ path, query,
|
|
738
|
+
* headers, body }` config and forwards it to the registered client plugin's
|
|
739
|
+
* (`@kubb/plugin-axios` / `@kubb/plugin-fetch`) `<op>` function.
|
|
640
740
|
*/
|
|
641
741
|
const mcpGenerator = (0, _kubb_core.defineGenerator)({
|
|
642
742
|
name: "mcp",
|
|
@@ -644,14 +744,19 @@ const mcpGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
644
744
|
operation(node, ctx) {
|
|
645
745
|
if (!_kubb_core.ast.isHttpOperationNode(node)) return null;
|
|
646
746
|
const { resolver, driver, root } = ctx;
|
|
647
|
-
const { output, client,
|
|
747
|
+
const { output, client, group } = ctx.options;
|
|
648
748
|
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
649
749
|
if (!pluginTs) return null;
|
|
650
750
|
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
651
|
-
const
|
|
652
|
-
|
|
653
|
-
|
|
751
|
+
const contractOp = resolveClientOperation({
|
|
752
|
+
clientPlugin: { pluginName: client.pluginName },
|
|
753
|
+
driver,
|
|
754
|
+
node,
|
|
755
|
+
root,
|
|
756
|
+
output
|
|
654
757
|
});
|
|
758
|
+
if (!contractOp) return null;
|
|
759
|
+
const requestConfigName = tsResolver.resolveRequestConfigName(node);
|
|
655
760
|
const meta = {
|
|
656
761
|
name: resolver.resolveHandlerName(node),
|
|
657
762
|
file: resolver.resolveFile({
|
|
@@ -680,8 +785,8 @@ const mcpGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
680
785
|
path: meta.file.path,
|
|
681
786
|
meta: meta.file.meta,
|
|
682
787
|
children: [
|
|
683
|
-
meta.fileTs &&
|
|
684
|
-
name:
|
|
788
|
+
meta.fileTs && requestConfigName && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
789
|
+
name: [requestConfigName],
|
|
685
790
|
root: meta.file.path,
|
|
686
791
|
path: meta.fileTs.path,
|
|
687
792
|
isTypeOnly: true
|
|
@@ -701,59 +806,15 @@ const mcpGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
701
806
|
isTypeOnly: true
|
|
702
807
|
}),
|
|
703
808
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
704
|
-
name: [
|
|
809
|
+
name: [contractOp.name],
|
|
705
810
|
root: meta.file.path,
|
|
706
|
-
path:
|
|
811
|
+
path: contractOp.path
|
|
707
812
|
}),
|
|
708
|
-
client.importPath ? /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
|
|
709
|
-
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
710
|
-
name: [
|
|
711
|
-
"Client",
|
|
712
|
-
"RequestConfig",
|
|
713
|
-
"ResponseErrorConfig"
|
|
714
|
-
],
|
|
715
|
-
path: client.importPath,
|
|
716
|
-
isTypeOnly: true
|
|
717
|
-
}),
|
|
718
|
-
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
719
|
-
name: "client",
|
|
720
|
-
path: client.importPath
|
|
721
|
-
}),
|
|
722
|
-
client.dataReturnType === "full" && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
723
|
-
name: ["ResponseConfig"],
|
|
724
|
-
path: client.importPath,
|
|
725
|
-
isTypeOnly: true
|
|
726
|
-
})
|
|
727
|
-
] }) : /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
|
|
728
|
-
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
729
|
-
name: [
|
|
730
|
-
"Client",
|
|
731
|
-
"RequestConfig",
|
|
732
|
-
"ResponseErrorConfig"
|
|
733
|
-
],
|
|
734
|
-
root: meta.file.path,
|
|
735
|
-
path: node_path.default.resolve(root, ".kubb/client.ts"),
|
|
736
|
-
isTypeOnly: true
|
|
737
|
-
}),
|
|
738
|
-
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
739
|
-
name: ["client"],
|
|
740
|
-
root: meta.file.path,
|
|
741
|
-
path: node_path.default.resolve(root, ".kubb/client.ts")
|
|
742
|
-
}),
|
|
743
|
-
client.dataReturnType === "full" && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
744
|
-
name: ["ResponseConfig"],
|
|
745
|
-
root: meta.file.path,
|
|
746
|
-
path: node_path.default.resolve(root, ".kubb/client.ts"),
|
|
747
|
-
isTypeOnly: true
|
|
748
|
-
})
|
|
749
|
-
] }),
|
|
750
813
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(McpHandler, {
|
|
751
814
|
name: meta.name,
|
|
815
|
+
clientName: contractOp.name,
|
|
752
816
|
node,
|
|
753
|
-
resolver: tsResolver
|
|
754
|
-
baseURL: client.baseURL,
|
|
755
|
-
dataReturnType: client.dataReturnType || "data",
|
|
756
|
-
paramsCasing
|
|
817
|
+
resolver: tsResolver
|
|
757
818
|
})
|
|
758
819
|
]
|
|
759
820
|
});
|
|
@@ -773,7 +834,7 @@ const serverGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
773
834
|
renderer: _kubb_renderer_jsx.jsxRenderer,
|
|
774
835
|
operations(nodes, ctx) {
|
|
775
836
|
const { config, resolver, plugin, driver, root } = ctx;
|
|
776
|
-
const { output,
|
|
837
|
+
const { output, group } = ctx.options;
|
|
777
838
|
const pluginZod = driver.getPlugin(_kubb_plugin_zod.pluginZodName);
|
|
778
839
|
if (!pluginZod) return;
|
|
779
840
|
const zodResolver = driver.getResolver(_kubb_plugin_zod.pluginZodName);
|
|
@@ -789,7 +850,7 @@ const serverGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
789
850
|
meta: { pluginName: plugin.name }
|
|
790
851
|
};
|
|
791
852
|
const operationsMapped = nodes.filter(_kubb_core.ast.isHttpOperationNode).map((node) => {
|
|
792
|
-
const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node
|
|
853
|
+
const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node);
|
|
793
854
|
const mcpFile = resolver.resolveFile({
|
|
794
855
|
name: node.operationId,
|
|
795
856
|
extname: ".ts",
|
|
@@ -895,7 +956,6 @@ const serverGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
895
956
|
name,
|
|
896
957
|
serverName: ctx.meta.title ?? "server",
|
|
897
958
|
serverVersion: ctx.meta.version ?? "0.0.0",
|
|
898
|
-
paramsCasing,
|
|
899
959
|
operations: operationsMapped
|
|
900
960
|
})
|
|
901
961
|
]
|
|
@@ -961,13 +1021,13 @@ const pluginMcpName = "plugin-mcp";
|
|
|
961
1021
|
/**
|
|
962
1022
|
* Generates a Model Context Protocol (MCP) server from an OpenAPI spec. Every
|
|
963
1023
|
* operation becomes a typed MCP tool that AI assistants (Claude Desktop, Claude
|
|
964
|
-
* Code, MCP-compatible clients) can call directly.
|
|
1024
|
+
* Code, MCP-compatible clients) can call directly. Each handler calls a contract
|
|
1025
|
+
* client `<op>` from a registered `@kubb/plugin-axios` or `@kubb/plugin-fetch`.
|
|
965
1026
|
*
|
|
966
1027
|
* @example
|
|
967
1028
|
* ```ts
|
|
968
1029
|
* import { defineConfig } from 'kubb'
|
|
969
1030
|
* import { pluginTs } from '@kubb/plugin-ts'
|
|
970
|
-
* import { pluginClient } from '@kubb/plugin-client'
|
|
971
1031
|
* import { pluginZod } from '@kubb/plugin-zod'
|
|
972
1032
|
* import { pluginMcp } from '@kubb/plugin-mcp'
|
|
973
1033
|
*
|
|
@@ -976,11 +1036,10 @@ const pluginMcpName = "plugin-mcp";
|
|
|
976
1036
|
* output: { path: './src/gen' },
|
|
977
1037
|
* plugins: [
|
|
978
1038
|
* pluginTs(),
|
|
979
|
-
* pluginClient(),
|
|
980
1039
|
* pluginZod(),
|
|
981
1040
|
* pluginMcp({
|
|
982
1041
|
* output: { path: './mcp' },
|
|
983
|
-
*
|
|
1042
|
+
* baseURL: 'https://petstore.swagger.io/v2',
|
|
984
1043
|
* }),
|
|
985
1044
|
* ],
|
|
986
1045
|
* })
|
|
@@ -990,9 +1049,7 @@ const pluginMcp = (0, _kubb_core.definePlugin)((options) => {
|
|
|
990
1049
|
const { output = {
|
|
991
1050
|
path: "mcp",
|
|
992
1051
|
barrel: { type: "named" }
|
|
993
|
-
}, group, exclude = [], include, override = [],
|
|
994
|
-
const clientName = client?.client ?? "axios";
|
|
995
|
-
const clientImportPath = client?.importPath ?? (!client?.bundle ? `@kubb/plugin-client/clients/${clientName}` : void 0);
|
|
1052
|
+
}, group, exclude = [], include, override = [], client, resolver: userResolver, macros: userMacros } = options;
|
|
996
1053
|
const groupConfig = createGroupConfig(group);
|
|
997
1054
|
return {
|
|
998
1055
|
name: pluginMcpName,
|
|
@@ -1003,51 +1060,27 @@ const pluginMcp = (0, _kubb_core.definePlugin)((options) => {
|
|
|
1003
1060
|
...resolverMcp,
|
|
1004
1061
|
...userResolver
|
|
1005
1062
|
} : resolverMcp;
|
|
1063
|
+
const resolvedClient = resolveClient({
|
|
1064
|
+
client,
|
|
1065
|
+
pluginNames: (ctx.config.plugins ?? []).map((p) => p.name).filter((name) => Boolean(name))
|
|
1066
|
+
});
|
|
1067
|
+
if (resolvedClient.kind === "error") throw new Error(resolvedClient.message);
|
|
1068
|
+
const resolvedClientDescriptor = {
|
|
1069
|
+
kind: "contract",
|
|
1070
|
+
pluginName: resolvedClient.pluginName
|
|
1071
|
+
};
|
|
1006
1072
|
ctx.setOptions({
|
|
1007
1073
|
output,
|
|
1008
1074
|
exclude,
|
|
1009
1075
|
include,
|
|
1010
1076
|
override,
|
|
1011
1077
|
group: groupConfig,
|
|
1012
|
-
|
|
1013
|
-
client: {
|
|
1014
|
-
client: clientName,
|
|
1015
|
-
clientType: client?.clientType ?? "function",
|
|
1016
|
-
importPath: clientImportPath,
|
|
1017
|
-
dataReturnType: client?.dataReturnType ?? "data",
|
|
1018
|
-
bundle: client?.bundle,
|
|
1019
|
-
baseURL: client?.baseURL,
|
|
1020
|
-
paramsCasing: client?.paramsCasing
|
|
1021
|
-
},
|
|
1078
|
+
client: resolvedClientDescriptor,
|
|
1022
1079
|
resolver
|
|
1023
1080
|
});
|
|
1024
1081
|
ctx.setResolver(resolver);
|
|
1025
1082
|
if (userMacros?.length) ctx.setMacros(userMacros);
|
|
1026
|
-
ctx.addGenerator(mcpGenerator);
|
|
1027
|
-
ctx.addGenerator(serverGenerator);
|
|
1028
|
-
for (const gen of userGenerators) ctx.addGenerator(gen);
|
|
1029
|
-
const root = node_path$1.default.resolve(ctx.config.root, ctx.config.output.path);
|
|
1030
|
-
const hasClientPlugin = ctx.config.plugins?.some((p) => p.name === _kubb_plugin_client.pluginClientName);
|
|
1031
|
-
if (client?.bundle && !hasClientPlugin && !clientImportPath) ctx.injectFile({
|
|
1032
|
-
baseName: "client.ts",
|
|
1033
|
-
path: node_path$1.default.resolve(root, ".kubb/client.ts"),
|
|
1034
|
-
sources: [_kubb_core.ast.factory.createSource({
|
|
1035
|
-
name: "client",
|
|
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)],
|
|
1037
|
-
isExportable: true,
|
|
1038
|
-
isIndexable: true
|
|
1039
|
-
})]
|
|
1040
|
-
});
|
|
1041
|
-
if (!hasClientPlugin) ctx.injectFile({
|
|
1042
|
-
baseName: "config.ts",
|
|
1043
|
-
path: node_path$1.default.resolve(root, ".kubb/config.ts"),
|
|
1044
|
-
sources: [_kubb_core.ast.factory.createSource({
|
|
1045
|
-
name: "config",
|
|
1046
|
-
nodes: [_kubb_core.ast.factory.createText(_kubb_plugin_client_templates_config_source.source)],
|
|
1047
|
-
isExportable: false,
|
|
1048
|
-
isIndexable: false
|
|
1049
|
-
})]
|
|
1050
|
-
});
|
|
1083
|
+
ctx.addGenerator(mcpGenerator, serverGenerator);
|
|
1051
1084
|
} }
|
|
1052
1085
|
};
|
|
1053
1086
|
});
|