Compare commits

...

19 Commits

Author SHA1 Message Date
github-actions[bot] ecda84f8d5 Publish New Versions (v2) (#1279)
Co-authored-by: lucasfernog <lucasfernog@users.noreply.github.com>
2024-05-11 07:13:52 -03:00
Fabian-Lars 021d23bef3 feat(deep-link): Add deep link support for desktop (#916) 2024-05-10 07:44:06 -03:00
Amr Bashir eb1679b997 fix(core/shell): speedup Command.execute & fix extra new lines (#1299)
* fix(core/shell): speedup `Command.execute` & fix extra new lines

The speed gains comes from running the Command in Rust fully and returning the result in one go instead of using events.

The extra new lines was a regression from https://github.com/tauri-apps/tauri/pull/6519
ref: https://github.com/tauri-apps/tauri/issues/7684#issuecomment-2100897383

* fmt

* dedup code
2024-05-09 18:15:03 +03:00
Amr Bashir 5c1b7917e4 fix(shell/command): retry sending events when it fails (#1298)
ref: https://github.com/tauri-apps/tauri/issues/7684
2024-05-09 10:38:56 -03:00
amrbashir 6af3216fab docs(global-shortcut): typo 2024-05-09 05:01:28 +03:00
Amr Bashir fa54f3cc9a fix(log): propagte some errors and avoid unwrapping (#1297) 2024-05-08 17:10:29 +03:00
renovate[bot] 56dde76889 chore(deps): update dependency eslint-plugin-n to v17.5.1 (#1292)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-07 16:19:57 +02:00
renovate[bot] 89a7754bdf chore(deps): update dependency svelte to v4.2.16 (#1293)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-07 16:17:18 +02:00
amrbashir 52a48dd80a docs(global-shortcut): add missing import 2024-05-07 17:01:54 +03:00
Amr Bashir 1829c2806a docs(global-shotcut): update docs in README and ts files (#1291) 2024-05-07 17:00:53 +03:00
renovate[bot] 723b9f7fa8 chore(deps): update dependency @tauri-apps/cli to v2.0.0-beta.16 (#1288)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-07 08:47:23 +02:00
renovate[bot] 62b0d739bc chore(deps): update dependency eslint-plugin-n to v17.5.0 (#1290)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-07 08:43:10 +02:00
renovate[bot] c776916f14 chore(deps): update dependency @iconify-json/ph to v1.1.13 (#1285)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-06 09:17:26 +02:00
Amr Bashir d9de5b19d1 feat(positioner, window-state): impl WindowExt for WebviewWindow (#1283)
closes #1281
2024-05-03 13:16:40 +02:00
Graham Held b4efa58d5d feat(shell) raw-encoded pipe reader directly outputs buffer (no newline scan) (#1231)
* Shell raw-encoded pipe reader directly outputs buffer (no newline scan)

* Suggestions from code review and add .changes file

* fmt
2024-05-02 16:00:03 +03:00
renovate[bot] aea748ced7 chore(deps): update dependency vite to v5.2.11 (#1278)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-02 13:04:46 +02:00
Fabian-Lars 8fecaba3f0 ci: Disable Cargo.lock patch updates for 0.x deps 2024-05-01 22:20:37 +02:00
Fabian-Lars f255343b54 ci: Disable Cargo.lock updates for patch/minor to make MSRV handling easier later. 2024-05-01 22:17:33 +02:00
Fabian-Lars e045223660 ci: Prevent renovate from changing stable patch/minor versions in cargo.toml 2024-05-01 22:04:42 +02:00
65 changed files with 1234 additions and 371 deletions
+6
View File
@@ -0,0 +1,6 @@
---
"deep-link": patch
"deep-link-js": patch
---
Added desktop support.
+6
View File
@@ -0,0 +1,6 @@
---
"shell": patch
---
When the "raw" encoding option is specified for a shell process, all bytes from the child's output streams are passed to the data handlers.
This makes it possible to read output from programs that write unencoded byte streams to stdout (like ffmpeg)
+6
View File
@@ -0,0 +1,6 @@
---
"positioner": "patch"
"window-state": "patch"
---
Implement `WindowExt` for `WebviewWindow`.
+6
View File
@@ -7,12 +7,14 @@
".changes/clipboard-manager-image.md",
".changes/clipboard-refactor.md",
".changes/clipboard-text-command-rename.md",
".changes/deep-link-desktop.md",
".changes/dialog-can-create-directories.md",
".changes/dialog-linux-freeze.md",
".changes/dialog-main-thread.md",
".changes/dialog-path-return-mismatch.md",
".changes/enhance-fs-scope-type.md",
".changes/enhance-http-scope.md",
".changes/enhance-shell-raw-out.md",
".changes/feat-log-attachlogger.md",
".changes/feat-single-instance-semver.md",
".changes/feat-websocket-tls-connector.md",
@@ -35,6 +37,7 @@
".changes/global-shortcut-refactor.md",
".changes/http-unsafe-headers.md",
".changes/http-user-agent.md",
".changes/impl-ext-for-webview-windows.md",
".changes/msrv-1.75.md",
".changes/notification-fix-dev-check.md",
".changes/public-with-store.md",
@@ -42,6 +45,9 @@
".changes/reqwest-0.12.md",
".changes/restore-default-window-state.md",
".changes/scoped-resources-table.md",
".changes/shell-command-execute-extra-new-lines.md",
".changes/shell-command-execute-speed.md",
".changes/shell-command-lost-events.md",
".changes/shell-fix-schema-command-property-name.md",
".changes/shell-shellexcute.md",
".changes/single-instance.macos.md",
@@ -0,0 +1,5 @@
---
"shell-js": "patch"
---
Fix `Command.execute` API including extra new lines.
+6
View File
@@ -0,0 +1,6 @@
---
"shell": "patch"
"shell-js": "patch"
---
Improve the speed of the JS `Command.execute` API
+5
View File
@@ -0,0 +1,5 @@
---
"shell": "patch"
---
Fix the JS `Command` API losing events for `stdout`.
+3
View File
@@ -56,6 +56,9 @@ jobs:
tauri-plugin-clipboard-manager:
- .github/workflows/test-rust.yml
- plugins/clipboard-manager/**
tauri-plugin-deep-link:
- .github/workflows/test-rust.yml
- plugins/deep-link/**
tauri-plugin-dialog:
- .github/workflows/test-rust.yml
- plugins/dialog/**
Generated
+111 -30
View File
@@ -230,7 +230,7 @@ checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
[[package]]
name = "api"
version = "2.0.0-beta.6"
version = "2.0.0-beta.7"
dependencies = [
"log",
"serde",
@@ -1161,6 +1161,26 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "const-random"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359"
dependencies = [
"const-random-macro",
]
[[package]]
name = "const-random-macro"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [
"getrandom 0.2.12",
"once_cell",
"tiny-keccak",
]
[[package]]
name = "constant_time_eq"
version = "0.1.5"
@@ -1621,6 +1641,15 @@ dependencies = [
"syn 2.0.52",
]
[[package]]
name = "dlv-list"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f"
dependencies = [
"const-random",
]
[[package]]
name = "dotenvy"
version = "0.15.7"
@@ -3199,7 +3228,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
dependencies = [
"cfg-if",
"windows-targets 0.48.5",
"windows-targets 0.52.5",
]
[[package]]
@@ -3830,6 +3859,16 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "ordered-multimap"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79"
dependencies = [
"dlv-list",
"hashbrown 0.14.3",
]
[[package]]
name = "ordered-stream"
version = "0.2.0"
@@ -4779,6 +4818,17 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "rust-ini"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d625ed57d8f49af6cfa514c42e1a71fadcff60eb0b1c517ff82fe41aa025b41"
dependencies = [
"cfg-if",
"ordered-multimap",
"trim-in-place",
]
[[package]]
name = "rust_decimal"
version = "1.34.3"
@@ -6043,7 +6093,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-authenticator"
version = "2.0.0-beta.4"
version = "2.0.0-beta.5"
dependencies = [
"authenticator",
"base64 0.22.0",
@@ -6065,7 +6115,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-autostart"
version = "2.0.0-beta.4"
version = "2.0.0-beta.5"
dependencies = [
"auto-launch",
"log",
@@ -6078,7 +6128,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-barcode-scanner"
version = "2.0.0-beta.4"
version = "2.0.0-beta.5"
dependencies = [
"log",
"serde",
@@ -6090,7 +6140,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-biometric"
version = "2.0.0-beta.3"
version = "2.0.0-beta.4"
dependencies = [
"log",
"serde",
@@ -6103,7 +6153,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-cli"
version = "2.0.0-beta.3"
version = "2.0.0-beta.4"
dependencies = [
"clap",
"log",
@@ -6116,7 +6166,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-clipboard-manager"
version = "2.1.0-beta.1"
version = "2.1.0-beta.2"
dependencies = [
"arboard",
"image",
@@ -6130,20 +6180,25 @@ dependencies = [
[[package]]
name = "tauri-plugin-deep-link"
version = "2.0.0-beta.3"
version = "2.0.0-beta.4"
dependencies = [
"dunce",
"log",
"rust-ini",
"serde",
"serde_json",
"tauri",
"tauri-plugin",
"tauri-utils",
"thiserror",
"url",
"windows-registry",
"windows-result",
]
[[package]]
name = "tauri-plugin-dialog"
version = "2.0.0-beta.6"
version = "2.0.0-beta.7"
dependencies = [
"dunce",
"log",
@@ -6159,7 +6214,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-fs"
version = "2.0.0-beta.6"
version = "2.0.0-beta.7"
dependencies = [
"anyhow",
"glob",
@@ -6178,7 +6233,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-global-shortcut"
version = "2.0.0-beta.3"
version = "2.0.0-beta.4"
dependencies = [
"global-hotkey",
"log",
@@ -6191,7 +6246,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-http"
version = "2.0.0-beta.6"
version = "2.0.0-beta.7"
dependencies = [
"data-url",
"http",
@@ -6210,7 +6265,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-localhost"
version = "2.0.0-beta.3"
version = "2.0.0-beta.4"
dependencies = [
"http",
"log",
@@ -6223,7 +6278,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-log"
version = "2.0.0-beta.3"
version = "2.0.0-beta.4"
dependencies = [
"android_logger",
"byte-unit",
@@ -6242,7 +6297,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-nfc"
version = "2.0.0-beta.3"
version = "2.0.0-beta.4"
dependencies = [
"log",
"serde",
@@ -6255,7 +6310,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-notification"
version = "2.0.0-beta.4"
version = "2.0.0-beta.5"
dependencies = [
"chrono",
"color-backtrace",
@@ -6282,7 +6337,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-os"
version = "2.0.0-beta.3"
version = "2.0.0-beta.4"
dependencies = [
"gethostname",
"log",
@@ -6298,7 +6353,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-persisted-scope"
version = "2.0.0-beta.6"
version = "2.0.0-beta.7"
dependencies = [
"aho-corasick",
"bincode",
@@ -6312,7 +6367,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-positioner"
version = "2.0.0-beta.3"
version = "2.0.0-beta.4"
dependencies = [
"log",
"serde",
@@ -6325,7 +6380,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-process"
version = "2.0.0-beta.3"
version = "2.0.0-beta.4"
dependencies = [
"tauri",
"tauri-plugin",
@@ -6333,7 +6388,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-shell"
version = "2.0.0-beta.3"
version = "2.0.0-beta.4"
dependencies = [
"encoding_rs",
"log",
@@ -6347,11 +6402,12 @@ dependencies = [
"tauri",
"tauri-plugin",
"thiserror",
"tokio",
]
[[package]]
name = "tauri-plugin-single-instance"
version = "2.0.0-beta.6"
version = "2.0.0-beta.7"
dependencies = [
"log",
"semver",
@@ -6365,7 +6421,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-sql"
version = "2.0.0-beta.3"
version = "2.0.0-beta.4"
dependencies = [
"futures-core",
"log",
@@ -6381,7 +6437,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-store"
version = "2.0.0-beta.5"
version = "2.0.0-beta.6"
dependencies = [
"dunce",
"log",
@@ -6394,7 +6450,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-stronghold"
version = "2.0.0-beta.3"
version = "2.0.0-beta.4"
dependencies = [
"hex",
"iota-crypto 0.23.1",
@@ -6415,7 +6471,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-updater"
version = "2.0.0-beta.4"
version = "2.0.0-beta.5"
dependencies = [
"base64 0.22.0",
"dirs-next",
@@ -6442,7 +6498,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-upload"
version = "2.0.0-beta.4"
version = "2.0.0-beta.5"
dependencies = [
"futures-util",
"log",
@@ -6459,7 +6515,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-websocket"
version = "2.0.0-beta.4"
version = "2.0.0-beta.5"
dependencies = [
"futures-util",
"http",
@@ -6476,7 +6532,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-window-state"
version = "2.0.0-beta.5"
version = "2.0.0-beta.6"
dependencies = [
"bitflags 2.4.2",
"log",
@@ -6701,6 +6757,15 @@ dependencies = [
"time-core",
]
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
"crunchy",
]
[[package]]
name = "tiny_http"
version = "0.12.0"
@@ -7023,6 +7088,12 @@ dependencies = [
"serde_json",
]
[[package]]
name = "trim-in-place"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc"
[[package]]
name = "try-lock"
version = "0.2.5"
@@ -7741,6 +7812,16 @@ dependencies = [
"syn 2.0.52",
]
[[package]]
name = "windows-registry"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f721bc2e55efb506a1a395a545cb76c2481fb023d33b51f0050e7888716281cf"
dependencies = [
"windows-result",
"windows-targets 0.52.5",
]
[[package]]
name = "windows-result"
version = "0.1.1"
+1
View File
@@ -13,6 +13,7 @@ log = "0.4"
tauri = "2.0.0-beta.17"
tauri-build = "2.0.0-beta.13"
tauri-plugin = "2.0.0-beta.13"
tauri-utils = "2.0.0-beta.13"
serde_json = "1"
thiserror = "1"
url = "2"
+6
View File
@@ -1,5 +1,11 @@
# Changelog
## \[2.0.0-beta.6]
### Dependencies
- Upgraded to `shell-js@2.0.0-beta.4`
## \[2.0.0-beta.5]
### Dependencies
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "svelte-app",
"private": true,
"version": "2.0.0-beta.5",
"version": "2.0.0-beta.6",
"type": "module",
"scripts": {
"dev": "vite --clearScreen false",
@@ -22,7 +22,7 @@
"@tauri-apps/plugin-notification": "2.0.0-beta.3",
"@tauri-apps/plugin-os": "2.0.0-beta.3",
"@tauri-apps/plugin-process": "2.0.0-beta.3",
"@tauri-apps/plugin-shell": "2.0.0-beta.3",
"@tauri-apps/plugin-shell": "2.0.0-beta.4",
"@tauri-apps/plugin-updater": "2.0.0-beta.3",
"@zerodevx/svelte-json-view": "1.0.9"
},
@@ -30,7 +30,7 @@
"@iconify-json/codicon": "^1.1.37",
"@iconify-json/ph": "^1.1.8",
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"@tauri-apps/cli": "2.0.0-beta.15",
"@tauri-apps/cli": "2.0.0-beta.16",
"@unocss/extractor-svelte": "^0.59.0",
"internal-ip": "^8.0.0",
"svelte": "^4.2.8",
+6
View File
@@ -1,5 +1,11 @@
# Changelog
## \[2.0.0-beta.8]
### Dependencies
- Upgraded to `shell@2.0.0-beta.5`
## \[2.0.0-beta.7]
### Dependencies
+2 -2
View File
@@ -1,7 +1,7 @@
[package]
name = "api"
publish = false
version = "2.0.0-beta.7"
version = "2.0.0-beta.8"
description = "An example Tauri Application showcasing the api"
edition = "2021"
rust-version = { workspace = true }
@@ -27,7 +27,7 @@ tauri-plugin-http = { path = "../../../plugins/http", features = [ "multipart" ]
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.0.0-beta.5", features = [ "windows7-compat" ] }
tauri-plugin-os = { path = "../../../plugins/os", version = "2.0.0-beta.4" }
tauri-plugin-process = { path = "../../../plugins/process", version = "2.0.0-beta.4" }
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.0.0-beta.4" }
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.0.0-beta.5" }
[dependencies.tauri]
workspace = true
@@ -2339,6 +2339,13 @@
"shell:allow-open"
]
},
{
"description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"shell:allow-spawn"
]
},
{
"description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.",
"type": "string",
@@ -2367,6 +2374,13 @@
"shell:deny-open"
]
},
{
"description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"shell:deny-spawn"
]
},
{
"description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.",
"type": "string",
@@ -5689,6 +5703,13 @@
"shell:allow-open"
]
},
{
"description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"shell:allow-spawn"
]
},
{
"description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.",
"type": "string",
@@ -5717,6 +5738,13 @@
"shell:deny-open"
]
},
{
"description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"shell:deny-spawn"
]
},
{
"description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.",
"type": "string",
+1 -1
View File
@@ -20,7 +20,7 @@
"eslint-config-prettier": "9.1.0",
"eslint-config-love": "47.0.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-n": "17.4.0",
"eslint-plugin-n": "17.5.1",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-security": "3.0.0",
"prettier": "3.2.5",
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.0.0-beta.4]
- [`021d23be`](https://github.com/tauri-apps/plugins-workspace/commit/021d23bef330de4ce001993e0ef2c7ab7815f044)([#916](https://github.com/tauri-apps/plugins-workspace/pull/916)) Added desktop support.
## \[2.0.0-beta.3]
- [`bd1ed590`](https://github.com/tauri-apps/plugins-workspace/commit/bd1ed5903ffcce5500310dac1e59e8c67674ef1e)([#1237](https://github.com/tauri-apps/plugins-workspace/pull/1237)) Update to tauri beta.17.
+11 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-deep-link"
version = "2.0.0-beta.4"
version = "2.0.0-beta.5"
description = "Set your Tauri application as the default handler for an URL"
authors = { workspace = true }
license = { workspace = true }
@@ -17,12 +17,22 @@ targets = [ "x86_64-linux-android" ]
[build-dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri-utils = { workspace = true }
tauri-plugin = { workspace = true, features = [ "build" ] }
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
tauri-utils = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
url = { workspace = true }
[target."cfg(windows)".dependencies]
dunce = "1"
windows-registry = "0.1"
windows-result = "0.1"
[target."cfg(target_os = \"linux\")".dependencies]
rust-ini = "0.21"
+9 -4
View File
@@ -93,16 +93,19 @@ See [supporting associated domains](https://developer.apple.com/documentation/xc
## Configuration
Under `tauri.conf.json > plugins > deep-link`, configure the domains you want to associate with your application:
Under `tauri.conf.json > plugins > deep-link`, configure the domains (mobile) and schemes (desktop) you want to associate with your application:
```json
{
"plugins": {
"deep-link": {
"domains": [
"mobile": [
{ "host": "your.website.com", "pathPrefix": ["/open"] },
{ "host": "another.site.br" }
]
],
"desktop": {
"schemes": ["something", "my-tauri-app"]
}
}
}
}
@@ -128,10 +131,12 @@ Afterwards all the plugin's APIs are available through the JavaScript guest bind
```javascript
import { onOpenUrl } from "@tauri-apps/plugin-deep-link";
await onOpenUrl((urls) => {
console.log('deep link:', urls);
console.log("deep link:", urls);
});
```
Note that the Plugin will only emit events on macOS, iOS and Android. On Windows and Linux the OS will spawn a new instance of your app with the URL as a CLI argument. If you want your app to behave on Windows & Linux similar to the other platforms you can use the [single-instance](../single-instance/) plugin.
## Contributing
PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
+1 -1
View File
@@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_DEEPLINK__=function(e){"use strict";function n(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}async function r(e,n={},r){return window.__TAURI_INTERNALS__.invoke(e,n,r)}var t;async function i(e,t,i){const _=(void 0,{kind:"Any"});return r("plugin:event|listen",{event:e,target:_,handler:n(t)}).then((n=>async()=>async function(e,n){await r("plugin:event|unlisten",{event:e,eventId:n})}(e,n)))}async function _(){return await r("plugin:deep-link|get_current")}return"function"==typeof SuppressedError&&SuppressedError,function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG="tauri://drag",e.DROP="tauri://drop",e.DROP_OVER="tauri://drop-over",e.DROP_CANCELLED="tauri://drag-cancelled"}(t||(t={})),e.getCurrent=_,e.onOpenUrl=async function(e){const n=await _();return null!=n&&e(n),await i("deep-link://new-url",(n=>{e(n.payload)}))},e}({});Object.defineProperty(window.__TAURI__,"deepLink",{value:__TAURI_PLUGIN_DEEPLINK__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_DEEPLINK__=function(e){"use strict";function n(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}async function r(e,n={},r){return window.__TAURI_INTERNALS__.invoke(e,n,r)}var t;async function i(e,t,i){const a=(void 0,{kind:"Any"});return r("plugin:event|listen",{event:e,target:a,handler:n(t)}).then((n=>async()=>async function(e,n){await r("plugin:event|unlisten",{event:e,eventId:n})}(e,n)))}async function a(){return await r("plugin:deep-link|get_current")}return"function"==typeof SuppressedError&&SuppressedError,function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG="tauri://drag",e.DROP="tauri://drop",e.DROP_OVER="tauri://drop-over",e.DROP_CANCELLED="tauri://drag-cancelled"}(t||(t={})),e.getCurrent=a,e.isRegistered=async function(e){return await r("plugin:deep-link|i_registered",{protocol:e})},e.onOpenUrl=async function(e){const n=await a();return null!=n&&e(n),await i("deep-link://new-url",(n=>{e(n.payload)}))},e.register=async function(e){return await r("plugin:deep-link|register",{protocol:e})},e.unregister=async function(e){return await r("plugin:deep-link|unregister",{protocol:e})},e}({});Object.defineProperty(window.__TAURI__,"deepLink",{value:__TAURI_PLUGIN_DEEPLINK__})}
+3 -3
View File
@@ -6,7 +6,7 @@
mod config;
use config::{AssociatedDomain, Config};
const COMMANDS: &[&str] = &["get_current"];
const COMMANDS: &[&str] = &["get_current", "register", "unregister", "is_registered"];
// TODO: Consider using activity-alias in case users may have multiple activities in their app.
// TODO: Do we want to support the other path* configs too?
@@ -48,7 +48,7 @@ fn main() {
"DEEP LINK PLUGIN",
"activity",
config
.domains
.mobile
.iter()
.map(intent_filter)
.collect::<Vec<_>>()
@@ -62,7 +62,7 @@ fn main() {
entitlements.insert(
"com.apple.developer.associated-domains".into(),
config
.domains
.mobile
.into_iter()
.map(|d| format!("applinks:{}", d.host).into())
.collect::<Vec<_>>()
@@ -1,5 +1,11 @@
# Changelog
## \[2.0.0-beta.4]
### Dependencies
- Upgraded to `deep-link-js@2.0.0-beta.4`
## \[2.0.0-beta.3]
### Dependencies
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "deep-link-example",
"private": true,
"version": "2.0.0-beta.3",
"version": "2.0.0-beta.4",
"type": "module",
"scripts": {
"dev": "vite",
@@ -11,10 +11,10 @@
},
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.11",
"@tauri-apps/plugin-deep-link": "2.0.0-beta.3"
"@tauri-apps/plugin-deep-link": "2.0.0-beta.4"
},
"devDependencies": {
"@tauri-apps/cli": "2.0.0-beta.15",
"@tauri-apps/cli": "2.0.0-beta.16",
"internal-ip": "^8.0.0",
"typescript": "^5.2.2",
"vite": "^5.0.13"
@@ -28,15 +28,13 @@
"hello": "world"
},
"deep-link": {
"domains": [
{
"host": "fabianlars.de",
"pathPrefix": ["/intent"]
},
{
"host": "tauri.app"
}
]
"mobile": [
{ "host": "fabianlars.de", "pathPrefix": ["/intent"] },
{ "host": "tauri.app" }
],
"desktop": {
"schemes": ["fabianlars", "my-tauri-app"]
}
}
},
"bundle": {
+1 -1
View File
@@ -3,7 +3,7 @@
"target": "ESNext",
"module": "ESNext",
"lib": ["ESNext", "DOM"],
"moduleResolution": "Node",
"moduleResolution": "bundler",
"strict": true,
"sourceMap": true,
"resolveJsonModule": true,
+86 -3
View File
@@ -5,12 +5,95 @@
import { invoke } from "@tauri-apps/api/core";
import { type UnlistenFn, listen } from "@tauri-apps/api/event";
/**
* Get the current URLs that triggered the deep link. Use this on app load to check whether your app was started via a deep link.
*
* @example
* ```typescript
* import { getCurrent } from '@tauri-apps/plugin-deep-link';
* const urls = await getCurrent();
* ```
*
* #### - **Windows / Linux**: Unsupported.
*
* @since 2.0.0
*/
export async function getCurrent(): Promise<string[] | null> {
return await invoke<string[] | null>("plugin:deep-link|get_current");
// return await invoke("plugin:deep-link|get_current");
return await invoke("plugin:deep-link|get_current");
}
/**
* Register the app as the default handler for the specified protocol.
*
* @param protocol The name of the protocol without `://`. For example, if you want your app to handle `tauri://` links, call this method with `tauri` as the protocol.
*
* @example
* ```typescript
* import { register } from '@tauri-apps/plugin-deep-link';
* await register("my-scheme");
* ```
*
* #### - **macOS / Android / iOS**: Unsupported.
*
* @since 2.0.0
*/
export async function register(protocol: string): Promise<null> {
return await invoke("plugin:deep-link|register", { protocol });
}
/**
* Unregister the app as the default handler for the specified protocol.
*
* @param protocol The name of the protocol without `://`.
*
* @example
* ```typescript
* import { unregister } from '@tauri-apps/plugin-deep-link';
* await unregister("my-scheme");
* ```
*
* #### - **macOS / Linux / Android / iOS**: Unsupported.
*
* @since 2.0.0
*/
export async function unregister(protocol: string): Promise<null> {
return await invoke("plugin:deep-link|unregister", { protocol });
}
/**
* Check whether the app is the default handler for the specified protocol.
*
* @param protocol The name of the protocol without `://`.
*
* @example
* ```typescript
* import { isRegistered } from '@tauri-apps/plugin-deep-link';
* await isRegistered("my-scheme");
* ```
*
* #### - **macOS / Android / iOS**: Unsupported, always returns `true`.
*
* @since 2.0.0
*/
export async function isRegistered(protocol: string): Promise<boolean> {
return await invoke("plugin:deep-link|i_registered", { protocol });
}
/**
* Helper function for the `deep-link://new-url` event to run a function each time the protocol is triggered while the app is running. Use `getCurrent` on app load to check whether your app was started via a deep link.
*
* @param protocol The name of the protocol without `://`.
*
* @example
* ```typescript
* import { onOpenUrl } from '@tauri-apps/plugin-deep-link';
* await onOpenUrl((urls) => { console.log(urls) });
* ```
*
* #### - **Windows / Linux**: Unsupported, the OS will spawn a new app instance passing the URL as a CLI argument.
*
* @since 2.0.0
*/
export async function onOpenUrl(
handler: (urls: string[]) => void,
): Promise<UnlistenFn> {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-deep-link",
"version": "2.0.0-beta.3",
"version": "2.0.0-beta.4",
"description": "Set your Tauri application as the default handler for an URL",
"license": "MIT or APACHE-2.0",
"authors": [
@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-is-registered"
description = "Enables the is_registered command without any pre-configured scope."
commands.allow = ["is_registered"]
[[permission]]
identifier = "deny-is-registered"
description = "Denies the is_registered command without any pre-configured scope."
commands.deny = ["is_registered"]
@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-register"
description = "Enables the register command without any pre-configured scope."
commands.allow = ["register"]
[[permission]]
identifier = "deny-register"
description = "Denies the register command without any pre-configured scope."
commands.deny = ["register"]
@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-unregister"
description = "Enables the unregister command without any pre-configured scope."
commands.allow = ["unregister"]
[[permission]]
identifier = "deny-unregister"
description = "Denies the unregister command without any pre-configured scope."
commands.deny = ["unregister"]
@@ -2,4 +2,10 @@
|------|-----|
|`allow-get-current`|Enables the get_current command without any pre-configured scope.|
|`deny-get-current`|Denies the get_current command without any pre-configured scope.|
|`allow-is-registered`|Enables the is_registered command without any pre-configured scope.|
|`deny-is-registered`|Denies the is_registered command without any pre-configured scope.|
|`allow-register`|Enables the register command without any pre-configured scope.|
|`deny-register`|Denies the register command without any pre-configured scope.|
|`allow-unregister`|Enables the unregister command without any pre-configured scope.|
|`deny-unregister`|Denies the unregister command without any pre-configured scope.|
|`default`|Allows reading the opened deep link via the get_current command|
@@ -308,6 +308,48 @@
"deny-get-current"
]
},
{
"description": "allow-is-registered -> Enables the is_registered command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-is-registered"
]
},
{
"description": "deny-is-registered -> Denies the is_registered command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-is-registered"
]
},
{
"description": "allow-register -> Enables the register command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-register"
]
},
{
"description": "deny-register -> Denies the register command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-register"
]
},
{
"description": "allow-unregister -> Enables the unregister command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-unregister"
]
},
{
"description": "deny-unregister -> Denies the unregister command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-unregister"
]
},
{
"description": "default -> Allows reading the opened deep link via the get_current command",
"type": "string",
+30
View File
@@ -14,3 +14,33 @@ pub(crate) async fn get_current<R: Runtime>(
) -> Result<Option<Vec<url::Url>>> {
deep_link.get_current()
}
#[command]
pub(crate) async fn register<R: Runtime>(
_app: AppHandle<R>,
_window: Window<R>,
deep_link: State<'_, DeepLink<R>>,
protocol: String,
) -> Result<()> {
deep_link.register(protocol)
}
#[command]
pub(crate) async fn unregister<R: Runtime>(
_app: AppHandle<R>,
_window: Window<R>,
deep_link: State<'_, DeepLink<R>>,
protocol: String,
) -> Result<()> {
deep_link.unregister(protocol)
}
#[command]
pub(crate) async fn is_registered<R: Runtime>(
_app: AppHandle<R>,
_window: Window<R>,
deep_link: State<'_, DeepLink<R>>,
protocol: String,
) -> Result<bool> {
deep_link.is_registered(protocol)
}
+13 -3
View File
@@ -4,9 +4,8 @@
// This module is also imported in build.rs!
#![allow(dead_code)]
use serde::{Deserialize, Deserializer};
use tauri_utils::config::DeepLinkProtocol;
#[derive(Deserialize)]
pub struct AssociatedDomain {
@@ -32,5 +31,16 @@ where
#[derive(Deserialize)]
pub struct Config {
pub domains: Vec<AssociatedDomain>,
/// Mobile requires `https://<host>` urls.
pub mobile: Vec<AssociatedDomain>,
/// Desktop requires urls starting with `<scheme>://`.
/// These urls are also active in dev mode on Android.
pub desktop: DesktopProtocol,
}
#[derive(Deserialize)]
#[serde(untagged)]
pub enum DesktopProtocol {
One(DeepLinkProtocol),
List(Vec<DeepLinkProtocol>),
}
+13
View File
@@ -8,8 +8,21 @@ pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("unsupported platform")]
UnsupportedPlatform,
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Tauri(#[from] tauri::Error),
#[cfg(target_os = "windows")]
#[error(transparent)]
Windows(#[from] windows_result::Error),
#[cfg(target_os = "linux")]
#[error(transparent)]
Ini(#[from] ini::Error),
#[cfg(target_os = "linux")]
#[error(transparent)]
ParseIni(#[from] ini::ParseError),
#[cfg(mobile)]
#[error(transparent)]
PluginInvoke(#[from] tauri::plugin::mobile::PluginInvokeError),
+256 -4
View File
@@ -82,32 +82,279 @@ mod imp {
pub struct DeepLink<R: Runtime>(pub(crate) PluginHandle<R>);
impl<R: Runtime> DeepLink<R> {
/// Get the current URLs that triggered the deep link.
/// Get the current URLs that triggered the deep link. Use this on app load to check whether your app was started via a deep link.
///
/// ## Platform-specific:
///
/// - **Windows / Linux**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
pub fn get_current(&self) -> crate::Result<Option<Vec<url::Url>>> {
self.0
.run_mobile_plugin::<GetCurrentResponse>("getCurrent", ())
.map(|v| v.url.map(|url| vec![url]))
.map_err(Into::into)
}
/// Register the app as the default handler for the specified protocol.
///
/// - `protocol`: The name of the protocol without `://`. For example, if you want your app to handle `tauri://` links, call this method with `tauri` as the protocol.
///
/// ## Platform-specific:
///
/// - **macOS / Android / iOS**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
pub fn register<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<()> {
Err(crate::Error::UnsupportedPlatform)
}
/// Unregister the app as the default handler for the specified protocol.
///
/// - `protocol`: The name of the protocol without `://`.
///
/// ## Platform-specific:
///
/// - **Linux**: Can only unregister the scheme if it was initially registered with [`register`](`Self::register`). May not work on older distros.
/// - **macOS / Android / iOS**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
pub fn unregister<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<()> {
Err(crate::Error::UnsupportedPlatform)
}
/// Check whether the app is the default handler for the specified protocol.
///
/// - `protocol`: The name of the protocol without `://`.
///
/// ## Platform-specific:
///
/// - **macOS / Android / iOS**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
pub fn is_registered<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<bool> {
Err(crate::Error::UnsupportedPlatform)
}
}
}
#[cfg(not(target_os = "android"))]
mod imp {
use std::sync::Mutex;
#[cfg(target_os = "linux")]
use std::{
fs::{create_dir_all, File},
io::Write,
process::Command,
};
#[cfg(target_os = "linux")]
use tauri::Manager;
use tauri::{AppHandle, Runtime};
#[cfg(windows)]
use windows_registry::CURRENT_USER;
/// Access to the deep-link APIs.
pub struct DeepLink<R: Runtime> {
#[allow(dead_code)]
pub(crate) app: AppHandle<R>,
#[allow(dead_code)]
pub(crate) current: Mutex<Option<Vec<url::Url>>>,
}
impl<R: Runtime> DeepLink<R> {
/// Get the current URLs that triggered the deep link.
/// Get the current URLs that triggered the deep link. Use this on app load to check whether your app was started via a deep link.
///
/// ## Platform-specific:
///
/// - **Windows / Linux**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
pub fn get_current(&self) -> crate::Result<Option<Vec<url::Url>>> {
Ok(self.current.lock().unwrap().clone())
#[cfg(not(any(windows, target_os = "linux")))]
return Ok(self.current.lock().unwrap().clone());
#[cfg(any(windows, target_os = "linux"))]
Err(crate::Error::UnsupportedPlatform)
}
/// Register the app as the default handler for the specified protocol.
///
/// - `protocol`: The name of the protocol without `://`. For example, if you want your app to handle `tauri://` links, call this method with `tauri` as the protocol.
///
/// ## Platform-specific:
///
/// - **macOS / Android / iOS**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
pub fn register<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<()> {
#[cfg(windows)]
{
let key_base = format!("Software\\Classes\\{}", _protocol.as_ref());
let exe = dunce::simplified(&tauri::utils::platform::current_exe()?)
.display()
.to_string();
let key_reg = CURRENT_USER.create(&key_base)?;
key_reg.set_string(
"",
&format!("URL:{} protocol", self.app.config().identifier),
)?;
key_reg.set_string("URL Protocol", "")?;
let icon_reg = CURRENT_USER.create(format!("{key_base}\\DefaultIcon"))?;
icon_reg.set_string("", &format!("{},0", &exe))?;
let cmd_reg = CURRENT_USER.create(format!("{key_base}\\shell\\open\\command"))?;
cmd_reg.set_string("", &format!("{} \"%1\"", &exe))?;
Ok(())
}
#[cfg(target_os = "linux")]
{
let bin = tauri::utils::platform::current_exe()?;
let file_name = format!(
"{}-handler.desktop",
bin.file_name().unwrap().to_string_lossy()
);
let appimage = self.app.env().appimage;
let exec = appimage
.clone()
.unwrap_or_else(|| bin.into_os_string())
.to_string_lossy()
.to_string();
let target = self.app.path().data_dir()?.join("applications");
create_dir_all(&target)?;
let target_file = target.join(&file_name);
let mime_type = format!("x-scheme-handler/{};", _protocol.as_ref());
if let Ok(mut desktop_file) = ini::Ini::load_from_file(&target_file) {
if let Some(section) = desktop_file.section_mut(Some("Desktop Entry")) {
if let Some(mimes) = section.remove("MimeType") {
section.append("MimeType", format!("{mimes};{mime_type};"))
} else {
section.append("MimeType", format!("{mime_type};"))
}
desktop_file.write_to_file(&target_file)?;
}
} else {
let mut file = File::create(target_file)?;
file.write_all(
format!(
include_str!("template.desktop"),
name = self
.app
.config()
.product_name
.clone()
.unwrap_or_else(|| file_name.clone()),
exec = exec,
mime_type = mime_type
)
.as_bytes(),
)?;
}
Command::new("update-desktop-database")
.arg(target)
.status()?;
Command::new("xdg-mime")
.args(["default", &file_name, _protocol.as_ref()])
.status()?;
Ok(())
}
#[cfg(not(any(windows, target_os = "linux")))]
Err(crate::Error::UnsupportedPlatform)
}
/// Unregister the app as the default handler for the specified protocol.
///
/// - `protocol`: The name of the protocol without `://`.
///
/// ## Platform-specific:
///
/// - **Linux**: Can only unregister the scheme if it was initially registered with [`register`](`Self::register`). May not work on older distros.
/// - **macOS / Android / iOS**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
pub fn unregister<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<()> {
#[cfg(windows)]
{
CURRENT_USER.remove_tree(format!("Software\\Classes\\{}", _protocol.as_ref()))?;
Ok(())
}
#[cfg(target_os = "linux")]
{
let mimeapps_path = self.app.path().config_dir()?.join("mimeapps.list");
let mut mimeapps = ini::Ini::load_from_file(&mimeapps_path)?;
let file_name = format!(
"{}-handler.desktop",
tauri::utils::platform::current_exe()?
.file_name()
.unwrap()
.to_string_lossy()
);
if let Some(section) = mimeapps.section_mut(Some("Default Applications")) {
let scheme = format!("x-scheme-handler/{}", _protocol.as_ref());
if section.get(&scheme).unwrap_or_default() == file_name {
section.remove(scheme);
}
}
mimeapps.write_to_file(mimeapps_path)?;
Ok(())
}
#[cfg(not(any(windows, target_os = "linux")))]
Err(crate::Error::UnsupportedPlatform)
}
/// Check whether the app is the default handler for the specified protocol.
///
/// - `protocol`: The name of the protocol without `://`.
///
/// ## Platform-specific:
///
/// - **macOS / Android / iOS**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
pub fn is_registered<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<bool> {
#[cfg(windows)]
{
let cmd_reg = CURRENT_USER.open(format!(
"Software\\Classes\\{}\\shell\\open\\command",
_protocol.as_ref()
))?;
let registered_cmd: String = cmd_reg.get_string("")?;
let exe = dunce::simplified(&tauri::utils::platform::current_exe()?)
.display()
.to_string();
Ok(registered_cmd == format!("{} \"%1\"", &exe))
}
#[cfg(target_os = "linux")]
{
let file_name = format!(
"{}-handler.desktop",
tauri::utils::platform::current_exe()?
.file_name()
.unwrap()
.to_string_lossy()
);
let output = Command::new("xdg-mime")
.args([
"query",
"default",
&format!("x-scheme-handler/{}", _protocol.as_ref()),
])
.output()?;
Ok(String::from_utf8_lossy(&output.stdout).contains(&file_name))
}
#[cfg(not(any(windows, target_os = "linux")))]
Err(crate::Error::UnsupportedPlatform)
}
}
}
@@ -128,7 +375,12 @@ impl<R: Runtime, T: Manager<R>> crate::DeepLinkExt<R> for T {
/// Initializes the plugin.
pub fn init<R: Runtime>() -> TauriPlugin<R, Option<config::Config>> {
Builder::new("deep-link")
.invoke_handler(tauri::generate_handler![commands::get_current])
.invoke_handler(tauri::generate_handler![
commands::get_current,
commands::register,
commands::unregister,
commands::is_registered
])
.setup(|app, api| {
app.manage(init_deep_link(app, api)?);
Ok(())
+7
View File
@@ -0,0 +1,7 @@
[Desktop Entry]
Type=Application
Name={name}
Exec={exec} %u
Terminal=false
MimeType={mime_type}
NoDisplay=true
+13 -9
View File
@@ -58,17 +58,19 @@ fn main() {
#[cfg(desktop)]
{
use tauri::Manager;
use tauri_plugin_global_shortcut::{Code, Modifiers};
use tauri_plugin_global_shortcut::{Code, Modifiers, ShortcutState};
app.handle().plugin(
tauri_plugin_global_shortcut::Builder::new()
.with_shortcuts(["ctrl+d", "alt+space"])?
.with_handler(|app, shortcut| {
if shortcut.matches(Modifiers::CONTROL, Code::KeyD) {
let _ = app.emit("shortcut-event", "Ctrl+D triggered");
}
if shortcut.matches(Modifiers::ALT, Code::Space) {
let _ = app.emit("shortcut-event", "Alt+Space triggered");
.with_handler(|app, shortcut, event| {
if event.state == ShortcutState::Pressed {
if shortcut.matches(Modifiers::CONTROL, Code::KeyD) {
let _ = app.emit("shortcut-event", "Ctrl+D triggered");
}
if shortcut.matches(Modifiers::ALT, Code::Space) {
let _ = app.emit("shortcut-event", "Alt+Space triggered");
}
}
})
.build(),
@@ -86,8 +88,10 @@ Afterwards all the plugin's APIs are available through the JavaScript bindings:
```javascript
import { register } from "@tauri-apps/plugin-global-shortcut";
await register("CommandOrControl+Shift+C", () => {
console.log("Shortcut triggered");
await register("CommandOrControl+Shift+C", (event) => {
if (event.state === "Pressed") {
console.log("Shortcut triggered");
}
});
```
+6 -4
View File
@@ -23,8 +23,10 @@ export type ShortcutHandler = (event: ShortcutEvent) => void;
* @example
* ```typescript
* import { register } from '@tauri-apps/plugin-global-shortcut';
* await register('CommandOrControl+Shift+C', () => {
* console.log('Shortcut triggered');
* await register('CommandOrControl+Shift+C', (event) => {
* if (event.state === "Pressed") {
* console.log('Shortcut triggered');
* }
* });
* ```
*
@@ -51,8 +53,8 @@ async function register(
* @example
* ```typescript
* import { registerAll } from '@tauri-apps/plugin-global-shortcut';
* await registerAll(['CommandOrControl+Shift+C', 'Ctrl+Alt+F12'], (shortcut) => {
* console.log(`Shortcut ${shortcut} triggered`);
* await registerAll(['CommandOrControl+Shift+C', 'Ctrl+Alt+F12'], (event) => {
* console.log(`Shortcut ${event.shortcut} ${event.state}`);
* });
* ```
*
+11 -12
View File
@@ -434,7 +434,7 @@ impl Builder {
TargetKind::Stderr => std::io::stderr().into(),
TargetKind::Folder { path, file_name } => {
if !path.exists() {
fs::create_dir_all(&path).unwrap();
fs::create_dir_all(&path)?;
}
fern::log_file(get_log_file_path(
@@ -450,9 +450,9 @@ impl Builder {
TargetKind::LogDir { .. } => continue,
#[cfg(desktop)]
TargetKind::LogDir { file_name } => {
let path = app_handle.path().app_log_dir().unwrap();
let path = app_handle.path().app_log_dir()?;
if !path.exists() {
fs::create_dir_all(&path).unwrap();
fs::create_dir_all(&path)?;
}
fern::log_file(get_log_file_path(
@@ -474,7 +474,7 @@ impl Builder {
};
let app_handle = app_handle.clone();
tauri::async_runtime::spawn(async move {
app_handle.emit("log://log", payload).unwrap();
let _ = app_handle.emit("log://log", payload);
});
})
}
@@ -511,13 +511,9 @@ fn get_log_file_path(
file_name,
timezone_strategy
.get_now()
.format(
&time::format_description::parse(
"[year]-[month]-[day]_[hour]-[minute]-[second]"
)
.unwrap()
)
.unwrap(),
.format(&time::format_description::parse(
"[year]-[month]-[day]_[hour]-[minute]-[second]"
)?)?,
));
if to.is_file() {
// designated rotated log file name already exists
@@ -525,7 +521,10 @@ fn get_log_file_path(
let mut to_bak = to.clone();
to_bak.set_file_name(format!(
"{}.bak",
to_bak.file_name().unwrap().to_string_lossy()
to_bak
.file_name()
.map(|f| f.to_string_lossy())
.unwrap_or_default()
));
fs::rename(&to, to_bak)?;
}
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.0.0-beta.5]
- [`d9de5b19`](https://github.com/tauri-apps/plugins-workspace/commit/d9de5b19d1e950c06f0915ae92a862acb266d108)([#1283](https://github.com/tauri-apps/plugins-workspace/pull/1283)) Implement `WindowExt` for `WebviewWindow`.
## \[2.0.0-beta.3]
- [`bd1ed590`](https://github.com/tauri-apps/plugins-workspace/commit/bd1ed5903ffcce5500310dac1e59e8c67674ef1e)([#1237](https://github.com/tauri-apps/plugins-workspace/pull/1237)) Update to tauri beta.17.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-positioner"
version = "2.0.0-beta.4"
version = "2.0.0-beta.5"
description = "Position your windows at well-known locations."
authors = { workspace = true }
license = { workspace = true }
+6 -1
View File
@@ -8,7 +8,7 @@ use crate::Tray;
use serde_repr::Deserialize_repr;
#[cfg(feature = "tray-icon")]
use tauri::Manager;
use tauri::{PhysicalPosition, PhysicalSize, Result, Runtime, Window};
use tauri::{PhysicalPosition, PhysicalSize, Result, Runtime, WebviewWindow, Window};
/// Well known window positions.
#[derive(Debug, Deserialize_repr)]
@@ -45,6 +45,11 @@ pub trait WindowExt {
fn move_window(&self, position: Position) -> Result<()>;
}
impl<R: Runtime> WindowExt for WebviewWindow<R> {
fn move_window(&self, pos: Position) -> Result<()> {
self.as_ref().window().move_window(pos)
}
}
impl<R: Runtime> WindowExt for Window<R> {
fn move_window(&self, pos: Position) -> Result<()> {
use Position::*;
+9
View File
@@ -1,5 +1,10 @@
# Changelog
## \[2.0.0-beta.4]
- [`eb1679b9`](https://github.com/tauri-apps/plugins-workspace/commit/eb1679b99780e5d2b867f5649a1ccc2f3f70ab56)([#1299](https://github.com/tauri-apps/plugins-workspace/pull/1299)) Fix `Command.execute` API including extra new lines.
- [`eb1679b9`](https://github.com/tauri-apps/plugins-workspace/commit/eb1679b99780e5d2b867f5649a1ccc2f3f70ab56)([#1299](https://github.com/tauri-apps/plugins-workspace/pull/1299)) Improve the speed of the JS `Command.execute` API
## \[2.0.0-beta.3]
- [`bd1ed590`](https://github.com/tauri-apps/plugins-workspace/commit/bd1ed5903ffcce5500310dac1e59e8c67674ef1e)([#1237](https://github.com/tauri-apps/plugins-workspace/pull/1237)) Update to tauri beta.17.
@@ -66,3 +71,7 @@
717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
+2 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-shell"
version = "2.0.0-beta.4"
version = "2.0.0-beta.5"
description = "Access the system shell. Allows you to spawn child processes and manage files and URLs using their default application."
edition = { workspace = true }
authors = { workspace = true }
@@ -23,6 +23,7 @@ serde = { workspace = true }
schemars = { workspace = true }
serde_json = { workspace = true }
tauri = { workspace = true }
tokio = { version = "1", features = [ "time" ] }
log = { workspace = true }
thiserror = { workspace = true }
shared_child = "1"
+1 -1
View File
@@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_SHELL__=function(t){"use strict";function e(t,e,s,n){if("a"===s&&!n)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!n:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===s?n:"a"===s?n.call(t):n?n.value:e.get(t)}function s(t,e,s,n,i){if("function"==typeof e?t!==e||!i:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(t,s),s}var n,i,r;"function"==typeof SuppressedError&&SuppressedError;class o{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,n.set(this,(()=>{})),i.set(this,0),r.set(this,{}),this.id=function(t,e=!1){return window.__TAURI_INTERNALS__.transformCallback(t,e)}((({message:t,id:o})=>{if(o===e(this,i,"f")){s(this,i,o+1),e(this,n,"f").call(this,t);const a=Object.keys(e(this,r,"f"));if(a.length>0){let t=o+1;for(const s of a.sort()){if(parseInt(s)!==t)break;{const i=e(this,r,"f")[s];delete e(this,r,"f")[s],e(this,n,"f").call(this,i),t+=1}}s(this,i,t)}}else e(this,r,"f")[o.toString()]=t}))}set onmessage(t){s(this,n,t)}get onmessage(){return e(this,n,"f")}toJSON(){return`__CHANNEL__:${this.id}`}}async function a(t,e={},s){return window.__TAURI_INTERNALS__.invoke(t,e,s)}n=new WeakMap,i=new WeakMap,r=new WeakMap;class h{constructor(){this.eventListeners=Object.create(null)}addListener(t,e){return this.on(t,e)}removeListener(t,e){return this.off(t,e)}on(t,e){return t in this.eventListeners?this.eventListeners[t].push(e):this.eventListeners[t]=[e],this}once(t,e){const s=n=>{this.removeListener(t,s),e(n)};return this.addListener(t,s)}off(t,e){return t in this.eventListeners&&(this.eventListeners[t]=this.eventListeners[t].filter((t=>t!==e))),this}removeAllListeners(t){return t?delete this.eventListeners[t]:this.eventListeners=Object.create(null),this}emit(t,e){if(t in this.eventListeners){const s=this.eventListeners[t];for(const t of s)t(e);return!0}return!1}listenerCount(t){return t in this.eventListeners?this.eventListeners[t].length:0}prependListener(t,e){return t in this.eventListeners?this.eventListeners[t].unshift(e):this.eventListeners[t]=[e],this}prependOnceListener(t,e){const s=n=>{this.removeListener(t,s),e(n)};return this.prependListener(t,s)}}class c{constructor(t){this.pid=t}async write(t){await a("plugin:shell|stdin_write",{pid:this.pid,buffer:"string"==typeof t?t:Array.from(t)})}async kill(){await a("plugin:shell|kill",{cmd:"killChild",pid:this.pid})}}class u extends h{constructor(t,e=[],s){super(),this.stdout=new h,this.stderr=new h,this.program=t,this.args="string"==typeof e?[e]:e,this.options=s??{}}static create(t,e=[],s){return new u(t,e,s)}static sidecar(t,e=[],s){const n=new u(t,e,s);return n.options.sidecar=!0,n}async spawn(){return await async function(t,e,s=[],n){"object"==typeof s&&Object.freeze(s);const i=new o;return i.onmessage=t,await a("plugin:shell|execute",{program:e,args:s,options:n,onEvent:i})}((t=>{switch(t.event){case"Error":this.emit("error",t.payload);break;case"Terminated":this.emit("close",t.payload);break;case"Stdout":this.stdout.emit("data",t.payload);break;case"Stderr":this.stderr.emit("data",t.payload)}}),this.program,this.args,this.options).then((t=>new c(t)))}async execute(){return await new Promise(((t,e)=>{this.on("error",e);const s=[],n=[];this.stdout.on("data",(t=>{s.push(t)})),this.stderr.on("data",(t=>{n.push(t)})),this.on("close",(e=>{t({code:e.code,signal:e.signal,stdout:this.collectOutput(s),stderr:this.collectOutput(n)})})),this.spawn().catch(e)}))}collectOutput(t){return"raw"===this.options.encoding?t.reduce(((t,e)=>new Uint8Array([...t,...e,10])),new Uint8Array):t.join("\n")}}return t.Child=c,t.Command=u,t.EventEmitter=h,t.open=async function(t,e){await a("plugin:shell|open",{path:t,with:e})},t}({});Object.defineProperty(window.__TAURI__,"shell",{value:__TAURI_PLUGIN_SHELL__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_SHELL__=function(e){"use strict";function t(e,t,s,n){if("a"===s&&!n)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!n:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===s?n:"a"===s?n.call(e):n?n.value:t.get(e)}function s(e,t,s,n,i){if("function"==typeof t?e!==t||!i:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return t.set(e,s),s}var n,i,r;"function"==typeof SuppressedError&&SuppressedError;class o{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,n.set(this,(()=>{})),i.set(this,0),r.set(this,{}),this.id=function(e,t=!1){return window.__TAURI_INTERNALS__.transformCallback(e,t)}((({message:e,id:o})=>{if(o===t(this,i,"f")){s(this,i,o+1),t(this,n,"f").call(this,e);const a=Object.keys(t(this,r,"f"));if(a.length>0){let e=o+1;for(const s of a.sort()){if(parseInt(s)!==e)break;{const i=t(this,r,"f")[s];delete t(this,r,"f")[s],t(this,n,"f").call(this,i),e+=1}}s(this,i,e)}}else t(this,r,"f")[o.toString()]=e}))}set onmessage(e){s(this,n,e)}get onmessage(){return t(this,n,"f")}toJSON(){return`__CHANNEL__:${this.id}`}}async function a(e,t={},s){return window.__TAURI_INTERNALS__.invoke(e,t,s)}n=new WeakMap,i=new WeakMap,r=new WeakMap;class h{constructor(){this.eventListeners=Object.create(null)}addListener(e,t){return this.on(e,t)}removeListener(e,t){return this.off(e,t)}on(e,t){return e in this.eventListeners?this.eventListeners[e].push(t):this.eventListeners[e]=[t],this}once(e,t){const s=n=>{this.removeListener(e,s),t(n)};return this.addListener(e,s)}off(e,t){return e in this.eventListeners&&(this.eventListeners[e]=this.eventListeners[e].filter((e=>e!==t))),this}removeAllListeners(e){return e?delete this.eventListeners[e]:this.eventListeners=Object.create(null),this}emit(e,t){if(e in this.eventListeners){const s=this.eventListeners[e];for(const e of s)e(t);return!0}return!1}listenerCount(e){return e in this.eventListeners?this.eventListeners[e].length:0}prependListener(e,t){return e in this.eventListeners?this.eventListeners[e].unshift(t):this.eventListeners[e]=[t],this}prependOnceListener(e,t){const s=n=>{this.removeListener(e,s),t(n)};return this.prependListener(e,s)}}class c{constructor(e){this.pid=e}async write(e){await a("plugin:shell|stdin_write",{pid:this.pid,buffer:"string"==typeof e?e:Array.from(e)})}async kill(){await a("plugin:shell|kill",{cmd:"killChild",pid:this.pid})}}class l extends h{constructor(e,t=[],s){super(),this.stdout=new h,this.stderr=new h,this.program=e,this.args="string"==typeof t?[t]:t,this.options=s??{}}static create(e,t=[],s){return new l(e,t,s)}static sidecar(e,t=[],s){const n=new l(e,t,s);return n.options.sidecar=!0,n}async spawn(){const e=this.program,t=this.args,s=this.options;"object"==typeof t&&Object.freeze(t);const n=new o;return n.onmessage=e=>{switch(e.event){case"Error":this.emit("error",e.payload);break;case"Terminated":this.emit("close",e.payload);break;case"Stdout":this.stdout.emit("data",e.payload);break;case"Stderr":this.stderr.emit("data",e.payload)}},await a("plugin:shell|spawn",{program:e,args:t,options:s,onEvent:n}).then((e=>new c(e)))}async execute(){const e=this.program,t=this.args,s=this.options;return"object"==typeof t&&Object.freeze(t),await a("plugin:shell|execute",{program:e,args:t,options:s})}}return e.Child=c,e.Command=l,e.EventEmitter=h,e.open=async function(e,t){await a("plugin:shell|open",{path:e,with:t})},e}({});Object.defineProperty(window.__TAURI__,"shell",{value:__TAURI_PLUGIN_SHELL__})}
+1 -1
View File
@@ -5,7 +5,7 @@
#[path = "src/scope_entry.rs"]
mod scope_entry;
const COMMANDS: &[&str] = &["execute", "stdin_write", "kill", "open"];
const COMMANDS: &[&str] = &["execute", "spawn", "stdin_write", "kill", "open"];
fn main() {
tauri_plugin::Builder::new(COMMANDS)
+43 -86
View File
@@ -99,39 +99,6 @@ interface ChildProcess<O extends IOPayload> {
stderr: O;
}
/**
* Spawns a process.
*
* @ignore
* @param program The name of the scoped command.
* @param onEventHandler Event handler.
* @param args Program arguments.
* @param options Configuration for the process spawn.
* @returns A promise resolving to the process id.
*
* @since 2.0.0
*/
async function execute<O extends IOPayload>(
onEventHandler: (event: CommandEvent<O>) => void,
program: string,
args: string | string[] = [],
options?: InternalSpawnOptions,
): Promise<number> {
if (typeof args === "object") {
Object.freeze(args);
}
const onEvent = new Channel<CommandEvent<O>>();
onEvent.onmessage = onEventHandler;
return await invoke<number>("plugin:shell|execute", {
program,
args,
options,
onEvent,
});
}
/**
* @since 2.0.0
*/
@@ -513,27 +480,38 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
* @since 2.0.0
*/
async spawn(): Promise<Child> {
return await execute<O>(
(event) => {
switch (event.event) {
case "Error":
this.emit("error", event.payload);
break;
case "Terminated":
this.emit("close", event.payload);
break;
case "Stdout":
this.stdout.emit("data", event.payload);
break;
case "Stderr":
this.stderr.emit("data", event.payload);
break;
}
},
this.program,
this.args,
this.options,
).then((pid) => new Child(pid));
const program = this.program;
const args = this.args;
const options = this.options;
if (typeof args === "object") {
Object.freeze(args);
}
const onEvent = new Channel<CommandEvent<O>>();
onEvent.onmessage = (event) => {
switch (event.event) {
case "Error":
this.emit("error", event.payload);
break;
case "Terminated":
this.emit("close", event.payload);
break;
case "Stdout":
this.stdout.emit("data", event.payload);
break;
case "Stderr":
this.stderr.emit("data", event.payload);
break;
}
};
return await invoke<number>("plugin:shell|spawn", {
program,
args,
options,
onEvent,
}).then((pid) => new Child(pid));
}
/**
@@ -553,40 +531,19 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
* @since 2.0.0
*/
async execute(): Promise<ChildProcess<O>> {
return await new Promise((resolve, reject) => {
this.on("error", reject);
const program = this.program;
const args = this.args;
const options = this.options;
const stdout: O[] = [];
const stderr: O[] = [];
this.stdout.on("data", (line: O) => {
stdout.push(line);
});
this.stderr.on("data", (line: O) => {
stderr.push(line);
});
this.on("close", (payload: TerminatedPayload) => {
resolve({
code: payload.code,
signal: payload.signal,
stdout: this.collectOutput(stdout) as O,
stderr: this.collectOutput(stderr) as O,
});
});
this.spawn().catch(reject);
});
}
/** @ignore */
private collectOutput(events: O[]): string | Uint8Array {
if (this.options.encoding === "raw") {
return events.reduce<Uint8Array>((p, c) => {
return new Uint8Array([...p, ...(c as Uint8Array), 10]);
}, new Uint8Array());
} else {
return events.join("\n");
if (typeof args === "object") {
Object.freeze(args);
}
return await invoke<ChildProcess<O>>("plugin:shell|execute", {
program,
args,
options,
});
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-shell",
"version": "2.0.0-beta.3",
"version": "2.0.0-beta.4",
"license": "MIT or APACHE-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-spawn"
description = "Enables the spawn command without any pre-configured scope."
commands.allow = ["spawn"]
[[permission]]
identifier = "deny-spawn"
description = "Denies the spawn command without any pre-configured scope."
commands.deny = ["spawn"]
@@ -6,5 +6,7 @@
|`deny-kill`|Denies the kill command without any pre-configured scope.|
|`allow-open`|Enables the open command without any pre-configured scope.|
|`deny-open`|Denies the open command without any pre-configured scope.|
|`allow-spawn`|Enables the spawn command without any pre-configured scope.|
|`deny-spawn`|Denies the spawn command without any pre-configured scope.|
|`allow-stdin-write`|Enables the stdin_write command without any pre-configured scope.|
|`deny-stdin-write`|Denies the stdin_write command without any pre-configured scope.|
@@ -336,6 +336,20 @@
"deny-open"
]
},
{
"description": "allow-spawn -> Enables the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-spawn"
]
},
{
"description": "deny-spawn -> Denies the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-spawn"
]
},
{
"description": "allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.",
"type": "string",
+100 -9
View File
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use std::{collections::HashMap, path::PathBuf, string::FromUtf8Error};
use std::{collections::HashMap, future::Future, path::PathBuf, pin::Pin, string::FromUtf8Error};
use encoding_rs::Encoding;
use serde::{Deserialize, Serialize};
@@ -94,18 +94,15 @@ fn default_env() -> Option<HashMap<String, String>> {
Some(HashMap::default())
}
#[allow(clippy::too_many_arguments)]
#[tauri::command]
pub fn execute<R: Runtime>(
#[inline(always)]
fn prepare_cmd<R: Runtime>(
window: Window<R>,
shell: State<'_, Shell<R>>,
program: String,
args: ExecuteArgs,
on_event: Channel,
options: CommandOptions,
command_scope: CommandScope<crate::scope::ScopeAllowedCommand>,
global_scope: GlobalScope<crate::scope::ScopeAllowedCommand>,
) -> crate::Result<ChildId> {
) -> crate::Result<(crate::process::Command, EncodingWrapper)> {
let scope = crate::scope::ShellScope {
scopes: command_scope
.allows()
@@ -151,10 +148,14 @@ pub fn execute<R: Runtime>(
} else {
command = command.env_clear();
}
let encoding = match options.encoding {
Option::None => EncodingWrapper::Text(None),
Some(encoding) => match encoding.as_str() {
"raw" => EncodingWrapper::Raw,
"raw" => {
command = command.set_raw_out(true);
EncodingWrapper::Raw
}
_ => {
if let Some(text_encoding) = Encoding::for_label(encoding.as_bytes()) {
EncodingWrapper::Text(Some(text_encoding))
@@ -165,6 +166,82 @@ pub fn execute<R: Runtime>(
},
};
Ok((command, encoding))
}
#[derive(Serialize)]
enum Output {
String(String),
Raw(Vec<u8>),
}
#[derive(Serialize)]
pub struct ChildProcessReturn {
code: Option<i32>,
signal: Option<i32>,
#[serde(flatten)]
stdout: Output,
#[serde(flatten)]
stderr: Output,
}
#[allow(clippy::too_many_arguments)]
#[tauri::command]
pub fn execute<R: Runtime>(
window: Window<R>,
program: String,
args: ExecuteArgs,
options: CommandOptions,
command_scope: CommandScope<crate::scope::ScopeAllowedCommand>,
global_scope: GlobalScope<crate::scope::ScopeAllowedCommand>,
) -> crate::Result<ChildProcessReturn> {
let (command, encoding) =
prepare_cmd(window, program, args, options, command_scope, global_scope)?;
let mut command: std::process::Command = command.into();
let output = command.output()?;
let (stdout, stderr) = match encoding {
EncodingWrapper::Text(Some(encoding)) => (
Output::String(encoding.decode_with_bom_removal(&output.stdout).0.into()),
Output::String(encoding.decode_with_bom_removal(&output.stderr).0.into()),
),
EncodingWrapper::Text(None) => (
Output::String(String::from_utf8(output.stdout)?),
Output::String(String::from_utf8(output.stderr)?),
),
EncodingWrapper::Raw => (Output::Raw(output.stdout), Output::Raw(output.stderr)),
};
#[cfg(unix)]
use std::os::unix::process::ExitStatusExt;
Ok(ChildProcessReturn {
code: output.status.code(),
#[cfg(windows)]
signal: None,
#[cfg(unix)]
signal: output.status.signal(),
stdout,
stderr,
})
}
#[allow(clippy::too_many_arguments)]
#[tauri::command]
pub fn spawn<R: Runtime>(
window: Window<R>,
shell: State<'_, Shell<R>>,
program: String,
args: ExecuteArgs,
on_event: Channel,
options: CommandOptions,
command_scope: CommandScope<crate::scope::ScopeAllowedCommand>,
global_scope: GlobalScope<crate::scope::ScopeAllowedCommand>,
) -> crate::Result<ChildId> {
let (command, encoding) =
prepare_cmd(window, program, args, options, command_scope, global_scope)?;
let (mut rx, child) = command.spawn()?;
let pid = child.pid();
@@ -177,7 +254,21 @@ pub fn execute<R: Runtime>(
children.lock().unwrap().remove(&pid);
};
let js_event = JSCommandEvent::new(event, encoding);
let _ = on_event.send(&js_event);
if on_event.send(&js_event).is_err() {
fn send<'a>(
on_event: &'a Channel,
js_event: &'a JSCommandEvent,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
tokio::time::sleep(std::time::Duration::from_millis(15)).await;
if on_event.send(js_event).is_err() {
send(on_event, js_event).await;
}
})
}
send(&on_event, &js_event).await;
}
}
});
+3
View File
@@ -27,6 +27,9 @@ pub enum Error {
/// JSON error.
#[error(transparent)]
Json(#[from] serde_json::Error),
/// Utf8 error.
#[error(transparent)]
Utf8(#[from] std::string::FromUtf8Error),
}
impl Serialize for Error {
+1
View File
@@ -81,6 +81,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R, Option<config::Config>> {
.js_init_script(include_str!("init-iife.js").to_string())
.invoke_handler(tauri::generate_handler![
commands::execute,
commands::spawn,
commands::stdin_write,
commands::kill,
commands::open
+89 -33
View File
@@ -4,7 +4,7 @@
use std::{
ffi::OsStr,
io::{BufReader, Write},
io::{BufRead, BufReader, Write},
path::{Path, PathBuf},
process::{Command as StdCommand, Stdio},
sync::{Arc, RwLock},
@@ -41,11 +41,13 @@ pub struct TerminatedPayload {
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum CommandEvent {
/// Stderr bytes until a newline (\n) or carriage return (\r) is found.
/// If configured for raw output, all bytes written to stderr.
/// Otherwise, bytes until a newline (\n) or carriage return (\r) is found.
Stderr(Vec<u8>),
/// Stdout bytes until a newline (\n) or carriage return (\r) is found.
/// If configured for raw output, all bytes written to stdout.
/// Otherwise, bytes until a newline (\n) or carriage return (\r) is found.
Stdout(Vec<u8>),
/// An error happened waiting for the command to finish or converting the stdout/stderr bytes to an UTF-8 string.
/// An error happened waiting for the command to finish or converting the stdout/stderr bytes to a UTF-8 string.
Error(String),
/// Command process terminated.
Terminated(TerminatedPayload),
@@ -53,7 +55,10 @@ pub enum CommandEvent {
/// The type to spawn commands.
#[derive(Debug)]
pub struct Command(StdCommand);
pub struct Command {
cmd: StdCommand,
raw_out: bool,
}
/// Spawned child process.
#[derive(Debug)]
@@ -122,7 +127,7 @@ fn relative_command_path(command: &Path) -> crate::Result<PathBuf> {
impl From<Command> for StdCommand {
fn from(cmd: Command) -> StdCommand {
cmd.0
cmd.cmd
}
}
@@ -136,7 +141,10 @@ impl Command {
#[cfg(windows)]
command.creation_flags(CREATE_NO_WINDOW);
Self(command)
Self {
cmd: command,
raw_out: false,
}
}
pub(crate) fn new_sidecar<S: AsRef<Path>>(program: S) -> crate::Result<Self> {
@@ -146,7 +154,7 @@ impl Command {
/// Appends an argument to the command.
#[must_use]
pub fn arg<S: AsRef<OsStr>>(mut self, arg: S) -> Self {
self.0.arg(arg);
self.cmd.arg(arg);
self
}
@@ -157,14 +165,14 @@ impl Command {
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
self.0.args(args);
self.cmd.args(args);
self
}
/// Clears the entire environment map for the child process.
#[must_use]
pub fn env_clear(mut self) -> Self {
self.0.env_clear();
self.cmd.env_clear();
self
}
@@ -175,7 +183,7 @@ impl Command {
K: AsRef<OsStr>,
V: AsRef<OsStr>,
{
self.0.env(key, value);
self.cmd.env(key, value);
self
}
@@ -187,14 +195,20 @@ impl Command {
K: AsRef<OsStr>,
V: AsRef<OsStr>,
{
self.0.envs(envs);
self.cmd.envs(envs);
self
}
/// Sets the working directory for the child process.
#[must_use]
pub fn current_dir<P: AsRef<Path>>(mut self, current_dir: P) -> Self {
self.0.current_dir(current_dir);
self.cmd.current_dir(current_dir);
self
}
/// Configures the reader to output bytes from the child process exactly as received
pub fn set_raw_out(mut self, raw_out: bool) -> Self {
self.raw_out = raw_out;
self
}
@@ -229,6 +243,7 @@ impl Command {
/// });
/// ```
pub fn spawn(self) -> crate::Result<(Receiver<CommandEvent>, CommandChild)> {
let raw = self.raw_out;
let mut command: StdCommand = self.into();
let (stdout_reader, stdout_writer) = pipe()?;
let (stderr_reader, stderr_writer) = pipe()?;
@@ -249,12 +264,14 @@ impl Command {
guard.clone(),
stdout_reader,
CommandEvent::Stdout,
raw,
);
spawn_pipe_reader(
tx.clone(),
guard.clone(),
stderr_reader,
CommandEvent::Stderr,
raw,
);
spawn(move || {
@@ -359,35 +376,74 @@ impl Command {
}
}
fn read_raw_bytes<F: Fn(Vec<u8>) -> CommandEvent + Send + Copy + 'static>(
mut reader: BufReader<PipeReader>,
tx: Sender<CommandEvent>,
wrapper: F,
) {
loop {
let result = reader.fill_buf();
match result {
Ok(buf) => {
let length = buf.len();
if length == 0 {
break;
}
let tx_ = tx.clone();
let _ = block_on_task(async move { tx_.send(wrapper(buf.to_vec())).await });
reader.consume(length);
}
Err(e) => {
let tx_ = tx.clone();
let _ = block_on_task(
async move { tx_.send(CommandEvent::Error(e.to_string())).await },
);
}
}
}
}
fn read_line<F: Fn(Vec<u8>) -> CommandEvent + Send + Copy + 'static>(
mut reader: BufReader<PipeReader>,
tx: Sender<CommandEvent>,
wrapper: F,
) {
loop {
let mut buf = Vec::new();
match tauri::utils::io::read_line(&mut reader, &mut buf) {
Ok(n) => {
if n == 0 {
break;
}
let tx_ = tx.clone();
let _ = block_on_task(async move { tx_.send(wrapper(buf)).await });
}
Err(e) => {
let tx_ = tx.clone();
let _ = block_on_task(
async move { tx_.send(CommandEvent::Error(e.to_string())).await },
);
break;
}
}
}
}
fn spawn_pipe_reader<F: Fn(Vec<u8>) -> CommandEvent + Send + Copy + 'static>(
tx: Sender<CommandEvent>,
guard: Arc<RwLock<()>>,
pipe_reader: PipeReader,
wrapper: F,
raw_out: bool,
) {
spawn(move || {
let _lock = guard.read().unwrap();
let mut reader = BufReader::new(pipe_reader);
let reader = BufReader::new(pipe_reader);
loop {
let mut buf = Vec::new();
match tauri::utils::io::read_line(&mut reader, &mut buf) {
Ok(n) => {
if n == 0 {
break;
}
let tx_ = tx.clone();
let _ = block_on_task(async move { tx_.send(wrapper(buf)).await });
}
Err(e) => {
let tx_ = tx.clone();
let _ =
block_on_task(
async move { tx_.send(CommandEvent::Error(e.to_string())).await },
);
break;
}
}
if raw_out {
read_raw_bytes(reader, tx, wrapper);
} else {
read_line(reader, tx, wrapper);
}
});
}
+44 -44
View File
@@ -9,13 +9,13 @@
"version": "1.0.0",
"license": "MIT",
"devDependencies": {
"@tauri-apps/cli": "2.0.0-beta.15"
"@tauri-apps/cli": "2.0.0-beta.16"
}
},
"node_modules/@tauri-apps/cli": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.0-beta.15.tgz",
"integrity": "sha512-3pCvc54QfsRY+i9B7w3Q5jPAGtf8p+g7N/BamWPeiW6YqDqbHi9rNVI3SzrHkRRNOJnzMW8E5a8G0HziOluZGg==",
"version": "2.0.0-beta.16",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.0-beta.16.tgz",
"integrity": "sha512-ELaPqTekAVfTU4lFf7k/Z422DKXk/uDWi7ppI8TuQOqcXjrxlXMvv/Y1eC2tem9vMeuOIU0Jg53pOhOu0w8JIQ==",
"dev": true,
"bin": {
"tauri": "tauri.js"
@@ -28,22 +28,22 @@
"url": "https://opencollective.com/tauri"
},
"optionalDependencies": {
"@tauri-apps/cli-darwin-arm64": "2.0.0-beta.15",
"@tauri-apps/cli-darwin-x64": "2.0.0-beta.15",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.0.0-beta.15",
"@tauri-apps/cli-linux-arm64-gnu": "2.0.0-beta.15",
"@tauri-apps/cli-linux-arm64-musl": "2.0.0-beta.15",
"@tauri-apps/cli-linux-x64-gnu": "2.0.0-beta.15",
"@tauri-apps/cli-linux-x64-musl": "2.0.0-beta.15",
"@tauri-apps/cli-win32-arm64-msvc": "2.0.0-beta.15",
"@tauri-apps/cli-win32-ia32-msvc": "2.0.0-beta.15",
"@tauri-apps/cli-win32-x64-msvc": "2.0.0-beta.15"
"@tauri-apps/cli-darwin-arm64": "2.0.0-beta.16",
"@tauri-apps/cli-darwin-x64": "2.0.0-beta.16",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.0.0-beta.16",
"@tauri-apps/cli-linux-arm64-gnu": "2.0.0-beta.16",
"@tauri-apps/cli-linux-arm64-musl": "2.0.0-beta.16",
"@tauri-apps/cli-linux-x64-gnu": "2.0.0-beta.16",
"@tauri-apps/cli-linux-x64-musl": "2.0.0-beta.16",
"@tauri-apps/cli-win32-arm64-msvc": "2.0.0-beta.16",
"@tauri-apps/cli-win32-ia32-msvc": "2.0.0-beta.16",
"@tauri-apps/cli-win32-x64-msvc": "2.0.0-beta.16"
}
},
"node_modules/@tauri-apps/cli-darwin-arm64": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.0-beta.15.tgz",
"integrity": "sha512-M4owBLoRdJb2/IK48KOQDU3j5xrjqGxa539rDXMjvaKydBk8x+aLdk3xZNsk/owHTI1GnrQZsPCMQaOgetYHaw==",
"version": "2.0.0-beta.16",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.0-beta.16.tgz",
"integrity": "sha512-5Gif4AvpJmnyLj3HO3AEl1RVrr4ast6mDQiXoLwe75bfWq1pj9VwsS5SuSrUKtB8YBSnnclcJwkqwa6soY/xkg==",
"cpu": [
"arm64"
],
@@ -57,9 +57,9 @@
}
},
"node_modules/@tauri-apps/cli-darwin-x64": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.0-beta.15.tgz",
"integrity": "sha512-ECpatfJdT4xKyFoE7tNEtTUIRxjQ2XSXa0TQkP3g7Kn7H/jRse+7pYe69jASA7shixajatAwmD4bXNT8jYRyNA==",
"version": "2.0.0-beta.16",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.0-beta.16.tgz",
"integrity": "sha512-6Cia8lGSroyoXKvfRI+Dv8Xinr27lptDzGZnd8mT9V0xPg73xcWxPKiTkuxPmLQTrQKVAurfsX3DwwgK8m9kSw==",
"cpu": [
"x64"
],
@@ -73,9 +73,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.0-beta.15.tgz",
"integrity": "sha512-GQz2nnPwIamzDbmmfGWvmmoLthOkOBs0RO5u72KYAa78ZRFTx7S6AovnxJv48Fq+zeGGdDKoD9+ZG2Ue+sCL4w==",
"version": "2.0.0-beta.16",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.0-beta.16.tgz",
"integrity": "sha512-1mQ0flIt0wrX4QLPwd8f1QFsuFjLPQtWuiObK63K0/YZmDS2yzKT6jnGqNCJsSiyXE2/36gKSyWh6OVpX8U7xg==",
"cpu": [
"arm"
],
@@ -89,9 +89,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.0-beta.15.tgz",
"integrity": "sha512-YBIfq0GbmIsWmRy6dVuDv3oMJN7a3R8HGVPMsa1W526AdCxoZDiPOQpSQN4VihJlbebUHxS/HyYF6maCY8uGzA==",
"version": "2.0.0-beta.16",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.0-beta.16.tgz",
"integrity": "sha512-CjgwOvaslvy06m36faZ40noQaBu37gcXtD0HlCgAMofDZz7fUWQJn3xE7r8fegXmY0oMKZ9ah8dgwd5KSk+L+Q==",
"cpu": [
"arm64"
],
@@ -105,9 +105,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.0-beta.15.tgz",
"integrity": "sha512-2ZBXoShz7UfqVGmc85mhwjI6ckdtrk15V69adxt/x+VS68yK6Ddbj+yqlffpeFNL90fZrsVhFoRIDqgkxtwksQ==",
"version": "2.0.0-beta.16",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.0-beta.16.tgz",
"integrity": "sha512-JMtryDJckutFzNpwFgh98o9Z4Vw1pwImYmJIDLpCPSqYIfd+mrBgPZFTaGl11ZsQnllqt4FNXlYR8T+ey7ZpfQ==",
"cpu": [
"arm64"
],
@@ -121,9 +121,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.0-beta.15.tgz",
"integrity": "sha512-cwJqIIdc4Kq9sBl/vYc+Y95iMe+mlTYUj7ZnSn4YAbLKFz432bGg6uBn2qHXFN5jzwXtEOVZiB1zDZ2kveVoAQ==",
"version": "2.0.0-beta.16",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.0-beta.16.tgz",
"integrity": "sha512-3dQGCKsbjaIzk4UM7Jf5FzBJpBJ1OfwBOwkVv2M4O7EDLNZi9brDR+I41eqyFhTabEcHJoLhtURLbD25dJuiug==",
"cpu": [
"x64"
],
@@ -137,9 +137,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-musl": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.0-beta.15.tgz",
"integrity": "sha512-nNuxZ8/qs0vQbdLO2hovskZGxwGn2z4x1QFJuL4xwd6Tryy9vVcznvyZS+t/72dCLoIkY9pKZQq5nYtAHYfTEg==",
"version": "2.0.0-beta.16",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.0-beta.16.tgz",
"integrity": "sha512-t+wdk/VCn8l9y1fhRQPfvZyz3Or7QEPTxXNobbUzbtckFsf/LqTxjaajOBmSGnZpoTDFvwVOmalDaylILxuM5g==",
"cpu": [
"x64"
],
@@ -153,9 +153,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.0-beta.15.tgz",
"integrity": "sha512-DXiXMTE00INjBkTgq1CYduMWgUwQ0NvLw+uXfu8BUupA+aOlv9ODhsGu7bZSaxKx4/glwxNAGZum4kQ0E0AxUg==",
"version": "2.0.0-beta.16",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.0-beta.16.tgz",
"integrity": "sha512-ouP0iiRMTNaKyz6c06LucMR5P585r2XJ3/GlzNWtUfP4EaP8mZAENB0ro9VZl10++7Z658MdWxSAf4+Qmkj0jQ==",
"cpu": [
"arm64"
],
@@ -169,9 +169,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.0-beta.15.tgz",
"integrity": "sha512-ajEQdW2jx2raPp7eDYryJkbBrgI8PIY1dz5ro8FweRrRmbotaUlclsro1kfNMQrfDah8+qfwnRvW3MahOBE5Wg==",
"version": "2.0.0-beta.16",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.0-beta.16.tgz",
"integrity": "sha512-BiBkv3IesPNGXVaampxpB+ub0tz2sGu+6OLzxSm1QTp+2ZSw/qeXi/icvJl5azmOyee4ZWBBiuBzdVY88QH+Vw==",
"cpu": [
"ia32"
],
@@ -185,9 +185,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.0-beta.15.tgz",
"integrity": "sha512-yzsSgoiY0PmFiR5LvVOFr1b7h9l3aLPPQFlDG6+kRMrxCo7x7Pbyh4D5cqiMUuZO0QacwSP38EH6w0F88Y+4OA==",
"version": "2.0.0-beta.16",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.0-beta.16.tgz",
"integrity": "sha512-rrJeC7eAT6diQpnI3aaflhvtKyTryywbhHLG/c1QyPhdxA7Or6nflo5KzWLd6q3GQqKRbvz5dDtxwFn+XLo+rQ==",
"cpu": [
"x64"
],
@@ -9,6 +9,6 @@
"author": "",
"license": "MIT",
"devDependencies": {
"@tauri-apps/cli": "2.0.0-beta.15"
"@tauri-apps/cli": "2.0.0-beta.16"
}
}
@@ -9,7 +9,7 @@
"preview": "vite preview"
},
"devDependencies": {
"@tauri-apps/cli": "2.0.0-beta.15",
"@tauri-apps/cli": "2.0.0-beta.16",
"typescript": "^5.3.3",
"vite": "^5.0.13"
},
+5 -1
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.0.0-beta.7]
- [`d9de5b19`](https://github.com/tauri-apps/plugins-workspace/commit/d9de5b19d1e950c06f0915ae92a862acb266d108)([#1283](https://github.com/tauri-apps/plugins-workspace/pull/1283)) Implement `WindowExt` for `WebviewWindow`.
## \[2.0.0-beta.4]
- [`bd1ed590`](https://github.com/tauri-apps/plugins-workspace/commit/bd1ed5903ffcce5500310dac1e59e8c67674ef1e)([#1237](https://github.com/tauri-apps/plugins-workspace/pull/1237)) Update to tauri beta.17.
@@ -83,4 +87,4 @@
- Fix restore maximization state only maximized on main monitor.
- [70d9908](https://github.com/tauri-apps/plugins-workspace/commit/70d99086de3a58189d65c49954a3495972880725) fix(window-state): restore window position if the one of the window corners intersects with monitor ([#898](https://github.com/tauri-apps/plugins-workspace/pull/898)) on 2024-01-25
://github.com/tauri-apps/plugins-workspace/commit/70d99086de3a58189d65c49954a3495972880725) fix(window-state): restore window position if the one of the window corners intersects with monitor ([#898](https://github.com/tauri-apps/plugins-workspace/pull/898)) on 2024-01-25
://github.com/tauri-apps/plugins-workspace/commit/70d99086de3a58189d65c49954a3495972880725) fix(window-state): restore window position if the one of the window corners intersects with monitor ([#898](https://github.com/tauri-apps/plugins-workspace/pull/898)) on 2024-01-25
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-window-state"
version = "2.0.0-beta.6"
version = "2.0.0-beta.7"
description = "Save window positions and sizes and restore them when the app is reopened."
authors = { workspace = true }
license = { workspace = true }
-2
View File
@@ -26,8 +26,6 @@ pub async fn restore_state<R: Runtime>(
.ok_or_else(|| format!("Invalid state flags bits: {}", flags))?;
app.get_webview_window(&label)
.ok_or_else(|| format!("Couldn't find window with label: {}", label))?
.as_ref()
.window()
.restore_state(flags)
.map_err(|e| e.to_string())?;
Ok(())
+14 -3
View File
@@ -16,8 +16,8 @@ use bitflags::bitflags;
use serde::{Deserialize, Serialize};
use tauri::{
plugin::{Builder as PluginBuilder, TauriPlugin},
LogicalSize, Manager, Monitor, PhysicalPosition, PhysicalSize, RunEvent, Runtime, Window,
WindowEvent,
LogicalSize, Manager, Monitor, PhysicalPosition, PhysicalSize, RunEvent, Runtime,
WebviewWindow, Window, WindowEvent,
};
use std::{
@@ -118,7 +118,7 @@ impl<R: Runtime> AppHandleExt for tauri::AppHandle<R> {
let mut state = cache.0.lock().unwrap();
for (label, s) in state.iter_mut() {
if let Some(window) = self.get_webview_window(label) {
window.as_ref().window().update_state(s, flags)?;
window.update_state(s, flags)?;
}
}
@@ -141,6 +141,11 @@ pub trait WindowExt {
fn restore_state(&self, flags: StateFlags) -> tauri::Result<()>;
}
impl<R: Runtime> WindowExt for WebviewWindow<R> {
fn restore_state(&self, flags: StateFlags) -> tauri::Result<()> {
self.as_ref().window().restore_state(flags)
}
}
impl<R: Runtime> WindowExt for Window<R> {
fn restore_state(&self, flags: StateFlags) -> tauri::Result<()> {
let cache = self.state::<WindowStateCache>();
@@ -246,6 +251,12 @@ trait WindowExtInternal {
fn update_state(&self, state: &mut WindowState, flags: StateFlags) -> tauri::Result<()>;
}
impl<R: Runtime> WindowExtInternal for WebviewWindow<R> {
fn update_state(&self, state: &mut WindowState, flags: StateFlags) -> tauri::Result<()> {
self.as_ref().window().update_state(state, flags)
}
}
impl<R: Runtime> WindowExtInternal for Window<R> {
fn update_state(&self, state: &mut WindowState, flags: StateFlags) -> tauri::Result<()> {
let is_maximized = match flags.intersects(StateFlags::MAXIMIZED | StateFlags::SIZE) {
+90 -90
View File
@@ -35,7 +35,7 @@ importers:
version: 8.57.0
eslint-config-love:
specifier: 47.0.0
version: 47.0.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@17.4.0)(eslint-plugin-promise@6.1.1)(eslint@8.57.0)(typescript@5.4.5)
version: 47.0.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@17.5.1)(eslint-plugin-promise@6.1.1)(eslint@8.57.0)(typescript@5.4.5)
eslint-config-prettier:
specifier: 9.1.0
version: 9.1.0(eslint@8.57.0)
@@ -43,8 +43,8 @@ importers:
specifier: 2.29.1
version: 2.29.1(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)
eslint-plugin-n:
specifier: 17.4.0
version: 17.4.0(eslint@8.57.0)
specifier: 17.5.1
version: 17.5.1(eslint@8.57.0)
eslint-plugin-promise:
specifier: 6.1.1
version: 6.1.1(eslint@8.57.0)
@@ -106,27 +106,27 @@ importers:
specifier: 2.0.0-beta.3
version: link:../../plugins/process
'@tauri-apps/plugin-shell':
specifier: 2.0.0-beta.3
specifier: 2.0.0-beta.4
version: link:../../plugins/shell
'@tauri-apps/plugin-updater':
specifier: 2.0.0-beta.3
version: link:../../plugins/updater
'@zerodevx/svelte-json-view':
specifier: 1.0.9
version: 1.0.9(svelte@4.2.15)
version: 1.0.9(svelte@4.2.16)
devDependencies:
'@iconify-json/codicon':
specifier: ^1.1.37
version: 1.1.47
'@iconify-json/ph':
specifier: ^1.1.8
version: 1.1.12
version: 1.1.13
'@sveltejs/vite-plugin-svelte':
specifier: ^3.0.1
version: 3.1.0(svelte@4.2.15)(vite@5.2.10)
version: 3.1.0(svelte@4.2.16)(vite@5.2.11)
'@tauri-apps/cli':
specifier: 2.0.0-beta.15
version: 2.0.0-beta.15
specifier: 2.0.0-beta.16
version: 2.0.0-beta.16
'@unocss/extractor-svelte':
specifier: ^0.59.0
version: 0.59.4
@@ -135,13 +135,13 @@ importers:
version: 8.0.0
svelte:
specifier: ^4.2.8
version: 4.2.15
version: 4.2.16
unocss:
specifier: ^0.59.0
version: 0.59.4(postcss@8.4.38)(rollup@4.17.2)(vite@5.2.10)
version: 0.59.4(postcss@8.4.38)(rollup@4.17.2)(vite@5.2.11)
vite:
specifier: ^5.0.13
version: 5.2.10
version: 5.2.11
plugins/authenticator:
dependencies:
@@ -191,12 +191,12 @@ importers:
specifier: 2.0.0-beta.11
version: 2.0.0-beta.11
'@tauri-apps/plugin-deep-link':
specifier: 2.0.0-beta.3
specifier: 2.0.0-beta.4
version: link:../..
devDependencies:
'@tauri-apps/cli':
specifier: 2.0.0-beta.15
version: 2.0.0-beta.15
specifier: 2.0.0-beta.16
version: 2.0.0-beta.16
internal-ip:
specifier: ^8.0.0
version: 8.0.0
@@ -205,7 +205,7 @@ importers:
version: 5.4.5
vite:
specifier: ^5.0.13
version: 5.2.10
version: 5.2.11
plugins/dialog:
dependencies:
@@ -276,8 +276,8 @@ importers:
plugins/single-instance/examples/vanilla:
devDependencies:
'@tauri-apps/cli':
specifier: 2.0.0-beta.15
version: 2.0.0-beta.15
specifier: 2.0.0-beta.16
version: 2.0.0-beta.16
plugins/sql:
dependencies:
@@ -295,13 +295,13 @@ importers:
devDependencies:
'@tauri-apps/cli':
specifier: ^2.0.0-beta.15
version: 2.0.0-beta.15
version: 2.0.0-beta.16
typescript:
specifier: ^5.3.3
version: 5.4.5
vite:
specifier: ^5.0.12
version: 5.2.10
version: 5.2.11
plugins/stronghold:
dependencies:
@@ -334,14 +334,14 @@ importers:
version: link:../..
devDependencies:
'@tauri-apps/cli':
specifier: 2.0.0-beta.15
version: 2.0.0-beta.15
specifier: 2.0.0-beta.16
version: 2.0.0-beta.16
typescript:
specifier: ^5.3.3
version: 5.4.5
vite:
specifier: ^5.0.13
version: 5.2.10
version: 5.2.11
plugins/window-state:
dependencies:
@@ -1110,8 +1110,8 @@ packages:
'@iconify/types': 2.0.0
dev: true
/@iconify-json/ph@1.1.12:
resolution: {integrity: sha512-m+rXTW084YaQQHT+F8TxdkCoAh+i/5MWRoSuPmxCWPlxwMAaLT/QfyVsbEiV95HM5806U/jKpBV6F1b7Pmr3Vg==}
/@iconify-json/ph@1.1.13:
resolution: {integrity: sha512-xtM4JJ63HCKj09WRqrBswXiHrpliBlqboWSZH8odcmqYXbvIFceU9/Til4V+MQr6+MoUC+KB72cxhky2+A6r/g==}
dependencies:
'@iconify/types': 2.0.0
dev: true
@@ -1387,7 +1387,7 @@ packages:
dev: true
optional: true
/@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@4.2.15)(vite@5.2.10):
/@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@4.2.16)(vite@5.2.11):
resolution: {integrity: sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==}
engines: {node: ^18.0.0 || >=20}
peerDependencies:
@@ -1395,30 +1395,30 @@ packages:
svelte: ^4.0.0 || ^5.0.0-next.0
vite: ^5.0.0
dependencies:
'@sveltejs/vite-plugin-svelte': 3.1.0(svelte@4.2.15)(vite@5.2.10)
'@sveltejs/vite-plugin-svelte': 3.1.0(svelte@4.2.16)(vite@5.2.11)
debug: 4.3.4(supports-color@8.1.1)
svelte: 4.2.15
vite: 5.2.10
svelte: 4.2.16
vite: 5.2.11
transitivePeerDependencies:
- supports-color
dev: true
/@sveltejs/vite-plugin-svelte@3.1.0(svelte@4.2.15)(vite@5.2.10):
/@sveltejs/vite-plugin-svelte@3.1.0(svelte@4.2.16)(vite@5.2.11):
resolution: {integrity: sha512-sY6ncCvg+O3njnzbZexcVtUqOBE3iYmQPJ9y+yXSkOwG576QI/xJrBnQSRXFLGwJNBa0T78JEKg5cIR0WOAuUw==}
engines: {node: ^18.0.0 || >=20}
peerDependencies:
svelte: ^4.0.0 || ^5.0.0-next.0
vite: ^5.0.0
dependencies:
'@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@4.2.15)(vite@5.2.10)
'@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.0)(svelte@4.2.16)(vite@5.2.11)
debug: 4.3.4(supports-color@8.1.1)
deepmerge: 4.3.1
kleur: 4.1.5
magic-string: 0.30.10
svelte: 4.2.15
svelte-hmr: 0.16.0(svelte@4.2.15)
vite: 5.2.10
vitefu: 0.2.5(vite@5.2.10)
svelte: 4.2.16
svelte-hmr: 0.16.0(svelte@4.2.16)
vite: 5.2.11
vitefu: 0.2.5(vite@5.2.11)
transitivePeerDependencies:
- supports-color
dev: true
@@ -1428,8 +1428,8 @@ packages:
engines: {node: '>= 18', npm: '>= 6.6.0', yarn: '>= 1.19.1'}
dev: false
/@tauri-apps/cli-darwin-arm64@2.0.0-beta.15:
resolution: {integrity: sha512-M4owBLoRdJb2/IK48KOQDU3j5xrjqGxa539rDXMjvaKydBk8x+aLdk3xZNsk/owHTI1GnrQZsPCMQaOgetYHaw==}
/@tauri-apps/cli-darwin-arm64@2.0.0-beta.16:
resolution: {integrity: sha512-5Gif4AvpJmnyLj3HO3AEl1RVrr4ast6mDQiXoLwe75bfWq1pj9VwsS5SuSrUKtB8YBSnnclcJwkqwa6soY/xkg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
@@ -1437,8 +1437,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-darwin-x64@2.0.0-beta.15:
resolution: {integrity: sha512-ECpatfJdT4xKyFoE7tNEtTUIRxjQ2XSXa0TQkP3g7Kn7H/jRse+7pYe69jASA7shixajatAwmD4bXNT8jYRyNA==}
/@tauri-apps/cli-darwin-x64@2.0.0-beta.16:
resolution: {integrity: sha512-6Cia8lGSroyoXKvfRI+Dv8Xinr27lptDzGZnd8mT9V0xPg73xcWxPKiTkuxPmLQTrQKVAurfsX3DwwgK8m9kSw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
@@ -1446,8 +1446,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-linux-arm-gnueabihf@2.0.0-beta.15:
resolution: {integrity: sha512-GQz2nnPwIamzDbmmfGWvmmoLthOkOBs0RO5u72KYAa78ZRFTx7S6AovnxJv48Fq+zeGGdDKoD9+ZG2Ue+sCL4w==}
/@tauri-apps/cli-linux-arm-gnueabihf@2.0.0-beta.16:
resolution: {integrity: sha512-1mQ0flIt0wrX4QLPwd8f1QFsuFjLPQtWuiObK63K0/YZmDS2yzKT6jnGqNCJsSiyXE2/36gKSyWh6OVpX8U7xg==}
engines: {node: '>= 10'}
cpu: [arm]
os: [linux]
@@ -1455,8 +1455,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-linux-arm64-gnu@2.0.0-beta.15:
resolution: {integrity: sha512-YBIfq0GbmIsWmRy6dVuDv3oMJN7a3R8HGVPMsa1W526AdCxoZDiPOQpSQN4VihJlbebUHxS/HyYF6maCY8uGzA==}
/@tauri-apps/cli-linux-arm64-gnu@2.0.0-beta.16:
resolution: {integrity: sha512-CjgwOvaslvy06m36faZ40noQaBu37gcXtD0HlCgAMofDZz7fUWQJn3xE7r8fegXmY0oMKZ9ah8dgwd5KSk+L+Q==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
@@ -1464,8 +1464,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-linux-arm64-musl@2.0.0-beta.15:
resolution: {integrity: sha512-2ZBXoShz7UfqVGmc85mhwjI6ckdtrk15V69adxt/x+VS68yK6Ddbj+yqlffpeFNL90fZrsVhFoRIDqgkxtwksQ==}
/@tauri-apps/cli-linux-arm64-musl@2.0.0-beta.16:
resolution: {integrity: sha512-JMtryDJckutFzNpwFgh98o9Z4Vw1pwImYmJIDLpCPSqYIfd+mrBgPZFTaGl11ZsQnllqt4FNXlYR8T+ey7ZpfQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
@@ -1473,8 +1473,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-linux-x64-gnu@2.0.0-beta.15:
resolution: {integrity: sha512-cwJqIIdc4Kq9sBl/vYc+Y95iMe+mlTYUj7ZnSn4YAbLKFz432bGg6uBn2qHXFN5jzwXtEOVZiB1zDZ2kveVoAQ==}
/@tauri-apps/cli-linux-x64-gnu@2.0.0-beta.16:
resolution: {integrity: sha512-3dQGCKsbjaIzk4UM7Jf5FzBJpBJ1OfwBOwkVv2M4O7EDLNZi9brDR+I41eqyFhTabEcHJoLhtURLbD25dJuiug==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
@@ -1482,8 +1482,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-linux-x64-musl@2.0.0-beta.15:
resolution: {integrity: sha512-nNuxZ8/qs0vQbdLO2hovskZGxwGn2z4x1QFJuL4xwd6Tryy9vVcznvyZS+t/72dCLoIkY9pKZQq5nYtAHYfTEg==}
/@tauri-apps/cli-linux-x64-musl@2.0.0-beta.16:
resolution: {integrity: sha512-t+wdk/VCn8l9y1fhRQPfvZyz3Or7QEPTxXNobbUzbtckFsf/LqTxjaajOBmSGnZpoTDFvwVOmalDaylILxuM5g==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
@@ -1491,8 +1491,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-win32-arm64-msvc@2.0.0-beta.15:
resolution: {integrity: sha512-DXiXMTE00INjBkTgq1CYduMWgUwQ0NvLw+uXfu8BUupA+aOlv9ODhsGu7bZSaxKx4/glwxNAGZum4kQ0E0AxUg==}
/@tauri-apps/cli-win32-arm64-msvc@2.0.0-beta.16:
resolution: {integrity: sha512-ouP0iiRMTNaKyz6c06LucMR5P585r2XJ3/GlzNWtUfP4EaP8mZAENB0ro9VZl10++7Z658MdWxSAf4+Qmkj0jQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
@@ -1500,8 +1500,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-win32-ia32-msvc@2.0.0-beta.15:
resolution: {integrity: sha512-ajEQdW2jx2raPp7eDYryJkbBrgI8PIY1dz5ro8FweRrRmbotaUlclsro1kfNMQrfDah8+qfwnRvW3MahOBE5Wg==}
/@tauri-apps/cli-win32-ia32-msvc@2.0.0-beta.16:
resolution: {integrity: sha512-BiBkv3IesPNGXVaampxpB+ub0tz2sGu+6OLzxSm1QTp+2ZSw/qeXi/icvJl5azmOyee4ZWBBiuBzdVY88QH+Vw==}
engines: {node: '>= 10'}
cpu: [ia32]
os: [win32]
@@ -1509,8 +1509,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-win32-x64-msvc@2.0.0-beta.15:
resolution: {integrity: sha512-yzsSgoiY0PmFiR5LvVOFr1b7h9l3aLPPQFlDG6+kRMrxCo7x7Pbyh4D5cqiMUuZO0QacwSP38EH6w0F88Y+4OA==}
/@tauri-apps/cli-win32-x64-msvc@2.0.0-beta.16:
resolution: {integrity: sha512-rrJeC7eAT6diQpnI3aaflhvtKyTryywbhHLG/c1QyPhdxA7Or6nflo5KzWLd6q3GQqKRbvz5dDtxwFn+XLo+rQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
@@ -1518,21 +1518,21 @@ packages:
dev: true
optional: true
/@tauri-apps/cli@2.0.0-beta.15:
resolution: {integrity: sha512-3pCvc54QfsRY+i9B7w3Q5jPAGtf8p+g7N/BamWPeiW6YqDqbHi9rNVI3SzrHkRRNOJnzMW8E5a8G0HziOluZGg==}
/@tauri-apps/cli@2.0.0-beta.16:
resolution: {integrity: sha512-ELaPqTekAVfTU4lFf7k/Z422DKXk/uDWi7ppI8TuQOqcXjrxlXMvv/Y1eC2tem9vMeuOIU0Jg53pOhOu0w8JIQ==}
engines: {node: '>= 10'}
hasBin: true
optionalDependencies:
'@tauri-apps/cli-darwin-arm64': 2.0.0-beta.15
'@tauri-apps/cli-darwin-x64': 2.0.0-beta.15
'@tauri-apps/cli-linux-arm-gnueabihf': 2.0.0-beta.15
'@tauri-apps/cli-linux-arm64-gnu': 2.0.0-beta.15
'@tauri-apps/cli-linux-arm64-musl': 2.0.0-beta.15
'@tauri-apps/cli-linux-x64-gnu': 2.0.0-beta.15
'@tauri-apps/cli-linux-x64-musl': 2.0.0-beta.15
'@tauri-apps/cli-win32-arm64-msvc': 2.0.0-beta.15
'@tauri-apps/cli-win32-ia32-msvc': 2.0.0-beta.15
'@tauri-apps/cli-win32-x64-msvc': 2.0.0-beta.15
'@tauri-apps/cli-darwin-arm64': 2.0.0-beta.16
'@tauri-apps/cli-darwin-x64': 2.0.0-beta.16
'@tauri-apps/cli-linux-arm-gnueabihf': 2.0.0-beta.16
'@tauri-apps/cli-linux-arm64-gnu': 2.0.0-beta.16
'@tauri-apps/cli-linux-arm64-musl': 2.0.0-beta.16
'@tauri-apps/cli-linux-x64-gnu': 2.0.0-beta.16
'@tauri-apps/cli-linux-x64-musl': 2.0.0-beta.16
'@tauri-apps/cli-win32-arm64-msvc': 2.0.0-beta.16
'@tauri-apps/cli-win32-ia32-msvc': 2.0.0-beta.16
'@tauri-apps/cli-win32-x64-msvc': 2.0.0-beta.16
dev: true
/@tauri-apps/toml@2.2.4:
@@ -1704,7 +1704,7 @@ packages:
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
dev: true
/@unocss/astro@0.59.4(rollup@4.17.2)(vite@5.2.10):
/@unocss/astro@0.59.4(rollup@4.17.2)(vite@5.2.11):
resolution: {integrity: sha512-DU3OR5MMR1Uvvec4/wB9EetDASHRg19Moy6z/MiIhn8JWJ0QzWYgSeJcfUX8exomMYv6WUEQJL+CyLI34Wmn8w==}
peerDependencies:
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0
@@ -1714,8 +1714,8 @@ packages:
dependencies:
'@unocss/core': 0.59.4
'@unocss/reset': 0.59.4
'@unocss/vite': 0.59.4(rollup@4.17.2)(vite@5.2.10)
vite: 5.2.10
'@unocss/vite': 0.59.4(rollup@4.17.2)(vite@5.2.11)
vite: 5.2.11
transitivePeerDependencies:
- rollup
dev: true
@@ -1902,7 +1902,7 @@ packages:
'@unocss/core': 0.59.4
dev: true
/@unocss/vite@0.59.4(rollup@4.17.2)(vite@5.2.10):
/@unocss/vite@0.59.4(rollup@4.17.2)(vite@5.2.11):
resolution: {integrity: sha512-q7GN7vkQYn79n7vYIUlaa7gXGwc7pk0Qo3z3ZFwWGE43/DtZnn2Hwl5UjgBAgi9McA+xqHJEHRsJnI7HJPHUYA==}
peerDependencies:
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0
@@ -1917,17 +1917,17 @@ packages:
chokidar: 3.6.0
fast-glob: 3.3.2
magic-string: 0.30.10
vite: 5.2.10
vite: 5.2.11
transitivePeerDependencies:
- rollup
dev: true
/@zerodevx/svelte-json-view@1.0.9(svelte@4.2.15):
/@zerodevx/svelte-json-view@1.0.9(svelte@4.2.16):
resolution: {integrity: sha512-2KKxBfDxEo7lM/kJSy+m1PdLAp5Q9c5nB6OYVBg7oWPdCLXB9JVH1Ytxn2hkqTn77m9MobqGI1fz9FFOTPONfA==}
peerDependencies:
svelte: ^3.57.0 || ^4.0.0
dependencies:
svelte: 4.2.15
svelte: 4.2.16
dev: false
/acorn-jsx@5.3.2(acorn@8.11.3):
@@ -2679,7 +2679,7 @@ packages:
eslint: 8.57.0
dev: true
/eslint-config-love@47.0.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@17.4.0)(eslint-plugin-promise@6.1.1)(eslint@8.57.0)(typescript@5.4.5):
/eslint-config-love@47.0.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@17.5.1)(eslint-plugin-promise@6.1.1)(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-wIeJhb4/NF7nE5Ltppg1e9dp1Auxx0+ZPRysrXQ3uBKlW4Nj/UiTZu4r3sKWCxo6HGcRcI4MC1Q5421y3fny2w==}
peerDependencies:
'@typescript-eslint/eslint-plugin': ^7.0.1
@@ -2693,7 +2693,7 @@ packages:
'@typescript-eslint/parser': 7.8.0(eslint@8.57.0)(typescript@5.4.5)
eslint: 8.57.0
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)
eslint-plugin-n: 17.4.0(eslint@8.57.0)
eslint-plugin-n: 17.5.1(eslint@8.57.0)
eslint-plugin-promise: 6.1.1(eslint@8.57.0)
typescript: 5.4.5
transitivePeerDependencies:
@@ -2795,8 +2795,8 @@ packages:
- supports-color
dev: true
/eslint-plugin-n@17.4.0(eslint@8.57.0):
resolution: {integrity: sha512-RtgGgNpYxECwE9dFr+D66RtbN0B8r/fY6ZF8EVsmK2YnZxE8/n9LNQhgnkL9z37UFZjYVmvMuC32qu7fQBsLVQ==}
/eslint-plugin-n@17.5.1(eslint@8.57.0):
resolution: {integrity: sha512-+E242KoY16xtwqqBRgSsDCrZ3K40jg3Np9fOgQyakcHaqymK3bnxYB1F1oe8Ksts8TDDViROFgraoLzbWhfHVw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: '>=8.23.0'
@@ -4563,17 +4563,17 @@ packages:
engines: {node: '>= 0.4'}
dev: true
/svelte-hmr@0.16.0(svelte@4.2.15):
/svelte-hmr@0.16.0(svelte@4.2.16):
resolution: {integrity: sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==}
engines: {node: ^12.20 || ^14.13.1 || >= 16}
peerDependencies:
svelte: ^3.19.0 || ^4.0.0
dependencies:
svelte: 4.2.15
svelte: 4.2.16
dev: true
/svelte@4.2.15:
resolution: {integrity: sha512-j9KJSccHgLeRERPlhMKrCXpk2TqL2m5Z+k+OBTQhZOhIdCCd3WfqV+ylPWeipEwq17P/ekiSFWwrVQv93i3bsg==}
/svelte@4.2.16:
resolution: {integrity: sha512-mQwHpqHD2PmFcCyHaZ7XiTqposaLvJ75WpYcyY5/ce3qxbYtwQpZ+M7ZKP+2CG5U6kfnBZBpPLyofhlE6ROrnQ==}
engines: {node: '>=16'}
dependencies:
'@ampproject/remapping': 2.3.0
@@ -4781,7 +4781,7 @@ packages:
'@types/unist': 2.0.10
dev: true
/unocss@0.59.4(postcss@8.4.38)(rollup@4.17.2)(vite@5.2.10):
/unocss@0.59.4(postcss@8.4.38)(rollup@4.17.2)(vite@5.2.11):
resolution: {integrity: sha512-QmCVjRObvVu/gsGrJGVt0NnrdhFFn314BUZn2WQyXV9rIvHLRmG5bIu0j5vibJkj7ZhFchTrnTM1pTFXP1xt5g==}
engines: {node: '>=14'}
peerDependencies:
@@ -4793,7 +4793,7 @@ packages:
vite:
optional: true
dependencies:
'@unocss/astro': 0.59.4(rollup@4.17.2)(vite@5.2.10)
'@unocss/astro': 0.59.4(rollup@4.17.2)(vite@5.2.11)
'@unocss/cli': 0.59.4(rollup@4.17.2)
'@unocss/core': 0.59.4
'@unocss/extractor-arbitrary-variants': 0.59.4
@@ -4812,8 +4812,8 @@ packages:
'@unocss/transformer-compile-class': 0.59.4
'@unocss/transformer-directives': 0.59.4
'@unocss/transformer-variant-group': 0.59.4
'@unocss/vite': 0.59.4(rollup@4.17.2)(vite@5.2.10)
vite: 5.2.10
'@unocss/vite': 0.59.4(rollup@4.17.2)(vite@5.2.11)
vite: 5.2.11
transitivePeerDependencies:
- postcss
- rollup
@@ -4857,8 +4857,8 @@ packages:
vfile-message: 2.0.4
dev: true
/vite@5.2.10:
resolution: {integrity: sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==}
/vite@5.2.11:
resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
@@ -4892,7 +4892,7 @@ packages:
fsevents: 2.3.3
dev: true
/vitefu@0.2.5(vite@5.2.10):
/vitefu@0.2.5(vite@5.2.11):
resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==}
peerDependencies:
vite: ^3.0.0 || ^4.0.0 || ^5.0.0
@@ -4900,7 +4900,7 @@ packages:
vite:
optional: true
dependencies:
vite: 5.2.10
vite: 5.2.11
dev: true
/wcwidth@1.0.1:
+19
View File
@@ -18,6 +18,25 @@
"matchPackageNames": ["node", "pnpm"],
"matchDepTypes": ["engines", "packageManager"],
"enabled": false
},
{
"description": "Prevent unwanted minor/patch Cargo.toml updates",
"matchManagers": ["cargo"],
"rangeStrategy": "update-lockfile"
},
{
"description": "Prevent spammy minor/patch Cargo.lock updates",
"matchManagers": ["cargo"],
"matchUpdateTypes": ["minor", "patch"],
"matchCurrentVersion": "!/^0/",
"enabled": false
},
{
"description": "Prevent spammy patch Cargo.lock updates for 0.x deps",
"matchManagers": ["cargo"],
"matchUpdateTypes": ["patch"],
"matchCurrentVersion": "/^0/",
"enabled": false
}
],
"postUpdateOptions": ["pnpmDedupe"]