fix: short-id parsing error

This commit is contained in:
Memory 2025-09-06 19:27:00 +08:00 committed by GitHub
parent bcecca7ab7
commit c8d83f45ac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 35 additions and 34 deletions

View File

@ -1,6 +1,6 @@
import { readFile, writeFile } from 'fs/promises'
import { appConfigPath } from '../utils/dirs'
import yaml from 'yaml'
import { parse, stringify } from '../utils/yaml'
import { deepMerge } from '../utils/merge'
import { defaultConfig } from '../utils/template'
@ -9,7 +9,7 @@ let appConfig: IAppConfig // config.yaml
export async function getAppConfig(force = false): Promise<IAppConfig> {
if (force || !appConfig) {
const data = await readFile(appConfigPath(), 'utf-8')
appConfig = yaml.parse(data, { merge: true }) || defaultConfig
appConfig = parse(data) || defaultConfig
}
if (typeof appConfig !== 'object') appConfig = defaultConfig
return appConfig
@ -20,5 +20,5 @@ export async function patchAppConfig(patch: Partial<IAppConfig>): Promise<void>
appConfig.nameserverPolicy = patch.nameserverPolicy
}
appConfig = deepMerge(appConfig, patch)
await writeFile(appConfigPath(), yaml.stringify(appConfig))
await writeFile(appConfigPath(), stringify(appConfig))
}

View File

@ -1,6 +1,6 @@
import { controledMihomoConfigPath } from '../utils/dirs'
import { readFile, writeFile } from 'fs/promises'
import yaml from 'yaml'
import { parse, stringify } from '../utils/yaml'
import { generateProfile } from '../core/factory'
import { getAppConfig } from './app'
import { defaultControledMihomoConfig } from '../utils/template'
@ -11,7 +11,7 @@ let controledMihomoConfig: Partial<IMihomoConfig> // mihomo.yaml
export async function getControledMihomoConfig(force = false): Promise<Partial<IMihomoConfig>> {
if (force || !controledMihomoConfig) {
const data = await readFile(controledMihomoConfigPath(), 'utf-8')
controledMihomoConfig = yaml.parse(data, { merge: true }) || defaultControledMihomoConfig
controledMihomoConfig = parse(data) || defaultControledMihomoConfig
// 确保配置包含所有必要的默认字段,处理升级场景
controledMihomoConfig = deepMerge(defaultControledMihomoConfig, controledMihomoConfig)
@ -46,5 +46,5 @@ export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>):
}
await generateProfile()
await writeFile(controledMihomoConfigPath(), yaml.stringify(controledMihomoConfig), 'utf-8')
await writeFile(controledMihomoConfigPath(), stringify(controledMihomoConfig), 'utf-8')
}

View File

