Merge remote-tracking branch 'origin/v2' into feat/http/refactor

pull/428/head
Lucas Nogueira 2 years ago
commit 8778a55116
No known key found for this signature in database
GPG Key ID: FFEA6C72E73482F1

@ -0,0 +1,5 @@
---
"fs-js": patch
---
Fix `writeBinaryFile` crashing with `command 'write_binary_file' not found`

@ -0,0 +1,5 @@
---
"persisted-scope": patch
---
Split up fs and asset scopes. **This will reset the asset protocol scope once!**

@ -0,0 +1,5 @@
---
"persisted-scope": patch
---
Fix usage of directory patterns by removing glob asterisks at the end before allowing/forbidding them. This was causing them to be escaped, and so undesirable paths were allowed/forbidden while polluting the `.persisted-scope` file.

@ -0,0 +1,5 @@
---
"shell": patch
---
Ensure the launched process is detached so it can out-live your tauri app and does not shutdown with it.

@ -0,0 +1,5 @@
---
"stronghold-js": patch
---
Change the argument name of the `Stronghold.remove` from `location` to `recordPath` to match the Stronghold command argument

@ -116,6 +116,6 @@ if (files.length > 0) {
console.log(missing.join("\n")); console.log(missing.join("\n"));
process.exit(1); process.exit(1);
} }
} },
); );
} }

@ -52,7 +52,7 @@ https.get(url, options, (response) => {
} }
} else if (kind === "npm") { } else if (kind === "npm") {
const versions = Object.keys(data.versions || {}).filter((v) => const versions = Object.keys(data.versions || {}).filter((v) =>
v.startsWith(target) v.startsWith(target),
); );
console.log(versions[versions.length - 1] || "0.0.0"); console.log(versions[versions.length - 1] || "0.0.0");
} }

406
Cargo.lock generated

