refactor(backend): specta ipc bindings (#8195)

* refactor(ipc): generate bindings with Specta

* fix(profile): project IPC inputs to consumed fields

* fix(events): remove unused refresh payloads

* fix(webdav): return only consumed backup metadata

* fix(network): trim unused interface metadata

* fix(sysinfo): return only displayed system fields

* chore(knip): check generated runtime exports

* fix(proxy): confirm runtime chain updates before UI changes

* fix(clipboard): propagate proxy environment copy failures

* refactor(dns): remove ignored runtime patch

* refactor(core): trim unused upgrade response fields

* refactor(ipc): avoid redundant response copies

* refactor(proxy): clarify automatic proxy query naming

* chore(tests): remove added IPC regression tests

* refactor(ipc): enforce typed command boundaries

* chore(contract): check generated bindings before push

* refactor(ipc): remove unused proxy liveness payloads
This commit is contained in:
Tunglies
2026-10-12 06:16:05 +00:00
committed by GitHub
parent 27efaf34f4
commit 6e08a77a84
89 changed files with 2714 additions and 1354 deletions
+41 -36
View File
@@ -1,44 +1,57 @@
use super::CmdResult;
use crate::{cmd::StringifyErr as _, config::Config, core::CoreManager, utils::yaml_emitter};
use anyhow::{Context as _, anyhow};
use clash_verge_logging::{Type, logging};
use serde_yaml_ng::Mapping;
use smartstring::alias::String;
use std::collections::HashMap;
#[tauri::command]
pub async fn get_runtime_config() -> CmdResult<Option<Mapping>> {
Ok(Config::runtime().await.latest_arc().config.clone())
#[specta::specta]
pub async fn get_runtime_config() -> CmdResult<Option<crate::ipc::YamlMapping>> {
Ok(Config::runtime()
.await
.latest_arc()
.config
.clone()
.map(crate::ipc::YamlMapping))
}
#[tauri::command]
pub async fn get_runtime_yaml() -> CmdResult<String> {
#[specta::specta]
pub async fn get_runtime_yaml() -> CmdResult<std::string::String> {
let runtime = Config::runtime().await;
let runtime = runtime.latest_arc();
let config = runtime.config.as_ref();
config
.ok_or_else(|| anyhow!("failed to parse config to yaml file"))
.and_then(|config| {
yaml_emitter::to_mihomo_config_string(config)
.context("failed to convert config to yaml")
.map(|s| s.into())
})
.and_then(|config| yaml_emitter::to_mihomo_config_string(config).context("failed to convert config to yaml"))
.stringify_err()
}
#[tauri::command]
pub async fn get_runtime_logs() -> CmdResult<HashMap<String, Vec<(String, String)>>> {
Ok(Config::runtime().await.latest_arc().chain_logs.clone())
#[specta::specta]
pub async fn get_runtime_logs() -> CmdResult<RuntimeLogs> {
Ok(RuntimeLogs(Config::runtime().await.latest_arc().chain_logs.clone()))
}
#[derive(serde::Serialize, specta::Type)]
#[serde(transparent)]
pub struct RuntimeLogs(
#[specta(type = HashMap<std::string::String, Vec<(std::string::String, std::string::String)>>)]
HashMap<String, Vec<(String, String)>>,
);
#[tauri::command]
#[specta::specta]
pub fn take_discarded_keys_notice() -> Option<std::string::String> {
crate::enhance::take_discarded_keys_notice().map(Into::into)
}
#[tauri::command]
pub fn take_discarded_keys_notice() -> Option<String> {
crate::enhance::take_discarded_keys_notice()
}
#[tauri::command]
pub async fn get_runtime_proxy_chain_config(proxy_chain_exit_node: String) -> CmdResult<String> {
#[specta::specta]
pub async fn get_runtime_proxy_chain_config(
proxy_chain_exit_node: std::string::String,
) -> CmdResult<std::string::String> {
let runtime = Config::runtime().await;
let runtime = runtime.latest_arc();
@@ -59,7 +72,7 @@ pub async fn get_runtime_proxy_chain_config(proxy_chain_exit_node: String) -> Cm
false
}
}) {
proxies_chain.push(proxy.to_owned());
proxies_chain.push(proxy);
proxy_name = proxy.get("dialer-proxy").map(|x| x.as_str());
}
@@ -68,18 +81,17 @@ pub async fn get_runtime_proxy_chain_config(proxy_chain_exit_node: String) -> Cm
.find(|proxy| proxy.get("name").map(|x| x.as_str()) == proxy_name)
&& !proxies_chain.is_empty()
{
proxies_chain.push(entry_proxy.to_owned());
proxies_chain.push(entry_proxy);
}
proxies_chain.reverse();
let mut config: HashMap<String, Vec<serde_yaml_ng::Value>> = HashMap::new();
let mut config: HashMap<String, Vec<&serde_yaml_ng::Value>> = HashMap::new();
config.insert("proxies".into(), proxies_chain);
yaml_emitter::to_mihomo_config_string(&config)
.context("YAML generation failed")
.map(|s| s.into())
.stringify_err()
} else {
Err("failed to get proxies or proxy-groups".into())
@@ -87,20 +99,13 @@ pub async fn get_runtime_proxy_chain_config(proxy_chain_exit_node: String) -> Cm
}
#[tauri::command]
pub async fn update_proxy_chain_config_in_runtime(proxy_chain_config: Option<serde_yaml_ng::Value>) -> CmdResult<()> {
match CoreManager::global()
#[specta::specta]
pub async fn update_proxy_chain_config_in_runtime(
proxy_chain_config: Option<crate::ipc::YamlValue>,
) -> CmdResult<crate::core::validate::ValidationOutcome> {
let proxy_chain_config = proxy_chain_config.map(|value| value.0);
CoreManager::global()
.update_runtime_config(|d| d.update_proxy_chain_config(proxy_chain_config))
.await
{
Ok(outcome) if outcome.is_valid() => {}
Ok(outcome) => logging!(
warn,
Type::Core,
"Failed to apply runtime proxy chain config: {}",
outcome
),
Err(err) => logging!(error, Type::Core, "Failed to apply runtime proxy chain config: {err:#}"),
}
Ok(())
.stringify_err()
}