Merge remote-tracking branch 'origin/v2' into deps/rand

pull/2367/head
FabianLars 3 weeks ago
commit 0d6e148965
No known key found for this signature in database

@ -0,0 +1,62 @@
# 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/" }`

@ -46,7 +46,7 @@ jobs:
node-version: 'lts/*' node-version: 'lts/*'
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
with: with:
version: 9.x.x version: 10.x.x
run_install: true run_install: true
- name: audit - name: audit
run: pnpm audit run: pnpm audit

@ -8,6 +8,7 @@ on:
pull_request: pull_request:
paths: paths:
- '.github/workflows/check-generated-files.yml' - '.github/workflows/check-generated-files.yml'
- pnpm-lock.yaml
- '**/guest-js/**' - '**/guest-js/**'
concurrency: concurrency:
@ -27,94 +28,117 @@ jobs:
filters: | filters: |
autostart: autostart:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/autostart/guest-js/** - plugins/autostart/guest-js/**
- plugins/autostart/src/api-iife.js - plugins/autostart/src/api-iife.js
cli: cli:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/cli/guest-js/** - plugins/cli/guest-js/**
- plugins/cli/src/api-iife.js - plugins/cli/src/api-iife.js
clipboard-manager: clipboard-manager:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/clipboard-manager/guest-js/** - plugins/clipboard-manager/guest-js/**
- plugins/clipboard-manager/src/api-iife.js - plugins/clipboard-manager/src/api-iife.js
dialog: dialog:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/dialog/guest-js/** - plugins/dialog/guest-js/**
- plugins/dialog/src/api-iife.js - plugins/dialog/src/api-iife.js
fs: fs:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/fs/guest-js/** - plugins/fs/guest-js/**
- plugins/fs/src/api-iife.js - plugins/fs/src/api-iife.js
geolocation: geolocation:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/geolocation/guest-js/** - plugins/geolocation/guest-js/**
- plugins/geolocation/src/api-iife.js - plugins/geolocation/src/api-iife.js
global-shortcut: global-shortcut:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/global-shortcut/guest-js/** - plugins/global-shortcut/guest-js/**
- plugins/global-shortcut/src/api-iife.js - plugins/global-shortcut/src/api-iife.js
opener: opener:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/opener/guest-js/** - plugins/opener/guest-js/**
- plugins/opener/src/api-iife.js - plugins/opener/src/api-iife.js
haptics: haptics:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/haptics/guest-js/** - plugins/haptics/guest-js/**
- plugins/haptics/src/api-iife.js - plugins/haptics/src/api-iife.js
http: http:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/http/guest-js/** - plugins/http/guest-js/**
- plugins/http/src/api-iife.js - plugins/http/src/api-iife.js
log: log:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/log/guest-js/** - plugins/log/guest-js/**
- plugins/log/src/api-iife.js - plugins/log/src/api-iife.js
notification: notification:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/notification/guest-js/** - plugins/notification/guest-js/**
- plugins/notification/src/api-iife.js - plugins/notification/src/api-iife.js
os: os:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/os/guest-js/** - plugins/os/guest-js/**
- plugins/os/src/api-iife.js - plugins/os/src/api-iife.js
positioner: positioner:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/positioner/guest-js/** - plugins/positioner/guest-js/**
- plugins/positioner/src/api-iife.js - plugins/positioner/src/api-iife.js
process: process:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/process/guest-js/** - plugins/process/guest-js/**
- plugins/process/src/api-iife.js - plugins/process/src/api-iife.js
shell: shell:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/shell/guest-js/** - plugins/shell/guest-js/**
- plugins/shell/src/api-iife.js - plugins/shell/src/api-iife.js
sql: sql:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/sql/guest-js/** - plugins/sql/guest-js/**
- plugins/sql/src/api-iife.js - plugins/sql/src/api-iife.js
store: store:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/store/guest-js/** - plugins/store/guest-js/**
- plugins/store/src/api-iife.js - plugins/store/src/api-iife.js
stronghold: stronghold:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/stronghold/guest-js/** - plugins/stronghold/guest-js/**
- plugins/stronghold/src/api-iife.js - plugins/stronghold/src/api-iife.js
updater: updater:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/updater/guest-js/** - plugins/updater/guest-js/**
- plugins/updater/src/api-iife.js - plugins/updater/src/api-iife.js
upload: upload:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/upload/guest-js/** - plugins/upload/guest-js/**
- plugins/upload/src/api-iife.js - plugins/upload/src/api-iife.js
websocket: websocket:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/websocket/guest-js/** - plugins/websocket/guest-js/**
- plugins/websocket/src/api-iife.js - plugins/websocket/src/api-iife.js
window-state: window-state:
- .github/workflows/check-generated-files.yml - .github/workflows/check-generated-files.yml
- pnpm-lock.yaml
- plugins/window-state/guest-js/** - plugins/window-state/guest-js/**
- plugins/window-state/src/api-iife.js - plugins/window-state/src/api-iife.js
@ -143,7 +167,7 @@ jobs:
node-version: 'lts/*' node-version: 'lts/*'
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
with: with:
version: 9.x.x version: 10.x.x
run_install: true run_install: true
- name: build api - name: build api

@ -39,7 +39,7 @@ jobs:
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
with: with:
version: 9.x.x version: 10.x.x
run_install: true run_install: true
- name: cargo login - name: cargo login
@ -75,7 +75,7 @@ jobs:
- name: Create Pull Request With Versions Bumped - name: Create Pull Request With Versions Bumped
id: cpr id: cpr
uses: tauri-apps/create-pull-request@v3 uses: peter-evans/create-pull-request@dd2324fc52d5d43c699a5636bcf19fceaa70c284 # 7.0.7
if: steps.covector.outputs.commandRan == 'version' if: steps.covector.outputs.commandRan == 'version'
with: with:
title: 'Publish New Versions (${{ github.ref_name }})' title: 'Publish New Versions (${{ github.ref_name }})'
@ -83,3 +83,4 @@ jobs:
labels: 'version updates' labels: 'version updates'
branch: 'ci/release-${{ github.ref_name }}' branch: 'ci/release-${{ github.ref_name }}'
body: ${{ steps.covector.outputs.change }} body: ${{ steps.covector.outputs.change }}
sign-commits: true

@ -38,7 +38,7 @@ jobs:
node-version: 'lts/*' node-version: 'lts/*'
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
with: with:
version: 9.x.x version: 10.x.x
run_install: true run_install: true
- run: pnpm format:check - run: pnpm format:check

@ -49,7 +49,7 @@ jobs:
node-version: 'lts/*' node-version: 'lts/*'
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
with: with:
version: 9.x.x version: 10.x.x
run_install: true run_install: true
- name: eslint - name: eslint
run: pnpm lint run: pnpm lint

@ -38,7 +38,7 @@ jobs:
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
with: with:
version: 9.x.x version: 10.x.x
run_install: true run_install: true
- name: Build packages - name: Build packages

5
.gitignore vendored

@ -14,6 +14,8 @@ target/
# .vscode workspace settings file # .vscode workspace settings file
.vscode/settings.json .vscode/settings.json
.vscode/launch.json
.vscode/tasks.json
# npm, yarn and bun lock files # npm, yarn and bun lock files
package-lock.json package-lock.json
@ -55,4 +57,5 @@ pids
*.sublime* *.sublime*
.idea .idea
debug.log debug.log
TODO.md TODO.md
.aider*

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

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

2495
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -12,10 +12,10 @@ resolver = "2"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
tracing = "0.1" tracing = "0.1"
log = "0.4" log = "0.4"
tauri = { version = "2", default-features = false } tauri = { version = "2.6", default-features = false }
tauri-build = "2" tauri-build = "2.3"
tauri-plugin = "2" tauri-plugin = "2.3"
tauri-utils = "2" tauri-utils = "2.5"
serde_json = "1" serde_json = "1"
thiserror = "2" thiserror = "2"
url = "2" url = "2"

@ -1,5 +1,138 @@
# Changelog # Changelog
## \[2.0.26]
### Dependencies
- Upgraded to `barcode-scanner-js@2.3.0`
- Upgraded to `biometric-js@2.3.0`
- Upgraded to `cli-js@2.4.0`
- Upgraded to `clipboard-manager-js@2.3.0`
- Upgraded to `fs-js@2.4.0`
- Upgraded to `dialog-js@2.3.0`
- Upgraded to `global-shortcut-js@2.3.0`
- Upgraded to `opener-js@2.4.0`
- Upgraded to `http-js@2.5.0`
- Upgraded to `log-js@2.6.0`
- Upgraded to `nfc-js@2.3.0`
- Upgraded to `notification-js@2.3.0`
- Upgraded to `os-js@2.3.0`
- Upgraded to `process-js@2.3.0`
- Upgraded to `shell-js@2.3.0`
- Upgraded to `store-js@2.3.0`
- Upgraded to `updater-js@2.9.0`
## \[2.0.25]
### Dependencies
- Upgraded to `cli-js@2.3.0`
- Upgraded to `log-js@2.5.1`
- Upgraded to `opener-js@2.3.1`
## \[2.0.24]
### Dependencies
- Upgraded to `updater-js@2.8.1`
## \[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
- Upgraded to `clipboard-manager-js@2.2.2`
- Upgraded to `notification-js@2.2.2`
- Upgraded to `os-js@2.2.1`
- Upgraded to `http-js@2.4.0`
- Upgraded to `log-js@2.3.0`
- Upgraded to `updater-js@2.6.0`
## \[2.0.15]
### Dependencies
- Upgraded to `log-js@2.2.3`
- Upgraded to `opener-js@2.2.6`
## \[2.0.14]
### Dependencies
- Upgraded to `log-js@2.2.2`
- Upgraded to `updater-js@2.5.1`
## \[2.0.13]
### Dependencies
- Upgraded to `updater-js@2.5.0`
## \[2.0.12] ## \[2.0.12]
### Dependencies ### Dependencies

@ -1,7 +1,7 @@
{ {
"name": "api", "name": "api",
"private": true, "private": true,
"version": "2.0.12", "version": "2.0.26",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite --clearScreen false", "dev": "vite --clearScreen false",
@ -10,35 +10,35 @@
"tauri": "tauri" "tauri": "tauri"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.2.0", "@tauri-apps/api": "2.6.0",
"@tauri-apps/plugin-barcode-scanner": "^2.2.0", "@tauri-apps/plugin-barcode-scanner": "^2.3.0",
"@tauri-apps/plugin-biometric": "^2.2.0", "@tauri-apps/plugin-biometric": "^2.3.0",
"@tauri-apps/plugin-cli": "^2.2.0", "@tauri-apps/plugin-cli": "^2.4.0",
"@tauri-apps/plugin-clipboard-manager": "^2.2.1", "@tauri-apps/plugin-clipboard-manager": "^2.3.0",
"@tauri-apps/plugin-dialog": "^2.2.0", "@tauri-apps/plugin-dialog": "^2.3.0",
"@tauri-apps/plugin-fs": "^2.2.0", "@tauri-apps/plugin-fs": "^2.4.0",
"@tauri-apps/plugin-geolocation": "^2.2.0", "@tauri-apps/plugin-geolocation": "^2.2.0",
"@tauri-apps/plugin-global-shortcut": "^2.2.0", "@tauri-apps/plugin-global-shortcut": "^2.3.0",
"@tauri-apps/plugin-opener": "^2.2.5",
"@tauri-apps/plugin-haptics": "^2.2.0", "@tauri-apps/plugin-haptics": "^2.2.0",
"@tauri-apps/plugin-http": "^2.3.0", "@tauri-apps/plugin-http": "^2.5.0",
"@tauri-apps/plugin-nfc": "^2.2.0", "@tauri-apps/plugin-nfc": "^2.3.0",
"@tauri-apps/plugin-notification": "^2.2.1", "@tauri-apps/plugin-notification": "^2.3.0",
"@tauri-apps/plugin-os": "^2.2.0", "@tauri-apps/plugin-opener": "^2.4.0",
"@tauri-apps/plugin-process": "^2.2.0", "@tauri-apps/plugin-os": "^2.3.0",
"@tauri-apps/plugin-shell": "^2.2.0", "@tauri-apps/plugin-process": "^2.3.0",
"@tauri-apps/plugin-store": "^2.2.0", "@tauri-apps/plugin-shell": "^2.3.0",
"@tauri-apps/plugin-updater": "^2.4.0", "@tauri-apps/plugin-store": "^2.3.0",
"@tauri-apps/plugin-updater": "^2.9.0",
"@zerodevx/svelte-json-view": "1.0.11" "@zerodevx/svelte-json-view": "1.0.11"
}, },
"devDependencies": { "devDependencies": {
"@iconify-json/codicon": "^1.2.6", "@iconify-json/codicon": "^1.2.12",
"@iconify-json/ph": "^1.2.1", "@iconify-json/ph": "^1.2.2",
"@sveltejs/vite-plugin-svelte": "^5.0.1", "@sveltejs/vite-plugin-svelte": "^5.0.3",
"@tauri-apps/cli": "2.2.7", "@tauri-apps/cli": "2.6.0",
"@unocss/extractor-svelte": "^65.0.0", "@unocss/extractor-svelte": "^66.0.0",
"svelte": "^5.10.0", "svelte": "^5.20.4",
"unocss": "^65.0.0", "unocss": "^66.0.0",
"vite": "^6.0.3" "vite": "^6.2.6"
} }
} }

@ -1,5 +1,144 @@
# Changelog # Changelog
## \[2.0.30]
### Dependencies
- Upgraded to `barcode-scanner@2.3.0`
- Upgraded to `biometric@2.3.0`
- Upgraded to `cli@2.4.0`
- Upgraded to `clipboard-manager@2.3.0`
- Upgraded to `fs@2.4.0`
- Upgraded to `dialog@2.3.0`
- Upgraded to `geolocation@2.3.0`
- Upgraded to `global-shortcut@2.3.0`
- Upgraded to `opener@2.4.0`
- Upgraded to `haptics@2.3.0`
- Upgraded to `http@2.5.0`
- Upgraded to `log@2.6.0`
- Upgraded to `nfc@2.3.0`
- Upgraded to `notification@2.3.0`
- Upgraded to `os@2.3.0`
- Upgraded to `process@2.3.0`
- Upgraded to `shell@2.3.0`
- Upgraded to `store@2.3.0`
- Upgraded to `updater@2.9.0`
## \[2.0.29]
### Dependencies
- Upgraded to `cli@2.3.0`
- Upgraded to `log@2.5.1`
- Upgraded to `opener@2.3.1`
## \[2.0.28]
### Dependencies
- Upgraded to `updater@2.8.1`
## \[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
- Upgraded to `clipboard-manager@2.2.2`
- Upgraded to `geolocation@2.2.4`
- Upgraded to `haptics@2.2.4`
- Upgraded to `notification@2.2.2`
- Upgraded to `os@2.2.1`
- Upgraded to `http@2.4.0`
- Upgraded to `log@2.3.0`
- Upgraded to `updater@2.6.0`
## \[2.0.19]
### Dependencies
- Upgraded to `log@2.2.3`
- Upgraded to `opener@2.2.6`
## \[2.0.18]
### Dependencies
- Upgraded to `log@2.2.2`
- Upgraded to `updater@2.5.1`
## \[2.0.17]
### Dependencies
- Upgraded to `updater@2.5.0`
## \[2.0.16] ## \[2.0.16]
### Dependencies ### Dependencies

@ -1,7 +1,7 @@
[package] [package]
name = "api" name = "api"
publish = false publish = false
version = "2.0.16" version = "2.0.30"
description = "An example Tauri Application showcasing the api" description = "An example Tauri Application showcasing the api"
edition = "2021" edition = "2021"
rust-version = { workspace = true } rust-version = { workspace = true }
@ -18,30 +18,33 @@ tauri-build = { workspace = true, features = ["codegen", "isolation"] }
serde_json = { workspace = true } serde_json = { workspace = true }
serde = { workspace = true } serde = { workspace = true }
tiny_http = "0.12" tiny_http = "0.12"
time = "0.3"
log = { workspace = true } log = { workspace = true }
tauri-plugin-log = { path = "../../../plugins/log", version = "2.2.1" } tauri-plugin-log = { path = "../../../plugins/log", version = "2.6.0" }
tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.2.0", features = [ tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.4.0", features = [
"watch", "watch",
] } ] }
tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.2.1" } tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.3.0" }
tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.2.0" } tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.3.0" }
tauri-plugin-http = { path = "../../../plugins/http", features = [ tauri-plugin-http = { path = "../../../plugins/http", features = [
"multipart", "multipart",
], version = "2.3.0" } "cookies",
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.2.1", features = [ ], version = "2.5.0" }
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.3.0", features = [
"windows7-compat", "windows7-compat",
] } ] }
tauri-plugin-os = { path = "../../../plugins/os", version = "2.2.0" } tauri-plugin-os = { path = "../../../plugins/os", version = "2.3.0" }
tauri-plugin-process = { path = "../../../plugins/process", version = "2.2.0" } tauri-plugin-process = { path = "../../../plugins/process", version = "2.3.0" }
tauri-plugin-opener = { path = "../../../plugins/opener", version = "2.2.5" } tauri-plugin-opener = { path = "../../../plugins/opener", version = "2.4.0" }
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.2.0" } tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.3.0" }
tauri-plugin-store = { path = "../../../plugins/store", version = "2.2.0" } tauri-plugin-store = { path = "../../../plugins/store", version = "2.3.0" }
[dependencies.tauri] [dependencies.tauri]
workspace = true workspace = true
features = [ features = [
"wry", "wry",
"compression", "common-controls-v6",
"x11",
"image-ico", "image-ico",
"image-png", "image-png",
"isolation", "isolation",
@ -51,17 +54,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] [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-cli = { path = "../../../plugins/cli", version = "2.4.0" }
tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.2.0" } tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.3.0" }
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.4.0" } tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.9.0" }
tauri-plugin-window-state = { path = "../../../plugins/window-state", version = "2.2.0" } tauri-plugin-window-state = { path = "../../../plugins/window-state", version = "2.2.0" }
[target."cfg(any(target_os = \"android\", target_os = \"ios\"))".dependencies] [target."cfg(any(target_os = \"android\", target_os = \"ios\"))".dependencies]
tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.2.0" } tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.3.0" }
tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.2.0" } tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.3.0" }
tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.2.0" } tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.3.0" }
tauri-plugin-geolocation = { path = "../../../plugins/geolocation/", version = "2.2.3" } tauri-plugin-geolocation = { path = "../../../plugins/geolocation/", version = "2.3.0" }
tauri-plugin-haptics = { path = "../../../plugins/haptics/", version = "2.2.3" } tauri-plugin-haptics = { path = "../../../plugins/haptics/", version = "2.3.0" }
[features] [features]
prod = ["tauri/custom-protocol"] prod = ["tauri/custom-protocol"]

@ -53,7 +53,7 @@
} }
] ]
}, },
"shell:allow-open", "shell:default",
"shell:allow-kill", "shell:allow-kill",
"shell:allow-stdin-write", "shell:allow-stdin-write",
"process:allow-exit", "process:allow-exit",
@ -69,6 +69,7 @@
"fs:allow-mkdir", "fs:allow-mkdir",
"fs:allow-remove", "fs:allow-remove",
"fs:allow-write-text-file", "fs:allow-write-text-file",
"fs:read-meta",
"fs:scope-download-recursive", "fs:scope-download-recursive",
"fs:scope-resource-recursive", "fs:scope-resource-recursive",
{ {
@ -82,6 +83,15 @@
}, },
"store:default", "store:default",
"opener:default", "opener:default",
{
"identifier": "opener:allow-open-url",
"allow": [
{
"url": "https://*",
"app": "inAppBrowser"
}
]
},
{ {
"identifier": "opener:allow-open-path", "identifier": "opener:allow-open-path",
"allow": [{ "path": "$APPDATA" }, { "path": "$APPDATA/**" }] "allow": [{ "path": "$APPDATA" }, { "path": "$APPDATA/**" }]

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="CompilerConfiguration"> <component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" /> <bytecodeTargetLevel target="21" />
</component> </component>
</project> </project>

@ -15,11 +15,12 @@
</builds> </builds>
</compositeBuild> </compositeBuild>
</compositeConfiguration> </compositeConfiguration>
<option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" /> <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$USER_HOME$/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tauri-2.0.2/mobile/android" /> <option value="$USER_HOME$/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-2.5.0/mobile/android" />
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" /> <option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/buildSrc" /> <option value="$PROJECT_DIR$/buildSrc" />
@ -32,10 +33,10 @@
<option value="$PROJECT_DIR$/../../../../../plugins/haptics/android" /> <option value="$PROJECT_DIR$/../../../../../plugins/haptics/android" />
<option value="$PROJECT_DIR$/../../../../../plugins/nfc/android" /> <option value="$PROJECT_DIR$/../../../../../plugins/nfc/android" />
<option value="$PROJECT_DIR$/../../../../../plugins/notification/android" /> <option value="$PROJECT_DIR$/../../../../../plugins/notification/android" />
<option value="$PROJECT_DIR$/../../../../../plugins/opener/android" />
<option value="$PROJECT_DIR$/../../../../../plugins/shell/android" /> <option value="$PROJECT_DIR$/../../../../../plugins/shell/android" />
</set> </set>
</option> </option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings> </GradleProjectSettings>
</option> </option>
</component> </component>

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

@ -1,116 +1,116 @@
{ {
"images": [ "images" : [
{ {
"size": "20x20", "size" : "20x20",
"idiom": "iphone", "idiom" : "iphone",
"filename": "AppIcon-20x20@2x.png", "filename" : "AppIcon-20x20@2x.png",
"scale": "2x" "scale" : "2x"
}, },
{ {
"size": "20x20", "size" : "20x20",
"idiom": "iphone", "idiom" : "iphone",
"filename": "AppIcon-20x20@3x.png", "filename" : "AppIcon-20x20@3x.png",
"scale": "3x" "scale" : "3x"
}, },
{ {
"size": "29x29", "size" : "29x29",
"idiom": "iphone", "idiom" : "iphone",
"filename": "AppIcon-29x29@2x-1.png", "filename" : "AppIcon-29x29@2x-1.png",
"scale": "2x" "scale" : "2x"
}, },
{ {
"size": "29x29", "size" : "29x29",
"idiom": "iphone", "idiom" : "iphone",
"filename": "AppIcon-29x29@3x.png", "filename" : "AppIcon-29x29@3x.png",
"scale": "3x" "scale" : "3x"
}, },
{ {
"size": "40x40", "size" : "40x40",
"idiom": "iphone", "idiom" : "iphone",
"filename": "AppIcon-40x40@2x.png", "filename" : "AppIcon-40x40@2x.png",
"scale": "2x" "scale" : "2x"
}, },
{ {
"size": "40x40", "size" : "40x40",
"idiom": "iphone", "idiom" : "iphone",
"filename": "AppIcon-40x40@3x.png", "filename" : "AppIcon-40x40@3x.png",
"scale": "3x" "scale" : "3x"
}, },
{ {
"size": "60x60", "size" : "60x60",
"idiom": "iphone", "idiom" : "iphone",
"filename": "AppIcon-60x60@2x.png", "filename" : "AppIcon-60x60@2x.png",
"scale": "2x" "scale" : "2x"
}, },
{ {
"size": "60x60", "size" : "60x60",
"idiom": "iphone", "idiom" : "iphone",
"filename": "AppIcon-60x60@3x.png", "filename" : "AppIcon-60x60@3x.png",
"scale": "3x" "scale" : "3x"
}, },
{ {
"size": "20x20", "size" : "20x20",
"idiom": "ipad", "idiom" : "ipad",
"filename": "AppIcon-20x20@1x.png", "filename" : "AppIcon-20x20@1x.png",
"scale": "1x" "scale" : "1x"
}, },
{ {
"size": "20x20", "size" : "20x20",
"idiom": "ipad", "idiom" : "ipad",
"filename": "AppIcon-20x20@2x-1.png", "filename" : "AppIcon-20x20@2x-1.png",
"scale": "2x" "scale" : "2x"
}, },
{ {
"size": "29x29", "size" : "29x29",
"idiom": "ipad", "idiom" : "ipad",
"filename": "AppIcon-29x29@1x.png", "filename" : "AppIcon-29x29@1x.png",
"scale": "1x" "scale" : "1x"
}, },
{ {
"size": "29x29", "size" : "29x29",
"idiom": "ipad", "idiom" : "ipad",
"filename": "AppIcon-29x29@2x.png", "filename" : "AppIcon-29x29@2x.png",
"scale": "2x" "scale" : "2x"
}, },
{ {
"size": "40x40", "size" : "40x40",
"idiom": "ipad", "idiom" : "ipad",
"filename": "AppIcon-40x40@1x.png", "filename" : "AppIcon-40x40@1x.png",
"scale": "1x" "scale" : "1x"
}, },
{ {
"size": "40x40", "size" : "40x40",
"idiom": "ipad", "idiom" : "ipad",
"filename": "AppIcon-40x40@2x-1.png", "filename" : "AppIcon-40x40@2x-1.png",
"scale": "2x" "scale" : "2x"
}, },
{ {
"size": "76x76", "size" : "76x76",
"idiom": "ipad", "idiom" : "ipad",
"filename": "AppIcon-76x76@1x.png", "filename" : "AppIcon-76x76@1x.png",
"scale": "1x" "scale" : "1x"
}, },
{ {
"size": "76x76", "size" : "76x76",
"idiom": "ipad", "idiom" : "ipad",
"filename": "AppIcon-76x76@2x.png", "filename" : "AppIcon-76x76@2x.png",
"scale": "2x" "scale" : "2x"
}, },
{ {
"size": "83.5x83.5", "size" : "83.5x83.5",
"idiom": "ipad", "idiom" : "ipad",
"filename": "AppIcon-83.5x83.5@2x.png", "filename" : "AppIcon-83.5x83.5@2x.png",
"scale": "2x" "scale" : "2x"
}, },
{ {
"size": "1024x1024", "size" : "1024x1024",
"idiom": "ios-marketing", "idiom" : "ios-marketing",
"filename": "AppIcon-512@2x.png", "filename" : "AppIcon-512@2x.png",
"scale": "1x" "scale" : "1x"
} }
], ],
"info": { "info" : {
"version": 1, "version" : 1,
"author": "xcode" "author" : "xcode"
} }
} }

@ -1,6 +1,6 @@
{ {
"info": { "info" : {
"version": 1, "version" : 1,
"author": "xcode" "author" : "xcode"
} }
} }

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17150" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17150" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Y6W-OH-hqX">
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17122"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17122"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/>

@ -1,7 +1,7 @@
# Uncomment the next line to define a global platform for your project # Uncomment the next line to define a global platform for your project
target 'api_iOS' do target 'api_iOS' do
platform :ios, '13.0' platform :ios, '14.0'
# Pods for api_iOS # Pods for api_iOS
end end

@ -3,7 +3,7 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 56; objectVersion = 54;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
@ -22,26 +22,26 @@
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
0E96CE07CD20273DD46BF325 /* main.rs */ = {isa = PBXFileReference; lastKnownFileType = text; path = main.rs; sourceTree = "<group>"; }; 0E96CE07CD20273DD46BF325 /* main.rs */ = {isa = PBXFileReference; path = main.rs; sourceTree = "<group>"; };
1C1AB1B414CA2795AFBEDDB9 /* tray.rs */ = {isa = PBXFileReference; lastKnownFileType = text; path = tray.rs; sourceTree = "<group>"; }; 1C1AB1B414CA2795AFBEDDB9 /* tray.rs */ = {isa = PBXFileReference; path = tray.rs; sourceTree = "<group>"; };
248286BAA086BB1A5F98B2B2 /* libapp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libapp.a; sourceTree = "<group>"; }; 248286BAA086BB1A5F98B2B2 /* libapp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libapp.a; sourceTree = "<group>"; };
2F63E2AA460089BB58D40C79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; 2F63E2AA460089BB58D40C79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
338E66700FD330B99D434DD7 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; }; 338E66700FD330B99D434DD7 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; };
384966E551417F94A02D2706 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 384966E551417F94A02D2706 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
4B2D1B108AE002010BDEC6D2 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; }; 4B2D1B108AE002010BDEC6D2 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
59CFE20DCF760BE67D9CE3D6 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; 59CFE20DCF760BE67D9CE3D6 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
5AC703CEBA41A121596066F3 /* Tauri API.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Tauri API.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 5AC703CEBA41A121596066F3 /* api_iOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = api_iOS.app; sourceTree = BUILT_PRODUCTS_DIR; };
62601E25FA39E62BE119B74D /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; 62601E25FA39E62BE119B74D /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
6B7E79E23E646BA7968B457C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 6B7E79E23E646BA7968B457C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
71EB788DE4662CFC0D97F567 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 71EB788DE4662CFC0D97F567 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
74A8FDFB350B966F5AAD4A24 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = SOURCE_ROOT; }; 74A8FDFB350B966F5AAD4A24 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = SOURCE_ROOT; };
785D025E9542F7E098BF22B5 /* lib.rs */ = {isa = PBXFileReference; lastKnownFileType = text; path = lib.rs; sourceTree = "<group>"; }; 785D025E9542F7E098BF22B5 /* lib.rs */ = {isa = PBXFileReference; path = lib.rs; sourceTree = "<group>"; };
879941AE3DAA14534BBC6391 /* api_iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = api_iOS.entitlements; sourceTree = "<group>"; }; 879941AE3DAA14534BBC6391 /* api_iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = api_iOS.entitlements; sourceTree = "<group>"; };
90D3B673AFAB8D8AB561F616 /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; }; 90D3B673AFAB8D8AB561F616 /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
B6082E363D51372A7658C351 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; B6082E363D51372A7658C351 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
DC377692DC31A070A0188C9D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; DC377692DC31A070A0188C9D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
EC8C7948C50C3C9B5D96CB61 /* bindings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bindings.h; sourceTree = "<group>"; }; EC8C7948C50C3C9B5D96CB61 /* bindings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bindings.h; sourceTree = "<group>"; };
F835F52713CE8F029D5D252C /* cmd.rs */ = {isa = PBXFileReference; lastKnownFileType = text; path = cmd.rs; sourceTree = "<group>"; }; F835F52713CE8F029D5D252C /* cmd.rs */ = {isa = PBXFileReference; path = cmd.rs; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -104,7 +104,7 @@
4AC51E67B71E27F15B02C5CD /* Products */ = { 4AC51E67B71E27F15B02C5CD /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
5AC703CEBA41A121596066F3 /* Tauri API.app */, 5AC703CEBA41A121596066F3 /* api_iOS.app */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
@ -171,8 +171,10 @@
dependencies = ( dependencies = (
); );
name = api_iOS; name = api_iOS;
packageProductDependencies = (
);
productName = api_iOS; productName = api_iOS;
productReference = 5AC703CEBA41A121596066F3 /* Tauri API.app */; productReference = 5AC703CEBA41A121596066F3 /* api_iOS.app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
}; };
/* End PBXNativeTarget section */ /* End PBXNativeTarget section */
@ -198,6 +200,8 @@
en, en,
); );
mainGroup = 0677CEAF1F282F38CBA0F140; mainGroup = 0677CEAF1F282F38CBA0F140;
minimizedProjectReferenceProxies = 1;
preferredProjectObjectVersion = 54;
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
targets = ( targets = (
@ -236,7 +240,6 @@
outputPaths = ( outputPaths = (
"$(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a", "$(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a",
"$(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a", "$(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a",
"$(SRCROOT)/Externals/arm64-sim/${CONFIGURATION}/libapp.a",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
@ -301,7 +304,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0; IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -363,7 +366,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0; IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
@ -381,52 +384,29 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ARCHS = ( ARCHS = (
arm64, arm64,
"arm64-sim",
); );
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = api_iOS/api_iOS.entitlements; CODE_SIGN_ENTITLEMENTS = api_iOS/api_iOS.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = "Q93MBH6S2F";
DEVELOPMENT_TEAM = Q93MBH6S2F;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphoneos*]" = "arm64-sim x86_64"; "EXCLUDED_ARCHS[sdk=iphoneos*]" = x86_64;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"\".\"", "\".\"",
); );
INFOPLIST_FILE = api_iOS/Info.plist; INFOPLIST_FILE = api_iOS/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
"LIBRARY_SEARCH_PATHS[arch=arm64-sim]" = ( "LIBRARY_SEARCH_PATHS[arch=arm64]" = "$(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
"$(inherited)", "LIBRARY_SEARCH_PATHS[arch=x86_64]" = "$(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
"$(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION)",
"$(SDKROOT)/usr/lib/swift",
"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
);
"LIBRARY_SEARCH_PATHS[arch=arm64]" = (
"$(inherited)",
"$(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION)",
"$(SDKROOT)/usr/lib/swift",
"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
);
"LIBRARY_SEARCH_PATHS[arch=x86_64]" = (
"$(inherited)",
"$(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION)",
"$(SDKROOT)/usr/lib/swift",
"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
);
PRODUCT_BUNDLE_IDENTIFIER = com.tauri.api; PRODUCT_BUNDLE_IDENTIFIER = com.tauri.api;
PRODUCT_NAME = "Tauri API"; PRODUCT_NAME = "Tauri API";
SDKROOT = iphoneos; SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = "arm64 arm64-sim"; VALID_ARCHS = arm64;
}; };
name = debug; name = debug;
}; };
@ -436,52 +416,29 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ARCHS = ( ARCHS = (
arm64, arm64,
"arm64-sim",
); );
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = api_iOS/api_iOS.entitlements; CODE_SIGN_ENTITLEMENTS = api_iOS/api_iOS.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = "Q93MBH6S2F";
DEVELOPMENT_TEAM = Q93MBH6S2F;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphoneos*]" = "arm64-sim x86_64"; "EXCLUDED_ARCHS[sdk=iphoneos*]" = x86_64;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"\".\"", "\".\"",
); );
INFOPLIST_FILE = api_iOS/Info.plist; INFOPLIST_FILE = api_iOS/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
"LIBRARY_SEARCH_PATHS[arch=arm64-sim]" = ( "LIBRARY_SEARCH_PATHS[arch=arm64]" = "$(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
"$(inherited)", "LIBRARY_SEARCH_PATHS[arch=x86_64]" = "$(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
"$(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION)",
"$(SDKROOT)/usr/lib/swift",
"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
);
"LIBRARY_SEARCH_PATHS[arch=arm64]" = (
"$(inherited)",
"$(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION)",
"$(SDKROOT)/usr/lib/swift",
"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
);
"LIBRARY_SEARCH_PATHS[arch=x86_64]" = (
"$(inherited)",
"$(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION)",
"$(SDKROOT)/usr/lib/swift",
"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
);
PRODUCT_BUNDLE_IDENTIFIER = com.tauri.api; PRODUCT_BUNDLE_IDENTIFIER = com.tauri.api;
PRODUCT_NAME = "Tauri API"; PRODUCT_NAME = "Tauri API";
SDKROOT = iphoneos; SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = "arm64 arm64-sim"; VALID_ARCHS = arm64;
}; };
name = release; name = release;
}; };

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

