diff --git a/src/components/connection/connection-item.tsx b/src/components/connection/connection-item.tsx index 7f7e823..be2ea48 100644 --- a/src/components/connection/connection-item.tsx +++ b/src/components/connection/connection-item.tsx @@ -23,7 +23,7 @@ const Tag = styled("span")(({ theme }) => ({ })); interface Props { - value: ApiType.ConnectionsItem; + value: IConnectionsItem; } const ConnectionItem = (props: Props) => { diff --git a/src/components/connection/connection-table.tsx b/src/components/connection/connection-table.tsx index 2111c81..35dfdd6 100644 --- a/src/components/connection/connection-table.tsx +++ b/src/components/connection/connection-table.tsx @@ -4,7 +4,7 @@ import { DataGrid, GridColDef } from "@mui/x-data-grid"; import parseTraffic from "@/utils/parse-traffic"; interface Props { - connections: ApiType.ConnectionsItem[]; + connections: IConnectionsItem[]; } const ConnectionTable = (props: Props) => { diff --git a/src/components/layout/layout-traffic.tsx b/src/components/layout/layout-traffic.tsx index c7247db..b122d21 100644 --- a/src/components/layout/layout-traffic.tsx +++ b/src/components/layout/layout-traffic.tsx @@ -45,7 +45,7 @@ const LayoutTraffic = () => { ws = new WebSocket(`ws://${server}/traffic?token=${secret}`); ws.addEventListener("message", (event) => { - const data = JSON.parse(event.data) as ApiType.TrafficItem; + const data = JSON.parse(event.data) as ITrafficItem; trafficRef.current?.appendData(data); setTraffic(data); }); diff --git a/src/components/layout/use-log-setup.ts b/src/components/layout/use-log-setup.ts index efd372f..a563393 100644 --- a/src/components/layout/use-log-setup.ts +++ b/src/components/layout/use-log-setup.ts @@ -21,7 +21,7 @@ export default function useLogSetup() { getClashLogs().then(setLogData); const handler = (event: MessageEvent) => { - const data = JSON.parse(event.data) as ApiType.LogItem; + const data = JSON.parse(event.data) as ILogItem; const time = dayjs().format("MM-DD HH:mm:ss"); setLogData((l) => { if (l.length >= MAX_LOG_NUM) l.shift(); diff --git a/src/components/log/log-item.tsx b/src/components/log/log-item.tsx index fff9729..c1086f6 100644 --- a/src/components/log/log-item.tsx +++ b/src/components/log/log-item.tsx @@ -20,7 +20,7 @@ const Item = styled(Box)(({ theme }) => ({ })); interface Props { - value: ApiType.LogItem; + value: ILogItem; } const LogItem = (props: Props) => { diff --git a/src/components/profile/enhanced.tsx b/src/components/profile/enhanced.tsx index 3c38913..cb5ec60 100644 --- a/src/components/profile/enhanced.tsx +++ b/src/components/profile/enhanced.tsx @@ -14,7 +14,7 @@ import ProfileMore from "./profile-more"; import Notice from "../base/base-notice"; interface Props { - items: CmdType.ProfileItem[]; + items: IProfileItem[]; chain: string[]; } diff --git a/src/components/profile/info-editor.tsx b/src/components/profile/info-editor.tsx index 4044dba..950943e 100644 --- a/src/components/profile/info-editor.tsx +++ b/src/components/profile/info-editor.tsx @@ -21,7 +21,7 @@ import Notice from "../base/base-notice"; interface Props { open: boolean; - itemData: CmdType.ProfileItem; + itemData: IProfileItem; onClose: () => void; } diff --git a/src/components/profile/profile-item.tsx b/src/components/profile/profile-item.tsx index d29c969..c721d77 100644 --- a/src/components/profile/profile-item.tsx +++ b/src/components/profile/profile-item.tsx @@ -29,7 +29,7 @@ const round = keyframes` interface Props { selected: boolean; - itemData: CmdType.ProfileItem; + itemData: IProfileItem; onSelect: (force: boolean) => void; } @@ -117,7 +117,7 @@ const ProfileItem = (props: Props) => { setAnchorEl(null); setLoadingCache((cache) => ({ ...cache, [itemData.uid]: true })); - const option: Partial = {}; + const option: Partial = {}; if (type === 0) { option.with_proxy = false; diff --git a/src/components/profile/profile-more.tsx b/src/components/profile/profile-more.tsx index 328962e..e8cfba2 100644 --- a/src/components/profile/profile-more.tsx +++ b/src/components/profile/profile-more.tsx @@ -21,7 +21,7 @@ import Notice from "../base/base-notice"; interface Props { selected: boolean; - itemData: CmdType.ProfileItem; + itemData: IProfileItem; enableNum: number; logInfo?: [string, string][]; onEnable: () => void; diff --git a/src/components/proxy/proxy-global.tsx b/src/components/proxy/proxy-global.tsx index d741fed..58651d5 100644 --- a/src/components/proxy/proxy-global.tsx +++ b/src/components/proxy/proxy-global.tsx @@ -13,7 +13,7 @@ import ProxyItem from "./proxy-item"; interface Props { groupName: string; curProxy?: string; - proxies: ApiType.ProxyItem[]; + proxies: IProxyItem[]; } // this component will be used for DIRECT/GLOBAL diff --git a/src/components/proxy/proxy-group.tsx b/src/components/proxy/proxy-group.tsx index d25e395..827359f 100644 --- a/src/components/proxy/proxy-group.tsx +++ b/src/components/proxy/proxy-group.tsx @@ -30,7 +30,7 @@ import ProxyHead from "./proxy-head"; import ProxyItem from "./proxy-item"; interface Props { - group: ApiType.ProxyGroupItem; + group: IProxyGroupItem; } const ProxyGroup = ({ group }: Props) => { diff --git a/src/components/proxy/proxy-item.tsx b/src/components/proxy/proxy-item.tsx index 14ebbe8..5dbdb31 100644 --- a/src/components/proxy/proxy-item.tsx +++ b/src/components/proxy/proxy-item.tsx @@ -17,7 +17,7 @@ import BaseLoading from "../base/base-loading"; interface Props { groupName: string; - proxy: ApiType.ProxyItem; + proxy: IProxyItem; selected: boolean; showType?: boolean; sx?: SxProps; diff --git a/src/components/proxy/use-filter-sort.ts b/src/components/proxy/use-filter-sort.ts index 2a0ce70..c5c3cba 100644 --- a/src/components/proxy/use-filter-sort.ts +++ b/src/components/proxy/use-filter-sort.ts @@ -5,7 +5,7 @@ import delayManager from "@/services/delay"; export type ProxySortType = 0 | 1 | 2; export default function useFilterSort( - proxies: ApiType.ProxyItem[], + proxies: IProxyItem[], groupName: string, filterText: string, sortType: ProxySortType @@ -47,7 +47,7 @@ const regex2 = /type=(.*)/i; * according to the regular conditions */ function filterProxies( - proxies: ApiType.ProxyItem[], + proxies: IProxyItem[], groupName: string, filterText: string ) { @@ -87,7 +87,7 @@ function filterProxies( * sort the proxy */ function sortProxies( - proxies: ApiType.ProxyItem[], + proxies: IProxyItem[], groupName: string, sortType: ProxySortType ) { diff --git a/src/components/rule/rule-item.tsx b/src/components/rule/rule-item.tsx index b663e86..6e01e06 100644 --- a/src/components/rule/rule-item.tsx +++ b/src/components/rule/rule-item.tsx @@ -19,7 +19,7 @@ const COLOR = [ interface Props { index: number; - value: ApiType.RuleItem; + value: IRuleItem; } const parseColor = (text: string) => { diff --git a/src/components/setting/mods/sysproxy-viewer.tsx b/src/components/setting/mods/sysproxy-viewer.tsx index ec7939e..c442ef4 100644 --- a/src/components/setting/mods/sysproxy-viewer.tsx +++ b/src/components/setting/mods/sysproxy-viewer.tsx @@ -89,7 +89,7 @@ const SysproxyViewer = ({ handler }: Props) => { return; } - const patch: Partial = {}; + const patch: Partial = {}; if (value.guard !== enable_proxy_guard) { patch.enable_proxy_guard = value.guard; diff --git a/src/components/setting/mods/theme-mode-switch.tsx b/src/components/setting/mods/theme-mode-switch.tsx index c8ee8af..595dd6a 100644 --- a/src/components/setting/mods/theme-mode-switch.tsx +++ b/src/components/setting/mods/theme-mode-switch.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { Button, ButtonGroup } from "@mui/material"; -type ThemeValue = CmdType.VergeConfig["theme_mode"]; +type ThemeValue = IVergeConfig["theme_mode"]; interface Props { value?: ThemeValue; diff --git a/src/components/setting/setting-clash.tsx b/src/components/setting/setting-clash.tsx index fdc7a38..06934f1 100644 --- a/src/components/setting/setting-clash.tsx +++ b/src/components/setting/setting-clash.tsx @@ -46,10 +46,10 @@ const SettingClash = ({ onError }: Props) => { const controllerHandler = useModalHandler(); const onSwitchFormat = (_e: any, value: boolean) => value; - const onChangeData = (patch: Partial) => { + const onChangeData = (patch: Partial) => { mutateClash((old) => ({ ...(old! || {}), ...patch }), false); }; - const onUpdateData = async (patch: Partial) => { + const onUpdateData = async (patch: Partial) => { await updateConfigs(patch); await patchClashConfig(patch); }; diff --git a/src/components/setting/setting-system.tsx b/src/components/setting/setting-system.tsx index c086645..ee0dc6f 100644 --- a/src/components/setting/setting-system.tsx +++ b/src/components/setting/setting-system.tsx @@ -46,7 +46,7 @@ const SettingSystem = ({ onError }: Props) => { } = vergeConfig ?? {}; const onSwitchFormat = (_e: any, value: boolean) => value; - const onChangeData = (patch: Partial) => { + const onChangeData = (patch: Partial) => { mutateVerge({ ...vergeConfig, ...patch }, false); }; diff --git a/src/components/setting/setting-verge.tsx b/src/components/setting/setting-verge.tsx index ad05cf7..7bfa416 100644 --- a/src/components/setting/setting-verge.tsx +++ b/src/components/setting/setting-verge.tsx @@ -42,7 +42,7 @@ const SettingVerge = ({ onError }: Props) => { const [configOpen, setConfigOpen] = useState(false); const onSwitchFormat = (_e: any, value: boolean) => value; - const onChangeData = (patch: Partial) => { + const onChangeData = (patch: Partial) => { mutateVerge({ ...vergeConfig, ...patch }, false); }; diff --git a/src/hooks/use-verge-config.ts b/src/hooks/use-verge-config.ts index 0de7a80..42eea7f 100644 --- a/src/hooks/use-verge-config.ts +++ b/src/hooks/use-verge-config.ts @@ -4,7 +4,7 @@ import { getVergeConfig, patchVergeConfig } from "@/services/cmds"; export const useVergeConfig = () => { const { data, mutate } = useSWR("getVergeConfig", getVergeConfig); - const patchVerge = async (value: Partial) => { + const patchVerge = async (value: Partial) => { await patchVergeConfig(value); mutate(); }; diff --git a/src/pages/connections.tsx b/src/pages/connections.tsx index 79ba71f..059bd63 100644 --- a/src/pages/connections.tsx +++ b/src/pages/connections.tsx @@ -22,14 +22,14 @@ import ConnectionTable from "@/components/connection/connection-table"; const initConn = { uploadTotal: 0, downloadTotal: 0, connections: [] }; -type OrderFunc = (list: ApiType.ConnectionsItem[]) => ApiType.ConnectionsItem[]; +type OrderFunc = (list: IConnectionsItem[]) => IConnectionsItem[]; const ConnectionsPage = () => { const { t, i18n } = useTranslation(); const [filterText, setFilterText] = useState(""); const [curOrderOpt, setOrderOpt] = useState("Default"); - const [connData, setConnData] = useState(initConn); + const [connData, setConnData] = useState(initConn); const [setting, setSetting] = useRecoilState(atomConnectionSetting); @@ -60,7 +60,7 @@ const ConnectionsPage = () => { ws = new WebSocket(`ws://${server}/connections?token=${secret}`); ws.addEventListener("message", (event) => { - const data = JSON.parse(event.data) as ApiType.Connections; + const data = JSON.parse(event.data) as IConnections; // 与前一次connections的展示顺序尽量保持一致 setConnData((old) => { diff --git a/src/services/api.ts b/src/services/api.ts index 625f96e..8ff75b7 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -50,11 +50,11 @@ export async function getVersion() { /// Get current base configs export async function getClashConfig() { const instance = await getAxios(); - return instance.get("/configs") as Promise; + return instance.get("/configs") as Promise; } /// Update current configs -export async function updateConfigs(config: Partial) { +export async function updateConfigs(config: Partial) { const instance = await getAxios(); return instance.patch("/configs", config); } @@ -63,7 +63,7 @@ export async function updateConfigs(config: Partial) { export async function getRules() { const instance = await getAxios(); const response = await instance.get("/rules"); - return response?.rules as ApiType.RuleItem[]; + return response?.rules as IRuleItem[]; } /// Get Proxy delay @@ -90,7 +90,7 @@ export async function updateProxy(group: string, proxy: string) { async function getProxiesInner() { const instance = await getAxios(); const response = await instance.get("/proxies"); - return (response?.proxies || {}) as Record; + return (response?.proxies || {}) as Record; } /// Get the Proxy information @@ -116,7 +116,7 @@ export async function getProxies() { const { GLOBAL: global, DIRECT: direct, REJECT: reject } = proxyRecord; - let groups: ApiType.ProxyGroupItem[] = []; + let groups: IProxyGroupItem[] = []; if (global?.all) { groups = global.all @@ -142,7 +142,7 @@ export async function getProxies() { ) ); - const _global: ApiType.ProxyGroupItem = { + const _global: IProxyGroupItem = { ...global, all: global?.all?.map((item) => generateItem(item)) || [], }; @@ -155,10 +155,7 @@ export async function getProviders() { const instance = await getAxios(); const response = await instance.get("/providers/proxies"); - const providers = (response.providers || {}) as Record< - string, - ApiType.ProviderItem - >; + const providers = (response.providers || {}) as Record; return Object.fromEntries( Object.entries(providers).filter(([key, item]) => { @@ -179,7 +176,7 @@ export async function providerHealthCheck(name: string) { export async function getConnections() { const instance = await getAxios(); const result = await instance.get("/connections"); - return result as any as ApiType.Connections; + return result as any as IConnections; } // Close specific connection diff --git a/src/services/cmds.ts b/src/services/cmds.ts index 1344134..168378e 100644 --- a/src/services/cmds.ts +++ b/src/services/cmds.ts @@ -21,23 +21,23 @@ export async function getClashLogs() { } return null; }) - .filter(Boolean) as ApiType.LogItem[]; + .filter(Boolean) as ILogItem[]; } export async function getProfiles() { - return invoke("get_profiles"); + return invoke("get_profiles"); } export async function enhanceProfiles() { return invoke("enhance_profiles"); } -export async function patchProfilesConfig(profiles: CmdType.ProfilesConfig) { +export async function patchProfilesConfig(profiles: IProfilesConfig) { return invoke("patch_profiles_config", { profiles }); } export async function createProfile( - item: Partial, + item: Partial, fileData?: string | null ) { return invoke("create_profile", { item, fileData }); @@ -62,10 +62,7 @@ export async function importProfile(url: string) { }); } -export async function updateProfile( - index: string, - option?: CmdType.ProfileOption -) { +export async function updateProfile(index: string, option?: IProfileOption) { return invoke("update_profile", { index, option }); } @@ -75,13 +72,13 @@ export async function deleteProfile(index: string) { export async function patchProfile( index: string, - profile: Partial + profile: Partial ) { return invoke("patch_profile", { index, profile }); } export async function getClashInfo() { - return invoke("get_clash_info"); + return invoke("get_clash_info"); } export async function getRuntimeConfig() { @@ -100,15 +97,15 @@ export async function getRuntimeLogs() { return invoke>("get_runtime_logs"); } -export async function patchClashConfig(payload: Partial) { +export async function patchClashConfig(payload: Partial) { return invoke("patch_clash_config", { payload }); } export async function getVergeConfig() { - return invoke("get_verge_config"); + return invoke("get_verge_config"); } -export async function patchVergeConfig(payload: CmdType.VergeConfig) { +export async function patchVergeConfig(payload: IVergeConfig) { return invoke("patch_verge_config", { payload }); } diff --git a/src/services/delay.ts b/src/services/delay.ts index 502b5e1..3086808 100644 --- a/src/services/delay.ts +++ b/src/services/delay.ts @@ -56,7 +56,7 @@ class DelayManager { } /// 暂时修复provider的节点延迟排序的问题 - getDelayFix(proxy: ApiType.ProxyItem, group: string) { + getDelayFix(proxy: IProxyItem, group: string) { if (!proxy.provider) return this.getDelay(proxy.name, group); if (proxy.history.length > 0) { diff --git a/src/services/states.ts b/src/services/states.ts index 48b66e8..8ef38c2 100644 --- a/src/services/states.ts +++ b/src/services/states.ts @@ -10,7 +10,7 @@ export const atomClashPort = atom({ default: 0, }); -export const atomLogData = atom({ +export const atomLogData = atom({ key: "atomLogData", default: [], }); @@ -50,10 +50,10 @@ export const atomConnectionSetting = atom({ try { const value = localStorage.getItem(key); - const data = value == null ? { layout: "list" } : JSON.parse(value); + const data = value == null ? { layout: "table" } : JSON.parse(value); setSelf(data); } catch { - setSelf({ layout: "list" }); + setSelf({ layout: "table" }); } onSet((newValue) => { diff --git a/src/services/types.d.ts b/src/services/types.d.ts index e84a281..aea3938 100644 --- a/src/services/types.d.ts +++ b/src/services/types.d.ts @@ -1,243 +1,240 @@ /** * Some interface for clash api */ -declare namespace ApiType { - interface ConfigData { - port: number; - mode: string; - ipv6: boolean; - "socket-port": number; - "allow-lan": boolean; - "log-level": string; - "mixed-port": number; - "redir-port": number; - "socks-port": number; - "tproxy-port": number; - "external-controller": string; - secret: string; - } +interface IConfigData { + port: number; + mode: string; + ipv6: boolean; + "socket-port": number; + "allow-lan": boolean; + "log-level": string; + "mixed-port": number; + "redir-port": number; + "socks-port": number; + "tproxy-port": number; + "external-controller": string; + secret: string; +} - interface RuleItem { +interface IRuleItem { + type: string; + payload: string; + proxy: string; +} + +interface IProxyItem { + name: string; + type: string; + udp: boolean; + history: { + time: string; + delay: number; + }[]; + all?: string[]; + now?: string; + provider?: string; // 记录是否来自provider +} + +type IProxyGroupItem = Omit & { + all: IProxyItem[]; +}; + +interface IProviderItem { + name: string; + type: string; + proxies: IProxyItem[]; + updatedAt: string; + vehicleType: string; +} + +interface ITrafficItem { + up: number; + down: number; +} + +interface ILogItem { + type: string; + time?: string; + payload: string; +} + +interface IConnectionsItem { + id: string; + metadata: { + network: string; type: string; - payload: string; - proxy: string; - } - - interface ProxyItem { - name: string; - type: string; - udp: boolean; - history: { - time: string; - delay: number; - }[]; - all?: string[]; - now?: string; - provider?: string; // 记录是否来自provider - } - - type ProxyGroupItem = Omit & { - all: ProxyItem[]; + host: string; + sourceIP: string; + sourcePort: string; + destinationPort: string; + destinationIP?: string; + process?: string; + processPath?: string; }; + upload: number; + download: number; + start: string; + chains: string[]; + rule: string; + rulePayload: string; + curUpload?: number; // upload speed, calculate at runtime + curDownload?: number; // download speed, calculate at runtime +} - interface ProviderItem { - name: string; - type: string; - proxies: ProxyItem[]; - updatedAt: string; - vehicleType: string; - } - - interface TrafficItem { - up: number; - down: number; - } - - interface LogItem { - type: string; - time?: string; - payload: string; - } - - interface ConnectionsItem { - id: string; - metadata: { - network: string; - type: string; - host: string; - sourceIP: string; - sourcePort: string; - destinationPort: string; - destinationIP?: string; - process?: string; - processPath?: string; - }; - upload: number; - download: number; - start: string; - chains: string[]; - rule: string; - rulePayload: string; - curUpload?: number; // upload speed, calculate at runtime - curDownload?: number; // download speed, calculate at runtime - } - - interface Connections { - downloadTotal: number; - uploadTotal: number; - connections: ConnectionsItem[]; - } +interface IConnections { + downloadTotal: number; + uploadTotal: number; + connections: IConnectionsItem[]; } /** * Some interface for command */ -declare namespace CmdType { - type ProfileType = "local" | "remote" | "merge" | "script"; - interface ClashInfo { - status: string; - port?: string; // clash mixed port - server?: string; // external-controller - secret?: string; - } +type IProfileType = "local" | "remote" | "merge" | "script"; - interface ProfileItem { - uid: string; - type?: ProfileType | string; - name?: string; - desc?: string; - file?: string; - url?: string; - updated?: number; - selected?: { - name?: string; - now?: string; - }[]; - extra?: { - upload: number; - download: number; - total: number; - expire: number; - }; - option?: ProfileOption; - } - - interface ProfileOption { - user_agent?: string; - with_proxy?: boolean; - self_proxy?: boolean; - update_interval?: number; - } - - interface ProfilesConfig { - current?: string; - chain?: string[]; - valid?: string[]; - items?: ProfileItem[]; - } - - interface VergeConfig { - language?: string; - clash_core?: string; - theme_mode?: "light" | "dark" | "system"; - theme_blur?: boolean; - traffic_graph?: boolean; - enable_tun_mode?: boolean; - enable_auto_launch?: boolean; - enable_service_mode?: boolean; - enable_silent_start?: boolean; - enable_system_proxy?: boolean; - enable_proxy_guard?: boolean; - proxy_guard_duration?: number; - system_proxy_bypass?: string; - web_ui_list?: string[]; - hotkeys?: string[]; - theme_setting?: { - primary_color?: string; - secondary_color?: string; - primary_text?: string; - secondary_text?: string; - info_color?: string; - error_color?: string; - warning_color?: string; - success_color?: string; - font_family?: string; - css_injection?: string; - }; - auto_close_connection?: boolean; - default_latency_test?: string; - } - - type ClashConfigValue = any; - - interface ProfileMerge { - // clash config fields (default supports) - rules?: ClashConfigValue; - proxies?: ClashConfigValue; - "proxy-groups"?: ClashConfigValue; - "proxy-providers"?: ClashConfigValue; - "rule-providers"?: ClashConfigValue; - // clash config fields (use flag) - tun?: ClashConfigValue; - dns?: ClashConfigValue; - hosts?: ClashConfigValue; - script?: ClashConfigValue; - profile?: ClashConfigValue; - payload?: ClashConfigValue; - "interface-name"?: ClashConfigValue; - "routing-mark"?: ClashConfigValue; - // functional fields - use?: string[]; - "prepend-rules"?: any[]; - "append-rules"?: any[]; - "prepend-proxies"?: any[]; - "append-proxies"?: any[]; - "prepend-proxy-groups"?: any[]; - "append-proxy-groups"?: any[]; - // fix - ebpf?: any; - experimental?: any; - iptables?: any; - sniffer?: any; - authentication?: any; - "bind-address"?: any; - "external-ui"?: any; - "auto-redir"?: any; - "socks-port"?: any; - "redir-port"?: any; - "tproxy-port"?: any; - "geodata-mode"?: any; - "tcp-concurrent"?: any; - } - - // partial of the clash config - type ProfileData = Partial<{ - rules: any[]; - proxies: any[]; - "proxy-groups": any[]; - "proxy-providers": any[]; - "rule-providers": any[]; - - [k: string]: any; - }>; - - interface ChainItem { - item: ProfileItem; - merge?: ProfileMerge; - script?: string; - } - - interface EnhancedPayload { - chain: ChainItem[]; - valid: string[]; - current: ProfileData; - callback: string; - } - - interface EnhancedResult { - data: ProfileData; - status: string; - error?: string; - } +interface IClashInfo { + status: string; + port?: string; // clash mixed port + server?: string; // external-controller + secret?: string; +} + +interface IProfileItem { + uid: string; + type?: IProfileType | string; + name?: string; + desc?: string; + file?: string; + url?: string; + updated?: number; + selected?: { + name?: string; + now?: string; + }[]; + extra?: { + upload: number; + download: number; + total: number; + expire: number; + }; + option?: IProfileOption; +} + +interface IProfileOption { + user_agent?: string; + with_proxy?: boolean; + self_proxy?: boolean; + update_interval?: number; +} + +interface IProfilesConfig { + current?: string; + chain?: string[]; + valid?: string[]; + items?: IProfileItem[]; +} + +interface IVergeConfig { + language?: string; + clash_core?: string; + theme_mode?: "light" | "dark" | "system"; + theme_blur?: boolean; + traffic_graph?: boolean; + enable_tun_mode?: boolean; + enable_auto_launch?: boolean; + enable_service_mode?: boolean; + enable_silent_start?: boolean; + enable_system_proxy?: boolean; + enable_proxy_guard?: boolean; + proxy_guard_duration?: number; + system_proxy_bypass?: string; + web_ui_list?: string[]; + hotkeys?: string[]; + theme_setting?: { + primary_color?: string; + secondary_color?: string; + primary_text?: string; + secondary_text?: string; + info_color?: string; + error_color?: string; + warning_color?: string; + success_color?: string; + font_family?: string; + css_injection?: string; + }; + auto_close_connection?: boolean; + default_latency_test?: string; +} + +type IClashConfigValue = any; + +interface IProfileMerge { + // clash config fields (default supports) + rules?: IClashConfigValue; + proxies?: IClashConfigValue; + "proxy-groups"?: IClashConfigValue; + "proxy-providers"?: IClashConfigValue; + "rule-providers"?: IClashConfigValue; + // clash config fields (use flag) + tun?: IClashConfigValue; + dns?: IClashConfigValue; + hosts?: IClashConfigValue; + script?: IClashConfigValue; + profile?: IClashConfigValue; + payload?: IClashConfigValue; + "interface-name"?: IClashConfigValue; + "routing-mark"?: IClashConfigValue; + // functional fields + use?: string[]; + "prepend-rules"?: any[]; + "append-rules"?: any[]; + "prepend-proxies"?: any[]; + "append-proxies"?: any[]; + "prepend-proxy-groups"?: any[]; + "append-proxy-groups"?: any[]; + // fix + ebpf?: any; + experimental?: any; + iptables?: any; + sniffer?: any; + authentication?: any; + "bind-address"?: any; + "external-ui"?: any; + "auto-redir"?: any; + "socks-port"?: any; + "redir-port"?: any; + "tproxy-port"?: any; + "geodata-mode"?: any; + "tcp-concurrent"?: any; +} + +// partial of the clash config +type IProfileData = Partial<{ + rules: any[]; + proxies: any[]; + "proxy-groups": any[]; + "proxy-providers": any[]; + "rule-providers": any[]; + + [k: string]: any; +}>; + +interface IChainItem { + item: IProfileItem; + merge?: IProfileMerge; + script?: string; +} + +interface IEnhancedPayload { + chain: IChainItem[]; + valid: string[]; + current: IProfileData; + callback: string; +} + +interface IEnhancedResult { + data: IProfileData; + status: string; + error?: string; }