Refactor commands and DB

This commit is contained in:
Gregory Schier
2024-02-01 02:29:24 -08:00
parent 3ab1f5308c
commit c655557313
46 changed files with 534 additions and 540 deletions

View File

@@ -1,8 +1,7 @@
use prost::Message;
use prost_reflect::{DynamicMessage, SerializeOptions}; use prost_reflect::{DynamicMessage, SerializeOptions};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Deserializer; use serde_json::Deserializer;
use tokio_stream::{Stream, StreamExt}; use tokio_stream::Stream;
use tonic::transport::Uri; use tonic::transport::Uri;
use tonic::{IntoRequest, Response, Streaming}; use tonic::{IntoRequest, Response, Streaming};
@@ -77,7 +76,7 @@ impl Stream for ClientStream {
fn poll_next( fn poll_next(
self: std::pin::Pin<&mut Self>, self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>, _cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Option<Self::Item>> { ) -> std::task::Poll<Option<Self::Item>> {
println!("poll_next"); println!("poll_next");
todo!() todo!()

View File

@@ -3,8 +3,7 @@ use serde::{Deserialize, Serialize};
use serde_json::json; use serde_json::json;
use sqlx::{Pool, Sqlite}; use sqlx::{Pool, Sqlite};
use sqlx::types::JsonValue; use sqlx::types::JsonValue;
use tauri::{AppHandle, Manager, State}; use tauri::{AppHandle, Manager};
use tokio::sync::Mutex;
use crate::{is_dev, models}; use crate::{is_dev, models};
@@ -126,17 +125,15 @@ pub struct LaunchEventInfo {
pub num_launches: i32, pub num_launches: i32,
} }
pub async fn track_launch_event(app_handle: &AppHandle) -> LaunchEventInfo { pub async fn track_launch_event(app_handle: &AppHandle, db: &Pool<Sqlite>) -> LaunchEventInfo {
let namespace = "analytics"; let namespace = "analytics";
let last_tracked_version_key = "last_tracked_version"; let last_tracked_version_key = "last_tracked_version";
let db_instance: State<'_, Mutex<Pool<Sqlite>>> = app_handle.state();
let pool = &*db_instance.lock().await;
let mut info = LaunchEventInfo::default(); let mut info = LaunchEventInfo::default();
info.num_launches = models::get_key_value_int(namespace, "num_launches", 0, pool).await + 1; info.num_launches = models::get_key_value_int(db, namespace, "num_launches", 0).await + 1;
info.previous_version = info.previous_version =
models::get_key_value_string(namespace, last_tracked_version_key, "", pool).await; models::get_key_value_string(db, namespace, last_tracked_version_key, "").await;
info.current_version = app_handle.package_info().version.to_string(); info.current_version = app_handle.package_info().version.to_string();
if info.previous_version.is_empty() { if info.previous_version.is_empty() {
@@ -167,19 +164,18 @@ pub async fn track_launch_event(app_handle: &AppHandle) -> LaunchEventInfo {
AnalyticsAction::Launch, AnalyticsAction::Launch,
Some(json!({ "num_launches": info.num_launches })), Some(json!({ "num_launches": info.num_launches })),
) )
.await; .await;
// Update key values // Update key values
models::set_key_value_string( models::set_key_value_string(
db,
namespace, namespace,
last_tracked_version_key, last_tracked_version_key,
info.current_version.as_str(), info.current_version.as_str(),
pool,
) )
.await; .await;
models::set_key_value_int(namespace, "num_launches", info.num_launches, pool).await; models::set_key_value_int(db, namespace, "num_launches", info.num_launches).await;
info info
} }

View File

@@ -19,16 +19,16 @@ use tauri::{AppHandle, Wry};
use crate::{emit_side_effect, models, render, response_err}; use crate::{emit_side_effect, models, render, response_err};
pub async fn send_http_request( pub async fn send_http_request(
app_handle: &AppHandle<Wry>,
db: &Pool<Sqlite>,
request: models::HttpRequest, request: models::HttpRequest,
response: &models::HttpResponse, response: &models::HttpResponse,
environment: Option<models::Environment>, environment: Option<models::Environment>,
cookie_jar: Option<models::CookieJar>, cookie_jar: Option<models::CookieJar>,
app_handle: &AppHandle<Wry>,
pool: &Pool<Sqlite>,
download_path: Option<PathBuf>, download_path: Option<PathBuf>,
) -> Result<models::HttpResponse, String> { ) -> Result<models::HttpResponse, String> {
let environment_ref = environment.as_ref(); let environment_ref = environment.as_ref();
let workspace = models::get_workspace(&request.workspace_id, pool) let workspace = models::get_workspace(db, &request.workspace_id)
.await .await
.expect("Failed to get Workspace"); .expect("Failed to get Workspace");
@@ -88,7 +88,7 @@ pub async fn send_http_request(
let url = match Url::from_str(url_string.as_str()) { let url = match Url::from_str(url_string.as_str()) {
Ok(u) => u, Ok(u) => u,
Err(e) => { Err(e) => {
return response_err(response, e.to_string(), app_handle, pool).await; return response_err(response, e.to_string(), app_handle, db).await;
} }
}; };
@@ -293,7 +293,7 @@ pub async fn send_http_request(
let sendable_req = match request_builder.build() { let sendable_req = match request_builder.build() {
Ok(r) => r, Ok(r) => r,
Err(e) => { Err(e) => {
return response_err(response, e.to_string(), app_handle, pool).await; return response_err(response, e.to_string(), app_handle, db).await;
} }
}; };
@@ -362,7 +362,7 @@ pub async fn send_http_request(
); );
} }
response = models::update_response_if_id(&response, pool) response = models::update_response_if_id(db, &response)
.await .await
.expect("Failed to update response"); .expect("Failed to update response");
if !request.id.is_empty() { if !request.id.is_empty() {
@@ -397,7 +397,7 @@ pub async fn send_http_request(
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
); );
cookie_jar.cookies = json_cookies; cookie_jar.cookies = json_cookies;
match models::upsert_cookie_jar(pool, &cookie_jar).await { match models::upsert_cookie_jar(db, &cookie_jar).await {
Ok(updated_jar) => { Ok(updated_jar) => {
emit_side_effect(app_handle, "updated_model", &updated_jar); emit_side_effect(app_handle, "updated_model", &updated_jar);
} }
@@ -409,6 +409,6 @@ pub async fn send_http_request(
Ok(response) Ok(response)
} }
Err(e) => response_err(response, e.to_string(), app_handle, pool).await, Err(e) => response_err(response, e.to_string(), app_handle, db).await,
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -58,9 +58,7 @@ impl Workspace {
} }
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)] #[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
pub struct CookieX { pub struct CookieX {}
}
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)] #[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
#[serde(default, rename_all = "camelCase")] #[serde(default, rename_all = "camelCase")]
@@ -260,32 +258,32 @@ pub struct KeyValue {
} }
pub async fn set_key_value_string( pub async fn set_key_value_string(
db: &Pool<Sqlite>,
namespace: &str, namespace: &str,
key: &str, key: &str,
value: &str, value: &str,
pool: &Pool<Sqlite>,
) -> (KeyValue, bool) { ) -> (KeyValue, bool) {
let encoded = serde_json::to_string(value); let encoded = serde_json::to_string(value);
set_key_value_raw(namespace, key, &encoded.unwrap(), pool).await set_key_value_raw(db, namespace, key, &encoded.unwrap()).await
} }
pub async fn set_key_value_int( pub async fn set_key_value_int(
db: &Pool<Sqlite>,
namespace: &str, namespace: &str,
key: &str, key: &str,
value: i32, value: i32,
pool: &Pool<Sqlite>,
) -> (KeyValue, bool) { ) -> (KeyValue, bool) {
let encoded = serde_json::to_string(&value); let encoded = serde_json::to_string(&value);
set_key_value_raw(namespace, key, &encoded.unwrap(), pool).await set_key_value_raw(db, namespace, key, &encoded.unwrap()).await
} }
pub async fn get_key_value_string( pub async fn get_key_value_string(
db: &Pool<Sqlite>,
namespace: &str, namespace: &str,
key: &str, key: &str,
default: &str, default: &str,
pool: &Pool<Sqlite>,
) -> String { ) -> String {
match get_key_value_raw(namespace, key, pool).await { match get_key_value_raw(db, namespace, key).await {
None => default.to_string(), None => default.to_string(),
Some(v) => { Some(v) => {
let result = serde_json::from_str(&v.value); let result = serde_json::from_str(&v.value);
@@ -296,17 +294,12 @@ pub async fn get_key_value_string(
default.to_string() default.to_string()
} }
} }
}, }
} }
} }
pub async fn get_key_value_int( pub async fn get_key_value_int(db: &Pool<Sqlite>, namespace: &str, key: &str, default: i32) -> i32 {
namespace: &str, match get_key_value_raw(db, namespace, key).await {
key: &str,
default: i32,
pool: &Pool<Sqlite>,
) -> i32 {
match get_key_value_raw(namespace, key, pool).await {
None => default.clone(), None => default.clone(),
Some(v) => { Some(v) => {
let result = serde_json::from_str(&v.value); let result = serde_json::from_str(&v.value);
@@ -317,17 +310,17 @@ pub async fn get_key_value_int(
default.clone() default.clone()
} }
} }
}, }
} }
} }
pub async fn set_key_value_raw( pub async fn set_key_value_raw(
db: &Pool<Sqlite>,
namespace: &str, namespace: &str,
key: &str, key: &str,
value: &str, value: &str,
pool: &Pool<Sqlite>,
) -> (KeyValue, bool) { ) -> (KeyValue, bool) {
let existing = get_key_value_raw(namespace, key, pool).await; let existing = get_key_value_raw(db, namespace, key).await;
sqlx::query!( sqlx::query!(
r#" r#"
INSERT INTO key_values (namespace, key, value) INSERT INTO key_values (namespace, key, value)
@@ -339,17 +332,17 @@ pub async fn set_key_value_raw(
key, key,
value, value,
) )
.execute(pool) .execute(db)
.await .await
.expect("Failed to insert key value"); .expect("Failed to insert key value");
let kv = get_key_value_raw(namespace, key, pool) let kv = get_key_value_raw(db, namespace, key)
.await .await
.expect("Failed to get key value"); .expect("Failed to get key value");
(kv, existing.is_none()) (kv, existing.is_none())
} }
pub async fn get_key_value_raw(namespace: &str, key: &str, pool: &Pool<Sqlite>) -> Option<KeyValue> { pub async fn get_key_value_raw(db: &Pool<Sqlite>, namespace: &str, key: &str) -> Option<KeyValue> {
sqlx::query_as!( sqlx::query_as!(
KeyValue, KeyValue,
r#" r#"
@@ -360,12 +353,12 @@ pub async fn get_key_value_raw(namespace: &str, key: &str, pool: &Pool<Sqlite>)
namespace, namespace,
key, key,
) )
.fetch_one(pool) .fetch_one(db)
.await .await
.ok() .ok()
} }
pub async fn find_workspaces(pool: &Pool<Sqlite>) -> Result<Vec<Workspace>, sqlx::Error> { pub async fn find_workspaces(db: &Pool<Sqlite>) -> Result<Vec<Workspace>, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
Workspace, Workspace,
r#" r#"
@@ -383,11 +376,11 @@ pub async fn find_workspaces(pool: &Pool<Sqlite>) -> Result<Vec<Workspace>, sqlx
FROM workspaces FROM workspaces
"#, "#,
) )
.fetch_all(pool) .fetch_all(db)
.await .await
} }
pub async fn get_workspace(id: &str, pool: &Pool<Sqlite>) -> Result<Workspace, sqlx::Error> { pub async fn get_workspace(db: &Pool<Sqlite>, id: &str) -> Result<Workspace, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
Workspace, Workspace,
r#" r#"
@@ -406,12 +399,12 @@ pub async fn get_workspace(id: &str, pool: &Pool<Sqlite>) -> Result<Workspace, s
"#, "#,
id, id,
) )
.fetch_one(pool) .fetch_one(db)
.await .await
} }
pub async fn delete_workspace(id: &str, pool: &Pool<Sqlite>) -> Result<Workspace, sqlx::Error> { pub async fn delete_workspace(db: &Pool<Sqlite>, id: &str) -> Result<Workspace, sqlx::Error> {
let workspace = get_workspace(id, pool).await?; let workspace = get_workspace(db, id).await?;
let _ = sqlx::query!( let _ = sqlx::query!(
r#" r#"
DELETE FROM workspaces DELETE FROM workspaces
@@ -419,17 +412,17 @@ pub async fn delete_workspace(id: &str, pool: &Pool<Sqlite>) -> Result<Workspace
"#, "#,
id, id,
) )
.execute(pool) .execute(db)
.await; .await;
for r in find_responses_by_workspace_id(id, pool).await? { for r in find_responses_by_workspace_id(db, id).await? {
delete_response(&r.id, pool).await?; delete_response(db, &r.id).await?;
} }
Ok(workspace) Ok(workspace)
} }
pub async fn get_cookie_jar(id: &str, pool: &Pool<Sqlite>) -> Result<CookieJar, sqlx::Error> { pub async fn get_cookie_jar(db: &Pool<Sqlite>, id: &str) -> Result<CookieJar, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
CookieJar, CookieJar,
r#" r#"
@@ -445,11 +438,14 @@ pub async fn get_cookie_jar(id: &str, pool: &Pool<Sqlite>) -> Result<CookieJar,
"#, "#,
id, id,
) )
.fetch_one(pool) .fetch_one(db)
.await .await
} }
pub async fn find_cookie_jars(workspace_id: &str, pool: &Pool<Sqlite>) -> Result<Vec<CookieJar>, sqlx::Error> { pub async fn find_cookie_jars(
db: &Pool<Sqlite>,
workspace_id: &str,
) -> Result<Vec<CookieJar>, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
CookieJar, CookieJar,
r#" r#"
@@ -465,12 +461,12 @@ pub async fn find_cookie_jars(workspace_id: &str, pool: &Pool<Sqlite>) -> Result
"#, "#,
workspace_id, workspace_id,
) )
.fetch_all(pool) .fetch_all(db)
.await .await
} }
pub async fn delete_cookie_jar(id: &str, pool: &Pool<Sqlite>) -> Result<CookieJar, sqlx::Error> { pub async fn delete_cookie_jar(db: &Pool<Sqlite>, id: &str) -> Result<CookieJar, sqlx::Error> {
let cookie_jar = get_cookie_jar(id, pool).await?; let cookie_jar = get_cookie_jar(db, id).await?;
let _ = sqlx::query!( let _ = sqlx::query!(
r#" r#"
@@ -479,14 +475,14 @@ pub async fn delete_cookie_jar(id: &str, pool: &Pool<Sqlite>) -> Result<CookieJa
"#, "#,
id, id,
) )
.execute(pool) .execute(db)
.await; .await;
Ok(cookie_jar) Ok(cookie_jar)
} }
pub async fn upsert_cookie_jar( pub async fn upsert_cookie_jar(
pool: &Pool<Sqlite>, db: &Pool<Sqlite>,
cookie_jar: &CookieJar, cookie_jar: &CookieJar,
) -> Result<CookieJar, sqlx::Error> { ) -> Result<CookieJar, sqlx::Error> {
let id = match cookie_jar.id.as_str() { let id = match cookie_jar.id.as_str() {
@@ -513,15 +509,15 @@ pub async fn upsert_cookie_jar(
trimmed_name, trimmed_name,
cookie_jar.cookies, cookie_jar.cookies,
) )
.execute(pool) .execute(db)
.await?; .await?;
get_cookie_jar(&id, pool).await get_cookie_jar(db, &id).await
} }
pub async fn find_environments( pub async fn find_environments(
db: &Pool<Sqlite>,
workspace_id: &str, workspace_id: &str,
pool: &Pool<Sqlite>,
) -> Result<Vec<Environment>, sqlx::Error> { ) -> Result<Vec<Environment>, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
Environment, Environment,
@@ -533,12 +529,12 @@ pub async fn find_environments(
"#, "#,
workspace_id, workspace_id,
) )
.fetch_all(pool) .fetch_all(db)
.await .await
} }
pub async fn delete_environment(id: &str, pool: &Pool<Sqlite>) -> Result<Environment, sqlx::Error> { pub async fn delete_environment(db: &Pool<Sqlite>, id: &str) -> Result<Environment, sqlx::Error> {
let env = get_environment(id, pool).await?; let env = get_environment(db, id).await?;
let _ = sqlx::query!( let _ = sqlx::query!(
r#" r#"
DELETE FROM environments DELETE FROM environments
@@ -546,13 +542,13 @@ pub async fn delete_environment(id: &str, pool: &Pool<Sqlite>) -> Result<Environ
"#, "#,
id, id,
) )
.execute(pool) .execute(db)
.await; .await;
Ok(env) Ok(env)
} }
async fn get_settings(pool: &Pool<Sqlite>) -> Result<Settings, sqlx::Error> { async fn get_settings(db: &Pool<Sqlite>) -> Result<Settings, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
Settings, Settings,
r#" r#"
@@ -568,28 +564,30 @@ async fn get_settings(pool: &Pool<Sqlite>) -> Result<Settings, sqlx::Error> {
WHERE id = 'default' WHERE id = 'default'
"#, "#,
) )
.fetch_one(pool) .fetch_one(db)
.await .await
} }
pub async fn get_or_create_settings(pool: &Pool<Sqlite>) -> Settings { pub async fn get_or_create_settings(db: &Pool<Sqlite>) -> Settings {
if let Ok(settings) = get_settings(pool).await { if let Ok(settings) = get_settings(db).await {
settings return settings;
} else { }
sqlx::query!(
r#" sqlx::query!(
r#"
INSERT INTO settings (id) INSERT INTO settings (id)
VALUES ('default') VALUES ('default')
"#, "#,
) )
.execute(pool) .execute(db)
.await.expect("Failed to insert settings"); .await
get_settings(pool).await.expect("Failed to get settings") .expect("Failed to insert settings");
}
get_settings(db).await.expect("Failed to get settings")
} }
pub async fn update_settings( pub async fn update_settings(
pool: &Pool<Sqlite>, db: &Pool<Sqlite>,
settings: Settings, settings: Settings,
) -> Result<Settings, sqlx::Error> { ) -> Result<Settings, sqlx::Error> {
sqlx::query!( sqlx::query!(
@@ -604,13 +602,13 @@ pub async fn update_settings(
settings.appearance, settings.appearance,
settings.update_channel settings.update_channel
) )
.execute(pool) .execute(db)
.await?; .await?;
get_settings(pool).await get_settings(db).await
} }
pub async fn upsert_environment( pub async fn upsert_environment(
pool: &Pool<Sqlite>, db: &Pool<Sqlite>,
environment: Environment, environment: Environment,
) -> Result<Environment, sqlx::Error> { ) -> Result<Environment, sqlx::Error> {
let id = match environment.id.as_str() { let id = match environment.id.as_str() {
@@ -637,12 +635,12 @@ pub async fn upsert_environment(
trimmed_name, trimmed_name,
environment.variables, environment.variables,
) )
.execute(pool) .execute(db)
.await?; .await?;
get_environment(&id, pool).await get_environment(db, &id).await
} }
pub async fn get_environment(id: &str, pool: &Pool<Sqlite>) -> Result<Environment, sqlx::Error> { pub async fn get_environment(db: &Pool<Sqlite>, id: &str) -> Result<Environment, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
Environment, Environment,
r#" r#"
@@ -659,11 +657,11 @@ pub async fn get_environment(id: &str, pool: &Pool<Sqlite>) -> Result<Environmen
"#, "#,
id, id,
) )
.fetch_one(pool) .fetch_one(db)
.await .await
} }
pub async fn get_folder(id: &str, pool: &Pool<Sqlite>) -> Result<Folder, sqlx::Error> { pub async fn get_folder(db: &Pool<Sqlite>, id: &str) -> Result<Folder, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
Folder, Folder,
r#" r#"
@@ -681,13 +679,13 @@ pub async fn get_folder(id: &str, pool: &Pool<Sqlite>) -> Result<Folder, sqlx::E
"#, "#,
id, id,
) )
.fetch_one(pool) .fetch_one(db)
.await .await
} }
pub async fn find_folders( pub async fn find_folders(
db: &Pool<Sqlite>,
workspace_id: &str, workspace_id: &str,
pool: &Pool<Sqlite>,
) -> Result<Vec<Folder>, sqlx::Error> { ) -> Result<Vec<Folder>, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
Folder, Folder,
@@ -706,12 +704,12 @@ pub async fn find_folders(
"#, "#,
workspace_id, workspace_id,
) )
.fetch_all(pool) .fetch_all(db)
.await .await
} }
pub async fn delete_folder(id: &str, pool: &Pool<Sqlite>) -> Result<Folder, sqlx::Error> { pub async fn delete_folder(db: &Pool<Sqlite>, id: &str) -> Result<Folder, sqlx::Error> {
let env = get_folder(id, pool).await?; let env = get_folder(db, id).await?;
let _ = sqlx::query!( let _ = sqlx::query!(
r#" r#"
DELETE FROM folders DELETE FROM folders
@@ -719,13 +717,13 @@ pub async fn delete_folder(id: &str, pool: &Pool<Sqlite>) -> Result<Folder, sqlx
"#, "#,
id, id,
) )
.execute(pool) .execute(db)
.await; .await;
Ok(env) Ok(env)
} }
pub async fn upsert_folder(pool: &Pool<Sqlite>, r: Folder) -> Result<Folder, sqlx::Error> { pub async fn upsert_folder(db: &Pool<Sqlite>, r: Folder) -> Result<Folder, sqlx::Error> {
let id = match r.id.as_str() { let id = match r.id.as_str() {
"" => generate_id(Some("fl")), "" => generate_id(Some("fl")),
_ => r.id.to_string(), _ => r.id.to_string(),
@@ -754,22 +752,19 @@ pub async fn upsert_folder(pool: &Pool<Sqlite>, r: Folder) -> Result<Folder, sql
trimmed_name, trimmed_name,
r.sort_priority, r.sort_priority,
) )
.execute(pool) .execute(db)
.await?; .await?;
get_folder(&id, pool).await get_folder(db, &id).await
} }
pub async fn duplicate_request(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest, sqlx::Error> { pub async fn duplicate_request(db: &Pool<Sqlite>, id: &str) -> Result<HttpRequest, sqlx::Error> {
let mut request = get_request(id, pool).await?.clone(); let mut request = get_request(db, id).await?.clone();
request.id = "".to_string(); request.id = "".to_string();
upsert_request(pool, request).await upsert_request(db, request).await
} }
pub async fn upsert_request( pub async fn upsert_request(db: &Pool<Sqlite>, r: HttpRequest) -> Result<HttpRequest, sqlx::Error> {
pool: &Pool<Sqlite>,
r: HttpRequest,
) -> Result<HttpRequest, sqlx::Error> {
let id = match r.id.as_str() { let id = match r.id.as_str() {
"" => generate_id(Some("rq")), "" => generate_id(Some("rq")),
_ => r.id.to_string(), _ => r.id.to_string(),
@@ -824,15 +819,15 @@ pub async fn upsert_request(
headers_json, headers_json,
r.sort_priority, r.sort_priority,
) )
.execute(pool) .execute(db)
.await?; .await?;
get_request(&id, pool).await get_request(db, &id).await
} }
pub async fn find_requests( pub async fn find_requests(
db: &Pool<Sqlite>,
workspace_id: &str, workspace_id: &str,
pool: &Pool<Sqlite>,
) -> Result<Vec<HttpRequest>, sqlx::Error> { ) -> Result<Vec<HttpRequest>, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
HttpRequest, HttpRequest,
@@ -859,11 +854,11 @@ pub async fn find_requests(
"#, "#,
workspace_id, workspace_id,
) )
.fetch_all(pool) .fetch_all(db)
.await .await
} }
pub async fn get_request(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest, sqlx::Error> { pub async fn get_request(db: &Pool<Sqlite>, id: &str) -> Result<HttpRequest, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
HttpRequest, HttpRequest,
r#" r#"
@@ -889,15 +884,15 @@ pub async fn get_request(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest, s
"#, "#,
id, id,
) )
.fetch_one(pool) .fetch_one(db)
.await .await
} }
pub async fn delete_request(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest, sqlx::Error> { pub async fn delete_request(db: &Pool<Sqlite>, id: &str) -> Result<HttpRequest, sqlx::Error> {
let req = get_request(id, pool).await?; let req = get_request(db, id).await?;
// DB deletes will cascade but this will delete the files // DB deletes will cascade but this will delete the files
delete_all_responses(id, pool).await?; delete_all_responses(db, id).await?;
let _ = sqlx::query!( let _ = sqlx::query!(
r#" r#"
@@ -906,7 +901,7 @@ pub async fn delete_request(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest
"#, "#,
id, id,
) )
.execute(pool) .execute(db)
.await; .await;
Ok(req) Ok(req)
@@ -914,6 +909,7 @@ pub async fn delete_request(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub async fn create_response( pub async fn create_response(
db: &Pool<Sqlite>,
request_id: &str, request_id: &str,
elapsed: i64, elapsed: i64,
elapsed_headers: i64, elapsed_headers: i64,
@@ -925,9 +921,8 @@ pub async fn create_response(
headers: Vec<HttpResponseHeader>, headers: Vec<HttpResponseHeader>,
version: Option<&str>, version: Option<&str>,
remote_addr: Option<&str>, remote_addr: Option<&str>,
pool: &Pool<Sqlite>,
) -> Result<HttpResponse, sqlx::Error> { ) -> Result<HttpResponse, sqlx::Error> {
let req = get_request(request_id, pool).await?; let req = get_request(db, request_id).await?;
let id = generate_id(Some("rp")); let id = generate_id(Some("rp"));
let headers_json = Json(headers); let headers_json = Json(headers);
sqlx::query!( sqlx::query!(
@@ -963,13 +958,13 @@ pub async fn create_response(
version, version,
remote_addr, remote_addr,
) )
.execute(pool) .execute(db)
.await?; .await?;
get_response(&id, pool).await get_response(db, &id).await
} }
pub async fn cancel_pending_responses(pool: &Pool<Sqlite>) -> Result<(), sqlx::Error> { pub async fn cancel_pending_responses(db: &Pool<Sqlite>) -> Result<(), sqlx::Error> {
sqlx::query!( sqlx::query!(
r#" r#"
UPDATE http_responses UPDATE http_responses
@@ -977,24 +972,24 @@ pub async fn cancel_pending_responses(pool: &Pool<Sqlite>) -> Result<(), sqlx::E
WHERE elapsed = 0; WHERE elapsed = 0;
"#, "#,
) )
.execute(pool) .execute(db)
.await?; .await?;
Ok(()) Ok(())
} }
pub async fn update_response_if_id( pub async fn update_response_if_id(
db: &Pool<Sqlite>,
response: &HttpResponse, response: &HttpResponse,
pool: &Pool<Sqlite>,
) -> Result<HttpResponse, sqlx::Error> { ) -> Result<HttpResponse, sqlx::Error> {
if response.id.is_empty() { if response.id.is_empty() {
Ok(response.clone()) Ok(response.clone())
} else { } else {
update_response(response, pool).await update_response(db, response).await
} }
} }
pub async fn upsert_workspace( pub async fn upsert_workspace(
pool: &Pool<Sqlite>, db: &Pool<Sqlite>,
workspace: Workspace, workspace: Workspace,
) -> Result<Workspace, sqlx::Error> { ) -> Result<Workspace, sqlx::Error> {
let id = match workspace.id.as_str() { let id = match workspace.id.as_str() {
@@ -1031,15 +1026,15 @@ pub async fn upsert_workspace(
workspace.setting_follow_redirects, workspace.setting_follow_redirects,
workspace.setting_validate_certificates, workspace.setting_validate_certificates,
) )
.execute(pool) .execute(db)
.await?; .await?;
get_workspace(&id, pool).await get_workspace(db, &id).await
} }
pub async fn update_response( pub async fn update_response(
db: &Pool<Sqlite>,
response: &HttpResponse, response: &HttpResponse,
pool: &Pool<Sqlite>,
) -> Result<HttpResponse, sqlx::Error> { ) -> Result<HttpResponse, sqlx::Error> {
let headers_json = Json(&response.headers); let headers_json = Json(&response.headers);
sqlx::query!( sqlx::query!(
@@ -1072,12 +1067,12 @@ pub async fn update_response(
response.remote_addr, response.remote_addr,
response.id, response.id,
) )
.execute(pool) .execute(db)
.await?; .await?;
get_response(&response.id, pool).await get_response(db, &response.id).await
} }
pub async fn get_response(id: &str, pool: &Pool<Sqlite>) -> Result<HttpResponse, sqlx::Error> { pub async fn get_response(db: &Pool<Sqlite>, id: &str) -> Result<HttpResponse, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
HttpResponse, HttpResponse,
r#" r#"
@@ -1091,14 +1086,14 @@ pub async fn get_response(id: &str, pool: &Pool<Sqlite>) -> Result<HttpResponse,
"#, "#,
id, id,
) )
.fetch_one(pool) .fetch_one(db)
.await .await
} }
pub async fn find_responses( pub async fn find_responses(
db: &Pool<Sqlite>,
request_id: &str, request_id: &str,
limit: Option<i64>, limit: Option<i64>,
pool: &Pool<Sqlite>,
) -> Result<Vec<HttpResponse>, sqlx::Error> { ) -> Result<Vec<HttpResponse>, sqlx::Error> {
let limit_unwrapped = limit.unwrap_or_else(|| i64::MAX); let limit_unwrapped = limit.unwrap_or_else(|| i64::MAX);
sqlx::query_as!( sqlx::query_as!(
@@ -1117,13 +1112,13 @@ pub async fn find_responses(
request_id, request_id,
limit_unwrapped, limit_unwrapped,
) )
.fetch_all(pool) .fetch_all(db)
.await .await
} }
pub async fn find_responses_by_workspace_id( pub async fn find_responses_by_workspace_id(
db: &Pool<Sqlite>,
workspace_id: &str, workspace_id: &str,
pool: &Pool<Sqlite>,
) -> Result<Vec<HttpResponse>, sqlx::Error> { ) -> Result<Vec<HttpResponse>, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
HttpResponse, HttpResponse,
@@ -1139,12 +1134,12 @@ pub async fn find_responses_by_workspace_id(
"#, "#,
workspace_id, workspace_id,
) )
.fetch_all(pool) .fetch_all(db)
.await .await
} }
pub async fn delete_response(id: &str, pool: &Pool<Sqlite>) -> Result<HttpResponse, sqlx::Error> { pub async fn delete_response(db: &Pool<Sqlite>, id: &str) -> Result<HttpResponse, sqlx::Error> {
let resp = get_response(id, pool).await?; let resp = get_response(db, id).await?;
// Delete the body file if it exists // Delete the body file if it exists
if let Some(p) = resp.body_path.clone() { if let Some(p) = resp.body_path.clone() {
@@ -1160,18 +1155,15 @@ pub async fn delete_response(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRespon
"#, "#,
id, id,
) )
.execute(pool) .execute(db)
.await; .await;
Ok(resp) Ok(resp)
} }
pub async fn delete_all_responses( pub async fn delete_all_responses(db: &Pool<Sqlite>, request_id: &str) -> Result<(), sqlx::Error> {
request_id: &str, for r in find_responses(db, request_id, None).await? {
pool: &Pool<Sqlite>, delete_response(db, &r.id).await?;
) -> Result<(), sqlx::Error> {
for r in find_responses(request_id, None, pool).await? {
delete_response(&r.id, pool).await?;
} }
Ok(()) Ok(())
} }
@@ -1204,10 +1196,10 @@ pub struct WorkspaceExportResources {
pub async fn get_workspace_export_resources( pub async fn get_workspace_export_resources(
app_handle: &AppHandle, app_handle: &AppHandle,
pool: &Pool<Sqlite>, db: &Pool<Sqlite>,
workspace_id: &str, workspace_id: &str,
) -> WorkspaceExport { ) -> WorkspaceExport {
let workspace = get_workspace(workspace_id, pool) let workspace = get_workspace(db, workspace_id)
.await .await
.expect("Failed to get workspace"); .expect("Failed to get workspace");
return WorkspaceExport { return WorkspaceExport {
@@ -1216,13 +1208,13 @@ pub async fn get_workspace_export_resources(
timestamp: chrono::Utc::now().naive_utc(), timestamp: chrono::Utc::now().naive_utc(),
resources: WorkspaceExportResources { resources: WorkspaceExportResources {
workspaces: vec![workspace], workspaces: vec![workspace],
environments: find_environments(workspace_id, pool) environments: find_environments(db, workspace_id)
.await .await
.expect("Failed to get environments"), .expect("Failed to get environments"),
folders: find_folders(workspace_id, pool) folders: find_folders(db, workspace_id)
.await .await
.expect("Failed to get folders"), .expect("Failed to get folders"),
requests: find_requests(workspace_id, pool) requests: find_requests(db, workspace_id)
.await .await
.expect("Failed to get requests"), .expect("Failed to get requests"),
}, },

View File

@@ -1,7 +1,8 @@
import useResizeObserver from '@react-hook/resize-observer';
import classNames from 'classnames'; import classNames from 'classnames';
import { format } from 'date-fns'; import { format } from 'date-fns';
import type { CSSProperties, FormEvent } from 'react'; import type { CSSProperties, FormEvent } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useRef, useCallback, useEffect, useMemo, useState } from 'react';
import { useAlert } from '../hooks/useAlert'; import { useAlert } from '../hooks/useAlert';
import type { GrpcMessage } from '../hooks/useGrpc'; import type { GrpcMessage } from '../hooks/useGrpc';
import { useGrpc } from '../hooks/useGrpc'; import { useGrpc } from '../hooks/useGrpc';
@@ -129,6 +130,12 @@ export function GrpcConnectionLayout({ style }: Props) {
return { value, options }; return { value, options };
}, [grpc.schema, method.value, service.value]); }, [grpc.schema, method.value, service.value]);
const [paneSize, setPaneSize] = useState(99999);
const urlContainerEl = useRef<HTMLDivElement>(null);
useResizeObserver<HTMLDivElement>(urlContainerEl.current, (entry) => {
setPaneSize(entry.contentRect.width);
});
if (url.isLoading || url.value == null) { if (url.isLoading || url.value == null) {
return null; return null;
} }
@@ -138,7 +145,13 @@ export function GrpcConnectionLayout({ style }: Props) {
style={style} style={style}
leftSlot={() => ( leftSlot={() => (
<VStack space={2}> <VStack space={2}>
<div className="grid grid-cols-[minmax(0,1fr)_auto_auto] gap-1.5"> <div
ref={urlContainerEl}
className={classNames(
'grid grid-cols-[minmax(0,1fr)_auto_auto] gap-1.5',
paneSize < 350 && '!grid-cols-1',
)}
>
<UrlBar <UrlBar
id="foo" id="foo"
url={url.value ?? ''} url={url.value ?? ''}
@@ -150,32 +163,34 @@ export function GrpcConnectionLayout({ style }: Props) {
isLoading={grpc.unary.isLoading} isLoading={grpc.unary.isLoading}
onUrlChange={url.set} onUrlChange={url.set}
/> />
<Select <HStack space={1.5}>
hideLabel <Select
name="service" hideLabel
label="Service" name="service"
className="text-gray-800" label="Service"
size="sm" className="text-gray-800"
value={select.value} size="sm"
onChange={handleChangeService} value={select.value}
options={select.options} onChange={handleChangeService}
/> options={select.options}
<IconButton />
className="border border-highlight" <IconButton
size="sm" className="border border-highlight"
title="ofo" size="sm"
hotkeyAction="request.send" title="ofo"
onClick={handleConnect} hotkeyAction="request.send"
icon={ onClick={handleConnect}
!activeMethod?.clientStreaming && activeMethod?.serverStreaming icon={
? 'arrowDownToDot' !activeMethod?.clientStreaming && activeMethod?.serverStreaming
: activeMethod?.clientStreaming && !activeMethod?.serverStreaming ? 'arrowDownToDot'
? 'arrowUpFromDot' : activeMethod?.clientStreaming && !activeMethod?.serverStreaming
: activeMethod?.clientStreaming && activeMethod?.serverStreaming ? 'arrowUpFromDot'
? 'arrowUpDown' : activeMethod?.clientStreaming && activeMethod?.serverStreaming
: 'sendHorizontal' ? 'arrowUpDown'
} : 'sendHorizontal'
/> }
/>
</HStack>
</div> </div>
<GrpcEditor <GrpcEditor
forceUpdateKey={[service, method].join('::')} forceUpdateKey={[service, method].join('::')}

View File

@@ -102,7 +102,7 @@ export function SettingsDropdown() {
label: 'Check for Updates', label: 'Check for Updates',
leftSlot: <Icon icon="update" />, leftSlot: <Icon icon="update" />,
onSelect: async () => { onSelect: async () => {
const hasUpdate: boolean = await invoke('check_for_updates'); const hasUpdate: boolean = await invoke('cmd_check_for_updates');
if (!hasUpdate) { if (!hasUpdate) {
alert({ alert({
id: 'no-updates', id: 'no-updates',

View File

@@ -59,7 +59,7 @@ export const WorkspaceActionsDropdown = memo(function WorkspaceActionsDropdown({
onClick={async () => { onClick={async () => {
hide(); hide();
const environmentId = (await getRecentEnvironments(w.id))[0]; const environmentId = (await getRecentEnvironments(w.id))[0];
await invoke('new_window', { await invoke('cmd_new_window', {
url: routes.paths.workspace({ workspaceId: w.id, environmentId }), url: routes.paths.workspace({ workspaceId: w.id, environmentId }),
}); });
}} }}

View File

@@ -6,6 +6,7 @@ const gapClasses = {
0: 'gap-0', 0: 'gap-0',
0.5: 'gap-0.5', 0.5: 'gap-0.5',
1: 'gap-1', 1: 'gap-1',
1.5: 'gap-1.5',
2: 'gap-2', 2: 'gap-2',
3: 'gap-3', 3: 'gap-3',
4: 'gap-4', 4: 'gap-4',

View File

@@ -15,7 +15,7 @@ export function useCookieJars() {
queryKey: cookieJarsQueryKey({ workspaceId: workspaceId ?? 'n/a' }), queryKey: cookieJarsQueryKey({ workspaceId: workspaceId ?? 'n/a' }),
queryFn: async () => { queryFn: async () => {
if (workspaceId == null) return []; if (workspaceId == null) return [];
return (await invoke('list_cookie_jars', { workspaceId })) as CookieJar[]; return (await invoke('cmd_list_cookie_jars', { workspaceId })) as CookieJar[];
}, },
}).data ?? [] }).data ?? []
); );

View File

@@ -23,7 +23,7 @@ export function useCreateCookieJar() {
label: 'Name', label: 'Name',
defaultValue: 'My Jar', defaultValue: 'My Jar',
}); });
return invoke('create_cookie_jar', { workspaceId, name }); return invoke('cmd_create_cookie_jar', { workspaceId, name });
}, },
onSettled: () => trackEvent('CookieJar', 'Create'), onSettled: () => trackEvent('CookieJar', 'Create'),
onSuccess: async (cookieJar) => { onSuccess: async (cookieJar) => {

View File

@@ -22,7 +22,7 @@ export function useCreateEnvironment() {
label: 'Name', label: 'Name',
defaultValue: 'My Environment', defaultValue: 'My Environment',
}); });
return invoke('create_environment', { name, variables: [], workspaceId }); return invoke('cmd_create_environment', { name, variables: [], workspaceId });
}, },
onSettled: () => trackEvent('Environment', 'Create'), onSettled: () => trackEvent('Environment', 'Create'),
onSuccess: async (environment) => { onSuccess: async (environment) => {

View File

@@ -16,7 +16,7 @@ export function useCreateFolder() {
} }
patch.name = patch.name || 'New Folder'; patch.name = patch.name || 'New Folder';
patch.sortPriority = patch.sortPriority || -Date.now(); patch.sortPriority = patch.sortPriority || -Date.now();
return invoke('create_folder', { workspaceId, ...patch }); return invoke('cmd_create_folder', { workspaceId, ...patch });
}, },
onSettled: () => trackEvent('Folder', 'Create'), onSettled: () => trackEvent('Folder', 'Create'),
onSuccess: async (request) => { onSuccess: async (request) => {

View File

@@ -34,7 +34,7 @@ export function useCreateRequest() {
} }
} }
patch.folderId = patch.folderId || activeRequest?.folderId; patch.folderId = patch.folderId || activeRequest?.folderId;
return invoke('create_request', { workspaceId, name: '', ...patch }); return invoke('cmd_create_request', { workspaceId, name: '', ...patch });
}, },
onSettled: () => trackEvent('HttpRequest', 'Create'), onSettled: () => trackEvent('HttpRequest', 'Create'),
onSuccess: async (request) => { onSuccess: async (request) => {

View File

@@ -10,7 +10,7 @@ export function useCreateWorkspace({ navigateAfter }: { navigateAfter: boolean }
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation<Workspace, unknown, Pick<Workspace, 'name'>>({ return useMutation<Workspace, unknown, Pick<Workspace, 'name'>>({
mutationFn: (patch) => { mutationFn: (patch) => {
return invoke('create_workspace', patch); return invoke('cmd_create_workspace', patch);
}, },
onSettled: () => trackEvent('Workspace', 'Create'), onSettled: () => trackEvent('Workspace', 'Create'),
onSuccess: async (workspace) => { onSuccess: async (workspace) => {

View File

@@ -27,7 +27,7 @@ export function useDeleteAnyRequest() {
), ),
}); });
if (!confirmed) return null; if (!confirmed) return null;
return invoke('delete_request', { requestId: id }); return invoke('cmd_delete_request', { requestId: id });
}, },
onSettled: () => trackEvent('HttpRequest', 'Delete'), onSettled: () => trackEvent('HttpRequest', 'Delete'),
onSuccess: async (request) => { onSuccess: async (request) => {

View File

@@ -23,7 +23,7 @@ export function useDeleteCookieJar(cookieJar: CookieJar | null) {
), ),
}); });
if (!confirmed) return null; if (!confirmed) return null;
return invoke('delete_cookie_jar', { cookieJarId: cookieJar?.id }); return invoke('cmd_delete_cookie_jar', { cookieJarId: cookieJar?.id });
}, },
onSettled: () => trackEvent('CookieJar', 'Delete'), onSettled: () => trackEvent('CookieJar', 'Delete'),
onSuccess: async (cookieJar) => { onSuccess: async (cookieJar) => {

View File

@@ -23,7 +23,7 @@ export function useDeleteEnvironment(environment: Environment | null) {
), ),
}); });
if (!confirmed) return null; if (!confirmed) return null;
return invoke('delete_environment', { environmentId: environment?.id }); return invoke('cmd_delete_environment', { environmentId: environment?.id });
}, },
onSettled: () => trackEvent('Environment', 'Delete'), onSettled: () => trackEvent('Environment', 'Delete'),
onSuccess: async (environment) => { onSuccess: async (environment) => {

View File

@@ -26,7 +26,7 @@ export function useDeleteFolder(id: string | null) {
), ),
}); });
if (!confirmed) return null; if (!confirmed) return null;
return invoke('delete_folder', { folderId: id }); return invoke('cmd_delete_folder', { folderId: id });
}, },
onSettled: () => trackEvent('Folder', 'Delete'), onSettled: () => trackEvent('Folder', 'Delete'),
onSuccess: async (folder) => { onSuccess: async (folder) => {

View File

@@ -8,7 +8,7 @@ export function useDeleteResponse(id: string | null) {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation<HttpResponse>({ return useMutation<HttpResponse>({
mutationFn: async () => { mutationFn: async () => {
return await invoke('delete_response', { id: id }); return await invoke('cmd_delete_response', { id: id });
}, },
onSettled: () => trackEvent('HttpResponse', 'Delete'), onSettled: () => trackEvent('HttpResponse', 'Delete'),
onSuccess: ({ requestId, id: responseId }) => { onSuccess: ({ requestId, id: responseId }) => {

View File

@@ -8,7 +8,7 @@ export function useDeleteResponses(requestId?: string) {
return useMutation({ return useMutation({
mutationFn: async () => { mutationFn: async () => {
if (requestId === undefined) return; if (requestId === undefined) return;
await invoke('delete_all_responses', { requestId }); await invoke('cmd_delete_all_responses', { requestId });
}, },
onSettled: () => trackEvent('HttpResponse', 'DeleteMany'), onSettled: () => trackEvent('HttpResponse', 'DeleteMany'),
onSuccess: async () => { onSuccess: async () => {

View File

@@ -28,7 +28,7 @@ export function useDeleteWorkspace(workspace: Workspace | null) {
), ),
}); });
if (!confirmed) return null; if (!confirmed) return null;
return invoke('delete_workspace', { workspaceId: workspace?.id }); return invoke('cmd_delete_workspace', { workspaceId: workspace?.id });
}, },
onSettled: () => trackEvent('Workspace', 'Delete'), onSettled: () => trackEvent('Workspace', 'Delete'),
onSuccess: async (workspace) => { onSuccess: async (workspace) => {

View File

@@ -21,7 +21,7 @@ export function useDuplicateRequest({
return useMutation<HttpRequest, string>({ return useMutation<HttpRequest, string>({
mutationFn: async () => { mutationFn: async () => {
if (id === null) throw new Error("Can't duplicate a null request"); if (id === null) throw new Error("Can't duplicate a null request");
return invoke('duplicate_request', { id }); return invoke('cmd_duplicate_request', { id });
}, },
onSettled: () => trackEvent('HttpRequest', 'Duplicate'), onSettled: () => trackEvent('HttpRequest', 'Duplicate'),
onSuccess: async (request) => { onSuccess: async (request) => {

View File

@@ -15,7 +15,7 @@ export function useEnvironments() {
queryKey: environmentsQueryKey({ workspaceId: workspaceId ?? 'n/a' }), queryKey: environmentsQueryKey({ workspaceId: workspaceId ?? 'n/a' }),
queryFn: async () => { queryFn: async () => {
if (workspaceId == null) return []; if (workspaceId == null) return [];
return (await invoke('list_environments', { workspaceId })) as Environment[]; return (await invoke('cmd_list_environments', { workspaceId })) as Environment[];
}, },
}).data ?? [] }).data ?? []
); );

View File

@@ -25,7 +25,7 @@ export function useExportData() {
return; return;
} }
await invoke('export_data', { workspaceId: workspace.id, exportPath }); await invoke('cmd_export_data', { workspaceId: workspace.id, exportPath });
}, },
}); });
} }

View File

@@ -16,7 +16,7 @@ export function useFilterResponse({
return null; return null;
} }
return (await invoke('filter_response', { responseId, filter })) as string | null; return (await invoke('cmd_filter_response', { responseId, filter })) as string | null;
}, },
}).data ?? null }).data ?? null
); );

