mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-06-16 13:34:04 +08:00
1805ed586e
Fixes two critical issues with the MCP JSON input:
1. Format button failed with wrapped format like "server": {...}
2. Submit button failed despite input validation passing
Changes:
- Updated formatJSON to use smart parser (supports wrapped format)
- Simplified submit validation logic (removed redundant validateJsonConfig call)
- Improved UX: input preserves original format, cleanup happens on format/submit
* Prevents confusing "instant disappearance" when pasting wrapped JSON
* Auto-fills ID/Name fields while keeping input unchanged
* Format button now strips wrapper key and formats cleanly
* Submit button correctly extracts config regardless of format
Code quality:
- Reduced code by 5 lines (20 changes, 11 insertions, 16 deletions)
- Consistent use of parseSmartMcpJson across all JSON operations
- No type errors introduced
81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
/**
|
|
* 格式化 JSON 字符串
|
|
* @param value - 原始 JSON 字符串(支持带键名包装的格式)
|
|
* @returns 格式化后的 JSON 字符串(2 空格缩进)
|
|
* @throws 如果 JSON 格式无效
|
|
*/
|
|
export function formatJSON(value: string): string {
|
|
const trimmed = value.trim();
|
|
if (!trimmed) {
|
|
return "";
|
|
}
|
|
// 使用智能解析器来处理可能的片段格式
|
|
const result = parseSmartMcpJson(trimmed);
|
|
return result.formattedConfig;
|
|
}
|
|
|
|
/**
|
|
* 智能解析 MCP JSON 配置
|
|
* 支持两种格式:
|
|
* 1. 纯配置对象:{ "command": "npx", "args": [...], ... }
|
|
* 2. 带键名包装: "server-name": { "command": "npx", ... } 或 { "server-name": {...} }
|
|
*
|
|
* @param jsonText - JSON 字符串
|
|
* @returns { id?: string, config: object, formattedConfig: string }
|
|
* @throws 如果 JSON 格式无效
|
|
*/
|
|
export function parseSmartMcpJson(jsonText: string): {
|
|
id?: string;
|
|
config: any;
|
|
formattedConfig: string;
|
|
} {
|
|
let trimmed = jsonText.trim();
|
|
if (!trimmed) {
|
|
return { config: {}, formattedConfig: "" };
|
|
}
|
|
|
|
// 如果是键值对片段("key": {...}),包装成完整对象
|
|
if (trimmed.startsWith('"') && !trimmed.startsWith('{')) {
|
|
trimmed = `{${trimmed}}`;
|
|
}
|
|
|
|
const parsed = JSON.parse(trimmed);
|
|
|
|
// 如果是单键对象且值是对象,提取键名和配置
|
|
const keys = Object.keys(parsed);
|
|
if (
|
|
keys.length === 1 &&
|
|
parsed[keys[0]] &&
|
|
typeof parsed[keys[0]] === "object" &&
|
|
!Array.isArray(parsed[keys[0]])
|
|
) {
|
|
const id = keys[0];
|
|
const config = parsed[id];
|
|
return {
|
|
id,
|
|
config,
|
|
formattedConfig: JSON.stringify(config, null, 2),
|
|
};
|
|
}
|
|
|
|
// 否则直接使用
|
|
return {
|
|
config: parsed,
|
|
formattedConfig: JSON.stringify(parsed, null, 2),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* TOML 格式化功能已禁用
|
|
*
|
|
* 原因:smol-toml 的 parse/stringify 会丢失所有注释和原有排版。
|
|
* 由于 TOML 常用于配置文件,注释是重要的文档说明,丢失注释会造成严重的用户体验问题。
|
|
*
|
|
* 未来可选方案:
|
|
* - 使用 @ltd/j-toml(支持注释保留,但需额外依赖和复杂的 API)
|
|
* - 实现仅格式化缩进/空白的轻量级方案
|
|
* - 使用 toml-eslint-parser + 自定义生成器
|
|
*
|
|
* 暂时建议:依赖现有的 TOML 语法校验(useCodexTomlValidation),不提供格式化功能。
|
|
*/
|