@ -40,12 +40,12 @@
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
</array> </array>
<key>NSFaceIDUsageDescription</key>
<string>Authenticate with biometrics</string>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
<string>Request camera access for WebRTC</string> <string>Request camera access for WebRTC</string>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>Request microphone access for WebRTC</string> <string>Request microphone access for WebRTC</string>
<key>NSFaceIDUsageDescription</key>
<string>Authenticate with biometrics</string>
<key>NFCReaderUsageDescription</key> <key>NFCReaderUsageDescription</key>
<string>Read and write to NFC tags for testing</string> <string>Read and write to NFC tags for testing</string>
</dict> </dict>

@ -1,10 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict/>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>
</array>
</dict>
</plist> </plist>

@ -63,14 +63,12 @@ targets:
settings: settings:
base: base:
ENABLE_BITCODE: false ENABLE_BITCODE: false
ARCHS: [arm64, arm64-sim] ARCHS: [arm64]
VALID_ARCHS: arm64 arm64-sim VALID_ARCHS: arm64
LIBRARY_SEARCH_PATHS[arch=x86_64]: $(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME) LIBRARY_SEARCH_PATHS[arch=x86_64]: $(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
LIBRARY_SEARCH_PATHS[arch=arm64]: $(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME) LIBRARY_SEARCH_PATHS[arch=arm64]: $(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
LIBRARY_SEARCH_PATHS[arch=arm64-sim]: $(inherited) $(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: true ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: true
EXCLUDED_ARCHS[sdk=iphonesimulator*]: arm64 EXCLUDED_ARCHS[sdk=iphoneos*]: x86_64
EXCLUDED_ARCHS[sdk=iphoneos*]: arm64-sim x86_64
groups: [app] groups: [app]
dependencies: dependencies:
- framework: libapp.a - framework: libapp.a
@ -88,5 +86,4 @@ targets:
basedOnDependencyAnalysis: false basedOnDependencyAnalysis: false
outputFiles: outputFiles:
- $(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a - $(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a
- $(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a - $(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a
- $(SRCROOT)/Externals/arm64-sim/${CONFIGURATION}/libapp.a

@ -102,9 +102,28 @@ pub fn run() {
if let Ok(mut request) = server.recv() { if let Ok(mut request) = server.recv() {
let mut body = Vec::new(); let mut body = Vec::new();
let _ = request.as_reader().read_to_end(&mut body); 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( let response = tiny_http::Response::new(
tiny_http::StatusCode(200), tiny_http::StatusCode(200),
request.headers().to_vec(), headers,
std::io::Cursor::new(body), std::io::Cursor::new(body),
request.body_length(), request.body_length(),
None, None,

@ -2,16 +2,18 @@
import * as fs from "@tauri-apps/plugin-fs"; import * as fs from "@tauri-apps/plugin-fs";
import { convertFileSrc } from "@tauri-apps/api/core"; import { convertFileSrc } from "@tauri-apps/api/core";
import { arrayBufferToBase64 } from "../lib/utils"; import { arrayBufferToBase64 } from "../lib/utils";
import { onDestroy } from "svelte";
export let onMessage; export let onMessage;
export let insecureRenderHtml; export let insecureRenderHtml;
let path = ""; let path = "";
let img; let img;
/** @type {fs.FileHandle} */
let file; let file;
let renameTo; let renameTo;
let watchPath = ""; let watchPath = "";
let watchDebounceDelay = 0; let watchDebounceDelay = "0";
let watchRecursive = false; let watchRecursive = false;
let unwatchFn; let unwatchFn;
let unwatchPath = ""; let unwatchPath = "";
@ -118,7 +120,7 @@
.getElementById("file-save") .getElementById("file-save")
.addEventListener("click", function () { .addEventListener("click", function () {
fs.writeTextFile(path, fileInput.value, { fs.writeTextFile(path, fileInput.value, {
dir: getDir(), baseDir: getDir(),
}).catch(onMessage); }).catch(onMessage);
}); });
}); });
@ -170,6 +172,15 @@
unwatchFn = undefined; unwatchFn = undefined;
unwatchPath = undefined; unwatchPath = undefined;
} }
onDestroy(() => {
if (file) {
file.close();
}
if (unwatchFn) {
unwatchFn();
}
})
</script> </script>
<div class="flex flex-col"> <div class="flex flex-col">

@ -1,10 +1,12 @@
<script> <script>
import * as opener from '@tauri-apps/plugin-opener' import * as opener from '@tauri-apps/plugin-opener'
import { platform } from '@tauri-apps/plugin-os'
export let onMessage export let onMessage
let url = '' let url = 'https://tauri.app'
let urlProgram = '' let urlProgram =
platform() === 'ios' || platform() === 'android' ? 'inAppBrowser' : ''
function openUrl() { function openUrl() {
opener.openUrl(url, urlProgram ? urlProgram : undefined).catch(onMessage) opener.openUrl(url, urlProgram ? urlProgram : undefined).catch(onMessage)
} }

@ -12,10 +12,14 @@
isChecking = true isChecking = true
try { try {
const update = await check() const update = await check()
onMessage(`Should update: ${update.available}`) if (update) {
onMessage(update) onMessage(`Should update: ${update.available}`)
onMessage(update)
newUpdate = update newUpdate = update
} else {
onMessage('No update available')
}
} catch (e) { } catch (e) {
onMessage(e) onMessage(e)
} finally { } finally {

@ -11,26 +11,29 @@
"example:api:dev": "pnpm run --filter \"api\" tauri dev" "example:api:dev": "pnpm run --filter \"api\" tauri dev"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "9.19.0", "@eslint/js": "9.29.0",
"@rollup/plugin-node-resolve": "16.0.0", "@rollup/plugin-node-resolve": "16.0.1",
"@rollup/plugin-terser": "0.4.4", "@rollup/plugin-terser": "0.4.4",
"@rollup/plugin-typescript": "11.1.6", "@rollup/plugin-typescript": "12.1.3",
"@types/eslint__js": "8.42.3", "covector": "^0.12.4",
"covector": "^0.12.3", "eslint": "9.29.0",
"eslint": "9.19.0", "eslint-config-prettier": "10.1.5",
"eslint-config-prettier": "10.0.1",
"eslint-plugin-security": "3.0.1", "eslint-plugin-security": "3.0.1",
"prettier": "3.4.2", "prettier": "3.6.1",
"rollup": "4.32.0", "rollup": "4.44.1",
"tslib": "2.8.1", "tslib": "2.8.1",
"typescript": "5.7.3", "typescript": "5.8.3",
"typescript-eslint": "8.22.0" "typescript-eslint": "8.35.0"
}, },
"resolutions": { "pnpm": {
"semver": ">=7.5.2", "overrides": {
"optionator": ">=0.9.3" "esbuild@<0.25.0": ">=0.25.0"
},
"onlyBuiltDependencies": [
"esbuild"
]
}, },
"engines": { "engines": {
"pnpm": "^9.0.0" "pnpm": "^10.0.0"
} }
} }

@ -1,5 +1,17 @@
# Changelog # Changelog
## \[2.5.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
## \[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] ## \[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. - [`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,6 +1,6 @@
[package] [package]
name = "tauri-plugin-autostart" name = "tauri-plugin-autostart"
version = "2.2.0" version = "2.5.0"
description = "Automatically launch your application at startup." description = "Automatically launch your application at startup."
authors = { workspace = true } authors = { workspace = true }
license = { workspace = true } license = { workspace = true }

@ -57,11 +57,12 @@ First you need to register the core plugin with Tauri:
`src-tauri/src/lib.rs` `src-tauri/src/lib.rs`
```rust ```rust
use tauri_plugin_autostart::MacosLauncher;
fn main() { fn main() {
tauri::Builder::default() 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!()) .run(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application");
} }

@ -1,6 +1,6 @@
{ {
"name": "@tauri-apps/plugin-autostart", "name": "@tauri-apps/plugin-autostart",
"version": "2.2.0", "version": "2.5.0",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"authors": [ "authors": [
"Tauri Programme within The Commons Conservancy" "Tauri Programme within The Commons Conservancy"
@ -24,6 +24,6 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2.0.0" "@tauri-apps/api": "^2.6.0"
} }
} }

@ -14,7 +14,7 @@ use auto_launch::{AutoLaunch, AutoLaunchBuilder};
use serde::{ser::Serializer, Serialize}; use serde::{ser::Serializer, Serialize};
use tauri::{ use tauri::{
command, command,
plugin::{Builder, TauriPlugin}, plugin::{Builder as PluginBuilder, TauriPlugin},
Manager, Runtime, State, Manager, Runtime, State,
}; };
@ -22,8 +22,9 @@ use std::env::current_exe;
type Result<T> = std::result::Result<T, Error>; type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Copy, Clone)] #[derive(Debug, Default, Copy, Clone)]
pub enum MacosLauncher { pub enum MacosLauncher {
#[default]
LaunchAgent, LaunchAgent,
AppleScript, AppleScript,
} }
@ -71,10 +72,12 @@ impl AutoLaunchManager {
} }
pub trait ManagerExt<R: Runtime> { pub trait ManagerExt<R: Runtime> {
/// TODO: Rename these to `autostart` or `auto_start` in v3
fn autolaunch(&self) -> State<'_, AutoLaunchManager>; fn autolaunch(&self) -> State<'_, AutoLaunchManager>;
} }
impl<R: Runtime, T: Manager<R>> ManagerExt<R> for T { 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> { fn autolaunch(&self) -> State<'_, AutoLaunchManager> {
self.state::<AutoLaunchManager>() self.state::<AutoLaunchManager>()
} }
@ -95,59 +98,153 @@ async fn is_enabled(manager: State<'_, AutoLaunchManager>) -> Result<bool> {
manager.is_enabled() manager.is_enabled()
} }
#[derive(Default)]
pub struct Builder {
#[cfg(target_os = "macos")]
macos_launcher: MacosLauncher,
args: Vec<String>,
app_name: Option<String>,
}
impl Builder {
/// Create a new auto start builder with default settings
pub fn new() -> Self {
Self::default()
}
/// 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());
}
app.manage(AutoLaunchManager(
builder.build().map_err(|e| e.to_string())?,
));
Ok(())
})
.build()
}
}
/// Initializes the plugin. /// Initializes the plugin.
/// ///
/// `args` - are passed to your app on startup. /// `args` - are passed to your app on startup.
pub fn init<R: Runtime>( pub fn init<R: Runtime>(
macos_launcher: MacosLauncher, #[allow(unused)] macos_launcher: MacosLauncher,
args: Option<Vec<&'static str>>, args: Option<Vec<&'static str>>,
) -> TauriPlugin<R> { ) -> TauriPlugin<R> {
Builder::new("autostart") let mut builder = Builder::new();
.invoke_handler(tauri::generate_handler![enable, disable, is_enabled]) if let Some(args) = args {
.setup(move |app, _api| { builder = builder.args(args)
let mut builder = AutoLaunchBuilder::new(); }
builder.set_app_name(&app.package_info().name); #[cfg(target_os = "macos")]
if let Some(args) = args { {
builder.set_args(&args); builder = builder.macos_launcher(macos_launcher);
} }
builder.set_use_launch_agent(matches!(macos_launcher, MacosLauncher::LaunchAgent)); builder.build()
let current_exe = current_exe()?;
#[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) {
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());
}
app.manage(AutoLaunchManager(
builder.build().map_err(|e| e.to_string())?,
));
Ok(())
})
.build()
} }

