mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-08-05 18:18:37 +02:00
Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01198111d1 | ||
|
|
f8053e659e | ||
|
|
19fb3926fd | ||
|
|
2371be839f | ||
|
|
e215ff90d3 | ||
|
|
ba89f32eb0 | ||
|
|
cc9ec9b4ad | ||
|
|
dc7f87bc7e | ||
|
|
304292d740 | ||
|
|
622f02bf21 | ||
|
|
abc903c240 | ||
|
|
ab7489c964 | ||
|
|
3fb27bf13a | ||
|
|
7e45774610 | ||
|
|
526726162f |
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"deep-link": patch
|
||||
"deep-link-js": patch
|
||||
---
|
||||
|
||||
adds proper Platform-specific sections to the docs for `register`, `unregister`, `isRegistered`, and `onOpenUrl`
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"dialog": patch
|
||||
"dialog-js": patch
|
||||
---
|
||||
|
||||
Fix Android save dialog MIME type when a single MIME type is provided.
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
"dialog": patch
|
||||
"dialog-js": patch
|
||||
"fs": patch
|
||||
"fs-js": patch
|
||||
"geolocation": patch
|
||||
"geolocation-js": patch
|
||||
"haptics": patch
|
||||
"haptics-js": patch
|
||||
"http": patch
|
||||
"http-js": patch
|
||||
"log": patch
|
||||
"log-js": patch
|
||||
"persisted-scope": patch
|
||||
"positioner": patch
|
||||
"positioner-js": patch
|
||||
"single-instance": patch
|
||||
"sql": patch
|
||||
"sql-js": patch
|
||||
"stronghold": patch
|
||||
"stronghold-js": patch
|
||||
"updater": patch
|
||||
"updater-js": patch
|
||||
"upload": patch
|
||||
"upload-js": patch
|
||||
"websocket": patch
|
||||
"websocket-js": patch
|
||||
---
|
||||
|
||||
Documented Cargo feature flags in each plugin's crate-level documentation.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"fs": patch
|
||||
"fs-js": patch
|
||||
---
|
||||
|
||||
Fixed `deny-webview-data` has no effect
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"http": minor
|
||||
"http-js": minor
|
||||
---
|
||||
|
||||
Added `system-proxy` feature to replace the old `macos-system-configuration` feature flag to match the new reqwest API.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
nfc: patch
|
||||
nfc-js: patch
|
||||
---
|
||||
|
||||
Expect a `NFCTag` as input and return a `ScanResponse` in the `scan` function.
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
notification: minor
|
||||
notification-js: minor
|
||||
---
|
||||
|
||||
- Add Rust builders for mobile notification action types.
|
||||
- Fix Android action-group entries being stored under the action type ID instead of sequential indices, causing later actions to overwrite earlier ones.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"updater": patch
|
||||
"updater-js": patch
|
||||
---
|
||||
|
||||
On Windows, returns an error if failed to spawn the installer in `install` through `ShellExecuteW`
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"updater": minor
|
||||
"updater-js": minor
|
||||
---
|
||||
|
||||
On Windows, add a new option `restartAfterInstall`/`restart_after_install` to install an update without the installer re-launching the app
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"updater": minor
|
||||
"updater-js": minor
|
||||
---
|
||||
|
||||
Added `system-proxy` (enabled by default) feature flag to control `reqwest/system-proxy` feature (Use Windows and macOS system proxy settings automatically)
|
||||
@@ -15,7 +15,7 @@
|
||||
"@tauri-apps/plugin-biometric": "workspace:*",
|
||||
"@tauri-apps/plugin-cli": "workspace:*",
|
||||
"@tauri-apps/plugin-clipboard-manager": "workspace:*",
|
||||
"@tauri-apps/plugin-dialog": "2",
|
||||
"@tauri-apps/plugin-dialog": "workspace:*",
|
||||
"@tauri-apps/plugin-fs": "workspace:*",
|
||||
"@tauri-apps/plugin-geolocation": "workspace:*",
|
||||
"@tauri-apps/plugin-global-shortcut": "workspace:*",
|
||||
@@ -27,10 +27,10 @@
|
||||
"@tauri-apps/plugin-os": "workspace:*",
|
||||
"@tauri-apps/plugin-process": "workspace:*",
|
||||
"@tauri-apps/plugin-shell": "workspace:*",
|
||||
"@tauri-apps/plugin-store": "2",
|
||||
"@tauri-apps/plugin-store": "workspace:*",
|
||||
"@tauri-apps/plugin-updater": "workspace:*",
|
||||
"@tauri-apps/plugin-upload": "workspace:*",
|
||||
"@zerodevx/svelte-json-view": "1.0.11"
|
||||
"@zerodevx/svelte-json-view": "2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/codicon": "^1.2.49",
|
||||
@@ -38,8 +38,8 @@
|
||||
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
||||
"@tauri-apps/cli": "2.11.4",
|
||||
"@unocss/extractor-svelte": "^66.6.7",
|
||||
"svelte": "^5.54.0",
|
||||
"svelte": "^5.55.7",
|
||||
"unocss": "^66.6.7",
|
||||
"vite": "^8.0.1"
|
||||
"vite": "^8.0.16"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,3 @@ tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.3.5" }
|
||||
tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.3.2" }
|
||||
tauri-plugin-geolocation = { path = "../../../plugins/geolocation/", version = "2.3.2" }
|
||||
tauri-plugin-haptics = { path = "../../../plugins/haptics/", version = "2.3.2" }
|
||||
|
||||
[features]
|
||||
prod = ["tauri/custom-protocol"]
|
||||
|
||||
@@ -77,7 +77,9 @@
|
||||
},
|
||||
"updater": {
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDE5QzMxNjYwNTM5OEUwNTgKUldSWTRKaFRZQmJER1h4d1ZMYVA3dnluSjdpN2RmMldJR09hUFFlZDY0SlFqckkvRUJhZDJVZXAK",
|
||||
"dangerousInsecureTransportProtocol": true,
|
||||
"endpoints": [
|
||||
"http://localhost:5173/updater-test/updater.json",
|
||||
"https://tauri-update-server.vercel.app/update/{{target}}/{{current_version}}"
|
||||
]
|
||||
}
|
||||
@@ -99,6 +101,9 @@
|
||||
"localePath": "locales/pt-BR.wxl"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nsis": {
|
||||
"compression": "none"
|
||||
}
|
||||
},
|
||||
"iOS": {
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
<script>
|
||||
import { check } from '@tauri-apps/plugin-updater'
|
||||
<script lang="ts">
|
||||
import { check, Update } from '@tauri-apps/plugin-updater'
|
||||
import { relaunch } from '@tauri-apps/plugin-process'
|
||||
import { onDestroy } from 'svelte'
|
||||
|
||||
export let onMessage
|
||||
let { onMessage } = $props()
|
||||
|
||||
let isChecking, isInstalling, newUpdate
|
||||
let totalSize = 0,
|
||||
downloadedSize = 0
|
||||
let isChecking = $state(false)
|
||||
let isInstalling = $state(false)
|
||||
let newUpdate = $state<Update | undefined>()
|
||||
let totalSize = $state(0)
|
||||
let downloadedSize = $state(0)
|
||||
let progress = $derived(
|
||||
totalSize ? Math.round((downloadedSize / totalSize) * 100) : 0
|
||||
)
|
||||
|
||||
async function checkUpdate() {
|
||||
isChecking = true
|
||||
@@ -31,10 +37,10 @@
|
||||
isInstalling = true
|
||||
downloadedSize = 0
|
||||
try {
|
||||
await newUpdate.downloadAndInstall((downloadProgress) => {
|
||||
await newUpdate!.downloadAndInstall((downloadProgress) => {
|
||||
switch (downloadProgress.event) {
|
||||
case 'Started':
|
||||
totalSize = downloadProgress.data.contentLength
|
||||
totalSize = downloadProgress.data.contentLength!
|
||||
break
|
||||
case 'Progress':
|
||||
downloadedSize += downloadProgress.data.chunkLength
|
||||
@@ -54,14 +60,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: progress = totalSize ? Math.round((downloadedSize / totalSize) * 100) : 0
|
||||
onDestroy(() => {
|
||||
newUpdate?.close()
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="flex children:grow children:h10">
|
||||
{#if !isChecking && !newUpdate}
|
||||
<button class="btn" on:click={checkUpdate}>Check update</button>
|
||||
<button class="btn" onclick={checkUpdate}>Check update</button>
|
||||
{:else if !isInstalling && newUpdate}
|
||||
<button class="btn" on:click={install}>Install update</button>
|
||||
<button class="btn" onclick={install}>Install update</button>
|
||||
{:else}
|
||||
<div class="progress">
|
||||
<span>{progress}%</span>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
*
|
||||
|
||||
!.gitignore
|
||||
!README.md
|
||||
!updater.json
|
||||
@@ -0,0 +1,10 @@
|
||||
To test the updater:
|
||||
|
||||
1. Comment out `verify_signature` inside `plugins/updater/src/updater.rs`
|
||||
2. Run `pnpm tauri build --debug` to build the bundles
|
||||
3. Copy the bundle you want to test to this folder (`examples/api/updater-test/`)
|
||||
4. Run `pnpm tauri dev` and open the Updater tab to check
|
||||
|
||||
If the bundle you're testing doesn't exist in the `updater.json` yet, add it manually and welcome to open an PR
|
||||
|
||||
> The `updater.json` and debug bundles will be served by `vite`
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "2.1.0",
|
||||
"notes": "Test update!",
|
||||
"pub_date": "2026-03-01T14:04:20+00:00",
|
||||
"platforms": {
|
||||
"windows-x86_64": {
|
||||
"signature": "",
|
||||
"url": "http://localhost:5173/updater-test/Tauri API_2.0.0_x64_en-US.msi"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ export default defineConfig(async () => {
|
||||
port: 5173,
|
||||
strictPort: true,
|
||||
fs: {
|
||||
allow: ['.', '../../tooling/api/dist']
|
||||
allow: ['.']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -19,11 +19,11 @@
|
||||
"eslint-config-prettier": "10.1.8",
|
||||
"eslint-plugin-security": "4.0.1",
|
||||
"prettier": "3.8.3",
|
||||
"rollup": "4.60.3",
|
||||
"rollup": "4.62.2",
|
||||
"tslib": "2.8.1",
|
||||
"typescript": "6.0.3",
|
||||
"typescript-eslint": "8.58.2"
|
||||
},
|
||||
"minimumReleaseAge": 4320,
|
||||
"packageManager": "pnpm@11.13.0"
|
||||
"packageManager": "pnpm@11.20.0"
|
||||
}
|
||||
|
||||
@@ -8,6 +8,13 @@ edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-autostart"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
@@ -161,7 +161,7 @@ impl Builder {
|
||||
///
|
||||
/// ```no_run
|
||||
/// Builder::new()
|
||||
/// .app_name("My Custom Name"))
|
||||
/// .app_name("My Custom Name")
|
||||
/// .build();
|
||||
/// ```
|
||||
pub fn app_name<S: Into<String>>(mut self, app_name: S) -> Self {
|
||||
|
||||
@@ -8,7 +8,13 @@ license = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-barcode-scanner"
|
||||
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-linux-android"]
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ authors = { workspace = true }
|
||||
license = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-biometric"
|
||||
exclude = ["/guest-js", "/package.json", "/rollup.config.js", "/tsconfig.json"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-linux-android"]
|
||||
|
||||
@@ -8,6 +8,13 @@ license = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-cli"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
@@ -8,6 +8,13 @@ license = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-clipboard-manager"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
|
||||
|
||||
@@ -8,6 +8,14 @@ edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-deep-link"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/examples",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-linux-android"]
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "2.11.4",
|
||||
"typescript": "^6.0.0",
|
||||
"vite": "^8.0.1"
|
||||
"typescript": "^6.0.3",
|
||||
"vite": "^8.0.16"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,3 @@ tauri-plugin-single-instance = { path = "../../../../single-instance", features
|
||||
"deep-link",
|
||||
] }
|
||||
log = "0.4"
|
||||
|
||||
[features]
|
||||
# this feature is used for production builds or when `devUrl` points to the filesystem and the built-in dev server is disabled.
|
||||
# If you use cargo directly instead of tauri's cli you can use this feature flag to switch between tauri's `dev` and `build` modes.
|
||||
# DO NOT REMOVE!!
|
||||
prod = ["tauri/custom-protocol"]
|
||||
|
||||
@@ -14,9 +14,11 @@ import { type UnlistenFn, listen } from '@tauri-apps/api/event'
|
||||
* const urls = await getCurrent();
|
||||
* ```
|
||||
*
|
||||
* #### - **Windows / Linux**: This function reads the command line arguments and checks if there's only one value, which must be an URL with scheme matching one of the configured values.
|
||||
* Note that you must manually check the arguments when registering deep link schemes dynamically with [`Self::register`].
|
||||
* Additionally, the deep link might have been provided as a CLI argument so you should check if its format matches what you expect..
|
||||
* #### Platform-specific
|
||||
*
|
||||
* - **Windows / Linux:** This function reads the command line arguments and checks if there's only one value, which must be an URL with scheme matching one of the configured values.
|
||||
* Note that you must manually check the arguments when registering deep link schemes dynamically with [`Self::register`].
|
||||
* Additionally, the deep link might have been provided as a CLI argument so you should check if its format matches what you expect.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@@ -35,7 +37,9 @@ export async function getCurrent(): Promise<string[] | null> {
|
||||
* await register("my-scheme");
|
||||
* ```
|
||||
*
|
||||
* #### - **macOS / Android / iOS**: Unsupported.
|
||||
* #### Platform-specific
|
||||
*
|
||||
* - **macOS / Android / iOS:** Unsupported.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@@ -54,7 +58,9 @@ export async function register(protocol: string): Promise<null> {
|
||||
* await unregister("my-scheme");
|
||||
* ```
|
||||
*
|
||||
* #### - **macOS / Linux / Android / iOS**: Unsupported.
|
||||
* #### Platform-specific
|
||||
*
|
||||
* - **macOS / Linux / Android / iOS:** Unsupported.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@@ -73,7 +79,9 @@ export async function unregister(protocol: string): Promise<null> {
|
||||
* await isRegistered("my-scheme");
|
||||
* ```
|
||||
*
|
||||
* #### - **macOS / Android / iOS**: Unsupported.
|
||||
* #### Platform-specific
|
||||
*
|
||||
* - **macOS / Android / iOS:** Unsupported.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@@ -92,7 +100,9 @@ export async function isRegistered(protocol: string): Promise<boolean> {
|
||||
* await onOpenUrl((urls) => { console.log(urls) });
|
||||
* ```
|
||||
*
|
||||
* #### - **Windows / Linux**: Unsupported without the single-instance plugin. The OS will spawn a new app instance passing the URL as a CLI argument.
|
||||
* #### Platform-specific
|
||||
*
|
||||
* - **Windows / Linux:** Unsupported without the single-instance plugin. The OS will spawn a new app instance passing the URL as a CLI argument.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,14 @@ license = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-dialog"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/test",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[features]
|
||||
default = ["gtk3"]
|
||||
|
||||
@@ -204,9 +204,10 @@ class DialogPlugin(private val activity: Activity): Plugin(activity) {
|
||||
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
intent.putExtra(Intent.EXTRA_TITLE, args.fileName ?: "")
|
||||
intent.type = "*/*"
|
||||
|
||||
if (parsedTypes.isNotEmpty()) {
|
||||
if (parsedTypes.size == 1) {
|
||||
intent.type = parsedTypes.first()
|
||||
} else {
|
||||
intent.type = "*/*"
|
||||
intent.putExtra(Intent.EXTRA_MIME_TYPES, parsedTypes)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Native system dialogs for opening and saving files along with message dialogs.
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! - **gtk3** *(enabled by default)*: Uses GTK for dialogs on Linux & BSDs; has no effect on Windows and macOS
|
||||
//! - **xdg-portal**: Uses XDG Desktop Portal instead of GTK on Linux & BSDs
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
|
||||
@@ -8,6 +8,13 @@ edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-fs"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "Apps installed via MSI or NSIS in `perMachine` and `both` mode require admin permissions for write access in `$RESOURCES` folder" }
|
||||
|
||||
@@ -6,7 +6,7 @@ description = """This denies read access to the
|
||||
`$APPLOCALDATA` folder on linux as the webview data and configuration values are stored here.
|
||||
Allowing access can lead to sensitive information disclosure and should be well considered."""
|
||||
|
||||
[[scope.deny]]
|
||||
[[permission.scope.deny]]
|
||||
path = "$APPLOCALDATA/**"
|
||||
|
||||
[[permission]]
|
||||
@@ -15,5 +15,5 @@ description = """This denies read access to the
|
||||
`$APPLOCALDATA/EBWebView` folder on windows as the webview data and configuration values are stored here.
|
||||
Allowing access can lead to sensitive information disclosure and should be well considered."""
|
||||
|
||||
[[scope.deny]]
|
||||
[[permission.scope.deny]]
|
||||
path = "$APPLOCALDATA/EBWebView/**"
|
||||
|
||||
+106
-109
@@ -74,7 +74,7 @@ pub type CommandResult<T> = std::result::Result<T, CommandError>;
|
||||
/// Represents either a plain PathBuf or a PathHandle that manages security-scoped resources.
|
||||
pub enum PathKind<R: Runtime> {
|
||||
/// A plain path that doesn't manage security-scoped resources.
|
||||
#[allow(dead_code)] // only used on mobile
|
||||
#[cfg(mobile)] // only used on mobile
|
||||
Path(PathBuf),
|
||||
/// A path handle that manages security-scoped resources and will clean them up on drop.
|
||||
Handle(PathHandle<R>),
|
||||
@@ -84,6 +84,7 @@ impl<R: Runtime> PathKind<R> {
|
||||
/// Get a reference to the underlying path.
|
||||
pub fn as_path(&self) -> &Path {
|
||||
match self {
|
||||
#[cfg(mobile)]
|
||||
PathKind::Path(p) => p.as_ref(),
|
||||
PathKind::Handle(h) => h.as_ref(),
|
||||
}
|
||||
@@ -92,6 +93,7 @@ impl<R: Runtime> PathKind<R> {
|
||||
/// Get a reference to the underlying PathBuf.
|
||||
pub fn as_path_buf(&self) -> &PathBuf {
|
||||
match self {
|
||||
#[cfg(mobile)]
|
||||
PathKind::Path(p) => p,
|
||||
PathKind::Handle(h) => h,
|
||||
}
|
||||
@@ -114,27 +116,13 @@ impl<R: Runtime> AsRef<PathBuf> for PathKind<R> {
|
||||
pub struct FileHandle<R: Runtime> {
|
||||
file: File,
|
||||
path: PathKind<R>,
|
||||
#[allow(dead_code)] // Used in Drop implementation
|
||||
#[cfg(target_os = "ios")]
|
||||
path_: SafeFilePath,
|
||||
#[allow(dead_code)] // Used in Drop implementation
|
||||
#[cfg(target_os = "ios")]
|
||||
app_handle: tauri::AppHandle<R>,
|
||||
}
|
||||
|
||||
impl<R: Runtime> FileHandle<R> {
|
||||
fn new(
|
||||
file: File,
|
||||
path: PathKind<R>,
|
||||
path_: SafeFilePath,
|
||||
app_handle: tauri::AppHandle<R>,
|
||||
) -> Self {
|
||||
Self {
|
||||
file,
|
||||
path,
|
||||
path_,
|
||||
app_handle,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the resolved path.
|
||||
pub fn path(&self) -> &Path {
|
||||
self.path.as_path()
|
||||
@@ -155,41 +143,39 @@ impl<R: Runtime> DerefMut for FileHandle<R> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
impl<R: Runtime> Drop for FileHandle<R> {
|
||||
fn drop(&mut self) {
|
||||
#[cfg(target_os = "ios")]
|
||||
{
|
||||
// Only clean up if we have a plain PathBuf, not a PathHandle
|
||||
// PathHandle will handle its own cleanup when it's dropped
|
||||
if let PathKind::Path(_) = &self.path {
|
||||
use crate::{FilePath, FsExt};
|
||||
// Convert SafeFilePath to FilePath
|
||||
let file_path: FilePath = match &self.path_ {
|
||||
SafeFilePath::Url(url) => FilePath::Url(url.clone()),
|
||||
SafeFilePath::Path(safe_path) => FilePath::Path(safe_path.as_ref().to_owned()),
|
||||
};
|
||||
// Only clean up if we have a plain PathBuf, not a PathHandle
|
||||
// PathHandle will handle its own cleanup when it's dropped
|
||||
if let PathKind::Path(_) = &self.path {
|
||||
use crate::{FilePath, FsExt};
|
||||
// Convert SafeFilePath to FilePath
|
||||
let file_path: FilePath = match &self.path_ {
|
||||
SafeFilePath::Url(url) => FilePath::Url(url.clone()),
|
||||
SafeFilePath::Path(safe_path) => FilePath::Path(safe_path.as_ref().to_owned()),
|
||||
};
|
||||
|
||||
// Only clean up if we're tracking this resource
|
||||
// If start_accessing_security_scoped_resource was used, it won't be in our tracking
|
||||
// and we shouldn't interfere
|
||||
if let FilePath::Url(url) = file_path {
|
||||
if url.scheme() == "file" {
|
||||
let security_scoped_resources =
|
||||
self.app_handle.state::<crate::SecurityScopedResources>();
|
||||
// Only clean up if we're tracking this resource
|
||||
// If start_accessing_security_scoped_resource was used, it won't be in our tracking
|
||||
// and we shouldn't interfere
|
||||
if let FilePath::Url(url) = file_path {
|
||||
if url.scheme() == "file" {
|
||||
let security_scoped_resources =
|
||||
self.app_handle.state::<crate::SecurityScopedResources>();
|
||||
|
||||
// Only clean up if it's not tracked manually
|
||||
if !security_scoped_resources.is_tracked_manually(url.as_str()) {
|
||||
log::debug!("Stopping accessing security-scoped resource for URL: {url} on drop");
|
||||
let _ = self
|
||||
.app_handle
|
||||
.fs()
|
||||
.stop_accessing_security_scoped_resource(FilePath::Url(
|
||||
url.clone(),
|
||||
));
|
||||
security_scoped_resources.remove(url.as_str());
|
||||
} else {
|
||||
log::debug!("Not cleaning up security-scoped resource for URL: {url} on drop (manually tracked via start_accessing_security_scoped_resource)");
|
||||
}
|
||||
// Only clean up if it's not tracked manually
|
||||
if !security_scoped_resources.is_tracked_manually(url.as_str()) {
|
||||
log::debug!(
|
||||
"Stopping accessing security-scoped resource for URL: {url} on drop"
|
||||
);
|
||||
let _ = self
|
||||
.app_handle
|
||||
.fs()
|
||||
.stop_accessing_security_scoped_resource(FilePath::Url(url.clone()));
|
||||
security_scoped_resources.remove(url.as_str());
|
||||
} else {
|
||||
log::debug!("Not cleaning up security-scoped resource for URL: {url} on drop (manually tracked via start_accessing_security_scoped_resource)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,38 +222,36 @@ impl<R: Runtime> AsRef<PathBuf> for PathHandle<R> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
impl<R: Runtime> Drop for PathHandle<R> {
|
||||
fn drop(&mut self) {
|
||||
#[cfg(target_os = "ios")]
|
||||
{
|
||||
use crate::{FilePath, FsExt};
|
||||
// Convert SafeFilePath to FilePath
|
||||
let file_path: FilePath = match &self.path_ {
|
||||
SafeFilePath::Url(url) => FilePath::Url(url.clone()),
|
||||
SafeFilePath::Path(safe_path) => FilePath::Path(safe_path.as_ref().to_owned()),
|
||||
};
|
||||
use crate::{FilePath, FsExt};
|
||||
// Convert SafeFilePath to FilePath
|
||||
let file_path: FilePath = match &self.path_ {
|
||||
SafeFilePath::Url(url) => FilePath::Url(url.clone()),
|
||||
SafeFilePath::Path(safe_path) => FilePath::Path(safe_path.as_ref().to_owned()),
|
||||
};
|
||||
|
||||
// Only clean up if we're tracking this resource (i.e., resolve_path started it)
|
||||
// If start_accessing_security_scoped_resource was used, it won't be in our tracking
|
||||
// and we shouldn't interfere
|
||||
if let FilePath::Url(url) = file_path {
|
||||
if url.scheme() == "file" {
|
||||
let security_scoped_resources =
|
||||
self.app_handle.state::<crate::SecurityScopedResources>();
|
||||
// Only clean up if we're tracking this resource (i.e., resolve_path started it)
|
||||
// If start_accessing_security_scoped_resource was used, it won't be in our tracking
|
||||
// and we shouldn't interfere
|
||||
if let FilePath::Url(url) = file_path {
|
||||
if url.scheme() == "file" {
|
||||
let security_scoped_resources =
|
||||
self.app_handle.state::<crate::SecurityScopedResources>();
|
||||
|
||||
// Only clean up if it's not tracked manually
|
||||
if !security_scoped_resources.is_tracked_manually(url.as_str()) {
|
||||
log::debug!(
|
||||
"Stopping accessing security-scoped resource for URL: {url} on drop"
|
||||
);
|
||||
let _ = self
|
||||
.app_handle
|
||||
.fs()
|
||||
.stop_accessing_security_scoped_resource(FilePath::Url(url.clone()));
|
||||
security_scoped_resources.remove(url.as_str());
|
||||
} else {
|
||||
log::debug!("Not cleaning up security-scoped resource for URL: {url} on drop (manually tracked via start_accessing_security_scoped_resource)");
|
||||
}
|
||||
// Only clean up if it's not tracked manually
|
||||
if !security_scoped_resources.is_tracked_manually(url.as_str()) {
|
||||
log::debug!(
|
||||
"Stopping accessing security-scoped resource for URL: {url} on drop"
|
||||
);
|
||||
let _ = self
|
||||
.app_handle
|
||||
.fs()
|
||||
.stop_accessing_security_scoped_resource(FilePath::Url(url.clone()));
|
||||
security_scoped_resources.remove(url.as_str());
|
||||
} else {
|
||||
log::debug!("Not cleaning up security-scoped resource for URL: {url} on drop (manually tracked via start_accessing_security_scoped_resource)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -288,6 +272,7 @@ pub fn create<R: Runtime>(
|
||||
path: SafeFilePath,
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<ResourceId> {
|
||||
#[cfg(target_os = "ios")]
|
||||
let path_ = path.clone();
|
||||
let resolved_path_handle = resolve_path(
|
||||
"create",
|
||||
@@ -303,13 +288,16 @@ pub fn create<R: Runtime>(
|
||||
resolved_path_handle.display()
|
||||
)
|
||||
})?;
|
||||
#[cfg(target_os = "ios")]
|
||||
let app_handle = webview.app_handle().clone();
|
||||
let file_handle = FileHandle::new(
|
||||
let file_handle = FileHandle {
|
||||
file,
|
||||
PathKind::Handle(resolved_path_handle),
|
||||
path: PathKind::Handle(resolved_path_handle),
|
||||
#[cfg(target_os = "ios")]
|
||||
path_,
|
||||
#[cfg(target_os = "ios")]
|
||||
app_handle,
|
||||
);
|
||||
};
|
||||
let rid = webview
|
||||
.resources_table()
|
||||
.add(StdFileResource::new(file_handle));
|
||||
@@ -1417,6 +1405,7 @@ fn resolve_file_in_fs<R: Runtime>(
|
||||
path: SafeFilePath,
|
||||
open_options: OpenOptions,
|
||||
) -> CommandResult<FileHandle<R>> {
|
||||
#[cfg(target_os = "ios")]
|
||||
let path_ = path.clone();
|
||||
let resolved_path_handle = resolve_path(
|
||||
permission,
|
||||
@@ -1436,13 +1425,16 @@ fn resolve_file_in_fs<R: Runtime>(
|
||||
)
|
||||
})?;
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
let app_handle = webview.app_handle().clone();
|
||||
Ok(FileHandle::new(
|
||||
Ok(FileHandle {
|
||||
file,
|
||||
PathKind::Handle(resolved_path_handle),
|
||||
path: PathKind::Handle(resolved_path_handle),
|
||||
#[cfg(target_os = "ios")]
|
||||
path_,
|
||||
#[cfg(target_os = "ios")]
|
||||
app_handle,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(mobile)]
|
||||
@@ -1456,6 +1448,7 @@ pub fn resolve_file<R: Runtime>(
|
||||
) -> CommandResult<FileHandle<R>> {
|
||||
use crate::FsExt;
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
let path_ = path.clone();
|
||||
match path {
|
||||
SafeFilePath::Url(url) => {
|
||||
@@ -1463,13 +1456,16 @@ pub fn resolve_file<R: Runtime>(
|
||||
let file = webview
|
||||
.fs()
|
||||
.open(SafeFilePath::Url(url.clone()), open_options.options)?;
|
||||
#[cfg(target_os = "ios")]
|
||||
let app_handle = webview.app_handle().clone();
|
||||
Ok(FileHandle::new(
|
||||
Ok(FileHandle {
|
||||
file,
|
||||
PathKind::Path(resolved_path),
|
||||
path: PathKind::Path(resolved_path),
|
||||
#[cfg(target_os = "ios")]
|
||||
path_,
|
||||
#[cfg(target_os = "ios")]
|
||||
app_handle,
|
||||
))
|
||||
})
|
||||
}
|
||||
SafeFilePath::Path(path) => resolve_file_in_fs(
|
||||
permission,
|
||||
@@ -1494,36 +1490,37 @@ pub fn resolve_path<R: Runtime>(
|
||||
// On iOS, start accessing security-scoped resource if the path is a file URL
|
||||
// Only if it hasn't been started already via start_accessing_security_scoped_resource
|
||||
#[cfg(target_os = "ios")]
|
||||
{
|
||||
if let SafeFilePath::Url(url) = &path {
|
||||
if url.scheme() == "file" {
|
||||
use objc2_foundation::{NSString, NSURL};
|
||||
if let SafeFilePath::Url(url) = &path {
|
||||
if url.scheme() == "file" {
|
||||
use objc2_foundation::{NSString, NSURL};
|
||||
|
||||
let security_scoped_resources = webview.state::<crate::SecurityScopedResources>();
|
||||
let security_scoped_resources = webview.state::<crate::SecurityScopedResources>();
|
||||
|
||||
// Check if already active (started via start_accessing_security_scoped_resource)
|
||||
if !security_scoped_resources.is_tracked_manually(url.as_str()) {
|
||||
let url_nsstring = NSString::from_str(url.as_str());
|
||||
let ns_url = unsafe { NSURL::URLWithString(&url_nsstring) };
|
||||
if let Some(ns_url) = ns_url {
|
||||
// Start accessing the security-scoped resource
|
||||
// This is required for files outside the app's sandbox (e.g., from file picker)
|
||||
unsafe {
|
||||
let success = ns_url.startAccessingSecurityScopedResource();
|
||||
if success {
|
||||
log::debug!("Started accessing security-scoped resource for URL: {} (via resolve_path)", url.as_str());
|
||||
// Track it so we know to clean it up
|
||||
security_scoped_resources.track_manually(url.as_str().to_string());
|
||||
} else {
|
||||
log::warn!("Failed to start accessing security-scoped resource for URL: {}", url.as_str());
|
||||
}
|
||||
// Check if already active (started via start_accessing_security_scoped_resource)
|
||||
if !security_scoped_resources.is_tracked_manually(url.as_str()) {
|
||||
let url_nsstring = NSString::from_str(url.as_str());
|
||||
let ns_url = unsafe { NSURL::URLWithString(&url_nsstring) };
|
||||
if let Some(ns_url) = ns_url {
|
||||
// Start accessing the security-scoped resource
|
||||
// This is required for files outside the app's sandbox (e.g., from file picker)
|
||||
unsafe {
|
||||
let success = ns_url.startAccessingSecurityScopedResource();
|
||||
if success {
|
||||
log::debug!("Started accessing security-scoped resource for URL: {} (via resolve_path)", url.as_str());
|
||||
// Track it so we know to clean it up
|
||||
security_scoped_resources.track_manually(url.as_str().to_string());
|
||||
} else {
|
||||
log::warn!(
|
||||
"Failed to start accessing security-scoped resource for URL: {}",
|
||||
url.as_str()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
log::debug!("Failed to create NSURL from URL: {}, ignoring security-scoped resource access request", url.as_str());
|
||||
}
|
||||
} else {
|
||||
log::debug!("Security-scoped resource already active for URL: {} (started via start_accessing_security_scoped_resource), skipping", url.as_str());
|
||||
log::debug!("Failed to create NSURL from URL: {}, ignoring security-scoped resource access request", url.as_str());
|
||||
}
|
||||
} else {
|
||||
log::debug!("Security-scoped resource already active for URL: {} (started via start_accessing_security_scoped_resource), skipping", url.as_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Access the file system.
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! - **watch**: Enables the `watch` command backed by [`notify`](http://crates.io/crates/notify).
|
||||
|
||||
// TODO(v3): consider redesign the API to implement automatic stopAccessingSecurityScopedResource on iOS
|
||||
// this likely requires returning a handle to a resource so we can impl Drop for it
|
||||
|
||||
@@ -7,6 +7,7 @@ authors = { workspace = true }
|
||||
license = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-geolocation"
|
||||
exclude = ["/guest-js", "/package.json", "/rollup.config.js", "/tsconfig.json"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-linux-android"]
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Access device geolocation APIs.
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! - **specta**: Add support for [`specta::specta`](https://docs.rs/specta/2.0.0-rc.25/specta/attr.specta.html) on structs like [`PermissionStatus`], [`PositionOptions`].
|
||||
|
||||
use tauri::{
|
||||
plugin::{Builder, TauriPlugin},
|
||||
Manager, Runtime,
|
||||
|
||||
@@ -8,6 +8,13 @@ license = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-global-shortcut"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
@@ -7,6 +7,7 @@ authors = { workspace = true }
|
||||
license = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-haptics"
|
||||
exclude = ["/guest-js", "/package.json", "/rollup.config.js", "/tsconfig.json"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-linux-android"]
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Trigger haptic feedback on supported devices.
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! - **specta**: Add support for [`specta::specta`](https://docs.rs/specta/2.0.0-rc.25/specta/attr.specta.html) on structs like [`ImpactFeedbackStyle`], [`NotificationFeedbackType`].
|
||||
|
||||
use tauri::{
|
||||
plugin::{Builder, TauriPlugin},
|
||||
Manager, Runtime,
|
||||
|
||||
+13
-8
@@ -8,6 +8,13 @@ license = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-http"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
@@ -34,7 +41,8 @@ tauri-plugin-fs = { path = "../fs", version = "2.5.1" }
|
||||
urlpattern = "0.3"
|
||||
regex = "1"
|
||||
http = "1"
|
||||
reqwest = { version = "0.12", default-features = false }
|
||||
# 0.12.16 is when `system-proxy` was added
|
||||
reqwest = { version = "0.13.0", default-features = false }
|
||||
url = { workspace = true }
|
||||
data-url = "0.3"
|
||||
cookie_store = { version = "0.22", optional = true, features = ["serde"] }
|
||||
@@ -42,13 +50,7 @@ bytes = { version = "1.9", optional = true }
|
||||
tracing = { workspace = true, optional = true }
|
||||
|
||||
[features]
|
||||
default = [
|
||||
"rustls-tls",
|
||||
"http2",
|
||||
"charset",
|
||||
"macos-system-configuration",
|
||||
"cookies",
|
||||
]
|
||||
default = ["rustls-tls", "http2", "charset", "system-proxy", "cookies"]
|
||||
multipart = ["reqwest/multipart"]
|
||||
json = ["reqwest/json"]
|
||||
stream = ["reqwest/stream"]
|
||||
@@ -69,7 +71,10 @@ trust-dns = ["reqwest/trust-dns"]
|
||||
socks = ["reqwest/socks"]
|
||||
http2 = ["reqwest/http2"]
|
||||
charset = ["reqwest/charset"]
|
||||
# Deprecated, switch to system-proxy
|
||||
macos-system-configuration = ["reqwest/macos-system-configuration"]
|
||||
system-proxy = ["reqwest/system-proxy"]
|
||||
|
||||
unsafe-headers = []
|
||||
tracing = ["dep:tracing"]
|
||||
dangerous-settings = []
|
||||
|
||||
@@ -3,6 +3,46 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Access the HTTP client written in Rust.
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! ### Reqwest feature forwards
|
||||
//!
|
||||
//! These features forwards [`reqwest`](https://docs.rs/reqwest/0.12.28/reqwest/index.html) features:
|
||||
//!
|
||||
//! - **http2** *(enabled by default)*: Enables HTTP/2 support.
|
||||
//! - **native-tls**: Enables TLS functionality provided by native-tls.
|
||||
//! - **native-tls-vendored**: Enables the vendored feature of native-tls.
|
||||
//! - **native-tls-alpn**: Enables the alpn feature of native-tls.
|
||||
//! - **rustls-tls** *(enabled by default)*: Enables TLS functionality provided by rustls. Equivalent to
|
||||
//! rustls-tls-webpki-roots.
|
||||
//! - **rustls-tls-manual-roots**: Enables TLS functionality provided by rustls, without setting any root
|
||||
//! certificates. Roots have to be specified manually.
|
||||
//! - **rustls-tls-webpki-roots**: Enables TLS functionality provided by rustls, while using root certificates
|
||||
//! from the webpki-roots crate.
|
||||
//! - **rustls-tls-native-roots**: Enables TLS functionality provided by rustls, while using root certificates
|
||||
//! from the rustls-native-certs crate.
|
||||
//! - **blocking**: Provides the [blocking](https://docs.rs/reqwest/0.12.28/reqwest/blocking/index.html) client API.
|
||||
//! - **charset** *(enabled by default)*: Improved support for decoding text.
|
||||
//! - **cookies** *(enabled by default)*: Provides cookie session support.
|
||||
//! - **gzip**: Provides response body gzip decompression.
|
||||
//! - **brotli**: Provides response body brotli decompression.
|
||||
//! - **zstd**: Provides response body zstd decompression.
|
||||
//! - **deflate**: Provides response body deflate decompression.
|
||||
//! - **json**: Provides serialization and deserialization for JSON bodies.
|
||||
//! - **multipart**: Provides functionality for multipart forms.
|
||||
//! - **stream**: Adds support for futures::Stream.
|
||||
//! - **socks**: Provides SOCKS5 proxy support.
|
||||
//! - **trust-dns**: Enables a trust-dns/Hickory DNS async resolver instead of the default threadpool using
|
||||
//! getaddrinfo.
|
||||
//! - **macos-system-configuration** *(deprecated, use `system-proxy` instead)*: Use Windows and macOS system proxy settings automatically.
|
||||
//! - **system-proxy** *(enabled by default)*: Use Windows and macOS system proxy settings automatically.
|
||||
//!
|
||||
//! ### tauri-plugin-http features
|
||||
//!
|
||||
//! - **tracing**: Adds request, response, and cookie-store diagnostics through `tracing`.
|
||||
//! - **unsafe-headers**: Allows webview requests to send any headers.
|
||||
//! - **dangerous-settings**: Allows dangerous client settings such as accepting invalid certificates or hostnames.
|
||||
|
||||
pub use reqwest;
|
||||
use tauri::{
|
||||
|
||||
@@ -7,6 +7,7 @@ license = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
exclude = ["/banner.png"]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
@@ -8,6 +8,13 @@ edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-log"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
+12
-1
@@ -3,6 +3,11 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Logging for Tauri applications.
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! - **colored**: Enables [`Builder::with_colors`] `fern`'s `colored` feature for ANSI-colored outputs.
|
||||
//! - **tracing**: Emit both log and tracing for the JavaScript log commands.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
@@ -648,7 +653,13 @@ impl Builder {
|
||||
|
||||
/// Skip the creation and global registration of a logger
|
||||
///
|
||||
/// If you wish to use your own global logger, you must call `skip_logger` so that the plugin does not attempt to set a second global logger. In this configuration, no logger will be created and the plugin's `log` command will rely on the result of `log::logger()`. You will be responsible for configuring the logger yourself and any included targets will be ignored. If ever initializing the plugin multiple times, such as if registering the plugin while testing, call this method to avoid panicking when registering multiple loggers. For interacting with `tracing`, you can leverage the `tracing-log` logger to forward logs to `tracing` or enable the `tracing` feature for this plugin to emit events directly to the tracing system. Both scenarios require calling this method.
|
||||
/// If you wish to use your own global logger, you must call `skip_logger` so that the plugin does not attempt to set a second global logger.
|
||||
/// In this configuration, no logger will be created and the plugin's `log` command will rely on the result of `log::logger()`.
|
||||
/// You will be responsible for configuring the logger yourself and any included targets will be ignored.
|
||||
/// If ever initializing the plugin multiple times, such as if registering the plugin while testing, call this method to avoid panicking when registering multiple loggers.
|
||||
/// For interacting with `tracing`, you can leverage the `tracing-log` logger to forward logs to `tracing` or enable the `tracing` feature for this plugin to emit events directly to the tracing system.
|
||||
/// Both scenarios require calling this method.
|
||||
///
|
||||
/// ```rust
|
||||
/// static LOGGER: SimpleLogger = SimpleLogger;
|
||||
///
|
||||
|
||||
@@ -7,6 +7,7 @@ authors = { workspace = true }
|
||||
license = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-nfc"
|
||||
exclude = ["/guest-js", "/package.json", "/rollup.config.js", "/tsconfig.json"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-linux-android"]
|
||||
|
||||
@@ -47,6 +47,7 @@ impl<R: Runtime> Nfc<R> {
|
||||
pub fn scan(&self, payload: ScanRequest) -> crate::Result<ScanResponse> {
|
||||
self.0
|
||||
.run_mobile_plugin("scan", payload)
|
||||
.map(|v| ScanResponse { tag: v })
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,14 @@ license = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-notification"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/test",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu", "x86_64-linux-android"]
|
||||
|
||||
@@ -80,11 +80,11 @@ class NotificationStorage(private val context: Context, private val jsonMapper:
|
||||
|
||||
fun writeActionGroup(actions: List<ActionType>) {
|
||||
for (type in actions) {
|
||||
val i = type.id
|
||||
val editor = getStorage(ACTION_TYPES_ID + type.id).edit()
|
||||
editor.clear()
|
||||
editor.putInt("count", type.actions.size)
|
||||
for (action in type.actions) {
|
||||
for (i in 0 until type.actions.size) {
|
||||
val action = type.actions[i]
|
||||
editor.putString("id$i", action.id)
|
||||
editor.putString("title$i", action.title)
|
||||
editor.putBoolean("input$i", action.input ?: false)
|
||||
|
||||
@@ -73,7 +73,8 @@ interface Options {
|
||||
/**
|
||||
* The sound resource name or file path for the notification.
|
||||
*
|
||||
* Platform specific behavior:
|
||||
* ## Platform-specific behavior:
|
||||
*
|
||||
* - On macOS: use system sounds (e.g., "Ping", "Blow") or sound files in the app bundle
|
||||
* - On Linux: use XDG theme sounds (e.g., "message-new-instant") or file paths
|
||||
* - On Windows: use file paths to sound files (.wav format)
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Send message notifications (brief auto-expiring OS window element) to your user. Can also be used with the Notification Web API.
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! - **windows7-compat**: Adds support for the legacy Windows 7 notification implementation and Windows-version detection.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
|
||||
@@ -320,6 +320,95 @@ pub struct ActionType {
|
||||
hidden_previews_show_subtitle: bool,
|
||||
}
|
||||
|
||||
#[cfg(mobile)]
|
||||
#[derive(Debug)]
|
||||
pub struct ActionTypeBuilder(ActionType);
|
||||
|
||||
#[cfg(mobile)]
|
||||
impl ActionType {
|
||||
pub fn builder(id: impl Into<String>) -> ActionTypeBuilder {
|
||||
ActionTypeBuilder(Self {
|
||||
id: id.into(),
|
||||
actions: Vec::new(),
|
||||
hidden_previews_body_placeholder: None,
|
||||
custom_dismiss_action: false,
|
||||
allow_in_car_play: false,
|
||||
hidden_previews_show_title: false,
|
||||
hidden_previews_show_subtitle: false,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
|
||||
pub fn actions(&self) -> &[Action] {
|
||||
&self.actions
|
||||
}
|
||||
|
||||
pub fn hidden_previews_body_placeholder(&self) -> Option<&str> {
|
||||
self.hidden_previews_body_placeholder.as_deref()
|
||||
}
|
||||
|
||||
pub fn custom_dismiss_action(&self) -> bool {
|
||||
self.custom_dismiss_action
|
||||
}
|
||||
|
||||
pub fn allow_in_car_play(&self) -> bool {
|
||||
self.allow_in_car_play
|
||||
}
|
||||
|
||||
pub fn hidden_previews_show_title(&self) -> bool {
|
||||
self.hidden_previews_show_title
|
||||
}
|
||||
|
||||
pub fn hidden_previews_show_subtitle(&self) -> bool {
|
||||
self.hidden_previews_show_subtitle
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(mobile)]
|
||||
impl ActionTypeBuilder {
|
||||
pub fn actions(mut self, actions: Vec<Action>) -> Self {
|
||||
self.0.actions = actions;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn hidden_previews_body_placeholder(
|
||||
mut self,
|
||||
hidden_previews_body_placeholder: impl Into<String>,
|
||||
) -> Self {
|
||||
self.0
|
||||
.hidden_previews_body_placeholder
|
||||
.replace(hidden_previews_body_placeholder.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn custom_dismiss_action(mut self, custom_dismiss_action: bool) -> Self {
|
||||
self.0.custom_dismiss_action = custom_dismiss_action;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn allow_in_car_play(mut self, allow_in_car_play: bool) -> Self {
|
||||
self.0.allow_in_car_play = allow_in_car_play;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn hidden_previews_show_title(mut self, hidden_previews_show_title: bool) -> Self {
|
||||
self.0.hidden_previews_show_title = hidden_previews_show_title;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn hidden_previews_show_subtitle(mut self, hidden_previews_show_subtitle: bool) -> Self {
|
||||
self.0.hidden_previews_show_subtitle = hidden_previews_show_subtitle;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> ActionType {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(mobile)]
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -334,6 +423,95 @@ pub struct Action {
|
||||
input_placeholder: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(mobile)]
|
||||
#[derive(Debug)]
|
||||
pub struct ActionBuilder(Action);
|
||||
|
||||
#[cfg(mobile)]
|
||||
impl Action {
|
||||
pub fn builder(id: impl Into<String>, title: impl Into<String>) -> ActionBuilder {
|
||||
ActionBuilder(Self {
|
||||
id: id.into(),
|
||||
title: title.into(),
|
||||
requires_authentication: false,
|
||||
foreground: false,
|
||||
destructive: false,
|
||||
input: false,
|
||||
input_button_title: None,
|
||||
input_placeholder: None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
|
||||
pub fn title(&self) -> &str {
|
||||
&self.title
|
||||
}
|
||||
|
||||
pub fn requires_authentication(&self) -> bool {
|
||||
self.requires_authentication
|
||||
}
|
||||
|
||||
pub fn foreground(&self) -> bool {
|
||||
self.foreground
|
||||
}
|
||||
|
||||
pub fn destructive(&self) -> bool {
|
||||
self.destructive
|
||||
}
|
||||
|
||||
pub fn input(&self) -> bool {
|
||||
self.input
|
||||
}
|
||||
|
||||
pub fn input_button_title(&self) -> Option<&str> {
|
||||
self.input_button_title.as_deref()
|
||||
}
|
||||
|
||||
pub fn input_placeholder(&self) -> Option<&str> {
|
||||
self.input_placeholder.as_deref()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(mobile)]
|
||||
impl ActionBuilder {
|
||||
pub fn requires_authentication(mut self, requires_authentication: bool) -> Self {
|
||||
self.0.requires_authentication = requires_authentication;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn foreground(mut self, foreground: bool) -> Self {
|
||||
self.0.foreground = foreground;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn destructive(mut self, destructive: bool) -> Self {
|
||||
self.0.destructive = destructive;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn input(mut self, input: bool) -> Self {
|
||||
self.0.input = input;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn input_button_title(mut self, input_button_title: impl Into<String>) -> Self {
|
||||
self.0.input_button_title.replace(input_button_title.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn input_placeholder(mut self, input_placeholder: impl Into<String>) -> Self {
|
||||
self.0.input_placeholder.replace(input_placeholder.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Action {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub use android::*;
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ links = "tauri-plugin-opener"
|
||||
# Platforms supported by the plugin
|
||||
# Support levels are "full", "partial", "none", "unknown"
|
||||
# Details of the support level are left to plugin maintainer
|
||||
exclude = ["/guest-js", "/package.json", "/rollup.config.js", "/tsconfig.json"]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
linux = { level = "full", notes = "" }
|
||||
|
||||
@@ -8,6 +8,13 @@ license = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-os"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
@@ -7,6 +7,7 @@ license = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
exclude = ["/banner.png"]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Save filesystem and asset scopes and restore them when the app is reopened.
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! - **protocol-asset**: Enables `tauri`'s `protocol-asset` feature and adds support for persisting `asset://` protocol scopes.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
@@ -188,25 +192,25 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||
|
||||
if let Some(fs_scope) = &fs_scope {
|
||||
if fs_scope_state_path.exists() {
|
||||
let scope: Scope = std::fs::read(&fs_scope_state_path)
|
||||
.map_err(Error::from)
|
||||
.and_then(|scope| bincode::deserialize(&scope).map_err(Into::into))
|
||||
.unwrap_or_default();
|
||||
let scope: Scope = std::fs::read(&fs_scope_state_path)
|
||||
.map_err(Error::from)
|
||||
.and_then(|scope| bincode::deserialize(&scope).map_err(Into::into))
|
||||
.unwrap_or_default();
|
||||
|
||||
for allowed in &scope.allowed_paths {
|
||||
let allowed = fix_pattern(&ac, allowed);
|
||||
allow_path(fs_scope, &allowed);
|
||||
}
|
||||
for forbidden in &scope.forbidden_patterns {
|
||||
let forbidden = fix_pattern(&ac, forbidden);
|
||||
forbid_path(fs_scope, &forbidden);
|
||||
}
|
||||
for allowed in &scope.allowed_paths {
|
||||
let allowed = fix_pattern(&ac, allowed);
|
||||
allow_path(fs_scope, &allowed);
|
||||
}
|
||||
for forbidden in &scope.forbidden_patterns {
|
||||
let forbidden = fix_pattern(&ac, forbidden);
|
||||
forbid_path(fs_scope, &forbidden);
|
||||
}
|
||||
|
||||
// Manually save the fixed scopes to disk once.
|
||||
// This is needed to fix broken .peristed-scope files in case the app doesn't update the scope itself.
|
||||
save_scopes(fs_scope, &app_dir, &fs_scope_state_path);
|
||||
// Manually save the fixed scopes to disk once.
|
||||
// This is needed to fix broken .peristed-scope files in case the app doesn't update the scope itself.
|
||||
save_scopes(fs_scope, &app_dir, &fs_scope_state_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "protocol-asset")]
|
||||
if asset_scope_state_path.exists() {
|
||||
|
||||
@@ -8,6 +8,13 @@ edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-positioner"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
//! A plugin for Tauri that helps position your windows at well-known locations.
|
||||
//!
|
||||
//! # Cargo features
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! - **tray-icon**: Enables tray-icon-relative positions.
|
||||
//!
|
||||
|
||||
@@ -8,6 +8,13 @@ license = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-process"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
@@ -8,6 +8,14 @@ license = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-shell"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/test",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
@@ -7,7 +7,7 @@ license = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
exclude = ["/examples"]
|
||||
exclude = ["/banner.png", "/examples"]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
@@ -16,6 +16,3 @@ tauri-plugin-cli = { path = "../../../../cli" }
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { workspace = true }
|
||||
|
||||
[features]
|
||||
prod = ["tauri/custom-protocol"]
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Ensure a single instance of your tauri app is running.
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! - **semver**: Allows the app with SemVer incompatible versions to run alongside each other.
|
||||
//! - **deep-link**: Trigger [`tauri-plugin-deep-link`](https://crates.io/crates/tauri-plugin-deep-link) event before invoking the single-instance callback.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
|
||||
@@ -8,6 +8,13 @@ edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-sql"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["sqlite"]
|
||||
|
||||
+10
-1
@@ -2,7 +2,16 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Interface with SQL databases through [sqlx](https://github.com/launchbadge/sqlx). It supports the `sqlite`, `mysql` and `postgres` drivers, enabled by a Cargo feature.
|
||||
//! Interface with SQL databases through [sqlx](https://github.com/launchbadge/sqlx).
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! No database driver is enabled by default. Enable at least one driver;
|
||||
//! multiple drivers may be enabled together.
|
||||
//!
|
||||
//! - **sqlite**: Adds support for SQLite.
|
||||
//! - **mysql**: Adds support for MySQL.
|
||||
//! - **postgres**: Adds support for PostgreSQL.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
|
||||
@@ -8,6 +8,14 @@ edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-store"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/examples",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "2.11.4",
|
||||
"typescript": "^6.0.0",
|
||||
"vite": "^8.0.1"
|
||||
"typescript": "^6.0.3",
|
||||
"vite": "^8.0.16"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,3 @@ tauri = { workspace = true, features = ["wry", "common-controls-v6", "x11"] }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tauri-plugin-store = { path = "../../../" }
|
||||
|
||||
[features]
|
||||
# this feature is used for production builds or when `devPath` points to the filesystem
|
||||
# DO NOT REMOVE!!
|
||||
prod = ["tauri/custom-protocol"]
|
||||
|
||||
@@ -8,6 +8,13 @@ edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-stronghold"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Store secrets and keys using the [IOTA Stronghold](https://github.com/iotaledger/stronghold.rs) encrypted database and secure runtime.
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! - **kdf** *(enabled by default)*: Exposes the key-derivation module and provides the default Argon2-based password-to-key derivation.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
|
||||
@@ -8,6 +8,14 @@ license = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-updater"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tests",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
no-default-features = true
|
||||
@@ -67,8 +75,9 @@ flate2 = "1"
|
||||
osakit = { version = "0.3", features = ["full"] }
|
||||
|
||||
[features]
|
||||
default = ["rustls-tls", "zip"]
|
||||
default = ["rustls-tls", "system-proxy", "zip"]
|
||||
zip = ["dep:zip", "dep:tar", "dep:flate2"]
|
||||
native-tls = ["reqwest/native-tls"]
|
||||
native-tls-vendored = ["reqwest/native-tls-vendored"]
|
||||
rustls-tls = ["reqwest/rustls-no-provider", "dep:rustls"]
|
||||
system-proxy = ["reqwest/system-proxy"]
|
||||
|
||||
@@ -69,6 +69,7 @@ import { relaunch } from '@tauri-apps/plugin-process'
|
||||
const update = await check()
|
||||
if (update) {
|
||||
await update.downloadAndInstall()
|
||||
// Relaunch the app on macOS and Linux to run the newly install version
|
||||
await relaunch()
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1 +1 @@
|
||||
if("__TAURI__"in window){var __TAURI_PLUGIN_UPDATER__=function(t){"use strict";function e(t,e,s,n){if("function"==typeof e?t!==e||!n:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===s?n:"a"===s?n.call(t):n?n.value:e.get(t)}function s(t,e,s,n,i){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(t,s),s}var n,i,a,r,o;"function"==typeof SuppressedError&&SuppressedError;const d="__TAURI_TO_IPC_KEY__";class c{constructor(t){n.set(this,void 0),i.set(this,0),a.set(this,[]),r.set(this,void 0),s(this,n,t||(()=>{})),this.id=function(t,e=!1){return window.__TAURI_INTERNALS__.transformCallback(t,e)}(t=>{const o=t.index;if("end"in t)return void(o==e(this,i,"f")?this.cleanupCallback():s(this,r,o));const d=t.message;if(o==e(this,i,"f")){for(e(this,n,"f").call(this,d),s(this,i,e(this,i,"f")+1);e(this,i,"f")in e(this,a,"f");){const t=e(this,a,"f")[e(this,i,"f")];e(this,n,"f").call(this,t),delete e(this,a,"f")[e(this,i,"f")],s(this,i,e(this,i,"f")+1)}e(this,i,"f")===e(this,r,"f")&&this.cleanupCallback()}else e(this,a,"f")[o]=d})}cleanupCallback(){window.__TAURI_INTERNALS__.unregisterCallback(this.id)}set onmessage(t){s(this,n,t)}get onmessage(){return e(this,n,"f")}[(n=new WeakMap,i=new WeakMap,a=new WeakMap,r=new WeakMap,d)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[d]()}}async function l(t,e={},s){return window.__TAURI_INTERNALS__.invoke(t,e,s)}class h{get rid(){return e(this,o,"f")}constructor(t){o.set(this,void 0),s(this,o,t)}async close(){return l("plugin:resources|close",{rid:this.rid})}}o=new WeakMap;class u extends h{constructor(t){super(t.rid),this.available=!0,this.currentVersion=t.currentVersion,this.version=t.version,this.date=t.date,this.body=t.body,this.rawJson=t.rawJson}async download(t,e){_(e);const s=new c;t&&(s.onmessage=t);const n=await l("plugin:updater|download",{onEvent:s,rid:this.rid,...e});this.downloadedBytes=new h(n)}async install(){if(!this.downloadedBytes)throw new Error("Update.install called before Update.download");await l("plugin:updater|install",{updateRid:this.rid,bytesRid:this.downloadedBytes.rid}),this.downloadedBytes=void 0}async downloadAndInstall(t,e){_(e);const s=new c;t&&(s.onmessage=t),await l("plugin:updater|download_and_install",{onEvent:s,rid:this.rid,...e})}async close(){await(this.downloadedBytes?.close()),await super.close()}}function _(t){t?.headers&&(t.headers=Array.from(new Headers(t.headers).entries()))}return t.Update=u,t.check=async function(t){_(t);const e=await l("plugin:updater|check",{...t});return e?new u(e):null},t}({});Object.defineProperty(window.__TAURI__,"updater",{value:__TAURI_PLUGIN_UPDATER__})}
|
||||
if("__TAURI__"in window){var __TAURI_PLUGIN_UPDATER__=function(t){"use strict";function e(t,e,s,n){if("function"==typeof e?t!==e||!n:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===s?n:"a"===s?n.call(t):n?n.value:e.get(t)}function s(t,e,s,n,i){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(t,s),s}var n,i,a,r,o;"function"==typeof SuppressedError&&SuppressedError;const d="__TAURI_TO_IPC_KEY__";class c{constructor(t){n.set(this,void 0),i.set(this,0),a.set(this,[]),r.set(this,void 0),s(this,n,t||(()=>{})),this.id=function(t,e=!1){return window.__TAURI_INTERNALS__.transformCallback(t,e)}(t=>{const o=t.index;if("end"in t)return void(o==e(this,i,"f")?this.cleanupCallback():s(this,r,o));const d=t.message;if(o==e(this,i,"f")){for(e(this,n,"f").call(this,d),s(this,i,e(this,i,"f")+1);e(this,i,"f")in e(this,a,"f");){const t=e(this,a,"f")[e(this,i,"f")];e(this,n,"f").call(this,t),delete e(this,a,"f")[e(this,i,"f")],s(this,i,e(this,i,"f")+1)}e(this,i,"f")===e(this,r,"f")&&this.cleanupCallback()}else e(this,a,"f")[o]=d})}cleanupCallback(){window.__TAURI_INTERNALS__.unregisterCallback(this.id)}set onmessage(t){s(this,n,t)}get onmessage(){return e(this,n,"f")}[(n=new WeakMap,i=new WeakMap,a=new WeakMap,r=new WeakMap,d)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[d]()}}async function l(t,e={},s){return window.__TAURI_INTERNALS__.invoke(t,e,s)}class h{get rid(){return e(this,o,"f")}constructor(t){o.set(this,void 0),s(this,o,t)}async close(){return l("plugin:resources|close",{rid:this.rid})}}o=new WeakMap;class u extends h{constructor(t){super(t.rid),this.available=!0,this.currentVersion=t.currentVersion,this.version=t.version,this.date=t.date,this.body=t.body,this.rawJson=t.rawJson}async download(t,e){_(e);const s=new c;t&&(s.onmessage=t);const n=await l("plugin:updater|download",{onEvent:s,rid:this.rid,...e});this.downloadedBytes=new h(n)}async install(t){if(!this.downloadedBytes)throw new Error("Update.install called before Update.download");await l("plugin:updater|install",{updateRid:this.rid,bytesRid:this.downloadedBytes.rid,...t}),this.downloadedBytes=void 0}async downloadAndInstall(t,e){_(e);const s=new c;t&&(s.onmessage=t),await l("plugin:updater|download_and_install",{onEvent:s,rid:this.rid,...e})}async close(){await(this.downloadedBytes?.close()),await super.close()}}function _(t){t?.headers&&(t.headers=Array.from(new Headers(t.headers).entries()))}return t.Update=u,t.check=async function(t){_(t);const e=await l("plugin:updater|check",{...t});return e?new u(e):null},t}({});Object.defineProperty(window.__TAURI__,"updater",{value:__TAURI_PLUGIN_UPDATER__})}
|
||||
|
||||
@@ -40,6 +40,14 @@ interface DownloadOptions {
|
||||
timeout?: number
|
||||
}
|
||||
|
||||
/** Options used when installing an update */
|
||||
interface InstallOptions {
|
||||
/**
|
||||
* If the Windows installer should restart the app after installed, default is `true`
|
||||
*/
|
||||
restartAfterInstall?: boolean
|
||||
}
|
||||
|
||||
interface UpdateMetadata {
|
||||
rid: number
|
||||
currentVersion: string
|
||||
@@ -76,7 +84,7 @@ class Update extends Resource {
|
||||
this.rawJson = metadata.rawJson
|
||||
}
|
||||
|
||||
/** Download the updater package */
|
||||
/** Download the updater package. Call {@linkcode install} later to install it */
|
||||
async download(
|
||||
onEvent?: (progress: DownloadEvent) => void,
|
||||
options?: DownloadOptions
|
||||
@@ -94,25 +102,40 @@ class Update extends Resource {
|
||||
this.downloadedBytes = new Resource(downloadedBytesRid)
|
||||
}
|
||||
|
||||
/** Install downloaded updater package */
|
||||
async install(): Promise<void> {
|
||||
/**
|
||||
* Install downloaded updater package. Must be called after {@linkcode download}.
|
||||
*
|
||||
* ## Platform-specific:
|
||||
*
|
||||
* - **Windows:** This function exits the app after launching the updater installer successfully
|
||||
* - **macOS / Linux:** You need to relaunch the app to run the newly install version
|
||||
*/
|
||||
async install(options?: InstallOptions): Promise<void> {
|
||||
if (!this.downloadedBytes) {
|
||||
throw new Error('Update.install called before Update.download')
|
||||
}
|
||||
|
||||
await invoke('plugin:updater|install', {
|
||||
updateRid: this.rid,
|
||||
bytesRid: this.downloadedBytes.rid
|
||||
bytesRid: this.downloadedBytes.rid,
|
||||
...options
|
||||
})
|
||||
|
||||
// Don't need to call close, we did it in rust side already
|
||||
this.downloadedBytes = undefined
|
||||
}
|
||||
|
||||
/** Downloads the updater package and installs it */
|
||||
/**
|
||||
* Downloads the updater package and installs it
|
||||
*
|
||||
* ## Platform-specific:
|
||||
*
|
||||
* - **Windows:** This function exits the app after launching the updater installer successfully
|
||||
* - **macOS / Linux:** You need to relaunch the app to run the newly install version
|
||||
*/
|
||||
async downloadAndInstall(
|
||||
onEvent?: (progress: DownloadEvent) => void,
|
||||
options?: DownloadOptions
|
||||
options?: DownloadOptions & InstallOptions
|
||||
): Promise<void> {
|
||||
convertToRustHeaders(options)
|
||||
const channel = new Channel<DownloadEvent>()
|
||||
|
||||
@@ -142,12 +142,22 @@ pub(crate) async fn install<R: Runtime>(
|
||||
webview: Webview<R>,
|
||||
update_rid: ResourceId,
|
||||
bytes_rid: ResourceId,
|
||||
restart_after_install: Option<bool>,
|
||||
) -> Result<()> {
|
||||
let update = webview.resources_table().get::<Update>(update_rid)?;
|
||||
let bytes = webview
|
||||
.resources_table()
|
||||
.get::<DownloadedBytes>(bytes_rid)?;
|
||||
update.install(&bytes.0)?;
|
||||
|
||||
if let Some(restart_after_install) = restart_after_install {
|
||||
let update = (*update).clone();
|
||||
update
|
||||
.restart_after_install(restart_after_install)
|
||||
.install(&bytes.0)?;
|
||||
} else {
|
||||
update.install(&bytes.0)?;
|
||||
}
|
||||
|
||||
let _ = webview.resources_table().close(bytes_rid);
|
||||
Ok(())
|
||||
}
|
||||
@@ -159,6 +169,7 @@ pub(crate) async fn download_and_install<R: Runtime>(
|
||||
on_event: Channel<DownloadEvent>,
|
||||
headers: Option<Vec<(String, String)>>,
|
||||
timeout: Option<u64>,
|
||||
restart_after_install: Option<bool>,
|
||||
) -> Result<()> {
|
||||
let update = webview.resources_table().get::<Update>(rid)?;
|
||||
|
||||
@@ -176,6 +187,10 @@ pub(crate) async fn download_and_install<R: Runtime>(
|
||||
update.timeout = Some(Duration::from_millis(timeout));
|
||||
}
|
||||
|
||||
if let Some(restart_after_install) = restart_after_install {
|
||||
update = update.restart_after_install(restart_after_install);
|
||||
}
|
||||
|
||||
let mut first_chunk = true;
|
||||
|
||||
update
|
||||
|
||||
@@ -32,17 +32,30 @@ impl WindowsUpdateInstallMode {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub(crate) fn msi_restart_after_install_args(&self) -> &'static [&'static str] {
|
||||
&["AUTOLAUNCHAPP=True"]
|
||||
}
|
||||
|
||||
/// Returns the associated nsis arguments.
|
||||
pub fn nsis_args(&self) -> &'static [&'static str] {
|
||||
// `/P`: Passive
|
||||
// `/S`: Silent
|
||||
// `/R`: Restart
|
||||
match self {
|
||||
Self::Passive => &["/P", "/R"],
|
||||
Self::Quiet => &["/S", "/R"],
|
||||
Self::Passive => &["/P"],
|
||||
Self::Quiet => &["/S"],
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub(crate) fn nsis_restart_after_install_args(&self) -> &'static [&'static str] {
|
||||
match self {
|
||||
Self::BasicUi => &[],
|
||||
_ => &["/R"],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for WindowsUpdateInstallMode {
|
||||
@@ -63,6 +76,8 @@ impl Display for WindowsUpdateInstallMode {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WindowsConfig {
|
||||
/// Additional arguments given to the NSIS or WiX installer.
|
||||
///
|
||||
/// Note: this applies to both WiX and NSIS installers
|
||||
#[serde(
|
||||
default,
|
||||
alias = "installer-args",
|
||||
|
||||
@@ -4,7 +4,15 @@
|
||||
|
||||
//! In-app updates for Tauri applications.
|
||||
//!
|
||||
//! - Supported platforms: Windows, Linux and macOS.crypted database and secure runtime.
|
||||
//! Supported platforms: Windows, Linux and macOS.
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! - **zip** *(enabled by default)*: Adds support for compressed updater bundles from Tauri v1.
|
||||
//! - **rustls-tls** *(enabled by default)*: Enables TLS functionality provided by `rustls`.
|
||||
//! - **native-tls**: Enables TLS functionality provided by `native-tls`.
|
||||
//! - **native-tls-vendored**: Enables the `vendored` feature of `native-tls`.
|
||||
//! - **system-proxy** *(enabled by default)*: Use Windows and macOS system proxy settings automatically.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
@@ -83,9 +91,9 @@ impl<R: Runtime, T: Manager<R>> UpdaterExt<R> for T {
|
||||
builder = builder.target(target);
|
||||
}
|
||||
|
||||
let args = self.env().args_os;
|
||||
if !args.is_empty() {
|
||||
builder = builder.current_exe_args(args);
|
||||
#[cfg(windows)]
|
||||
{
|
||||
builder = builder.current_exe_args(self.env().args_os);
|
||||
}
|
||||
|
||||
builder.version_comparator = version_comparator.clone();
|
||||
|
||||
+226
-149
@@ -129,16 +129,34 @@ impl RemoteRelease {
|
||||
pub type OnBeforeExit = Arc<dyn Fn() + Send + Sync + 'static>;
|
||||
pub type OnBeforeRequest = Arc<dyn Fn(ClientBuilder) -> ClientBuilder + Send + Sync + 'static>;
|
||||
pub type VersionComparator = Arc<dyn Fn(Version, RemoteRelease) -> bool + Send + Sync>;
|
||||
#[cfg(target_os = "macos")]
|
||||
type MainThreadClosure = Box<dyn FnOnce() + Send + Sync + 'static>;
|
||||
type RunOnMainThread =
|
||||
Box<dyn Fn(MainThreadClosure) -> std::result::Result<(), tauri::Error> + Send + Sync + 'static>;
|
||||
#[cfg(target_os = "macos")]
|
||||
type RunOnMainThread = Arc<dyn Fn(MainThreadClosure) -> tauri::Result<()> + Send + Sync + 'static>;
|
||||
|
||||
// TODO: Move more fields to this in v3 if we can mark those fields non `pub`
|
||||
/// Updater context shared between [`UpdaterBuilder`], [`Updater`] and [`Update`]
|
||||
#[derive(Clone)]
|
||||
struct UpdaterContext {
|
||||
config: Config,
|
||||
configure_client: Option<OnBeforeRequest>,
|
||||
#[cfg(target_os = "macos")]
|
||||
run_on_main_thread: RunOnMainThread,
|
||||
/// App name, used for creating named tempfiles
|
||||
#[cfg(windows)]
|
||||
app_name: String,
|
||||
#[cfg(windows)]
|
||||
installer_args: Vec<OsString>,
|
||||
#[cfg(windows)]
|
||||
current_exe_args: Vec<OsString>,
|
||||
#[cfg(windows)]
|
||||
on_before_exit: Option<OnBeforeExit>,
|
||||
#[cfg(windows)]
|
||||
restart_after_install: bool,
|
||||
}
|
||||
|
||||
pub struct UpdaterBuilder {
|
||||
#[allow(dead_code)]
|
||||
run_on_main_thread: RunOnMainThread,
|
||||
app_name: String,
|
||||
current_version: Version,
|
||||
config: Config,
|
||||
pub(crate) version_comparator: Option<VersionComparator>,
|
||||
executable_path: Option<PathBuf>,
|
||||
target: Option<String>,
|
||||
@@ -147,27 +165,38 @@ pub struct UpdaterBuilder {
|
||||
timeout: Option<Duration>,
|
||||
proxy: Option<Url>,
|
||||
no_proxy: bool,
|
||||
installer_args: Vec<OsString>,
|
||||
current_exe_args: Vec<OsString>,
|
||||
on_before_exit: Option<OnBeforeExit>,
|
||||
configure_client: Option<OnBeforeRequest>,
|
||||
context: UpdaterContext,
|
||||
}
|
||||
|
||||
impl UpdaterBuilder {
|
||||
pub(crate) fn new<R: Runtime>(app: &AppHandle<R>, config: crate::Config) -> Self {
|
||||
let app_ = app.clone();
|
||||
let run_on_main_thread = move |f| app_.run_on_main_thread(f);
|
||||
#[cfg(target_os = "macos")]
|
||||
let run_on_main_thread = {
|
||||
let app_ = app.clone();
|
||||
Arc::new(move |f| app_.run_on_main_thread(f))
|
||||
};
|
||||
Self {
|
||||
run_on_main_thread: Box::new(run_on_main_thread),
|
||||
installer_args: config
|
||||
.windows
|
||||
.as_ref()
|
||||
.map(|w| w.installer_args.clone())
|
||||
.unwrap_or_default(),
|
||||
current_exe_args: Vec::new(),
|
||||
app_name: app.package_info().name.clone(),
|
||||
context: UpdaterContext {
|
||||
#[cfg(windows)]
|
||||
installer_args: config
|
||||
.windows
|
||||
.as_ref()
|
||||
.map(|w| w.installer_args.clone())
|
||||
.unwrap_or_default(),
|
||||
config,
|
||||
configure_client: None,
|
||||
#[cfg(target_os = "macos")]
|
||||
run_on_main_thread,
|
||||
#[cfg(windows)]
|
||||
app_name: app.package_info().name.clone(),
|
||||
#[cfg(windows)]
|
||||
current_exe_args: Vec::new(),
|
||||
#[cfg(windows)]
|
||||
on_before_exit: None,
|
||||
#[cfg(windows)]
|
||||
restart_after_install: true,
|
||||
},
|
||||
current_version: app.package_info().version.clone(),
|
||||
config,
|
||||
version_comparator: None,
|
||||
executable_path: None,
|
||||
target: None,
|
||||
@@ -176,8 +205,6 @@ impl UpdaterBuilder {
|
||||
timeout: None,
|
||||
proxy: None,
|
||||
no_proxy: false,
|
||||
on_before_exit: None,
|
||||
configure_client: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +224,7 @@ impl UpdaterBuilder {
|
||||
pub fn endpoints(mut self, endpoints: Vec<Url>) -> Result<Self> {
|
||||
crate::config::validate_endpoints(
|
||||
&endpoints,
|
||||
self.config.dangerous_insecure_transport_protocol,
|
||||
self.context.config.dangerous_insecure_transport_protocol,
|
||||
)?;
|
||||
|
||||
self.endpoints.replace(endpoints);
|
||||
@@ -251,26 +278,40 @@ impl UpdaterBuilder {
|
||||
}
|
||||
|
||||
pub fn pubkey<S: Into<String>>(mut self, pubkey: S) -> Self {
|
||||
self.config.pubkey = pubkey.into();
|
||||
self.context.config.pubkey = pubkey.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds an argument to pass to the Windows installer.
|
||||
///
|
||||
/// Note: this applies to both WiX and NSIS installers
|
||||
#[cfg_attr(not(windows), allow(unused))]
|
||||
pub fn installer_arg<S>(mut self, arg: S) -> Self
|
||||
where
|
||||
S: Into<OsString>,
|
||||
{
|
||||
self.installer_args.push(arg.into());
|
||||
#[cfg(windows)]
|
||||
{
|
||||
self.context.installer_args.push(arg.into());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds multiple arguments to pass to the Windows installer.
|
||||
///
|
||||
/// Note: this applies to both WiX and NSIS installers
|
||||
#[cfg_attr(not(windows), allow(unused))]
|
||||
pub fn installer_args<I, S>(mut self, args: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = S>,
|
||||
S: Into<OsString>,
|
||||
{
|
||||
self.installer_args.extend(args.into_iter().map(Into::into));
|
||||
#[cfg(windows)]
|
||||
{
|
||||
self.context
|
||||
.installer_args
|
||||
.extend(args.into_iter().map(Into::into));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
@@ -280,14 +321,32 @@ impl UpdaterBuilder {
|
||||
/// [`Self::installer_arg`], [`crate::Builder::installer_arg`]
|
||||
/// and the `plugins > updater > windows > installerArgs` config,
|
||||
/// not the ones managed by us (e.g. `/UPDATER` flag passed to the NSIS installer)
|
||||
#[cfg_attr(not(windows), allow(unused))]
|
||||
pub fn clear_installer_args(mut self) -> Self {
|
||||
self.installer_args.clear();
|
||||
#[cfg(windows)]
|
||||
{
|
||||
self.context.installer_args.clear();
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Function to run before we run the installer and exit the app through `std::process::exit(0)` on Windows
|
||||
#[cfg_attr(not(windows), allow(unused))]
|
||||
pub fn on_before_exit<F: Fn() + Send + Sync + 'static>(mut self, f: F) -> Self {
|
||||
self.on_before_exit.replace(Arc::new(f));
|
||||
#[cfg(windows)]
|
||||
{
|
||||
self.context.on_before_exit.replace(Arc::new(f));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// If the Windows installer should restart the app after installed, default is `true`
|
||||
#[cfg_attr(not(windows), allow(unused))]
|
||||
pub fn restart_after_install(mut self, restart_after_install: bool) -> Self {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
self.context.restart_after_install = restart_after_install;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
@@ -299,14 +358,14 @@ impl UpdaterBuilder {
|
||||
mut self,
|
||||
f: F,
|
||||
) -> Self {
|
||||
self.configure_client.replace(Arc::new(f));
|
||||
self.context.configure_client.replace(Arc::new(f));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<Updater> {
|
||||
let endpoints = self
|
||||
.endpoints
|
||||
.unwrap_or_else(|| self.config.endpoints.clone());
|
||||
.unwrap_or_else(|| self.context.config.endpoints.clone());
|
||||
|
||||
if endpoints.is_empty() {
|
||||
return Err(Error::EmptyEndpoints);
|
||||
@@ -324,44 +383,36 @@ impl UpdaterBuilder {
|
||||
};
|
||||
|
||||
Ok(Updater {
|
||||
run_on_main_thread: Arc::new(self.run_on_main_thread),
|
||||
config: self.config,
|
||||
app_name: self.app_name,
|
||||
current_version: self.current_version,
|
||||
version_comparator: self.version_comparator,
|
||||
timeout: self.timeout,
|
||||
proxy: self.proxy,
|
||||
no_proxy: self.no_proxy,
|
||||
endpoints,
|
||||
installer_args: self.installer_args,
|
||||
current_exe_args: self.current_exe_args,
|
||||
arch,
|
||||
target: self.target,
|
||||
headers: self.headers,
|
||||
extract_path,
|
||||
on_before_exit: self.on_before_exit,
|
||||
configure_client: self.configure_client,
|
||||
context: self.context.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl UpdaterBuilder {
|
||||
pub(crate) fn current_exe_args<I, S>(mut self, args: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = S>,
|
||||
S: Into<OsString>,
|
||||
{
|
||||
self.current_exe_args
|
||||
self.context
|
||||
.current_exe_args
|
||||
.extend(args.into_iter().map(Into::into));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Updater {
|
||||
#[allow(dead_code)]
|
||||
run_on_main_thread: Arc<RunOnMainThread>,
|
||||
config: Config,
|
||||
app_name: String,
|
||||
current_version: Version,
|
||||
version_comparator: Option<VersionComparator>,
|
||||
timeout: Option<Duration>,
|
||||
@@ -374,12 +425,7 @@ pub struct Updater {
|
||||
target: Option<String>,
|
||||
headers: HeaderMap,
|
||||
extract_path: PathBuf,
|
||||
on_before_exit: Option<OnBeforeExit>,
|
||||
configure_client: Option<OnBeforeRequest>,
|
||||
#[allow(unused)]
|
||||
installer_args: Vec<OsString>,
|
||||
#[allow(unused)]
|
||||
current_exe_args: Vec<OsString>,
|
||||
context: UpdaterContext,
|
||||
}
|
||||
|
||||
impl Updater {
|
||||
@@ -449,10 +495,10 @@ impl Updater {
|
||||
}
|
||||
|
||||
let mut request = ClientBuilder::new().user_agent(UPDATER_USER_AGENT);
|
||||
if self.config.dangerous_accept_invalid_certs {
|
||||
if self.context.config.dangerous_accept_invalid_certs {
|
||||
request = request.danger_accept_invalid_certs(true);
|
||||
}
|
||||
if self.config.dangerous_accept_invalid_hostnames {
|
||||
if self.context.config.dangerous_accept_invalid_hostnames {
|
||||
request = request.danger_accept_invalid_hostnames(true);
|
||||
}
|
||||
if let Some(timeout) = self.timeout {
|
||||
@@ -467,7 +513,7 @@ impl Updater {
|
||||
request = request.proxy(proxy);
|
||||
}
|
||||
|
||||
if let Some(ref configure_client) = self.configure_client {
|
||||
if let Some(ref configure_client) = self.context.configure_client {
|
||||
request = configure_client(request);
|
||||
}
|
||||
|
||||
@@ -537,10 +583,6 @@ impl Updater {
|
||||
|
||||
let update = if should_update {
|
||||
Some(Update {
|
||||
run_on_main_thread: self.run_on_main_thread.clone(),
|
||||
config: self.config.clone(),
|
||||
on_before_exit: self.on_before_exit.clone(),
|
||||
app_name: self.app_name.clone(),
|
||||
current_version: self.current_version.to_string(),
|
||||
target: target.to_owned(),
|
||||
extract_path: self.extract_path.clone(),
|
||||
@@ -554,9 +596,7 @@ impl Updater {
|
||||
proxy: self.proxy.clone(),
|
||||
no_proxy: self.no_proxy,
|
||||
headers: self.headers.clone(),
|
||||
installer_args: self.installer_args.clone(),
|
||||
current_exe_args: self.current_exe_args.clone(),
|
||||
configure_client: self.configure_client.clone(),
|
||||
context: self.context.clone(),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
@@ -600,11 +640,6 @@ impl Updater {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Update {
|
||||
#[allow(dead_code)]
|
||||
run_on_main_thread: Arc<RunOnMainThread>,
|
||||
config: Config,
|
||||
#[allow(unused)]
|
||||
on_before_exit: Option<OnBeforeExit>,
|
||||
/// Update description
|
||||
pub body: Option<String>,
|
||||
/// Version used to check for update
|
||||
@@ -633,14 +668,7 @@ pub struct Update {
|
||||
/// Extract path
|
||||
#[allow(unused)]
|
||||
extract_path: PathBuf,
|
||||
/// App name, used for creating named tempfiles on Windows
|
||||
#[allow(unused)]
|
||||
app_name: String,
|
||||
#[allow(unused)]
|
||||
installer_args: Vec<OsString>,
|
||||
#[allow(unused)]
|
||||
current_exe_args: Vec<OsString>,
|
||||
configure_client: Option<OnBeforeRequest>,
|
||||
context: UpdaterContext,
|
||||
}
|
||||
|
||||
impl Resource for Update {}
|
||||
@@ -661,10 +689,10 @@ impl Update {
|
||||
}
|
||||
|
||||
let mut request = ClientBuilder::new().user_agent(UPDATER_USER_AGENT);
|
||||
if self.config.dangerous_accept_invalid_certs {
|
||||
if self.context.config.dangerous_accept_invalid_certs {
|
||||
request = request.danger_accept_invalid_certs(true);
|
||||
}
|
||||
if self.config.dangerous_accept_invalid_hostnames {
|
||||
if self.context.config.dangerous_accept_invalid_hostnames {
|
||||
request = request.danger_accept_invalid_hostnames(true);
|
||||
}
|
||||
if let Some(timeout) = self.timeout {
|
||||
@@ -676,7 +704,7 @@ impl Update {
|
||||
let proxy = reqwest::Proxy::all(proxy.as_str())?;
|
||||
request = request.proxy(proxy);
|
||||
}
|
||||
if let Some(ref configure_client) = self.configure_client {
|
||||
if let Some(ref configure_client) = self.context.configure_client {
|
||||
request = configure_client(request);
|
||||
}
|
||||
let response = request
|
||||
@@ -709,17 +737,27 @@ impl Update {
|
||||
}
|
||||
on_download_finish();
|
||||
|
||||
verify_signature(&buffer, &self.signature, &self.config.pubkey)?;
|
||||
verify_signature(&buffer, &self.signature, &self.context.config.pubkey)?;
|
||||
|
||||
Ok(buffer)
|
||||
}
|
||||
|
||||
/// Installs the updater package downloaded by [`Update::download`]
|
||||
///
|
||||
/// ## Platform-specific:
|
||||
///
|
||||
/// - **Windows:** This function exits the app after launching the updater installer successfully
|
||||
/// - **macOS / Linux:** You need to relaunch the app to run the newly install version
|
||||
pub fn install(&self, bytes: impl AsRef<[u8]>) -> Result<()> {
|
||||
self.install_inner(bytes.as_ref())
|
||||
}
|
||||
|
||||
/// Downloads and installs the updater package
|
||||
///
|
||||
/// ## Platform-specific:
|
||||
///
|
||||
/// - **Windows:** This function exits the app after launching the updater installer successfully
|
||||
/// - **macOS / Linux:** You need to relaunch the app to run the newly install version
|
||||
pub async fn download_and_install<C: FnMut(usize, Option<u64>), D: FnOnce()>(
|
||||
&self,
|
||||
on_chunk: C,
|
||||
@@ -733,6 +771,16 @@ impl Update {
|
||||
fn install_inner(&self, _bytes: &[u8]) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Whether the Windows installer should restart the app after installed, default is `true`
|
||||
#[cfg_attr(not(windows), allow(unused))]
|
||||
pub fn restart_after_install(mut self, restart_after_install: bool) -> Self {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
self.context.restart_after_install = restart_after_install;
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
@@ -785,7 +833,6 @@ impl Update {
|
||||
/// │ └──[AppName]_[version]_x64-setup.exe # NSIS installer
|
||||
/// └── ...
|
||||
fn install_inner(&self, bytes: &[u8]) -> Result<()> {
|
||||
use std::iter::once;
|
||||
use windows_sys::{
|
||||
w,
|
||||
Win32::UI::{Shell::ShellExecuteW, WindowsAndMessaging::SW_SHOW},
|
||||
@@ -793,48 +840,7 @@ impl Update {
|
||||
|
||||
let updater_type = self.extract(bytes)?;
|
||||
|
||||
let install_mode = self.config.install_mode();
|
||||
let current_args = &self.current_exe_args()[1..];
|
||||
let msi_args;
|
||||
let nsis_args;
|
||||
|
||||
let installer_args: Vec<&OsStr> = match &updater_type {
|
||||
WindowsUpdaterType::Nsis { .. } => {
|
||||
nsis_args = current_args
|
||||
.iter()
|
||||
.map(escape_nsis_current_exe_arg)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
install_mode
|
||||
.nsis_args()
|
||||
.iter()
|
||||
.map(OsStr::new)
|
||||
.chain(once(OsStr::new("/UPDATE")))
|
||||
.chain(once(OsStr::new("/ARGS")))
|
||||
.chain(nsis_args.iter().map(OsStr::new))
|
||||
.chain(self.installer_args())
|
||||
.collect()
|
||||
}
|
||||
WindowsUpdaterType::Msi { path, .. } => {
|
||||
let escaped_args = current_args
|
||||
.iter()
|
||||
.map(escape_msi_property_arg)
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
msi_args = OsString::from(format!("LAUNCHAPPARGS=\"{escaped_args}\""));
|
||||
|
||||
[OsStr::new("/i"), path.as_os_str()]
|
||||
.into_iter()
|
||||
.chain(install_mode.msiexec_args().iter().map(OsStr::new))
|
||||
.chain(once(OsStr::new("/promptrestart")))
|
||||
.chain(self.installer_args())
|
||||
.chain(once(OsStr::new("AUTOLAUNCHAPP=True")))
|
||||
.chain(once(msi_args.as_os_str()))
|
||||
.collect()
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(on_before_exit) = self.on_before_exit.as_ref() {
|
||||
if let Some(on_before_exit) = self.context.on_before_exit.as_ref() {
|
||||
log::debug!("running on_before_exit hook");
|
||||
on_before_exit();
|
||||
}
|
||||
@@ -846,12 +852,14 @@ impl Update {
|
||||
|p| OsString::from(format!("{p}\\System32\\msiexec.exe")),
|
||||
),
|
||||
};
|
||||
let file = encode_wide(file);
|
||||
let parameters = self.updater_parameters(&updater_type);
|
||||
|
||||
let parameters = installer_args.join(OsStr::new(" "));
|
||||
log::debug!("Executing updater {file:?} with parameters: {parameters:?}");
|
||||
|
||||
let file = encode_wide(file);
|
||||
let parameters = encode_wide(parameters);
|
||||
|
||||
unsafe {
|
||||
let result = unsafe {
|
||||
ShellExecuteW(
|
||||
std::ptr::null_mut(),
|
||||
w!("open"),
|
||||
@@ -861,22 +869,79 @@ impl Update {
|
||||
SW_SHOW,
|
||||
)
|
||||
};
|
||||
if result as isize <= 32 {
|
||||
return Err(crate::Error::Io(std::io::Error::last_os_error()));
|
||||
}
|
||||
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
fn installer_args(&self) -> Vec<&OsStr> {
|
||||
self.installer_args
|
||||
.iter()
|
||||
.map(OsStr::new)
|
||||
.collect::<Vec<_>>()
|
||||
fn updater_parameters(&self, updater_type: &WindowsUpdaterType) -> OsString {
|
||||
let install_mode = self.context.config.install_mode();
|
||||
let current_args = &self.context.current_exe_args[1..];
|
||||
|
||||
match updater_type {
|
||||
WindowsUpdaterType::Nsis { .. } => {
|
||||
let mut installer_args: Vec<&OsStr> = Vec::new();
|
||||
installer_args.extend(install_mode.nsis_args().iter().map(OsStr::new));
|
||||
installer_args.push(OsStr::new("/UPDATE"));
|
||||
|
||||
let nsis_current_exe_arg;
|
||||
if self.context.restart_after_install {
|
||||
nsis_current_exe_arg = current_args
|
||||
.iter()
|
||||
.map(escape_nsis_current_exe_arg)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
installer_args.extend(
|
||||
install_mode
|
||||
.nsis_restart_after_install_args()
|
||||
.iter()
|
||||
.map(OsStr::new),
|
||||
);
|
||||
installer_args.push(OsStr::new("/ARGS"));
|
||||
installer_args.extend(nsis_current_exe_arg.iter().map(OsStr::new));
|
||||
}
|
||||
|
||||
installer_args.extend(self.installer_args());
|
||||
|
||||
installer_args.join(OsStr::new(" "))
|
||||
}
|
||||
WindowsUpdaterType::Msi { path, .. } => {
|
||||
let mut installer_args: Vec<&OsStr> = vec![OsStr::new("/i"), path.as_os_str()];
|
||||
installer_args.extend(install_mode.msiexec_args().iter().map(OsStr::new));
|
||||
installer_args.push(OsStr::new("/promptrestart"));
|
||||
installer_args.extend(self.installer_args());
|
||||
|
||||
let msi_current_exe_arg;
|
||||
if self.context.restart_after_install {
|
||||
msi_current_exe_arg = format!(
|
||||
"LAUNCHAPPARGS=\"{}\"",
|
||||
current_args
|
||||
.iter()
|
||||
.map(escape_msi_property_arg)
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")
|
||||
);
|
||||
|
||||
installer_args.extend(
|
||||
install_mode
|
||||
.msi_restart_after_install_args()
|
||||
.iter()
|
||||
.map(OsStr::new),
|
||||
);
|
||||
installer_args.push(OsStr::new(&msi_current_exe_arg));
|
||||
}
|
||||
|
||||
installer_args.join(OsStr::new(" "))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn current_exe_args(&self) -> Vec<&OsStr> {
|
||||
self.current_exe_args
|
||||
.iter()
|
||||
.map(OsStr::new)
|
||||
.collect::<Vec<_>>()
|
||||
fn installer_args(
|
||||
&self,
|
||||
) -> std::iter::Map<std::slice::Iter<'_, OsString>, fn(&OsString) -> &OsStr> {
|
||||
self.context.installer_args.iter().map(OsStr::new)
|
||||
}
|
||||
|
||||
fn extract(&self, bytes: &[u8]) -> Result<WindowsUpdaterType> {
|
||||
@@ -890,7 +955,10 @@ impl Update {
|
||||
|
||||
fn make_temp_dir(&self) -> Result<PathBuf> {
|
||||
Ok(tempfile::Builder::new()
|
||||
.prefix(&format!("{}-{}-updater-", self.app_name, self.version))
|
||||
.prefix(&format!(
|
||||
"{}-{}-updater-",
|
||||
self.context.app_name, self.version
|
||||
))
|
||||
.tempdir()?
|
||||
.keep())
|
||||
}
|
||||
@@ -938,7 +1006,10 @@ impl Update {
|
||||
|
||||
let temp_dir = self.make_temp_dir()?;
|
||||
let mut temp_file = tempfile::Builder::new()
|
||||
.prefix(&format!("{}-{}-installer", self.app_name, self.version))
|
||||
.prefix(&format!(
|
||||
"{}-{}-installer",
|
||||
self.context.app_name, self.version
|
||||
))
|
||||
.suffix(ext)
|
||||
.rand_bytes(0)
|
||||
.tempfile_in(temp_dir)?;
|
||||
@@ -1277,7 +1348,7 @@ impl Update {
|
||||
);
|
||||
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
let res = (self.run_on_main_thread)(Box::new(move || {
|
||||
let res = (self.context.run_on_main_thread)(Box::new(move || {
|
||||
let mut script =
|
||||
osakit::Script::new_from_source(osakit::Language::AppleScript, &apple_script);
|
||||
script.compile().expect("invalid AppleScript");
|
||||
@@ -1450,7 +1521,7 @@ where
|
||||
}
|
||||
|
||||
// Validate signature
|
||||
fn verify_signature(data: &[u8], release_signature: &str, pub_key: &str) -> Result<bool> {
|
||||
fn verify_signature(data: &[u8], release_signature: &str, pub_key: &str) -> Result<()> {
|
||||
// we need to convert the pub key
|
||||
let pub_key_decoded = base64_to_string(pub_key)?;
|
||||
let public_key = PublicKey::decode(&pub_key_decoded)?;
|
||||
@@ -1459,7 +1530,7 @@ fn verify_signature(data: &[u8], release_signature: &str, pub_key: &str) -> Resu
|
||||
|
||||
// Validate signature or bail out
|
||||
public_key.verify(data, &signature, true)?;
|
||||
Ok(true)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn base64_to_string(base64_string: &str) -> Result<String> {
|
||||
@@ -1498,25 +1569,31 @@ impl PathExt for PathBuf {
|
||||
|
||||
// adapted from https://github.com/rust-lang/rust/blob/1c047506f94cd2d05228eb992b0a6bbed1942349/library/std/src/sys/args/windows.rs#L174
|
||||
#[cfg(windows)]
|
||||
fn escape_nsis_current_exe_arg(arg: &&OsStr) -> String {
|
||||
let arg = arg.to_string_lossy();
|
||||
let mut cmd: Vec<char> = Vec::new();
|
||||
fn escape_nsis_current_exe_arg(arg: impl AsRef<OsStr>) -> OsString {
|
||||
use std::os::windows::ffi::{OsStrExt, OsStringExt};
|
||||
|
||||
let arg = arg.as_ref();
|
||||
let mut cmd: Vec<u16> = Vec::new();
|
||||
|
||||
// compared to std we additionally escape `/` so that nsis won't interpret them as a beginning of an nsis argument.
|
||||
let quote = arg.chars().any(|c| c == ' ' || c == '\t' || c == '/') || arg.is_empty();
|
||||
let quote = arg
|
||||
.as_encoded_bytes()
|
||||
.iter()
|
||||
.any(|c| *c == b' ' || *c == b'\t' || *c == b'/')
|
||||
|| arg.is_empty();
|
||||
let escape = true;
|
||||
if quote {
|
||||
cmd.push('"');
|
||||
cmd.push('"' as u16);
|
||||
}
|
||||
let mut backslashes: usize = 0;
|
||||
for x in arg.chars() {
|
||||
for x in arg.encode_wide() {
|
||||
if escape {
|
||||
if x == '\\' {
|
||||
if x == '\\' as u16 {
|
||||
backslashes += 1;
|
||||
} else {
|
||||
if x == '"' {
|
||||
if x == '"' as u16 {
|
||||
// Add n+1 backslashes to total 2n+1 before internal '"'.
|
||||
cmd.extend((0..=backslashes).map(|_| '\\'));
|
||||
cmd.extend((0..=backslashes).map(|_| '\\' as u16));
|
||||
}
|
||||
backslashes = 0;
|
||||
}
|
||||
@@ -1525,10 +1602,10 @@ fn escape_nsis_current_exe_arg(arg: &&OsStr) -> String {
|
||||
}
|
||||
if quote {
|
||||
// Add n backslashes to total 2n before ending '"'.
|
||||
cmd.extend((0..backslashes).map(|_| '\\'));
|
||||
cmd.push('"');
|
||||
cmd.extend((0..backslashes).map(|_| '\\' as u16));
|
||||
cmd.push('"' as u16);
|
||||
}
|
||||
cmd.into_iter().collect()
|
||||
OsString::from_wide(&cmd)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
|
||||
@@ -13,6 +13,3 @@ serde_json = { workspace = true }
|
||||
tauri-plugin-updater = { path = "../.." }
|
||||
tiny_http = "0.12"
|
||||
time = { version = "0.3", features = ["formatting"] }
|
||||
|
||||
[features]
|
||||
prod = ["tauri/custom-protocol"]
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
"endpoints": ["http://localhost:3007"],
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEUwNDRGMjkwRjg2MDhCRDAKUldUUWkyRDRrUEpFNEQ4SmdwcU5PaXl6R2ZRUUNvUnhIaVkwVUltV0NMaEx6VTkrWVhpT0ZqeEEK",
|
||||
"windows": {
|
||||
"installMode": "quiet",
|
||||
"installerArgs": ["/NS"]
|
||||
"installMode": "quiet"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -46,7 +46,7 @@ struct Update {
|
||||
platforms: HashMap<String, PlatformUpdate>,
|
||||
}
|
||||
|
||||
fn build_app(cwd: &Path, config: &Config, bundle_updater: bool, target: BundleTarget) {
|
||||
fn build_app(cwd: &Path, config: &Config, target: Option<BundleTarget>) {
|
||||
let mut command = Command::new("cargo");
|
||||
command
|
||||
.args(["tauri", "build", "--verbose"])
|
||||
@@ -56,17 +56,10 @@ fn build_app(cwd: &Path, config: &Config, bundle_updater: bool, target: BundleTa
|
||||
.env("TAURI_SIGNING_PRIVATE_KEY_PASSWORD", "")
|
||||
.current_dir(cwd);
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
command.args(["--bundles", target.name()]);
|
||||
#[cfg(target_os = "macos")]
|
||||
command.args(["--bundles", target.name()]);
|
||||
|
||||
if bundle_updater {
|
||||
#[cfg(windows)]
|
||||
command.args(["--bundles", "msi", "nsis"]);
|
||||
if let Some(target) = target {
|
||||
command.arg("--bundles").arg(target.name());
|
||||
} else {
|
||||
#[cfg(windows)]
|
||||
command.args(["--bundles", target.name()]);
|
||||
command.arg("--no-bundle");
|
||||
}
|
||||
|
||||
let status = command
|
||||
@@ -318,7 +311,7 @@ fn update_app() {
|
||||
{
|
||||
// bundle app update
|
||||
config.version = "1.0.0";
|
||||
build_app(&manifest_dir, &config, true, BundleTarget::default());
|
||||
build_app(&manifest_dir, &config, Some(bundle_target));
|
||||
|
||||
let bundle_updater_ext = if v1_compatible {
|
||||
out_bundle_path
|
||||
@@ -401,7 +394,7 @@ fn update_app() {
|
||||
config.version = "0.1.0";
|
||||
|
||||
// bundle initial app version
|
||||
build_app(&manifest_dir, &config, false, bundle_target);
|
||||
build_app(&manifest_dir, &config, None);
|
||||
|
||||
for expected_exit_code in status_checks {
|
||||
let mut binary_cmd = if cfg!(windows) {
|
||||
|
||||
+3
-3
@@ -3794,7 +3794,7 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4137,9 +4137,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.24.10"
|
||||
version = "0.24.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00711278ed357350d44c749c286786ecac644e044e4da410d466212152383b45"
|
||||
checksum = "4a2a144c3ab5e83e04724bc8e67cea552ffae413185fda459fafdae173fd985d"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"block",
|
||||
|
||||
@@ -8,6 +8,14 @@ edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-upload"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/test",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
@@ -27,7 +35,7 @@ log = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
tokio = { version = "1", features = ["fs"] }
|
||||
tokio-util = { version = "0.7", features = ["codec"] }
|
||||
reqwest = { version = "0.12", default-features = false, features = [
|
||||
reqwest = { version = "0.13", default-features = false, features = [
|
||||
"macos-system-configuration",
|
||||
"json",
|
||||
"stream",
|
||||
|
||||
@@ -5,6 +5,12 @@
|
||||
//! Upload files from disk to a remote server over HTTP.
|
||||
//!
|
||||
//! Download files from a remote HTTP server to disk.
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! - **rustls-tls** *(enabled by default)*: Enables TLS functionality provided by `rustls`.
|
||||
//! - **native-tls**: Enables TLS functionality provided by `native-tls`.
|
||||
//! - **native-tls-vendored**: Enables the `vendored` feature of `native-tls`.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
|
||||
@@ -8,7 +8,14 @@ edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-websocket"
|
||||
exclude = ["/examples"]
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/examples",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "2.11.4",
|
||||
"typescript": "^6.0.0",
|
||||
"vite": "^8.0.1"
|
||||
"typescript": "^6.0.3",
|
||||
"vite": "^8.0.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"tauri-plugin-websocket-api": "link:..\\.."
|
||||
|
||||
@@ -15,6 +15,3 @@ tokio-tungstenite = "0.29"
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { workspace = true }
|
||||
|
||||
[features]
|
||||
prod = ["tauri/custom-protocol"]
|
||||
|
||||
@@ -3,6 +3,15 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Open a WebSocket connection using a Rust client in JS.
|
||||
//!
|
||||
//! ## Cargo features
|
||||
//!
|
||||
//! - **rustls-tls** *(enabled by default)*: Enables TLS functionality provided by `rustls` with WebPKI roots.
|
||||
//! - **rustls-tls-native-roots**: Enables TLS functionality provided by `rustls` with the platform's native certificate roots.
|
||||
//! - **native-tls**: Enables TLS functionality provided by `native-tls`.
|
||||
//! - **native-tls-vendored**: Enables the `vendored` feature of `native-tls`.
|
||||
//!
|
||||
//! At least one TLS feature is required for `wss://`; plain `ws://` works without one.
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
|
||||
|
||||
@@ -8,6 +8,13 @@ edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-window-state"
|
||||
exclude = [
|
||||
"/banner.png",
|
||||
"/guest-js",
|
||||
"/package.json",
|
||||
"/rollup.config.js",
|
||||
"/tsconfig.json",
|
||||
]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
windows = { level = "full", notes = "" }
|
||||
|
||||
Generated
+154
-170
@@ -13,13 +13,13 @@ importers:
|
||||
version: 10.0.1(eslint@10.4.0(jiti@2.6.1))
|
||||
'@rollup/plugin-node-resolve':
|
||||
specifier: 16.0.3
|
||||
version: 16.0.3(rollup@4.60.3)
|
||||
version: 16.0.3(rollup@4.62.2)
|
||||
'@rollup/plugin-terser':
|
||||
specifier: 1.0.0
|
||||
version: 1.0.0(rollup@4.60.3)
|
||||
version: 1.0.0(rollup@4.62.2)
|
||||
'@rollup/plugin-typescript':
|
||||
specifier: 12.3.0
|
||||
version: 12.3.0(rollup@4.60.3)(tslib@2.8.1)(typescript@6.0.3)
|
||||
version: 12.3.0(rollup@4.62.2)(tslib@2.8.1)(typescript@6.0.3)
|
||||
eslint:
|
||||
specifier: 10.4.0
|
||||
version: 10.4.0(jiti@2.6.1)
|
||||
@@ -33,8 +33,8 @@ importers:
|
||||
specifier: 3.8.3
|
||||
version: 3.8.3
|
||||
rollup:
|
||||
specifier: 4.60.3
|
||||
version: 4.60.3
|
||||
specifier: 4.62.2
|
||||
version: 4.62.2
|
||||
tslib:
|
||||
specifier: 2.8.1
|
||||
version: 2.8.1
|
||||
@@ -63,8 +63,8 @@ importers:
|
||||
specifier: workspace:*
|
||||
version: link:../../plugins/clipboard-manager
|
||||
'@tauri-apps/plugin-dialog':
|
||||
specifier: '2'
|
||||
version: 2.7.1
|
||||
specifier: workspace:*
|
||||
version: link:../../plugins/dialog
|
||||
'@tauri-apps/plugin-fs':
|
||||
specifier: workspace:*
|
||||
version: link:../../plugins/fs
|
||||
@@ -99,8 +99,8 @@ importers:
|
||||
specifier: workspace:*
|
||||
version: link:../../plugins/shell
|
||||
'@tauri-apps/plugin-store':
|
||||
specifier: '2'
|
||||
version: 2.4.3
|
||||
specifier: workspace:*
|
||||
version: link:../../plugins/store
|
||||
'@tauri-apps/plugin-updater':
|
||||
specifier: workspace:*
|
||||
version: link:../../plugins/updater
|
||||
@@ -108,8 +108,8 @@ importers:
|
||||
specifier: workspace:*
|
||||
version: link:../../plugins/upload
|
||||
'@zerodevx/svelte-json-view':
|
||||
specifier: 1.0.11
|
||||
version: 1.0.11(svelte@5.55.7(@typescript-eslint/types@8.58.2))
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0(svelte@5.55.7(@typescript-eslint/types@8.58.2))
|
||||
devDependencies:
|
||||
'@iconify-json/codicon':
|
||||
specifier: ^1.2.49
|
||||
@@ -127,13 +127,13 @@ importers:
|
||||
specifier: ^66.6.7
|
||||
version: 66.6.7
|
||||
svelte:
|
||||
specifier: ^5.54.0
|
||||
specifier: ^5.55.7
|
||||
version: 5.55.7(@typescript-eslint/types@8.58.2)
|
||||
unocss:
|
||||
specifier: ^66.6.7
|
||||
version: 66.6.7(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(vite@8.0.16(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.1)(tsx@4.23.1))
|
||||
vite:
|
||||
specifier: ^8.0.1
|
||||
specifier: ^8.0.16
|
||||
version: 8.0.16(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.1)(tsx@4.23.1)
|
||||
|
||||
plugins/autostart:
|
||||
@@ -189,10 +189,10 @@ importers:
|
||||
specifier: 2.11.4
|
||||
version: 2.11.4
|
||||
typescript:
|
||||
specifier: ^6.0.0
|
||||
specifier: ^6.0.3
|
||||
version: 6.0.3
|
||||
vite:
|
||||
specifier: ^8.0.1
|
||||
specifier: ^8.0.16
|
||||
version: 8.0.16(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.1)(tsx@4.23.1)
|
||||
|
||||
plugins/dialog:
|
||||
@@ -303,10 +303,10 @@ importers:
|
||||
specifier: 2.11.4
|
||||
version: 2.11.4
|
||||
typescript:
|
||||
specifier: ^6.0.0
|
||||
specifier: ^6.0.3
|
||||
version: 6.0.3
|
||||
vite:
|
||||
specifier: ^8.0.1
|
||||
specifier: ^8.0.16
|
||||
version: 8.0.16(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.1)(tsx@4.23.1)
|
||||
|
||||
plugins/stronghold:
|
||||
@@ -343,10 +343,10 @@ importers:
|
||||
specifier: 2.11.4
|
||||
version: 2.11.4
|
||||
typescript:
|
||||
specifier: ^6.0.0
|
||||
specifier: ^6.0.3
|
||||
version: 6.0.3
|
||||
vite:
|
||||
specifier: ^8.0.1
|
||||
specifier: ^8.0.16
|
||||
version: 8.0.16(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.1)(tsx@4.23.1)
|
||||
|
||||
plugins/window-state:
|
||||
@@ -894,141 +894,141 @@ packages:
|
||||
rollup:
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.60.3':
|
||||
resolution: {integrity: sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==}
|
||||
'@rollup/rollup-android-arm-eabi@4.62.2':
|
||||
resolution: {integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-android-arm64@4.60.3':
|
||||
resolution: {integrity: sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==}
|
||||
'@rollup/rollup-android-arm64@4.62.2':
|
||||
resolution: {integrity: sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.60.3':
|
||||
resolution: {integrity: sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==}
|
||||
'@rollup/rollup-darwin-arm64@4.62.2':
|
||||
resolution: {integrity: sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.60.3':
|
||||
resolution: {integrity: sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw==}
|
||||
'@rollup/rollup-darwin-x64@4.62.2':
|
||||
resolution: {integrity: sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.60.3':
|
||||
resolution: {integrity: sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==}
|
||||
'@rollup/rollup-freebsd-arm64@4.62.2':
|
||||
resolution: {integrity: sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.60.3':
|
||||
resolution: {integrity: sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==}
|
||||
'@rollup/rollup-freebsd-x64@4.62.2':
|
||||
resolution: {integrity: sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.60.3':
|
||||
resolution: {integrity: sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==}
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.62.2':
|
||||
resolution: {integrity: sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.60.3':
|
||||
resolution: {integrity: sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==}
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.62.2':
|
||||
resolution: {integrity: sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.60.3':
|
||||
resolution: {integrity: sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==}
|
||||
'@rollup/rollup-linux-arm64-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.60.3':
|
||||
resolution: {integrity: sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==}
|
||||
'@rollup/rollup-linux-arm64-musl@4.62.2':
|
||||
resolution: {integrity: sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.60.3':
|
||||
resolution: {integrity: sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==}
|
||||
'@rollup/rollup-linux-loong64-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-loong64-musl@4.60.3':
|
||||
resolution: {integrity: sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==}
|
||||
'@rollup/rollup-linux-loong64-musl@4.62.2':
|
||||
resolution: {integrity: sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.60.3':
|
||||
resolution: {integrity: sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==}
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-musl@4.60.3':
|
||||
resolution: {integrity: sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==}
|
||||
'@rollup/rollup-linux-ppc64-musl@4.62.2':
|
||||
resolution: {integrity: sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.60.3':
|
||||
resolution: {integrity: sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==}
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.60.3':
|
||||
resolution: {integrity: sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==}
|
||||
'@rollup/rollup-linux-riscv64-musl@4.62.2':
|
||||
resolution: {integrity: sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.60.3':
|
||||
resolution: {integrity: sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==}
|
||||
'@rollup/rollup-linux-s390x-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.60.3':
|
||||
resolution: {integrity: sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==}
|
||||
'@rollup/rollup-linux-x64-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.60.3':
|
||||
resolution: {integrity: sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==}
|
||||
'@rollup/rollup-linux-x64-musl@4.62.2':
|
||||
resolution: {integrity: sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-openbsd-x64@4.60.3':
|
||||
resolution: {integrity: sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==}
|
||||
'@rollup/rollup-openbsd-x64@4.62.2':
|
||||
resolution: {integrity: sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.60.3':
|
||||
resolution: {integrity: sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==}
|
||||
'@rollup/rollup-openharmony-arm64@4.62.2':
|
||||
resolution: {integrity: sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.60.3':
|
||||
resolution: {integrity: sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==}
|
||||
'@rollup/rollup-win32-arm64-msvc@4.62.2':
|
||||
resolution: {integrity: sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.60.3':
|
||||
resolution: {integrity: sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==}
|
||||
'@rollup/rollup-win32-ia32-msvc@4.62.2':
|
||||
resolution: {integrity: sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-x64-gnu@4.60.3':
|
||||
resolution: {integrity: sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==}
|
||||
'@rollup/rollup-win32-x64-gnu@4.62.2':
|
||||
resolution: {integrity: sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.60.3':
|
||||
resolution: {integrity: sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==}
|
||||
'@rollup/rollup-win32-x64-msvc@4.62.2':
|
||||
resolution: {integrity: sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
@@ -1123,21 +1123,12 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
hasBin: true
|
||||
|
||||
'@tauri-apps/plugin-dialog@2.7.1':
|
||||
resolution: {integrity: sha512-OK1UBXYt+ojcmxMktzzuyonYIFta8CmAASpX+CA+DTGK24KlHjhYI6x2iOJ/TjZF4N7/ACK1oFmEOjIY9IhzOQ==}
|
||||
|
||||
'@tauri-apps/plugin-store@2.4.3':
|
||||
resolution: {integrity: sha512-9LWPj9yMphRi9czEtUv87XHbl1b6xgd9EXpPrUnq6nG7+nbtoF84d4Kwz9xhAv/Hf30sr58pq7EOlyI936y8qw==}
|
||||
|
||||
'@tybys/wasm-util@0.10.2':
|
||||
resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==}
|
||||
|
||||
'@types/esrecurse@4.3.1':
|
||||
resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==}
|
||||
|
||||
'@types/estree@1.0.8':
|
||||
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
||||
|
||||
'@types/estree@1.0.9':
|
||||
resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
|
||||
|
||||
@@ -1281,10 +1272,13 @@ packages:
|
||||
peerDependencies:
|
||||
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0-0
|
||||
|
||||
'@zerodevx/svelte-json-view@1.0.11':
|
||||
resolution: {integrity: sha512-mIjj0H1al/P4FPlbeDoiey93lNEUqBEAe5LIdD5GttZfEYt3awexD2lHwKNfUeY4jHizOJkoWTPN/2iO0GBqpw==}
|
||||
'@zerodevx/svelte-json-view@2.0.0':
|
||||
resolution: {integrity: sha512-bzkyssGxz0Z6Utv80vxBBkfkTzW1ZkkJ28cAmURc2+ytMPd6zTH7LRiUJgJf14gIzdeRRYNkD7CZ/MHPlP7LVQ==}
|
||||
peerDependencies:
|
||||
svelte: ^3.57.0 || ^4.0.0 || ^5.0.0
|
||||
svelte: ^5.0.0
|
||||
peerDependenciesMeta:
|
||||
svelte:
|
||||
optional: true
|
||||
|
||||
acorn-jsx@5.3.2:
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
@@ -1311,9 +1305,9 @@ packages:
|
||||
resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
|
||||
engines: {node: 18 || 20 || >=22}
|
||||
|
||||
brace-expansion@5.0.6:
|
||||
resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==}
|
||||
engines: {node: 18 || 20 || >=22}
|
||||
brace-expansion@5.0.9:
|
||||
resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
buffer-from@1.1.2:
|
||||
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
|
||||
@@ -1671,8 +1665,8 @@ packages:
|
||||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
nanoid@3.3.12:
|
||||
resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==}
|
||||
nanoid@3.3.16:
|
||||
resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==}
|
||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
hasBin: true
|
||||
|
||||
@@ -1739,8 +1733,8 @@ packages:
|
||||
pkg-types@1.3.1:
|
||||
resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
|
||||
|
||||
postcss@8.5.15:
|
||||
resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==}
|
||||
postcss@8.5.23:
|
||||
resolution: {integrity: sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
prelude-ls@1.2.1:
|
||||
@@ -1777,8 +1771,8 @@ packages:
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
|
||||
rollup@4.60.3:
|
||||
resolution: {integrity: sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==}
|
||||
rollup@4.62.2:
|
||||
resolution: {integrity: sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
@@ -2303,114 +2297,114 @@ snapshots:
|
||||
|
||||
'@rolldown/pluginutils@1.0.1': {}
|
||||
|
||||
'@rollup/plugin-node-resolve@16.0.3(rollup@4.60.3)':
|
||||
'@rollup/plugin-node-resolve@16.0.3(rollup@4.62.2)':
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.60.3)
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.62.2)
|
||||
'@types/resolve': 1.20.2
|
||||
deepmerge: 4.3.1
|
||||
is-module: 1.0.0
|
||||
resolve: 1.22.11
|
||||
optionalDependencies:
|
||||
rollup: 4.60.3
|
||||
rollup: 4.62.2
|
||||
|
||||
'@rollup/plugin-terser@1.0.0(rollup@4.60.3)':
|
||||
'@rollup/plugin-terser@1.0.0(rollup@4.62.2)':
|
||||
dependencies:
|
||||
serialize-javascript: 7.0.5
|
||||
smob: 1.6.1
|
||||
terser: 5.46.1
|
||||
optionalDependencies:
|
||||
rollup: 4.60.3
|
||||
rollup: 4.62.2
|
||||
|
||||
'@rollup/plugin-typescript@12.3.0(rollup@4.60.3)(tslib@2.8.1)(typescript@6.0.3)':
|
||||
'@rollup/plugin-typescript@12.3.0(rollup@4.62.2)(tslib@2.8.1)(typescript@6.0.3)':
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.60.3)
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.62.2)
|
||||
resolve: 1.22.11
|
||||
typescript: 6.0.3
|
||||
optionalDependencies:
|
||||
rollup: 4.60.3
|
||||
rollup: 4.62.2
|
||||
tslib: 2.8.1
|
||||
|
||||
'@rollup/pluginutils@5.3.0(rollup@4.60.3)':
|
||||
'@rollup/pluginutils@5.3.0(rollup@4.62.2)':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.9
|
||||
estree-walker: 2.0.2
|
||||
picomatch: 4.0.4
|
||||
optionalDependencies:
|
||||
rollup: 4.60.3
|
||||
rollup: 4.62.2
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.60.3':
|
||||
'@rollup/rollup-android-arm-eabi@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm64@4.60.3':
|
||||
'@rollup/rollup-android-arm64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.60.3':
|
||||
'@rollup/rollup-darwin-arm64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.60.3':
|
||||
'@rollup/rollup-darwin-x64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.60.3':
|
||||
'@rollup/rollup-freebsd-arm64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.60.3':
|
||||
'@rollup/rollup-freebsd-x64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.60.3':
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.60.3':
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.60.3':
|
||||
'@rollup/rollup-linux-arm64-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.60.3':
|
||||
'@rollup/rollup-linux-arm64-musl@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.60.3':
|
||||
'@rollup/rollup-linux-loong64-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-loong64-musl@4.60.3':
|
||||
'@rollup/rollup-linux-loong64-musl@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.60.3':
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-ppc64-musl@4.60.3':
|
||||
'@rollup/rollup-linux-ppc64-musl@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.60.3':
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.60.3':
|
||||
'@rollup/rollup-linux-riscv64-musl@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.60.3':
|
||||
'@rollup/rollup-linux-s390x-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.60.3':
|
||||
'@rollup/rollup-linux-x64-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.60.3':
|
||||
'@rollup/rollup-linux-x64-musl@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-openbsd-x64@4.60.3':
|
||||
'@rollup/rollup-openbsd-x64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.60.3':
|
||||
'@rollup/rollup-openharmony-arm64@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.60.3':
|
||||
'@rollup/rollup-win32-arm64-msvc@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.60.3':
|
||||
'@rollup/rollup-win32-ia32-msvc@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-gnu@4.60.3':
|
||||
'@rollup/rollup-win32-x64-gnu@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.60.3':
|
||||
'@rollup/rollup-win32-x64-msvc@4.62.2':
|
||||
optional: true
|
||||
|
||||
'@sveltejs/acorn-typescript@1.0.9(acorn@8.16.0)':
|
||||
@@ -2475,14 +2469,6 @@ snapshots:
|
||||
'@tauri-apps/cli-win32-ia32-msvc': 2.11.4
|
||||
'@tauri-apps/cli-win32-x64-msvc': 2.11.4
|
||||
|
||||
'@tauri-apps/plugin-dialog@2.7.1':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.11.0
|
||||
|
||||
'@tauri-apps/plugin-store@2.4.3':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.11.0
|
||||
|
||||
'@tybys/wasm-util@0.10.2':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
@@ -2490,8 +2476,6 @@ snapshots:
|
||||
|
||||
'@types/esrecurse@4.3.1': {}
|
||||
|
||||
'@types/estree@1.0.8': {}
|
||||
|
||||
'@types/estree@1.0.9': {}
|
||||
|
||||
'@types/json-schema@7.0.15': {}
|
||||
@@ -2725,8 +2709,8 @@ snapshots:
|
||||
unplugin-utils: 0.3.1
|
||||
vite: 8.0.16(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.1)(tsx@4.23.1)
|
||||
|
||||
'@zerodevx/svelte-json-view@1.0.11(svelte@5.55.7(@typescript-eslint/types@8.58.2))':
|
||||
dependencies:
|
||||
'@zerodevx/svelte-json-view@2.0.0(svelte@5.55.7(@typescript-eslint/types@8.58.2))':
|
||||
optionalDependencies:
|
||||
svelte: 5.55.7(@typescript-eslint/types@8.58.2)
|
||||
|
||||
acorn-jsx@5.3.2(acorn@8.16.0):
|
||||
@@ -2748,7 +2732,7 @@ snapshots:
|
||||
|
||||
balanced-match@4.0.4: {}
|
||||
|
||||
brace-expansion@5.0.6:
|
||||
brace-expansion@5.0.9:
|
||||
dependencies:
|
||||
balanced-match: 4.0.4
|
||||
|
||||
@@ -3076,7 +3060,7 @@ snapshots:
|
||||
|
||||
minimatch@10.2.4:
|
||||
dependencies:
|
||||
brace-expansion: 5.0.6
|
||||
brace-expansion: 5.0.9
|
||||
|
||||
mlly@1.8.2:
|
||||
dependencies:
|
||||
@@ -3089,7 +3073,7 @@ snapshots:
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
nanoid@3.3.12: {}
|
||||
nanoid@3.3.16: {}
|
||||
|
||||
natural-compare@1.4.0: {}
|
||||
|
||||
@@ -3175,9 +3159,9 @@ snapshots:
|
||||
mlly: 1.8.2
|
||||
pathe: 2.0.3
|
||||
|
||||
postcss@8.5.15:
|
||||
postcss@8.5.23:
|
||||
dependencies:
|
||||
nanoid: 3.3.12
|
||||
nanoid: 3.3.16
|
||||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
@@ -3220,35 +3204,35 @@ snapshots:
|
||||
'@rolldown/binding-win32-arm64-msvc': 1.0.3
|
||||
'@rolldown/binding-win32-x64-msvc': 1.0.3
|
||||
|
||||
rollup@4.60.3:
|
||||
rollup@4.62.2:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
'@types/estree': 1.0.9
|
||||
optionalDependencies:
|
||||
'@rollup/rollup-android-arm-eabi': 4.60.3
|
||||
'@rollup/rollup-android-arm64': 4.60.3
|
||||
'@rollup/rollup-darwin-arm64': 4.60.3
|
||||
'@rollup/rollup-darwin-x64': 4.60.3
|
||||
'@rollup/rollup-freebsd-arm64': 4.60.3
|
||||
'@rollup/rollup-freebsd-x64': 4.60.3
|
||||
'@rollup/rollup-linux-arm-gnueabihf': 4.60.3
|
||||
'@rollup/rollup-linux-arm-musleabihf': 4.60.3
|
||||
'@rollup/rollup-linux-arm64-gnu': 4.60.3
|
||||
'@rollup/rollup-linux-arm64-musl': 4.60.3
|
||||
'@rollup/rollup-linux-loong64-gnu': 4.60.3
|
||||
'@rollup/rollup-linux-loong64-musl': 4.60.3
|
||||
'@rollup/rollup-linux-ppc64-gnu': 4.60.3
|
||||
'@rollup/rollup-linux-ppc64-musl': 4.60.3
|
||||
'@rollup/rollup-linux-riscv64-gnu': 4.60.3
|
||||
'@rollup/rollup-linux-riscv64-musl': 4.60.3
|
||||
'@rollup/rollup-linux-s390x-gnu': 4.60.3
|
||||
'@rollup/rollup-linux-x64-gnu': 4.60.3
|
||||
'@rollup/rollup-linux-x64-musl': 4.60.3
|
||||
'@rollup/rollup-openbsd-x64': 4.60.3
|
||||
'@rollup/rollup-openharmony-arm64': 4.60.3
|
||||
'@rollup/rollup-win32-arm64-msvc': 4.60.3
|
||||
'@rollup/rollup-win32-ia32-msvc': 4.60.3
|
||||
'@rollup/rollup-win32-x64-gnu': 4.60.3
|
||||
'@rollup/rollup-win32-x64-msvc': 4.60.3
|
||||
'@rollup/rollup-android-arm-eabi': 4.62.2
|
||||
'@rollup/rollup-android-arm64': 4.62.2
|
||||
'@rollup/rollup-darwin-arm64': 4.62.2
|
||||
'@rollup/rollup-darwin-x64': 4.62.2
|
||||
'@rollup/rollup-freebsd-arm64': 4.62.2
|
||||
'@rollup/rollup-freebsd-x64': 4.62.2
|
||||
'@rollup/rollup-linux-arm-gnueabihf': 4.62.2
|
||||
'@rollup/rollup-linux-arm-musleabihf': 4.62.2
|
||||
'@rollup/rollup-linux-arm64-gnu': 4.62.2
|
||||
'@rollup/rollup-linux-arm64-musl': 4.62.2
|
||||
'@rollup/rollup-linux-loong64-gnu': 4.62.2
|
||||
'@rollup/rollup-linux-loong64-musl': 4.62.2
|
||||
'@rollup/rollup-linux-ppc64-gnu': 4.62.2
|
||||
'@rollup/rollup-linux-ppc64-musl': 4.62.2
|
||||
'@rollup/rollup-linux-riscv64-gnu': 4.62.2
|
||||
'@rollup/rollup-linux-riscv64-musl': 4.62.2
|
||||
'@rollup/rollup-linux-s390x-gnu': 4.62.2
|
||||
'@rollup/rollup-linux-x64-gnu': 4.62.2
|
||||
'@rollup/rollup-linux-x64-musl': 4.62.2
|
||||
'@rollup/rollup-openbsd-x64': 4.62.2
|
||||
'@rollup/rollup-openharmony-arm64': 4.62.2
|
||||
'@rollup/rollup-win32-arm64-msvc': 4.62.2
|
||||
'@rollup/rollup-win32-ia32-msvc': 4.62.2
|
||||
'@rollup/rollup-win32-x64-gnu': 4.62.2
|
||||
'@rollup/rollup-win32-x64-msvc': 4.62.2
|
||||
fsevents: 2.3.3
|
||||
|
||||
safe-regex@2.1.1:
|
||||
@@ -3412,7 +3396,7 @@ snapshots:
|
||||
dependencies:
|
||||
lightningcss: 1.32.0
|
||||
picomatch: 4.0.4
|
||||
postcss: 8.5.15
|
||||
postcss: 8.5.23
|
||||
rolldown: 1.0.3
|
||||
tinyglobby: 0.2.17
|
||||
optionalDependencies:
|
||||
|
||||
Reference in New Issue
Block a user