@ -96,6 +96,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"getrandom 0.2.9",
"once_cell", "once_cell",
"version_check", "version_check",
] ]
@ -269,7 +270,7 @@ dependencies = [
"objc-foundation", "objc-foundation",
"objc_id", "objc_id",
"once_cell", "once_cell",
"parking_lot 0.12.1", "parking_lot",
"thiserror", "thiserror",
"winapi", "winapi",
"x11rb", "x11rb",
@ -469,9 +470,9 @@ dependencies = [
[[package]] [[package]]
name = "atoi" name = "atoi"
version = "1.0.0" version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
dependencies = [ dependencies = [
"num-traits", "num-traits",
] ]
@ -571,6 +572,9 @@ name = "bitflags"
version = "2.3.1" version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6776fc96284a0bb647b615056fc496d1fe1644a7ab01829818a6d91cae888b84" checksum = "6776fc96284a0bb647b615056fc496d1fe1644a7ab01829818a6d91cae888b84"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "blake2" name = "blake2"
@ -974,9 +978,9 @@ dependencies = [
[[package]] [[package]]
name = "const-oid" name = "const-oid"
version = "0.7.1" version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" checksum = "6340df57935414636969091153f35f68d9f00bbc8fb4a9c6054706c213e6c6bc"
[[package]] [[package]]
name = "constant_time_eq" name = "constant_time_eq"
@ -1127,16 +1131,6 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "crypto-bigint"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21"
dependencies = [
"generic-array",
"subtle",
]
[[package]] [[package]]
name = "crypto-common" name = "crypto-common"
version = "0.1.6" version = "0.1.6"
@ -1265,13 +1259,13 @@ checksum = "41b319d1b62ffbd002e057f36bebd1f42b9f97927c9577461d855f3513c4289f"
[[package]] [[package]]
name = "der" name = "der"
version = "0.5.1" version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946"
dependencies = [ dependencies = [
"const-oid", "const-oid",
"crypto-bigint",
"pem-rfc7468", "pem-rfc7468",
"zeroize",
] ]
[[package]] [[package]]
@ -1324,6 +1318,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [ dependencies = [
"block-buffer 0.10.4", "block-buffer 0.10.4",
"const-oid",
"crypto-common", "crypto-common",
"subtle", "subtle",
] ]
@ -1421,6 +1416,9 @@ name = "either"
version = "1.8.1" version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "embed-resource" name = "embed-resource"
@ -1493,6 +1491,12 @@ dependencies = [
"regex", "regex",
] ]
[[package]]
name = "equivalent"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1"
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.1" version = "0.3.1"
@ -1524,6 +1528,17 @@ dependencies = [
"str-buf", "str-buf",
] ]
[[package]]
name = "etcetera"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943"
dependencies = [
"cfg-if",
"home",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "event-listener" name = "event-listener"
version = "2.5.3" version = "2.5.3"
@ -1695,13 +1710,13 @@ dependencies = [
[[package]] [[package]]
name = "futures-intrusive" name = "futures-intrusive"
version = "0.4.2" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"lock_api", "lock_api",
"parking_lot 0.11.2", "parking_lot",
] ]
[[package]] [[package]]
@ -2139,7 +2154,7 @@ dependencies = [
"futures-sink", "futures-sink",
"futures-util", "futures-util",
"http", "http",
"indexmap", "indexmap 1.9.3",
"slab", "slab",
"tokio", "tokio",
"tokio-util", "tokio-util",
@ -2192,6 +2207,12 @@ dependencies = [
"ahash 0.8.3", "ahash 0.8.3",
] ]
[[package]]
name = "hashbrown"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
[[package]] [[package]]
name = "hashlink" name = "hashlink"
version = "0.8.2" version = "0.8.2"
@ -2267,6 +2288,15 @@ dependencies = [
"digest 0.10.7", "digest 0.10.7",
] ]
[[package]]
name = "home"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
dependencies = [
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "hostname" name = "hostname"
version = "0.3.1" version = "0.3.1"
@ -2364,9 +2394,9 @@ checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7"
dependencies = [ dependencies = [
"http", "http",
"hyper", "hyper",
"rustls 0.21.1", "rustls",
"tokio", "tokio",
"tokio-rustls 0.24.0", "tokio-rustls",
] ]
[[package]] [[package]]
@ -2505,6 +2535,16 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "indexmap"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
dependencies = [
"equivalent",
"hashbrown 0.14.0",
]
[[package]] [[package]]
name = "infer" name = "infer"
version = "0.9.0" version = "0.9.0"
@ -2600,9 +2640,9 @@ dependencies = [
[[package]] [[package]]
name = "iota-crypto" name = "iota-crypto"
version = "0.20.1" version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb2df6763689b6e2b95787941eb9a58b29d16d17c2055392f550b3daf40bdce" checksum = "c5d5a986d972c3a703d48ced24fdc0bf16fb2d02959ff4b152fa77b9132f6fb0"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]
@ -2886,9 +2926,9 @@ dependencies = [
[[package]] [[package]]
name = "libsqlite3-sys" name = "libsqlite3-sys"
version = "0.24.2" version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326"
dependencies = [ dependencies = [
"cc", "cc",
"pkg-config", "pkg-config",
@ -3299,17 +3339,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "num-bigint"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]] [[package]]
name = "num-bigint-dig" name = "num-bigint-dig"
version = "0.8.2" version = "0.8.2"
@ -3462,11 +3491,12 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]] [[package]]
name = "open" name = "open"
version = "4.1.0" version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d16814a067484415fda653868c9be0ac5f2abd2ef5d951082a5f2fe1b3662944" checksum = "3a083c0c7e5e4a8ec4176346cf61f67ac674e8bfb059d9226e1c54a96b377c12"
dependencies = [ dependencies = [
"is-wsl", "is-wsl",
"libc",
"pathdiff", "pathdiff",
] ]
@ -3593,17 +3623,6 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e"
[[package]]
name = "parking_lot"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
dependencies = [
"instant",
"lock_api",
"parking_lot_core 0.8.6",
]
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.1" version = "0.12.1"
@ -3611,21 +3630,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [ dependencies = [
"lock_api", "lock_api",
"parking_lot_core 0.9.7", "parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
dependencies = [
"cfg-if",
"instant",
"libc",
"redox_syscall 0.2.16",
"smallvec",
"winapi",
] ]
[[package]] [[package]]
@ -3664,9 +3669,9 @@ dependencies = [
[[package]] [[package]]
name = "pem-rfc7468" name = "pem-rfc7468"
version = "0.3.1" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01de5d978f34aa4b2296576379fcc416034702fd94117c56ffd8a1a767cefb30" checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
dependencies = [ dependencies = [
"base64ct", "base64ct",
] ]
@ -3809,24 +3814,23 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]] [[package]]
name = "pkcs1" name = "pkcs1"
version = "0.3.3" version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a78f66c04ccc83dd4486fd46c33896f4e17b24a7a3a6400dedc48ed0ddd72320" checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
dependencies = [ dependencies = [
"der", "der",
"pkcs8", "pkcs8",
"zeroize", "spki",
] ]
[[package]] [[package]]
name = "pkcs8" name = "pkcs8"
version = "0.8.0" version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
dependencies = [ dependencies = [
"der", "der",
"spki", "spki",
"zeroize",
] ]
[[package]] [[package]]
@ -3842,7 +3846,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bd9647b268a3d3e14ff09c23201133a62589c658db02bb7388c7246aafe0590" checksum = "9bd9647b268a3d3e14ff09c23201133a62589c658db02bb7388c7246aafe0590"
dependencies = [ dependencies = [
"base64 0.21.2", "base64 0.21.2",
"indexmap", "indexmap 1.9.3",
"line-wrap", "line-wrap",
"quick-xml 0.28.2", "quick-xml 0.28.2",
"serde", "serde",
@ -4025,7 +4029,7 @@ dependencies = [
"quinn-proto", "quinn-proto",
"quinn-udp", "quinn-udp",
"rustc-hash", "rustc-hash",
"rustls 0.21.1", "rustls",
"thiserror", "thiserror",
"tokio", "tokio",
"tracing", "tracing",
@ -4041,7 +4045,7 @@ dependencies = [
"rand 0.8.5", "rand 0.8.5",
"ring", "ring",
"rustc-hash", "rustc-hash",
"rustls 0.21.1", "rustls",
"slab", "slab",
"thiserror", "thiserror",
"tinyvec", "tinyvec",
@ -4262,7 +4266,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"quinn", "quinn",
"rustls 0.21.1", "rustls",
"rustls-native-certs", "rustls-native-certs",
"rustls-pemfile", "rustls-pemfile",
"serde", "serde",
@ -4270,7 +4274,7 @@ dependencies = [
"serde_urlencoded", "serde_urlencoded",
"tokio", "tokio",
"tokio-native-tls", "tokio-native-tls",
"tokio-rustls 0.24.0", "tokio-rustls",
"tokio-socks", "tokio-socks",
"tokio-util", "tokio-util",
"tower-service", "tower-service",
@ -4336,11 +4340,12 @@ dependencies = [
[[package]] [[package]]
name = "rsa" name = "rsa"
version = "0.6.1" version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cf22754c49613d2b3b119f0e5d46e34a2c628a937e3024b8762de4e7d8c710b" checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"const-oid",
"digest 0.10.7", "digest 0.10.7",
"num-bigint-dig", "num-bigint-dig",
"num-integer", "num-integer",
@ -4349,7 +4354,8 @@ dependencies = [
"pkcs1", "pkcs1",
"pkcs8", "pkcs8",
"rand_core 0.6.4", "rand_core 0.6.4",
"smallvec", "signature",
"spki",
"subtle", "subtle",
"zeroize", "zeroize",
] ]
@ -4401,18 +4407,6 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "rustls"
version = "0.20.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f"
dependencies = [
"log",
"ring",
"sct",
"webpki",
]
[[package]] [[package]]
name = "rustls" name = "rustls"
version = "0.21.1" version = "0.21.1"
@ -4650,7 +4644,7 @@ dependencies = [
"base64 0.21.2", "base64 0.21.2",
"chrono", "chrono",
"hex", "hex",
"indexmap", "indexmap 1.9.3",
"serde", "serde",
"serde_json", "serde_json",
"serde_with_macros", "serde_with_macros",
@ -4755,6 +4749,16 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "signature"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500"
dependencies = [
"digest 0.10.7",
"rand_core 0.6.4",
]
[[package]] [[package]]
name = "simd-adler32" name = "simd-adler32"
version = "0.3.5" version = "0.3.5"
@ -4853,9 +4857,9 @@ dependencies = [
[[package]] [[package]]
name = "spki" name = "spki"
version = "0.5.4" version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a"
dependencies = [ dependencies = [
"base64ct", "base64ct",
"der", "der",
@ -4874,104 +4878,204 @@ dependencies = [
[[package]] [[package]]
name = "sqlx" name = "sqlx"
version = "0.6.3" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" checksum = "91ef53c86d2066e04f0ac6b1364f16d13d82388e2d07f11a5c71782345555761"
dependencies = [ dependencies = [
"sqlx-core", "sqlx-core",
"sqlx-macros", "sqlx-macros",
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
] ]
[[package]] [[package]]
name = "sqlx-core" name = "sqlx-core"
version = "0.6.3" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" checksum = "8a22fd81e9c1ad53c562edb869ff042b215d4eadefefc4784bacfbfd19835945"
dependencies = [ dependencies = [
"ahash 0.7.6", "ahash 0.8.3",
"atoi", "atoi",
"base64 0.13.1",
"bitflags 1.3.2",
"byteorder", "byteorder",
"bytes 1.4.0", "bytes 1.4.0",
"crc", "crc",
"crossbeam-queue", "crossbeam-queue",
"digest 0.10.7",
"dirs",
"dotenvy", "dotenvy",
"either", "either",
"event-listener", "event-listener",
"flume",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-executor",
"futures-intrusive", "futures-intrusive",
"futures-io",
"futures-util", "futures-util",
"generic-array",
"hashlink", "hashlink",
"hex", "hex",
"hkdf", "indexmap 2.0.0",
"hmac",
"indexmap",
"itoa 1.0.6",
"libc",
"libsqlite3-sys",
"log", "log",
"md-5",
"memchr", "memchr",
"num-bigint",
"once_cell", "once_cell",
"paste", "paste",
"percent-encoding", "percent-encoding",
"rand 0.8.5", "rustls",
"rsa",
"rustls 0.20.8",
"rustls-pemfile", "rustls-pemfile",
"serde", "serde",
"serde_json", "serde_json",
"sha1",
"sha2 0.10.6", "sha2 0.10.6",
"smallvec", "smallvec",
"sqlformat", "sqlformat",
"sqlx-rt",
"stringprep",
"thiserror", "thiserror",
"time 0.3.21", "time 0.3.21",
"tokio",
"tokio-stream", "tokio-stream",
"tracing",
"url", "url",
"webpki-roots 0.22.6", "webpki-roots 0.23.0",
"whoami",
] ]
[[package]] [[package]]
name = "sqlx-macros" name = "sqlx-macros"
version = "0.6.3" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00bb7c096a202b8164c175614cbfb79fe0e1e0a3d50e0374526183ef2974e4a2"
dependencies = [
"proc-macro2",
"quote",
"sqlx-core",
"sqlx-macros-core",
"syn 1.0.109",
]
[[package]]
name = "sqlx-macros-core"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" checksum = "37d644623ab9699014e5b3cb61a040d16caa50fd477008f63f1399ae35498a58"
dependencies = [ dependencies = [
"dotenvy", "dotenvy",
"either", "either",
"heck 0.4.1", "heck 0.4.1",
"hex",
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde",
"serde_json", "serde_json",
"sha2 0.10.6", "sha2 0.10.6",
"sqlx-core", "sqlx-core",
"sqlx-rt", "sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
"syn 1.0.109", "syn 1.0.109",
"tempfile",
"tokio",
"url", "url",
] ]
[[package]] [[package]]
name = "sqlx-rt" name = "sqlx-mysql"
version = "0.6.3" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" checksum = "8264c59b28b6858796acfcedc660aa4c9075cc6e4ec8eb03cdca2a3e725726db"
dependencies = [ dependencies = [
"atoi",
"base64 0.21.2",
"bitflags 2.3.1",
"byteorder",
"bytes 1.4.0",
"crc",
"digest 0.10.7",
"dotenvy",
"either",
"futures-channel",
"futures-core",
"futures-io",
"futures-util",
"generic-array",
"hex",
"hkdf",
"hmac",
"itoa 1.0.6",
"log",
"md-5",
"memchr",
"once_cell", "once_cell",
"tokio", "percent-encoding",
"tokio-rustls 0.23.4", "rand 0.8.5",
"rsa",
"serde",
"sha1",
"sha2 0.10.6",
"smallvec",
"sqlx-core",
"stringprep",
"thiserror",
"time 0.3.21",
"tracing",
"whoami",
]
[[package]]
name = "sqlx-postgres"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cab6147b81ca9213a7578f1b4c9d24c449a53953cd2222a7b5d7cd29a5c3139"
dependencies = [
"atoi",
"base64 0.21.2",
"bitflags 2.3.1",
"byteorder",
"crc",
"dotenvy",
"etcetera",
"futures-channel",
"futures-core",
"futures-io",
"futures-util",
"hex",
"hkdf",
"hmac",
"home",
"itoa 1.0.6",
"log",
"md-5",
"memchr",
"once_cell",
"rand 0.8.5",
"serde",
"serde_json",
"sha1",
"sha2 0.10.6",
"smallvec",
"sqlx-core",
"stringprep",
"thiserror",
"time 0.3.21",
"tracing",
"whoami",
]
[[package]]
name = "sqlx-sqlite"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59fba60afa64718104b71eec6984f8779d4caffff3b30cde91a75843c7efc126"
dependencies = [
"atoi",
"flume",
"futures-channel",
"futures-core",
"futures-executor",
"futures-intrusive",
"futures-util",
"libsqlite3-sys",
"log",
"percent-encoding",
"serde",
"sqlx-core",
"time 0.3.21",
"tracing",
"url",
] ]
[[package]] [[package]]
@ -5009,7 +5113,7 @@ checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b"
dependencies = [ dependencies = [
"new_debug_unreachable", "new_debug_unreachable",
"once_cell", "once_cell",
"parking_lot 0.12.1", "parking_lot",
"phf_shared 0.10.0", "phf_shared 0.10.0",
"precomputed-hash", "precomputed-hash",
"serde", "serde",
@ -5220,7 +5324,7 @@ dependencies = [
"ndk-sys", "ndk-sys",
"objc", "objc",
"once_cell", "once_cell",
"parking_lot 0.12.1", "parking_lot",
"png", "png",
"raw-window-handle", "raw-window-handle",
"scopeguard", "scopeguard",
@ -5652,7 +5756,7 @@ name = "tauri-plugin-stronghold"
version = "2.0.0-alpha.0" version = "2.0.0-alpha.0"
dependencies = [ dependencies = [
"hex", "hex",
"iota-crypto 0.20.1", "iota-crypto 0.23.0",
"iota_stronghold", "iota_stronghold",
"log", "log",
"rand 0.8.5", "rand 0.8.5",
@ -6017,24 +6121,13 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "tokio-rustls"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
dependencies = [
"rustls 0.20.8",
"tokio",
"webpki",
]
[[package]] [[package]]
name = "tokio-rustls" name = "tokio-rustls"
version = "0.24.0" version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5" checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5"
dependencies = [ dependencies = [
"rustls 0.21.1", "rustls",
"tokio", "tokio",
] ]
@ -6083,10 +6176,10 @@ dependencies = [
"futures-util", "futures-util",
"log", "log",
"native-tls", "native-tls",
"rustls 0.21.1", "rustls",
"tokio", "tokio",
"tokio-native-tls", "tokio-native-tls",
"tokio-rustls 0.24.0", "tokio-rustls",
"tungstenite", "tungstenite",
"webpki-roots 0.23.0", "webpki-roots 0.23.0",
] ]
@ -6132,7 +6225,7 @@ version = "0.19.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739"
dependencies = [ dependencies = [
"indexmap", "indexmap 1.9.3",
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
@ -6152,6 +6245,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"log",
"pin-project-lite", "pin-project-lite",
"tracing-attributes", "tracing-attributes",
"tracing-core", "tracing-core",
@ -6252,7 +6346,7 @@ dependencies = [
"ipconfig", "ipconfig",
"lazy_static", "lazy_static",
"lru-cache", "lru-cache",
"parking_lot 0.12.1", "parking_lot",
"resolv-conf", "resolv-conf",
"smallvec", "smallvec",
"thiserror", "thiserror",
@ -6281,7 +6375,7 @@ dependencies = [
"log", "log",
"native-tls", "native-tls",
"rand 0.8.5", "rand 0.8.5",
"rustls 0.21.1", "rustls",
"sha1", "sha1",
"thiserror", "thiserror",
"url", "url",
@ -6746,10 +6840,6 @@ name = "whoami"
version = "1.4.0" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c70234412ca409cc04e864e89523cb0fc37f5e1344ebed5a3ebf4192b6b9f68" checksum = "2c70234412ca409cc04e864e89523cb0fc37f5e1344ebed5a3ebf4192b6b9f68"
dependencies = [
"wasm-bindgen",
"web-sys",
]
[[package]] [[package]]
name = "widestring" name = "widestring"

@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en" theme="dark"> <html lang="en" theme="dark">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />

@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />

@ -4,7 +4,7 @@ publish = false
version = "2.0.0-alpha.1" version = "2.0.0-alpha.1"
description = "An example Tauri Application showcasing the api" description = "An example Tauri Application showcasing the api"
edition = "2021" edition = "2021"
rust-version = "1.65" rust-version = { workspace = true }
license = "Apache-2.0 OR MIT" license = "Apache-2.0 OR MIT"
[lib] [lib]

@ -10,24 +10,28 @@
"format-check": "prettier --check ." "format-check": "prettier --check ."
}, },
"devDependencies": { "devDependencies": {
"@rollup/plugin-node-resolve": "^15.1.0", "@rollup/plugin-node-resolve": "15.1.0",
"@rollup/plugin-terser": "^0.4.3", "@rollup/plugin-terser": "0.4.3",
"@rollup/plugin-typescript": "^11.1.1", "@rollup/plugin-typescript": "11.1.2",
"@typescript-eslint/eslint-plugin": "^5.59.11", "@typescript-eslint/eslint-plugin": "6.1.0",
"@typescript-eslint/parser": "^5.59.11", "@typescript-eslint/parser": "6.1.0",
"covector": "^0.9.0", "covector": "^0.9.0",
"eslint": "^8.43.0", "eslint": "8.45.0",
"eslint-config-prettier": "^8.8.0", "eslint-config-prettier": "8.8.0",
"eslint-config-standard-with-typescript": "^35.0.0", "eslint-config-standard-with-typescript": "36.1.0",
"eslint-plugin-import": "^2.27.5", "eslint-plugin-import": "2.27.5",
"eslint-plugin-n": "^16.0.0", "eslint-plugin-n": "16.0.1",
"eslint-plugin-promise": "^6.1.1", "eslint-plugin-promise": "6.1.1",
"eslint-plugin-security": "^1.7.1", "eslint-plugin-security": "1.7.1",
"prettier": "^2.8.8", "prettier": "3.0.0",
"rollup": "^3.25.1", "rollup": "3.26.3",
"typescript": "^5.1.3" "typescript": "5.1.6"
},
"resolutions": {
"semver": ">=7.5.2",
"optionator": ">=0.9.3"
}, },
"engines": { "engines": {
"pnpm": ">=7.33.0" "pnpm": ">=7.33.1"
} }
} }

@ -1,4 +1,4 @@
![plugin-app](banner.png) ![plugin-app](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/app/banner.png)
This plugin provides APIs to read application metadata and macOS app visibility functions. This plugin provides APIs to read application metadata and macOS app visibility functions.

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-authenticator](banner.png) ![plugin-authenticator](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/authenticator/banner.png)
Use hardware security-keys in your Tauri App. Use hardware security-keys in your Tauri App.
@ -93,7 +93,7 @@ const r2 = await auth.verifyRegistration(
challenge, challenge,
app, app,
registerResult.registerData, registerResult.registerData,
registerResult.clientData registerResult.clientData,
); );
const j2 = JSON.parse(r2); const j2 = JSON.parse(r2);
@ -108,7 +108,7 @@ const counter = await auth.verifySignature(
signData.signData, signData.signData,
clientData, clientData,
keyHandle, keyHandle,
pubkey pubkey,
); );
if (counter && counter > 0) { if (counter && counter > 0) {

@ -25,7 +25,7 @@ export class Authenticator {
challenge: string, challenge: string,
application: string, application: string,
registerData: string, registerData: string,
clientData: string clientData: string,
): Promise<string> { ): Promise<string> {
return await window.__TAURI_INVOKE__( return await window.__TAURI_INVOKE__(
"plugin:authenticator|verify_registration", "plugin:authenticator|verify_registration",
@ -34,14 +34,14 @@ export class Authenticator {
application, application,
registerData, registerData,
clientData, clientData,
} },
); );
} }
async sign( async sign(
challenge: string, challenge: string,
application: string, application: string,
keyHandle: string keyHandle: string,
): Promise<string> { ): Promise<string> {
return await window.__TAURI_INVOKE__("plugin:authenticator|sign", { return await window.__TAURI_INVOKE__("plugin:authenticator|sign", {
timeout: 10000, timeout: 10000,
@ -57,7 +57,7 @@ export class Authenticator {
signData: string, signData: string,
clientData: string, clientData: string,
keyHandle: string, keyHandle: string,
pubkey: string pubkey: string,
): Promise<number> { ): Promise<number> {
return await window.__TAURI_INVOKE__( return await window.__TAURI_INVOKE__(
"plugin:authenticator|verify_signature", "plugin:authenticator|verify_signature",
@ -68,7 +68,7 @@ export class Authenticator {
clientData, clientData,
keyHandle, keyHandle,
pubkey, pubkey,
} },
); );
} }
} }

@ -25,7 +25,7 @@
"LICENSE" "LICENSE"
], ],
"devDependencies": { "devDependencies": {
"tslib": "^2.5.0" "tslib": "2.6.0"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.0.0-alpha.5" "@tauri-apps/api": "2.0.0-alpha.5"

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-autostart](banner.png) ![plugin-autostart](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/autostart/banner.png)
Automatically launch your application at startup. Supports Windows, Mac (via AppleScript or Launch Agent), and Linux. Automatically launch your application at startup. Supports Windows, Mac (via AppleScript or Launch Agent), and Linux.

@ -24,7 +24,7 @@
"LICENSE" "LICENSE"
], ],
"devDependencies": { "devDependencies": {
"tslib": "^2.5.0" "tslib": "2.6.0"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.0.0-alpha.5" "@tauri-apps/api": "2.0.0-alpha.5"

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-cli](banner.png) ![plugin-cli](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/cli/banner.png)
Parse arguments from your Command Line Interface. Parse arguments from your Command Line Interface.

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-clipboard-manager](banner.png) ![plugin-clipboard-manager](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/clipboard-manager/banner.png)
Read and write to the system clipboard. Read and write to the system clipboard.

@ -36,7 +36,7 @@ type ClipResponse = Clip<"PlainText", string>;
*/ */
async function writeText( async function writeText(
text: string, text: string,
opts?: { label?: string } opts?: { label?: string },
): Promise<void> { ): Promise<void> {
return window.__TAURI_INVOKE__("plugin:clipboard|write", { return window.__TAURI_INVOKE__("plugin:clipboard|write", {
data: { data: {
@ -60,7 +60,7 @@ async function writeText(
*/ */
async function readText(): Promise<string> { async function readText(): Promise<string> {
const kind: ClipResponse = await window.__TAURI_INVOKE__( const kind: ClipResponse = await window.__TAURI_INVOKE__(
"plugin:clipboard|read" "plugin:clipboard|read",
); );
return kind.options; return kind.options;
} }

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-dialog](banner.png) ![plugin-dialog](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/dialog/banner.png)
Native system dialogs for opening and saving files along with message dialogs. Native system dialogs for opening and saving files along with message dialogs.

@ -103,16 +103,16 @@ interface ConfirmDialogOptions {
} }
async function open( async function open(
options?: OpenDialogOptions & { multiple?: false; directory?: false } options?: OpenDialogOptions & { multiple?: false; directory?: false },
): Promise<null | FileResponse>; ): Promise<null | FileResponse>;
async function open( async function open(
options?: OpenDialogOptions & { multiple?: true; directory?: false } options?: OpenDialogOptions & { multiple?: true; directory?: false },
): Promise<null | FileResponse[]>; ): Promise<null | FileResponse[]>;
async function open( async function open(
options?: OpenDialogOptions & { multiple?: false; directory?: true } options?: OpenDialogOptions & { multiple?: false; directory?: true },
): Promise<null | string>; ): Promise<null | string>;
async function open( async function open(
options?: OpenDialogOptions & { multiple?: true; directory?: true } options?: OpenDialogOptions & { multiple?: true; directory?: true },
): Promise<null | string[]>; ): Promise<null | string[]>;
/** /**
* Open a file/directory selection dialog. * Open a file/directory selection dialog.
@ -125,7 +125,7 @@ async function open(
* You can save it to the filesystem using [tauri-plugin-persisted-scope](https://github.com/tauri-apps/tauri-plugin-persisted-scope). * You can save it to the filesystem using [tauri-plugin-persisted-scope](https://github.com/tauri-apps/tauri-plugin-persisted-scope).
* @example * @example
* ```typescript * ```typescript
* import { open } from '@tauri-apps/api/dialog'; * import { open } from '@tauri-apps/plugin-dialog';
* // Open a selection dialog for image files * // Open a selection dialog for image files
* const selected = await open({ * const selected = await open({
* multiple: true, * multiple: true,
@ -145,7 +145,7 @@ async function open(
* *
* @example * @example
* ```typescript * ```typescript
* import { open } from '@tauri-apps/api/dialog'; * import { open } from '@tauri-apps/plugin-dialog';
* import { appDir } from '@tauri-apps/api/path'; * import { appDir } from '@tauri-apps/api/path';
* // Open a selection dialog for directories * // Open a selection dialog for directories
* const selected = await open({ * const selected = await open({
@ -167,7 +167,7 @@ async function open(
* @since 2.0.0 * @since 2.0.0
*/ */
async function open( async function open(
options: OpenDialogOptions = {} options: OpenDialogOptions = {},
): Promise<null | string | string[] | FileResponse | FileResponse[]> { ): Promise<null | string | string[] | FileResponse | FileResponse[]> {
if (typeof options === "object") { if (typeof options === "object") {
Object.freeze(options); Object.freeze(options);
@ -187,7 +187,7 @@ async function open(
* You can save it to the filesystem using [tauri-plugin-persisted-scope](https://github.com/tauri-apps/tauri-plugin-persisted-scope). * You can save it to the filesystem using [tauri-plugin-persisted-scope](https://github.com/tauri-apps/tauri-plugin-persisted-scope).
* @example * @example
* ```typescript * ```typescript
* import { save } from '@tauri-apps/api/dialog'; * import { save } from '@tauri-apps/plugin-dialog';
* const filePath = await save({ * const filePath = await save({
* filters: [{ * filters: [{
* name: 'Image', * name: 'Image',
@ -212,7 +212,7 @@ async function save(options: SaveDialogOptions = {}): Promise<string | null> {
* Shows a message dialog with an `Ok` button. * Shows a message dialog with an `Ok` button.
* @example * @example
* ```typescript * ```typescript
* import { message } from '@tauri-apps/api/dialog'; * import { message } from '@tauri-apps/plugin-dialog';
* await message('Tauri is awesome', 'Tauri'); * await message('Tauri is awesome', 'Tauri');
* await message('File not found', { title: 'Tauri', type: 'error' }); * await message('File not found', { title: 'Tauri', type: 'error' });
* ``` * ```
@ -227,7 +227,7 @@ async function save(options: SaveDialogOptions = {}): Promise<string | null> {
*/ */
async function message( async function message(
message: string, message: string,
options?: string | MessageDialogOptions options?: string | MessageDialogOptions,
): Promise<void> { ): Promise<void> {
const opts = typeof options === "string" ? { title: options } : options; const opts = typeof options === "string" ? { title: options } : options;
return window.__TAURI_INVOKE__("plugin:dialog|message", { return window.__TAURI_INVOKE__("plugin:dialog|message", {
@ -242,7 +242,7 @@ async function message(
* Shows a question dialog with `Yes` and `No` buttons. * Shows a question dialog with `Yes` and `No` buttons.
* @example * @example
* ```typescript * ```typescript
* import { ask } from '@tauri-apps/api/dialog'; * import { ask } from '@tauri-apps/plugin-dialog';
* const yes = await ask('Are you sure?', 'Tauri'); * const yes = await ask('Are you sure?', 'Tauri');
* const yes2 = await ask('This action cannot be reverted. Are you sure?', { title: 'Tauri', type: 'warning' }); * const yes2 = await ask('This action cannot be reverted. Are you sure?', { title: 'Tauri', type: 'warning' });
* ``` * ```
@ -256,7 +256,7 @@ async function message(
*/ */
async function ask( async function ask(
message: string, message: string,
options?: string | ConfirmDialogOptions options?: string | ConfirmDialogOptions,
): Promise<boolean> { ): Promise<boolean> {
const opts = typeof options === "string" ? { title: options } : options; const opts = typeof options === "string" ? { title: options } : options;
return window.__TAURI_INVOKE__("plugin:dialog|ask", { return window.__TAURI_INVOKE__("plugin:dialog|ask", {
@ -272,7 +272,7 @@ async function ask(
* Shows a question dialog with `Ok` and `Cancel` buttons. * Shows a question dialog with `Ok` and `Cancel` buttons.
* @example * @example
* ```typescript * ```typescript
* import { confirm } from '@tauri-apps/api/dialog'; * import { confirm } from '@tauri-apps/plugin-dialog';
* const confirmed = await confirm('Are you sure?', 'Tauri'); * const confirmed = await confirm('Are you sure?', 'Tauri');
* const confirmed2 = await confirm('This action cannot be reverted. Are you sure?', { title: 'Tauri', type: 'warning' }); * const confirmed2 = await confirm('This action cannot be reverted. Are you sure?', { title: 'Tauri', type: 'warning' });
* ``` * ```
@ -286,7 +286,7 @@ async function ask(
*/ */
async function confirm( async function confirm(
message: string, message: string,
options?: string | ConfirmDialogOptions options?: string | ConfirmDialogOptions,
): Promise<boolean> { ): Promise<boolean> {
const opts = typeof options === "string" ? { title: options } : options; const opts = typeof options === "string" ? { title: options } : options;
return window.__TAURI_INVOKE__("plugin:dialog|confirm", { return window.__TAURI_INVOKE__("plugin:dialog|confirm", {

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-fs](banner.png) ![plugin-fs](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/fs/banner.png)
Access the file system. Access the file system.

@ -229,7 +229,7 @@ interface FileEntry {
*/ */
async function readTextFile( async function readTextFile(
filePath: string, filePath: string,
options: FsOptions = {} options: FsOptions = {},
): Promise<string> { ): Promise<string> {
return await window.__TAURI_INVOKE__("plugin:fs|read_text_file", { return await window.__TAURI_INVOKE__("plugin:fs|read_text_file", {
path: filePath, path: filePath,
@ -250,7 +250,7 @@ async function readTextFile(
*/ */
async function readBinaryFile( async function readBinaryFile(
filePath: string, filePath: string,
options: FsOptions = {} options: FsOptions = {},
): Promise<Uint8Array> { ): Promise<Uint8Array> {
const arr = await window.__TAURI_INVOKE__<number[]>("plugin:fs|read_file", { const arr = await window.__TAURI_INVOKE__<number[]>("plugin:fs|read_file", {
path: filePath, path: filePath,
@ -274,7 +274,7 @@ async function readBinaryFile(
async function writeTextFile( async function writeTextFile(
path: string, path: string,
contents: string, contents: string,
options?: FsOptions options?: FsOptions,
): Promise<void>; ): Promise<void>;
/** /**
@ -291,7 +291,7 @@ async function writeTextFile(
*/ */
async function writeTextFile( async function writeTextFile(
file: FsTextFileOption, file: FsTextFileOption,
options?: FsOptions options?: FsOptions,
): Promise<void>; ): Promise<void>;
/** /**
@ -304,7 +304,7 @@ async function writeTextFile(
async function writeTextFile( async function writeTextFile(
path: string | FsTextFileOption, path: string | FsTextFileOption,
contents?: string | FsOptions, contents?: string | FsOptions,
options?: FsOptions options?: FsOptions,
): Promise<void> { ): Promise<void> {
if (typeof options === "object") { if (typeof options === "object") {
Object.freeze(options); Object.freeze(options);
@ -352,7 +352,7 @@ async function writeTextFile(
async function writeBinaryFile( async function writeBinaryFile(
path: string, path: string,
contents: BinaryFileContents, contents: BinaryFileContents,
options?: FsOptions options?: FsOptions,
): Promise<void>; ): Promise<void>;
/** /**
@ -372,7 +372,7 @@ async function writeBinaryFile(
*/ */
async function writeBinaryFile( async function writeBinaryFile(
file: FsBinaryFileOption, file: FsBinaryFileOption,
options?: FsOptions options?: FsOptions,
): Promise<void>; ): Promise<void>;
/** /**
@ -385,7 +385,7 @@ async function writeBinaryFile(
async function writeBinaryFile( async function writeBinaryFile(
path: string | FsBinaryFileOption, path: string | FsBinaryFileOption,
contents?: BinaryFileContents | FsOptions, contents?: BinaryFileContents | FsOptions,
options?: FsOptions options?: FsOptions,
): Promise<void> { ): Promise<void> {
if (typeof options === "object") { if (typeof options === "object") {
Object.freeze(options); Object.freeze(options);
@ -410,12 +410,12 @@ async function writeBinaryFile(
file.contents = contents ?? []; file.contents = contents ?? [];
} }
return await window.__TAURI_INVOKE__("plugin:fs|write_binary_file", { return await window.__TAURI_INVOKE__("plugin:fs|write_file", {
path: file.path, path: file.path,
contents: Array.from( contents: Array.from(
file.contents instanceof ArrayBuffer file.contents instanceof ArrayBuffer
? new Uint8Array(file.contents) ? new Uint8Array(file.contents)
: file.contents : file.contents,
), ),
options: fileOptions, options: fileOptions,
}); });
@ -443,7 +443,7 @@ async function writeBinaryFile(
*/ */
async function readDir( async function readDir(
dir: string, dir: string,
options: FsDirOptions = {} options: FsDirOptions = {},
): Promise<FileEntry[]> { ): Promise<FileEntry[]> {
return await window.__TAURI_INVOKE__("plugin:fs|read_dir", { return await window.__TAURI_INVOKE__("plugin:fs|read_dir", {
path: dir, path: dir,
@ -468,7 +468,7 @@ async function readDir(
*/ */
async function createDir( async function createDir(
dir: string, dir: string,
options: FsDirOptions = {} options: FsDirOptions = {},
): Promise<void> { ): Promise<void> {
return await window.__TAURI_INVOKE__("plugin:fs|create_dir", { return await window.__TAURI_INVOKE__("plugin:fs|create_dir", {
path: dir, path: dir,
@ -492,7 +492,7 @@ async function createDir(
*/ */
async function removeDir( async function removeDir(
dir: string, dir: string,
options: FsDirOptions = {} options: FsDirOptions = {},
): Promise<void> { ): Promise<void> {
return await window.__TAURI_INVOKE__("plugin:fs|remove_dir", { return await window.__TAURI_INVOKE__("plugin:fs|remove_dir", {
path: dir, path: dir,
@ -516,7 +516,7 @@ async function removeDir(
async function copyFile( async function copyFile(
source: string, source: string,
destination: string, destination: string,
options: FsOptions = {} options: FsOptions = {},
): Promise<void> { ): Promise<void> {
return await window.__TAURI_INVOKE__("plugin:fs|copy_file", { return await window.__TAURI_INVOKE__("plugin:fs|copy_file", {
source, source,
@ -540,7 +540,7 @@ async function copyFile(
*/ */
async function removeFile( async function removeFile(
file: string, file: string,
options: FsOptions = {} options: FsOptions = {},
): Promise<void> { ): Promise<void> {
return await window.__TAURI_INVOKE__("plugin:fs|remove_file", { return await window.__TAURI_INVOKE__("plugin:fs|remove_file", {
path: file, path: file,
@ -564,7 +564,7 @@ async function removeFile(
async function renameFile( async function renameFile(
oldPath: string, oldPath: string,
newPath: string, newPath: string,
options: FsOptions = {} options: FsOptions = {},
): Promise<void> { ): Promise<void> {
return await window.__TAURI_INVOKE__("plugin:fs|rename_file", { return await window.__TAURI_INVOKE__("plugin:fs|rename_file", {
oldPath, oldPath,

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

File diff suppressed because one or more lines are too long

@ -1,4 +1,4 @@
![plugin-global-shortcut](banner.png) ![plugin-global-shortcut](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/global-shortcut/banner.png)
Register global shortcuts. Register global shortcuts.

@ -36,7 +36,7 @@ export type ShortcutHandler = (shortcut: string) => void;
*/ */
async function register( async function register(
shortcut: string, shortcut: string,
handler: ShortcutHandler handler: ShortcutHandler,
): Promise<void> { ): Promise<void> {
return await window.__TAURI_INVOKE__("plugin:globalShortcut|register", { return await window.__TAURI_INVOKE__("plugin:globalShortcut|register", {
shortcut, shortcut,
@ -61,7 +61,7 @@ async function register(
*/ */
async function registerAll( async function registerAll(
shortcuts: string[], shortcuts: string[],
handler: ShortcutHandler handler: ShortcutHandler,
): Promise<void> { ): Promise<void> {
return await window.__TAURI_INVOKE__("plugin:globalShortcut|register_all", { return await window.__TAURI_INVOKE__("plugin:globalShortcut|register_all", {
shortcuts, shortcuts,

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-http](banner.png) ![plugin-http](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/http/banner.png)
Access the HTTP client written in Rust. Access the HTTP client written in Rust.

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-localhost](banner.png) ![plugin-localhost](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/localhost/banner.png)
Expose your apps assets through a localhost server instead of the default custom protocol. Expose your apps assets through a localhost server instead of the default custom protocol.

@ -1,4 +1,4 @@
![plugin-log](banner.png) ![plugin-log](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/log/banner.png)
Configurable logging for your Tauri app. Configurable logging for your Tauri app.

@ -52,7 +52,7 @@ enum LogLevel {
async function log( async function log(
level: LogLevel, level: LogLevel,
message: string, message: string,
options?: LogOptions options?: LogOptions,
): Promise<void> { ): Promise<void> {
const traces = new Error().stack?.split("\n").map((line) => line.split("@")); const traces = new Error().stack?.split("\n").map((line) => line.split("@"));
@ -95,7 +95,7 @@ async function log(
*/ */
export async function error( export async function error(
message: string, message: string,
options?: LogOptions options?: LogOptions,
): Promise<void> { ): Promise<void> {
await log(LogLevel.Error, message, options); await log(LogLevel.Error, message, options);
} }
@ -117,7 +117,7 @@ export async function error(
*/ */
export async function warn( export async function warn(
message: string, message: string,
options?: LogOptions options?: LogOptions,
): Promise<void> { ): Promise<void> {
await log(LogLevel.Warn, message, options); await log(LogLevel.Warn, message, options);
} }
@ -139,7 +139,7 @@ export async function warn(
*/ */
export async function info( export async function info(
message: string, message: string,
options?: LogOptions options?: LogOptions,
): Promise<void> { ): Promise<void> {
await log(LogLevel.Info, message, options); await log(LogLevel.Info, message, options);
} }
@ -161,7 +161,7 @@ export async function info(
*/ */
export async function debug( export async function debug(
message: string, message: string,
options?: LogOptions options?: LogOptions,
): Promise<void> { ): Promise<void> {
await log(LogLevel.Debug, message, options); await log(LogLevel.Debug, message, options);
} }
@ -183,7 +183,7 @@ export async function debug(
*/ */
export async function trace( export async function trace(
message: string, message: string,
options?: LogOptions options?: LogOptions,
): Promise<void> { ): Promise<void> {
await log(LogLevel.Trace, message, options); await log(LogLevel.Trace, message, options);
} }
@ -202,7 +202,7 @@ export async function attachConsole(): Promise<UnlistenFn> {
// TODO: Investigate security/detect-unsafe-regex // TODO: Investigate security/detect-unsafe-regex
// eslint-disable-next-line no-control-regex, security/detect-unsafe-regex // eslint-disable-next-line no-control-regex, security/detect-unsafe-regex
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
"" "",
); );
switch (payload.level) { switch (payload.level) {

@ -25,7 +25,7 @@
"LICENSE" "LICENSE"
], ],
"devDependencies": { "devDependencies": {
"tslib": "^2.5.0" "tslib": "2.6.0"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.0.0-alpha.5" "@tauri-apps/api": "2.0.0-alpha.5"

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-notification](banner.png) ![plugin-notification](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/notification/banner.png)
Send message notifications (brief auto-expiring OS window element) to your user. Can also be used with the Notification Web API. Send message notifications (brief auto-expiring OS window element) to your user. Can also be used with the Notification Web API.

@ -296,7 +296,7 @@ type Permission = "granted" | "denied" | "default";
* Checks if the permission to send notifications is granted. * Checks if the permission to send notifications is granted.
* @example * @example
* ```typescript * ```typescript
* import { isPermissionGranted } from '@tauri-apps/api/notification'; * import { isPermissionGranted } from '@tauri-apps/plugin-notification';
* const permissionGranted = await isPermissionGranted(); * const permissionGranted = await isPermissionGranted();
* ``` * ```
* *
@ -313,7 +313,7 @@ async function isPermissionGranted(): Promise<boolean> {
* Requests the permission to send notifications. * Requests the permission to send notifications.
* @example * @example
* ```typescript * ```typescript
* import { isPermissionGranted, requestPermission } from '@tauri-apps/api/notification'; * import { isPermissionGranted, requestPermission } from '@tauri-apps/plugin-notification';
* let permissionGranted = await isPermissionGranted(); * let permissionGranted = await isPermissionGranted();
* if (!permissionGranted) { * if (!permissionGranted) {
* const permission = await requestPermission(); * const permission = await requestPermission();
@ -333,7 +333,7 @@ async function requestPermission(): Promise<Permission> {
* Sends a notification to the user. * Sends a notification to the user.
* @example * @example
* ```typescript * ```typescript
* import { isPermissionGranted, requestPermission, sendNotification } from '@tauri-apps/api/notification'; * import { isPermissionGranted, requestPermission, sendNotification } from '@tauri-apps/plugin-notification';
* let permissionGranted = await isPermissionGranted(); * let permissionGranted = await isPermissionGranted();
* if (!permissionGranted) { * if (!permissionGranted) {
* const permission = await requestPermission(); * const permission = await requestPermission();
@ -362,7 +362,7 @@ function sendNotification(options: Options | string): void {
* *
* @example * @example
* ```typescript * ```typescript
* import { registerActionTypes } from '@tauri-apps/api/notification'; * import { registerActionTypes } from '@tauri-apps/plugin-notification';
* await registerActionTypes([{ * await registerActionTypes([{
* id: 'tauri', * id: 'tauri',
* actions: [{ * actions: [{
@ -385,7 +385,7 @@ async function registerActionTypes(types: ActionType[]): Promise<void> {
* *
* @example * @example
* ```typescript * ```typescript
* import { pending } from '@tauri-apps/api/notification'; * import { pending } from '@tauri-apps/plugin-notification';
* const pendingNotifications = await pending(); * const pendingNotifications = await pending();
* ``` * ```
* *
@ -402,7 +402,7 @@ async function pending(): Promise<PendingNotification[]> {
* *
* @example * @example
* ```typescript * ```typescript
* import { cancel } from '@tauri-apps/api/notification'; * import { cancel } from '@tauri-apps/plugin-notification';
* await cancel([-34234, 23432, 4311]); * await cancel([-34234, 23432, 4311]);
* ``` * ```
* *
@ -419,7 +419,7 @@ async function cancel(notifications: number[]): Promise<void> {
* *
* @example * @example
* ```typescript * ```typescript
* import { cancelAll } from '@tauri-apps/api/notification'; * import { cancelAll } from '@tauri-apps/plugin-notification';
* await cancelAll(); * await cancelAll();
* ``` * ```
* *
@ -436,7 +436,7 @@ async function cancelAll(): Promise<void> {
* *
* @example * @example
* ```typescript * ```typescript
* import { active } from '@tauri-apps/api/notification'; * import { active } from '@tauri-apps/plugin-notification';
* const activeNotifications = await active(); * const activeNotifications = await active();
* ``` * ```
* *
@ -453,7 +453,7 @@ async function active(): Promise<ActiveNotification[]> {
* *
* @example * @example
* ```typescript * ```typescript
* import { cancel } from '@tauri-apps/api/notification'; * import { cancel } from '@tauri-apps/plugin-notification';
* await cancel([-34234, 23432, 4311]) * await cancel([-34234, 23432, 4311])
* ``` * ```
* *
@ -470,7 +470,7 @@ async function removeActive(notifications: number[]): Promise<void> {
* *
* @example * @example
* ```typescript * ```typescript
* import { removeAllActive } from '@tauri-apps/api/notification'; * import { removeAllActive } from '@tauri-apps/plugin-notification';
* await removeAllActive() * await removeAllActive()
* ``` * ```
* *
@ -487,7 +487,7 @@ async function removeAllActive(): Promise<void> {
* *
* @example * @example
* ```typescript * ```typescript
* import { createChannel, Importance, Visibility } from '@tauri-apps/api/notification'; * import { createChannel, Importance, Visibility } from '@tauri-apps/plugin-notification';
* await createChannel({ * await createChannel({
* id: 'new-messages', * id: 'new-messages',
* name: 'New Messages', * name: 'New Messages',
@ -511,7 +511,7 @@ async function createChannel(channel: Channel): Promise<void> {
* *
* @example * @example
* ```typescript * ```typescript
* import { removeChannel } from '@tauri-apps/api/notification'; * import { removeChannel } from '@tauri-apps/plugin-notification';
* await removeChannel(); * await removeChannel();
* ``` * ```
* *
@ -528,7 +528,7 @@ async function removeChannel(id: string): Promise<void> {
* *
* @example * @example
* ```typescript * ```typescript
* import { channels } from '@tauri-apps/api/notification'; * import { channels } from '@tauri-apps/plugin-notification';
* const notificationChannels = await channels(); * const notificationChannels = await channels();
* ``` * ```
* *
@ -541,13 +541,13 @@ async function channels(): Promise<Channel[]> {
} }
async function onNotificationReceived( async function onNotificationReceived(
cb: (notification: Options) => void cb: (notification: Options) => void,
): Promise<PluginListener> { ): Promise<PluginListener> {
return addPluginListener("notification", "notification", cb); return addPluginListener("notification", "notification", cb);
} }
async function onAction( async function onAction(
cb: (notification: Options) => void cb: (notification: Options) => void,
): Promise<PluginListener> { ): Promise<PluginListener> {
return addPluginListener("notification", "actionPerformed", cb); return addPluginListener("notification", "actionPerformed", cb);
} }

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-os](banner.png) ![plugin-os](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/os/banner.png)
Read information about the operating system. Read information about the operating system.

@ -166,7 +166,7 @@ async function exeExtension(): Promise<string | null> {
* Returns the host name of the operating system. * Returns the host name of the operating system.
* @example * @example
* ```typescript * ```typescript
* import { hostname } from '@tauri-apps/api/os'; * import { hostname } from '@tauri-apps/plugin-os';
* const hostname = await hostname(); * const hostname = await hostname();
* ``` * ```
*/ */

@ -24,7 +24,7 @@
"LICENSE" "LICENSE"
], ],
"devDependencies": { "devDependencies": {
"tslib": "^2.5.0" "tslib": "2.6.0"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.0.0-alpha.5" "@tauri-apps/api": "2.0.0-alpha.5"

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -5,6 +5,16 @@
- [`ebb2eb2`](https://github.com/tauri-apps/plugins-workspace/commit/ebb2eb2fe2ebfbb70530d16a983d396aa5829aa1)([#274](https://github.com/tauri-apps/plugins-workspace/pull/274)) Recursively unescape saved patterns before allowing/forbidding them. This effectively prevents `.persisted-scope` files from blowing up, which caused Out-Of-Memory issues, while automatically fixing existing broken files seamlessly. - [`ebb2eb2`](https://github.com/tauri-apps/plugins-workspace/commit/ebb2eb2fe2ebfbb70530d16a983d396aa5829aa1)([#274](https://github.com/tauri-apps/plugins-workspace/pull/274)) Recursively unescape saved patterns before allowing/forbidding them. This effectively prevents `.persisted-scope` files from blowing up, which caused Out-Of-Memory issues, while automatically fixing existing broken files seamlessly.
- [`717ae67`](https://github.com/tauri-apps/plugins-workspace/commit/717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release! - [`717ae67`](https://github.com/tauri-apps/plugins-workspace/commit/717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
## \[0.1.3]
- Split up fs and asset scopes. **This will reset the asset protocol scope once!**
- [ad30286](https://github.com/tauri-apps/plugins-workspace/commit/ad3028646c96ed213a2f483823ffdc3c17b5fc1e) fix(persisted-scope): separately save asset protocol patterns ([#459](https://github.com/tauri-apps/plugins-workspace/pull/459)) on 2023-07-10
## \[0.1.2]
- Fix usage of directory patterns by removing glob asterisks at the end before allowing/forbidding them. This was causing them to be escaped, and so undesirable paths were allowed/forbidden while polluting the `.persisted_scope` file.
- [9174b80](https://github.com/tauri-apps/plugins-workspace/commit/9174b808dc37154999c119fcc3f31258a9c5a3fb) \[persisted scope] fix: handle recursive directory correctly ([#455](https://github.com/tauri-apps/plugins-workspace/pull/455)) on 2023-06-29
## \[0.1.1] ## \[0.1.1]
- The MSRV was raised to 1.64! - The MSRV was raised to 1.64!

@ -1,4 +1,4 @@
![plugin-persisted-scope](banner.png) ![plugin-persisted-scope](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/persisted-scope/banner.png)
Save filesystem and asset scopes and restore them when the app is reopened. Save filesystem and asset scopes and restore them when the app is reopened.

@ -15,17 +15,23 @@ use aho_corasick::AhoCorasick;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tauri::{ use tauri::{
plugin::{Builder, TauriPlugin}, plugin::{Builder, TauriPlugin},
AppHandle, Manager, Runtime, GlobPattern, Manager, Runtime,
}; };
use tauri_plugin_fs::{FsExt, ScopeEvent as FsScopeEvent}; #[cfg(feature = "protocol-asset")]
use tauri::{FsScope, FsScopeEvent};
use tauri_plugin_fs::{FsExt, Scope as FsPluginScope, ScopeEvent as FsPluginScopeEvent};
use std::{ use std::{
collections::HashSet,
fs::{create_dir_all, File}, fs::{create_dir_all, File},
io::Write, io::Write,
path::Path, path::Path,
}; };
// Using 2 separate files so that we don't have to think about write conflicts and not break backwards compat.
const SCOPE_STATE_FILENAME: &str = ".persisted-scope"; const SCOPE_STATE_FILENAME: &str = ".persisted-scope";
#[cfg(feature = "protocol-asset")]
const ASSET_SCOPE_STATE_FILENAME: &str = ".persisted-scope-asset";
// Most of these patterns are just added to try to fix broken files in the wild. // Most of these patterns are just added to try to fix broken files in the wild.
// After a while we can hopefully reduce it to something like [r"[?]", r"[*]", r"\\?\\\?\"] // After a while we can hopefully reduce it to something like [r"[?]", r"[*]", r"\\?\\\?\"]
@ -40,6 +46,70 @@ const PATTERNS: &[&str] = &[
]; ];
const REPLACE_WITH: &[&str] = &[r"[", r"]", r"?", r"*", r"\?", r"\\?\", r"\\?\"]; const REPLACE_WITH: &[&str] = &[r"[", r"]", r"?", r"*", r"\?", r"\\?\", r"\\?\"];
trait ScopeExt {
fn allow_file(&self, path: &Path);
fn allow_directory(&self, path: &Path, recursive: bool);
fn forbid_file(&self, path: &Path);
fn forbid_directory(&self, path: &Path, recursive: bool);
fn allowed_patterns(&self) -> HashSet<GlobPattern>;
fn forbidden_patterns(&self) -> HashSet<GlobPattern>;
}
impl ScopeExt for &FsPluginScope {
fn allow_file(&self, path: &Path) {
let _ = FsPluginScope::allow_file(self, path);
}
fn allow_directory(&self, path: &Path, recursive: bool) {
let _ = FsPluginScope::allow_directory(self, path, recursive);
}
fn forbid_file(&self, path: &Path) {
let _ = FsPluginScope::forbid_file(self, path);
}
fn forbid_directory(&self, path: &Path, recursive: bool) {
let _ = FsPluginScope::forbid_directory(self, path, recursive);
}
fn allowed_patterns(&self) -> HashSet<GlobPattern> {
FsPluginScope::allowed_patterns(self)
}
fn forbidden_patterns(&self) -> HashSet<GlobPattern> {
FsPluginScope::forbidden_patterns(self)
}
}
#[cfg(feature = "protocol-asset")]
impl ScopeExt for &FsScope {
fn allow_file(&self, path: &Path) {
let _ = FsScope::allow_file(self, path);
}
fn allow_directory(&self, path: &Path, recursive: bool) {
let _ = FsScope::allow_directory(self, path, recursive);
}
fn forbid_file(&self, path: &Path) {
let _ = FsScope::forbid_file(self, path);
}
fn forbid_directory(&self, path: &Path, recursive: bool) {
let _ = FsScope::forbid_directory(self, path, recursive);
}
fn allowed_patterns(&self) -> HashSet<GlobPattern> {
FsScope::allowed_patterns(self)
}
fn forbidden_patterns(&self) -> HashSet<GlobPattern> {
FsScope::forbidden_patterns(self)
}
}
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
enum Error { enum Error {
#[error(transparent)] #[error(transparent)]
@ -52,6 +122,14 @@ enum Error {
Bincode(#[from] Box<bincode::ErrorKind>), Bincode(#[from] Box<bincode::ErrorKind>),
} }
#[derive(Debug, Default, Deserialize, Serialize, Eq, PartialEq, Hash)]
enum TargetType {
#[default]
File,
Directory,
RecursiveDirectory,
}
#[derive(Debug, Default, Deserialize, Serialize)] #[derive(Debug, Default, Deserialize, Serialize)]
struct Scope { struct Scope {
allowed_paths: Vec<String>, allowed_paths: Vec<String>,
@ -68,15 +146,74 @@ fn fix_pattern(ac: &AhoCorasick, s: &str) -> String {
s s
} }
fn save_scopes<R: Runtime>(app: &AppHandle<R>, app_dir: &Path, scope_state_path: &Path) { const RESURSIVE_DIRECTORY_SUFFIX: &str = "**";
if let Some(fs_scope) = app.try_fs_scope() { const DIRECTORY_SUFFIX: &str = "*";
fn detect_scope_type(scope_state_path: &str) -> TargetType {
if scope_state_path.ends_with(RESURSIVE_DIRECTORY_SUFFIX) {
TargetType::RecursiveDirectory
} else if scope_state_path.ends_with(DIRECTORY_SUFFIX) {
TargetType::Directory
} else {
TargetType::File
}
}
fn fix_directory(path_str: &str) -> &Path {
let mut path = Path::new(path_str);
if path.ends_with(DIRECTORY_SUFFIX) || path.ends_with(RESURSIVE_DIRECTORY_SUFFIX) {
path = match path.parent() {
Some(value) => value,
None => return path,
};
}
path
}
fn allow_path(scope: impl ScopeExt, path: &str) {
let target_type = detect_scope_type(path);
match target_type {
TargetType::File => {
scope.allow_file(Path::new(path));
}
TargetType::Directory => {
// We remove the '*' at the end of it, else it will be escaped by the pattern.
scope.allow_directory(fix_directory(path), false);
}
TargetType::RecursiveDirectory => {
// We remove the '**' at the end of it, else it will be escaped by the pattern.
scope.allow_directory(fix_directory(path), true);
}
}
}
fn forbid_path(scope: impl ScopeExt, path: &str) {
let target_type = detect_scope_type(path);
match target_type {
TargetType::File => {
scope.forbid_file(Path::new(path));
}
TargetType::Directory => {
scope.forbid_directory(fix_directory(path), false);
}
TargetType::RecursiveDirectory => {
scope.forbid_directory(fix_directory(path), true);
}
}
}
fn save_scopes(scope: impl ScopeExt, app_dir: &Path, scope_state_path: &Path) {
let scope = Scope { let scope = Scope {
allowed_paths: fs_scope allowed_paths: scope
.allowed_patterns() .allowed_patterns()
.into_iter() .into_iter()
.map(|p| p.to_string()) .map(|p| p.to_string())
.collect(), .collect(),
forbidden_patterns: fs_scope forbidden_patterns: scope
.forbidden_patterns() .forbidden_patterns()
.into_iter() .into_iter()
.map(|p| p.to_string()) .map(|p| p.to_string())
@ -90,63 +227,92 @@ fn save_scopes<R: Runtime>(app: &AppHandle<R>, app_dir: &Path, scope_state_path:
f.write_all(&bincode::serialize(&scope).map_err(Error::from)?) f.write_all(&bincode::serialize(&scope).map_err(Error::from)?)
.map_err(Into::into) .map_err(Into::into)
}); });
}
} }
pub fn init<R: Runtime>() -> TauriPlugin<R> { pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("persisted-scope") Builder::new("persisted-scope")
.setup(|app, _api| { .setup(|app, _api| {
let fs_scope = app.try_fs_scope(); let fs_scope = app.try_fs_scope();
let core_scopes = app.state::<tauri::scope::Scopes>(); #[cfg(feature = "protocol-asset")]
let asset_protocol_scope = app.asset_protocol_scope();
let app = app.clone(); let app = app.clone();
let app_dir = app.path().app_data_dir(); let app_dir = app.path().app_data_dir();
if let Ok(app_dir) = app_dir { if let Ok(app_dir) = app_dir {
let scope_state_path = app_dir.join(SCOPE_STATE_FILENAME); let fs_scope_state_path = app_dir.join(SCOPE_STATE_FILENAME);
#[cfg(feature = "protocol-asset")]
let asset_scope_state_path = app_dir.join(ASSET_SCOPE_STATE_FILENAME);
if let Some(s) = fs_scope { if let Some(fs_scope) = fs_scope {
let _ = s.forbid_file(&scope_state_path); let _ = fs_scope.forbid_file(&fs_scope_state_path);}
} #[cfg(feature = "protocol-asset")]
let _ = core_scopes.forbid_file(&scope_state_path); let _ = asset_protocol_scope.forbid_file(&asset_scope_state_path);
// We're trying to fix broken .persisted-scope files seamlessly, so we'll be running this on the values read on the saved file. // We're trying to fix broken .persisted-scope files seamlessly, so we'll be running this on the values read on the saved file.
// We will still save some semi-broken values because the scope events are quite spammy and we don't want to reduce runtime performance any further. // We will still save some semi-broken values because the scope events are quite spammy and we don't want to reduce runtime performance any further.
let ac = AhoCorasick::new(PATTERNS).unwrap(/* This should be impossible to fail since we're using a small static input */); let ac = AhoCorasick::new(PATTERNS).unwrap(/* This should be impossible to fail since we're using a small static input */);
if scope_state_path.exists() { if let Some(fs_scope) = fs_scope {
let scope: Scope = tauri::api::file::read_binary(&scope_state_path) if fs_scope_state_path.exists() {
let scope: Scope = tauri::api::file::read_binary(&fs_scope_state_path)
.map_err(Error::from) .map_err(Error::from)
.and_then(|scope| bincode::deserialize(&scope).map_err(Into::into)) .and_then(|scope| bincode::deserialize(&scope).map_err(Into::into))
.unwrap_or_default(); .unwrap_or_default();
for allowed in &scope.allowed_paths { for allowed in &scope.allowed_paths {
let allowed = fix_pattern(&ac, allowed); let allowed = fix_pattern(&ac, allowed);
allow_path(fs_scope, &allowed);
if let Some(s) = fs_scope {
let _ = s.allow_file(&allowed);
}
let _ = core_scopes.allow_file(&allowed);
} }
for forbidden in &scope.forbidden_patterns { for forbidden in &scope.forbidden_patterns {
let forbidden = fix_pattern(&ac, forbidden); let forbidden = fix_pattern(&ac, forbidden);
forbid_path(fs_scope, &forbidden);
}
// Manually save the fixed scopes to disk once.
// This is needed to fix broken .peristed-scope files in case the app doesn't update the scope itself.
save_scopes(fs_scope, &app_dir, &fs_scope_state_path);
}
}
#[cfg(feature = "protocol-asset")]
if asset_scope_state_path.exists() {
let scope: Scope = tauri::api::file::read_binary(&asset_scope_state_path)
.map_err(Error::from)
.and_then(|scope| bincode::deserialize(&scope).map_err(Into::into))
.unwrap_or_default();
if let Some(s) = fs_scope { for allowed in &scope.allowed_paths {
let _ = s.forbid_file(&forbidden); let allowed = fix_pattern(&ac, allowed);
allow_path(&asset_protocol_scope, &allowed);
} }
let _ = core_scopes.forbid_file(&forbidden); for forbidden in &scope.forbidden_patterns {
let forbidden = fix_pattern(&ac, forbidden);
forbid_path(&asset_protocol_scope, &forbidden);
} }
// Manually save the fixed scopes to disk once. // Manually save the fixed scopes to disk once.
// This is needed to fix broken .peristed-scope files in case the app doesn't update the scope itself. save_scopes(&asset_protocol_scope, &app_dir, &asset_scope_state_path);
save_scopes(&app, &app_dir, &scope_state_path);
} }
if let Some(s) = fs_scope { #[cfg(feature = "protocol-asset")]
s.listen(move |event| { let app_dir_ = app_dir.clone();
if let FsScopeEvent::PathAllowed(_) = event { if let Some(fs_scope) = fs_scope {
save_scopes(&app, &app_dir, &scope_state_path); let fs_scope_ = fs_scope.clone();
fs_scope.listen(move |event| {
if let FsPluginScopeEvent::PathAllowed(_) = event {
save_scopes(&fs_scope_, &app_dir, &fs_scope_state_path);
} }
}); });
} }
#[cfg(feature = "protocol-asset")]
{
let asset_protocol_scope_ = asset_protocol_scope.clone();
asset_protocol_scope.listen(move |event| {
if let FsScopeEvent::PathAllowed(_) = event {
save_scopes(&asset_protocol_scope_, &app_dir_, &asset_scope_state_path);
}
});}
} }
Ok(()) Ok(())
}) })

@ -1,4 +1,4 @@
![plugin-positioner](banner.png) ![plugin-positioner](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/positioner/banner.png)
Position your windows at well-known locations. Position your windows at well-known locations.

@ -25,7 +25,7 @@
"LICENSE" "LICENSE"
], ],
"devDependencies": { "devDependencies": {
"tslib": "^2.5.0" "tslib": "2.6.0"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.0.0-alpha.5" "@tauri-apps/api": "2.0.0-alpha.5"

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-process](banner.png) ![plugin-process](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/process/banner.png)
This plugin provides APIs to access the current process. To spawn child processes, see the [`shell`](https://github.com/tauri-apps/tauri-plugin-shell) plugin. This plugin provides APIs to access the current process. To spawn child processes, see the [`shell`](https://github.com/tauri-apps/tauri-plugin-shell) plugin.

@ -24,7 +24,7 @@
"LICENSE" "LICENSE"
], ],
"devDependencies": { "devDependencies": {
"tslib": "^2.5.0" "tslib": "2.6.0"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.0.0-alpha.5" "@tauri-apps/api": "2.0.0-alpha.5"

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-shell](banner.png) ![plugin-shell](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/shell/banner.png)
Access the system shell. Allows you to spawn child processes and manage files and URLs using their default application. Access the system shell. Allows you to spawn child processes and manage files and URLs using their default application.

@ -122,7 +122,7 @@ async function execute<O extends IOPayload>(
onEvent: (event: CommandEvent<O>) => void, onEvent: (event: CommandEvent<O>) => void,
program: string, program: string,
args: string | string[] = [], args: string | string[] = [],
options?: InternalSpawnOptions options?: InternalSpawnOptions,
): Promise<number> { ): Promise<number> {
if (typeof args === "object") { if (typeof args === "object") {
Object.freeze(args); Object.freeze(args);
@ -153,7 +153,7 @@ class EventEmitter<E extends Record<string, any>> {
*/ */
addListener<N extends keyof E>( addListener<N extends keyof E>(
eventName: N, eventName: N,
listener: (arg: E[typeof eventName]) => void listener: (arg: E[typeof eventName]) => void,
): this { ): this {
return this.on(eventName, listener); return this.on(eventName, listener);
} }
@ -165,7 +165,7 @@ class EventEmitter<E extends Record<string, any>> {
*/ */
removeListener<N extends keyof E>( removeListener<N extends keyof E>(
eventName: N, eventName: N,
listener: (arg: E[typeof eventName]) => void listener: (arg: E[typeof eventName]) => void,
): this { ): this {
return this.off(eventName, listener); return this.off(eventName, listener);
} }
@ -182,7 +182,7 @@ class EventEmitter<E extends Record<string, any>> {
*/ */
on<N extends keyof E>( on<N extends keyof E>(
eventName: N, eventName: N,
listener: (arg: E[typeof eventName]) => void listener: (arg: E[typeof eventName]) => void,
): this { ): this {
if (eventName in this.eventListeners) { if (eventName in this.eventListeners) {
// eslint-disable-next-line security/detect-object-injection // eslint-disable-next-line security/detect-object-injection
@ -204,7 +204,7 @@ class EventEmitter<E extends Record<string, any>> {
*/ */
once<N extends keyof E>( once<N extends keyof E>(
eventName: N, eventName: N,
listener: (arg: E[typeof eventName]) => void listener: (arg: E[typeof eventName]) => void,
): this { ): this {
const wrapper = (arg: E[typeof eventName]): void => { const wrapper = (arg: E[typeof eventName]): void => {
this.removeListener(eventName, wrapper); this.removeListener(eventName, wrapper);
@ -222,12 +222,12 @@ class EventEmitter<E extends Record<string, any>> {
*/ */
off<N extends keyof E>( off<N extends keyof E>(
eventName: N, eventName: N,
listener: (arg: E[typeof eventName]) => void listener: (arg: E[typeof eventName]) => void,
): this { ): this {
if (eventName in this.eventListeners) { if (eventName in this.eventListeners) {
// eslint-disable-next-line security/detect-object-injection // eslint-disable-next-line security/detect-object-injection
this.eventListeners[eventName] = this.eventListeners[eventName].filter( this.eventListeners[eventName] = this.eventListeners[eventName].filter(
(l) => l !== listener (l) => l !== listener,
); );
} }
return this; return this;
@ -295,7 +295,7 @@ class EventEmitter<E extends Record<string, any>> {
*/ */
prependListener<N extends keyof E>( prependListener<N extends keyof E>(
eventName: N, eventName: N,
listener: (arg: E[typeof eventName]) => void listener: (arg: E[typeof eventName]) => void,
): this { ): this {
if (eventName in this.eventListeners) { if (eventName in this.eventListeners) {
// eslint-disable-next-line security/detect-object-injection // eslint-disable-next-line security/detect-object-injection
@ -317,7 +317,7 @@ class EventEmitter<E extends Record<string, any>> {
*/ */
prependOnceListener<N extends keyof E>( prependOnceListener<N extends keyof E>(
eventName: N, eventName: N,
listener: (arg: E[typeof eventName]) => void listener: (arg: E[typeof eventName]) => void,
): this { ): this {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const wrapper = (arg: any): void => { const wrapper = (arg: any): void => {
@ -434,7 +434,7 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
private constructor( private constructor(
program: string, program: string,
args: string | string[] = [], args: string | string[] = [],
options?: SpawnOptions options?: SpawnOptions,
) { ) {
super(); super();
this.program = program; this.program = program;
@ -446,12 +446,12 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
static create( static create(
program: string, program: string,
args?: string | string[], args?: string | string[],
options?: SpawnOptions & { encoding: "raw" } options?: SpawnOptions & { encoding: "raw" },
): Command<Uint8Array>; ): Command<Uint8Array>;
static create( static create(
program: string, program: string,
args?: string | string[], args?: string | string[],
options?: SpawnOptions options?: SpawnOptions,
): Command<string>; ): Command<string>;
/** /**
@ -469,7 +469,7 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
static create<O extends IOPayload>( static create<O extends IOPayload>(
program: string, program: string,
args: string | string[] = [], args: string | string[] = [],
options?: SpawnOptions options?: SpawnOptions,
): Command<O> { ): Command<O> {
return new Command(program, args, options); return new Command(program, args, options);
} }
@ -478,12 +478,12 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
static sidecar( static sidecar(
program: string, program: string,
args?: string | string[], args?: string | string[],
options?: SpawnOptions & { encoding: "raw" } options?: SpawnOptions & { encoding: "raw" },
): Command<Uint8Array>; ): Command<Uint8Array>;
static sidecar( static sidecar(
program: string, program: string,
args?: string | string[], args?: string | string[],
options?: SpawnOptions options?: SpawnOptions,
): Command<string>; ): Command<string>;
/** /**
@ -501,7 +501,7 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
static sidecar<O extends IOPayload>( static sidecar<O extends IOPayload>(
program: string, program: string,
args: string | string[] = [], args: string | string[] = [],
options?: SpawnOptions options?: SpawnOptions,
): Command<O> { ): Command<O> {
const instance = new Command<O>(program, args, options); const instance = new Command<O>(program, args, options);
instance.options.sidecar = true; instance.options.sidecar = true;
@ -535,7 +535,7 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
}, },
this.program, this.program,
this.args, this.args,
this.options this.options,
).then((pid) => new Child(pid)); ).then((pid) => new Child(pid));
} }

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -12,7 +12,7 @@
if ( if (
target.href && target.href &&
["http://", "https://", "mailto:", "tel:"].some((v) => ["http://", "https://", "mailto:", "tel:"].some((v) =>
target.href.startsWith(v) target.href.startsWith(v),
) && ) &&
target.target === "_blank" target.target === "_blank"
) { ) {

@ -264,8 +264,8 @@ impl Scope {
// The prevention of argument escaping is handled by the usage of std::process::Command::arg by // The prevention of argument escaping is handled by the usage of std::process::Command::arg by
// the `open` dependency. This behavior should be re-confirmed during upgrades of `open`. // the `open` dependency. This behavior should be re-confirmed during upgrades of `open`.
match with.map(Program::name) { match with.map(Program::name) {
Some(program) => ::open::with(path, program), Some(program) => ::open::with_detached(path, program),
None => ::open::that(path), None => ::open::that_detached(path),
} }
.map_err(Into::into) .map_err(Into::into)
} }

@ -1,4 +1,4 @@
![tauri-plugin-single-instance](banner.png) ![tauri-plugin-single-instance](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/single-instance/banner.png)
Ensure a single instance of your tauri app is running. Ensure a single instance of your tauri app is running.

@ -1,106 +0,0 @@
lockfileVersion: 5.4
specifiers:
'@tauri-apps/cli': ^1.0.0
dependencies:
'@tauri-apps/cli': 1.0.2
packages:
/@tauri-apps/cli-darwin-arm64/1.0.2:
resolution: {integrity: sha512-Ahd951yoYon1+WLNBg6xsx6Bb7+GJt7WwC1FllHZ2/iLCbrtWCS2qfeLS0L4ngBqCuWyL35JC/M2LIr9mcUzrg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: false
optional: true
/@tauri-apps/cli-darwin-x64/1.0.2:
resolution: {integrity: sha512-8wo+SN1zWoXFQVa/iyEt3Cs0vNMjxDXqVe3Srm4UNpgKboFN5mIgbugwqvM+aJKnEZAH8h8n+ZJUHzc4wtPGHA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: false
optional: true
/@tauri-apps/cli-linux-arm-gnueabihf/1.0.2:
resolution: {integrity: sha512-PGQghMn0adt9PTnyi2K2o/CLG3tWbOyZvwQjam5cfQbK757WmMgPErC1VqsxiQc+PItWYvqoE9gjANiFc2MpAQ==}
engines: {node: '>= 10'}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@tauri-apps/cli-linux-arm64-gnu/1.0.2:
resolution: {integrity: sha512-Uc+XNlWelrnRh7DYrdxBi8Oam9JAQM1GzgEwjupF6Pv7BwlODN7s0HImGPQOKrEkqzpfmYw7KpfgWiiEjS5/3Q==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@tauri-apps/cli-linux-arm64-musl/1.0.2:
resolution: {integrity: sha512-lVwCG1QzQs2zWP32H4+Dw8NKgJ6hBox2X+bmawGfV9Ce+K4P84bnqfNgpdaSAncjeiTjrO+g7yT9gJFQCOrjlQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@tauri-apps/cli-linux-x64-gnu/1.0.2:
resolution: {integrity: sha512-G2XmGxvufW9sgGhA3rx+HehcifVTUo8zyISd8DpvGwtpp6Z4WakbivzKFyGiNnnok0nvj/WUrLgBxtUbfdSY+A==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@tauri-apps/cli-linux-x64-musl/1.0.2:
resolution: {integrity: sha512-/eX536p+KXSmkFuINGeU6EQmYiQEXj6JXbmetmJmkXN0297HbtH3rS3wlyVDCnobRzh1hMeOJEnV+XA20GghMA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@tauri-apps/cli-win32-ia32-msvc/1.0.2:
resolution: {integrity: sha512-ZvnaKkCABqUbyUKlNk4RdxKyfOte30D5BxN1pj6iZNeKAwXEuTcgP6iPzOovdeaDirkIjcWCEZymwtZDXN4Rvg==}
engines: {node: '>= 10'}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@tauri-apps/cli-win32-x64-msvc/1.0.2:
resolution: {integrity: sha512-uMcQyQQD7nyxps34HyYBYUYzFwH26lP58/qdT/GZWvBL1Sv2rqkQXuxHT7xtp4g7nTs0fGRWOtfcnvYIr/1wDw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@tauri-apps/cli/1.0.2:
resolution: {integrity: sha512-OJdQJVwtKnTAuv2a9JQlOd0gHbbGsXwT+N6M6YQiXZ3/5WdlXey1zhnD78GXwZsf8Cz0R7QIGTBECO4ur4fnKg==}
engines: {node: '>= 10'}
hasBin: true
optionalDependencies:
'@tauri-apps/cli-darwin-arm64': 1.0.2
'@tauri-apps/cli-darwin-x64': 1.0.2
'@tauri-apps/cli-linux-arm-gnueabihf': 1.0.2
'@tauri-apps/cli-linux-arm64-gnu': 1.0.2
'@tauri-apps/cli-linux-arm64-musl': 1.0.2
'@tauri-apps/cli-linux-x64-gnu': 1.0.2
'@tauri-apps/cli-linux-x64-musl': 1.0.2
'@tauri-apps/cli-win32-ia32-msvc': 1.0.2
'@tauri-apps/cli-win32-x64-msvc': 1.0.2
dev: false

@ -7,7 +7,7 @@ description = "A Tauri App"
authors = [ "You" ] authors = [ "You" ]
repository = "" repository = ""
edition = "2021" edition = "2021"
rust-version = "1.57" rust-version = "1.65"
[dependencies] [dependencies]
serde_json = "1.0" serde_json = "1.0"

@ -17,7 +17,7 @@ tauri = { workspace = true }
log = { workspace = true } log = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
futures-core = "0.3" futures-core = "0.3"
sqlx = { version = "0.6", features = [ "runtime-tokio-rustls", "json", "time" ] } sqlx = { version = "0.7", features = [ "runtime-tokio-rustls", "json", "time" ] }
time = "0.3" time = "0.3"
tokio = { version = "1", features = [ "sync" ] } tokio = { version = "1", features = [ "sync" ] }

@ -1,4 +1,4 @@
![plugin-sql](banner.png) ![plugin-sql](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/sql/banner.png)
Interface with SQL databases through [sqlx](https://github.com/launchbadge/sqlx). It supports the `sqlite`, `mysql` and `postgres` drivers, enabled by a Cargo feature. Interface with SQL databases through [sqlx](https://github.com/launchbadge/sqlx). It supports the `sqlite`, `mysql` and `postgres` drivers, enabled by a Cargo feature.
@ -74,6 +74,37 @@ const db = await Database.load("postgres://postgres:password@localhost/test");
await db.execute("INSERT INTO ..."); await db.execute("INSERT INTO ...");
``` ```
## Syntax
We use sqlx as our underlying library, adopting their query syntax:
- sqlite and postgres use the "$#" syntax when substituting query data
- mysql uses "?" when substituting query data
```javascript
// INSERT and UPDATE examples for sqlite and postgres
const result = await db.execute(
"INSERT into todos (id, title, status) VALUES ($1, $2, $3)",
[todos.id, todos.title, todos.status],
);
const result = await db.execute(
"UPDATE todos SET title = $1, completed = $2 WHERE id = $3",
[todos.title, todos.status, todos.id],
);
// INSERT and UPDATE examples for mysql
const result = await db.execute(
"INSERT into todos (id, title, status) VALUES (?, ?, ?)",
[todos.id, todos.title, todos.status],
);
const result = await db.execute(
"UPDATE todos SET title = ?, completed = ? WHERE id = ?",
[todos.title, todos.status, todos.id],
);
```
## Contributing ## Contributing
PRs accepted. Please make sure to read the Contributing Guide before making a pull request. PRs accepted. Please make sure to read the Contributing Guide before making a pull request.

@ -84,10 +84,29 @@ export default class Database {
* *
* @example * @example
* ```ts * ```ts
* // for sqlite & postgres
* // INSERT example
* const result = await db.execute(
* "INSERT into todos (id, title, status) VALUES ($1, $2, $3)",
* [ todos.id, todos.title, todos.status ]
* );
* // UPDATE example
* const result = await db.execute( * const result = await db.execute(
* "UPDATE todos SET title = $1, completed = $2 WHERE id = $3", * "UPDATE todos SET title = $1, completed = $2 WHERE id = $3",
* [ todos.title, todos.status, todos.id ] * [ todos.title, todos.status, todos.id ]
* ); * );
*
* // for mysql
* // INSERT example
* const result = await db.execute(
* "INSERT into todos (id, title, status) VALUES (?, ?, ?)",
* [ todos.id, todos.title, todos.status ]
* );
* // UPDATE example
* const result = await db.execute(
* "UPDATE todos SET title = ?, completed = ? WHERE id = ?",
* [ todos.title, todos.status, todos.id ]
* );
* ``` * ```
*/ */
async execute(query: string, bindValues?: unknown[]): Promise<QueryResult> { async execute(query: string, bindValues?: unknown[]): Promise<QueryResult> {
@ -104,7 +123,6 @@ export default class Database {
rowsAffected, rowsAffected,
}; };
} }
/** /**
* **select** * **select**
* *
@ -112,9 +130,15 @@ export default class Database {
* *
* @example * @example
* ```ts * ```ts
* // for sqlite & postgres
* const result = await db.select( * const result = await db.select(
* "SELECT * from todos WHERE id = $1", id * "SELECT * from todos WHERE id = $1", id
* ); * );
*
* // for mysql
* const result = await db.select(
* "SELECT * from todos WHERE id = ?", id
* );
* ``` * ```
*/ */
async select<T>(query: string, bindValues?: unknown[]): Promise<T> { async select<T>(query: string, bindValues?: unknown[]): Promise<T> {

@ -25,7 +25,7 @@
"LICENSE" "LICENSE"
], ],
"devDependencies": { "devDependencies": {
"tslib": "^2.5.0" "tslib": "2.6.0"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.0.0-alpha.5" "@tauri-apps/api": "2.0.0-alpha.5"

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-store](banner.png) ![plugin-store](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/store/banner.png)
Simple, persistent key-value store. Simple, persistent key-value store.

@ -184,7 +184,7 @@ export class Store {
*/ */
async onKeyChange<T>( async onKeyChange<T>(
key: string, key: string,
cb: (value: T | null) => void cb: (value: T | null) => void,
): Promise<UnlistenFn> { ): Promise<UnlistenFn> {
return await listen<ChangePayload<T>>("store://change", (event) => { return await listen<ChangePayload<T>>("store://change", (event) => {
if (event.payload.path === this.path && event.payload.key === key) { if (event.payload.path === this.path && event.payload.key === key) {
@ -201,7 +201,7 @@ export class Store {
* @since 2.0.0 * @since 2.0.0
*/ */
async onChange<T>( async onChange<T>(
cb: (key: string, value: T | null) => void cb: (key: string, value: T | null) => void,
): Promise<UnlistenFn> { ): Promise<UnlistenFn> {
return await listen<ChangePayload<T>>("store://change", (event) => { return await listen<ChangePayload<T>>("store://change", (event) => {
if (event.payload.path === this.path) { if (event.payload.path === this.path) {

@ -25,7 +25,7 @@
"LICENSE" "LICENSE"
], ],
"devDependencies": { "devDependencies": {
"tslib": "^2.5.0" "tslib": "2.6.0"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.0.0-alpha.5" "@tauri-apps/api": "2.0.0-alpha.5"

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -14,7 +14,7 @@ tauri = { workspace = true }
log = { workspace = true } log = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
iota_stronghold = "1" iota_stronghold = "1"
iota-crypto = "0.20" iota-crypto = "0.23"
hex = "0.4" hex = "0.4"
zeroize = { version = "1", features = [ "zeroize_derive" ] } zeroize = { version = "1", features = [ "zeroize_derive" ] }

@ -1,4 +1,4 @@
![plugin-stronghold](banner.png) ![plugin-stronghold](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/stronghold/banner.png)
Store secrets and keys using the [IOTA Stronghold](https://github.com/iotaledger/stronghold.rs) encrypted database and secure runtime. Store secrets and keys using the [IOTA Stronghold](https://github.com/iotaledger/stronghold.rs) encrypted database and secure runtime.

@ -31,7 +31,7 @@ export type StoreKey =
| ArrayBuffer; | ArrayBuffer;
function toBytesDto( function toBytesDto(
v: ClientPath | VaultPath | RecordPath | StoreKey v: ClientPath | VaultPath | RecordPath | StoreKey,
): string | number[] { ): string | number[] {
if (typeof v === "string") { if (typeof v === "string") {
return v; return v;
@ -133,7 +133,7 @@ class ProcedureExecutor {
*/ */
async generateSLIP10Seed( async generateSLIP10Seed(
outputLocation: Location, outputLocation: Location,
sizeBytes?: number sizeBytes?: number,
): Promise<Uint8Array> { ): Promise<Uint8Array> {
return await window return await window
.__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", { .__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", {
@ -162,7 +162,7 @@ class ProcedureExecutor {
chain: number[], chain: number[],
source: "Seed" | "Key", source: "Seed" | "Key",
sourceLocation: Location, sourceLocation: Location,
outputLocation: Location outputLocation: Location,
): Promise<Uint8Array> { ): Promise<Uint8Array> {
return await window return await window
.__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", { .__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", {
@ -193,7 +193,7 @@ class ProcedureExecutor {
async recoverBIP39( async recoverBIP39(
mnemonic: string, mnemonic: string,
outputLocation: Location, outputLocation: Location,
passphrase?: string passphrase?: string,
): Promise<Uint8Array> { ): Promise<Uint8Array> {
return await window return await window
.__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", { .__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", {
@ -219,7 +219,7 @@ class ProcedureExecutor {
*/ */
async generateBIP39( async generateBIP39(
outputLocation: Location, outputLocation: Location,
passphrase?: string passphrase?: string,
): Promise<Uint8Array> { ): Promise<Uint8Array> {
return await window return await window
.__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", { .__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", {
@ -267,7 +267,7 @@ class ProcedureExecutor {
*/ */
async signEd25519( async signEd25519(
privateKeyLocation: Location, privateKeyLocation: Location,
msg: string msg: string,
): Promise<Uint8Array> { ): Promise<Uint8Array> {
return await window return await window
.__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", { .__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", {
@ -317,20 +317,20 @@ export class Store {
this.client = client; this.client = client;
} }
async get(key: StoreKey): Promise<Uint8Array> { async get(key: StoreKey): Promise<Uint8Array | null> {
return await window return await window
.__TAURI_INVOKE__<number[]>("plugin:stronghold|get_store_record", { .__TAURI_INVOKE__<number[]>("plugin:stronghold|get_store_record", {
snapshotPath: this.path, snapshotPath: this.path,
client: this.client, client: this.client,
key: toBytesDto(key), key: toBytesDto(key),
}) })
.then((v) => Uint8Array.from(v)); .then((v) => (v != null ? Uint8Array.from(v) : null));
} }
async insert( async insert(
key: StoreKey, key: StoreKey,
value: number[], value: number[],
lifetime?: Duration lifetime?: Duration,
): Promise<void> { ): Promise<void> {
return await window.__TAURI_INVOKE__( return await window.__TAURI_INVOKE__(
"plugin:stronghold|save_store_record", "plugin:stronghold|save_store_record",
@ -340,7 +340,7 @@ export class Store {
key: toBytesDto(key), key: toBytesDto(key),
value, value,
lifetime, lifetime,
} },
); );
} }
@ -352,7 +352,7 @@ export class Store {
snapshotPath: this.path, snapshotPath: this.path,
client: this.client, client: this.client,
key: toBytesDto(key), key: toBytesDto(key),
} },
) )
.then((v) => (v != null ? Uint8Array.from(v) : null)); .then((v) => (v != null ? Uint8Array.from(v) : null));
} }
@ -409,7 +409,7 @@ export class Vault extends ProcedureExecutor {
snapshotPath: this.path, snapshotPath: this.path,
client: this.client, client: this.client,
vault: this.name, vault: this.name,
location, recordPath: location.payload.record,
}); });
} }
} }

@ -25,7 +25,7 @@
"LICENSE" "LICENSE"
], ],
"devDependencies": { "devDependencies": {
"tslib": "^2.5.0" "tslib": "2.6.0"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.0.0-alpha.5" "@tauri-apps/api": "2.0.0-alpha.5"

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_STRONGHOLD__=function(t){"use strict";function e(t){return"string"==typeof t?t:Array.from(t instanceof ArrayBuffer?new Uint8Array(t):t)}class r{constructor(t,e){this.type=t,this.payload=e}static generic(t,n){return new r("Generic",{vault:e(t),record:e(n)})}static counter(t,n){return new r("Counter",{vault:e(t),counter:n})}}class n{constructor(t){this.procedureArgs=t}async generateSLIP10Seed(t,e){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"SLIP10Generate",payload:{output:t,sizeBytes:e}}}).then((t=>Uint8Array.from(t)))}async deriveSLIP10(t,e,r,n){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"SLIP10Derive",payload:{chain:t,input:{type:e,payload:r},output:n}}}).then((t=>Uint8Array.from(t)))}async recoverBIP39(t,e,r){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"BIP39Recover",payload:{mnemonic:t,passphrase:r,output:e}}}).then((t=>Uint8Array.from(t)))}async generateBIP39(t,e){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"BIP39Generate",payload:{output:t,passphrase:e}}}).then((t=>Uint8Array.from(t)))}async getEd25519PublicKey(t){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"PublicKey",payload:{type:"Ed25519",privateKey:t}}}).then((t=>Uint8Array.from(t)))}async signEd25519(t,e){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"Ed25519Sign",payload:{privateKey:t,msg:e}}}).then((t=>Uint8Array.from(t)))}}class a{constructor(t,r){this.path=t,this.name=e(r)}getVault(t){return new s(this.path,this.name,e(t))}getStore(){return new i(this.path,this.name)}}class i{constructor(t,e){this.path=t,this.client=e}async get(t){return await window.__TAURI_INVOKE__("plugin:stronghold|get_store_record",{snapshotPath:this.path,client:this.client,key:e(t)}).then((t=>Uint8Array.from(t)))}async insert(t,r,n){return await window.__TAURI_INVOKE__("plugin:stronghold|save_store_record",{snapshotPath:this.path,client:this.client,key:e(t),value:r,lifetime:n})}async remove(t){return await window.__TAURI_INVOKE__("plugin:stronghold|remove_store_record",{snapshotPath:this.path,client:this.client,key:e(t)}).then((t=>null!=t?Uint8Array.from(t):null))}}class s extends n{constructor(t,r,n){super({snapshotPath:t,client:r,vault:n}),this.path=t,this.client=e(r),this.name=e(n)}async insert(t,r){return await window.__TAURI_INVOKE__("plugin:stronghold|save_secret",{snapshotPath:this.path,client:this.client,vault:this.name,recordPath:e(t),secret:r})}async remove(t){return await window.__TAURI_INVOKE__("plugin:stronghold|remove_secret",{snapshotPath:this.path,client:this.client,vault:this.name,location:t})}}class o{constructor(t){this.path=t}static async load(t,e){return await window.__TAURI_INVOKE__("plugin:stronghold|initialize",{snapshotPath:t,password:e}).then((()=>new o(t)))}async unload(){return await window.__TAURI_INVOKE__("plugin:stronghold|destroy",{snapshotPath:this.path})}async loadClient(t){return await window.__TAURI_INVOKE__("plugin:stronghold|load_client",{snapshotPath:this.path,client:e(t)}).then((()=>new a(this.path,t)))}async createClient(t){return await window.__TAURI_INVOKE__("plugin:stronghold|create_client",{snapshotPath:this.path,client:e(t)}).then((()=>new a(this.path,t)))}async save(){return await window.__TAURI_INVOKE__("plugin:stronghold|save",{snapshotPath:this.path})}}return t.Client=a,t.Location=r,t.Store=i,t.Stronghold=o,t.Vault=s,t}({});Object.defineProperty(window.__TAURI__,"stronghold",{value:__TAURI_STRONGHOLD__})} if("__TAURI__"in window){var __TAURI_STRONGHOLD__=function(t){"use strict";function e(t){return"string"==typeof t?t:Array.from(t instanceof ArrayBuffer?new Uint8Array(t):t)}class r{constructor(t,e){this.type=t,this.payload=e}static generic(t,n){return new r("Generic",{vault:e(t),record:e(n)})}static counter(t,n){return new r("Counter",{vault:e(t),counter:n})}}class n{constructor(t){this.procedureArgs=t}async generateSLIP10Seed(t,e){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"SLIP10Generate",payload:{output:t,sizeBytes:e}}}).then((t=>Uint8Array.from(t)))}async deriveSLIP10(t,e,r,n){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"SLIP10Derive",payload:{chain:t,input:{type:e,payload:r},output:n}}}).then((t=>Uint8Array.from(t)))}async recoverBIP39(t,e,r){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"BIP39Recover",payload:{mnemonic:t,passphrase:r,output:e}}}).then((t=>Uint8Array.from(t)))}async generateBIP39(t,e){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"BIP39Generate",payload:{output:t,passphrase:e}}}).then((t=>Uint8Array.from(t)))}async getEd25519PublicKey(t){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"PublicKey",payload:{type:"Ed25519",privateKey:t}}}).then((t=>Uint8Array.from(t)))}async signEd25519(t,e){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"Ed25519Sign",payload:{privateKey:t,msg:e}}}).then((t=>Uint8Array.from(t)))}}class a{constructor(t,r){this.path=t,this.name=e(r)}getVault(t){return new s(this.path,this.name,e(t))}getStore(){return new o(this.path,this.name)}}class o{constructor(t,e){this.path=t,this.client=e}async get(t){return await window.__TAURI_INVOKE__("plugin:stronghold|get_store_record",{snapshotPath:this.path,client:this.client,key:e(t)}).then((t=>null!=t?Uint8Array.from(t):null))}async insert(t,r,n){return await window.__TAURI_INVOKE__("plugin:stronghold|save_store_record",{snapshotPath:this.path,client:this.client,key:e(t),value:r,lifetime:n})}async remove(t){return await window.__TAURI_INVOKE__("plugin:stronghold|remove_store_record",{snapshotPath:this.path,client:this.client,key:e(t)}).then((t=>null!=t?Uint8Array.from(t):null))}}class s extends n{constructor(t,r,n){super({snapshotPath:t,client:r,vault:n}),this.path=t,this.client=e(r),this.name=e(n)}async insert(t,r){return await window.__TAURI_INVOKE__("plugin:stronghold|save_secret",{snapshotPath:this.path,client:this.client,vault:this.name,recordPath:e(t),secret:r})}async remove(t){return await window.__TAURI_INVOKE__("plugin:stronghold|remove_secret",{snapshotPath:this.path,client:this.client,vault:this.name,recordPath:t.payload.record})}}class i{constructor(t){this.path=t}static async load(t,e){return await window.__TAURI_INVOKE__("plugin:stronghold|initialize",{snapshotPath:t,password:e}).then((()=>new i(t)))}async unload(){return await window.__TAURI_INVOKE__("plugin:stronghold|destroy",{snapshotPath:this.path})}async loadClient(t){return await window.__TAURI_INVOKE__("plugin:stronghold|load_client",{snapshotPath:this.path,client:e(t)}).then((()=>new a(this.path,t)))}async createClient(t){return await window.__TAURI_INVOKE__("plugin:stronghold|create_client",{snapshotPath:this.path,client:e(t)}).then((()=>new a(this.path,t)))}async save(){return await window.__TAURI_INVOKE__("plugin:stronghold|save",{snapshotPath:this.path})}}return t.Client=a,t.Location=r,t.Store=o,t.Stronghold=i,t.Vault=s,t}({});Object.defineProperty(window.__TAURI__,"stronghold",{value:__TAURI_STRONGHOLD__})}

@ -1,4 +1,4 @@
![plugin-updater](banner.png) ![plugin-updater](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/updater/banner.png)
In-app updates for Tauri applications. In-app updates for Tauri applications.

@ -40,7 +40,7 @@ class Update {
} }
async downloadAndInstall( async downloadAndInstall(
onEvent?: (progress: DownloadEvent) => void onEvent?: (progress: DownloadEvent) => void,
): Promise<void> { ): Promise<void> {
const channel = new Channel<DownloadEvent>(); const channel = new Channel<DownloadEvent>();
if (onEvent != null) { if (onEvent != null) {
@ -54,7 +54,7 @@ class Update {
async function check(options?: CheckOptions): Promise<Update> { async function check(options?: CheckOptions): Promise<Update> {
return invoke<UpdateResponse>("plugin:updater|check", { ...options }).then( return invoke<UpdateResponse>("plugin:updater|check", { ...options }).then(
(response) => new Update(response) (response) => new Update(response),
); );
} }

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-upload](banner.png) ![plugin-upload](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/upload/banner.png)
Upload files from disk to a remote server over HTTP. Upload files from disk to a remote server over HTTP.
Download files from a remote HTTP server to disk. Download files from a remote HTTP server to disk.
@ -67,7 +67,7 @@ upload(
"https://example.com/file-upload", "https://example.com/file-upload",
"./path/to/my/file.txt", "./path/to/my/file.txt",
(progress, total) => console.log(`Uploaded ${progress} of ${total} bytes`), // a callback that will be called with the upload progress (progress, total) => console.log(`Uploaded ${progress} of ${total} bytes`), // a callback that will be called with the upload progress
{ "Content-Type": "text/plain" } // optional headers to send with the request { "Content-Type": "text/plain" }, // optional headers to send with the request
); );
``` ```
@ -78,7 +78,7 @@ download(
"https://example.com/file-download-link", "https://example.com/file-download-link",
"./path/to/save/my/file.txt", "./path/to/save/my/file.txt",
(progress, total) => console.log(`Downloaded ${progress} of ${total} bytes`), // a callback that will be called with the download progress (progress, total) => console.log(`Downloaded ${progress} of ${total} bytes`), // a callback that will be called with the download progress
{ "Content-Type": "text/plain" } // optional headers to send with the request { "Content-Type": "text/plain" }, // optional headers to send with the request
); );
``` ```

@ -15,7 +15,7 @@ async function upload(
url: string, url: string,
filePath: string, filePath: string,
progressHandler?: ProgressHandler, progressHandler?: ProgressHandler,
headers?: Map<string, string> headers?: Map<string, string>,
): Promise<void> { ): Promise<void> {
const ids = new Uint32Array(1); const ids = new Uint32Array(1);
window.crypto.getRandomValues(ids); window.crypto.getRandomValues(ids);
@ -43,7 +43,7 @@ async function download(
url: string, url: string,
filePath: string, filePath: string,
progressHandler?: ProgressHandler, progressHandler?: ProgressHandler,
headers?: Map<string, string> headers?: Map<string, string>,
): Promise<void> { ): Promise<void> {
const ids = new Uint32Array(1); const ids = new Uint32Array(1);
window.crypto.getRandomValues(ids); window.crypto.getRandomValues(ids);

@ -25,7 +25,7 @@
"LICENSE" "LICENSE"
], ],
"devDependencies": { "devDependencies": {
"tslib": "^2.5.0" "tslib": "2.6.0"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.0.0-alpha.5" "@tauri-apps/api": "2.0.0-alpha.5"

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-websocket](banner.png) ![plugin-websocket](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/websocket/banner.png)
Expose a WebSocket server to your Tauri frontend. Expose a WebSocket server to your Tauri frontend.
@ -60,7 +60,7 @@ fn main() {
Afterwards all the plugin's APIs are available through the JavaScript guest bindings: Afterwards all the plugin's APIs are available through the JavaScript guest bindings:
```javascript ```javascript
import { WebSocket } from "@tauri-apps/plugin-websocket"; import WebSocket from "@tauri-apps/plugin-websocket";
const ws = await WebSocket.connect("wss://example.com"); const ws = await WebSocket.connect("wss://example.com");

@ -11,14 +11,14 @@
"tauri": "tauri" "tauri": "tauri"
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/adapter-auto": "^2.0.0", "@sveltejs/adapter-auto": "2.1.0",
"@sveltejs/kit": "^1.15.5", "@sveltejs/kit": "1.22.3",
"@tauri-apps/cli": "2.0.0-alpha.10", "@tauri-apps/cli": "2.0.0-alpha.10",
"svelte": "^3.58.0", "svelte": "4.0.5",
"svelte-check": "^3.2.0", "svelte-check": "3.4.6",
"tslib": "^2.5.0", "tslib": "2.6.0",
"typescript": "^5.0.4", "typescript": "5.1.6",
"vite": "^4.3.9" "vite": "4.4.4"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/plugin-websocket": "link:../../" "@tauri-apps/plugin-websocket": "link:../../"

@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

@ -66,7 +66,7 @@ export default class WebSocket {
m = { type: "Binary", data: message }; m = { type: "Binary", data: message };
} else { } else {
throw new Error( throw new Error(
"invalid `message` type, expected a `{ type: string, data: any }` object, a string or a numeric array" "invalid `message` type, expected a `{ type: string, data: any }` object, a string or a numeric array",
); );
} }
return await window.__TAURI_INVOKE__("plugin:websocket|send", { return await window.__TAURI_INVOKE__("plugin:websocket|send", {

@ -24,7 +24,7 @@
"LICENSE" "LICENSE"
], ],
"devDependencies": { "devDependencies": {
"tslib": "^2.5.0" "tslib": "2.6.0"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.0.0-alpha.5" "@tauri-apps/api": "2.0.0-alpha.5"

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-window-state](banner.png) ![plugin-window-state](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/window-state/banner.png)
Save window positions and sizes and restore them when the app is reopened. Save window positions and sizes and restore them when the app is reopened.

@ -25,7 +25,7 @@
"LICENSE" "LICENSE"
], ],
"devDependencies": { "devDependencies": {
"tslib": "^2.5.0" "tslib": "2.6.0"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.0.0-alpha.5" "@tauri-apps/api": "2.0.0-alpha.5"

@ -5,7 +5,7 @@ import { createConfig } from "../../shared/rollup.config.mjs";
export default createConfig({ export default createConfig({
input: "guest-js/index.ts", input: "guest-js/index.ts",
pkg: JSON.parse( pkg: JSON.parse(
readFileSync(new URL("./package.json", import.meta.url), "utf8") readFileSync(new URL("./package.json", import.meta.url), "utf8"),
), ),
external: [/^@tauri-apps\/api/], external: [/^@tauri-apps\/api/],
}); });

@ -1,4 +1,4 @@
![plugin-window](banner.png) ![plugin-window](https://github.com/tauri-apps/plugins-workspace/raw/v2/plugins/window/banner.png)
Interact with the Tauri window. Interact with the Tauri window.

@ -102,7 +102,7 @@ class PhysicalSize {
* Converts the physical size to a logical one. * Converts the physical size to a logical one.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const factor = await appWindow.scaleFactor(); * const factor = await appWindow.scaleFactor();
* const size = await appWindow.innerSize(); * const size = await appWindow.innerSize();
* const logical = size.toLogical(factor); * const logical = size.toLogical(factor);
@ -148,7 +148,7 @@ class PhysicalPosition {
* Converts the physical position to a logical one. * Converts the physical position to a logical one.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const factor = await appWindow.scaleFactor(); * const factor = await appWindow.scaleFactor();
* const position = await appWindow.innerPosition(); * const position = await appWindow.innerPosition();
* const logical = position.toLogical(factor); * const logical = position.toLogical(factor);
@ -258,7 +258,7 @@ function getAll(): WebviewWindow[] {
new WebviewWindow(w.label, { new WebviewWindow(w.label, {
// @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor
skip: true, skip: true,
}) }),
); );
} }
@ -291,7 +291,7 @@ class WebviewWindowHandle {
* *
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const unlisten = await appWindow.listen<string>('state-changed', (event) => { * const unlisten = await appWindow.listen<string>('state-changed', (event) => {
* console.log(`Got error: ${payload}`); * console.log(`Got error: ${payload}`);
* }); * });
@ -309,7 +309,7 @@ class WebviewWindowHandle {
*/ */
async listen<T>( async listen<T>(
event: EventName, event: EventName,
handler: EventCallback<T> handler: EventCallback<T>,
): Promise<UnlistenFn> { ): Promise<UnlistenFn> {
if (this._handleTauriEvent(event, handler)) { if (this._handleTauriEvent(event, handler)) {
return Promise.resolve(() => { return Promise.resolve(() => {
@ -326,7 +326,7 @@ class WebviewWindowHandle {
* *
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const unlisten = await appWindow.once<null>('initialized', (event) => { * const unlisten = await appWindow.once<null>('initialized', (event) => {
* console.log(`Window initialized!`); * console.log(`Window initialized!`);
* }); * });
@ -357,7 +357,7 @@ class WebviewWindowHandle {
* Emits an event to the backend, tied to the webview window. * Emits an event to the backend, tied to the webview window.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.emit('window-loaded', { loggedIn: true, token: 'authToken' }); * await appWindow.emit('window-loaded', { loggedIn: true, token: 'authToken' });
* ``` * ```
* *
@ -403,7 +403,7 @@ class WindowManager extends WebviewWindowHandle {
* The scale factor that can be used to map physical pixels to logical pixels. * The scale factor that can be used to map physical pixels to logical pixels.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const factor = await appWindow.scaleFactor(); * const factor = await appWindow.scaleFactor();
* ``` * ```
* *
@ -421,7 +421,7 @@ class WindowManager extends WebviewWindowHandle {
* The position of the top-left hand corner of the window's client area relative to the top-left hand corner of the desktop. * The position of the top-left hand corner of the window's client area relative to the top-left hand corner of the desktop.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const position = await appWindow.innerPosition(); * const position = await appWindow.innerPosition();
* ``` * ```
* *
@ -435,7 +435,7 @@ class WindowManager extends WebviewWindowHandle {
"plugin:window|inner_position", "plugin:window|inner_position",
{ {
label: this.label, label: this.label,
} },
) )
.then(({ x, y }) => new PhysicalPosition(x, y)); .then(({ x, y }) => new PhysicalPosition(x, y));
} }
@ -444,7 +444,7 @@ class WindowManager extends WebviewWindowHandle {
* The position of the top-left hand corner of the window relative to the top-left hand corner of the desktop. * The position of the top-left hand corner of the window relative to the top-left hand corner of the desktop.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const position = await appWindow.outerPosition(); * const position = await appWindow.outerPosition();
* ``` * ```
* *
@ -458,7 +458,7 @@ class WindowManager extends WebviewWindowHandle {
"plugin:window|outer_position", "plugin:window|outer_position",
{ {
label: this.label, label: this.label,
} },
) )
.then(({ x, y }) => new PhysicalPosition(x, y)); .then(({ x, y }) => new PhysicalPosition(x, y));
} }
@ -468,7 +468,7 @@ class WindowManager extends WebviewWindowHandle {
* The client area is the content of the window, excluding the title bar and borders. * The client area is the content of the window, excluding the title bar and borders.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const size = await appWindow.innerSize(); * const size = await appWindow.innerSize();
* ``` * ```
* *
@ -482,7 +482,7 @@ class WindowManager extends WebviewWindowHandle {
"plugin:window|inner_size", "plugin:window|inner_size",
{ {
label: this.label, label: this.label,
} },
) )
.then(({ width, height }) => new PhysicalSize(width, height)); .then(({ width, height }) => new PhysicalSize(width, height));
} }
@ -492,7 +492,7 @@ class WindowManager extends WebviewWindowHandle {
* These dimensions include the title bar and borders. If you don't want that (and you usually don't), use inner_size instead. * These dimensions include the title bar and borders. If you don't want that (and you usually don't), use inner_size instead.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const size = await appWindow.outerSize(); * const size = await appWindow.outerSize();
* ``` * ```
* *
@ -506,7 +506,7 @@ class WindowManager extends WebviewWindowHandle {
"plugin:window|outer_size", "plugin:window|outer_size",
{ {
label: this.label, label: this.label,
} },
) )
.then(({ width, height }) => new PhysicalSize(width, height)); .then(({ width, height }) => new PhysicalSize(width, height));
} }
@ -515,7 +515,7 @@ class WindowManager extends WebviewWindowHandle {
* Gets the window's current fullscreen state. * Gets the window's current fullscreen state.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const fullscreen = await appWindow.isFullscreen(); * const fullscreen = await appWindow.isFullscreen();
* ``` * ```
* *
@ -533,7 +533,7 @@ class WindowManager extends WebviewWindowHandle {
* Gets the window's current minimized state. * Gets the window's current minimized state.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const minimized = await appWindow.isMinimized(); * const minimized = await appWindow.isMinimized();
* ``` * ```
* *
@ -549,7 +549,7 @@ class WindowManager extends WebviewWindowHandle {
* Gets the window's current maximized state. * Gets the window's current maximized state.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const maximized = await appWindow.isMaximized(); * const maximized = await appWindow.isMaximized();
* ``` * ```
* *
@ -585,7 +585,7 @@ class WindowManager extends WebviewWindowHandle {
* Gets the window's current decorated state. * Gets the window's current decorated state.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const decorated = await appWindow.isDecorated(); * const decorated = await appWindow.isDecorated();
* ``` * ```
* *
@ -603,7 +603,7 @@ class WindowManager extends WebviewWindowHandle {
* Gets the window's current resizable state. * Gets the window's current resizable state.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const resizable = await appWindow.isResizable(); * const resizable = await appWindow.isResizable();
* ``` * ```
* *
@ -684,7 +684,7 @@ class WindowManager extends WebviewWindowHandle {
* Gets the window's current visible state. * Gets the window's current visible state.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const visible = await appWindow.isVisible(); * const visible = await appWindow.isVisible();
* ``` * ```
* *
@ -702,7 +702,7 @@ class WindowManager extends WebviewWindowHandle {
* Gets the window's current title. * Gets the window's current title.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const title = await appWindow.title(); * const title = await appWindow.title();
* ``` * ```
* *
@ -723,7 +723,7 @@ class WindowManager extends WebviewWindowHandle {
* *
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* const theme = await appWindow.theme(); * const theme = await appWindow.theme();
* ``` * ```
* *
@ -743,7 +743,7 @@ class WindowManager extends WebviewWindowHandle {
* Centers the window. * Centers the window.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.center(); * await appWindow.center();
* ``` * ```
* *
@ -772,7 +772,7 @@ class WindowManager extends WebviewWindowHandle {
* - **Linux:** Urgency levels have the same effect. * - **Linux:** Urgency levels have the same effect.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.requestUserAttention(); * await appWindow.requestUserAttention();
* ``` * ```
* *
@ -782,7 +782,7 @@ class WindowManager extends WebviewWindowHandle {
* @since 2.0.0 * @since 2.0.0
*/ */
async requestUserAttention( async requestUserAttention(
requestType: UserAttentionType | null requestType: UserAttentionType | null,
): Promise<void> { ): Promise<void> {
let requestType_ = null; let requestType_ = null;
if (requestType) { if (requestType) {
@ -803,7 +803,7 @@ class WindowManager extends WebviewWindowHandle {
* Updates the window resizable flag. * Updates the window resizable flag.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setResizable(false); * await appWindow.setResizable(false);
* ``` * ```
* *
@ -895,7 +895,7 @@ class WindowManager extends WebviewWindowHandle {
* Sets the window title. * Sets the window title.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setTitle('Tauri'); * await appWindow.setTitle('Tauri');
* ``` * ```
* *
@ -915,7 +915,7 @@ class WindowManager extends WebviewWindowHandle {
* Maximizes the window. * Maximizes the window.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.maximize(); * await appWindow.maximize();
* ``` * ```
* *
@ -933,7 +933,7 @@ class WindowManager extends WebviewWindowHandle {
* Unmaximizes the window. * Unmaximizes the window.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.unmaximize(); * await appWindow.unmaximize();
* ``` * ```
* *
@ -951,7 +951,7 @@ class WindowManager extends WebviewWindowHandle {
* Toggles the window maximized state. * Toggles the window maximized state.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.toggleMaximize(); * await appWindow.toggleMaximize();
* ``` * ```
* *
@ -969,7 +969,7 @@ class WindowManager extends WebviewWindowHandle {
* Minimizes the window. * Minimizes the window.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.minimize(); * await appWindow.minimize();
* ``` * ```
* *
@ -987,7 +987,7 @@ class WindowManager extends WebviewWindowHandle {
* Unminimizes the window. * Unminimizes the window.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.unminimize(); * await appWindow.unminimize();
* ``` * ```
* *
@ -1005,7 +1005,7 @@ class WindowManager extends WebviewWindowHandle {
* Sets the window visibility to true. * Sets the window visibility to true.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.show(); * await appWindow.show();
* ``` * ```
* *
@ -1023,7 +1023,7 @@ class WindowManager extends WebviewWindowHandle {
* Sets the window visibility to false. * Sets the window visibility to false.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.hide(); * await appWindow.hide();
* ``` * ```
* *
@ -1041,7 +1041,7 @@ class WindowManager extends WebviewWindowHandle {
* Closes the window. * Closes the window.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.close(); * await appWindow.close();
* ``` * ```
* *
@ -1059,7 +1059,7 @@ class WindowManager extends WebviewWindowHandle {
* Whether the window should have borders and bars. * Whether the window should have borders and bars.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setDecorations(false); * await appWindow.setDecorations(false);
* ``` * ```
* *
@ -1088,7 +1088,7 @@ class WindowManager extends WebviewWindowHandle {
* *
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setShadow(false); * await appWindow.setShadow(false);
* ``` * ```
* *
@ -1131,7 +1131,7 @@ class WindowManager extends WebviewWindowHandle {
* Whether the window should always be on top of other windows. * Whether the window should always be on top of other windows.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setAlwaysOnTop(true); * await appWindow.setAlwaysOnTop(true);
* ``` * ```
* *
@ -1151,7 +1151,7 @@ class WindowManager extends WebviewWindowHandle {
* Prevents the window contents from being captured by other apps. * Prevents the window contents from being captured by other apps.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setContentProtected(true); * await appWindow.setContentProtected(true);
* ``` * ```
* *
@ -1170,7 +1170,7 @@ class WindowManager extends WebviewWindowHandle {
* Resizes the window with a new inner size. * Resizes the window with a new inner size.
* @example * @example
* ```typescript * ```typescript
* import { appWindow, LogicalSize } from '@tauri-apps/window'; * import { appWindow, LogicalSize } from '@tauri-apps/plugin-window';
* await appWindow.setSize(new LogicalSize(600, 500)); * await appWindow.setSize(new LogicalSize(600, 500));
* ``` * ```
* *
@ -1182,7 +1182,7 @@ class WindowManager extends WebviewWindowHandle {
async setSize(size: LogicalSize | PhysicalSize): Promise<void> { async setSize(size: LogicalSize | PhysicalSize): Promise<void> {
if (!size || (size.type !== "Logical" && size.type !== "Physical")) { if (!size || (size.type !== "Logical" && size.type !== "Physical")) {
throw new Error( throw new Error(
"the `size` argument must be either a LogicalSize or a PhysicalSize instance" "the `size` argument must be either a LogicalSize or a PhysicalSize instance",
); );
} }
@ -1202,7 +1202,7 @@ class WindowManager extends WebviewWindowHandle {
* Sets the window minimum inner size. If the `size` argument is not provided, the constraint is unset. * Sets the window minimum inner size. If the `size` argument is not provided, the constraint is unset.
* @example * @example
* ```typescript * ```typescript
* import { appWindow, PhysicalSize } from '@tauri-apps/window'; * import { appWindow, PhysicalSize } from '@tauri-apps/plugin-window';
* await appWindow.setMinSize(new PhysicalSize(600, 500)); * await appWindow.setMinSize(new PhysicalSize(600, 500));
* ``` * ```
* *
@ -1212,11 +1212,11 @@ class WindowManager extends WebviewWindowHandle {
* @since 2.0.0 * @since 2.0.0
*/ */
async setMinSize( async setMinSize(
size: LogicalSize | PhysicalSize | null | undefined size: LogicalSize | PhysicalSize | null | undefined,
): Promise<void> { ): Promise<void> {
if (size && size.type !== "Logical" && size.type !== "Physical") { if (size && size.type !== "Logical" && size.type !== "Physical") {
throw new Error( throw new Error(
"the `size` argument must be either a LogicalSize or a PhysicalSize instance" "the `size` argument must be either a LogicalSize or a PhysicalSize instance",
); );
} }
@ -1238,7 +1238,7 @@ class WindowManager extends WebviewWindowHandle {
* Sets the window maximum inner size. If the `size` argument is undefined, the constraint is unset. * Sets the window maximum inner size. If the `size` argument is undefined, the constraint is unset.
* @example * @example
* ```typescript * ```typescript
* import { appWindow, LogicalSize } from '@tauri-apps/window'; * import { appWindow, LogicalSize } from '@tauri-apps/plugin-window';
* await appWindow.setMaxSize(new LogicalSize(600, 500)); * await appWindow.setMaxSize(new LogicalSize(600, 500));
* ``` * ```
* *
@ -1248,11 +1248,11 @@ class WindowManager extends WebviewWindowHandle {
* @since 2.0.0 * @since 2.0.0
*/ */
async setMaxSize( async setMaxSize(
size: LogicalSize | PhysicalSize | null | undefined size: LogicalSize | PhysicalSize | null | undefined,
): Promise<void> { ): Promise<void> {
if (size && size.type !== "Logical" && size.type !== "Physical") { if (size && size.type !== "Logical" && size.type !== "Physical") {
throw new Error( throw new Error(
"the `size` argument must be either a LogicalSize or a PhysicalSize instance" "the `size` argument must be either a LogicalSize or a PhysicalSize instance",
); );
} }
@ -1274,7 +1274,7 @@ class WindowManager extends WebviewWindowHandle {
* Sets the window outer position. * Sets the window outer position.
* @example * @example
* ```typescript * ```typescript
* import { appWindow, LogicalPosition } from '@tauri-apps/window'; * import { appWindow, LogicalPosition } from '@tauri-apps/plugin-window';
* await appWindow.setPosition(new LogicalPosition(600, 500)); * await appWindow.setPosition(new LogicalPosition(600, 500));
* ``` * ```
* *
@ -1284,14 +1284,14 @@ class WindowManager extends WebviewWindowHandle {
* @since 2.0.0 * @since 2.0.0
*/ */
async setPosition( async setPosition(
position: LogicalPosition | PhysicalPosition position: LogicalPosition | PhysicalPosition,
): Promise<void> { ): Promise<void> {
if ( if (
!position || !position ||
(position.type !== "Logical" && position.type !== "Physical") (position.type !== "Logical" && position.type !== "Physical")
) { ) {
throw new Error( throw new Error(
"the `position` argument must be either a LogicalPosition or a PhysicalPosition instance" "the `position` argument must be either a LogicalPosition or a PhysicalPosition instance",
); );
} }
@ -1311,7 +1311,7 @@ class WindowManager extends WebviewWindowHandle {
* Sets the window fullscreen state. * Sets the window fullscreen state.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setFullscreen(true); * await appWindow.setFullscreen(true);
* ``` * ```
* *
@ -1331,7 +1331,7 @@ class WindowManager extends WebviewWindowHandle {
* Bring the window to front and focus. * Bring the window to front and focus.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setFocus(); * await appWindow.setFocus();
* ``` * ```
* *
@ -1349,7 +1349,7 @@ class WindowManager extends WebviewWindowHandle {
* Sets the window icon. * Sets the window icon.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setIcon('/tauri/awesome.png'); * await appWindow.setIcon('/tauri/awesome.png');
* ``` * ```
* *
@ -1380,7 +1380,7 @@ class WindowManager extends WebviewWindowHandle {
* - **macOS:** Unsupported. * - **macOS:** Unsupported.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setSkipTaskbar(true); * await appWindow.setSkipTaskbar(true);
* ``` * ```
* *
@ -1408,7 +1408,7 @@ class WindowManager extends WebviewWindowHandle {
* - **macOS:** This locks the cursor in a fixed location, which looks visually awkward. * - **macOS:** This locks the cursor in a fixed location, which looks visually awkward.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setCursorGrab(true); * await appWindow.setCursorGrab(true);
* ``` * ```
* *
@ -1434,7 +1434,7 @@ class WindowManager extends WebviewWindowHandle {
* outside of the window. * outside of the window.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setCursorVisible(false); * await appWindow.setCursorVisible(false);
* ``` * ```
* *
@ -1454,7 +1454,7 @@ class WindowManager extends WebviewWindowHandle {
* Modifies the cursor icon of the window. * Modifies the cursor icon of the window.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setCursorIcon('help'); * await appWindow.setCursorIcon('help');
* ``` * ```
* *
@ -1474,7 +1474,7 @@ class WindowManager extends WebviewWindowHandle {
* Changes the position of the cursor in window coordinates. * Changes the position of the cursor in window coordinates.
* @example * @example
* ```typescript * ```typescript
* import { appWindow, LogicalPosition } from '@tauri-apps/window'; * import { appWindow, LogicalPosition } from '@tauri-apps/plugin-window';
* await appWindow.setCursorPosition(new LogicalPosition(600, 300)); * await appWindow.setCursorPosition(new LogicalPosition(600, 300));
* ``` * ```
* *
@ -1484,14 +1484,14 @@ class WindowManager extends WebviewWindowHandle {
* @since 2.0.0 * @since 2.0.0
*/ */
async setCursorPosition( async setCursorPosition(
position: LogicalPosition | PhysicalPosition position: LogicalPosition | PhysicalPosition,
): Promise<void> { ): Promise<void> {
if ( if (
!position || !position ||
(position.type !== "Logical" && position.type !== "Physical") (position.type !== "Logical" && position.type !== "Physical")
) { ) {
throw new Error( throw new Error(
"the `position` argument must be either a LogicalPosition or a PhysicalPosition instance" "the `position` argument must be either a LogicalPosition or a PhysicalPosition instance",
); );
} }
@ -1512,7 +1512,7 @@ class WindowManager extends WebviewWindowHandle {
* *
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.setIgnoreCursorEvents(true); * await appWindow.setIgnoreCursorEvents(true);
* ``` * ```
* *
@ -1532,7 +1532,7 @@ class WindowManager extends WebviewWindowHandle {
* Starts dragging the window. * Starts dragging the window.
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from '@tauri-apps/window'; * import { appWindow } from '@tauri-apps/plugin-window';
* await appWindow.startDragging(); * await appWindow.startDragging();
* ``` * ```
* *
@ -1606,7 +1606,7 @@ class WindowManager extends WebviewWindowHandle {
* @example * @example
* ```typescript * ```typescript
* import { appWindow } from "@tauri-apps/plugin-window"; * import { appWindow } from "@tauri-apps/plugin-window";
* import { confirm } from '@tauri-apps/api/dialog'; * import { confirm } from '@tauri-apps/plugin-dialog';
* const unlisten = await appWindow.onCloseRequested(async (event) => { * const unlisten = await appWindow.onCloseRequested(async (event) => {
* const confirmed = await confirm('Are you sure?'); * const confirmed = await confirm('Are you sure?');
* if (!confirmed) { * if (!confirmed) {
@ -1626,7 +1626,7 @@ class WindowManager extends WebviewWindowHandle {
*/ */
/* eslint-disable @typescript-eslint/promise-function-async */ /* eslint-disable @typescript-eslint/promise-function-async */
async onCloseRequested( async onCloseRequested(
handler: (event: CloseRequestedEvent) => void | Promise<void> handler: (event: CloseRequestedEvent) => void | Promise<void>,
): Promise<UnlistenFn> { ): Promise<UnlistenFn> {
return this.listen<null>(TauriEvent.WINDOW_CLOSE_REQUESTED, (event) => { return this.listen<null>(TauriEvent.WINDOW_CLOSE_REQUESTED, (event) => {
const evt = new CloseRequestedEvent(event); const evt = new CloseRequestedEvent(event);
@ -1663,13 +1663,13 @@ class WindowManager extends WebviewWindowHandle {
TauriEvent.WINDOW_FOCUS, TauriEvent.WINDOW_FOCUS,
(event) => { (event) => {
handler({ ...event, payload: true }); handler({ ...event, payload: true });
} },
); );
const unlistenBlur = await this.listen<PhysicalPosition>( const unlistenBlur = await this.listen<PhysicalPosition>(
TauriEvent.WINDOW_BLUR, TauriEvent.WINDOW_BLUR,
(event) => { (event) => {
handler({ ...event, payload: false }); handler({ ...event, payload: false });
} },
); );
return () => { return () => {
unlistenFocus(); unlistenFocus();
@ -1701,11 +1701,11 @@ class WindowManager extends WebviewWindowHandle {
* @since 2.0.0 * @since 2.0.0
*/ */
async onScaleChanged( async onScaleChanged(
handler: EventCallback<ScaleFactorChanged> handler: EventCallback<ScaleFactorChanged>,
): Promise<UnlistenFn> { ): Promise<UnlistenFn> {
return this.listen<ScaleFactorChanged>( return this.listen<ScaleFactorChanged>(
TauriEvent.WINDOW_SCALE_FACTOR_CHANGED, TauriEvent.WINDOW_SCALE_FACTOR_CHANGED,
handler handler,
); );
} }
@ -1760,27 +1760,27 @@ class WindowManager extends WebviewWindowHandle {
* @since 2.0.0 * @since 2.0.0
*/ */
async onFileDropEvent( async onFileDropEvent(
handler: EventCallback<FileDropEvent> handler: EventCallback<FileDropEvent>,
): Promise<UnlistenFn> { ): Promise<UnlistenFn> {
const unlistenFileDrop = await this.listen<string[]>( const unlistenFileDrop = await this.listen<string[]>(
TauriEvent.WINDOW_FILE_DROP, TauriEvent.WINDOW_FILE_DROP,
(event) => { (event) => {
handler({ ...event, payload: { type: "drop", paths: event.payload } }); handler({ ...event, payload: { type: "drop", paths: event.payload } });
} },
); );
const unlistenFileHover = await this.listen<string[]>( const unlistenFileHover = await this.listen<string[]>(
TauriEvent.WINDOW_FILE_DROP_HOVER, TauriEvent.WINDOW_FILE_DROP_HOVER,
(event) => { (event) => {
handler({ ...event, payload: { type: "hover", paths: event.payload } }); handler({ ...event, payload: { type: "hover", paths: event.payload } });
} },
); );
const unlistenCancel = await this.listen<null>( const unlistenCancel = await this.listen<null>(
TauriEvent.WINDOW_FILE_DROP_CANCELLED, TauriEvent.WINDOW_FILE_DROP_CANCELLED,
(event) => { (event) => {
handler({ ...event, payload: { type: "cancel" } }); handler({ ...event, payload: { type: "cancel" } });
} },
); );
return () => { return () => {
@ -1879,7 +1879,7 @@ class WebviewWindow extends WindowManager {
* Creates a new WebviewWindow. * Creates a new WebviewWindow.
* @example * @example
* ```typescript * ```typescript
* import { WebviewWindow } from '@tauri-apps/window'; * import { WebviewWindow } from '@tauri-apps/plugin-window';
* const webview = new WebviewWindow('my-label', { * const webview = new WebviewWindow('my-label', {
* url: 'https://github.com/tauri-apps/tauri' * url: 'https://github.com/tauri-apps/tauri'
* }); * });
@ -1916,7 +1916,7 @@ class WebviewWindow extends WindowManager {
* Gets the WebviewWindow for the webview associated with the given label. * Gets the WebviewWindow for the webview associated with the given label.
* @example * @example
* ```typescript * ```typescript
* import { WebviewWindow } from '@tauri-apps/window'; * import { WebviewWindow } from '@tauri-apps/plugin-window';
* const mainWindow = WebviewWindow.getByLabel('main'); * const mainWindow = WebviewWindow.getByLabel('main');
* ``` * ```
* *
@ -1963,11 +1963,11 @@ if ("__TAURI_METADATA__" in window) {
{ {
// @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor
skip: true, skip: true,
} },
); );
} else { } else {
console.warn( console.warn(
`Could not find "window.__TAURI_METADATA__". The "appWindow" value will reference the "main" window label.\nNote that this is not an issue if running this frontend on a browser instead of a Tauri window.` `Could not find "window.__TAURI_METADATA__". The "appWindow" value will reference the "main" window label.\nNote that this is not an issue if running this frontend on a browser instead of a Tauri window.`,
); );
appWindow = new WebviewWindow("main", { appWindow = new WebviewWindow("main", {
// @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor
@ -2296,7 +2296,7 @@ function mapPhysicalSize(m: PhysicalSize): PhysicalSize {
* Returns `null` if current monitor can't be detected. * Returns `null` if current monitor can't be detected.
* @example * @example
* ```typescript * ```typescript
* import { currentMonitor } from '@tauri-apps/window'; * import { currentMonitor } from '@tauri-apps/plugin-window';
* const monitor = currentMonitor(); * const monitor = currentMonitor();
* ``` * ```
* *
@ -2313,7 +2313,7 @@ async function currentMonitor(): Promise<Monitor | null> {
* Returns `null` if it can't identify any monitor as a primary one. * Returns `null` if it can't identify any monitor as a primary one.
* @example * @example
* ```typescript * ```typescript
* import { primaryMonitor } from '@tauri-apps/window'; * import { primaryMonitor } from '@tauri-apps/plugin-window';
* const monitor = primaryMonitor(); * const monitor = primaryMonitor();
* ``` * ```
* *
@ -2329,7 +2329,7 @@ async function primaryMonitor(): Promise<Monitor | null> {
* Returns the list of all the monitors available on the system. * Returns the list of all the monitors available on the system.
* @example * @example
* ```typescript * ```typescript
* import { availableMonitors } from '@tauri-apps/window'; * import { availableMonitors } from '@tauri-apps/plugin-window';
* const monitors = availableMonitors(); * const monitors = availableMonitors();
* ``` * ```
* *

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save