mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-05-08 08:53:43 +02:00
Merge main into proxy foundation
This commit is contained in:
8
.oxfmtrc.json
Normal file
8
.oxfmtrc.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"ignorePatterns": [
|
||||
"**/bindings/**",
|
||||
"crates/yaak-templates/pkg/**",
|
||||
"apps/yaak-client/routeTree.gen.ts"
|
||||
]
|
||||
}
|
||||
16
Cargo.lock
generated
16
Cargo.lock
generated
@@ -1169,7 +1169,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
||||
dependencies = [
|
||||
"lazy_static 1.5.0",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5791,9 +5791,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quinn-proto"
|
||||
version = "0.11.12"
|
||||
version = "0.11.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e"
|
||||
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"getrandom 0.3.3",
|
||||
@@ -6856,9 +6856,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.7"
|
||||
version = "0.103.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf"
|
||||
checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"ring",
|
||||
@@ -7746,9 +7746,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "tar"
|
||||
version = "0.4.44"
|
||||
version = "0.4.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a"
|
||||
checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973"
|
||||
dependencies = [
|
||||
"filetime",
|
||||
"libc",
|
||||
@@ -9549,7 +9549,7 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -67,6 +67,13 @@
|
||||
@apply bg-selection !important;
|
||||
}
|
||||
|
||||
/* Fix WebKit/WKWebView rendering bug where selection layer leaves a ghost
|
||||
residual line below wrapped lines after deselecting (CodeMirror issue #1600, #1627).
|
||||
The layer div must be hidden when empty to force a repaint. */
|
||||
.cm-selectionLayer:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Style gutters */
|
||||
|
||||
.cm-gutters {
|
||||
|
||||
@@ -57,7 +57,7 @@ export function HttpMethodTagRaw({
|
||||
let label = method.toUpperCase();
|
||||
if (short) {
|
||||
label = methodNames[method.toLowerCase()] ?? method.slice(0, 4);
|
||||
label = label.padStart(4, " ");
|
||||
label = label.padEnd(4, " ");
|
||||
}
|
||||
|
||||
const m = method.toUpperCase();
|
||||
|
||||
@@ -59,9 +59,9 @@
|
||||
"nanoid": "^5.0.9",
|
||||
"papaparse": "^5.4.1",
|
||||
"parse-color": "^1.0.0",
|
||||
"react": "^19.1.0",
|
||||
"react": "^19.2.0",
|
||||
"react-colorful": "^5.6.1",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-pdf": "^10.0.1",
|
||||
"react-syntax-highlighter": "^16.1.0",
|
||||
@@ -70,10 +70,10 @@
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"slugify": "^1.6.6",
|
||||
"uuid": "^11.1.0",
|
||||
"uuid": "^14.0.0",
|
||||
"vkbeautify": "^0.99.3",
|
||||
"whatwg-mimetype": "^4.0.0",
|
||||
"yaml": "^2.6.1"
|
||||
"yaml": "^2.8.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lezer/generator": "^1.8.0",
|
||||
@@ -83,12 +83,12 @@
|
||||
"@types/node": "^24.0.13",
|
||||
"@types/papaparse": "^5.3.16",
|
||||
"@types/parse-color": "^1.0.3",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@types/react": "^19.2.0",
|
||||
"@types/react-dom": "^19.2.0",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@types/whatwg-mimetype": "^3.0.2",
|
||||
"@vitejs/plugin-react": "^4.6.0",
|
||||
"@vitejs/plugin-react": "^6.0.0",
|
||||
"@yaakapp-internal/theme": "^1.0.0",
|
||||
"@yaakapp-internal/ui": "^1.0.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
@@ -98,8 +98,8 @@
|
||||
"postcss-nesting": "^13.0.2",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"vite": "^7.0.8",
|
||||
"vite-plugin-static-copy": "^3.1.2",
|
||||
"vite-plugin-svgr": "^4.3.0",
|
||||
"vite-plugin-static-copy": "^3.3.0",
|
||||
"vite-plugin-svgr": "^4.5.0",
|
||||
"vite-plugin-top-level-await": "^1.5.0",
|
||||
"vite-plugin-wasm": "^3.5.0"
|
||||
}
|
||||
|
||||
@@ -19,13 +19,13 @@
|
||||
"classnames": "^2.5.1",
|
||||
"jotai": "^2.18.0",
|
||||
"motion": "^12.4.7",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0"
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@vitejs/plugin-react": "^4.6.0",
|
||||
"@types/react": "^19.2.0",
|
||||
"@types/react-dom": "^19.2.0",
|
||||
"@vitejs/plugin-react": "^6.0.0",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^7.0.8"
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"noUncheckedIndexedAccess": true
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
|
||||
2
apps/yaak-proxy/vite-env.d.ts
vendored
2
apps/yaak-proxy/vite-env.d.ts
vendored
@@ -1 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
/// <reference types="vite-plus/client" />
|
||||
|
||||
80
biome.json
80
biome.json
@@ -1,80 +0,0 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.3.13/schema.json",
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true,
|
||||
"a11y": {
|
||||
"useKeyWithClickEvents": "off"
|
||||
},
|
||||
"style": {
|
||||
"noRestrictedImports": {
|
||||
"level": "error",
|
||||
"options": {
|
||||
"paths": {
|
||||
"@tauri-apps/api/core": "Use lib/tauri.ts instead of importing @tauri-apps directly",
|
||||
"@tauri-apps/api/event": "Use lib/tauri.ts instead of importing @tauri-apps directly",
|
||||
"@tauri-apps/api/webviewWindow": "Use lib/tauri.ts instead of importing @tauri-apps directly",
|
||||
"@tauri-apps/plugin-os": "Use lib/tauri.ts instead of importing @tauri-apps directly"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 2,
|
||||
"lineWidth": 100,
|
||||
"bracketSpacing": true
|
||||
},
|
||||
"css": {
|
||||
"parser": {
|
||||
"tailwindDirectives": true
|
||||
},
|
||||
"linter": {
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"quoteStyle": "single",
|
||||
"jsxQuoteStyle": "double",
|
||||
"trailingCommas": "all",
|
||||
"semicolons": "always"
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"includes": ["apps/yaak-proxy/lib/tauri.ts"],
|
||||
"linter": {
|
||||
"rules": {
|
||||
"style": {
|
||||
"noRestrictedImports": "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"files": {
|
||||
"includes": [
|
||||
"**",
|
||||
"!**/node_modules",
|
||||
"!**/dist",
|
||||
"!**/build",
|
||||
"!target",
|
||||
"!scripts",
|
||||
"!crates",
|
||||
"!crates-tauri",
|
||||
"!apps/yaak-client/tailwind.config.cjs",
|
||||
"!apps/yaak-client/postcss.config.cjs",
|
||||
"!apps/yaak-client/vite.config.ts",
|
||||
"!apps/yaak-client/routeTree.gen.ts",
|
||||
"!packages/plugin-runtime-types/lib",
|
||||
"!**/bindings",
|
||||
"!flatpak",
|
||||
"!npm"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ use yaak::plugin_events::{
|
||||
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_http::cookies::get_cookie_value_from_jar;
|
||||
use yaak_models::blob_manager::BlobManager;
|
||||
use yaak_models::models::Environment;
|
||||
use yaak_models::queries::any_request::AnyRequest;
|
||||
@@ -496,10 +497,8 @@ async fn build_plugin_reply(
|
||||
}
|
||||
};
|
||||
|
||||
let value = cookie_jar.cookies.into_iter().find_map(|c| {
|
||||
let (name, value) = parse_cookie_name_value(&c.raw_cookie)?;
|
||||
if name == req.name { Some(value) } else { None }
|
||||
});
|
||||
let value =
|
||||
get_cookie_value_from_jar(cookie_jar.cookies, &req.name, req.domain.as_deref());
|
||||
Some(InternalEventPayload::GetCookieValueResponse(GetCookieValueResponse { value }))
|
||||
}
|
||||
HostRequest::WindowInfo(req) => {
|
||||
@@ -532,7 +531,6 @@ async fn render_json_value_for_cli<T: TemplateCallback>(
|
||||
render_json_value_raw(value, vars, cb, opt).await
|
||||
}
|
||||
|
||||
|
||||
fn parse_cookie_name_value(raw_cookie: &str) -> Option<(String, String)> {
|
||||
let first_part = raw_cookie.split(';').next()?.trim();
|
||||
let (name, value) = first_part.split_once('=')?;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use crate::PluginContextExt;
|
||||
use crate::error::Result;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::models_ext::QueryManagerExt;
|
||||
use log::info;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs::read_to_string;
|
||||
use std::io::ErrorKind;
|
||||
use tauri::{Manager, Runtime, WebviewWindow};
|
||||
use yaak_core::WorkspaceContext;
|
||||
use yaak_models::models::{
|
||||
@@ -18,8 +19,7 @@ pub(crate) async fn import_data<R: Runtime>(
|
||||
file_path: &str,
|
||||
) -> Result<BatchUpsertResult> {
|
||||
let plugin_manager = window.state::<PluginManager>();
|
||||
let file =
|
||||
read_to_string(file_path).unwrap_or_else(|_| panic!("Unable to read file {}", file_path));
|
||||
let file = read_import_file(file_path)?;
|
||||
let file_contents = file.as_str();
|
||||
let import_result = plugin_manager.import_data(&window.plugin_context(), file_contents).await?;
|
||||
|
||||
@@ -127,3 +127,41 @@ pub(crate) async fn import_data<R: Runtime>(
|
||||
|
||||
Ok(upserted)
|
||||
}
|
||||
|
||||
fn read_import_file(file_path: &str) -> Result<String> {
|
||||
read_to_string(file_path).map_err(|err| {
|
||||
if err.kind() == ErrorKind::InvalidData {
|
||||
Error::GenericError(format!(
|
||||
"Import file must be UTF-8 text; binary files are not supported: {file_path}"
|
||||
))
|
||||
} else {
|
||||
Error::GenericError(format!("Unable to read import file {file_path}: {err}"))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::fs::{remove_file, write};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
#[test]
|
||||
fn read_import_file_returns_error_for_binary_file() {
|
||||
let path = std::env::temp_dir().join(format!(
|
||||
"yaak-import-binary-{}.pftrace",
|
||||
SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("system time before unix epoch")
|
||||
.as_nanos()
|
||||
));
|
||||
write(&path, [0xff, 0xfe, 0xfd]).expect("write binary fixture");
|
||||
|
||||
let err = read_import_file(path.to_str().expect("temp path is utf-8"))
|
||||
.expect_err("binary import should return an error");
|
||||
|
||||
assert!(err.to_string().contains("binary files are not supported"));
|
||||
|
||||
remove_file(path).expect("remove binary fixture");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,7 @@ use tokio::time;
|
||||
use yaak_common::command::new_checked_command;
|
||||
use yaak_crypto::manager::EncryptionManager;
|
||||
use yaak_grpc::manager::{GrpcConfig, GrpcHandle};
|
||||
use yaak_templates::strip_json_comments::strip_json_comments;
|
||||
use yaak_grpc::{Code, ServiceDefinition, serialize_message};
|
||||
use yaak_grpc::{Code, ServiceDefinition};
|
||||
use yaak_mac_window::AppHandleMacWindowExt;
|
||||
use yaak_models::models::{
|
||||
AnyModel, CookieJar, Environment, GrpcConnection, GrpcConnectionState, GrpcEvent,
|
||||
@@ -60,6 +59,7 @@ use yaak_plugins::template_callback::PluginTemplateCallback;
|
||||
use yaak_sse::sse::ServerSentEvent;
|
||||
use yaak_tauri_utils::window::WorkspaceWindowTrait;
|
||||
use yaak_templates::format_json::format_json;
|
||||
use yaak_templates::strip_json_comments::strip_json_comments;
|
||||
use yaak_templates::{RenderErrorBehavior, RenderOptions, Tokens, transform_args};
|
||||
use yaak_tls::find_client_certificate;
|
||||
|
||||
@@ -591,7 +591,7 @@ async fn cmd_grpc_go<R: Runtime>(
|
||||
&method,
|
||||
in_msg_stream,
|
||||
&metadata,
|
||||
client_cert,
|
||||
client_cert.clone(),
|
||||
on_message.clone(),
|
||||
)
|
||||
.await,
|
||||
@@ -607,7 +607,7 @@ async fn cmd_grpc_go<R: Runtime>(
|
||||
&method,
|
||||
in_msg_stream,
|
||||
&metadata,
|
||||
client_cert,
|
||||
client_cert.clone(),
|
||||
on_message.clone(),
|
||||
)
|
||||
.await,
|
||||
@@ -620,7 +620,9 @@ async fn cmd_grpc_go<R: Runtime>(
|
||||
(false, false) => (
|
||||
None,
|
||||
Some(
|
||||
connection.unary(&service, &method, &msg, &metadata, client_cert).await,
|
||||
connection
|
||||
.unary(&service, &method, &msg, &metadata, client_cert.clone())
|
||||
.await,
|
||||
),
|
||||
),
|
||||
};
|
||||
@@ -658,11 +660,34 @@ async fn cmd_grpc_go<R: Runtime>(
|
||||
&UpdateSource::from_window_label(window.label()),
|
||||
)
|
||||
.unwrap();
|
||||
let response_message = msg.into_inner();
|
||||
let content = match connection
|
||||
.serialize_message(&response_message, &metadata, client_cert.clone())
|
||||
.await
|
||||
{
|
||||
Ok(content) => content,
|
||||
Err(err) => {
|
||||
app_handle
|
||||
.db()
|
||||
.upsert_grpc_event(
|
||||
&GrpcEvent {
|
||||
content: "Failed to read response".to_string(),
|
||||
error: Some(err.to_string()),
|
||||
status: Some(Code::Internal as i32),
|
||||
event_type: GrpcEventType::ConnectionEnd,
|
||||
..base_event.clone()
|
||||
},
|
||||
&UpdateSource::from_window_label(window.label()),
|
||||
)
|
||||
.unwrap();
|
||||
return;
|
||||
}
|
||||
};
|
||||
app_handle
|
||||
.db()
|
||||
.upsert_grpc_event(
|
||||
&GrpcEvent {
|
||||
content: serialize_message(&msg.into_inner()).unwrap(),
|
||||
content,
|
||||
event_type: GrpcEventType::ServerMessage,
|
||||
..base_event.clone()
|
||||
},
|
||||
@@ -797,7 +822,28 @@ async fn cmd_grpc_go<R: Runtime>(
|
||||
loop {
|
||||
match stream.message().await {
|
||||
Ok(Some(msg)) => {
|
||||
let message = serialize_message(&msg).unwrap();
|
||||
let message = match connection
|
||||
.serialize_message(&msg, &metadata, client_cert.clone())
|
||||
.await
|
||||
{
|
||||
Ok(message) => message,
|
||||
Err(err) => {
|
||||
app_handle
|
||||
.db()
|
||||
.upsert_grpc_event(
|
||||
&GrpcEvent {
|
||||
content: "Failed to read response".to_string(),
|
||||
error: Some(err.to_string()),
|
||||
status: Some(Code::Internal as i32),
|
||||
event_type: GrpcEventType::ConnectionEnd,
|
||||
..base_event.clone()
|
||||
},
|
||||
&UpdateSource::from_window_label(window.label()),
|
||||
)
|
||||
.unwrap();
|
||||
break;
|
||||
}
|
||||
};
|
||||
app_handle
|
||||
.db()
|
||||
.upsert_grpc_event(
|
||||
|
||||
@@ -19,6 +19,7 @@ use yaak::plugin_events::{
|
||||
GroupedPluginEvent, HostRequest, SharedPluginEventContext, handle_shared_plugin_event,
|
||||
};
|
||||
use yaak_crypto::manager::EncryptionManager;
|
||||
use yaak_http::cookies::get_cookie_value_from_jar;
|
||||
use yaak_models::models::{HttpResponse, Plugin};
|
||||
use yaak_models::queries::any_request::AnyRequest;
|
||||
use yaak_models::util::UpdateSource;
|
||||
@@ -422,12 +423,7 @@ async fn handle_host_plugin_request<R: Runtime>(
|
||||
let window = get_window_from_plugin_context(app_handle, plugin_context)?;
|
||||
let value = match cookie_jar_from_window(&window) {
|
||||
None => None,
|
||||
Some(j) => j.cookies.into_iter().find_map(|c| match Cookie::parse(c.raw_cookie) {
|
||||
Ok(c) if c.name().to_string().eq(&req.name) => {
|
||||
Some(c.value_trimmed().to_string())
|
||||
}
|
||||
_ => None,
|
||||
}),
|
||||
Some(j) => get_cookie_value_from_jar(j.cookies, &req.name, req.domain.as_deref()),
|
||||
};
|
||||
Ok(Some(InternalEventPayload::GetCookieValueResponse(GetCookieValueResponse { value })))
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ pub struct MethodDefinition {
|
||||
static SERIALIZE_OPTIONS: &'static SerializeOptions =
|
||||
&SerializeOptions::new().skip_default_fields(false).stringify_64_bit_integers(false);
|
||||
|
||||
pub fn serialize_message(msg: &DynamicMessage) -> Result<String, String> {
|
||||
pub(crate) fn serialize_dynamic_message_json(msg: &DynamicMessage) -> Result<String, String> {
|
||||
let mut buf = Vec::new();
|
||||
let mut se = serde_json::Serializer::pretty(&mut buf);
|
||||
msg.serialize_with_options(&mut se, SERIALIZE_OPTIONS).map_err(|e| e.to_string())?;
|
||||
|
||||
@@ -2,7 +2,8 @@ use crate::codec::DynamicCodec;
|
||||
use crate::error::Error::GenericError;
|
||||
use crate::error::Result;
|
||||
use crate::reflection::{
|
||||
fill_pool_from_files, fill_pool_from_reflection, method_desc_to_path, reflect_types_for_message,
|
||||
fill_pool_from_files, fill_pool_from_reflection, method_desc_to_path,
|
||||
reflect_types_for_dynamic_message, reflect_types_for_message,
|
||||
};
|
||||
use crate::transport::get_transport;
|
||||
use crate::{MethodDefinition, ServiceDefinition, json_schema};
|
||||
@@ -11,8 +12,11 @@ use hyper_util::client::legacy::Client;
|
||||
use hyper_util::client::legacy::connect::HttpConnector;
|
||||
use log::{info, warn};
|
||||
pub use prost_reflect::DynamicMessage;
|
||||
use prost_reflect::ReflectMessage;
|
||||
use prost_reflect::prost::Message;
|
||||
use prost_reflect::{DescriptorPool, MethodDescriptor, ServiceDescriptor};
|
||||
use serde_json::Deserializer;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
@@ -115,6 +119,38 @@ impl GrpcConnection {
|
||||
Ok(client.unary(req, path, codec).await?)
|
||||
}
|
||||
|
||||
pub async fn serialize_message(
|
||||
&self,
|
||||
message: &DynamicMessage,
|
||||
metadata: &BTreeMap<String, String>,
|
||||
client_cert: Option<ClientCertificateConfig>,
|
||||
) -> Result<String> {
|
||||
let message = if self.use_reflection {
|
||||
reflect_types_for_dynamic_message(
|
||||
self.pool.clone(),
|
||||
&self.uri,
|
||||
message,
|
||||
metadata,
|
||||
client_cert,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let message_name = message.descriptor().full_name().to_string();
|
||||
let message_desc = {
|
||||
let pool = self.pool.read().await;
|
||||
pool.get_message_by_name(&message_name)
|
||||
.ok_or(GenericError(format!("Failed to find message {message_name}")))?
|
||||
};
|
||||
let mut message_with_updated_pool = DynamicMessage::new(message_desc);
|
||||
message_with_updated_pool.merge(message.encode_to_vec().as_slice())?;
|
||||
Cow::Owned(message_with_updated_pool)
|
||||
} else {
|
||||
Cow::Borrowed(message)
|
||||
};
|
||||
|
||||
crate::serialize_dynamic_message_json(message.as_ref()).map_err(GenericError)
|
||||
}
|
||||
|
||||
pub async fn streaming<F>(
|
||||
&self,
|
||||
service: &str,
|
||||
|
||||
@@ -7,7 +7,7 @@ use anyhow::anyhow;
|
||||
use async_recursion::async_recursion;
|
||||
use log::{debug, info, warn};
|
||||
use prost::Message;
|
||||
use prost_reflect::{DescriptorPool, MethodDescriptor};
|
||||
use prost_reflect::{DescriptorPool, DynamicMessage, MethodDescriptor, ReflectMessage, Value};
|
||||
use prost_types::{FileDescriptorProto, FileDescriptorSet};
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::env::temp_dir;
|
||||
@@ -233,6 +233,83 @@ pub(crate) async fn reflect_types_for_message(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn reflect_types_for_dynamic_message(
|
||||
pool: Arc<RwLock<DescriptorPool>>,
|
||||
uri: &Uri,
|
||||
message: &DynamicMessage,
|
||||
metadata: &BTreeMap<String, String>,
|
||||
client_cert: Option<ClientCertificateConfig>,
|
||||
) -> Result<()> {
|
||||
let mut extra_types = HashSet::new();
|
||||
collect_any_types_from_dynamic_message(message, &mut extra_types);
|
||||
|
||||
if extra_types.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut client = AutoReflectionClient::new(uri, false, client_cert)?;
|
||||
for extra_type in extra_types {
|
||||
{
|
||||
let guard = pool.read().await;
|
||||
if guard.get_message_by_name(&extra_type).is_some() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
info!("Adding response file descriptor for {:?} from reflection", extra_type);
|
||||
let req = MessageRequest::FileContainingSymbol(extra_type.clone().into());
|
||||
let resp = match client.send_reflection_request(req, metadata).await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Err(GenericError(format!(
|
||||
"Error sending reflection request for response @type \"{extra_type}\": {e:?}",
|
||||
)));
|
||||
}
|
||||
};
|
||||
let files = match resp {
|
||||
MessageResponse::FileDescriptorResponse(resp) => resp.file_descriptor_proto,
|
||||
_ => panic!("Expected a FileDescriptorResponse variant"),
|
||||
};
|
||||
|
||||
{
|
||||
let mut guard = pool.write().await;
|
||||
add_file_descriptors_to_pool(files, &mut *guard, &mut client, metadata).await;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn collect_any_types_from_dynamic_message(message: &DynamicMessage, out: &mut HashSet<String>) {
|
||||
if message.descriptor().full_name() == "google.protobuf.Any" {
|
||||
if let Some(Value::String(type_url)) = message.get_field_by_name("type_url").as_deref() {
|
||||
if let Some(full_name) = type_url.rsplit_once('/').map(|(_, name)| name) {
|
||||
out.insert(full_name.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (_, value) in message.fields() {
|
||||
collect_any_types_from_value(value, out);
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_any_types_from_value(value: &Value, out: &mut HashSet<String>) {
|
||||
match value {
|
||||
Value::Message(message) => collect_any_types_from_dynamic_message(message, out),
|
||||
Value::List(values) => {
|
||||
for value in values {
|
||||
collect_any_types_from_value(value, out);
|
||||
}
|
||||
}
|
||||
Value::Map(values) => {
|
||||
for value in values.values() {
|
||||
collect_any_types_from_value(value, out);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_recursion]
|
||||
pub(crate) async fn add_file_descriptors_to_pool(
|
||||
fds: Vec<Vec<u8>>,
|
||||
|
||||
@@ -1,11 +1,36 @@
|
||||
use crate::dns::LocalhostResolver;
|
||||
use crate::error::Result;
|
||||
use log::{debug, info, warn};
|
||||
use reqwest::{Client, Proxy, redirect};
|
||||
use reqwest::{Client, ClientBuilder, Proxy, redirect};
|
||||
use std::sync::Arc;
|
||||
use yaak_models::models::DnsOverride;
|
||||
use yaak_tls::{ClientCertificateConfig, get_tls_config};
|
||||
|
||||
pub const HTTP2_MAX_RESPONSE_HEADER_LIST_SIZE: u32 = 1024 * 1024;
|
||||
|
||||
fn client_builder() -> ClientBuilder {
|
||||
Client::builder().http2_max_header_list_size(HTTP2_MAX_RESPONSE_HEADER_LIST_SIZE)
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ConfiguredClient {
|
||||
inner: Client,
|
||||
}
|
||||
|
||||
impl ConfiguredClient {
|
||||
pub(crate) fn build_default() -> Result<Self> {
|
||||
Ok(Self { inner: client_builder().build()? })
|
||||
}
|
||||
|
||||
pub(crate) fn from_inner(inner: Client) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub(crate) fn inner(&self) -> &Client {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
/// Build a native-tls connector for maximum compatibility when certificate
|
||||
/// validation is disabled. Unlike rustls, native-tls uses the OS TLS stack
|
||||
/// (Secure Transport on macOS, SChannel on Windows, OpenSSL on Linux) which
|
||||
@@ -87,8 +112,8 @@ impl HttpConnectionOptions {
|
||||
/// Build a reqwest Client and return it along with the DNS resolver.
|
||||
/// The resolver is returned separately so it can be configured per-request
|
||||
/// to emit DNS timing events to the appropriate channel.
|
||||
pub(crate) fn build_client(&self) -> Result<(Client, Arc<LocalhostResolver>)> {
|
||||
let mut client = Client::builder()
|
||||
pub(crate) fn build_client(&self) -> Result<(ConfiguredClient, Arc<LocalhostResolver>)> {
|
||||
let mut client = client_builder()
|
||||
.connection_verbose(true)
|
||||
.redirect(redirect::Policy::none())
|
||||
// Decompression is handled by HttpTransaction, not reqwest
|
||||
@@ -108,8 +133,7 @@ impl HttpConnectionOptions {
|
||||
client = client.use_preconfigured_tls(config);
|
||||
} else {
|
||||
// Use native TLS for maximum compatibility (supports TLS 1.0+)
|
||||
let connector =
|
||||
build_native_tls_connector(self.client_certificate.clone())?;
|
||||
let connector = build_native_tls_connector(self.client_certificate.clone())?;
|
||||
client = client.use_preconfigured_tls(connector);
|
||||
}
|
||||
|
||||
@@ -136,7 +160,7 @@ impl HttpConnectionOptions {
|
||||
self.client_certificate.is_some()
|
||||
);
|
||||
|
||||
Ok((client.build()?, resolver))
|
||||
Ok((ConfiguredClient::from_inner(client.build()?), resolver))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -124,6 +124,30 @@ impl CookieStore {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a stored cookie value by name, optionally scoped to an exact stored domain.
|
||||
pub fn get_cookie_value_from_jar(
|
||||
cookies: impl IntoIterator<Item = Cookie>,
|
||||
name: &str,
|
||||
domain: Option<&str>,
|
||||
) -> Option<String> {
|
||||
let domain = domain.and_then(normalize_cookie_domain_filter);
|
||||
|
||||
cookies.into_iter().find_map(|cookie| {
|
||||
let (cookie_name, value) = parse_cookie_name_value(&cookie.raw_cookie)?;
|
||||
if cookie_name != name {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(domain) = domain.as_deref() {
|
||||
if !cookie_domain_matches_filter(&cookie.domain, domain) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
Some(value)
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse name=value from a cookie string (raw_cookie format)
|
||||
fn parse_cookie_name_value(raw_cookie: &str) -> Option<(String, String)> {
|
||||
// The raw_cookie typically looks like "name=value" or "name=value; attr1; attr2=..."
|
||||
@@ -135,6 +159,20 @@ fn parse_cookie_name_value(raw_cookie: &str) -> Option<(String, String)> {
|
||||
if name.is_empty() { None } else { Some((name, value)) }
|
||||
}
|
||||
|
||||
fn normalize_cookie_domain_filter(domain: &str) -> Option<String> {
|
||||
let domain = domain.trim().trim_start_matches('.').to_lowercase();
|
||||
if domain.is_empty() { None } else { Some(domain) }
|
||||
}
|
||||
|
||||
fn cookie_domain_matches_filter(cookie_domain: &CookieDomain, domain: &str) -> bool {
|
||||
match cookie_domain {
|
||||
CookieDomain::HostOnly(cookie_domain) | CookieDomain::Suffix(cookie_domain) => {
|
||||
normalize_cookie_domain_filter(cookie_domain).is_some_and(|d| d == domain)
|
||||
}
|
||||
CookieDomain::NotPresent | CookieDomain::Empty => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a Set-Cookie header into a Cookie
|
||||
fn parse_set_cookie(header_value: &str, request_url: &Url) -> Option<Cookie> {
|
||||
let parsed = cookie::Cookie::parse(header_value).ok()?;
|
||||
@@ -278,6 +316,15 @@ fn is_localhost(domain: &str) -> bool {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn cookie(raw_cookie: &str, domain: CookieDomain) -> Cookie {
|
||||
Cookie {
|
||||
raw_cookie: raw_cookie.to_string(),
|
||||
domain,
|
||||
expires: CookieExpires::SessionEnd,
|
||||
path: ("/".to_string(), false),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_cookie_name_value() {
|
||||
assert_eq!(
|
||||
@@ -387,6 +434,52 @@ mod tests {
|
||||
assert_eq!(store.get_all_cookies().len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_cookie_value_preserves_name_only_first_match() {
|
||||
let cookies = vec![
|
||||
cookie("co-auth=", CookieDomain::HostOnly("foo.example.com".to_string())),
|
||||
cookie("co-auth=token", CookieDomain::Suffix("example.com".to_string())),
|
||||
];
|
||||
|
||||
assert_eq!(get_cookie_value_from_jar(cookies, "co-auth", None), Some("".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_cookie_value_matches_domain() {
|
||||
let cookies = vec![
|
||||
cookie("co-auth=", CookieDomain::HostOnly("foo.example.com".to_string())),
|
||||
cookie("co-auth=token", CookieDomain::Suffix("example.com".to_string())),
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
get_cookie_value_from_jar(cookies, "co-auth", Some("example.com")),
|
||||
Some("token".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_cookie_value_normalizes_domain_filter() {
|
||||
let cookies = vec![cookie(
|
||||
"co-auth=token",
|
||||
CookieDomain::Suffix("Example.COM".to_string()),
|
||||
)];
|
||||
|
||||
assert_eq!(
|
||||
get_cookie_value_from_jar(cookies, "co-auth", Some(" .example.com ")),
|
||||
Some("token".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_cookie_value_requires_exact_stored_domain_match() {
|
||||
let cookies = vec![cookie(
|
||||
"co-auth=token",
|
||||
CookieDomain::HostOnly("foo.example.com".to_string()),
|
||||
)];
|
||||
|
||||
assert_eq!(get_cookie_value_from_jar(cookies, "co-auth", Some("example.com")), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_single_component_domain() {
|
||||
// Single-component domains (TLDs)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::client::HttpConnectionOptions;
|
||||
use crate::client::{ConfiguredClient, HttpConnectionOptions};
|
||||
use crate::dns::LocalhostResolver;
|
||||
use crate::error::Result;
|
||||
use reqwest::Client;
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
@@ -10,7 +9,7 @@ use tokio::sync::RwLock;
|
||||
/// A cached HTTP client along with its DNS resolver.
|
||||
/// The resolver is needed to set the event sender per-request.
|
||||
pub struct CachedClient {
|
||||
pub client: Client,
|
||||
pub client: ConfiguredClient,
|
||||
pub resolver: Arc<LocalhostResolver>,
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use async_trait::async_trait;
|
||||
use bytes::Bytes;
|
||||
use futures_util::StreamExt;
|
||||
use http_body::{Body as HttpBody, Frame, SizeHint};
|
||||
use reqwest::{Client, Method, Version};
|
||||
use reqwest::{Method, Version};
|
||||
use std::fmt::Display;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
@@ -411,18 +411,18 @@ pub trait HttpSender: Send + Sync {
|
||||
|
||||
/// Reqwest-based implementation of HttpSender
|
||||
pub struct ReqwestSender {
|
||||
client: Client,
|
||||
client: crate::client::ConfiguredClient,
|
||||
}
|
||||
|
||||
impl ReqwestSender {
|
||||
/// Create a new ReqwestSender with a default client
|
||||
pub fn new() -> Result<Self> {
|
||||
let client = Client::builder().build().map_err(Error::Client)?;
|
||||
let client = crate::client::ConfiguredClient::build_default()?;
|
||||
Ok(Self { client })
|
||||
}
|
||||
|
||||
/// Create a new ReqwestSender with a custom client
|
||||
pub fn with_client(client: Client) -> Self {
|
||||
/// Create a new ReqwestSender with a configured client
|
||||
pub fn with_client(client: crate::client::ConfiguredClient) -> Self {
|
||||
Self { client }
|
||||
}
|
||||
}
|
||||
@@ -444,7 +444,7 @@ impl HttpSender for ReqwestSender {
|
||||
.map_err(|e| Error::RequestError(format!("Invalid HTTP method: {}", e)))?;
|
||||
|
||||
// Build the request
|
||||
let mut req_builder = self.client.request(method, &request.url);
|
||||
let mut req_builder = self.client.inner().request(method, &request.url);
|
||||
|
||||
// Add headers
|
||||
for header in request.headers {
|
||||
@@ -513,7 +513,7 @@ impl HttpSender for ReqwestSender {
|
||||
send_event(HttpResponseEvent::Info("Sending request to server".to_string()));
|
||||
|
||||
// Map some errors to our own, so they look nicer
|
||||
let response = self.client.execute(sendable_req).await.map_err(|e| {
|
||||
let response = self.client.inner().execute(sendable_req).await.map_err(|e| {
|
||||
if reqwest::Error::is_timeout(&e) {
|
||||
Error::RequestTimeout(
|
||||
request.options.timeout.unwrap_or(Duration::from_secs(0)).clone(),
|
||||
|
||||
@@ -226,10 +226,8 @@ async fn build_body(
|
||||
|
||||
let (body, content_type) = match body_type.as_str() {
|
||||
"binary" => (build_binary_body(&body).await?, None),
|
||||
"graphql" => (build_graphql_body(&method, &body), Some("application/json".to_string())),
|
||||
"application/x-www-form-urlencoded" => {
|
||||
(build_form_body(&body), Some("application/x-www-form-urlencoded".to_string()))
|
||||
}
|
||||
"graphql" => (build_graphql_body(&method, &body), None),
|
||||
"application/x-www-form-urlencoded" => (build_form_body(&body), None),
|
||||
"multipart/form-data" => build_multipart_body(&body, &headers).await?,
|
||||
_ if body.contains_key("text") => (build_text_body(&body, body_type), None),
|
||||
t => {
|
||||
|
||||
@@ -144,9 +144,10 @@ export function duplicateModel<M extends AnyModel["model"], T extends ExtractMod
|
||||
throw new Error("Failed to duplicate null model");
|
||||
}
|
||||
|
||||
// If the model has a name, try to duplicate it with a name that doesn't conflict
|
||||
let name = "name" in model ? resolvedModelName(model) : undefined;
|
||||
if (name != null) {
|
||||
// If the model has an explicit (non-empty) name, try to duplicate it with a name that doesn't conflict.
|
||||
// When the name is empty, keep it empty so the display falls back to the URL.
|
||||
let name = "name" in model ? model.name : undefined;
|
||||
if (name) {
|
||||
const existingModels = listModels(model.model);
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const hasConflict = existingModels.some((m) => {
|
||||
|
||||
2
crates/yaak-plugins/bindings/gen_events.ts
generated
2
crates/yaak-plugins/bindings/gen_events.ts
generated
@@ -396,7 +396,7 @@ description?: string, };
|
||||
|
||||
export type GenericCompletionOption = { label: string, detail?: string, info?: string, type?: CompletionOptionType, boost?: number, };
|
||||
|
||||
export type GetCookieValueRequest = { name: string, };
|
||||
export type GetCookieValueRequest = { name: string, domain?: string | null, };
|
||||
|
||||
export type GetCookieValueResponse = { value: string | null, };
|
||||
|
||||
|
||||
@@ -307,6 +307,9 @@ pub struct ListCookieNamesResponse {
|
||||
#[ts(export, export_to = "gen_events.ts")]
|
||||
pub struct GetCookieValueRequest {
|
||||
pub name: String,
|
||||
|
||||
#[ts(optional = nullable)]
|
||||
pub domain: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
|
||||
2
crates/yaak-templates/pkg/yaak_templates.d.ts
generated
vendored
2
crates/yaak-templates/pkg/yaak_templates.d.ts
generated
vendored
@@ -1,5 +1,5 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export function unescape_template(template: string): any;
|
||||
export function escape_template(template: string): any;
|
||||
export function parse_template(template: string): any;
|
||||
export function unescape_template(template: string): any;
|
||||
|
||||
28
crates/yaak-templates/pkg/yaak_templates_bg.js
generated
28
crates/yaak-templates/pkg/yaak_templates_bg.js
generated
@@ -161,6 +161,20 @@ function takeFromExternrefTable0(idx) {
|
||||
wasm.__externref_table_dealloc(idx);
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* @param {string} template
|
||||
* @returns {any}
|
||||
*/
|
||||
export function unescape_template(template) {
|
||||
const ptr0 = passStringToWasm0(template, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
const ret = wasm.unescape_template(ptr0, len0);
|
||||
if (ret[2]) {
|
||||
throw takeFromExternrefTable0(ret[1]);
|
||||
}
|
||||
return takeFromExternrefTable0(ret[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} template
|
||||
* @returns {any}
|
||||
@@ -189,20 +203,6 @@ export function parse_template(template) {
|
||||
return takeFromExternrefTable0(ret[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} template
|
||||
* @returns {any}
|
||||
*/
|
||||
export function unescape_template(template) {
|
||||
const ptr0 = passStringToWasm0(template, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
const ret = wasm.unescape_template(ptr0, len0);
|
||||
if (ret[2]) {
|
||||
throw takeFromExternrefTable0(ret[1]);
|
||||
}
|
||||
return takeFromExternrefTable0(ret[0]);
|
||||
}
|
||||
|
||||
export function __wbg_new_405e22f390576ce2() {
|
||||
const ret = new Object();
|
||||
return ret;
|
||||
|
||||
BIN
crates/yaak-templates/pkg/yaak_templates_bg.wasm
generated
BIN
crates/yaak-templates/pkg/yaak_templates_bg.wasm
generated
Binary file not shown.
233
package-lock.json
generated
233
package-lock.json
generated
@@ -142,9 +142,9 @@
|
||||
"nanoid": "^5.0.9",
|
||||
"papaparse": "^5.4.1",
|
||||
"parse-color": "^1.0.0",
|
||||
"react": "^19.1.0",
|
||||
"react": "^19.2.0",
|
||||
"react-colorful": "^5.6.1",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-pdf": "^10.0.1",
|
||||
"react-syntax-highlighter": "^16.1.0",
|
||||
@@ -153,10 +153,10 @@
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"slugify": "^1.6.6",
|
||||
"uuid": "^11.1.0",
|
||||
"uuid": "^14.0.0",
|
||||
"vkbeautify": "^0.99.3",
|
||||
"whatwg-mimetype": "^4.0.0",
|
||||
"yaml": "^2.6.1"
|
||||
"yaml": "^2.8.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lezer/generator": "^1.8.0",
|
||||
@@ -166,12 +166,12 @@
|
||||
"@types/node": "^24.0.13",
|
||||
"@types/papaparse": "^5.3.16",
|
||||
"@types/parse-color": "^1.0.3",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@types/react": "^19.2.0",
|
||||
"@types/react-dom": "^19.2.0",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@types/whatwg-mimetype": "^3.0.2",
|
||||
"@vitejs/plugin-react": "^4.6.0",
|
||||
"@vitejs/plugin-react": "^6.0.0",
|
||||
"@yaakapp-internal/theme": "^1.0.0",
|
||||
"@yaakapp-internal/ui": "^1.0.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
@@ -181,8 +181,8 @@
|
||||
"postcss-nesting": "^13.0.2",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"vite": "^7.0.8",
|
||||
"vite-plugin-static-copy": "^3.1.2",
|
||||
"vite-plugin-svgr": "^4.3.0",
|
||||
"vite-plugin-static-copy": "^3.3.0",
|
||||
"vite-plugin-svgr": "^4.5.0",
|
||||
"vite-plugin-top-level-await": "^1.5.0",
|
||||
"vite-plugin-wasm": "^3.5.0"
|
||||
}
|
||||
@@ -213,14 +213,16 @@
|
||||
}
|
||||
},
|
||||
"apps/yaak-client/node_modules/uuid": {
|
||||
"version": "11.1.0",
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz",
|
||||
"integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/esm/bin/uuid"
|
||||
"uuid": "dist-node/bin/uuid"
|
||||
}
|
||||
},
|
||||
"apps/yaak-proxy": {
|
||||
@@ -237,13 +239,13 @@
|
||||
"classnames": "^2.5.1",
|
||||
"jotai": "^2.18.0",
|
||||
"motion": "^12.4.7",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0"
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@vitejs/plugin-react": "^4.6.0",
|
||||
"@types/react": "^19.2.0",
|
||||
"@types/react-dom": "^19.2.0",
|
||||
"@vitejs/plugin-react": "^6.0.0",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^7.0.8"
|
||||
}
|
||||
@@ -592,38 +594,6 @@
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-react-jsx-self": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
|
||||
"integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-react-jsx-source": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
|
||||
"integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
|
||||
@@ -1490,9 +1460,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@hono/node-server": {
|
||||
"version": "1.19.9",
|
||||
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz",
|
||||
"integrity": "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==",
|
||||
"version": "1.19.14",
|
||||
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz",
|
||||
"integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.14.1"
|
||||
@@ -2928,9 +2898,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/pluginutils": {
|
||||
"version": "1.0.0-beta.27",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
|
||||
"integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==",
|
||||
"version": "1.0.0-rc.7",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz",
|
||||
"integrity": "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -4457,51 +4427,6 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||
"integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.20.7",
|
||||
"@babel/types": "^7.20.7",
|
||||
"@types/babel__generator": "*",
|
||||
"@types/babel__template": "*",
|
||||
"@types/babel__traverse": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__generator": {
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
|
||||
"integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__template": {
|
||||
"version": "7.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
|
||||
"integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.1.0",
|
||||
"@babel/types": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__traverse": {
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
|
||||
"integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.28.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/chai": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
|
||||
@@ -4723,24 +4648,29 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@vitejs/plugin-react": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz",
|
||||
"integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==",
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.1.tgz",
|
||||
"integrity": "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.28.0",
|
||||
"@babel/plugin-transform-react-jsx-self": "^7.27.1",
|
||||
"@babel/plugin-transform-react-jsx-source": "^7.27.1",
|
||||
"@rolldown/pluginutils": "1.0.0-beta.27",
|
||||
"@types/babel__core": "^7.20.5",
|
||||
"react-refresh": "^0.17.0"
|
||||
"@rolldown/pluginutils": "1.0.0-rc.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.18.0 || >=16.0.0"
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
||||
"@rolldown/plugin-babel": "^0.1.7 || ^0.2.0",
|
||||
"babel-plugin-react-compiler": "^1.0.0",
|
||||
"vite": "^8.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@rolldown/plugin-babel": {
|
||||
"optional": true
|
||||
},
|
||||
"babel-plugin-react-compiler": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/expect": {
|
||||
@@ -5130,9 +5060,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@xmldom/xmldom": {
|
||||
"version": "0.9.8",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz",
|
||||
"integrity": "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==",
|
||||
"version": "0.9.10",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz",
|
||||
"integrity": "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.6"
|
||||
@@ -8942,9 +8872,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/hono": {
|
||||
"version": "4.11.10",
|
||||
"resolved": "https://registry.npmjs.org/hono/-/hono-4.11.10.tgz",
|
||||
"integrity": "sha512-kyWP5PAiMooEvGrA9jcD3IXF7ATu8+o7B3KCbPXid5se52NPqnOpM/r9qeW2heMnOekF4kqR1fXJqCYeCLKrZg==",
|
||||
"version": "4.12.18",
|
||||
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.18.tgz",
|
||||
"integrity": "sha512-RWzP96k/yv0PQfyXnWjs6zot20TqfpfsNXhOnev8d1InAxubW93L11/oNUc3tQqn2G0bSdAOBpX+2uDFHV7kdQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
@@ -13753,16 +13683,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
"version": "0.17.0",
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
|
||||
"integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-syntax-highlighter": {
|
||||
"version": "16.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-16.1.0.tgz",
|
||||
@@ -16544,22 +16464,26 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-static-copy": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-3.1.4.tgz",
|
||||
"integrity": "sha512-iCmr4GSw4eSnaB+G8zc2f4dxSuDjbkjwpuBLLGvQYR9IW7rnDzftnUjOH5p4RYR+d4GsiBqXRvzuFhs5bnzVyw==",
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-3.4.0.tgz",
|
||||
"integrity": "sha512-ekryzCw0ouAOE8tw4RvVL/dfqguXzumsV3FBKoKso4MQ1MUUrUXtl5RI4KpJQUNGqFEsg9kxl4EvDl02YtA9VQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chokidar": "^3.6.0",
|
||||
"p-map": "^7.0.3",
|
||||
"p-map": "^7.0.4",
|
||||
"picocolors": "^1.1.1",
|
||||
"tinyglobby": "^0.2.15"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.0.0 || >=20.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/sapphi-red"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
|
||||
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-svgr": {
|
||||
@@ -17086,9 +17010,9 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "2.8.2",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
|
||||
"integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
|
||||
"version": "2.8.4",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.4.tgz",
|
||||
"integrity": "sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
@@ -17257,9 +17181,9 @@
|
||||
"version": "0.2.1",
|
||||
"dependencies": {
|
||||
"@hono/mcp": "^0.2.3",
|
||||
"@hono/node-server": "^1.19.10",
|
||||
"@hono/node-server": "^1.19.13",
|
||||
"@modelcontextprotocol/sdk": "^1.26.0",
|
||||
"hono": "^4.12.4",
|
||||
"hono": "^4.12.14",
|
||||
"zod": "^3.25.76"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -17267,27 +17191,6 @@
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
},
|
||||
"plugins-external/mcp-server/node_modules/@hono/node-server": {
|
||||
"version": "1.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz",
|
||||
"integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.14.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"hono": "^4"
|
||||
}
|
||||
},
|
||||
"plugins-external/mcp-server/node_modules/hono": {
|
||||
"version": "4.12.7",
|
||||
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.7.tgz",
|
||||
"integrity": "sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"plugins/action-copy-curl": {
|
||||
"name": "@yaak/action-copy-curl",
|
||||
"version": "0.1.0"
|
||||
@@ -17370,7 +17273,7 @@
|
||||
"name": "@yaak/filter-xpath",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.9.8",
|
||||
"@xmldom/xmldom": "^0.9.10",
|
||||
"xpath": "^0.0.34"
|
||||
}
|
||||
},
|
||||
@@ -17385,7 +17288,7 @@
|
||||
"name": "@yaak/importer-insomnia",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"yaml": "^2.4.2"
|
||||
"yaml": "^2.8.3"
|
||||
}
|
||||
},
|
||||
"plugins/importer-openapi": {
|
||||
@@ -17393,7 +17296,7 @@
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"openapi-to-postmanv2": "^5.8.0",
|
||||
"yaml": "^2.4.2"
|
||||
"yaml": "^2.8.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/openapi-to-postmanv2": "^5.0.0"
|
||||
@@ -17489,25 +17392,27 @@
|
||||
"name": "@yaak/template-function-uuid",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"uuid": "^11.1.0"
|
||||
"uuid": "^14.0.0"
|
||||
}
|
||||
},
|
||||
"plugins/template-function-uuid/node_modules/uuid": {
|
||||
"version": "11.1.0",
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz",
|
||||
"integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/esm/bin/uuid"
|
||||
"uuid": "dist-node/bin/uuid"
|
||||
}
|
||||
},
|
||||
"plugins/template-function-xml": {
|
||||
"name": "@yaak/template-function-xml",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.9.8",
|
||||
"@xmldom/xmldom": "^0.9.10",
|
||||
"xpath": "^0.0.34"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -396,7 +396,7 @@ description?: string, };
|
||||
|
||||
export type GenericCompletionOption = { label: string, detail?: string, info?: string, type?: CompletionOptionType, boost?: number, };
|
||||
|
||||
export type GetCookieValueRequest = { name: string, };
|
||||
export type GetCookieValueRequest = { name: string, domain?: string | null, };
|
||||
|
||||
export type GetCookieValueResponse = { value: string | null, };
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"lib": ["es2021", "dom"],
|
||||
"declaration": true,
|
||||
"declarationDir": "./lib",
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"strict": true,
|
||||
"types": ["node"]
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@hono/mcp": "^0.2.3",
|
||||
"@hono/node-server": "^1.19.10",
|
||||
"@hono/node-server": "^1.19.13",
|
||||
"@modelcontextprotocol/sdk": "^1.26.0",
|
||||
"hono": "^4.12.4",
|
||||
"hono": "^4.12.14",
|
||||
"zod": "^3.25.76"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"dev": "yaakcli dev"
|
||||
},
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.9.8",
|
||||
"@xmldom/xmldom": "^0.9.10",
|
||||
"xpath": "^0.0.34"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,6 @@
|
||||
"test": "vp test --run tests"
|
||||
},
|
||||
"dependencies": {
|
||||
"yaml": "^2.4.2"
|
||||
"yaml": "^2.8.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"openapi-to-postmanv2": "^5.8.0",
|
||||
"yaml": "^2.4.2"
|
||||
"yaml": "^2.8.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/openapi-to-postmanv2": "^5.0.0"
|
||||
|
||||
@@ -11,12 +11,26 @@ export const plugin: PluginDefinition = {
|
||||
type: "text",
|
||||
name: "name",
|
||||
label: "Cookie Name",
|
||||
placeholder: "cookie_name",
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
name: "domain",
|
||||
label: "Domain",
|
||||
placeholder: "example.com",
|
||||
description: "Optionally filter by domain, useful if multiple cookies with the same name.",
|
||||
optional: true,
|
||||
},
|
||||
],
|
||||
async onRender(ctx: Context, args: CallTemplateFunctionArgs): Promise<string | null> {
|
||||
// The legacy name was cookie_name, but we changed it
|
||||
const name = args.values.cookie_name ?? args.values.name;
|
||||
return ctx.cookies.getValue({ name: String(name) });
|
||||
const domain = String(args.values.domain ?? "").trim();
|
||||
|
||||
return ctx.cookies.getValue({
|
||||
name: String(name),
|
||||
...(domain.length > 0 ? { domain } : {}),
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
"dev": "yaakcli dev"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": "^11.1.0"
|
||||
"uuid": "^14.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
2
plugins/template-function-xml/package.json
Executable file → Normal file
2
plugins/template-function-xml/package.json
Executable file → Normal file
@@ -11,7 +11,7 @@
|
||||
"dev": "yaakcli dev"
|
||||
},
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.9.8",
|
||||
"@xmldom/xmldom": "^0.9.10",
|
||||
"xpath": "^0.0.34"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
}
|
||||
"jsx": "react-jsx",
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["flatpak", "npm", "crates/yaak-templates/pkg"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user