@kubb/plugin-mcp 5.0.0-beta.85 → 5.0.0-beta.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +35 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +13 -16
- package/dist/index.js +35 -75
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "./rolldown-runtime-C0LytTxp.js";
|
|
2
|
-
import
|
|
3
|
-
import { ast, defineGenerator, definePlugin, defineResolver } from "kubb/kit";
|
|
2
|
+
import { Resolver, ast, createResolver, defineGenerator, definePlugin } from "kubb/kit";
|
|
4
3
|
import { Const, File, Function, jsxRenderer } from "kubb/jsx";
|
|
5
4
|
import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
|
|
6
5
|
import { createFunctionParameter, createFunctionParameters, createObjectBindingPattern, functionPrinter, pluginTsName } from "@kubb/plugin-ts";
|
|
6
|
+
import path from "node:path";
|
|
7
7
|
import { pluginZodName } from "@kubb/plugin-zod";
|
|
8
8
|
//#region ../../internals/utils/src/casing.ts
|
|
9
9
|
/**
|
|
@@ -32,31 +32,6 @@ function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
|
32
32
|
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
33
33
|
}
|
|
34
34
|
//#endregion
|
|
35
|
-
//#region ../../internals/utils/src/fs.ts
|
|
36
|
-
/**
|
|
37
|
-
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
38
|
-
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
39
|
-
* every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
|
|
40
|
-
*
|
|
41
|
-
* Empty segments are dropped before joining. They arise when the name starts with a dot
|
|
42
|
-
* followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
|
|
43
|
-
* an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
|
|
44
|
-
* absolute path, letting generated files escape the configured output directory.
|
|
45
|
-
*
|
|
46
|
-
* @example Nested path from a dotted name
|
|
47
|
-
* `toFilePath('pet.petId') // 'pet/petId'`
|
|
48
|
-
*
|
|
49
|
-
* @example PascalCase the final segment
|
|
50
|
-
* `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
|
|
51
|
-
*
|
|
52
|
-
* @example Suffix applied to the final segment only
|
|
53
|
-
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
54
|
-
*/
|
|
55
|
-
function toFilePath(name, caseLast = camelCase) {
|
|
56
|
-
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
57
|
-
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
58
|
-
}
|
|
59
|
-
//#endregion
|
|
60
35
|
//#region ../../internals/utils/src/reserved.ts
|
|
61
36
|
/**
|
|
62
37
|
* JavaScript and Java reserved words.
|
|
@@ -312,13 +287,13 @@ function dedupeByCasedName(params) {
|
|
|
312
287
|
//#region ../../internals/shared/src/operation.ts
|
|
313
288
|
/**
|
|
314
289
|
* Builds the `ResolverFileParams` every operation generator passes to
|
|
315
|
-
* `resolver.
|
|
290
|
+
* `resolver.file`: a file named `name`, tagged by the operation's first
|
|
316
291
|
* tag (or `'default'`), at the operation's path. Centralizes the entry object
|
|
317
292
|
* that was repeated at dozens of call sites across the client and query plugins.
|
|
318
293
|
*
|
|
319
294
|
* @example
|
|
320
295
|
* ```ts
|
|
321
|
-
* resolver.
|
|
296
|
+
* resolver.file(operationFileEntry(node, node.operationId), { root, output, group })
|
|
322
297
|
* ```
|
|
323
298
|
*/
|
|
324
299
|
function operationFileEntry(node, name, extname = ".ts") {
|
|
@@ -401,7 +376,7 @@ function getRequestGroupOptionality(node) {
|
|
|
401
376
|
}
|
|
402
377
|
/**
|
|
403
378
|
* Builds the grouped `{ path, query, body, headers }` parameter for a generated client
|
|
404
|
-
* function, typed from the operation's `
|
|
379
|
+
* function, typed from the operation's `Options` (minus `url`). Only the groups the
|
|
405
380
|
* operation actually has are destructured. The trailing `config` parameter carries the
|
|
406
381
|
* runtime `RequestConfig` overrides plus `client`.
|
|
407
382
|
*/
|
|
@@ -415,7 +390,7 @@ function buildRequestParamsSignature(node, resolver, options = {}) {
|
|
|
415
390
|
"headers"
|
|
416
391
|
].filter((key) => groups[key]);
|
|
417
392
|
return {
|
|
418
|
-
signature: [names.length > 0 ? `{ ${names.join(", ")} }: ${resolver.
|
|
393
|
+
signature: [names.length > 0 ? `{ ${names.join(", ")} }: ${resolver.response.options(node)}${isOptional ? " = {}" : ""}` : null, isConfigurable ? `config: ${buildRequestConfigType(node)} = {}` : null].filter(Boolean).join(", "),
|
|
419
394
|
groups
|
|
420
395
|
};
|
|
421
396
|
}
|
|
@@ -744,15 +719,15 @@ function resolveClientOperation(options) {
|
|
|
744
719
|
const { clientPlugin, driver, node, root, output } = options;
|
|
745
720
|
if (!clientPlugin) return null;
|
|
746
721
|
const resolver = driver.getResolver(clientPlugin.pluginName);
|
|
747
|
-
if (!resolver) return null;
|
|
748
722
|
const plugin = driver.getPlugin(clientPlugin.pluginName);
|
|
749
|
-
const file = resolver.
|
|
723
|
+
const file = resolver.file({
|
|
724
|
+
...operationFileEntry(node, node.operationId),
|
|
750
725
|
root,
|
|
751
726
|
output: plugin?.options?.output ?? output,
|
|
752
727
|
group: plugin?.options?.group ?? void 0
|
|
753
728
|
});
|
|
754
729
|
return {
|
|
755
|
-
name: resolver.
|
|
730
|
+
name: resolver.name(node.operationId),
|
|
756
731
|
path: file.path,
|
|
757
732
|
clientPath: path.resolve(root, ".kubb/client.ts")
|
|
758
733
|
};
|
|
@@ -783,25 +758,23 @@ const mcpGenerator = defineGenerator({
|
|
|
783
758
|
output
|
|
784
759
|
});
|
|
785
760
|
if (!contractOp) return null;
|
|
786
|
-
const
|
|
761
|
+
const optionsName = tsResolver.response.options(node);
|
|
787
762
|
const meta = {
|
|
788
|
-
name: resolver.
|
|
789
|
-
file: resolver.
|
|
763
|
+
name: resolver.handler.name(node),
|
|
764
|
+
file: resolver.file({
|
|
790
765
|
name: node.operationId,
|
|
791
766
|
extname: ".ts",
|
|
792
767
|
tag: node.tags[0] ?? "default",
|
|
793
|
-
path: node.path
|
|
794
|
-
}, {
|
|
768
|
+
path: node.path,
|
|
795
769
|
root,
|
|
796
770
|
output,
|
|
797
771
|
group: group ?? void 0
|
|
798
772
|
}),
|
|
799
|
-
fileTs: tsResolver.
|
|
773
|
+
fileTs: tsResolver.file({
|
|
800
774
|
name: node.operationId,
|
|
801
775
|
extname: ".ts",
|
|
802
776
|
tag: node.tags[0] ?? "default",
|
|
803
|
-
path: node.path
|
|
804
|
-
}, {
|
|
777
|
+
path: node.path,
|
|
805
778
|
root,
|
|
806
779
|
output: pluginTs.options?.output ?? output,
|
|
807
780
|
group: pluginTs.options?.group ?? void 0
|
|
@@ -812,8 +785,8 @@ const mcpGenerator = defineGenerator({
|
|
|
812
785
|
path: meta.file.path,
|
|
813
786
|
meta: meta.file.meta,
|
|
814
787
|
children: [
|
|
815
|
-
meta.fileTs &&
|
|
816
|
-
name: [
|
|
788
|
+
meta.fileTs && optionsName && /* @__PURE__ */ jsx(File.Import, {
|
|
789
|
+
name: [optionsName],
|
|
817
790
|
root: meta.file.path,
|
|
818
791
|
path: meta.fileTs.path,
|
|
819
792
|
isTypeOnly: true
|
|
@@ -878,32 +851,30 @@ const serverGenerator = defineGenerator({
|
|
|
878
851
|
};
|
|
879
852
|
const operationsMapped = nodes.filter(ast.isHttpOperationNode).map((node) => {
|
|
880
853
|
const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node);
|
|
881
|
-
const mcpFile = resolver.
|
|
854
|
+
const mcpFile = resolver.file({
|
|
882
855
|
name: node.operationId,
|
|
883
856
|
extname: ".ts",
|
|
884
857
|
tag: node.tags[0] ?? "default",
|
|
885
|
-
path: node.path
|
|
886
|
-
}, {
|
|
858
|
+
path: node.path,
|
|
887
859
|
root,
|
|
888
860
|
output,
|
|
889
861
|
group: group ?? void 0
|
|
890
862
|
});
|
|
891
|
-
const zodFile = zodResolver.
|
|
863
|
+
const zodFile = zodResolver.file({
|
|
892
864
|
name: node.operationId,
|
|
893
865
|
extname: ".ts",
|
|
894
866
|
tag: node.tags[0] ?? "default",
|
|
895
|
-
path: node.path
|
|
896
|
-
}, {
|
|
867
|
+
path: node.path,
|
|
897
868
|
root,
|
|
898
869
|
output: pluginZod.options?.output ?? output,
|
|
899
870
|
group: pluginZod.options?.group ?? void 0
|
|
900
871
|
});
|
|
901
|
-
const requestName = node.requestBody?.content?.[0]?.schema ? zodResolver.
|
|
872
|
+
const requestName = node.requestBody?.content?.[0]?.schema ? zodResolver.response.body(node) : null;
|
|
902
873
|
const successStatus = findSuccessStatusCode(node.responses);
|
|
903
|
-
const responseName = successStatus ? zodResolver.
|
|
874
|
+
const responseName = successStatus ? zodResolver.response.status(node, successStatus) : null;
|
|
904
875
|
const resolveParams = (params) => params.map((p) => ({
|
|
905
876
|
name: p.name,
|
|
906
|
-
schemaName: zodResolver.
|
|
877
|
+
schemaName: zodResolver.param.name(node, p)
|
|
907
878
|
}));
|
|
908
879
|
return {
|
|
909
880
|
tool: {
|
|
@@ -912,7 +883,7 @@ const serverGenerator = defineGenerator({
|
|
|
912
883
|
description: node.description || `Make a ${node.method.toUpperCase()} request to ${node.path}`
|
|
913
884
|
},
|
|
914
885
|
mcp: {
|
|
915
|
-
name: resolver.
|
|
886
|
+
name: resolver.handler.name(node),
|
|
916
887
|
file: mcpFile
|
|
917
888
|
},
|
|
918
889
|
zod: {
|
|
@@ -949,7 +920,7 @@ const serverGenerator = defineGenerator({
|
|
|
949
920
|
baseName: serverFile.baseName,
|
|
950
921
|
path: serverFile.path,
|
|
951
922
|
meta: serverFile.meta,
|
|
952
|
-
banner: resolver.
|
|
923
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
953
924
|
output,
|
|
954
925
|
config,
|
|
955
926
|
file: {
|
|
@@ -957,7 +928,7 @@ const serverGenerator = defineGenerator({
|
|
|
957
928
|
baseName: serverFile.baseName
|
|
958
929
|
}
|
|
959
930
|
}),
|
|
960
|
-
footer: resolver.
|
|
931
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
961
932
|
output,
|
|
962
933
|
config,
|
|
963
934
|
file: {
|
|
@@ -1018,26 +989,18 @@ const serverGenerator = defineGenerator({
|
|
|
1018
989
|
* ```ts
|
|
1019
990
|
* import { resolverMcp } from '@kubb/plugin-mcp'
|
|
1020
991
|
*
|
|
1021
|
-
* resolverMcp.
|
|
992
|
+
* resolverMcp.name('addPet') // 'addPetHandler'
|
|
1022
993
|
* ```
|
|
1023
994
|
*/
|
|
1024
|
-
const resolverMcp =
|
|
1025
|
-
name: "default",
|
|
995
|
+
const resolverMcp = createResolver({
|
|
1026
996
|
pluginName: "plugin-mcp",
|
|
1027
|
-
|
|
1028
|
-
if (type === "file") return toFilePath(name);
|
|
997
|
+
name(name) {
|
|
1029
998
|
return camelCase(name, { suffix: "handler" });
|
|
1030
999
|
},
|
|
1031
|
-
|
|
1032
|
-
return this.
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
return this.default(name, type);
|
|
1036
|
-
},
|
|
1037
|
-
resolveHandlerName(node) {
|
|
1038
|
-
return this.resolveName(node.operationId);
|
|
1039
|
-
}
|
|
1040
|
-
}));
|
|
1000
|
+
handler: { name(node) {
|
|
1001
|
+
return this.name(node.operationId);
|
|
1002
|
+
} }
|
|
1003
|
+
});
|
|
1041
1004
|
//#endregion
|
|
1042
1005
|
//#region src/plugin.ts
|
|
1043
1006
|
/**
|
|
@@ -1083,10 +1046,7 @@ const pluginMcp = definePlugin((options) => {
|
|
|
1083
1046
|
options,
|
|
1084
1047
|
dependencies: [pluginTsName, pluginZodName],
|
|
1085
1048
|
hooks: { "kubb:plugin:setup"(ctx) {
|
|
1086
|
-
const resolver = userResolver ?
|
|
1087
|
-
...resolverMcp,
|
|
1088
|
-
...userResolver
|
|
1089
|
-
} : resolverMcp;
|
|
1049
|
+
const resolver = userResolver ? Resolver.merge(resolverMcp, userResolver) : resolverMcp;
|
|
1090
1050
|
const resolvedClient = resolveClient({
|
|
1091
1051
|
client,
|
|
1092
1052
|
pluginNames: (ctx.config.plugins ?? []).map((p) => p.name).filter((name) => Boolean(name))
|