Skip to content

Commit

Permalink
support yaml override
Browse files Browse the repository at this point in the history
  • Loading branch information
pompurin404 committed Aug 17, 2024
1 parent 6564b2b commit a464666
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 46 deletions.
20 changes: 11 additions & 9 deletions src/main/config/override.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ export async function addOverrideItem(item: Partial<IOverrideItem>): Promise<voi

export async function removeOverrideItem(id: string): Promise<void> {
const config = await getOverrideConfig()
const item = await getOverrideItem(id)
config.items = config.items?.filter((item) => item.id !== id)
await setOverrideConfig(config)
await rm(overridePath(id))
await rm(overridePath(id, item?.ext || 'js'))
}

export async function createOverride(item: Partial<IOverrideItem>): Promise<IOverrideItem> {
Expand All @@ -59,6 +60,7 @@ export async function createOverride(item: Partial<IOverrideItem>): Promise<IOve
id,
name: item.name || (item.type === 'remote' ? 'Remote File' : 'Local File'),
type: item.type,
ext: item.ext || 'js',
url: item.url,
updated: new Date().getTime()
} as IOverrideItem
Expand All @@ -74,26 +76,26 @@ export async function createOverride(item: Partial<IOverrideItem>): Promise<IOve
}
})
const data = res.data
await setOverride(id, data)
await setOverride(id, newItem.ext, data)
break
}
case 'local': {
const data = item.file || ''
setOverride(id, data)
setOverride(id, newItem.ext, data)
break
}
}

return newItem
}

