- 新增 `shared/` 目录,统一管理前后端共享的类型定义与工具函数,消除重复代码 - 重构 IPC 数据传输,使用 `toIpcSafeSnapshot` 确保序列化安全 - 新增系统托盘独立窗口 (`/tray` 路由) 与主窗口关闭行为设置,提升用户体验 - 优化 Sing-box 配置校验错误提示,增强可读性 - 修复订阅更新无新节点时的提示逻辑 - 更新项目依赖与构建配置,支持共享层路径别名 (`@shared`) - 补充单元测试,完善国际化词条
66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
/**
|
||
* 标准化节点类型字符串
|
||
*
|
||
* 统一前后端对节点类型的标识,合并了两端原有的逻辑。
|
||
*
|
||
* @param type - 原始节点类型
|
||
* @returns 标准化后的节点类型
|
||
*
|
||
* @example
|
||
* normalizeNodeType('ss') // 'shadowsocks'
|
||
* normalizeNodeType('socks5') // 'socks'
|
||
* normalizeNodeType('https') // 'http'
|
||
*/
|
||
export function normalizeNodeType(type: unknown): string {
|
||
const t = String(type ?? '').trim().toLowerCase()
|
||
if (t === 'ss' || t === 'shadowsocks') return 'shadowsocks'
|
||
if (t === 'socks5' || t === 'socks') return 'socks'
|
||
if (t === 'https' || t === 'http') return 'http'
|
||
return t
|
||
}
|
||
|
||
/**
|
||
* 检查字符串是否为有效的图标 URL
|
||
*
|
||
* 支持 http/https/file 协议及 data URI scheme。
|
||
*/
|
||
export function isIconUrl(value: string): boolean {
|
||
const v = value.trim()
|
||
return (
|
||
v.startsWith('http://') ||
|
||
v.startsWith('https://') ||
|
||
v.startsWith('file://') ||
|
||
v.startsWith('data:')
|
||
)
|
||
}
|
||
|
||
/**
|
||
* 安全解析 JSON 字符串
|
||
*
|
||
* 尝试解析 JSON,如果失败则返回默认值,避免抛出异常。
|
||
*/
|
||
export function safeJsonParse<T>(value: string, fallback: T): T {
|
||
try {
|
||
return JSON.parse(value) as T
|
||
} catch {
|
||
return fallback
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 解析字符串数组
|
||
*
|
||
* 支持解析 JSON 数组字符串或逗号分隔的字符串。
|
||
*/
|
||
export function parseStringArray(value: string): string[] {
|
||
try {
|
||
const parsed = JSON.parse(value)
|
||
if (Array.isArray(parsed)) {
|
||
return parsed.map(v => String(v).trim()).filter(Boolean)
|
||
}
|
||
} catch {
|
||
// ignore
|
||
}
|
||
return value.split(/[,,]/).map(v => v.trim()).filter(Boolean)
|
||
}
|