Fix text encoding and delete responses

This commit is contained in:
Gregory Schier
2023-04-14 13:50:41 -07:00
parent 9755833577
commit 67007b1f5c
7 changed files with 146 additions and 35 deletions

View File

@@ -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": {

View File

@@ -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)

View File

@@ -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() {

View File

@@ -15,14 +15,14 @@
"allowlist": {
"all": false,
"protocol": {
"assetScope": ["$APPDATA/*"],
"assetScope": ["$APPDATA/responses/*"],
"asset": true
},
"fs": {
"readFile": true,
"scope": [
"$RESOURCE/*",
"$APPDATA/*"
"$APPDATA/responses/*"
]
},
"shell": {

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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) {