Compare commits

...

103 Commits

Author SHA1 Message Date
github-actions[bot] 3eebea2a17 publish new versions (#2712)
Co-authored-by: FabianLars <30730186+FabianLars@users.noreply.github.com>
2025-06-16 23:50:39 +02:00
FabianLars 6bc3e81dc6 chore: Remove recently released crates from refresh list 2025-06-16 23:49:01 +02:00
Fabian-Lars f634e5248e chore: Add changefile to refresh all packages. 2025-06-16 23:42:40 +02:00
kandrelczyk 9841ff81ce chore: add contributing guide (#2753) 2025-06-16 22:05:11 +02:00
renovate[bot] 2e680620c4 chore(deps): update rust crate windows-sys to v0.60.2 (v2) (#2763)
* chore(deps): update rust crate windows-sys to v0.60.2

* update lock file
2025-06-16 18:53:33 +08:00
Tony 041b93f46b chore(deps): fix brace expansion pnpm audit (#2773) 2025-06-16 12:40:40 +02:00
renovate[bot] a05698ac24 chore(deps): update dependency rollup to v4.43.0 (#2759)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-16 15:12:10 +08:00
renovate[bot] 0acca18f65 chore(deps): update eslint monorepo to v9.29.0 (#2766)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-16 15:05:14 +08:00
Fabian-Lars ce9888a2d4 feat(opener): Add requireLiteralLeadingDot config (#2762) 2025-06-12 13:39:36 +02:00
kris-ava 106e46ed51 feat(log): Add KeepSome rotation strategy (#677)
Co-authored-by: Krzysztof Krolak <krzysiek.krolak@gmail.com>
Co-authored-by: FabianLars <github@fabianlars.de>
2025-06-10 19:46:10 +02:00
renovate[bot] 8b63de9dfe chore(deps): update dependency rollup to v4.42.0 (v2) (#2750)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: FabianLars <github@fabianlars.de>
2025-06-10 15:22:34 +02:00
Tony 73ff15de5d fix(updater): fix headers option in Updater.download (#2757) 2025-06-10 13:48:17 +02:00
renovate[bot] ff19affa7b chore(deps): update dependency typescript-eslint to v8.34.0 (#2755)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-10 09:34:46 +08:00
renovate[bot] f501bc2f1c chore(deps): update dependency typescript-eslint to v8.33.1 (#2735)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-04 18:17:59 +08:00
Brendan Osborne 87afa23cad feat(updater): add allowDowngrades option (#2726)
* feat(updater): add allowDowngrades option

* Add change file for allow_downgrades feature

* Update .changes/add-allow-downgrades.md
2025-06-02 11:22:06 +08:00
renovate[bot] d40190721c chore(deps): update eslint monorepo to v9.28.0 (#2730)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-31 08:59:06 +08:00
renovate[bot] 909bc1f9ca chore(deps): update dependency typescript-eslint to v8.33.0 (#2722)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-28 11:45:04 +02:00
renovate[bot] 9bc4b2230e chore(deps): update dependency rollup to v4.41.1 (#2715)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-24 16:05:46 +08:00
Fabian-Lars b9dc03d5ce docs(geolocation): fix android feature name 2025-05-22 13:56:46 +02:00
renovate[bot] cd8fbf834a chore(deps): update rust crate zip to v4 (#2711)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-22 13:37:52 +08:00
Tunglies 764e8f7719 feat(autostart): add app name configuration for auto start entry (#2707)
* feat(autostart): add prefered name configuration for auto start entry

- Add PreferedName enum to support different naming strategies
- Implement Default trait for PreferedName with PackageInfoName as default
- Add prefered_name builder method with documentation and examples
- Integrate prefered name into auto start configuration

This change allows users to customize the name of their application in the
auto start entry using various naming strategies like package info name,
crate name, config identifier, or custom name.

* refactor(autostart): rename prefered_name to app_name and update related logic

- Change prefered_name to app_name in the Builder struct and methods
- Update PreferedName enum to include new variants and set AppName as default
- Modify documentation to reflect the new app_name usage for auto start entry

This refactor improves clarity in naming conventions and enhances the configuration options for auto start entries.

* refactor(autostart): update app_name handling in README and lib.rs

- Change app_name usage in README to a custom string
- Simplify app_name handling in lib.rs by removing PreferedName enum
- Update Builder struct to accept app_name as an optional string

This refactor enhances the clarity and usability of the auto start configuration.

* feat(autostart): add app_name builder method for custom application naming

- Introduced a new builder method app_name() to customize the application name in the autostart entry.
- Updated app_name handling in the Builder struct to accept a generic string type.

This enhancement allows for greater flexibility in defining application names for autostart configurations.

* Update .changes/autostart-feature.md

Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com>

* [skip ci] format

---------

Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com>
2025-05-20 23:51:36 +08:00
github-actions[bot] 85635a2807 publish new versions (#2643)
Co-authored-by: FabianLars <30730186+FabianLars@users.noreply.github.com>
2025-05-20 10:27:36 +02:00
renovate[bot] 848e703b78 chore(deps): update dependency rollup to v4.41.0 (#2702)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-18 10:45:25 +02:00
renovate[bot] b768b0623b chore(deps): update rust crate zip to v3 (v2) (#2699)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: FabianLars <github@fabianlars.de>
2025-05-18 10:44:49 +02:00
renovate[bot] 047081c3d5 chore(deps): update dependency typescript-eslint to v8.32.1 (#2692)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-18 09:56:13 +02:00
renovate[bot] 7cd8c7806e chore(deps): update eslint monorepo to v9.27.0 (#2698)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-18 10:59:38 +08:00
Shaun Hamilton 6c9e08dccb fix(opener-js): allow URL type (#2695)
* fix(opener-js): allow URL type

* bump opener rs in change file

---------

Co-authored-by: Tony <legendmastertony@gmail.com>
2025-05-14 17:58:54 +08:00
renovate[bot] a6b854032d chore(deps): update dependency eslint-config-prettier to v10.1.5 (#2688)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-09 13:57:48 +08:00
renovate[bot] 494d1fea13 chore(deps): update rust crate global-hotkey to 0.7 (v2) (#2684)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Fabian-Lars <github@fabianlars.de>
2025-05-07 11:17:59 +02:00
renovate[bot] 4a29dd6cc6 chore(deps): update eslint monorepo to v9.26.0 (#2673)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-07 10:51:38 +02:00
renovate[bot] fa778d602a chore(deps): update dependency eslint-config-prettier to v10.1.3 (#2685)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-07 16:27:59 +08:00
renovate[bot] 323afd1b6d chore(deps): update dependency rollup to v4.40.2 (#2681)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-06 21:33:21 +08:00
renovate[bot] 682bb47cda chore(deps): update dependency typescript-eslint to v8.32.0 (#2679)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-06 11:28:55 +08:00
renovate[bot] 98e268a98f chore(deps): update dependency vite to v6.2.7 [security] (#2669)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-30 23:19:22 +02:00
Łukasz Mariański 4d10acee61 feat(deep-link): Add more AssociatedDomain attributes (android) (#993)
Co-authored-by: FabianLars <github@fabianlars.de>
2025-04-30 21:51:38 +02:00
asomethings 2448e717e5 feat(http): add status code 101, 103 for null body (#2655) 2025-04-30 19:52:23 +03:00
renovate[bot] 91d1521a4c chore(deps): update dependency typescript-eslint to v8.31.1 (#2666)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-29 08:34:02 +08:00
renovate[bot] dce04b7d72 chore(deps): update dependency rollup to v4.40.1 (#2663)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 15:46:34 +08:00
renovate[bot] d8e627522c chore(deps): update dependency typescript-eslint to v8.31.0 (#2652)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-22 22:13:18 +08:00
renovate[bot] 5cb158983c chore(deps): update eslint monorepo to v9.25.1 (#2651)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-22 22:10:18 +08:00
renovate[bot] dde6f3c31c chore(deps): update rust crate windows to 0.61 (v2) (#2549)
* chore(deps): update rust crate windows to 0.61

* Change file

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tony <legendmastertony@gmail.com>
2025-04-20 20:17:32 +08:00
Tony dac4d53724 refactor(fs): reduce overhead of watch (#2613) 2025-04-19 13:35:14 +02:00
Amr Bashir 5e78988f72 feat(http): handle 205, 304 null body (#2647)
followup to #2636

ref: https://github.com/tauri-apps/plugins-workspace/pull/2636#issuecomment-2815593359
2025-04-19 12:45:41 +02:00
renovate[bot] 4089002880 chore(deps): update eslint monorepo to v9.25.0 (#2644)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-19 07:18:58 +08:00
Simon Laux dc84f8d8bb single-instance: fix cwd in single instance on macOS (#2609)
* single-instance: fix `cwd` in single instance on macOS

which was the `cwd` of the first instance, instead of the second how it should be and is  on windows and linux.

also add rustfmt.toml to enforce the correct formatting (4 spaces for indent)

* use split_once

* remove rustfmt

* fix indentation

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
2025-04-18 10:14:52 -03:00
asomethings ff384cbabe fix(http): handle status code 204 to use js null fix #2580 (#2636)
* fix(http): handle status code 204 to use javascript null

* add change file

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
2025-04-18 09:53:25 -03:00
github-actions[bot] 4bb51b3cc8 publish new versions (#2603)
Co-authored-by: lucasfernog <20051258+lucasfernog@users.noreply.github.com>
2025-04-18 09:04:15 -03:00
Tony c5b0f51cfd fix(updater): don't override user provided headers (#2621) 2025-04-16 23:09:49 -03:00
Patrick F. 10f9e66e32 fix(biometric) prompt for fallback credentials when enabled and biometry unavailable on iOS (fix #2632) (#2633) 2025-04-16 17:56:43 -03:00
renovate[bot] c97e9c511d chore(deps): update tauri monorepo to v2.5.0 (v2) (#2634)
* chore(deps): update tauri monorepo to v2.5.0

* Update rust dependency and re-build iifes

* Downgrade for msrv

don't know why MSRV-aware resolver didn't work

* Downgrade cargo_metadata

* Downgrade home

* Downgrade native-tls

* trigger ci?

* Downgrade colored and base64ct

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tony <legendmastertony@gmail.com>
2025-04-16 10:27:20 +08:00
renovate[bot] 60075f0fb6 chore(deps): update dependency typescript-eslint to v8.30.1 (#2630)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-15 09:24:39 +08:00
Merlin Gough f81e8003c0 chore(notifications): regen lockfile bumping notify-rust to 4.11.7 (#2623) 2025-04-14 14:47:02 +02:00
Lucas Fernandes Nogueira 686a839c96 fix(log): iOS simulator freezes when calling os_log too early (#2626)
let's delay logs on simulator to prevent deadlocks - looks like the logging system isn't available when the Rust process starts, and it's freezing the app (simulator only)

closes https://github.com/tauri-apps/tauri/issues/12172
2025-04-12 12:50:18 -03:00
renovate[bot] db7baff3fc chore(deps): update dependency rollup to v4.40.0 (#2627)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-12 17:46:15 +08:00
Lucas Fernandes Nogueira c9b21f6f43 fix(log): export the LogLevel type (#2625)
* fix(log): export the LogLevel type

`LogLevel` is an argument of the log functions but it's incorrectly not exported

* rebuild
2025-04-11 20:35:05 -03:00
dependabot[bot] c698e72594 chore(deps): bump crossbeam-channel (#2616)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-10 16:53:39 +02:00
renovate[bot] 4ec8716155 chore(deps): update dependency eslint-config-prettier to v10.1.2 (v2) (#2611)
* chore(deps): update dependency eslint-config-prettier to v10.1.2

* Bump vite

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tony <legendmastertony@gmail.com>
2025-04-10 19:22:11 +08:00
Tony 2445e103f2 refactor(log): use time macro (#2604) 2025-04-08 20:01:11 +08:00
Tony 4cd625049d docs: fix log targets docs (#2602)
* docs: fix log targets docs

* replace(s)
2025-04-08 20:00:59 +08:00
renovate[bot] d88387ace6 chore(deps): update dependency typescript-eslint to v8.29.1 (#2606)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-08 11:25:39 +08:00
renovate[bot] ba611e4341 chore(deps): update rust crate tokio to v1.43.1 [security] (#2607)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-08 09:35:39 +08:00
Jim 60fc35d35c Support emitting traces behind feature flag (#2576)
* Let logging be skippable so user can handle logger()

* Add changes file

* changes meta info

* Update documentation

* Support emitting to tracing behind feature flag

* typo

* rename key_values => kv

* changes file

* Remove rebase skip-logger

* fix format
2025-04-07 10:33:52 +08:00
TATSUNO “Taz” Yasuhiro 9629c2f4f9 [v2][log]: Add generic fern::Dispatch TargetKind to log (#2600)
* [v2][log]: Add generic fern::Dispatch TargetKind to log

Original: https://github.com/tauri-apps/plugins-workspace/pull/1130/commits/b691382d1ea54733ca837995cfac9f82ea05f168

* Add change file

* clippy

---------

Co-authored-by: Tony <legendmastertony@gmail.com>
Co-authored-by: venkr <venkateshrameshkumar+1@gmail.com>
2025-04-07 10:13:17 +08:00
East Monster 🍉 d1609913be docs: acces -> access typo (#2599) 2025-04-05 10:39:58 +08:00
renovate[bot] c2fd60ab3f chore(deps): update eslint monorepo to v9.24.0 (#2596)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-05 10:25:56 +08:00
dependabot[bot] 996975ce52 chore(deps): bump openssl (#2595)
Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.70 to 0.10.72.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.70...openssl-v0.10.72)

---
updated-dependencies:
- dependency-name: openssl
  dependency-version: 0.10.72
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-05 10:06:48 +08:00
renovate[bot] 20770a96ae chore(deps): update dependency typescript to v5.8.3 (#2597)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-05 10:05:19 +08:00
renovate[bot] efe3f88acd chore(deps): update dependency rollup to v4.39.0 (#2590)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-02 17:18:15 +08:00
github-actions[bot] 8b39aefb1b publish new versions (#2545)
Co-authored-by: lucasfernog <20051258+lucasfernog@users.noreply.github.com>
2025-04-02 00:31:52 -03:00
Lucas Nogueira beab018b21 fix: remove packageManager field from package.json 2025-04-02 00:27:37 -03:00
Tillmann 9cf0390a52 Merge commit from fork
* fix(shell): properly validate open scope

* change empty regex to an impossible match

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
Co-authored-by: Chip Reed <chip@chip.sh>
2025-04-02 00:24:25 -03:00
renovate[bot] 4dd5c51436 chore(deps): update tauri monorepo to v2.4.1 (v2) (#2589)
* chore(deps): update tauri monorepo to v2.4.1

* Update tauri and regenerate command ref and schema

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tony <legendmastertony@gmail.com>
2025-04-02 09:37:19 +08:00
Tony d2aef2fddb chore(process): use request_restart (#2581) 2025-04-01 22:17:23 +08:00
renovate[bot] 02e886b21a chore(deps): update dependency vite to v6.2.4 [security] (#2585)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-01 08:58:54 +08:00
renovate[bot] d78930cdd4 chore(deps): update dependency typescript-eslint to v8.29.0 (#2586)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-01 08:58:34 +08:00
Tony a35fea5015 fix(window-state): window size jump on multi monitor setup (#2583)
* fix: window size jump on multi monitor setup

* Add change file
2025-03-31 22:34:57 +08:00
Tony a77b1353e9 refactor(window-state): simply some code (#2578) 2025-03-30 00:31:54 +08:00
renovate[bot] 6fa388d0b2 chore(deps): update dependency rollup to v4.38.0 (#2577)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-29 15:16:09 +08:00
Tony 2d731f8022 fix(updater): format Update.date to RFC 3339 (#2573)
* fix(updater): format `Update.date` to RFC 3339

* Messed up on argument in #2572

* Format

* Update example

* Avoid extra to_string

* Deprecate `Update.available`
2025-03-29 08:36:50 +08:00
Tony 0bc5d58874 fix(updater): download reuses check's timeout (#2572)
* fix(updater): download inherit timeout from check

* Add change file
2025-03-28 18:53:49 +08:00
renovate[bot] 517a29a1a1 chore(deps): update dependency vite to v6.2.3 [security] (#2570)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-25 23:19:24 +08:00
Tony 8ecb418a1a feat(auto-start): introduce a builder (#2569)
* feat(auto-start): introduce a builder

* Update examples

* Fix missing end --- in change file

* Fix missing self.

* Update .changes/autostart-builder.md

Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>

---------

Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>
2025-03-25 22:57:40 +08:00
renovate[bot] 286e3c6252 chore(deps): update dependency typescript-eslint to v8.28.0 (#2567)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-25 10:04:19 +08:00
renovate[bot] 174b31b8b1 chore(deps): update dependency rollup to v4.37.0 (#2565)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-24 09:44:35 +08:00
renovate[bot] 35c1cd9aa5 chore(deps): update eslint monorepo to v9.23.0 (#2559)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-22 10:34:32 +08:00
Teddy Byron 37c0477afe feat(http): add zstd support (#2561) 2025-03-22 03:26:57 +02:00
Tim Ramage 831c35ff39 fix(fs): convert async iterator syntax to manual read (#2550) 2025-03-21 09:19:50 +02:00
renovate[bot] a9cbefc910 chore(deps): update tauri monorepo to v2.4.0 (v2) (#2555)
* chore(deps): update tauri monorepo to v2.4.0

* Bump tauri rust crates in lock file

* Re-generate window-state api-iife.js

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tony <legendmastertony@gmail.com>
2025-03-21 11:16:29 +08:00
renovate[bot] 43f0f95da6 chore(deps): update dependency typescript-eslint to v8.27.0 (#2551)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-20 14:18:34 +08:00
Tony 38deef43dc fix(deep-link): local machine registry handling (#2483)
* fix(deep-link): local machine registry handling

* typo

* Wrong version bump

* return false if registry open fails

---------

Co-authored-by: Lucas Fernandes Nogueira <lucas@tauri.app>
2025-03-18 09:18:43 -03:00
renovate[bot] c245f123ea chore(deps): update rust crate zip to v2.3.0 [security] (#2547)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-18 11:36:35 +08:00
renovate[bot] 8c540d54a1 chore(deps): update dependency rollup to v4.36.0 (#2543)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-17 19:35:52 +08:00
Amr Bashir 9ebbfb2e3c feat(http): persist cookies on disk (#1978)
* enhance(http): persist cookies on disk

closes tauri-apps/tauri#11518

* clippy

* inline reqwest_cookie_store to fix clippy

* clippy

* Update .changes/persist-cookies.md

* Update plugins/http/src/reqwest_cookie_store.rs

* update example

* fallback to empty store if failed to load

* fix example

* persist cookies immediately

* clone

* lint

* .cookies filename

* prevent race condition

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
2025-03-17 07:26:42 -03:00
github-actions[bot] 4bbcdbd556 publish new versions (#2542) 2025-03-16 21:51:48 -03:00
Lucas Fernandes Nogueira 12c4537b8e feat(updater): add support to riscv64 architecture (#2541)
Tauri now supports it, so the updater should check the riscv64 arch and replace the {{arch}} and {{target}} variables properly.

ref https://github.com/tauri-apps/tauri/pull/12602/
2025-03-17 02:42:37 +02:00
Amr Bashir a15eedf378 fix(http): avoid closing stream multiple times (#2535)
* fix(http): avoid closing stream multiple times

closes #2533

* use different signal than empty vec
2025-03-16 16:45:45 -03:00
github-actions[bot] 5347de8db9 publish new versions (#2534)
Co-authored-by: amrbashir <48618675+amrbashir@users.noreply.github.com>
2025-03-15 02:08:18 +02:00
Adriel Jansen Siahaya d3183aa99d fix(http): return response early in JS before waiting for chunks on the rust side (#2522) 2025-03-15 02:06:41 +02:00
github-actions[bot] 1e9e496b06 publish new versions (#2526)
Co-authored-by: FabianLars <30730186+FabianLars@users.noreply.github.com>
2025-03-12 22:29:34 +01:00
Knobibrot 1bb1ced538 feat(log): enable TargetKind::LogDir on mobile (#2524)
* enable log dir on iOS/Android

* Create change-pr-2524.md

---------

Co-authored-by: Fabian-Lars <github@fabianlars.de>
2025-03-12 22:27:40 +01:00
renovate[bot] 68eb74353b chore(deps): update dependency @rollup/plugin-node-resolve to v16.0.1 (#2520)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-12 16:34:42 +08:00
renovate[bot] 95e8f909b1 chore(deps): update dependency typescript-eslint to v8.26.1 (#2517)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-10 20:55:32 +01:00
renovate[bot] 8882dea3b9 chore(deps): update rust crate android_logger to 0.15 (#2502)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-10 16:00:28 +01:00
211 changed files with 4758 additions and 3095 deletions
+64
View File
@@ -0,0 +1,64 @@
# Tauri Contributing Guide
Hi! We, the maintainers, are really excited that you are interested in contributing to Tauri. Before submitting your contribution though, please make sure to take a moment and read through the [Code of Conduct](CODE_OF_CONDUCT.md), as well as the appropriate section for the contribution you intend to make:
- [Issue Reporting Guidelines](#issue-reporting-guidelines)
- [Pull Request Guidelines](#pull-request-guidelines)
- [Development Guide](#development-guide)
## Issue Reporting Guidelines
- The issue list of this repo is **exclusively** for bug reports and feature requests. Non-conforming issues will be closed immediately.
- If you have a question, you can get quick answers from the [Tauri Discord chat](https://discord.com/invite/tauri).
- Try to search for your issue, it may have already been answered or even fixed in the development branch (`v2`).
- Check if the issue is reproducible with the latest stable version of Tauri. If you are using a pre-release, please indicate the specific version you are using.
- It is **required** that you clearly describe the steps necessary to reproduce the issue you are running into. Although we would love to help our users as much as possible, diagnosing issues without clear reproduction steps is extremely time-consuming and simply not sustainable.
- Use only the minimum amount of code necessary to reproduce the unexpected behavior. A good bug report should isolate specific methods that exhibit unexpected behavior and precisely define how expectations were violated. What did you expect the method or methods to do, and how did the observed behavior differ? The more precisely you isolate the issue, the faster we can investigate.
- Issues with no clear repro steps will not be triaged. If an issue labeled "need repro" receives no further input from the issue author for more than 5 days, it will be closed.
- If your issue is resolved but still open, don't hesitate to close it. In case you found a solution by yourself, it could be helpful for others to explain how you fixed it.
- Most importantly, we beg your patience: the team must balance your request against many other responsibilities — fixing other bugs, answering other questions, new features, new documentation, etc. The issue list is not paid support and we cannot make guarantees about how fast your issue can be resolved.
## Pull Request Guidelines
- You have to [sign your commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits).
- It's OK to have multiple small commits as you work on the PR - we will let GitHub automatically squash it before merging.
- If adding new feature:
- Provide convincing reason to add this feature. Ideally you should open a suggestion issue first and have it greenlighted before working on it.
- If fixing a bug:
- If you are resolving a special issue, add `(fix: #xxxx[,#xxx])` (#xxxx is the issue id) in your PR title for a better release log, e.g. `fix: update entities encoding/decoding (fix #3899)`.
- Provide detailed description of the bug in the PR, or link to an issue that does.
- If the PR is meant to be released, follow the instructions in `.changes/readme.md` to log your changes. ie. [readme.md](https://github.com/tauri-apps/plugins-workspace/blob/v2/.changes/readme.md)
## Development Guide
**NOTE: If you have any question don't hesitate to ask in our Discord server. We try to keep this guide to up guide, but if something doesn't work let us know.**
### General Setup
First, [join our Discord server](https://discord.com/invite/tauri) and let us know that you want to contribute. This way we can point you in the right direction and help ensure your contribution will be as helpful as possible.
To set up your machine for development, follow the [Tauri setup guide](https://v2.tauri.app/start/prerequisites/) to get all the tools you need to develop Tauri apps. The only additional tool you may need is [PNPM](https://pnpm.io/).
Next, [fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo) and clone [this repository](https://github.com/tauri-apps/plugins-workspace/tree/v2).
### Developing and testing
The easiest way to test your changes is to use the [example app](https://github.com/tauri-apps/plugins-workspace/tree/v2/examples/api) example app. It automatically rebuilds and uses your local copy of the plugins. To run it follow the instructions inside [README.md](https://github.com/tauri-apps/plugins-workspace/blob/v2/examples/api/README.md).
To test local changes against your own application simply point the plugin create to your local repository, for example:
`tauri-plugin-sample = { path = "path/to/local/tauri-plugin-sample/" }`
+2 -1
View File
@@ -57,4 +57,5 @@ pids
*.sublime*
.idea
debug.log
TODO.md
TODO.md
.aider*
Generated
+1126 -1098
View File
File diff suppressed because it is too large Load Diff
+66
View File
@@ -1,5 +1,71 @@
# Changelog
## \[2.0.23]
### Dependencies
- Upgraded to `updater-js@2.8.0`
- Upgraded to `barcode-scanner-js@2.2.1`
- Upgraded to `biometric-js@2.2.2`
- Upgraded to `cli-js@2.2.1`
- Upgraded to `clipboard-manager-js@2.2.3`
- Upgraded to `nfc-js@2.2.1`
- Upgraded to `notification-js@2.2.3`
- Upgraded to `os-js@2.2.2`
- Upgraded to `process-js@2.2.2`
- Upgraded to `shell-js@2.2.2`
- Upgraded to `store-js@2.2.1`
- Upgraded to `log-js@2.5.0`
- Upgraded to `opener-js@2.3.0`
## \[2.0.22]
### Dependencies
- Upgraded to `fs-js@2.3.0`
- Upgraded to `global-shortcut-js@2.2.1`
- Upgraded to `http-js@2.4.4`
- Upgraded to `opener-js@2.2.7`
- Upgraded to `dialog-js@2.2.2`
## \[2.0.21]
### Dependencies
- Upgraded to `log-js@2.4.0`
- Upgraded to `biometric-js@2.2.1`
- Upgraded to `updater-js@2.7.1`
## \[2.0.20]
### Dependencies
- Upgraded to `http-js@2.4.3`
- Upgraded to `shell-js@2.2.1`
- Upgraded to `fs-js@2.2.1`
- Upgraded to `process-js@2.2.1`
- Upgraded to `updater-js@2.7.0`
- Upgraded to `dialog-js@2.2.1`
## \[2.0.19]
### Dependencies
- Upgraded to `http-js@2.4.2`
- Upgraded to `updater-js@2.6.1`
## \[2.0.18]
### Dependencies
- Upgraded to `http-js@2.4.1`
## \[2.0.17]
### Dependencies
- Upgraded to `log-js@2.3.1`
## \[2.0.16]
### Dependencies
+20 -20
View File
@@ -1,7 +1,7 @@
{
"name": "api",
"private": true,
"version": "2.0.16",
"version": "2.0.23",
"type": "module",
"scripts": {
"dev": "vite --clearScreen false",
@@ -10,35 +10,35 @@
"tauri": "tauri"
},
"dependencies": {
"@tauri-apps/api": "2.3.0",
"@tauri-apps/plugin-barcode-scanner": "^2.2.0",
"@tauri-apps/plugin-biometric": "^2.2.0",
"@tauri-apps/plugin-cli": "^2.2.0",
"@tauri-apps/plugin-clipboard-manager": "^2.2.2",
"@tauri-apps/plugin-dialog": "^2.2.0",
"@tauri-apps/plugin-fs": "^2.2.0",
"@tauri-apps/api": "2.5.0",
"@tauri-apps/plugin-barcode-scanner": "^2.2.1",
"@tauri-apps/plugin-biometric": "^2.2.2",
"@tauri-apps/plugin-cli": "^2.2.1",
"@tauri-apps/plugin-clipboard-manager": "^2.2.3",
"@tauri-apps/plugin-dialog": "^2.2.2",
"@tauri-apps/plugin-fs": "^2.3.0",
"@tauri-apps/plugin-geolocation": "^2.2.0",
"@tauri-apps/plugin-global-shortcut": "^2.2.0",
"@tauri-apps/plugin-global-shortcut": "^2.2.1",
"@tauri-apps/plugin-haptics": "^2.2.0",
"@tauri-apps/plugin-http": "^2.4.0",
"@tauri-apps/plugin-nfc": "^2.2.0",
"@tauri-apps/plugin-notification": "^2.2.2",
"@tauri-apps/plugin-opener": "^2.2.6",
"@tauri-apps/plugin-os": "^2.2.1",
"@tauri-apps/plugin-process": "^2.2.0",
"@tauri-apps/plugin-shell": "^2.2.0",
"@tauri-apps/plugin-store": "^2.2.0",
"@tauri-apps/plugin-updater": "^2.6.0",
"@tauri-apps/plugin-http": "^2.4.4",
"@tauri-apps/plugin-nfc": "^2.2.1",
"@tauri-apps/plugin-notification": "^2.2.3",
"@tauri-apps/plugin-opener": "^2.3.0",
"@tauri-apps/plugin-os": "^2.2.2",
"@tauri-apps/plugin-process": "^2.2.2",
"@tauri-apps/plugin-shell": "^2.2.2",
"@tauri-apps/plugin-store": "^2.2.1",
"@tauri-apps/plugin-updater": "^2.8.0",
"@zerodevx/svelte-json-view": "1.0.11"
},
"devDependencies": {
"@iconify-json/codicon": "^1.2.12",
"@iconify-json/ph": "^1.2.2",
"@sveltejs/vite-plugin-svelte": "^5.0.3",
"@tauri-apps/cli": "2.3.1",
"@tauri-apps/cli": "2.5.0",
"@unocss/extractor-svelte": "^66.0.0",
"svelte": "^5.20.4",
"unocss": "^66.0.0",
"vite": "^6.2.0"
"vite": "^6.2.6"
}
}
+68
View File
@@ -1,5 +1,73 @@
# Changelog
## \[2.0.27]
### Dependencies
- Upgraded to `updater@2.8.0`
- Upgraded to `barcode-scanner@2.2.1`
- Upgraded to `biometric@2.2.2`
- Upgraded to `cli@2.2.1`
- Upgraded to `clipboard-manager@2.2.3`
- Upgraded to `geolocation@2.2.5`
- Upgraded to `haptics@2.2.5`
- Upgraded to `nfc@2.2.1`
- Upgraded to `notification@2.2.3`
- Upgraded to `os@2.2.2`
- Upgraded to `process@2.2.2`
- Upgraded to `shell@2.2.2`
- Upgraded to `store@2.2.1`
- Upgraded to `log@2.5.0`
- Upgraded to `opener@2.3.0`
## \[2.0.26]
### Dependencies
- Upgraded to `fs@2.3.0`
- Upgraded to `global-shortcut@2.2.1`
- Upgraded to `http@2.4.4`
- Upgraded to `opener@2.2.7`
- Upgraded to `dialog@2.2.2`
## \[2.0.25]
### Dependencies
- Upgraded to `log@2.4.0`
- Upgraded to `biometric@2.2.1`
- Upgraded to `updater@2.7.1`
## \[2.0.24]
### Dependencies
- Upgraded to `http@2.4.3`
- Upgraded to `shell@2.2.1`
- Upgraded to `fs@2.2.1`
- Upgraded to `process@2.2.1`
- Upgraded to `updater@2.7.0`
- Upgraded to `dialog@2.2.1`
## \[2.0.23]
### Dependencies
- Upgraded to `http@2.4.2`
- Upgraded to `updater@2.6.1`
## \[2.0.22]
### Dependencies
- Upgraded to `http@2.4.1`
## \[2.0.21]
### Dependencies
- Upgraded to `log@2.3.1`
## \[2.0.20]
### Dependencies
+22 -20
View File
@@ -1,7 +1,7 @@
[package]
name = "api"
publish = false
version = "2.0.20"
version = "2.0.27"
description = "An example Tauri Application showcasing the api"
edition = "2021"
rust-version = { workspace = true }
@@ -18,24 +18,26 @@ tauri-build = { workspace = true, features = ["codegen", "isolation"] }
serde_json = { workspace = true }
serde = { workspace = true }
tiny_http = "0.12"
time = "0.3"
log = { workspace = true }
tauri-plugin-log = { path = "../../../plugins/log", version = "2.3.0" }
tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.2.0", features = [
tauri-plugin-log = { path = "../../../plugins/log", version = "2.5.0" }
tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.3.0", features = [
"watch",
] }
tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.2.2" }
tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.2.0" }
tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.2.3" }
tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.2.2" }
tauri-plugin-http = { path = "../../../plugins/http", features = [
"multipart",
], version = "2.4.0" }
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.2.2", features = [
"cookies",
], version = "2.4.4" }
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.2.3", features = [
"windows7-compat",
] }
tauri-plugin-os = { path = "../../../plugins/os", version = "2.2.1" }
tauri-plugin-process = { path = "../../../plugins/process", version = "2.2.0" }
tauri-plugin-opener = { path = "../../../plugins/opener", version = "2.2.6" }
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.2.0" }
tauri-plugin-store = { path = "../../../plugins/store", version = "2.2.0" }
tauri-plugin-os = { path = "../../../plugins/os", version = "2.2.2" }
tauri-plugin-process = { path = "../../../plugins/process", version = "2.2.2" }
tauri-plugin-opener = { path = "../../../plugins/opener", version = "2.3.0" }
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.2.2" }
tauri-plugin-store = { path = "../../../plugins/store", version = "2.2.1" }
[dependencies.tauri]
workspace = true
@@ -51,17 +53,17 @@ features = [
]
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
tauri-plugin-cli = { path = "../../../plugins/cli", version = "2.2.0" }
tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.2.0" }
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.6.0" }
tauri-plugin-cli = { path = "../../../plugins/cli", version = "2.2.1" }
tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.2.1" }
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.8.0" }
tauri-plugin-window-state = { path = "../../../plugins/window-state", version = "2.2.0" }
[target."cfg(any(target_os = \"android\", target_os = \"ios\"))".dependencies]
tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.2.0" }
tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.2.0" }
tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.2.0" }
tauri-plugin-geolocation = { path = "../../../plugins/geolocation/", version = "2.2.4" }
tauri-plugin-haptics = { path = "../../../plugins/haptics/", version = "2.2.4" }
tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.2.1" }
tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.2.1" }
tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.2.2" }
tauri-plugin-geolocation = { path = "../../../plugins/geolocation/", version = "2.2.5" }
tauri-plugin-haptics = { path = "../../../plugins/haptics/", version = "2.2.5" }
[features]
prod = ["tauri/custom-protocol"]
@@ -53,7 +53,7 @@
}
]
},
"shell:allow-open",
"shell:default",
"shell:allow-kill",
"shell:allow-stdin-write",
"process:allow-exit",
@@ -69,6 +69,7 @@
"fs:allow-mkdir",
"fs:allow-remove",
"fs:allow-write-text-file",
"fs:read-meta",
"fs:scope-download-recursive",
"fs:scope-resource-recursive",
{
+20 -1
View File
@@ -102,9 +102,28 @@ pub fn run() {
if let Ok(mut request) = server.recv() {
let mut body = Vec::new();
let _ = request.as_reader().read_to_end(&mut body);
let mut headers = request.headers().to_vec();
if !headers.iter().any(|header| header.field == tiny_http::HeaderField::from_bytes(b"Cookie").unwrap()) {
let expires = time::OffsetDateTime::now_utc() + time::Duration::days(1);
// RFC 1123 format
let format = time::macros::format_description!(
"[weekday repr:short], [day] [month repr:short] [year] [hour]:[minute]:[second] GMT"
);
let expires_str = expires.format(format).unwrap();
headers.push(
tiny_http::Header::from_bytes(
&b"Set-Cookie"[..],
format!("session-token=test-value; Secure; Path=/; Expires={expires_str}")
.as_bytes(),
)
.unwrap(),
);
}
let response = tiny_http::Response::new(
tiny_http::StatusCode(200),
request.headers().to_vec(),
headers,
std::io::Cursor::new(body),
request.body_length(),
None,
+13 -2
View File
@@ -2,16 +2,18 @@
import * as fs from "@tauri-apps/plugin-fs";
import { convertFileSrc } from "@tauri-apps/api/core";
import { arrayBufferToBase64 } from "../lib/utils";
import { onDestroy } from "svelte";
export let onMessage;
export let insecureRenderHtml;
let path = "";
let img;
/** @type {fs.FileHandle} */
let file;
let renameTo;
let watchPath = "";
let watchDebounceDelay = 0;
let watchDebounceDelay = "0";
let watchRecursive = false;
let unwatchFn;
let unwatchPath = "";
@@ -118,7 +120,7 @@
.getElementById("file-save")
.addEventListener("click", function () {
fs.writeTextFile(path, fileInput.value, {
dir: getDir(),
baseDir: getDir(),
}).catch(onMessage);
});
});
@@ -170,6 +172,15 @@
unwatchFn = undefined;
unwatchPath = undefined;
}
onDestroy(() => {
if (file) {
file.close();
}
if (unwatchFn) {
unwatchFn();
}
})
</script>
<div class="flex flex-col">
+7 -3
View File
@@ -12,10 +12,14 @@
isChecking = true
try {
const update = await check()
onMessage(`Should update: ${update.available}`)
onMessage(update)
if (update) {
onMessage(`Should update: ${update.available}`)
onMessage(update)
newUpdate = update
newUpdate = update
} else {
onMessage('No update available')
}
} catch (e) {
onMessage(e)
} finally {
+7 -7
View File
@@ -11,19 +11,19 @@
"example:api:dev": "pnpm run --filter \"api\" tauri dev"
},
"devDependencies": {
"@eslint/js": "9.22.0",
"@rollup/plugin-node-resolve": "16.0.0",
"@eslint/js": "9.29.0",
"@rollup/plugin-node-resolve": "16.0.1",
"@rollup/plugin-terser": "0.4.4",
"@rollup/plugin-typescript": "12.1.2",
"covector": "^0.12.4",
"eslint": "9.22.0",
"eslint-config-prettier": "10.1.1",
"eslint": "9.29.0",
"eslint-config-prettier": "10.1.5",
"eslint-plugin-security": "3.0.1",
"prettier": "3.5.3",
"rollup": "4.35.0",
"rollup": "4.43.0",
"tslib": "2.8.1",
"typescript": "5.8.2",
"typescript-eslint": "8.26.0"
"typescript": "5.8.3",
"typescript-eslint": "8.34.0"
},
"pnpm": {
"overrides": {
+8
View File
@@ -1,5 +1,13 @@
# Changelog
## \[2.4.0]
- [`764e8f77`](https://github.com/tauri-apps/plugins-workspace/commit/764e8f7719247da515243d9c9cafa6d087d21769) ([#2707](https://github.com/tauri-apps/plugins-workspace/pull/2707)) Added a new builder method app_name() to allow customizing the application name in the autostart entry.
## \[2.3.0]
- [`8ecb418a`](https://github.com/tauri-apps/plugins-workspace/commit/8ecb418a1a35d7f234dc5d833746ac2d8e062aec) ([#2569](https://github.com/tauri-apps/plugins-workspace/pull/2569)) Add a `Builder` for more flexible settings
## \[2.2.0]
- [`3a79266b`](https://github.com/tauri-apps/plugins-workspace/commit/3a79266b8cf96a55b1ae6339d725567d45a44b1d) ([#2173](https://github.com/tauri-apps/plugins-workspace/pull/2173) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Bumped all plugins to `v2.2.0`. From now, the versions for the Rust and JavaScript packages of each plugin will be in sync with each other.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-autostart"
version = "2.2.0"
version = "2.4.0"
description = "Automatically launch your application at startup."
authors = { workspace = true }
license = { workspace = true }
+4 -3
View File
@@ -57,11 +57,12 @@ First you need to register the core plugin with Tauri:
`src-tauri/src/lib.rs`
```rust
use tauri_plugin_autostart::MacosLauncher;
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_autostart::init(MacosLauncher::LaunchAgent, Some(vec!["--flag1", "--flag2"]) /* arbitrary number of args to pass to your app */))
.plugin(tauri_plugin_autostart::Builder::new()
.args(["--flag1", "--flag2"])
.app_name("My Custom Name")
.build())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-autostart",
"version": "2.2.0",
"version": "2.4.0",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
@@ -11,6 +11,8 @@ disable the automatic start on boot.
#### This default permission set includes the following:
- `allow-enable`
- `allow-disable`
- `allow-is-enabled`
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -297,37 +297,44 @@
{
"description": "Enables the disable command without any pre-configured scope.",
"type": "string",
"const": "allow-disable"
"const": "allow-disable",
"markdownDescription": "Enables the disable command without any pre-configured scope."
},
{
"description": "Denies the disable command without any pre-configured scope.",
"type": "string",
"const": "deny-disable"
"const": "deny-disable",
"markdownDescription": "Denies the disable command without any pre-configured scope."
},
{
"description": "Enables the enable command without any pre-configured scope.",
"type": "string",
"const": "allow-enable"
"const": "allow-enable",
"markdownDescription": "Enables the enable command without any pre-configured scope."
},
{
"description": "Denies the enable command without any pre-configured scope.",
"type": "string",
"const": "deny-enable"
"const": "deny-enable",
"markdownDescription": "Denies the enable command without any pre-configured scope."
},
{
"description": "Enables the is_enabled command without any pre-configured scope.",
"type": "string",
"const": "allow-is-enabled"
"const": "allow-is-enabled",
"markdownDescription": "Enables the is_enabled command without any pre-configured scope."
},
{
"description": "Denies the is_enabled command without any pre-configured scope.",
"type": "string",
"const": "deny-is-enabled"
"const": "deny-is-enabled",
"markdownDescription": "Denies the is_enabled command without any pre-configured scope."
},
{
"description": "This permission set configures if your\napplication can enable or disable auto\nstarting the application on boot.\n\n#### Granted Permissions\n\nIt allows all to check, enable and\ndisable the automatic start on boot.\n\n",
"description": "This permission set configures if your\napplication can enable or disable auto\nstarting the application on boot.\n\n#### Granted Permissions\n\nIt allows all to check, enable and\ndisable the automatic start on boot.\n\n\n#### This default permission set includes:\n\n- `allow-enable`\n- `allow-disable`\n- `allow-is-enabled`",
"type": "string",
"const": "default"
"const": "default",
"markdownDescription": "This permission set configures if your\napplication can enable or disable auto\nstarting the application on boot.\n\n#### Granted Permissions\n\nIt allows all to check, enable and\ndisable the automatic start on boot.\n\n\n#### This default permission set includes:\n\n- `allow-enable`\n- `allow-disable`\n- `allow-is-enabled`"
}
]
}
+146 -49
View File
@@ -14,7 +14,7 @@ use auto_launch::{AutoLaunch, AutoLaunchBuilder};
use serde::{ser::Serializer, Serialize};
use tauri::{
command,
plugin::{Builder, TauriPlugin},
plugin::{Builder as PluginBuilder, TauriPlugin},
Manager, Runtime, State,
};
@@ -22,8 +22,9 @@ use std::env::current_exe;
type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Copy, Clone)]
#[derive(Debug, Default, Copy, Clone)]
pub enum MacosLauncher {
#[default]
LaunchAgent,
AppleScript,
}
@@ -71,10 +72,12 @@ impl AutoLaunchManager {
}
pub trait ManagerExt<R: Runtime> {
/// TODO: Rename these to `autostart` or `auto_start` in v3
fn autolaunch(&self) -> State<'_, AutoLaunchManager>;
}
impl<R: Runtime, T: Manager<R>> ManagerExt<R> for T {
/// TODO: Rename these to `autostart` or `auto_start` in v3
fn autolaunch(&self) -> State<'_, AutoLaunchManager> {
self.state::<AutoLaunchManager>()
}
@@ -95,59 +98,153 @@ async fn is_enabled(manager: State<'_, AutoLaunchManager>) -> Result<bool> {
manager.is_enabled()
}
/// Initializes the plugin.
///
/// `args` - are passed to your app on startup.
pub fn init<R: Runtime>(
#[derive(Default)]
pub struct Builder {
#[cfg(target_os = "macos")]
macos_launcher: MacosLauncher,
args: Option<Vec<&'static str>>,
) -> TauriPlugin<R> {
Builder::new("autostart")
.invoke_handler(tauri::generate_handler![enable, disable, is_enabled])
.setup(move |app, _api| {
let mut builder = AutoLaunchBuilder::new();
builder.set_app_name(&app.package_info().name);
if let Some(args) = args {
builder.set_args(&args);
}
builder.set_use_launch_agent(matches!(macos_launcher, MacosLauncher::LaunchAgent));
args: Vec<String>,
app_name: Option<String>,
}
let current_exe = current_exe()?;
impl Builder {
/// Create a new auto start builder with default settings
pub fn new() -> Self {
Self::default()
}
#[cfg(windows)]
builder.set_app_path(&current_exe.display().to_string());
#[cfg(target_os = "macos")]
{
// on macOS, current_exe gives path to /Applications/Example.app/MacOS/Example
// but this results in seeing a Unix Executable in macOS login items
// It must be: /Applications/Example.app
// If it didn't find exactly a single occurance of .app, it will default to
// exe path to not break it.
let exe_path = current_exe.canonicalize()?.display().to_string();
let parts: Vec<&str> = exe_path.split(".app/").collect();
let app_path =
if parts.len() == 2 && matches!(macos_launcher, MacosLauncher::AppleScript) {
/// Adds an argument to pass to your app on startup.
///
/// ## Examples
///
/// ```no_run
/// Builder::new()
/// .arg("--from-autostart")
/// .arg("--hey")
/// .build();
/// ```
pub fn arg<S: Into<String>>(mut self, arg: S) -> Self {
self.args.push(arg.into());
self
}
/// Adds multiple arguments to pass to your app on startup.
///
/// ## Examples
///
/// ```no_run
/// Builder::new()
/// .args(["--from-autostart", "--hey"])
/// .build();
/// ```
pub fn args<I, S>(mut self, args: I) -> Self
where
I: IntoIterator<Item = S>,
S: Into<String>,
{
for arg in args {
self = self.arg(arg);
}
self
}
/// Sets whether to use launch agent or apple script to be used to enable auto start,
/// the builder's default is [`MacosLauncher::LaunchAgent`]
#[cfg(target_os = "macos")]
pub fn macos_launcher(mut self, macos_launcher: MacosLauncher) -> Self {
self.macos_launcher = macos_launcher;
self
}
/// Sets the app name to be used for the auto start entry.
///
/// ## Examples
///
/// ```no_run
/// Builder::new()
/// .app_name("My Custom Name"))
/// .build();
/// ```
pub fn app_name<S: Into<String>>(mut self, app_name: S) -> Self {
self.app_name = Some(app_name.into());
self
}
pub fn build<R: Runtime>(self) -> TauriPlugin<R> {
PluginBuilder::new("autostart")
.invoke_handler(tauri::generate_handler![enable, disable, is_enabled])
.setup(move |app, _api| {
let mut builder = AutoLaunchBuilder::new();
let app_name = self
.app_name
.as_ref()
.unwrap_or_else(|| &app.package_info().name);
builder.set_app_name(app_name);
builder.set_args(&self.args);
let current_exe = current_exe()?;
#[cfg(windows)]
builder.set_app_path(&current_exe.display().to_string());
#[cfg(target_os = "macos")]
{
builder.set_use_launch_agent(matches!(
self.macos_launcher,
MacosLauncher::LaunchAgent
));
// on macOS, current_exe gives path to /Applications/Example.app/MacOS/Example
// but this results in seeing a Unix Executable in macOS login items
// It must be: /Applications/Example.app
// If it didn't find exactly a single occurance of .app, it will default to
// exe path to not break it.
let exe_path = current_exe.canonicalize()?.display().to_string();
let parts: Vec<&str> = exe_path.split(".app/").collect();
let app_path = if parts.len() == 2
&& matches!(self.macos_launcher, MacosLauncher::AppleScript)
{
format!("{}.app", parts.first().unwrap())
} else {
exe_path
};
builder.set_app_path(&app_path);
}
#[cfg(target_os = "linux")]
if let Some(appimage) = app
.env()
.appimage
.and_then(|p| p.to_str().map(|s| s.to_string()))
{
builder.set_app_path(&appimage);
} else {
builder.set_app_path(&current_exe.display().to_string());
}
builder.set_app_path(&app_path);
}
app.manage(AutoLaunchManager(
builder.build().map_err(|e| e.to_string())?,
));
Ok(())
})
.build()
#[cfg(target_os = "linux")]
if let Some(appimage) = app
.env()
.appimage
.and_then(|p| p.to_str().map(|s| s.to_string()))
{
builder.set_app_path(&appimage);
} else {
builder.set_app_path(&current_exe.display().to_string());
}
app.manage(AutoLaunchManager(
builder.build().map_err(|e| e.to_string())?,
));
Ok(())
})
.build()
}
}
/// Initializes the plugin.
///
/// `args` - are passed to your app on startup.
pub fn init<R: Runtime>(
#[allow(unused)] macos_launcher: MacosLauncher,
args: Option<Vec<&'static str>>,
) -> TauriPlugin<R> {
let mut builder = Builder::new();
if let Some(args) = args {
builder = builder.args(args)
}
#[cfg(target_os = "macos")]
{
builder = builder.macos_launcher(macos_launcher);
}
builder.build()
}
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.2.1]
- [`f634e524`](https://github.com/tauri-apps/plugins-workspace/commit/f634e5248ebe428f8305a59f74c13fc15147fb8e) This is an "empty" release to update the plugins' source files on crates.io and docs.rs. This should fix docs.rs build failures for projects using tauri plugins as dependencies.
## \[2.2.0]
- [`3a79266b`](https://github.com/tauri-apps/plugins-workspace/commit/3a79266b8cf96a55b1ae6339d725567d45a44b1d) ([#2173](https://github.com/tauri-apps/plugins-workspace/pull/2173) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Bumped all plugins to `v2.2.0`. From now, the versions for the Rust and JavaScript packages of each plugin will be in sync with each other.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-barcode-scanner"
version = "2.2.0"
version = "2.2.1"
description = "Scan QR codes, EAN-13 and other kinds of barcodes on Android and iOS"
edition = { workspace = true }
authors = { workspace = true }
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-barcode-scanner",
"version": "2.2.0",
"version": "2.2.1",
"description": "Scan QR codes, EAN-13 and other kinds of barcodes on Android and iOS",
"license": "MIT OR Apache-2.0",
"authors": [
@@ -9,6 +9,8 @@ It allows all barcode related features.
#### This default permission set includes the following:
- `allow-cancel`
- `allow-check-permissions`
- `allow-open-app-settings`
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -297,67 +297,80 @@
{
"description": "Enables the cancel command without any pre-configured scope.",
"type": "string",
"const": "allow-cancel"
"const": "allow-cancel",
"markdownDescription": "Enables the cancel command without any pre-configured scope."
},
{
"description": "Denies the cancel command without any pre-configured scope.",
"type": "string",
"const": "deny-cancel"
"const": "deny-cancel",
"markdownDescription": "Denies the cancel command without any pre-configured scope."
},
{
"description": "Enables the check_permissions command without any pre-configured scope.",
"type": "string",
"const": "allow-check-permissions"
"const": "allow-check-permissions",
"markdownDescription": "Enables the check_permissions command without any pre-configured scope."
},
{
"description": "Denies the check_permissions command without any pre-configured scope.",
"type": "string",
"const": "deny-check-permissions"
"const": "deny-check-permissions",
"markdownDescription": "Denies the check_permissions command without any pre-configured scope."
},
{
"description": "Enables the open_app_settings command without any pre-configured scope.",
"type": "string",
"const": "allow-open-app-settings"
"const": "allow-open-app-settings",
"markdownDescription": "Enables the open_app_settings command without any pre-configured scope."
},
{
"description": "Denies the open_app_settings command without any pre-configured scope.",
"type": "string",
"const": "deny-open-app-settings"
"const": "deny-open-app-settings",
"markdownDescription": "Denies the open_app_settings command without any pre-configured scope."
},
{
"description": "Enables the request_permissions command without any pre-configured scope.",
"type": "string",
"const": "allow-request-permissions"
"const": "allow-request-permissions",
"markdownDescription": "Enables the request_permissions command without any pre-configured scope."
},
{
"description": "Denies the request_permissions command without any pre-configured scope.",
"type": "string",
"const": "deny-request-permissions"
"const": "deny-request-permissions",
"markdownDescription": "Denies the request_permissions command without any pre-configured scope."
},
{
"description": "Enables the scan command without any pre-configured scope.",
"type": "string",
"const": "allow-scan"
"const": "allow-scan",
"markdownDescription": "Enables the scan command without any pre-configured scope."
},
{
"description": "Denies the scan command without any pre-configured scope.",
"type": "string",
"const": "deny-scan"
"const": "deny-scan",
"markdownDescription": "Denies the scan command without any pre-configured scope."
},
{
"description": "Enables the vibrate command without any pre-configured scope.",
"type": "string",
"const": "allow-vibrate"
"const": "allow-vibrate",
"markdownDescription": "Enables the vibrate command without any pre-configured scope."
},
{
"description": "Denies the vibrate command without any pre-configured scope.",
"type": "string",
"const": "deny-vibrate"
"const": "deny-vibrate",
"markdownDescription": "Denies the vibrate command without any pre-configured scope."
},
{
"description": "This permission set configures which\nbarcode scanning features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all barcode related features.\n\n",
"description": "This permission set configures which\nbarcode scanning features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all barcode related features.\n\n\n#### This default permission set includes:\n\n- `allow-cancel`\n- `allow-check-permissions`\n- `allow-open-app-settings`\n- `allow-request-permissions`\n- `allow-scan`\n- `allow-vibrate`",
"type": "string",
"const": "default"
"const": "default",
"markdownDescription": "This permission set configures which\nbarcode scanning features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all barcode related features.\n\n\n#### This default permission set includes:\n\n- `allow-cancel`\n- `allow-check-permissions`\n- `allow-open-app-settings`\n- `allow-request-permissions`\n- `allow-scan`\n- `allow-vibrate`"
}
]
}
+10
View File
@@ -1,5 +1,15 @@
# Changelog
## \[2.2.2]
- [`f634e524`](https://github.com/tauri-apps/plugins-workspace/commit/f634e5248ebe428f8305a59f74c13fc15147fb8e) This is an "empty" release to update the plugins' source files on crates.io and docs.rs. This should fix docs.rs build failures for projects using tauri plugins as dependencies.
## \[2.2.1]
### bug
- [`10f9e66e`](https://github.com/tauri-apps/plugins-workspace/commit/10f9e66e32141dd35f4bf884fbf9102691187e92) ([#2633](https://github.com/tauri-apps/plugins-workspace/pull/2633) by [@pjf-dev](https://github.com/tauri-apps/plugins-workspace/../../pjf-dev)) Fix biometric plugin ignoring fallback logic when biometry status is unavailable or not enrolled on iOS.
## \[2.2.0]
- [`3a79266b`](https://github.com/tauri-apps/plugins-workspace/commit/3a79266b8cf96a55b1ae6339d725567d45a44b1d) ([#2173](https://github.com/tauri-apps/plugins-workspace/pull/2173) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Bumped all plugins to `v2.2.0`. From now, the versions for the Rust and JavaScript packages of each plugin will be in sync with each other.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-biometric"
version = "2.2.0"
version = "2.2.2"
description = "Prompt the user for biometric authentication on Android and iOS."
edition = { workspace = true }
authors = { workspace = true }
@@ -98,7 +98,12 @@ class BiometricPlugin: Plugin {
}
@objc func authenticate(_ invoke: Invoke) throws {
guard self.status.available else {
let args = try invoke.parseArgs(AuthOptions.self)
let allowDeviceCredential = args.allowDeviceCredential ?? false
guard self.status.available || allowDeviceCredential else {
// Biometry unavailable, fallback disabled
invoke.reject(
self.status.errorReason ?? "",
code: self.status.errorCode ?? ""
@@ -106,15 +111,11 @@ class BiometricPlugin: Plugin {
return
}
let args = try invoke.parseArgs(AuthOptions.self)
let context = LAContext()
context.localizedFallbackTitle = args.fallbackTitle
context.localizedCancelTitle = args.cancelTitle
context.touchIDAuthenticationAllowableReuseDuration = 0
let allowDeviceCredential = args.allowDeviceCredential ?? false
// force system default fallback title if an empty string is provided (the OS hides the fallback button in this case)
if allowDeviceCredential,
let fallbackTitle = context.localizedFallbackTitle,
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-biometric",
"version": "2.2.0",
"version": "2.2.2",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
@@ -9,6 +9,8 @@ It allows acccess to all biometric commands.
#### This default permission set includes the following:
- `allow-authenticate`
- `allow-status`
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -297,27 +297,32 @@
{
"description": "Enables the authenticate command without any pre-configured scope.",
"type": "string",
"const": "allow-authenticate"
"const": "allow-authenticate",
"markdownDescription": "Enables the authenticate command without any pre-configured scope."
},
{
"description": "Denies the authenticate command without any pre-configured scope.",
"type": "string",
"const": "deny-authenticate"
"const": "deny-authenticate",
"markdownDescription": "Denies the authenticate command without any pre-configured scope."
},
{
"description": "Enables the status command without any pre-configured scope.",
"type": "string",
"const": "allow-status"
"const": "allow-status",
"markdownDescription": "Enables the status command without any pre-configured scope."
},
{
"description": "Denies the status command without any pre-configured scope.",
"type": "string",
"const": "deny-status"
"const": "deny-status",
"markdownDescription": "Denies the status command without any pre-configured scope."
},
{
"description": "This permission set configures which\nbiometric features are by default exposed.\n\n#### Granted Permissions\n\nIt allows acccess to all biometric commands.\n\n",
"description": "This permission set configures which\nbiometric features are by default exposed.\n\n#### Granted Permissions\n\nIt allows acccess to all biometric commands.\n\n\n#### This default permission set includes:\n\n- `allow-authenticate`\n- `allow-status`",
"type": "string",
"const": "default"
"const": "default",
"markdownDescription": "This permission set configures which\nbiometric features are by default exposed.\n\n#### Granted Permissions\n\nIt allows acccess to all biometric commands.\n\n\n#### This default permission set includes:\n\n- `allow-authenticate`\n- `allow-status`"
}
]
}
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.2.1]
- [`f634e524`](https://github.com/tauri-apps/plugins-workspace/commit/f634e5248ebe428f8305a59f74c13fc15147fb8e) This is an "empty" release to update the plugins' source files on crates.io and docs.rs. This should fix docs.rs build failures for projects using tauri plugins as dependencies.
## \[2.2.0]
- [`3a79266b`](https://github.com/tauri-apps/plugins-workspace/commit/3a79266b8cf96a55b1ae6339d725567d45a44b1d) ([#2173](https://github.com/tauri-apps/plugins-workspace/pull/2173) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Bumped all plugins to `v2.2.0`. From now, the versions for the Rust and JavaScript packages of each plugin will be in sync with each other.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-cli"
version = "2.2.0"
version = "2.2.1"
description = "Parse arguments from your Tauri application's command line interface."
edition = { workspace = true }
authors = { workspace = true }
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-cli",
"version": "2.2.0",
"version": "2.2.1",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
@@ -2,6 +2,8 @@
Allows reading the CLI matches
#### This default permission set includes the following:
- `allow-cli-matches`
## Permission Table
+9 -6
View File
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -297,17 +297,20 @@
{
"description": "Enables the cli_matches command without any pre-configured scope.",
"type": "string",
"const": "allow-cli-matches"
"const": "allow-cli-matches",
"markdownDescription": "Enables the cli_matches command without any pre-configured scope."
},
{
"description": "Denies the cli_matches command without any pre-configured scope.",
"type": "string",
"const": "deny-cli-matches"
"const": "deny-cli-matches",
"markdownDescription": "Denies the cli_matches command without any pre-configured scope."
},
{
"description": "Allows reading the CLI matches",
"description": "Allows reading the CLI matches\n#### This default permission set includes:\n\n- `allow-cli-matches`",
"type": "string",
"const": "default"
"const": "default",
"markdownDescription": "Allows reading the CLI matches\n#### This default permission set includes:\n\n- `allow-cli-matches`"
}
]
}
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.2.3]
- [`f634e524`](https://github.com/tauri-apps/plugins-workspace/commit/f634e5248ebe428f8305a59f74c13fc15147fb8e) This is an "empty" release to update the plugins' source files on crates.io and docs.rs. This should fix docs.rs build failures for projects using tauri plugins as dependencies.
## \[2.2.2]
### bug
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-clipboard-manager"
version = "2.2.2"
version = "2.2.3"
description = "Read and write to the system clipboard."
edition = { workspace = true }
authors = { workspace = true }
+1 -1
View File
@@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_CLIPBOARD_MANAGER__=function(e){"use strict";var n;async function t(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}"function"==typeof SuppressedError&&SuppressedError;class r{get rid(){return function(e,n,t,r){if("function"==typeof n||!n.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===t?r:"a"===t?r.call(e):r?r.value:n.get(e)}(this,n,"f")}constructor(e){n.set(this,void 0),function(e,n,t){if("function"==typeof n||!n.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");n.set(e,t)}(this,n,e)}async close(){return t("plugin:resources|close",{rid:this.rid})}}n=new WeakMap;class a extends r{constructor(e){super(e)}static async new(e,n,r){return t("plugin:image|new",{rgba:i(e),width:n,height:r}).then((e=>new a(e)))}static async fromBytes(e){return t("plugin:image|from_bytes",{bytes:i(e)}).then((e=>new a(e)))}static async fromPath(e){return t("plugin:image|from_path",{path:e}).then((e=>new a(e)))}async rgba(){return t("plugin:image|rgba",{rid:this.rid}).then((e=>new Uint8Array(e)))}async size(){return t("plugin:image|size",{rid:this.rid})}}function i(e){return null==e?null:"string"==typeof e?e:e instanceof a?e.rid:e}return e.clear=async function(){await t("plugin:clipboard-manager|clear")},e.readImage=async function(){return await t("plugin:clipboard-manager|read_image").then((e=>new a(e)))},e.readText=async function(){return await t("plugin:clipboard-manager|read_text")},e.writeHtml=async function(e,n){await t("plugin:clipboard-manager|write_html",{html:e,altText:n})},e.writeImage=async function(e){await t("plugin:clipboard-manager|write_image",{image:i(e)})},e.writeText=async function(e,n){await t("plugin:clipboard-manager|write_text",{label:n?.label,text:e})},e}({});Object.defineProperty(window.__TAURI__,"clipboardManager",{value:__TAURI_PLUGIN_CLIPBOARD_MANAGER__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_CLIPBOARD_MANAGER__=function(e){"use strict";var n;async function t(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}"function"==typeof SuppressedError&&SuppressedError;class r{get rid(){return function(e,n,t,r){if("function"==typeof n?e!==n||!r:!n.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===t?r:"a"===t?r.call(e):r?r.value:n.get(e)}(this,n,"f")}constructor(e){n.set(this,void 0),function(e,n,t){if("function"==typeof n||!n.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");n.set(e,t)}(this,n,e)}async close(){return t("plugin:resources|close",{rid:this.rid})}}n=new WeakMap;class a extends r{constructor(e){super(e)}static async new(e,n,r){return t("plugin:image|new",{rgba:i(e),width:n,height:r}).then((e=>new a(e)))}static async fromBytes(e){return t("plugin:image|from_bytes",{bytes:i(e)}).then((e=>new a(e)))}static async fromPath(e){return t("plugin:image|from_path",{path:e}).then((e=>new a(e)))}async rgba(){return t("plugin:image|rgba",{rid:this.rid}).then((e=>new Uint8Array(e)))}async size(){return t("plugin:image|size",{rid:this.rid})}}function i(e){return null==e?null:"string"==typeof e?e:e instanceof a?e.rid:e}return e.clear=async function(){await t("plugin:clipboard-manager|clear")},e.readImage=async function(){return await t("plugin:clipboard-manager|read_image").then((e=>new a(e)))},e.readText=async function(){return await t("plugin:clipboard-manager|read_text")},e.writeHtml=async function(e,n){await t("plugin:clipboard-manager|write_html",{html:e,altText:n})},e.writeImage=async function(e){await t("plugin:clipboard-manager|write_image",{image:i(e)})},e.writeText=async function(e,n){await t("plugin:clipboard-manager|write_text",{label:n?.label,text:e})},e}({});Object.defineProperty(window.__TAURI__,"clipboardManager",{value:__TAURI_PLUGIN_CLIPBOARD_MANAGER__})}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-clipboard-manager",
"version": "2.2.2",
"version": "2.2.3",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
@@ -7,6 +7,8 @@ application specific if read and/or write access is needed.
Clipboard interaction needs to be explicitly enabled.
#### This default permission set includes the following:
## Permission Table
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -297,67 +297,80 @@
{
"description": "Enables the clear command without any pre-configured scope.",
"type": "string",
"const": "allow-clear"
"const": "allow-clear",
"markdownDescription": "Enables the clear command without any pre-configured scope."
},
{
"description": "Denies the clear command without any pre-configured scope.",
"type": "string",
"const": "deny-clear"
"const": "deny-clear",
"markdownDescription": "Denies the clear command without any pre-configured scope."
},
{
"description": "Enables the read_image command without any pre-configured scope.",
"type": "string",
"const": "allow-read-image"
"const": "allow-read-image",
"markdownDescription": "Enables the read_image command without any pre-configured scope."
},
{
"description": "Denies the read_image command without any pre-configured scope.",
"type": "string",
"const": "deny-read-image"
"const": "deny-read-image",
"markdownDescription": "Denies the read_image command without any pre-configured scope."
},
{
"description": "Enables the read_text command without any pre-configured scope.",
"type": "string",
"const": "allow-read-text"
"const": "allow-read-text",
"markdownDescription": "Enables the read_text command without any pre-configured scope."
},
{
"description": "Denies the read_text command without any pre-configured scope.",
"type": "string",
"const": "deny-read-text"
"const": "deny-read-text",
"markdownDescription": "Denies the read_text command without any pre-configured scope."
},
{
"description": "Enables the write_html command without any pre-configured scope.",
"type": "string",
"const": "allow-write-html"
"const": "allow-write-html",
"markdownDescription": "Enables the write_html command without any pre-configured scope."
},
{
"description": "Denies the write_html command without any pre-configured scope.",
"type": "string",
"const": "deny-write-html"
"const": "deny-write-html",
"markdownDescription": "Denies the write_html command without any pre-configured scope."
},
{
"description": "Enables the write_image command without any pre-configured scope.",
"type": "string",
"const": "allow-write-image"
"const": "allow-write-image",
"markdownDescription": "Enables the write_image command without any pre-configured scope."
},
{
"description": "Denies the write_image command without any pre-configured scope.",
"type": "string",
"const": "deny-write-image"
"const": "deny-write-image",
"markdownDescription": "Denies the write_image command without any pre-configured scope."
},
{
"description": "Enables the write_text command without any pre-configured scope.",
"type": "string",
"const": "allow-write-text"
"const": "allow-write-text",
"markdownDescription": "Enables the write_text command without any pre-configured scope."
},
{
"description": "Denies the write_text command without any pre-configured scope.",
"type": "string",
"const": "deny-write-text"
"const": "deny-write-text",
"markdownDescription": "Denies the write_text command without any pre-configured scope."
},
{
"description": "No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n",
"type": "string",
"const": "default"
"const": "default",
"markdownDescription": "No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n"
}
]
}
+12
View File
@@ -1,5 +1,17 @@
# Changelog
## \[2.3.0]
- [`4d10acee`](https://github.com/tauri-apps/plugins-workspace/commit/4d10acee61bad8045705508121424ed5f2d381f6) ([#993](https://github.com/tauri-apps/plugins-workspace/pull/993) by [@m00nwtchr](https://github.com/tauri-apps/plugins-workspace/../../m00nwtchr)) Exposed Android's `path`, `pathPattern` and `pathSuffix` configurations.
- [`4d10acee`](https://github.com/tauri-apps/plugins-workspace/commit/4d10acee61bad8045705508121424ed5f2d381f6) ([#993](https://github.com/tauri-apps/plugins-workspace/pull/993) by [@m00nwtchr](https://github.com/tauri-apps/plugins-workspace/../../m00nwtchr)) Added a `scheme` configuration to set a scheme other than http/https. This is only supported on Android and will still default to http,https if not set.
## \[2.2.1]
### bug
- [`38deef43`](https://github.com/tauri-apps/plugins-workspace/commit/38deef43dca9d5a09a38ed2da45b0f86c6afa1c5) ([#2483](https://github.com/tauri-apps/plugins-workspace/pull/2483)) Fix `is_registered` not being able to pickup deep link registered in `HKEY_LOCAL_MACHINE` on Windows
- [`38deef43`](https://github.com/tauri-apps/plugins-workspace/commit/38deef43dca9d5a09a38ed2da45b0f86c6afa1c5) ([#2483](https://github.com/tauri-apps/plugins-workspace/pull/2483)) Fix `unregister` not being able to remove deep link registered in `HKEY_LOCAL_MACHINE` on Windows
## \[2.2.0]
- [`3a79266b`](https://github.com/tauri-apps/plugins-workspace/commit/3a79266b8cf96a55b1ae6339d725567d45a44b1d) ([#2173](https://github.com/tauri-apps/plugins-workspace/pull/2173) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Bumped all plugins to `v2.2.0`. From now, the versions for the Rust and JavaScript packages of each plugin will be in sync with each other.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-deep-link"
version = "2.2.0"
version = "2.3.0"
description = "Set your Tauri application as the default handler for an URL"
authors = { workspace = true }
license = { workspace = true }
+29 -4
View File
@@ -9,25 +9,50 @@ use config::{AssociatedDomain, Config};
const COMMANDS: &[&str] = &["get_current", "register", "unregister", "is_registered"];
// TODO: Consider using activity-alias in case users may have multiple activities in their app.
// TODO: Do we want to support the other path* configs too?
fn intent_filter(domain: &AssociatedDomain) -> String {
format!(
r#"<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
{}
<data android:host="{}" />
{}
{}
{}
{}
</intent-filter>"#,
domain
.scheme
.iter()
.map(|scheme| format!(r#"<data android:scheme="{scheme}" />"#))
.collect::<Vec<_>>()
.join("\n "),
domain.host,
domain
.path
.iter()
.map(|path| format!(r#"<data android:path="{path}" />"#))
.collect::<Vec<_>>()
.join("\n "),
domain
.path_pattern
.iter()
.map(|pattern| format!(r#"<data android:pathPattern="{pattern}" />"#))
.collect::<Vec<_>>()
.join("\n "),
domain
.path_prefix
.iter()
.map(|prefix| format!(r#"<data android:pathPrefix="{prefix}" />"#))
.collect::<Vec<_>>()
.join("\n ")
.join("\n "),
domain
.path_suffix
.iter()
.map(|suffix| format!(r#"<data android:pathSuffix="{suffix}" />"#))
.collect::<Vec<_>>()
.join("\n "),
)
}
@@ -1,5 +1,17 @@
# Changelog
## \[2.2.2]
### Dependencies
- Upgraded to `deep-link-js@2.3.0`
## \[2.2.1]
### Dependencies
- Upgraded to `deep-link-js@2.2.1`
## \[2.2.0]
### Dependencies
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "deep-link-example",
"private": true,
"version": "2.2.0",
"version": "2.2.2",
"type": "module",
"scripts": {
"dev": "vite",
@@ -10,12 +10,12 @@
"tauri": "tauri"
},
"dependencies": {
"@tauri-apps/api": "2.3.0",
"@tauri-apps/plugin-deep-link": "2.2.0"
"@tauri-apps/api": "2.5.0",
"@tauri-apps/plugin-deep-link": "2.3.0"
},
"devDependencies": {
"@tauri-apps/cli": "2.3.1",
"@tauri-apps/cli": "2.5.0",
"typescript": "^5.7.3",
"vite": "^6.2.0"
"vite": "^6.2.6"
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-deep-link",
"version": "2.2.0",
"version": "2.3.0",
"description": "Set your Tauri application as the default handler for an URL",
"license": "MIT OR Apache-2.0",
"authors": [
@@ -2,6 +2,8 @@
Allows reading the opened deep link via the get_current command
#### This default permission set includes the following:
- `allow-get-current`
## Permission Table
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -297,47 +297,56 @@
{
"description": "Enables the get_current command without any pre-configured scope.",
"type": "string",
"const": "allow-get-current"
"const": "allow-get-current",
"markdownDescription": "Enables the get_current command without any pre-configured scope."
},
{
"description": "Denies the get_current command without any pre-configured scope.",
"type": "string",
"const": "deny-get-current"
"const": "deny-get-current",
"markdownDescription": "Denies the get_current command without any pre-configured scope."
},
{
"description": "Enables the is_registered command without any pre-configured scope.",
"type": "string",
"const": "allow-is-registered"
"const": "allow-is-registered",
"markdownDescription": "Enables the is_registered command without any pre-configured scope."
},
{
"description": "Denies the is_registered command without any pre-configured scope.",
"type": "string",
"const": "deny-is-registered"
"const": "deny-is-registered",
"markdownDescription": "Denies the is_registered command without any pre-configured scope."
},
{
"description": "Enables the register command without any pre-configured scope.",
"type": "string",
"const": "allow-register"
"const": "allow-register",
"markdownDescription": "Enables the register command without any pre-configured scope."
},
{
"description": "Denies the register command without any pre-configured scope.",
"type": "string",
"const": "deny-register"
"const": "deny-register",
"markdownDescription": "Denies the register command without any pre-configured scope."
},
{
"description": "Enables the unregister command without any pre-configured scope.",
"type": "string",
"const": "allow-unregister"
"const": "allow-unregister",
"markdownDescription": "Enables the unregister command without any pre-configured scope."
},
{
"description": "Denies the unregister command without any pre-configured scope.",
"type": "string",
"const": "deny-unregister"
"const": "deny-unregister",
"markdownDescription": "Denies the unregister command without any pre-configured scope."
},
{
"description": "Allows reading the opened deep link via the get_current command",
"description": "Allows reading the opened deep link via the get_current command\n#### This default permission set includes:\n\n- `allow-get-current`",
"type": "string",
"const": "default"
"const": "default",
"markdownDescription": "Allows reading the opened deep link via the get_current command\n#### This default permission set includes:\n\n- `allow-get-current`"
}
]
}
+15
View File
@@ -9,10 +9,25 @@ use tauri_utils::config::DeepLinkProtocol;
#[derive(Deserialize, Clone)]
pub struct AssociatedDomain {
#[serde(default = "default_schemes")]
pub scheme: Vec<String>,
#[serde(deserialize_with = "deserialize_associated_host")]
pub host: String,
#[serde(default)]
pub path: Vec<String>,
#[serde(default, alias = "path-pattern", rename = "pathPattern")]
pub path_pattern: Vec<String>,
#[serde(default, alias = "path-prefix", rename = "pathPrefix")]
pub path_prefix: Vec<String>,
#[serde(default, alias = "path-suffix", rename = "pathSuffix")]
pub path_suffix: Vec<String>,
}
// TODO: Consider removing this in v3
fn default_schemes() -> Vec<String> {
vec!["https".to_string(), "http".to_string()]
}
fn deserialize_associated_host<'de, D>(deserializer: D) -> Result<String, D::Error>
+22 -12
View File
@@ -114,8 +114,8 @@ mod imp {
/// ## Platform-specific:
///
/// - **Windows / Linux**: This function reads the command line arguments and checks if there's only one value, which must be an URL with scheme matching one of the configured values.
/// Note that you must manually check the arguments when registering deep link schemes dynamically with [`Self::register`].
/// Additionally, the deep link might have been provided as a CLI argument so you should check if its format matches what you expect.
/// Note that you must manually check the arguments when registering deep link schemes dynamically with [`Self::register`].
/// Additionally, the deep link might have been provided as a CLI argument so you should check if its format matches what you expect.
pub fn get_current(&self) -> crate::Result<Option<Vec<url::Url>>> {
self.plugin_handle
.run_mobile_plugin::<GetCurrentResponse>("getCurrent", ())
@@ -172,7 +172,7 @@ mod imp {
use tauri::Manager;
use tauri::{AppHandle, Runtime};
#[cfg(windows)]
use windows_registry::CURRENT_USER;
use windows_registry::{CLASSES_ROOT, CURRENT_USER, LOCAL_MACHINE};
/// Access to the deep-link APIs.
pub struct DeepLink<R: Runtime> {
@@ -226,8 +226,8 @@ mod imp {
/// ## Platform-specific:
///
/// - **Windows / Linux**: This function reads the command line arguments and checks if there's only one value, which must be an URL with scheme matching one of the configured values.
/// Note that you must manually check the arguments when registering deep link schemes dynamically with [`Self::register`].
/// Additionally, the deep link might have been provided as a CLI argument so you should check if its format matches what you expect.
/// Note that you must manually check the arguments when registering deep link schemes dynamically with [`Self::register`].
/// Additionally, the deep link might have been provided as a CLI argument so you should check if its format matches what you expect.
pub fn get_current(&self) -> crate::Result<Option<Vec<url::Url>>> {
return Ok(self.current.lock().unwrap().clone());
}
@@ -258,7 +258,8 @@ mod imp {
pub fn register<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<()> {
#[cfg(windows)]
{
let key_base = format!("Software\\Classes\\{}", _protocol.as_ref());
let protocol = _protocol.as_ref();
let key_base = format!("Software\\Classes\\{protocol}");
let exe = dunce::simplified(&tauri::utils::platform::current_exe()?)
.display()
@@ -348,13 +349,21 @@ mod imp {
///
/// ## Platform-specific:
///
/// - **Windows**: Requires admin rights if the protocol is registered on local machine
/// (this can happen when registered from the NSIS installer when the install mode is set to both or per machine)
/// - **Linux**: Can only unregister the scheme if it was initially registered with [`register`](`Self::register`). May not work on older distros.
/// - **macOS / Android / iOS**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
pub fn unregister<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<()> {
#[cfg(windows)]
{
CURRENT_USER.remove_tree(format!("Software\\Classes\\{}", _protocol.as_ref()))?;
let protocol = _protocol.as_ref();
let path = format!("Software\\Classes\\{protocol}");
if LOCAL_MACHINE.open(&path).is_ok() {
LOCAL_MACHINE.remove_tree(&path)?;
}
if CURRENT_USER.open(&path).is_ok() {
CURRENT_USER.remove_tree(&path)?;
}
Ok(())
}
@@ -398,10 +407,11 @@ mod imp {
pub fn is_registered<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<bool> {
#[cfg(windows)]
{
let cmd_reg = CURRENT_USER.open(format!(
"Software\\Classes\\{}\\shell\\open\\command",
_protocol.as_ref()
))?;
let protocol = _protocol.as_ref();
let Ok(cmd_reg) = CLASSES_ROOT.open(format!("{protocol}\\shell\\open\\command"))
else {
return Ok(false);
};
let registered_cmd = cmd_reg.get_string("")?;
+12
View File
@@ -1,5 +1,17 @@
# Changelog
## \[2.2.2]
### Dependencies
- Upgraded to `fs-js@2.3.0`
## \[2.2.1]
### Dependencies
- Upgraded to `fs-js@2.2.1`
## \[2.2.0]
- [`3a79266b`](https://github.com/tauri-apps/plugins-workspace/commit/3a79266b8cf96a55b1ae6339d725567d45a44b1d) ([#2173](https://github.com/tauri-apps/plugins-workspace/pull/2173) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Bumped all plugins to `v2.2.0`. From now, the versions for the Rust and JavaScript packages of each plugin will be in sync with each other.
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-dialog"
version = "2.2.0"
version = "2.2.2"
description = "Native system dialogs for opening and saving files along with message dialogs on your Tauri application."
edition = { workspace = true }
authors = { workspace = true }
@@ -34,7 +34,7 @@ tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
url = { workspace = true }
tauri-plugin-fs = { path = "../fs", version = "2.2.0" }
tauri-plugin-fs = { path = "../fs", version = "2.3.0" }
[target.'cfg(target_os = "ios")'.dependencies]
tauri = { workspace = true, features = ["wry"] }
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-dialog",
"version": "2.2.0",
"version": "2.2.2",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
@@ -10,6 +10,8 @@ All dialog types are enabled.
#### This default permission set includes the following:
- `allow-ask`
- `allow-confirm`
- `allow-message`
+25 -14
View File
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -297,57 +297,68 @@
{
"description": "Enables the ask command without any pre-configured scope.",
"type": "string",
"const": "allow-ask"
"const": "allow-ask",
"markdownDescription": "Enables the ask command without any pre-configured scope."
},
{
"description": "Denies the ask command without any pre-configured scope.",
"type": "string",
"const": "deny-ask"
"const": "deny-ask",
"markdownDescription": "Denies the ask command without any pre-configured scope."
},
{
"description": "Enables the confirm command without any pre-configured scope.",
"type": "string",
"const": "allow-confirm"
"const": "allow-confirm",
"markdownDescription": "Enables the confirm command without any pre-configured scope."
},
{
"description": "Denies the confirm command without any pre-configured scope.",
"type": "string",
"const": "deny-confirm"
"const": "deny-confirm",
"markdownDescription": "Denies the confirm command without any pre-configured scope."
},
{
"description": "Enables the message command without any pre-configured scope.",
"type": "string",
"const": "allow-message"
"const": "allow-message",
"markdownDescription": "Enables the message command without any pre-configured scope."
},
{
"description": "Denies the message command without any pre-configured scope.",
"type": "string",
"const": "deny-message"
"const": "deny-message",
"markdownDescription": "Denies the message command without any pre-configured scope."
},
{
"description": "Enables the open command without any pre-configured scope.",
"type": "string",
"const": "allow-open"
"const": "allow-open",
"markdownDescription": "Enables the open command without any pre-configured scope."
},
{
"description": "Denies the open command without any pre-configured scope.",
"type": "string",
"const": "deny-open"
"const": "deny-open",
"markdownDescription": "Denies the open command without any pre-configured scope."
},
{
"description": "Enables the save command without any pre-configured scope.",
"type": "string",
"const": "allow-save"
"const": "allow-save",
"markdownDescription": "Enables the save command without any pre-configured scope."
},
{
"description": "Denies the save command without any pre-configured scope.",
"type": "string",
"const": "deny-save"
"const": "deny-save",
"markdownDescription": "Denies the save command without any pre-configured scope."
},
{
"description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n",
"description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-ask`\n- `allow-confirm`\n- `allow-message`\n- `allow-save`\n- `allow-open`",
"type": "string",
"const": "default"
"const": "default",
"markdownDescription": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-ask`\n- `allow-confirm`\n- `allow-message`\n- `allow-save`\n- `allow-open`"
}
]
}
+10
View File
@@ -1,5 +1,15 @@
# Changelog
## \[2.3.0]
- [`dac4d537`](https://github.com/tauri-apps/plugins-workspace/commit/dac4d53724bb3430a00a3f0119857cba32a031e8) ([#2613](https://github.com/tauri-apps/plugins-workspace/pull/2613) by [@Legend-Master](https://github.com/tauri-apps/plugins-workspace/../../Legend-Master)) Reduce the overhead of `watch` and `unwatch`
## \[2.2.1]
### bug
- [`831c35ff`](https://github.com/tauri-apps/plugins-workspace/commit/831c35ff3940e841fe4418bb4cb104038b03304b) ([#2550](https://github.com/tauri-apps/plugins-workspace/pull/2550)) Fix `writeFile` ReadableStream handling due to missing async iterator support on macOS platform
## \[2.2.0]
- [`3a79266b`](https://github.com/tauri-apps/plugins-workspace/commit/3a79266b8cf96a55b1ae6339d725567d45a44b1d) ([#2173](https://github.com/tauri-apps/plugins-workspace/pull/2173) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Bumped all plugins to `v2.2.0`. From now, the versions for the Rust and JavaScript packages of each plugin will be in sync with each other.
+2 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-fs"
version = "2.2.0"
version = "2.3.0"
description = "Access the file system."
authors = { workspace = true }
license = { workspace = true }
@@ -14,7 +14,7 @@ rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.platforms.support]
windows = { level = "full", notes = "Apps installed via MSI or NSIS in `perMachine` and `both` mode require admin permissions for write acces in `$RESOURCES` folder" }
windows = { level = "full", notes = "Apps installed via MSI or NSIS in `perMachine` and `both` mode require admin permissions for write access in `$RESOURCES` folder" }
linux = { level = "full", notes = "No write access to `$RESOURCES` folder" }
macos = { level = "full", notes = "No write access to `$RESOURCES` folder" }
android = { level = "partial", notes = "Access is restricted to Application folder by default" }
@@ -35,7 +35,6 @@ tauri = { workspace = true }
thiserror = { workspace = true }
url = { workspace = true }
anyhow = "1"
uuid = { version = "1", features = ["v4"] }
glob = { workspace = true }
# TODO: Remove `serialization-compat-6` in v3
notify = { version = "8", optional = true, features = [
+2 -2
View File
@@ -68,9 +68,9 @@ fn main() {
Afterwards all the plugin's APIs are available through the JavaScript guest bindings:
```javascript
import { metadata } from '@tauri-apps/plugin-fs'
import { stat } from '@tauri-apps/plugin-fs'
await metadata('/path/to/file')
await stat('/path/to/file')
```
## Contributing
File diff suppressed because one or more lines are too long
+1
View File
@@ -101,6 +101,7 @@ const COMMANDS: &[(&str, &[&str])] = &[
("fstat", &[]),
("exists", &[]),
("watch", &[]),
// TODO: Remove this in v3
("unwatch", &[]),
("size", &[]),
];
+46 -52
View File
@@ -1075,10 +1075,18 @@ async function writeFile(
if (data instanceof ReadableStream) {
const file = await open(path, options)
for await (const chunk of data) {
await file.write(chunk)
const reader = data.getReader()
try {
while (true) {
const { done, value } = await reader.read()
if (done) break
await file.write(value)
}
} finally {
reader.releaseLock()
await file.close()
}
await file.close()
} else {
await invoke('plugin:fs|write_file', data, {
headers: {
@@ -1237,15 +1245,44 @@ type WatchEventKindRemove =
| { kind: 'folder' }
| { kind: 'other' }
// TODO: Remove this in v3, return `Watcher` instead
/**
* @since 2.0.0
*/
type UnwatchFn = () => void
async function unwatch(rid: number): Promise<void> {
await invoke('plugin:fs|unwatch', { rid })
class Watcher extends Resource {}
async function watchInternal(
paths: string | string[] | URL | URL[],
cb: (event: WatchEvent) => void,
options: DebouncedWatchOptions
): Promise<UnwatchFn> {
const watchPaths = Array.isArray(paths) ? paths : [paths]
for (const path of watchPaths) {
if (path instanceof URL && path.protocol !== 'file:') {
throw new TypeError('Must be a file URL.')
}
}
const onEvent = new Channel<WatchEvent>()
onEvent.onmessage = cb
const rid: number = await invoke('plugin:fs|watch', {
paths: watchPaths.map((p) => (p instanceof URL ? p.toString() : p)),
options,
onEvent
})
const watcher = new Watcher(rid)
return () => {
void watcher.close()
}
}
// TODO: Return `Watcher` instead in v3
/**
* Watch changes (after a delay) on files or directories.
*
@@ -1256,34 +1293,13 @@ async function watch(
cb: (event: WatchEvent) => void,
options?: DebouncedWatchOptions
): Promise<UnwatchFn> {
const opts = {
recursive: false,
return await watchInternal(paths, cb, {
delayMs: 2000,
...options
}
const watchPaths = Array.isArray(paths) ? paths : [paths]
for (const path of watchPaths) {
if (path instanceof URL && path.protocol !== 'file:') {
throw new TypeError('Must be a file URL.')
}
}
const onEvent = new Channel<WatchEvent>()
onEvent.onmessage = cb
const rid: number = await invoke('plugin:fs|watch', {
paths: watchPaths.map((p) => (p instanceof URL ? p.toString() : p)),
options: opts,
onEvent
})
return () => {
void unwatch(rid)
}
}
// TODO: Return `Watcher` instead in v3
/**
* Watch changes on files or directories.
*
@@ -1294,32 +1310,10 @@ async function watchImmediate(
cb: (event: WatchEvent) => void,
options?: WatchOptions
): Promise<UnwatchFn> {
const opts = {
recursive: false,
return await watchInternal(paths, cb, {
...options,
delayMs: null
}
const watchPaths = Array.isArray(paths) ? paths : [paths]
for (const path of watchPaths) {
if (path instanceof URL && path.protocol !== 'file:') {
throw new TypeError('Must be a file URL.')
}
}
const onEvent = new Channel<WatchEvent>()
onEvent.onmessage = cb
const rid: number = await invoke('plugin:fs|watch', {
paths: watchPaths.map((p) => (p instanceof URL ? p.toString() : p)),
options: opts,
onEvent
delayMs: undefined
})
return () => {
void unwatch(rid)
}
}
/**
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-fs",
"version": "2.2.0",
"version": "2.3.0",
"description": "Access the file system.",
"license": "MIT OR Apache-2.0",
"authors": [
@@ -24,8 +24,8 @@ This default permission set prevents access to critical components
of the Tauri application by default.
On Windows the webview data folder access is denied.
#### Included permissions within this default permission set:
#### This default permission set includes the following:
- `create-app-specific-dirs`
- `read-app-specific-dirs-recursive`
-2
View File
@@ -25,8 +25,6 @@ the `mkdir` command.
This default permission set prevents access to critical components
of the Tauri application by default.
On Windows the webview data folder access is denied.
#### Included permissions within this default permission set:
"""
permissions = [
"create-app-specific-dirs",
File diff suppressed because it is too large Load Diff
-5
View File
@@ -150,11 +150,6 @@ pub fn open<R: Runtime>(
Ok(rid)
}
#[tauri::command]
pub fn close<R: Runtime>(webview: Webview<R>, rid: ResourceId) -> CommandResult<()> {
webview.resources_table().close(rid).map_err(Into::into)
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CopyFileOptions {
-3
View File
@@ -397,7 +397,6 @@ pub fn init<R: Runtime>() -> TauriPlugin<R, Option<config::Config>> {
commands::create,
commands::open,
commands::copy_file,
commands::close,
commands::mkdir,
commands::read_dir,
commands::read,
@@ -420,8 +419,6 @@ pub fn init<R: Runtime>() -> TauriPlugin<R, Option<config::Config>> {
commands::size,
#[cfg(feature = "watch")]
watcher::watch,
#[cfg(feature = "watch")]
watcher::unwatch
])
.setup(|app, api| {
let scope = Scope {
+43 -98
View File
@@ -2,8 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use notify::{Config, Event, RecommendedWatcher, RecursiveMode, Watcher};
use notify_debouncer_full::{new_debouncer, DebounceEventResult, Debouncer, RecommendedCache};
use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher};
use notify_debouncer_full::{new_debouncer, DebouncedEvent, Debouncer, RecommendedCache};
use serde::Deserialize;
use tauri::{
ipc::{Channel, CommandScope, GlobalScope},
@@ -11,15 +11,7 @@ use tauri::{
Manager, Resource, ResourceId, Runtime, Webview,
};
use std::{
path::PathBuf,
sync::{
mpsc::{channel, Receiver},
Mutex,
},
thread::spawn,
time::Duration,
};
use std::time::Duration;
use crate::{
commands::{resolve_path, CommandResult},
@@ -27,79 +19,44 @@ use crate::{
SafeFilePath,
};
struct InnerWatcher {
pub kind: WatcherKind,
paths: Vec<PathBuf>,
}
pub struct WatcherResource(Mutex<InnerWatcher>);
impl WatcherResource {
fn new(kind: WatcherKind, paths: Vec<PathBuf>) -> Self {
Self(Mutex::new(InnerWatcher { kind, paths }))
}
fn with_lock<R, F: FnMut(&mut InnerWatcher) -> R>(&self, mut f: F) -> R {
let mut watcher = self.0.lock().unwrap();
f(&mut watcher)
}
}
impl Resource for WatcherResource {}
#[allow(unused)]
enum WatcherKind {
Debouncer(Debouncer<RecommendedWatcher, RecommendedCache>),
Watcher(RecommendedWatcher),
}
fn watch_raw(on_event: Channel<Event>, rx: Receiver<notify::Result<Event>>) {
spawn(move || {
while let Ok(event) = rx.recv() {
if let Ok(event) = event {
// TODO: Should errors be emitted too?
let _ = on_event.send(event);
}
}
});
}
fn watch_debounced(on_event: Channel<Event>, rx: Receiver<DebounceEventResult>) {
spawn(move || {
while let Ok(Ok(events)) = rx.recv() {
for event in events {
// TODO: Should errors be emitted too?
let _ = on_event.send(event.event);
}
}
});
}
impl Resource for WatcherKind {}
#[derive(Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WatchOptions {
base_dir: Option<BaseDirectory>,
#[serde(default)]
recursive: bool,
delay_ms: Option<u64>,
}
#[tauri::command]
pub async fn watch<R: Runtime>(
pub fn watch<R: Runtime>(
webview: Webview<R>,
paths: Vec<SafeFilePath>,
options: WatchOptions,
on_event: Channel<Event>,
on_event: Channel<notify::Event>,
global_scope: GlobalScope<Entry>,
command_scope: CommandScope<Entry>,
) -> CommandResult<ResourceId> {
let mut resolved_paths = Vec::with_capacity(paths.capacity());
for path in paths {
resolved_paths.push(resolve_path(
&webview,
&global_scope,
&command_scope,
path,
options.base_dir,
)?);
}
let resolved_paths = paths
.into_iter()
.map(|path| {
resolve_path(
&webview,
&global_scope,
&command_scope,
path,
options.base_dir,
)
})
.collect::<CommandResult<Vec<_>>>()?;
let recursive_mode = if options.recursive {
RecursiveMode::Recursive
@@ -107,52 +64,40 @@ pub async fn watch<R: Runtime>(
RecursiveMode::NonRecursive
};
let kind = if let Some(delay) = options.delay_ms {
let (tx, rx) = channel();
let mut debouncer = new_debouncer(Duration::from_millis(delay), None, tx)?;
let watcher_kind = if let Some(delay) = options.delay_ms {
let mut debouncer = new_debouncer(
Duration::from_millis(delay),
None,
move |events: Result<Vec<DebouncedEvent>, Vec<notify::Error>>| {
if let Ok(events) = events {
for event in events {
// TODO: Should errors be emitted too?
let _ = on_event.send(event.event);
}
}
},
)?;
for path in &resolved_paths {
debouncer.watch(path, recursive_mode)?;
}
watch_debounced(on_event, rx);
WatcherKind::Debouncer(debouncer)
} else {
let (tx, rx) = channel();
let mut watcher = RecommendedWatcher::new(tx, Config::default())?;
let mut watcher = RecommendedWatcher::new(
move |event| {
if let Ok(event) = event {
// TODO: Should errors be emitted too?
let _ = on_event.send(event);
}
},
Config::default(),
)?;
for path in &resolved_paths {
watcher.watch(path, recursive_mode)?;
}
watch_raw(on_event, rx);
WatcherKind::Watcher(watcher)
};
let rid = webview
.resources_table()
.add(WatcherResource::new(kind, resolved_paths));
let rid = webview.resources_table().add(watcher_kind);
Ok(rid)
}
#[tauri::command]
pub async fn unwatch<R: Runtime>(webview: Webview<R>, rid: ResourceId) -> CommandResult<()> {
let watcher = webview.resources_table().take::<WatcherResource>(rid)?;
WatcherResource::with_lock(&watcher, |watcher| {
match &mut watcher.kind {
WatcherKind::Debouncer(ref mut debouncer) => {
for path in &watcher.paths {
debouncer.unwatch(path).map_err(|e| {
format!("failed to unwatch path: {} with error: {e}", path.display())
})?;
}
}
WatcherKind::Watcher(ref mut w) => {
for path in &watcher.paths {
w.unwatch(path).map_err(|e| {
format!("failed to unwatch path: {} with error: {e}", path.display())
})?;
}
}
}
Ok(())
})
}
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.2.5]
- [`f634e524`](https://github.com/tauri-apps/plugins-workspace/commit/f634e5248ebe428f8305a59f74c13fc15147fb8e) This is an "empty" release to update the plugins' source files on crates.io and docs.rs. This should fix docs.rs build failures for projects using tauri plugins as dependencies.
## \[2.2.4]
- [`a1b3fa27`](https://github.com/tauri-apps/plugins-workspace/commit/a1b3fa27f11022c9b6622b4fab12d93239eb05de) ([#2515](https://github.com/tauri-apps/plugins-workspace/pull/2515) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Re-exported the `Geolocation`, `Haptics`, `Notification`, and `Os` structs so that they show up on docs.rs.
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "tauri-plugin-geolocation"
description = "Get and track the device's current position"
version = "2.2.4"
version = "2.2.5"
edition = { workspace = true }
authors = { workspace = true }
license = { workspace = true }
+1 -1
View File
@@ -72,7 +72,7 @@ This plugin automatically adds the following permissions to your `AndroidManifes
If your app requires GPS functionality to function, **you** should add the following to your `AndroidManifest.xml` file:
```xml
<uses-feature android:name="android.hardware.gps" android:required="true" />
<uses-feature android:name="android.hardware.location.gps" android:required="true" />
```
The Google Play Store uses this property to decide whether it should show the app to devices without GPS capabilities.
+1 -1
View File
@@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_GEOLOCATION__=function(t){"use strict";function n(t,n,e,i){if("function"==typeof n||!n.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===e?i:"a"===e?i.call(t):i?i.value:n.get(t)}function e(t,n,e,i,s){if("function"==typeof n||!n.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return n.set(t,e),e}var i,s,o;"function"==typeof SuppressedError&&SuppressedError;const r="__TAURI_TO_IPC_KEY__";class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),s.set(this,0),o.set(this,[]),this.id=function(t,n=!1){return window.__TAURI_INTERNALS__.transformCallback(t,n)}((({message:t,id:r})=>{if(r==n(this,s,"f"))for(n(this,i,"f").call(this,t),e(this,s,n(this,s,"f")+1);n(this,s,"f")in n(this,o,"f");){const t=n(this,o,"f")[n(this,s,"f")];n(this,i,"f").call(this,t),delete n(this,o,"f")[n(this,s,"f")],e(this,s,n(this,s,"f")+1)}else n(this,o,"f")[r]=t}))}set onmessage(t){e(this,i,t)}get onmessage(){return n(this,i,"f")}[(i=new WeakMap,s=new WeakMap,o=new WeakMap,r)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[r]()}}async function c(t,n={},e){return window.__TAURI_INTERNALS__.invoke(t,n,e)}return t.checkPermissions=async function(){return await async function(t){return c(`plugin:${t}|check_permissions`)}("geolocation")},t.clearWatch=async function(t){await c("plugin:geolocation|clear_watch",{channelId:t})},t.getCurrentPosition=async function(t){return await c("plugin:geolocation|get_current_position",{options:t})},t.requestPermissions=async function(t){return await c("plugin:geolocation|request_permissions",{permissions:t})},t.watchPosition=async function(t,n){const e=new a;return e.onmessage=t=>{"string"==typeof t?n(null,t):n(t)},await c("plugin:geolocation|watch_position",{options:t,channel:e}),e.id},t}({});Object.defineProperty(window.__TAURI__,"geolocation",{value:__TAURI_PLUGIN_GEOLOCATION__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_GEOLOCATION__=function(t){"use strict";function n(t,n,e,i){if("function"==typeof n?t!==n||!i:!n.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===e?i:"a"===e?i.call(t):i?i.value:n.get(t)}function e(t,n,e,i,s){if("function"==typeof n||!n.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return n.set(t,e),e}var i,s,o,r;"function"==typeof SuppressedError&&SuppressedError;const a="__TAURI_TO_IPC_KEY__";class c{constructor(t){i.set(this,void 0),s.set(this,0),o.set(this,[]),r.set(this,void 0),e(this,i,t||(()=>{})),this.id=function(t,n=!1){return window.__TAURI_INTERNALS__.transformCallback(t,n)}((t=>{const a=t.index;if("end"in t)return void(a==n(this,s,"f")?this.cleanupCallback():e(this,r,a));const c=t.message;if(a==n(this,s,"f")){for(n(this,i,"f").call(this,c),e(this,s,n(this,s,"f")+1);n(this,s,"f")in n(this,o,"f");){const t=n(this,o,"f")[n(this,s,"f")];n(this,i,"f").call(this,t),delete n(this,o,"f")[n(this,s,"f")],e(this,s,n(this,s,"f")+1)}n(this,s,"f")===n(this,r,"f")&&this.cleanupCallback()}else n(this,o,"f")[a]=c}))}cleanupCallback(){Reflect.deleteProperty(window,`_${this.id}`)}set onmessage(t){e(this,i,t)}get onmessage(){return n(this,i,"f")}[(i=new WeakMap,s=new WeakMap,o=new WeakMap,r=new WeakMap,a)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[a]()}}async function _(t,n={},e){return window.__TAURI_INTERNALS__.invoke(t,n,e)}return t.checkPermissions=async function(){return await async function(t){return _(`plugin:${t}|check_permissions`)}("geolocation")},t.clearWatch=async function(t){await _("plugin:geolocation|clear_watch",{channelId:t})},t.getCurrentPosition=async function(t){return await _("plugin:geolocation|get_current_position",{options:t})},t.requestPermissions=async function(t){return await _("plugin:geolocation|request_permissions",{permissions:t})},t.watchPosition=async function(t,n){const e=new c;return e.onmessage=t=>{"string"==typeof t?n(null,t):n(t)},await _("plugin:geolocation|watch_position",{options:t,channel:e}),e.id},t}({});Object.defineProperty(window.__TAURI__,"geolocation",{value:__TAURI_PLUGIN_GEOLOCATION__})}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-geolocation",
"version": "2.2.4",
"version": "2.2.5",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -297,62 +297,74 @@
{
"description": "Enables the check_permissions command without any pre-configured scope.",
"type": "string",
"const": "allow-check-permissions"
"const": "allow-check-permissions",
"markdownDescription": "Enables the check_permissions command without any pre-configured scope."
},
{
"description": "Denies the check_permissions command without any pre-configured scope.",
"type": "string",
"const": "deny-check-permissions"
"const": "deny-check-permissions",
"markdownDescription": "Denies the check_permissions command without any pre-configured scope."
},
{
"description": "Enables the clear_permissions command without any pre-configured scope.",
"type": "string",
"const": "allow-clear-permissions"
"const": "allow-clear-permissions",
"markdownDescription": "Enables the clear_permissions command without any pre-configured scope."
},
{
"description": "Denies the clear_permissions command without any pre-configured scope.",
"type": "string",
"const": "deny-clear-permissions"
"const": "deny-clear-permissions",
"markdownDescription": "Denies the clear_permissions command without any pre-configured scope."
},
{
"description": "Enables the clear_watch command without any pre-configured scope.",
"type": "string",
"const": "allow-clear-watch"
"const": "allow-clear-watch",
"markdownDescription": "Enables the clear_watch command without any pre-configured scope."
},
{
"description": "Denies the clear_watch command without any pre-configured scope.",
"type": "string",
"const": "deny-clear-watch"
"const": "deny-clear-watch",
"markdownDescription": "Denies the clear_watch command without any pre-configured scope."
},
{
"description": "Enables the get_current_position command without any pre-configured scope.",
"type": "string",
"const": "allow-get-current-position"
"const": "allow-get-current-position",
"markdownDescription": "Enables the get_current_position command without any pre-configured scope."
},
{
"description": "Denies the get_current_position command without any pre-configured scope.",
"type": "string",
"const": "deny-get-current-position"
"const": "deny-get-current-position",
"markdownDescription": "Denies the get_current_position command without any pre-configured scope."
},
{
"description": "Enables the request_permissions command without any pre-configured scope.",
"type": "string",
"const": "allow-request-permissions"
"const": "allow-request-permissions",
"markdownDescription": "Enables the request_permissions command without any pre-configured scope."
},
{
"description": "Denies the request_permissions command without any pre-configured scope.",
"type": "string",
"const": "deny-request-permissions"
"const": "deny-request-permissions",
"markdownDescription": "Denies the request_permissions command without any pre-configured scope."
},
{
"description": "Enables the watch_position command without any pre-configured scope.",
"type": "string",
"const": "allow-watch-position"
"const": "allow-watch-position",
"markdownDescription": "Enables the watch_position command without any pre-configured scope."
},
{
"description": "Denies the watch_position command without any pre-configured scope.",
"type": "string",
"const": "deny-watch-position"
"const": "deny-watch-position",
"markdownDescription": "Denies the watch_position command without any pre-configured scope."
}
]
}
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.2.1]
- [`494d1fea`](https://github.com/tauri-apps/plugins-workspace/commit/494d1fea137ffd60da98b25305c9d666df62cc63) ([#2684](https://github.com/tauri-apps/plugins-workspace/pull/2684) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated `global-hotkey` crate to `0.7` to fix a panic when trying to register a key combination which was already registered by another program. No API changes.
## \[2.2.0]
- [`3a79266b`](https://github.com/tauri-apps/plugins-workspace/commit/3a79266b8cf96a55b1ae6339d725567d45a44b1d) ([#2173](https://github.com/tauri-apps/plugins-workspace/pull/2173) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Bumped all plugins to `v2.2.0`. From now, the versions for the Rust and JavaScript packages of each plugin will be in sync with each other.
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-global-shortcut"
version = "2.2.0"
version = "2.2.1"
description = "Register global hotkeys listeners on your Tauri application."
edition = { workspace = true }
authors = { workspace = true }
@@ -31,4 +31,4 @@ log = { workspace = true }
thiserror = { workspace = true }
[target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies]
global-hotkey = { version = "0.6", features = ["serde"] }
global-hotkey = { version = "0.7", features = ["serde"] }
+1 -1
View File
@@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_GLOBAL_SHORTCUT__=function(t){"use strict";function e(t,e,r,s){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===r?s:"a"===r?s.call(t):s?s.value:e.get(t)}function r(t,e,r,s,i){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(t,r),r}var s,i,n;"function"==typeof SuppressedError&&SuppressedError;const o="__TAURI_TO_IPC_KEY__";class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,s.set(this,(()=>{})),i.set(this,0),n.set(this,[]),this.id=function(t,e=!1){return window.__TAURI_INTERNALS__.transformCallback(t,e)}((({message:t,id:o})=>{if(o==e(this,i,"f"))for(e(this,s,"f").call(this,t),r(this,i,e(this,i,"f")+1);e(this,i,"f")in e(this,n,"f");){const t=e(this,n,"f")[e(this,i,"f")];e(this,s,"f").call(this,t),delete e(this,n,"f")[e(this,i,"f")],r(this,i,e(this,i,"f")+1)}else e(this,n,"f")[o]=t}))}set onmessage(t){r(this,s,t)}get onmessage(){return e(this,s,"f")}[(s=new WeakMap,i=new WeakMap,n=new WeakMap,o)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[o]()}}async function _(t,e={},r){return window.__TAURI_INTERNALS__.invoke(t,e,r)}return t.isRegistered=async function(t){return await _("plugin:global-shortcut|is_registered",{shortcut:t})},t.register=async function(t,e){const r=new a;return r.onmessage=e,await _("plugin:global-shortcut|register",{shortcuts:Array.isArray(t)?t:[t],handler:r})},t.unregister=async function(t){return await _("plugin:global-shortcut|unregister",{shortcuts:Array.isArray(t)?t:[t]})},t.unregisterAll=async function(){return await _("plugin:global-shortcut|unregister_all",{})},t}({});Object.defineProperty(window.__TAURI__,"globalShortcut",{value:__TAURI_PLUGIN_GLOBAL_SHORTCUT__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_GLOBAL_SHORTCUT__=function(t){"use strict";function e(t,e,s,i){if("function"==typeof e?t!==e||!i:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===s?i:"a"===s?i.call(t):i?i.value:e.get(t)}function s(t,e,s,i,r){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(t,s),s}var i,r,n,a;"function"==typeof SuppressedError&&SuppressedError;const o="__TAURI_TO_IPC_KEY__";class c{constructor(t){i.set(this,void 0),r.set(this,0),n.set(this,[]),a.set(this,void 0),s(this,i,t||(()=>{})),this.id=function(t,e=!1){return window.__TAURI_INTERNALS__.transformCallback(t,e)}((t=>{const o=t.index;if("end"in t)return void(o==e(this,r,"f")?this.cleanupCallback():s(this,a,o));const c=t.message;if(o==e(this,r,"f")){for(e(this,i,"f").call(this,c),s(this,r,e(this,r,"f")+1);e(this,r,"f")in e(this,n,"f");){const t=e(this,n,"f")[e(this,r,"f")];e(this,i,"f").call(this,t),delete e(this,n,"f")[e(this,r,"f")],s(this,r,e(this,r,"f")+1)}e(this,r,"f")===e(this,a,"f")&&this.cleanupCallback()}else e(this,n,"f")[o]=c}))}cleanupCallback(){Reflect.deleteProperty(window,`_${this.id}`)}set onmessage(t){s(this,i,t)}get onmessage(){return e(this,i,"f")}[(i=new WeakMap,r=new WeakMap,n=new WeakMap,a=new WeakMap,o)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[o]()}}async function u(t,e={},s){return window.__TAURI_INTERNALS__.invoke(t,e,s)}return t.isRegistered=async function(t){return await u("plugin:global-shortcut|is_registered",{shortcut:t})},t.register=async function(t,e){const s=new c;return s.onmessage=e,await u("plugin:global-shortcut|register",{shortcuts:Array.isArray(t)?t:[t],handler:s})},t.unregister=async function(t){return await u("plugin:global-shortcut|unregister",{shortcuts:Array.isArray(t)?t:[t]})},t.unregisterAll=async function(){return await u("plugin:global-shortcut|unregister_all",{})},t}({});Object.defineProperty(window.__TAURI__,"globalShortcut",{value:__TAURI_PLUGIN_GLOBAL_SHORTCUT__})}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-global-shortcut",
"version": "2.2.0",
"version": "2.2.1",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
@@ -6,6 +6,8 @@ application specific if specific shortcuts should be
registered or unregistered.
#### This default permission set includes the following:
## Permission Table
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -297,57 +297,68 @@
{
"description": "Enables the is_registered command without any pre-configured scope.",
"type": "string",
"const": "allow-is-registered"
"const": "allow-is-registered",
"markdownDescription": "Enables the is_registered command without any pre-configured scope."
},
{
"description": "Denies the is_registered command without any pre-configured scope.",
"type": "string",
"const": "deny-is-registered"
"const": "deny-is-registered",
"markdownDescription": "Denies the is_registered command without any pre-configured scope."
},
{
"description": "Enables the register command without any pre-configured scope.",
"type": "string",
"const": "allow-register"
"const": "allow-register",
"markdownDescription": "Enables the register command without any pre-configured scope."
},
{
"description": "Denies the register command without any pre-configured scope.",
"type": "string",
"const": "deny-register"
"const": "deny-register",
"markdownDescription": "Denies the register command without any pre-configured scope."
},
{
"description": "Enables the register_all command without any pre-configured scope.",
"type": "string",
"const": "allow-register-all"
"const": "allow-register-all",
"markdownDescription": "Enables the register_all command without any pre-configured scope."
},
{
"description": "Denies the register_all command without any pre-configured scope.",
"type": "string",
"const": "deny-register-all"
"const": "deny-register-all",
"markdownDescription": "Denies the register_all command without any pre-configured scope."
},
{
"description": "Enables the unregister command without any pre-configured scope.",
"type": "string",
"const": "allow-unregister"
"const": "allow-unregister",
"markdownDescription": "Enables the unregister command without any pre-configured scope."
},
{
"description": "Denies the unregister command without any pre-configured scope.",
"type": "string",
"const": "deny-unregister"
"const": "deny-unregister",
"markdownDescription": "Denies the unregister command without any pre-configured scope."
},
{
"description": "Enables the unregister_all command without any pre-configured scope.",
"type": "string",
"const": "allow-unregister-all"
"const": "allow-unregister-all",
"markdownDescription": "Enables the unregister_all command without any pre-configured scope."
},
{
"description": "Denies the unregister_all command without any pre-configured scope.",
"type": "string",
"const": "deny-unregister-all"
"const": "deny-unregister-all",
"markdownDescription": "Denies the unregister_all command without any pre-configured scope."
},
{
"description": "No features are enabled by default, as we believe\nthe shortcuts can be inherently dangerous and it is\napplication specific if specific shortcuts should be\nregistered or unregistered.\n",
"type": "string",
"const": "default"
"const": "default",
"markdownDescription": "No features are enabled by default, as we believe\nthe shortcuts can be inherently dangerous and it is\napplication specific if specific shortcuts should be\nregistered or unregistered.\n"
}
]
}
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.2.5]
- [`f634e524`](https://github.com/tauri-apps/plugins-workspace/commit/f634e5248ebe428f8305a59f74c13fc15147fb8e) This is an "empty" release to update the plugins' source files on crates.io and docs.rs. This should fix docs.rs build failures for projects using tauri plugins as dependencies.
## \[2.2.4]
- [`a1b3fa27`](https://github.com/tauri-apps/plugins-workspace/commit/a1b3fa27f11022c9b6622b4fab12d93239eb05de) ([#2515](https://github.com/tauri-apps/plugins-workspace/pull/2515) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Re-exported the `Geolocation`, `Haptics`, `Notification`, and `Os` structs so that they show up on docs.rs.
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "tauri-plugin-haptics"
description = "Haptic feedback and vibrations on Android and iOS"
version = "2.2.4"
version = "2.2.5"
edition = { workspace = true }
authors = { workspace = true }
license = { workspace = true }
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-haptics",
"version": "2.2.4",
"version": "2.2.5",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
+18 -10
View File
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -297,42 +297,50 @@
{
"description": "Enables the impact_feedback command without any pre-configured scope.",
"type": "string",
"const": "allow-impact-feedback"
"const": "allow-impact-feedback",
"markdownDescription": "Enables the impact_feedback command without any pre-configured scope."
},
{
"description": "Denies the impact_feedback command without any pre-configured scope.",
"type": "string",
"const": "deny-impact-feedback"
"const": "deny-impact-feedback",
"markdownDescription": "Denies the impact_feedback command without any pre-configured scope."
},
{
"description": "Enables the notification_feedback command without any pre-configured scope.",
"type": "string",
"const": "allow-notification-feedback"
"const": "allow-notification-feedback",
"markdownDescription": "Enables the notification_feedback command without any pre-configured scope."
},
{
"description": "Denies the notification_feedback command without any pre-configured scope.",
"type": "string",
"const": "deny-notification-feedback"
"const": "deny-notification-feedback",
"markdownDescription": "Denies the notification_feedback command without any pre-configured scope."
},
{
"description": "Enables the selection_feedback command without any pre-configured scope.",
"type": "string",
"const": "allow-selection-feedback"
"const": "allow-selection-feedback",
"markdownDescription": "Enables the selection_feedback command without any pre-configured scope."
},
{
"description": "Denies the selection_feedback command without any pre-configured scope.",
"type": "string",
"const": "deny-selection-feedback"
"const": "deny-selection-feedback",
"markdownDescription": "Denies the selection_feedback command without any pre-configured scope."
},
{
"description": "Enables the vibrate command without any pre-configured scope.",
"type": "string",
"const": "allow-vibrate"
"const": "allow-vibrate",
"markdownDescription": "Enables the vibrate command without any pre-configured scope."
},
{
"description": "Denies the vibrate command without any pre-configured scope.",
"type": "string",
"const": "deny-vibrate"
"const": "deny-vibrate",
"markdownDescription": "Denies the vibrate command without any pre-configured scope."
}
]
}
+25
View File
@@ -1,5 +1,30 @@
# Changelog
## \[2.4.4]
- [`ff384cba`](https://github.com/tauri-apps/plugins-workspace/commit/ff384cbabe82ae715798a4ee49fd07ffcfbcdb5d) ([#2636](https://github.com/tauri-apps/plugins-workspace/pull/2636) by [@asomethings](https://github.com/tauri-apps/plugins-workspace/../../asomethings)) Properly handle responses with status code 204.
### Dependencies
- Upgraded to `fs-js@2.3.0`
## \[2.4.3]
- [`37c0477a`](https://github.com/tauri-apps/plugins-workspace/commit/37c0477afe926d326573f1827045875ce8bf8187) ([#2561](https://github.com/tauri-apps/plugins-workspace/pull/2561)) Add `zstd` cargo feature flag to enable `reqwest/zstd` flag.
- [`9ebbfb2e`](https://github.com/tauri-apps/plugins-workspace/commit/9ebbfb2e3ccef8e0f277a0c02fe6b399b41feeb6) ([#1978](https://github.com/tauri-apps/plugins-workspace/pull/1978)) Persist cookies to disk and load it on next app start.
### Dependencies
- Upgraded to `fs-js@2.2.1`
## \[2.4.2]
- [`a15eedf3`](https://github.com/tauri-apps/plugins-workspace/commit/a15eedf37854344f7ffbcb0d373d848563817011) ([#2535](https://github.com/tauri-apps/plugins-workspace/pull/2535) by [@amrbashir](https://github.com/tauri-apps/plugins-workspace/../../amrbashir)) Fix `fetch` occasionally throwing an error due to trying to close the underline stream twice.
## \[2.4.1]
- [`d3183aa9`](https://github.com/tauri-apps/plugins-workspace/commit/d3183aa99da7ca67e627394132ddeb3b85ccef06) ([#2522](https://github.com/tauri-apps/plugins-workspace/pull/2522) by [@adrieljss](https://github.com/tauri-apps/plugins-workspace/../../adrieljss)) Fix `fetch` blocking until the whole response is read even if it was a streaming response.
## \[2.4.0]
- [`cb38f54f`](https://github.com/tauri-apps/plugins-workspace/commit/cb38f54f4a4ef30995283cd82166c62da17bac44) ([#2479](https://github.com/tauri-apps/plugins-workspace/pull/2479) by [@adrieljss](https://github.com/tauri-apps/plugins-workspace/../../adrieljss)) Add stream support for HTTP stream responses.
+6 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-http"
version = "2.4.0"
version = "2.4.4"
description = "Access an HTTP client written in Rust."
edition = { workspace = true }
authors = { workspace = true }
@@ -34,13 +34,15 @@ serde_json = { workspace = true }
tauri = { workspace = true }
thiserror = { workspace = true }
tokio = { version = "1", features = ["sync", "macros"] }
tauri-plugin-fs = { path = "../fs", version = "2.2.0" }
tauri-plugin-fs = { path = "../fs", version = "2.3.0" }
urlpattern = "0.3"
regex = "1"
http = "1"
reqwest = { version = "0.12", default-features = false }
url = { workspace = true }
data-url = "0.3"
cookie_store = { version = "0.21.1", optional = true, features = ["serde"] }
bytes = { version = "1.9", optional = true }
tracing = { workspace = true, optional = true }
[features]
@@ -62,10 +64,11 @@ rustls-tls-manual-roots = ["reqwest/rustls-tls-manual-roots"]
rustls-tls-webpki-roots = ["reqwest/rustls-tls-webpki-roots"]
rustls-tls-native-roots = ["reqwest/rustls-tls-native-roots"]
blocking = ["reqwest/blocking"]
cookies = ["reqwest/cookies"]
cookies = ["reqwest/cookies", "dep:cookie_store", "dep:bytes"]
gzip = ["reqwest/gzip"]
brotli = ["reqwest/brotli"]
deflate = ["reqwest/deflate"]
zstd = ["reqwest/zstd"]
trust-dns = ["reqwest/trust-dns"]
socks = ["reqwest/socks"]
http2 = ["reqwest/http2"]
+1 -1
View File
@@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_HTTP__=function(e){"use strict";function t(e,t,r,n){if("function"==typeof t||!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===r?n:"a"===r?n.call(e):n?n.value:t.get(e)}function r(e,t,r,n,s){if("function"==typeof t||!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return t.set(e,r),r}var n,s,a;"function"==typeof SuppressedError&&SuppressedError;const i="__TAURI_TO_IPC_KEY__";class o{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,n.set(this,(()=>{})),s.set(this,0),a.set(this,[]),this.id=function(e,t=!1){return window.__TAURI_INTERNALS__.transformCallback(e,t)}((({message:e,id:i})=>{if(i==t(this,s,"f"))for(t(this,n,"f").call(this,e),r(this,s,t(this,s,"f")+1);t(this,s,"f")in t(this,a,"f");){const e=t(this,a,"f")[t(this,s,"f")];t(this,n,"f").call(this,e),delete t(this,a,"f")[t(this,s,"f")],r(this,s,t(this,s,"f")+1)}else t(this,a,"f")[i]=e}))}set onmessage(e){r(this,n,e)}get onmessage(){return t(this,n,"f")}[(n=new WeakMap,s=new WeakMap,a=new WeakMap,i)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[i]()}}async function c(e,t={},r){return window.__TAURI_INTERNALS__.invoke(e,t,r)}const d="Request canceled";return e.fetch=async function(e,t){const r=t?.signal;if(r?.aborted)throw new Error(d);const n=t?.maxRedirections,s=t?.connectTimeout,a=t?.proxy,i=t?.danger;t&&(delete t.maxRedirections,delete t.connectTimeout,delete t.proxy,delete t.danger);const f=t?.headers?t.headers instanceof Headers?t.headers:new Headers(t.headers):new Headers,h=new Request(e,t),_=await h.arrayBuffer(),u=0!==_.byteLength?Array.from(new Uint8Array(_)):null;for(const[e,t]of h.headers)f.get(e)||f.set(e,t);const l=(f instanceof Headers?Array.from(f.entries()):Array.isArray(f)?f:Object.entries(f)).map((([e,t])=>[e,"string"==typeof t?t:t.toString()]));if(r?.aborted)throw new Error(d);const w=new o,p=new ReadableStream({start:e=>{w.onmessage=t=>{if(r?.aborted)return e.error(d),void e.close();(t instanceof ArrayBuffer?0!=t.byteLength:0!=t.length)?e.enqueue(new Uint8Array(t)):e.close()}}}),m=await c("plugin:http|fetch",{clientConfig:{method:h.method,url:h.url,headers:l,data:u,maxRedirections:n,connectTimeout:s,proxy:a,danger:i},streamChannel:w}),y=()=>c("plugin:http|fetch_cancel",{rid:m});if(r?.aborted)throw y(),new Error(d);r?.addEventListener("abort",(()=>{y()}));const{status:T,statusText:g,url:A,headers:R}=await c("plugin:http|fetch_send",{rid:m}),b=new Response(p,{status:T,statusText:g});return Object.defineProperty(b,"url",{value:A}),Object.defineProperty(b,"headers",{value:new Headers(R)}),b},e}({});Object.defineProperty(window.__TAURI__,"http",{value:__TAURI_PLUGIN_HTTP__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_HTTP__=function(e){"use strict";function t(e,t,r,n){if("function"==typeof t?e!==t||!n:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===r?n:"a"===r?n.call(e):n?n.value:t.get(e)}function r(e,t,r,n,s){if("function"==typeof t||!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return t.set(e,r),r}var n,s,i,a;"function"==typeof SuppressedError&&SuppressedError;const o="__TAURI_TO_IPC_KEY__";class c{constructor(e){n.set(this,void 0),s.set(this,0),i.set(this,[]),a.set(this,void 0),r(this,n,e||(()=>{})),this.id=function(e,t=!1){return window.__TAURI_INTERNALS__.transformCallback(e,t)}((e=>{const o=e.index;if("end"in e)return void(o==t(this,s,"f")?this.cleanupCallback():r(this,a,o));const c=e.message;if(o==t(this,s,"f")){for(t(this,n,"f").call(this,c),r(this,s,t(this,s,"f")+1);t(this,s,"f")in t(this,i,"f");){const e=t(this,i,"f")[t(this,s,"f")];t(this,n,"f").call(this,e),delete t(this,i,"f")[t(this,s,"f")],r(this,s,t(this,s,"f")+1)}t(this,s,"f")===t(this,a,"f")&&this.cleanupCallback()}else t(this,i,"f")[o]=c}))}cleanupCallback(){Reflect.deleteProperty(window,`_${this.id}`)}set onmessage(e){r(this,n,e)}get onmessage(){return t(this,n,"f")}[(n=new WeakMap,s=new WeakMap,i=new WeakMap,a=new WeakMap,o)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[o]()}}async function d(e,t={},r){return window.__TAURI_INTERNALS__.invoke(e,t,r)}const h="Request cancelled";return e.fetch=async function(e,t){const r=t?.signal;if(r?.aborted)throw new Error(h);const n=t?.maxRedirections,s=t?.connectTimeout,i=t?.proxy,a=t?.danger;t&&(delete t.maxRedirections,delete t.connectTimeout,delete t.proxy,delete t.danger);const o=t?.headers?t.headers instanceof Headers?t.headers:new Headers(t.headers):new Headers,f=new Request(e,t),l=await f.arrayBuffer(),u=0!==l.byteLength?Array.from(new Uint8Array(l)):null;for(const[e,t]of f.headers)o.get(e)||o.set(e,t);const _=(o instanceof Headers?Array.from(o.entries()):Array.isArray(o)?o:Object.entries(o)).map((([e,t])=>[e,"string"==typeof t?t:t.toString()]));if(r?.aborted)throw new Error(h);const w=await d("plugin:http|fetch",{clientConfig:{method:f.method,url:f.url,headers:_,data:u,maxRedirections:n,connectTimeout:s,proxy:i,danger:a}}),p=()=>d("plugin:http|fetch_cancel",{rid:w});if(r?.aborted)throw p(),new Error(h);r?.addEventListener("abort",(()=>{p()}));const{status:y,statusText:m,url:b,headers:g,rid:T}=await d("plugin:http|fetch_send",{rid:w}),R=[101,103,204,205,304].includes(y)?null:new ReadableStream({start:e=>{const t=new c;t.onmessage=t=>{if(r?.aborted)return void e.error(h);const n=new Uint8Array(t),s=n[n.byteLength-1],i=n.slice(0,n.byteLength-1);1!=s?e.enqueue(i):e.close()},d("plugin:http|fetch_read_body",{rid:T,streamChannel:t}).catch((t=>{e.error(t)}))}}),A=new Response(R,{status:y,statusText:m});return Object.defineProperty(A,"url",{value:b}),Object.defineProperty(A,"headers",{value:new Headers(g)}),A},e}({});Object.defineProperty(window.__TAURI__,"http",{value:__TAURI_PLUGIN_HTTP__})}
+46 -39
View File
@@ -106,7 +106,7 @@ export interface DangerousSettings {
acceptInvalidHostnames?: boolean
}
const ERROR_REQUEST_CANCELLED = 'Request canceled'
const ERROR_REQUEST_CANCELLED = 'Request cancelled'
/**
* Fetch a resource from the network. It returns a `Promise` that resolves to the
@@ -186,35 +186,6 @@ export async function fetch(
throw new Error(ERROR_REQUEST_CANCELLED)
}
const streamChannel = new Channel<ArrayBuffer | number[]>()
const readableStreamBody = new ReadableStream({
start: (controller) => {
streamChannel.onmessage = (res: ArrayBuffer | number[]) => {
// close early if aborted
if (signal?.aborted) {
controller.error(ERROR_REQUEST_CANCELLED)
controller.close()
return
}
// close when the signal to close (an empty chunk)
// is sent from the IPC.
if (
res instanceof ArrayBuffer ? res.byteLength == 0 : res.length == 0
) {
controller.close()
return
}
// the content conversion (like .text(), .json(), etc.) in Response
// must have Uint8Array as its content, else it will
// have untraceable error that's hard to debug.
controller.enqueue(new Uint8Array(res))
}
}
})
const rid = await invoke<number>('plugin:http|fetch', {
clientConfig: {
method: req.method,
@@ -225,8 +196,7 @@ export async function fetch(
connectTimeout,
proxy,
danger
},
streamChannel
}
})
const abort = () => invoke('plugin:http|fetch_cancel', { rid })
@@ -253,22 +223,59 @@ export async function fetch(
status,
statusText,
url,
headers: responseHeaders
headers: responseHeaders,
rid: responseRid
} = await invoke<FetchSendResponse>('plugin:http|fetch_send', {
rid
})
const res = new Response(readableStreamBody, {
// no body for 101, 103, 204, 205 and 304
// see https://fetch.spec.whatwg.org/#null-body-status
const body = [101, 103, 204, 205, 304].includes(status)
? null
: new ReadableStream({
start: (controller) => {
const streamChannel = new Channel<ArrayBuffer | number[]>()
streamChannel.onmessage = (res: ArrayBuffer | number[]) => {
// close early if aborted
if (signal?.aborted) {
controller.error(ERROR_REQUEST_CANCELLED)
return
}
const resUint8 = new Uint8Array(res)
const lastByte = resUint8[resUint8.byteLength - 1]
const actualRes = resUint8.slice(0, resUint8.byteLength - 1)
// close when the signal to close (last byte is 1) is sent from the IPC.
if (lastByte == 1) {
controller.close()
return
}
controller.enqueue(actualRes)
}
// run a non-blocking body stream fetch
invoke('plugin:http|fetch_read_body', {
rid: responseRid,
streamChannel
}).catch((e) => {
controller.error(e)
})
}
})
const res = new Response(body, {
status,
statusText
})
// url and headers are read only properties
// but seems like we can set them like this
// Set `Response` properties that are ignored by the
// constructor, like url and some headers
//
// we define theme like this, because using `Response`
// constructor, it removes url and some headers
// like `set-cookie` headers
// Since url and headers are read only properties
// this is the only way to set them.
Object.defineProperty(res, 'url', { value: url })
Object.defineProperty(res, 'headers', {
value: new Headers(responseHeaders)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-http",
"version": "2.4.0",
"version": "2.4.4",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
@@ -13,6 +13,8 @@ All fetch operations are enabled.
#### This default permission set includes the following:
- `allow-fetch`
- `allow-fetch-cancel`
- `allow-fetch-read-body`
+21 -12
View File
@@ -49,7 +49,7 @@
"minimum": 1.0
},
"description": {
"description": "Human-readable description of what the permission does. Tauri convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -111,7 +111,7 @@
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does. Tauri internal convention is to use <h4> headings in markdown content for Tauri documentation generation purposes.",
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
@@ -297,47 +297,56 @@
{
"description": "Enables the fetch command without any pre-configured scope.",
"type": "string",
"const": "allow-fetch"
"const": "allow-fetch",
"markdownDescription": "Enables the fetch command without any pre-configured scope."
},
{
"description": "Denies the fetch command without any pre-configured scope.",
"type": "string",
"const": "deny-fetch"
"const": "deny-fetch",
"markdownDescription": "Denies the fetch command without any pre-configured scope."
},
{
"description": "Enables the fetch_cancel command without any pre-configured scope.",
"type": "string",
"const": "allow-fetch-cancel"
"const": "allow-fetch-cancel",
"markdownDescription": "Enables the fetch_cancel command without any pre-configured scope."
},
{
"description": "Denies the fetch_cancel command without any pre-configured scope.",
"type": "string",
"const": "deny-fetch-cancel"
"const": "deny-fetch-cancel",
"markdownDescription": "Denies the fetch_cancel command without any pre-configured scope."
},
{
"description": "Enables the fetch_read_body command without any pre-configured scope.",
"type": "string",
"const": "allow-fetch-read-body"
"const": "allow-fetch-read-body",
"markdownDescription": "Enables the fetch_read_body command without any pre-configured scope."
},
{
"description": "Denies the fetch_read_body command without any pre-configured scope.",
"type": "string",
"const": "deny-fetch-read-body"
"const": "deny-fetch-read-body",
"markdownDescription": "Denies the fetch_read_body command without any pre-configured scope."
},
{
"description": "Enables the fetch_send command without any pre-configured scope.",
"type": "string",
"const": "allow-fetch-send"
"const": "allow-fetch-send",
"markdownDescription": "Enables the fetch_send command without any pre-configured scope."
},
{
"description": "Denies the fetch_send command without any pre-configured scope.",
"type": "string",
"const": "deny-fetch-send"
"const": "deny-fetch-send",
"markdownDescription": "Denies the fetch_send command without any pre-configured scope."
},
{
"description": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n",
"description": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-read-body`\n- `allow-fetch-send`",
"type": "string",
"const": "default"
"const": "default",
"markdownDescription": "This permission set configures what kind of\nfetch operations are available from the http plugin.\n\nThis enables all fetch operations but does not\nallow explicitly any origins to be fetched. This needs to\nbe manually configured before usage.\n\n#### Granted Permissions\n\nAll fetch operations are enabled.\n\n\n#### This default permission set includes:\n\n- `allow-fetch`\n- `allow-fetch-cancel`\n- `allow-fetch-read-body`\n- `allow-fetch-send`"
}
]
}
+35 -16
View File
@@ -22,6 +22,9 @@ use crate::{
const HTTP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"),);
struct ReqwestResponse(reqwest::Response);
impl tauri::Resource for ReqwestResponse {}
type CancelableResponseResult = Result<reqwest::Response>;
type CancelableResponseFuture =
Pin<Box<dyn Future<Output = CancelableResponseResult> + Send + Sync>>;
@@ -178,7 +181,6 @@ pub async fn fetch<R: Runtime>(
client_config: ClientConfig,
command_scope: CommandScope<Entry>,
global_scope: GlobalScope<Entry>,
stream_channel: Channel<tauri::ipc::InvokeResponseBody>,
) -> crate::Result<ResourceId> {
let ClientConfig {
method,
@@ -312,20 +314,7 @@ pub async fn fetch<R: Runtime>(
#[cfg(feature = "tracing")]
tracing::trace!("{:?}", request);
let fut = async move {
let mut res = request.send().await?;
// send response through IPC channel
while let Some(chunk) = res.chunk().await? {
stream_channel.send(tauri::ipc::InvokeResponseBody::Raw(chunk.to_vec()))?;
}
// send empty vector when done
stream_channel.send(tauri::ipc::InvokeResponseBody::Raw(Vec::new()))?;
// return that response
Ok(res)
};
let fut = async move { request.send().await.map_err(Into::into) };
let mut resources_table = webview.resources_table();
let rid = resources_table.add_request(Box::pin(fut));
@@ -370,7 +359,7 @@ pub fn fetch_cancel<R: Runtime>(webview: Webview<R>, rid: ResourceId) -> crate::
Ok(())
}
#[tauri::command]
#[command]
pub async fn fetch_send<R: Runtime>(
webview: Webview<R>,
rid: ResourceId,
@@ -410,6 +399,9 @@ pub async fn fetch_send<R: Runtime>(
));
}
let mut resources_table = webview.resources_table();
let rid = resources_table.add(ReqwestResponse(res));
Ok(FetchResponse {
status: status.as_u16(),
status_text: status.canonical_reason().unwrap_or_default().to_string(),
@@ -419,6 +411,33 @@ pub async fn fetch_send<R: Runtime>(
})
}
#[command]
pub async fn fetch_read_body<R: Runtime>(
webview: Webview<R>,
rid: ResourceId,
stream_channel: Channel<tauri::ipc::InvokeResponseBody>,
) -> crate::Result<()> {
let res = {
let mut resources_table = webview.resources_table();
resources_table.take::<ReqwestResponse>(rid)?
};
let mut res = Arc::into_inner(res).unwrap().0;
// send response through IPC channel
while let Some(chunk) = res.chunk().await? {
let mut chunk = chunk.to_vec();
// append 0 to indicate we are not done yet
chunk.push(0);
stream_channel.send(tauri::ipc::InvokeResponseBody::Raw(chunk))?;
}
// send 1 to indicate we are done
stream_channel.send(tauri::ipc::InvokeResponseBody::Raw(vec![1]))?;
Ok(())
}
// forbidden headers per fetch spec https://fetch.spec.whatwg.org/#terminology-headers
#[cfg(not(feature = "unsafe-headers"))]
fn is_unsafe_header(header: &HeaderName) -> bool {
+51 -3
View File
@@ -14,29 +14,77 @@ pub use error::{Error, Result};
mod commands;
mod error;
#[cfg(feature = "cookies")]
mod reqwest_cookie_store;
mod scope;
#[cfg(feature = "cookies")]
const COOKIES_FILENAME: &str = ".cookies";
pub(crate) struct Http {
#[cfg(feature = "cookies")]
cookies_jar: std::sync::Arc<reqwest::cookie::Jar>,
cookies_jar: std::sync::Arc<crate::reqwest_cookie_store::CookieStoreMutex>,
}
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::<R>::new("http")
.setup(|app, _| {
#[cfg(feature = "cookies")]
let cookies_jar = {
use crate::reqwest_cookie_store::*;
use std::fs::File;
use std::io::BufReader;
let cache_dir = app.path().app_cache_dir()?;
std::fs::create_dir_all(&cache_dir)?;
let path = cache_dir.join(COOKIES_FILENAME);
let file = File::options()
.create(true)
.append(true)
.read(true)
.open(&path)?;
let reader = BufReader::new(file);
CookieStoreMutex::load(path.clone(), reader).unwrap_or_else(|_e| {
#[cfg(feature = "tracing")]
tracing::warn!(
"failed to load cookie store: {_e}, falling back to empty store"
);
CookieStoreMutex::new(path, Default::default())
})
};
let state = Http {
#[cfg(feature = "cookies")]
cookies_jar: std::sync::Arc::new(reqwest::cookie::Jar::default()),
cookies_jar: std::sync::Arc::new(cookies_jar),
};
app.manage(state);
Ok(())
})
.on_event(|app, event| {
#[cfg(feature = "cookies")]
if let tauri::RunEvent::Exit = event {
let state = app.state::<Http>();
match state.cookies_jar.request_save() {
Ok(rx) => {
let _ = rx.recv();
}
Err(_e) => {
#[cfg(feature = "tracing")]
tracing::error!("failed to save cookie jar: {_e}");
}
}
}
})
.invoke_handler(tauri::generate_handler![
commands::fetch,
commands::fetch_cancel,
commands::fetch_send
commands::fetch_send,
commands::fetch_read_body
])
.build()
}
+133
View File
@@ -0,0 +1,133 @@
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
// taken from https://github.com/pfernie/reqwest_cookie_store/blob/2ec4afabcd55e24d3afe3f0626ee6dc97bed938d/src/lib.rs
use std::{
path::PathBuf,
sync::{mpsc::Receiver, Mutex},
};
use cookie_store::{CookieStore, RawCookie, RawCookieParseError};
use reqwest::header::HeaderValue;
fn set_cookies(
cookie_store: &mut CookieStore,
cookie_headers: &mut dyn Iterator<Item = &HeaderValue>,
url: &url::Url,
) {
let cookies = cookie_headers.filter_map(|val| {
std::str::from_utf8(val.as_bytes())
.map_err(RawCookieParseError::from)
.and_then(RawCookie::parse)
.map(|c| c.into_owned())
.ok()
});
cookie_store.store_response_cookies(cookies, url);
}
fn cookies(cookie_store: &CookieStore, url: &url::Url) -> Option<HeaderValue> {
let s = cookie_store
.get_request_values(url)
.map(|(name, value)| format!("{}={}", name, value))
.collect::<Vec<_>>()
.join("; ");
if s.is_empty() {
return None;
}
HeaderValue::from_maybe_shared(bytes::Bytes::from(s)).ok()
}
/// A [`cookie_store::CookieStore`] wrapped internally by a [`std::sync::Mutex`], suitable for use in
/// async/concurrent contexts.
#[derive(Debug)]
pub struct CookieStoreMutex {
pub path: PathBuf,
store: Mutex<CookieStore>,
save_task: Mutex<Option<CancellableTask>>,
}
impl CookieStoreMutex {
/// Create a new [`CookieStoreMutex`] from an existing [`cookie_store::CookieStore`].
pub fn new(path: PathBuf, cookie_store: CookieStore) -> CookieStoreMutex {
CookieStoreMutex {
path,
store: Mutex::new(cookie_store),
save_task: Default::default(),
}
}
pub fn load<R: std::io::BufRead>(
path: PathBuf,
reader: R,
) -> cookie_store::Result<CookieStoreMutex> {
cookie_store::serde::load(reader, |c| serde_json::from_str(c))
.map(|store| CookieStoreMutex::new(path, store))
}
fn cookies_to_str(&self) -> Result<String, serde_json::Error> {
let mut cookies = Vec::new();
for cookie in self
.store
.lock()
.expect("poisoned cookie jar mutex")
.iter_unexpired()
{
if cookie.is_persistent() {
cookies.push(cookie.clone());
}
}
serde_json::to_string(&cookies)
}
pub fn request_save(&self) -> cookie_store::Result<Receiver<()>> {
let cookie_str = self.cookies_to_str()?;
let path = self.path.clone();
let (tx, rx) = std::sync::mpsc::channel();
let task = tauri::async_runtime::spawn(async move {
match tokio::fs::write(&path, &cookie_str).await {
Ok(()) => {
let _ = tx.send(());
}
Err(_e) => {
#[cfg(feature = "tracing")]
tracing::error!("failed to save cookie jar: {_e}");
}
}
});
self.save_task
.lock()
.unwrap()
.replace(CancellableTask(task));
Ok(rx)
}
}
impl reqwest::cookie::CookieStore for CookieStoreMutex {
fn set_cookies(&self, cookie_headers: &mut dyn Iterator<Item = &HeaderValue>, url: &url::Url) {
set_cookies(&mut self.store.lock().unwrap(), cookie_headers, url);
// try to persist cookies immediately asynchronously
if let Err(_e) = self.request_save() {
#[cfg(feature = "tracing")]
tracing::error!("failed to save cookie jar: {_e}");
}
}
fn cookies(&self, url: &url::Url) -> Option<HeaderValue> {
let store = self.store.lock().unwrap();
cookies(&store, url)
}
}
#[derive(Debug)]
struct CancellableTask(tauri::async_runtime::JoinHandle<()>);
impl Drop for CancellableTask {
fn drop(&mut self) {
self.0.abort();
}
}
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.2.1]
- [`f634e524`](https://github.com/tauri-apps/plugins-workspace/commit/f634e5248ebe428f8305a59f74c13fc15147fb8e) This is an "empty" release to update the plugins' source files on crates.io and docs.rs. This should fix docs.rs build failures for projects using tauri plugins as dependencies.
## \[2.2.0]
- [`3a79266b`](https://github.com/tauri-apps/plugins-workspace/commit/3a79266b8cf96a55b1ae6339d725567d45a44b1d) ([#2173](https://github.com/tauri-apps/plugins-workspace/pull/2173) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Bumped all plugins to `v2.2.0`. From now, the versions for the Rust and JavaScript packages of each plugin will be in sync with each other.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-localhost"
version = "2.2.0"
version = "2.2.1"
description = "Expose your apps assets through a localhost server instead of the default custom protocol."
authors = { workspace = true }
license = { workspace = true }
+18
View File
@@ -1,5 +1,23 @@
# Changelog
## \[2.5.0]
- [`106e46ed`](https://github.com/tauri-apps/plugins-workspace/commit/106e46ed5125be33d0427cab9c5c066802f68791) ([#677](https://github.com/tauri-apps/plugins-workspace/pull/677)) Added the `KeepSome` rotation strategy. Like `KeepAll` it will rename files when the max file size is exceeded but will keep only the specified amount of files around.
## \[2.4.0]
- [`c9b21f6f`](https://github.com/tauri-apps/plugins-workspace/commit/c9b21f6f4345806eff5f495885f20dea0082b7d7) ([#2625](https://github.com/tauri-apps/plugins-workspace/pull/2625) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Export the `LogLevel` type.
- [`9629c2f4`](https://github.com/tauri-apps/plugins-workspace/commit/9629c2f4f90a56b5c2d265d1d13d3af40fc0c525) ([#2600](https://github.com/tauri-apps/plugins-workspace/pull/2600) by [@exoego](https://github.com/tauri-apps/plugins-workspace/../../exoego)) Adds a new varient `TargetKind::Dispatch` that allows you to construct arbitrary log targets
- [`686a839c`](https://github.com/tauri-apps/plugins-workspace/commit/686a839c96fae1b0334f2df9dc76ca5cdbe00dbe) ([#2626](https://github.com/tauri-apps/plugins-workspace/pull/2626) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Fix iOS app stuck when using the iOS Simulator and the log plugin due to a deadlock when calling os_log too early.
### feat
- [`60fc35d3`](https://github.com/tauri-apps/plugins-workspace/commit/60fc35d35cccaf1654eceb4446ecf0f89dc15502) ([#2576](https://github.com/tauri-apps/plugins-workspace/pull/2576) by [@3lpsy](https://github.com/tauri-apps/plugins-workspace/../../3lpsy)) Add a `tracing` feature to the `log` plugin that emits log messages to the `tracing` system.
## \[2.3.1]
- [`1bb1ced5`](https://github.com/tauri-apps/plugins-workspace/commit/1bb1ced53820127204aa7adf57510c1cbce55e12) ([#2524](https://github.com/tauri-apps/plugins-workspace/pull/2524) by [@elwerene](https://github.com/tauri-apps/plugins-workspace/../../elwerene)) enable TargetKind::LogDir on mobile
## \[2.3.0]
### feat
+10 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-log"
version = "2.3.0"
version = "2.5.0"
description = "Configurable logging for your Tauri app."
authors = { workspace = true }
license = { workspace = true }
@@ -31,11 +31,17 @@ thiserror = { workspace = true }
serde_repr = "0.1"
byte-unit = "5"
log = { workspace = true, features = ["kv_unstable"] }
time = { version = "0.3", features = ["formatting", "local-offset"] }
time = { version = "0.3", features = [
"formatting",
"local-offset",
"macros",
"parsing",
] }
fern = "0.7"
tracing = { workspace = true, optional = true }
[target."cfg(target_os = \"android\")".dependencies]
android_logger = "0.14"
android_logger = "0.15"
[target."cfg(target_os = \"ios\")".dependencies]
swift-rs = "1"
@@ -47,3 +53,4 @@ objc2-foundation = { version = "0.3", default-features = false, features = [
[features]
colored = ["fern/colored"]
tracing = ["dep:tracing"]
+1 -1
View File
@@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_LOG__=function(e){"use strict";function n(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}async function r(e,n={},r){return window.__TAURI_INTERNALS__.invoke(e,n,r)}var a,t;async function o(e,a,t){const o={kind:"Any"};return r("plugin:event|listen",{event:e,target:o,handler:n(a)}).then((n=>async()=>async function(e,n){await r("plugin:event|unlisten",{event:e,eventId:n})}(e,n)))}async function i(e,n,a){const t=function(e){if(e){if(!e.startsWith("Error")){const n=e.split("\n").map((e=>e.split("@"))).filter((([e,n])=>e.length>0&&"[native code]"!==n));return n[2]?.filter((e=>e.length>0)).join("@")}{const n=e.split("\n"),r=n[3]?.trim();if(!r)return;const a=/at\s+(?<functionName>.*?)\s+\((?<fileName>.*?):(?<lineNumber>\d+):(?<columnNumber>\d+)\)/,t=r.match(a);if(t){const{functionName:e,fileName:n,lineNumber:r,columnNumber:a}=t.groups;return`${e}@${n}:${r}:${a}`}{const e=/at\s+(?<fileName>.*?):(?<lineNumber>\d+):(?<columnNumber>\d+)/,n=r.match(e);if(n){const{fileName:e,lineNumber:r,columnNumber:a}=n.groups;return`<anonymous>@${e}:${r}:${a}`}}}}}((new Error).stack),{file:o,line:i,keyValues:u}=a??{};await r("plugin:log|log",{level:e,message:n,location:t,file:o,line:i,keyValues:u})}async function u(e){return await o("log://log",(n=>{const{level:r}=n.payload;let{message:a}=n.payload;a=a.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,""),e({message:a,level:r})}))}return"function"==typeof SuppressedError&&SuppressedError,function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG_ENTER="tauri://drag-enter",e.DRAG_OVER="tauri://drag-over",e.DRAG_DROP="tauri://drag-drop",e.DRAG_LEAVE="tauri://drag-leave"}(a||(a={})),function(e){e[e.Trace=1]="Trace",e[e.Debug=2]="Debug",e[e.Info=3]="Info",e[e.Warn=4]="Warn",e[e.Error=5]="Error"}(t||(t={})),e.attachConsole=async function(){return await u((({level:e,message:n})=>{switch(e){case t.Trace:console.log(n);break;case t.Debug:console.debug(n);break;case t.Info:console.info(n);break;case t.Warn:console.warn(n);break;case t.Error:console.error(n);break;default:throw new Error(`unknown log level ${e}`)}}))},e.attachLogger=u,e.debug=async function(e,n){await i(t.Debug,e,n)},e.error=async function(e,n){await i(t.Error,e,n)},e.info=async function(e,n){await i(t.Info,e,n)},e.trace=async function(e,n){await i(t.Trace,e,n)},e.warn=async function(e,n){await i(t.Warn,e,n)},e}({});Object.defineProperty(window.__TAURI__,"log",{value:__TAURI_PLUGIN_LOG__})}
if("__TAURI__"in window){var __TAURI_PLUGIN_LOG__=function(e){"use strict";function n(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}async function r(e,n={},r){return window.__TAURI_INTERNALS__.invoke(e,n,r)}var a,o;async function t(e,a,o){const t={kind:"Any"};return r("plugin:event|listen",{event:e,target:t,handler:n(a)}).then((n=>async()=>async function(e,n){await r("plugin:event|unlisten",{event:e,eventId:n})}(e,n)))}async function i(e,n,a){const o=function(e){if(e){if(!e.startsWith("Error")){const n=e.split("\n").map((e=>e.split("@"))).filter((([e,n])=>e.length>0&&"[native code]"!==n));return n[2]?.filter((e=>e.length>0)).join("@")}{const n=e.split("\n"),r=n[3]?.trim();if(!r)return;const a=/at\s+(?<functionName>.*?)\s+\((?<fileName>.*?):(?<lineNumber>\d+):(?<columnNumber>\d+)\)/,o=r.match(a);if(o){const{functionName:e,fileName:n,lineNumber:r,columnNumber:a}=o.groups;return`${e}@${n}:${r}:${a}`}{const e=/at\s+(?<fileName>.*?):(?<lineNumber>\d+):(?<columnNumber>\d+)/,n=r.match(e);if(n){const{fileName:e,lineNumber:r,columnNumber:a}=n.groups;return`<anonymous>@${e}:${r}:${a}`}}}}}((new Error).stack),{file:t,line:i,keyValues:l}=a??{};await r("plugin:log|log",{level:e,message:n,location:o,file:t,line:i,keyValues:l})}async function l(e){return await t("log://log",(n=>{const{level:r}=n.payload;let{message:a}=n.payload;a=a.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,""),e({message:a,level:r})}))}return"function"==typeof SuppressedError&&SuppressedError,function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG_ENTER="tauri://drag-enter",e.DRAG_OVER="tauri://drag-over",e.DRAG_DROP="tauri://drag-drop",e.DRAG_LEAVE="tauri://drag-leave"}(a||(a={})),e.LogLevel=void 0,(o=e.LogLevel||(e.LogLevel={}))[o.Trace=1]="Trace",o[o.Debug=2]="Debug",o[o.Info=3]="Info",o[o.Warn=4]="Warn",o[o.Error=5]="Error",e.attachConsole=async function(){return await l((({level:n,message:r})=>{switch(n){case e.LogLevel.Trace:console.log(r);break;case e.LogLevel.Debug:console.debug(r);break;case e.LogLevel.Info:console.info(r);break;case e.LogLevel.Warn:console.warn(r);break;case e.LogLevel.Error:console.error(r);break;default:throw new Error(`unknown log level ${n}`)}}))},e.attachLogger=l,e.debug=async function(n,r){await i(e.LogLevel.Debug,n,r)},e.error=async function(n,r){await i(e.LogLevel.Error,n,r)},e.info=async function(n,r){await i(e.LogLevel.Info,n,r)},e.trace=async function(n,r){await i(e.LogLevel.Trace,n,r)},e.warn=async function(n,r){await i(e.LogLevel.Warn,n,r)},e}({});Object.defineProperty(window.__TAURI__,"log",{value:__TAURI_PLUGIN_LOG__})}

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