Route all app commands through a single RPC envelope (#542)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Gregory Schier
2026-08-14 14:16:14 -07:00
committed by GitHub
co-authored by Claude Fable 5
parent 1f91cddab9
commit 23e7229e63
37 changed files with 2473 additions and 395 deletions
+1 -9
View File
@@ -1,7 +1,7 @@
use crate::PluginContextExt;
use crate::error::Result;
use std::sync::Arc;
use tauri::{AppHandle, Manager, Runtime, State, WebviewWindow, command};
use tauri::{AppHandle, Manager, Runtime, State, WebviewWindow};
use yaak_crypto::manager::EncryptionManager;
use yaak_models::models::HttpRequestHeader;
use yaak_models::queries::workspaces::default_headers;
@@ -22,7 +22,6 @@ impl<'a, R: Runtime, M: Manager<R>> EncryptionManagerExt<'a, R> for M {
}
}
#[command]
pub(crate) async fn cmd_decrypt_template<R: Runtime>(
window: WebviewWindow<R>,
template: &str,
@@ -32,7 +31,6 @@ pub(crate) async fn cmd_decrypt_template<R: Runtime>(
Ok(decrypt_secure_template_function(&encryption_manager, &plugin_context, template)?)
}
#[command]
pub(crate) async fn cmd_secure_template<R: Runtime>(
app_handle: AppHandle<R>,
window: WebviewWindow<R>,
@@ -49,7 +47,6 @@ pub(crate) async fn cmd_secure_template<R: Runtime>(
)?)
}
#[command]
pub(crate) async fn cmd_get_themes<R: Runtime>(
window: WebviewWindow<R>,
plugin_manager: State<'_, PluginManager>,
@@ -57,7 +54,6 @@ pub(crate) async fn cmd_get_themes<R: Runtime>(
Ok(plugin_manager.get_themes(&window.plugin_context()).await?)
}
#[command]
pub(crate) async fn cmd_enable_encryption<R: Runtime>(
window: WebviewWindow<R>,
workspace_id: &str,
@@ -67,7 +63,6 @@ pub(crate) async fn cmd_enable_encryption<R: Runtime>(
Ok(())
}
#[command]
pub(crate) async fn cmd_reveal_workspace_key<R: Runtime>(
window: WebviewWindow<R>,
workspace_id: &str,
@@ -75,7 +70,6 @@ pub(crate) async fn cmd_reveal_workspace_key<R: Runtime>(
Ok(window.crypto().reveal_workspace_key(workspace_id)?)
}
#[command]
pub(crate) async fn cmd_set_workspace_key<R: Runtime>(
window: WebviewWindow<R>,
workspace_id: &str,
@@ -85,7 +79,6 @@ pub(crate) async fn cmd_set_workspace_key<R: Runtime>(
Ok(())
}
#[command]
pub(crate) async fn cmd_disable_encryption<R: Runtime>(
window: WebviewWindow<R>,
workspace_id: &str,
@@ -94,7 +87,6 @@ pub(crate) async fn cmd_disable_encryption<R: Runtime>(
Ok(())
}
#[command]
pub(crate) fn cmd_default_headers() -> Vec<HttpRequestHeader> {
default_headers()
}
@@ -3,10 +3,7 @@
//! This module provides the Tauri commands for git functionality.
use crate::error::Result;
use crate::git_watcher::{GitWatchResult, watch_git_worktree_status};
use std::path::{Path, PathBuf};
use tauri::ipc::Channel;
use tauri::{AppHandle, Runtime, command};
use yaak_git::{
BranchDeleteResult, CloneResult, GitBranchInfo, GitCommit, GitFileDiff, GitRemote,
GitStatusSummary, GitWorktreeStatus, PullResult, PushResult, git_add, git_add_credential,
@@ -19,17 +16,14 @@ use yaak_git::{
// NOTE: All of these commands are async to prevent blocking work from locking up the UI
#[command]
pub async fn cmd_git_checkout(dir: &Path, branch: &str, force: bool) -> Result<String> {
Ok(git_checkout_branch(dir, branch, force).await?)
}
#[command]
pub async fn cmd_git_branch(dir: &Path, branch: &str, base: Option<&str>) -> Result<()> {
Ok(git_create_branch(dir, branch, base).await?)
}
#[command]
pub async fn cmd_git_delete_branch(
dir: &Path,
branch: &str,
@@ -38,56 +32,38 @@ pub async fn cmd_git_delete_branch(
Ok(git_delete_branch(dir, branch, force.unwrap_or(false)).await?)
}
#[command]
pub async fn cmd_git_delete_remote_branch(dir: &Path, branch: &str) -> Result<()> {
Ok(git_delete_remote_branch(dir, branch).await?)
}
#[command]
pub async fn cmd_git_merge_branch(dir: &Path, branch: &str) -> Result<()> {
Ok(git_merge_branch(dir, branch).await?)
}
#[command]
pub async fn cmd_git_rename_branch(dir: &Path, old_name: &str, new_name: &str) -> Result<()> {
Ok(git_rename_branch(dir, old_name, new_name).await?)
}
#[command]
pub async fn cmd_git_status(dir: &Path) -> Result<GitStatusSummary> {
Ok(git_status(dir)?)
}
#[command]
pub async fn cmd_git_branch_info(dir: &Path) -> Result<GitBranchInfo> {
Ok(git_branch_info(dir)?)
}
#[command]
pub async fn cmd_git_worktree_status(dir: &Path) -> Result<GitWorktreeStatus> {
Ok(git_worktree_status(dir)?)
}
#[command]
pub async fn cmd_git_watch_worktree_status<R: Runtime>(
app_handle: AppHandle<R>,
dir: &Path,
channel: Channel<GitWorktreeStatus>,
) -> Result<GitWatchResult> {
watch_git_worktree_status(app_handle, dir, channel).await
}
#[command]
pub async fn cmd_git_log(dir: &Path) -> Result<Vec<GitCommit>> {
Ok(git_log(dir)?)
}
#[command]
pub async fn cmd_git_log_for_file(dir: &Path, rela_path: PathBuf) -> Result<Vec<GitCommit>> {
Ok(git_log_for_file(dir, &rela_path)?)
}
#[command]
pub async fn cmd_git_file_diff_for_commit(
dir: &Path,
commit_oid: &str,
@@ -96,37 +72,30 @@ pub async fn cmd_git_file_diff_for_commit(
Ok(git_file_diff_for_commit(dir, commit_oid, &rela_path)?)
}
#[command]
pub async fn cmd_git_initialize(dir: &Path) -> Result<()> {
Ok(git_init(dir)?)
}
#[command]
pub async fn cmd_git_clone(url: &str, dir: &Path) -> Result<CloneResult> {
Ok(git_clone(url, dir).await?)
}
#[command]
pub async fn cmd_git_commit(dir: &Path, message: &str) -> Result<()> {
Ok(git_commit(dir, message).await?)
}
#[command]
pub async fn cmd_git_fetch_all(dir: &Path) -> Result<()> {
Ok(git_fetch_all(dir).await?)
}
#[command]
pub async fn cmd_git_push(dir: &Path) -> Result<PushResult> {
Ok(git_push(dir).await?)
}
#[command]
pub async fn cmd_git_pull(dir: &Path) -> Result<PullResult> {
Ok(git_pull(dir).await?)
}
#[command]
pub async fn cmd_git_pull_force_reset(
dir: &Path,
remote: &str,
@@ -135,12 +104,10 @@ pub async fn cmd_git_pull_force_reset(
Ok(git_pull_force_reset(dir, remote, branch).await?)
}
#[command]
pub async fn cmd_git_pull_merge(dir: &Path, remote: &str, branch: &str) -> Result<PullResult> {
Ok(git_pull_merge(dir, remote, branch).await?)
}
#[command]
pub async fn cmd_git_add(dir: &Path, rela_paths: Vec<PathBuf>) -> Result<()> {
for path in rela_paths {
git_add(dir, &path)?;
@@ -148,7 +115,6 @@ pub async fn cmd_git_add(dir: &Path, rela_paths: Vec<PathBuf>) -> Result<()> {
Ok(())
}
#[command]
pub async fn cmd_git_unstage(dir: &Path, rela_paths: Vec<PathBuf>) -> Result<()> {
for path in rela_paths {
git_unstage(dir, &path)?;
@@ -156,12 +122,10 @@ pub async fn cmd_git_unstage(dir: &Path, rela_paths: Vec<PathBuf>) -> Result<()>
Ok(())
}
#[command]
pub async fn cmd_git_reset_changes(dir: &Path) -> Result<()> {
Ok(git_reset_changes(dir).await?)
}
#[command]
pub async fn cmd_git_restore_files(dir: &Path, rela_paths: Vec<PathBuf>) -> Result<()> {
for path in rela_paths {
git_restore(dir, &path)?;
@@ -169,7 +133,6 @@ pub async fn cmd_git_restore_files(dir: &Path, rela_paths: Vec<PathBuf>) -> Resu
Ok(())
}
#[command]
pub async fn cmd_git_restore_file_from_commit(
dir: &Path,
commit_oid: &str,
@@ -178,7 +141,6 @@ pub async fn cmd_git_restore_file_from_commit(
Ok(git_restore_file_from_commit(dir, commit_oid, &rela_path)?)
}
#[command]
pub async fn cmd_git_add_credential(
remote_url: &str,
username: &str,
@@ -187,17 +149,14 @@ pub async fn cmd_git_add_credential(
Ok(git_add_credential(remote_url, username, password).await?)
}
#[command]
pub async fn cmd_git_remotes(dir: &Path) -> Result<Vec<GitRemote>> {
Ok(git_remotes(dir)?)
}
#[command]
pub async fn cmd_git_add_remote(dir: &Path, name: &str, url: &str) -> Result<GitRemote> {
Ok(git_add_remote(dir, name, url)?)
}
#[command]
pub async fn cmd_git_rm_remote(dir: &Path, name: &str) -> Result<()> {
Ok(git_rm_remote(dir, name)?)
}
+14 -15
View File
@@ -6,7 +6,6 @@ use serde::{Deserialize, Serialize};
use std::path::Path;
use std::sync::mpsc;
use std::time::Duration;
use tauri::ipc::Channel;
use tauri::{AppHandle, Listener, Runtime};
use tokio::select;
use tokio::sync::watch;
@@ -23,11 +22,15 @@ pub(crate) struct GitWatchResult {
unlisten_event: String,
}
pub(crate) async fn watch_git_worktree_status<R: Runtime>(
pub(crate) async fn watch_git_worktree_status<R, F>(
app_handle: AppHandle<R>,
dir: &Path,
channel: Channel<GitWorktreeStatus>,
) -> Result<GitWatchResult> {
on_status: F,
) -> Result<GitWatchResult>
where
R: Runtime,
F: Fn(GitWorktreeStatus) + Send + Sync + 'static,
{
let paths = git_repository_paths(dir)?;
let repo_dir = dir.to_path_buf();
let workdir = paths.workdir;
@@ -76,7 +79,7 @@ pub(crate) async fn watch_git_worktree_status<R: Runtime>(
let (cancel_tx, cancel_rx) = watch::channel(());
let mut cancel_rx = cancel_rx;
send_worktree_status(&repo_dir, &channel);
send_worktree_status(&repo_dir, &on_status);
tauri::async_runtime::spawn(async move {
let _watcher = watcher;
@@ -90,7 +93,7 @@ pub(crate) async fn watch_git_worktree_status<R: Runtime>(
&workdir,
&gitdir,
&commondir,
&channel,
&on_status,
).await;
}
_ = cancel_rx.changed() => {
@@ -119,13 +122,13 @@ async fn handle_git_watch_event(
workdir: &Path,
gitdir: &Path,
commondir: &Path,
channel: &Channel<GitWorktreeStatus>,
on_status: &impl Fn(GitWorktreeStatus),
) {
if !is_relevant_git_watch_event(event_res, repo_dir, workdir, gitdir, commondir) {
return;
}
send_worktree_status(repo_dir, channel);
send_worktree_status(repo_dir, on_status);
let settle_window = sleep(GIT_STATUS_COALESCE_WINDOW);
tokio::pin!(settle_window);
@@ -140,7 +143,7 @@ async fn handle_git_watch_event(
}
}
send_worktree_status(repo_dir, channel);
send_worktree_status(repo_dir, on_status);
}
fn is_relevant_git_watch_event(
@@ -180,13 +183,9 @@ fn is_relevant_git_watch_event(
false
}
fn send_worktree_status(repo_dir: &Path, channel: &Channel<GitWorktreeStatus>) {
fn send_worktree_status(repo_dir: &Path, on_status: &impl Fn(GitWorktreeStatus)) {
match git_worktree_status(repo_dir) {
Ok(status) => {
if let Err(e) = channel.send(status) {
warn!("Failed to send git worktree status: {:?}", e);
}
}
Ok(status) => on_status(status),
Err(e) => {
warn!("Failed to get git worktree status: {e}");
}
+9 -169
View File
@@ -77,6 +77,7 @@ mod notifications;
mod plugin_events;
mod plugins_ext;
mod render;
mod rpc_ext;
mod sync_ext;
mod updates;
mod uri_scheme;
@@ -181,9 +182,10 @@ impl<R: Runtime> PluginContextExt<R> for WebviewWindow<R> {
}
}
#[derive(serde::Serialize)]
#[derive(serde::Serialize, ts_rs::TS)]
#[serde(default, rename_all = "camelCase")]
struct AppMetaData {
#[ts(export, export_to = "gen_rpc.ts")]
pub struct AppMetaData {
is_dev: bool,
version: String,
cli_version: Option<String>,
@@ -196,7 +198,6 @@ struct AppMetaData {
feature_license: bool,
}
#[tauri::command]
async fn cmd_metadata<R: Runtime>(app_handle: AppHandle<R>) -> YaakResult<AppMetaData> {
let app_data_dir = app_handle.path().app_data_dir()?;
let app_log_dir = app_handle.path().app_log_dir()?;
@@ -236,7 +237,6 @@ async fn detect_cli_version_for_binary(program: &str) -> Option<String> {
Some(parts.next().unwrap_or(line).to_string())
}
#[tauri::command]
async fn cmd_template_tokens_to_string<R: Runtime>(
window: WebviewWindow<R>,
app_handle: AppHandle<R>,
@@ -254,7 +254,6 @@ async fn cmd_template_tokens_to_string<R: Runtime>(
Ok(new_tokens.to_string())
}
#[tauri::command]
async fn cmd_render_template<R: Runtime>(
window: WebviewWindow<R>,
app_handle: AppHandle<R>,
@@ -288,7 +287,6 @@ async fn cmd_render_template<R: Runtime>(
Ok(result)
}
#[tauri::command]
async fn cmd_send_feedback<R: Runtime>(
app_handle: AppHandle<R>,
feature: String,
@@ -298,7 +296,6 @@ async fn cmd_send_feedback<R: Runtime>(
Ok(())
}
#[tauri::command]
async fn cmd_dismiss_notification<R: Runtime>(
window: WebviewWindow<R>,
notification_id: &str,
@@ -307,7 +304,6 @@ async fn cmd_dismiss_notification<R: Runtime>(
Ok(yaak_notifier.lock().await.seen(&window, notification_id).await?)
}
#[tauri::command]
async fn cmd_grpc_reflect<R: Runtime>(
request_id: &str,
environment_id: Option<&str>,
@@ -368,7 +364,6 @@ async fn cmd_grpc_reflect<R: Runtime>(
.map_err(|e| GenericError(e.to_string()))?)
}
#[tauri::command]
async fn cmd_grpc_go<R: Runtime>(
request_id: &str,
environment_id: Option<&str>,
@@ -981,13 +976,11 @@ async fn cmd_grpc_go<R: Runtime>(
Ok(conn.id)
}
#[tauri::command]
async fn cmd_restart<R: Runtime>(app_handle: AppHandle<R>) -> YaakResult<()> {
app_handle.request_restart();
Ok(())
}
#[tauri::command]
async fn cmd_send_ephemeral_request<R: Runtime>(
mut request: HttpRequest,
environment_id: Option<&str>,
@@ -1016,12 +1009,10 @@ async fn cmd_send_ephemeral_request<R: Runtime>(
send_http_request(&window, &request, &response, environment, cookie_jar, &mut cancel_rx).await
}
#[tauri::command]
async fn cmd_format_json(text: &str) -> YaakResult<String> {
Ok(format_json(text, " "))
}
#[tauri::command]
async fn cmd_format_graphql(text: &str) -> YaakResult<String> {
match pretty_graphql::format_text(text, &Default::default()) {
Ok(formatted) => Ok(formatted),
@@ -1029,7 +1020,6 @@ async fn cmd_format_graphql(text: &str) -> YaakResult<String> {
}
}
#[tauri::command]
async fn cmd_http_response_body<R: Runtime>(
window: WebviewWindow<R>,
plugin_manager: State<'_, PluginManager>,
@@ -1063,7 +1053,6 @@ async fn cmd_http_response_body<R: Runtime>(
}
}
#[tauri::command]
async fn cmd_http_request_body<R: Runtime>(
app_handle: AppHandle<R>,
response_id: &str,
@@ -1080,7 +1069,6 @@ async fn cmd_http_request_body<R: Runtime>(
Ok(Some(body))
}
#[tauri::command]
async fn cmd_get_sse_events(file_path: &str) -> YaakResult<Vec<ServerSentEvent>> {
let body = fs::read(file_path)?;
let mut event_parser = EventParser::new();
@@ -1101,7 +1089,6 @@ async fn cmd_get_sse_events(file_path: &str) -> YaakResult<Vec<ServerSentEvent>>
Ok(events)
}
#[tauri::command]
async fn cmd_get_http_response_events<R: Runtime>(
app_handle: AppHandle<R>,
response_id: &str,
@@ -1110,7 +1097,6 @@ async fn cmd_get_http_response_events<R: Runtime>(
Ok(events)
}
#[tauri::command]
async fn cmd_import_data<R: Runtime>(
window: WebviewWindow<R>,
file_path: &str,
@@ -1118,7 +1104,6 @@ async fn cmd_import_data<R: Runtime>(
import_data(&window, file_path).await
}
#[tauri::command]
async fn cmd_http_request_actions<R: Runtime>(
window: WebviewWindow<R>,
plugin_manager: State<'_, PluginManager>,
@@ -1126,7 +1111,6 @@ async fn cmd_http_request_actions<R: Runtime>(
Ok(plugin_manager.get_http_request_actions(&window.plugin_context()).await?)
}
#[tauri::command]
async fn cmd_websocket_request_actions<R: Runtime>(
window: WebviewWindow<R>,
plugin_manager: State<'_, PluginManager>,
@@ -1134,7 +1118,6 @@ async fn cmd_websocket_request_actions<R: Runtime>(
Ok(plugin_manager.get_websocket_request_actions(&window.plugin_context()).await?)
}
#[tauri::command]
async fn cmd_call_websocket_request_action<R: Runtime>(
window: WebviewWindow<R>,
req: CallWebsocketRequestActionRequest,
@@ -1152,7 +1135,6 @@ async fn cmd_call_websocket_request_action<R: Runtime>(
.await?)
}
#[tauri::command]
async fn cmd_workspace_actions<R: Runtime>(
window: WebviewWindow<R>,
plugin_manager: State<'_, PluginManager>,
@@ -1160,7 +1142,6 @@ async fn cmd_workspace_actions<R: Runtime>(
Ok(plugin_manager.get_workspace_actions(&window.plugin_context()).await?)
}
#[tauri::command]
async fn cmd_call_workspace_action<R: Runtime>(
window: WebviewWindow<R>,
req: CallWorkspaceActionRequest,
@@ -1175,7 +1156,6 @@ async fn cmd_call_workspace_action<R: Runtime>(
.await?)
}
#[tauri::command]
async fn cmd_folder_actions<R: Runtime>(
window: WebviewWindow<R>,
plugin_manager: State<'_, PluginManager>,
@@ -1183,7 +1163,6 @@ async fn cmd_folder_actions<R: Runtime>(
Ok(plugin_manager.get_folder_actions(&window.plugin_context()).await?)
}
#[tauri::command]
async fn cmd_call_folder_action<R: Runtime>(
window: WebviewWindow<R>,
req: CallFolderActionRequest,
@@ -1198,7 +1177,6 @@ async fn cmd_call_folder_action<R: Runtime>(
.await?)
}
#[tauri::command]
async fn cmd_grpc_request_actions<R: Runtime>(
window: WebviewWindow<R>,
plugin_manager: State<'_, PluginManager>,
@@ -1206,7 +1184,6 @@ async fn cmd_grpc_request_actions<R: Runtime>(
Ok(plugin_manager.get_grpc_request_actions(&window.plugin_context()).await?)
}
#[tauri::command]
async fn cmd_template_function_summaries<R: Runtime>(
window: WebviewWindow<R>,
plugin_manager: State<'_, PluginManager>,
@@ -1215,7 +1192,6 @@ async fn cmd_template_function_summaries<R: Runtime>(
Ok(results)
}
#[tauri::command]
async fn cmd_template_function_config<R: Runtime>(
window: WebviewWindow<R>,
plugin_manager: State<'_, PluginManager>,
@@ -1229,7 +1205,6 @@ async fn cmd_template_function_config<R: Runtime>(
.await?)
}
#[tauri::command]
async fn cmd_get_http_authentication_summaries<R: Runtime>(
window: WebviewWindow<R>,
plugin_manager: State<'_, PluginManager>,
@@ -1239,7 +1214,6 @@ async fn cmd_get_http_authentication_summaries<R: Runtime>(
Ok(results.into_iter().map(|(_, a)| a).collect())
}
#[tauri::command]
async fn cmd_get_http_authentication_config<R: Runtime>(
window: WebviewWindow<R>,
app_handle: AppHandle<R>,
@@ -1294,7 +1268,6 @@ async fn cmd_get_http_authentication_config<R: Runtime>(
.await?)
}
#[tauri::command]
async fn cmd_call_http_request_action<R: Runtime>(
window: WebviewWindow<R>,
req: CallHttpRequestActionRequest,
@@ -1314,7 +1287,6 @@ async fn cmd_call_http_request_action<R: Runtime>(
.await?)
}
#[tauri::command]
async fn cmd_call_grpc_request_action<R: Runtime>(
window: WebviewWindow<R>,
req: CallGrpcRequestActionRequest,
@@ -1334,7 +1306,6 @@ async fn cmd_call_grpc_request_action<R: Runtime>(
.await?)
}
#[tauri::command]
async fn cmd_call_http_authentication_action<R: Runtime>(
window: WebviewWindow<R>,
app_handle: AppHandle<R>,
@@ -1390,7 +1361,6 @@ async fn cmd_call_http_authentication_action<R: Runtime>(
.await?)
}
#[tauri::command]
async fn cmd_curl_to_request<R: Runtime>(
window: WebviewWindow<R>,
command: &str,
@@ -1412,7 +1382,6 @@ async fn cmd_curl_to_request<R: Runtime>(
})?)
}
#[tauri::command]
async fn cmd_export_data<R: Runtime>(
app_handle: AppHandle<R>,
export_path: &str,
@@ -1439,7 +1408,6 @@ async fn cmd_export_data<R: Runtime>(
/// array of numbers, several times the size of the thing being saved. And the callers that need
/// this — values the editor collapsed — are holding base64 already, so passing it through
/// untouched means the save never decodes megabytes on the main thread.
#[tauri::command]
async fn cmd_save_base64_to_binary<R: Runtime>(
_app_handle: AppHandle<R>,
filepath: &str,
@@ -1453,7 +1421,6 @@ async fn cmd_save_base64_to_binary<R: Runtime>(
Ok(())
}
#[tauri::command]
async fn cmd_save_response<R: Runtime>(
app_handle: AppHandle<R>,
response_id: &str,
@@ -1468,7 +1435,6 @@ async fn cmd_save_response<R: Runtime>(
Ok(())
}
#[tauri::command]
async fn cmd_send_http_request<R: Runtime>(
app_handle: AppHandle<R>,
window: WebviewWindow<R>,
@@ -1540,7 +1506,6 @@ async fn cmd_send_http_request<R: Runtime>(
Ok(r)
}
#[tauri::command]
async fn cmd_reload_plugins<R: Runtime>(
app_handle: AppHandle<R>,
window: WebviewWindow<R>,
@@ -1553,7 +1518,6 @@ async fn cmd_reload_plugins<R: Runtime>(
Ok(errors)
}
#[tauri::command]
async fn cmd_plugin_info<R: Runtime>(
id: &str,
app_handle: AppHandle<R>,
@@ -1592,7 +1556,6 @@ fn fallback_plugin_metadata(directory: &str) -> PluginMetadata {
}
}
#[tauri::command]
async fn cmd_delete_all_grpc_connections<R: Runtime>(
request_id: &str,
app_handle: AppHandle<R>,
@@ -1604,7 +1567,6 @@ async fn cmd_delete_all_grpc_connections<R: Runtime>(
)?)
}
#[tauri::command]
async fn cmd_delete_send_history<R: Runtime>(
workspace_id: &str,
app_handle: AppHandle<R>,
@@ -1619,7 +1581,6 @@ async fn cmd_delete_send_history<R: Runtime>(
})?)
}
#[tauri::command]
async fn cmd_delete_all_http_responses<R: Runtime>(
request_id: &str,
app_handle: AppHandle<R>,
@@ -1632,7 +1593,6 @@ async fn cmd_delete_all_http_responses<R: Runtime>(
Ok(())
}
#[tauri::command]
async fn cmd_get_workspace_meta<R: Runtime>(
app_handle: AppHandle<R>,
workspace_id: &str,
@@ -1642,7 +1602,6 @@ async fn cmd_get_workspace_meta<R: Runtime>(
Ok(db.get_or_create_workspace_meta(&workspace.id)?)
}
#[tauri::command]
async fn cmd_new_child_window<R: Runtime>(
parent_window: WebviewWindow<R>,
url: &str,
@@ -1665,7 +1624,6 @@ async fn cmd_new_child_window<R: Runtime>(
Ok(())
}
#[tauri::command]
async fn cmd_new_main_window<R: Runtime>(app_handle: AppHandle<R>, url: &str) -> YaakResult<()> {
let use_native_titlebar = app_handle.db().get_settings().use_native_titlebar;
let initialization_script = initial_appearance_script(&app_handle);
@@ -1679,7 +1637,6 @@ async fn cmd_new_main_window<R: Runtime>(app_handle: AppHandle<R>, url: &str) ->
Ok(())
}
#[tauri::command]
async fn cmd_check_for_updates<R: Runtime>(
window: WebviewWindow<R>,
yaak_updater: State<'_, Mutex<YaakUpdater>>,
@@ -1770,6 +1727,10 @@ pub fn run() {
builder
.setup(|app| {
// The RPC command registry — every frontend command dispatches
// through this via the single `rpc` Tauri command
app.manage(rpc_ext::build_rpc_router::<TauriRuntime>());
// Initialize HTTP connection manager
app.manage(yaak_http::manager::HttpConnectionManager::new());
@@ -1844,128 +1805,7 @@ pub fn run() {
Ok(())
})
.invoke_handler(tauri::generate_handler![
cmd_call_http_authentication_action,
cmd_call_http_request_action,
cmd_call_websocket_request_action,
cmd_call_workspace_action,
cmd_call_folder_action,
cmd_call_grpc_request_action,
cmd_check_for_updates,
cmd_curl_to_request,
cmd_delete_all_grpc_connections,
cmd_delete_all_http_responses,
cmd_delete_send_history,
cmd_dismiss_notification,
cmd_export_data,
cmd_send_feedback,
cmd_http_request_body,
cmd_http_response_body,
cmd_format_json,
cmd_format_graphql,
cmd_get_http_authentication_summaries,
cmd_get_http_authentication_config,
cmd_get_sse_events,
cmd_get_http_response_events,
cmd_get_workspace_meta,
cmd_grpc_go,
cmd_grpc_reflect,
cmd_grpc_request_actions,
cmd_http_request_actions,
cmd_websocket_request_actions,
cmd_workspace_actions,
cmd_folder_actions,
cmd_import_data,
cmd_metadata,
cmd_new_child_window,
cmd_new_main_window,
cmd_plugin_info,
cmd_reload_plugins,
cmd_render_template,
cmd_restart,
cmd_save_base64_to_binary,
cmd_save_response,
cmd_send_ephemeral_request,
cmd_send_http_request,
cmd_template_function_config,
cmd_template_function_summaries,
cmd_template_tokens_to_string,
//
//
// Migrated commands
crate::commands::cmd_decrypt_template,
crate::commands::cmd_default_headers,
crate::commands::cmd_disable_encryption,
crate::commands::cmd_enable_encryption,
crate::commands::cmd_get_themes,
crate::commands::cmd_reveal_workspace_key,
crate::commands::cmd_secure_template,
crate::commands::cmd_set_workspace_key,
//
// Models commands
models_ext::models_delete,
models_ext::models_duplicate,
models_ext::models_get_graphql_introspection,
models_ext::models_get_settings,
models_ext::models_grpc_events,
models_ext::models_upsert,
models_ext::models_upsert_graphql_introspection,
models_ext::models_websocket_events,
models_ext::models_workspace_models,
//
// Sync commands
sync_ext::cmd_sync_calculate,
sync_ext::cmd_sync_calculate_fs,
sync_ext::cmd_sync_apply,
sync_ext::cmd_sync_watch,
//
// Git commands
git_ext::cmd_git_checkout,
git_ext::cmd_git_branch,
git_ext::cmd_git_delete_branch,
git_ext::cmd_git_delete_remote_branch,
git_ext::cmd_git_merge_branch,
git_ext::cmd_git_rename_branch,
git_ext::cmd_git_branch_info,
git_ext::cmd_git_status,
git_ext::cmd_git_worktree_status,
git_ext::cmd_git_watch_worktree_status,
git_ext::cmd_git_log,
git_ext::cmd_git_log_for_file,
git_ext::cmd_git_file_diff_for_commit,
git_ext::cmd_git_initialize,
git_ext::cmd_git_clone,
git_ext::cmd_git_commit,
git_ext::cmd_git_fetch_all,
git_ext::cmd_git_push,
git_ext::cmd_git_pull,
git_ext::cmd_git_pull_force_reset,
git_ext::cmd_git_pull_merge,
git_ext::cmd_git_add,
git_ext::cmd_git_unstage,
git_ext::cmd_git_reset_changes,
git_ext::cmd_git_restore_files,
git_ext::cmd_git_restore_file_from_commit,
git_ext::cmd_git_add_credential,
git_ext::cmd_git_remotes,
git_ext::cmd_git_add_remote,
git_ext::cmd_git_rm_remote,
//
// Plugin commands
plugins_ext::cmd_plugin_init_errors,
plugins_ext::cmd_plugins_install_from_directory,
plugins_ext::cmd_plugins_search,
plugins_ext::cmd_plugins_install,
plugins_ext::cmd_plugins_uninstall,
plugins_ext::cmd_plugins_updates,
plugins_ext::cmd_plugins_update_all,
//
// WebSocket commands
ws_ext::cmd_ws_delete_connections,
ws_ext::cmd_ws_send,
ws_ext::cmd_ws_close,
ws_ext::cmd_ws_connect,
])
.invoke_handler(tauri::generate_handler![rpc_ext::rpc])
.build(tauri::generate_context!())
.expect("error while running tauri application")
.run(|app_handle, event| {
@@ -140,7 +140,6 @@ impl<'a, R: Runtime, M: Manager<R>> BlobManagerExt<'a, R> for M {
// Commands for yaak-models
use tauri::WebviewWindow;
#[tauri::command]
pub(crate) fn models_upsert<R: Runtime>(
window: WebviewWindow<R>,
model: AnyModel,
@@ -171,7 +170,6 @@ pub(crate) fn models_upsert<R: Runtime>(
// Async so cascading deletes (e.g. a workspace with thousands of requests) run on a
// blocking thread instead of stalling the main thread and all other IPC.
#[tauri::command]
pub(crate) async fn models_delete<R: Runtime>(
window: WebviewWindow<R>,
model: AnyModel,
@@ -204,7 +202,6 @@ pub(crate) async fn models_delete<R: Runtime>(
.map_err(|e| GenericError(format!("Delete task failed: {e}")))?
}
#[tauri::command]
pub(crate) fn models_duplicate<R: Runtime>(
window: WebviewWindow<R>,
model_type: String,
@@ -238,7 +235,6 @@ pub(crate) fn models_duplicate<R: Runtime>(
})
}
#[tauri::command]
pub(crate) fn models_websocket_events<R: Runtime>(
app_handle: tauri::AppHandle<R>,
connection_id: &str,
@@ -246,7 +242,6 @@ pub(crate) fn models_websocket_events<R: Runtime>(
Ok(app_handle.db().list_websocket_events(connection_id)?)
}
#[tauri::command]
pub(crate) fn models_grpc_events<R: Runtime>(
app_handle: tauri::AppHandle<R>,
connection_id: &str,
@@ -254,12 +249,10 @@ pub(crate) fn models_grpc_events<R: Runtime>(
Ok(app_handle.db().list_grpc_events(connection_id)?)
}
#[tauri::command]
pub(crate) fn models_get_settings<R: Runtime>(app_handle: tauri::AppHandle<R>) -> Result<Settings> {
Ok(app_handle.db().get_settings())
}
#[tauri::command]
pub(crate) fn models_get_graphql_introspection<R: Runtime>(
app_handle: tauri::AppHandle<R>,
request_id: &str,
@@ -267,7 +260,6 @@ pub(crate) fn models_get_graphql_introspection<R: Runtime>(
Ok(app_handle.db().get_graphql_introspection(request_id))
}
#[tauri::command]
pub(crate) fn models_upsert_graphql_introspection<R: Runtime>(
app_handle: tauri::AppHandle<R>,
request_id: &str,
@@ -279,7 +271,6 @@ pub(crate) fn models_upsert_graphql_introspection<R: Runtime>(
Ok(app_handle.db().upsert_graphql_introspection(workspace_id, request_id, content, &source)?)
}
#[tauri::command]
pub(crate) async fn models_workspace_models<R: Runtime>(
window: WebviewWindow<R>,
workspace_id: Option<&str>,
@@ -16,7 +16,7 @@ use std::time::{Duration, Instant};
use tauri::path::BaseDirectory;
use tauri::plugin::{Builder, TauriPlugin};
use tauri::{
AppHandle, Emitter, Manager, RunEvent, Runtime, State, WebviewWindow, WindowEvent, command,
AppHandle, Emitter, Manager, RunEvent, Runtime, State, WebviewWindow, WindowEvent,
is_dev,
};
use tokio::sync::Mutex;
@@ -132,7 +132,6 @@ impl PluginUpdater {
// Tauri Commands
// ============================================================================
#[command]
pub async fn cmd_plugins_search<R: Runtime>(
app_handle: AppHandle<R>,
query: &str,
@@ -142,7 +141,6 @@ pub async fn cmd_plugins_search<R: Runtime>(
Ok(search_plugins(&http_client, query).await?)
}
#[command]
pub async fn cmd_plugins_install<R: Runtime>(
window: WebviewWindow<R>,
name: &str,
@@ -165,7 +163,6 @@ pub async fn cmd_plugins_install<R: Runtime>(
Ok(())
}
#[command]
pub async fn cmd_plugins_install_from_directory<R: Runtime>(
window: WebviewWindow<R>,
directory: &str,
@@ -187,7 +184,6 @@ pub async fn cmd_plugins_install_from_directory<R: Runtime>(
Ok(plugin)
}
#[command]
pub async fn cmd_plugins_uninstall<R: Runtime>(
plugin_id: &str,
window: WebviewWindow<R>,
@@ -198,14 +194,12 @@ pub async fn cmd_plugins_uninstall<R: Runtime>(
Ok(delete_and_uninstall(plugin_manager, &query_manager, &plugin_context, plugin_id).await?)
}
#[command]
pub async fn cmd_plugin_init_errors(
plugin_manager: State<'_, PluginManager>,
) -> Result<Vec<(String, String)>> {
Ok(plugin_manager.take_init_errors().await)
}
#[command]
pub async fn cmd_plugins_updates<R: Runtime>(
app_handle: AppHandle<R>,
) -> Result<PluginUpdatesResponse> {
@@ -215,7 +209,6 @@ pub async fn cmd_plugins_updates<R: Runtime>(
Ok(check_plugin_updates(&http_client, plugins).await?)
}
#[command]
pub async fn cmd_plugins_update_all<R: Runtime>(
window: WebviewWindow<R>,
) -> Result<Vec<PluginNameVersion>> {
File diff suppressed because it is too large Load Diff
+9 -17
View File
@@ -8,8 +8,7 @@ use chrono::Utc;
use log::warn;
use serde::{Deserialize, Serialize};
use std::path::Path;
use tauri::ipc::Channel;
use tauri::{AppHandle, Listener, Runtime, command};
use tauri::{AppHandle, Listener, Runtime};
use tokio::sync::watch;
use ts_rs::TS;
use yaak_sync::error::Error::InvalidSyncDirectory;
@@ -19,7 +18,6 @@ use yaak_sync::sync::{
};
use yaak_sync::watch::{WatchEvent, watch_directory};
#[command]
pub(crate) async fn cmd_sync_calculate<R: Runtime>(
app_handle: AppHandle<R>,
workspace_id: &str,
@@ -40,14 +38,12 @@ pub(crate) async fn cmd_sync_calculate<R: Runtime>(
Ok(compute_sync_ops(db_candidates, fs_candidates))
}
#[command]
pub(crate) async fn cmd_sync_calculate_fs(dir: &Path) -> Result<Vec<SyncOp>> {
let db_candidates = Vec::new();
let fs_candidates = get_fs_candidates(dir)?;
Ok(compute_sync_ops(db_candidates, fs_candidates))
}
#[command]
pub(crate) async fn cmd_sync_apply<R: Runtime>(
app_handle: AppHandle<R>,
sync_ops: Vec<SyncOp>,
@@ -68,23 +64,19 @@ pub(crate) struct WatchResult {
unlisten_event: String,
}
#[command]
pub(crate) async fn cmd_sync_watch<R: Runtime>(
pub(crate) async fn sync_watch<R, F>(
app_handle: AppHandle<R>,
sync_dir: &Path,
workspace_id: &str,
channel: Channel<WatchEvent>,
) -> Result<WatchResult> {
on_event: F,
) -> Result<WatchResult>
where
R: Runtime,
F: Fn(WatchEvent) + Send + Sync + 'static,
{
let (cancel_tx, cancel_rx) = watch::channel(());
// Create a callback that forwards events to the Tauri channel
let callback = move |event: WatchEvent| {
if let Err(e) = channel.send(event) {
warn!("Failed to send watch event: {:?}", e);
}
};
watch_directory(&sync_dir, callback, cancel_rx).await?;
watch_directory(&sync_dir, on_event, cancel_rx).await?;
let app_handle_inner = app_handle.clone();
let unlisten_event =
+1 -5
View File
@@ -9,7 +9,7 @@ use log::{debug, info, warn};
use std::str::FromStr;
use std::sync::Arc;
use tauri::http::HeaderValue;
use tauri::{AppHandle, Manager, Runtime, State, WebviewWindow, command};
use tauri::{AppHandle, Manager, Runtime, State, WebviewWindow};
use tokio::sync::{Mutex, mpsc};
use tokio_tungstenite::tungstenite::Message;
use url::Url;
@@ -29,7 +29,6 @@ use yaak_templates::{RenderErrorBehavior, RenderOptions};
use yaak_tls::find_client_certificate;
use yaak_ws::{WebsocketManager, render_websocket_request};
#[command]
pub async fn cmd_ws_delete_connections<R: Runtime>(
request_id: &str,
app_handle: AppHandle<R>,
@@ -41,7 +40,6 @@ pub async fn cmd_ws_delete_connections<R: Runtime>(
)?)
}
#[command]
pub async fn cmd_ws_send<R: Runtime>(
connection_id: &str,
environment_id: Option<&str>,
@@ -125,7 +123,6 @@ async fn send_websocket_message<R: Runtime>(
Ok(connection.clone())
}
#[command]
pub async fn cmd_ws_close<R: Runtime>(
connection_id: &str,
app_handle: AppHandle<R>,
@@ -149,7 +146,6 @@ pub async fn cmd_ws_close<R: Runtime>(
Ok(connection)
}
#[command]
pub async fn cmd_ws_connect<R: Runtime>(
request_id: &str,
environment_id: Option<&str>,