View File

@@ -15,7 +15,7 @@ export function useFolders() {
queryKey: foldersQueryKey({ workspaceId: workspaceId ?? 'n/a' }), queryKey: foldersQueryKey({ workspaceId: workspaceId ?? 'n/a' }),
queryFn: async () => { queryFn: async () => {
if (workspaceId == null) return []; if (workspaceId == null) return [];
return (await invoke('list_folders', { workspaceId })) as Folder[]; return (await invoke('cmd_list_folders', { workspaceId })) as Folder[];
}, },
}).data ?? [] }).data ?? []
); );

View File

@@ -30,7 +30,7 @@ export function useGrpc(url: string | null) {
mutationKey: ['grpc_unary', url], mutationKey: ['grpc_unary', url],
mutationFn: async ({ service, method, message }) => { mutationFn: async ({ service, method, message }) => {
if (url === null) throw new Error('No URL provided'); if (url === null) throw new Error('No URL provided');
return (await invoke('grpc_call_unary', { return (await invoke('cmd_grpc_call_unary', {
endpoint: url, endpoint: url,
service, service,
method, method,
@@ -50,7 +50,7 @@ export function useGrpc(url: string | null) {
setMessages([ setMessages([
{ isServer: false, message: JSON.stringify(JSON.parse(message)), time: new Date() }, { isServer: false, message: JSON.stringify(JSON.parse(message)), time: new Date() },
]); ]);
return (await invoke('grpc_server_streaming', { return (await invoke('cmd_grpc_server_streaming', {
endpoint: url, endpoint: url,
service, service,
method, method,
@@ -64,7 +64,7 @@ export function useGrpc(url: string | null) {
queryFn: async () => { queryFn: async () => {
if (url === null) return []; if (url === null) return [];
console.log('GETTING SCHEMA', url); console.log('GETTING SCHEMA', url);
return (await invoke('grpc_reflect', { endpoint: url })) as ReflectResponseService[]; return (await invoke('cmd_grpc_reflect', { endpoint: url })) as ReflectResponseService[];
}, },
}); });

View File

@@ -35,7 +35,7 @@ export function useImportData() {
environments: Environment[]; environments: Environment[];
folders: Folder[]; folders: Folder[];
requests: HttpRequest[]; requests: HttpRequest[];
} = await invoke('import_data', { } = await invoke('cmd_import_data', {
filePaths: Array.isArray(selected) ? selected : [selected], filePaths: Array.isArray(selected) ? selected : [selected],
}); });
const importedWorkspace = imported.workspaces[0]; const importedWorkspace = imported.workspaces[0];

View File

@@ -15,7 +15,7 @@ export function useRequests() {
queryKey: requestsQueryKey({ workspaceId: workspaceId ?? 'n/a' }), queryKey: requestsQueryKey({ workspaceId: workspaceId ?? 'n/a' }),
queryFn: async () => { queryFn: async () => {
if (workspaceId == null) return []; if (workspaceId == null) return [];
return (await invoke('list_requests', { workspaceId })) as HttpRequest[]; return (await invoke('cmd_list_requests', { workspaceId })) as HttpRequest[];
}, },
}).data ?? [] }).data ?? []
); );

View File

@@ -13,7 +13,7 @@ export function useResponses(requestId: string | null) {
initialData: [], initialData: [],
queryKey: responsesQueryKey({ requestId: requestId ?? 'n/a' }), queryKey: responsesQueryKey({ requestId: requestId ?? 'n/a' }),
queryFn: async () => { queryFn: async () => {
return (await invoke('list_responses', { requestId, limit: 200 })) as HttpResponse[]; return (await invoke('cmd_list_responses', { requestId, limit: 200 })) as HttpResponse[];
}, },
}).data ?? [] }).data ?? []
); );

View File

@@ -31,7 +31,7 @@ export function useSendAnyRequest(options: { download?: boolean } = {}) {
} }
} }
return invoke('send_request', { return invoke('cmd_send_request', {
requestId: id, requestId: id,
environmentId, environmentId,
downloadDir: downloadDir, downloadDir: downloadDir,

View File

@@ -11,7 +11,7 @@ export function useSettings() {
useQuery({ useQuery({
queryKey: settingsQueryKey(), queryKey: settingsQueryKey(),
queryFn: async () => { queryFn: async () => {
return (await invoke('get_settings')) as Settings; return (await invoke('cmd_get_settings')) as Settings;
}, },
}).data ?? undefined }).data ?? undefined
); );

View File

@@ -14,7 +14,7 @@ export function useUpdateAnyFolder() {
throw new Error("Can't update a null folder"); throw new Error("Can't update a null folder");
} }
await invoke('update_folder', { folder: update(folder) }); await invoke('cmd_update_folder', { folder: update(folder) });
}, },
onMutate: async ({ id, update }) => { onMutate: async ({ id, update }) => {
const folder = await getFolder(id); const folder = await getFolder(id);

View File

@@ -20,7 +20,7 @@ export function useUpdateAnyRequest() {
const patchedRequest = const patchedRequest =
typeof update === 'function' ? update(request) : { ...request, ...update }; typeof update === 'function' ? update(request) : { ...request, ...update };
await invoke('update_request', { request: patchedRequest }); await invoke('cmd_update_request', { request: patchedRequest });
}, },
onMutate: async ({ id, update }) => { onMutate: async ({ id, update }) => {
const request = await getRequest(id); const request = await getRequest(id);

View File

@@ -15,7 +15,7 @@ export function useUpdateCookieJar(id: string | null) {
const newCookieJar = typeof v === 'function' ? v(cookieJar) : { ...cookieJar, ...v }; const newCookieJar = typeof v === 'function' ? v(cookieJar) : { ...cookieJar, ...v };
console.log('NEW COOKIE JAR', newCookieJar.cookies.length); console.log('NEW COOKIE JAR', newCookieJar.cookies.length);
await invoke('update_cookie_jar', { cookieJar: newCookieJar }); await invoke('cmd_update_cookie_jar', { cookieJar: newCookieJar });
}, },
onMutate: async (v) => { onMutate: async (v) => {
const cookieJar = await getCookieJar(id); const cookieJar = await getCookieJar(id);

View File

@@ -14,7 +14,7 @@ export function useUpdateEnvironment(id: string | null) {
} }
const newEnvironment = typeof v === 'function' ? v(environment) : { ...environment, ...v }; const newEnvironment = typeof v === 'function' ? v(environment) : { ...environment, ...v };
await invoke('update_environment', { environment: newEnvironment }); await invoke('cmd_update_environment', { environment: newEnvironment });
}, },
onMutate: async (v) => { onMutate: async (v) => {
const environment = await getEnvironment(id); const environment = await getEnvironment(id);

View File

@@ -8,7 +8,7 @@ export function useUpdateSettings() {
return useMutation<void, unknown, Settings>({ return useMutation<void, unknown, Settings>({
mutationFn: async (settings) => { mutationFn: async (settings) => {
await invoke('update_settings', { settings }); await invoke('cmd_update_settings', { settings });
}, },
onMutate: async (settings) => { onMutate: async (settings) => {
queryClient.setQueryData<Settings>(settingsQueryKey(), settings); queryClient.setQueryData<Settings>(settingsQueryKey(), settings);

View File

@@ -14,7 +14,7 @@ export function useUpdateWorkspace(id: string | null) {
} }
const newWorkspace = typeof v === 'function' ? v(workspace) : { ...workspace, ...v }; const newWorkspace = typeof v === 'function' ? v(workspace) : { ...workspace, ...v };
await invoke('update_workspace', { workspace: newWorkspace }); await invoke('cmd_update_workspace', { workspace: newWorkspace });
}, },
onMutate: async (v) => { onMutate: async (v) => {
const workspace = await getWorkspace(id); const workspace = await getWorkspace(id);

View File

@@ -11,7 +11,7 @@ export function useVariables({ environmentId }: { environmentId: string }) {
useQuery({ useQuery({
queryKey: variablesQueryKey({ environmentId }), queryKey: variablesQueryKey({ environmentId }),
queryFn: async () => { queryFn: async () => {
return (await invoke('list_variables', { environmentId })) as EnvironmentVariable[]; return (await invoke('cmd_list_variables', { environmentId })) as EnvironmentVariable[];
}, },
}).data ?? [] }).data ?? []
); );

View File

@@ -10,7 +10,7 @@ export function workspacesQueryKey(_?: {}) {
export function useWorkspaces() { export function useWorkspaces() {
return ( return (
useQuery(workspacesQueryKey(), async () => { useQuery(workspacesQueryKey(), async () => {
return (await invoke('list_workspaces')) as Workspace[]; return (await invoke('cmd_list_workspaces')) as Workspace[];
}).data ?? [] }).data ?? []
); );
} }

View File

@@ -25,7 +25,7 @@ export function trackEvent(
| 'Duplicate', | 'Duplicate',
attributes: Record<string, string | number> = {}, attributes: Record<string, string | number> = {},
) { ) {
invoke('track_event', { invoke('cmd_track_event', {
resource: resource, resource: resource,
action, action,
attributes, attributes,

View File

@@ -14,7 +14,7 @@ export async function setKeyValue<T>({
key: string | string[]; key: string | string[];
value: T; value: T;
}): Promise<void> { }): Promise<void> {
await invoke('set_key_value', { await invoke('cmd_set_key_value', {
namespace, namespace,
key: buildKeyValueKey(key), key: buildKeyValueKey(key),
value: JSON.stringify(value), value: JSON.stringify(value),
@@ -30,7 +30,7 @@ export async function getKeyValue<T>({
key: string | string[]; key: string | string[];
fallback: T; fallback: T;
}) { }) {
const kv = (await invoke('get_key_value', { const kv = (await invoke('cmd_get_key_value', {
namespace, namespace,
key: buildKeyValueKey(key), key: buildKeyValueKey(key),
})) as KeyValue | null; })) as KeyValue | null;

View File

@@ -7,5 +7,5 @@ export async function sendEphemeralRequest(
): Promise<HttpResponse> { ): Promise<HttpResponse> {
// Remove some things that we don't want to associate // Remove some things that we don't want to associate
const newRequest = { ...request }; const newRequest = { ...request };
return invoke('send_ephemeral_request', { request: newRequest, environmentId }); return invoke('cmd_send_ephemeral_request', { request: newRequest, environmentId });
} }

View File

@@ -2,12 +2,12 @@ import { invoke } from '@tauri-apps/api';
import type { CookieJar, Environment, Folder, HttpRequest, Settings, Workspace } from './models'; import type { CookieJar, Environment, Folder, HttpRequest, Settings, Workspace } from './models';
export async function getSettings(): Promise<Settings> { export async function getSettings(): Promise<Settings> {
return invoke('get_settings', {}); return invoke('cmd_get_settings', {});
} }
export async function getRequest(id: string | null): Promise<HttpRequest | null> { export async function getRequest(id: string | null): Promise<HttpRequest | null> {
if (id === null) return null; if (id === null) return null;
const request: HttpRequest = (await invoke('get_request', { id })) ?? null; const request: HttpRequest = (await invoke('cmd_get_request', { id })) ?? null;
if (request == null) { if (request == null) {
return null; return null;
} }
@@ -16,7 +16,7 @@ export async function getRequest(id: string | null): Promise<HttpRequest | null>
export async function getEnvironment(id: string | null): Promise<Environment | null> { export async function getEnvironment(id: string | null): Promise<Environment | null> {
if (id === null) return null; if (id === null) return null;
const environment: Environment = (await invoke('get_environment', { id })) ?? null; const environment: Environment = (await invoke('cmd_get_environment', { id })) ?? null;
if (environment == null) { if (environment == null) {
return null; return null;
} }
@@ -25,7 +25,7 @@ export async function getEnvironment(id: string | null): Promise<Environment | n
export async function getFolder(id: string | null): Promise<Folder | null> { export async function getFolder(id: string | null): Promise<Folder | null> {
if (id === null) return null; if (id === null) return null;
const folder: Folder = (await invoke('get_folder', { id })) ?? null; const folder: Folder = (await invoke('cmd_get_folder', { id })) ?? null;
if (folder == null) { if (folder == null) {
return null; return null;
} }
@@ -34,7 +34,7 @@ export async function getFolder(id: string | null): Promise<Folder | null> {
export async function getWorkspace(id: string | null): Promise<Workspace | null> { export async function getWorkspace(id: string | null): Promise<Workspace | null> {
if (id === null) return null; if (id === null) return null;
const workspace: Workspace = (await invoke('get_workspace', { id })) ?? null; const workspace: Workspace = (await invoke('cmd_get_workspace', { id })) ?? null;
if (workspace == null) { if (workspace == null) {
return null; return null;
} }
@@ -43,7 +43,7 @@ export async function getWorkspace(id: string | null): Promise<Workspace | null>
export async function getCookieJar(id: string | null): Promise<CookieJar | null> { export async function getCookieJar(id: string | null): Promise<CookieJar | null> {
if (id === null) return null; if (id === null) return null;
const cookieJar: CookieJar = (await invoke('get_cookie_jar', { id })) ?? null; const cookieJar: CookieJar = (await invoke('cmd_get_cookie_jar', { id })) ?? null;
if (cookieJar == null) { if (cookieJar == null) {
return null; return null;
} }

View File

@@ -1,15 +1,12 @@
import { invoke } from '@tauri-apps/api'; import { type } from '@tauri-apps/api/os';
import { appWindow } from '@tauri-apps/api/window';
import { StrictMode } from 'react'; import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import { attachConsole } from 'tauri-plugin-log-api';
import { App } from './components/App'; import { App } from './components/App';
import { maybeRestorePathname } from './lib/persistPathname';
import './main.css'; import './main.css';
import { getSettings } from './lib/store'; import { getSettings } from './lib/store';
import type { Appearance } from './lib/theme/window'; import type { Appearance } from './lib/theme/window';
import { setAppearanceOnDocument } from './lib/theme/window'; import { setAppearanceOnDocument } from './lib/theme/window';
import { appWindow } from '@tauri-apps/api/window';
import { type } from '@tauri-apps/api/os';
// Hide decorations here because it doesn't work in Rust for some reason (bug?) // Hide decorations here because it doesn't work in Rust for some reason (bug?)
const osType = await type(); const osType = await type();
@@ -17,8 +14,8 @@ if (osType !== 'Darwin') {
await appWindow.setDecorations(false); await appWindow.setDecorations(false);
} }
await attachConsole(); // await attachConsole();
await maybeRestorePathname(); // await maybeRestorePathname();
const settings = await getSettings(); const settings = await getSettings();
setAppearanceOnDocument(settings.appearance as Appearance); setAppearanceOnDocument(settings.appearance as Appearance);