Merge branch 'v2' into feat/dialog/folder-picker

pull/2322/head
Julian Carrier 5 months ago committed by GitHub
commit cf0b54bf6b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -8,6 +8,7 @@ on:
pull_request:
paths:
- '.github/workflows/check-generated-files.yml'
- pnpm-lock.yaml
- '**/guest-js/**'
concurrency:
@ -27,94 +28,117 @@ jobs:
filters: |
autostart:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/autostart/guest-js/**
- plugins/autostart/src/api-iife.js
cli:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/cli/guest-js/**
- plugins/cli/src/api-iife.js
clipboard-manager:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/clipboard-manager/guest-js/**
- plugins/clipboard-manager/src/api-iife.js
dialog:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/dialog/guest-js/**
- plugins/dialog/src/api-iife.js
fs:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/fs/guest-js/**
- plugins/fs/src/api-iife.js
geolocation:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/geolocation/guest-js/**
- plugins/geolocation/src/api-iife.js
global-shortcut:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/global-shortcut/guest-js/**
- plugins/global-shortcut/src/api-iife.js
opener:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/opener/guest-js/**
- plugins/opener/src/api-iife.js
haptics:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/haptics/guest-js/**
- plugins/haptics/src/api-iife.js
http:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/http/guest-js/**
- plugins/http/src/api-iife.js
log:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/log/guest-js/**
- plugins/log/src/api-iife.js
notification:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/notification/guest-js/**
- plugins/notification/src/api-iife.js
os:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/os/guest-js/**
- plugins/os/src/api-iife.js
positioner:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/positioner/guest-js/**
- plugins/positioner/src/api-iife.js
process:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/process/guest-js/**
- plugins/process/src/api-iife.js
shell:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/shell/guest-js/**
- plugins/shell/src/api-iife.js
sql:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/sql/guest-js/**
- plugins/sql/src/api-iife.js
store:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/store/guest-js/**
- plugins/store/src/api-iife.js
stronghold:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/stronghold/guest-js/**
- plugins/stronghold/src/api-iife.js
updater:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/updater/guest-js/**
- plugins/updater/src/api-iife.js
upload:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/upload/guest-js/**
- plugins/upload/src/api-iife.js
websocket:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/websocket/guest-js/**
- plugins/websocket/src/api-iife.js
window-state:
- .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/window-state/guest-js/**
- plugins/window-state/src/api-iife.js

@ -1,5 +1,6 @@
{
"singleQuote": true,
"semi": false,
"trailingComma": "none"
"trailingComma": "none",
"experimentalOperatorPosition": "start"
}

@ -32,8 +32,8 @@ const ignore = [
async function checkFile(file) {
if (
extensions.some((e) => file.endsWith(e)) &&
!ignore.some((i) => file.includes(`${path.sep}${i}`))
extensions.some((e) => file.endsWith(e))
&& !ignore.some((i) => file.includes(`${path.sep}${i}`))
) {
const fileStream = fs.createReadStream(file)
const rl = readline.createInterface({
@ -46,10 +46,10 @@ async function checkFile(file) {
for await (let line of rl) {
// ignore empty lines, allow shebang, swift-tools-version and bundler license
if (
line.length === 0 ||
line.startsWith('#!') ||
line.startsWith('// swift-tools-version:') ||
ignoredLicenses.includes(line)
line.length === 0
|| line.startsWith('#!')
|| line.startsWith('// swift-tools-version:')
|| ignoredLicenses.includes(line)
) {
continue
}

219
Cargo.lock generated

@ -206,7 +206,7 @@ checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
[[package]]
name = "api"
version = "2.0.16"
version = "2.0.18"
dependencies = [
"log",
"serde",
@ -685,6 +685,25 @@ dependencies = [
"generic-array",
]
[[package]]
name = "block-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7"
dependencies = [
"objc-sys",
]
[[package]]
name = "block2"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e58aa60e59d8dbfcc36138f5f18be5f24394d33b38b24f7fd0b1caa33095f22f"
dependencies = [
"block-sys",
"objc2",
]
[[package]]
name = "block2"
version = "0.5.1"
@ -1054,9 +1073,9 @@ dependencies = [
[[package]]
name = "color-backtrace"
version = "0.6.1"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "150fd80a270c0671379f388c8204deb6a746bb4eac8a6c03fe2460b2c0127ea0"
checksum = "2123a5984bd52ca861c66f66a9ab9883b27115c607f801f86c1bc2a84eb69f0f"
dependencies = [
"backtrace",
"termcolor",
@ -2349,9 +2368,9 @@ dependencies = [
[[package]]
name = "gethostname"
version = "0.5.0"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc3655aa6818d65bc620d6911f05aa7b6aeb596291e1e9f79e52df85583d1e30"
checksum = "4fd4b8790c0792e3b11895efdf5f289ebe8b59107a6624f1cce68f24ff8c7035"
dependencies = [
"rustix",
"windows-targets 0.52.6",
@ -2851,6 +2870,16 @@ dependencies = [
"png",
]
[[package]]
name = "icrate"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb69199826926eb864697bddd27f73d9fddcffc004f5733131e15b465e30642"
dependencies = [
"block2 0.4.0",
"objc2",
]
[[package]]
name = "icu_collections"
version = "1.5.0"
@ -3040,6 +3069,15 @@ dependencies = [
"cfb",
]
[[package]]
name = "infer"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7"
dependencies = [
"cfb",
]
[[package]]
name = "inotify"
version = "0.11.0"
@ -3941,7 +3979,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
dependencies = [
"bitflags 2.7.0",
"block2",
"block2 0.5.1",
"libc",
"objc2",
"objc2-core-data",
@ -3957,7 +3995,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
dependencies = [
"bitflags 2.7.0",
"block2",
"block2 0.5.1",
"objc2",
"objc2-core-location",
"objc2-foundation",
@ -3969,7 +4007,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889"
dependencies = [
"block2",
"block2 0.5.1",
"objc2",
"objc2-foundation",
]
@ -3981,7 +4019,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
dependencies = [
"bitflags 2.7.0",
"block2",
"block2 0.5.1",
"objc2",
"objc2-foundation",
]
@ -3992,7 +4030,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
dependencies = [
"block2",
"block2 0.5.1",
"objc2",
"objc2-foundation",
"objc2-metal",
@ -4004,7 +4042,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781"
dependencies = [
"block2",
"block2 0.5.1",
"objc2",
"objc2-contacts",
"objc2-foundation",
@ -4023,7 +4061,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
dependencies = [
"bitflags 2.7.0",
"block2",
"block2 0.5.1",
"dispatch",
"libc",
"objc2",
@ -4035,7 +4073,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398"
dependencies = [
"block2",
"block2 0.5.1",
"objc2",
"objc2-app-kit",
"objc2-foundation",
@ -4048,11 +4086,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
dependencies = [
"bitflags 2.7.0",
"block2",
"block2 0.5.1",
"objc2",
"objc2-foundation",
]
[[package]]
name = "objc2-osa-kit"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6788b04a18ea31e3dc3ab256b8546639e5bbae07c1a0dc4ea8615252bc6aee9a"
dependencies = [
"bitflags 2.7.0",
"objc2",
"objc2-app-kit",
"objc2-foundation",
]
[[package]]
name = "objc2-quartz-core"
version = "0.2.2"
@ -4060,7 +4110,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
dependencies = [
"bitflags 2.7.0",
"block2",
"block2 0.5.1",
"objc2",
"objc2-foundation",
"objc2-metal",
@ -4083,7 +4133,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
dependencies = [
"bitflags 2.7.0",
"block2",
"block2 0.5.1",
"objc2",
"objc2-cloud-kit",
"objc2-core-data",
@ -4103,7 +4153,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe"
dependencies = [
"block2",
"block2 0.5.1",
"objc2",
"objc2-foundation",
]
@ -4115,7 +4165,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
dependencies = [
"bitflags 2.7.0",
"block2",
"block2 0.5.1",
"objc2",
"objc2-core-location",
"objc2-foundation",
@ -4128,7 +4178,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68bc69301064cebefc6c4c90ce9cba69225239e4b8ff99d445a2b5563797da65"
dependencies = [
"bitflags 2.7.0",
"block2",
"block2 0.5.1",
"objc2",
"objc2-app-kit",
"objc2-foundation",
@ -4276,6 +4326,20 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "osakit"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35366a452fce3f8947eb2f33226a133aaf0cacedef2af67ade348d58be7f85d0"
dependencies = [
"icrate",
"objc2-foundation",
"objc2-osa-kit",
"serde",
"serde_json",
"thiserror 1.0.69",
]
[[package]]
name = "pango"
version = "0.18.3"
@ -5080,7 +5144,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46f6f80a9b882647d9014673ca9925d30ffc9750f2eed2b4490e189eaebd01e8"
dependencies = [
"ashpd",
"block2",
"block2 0.5.1",
"glib-sys",
"gobject-sys",
"gtk-sys",
@ -6555,8 +6619,8 @@ dependencies = [
"thiserror 2.0.9",
"tracing",
"url",
"windows-registry 0.4.0",
"windows-result 0.3.0",
"windows-registry 0.5.0",
"windows-result 0.3.1",
]
[[package]]
@ -6673,7 +6737,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-log"
version = "2.2.1"
version = "2.2.2"
dependencies = [
"android_logger",
"byte-unit",
@ -6750,7 +6814,7 @@ dependencies = [
name = "tauri-plugin-os"
version = "2.2.0"
dependencies = [
"gethostname 0.5.0",
"gethostname 1.0.0",
"log",
"os_info",
"serde",
@ -6818,7 +6882,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-single-instance"
version = "2.2.1"
version = "2.2.2"
dependencies = [
"semver",
"serde",
@ -6885,15 +6949,16 @@ dependencies = [
[[package]]
name = "tauri-plugin-updater"
version = "2.4.0"
version = "2.5.1"
dependencies = [
"base64 0.22.1",
"dirs 6.0.0",
"flate2",
"futures-util",
"http",
"infer",
"infer 0.19.0",
"minisign-verify",
"osakit",
"percent-encoding",
"reqwest",
"semver",
@ -6913,7 +6978,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-upload"
version = "2.2.0"
version = "2.2.1"
dependencies = [
"futures-util",
"log",
@ -7019,7 +7084,7 @@ dependencies = [
"glob",
"html5ever",
"http",
"infer",
"infer 0.16.0",
"json-patch",
"kuchikiki",
"log",
@ -8252,6 +8317,12 @@ dependencies = [
"syn 2.0.90",
]
[[package]]
name = "windows-link"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3"
[[package]]
name = "windows-registry"
version = "0.2.0"
@ -8265,13 +8336,13 @@ dependencies = [
[[package]]
name = "windows-registry"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3"
checksum = "6c44a98275e31bfd112bb06ba96c8ab13c03383a3753fdddd715406a1824c7e0"
dependencies = [
"windows-result 0.3.0",
"windows-strings 0.3.0",
"windows-targets 0.53.0",
"windows-link",
"windows-result 0.3.1",
"windows-strings 0.3.1",
]
[[package]]
@ -8294,11 +8365,11 @@ dependencies = [
[[package]]
name = "windows-result"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d08106ce80268c4067c0571ca55a9b4e9516518eaa1a1fe9b37ca403ae1d1a34"
checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189"
dependencies = [
"windows-targets 0.53.0",
"windows-link",
]
[[package]]
@ -8313,11 +8384,11 @@ dependencies = [
[[package]]
name = "windows-strings"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b888f919960b42ea4e11c2f408fadb55f78a9f236d5eef084103c8ce52893491"
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
dependencies = [
"windows-targets 0.53.0",
"windows-link",
]
[[package]]
@ -8395,29 +8466,13 @@ dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm 0.52.6",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
dependencies = [
"windows_aarch64_gnullvm 0.53.0",
"windows_aarch64_msvc 0.53.0",
"windows_i686_gnu 0.53.0",
"windows_i686_gnullvm 0.53.0",
"windows_i686_msvc 0.53.0",
"windows_x86_64_gnu 0.53.0",
"windows_x86_64_gnullvm 0.53.0",
"windows_x86_64_msvc 0.53.0",
]
[[package]]
name = "windows-version"
version = "0.1.1"
@ -8445,12 +8500,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
[[package]]
name = "windows_aarch64_msvc"
version = "0.36.1"
@ -8475,12 +8524,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
version = "0.36.1"
@ -8505,24 +8548,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
[[package]]
name = "windows_i686_msvc"
version = "0.36.1"
@ -8547,12 +8578,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
[[package]]
name = "windows_x86_64_gnu"
version = "0.36.1"
@ -8577,12 +8602,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
@ -8601,12 +8620,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
[[package]]
name = "windows_x86_64_msvc"
version = "0.36.1"
@ -8631,12 +8644,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "winnow"
version = "0.5.40"
@ -8693,7 +8700,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e644bf458e27b11b0ecafc9e5633d1304fdae82baca1d42185669752fe6ca4f"
dependencies = [
"base64 0.22.1",
"block2",
"block2 0.5.1",
"cookie",
"crossbeam-channel",
"dpi",

@ -1,5 +1,18 @@
# Changelog
## \[2.0.14]
### Dependencies
- Upgraded to `log-js@2.2.2`
- Upgraded to `updater-js@2.5.1`
## \[2.0.13]
### Dependencies
- Upgraded to `updater-js@2.5.0`
## \[2.0.12]
### Dependencies

@ -1,7 +1,7 @@
{
"name": "api",
"private": true,
"version": "2.0.12",
"version": "2.0.14",
"type": "module",
"scripts": {
"dev": "vite --clearScreen false",
@ -28,7 +28,7 @@
"@tauri-apps/plugin-process": "^2.2.0",
"@tauri-apps/plugin-shell": "^2.2.0",
"@tauri-apps/plugin-store": "^2.2.0",
"@tauri-apps/plugin-updater": "^2.4.0",
"@tauri-apps/plugin-updater": "^2.5.1",
"@zerodevx/svelte-json-view": "1.0.11"
},
"devDependencies": {
@ -36,9 +36,9 @@
"@iconify-json/ph": "^1.2.1",
"@sveltejs/vite-plugin-svelte": "^5.0.1",
"@tauri-apps/cli": "2.2.7",
"@unocss/extractor-svelte": "^65.0.0",
"@unocss/extractor-svelte": "^66.0.0",
"svelte": "^5.10.0",
"unocss": "^65.0.0",
"unocss": "^66.0.0",
"vite": "^6.0.3"
}
}

@ -1,5 +1,18 @@
# Changelog
## \[2.0.18]
### Dependencies
- Upgraded to `log@2.2.2`
- Upgraded to `updater@2.5.1`
## \[2.0.17]
### Dependencies
- Upgraded to `updater@2.5.0`
## \[2.0.16]
### Dependencies

@ -1,7 +1,7 @@
[package]
name = "api"
publish = false
version = "2.0.16"
version = "2.0.18"
description = "An example Tauri Application showcasing the api"
edition = "2021"
rust-version = { workspace = true }
@ -19,7 +19,7 @@ serde_json = { workspace = true }
serde = { workspace = true }
tiny_http = "0.12"
log = { workspace = true }
tauri-plugin-log = { path = "../../../plugins/log", version = "2.2.1" }
tauri-plugin-log = { path = "../../../plugins/log", version = "2.2.2" }
tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.2.0", features = [
"watch",
] }
@ -53,7 +53,7 @@ features = [
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
tauri-plugin-cli = { path = "../../../plugins/cli", version = "2.2.0" }
tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.2.0" }
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.4.0" }
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.5.1" }
tauri-plugin-window-state = { path = "../../../plugins/window-state", version = "2.2.0" }
[target."cfg(any(target_os = \"android\", target_os = \"ios\"))".dependencies]

@ -11,20 +11,19 @@
"example:api:dev": "pnpm run --filter \"api\" tauri dev"
},
"devDependencies": {
"@eslint/js": "9.19.0",
"@eslint/js": "9.21.0",
"@rollup/plugin-node-resolve": "16.0.0",
"@rollup/plugin-terser": "0.4.4",
"@rollup/plugin-typescript": "11.1.6",
"@types/eslint__js": "8.42.3",
"covector": "^0.12.3",
"eslint": "9.19.0",
"eslint": "9.21.0",
"eslint-config-prettier": "10.0.1",
"eslint-plugin-security": "3.0.1",
"prettier": "3.4.2",
"rollup": "4.32.1",
"prettier": "3.5.2",
"rollup": "4.34.8",
"tslib": "2.8.1",
"typescript": "5.7.3",
"typescript-eslint": "8.22.0"
"typescript-eslint": "8.25.0"
},
"resolutions": {
"semver": ">=7.5.2",

@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_CLIPBOARD_MANAGER__=function(e){"use strict";var t;async function r(e,t={},r){return window.__TAURI_INTERNALS__.invoke(e,t,r)}"function"==typeof SuppressedError&&SuppressedError;class n{get rid(){return function(e,t,r,n){if("a"===r&&!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"===r?n:"a"===r?n.call(e):n?n.value:t.get(e)}(this,t,"f")}constructor(e){t.set(this,void 0),function(e,t,r){if("function"==typeof t||!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");t.set(e,r)}(this,t,e)}async close(){return r("plugin:resources|close",{rid:this.rid})}}t=new WeakMap;class a extends n{constructor(e){super(e)}static async new(e,t,n){return r("plugin:image|new",{rgba:i(e),width:t,height:n}).then((e=>new a(e)))}static async fromBytes(e){return r("plugin:image|from_bytes",{bytes:i(e)}).then((e=>new a(e)))}static async fromPath(e){return r("plugin:image|from_path",{path:e}).then((e=>new a(e)))}async rgba(){return r("plugin:image|rgba",{rid:this.rid}).then((e=>new Uint8Array(e)))}async size(){return r("plugin:image|size",{rid:this.rid})}}function i(e){return null==e?null:"string"==typeof e?e:e instanceof a?e.rid:e}return e.clear=async function(){await r("plugin:clipboard-manager|clear")},e.readImage=async function(){return await r("plugin:clipboard-manager|read_image").then((e=>new a(e)))},e.readText=async function(){return await r("plugin:clipboard-manager|read_text")},e.writeHtml=async function(e,t){await r("plugin:clipboard-manager|write_html",{html:e,altText:t})},e.writeImage=async function(e){await r("plugin:clipboard-manager|write_image",{image:i(e)})},e.writeText=async function(e,t){await r("plugin:clipboard-manager|write_text",{label:t?.label,text:e})},e}({});Object.defineProperty(window.__TAURI__,"clipboardManager",{value:__TAURI_PLUGIN_CLIPBOARD_MANAGER__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_CLIPBOARD_MANAGER__=function(e){"use strict";var n;async function t(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}"function"==typeof SuppressedError&&SuppressedError;class r{get rid(){return function(e,n,t,r){if("function"==typeof n||!n.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===t?r:"a"===t?r.call(e):r?r.value:n.get(e)}(this,n,"f")}constructor(e){n.set(this,void 0),function(e,n,t){if("function"==typeof n||!n.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");n.set(e,t)}(this,n,e)}async close(){return t("plugin:resources|close",{rid:this.rid})}}n=new WeakMap;class a extends r{constructor(e){super(e)}static async new(e,n,r){return t("plugin:image|new",{rgba:i(e),width:n,height:r}).then((e=>new a(e)))}static async fromBytes(e){return t("plugin:image|from_bytes",{bytes:i(e)}).then((e=>new a(e)))}static async fromPath(e){return t("plugin:image|from_path",{path:e}).then((e=>new a(e)))}async rgba(){return t("plugin:image|rgba",{rid:this.rid}).then((e=>new Uint8Array(e)))}async size(){return t("plugin:image|size",{rid:this.rid})}}function i(e){return null==e?null:"string"==typeof e?e:e instanceof a?e.rid:e}return e.clear=async function(){await t("plugin:clipboard-manager|clear")},e.readImage=async function(){return await t("plugin:clipboard-manager|read_image").then((e=>new a(e)))},e.readText=async function(){return await t("plugin:clipboard-manager|read_text")},e.writeHtml=async function(e,n){await t("plugin:clipboard-manager|write_html",{html:e,altText:n})},e.writeImage=async function(e){await t("plugin:clipboard-manager|write_image",{image:i(e)})},e.writeText=async function(e,n){await t("plugin:clipboard-manager|write_text",{label:n?.label,text:e})},e}({});Object.defineProperty(window.__TAURI__,"clipboardManager",{value:__TAURI_PLUGIN_CLIPBOARD_MANAGER__})}

@ -38,7 +38,7 @@ url = { workspace = true }
[target."cfg(windows)".dependencies]
dunce = "1"
windows-registry = "0.4"
windows-registry = "0.5"
windows-result = "0.3"
[target."cfg(target_os = \"linux\")".dependencies]

File diff suppressed because one or more lines are too long

@ -604,8 +604,8 @@ async function copyFile(
options?: CopyFileOptions
): Promise<void> {
if (
(fromPath instanceof URL && fromPath.protocol !== 'file:') ||
(toPath instanceof URL && toPath.protocol !== 'file:')
(fromPath instanceof URL && fromPath.protocol !== 'file:')
|| (toPath instanceof URL && toPath.protocol !== 'file:')
) {
throw new TypeError('Must be a file URL.')
}
@ -919,8 +919,8 @@ async function rename(
options?: RenameOptions
): Promise<void> {
if (
(oldPath instanceof URL && oldPath.protocol !== 'file:') ||
(newPath instanceof URL && newPath.protocol !== 'file:')
(oldPath instanceof URL && oldPath.protocol !== 'file:')
|| (newPath instanceof URL && newPath.protocol !== 'file:')
) {
throw new TypeError('Must be a file URL.')
}

@ -118,8 +118,8 @@ import {
let permissions = await checkPermissions()
if (
permissions.location === 'prompt' ||
permissions.location === 'prompt-with-rationale'
permissions.location === 'prompt'
|| permissions.location === 'prompt-with-rationale'
) {
permissions = await requestPermissions(['location'])
}

@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_GEOLOCATION__=function(t){"use strict";function n(t,n,e,i){if("a"===e&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof n?t!==n||!i:!n.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===e?i:"a"===e?i.call(t):i?i.value:n.get(t)}function e(t,n,e,i,s){if("function"==typeof n||!n.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return n.set(t,e),e}var i,s,o;"function"==typeof SuppressedError&&SuppressedError;const r="__TAURI_TO_IPC_KEY__";class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),s.set(this,0),o.set(this,[]),this.id=function(t,n=!1){return window.__TAURI_INTERNALS__.transformCallback(t,n)}((({message:t,id:r})=>{if(r==n(this,s,"f"))for(n(this,i,"f").call(this,t),e(this,s,n(this,s,"f")+1);n(this,s,"f")in n(this,o,"f");){const t=n(this,o,"f")[n(this,s,"f")];n(this,i,"f").call(this,t),delete n(this,o,"f")[n(this,s,"f")],e(this,s,n(this,s,"f")+1)}else n(this,o,"f")[r]=t}))}set onmessage(t){e(this,i,t)}get onmessage(){return n(this,i,"f")}[(i=new WeakMap,s=new WeakMap,o=new WeakMap,r)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[r]()}}async function c(t,n={},e){return window.__TAURI_INTERNALS__.invoke(t,n,e)}return t.checkPermissions=async function(){return await async function(t){return c(`plugin:${t}|check_permissions`)}("geolocation")},t.clearWatch=async function(t){await c("plugin:geolocation|clear_watch",{channelId:t})},t.getCurrentPosition=async function(t){return await c("plugin:geolocation|get_current_position",{options:t})},t.requestPermissions=async function(t){return await c("plugin:geolocation|request_permissions",{permissions:t})},t.watchPosition=async function(t,n){const e=new a;return e.onmessage=t=>{"string"==typeof t?n(null,t):n(t)},await c("plugin:geolocation|watch_position",{options:t,channel:e}),e.id},t}({});Object.defineProperty(window.__TAURI__,"geolocation",{value:__TAURI_PLUGIN_GEOLOCATION__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_GEOLOCATION__=function(t){"use strict";function n(t,n,e,i){if("function"==typeof n||!n.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===e?i:"a"===e?i.call(t):i?i.value:n.get(t)}function e(t,n,e,i,s){if("function"==typeof n||!n.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return n.set(t,e),e}var i,s,o;"function"==typeof SuppressedError&&SuppressedError;const r="__TAURI_TO_IPC_KEY__";class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),s.set(this,0),o.set(this,[]),this.id=function(t,n=!1){return window.__TAURI_INTERNALS__.transformCallback(t,n)}((({message:t,id:r})=>{if(r==n(this,s,"f"))for(n(this,i,"f").call(this,t),e(this,s,n(this,s,"f")+1);n(this,s,"f")in n(this,o,"f");){const t=n(this,o,"f")[n(this,s,"f")];n(this,i,"f").call(this,t),delete n(this,o,"f")[n(this,s,"f")],e(this,s,n(this,s,"f")+1)}else n(this,o,"f")[r]=t}))}set onmessage(t){e(this,i,t)}get onmessage(){return n(this,i,"f")}[(i=new WeakMap,s=new WeakMap,o=new WeakMap,r)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[r]()}}async function c(t,n={},e){return window.__TAURI_INTERNALS__.invoke(t,n,e)}return t.checkPermissions=async function(){return await async function(t){return c(`plugin:${t}|check_permissions`)}("geolocation")},t.clearWatch=async function(t){await c("plugin:geolocation|clear_watch",{channelId:t})},t.getCurrentPosition=async function(t){return await c("plugin:geolocation|get_current_position",{options:t})},t.requestPermissions=async function(t){return await c("plugin:geolocation|request_permissions",{permissions:t})},t.watchPosition=async function(t,n){const e=new a;return e.onmessage=t=>{"string"==typeof t?n(null,t):n(t)},await c("plugin:geolocation|watch_position",{options:t,channel:e}),e.id},t}({});Object.defineProperty(window.__TAURI__,"geolocation",{value:__TAURI_PLUGIN_GEOLOCATION__})}

@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_GLOBAL_SHORTCUT__=function(t){"use strict";function e(t,e,r,s){if("a"===r&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===r?s:"a"===r?s.call(t):s?s.value:e.get(t)}function r(t,e,r,s,i){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(t,r),r}var s,i,n;"function"==typeof SuppressedError&&SuppressedError;const o="__TAURI_TO_IPC_KEY__";class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,s.set(this,(()=>{})),i.set(this,0),n.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"))for(e(this,s,"f").call(this,t),r(this,i,e(this,i,"f")+1);e(this,i,"f")in e(this,n,"f");){const t=e(this,n,"f")[e(this,i,"f")];e(this,s,"f").call(this,t),delete e(this,n,"f")[e(this,i,"f")],r(this,i,e(this,i,"f")+1)}else e(this,n,"f")[o]=t}))}set onmessage(t){r(this,s,t)}get onmessage(){return e(this,s,"f")}[(s=new WeakMap,i=new WeakMap,n=new WeakMap,o)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[o]()}}async function _(t,e={},r){return window.__TAURI_INTERNALS__.invoke(t,e,r)}return t.isRegistered=async function(t){return await _("plugin:global-shortcut|is_registered",{shortcut:t})},t.register=async function(t,e){const r=new a;return r.onmessage=e,await _("plugin:global-shortcut|register",{shortcuts:Array.isArray(t)?t:[t],handler:r})},t.unregister=async function(t){return await _("plugin:global-shortcut|unregister",{shortcuts:Array.isArray(t)?t:[t]})},t.unregisterAll=async function(){return await _("plugin:global-shortcut|unregister_all",{})},t}({});Object.defineProperty(window.__TAURI__,"globalShortcut",{value:__TAURI_PLUGIN_GLOBAL_SHORTCUT__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_GLOBAL_SHORTCUT__=function(t){"use strict";function e(t,e,r,s){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===r?s:"a"===r?s.call(t):s?s.value:e.get(t)}function r(t,e,r,s,i){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(t,r),r}var s,i,n;"function"==typeof SuppressedError&&SuppressedError;const o="__TAURI_TO_IPC_KEY__";class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,s.set(this,(()=>{})),i.set(this,0),n.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"))for(e(this,s,"f").call(this,t),r(this,i,e(this,i,"f")+1);e(this,i,"f")in e(this,n,"f");){const t=e(this,n,"f")[e(this,i,"f")];e(this,s,"f").call(this,t),delete e(this,n,"f")[e(this,i,"f")],r(this,i,e(this,i,"f")+1)}else e(this,n,"f")[o]=t}))}set onmessage(t){r(this,s,t)}get onmessage(){return e(this,s,"f")}[(s=new WeakMap,i=new WeakMap,n=new WeakMap,o)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[o]()}}async function _(t,e={},r){return window.__TAURI_INTERNALS__.invoke(t,e,r)}return t.isRegistered=async function(t){return await _("plugin:global-shortcut|is_registered",{shortcut:t})},t.register=async function(t,e){const r=new a;return r.onmessage=e,await _("plugin:global-shortcut|register",{shortcuts:Array.isArray(t)?t:[t],handler:r})},t.unregister=async function(t){return await _("plugin:global-shortcut|unregister",{shortcuts:Array.isArray(t)?t:[t]})},t.unregisterAll=async function(){return await _("plugin:global-shortcut|unregister_all",{})},t}({});Object.defineProperty(window.__TAURI__,"globalShortcut",{value:__TAURI_PLUGIN_GLOBAL_SHORTCUT__})}

@ -69,6 +69,19 @@ fn main() {
}
```
Second, add the required permissions in the project:
`src-tauri/capabilities/default.json`
```json
"permissions": [
"haptics:allow-impact-feedback",
"haptics:allow-notification-feedback",
"haptics:allow-selection-feedback",
"haptics:allow-vibrate"
]
```
Afterwards all the plugin's APIs are available through the JavaScript guest bindings:
```javascript

@ -1,5 +1,9 @@
# Changelog
## \[2.2.2]
- [`6b4c3917`](https://github.com/tauri-apps/plugins-workspace/commit/6b4c3917389f4bc489d03b48a837557ac0584175) ([#2401](https://github.com/tauri-apps/plugins-workspace/pull/2401) by [@Seishiin](https://github.com/tauri-apps/plugins-workspace/../../Seishiin)) Fix timezone_strategy overwriting previously set LogLevels.
## \[2.2.1]
- [`784a54a3`](https://github.com/tauri-apps/plugins-workspace/commit/784a54a39094dfbaaa8dd123eb083c04dc6c3bb2) ([#2344](https://github.com/tauri-apps/plugins-workspace/pull/2344) by [@madsmtm](https://github.com/tauri-apps/plugins-workspace/../../madsmtm)) Use `objc2` instead of `objc`.

@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-log"
version = "2.2.1"
version = "2.2.2"
description = "Configurable logging for your Tauri app."
authors = { workspace = true }
license = { workspace = true }

@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-log",
"version": "2.2.1",
"version": "2.2.2",
"description": "Configurable logging for your Tauri app.",
"license": "MIT OR Apache-2.0",
"authors": [

@ -278,7 +278,7 @@ impl Builder {
let format =
time::format_description::parse("[[[year]-[month]-[day]][[[hour]:[minute]:[second]]")
.unwrap();
self.dispatch = fern::Dispatch::new().format(move |out, message, record| {
self.dispatch = self.dispatch.format(move |out, message, record| {
out.finish(format_args!(
"{}[{}][{}] {}",
timezone_strategy.get_now().format(&format).unwrap(),

@ -181,8 +181,8 @@ function encodeURI(uri: string): number[] {
protocols.slice(1).forEach(function (protocol) {
if (
(prefix.length === 0 || prefix === 'urn:') &&
uri.indexOf(protocol) === 0
(prefix.length === 0 || prefix === 'urn:')
&& uri.indexOf(protocol) === 0
) {
prefix = protocol
}

@ -46,7 +46,7 @@ windows-version = { version = "0.1", optional = true }
notify-rust = "4.11"
[dev-dependencies]
color-backtrace = "0.6"
color-backtrace = "0.7"
ctor = "0.2"
maplit = "1"

@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_NOTIFICATION__=function(i){"use strict";function t(i,t,n,e){if("a"===n&&!e)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?i!==t||!e:!t.has(i))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?e:"a"===n?e.call(i):e?e.value:t.get(i)}function n(i,t,n,e,a){if("function"==typeof t||!t.has(i))throw new TypeError("Cannot write private member to an object whose class did not declare it");return t.set(i,n),n}var e,a,o;"function"==typeof SuppressedError&&SuppressedError;const r="__TAURI_TO_IPC_KEY__";class s{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,e.set(this,(()=>{})),a.set(this,0),o.set(this,[]),this.id=function(i,t=!1){return window.__TAURI_INTERNALS__.transformCallback(i,t)}((({message:i,id:r})=>{if(r==t(this,a,"f"))for(t(this,e,"f").call(this,i),n(this,a,t(this,a,"f")+1);t(this,a,"f")in t(this,o,"f");){const i=t(this,o,"f")[t(this,a,"f")];t(this,e,"f").call(this,i),delete t(this,o,"f")[t(this,a,"f")],n(this,a,t(this,a,"f")+1)}else t(this,o,"f")[r]=i}))}set onmessage(i){n(this,e,i)}get onmessage(){return t(this,e,"f")}[(e=new WeakMap,a=new WeakMap,o=new WeakMap,r)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[r]()}}class c{constructor(i,t,n){this.plugin=i,this.event=t,this.channelId=n}async unregister(){return u(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}}async function l(i,t,n){const e=new s;return e.onmessage=n,u(`plugin:${i}|registerListener`,{event:t,handler:e}).then((()=>new c(i,t,e.id)))}async function u(i,t={},n){return window.__TAURI_INTERNALS__.invoke(i,t,n)}var f,h,d;i.ScheduleEvery=void 0,(f=i.ScheduleEvery||(i.ScheduleEvery={})).Year="year",f.Month="month",f.TwoWeeks="twoWeeks",f.Week="week",f.Day="day",f.Hour="hour",f.Minute="minute",f.Second="second";return i.Importance=void 0,(h=i.Importance||(i.Importance={}))[h.None=0]="None",h[h.Min=1]="Min",h[h.Low=2]="Low",h[h.Default=3]="Default",h[h.High=4]="High",i.Visibility=void 0,(d=i.Visibility||(i.Visibility={}))[d.Secret=-1]="Secret",d[d.Private=0]="Private",d[d.Public=1]="Public",i.Schedule=class{static at(i,t=!1,n=!1){return{at:{date:i,repeating:t,allowWhileIdle:n},interval:void 0,every:void 0}}static interval(i,t=!1){return{at:void 0,interval:{interval:i,allowWhileIdle:t},every:void 0}}static every(i,t,n=!1){return{at:void 0,interval:void 0,every:{interval:i,count:t,allowWhileIdle:n}}}},i.active=async function(){return await u("plugin:notification|get_active")},i.cancel=async function(i){await u("plugin:notification|cancel",{notifications:i})},i.cancelAll=async function(){await u("plugin:notification|cancel")},i.channels=async function(){return await u("plugin:notification|listChannels")},i.createChannel=async function(i){await u("plugin:notification|create_channel",{...i})},i.isPermissionGranted=async function(){return"default"!==window.Notification.permission?await Promise.resolve("granted"===window.Notification.permission):await u("plugin:notification|is_permission_granted")},i.onAction=async function(i){return await l("notification","actionPerformed",i)},i.onNotificationReceived=async function(i){return await l("notification","notification",i)},i.pending=async function(){return await u("plugin:notification|get_pending")},i.registerActionTypes=async function(i){await u("plugin:notification|register_action_types",{types:i})},i.removeActive=async function(i){await u("plugin:notification|remove_active",{notifications:i})},i.removeAllActive=async function(){await u("plugin:notification|remove_active")},i.removeChannel=async function(i){await u("plugin:notification|delete_channel",{id:i})},i.requestPermission=async function(){return await window.Notification.requestPermission()},i.sendNotification=function(i){"string"==typeof i?new window.Notification(i):new window.Notification(i.title,i)},i}({});Object.defineProperty(window.__TAURI__,"notification",{value:__TAURI_PLUGIN_NOTIFICATION__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_NOTIFICATION__=function(i){"use strict";function n(i,n,t,e){if("function"==typeof n||!n.has(i))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===t?e:"a"===t?e.call(i):e?e.value:n.get(i)}function t(i,n,t,e,o){if("function"==typeof n||!n.has(i))throw new TypeError("Cannot write private member to an object whose class did not declare it");return n.set(i,t),t}var e,o,a;"function"==typeof SuppressedError&&SuppressedError;const r="__TAURI_TO_IPC_KEY__";class c{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,e.set(this,(()=>{})),o.set(this,0),a.set(this,[]),this.id=function(i,n=!1){return window.__TAURI_INTERNALS__.transformCallback(i,n)}((({message:i,id:r})=>{if(r==n(this,o,"f"))for(n(this,e,"f").call(this,i),t(this,o,n(this,o,"f")+1);n(this,o,"f")in n(this,a,"f");){const i=n(this,a,"f")[n(this,o,"f")];n(this,e,"f").call(this,i),delete n(this,a,"f")[n(this,o,"f")],t(this,o,n(this,o,"f")+1)}else n(this,a,"f")[r]=i}))}set onmessage(i){t(this,e,i)}get onmessage(){return n(this,e,"f")}[(e=new WeakMap,o=new WeakMap,a=new WeakMap,r)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[r]()}}class s{constructor(i,n,t){this.plugin=i,this.event=n,this.channelId=t}async unregister(){return u(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}}async function l(i,n,t){const e=new c;return e.onmessage=t,u(`plugin:${i}|registerListener`,{event:n,handler:e}).then((()=>new s(i,n,e.id)))}async function u(i,n={},t){return window.__TAURI_INTERNALS__.invoke(i,n,t)}var f,h,d;i.ScheduleEvery=void 0,(f=i.ScheduleEvery||(i.ScheduleEvery={})).Year="year",f.Month="month",f.TwoWeeks="twoWeeks",f.Week="week",f.Day="day",f.Hour="hour",f.Minute="minute",f.Second="second";return i.Importance=void 0,(h=i.Importance||(i.Importance={}))[h.None=0]="None",h[h.Min=1]="Min",h[h.Low=2]="Low",h[h.Default=3]="Default",h[h.High=4]="High",i.Visibility=void 0,(d=i.Visibility||(i.Visibility={}))[d.Secret=-1]="Secret",d[d.Private=0]="Private",d[d.Public=1]="Public",i.Schedule=class{static at(i,n=!1,t=!1){return{at:{date:i,repeating:n,allowWhileIdle:t},interval:void 0,every:void 0}}static interval(i,n=!1){return{at:void 0,interval:{interval:i,allowWhileIdle:n},every:void 0}}static every(i,n,t=!1){return{at:void 0,interval:void 0,every:{interval:i,count:n,allowWhileIdle:t}}}},i.active=async function(){return await u("plugin:notification|get_active")},i.cancel=async function(i){await u("plugin:notification|cancel",{notifications:i})},i.cancelAll=async function(){await u("plugin:notification|cancel")},i.channels=async function(){return await u("plugin:notification|listChannels")},i.createChannel=async function(i){await u("plugin:notification|create_channel",{...i})},i.isPermissionGranted=async function(){return"default"!==window.Notification.permission?await Promise.resolve("granted"===window.Notification.permission):await u("plugin:notification|is_permission_granted")},i.onAction=async function(i){return await l("notification","actionPerformed",i)},i.onNotificationReceived=async function(i){return await l("notification","notification",i)},i.pending=async function(){return await u("plugin:notification|get_pending")},i.registerActionTypes=async function(i){await u("plugin:notification|register_action_types",{types:i})},i.removeActive=async function(i){await u("plugin:notification|remove_active",{notifications:i})},i.removeAllActive=async function(){await u("plugin:notification|remove_active")},i.removeChannel=async function(i){await u("plugin:notification|delete_channel",{id:i})},i.requestPermission=async function(){return await window.Notification.requestPermission()},i.sendNotification=function(i){"string"==typeof i?new window.Notification(i):new window.Notification(i.title,i)},i}({});Object.defineProperty(window.__TAURI__,"notification",{value:__TAURI_PLUGIN_NOTIFICATION__})}

@ -9,13 +9,13 @@ window.addEventListener('click', function (evt) {
// return early if
if (
// event was prevented
evt.defaultPrevented ||
evt.defaultPrevented
// or not a left click
evt.button !== 0 ||
|| evt.button !== 0
// or meta key pressed
evt.metaKey ||
|| evt.metaKey
// or al key pressed
evt.altKey
|| evt.altKey
)
return
@ -28,16 +28,16 @@ window.addEventListener('click', function (evt) {
// return early if
if (
// not tirggered from <a> element
!a ||
!a
// or doesn't have a href
!a.href ||
|| !a.href
// or not supposed to be open in a new tab
!(
a.target === '_blank' ||
|| !(
a.target === '_blank'
// or ctrl key pressed
evt.ctrlKey ||
|| evt.ctrlKey
// or shift key pressed
evt.shiftKey
|| evt.shiftKey
)
)
return
@ -47,9 +47,9 @@ window.addEventListener('click', function (evt) {
// return early if
if (
// same origin (internal navigation)
url.origin === window.location.origin ||
url.origin === window.location.origin
// not default protocols
['http:', 'https:', 'mailto:', 'tel:'].every((p) => url.protocol !== p)
|| ['http:', 'https:', 'mailto:', 'tel:'].every((p) => url.protocol !== p)
)
return

@ -31,5 +31,5 @@ log = { workspace = true }
thiserror = { workspace = true }
os_info = "3"
sys-locale = "0.3"
gethostname = "0.5"
gethostname = "1.0"
serialize-to-javascript = "=0.1.1"

@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_SHELL__=function(e){"use strict";function t(e,t,s,i){if("a"===s&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!i:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===s?i:"a"===s?i.call(e):i?i.value:t.get(e)}function s(e,t,s,i,n){if("function"==typeof t||!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 i,n,r;"function"==typeof SuppressedError&&SuppressedError;const o="__TAURI_TO_IPC_KEY__";class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),n.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,n,"f"))for(t(this,i,"f").call(this,e),s(this,n,t(this,n,"f")+1);t(this,n,"f")in t(this,r,"f");){const e=t(this,r,"f")[t(this,n,"f")];t(this,i,"f").call(this,e),delete t(this,r,"f")[t(this,n,"f")],s(this,n,t(this,n,"f")+1)}else t(this,r,"f")[o]=e}))}set onmessage(e){s(this,i,e)}get onmessage(){return t(this,i,"f")}[(i=new WeakMap,n=new WeakMap,r=new WeakMap,o)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[o]()}}async function h(e,t={},s){return window.__TAURI_INTERNALS__.invoke(e,t,s)}class c{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=i=>{this.removeListener(e,s),t(i)};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=i=>{this.removeListener(e,s),t(i)};return this.prependListener(e,s)}}class l{constructor(e){this.pid=e}async write(e){await h("plugin:shell|stdin_write",{pid:this.pid,buffer:e})}async kill(){await h("plugin:shell|kill",{cmd:"killChild",pid:this.pid})}}class u extends c{constructor(e,t=[],s){super(),this.stdout=new c,this.stderr=new c,this.program=e,this.args="string"==typeof t?[t]:t,this.options=s??{}}static create(e,t=[],s){return new u(e,t,s)}static sidecar(e,t=[],s){const i=new u(e,t,s);return i.options.sidecar=!0,i}async spawn(){const e=this.program,t=this.args,s=this.options;"object"==typeof t&&Object.freeze(t);const i=new a;return i.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 h("plugin:shell|spawn",{program:e,args:t,options:s,onEvent:i}).then((e=>new l(e)))}async execute(){const e=this.program,t=this.args,s=this.options;return"object"==typeof t&&Object.freeze(t),await h("plugin:shell|execute",{program:e,args:t,options:s})}}return e.Child=l,e.Command=u,e.EventEmitter=c,e.open=async function(e,t){await h("plugin:shell|open",{path:e,with:t})},e}({});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,i){if("function"==typeof t||!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===s?i:"a"===s?i.call(e):i?i.value:t.get(e)}function s(e,t,s,i,n){if("function"==typeof t||!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 i,n,r;"function"==typeof SuppressedError&&SuppressedError;const o="__TAURI_TO_IPC_KEY__";class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),n.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,n,"f"))for(t(this,i,"f").call(this,e),s(this,n,t(this,n,"f")+1);t(this,n,"f")in t(this,r,"f");){const e=t(this,r,"f")[t(this,n,"f")];t(this,i,"f").call(this,e),delete t(this,r,"f")[t(this,n,"f")],s(this,n,t(this,n,"f")+1)}else t(this,r,"f")[o]=e}))}set onmessage(e){s(this,i,e)}get onmessage(){return t(this,i,"f")}[(i=new WeakMap,n=new WeakMap,r=new WeakMap,o)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[o]()}}async function h(e,t={},s){return window.__TAURI_INTERNALS__.invoke(e,t,s)}class c{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=i=>{this.removeListener(e,s),t(i)};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=i=>{this.removeListener(e,s),t(i)};return this.prependListener(e,s)}}class l{constructor(e){this.pid=e}async write(e){await h("plugin:shell|stdin_write",{pid:this.pid,buffer:e})}async kill(){await h("plugin:shell|kill",{cmd:"killChild",pid:this.pid})}}class u extends c{constructor(e,t=[],s){super(),this.stdout=new c,this.stderr=new c,this.program=e,this.args="string"==typeof t?[t]:t,this.options=s??{}}static create(e,t=[],s){return new u(e,t,s)}static sidecar(e,t=[],s){const i=new u(e,t,s);return i.options.sidecar=!0,i}async spawn(){const e=this.program,t=this.args,s=this.options;"object"==typeof t&&Object.freeze(t);const i=new a;return i.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 h("plugin:shell|spawn",{program:e,args:t,options:s,onEvent:i}).then((e=>new l(e)))}async execute(){const e=this.program,t=this.args,s=this.options;return"object"==typeof t&&Object.freeze(t),await h("plugin:shell|execute",{program:e,args:t,options:s})}}return e.Child=l,e.Command=u,e.EventEmitter=c,e.open=async function(e,t){await h("plugin:shell|open",{path:e,with:t})},e}({});Object.defineProperty(window.__TAURI__,"shell",{value:__TAURI_PLUGIN_SHELL__})}

@ -12,11 +12,11 @@ function openLinks(): void {
if (target.matches('a')) {
const t = target as HTMLAnchorElement
if (
t.href !== '' &&
['http://', 'https://', 'mailto:', 'tel:'].some((v) =>
t.href !== ''
&& ['http://', 'https://', 'mailto:', 'tel:'].some((v) =>
t.href.startsWith(v)
) &&
t.target === '_blank'
)
&& t.target === '_blank'
) {
void invoke('plugin:shell|open', {
path: t.href
@ -31,8 +31,8 @@ function openLinks(): void {
}
if (
document.readyState === 'complete' ||
document.readyState === 'interactive'
document.readyState === 'complete'
|| document.readyState === 'interactive'
) {
openLinks()
} else {

@ -1,5 +1,9 @@
# Changelog
## \[2.2.2]
- [`1ab5f157`](https://github.com/tauri-apps/plugins-workspace/commit/1ab5f1576333174095bc7dad4bef7a8576bb29ab) ([#2452](https://github.com/tauri-apps/plugins-workspace/pull/2452) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Fixed `null pointer dereference` panic on rust nightly on Windows.
## \[2.2.1]
- [`da5c59e2`](https://github.com/tauri-apps/plugins-workspace/commit/da5c59e2fe879d177e3cfd52fcacce85440423cb) ([#2271](https://github.com/tauri-apps/plugins-workspace/pull/2271) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated `zbus` dependency to version 5. No API changes.

@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-single-instance"
version = "2.2.1"
version = "2.2.2"
description = "Ensure a single instance of your tauri app is running."
authors = { workspace = true }
license = { workspace = true }

@ -3,5 +3,5 @@
// SPDX-License-Identifier: MIT
fn main() {
tauri_build::build()
tauri_build::build()
}

@ -1,14 +0,0 @@
max_width = 100
hard_tabs = false
tab_spaces = 2
newline_style = "Auto"
use_small_heuristics = "Default"
reorder_imports = true
reorder_modules = true
remove_nested_parens = true
edition = "2021"
merge_derives = true
use_try_shorthand = false
use_field_init_shorthand = false
force_explicit_abi = true
imports_granularity = "Crate"

@ -3,16 +3,15 @@
// SPDX-License-Identifier: MIT
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_cli::init())
.plugin(tauri_plugin_single_instance::init(|app, argv, cwd| {
println!("{}, {argv:?}, {cwd}", app.package_info().name);
}))
.run(tauri::generate_context!())
.expect("error while running tauri application");
tauri::Builder::default()
.plugin(tauri_plugin_single_instance::init(|app, argv, cwd| {
println!("{}, {argv:?}, {cwd}", app.package_info().name);
}))
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

@ -20,18 +20,38 @@ use windows_sys::Win32::{
},
UI::WindowsAndMessaging::{
self as w32wm, CreateWindowExW, DefWindowProcW, DestroyWindow, FindWindowW,
RegisterClassExW, SendMessageW, GWL_STYLE, GWL_USERDATA, WINDOW_LONG_PTR_INDEX,
WM_COPYDATA, WM_DESTROY, WNDCLASSEXW, WS_EX_LAYERED, WS_EX_NOACTIVATE, WS_EX_TOOLWINDOW,
WS_EX_TRANSPARENT, WS_OVERLAPPED, WS_POPUP, WS_VISIBLE,
RegisterClassExW, SendMessageW, CREATESTRUCTW, GWLP_USERDATA, GWL_STYLE,
WINDOW_LONG_PTR_INDEX, WM_COPYDATA, WM_CREATE, WM_DESTROY, WNDCLASSEXW, WS_EX_LAYERED,
WS_EX_NOACTIVATE, WS_EX_TOOLWINDOW, WS_EX_TRANSPARENT, WS_OVERLAPPED, WS_POPUP, WS_VISIBLE,
},
};
const WMCOPYDATA_SINGLE_INSTANCE_DATA: usize = 1542;
struct MutexHandle(isize);
struct TargetWindowHandle(isize);
const WMCOPYDATA_SINGLE_INSTANCE_DATA: usize = 1542;
struct UserData<R: Runtime> {
app: AppHandle<R>,
callback: Box<SingleInstanceCallback<R>>,
}
impl<R: Runtime> UserData<R> {
unsafe fn from_hwnd_raw(hwnd: HWND) -> *mut Self {
GetWindowLongPtrW(hwnd, GWLP_USERDATA) as *mut Self
}
pub fn init<R: Runtime>(f: Box<SingleInstanceCallback<R>>) -> TauriPlugin<R> {
unsafe fn from_hwnd<'a>(hwnd: HWND) -> &'a mut Self {
&mut *Self::from_hwnd_raw(hwnd)
}
fn run_callback(&mut self, args: Vec<String>, cwd: String) {
(self.callback)(&self.app, args, cwd)
}
}
pub fn init<R: Runtime>(callback: Box<SingleInstanceCallback<R>>) -> TauriPlugin<R> {
plugin::Builder::new("single-instance")
.setup(|app, _api| {
#[allow(unused_mut)]
@ -54,21 +74,22 @@ pub fn init<R: Runtime>(f: Box<SingleInstanceCallback<R>>) -> TauriPlugin<R> {
let hwnd = FindWindowW(class_name.as_ptr(), window_name.as_ptr());
if !hwnd.is_null() {
let data = format!(
"{}|{}\0",
std::env::current_dir()
.unwrap_or_default()
.to_str()
.unwrap_or_default(),
std::env::args().collect::<Vec<String>>().join("|")
);
let cwd = std::env::current_dir().unwrap_or_default();
let cwd = cwd.to_str().unwrap_or_default();
let args = std::env::args().collect::<Vec<String>>().join("|");
let data = format!("{cwd}|{args}\0",);
let bytes = data.as_bytes();
let cds = COPYDATASTRUCT {
dwData: WMCOPYDATA_SINGLE_INSTANCE_DATA,
cbData: bytes.len() as _,
lpData: bytes.as_ptr() as _,
};
SendMessageW(hwnd, WM_COPYDATA, 0, &cds as *const _ as _);
app.cleanup_before_exit();
std::process::exit(0);
}
@ -76,15 +97,12 @@ pub fn init<R: Runtime>(f: Box<SingleInstanceCallback<R>>) -> TauriPlugin<R> {
} else {
app.manage(MutexHandle(hmutex as _));
let hwnd = create_event_target_window::<R>(&class_name, &window_name);
unsafe {
SetWindowLongPtrW(
hwnd,
GWL_USERDATA,
Box::into_raw(Box::new((app.clone(), f))) as _,
)
let userdata = UserData {
app: app.clone(),
callback,
};
let userdata = Box::into_raw(Box::new(userdata));
let hwnd = create_event_target_window::<R>(&class_name, &window_name, userdata);
app.manage(TargetWindowHandle(hwnd as _));
}
@ -116,32 +134,43 @@ unsafe extern "system" fn single_instance_window_proc<R: Runtime>(
wparam: WPARAM,
lparam: LPARAM,
) -> LRESULT {
let data_ptr = GetWindowLongPtrW(hwnd, GWL_USERDATA)
as *mut (AppHandle<R>, Box<SingleInstanceCallback<R>>);
let (app_handle, callback) = &mut *data_ptr;
match msg {
WM_CREATE => {
let create_struct = &*(lparam as *const CREATESTRUCTW);
let userdata = create_struct.lpCreateParams as *const UserData<R>;
SetWindowLongPtrW(hwnd, GWLP_USERDATA, userdata as _);
0
}
WM_COPYDATA => {
let cds_ptr = lparam as *const COPYDATASTRUCT;
if (*cds_ptr).dwData == WMCOPYDATA_SINGLE_INSTANCE_DATA {
let userdata = UserData::<R>::from_hwnd(hwnd);
let data = CStr::from_ptr((*cds_ptr).lpData as _).to_string_lossy();
let mut s = data.split('|');
let cwd = s.next().unwrap();
let args = s.map(|s| s.to_string()).collect();
callback(app_handle, args, cwd.to_string());
userdata.run_callback(args, cwd.to_string());
}
1
}
WM_DESTROY => {
let _ = Box::from_raw(data_ptr);
let userdata = UserData::<R>::from_hwnd_raw(hwnd);
drop(Box::from_raw(userdata));
0
}
_ => DefWindowProcW(hwnd, msg, wparam, lparam),
}
}
fn create_event_target_window<R: Runtime>(class_name: &[u16], window_name: &[u16]) -> HWND {
fn create_event_target_window<R: Runtime>(
class_name: &[u16],
window_name: &[u16],
userdata: *const UserData<R>,
) -> HWND {
unsafe {
let class = WNDCLASSEXW {
cbSize: std::mem::size_of::<WNDCLASSEXW>() as u32,
@ -182,7 +211,7 @@ fn create_event_target_window<R: Runtime>(class_name: &[u16], window_name: &[u16
std::ptr::null_mut(),
std::ptr::null_mut(),
GetModuleHandleW(std::ptr::null()),
std::ptr::null(),
userdata as _,
);
SetWindowLongPtrW(
hwnd,

@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_STORE__=function(t){"use strict";var e,a;function r(t,e=!1){return window.__TAURI_INTERNALS__.transformCallback(t,e)}async function s(t,e={},a){return window.__TAURI_INTERNALS__.invoke(t,e,a)}"function"==typeof SuppressedError&&SuppressedError;class i{get rid(){return function(t,e,a,r){if("a"===a&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!r:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===a?r:"a"===a?r.call(t):r?r.value:e.get(t)}(this,e,"f")}constructor(t){e.set(this,void 0),function(t,e,a){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");e.set(t,a)}(this,e,t)}async close(){return s("plugin:resources|close",{rid:this.rid})}}async function n(t,e,a){const i={kind:"Any"};return s("plugin:event|listen",{event:t,target:i,handler:r(e)}).then((e=>async()=>async function(t,e){await s("plugin:event|unlisten",{event:t,eventId:e})}(t,e)))}async function o(t,e){return await u.load(t,e)}e=new WeakMap,function(t){t.WINDOW_RESIZED="tauri://resize",t.WINDOW_MOVED="tauri://move",t.WINDOW_CLOSE_REQUESTED="tauri://close-requested",t.WINDOW_DESTROYED="tauri://destroyed",t.WINDOW_FOCUS="tauri://focus",t.WINDOW_BLUR="tauri://blur",t.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",t.WINDOW_THEME_CHANGED="tauri://theme-changed",t.WINDOW_CREATED="tauri://window-created",t.WEBVIEW_CREATED="tauri://webview-created",t.DRAG_ENTER="tauri://drag-enter",t.DRAG_OVER="tauri://drag-over",t.DRAG_DROP="tauri://drag-drop",t.DRAG_LEAVE="tauri://drag-leave"}(a||(a={}));class u extends i{constructor(t){super(t)}static async load(t,e){const a=await s("plugin:store|load",{path:t,...e});return new u(a)}static async get(t){return await s("plugin:store|get_store",{path:t}).then((t=>t?new u(t):null))}async set(t,e){await s("plugin:store|set",{rid:this.rid,key:t,value:e})}async get(t){const[e,a]=await s("plugin:store|get",{rid:this.rid,key:t});return a?e:void 0}async has(t){return await s("plugin:store|has",{rid:this.rid,key:t})}async delete(t){return await s("plugin:store|delete",{rid:this.rid,key:t})}async clear(){await s("plugin:store|clear",{rid:this.rid})}async reset(){await s("plugin:store|reset",{rid:this.rid})}async keys(){return await s("plugin:store|keys",{rid:this.rid})}async values(){return await s("plugin:store|values",{rid:this.rid})}async entries(){return await s("plugin:store|entries",{rid:this.rid})}async length(){return await s("plugin:store|length",{rid:this.rid})}async reload(){await s("plugin:store|reload",{rid:this.rid})}async save(){await s("plugin:store|save",{rid:this.rid})}async onKeyChange(t,e){return await n("store://change",(a=>{a.payload.resourceId===this.rid&&a.payload.key===t&&e(a.payload.exists?a.payload.value:void 0)}))}async onChange(t){return await n("store://change",(e=>{e.payload.resourceId===this.rid&&t(e.payload.key,e.payload.exists?e.payload.value:void 0)}))}}return t.LazyStore=class{get store(){return this._store||(this._store=o(this.path,this.options)),this._store}constructor(t,e){this.path=t,this.options=e}async init(){await this.store}async set(t,e){return(await this.store).set(t,e)}async get(t){return(await this.store).get(t)}async has(t){return(await this.store).has(t)}async delete(t){return(await this.store).delete(t)}async clear(){await(await this.store).clear()}async reset(){await(await this.store).reset()}async keys(){return(await this.store).keys()}async values(){return(await this.store).values()}async entries(){return(await this.store).entries()}async length(){return(await this.store).length()}async reload(){await(await this.store).reload()}async save(){await(await this.store).save()}async onKeyChange(t,e){return(await this.store).onKeyChange(t,e)}async onChange(t){return(await this.store).onChange(t)}async close(){this._store&&await(await this._store).close()}},t.Store=u,t.getStore=async function(t){return await u.get(t)},t.load=o,t}({});Object.defineProperty(window.__TAURI__,"store",{value:__TAURI_PLUGIN_STORE__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_STORE__=function(t){"use strict";var e,a;function r(t,e=!1){return window.__TAURI_INTERNALS__.transformCallback(t,e)}async function s(t,e={},a){return window.__TAURI_INTERNALS__.invoke(t,e,a)}"function"==typeof SuppressedError&&SuppressedError;class i{get rid(){return function(t,e,a,r){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===a?r:"a"===a?r.call(t):r?r.value:e.get(t)}(this,e,"f")}constructor(t){e.set(this,void 0),function(t,e,a){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");e.set(t,a)}(this,e,t)}async close(){return s("plugin:resources|close",{rid:this.rid})}}async function n(t,e,a){const i={kind:"Any"};return s("plugin:event|listen",{event:t,target:i,handler:r(e)}).then((e=>async()=>async function(t,e){await s("plugin:event|unlisten",{event:t,eventId:e})}(t,e)))}async function o(t,e){return await u.load(t,e)}e=new WeakMap,function(t){t.WINDOW_RESIZED="tauri://resize",t.WINDOW_MOVED="tauri://move",t.WINDOW_CLOSE_REQUESTED="tauri://close-requested",t.WINDOW_DESTROYED="tauri://destroyed",t.WINDOW_FOCUS="tauri://focus",t.WINDOW_BLUR="tauri://blur",t.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",t.WINDOW_THEME_CHANGED="tauri://theme-changed",t.WINDOW_CREATED="tauri://window-created",t.WEBVIEW_CREATED="tauri://webview-created",t.DRAG_ENTER="tauri://drag-enter",t.DRAG_OVER="tauri://drag-over",t.DRAG_DROP="tauri://drag-drop",t.DRAG_LEAVE="tauri://drag-leave"}(a||(a={}));class u extends i{constructor(t){super(t)}static async load(t,e){const a=await s("plugin:store|load",{path:t,...e});return new u(a)}static async get(t){return await s("plugin:store|get_store",{path:t}).then((t=>t?new u(t):null))}async set(t,e){await s("plugin:store|set",{rid:this.rid,key:t,value:e})}async get(t){const[e,a]=await s("plugin:store|get",{rid:this.rid,key:t});return a?e:void 0}async has(t){return await s("plugin:store|has",{rid:this.rid,key:t})}async delete(t){return await s("plugin:store|delete",{rid:this.rid,key:t})}async clear(){await s("plugin:store|clear",{rid:this.rid})}async reset(){await s("plugin:store|reset",{rid:this.rid})}async keys(){return await s("plugin:store|keys",{rid:this.rid})}async values(){return await s("plugin:store|values",{rid:this.rid})}async entries(){return await s("plugin:store|entries",{rid:this.rid})}async length(){return await s("plugin:store|length",{rid:this.rid})}async reload(){await s("plugin:store|reload",{rid:this.rid})}async save(){await s("plugin:store|save",{rid:this.rid})}async onKeyChange(t,e){return await n("store://change",(a=>{a.payload.resourceId===this.rid&&a.payload.key===t&&e(a.payload.exists?a.payload.value:void 0)}))}async onChange(t){return await n("store://change",(e=>{e.payload.resourceId===this.rid&&t(e.payload.key,e.payload.exists?e.payload.value:void 0)}))}}return t.LazyStore=class{get store(){return this._store||(this._store=o(this.path,this.options)),this._store}constructor(t,e){this.path=t,this.options=e}async init(){await this.store}async set(t,e){return(await this.store).set(t,e)}async get(t){return(await this.store).get(t)}async has(t){return(await this.store).has(t)}async delete(t){return(await this.store).delete(t)}async clear(){await(await this.store).clear()}async reset(){await(await this.store).reset()}async keys(){return(await this.store).keys()}async values(){return(await this.store).values()}async entries(){return(await this.store).entries()}async length(){return(await this.store).length()}async reload(){await(await this.store).reload()}async save(){await(await this.store).save()}async onKeyChange(t,e){return(await this.store).onKeyChange(t,e)}async onChange(t){return(await this.store).onChange(t)}async close(){this._store&&await(await this._store).close()}},t.Store=u,t.getStore=async function(t){return await u.get(t)},t.load=o,t}({});Object.defineProperty(window.__TAURI__,"store",{value:__TAURI_PLUGIN_STORE__})}

@ -1,5 +1,14 @@
# Changelog
## \[2.5.1]
- [`6f881293`](https://github.com/tauri-apps/plugins-workspace/commit/6f881293fcd67838f6f3f8063f536292431dd1f7) ([#2439](https://github.com/tauri-apps/plugins-workspace/pull/2439) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Fixed an issue that caused the plugin to emit a `ReleaseNotFound` error instead of a `Reqwest` error when the http request in `check()` failed.
## \[2.5.0]
- [`5369898d`](https://github.com/tauri-apps/plugins-workspace/commit/5369898db7a6098e3e2f43436100ea556d405628) ([#2067](https://github.com/tauri-apps/plugins-workspace/pull/2067) by [@jLynx](https://github.com/tauri-apps/plugins-workspace/../../jLynx)) Fix update installation on macOS when using an user without admin privileges.
- [`5369898d`](https://github.com/tauri-apps/plugins-workspace/commit/5369898db7a6098e3e2f43436100ea556d405628) ([#2067](https://github.com/tauri-apps/plugins-workspace/pull/2067) by [@jLynx](https://github.com/tauri-apps/plugins-workspace/../../jLynx)) Remove the `UpdaterBuilder::new` function, use `UpdaterExt::updater_builder` instead.
## \[2.4.0]
- [`0afc9b6b`](https://github.com/tauri-apps/plugins-workspace/commit/0afc9b6be07bee1077f05a86285d977e57810ed9) ([#2325](https://github.com/tauri-apps/plugins-workspace/pull/2325) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) The `Update` struct/object will now contain a `raw_json`/`rawJson` property to be able to read parts of server's json response that are not handled by the plugin.

@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-updater"
version = "2.4.0"
version = "2.5.1"
description = "In-app updates for Tauri applications."
edition = { workspace = true }
authors = { workspace = true }
@ -43,7 +43,7 @@ base64 = "0.22"
semver = { version = "1", features = ["serde"] }
futures-util = "0.3"
tempfile = "3"
infer = "0.16"
infer = "0.19"
percent-encoding = "2.3"
[target."cfg(target_os = \"windows\")".dependencies]
@ -62,6 +62,7 @@ flate2 = { version = "1", optional = true }
[target."cfg(target_os = \"macos\")".dependencies]
tar = "0.4"
flate2 = "1"
osakit = { version = "0.3", features = ["full"] }
[features]
default = ["rustls-tls", "zip"]

@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_UPDATER__=function(e){"use strict";function t(e,t,s,i){if("a"===s&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!i:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===s?i:"a"===s?i.call(e):i?i.value:t.get(e)}function s(e,t,s,i,n){if("function"==typeof t||!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 i,n,r,a;"function"==typeof SuppressedError&&SuppressedError;const o="__TAURI_TO_IPC_KEY__";class d{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),n.set(this,0),r.set(this,[]),this.id=function(e,t=!1){return window.__TAURI_INTERNALS__.transformCallback(e,t)}((({message:e,id:a})=>{if(a==t(this,n,"f"))for(t(this,i,"f").call(this,e),s(this,n,t(this,n,"f")+1);t(this,n,"f")in t(this,r,"f");){const e=t(this,r,"f")[t(this,n,"f")];t(this,i,"f").call(this,e),delete t(this,r,"f")[t(this,n,"f")],s(this,n,t(this,n,"f")+1)}else t(this,r,"f")[a]=e}))}set onmessage(e){s(this,i,e)}get onmessage(){return t(this,i,"f")}[(i=new WeakMap,n=new WeakMap,r=new WeakMap,o)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[o]()}}async function l(e,t={},s){return window.__TAURI_INTERNALS__.invoke(e,t,s)}class h{get rid(){return t(this,a,"f")}constructor(e){a.set(this,void 0),s(this,a,e)}async close(){return l("plugin:resources|close",{rid:this.rid})}}a=new WeakMap;class c extends h{constructor(e){super(e.rid),this.available=e.available,this.currentVersion=e.currentVersion,this.version=e.version,this.date=e.date,this.body=e.body,this.rawJson=e.rawJson}async download(e,t){const s=new d;e&&(s.onmessage=e);const i=await l("plugin:updater|download",{onEvent:s,rid:this.rid,...t});this.downloadedBytes=new h(i)}async install(){if(!this.downloadedBytes)throw new Error("Update.install called before Update.download");await l("plugin:updater|install",{updateRid:this.rid,bytesRid:this.downloadedBytes.rid}),this.downloadedBytes=void 0}async downloadAndInstall(e,t){const s=new d;e&&(s.onmessage=e),await l("plugin:updater|download_and_install",{onEvent:s,rid:this.rid,...t})}async close(){await(this.downloadedBytes?.close()),await super.close()}}return e.Update=c,e.check=async function(e){return e?.headers&&(e.headers=Array.from(new Headers(e.headers).entries())),await l("plugin:updater|check",{...e}).then((e=>e.available?new c(e):null))},e}({});Object.defineProperty(window.__TAURI__,"updater",{value:__TAURI_PLUGIN_UPDATER__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_UPDATER__=function(e){"use strict";function t(e,t,s,n){if("function"==typeof t||!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||!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,a,r;"function"==typeof SuppressedError&&SuppressedError;const o="__TAURI_TO_IPC_KEY__";class d{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,n.set(this,(()=>{})),i.set(this,0),a.set(this,[]),this.id=function(e,t=!1){return window.__TAURI_INTERNALS__.transformCallback(e,t)}((({message:e,id:r})=>{if(r==t(this,i,"f"))for(t(this,n,"f").call(this,e),s(this,i,t(this,i,"f")+1);t(this,i,"f")in t(this,a,"f");){const e=t(this,a,"f")[t(this,i,"f")];t(this,n,"f").call(this,e),delete t(this,a,"f")[t(this,i,"f")],s(this,i,t(this,i,"f")+1)}else t(this,a,"f")[r]=e}))}set onmessage(e){s(this,n,e)}get onmessage(){return t(this,n,"f")}[(n=new WeakMap,i=new WeakMap,a=new WeakMap,o)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[o]()}}async function l(e,t={},s){return window.__TAURI_INTERNALS__.invoke(e,t,s)}class h{get rid(){return t(this,r,"f")}constructor(e){r.set(this,void 0),s(this,r,e)}async close(){return l("plugin:resources|close",{rid:this.rid})}}r=new WeakMap;class c extends h{constructor(e){super(e.rid),this.available=e.available,this.currentVersion=e.currentVersion,this.version=e.version,this.date=e.date,this.body=e.body,this.rawJson=e.rawJson}async download(e,t){const s=new d;e&&(s.onmessage=e);const n=await l("plugin:updater|download",{onEvent:s,rid:this.rid,...t});this.downloadedBytes=new h(n)}async install(){if(!this.downloadedBytes)throw new Error("Update.install called before Update.download");await l("plugin:updater|install",{updateRid:this.rid,bytesRid:this.downloadedBytes.rid}),this.downloadedBytes=void 0}async downloadAndInstall(e,t){const s=new d;e&&(s.onmessage=e),await l("plugin:updater|download_and_install",{onEvent:s,rid:this.rid,...t})}async close(){await(this.downloadedBytes?.close()),await super.close()}}return e.Update=c,e.check=async function(e){return e?.headers&&(e.headers=Array.from(new Headers(e.headers).entries())),await l("plugin:updater|check",{...e}).then((e=>e.available?new c(e):null))},e}({});Object.defineProperty(window.__TAURI__,"updater",{value:__TAURI_PLUGIN_UPDATER__})}

@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-updater",
"version": "2.4.0",
"version": "2.5.1",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"

@ -70,7 +70,6 @@ pub trait UpdaterExt<R: Runtime> {
impl<R: Runtime, T: Manager<R>> UpdaterExt<R> for T {
fn updater_builder(&self) -> UpdaterBuilder {
let app = self.app_handle();
let package_info = app.package_info();
let UpdaterState {
config,
target,
@ -78,12 +77,7 @@ impl<R: Runtime, T: Manager<R>> UpdaterExt<R> for T {
headers,
} = self.state::<UpdaterState>().inner();
let mut builder = UpdaterBuilder::new(
package_info.name.clone(),
package_info.version.clone(),
config.clone(),
)
.headers(headers.clone());
let mut builder = UpdaterBuilder::new(app, config.clone()).headers(headers.clone());
if let Some(target) = target {
builder = builder.target(target);

@ -23,7 +23,7 @@ use reqwest::{
};
use semver::Version;
use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize};
use tauri::{utils::platform::current_exe, Resource};
use tauri::{utils::platform::current_exe, AppHandle, Resource, Runtime};
use time::OffsetDateTime;
use url::Url;
@ -94,8 +94,13 @@ impl RemoteRelease {
pub type OnBeforeExit = Arc<dyn Fn() + Send + Sync + 'static>;
pub type VersionComparator = Arc<dyn Fn(Version, RemoteRelease) -> bool + Send + Sync>;
type MainThreadClosure = Box<dyn FnOnce() + Send + Sync + 'static>;
type RunOnMainThread =
Box<dyn Fn(MainThreadClosure) -> std::result::Result<(), tauri::Error> + Send + Sync + 'static>;
pub struct UpdaterBuilder {
#[allow(dead_code)]
run_on_main_thread: RunOnMainThread,
app_name: String,
current_version: Version,
config: Config,
@ -112,18 +117,20 @@ pub struct UpdaterBuilder {
}
impl UpdaterBuilder {
/// It's prefered to use [`crate::UpdaterExt::updater_builder`] instead of
/// constructing a [`UpdaterBuilder`] with this function yourself
pub fn new(app_name: String, current_version: Version, config: crate::Config) -> Self {
pub(crate) fn new<R: Runtime>(app: &AppHandle<R>, config: crate::Config) -> Self {
let app_ = app.clone();
let run_on_main_thread =
move |f: Box<dyn FnOnce() + Send + Sync + 'static>| app_.run_on_main_thread(f);
Self {
run_on_main_thread: Box::new(run_on_main_thread),
installer_args: config
.windows
.as_ref()
.map(|w| w.installer_args.clone())
.unwrap_or_default(),
current_exe_args: Vec::new(),
app_name,
current_version,
app_name: app.package_info().name.clone(),
current_version: app.package_info().version.clone(),
config,
version_comparator: None,
executable_path: None,
@ -259,6 +266,7 @@ impl UpdaterBuilder {
};
Ok(Updater {
run_on_main_thread: Arc::new(self.run_on_main_thread),
config: self.config,
app_name: self.app_name,
current_version: self.current_version,
@ -291,6 +299,8 @@ impl UpdaterBuilder {
}
pub struct Updater {
#[allow(dead_code)]
run_on_main_thread: Arc<RunOnMainThread>,
config: Config,
app_name: String,
current_version: Version,
@ -373,26 +383,29 @@ impl Updater {
.send()
.await;
if let Ok(res) = response {
if res.status().is_success() {
// no updates found!
if StatusCode::NO_CONTENT == res.status() {
return Ok(None);
};
raw_json = Some(res.json().await?);
match serde_json::from_value::<RemoteRelease>(raw_json.clone().unwrap())
.map_err(Into::into)
{
Ok(release) => {
last_error = None;
remote_release = Some(release);
// we found a relase, break the loop
break;
match response {
Ok(res) => {
if res.status().is_success() {
// no updates found!
if StatusCode::NO_CONTENT == res.status() {
return Ok(None);
};
raw_json = Some(res.json().await?);
match serde_json::from_value::<RemoteRelease>(raw_json.clone().unwrap())
.map_err(Into::into)
{
Ok(release) => {
last_error = None;
remote_release = Some(release);
// we found a relase, break the loop
break;
}
Err(err) => last_error = Some(err),
}
Err(err) => last_error = Some(err),
}
}
Err(err) => last_error = Some(err.into()),
}
}
@ -412,6 +425,7 @@ impl Updater {
let update = if should_update {
Some(Update {
run_on_main_thread: self.run_on_main_thread.clone(),
config: self.config.clone(),
on_before_exit: self.on_before_exit.clone(),
app_name: self.app_name.clone(),
@ -440,6 +454,8 @@ impl Updater {
#[derive(Clone)]
pub struct Update {
#[allow(dead_code)]
run_on_main_thread: Arc<RunOnMainThread>,
config: Config,
#[allow(unused)]
on_before_exit: Option<OnBeforeExit>,
@ -1031,42 +1047,85 @@ impl Update {
let cursor = Cursor::new(bytes);
let mut extracted_files: Vec<PathBuf> = Vec::new();
// the first file in the tar.gz will always be
// <app_name>/Contents
let tmp_dir = tempfile::Builder::new()
// Create temp directories for backup and extraction
let tmp_backup_dir = tempfile::Builder::new()
.prefix("tauri_current_app")
.tempdir()?;
// create backup of our current app
std::fs::rename(&self.extract_path, tmp_dir.path())?;
let tmp_extract_dir = tempfile::Builder::new()
.prefix("tauri_updated_app")
.tempdir()?;
let decoder = GzDecoder::new(cursor);
let mut archive = tar::Archive::new(decoder);
std::fs::create_dir(&self.extract_path)?;
// Extract files to temporary directory
for entry in archive.entries()? {
let mut entry = entry?;
// skip the first folder (should be the app name)
let collected_path: PathBuf = entry.path()?.iter().skip(1).collect();
let extraction_path = &self.extract_path.join(collected_path);
// if something went wrong during the extraction, we should restore previous app
if let Err(err) = entry.unpack(extraction_path) {
for file in extracted_files.iter().rev() {
// delete all the files we extracted
if file.is_dir() {
std::fs::remove_dir(file)?;
} else {
std::fs::remove_file(file)?;
}
}
std::fs::rename(tmp_dir.path(), &self.extract_path)?;
let extraction_path = tmp_extract_dir.path().join(&collected_path);
// Ensure parent directories exist
if let Some(parent) = extraction_path.parent() {
std::fs::create_dir_all(parent)?;
}
if let Err(err) = entry.unpack(&extraction_path) {
// Cleanup on error
std::fs::remove_dir_all(tmp_extract_dir.path()).ok();
return Err(err.into());
}
extracted_files.push(extraction_path);
}
// Try to move the current app to backup
let move_result = std::fs::rename(
&self.extract_path,
tmp_backup_dir.path().join("current_app"),
);
let need_authorization = if let Err(err) = move_result {
if err.kind() == std::io::ErrorKind::PermissionDenied {
true
} else {
std::fs::remove_dir_all(tmp_extract_dir.path()).ok();
return Err(err.into());
}
} else {
false
};
extracted_files.push(extraction_path.to_path_buf());
if need_authorization {
// Use AppleScript to perform moves with admin privileges
let apple_script = format!(
"do shell script \"rm -rf '{src}' && mv -f '{new}' '{src}'\" with administrator privileges",
src = self.extract_path.display(),
new = tmp_extract_dir.path().display()
);
let (tx, rx) = std::sync::mpsc::channel();
let res = (self.run_on_main_thread)(Box::new(move || {
let mut script =
osakit::Script::new_from_source(osakit::Language::AppleScript, &apple_script);
script.compile().expect("invalid AppleScript");
let r = script.execute();
tx.send(r).unwrap();
}));
let result = rx.recv().unwrap();
if res.is_err() || result.is_err() {
std::fs::remove_dir_all(tmp_extract_dir.path()).ok();
return Err(Error::Io(std::io::Error::new(
std::io::ErrorKind::PermissionDenied,
"Failed to move the new app into place",
)));
}
} else {
// Remove existing directory if it exists
if self.extract_path.exists() {
std::fs::remove_dir_all(&self.extract_path)?;
}
// Move the new app to the target path
std::fs::rename(tmp_extract_dir.path(), &self.extract_path)?;
}
let _ = std::process::Command::new("touch")

@ -1822,9 +1822,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "openssl"
version = "0.10.66"
version = "0.10.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1"
checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6"
dependencies = [
"bitflags 2.6.0",
"cfg-if",
@ -1854,9 +1854,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
version = "0.9.103"
version = "0.9.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6"
checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc"
dependencies = [
"cc",
"libc",

@ -2,6 +2,10 @@
## \[2.2.1]
- [`ca7395a5`](https://github.com/tauri-apps/plugins-workspace/commit/ca7395a5ce971cbac25fb54285056edf3dd84e1f) ([#2378](https://github.com/tauri-apps/plugins-workspace/pull/2378) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) the `rustls-tls` feature is now enabled by default
## \[2.2.1]
- [`05c62d73`](https://github.com/tauri-apps/plugins-workspace/commit/05c62d731fa48fd06b8cb3694a962d8cb0db8619) ([#1523](https://github.com/tauri-apps/plugins-workspace/pull/1523) by [@enri90](https://github.com/tauri-apps/plugins-workspace/../../enri90)) Added post request on download function
## \[2.2.0]

@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-upload"
version = "2.2.0"
version = "2.2.1"
description = "Upload files from disk to a remote server over HTTP."
authors = { workspace = true }
license = { workspace = true }
@ -32,6 +32,7 @@ thiserror = { workspace = true }
tokio = { version = "1", features = ["fs"] }
tokio-util = { version = "0.7", features = ["codec"] }
reqwest = { version = "0.12", default-features = false, features = [
"macos-system-configuration",
"json",
"stream",
] }
@ -39,6 +40,7 @@ futures-util = "0.3"
read-progress-stream = "1.0.0"
[features]
default = ["rustls-tls"]
native-tls = ["reqwest/native-tls"]
native-tls-vendored = ["reqwest/native-tls-vendored"]
rustls-tls = ["reqwest/rustls-tls"]

@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_UPLOAD__=function(t){"use strict";function e(t,e,n,s){if("a"===n&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?s:"a"===n?s.call(t):s?s.value:e.get(t)}function n(t,e,n,s,i){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(t,n),n}var s,i,o;"function"==typeof SuppressedError&&SuppressedError;const r="__TAURI_TO_IPC_KEY__";class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,s.set(this,(()=>{})),i.set(this,0),o.set(this,[]),this.id=function(t,e=!1){return window.__TAURI_INTERNALS__.transformCallback(t,e)}((({message:t,id:r})=>{if(r==e(this,i,"f"))for(e(this,s,"f").call(this,t),n(this,i,e(this,i,"f")+1);e(this,i,"f")in e(this,o,"f");){const t=e(this,o,"f")[e(this,i,"f")];e(this,s,"f").call(this,t),delete e(this,o,"f")[e(this,i,"f")],n(this,i,e(this,i,"f")+1)}else e(this,o,"f")[r]=t}))}set onmessage(t){n(this,s,t)}get onmessage(){return e(this,s,"f")}[(s=new WeakMap,i=new WeakMap,o=new WeakMap,r)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[r]()}}async function _(t,e={},n){return window.__TAURI_INTERNALS__.invoke(t,e,n)}return t.download=async function(t,e,n,s,i){const o=new Uint32Array(1);window.crypto.getRandomValues(o);const r=o[0],c=new a;n&&(c.onmessage=n),await _("plugin:upload|download",{id:r,url:t,filePath:e,headers:s??{},onProgress:c,body:i})},t.upload=async function(t,e,n,s){const i=new Uint32Array(1);window.crypto.getRandomValues(i);const o=i[0],r=new a;return n&&(r.onmessage=n),await _("plugin:upload|upload",{id:o,url:t,filePath:e,headers:s??{},onProgress:r})},t}({});Object.defineProperty(window.__TAURI__,"upload",{value:__TAURI_PLUGIN_UPLOAD__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_UPLOAD__=function(t){"use strict";function e(t,e,n,s){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?s:"a"===n?s.call(t):s?s.value:e.get(t)}function n(t,e,n,s,i){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(t,n),n}var s,i,o;"function"==typeof SuppressedError&&SuppressedError;const r="__TAURI_TO_IPC_KEY__";class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,s.set(this,(()=>{})),i.set(this,0),o.set(this,[]),this.id=function(t,e=!1){return window.__TAURI_INTERNALS__.transformCallback(t,e)}((({message:t,id:r})=>{if(r==e(this,i,"f"))for(e(this,s,"f").call(this,t),n(this,i,e(this,i,"f")+1);e(this,i,"f")in e(this,o,"f");){const t=e(this,o,"f")[e(this,i,"f")];e(this,s,"f").call(this,t),delete e(this,o,"f")[e(this,i,"f")],n(this,i,e(this,i,"f")+1)}else e(this,o,"f")[r]=t}))}set onmessage(t){n(this,s,t)}get onmessage(){return e(this,s,"f")}[(s=new WeakMap,i=new WeakMap,o=new WeakMap,r)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[r]()}}async function _(t,e={},n){return window.__TAURI_INTERNALS__.invoke(t,e,n)}return t.download=async function(t,e,n,s,i){const o=new Uint32Array(1);window.crypto.getRandomValues(o);const r=o[0],c=new a;n&&(c.onmessage=n),await _("plugin:upload|download",{id:r,url:t,filePath:e,headers:s??{},onProgress:c,body:i})},t.upload=async function(t,e,n,s){const i=new Uint32Array(1);window.crypto.getRandomValues(i);const o=i[0],r=new a;return n&&(r.onmessage=n),await _("plugin:upload|upload",{id:o,url:t,filePath:e,headers:s??{},onProgress:r})},t}({});Object.defineProperty(window.__TAURI__,"upload",{value:__TAURI_PLUGIN_UPLOAD__})}

@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-upload",
"version": "2.2.0",
"version": "2.2.1",
"description": "Upload files from disk to a remote server over HTTP.",
"license": "MIT OR Apache-2.0",
"authors": [

@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_WEBSOCKET__=function(){"use strict";function e(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 t(e,t,s,n,i){if("function"==typeof t||!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 s,n,i;"function"==typeof SuppressedError&&SuppressedError;const r="__TAURI_TO_IPC_KEY__";class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,s.set(this,(()=>{})),n.set(this,0),i.set(this,[]),this.id=function(e,t=!1){return window.__TAURI_INTERNALS__.transformCallback(e,t)}((({message:r,id:a})=>{if(a==e(this,n,"f"))for(e(this,s,"f").call(this,r),t(this,n,e(this,n,"f")+1);e(this,n,"f")in e(this,i,"f");){const r=e(this,i,"f")[e(this,n,"f")];e(this,s,"f").call(this,r),delete e(this,i,"f")[e(this,n,"f")],t(this,n,e(this,n,"f")+1)}else e(this,i,"f")[a]=r}))}set onmessage(e){t(this,s,e)}get onmessage(){return e(this,s,"f")}[(s=new WeakMap,n=new WeakMap,i=new WeakMap,r)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[r]()}}async function o(e,t={},s){return window.__TAURI_INTERNALS__.invoke(e,t,s)}class c{constructor(e,t){this.id=e,this.listeners=t}static async connect(e,t){const s=new Set,n=new a;return n.onmessage=e=>{s.forEach((t=>{t(e)}))},t?.headers&&(t.headers=Array.from(new Headers(t.headers).entries())),await o("plugin:websocket|connect",{url:e,onMessage:n,config:t}).then((e=>new c(e,s)))}addListener(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}async send(e){let t;if("string"==typeof e)t={type:"Text",data:e};else if("object"==typeof e&&"type"in e)t=e;else{if(!Array.isArray(e))throw new Error("invalid `message` type, expected a `{ type: string, data: any }` object, a string or a numeric array");t={type:"Binary",data:e}}await o("plugin:websocket|send",{id:this.id,message:t})}async disconnect(){await this.send({type:"Close",data:{code:1e3,reason:"Disconnected by client"}})}}return c}();Object.defineProperty(window.__TAURI__,"websocket",{value:__TAURI_PLUGIN_WEBSOCKET__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_WEBSOCKET__=function(){"use strict";function e(e,t,s,n){if("function"==typeof t||!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 t(e,t,s,n,i){if("function"==typeof t||!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 s,n,i;"function"==typeof SuppressedError&&SuppressedError;const r="__TAURI_TO_IPC_KEY__";class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,s.set(this,(()=>{})),n.set(this,0),i.set(this,[]),this.id=function(e,t=!1){return window.__TAURI_INTERNALS__.transformCallback(e,t)}((({message:r,id:a})=>{if(a==e(this,n,"f"))for(e(this,s,"f").call(this,r),t(this,n,e(this,n,"f")+1);e(this,n,"f")in e(this,i,"f");){const r=e(this,i,"f")[e(this,n,"f")];e(this,s,"f").call(this,r),delete e(this,i,"f")[e(this,n,"f")],t(this,n,e(this,n,"f")+1)}else e(this,i,"f")[a]=r}))}set onmessage(e){t(this,s,e)}get onmessage(){return e(this,s,"f")}[(s=new WeakMap,n=new WeakMap,i=new WeakMap,r)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[r]()}}async function o(e,t={},s){return window.__TAURI_INTERNALS__.invoke(e,t,s)}class c{constructor(e,t){this.id=e,this.listeners=t}static async connect(e,t){const s=new Set,n=new a;return n.onmessage=e=>{s.forEach((t=>{t(e)}))},t?.headers&&(t.headers=Array.from(new Headers(t.headers).entries())),await o("plugin:websocket|connect",{url:e,onMessage:n,config:t}).then((e=>new c(e,s)))}addListener(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}async send(e){let t;if("string"==typeof e)t={type:"Text",data:e};else if("object"==typeof e&&"type"in e)t=e;else{if(!Array.isArray(e))throw new Error("invalid `message` type, expected a `{ type: string, data: any }` object, a string or a numeric array");t={type:"Binary",data:e}}await o("plugin:websocket|send",{id:this.id,message:t})}async disconnect(){await this.send({type:"Close",data:{code:1e3,reason:"Disconnected by client"}})}}return c}();Object.defineProperty(window.__TAURI__,"websocket",{value:__TAURI_PLUGIN_WEBSOCKET__})}

@ -10,8 +10,9 @@ body {
margin: 0;
padding: 8px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
font-family:
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu,
Cantarell, 'Helvetica Neue', sans-serif;
}
a {

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save