feat(clipboard): support `readImage` & `writeImage` (#845)

* feat(clipboard): support `read_image` & `write_image`

* fix plugin name

* platform specific bahavior

* remove unnecessary BufWriter

* improvement

* update example

* update example

* format

* header, fix change file

* use image from tauri

* fix ci

* update tauri, fix read

* image crate only on desktop [skip ci]

* Update plugins/authenticator/src/u2f_crate/protocol.rs [skip ci]

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

* Update plugins/authenticator/src/u2f_crate/protocol.rs [skip ci]

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

* update deps, address code review

* fix mobile [skip ci]

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
Co-authored-by: Lucas Nogueira <lucas@tauri.app>
Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>
pull/1071/head^2
阿良仔 1 year ago committed by GitHub
parent 7b9fa6607b
commit 9dec9605ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,6 @@
---
"clipboard-manager": "minor"
"clipboard-manager-js": "minor"
---
Add support for `read_image` and `write_image` to the clipboard plugin (desktop).

@ -0,0 +1,5 @@
---
"clipboard-manager": patch
---
The `write` and `read` commands are now called `write_text` and `read_text` so the permission name was changed.

547
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -10,9 +10,9 @@ resolver = "2"
[workspace.dependencies]
serde = { version = "1", features = ["derive"] }
log = "0.4"
tauri = "2.0.0-beta.9"
tauri-build = "2.0.0-beta.7"
tauri-plugin = "2.0.0-beta.7"
tauri = "2.0.0-beta.12"
tauri-build = "2.0.0-beta.10"
tauri-plugin = "2.0.0-beta.10"
serde_json = "1"
thiserror = "1"
url = "2"

@ -9,7 +9,7 @@
"serve": "vite preview"
},
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4",
"@tauri-apps/api": "2.0.0-beta.6",
"@tauri-apps/plugin-barcode-scanner": "2.0.0-beta.2",
"@tauri-apps/plugin-biometric": "2.0.0-beta.2",
"@tauri-apps/plugin-cli": "2.0.0-beta.2",
@ -30,7 +30,7 @@
"@iconify-json/codicon": "^1.1.37",
"@iconify-json/ph": "^1.1.8",
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"@tauri-apps/cli": "2.0.0-beta.7",
"@tauri-apps/cli": "2.0.0-beta.9",
"@unocss/extractor-svelte": "^0.58.0",
"internal-ip": "^8.0.0",
"svelte": "^4.2.8",

@ -21,6 +21,7 @@
"tray:default",
"event:default",
"window:default",
"image:default",
"notification:default",
"os:allow-platform",
"dialog:allow-open",
@ -54,8 +55,10 @@
},
"shell:allow-kill",
"shell:allow-stdin-write",
"clipboard-manager:allow-read",
"clipboard-manager:allow-write",
"clipboard-manager:allow-read-text",
"clipboard-manager:allow-write-text",
"clipboard-manager:allow-read-image",
"clipboard-manager:allow-write-image",
"fs:allow-rename",
"fs:allow-mkdir",
"fs:allow-remove",

