From 7f4d082c172d2d088d01e314d69cc7ca262d42a3 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Sun, 18 Feb 2024 08:35:31 -0800 Subject: [PATCH] Add metadata and squash migrations --- ...96ec10188b559063a9093e432ae993154f31.json} | 10 ++++-- ...2a4ddeac667cf6e71b97bc7e122848ad1565f.json | 12 +++++++ ...7066724fc23c94cd279d074253d5581b6f2c.json} | 10 ++++-- ...4c6060c3d2a209689a879824dea4d26e5497e.json | 12 ------- src-tauri/migrations/20240203164833_grpc.sql | 28 +++++++++------- .../migrations/20240206191206_grpc-protos.sql | 1 - .../20240218071057_grpc-authentication.sql | 2 -- src-tauri/src/main.rs | 20 ++++++++++- src-tauri/src/models.rs | 33 ++++++++++++------- .../components/GrpcConnectionSetupPane.tsx | 17 +++++++++- src-web/lib/models.ts | 7 ++++ 11 files changed, 108 insertions(+), 44 deletions(-) rename src-tauri/.sqlx/{query-545d21ff21bd02468be86746325dc9f1b50f3fe53d7735194d91927b5d14a436.json => query-24a721700844cb0ea9c2585c4df796ec10188b559063a9093e432ae993154f31.json} (82%) create mode 100644 src-tauri/.sqlx/query-38e8fd3b0959623322bf49cf6682a4ddeac667cf6e71b97bc7e122848ad1565f.json rename src-tauri/.sqlx/{query-0d9e685f878fc2a0e1803c6aaae3828deebd684fc9f78e9f8595a550f90749fe.json => query-697afa2c3072b7b01676be53d5857066724fc23c94cd279d074253d5581b6f2c.json} (83%) delete mode 100644 src-tauri/.sqlx/query-c554305252cb21e34aa1e3c1f204c6060c3d2a209689a879824dea4d26e5497e.json delete mode 100644 src-tauri/migrations/20240206191206_grpc-protos.sql delete mode 100644 src-tauri/migrations/20240218071057_grpc-authentication.sql diff --git a/src-tauri/.sqlx/query-545d21ff21bd02468be86746325dc9f1b50f3fe53d7735194d91927b5d14a436.json b/src-tauri/.sqlx/query-24a721700844cb0ea9c2585c4df796ec10188b559063a9093e432ae993154f31.json similarity index 82% rename from src-tauri/.sqlx/query-545d21ff21bd02468be86746325dc9f1b50f3fe53d7735194d91927b5d14a436.json rename to src-tauri/.sqlx/query-24a721700844cb0ea9c2585c4df796ec10188b559063a9093e432ae993154f31.json index d2e4bdb7..663bbcbc 100644 --- a/src-tauri/.sqlx/query-545d21ff21bd02468be86746325dc9f1b50f3fe53d7735194d91927b5d14a436.json +++ b/src-tauri/.sqlx/query-24a721700844cb0ea9c2585c4df796ec10188b559063a9093e432ae993154f31.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,\n url, service, method, message, authentication_type,\n authentication AS \"authentication!: Json>\",\n proto_files AS \"proto_files!: sqlx::types::Json>\"\n FROM grpc_requests\n WHERE workspace_id = ?\n ", + "query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,\n url, service, method, message, authentication_type,\n authentication AS \"authentication!: Json>\",\n proto_files AS \"proto_files!: sqlx::types::Json>\",\n metadata AS \"metadata!: sqlx::types::Json>\"\n FROM grpc_requests\n WHERE workspace_id = ?\n ", "describe": { "columns": [ { @@ -77,6 +77,11 @@ "name": "proto_files!: sqlx::types::Json>", "ordinal": 14, "type_info": "Text" + }, + { + "name": "metadata!: sqlx::types::Json>", + "ordinal": 15, + "type_info": "Text" } ], "parameters": { @@ -97,8 +102,9 @@ false, true, false, + false, false ] }, - "hash": "545d21ff21bd02468be86746325dc9f1b50f3fe53d7735194d91927b5d14a436" + "hash": "24a721700844cb0ea9c2585c4df796ec10188b559063a9093e432ae993154f31" } diff --git a/src-tauri/.sqlx/query-38e8fd3b0959623322bf49cf6682a4ddeac667cf6e71b97bc7e122848ad1565f.json b/src-tauri/.sqlx/query-38e8fd3b0959623322bf49cf6682a4ddeac667cf6e71b97bc7e122848ad1565f.json new file mode 100644 index 00000000..0d196755 --- /dev/null +++ b/src-tauri/.sqlx/query-38e8fd3b0959623322bf49cf6682a4ddeac667cf6e71b97bc7e122848ad1565f.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO grpc_requests (\n id, name, workspace_id, folder_id, sort_priority, url, service, method, message,\n proto_files, authentication_type, authentication, metadata\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n folder_id = excluded.folder_id,\n sort_priority = excluded.sort_priority,\n url = excluded.url,\n service = excluded.service,\n method = excluded.method,\n message = excluded.message,\n proto_files = excluded.proto_files,\n authentication_type = excluded.authentication_type,\n authentication = excluded.authentication,\n metadata = excluded.metadata\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 13 + }, + "nullable": [] + }, + "hash": "38e8fd3b0959623322bf49cf6682a4ddeac667cf6e71b97bc7e122848ad1565f" +} diff --git a/src-tauri/.sqlx/query-0d9e685f878fc2a0e1803c6aaae3828deebd684fc9f78e9f8595a550f90749fe.json b/src-tauri/.sqlx/query-697afa2c3072b7b01676be53d5857066724fc23c94cd279d074253d5581b6f2c.json similarity index 83% rename from src-tauri/.sqlx/query-0d9e685f878fc2a0e1803c6aaae3828deebd684fc9f78e9f8595a550f90749fe.json rename to src-tauri/.sqlx/query-697afa2c3072b7b01676be53d5857066724fc23c94cd279d074253d5581b6f2c.json index 4b82c0a6..42b6a01f 100644 --- a/src-tauri/.sqlx/query-0d9e685f878fc2a0e1803c6aaae3828deebd684fc9f78e9f8595a550f90749fe.json +++ b/src-tauri/.sqlx/query-697afa2c3072b7b01676be53d5857066724fc23c94cd279d074253d5581b6f2c.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,\n url, service, method, message, authentication_type,\n authentication AS \"authentication!: Json>\",\n proto_files AS \"proto_files!: sqlx::types::Json>\"\n FROM grpc_requests\n WHERE id = ?\n ", + "query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,\n url, service, method, message, authentication_type,\n authentication AS \"authentication!: Json>\",\n proto_files AS \"proto_files!: sqlx::types::Json>\",\n metadata AS \"metadata!: sqlx::types::Json>\"\n FROM grpc_requests\n WHERE id = ?\n ", "describe": { "columns": [ { @@ -77,6 +77,11 @@ "name": "proto_files!: sqlx::types::Json>", "ordinal": 14, "type_info": "Text" + }, + { + "name": "metadata!: sqlx::types::Json>", + "ordinal": 15, + "type_info": "Text" } ], "parameters": { @@ -97,8 +102,9 @@ false, true, false, + false, false ] }, - "hash": "0d9e685f878fc2a0e1803c6aaae3828deebd684fc9f78e9f8595a550f90749fe" + "hash": "697afa2c3072b7b01676be53d5857066724fc23c94cd279d074253d5581b6f2c" } diff --git a/src-tauri/.sqlx/query-c554305252cb21e34aa1e3c1f204c6060c3d2a209689a879824dea4d26e5497e.json b/src-tauri/.sqlx/query-c554305252cb21e34aa1e3c1f204c6060c3d2a209689a879824dea4d26e5497e.json deleted file mode 100644 index c5db2a1c..00000000 --- a/src-tauri/.sqlx/query-c554305252cb21e34aa1e3c1f204c6060c3d2a209689a879824dea4d26e5497e.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO grpc_requests (\n id, name, workspace_id, folder_id, sort_priority, url, service, method, message,\n proto_files, authentication_type, authentication\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n folder_id = excluded.folder_id,\n sort_priority = excluded.sort_priority,\n url = excluded.url,\n service = excluded.service,\n method = excluded.method,\n message = excluded.message,\n proto_files = excluded.proto_files,\n authentication_type = excluded.authentication_type,\n authentication = excluded.authentication\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 12 - }, - "nullable": [] - }, - "hash": "c554305252cb21e34aa1e3c1f204c6060c3d2a209689a879824dea4d26e5497e" -} diff --git a/src-tauri/migrations/20240203164833_grpc.sql b/src-tauri/migrations/20240203164833_grpc.sql index f7dc2d63..db14a1ca 100644 --- a/src-tauri/migrations/20240203164833_grpc.sql +++ b/src-tauri/migrations/20240203164833_grpc.sql @@ -1,22 +1,26 @@ CREATE TABLE grpc_requests ( - id TEXT NOT NULL + id TEXT NOT NULL PRIMARY KEY, - model TEXT DEFAULT 'grpc_request' NOT NULL, - workspace_id TEXT NOT NULL + model TEXT DEFAULT 'grpc_request' NOT NULL, + workspace_id TEXT NOT NULL REFERENCES workspaces ON DELETE CASCADE, - folder_id TEXT NULL + folder_id TEXT NULL REFERENCES folders ON DELETE CASCADE, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, - name TEXT NOT NULL, - sort_priority REAL NOT NULL, - url TEXT NOT NULL, - service TEXT NULL, - method TEXT NULL, - message TEXT NOT NULL + created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, + name TEXT NOT NULL, + sort_priority REAL NOT NULL, + url TEXT NOT NULL, + service TEXT NULL, + method TEXT NULL, + message TEXT NOT NULL, + proto_files TEXT DEFAULT '[]' NOT NULL, + authentication TEXT DEFAULT '{}' NOT NULL, + authentication_type TEXT NULL, + metadata TEXT DEFAULT '[]' NOT NULL ); CREATE TABLE grpc_connections diff --git a/src-tauri/migrations/20240206191206_grpc-protos.sql b/src-tauri/migrations/20240206191206_grpc-protos.sql deleted file mode 100644 index 9ad50ba1..00000000 --- a/src-tauri/migrations/20240206191206_grpc-protos.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE grpc_requests ADD COLUMN proto_files TEXT DEFAULT '[]' NOT NULL; diff --git a/src-tauri/migrations/20240218071057_grpc-authentication.sql b/src-tauri/migrations/20240218071057_grpc-authentication.sql deleted file mode 100644 index 2b2be63a..00000000 --- a/src-tauri/migrations/20240218071057_grpc-authentication.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE grpc_requests ADD COLUMN authentication TEXT NOT NULL DEFAULT '{}'; -ALTER TABLE grpc_requests ADD COLUMN authentication_type TEXT; diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 1460ba39..05f7ca35 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -16,7 +16,7 @@ use std::process::exit; use std::str::FromStr; use ::http::uri::InvalidUri; -use ::http::Uri; +use ::http::{HeaderValue, Uri}; use base64::Engine; use fern::colors::ColoredLevelConfig; use log::{debug, error, info, warn}; @@ -275,6 +275,23 @@ async fn cmd_grpc_go( }; let event_handler = w.listen_global(format!("grpc_client_msg_{}", conn.id).as_str(), cb); let mut metadata = HashMap::new(); + + // Add rest of metadata + for h in req.clone().metadata.0 { + if h.name.is_empty() && h.value.is_empty() { + continue; + } + + if !h.enabled { + continue; + } + + let name = render::render(&h.name, &workspace, environment.as_ref()); + let value = render::render(&h.value, &workspace, environment.as_ref()); + + metadata.insert(name, value); + } + if let Some(b) = &req.authentication_type { let req = req.clone(); let environment_ref = environment.as_ref(); @@ -304,6 +321,7 @@ async fn cmd_grpc_go( metadata.insert("Authorization".to_string(), format!("Bearer {token}")); } } + println!("METADATA: {:?}", metadata); let grpc_listen = { diff --git a/src-tauri/src/models.rs b/src-tauri/src/models.rs index 5f7a6a40..78b7aad9 100644 --- a/src-tauri/src/models.rs +++ b/src-tauri/src/models.rs @@ -189,6 +189,15 @@ impl HttpResponse { } } +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[serde(default, rename_all = "camelCase")] +pub struct GrpcMetadataEntry { + #[serde(default = "default_true")] + pub enabled: bool, + pub name: String, + pub value: String, +} + #[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)] #[serde(default, rename_all = "camelCase")] pub struct GrpcRequest { @@ -207,6 +216,7 @@ pub struct GrpcRequest { pub proto_files: Json>, pub authentication_type: Option, pub authentication: Json>, + pub metadata: Json>, } #[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)] @@ -504,9 +514,9 @@ pub async fn upsert_grpc_request( r#" INSERT INTO grpc_requests ( id, name, workspace_id, folder_id, sort_priority, url, service, method, message, - proto_files, authentication_type, authentication + proto_files, authentication_type, authentication, metadata ) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT (id) DO UPDATE SET updated_at = CURRENT_TIMESTAMP, name = excluded.name, @@ -518,7 +528,8 @@ pub async fn upsert_grpc_request( message = excluded.message, proto_files = excluded.proto_files, authentication_type = excluded.authentication_type, - authentication = excluded.authentication + authentication = excluded.authentication, + metadata = excluded.metadata "#, id, trimmed_name, @@ -532,6 +543,7 @@ pub async fn upsert_grpc_request( request.proto_files, request.authentication_type, request.authentication, + request.metadata, ) .execute(&db) .await?; @@ -554,7 +566,8 @@ pub async fn get_grpc_request( id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority, url, service, method, message, authentication_type, authentication AS "authentication!: Json>", - proto_files AS "proto_files!: sqlx::types::Json>" + proto_files AS "proto_files!: sqlx::types::Json>", + metadata AS "metadata!: sqlx::types::Json>" FROM grpc_requests WHERE id = ? "#, @@ -576,7 +589,8 @@ pub async fn list_grpc_requests( id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority, url, service, method, message, authentication_type, authentication AS "authentication!: Json>", - proto_files AS "proto_files!: sqlx::types::Json>" + proto_files AS "proto_files!: sqlx::types::Json>", + metadata AS "metadata!: sqlx::types::Json>" FROM grpc_requests WHERE workspace_id = ? "#, @@ -1032,8 +1046,6 @@ pub async fn upsert_http_request( "" => generate_id(Some("rq")), _ => r.id.to_string(), }; - let headers_json = Json(r.headers); - let auth_json = Json(r.authentication); let trimmed_name = r.name.trim(); let db = get_db(mgr).await; @@ -1068,9 +1080,9 @@ pub async fn upsert_http_request( r.method, r.body, r.body_type, - auth_json, + r.authentication, r.authentication_type, - headers_json, + r.headers, r.sort_priority, ) .execute(&db) @@ -1291,7 +1303,6 @@ pub async fn update_response( mgr: &impl Manager, response: &HttpResponse, ) -> Result { - let headers_json = Json(&response.headers); let db = get_db(mgr).await; sqlx::query!( r#" @@ -1308,7 +1319,7 @@ pub async fn update_response( response.content_length, response.body_path, response.error, - headers_json, + response.headers, response.version, response.remote_addr, response.id, diff --git a/src-web/components/GrpcConnectionSetupPane.tsx b/src-web/components/GrpcConnectionSetupPane.tsx index 9639ffe4..09534ac1 100644 --- a/src-web/components/GrpcConnectionSetupPane.tsx +++ b/src-web/components/GrpcConnectionSetupPane.tsx @@ -7,13 +7,14 @@ import type { ReflectResponseService } from '../hooks/useGrpc'; import { useGrpcConnections } from '../hooks/useGrpcConnections'; import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey'; import { useUpdateGrpcRequest } from '../hooks/useUpdateGrpcRequest'; -import type { GrpcRequest } from '../lib/models'; +import type { GrpcMetadataEntry, GrpcRequest } from '../lib/models'; import { AUTH_TYPE_BASIC, AUTH_TYPE_BEARER, AUTH_TYPE_NONE } from '../lib/models'; import { BasicAuth } from './BasicAuth'; import { BearerAuth } from './BearerAuth'; import { Button } from './core/Button'; import { Icon } from './core/Icon'; import { IconButton } from './core/IconButton'; +import { PairEditor } from './core/PairEditor'; import { RadioDropdown } from './core/RadioDropdown'; import { HStack, VStack } from './core/Stacks'; import type { TabItem } from './core/Tabs/Tabs'; @@ -155,6 +156,11 @@ export function GrpcConnectionSetupPane({ [activeRequest.authentication, activeRequest.authenticationType, updateRequest], ); + const handleMetadataChange = useCallback( + (metadata: GrpcMetadataEntry[]) => updateRequest.mutate({ metadata }), + [updateRequest], + ); + return (
No Authentication {activeRequest.authenticationType} )} + + + ); diff --git a/src-web/lib/models.ts b/src-web/lib/models.ts index 6935866b..65c2a228 100644 --- a/src-web/lib/models.ts +++ b/src-web/lib/models.ts @@ -104,6 +104,12 @@ export interface HttpUrlParameter { enabled?: boolean; } +export interface GrpcMetadataEntry { + name: string; + value: string; + enabled?: boolean; +} + export interface GrpcRequest extends BaseModel { readonly workspaceId: string; readonly model: 'grpc_request'; @@ -117,6 +123,7 @@ export interface GrpcRequest extends BaseModel { protoFiles: string[]; authentication: Record; authenticationType: string | null; + metadata: GrpcMetadataEntry[]; } export interface GrpcMessage extends BaseModel {