From c348eb31ea6eefea919f46cce188434e2edba346 Mon Sep 17 00:00:00 2001 From: Fabian-Lars Date: Wed, 15 Feb 2023 13:06:43 +0100 Subject: [PATCH 01/71] feat(upload): Add function to download files (#89) --- Cargo.lock | 2 +- plugins/upload/Cargo.toml | 2 +- plugins/upload/guest-js/index.ts | 35 ++++++++++++++++++++--- plugins/upload/src/lib.rs | 48 ++++++++++++++++++++++++++++++-- 4 files changed, 78 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75568883..ebd4ec1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4422,7 +4422,7 @@ dependencies = [ name = "tauri-plugin-upload" version = "0.1.0" dependencies = [ - "futures", + "futures-util", "log", "read-progress-stream", "reqwest", diff --git a/plugins/upload/Cargo.toml b/plugins/upload/Cargo.toml index 26ec517e..985645d6 100644 --- a/plugins/upload/Cargo.toml +++ b/plugins/upload/Cargo.toml @@ -18,5 +18,5 @@ thiserror.workspace = true tokio = { version = "1", features = [ "fs" ] } tokio-util = { version = "0.7", features = [ "codec" ] } reqwest = { version = "0.11", features = [ "json", "stream" ] } -futures = "0.3" +futures-util = "0.3" read-progress-stream = "1.0.0" \ No newline at end of file diff --git a/plugins/upload/guest-js/index.ts b/plugins/upload/guest-js/index.ts index 88f5202e..7b4a94c7 100644 --- a/plugins/upload/guest-js/index.ts +++ b/plugins/upload/guest-js/index.ts @@ -11,12 +11,12 @@ type ProgressHandler = (progress: number, total: number) => void; const handlers: Map = new Map(); let listening = false; -async function listenToUploadEventIfNeeded(): Promise { +async function listenToEventIfNeeded(event: string): Promise { if (listening) { return await Promise.resolve(); } return await appWindow - .listen("upload://progress", ({ payload }) => { + .listen(event, ({ payload }) => { const handler = handlers.get(payload.id); if (handler != null) { handler(payload.progress, payload.total); @@ -27,7 +27,7 @@ async function listenToUploadEventIfNeeded(): Promise { }); } -export default async function upload( +async function upload( url: string, filePath: string, progressHandler?: ProgressHandler, @@ -41,7 +41,7 @@ export default async function upload( handlers.set(id, progressHandler); } - await listenToUploadEventIfNeeded(); + await listenToEventIfNeeded("upload://progress"); await invoke("plugin:upload|upload", { id, @@ -50,3 +50,30 @@ export default async function upload( headers: headers ?? {}, }); } + +async function download( + url: string, + filePath: string, + progressHandler?: ProgressHandler, + headers?: Map +): Promise { + const ids = new Uint32Array(1); + window.crypto.getRandomValues(ids); + const id = ids[0]; + + if (progressHandler != null) { + handlers.set(id, progressHandler); + } + + await listenToEventIfNeeded("download://progress"); + + await invoke("plugin:upload|upload", { + id, + url, + filePath, + headers: headers ?? {}, + }); +} + +export default upload; +export { download, upload }; diff --git a/plugins/upload/src/lib.rs b/plugins/upload/src/lib.rs index a83a87ff..f57683c6 100644 --- a/plugins/upload/src/lib.rs +++ b/plugins/upload/src/lib.rs @@ -2,14 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use futures::TryStreamExt; +use futures_util::TryStreamExt; use serde::{ser::Serializer, Serialize}; use tauri::{ command, plugin::{Builder as PluginBuilder, TauriPlugin}, Runtime, Window, }; -use tokio::fs::File; +use tokio::{fs::File, io::AsyncWriteExt}; use tokio_util::codec::{BytesCodec, FramedRead}; use read_progress_stream::ReadProgressStream; @@ -24,6 +24,8 @@ pub enum Error { Io(#[from] std::io::Error), #[error(transparent)] Request(#[from] reqwest::Error), + #[error("{0}")] + ContentLength(String), } impl Serialize for Error { @@ -42,6 +44,46 @@ struct ProgressPayload { total: u64, } +#[command] +async fn download( + window: Window, + id: u32, + url: &str, + file_path: &str, + headers: HashMap, +) -> Result { + let client = reqwest::Client::new(); + + let mut request = client.get(url); + // Loop trought the headers keys and values + // and add them to the request object. + for (key, value) in headers { + request = request.header(&key, value); + } + + let response = request.send().await?; + let total = response.content_length().ok_or_else(|| { + Error::ContentLength(format!("Failed to get content length from '{}'", url)) + })?; + + let mut file = File::create(file_path).await?; + let mut stream = response.bytes_stream(); + + while let Some(chunk) = stream.try_next().await? { + file.write_all(&chunk).await?; + let _ = window.emit( + "download://progress", + ProgressPayload { + id, + progress: chunk.len() as u64, + total, + }, + ); + } + + Ok(id) +} + #[command] async fn upload( window: Window, @@ -88,6 +130,6 @@ fn file_to_body(id: u32, window: Window, file: File) -> reqwest:: pub fn init() -> TauriPlugin { PluginBuilder::new("upload") - .invoke_handler(tauri::generate_handler![upload]) + .invoke_handler(tauri::generate_handler![download, upload]) .build() } From d18bc1ea603882484ca0a05b11f2434d02e41c3d Mon Sep 17 00:00:00 2001 From: Fabian-Lars Date: Wed, 15 Feb 2023 13:07:21 +0100 Subject: [PATCH 02/71] fix(sql): derive datatype from value, not colomn (#118) --- plugins/sql/src/plugin.rs | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/plugins/sql/src/plugin.rs b/plugins/sql/src/plugin.rs index e7deb885..c33e81e6 100644 --- a/plugins/sql/src/plugin.rs +++ b/plugins/sql/src/plugin.rs @@ -10,7 +10,7 @@ use sqlx::{ migrate::{ MigrateDatabase, Migration as SqlxMigration, MigrationSource, MigrationType, Migrator, }, - Column, Pool, Row, TypeInfo, + Column, Pool, Row, TypeInfo, ValueRef, }; use tauri::{ command, @@ -44,6 +44,8 @@ pub enum Error { Migration(#[from] sqlx::migrate::MigrateError), #[error("database {0} not loaded")] DatabaseNotLoaded(String), + #[error("unsupported datatype: {0}")] + UnsupportedDatatype(String), } impl Serialize for Error { @@ -246,12 +248,16 @@ async fn select( for row in rows { let mut value = HashMap::default(); for (i, column) in row.columns().iter().enumerate() { - let info = column.type_info(); - let v = if info.is_null() { + let v = row.try_get_raw(i)?; + + let v = if v.is_null() { JsonValue::Null } else { - match info.name() { - "VARCHAR" | "STRING" | "TEXT" | "DATETIME" | "JSON" => { + // TODO: postgresql's JSON type + match v.type_info().name() { + "VARCHAR" | "STRING" | "TEXT" | "TINYTEXT" | "LONGTEXT" | "NVARCHAR" + | "BIGVARCHAR" | "CHAR" | "BIGCHAR" | "NCHAR" | "DATETIME" | "DATE" + | "TIME" | "YEAR" | "TIMESTAMP" => { if let Ok(s) = row.try_get(i) { JsonValue::String(s) } else { @@ -266,22 +272,25 @@ async fn select( JsonValue::Bool(x.to_lowercase() == "true") } } - "INT" | "NUMBER" | "INTEGER" | "BIGINT" | "INT8" => { + "INT" | "NUMBER" | "INTEGER" | "BIGINT" | "INT2" | "INT4" | "INT8" + | "NUMERIC" | "TINYINT" | "SMALLINT" | "MEDIUMINT" | "TINYINT UNSINGED" + | "SMALLINT UNSINGED" | "INT UNSINGED" | "MEDIUMINT UNSINGED" + | "BIGINT UNSINGED" => { if let Ok(n) = row.try_get::(i) { JsonValue::Number(n.into()) } else { JsonValue::Null } } - "REAL" => { + "REAL" | "FLOAT" | "DOUBLE" | "FLOAT4" | "FLOAT8" => { if let Ok(n) = row.try_get::(i) { JsonValue::from(n) } else { JsonValue::Null } } - // "JSON" => JsonValue::Object(row.get(i)), - "BLOB" => { + "BLOB" | "TINYBLOB" | "MEDIUMBLOB" | "LONGBLOB" | "BINARY" | "VARBINARY" + | "BYTEA" => { if let Ok(n) = row.try_get::, usize>(i) { JsonValue::Array( n.into_iter().map(|n| JsonValue::Number(n.into())).collect(), @@ -290,13 +299,16 @@ async fn select( JsonValue::Null } } - _ => JsonValue::Null, + _ => return Err(Error::UnsupportedDatatype(v.type_info().name().to_string())), } }; + value.insert(column.name().to_string(), v); } + values.push(value); } + Ok(values) } From 2e090c90cd28a5d4aea4018b5f7741916545f77a Mon Sep 17 00:00:00 2001 From: Fabian-Lars Date: Wed, 15 Feb 2023 14:32:17 +0100 Subject: [PATCH 03/71] chore: Add MSRV to all readmes (#255) * chore: Add MSRV to all readmes * fix single-instance support matrix * wording * wording * typo --- README.md | 5 ++++- plugins/authenticator/README.md | 2 ++ plugins/autostart/README.md | 2 ++ plugins/fs-extra/README.md | 2 ++ plugins/fs-watch/README.md | 2 ++ plugins/localhost/README.md | 2 ++ plugins/log/README.md | 2 ++ plugins/persisted-scope/README.md | 2 ++ plugins/positioner/README.md | 2 ++ plugins/single-instance/README.md | 2 ++ plugins/sql/README.md | 2 ++ plugins/store/README.md | 2 ++ plugins/stronghold/README.md | 2 ++ plugins/upload/README.md | 2 ++ plugins/websocket/README.md | 2 ++ plugins/window-state/README.md | 2 ++ shared/template/README.md | 2 ++ 17 files changed, 36 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 57583af9..cc7541ae 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,12 @@ | [log](plugins/log) | Configurable logging. | ✅ | ✅ | ✅ | ✅ | ✅ | | [persisted-scope](plugins/persisted-scope) | Persist runtime scope changes on the filesystem. | ✅ | ✅ | ✅ | ? | ? | | [positioner](plugins/positioner) | Move windows to common locations. | ✅ | ✅ | ✅ | ? | ? | +| [single-instance](plugins/single-instance) | Ensure a single instance of your tauri app is running. | ✅ | ? | ✅ | ? | ? | | [sql](plugins/sql) | Interface with SQL databases. | ✅ | ✅ | ✅ | ? | ? | | [store](plugins/store) | Persistent key value storage. | ✅ | ✅ | ✅ | ? | ? | | [stronghold](plugins/stronghold) | Encrypted, secure database. | ✅ | ✅ | ✅ | ? | ? | | [upload](plugins/upload) | Tauri plugin for file uploads through HTTP. | ✅ | ✅ | ✅ | ? | ? | -| [websocket](plugins/websocket) | | ✅ | ✅ | ✅ | ? | ? | +| [websocket](plugins/websocket) | Open a WebSocket connection using a Rust client in JS. | ✅ | ✅ | ✅ | ? | ? | | [window-state](plugins/window-state) | Persist window sizes and positions. | ✅ | ✅ | ✅ | ? | ? | + +_This repo and all plugins require a Rust version of at least **1.64**_ diff --git a/plugins/authenticator/README.md b/plugins/authenticator/README.md index 884d81b9..0e700f6a 100644 --- a/plugins/authenticator/README.md +++ b/plugins/authenticator/README.md @@ -4,6 +4,8 @@ Use hardware security-keys in your Tauri App. ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/autostart/README.md b/plugins/autostart/README.md index 78859423..419907c3 100644 --- a/plugins/autostart/README.md +++ b/plugins/autostart/README.md @@ -4,6 +4,8 @@ Automatically launch your application at startup. Supports Windows, Mac (via App ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/fs-extra/README.md b/plugins/fs-extra/README.md index 6ea6ea1c..98d311fe 100644 --- a/plugins/fs-extra/README.md +++ b/plugins/fs-extra/README.md @@ -4,6 +4,8 @@ Additional file system methods not included in the core API. ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/fs-watch/README.md b/plugins/fs-watch/README.md index 26ee5bfc..8162d1fe 100644 --- a/plugins/fs-watch/README.md +++ b/plugins/fs-watch/README.md @@ -4,6 +4,8 @@ Watch files and directories for changes using [notify](https://github.com/notify ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/localhost/README.md b/plugins/localhost/README.md index 23b07577..50665f66 100644 --- a/plugins/localhost/README.md +++ b/plugins/localhost/README.md @@ -6,6 +6,8 @@ Expose your apps assets through a localhost server instead of the default custom ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/log/README.md b/plugins/log/README.md index f49c2c7b..fca43611 100644 --- a/plugins/log/README.md +++ b/plugins/log/README.md @@ -4,6 +4,8 @@ Configurable logging for your Tauri app. ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/persisted-scope/README.md b/plugins/persisted-scope/README.md index 43dd5909..26888b59 100644 --- a/plugins/persisted-scope/README.md +++ b/plugins/persisted-scope/README.md @@ -4,6 +4,8 @@ Save filesystem and asset scopes and restore them when the app is reopened. ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/positioner/README.md b/plugins/positioner/README.md index 54332ddc..ebac8500 100644 --- a/plugins/positioner/README.md +++ b/plugins/positioner/README.md @@ -6,6 +6,8 @@ This plugin is a port of [electron-positioner](https://github.com/jenslind/elect ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/single-instance/README.md b/plugins/single-instance/README.md index 75d985e9..1efbba90 100644 --- a/plugins/single-instance/README.md +++ b/plugins/single-instance/README.md @@ -4,6 +4,8 @@ Ensure a single instance of your tauri app is running. ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/sql/README.md b/plugins/sql/README.md index 6b034f7c..7ec807b1 100644 --- a/plugins/sql/README.md +++ b/plugins/sql/README.md @@ -4,6 +4,8 @@ Interface with SQL databases through [sqlx](https://github.com/launchbadge/sqlx) ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/store/README.md b/plugins/store/README.md index 0e1eb29a..3c3f7c7e 100644 --- a/plugins/store/README.md +++ b/plugins/store/README.md @@ -4,6 +4,8 @@ Simple, persistent key-value store. ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/stronghold/README.md b/plugins/stronghold/README.md index bc79b46c..2b5b2790 100644 --- a/plugins/stronghold/README.md +++ b/plugins/stronghold/README.md @@ -4,6 +4,8 @@ Store secrets and keys using the [IOTA Stronghold](https://github.com/iotaledger ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/upload/README.md b/plugins/upload/README.md index 1168a362..cd24a9d5 100644 --- a/plugins/upload/README.md +++ b/plugins/upload/README.md @@ -4,6 +4,8 @@ Upload files from disk to a remote server over HTTP. ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/websocket/README.md b/plugins/websocket/README.md index 954a650f..96c5c324 100644 --- a/plugins/websocket/README.md +++ b/plugins/websocket/README.md @@ -4,6 +4,8 @@ ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/plugins/window-state/README.md b/plugins/window-state/README.md index de86ae9e..303d54a5 100644 --- a/plugins/window-state/README.md +++ b/plugins/window-state/README.md @@ -4,6 +4,8 @@ Save window positions and sizes and restore them when the app is reopened. ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) diff --git a/shared/template/README.md b/shared/template/README.md index 0a059e4f..ed5545a2 100644 --- a/shared/template/README.md +++ b/shared/template/README.md @@ -4,6 +4,8 @@ ## Install +_This plugin requires a Rust version of at least **1.64**_ + There are three general methods of installation that we can recommend. 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) From e203b4f68f139e83d282af2f33461eb360956db2 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Wed, 15 Feb 2023 17:28:36 +0330 Subject: [PATCH 04/71] fix(autostart): fix auto start choosing wrong app path on macOS (#125) * Update lib.rs * Update lib.rs * Update lib.rs --------- Co-authored-by: Fabian-Lars --- plugins/autostart/src/lib.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/plugins/autostart/src/lib.rs b/plugins/autostart/src/lib.rs index 509e6b3f..91dcfa27 100644 --- a/plugins/autostart/src/lib.rs +++ b/plugins/autostart/src/lib.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: MIT use auto_launch::{AutoLaunch, AutoLaunchBuilder}; +use log::info; use serde::{ser::Serializer, Serialize}; use tauri::{ command, @@ -98,7 +99,6 @@ pub fn init( .invoke_handler(tauri::generate_handler![enable, disable, is_enabled]) .setup(move |app| { let mut builder = AutoLaunchBuilder::new(); - builder.set_app_name(&app.package_info().name); if let Some(args) = args { builder.set_args(&args); @@ -110,7 +110,26 @@ pub fn init( #[cfg(windows)] builder.set_app_path(¤t_exe.display().to_string()); #[cfg(target_os = "macos")] - builder.set_app_path(¤t_exe.canonicalize()?.display().to_string()); + { + // on macOS, current_exe gives path to /Applications/Example.app/MacOS/Example + // but this results in seeing a Unix Executable in macOS login items + // It must be: /Applications/Example.app + // If it didn't find exactly a single occurance of .app, it will default to + // exe path to not break it. + let exe_path = current_exe.canonicalize()?.display().to_string(); + let parts: Vec<&str> = exe_path.split(".app/").collect(); + let app_path = if parts.len() == 2 { + format!( + "{}{}", + parts.get(0).unwrap().to_string(), + ".app" + ) + } else { + exe_path + }; + info!("auto_start path {}", &app_path); + builder.set_app_path(&app_path); + } #[cfg(target_os = "linux")] if let Some(appimage) = app .env() From 92d9f2754c34559a65392fd3e7eefbbcb060ff68 Mon Sep 17 00:00:00 2001 From: Fabian-Lars Date: Wed, 15 Feb 2023 15:32:11 +0100 Subject: [PATCH 05/71] chore: apply clippy suggestions (#256) --- plugins/autostart/src/lib.rs | 7 ++----- plugins/upload/src/lib.rs | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/plugins/autostart/src/lib.rs b/plugins/autostart/src/lib.rs index 91dcfa27..3c76c34a 100644 --- a/plugins/autostart/src/lib.rs +++ b/plugins/autostart/src/lib.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: MIT use auto_launch::{AutoLaunch, AutoLaunchBuilder}; +#[cfg(target_os = "macos")] use log::info; use serde::{ser::Serializer, Serialize}; use tauri::{ @@ -119,11 +120,7 @@ pub fn init( let exe_path = current_exe.canonicalize()?.display().to_string(); let parts: Vec<&str> = exe_path.split(".app/").collect(); let app_path = if parts.len() == 2 { - format!( - "{}{}", - parts.get(0).unwrap().to_string(), - ".app" - ) + format!("{}.app", parts.get(0).unwrap().to_string()) } else { exe_path }; diff --git a/plugins/upload/src/lib.rs b/plugins/upload/src/lib.rs index f57683c6..21154e89 100644 --- a/plugins/upload/src/lib.rs +++ b/plugins/upload/src/lib.rs @@ -63,7 +63,7 @@ async fn download( let response = request.send().await?; let total = response.content_length().ok_or_else(|| { - Error::ContentLength(format!("Failed to get content length from '{}'", url)) + Error::ContentLength(format!("Failed to get content length from '{url}'")) })?; let mut file = File::create(file_path).await?; From aeb21251766c83574949f8d293b8fcd0dcd2a29b Mon Sep 17 00:00:00 2001 From: Fabian-Lars Date: Fri, 17 Feb 2023 21:14:42 +0100 Subject: [PATCH 06/71] chore(single-instance): Fix banner link in readme --- plugins/single-instance/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/single-instance/README.md b/plugins/single-instance/README.md index 1efbba90..c6b0c685 100644 --- a/plugins/single-instance/README.md +++ b/plugins/single-instance/README.md @@ -1,4 +1,4 @@ -![tauri-plugin-single-instance](banner.jpg) +![tauri-plugin-single-instance](banner.png) Ensure a single instance of your tauri app is running. From 8f0d662ea959c671405c36f5f1d349088fe85199 Mon Sep 17 00:00:00 2001 From: Fabian-Lars Date: Thu, 23 Feb 2023 13:30:32 +0100 Subject: [PATCH 07/71] fix(upload): download function invokes wrong command --- plugins/upload/guest-js/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/upload/guest-js/index.ts b/plugins/upload/guest-js/index.ts index 7b4a94c7..d2eced4e 100644 --- a/plugins/upload/guest-js/index.ts +++ b/plugins/upload/guest-js/index.ts @@ -67,7 +67,7 @@ async function download( await listenToEventIfNeeded("download://progress"); - await invoke("plugin:upload|upload", { + await invoke("plugin:upload|download", { id, url, filePath, From 8f34eb83e4f9a8c72fd3823a066c94f861f2d021 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 23 Feb 2023 13:54:46 +0100 Subject: [PATCH 08/71] fix(deps): update rust crate windows-sys to 0.45 (#103) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 42 +++++++++++++++++++++++------- plugins/single-instance/Cargo.toml | 2 +- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ebd4ec1a..35300066 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -153,7 +153,7 @@ dependencies = [ "slab", "socket2", "waker-fn", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1156,7 +1156,7 @@ dependencies = [ "cfg-if", "libc", "redox_syscall", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -2384,7 +2384,7 @@ dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -2506,7 +2506,7 @@ dependencies = [ "mio", "serde", "walkdir", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -2808,7 +2808,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -3046,7 +3046,7 @@ dependencies = [ "libc", "log", "wepoll-ffi", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -3489,7 +3489,7 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -4372,7 +4372,7 @@ dependencies = [ "serde_json", "tauri", "thiserror", - "windows-sys", + "windows-sys 0.45.0", "zbus", ] @@ -4678,7 +4678,7 @@ dependencies = [ "num_cpus", "pin-project-lite", "socket2", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -5414,6 +5414,30 @@ dependencies = [ "windows_x86_64_msvc 0.42.1", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.1", +] + [[package]] name = "windows-tokens" version = "0.39.0" diff --git a/plugins/single-instance/Cargo.toml b/plugins/single-instance/Cargo.toml index 4762e033..d57ff092 100644 --- a/plugins/single-instance/Cargo.toml +++ b/plugins/single-instance/Cargo.toml @@ -18,7 +18,7 @@ log.workspace = true thiserror.workspace = true [target.'cfg(target_os = "windows")'.dependencies.windows-sys] -version = "0.42" +version = "0.45" features = [ "Win32_System_Threading", "Win32_System_DataExchange", From 265acf745435dabe78321ff7cf1e0af92df566e2 Mon Sep 17 00:00:00 2001 From: Flux Xu Date: Mon, 27 Feb 2023 03:15:07 -0500 Subject: [PATCH 09/71] docs(single-instance): Fix a typo (#264) --- plugins/single-instance/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/single-instance/README.md b/plugins/single-instance/README.md index c6b0c685..595d6b17 100644 --- a/plugins/single-instance/README.md +++ b/plugins/single-instance/README.md @@ -38,7 +38,7 @@ struct Payload { fn main() { tauri::Builder::default() - .plugin(auri_plugin_single_instance::init(|app, argv, cwd| { + .plugin(tauri_plugin_single_instance::init(|app, argv, cwd| { println!("{}, {argv:?}, {cwd}", app.package_info().name); app.emit_all("single-instance", Payload { args: argv, cwd }).unwrap(); From 1d52416f7042b1b6b157dc66f6daa96a96d342e2 Mon Sep 17 00:00:00 2001 From: Fabian-Lars Date: Sun, 5 Mar 2023 12:25:15 +0100 Subject: [PATCH 10/71] feat(sql): Improve type decoding. Adds support for time and dates (#266) * feat(sql): Improve type decoding. Adds support for time and dates * remove default feat * typo --- Cargo.lock | 4 +- plugins/sql/Cargo.toml | 5 +- plugins/sql/src/decode/mod.rs | 15 +++++ plugins/sql/src/decode/mysql.rs | 90 ++++++++++++++++++++++++++++++ plugins/sql/src/decode/postgres.rs | 82 +++++++++++++++++++++++++++ plugins/sql/src/decode/sqlite.rs | 74 ++++++++++++++++++++++++ plugins/sql/src/lib.rs | 11 +--- plugins/sql/src/plugin.rs | 57 +------------------ 8 files changed, 271 insertions(+), 67 deletions(-) create mode 100644 plugins/sql/src/decode/mod.rs create mode 100644 plugins/sql/src/decode/mysql.rs create mode 100644 plugins/sql/src/decode/postgres.rs create mode 100644 plugins/sql/src/decode/sqlite.rs diff --git a/Cargo.lock b/Cargo.lock index 35300066..d2a0e851 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3901,6 +3901,7 @@ dependencies = [ "sqlx-rt", "stringprep", "thiserror", + "time 0.3.17", "tokio-stream", "url", "webpki-roots", @@ -4380,13 +4381,14 @@ dependencies = [ name = "tauri-plugin-sql" version = "0.1.0" dependencies = [ - "futures", + "futures-core", "log", "serde", "serde_json", "sqlx", "tauri", "thiserror", + "time 0.3.17", "tokio", ] diff --git a/plugins/sql/Cargo.toml b/plugins/sql/Cargo.toml index c72e237c..502cd12c 100644 --- a/plugins/sql/Cargo.toml +++ b/plugins/sql/Cargo.toml @@ -15,9 +15,10 @@ serde_json.workspace = true tauri.workspace = true log.workspace = true thiserror.workspace = true -sqlx = { version = "0.6", features = ["runtime-tokio-rustls", "json"] } +futures-core = "0.3" +sqlx = { version = "0.6", features = ["runtime-tokio-rustls", "json", "time"] } +time = "0.3" tokio = { version = "1", features = ["sync"] } -futures = "0.3" [features] sqlite = ["sqlx/sqlite"] diff --git a/plugins/sql/src/decode/mod.rs b/plugins/sql/src/decode/mod.rs new file mode 100644 index 00000000..415c99b8 --- /dev/null +++ b/plugins/sql/src/decode/mod.rs @@ -0,0 +1,15 @@ +#[cfg(feature = "mysql")] +mod mysql; +#[cfg(feature = "postgres")] +mod postgres; +#[cfg(feature = "sqlite")] +mod sqlite; + +#[cfg(feature = "mysql")] +pub(crate) use mysql::to_json; + +#[cfg(feature = "postgres")] +pub(crate) use postgres::to_json; + +#[cfg(feature = "sqlite")] +pub(crate) use sqlite::to_json; diff --git a/plugins/sql/src/decode/mysql.rs b/plugins/sql/src/decode/mysql.rs new file mode 100644 index 00000000..e68bd1ac --- /dev/null +++ b/plugins/sql/src/decode/mysql.rs @@ -0,0 +1,90 @@ +use serde_json::Value as JsonValue; +use sqlx::{mysql::MySqlValueRef, TypeInfo, Value, ValueRef}; +use time::{Date, OffsetDateTime, PrimitiveDateTime, Time}; + +use crate::Error; + +pub(crate) fn to_json(v: MySqlValueRef) -> Result { + if v.is_null() { + return Ok(JsonValue::Null); + } + + let res = match v.type_info().name() { + "CHAR" | "VARCHAR" | "TINYTEXT" | "TEXT" | "MEDIUMTEXT" | "LONGTEXT" | "ENUM" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode() { + JsonValue::String(v) + } else { + JsonValue::Null + } + } + "FLOAT" | "DOUBLE" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode::() { + JsonValue::from(v) + } else { + JsonValue::Null + } + } + "TINYINT" | "SMALLINT" | "INT" | "MEDIUMINT" | "BIGINT" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode::() { + JsonValue::Number(v.into()) + } else { + JsonValue::Null + } + } + "TINYINT UNSIGNED" | "SMALLINT UNSIGNED" | "INT UNSIGNED" | "MEDIUMINT UNSIGNED" + | "BIGINT UNSIGNED" | "YEAR" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode::() { + JsonValue::Number(v.into()) + } else { + JsonValue::Null + } + } + "BOOLEAN" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode() { + JsonValue::Bool(v) + } else { + JsonValue::Null + } + } + "DATE" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode::() { + JsonValue::String(v.to_string()) + } else { + JsonValue::Null + } + } + "TIME" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode::