diff --git a/crates-cli/yaak-cli/src/plugin_events.rs b/crates-cli/yaak-cli/src/plugin_events.rs index 1e7f9f36..cadc42dc 100644 --- a/crates-cli/yaak-cli/src/plugin_events.rs +++ b/crates-cli/yaak-cli/src/plugin_events.rs @@ -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( render_json_value_raw(value, vars, cb, opt).await } -async fn render_grpc_request_for_cli( - grpc_request: &GrpcRequest, - environment_chain: Vec, - cb: &T, - opt: &RenderOptions, -) -> yaak_templates::error::Result { - 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(); diff --git a/crates-tauri/yaak-app/src/render.rs b/crates-tauri/yaak-app/src/render.rs index 8cb3fd00..a6abe0d3 100644 --- a/crates-tauri/yaak-app/src/render.rs +++ b/crates-tauri/yaak-app/src/render.rs @@ -1,8 +1,6 @@ -use log::info; use serde_json::Value; -use std::collections::BTreeMap; -pub use yaak::render::render_http_request; -use yaak_models::models::{Environment, GrpcRequest, HttpRequestHeader}; +pub use yaak::render::{render_grpc_request, render_http_request}; +use yaak_models::models::Environment; use yaak_models::render::make_vars_hashmap; use yaak_templates::{RenderOptions, TemplateCallback, parse_and_render, render_json_value_raw}; @@ -25,61 +23,3 @@ pub async fn render_json_value( let vars = &make_vars_hashmap(environment_chain); render_json_value_raw(value, vars, cb, opt).await } - -pub async fn render_grpc_request( - r: &GrpcRequest, - environment_chain: Vec, - cb: &T, - opt: &RenderOptions, -) -> yaak_templates::error::Result { - let vars = &make_vars_hashmap(environment_chain); - - let mut metadata = Vec::new(); - for p in r.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 r.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(); - info!( - "Rendering authentication.disabled as a template: {disabled} from \"{tmpl}\"" - ); - } - _ => {} - } - if disabled { - auth.insert("disabled".to_string(), Value::Bool(true)); - } else { - for (k, v) in r.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(r.url.as_str(), vars, cb, &opt).await?; - - Ok(GrpcRequest { url, metadata, authentication, ..r.to_owned() }) -} diff --git a/crates-tauri/yaak-app/src/ws_ext.rs b/crates-tauri/yaak-app/src/ws_ext.rs index 28580f93..96b6f438 100644 --- a/crates-tauri/yaak-app/src/ws_ext.rs +++ b/crates-tauri/yaak-app/src/ws_ext.rs @@ -24,6 +24,7 @@ use yaak_models::util::UpdateSource; use yaak_plugins::events::{CallHttpAuthenticationRequest, HttpHeader, RenderPurpose}; use yaak_plugins::manager::PluginManager; use yaak_plugins::template_callback::PluginTemplateCallback; +use yaak_templates::strip_json_comments::maybe_strip_json_comments; use yaak_templates::{RenderErrorBehavior, RenderOptions}; use yaak_tls::find_client_certificate; use yaak_ws::{WebsocketManager, render_websocket_request}; @@ -72,8 +73,10 @@ pub async fn cmd_ws_send( ) .await?; + let message = maybe_strip_json_comments(&request.message); + let mut ws_manager = ws_manager.lock().await; - ws_manager.send(&connection.id, Message::Text(request.message.clone().into())).await?; + ws_manager.send(&connection.id, Message::Text(message.clone().into())).await?; app_handle.db().upsert_websocket_event( &WebsocketEvent { @@ -82,7 +85,7 @@ pub async fn cmd_ws_send( workspace_id: connection.workspace_id.clone(), is_server: false, message_type: WebsocketEventType::Text, - message: request.message.into(), + message: message.into(), ..Default::default() }, &UpdateSource::from_window_label(window.label()), diff --git a/crates/yaak-templates/src/strip_json_comments.rs b/crates/yaak-templates/src/strip_json_comments.rs index da2267db..024d4825 100644 --- a/crates/yaak-templates/src/strip_json_comments.rs +++ b/crates/yaak-templates/src/strip_json_comments.rs @@ -1,3 +1,14 @@ +/// Strips JSON comments only if the result is valid JSON. If stripping comments +/// produces invalid JSON, the original text is returned unchanged. +pub fn maybe_strip_json_comments(text: &str) -> String { + let stripped = strip_json_comments(text); + if serde_json::from_str::(&stripped).is_ok() { + stripped + } else { + text.to_string() + } +} + /// Strips comments from JSONC, preserving the original formatting as much as possible. /// /// - Trailing comments on a line are removed (along with preceding whitespace) diff --git a/crates/yaak/src/render.rs b/crates/yaak/src/render.rs index 64b5e04e..75015ae7 100644 --- a/crates/yaak/src/render.rs +++ b/crates/yaak/src/render.rs @@ -2,7 +2,7 @@ use log::info; use serde_json::Value; use std::collections::BTreeMap; use yaak_http::path_placeholders::apply_path_placeholders; -use yaak_models::models::{Environment, HttpRequest, HttpRequestHeader, HttpUrlParameter}; +use yaak_models::models::{Environment, GrpcRequest, HttpRequest, HttpRequestHeader, HttpUrlParameter}; use yaak_models::render::make_vars_hashmap; use yaak_templates::{RenderOptions, TemplateCallback, parse_and_render, render_json_value_raw}; @@ -89,6 +89,64 @@ pub async fn render_http_request( Ok(HttpRequest { url, url_parameters, headers, body, authentication, ..request.to_owned() }) } +pub async fn render_grpc_request( + r: &GrpcRequest, + environment_chain: Vec, + cb: &T, + opt: &RenderOptions, +) -> yaak_templates::error::Result { + let vars = &make_vars_hashmap(environment_chain); + + let mut metadata = Vec::new(); + for p in r.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 r.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(); + info!( + "Rendering authentication.disabled as a template: {disabled} from \"{tmpl}\"" + ); + } + _ => {} + } + if disabled { + auth.insert("disabled".to_string(), Value::Bool(true)); + } else { + for (k, v) in r.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(r.url.as_str(), vars, cb, opt).await?; + + Ok(GrpcRequest { url, metadata, authentication, ..r.to_owned() }) +} + fn strip_disabled_form_entries(v: Value) -> Value { match v { Value::Array(items) => Value::Array(