fix: add missing await keywords and refactor duplicate code

This commit is contained in:
xmk23333 2025-12-08 22:32:14 +08:00
parent dcbd837949
commit 972d2fe946
6 changed files with 42 additions and 115 deletions

View File

@ -40,7 +40,7 @@ export async function addOverrideItem(item: Partial<IOverrideItem>): Promise<voi
const config = await getOverrideConfig()
const newItem = await createOverride(item)
if (await getOverrideItem(item.id)) {
updateOverrideItem(newItem)
await updateOverrideItem(newItem)
} else {
config.items.push(newItem)
}
@ -84,7 +84,7 @@ export async function createOverride(item: Partial<IOverrideItem>): Promise<IOve
}
case 'local': {
const data = item.file || ''
setOverride(id, newItem.ext, data)
await setOverride(id, newItem.ext, data)
break
}
}

View File

@ -339,30 +339,14 @@ export async function createSmartOverride(): Promise<void> {
smartCollectorSize
)
// 检查是否已存在 Smart 覆写配置
const existingOverride = await getOverrideItem(SMART_OVERRIDE_ID)
if (existingOverride) {
// 如果已存在,更新配置
await addOverrideItem({
id: SMART_OVERRIDE_ID,
name: 'Smart Core Override',
type: 'local',
ext: 'js',
global: true,
file: template
})
} else {
// 如果不存在,创建新的覆写配置
await addOverrideItem({
id: SMART_OVERRIDE_ID,
name: 'Smart Core Override',
type: 'local',
ext: 'js',
global: true,
file: template
})
}
await addOverrideItem({
id: SMART_OVERRIDE_ID,
name: 'Smart Core Override',
type: 'local',
ext: 'js',
global: true,
file: template
})
} catch (error) {
await overrideLogger.error('Failed to create Smart override', error)
throw error

View File

@ -499,24 +499,7 @@ async function checkProfile(): Promise<void> {
}
export async function checkTunPermissions(): Promise<boolean> {
const { core = 'mihomo' } = await getAppConfig()
const corePath = mihomoCorePath(core)
try {
if (process.platform === 'win32') {
return await checkAdminPrivileges()
}
if (process.platform === 'darwin' || process.platform === 'linux') {
const { stat } = await import('fs/promises')
const stats = await stat(corePath)
return (stats.mode & 0o4000) !== 0 && stats.uid === 0
}
} catch {
return false
}
return false
return checkMihomoCorePermissions()
}
export async function grantTunPermissions(): Promise<void> {

View File

@ -7,7 +7,7 @@ import { quitWithoutCore, startCore, stopCore, checkAdminRestartForTun, checkHig
import { triggerSysProxy } from './sys/sysproxy'
import icon from '../../resources/icon.png?asset'
import { createTray, hideDockIcon, showDockIcon } from './resolve/tray'
import { init, initBasic } from './utils/init'
import { init, initBasic, safeShowErrorBox } from './utils/init'
import { join } from 'path'
import { initShortcut } from './resolve/shortcut'
import { spawn, exec } from 'child_process'
@ -23,24 +23,6 @@ import i18next from 'i18next'
import { logger } from './utils/logger'
import { initWebdavBackupScheduler } from './resolve/backup'
// 错误处理
function showSafeErrorBox(titleKey: string, message: string): void {
let title: string
try {
title = i18next.t(titleKey)
if (!title || title === titleKey) throw new Error('Translation not ready')
} catch {
const isZh = app.getLocale().startsWith('zh')
const fallbacks: Record<string, { zh: string; en: string }> = {
'common.error.initFailed': { zh: '应用初始化失败', en: 'Application initialization failed' },
'mihomo.error.coreStartFailed': { zh: '内核启动出错', en: 'Core start failed' },
'profiles.error.importFailed': { zh: '配置导入失败', en: 'Profile import failed' },
'common.error.adminRequired': { zh: '需要管理员权限', en: 'Administrator privileges required' }
}
title = fallbacks[titleKey] ? (isZh ? fallbacks[titleKey].zh : fallbacks[titleKey].en) : (isZh ? '错误' : 'Error')
}
dialog.showErrorBox(title, message)
}
async function fixUserDataPermissions(): Promise<void> {
if (process.platform !== 'darwin') return
@ -80,7 +62,7 @@ async function initApp(): Promise<void> {
initApp()
.catch((e) => {
showSafeErrorBox('common.error.initFailed', `${e}`)
safeShowErrorBox('common.error.initFailed', `${e}`)
app.quit()
})
@ -150,7 +132,7 @@ async function checkHighPrivilegeCoreEarly(): Promise<void> {
await restartAsAdmin(false)
process.exit(0)
} catch (error) {
showSafeErrorBox('common.error.adminRequired', `${error}`)
safeShowErrorBox('common.error.adminRequired', `${error}`)
process.exit(1)
}
} else {
@ -234,7 +216,7 @@ app.whenReady().then(async () => {
}
await initI18n({ lng: appConfig.language })
} catch (e) {
showSafeErrorBox('common.error.initFailed', `${e}`)
safeShowErrorBox('common.error.initFailed', `${e}`)
app.quit()
}
@ -247,7 +229,7 @@ app.whenReady().then(async () => {
await checkAdminRestartForTun()
})
} catch (e) {
showSafeErrorBox('mihomo.error.coreStartFailed', `${e}`)
safeShowErrorBox('mihomo.error.coreStartFailed', `${e}`)
}
try {
await startMonitor()
@ -303,7 +285,7 @@ async function handleDeepLink(url: string): Promise<void> {
new Notification({ title: i18next.t('profiles.notification.importSuccess') }).show()
break
} catch (e) {
showSafeErrorBox('profiles.error.importFailed', `${url}\n${e}`)
safeShowErrorBox('profiles.error.importFailed', `${url}\n${e}`)
}
}
}

View File

@ -21,7 +21,13 @@ import i18next from 'i18next'
let backupCronJob: Cron | null = null
export async function webdavBackup(): Promise<boolean> {
interface WebDAVContext {
client: ReturnType<Awaited<typeof import('webdav/dist/node/index.js')>['createClient']>
webdavDir: string
webdavMaxBackups: number
}
async function getWebDAVClient(): Promise<WebDAVContext> {
const { createClient } = await import('webdav/dist/node/index.js')
const {
webdavUrl = '',
@ -30,6 +36,17 @@ export async function webdavBackup(): Promise<boolean> {
webdavDir = 'clash-party',
webdavMaxBackups = 0
} = await getAppConfig()
const client = createClient(webdavUrl, {
username: webdavUsername,
password: webdavPassword
})
return { client, webdavDir, webdavMaxBackups }
}
export async function webdavBackup(): Promise<boolean> {
const { client, webdavDir, webdavMaxBackups } = await getWebDAVClient()
const zip = new AdmZip()
zip.addLocalFile(appConfigPath())
@ -44,10 +61,6 @@ export async function webdavBackup(): Promise<boolean> {
const date = new Date()
const zipFileName = `${process.platform}_${dayjs(date).format('YYYY-MM-DD_HH-mm-ss')}.zip`
const client = createClient(webdavUrl, {
username: webdavUsername,
password: webdavPassword
})
try {
await client.createDirectory(webdavDir)
} catch {
@ -92,36 +105,14 @@ export async function webdavBackup(): Promise<boolean> {
}
export async function webdavRestore(filename: string): Promise<void> {
const { createClient } = await import('webdav/dist/node/index.js')
const {
webdavUrl = '',
webdavUsername = '',
webdavPassword = '',
webdavDir = 'clash-party'
} = await getAppConfig()
const client = createClient(webdavUrl, {
username: webdavUsername,
password: webdavPassword
})
const { client, webdavDir } = await getWebDAVClient()
const zipData = await client.getFileContents(`${webdavDir}/${filename}`)
const zip = new AdmZip(zipData as Buffer)
zip.extractAllTo(dataDir(), true)
}
export async function listWebdavBackups(): Promise<string[]> {
const { createClient } = await import('webdav/dist/node/index.js')
const {
webdavUrl = '',
webdavUsername = '',
webdavPassword = '',
webdavDir = 'clash-party'
} = await getAppConfig()
const client = createClient(webdavUrl, {
username: webdavUsername,
password: webdavPassword
})
const { client, webdavDir } = await getWebDAVClient()
const files = await client.getDirectoryContents(webdavDir, { glob: '*.zip' })
if (Array.isArray(files)) {
return files.map((file) => file.basename)
@ -131,18 +122,7 @@ export async function listWebdavBackups(): Promise<string[]> {
}
export async function webdavDelete(filename: string): Promise<void> {
const { createClient } = await import('webdav/dist/node/index.js')
const {
webdavUrl = '',
webdavUsername = '',
webdavPassword = '',
webdavDir = 'clash-party'
} = await getAppConfig()
const client = createClient(webdavUrl, {
username: webdavUsername,
password: webdavPassword
})
const { client, webdavDir } = await getWebDAVClient()
await client.deleteFile(`${webdavDir}/${filename}`)
}

View File

@ -42,7 +42,7 @@ import {
} from '../config'
import { app, dialog } from 'electron'
import { startSSIDCheck } from '../sys/ssid'
import i18next from '../../shared/i18n'
import i18next, { resources } from '../../shared/i18n'
import { initLogger } from './logger'
let isInitBasicCompleted = false
@ -54,11 +54,9 @@ export function safeShowErrorBox(titleKey: string, message: string): void {
title = i18next.t(titleKey)
if (!title || title === titleKey) throw new Error('Translation not ready')
} catch {
const isZh = process.env.LANG?.startsWith('zh') || process.env.LC_ALL?.startsWith('zh')
const fallbacks: Record<string, { zh: string; en: string }> = {
'mihomo.error.coreStartFailed': { zh: '内核启动出错', en: 'Core start failed' }
}
title = fallbacks[titleKey] ? (isZh ? fallbacks[titleKey].zh : fallbacks[titleKey].en) : (isZh ? '错误' : 'Error')
const isZh = app.getLocale().startsWith('zh')
const lang = isZh ? resources['zh-CN'].translation : resources['en-US'].translation
title = lang[titleKey] || (isZh ? '错误' : 'Error')
}
dialog.showErrorBox(title, message)
}