diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..83ba0c42 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,5 @@ +# Order is important; the last matching pattern takes the most precedence. +* @tauri-apps/plugin-maintainers + +# Currently CI/CD for plugins are in heavy flux, and the plugin team manages it themselves. +# .github @tauri-apps/wg-devops diff --git a/.github/sync-to-mirrors.sh b/.github/sync-to-mirrors.sh index 757e1d10..1a65bf2d 100755 --- a/.github/sync-to-mirrors.sh +++ b/.github/sync-to-mirrors.sh @@ -93,12 +93,12 @@ while read -r PLUGIN_NAME; do echo "Failed to find a branch to branch from, just creating an empty one." FORCE_COMMIT=--allow-empty fi - git add -Af + git add -A echo "::endgroup::" if [[ -n "$FORCE_COMMIT" || -n "$(git status --porcelain)" ]]; then echo "Committing to $PLUGIN_NAME" - if git commit --quiet $FORCE_COMMIT --author="${COMMIT_ORIGINAL_AUTHOR}" -m "${COMMIT_MESSAGE}" && + if git commit $FORCE_COMMIT --author="${COMMIT_ORIGINAL_AUTHOR}" -m "${COMMIT_MESSAGE}" && { [[ -z "$CI" ]] || git push origin "$BRANCH"; } # Only do the actual push from the GitHub Action then # echo "$BUILD_BASE/changes.diff" diff --git a/.github/workflows/lint-rust.yml b/.github/workflows/lint-rust.yml index 4ad8c167..da353a56 100644 --- a/.github/workflows/lint-rust.yml +++ b/.github/workflows/lint-rust.yml @@ -6,14 +6,14 @@ on: - dev paths: - ".github/workflows/lint-rust.yml" - - "plugins/src/**" + - "plugins/*/src/**" - "**/Cargo.toml" pull_request: branches: - dev paths: - ".github/workflows/lint-rust.yml" - - "plugins/src/**" + - "plugins/*/src/**" - "**/Cargo.toml" concurrency: @@ -28,42 +28,30 @@ jobs: steps: - uses: actions/checkout@v3 - - name: install webkit2gtk + + - name: install webkit2gtk and libudev for [authenticator] run: | sudo apt-get update - sudo apt-get install -y webkit2gtk-4.0 - - name: install libudev for [authenticator] - run: | - sudo apt-get install -y libudev-dev + sudo apt-get install -y webkit2gtk-4.0 libudev-dev + - name: Install clippy with stable toolchain - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@stable with: - profile: minimal - toolchain: stable - override: true components: clippy - - uses: Swatinem/rust-cache@v1 - - uses: actions-rs/clippy-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - args: --workspace --exclude 'tauri-plugin-sql' --all-targets --all-features -- -D warnings - name: clippy - - uses: actions-rs/clippy-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - args: --workspace --package 'tauri-plugin-sql' --all-targets --features sqlite -- -D warnings - name: clippy sql:sqlite - - uses: actions-rs/clippy-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - args: --workspace --package 'tauri-plugin-sql' --all-targets --features mysql -- -D warnings - name: clippy sql:mysql - - uses: actions-rs/clippy-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - args: --workspace --package 'tauri-plugin-sql' --all-targets --features postgres -- -D warnings - name: clippy sql:postgres + - uses: Swatinem/rust-cache@v2 + + - name: clippy + run: cargo clippy --workspace --exclude 'tauri-plugin-sql' --all-targets --all-features -- -D warnings + + - name: clippy sql:sqlite + run: cargo clippy --package 'tauri-plugin-sql' --all-targets --features sqlite -- -D warnings + + - name: clippy sql:mysql + run: cargo clippy --package 'tauri-plugin-sql' --all-targets --features mysql -- -D warnings + + - name: clippy sql:postgres + run: cargo clippy --package 'tauri-plugin-sql' --all-targets --features postgres -- -D warnings fmt: runs-on: ubuntu-latest @@ -72,14 +60,11 @@ jobs: steps: - uses: actions/checkout@v3 + - name: Install rustfmt with nightly toolchain - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@nightly with: - profile: minimal - toolchain: nightly - override: true components: rustfmt - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check + + - name: Check formatting + run: cargo fmt --all -- --check diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index aabf8d93..51521aab 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -33,5 +33,5 @@ jobs: - name: Sync run: .github/sync-to-mirrors.sh env: - BUILD_BASE: ./plugins + BUILD_BASE: ${{ github.workspace }}/plugins API_TOKEN_GITHUB: ${{ secrets.ORG_TAURI_BOT_PAT }} diff --git a/.prettierignore b/.prettierignore index 2c6d35b6..13134b1f 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,5 @@ target node_modules -dist \ No newline at end of file +dist +pnpm-lock.yaml +Cargo.lock \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 0a70412a..6511665a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -157,12 +157,12 @@ dependencies = [ [[package]] name = "auto-launch" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642d13324da4df30a472026356a7fd24845d4a8038e5c47ed99c62074b526fa5" +checksum = "5904a4d734f0235edf29aab320a14899f3e090446e594ff96508a6215f76f89c" dependencies = [ - "anyhow", "dirs", + "thiserror", "winreg", ] @@ -2540,9 +2540,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "opaque-debug" @@ -3527,17 +3527,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "sha-1" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" -dependencies = [ - "cfg-if 1.0.0", - "cpufeatures 0.2.5", - "digest 0.10.6", -] - [[package]] name = "sha1" version = "0.10.5" @@ -4467,15 +4456,14 @@ dependencies = [ [[package]] name = "tiny_http" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d6ef4e10d23c1efb862eecad25c5054429a71958b4eeef85eb5e7170b477ca" +checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82" dependencies = [ "ascii", "chunked_transfer", + "httpdate", "log", - "time 0.3.17", - "url", ] [[package]] @@ -4495,9 +4483,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.23.0" +version = "1.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" +checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae" dependencies = [ "autocfg", "bytes 1.3.0", @@ -4544,9 +4532,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.17.2" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" +checksum = "54319c93411147bced34cb5609a80e0a8e44c5999c93903a81cd866630ec0bfd" dependencies = [ "futures-util", "log", @@ -4664,9 +4652,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tungstenite" -version = "0.17.3" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788" dependencies = [ "base64 0.13.1", "byteorder", @@ -4676,7 +4664,7 @@ dependencies = [ "log", "native-tls", "rand 0.8.5", - "sha-1", + "sha1", "thiserror", "url", "utf-8", diff --git a/Cargo.toml b/Cargo.toml index 41ae9082..48a6a386 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,5 @@ thiserror = "1" [workspace.package] edition = "2021" authors = [ "Tauri Programme within The Commons Conservancy" ] -license = "Apache-2.0 OR MIT" \ No newline at end of file +license = "Apache-2.0 OR MIT" +rust-version = "1.59" \ No newline at end of file diff --git a/plugins/authenticator/Cargo.toml b/plugins/authenticator/Cargo.toml index 73978f5f..0df4e4b1 100644 --- a/plugins/authenticator/Cargo.toml +++ b/plugins/authenticator/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "tauri-plugin-authenticator" version = "0.1.0" -edition.workspace = true +description = "Use hardware security-keys in your Tauri App." authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -14,7 +16,7 @@ tauri.workspace = true log.workspace = true thiserror.workspace = true authenticator = "0.3.1" -once_cell = "1.9" +once_cell = "1" sha2 = "0.10" base64 = { version = "^0.13" } u2f = "0.2" diff --git a/plugins/authenticator/README.md b/plugins/authenticator/README.md index 9b0fdcbe..884d81b9 100644 --- a/plugins/authenticator/README.md +++ b/plugins/authenticator/README.md @@ -1,17 +1,100 @@ ![plugin-authenticator](banner.png) - +Use hardware security-keys in your Tauri App. ## Install +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` + +```toml +[dependencies] +tauri-plugin-authenticator = "0.1" +# or through git +tauri-plugin-authenticator = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } ``` +You can install the JavaScript Guest bindings using your preferred JavaScript package manager: + +> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use. + +```sh +pnpm add https://github.com/tauri-apps/tauri-plugin-authenticator +# or +npm add https://github.com/tauri-apps/tauri-plugin-authenticator +# or +yarn add https://github.com/tauri-apps/tauri-plugin-authenticator ``` ## Usage +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_authenticator::init()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards all the plugin's APIs are available through the JavaScript guest bindings: + +```javascript +import { Authenticator } from "tauri-plugin-authenticator-api"; + +const auth = new Authenticator(); +auth.init(); // initialize transports + +// generate a 32-bytes long random challenge +const arr = new Uint32Array(32); +window.crypto.getRandomValues(arr); +const b64 = btoa(String.fromCharCode.apply(null, arr)); +// web-safe base64 +const challenge = b64.replace(/\+/g, "-").replace(/\//g, "_"); + +const domain = "https://tauri.app"; + +// attempt to register with the security key +const json = await auth.register(challenge, domain); +const registerResult = JSON.parse(json); + +// verify te registration was successfull +const r2 = await auth.verifyRegistration( + challenge, + app, + registerResult.registerData, + registerResult.clientData +); +const j2 = JSON.parse(r2); + +// sign some data +const json = await auth.sign(challenge, app, keyHandle); +const signData = JSON.parse(json); + +// verify the signature again +const counter = await auth.verifySignature( + challenge, + app, + signData.signData, + clientData, + keyHandle, + pubkey +); + +if (counter && counter > 0) { + console.log("SUCCESS!"); +} ``` ## Contributing @@ -20,6 +103,6 @@ PRs accepted. Please make sure to read the Contributing Guide before making a pu ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/plugins/authenticator/guest-js/index.ts b/plugins/authenticator/guest-js/index.ts index 6f9da943..8b4a533c 100644 --- a/plugins/authenticator/guest-js/index.ts +++ b/plugins/authenticator/guest-js/index.ts @@ -2,7 +2,7 @@ import { invoke } from "@tauri-apps/api/tauri"; export class Authenticator { async init(): Promise { - return await invoke("plugin:authenticator|init"); + return await invoke("plugin:authenticator|init_auth"); } async register(challenge: string, application: string): Promise { diff --git a/plugins/authenticator/package.json b/plugins/authenticator/package.json index 6cf8288e..e0c7725e 100644 --- a/plugins/authenticator/package.json +++ b/plugins/authenticator/package.json @@ -1,6 +1,7 @@ { "name": "tauri-plugin-authenticator-api", "version": "0.0.0", + "description": "Use hardware security-keys in your Tauri App.", "license": "MIT or APACHE-2.0", "authors": [ "Tauri Programme within The Commons Conservancy" diff --git a/plugins/authenticator/src/auth.rs b/plugins/authenticator/src/auth.rs index 363b0d11..3241ef72 100644 --- a/plugins/authenticator/src/auth.rs +++ b/plugins/authenticator/src/auth.rs @@ -75,8 +75,8 @@ pub fn register(application: String, timeout: u64, challenge: String) -> crate:: let (key_handle, public_key) = _u2f_get_key_handle_and_public_key_from_register_response(®ister_data).unwrap(); - let key_handle_base64 = encode_config(&key_handle, URL_SAFE_NO_PAD); - let public_key_base64 = encode_config(&public_key, URL_SAFE_NO_PAD); + let key_handle_base64 = encode_config(key_handle, URL_SAFE_NO_PAD); + let public_key_base64 = encode_config(public_key, URL_SAFE_NO_PAD); let register_data_base64 = encode_config(®ister_data, URL_SAFE_NO_PAD); println!("Key Handle: {}", &key_handle_base64); println!("Public Key: {}", &public_key_base64); @@ -108,7 +108,7 @@ pub fn sign( challenge: String, key_handle: String, ) -> crate::Result { - let credential = match decode_config(&key_handle, URL_SAFE_NO_PAD) { + let credential = match decode_config(key_handle, URL_SAFE_NO_PAD) { Ok(v) => v, Err(e) => { return Err(e.into()); @@ -152,7 +152,7 @@ pub fn sign( let (_, handle_used, sign_data, device_info) = sign_result.unwrap(); - let sig = encode_config(&sign_data, URL_SAFE_NO_PAD); + let sig = encode_config(sign_data, URL_SAFE_NO_PAD); println!("Sign result: {}", sig); println!( diff --git a/plugins/authenticator/src/lib.rs b/plugins/authenticator/src/lib.rs index bc0d4c35..ef889e21 100644 --- a/plugins/authenticator/src/lib.rs +++ b/plugins/authenticator/src/lib.rs @@ -6,13 +6,16 @@ mod auth; mod error; mod u2f; -use tauri::{plugin::Plugin, Invoke, Runtime}; +use tauri::{ + plugin::{Builder as PluginBuilder, TauriPlugin}, + Runtime, +}; pub use error::Error; type Result = std::result::Result; #[tauri::command] -fn init() { +fn init_auth() { auth::init_usb(); } @@ -60,30 +63,14 @@ fn verify_signature( ) } -pub struct TauriAuthenticator { - invoke_handler: Box) + Send + Sync>, -} - -impl Default for TauriAuthenticator { - fn default() -> Self { - Self { - invoke_handler: Box::new(tauri::generate_handler![ - init, - register, - verify_registration, - sign, - verify_signature - ]), - } - } -} - -impl Plugin for TauriAuthenticator { - fn name(&self) -> &'static str { - "authenticator" - } - - fn extend_api(&mut self, invoke: Invoke) { - (self.invoke_handler)(invoke) - } +pub fn init() -> TauriPlugin { + PluginBuilder::new("authenticator") + .invoke_handler(tauri::generate_handler![ + init_auth, + register, + verify_registration, + sign, + verify_signature + ]) + .build() } diff --git a/plugins/authenticator/src/u2f.rs b/plugins/authenticator/src/u2f.rs index b1f2e280..80eb9497 100644 --- a/plugins/authenticator/src/u2f.rs +++ b/plugins/authenticator/src/u2f.rs @@ -15,7 +15,7 @@ static VERSION: &str = "U2F_V2"; pub fn make_challenge(app_id: &str, challenge_bytes: Vec) -> Challenge { let utc: DateTime = Utc::now(); Challenge { - challenge: encode_config(&challenge_bytes, URL_SAFE_NO_PAD), + challenge: encode_config(challenge_bytes, URL_SAFE_NO_PAD), timestamp: format!("{:?}", utc), app_id: app_id.to_string(), } @@ -35,10 +35,10 @@ pub fn verify_registration( register_data: String, client_data: String, ) -> crate::Result { - let challenge_bytes = decode_config(&challenge, URL_SAFE_NO_PAD)?; + let challenge_bytes = decode_config(challenge, URL_SAFE_NO_PAD)?; let challenge = make_challenge(&app_id, challenge_bytes); let client_data_bytes: Vec = client_data.as_bytes().into(); - let client_data_base64 = encode_config(&client_data_bytes, URL_SAFE_NO_PAD); + let client_data_base64 = encode_config(client_data_bytes, URL_SAFE_NO_PAD); let client = U2f::new(app_id); match client.register_response( challenge, @@ -74,12 +74,12 @@ pub fn verify_signature( key_handle: String, pub_key: String, ) -> crate::Result { - let challenge_bytes = decode_config(&challenge, URL_SAFE_NO_PAD)?; + let challenge_bytes = decode_config(challenge, URL_SAFE_NO_PAD)?; let chal = make_challenge(&app_id, challenge_bytes); let client_data_bytes: Vec = client_data.as_bytes().into(); - let client_data_base64 = encode_config(&client_data_bytes, URL_SAFE_NO_PAD); + let client_data_base64 = encode_config(client_data_bytes, URL_SAFE_NO_PAD); let key_handle_bytes = decode_config(&key_handle, URL_SAFE_NO_PAD)?; - let pubkey_bytes = decode_config(&pub_key, URL_SAFE_NO_PAD)?; + let pubkey_bytes = decode_config(pub_key, URL_SAFE_NO_PAD)?; let client = U2f::new(app_id); let mut _counter: u32 = 0; match client.sign_response( diff --git a/plugins/autostart/Cargo.toml b/plugins/autostart/Cargo.toml index 3819ec10..dc42168d 100644 --- a/plugins/autostart/Cargo.toml +++ b/plugins/autostart/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "tauri-plugin-autostart" version = "0.1.0" -edition.workspace = true +description = "Automatically launch your application at startup." authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -13,4 +15,4 @@ serde_json.workspace = true tauri.workspace = true log.workspace = true thiserror.workspace = true -auto-launch = "0.3" \ No newline at end of file +auto-launch = "0.4" \ No newline at end of file diff --git a/plugins/autostart/README.md b/plugins/autostart/README.md index 6fb45653..87e7d132 100644 --- a/plugins/autostart/README.md +++ b/plugins/autostart/README.md @@ -1,17 +1,61 @@ ![plugin-autostart](banner.png) - +Automatically launch your application at startup. Supports Windows, Mac (via AppleScript or Launch Agent), and Linux. ## Install +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` + +```toml +[dependencies] +tauri-plugin-autostart = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } ``` +You can install the JavaScript Guest bindings using your preferred JavaScript package manager: + +> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use. + +```sh +pnpm add https://github.com/tauri-apps/tauri-plugin-autostart +# or +npm add https://github.com/tauri-apps/tauri-plugin-autostart +# or +yarn add https://github.com/tauri-apps/tauri-plugin-autostart ``` ## Usage +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_autostart::init(MacosLauncher::LaunchAgent, Some(vec!["--flag1", "--flag2"]) /* arbitrary number of args to pass to your app */)) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards all the plugin's APIs are available through the JavaScript guest bindings: + +```javascript +import { enable, isEnabled, disable } from "tauri-plugin-autostart-api"; + +await enable(); + +console.log(`registered for autostart? ${await isEnabled()}`); + +disable(); ``` ## Contributing @@ -20,6 +64,6 @@ PRs accepted. Please make sure to read the Contributing Guide before making a pu ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/plugins/fs-extra/Cargo.toml b/plugins/fs-extra/Cargo.toml index 63d5a13e..79b0e7ce 100644 --- a/plugins/fs-extra/Cargo.toml +++ b/plugins/fs-extra/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "tauri-plugin-fs-extra" version = "0.1.0" -edition.workspace = true +description = "Additional file system methods not included in the core API." authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/plugins/fs-extra/README.md b/plugins/fs-extra/README.md index 6047161d..6ea6ea1c 100644 --- a/plugins/fs-extra/README.md +++ b/plugins/fs-extra/README.md @@ -1,17 +1,57 @@ -![plugin-fs-extra](banner.png) +![tauri-plugin-fs-extra](banner.png) - +Additional file system methods not included in the core API. ## Install +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` + +```toml +[dependencies] +tauri-plugin-fs-extra = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } ``` +You can install the JavaScript Guest bindings using your preferred JavaScript package manager: + +> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use. + +```sh +pnpm add https://github.com/tauri-apps/tauri-plugin-fs-extra +# or +npm add https://github.com/tauri-apps/tauri-plugin-fs-extra +# or +yarn add https://github.com/tauri-apps/tauri-plugin-fs-extra ``` ## Usage +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_fs_extra::init()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards all the plugin's APIs are available through the JavaScript guest bindings: + +```javascript +import { metadata } from "tauri-plugin-fs-extra-api"; + +await metadata("/path/to/file"); ``` ## Contributing @@ -20,6 +60,6 @@ PRs accepted. Please make sure to read the Contributing Guide before making a pu ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/plugins/fs-extra/package.json b/plugins/fs-extra/package.json index 8929b996..52eb1eef 100644 --- a/plugins/fs-extra/package.json +++ b/plugins/fs-extra/package.json @@ -1,6 +1,7 @@ { "name": "tauri-plugin-fs-extra-api", "version": "0.0.0", + "description": "Additional file system methods not included in the core API.", "license": "MIT or APACHE-2.0", "authors": [ "Tauri Programme within The Commons Conservancy" diff --git a/plugins/fs-extra/src/lib.rs b/plugins/fs-extra/src/lib.rs index 286e8508..621a28bd 100644 --- a/plugins/fs-extra/src/lib.rs +++ b/plugins/fs-extra/src/lib.rs @@ -3,7 +3,11 @@ // SPDX-License-Identifier: MIT use serde::{ser::Serializer, Serialize}; -use tauri::{command, plugin::Plugin, Invoke, Runtime}; +use tauri::{ + command, + plugin::{Builder as PluginBuilder, TauriPlugin}, + Runtime, +}; use std::{ path::PathBuf, @@ -121,25 +125,8 @@ async fn exists(path: PathBuf) -> bool { path.exists() } -/// Tauri plugin. -pub struct FsExtra { - invoke_handler: Box) + Send + Sync>, -} - -impl Default for FsExtra { - fn default() -> Self { - Self { - invoke_handler: Box::new(tauri::generate_handler![exists, metadata]), - } - } -} - -impl Plugin for FsExtra { - fn name(&self) -> &'static str { - "fs-extra" - } - - fn extend_api(&mut self, message: Invoke) { - (self.invoke_handler)(message) - } +pub fn init() -> TauriPlugin { + PluginBuilder::new("fs-extra") + .invoke_handler(tauri::generate_handler![exists, metadata]) + .build() } diff --git a/plugins/fs-watch/Cargo.toml b/plugins/fs-watch/Cargo.toml index 0eb232a4..89501ac8 100644 --- a/plugins/fs-watch/Cargo.toml +++ b/plugins/fs-watch/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "tauri-plugin-fs-watch" version = "0.1.0" -edition.workspace = true +description = "Watch files and directories for changes." authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/plugins/fs-watch/README.md b/plugins/fs-watch/README.md index 1c11acf0..26ee5bfc 100644 --- a/plugins/fs-watch/README.md +++ b/plugins/fs-watch/README.md @@ -1,17 +1,72 @@ ![plugin-fs-watch](banner.png) - +Watch files and directories for changes using [notify](https://github.com/notify-rs/notify). ## Install +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` + +```toml +[dependencies] +tauri-plugin-fs-watch = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } ``` +You can install the JavaScript Guest bindings using your preferred JavaScript package manager: + +> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use. + +```sh +pnpm add https://github.com/tauri-apps/tauri-plugin-fs-watch +# or +npm add https://github.com/tauri-apps/tauri-plugin-fs-watch +# or +yarn add https://github.com/tauri-apps/tauri-plugin-fs-watch ``` ## Usage +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_fs_watch::init()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards all the plugin's APIs are available through the JavaScript guest bindings: + +```javascript +import { watch, watchImmediate } from "tauri-plugin-fs-watch-api"; + +// can also watch an array of paths +const stopWatching = await watch( + "/path/to/something", + { recursive: true }, + (event) => { + const { type, payload } = event; + } +); + +const stopRawWatcher = await watchImmediate( + ["/path/a", "/path/b"], + {}, + (event) => { + const { path, operation, cookie } = event; + } +); ``` ## Contributing @@ -20,6 +75,6 @@ PRs accepted. Please make sure to read the Contributing Guide before making a pu ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/plugins/fs-watch/package.json b/plugins/fs-watch/package.json index c903f942..adf44a2c 100644 --- a/plugins/fs-watch/package.json +++ b/plugins/fs-watch/package.json @@ -1,6 +1,7 @@ { "name": "tauri-plugin-fs-watch-api", "version": "0.0.0", + "description": "Watch files and directories for changes.", "license": "MIT or APACHE-2.0", "authors": [ "Tauri Programme within The Commons Conservancy" diff --git a/plugins/fs-watch/src/lib.rs b/plugins/fs-watch/src/lib.rs index facf3298..790507b7 100644 --- a/plugins/fs-watch/src/lib.rs +++ b/plugins/fs-watch/src/lib.rs @@ -3,8 +3,11 @@ use notify::{ Watcher as _, }; use serde::{ser::Serializer, Deserialize, Serialize}; -use serde_json::Value as JsonValue; -use tauri::{command, plugin::Plugin, AppHandle, Invoke, Manager, Runtime, State, Window}; +use tauri::{ + command, + plugin::{Builder as PluginBuilder, TauriPlugin}, + Manager, Runtime, State, Window, +}; use std::{ collections::HashMap, @@ -160,30 +163,12 @@ async fn unwatch(watchers: State<'_, WatcherCollection>, id: Id) -> Result<()> { Ok(()) } -/// Tauri plugin. -pub struct Watcher { - invoke_handler: Box) + Send + Sync>, -} - -impl Default for Watcher { - fn default() -> Self { - Self { - invoke_handler: Box::new(tauri::generate_handler![watch, unwatch]), - } - } -} - -impl Plugin for Watcher { - fn name(&self) -> &'static str { - "fs-watch" - } - - fn initialize(&mut self, app: &AppHandle, _config: JsonValue) -> tauri::plugin::Result<()> { - app.manage(WatcherCollection::default()); - Ok(()) - } - - fn extend_api(&mut self, message: Invoke) { - (self.invoke_handler)(message) - } +pub fn init() -> TauriPlugin { + PluginBuilder::new("fs-watch") + .invoke_handler(tauri::generate_handler![watch, unwatch]) + .setup(|app| { + app.manage(WatcherCollection::default()); + Ok(()) + }) + .build() } diff --git a/plugins/localhost/Cargo.toml b/plugins/localhost/Cargo.toml index 5c20919d..12fad9a0 100644 --- a/plugins/localhost/Cargo.toml +++ b/plugins/localhost/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "tauri-plugin-localhost" version = "0.1.0" -edition.workspace = true +description = "Expose your apps assets through a localhost server instead of the default custom protocol." authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -13,5 +15,5 @@ serde_json.workspace = true tauri.workspace = true log.workspace = true thiserror.workspace = true -tiny_http = "0.11" +tiny_http = "0.12" http = "0.2" \ No newline at end of file diff --git a/plugins/localhost/README.md b/plugins/localhost/README.md index 66c0c587..23b07577 100644 --- a/plugins/localhost/README.md +++ b/plugins/localhost/README.md @@ -1,17 +1,57 @@ ![plugin-localhost](banner.png) - +Expose your apps assets through a localhost server instead of the default custom protocol. + +> Note: This plugins brings considerable security risks and you should only use it if you know what your are doing. If in doubt, use the default custom protocol implementation. ## Install -``` +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` +```toml +[dependencies] +tauri-plugin-localhost = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } +portpicker = "0.1" # used in the example to pick a random free port ``` ## Usage -``` +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +use tauri::{utils::config::AppUrl, window::WindowBuilder, WindowUrl}; + +fn main() { + let port = portpicker::pick_unused_port().expect("failed to find unused port"); + + let mut context = tauri::generate_context!(); + let url = format!("http://localhost:{}", port).parse().unwrap(); + let window_url = WindowUrl::External(url); + // rewrite the config so the IPC is enabled on this URL + context.config_mut().build.dist_dir = AppUrl::Url(window_url.clone()); + context.config_mut().build.dev_path = AppUrl::Url(window_url.clone()); + tauri::Builder::default() + .plugin(tauri_plugin_localhost::Builder::new(port).build()) + .setup(move |app| { + WindowBuilder::new(app, "main".to_string(), window_url) + .title("Localhost Example") + .build()?; + Ok(()) + }) + .run(context) + .expect("error while running tauri application"); +} ``` ## Contributing @@ -20,6 +60,6 @@ PRs accepted. Please make sure to read the Contributing Guide before making a pu ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/plugins/log/Cargo.toml b/plugins/log/Cargo.toml index 8d627dfe..e590222b 100644 --- a/plugins/log/Cargo.toml +++ b/plugins/log/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "tauri-plugin-log" version = "0.1.0" -edition.workspace = true +description = "Configurable logging for your Tauri app." authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/plugins/log/README.md b/plugins/log/README.md index 79504c98..f49c2c7b 100644 --- a/plugins/log/README.md +++ b/plugins/log/README.md @@ -1,25 +1,88 @@ ![plugin-log](banner.png) - +Configurable logging for your Tauri app. ## Install +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` + +```toml +[dependencies] +tauri-plugin-log = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } ``` +You can install the JavaScript Guest bindings using your preferred JavaScript package manager: + +> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use. + +```sh +pnpm add https://github.com/tauri-apps/tauri-plugin-log +# or +npm add https://github.com/tauri-apps/tauri-plugin-log +# or +yarn add https://github.com/tauri-apps/tauri-plugin-log ``` ## Usage +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +use tauri_plugin_log::{LogTarget}; + +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_log::Builder::default().targets([ + LogTarget::LogDir, + LogTarget::Stdout, + LogTarget::Webview, + ]).build()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards all the plugin's APIs are available through the JavaScript guest bindings: + +```javascript +import { trace, info, error, attachConsole } from "tauri-plugin-log-api"; + +// with LogTarget::Webview enabled this function will print logs to the browser console +const detach = await attachConsole(); + +trace("Trace"); +info("Info"); +error("Error"); + +// detach the browser console from the log stream +detach(); ``` +To log from rust code, add the log crate to your `Cargo.toml`: + +```toml +[dependencies] +log = "^0.4" +``` + +Now, you can use the macros provided by the log crate to log messages from your backend. See the [docs](https://docs.rs/log/latest) for more details. + ## Contributing PRs accepted. Please make sure to read the Contributing Guide before making a pull request. ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/plugins/log/package.json b/plugins/log/package.json index 9574a8fc..ff13c42d 100644 --- a/plugins/log/package.json +++ b/plugins/log/package.json @@ -1,6 +1,7 @@ { "name": "tauri-plugin-log-api", "version": "0.0.0", + "description": "Configurable logging for your Tauri app.", "license": "MIT or APACHE-2.0", "authors": [ "Tauri Programme within The Commons Conservancy" diff --git a/plugins/log/src/lib.rs b/plugins/log/src/lib.rs index 9288fe01..cf25db2d 100644 --- a/plugins/log/src/lib.rs +++ b/plugins/log/src/lib.rs @@ -142,14 +142,14 @@ fn log( logger().log(&builder.args(format_args!("{message}")).build()); } -pub struct LoggerBuilder { +pub struct Builder { dispatch: fern::Dispatch, rotation_strategy: RotationStrategy, max_file_size: u128, targets: Vec, } -impl Default for LoggerBuilder { +impl Default for Builder { fn default() -> Self { let format = time::format_description::parse("[[[year]-[month]-[day]][[[hour]:[minute]:[second]]") @@ -172,7 +172,7 @@ impl Default for LoggerBuilder { } } -impl LoggerBuilder { +impl Builder { pub fn new() -> Self { Default::default() } diff --git a/plugins/mirrors.txt b/plugins/mirrors.txt index ca4cb0cf..4ad29c51 100644 --- a/plugins/mirrors.txt +++ b/plugins/mirrors.txt @@ -1 +1,14 @@ +authenticator +autostart +fs-extra +fs-watch +localhost +log +persisted-scope +positioner +sql +store +stronghold +upload websocket +window-state diff --git a/plugins/persisted-scope/Cargo.toml b/plugins/persisted-scope/Cargo.toml index 58427d32..7bc30228 100644 --- a/plugins/persisted-scope/Cargo.toml +++ b/plugins/persisted-scope/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "tauri-plugin-persisted-scope" version = "0.1.0" -edition.workspace = true +description = "Save filesystem and asset scopes and restore them when the app is reopened." authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/plugins/persisted-scope/README.md b/plugins/persisted-scope/README.md index 3891b209..43dd5909 100644 --- a/plugins/persisted-scope/README.md +++ b/plugins/persisted-scope/README.md @@ -1,25 +1,47 @@ ![plugin-persisted-scope](banner.png) - +Save filesystem and asset scopes and restore them when the app is reopened. ## Install -``` +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` +```toml +[dependencies] +tauri-plugin-persisted-scope = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } ``` ## Usage -``` +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` +```rust +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_persisted_scope::init()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards the plugin will automatically save and restore filesystem and asset scopes. + ## Contributing PRs accepted. Please make sure to read the Contributing Guide before making a pull request. ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/plugins/persisted-scope/src/lib.rs b/plugins/persisted-scope/src/lib.rs index 6827e4cd..ef0625ba 100644 --- a/plugins/persisted-scope/src/lib.rs +++ b/plugins/persisted-scope/src/lib.rs @@ -54,15 +54,15 @@ pub fn init() -> TauriPlugin { .map_err(Error::from) .and_then(|scope| bincode::deserialize(&scope).map_err(Into::into)) .unwrap_or_default(); - for allowed in scope.allowed_paths { + for allowed in &scope.allowed_paths { // allows the path as is - let _ = fs_scope.allow_file(&allowed); + let _ = fs_scope.allow_file(allowed); #[cfg(feature = "protocol-asset")] let _ = asset_protocol_scope.allow_file(allowed); } - for forbidden in scope.forbidden_patterns { + for forbidden in &scope.forbidden_patterns { // forbid the path as is - let _ = fs_scope.forbid_file(&forbidden); + let _ = fs_scope.forbid_file(forbidden); #[cfg(feature = "protocol-asset")] let _ = asset_protocol_scope.forbid_file(forbidden); } diff --git a/plugins/positioner/Cargo.toml b/plugins/positioner/Cargo.toml index 59a9cfef..08155a5d 100644 --- a/plugins/positioner/Cargo.toml +++ b/plugins/positioner/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "tauri-plugin-positioner" version = "0.2.7" -edition.workspace = true +description = "Position your windows at well-known locations." authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/plugins/positioner/README.md b/plugins/positioner/README.md index 5eb5195e..54332ddc 100644 --- a/plugins/positioner/README.md +++ b/plugins/positioner/README.md @@ -1,17 +1,84 @@ ![plugin-positioner](banner.png) - +Position your windows at well-known locations. + +This plugin is a port of [electron-positioner](https://github.com/jenslind/electron-positioner) for Tauri. ## Install +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` + +```toml +[dependencies] +tauri-plugin-positioner = "1.0" +# or through git +tauri-plugin-positioner = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } +``` + +You can install the JavaScript Guest bindings using your preferred JavaScript package manager: + +> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use. + +```sh +pnpm add tauri-plugin-positioner +# or +npm add tauri-plugin-positioner +# or +yarn add tauri-plugin-positioner ``` +Or through git: + +```sh +pnpm add https://github.com/tauri-apps/tauri-plugin-positioner +# or +npm add https://github.com/tauri-apps/tauri-plugin-positioner +# or +yarn add https://github.com/tauri-apps/tauri-plugin-positioner ``` ## Usage +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_positioner::init()) + // This is required to get tray-relative positions to work + .on_system_tray_event(|app, event| { + tauri_plugin_positioner::on_tray_event(app, &event); + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards all the plugin's APIs are available through the JavaScript guest bindings: + +```javascript +import { move_window, Position } from "tauri-plugin-positioner-api"; + +move_window(Position.TopRight); +``` + +If you only intend on moving the window from rust code, you can import the Window trait extension instead of registering the plugin: + +```rust +use tauri_plugin_positioner::{WindowExt, Position}; + +let mut win = app.get_window("main").unwrap(); +let _ = win.move_window(Position::TopRight); ``` ## Contributing @@ -20,6 +87,6 @@ PRs accepted. Please make sure to read the Contributing Guide before making a pu ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2021 - Jonas Kruckenberg. 2021 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/plugins/positioner/package.json b/plugins/positioner/package.json index 5ee70039..8f20982c 100644 --- a/plugins/positioner/package.json +++ b/plugins/positioner/package.json @@ -1,6 +1,7 @@ { "name": "tauri-plugin-positioner-api", "version": "0.0.0", + "description": "Position your windows at well-known locations.", "license": "MIT or APACHE-2.0", "authors": [ "Tauri Programme within The Commons Conservancy" diff --git a/plugins/sql/Cargo.toml b/plugins/sql/Cargo.toml index cee4ba13..c72e237c 100644 --- a/plugins/sql/Cargo.toml +++ b/plugins/sql/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "tauri-plugin-sql" version = "0.1.0" -edition.workspace = true +description = "Interface with SQL databases." authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/plugins/sql/README.md b/plugins/sql/README.md index 8649c739..2b7c6f9b 100644 --- a/plugins/sql/README.md +++ b/plugins/sql/README.md @@ -1,17 +1,66 @@ ![plugin-sql](banner.png) - +Interface with SQL databases through [sqlx](https://github.com/launchbadge/sqlx). It supports the `sqlite`, `mysql` and `postgres` drivers, enabled by a Cargo feature. ## Install +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` + +```toml +[dependencies.tauri-plugin-sql] +git = "https://github.com/tauri-apps/plugins-workspace" +branch = "dev" +features = ["sqlite"] # or "postgres", or "mysql" ``` +You can install the JavaScript Guest bindings using your preferred JavaScript package manager: + +> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use. + +```sh +pnpm add https://github.com/tauri-apps/tauri-plugin-sql +# or +npm add https://github.com/tauri-apps/tauri-plugin-sql +# or +yarn add https://github.com/tauri-apps/tauri-plugin-sql ``` ## Usage +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_sql::Builder::default()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards all the plugin's APIs are available through the JavaScript guest bindings: + +```javascript +import Database from "tauri-plugin-sql-api"; + +// sqlite. The path is relative to `tauri::api::path::BaseDirectory::App`. +const db = await Database.load("sqlite:test.db"); +// mysql +const db = await Database.load("mysql://user:pass@host/database"); +// postgres +const db = await Database.load("postgres://postgres:password@localhost/test"); + +await db.execute("INSERT INTO ..."); ``` ## Contributing @@ -20,6 +69,6 @@ PRs accepted. Please make sure to read the Contributing Guide before making a pu ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/plugins/sql/package.json b/plugins/sql/package.json index 35b279ed..9ad3d1fe 100644 --- a/plugins/sql/package.json +++ b/plugins/sql/package.json @@ -1,6 +1,7 @@ { "name": "tauri-plugin-sql-api", "version": "0.0.0", + "description": "Interface with SQL databases", "license": "MIT or APACHE-2.0", "authors": [ "Tauri Programme within The Commons Conservancy" diff --git a/plugins/sql/src/plugin.rs b/plugins/sql/src/plugin.rs index 5440c926..0674f634 100644 --- a/plugins/sql/src/plugin.rs +++ b/plugins/sql/src/plugin.rs @@ -14,8 +14,8 @@ use sqlx::{ }; use tauri::{ command, - plugin::{Plugin, Result as PluginResult}, - AppHandle, Invoke, Manager, RunEvent, Runtime, State, + plugin::{Builder as PluginBuilder, TauriPlugin}, + AppHandle, Manager, RunEvent, Runtime, State, }; use tokio::sync::Mutex; @@ -92,7 +92,7 @@ struct DbInstances(Mutex>>); struct Migrations(Mutex>); #[derive(Default, Deserialize)] -struct PluginConfig { +pub struct PluginConfig { #[serde(default)] preload: Vec, } @@ -300,88 +300,69 @@ async fn select( Ok(values) } -/// Tauri SQL plugin. -pub struct TauriSql { +/// Tauri SQL plugin builder. +pub struct Builder { migrations: Option>, - invoke_handler: Box) + Send + Sync>, } -impl Default for TauriSql { - fn default() -> Self { - Self { - migrations: Some(Default::default()), - invoke_handler: Box::new(tauri::generate_handler![load, execute, select, close]), - } - } -} - -impl TauriSql { +impl Builder { /// Add migrations to a database. #[must_use] pub fn add_migrations(mut self, db_url: &str, migrations: Vec) -> Self { self.migrations - .as_mut() - .unwrap() + .get_or_insert(Default::default()) .insert(db_url.to_string(), MigrationList(migrations)); self } -} - -impl Plugin for TauriSql { - fn name(&self) -> &'static str { - "sql" - } - - fn initialize(&mut self, app: &AppHandle, config: serde_json::Value) -> PluginResult<()> { - tauri::async_runtime::block_on(async move { - let config: PluginConfig = if config.is_null() { - Default::default() - } else { - serde_json::from_value(config)? - }; - #[cfg(feature = "sqlite")] - create_dir_all(app_path(app)).expect("problems creating App directory!"); + pub fn build(mut self) -> TauriPlugin> { + PluginBuilder::new("sql") + .invoke_handler(tauri::generate_handler![load, execute, select, close]) + .setup_with_config(|app, config: Option| { + let config = config.unwrap_or_default(); - let instances = DbInstances::default(); - let mut lock = instances.0.lock().await; - for db in config.preload { #[cfg(feature = "sqlite")] - let fqdb = path_mapper(app_path(app), &db); - #[cfg(not(feature = "sqlite"))] - let fqdb = db.clone(); - - if !Db::database_exists(&fqdb).await.unwrap_or(false) { - Db::create_database(&fqdb).await?; - } - let pool = Pool::connect(&fqdb).await?; - - if let Some(migrations) = self.migrations.as_mut().unwrap().remove(&db) { - let migrator = Migrator::new(migrations).await?; - migrator.run(&pool).await?; - } - lock.insert(db, pool); - } - drop(lock); - app.manage(instances); - app.manage(Migrations(Mutex::new(self.migrations.take().unwrap()))); - Ok(()) - }) - } - - fn extend_api(&mut self, message: Invoke) { - (self.invoke_handler)(message) - } + create_dir_all(app_path(app)).expect("problems creating App directory!"); + + tauri::async_runtime::block_on(async move { + let instances = DbInstances::default(); + let mut lock = instances.0.lock().await; + for db in config.preload { + #[cfg(feature = "sqlite")] + let fqdb = path_mapper(app_path(app), &db); + #[cfg(not(feature = "sqlite"))] + let fqdb = db.clone(); + + if !Db::database_exists(&fqdb).await.unwrap_or(false) { + Db::create_database(&fqdb).await?; + } + let pool = Pool::connect(&fqdb).await?; - fn on_event(&mut self, app: &AppHandle, event: &RunEvent) { - if let RunEvent::Exit = event { - tauri::async_runtime::block_on(async move { - let instances = &*app.state::(); - let instances = instances.0.lock().await; - for value in instances.values() { - value.close().await; + if let Some(migrations) = self.migrations.as_mut().unwrap().remove(&db) { + let migrator = Migrator::new(migrations).await?; + migrator.run(&pool).await?; + } + lock.insert(db, pool); + } + drop(lock); + + app.manage(instances); + app.manage(Migrations(Mutex::new(self.migrations.take().unwrap()))); + + Ok(()) + }) + }) + .on_event(|app, event| { + if let RunEvent::Exit = event { + tauri::async_runtime::block_on(async move { + let instances = &*app.state::(); + let instances = instances.0.lock().await; + for value in instances.values() { + value.close().await; + } + }); } - }); - } + }) + .build() } } diff --git a/plugins/store/Cargo.toml b/plugins/store/Cargo.toml index 4ea9924e..9fd091fc 100644 --- a/plugins/store/Cargo.toml +++ b/plugins/store/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "tauri-plugin-store" version = "0.1.0" -edition.workspace = true +description = "Simple, persistent key-value store." authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/plugins/store/README.md b/plugins/store/README.md index 8baf2b8e..0e1eb29a 100644 --- a/plugins/store/README.md +++ b/plugins/store/README.md @@ -1,17 +1,62 @@ ![plugin-store](banner.png) - +Simple, persistent key-value store. ## Install +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` + +```toml +[dependencies] +tauri-plugin-store = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } ``` +You can install the JavaScript Guest bindings using your preferred JavaScript package manager: + +> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use. + +```sh +pnpm add https://github.com/tauri-apps/tauri-plugin-store +# or +npm add https://github.com/tauri-apps/tauri-plugin-store +# or +yarn add https://github.com/tauri-apps/tauri-plugin-store ``` ## Usage +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_store::Builder::default().build()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards all the plugin's APIs are available through the JavaScript guest bindings: + +```javascript +import { Store } from "tauri-plugin-store-api"; + +const store = new Store(".settings.dat"); + +await store.set("some-key", { value: 5 }); + +const val = await store.get("some-key"); +assert(val, { value: 5 }); ``` ## Contributing @@ -20,6 +65,6 @@ PRs accepted. Please make sure to read the Contributing Guide before making a pu ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/plugins/store/package.json b/plugins/store/package.json index cc55321f..37f6c532 100644 --- a/plugins/store/package.json +++ b/plugins/store/package.json @@ -1,6 +1,7 @@ { "name": "tauri-plugin-store-api", "version": "0.0.0", + "description": "Simple, persistent key-value store.", "license": "MIT or APACHE-2.0", "authors": [ "Tauri Programme within The Commons Conservancy" diff --git a/plugins/store/src/lib.rs b/plugins/store/src/lib.rs index db9b3048..6c641dbc 100644 --- a/plugins/store/src/lib.rs +++ b/plugins/store/src/lib.rs @@ -244,12 +244,12 @@ async fn save( } #[derive(Default)] -pub struct PluginBuilder { +pub struct Builder { stores: HashMap, frozen: bool, } -impl PluginBuilder { +impl Builder { /// Registers a store with the plugin. /// /// # Examples diff --git a/plugins/store/src/store.rs b/plugins/store/src/store.rs index 867bb0cd..af106e30 100644 --- a/plugins/store/src/store.rs +++ b/plugins/store/src/store.rs @@ -176,7 +176,7 @@ impl Store { .expect("failed to resolve app dir"); let store_path = app_dir.join(&self.path); - let bytes = read(&store_path)?; + let bytes = read(store_path)?; self.cache = (self.deserialize)(&bytes).map_err(Error::Deserialize)?; diff --git a/plugins/stronghold/Cargo.toml b/plugins/stronghold/Cargo.toml index ba8f6c3f..7abd5f07 100644 --- a/plugins/stronghold/Cargo.toml +++ b/plugins/stronghold/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "tauri-plugin-stronghold" version = "0.1.0" -edition.workspace = true +description = "Store secrets and keys using the IOTA Stronghold encrypted database." authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/plugins/stronghold/README.md b/plugins/stronghold/README.md index 0f5158c4..bc79b46c 100644 --- a/plugins/stronghold/README.md +++ b/plugins/stronghold/README.md @@ -1,17 +1,61 @@ ![plugin-stronghold](banner.png) - +Store secrets and keys using the [IOTA Stronghold](https://github.com/iotaledger/stronghold.rs) encrypted database and secure runtime. ## Install +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` + +```toml +[dependencies] +tauri-plugin-stronghold = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } ``` +You can install the JavaScript Guest bindings using your preferred JavaScript package manager: + +> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use. + +```sh +pnpm add https://github.com/tauri-apps/tauri-plugin-stronghold +# or +npm add https://github.com/tauri-apps/tauri-plugin-stronghold +# or +yarn add https://github.com/tauri-apps/tauri-plugin-stronghold ``` ## Usage +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_stronghold::Builder::new(|password| { + // TODO: hash the password here with e.g. argon2, blake2b or any other secure algorithm + todo!() + }) + .build()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards all the plugin's APIs are available through the JavaScript guest bindings: + +```javascript +import { Stronghold, Location } from "tauri-plugin-stronghold-api"; + +// TODO ``` ## Contributing @@ -20,6 +64,6 @@ PRs accepted. Please make sure to read the Contributing Guide before making a pu ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/plugins/stronghold/package.json b/plugins/stronghold/package.json index b929c2c2..4892e730 100644 --- a/plugins/stronghold/package.json +++ b/plugins/stronghold/package.json @@ -1,6 +1,7 @@ { "name": "tauri-plugin-stronghold-api", "version": "0.0.0", + "description": "Store secrets and keys using the IOTA Stronghold encrypted database.", "license": "MIT or APACHE-2.0", "authors": [ "Tauri Programme within The Commons Conservancy" diff --git a/plugins/upload/Cargo.toml b/plugins/upload/Cargo.toml index 9d427d15..26ec517e 100644 --- a/plugins/upload/Cargo.toml +++ b/plugins/upload/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "tauri-plugin-upload" version = "0.1.0" -edition.workspace = true +description = "Upload files from disk to a remote server over HTTP." authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -13,7 +15,7 @@ serde_json.workspace = true tauri.workspace = true log.workspace = true thiserror.workspace = true -tokio = { version = "1.17", features = [ "fs" ] } +tokio = { version = "1", features = [ "fs" ] } tokio-util = { version = "0.7", features = [ "codec" ] } reqwest = { version = "0.11", features = [ "json", "stream" ] } futures = "0.3" diff --git a/plugins/upload/README.md b/plugins/upload/README.md index 04bb3400..1168a362 100644 --- a/plugins/upload/README.md +++ b/plugins/upload/README.md @@ -1,17 +1,62 @@ ![plugin-upload](banner.png) - +Upload files from disk to a remote server over HTTP. ## Install +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` + +```toml +[dependencies] +tauri-plugin-upload = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } ``` +You can install the JavaScript Guest bindings using your preferred JavaScript package manager: + +> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use. + +```sh +pnpm add https://github.com/tauri-apps/tauri-plugin-upload +# or +npm add https://github.com/tauri-apps/tauri-plugin-upload +# or +yarn add https://github.com/tauri-apps/tauri-plugin-upload ``` ## Usage +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_upload::init()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards all the plugin's APIs are available through the JavaScript guest bindings: + +```javascript +import { upload } from 'tauri-plugin-upload-api' + +upload( + 'https://example.com/file-upload' + './path/to/my/file.txt' + (progress, total) => console.log(`Downloaded ${progress} of ${total} bytes`) // a callback that will be called with the upload progress + { 'ContentType': 'text/plain' } // optional headers to send with the request +) ``` ## Contributing @@ -20,6 +65,6 @@ PRs accepted. Please make sure to read the Contributing Guide before making a pu ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/plugins/upload/package.json b/plugins/upload/package.json index 8ec9afaf..711620b2 100644 --- a/plugins/upload/package.json +++ b/plugins/upload/package.json @@ -1,6 +1,7 @@ { "name": "tauri-plugin-upload-api", "version": "0.0.0", + "description": "Upload files from disk to a remote server over HTTP.", "license": "MIT or APACHE-2.0", "authors": [ "Tauri Programme within The Commons Conservancy" diff --git a/plugins/upload/src/lib.rs b/plugins/upload/src/lib.rs index b739435d..a83a87ff 100644 --- a/plugins/upload/src/lib.rs +++ b/plugins/upload/src/lib.rs @@ -4,7 +4,11 @@ use futures::TryStreamExt; use serde::{ser::Serializer, Serialize}; -use tauri::{command, plugin::Plugin, Invoke, Runtime, Window}; +use tauri::{ + command, + plugin::{Builder as PluginBuilder, TauriPlugin}, + Runtime, Window, +}; use tokio::fs::File; use tokio_util::codec::{BytesCodec, FramedRead}; @@ -82,25 +86,8 @@ fn file_to_body(id: u32, window: Window, file: File) -> reqwest:: )) } -/// Tauri plugin. -pub struct Upload { - invoke_handler: Box) + Send + Sync>, -} - -impl Default for Upload { - fn default() -> Self { - Self { - invoke_handler: Box::new(tauri::generate_handler![upload]), - } - } -} - -impl Plugin for Upload { - fn name(&self) -> &'static str { - "upload" - } - - fn extend_api(&mut self, message: Invoke) { - (self.invoke_handler)(message) - } +pub fn init() -> TauriPlugin { + PluginBuilder::new("upload") + .invoke_handler(tauri::generate_handler![upload]) + .build() } diff --git a/plugins/websocket/Cargo.toml b/plugins/websocket/Cargo.toml index 1bea91f3..1233eccc 100644 --- a/plugins/websocket/Cargo.toml +++ b/plugins/websocket/Cargo.toml @@ -1,9 +1,10 @@ [package] name = "tauri-plugin-websocket" version = "0.1.0" -edition.workspace = true authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -15,5 +16,5 @@ log.workspace = true thiserror.workspace = true rand = "0.8" futures-util = "0.3" -tokio = { version = "1.17", features = ["net", "sync"] } -tokio-tungstenite = { version = "0.17", features = ["native-tls"] } \ No newline at end of file +tokio = { version = "1", features = ["net", "sync"] } +tokio-tungstenite = { version = "0.18", features = ["native-tls"] } \ No newline at end of file diff --git a/plugins/websocket/README.md b/plugins/websocket/README.md index a864895b..954a650f 100644 --- a/plugins/websocket/README.md +++ b/plugins/websocket/README.md @@ -4,14 +4,58 @@ ## Install +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` + +```toml +[dependencies] +tauri-plugin-websocket = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } ``` +You can install the JavaScript Guest bindings using your preferred JavaScript package manager: + +> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use. + +```sh +pnpm add https://github.com/tauri-apps/tauri-plugin-websocket +# or +npm add https://github.com/tauri-apps/tauri-plugin-websocket +# or +yarn add https://github.com/tauri-apps/tauri-plugin-websocket ``` ## Usage +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_websocket::init()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards all the plugin's APIs are available through the JavaScript guest bindings: + +```javascript +import { WebSocket } from "tauri-plugin-websocket-api"; + +const ws = await WebSocket.connect("wss://example.com"); + +await ws.send("Hello World"); + +await ws.disconnect(); ``` ## Contributing @@ -20,6 +64,6 @@ PRs accepted. Please make sure to read the Contributing Guide before making a pu ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/plugins/websocket/src/lib.rs b/plugins/websocket/src/lib.rs index dccea1ec..c3e08ace 100644 --- a/plugins/websocket/src/lib.rs +++ b/plugins/websocket/src/lib.rs @@ -1,10 +1,9 @@ use futures_util::{stream::SplitSink, SinkExt, StreamExt}; use serde::{ser::Serializer, Deserialize, Serialize}; -use serde_json::Value as JsonValue; use tauri::{ api::ipc::{format_callback, CallbackFn}, - plugin::Plugin, - AppHandle, Invoke, Manager, Runtime, State, Window, + plugin::{Builder as PluginBuilder, TauriPlugin}, + Manager, Runtime, State, Window, }; use tokio::{net::TcpStream, sync::Mutex}; use tokio_tungstenite::{ @@ -161,29 +160,12 @@ async fn send( } } -pub struct TauriWebsocket { - invoke_handler: Box) + Send + Sync>, -} - -impl Default for TauriWebsocket { - fn default() -> Self { - Self { - invoke_handler: Box::new(tauri::generate_handler![connect, send]), - } - } -} - -impl Plugin for TauriWebsocket { - fn name(&self) -> &'static str { - "websocket" - } - - fn initialize(&mut self, app: &AppHandle, _config: JsonValue) -> tauri::plugin::Result<()> { - app.manage(ConnectionManager::default()); - Ok(()) - } - - fn extend_api(&mut self, invoke: Invoke) { - (self.invoke_handler)(invoke) - } +pub fn init() -> TauriPlugin { + PluginBuilder::new("websocket") + .invoke_handler(tauri::generate_handler![connect, send]) + .setup(|app| { + app.manage(ConnectionManager::default()); + Ok(()) + }) + .build() } diff --git a/plugins/window-state/Cargo.toml b/plugins/window-state/Cargo.toml index 001ac646..00d15f97 100644 --- a/plugins/window-state/Cargo.toml +++ b/plugins/window-state/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "tauri-plugin-window-state" version = "0.1.0" -edition.workspace = true +description = "Save window positions and sizse and restore them when the app is reopened." authors.workspace = true license.workspace = true +edition.workspace = true +rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/plugins/window-state/README.md b/plugins/window-state/README.md index 3f2619a2..de309e73 100644 --- a/plugins/window-state/README.md +++ b/plugins/window-state/README.md @@ -1,17 +1,57 @@ ![plugin-window-state](banner.png) - +Save window positions and sizse and restore them when the app is reopened. ## Install -``` +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` +```toml +[dependencies] +tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } ``` ## Usage +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_window_state::Builder::default().build()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards all windows will remember their state when the app is being closed and will restore to their previous state on the next launch. + +Optionally you can also tell the plugin to save the state of all open window to disk my using the `save_window_state()` method exposed by the `AppHandleExt` trait: + +```rust +use tauri_plugin_window_state::AppHandleExt; + +// `tauri::AppHandle` now has the following additional method +app.save_window_state(); // will save the state of all open windows to disk +``` + +To manually restore a windows state from disk you can call the `restore_state()` method exposed by the `WindowExt` trait: + +```rust +use tauri_plugin_window_state::{WindowExt, ShowMode}; + +// all `Window` types now have the following additional method +window.restore_state(ShowMode::LastSaved); // will restore the windows state from disk ``` ## Contributing @@ -20,6 +60,6 @@ PRs accepted. Please make sure to read the Contributing Guide before making a pu ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/renovate.json b/renovate.json new file mode 100644 index 00000000..4dac52b1 --- /dev/null +++ b/renovate.json @@ -0,0 +1,4 @@ +{ + "extends": ["config:base"], + "enabledManagers": ["cargo", "npm"] +} diff --git a/shared/template/README.md b/shared/template/README.md index 97196018..0a059e4f 100644 --- a/shared/template/README.md +++ b/shared/template/README.md @@ -1,17 +1,55 @@ -{{name}} +![{{plugin name}}](banner.jpg) ## Install +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) +2. Pull sources directly from Github using git tags / revision hashes (most secure) +3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) + +Install the Core plugin by adding the following to your `Cargo.toml` file: + +`src-tauri/Cargo.toml` + +```toml +[dependencies] + = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } ``` +You can install the JavaScript Guest bindings using your preferred JavaScript package manager: + +> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use. + +```sh +pnpm add +# or +npm add +# or +yarn add ``` ## Usage +First you need to register the core plugin with Tauri: + +`src-tauri/src/main.rs` + +```rust +fn main() { + tauri::Builder::default() + .plugin() + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} ``` +Afterwards all the plugin's APIs are available through the JavaScript guest bindings: + +```javascript + ``` ## Contributing @@ -20,6 +58,6 @@ PRs accepted. Please make sure to read the Contributing Guide before making a pu ## License -Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy. +Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. MIT or MIT/Apache 2.0 where applicable. diff --git a/shared/template/guest-js/tsconfig.json b/shared/template/guest-js/tsconfig.json deleted file mode 120000 index 9c2b2da2..00000000 --- a/shared/template/guest-js/tsconfig.json +++ /dev/null @@ -1 +0,0 @@ -../../../shared/tsconfig.json \ No newline at end of file diff --git a/shared/template/guest-js/package.json b/shared/template/package.json similarity index 63% rename from shared/template/guest-js/package.json rename to shared/template/package.json index 2c479ef3..ac5eefd1 100644 --- a/shared/template/guest-js/package.json +++ b/shared/template/package.json @@ -6,13 +6,13 @@ "Tauri Programme within The Commons Conservancy" ], "type": "module", - "browser": "dist/index.min.js", - "module": "dist/index.mjs", - "types": "dist/index.d.ts", + "browser": "guest-js/dist/index.min.js", + "module": "guest-js/dist/index.mjs", + "types": "guest-js/dist/index.d.ts", "exports": { - "import": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "browser": "./dist/index.min.js" + "import": "./guest-js/dist/index.mjs", + "types": "./guest-js/dist/index.d.ts", + "browser": "./guest-js/dist/index.min.js" }, "scripts": { "build": "rollup -c" diff --git a/shared/template/guest-js/rollup.config.mjs b/shared/template/rollup.config.mjs similarity index 70% rename from shared/template/guest-js/rollup.config.mjs rename to shared/template/rollup.config.mjs index ee885522..96840adc 100644 --- a/shared/template/guest-js/rollup.config.mjs +++ b/shared/template/rollup.config.mjs @@ -1,8 +1,9 @@ import { readFileSync } from "fs"; -import { createConfig } from "../../../shared/rollup.config.mjs"; +import { createConfig } from "../rollup.config.mjs"; export default createConfig({ + input: "guest-js/index.ts", pkg: JSON.parse( readFileSync(new URL("./package.json", import.meta.url), "utf8") ), diff --git a/shared/template/tsconfig.json b/shared/template/tsconfig.json new file mode 120000 index 00000000..4ec6ff6a --- /dev/null +++ b/shared/template/tsconfig.json @@ -0,0 +1 @@ +../tsconfig.json \ No newline at end of file