@ -1,5 +1,13 @@
# Changelog # Changelog
## \[2.3.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
## \[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] ## \[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. - [`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,6 +1,6 @@
[package] [package]
name = "tauri-plugin-barcode-scanner" name = "tauri-plugin-barcode-scanner"
version = "2.2.0" version = "2.3.0"
description = "Scan QR codes, EAN-13 and other kinds of barcodes on Android and iOS" description = "Scan QR codes, EAN-13 and other kinds of barcodes on Android and iOS"
edition = { workspace = true } edition = { workspace = true }
authors = { workspace = true } authors = { workspace = true }

@ -1,6 +1,6 @@
{ {
"name": "@tauri-apps/plugin-barcode-scanner", "name": "@tauri-apps/plugin-barcode-scanner",
"version": "2.2.0", "version": "2.3.0",
"description": "Scan QR codes, EAN-13 and other kinds of barcodes on Android and iOS", "description": "Scan QR codes, EAN-13 and other kinds of barcodes on Android and iOS",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"authors": [ "authors": [
@ -25,6 +25,6 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2.0.0" "@tauri-apps/api": "^2.6.0"
} }
} }

@ -1,5 +1,19 @@
# Changelog # Changelog
## \[2.3.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
## \[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] ## \[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. - [`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,6 +1,6 @@
[package] [package]
name = "tauri-plugin-biometric" name = "tauri-plugin-biometric"
version = "2.2.0" version = "2.3.0"
description = "Prompt the user for biometric authentication on Android and iOS." description = "Prompt the user for biometric authentication on Android and iOS."
edition = { workspace = true } edition = { workspace = true }
authors = { workspace = true } authors = { workspace = true }