export async function getOverride(id: string): Promise<string> {
if (!existsSync(overridePath(id))) {
return `function main(config){ return config }`
export async function getOverride(id: string, ext: 'js' | 'yaml'): Promise<string> {
if (!existsSync(overridePath(id, ext))) {
return ''
}
return await readFile(overridePath(id), 'utf-8')
return await readFile(overridePath(id, ext), 'utf-8')
}

export async function setOverride(id: string, content: string): Promise<void> {
await writeFile(overridePath(id), content, 'utf-8')
export async function setOverride(id: string, ext: 'js' | 'yaml', content: string): Promise<void> {
await writeFile(overridePath(id, ext), content, 'utf-8')
}
15 changes: 12 additions & 3 deletions src/main/core/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {
getProfileConfig,
getProfile,
getProfileItem,
getOverride
getOverride,
getOverrideItem
} from '../config'
import { mihomoWorkConfigPath } from '../utils/dirs'
import yaml from 'yaml'
Expand All @@ -24,8 +25,16 @@ async function overrideProfile(
): Promise<IMihomoConfig> {
const { override = [] } = (await getProfileItem(current)) || {}
for (const ov of override) {
const script = await getOverride(ov)
profile = runOverrideScript(profile, script)
const item = await getOverrideItem(ov)
const content = await getOverride(ov, item?.ext || 'js')
switch (item?.ext) {
case 'js':
profile = runOverrideScript(profile, content)
break
case 'yaml':
profile = deepMerge(profile, yaml.parse(content))
break
}
}
return profile
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/utils/dirs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ export function overrideConfigPath(): string {
return path.join(dataDir(), 'override.yaml')
}

export function overridePath(id: string): string {
return path.join(overrideDir(), `${id}.js`)
export function overridePath(id: string, ext: 'js' | 'yaml'): string {
return path.join(overrideDir(), `${id}.${ext}`)
}

export function mihomoWorkDir(): string {
Expand Down
4 changes: 2 additions & 2 deletions src/main/utils/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ export function registerIpcMainHandlers(): void {
ipcMain.handle('addOverrideItem', (_e, item) => ipcErrorWrapper(addOverrideItem)(item))
ipcMain.handle('removeOverrideItem', (_e, id) => ipcErrorWrapper(removeOverrideItem)(id))
ipcMain.handle('updateOverrideItem', (_e, item) => ipcErrorWrapper(updateOverrideItem)(item))
ipcMain.handle('getOverride', (_e, id) => ipcErrorWrapper(getOverride)(id))
ipcMain.handle('setOverride', (_e, id, str) => ipcErrorWrapper(setOverride)(id, str))
ipcMain.handle('getOverride', (_e, id, ext) => ipcErrorWrapper(getOverride)(id, ext))
ipcMain.handle('setOverride', (_e, id, ext, str) => ipcErrorWrapper(setOverride)(id, ext, str))
ipcMain.handle('restartCore', ipcErrorWrapper(restartCore))
ipcMain.handle('triggerSysProxy', (_e, enable) => ipcErrorWrapper(triggerSysProxy)(enable))
ipcMain.handle('isEncryptionAvailable', isEncryptionAvailable)
Expand Down
2 changes: 1 addition & 1 deletion src/main/utils/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const defaultControledMihomoConfig: Partial<IMihomoConfig> = {
'use-hosts': false,
'use-system-hosts': false,
nameserver: ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
'proxy-server-nameserver': ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
'proxy-server-nameserver': ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query']
},
sniffer: {
enable: true,
Expand Down
13 changes: 8 additions & 5 deletions src/renderer/src/components/override/edit-file-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import { BaseEditor } from '../base/base-editor'
import { getOverride, setOverride } from '@renderer/utils/ipc'
interface Props {
id: string
language: 'javascript' | 'yaml'
onClose: () => void
}
const EditFileModal: React.FC<Props> = (props) => {
const { id, onClose } = props
const { id, language, onClose } = props
const [currData, setCurrData] = useState('')

const getContent = async (): Promise<void> => {
setCurrData(await getOverride(id))
setCurrData(await getOverride(id, language === 'javascript' ? 'js' : 'yaml'))
}

useEffect(() => {
Expand All @@ -28,10 +29,12 @@ const EditFileModal: React.FC<Props> = (props) => {
scrollBehavior="inside"
>
<ModalContent className="h-full w-[calc(100%-100px)]">
<ModalHeader className="flex">编辑覆写脚本</ModalHeader>
<ModalHeader className="flex">
编辑覆写{language === 'javascript' ? '脚本' : '配置'}
</ModalHeader>
<ModalBody className="h-full">
<BaseEditor
language="javascript"
language={language}
value={currData}
onChange={(value) => setCurrData(value)}
/>
Expand All @@ -43,7 +46,7 @@ const EditFileModal: React.FC<Props> = (props) => {
<Button
color="primary"
onPress={async () => {
await setOverride(id, currData)
await setOverride(id, language === 'javascript' ? 'js' : 'yaml', currData)
onClose()
}}
>
Expand Down
29 changes: 19 additions & 10 deletions src/renderer/src/components/override/override-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,13 @@ const OverrideItem: React.FC<Props> = (props) => {
zIndex: isDragging ? 'calc(infinity)' : undefined
}}
>
{openFile && <EditFileModal id={info.id} onClose={() => setOpenFile(false)} />}
{openFile && (
<EditFileModal
id={info.id}
language={info.ext === 'yaml' ? 'yaml' : 'javascript'}
onClose={() => setOpenFile(false)}
/>
)}
{openInfo && (
<EditInfoModal
item={info}
Expand Down Expand Up @@ -184,18 +190,21 @@ const OverrideItem: React.FC<Props> = (props) => {
</Dropdown>
</div>
</div>
{info.type === 'remote' && (
<div className={`mt-2 flex justify-end`}>
<small>{dayjs(info.updated).fromNow()}</small>
</div>
)}
{info.type === 'local' && (
<div className={`mt-2 flex justify-between`}>
<div className="flex justify-between">
<div className={`mt-2 flex justify-start`}>
<Chip size="sm" variant="bordered">
本地
{info.type === 'local' ? '本地' : '远程'}
</Chip>
<Chip size="sm" variant="bordered" className="ml-2">
{info.ext === 'yaml' ? 'YAML' : 'JavaScript'}
</Chip>
</div>
)}
{info.type === 'remote' && (
<div className={`mt-2 flex justify-end`}>
<small>{dayjs(info.updated).fromNow()}</small>
</div>
)}
</div>
</CardBody>
</Card>
</div>
Expand Down
22 changes: 21 additions & 1 deletion src/renderer/src/components/profiles/edit-file-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Button } from
import React, { useEffect, useState } from 'react'
import { BaseEditor } from '../base/base-editor'
import { getProfileStr, setProfileStr } from '@renderer/utils/ipc'
import { useNavigate } from 'react-router-dom'
interface Props {
id: string
onClose: () => void
}
const EditFileModal: React.FC<Props> = (props) => {
const { id, onClose } = props
const [currData, setCurrData] = useState('')
const navigate = useNavigate()

const getContent = async (): Promise<void> => {
setCurrData(await getProfileStr(id))
Expand All @@ -28,7 +30,25 @@ const EditFileModal: React.FC<Props> = (props) => {
scrollBehavior="inside"
>
<ModalContent className="h-full w-[calc(100%-100px)]">
<ModalHeader className="flex">编辑订阅</ModalHeader>
<ModalHeader className="flex">
<div className="flex justify-start">
<div className="flex items-center">编辑订阅</div>
<small className="ml-2 text-default-500">
注意:此处编辑配置更新订阅后会还原,如需要自定义配置请使用
<Button
size="sm"
color="primary"
variant="light"
onPress={() => {
navigate('/override')
}}
>
覆写
</Button>
功能
</small>
</div>
</ModalHeader>
<ModalBody className="h-full">
<BaseEditor language="yaml" value={currData} onChange={(value) => setCurrData(value)} />
</ModalBody>
Expand Down
9 changes: 7 additions & 2 deletions src/renderer/src/components/profiles/edit-info-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,19 @@ const EditInfoModal: React.FC<Props> = (props) => {
</SettingItem>
</>
)}
<SettingItem title="覆写脚本">
<SettingItem title="覆写">
<Select
className="w-[200px]"
size="sm"
selectionMode="multiple"
selectedKeys={new Set(values.override || [])}
onSelectionChange={(v) => {
setValues({ ...values, override: Array.from(v).map((i) => i.toString()) })
setValues({
...values,
override: Array.from(v)
.map((i) => i.toString())
.filter((i) => overrideItems.find((t) => t.id === i))
})
}}
>
{overrideItems.map((i) => (
Expand Down
5 changes: 4 additions & 1 deletion src/renderer/src/pages/dns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ const DNS: React.FC = () => {
'use-system-hosts': useSystemHosts = false,
'respect-rules': respectRules = false,
nameserver = ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
'proxy-server-nameserver': proxyServerNameserver = ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
'proxy-server-nameserver': proxyServerNameserver = [
'https://doh.pub/dns-query',
'https://dns.alidns.com/dns-query'
]
} = dns || {}

const [values, setValues] = useState({
Expand Down
27 changes: 21 additions & 6 deletions src/renderer/src/pages/override.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ const Override: React.FC = () => {
const handleImport = async (): Promise<void> => {
setImporting(true)
try {
await addOverrideItem({ name: '', type: 'remote', url })
await addOverrideItem({
name: '',
type: 'remote',
url,
ext: url.endsWith('.js') ? 'js' : 'yaml'
})
} finally {
setImporting(false)
}
Expand Down Expand Up @@ -71,10 +76,15 @@ const Override: React.FC = () => {
event.stopPropagation()
if (event.dataTransfer?.files) {
const file = event.dataTransfer.files[0]
if (file.name.endsWith('.js')) {
if (file.name.endsWith('.js') || file.name.endsWith('.yaml')) {
const content = await readTextFile(file.path)
try {
await addOverrideItem({ name: file.name, type: 'local', file: content })
await addOverrideItem({
name: file.name,
type: 'local',
file: content,
ext: file.name.endsWith('.js') ? 'js' : 'yaml'
})
} finally {
setFileOver(false)
}
Expand All @@ -96,7 +106,7 @@ const Override: React.FC = () => {
}, [items])

return (
<BasePage ref={pageRef} title="覆写脚本">
<BasePage ref={pageRef} title="覆写">
<div className="sticky top-[48px] z-40 backdrop-blur bg-background/40 flex p-2">
<Input
variant="bordered"
Expand Down Expand Up @@ -133,11 +143,16 @@ const Override: React.FC = () => {
color="primary"
className="ml-2"
onPress={() => {
getFilePath(['js']).then(async (files) => {
getFilePath(['js', 'yaml']).then(async (files) => {
if (files?.length) {
const content = await readTextFile(files[0])
const fileName = files[0].split('/').pop()?.split('\\').pop()
await addOverrideItem({ name: fileName, type: 'local', file: content })
await addOverrideItem({
name: fileName,
type: 'local',
file: content,
ext: fileName?.endsWith('.js') ? 'js' : 'yaml'
})
}
})
}}
Expand Down
8 changes: 4 additions & 4 deletions src/renderer/src/utils/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,12 @@ export async function updateOverrideItem(item: IOverrideItem): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('updateOverrideItem', item))
}

export async function getOverride(id: string): Promise<string> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('getOverride', id))
export async function getOverride(id: string, ext: 'js' | 'yaml'): Promise<string> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('getOverride', id, ext))
}

export async function setOverride(id: string, str: string): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('setOverride', id, str))
export async function setOverride(id: string, ext: 'js' | 'yaml', str: string): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('setOverride', id, ext, str))
}

export async function restartCore(): Promise<void> {
Expand Down
1 change: 1 addition & 0 deletions src/shared/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ interface IProfileConfig {
interface IOverrideItem {
id: string
type: 'remote' | 'local'
ext: 'js' | 'yaml'
name: string
updated: number
url?: string
Expand Down

0 comments on commit a464666

Please sign in to comment.