frontmcp 0.3.1 → 0.4.1
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/LICENSE +201 -0
- package/README.md +448 -0
- package/package.json +5 -5
- package/src/args.d.ts +8 -0
- package/src/args.js +19 -0
- package/src/args.js.map +1 -0
- package/src/cli.d.ts +0 -1
- package/src/cli.js +30 -574
- package/src/cli.js.map +1 -1
- package/src/colors.d.ts +12 -0
- package/src/colors.js +17 -0
- package/src/colors.js.map +1 -0
- package/src/commands/build.d.ts +2 -0
- package/src/commands/build.js +43 -0
- package/src/commands/build.js.map +1 -0
- package/src/commands/create.d.ts +1 -0
- package/src/commands/create.js +204 -0
- package/src/commands/create.js.map +1 -0
- package/src/commands/dev.d.ts +2 -0
- package/src/commands/dev.js +49 -0
- package/src/commands/dev.js.map +1 -0
- package/src/commands/doctor.d.ts +1 -0
- package/src/commands/doctor.js +87 -0
- package/src/commands/doctor.js.map +1 -0
- package/src/commands/inspector.d.ts +1 -0
- package/src/commands/inspector.js +10 -0
- package/src/commands/inspector.js.map +1 -0
- package/src/commands/template.d.ts +13 -0
- package/src/commands/template.js +179 -0
- package/src/commands/template.js.map +1 -0
- package/src/templates/3rd-party-integration/src/http-client.d.ts +20 -0
- package/src/templates/3rd-party-integration/src/http-client.js +101 -0
- package/src/templates/3rd-party-integration/src/http-client.js.map +1 -0
- package/src/templates/3rd-party-integration/src/mcp-http-types.d.ts +199 -0
- package/src/templates/3rd-party-integration/src/mcp-http-types.js +51 -0
- package/src/templates/3rd-party-integration/src/mcp-http-types.js.map +1 -0
- package/src/templates/3rd-party-integration/src/tools/example.list.d.ts +125 -0
- package/src/templates/3rd-party-integration/src/tools/example.list.js +85 -0
- package/src/templates/3rd-party-integration/src/tools/example.list.js.map +1 -0
- package/src/tsconfig.d.ts +34 -0
- package/src/tsconfig.js +103 -0
- package/src/tsconfig.js.map +1 -0
- package/src/utils/fs.d.ts +11 -0
- package/src/utils/fs.js +104 -0
- package/src/utils/fs.js.map +1 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { HttpOutput, ToolExecute } from "../mcp-http-types";
|
|
3
|
+
export declare const inputSchema: z.ZodObject<{
|
|
4
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
5
|
+
query: z.ZodOptional<z.ZodString>;
|
|
6
|
+
}, "strict", z.ZodTypeAny, {
|
|
7
|
+
limit?: number | undefined;
|
|
8
|
+
query?: string | undefined;
|
|
9
|
+
}, {
|
|
10
|
+
limit?: number | undefined;
|
|
11
|
+
query?: string | undefined;
|
|
12
|
+
}>;
|
|
13
|
+
export type Input = z.infer<typeof inputSchema>;
|
|
14
|
+
export declare const ItemSchema: z.ZodObject<{
|
|
15
|
+
id: z.ZodString;
|
|
16
|
+
name: z.ZodString;
|
|
17
|
+
type: z.ZodString;
|
|
18
|
+
}, "strict", z.ZodTypeAny, {
|
|
19
|
+
name: string;
|
|
20
|
+
type: string;
|
|
21
|
+
id: string;
|
|
22
|
+
}, {
|
|
23
|
+
name: string;
|
|
24
|
+
type: string;
|
|
25
|
+
id: string;
|
|
26
|
+
}>;
|
|
27
|
+
export declare const BodySchema: z.ZodObject<{
|
|
28
|
+
items: z.ZodArray<z.ZodObject<{
|
|
29
|
+
id: z.ZodString;
|
|
30
|
+
name: z.ZodString;
|
|
31
|
+
type: z.ZodString;
|
|
32
|
+
}, "strict", z.ZodTypeAny, {
|
|
33
|
+
name: string;
|
|
34
|
+
type: string;
|
|
35
|
+
id: string;
|
|
36
|
+
}, {
|
|
37
|
+
name: string;
|
|
38
|
+
type: string;
|
|
39
|
+
id: string;
|
|
40
|
+
}>, "many">;
|
|
41
|
+
nextCursor: z.ZodNullable<z.ZodString>;
|
|
42
|
+
}, "strict", z.ZodTypeAny, {
|
|
43
|
+
items: {
|
|
44
|
+
name: string;
|
|
45
|
+
type: string;
|
|
46
|
+
id: string;
|
|
47
|
+
}[];
|
|
48
|
+
nextCursor: string | null;
|
|
49
|
+
}, {
|
|
50
|
+
items: {
|
|
51
|
+
name: string;
|
|
52
|
+
type: string;
|
|
53
|
+
id: string;
|
|
54
|
+
}[];
|
|
55
|
+
nextCursor: string | null;
|
|
56
|
+
}>;
|
|
57
|
+
export type Body = z.infer<typeof BodySchema>;
|
|
58
|
+
export declare const outputSchema: z.ZodObject<{
|
|
59
|
+
status: z.ZodNumber;
|
|
60
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
61
|
+
body: z.ZodObject<{
|
|
62
|
+
items: z.ZodArray<z.ZodObject<{
|
|
63
|
+
id: z.ZodString;
|
|
64
|
+
name: z.ZodString;
|
|
65
|
+
type: z.ZodString;
|
|
66
|
+
}, "strict", z.ZodTypeAny, {
|
|
67
|
+
name: string;
|
|
68
|
+
type: string;
|
|
69
|
+
id: string;
|
|
70
|
+
}, {
|
|
71
|
+
name: string;
|
|
72
|
+
type: string;
|
|
73
|
+
id: string;
|
|
74
|
+
}>, "many">;
|
|
75
|
+
nextCursor: z.ZodNullable<z.ZodString>;
|
|
76
|
+
}, "strict", z.ZodTypeAny, {
|
|
77
|
+
items: {
|
|
78
|
+
name: string;
|
|
79
|
+
type: string;
|
|
80
|
+
id: string;
|
|
81
|
+
}[];
|
|
82
|
+
nextCursor: string | null;
|
|
83
|
+
}, {
|
|
84
|
+
items: {
|
|
85
|
+
name: string;
|
|
86
|
+
type: string;
|
|
87
|
+
id: string;
|
|
88
|
+
}[];
|
|
89
|
+
nextCursor: string | null;
|
|
90
|
+
}>;
|
|
91
|
+
}, "strip", z.ZodTypeAny, {
|
|
92
|
+
status: number;
|
|
93
|
+
body: {
|
|
94
|
+
items: {
|
|
95
|
+
name: string;
|
|
96
|
+
type: string;
|
|
97
|
+
id: string;
|
|
98
|
+
}[];
|
|
99
|
+
nextCursor: string | null;
|
|
100
|
+
};
|
|
101
|
+
headers?: Record<string, string> | undefined;
|
|
102
|
+
}, {
|
|
103
|
+
status: number;
|
|
104
|
+
body: {
|
|
105
|
+
items: {
|
|
106
|
+
name: string;
|
|
107
|
+
type: string;
|
|
108
|
+
id: string;
|
|
109
|
+
}[];
|
|
110
|
+
nextCursor: string | null;
|
|
111
|
+
};
|
|
112
|
+
headers?: Record<string, string> | undefined;
|
|
113
|
+
}>;
|
|
114
|
+
export type Output = HttpOutput<Body>;
|
|
115
|
+
/**
|
|
116
|
+
* Example tool: "example.list"
|
|
117
|
+
*
|
|
118
|
+
* - Replace path/method/logic with actual __OWNER__/__SERVICE__ API calls.
|
|
119
|
+
* - Demonstrates:
|
|
120
|
+
* - strict input validation
|
|
121
|
+
* - HTTP client with auth
|
|
122
|
+
* - typed body mapping
|
|
123
|
+
* - non-2xx error normalization
|
|
124
|
+
*/
|
|
125
|
+
export declare const execute: ToolExecute<Input, Body>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.execute = exports.outputSchema = exports.BodySchema = exports.ItemSchema = exports.inputSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const mcp_http_types_1 = require("../mcp-http-types");
|
|
6
|
+
const http_client_1 = require("../http-client");
|
|
7
|
+
// MCP-visible input schema.
|
|
8
|
+
// Keep this in sync with tools/json/example.list.json -> input_schema.
|
|
9
|
+
exports.inputSchema = zod_1.z
|
|
10
|
+
.object({
|
|
11
|
+
limit: zod_1.z.number().int().min(1).max(1000).optional(),
|
|
12
|
+
query: zod_1.z.string().optional()
|
|
13
|
+
})
|
|
14
|
+
.strict();
|
|
15
|
+
// Body payload for success
|
|
16
|
+
exports.ItemSchema = zod_1.z
|
|
17
|
+
.object({
|
|
18
|
+
id: zod_1.z.string(),
|
|
19
|
+
name: zod_1.z.string(),
|
|
20
|
+
type: zod_1.z.string()
|
|
21
|
+
})
|
|
22
|
+
.strict();
|
|
23
|
+
exports.BodySchema = zod_1.z
|
|
24
|
+
.object({
|
|
25
|
+
items: zod_1.z.array(exports.ItemSchema),
|
|
26
|
+
nextCursor: zod_1.z.string().nullable()
|
|
27
|
+
})
|
|
28
|
+
.strict();
|
|
29
|
+
// HTTP wrapper output
|
|
30
|
+
exports.outputSchema = (0, mcp_http_types_1.makeHttpOutputSchema)(exports.BodySchema);
|
|
31
|
+
// Optional: error body type if you want to distinguish
|
|
32
|
+
const ErrorBodySchema = zod_1.z
|
|
33
|
+
.object({
|
|
34
|
+
error: zod_1.z.object({
|
|
35
|
+
code: zod_1.z.string().optional(),
|
|
36
|
+
message: zod_1.z.string()
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
.strip();
|
|
40
|
+
/**
|
|
41
|
+
* Example tool: "example.list"
|
|
42
|
+
*
|
|
43
|
+
* - Replace path/method/logic with actual __OWNER__/__SERVICE__ API calls.
|
|
44
|
+
* - Demonstrates:
|
|
45
|
+
* - strict input validation
|
|
46
|
+
* - HTTP client with auth
|
|
47
|
+
* - typed body mapping
|
|
48
|
+
* - non-2xx error normalization
|
|
49
|
+
*/
|
|
50
|
+
const execute = async ({ input, ctx }) => {
|
|
51
|
+
const ctxSafe = mcp_http_types_1.ExecuteContextSchema.parse(ctx);
|
|
52
|
+
const http = new http_client_1.HttpClient(ctxSafe);
|
|
53
|
+
// Construct path; you can also use claims from ctxSafe.auth.oauth2?.claims here.
|
|
54
|
+
const path = "/tenants/self/resources";
|
|
55
|
+
const res = await http.request({
|
|
56
|
+
method: "GET",
|
|
57
|
+
path,
|
|
58
|
+
query: {
|
|
59
|
+
limit: input.limit ?? 50,
|
|
60
|
+
query: input.query
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
// Treat non-2xx as an error: normalize upstream error details and throw.
|
|
64
|
+
if (res.status < 200 || res.status >= 300) {
|
|
65
|
+
const errorBody = ErrorBodySchema.safeParse(res.json ?? { error: { message: res.text ?? "Unknown error" } });
|
|
66
|
+
throw new Error(`Upstream error (${res.status}): ${errorBody.success ? errorBody.data.error.message : "Unknown error"}`);
|
|
67
|
+
}
|
|
68
|
+
const body = exports.BodySchema.parse({
|
|
69
|
+
items: Array.isArray(res.json?.items)
|
|
70
|
+
? res.json.items.map((it) => ({
|
|
71
|
+
id: String(it.id),
|
|
72
|
+
name: String(it.name),
|
|
73
|
+
type: String(it.type ?? "unknown")
|
|
74
|
+
}))
|
|
75
|
+
: [],
|
|
76
|
+
nextCursor: res.json?.nextCursor ?? null
|
|
77
|
+
});
|
|
78
|
+
return exports.outputSchema.parse({
|
|
79
|
+
status: res.status,
|
|
80
|
+
headers: res.headers,
|
|
81
|
+
body
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
exports.execute = execute;
|
|
85
|
+
//# sourceMappingURL=example.list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example.list.js","sourceRoot":"","sources":["../../../../../../src/templates/3rd-party-integration/src/tools/example.list.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport {\n ExecuteContextSchema,\n HttpOutput,\n ToolExecute,\n makeHttpOutputSchema\n} from \"../mcp-http-types\";\nimport { HttpClient } from \"../http-client\";\n\n// MCP-visible input schema.\n// Keep this in sync with tools/json/example.list.json -> input_schema.\nexport const inputSchema = z\n .object({\n limit: z.number().int().min(1).max(1000).optional(),\n query: z.string().optional()\n })\n .strict();\n\nexport type Input = z.infer<typeof inputSchema>;\n\n// Body payload for success\nexport const ItemSchema = z\n .object({\n id: z.string(),\n name: z.string(),\n type: z.string()\n })\n .strict();\n\nexport const BodySchema = z\n .object({\n items: z.array(ItemSchema),\n nextCursor: z.string().nullable()\n })\n .strict();\n\nexport type Body = z.infer<typeof BodySchema>;\n\n// HTTP wrapper output\nexport const outputSchema = makeHttpOutputSchema(BodySchema);\nexport type Output = HttpOutput<Body>;\n\n// Optional: error body type if you want to distinguish\nconst ErrorBodySchema = z\n .object({\n error: z.object({\n code: z.string().optional(),\n message: z.string()\n })\n })\n .strip();\n\n/**\n * Example tool: \"example.list\"\n *\n * - Replace path/method/logic with actual __OWNER__/__SERVICE__ API calls.\n * - Demonstrates:\n * - strict input validation\n * - HTTP client with auth\n * - typed body mapping\n * - non-2xx error normalization\n */\nexport const execute: ToolExecute<Input, Body> = async ({ input, ctx }) => {\n const ctxSafe = ExecuteContextSchema.parse(ctx);\n const http = new HttpClient(ctxSafe);\n\n // Construct path; you can also use claims from ctxSafe.auth.oauth2?.claims here.\n const path = \"/tenants/self/resources\";\n\n const res = await http.request({\n method: \"GET\",\n path,\n query: {\n limit: input.limit ?? 50,\n query: input.query\n }\n });\n\n // Treat non-2xx as an error: normalize upstream error details and throw.\n if (res.status < 200 || res.status >= 300) {\n const errorBody = ErrorBodySchema.safeParse(\n res.json ?? { error: { message: res.text ?? \"Unknown error\" } }\n );\n throw new Error(\n `Upstream error (${res.status}): ${\n errorBody.success ? errorBody.data.error.message : \"Unknown error\"\n }`\n );\n }\n\n const body: Body = BodySchema.parse({\n items: Array.isArray(res.json?.items)\n ? res.json.items.map((it: any) => ({\n id: String(it.id),\n name: String(it.name),\n type: String(it.type ?? \"unknown\")\n }))\n : [],\n nextCursor: res.json?.nextCursor ?? null\n });\n\n return outputSchema.parse({\n status: res.status,\n headers: res.headers,\n body\n });\n};\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export declare const REQUIRED_DECORATOR_FIELDS: {
|
|
2
|
+
readonly target: "es2021";
|
|
3
|
+
readonly module: "esnext";
|
|
4
|
+
readonly emitDecoratorMetadata: true;
|
|
5
|
+
readonly experimentalDecorators: true;
|
|
6
|
+
readonly strictFunctionTypes: true;
|
|
7
|
+
readonly moduleResolution: "node";
|
|
8
|
+
};
|
|
9
|
+
export declare const RECOMMENDED_TSCONFIG: {
|
|
10
|
+
readonly compilerOptions: {
|
|
11
|
+
readonly target: "es2021";
|
|
12
|
+
readonly module: "esnext";
|
|
13
|
+
readonly emitDecoratorMetadata: true;
|
|
14
|
+
readonly experimentalDecorators: true;
|
|
15
|
+
readonly strictFunctionTypes: true;
|
|
16
|
+
readonly moduleResolution: "node";
|
|
17
|
+
readonly strict: true;
|
|
18
|
+
readonly esModuleInterop: true;
|
|
19
|
+
readonly resolveJsonModule: true;
|
|
20
|
+
readonly skipLibCheck: true;
|
|
21
|
+
readonly sourceMap: true;
|
|
22
|
+
readonly outDir: "dist";
|
|
23
|
+
readonly rootDir: "src";
|
|
24
|
+
readonly types: readonly ["node"];
|
|
25
|
+
};
|
|
26
|
+
readonly include: readonly ["src/**/*"];
|
|
27
|
+
};
|
|
28
|
+
export declare function deepMerge<T extends Record<string, any>, U extends Record<string, any>>(base: T, patch: U): T & U;
|
|
29
|
+
export declare function ensureRequiredTsOptions(obj: Record<string, any>): Record<string, any>;
|
|
30
|
+
export declare function checkRequiredTsOptions(compilerOptions: Record<string, any> | undefined): {
|
|
31
|
+
ok: string[];
|
|
32
|
+
issues: string[];
|
|
33
|
+
};
|
|
34
|
+
export declare function runInit(baseDir?: string): Promise<void>;
|
package/src/tsconfig.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RECOMMENDED_TSCONFIG = exports.REQUIRED_DECORATOR_FIELDS = void 0;
|
|
4
|
+
exports.deepMerge = deepMerge;
|
|
5
|
+
exports.ensureRequiredTsOptions = ensureRequiredTsOptions;
|
|
6
|
+
exports.checkRequiredTsOptions = checkRequiredTsOptions;
|
|
7
|
+
exports.runInit = runInit;
|
|
8
|
+
const tslib_1 = require("tslib");
|
|
9
|
+
const path = tslib_1.__importStar(require("path"));
|
|
10
|
+
const colors_1 = require("./colors");
|
|
11
|
+
const fs_1 = require("./utils/fs");
|
|
12
|
+
exports.REQUIRED_DECORATOR_FIELDS = {
|
|
13
|
+
target: 'es2021',
|
|
14
|
+
module: 'esnext',
|
|
15
|
+
emitDecoratorMetadata: true,
|
|
16
|
+
experimentalDecorators: true,
|
|
17
|
+
strictFunctionTypes: true,
|
|
18
|
+
moduleResolution: 'node',
|
|
19
|
+
};
|
|
20
|
+
exports.RECOMMENDED_TSCONFIG = {
|
|
21
|
+
compilerOptions: {
|
|
22
|
+
target: exports.REQUIRED_DECORATOR_FIELDS.target,
|
|
23
|
+
module: exports.REQUIRED_DECORATOR_FIELDS.module,
|
|
24
|
+
emitDecoratorMetadata: exports.REQUIRED_DECORATOR_FIELDS.emitDecoratorMetadata,
|
|
25
|
+
experimentalDecorators: exports.REQUIRED_DECORATOR_FIELDS.experimentalDecorators,
|
|
26
|
+
strictFunctionTypes: exports.REQUIRED_DECORATOR_FIELDS.strictFunctionTypes,
|
|
27
|
+
moduleResolution: exports.REQUIRED_DECORATOR_FIELDS.moduleResolution,
|
|
28
|
+
strict: true,
|
|
29
|
+
esModuleInterop: true,
|
|
30
|
+
resolveJsonModule: true,
|
|
31
|
+
skipLibCheck: true,
|
|
32
|
+
sourceMap: true,
|
|
33
|
+
outDir: 'dist',
|
|
34
|
+
rootDir: 'src',
|
|
35
|
+
types: ['node'],
|
|
36
|
+
},
|
|
37
|
+
include: ['src/**/*'],
|
|
38
|
+
};
|
|
39
|
+
function deepMerge(base, patch) {
|
|
40
|
+
const out = { ...base };
|
|
41
|
+
for (const [k, v] of Object.entries(patch)) {
|
|
42
|
+
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
43
|
+
out[k] = deepMerge(base[k] ?? {}, v);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
out[k] = v;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
function ensureRequiredTsOptions(obj) {
|
|
52
|
+
const next = { ...obj };
|
|
53
|
+
next.compilerOptions = { ...(next.compilerOptions || {}) };
|
|
54
|
+
next.compilerOptions.target = exports.REQUIRED_DECORATOR_FIELDS.target;
|
|
55
|
+
next.compilerOptions.module = exports.REQUIRED_DECORATOR_FIELDS.module;
|
|
56
|
+
next.compilerOptions.emitDecoratorMetadata = exports.REQUIRED_DECORATOR_FIELDS.emitDecoratorMetadata;
|
|
57
|
+
next.compilerOptions.experimentalDecorators = exports.REQUIRED_DECORATOR_FIELDS.experimentalDecorators;
|
|
58
|
+
return next;
|
|
59
|
+
}
|
|
60
|
+
function normalizeStr(x) {
|
|
61
|
+
return typeof x === 'string' ? x.toLowerCase() : undefined;
|
|
62
|
+
}
|
|
63
|
+
function checkRequiredTsOptions(compilerOptions) {
|
|
64
|
+
const issues = [];
|
|
65
|
+
const ok = [];
|
|
66
|
+
const target = normalizeStr(compilerOptions?.target);
|
|
67
|
+
const moduleVal = normalizeStr(compilerOptions?.module);
|
|
68
|
+
const edm = compilerOptions?.emitDecoratorMetadata;
|
|
69
|
+
const ed = compilerOptions?.experimentalDecorators;
|
|
70
|
+
if (target === exports.REQUIRED_DECORATOR_FIELDS.target)
|
|
71
|
+
ok.push(`compilerOptions.target = "${exports.REQUIRED_DECORATOR_FIELDS.target}"`);
|
|
72
|
+
else
|
|
73
|
+
issues.push(`compilerOptions.target should be "${exports.REQUIRED_DECORATOR_FIELDS.target}"`);
|
|
74
|
+
if (moduleVal === exports.REQUIRED_DECORATOR_FIELDS.module)
|
|
75
|
+
ok.push(`compilerOptions.module = "${exports.REQUIRED_DECORATOR_FIELDS.module}"`);
|
|
76
|
+
else
|
|
77
|
+
issues.push(`compilerOptions.module should be "${exports.REQUIRED_DECORATOR_FIELDS.module}"`);
|
|
78
|
+
if (edm === exports.REQUIRED_DECORATOR_FIELDS.emitDecoratorMetadata)
|
|
79
|
+
ok.push(`compilerOptions.emitDecoratorMetadata = true`);
|
|
80
|
+
else
|
|
81
|
+
issues.push(`compilerOptions.emitDecoratorMetadata should be true`);
|
|
82
|
+
if (ed === exports.REQUIRED_DECORATOR_FIELDS.experimentalDecorators)
|
|
83
|
+
ok.push(`compilerOptions.experimentalDecorators = true`);
|
|
84
|
+
else
|
|
85
|
+
issues.push(`compilerOptions.experimentalDecorators should be true`);
|
|
86
|
+
return { ok, issues };
|
|
87
|
+
}
|
|
88
|
+
async function runInit(baseDir) {
|
|
89
|
+
const cwd = baseDir ?? process.cwd();
|
|
90
|
+
const tsconfigPath = path.join(cwd, 'tsconfig.json');
|
|
91
|
+
const existing = await (0, fs_1.readJSON)(tsconfigPath);
|
|
92
|
+
if (!existing) {
|
|
93
|
+
console.log((0, colors_1.c)('yellow', `tsconfig.json not found — creating one in ${path.relative(process.cwd(), cwd) || '.'}.`));
|
|
94
|
+
await (0, fs_1.writeJSON)(tsconfigPath, exports.RECOMMENDED_TSCONFIG);
|
|
95
|
+
console.log((0, colors_1.c)('green', '✅ Created tsconfig.json with required decorator settings.'));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
let merged = deepMerge(exports.RECOMMENDED_TSCONFIG, existing);
|
|
99
|
+
merged = ensureRequiredTsOptions(merged);
|
|
100
|
+
await (0, fs_1.writeJSON)(tsconfigPath, merged);
|
|
101
|
+
console.log((0, colors_1.c)('green', '✅ tsconfig.json verified and updated (required decorator settings enforced).'));
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=tsconfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tsconfig.js","sourceRoot":"","sources":["../../src/tsconfig.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\nimport { c } from './colors';\nimport { fileExists, readJSON, writeJSON } from './utils/fs';\n\nexport const REQUIRED_DECORATOR_FIELDS = {\n target: 'es2021',\n module: 'esnext',\n emitDecoratorMetadata: true,\n experimentalDecorators: true,\n strictFunctionTypes: true,\n moduleResolution: 'node',\n} as const;\n\nexport const RECOMMENDED_TSCONFIG = {\n compilerOptions: {\n target: REQUIRED_DECORATOR_FIELDS.target,\n module: REQUIRED_DECORATOR_FIELDS.module,\n emitDecoratorMetadata: REQUIRED_DECORATOR_FIELDS.emitDecoratorMetadata,\n experimentalDecorators: REQUIRED_DECORATOR_FIELDS.experimentalDecorators,\n strictFunctionTypes: REQUIRED_DECORATOR_FIELDS.strictFunctionTypes,\n moduleResolution: REQUIRED_DECORATOR_FIELDS.moduleResolution,\n strict: true,\n esModuleInterop: true,\n resolveJsonModule: true,\n skipLibCheck: true,\n sourceMap: true,\n outDir: 'dist',\n rootDir: 'src',\n types: ['node'],\n },\n include: ['src/**/*'],\n} as const;\n\nexport function deepMerge<T extends Record<string, any>, U extends Record<string, any>>(base: T, patch: U): T & U {\n const out: Record<string, any> = { ...base };\n for (const [k, v] of Object.entries(patch)) {\n if (v && typeof v === 'object' && !Array.isArray(v)) {\n out[k] = deepMerge(base[k] ?? {}, v as Record<string, any>);\n } else {\n out[k] = v;\n }\n }\n return out as T & U;\n}\n\nexport function ensureRequiredTsOptions(obj: Record<string, any>): Record<string, any> {\n const next = { ...obj };\n next.compilerOptions = { ...(next.compilerOptions || {}) };\n next.compilerOptions.target = REQUIRED_DECORATOR_FIELDS.target;\n next.compilerOptions.module = REQUIRED_DECORATOR_FIELDS.module;\n next.compilerOptions.emitDecoratorMetadata = REQUIRED_DECORATOR_FIELDS.emitDecoratorMetadata;\n next.compilerOptions.experimentalDecorators = REQUIRED_DECORATOR_FIELDS.experimentalDecorators;\n return next;\n}\n\nfunction normalizeStr(x: unknown): string | undefined {\n return typeof x === 'string' ? x.toLowerCase() : undefined;\n}\n\nexport function checkRequiredTsOptions(compilerOptions: Record<string, any> | undefined) {\n const issues: string[] = [];\n const ok: string[] = [];\n\n const target = normalizeStr(compilerOptions?.target);\n const moduleVal = normalizeStr(compilerOptions?.module);\n const edm = compilerOptions?.emitDecoratorMetadata;\n const ed = compilerOptions?.experimentalDecorators;\n\n if (target === REQUIRED_DECORATOR_FIELDS.target)\n ok.push(`compilerOptions.target = \"${REQUIRED_DECORATOR_FIELDS.target}\"`);\n else issues.push(`compilerOptions.target should be \"${REQUIRED_DECORATOR_FIELDS.target}\"`);\n\n if (moduleVal === REQUIRED_DECORATOR_FIELDS.module)\n ok.push(`compilerOptions.module = \"${REQUIRED_DECORATOR_FIELDS.module}\"`);\n else issues.push(`compilerOptions.module should be \"${REQUIRED_DECORATOR_FIELDS.module}\"`);\n\n if (edm === REQUIRED_DECORATOR_FIELDS.emitDecoratorMetadata) ok.push(`compilerOptions.emitDecoratorMetadata = true`);\n else issues.push(`compilerOptions.emitDecoratorMetadata should be true`);\n\n if (ed === REQUIRED_DECORATOR_FIELDS.experimentalDecorators) ok.push(`compilerOptions.experimentalDecorators = true`);\n else issues.push(`compilerOptions.experimentalDecorators should be true`);\n\n return { ok, issues };\n}\n\nexport async function runInit(baseDir?: string): Promise<void> {\n const cwd = baseDir ?? process.cwd();\n const tsconfigPath = path.join(cwd, 'tsconfig.json');\n const existing = await readJSON<Record<string, any>>(tsconfigPath);\n\n if (!existing) {\n console.log(c('yellow', `tsconfig.json not found — creating one in ${path.relative(process.cwd(), cwd) || '.'}.`));\n await writeJSON(tsconfigPath, RECOMMENDED_TSCONFIG);\n console.log(c('green', '✅ Created tsconfig.json with required decorator settings.'));\n return;\n }\n\n let merged = deepMerge(RECOMMENDED_TSCONFIG as any, existing);\n merged = ensureRequiredTsOptions(merged);\n\n await writeJSON(tsconfigPath, merged);\n console.log(c('green', '✅ tsconfig.json verified and updated (required decorator settings enforced).'));\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { promises as fsp } from 'fs';
|
|
2
|
+
export declare function fileExists(p: string): Promise<boolean>;
|
|
3
|
+
export declare function readJSON<T = any>(jsonPath: string): Promise<T | null>;
|
|
4
|
+
export declare function writeJSON(p: string, obj: any): Promise<void>;
|
|
5
|
+
export declare function resolveEntry(cwd: string, explicit?: string): Promise<string>;
|
|
6
|
+
export declare function runCmd(cmd: string, args: string[], opts?: {
|
|
7
|
+
cwd?: string;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
export declare function ensureDir(p: string): Promise<void>;
|
|
10
|
+
export declare function isDirEmpty(dir: string): Promise<boolean>;
|
|
11
|
+
export { fsp };
|
package/src/utils/fs.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fsp = void 0;
|
|
4
|
+
exports.fileExists = fileExists;
|
|
5
|
+
exports.readJSON = readJSON;
|
|
6
|
+
exports.writeJSON = writeJSON;
|
|
7
|
+
exports.resolveEntry = resolveEntry;
|
|
8
|
+
exports.runCmd = runCmd;
|
|
9
|
+
exports.ensureDir = ensureDir;
|
|
10
|
+
exports.isDirEmpty = isDirEmpty;
|
|
11
|
+
const tslib_1 = require("tslib");
|
|
12
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
13
|
+
const fs_1 = require("fs");
|
|
14
|
+
Object.defineProperty(exports, "fsp", { enumerable: true, get: function () { return fs_1.promises; } });
|
|
15
|
+
const path = tslib_1.__importStar(require("path"));
|
|
16
|
+
const child_process_1 = require("child_process");
|
|
17
|
+
const colors_1 = require("../colors");
|
|
18
|
+
async function fileExists(p) {
|
|
19
|
+
try {
|
|
20
|
+
await fs_1.promises.access(p, fs.constants.F_OK);
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function readJSON(jsonPath) {
|
|
28
|
+
try {
|
|
29
|
+
const buf = await fs_1.promises.readFile(jsonPath, 'utf8');
|
|
30
|
+
return JSON.parse(buf);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function writeJSON(p, obj) {
|
|
37
|
+
await fs_1.promises.writeFile(p, JSON.stringify(obj, null, 2) + '\n', 'utf8');
|
|
38
|
+
}
|
|
39
|
+
function tryCandidates(base) {
|
|
40
|
+
const exts = ['', '.ts', '.tsx', '.js', '.mjs', '.cjs'];
|
|
41
|
+
return exts.map((ext) => base + ext);
|
|
42
|
+
}
|
|
43
|
+
async function resolveEntry(cwd, explicit) {
|
|
44
|
+
if (explicit) {
|
|
45
|
+
const full = path.resolve(cwd, explicit);
|
|
46
|
+
if (await fileExists(full))
|
|
47
|
+
return full;
|
|
48
|
+
throw new Error(`Entry override not found: ${explicit}`);
|
|
49
|
+
}
|
|
50
|
+
const pkgPath = path.join(cwd, 'package.json');
|
|
51
|
+
if (await fileExists(pkgPath)) {
|
|
52
|
+
const pkg = await readJSON(pkgPath);
|
|
53
|
+
if (pkg && typeof pkg.main === 'string' && pkg.main.trim()) {
|
|
54
|
+
const mainCandidates = tryCandidates(path.resolve(cwd, pkg.main));
|
|
55
|
+
for (const p of mainCandidates) {
|
|
56
|
+
if (await fileExists(p))
|
|
57
|
+
return p;
|
|
58
|
+
}
|
|
59
|
+
const asDir = path.resolve(cwd, pkg.main);
|
|
60
|
+
const idxCandidates = tryCandidates(path.join(asDir, 'index'));
|
|
61
|
+
for (const p of idxCandidates) {
|
|
62
|
+
if (await fileExists(p))
|
|
63
|
+
return p;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const fallback = path.join(cwd, 'src', 'main.ts');
|
|
68
|
+
if (await fileExists(fallback))
|
|
69
|
+
return fallback;
|
|
70
|
+
const msg = [
|
|
71
|
+
(0, colors_1.c)('red', 'No entry file found.'),
|
|
72
|
+
'',
|
|
73
|
+
'I looked for:',
|
|
74
|
+
` • ${pkgPath} with a valid "main" field`,
|
|
75
|
+
` • ${path.relative(cwd, fallback)}`,
|
|
76
|
+
'',
|
|
77
|
+
'Please create an entry file (e.g. src/main.ts) or set "main" in package.json,',
|
|
78
|
+
'or run with an explicit path:',
|
|
79
|
+
` frontmcp dev --entry src/main.ts`,
|
|
80
|
+
].join('\n');
|
|
81
|
+
throw new Error(msg);
|
|
82
|
+
}
|
|
83
|
+
function runCmd(cmd, args, opts = {}) {
|
|
84
|
+
return new Promise((resolve, reject) => {
|
|
85
|
+
const child = (0, child_process_1.spawn)(cmd, args, { stdio: 'inherit', shell: false, ...opts });
|
|
86
|
+
child.on('close', (code) => (code === 0 ? resolve() : reject(new Error(`${cmd} exited with code ${code}`))));
|
|
87
|
+
child.on('error', reject);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
async function ensureDir(p) {
|
|
91
|
+
await fs_1.promises.mkdir(p, { recursive: true });
|
|
92
|
+
}
|
|
93
|
+
async function isDirEmpty(dir) {
|
|
94
|
+
try {
|
|
95
|
+
const items = await fs_1.promises.readdir(dir);
|
|
96
|
+
return items.length === 0;
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
if (e?.code === 'ENOENT')
|
|
100
|
+
return true;
|
|
101
|
+
throw e;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=fs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../../src/utils/fs.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport { promises as fsp } from 'fs';\nimport * as path from 'path';\nimport { spawn } from 'child_process';\nimport { c } from '../colors';\n\nexport async function fileExists(p: string): Promise<boolean> {\n try {\n await fsp.access(p, fs.constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readJSON<T = any>(jsonPath: string): Promise<T | null> {\n try {\n const buf = await fsp.readFile(jsonPath, 'utf8');\n return JSON.parse(buf) as T;\n } catch {\n return null;\n }\n}\n\nexport async function writeJSON(p: string, obj: any) {\n await fsp.writeFile(p, JSON.stringify(obj, null, 2) + '\\n', 'utf8');\n}\n\nfunction tryCandidates(base: string): string[] {\n const exts = ['', '.ts', '.tsx', '.js', '.mjs', '.cjs'];\n return exts.map((ext) => base + ext);\n}\n\nexport async function resolveEntry(cwd: string, explicit?: string): Promise<string> {\n if (explicit) {\n const full = path.resolve(cwd, explicit);\n if (await fileExists(full)) return full;\n throw new Error(`Entry override not found: ${explicit}`);\n }\n\n const pkgPath = path.join(cwd, 'package.json');\n if (await fileExists(pkgPath)) {\n const pkg = await readJSON<any>(pkgPath);\n if (pkg && typeof pkg.main === 'string' && pkg.main.trim()) {\n const mainCandidates = tryCandidates(path.resolve(cwd, pkg.main));\n for (const p of mainCandidates) {\n if (await fileExists(p)) return p;\n }\n const asDir = path.resolve(cwd, pkg.main);\n const idxCandidates = tryCandidates(path.join(asDir, 'index'));\n for (const p of idxCandidates) {\n if (await fileExists(p)) return p;\n }\n }\n }\n\n const fallback = path.join(cwd, 'src', 'main.ts');\n if (await fileExists(fallback)) return fallback;\n\n const msg = [\n c('red', 'No entry file found.'),\n '',\n 'I looked for:',\n ` • ${pkgPath} with a valid \"main\" field`,\n ` • ${path.relative(cwd, fallback)}`,\n '',\n 'Please create an entry file (e.g. src/main.ts) or set \"main\" in package.json,',\n 'or run with an explicit path:',\n ` frontmcp dev --entry src/main.ts`,\n ].join('\\n');\n throw new Error(msg);\n}\n\nexport function runCmd(cmd: string, args: string[], opts: { cwd?: string } = {}): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(cmd, args, { stdio: 'inherit', shell: false, ...opts });\n child.on('close', (code) => (code === 0 ? resolve() : reject(new Error(`${cmd} exited with code ${code}`))));\n child.on('error', reject);\n });\n}\n\nexport async function ensureDir(p: string): Promise<void> {\n await fsp.mkdir(p, { recursive: true });\n}\n\nexport async function isDirEmpty(dir: string): Promise<boolean> {\n try {\n const items = await fsp.readdir(dir);\n return items.length === 0;\n } catch (e: unknown) {\n if ((e as NodeJS.ErrnoException)?.code === 'ENOENT') return true;\n throw e;\n }\n}\n\nexport { fsp }; // re-export if needed in other modules\n"]}
|