mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-19 15:21:23 +02:00
Compare commits
1 Commits
omnara/pre
...
omnara/rep
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa3e6e6508 |
@@ -178,14 +178,11 @@ async fn send_http_request_inner<R: Runtime>(
|
|||||||
window.db().resolve_environments(&workspace.id, folder_id, environment_id.as_deref())?;
|
window.db().resolve_environments(&workspace.id, folder_id, environment_id.as_deref())?;
|
||||||
let request = render_http_request(&resolved, env_chain, &cb, &RenderOptions::throw()).await?;
|
let request = render_http_request(&resolved, env_chain, &cb, &RenderOptions::throw()).await?;
|
||||||
|
|
||||||
// Resolve inherited settings for this request
|
|
||||||
let resolved_settings = window.db().resolve_settings_for_http_request(&resolved)?;
|
|
||||||
|
|
||||||
// Build the sendable request using the new SendableHttpRequest type
|
// Build the sendable request using the new SendableHttpRequest type
|
||||||
let options = SendableHttpRequestOptions {
|
let options = SendableHttpRequestOptions {
|
||||||
follow_redirects: resolved_settings.follow_redirects,
|
follow_redirects: workspace.setting_follow_redirects,
|
||||||
timeout: if resolved_settings.request_timeout > 0 {
|
timeout: if workspace.setting_request_timeout > 0 {
|
||||||
Some(Duration::from_millis(resolved_settings.request_timeout.unsigned_abs() as u64))
|
Some(Duration::from_millis(workspace.setting_request_timeout.unsigned_abs() as u64))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
@@ -234,7 +231,7 @@ async fn send_http_request_inner<R: Runtime>(
|
|||||||
let client = connection_manager
|
let client = connection_manager
|
||||||
.get_client(&HttpConnectionOptions {
|
.get_client(&HttpConnectionOptions {
|
||||||
id: plugin_context.id.clone(),
|
id: plugin_context.id.clone(),
|
||||||
validate_certificates: resolved_settings.validate_certificates,
|
validate_certificates: workspace.setting_validate_certificates,
|
||||||
proxy: proxy_setting,
|
proxy: proxy_setting,
|
||||||
client_certificate,
|
client_certificate,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ async fn cmd_grpc_reflect<R: Runtime>(
|
|||||||
&uri,
|
&uri,
|
||||||
&proto_files.iter().map(|p| PathBuf::from_str(p).unwrap()).collect(),
|
&proto_files.iter().map(|p| PathBuf::from_str(p).unwrap()).collect(),
|
||||||
&metadata,
|
&metadata,
|
||||||
workspace.setting_validate_certificates.unwrap_or(true),
|
workspace.setting_validate_certificates,
|
||||||
client_certificate,
|
client_certificate,
|
||||||
skip_cache.unwrap_or(false),
|
skip_cache.unwrap_or(false),
|
||||||
)
|
)
|
||||||
@@ -327,7 +327,7 @@ async fn cmd_grpc_go<R: Runtime>(
|
|||||||
uri.as_str(),
|
uri.as_str(),
|
||||||
&proto_files.iter().map(|p| PathBuf::from_str(p).unwrap()).collect(),
|
&proto_files.iter().map(|p| PathBuf::from_str(p).unwrap()).collect(),
|
||||||
&metadata,
|
&metadata,
|
||||||
workspace.setting_validate_certificates.unwrap_or(true),
|
workspace.setting_validate_certificates,
|
||||||
client_cert.clone(),
|
client_cert.clone(),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|||||||
@@ -355,7 +355,7 @@ pub async fn cmd_ws_connect<R: Runtime>(
|
|||||||
url.as_str(),
|
url.as_str(),
|
||||||
headers,
|
headers,
|
||||||
receive_tx,
|
receive_tx,
|
||||||
workspace.setting_validate_certificates.unwrap_or(true),
|
workspace.setting_validate_certificates,
|
||||||
client_cert,
|
client_cert,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
-- Add nullable settings columns to folders (NULL = inherit from parent)
|
|
||||||
ALTER TABLE folders ADD COLUMN setting_request_timeout INTEGER DEFAULT NULL;
|
|
||||||
ALTER TABLE folders ADD COLUMN setting_validate_certificates BOOLEAN DEFAULT NULL;
|
|
||||||
ALTER TABLE folders ADD COLUMN setting_follow_redirects BOOLEAN DEFAULT NULL;
|
|
||||||
|
|
||||||
-- Add nullable settings columns to http_requests (NULL = inherit from parent)
|
|
||||||
ALTER TABLE http_requests ADD COLUMN setting_request_timeout INTEGER DEFAULT NULL;
|
|
||||||
ALTER TABLE http_requests ADD COLUMN setting_validate_certificates BOOLEAN DEFAULT NULL;
|
|
||||||
ALTER TABLE http_requests ADD COLUMN setting_follow_redirects BOOLEAN DEFAULT NULL;
|
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
|
use crate::models::HttpRequestIden::{
|
||||||
|
Authentication, AuthenticationType, Body, BodyType, CreatedAt, Description, FolderId, Headers,
|
||||||
|
Method, Name, SortPriority, UpdatedAt, Url, UrlParameters, WorkspaceId,
|
||||||
|
};
|
||||||
use crate::util::{UpdateSource, generate_prefixed_id};
|
use crate::util::{UpdateSource, generate_prefixed_id};
|
||||||
use chrono::{NaiveDateTime, Utc};
|
use chrono::{NaiveDateTime, Utc};
|
||||||
use rusqlite::Row;
|
use rusqlite::Row;
|
||||||
@@ -111,36 +115,6 @@ impl Default for EditorKeymap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Settings that can be inherited at workspace → folder → request level.
|
|
||||||
/// All fields optional - None means "inherit from parent" (or use default if at root).
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
|
|
||||||
#[serde(default, rename_all = "camelCase")]
|
|
||||||
#[ts(export, export_to = "gen_models.ts")]
|
|
||||||
pub struct HttpRequestSettingsOverride {
|
|
||||||
pub setting_validate_certificates: Option<bool>,
|
|
||||||
pub setting_follow_redirects: Option<bool>,
|
|
||||||
pub setting_request_timeout: Option<i32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resolved settings with concrete values (after inheritance + defaults applied)
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
pub struct ResolvedHttpRequestSettings {
|
|
||||||
pub validate_certificates: bool,
|
|
||||||
pub follow_redirects: bool,
|
|
||||||
pub request_timeout: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ResolvedHttpRequestSettings {
|
|
||||||
/// Default values when nothing is set in the inheritance chain
|
|
||||||
pub fn defaults() -> Self {
|
|
||||||
Self {
|
|
||||||
validate_certificates: true,
|
|
||||||
follow_redirects: true,
|
|
||||||
request_timeout: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to = "gen_models.ts")]
|
#[ts(export, export_to = "gen_models.ts")]
|
||||||
@@ -323,10 +297,12 @@ pub struct Workspace {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
pub encryption_key_challenge: Option<String>,
|
pub encryption_key_challenge: Option<String>,
|
||||||
|
|
||||||
// Inheritable settings (Option = can be null, defaults applied at resolution time)
|
// Settings
|
||||||
pub setting_validate_certificates: Option<bool>,
|
#[serde(default = "default_true")]
|
||||||
pub setting_follow_redirects: Option<bool>,
|
pub setting_validate_certificates: bool,
|
||||||
pub setting_request_timeout: Option<i32>,
|
#[serde(default = "default_true")]
|
||||||
|
pub setting_follow_redirects: bool,
|
||||||
|
pub setting_request_timeout: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UpsertModelInfo for Workspace {
|
impl UpsertModelInfo for Workspace {
|
||||||
@@ -750,11 +726,6 @@ pub struct Folder {
|
|||||||
pub headers: Vec<HttpRequestHeader>,
|
pub headers: Vec<HttpRequestHeader>,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub sort_priority: f64,
|
pub sort_priority: f64,
|
||||||
|
|
||||||
// Inheritable settings (Option = null means inherit from parent)
|
|
||||||
pub setting_validate_certificates: Option<bool>,
|
|
||||||
pub setting_follow_redirects: Option<bool>,
|
|
||||||
pub setting_request_timeout: Option<i32>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UpsertModelInfo for Folder {
|
impl UpsertModelInfo for Folder {
|
||||||
@@ -794,9 +765,6 @@ impl UpsertModelInfo for Folder {
|
|||||||
(Description, self.description.into()),
|
(Description, self.description.into()),
|
||||||
(Name, self.name.trim().into()),
|
(Name, self.name.trim().into()),
|
||||||
(SortPriority, self.sort_priority.into()),
|
(SortPriority, self.sort_priority.into()),
|
||||||
(SettingValidateCertificates, self.setting_validate_certificates.into()),
|
|
||||||
(SettingFollowRedirects, self.setting_follow_redirects.into()),
|
|
||||||
(SettingRequestTimeout, self.setting_request_timeout.into()),
|
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -810,9 +778,6 @@ impl UpsertModelInfo for Folder {
|
|||||||
FolderIden::Description,
|
FolderIden::Description,
|
||||||
FolderIden::FolderId,
|
FolderIden::FolderId,
|
||||||
FolderIden::SortPriority,
|
FolderIden::SortPriority,
|
||||||
FolderIden::SettingValidateCertificates,
|
|
||||||
FolderIden::SettingFollowRedirects,
|
|
||||||
FolderIden::SettingRequestTimeout,
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -835,9 +800,6 @@ impl UpsertModelInfo for Folder {
|
|||||||
headers: serde_json::from_str(&headers).unwrap_or_default(),
|
headers: serde_json::from_str(&headers).unwrap_or_default(),
|
||||||
authentication_type: row.get("authentication_type")?,
|
authentication_type: row.get("authentication_type")?,
|
||||||
authentication: serde_json::from_str(&authentication).unwrap_or_default(),
|
authentication: serde_json::from_str(&authentication).unwrap_or_default(),
|
||||||
setting_validate_certificates: row.get("setting_validate_certificates")?,
|
|
||||||
setting_follow_redirects: row.get("setting_follow_redirects")?,
|
|
||||||
setting_request_timeout: row.get("setting_request_timeout")?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -895,11 +857,6 @@ pub struct HttpRequest {
|
|||||||
pub sort_priority: f64,
|
pub sort_priority: f64,
|
||||||
pub url: String,
|
pub url: String,
|
||||||
pub url_parameters: Vec<HttpUrlParameter>,
|
pub url_parameters: Vec<HttpUrlParameter>,
|
||||||
|
|
||||||
// Inheritable settings (Option = null means inherit from parent)
|
|
||||||
pub setting_validate_certificates: Option<bool>,
|
|
||||||
pub setting_follow_redirects: Option<bool>,
|
|
||||||
pub setting_request_timeout: Option<i32>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UpsertModelInfo for HttpRequest {
|
impl UpsertModelInfo for HttpRequest {
|
||||||
@@ -927,7 +884,6 @@ impl UpsertModelInfo for HttpRequest {
|
|||||||
self,
|
self,
|
||||||
source: &UpdateSource,
|
source: &UpdateSource,
|
||||||
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
||||||
use HttpRequestIden::*;
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
(CreatedAt, upsert_date(source, self.created_at)),
|
(CreatedAt, upsert_date(source, self.created_at)),
|
||||||
(UpdatedAt, upsert_date(source, self.updated_at)),
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
||||||
@@ -944,14 +900,10 @@ impl UpsertModelInfo for HttpRequest {
|
|||||||
(AuthenticationType, self.authentication_type.into()),
|
(AuthenticationType, self.authentication_type.into()),
|
||||||
(Headers, serde_json::to_string(&self.headers)?.into()),
|
(Headers, serde_json::to_string(&self.headers)?.into()),
|
||||||
(SortPriority, self.sort_priority.into()),
|
(SortPriority, self.sort_priority.into()),
|
||||||
(SettingValidateCertificates, self.setting_validate_certificates.into()),
|
|
||||||
(SettingFollowRedirects, self.setting_follow_redirects.into()),
|
|
||||||
(SettingRequestTimeout, self.setting_request_timeout.into()),
|
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_columns() -> Vec<impl IntoIden> {
|
fn update_columns() -> Vec<impl IntoIden> {
|
||||||
use HttpRequestIden::*;
|
|
||||||
vec![
|
vec![
|
||||||
UpdatedAt,
|
UpdatedAt,
|
||||||
WorkspaceId,
|
WorkspaceId,
|
||||||
@@ -967,9 +919,6 @@ impl UpsertModelInfo for HttpRequest {
|
|||||||
Url,
|
Url,
|
||||||
UrlParameters,
|
UrlParameters,
|
||||||
SortPriority,
|
SortPriority,
|
||||||
SettingValidateCertificates,
|
|
||||||
SettingFollowRedirects,
|
|
||||||
SettingRequestTimeout,
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -996,9 +945,6 @@ impl UpsertModelInfo for HttpRequest {
|
|||||||
sort_priority: row.get("sort_priority")?,
|
sort_priority: row.get("sort_priority")?,
|
||||||
url: row.get("url")?,
|
url: row.get("url")?,
|
||||||
url_parameters: serde_json::from_str(url_parameters.as_str()).unwrap_or_default(),
|
url_parameters: serde_json::from_str(url_parameters.as_str()).unwrap_or_default(),
|
||||||
setting_validate_certificates: row.get("setting_validate_certificates")?,
|
|
||||||
setting_follow_redirects: row.get("setting_follow_redirects")?,
|
|
||||||
setting_request_timeout: row.get("setting_request_timeout")?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::db_context::DbContext;
|
use crate::db_context::DbContext;
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use crate::models::{Folder, FolderIden, HttpRequest, HttpRequestHeader, HttpRequestIden, ResolvedHttpRequestSettings};
|
use crate::models::{Folder, FolderIden, HttpRequest, HttpRequestHeader, HttpRequestIden};
|
||||||
use crate::util::UpdateSource;
|
use crate::util::UpdateSource;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
@@ -103,79 +103,4 @@ impl<'a> DbContext<'a> {
|
|||||||
}
|
}
|
||||||
Ok(children)
|
Ok(children)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve settings for an HTTP request by walking the inheritance chain:
|
|
||||||
/// Workspace → Folder(s) → Request
|
|
||||||
/// Last non-None value wins, then defaults are applied.
|
|
||||||
pub fn resolve_settings_for_http_request(
|
|
||||||
&self,
|
|
||||||
http_request: &HttpRequest,
|
|
||||||
) -> Result<ResolvedHttpRequestSettings> {
|
|
||||||
let workspace = self.get_workspace(&http_request.workspace_id)?;
|
|
||||||
|
|
||||||
// Start with None for all settings
|
|
||||||
let mut validate_certs: Option<bool> = None;
|
|
||||||
let mut follow_redirects: Option<bool> = None;
|
|
||||||
let mut timeout: Option<i32> = None;
|
|
||||||
|
|
||||||
// Apply workspace settings
|
|
||||||
if workspace.setting_validate_certificates.is_some() {
|
|
||||||
validate_certs = workspace.setting_validate_certificates;
|
|
||||||
}
|
|
||||||
if workspace.setting_follow_redirects.is_some() {
|
|
||||||
follow_redirects = workspace.setting_follow_redirects;
|
|
||||||
}
|
|
||||||
if workspace.setting_request_timeout.is_some() {
|
|
||||||
timeout = workspace.setting_request_timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply folder chain settings (root first, immediate parent last)
|
|
||||||
if let Some(folder_id) = &http_request.folder_id {
|
|
||||||
let folders = self.get_folder_ancestors(folder_id)?;
|
|
||||||
for folder in folders {
|
|
||||||
if folder.setting_validate_certificates.is_some() {
|
|
||||||
validate_certs = folder.setting_validate_certificates;
|
|
||||||
}
|
|
||||||
if folder.setting_follow_redirects.is_some() {
|
|
||||||
follow_redirects = folder.setting_follow_redirects;
|
|
||||||
}
|
|
||||||
if folder.setting_request_timeout.is_some() {
|
|
||||||
timeout = folder.setting_request_timeout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply request-level settings (highest priority)
|
|
||||||
if http_request.setting_validate_certificates.is_some() {
|
|
||||||
validate_certs = http_request.setting_validate_certificates;
|
|
||||||
}
|
|
||||||
if http_request.setting_follow_redirects.is_some() {
|
|
||||||
follow_redirects = http_request.setting_follow_redirects;
|
|
||||||
}
|
|
||||||
if http_request.setting_request_timeout.is_some() {
|
|
||||||
timeout = http_request.setting_request_timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply defaults for anything still None
|
|
||||||
Ok(ResolvedHttpRequestSettings {
|
|
||||||
validate_certificates: validate_certs.unwrap_or(true),
|
|
||||||
follow_redirects: follow_redirects.unwrap_or(true),
|
|
||||||
request_timeout: timeout.unwrap_or(0),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get folder ancestors in order from root to immediate parent
|
|
||||||
fn get_folder_ancestors(&self, folder_id: &str) -> Result<Vec<Folder>> {
|
|
||||||
let mut ancestors = Vec::new();
|
|
||||||
let mut current_id = Some(folder_id.to_string());
|
|
||||||
|
|
||||||
while let Some(id) = current_id {
|
|
||||||
let folder = self.get_folder(&id)?;
|
|
||||||
current_id = folder.folder_id.clone();
|
|
||||||
ancestors.push(folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
ancestors.reverse(); // Root first, immediate parent last
|
|
||||||
Ok(ancestors)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ impl<'a> DbContext<'a> {
|
|||||||
workspaces.push(self.upsert_workspace(
|
workspaces.push(self.upsert_workspace(
|
||||||
&Workspace {
|
&Workspace {
|
||||||
name: "Yaak".to_string(),
|
name: "Yaak".to_string(),
|
||||||
setting_follow_redirects: Some(true),
|
setting_follow_redirects: true,
|
||||||
setting_validate_certificates: Some(true),
|
setting_validate_certificates: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
&UpdateSource::Background,
|
&UpdateSource::Background,
|
||||||
@@ -65,28 +65,7 @@ impl<'a> DbContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn upsert_workspace(&self, w: &Workspace, source: &UpdateSource) -> Result<Workspace> {
|
pub fn upsert_workspace(&self, w: &Workspace, source: &UpdateSource) -> Result<Workspace> {
|
||||||
let mut workspace = w.clone();
|
self.upsert(w, source)
|
||||||
|
|
||||||
// Add default headers only for NEW workspaces (empty ID means insert, not update)
|
|
||||||
// This prevents re-adding headers if a user intentionally removes all headers
|
|
||||||
if workspace.id.is_empty() && workspace.headers.is_empty() {
|
|
||||||
workspace.headers = vec![
|
|
||||||
HttpRequestHeader {
|
|
||||||
enabled: true,
|
|
||||||
name: "User-Agent".to_string(),
|
|
||||||
value: "yaak".to_string(),
|
|
||||||
id: None,
|
|
||||||
},
|
|
||||||
HttpRequestHeader {
|
|
||||||
enabled: true,
|
|
||||||
name: "Accept".to_string(),
|
|
||||||
value: "*/*".to_string(),
|
|
||||||
id: None,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
self.upsert(&workspace, source)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_auth_for_workspace(
|
pub fn resolve_auth_for_workspace(
|
||||||
|
|||||||
6
crates/yaak-plugins/bindings/gen_events.ts
generated
6
crates/yaak-plugins/bindings/gen_events.ts
generated
File diff suppressed because one or more lines are too long
@@ -157,6 +157,9 @@ pub enum InternalEventPayload {
|
|||||||
PromptTextRequest(PromptTextRequest),
|
PromptTextRequest(PromptTextRequest),
|
||||||
PromptTextResponse(PromptTextResponse),
|
PromptTextResponse(PromptTextResponse),
|
||||||
|
|
||||||
|
PromptFormRequest(PromptFormRequest),
|
||||||
|
PromptFormResponse(PromptFormResponse),
|
||||||
|
|
||||||
WindowInfoRequest(WindowInfoRequest),
|
WindowInfoRequest(WindowInfoRequest),
|
||||||
WindowInfoResponse(WindowInfoResponse),
|
WindowInfoResponse(WindowInfoResponse),
|
||||||
|
|
||||||
@@ -571,6 +574,28 @@ pub struct PromptTextResponse {
|
|||||||
pub value: Option<String>,
|
pub value: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(default, rename_all = "camelCase")]
|
||||||
|
#[ts(export, export_to = "gen_events.ts")]
|
||||||
|
pub struct PromptFormRequest {
|
||||||
|
pub id: String,
|
||||||
|
pub title: String,
|
||||||
|
#[ts(optional)]
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub inputs: Vec<FormInput>,
|
||||||
|
#[ts(optional)]
|
||||||
|
pub confirm_text: Option<String>,
|
||||||
|
#[ts(optional)]
|
||||||
|
pub cancel_text: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(default, rename_all = "camelCase")]
|
||||||
|
#[ts(export, export_to = "gen_events.ts")]
|
||||||
|
pub struct PromptFormResponse {
|
||||||
|
pub values: Option<HashMap<String, JsonPrimitive>>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to = "gen_events.ts")]
|
#[ts(export, export_to = "gen_events.ts")]
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -11,6 +11,8 @@ import type {
|
|||||||
ListHttpRequestsRequest,
|
ListHttpRequestsRequest,
|
||||||
ListHttpRequestsResponse,
|
ListHttpRequestsResponse,
|
||||||
OpenWindowRequest,
|
OpenWindowRequest,
|
||||||
|
PromptFormRequest,
|
||||||
|
PromptFormResponse,
|
||||||
PromptTextRequest,
|
PromptTextRequest,
|
||||||
PromptTextResponse,
|
PromptTextResponse,
|
||||||
RenderGrpcRequestRequest,
|
RenderGrpcRequestRequest,
|
||||||
@@ -37,6 +39,7 @@ export interface Context {
|
|||||||
};
|
};
|
||||||
prompt: {
|
prompt: {
|
||||||
text(args: PromptTextRequest): Promise<PromptTextResponse['value']>;
|
text(args: PromptTextRequest): Promise<PromptTextResponse['value']>;
|
||||||
|
form(args: PromptFormRequest): Promise<PromptFormResponse['values']>;
|
||||||
};
|
};
|
||||||
store: {
|
store: {
|
||||||
set<T>(key: string, value: T): Promise<void>;
|
set<T>(key: string, value: T): Promise<void>;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import type {
|
|||||||
ListHttpRequestsResponse,
|
ListHttpRequestsResponse,
|
||||||
ListWorkspacesResponse,
|
ListWorkspacesResponse,
|
||||||
PluginContext,
|
PluginContext,
|
||||||
|
PromptFormResponse,
|
||||||
PromptTextResponse,
|
PromptTextResponse,
|
||||||
RenderGrpcRequestResponse,
|
RenderGrpcRequestResponse,
|
||||||
RenderHttpRequestResponse,
|
RenderHttpRequestResponse,
|
||||||
@@ -661,6 +662,13 @@ export class PluginInstance {
|
|||||||
});
|
});
|
||||||
return reply.value;
|
return reply.value;
|
||||||
},
|
},
|
||||||
|
form: async (args) => {
|
||||||
|
const reply: PromptFormResponse = await this.#sendForReply(context, {
|
||||||
|
type: 'prompt_form_request',
|
||||||
|
...args,
|
||||||
|
});
|
||||||
|
return reply.values;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
httpResponse: {
|
httpResponse: {
|
||||||
find: async (args) => {
|
find: async (args) => {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { stringToColor } from './color';
|
|||||||
import { generateId } from './generateId';
|
import { generateId } from './generateId';
|
||||||
import { jotaiStore } from './jotai';
|
import { jotaiStore } from './jotai';
|
||||||
import { showPrompt } from './prompt';
|
import { showPrompt } from './prompt';
|
||||||
|
import { showPromptForm } from './prompt-form';
|
||||||
import { invokeCmd } from './tauri';
|
import { invokeCmd } from './tauri';
|
||||||
import { showToast } from './toast';
|
import { showToast } from './toast';
|
||||||
|
|
||||||
@@ -47,6 +48,27 @@ export function initGlobalListeners() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
await emit(event.id, result);
|
await emit(event.id, result);
|
||||||
|
} else if (event.payload.type === 'prompt_form_request') {
|
||||||
|
const values = await showPromptForm({
|
||||||
|
id: event.payload.id,
|
||||||
|
title: event.payload.title,
|
||||||
|
description: event.payload.description,
|
||||||
|
inputs: event.payload.inputs,
|
||||||
|
confirmText: event.payload.confirmText,
|
||||||
|
cancelText: event.payload.cancelText,
|
||||||
|
});
|
||||||
|
const result: InternalEvent = {
|
||||||
|
id: generateId(),
|
||||||
|
replyId: event.id,
|
||||||
|
pluginName: event.pluginName,
|
||||||
|
pluginRefId: event.pluginRefId,
|
||||||
|
context: event.context,
|
||||||
|
payload: {
|
||||||
|
type: 'prompt_form_response',
|
||||||
|
values,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
await emit(event.id, result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user