feat(schema): add common JSON/TOML validators and enforce MCP conditional fields

- Add src/lib/schemas/common.ts with jsonConfigSchema and tomlConfigSchema
- Enhance src/lib/schemas/mcp.ts to require command for stdio and url for http via superRefine
- Keep ProviderForm as-is; future steps will wire new schemas into RHF flows
- Verified: pnpm typecheck passes
This commit is contained in:
Jason
2025-11-09 20:42:25 +08:00
parent 772081312e
commit 7b52c44a9d
4 changed files with 224 additions and 44 deletions

View File

@@ -1,19 +1,56 @@
import { z } from "zod";
/**
* 解析 JSON 语法错误,提取位置信息
*/
function parseJsonError(error: unknown): string {
if (!(error instanceof SyntaxError)) {
return "配置 JSON 格式错误";
}
const message = error.message;
// 提取位置信息Chrome/V8: "Unexpected token ... in JSON at position 123"
const positionMatch = message.match(/at position (\d+)/i);
if (positionMatch) {
const position = parseInt(positionMatch[1], 10);
return `JSON 格式错误:${message.split(" in JSON")[0]}(位置:${position}`;
}
// Firefox: "JSON.parse: unexpected character at line 1 column 23"
const lineColumnMatch = message.match(/line (\d+) column (\d+)/i);
if (lineColumnMatch) {
const line = lineColumnMatch[1];
const column = lineColumnMatch[2];
return `JSON 格式错误:第 ${line} 行,第 ${column}`;
}
// 通用情况:提取关键错误信息
const cleanMessage = message
.replace(/^JSON\.parse:\s*/i, "")
.replace(/^Unexpected\s+/i, "意外的 ")
.replace(/token/gi, "符号")
.replace(/Expected/gi, "预期");
return `JSON 格式错误:${cleanMessage}`;
}
export const providerSchema = z.object({
name: z.string().min(1, "请填写供应商名称"),
websiteUrl: z.string().url("请输入有效的网址").optional().or(z.literal("")),
settingsConfig: z
.string()
.min(1, "请填写配置内容")
.refine((value) => {
.superRefine((value, ctx) => {
try {
JSON.parse(value);
return true;
} catch {
return false;
} catch (error) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: parseJsonError(error),
});
}
}, "配置 JSON 格式错误"),
}),
});
export type ProviderFormData = z.infer<typeof providerSchema>;