| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- use crate::{
- db::{self, Update},
- request::{
- self,
- url::{RequestUrl, RequestUrlOwned, Segment, UrlError},
- EntryRequestBody, HttpRequestParameters, HttpResponse, RequestBody, RequestHeader,
- RequestHeaderInsert, RequestHeaderUpdate, RequestPathParam, RequestPathUpdate,
- },
- state::AppState,
- var::{expand_vars, parse_vars},
- workspace::{
- Workspace, WorkspaceEntry, WorkspaceEntryBase, WorkspaceEntryCreate, WorkspaceEntryUpdate,
- WorkspaceEntryUpdateBase, WorkspaceEnvVariable, WorkspaceEnvironment,
- },
- };
- use tauri_plugin_log::log;
- #[tauri::command]
- pub async fn list_workspaces(state: tauri::State<'_, AppState>) -> Result<Vec<Workspace>, String> {
- match db::list_workspaces(state.db.clone()).await {
- Ok(ws) => Ok(ws),
- Err(e) => Err(e.to_string()),
- }
- }
- #[tauri::command]
- pub async fn create_workspace(
- state: tauri::State<'_, AppState>,
- name: String,
- ) -> Result<Workspace, String> {
- match db::create_workspace(state.db.clone(), name).await {
- Ok(ws) => Ok(ws),
- Err(e) => Err(e.to_string()),
- }
- }
- #[tauri::command]
- pub async fn list_workspace_entries(
- state: tauri::State<'_, AppState>,
- id: i64,
- ) -> Result<Vec<WorkspaceEntry>, String> {
- match db::list_workspace_entries(state.db.clone(), id).await {
- Ok(ws) => Ok(ws),
- Err(e) => Err(e.to_string()),
- }
- }
- #[tauri::command]
- pub async fn create_workspace_entry(
- state: tauri::State<'_, AppState>,
- data: WorkspaceEntryCreate,
- ) -> Result<WorkspaceEntryBase, String> {
- match db::create_workspace_entry(state.db.clone(), data).await {
- Ok(ws) => Ok(ws),
- Err(e) => Err(e.to_string()),
- }
- }
- #[tauri::command]
- pub async fn update_workspace_entry(
- state: tauri::State<'_, AppState>,
- entry_id: i64,
- data: WorkspaceEntryUpdate,
- ) -> Result<(), String> {
- match db::update_workspace_entry(state.db.clone(), entry_id, data).await {
- Ok(()) => Ok(()),
- Err(e) => Err(e.to_string()),
- }
- }
- #[tauri::command]
- pub async fn insert_request_body(
- state: tauri::State<'_, AppState>,
- entry_id: i64,
- body: RequestBody,
- ) -> Result<EntryRequestBody, String> {
- match db::insert_request_body(state.db.clone(), entry_id, body).await {
- Ok(b) => Ok(b),
- Err(e) => return Err(e.to_string()),
- }
- }
- #[tauri::command]
- pub async fn update_request_body(
- state: tauri::State<'_, AppState>,
- id: i64,
- body: Update<RequestBody>,
- ) -> Result<(), String> {
- if let Err(e) = db::update_request_body(state.db.clone(), id, body).await {
- return Err(e.to_string());
- }
- Ok(())
- }
- #[tauri::command]
- pub async fn parse_url(url: String) -> Result<RequestUrlOwned, UrlError> {
- match RequestUrl::parse(&url) {
- Ok(url_parsed) => Ok(url_parsed.into()),
- Err(e) => {
- log::debug!("{e:?}");
- Err(UrlError::Parse(e))
- }
- }
- }
- #[tauri::command]
- pub async fn expand_url(
- state: tauri::State<'_, AppState>,
- entry_id: i64,
- env_id: Option<i64>,
- mut url: String,
- ) -> Result<String, UrlError> {
- if let Some(env_id) = env_id {
- let vars = match parse_vars(&url) {
- Ok(vars) => vars.iter().map(|v| v.name).collect::<Vec<_>>(),
- Err(e) => return Err(UrlError::Var(e.to_string())),
- };
- if !vars.is_empty() {
- let vars = match db::get_env_variables(state.db.clone(), env_id, &vars).await {
- Ok(v) => v,
- Err(e) => return Err(UrlError::Db(e.to_string())),
- };
- url = expand_vars(&url, &vars);
- }
- }
- match RequestUrl::parse(&url) {
- Ok(mut url) => {
- let params = match db::list_request_path_params(state.db.clone(), entry_id).await {
- Ok(p) => p,
- Err(e) => return Err(UrlError::Db(e.to_string())),
- };
- url.populate_path(
- params
- .iter()
- .map(|p| (p.name.as_str(), p.value.as_str()))
- .collect(),
- );
- let url = url.to_string();
- let vars = match parse_vars(&url) {
- Ok(vars) => vars.iter().map(|v| v.name).collect::<Vec<_>>(),
- Err(e) => return Err(UrlError::Var(e.to_string())),
- };
- if vars.is_empty() {
- return Ok(url);
- }
- let Some(env_id) = env_id else {
- return Ok(url);
- };
- let vars = match db::get_env_variables(state.db.clone(), env_id, &vars).await {
- Ok(v) => v,
- Err(e) => return Err(UrlError::Db(e.to_string())),
- };
- Ok(expand_vars(&url.to_string(), &vars))
- }
- Err(e) => {
- log::debug!("{e:?}");
- Err(UrlError::Parse(e))
- }
- }
- }
- /// Updates a URL.
- ///
- /// * `entry_id`: The request entry ID whose URL will be updated.
- /// * `env_id`: The environment to use for expanding variables.
- /// * `url`: The URL string which will be populated from the env and parsed with [RequestUrl].
- /// * `path_params`: List of dynamic path params to persist for the URL.
- #[tauri::command]
- pub async fn update_url(
- state: tauri::State<'_, AppState>,
- entry_id: i64,
- use_path_params: bool,
- url: String,
- // Dynamic path params
- path_params: Vec<RequestPathParam>,
- ) -> Result<(RequestUrlOwned, Vec<RequestPathParam>), UrlError> {
- match RequestUrl::parse(&url) {
- Ok(mut url_parsed) => {
- let mut update: Vec<RequestPathUpdate> = vec![];
- let mut subs = vec![];
- for seg in url_parsed.path.iter_mut() {
- if let Segment::Dynamic(seg, position) = seg {
- let Some(path_param) = path_params
- .iter()
- .find(|pp| pp.position as usize == *position || &pp.name == seg)
- else {
- update.push(RequestPathUpdate {
- position: *position,
- name: seg.to_string(),
- value: None,
- });
- continue;
- };
- if use_path_params {
- update.push(RequestPathUpdate {
- position: *position,
- name: path_param.name.clone(),
- value: Some(path_param.value.clone()),
- });
- subs.push(Segment::Dynamic(&path_param.name, *position));
- } else {
- update.push(RequestPathUpdate {
- position: *position,
- name: seg.to_string(),
- value: Some(path_param.value.clone()),
- })
- }
- }
- }
- dbg!(&subs);
- for sub in subs {
- url_parsed.swap_path_segment(sub);
- }
- dbg!(&update, &url_parsed);
- db::update_workspace_entry(
- state.db.clone(),
- entry_id,
- WorkspaceEntryUpdate::Request {
- path_params: Some(update),
- url: Some(url_parsed.to_string()),
- base: WorkspaceEntryUpdateBase::default(),
- method: None,
- },
- )
- .await
- .map_err(|e| UrlError::Db(e.to_string()))?;
- let params = match db::list_request_path_params(state.db.clone(), entry_id).await {
- Ok(p) => p,
- Err(e) => return Err(UrlError::Db(e.to_string())),
- };
- dbg!(&url_parsed, ¶ms);
- Ok((url_parsed.into(), params))
- }
- Err(e) => {
- log::debug!("{e:?}");
- Err(UrlError::Parse(e))
- }
- }
- }
- #[tauri::command]
- pub async fn send_request(
- state: tauri::State<'_, AppState>,
- req_id: i64,
- env_id: Option<i64>,
- ) -> Result<HttpResponse, String> {
- let mut req = match db::get_workspace_request(state.db.clone(), req_id).await {
- Ok(req) => req,
- Err(e) => return Err(e.to_string()),
- };
- req.url = if let Some(env_id) = env_id {
- let vars = match parse_vars(&req.url) {
- Ok(vars) => vars.iter().map(|v| v.name).collect::<Vec<_>>(),
- Err(e) => return Err(e.to_string()),
- };
- let vars = match db::get_env_variables(state.db.clone(), env_id, &vars).await {
- Ok(v) => v,
- Err(e) => return Err(e.to_string()),
- };
- expand_vars(&req.url, &vars)
- } else {
- req.url
- };
- let req = match RequestUrl::parse(&req.url.to_string()) {
- Ok(mut url) => {
- let params = match db::list_request_path_params(state.db.clone(), req_id).await {
- Ok(p) => p,
- Err(e) => return Err(e.to_string()),
- };
- url.populate_path(
- params
- .iter()
- .map(|p| (p.name.as_str(), p.value.as_str()))
- .collect(),
- );
- req.url = url.to_string();
- let vars = match parse_vars(&req.url) {
- Ok(vars) => vars.iter().map(|v| v.name).collect::<Vec<_>>(),
- Err(e) => return Err(e.to_string()),
- };
- req.url = if let Some(env_id) = env_id {
- let vars = match db::get_env_variables(state.db.clone(), env_id, &vars).await {
- Ok(v) => v,
- Err(e) => return Err(e.to_string()),
- };
- expand_vars(&url.to_string(), &vars)
- } else {
- req.url
- };
- HttpRequestParameters::try_from(req)?
- }
- Err(e) => {
- log::debug!("{e:?}");
- return Err(String::from("error parsing URL"));
- }
- };
- let response = match request::send(state.client.clone(), req).await {
- Ok(res) => res,
- Err(e) => return Err(e.to_string()),
- };
- Ok(response)
- }
- #[tauri::command]
- pub async fn list_environments(
- state: tauri::State<'_, AppState>,
- workspace_id: i64,
- ) -> Result<Vec<WorkspaceEnvironment>, String> {
- match db::list_environments(state.db.clone(), workspace_id).await {
- Ok(ws) => Ok(ws),
- Err(e) => Err(e.to_string()),
- }
- }
- #[tauri::command]
- pub async fn create_env(
- state: tauri::State<'_, AppState>,
- workspace_id: i64,
- name: String,
- ) -> Result<WorkspaceEnvironment, String> {
- match db::create_environment(state.db.clone(), workspace_id, name).await {
- Ok(ws) => Ok(ws),
- Err(e) => Err(e.to_string()),
- }
- }
- #[tauri::command]
- pub async fn update_env(
- state: tauri::State<'_, AppState>,
- id: i64,
- name: String,
- ) -> Result<(), String> {
- if let Err(e) = db::update_environment(state.db.clone(), id, name).await {
- return Err(e.to_string());
- }
- Ok(())
- }
- #[tauri::command]
- pub async fn insert_env_var(
- state: tauri::State<'_, AppState>,
- workspace_id: i64,
- env_id: i64,
- name: String,
- value: String,
- secret: bool,
- ) -> Result<WorkspaceEnvVariable, String> {
- match db::insert_env_var(state.db.clone(), workspace_id, env_id, name, value, secret).await {
- Ok(var) => Ok(var),
- Err(e) => Err(e.to_string()),
- }
- }
- #[tauri::command]
- pub async fn update_env_var(
- state: tauri::State<'_, AppState>,
- id: i64,
- name: Option<String>,
- value: Option<String>,
- secret: Option<bool>,
- ) -> Result<(), String> {
- if let Err(e) = db::update_env_var(state.db.clone(), id, name, value, secret).await {
- return Err(e.to_string());
- }
- Ok(())
- }
- #[tauri::command]
- pub async fn delete_env_var(state: tauri::State<'_, AppState>, id: i64) -> Result<(), String> {
- if let Err(e) = db::delete_env_var(state.db.clone(), id).await {
- return Err(e.to_string());
- }
- Ok(())
- }
- #[tauri::command]
- pub async fn insert_header(
- state: tauri::State<'_, AppState>,
- entry_id: i64,
- insert: RequestHeaderInsert,
- ) -> Result<RequestHeader, String> {
- match db::insert_headers(state.db.clone(), entry_id, vec![insert]).await {
- Ok(header) => Ok(header),
- Err(e) => return Err(e.to_string()),
- }
- }
- #[tauri::command]
- pub async fn update_header(
- state: tauri::State<'_, AppState>,
- update: RequestHeaderUpdate,
- ) -> Result<(), String> {
- if let Err(e) = db::update_header(state.db.clone(), update).await {
- return Err(e.to_string());
- }
- Ok(())
- }
- #[tauri::command]
- pub async fn delete_header(
- state: tauri::State<'_, AppState>,
- header_id: i64,
- ) -> Result<(), String> {
- if let Err(e) = db::delete_header(state.db.clone(), header_id).await {
- return Err(e.to_string());
- }
- Ok(())
- }
|