mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-01-11 20:00:29 +01:00
Fix text encoding and delete responses
This commit is contained in:
@@ -58,15 +58,107 @@
|
||||
},
|
||||
"query": "\n DELETE FROM http_responses\n WHERE id = ?\n "
|
||||
},
|
||||
"0fa36011553f7ca91113459a5cefd47f990f9b548a95e475ffd6e4b017059488": {
|
||||
"26072725d536c3cfdffd9a681d17c0ee2f246ca98e0459630a2430236d3bbdd2": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "model",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "request_id",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at",
|
||||
"ordinal": 4,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 5,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "status",
|
||||
"ordinal": 7,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "status_reason",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "content_length",
|
||||
"ordinal": 9,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"ordinal": 10,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "body_path",
|
||||
"ordinal": 11,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "elapsed",
|
||||
"ordinal": 12,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "error",
|
||||
"ordinal": 13,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "headers!: sqlx::types::Json<Vec<HttpResponseHeader>>",
|
||||
"ordinal": 14,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "\n DELETE FROM http_responses\n WHERE request_id = ?\n "
|
||||
"query": "\n SELECT id, model, workspace_id, request_id, updated_at, created_at, url,\n status, status_reason, content_length, body, body_path, elapsed, error,\n headers AS \"headers!: sqlx::types::Json<Vec<HttpResponseHeader>>\"\n FROM http_responses\n WHERE workspace_id = ?\n ORDER BY created_at DESC\n "
|
||||
},
|
||||
"448a1d1f1866ab42c0f81fcf8eb2930bf21dfdd43ca4831bc1a198cf45ac3732": {
|
||||
"describe": {
|
||||
|
||||
@@ -9,6 +9,7 @@ extern crate objc;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::env::current_dir;
|
||||
use std::fs;
|
||||
use std::fs::{create_dir_all, File};
|
||||
use std::io::Write;
|
||||
|
||||
@@ -225,7 +226,9 @@ async fn actually_send_ephemeral_request(
|
||||
let body_bytes = v.bytes().await.expect("Failed to get body").to_vec();
|
||||
response.content_length = Some(body_bytes.len() as i64);
|
||||
let dir = app_handle.path_resolver().app_data_dir().unwrap();
|
||||
let body_path = dir.join(response.id.clone());
|
||||
let base_dir = dir.join("responses");
|
||||
create_dir_all(base_dir.clone()).expect("Failed to create responses dir");
|
||||
let body_path = base_dir.join(response.id.clone());
|
||||
let mut f = File::options()
|
||||
.create(true)
|
||||
.write(true)
|
||||
|
||||
@@ -154,9 +154,7 @@ pub async fn get_workspace(id: &str, pool: &Pool<Sqlite>) -> Result<Workspace, s
|
||||
}
|
||||
|
||||
pub async fn delete_workspace(id: &str, pool: &Pool<Sqlite>) -> Result<Workspace, sqlx::Error> {
|
||||
let workspace = get_workspace(id, pool)
|
||||
.await
|
||||
.expect("Failed to get request to delete");
|
||||
let workspace = get_workspace(id, pool).await?;
|
||||
let _ = sqlx::query!(
|
||||
r#"
|
||||
DELETE FROM workspaces
|
||||
@@ -166,6 +164,11 @@ pub async fn delete_workspace(id: &str, pool: &Pool<Sqlite>) -> Result<Workspace
|
||||
)
|
||||
.execute(pool)
|
||||
.await;
|
||||
|
||||
for r in find_responses_by_workspace_id(id, pool).await? {
|
||||
delete_response(&r.id, pool).await?;
|
||||
}
|
||||
|
||||
Ok(workspace)
|
||||
}
|
||||
|
||||
@@ -185,16 +188,13 @@ pub async fn create_workspace(
|
||||
description,
|
||||
)
|
||||
.execute(pool)
|
||||
.await
|
||||
.expect("Failed to insert new workspace");
|
||||
.await?;
|
||||
|
||||
get_workspace(&id, pool).await
|
||||
}
|
||||
|
||||
pub async fn duplicate_request(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest, sqlx::Error> {
|
||||
let existing = get_request(id, pool)
|
||||
.await
|
||||
.expect("Failed to get request to duplicate");
|
||||
let existing = get_request(id, pool).await?;
|
||||
|
||||
// TODO: Figure out how to make this better
|
||||
let b2;
|
||||
@@ -289,8 +289,7 @@ pub async fn upsert_request(
|
||||
sort_priority,
|
||||
)
|
||||
.execute(pool)
|
||||
.await
|
||||
.expect("Failed to insert new request");
|
||||
.await?;
|
||||
get_request(id, pool).await
|
||||
}
|
||||
|
||||
@@ -354,9 +353,7 @@ pub async fn get_request(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest, s
|
||||
}
|
||||
|
||||
pub async fn delete_request(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest, sqlx::Error> {
|
||||
let req = get_request(id, pool)
|
||||
.await
|
||||
.expect("Failed to get request to delete");
|
||||
let req = get_request(id, pool).await?;
|
||||
let _ = sqlx::query!(
|
||||
r#"
|
||||
DELETE FROM http_requests
|
||||
@@ -367,6 +364,8 @@ pub async fn delete_request(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest
|
||||
.execute(pool)
|
||||
.await;
|
||||
|
||||
delete_all_responses(id, pool).await?;
|
||||
|
||||
Ok(req)
|
||||
}
|
||||
|
||||
@@ -382,9 +381,7 @@ pub async fn create_response(
|
||||
headers: Vec<HttpResponseHeader>,
|
||||
pool: &Pool<Sqlite>,
|
||||
) -> Result<HttpResponse, sqlx::Error> {
|
||||
let req = get_request(request_id, pool)
|
||||
.await
|
||||
.expect("Failed to get request");
|
||||
let req = get_request(request_id, pool).await?;
|
||||
let id = generate_id("rp");
|
||||
let headers_json = Json(headers);
|
||||
sqlx::query!(
|
||||
@@ -417,8 +414,7 @@ pub async fn create_response(
|
||||
headers_json,
|
||||
)
|
||||
.execute(pool)
|
||||
.await
|
||||
.expect("Failed to insert new response");
|
||||
.await?;
|
||||
|
||||
get_response(&id, pool).await
|
||||
}
|
||||
@@ -447,8 +443,8 @@ pub async fn update_workspace(
|
||||
workspace.id,
|
||||
)
|
||||
.execute(pool)
|
||||
.await
|
||||
.expect("Failed to update workspace");
|
||||
.await?;
|
||||
|
||||
get_workspace(&workspace.id, pool).await
|
||||
}
|
||||
|
||||
@@ -484,8 +480,7 @@ pub async fn update_response(
|
||||
response.id,
|
||||
)
|
||||
.execute(pool)
|
||||
.await
|
||||
.expect("Failed to update response");
|
||||
.await?;
|
||||
get_response(&response.id, pool).await
|
||||
}
|
||||
|
||||
@@ -525,10 +520,28 @@ pub async fn find_responses(
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn find_responses_by_workspace_id(
|
||||
workspace_id: &str,
|
||||
pool: &Pool<Sqlite>,
|
||||
) -> Result<Vec<HttpResponse>, sqlx::Error> {
|
||||
sqlx::query_as!(
|
||||
HttpResponse,
|
||||
r#"
|
||||
SELECT id, model, workspace_id, request_id, updated_at, created_at, url,
|
||||
status, status_reason, content_length, body, body_path, elapsed, error,
|
||||
headers AS "headers!: sqlx::types::Json<Vec<HttpResponseHeader>>"
|
||||
FROM http_responses
|
||||
WHERE workspace_id = ?
|
||||
ORDER BY created_at DESC
|
||||
"#,
|
||||
workspace_id,
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn delete_response(id: &str, pool: &Pool<Sqlite>) -> Result<HttpResponse, sqlx::Error> {
|
||||
let resp = get_response(id, pool)
|
||||
.await
|
||||
.expect("Failed to get response to delete");
|
||||
let resp = get_response(id, pool).await?;
|
||||
|
||||
// Delete the body file if it exists
|
||||
if let Some(p) = resp.body_path.clone() {
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
"allowlist": {
|
||||
"all": false,
|
||||
"protocol": {
|
||||
"assetScope": ["$APPDATA/*"],
|
||||
"assetScope": ["$APPDATA/responses/*"],
|
||||
"asset": true
|
||||
},
|
||||
"fs": {
|
||||
"readFile": true,
|
||||
"scope": [
|
||||
"$RESOURCE/*",
|
||||
"$APPDATA/*"
|
||||
"$APPDATA/responses/*"
|
||||
]
|
||||
},
|
||||
"shell": {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { createGlobalState } from 'react-use';
|
||||
import { useActiveRequestId } from '../hooks/useActiveRequestId';
|
||||
import { useDeleteResponse } from '../hooks/useDeleteResponse';
|
||||
import { useDeleteResponses } from '../hooks/useDeleteResponses';
|
||||
import { useLatestResponse } from '../hooks/useLatestResponse';
|
||||
import { useResponseContentType } from '../hooks/useResponseContentType';
|
||||
import { useResponses } from '../hooks/useResponses';
|
||||
import { useResponseViewMode } from '../hooks/useResponseViewMode';
|
||||
@@ -38,10 +39,11 @@ const useActiveTab = createGlobalState<string>('body');
|
||||
export const ResponsePane = memo(function ResponsePane({ style, className }: Props) {
|
||||
const [pinnedResponseId, setPinnedResponseId] = useState<string | null>(null);
|
||||
const activeRequestId = useActiveRequestId();
|
||||
const latestResponse = useLatestResponse(activeRequestId);
|
||||
const responses = useResponses(activeRequestId);
|
||||
const activeResponse: HttpResponse | null = pinnedResponseId
|
||||
? responses.find((r) => r.id === pinnedResponseId) ?? null
|
||||
: responses[0] ?? null;
|
||||
: latestResponse ?? null;
|
||||
const [viewMode, setViewMode] = useResponseViewMode(activeResponse?.requestId);
|
||||
const deleteResponse = useDeleteResponse(activeResponse?.id ?? null);
|
||||
const deleteAllResponses = useDeleteResponses(activeResponse?.requestId);
|
||||
|
||||
@@ -3,5 +3,5 @@ import { useResponses } from './useResponses';
|
||||
|
||||
export function useLatestResponse(requestId: string | null): HttpResponse | null {
|
||||
const responses = useResponses(requestId);
|
||||
return responses[responses.length - 1] ?? null;
|
||||
return responses[0] ?? null;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ export function useResponseBodyText(response: HttpResponse) {
|
||||
initialData: null,
|
||||
queryFn: async () => {
|
||||
if (response.body) {
|
||||
return String.fromCharCode.apply(null, response.body);
|
||||
const uint8Array = Uint8Array.of(...response.body);
|
||||
return new TextDecoder().decode(uint8Array);
|
||||
}
|
||||
|
||||
if (response.bodyPath) {
|
||||
|
||||
Reference in New Issue
Block a user