mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-06-20 14:50:07 +02:00
Compare commits
165 Commits
shell-v2.3.3
...
feat/cef
| Author | SHA1 | Date | |
|---|---|---|---|
| 8049700614 | |||
| b7dab55a2e | |||
| bc005c44b0 | |||
| e919bab3eb | |||
| 95c9291cee | |||
| 114e902537 | |||
| 6972acdca6 | |||
| 06af78ae51 | |||
| 77efbab515 | |||
| 8bbc7a0d1d | |||
| 2d013294ef | |||
| 5c7668b6bb | |||
| ec0540138b | |||
| b86e999beb | |||
| c463d8ab14 | |||
| 1bb7beb307 | |||
| 3412fa2741 | |||
| af81fdac98 | |||
| c1fd33b3a2 | |||
| 250857b7b7 | |||
| 964e13f124 | |||
| e6cdc9f52e | |||
| 9228419e13 | |||
| 04d92139c8 | |||
| 5260fc90b0 | |||
| ea5c70060b | |||
| d016a8ab1e | |||
| d6a3898001 | |||
| 2e5bcdf202 | |||
| 4374b4fc1a | |||
| f75d21db33 | |||
| 4b95f5e079 | |||
| 99c3e37b54 | |||
| eaac19a5b7 | |||
| 5183e314cb | |||
| 2c0883e64e | |||
| 024ec0c29c | |||
| 35aad24773 | |||
| ab037b70d6 | |||
| 1198ad4fb0 | |||
| ea033fe3b8 | |||
| c6561ab6b4 | |||
| 8d6a6d6d31 | |||
| 2e432f70c9 | |||
| b19dcd25cb | |||
| 995e76436f | |||
| 1dc3612862 | |||
| f5f68063e4 | |||
| 36d3d19247 | |||
| 31ab6f8d24 | |||
| 21ae430ea3 | |||
| 015e817cf2 | |||
| 2a6d4b42bb | |||
| 550d137c64 | |||
| 3f21f39584 | |||
| 759c22758e | |||
| 6816dd1960 | |||
| 24154472a6 | |||
| 2574ec89e7 | |||
| 352381c6c6 | |||
| e2840a7b52 | |||
| 2971289252 | |||
| 6c3da6d290 | |||
| e97a4dedab | |||
| 93ac4cb59b | |||
| 05045f9a72 | |||
| 4f53e36a50 | |||
| ad8ec1b6b8 | |||
| 8374e997b8 | |||
| 35aa52f45e | |||
| bbc177150f | |||
| e6e2edca11 | |||
| 7ecd19da51 | |||
| a0b6c8ff3b | |||
| c12ea9306a | |||
| 98e2c11eef | |||
| 50b159f668 | |||
| 305c4f6b4e | |||
| 89f3e17952 | |||
| d4613ff002 | |||
| 69a9d5771c | |||
| 61e9b0ab64 | |||
| 25ad21beff | |||
| 2dc3f3f039 | |||
| c27af9128d | |||
| b60dd88702 | |||
| a97033bcd9 | |||
| 4375c98bed | |||
| 82fbb0c790 | |||
| de6bf68585 | |||
| 734c627084 | |||
| 05c5da072b | |||
| 0d126ff0ad | |||
| f122ee98c6 | |||
| 2308f2299d | |||
| 82c404635b | |||
| b1dbee2c55 | |||
| d7a0bb325d | |||
| f3d75f7abb | |||
| 6e2e7e48c3 | |||
| 9a2c98f450 | |||
| 4a2ecb6287 | |||
| 31415effdf | |||
| 04b33ea0b0 | |||
| 54e21f142b | |||
| d528c88b4f | |||
| 69146fa852 | |||
| 9f68f2d827 | |||
| 3d0d2e041b | |||
| 1e3d7ef16e | |||
| ce6835d50f | |||
| 1d9f47c882 | |||
| e221a04ef4 | |||
| eebfd2ed3e | |||
| 521cd8b372 | |||
| e4a40f4423 | |||
| fa8b11f19d | |||
| baefd761e0 | |||
| 2804803949 | |||
| d9d51eb8ea | |||
| 1483c63101 | |||
| 26ed78989a | |||
| f1564e58b6 | |||
| f2d4abb9e2 | |||
| 3dcf7522b1 | |||
| 02068550e8 | |||
| 66a75ece27 | |||
| fa601e8754 | |||
| d8bfe61f20 | |||
| e8915f17e4 | |||
| 6de61f854b | |||
| ad7a8d3e42 | |||
| d5509a9ac8 | |||
| 06727b19c1 | |||
| 2f9fa79747 | |||
| 1db4b0719d | |||
| dff6fa986a | |||
| a4aa53ab90 | |||
| ae278ddf60 | |||
| e644f38673 | |||
| 8bfa445023 | |||
| 14fb36e347 | |||
| 5767b848fa | |||
| 277a45f56c | |||
| 8dbe7e3233 | |||
| c23fa03f07 | |||
| 631d0e256a | |||
| b4348cee92 | |||
| 3019063ae1 | |||
| 944614f46a | |||
| a368cef912 | |||
| 27790aa67c | |||
| ad910b1135 | |||
| 6b854421a1 | |||
| 5438a5cd22 | |||
| 5cd7778723 | |||
| 1a03e9761f | |||
| 1d4bffadda | |||
| b8794272ae | |||
| 2a625adff3 | |||
| 371cd8227c | |||
| 70ef6f8d3e | |||
| 5f0ac1436f | |||
| ea172bfa3c | |||
| 6aead24047 |
+4
-8
@@ -1,11 +1,7 @@
|
|||||||
[advisories]
|
[advisories]
|
||||||
ignore = [
|
ignore = [
|
||||||
# time 0.1
|
# time crate can't be updated in the repo because of MSRV, users are unaffected
|
||||||
"RUSTSEC-2020-0071",
|
"RUSTSEC-2026-0009",
|
||||||
# needs sqlx 0.7 (still in alpha)
|
# libflate crates can't be updated in the repo because of MSRV, users are unaffected
|
||||||
"RUSTSEC-2022-0090",
|
"RUSTSEC-2026-0105",
|
||||||
# wry needs kuchiki on Android
|
|
||||||
"RUSTSEC-2023-0019",
|
|
||||||
# atty is only used when the `colored` feature is enabled on tauri-plugin-log
|
|
||||||
"RUSTSEC-2021-0145",
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ Hi! We, the maintainers, are really excited that you are interested in contribut
|
|||||||
- [Issue Reporting Guidelines](#issue-reporting-guidelines)
|
- [Issue Reporting Guidelines](#issue-reporting-guidelines)
|
||||||
- [Pull Request Guidelines](#pull-request-guidelines)
|
- [Pull Request Guidelines](#pull-request-guidelines)
|
||||||
- [Development Guide](#development-guide)
|
- [Development Guide](#development-guide)
|
||||||
|
- [AI Tool Policy](#ai-tool-policy)
|
||||||
|
|
||||||
## Issue Reporting Guidelines
|
## Issue Reporting Guidelines
|
||||||
|
|
||||||
@@ -60,3 +61,13 @@ The easiest way to test your changes is to use the [example app](https://github.
|
|||||||
To test local changes against your own application simply point the plugin create to your local repository, for example:
|
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/" }`
|
`tauri-plugin-sample = { path = "path/to/local/tauri-plugin-sample/" }`
|
||||||
|
|
||||||
|
## AI Tool Policy
|
||||||
|
|
||||||
|
It takes a lot of time to review a Pull Request while it's very easy to make a nonsensical but plausible looking one using AI tools.
|
||||||
|
It is unfair for other contributors and the reviewers to spend much of the time dealing with this, hence these rules:
|
||||||
|
|
||||||
|
1. Review and test all LLM-generated content before submitting, you're the one responsible for it, not the AI.
|
||||||
|
2. Don't use AI to respond to review comments (except for translations).
|
||||||
|
|
||||||
|
We will close the Pull Request with a `ai-slop` tag if you failed to do so.
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
name: 🐞 Bug Report
|
||||||
|
description: Report a bug
|
||||||
|
labels: ['type: bug']
|
||||||
|
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
## First of all
|
||||||
|
1. Please search for [existing issues](https://github.com/tauri-apps/plugins-workspace/issues?q=is%3Aissue) about this problem first.
|
||||||
|
2. Make sure `rustc` and all relevant Tauri packages are up to date.
|
||||||
|
3. Make sure it's an issue with a tauri plugin and not something else you are using.
|
||||||
|
4. Remember to follow our community guidelines and be friendly.
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: Describe the bug
|
||||||
|
description: A clear description of what the bug is. Include screenshots if applicable.
|
||||||
|
placeholder: Bug description
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: reproduction
|
||||||
|
attributes:
|
||||||
|
label: Reproduction
|
||||||
|
description: A link to a reproduction repo or steps to reproduce the behaviour.
|
||||||
|
placeholder: |
|
||||||
|
Please provide a minimal reproduction or steps to reproduce, see this guide https://stackoverflow.com/help/minimal-reproducible-example
|
||||||
|
Why reproduction is required? see this article https://antfu.me/posts/why-reproductions-are-required
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: expected-behavior
|
||||||
|
attributes:
|
||||||
|
label: Expected behavior
|
||||||
|
description: A clear description of what you expected to happen.
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: info
|
||||||
|
attributes:
|
||||||
|
label: Full `tauri info` output
|
||||||
|
description: 'Output of `npm run tauri info` or `cargo tauri info`. Issues without this will be closed!'
|
||||||
|
render: text
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: logs
|
||||||
|
attributes:
|
||||||
|
label: Stack trace
|
||||||
|
description: A stack trace or ANY error messages you may see.
|
||||||
|
render: text
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: context
|
||||||
|
attributes:
|
||||||
|
label: Additional context
|
||||||
|
description: Add any other context about the problem here. For example a link to a Discord discussion.
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: 💡 Request a new plugin
|
||||||
|
url: https://github.com/orgs/tauri-apps/discussions/new?category=plugin-requests
|
||||||
|
about: Propose a new Plugin to the community or the Tauri org.
|
||||||
|
- name: 💬 Discord Chat
|
||||||
|
url: https://discord.com/invite/tauri
|
||||||
|
about: Ask questions and talk to other Tauri users and the maintainers
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
name: 📚 Docs Report
|
||||||
|
about: Create a report to help us improve the docs
|
||||||
|
labels: 'type: documentation'
|
||||||
|
---
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
name: 💡 Feature Request
|
||||||
|
description: Request a feature or enhancement for an existing plugin
|
||||||
|
labels: ['type: feature request']
|
||||||
|
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
## First of all
|
||||||
|
- Please search for [existing issues](https://github.com/tauri-apps/plugins-workspace/issues?q=is%3Aissue) for this request first.
|
||||||
|
- Only requests for plugins that exist in this repo are allowed.
|
||||||
|
- You can request new plugins [here](https://github.com/orgs/tauri-apps/discussions/new?category=plugin-requests)
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: problem
|
||||||
|
attributes:
|
||||||
|
label: Describe the problem
|
||||||
|
description: A clear description of the problem this feature would solve
|
||||||
|
placeholder: "I'm always frustrated when..."
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: solution
|
||||||
|
attributes:
|
||||||
|
label: "Describe the solution you'd like"
|
||||||
|
description: A clear description of what change you would like
|
||||||
|
placeholder: 'I would like to...'
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: alternatives
|
||||||
|
attributes:
|
||||||
|
label: Alternatives considered
|
||||||
|
description: "Any alternative solutions you've considered"
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: context
|
||||||
|
attributes:
|
||||||
|
label: Additional context
|
||||||
|
description: Add any other context about the problem here.
|
||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: rustsec/audit-check@v1
|
- uses: rustsec/audit-check@v2
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
# https://github.com/tauri-apps/plugins-workspace/issues/774
|
# https://github.com/tauri-apps/plugins-workspace/issues/774
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ on:
|
|||||||
- v2
|
- v2
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
# required for npm provenance
|
# required for oidc token
|
||||||
id-token: write
|
id-token: write
|
||||||
# required to create the GitHub Release
|
# required to create the GitHub Release
|
||||||
contents: write
|
contents: write
|
||||||
@@ -62,7 +62,6 @@ jobs:
|
|||||||
id: covector
|
id: covector
|
||||||
env:
|
env:
|
||||||
CARGO_TARGET_DIR: /mnt/target
|
CARGO_TARGET_DIR: /mnt/target
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.ORG_NPM_TOKEN }}
|
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
command: 'version-or-publish'
|
command: 'version-or-publish'
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
name: integration tests
|
name: integration tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- v1
|
- v1
|
||||||
|
|||||||
@@ -154,4 +154,5 @@ jobs:
|
|||||||
run: cargo clippy --package ${{ matrix.package }} --all-targets -- -D warnings
|
run: cargo clippy --package ${{ matrix.package }} --all-targets -- -D warnings
|
||||||
|
|
||||||
- name: clippy ${{ matrix.package }} --all-features
|
- name: clippy ${{ matrix.package }} --all-features
|
||||||
|
if: matrix.package != 'tauri-plugin-dialog'
|
||||||
run: cargo clippy --package ${{ matrix.package }} --all-targets --all-features -- -D warnings
|
run: cargo clippy --package ${{ matrix.package }} --all-targets --all-features -- -D warnings
|
||||||
|
|||||||
@@ -246,9 +246,9 @@ jobs:
|
|||||||
run: cargo +stable install cross --git https://github.com/cross-rs/cross
|
run: cargo +stable install cross --git https://github.com/cross-rs/cross
|
||||||
|
|
||||||
- name: test ${{ matrix.package }}
|
- name: test ${{ matrix.package }}
|
||||||
if: matrix.package != 'tauri-plugin-http'
|
if: ${{ matrix.package != 'tauri-plugin-http' && matrix.package != 'tauri-plugin-dialog' }}
|
||||||
run: ${{ matrix.platform.runner }} ${{ matrix.platform.command }} --package ${{ matrix.package }} --target ${{ matrix.platform.target }} --all-targets --all-features
|
run: ${{ matrix.platform.runner }} ${{ matrix.platform.command }} --package ${{ matrix.package }} --target ${{ matrix.platform.target }} --all-targets --all-features
|
||||||
|
|
||||||
- name: test ${{ matrix.package }}
|
- name: test ${{ matrix.package }}
|
||||||
if: matrix.package == 'tauri-plugin-http'
|
if: ${{ matrix.package == 'tauri-plugin-http' || matrix.package == 'tauri-plugin-dialog' }}
|
||||||
run: ${{ matrix.platform.runner }} ${{ matrix.platform.command }} --package ${{ matrix.package }} --target ${{ matrix.platform.target }} --all-targets
|
run: ${{ matrix.platform.runner }} ${{ matrix.platform.command }} --package ${{ matrix.package }} --target ${{ matrix.platform.target }} --all-targets
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ target/
|
|||||||
package-lock.json
|
package-lock.json
|
||||||
yarn.lock
|
yarn.lock
|
||||||
bun.lockb
|
bun.lockb
|
||||||
|
bun.lock
|
||||||
|
|
||||||
# rust compiled folders
|
# rust compiled folders
|
||||||
target/
|
target/
|
||||||
|
|||||||
Generated
+1064
-374
File diff suppressed because it is too large
Load Diff
+11
-5
@@ -12,14 +12,14 @@ 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.8.2", default-features = false }
|
tauri = { version = "2.10", default-features = false }
|
||||||
tauri-build = "2.4"
|
tauri-build = "2.5"
|
||||||
tauri-plugin = "2.4"
|
tauri-plugin = "2.5"
|
||||||
tauri-utils = "2.7"
|
tauri-utils = "2.8"
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
thiserror = "2"
|
thiserror = "2"
|
||||||
url = "2"
|
url = "2"
|
||||||
schemars = "0.8"
|
schemars = "1"
|
||||||
dunce = "1"
|
dunce = "1"
|
||||||
specta = "^2.0.0-rc.16"
|
specta = "^2.0.0-rc.16"
|
||||||
glob = "0.3"
|
glob = "0.3"
|
||||||
@@ -39,3 +39,9 @@ codegen-units = 1
|
|||||||
lto = true
|
lto = true
|
||||||
incremental = false
|
incremental = false
|
||||||
opt-level = "s"
|
opt-level = "s"
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
tauri = { git = "https://github.com/tauri-apps/tauri.git", tag = "tauri-cef-v3.0.0-alpha.9" }
|
||||||
|
tauri-utils = { git = "https://github.com/tauri-apps/tauri.git", tag = "tauri-cef-v3.0.0-alpha.9" }
|
||||||
|
tauri-plugin = { git = "https://github.com/tauri-apps/tauri.git", tag = "tauri-cef-v3.0.0-alpha.9" }
|
||||||
|
tauri-build = { git = "https://github.com/tauri-apps/tauri.git", tag = "tauri-cef-v3.0.0-alpha.9" }
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ This repo and all plugins require a Rust version of at least **1.77.2**
|
|||||||
| [log](plugins/log) | Configurable logging. | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [log](plugins/log) | Configurable logging. | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [nfc](plugins/nfc) | Read and write NFC tags on Android and iOS. | ? | ? | ? | ✅ | ✅ |
|
| [nfc](plugins/nfc) | Read and write NFC tags on Android and iOS. | ? | ? | ? | ✅ | ✅ |
|
||||||
| [notification](plugins/notification) | Send message notifications (brief auto-expiring OS window element) to your user. Can also be used with the Notification Web API. | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [notification](plugins/notification) | Send message notifications (brief auto-expiring OS window element) to your user. Can also be used with the Notification Web API. | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [opener](plugins/opener) | Open files and URLs using their default application. | ✅ | ✅ | ✅ | ? | ? |
|
| [opener](plugins/opener) | Open files and URLs using their default application. | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [os](plugins/os) | Read information about the operating system. | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [os](plugins/os) | Read information about the operating system. | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [persisted-scope](plugins/persisted-scope) | Persist runtime scope changes on the filesystem. | ✅ | ✅ | ✅ | ? | ? |
|
| [persisted-scope](plugins/persisted-scope) | Persist runtime scope changes on the filesystem. | ✅ | ✅ | ✅ | ? | ? |
|
||||||
| [positioner](plugins/positioner) | Move windows to common locations. | ✅ | ✅ | ✅ | ❌ | ❌ |
|
| [positioner](plugins/positioner) | Move windows to common locations. | ✅ | ✅ | ✅ | ❌ | ❌ |
|
||||||
|
|||||||
@@ -1,5 +1,55 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## \[2.0.39]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `fs-js@2.5.1`
|
||||||
|
- Upgraded to `opener-js@2.5.4`
|
||||||
|
- Upgraded to `store-js@2.4.3`
|
||||||
|
- Upgraded to `dialog-js@2.7.1`
|
||||||
|
- Upgraded to `http-js@2.5.9`
|
||||||
|
|
||||||
|
## \[2.0.38]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `fs-js@2.5.0`
|
||||||
|
- Upgraded to `http-js@2.5.8`
|
||||||
|
- Upgraded to `updater-js@2.10.1`
|
||||||
|
- Upgraded to `nfc-js@2.3.5`
|
||||||
|
- Upgraded to `dialog-js@2.7.0`
|
||||||
|
|
||||||
|
## \[2.0.37]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `updater-js@2.10.0`
|
||||||
|
- Upgraded to `barcode-scanner-js@2.4.4`
|
||||||
|
- Upgraded to `http-js@2.5.7`
|
||||||
|
- Upgraded to `shell-js@2.3.5`
|
||||||
|
|
||||||
|
## \[2.0.36]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `http-js@2.5.6`
|
||||||
|
- Upgraded to `dialog-js@2.6.0`
|
||||||
|
|
||||||
|
## \[2.0.35]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `dialog-js@2.5.0`
|
||||||
|
- Upgraded to `log-js@2.8.0`
|
||||||
|
- Upgraded to `shell-js@2.3.4`
|
||||||
|
- Upgraded to `barcode-scanner-js@2.4.3`
|
||||||
|
- Upgraded to `fs-js@2.4.5`
|
||||||
|
- Upgraded to `http-js@2.5.5`
|
||||||
|
- Upgraded to `nfc-js@2.3.4`
|
||||||
|
- Upgraded to `opener-js@2.5.3`
|
||||||
|
- Upgraded to `store-js@2.4.2`
|
||||||
|
|
||||||
## \[2.0.34]
|
## \[2.0.34]
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|||||||
+21
-21
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "api",
|
"name": "api",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "2.0.34",
|
"version": "2.0.39",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --clearScreen false",
|
"dev": "vite --clearScreen false",
|
||||||
@@ -10,36 +10,36 @@
|
|||||||
"tauri": "tauri"
|
"tauri": "tauri"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "2.9.0",
|
"@tauri-apps/api": "^2.11.0",
|
||||||
"@tauri-apps/plugin-barcode-scanner": "^2.4.2",
|
"@tauri-apps/plugin-barcode-scanner": "^2.4.4",
|
||||||
"@tauri-apps/plugin-biometric": "^2.3.2",
|
"@tauri-apps/plugin-biometric": "^2.3.2",
|
||||||
"@tauri-apps/plugin-cli": "^2.4.1",
|
"@tauri-apps/plugin-cli": "^2.4.1",
|
||||||
"@tauri-apps/plugin-clipboard-manager": "^2.3.2",
|
"@tauri-apps/plugin-clipboard-manager": "^2.3.2",
|
||||||
"@tauri-apps/plugin-dialog": "^2.4.2",
|
"@tauri-apps/plugin-dialog": "^2.7.1",
|
||||||
"@tauri-apps/plugin-fs": "^2.4.4",
|
"@tauri-apps/plugin-fs": "^2.5.1",
|
||||||
"@tauri-apps/plugin-geolocation": "^2.2.0",
|
"@tauri-apps/plugin-geolocation": "^2.3.2",
|
||||||
"@tauri-apps/plugin-global-shortcut": "^2.3.1",
|
"@tauri-apps/plugin-global-shortcut": "^2.3.1",
|
||||||
"@tauri-apps/plugin-haptics": "^2.2.0",
|
"@tauri-apps/plugin-haptics": "^2.3.2",
|
||||||
"@tauri-apps/plugin-http": "^2.5.4",
|
"@tauri-apps/plugin-http": "^2.5.9",
|
||||||
"@tauri-apps/plugin-nfc": "^2.3.3",
|
"@tauri-apps/plugin-nfc": "^2.3.5",
|
||||||
"@tauri-apps/plugin-notification": "^2.3.3",
|
"@tauri-apps/plugin-notification": "^2.3.3",
|
||||||
"@tauri-apps/plugin-opener": "^2.5.2",
|
"@tauri-apps/plugin-opener": "^2.5.4",
|
||||||
"@tauri-apps/plugin-os": "^2.3.2",
|
"@tauri-apps/plugin-os": "^2.3.2",
|
||||||
"@tauri-apps/plugin-process": "^2.3.1",
|
"@tauri-apps/plugin-process": "^2.3.1",
|
||||||
"@tauri-apps/plugin-shell": "^2.3.3",
|
"@tauri-apps/plugin-shell": "^2.3.5",
|
||||||
"@tauri-apps/plugin-store": "^2.4.1",
|
"@tauri-apps/plugin-store": "^2.4.3",
|
||||||
"@tauri-apps/plugin-updater": "^2.9.0",
|
"@tauri-apps/plugin-updater": "^2.10.1",
|
||||||
"@tauri-apps/plugin-upload": "^2.3.0",
|
"@tauri-apps/plugin-upload": "^2.4.0",
|
||||||
"@zerodevx/svelte-json-view": "1.0.11"
|
"@zerodevx/svelte-json-view": "1.0.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify-json/codicon": "^1.2.12",
|
"@iconify-json/codicon": "^1.2.49",
|
||||||
"@iconify-json/ph": "^1.2.2",
|
"@iconify-json/ph": "^1.2.2",
|
||||||
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
||||||
"@tauri-apps/cli": "2.9.1",
|
"@tauri-apps/cli-cef": "3.0.0-alpha.5",
|
||||||
"@unocss/extractor-svelte": "^66.3.3",
|
"@unocss/extractor-svelte": "^66.6.7",
|
||||||
"svelte": "^5.20.4",
|
"svelte": "^5.54.0",
|
||||||
"unocss": "^66.3.3",
|
"unocss": "^66.6.7",
|
||||||
"vite": "^7.0.7"
|
"vite": "^8.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,55 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## \[2.0.43]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `fs@2.5.1`
|
||||||
|
- Upgraded to `opener@2.5.4`
|
||||||
|
- Upgraded to `store@2.4.3`
|
||||||
|
- Upgraded to `dialog@2.7.1`
|
||||||
|
- Upgraded to `http@2.5.9`
|
||||||
|
|
||||||
|
## \[2.0.42]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `fs@2.5.0`
|
||||||
|
- Upgraded to `http@2.5.8`
|
||||||
|
- Upgraded to `updater@2.10.1`
|
||||||
|
- Upgraded to `nfc@2.3.5`
|
||||||
|
- Upgraded to `dialog@2.7.0`
|
||||||
|
|
||||||
|
## \[2.0.41]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `updater@2.10.0`
|
||||||
|
- Upgraded to `barcode-scanner@2.4.4`
|
||||||
|
- Upgraded to `http@2.5.7`
|
||||||
|
- Upgraded to `shell@2.3.5`
|
||||||
|
|
||||||
|
## \[2.0.40]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `http@2.5.6`
|
||||||
|
- Upgraded to `dialog@2.6.0`
|
||||||
|
|
||||||
|
## \[2.0.39]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `dialog@2.5.0`
|
||||||
|
- Upgraded to `log@2.8.0`
|
||||||
|
- Upgraded to `shell@2.3.4`
|
||||||
|
- Upgraded to `barcode-scanner@2.4.3`
|
||||||
|
- Upgraded to `fs@2.4.5`
|
||||||
|
- Upgraded to `http@2.5.5`
|
||||||
|
- Upgraded to `nfc@2.3.4`
|
||||||
|
- Upgraded to `opener@2.5.3`
|
||||||
|
- Upgraded to `store@2.4.2`
|
||||||
|
|
||||||
## \[2.0.38]
|
## \[2.0.38]
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "api"
|
name = "api"
|
||||||
publish = false
|
publish = false
|
||||||
version = "2.0.38"
|
version = "2.0.43"
|
||||||
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 }
|
||||||
@@ -20,24 +20,24 @@ serde = { workspace = true }
|
|||||||
tiny_http = "0.12"
|
tiny_http = "0.12"
|
||||||
time = "0.3"
|
time = "0.3"
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
tauri-plugin-log = { path = "../../../plugins/log", version = "2.7.1" }
|
tauri-plugin-log = { path = "../../../plugins/log", version = "2.8.0" }
|
||||||
tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.4.4", features = [
|
tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.5.1", features = [
|
||||||
"watch",
|
"watch",
|
||||||
] }
|
] }
|
||||||
tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.3.2" }
|
tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.3.2" }
|
||||||
tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.4.2" }
|
tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.7.1" }
|
||||||
tauri-plugin-http = { path = "../../../plugins/http", features = [
|
tauri-plugin-http = { path = "../../../plugins/http", features = [
|
||||||
"multipart",
|
"multipart",
|
||||||
"cookies",
|
"cookies",
|
||||||
], version = "2.5.4" }
|
], version = "2.5.9" }
|
||||||
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.3.3", features = [
|
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.3.3", features = [
|
||||||
"windows7-compat",
|
"windows7-compat",
|
||||||
] }
|
] }
|
||||||
tauri-plugin-os = { path = "../../../plugins/os", version = "2.3.2" }
|
tauri-plugin-os = { path = "../../../plugins/os", version = "2.3.2" }
|
||||||
tauri-plugin-process = { path = "../../../plugins/process", version = "2.3.1" }
|
tauri-plugin-process = { path = "../../../plugins/process", version = "2.3.1" }
|
||||||
tauri-plugin-opener = { path = "../../../plugins/opener", version = "2.5.2" }
|
tauri-plugin-opener = { path = "../../../plugins/opener", version = "2.5.4" }
|
||||||
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.3.3" }
|
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.3.5" }
|
||||||
tauri-plugin-store = { path = "../../../plugins/store", version = "2.4.1" }
|
tauri-plugin-store = { path = "../../../plugins/store", version = "2.4.3" }
|
||||||
tauri-plugin-upload = { path = "../../../plugins/upload", version = "2.3.0" }
|
tauri-plugin-upload = { path = "../../../plugins/upload", version = "2.3.0" }
|
||||||
|
|
||||||
[dependencies.tauri]
|
[dependencies.tauri]
|
||||||
@@ -57,12 +57,12 @@ 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.4.1" }
|
tauri-plugin-cli = { path = "../../../plugins/cli", version = "2.4.1" }
|
||||||
tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.3.1" }
|
tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.3.1" }
|
||||||
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.9.0" }
|
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.10.1" }
|
||||||
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.4.2" }
|
tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.4.4" }
|
||||||
tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.3.3" }
|
tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.3.5" }
|
||||||
tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.3.2" }
|
tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.3.2" }
|
||||||
tauri-plugin-geolocation = { path = "../../../plugins/geolocation/", version = "2.3.2" }
|
tauri-plugin-geolocation = { path = "../../../plugins/geolocation/", version = "2.3.2" }
|
||||||
tauri-plugin-haptics = { path = "../../../plugins/haptics/", version = "2.3.2" }
|
tauri-plugin-haptics = { path = "../../../plugins/haptics/", version = "2.3.2" }
|
||||||
|
|||||||
@@ -23,11 +23,7 @@
|
|||||||
"core:window:allow-start-dragging",
|
"core:window:allow-start-dragging",
|
||||||
"notification:default",
|
"notification:default",
|
||||||
"os:allow-platform",
|
"os:allow-platform",
|
||||||
"dialog:allow-open",
|
"dialog:default",
|
||||||
"dialog:allow-ask",
|
|
||||||
"dialog:allow-save",
|
|
||||||
"dialog:allow-confirm",
|
|
||||||
"dialog:allow-message",
|
|
||||||
{
|
{
|
||||||
"identifier": "shell:allow-spawn",
|
"identifier": "shell:allow-spawn",
|
||||||
"allow": [
|
"allow": [
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
let filter = null;
|
let filter = null;
|
||||||
let multiple = false;
|
let multiple = false;
|
||||||
let directory = false;
|
let directory = false;
|
||||||
|
let pickerMode = "document";
|
||||||
|
let fileAccessMode = "scoped";
|
||||||
|
|
||||||
function arrayBufferToBase64(buffer, callback) {
|
function arrayBufferToBase64(buffer, callback) {
|
||||||
var blob = new Blob([buffer], {
|
var blob = new Blob([buffer], {
|
||||||
@@ -41,7 +43,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function msg() {
|
async function msg() {
|
||||||
await message("Tauri is awesome!");
|
await message("Tauri is awesome!").then((res) => onMessage(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function msgCustom(result) {
|
async function msgCustom(result) {
|
||||||
@@ -51,53 +53,60 @@
|
|||||||
.catch(onMessage);
|
.catch(onMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
function openDialog() {
|
async function openDialog() {
|
||||||
open({
|
try {
|
||||||
title: "My wonderful open dialog",
|
var result = await open({
|
||||||
defaultPath,
|
title: "My wonderful open dialog",
|
||||||
filters: filter
|
defaultPath,
|
||||||
? [
|
filters: filter
|
||||||
{
|
? [
|
||||||
name: "Tauri Example",
|
{
|
||||||
extensions: filter.split(",").map((f) => f.trim()),
|
name: "Tauri Example",
|
||||||
},
|
extensions: filter.split(",").map((f) => f.trim()),
|
||||||
]
|
},
|
||||||
: [],
|
]
|
||||||
multiple,
|
: [],
|
||||||
directory,
|
multiple,
|
||||||
})
|
directory,
|
||||||
.then(function (res) {
|
pickerMode,
|
||||||
if (Array.isArray(res)) {
|
fileAccessMode,
|
||||||
onMessage(res);
|
|
||||||
} else {
|
|
||||||
var pathToRead = res;
|
|
||||||
var isFile = pathToRead.match(/\S+\.\S+$/g);
|
|
||||||
readFile(pathToRead)
|
|
||||||
.then(function (response) {
|
|
||||||
if (isFile) {
|
|
||||||
if (
|
|
||||||
pathToRead.includes(".png") ||
|
|
||||||
pathToRead.includes(".jpg") ||
|
|
||||||
pathToRead.includes(".jpeg")
|
|
||||||
) {
|
|
||||||
arrayBufferToBase64(
|
|
||||||
new Uint8Array(response),
|
|
||||||
function (base64) {
|
|
||||||
var src = "data:image/png;base64," + base64;
|
|
||||||
insecureRenderHtml('<img src="' + src + '"></img>');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
onMessage(res);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
onMessage(res);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(onMessage(res));
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.catch(onMessage);
|
|
||||||
|
if (Array.isArray(result)) {
|
||||||
|
onMessage(result);
|
||||||
|
} else {
|
||||||
|
var pathToRead = result;
|
||||||
|
var isFile = pathToRead.match(/\S+\.\S+$/g);
|
||||||
|
|
||||||
|
await readFile(pathToRead)
|
||||||
|
.then(function (res) {
|
||||||
|
if (isFile) {
|
||||||
|
if (
|
||||||
|
pathToRead.includes(".png") ||
|
||||||
|
pathToRead.includes(".jpg") ||
|
||||||
|
pathToRead.includes(".jpeg")
|
||||||
|
) {
|
||||||
|
arrayBufferToBase64(
|
||||||
|
new Uint8Array(res),
|
||||||
|
function (base64) {
|
||||||
|
var src = "data:image/png;base64," + base64;
|
||||||
|
insecureRenderHtml('<img src="' + src + '"></img>');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Convert byte array to UTF-8 string
|
||||||
|
const decoder = new TextDecoder('utf-8');
|
||||||
|
const text = decoder.decode(new Uint8Array(res));
|
||||||
|
onMessage(text);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
onMessage(res);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch(exception) {
|
||||||
|
onMessage(exception)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveDialog() {
|
function saveDialog() {
|
||||||
@@ -112,7 +121,7 @@
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
})
|
})
|
||||||
.then(onMessage)
|
.then(onMessage)
|
||||||
.catch(onMessage);
|
.catch(onMessage);
|
||||||
}
|
}
|
||||||
@@ -142,6 +151,23 @@
|
|||||||
<input type="checkbox" id="dialog-directory" bind:checked={directory} />
|
<input type="checkbox" id="dialog-directory" bind:checked={directory} />
|
||||||
<label for="dialog-directory">Directory</label>
|
<label for="dialog-directory">Directory</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="dialog-picker-mode">Picker Mode:</label>
|
||||||
|
<select id="dialog-picker-mode" bind:value={pickerMode}>
|
||||||
|
<option value="">None</option>
|
||||||
|
<option value="media">Media</option>
|
||||||
|
<option value="image">Image</option>
|
||||||
|
<option value="video">Video</option>
|
||||||
|
<option value="document">Document</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="dialog-file-access-mode">File Access Mode:</label>
|
||||||
|
<select id="dialog-file-access-mode" bind:value={fileAccessMode}>
|
||||||
|
<option value="copy">Copy</option>
|
||||||
|
<option value="scoped">Scoped</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<div class="flex flex-wrap flex-col md:flex-row gap-2 children:flex-shrink-0">
|
<div class="flex flex-wrap flex-col md:flex-row gap-2 children:flex-shrink-0">
|
||||||
@@ -156,4 +182,4 @@
|
|||||||
<button class="btn" id="message-dialog" on:click={msg}>Message</button>
|
<button class="btn" id="message-dialog" on:click={msg}>Message</button>
|
||||||
<button class="btn" id="message-dialog" on:click={msgCustom}>Message (custom)</button>
|
<button class="btn" id="message-dialog" on:click={msgCustom}>Message (custom)</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { download, upload } from '@tauri-apps/plugin-upload'
|
import { download, upload, HttpMethod } from '@tauri-apps/plugin-upload'
|
||||||
import { open } from '@tauri-apps/plugin-dialog'
|
import { open } from '@tauri-apps/plugin-dialog'
|
||||||
import { JsonView } from '@zerodevx/svelte-json-view'
|
import { JsonView } from '@zerodevx/svelte-json-view'
|
||||||
import { appDataDir } from '@tauri-apps/api/path'
|
import { appDataDir } from '@tauri-apps/api/path'
|
||||||
@@ -16,6 +16,22 @@
|
|||||||
|
|
||||||
let uploadUrl = 'https://httpbin.org/post'
|
let uploadUrl = 'https://httpbin.org/post'
|
||||||
let uploadFilePath = ''
|
let uploadFilePath = ''
|
||||||
|
let uploadMethod = HttpMethod.Post
|
||||||
|
|
||||||
|
// Update URL when method changes
|
||||||
|
$: {
|
||||||
|
switch (uploadMethod) {
|
||||||
|
case HttpMethod.Post:
|
||||||
|
uploadUrl = 'https://httpbin.org/post'
|
||||||
|
break
|
||||||
|
case HttpMethod.Put:
|
||||||
|
uploadUrl = 'https://httpbin.org/put'
|
||||||
|
break
|
||||||
|
case HttpMethod.Patch:
|
||||||
|
uploadUrl = 'https://httpbin.org/patch'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
let uploadProgress = null
|
let uploadProgress = null
|
||||||
let uploadResult = null
|
let uploadResult = null
|
||||||
let isUploading = false
|
let isUploading = false
|
||||||
@@ -197,7 +213,8 @@
|
|||||||
},
|
},
|
||||||
new Map([
|
new Map([
|
||||||
['User-Agent', 'Tauri Upload Plugin Demo']
|
['User-Agent', 'Tauri Upload Plugin Demo']
|
||||||
])
|
]),
|
||||||
|
uploadMethod
|
||||||
)
|
)
|
||||||
|
|
||||||
uploadResult = {
|
uploadResult = {
|
||||||
@@ -340,12 +357,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="upload-method" class="block text-sm font-medium text-gray-700 mb-1">HTTP Method:</label>
|
||||||
|
<select
|
||||||
|
id="upload-method"
|
||||||
|
bind:value={uploadMethod}
|
||||||
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
|
||||||
|
disabled={isUploading}
|
||||||
|
>
|
||||||
|
<option value={HttpMethod.Post}>POST</option>
|
||||||
|
<option value={HttpMethod.Put}>PUT</option>
|
||||||
|
<option value={HttpMethod.Patch}>PATCH</option>
|
||||||
|
</select>
|
||||||
|
<p class="text-xs text-gray-500 mt-1">Choose the HTTP method for the upload request</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-blue-50 border border-blue-200 p-3 rounded-md">
|
||||||
|
<div class="text-sm text-blue-800">
|
||||||
|
<strong>Upload Configuration:</strong>
|
||||||
|
<div class="font-mono text-xs mt-1">
|
||||||
|
Method: {uploadMethod} | URL: {uploadUrl || 'Not set'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
on:click={startUpload}
|
on:click={startUpload}
|
||||||
class="w-full px-4 py-2 bg-green-500 text-white rounded-md hover:bg-green-600 disabled:opacity-50 disabled:cursor-not-allowed"
|
class="w-full px-4 py-2 bg-green-500 text-white rounded-md hover:bg-green-600 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
disabled={isUploading || !uploadUrl || !uploadFilePath}
|
disabled={isUploading || !uploadUrl || !uploadFilePath}
|
||||||
>
|
>
|
||||||
{isUploading ? 'Uploading...' : 'Upload File'}
|
{isUploading ? `Uploading (${uploadMethod})...` : `Upload File (${uploadMethod})`}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{#if uploadProgress}
|
{#if uploadProgress}
|
||||||
|
|||||||
+8
-9
@@ -11,19 +11,18 @@
|
|||||||
"example:api:dev": "pnpm run --filter \"api\" tauri dev"
|
"example:api:dev": "pnpm run --filter \"api\" tauri dev"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "9.38.0",
|
"@eslint/js": "10.0.1",
|
||||||
"@rollup/plugin-node-resolve": "16.0.3",
|
"@rollup/plugin-node-resolve": "16.0.3",
|
||||||
"@rollup/plugin-terser": "0.4.4",
|
"@rollup/plugin-terser": "1.0.0",
|
||||||
"@rollup/plugin-typescript": "12.3.0",
|
"@rollup/plugin-typescript": "12.3.0",
|
||||||
"covector": "^0.12.4",
|
"eslint": "10.2.0",
|
||||||
"eslint": "9.38.0",
|
|
||||||
"eslint-config-prettier": "10.1.8",
|
"eslint-config-prettier": "10.1.8",
|
||||||
"eslint-plugin-security": "3.0.1",
|
"eslint-plugin-security": "4.0.0",
|
||||||
"prettier": "3.6.2",
|
"prettier": "3.8.1",
|
||||||
"rollup": "4.52.5",
|
"rollup": "4.60.3",
|
||||||
"tslib": "2.8.1",
|
"tslib": "2.8.1",
|
||||||
"typescript": "5.9.3",
|
"typescript": "6.0.3",
|
||||||
"typescript-eslint": "8.46.2"
|
"typescript-eslint": "8.58.2"
|
||||||
},
|
},
|
||||||
"minimumReleaseAge": 4320,
|
"minimumReleaseAge": 4320,
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
|
|||||||
@@ -24,6 +24,6 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^2.8.0"
|
"@tauri-apps/api": "^2.11.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Automatically generated - DO NOT EDIT!
|
||||||
|
|
||||||
|
"$schema" = "../../schemas/schema.json"
|
||||||
|
|
||||||
|
commands = ["enable","disable","is_enabled"]
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-disable"
|
|
||||||
description = "Enables the disable command without any pre-configured scope."
|
|
||||||
commands.allow = ["disable"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-disable"
|
|
||||||
description = "Denies the disable command without any pre-configured scope."
|
|
||||||
commands.deny = ["disable"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-enable"
|
|
||||||
description = "Enables the enable command without any pre-configured scope."
|
|
||||||
commands.allow = ["enable"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-enable"
|
|
||||||
description = "Denies the enable command without any pre-configured scope."
|
|
||||||
commands.deny = ["enable"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-is-enabled"
|
|
||||||
description = "Enables the is_enabled command without any pre-configured scope."
|
|
||||||
commands.allow = ["is_enabled"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-is-enabled"
|
|
||||||
description = "Denies the is_enabled command without any pre-configured scope."
|
|
||||||
commands.deny = ["is_enabled"]
|
|
||||||
@@ -24,10 +24,17 @@
|
|||||||
},
|
},
|
||||||
"permission": {
|
"permission": {
|
||||||
"description": "A list of inlined permissions",
|
"description": "A list of inlined permissions",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/Permission"
|
"$ref": "#/definitions/Permission"
|
||||||
|
},
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"description": "A list of command names that get `allow-$command` and `deny-$command` permissions\nautogenerated on demand instead of being stored as explicit permissions.\n\nSee [`Manifest::command_permission`] and the ACL resolver for how these are expanded.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -35,9 +42,6 @@
|
|||||||
"DefaultPermission": {
|
"DefaultPermission": {
|
||||||
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"description": "The version of the permission.",
|
"description": "The version of the permission.",
|
||||||
@@ -46,10 +50,10 @@
|
|||||||
"null"
|
"null"
|
||||||
],
|
],
|
||||||
"format": "uint64",
|
"format": "uint64",
|
||||||
"minimum": 1.0
|
"minimum": 1
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
|
"description": "Human-readable description of what the permission does.\nTauri convention is to use `<h4>` headings in markdown content\nfor Tauri documentation generation purposes.",
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
"null"
|
"null"
|
||||||
@@ -62,16 +66,14 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"permissions"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"PermissionSet": {
|
"PermissionSet": {
|
||||||
"description": "A set of direct permissions grouped together under a new name.",
|
"description": "A set of direct permissions grouped together under a new name.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"description",
|
|
||||||
"identifier",
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"description": "A unique identifier for the permission.",
|
"description": "A unique identifier for the permission.",
|
||||||
@@ -85,17 +87,19 @@
|
|||||||
"description": "All permissions this set contains.",
|
"description": "All permissions this set contains.",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/PermissionKind"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"identifier",
|
||||||
|
"description",
|
||||||
|
"permissions"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"Permission": {
|
"Permission": {
|
||||||
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"identifier"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"description": "The version of the permission.",
|
"description": "The version of the permission.",
|
||||||
@@ -104,14 +108,14 @@
|
|||||||
"null"
|
"null"
|
||||||
],
|
],
|
||||||
"format": "uint64",
|
"format": "uint64",
|
||||||
"minimum": 1.0
|
"minimum": 1
|
||||||
},
|
},
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"description": "A unique identifier for the permission.",
|
"description": "A unique identifier for the permission.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
|
"description": "Human-readable description of what the permission does.\nTauri internal convention is to use `<h4>` headings in markdown content\nfor Tauri documentation generation purposes.",
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
"null"
|
"null"
|
||||||
@@ -147,7 +151,10 @@
|
|||||||
"$ref": "#/definitions/Target"
|
"$ref": "#/definitions/Target"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"identifier"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"Commands": {
|
"Commands": {
|
||||||
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
||||||
@@ -155,24 +162,24 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"allow": {
|
"allow": {
|
||||||
"description": "Allowed command.",
|
"description": "Allowed command.",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"default": []
|
||||||
},
|
},
|
||||||
"deny": {
|
"deny": {
|
||||||
"description": "Denied command, which takes priority.",
|
"description": "Denied command, which takes priority.",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"default": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Scopes": {
|
"Scopes": {
|
||||||
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command. The configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json { \"allow\": [{ \"path\": \"$HOME/**\" }], \"deny\": [{ \"path\": \"$HOME/secret.txt\" }] } ```",
|
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command.\nThe configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json\n{\n \"allow\": [{ \"path\": \"$HOME/**\" }],\n \"deny\": [{ \"path\": \"$HOME/secret.txt\" }]\n}\n```",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"allow": {
|
"allow": {
|
||||||
@@ -257,84 +264,27 @@
|
|||||||
{
|
{
|
||||||
"description": "MacOS.",
|
"description": "MacOS.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "macOS"
|
||||||
"macOS"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Windows.",
|
"description": "Windows.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "windows"
|
||||||
"windows"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Linux.",
|
"description": "Linux.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "linux"
|
||||||
"linux"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Android.",
|
"description": "Android.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "android"
|
||||||
"android"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "iOS.",
|
"description": "iOS.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "iOS"
|
||||||
"iOS"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"PermissionKind": {
|
|
||||||
"type": "string",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"description": "Enables the disable command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-disable",
|
|
||||||
"markdownDescription": "Enables the disable command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the disable command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-disable",
|
|
||||||
"markdownDescription": "Denies the disable command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the enable command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-enable",
|
|
||||||
"markdownDescription": "Enables the enable command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the enable command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-enable",
|
|
||||||
"markdownDescription": "Denies the enable command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the is_enabled command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-is-enabled",
|
|
||||||
"markdownDescription": "Enables the is_enabled command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the is_enabled command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-is-enabled",
|
|
||||||
"markdownDescription": "Denies the is_enabled command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "This permission set configures if your\napplication can enable or disable auto\nstarting the application on boot.\n\n#### Granted Permissions\n\nIt allows all to check, enable and\ndisable the automatic start on boot.\n\n\n#### This default permission set includes:\n\n- `allow-enable`\n- `allow-disable`\n- `allow-is-enabled`",
|
|
||||||
"type": "string",
|
|
||||||
"const": "default",
|
|
||||||
"markdownDescription": "This permission set configures if your\napplication can enable or disable auto\nstarting the application on boot.\n\n#### Granted Permissions\n\nIt allows all to check, enable and\ndisable the automatic start on boot.\n\n\n#### This default permission set includes:\n\n- `allow-enable`\n- `allow-disable`\n- `allow-is-enabled`"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.base.json",
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "guest-js"
|
||||||
|
},
|
||||||
"include": ["guest-js/*.ts"]
|
"include": ["guest-js/*.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## \[2.4.4]
|
||||||
|
|
||||||
|
- [`82fbb0c7`](https://github.com/tauri-apps/plugins-workspace/commit/82fbb0c790288eca72af9ade13828ded7700ff90) ([#3221](https://github.com/tauri-apps/plugins-workspace/pull/3221)) On iOS, fixed an application crash happening when the scanner was started when user denied permission before.
|
||||||
|
- [`b60dd887`](https://github.com/tauri-apps/plugins-workspace/commit/b60dd88702a2be2af942a3d104d728970a4c42d6) ([#3223](https://github.com/tauri-apps/plugins-workspace/pull/3223)) On iOS, start the scanning session on a separate thread to fix performance issues.
|
||||||
|
- [`c27af912`](https://github.com/tauri-apps/plugins-workspace/commit/c27af9128d6cc7a2424ec49e98005e68b2d0eb1a) ([#3222](https://github.com/tauri-apps/plugins-workspace/pull/3222)) On iOS, fixed an application crash happening when the scanner was started on the iOS Simulator (no camera available).
|
||||||
|
|
||||||
|
## \[2.4.3]
|
||||||
|
|
||||||
|
- [`d8bfe61f`](https://github.com/tauri-apps/plugins-workspace/commit/d8bfe61f20f235314bad93a9c50d8b7f3eade734) ([#3121](https://github.com/tauri-apps/plugins-workspace/pull/3121) by [@NKIPSC](https://github.com/tauri-apps/plugins-workspace/../../NKIPSC)) Remove unnecessary checks on Android when requesting camera permission.
|
||||||
|
- [`631d0e25`](https://github.com/tauri-apps/plugins-workspace/commit/631d0e256a37946b6a9102ca35511abfbebb92c5) ([#2440](https://github.com/tauri-apps/plugins-workspace/pull/2440) by [@kingsword09](https://github.com/tauri-apps/plugins-workspace/../../kingsword09)) Fix the `cameraView` is not removed after scanning in iOS.
|
||||||
|
|
||||||
## \[2.4.2]
|
## \[2.4.2]
|
||||||
|
|
||||||
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
|
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tauri-plugin-barcode-scanner"
|
name = "tauri-plugin-barcode-scanner"
|
||||||
version = "2.4.2"
|
version = "2.4.4"
|
||||||
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 }
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ import java.util.concurrent.ExecutionException
|
|||||||
|
|
||||||
private const val PERMISSION_ALIAS_CAMERA = "camera"
|
private const val PERMISSION_ALIAS_CAMERA = "camera"
|
||||||
private const val PERMISSION_NAME = Manifest.permission.CAMERA
|
private const val PERMISSION_NAME = Manifest.permission.CAMERA
|
||||||
private const val PREFS_PERMISSION_FIRST_TIME_ASKING = "PREFS_PERMISSION_FIRST_TIME_ASKING"
|
|
||||||
|
|
||||||
@InvokeArg
|
@InvokeArg
|
||||||
class ScanOptions {
|
class ScanOptions {
|
||||||
@@ -354,17 +353,6 @@ class BarcodeScannerPlugin(private val activity: Activity) : Plugin(activity),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun markFirstPermissionRequest() {
|
|
||||||
val sharedPreference: SharedPreferences =
|
|
||||||
activity.getSharedPreferences(PREFS_PERMISSION_FIRST_TIME_ASKING, MODE_PRIVATE)
|
|
||||||
sharedPreference.edit().putBoolean(PERMISSION_NAME, false).apply()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun firstPermissionRequest(): Boolean {
|
|
||||||
return activity.getSharedPreferences(PREFS_PERMISSION_FIRST_TIME_ASKING, MODE_PRIVATE)
|
|
||||||
.getBoolean(PERMISSION_NAME, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("ObsoleteSdkInt")
|
@SuppressLint("ObsoleteSdkInt")
|
||||||
@PermissionCallback
|
@PermissionCallback
|
||||||
fun cameraPermissionCallback(invoke: Invoke) {
|
fun cameraPermissionCallback(invoke: Invoke) {
|
||||||
@@ -380,9 +368,7 @@ class BarcodeScannerPlugin(private val activity: Activity) : Plugin(activity),
|
|||||||
requestPermissionResponse.put(PERMISSION_ALIAS_CAMERA, PermissionState.GRANTED)
|
requestPermissionResponse.put(PERMISSION_ALIAS_CAMERA, PermissionState.GRANTED)
|
||||||
} else {
|
} else {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
if (!activity.shouldShowRequestPermissionRationale(PERMISSION_NAME)) {
|
requestPermissionResponse.put(PERMISSION_ALIAS_CAMERA, PermissionState.DENIED)
|
||||||
requestPermissionResponse.put(PERMISSION_ALIAS_CAMERA, PermissionState.DENIED)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
requestPermissionResponse.put(PERMISSION_ALIAS_CAMERA, PermissionState.GRANTED)
|
requestPermissionResponse.put(PERMISSION_ALIAS_CAMERA, PermissionState.GRANTED)
|
||||||
}
|
}
|
||||||
@@ -401,20 +387,12 @@ class BarcodeScannerPlugin(private val activity: Activity) : Plugin(activity),
|
|||||||
requestPermissionResponse.put(PERMISSION_ALIAS_CAMERA, PermissionState.GRANTED)
|
requestPermissionResponse.put(PERMISSION_ALIAS_CAMERA, PermissionState.GRANTED)
|
||||||
} else {
|
} else {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
if (firstPermissionRequest() || activity.shouldShowRequestPermissionRationale(
|
requestPermissionForAlias(
|
||||||
PERMISSION_NAME
|
PERMISSION_ALIAS_CAMERA,
|
||||||
)
|
invoke,
|
||||||
) {
|
"cameraPermissionCallback"
|
||||||
markFirstPermissionRequest()
|
)
|
||||||
requestPermissionForAlias(
|
return
|
||||||
PERMISSION_ALIAS_CAMERA,
|
|
||||||
invoke,
|
|
||||||
"cameraPermissionCallback"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
requestPermissionResponse.put(PERMISSION_ALIAS_CAMERA, PermissionState.DENIED)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
requestPermissionResponse.put(PERMISSION_ALIAS_CAMERA, PermissionState.GRANTED)
|
requestPermissionResponse.put(PERMISSION_ALIAS_CAMERA, PermissionState.GRANTED)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
if("__TAURI__"in window){var __TAURI_PLUGIN_BARCODE_SCANNER__=function(n){"use strict";async function a(n,a={},e){return window.__TAURI_INTERNALS__.invoke(n,a,e)}var e;return"function"==typeof SuppressedError&&SuppressedError,n.Format=void 0,(e=n.Format||(n.Format={})).QRCode="QR_CODE",e.UPC_A="UPC_A",e.UPC_E="UPC_E",e.EAN8="EAN_8",e.EAN13="EAN_13",e.Code39="CODE_39",e.Code93="CODE_93",e.Code128="CODE_128",e.Codabar="CODABAR",e.ITF="ITF",e.Aztec="AZTEC",e.DataMatrix="DATA_MATRIX",e.PDF417="PDF_417",e.GS1DataBar="GS1_DATA_BAR",e.GS1DataBarLimited="GS1_DATA_BAR_LIMITED",e.GS1DataBarExpanded="GS1_DATA_BAR_EXPANDED",n.cancel=async function(){await a("plugin:barcode-scanner|cancel")},n.checkPermissions=async function(){return await async function(n){return a(`plugin:${n}|check_permissions`)}("barcode-scanner").then((n=>n.camera))},n.openAppSettings=async function(){await a("plugin:barcode-scanner|open_app_settings")},n.requestPermissions=async function(){return await async function(n){return a(`plugin:${n}|request_permissions`)}("barcode-scanner").then((n=>n.camera))},n.scan=async function(n){return await a("plugin:barcode-scanner|scan",{...n})},n}({});Object.defineProperty(window.__TAURI__,"barcodeScanner",{value:__TAURI_PLUGIN_BARCODE_SCANNER__})}
|
if("__TAURI__"in window){var __TAURI_PLUGIN_BARCODE_SCANNER__=function(n){"use strict";async function a(n,a={},e){return window.__TAURI_INTERNALS__.invoke(n,a,e)}var e;return"function"==typeof SuppressedError&&SuppressedError,n.Format=void 0,(e=n.Format||(n.Format={})).QRCode="QR_CODE",e.UPC_A="UPC_A",e.UPC_E="UPC_E",e.EAN8="EAN_8",e.EAN13="EAN_13",e.Code39="CODE_39",e.Code93="CODE_93",e.Code128="CODE_128",e.Codabar="CODABAR",e.ITF="ITF",e.Aztec="AZTEC",e.DataMatrix="DATA_MATRIX",e.PDF417="PDF_417",e.GS1DataBar="GS1_DATA_BAR",e.GS1DataBarLimited="GS1_DATA_BAR_LIMITED",e.GS1DataBarExpanded="GS1_DATA_BAR_EXPANDED",n.cancel=async function(){await a("plugin:barcode-scanner|cancel")},n.checkPermissions=async function(){return await async function(n){return a(`plugin:${n}|check_permissions`)}("barcode-scanner").then(n=>n.camera)},n.openAppSettings=async function(){await a("plugin:barcode-scanner|open_app_settings")},n.requestPermissions=async function(){return await async function(n){return a(`plugin:${n}|request_permissions`)}("barcode-scanner").then(n=>n.camera)},n.scan=async function(n){return await a("plugin:barcode-scanner|scan",{...n})},n}({});Object.defineProperty(window.__TAURI__,"barcodeScanner",{value:__TAURI_PLUGIN_BARCODE_SCANNER__})}
|
||||||
|
|||||||
@@ -191,6 +191,7 @@ class BarcodeScannerPlugin: Plugin, AVCaptureMetadataOutputObjectsDelegate {
|
|||||||
if self.captureSession != nil {
|
if self.captureSession != nil {
|
||||||
self.captureSession!.stopRunning()
|
self.captureSession!.stopRunning()
|
||||||
self.cameraView.removePreviewLayer()
|
self.cameraView.removePreviewLayer()
|
||||||
|
self.cameraView.removeFromSuperview()
|
||||||
self.captureVideoPreviewLayer = nil
|
self.captureVideoPreviewLayer = nil
|
||||||
self.metaOutput = nil
|
self.metaOutput = nil
|
||||||
self.captureSession = nil
|
self.captureSession = nil
|
||||||
@@ -260,27 +261,34 @@ class BarcodeScannerPlugin: Plugin, AVCaptureMetadataOutputObjectsDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func runScanner(_ invoke: Invoke, args: ScanOptions) {
|
private func runScanner(_ invoke: Invoke, args: ScanOptions) {
|
||||||
|
if getPermissionState() != "granted" {
|
||||||
|
invoke.reject("Camera permission denied or not yet requested")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
scanFormats = [AVMetadataObject.ObjectType]()
|
scanFormats = [AVMetadataObject.ObjectType]()
|
||||||
|
|
||||||
(args.formats ?? []).forEach { format in
|
(args.formats ?? []).forEach { format in
|
||||||
if let formatValue = format.value {
|
if let formatValue = format.value {
|
||||||
scanFormats.append(formatValue)
|
scanFormats.append(formatValue)
|
||||||
} else {
|
} else {
|
||||||
invoke.reject("Unsupported barcode format on this iOS version: \(format)")
|
invoke.reject("Unsupported barcode format on this iOS version: \(format)")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if scanFormats.isEmpty {
|
if scanFormats.isEmpty {
|
||||||
for supportedFormat in SupportedFormat.allCases {
|
for supportedFormat in SupportedFormat.allCases {
|
||||||
if let formatValue = supportedFormat.value {
|
if let formatValue = supportedFormat.value {
|
||||||
scanFormats.append(formatValue)
|
scanFormats.append(formatValue)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.metaOutput!.metadataObjectTypes = self.scanFormats
|
self.metaOutput!.metadataObjectTypes = self.scanFormats
|
||||||
self.captureSession!.startRunning()
|
DispatchQueue.main.async {
|
||||||
|
self.captureSession!.startRunning()
|
||||||
|
}
|
||||||
|
|
||||||
self.isScanning = true
|
self.isScanning = true
|
||||||
}
|
}
|
||||||
@@ -297,6 +305,13 @@ class BarcodeScannerPlugin: Plugin, AVCaptureMetadataOutputObjectsDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if camera is available on this platform (iOS simulator doesn't have cameras)
|
||||||
|
let availableVideoDevices = discoverCaptureDevices()
|
||||||
|
if availableVideoDevices.isEmpty {
|
||||||
|
invoke.reject("No camera available on this device (e.g., iOS Simulator)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var iOS14min: Bool = false
|
var iOS14min: Bool = false
|
||||||
if #available(iOS 14.0, *) { iOS14min = true }
|
if #available(iOS 14.0, *) { iOS14min = true }
|
||||||
if !iOS14min && self.getPermissionState() != "granted" {
|
if !iOS14min && self.getPermissionState() != "granted" {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@tauri-apps/plugin-barcode-scanner",
|
"name": "@tauri-apps/plugin-barcode-scanner",
|
||||||
"version": "2.4.2",
|
"version": "2.4.4",
|
||||||
"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.8.0"
|
"@tauri-apps/api": "^2.11.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-cancel"
|
|
||||||
description = "Enables the cancel command without any pre-configured scope."
|
|
||||||
commands.allow = ["cancel"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-cancel"
|
|
||||||
description = "Denies the cancel command without any pre-configured scope."
|
|
||||||
commands.deny = ["cancel"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-check-permissions"
|
|
||||||
description = "Enables the check_permissions command without any pre-configured scope."
|
|
||||||
commands.allow = ["check_permissions"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-check-permissions"
|
|
||||||
description = "Denies the check_permissions command without any pre-configured scope."
|
|
||||||
commands.deny = ["check_permissions"]
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Automatically generated - DO NOT EDIT!
|
||||||
|
|
||||||
|
"$schema" = "../../schemas/schema.json"
|
||||||
|
|
||||||
|
commands = ["scan","cancel","request_permissions","check_permissions","open_app_settings","vibrate"]
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-open-app-settings"
|
|
||||||
description = "Enables the open_app_settings command without any pre-configured scope."
|
|
||||||
commands.allow = ["open_app_settings"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-open-app-settings"
|
|
||||||
description = "Denies the open_app_settings command without any pre-configured scope."
|
|
||||||
commands.deny = ["open_app_settings"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-request-permissions"
|
|
||||||
description = "Enables the request_permissions command without any pre-configured scope."
|
|
||||||
commands.allow = ["request_permissions"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-request-permissions"
|
|
||||||
description = "Denies the request_permissions command without any pre-configured scope."
|
|
||||||
commands.deny = ["request_permissions"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-scan"
|
|
||||||
description = "Enables the scan command without any pre-configured scope."
|
|
||||||
commands.allow = ["scan"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-scan"
|
|
||||||
description = "Denies the scan command without any pre-configured scope."
|
|
||||||
commands.deny = ["scan"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-vibrate"
|
|
||||||
description = "Enables the vibrate command without any pre-configured scope."
|
|
||||||
commands.allow = ["vibrate"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-vibrate"
|
|
||||||
description = "Denies the vibrate command without any pre-configured scope."
|
|
||||||
commands.deny = ["vibrate"]
|
|
||||||
@@ -24,10 +24,17 @@
|
|||||||
},
|
},
|
||||||
"permission": {
|
"permission": {
|
||||||
"description": "A list of inlined permissions",
|
"description": "A list of inlined permissions",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/Permission"
|
"$ref": "#/definitions/Permission"
|
||||||
|
},
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"description": "A list of command names that get `allow-$command` and `deny-$command` permissions\nautogenerated on demand instead of being stored as explicit permissions.\n\nSee [`Manifest::command_permission`] and the ACL resolver for how these are expanded.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -35,9 +42,6 @@
|
|||||||
"DefaultPermission": {
|
"DefaultPermission": {
|
||||||
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"description": "The version of the permission.",
|
"description": "The version of the permission.",
|
||||||
@@ -46,10 +50,10 @@
|
|||||||
"null"
|
"null"
|
||||||
],
|
],
|
||||||
"format": "uint64",
|
"format": "uint64",
|
||||||
"minimum": 1.0
|
"minimum": 1
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
|
"description": "Human-readable description of what the permission does.\nTauri convention is to use `<h4>` headings in markdown content\nfor Tauri documentation generation purposes.",
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
"null"
|
"null"
|
||||||
@@ -62,16 +66,14 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"permissions"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"PermissionSet": {
|
"PermissionSet": {
|
||||||
"description": "A set of direct permissions grouped together under a new name.",
|
"description": "A set of direct permissions grouped together under a new name.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"description",
|
|
||||||
"identifier",
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"description": "A unique identifier for the permission.",
|
"description": "A unique identifier for the permission.",
|
||||||
@@ -85,17 +87,19 @@
|
|||||||
"description": "All permissions this set contains.",
|
"description": "All permissions this set contains.",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/PermissionKind"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"identifier",
|
||||||
|
"description",
|
||||||
|
"permissions"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"Permission": {
|
"Permission": {
|
||||||
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"identifier"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"description": "The version of the permission.",
|
"description": "The version of the permission.",
|
||||||
@@ -104,14 +108,14 @@
|
|||||||
"null"
|
"null"
|
||||||
],
|
],
|
||||||
"format": "uint64",
|
"format": "uint64",
|
||||||
"minimum": 1.0
|
"minimum": 1
|
||||||
},
|
},
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"description": "A unique identifier for the permission.",
|
"description": "A unique identifier for the permission.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
|
"description": "Human-readable description of what the permission does.\nTauri internal convention is to use `<h4>` headings in markdown content\nfor Tauri documentation generation purposes.",
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
"null"
|
"null"
|
||||||
@@ -147,7 +151,10 @@
|
|||||||
"$ref": "#/definitions/Target"
|
"$ref": "#/definitions/Target"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"identifier"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"Commands": {
|
"Commands": {
|
||||||
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
||||||
@@ -155,24 +162,24 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"allow": {
|
"allow": {
|
||||||
"description": "Allowed command.",
|
"description": "Allowed command.",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"default": []
|
||||||
},
|
},
|
||||||
"deny": {
|
"deny": {
|
||||||
"description": "Denied command, which takes priority.",
|
"description": "Denied command, which takes priority.",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"default": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Scopes": {
|
"Scopes": {
|
||||||
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command. The configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json { \"allow\": [{ \"path\": \"$HOME/**\" }], \"deny\": [{ \"path\": \"$HOME/secret.txt\" }] } ```",
|
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command.\nThe configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json\n{\n \"allow\": [{ \"path\": \"$HOME/**\" }],\n \"deny\": [{ \"path\": \"$HOME/secret.txt\" }]\n}\n```",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"allow": {
|
"allow": {
|
||||||
@@ -257,120 +264,27 @@
|
|||||||
{
|
{
|
||||||
"description": "MacOS.",
|
"description": "MacOS.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "macOS"
|
||||||
"macOS"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Windows.",
|
"description": "Windows.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "windows"
|
||||||
"windows"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Linux.",
|
"description": "Linux.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "linux"
|
||||||
"linux"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Android.",
|
"description": "Android.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "android"
|
||||||
"android"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "iOS.",
|
"description": "iOS.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "iOS"
|
||||||
"iOS"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"PermissionKind": {
|
|
||||||
"type": "string",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"description": "Enables the cancel command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-cancel",
|
|
||||||
"markdownDescription": "Enables the cancel command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the cancel command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-cancel",
|
|
||||||
"markdownDescription": "Denies the cancel command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the check_permissions command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-check-permissions",
|
|
||||||
"markdownDescription": "Enables the check_permissions command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the check_permissions command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-check-permissions",
|
|
||||||
"markdownDescription": "Denies the check_permissions command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the open_app_settings command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-open-app-settings",
|
|
||||||
"markdownDescription": "Enables the open_app_settings command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the open_app_settings command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-open-app-settings",
|
|
||||||
"markdownDescription": "Denies the open_app_settings command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the request_permissions command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-request-permissions",
|
|
||||||
"markdownDescription": "Enables the request_permissions command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the request_permissions command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-request-permissions",
|
|
||||||
"markdownDescription": "Denies the request_permissions command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the scan command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-scan",
|
|
||||||
"markdownDescription": "Enables the scan command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the scan command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-scan",
|
|
||||||
"markdownDescription": "Denies the scan command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the vibrate command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-vibrate",
|
|
||||||
"markdownDescription": "Enables the vibrate command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the vibrate command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-vibrate",
|
|
||||||
"markdownDescription": "Denies the vibrate command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "This permission set configures which\nbarcode scanning features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all barcode related features.\n\n\n#### This default permission set includes:\n\n- `allow-cancel`\n- `allow-check-permissions`\n- `allow-open-app-settings`\n- `allow-request-permissions`\n- `allow-scan`\n- `allow-vibrate`",
|
|
||||||
"type": "string",
|
|
||||||
"const": "default",
|
|
||||||
"markdownDescription": "This permission set configures which\nbarcode scanning features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all barcode related features.\n\n\n#### This default permission set includes:\n\n- `allow-cancel`\n- `allow-check-permissions`\n- `allow-open-app-settings`\n- `allow-request-permissions`\n- `allow-scan`\n- `allow-vibrate`"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.base.json",
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "guest-js"
|
||||||
|
},
|
||||||
"include": ["guest-js/*.ts"]
|
"include": ["guest-js/*.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,6 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^2.8.0"
|
"@tauri-apps/api": "^2.11.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-authenticate"
|
|
||||||
description = "Enables the authenticate command without any pre-configured scope."
|
|
||||||
commands.allow = ["authenticate"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-authenticate"
|
|
||||||
description = "Denies the authenticate command without any pre-configured scope."
|
|
||||||
commands.deny = ["authenticate"]
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Automatically generated - DO NOT EDIT!
|
||||||
|
|
||||||
|
"$schema" = "../../schemas/schema.json"
|
||||||
|
|
||||||
|
commands = ["authenticate","status"]
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-status"
|
|
||||||
description = "Enables the status command without any pre-configured scope."
|
|
||||||
commands.allow = ["status"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-status"
|
|
||||||
description = "Denies the status command without any pre-configured scope."
|
|
||||||
commands.deny = ["status"]
|
|
||||||
@@ -24,10 +24,17 @@
|
|||||||
},
|
},
|
||||||
"permission": {
|
"permission": {
|
||||||
"description": "A list of inlined permissions",
|
"description": "A list of inlined permissions",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/Permission"
|
"$ref": "#/definitions/Permission"
|
||||||
|
},
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"description": "A list of command names that get `allow-$command` and `deny-$command` permissions\nautogenerated on demand instead of being stored as explicit permissions.\n\nSee [`Manifest::command_permission`] and the ACL resolver for how these are expanded.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -35,9 +42,6 @@
|
|||||||
"DefaultPermission": {
|
"DefaultPermission": {
|
||||||
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"description": "The version of the permission.",
|
"description": "The version of the permission.",
|
||||||
@@ -46,10 +50,10 @@
|
|||||||
"null"
|
"null"
|
||||||
],
|
],
|
||||||
"format": "uint64",
|
"format": "uint64",
|
||||||
"minimum": 1.0
|
"minimum": 1
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
|
"description": "Human-readable description of what the permission does.\nTauri convention is to use `<h4>` headings in markdown content\nfor Tauri documentation generation purposes.",
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
"null"
|
"null"
|
||||||
@@ -62,16 +66,14 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"permissions"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"PermissionSet": {
|
"PermissionSet": {
|
||||||
"description": "A set of direct permissions grouped together under a new name.",
|
"description": "A set of direct permissions grouped together under a new name.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"description",
|
|
||||||
"identifier",
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"description": "A unique identifier for the permission.",
|
"description": "A unique identifier for the permission.",
|
||||||
@@ -85,17 +87,19 @@
|
|||||||
"description": "All permissions this set contains.",
|
"description": "All permissions this set contains.",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/PermissionKind"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"identifier",
|
||||||
|
"description",
|
||||||
|
"permissions"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"Permission": {
|
"Permission": {
|
||||||
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"identifier"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"description": "The version of the permission.",
|
"description": "The version of the permission.",
|
||||||
@@ -104,14 +108,14 @@
|
|||||||
"null"
|
"null"
|
||||||
],
|
],
|
||||||
"format": "uint64",
|
"format": "uint64",
|
||||||
"minimum": 1.0
|
"minimum": 1
|
||||||
},
|
},
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"description": "A unique identifier for the permission.",
|
"description": "A unique identifier for the permission.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
|
"description": "Human-readable description of what the permission does.\nTauri internal convention is to use `<h4>` headings in markdown content\nfor Tauri documentation generation purposes.",
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
"null"
|
"null"
|
||||||
@@ -147,7 +151,10 @@
|
|||||||
"$ref": "#/definitions/Target"
|
"$ref": "#/definitions/Target"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"identifier"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"Commands": {
|
"Commands": {
|
||||||
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
||||||
@@ -155,24 +162,24 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"allow": {
|
"allow": {
|
||||||
"description": "Allowed command.",
|
"description": "Allowed command.",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"default": []
|
||||||
},
|
},
|
||||||
"deny": {
|
"deny": {
|
||||||
"description": "Denied command, which takes priority.",
|
"description": "Denied command, which takes priority.",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"default": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Scopes": {
|
"Scopes": {
|
||||||
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command. The configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json { \"allow\": [{ \"path\": \"$HOME/**\" }], \"deny\": [{ \"path\": \"$HOME/secret.txt\" }] } ```",
|
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command.\nThe configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json\n{\n \"allow\": [{ \"path\": \"$HOME/**\" }],\n \"deny\": [{ \"path\": \"$HOME/secret.txt\" }]\n}\n```",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"allow": {
|
"allow": {
|
||||||
@@ -257,72 +264,27 @@
|
|||||||
{
|
{
|
||||||
"description": "MacOS.",
|
"description": "MacOS.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "macOS"
|
||||||
"macOS"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Windows.",
|
"description": "Windows.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "windows"
|
||||||
"windows"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Linux.",
|
"description": "Linux.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "linux"
|
||||||
"linux"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Android.",
|
"description": "Android.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "android"
|
||||||
"android"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "iOS.",
|
"description": "iOS.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "iOS"
|
||||||
"iOS"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"PermissionKind": {
|
|
||||||
"type": "string",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"description": "Enables the authenticate command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-authenticate",
|
|
||||||
"markdownDescription": "Enables the authenticate command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the authenticate command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-authenticate",
|
|
||||||
"markdownDescription": "Denies the authenticate command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the status command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-status",
|
|
||||||
"markdownDescription": "Enables the status command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the status command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-status",
|
|
||||||
"markdownDescription": "Denies the status command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "This permission set configures which\nbiometric features are by default exposed.\n\n#### Granted Permissions\n\nIt allows acccess to all biometric commands.\n\n\n#### This default permission set includes:\n\n- `allow-authenticate`\n- `allow-status`",
|
|
||||||
"type": "string",
|
|
||||||
"const": "default",
|
|
||||||
"markdownDescription": "This permission set configures which\nbiometric features are by default exposed.\n\n#### Granted Permissions\n\nIt allows acccess to all biometric commands.\n\n\n#### This default permission set includes:\n\n- `allow-authenticate`\n- `allow-status`"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.base.json",
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "guest-js"
|
||||||
|
},
|
||||||
"include": ["guest-js/*.ts"]
|
"include": ["guest-js/*.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,6 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^2.8.0"
|
"@tauri-apps/api": "^2.11.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-cli-matches"
|
|
||||||
description = "Enables the cli_matches command without any pre-configured scope."
|
|
||||||
commands.allow = ["cli_matches"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-cli-matches"
|
|
||||||
description = "Denies the cli_matches command without any pre-configured scope."
|
|
||||||
commands.deny = ["cli_matches"]
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Automatically generated - DO NOT EDIT!
|
||||||
|
|
||||||
|
"$schema" = "../../schemas/schema.json"
|
||||||
|
|
||||||
|
commands = ["cli_matches"]
|
||||||
@@ -24,10 +24,17 @@
|
|||||||
},
|
},
|
||||||
"permission": {
|
"permission": {
|
||||||
"description": "A list of inlined permissions",
|
"description": "A list of inlined permissions",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/Permission"
|
"$ref": "#/definitions/Permission"
|
||||||
|
},
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"description": "A list of command names that get `allow-$command` and `deny-$command` permissions\nautogenerated on demand instead of being stored as explicit permissions.\n\nSee [`Manifest::command_permission`] and the ACL resolver for how these are expanded.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -35,9 +42,6 @@
|
|||||||
"DefaultPermission": {
|
"DefaultPermission": {
|
||||||
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"description": "The version of the permission.",
|
"description": "The version of the permission.",
|
||||||
@@ -46,10 +50,10 @@
|
|||||||
"null"
|
"null"
|
||||||
],
|
],
|
||||||
"format": "uint64",
|
"format": "uint64",
|
||||||
"minimum": 1.0
|
"minimum": 1
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
|
"description": "Human-readable description of what the permission does.\nTauri convention is to use `<h4>` headings in markdown content\nfor Tauri documentation generation purposes.",
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
"null"
|
"null"
|
||||||
@@ -62,16 +66,14 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"permissions"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"PermissionSet": {
|
"PermissionSet": {
|
||||||
"description": "A set of direct permissions grouped together under a new name.",
|
"description": "A set of direct permissions grouped together under a new name.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"description",
|
|
||||||
"identifier",
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"description": "A unique identifier for the permission.",
|
"description": "A unique identifier for the permission.",
|
||||||
@@ -85,17 +87,19 @@
|
|||||||
"description": "All permissions this set contains.",
|
"description": "All permissions this set contains.",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/PermissionKind"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"identifier",
|
||||||
|
"description",
|
||||||
|
"permissions"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"Permission": {
|
"Permission": {
|
||||||
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"identifier"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"description": "The version of the permission.",
|
"description": "The version of the permission.",
|
||||||
@@ -104,14 +108,14 @@
|
|||||||
"null"
|
"null"
|
||||||
],
|
],
|
||||||
"format": "uint64",
|
"format": "uint64",
|
||||||
"minimum": 1.0
|
"minimum": 1
|
||||||
},
|
},
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"description": "A unique identifier for the permission.",
|
"description": "A unique identifier for the permission.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
|
"description": "Human-readable description of what the permission does.\nTauri internal convention is to use `<h4>` headings in markdown content\nfor Tauri documentation generation purposes.",
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
"null"
|
"null"
|
||||||
@@ -147,7 +151,10 @@
|
|||||||
"$ref": "#/definitions/Target"
|
"$ref": "#/definitions/Target"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"identifier"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"Commands": {
|
"Commands": {
|
||||||
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
||||||
@@ -155,24 +162,24 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"allow": {
|
"allow": {
|
||||||
"description": "Allowed command.",
|
"description": "Allowed command.",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"default": []
|
||||||
},
|
},
|
||||||
"deny": {
|
"deny": {
|
||||||
"description": "Denied command, which takes priority.",
|
"description": "Denied command, which takes priority.",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"default": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Scopes": {
|
"Scopes": {
|
||||||
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command. The configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json { \"allow\": [{ \"path\": \"$HOME/**\" }], \"deny\": [{ \"path\": \"$HOME/secret.txt\" }] } ```",
|
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command.\nThe configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json\n{\n \"allow\": [{ \"path\": \"$HOME/**\" }],\n \"deny\": [{ \"path\": \"$HOME/secret.txt\" }]\n}\n```",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"allow": {
|
"allow": {
|
||||||
@@ -257,60 +264,27 @@
|
|||||||
{
|
{
|
||||||
"description": "MacOS.",
|
"description": "MacOS.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "macOS"
|
||||||
"macOS"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Windows.",
|
"description": "Windows.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "windows"
|
||||||
"windows"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Linux.",
|
"description": "Linux.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "linux"
|
||||||
"linux"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Android.",
|
"description": "Android.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "android"
|
||||||
"android"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "iOS.",
|
"description": "iOS.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "iOS"
|
||||||
"iOS"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"PermissionKind": {
|
|
||||||
"type": "string",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"description": "Enables the cli_matches command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-cli-matches",
|
|
||||||
"markdownDescription": "Enables the cli_matches command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the cli_matches command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-cli-matches",
|
|
||||||
"markdownDescription": "Denies the cli_matches command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Allows reading the CLI matches\n#### This default permission set includes:\n\n- `allow-cli-matches`",
|
|
||||||
"type": "string",
|
|
||||||
"const": "default",
|
|
||||||
"markdownDescription": "Allows reading the CLI matches\n#### This default permission set includes:\n\n- `allow-cli-matches`"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.base.json",
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "guest-js"
|
||||||
|
},
|
||||||
"include": ["guest-js/*.ts"]
|
"include": ["guest-js/*.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
if("__TAURI__"in window){var __TAURI_PLUGIN_CLIPBOARD_MANAGER__=function(e){"use strict";var n;async function t(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}"function"==typeof SuppressedError&&SuppressedError;class r{get rid(){return function(e,n,t,r){if("function"==typeof n?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__})}
|
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__})}
|
||||||
|
|||||||
@@ -24,6 +24,6 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^2.8.0"
|
"@tauri-apps/api": "^2.11.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-clear"
|
|
||||||
description = "Enables the clear command without any pre-configured scope."
|
|
||||||
commands.allow = ["clear"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-clear"
|
|
||||||
description = "Denies the clear command without any pre-configured scope."
|
|
||||||
commands.deny = ["clear"]
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Automatically generated - DO NOT EDIT!
|
||||||
|
|
||||||
|
"$schema" = "../../schemas/schema.json"
|
||||||
|
|
||||||
|
commands = ["write_text","read_text","write_image","read_image","write_html","clear"]
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-read-image"
|
|
||||||
description = "Enables the read_image command without any pre-configured scope."
|
|
||||||
commands.allow = ["read_image"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-read-image"
|
|
||||||
description = "Denies the read_image command without any pre-configured scope."
|
|
||||||
commands.deny = ["read_image"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-read-text"
|
|
||||||
description = "Enables the read_text command without any pre-configured scope."
|
|
||||||
commands.allow = ["read_text"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-read-text"
|
|
||||||
description = "Denies the read_text command without any pre-configured scope."
|
|
||||||
commands.deny = ["read_text"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-write-html"
|
|
||||||
description = "Enables the write_html command without any pre-configured scope."
|
|
||||||
commands.allow = ["write_html"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-write-html"
|
|
||||||
description = "Denies the write_html command without any pre-configured scope."
|
|
||||||
commands.deny = ["write_html"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-write-image"
|
|
||||||
description = "Enables the write_image command without any pre-configured scope."
|
|
||||||
commands.allow = ["write_image"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-write-image"
|
|
||||||
description = "Denies the write_image command without any pre-configured scope."
|
|
||||||
commands.deny = ["write_image"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-write-text"
|
|
||||||
description = "Enables the write_text command without any pre-configured scope."
|
|
||||||
commands.allow = ["write_text"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-write-text"
|
|
||||||
description = "Denies the write_text command without any pre-configured scope."
|
|
||||||
commands.deny = ["write_text"]
|
|
||||||
@@ -24,10 +24,17 @@
|
|||||||
},
|
},
|
||||||
"permission": {
|
"permission": {
|
||||||
"description": "A list of inlined permissions",
|
"description": "A list of inlined permissions",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/Permission"
|
"$ref": "#/definitions/Permission"
|
||||||
|
},
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"description": "A list of command names that get `allow-$command` and `deny-$command` permissions\nautogenerated on demand instead of being stored as explicit permissions.\n\nSee [`Manifest::command_permission`] and the ACL resolver for how these are expanded.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -35,9 +42,6 @@
|
|||||||
"DefaultPermission": {
|
"DefaultPermission": {
|
||||||
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"description": "The version of the permission.",
|
"description": "The version of the permission.",
|
||||||
@@ -46,10 +50,10 @@
|
|||||||
"null"
|
"null"
|
||||||
],
|
],
|
||||||
"format": "uint64",
|
"format": "uint64",
|
||||||
"minimum": 1.0
|
"minimum": 1
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
|
"description": "Human-readable description of what the permission does.\nTauri convention is to use `<h4>` headings in markdown content\nfor Tauri documentation generation purposes.",
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
"null"
|
"null"
|
||||||
@@ -62,16 +66,14 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"permissions"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"PermissionSet": {
|
"PermissionSet": {
|
||||||
"description": "A set of direct permissions grouped together under a new name.",
|
"description": "A set of direct permissions grouped together under a new name.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"description",
|
|
||||||
"identifier",
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"description": "A unique identifier for the permission.",
|
"description": "A unique identifier for the permission.",
|
||||||
@@ -85,17 +87,19 @@
|
|||||||
"description": "All permissions this set contains.",
|
"description": "All permissions this set contains.",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/PermissionKind"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"identifier",
|
||||||
|
"description",
|
||||||
|
"permissions"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"Permission": {
|
"Permission": {
|
||||||
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"identifier"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"description": "The version of the permission.",
|
"description": "The version of the permission.",
|
||||||
@@ -104,14 +108,14 @@
|
|||||||
"null"
|
"null"
|
||||||
],
|
],
|
||||||
"format": "uint64",
|
"format": "uint64",
|
||||||
"minimum": 1.0
|
"minimum": 1
|
||||||
},
|
},
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"description": "A unique identifier for the permission.",
|
"description": "A unique identifier for the permission.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
|
"description": "Human-readable description of what the permission does.\nTauri internal convention is to use `<h4>` headings in markdown content\nfor Tauri documentation generation purposes.",
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
"null"
|
"null"
|
||||||
@@ -147,7 +151,10 @@
|
|||||||
"$ref": "#/definitions/Target"
|
"$ref": "#/definitions/Target"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"identifier"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"Commands": {
|
"Commands": {
|
||||||
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
||||||
@@ -155,24 +162,24 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"allow": {
|
"allow": {
|
||||||
"description": "Allowed command.",
|
"description": "Allowed command.",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"default": []
|
||||||
},
|
},
|
||||||
"deny": {
|
"deny": {
|
||||||
"description": "Denied command, which takes priority.",
|
"description": "Denied command, which takes priority.",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"default": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Scopes": {
|
"Scopes": {
|
||||||
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command. The configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json { \"allow\": [{ \"path\": \"$HOME/**\" }], \"deny\": [{ \"path\": \"$HOME/secret.txt\" }] } ```",
|
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command.\nThe configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json\n{\n \"allow\": [{ \"path\": \"$HOME/**\" }],\n \"deny\": [{ \"path\": \"$HOME/secret.txt\" }]\n}\n```",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"allow": {
|
"allow": {
|
||||||
@@ -257,120 +264,27 @@
|
|||||||
{
|
{
|
||||||
"description": "MacOS.",
|
"description": "MacOS.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "macOS"
|
||||||
"macOS"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Windows.",
|
"description": "Windows.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "windows"
|
||||||
"windows"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Linux.",
|
"description": "Linux.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "linux"
|
||||||
"linux"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Android.",
|
"description": "Android.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "android"
|
||||||
"android"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "iOS.",
|
"description": "iOS.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "iOS"
|
||||||
"iOS"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"PermissionKind": {
|
|
||||||
"type": "string",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"description": "Enables the clear command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-clear",
|
|
||||||
"markdownDescription": "Enables the clear command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the clear command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-clear",
|
|
||||||
"markdownDescription": "Denies the clear command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the read_image command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-read-image",
|
|
||||||
"markdownDescription": "Enables the read_image command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the read_image command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-read-image",
|
|
||||||
"markdownDescription": "Denies the read_image command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the read_text command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-read-text",
|
|
||||||
"markdownDescription": "Enables the read_text command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the read_text command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-read-text",
|
|
||||||
"markdownDescription": "Denies the read_text command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the write_html command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-write-html",
|
|
||||||
"markdownDescription": "Enables the write_html command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the write_html command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-write-html",
|
|
||||||
"markdownDescription": "Denies the write_html command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the write_image command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-write-image",
|
|
||||||
"markdownDescription": "Enables the write_image command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the write_image command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-write-image",
|
|
||||||
"markdownDescription": "Denies the write_image command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the write_text command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-write-text",
|
|
||||||
"markdownDescription": "Enables the write_text command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the write_text command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-write-text",
|
|
||||||
"markdownDescription": "Denies the write_text command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n",
|
|
||||||
"type": "string",
|
|
||||||
"const": "default",
|
|
||||||
"markdownDescription": "No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.base.json",
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "guest-js"
|
||||||
|
},
|
||||||
"include": ["guest-js/*.ts"]
|
"include": ["guest-js/*.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,22 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## \[2.4.9]
|
||||||
|
|
||||||
|
- [`e6cdc9f5`](https://github.com/tauri-apps/plugins-workspace/commit/e6cdc9f52e2cd975b11b8e4c12879d597f1f76c3) ([#3396](https://github.com/tauri-apps/plugins-workspace/pull/3396) by [@Legend-Master](https://github.com/tauri-apps/plugins-workspace/../../Legend-Master)) Fix broken iOS custom URL schemes
|
||||||
|
|
||||||
|
## \[2.4.8]
|
||||||
|
|
||||||
|
- [`024ec0c2`](https://github.com/tauri-apps/plugins-workspace/commit/024ec0c29c20cf94579dab9b79d6be0da61a8daa) ([#3214](https://github.com/tauri-apps/plugins-workspace/pull/3214) by [@joshIsCoding](https://github.com/tauri-apps/plugins-workspace/../../joshIsCoding)) Account for differing Android VIEW intent in ChromeOS, fixing deep-link behaviour on Chromium platforms.
|
||||||
|
- [`015e817c`](https://github.com/tauri-apps/plugins-workspace/commit/015e817cf2d7f66c1b9268606af8318dfe0bc4ee) ([#3186](https://github.com/tauri-apps/plugins-workspace/pull/3186) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Validate Android new intent is actually a deep link before triggering the onOpenUrl event.
|
||||||
|
|
||||||
|
## \[2.4.7]
|
||||||
|
|
||||||
|
- [`8374e997`](https://github.com/tauri-apps/plugins-workspace/commit/8374e997b82c95516fc0c1f6d665d9fc3b52edf8) ([#3258](https://github.com/tauri-apps/plugins-workspace/pull/3258) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Fix runtime deep link registration failing on Linux when the app path has spaces.
|
||||||
|
|
||||||
|
## \[2.4.6]
|
||||||
|
|
||||||
|
- [`28048039`](https://github.com/tauri-apps/plugins-workspace/commit/28048039496e84b46847c008416d341f1349e30e) ([#3143](https://github.com/tauri-apps/plugins-workspace/pull/3143) by [@Tunglies](https://github.com/tauri-apps/plugins-workspace/../../Tunglies)) Fix clippy warnings. No user facing changes.
|
||||||
|
|
||||||
## \[2.4.5]
|
## \[2.4.5]
|
||||||
|
|
||||||
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
|
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tauri-plugin-deep-link"
|
name = "tauri-plugin-deep-link"
|
||||||
version = "2.4.5"
|
version = "2.4.9"
|
||||||
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 }
|
||||||
|
|||||||
@@ -6,9 +6,8 @@ package app.tauri.deep_link
|
|||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.PatternMatcher
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import app.tauri.Logger
|
|
||||||
import app.tauri.annotation.InvokeArg
|
import app.tauri.annotation.InvokeArg
|
||||||
import app.tauri.annotation.Command
|
import app.tauri.annotation.Command
|
||||||
import app.tauri.annotation.TauriPlugin
|
import app.tauri.annotation.TauriPlugin
|
||||||
@@ -16,23 +15,43 @@ import app.tauri.plugin.Channel
|
|||||||
import app.tauri.plugin.JSObject
|
import app.tauri.plugin.JSObject
|
||||||
import app.tauri.plugin.Plugin
|
import app.tauri.plugin.Plugin
|
||||||
import app.tauri.plugin.Invoke
|
import app.tauri.plugin.Invoke
|
||||||
|
import androidx.core.net.toUri
|
||||||
|
|
||||||
@InvokeArg
|
@InvokeArg
|
||||||
class SetEventHandlerArgs {
|
class SetEventHandlerArgs {
|
||||||
lateinit var handler: Channel
|
lateinit var handler: Channel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@InvokeArg
|
||||||
|
class AssociatedDomain {
|
||||||
|
var scheme: List<String> = listOf("https", "http")
|
||||||
|
var host: String? = null
|
||||||
|
var path: List<String> = listOf()
|
||||||
|
var pathPattern: List<String> = listOf()
|
||||||
|
var pathPrefix: List<String> = listOf()
|
||||||
|
var pathSuffix: List<String> = listOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
@InvokeArg
|
||||||
|
class PluginConfig {
|
||||||
|
var mobile: List<AssociatedDomain> = listOf()
|
||||||
|
}
|
||||||
|
|
||||||
@TauriPlugin
|
@TauriPlugin
|
||||||
class DeepLinkPlugin(private val activity: Activity): Plugin(activity) {
|
class DeepLinkPlugin(private val activity: Activity): Plugin(activity) {
|
||||||
//private val implementation = Example()
|
//private val implementation = Example()
|
||||||
private var webView: WebView? = null
|
private var webView: WebView? = null
|
||||||
private var currentUrl: String? = null
|
private var currentUrl: String? = null
|
||||||
private var channel: Channel? = null
|
private var channel: Channel? = null
|
||||||
|
private var config: PluginConfig? = null
|
||||||
companion object {
|
companion object {
|
||||||
var instance: DeepLinkPlugin? = null
|
var instance: DeepLinkPlugin? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isViewIntent(action: String?): Boolean {
|
||||||
|
return action == Intent.ACTION_VIEW || action == "org.chromium.arc.intent.action.VIEW"
|
||||||
|
}
|
||||||
|
|
||||||
@Command
|
@Command
|
||||||
fun getCurrent(invoke: Invoke) {
|
fun getCurrent(invoke: Invoke) {
|
||||||
val ret = JSObject()
|
val ret = JSObject()
|
||||||
@@ -51,27 +70,105 @@ class DeepLinkPlugin(private val activity: Activity): Plugin(activity) {
|
|||||||
|
|
||||||
override fun load(webView: WebView) {
|
override fun load(webView: WebView) {
|
||||||
instance = this
|
instance = this
|
||||||
|
config = getConfig(PluginConfig::class.java)
|
||||||
val intent = activity.intent
|
|
||||||
|
|
||||||
if (intent.action == Intent.ACTION_VIEW) {
|
|
||||||
// TODO: check if it makes sense to split up init url and last url
|
|
||||||
this.currentUrl = intent.data.toString()
|
|
||||||
val event = JSObject()
|
|
||||||
event.put("url", this.currentUrl)
|
|
||||||
this.channel?.send(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
super.load(webView)
|
super.load(webView)
|
||||||
this.webView = webView
|
this.webView = webView
|
||||||
|
|
||||||
|
val intent = activity.intent
|
||||||
|
|
||||||
|
if (isViewIntent(intent.action) && intent.data != null) {
|
||||||
|
val url = intent.data.toString()
|
||||||
|
if (isDeepLink(url)) {
|
||||||
|
// TODO: check if it makes sense to split up init url and last url
|
||||||
|
this.currentUrl = url
|
||||||
|
val event = JSObject()
|
||||||
|
event.put("url", this.currentUrl)
|
||||||
|
this.channel?.send(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewIntent(intent: Intent) {
|
override fun onNewIntent(intent: Intent) {
|
||||||
if (intent.action == Intent.ACTION_VIEW) {
|
if (isViewIntent(intent.action) && intent.data != null) {
|
||||||
this.currentUrl = intent.data.toString()
|
val url = intent.data.toString()
|
||||||
val event = JSObject()
|
if (isDeepLink(url)) {
|
||||||
event.put("url", this.currentUrl)
|
this.currentUrl = url
|
||||||
this.channel?.send(event)
|
val event = JSObject()
|
||||||
|
event.put("url", this.currentUrl)
|
||||||
|
this.channel?.send(event)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isDeepLink(url: String): Boolean {
|
||||||
|
val config = this.config ?: return false
|
||||||
|
|
||||||
|
if (config.mobile.isEmpty()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val uri = try {
|
||||||
|
url.toUri()
|
||||||
|
} catch (_: Exception) {
|
||||||
|
// not a URL
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val scheme = uri.scheme ?: return false
|
||||||
|
val host = uri.host
|
||||||
|
val path = uri.path ?: ""
|
||||||
|
|
||||||
|
// Check if URL matches any configured mobile deep link
|
||||||
|
for (domain in config.mobile) {
|
||||||
|
// Check scheme
|
||||||
|
if (!domain.scheme.any { it.equals(scheme, ignoreCase = true) }) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check host (if configured)
|
||||||
|
if (domain.host != null) {
|
||||||
|
if (!host.equals(domain.host, ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check path constraints
|
||||||
|
// According to Android docs:
|
||||||
|
// - path: exact match, must begin with /
|
||||||
|
// - pathPrefix: matches initial part of path
|
||||||
|
// - pathSuffix: matches ending part, doesn't need to begin with /
|
||||||
|
// - pathPattern: simple glob pattern (., *, .*)
|
||||||
|
val pathMatches = when {
|
||||||
|
// Exact path match (must begin with /)
|
||||||
|
domain.path.isNotEmpty() && domain.path.any { it == path } -> true
|
||||||
|
// Path pattern match (simple glob: ., *, .*)
|
||||||
|
domain.pathPattern.isNotEmpty() && domain.pathPattern.any { pattern ->
|
||||||
|
try {
|
||||||
|
PatternMatcher(pattern, PatternMatcher.PATTERN_SIMPLE_GLOB).match(path)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} -> true
|
||||||
|
// Path prefix match
|
||||||
|
domain.pathPrefix.isNotEmpty() && domain.pathPrefix.any { prefix ->
|
||||||
|
path.startsWith(prefix)
|
||||||
|
} -> true
|
||||||
|
// Path suffix match
|
||||||
|
domain.pathSuffix.isNotEmpty() && domain.pathSuffix.any { suffix ->
|
||||||
|
path.endsWith(suffix)
|
||||||
|
} -> true
|
||||||
|
// If no path constraints, any path is allowed
|
||||||
|
domain.path.isEmpty() && domain.pathPattern.isEmpty() &&
|
||||||
|
domain.pathPrefix.isEmpty() && domain.pathSuffix.isEmpty() -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pathMatches) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 _={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__})}
|
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.WINDOW_SUSPENDED="tauri://suspended",e.WINDOW_RESUMED="tauri://resumed",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__})}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ fn intent_filter(domain: &AssociatedDomain) -> String {
|
|||||||
format!(
|
format!(
|
||||||
r#"<intent-filter {auto_verify}>
|
r#"<intent-filter {auto_verify}>
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<!-- ChromeOS ARC++ uses a different action for deep links -->
|
||||||
|
<action android:name="org.chromium.arc.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" />
|
||||||
{schemes}
|
{schemes}
|
||||||
@@ -137,13 +139,7 @@ fn main() {
|
|||||||
let deep_link_domains = config
|
let deep_link_domains = config
|
||||||
.mobile
|
.mobile
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|domain| {
|
.filter(|domain| !domain.is_app_link())
|
||||||
if domain.is_app_link() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(domain)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if deep_link_domains.is_empty() {
|
if deep_link_domains.is_empty() {
|
||||||
@@ -177,7 +173,7 @@ fn main() {
|
|||||||
);
|
);
|
||||||
dict.insert(
|
dict.insert(
|
||||||
"CFBundleURLName".into(),
|
"CFBundleURLName".into(),
|
||||||
format!("{}", domain.scheme[0]).into(),
|
domain.scheme[0].clone().into(),
|
||||||
);
|
);
|
||||||
plist::Value::Dictionary(dict)
|
plist::Value::Dictionary(dict)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,29 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## \[2.2.12]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `deep-link-js@2.4.9`
|
||||||
|
|
||||||
|
## \[2.2.11]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `deep-link-js@2.4.8`
|
||||||
|
|
||||||
|
## \[2.2.10]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `deep-link-js@2.4.7`
|
||||||
|
|
||||||
|
## \[2.2.9]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `deep-link-js@2.4.6`
|
||||||
|
|
||||||
## \[2.2.8]
|
## \[2.2.8]
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "deep-link-example",
|
"name": "deep-link-example",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "2.2.8",
|
"version": "2.2.12",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
@@ -10,12 +10,12 @@
|
|||||||
"tauri": "tauri"
|
"tauri": "tauri"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "2.9.0",
|
"@tauri-apps/api": "^2.11.0",
|
||||||
"@tauri-apps/plugin-deep-link": "2.4.5"
|
"@tauri-apps/plugin-deep-link": "2.4.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tauri-apps/cli": "2.9.1",
|
"@tauri-apps/cli-cef": "3.0.0-alpha.5",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^6.0.0",
|
||||||
"vite": "^7.0.7"
|
"vite": "^8.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@tauri-apps/plugin-deep-link",
|
"name": "@tauri-apps/plugin-deep-link",
|
||||||
"version": "2.4.5",
|
"version": "2.4.9",
|
||||||
"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,9 +25,9 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^2.8.0"
|
"@tauri-apps/api": "^2.11.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tauri-apps/cli": "2.9.1"
|
"@tauri-apps/cli-cef": "3.0.0-alpha.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Automatically generated - DO NOT EDIT!
|
||||||
|
|
||||||
|
"$schema" = "../../schemas/schema.json"
|
||||||
|
|
||||||
|
commands = ["get_current","register","unregister","is_registered"]
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-get-current"
|
|
||||||
description = "Enables the get_current command without any pre-configured scope."
|
|
||||||
commands.allow = ["get_current"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-get-current"
|
|
||||||
description = "Denies the get_current command without any pre-configured scope."
|
|
||||||
commands.deny = ["get_current"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-is-registered"
|
|
||||||
description = "Enables the is_registered command without any pre-configured scope."
|
|
||||||
commands.allow = ["is_registered"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-is-registered"
|
|
||||||
description = "Denies the is_registered command without any pre-configured scope."
|
|
||||||
commands.deny = ["is_registered"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-register"
|
|
||||||
description = "Enables the register command without any pre-configured scope."
|
|
||||||
commands.allow = ["register"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-register"
|
|
||||||
description = "Denies the register command without any pre-configured scope."
|
|
||||||
commands.deny = ["register"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-unregister"
|
|
||||||
description = "Enables the unregister command without any pre-configured scope."
|
|
||||||
commands.allow = ["unregister"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-unregister"
|
|
||||||
description = "Denies the unregister command without any pre-configured scope."
|
|
||||||
commands.deny = ["unregister"]
|
|
||||||
@@ -24,10 +24,17 @@
|
|||||||
},
|
},
|
||||||
"permission": {
|
"permission": {
|
||||||
"description": "A list of inlined permissions",
|
"description": "A list of inlined permissions",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/Permission"
|
"$ref": "#/definitions/Permission"
|
||||||
|
},
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"description": "A list of command names that get `allow-$command` and `deny-$command` permissions\nautogenerated on demand instead of being stored as explicit permissions.\n\nSee [`Manifest::command_permission`] and the ACL resolver for how these are expanded.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -35,9 +42,6 @@
|
|||||||
"DefaultPermission": {
|
"DefaultPermission": {
|
||||||
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"description": "The version of the permission.",
|
"description": "The version of the permission.",
|
||||||
@@ -46,10 +50,10 @@
|
|||||||
"null"
|
"null"
|
||||||
],
|
],
|
||||||
"format": "uint64",
|
"format": "uint64",
|
||||||
"minimum": 1.0
|
"minimum": 1
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
|
"description": "Human-readable description of what the permission does.\nTauri convention is to use `<h4>` headings in markdown content\nfor Tauri documentation generation purposes.",
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
"null"
|
"null"
|
||||||
@@ -62,16 +66,14 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"permissions"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"PermissionSet": {
|
"PermissionSet": {
|
||||||
"description": "A set of direct permissions grouped together under a new name.",
|
"description": "A set of direct permissions grouped together under a new name.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"description",
|
|
||||||
"identifier",
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"description": "A unique identifier for the permission.",
|
"description": "A unique identifier for the permission.",
|
||||||
@@ -85,17 +87,19 @@
|
|||||||
"description": "All permissions this set contains.",
|
"description": "All permissions this set contains.",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/PermissionKind"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"identifier",
|
||||||
|
"description",
|
||||||
|
"permissions"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"Permission": {
|
"Permission": {
|
||||||
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"identifier"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"version": {
|
"version": {
|
||||||
"description": "The version of the permission.",
|
"description": "The version of the permission.",
|
||||||
@@ -104,14 +108,14 @@
|
|||||||
"null"
|
"null"
|
||||||
],
|
],
|
||||||
"format": "uint64",
|
"format": "uint64",
|
||||||
"minimum": 1.0
|
"minimum": 1
|
||||||
},
|
},
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"description": "A unique identifier for the permission.",
|
"description": "A unique identifier for the permission.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
|
"description": "Human-readable description of what the permission does.\nTauri internal convention is to use `<h4>` headings in markdown content\nfor Tauri documentation generation purposes.",
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
"null"
|
"null"
|
||||||
@@ -147,7 +151,10 @@
|
|||||||
"$ref": "#/definitions/Target"
|
"$ref": "#/definitions/Target"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"required": [
|
||||||
|
"identifier"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"Commands": {
|
"Commands": {
|
||||||
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
|
||||||
@@ -155,24 +162,24 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"allow": {
|
"allow": {
|
||||||
"description": "Allowed command.",
|
"description": "Allowed command.",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"default": []
|
||||||
},
|
},
|
||||||
"deny": {
|
"deny": {
|
||||||
"description": "Denied command, which takes priority.",
|
"description": "Denied command, which takes priority.",
|
||||||
"default": [],
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
|
"default": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Scopes": {
|
"Scopes": {
|
||||||
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command. The configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json { \"allow\": [{ \"path\": \"$HOME/**\" }], \"deny\": [{ \"path\": \"$HOME/secret.txt\" }] } ```",
|
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command.\nThe configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json\n{\n \"allow\": [{ \"path\": \"$HOME/**\" }],\n \"deny\": [{ \"path\": \"$HOME/secret.txt\" }]\n}\n```",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"allow": {
|
"allow": {
|
||||||
@@ -257,96 +264,27 @@
|
|||||||
{
|
{
|
||||||
"description": "MacOS.",
|
"description": "MacOS.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "macOS"
|
||||||
"macOS"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Windows.",
|
"description": "Windows.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "windows"
|
||||||
"windows"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Linux.",
|
"description": "Linux.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "linux"
|
||||||
"linux"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Android.",
|
"description": "Android.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "android"
|
||||||
"android"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "iOS.",
|
"description": "iOS.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "iOS"
|
||||||
"iOS"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"PermissionKind": {
|
|
||||||
"type": "string",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"description": "Enables the get_current command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-get-current",
|
|
||||||
"markdownDescription": "Enables the get_current command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the get_current command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-get-current",
|
|
||||||
"markdownDescription": "Denies the get_current command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the is_registered command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-is-registered",
|
|
||||||
"markdownDescription": "Enables the is_registered command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the is_registered command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-is-registered",
|
|
||||||
"markdownDescription": "Denies the is_registered command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the register command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-register",
|
|
||||||
"markdownDescription": "Enables the register command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the register command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-register",
|
|
||||||
"markdownDescription": "Denies the register command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Enables the unregister command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "allow-unregister",
|
|
||||||
"markdownDescription": "Enables the unregister command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Denies the unregister command without any pre-configured scope.",
|
|
||||||
"type": "string",
|
|
||||||
"const": "deny-unregister",
|
|
||||||
"markdownDescription": "Denies the unregister command without any pre-configured scope."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Allows reading the opened deep link via the get_current command\n#### This default permission set includes:\n\n- `allow-get-current`",
|
|
||||||
"type": "string",
|
|
||||||
"const": "default",
|
|
||||||
"markdownDescription": "Allows reading the opened deep link via the get_current command\n#### This default permission set includes:\n\n- `allow-get-current`"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ mod imp {
|
|||||||
.unwrap_or_else(|| bin.into_os_string())
|
.unwrap_or_else(|| bin.into_os_string())
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.to_string();
|
.to_string();
|
||||||
let qualified_exec = format!("{} %u", exec);
|
let qualified_exec = format!("\"{}\" %u", exec);
|
||||||
|
|
||||||
let target = self.app.path().data_dir()?.join("applications");
|
let target = self.app.path().data_dir()?.join("applications");
|
||||||
|
|
||||||
@@ -540,7 +540,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R, Option<config::Config>> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.on_event(|_app, _event| {
|
.on_event(|_app, _event| {
|
||||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
#[cfg(desktop)]
|
||||||
if let tauri::RunEvent::Opened { urls } = _event {
|
if let tauri::RunEvent::Opened { urls } = _event {
|
||||||
use tauri::Emitter;
|
use tauri::Emitter;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.base.json",
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "guest-js"
|
||||||
|
},
|
||||||
"include": ["guest-js/*.ts"]
|
"include": ["guest-js/*.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,35 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## \[2.7.1]
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `fs-js@2.5.1`
|
||||||
|
|
||||||
|
## \[2.7.0]
|
||||||
|
|
||||||
|
- [`24154472`](https://github.com/tauri-apps/plugins-workspace/commit/24154472a6710a690173df0a121125d1f1b871e8) ([#3287](https://github.com/tauri-apps/plugins-workspace/pull/3287) by [@Legend-Master](https://github.com/tauri-apps/plugins-workspace/../../Legend-Master)) Re-use `message` command in Rust side for `ask` and `confirm` commands, `allow-ask` and `allow-confirm` permissions are now aliases to `allow-message`
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `fs-js@2.5.0`
|
||||||
|
|
||||||
|
## \[2.6.0]
|
||||||
|
|
||||||
|
- [`d7a0bb32`](https://github.com/tauri-apps/plugins-workspace/commit/d7a0bb325dad919d6cc132eb3898c33540de77c4) ([#3136](https://github.com/tauri-apps/plugins-workspace/pull/3136) by [@onehumandev](https://github.com/tauri-apps/plugins-workspace/../../onehumandev)) Add `fileAccessMode` option to file picker.
|
||||||
|
|
||||||
|
## \[2.5.0]
|
||||||
|
|
||||||
|
- [`dff6fa98`](https://github.com/tauri-apps/plugins-workspace/commit/dff6fa986a9a05ba98b6ca660fea78ae97251fc2) ([#3034](https://github.com/tauri-apps/plugins-workspace/pull/3034) by [@onehumandev](https://github.com/tauri-apps/plugins-workspace/../../onehumandev)) Add `pickerMode` option to file picker (currently only used on iOS)
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Upgraded to `fs-js@2.4.5`
|
||||||
|
|
||||||
|
### feat
|
||||||
|
|
||||||
|
- [`c23fa03f`](https://github.com/tauri-apps/plugins-workspace/commit/c23fa03f07d5c1c220bcf0bca482364513e3f754) ([#3098](https://github.com/tauri-apps/plugins-workspace/pull/3098) by [@Lepidopteran](https://github.com/tauri-apps/plugins-workspace/../../Lepidopteran)) Add `xdg-portal` as an optional feature for `rfd`
|
||||||
|
|
||||||
## \[2.4.2]
|
## \[2.4.2]
|
||||||
|
|
||||||
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
|
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tauri-plugin-dialog"
|
name = "tauri-plugin-dialog"
|
||||||
version = "2.4.2"
|
version = "2.7.1"
|
||||||
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 }
|
||||||
@@ -9,6 +9,11 @@ rust-version = { workspace = true }
|
|||||||
repository = { workspace = true }
|
repository = { workspace = true }
|
||||||
links = "tauri-plugin-dialog"
|
links = "tauri-plugin-dialog"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["gtk3"]
|
||||||
|
xdg-portal = ["rfd/xdg-portal", "rfd/tokio", "rfd/wayland"]
|
||||||
|
gtk3 = ["rfd/gtk3"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
targets = ["x86_64-unknown-linux-gnu", "x86_64-linux-android"]
|
targets = ["x86_64-unknown-linux-gnu", "x86_64-linux-android"]
|
||||||
|
|
||||||
@@ -32,15 +37,14 @@ 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.4.4" }
|
tauri-plugin-fs = { path = "../fs", version = "2.5.1" }
|
||||||
|
|
||||||
[target.'cfg(target_os = "ios")'.dependencies]
|
[target.'cfg(target_os = "ios")'.dependencies]
|
||||||
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]
|
||||||
rfd = { version = "0.15", default-features = false, features = [
|
rfd = { version = "0.16", default-features = false, features = [
|
||||||
"tokio",
|
|
||||||
"gtk3",
|
|
||||||
"common-controls-v6",
|
"common-controls-v6",
|
||||||
] }
|
] }
|
||||||
|
|
||||||
raw-window-handle = "0.6"
|
raw-window-handle = "0.6"
|
||||||
|
|||||||
@@ -31,6 +31,24 @@ tauri-plugin-dialog = "2.0.0"
|
|||||||
tauri-plugin-dialog = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
|
tauri-plugin-dialog = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Linux XDG Desktop Portal Support
|
||||||
|
|
||||||
|
By default, this plugin uses gtk to show dialogs, however since `v2.5.0` you can switch to using [XDG Desktop Portal](https://flatpak.github.io/xdg-desktop-portal/) by adding the following to your `Cargo.toml` file:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[dependencies]
|
||||||
|
tauri-plugin-dialog = { version = "2.5.0", default-features = false, features = ["xdg-portal"] }
|
||||||
|
# alternatively with Git:
|
||||||
|
tauri-plugin-dialog = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2", default-features = false, features = ["xdg-portal"] }
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Do note if you use the `xdg-portal` feature, you need to ensure that [`zenity`](https://gitlab.gnome.org/GNOME/zenity) and an [XDG Desktop Portal backend](https://flatpak.github.io/xdg-desktop-portal#using-portals) is installed with your program.
|
||||||
|
|
||||||
|
For more information, see [XDG Desktop Portal documentation](https://flatpak.github.io/xdg-desktop-portal/) and [`rfd` documentation](https://docs.rs/rfd/latest/rfd#xdg-desktop-portal-backend).
|
||||||
|
|
||||||
|
### JavaScript
|
||||||
|
|
||||||
You can install the JavaScript Guest bindings using your preferred JavaScript package manager:
|
You can install the JavaScript Guest bindings using your preferred JavaScript package manager:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ class Filter {
|
|||||||
class FilePickerOptions {
|
class FilePickerOptions {
|
||||||
lateinit var filters: Array<Filter>
|
lateinit var filters: Array<Filter>
|
||||||
var multiple: Boolean? = null
|
var multiple: Boolean? = null
|
||||||
|
var pickerMode: String? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
@InvokeArg
|
@InvokeArg
|
||||||
@@ -61,10 +62,19 @@ class DialogPlugin(private val activity: Activity): Plugin(activity) {
|
|||||||
// TODO: ACTION_OPEN_DOCUMENT ??
|
// TODO: ACTION_OPEN_DOCUMENT ??
|
||||||
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
||||||
intent.type = "*/*"
|
|
||||||
|
|
||||||
if (parsedTypes.isNotEmpty()) {
|
if (args.pickerMode == "image") {
|
||||||
|
intent.type = "image/*"
|
||||||
|
} else if (args.pickerMode == "video") {
|
||||||
|
intent.type = "video/*"
|
||||||
|
} else if (args.pickerMode == "media") {
|
||||||
|
intent.type = "*/*"
|
||||||
|
intent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("video/*", "image/*"))
|
||||||
|
} else if (parsedTypes.isNotEmpty()) {
|
||||||
|
intent.type = "*/*"
|
||||||
intent.putExtra(Intent.EXTRA_MIME_TYPES, parsedTypes)
|
intent.putExtra(Intent.EXTRA_MIME_TYPES, parsedTypes)
|
||||||
|
} else {
|
||||||
|
intent.type = "*/*"
|
||||||
}
|
}
|
||||||
|
|
||||||
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, args.multiple ?: false)
|
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, args.multiple ?: false)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
if("__TAURI__"in window){var __TAURI_PLUGIN_DIALOG__=function(t){"use strict";async function n(t,n={},e){return window.__TAURI_INTERNALS__.invoke(t,n,e)}function e(t){if(void 0!==t)return"string"==typeof t?t:"ok"in t&&"cancel"in t?{OkCancelCustom:[t.ok,t.cancel]}:"yes"in t&&"no"in t&&"cancel"in t?{YesNoCancelCustom:[t.yes,t.no,t.cancel]}:"ok"in t?{OkCustom:t.ok}:void 0}return"function"==typeof SuppressedError&&SuppressedError,t.ask=async function(t,e){const o="string"==typeof e?{title:e}:e;return await n("plugin:dialog|ask",{message:t.toString(),title:o?.title?.toString(),kind:o?.kind,yesButtonLabel:o?.okLabel?.toString(),noButtonLabel:o?.cancelLabel?.toString()})},t.confirm=async function(t,e){const o="string"==typeof e?{title:e}:e;return await n("plugin:dialog|confirm",{message:t.toString(),title:o?.title?.toString(),kind:o?.kind,okButtonLabel:o?.okLabel?.toString(),cancelButtonLabel:o?.cancelLabel?.toString()})},t.message=async function(t,o){const i="string"==typeof o?{title:o}:o;return n("plugin:dialog|message",{message:t.toString(),title:i?.title?.toString(),kind:i?.kind,okButtonLabel:i?.okLabel?.toString(),buttons:e(i?.buttons)})},t.open=async function(t={}){return"object"==typeof t&&Object.freeze(t),await n("plugin:dialog|open",{options:t})},t.save=async function(t={}){return"object"==typeof t&&Object.freeze(t),await n("plugin:dialog|save",{options:t})},t}({});Object.defineProperty(window.__TAURI__,"dialog",{value:__TAURI_PLUGIN_DIALOG__})}
|
if("__TAURI__"in window){var __TAURI_PLUGIN_DIALOG__=function(n){"use strict";async function e(n,e={},t){return window.__TAURI_INTERNALS__.invoke(n,e,t)}function t(n){if(void 0!==n)return"string"==typeof n?n:"ok"in n&&"cancel"in n?{OkCancelCustom:[n.ok,n.cancel]}:"yes"in n&&"no"in n&&"cancel"in n?{YesNoCancelCustom:[n.yes,n.no,n.cancel]}:"ok"in n?{OkCustom:n.ok}:void 0}async function o(n,o){return await e("plugin:dialog|message",{message:n,title:o?.title,kind:o?.kind,buttons:t(o?.buttons)})}return"function"==typeof SuppressedError&&SuppressedError,n.ask=async function(n,e){const t="string"==typeof e?{title:e}:e,i=t?.okLabel||t?.cancelLabel,a=t?.okLabel??"Yes";return await o(n,{title:t?.title,kind:t?.kind,buttons:i?{ok:a,cancel:t.cancelLabel??"No"}:"YesNo"})===a},n.confirm=async function(n,e){const t="string"==typeof e?{title:e}:e,i=t?.okLabel||t?.cancelLabel,a=t?.okLabel??"Ok";return await o(n,{title:t?.title,kind:t?.kind,buttons:i?{ok:a,cancel:t.cancelLabel??"Cancel"}:"OkCancel"})===a},n.message=async function(n,e){const t="string"==typeof e?{title:e}:e;return t&&!t.buttons&&t.okLabel&&(t.buttons={ok:t.okLabel}),o(n,t)},n.open=async function(n={}){return"object"==typeof n&&Object.freeze(n),await e("plugin:dialog|open",{options:n})},n.save=async function(n={}){return"object"==typeof n&&Object.freeze(n),await e("plugin:dialog|save",{options:n})},n}({});Object.defineProperty(window.__TAURI__,"dialog",{value:__TAURI_PLUGIN_DIALOG__})}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
const COMMANDS: &[&str] = &["open", "save", "message", "ask", "confirm"];
|
const COMMANDS: &[&str] = &["open", "save", "message"];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let result = tauri_plugin::Builder::new(COMMANDS)
|
let result = tauri_plugin::Builder::new(COMMANDS)
|
||||||
|
|||||||
@@ -14,6 +14,16 @@ interface DialogFilter {
|
|||||||
name: string
|
name: string
|
||||||
/**
|
/**
|
||||||
* Extensions to filter, without a `.` prefix.
|
* Extensions to filter, without a `.` prefix.
|
||||||
|
*
|
||||||
|
* **Note:** Mobile platforms have different APIs for filtering that may not support extensions.
|
||||||
|
* iOS: Extensions are supported in the document picker, but not in the media picker.
|
||||||
|
* Android: Extensions are not supported.
|
||||||
|
*
|
||||||
|
* For these platforms, MIME types are the primary way to filter files, as opposed to extensions.
|
||||||
|
* This means the string values here labeled as `extensions` may also be a MIME type.
|
||||||
|
* This property name of `extensions` is being kept for backwards compatibility, but this may be revisited to
|
||||||
|
* specify the difference between extension or MIME type filtering.
|
||||||
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```typescript
|
* ```typescript
|
||||||
* extensions: ['svg', 'png']
|
* extensions: ['svg', 'png']
|
||||||
@@ -30,7 +40,14 @@ interface DialogFilter {
|
|||||||
interface OpenDialogOptions {
|
interface OpenDialogOptions {
|
||||||
/** The title of the dialog window (desktop only). */
|
/** The title of the dialog window (desktop only). */
|
||||||
title?: string
|
title?: string
|
||||||
/** The filters of the dialog. */
|
/**
|
||||||
|
* The filters of the dialog.
|
||||||
|
* On mobile platforms, if either:
|
||||||
|
* A) the {@linkcode pickerMode} is set to `media`, `image`, or `video`
|
||||||
|
* -- or --
|
||||||
|
* B) the filters include **only** either image or video mime types, the media picker will be displayed.
|
||||||
|
* Otherwise, the document picker will be displayed.
|
||||||
|
*/
|
||||||
filters?: DialogFilter[]
|
filters?: DialogFilter[]
|
||||||
/**
|
/**
|
||||||
* Initial directory or file path.
|
* Initial directory or file path.
|
||||||
@@ -52,6 +69,38 @@ interface OpenDialogOptions {
|
|||||||
recursive?: boolean
|
recursive?: boolean
|
||||||
/** Whether to allow creating directories in the dialog. Enabled by default. **macOS Only** */
|
/** Whether to allow creating directories in the dialog. Enabled by default. **macOS Only** */
|
||||||
canCreateDirectories?: boolean
|
canCreateDirectories?: boolean
|
||||||
|
/**
|
||||||
|
* The preferred mode of the dialog.
|
||||||
|
* This is meant for mobile platforms (iOS and Android) which have distinct file and media pickers.
|
||||||
|
* If not provided, the dialog will automatically choose the best mode based on the MIME types or extensions of the {@linkcode filters}.
|
||||||
|
* On desktop, this option is ignored.
|
||||||
|
*/
|
||||||
|
pickerMode?: PickerMode
|
||||||
|
/**
|
||||||
|
* The file access mode of the dialog.
|
||||||
|
* If not provided, `copy` is used, which matches the behavior of the {@linkcode open} method before the introduction of this option.
|
||||||
|
*
|
||||||
|
* **Usage**
|
||||||
|
* If a file is opened with {@linkcode fileAccessMode: 'copy'}, it will be copied to the app's sandbox.
|
||||||
|
* This means the file can be read, edited, deleted, copied, or any other operation without any issues, since the file
|
||||||
|
* now belongs to the app.
|
||||||
|
* This also means that the caller has responsibility of deleting the file if this file is not meant to be retained
|
||||||
|
* in the app sandbox.
|
||||||
|
*
|
||||||
|
* If a file is opened with {@linkcode fileAccessMode: 'scoped'}, the file will remain in its original location
|
||||||
|
* and security-scoped access will be automatically managed by the system.
|
||||||
|
*
|
||||||
|
* **Note**
|
||||||
|
* This is specifically meant for document pickers on iOS or MacOS, in conjunction with [security scoped resources](https://developer.apple.com/documentation/foundation/nsurl/startaccessingsecurityscopedresource()).
|
||||||
|
*
|
||||||
|
* Why only document pickers, and not image or video pickers?
|
||||||
|
* The image and video pickers on iOS behave differently from the document pickers, and return [NSItemProvider](https://developer.apple.com/documentation/foundation/nsitemprovider) objects instead of file URLs.
|
||||||
|
* These are meant to be ephemeral (only available within the callback of the picker), and are not accessible outside of the callback.
|
||||||
|
* So for image and video pickers, the only way to access the file is to copy it to the app's sandbox, and this is the URL that is returned from this API.
|
||||||
|
* This means there is no provision for using `scoped` mode with image or video pickers.
|
||||||
|
* If an image or video picker is used, `copy` is always used.
|
||||||
|
*/
|
||||||
|
fileAccessMode?: FileAccessMode
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -77,6 +126,26 @@ interface SaveDialogOptions {
|
|||||||
canCreateDirectories?: boolean
|
canCreateDirectories?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The preferred mode of the dialog.
|
||||||
|
* This is meant for mobile platforms (iOS and Android) which have distinct file and media pickers.
|
||||||
|
* On desktop, this option is ignored.
|
||||||
|
* If not provided, the dialog will automatically choose the best mode based on the MIME types or extensions of the {@linkcode filters}.
|
||||||
|
*
|
||||||
|
* **Note:** This option is only supported on iOS 14 and above. This parameter is ignored on iOS 13 and below.
|
||||||
|
*/
|
||||||
|
export type PickerMode = 'document' | 'media' | 'image' | 'video'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file access mode of the dialog.
|
||||||
|
*
|
||||||
|
* - `copy`: copy/move the picked file to the app sandbox; no scoped access required.
|
||||||
|
* - `scoped`: keep file in place; security-scoped access is automatically managed.
|
||||||
|
*
|
||||||
|
* **Note:** This option is only supported on iOS 14 and above. This parameter is ignored on iOS 13 and below.
|
||||||
|
*/
|
||||||
|
export type FileAccessMode = 'copy' | 'scoped'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default buttons for a message dialog.
|
* Default buttons for a message dialog.
|
||||||
*
|
*
|
||||||
@@ -336,6 +405,18 @@ async function save(options: SaveDialogOptions = {}): Promise<string | null> {
|
|||||||
*/
|
*/
|
||||||
export type MessageDialogResult = 'Yes' | 'No' | 'Ok' | 'Cancel' | (string & {})
|
export type MessageDialogResult = 'Yes' | 'No' | 'Ok' | 'Cancel' | (string & {})
|
||||||
|
|
||||||
|
async function messageCommand(
|
||||||
|
message: string,
|
||||||
|
options?: Omit<MessageDialogOptions, 'okLabel'>
|
||||||
|
) {
|
||||||
|
return await invoke<MessageDialogResult>('plugin:dialog|message', {
|
||||||
|
message,
|
||||||
|
title: options?.title,
|
||||||
|
kind: options?.kind,
|
||||||
|
buttons: buttonsToRust(options?.buttons)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a message dialog with an `Ok` button.
|
* Shows a message dialog with an `Ok` button.
|
||||||
* @example
|
* @example
|
||||||
@@ -358,18 +439,17 @@ async function message(
|
|||||||
options?: string | MessageDialogOptions
|
options?: string | MessageDialogOptions
|
||||||
): Promise<MessageDialogResult> {
|
): Promise<MessageDialogResult> {
|
||||||
const opts = typeof options === 'string' ? { title: options } : options
|
const opts = typeof options === 'string' ? { title: options } : options
|
||||||
|
if (opts && !opts.buttons && opts.okLabel) {
|
||||||
return invoke<MessageDialogResult>('plugin:dialog|message', {
|
opts.buttons = { ok: opts.okLabel }
|
||||||
message: message.toString(),
|
}
|
||||||
title: opts?.title?.toString(),
|
return messageCommand(message, opts)
|
||||||
kind: opts?.kind,
|
|
||||||
okButtonLabel: opts?.okLabel?.toString(),
|
|
||||||
buttons: buttonsToRust(opts?.buttons)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a question dialog with `Yes` and `No` buttons.
|
* Shows a question dialog with `Yes` and `No` buttons.
|
||||||
|
*
|
||||||
|
* Convenient wrapper for `await message('msg', { buttons: 'YesNo' }) === 'Yes'`
|
||||||
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```typescript
|
* ```typescript
|
||||||
* import { ask } from '@tauri-apps/plugin-dialog';
|
* import { ask } from '@tauri-apps/plugin-dialog';
|
||||||
@@ -389,17 +469,24 @@ async function ask(
|
|||||||
options?: string | ConfirmDialogOptions
|
options?: string | ConfirmDialogOptions
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const opts = typeof options === 'string' ? { title: options } : options
|
const opts = typeof options === 'string' ? { title: options } : options
|
||||||
return await invoke('plugin:dialog|ask', {
|
const customButtons = opts?.okLabel || opts?.cancelLabel
|
||||||
message: message.toString(),
|
const okLabel = opts?.okLabel ?? 'Yes'
|
||||||
title: opts?.title?.toString(),
|
return (
|
||||||
kind: opts?.kind,
|
(await messageCommand(message, {
|
||||||
yesButtonLabel: opts?.okLabel?.toString(),
|
title: opts?.title,
|
||||||
noButtonLabel: opts?.cancelLabel?.toString()
|
kind: opts?.kind,
|
||||||
})
|
buttons: customButtons
|
||||||
|
? { ok: okLabel, cancel: opts.cancelLabel ?? 'No' }
|
||||||
|
: 'YesNo'
|
||||||
|
})) === okLabel
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a question dialog with `Ok` and `Cancel` buttons.
|
* Shows a question dialog with `Ok` and `Cancel` buttons.
|
||||||
|
*
|
||||||
|
* Convenient wrapper for `await message('msg', { buttons: 'OkCancel' }) === 'Ok'`
|
||||||
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```typescript
|
* ```typescript
|
||||||
* import { confirm } from '@tauri-apps/plugin-dialog';
|
* import { confirm } from '@tauri-apps/plugin-dialog';
|
||||||
@@ -419,13 +506,17 @@ async function confirm(
|
|||||||
options?: string | ConfirmDialogOptions
|
options?: string | ConfirmDialogOptions
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const opts = typeof options === 'string' ? { title: options } : options
|
const opts = typeof options === 'string' ? { title: options } : options
|
||||||
return await invoke('plugin:dialog|confirm', {
|
const customButtons = opts?.okLabel || opts?.cancelLabel
|
||||||
message: message.toString(),
|
const okLabel = opts?.okLabel ?? 'Ok'
|
||||||
title: opts?.title?.toString(),
|
return (
|
||||||
kind: opts?.kind,
|
(await messageCommand(message, {
|
||||||
okButtonLabel: opts?.okLabel?.toString(),
|
title: opts?.title,
|
||||||
cancelButtonLabel: opts?.cancelLabel?.toString()
|
kind: opts?.kind,
|
||||||
})
|
buttons: customButtons
|
||||||
|
? { ok: okLabel, cancel: opts.cancelLabel ?? 'Cancel' }
|
||||||
|
: 'OkCancel'
|
||||||
|
})) === okLabel
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import PhotosUI
|
|||||||
import SwiftRs
|
import SwiftRs
|
||||||
import Tauri
|
import Tauri
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import UniformTypeIdentifiers
|
||||||
import WebKit
|
import WebKit
|
||||||
|
|
||||||
enum FilePickerEvent {
|
enum FilePickerEvent {
|
||||||
@@ -32,6 +33,8 @@ struct FilePickerOptions: Decodable {
|
|||||||
var multiple: Bool?
|
var multiple: Bool?
|
||||||
var filters: [Filter]?
|
var filters: [Filter]?
|
||||||
var defaultPath: String?
|
var defaultPath: String?
|
||||||
|
var pickerMode: PickerMode?
|
||||||
|
var fileAccessMode: FileAccessMode?
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SaveFileDialogOptions: Decodable {
|
struct SaveFileDialogOptions: Decodable {
|
||||||
@@ -39,6 +42,18 @@ struct SaveFileDialogOptions: Decodable {
|
|||||||
var defaultPath: String?
|
var defaultPath: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum FileAccessMode: String, Decodable {
|
||||||
|
case copy
|
||||||
|
case scoped
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PickerMode: String, Decodable {
|
||||||
|
case document
|
||||||
|
case media
|
||||||
|
case image
|
||||||
|
case video
|
||||||
|
}
|
||||||
|
|
||||||
class DialogPlugin: Plugin {
|
class DialogPlugin: Plugin {
|
||||||
|
|
||||||
var filePickerController: FilePickerController!
|
var filePickerController: FilePickerController!
|
||||||
@@ -47,31 +62,12 @@ class DialogPlugin: Plugin {
|
|||||||
override init() {
|
override init() {
|
||||||
super.init()
|
super.init()
|
||||||
filePickerController = FilePickerController(self)
|
filePickerController = FilePickerController(self)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public func showFilePicker(_ invoke: Invoke) throws {
|
@objc public func showFilePicker(_ invoke: Invoke) throws {
|
||||||
let args = try invoke.parseArgs(FilePickerOptions.self)
|
let args = try invoke.parseArgs(FilePickerOptions.self)
|
||||||
|
|
||||||
let parsedTypes = parseFiltersOption(args.filters ?? [])
|
|
||||||
|
|
||||||
var isMedia = !parsedTypes.isEmpty
|
|
||||||
var uniqueMimeType: Bool? = nil
|
|
||||||
var mimeKind: String? = nil
|
|
||||||
if !parsedTypes.isEmpty {
|
|
||||||
uniqueMimeType = true
|
|
||||||
for mime in parsedTypes {
|
|
||||||
let kind = mime.components(separatedBy: "/")[0]
|
|
||||||
if kind != "image" && kind != "video" {
|
|
||||||
isMedia = false
|
|
||||||
}
|
|
||||||
if mimeKind == nil {
|
|
||||||
mimeKind = kind
|
|
||||||
} else if mimeKind != kind {
|
|
||||||
uniqueMimeType = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onFilePickerResult = { (event: FilePickerEvent) -> Void in
|
onFilePickerResult = { (event: FilePickerEvent) -> Void in
|
||||||
switch event {
|
switch event {
|
||||||
case .selected(let urls):
|
case .selected(let urls):
|
||||||
@@ -83,49 +79,59 @@ class DialogPlugin: Plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if uniqueMimeType == true || isMedia {
|
if #available(iOS 14, *) {
|
||||||
DispatchQueue.main.async {
|
let parsedTypes = parseFiltersOption(args.filters ?? [])
|
||||||
if #available(iOS 14, *) {
|
|
||||||
|
let mimeKinds = Set(
|
||||||
|
parsedTypes.compactMap { $0.preferredMIMEType?.components(separatedBy: "/")[0] })
|
||||||
|
let filtersIncludeImage = mimeKinds.contains("image")
|
||||||
|
let filtersIncludeVideo = mimeKinds.contains("video")
|
||||||
|
let filtersIncludeNonMedia = mimeKinds.contains(where: { $0 != "image" && $0 != "video" })
|
||||||
|
|
||||||
|
// If the picker mode is media, images, or videos, we always want to show the media picker regardless of what's in the filters.
|
||||||
|
// Otherwise, if the filters A) do not include non-media types and B) include either image or video, we want to show the media picker.
|
||||||
|
if args.pickerMode == .media
|
||||||
|
|| args.pickerMode == .image
|
||||||
|
|| args.pickerMode == .video
|
||||||
|
|| (!filtersIncludeNonMedia && (filtersIncludeImage || filtersIncludeVideo))
|
||||||
|
{
|
||||||
|
DispatchQueue.main.async {
|
||||||
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
|
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
|
||||||
configuration.selectionLimit = (args.multiple ?? false) ? 0 : 1
|
configuration.selectionLimit = (args.multiple ?? false) ? 0 : 1
|
||||||
|
|
||||||
if uniqueMimeType == true {
|
// If the filters include image or video, use the appropriate filter.
|
||||||
if mimeKind == "image" {
|
// If both are true, don't define a filter, which means we will display all media.
|
||||||
configuration.filter = .images
|
if args.pickerMode == .image || (filtersIncludeImage && !filtersIncludeVideo) {
|
||||||
} else if mimeKind == "video" {
|
configuration.filter = .images
|
||||||
configuration.filter = .videos
|
} else if args.pickerMode == .video || (filtersIncludeVideo && !filtersIncludeImage) {
|
||||||
}
|
configuration.filter = .videos
|
||||||
}
|
}
|
||||||
|
|
||||||
let picker = PHPickerViewController(configuration: configuration)
|
let picker = PHPickerViewController(configuration: configuration)
|
||||||
picker.delegate = self.filePickerController
|
picker.delegate = self.filePickerController
|
||||||
picker.modalPresentationStyle = .fullScreen
|
picker.modalPresentationStyle = .fullScreen
|
||||||
self.presentViewController(picker)
|
self.presentViewController(picker)
|
||||||
} else {
|
}
|
||||||
let picker = UIImagePickerController()
|
} else {
|
||||||
picker.delegate = self.filePickerController
|
DispatchQueue.main.async {
|
||||||
|
// The UTType.item is the catch-all, allowing for any file type to be selected.
|
||||||
|
let contentTypes = parsedTypes.isEmpty ? [UTType.item] : parsedTypes
|
||||||
|
let picker: UIDocumentPickerViewController = UIDocumentPickerViewController(
|
||||||
|
forOpeningContentTypes: contentTypes,
|
||||||
|
asCopy: args.fileAccessMode == .scoped ? false : true)
|
||||||
|
|
||||||
if uniqueMimeType == true && mimeKind == "image" {
|
if let defaultPath = args.defaultPath {
|
||||||
picker.sourceType = .photoLibrary
|
picker.directoryURL = URL(string: defaultPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
picker.sourceType = .photoLibrary
|
picker.delegate = self.filePickerController
|
||||||
|
picker.allowsMultipleSelection = args.multiple ?? false
|
||||||
picker.modalPresentationStyle = .fullScreen
|
picker.modalPresentationStyle = .fullScreen
|
||||||
self.presentViewController(picker)
|
self.presentViewController(picker)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let documentTypes = parsedTypes.isEmpty ? ["public.data"] : parsedTypes
|
showFilePickerLegacy(args: args)
|
||||||
DispatchQueue.main.async {
|
|
||||||
let picker = UIDocumentPickerViewController(documentTypes: documentTypes, in: .import)
|
|
||||||
if let defaultPath = args.defaultPath {
|
|
||||||
picker.directoryURL = URL(string: defaultPath)
|
|
||||||
}
|
|
||||||
picker.delegate = self.filePickerController
|
|
||||||
picker.allowsMultipleSelection = args.multiple ?? false
|
|
||||||
picker.modalPresentationStyle = .fullScreen
|
|
||||||
self.presentViewController(picker)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +179,68 @@ class DialogPlugin: Plugin {
|
|||||||
self.manager.viewController?.present(viewControllerToPresent, animated: true, completion: nil)
|
self.manager.viewController?.present(viewControllerToPresent, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func parseFiltersOption(_ filters: [Filter]) -> [String] {
|
@available(iOS 14, *)
|
||||||
|
private func parseFiltersOption(_ filters: [Filter]) -> [UTType] {
|
||||||
|
var parsedTypes: [UTType] = []
|
||||||
|
for filter in filters {
|
||||||
|
for ext in filter.extensions ?? [] {
|
||||||
|
// We need to support extensions as well as MIME types.
|
||||||
|
if let utType = UTType(mimeType: ext) {
|
||||||
|
parsedTypes.append(utType)
|
||||||
|
} else if let utType = UTType(filenameExtension: ext) {
|
||||||
|
parsedTypes.append(utType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This function is only used for iOS < 14, and should be removed if/when the deployment target is raised to 14.
|
||||||
|
private func showFilePickerLegacy(args: FilePickerOptions) {
|
||||||
|
let parsedTypes = parseFiltersOptionLegacy(args.filters ?? [])
|
||||||
|
|
||||||
|
var filtersIncludeImage: Bool = false
|
||||||
|
var filtersIncludeVideo: Bool = false
|
||||||
|
var filtersIncludeNonMedia: Bool = false
|
||||||
|
|
||||||
|
if !parsedTypes.isEmpty {
|
||||||
|
let mimeKinds = Set(parsedTypes.map { $0.components(separatedBy: "/")[0] })
|
||||||
|
filtersIncludeImage = mimeKinds.contains("image")
|
||||||
|
filtersIncludeVideo = mimeKinds.contains("video")
|
||||||
|
filtersIncludeNonMedia = mimeKinds.contains(where: { $0 != "image" && $0 != "video" })
|
||||||
|
}
|
||||||
|
|
||||||
|
if !filtersIncludeNonMedia && (filtersIncludeImage || filtersIncludeVideo) {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
let picker = UIImagePickerController()
|
||||||
|
picker.delegate = self.filePickerController
|
||||||
|
|
||||||
|
if filtersIncludeImage && !filtersIncludeVideo {
|
||||||
|
picker.sourceType = .photoLibrary
|
||||||
|
}
|
||||||
|
|
||||||
|
picker.modalPresentationStyle = .fullScreen
|
||||||
|
self.presentViewController(picker)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let documentTypes = parsedTypes.isEmpty ? ["public.data"] : parsedTypes
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
let picker = UIDocumentPickerViewController(documentTypes: documentTypes, in: .import)
|
||||||
|
if let defaultPath = args.defaultPath {
|
||||||
|
picker.directoryURL = URL(string: defaultPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
picker.delegate = self.filePickerController
|
||||||
|
picker.allowsMultipleSelection = args.multiple ?? false
|
||||||
|
picker.modalPresentationStyle = .fullScreen
|
||||||
|
self.presentViewController(picker)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This function is only used for iOS < 14, and should be removed if/when the deployment target is raised to 14.
|
||||||
|
private func parseFiltersOptionLegacy(_ filters: [Filter]) -> [String] {
|
||||||
var parsedTypes: [String] = []
|
var parsedTypes: [String] = []
|
||||||
for filter in filters {
|
for filter in filters {
|
||||||
for ext in filter.extensions ?? [] {
|
for ext in filter.extensions ?? [] {
|
||||||
@@ -186,6 +253,7 @@ class DialogPlugin: Plugin {
|
|||||||
parsedTypes.append(utType)
|
parsedTypes.append(utType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsedTypes
|
return parsedTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,6 +304,7 @@ class DialogPlugin: Plugin {
|
|||||||
manager.viewController?.present(alert, animated: true, completion: nil)
|
manager.viewController?.present(alert, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@_cdecl("init_plugin_dialog")
|
@_cdecl("init_plugin_dialog")
|
||||||
|
|||||||
@@ -95,16 +95,33 @@ public class FilePickerController: NSObject {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ## In which cases do we need to save a copy of a file selected by a user to the app sandbox?
|
||||||
|
/// In short, only when the file is **not** selected using UIDocumentPickerDelegate.
|
||||||
|
/// For the rest of the cases, we need to write a copy of the file to the app sandbox.
|
||||||
|
///
|
||||||
|
/// For PHPicker (used for photos and videos), `NSItemProvider.loadFileRepresentation` returns a temporary file URL that is deleted after the completion handler.
|
||||||
|
/// The recommendation is to [Persist](https://developer.apple.com/documentation/foundation/nsitemprovider/2888338-loadfilerepresentation) the file by moving/copying
|
||||||
|
/// it to your app’s directory within the completion handler.
|
||||||
|
///
|
||||||
|
/// If available, `loadInPlaceFileRepresentation` can open a file in place; Photos assets typically do not support true in-place access,
|
||||||
|
/// so fall back to persisting a local file.
|
||||||
|
/// Ref: https://developer.apple.com/documentation/foundation/nsitemprovider/2888335-loadinplacefilerepresentation
|
||||||
|
///
|
||||||
|
/// For UIDocumentPicker, prefer "open in place" and avoid copying when possible.
|
||||||
|
/// Ref: https://developer.apple.com/documentation/uikit/uidocumentpickerviewcontroller
|
||||||
private func saveTemporaryFile(_ sourceUrl: URL) throws -> URL {
|
private func saveTemporaryFile(_ sourceUrl: URL) throws -> URL {
|
||||||
|
|
||||||
var directory = URL(fileURLWithPath: NSTemporaryDirectory())
|
var directory = URL(fileURLWithPath: NSTemporaryDirectory())
|
||||||
if let cachesDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first {
|
if let cachesDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first {
|
||||||
directory = cachesDirectory
|
directory = cachesDirectory
|
||||||
}
|
}
|
||||||
|
|
||||||
let targetUrl = directory.appendingPathComponent(sourceUrl.lastPathComponent)
|
let targetUrl = directory.appendingPathComponent(sourceUrl.lastPathComponent)
|
||||||
do {
|
do {
|
||||||
try deleteFile(targetUrl)
|
try deleteFile(targetUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
try FileManager.default.copyItem(at: sourceUrl, to: targetUrl)
|
try FileManager.default.copyItem(at: sourceUrl, to: targetUrl)
|
||||||
return targetUrl
|
return targetUrl
|
||||||
}
|
}
|
||||||
@@ -119,8 +136,7 @@ public class FilePickerController: NSObject {
|
|||||||
extension FilePickerController: UIDocumentPickerDelegate {
|
extension FilePickerController: UIDocumentPickerDelegate {
|
||||||
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
|
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
|
||||||
do {
|
do {
|
||||||
let temporaryUrls = try urls.map { try saveTemporaryFile($0) }
|
self.plugin.onFilePickerEvent(.selected(urls))
|
||||||
self.plugin.onFilePickerEvent(.selected(temporaryUrls))
|
|
||||||
} catch {
|
} catch {
|
||||||
self.plugin.onFilePickerEvent(.error("Failed to create a temporary copy of the file"))
|
self.plugin.onFilePickerEvent(.error("Failed to create a temporary copy of the file"))
|
||||||
}
|
}
|
||||||
@@ -191,6 +207,8 @@ extension FilePickerController: PHPickerViewControllerDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
// We have to make a copy of the file to the app sandbox here, as PHPicker returns an NSItemProvider with either an ephemeral file URL or content that is deleted after the completion handler.
|
||||||
|
// This is a different behavior from UIDocumentPicker, where the file can either be copied to the app sandbox or opened in place, and then accessed with `startAccessingSecurityScopedResource`.
|
||||||
let temporaryUrl = try self.saveTemporaryFile(url)
|
let temporaryUrl = try self.saveTemporaryFile(url)
|
||||||
temporaryUrls.append(temporaryUrl)
|
temporaryUrls.append(temporaryUrl)
|
||||||
} catch {
|
} catch {
|
||||||
@@ -212,6 +230,8 @@ extension FilePickerController: PHPickerViewControllerDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
// We have to make a copy of the file to the app sandbox here, as PHPicker returns an NSItemProvider with either an ephemeral file URL or content that is deleted after the completion handler.
|
||||||
|
// This is a different behavior from UIDocumentPicker, where the file can either be copied to the app sandbox or opened in place, and then accessed with `startAccessingSecurityScopedResource`.
|
||||||
let temporaryUrl = try self.saveTemporaryFile(url)
|
let temporaryUrl = try self.saveTemporaryFile(url)
|
||||||
temporaryUrls.append(temporaryUrl)
|
temporaryUrls.append(temporaryUrl)
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@tauri-apps/plugin-dialog",
|
"name": "@tauri-apps/plugin-dialog",
|
||||||
"version": "2.4.2",
|
"version": "2.7.1",
|
||||||
"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.8.0"
|
"@tauri-apps/api": "^2.11.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
"$schema" = "schemas/schema.json"
|
||||||
|
|
||||||
|
[[permission]]
|
||||||
|
identifier = "allow-ask"
|
||||||
|
description = "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)"
|
||||||
|
commands.allow = ["message"]
|
||||||
|
|
||||||
|
[[permission]]
|
||||||
|
identifier = "deny-ask"
|
||||||
|
description = "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)"
|
||||||
|
commands.deny = ["message"]
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-ask"
|
|
||||||
description = "Enables the ask command without any pre-configured scope."
|
|
||||||
commands.allow = ["ask"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-ask"
|
|
||||||
description = "Denies the ask command without any pre-configured scope."
|
|
||||||
commands.deny = ["ask"]
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Automatically generated - DO NOT EDIT!
|
||||||
|
|
||||||
|
"$schema" = "../../schemas/schema.json"
|
||||||
|
|
||||||
|
commands = ["open","save","message"]
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-confirm"
|
|
||||||
description = "Enables the confirm command without any pre-configured scope."
|
|
||||||
commands.allow = ["confirm"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-confirm"
|
|
||||||
description = "Denies the confirm command without any pre-configured scope."
|
|
||||||
commands.deny = ["confirm"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-message"
|
|
||||||
description = "Enables the message command without any pre-configured scope."
|
|
||||||
commands.allow = ["message"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-message"
|
|
||||||
description = "Denies the message command without any pre-configured scope."
|
|
||||||
commands.deny = ["message"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-open"
|
|
||||||
description = "Enables the open command without any pre-configured scope."
|
|
||||||
commands.allow = ["open"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-open"
|
|
||||||
description = "Denies the open command without any pre-configured scope."
|
|
||||||
commands.deny = ["open"]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Automatically generated - DO NOT EDIT!
|
|
||||||
|
|
||||||
"$schema" = "../../schemas/schema.json"
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "allow-save"
|
|
||||||
description = "Enables the save command without any pre-configured scope."
|
|
||||||
commands.allow = ["save"]
|
|
||||||
|
|
||||||
[[permission]]
|
|
||||||
identifier = "deny-save"
|
|
||||||
description = "Denies the save command without any pre-configured scope."
|
|
||||||
commands.deny = ["save"]
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user