@ -41,8 +41,7 @@
"type": "object",
"required": [
"identifier",
"permissions",
"windows"
"permissions"
],
"properties": {
"identifier": {
@ -93,14 +92,10 @@
},
"platforms": {
"description": "Target platforms this capability applies. By default all platforms are affected by this capability.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}
@ -115,7 +110,7 @@
],
"properties": {
"urls": {
"description": "Remote domains this capability refers to. Can use glob patterns.",
"description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).\n\n# Examples\n\n- \"https://*.mydomain.dev\": allows subdomains of mydomain.dev - \"https://mydomain.dev/api/*\": allows any subpath of mydomain.dev/api",
"type": "array",
"items": {
"type": "string"
@ -2297,6 +2292,12 @@
"properties": {
"identifier": {
"oneOf": [
{
"type": "string",
"enum": [
"shell:default"
]
},
{
"description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.",
"type": "string",
@ -2532,31 +2533,99 @@
]
},
{
"description": "clipboard-manager:allow-read -> Enables the read command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-read"
"clipboard-manager:default"
]
},
{
"description": "clipboard-manager:allow-clear -> Enables the clear command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-clear"
]
},
{
"description": "clipboard-manager:allow-read-image -> Enables the read_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-read-image"
]
},
{
"description": "clipboard-manager:allow-read-text -> Enables the read_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-read-text"
]
},
{
"description": "clipboard-manager:allow-write-html -> Enables the write_html command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-write-html"
]
},
{
"description": "clipboard-manager:allow-write-image -> Enables the write_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-write-image"
]
},
{
"description": "clipboard-manager:allow-write -> Enables the write command without any pre-configured scope.",
"description": "clipboard-manager:allow-write-text -> Enables the write_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-write"
"clipboard-manager:allow-write-text"
]
},
{
"description": "clipboard-manager:deny-read -> Denies the read command without any pre-configured scope.",
"description": "clipboard-manager:deny-clear -> Denies the clear command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-read"
"clipboard-manager:deny-clear"
]
},
{
"description": "clipboard-manager:deny-write -> Denies the write command without any pre-configured scope.",
"description": "clipboard-manager:deny-read-image -> Denies the read_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write"
"clipboard-manager:deny-read-image"
]
},
{
"description": "clipboard-manager:deny-read-text -> Denies the read_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-read-text"
]
},
{
"description": "clipboard-manager:deny-write-html -> Denies the write_html command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write-html"
]
},
{
"description": "clipboard-manager:deny-write-image -> Denies the write_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write-image"
]
},
{
"description": "clipboard-manager:deny-write-text -> Denies the write_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write-text"
]
},
{
"type": "string",
"enum": [
"dialog:default"
]
},
{
@ -4680,6 +4749,12 @@
"fs:write-files"
]
},
{
"type": "string",
"enum": [
"global-shortcut:default"
]
},
{
"description": "global-shortcut:allow-is-registered -> Enables the is_registered command without any pre-configured scope.",
"type": "string",
@ -4827,13 +4902,6 @@
"image:allow-from-bytes"
]
},
{
"description": "image:allow-from-ico-bytes -> Enables the from_ico_bytes command without any pre-configured scope.",
"type": "string",
"enum": [
"image:allow-from-ico-bytes"
]
},
{
"description": "image:allow-from-path -> Enables the from_path command without any pre-configured scope.",
"type": "string",
@ -4841,20 +4909,6 @@
"image:allow-from-path"
]
},
{
"description": "image:allow-from-png-bytes -> Enables the from_png_bytes command without any pre-configured scope.",
"type": "string",
"enum": [
"image:allow-from-png-bytes"
]
},
{
"description": "image:allow-height -> Enables the height command without any pre-configured scope.",
"type": "string",
"enum": [
"image:allow-height"
]
},
{
"description": "image:allow-new -> Enables the new command without any pre-configured scope.",
"type": "string",
@ -4870,10 +4924,10 @@
]
},
{
"description": "image:allow-width -> Enables the width command without any pre-configured scope.",
"description": "image:allow-size -> Enables the size command without any pre-configured scope.",
"type": "string",
"enum": [
"image:allow-width"
"image:allow-size"
]
},
{
@ -4883,13 +4937,6 @@
"image:deny-from-bytes"
]
},
{
"description": "image:deny-from-ico-bytes -> Denies the from_ico_bytes command without any pre-configured scope.",
"type": "string",
"enum": [
"image:deny-from-ico-bytes"
]
},
{
"description": "image:deny-from-path -> Denies the from_path command without any pre-configured scope.",
"type": "string",
@ -4897,20 +4944,6 @@
"image:deny-from-path"
]
},
{
"description": "image:deny-from-png-bytes -> Denies the from_png_bytes command without any pre-configured scope.",
"type": "string",
"enum": [
"image:deny-from-png-bytes"
]
},
{
"description": "image:deny-height -> Denies the height command without any pre-configured scope.",
"type": "string",
"enum": [
"image:deny-height"
]
},
{
"description": "image:deny-new -> Denies the new command without any pre-configured scope.",
"type": "string",
@ -4926,10 +4959,10 @@
]
},
{
"description": "image:deny-width -> Denies the width command without any pre-configured scope.",
"description": "image:deny-size -> Denies the size command without any pre-configured scope.",
"type": "string",
"enum": [
"image:deny-width"
"image:deny-size"
]
},
{
@ -5317,6 +5350,12 @@
"notification:deny-request-permission"
]
},
{
"type": "string",
"enum": [
"os:default"
]
},
{
"description": "os:allow-arch -> Enables the arch command without any pre-configured scope.",
"type": "string",
@ -5548,6 +5587,12 @@
"path:deny-resolve-directory"
]
},
{
"type": "string",
"enum": [
"process:default"
]
},
{
"description": "process:allow-exit -> Enables the exit command without any pre-configured scope.",
"type": "string",
@ -5597,6 +5642,12 @@
"resources:deny-close"
]
},
{
"type": "string",
"enum": [
"shell:default"
]
},
{
"description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.",
"type": "string",
@ -5660,6 +5711,13 @@
"tray:default"
]
},
{
"description": "tray:allow-get-by-id -> Enables the get_by_id command without any pre-configured scope.",
"type": "string",
"enum": [
"tray:allow-get-by-id"
]
},
{
"description": "tray:allow-new -> Enables the new command without any pre-configured scope.",
"type": "string",
@ -5667,6 +5725,13 @@
"tray:allow-new"
]
},
{
"description": "tray:allow-remove-by-id -> Enables the remove_by_id command without any pre-configured scope.",
"type": "string",
"enum": [
"tray:allow-remove-by-id"
]
},
{
"description": "tray:allow-set-icon -> Enables the set_icon command without any pre-configured scope.",
"type": "string",
@ -5723,6 +5788,13 @@
"tray:allow-set-visible"
]
},
{
"description": "tray:deny-get-by-id -> Denies the get_by_id command without any pre-configured scope.",
"type": "string",
"enum": [
"tray:deny-get-by-id"
]
},
{
"description": "tray:deny-new -> Denies the new command without any pre-configured scope.",
"type": "string",
@ -5730,6 +5802,13 @@
"tray:deny-new"
]
},
{
"description": "tray:deny-remove-by-id -> Denies the remove_by_id command without any pre-configured scope.",
"type": "string",
"enum": [
"tray:deny-remove-by-id"
]
},
{
"description": "tray:deny-set-icon -> Denies the set_icon command without any pre-configured scope.",
"type": "string",

@ -11,6 +11,13 @@
}
]
},
{
"description": "A list of capabilities.",
"type": "array",
"items": {
"$ref": "#/definitions/Capability"
}
},
{
"description": "A list of capabilities.",
"type": "object",
@ -34,8 +41,7 @@
"type": "object",
"required": [
"identifier",
"permissions",
"windows"
"permissions"
],
"properties": {
"identifier": {
@ -86,14 +92,10 @@
},
"platforms": {
"description": "Target platforms this capability applies. By default all platforms are affected by this capability.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}
@ -108,7 +110,7 @@
],
"properties": {
"urls": {
"description": "Remote domains this capability refers to. Can use glob patterns.",
"description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).\n\n# Examples\n\n- \"https://*.mydomain.dev\": allows subdomains of mydomain.dev - \"https://mydomain.dev/api/*\": allows any subpath of mydomain.dev/api",
"type": "array",
"items": {
"type": "string"
@ -2290,6 +2292,12 @@
"properties": {
"identifier": {
"oneOf": [
{
"type": "string",
"enum": [
"shell:default"
]
},
{
"description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.",
"type": "string",
@ -2503,6 +2511,12 @@
"app:deny-version"
]
},
{
"type": "string",
"enum": [
"barcode-scanner:default"
]
},
{
"description": "barcode-scanner:allow-cancel -> Enables the cancel command without any pre-configured scope.",
"type": "string",
@ -2587,6 +2601,12 @@
"barcode-scanner:deny-vibrate"
]
},
{
"type": "string",
"enum": [
"biometric:default"
]
},
{
"description": "biometric:allow-authenticate -> Enables the authenticate command without any pre-configured scope.",
"type": "string",
@ -2616,31 +2636,99 @@
]
},
{
"description": "clipboard-manager:allow-read -> Enables the read command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-read"
"clipboard-manager:default"
]
},
{
"description": "clipboard-manager:allow-write -> Enables the write command without any pre-configured scope.",
"description": "clipboard-manager:allow-clear -> Enables the clear command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-write"
"clipboard-manager:allow-clear"
]
},
{
"description": "clipboard-manager:deny-read -> Denies the read command without any pre-configured scope.",
"description": "clipboard-manager:allow-read-image -> Enables the read_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-read"
"clipboard-manager:allow-read-image"
]
},
{
"description": "clipboard-manager:deny-write -> Denies the write command without any pre-configured scope.",
"description": "clipboard-manager:allow-read-text -> Enables the read_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write"
"clipboard-manager:allow-read-text"
]
},
{
"description": "clipboard-manager:allow-write-html -> Enables the write_html command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-write-html"
]
},
{
"description": "clipboard-manager:allow-write-image -> Enables the write_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-write-image"
]
},
{
"description": "clipboard-manager:allow-write-text -> Enables the write_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-write-text"
]
},
{
"description": "clipboard-manager:deny-clear -> Denies the clear command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-clear"
]
},
{
"description": "clipboard-manager:deny-read-image -> Denies the read_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-read-image"
]
},
{
"description": "clipboard-manager:deny-read-text -> Denies the read_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-read-text"
]
},
{
"description": "clipboard-manager:deny-write-html -> Denies the write_html command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write-html"
]
},
{
"description": "clipboard-manager:deny-write-image -> Denies the write_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write-image"
]
},
{
"description": "clipboard-manager:deny-write-text -> Denies the write_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write-text"
]
},
{
"type": "string",
"enum": [
"dialog:default"
]
},
{
@ -4827,6 +4915,83 @@
"http:deny-fetch-send"
]
},
{
"description": "image:default -> Default permissions for the plugin.",
"type": "string",
"enum": [
"image:default"
]
},
{
"description": "image:allow-from-bytes -> Enables the from_bytes command without any pre-configured scope.",
"type": "string",
"enum": [
"image:allow-from-bytes"
]
},
{
"description": "image:allow-from-path -> Enables the from_path command without any pre-configured scope.",
"type": "string",
"enum": [
"image:allow-from-path"
]
},
{
"description": "image:allow-new -> Enables the new command without any pre-configured scope.",
"type": "string",
"enum": [
"image:allow-new"
]
},
{
"description": "image:allow-rgba -> Enables the rgba command without any pre-configured scope.",
"type": "string",
"enum": [
"image:allow-rgba"
]
},
{
"description": "image:allow-size -> Enables the size command without any pre-configured scope.",
"type": "string",
"enum": [
"image:allow-size"
]
},
{
"description": "image:deny-from-bytes -> Denies the from_bytes command without any pre-configured scope.",
"type": "string",
"enum": [
"image:deny-from-bytes"
]
},
{
"description": "image:deny-from-path -> Denies the from_path command without any pre-configured scope.",
"type": "string",
"enum": [
"image:deny-from-path"
]
},
{
"description": "image:deny-new -> Denies the new command without any pre-configured scope.",
"type": "string",
"enum": [
"image:deny-new"
]
},
{
"description": "image:deny-rgba -> Denies the rgba command without any pre-configured scope.",
"type": "string",
"enum": [
"image:deny-rgba"
]
},
{
"description": "image:deny-size -> Denies the size command without any pre-configured scope.",
"type": "string",
"enum": [
"image:deny-size"
]
},
{
"description": "log:default -> Allows the log command",
"type": "string",
@ -5163,6 +5328,12 @@
"menu:deny-text"
]
},
{
"type": "string",
"enum": [
"nfc:default"
]
},
{
"description": "nfc:allow-is-available -> Enables the is_available command without any pre-configured scope.",
"type": "string",
@ -5254,6 +5425,12 @@
"notification:deny-request-permission"
]
},
{
"type": "string",
"enum": [
"os:default"
]
},
{
"description": "os:allow-arch -> Enables the arch command without any pre-configured scope.",
"type": "string",
@ -5485,6 +5662,12 @@
"path:deny-resolve-directory"
]
},
{
"type": "string",
"enum": [
"process:default"
]
},
{
"description": "process:allow-exit -> Enables the exit command without any pre-configured scope.",
"type": "string",
@ -5534,6 +5717,12 @@
"resources:deny-close"
]
},
{
"type": "string",
"enum": [
"shell:default"
]
},
{
"description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.",
"type": "string",
@ -5597,6 +5786,13 @@
"tray:default"
]
},
{
"description": "tray:allow-get-by-id -> Enables the get_by_id command without any pre-configured scope.",
"type": "string",
"enum": [
"tray:allow-get-by-id"
]
},
{
"description": "tray:allow-new -> Enables the new command without any pre-configured scope.",
"type": "string",
@ -5604,6 +5800,13 @@
"tray:allow-new"
]
},
{
"description": "tray:allow-remove-by-id -> Enables the remove_by_id command without any pre-configured scope.",
"type": "string",
"enum": [
"tray:allow-remove-by-id"
]
},
{
"description": "tray:allow-set-icon -> Enables the set_icon command without any pre-configured scope.",
"type": "string",
@ -5660,6 +5863,13 @@
"tray:allow-set-visible"
]
},
{
"description": "tray:deny-get-by-id -> Denies the get_by_id command without any pre-configured scope.",
"type": "string",
"enum": [
"tray:deny-get-by-id"
]
},
{
"description": "tray:deny-new -> Denies the new command without any pre-configured scope.",
"type": "string",
@ -5667,6 +5877,13 @@
"tray:deny-new"
]
},
{
"description": "tray:deny-remove-by-id -> Denies the remove_by_id command without any pre-configured scope.",
"type": "string",
"enum": [
"tray:deny-remove-by-id"
]
},
{
"description": "tray:deny-set-icon -> Denies the set_icon command without any pre-configured scope.",
"type": "string",

@ -80,9 +80,10 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
i @ "icon-1" | i @ "icon-2" => {
if let Some(tray) = app.tray_by_id("tray-1") {
let _ = tray.set_icon(Some(if i == "icon-1" {
tauri::Image::from_ico_bytes(include_bytes!("../icons/icon.ico")).unwrap()
tauri::image::Image::from_bytes(include_bytes!("../icons/icon.ico"))
.unwrap()
} else {
tauri::Image::from_png_bytes(include_bytes!(
tauri::image::Image::from_bytes(include_bytes!(
"../icons/tray_icon_with_transparency.png"
))
.unwrap()

@ -0,0 +1,15 @@
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
export function arrayBufferToBase64(buffer, callback) {
const blob = new Blob([buffer], {
type: "application/octet-binary",
});
const reader = new FileReader();
reader.onload = function (evt) {
const dataurl = evt.target.result;
callback(dataurl.substr(dataurl.indexOf(",") + 1));
};
reader.readAsDataURL(blob);
}

@ -1,23 +1,59 @@
<script>
import { writeText, readText } from "@tauri-apps/plugin-clipboard-manager";
import * as clipboard from "@tauri-apps/plugin-clipboard-manager";
import { open } from "@tauri-apps/plugin-dialog";
import { arrayBufferToBase64 } from "../lib/utils";
import { readFile } from "@tauri-apps/plugin-fs";
export let onMessage;
export let insecureRenderHtml;
let text = "clipboard message";
function write() {
writeText(text)
function writeText() {
clipboard
.writeText(text)
.then(() => {
onMessage("Wrote to the clipboard");
})
.catch(onMessage);
}
function read() {
readText()
async function writeImage() {
try {
const res = await open({
title: "Image to write to clipboard",
filters: [
{
name: "Clipboard IMG",
extensions: ["png", "jpg", "jpeg"],
},
],
});
const bytes = await readFile(res.path);
await clipboard.writeImage(bytes);
onMessage("wrote image");
} catch (e) {
onMessage(e);
}
}
async function read() {
try {
const image = await clipboard.readImage();
arrayBufferToBase64(await image.rgba(), function (base64) {
const src = "data:image/png;base64," + base64;
insecureRenderHtml('<img src="' + src + '"></img>');
});
return;
} catch (_) {}
clipboard
.readText()
.then((contents) => {
onMessage(`Clipboard contents: ${contents}`);
})
.catch(onMessage);
.catch((e) => {
onMessage(e);
});
}
</script>
@ -27,6 +63,8 @@
placeholder="Text to write to the clipboard"
bind:value={text}
/>
<button class="btn" type="button" on:click={write}>Write</button>
<button class="btn" type="button" on:click={writeText}>Write</button>
<button class="btn" type="button" on:click={writeImage}>Pick Image</button>
<button class="btn" type="button" on:click={read}>Read</button>
</div>

@ -1,6 +1,7 @@
<script>
import * as fs from "@tauri-apps/plugin-fs";
import { convertFileSrc } from "@tauri-apps/api/core";
import { arrayBufferToBase64 } from "../lib/utils";
export let onMessage;
export let insecureRenderHtml;
@ -20,18 +21,6 @@
return dirSelect.value ? parseInt(dir.value) : null;
}
function arrayBufferToBase64(buffer, callback) {
const blob = new Blob([buffer], {
type: "application/octet-binary",
});
const reader = new FileReader();
reader.onload = function (evt) {
const dataurl = evt.target.result;
callback(dataurl.substr(dataurl.indexOf(",") + 1));
};
reader.readAsDataURL(blob);
}
const DirOptions = Object.keys(fs.BaseDirectory)
.filter((key) => isNaN(parseInt(key)))
.map((dir) => [dir, fs.BaseDirectory[dir]]);
@ -215,7 +204,7 @@
<button class="btn" on:click={stat}>Stat</button>
</div>
{/if}
<h3>Watch</h3>
<input
@ -225,7 +214,9 @@
/>
<br />
<div>
<label for="watch-debounce-delay">Debounce delay in milliseconds (`0` disables the debouncer)</label>
<label for="watch-debounce-delay"
>Debounce delay in milliseconds (`0` disables the debouncer)</label
>
<input
class="input"
id="watch-debounce-delay"

@ -24,6 +24,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -95,7 +95,8 @@ impl U2f {
challenge: Challenge,
response: RegisterResponse,
) -> Result<Registration> {
if expiration(challenge.timestamp) > Duration::seconds(300) {
// Safe to unwrap since 300 is within the constraints of Duration::try_seconds
if expiration(challenge.timestamp) > Duration::try_seconds(300).unwrap() {
return Err(U2fError::ChallengeExpired);
}
@ -152,7 +153,8 @@ impl U2f {
sign_resp: SignResponse,
counter: u32,
) -> Result<u32> {
if expiration(challenge.timestamp) > Duration::seconds(300) {
// Safe to unwrap since 300 is within the constraints of Duration::try_seconds
if expiration(challenge.timestamp) > Duration::try_seconds(300).unwrap() {
return Err(U2fError::ChallengeExpired);
}

@ -23,6 +23,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -24,6 +24,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -27,6 +27,6 @@
"tslib": "2.6.0"
},
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -23,6 +23,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -25,3 +25,4 @@ thiserror = { workspace = true }
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
arboard = "3"
image = "0.24"

@ -87,7 +87,7 @@ class ClipboardPlugin(private val activity: Activity) : Plugin(activity) {
@Command
@Suppress("MoveVariableDeclarationIntoWhen")
fun write(invoke: Invoke) {
fun writeText(invoke: Invoke) {
val args = invoke.parseArgs(WriteOptions::class.java)
val clipData = when (args) {
@ -106,7 +106,7 @@ class ClipboardPlugin(private val activity: Activity) : Plugin(activity) {
}
@Command
fun read(invoke: Invoke) {
fun readText(invoke: Invoke) {
val data = if (manager.hasPrimaryClip()) {
if (manager.primaryClipDescription?.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN) == true) {
val item: ClipData.Item = manager.primaryClip!!.getItemAt(0)

@ -2,7 +2,14 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
const COMMANDS: &[&str] = &["write", "read"];
const COMMANDS: &[&str] = &[
"write_text",
"read_text",
"write_image",
"read_image",
"write_html",
"clear",
];
fn main() {
if let Err(error) = tauri_plugin::Builder::new(COMMANDS)

@ -9,6 +9,7 @@
*/
import { invoke } from "@tauri-apps/api/core";
import { Image, transformImage } from "@tauri-apps/api/image";
type ClipResponse = Record<"plainText", { text: string }>;
@ -29,7 +30,7 @@ async function writeText(
text: string,
opts?: { label?: string },
): Promise<void> {
return invoke("plugin:clipboard-manager|write", {
return invoke("plugin:clipboard-manager|write_text", {
data: {
plainText: {
label: opts?.label,
@ -49,12 +50,60 @@ async function writeText(
* @since 2.0.0
*/
async function readText(): Promise<string> {
const kind: ClipResponse = await invoke("plugin:clipboard-manager|read");
const kind: ClipResponse = await invoke("plugin:clipboard-manager|read_text");
return kind.plainText.text;
}
/**
* Writes HTML or fallbacks to write provided plain text to the clipboard.
* Gets the clipboard content as Uint8Array image.
* @example
* ```typescript
* import { readImage } from '@tauri-apps/plugin-clipboard-manager';
*
* const clipboardImage = await readImage();
* const blob = new Blob([clipboardImage.bytes], { type: 'image' })
* const url = URL.createObjectURL(blob)
* ```
* @since 2.0.0
*/
async function readImage(): Promise<Image> {
return await invoke<number>("plugin:clipboard-manager|read_image").then(
(rid) => new Image(rid),
);
}
/**
* Writes image buffer to the clipboard.
* @example
* ```typescript
* import { writeImage } from '@tauri-apps/plugin-clipboard-manager';
* const buffer = [
* // A red pixel
* 255, 0, 0, 255,
*
* // A green pixel
* 0, 255, 0, 255,
* ];
* await writeImage(buffer);
*
* @returns A promise indicating the success or failure of the operation.
*
* @since 2.0.0
*/
async function writeImage(
image: string | Image | Uint8Array | ArrayBuffer | number[],
): Promise<void> {
return invoke("plugin:clipboard-manager|write_image", {
data: {
image: {
image: transformImage(image),
},
},
});
}
/**
* * Writes HTML or fallbacks to write provided plain text to the clipboard.
* @example
* ```typescript
* import { writeHtml, readHtml } from '@tauri-apps/plugin-clipboard-manager';
@ -92,4 +141,4 @@ async function clear(): Promise<void> {
return;
}
export { writeText, readText, writeHtml, clear };
export { writeText, readText, writeHtml, clear, readImage, writeImage };

@ -16,7 +16,7 @@ enum ReadClipData: Codable {
}
class ClipboardPlugin: Plugin {
@objc public func write(_ invoke: Invoke) throws {
@objc public func writeText(_ invoke: Invoke) throws {
let options = try invoke.parseArgs(WriteOptions.self)
let clipboard = UIPasteboard.general
switch options {
@ -30,7 +30,7 @@ class ClipboardPlugin: Plugin {
}
@objc public func read(_ invoke: Invoke) throws {
@objc public func readText(_ invoke: Invoke) throws {
let clipboard = UIPasteboard.general
if let text = clipboard.string {
invoke.resolve(ReadClipData.plainText(text: text))

@ -23,6 +23,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -0,0 +1,13 @@
# 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"]

@ -1,13 +0,0 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-read"
description = "Enables the read command without any pre-configured scope."
commands.allow = ["read"]
[[permission]]
identifier = "deny-read"
description = "Denies the read command without any pre-configured scope."
commands.deny = ["read"]

@ -0,0 +1,13 @@
# 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"]

@ -0,0 +1,13 @@
# 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"
description = "Enables the write command without any pre-configured scope."
commands.allow = ["write"]
[[permission]]
identifier = "deny-write"
description = "Denies the write command without any pre-configured scope."
commands.deny = ["write"]

@ -0,0 +1,13 @@
# 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"]

@ -0,0 +1,13 @@
# 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"]

@ -0,0 +1,13 @@
# 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"]

@ -1,6 +1,14 @@
| Permission | Description |
|------|-----|
|`allow-read`|Enables the read command without any pre-configured scope.|
|`deny-read`|Denies the read command without any pre-configured scope.|
|`allow-write`|Enables the write command without any pre-configured scope.|
|`deny-write`|Denies the write command without any pre-configured scope.|
|`allow-clear`|Enables the clear command without any pre-configured scope.|
|`deny-clear`|Denies the clear command without any pre-configured scope.|
|`allow-read-image`|Enables the read_image command without any pre-configured scope.|
|`deny-read-image`|Denies the read_image command without any pre-configured scope.|
|`allow-read-text`|Enables the read_text command without any pre-configured scope.|
|`deny-read-text`|Denies the read_text command without any pre-configured scope.|
|`allow-write-html`|Enables the write_html command without any pre-configured scope.|
|`deny-write-html`|Denies the write_html command without any pre-configured scope.|
|`allow-write-image`|Enables the write_image command without any pre-configured scope.|
|`deny-write-image`|Denies the write_image command without any pre-configured scope.|
|`allow-write-text`|Enables the write_text command without any pre-configured scope.|
|`deny-write-text`|Denies the write_text command without any pre-configured scope.|

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}
@ -299,31 +295,87 @@
"type": "string",
"oneOf": [
{
"description": "allow-read -> Enables the read command without any pre-configured scope.",
"description": "allow-clear -> Enables the clear command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-clear"
]
},
{
"description": "deny-clear -> Denies the clear command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-clear"
]
},
{
"description": "allow-read-image -> Enables the read_image command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-read-image"
]
},
{
"description": "deny-read-image -> Denies the read_image command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-read-image"
]
},
{
"description": "allow-read-text -> Enables the read_text command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-read-text"
]
},
{
"description": "deny-read-text -> Denies the read_text command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-read-text"
]
},
{
"description": "allow-write-html -> Enables the write_html command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-write-html"
]
},
{
"description": "deny-write-html -> Denies the write_html command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-write-html"
]
},
{
"description": "allow-write-image -> Enables the write_image command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-read"
"allow-write-image"
]
},
{
"description": "deny-read -> Denies the read command without any pre-configured scope.",
"description": "deny-write-image -> Denies the write_image command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-read"
"deny-write-image"
]
},
{
"description": "allow-write -> Enables the write command without any pre-configured scope.",
"description": "allow-write-text -> Enables the write_text command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-write"
"allow-write-text"
]
},
{
"description": "deny-write -> Denies the write command without any pre-configured scope.",
"description": "deny-write-text -> Denies the write_text command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-write"
"deny-write-text"
]
}
]

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

@ -2,25 +2,45 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use tauri::{command, AppHandle, Runtime, State};
use tauri::{command, AppHandle, Manager, ResourceId, Runtime, State};
use crate::{ClipKind, Clipboard, ClipboardContents, Result};
#[command]
pub(crate) async fn write<R: Runtime>(
pub(crate) async fn write_text<R: Runtime>(
_app: AppHandle<R>,
clipboard: State<'_, Clipboard<R>>,
data: ClipKind,
) -> Result<()> {
clipboard.write(data)
clipboard.write_text(data)
}
#[command]
pub(crate) async fn read<R: Runtime>(
pub(crate) async fn write_image<R: Runtime>(
_app: AppHandle<R>,
clipboard: State<'_, Clipboard<R>>,
data: ClipKind,
) -> Result<()> {
clipboard.write_image(data)
}
#[command]
pub(crate) async fn read_text<R: Runtime>(
_app: AppHandle<R>,
clipboard: State<'_, Clipboard<R>>,
) -> Result<ClipboardContents> {
clipboard.read()
clipboard.read_text()
}
#[command]
pub(crate) async fn read_image<R: Runtime>(
app: AppHandle<R>,
clipboard: State<'_, Clipboard<R>>,
) -> Result<ResourceId> {
let image = clipboard.read_image()?.to_owned();
let mut resources_table = app.resources_table();
let rid = resources_table.add(image);
Ok(rid)
}
#[command]

@ -2,12 +2,14 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use arboard::ImageData;
use image::ImageEncoder;
use serde::de::DeserializeOwned;
use tauri::{plugin::PluginApi, AppHandle, Runtime};
use tauri::{image::Image, plugin::PluginApi, AppHandle, Runtime};
use crate::models::*;
use std::sync::Mutex;
use std::{borrow::Cow, sync::Mutex};
pub fn init<R: Runtime, C: DeserializeOwned>(
app: &AppHandle<R>,
@ -27,17 +29,38 @@ pub struct Clipboard<R: Runtime> {
}
impl<R: Runtime> Clipboard<R> {
pub fn write(&self, kind: ClipKind) -> crate::Result<()> {
pub fn write_text(&self, kind: ClipKind) -> crate::Result<()> {
match kind {
ClipKind::PlainText { text, .. } => match &self.clipboard {
Ok(clipboard) => clipboard.lock().unwrap().set_text(text).map_err(Into::into),
Err(e) => Err(crate::Error::Clipboard(e.to_string())),
},
_ => Err(crate::Error::Clipboard("Invalid clip kind!".to_string())),
_ => Err(crate::Error::Clipboard("Invalid clip kind".to_string())),
}
}
pub fn write_image(&self, kind: ClipKind) -> crate::Result<()> {
match kind {
ClipKind::Image { image, .. } => match &self.clipboard {
Ok(clipboard) => {
let image = image.into_img(&self.app)?;
clipboard
.lock()
.unwrap()
.set_image(ImageData {
bytes: Cow::Borrowed(image.rgba()),
width: image.width() as usize,
height: image.height() as usize,
})
.map_err(Into::into)
}
Err(e) => Err(crate::Error::Clipboard(e.to_string())),
},
_ => Err(crate::Error::Clipboard("Invalid clip kind".to_string())),
}
}
pub fn read(&self) -> crate::Result<ClipboardContents> {
pub fn read_text(&self) -> crate::Result<ClipboardContents> {
match &self.clipboard {
Ok(clipboard) => {
let text = clipboard.lock().unwrap().get_text()?;
@ -67,4 +90,24 @@ impl<R: Runtime> Clipboard<R> {
Err(e) => Err(crate::Error::Clipboard(e.to_string())),
}
}
pub fn read_image(&self) -> crate::Result<Image<'_>> {
match &self.clipboard {
Ok(clipboard) => {
let image = clipboard.lock().unwrap().get_image()?;
let mut buffer: Vec<u8> = Vec::new();
image::codecs::png::PngEncoder::new(&mut buffer).write_image(
&image.bytes,
image.width as u32,
image.height as u32,
image::ColorType::Rgba8,
)?;
let image = Image::new_owned(buffer, image.width as u32, image.height as u32);
Ok(image)
}
Err(e) => Err(crate::Error::Clipboard(e.to_string())),
}
}
}

@ -13,6 +13,12 @@ pub enum Error {
PluginInvoke(#[from] tauri::plugin::mobile::PluginInvokeError),
#[error("{0}")]
Clipboard(String),
#[cfg(desktop)]
#[error(transparent)]
Tauri(#[from] tauri::Error),
#[cfg(desktop)]
#[error("invalid image: {0}")]
Image(#[from] image::ImageError),
}
impl Serialize for Error {

@ -50,11 +50,11 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("clipboard-manager")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![
commands::write,
commands::read,
#[cfg(desktop)]
commands::write_text,
commands::read_text,
commands::read_image,
commands::write_image,
commands::write_html,
#[cfg(desktop)]
commands::clear
])
.setup(|app, api| {

@ -4,6 +4,7 @@
use serde::de::DeserializeOwned;
use tauri::{
image::Image,
plugin::{PluginApi, PluginHandle},
AppHandle, Runtime,
};
@ -32,14 +33,26 @@ pub fn init<R: Runtime, C: DeserializeOwned>(
pub struct Clipboard<R: Runtime>(PluginHandle<R>);
impl<R: Runtime> Clipboard<R> {
pub fn write(&self, kind: ClipKind) -> crate::Result<()> {
pub fn write_text(&self, kind: ClipKind) -> crate::Result<()> {
self.0.run_mobile_plugin("write", kind).map_err(Into::into)
}
pub fn read(&self) -> crate::Result<ClipboardContents> {
pub fn write_image(&self, kind: ClipKind) -> crate::Result<()> {
Err(crate::Error::Clipboard(
"Unsupported on this platform".to_string(),
))
}
pub fn read_text(&self) -> crate::Result<ClipboardContents> {
self.0.run_mobile_plugin("read", ()).map_err(Into::into)
}
pub fn read_image(&self) -> crate::Result<Image<'_>> {
Err(crate::Error::Clipboard(
"Unsupported on this platform".to_string(),
))
}
// Treat HTML as unsupported on mobile until tested
pub fn write_html(&self, _kind: ClipKind) -> crate::Result<()> {
Err(crate::Error::Clipboard(

@ -4,13 +4,18 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
#[derive(Deserialize)]
#[cfg_attr(mobile, derive(Serialize))]
#[serde(rename_all = "camelCase")]
pub enum ClipKind {
PlainText {
label: Option<String>,
text: String,
},
#[cfg(desktop)]
Image {
image: tauri::image::JsImage,
},
Html {
html: String,
alt_html: Option<String>,
@ -20,5 +25,12 @@ pub enum ClipKind {
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum ClipboardContents {
PlainText { text: String },
PlainText {
text: String,
},
Image {
bytes: Vec<u8>,
width: usize,
height: usize,
},
}

@ -10,11 +10,11 @@
"tauri": "tauri"
},
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4",
"@tauri-apps/api": "2.0.0-beta.6",
"@tauri-apps/plugin-deep-link": "2.0.0-beta.2"
},
"devDependencies": {
"@tauri-apps/cli": "2.0.0-beta.7",
"@tauri-apps/cli": "2.0.0-beta.9",
"internal-ip": "^8.0.0",
"typescript": "^5.2.2",
"vite": "^5.0.12"

@ -24,6 +24,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -23,6 +23,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -24,6 +24,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -23,6 +23,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -23,6 +23,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -24,6 +24,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -27,6 +27,6 @@
"tslib": "2.6.0"
},
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -33,7 +33,6 @@ windows-version = { version = "0.1", optional = true }
[target."cfg(all(unix, not(target_os = \"macos\")))".dependencies]
lazy_static = { version = "1", optional = true }
image = { version = "0.24", optional = true }
zbus = { version = "4", optional = true }
log = "0.4"
env_logger = { version = "0.10", optional = true }

@ -23,6 +23,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -23,6 +23,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -24,6 +24,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -23,6 +23,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -23,6 +23,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -9,6 +9,6 @@
"author": "",
"license": "MIT",
"devDependencies": {
"@tauri-apps/cli": "2.0.0-beta.7"
"@tauri-apps/cli": "2.0.0-beta.9"
}
}

@ -24,6 +24,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -24,6 +24,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -24,6 +24,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -23,6 +23,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -24,6 +24,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -9,7 +9,7 @@
"preview": "vite preview"
},
"devDependencies": {
"@tauri-apps/cli": "2.0.0-beta.7",
"@tauri-apps/cli": "2.0.0-beta.9",
"typescript": "^5.3.3",
"vite": "^5.0.12"
},

@ -23,6 +23,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

@ -24,6 +24,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

@ -139,14 +139,10 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
"type": [
"array",
"null"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

File diff suppressed because one or more lines are too long

@ -64,8 +64,8 @@ importers:
examples/api:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
'@tauri-apps/plugin-barcode-scanner':
specifier: 2.0.0-beta.2
version: link:../../plugins/barcode-scanner
@ -122,8 +122,8 @@ importers:
specifier: ^3.0.1
version: 3.0.1(svelte@4.2.8)(vite@5.0.12)
'@tauri-apps/cli':
specifier: 2.0.0-beta.7
version: 2.0.0-beta.7
specifier: 2.0.0-beta.9
version: 2.0.0-beta.9
'@unocss/extractor-svelte':
specifier: ^0.58.0
version: 0.58.0
@ -135,7 +135,7 @@ importers:
version: 4.2.8
unocss:
specifier: ^0.58.0
version: 0.58.0(postcss@8.4.32)(vite@5.0.12)
version: 0.58.0(postcss@8.4.32)(rollup@4.9.6)(vite@5.0.12)
vite:
specifier: ^5.0.12
version: 5.0.12
@ -143,26 +143,26 @@ importers:
plugins/authenticator:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/autostart:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/barcode-scanner:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/biometric:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
devDependencies:
tslib:
specifier: 2.6.0
@ -171,33 +171,33 @@ importers:
plugins/cli:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/clipboard-manager:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/deep-link:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/deep-link/examples/app:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
'@tauri-apps/plugin-deep-link':
specifier: 2.0.0-beta.2
version: link:../..
devDependencies:
'@tauri-apps/cli':
specifier: 2.0.0-beta.7
version: 2.0.0-beta.7
specifier: 2.0.0-beta.9
version: 2.0.0-beta.9
internal-ip:
specifier: ^8.0.0
version: 8.0.0
@ -211,38 +211,38 @@ importers:
plugins/dialog:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/fs:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/global-shortcut:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/http:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/log:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/nfc:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
devDependencies:
tslib:
specifier: 2.6.0
@ -251,74 +251,74 @@ importers:
plugins/notification:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/os:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/positioner:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/process:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/shell:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/single-instance/examples/vanilla:
devDependencies:
'@tauri-apps/cli':
specifier: 2.0.0-beta.7
version: 2.0.0-beta.7
specifier: 2.0.0-beta.9
version: 2.0.0-beta.9
plugins/sql:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/store:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/stronghold:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/updater:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/upload:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/websocket:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
plugins/websocket/examples/tauri-app:
dependencies:
@ -327,8 +327,8 @@ importers:
version: link:../..
devDependencies:
'@tauri-apps/cli':
specifier: 2.0.0-beta.7
version: 2.0.0-beta.7
specifier: 2.0.0-beta.9
version: 2.0.0-beta.9
typescript:
specifier: ^5.3.3
version: 5.3.3
@ -339,8 +339,8 @@ importers:
plugins/window-state:
dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.4
version: 2.0.0-beta.4
specifier: 2.0.0-beta.6
version: 2.0.0-beta.6
packages:
@ -395,7 +395,7 @@ packages:
'@babel/traverse': 7.23.5
'@babel/types': 7.23.5
convert-source-map: 2.0.0
debug: 4.3.4
debug: 4.3.4(supports-color@8.1.1)
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 7.5.4
@ -665,7 +665,7 @@ packages:
'@babel/helper-split-export-declaration': 7.22.6
'@babel/parser': 7.23.5
'@babel/types': 7.23.5
debug: 4.3.4
debug: 4.3.4(supports-color@8.1.1)
globals: 11.12.0
transitivePeerDependencies:
- supports-color
@ -799,7 +799,7 @@ packages:
peerDependencies:
mocha: ^10.0.0
dependencies:
effection: 2.0.8
effection: 2.0.8(mocha@10.2.0)
mocha: 10.2.0
dev: true
@ -1046,7 +1046,7 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
ajv: 6.12.6
debug: 4.3.4
debug: 4.3.4(supports-color@8.1.1)
espree: 9.6.1
globals: 13.23.0
ignore: 5.3.0
@ -1068,7 +1068,7 @@ packages:
engines: {node: '>=10.10.0'}
dependencies:
'@humanwhocodes/object-schema': 2.0.1
debug: 4.3.4
debug: 4.3.4(supports-color@8.1.1)
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
@ -1109,7 +1109,7 @@ packages:
'@antfu/install-pkg': 0.1.1
'@antfu/utils': 0.7.6
'@iconify/types': 2.0.0
debug: 4.3.4
debug: 4.3.4(supports-color@8.1.1)
kolorist: 1.8.0
local-pkg: 0.4.3
transitivePeerDependencies:
@ -1225,20 +1225,6 @@ packages:
typescript: 5.3.3
dev: true
/@rollup/pluginutils@5.1.0:
resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
dependencies:
'@types/estree': 1.0.5
estree-walker: 2.0.2
picomatch: 2.3.1
dev: true
/@rollup/pluginutils@5.1.0(rollup@4.9.6):
resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
engines: {node: '>=14.0.0'}
@ -1463,7 +1449,7 @@ packages:
vite: ^5.0.0
dependencies:
'@sveltejs/vite-plugin-svelte': 3.0.1(svelte@4.2.8)(vite@5.0.12)
debug: 4.3.4
debug: 4.3.4(supports-color@8.1.1)
svelte: 4.2.8
vite: 5.0.12
transitivePeerDependencies:
@ -1478,7 +1464,7 @@ packages:
vite: ^5.0.0
dependencies:
'@sveltejs/vite-plugin-svelte-inspector': 2.0.0(@sveltejs/vite-plugin-svelte@3.0.1)(svelte@4.2.8)(vite@5.0.12)
debug: 4.3.4
debug: 4.3.4(supports-color@8.1.1)
deepmerge: 4.3.1
kleur: 4.1.5
magic-string: 0.30.5
@ -1490,13 +1476,13 @@ packages:
- supports-color
dev: true
/@tauri-apps/api@2.0.0-beta.4:
resolution: {integrity: sha512-Nxtj28NYUo5iwYkpYslxmOPkdI2WkELU2e3UH9nbJm9Ydki2CQwJVGQxx4EANtdZcMNsEsUzRqaDTvEUYH1l6w==}
/@tauri-apps/api@2.0.0-beta.6:
resolution: {integrity: sha512-ay3kAXYQoqC3rX4Vr3y6uGwrBhRPM7UQqZ9wr1VYzN6lkcMIcu7+UBvytmcfXDlVctqFoMQJafn6+dK/Oqh8+Q==}
engines: {node: '>= 18', npm: '>= 6.6.0', yarn: '>= 1.19.1'}
dev: false
/@tauri-apps/cli-darwin-arm64@2.0.0-beta.7:
resolution: {integrity: sha512-pwPkYEmIKRWbjxTCzPob67ecH8BrdYuE40chTRKudKCOgSahxW3oRHXnF8f7MU1pd34XpMG0vjwbETc0NA4DJw==}
/@tauri-apps/cli-darwin-arm64@2.0.0-beta.9:
resolution: {integrity: sha512-7OthLcko0Z2FUpP6fqJQhjaVKmxgXW6tWOi+X67HDjP1Iixquhh/vP5JqdSi7gYK8bphcegPp9UETuAgHx7MtA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
@ -1504,8 +1490,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-darwin-x64@2.0.0-beta.7:
resolution: {integrity: sha512-GP0u+CQxS9bRzxECtiFpAaEmhxibyCKRNhXVzbUwKkqbYtPKHnL5ZkppaQGZ+72aU+ezN2wyUGJM2JywGO6WrA==}
/@tauri-apps/cli-darwin-x64@2.0.0-beta.9:
resolution: {integrity: sha512-Pwf6GBGZuV9y7PEtaLQlzS3x91hFPkA0Ro8vaUxTirYkFiJFTgoigXDHjMsjfjy+E/8oAAHr7Z0zeA6ijR5t1w==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
@ -1513,8 +1499,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-linux-arm-gnueabihf@2.0.0-beta.7:
resolution: {integrity: sha512-oFMPnELZaXav3BzJimezP7gNxH44MHdBn2uOO1GkS8aV5P3GRBdu2xqwz2jr1awxfu0MAqTFj2ed9MsjiDDLhw==}
/@tauri-apps/cli-linux-arm-gnueabihf@2.0.0-beta.9:
resolution: {integrity: sha512-daAXSac82vbYlwxbRT0DwFr4gP4v1XnHEwA72EeKRiKGw7GeHwzqoY/URVolBGY7sIBwwL+0qc1hqPde9dsm1g==}
engines: {node: '>= 10'}
cpu: [arm]
os: [linux]
@ -1522,8 +1508,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-linux-arm64-gnu@2.0.0-beta.7:
resolution: {integrity: sha512-89MoAIRlIA8+qMpOEZZQ2+Q4LBUY1kwMGNS3mg5OJDU0+vSfNUkLr17Zvjwqizd/tVUp/vTWNWtSPthm8wliHQ==}
/@tauri-apps/cli-linux-arm64-gnu@2.0.0-beta.9:
resolution: {integrity: sha512-qHyACvFWIAbcl1C7cq64ciIXxaLOnZAgGXIEE48JLc5VeXkpYUF5sNLPjafidY/CxYoFoE453lh3dLc3DjNhuw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
@ -1531,8 +1517,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-linux-arm64-musl@2.0.0-beta.7:
resolution: {integrity: sha512-3TM4YapftA+VU555CQ8xxZhkcGDCGuJ+2X3qaHY4XEgC2viyke7MybbA6duHhb1HY64rZhSx6y5cqi9SE/AsSg==}
/@tauri-apps/cli-linux-arm64-musl@2.0.0-beta.9:
resolution: {integrity: sha512-DkrkxGKlQ1Sonvo4ltv6XqNxNuNxDyxfdZdvx3CEecKomMyFV6xTxp0/IcqF9fIRPL2Gp2PaPBWOuj+K8v95vw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
@ -1540,8 +1526,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-linux-x64-gnu@2.0.0-beta.7:
resolution: {integrity: sha512-+NbQOJheRZGTm5EF8h0y7JB1sW5qi1kTwqSCVeePJJStQX8QG2RmWdDbo44/PGLOwy8iJlGH/Tlo+ZaHuWtV9A==}
/@tauri-apps/cli-linux-x64-gnu@2.0.0-beta.9:
resolution: {integrity: sha512-pY0DOrWAwSkIkhw7UdRK0VNVFLwP+yltqCoQ+Zji5Vwk/x98mBo0L2bF3nSOLhYPAaW41v3AIOIZY1sBYWSq/w==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
@ -1549,8 +1535,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-linux-x64-musl@2.0.0-beta.7:
resolution: {integrity: sha512-1uDMC3Uh8yFWsKRkwrwLWY9pQ1uQ008lAimNedlGnuSJ3dW3SViNGbhdmvKw/lrXL24183ppGv2z/B6c/DydBg==}
/@tauri-apps/cli-linux-x64-musl@2.0.0-beta.9:
resolution: {integrity: sha512-GYQy1bKWbrRyr4X2epbltq82k4Vhr9TzNFky/fflOyDXlMP36IqBOjQ6PEzvKTajNglciIdTPQfdoUKX4+PA/Q==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
@ -1558,8 +1544,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-win32-arm64-msvc@2.0.0-beta.7:
resolution: {integrity: sha512-166jg+BfgFw22Hj0oZgU1ujWb5Gzf0+4p8L9Vuzu0Ne7U8flHfvlFpFKdf6uCa61cxS0sfmEnAi5r2Fh8VOA4w==}
/@tauri-apps/cli-win32-arm64-msvc@2.0.0-beta.9:
resolution: {integrity: sha512-0DTM06N/x57+vV/itT3l/34ZHjXIxPc315OWHE9MmY+vE37t/QFp9FNZDN/VdveZ1ZgmEn3rSQNchqcMaMdD3w==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
@ -1567,8 +1553,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-win32-ia32-msvc@2.0.0-beta.7:
resolution: {integrity: sha512-NuR1AkZlNwcu/Jv9qRKA0yguvJIW4aLEhZG6sWssMGhJGRzxZssZfHiBVfDCDQgfprbtOXXnshy7rFjNe0IEgA==}
/@tauri-apps/cli-win32-ia32-msvc@2.0.0-beta.9:
resolution: {integrity: sha512-HxrSAVjYRjPGm97lf18BvuoirgrE5uyvpALvGO98m8ZO9Y9CHklEadYi19nCVlr5d4mmP2GUbxCCx1Mc8XRAuA==}
engines: {node: '>= 10'}
cpu: [ia32]
os: [win32]
@ -1576,8 +1562,8 @@ packages:
dev: true
optional: true
/@tauri-apps/cli-win32-x64-msvc@2.0.0-beta.7:
resolution: {integrity: sha512-BVlwb6fRRCOaQPZWYIee8Z37NEHkceVmFDSQhrmLhF9E60/M09UCTrj0J5IOrDSj7t5/h5aWlYmDTASaJJRzKg==}
/@tauri-apps/cli-win32-x64-msvc@2.0.0-beta.9:
resolution: {integrity: sha512-abdCoiMjit9sSXziRCEf9VdEFbqqbEqg3ySOQmNAQTCsenr33iWjIoCMv/ThORtXKJ209yGyXlxBZY7Muxfi3A==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
@ -1585,21 +1571,21 @@ packages:
dev: true
optional: true
/@tauri-apps/cli@2.0.0-beta.7:
resolution: {integrity: sha512-ZaXvF46H+bSkP31C3ygFMhH3RAkdUnmxsGe5YKPublOnsWkyEvj9OLafBt2rTedF5Ko6HsIFqtgp4MqT9K9mHg==}
/@tauri-apps/cli@2.0.0-beta.9:
resolution: {integrity: sha512-QYBuCAAdV10tGOTMWGLbt6d+2+Tq8K9bb4oiinChUV/JmCNe9SaTlG6VW1cCJDf+/F0AuGOTgjyBNw8DOiTrow==}
engines: {node: '>= 10'}
hasBin: true
optionalDependencies:
'@tauri-apps/cli-darwin-arm64': 2.0.0-beta.7
'@tauri-apps/cli-darwin-x64': 2.0.0-beta.7
'@tauri-apps/cli-linux-arm-gnueabihf': 2.0.0-beta.7
'@tauri-apps/cli-linux-arm64-gnu': 2.0.0-beta.7
'@tauri-apps/cli-linux-arm64-musl': 2.0.0-beta.7
'@tauri-apps/cli-linux-x64-gnu': 2.0.0-beta.7
'@tauri-apps/cli-linux-x64-musl': 2.0.0-beta.7
'@tauri-apps/cli-win32-arm64-msvc': 2.0.0-beta.7
'@tauri-apps/cli-win32-ia32-msvc': 2.0.0-beta.7
'@tauri-apps/cli-win32-x64-msvc': 2.0.0-beta.7
'@tauri-apps/cli-darwin-arm64': 2.0.0-beta.9
'@tauri-apps/cli-darwin-x64': 2.0.0-beta.9
'@tauri-apps/cli-linux-arm-gnueabihf': 2.0.0-beta.9
'@tauri-apps/cli-linux-arm64-gnu': 2.0.0-beta.9
'@tauri-apps/cli-linux-arm64-musl': 2.0.0-beta.9
'@tauri-apps/cli-linux-x64-gnu': 2.0.0-beta.9
'@tauri-apps/cli-linux-x64-musl': 2.0.0-beta.9
'@tauri-apps/cli-win32-arm64-msvc': 2.0.0-beta.9
'@tauri-apps/cli-win32-ia32-msvc': 2.0.0-beta.9
'@tauri-apps/cli-win32-x64-msvc': 2.0.0-beta.9
dev: true
/@tauri-apps/toml@2.2.4:
@ -1652,7 +1638,7 @@ packages:
'@typescript-eslint/type-utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3)
'@typescript-eslint/utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 6.20.0
debug: 4.3.4
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.56.0
graphemer: 1.4.0
ignore: 5.3.0
@ -1678,7 +1664,7 @@ packages:
'@typescript-eslint/types': 6.20.0
'@typescript-eslint/typescript-estree': 6.20.0(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 6.20.0
debug: 4.3.4
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.56.0
typescript: 5.3.3
transitivePeerDependencies:
@ -1705,7 +1691,7 @@ packages:
dependencies:
'@typescript-eslint/typescript-estree': 6.20.0(typescript@5.3.3)
'@typescript-eslint/utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3)
debug: 4.3.4
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.56.0
ts-api-utils: 1.0.3(typescript@5.3.3)
typescript: 5.3.3
@ -1729,7 +1715,7 @@ packages:
dependencies:
'@typescript-eslint/types': 6.20.0
'@typescript-eslint/visitor-keys': 6.20.0
debug: 4.3.4
debug: 4.3.4(supports-color@8.1.1)
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.3
@ -1771,7 +1757,7 @@ packages:
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
dev: true
/@unocss/astro@0.58.0(vite@5.0.12):
/@unocss/astro@0.58.0(rollup@4.9.6)(vite@5.0.12):
resolution: {integrity: sha512-df+tEFO5eKXjQOwSWQhS9IdjD0sfLHLtn8U09sEKR2Nmh5CvpwyBxmvLQgOCilPou7ehmyKfsyGRLZg7IMp+Ew==}
peerDependencies:
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0
@ -1781,19 +1767,19 @@ packages:
dependencies:
'@unocss/core': 0.58.0
'@unocss/reset': 0.58.0
'@unocss/vite': 0.58.0(vite@5.0.12)
'@unocss/vite': 0.58.0(rollup@4.9.6)(vite@5.0.12)
vite: 5.0.12
transitivePeerDependencies:
- rollup
dev: true
/@unocss/cli@0.58.0:
/@unocss/cli@0.58.0(rollup@4.9.6):
resolution: {integrity: sha512-rhsrDBxAVueygMcAbMkbuvsHbBL2rG6N96LllYwHn16FLgOE3Sf4JW1/LlNjQje3BtwMMtbSCCAeu2SryFhzbw==}
engines: {node: '>=14'}
hasBin: true
dependencies:
'@ampproject/remapping': 2.2.1
'@rollup/pluginutils': 5.1.0
'@rollup/pluginutils': 5.1.0(rollup@4.9.6)
'@unocss/config': 0.58.0
'@unocss/core': 0.58.0
'@unocss/preset-uno': 0.58.0
@ -1969,13 +1955,13 @@ packages:
'@unocss/core': 0.58.0
dev: true
/@unocss/vite@0.58.0(vite@5.0.12):
/@unocss/vite@0.58.0(rollup@4.9.6)(vite@5.0.12):
resolution: {integrity: sha512-OCUOLMSOBEtXOEyBbAvMI3/xdR175BWRzmvV9Wc34ANZclEvCdVH8+WU725ibjY4VT0gVIuX68b13fhXdHV41A==}
peerDependencies:
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0
dependencies:
'@ampproject/remapping': 2.2.1
'@rollup/pluginutils': 5.1.0
'@rollup/pluginutils': 5.1.0(rollup@4.9.6)
'@unocss/config': 0.58.0
'@unocss/core': 0.58.0
'@unocss/inspector': 0.58.0
@ -2478,18 +2464,6 @@ packages:
ms: 2.1.3
dev: true
/debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
dependencies:
ms: 2.1.2
dev: true
/debug@4.3.4(supports-color@8.1.1):
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
@ -2590,18 +2564,6 @@ packages:
resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
dev: true
/effection@2.0.8:
resolution: {integrity: sha512-/v7cbPIXGGylInQgHHjJutzqUn6VIfcP13hh2X0hXf04wwAlSI+lVjUBKpr5TX3+v9dXV/JLHO/pqQ9Cp1QAnQ==}
dependencies:
'@effection/channel': 2.0.6
'@effection/core': 2.2.3
'@effection/events': 2.0.6
'@effection/fetch': 2.0.7(mocha@10.2.0)
'@effection/main': 2.1.2
'@effection/stream': 2.0.6
'@effection/subscription': 2.0.6
dev: true
/effection@2.0.8(mocha@10.2.0):
resolution: {integrity: sha512-/v7cbPIXGGylInQgHHjJutzqUn6VIfcP13hh2X0hXf04wwAlSI+lVjUBKpr5TX3+v9dXV/JLHO/pqQ9Cp1QAnQ==}
dependencies:
@ -2944,7 +2906,7 @@ packages:
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
debug: 4.3.4
debug: 4.3.4(supports-color@8.1.1)
doctrine: 3.0.0
escape-string-regexp: 4.0.0
eslint-scope: 7.2.2
@ -3866,7 +3828,7 @@ packages:
/micromark@2.11.4:
resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==}
dependencies:
debug: 4.3.4
debug: 4.3.4(supports-color@8.1.1)
parse-entities: 2.0.0
transitivePeerDependencies:
- supports-color
@ -4893,7 +4855,7 @@ packages:
'@types/unist': 2.0.10
dev: true
/unocss@0.58.0(postcss@8.4.32)(vite@5.0.12):
/unocss@0.58.0(postcss@8.4.32)(rollup@4.9.6)(vite@5.0.12):
resolution: {integrity: sha512-MSPRHxBqWN+1AHGV+J5uUy4//e6ZBK6O+ISzD0qrXcCD/GNtxk1+lYjOK2ltkUiKX539+/KF91vNxzhhwEf+xA==}
engines: {node: '>=14'}
peerDependencies:
@ -4905,8 +4867,8 @@ packages:
vite:
optional: true
dependencies:
'@unocss/astro': 0.58.0(vite@5.0.12)
'@unocss/cli': 0.58.0
'@unocss/astro': 0.58.0(rollup@4.9.6)(vite@5.0.12)
'@unocss/cli': 0.58.0(rollup@4.9.6)
'@unocss/core': 0.58.0
'@unocss/extractor-arbitrary-variants': 0.58.0
'@unocss/postcss': 0.58.0(postcss@8.4.32)
@ -4924,7 +4886,7 @@ packages:
'@unocss/transformer-compile-class': 0.58.0
'@unocss/transformer-directives': 0.58.0
'@unocss/transformer-variant-group': 0.58.0
'@unocss/vite': 0.58.0(vite@5.0.12)
'@unocss/vite': 0.58.0(rollup@4.9.6)(vite@5.0.12)
vite: 5.0.12
transitivePeerDependencies:
- postcss

@ -23,6 +23,6 @@
"LICENSE"
],
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.4"
"@tauri-apps/api": "2.0.0-beta.6"
}
}

Loading…
Cancel
Save