@ -3,14 +3,14 @@ import { getControledMihomoConfig } from './controledMihomo'
import { readFile, writeFile, rm } from 'fs/promises'
import { existsSync } from 'fs'
import axios from 'axios'
import yaml from 'yaml'
import { parse, stringify } from '../utils/yaml'
let overrideConfig: IOverrideConfig // override.yaml
export async function getOverrideConfig(force = false): Promise<IOverrideConfig> {
if (force || !overrideConfig) {
const data = await readFile(overrideConfigPath(), 'utf-8')
overrideConfig = yaml.parse(data, { merge: true }) || { items: [] }
overrideConfig = parse(data) || { items: [] }
}
if (typeof overrideConfig !== 'object') overrideConfig = { items: [] }
return overrideConfig
@ -18,7 +18,7 @@ export async function getOverrideConfig(force = false): Promise<IOverrideConfig>
export async function setOverrideConfig(config: IOverrideConfig): Promise<void> {
overrideConfig = config
await writeFile(overrideConfigPath(), yaml.stringify(overrideConfig), 'utf-8')
await writeFile(overrideConfigPath(), stringify(overrideConfig), 'utf-8')
}
export async function getOverrideItem(id: string | undefined): Promise<IOverrideItem | undefined> {

View File

@ -6,7 +6,7 @@ import { restartCore } from '../core/manager'
import { getAppConfig } from './app'
import { existsSync } from 'fs'
import axios, { AxiosResponse } from 'axios'
import yaml from 'yaml'
import { parse, stringify } from '../utils/yaml'
import { defaultProfile } from '../utils/template'
import { subStorePort } from '../resolve/server'
import { join } from 'path'
@ -17,7 +17,7 @@ let profileConfig: IProfileConfig // profile.yaml
export async function getProfileConfig(force = false): Promise<IProfileConfig> {
if (force || !profileConfig) {
const data = await readFile(profileConfigPath(), 'utf-8')
profileConfig = yaml.parse(data, { merge: true }) || { items: [] }
profileConfig = parse(data) || { items: [] }
}
if (typeof profileConfig !== 'object') profileConfig = { items: [] }
return profileConfig
@ -25,7 +25,7 @@ export async function getProfileConfig(force = false): Promise<IProfileConfig> {
export async function setProfileConfig(config: IProfileConfig): Promise<void> {
profileConfig = config
await writeFile(profileConfigPath(), yaml.stringify(config), 'utf-8')
await writeFile(profileConfigPath(), stringify(config), 'utf-8')
}
export async function getProfileItem(id: string | undefined): Promise<IProfileItem | undefined> {
@ -198,7 +198,7 @@ export async function getProfileStr(id: string | undefined): Promise<string> {
if (existsSync(profilePath(id || 'default'))) {
return await readFile(profilePath(id || 'default'), 'utf-8')
} else {
return yaml.stringify(defaultProfile)
return stringify(defaultProfile)
}
}
@ -210,12 +210,9 @@ export async function setProfileStr(id: string, content: string): Promise<void>
export async function getProfile(id: string | undefined): Promise<IMihomoConfig> {
const profile = await getProfileStr(id)
// 替换 防止错误使用科学记数法解析
const patchedProfile = profile.replace(/(\w+:\s*)(\d+E\d+)(\s|$)/gi, '$1"$2"$3')
let result = yaml.parse(patchedProfile, { merge: true }) || {}
let result = parse(profile)
if (typeof result !== 'object') result = {}
return result
return result as IMihomoConfig
}
// attachment;filename=xxx.yaml; filename*=UTF-8''%xx%xx%xx

View File

@ -14,7 +14,7 @@ import {
mihomoWorkDir,
overridePath
} from '../utils/dirs'
import yaml from 'yaml'
import { parse, stringify } from '../utils/yaml'
import { copyFile, mkdir, writeFile } from 'fs/promises'
import { deepMerge } from '../utils/merge'
import vm from 'vm'
@ -50,16 +50,7 @@ export async function generateProfile(): Promise<void> {
profile['log-level'] = 'info'
}
runtimeConfig = profile
// 先正常生成 YAML 字符串
let yamlStr = yaml.stringify(profile)
// 还原科学记数法的引号
yamlStr = yamlStr.replace(
/(\w+:\s*)"(\d+E\d+)"(\s|$)/gi,
'$1$2$3'
)
runtimeConfigStr = yamlStr
runtimeConfigStr = stringify(profile)
if (diffWorkDir) {
await prepareProfileWorkDir(current)
}
@ -104,7 +95,7 @@ async function overrideProfile(
profile = runOverrideScript(profile, content, item)
break
case 'yaml': {
let patch = yaml.parse(content, { merge: true }) || {}
let patch = parse(content) || {}
if (typeof patch !== 'object') patch = {}
profile = deepMerge(profile, patch)
break

View File

@ -1,5 +1,5 @@
import axios from 'axios'
import yaml from 'yaml'
import { parse } from '../utils/yaml'
import { app, shell } from 'electron'
import { getControledMihomoConfig } from '../config'
import { dataDir, exeDir, exePath, isPortable, resourcesFilesDir } from '../utils/dirs'
@ -26,7 +26,7 @@ export async function checkUpdate(): Promise<IAppVersion | undefined> {
responseType: 'text'
}
)
const latest = yaml.parse(res.data, { merge: true }) as IAppVersion
const latest = parse(res.data) as IAppVersion
const currentVersion = app.getVersion()
if (compareVersions(latest.version, currentVersion) > 0) {
return latest

View File

@ -21,7 +21,7 @@ import {
defaultProfile,
defaultProfileConfig
} from './template'
import yaml from 'yaml'
import { stringify } from './yaml'
import { mkdir, writeFile, rm, readdir, cp, stat, rename } from 'fs/promises'
import { existsSync } from 'fs'
import { exec } from 'child_process'
@ -134,7 +134,7 @@ async function initConfig(): Promise<void> {
for (const config of configs) {
try {
if (!existsSync(config.path)) {
await writeFile(config.path, yaml.stringify(config.content))
await writeFile(config.path, stringify(config.content))
}
} catch (error) {
await initLogger.error(`Failed to create ${config.name} at ${config.path}`, error)

13
src/main/utils/yaml.ts Normal file
View File

@ -0,0 +1,13 @@
import yaml from 'yaml'
export const parse = <T = unknown>(content: string): T => {
const processedContent = content.replace(
/(^|\{|,)(\s*short-id:\s*)(?!['"]|null\b|Null\b|NULL\b|~)([^"'\s,}\n]+)/gm,
'$1$2"$3"'
)
return (yaml.parse(processedContent, { merge: true }) as T) || ({} as T)
}
export function stringify(content: unknown): string {
return yaml.stringify(content)
}