mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-01 06:53:11 +02:00
Handle import errors
This commit is contained in:
@@ -10,39 +10,54 @@ extern crate objc;
|
|||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env::current_dir;
|
use std::env::current_dir;
|
||||||
use std::fs::{create_dir_all, File, read_to_string};
|
use std::fs::{create_dir_all, read_to_string, File};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use ::http::Uri;
|
|
||||||
use ::http::uri::InvalidUri;
|
use ::http::uri::InvalidUri;
|
||||||
|
use ::http::Uri;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use fern::colors::ColoredLevelConfig;
|
use fern::colors::ColoredLevelConfig;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use rand::random;
|
use rand::random;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use sqlx::{Pool, Sqlite, SqlitePool};
|
|
||||||
use sqlx::migrate::Migrator;
|
use sqlx::migrate::Migrator;
|
||||||
use sqlx::types::Json;
|
use sqlx::types::Json;
|
||||||
use tauri::{AppHandle, RunEvent, State, Window, WindowUrl};
|
use sqlx::{Pool, Sqlite, SqlitePool};
|
||||||
use tauri::{Manager, WindowEvent};
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
use tauri::TitleBarStyle;
|
use tauri::TitleBarStyle;
|
||||||
|
use tauri::{AppHandle, RunEvent, State, Window, WindowUrl};
|
||||||
|
use tauri::{Manager, WindowEvent};
|
||||||
use tauri_plugin_log::{fern, LogTarget};
|
use tauri_plugin_log::{fern, LogTarget};
|
||||||
use tauri_plugin_window_state::{StateFlags, WindowExt};
|
use tauri_plugin_window_state::{StateFlags, WindowExt};
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use window_shadows::set_shadow;
|
use window_shadows::set_shadow;
|
||||||
|
|
||||||
use ::grpc::{Code, deserialize_message, serialize_message, ServiceDefinition};
|
|
||||||
use ::grpc::manager::{DynamicMessage, GrpcHandle};
|
use ::grpc::manager::{DynamicMessage, GrpcHandle};
|
||||||
|
use ::grpc::{deserialize_message, serialize_message, Code, ServiceDefinition};
|
||||||
use window_ext::TrafficLightWindowExt;
|
use window_ext::TrafficLightWindowExt;
|
||||||
|
|
||||||
use crate::analytics::{AnalyticsAction, AnalyticsResource};
|
use crate::analytics::{AnalyticsAction, AnalyticsResource};
|
||||||
use crate::grpc::metadata_to_map;
|
use crate::grpc::metadata_to_map;
|
||||||
use crate::http::send_http_request;
|
use crate::http::send_http_request;
|
||||||
use crate::models::{cancel_pending_grpc_connections, cancel_pending_responses, CookieJar, create_http_response, delete_all_grpc_connections, delete_all_http_responses, delete_cookie_jar, delete_environment, delete_folder, delete_grpc_connection, delete_grpc_request, delete_http_request, delete_http_response, delete_workspace, duplicate_grpc_request, duplicate_http_request, Environment, EnvironmentVariable, Folder, get_cookie_jar, get_environment, get_folder, get_grpc_connection, get_grpc_request, get_http_request, get_http_response, get_key_value_raw, get_or_create_settings, get_workspace, get_workspace_export_resources, GrpcConnection, GrpcEvent, GrpcEventType, GrpcRequest, HttpRequest, HttpRequestHeader, HttpResponse, KeyValue, list_cookie_jars, list_environments, list_folders, list_grpc_connections, list_grpc_events, list_grpc_requests, list_http_requests, list_responses, list_workspaces, set_key_value_raw, Settings, update_response_if_id, update_settings, upsert_cookie_jar, upsert_environment, upsert_folder, upsert_grpc_connection, upsert_grpc_event, upsert_grpc_request, upsert_http_request, upsert_workspace, Workspace, WorkspaceExportResources};
|
use crate::models::{
|
||||||
|
cancel_pending_grpc_connections, cancel_pending_responses, create_http_response,
|
||||||
|
delete_all_grpc_connections, delete_all_http_responses, delete_cookie_jar, delete_environment,
|
||||||
|
delete_folder, delete_grpc_connection, delete_grpc_request, delete_http_request,
|
||||||
|
delete_http_response, delete_workspace, duplicate_grpc_request, duplicate_http_request,
|
||||||
|
get_cookie_jar, get_environment, get_folder, get_grpc_connection, get_grpc_request,
|
||||||
|
get_http_request, get_http_response, get_key_value_raw, get_or_create_settings, get_workspace,
|
||||||
|
get_workspace_export_resources, list_cookie_jars, list_environments, list_folders,
|
||||||
|
list_grpc_connections, list_grpc_events, list_grpc_requests, list_http_requests,
|
||||||
|
list_responses, list_workspaces, set_key_value_raw, update_response_if_id, update_settings,
|
||||||
|
upsert_cookie_jar, upsert_environment, upsert_folder, upsert_grpc_connection,
|
||||||
|
upsert_grpc_event, upsert_grpc_request, upsert_http_request, upsert_workspace, CookieJar,
|
||||||
|
Environment, EnvironmentVariable, Folder, GrpcConnection, GrpcEvent, GrpcEventType,
|
||||||
|
GrpcRequest, HttpRequest, HttpRequestHeader, HttpResponse, KeyValue, Settings, Workspace,
|
||||||
|
WorkspaceExportResources,
|
||||||
|
};
|
||||||
use crate::plugin::ImportResult;
|
use crate::plugin::ImportResult;
|
||||||
use crate::updates::{update_mode_from_str, UpdateMode, YaakUpdater};
|
use crate::updates::{update_mode_from_str, UpdateMode, YaakUpdater};
|
||||||
|
|
||||||
@@ -82,12 +97,12 @@ struct AppMetaData {
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_metadata(app_handle: AppHandle) -> Result<AppMetaData, ()> {
|
async fn cmd_metadata(app_handle: AppHandle) -> Result<AppMetaData, ()> {
|
||||||
let p = app_handle.path_resolver();
|
let p = app_handle.path_resolver();
|
||||||
return Ok(AppMetaData{
|
return Ok(AppMetaData {
|
||||||
is_dev: is_dev(),
|
is_dev: is_dev(),
|
||||||
version: app_handle.package_info().version.to_string(),
|
version: app_handle.package_info().version.to_string(),
|
||||||
name: app_handle.package_info().name.to_string(),
|
name: app_handle.package_info().name.to_string(),
|
||||||
app_data_dir: p.app_data_dir().unwrap().to_string_lossy().to_string(),
|
app_data_dir: p.app_data_dir().unwrap().to_string_lossy().to_string(),
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -707,17 +722,11 @@ async fn cmd_filter_response(w: Window, response_id: &str, filter: &str) -> Resu
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_import_data(
|
async fn cmd_import_data(w: Window, file_path: &str) -> Result<WorkspaceExportResources, String> {
|
||||||
w: Window,
|
|
||||||
file_paths: Vec<&str>,
|
|
||||||
) -> Result<WorkspaceExportResources, String> {
|
|
||||||
let mut result: Option<ImportResult> = None;
|
let mut result: Option<ImportResult> = None;
|
||||||
let plugins = vec!["importer-yaak", "importer-insomnia", "importer-postman"];
|
let plugins = vec!["importer-yaak", "importer-insomnia", "importer-postman"];
|
||||||
for plugin_name in plugins {
|
for plugin_name in plugins {
|
||||||
if let Some(r) =
|
if let Some(r) = plugin::run_plugin_import(&w.app_handle(), plugin_name, file_path).await {
|
||||||
plugin::run_plugin_import(&w.app_handle(), plugin_name, file_paths.first().unwrap())
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
analytics::track_event(
|
analytics::track_event(
|
||||||
&w.app_handle(),
|
&w.app_handle(),
|
||||||
AnalyticsResource::App,
|
AnalyticsResource::App,
|
||||||
@@ -731,29 +740,25 @@ async fn cmd_import_data(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
None => Err("No importers found for the chosen file".to_string()),
|
None => Err("No import handlers found".to_string()),
|
||||||
Some(r) => {
|
Some(r) => {
|
||||||
let mut imported_resources = WorkspaceExportResources::default();
|
let mut imported_resources = WorkspaceExportResources::default();
|
||||||
|
|
||||||
info!("Importing resources");
|
info!("Importing resources");
|
||||||
for v in r.resources.workspaces {
|
for v in r.resources.workspaces {
|
||||||
let x = upsert_workspace(&w, v)
|
let x = upsert_workspace(&w, v).await.map_err(|e| e.to_string())?;
|
||||||
.await
|
|
||||||
.expect("Failed to create workspace");
|
|
||||||
imported_resources.workspaces.push(x.clone());
|
imported_resources.workspaces.push(x.clone());
|
||||||
info!("Imported workspace: {}", x.name);
|
info!("Imported workspace: {}", x.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for v in r.resources.environments {
|
for v in r.resources.environments {
|
||||||
let x = upsert_environment(&w, v)
|
let x = upsert_environment(&w, v).await.map_err(|e| e.to_string())?;
|
||||||
.await
|
|
||||||
.expect("Failed to create environment");
|
|
||||||
imported_resources.environments.push(x.clone());
|
imported_resources.environments.push(x.clone());
|
||||||
info!("Imported environment: {}", x.name);
|
info!("Imported environment: {}", x.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for v in r.resources.folders {
|
for v in r.resources.folders {
|
||||||
let x = upsert_folder(&w, v).await.expect("Failed to create folder");
|
let x = upsert_folder(&w, v).await.map_err(|e| e.to_string())?;
|
||||||
imported_resources.folders.push(x.clone());
|
imported_resources.folders.push(x.clone());
|
||||||
info!("Imported folder: {}", x.name);
|
info!("Imported folder: {}", x.name);
|
||||||
}
|
}
|
||||||
@@ -761,7 +766,7 @@ async fn cmd_import_data(
|
|||||||
for v in r.resources.http_requests {
|
for v in r.resources.http_requests {
|
||||||
let x = upsert_http_request(&w, v)
|
let x = upsert_http_request(&w, v)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to create HTTP request");
|
.map_err(|e| e.to_string())?;
|
||||||
imported_resources.http_requests.push(x.clone());
|
imported_resources.http_requests.push(x.clone());
|
||||||
info!("Imported request: {}", x.name);
|
info!("Imported request: {}", x.name);
|
||||||
}
|
}
|
||||||
@@ -769,7 +774,7 @@ async fn cmd_import_data(
|
|||||||
for v in r.resources.grpc_requests {
|
for v in r.resources.grpc_requests {
|
||||||
let x = upsert_grpc_request(&w, &v)
|
let x = upsert_grpc_request(&w, &v)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to create GRPC request");
|
.map_err(|e| e.to_string())?;
|
||||||
imported_resources.grpc_requests.push(x.clone());
|
imported_resources.grpc_requests.push(x.clone());
|
||||||
info!("Imported request: {}", x.name);
|
info!("Imported request: {}", x.name);
|
||||||
}
|
}
|
||||||
@@ -822,14 +827,13 @@ async fn cmd_send_http_request(
|
|||||||
.expect("Failed to get request");
|
.expect("Failed to get request");
|
||||||
|
|
||||||
let environment = match environment_id {
|
let environment = match environment_id {
|
||||||
Some(id) =>
|
Some(id) => match get_environment(&window, id).await {
|
||||||
match get_environment(&window, id).await {
|
Ok(env) => Some(env),
|
||||||
Ok(env) => Some(env),
|
Err(e) => {
|
||||||
Err(e) => {
|
warn!("Failed to find environment by id {id} {}", e);
|
||||||
warn!("Failed to find environment by id {id} {}", e);
|
None
|
||||||
None
|
}
|
||||||
}
|
},
|
||||||
},
|
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export function useImportData() {
|
|||||||
httpRequests: HttpRequest[];
|
httpRequests: HttpRequest[];
|
||||||
grpcRequests: GrpcRequest[];
|
grpcRequests: GrpcRequest[];
|
||||||
} = await invoke('cmd_import_data', {
|
} = await invoke('cmd_import_data', {
|
||||||
filePaths: Array.isArray(selected) ? selected : [selected],
|
filePath: Array.isArray(selected) ? selected[0] : selected,
|
||||||
});
|
});
|
||||||
const importedWorkspace = imported.workspaces[0];
|
const importedWorkspace = imported.workspaces[0];
|
||||||
|
|
||||||
@@ -76,27 +76,40 @@ export function useImportData() {
|
|||||||
alert({ id: 'import-failed', title: 'Import Failed', body: err });
|
alert({ id: 'import-failed', title: 'Import Failed', body: err });
|
||||||
},
|
},
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
dialog.show({
|
return new Promise<void>((resolve, reject) => {
|
||||||
id: 'import',
|
dialog.show({
|
||||||
title: 'Import Data',
|
id: 'import',
|
||||||
size: 'sm',
|
title: 'Import Data',
|
||||||
render: ({ hide }) => {
|
size: 'sm',
|
||||||
return (
|
render: ({ hide }) => {
|
||||||
<VStack space={3} className="pb-4">
|
return (
|
||||||
<p>Insomnia or Postman Collection v2/v2.1 formats are supported</p>
|
<VStack space={5} className="pb-4">
|
||||||
<Button
|
<VStack space={1}>
|
||||||
size="sm"
|
<p>Supported Formats:</p>
|
||||||
color="primary"
|
<ul className="list-disc pl-5">
|
||||||
onClick={async () => {
|
<li>Postman Collection v2/v2.1</li>
|
||||||
await importData();
|
<li>Insomnia</li>
|
||||||
hide();
|
</ul>
|
||||||
}}
|
</VStack>
|
||||||
>
|
<Button
|
||||||
Select File
|
size="sm"
|
||||||
</Button>
|
color="primary"
|
||||||
</VStack>
|
onClick={async () => {
|
||||||
);
|
try {
|
||||||
},
|
await importData();
|
||||||
|
resolve();
|
||||||
|
} catch (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
hide();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Select File
|
||||||
|
</Button>
|
||||||
|
</VStack>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user