Merge branch 'main' into wip/yaak-proxy-foundation

# Conflicts:
#	apps/yaak-client/components/JsonBodyEditor.tsx
#	apps/yaak-client/lib/jsonComments.ts
#	package-lock.json
#	packages/theme/src/window.ts
#	packages/ui/src/components/HeaderSize.tsx
This commit is contained in:
Gregory Schier
2026-03-11 15:36:57 -07:00
40 changed files with 1187 additions and 518 deletions

View File

@@ -10,6 +10,7 @@ mod version_check;
use clap::Parser;
use cli::{Cli, Commands, PluginCommands, RequestCommands};
use context::{CliContext, CliExecutionContext};
use std::path::PathBuf;
use yaak_models::queries::any_request::AnyRequest;
#[tokio::main]
@@ -30,9 +31,7 @@ async fn main() {
let app_id = if cfg!(debug_assertions) { "app.yaak.desktop.dev" } else { "app.yaak.desktop" };
let data_dir = data_dir.unwrap_or_else(|| {
dirs::data_dir().expect("Could not determine data directory").join(app_id)
});
let data_dir = data_dir.unwrap_or_else(|| resolve_data_dir(app_id));
version_check::maybe_check_for_updates().await;
@@ -239,3 +238,46 @@ fn resolve_cookie_jar_id(
.map(|jar| jar.id);
Ok(default_cookie_jar)
}
fn resolve_data_dir(app_id: &str) -> PathBuf {
if let Some(dir) = wsl_data_dir(app_id) {
return dir;
}
dirs::data_dir().expect("Could not determine data directory").join(app_id)
}
/// Detect WSL and resolve the Windows AppData\Roaming path for the Yaak data directory.
fn wsl_data_dir(app_id: &str) -> Option<PathBuf> {
if !cfg!(target_os = "linux") {
return None;
}
let proc_version = std::fs::read_to_string("/proc/version").ok()?;
let is_wsl = proc_version.to_lowercase().contains("microsoft");
if !is_wsl {
return None;
}
// We're in WSL, so try to resolve the Yaak app's data directory in Windows
// Get the Windows %APPDATA% path via cmd.exe
let appdata_output =
std::process::Command::new("cmd.exe").args(["/C", "echo", "%APPDATA%"]).output().ok()?;
let win_path = String::from_utf8(appdata_output.stdout).ok()?.trim().to_string();
if win_path.is_empty() || win_path == "%APPDATA%" {
return None;
}
// Convert Windows path to WSL path using wslpath (handles custom mount points)
let wslpath_output = std::process::Command::new("wslpath").arg(&win_path).output().ok()?;
let wsl_appdata = String::from_utf8(wslpath_output.stdout).ok()?.trim().to_string();
if wsl_appdata.is_empty() {
return None;
}
let wsl_path = PathBuf::from(wsl_appdata).join(app_id);
if wsl_path.exists() { Some(wsl_path) } else { None }
}

View File

@@ -3,7 +3,7 @@ use arboard::Clipboard;
use console::Term;
use inquire::{Confirm, Editor, Password, PasswordDisplayMode, Select, Text};
use serde_json::Value;
use std::collections::{BTreeMap, HashMap};
use std::collections::HashMap;
use std::io::IsTerminal;
use std::path::PathBuf;
use std::sync::Arc;
@@ -11,11 +11,11 @@ use tokio::task::JoinHandle;
use yaak::plugin_events::{
GroupedPluginEvent, HostRequest, SharedPluginEventContext, handle_shared_plugin_event,
};
use yaak::render::render_http_request;
use yaak::render::{render_grpc_request, render_http_request};
use yaak::send::{SendHttpRequestWithPluginsParams, send_http_request_with_plugins};
use yaak_crypto::manager::EncryptionManager;
use yaak_models::blob_manager::BlobManager;
use yaak_models::models::{Environment, GrpcRequest, HttpRequestHeader};
use yaak_models::models::Environment;
use yaak_models::queries::any_request::AnyRequest;
use yaak_models::query_manager::QueryManager;
use yaak_models::render::make_vars_hashmap;
@@ -29,7 +29,7 @@ use yaak_plugins::events::{
};
use yaak_plugins::manager::PluginManager;
use yaak_plugins::template_callback::PluginTemplateCallback;
use yaak_templates::{RenderOptions, TemplateCallback, parse_and_render, render_json_value_raw};
use yaak_templates::{RenderOptions, TemplateCallback, render_json_value_raw};
pub struct CliPluginEventBridge {
rx_id: String,
@@ -269,7 +269,7 @@ async fn build_plugin_reply(
);
let render_options = RenderOptions::throw();
match render_grpc_request_for_cli(
match render_grpc_request(
&grpc_request,
environment_chain,
&template_callback,
@@ -532,60 +532,6 @@ async fn render_json_value_for_cli<T: TemplateCallback>(
render_json_value_raw(value, vars, cb, opt).await
}
async fn render_grpc_request_for_cli<T: TemplateCallback>(
grpc_request: &GrpcRequest,
environment_chain: Vec<Environment>,
cb: &T,
opt: &RenderOptions,
) -> yaak_templates::error::Result<GrpcRequest> {
let vars = &make_vars_hashmap(environment_chain);
let mut metadata = Vec::new();
for p in grpc_request.metadata.clone() {
if !p.enabled {
continue;
}
metadata.push(HttpRequestHeader {
enabled: p.enabled,
name: parse_and_render(p.name.as_str(), vars, cb, opt).await?,
value: parse_and_render(p.value.as_str(), vars, cb, opt).await?,
id: p.id,
})
}
let authentication = {
let mut disabled = false;
let mut auth = BTreeMap::new();
match grpc_request.authentication.get("disabled") {
Some(Value::Bool(true)) => {
disabled = true;
}
Some(Value::String(tmpl)) => {
disabled = parse_and_render(tmpl.as_str(), vars, cb, opt)
.await
.unwrap_or_default()
.is_empty();
}
_ => {}
}
if disabled {
auth.insert("disabled".to_string(), Value::Bool(true));
} else {
for (k, v) in grpc_request.authentication.clone() {
if k == "disabled" {
auth.insert(k, Value::Bool(false));
} else {
auth.insert(k, render_json_value_raw(v, vars, cb, opt).await?);
}
}
}
auth
};
let url = parse_and_render(grpc_request.url.as_str(), vars, cb, opt).await?;
Ok(GrpcRequest { url, metadata, authentication, ..grpc_request.to_owned() })
}
fn parse_cookie_name_value(raw_cookie: &str) -> Option<(String, String)> {
let first_part = raw_cookie.split(';').next()?.trim();