use deep merge

This commit is contained in:
pompurin404 2024-08-17 15:02:54 +08:00
parent 17e681e156
commit d9b9977fe9
No known key found for this signature in database
5 changed files with 28 additions and 50 deletions

View File

@ -1,6 +1,7 @@
import { readFile, writeFile } from 'fs/promises'
import { appConfigPath } from '../utils/dirs'
import yaml from 'yaml'
import { deepMerge } from '../utils/merge'
let appConfig: IAppConfig // config.yaml
@ -13,11 +14,6 @@ export async function getAppConfig(force = false): Promise<IAppConfig> {
}
export async function patchAppConfig(patch: Partial<IAppConfig>): Promise<void> {
if (patch.sysProxy) {
const oldSysProxy = appConfig.sysProxy || {}
const newSysProxy = Object.assign(oldSysProxy, patch.sysProxy)
patch.sysProxy = newSysProxy
}
appConfig = Object.assign(appConfig, patch)
appConfig = deepMerge(appConfig, patch)
await writeFile(appConfigPath(), yaml.stringify(appConfig))
}

View File

@ -5,6 +5,7 @@ import { getAxios, startMihomoMemory, startMihomoTraffic } from '../core/mihomoA
import { generateProfile } from '../core/factory'
import { getAppConfig } from './app'
import { defaultControledMihomoConfig } from '../utils/template'
import { deepMerge } from '../utils/merge'
let controledMihomoConfig: Partial<IMihomoConfig> // mihomo.yaml
@ -18,11 +19,6 @@ export async function getControledMihomoConfig(force = false): Promise<Partial<I
export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>): Promise<void> {
const { useNameserverPolicy, controlDns = true, controlSniff = true } = await getAppConfig()
if (patch.tun) {
const oldTun = controledMihomoConfig.tun || {}
const newTun = Object.assign(oldTun, patch.tun)
patch.tun = newTun
}
if (!controlDns) {
delete controledMihomoConfig.dns
delete controledMihomoConfig.hosts
@ -32,14 +28,6 @@ export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>):
controledMihomoConfig.dns = defaultControledMihomoConfig.dns
}
}
if (patch.dns) {
const oldDns = controledMihomoConfig.dns || {}
const newDns = Object.assign(oldDns, patch.dns)
if (!useNameserverPolicy) {
delete newDns['nameserver-policy']
}
patch.dns = newDns
}
if (!controlSniff) {
delete controledMihomoConfig.sniffer
} else {
@ -48,12 +36,10 @@ export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>):
controledMihomoConfig.sniffer = defaultControledMihomoConfig.sniffer
}
}
if (patch.sniffer) {
const oldSniffer = controledMihomoConfig.sniffer || {}
const newSniffer = Object.assign(oldSniffer, patch.sniffer)
patch.sniffer = newSniffer
controledMihomoConfig = deepMerge(controledMihomoConfig, patch)
if (!useNameserverPolicy) {
delete controledMihomoConfig?.dns?.['nameserver-policy']
}
controledMihomoConfig = Object.assign(controledMihomoConfig, patch)
if (patch['external-controller'] || patch.secret) {
await getAxios(true)

View File

@ -7,35 +7,15 @@ import {
} from '../config'
import { mihomoWorkConfigPath } from '../utils/dirs'
import yaml from 'yaml'
import fs from 'fs'
import { readFile } from 'fs/promises'
import { readFile, writeFile } from 'fs/promises'
import { deepMerge } from '../utils/merge'
export async function generateProfile(): Promise<void> {
const { current } = await getProfileConfig()
const currentProfile = await overrideProfile(current, await getProfile(current))
const controledMihomoConfig = await getControledMihomoConfig()
const { tun: profileTun = {} } = currentProfile
const { tun: controledTun } = controledMihomoConfig
const tun = Object.assign(profileTun, controledTun)
const { dns: profileDns = {} } = currentProfile
const { dns: controledDns } = controledMihomoConfig
const dns = Object.assign(profileDns, controledDns)
const { sniffer: profileSniffer = {} } = currentProfile
const { sniffer: controledSniffer } = controledMihomoConfig
const sniffer = Object.assign(profileSniffer, controledSniffer)
const profile = Object.assign(currentProfile, controledMihomoConfig)
profile.tun = tun
profile.dns = dns
profile.sniffer = sniffer
return new Promise((resolve, reject) => {
fs.writeFile(mihomoWorkConfigPath(), yaml.stringify(profile), (err) => {
if (err) {
reject(err)
} else {
resolve()
}
})
})
const profile = deepMerge(currentProfile, controledMihomoConfig)
await writeFile(mihomoWorkConfigPath(), yaml.stringify(profile))
}
async function overrideProfile(

View File

@ -1,13 +1,13 @@
import { is } from '@electron-toolkit/utils'
import { app } from 'electron'
import fs from 'fs'
import { existsSync } from 'fs'
import { rm, writeFile } from 'fs/promises'
import path from 'path'
export const homeDir = app.getPath('home')
export function isPortable(): boolean {
return fs.existsSync(path.join(exeDir(), 'PORTABLE'))
return existsSync(path.join(exeDir(), 'PORTABLE'))
}
export async function setPortable(portable: boolean): Promise<void> {

16
src/main/utils/merge.ts Normal file
View File

@ -0,0 +1,16 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isObject(item: any): boolean {
return item && typeof item === 'object' && !Array.isArray(item)
}
export function deepMerge<T extends object>(target: T, other: Partial<T>): T {
for (const key in other) {
if (isObject(other[key])) {
if (!target[key]) Object.assign(target, { [key]: {} })
deepMerge(target[key] as object, other[key] as object)
} else {
Object.assign(target, { [key]: other[key] })
}
}
return target as T
}