@ -98,7 +98,12 @@ class BiometricPlugin: Plugin {
} }
@objc func authenticate(_ invoke: Invoke) throws { @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( invoke.reject(
self.status.errorReason ?? "", self.status.errorReason ?? "",
code: self.status.errorCode ?? "" code: self.status.errorCode ?? ""
@ -106,15 +111,11 @@ class BiometricPlugin: Plugin {
return return
} }
let args = try invoke.parseArgs(AuthOptions.self)
let context = LAContext() let context = LAContext()
context.localizedFallbackTitle = args.fallbackTitle context.localizedFallbackTitle = args.fallbackTitle
context.localizedCancelTitle = args.cancelTitle context.localizedCancelTitle = args.cancelTitle
context.touchIDAuthenticationAllowableReuseDuration = 0 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) // force system default fallback title if an empty string is provided (the OS hides the fallback button in this case)
if allowDeviceCredential, if allowDeviceCredential,
let fallbackTitle = context.localizedFallbackTitle, let fallbackTitle = context.localizedFallbackTitle,

@ -1,6 +1,6 @@
{ {
"name": "@tauri-apps/plugin-biometric", "name": "@tauri-apps/plugin-biometric",
"version": "2.2.0", "version": "2.3.0",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"authors": [ "authors": [
"Tauri Programme within The Commons Conservancy" "Tauri Programme within The Commons Conservancy"
@ -25,6 +25,6 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2.0.0" "@tauri-apps/api": "^2.6.0"
} }
} }

@ -1,5 +1,20 @@
# Changelog # Changelog
## \[2.4.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
## \[2.3.0]
- [`f6e11282`](https://github.com/tauri-apps/plugins-workspace/commit/f6e11282a7f4036dd6d1dbb8f100e777e9e42f11) ([#2787](https://github.com/tauri-apps/plugins-workspace/pull/2787) by [@mikew](https://github.com/tauri-apps/plugins-workspace/../../mikew)) Added `Cli.matches_from(args)`. This can be combined with the `args` passed to the callback of `tauri_plugin_single_instance::init` to parse the command line arguments passed to subsequent instances of the application.
- [`37c2fb41`](https://github.com/tauri-apps/plugins-workspace/commit/37c2fb41201160e85c8dc3ad40f462cd4e17a304) ([#2772](https://github.com/tauri-apps/plugins-workspace/pull/2772) by [@floriskn](https://github.com/tauri-apps/plugins-workspace/../../floriskn)) Added a new `global` boolean flag to the `CliArg` struct to support global CLI arguments. This flag allows arguments like `--verbose` to be marked as global and automatically propagated to all subcommands, enabling consistent availability throughout the CLI.
The new field is optional and defaults to false.
## \[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] ## \[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. - [`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,6 +1,6 @@
[package] [package]
name = "tauri-plugin-cli" name = "tauri-plugin-cli"
version = "2.2.0" version = "2.4.0"
description = "Parse arguments from your Tauri application's command line interface." description = "Parse arguments from your Tauri application's command line interface."
edition = { workspace = true } edition = { workspace = true }
authors = { workspace = true } authors = { workspace = true }

@ -1,6 +1,6 @@
{ {
"name": "@tauri-apps/plugin-cli", "name": "@tauri-apps/plugin-cli",
"version": "2.2.0", "version": "2.4.0",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"authors": [ "authors": [
"Tauri Programme within The Commons Conservancy" "Tauri Programme within The Commons Conservancy"
@ -24,6 +24,6 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2.0.0" "@tauri-apps/api": "^2.6.0"
} }
} }

@ -114,6 +114,12 @@ pub struct Arg {
/// It does not define position in the argument list as a whole. When utilized with multiple=true, /// It does not define position in the argument list as a whole. When utilized with multiple=true,
/// only the last positional argument may be defined as multiple (i.e. the one with the highest index). /// only the last positional argument may be defined as multiple (i.e. the one with the highest index).
pub index: Option<usize>, pub index: Option<usize>,
/// Specifies whether the argument should be global.
///
/// Global arguments are propagated to all subcommands automatically,
/// making them available throughout the CLI regardless of where they are defined.
#[serde(default)]
pub global: bool,
} }
/// describes a CLI configuration /// describes a CLI configuration

@ -29,7 +29,11 @@ pub struct Cli<R: Runtime>(PluginApi<R, Config>);
impl<R: Runtime> Cli<R> { impl<R: Runtime> Cli<R> {
pub fn matches(&self) -> Result<parser::Matches> { pub fn matches(&self) -> Result<parser::Matches> {
parser::get_matches(self.0.config(), self.0.app().package_info()) parser::get_matches(self.0.config(), self.0.app().package_info(), None)
}
pub fn matches_from(&self, args: Vec<String>) -> Result<parser::Matches> {
parser::get_matches(self.0.config(), self.0.app().package_info(), Some(args))
} }
} }

@ -19,7 +19,7 @@ use std::collections::HashMap;
mod macros; mod macros;
/// The resolution of a argument match. /// The resolution of a argument match.
#[derive(Default, Debug, Serialize)] #[derive(Default, Debug, Serialize, Clone)]
#[non_exhaustive] #[non_exhaustive]
pub struct ArgData { pub struct ArgData {
/// - [`Value::Bool`] if it's a flag, /// - [`Value::Bool`] if it's a flag,
@ -33,7 +33,7 @@ pub struct ArgData {
} }
/// The matched subcommand. /// The matched subcommand.
#[derive(Default, Debug, Serialize)] #[derive(Default, Debug, Serialize, Clone)]
#[non_exhaustive] #[non_exhaustive]
pub struct SubcommandMatches { pub struct SubcommandMatches {
/// The subcommand name. /// The subcommand name.
@ -43,7 +43,7 @@ pub struct SubcommandMatches {
} }
/// The argument matches of a command. /// The argument matches of a command.
#[derive(Default, Debug, Serialize)] #[derive(Default, Debug, Serialize, Clone)]
#[non_exhaustive] #[non_exhaustive]
pub struct Matches { pub struct Matches {
/// Data structure mapping each found arg with its resolution. /// Data structure mapping each found arg with its resolution.
@ -79,7 +79,11 @@ impl Matches {
/// Ok(()) /// Ok(())
/// }); /// });
/// ``` /// ```
pub fn get_matches(cli: &Config, package_info: &PackageInfo) -> crate::Result<Matches> { pub fn get_matches(
cli: &Config,
package_info: &PackageInfo,
args: Option<Vec<String>>,
) -> crate::Result<Matches> {
let about = cli let about = cli
.description() .description()
.unwrap_or(&package_info.description.to_string()) .unwrap_or(&package_info.description.to_string())
@ -92,7 +96,14 @@ pub fn get_matches(cli: &Config, package_info: &PackageInfo) -> crate::Result<Ma
Some(&about), Some(&about),
cli, cli,
); );
match app.try_get_matches() {
let matches = if let Some(args) = args {
app.try_get_matches_from(args)
} else {
app.try_get_matches()
};
match matches {
Ok(matches) => Ok(get_matches_internal(cli, &matches)), Ok(matches) => Ok(get_matches_internal(cli, &matches)),
Err(e) => match e.kind() { Err(e) => match e.kind() {
ErrorKind::DisplayHelp => { ErrorKind::DisplayHelp => {
@ -278,5 +289,7 @@ fn get_arg(arg_name: String, arg: &Arg) -> ClapArg {
clap_arg = bind_value_arg!(arg, clap_arg, require_equals); clap_arg = bind_value_arg!(arg, clap_arg, require_equals);
clap_arg = bind_value_arg!(arg, clap_arg, index); clap_arg = bind_value_arg!(arg, clap_arg, index);
clap_arg = clap_arg.global(arg.global);
clap_arg clap_arg
} }

@ -1,5 +1,19 @@
# Changelog # Changelog
## \[2.3.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
## \[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
- [`d37bbdef`](https://github.com/tauri-apps/plugins-workspace/commit/d37bbdef8dc70e61e59f9fe0bb8b2a48999d0aa1) ([#2507](https://github.com/tauri-apps/plugins-workspace/pull/2507) by [@SquitchYT](https://github.com/tauri-apps/plugins-workspace/../../SquitchYT)) Fix clipboard-manager Wayland support.
## \[2.2.1] ## \[2.2.1]
- [`ce11079f`](https://github.com/tauri-apps/plugins-workspace/commit/ce11079f19852fbefdecf0e4c7d947af3624fee0) ([#2280](https://github.com/tauri-apps/plugins-workspace/pull/2280) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Explicitly drop `arboard::Clipboard` on exit. Add recommendation to not use read methods on the mainthread. - [`ce11079f`](https://github.com/tauri-apps/plugins-workspace/commit/ce11079f19852fbefdecf0e4c7d947af3624fee0) ([#2280](https://github.com/tauri-apps/plugins-workspace/pull/2280) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Explicitly drop `arboard::Clipboard` on exit. Add recommendation to not use read methods on the mainthread.

@ -1,6 +1,6 @@
[package] [package]
name = "tauri-plugin-clipboard-manager" name = "tauri-plugin-clipboard-manager"
version = "2.2.1" version = "2.3.0"
description = "Read and write to the system clipboard." description = "Read and write to the system clipboard."
edition = { workspace = true } edition = { workspace = true }
authors = { workspace = true } authors = { workspace = true }
@ -36,4 +36,4 @@ thiserror = { workspace = true }
tauri = { workspace = true, features = ["wry"] } tauri = { workspace = true, features = ["wry"] }
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies] [target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
arboard = "3" arboard = { version = "3", features = ["wayland-data-control"] }

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

@ -91,7 +91,7 @@ async function writeImage(
* import { readImage } from '@tauri-apps/plugin-clipboard-manager'; * import { readImage } from '@tauri-apps/plugin-clipboard-manager';
* *
* const clipboardImage = await readImage(); * const clipboardImage = await readImage();
* const blob = new Blob([await clipboardImage.rbga()], { type: 'image' }) * const blob = new Blob([await clipboardImage.rgba()], { type: 'image' })
* const url = URL.createObjectURL(blob) * const url = URL.createObjectURL(blob)
* ``` * ```
* @since 2.0.0 * @since 2.0.0

@ -1,6 +1,6 @@
{ {
"name": "@tauri-apps/plugin-clipboard-manager", "name": "@tauri-apps/plugin-clipboard-manager",
"version": "2.2.1", "version": "2.3.0",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"authors": [ "authors": [
"Tauri Programme within The Commons Conservancy" "Tauri Programme within The Commons Conservancy"
@ -24,6 +24,6 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2.0.0" "@tauri-apps/api": "^2.6.0"
} }
} }

@ -1,5 +1,21 @@
# Changelog # Changelog
## \[2.4.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
## \[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] ## \[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. - [`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,6 +1,6 @@
[package] [package]
name = "tauri-plugin-deep-link" name = "tauri-plugin-deep-link"
version = "2.2.0" version = "2.4.0"
description = "Set your Tauri application as the default handler for an URL" description = "Set your Tauri application as the default handler for an URL"
authors = { workspace = true } authors = { workspace = true }
license = { workspace = true } license = { workspace = true }
@ -38,7 +38,7 @@ url = { workspace = true }
[target."cfg(windows)".dependencies] [target."cfg(windows)".dependencies]
dunce = "1" dunce = "1"
windows-registry = "0.4" windows-registry = "0.5"
windows-result = "0.3" windows-result = "0.3"
[target."cfg(target_os = \"linux\")".dependencies] [target."cfg(target_os = \"linux\")".dependencies]

@ -1 +1 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_DEEP_LINK__=function(e){"use strict";function n(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}async function r(e,n={},r){return window.__TAURI_INTERNALS__.invoke(e,n,r)}var t;async function i(e,t,i){const a={kind:"Any"};return r("plugin:event|listen",{event:e,target:a,handler:n(t)}).then((n=>async()=>async function(e,n){await r("plugin:event|unlisten",{event:e,eventId:n})}(e,n)))}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"}(t||(t={})),e.getCurrent=async function(){return await r("plugin:deep-link|get_current")},e.isRegistered=async function(e){return await r("plugin:deep-link|is_registered",{protocol:e})},e.onOpenUrl=async function(e){return await i("deep-link://new-url",(n=>{e(n.payload)}))},e.register=async function(e){return await r("plugin:deep-link|register",{protocol:e})},e.unregister=async function(e){return await r("plugin:deep-link|unregister",{protocol:e})},e}({});Object.defineProperty(window.__TAURI__,"deepLink",{value:__TAURI_PLUGIN_DEEP_LINK__})} if("__TAURI__"in window){var __TAURI_PLUGIN_DEEP_LINK__=function(e){"use strict";function n(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}async function r(e,n={},r){return window.__TAURI_INTERNALS__.invoke(e,n,r)}var t;async function i(e,t,i){const _={kind:"Any"};return r("plugin:event|listen",{event:e,target:_,handler:n(t)}).then((n=>async()=>async function(e,n){window.__TAURI_EVENT_PLUGIN_INTERNALS__.unregisterListener(e,n),await r("plugin:event|unlisten",{event:e,eventId:n})}(e,n)))}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"}(t||(t={})),e.getCurrent=async function(){return await r("plugin:deep-link|get_current")},e.isRegistered=async function(e){return await r("plugin:deep-link|is_registered",{protocol:e})},e.onOpenUrl=async function(e){return await i("deep-link://new-url",(n=>{e(n.payload)}))},e.register=async function(e){return await r("plugin:deep-link|register",{protocol:e})},e.unregister=async function(e){return await r("plugin:deep-link|unregister",{protocol:e})},e}({});Object.defineProperty(window.__TAURI__,"deepLink",{value:__TAURI_PLUGIN_DEEP_LINK__})}

@ -9,25 +9,50 @@ use config::{AssociatedDomain, Config};
const COMMANDS: &[&str] = &["get_current", "register", "unregister", "is_registered"]; 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: 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 { fn intent_filter(domain: &AssociatedDomain) -> String {
format!( format!(
r#"<intent-filter android:autoVerify="true"> r#"<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" /> {}
<data android:scheme="https" />
<data android:host="{}" /> <data android:host="{}" />
{} {}
{}
{}
{}
</intent-filter>"#, </intent-filter>"#,
domain
.scheme
.iter()
.map(|scheme| format!(r#"<data android:scheme="{scheme}" />"#))
.collect::<Vec<_>>()
.join("\n "),
domain.host, 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 domain
.path_prefix .path_prefix
.iter() .iter()
.map(|prefix| format!(r#"<data android:pathPrefix="{prefix}" />"#)) .map(|prefix| format!(r#"<data android:pathPrefix="{prefix}" />"#))
.collect::<Vec<_>>() .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,23 @@
# Changelog # Changelog
## \[2.2.3]
### Dependencies
- Upgraded to `deep-link-js@2.4.0`
## \[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] ## \[2.2.0]
### Dependencies ### Dependencies

@ -1,7 +1,7 @@
{ {
"name": "deep-link-example", "name": "deep-link-example",
"private": true, "private": true,
"version": "2.2.0", "version": "2.2.3",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
@ -10,12 +10,12 @@
"tauri": "tauri" "tauri": "tauri"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "2.2.0", "@tauri-apps/api": "2.6.0",
"@tauri-apps/plugin-deep-link": "2.2.0" "@tauri-apps/plugin-deep-link": "2.4.0"
}, },
"devDependencies": { "devDependencies": {
"@tauri-apps/cli": "2.2.7", "@tauri-apps/cli": "2.6.0",
"typescript": "^5.2.2", "typescript": "^5.7.3",
"vite": "^6.0.0" "vite": "^6.2.6"
} }
} }

@ -19,7 +19,7 @@ tauri-build = { workspace = true }
[dependencies] [dependencies]
serde = { workspace = true } serde = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
tauri = { workspace = true, features = ["wry", "compression"] } tauri = { workspace = true, features = ["wry", "common-controls-v6", "x11"] }
tauri-plugin-deep-link = { path = "../../../" } tauri-plugin-deep-link = { path = "../../../" }
tauri-plugin-log = { path = "../../../../log" } tauri-plugin-log = { path = "../../../../log" }
tauri-plugin-single-instance = { path = "../../../../single-instance", features = [ tauri-plugin-single-instance = { path = "../../../../single-instance", features = [

@ -1,6 +1,6 @@
{ {
"name": "@tauri-apps/plugin-deep-link", "name": "@tauri-apps/plugin-deep-link",
"version": "2.2.0", "version": "2.4.0",
"description": "Set your Tauri application as the default handler for an URL", "description": "Set your Tauri application as the default handler for an URL",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"authors": [ "authors": [
@ -25,6 +25,6 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2.0.0" "@tauri-apps/api": "^2.6.0"
} }
} }

@ -9,10 +9,25 @@ use tauri_utils::config::DeepLinkProtocol;
#[derive(Deserialize, Clone)] #[derive(Deserialize, Clone)]
pub struct AssociatedDomain { pub struct AssociatedDomain {
#[serde(default = "default_schemes")]
pub scheme: Vec<String>,
#[serde(deserialize_with = "deserialize_associated_host")] #[serde(deserialize_with = "deserialize_associated_host")]
pub host: String, 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")] #[serde(default, alias = "path-prefix", rename = "pathPrefix")]
pub path_prefix: Vec<String>, 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> fn deserialize_associated_host<'de, D>(deserializer: D) -> Result<String, D::Error>

@ -114,8 +114,8 @@ mod imp {
/// ## Platform-specific: /// ## 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. /// - **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`]. /// 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. /// 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>>> { pub fn get_current(&self) -> crate::Result<Option<Vec<url::Url>>> {
self.plugin_handle self.plugin_handle
.run_mobile_plugin::<GetCurrentResponse>("getCurrent", ()) .run_mobile_plugin::<GetCurrentResponse>("getCurrent", ())
@ -172,7 +172,7 @@ mod imp {
use tauri::Manager; use tauri::Manager;
use tauri::{AppHandle, Runtime}; use tauri::{AppHandle, Runtime};
#[cfg(windows)] #[cfg(windows)]
use windows_registry::CURRENT_USER; use windows_registry::{CLASSES_ROOT, CURRENT_USER, LOCAL_MACHINE};
/// Access to the deep-link APIs. /// Access to the deep-link APIs.
pub struct DeepLink<R: Runtime> { pub struct DeepLink<R: Runtime> {
@ -226,8 +226,8 @@ mod imp {
/// ## Platform-specific: /// ## 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. /// - **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`]. /// 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. /// 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>>> { pub fn get_current(&self) -> crate::Result<Option<Vec<url::Url>>> {
return Ok(self.current.lock().unwrap().clone()); return Ok(self.current.lock().unwrap().clone());
} }
@ -258,25 +258,23 @@ mod imp {
pub fn register<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<()> { pub fn register<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<()> {
#[cfg(windows)] #[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()?) let exe = dunce::simplified(&tauri::utils::platform::current_exe()?)
.display() .display()
.to_string(); .to_string();
let key_reg = CURRENT_USER.create(&key_base)?; let key_reg = CURRENT_USER.create(&key_base)?;
key_reg.set_string( key_reg.set_string("", format!("URL:{} protocol", self.app.config().identifier))?;
"",
&format!("URL:{} protocol", self.app.config().identifier),
)?;
key_reg.set_string("URL Protocol", "")?; key_reg.set_string("URL Protocol", "")?;
let icon_reg = CURRENT_USER.create(format!("{key_base}\\DefaultIcon"))?; let icon_reg = CURRENT_USER.create(format!("{key_base}\\DefaultIcon"))?;
icon_reg.set_string("", &format!("{exe},0"))?; icon_reg.set_string("", format!("{exe},0"))?;
let cmd_reg = CURRENT_USER.create(format!("{key_base}\\shell\\open\\command"))?; let cmd_reg = CURRENT_USER.create(format!("{key_base}\\shell\\open\\command"))?;
cmd_reg.set_string("", &format!("\"{exe}\" \"%1\""))?; cmd_reg.set_string("", format!("\"{exe}\" \"%1\""))?;
Ok(()) Ok(())
} }
@ -351,13 +349,21 @@ mod imp {
/// ///
/// ## Platform-specific: /// ## 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. /// - **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`). /// - **macOS / Android / iOS**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
pub fn unregister<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<()> { pub fn unregister<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<()> {
#[cfg(windows)] #[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(()) Ok(())
} }
@ -401,10 +407,11 @@ mod imp {
pub fn is_registered<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<bool> { pub fn is_registered<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<bool> {
#[cfg(windows)] #[cfg(windows)]
{ {
let cmd_reg = CURRENT_USER.open(format!( let protocol = _protocol.as_ref();
"Software\\Classes\\{}\\shell\\open\\command", let Ok(cmd_reg) = CLASSES_ROOT.open(format!("{protocol}\\shell\\open\\command"))
_protocol.as_ref() else {
))?; return Ok(false);
};
let registered_cmd = cmd_reg.get_string("")?; let registered_cmd = cmd_reg.get_string("")?;

@ -1,5 +1,25 @@
# Changelog # Changelog
## \[2.3.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
### Dependencies
- Upgraded to `fs-js@2.4.0`
## \[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] ## \[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. - [`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,6 +1,6 @@
[package] [package]
name = "tauri-plugin-dialog" name = "tauri-plugin-dialog"
version = "2.2.0" version = "2.3.0"
description = "Native system dialogs for opening and saving files along with message dialogs on your Tauri application." description = "Native system dialogs for opening and saving files along with message dialogs on your Tauri application."
edition = { workspace = true } edition = { workspace = true }
authors = { workspace = true } authors = { workspace = true }
@ -34,7 +34,7 @@ tauri = { workspace = true }
log = { workspace = true } log = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
url = { workspace = true } url = { workspace = true }
tauri-plugin-fs = { path = "../fs", version = "2.2.0" } tauri-plugin-fs = { path = "../fs", version = "2.4.0" }
[target.'cfg(target_os = "ios")'.dependencies] [target.'cfg(target_os = "ios")'.dependencies]
tauri = { workspace = true, features = ["wry"] } tauri = { workspace = true, features = ["wry"] }

@ -1,6 +1,6 @@
{ {
"name": "@tauri-apps/plugin-dialog", "name": "@tauri-apps/plugin-dialog",
"version": "2.2.0", "version": "2.3.0",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"authors": [ "authors": [
"Tauri Programme within The Commons Conservancy" "Tauri Programme within The Commons Conservancy"
@ -24,6 +24,6 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2.0.0" "@tauri-apps/api": "^2.6.0"
} }
} }

@ -1,5 +1,19 @@
# Changelog # Changelog
## \[2.4.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
## \[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] ## \[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. - [`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,6 +1,6 @@
[package] [package]
name = "tauri-plugin-fs" name = "tauri-plugin-fs"
version = "2.2.0" version = "2.4.0"
description = "Access the file system." description = "Access the file system."
authors = { workspace = true } authors = { workspace = true }
license = { workspace = true } license = { workspace = true }
@ -14,7 +14,7 @@ rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"] rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.platforms.support] [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" } linux = { level = "full", notes = "No write access to `$RESOURCES` folder" }
macos = { 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" } android = { level = "partial", notes = "Access is restricted to Application folder by default" }
@ -35,7 +35,6 @@ tauri = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
url = { workspace = true } url = { workspace = true }
anyhow = "1" anyhow = "1"
uuid = { version = "1", features = ["v4"] }
glob = { workspace = true } glob = { workspace = true }
# TODO: Remove `serialization-compat-6` in v3 # TODO: Remove `serialization-compat-6` in v3
notify = { version = "8", optional = true, features = [ notify = { version = "8", optional = true, features = [

@ -68,9 +68,9 @@ fn main() {
Afterwards all the plugin's APIs are available through the JavaScript guest bindings: Afterwards all the plugin's APIs are available through the JavaScript guest bindings:
```javascript ```javascript
import { metadata } from '@tauri-apps/plugin-fs' import { stat } from '@tauri-apps/plugin-fs'
await metadata('/path/to/file') await stat('/path/to/file')
``` ```
## Contributing ## Contributing

File diff suppressed because one or more lines are too long

@ -101,6 +101,7 @@ const COMMANDS: &[(&str, &[&str])] = &[
("fstat", &[]), ("fstat", &[]),
("exists", &[]), ("exists", &[]),
("watch", &[]), ("watch", &[]),
// TODO: Remove this in v3
("unwatch", &[]), ("unwatch", &[]),
("size", &[]), ("size", &[]),
]; ];

@ -604,8 +604,8 @@ async function copyFile(
options?: CopyFileOptions options?: CopyFileOptions
): Promise<void> { ): Promise<void> {
if ( if (
(fromPath instanceof URL && fromPath.protocol !== 'file:') || (fromPath instanceof URL && fromPath.protocol !== 'file:')
(toPath instanceof URL && toPath.protocol !== 'file:') || (toPath instanceof URL && toPath.protocol !== 'file:')
) { ) {
throw new TypeError('Must be a file URL.') throw new TypeError('Must be a file URL.')
} }
@ -919,8 +919,8 @@ async function rename(
options?: RenameOptions options?: RenameOptions
): Promise<void> { ): Promise<void> {
if ( if (
(oldPath instanceof URL && oldPath.protocol !== 'file:') || (oldPath instanceof URL && oldPath.protocol !== 'file:')
(newPath instanceof URL && newPath.protocol !== 'file:') || (newPath instanceof URL && newPath.protocol !== 'file:')
) { ) {
throw new TypeError('Must be a file URL.') throw new TypeError('Must be a file URL.')
} }
@ -1075,10 +1075,18 @@ async function writeFile(
if (data instanceof ReadableStream) { if (data instanceof ReadableStream) {
const file = await open(path, options) const file = await open(path, options)
for await (const chunk of data) { const reader = data.getReader()
await file.write(chunk)
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 { } else {
await invoke('plugin:fs|write_file', data, { await invoke('plugin:fs|write_file', data, {
headers: { headers: {
@ -1237,31 +1245,19 @@ type WatchEventKindRemove =
| { kind: 'folder' } | { kind: 'folder' }
| { kind: 'other' } | { kind: 'other' }
// TODO: Remove this in v3, return `Watcher` instead
/** /**
* @since 2.0.0 * @since 2.0.0
*/ */
type UnwatchFn = () => void type UnwatchFn = () => void
async function unwatch(rid: number): Promise<void> { class Watcher extends Resource {}
await invoke('plugin:fs|unwatch', { rid })
}
/** async function watchInternal(
* Watch changes (after a delay) on files or directories.
*
* @since 2.0.0
*/
async function watch(
paths: string | string[] | URL | URL[], paths: string | string[] | URL | URL[],
cb: (event: WatchEvent) => void, cb: (event: WatchEvent) => void,
options?: DebouncedWatchOptions options: DebouncedWatchOptions
): Promise<UnwatchFn> { ): Promise<UnwatchFn> {
const opts = {
recursive: false,
delayMs: 2000,
...options
}
const watchPaths = Array.isArray(paths) ? paths : [paths] const watchPaths = Array.isArray(paths) ? paths : [paths]
for (const path of watchPaths) { for (const path of watchPaths) {
@ -1275,15 +1271,35 @@ async function watch(
const rid: number = await invoke('plugin:fs|watch', { const rid: number = await invoke('plugin:fs|watch', {
paths: watchPaths.map((p) => (p instanceof URL ? p.toString() : p)), paths: watchPaths.map((p) => (p instanceof URL ? p.toString() : p)),
options: opts, options,
onEvent onEvent
}) })
const watcher = new Watcher(rid)
return () => { return () => {
void unwatch(rid) void watcher.close()
} }
} }
// TODO: Return `Watcher` instead in v3
/**
* Watch changes (after a delay) on files or directories.
*
* @since 2.0.0
*/
async function watch(
paths: string | string[] | URL | URL[],
cb: (event: WatchEvent) => void,
options?: DebouncedWatchOptions
): Promise<UnwatchFn> {
return await watchInternal(paths, cb, {
delayMs: 2000,
...options
})
}
// TODO: Return `Watcher` instead in v3
/** /**
* Watch changes on files or directories. * Watch changes on files or directories.
* *
@ -1294,32 +1310,10 @@ async function watchImmediate(
cb: (event: WatchEvent) => void, cb: (event: WatchEvent) => void,
options?: WatchOptions options?: WatchOptions
): Promise<UnwatchFn> { ): Promise<UnwatchFn> {
const opts = { return await watchInternal(paths, cb, {
recursive: false,
...options, ...options,
delayMs: null delayMs: undefined
}
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)
}
} }
/** /**

@ -1,6 +1,6 @@
{ {
"name": "@tauri-apps/plugin-fs", "name": "@tauri-apps/plugin-fs",
"version": "2.2.0", "version": "2.4.0",
"description": "Access the file system.", "description": "Access the file system.",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"authors": [ "authors": [
@ -25,6 +25,6 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2.0.0" "@tauri-apps/api": "^2.6.0"
} }
} }

@ -24,8 +24,6 @@ This default permission set prevents access to critical components
of the Tauri application by default. of the Tauri application by default.
On Windows the webview data folder access is denied. On Windows the webview data folder access is denied.
#### Included permissions within this default permission set:
- `create-app-specific-dirs` - `create-app-specific-dirs`
- `read-app-specific-dirs-recursive` - `read-app-specific-dirs-recursive`

@ -25,8 +25,6 @@ the `mkdir` command.
This default permission set prevents access to critical components This default permission set prevents access to critical components
of the Tauri application by default. of the Tauri application by default.
On Windows the webview data folder access is denied. On Windows the webview data folder access is denied.
#### Included permissions within this default permission set:
""" """
permissions = [ permissions = [
"create-app-specific-dirs", "create-app-specific-dirs",

@ -1675,7 +1675,7 @@
"const": "create-app-specific-dirs" "const": "create-app-specific-dirs"
}, },
{ {
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n#### Included permissions within this default permission set:\n", "description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n",
"type": "string", "type": "string",
"const": "default" "const": "default"
}, },

@ -150,11 +150,6 @@ pub fn open<R: Runtime>(
Ok(rid) 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)] #[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CopyFileOptions { pub struct CopyFileOptions {

@ -53,10 +53,7 @@ impl FilePath {
#[inline] #[inline]
pub fn into_path(self) -> Result<PathBuf> { pub fn into_path(self) -> Result<PathBuf> {
match self { match self {
Self::Url(url) => url Self::Url(url) => url.to_file_path().map_err(|_| Error::InvalidPathUrl),
.to_file_path()
.map(PathBuf::from)
.map_err(|_| Error::InvalidPathUrl),
Self::Path(p) => Ok(p), Self::Path(p) => Ok(p),
} }
} }
@ -91,10 +88,7 @@ impl SafeFilePath {
#[inline] #[inline]
pub fn into_path(self) -> Result<PathBuf> { pub fn into_path(self) -> Result<PathBuf> {
match self { match self {
Self::Url(url) => url Self::Url(url) => url.to_file_path().map_err(|_| Error::InvalidPathUrl),
.to_file_path()
.map(PathBuf::from)
.map_err(|_| Error::InvalidPathUrl),
Self::Path(p) => Ok(p.as_ref().to_owned()), Self::Path(p) => Ok(p.as_ref().to_owned()),
} }
} }

@ -397,7 +397,6 @@ pub fn init<R: Runtime>() -> TauriPlugin<R, Option<config::Config>> {
commands::create, commands::create,
commands::open, commands::open,
commands::copy_file, commands::copy_file,
commands::close,
commands::mkdir, commands::mkdir,
commands::read_dir, commands::read_dir,
commands::read, commands::read,
@ -420,8 +419,6 @@ pub fn init<R: Runtime>() -> TauriPlugin<R, Option<config::Config>> {
commands::size, commands::size,
#[cfg(feature = "watch")] #[cfg(feature = "watch")]
watcher::watch, watcher::watch,
#[cfg(feature = "watch")]
watcher::unwatch
]) ])
.setup(|app, api| { .setup(|app, api| {
let scope = Scope { let scope = Scope {

@ -2,8 +2,8 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
use notify::{Config, Event, RecommendedWatcher, RecursiveMode, Watcher}; use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher};
use notify_debouncer_full::{new_debouncer, DebounceEventResult, Debouncer, RecommendedCache}; use notify_debouncer_full::{new_debouncer, DebouncedEvent, Debouncer, RecommendedCache};
use serde::Deserialize; use serde::Deserialize;
use tauri::{ use tauri::{
ipc::{Channel, CommandScope, GlobalScope}, ipc::{Channel, CommandScope, GlobalScope},
@ -11,15 +11,7 @@ use tauri::{
Manager, Resource, ResourceId, Runtime, Webview, Manager, Resource, ResourceId, Runtime, Webview,
}; };
use std::{ use std::time::Duration;
path::PathBuf,
sync::{
mpsc::{channel, Receiver},
Mutex,
},
thread::spawn,
time::Duration,
};
use crate::{ use crate::{
commands::{resolve_path, CommandResult}, commands::{resolve_path, CommandResult},
@ -27,79 +19,44 @@ use crate::{
SafeFilePath, SafeFilePath,
}; };
struct InnerWatcher { #[allow(unused)]
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 {}
enum WatcherKind { enum WatcherKind {
Debouncer(Debouncer<RecommendedWatcher, RecommendedCache>), Debouncer(Debouncer<RecommendedWatcher, RecommendedCache>),
Watcher(RecommendedWatcher), Watcher(RecommendedWatcher),
} }
fn watch_raw(on_event: Channel<Event>, rx: Receiver<notify::Result<Event>>) { impl Resource for WatcherKind {}
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);
}
}
});
}
#[derive(Clone, Deserialize)] #[derive(Clone, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct WatchOptions { pub struct WatchOptions {
base_dir: Option<BaseDirectory>, base_dir: Option<BaseDirectory>,
#[serde(default)]
recursive: bool, recursive: bool,
delay_ms: Option<u64>, delay_ms: Option<u64>,
} }
#[tauri::command] #[tauri::command]
pub async fn watch<R: Runtime>( pub fn watch<R: Runtime>(
webview: Webview<R>, webview: Webview<R>,
paths: Vec<SafeFilePath>, paths: Vec<SafeFilePath>,
options: WatchOptions, options: WatchOptions,
on_event: Channel<Event>, on_event: Channel<notify::Event>,
global_scope: GlobalScope<Entry>, global_scope: GlobalScope<Entry>,
command_scope: CommandScope<Entry>, command_scope: CommandScope<Entry>,
) -> CommandResult<ResourceId> { ) -> CommandResult<ResourceId> {
let mut resolved_paths = Vec::with_capacity(paths.capacity()); let resolved_paths = paths
for path in paths { .into_iter()
resolved_paths.push(resolve_path( .map(|path| {
&webview, resolve_path(
&global_scope, &webview,
&command_scope, &global_scope,
path, &command_scope,
options.base_dir, path,
)?); options.base_dir,
} )
})
.collect::<CommandResult<Vec<_>>>()?;
let recursive_mode = if options.recursive { let recursive_mode = if options.recursive {
RecursiveMode::Recursive RecursiveMode::Recursive
@ -107,52 +64,40 @@ pub async fn watch<R: Runtime>(
RecursiveMode::NonRecursive RecursiveMode::NonRecursive
}; };
let kind = if let Some(delay) = options.delay_ms { let watcher_kind = if let Some(delay) = options.delay_ms {
let (tx, rx) = channel(); let mut debouncer = new_debouncer(
let mut debouncer = new_debouncer(Duration::from_millis(delay), None, tx)?; 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 { for path in &resolved_paths {
debouncer.watch(path, recursive_mode)?; debouncer.watch(path, recursive_mode)?;
} }
watch_debounced(on_event, rx);
WatcherKind::Debouncer(debouncer) WatcherKind::Debouncer(debouncer)
} else { } else {
let (tx, rx) = channel(); let mut watcher = RecommendedWatcher::new(
let mut watcher = RecommendedWatcher::new(tx, Config::default())?; 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 { for path in &resolved_paths {
watcher.watch(path, recursive_mode)?; watcher.watch(path, recursive_mode)?;
} }
watch_raw(on_event, rx);
WatcherKind::Watcher(watcher) WatcherKind::Watcher(watcher)
}; };
let rid = webview let rid = webview.resources_table().add(watcher_kind);
.resources_table()
.add(WatcherResource::new(kind, resolved_paths));
Ok(rid) 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(())
})
}

@ -1,5 +1,17 @@
# Changelog # Changelog
## \[2.3.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
## \[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.
## \[2.2.3] ## \[2.2.3]
- [`406e6f48`](https://github.com/tauri-apps/plugins-workspace/commit/406e6f484cdc13d35c50fb949f7489ca9eeccc44) ([#2323](https://github.com/tauri-apps/plugins-workspace/pull/2323) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Fixed an issue that caused build failures when the `haptics` or `geolocation` plugin was used without their `specta` feature flag enabled. - [`406e6f48`](https://github.com/tauri-apps/plugins-workspace/commit/406e6f484cdc13d35c50fb949f7489ca9eeccc44) ([#2323](https://github.com/tauri-apps/plugins-workspace/pull/2323) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Fixed an issue that caused build failures when the `haptics` or `geolocation` plugin was used without their `specta` feature flag enabled.

@ -1,7 +1,7 @@
[package] [package]
name = "tauri-plugin-geolocation" name = "tauri-plugin-geolocation"
description = "Get and track the device's current position" description = "Get and track the device's current position"
version = "2.2.3" version = "2.3.0"
edition = { workspace = true } edition = { workspace = true }
authors = { workspace = true } authors = { workspace = true }
license = { workspace = true } license = { workspace = true }

@ -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: If your app requires GPS functionality to function, **you** should add the following to your `AndroidManifest.xml` file:
```xml ```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. The Google Play Store uses this property to decide whether it should show the app to devices without GPS capabilities.
@ -118,8 +118,8 @@ import {
let permissions = await checkPermissions() let permissions = await checkPermissions()
if ( if (
permissions.location === 'prompt' || permissions.location === 'prompt'
permissions.location === 'prompt-with-rationale' || permissions.location === 'prompt-with-rationale'
) { ) {
permissions = await requestPermissions(['location']) permissions = await requestPermissions(['location'])
} }

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

@ -1,6 +1,6 @@
{ {
"name": "@tauri-apps/plugin-geolocation", "name": "@tauri-apps/plugin-geolocation",
"version": "2.2.3", "version": "2.3.0",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"authors": [ "authors": [
"Tauri Programme within The Commons Conservancy" "Tauri Programme within The Commons Conservancy"
@ -24,6 +24,6 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2.0.0" "@tauri-apps/api": "^2.6.0"
} }
} }

@ -21,9 +21,9 @@ mod models;
pub use error::{Error, Result}; pub use error::{Error, Result};
#[cfg(desktop)] #[cfg(desktop)]
use desktop::Geolocation; pub use desktop::Geolocation;
#[cfg(mobile)] #[cfg(mobile)]
use mobile::Geolocation; pub use mobile::Geolocation;
/// Extensions to [`tauri::App`], [`tauri::AppHandle`], [`tauri::WebviewWindow`], [`tauri::Webview`] and [`tauri::Window`] to access the geolocation APIs. /// Extensions to [`tauri::App`], [`tauri::AppHandle`], [`tauri::WebviewWindow`], [`tauri::Webview`] and [`tauri::Window`] to access the geolocation APIs.
pub trait GeolocationExt<R: Runtime> { pub trait GeolocationExt<R: Runtime> {

@ -1,5 +1,13 @@
# Changelog # Changelog
## \[2.3.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
## \[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] ## \[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. - [`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,6 +1,6 @@
[package] [package]
name = "tauri-plugin-global-shortcut" name = "tauri-plugin-global-shortcut"
version = "2.2.0" version = "2.3.0"
description = "Register global hotkeys listeners on your Tauri application." description = "Register global hotkeys listeners on your Tauri application."
edition = { workspace = true } edition = { workspace = true }
authors = { workspace = true } authors = { workspace = true }
@ -31,4 +31,4 @@ log = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
[target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies] [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 @@
if("__TAURI__"in window){var __TAURI_PLUGIN_GLOBAL_SHORTCUT__=function(t){"use strict";function e(t,e,r,s){if("a"===r&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===r?s:"a"===r?s.call(t):s?s.value:e.get(t)}function r(t,e,r,s,i){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(t,r),r}var s,i,n;"function"==typeof SuppressedError&&SuppressedError;const o="__TAURI_TO_IPC_KEY__";class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,s.set(this,(()=>{})),i.set(this,0),n.set(this,[]),this.id=function(t,e=!1){return window.__TAURI_INTERNALS__.transformCallback(t,e)}((({message:t,id:o})=>{if(o==e(this,i,"f"))for(e(this,s,"f").call(this,t),r(this,i,e(this,i,"f")+1);e(this,i,"f")in e(this,n,"f");){const t=e(this,n,"f")[e(this,i,"f")];e(this,s,"f").call(this,t),delete e(this,n,"f")[e(this,i,"f")],r(this,i,e(this,i,"f")+1)}else e(this,n,"f")[o]=t}))}set onmessage(t){r(this,s,t)}get onmessage(){return e(this,s,"f")}[(s=new WeakMap,i=new WeakMap,n=new WeakMap,o)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[o]()}}async function _(t,e={},r){return window.__TAURI_INTERNALS__.invoke(t,e,r)}return t.isRegistered=async function(t){return await _("plugin:global-shortcut|is_registered",{shortcut:t})},t.register=async function(t,e){const r=new a;return r.onmessage=e,await _("plugin:global-shortcut|register",{shortcuts:Array.isArray(t)?t:[t],handler:r})},t.unregister=async function(t){return await _("plugin:global-shortcut|unregister",{shortcuts:Array.isArray(t)?t:[t]})},t.unregisterAll=async function(){return await _("plugin:global-shortcut|unregister_all",{})},t}({});Object.defineProperty(window.__TAURI__,"globalShortcut",{value:__TAURI_PLUGIN_GLOBAL_SHORTCUT__})} if("__TAURI__"in window){var __TAURI_PLUGIN_GLOBAL_SHORTCUT__=function(t){"use strict";function e(t,e,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(){window.__TAURI_INTERNALS__.unregisterCallback(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,6 +1,6 @@
{ {
"name": "@tauri-apps/plugin-global-shortcut", "name": "@tauri-apps/plugin-global-shortcut",
"version": "2.2.0", "version": "2.3.0",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"authors": [ "authors": [
"Tauri Programme within The Commons Conservancy" "Tauri Programme within The Commons Conservancy"
@ -24,6 +24,6 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2.0.0" "@tauri-apps/api": "^2.6.0"
} }
} }

@ -1,5 +1,17 @@
# Changelog # Changelog
## \[2.3.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
## \[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.
## \[2.2.3] ## \[2.2.3]
- [`406e6f48`](https://github.com/tauri-apps/plugins-workspace/commit/406e6f484cdc13d35c50fb949f7489ca9eeccc44) ([#2323](https://github.com/tauri-apps/plugins-workspace/pull/2323) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Fixed an issue that caused build failures when the `haptics` or `geolocation` plugin was used without their `specta` feature flag enabled. - [`406e6f48`](https://github.com/tauri-apps/plugins-workspace/commit/406e6f484cdc13d35c50fb949f7489ca9eeccc44) ([#2323](https://github.com/tauri-apps/plugins-workspace/pull/2323) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Fixed an issue that caused build failures when the `haptics` or `geolocation` plugin was used without their `specta` feature flag enabled.

@ -1,7 +1,7 @@
[package] [package]
name = "tauri-plugin-haptics" name = "tauri-plugin-haptics"
description = "Haptic feedback and vibrations on Android and iOS" description = "Haptic feedback and vibrations on Android and iOS"
version = "2.2.3" version = "2.3.0"
edition = { workspace = true } edition = { workspace = true }
authors = { workspace = true } authors = { workspace = true }
license = { workspace = true } license = { workspace = true }

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

@ -1,6 +1,6 @@
{ {
"name": "@tauri-apps/plugin-haptics", "name": "@tauri-apps/plugin-haptics",
"version": "2.2.3", "version": "2.3.0",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"authors": [ "authors": [
"Tauri Programme within The Commons Conservancy" "Tauri Programme within The Commons Conservancy"
@ -24,6 +24,6 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2.0.0" "@tauri-apps/api": "^2.6.0"
} }
} }

@ -21,9 +21,9 @@ mod models;
pub use error::{Error, Result}; pub use error::{Error, Result};
#[cfg(desktop)] #[cfg(desktop)]
use desktop::Haptics; pub use desktop::Haptics;
#[cfg(mobile)] #[cfg(mobile)]
use mobile::Haptics; pub use mobile::Haptics;
/// Extensions to [`tauri::App`], [`tauri::AppHandle`], [`tauri::WebviewWindow`], [`tauri::Webview`] and [`tauri::Window`] to access the haptics APIs. /// Extensions to [`tauri::App`], [`tauri::AppHandle`], [`tauri::WebviewWindow`], [`tauri::Webview`] and [`tauri::Window`] to access the haptics APIs.
pub trait HapticsExt<R: Runtime> { pub trait HapticsExt<R: Runtime> {

@ -1,5 +1,42 @@
# Changelog # Changelog
## \[2.5.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
### Dependencies
- Upgraded to `fs-js@2.4.0`
## \[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.
## \[2.3.0] ## \[2.3.0]
- [`10513649`](https://github.com/tauri-apps/plugins-workspace/commit/105136494c5a5bf4b1f1cc06cc71815412d17ec8) ([#2204](https://github.com/tauri-apps/plugins-workspace/pull/2204) by [@RickeyWard](https://github.com/tauri-apps/plugins-workspace/../../RickeyWard)) Add `dangerous-settings` feature flag and new JS `danger` option to disable tls hostname/certificate validation. - [`10513649`](https://github.com/tauri-apps/plugins-workspace/commit/105136494c5a5bf4b1f1cc06cc71815412d17ec8) ([#2204](https://github.com/tauri-apps/plugins-workspace/pull/2204) by [@RickeyWard](https://github.com/tauri-apps/plugins-workspace/../../RickeyWard)) Add `dangerous-settings` feature flag and new JS `danger` option to disable tls hostname/certificate validation.

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

Loading…
Cancel
Save