From 13365872e132ac8fe5531fa1698466109d5bee97 Mon Sep 17 00:00:00 2001 From: jLynx Date: Thu, 31 Oct 2024 09:31:21 +1300 Subject: [PATCH 01/51] Added deb to build --- .../src/bundle/updater_bundle.rs | 113 ++++++++++++++---- 1 file changed, 89 insertions(+), 24 deletions(-) diff --git a/crates/tauri-bundler/src/bundle/updater_bundle.rs b/crates/tauri-bundler/src/bundle/updater_bundle.rs index 77749afca21e..d08ccdb7876f 100644 --- a/crates/tauri-bundler/src/bundle/updater_bundle.rs +++ b/crates/tauri-bundler/src/bundle/updater_bundle.rs @@ -25,6 +25,7 @@ use std::{ use anyhow::Context; use zip::write::SimpleFileOptions; +use std::process::Command; // Build update pub fn bundle_project(settings: &Settings, bundles: &[Bundle]) -> crate::Result> { @@ -42,7 +43,7 @@ pub fn bundle_project(settings: &Settings, bundles: &[Bundle]) -> crate::Result< #[cfg(target_os = "macos")] return bundle_update_macos(bundles); #[cfg(target_os = "linux")] - return bundle_update_linux(bundles); + return bundle_update_linux(settings, bundles); #[cfg(not(any(target_os = "macos", target_os = "linux")))] { @@ -90,34 +91,98 @@ fn bundle_update_macos(bundles: &[Bundle]) -> crate::Result> { // Right now in linux we hot replace the bin and request a restart // No assets are replaced #[cfg(target_os = "linux")] -fn bundle_update_linux(bundles: &[Bundle]) -> crate::Result> { - use std::ffi::OsStr; +fn bundle_update_linux(settings: &Settings, bundles: &[Bundle]) -> crate::Result> { + use std::ffi::OsStr; - // build our app actually we support only appimage on linux - if let Some(source_path) = bundles - .iter() - .filter(|bundle| bundle.package_type == crate::PackageType::AppImage) - .find_map(|bundle| { - bundle - .bundle_paths + let mut update_artifacts = Vec::new(); + + // Handle AppImage updates + if let Some(source_path) = bundles .iter() - .find(|path| path.extension() == Some(OsStr::new("AppImage"))) - }) - { - // add .tar.gz to our path - let appimage_archived = format!("{}.tar.gz", source_path.display()); - let appimage_archived_path = PathBuf::from(&appimage_archived); + .filter(|bundle| bundle.package_type == crate::PackageType::AppImage) + .find_map(|bundle| { + bundle + .bundle_paths + .iter() + .find(|path| path.extension() == Some(OsStr::new("AppImage"))) + }) + { + // add .tar.gz to our path + let appimage_archived = format!("{}.tar.gz", source_path.display()); + let appimage_archived_path = PathBuf::from(&appimage_archived); + + // Create our gzip file + create_tar(source_path, &appimage_archived_path) + .with_context(|| "Failed to tar.gz update directory")?; + + log::info!(action = "Bundling"; "{} ({})", appimage_archived, display_path(&appimage_archived_path)); + + update_artifacts.push(appimage_archived_path); + } - // Create our gzip file - create_tar(source_path, &appimage_archived_path) - .with_context(|| "Failed to tar.gz update directory")?; + // Handle Deb package updates + if let Some(source_path) = bundles + .iter() + .filter(|bundle| bundle.package_type == crate::PackageType::Deb) + .find_map(|bundle| { + bundle + .bundle_paths + .iter() + .find(|path| path.extension() == Some(OsStr::new("deb"))) + }) + { + // For .deb packages, we don't need to archive them as they're already packaged + // We just need to sign them for the updater + + // Generate signature for the .deb package + let signature_path = sign_debian_package(source_path, settings) + .with_context(|| "Failed to sign Debian package")?; + + log::info!(action = "Signing"; "{} ({})", source_path.display(), display_path(&signature_path)); + + update_artifacts.push(source_path.to_path_buf()); + update_artifacts.push(signature_path); + } - log::info!(action = "Bundling"; "{} ({})", appimage_archived, display_path(&appimage_archived_path)); + if update_artifacts.is_empty() { + Err(crate::Error::UnableToFindProject) + } else { + Ok(update_artifacts) + } +} - Ok(vec![appimage_archived_path]) - } else { - Err(crate::Error::UnableToFindProject) - } +#[cfg(target_os = "linux")] +fn sign_debian_package(package_path: &Path, settings: &Settings) -> crate::Result { + use base64::{engine::general_purpose::STANDARD, Engine}; + use std::io::Read; + + // Read the package file + let mut package_contents = Vec::new(); + File::open(package_path)?.read_to_end(&mut package_contents)?; + + // Get the private key from settings + let private_key = settings + .private_key() + .ok_or_else(|| anyhow::anyhow!("Private key not found in settings"))?; + + // Create signature using minisign + let secret_key = minisign::SecretKey::from_base64(private_key) + .map_err(|e| anyhow::anyhow!("Invalid private key: {}", e))?; + + let signature = minisign::sign( + &secret_key, + &package_contents, + None, + None, + false, + ).map_err(|e| anyhow::anyhow!("Failed to create signature: {}", e))?; + + // Create signature file + let signature_path = package_path.with_extension("sig"); + let mut signature_file = File::create(&signature_path)?; + signature_file.write_all(STANDARD.encode(signature.to_string()).as_bytes())?; + + Ok(signature_path) } // Create simple update-win_.zip From 0aee430c4a42e4ab05b72b295864b511e973842f Mon Sep 17 00:00:00 2001 From: jLynx Date: Fri, 1 Nov 2024 11:20:58 +1300 Subject: [PATCH 02/51] Builds a deb updater too --- .../src/bundle/updater_bundle.rs | 73 +++++-------------- crates/tauri-cli/config.schema.json | 4 +- .../schemas/capability.schema.json | 4 +- .../schemas/config.schema.json | 4 +- 4 files changed, 25 insertions(+), 60 deletions(-) diff --git a/crates/tauri-bundler/src/bundle/updater_bundle.rs b/crates/tauri-bundler/src/bundle/updater_bundle.rs index d08ccdb7876f..96ae0809ea2e 100644 --- a/crates/tauri-bundler/src/bundle/updater_bundle.rs +++ b/crates/tauri-bundler/src/bundle/updater_bundle.rs @@ -25,7 +25,6 @@ use std::{ use anyhow::Context; use zip::write::SimpleFileOptions; -use std::process::Command; // Build update pub fn bundle_project(settings: &Settings, bundles: &[Bundle]) -> crate::Result> { @@ -43,7 +42,7 @@ pub fn bundle_project(settings: &Settings, bundles: &[Bundle]) -> crate::Result< #[cfg(target_os = "macos")] return bundle_update_macos(bundles); #[cfg(target_os = "linux")] - return bundle_update_linux(settings, bundles); + return bundle_update_linux(bundles); #[cfg(not(any(target_os = "macos", target_os = "linux")))] { @@ -91,12 +90,12 @@ fn bundle_update_macos(bundles: &[Bundle]) -> crate::Result> { // Right now in linux we hot replace the bin and request a restart // No assets are replaced #[cfg(target_os = "linux")] -fn bundle_update_linux(settings: &Settings, bundles: &[Bundle]) -> crate::Result> { +fn bundle_update_linux(bundles: &[Bundle]) -> crate::Result> { use std::ffi::OsStr; - let mut update_artifacts = Vec::new(); + let mut archived_paths = Vec::new(); - // Handle AppImage updates + // Handle AppImage bundles if let Some(source_path) = bundles .iter() .filter(|bundle| bundle.package_type == crate::PackageType::AppImage) @@ -111,16 +110,16 @@ fn bundle_update_linux(settings: &Settings, bundles: &[Bundle]) -> crate::Result let appimage_archived = format!("{}.tar.gz", source_path.display()); let appimage_archived_path = PathBuf::from(&appimage_archived); - // Create our gzip file + // Create our gzip file for AppImage create_tar(source_path, &appimage_archived_path) - .with_context(|| "Failed to tar.gz update directory")?; + .with_context(|| "Failed to tar.gz AppImage update directory")?; log::info!(action = "Bundling"; "{} ({})", appimage_archived, display_path(&appimage_archived_path)); - update_artifacts.push(appimage_archived_path); + archived_paths.push(appimage_archived_path); } - // Handle Deb package updates + // Handle Debian packages if let Some(source_path) = bundles .iter() .filter(|bundle| bundle.package_type == crate::PackageType::Deb) @@ -131,60 +130,26 @@ fn bundle_update_linux(settings: &Settings, bundles: &[Bundle]) -> crate::Result .find(|path| path.extension() == Some(OsStr::new("deb"))) }) { - // For .deb packages, we don't need to archive them as they're already packaged - // We just need to sign them for the updater - - // Generate signature for the .deb package - let signature_path = sign_debian_package(source_path, settings) - .with_context(|| "Failed to sign Debian package")?; + // add .tar.gz to our path + let deb_archived = format!("{}.tar.gz", source_path.display()); + let deb_archived_path = PathBuf::from(&deb_archived); + + // Create our gzip file for Deb + create_tar(source_path, &deb_archived_path) + .with_context(|| "Failed to tar.gz Debian package update directory")?; - log::info!(action = "Signing"; "{} ({})", source_path.display(), display_path(&signature_path)); + log::info!(action = "Bundling"; "{} ({})", deb_archived, display_path(&deb_archived_path)); - update_artifacts.push(source_path.to_path_buf()); - update_artifacts.push(signature_path); + archived_paths.push(deb_archived_path); } - if update_artifacts.is_empty() { + if archived_paths.is_empty() { Err(crate::Error::UnableToFindProject) } else { - Ok(update_artifacts) + Ok(archived_paths) } } -#[cfg(target_os = "linux")] -fn sign_debian_package(package_path: &Path, settings: &Settings) -> crate::Result { - use base64::{engine::general_purpose::STANDARD, Engine}; - use std::io::Read; - - // Read the package file - let mut package_contents = Vec::new(); - File::open(package_path)?.read_to_end(&mut package_contents)?; - - // Get the private key from settings - let private_key = settings - .private_key() - .ok_or_else(|| anyhow::anyhow!("Private key not found in settings"))?; - - // Create signature using minisign - let secret_key = minisign::SecretKey::from_base64(private_key) - .map_err(|e| anyhow::anyhow!("Invalid private key: {}", e))?; - - let signature = minisign::sign( - &secret_key, - &package_contents, - None, - None, - false, - ).map_err(|e| anyhow::anyhow!("Failed to create signature: {}", e))?; - - // Create signature file - let signature_path = package_path.with_extension("sig"); - let mut signature_file = File::create(&signature_path)?; - signature_file.write_all(STANDARD.encode(signature.to_string()).as_bytes())?; - - Ok(signature_path) -} - // Create simple update-win_.zip // Including the binary as root // Right now in windows we hot replace the bin and request a restart diff --git a/crates/tauri-cli/config.schema.json b/crates/tauri-cli/config.schema.json index a05ba79935ed..047c4a7393e0 100644 --- a/crates/tauri-cli/config.schema.json +++ b/crates/tauri-cli/config.schema.json @@ -1104,7 +1104,7 @@ ] }, "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```", "type": "object", "required": [ "identifier", @@ -1151,7 +1151,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ```", + "description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ]\n ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" diff --git a/crates/tauri-schema-generator/schemas/capability.schema.json b/crates/tauri-schema-generator/schemas/capability.schema.json index 80df9a6893f8..0c9462c500aa 100644 --- a/crates/tauri-schema-generator/schemas/capability.schema.json +++ b/crates/tauri-schema-generator/schemas/capability.schema.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Capability", - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```", "type": "object", "required": [ "identifier", @@ -48,7 +48,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ```", + "description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ]\n ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json index a05ba79935ed..047c4a7393e0 100644 --- a/crates/tauri-schema-generator/schemas/config.schema.json +++ b/crates/tauri-schema-generator/schemas/config.schema.json @@ -1104,7 +1104,7 @@ ] }, "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```", "type": "object", "required": [ "identifier", @@ -1151,7 +1151,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ```", + "description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ]\n ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" From 8bb40047a1a4df05522f4a15c8d1122e411a27d5 Mon Sep 17 00:00:00 2001 From: jLynx Date: Fri, 1 Nov 2024 12:23:28 +1300 Subject: [PATCH 03/51] generates deb as update --- crates/tauri-bundler/src/bundle.rs | 3 ++- crates/tauri-cli/src/bundle.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/tauri-bundler/src/bundle.rs b/crates/tauri-bundler/src/bundle.rs index 17100cb9cdfd..2f470c0c38d9 100644 --- a/crates/tauri-bundler/src/bundle.rs +++ b/crates/tauri-bundler/src/bundle.rs @@ -151,6 +151,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { | PackageType::MacOsBundle | PackageType::Nsis | PackageType::WindowsMsi + | PackageType::Deb ) } else { matches!(package_type, PackageType::MacOsBundle) @@ -166,7 +167,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { // Self contained updater, no need to zip matches!( package_type, - PackageType::AppImage | PackageType::Nsis | PackageType::WindowsMsi + PackageType::AppImage | PackageType::Nsis | PackageType::WindowsMsi | PackageType::Deb ) }) { diff --git a/crates/tauri-cli/src/bundle.rs b/crates/tauri-cli/src/bundle.rs index eded4aa2b477..476be86a988b 100644 --- a/crates/tauri-cli/src/bundle.rs +++ b/crates/tauri-cli/src/bundle.rs @@ -226,7 +226,7 @@ fn sign_updaters( .filter(|bundle| { matches!( bundle.package_type, - PackageType::Updater | PackageType::Nsis | PackageType::WindowsMsi | PackageType::AppImage + PackageType::Updater | PackageType::Nsis | PackageType::WindowsMsi | PackageType::AppImage | PackageType::Deb ) }) .collect(); From acd16d228940aaa0cf7331af36099199dcdba4b8 Mon Sep 17 00:00:00 2001 From: jLynx Date: Fri, 1 Nov 2024 15:58:02 +1300 Subject: [PATCH 04/51] Fixed linting --- .../src/bundle/updater_bundle.rs | 102 +++++++++--------- crates/tauri-cli/src/bundle.rs | 6 +- 2 files changed, 56 insertions(+), 52 deletions(-) diff --git a/crates/tauri-bundler/src/bundle/updater_bundle.rs b/crates/tauri-bundler/src/bundle/updater_bundle.rs index 96ae0809ea2e..fdab4e15523d 100644 --- a/crates/tauri-bundler/src/bundle/updater_bundle.rs +++ b/crates/tauri-bundler/src/bundle/updater_bundle.rs @@ -91,63 +91,63 @@ fn bundle_update_macos(bundles: &[Bundle]) -> crate::Result> { // No assets are replaced #[cfg(target_os = "linux")] fn bundle_update_linux(bundles: &[Bundle]) -> crate::Result> { - use std::ffi::OsStr; + use std::ffi::OsStr; - let mut archived_paths = Vec::new(); + let mut archived_paths = Vec::new(); - // Handle AppImage bundles - if let Some(source_path) = bundles + // Handle AppImage bundles + if let Some(source_path) = bundles + .iter() + .filter(|bundle| bundle.package_type == crate::PackageType::AppImage) + .find_map(|bundle| { + bundle + .bundle_paths .iter() - .filter(|bundle| bundle.package_type == crate::PackageType::AppImage) - .find_map(|bundle| { - bundle - .bundle_paths - .iter() - .find(|path| path.extension() == Some(OsStr::new("AppImage"))) - }) - { - // add .tar.gz to our path - let appimage_archived = format!("{}.tar.gz", source_path.display()); - let appimage_archived_path = PathBuf::from(&appimage_archived); - - // Create our gzip file for AppImage - create_tar(source_path, &appimage_archived_path) - .with_context(|| "Failed to tar.gz AppImage update directory")?; - - log::info!(action = "Bundling"; "{} ({})", appimage_archived, display_path(&appimage_archived_path)); - - archived_paths.push(appimage_archived_path); - } + .find(|path| path.extension() == Some(OsStr::new("AppImage"))) + }) + { + // add .tar.gz to our path + let appimage_archived = format!("{}.tar.gz", source_path.display()); + let appimage_archived_path = PathBuf::from(&appimage_archived); + + // Create our gzip file for AppImage + create_tar(source_path, &appimage_archived_path) + .with_context(|| "Failed to tar.gz AppImage update directory")?; + + log::info!(action = "Bundling"; "{} ({})", appimage_archived, display_path(&appimage_archived_path)); - // Handle Debian packages - if let Some(source_path) = bundles + archived_paths.push(appimage_archived_path); + } + + // Handle Debian packages + if let Some(source_path) = bundles + .iter() + .filter(|bundle| bundle.package_type == crate::PackageType::Deb) + .find_map(|bundle| { + bundle + .bundle_paths .iter() - .filter(|bundle| bundle.package_type == crate::PackageType::Deb) - .find_map(|bundle| { - bundle - .bundle_paths - .iter() - .find(|path| path.extension() == Some(OsStr::new("deb"))) - }) - { - // add .tar.gz to our path - let deb_archived = format!("{}.tar.gz", source_path.display()); - let deb_archived_path = PathBuf::from(&deb_archived); - - // Create our gzip file for Deb - create_tar(source_path, &deb_archived_path) - .with_context(|| "Failed to tar.gz Debian package update directory")?; - - log::info!(action = "Bundling"; "{} ({})", deb_archived, display_path(&deb_archived_path)); - - archived_paths.push(deb_archived_path); - } + .find(|path| path.extension() == Some(OsStr::new("deb"))) + }) + { + // add .tar.gz to our path + let deb_archived = format!("{}.tar.gz", source_path.display()); + let deb_archived_path = PathBuf::from(&deb_archived); - if archived_paths.is_empty() { - Err(crate::Error::UnableToFindProject) - } else { - Ok(archived_paths) - } + // Create our gzip file for Deb + create_tar(source_path, &deb_archived_path) + .with_context(|| "Failed to tar.gz Debian package update directory")?; + + log::info!(action = "Bundling"; "{} ({})", deb_archived, display_path(&deb_archived_path)); + + archived_paths.push(deb_archived_path); + } + + if archived_paths.is_empty() { + Err(crate::Error::UnableToFindProject) + } else { + Ok(archived_paths) + } } // Create simple update-win_.zip diff --git a/crates/tauri-cli/src/bundle.rs b/crates/tauri-cli/src/bundle.rs index 476be86a988b..5473c4b4690c 100644 --- a/crates/tauri-cli/src/bundle.rs +++ b/crates/tauri-cli/src/bundle.rs @@ -226,7 +226,11 @@ fn sign_updaters( .filter(|bundle| { matches!( bundle.package_type, - PackageType::Updater | PackageType::Nsis | PackageType::WindowsMsi | PackageType::AppImage | PackageType::Deb + PackageType::Updater + | PackageType::Nsis + | PackageType::WindowsMsi + | PackageType::AppImage + | PackageType::Deb ) }) .collect(); From 619ae702463efcf67f10696ddb129cdf70acbd00 Mon Sep 17 00:00:00 2001 From: jLynx Date: Mon, 4 Nov 2024 10:14:03 +1300 Subject: [PATCH 05/51] Revert deb gz --- .../src/bundle/updater_bundle.rs | 40 +++---------------- 1 file changed, 5 insertions(+), 35 deletions(-) diff --git a/crates/tauri-bundler/src/bundle/updater_bundle.rs b/crates/tauri-bundler/src/bundle/updater_bundle.rs index fdab4e15523d..77749afca21e 100644 --- a/crates/tauri-bundler/src/bundle/updater_bundle.rs +++ b/crates/tauri-bundler/src/bundle/updater_bundle.rs @@ -93,9 +93,7 @@ fn bundle_update_macos(bundles: &[Bundle]) -> crate::Result> { fn bundle_update_linux(bundles: &[Bundle]) -> crate::Result> { use std::ffi::OsStr; - let mut archived_paths = Vec::new(); - - // Handle AppImage bundles + // build our app actually we support only appimage on linux if let Some(source_path) = bundles .iter() .filter(|bundle| bundle.package_type == crate::PackageType::AppImage) @@ -110,43 +108,15 @@ fn bundle_update_linux(bundles: &[Bundle]) -> crate::Result> { let appimage_archived = format!("{}.tar.gz", source_path.display()); let appimage_archived_path = PathBuf::from(&appimage_archived); - // Create our gzip file for AppImage + // Create our gzip file create_tar(source_path, &appimage_archived_path) - .with_context(|| "Failed to tar.gz AppImage update directory")?; + .with_context(|| "Failed to tar.gz update directory")?; log::info!(action = "Bundling"; "{} ({})", appimage_archived, display_path(&appimage_archived_path)); - archived_paths.push(appimage_archived_path); - } - - // Handle Debian packages - if let Some(source_path) = bundles - .iter() - .filter(|bundle| bundle.package_type == crate::PackageType::Deb) - .find_map(|bundle| { - bundle - .bundle_paths - .iter() - .find(|path| path.extension() == Some(OsStr::new("deb"))) - }) - { - // add .tar.gz to our path - let deb_archived = format!("{}.tar.gz", source_path.display()); - let deb_archived_path = PathBuf::from(&deb_archived); - - // Create our gzip file for Deb - create_tar(source_path, &deb_archived_path) - .with_context(|| "Failed to tar.gz Debian package update directory")?; - - log::info!(action = "Bundling"; "{} ({})", deb_archived, display_path(&deb_archived_path)); - - archived_paths.push(deb_archived_path); - } - - if archived_paths.is_empty() { - Err(crate::Error::UnableToFindProject) + Ok(vec![appimage_archived_path]) } else { - Ok(archived_paths) + Err(crate::Error::UnableToFindProject) } } From 129414faa4e027c9035d56614682cacc0335a6a0 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Mon, 4 Nov 2024 13:58:47 +0200 Subject: [PATCH 06/51] fix: fix webview not focused by default (#11569) * fix: fix webview not focused by default closes #10746 * fix compile * typo * fix compile again * clippy --- .changes/webview-focus-apis.md | 5 +++ .changes/webview-window-focused.md | 7 ++++ crates/tauri-cli/config.schema.json | 4 +- crates/tauri-runtime-wry/src/lib.rs | 3 +- crates/tauri-runtime/src/webview.rs | 18 ++++++-- .../schemas/capability.schema.json | 4 +- .../schemas/config.schema.json | 4 +- crates/tauri/src/webview/mod.rs | 7 ++++ crates/tauri/src/webview/plugin.rs | 42 ++++++++++++++----- crates/tauri/src/webview/webview_window.rs | 4 +- crates/tauri/src/window/mod.rs | 2 +- packages/api/src/webview.ts | 6 +++ 12 files changed, 82 insertions(+), 24 deletions(-) create mode 100644 .changes/webview-focus-apis.md create mode 100644 .changes/webview-window-focused.md diff --git a/.changes/webview-focus-apis.md b/.changes/webview-focus-apis.md new file mode 100644 index 000000000000..2d478fede8cd --- /dev/null +++ b/.changes/webview-focus-apis.md @@ -0,0 +1,5 @@ +--- +"tauri": "patch:feat" +--- + +Add `WebviewBuilder::focused` method to choose whether to focus webview or not on creation. diff --git a/.changes/webview-window-focused.md b/.changes/webview-window-focused.md new file mode 100644 index 000000000000..b95b4cf42a74 --- /dev/null +++ b/.changes/webview-window-focused.md @@ -0,0 +1,7 @@ +--- +"tauri": "patch:bug" +"tauri-runtime": "patch:bug" +"tauri-runtime-wry": "patch:bug" +--- + +Fix webview not focused by default. diff --git a/crates/tauri-cli/config.schema.json b/crates/tauri-cli/config.schema.json index a05ba79935ed..047c4a7393e0 100644 --- a/crates/tauri-cli/config.schema.json +++ b/crates/tauri-cli/config.schema.json @@ -1104,7 +1104,7 @@ ] }, "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```", "type": "object", "required": [ "identifier", @@ -1151,7 +1151,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ```", + "description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ]\n ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index 4dd17d494910..0e2f23386f46 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -789,6 +789,7 @@ impl WindowBuilder for WindowBuilderWrapper { window = window .title(config.title.to_string()) .inner_size(config.width, config.height) + .focused(config.focus) .visible(config.visible) .resizable(config.resizable) .fullscreen(config.fullscreen) @@ -4017,7 +4018,7 @@ fn create_webview( let mut webview_builder = WebViewBuilder::with_web_context(&mut web_context.inner) .with_id(&label) - .with_focused(window.is_focused()) + .with_focused(webview_attributes.focus) .with_url(&url) .with_transparent(webview_attributes.transparent) .with_accept_first_mouse(webview_attributes.accept_first_mouse) diff --git a/crates/tauri-runtime/src/webview.rs b/crates/tauri-runtime/src/webview.rs index 4c4c83e3ea8a..651aaec5eac3 100644 --- a/crates/tauri-runtime/src/webview.rs +++ b/crates/tauri-runtime/src/webview.rs @@ -204,6 +204,7 @@ pub struct WebviewAttributes { pub window_effects: Option, pub incognito: bool, pub transparent: bool, + pub focus: bool, pub bounds: Option, pub auto_resize: bool, pub proxy_url: Option, @@ -213,8 +214,11 @@ pub struct WebviewAttributes { impl From<&WindowConfig> for WebviewAttributes { fn from(config: &WindowConfig) -> Self { - let mut builder = Self::new(config.url.clone()); - builder = builder.incognito(config.incognito); + let mut builder = Self::new(config.url.clone()) + .incognito(config.incognito) + .focused(config.focus) + .zoom_hotkeys_enabled(config.zoom_hotkeys_enabled) + .browser_extensions_enabled(config.browser_extensions_enabled); #[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))] { builder = builder.transparent(config.transparent); @@ -235,8 +239,6 @@ impl From<&WindowConfig> for WebviewAttributes { if let Some(url) = &config.proxy_url { builder = builder.proxy_url(url.to_owned()); } - builder = builder.zoom_hotkeys_enabled(config.zoom_hotkeys_enabled); - builder = builder.browser_extensions_enabled(config.browser_extensions_enabled); builder } } @@ -256,6 +258,7 @@ impl WebviewAttributes { window_effects: None, incognito: false, transparent: false, + focus: true, bounds: None, auto_resize: false, proxy_url: None, @@ -338,6 +341,13 @@ impl WebviewAttributes { self } + /// Whether the webview should be focused or not. + #[must_use] + pub fn focused(mut self, focus: bool) -> Self { + self.focus = focus; + self + } + /// Sets the webview to automatically grow and shrink its size and position when the parent window resizes. #[must_use] pub fn auto_resize(mut self) -> Self { diff --git a/crates/tauri-schema-generator/schemas/capability.schema.json b/crates/tauri-schema-generator/schemas/capability.schema.json index 80df9a6893f8..0c9462c500aa 100644 --- a/crates/tauri-schema-generator/schemas/capability.schema.json +++ b/crates/tauri-schema-generator/schemas/capability.schema.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Capability", - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```", "type": "object", "required": [ "identifier", @@ -48,7 +48,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ```", + "description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ]\n ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json index a05ba79935ed..047c4a7393e0 100644 --- a/crates/tauri-schema-generator/schemas/config.schema.json +++ b/crates/tauri-schema-generator/schemas/config.schema.json @@ -1104,7 +1104,7 @@ ] }, "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```", "type": "object", "required": [ "identifier", @@ -1151,7 +1151,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ```", + "description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ]\n ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" diff --git a/crates/tauri/src/webview/mod.rs b/crates/tauri/src/webview/mod.rs index e0df92ecea08..06fa0eda0909 100644 --- a/crates/tauri/src/webview/mod.rs +++ b/crates/tauri/src/webview/mod.rs @@ -754,6 +754,13 @@ fn main() { self } + /// Whether the webview should be focused or not. + #[must_use] + pub fn focused(mut self, focus: bool) -> Self { + self.webview_attributes.focus = focus; + self + } + /// Sets the webview to automatically grow and shrink its size and position when the parent window resizes. #[must_use] pub fn auto_resize(mut self) -> Self { diff --git a/crates/tauri/src/webview/plugin.rs b/crates/tauri/src/webview/plugin.rs index ca8fd24eea6d..0856e254e65f 100644 --- a/crates/tauri/src/webview/plugin.rs +++ b/crates/tauri/src/webview/plugin.rs @@ -22,6 +22,10 @@ mod desktop_commands { WebviewWindowBuilder, }; + fn default_true() -> bool { + true + } + #[derive(Debug, PartialEq, Clone, Deserialize)] #[serde(rename_all = "camelCase")] pub struct WebviewConfig { @@ -35,6 +39,8 @@ mod desktop_commands { height: f64, #[serde(default)] transparent: bool, + #[serde(default = "default_true")] + focus: bool, #[serde(default)] accept_first_mouse: bool, window_effects: Option, @@ -44,6 +50,23 @@ mod desktop_commands { zoom_hotkeys_enabled: bool, } + #[cfg(feature = "unstable")] + impl crate::webview::WebviewBuilder { + fn from_webview_config(label: String, config: WebviewConfig) -> Self { + let mut builder = Self::new(label, config.url); + builder.webview_attributes.user_agent = config.user_agent; + builder.webview_attributes.drag_drop_handler_enabled = + config.drag_drop_enabled.unwrap_or(true); + builder.webview_attributes.transparent = config.transparent; + builder.webview_attributes.focus = config.focus; + builder.webview_attributes.accept_first_mouse = config.accept_first_mouse; + builder.webview_attributes.window_effects = config.window_effects; + builder.webview_attributes.incognito = config.incognito; + builder.webview_attributes.zoom_hotkeys_enabled = config.zoom_hotkeys_enabled; + builder + } + } + #[derive(Serialize)] pub struct WebviewRef { window_label: String, @@ -89,21 +112,18 @@ mod desktop_commands { .manager() .get_window(&window_label) .ok_or(crate::Error::WindowNotFound)?; - let mut builder = crate::webview::WebviewBuilder::new(label, options.url); - builder.webview_attributes.user_agent = options.user_agent; - builder.webview_attributes.drag_drop_handler_enabled = - options.drag_drop_enabled.unwrap_or(true); - builder.webview_attributes.transparent = options.transparent; - builder.webview_attributes.accept_first_mouse = options.accept_first_mouse; - builder.webview_attributes.window_effects = options.window_effects; - builder.webview_attributes.incognito = options.incognito; - builder.webview_attributes.zoom_hotkeys_enabled = options.zoom_hotkeys_enabled; + let x = options.x; + let y = options.y; + let width = options.width; + let height = options.height; + + let builder = crate::webview::WebviewBuilder::from_webview_config(label, options); window.add_child( builder, - tauri_runtime::dpi::LogicalPosition::new(options.x, options.y), - tauri_runtime::dpi::LogicalSize::new(options.width, options.height), + tauri_runtime::dpi::LogicalPosition::new(x, y), + tauri_runtime::dpi::LogicalSize::new(width, height), )?; Ok(()) diff --git a/crates/tauri/src/webview/webview_window.rs b/crates/tauri/src/webview/webview_window.rs index ee1878e72252..853d5406452d 100644 --- a/crates/tauri/src/webview/webview_window.rs +++ b/crates/tauri/src/webview/webview_window.rs @@ -476,10 +476,11 @@ impl<'a, R: Runtime, M: Manager> WebviewWindowBuilder<'a, R, M> { #[must_use] #[deprecated( since = "1.2.0", - note = "The window is automatically focused by default. This function Will be removed in 2.0.0. Use `focused` instead." + note = "The window is automatically focused by default. This function Will be removed in 3.0.0. Use `focused` instead." )] pub fn focus(mut self) -> Self { self.window_builder = self.window_builder.focused(true); + self.webview_builder = self.webview_builder.focused(true); self } @@ -487,6 +488,7 @@ impl<'a, R: Runtime, M: Manager> WebviewWindowBuilder<'a, R, M> { #[must_use] pub fn focused(mut self, focused: bool) -> Self { self.window_builder = self.window_builder.focused(focused); + self.webview_builder = self.webview_builder.focused(focused); self } diff --git a/crates/tauri/src/window/mod.rs b/crates/tauri/src/window/mod.rs index ab0e8cc7fe10..9b8e02b8ef7a 100644 --- a/crates/tauri/src/window/mod.rs +++ b/crates/tauri/src/window/mod.rs @@ -531,7 +531,7 @@ impl<'a, R: Runtime, M: Manager> WindowBuilder<'a, R, M> { #[must_use] #[deprecated( since = "1.2.0", - note = "The window is automatically focused by default. This function Will be removed in 2.0.0. Use `focused` instead." + note = "The window is automatically focused by default. This function Will be removed in 3.0.0. Use `focused` instead." )] pub fn focus(mut self) -> Self { self.window_builder = self.window_builder.focused(true); diff --git a/packages/api/src/webview.ts b/packages/api/src/webview.ts index 5b16f058b48e..e04252a95018 100644 --- a/packages/api/src/webview.ts +++ b/packages/api/src/webview.ts @@ -684,6 +684,12 @@ interface WebviewOptions { * WARNING: Using private APIs on `macOS` prevents your application from being accepted to the `App Store`. */ transparent?: boolean + /** + * Whether the webview should have focus or not + * + * @since 2.1.0 + */ + focus?: boolean /** * Whether the drag and drop is enabled or not on the webview. By default it is enabled. * From c33bbf45740274b6918ea6c647f366fb6008e459 Mon Sep 17 00:00:00 2001 From: Kornel Date: Mon, 4 Nov 2024 12:30:43 +0000 Subject: [PATCH 07/51] enhance: include the path in ACL I/O errors (#11575) --- .changes/utils-acl-path-errors.md | 6 ++++++ crates/tauri-utils/src/acl/build.rs | 14 ++++++++------ crates/tauri-utils/src/acl/capability.rs | 3 ++- crates/tauri-utils/src/acl/mod.rs | 18 +++++++++--------- crates/tauri-utils/src/acl/schema.rs | 4 ++-- 5 files changed, 27 insertions(+), 18 deletions(-) create mode 100644 .changes/utils-acl-path-errors.md diff --git a/.changes/utils-acl-path-errors.md b/.changes/utils-acl-path-errors.md new file mode 100644 index 000000000000..95fcf0fe3be1 --- /dev/null +++ b/.changes/utils-acl-path-errors.md @@ -0,0 +1,6 @@ +--- +"tauri": minor:enhance +"tauri-utils": minor:enhance +--- + +Include the path in ACL I/O errors. \ No newline at end of file diff --git a/crates/tauri-utils/src/acl/build.rs b/crates/tauri-utils/src/acl/build.rs index d2425b50ad46..d32eb0232846 100644 --- a/crates/tauri-utils/src/acl/build.rs +++ b/crates/tauri-utils/src/acl/build.rs @@ -44,8 +44,8 @@ const CORE_PLUGIN_PERMISSIONS_TOKEN: &str = "__CORE_PLUGIN__"; fn parse_permissions(paths: Vec) -> Result, Error> { let mut permissions = Vec::new(); for path in paths { - let permission_file = fs::read_to_string(&path).map_err(Error::ReadFile)?; let ext = path.extension().unwrap().to_string_lossy().to_string(); + let permission_file = fs::read_to_string(&path).map_err(|e| Error::ReadFile(e, path))?; let permission: PermissionFile = match ext.as_str() { "toml" => toml::from_str(&permission_file)?, "json" => serde_json::from_str(&permission_file)?, @@ -81,7 +81,8 @@ pub fn define_permissions bool>( let pkg_name_valid_path = pkg_name.replace(':', "-"); let permission_files_path = out_dir.join(format!("{}-permission-files", pkg_name_valid_path)); let permission_files_json = serde_json::to_string(&permission_files)?; - fs::write(&permission_files_path, permission_files_json).map_err(Error::WriteFile)?; + fs::write(&permission_files_path, permission_files_json) + .map_err(|e| Error::WriteFile(e, permission_files_path.clone()))?; if let Some(plugin_name) = pkg_name.strip_prefix("tauri:") { println!( @@ -115,7 +116,8 @@ pub fn read_permissions() -> Result>, Error> }) { let permissions_path = PathBuf::from(value); - let permissions_str = fs::read_to_string(&permissions_path).map_err(Error::ReadFile)?; + let permissions_str = + fs::read_to_string(&permissions_path).map_err(|e| Error::ReadFile(e, permissions_path))?; let permissions: Vec = serde_json::from_str(&permissions_str)?; let permissions = parse_permissions(permissions)?; @@ -139,7 +141,7 @@ pub fn define_global_scope_schema( out_dir: &Path, ) -> Result<(), Error> { let path = out_dir.join("global-scope.json"); - fs::write(&path, serde_json::to_vec(&schema)?).map_err(Error::WriteFile)?; + fs::write(&path, serde_json::to_vec(&schema)?).map_err(|e| Error::WriteFile(e, path.clone()))?; if let Some(plugin_name) = pkg_name.strip_prefix("tauri:") { println!( @@ -170,7 +172,7 @@ pub fn read_global_scope_schemas() -> Result, }) { let path = PathBuf::from(value); - let json = fs::read_to_string(&path).map_err(Error::ReadFile)?; + let json = fs::read_to_string(&path).map_err(|e| Error::ReadFile(e, path))?; let schema: serde_json::Value = serde_json::from_str(&json)?; let plugin_crate_name = plugin_crate_name_var.to_lowercase().replace('_', "-"); @@ -368,7 +370,7 @@ pub fn generate_docs( format!("{default_permission}\n{PERMISSION_TABLE_HEADER}\n{permission_table}\n"); let reference_path = out_dir.join(PERMISSION_DOCS_FILE_NAME); - write_if_changed(reference_path, docs).map_err(Error::WriteFile)?; + write_if_changed(&reference_path, docs).map_err(|e| Error::WriteFile(e, reference_path))?; Ok(()) } diff --git a/crates/tauri-utils/src/acl/capability.rs b/crates/tauri-utils/src/acl/capability.rs index a158ea7d3df7..9ac56f3ed83c 100644 --- a/crates/tauri-utils/src/acl/capability.rs +++ b/crates/tauri-utils/src/acl/capability.rs @@ -261,7 +261,8 @@ impl CapabilityFile { /// Load the given capability file. pub fn load>(path: P) -> Result { let path = path.as_ref(); - let capability_file = std::fs::read_to_string(path).map_err(super::Error::ReadFile)?; + let capability_file = + std::fs::read_to_string(path).map_err(|e| super::Error::ReadFile(e, path.into()))?; let ext = path.extension().unwrap().to_string_lossy().to_string(); let file: Self = match ext.as_str() { "toml" => toml::from_str(&capability_file)?, diff --git a/crates/tauri-utils/src/acl/mod.rs b/crates/tauri-utils/src/acl/mod.rs index 3a48b377d763..40e475fde51c 100644 --- a/crates/tauri-utils/src/acl/mod.rs +++ b/crates/tauri-utils/src/acl/mod.rs @@ -22,7 +22,7 @@ //! [Struct Update Syntax]: https://doc.rust-lang.org/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax use serde::{Deserialize, Serialize}; -use std::{num::NonZeroU64, str::FromStr, sync::Arc}; +use std::{num::NonZeroU64, path::PathBuf, str::FromStr, sync::Arc}; use thiserror::Error; use url::Url; @@ -71,20 +71,20 @@ pub enum Error { LinksName, /// IO error while reading a file - #[error("failed to read file: {0}")] - ReadFile(std::io::Error), + #[error("failed to read file '{}': {}", _1.display(), _0)] + ReadFile(std::io::Error, PathBuf), /// IO error while writing a file - #[error("failed to write file: {0}")] - WriteFile(std::io::Error), + #[error("failed to write file '{}': {}", _1.display(), _0)] + WriteFile(std::io::Error, PathBuf), /// IO error while creating a file - #[error("failed to create file: {0}")] - CreateFile(std::io::Error), + #[error("failed to create file '{}': {}", _1.display(), _0)] + CreateFile(std::io::Error, PathBuf), /// IO error while creating a dir - #[error("failed to create dir: {0}")] - CreateDir(std::io::Error), + #[error("failed to create dir '{}': {}", _1.display(), _0)] + CreateDir(std::io::Error, PathBuf), /// [`cargo_metadata`] was not able to complete successfully #[cfg(feature = "build")] diff --git a/crates/tauri-utils/src/acl/schema.rs b/crates/tauri-utils/src/acl/schema.rs index bdce02ea013a..24cc07de6412 100644 --- a/crates/tauri-utils/src/acl/schema.rs +++ b/crates/tauri-utils/src/acl/schema.rs @@ -336,10 +336,10 @@ pub fn generate_permissions_schema>( let schema_str = serde_json::to_string_pretty(&schema)?; let out_dir = out_dir.as_ref().join(PERMISSION_SCHEMAS_FOLDER_NAME); - fs::create_dir_all(&out_dir).map_err(Error::CreateDir)?; + fs::create_dir_all(&out_dir).map_err(|e| Error::CreateDir(e, out_dir.clone()))?; let schema_path = out_dir.join(PERMISSION_SCHEMA_FILE_NAME); - write_if_changed(&schema_path, schema_str).map_err(Error::WriteFile)?; + write_if_changed(&schema_path, schema_str).map_err(|e| Error::WriteFile(e, schema_path))?; Ok(()) } From f8994b214e89acc99ab5ce8dcca8485f43a62dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20T=C3=B8nder?= <71938724+Mikkel-T@users.noreply.github.com> Date: Mon, 4 Nov 2024 13:31:18 +0100 Subject: [PATCH 08/51] fix(event): handle AnyLabel listeners in `emit_to` (#11581) closes #11561 --- .changes/event-anylabel-fix.md | 5 +++++ crates/tauri/src/manager/mod.rs | 26 +++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 .changes/event-anylabel-fix.md diff --git a/.changes/event-anylabel-fix.md b/.changes/event-anylabel-fix.md new file mode 100644 index 000000000000..cdf47c67c7c4 --- /dev/null +++ b/.changes/event-anylabel-fix.md @@ -0,0 +1,5 @@ +--- +"tauri": "patch:bug" +--- + +Fix listeners created with `EventTarget::AnyLabel` never receiving events. diff --git a/crates/tauri/src/manager/mod.rs b/crates/tauri/src/manager/mod.rs index 7353c3ae36f4..d272b241bfb9 100644 --- a/crates/tauri/src/manager/mod.rs +++ b/crates/tauri/src/manager/mod.rs @@ -597,7 +597,31 @@ impl AppManager { } => self.emit_filter(event, payload, |t| match t { EventTarget::Window { label } | EventTarget::Webview { label } - | EventTarget::WebviewWindow { label } => label == &target_label, + | EventTarget::WebviewWindow { label } + | EventTarget::AnyLabel { label } => label == &target_label, + _ => false, + }), + + EventTarget::Window { + label: target_label, + } => self.emit_filter(event, payload, |t| match t { + EventTarget::AnyLabel { label } | EventTarget::Window { label } => label == &target_label, + _ => false, + }), + + EventTarget::Webview { + label: target_label, + } => self.emit_filter(event, payload, |t| match t { + EventTarget::AnyLabel { label } | EventTarget::Webview { label } => label == &target_label, + _ => false, + }), + + EventTarget::WebviewWindow { + label: target_label, + } => self.emit_filter(event, payload, |t| match t { + EventTarget::AnyLabel { label } | EventTarget::WebviewWindow { label } => { + label == &target_label + } _ => false, }), From 058c0db72f43fbe1574d0db654560e693755cd7e Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 5 Nov 2024 14:08:08 +0200 Subject: [PATCH 09/51] feat(bundler): add option to configure RPM compression (#11584) --- .changes/rpm-compression-level.md | 10 ++ crates/tauri-bundler/src/bundle/linux/rpm.rs | 18 ++- crates/tauri-bundler/src/bundle/settings.rs | 7 +- .../src/bundle/windows/nsis/mod.rs | 4 +- crates/tauri-cli/config.schema.json | 123 ++++++++++++++++++ crates/tauri-cli/src/interface/rust.rs | 1 + .../schemas/config.schema.json | 123 ++++++++++++++++++ crates/tauri-utils/src/config.rs | 33 +++++ 8 files changed, 314 insertions(+), 5 deletions(-) create mode 100644 .changes/rpm-compression-level.md diff --git a/.changes/rpm-compression-level.md b/.changes/rpm-compression-level.md new file mode 100644 index 000000000000..5a2017fea94d --- /dev/null +++ b/.changes/rpm-compression-level.md @@ -0,0 +1,10 @@ +--- +"tauri-bundler": "minor:feat" +"tauri-cli": "minor:feat" +"@tauri-apps/cli": "minor:feat" +"tauri-utils": "minor:feat" +--- + +Add `bundle > linux > rpm > compression` config option to control RPM bundle compression type and level. + + diff --git a/crates/tauri-bundler/src/bundle/linux/rpm.rs b/crates/tauri-bundler/src/bundle/linux/rpm.rs index 06cbc953dfa1..f01f6a8718a4 100644 --- a/crates/tauri-bundler/src/bundle/linux/rpm.rs +++ b/crates/tauri-bundler/src/bundle/linux/rpm.rs @@ -12,6 +12,7 @@ use std::{ fs::{self, File}, path::{Path, PathBuf}, }; +use tauri_utils::config::RpmCompression; use super::freedesktop; @@ -54,11 +55,24 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { let license = settings.license().unwrap_or_default(); let name = heck::AsKebabCase(settings.product_name()).to_string(); + + let compression = settings + .rpm() + .compression + .map(|c| match c { + RpmCompression::Gzip { level } => rpm::CompressionWithLevel::Gzip(level), + RpmCompression::Zstd { level } => rpm::CompressionWithLevel::Zstd(level), + RpmCompression::Xz { level } => rpm::CompressionWithLevel::Xz(level), + RpmCompression::Bzip2 { level } => rpm::CompressionWithLevel::Bzip2(level), + _ => rpm::CompressionWithLevel::None, + }) + // This matches .deb compression. On a 240MB source binary the bundle will be 100KB larger than rpm's default while reducing build times by ~25%. + .unwrap_or(rpm::CompressionWithLevel::Gzip(6)); + let mut builder = rpm::PackageBuilder::new(&name, version, &license, arch, summary) .epoch(epoch) .release(release) - // This matches .deb compression. On a 240MB source binary the bundle will be 100KB larger than rpm's default while reducing build times by ~25%. - .compression(rpm::CompressionWithLevel::Gzip(6)); + .compression(compression); if let Some(description) = settings.long_description() { builder = builder.description(description); diff --git a/crates/tauri-bundler/src/bundle/settings.rs b/crates/tauri-bundler/src/bundle/settings.rs index 610c6e749f1e..a29398f76b98 100644 --- a/crates/tauri-bundler/src/bundle/settings.rs +++ b/crates/tauri-bundler/src/bundle/settings.rs @@ -8,7 +8,10 @@ use crate::bundle::{common, platform::target_triple}; use anyhow::Context; pub use tauri_utils::config::WebviewInstallMode; use tauri_utils::{ - config::{BundleType, DeepLinkProtocol, FileAssociation, NSISInstallerMode, NsisCompression}, + config::{ + BundleType, DeepLinkProtocol, FileAssociation, NSISInstallerMode, NsisCompression, + RpmCompression, + }, resources::{external_binaries, ResourcePaths}, }; @@ -262,6 +265,8 @@ pub struct RpmSettings { /// Path to script that will be executed after the package is removed. See /// pub post_remove_script: Option, + /// Compression algorithm and level. Defaults to `Gzip` with level 6. + pub compression: Option, } /// Position coordinates struct. diff --git a/crates/tauri-bundler/src/bundle/windows/nsis/mod.rs b/crates/tauri-bundler/src/bundle/windows/nsis/mod.rs index 3d281489c369..810141214c5c 100644 --- a/crates/tauri-bundler/src/bundle/windows/nsis/mod.rs +++ b/crates/tauri-bundler/src/bundle/windows/nsis/mod.rs @@ -90,8 +90,8 @@ pub fn bundle_project(settings: &Settings, updater: bool) -> crate::Result", "type": "object", diff --git a/crates/tauri-cli/src/interface/rust.rs b/crates/tauri-cli/src/interface/rust.rs index 08008171427b..8a407f8eebe7 100644 --- a/crates/tauri-cli/src/interface/rust.rs +++ b/crates/tauri-cli/src/interface/rust.rs @@ -1388,6 +1388,7 @@ fn tauri_config_to_bundle_settings( post_install_script: config.linux.rpm.post_install_script, pre_remove_script: config.linux.rpm.pre_remove_script, post_remove_script: config.linux.rpm.post_remove_script, + compression: config.linux.rpm.compression, }, dmg: DmgSettings { background: config.macos.dmg.background, diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json index 047c4a7393e0..90acf8973183 100644 --- a/crates/tauri-schema-generator/schemas/config.schema.json +++ b/crates/tauri-schema-generator/schemas/config.schema.json @@ -2789,10 +2789,133 @@ "string", "null" ] + }, + "compression": { + "description": "Compression algorithm and level. Defaults to `Gzip` with level 6.", + "anyOf": [ + { + "$ref": "#/definitions/RpmCompression" + }, + { + "type": "null" + } + ] } }, "additionalProperties": false }, + "RpmCompression": { + "description": "Compression algorithms used when bundling RPM packages.", + "oneOf": [ + { + "description": "Gzip compression", + "type": "object", + "required": [ + "level", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "gzip" + ] + }, + "level": { + "description": "Gzip compression level", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "Zstd compression", + "type": "object", + "required": [ + "level", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "zstd" + ] + }, + "level": { + "description": "Zstd compression level", + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + { + "description": "Xz compression", + "type": "object", + "required": [ + "level", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "xz" + ] + }, + "level": { + "description": "Xz compression level", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "Bzip2 compression", + "type": "object", + "required": [ + "level", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "bzip2" + ] + }, + "level": { + "description": "Bzip2 compression level", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "Disable compression", + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "none" + ] + } + }, + "additionalProperties": false + } + ] + }, "MacConfig": { "description": "Configuration for the macOS bundles.\n\n See more: ", "type": "object", diff --git a/crates/tauri-utils/src/config.rs b/crates/tauri-utils/src/config.rs index 3780079bf1e5..041deda585b1 100644 --- a/crates/tauri-utils/src/config.rs +++ b/crates/tauri-utils/src/config.rs @@ -392,6 +392,36 @@ pub struct LinuxConfig { pub rpm: RpmConfig, } +/// Compression algorithms used when bundling RPM packages. +#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields, tag = "type")] +#[non_exhaustive] +pub enum RpmCompression { + /// Gzip compression + Gzip { + /// Gzip compression level + level: u32, + }, + /// Zstd compression + Zstd { + /// Zstd compression level + level: i32, + }, + /// Xz compression + Xz { + /// Xz compression level + level: u32, + }, + /// Bzip2 compression + Bzip2 { + /// Bzip2 compression level + level: u32, + }, + /// Disable compression + None, +} + /// Configuration for RPM bundles. #[skip_serializing_none] #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)] @@ -440,6 +470,8 @@ pub struct RpmConfig { /// #[serde(alias = "post-remove-script")] pub post_remove_script: Option, + /// Compression algorithm and level. Defaults to `Gzip` with level 6. + pub compression: Option, } impl Default for RpmConfig { @@ -458,6 +490,7 @@ impl Default for RpmConfig { post_install_script: None, pre_remove_script: None, post_remove_script: None, + compression: None, } } } From f37e97d410c4a219e99f97692da05ca9d8e0ba3a Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 5 Nov 2024 14:48:59 +0200 Subject: [PATCH 10/51] feat: add `use_https_scheme` for Windows and Android (#11477) * feat: add `use_https_scheme` for Windows and Android closes #11252 * fix compilation * Apply suggestions from code review Co-authored-by: Fabian-Lars * change wording * add migrations * migrate `dangerousUseHttpScheme` * fmt * infer AssetResolver::get https scheme config * fix tests --------- Co-authored-by: Fabian-Lars Co-authored-by: Lucas Nogueira --- .../use_https_windows-and-android-config.md | 6 ++ .changes/use_https_windows-and-android.md | 7 ++ crates/tauri-cli/config.schema.json | 5 ++ .../src/migrate/migrations/v1/config.rs | 49 +++++++++++- crates/tauri-runtime-wry/src/lib.rs | 79 +++++++++++++------ crates/tauri-runtime/src/webview.rs | 18 +++++ crates/tauri-runtime/src/window.rs | 18 ++++- .../schemas/config.schema.json | 5 ++ crates/tauri-utils/src/config.rs | 17 +++- crates/tauri/scripts/core.js | 3 +- crates/tauri/src/app.rs | 19 ++++- crates/tauri/src/manager/mod.rs | 29 +++++-- crates/tauri/src/manager/webview.rs | 23 ++++-- crates/tauri/src/pattern.rs | 5 +- crates/tauri/src/protocol/isolation.rs | 4 +- crates/tauri/src/protocol/tauri.rs | 8 +- crates/tauri/src/test/mock_runtime.rs | 57 +++++++------ crates/tauri/src/webview/mod.rs | 46 +++++++++-- crates/tauri/src/webview/webview_window.rs | 15 ++++ crates/tauri/src/window/mod.rs | 6 +- examples/api/src-tauri/src/lib.rs | 3 +- packages/api/src/webview.ts | 15 ++++ 22 files changed, 358 insertions(+), 79 deletions(-) create mode 100644 .changes/use_https_windows-and-android-config.md create mode 100644 .changes/use_https_windows-and-android.md diff --git a/.changes/use_https_windows-and-android-config.md b/.changes/use_https_windows-and-android-config.md new file mode 100644 index 000000000000..3e5598a89e42 --- /dev/null +++ b/.changes/use_https_windows-and-android-config.md @@ -0,0 +1,6 @@ +--- +"tauri": "minor:feat" +"tauri-utils": "minor:feat" +--- + +Add `app > windows > useHttpsScheme` config option to choose whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android diff --git a/.changes/use_https_windows-and-android.md b/.changes/use_https_windows-and-android.md new file mode 100644 index 000000000000..0e1bbb1a6c6d --- /dev/null +++ b/.changes/use_https_windows-and-android.md @@ -0,0 +1,7 @@ +--- +"tauri": "minor:feat" +"tauri-runtime": "minor:feat" +"tauri-runtime-wry": "minor:feat" +--- + +Add `WebviewWindowBuilder/WebviewBuilder::use_https_scheme` to choose whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android diff --git a/crates/tauri-cli/config.schema.json b/crates/tauri-cli/config.schema.json index 90acf8973183..820fb35a55f0 100644 --- a/crates/tauri-cli/config.schema.json +++ b/crates/tauri-cli/config.schema.json @@ -486,6 +486,11 @@ "description": "Whether browser extensions can be installed for the webview process\n\n ## Platform-specific:\n\n - **Windows**: Enables the WebView2 environment's [`AreBrowserExtensionsEnabled`](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2environmentoptions?view=webview2-winrt-1.0.2739.15#arebrowserextensionsenabled)\n - **MacOS / Linux / iOS / Android** - Unsupported.", "default": false, "type": "boolean" + }, + "useHttpsScheme": { + "description": "Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`.\n\n ## Note\n\n Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `://localhost` protocols used on macOS and Linux.\n\n ## Warning\n\n Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.", + "default": false, + "type": "boolean" } }, "additionalProperties": false diff --git a/crates/tauri-cli/src/migrate/migrations/v1/config.rs b/crates/tauri-cli/src/migrate/migrations/v1/config.rs index ab956e76aa19..2b211470a096 100644 --- a/crates/tauri-cli/src/migrate/migrations/v1/config.rs +++ b/crates/tauri-cli/src/migrate/migrations/v1/config.rs @@ -87,6 +87,28 @@ fn migrate_config(config: &mut Value) -> Result { migrated.permissions = permissions; } + // dangerousUseHttpScheme/useHttpsScheme + let dangerouse_use_http = tauri_config + .get("security") + .and_then(|w| w.as_object()) + .and_then(|w| { + w.get("dangerousUseHttpScheme") + .or_else(|| w.get("dangerous-use-http-scheme")) + }) + .and_then(|v| v.as_bool()) + .unwrap_or_default(); + + if let Some(windows) = tauri_config + .get_mut("windows") + .and_then(|w| w.as_array_mut()) + { + for window in windows { + if let Some(window) = window.as_object_mut() { + window.insert("useHttpsScheme".to_string(), (!dangerouse_use_http).into()); + } + } + } + // security if let Some(security) = tauri_config .get_mut("security") @@ -802,7 +824,8 @@ mod test { "pattern": { "use": "brownfield" }, "security": { "csp": "default-src 'self' tauri:" - } + }, + "windows": [{}] } }); @@ -907,6 +930,8 @@ mod test { migrated["app"]["withGlobalTauri"], original["build"]["withGlobalTauri"] ); + + assert_eq!(migrated["app"]["windows"][0]["useHttpsScheme"], true); } #[test] @@ -941,6 +966,28 @@ mod test { ); } + #[test] + fn migrate_dangerous_use_http_scheme() { + let original = serde_json::json!({ + "tauri": { + "windows": [{}], + "security": { + "dangerousUseHttpScheme": true, + } + } + }); + + let migrated = migrate(&original); + assert_eq!( + !migrated["app"]["windows"][0]["useHttpsScheme"] + .as_bool() + .unwrap(), + original["tauri"]["security"]["dangerousUseHttpScheme"] + .as_bool() + .unwrap() + ); + } + #[test] fn can_migrate_default_config() { let original = serde_json::to_value(tauri_utils_v1::config::Config::default()).unwrap(); diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index 0e2f23386f46..838def7790ec 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -22,8 +22,8 @@ use tauri_runtime::{ monitor::Monitor, webview::{DetachedWebview, DownloadEvent, PendingWebview, WebviewIpcHandler}, window::{ - CursorIcon, DetachedWindow, DragDropEvent, PendingWindow, RawWindow, WebviewEvent, - WindowBuilder, WindowBuilderBase, WindowEvent, WindowId, WindowSizeConstraints, + CursorIcon, DetachedWindow, DetachedWindowWebview, DragDropEvent, PendingWindow, RawWindow, + WebviewEvent, WindowBuilder, WindowBuilderBase, WindowEvent, WindowId, WindowSizeConstraints, }, DeviceEventFilter, Error, EventLoopProxy, ExitRequestedEventAction, Icon, ProgressBarState, ProgressBarStatus, Result, RunEvent, Runtime, RuntimeHandle, RuntimeInitArgs, UserAttentionType, @@ -276,7 +276,16 @@ impl Context { let label = pending.label.clone(); let context = self.clone(); let window_id = self.next_window_id(); - let webview_id = pending.webview.as_ref().map(|_| context.next_webview_id()); + let (webview_id, use_https_scheme) = pending + .webview + .as_ref() + .map(|w| { + ( + Some(context.next_webview_id()), + w.webview_attributes.use_https_scheme, + ) + }) + .unwrap_or((None, false)); send_user_message( self, @@ -300,13 +309,19 @@ impl Context { context: self.clone(), }; - let detached_webview = webview_id.map(|id| DetachedWebview { - label: label.clone(), - dispatcher: WryWebviewDispatcher { - window_id: Arc::new(Mutex::new(window_id)), - webview_id: id, - context: self.clone(), - }, + let detached_webview = webview_id.map(|id| { + let webview = DetachedWebview { + label: label.clone(), + dispatcher: WryWebviewDispatcher { + window_id: Arc::new(Mutex::new(window_id)), + webview_id: id, + context: self.clone(), + }, + }; + DetachedWindowWebview { + webview, + use_https_scheme, + } }); Ok(DetachedWindow { @@ -746,6 +761,8 @@ impl WindowBuilder for WindowBuilderWrapper { builder = builder.title_bar_style(TitleBarStyle::Visible); } + builder = builder.title("Tauri App"); + builder } @@ -2497,10 +2514,16 @@ impl Runtime for Wry { ) -> Result> { let label = pending.label.clone(); let window_id = self.context.next_window_id(); - let webview_id = pending + let (webview_id, use_https_scheme) = pending .webview .as_ref() - .map(|_| self.context.next_webview_id()); + .map(|w| { + ( + Some(self.context.next_webview_id()), + w.webview_attributes.use_https_scheme, + ) + }) + .unwrap_or((None, false)); let window = create_window( window_id, @@ -2524,13 +2547,19 @@ impl Runtime for Wry { .borrow_mut() .insert(window_id, window); - let detached_webview = webview_id.map(|id| DetachedWebview { - label: label.clone(), - dispatcher: WryWebviewDispatcher { - window_id: Arc::new(Mutex::new(window_id)), - webview_id: id, - context: self.context.clone(), - }, + let detached_webview = webview_id.map(|id| { + let webview = DetachedWebview { + label: label.clone(), + dispatcher: WryWebviewDispatcher { + window_id: Arc::new(Mutex::new(window_id)), + webview_id: id, + context: self.context.clone(), + }, + }; + DetachedWindowWebview { + webview, + use_https_scheme, + } }); Ok(DetachedWindow { @@ -4026,6 +4055,11 @@ fn create_webview( .with_clipboard(webview_attributes.clipboard) .with_hotkeys_zoom(webview_attributes.zoom_hotkeys_enabled); + #[cfg(any(target_os = "windows", target_os = "android"))] + { + webview_builder = webview_builder.with_https_scheme(webview_attributes.use_https_scheme); + } + if webview_attributes.drag_drop_handler_enabled { let proxy = context.proxy.clone(); let window_id_ = window_id.clone(); @@ -4168,11 +4202,6 @@ fn create_webview( }); } - #[cfg(windows)] - { - webview_builder = webview_builder.with_https_scheme(false); - } - #[cfg(windows)] { webview_builder = webview_builder @@ -4282,7 +4311,7 @@ fn create_webview( builder } } - .map_err(|e| Error::CreateWebview(Box::new(dbg!(e))))?; + .map_err(|e| Error::CreateWebview(Box::new(e)))?; if kind == WebviewKind::WindowContent { #[cfg(any( diff --git a/crates/tauri-runtime/src/webview.rs b/crates/tauri-runtime/src/webview.rs index 651aaec5eac3..149983808895 100644 --- a/crates/tauri-runtime/src/webview.rs +++ b/crates/tauri-runtime/src/webview.rs @@ -210,6 +210,7 @@ pub struct WebviewAttributes { pub proxy_url: Option, pub zoom_hotkeys_enabled: bool, pub browser_extensions_enabled: bool, + pub use_https_scheme: bool, } impl From<&WindowConfig> for WebviewAttributes { @@ -218,6 +219,7 @@ impl From<&WindowConfig> for WebviewAttributes { .incognito(config.incognito) .focused(config.focus) .zoom_hotkeys_enabled(config.zoom_hotkeys_enabled) + .use_https_scheme(config.use_https_scheme) .browser_extensions_enabled(config.browser_extensions_enabled); #[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))] { @@ -264,6 +266,7 @@ impl WebviewAttributes { proxy_url: None, zoom_hotkeys_enabled: false, browser_extensions_enabled: false, + use_https_scheme: false, } } @@ -388,6 +391,21 @@ impl WebviewAttributes { self.browser_extensions_enabled = enabled; self } + + /// Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`. + /// + /// ## Note + /// + /// Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `://localhost` protocols used on macOS and Linux. + /// + /// ## Warning + /// + /// Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data. + #[must_use] + pub fn use_https_scheme(mut self, enabled: bool) -> Self { + self.use_https_scheme = enabled; + self + } } /// IPC handler. diff --git a/crates/tauri-runtime/src/window.rs b/crates/tauri-runtime/src/window.rs index 54676ef65bf9..cea526f5f120 100644 --- a/crates/tauri-runtime/src/window.rs +++ b/crates/tauri-runtime/src/window.rs @@ -512,7 +512,23 @@ pub struct DetachedWindow> { pub dispatcher: R::WindowDispatcher, /// The webview dispatcher in case this window has an attached webview. - pub webview: Option>, + pub webview: Option>, +} + +/// A detached webview associated with a window. +#[derive(Debug)] +pub struct DetachedWindowWebview> { + pub webview: DetachedWebview, + pub use_https_scheme: bool, +} + +impl> Clone for DetachedWindowWebview { + fn clone(&self) -> Self { + Self { + webview: self.webview.clone(), + use_https_scheme: self.use_https_scheme, + } + } } impl> Clone for DetachedWindow { diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json index 90acf8973183..820fb35a55f0 100644 --- a/crates/tauri-schema-generator/schemas/config.schema.json +++ b/crates/tauri-schema-generator/schemas/config.schema.json @@ -486,6 +486,11 @@ "description": "Whether browser extensions can be installed for the webview process\n\n ## Platform-specific:\n\n - **Windows**: Enables the WebView2 environment's [`AreBrowserExtensionsEnabled`](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2environmentoptions?view=webview2-winrt-1.0.2739.15#arebrowserextensionsenabled)\n - **MacOS / Linux / iOS / Android** - Unsupported.", "default": false, "type": "boolean" + }, + "useHttpsScheme": { + "description": "Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`.\n\n ## Note\n\n Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `://localhost` protocols used on macOS and Linux.\n\n ## Warning\n\n Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.", + "default": false, + "type": "boolean" } }, "additionalProperties": false diff --git a/crates/tauri-utils/src/config.rs b/crates/tauri-utils/src/config.rs index 041deda585b1..4affc4c87cd2 100644 --- a/crates/tauri-utils/src/config.rs +++ b/crates/tauri-utils/src/config.rs @@ -1519,6 +1519,18 @@ pub struct WindowConfig { /// - **MacOS / Linux / iOS / Android** - Unsupported. #[serde(default)] pub browser_extensions_enabled: bool, + + /// Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`. + /// + /// ## Note + /// + /// Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `://localhost` protocols used on macOS and Linux. + /// + /// ## Warning + /// + /// Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data. + #[serde(default, alias = "use-https-scheme")] + pub use_https_scheme: bool, } impl Default for WindowConfig { @@ -1567,6 +1579,7 @@ impl Default for WindowConfig { proxy_url: None, zoom_hotkeys_enabled: false, browser_extensions_enabled: false, + use_https_scheme: false, } } } @@ -2538,6 +2551,7 @@ mod build { let parent = opt_str_lit(self.parent.as_ref()); let zoom_hotkeys_enabled = self.zoom_hotkeys_enabled; let browser_extensions_enabled = self.browser_extensions_enabled; + let use_https_scheme = self.use_https_scheme; literal_struct!( tokens, @@ -2584,7 +2598,8 @@ mod build { incognito, parent, zoom_hotkeys_enabled, - browser_extensions_enabled + browser_extensions_enabled, + use_https_scheme ); } } diff --git a/crates/tauri/scripts/core.js b/crates/tauri/scripts/core.js index 6f4523c8d67a..b68b6039195b 100644 --- a/crates/tauri/scripts/core.js +++ b/crates/tauri/scripts/core.js @@ -8,12 +8,13 @@ } const osName = __TEMPLATE_os_name__ + const protocolScheme = __TEMPLATE_protocol_scheme__ Object.defineProperty(window.__TAURI_INTERNALS__, 'convertFileSrc', { value: function (filePath, protocol = 'asset') { const path = encodeURIComponent(filePath) return osName === 'windows' || osName === 'android' - ? `http://${protocol}.localhost/${path}` + ? `${protocolScheme}://${protocol}.localhost/${path}` : `${protocol}://localhost/${path}` } }) diff --git a/crates/tauri/src/app.rs b/crates/tauri/src/app.rs index b513ed7f8964..509ba340c8f4 100644 --- a/crates/tauri/src/app.rs +++ b/crates/tauri/src/app.rs @@ -268,6 +268,10 @@ pub struct AssetResolver { impl AssetResolver { /// Gets the app asset associated with the given path. /// + /// By default it tries to infer your application's URL scheme in production by checking if all webviews + /// were configured with [`crate::webview::WebviewBuilder::use_https_scheme`] or `tauri.conf.json > app > windows > useHttpsScheme`. + /// If you are resolving an asset for a webview with a more dynamic configuration, see [`AssetResolver::get_for_scheme`]. + /// /// Resolves to the embedded asset that is part of the app /// in dev when [`devUrl`](https://v2.tauri.app/reference/config/#devurl) points to a folder in your filesystem /// or in production when [`frontendDist`](https://v2.tauri.app/reference/config/#frontenddist) @@ -276,6 +280,19 @@ impl AssetResolver { /// Fallbacks to reading the asset from the [distDir] folder so the behavior is consistent in development. /// Note that the dist directory must exist so you might need to build your frontend assets first. pub fn get(&self, path: String) -> Option { + let use_https_scheme = self + .manager + .webviews() + .values() + .all(|webview| webview.use_https_scheme()); + self.get_for_scheme(path, use_https_scheme) + } + + /// Same as [AssetResolver::get] but resolves the custom protocol scheme based on a parameter. + /// + /// - `use_https_scheme`: If `true` when using [`Pattern::Isolation`](tauri::Pattern::Isolation), + /// the csp header will contain `https://tauri.localhost` instead of `http://tauri.localhost` + pub fn get_for_scheme(&self, path: String, use_https_scheme: bool) -> Option { #[cfg(dev)] { // on dev if the devPath is a path to a directory we have the embedded assets @@ -306,7 +323,7 @@ impl AssetResolver { } } - self.manager.get_asset(path).ok() + self.manager.get_asset(path, use_https_scheme).ok() } /// Iterate on all assets. diff --git a/crates/tauri/src/manager/mod.rs b/crates/tauri/src/manager/mod.rs index d272b241bfb9..81f0eaae284d 100644 --- a/crates/tauri/src/manager/mod.rs +++ b/crates/tauri/src/manager/mod.rs @@ -340,9 +340,10 @@ impl AppManager { self.config.build.dev_url.as_ref() } - pub(crate) fn protocol_url(&self) -> Cow<'_, Url> { + pub(crate) fn protocol_url(&self, https: bool) -> Cow<'_, Url> { if cfg!(windows) || cfg!(target_os = "android") { - Cow::Owned(Url::parse("http://tauri.localhost").unwrap()) + let scheme = if https { "https" } else { "http" }; + Cow::Owned(Url::parse(&format!("{scheme}://tauri.localhost")).unwrap()) } else { Cow::Owned(Url::parse("tauri://localhost").unwrap()) } @@ -351,10 +352,10 @@ impl AppManager { /// Get the base URL to use for webview requests. /// /// In dev mode, this will be based on the `devUrl` configuration value. - pub(crate) fn get_url(&self) -> Cow<'_, Url> { + pub(crate) fn get_url(&self, https: bool) -> Cow<'_, Url> { match self.base_path() { Some(url) => Cow::Borrowed(url), - _ => self.protocol_url(), + _ => self.protocol_url(https), } } @@ -372,7 +373,11 @@ impl AppManager { } } - pub fn get_asset(&self, mut path: String) -> Result> { + pub fn get_asset( + &self, + mut path: String, + use_https_schema: bool, + ) -> Result> { let assets = &self.assets; if path.ends_with('/') { path.pop(); @@ -435,7 +440,7 @@ impl AppManager { let default_src = csp_map .entry("default-src".into()) .or_insert_with(Default::default); - default_src.push(crate::pattern::format_real_schema(schema)); + default_src.push(crate::pattern::format_real_schema(schema, use_https_schema)); } csp_header.replace(Csp::DirectiveMap(csp_map).to_string()); @@ -771,17 +776,25 @@ mod test { #[cfg(custom_protocol)] { assert_eq!( - manager.get_url().to_string(), + manager.get_url(false).to_string(), if cfg!(windows) || cfg!(target_os = "android") { "http://tauri.localhost/" } else { "tauri://localhost" } ); + assert_eq!( + manager.get_url(true).to_string(), + if cfg!(windows) || cfg!(target_os = "android") { + "https://tauri.localhost/" + } else { + "tauri://localhost" + } + ); } #[cfg(dev)] - assert_eq!(manager.get_url().to_string(), "http://localhost:4000/"); + assert_eq!(manager.get_url(false).to_string(), "http://localhost:4000/"); } struct EventSetup { diff --git a/crates/tauri/src/manager/webview.rs b/crates/tauri/src/manager/webview.rs index 5eb4ba8de2a3..8773600dca2e 100644 --- a/crates/tauri/src/manager/webview.rs +++ b/crates/tauri/src/manager/webview.rs @@ -137,10 +137,14 @@ impl WebviewManager { let mut webview_attributes = pending.webview_attributes; + let use_https_scheme = webview_attributes.use_https_scheme; + let ipc_init = IpcJavascript { isolation_origin: &match &*app_manager.pattern { #[cfg(feature = "isolation")] - crate::Pattern::Isolation { schema, .. } => crate::pattern::format_real_schema(schema), + crate::Pattern::Isolation { schema, .. } => { + crate::pattern::format_real_schema(schema, use_https_scheme) + } _ => "".to_string(), }, } @@ -180,6 +184,7 @@ impl WebviewManager { &ipc_init.into_string(), &pattern_init.into_string(), is_init_global, + use_https_scheme, )?); for plugin_init_script in plugin_init_scripts { @@ -190,7 +195,7 @@ impl WebviewManager { if let crate::Pattern::Isolation { schema, .. } = &*app_manager.pattern { webview_attributes = webview_attributes.initialization_script( &IsolationJavascript { - isolation_src: &crate::pattern::format_real_schema(schema), + isolation_src: &crate::pattern::format_real_schema(schema, use_https_scheme), style: tauri_utils::pattern::isolation::IFRAME_STYLE, } .render_default(&Default::default())? @@ -232,7 +237,8 @@ impl WebviewManager { && window_url.scheme() != "http" && window_url.scheme() != "https" { - format!("http://{}.localhost", window_url.scheme()) + let https = if use_https_scheme { "https" } else { "http" }; + format!("{https}://{}.localhost", window_url.scheme()) } else if let Some(host) = window_url.host() { format!( "{}://{}{}", @@ -320,6 +326,7 @@ impl WebviewManager { assets.clone(), *crypto_keys.aes_gcm().raw(), window_origin, + use_https_scheme, ); pending.register_uri_scheme_protocol(schema, move |webview_id, request, responder| { protocol(webview_id, request, UriSchemeResponder(responder)) @@ -335,6 +342,7 @@ impl WebviewManager { ipc_script: &str, pattern_script: &str, with_global_tauri: bool, + use_https_scheme: bool, ) -> crate::Result { #[derive(Template)] #[default_template("../../scripts/init.js")] @@ -357,6 +365,7 @@ impl WebviewManager { #[default_template("../../scripts/core.js")] struct CoreJavascript<'a> { os_name: &'a str, + protocol_scheme: &'a str, invoke_key: &'a str, } @@ -378,6 +387,7 @@ impl WebviewManager { bundle_script, core_script: &CoreJavascript { os_name: std::env::consts::OS, + protocol_scheme: if use_https_scheme { "https" } else { "http" }, invoke_key: self.invoke_key(), } .render_default(&Default::default())? @@ -411,7 +421,7 @@ impl WebviewManager { let url = if PROXY_DEV_SERVER { Cow::Owned(Url::parse("tauri://localhost").unwrap()) } else { - app_manager.get_url() + app_manager.get_url(pending.webview_attributes.use_https_scheme) }; // ignore "index.html" just to simplify the url if path.to_str() != Some("index.html") { @@ -425,7 +435,7 @@ impl WebviewManager { } } WebviewUrl::External(url) => { - let config_url = app_manager.get_url(); + let config_url = app_manager.get_url(pending.webview_attributes.use_https_scheme); let is_local = config_url.make_relative(url).is_some(); let mut url = url.clone(); if is_local && PROXY_DEV_SERVER { @@ -572,8 +582,9 @@ impl WebviewManager { &self, window: Window, webview: DetachedWebview, + use_https_scheme: bool, ) -> Webview { - let webview = Webview::new(window, webview); + let webview = Webview::new(window, webview, use_https_scheme); let webview_event_listeners = self.event_listeners.clone(); let webview_ = webview.clone(); diff --git a/crates/tauri/src/pattern.rs b/crates/tauri/src/pattern.rs index 221fce9fb1c2..d0cd132c21b9 100644 --- a/crates/tauri/src/pattern.rs +++ b/crates/tauri/src/pattern.rs @@ -85,9 +85,10 @@ pub(crate) struct PatternJavascript { } #[allow(dead_code)] -pub(crate) fn format_real_schema(schema: &str) -> String { +pub(crate) fn format_real_schema(schema: &str, https: bool) -> String { if cfg!(windows) || cfg!(target_os = "android") { - format!("http://{schema}.{ISOLATION_IFRAME_SRC_DOMAIN}") + let scheme = if https { "https" } else { "http" }; + format!("{scheme}://{schema}.{ISOLATION_IFRAME_SRC_DOMAIN}") } else { format!("{schema}://{ISOLATION_IFRAME_SRC_DOMAIN}") } diff --git a/crates/tauri/src/protocol/isolation.rs b/crates/tauri/src/protocol/isolation.rs index 6d546d288695..f85f8e6cd3a7 100644 --- a/crates/tauri/src/protocol/isolation.rs +++ b/crates/tauri/src/protocol/isolation.rs @@ -21,9 +21,11 @@ pub fn get( assets: Arc, aes_gcm_key: [u8; 32], window_origin: String, + use_https_scheme: bool, ) -> UriSchemeProtocolHandler { let frame_src = if cfg!(any(windows, target_os = "android")) { - format!("http://{schema}.localhost") + let https = if use_https_scheme { "https" } else { "http" }; + format!("{https}://{schema}.localhost") } else { format!("{schema}:") }; diff --git a/crates/tauri/src/protocol/tauri.rs b/crates/tauri/src/protocol/tauri.rs index 2d33c4a00f7f..ac33b5be2de7 100644 --- a/crates/tauri/src/protocol/tauri.rs +++ b/crates/tauri/src/protocol/tauri.rs @@ -30,7 +30,10 @@ pub fn get( ) -> UriSchemeProtocolHandler { #[cfg(all(dev, mobile))] let url = { - let mut url = manager.get_url().as_str().to_string(); + let mut url = manager + .get_url(window_origin.starts_with("https")) + .as_str() + .to_string(); if url.ends_with('/') { url.pop(); } @@ -152,7 +155,8 @@ fn get_response( #[cfg(not(all(dev, mobile)))] let mut response = { - let asset = manager.get_asset(path)?; + let use_https_scheme = request.uri().scheme() == Some(&http::uri::Scheme::HTTPS); + let asset = manager.get_asset(path, use_https_scheme)?; builder = builder.header(CONTENT_TYPE, &asset.mime_type); if let Some(csp) = &asset.csp_header { builder = builder.header("Content-Security-Policy", csp); diff --git a/crates/tauri/src/test/mock_runtime.rs b/crates/tauri/src/test/mock_runtime.rs index 80c32e26d8ed..7f51b1902077 100644 --- a/crates/tauri/src/test/mock_runtime.rs +++ b/crates/tauri/src/test/mock_runtime.rs @@ -9,8 +9,10 @@ use tauri_runtime::{ dpi::{PhysicalPosition, PhysicalSize, Position, Size}, monitor::Monitor, webview::{DetachedWebview, PendingWebview}, - window::{CursorIcon, DetachedWindow, PendingWindow, RawWindow, WindowEvent, WindowId}, - window::{WindowBuilder, WindowBuilderBase}, + window::{ + CursorIcon, DetachedWindow, DetachedWindowWebview, PendingWindow, RawWindow, WindowBuilder, + WindowBuilderBase, WindowEvent, WindowId, + }, DeviceEventFilter, Error, EventLoopProxy, ExitRequestedEventAction, Icon, ProgressBarState, Result, RunEvent, Runtime, RuntimeHandle, RuntimeInitArgs, UserAttentionType, UserEvent, WebviewDispatch, WindowDispatch, WindowEventId, @@ -158,14 +160,17 @@ impl RuntimeHandle for MockRuntimeHandle { }, ); - let webview = webview_id.map(|id| DetachedWebview { - label: pending.label.clone(), - dispatcher: MockWebviewDispatcher { - id, - context: self.context.clone(), - url: Arc::new(Mutex::new(pending.webview.unwrap().url)), - last_evaluated_script: Default::default(), + let webview = webview_id.map(|id| DetachedWindowWebview { + webview: DetachedWebview { + label: pending.label.clone(), + dispatcher: MockWebviewDispatcher { + id, + context: self.context.clone(), + url: Arc::new(Mutex::new(pending.webview.unwrap().url)), + last_evaluated_script: Default::default(), + }, }, + use_https_scheme: false, }); Ok(DetachedWindow { @@ -773,14 +778,17 @@ impl WindowDispatch for MockWindowDispatcher { }, ); - let webview = webview_id.map(|id| DetachedWebview { - label: pending.label.clone(), - dispatcher: MockWebviewDispatcher { - id, - context: self.context.clone(), - url: Arc::new(Mutex::new(pending.webview.unwrap().url)), - last_evaluated_script: Default::default(), + let webview = webview_id.map(|id| DetachedWindowWebview { + webview: DetachedWebview { + label: pending.label.clone(), + dispatcher: MockWebviewDispatcher { + id, + context: self.context.clone(), + url: Arc::new(Mutex::new(pending.webview.unwrap().url)), + last_evaluated_script: Default::default(), + }, }, + use_https_scheme: false, }); Ok(DetachedWindow { @@ -1065,14 +1073,17 @@ impl Runtime for MockRuntime { }, ); - let webview = webview_id.map(|id| DetachedWebview { - label: pending.label.clone(), - dispatcher: MockWebviewDispatcher { - id, - context: self.context.clone(), - url: Arc::new(Mutex::new(pending.webview.unwrap().url)), - last_evaluated_script: Default::default(), + let webview = webview_id.map(|id| DetachedWindowWebview { + webview: DetachedWebview { + label: pending.label.clone(), + dispatcher: MockWebviewDispatcher { + id, + context: self.context.clone(), + url: Arc::new(Mutex::new(pending.webview.unwrap().url)), + last_evaluated_script: Default::default(), + }, }, + use_https_scheme: false, }); Ok(DetachedWindow { diff --git a/crates/tauri/src/webview/mod.rs b/crates/tauri/src/webview/mod.rs index 06fa0eda0909..199d5a8f90d8 100644 --- a/crates/tauri/src/webview/mod.rs +++ b/crates/tauri/src/webview/mod.rs @@ -605,11 +605,17 @@ tauri::Builder::default() pending.webview_attributes.bounds = Some(tauri_runtime::Rect { size, position }); + let use_https_scheme = pending.webview_attributes.use_https_scheme; + let webview = match &mut window.runtime() { RuntimeOrDispatch::Dispatch(dispatcher) => dispatcher.create_webview(pending), _ => unimplemented!(), } - .map(|webview| app_manager.webview.attach_webview(window.clone(), webview))?; + .map(|webview| { + app_manager + .webview + .attach_webview(window.clone(), webview, use_https_scheme) + })?; Ok(webview) } @@ -794,6 +800,21 @@ fn main() { self.webview_attributes.browser_extensions_enabled = enabled; self } + + /// Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`. + /// + /// ## Note + /// + /// Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `://localhost` protocols used on macOS and Linux. + /// + /// ## Warning + /// + /// Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data. + #[must_use] + pub fn use_https_scheme(mut self, enabled: bool) -> Self { + self.webview_attributes.use_https_scheme = enabled; + self + } } /// Webview. @@ -806,6 +827,7 @@ pub struct Webview { pub(crate) manager: Arc>, pub(crate) app_handle: AppHandle, pub(crate) resources_table: Arc>, + use_https_scheme: bool, } impl std::fmt::Debug for Webview { @@ -813,6 +835,7 @@ impl std::fmt::Debug for Webview { f.debug_struct("Window") .field("window", &self.window.lock().unwrap()) .field("webview", &self.webview) + .field("use_https_scheme", &self.use_https_scheme) .finish() } } @@ -825,6 +848,7 @@ impl Clone for Webview { manager: self.manager.clone(), app_handle: self.app_handle.clone(), resources_table: self.resources_table.clone(), + use_https_scheme: self.use_https_scheme, } } } @@ -847,13 +871,18 @@ impl PartialEq for Webview { /// Base webview functions. impl Webview { /// Create a new webview that is attached to the window. - pub(crate) fn new(window: Window, webview: DetachedWebview) -> Self { + pub(crate) fn new( + window: Window, + webview: DetachedWebview, + use_https_scheme: bool, + ) -> Self { Self { manager: window.manager.clone(), app_handle: window.app_handle.clone(), window: Arc::new(Mutex::new(window)), webview, resources_table: Default::default(), + use_https_scheme, } } @@ -880,6 +909,11 @@ impl Webview { &self.webview.label } + /// Whether the webview was configured to use the HTTPS scheme or not. + pub(crate) fn use_https_scheme(&self) -> bool { + self.use_https_scheme + } + /// Registers a window event listener. pub fn on_webview_event(&self, f: F) { self @@ -1180,9 +1214,11 @@ fn main() { } fn is_local_url(&self, current_url: &Url) -> bool { + let uses_https = current_url.scheme() == "https"; + // if from `tauri://` custom protocol ({ - let protocol_url = self.manager().protocol_url(); + let protocol_url = self.manager().protocol_url(uses_https); current_url.scheme() == protocol_url.scheme() && current_url.domain() == protocol_url.domain() }) || @@ -1190,7 +1226,7 @@ fn main() { // or if relative to `devUrl` or `frontendDist` self .manager() - .get_url() + .get_url(uses_https) .make_relative(current_url) .is_some() @@ -1206,7 +1242,7 @@ fn main() { // so we check using the first part of the domain #[cfg(any(windows, target_os = "android"))] let local = { - let protocol_url = self.manager().protocol_url(); + let protocol_url = self.manager().protocol_url(uses_https); let maybe_protocol = current_url .domain() .and_then(|d| d .split_once('.')) diff --git a/crates/tauri/src/webview/webview_window.rs b/crates/tauri/src/webview/webview_window.rs index 853d5406452d..f66b119abe19 100644 --- a/crates/tauri/src/webview/webview_window.rs +++ b/crates/tauri/src/webview/webview_window.rs @@ -898,6 +898,21 @@ impl<'a, R: Runtime, M: Manager> WebviewWindowBuilder<'a, R, M> { self.webview_builder = self.webview_builder.browser_extensions_enabled(enabled); self } + + /// Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`. + /// + /// ## Note + /// + /// Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `://localhost` protocols used on macOS and Linux. + /// + /// ## Warning + /// + /// Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data. + #[must_use] + pub fn use_https_scheme(mut self, enabled: bool) -> Self { + self.webview_builder = self.webview_builder.use_https_scheme(enabled); + self + } } /// A type that wraps a [`Window`] together with a [`Webview`]. diff --git a/crates/tauri/src/window/mod.rs b/crates/tauri/src/window/mod.rs index 9b8e02b8ef7a..f1292b37ab94 100644 --- a/crates/tauri/src/window/mod.rs +++ b/crates/tauri/src/window/mod.rs @@ -381,7 +381,11 @@ tauri::Builder::default() ); if let Some(webview) = detached_window.webview { - app_manager.webview.attach_webview(window.clone(), webview); + app_manager.webview.attach_webview( + window.clone(), + webview.webview, + webview.use_https_scheme, + ); } window diff --git a/examples/api/src-tauri/src/lib.rs b/examples/api/src-tauri/src/lib.rs index 512f43c0aac0..7f7007eef558 100644 --- a/examples/api/src-tauri/src/lib.rs +++ b/examples/api/src-tauri/src/lib.rs @@ -66,7 +66,8 @@ pub fn run_app) + Send + 'static>( .build()?, )); - let mut window_builder = WebviewWindowBuilder::new(app, "main", WebviewUrl::default()); + let mut window_builder = + WebviewWindowBuilder::new(app, "main", WebviewUrl::default()).use_https_scheme(true); #[cfg(all(desktop, not(test)))] { diff --git a/packages/api/src/webview.ts b/packages/api/src/webview.ts index e04252a95018..a495e135c2c2 100644 --- a/packages/api/src/webview.ts +++ b/packages/api/src/webview.ts @@ -734,6 +734,21 @@ interface WebviewOptions { * - **Android / iOS**: Unsupported. */ zoomHotkeysEnabled?: boolean + + /** + * Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`. + * + * #### Note + * + * Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `://localhost` protocols used on macOS and Linux. + * + * #### Warning + * + * Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access them. + * + * @since 2.1.0 + */ + useHttpsScheme?: boolean } export { Webview, getCurrentWebview, getAllWebviews } From 4191a7a53d941b179780a550638f1b4a09d17fd1 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 5 Nov 2024 17:42:08 +0200 Subject: [PATCH 11/51] fix(tray): build tray on main thread (#11583) --- .changes/tray-async-command.md | 5 +++++ crates/tauri/src/lib.rs | 9 +++++++++ crates/tauri/src/menu/mod.rs | 7 ++----- crates/tauri/src/tray/mod.rs | 19 +++++++++++++++++-- 4 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 .changes/tray-async-command.md diff --git a/.changes/tray-async-command.md b/.changes/tray-async-command.md new file mode 100644 index 000000000000..9e40178190e2 --- /dev/null +++ b/.changes/tray-async-command.md @@ -0,0 +1,5 @@ +--- +"tauri": "patch:bug" +--- + +Fix tray events not fired for tray icons created inside an async command. diff --git a/crates/tauri/src/lib.rs b/crates/tauri/src/lib.rs index ee9f58f9a517..e37df1624d07 100644 --- a/crates/tauri/src/lib.rs +++ b/crates/tauri/src/lib.rs @@ -1011,6 +1011,15 @@ pub(crate) mod sealed { } } +struct UnsafeSend(T); +unsafe impl Send for UnsafeSend {} + +impl UnsafeSend { + fn take(self) -> T { + self.0 + } +} + #[allow(unused)] macro_rules! run_main_thread { ($handle:ident, $ex:expr) => {{ diff --git a/crates/tauri/src/menu/mod.rs b/crates/tauri/src/menu/mod.rs index 2797a5543ea2..2ae33d971b89 100644 --- a/crates/tauri/src/menu/mod.rs +++ b/crates/tauri/src/menu/mod.rs @@ -75,7 +75,6 @@ macro_rules! gen_wrappers { app_handle: $crate::AppHandle, } - /// # Safety /// /// We make sure it always runs on the main thread. @@ -96,11 +95,9 @@ macro_rules! gen_wrappers { impl Drop for $inner { fn drop(&mut self) { - struct SafeSend(T); - unsafe impl Send for SafeSend {} - let inner = self.inner.take(); - let inner = SafeSend(inner); + // SAFETY: inner was created on main thread and is being dropped on main thread + let inner = $crate::UnsafeSend(inner); let _ = self.app_handle.run_on_main_thread(move || { drop(inner); }); diff --git a/crates/tauri/src/tray/mod.rs b/crates/tauri/src/tray/mod.rs index 21623ff2b7d5..5c053f52b66d 100644 --- a/crates/tauri/src/tray/mod.rs +++ b/crates/tauri/src/tray/mod.rs @@ -10,6 +10,7 @@ use crate::app::{GlobalMenuEventListener, GlobalTrayIconEventListener}; use crate::menu::ContextMenu; use crate::menu::MenuEvent; use crate::resources::Resource; +use crate::UnsafeSend; use crate::{ image::Image, menu::run_item_main_thread, AppHandle, Manager, PhysicalPosition, Rect, Runtime, }; @@ -342,10 +343,24 @@ impl TrayIconBuilder { /// Builds and adds a new [`TrayIcon`] to the system tray. pub fn build>(self, manager: &M) -> crate::Result> { let id = self.id().clone(); - let inner = self.inner.build()?; + + // SAFETY: + // the menu within this builder was created on main thread + // and will be accessed on the main thread + let unsafe_builder = UnsafeSend(self.inner); + + let (tx, rx) = std::sync::mpsc::channel(); + let unsafe_tray = manager + .app_handle() + .run_on_main_thread(move || { + // SAFETY: will only be accessed on main thread + let _ = tx.send(unsafe_builder.take().build().map(UnsafeSend)); + }) + .and_then(|_| rx.recv().map_err(|_| crate::Error::FailedToReceiveMessage))??; + let icon = TrayIcon { id, - inner, + inner: unsafe_tray.take(), app_handle: manager.app_handle().clone(), }; From 100a4455aa48df508510bbc08273215bdf70c012 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 5 Nov 2024 19:15:48 +0200 Subject: [PATCH 12/51] fix(cli): fix yarn berry detection (#11529) closes #11495 --- .changes/cli-yarn-berry.md | 6 +++ crates/tauri-cli/src/add.rs | 5 +-- crates/tauri-cli/src/helpers/npm.rs | 37 ++++++++++++++++++- crates/tauri-cli/src/info/env_nodejs.rs | 18 +-------- crates/tauri-cli/src/info/packages_nodejs.rs | 14 ++----- crates/tauri-cli/src/init.rs | 5 +-- .../src/migrate/migrations/v1/frontend.rs | 5 +-- .../tauri-cli/src/migrate/migrations/v2_rc.rs | 5 +-- 8 files changed, 49 insertions(+), 46 deletions(-) create mode 100644 .changes/cli-yarn-berry.md diff --git a/.changes/cli-yarn-berry.md b/.changes/cli-yarn-berry.md new file mode 100644 index 000000000000..6c75565de6b6 --- /dev/null +++ b/.changes/cli-yarn-berry.md @@ -0,0 +1,6 @@ +--- +"tauri-cli": "patch:bug" +"@tauri-apps/cli": "patch:bug" +--- + +Fix detecting yarn berry (v2 and higher) in various tauri cli commands. diff --git a/crates/tauri-cli/src/add.rs b/crates/tauri-cli/src/add.rs index ceb73533326e..f02771d97fe3 100644 --- a/crates/tauri-cli/src/add.rs +++ b/crates/tauri-cli/src/add.rs @@ -81,10 +81,7 @@ pub fn run(options: Options) -> Result<()> { })?; if !metadata.rust_only { - if let Some(manager) = frontend_dir - .map(PackageManager::from_project) - .and_then(|managers| managers.into_iter().next()) - { + if let Some(manager) = frontend_dir.map(PackageManager::from_project) { let npm_version_req = version .map(ToString::to_string) .or(metadata.version_req.as_ref().map(|v| match manager { diff --git a/crates/tauri-cli/src/helpers/npm.rs b/crates/tauri-cli/src/helpers/npm.rs index 8e6134bb1bf9..d1591f78dfdb 100644 --- a/crates/tauri-cli/src/helpers/npm.rs +++ b/crates/tauri-cli/src/helpers/npm.rs @@ -7,6 +7,22 @@ use anyhow::Context; use crate::helpers::cross_command; use std::{fmt::Display, path::Path, process::Command}; +pub fn manager_version(package_manager: &str) -> Option { + cross_command(package_manager) + .arg("-v") + .output() + .map(|o| { + if o.status.success() { + let v = String::from_utf8_lossy(o.stdout.as_slice()).to_string(); + Some(v.split('\n').next().unwrap().to_string()) + } else { + None + } + }) + .ok() + .unwrap_or_default() +} + #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum PackageManager { Npm, @@ -35,7 +51,16 @@ impl Display for PackageManager { } impl PackageManager { - pub fn from_project>(path: P) -> Vec { + /// Detects package manager from the given directory, falls back to [`PackageManager::Npm`]. + pub fn from_project>(path: P) -> Self { + Self::all_from_project(path) + .first() + .copied() + .unwrap_or(Self::Npm) + } + + /// Detects all possible package managers from the given directory. + pub fn all_from_project>(path: P) -> Vec { let mut found = Vec::new(); if let Ok(entries) = std::fs::read_dir(path) { @@ -47,7 +72,15 @@ impl PackageManager { } else if name.as_ref() == "pnpm-lock.yaml" { found.push(PackageManager::Pnpm); } else if name.as_ref() == "yarn.lock" { - found.push(PackageManager::Yarn); + let yarn = if manager_version("yarn") + .map(|v| v.chars().next().map(|c| c > '1').unwrap_or_default()) + .unwrap_or(false) + { + PackageManager::YarnBerry + } else { + PackageManager::Yarn + }; + found.push(yarn); } else if name.as_ref() == "bun.lockb" { found.push(PackageManager::Bun); } else if name.as_ref() == "deno.lock" { diff --git a/crates/tauri-cli/src/info/env_nodejs.rs b/crates/tauri-cli/src/info/env_nodejs.rs index 5d210429ca41..eb9938eee72d 100644 --- a/crates/tauri-cli/src/info/env_nodejs.rs +++ b/crates/tauri-cli/src/info/env_nodejs.rs @@ -5,23 +5,7 @@ use super::{ActionResult, SectionItem, VersionMetadata}; use colored::Colorize; -use crate::helpers::cross_command; - -pub fn manager_version(package_manager: &str) -> Option { - cross_command(package_manager) - .arg("-v") - .output() - .map(|o| { - if o.status.success() { - let v = String::from_utf8_lossy(o.stdout.as_slice()).to_string(); - Some(v.split('\n').next().unwrap().to_string()) - } else { - None - } - }) - .ok() - .unwrap_or_default() -} +use crate::helpers::{cross_command, npm::manager_version}; pub fn items(metadata: &VersionMetadata) -> Vec { let node_target_ver = metadata.js_cli.node.replace(">= ", ""); diff --git a/crates/tauri-cli/src/info/packages_nodejs.rs b/crates/tauri-cli/src/info/packages_nodejs.rs index f484ffd20e7a..73b87d8b7803 100644 --- a/crates/tauri-cli/src/info/packages_nodejs.rs +++ b/crates/tauri-cli/src/info/packages_nodejs.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT use super::SectionItem; -use super::{env_nodejs::manager_version, VersionMetadata}; +use super::VersionMetadata; use colored::Colorize; use serde::Deserialize; use std::path::PathBuf; @@ -77,7 +77,7 @@ pub fn npm_latest_version(pm: &PackageManager, name: &str) -> crate::Result PackageManager { - let found = PackageManager::from_project(frontend_dir); + let found = PackageManager::all_from_project(frontend_dir); if found.is_empty() { println!( @@ -98,15 +98,7 @@ pub fn package_manager(frontend_dir: &PathBuf) -> PackageManager { ); } - if pkg_manager == PackageManager::Yarn - && manager_version("yarn") - .map(|v| v.chars().next().map(|c| c > '1').unwrap_or_default()) - .unwrap_or(false) - { - PackageManager::YarnBerry - } else { - pkg_manager - } + pkg_manager } pub fn items( diff --git a/crates/tauri-cli/src/init.rs b/crates/tauri-cli/src/init.rs index cbd4ae1a0ef5..f12bc4abf00e 100644 --- a/crates/tauri-cli/src/init.rs +++ b/crates/tauri-cli/src/init.rs @@ -131,10 +131,7 @@ impl Options { ) })?; - let detected_package_manager = match PackageManager::from_project(&self.directory).first() { - Some(&package_manager) => package_manager, - None => PackageManager::Npm, - }; + let detected_package_manager = PackageManager::from_project(&self.directory); self.before_dev_command = self .before_dev_command diff --git a/crates/tauri-cli/src/migrate/migrations/v1/frontend.rs b/crates/tauri-cli/src/migrate/migrations/v1/frontend.rs index 83f906a905cc..8ad2771f3554 100644 --- a/crates/tauri-cli/src/migrate/migrations/v1/frontend.rs +++ b/crates/tauri-cli/src/migrate/migrations/v1/frontend.rs @@ -84,10 +84,7 @@ pub fn migrate(frontend_dir: &Path) -> Result> { ) }; - let pm = PackageManager::from_project(frontend_dir) - .into_iter() - .next() - .unwrap_or(PackageManager::Npm); + let pm = PackageManager::from_project(frontend_dir); for pkg in ["@tauri-apps/cli", "@tauri-apps/api"] { let version = pm diff --git a/crates/tauri-cli/src/migrate/migrations/v2_rc.rs b/crates/tauri-cli/src/migrate/migrations/v2_rc.rs index 50ce8a37b10e..844c7de048be 100644 --- a/crates/tauri-cli/src/migrate/migrations/v2_rc.rs +++ b/crates/tauri-cli/src/migrate/migrations/v2_rc.rs @@ -35,10 +35,7 @@ pub fn run() -> Result<()> { } fn migrate_npm_dependencies(frontend_dir: &Path) -> Result<()> { - let pm = PackageManager::from_project(frontend_dir) - .into_iter() - .next() - .unwrap_or(PackageManager::Npm); + let pm = PackageManager::from_project(frontend_dir); let mut install_deps = Vec::new(); for pkg in [ From 7af01ff2ce623d727cd13a4c8a549c1c80031882 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 5 Nov 2024 19:16:32 +0200 Subject: [PATCH 13/51] fix(cli): fix `tauri migrate` failing to install NPM deps when running from Deno (#11523) * fix(cli): fix `tauri migrate` failing to install NPM deps when running from Deno * clippy --- .changes/cli-migrate-deno.md | 7 +++++++ crates/tauri-cli/src/add.rs | 5 +---- crates/tauri-cli/src/helpers/npm.rs | 13 +++++++++---- 3 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 .changes/cli-migrate-deno.md diff --git a/.changes/cli-migrate-deno.md b/.changes/cli-migrate-deno.md new file mode 100644 index 000000000000..63e58dcfdb3f --- /dev/null +++ b/.changes/cli-migrate-deno.md @@ -0,0 +1,7 @@ +--- +"tauri-cli": "patch:bug" +"@tauri-apps/cli": "patch:bug" +--- + +Fix `tauri migrate` failing to install NPM depenencies when running from Deno. + diff --git a/crates/tauri-cli/src/add.rs b/crates/tauri-cli/src/add.rs index f02771d97fe3..56ad58ef0495 100644 --- a/crates/tauri-cli/src/add.rs +++ b/crates/tauri-cli/src/add.rs @@ -90,10 +90,7 @@ pub fn run(options: Options) -> Result<()> { })); let npm_spec = match (npm_version_req, options.tag, options.rev, options.branch) { - (Some(version_req), _, _, _) => match manager { - PackageManager::Deno => format!("npm:{npm_name}@{version_req}"), - _ => format!("{npm_name}@{version_req}"), - }, + (Some(version_req), _, _, _) => format!("{npm_name}@{version_req}"), (None, Some(tag), None, None) => { format!("tauri-apps/tauri-plugin-{plugin}#{tag}") } diff --git a/crates/tauri-cli/src/helpers/npm.rs b/crates/tauri-cli/src/helpers/npm.rs index d1591f78dfdb..1189aa323a52 100644 --- a/crates/tauri-cli/src/helpers/npm.rs +++ b/crates/tauri-cli/src/helpers/npm.rs @@ -122,10 +122,15 @@ impl PackageManager { .join(", ") ); - let status = self - .cross_command() - .arg("add") - .args(dependencies) + let mut command = self.cross_command(); + command.arg("add"); + + match self { + PackageManager::Deno => command.args(dependencies.iter().map(|d| format!("npm:{d}"))), + _ => command.args(dependencies), + }; + + let status = command .current_dir(frontend_dir) .status() .with_context(|| format!("failed to run {self}"))?; From 17c6952aec965fa41e6695ad68461a218afc20f1 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 5 Nov 2024 19:20:30 +0200 Subject: [PATCH 14/51] enhance(core): use `diagnostic::on_unimplemented` on rustc 1.78 and newer for async commands with references (#11522) * enhance(core): use `diagnostic::on_unimplemented` on rustc 1.78 and newer for async commands with references * change file * clippy * clippy * add TODO --- .changes/enhance-async-commands-error.md | 6 +++ crates/tauri-macros/src/command/wrapper.rs | 48 ++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 .changes/enhance-async-commands-error.md diff --git a/.changes/enhance-async-commands-error.md b/.changes/enhance-async-commands-error.md new file mode 100644 index 000000000000..e7be9d49383a --- /dev/null +++ b/.changes/enhance-async-commands-error.md @@ -0,0 +1,6 @@ +--- +"tauri": "patch:enhance" +"tauri-macros": "patch:enhance" +--- + +Enhance the error message when using `async` commands with a reference. diff --git a/crates/tauri-macros/src/command/wrapper.rs b/crates/tauri-macros/src/command/wrapper.rs index 306d964e864f..4babd0dbb325 100644 --- a/crates/tauri-macros/src/command/wrapper.rs +++ b/crates/tauri-macros/src/command/wrapper.rs @@ -186,9 +186,18 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream { // only implemented by `Result`. That way we don't exclude renamed result types // which we wouldn't otherwise be able to detect purely from the token stream. // The "error message" displayed to the user is simply the trait name. + // + // TODO: remove this check once our MSRV is high enough + let diagnostic = if is_rustc_at_least(1, 78) { + quote!(#[diagnostic::on_unimplemented(message = "async commands that contain references as inputs must return a `Result`")]) + } else { + quote!() + }; + async_command_check = quote_spanned! {return_type.span() => #[allow(unreachable_code, clippy::diverging_sub_expression)] const _: () = if false { + #diagnostic trait AsyncCommandMustReturnResult {} impl AsyncCommandMustReturnResult for ::std::result::Result {} let _check: #return_type = unreachable!(); @@ -452,3 +461,42 @@ fn parse_arg( } ))) } + +fn is_rustc_at_least(major: u32, minor: u32) -> bool { + let version = rustc_version(); + version.0 >= major && version.1 >= minor +} + +fn rustc_version() -> (u32, u32) { + cross_command("rustc") + .arg("-V") + .output() + .ok() + .and_then(|o| { + let version = String::from_utf8_lossy(&o.stdout) + .trim() + .split(' ') + .nth(1) + .unwrap_or_default() + .split(".") + .take(2) + .flat_map(|p| p.parse::().ok()) + .collect::>(); + version + .first() + .and_then(|major| version.get(1).map(|minor| (*major, *minor))) + }) + .unwrap_or((1, 0)) +} + +fn cross_command(bin: &str) -> std::process::Command { + #[cfg(target_os = "windows")] + let cmd = { + let mut cmd = std::process::Command::new("cmd"); + cmd.arg("/c").arg(bin); + cmd + }; + #[cfg(not(target_os = "windows"))] + let cmd = std::process::Command::new(bin); + cmd +} From 1b6b2cfaa14ab1d418c676cedbf942a812377a30 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 5 Nov 2024 19:46:54 +0200 Subject: [PATCH 15/51] feat(cli): process `bundle > windows > wix > fragmentPaths` with Handlebars (#11521) * feat(cli): process `bundle > windows > wix > fragmentPaths` with Handlebars closes #11520 * remove unneeded register_template_string * Update crates/tauri-bundler/src/bundle/windows/msi/mod.rs --------- Co-authored-by: Lucas Fernandes Nogueira --- .changes/bundler-fragment-handlebars.md | 7 ++++++ Cargo.lock | 4 ++-- .../src/bundle/linux/appimage/mod.rs | 5 +--- .../src/bundle/windows/msi/mod.rs | 24 ++++++------------- 4 files changed, 17 insertions(+), 23 deletions(-) create mode 100644 .changes/bundler-fragment-handlebars.md diff --git a/.changes/bundler-fragment-handlebars.md b/.changes/bundler-fragment-handlebars.md new file mode 100644 index 000000000000..d836fec27ad5 --- /dev/null +++ b/.changes/bundler-fragment-handlebars.md @@ -0,0 +1,7 @@ +--- +"tauri-bundler": "minor:feat" +"tauri-cli": "minor:feat" +--- + +Process `bundle > windows > wix > fragmentPaths` with Handlebars to interpolate expressions within it. + diff --git a/Cargo.lock b/Cargo.lock index bf60de3db43b..a1ed9ccdda65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8758,9 +8758,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.30.2" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e48d7c56b3f7425d061886e8ce3b6acfab1993682ed70bef50fd133d721ee6" +checksum = "a0dbbebe82d02044dfa481adca1550d6dd7bd16e086bc34fa0fbecceb5a63751" dependencies = [ "bitflags 2.6.0", "cocoa 0.26.0", diff --git a/crates/tauri-bundler/src/bundle/linux/appimage/mod.rs b/crates/tauri-bundler/src/bundle/linux/appimage/mod.rs index ce6d6170c160..f6942a47f97c 100644 --- a/crates/tauri-bundler/src/bundle/linux/appimage/mod.rs +++ b/crates/tauri-bundler/src/bundle/linux/appimage/mod.rs @@ -106,10 +106,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { // initialize shell script template. let mut handlebars = Handlebars::new(); handlebars.register_escape_fn(handlebars::no_escape); - handlebars - .register_template_string("appimage", include_str!("./appimage")) - .expect("Failed to register template for handlebars"); - let temp = handlebars.render("appimage", &sh_map)?; + let temp = handlebars.render_template(include_str!("./appimage"), &sh_map)?; // create the shell script file in the target/ folder. let sh_file = output_path.join("build_appimage.sh"); diff --git a/crates/tauri-bundler/src/bundle/windows/msi/mod.rs b/crates/tauri-bundler/src/bundle/windows/msi/mod.rs index f9daaf25718e..bc633a4be9f3 100644 --- a/crates/tauri-bundler/src/bundle/windows/msi/mod.rs +++ b/crates/tauri-bundler/src/bundle/windows/msi/mod.rs @@ -726,38 +726,26 @@ pub fn build_wix_app_installer( ); // Create the update task XML - let mut skip_uac_task = Handlebars::new(); + let skip_uac_task = Handlebars::new(); let xml = include_str!("./update-task.xml"); - skip_uac_task - .register_template_string("update.xml", xml) - .map_err(|e| e.to_string()) - .expect("Failed to setup Update Task handlebars"); + let update_content = skip_uac_task.render_template(xml, &data)?; let temp_xml_path = output_path.join("update.xml"); - let update_content = skip_uac_task.render("update.xml", &data)?; fs::write(temp_xml_path, update_content)?; // Create the Powershell script to install the task let mut skip_uac_task_installer = Handlebars::new(); skip_uac_task_installer.register_escape_fn(handlebars::no_escape); let xml = include_str!("./install-task.ps1"); - skip_uac_task_installer - .register_template_string("install-task.ps1", xml) - .map_err(|e| e.to_string()) - .expect("Failed to setup Update Task Installer handlebars"); + let install_script_content = skip_uac_task_installer.render_template(xml, &data)?; let temp_ps1_path = output_path.join("install-task.ps1"); - let install_script_content = skip_uac_task_installer.render("install-task.ps1", &data)?; fs::write(temp_ps1_path, install_script_content)?; // Create the Powershell script to uninstall the task let mut skip_uac_task_uninstaller = Handlebars::new(); skip_uac_task_uninstaller.register_escape_fn(handlebars::no_escape); let xml = include_str!("./uninstall-task.ps1"); - skip_uac_task_uninstaller - .register_template_string("uninstall-task.ps1", xml) - .map_err(|e| e.to_string()) - .expect("Failed to setup Update Task Uninstaller handlebars"); + let install_script_content = skip_uac_task_uninstaller.render_template(xml, &data)?; let temp_ps1_path = output_path.join("uninstall-task.ps1"); - let install_script_content = skip_uac_task_uninstaller.render("uninstall-task.ps1", &data)?; fs::write(temp_ps1_path, install_script_content)?; data.insert("enable_elevated_update_task", to_json(true)); @@ -772,7 +760,9 @@ pub fn build_wix_app_installer( let extension_regex = Regex::new("\"http://schemas.microsoft.com/wix/(\\w+)\"")?; for fragment_path in fragment_paths { let fragment_path = current_dir.join(fragment_path); - let fragment = fs::read_to_string(&fragment_path)?; + let fragment_content = fs::read_to_string(&fragment_path)?; + let fragment_handlebars = Handlebars::new(); + let fragment = fragment_handlebars.render_template(&fragment_content, &data)?; let mut extensions = Vec::new(); for cap in extension_regex.captures_iter(&fragment) { extensions.push(wix_toolset_path.join(format!("Wix{}.dll", &cap[1]))); From 2a75c64b5431284e7340e8743d4ea56a62c75466 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 5 Nov 2024 20:18:47 +0200 Subject: [PATCH 16/51] feat(core): add window_class name API on Windows (#11469) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * On Windows, set name of Window Class, closes #7498 allow to customize it instead of current value hard coded "Window Class" * feat(windows): add window_classname, closes #7498 allow to customize the window class name instead of current value hard coded "Window Class" * feat: add window_classname, closes #7498 * add changes file * Update core/tauri-config-schema/schema.json * Update tooling/cli/schema.json * missing pieces after merge * clippy --------- Co-authored-by: Géraud-Loup <47665233+geraudloup@users.noreply.github.com> Co-authored-by: Lucas Nogueira --- .changes/window-class-name-config-api.md | 5 +++++ .changes/window-class-name-config.md | 6 ++++++ .changes/window-class-name.md | 7 +++++++ crates/tauri-cli/config.schema.json | 7 +++++++ crates/tauri-runtime-wry/src/lib.rs | 19 +++++++++++++++++++ crates/tauri-runtime/src/window.rs | 4 ++++ .../schemas/config.schema.json | 7 +++++++ crates/tauri-utils/src/config.rs | 5 +++++ crates/tauri/src/test/mock_runtime.rs | 4 ++++ crates/tauri/src/webview/webview_window.rs | 7 +++++++ crates/tauri/src/window/mod.rs | 7 +++++++ 11 files changed, 78 insertions(+) create mode 100644 .changes/window-class-name-config-api.md create mode 100644 .changes/window-class-name-config.md create mode 100644 .changes/window-class-name.md diff --git a/.changes/window-class-name-config-api.md b/.changes/window-class-name-config-api.md new file mode 100644 index 000000000000..13128871bad5 --- /dev/null +++ b/.changes/window-class-name-config-api.md @@ -0,0 +1,5 @@ +--- +"@tauri-apps/api": 'minor:feat' +--- + +Added `windowClassname` option, when constructing a `Webview` or `WebviewWindow`, to specify the name of the window class on Windows. diff --git a/.changes/window-class-name-config.md b/.changes/window-class-name-config.md new file mode 100644 index 000000000000..66e318c0994d --- /dev/null +++ b/.changes/window-class-name-config.md @@ -0,0 +1,6 @@ +--- +"tauri": 'minor:feat' +"tauri-utils": 'minor:feat' +--- + +Added `app > windows > windowClassname` config option to specify the name of the window class on Windows. diff --git a/.changes/window-class-name.md b/.changes/window-class-name.md new file mode 100644 index 000000000000..015602e820c8 --- /dev/null +++ b/.changes/window-class-name.md @@ -0,0 +1,7 @@ +--- +"tauri": 'minor:feat' +"tauri-runtime-wry": 'minor:feat' +"tauri-runtime": 'minor:feat' +--- + +Added `WindowBuilder/WebviewWindowBuilder::window_classname` method to specify the name of the window class on Windows. diff --git a/crates/tauri-cli/config.schema.json b/crates/tauri-cli/config.schema.json index 820fb35a55f0..9efeba50db44 100644 --- a/crates/tauri-cli/config.schema.json +++ b/crates/tauri-cli/config.schema.json @@ -397,6 +397,13 @@ "default": false, "type": "boolean" }, + "windowClassname": { + "description": "The name of the window class created on Windows to create the window. **Windows only**.", + "type": [ + "string", + "null" + ] + }, "theme": { "description": "The initial window theme. Defaults to the system theme. Only implemented on Windows and macOS 10.14+.", "anyOf": [ diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index 838def7790ec..65e77ec95670 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -763,6 +763,11 @@ impl WindowBuilder for WindowBuilderWrapper { builder = builder.title("Tauri App"); + #[cfg(windows)] + { + builder = builder.window_classname("Tauri Window"); + } + builder } @@ -846,6 +851,10 @@ impl WindowBuilder for WindowBuilderWrapper { if config.center { window = window.center(); } + + if let Some(window_classname) = &config.window_classname { + window = window.window_classname(window_classname); + } } window @@ -1106,6 +1115,16 @@ impl WindowBuilder for WindowBuilderWrapper { _ => Theme::Light, }) } + + #[cfg(windows)] + fn window_classname>(mut self, window_classname: S) -> Self { + self.inner = self.inner.with_window_classname(window_classname); + self + } + #[cfg(not(windows))] + fn window_classname>(self, _window_classname: S) -> Self { + self + } } #[cfg(any( diff --git a/crates/tauri-runtime/src/window.rs b/crates/tauri-runtime/src/window.rs index cea526f5f120..69f8eaf8a5c7 100644 --- a/crates/tauri-runtime/src/window.rs +++ b/crates/tauri-runtime/src/window.rs @@ -438,6 +438,10 @@ pub trait WindowBuilder: WindowBuilderBase { fn has_icon(&self) -> bool; fn get_theme(&self) -> Option; + + /// Sets custom name for Windows' window class. **Windows only**. + #[must_use] + fn window_classname>(self, window_classname: S) -> Self; } /// A window that has yet to be built. diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json index 820fb35a55f0..9efeba50db44 100644 --- a/crates/tauri-schema-generator/schemas/config.schema.json +++ b/crates/tauri-schema-generator/schemas/config.schema.json @@ -397,6 +397,13 @@ "default": false, "type": "boolean" }, + "windowClassname": { + "description": "The name of the window class created on Windows to create the window. **Windows only**.", + "type": [ + "string", + "null" + ] + }, "theme": { "description": "The initial window theme. Defaults to the system theme. Only implemented on Windows and macOS 10.14+.", "anyOf": [ diff --git a/crates/tauri-utils/src/config.rs b/crates/tauri-utils/src/config.rs index 4affc4c87cd2..1ff12495c022 100644 --- a/crates/tauri-utils/src/config.rs +++ b/crates/tauri-utils/src/config.rs @@ -1429,6 +1429,8 @@ pub struct WindowConfig { /// If `true`, hides the window icon from the taskbar on Windows and Linux. #[serde(default, alias = "skip-taskbar")] pub skip_taskbar: bool, + /// The name of the window class created on Windows to create the window. **Windows only**. + pub window_classname: Option, /// The initial window theme. Defaults to the system theme. Only implemented on Windows and macOS 10.14+. pub theme: Option, /// The style of the macOS title bar. @@ -1566,6 +1568,7 @@ impl Default for WindowConfig { visible_on_all_workspaces: false, content_protected: false, skip_taskbar: false, + window_classname: None, theme: None, title_bar_style: Default::default(), hidden_title: false, @@ -2539,6 +2542,7 @@ mod build { let visible_on_all_workspaces = self.visible_on_all_workspaces; let content_protected = self.content_protected; let skip_taskbar = self.skip_taskbar; + let window_classname = opt_str_lit(self.window_classname.as_ref()); let theme = opt_lit(self.theme.as_ref()); let title_bar_style = &self.title_bar_style; let hidden_title = self.hidden_title; @@ -2587,6 +2591,7 @@ mod build { visible_on_all_workspaces, content_protected, skip_taskbar, + window_classname, theme, title_bar_style, hidden_title, diff --git a/crates/tauri/src/test/mock_runtime.rs b/crates/tauri/src/test/mock_runtime.rs index 7f51b1902077..92fcb9be64c4 100644 --- a/crates/tauri/src/test/mock_runtime.rs +++ b/crates/tauri/src/test/mock_runtime.rs @@ -421,6 +421,10 @@ impl WindowBuilder for MockWindowBuilder { self } + fn window_classname>(self, classname: S) -> Self { + self + } + fn shadow(self, enable: bool) -> Self { self } diff --git a/crates/tauri/src/webview/webview_window.rs b/crates/tauri/src/webview/webview_window.rs index f66b119abe19..9909830eaa73 100644 --- a/crates/tauri/src/webview/webview_window.rs +++ b/crates/tauri/src/webview/webview_window.rs @@ -571,6 +571,13 @@ impl<'a, R: Runtime, M: Manager> WebviewWindowBuilder<'a, R, M> { self } + /// Sets custom name for Windows' window class. **Windows only**. + #[must_use] + pub fn window_classname>(mut self, classname: S) -> Self { + self.window_builder = self.window_builder.window_classname(classname); + self + } + /// Sets whether or not the window has shadow. /// /// ## Platform-specific diff --git a/crates/tauri/src/window/mod.rs b/crates/tauri/src/window/mod.rs index f1292b37ab94..40de751171ff 100644 --- a/crates/tauri/src/window/mod.rs +++ b/crates/tauri/src/window/mod.rs @@ -645,6 +645,13 @@ impl<'a, R: Runtime, M: Manager> WindowBuilder<'a, R, M> { self } + /// Sets custom name for Windows' window class. **Windows only**. + #[must_use] + pub fn window_classname>(mut self, classname: S) -> Self { + self.window_builder = self.window_builder.window_classname(classname); + self + } + /// Sets whether or not the window has shadow. /// /// ## Platform-specific From cbc095ec5fe7de29b5c9265576d4e071ec159c1c Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 5 Nov 2024 21:00:48 +0200 Subject: [PATCH 17/51] feat: add `WebviewWindow/Webview::devtools` (#11451) * feat: add `WebviewWindow/Webview::devtools` closes #10849 * clippy * fix ToTokens * document default behavior * move builder usage --------- Co-authored-by: Lucas Nogueira --- .changes/config-devtools.md | 8 ++++++++ .changes/webview-builder-devtools.md | 8 ++++++++ crates/tauri-cli/config.schema.json | 7 +++++++ crates/tauri-runtime-wry/src/lib.rs | 2 +- crates/tauri-runtime/src/webview.rs | 20 ++++++++++++++++++- .../schemas/config.schema.json | 7 +++++++ crates/tauri-utils/src/config.rs | 15 +++++++++++++- crates/tauri/src/webview/mod.rs | 15 ++++++++++++++ crates/tauri/src/webview/webview_window.rs | 15 ++++++++++++++ packages/api/src/webview.ts | 14 +++++++++++++ packages/api/src/window.ts | 11 ++++++++++ 11 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 .changes/config-devtools.md create mode 100644 .changes/webview-builder-devtools.md diff --git a/.changes/config-devtools.md b/.changes/config-devtools.md new file mode 100644 index 000000000000..a75ecfbc1f14 --- /dev/null +++ b/.changes/config-devtools.md @@ -0,0 +1,8 @@ +--- +"tauri": "patch:feat" +"tauri-utils": "patch:feat" +"@tauri-apps/api": "patch:feat" +--- + +Add `app > windows > devtools` config option and when creating the webview from JS, to enable or disable devtools for a specific webview. + diff --git a/.changes/webview-builder-devtools.md b/.changes/webview-builder-devtools.md new file mode 100644 index 000000000000..5db1761729b0 --- /dev/null +++ b/.changes/webview-builder-devtools.md @@ -0,0 +1,8 @@ +--- +"tauri": "patch:feat" +"tauri-runtime": "patch:feat" +"tauri-runtime-wry": "patch:feat" +--- + +Add `WebviewWindowBuilder::devtools` and `WebviewBuilder::devtools` to enable or disable devtools for a specific webview. + diff --git a/crates/tauri-cli/config.schema.json b/crates/tauri-cli/config.schema.json index 9efeba50db44..d6742021f9d0 100644 --- a/crates/tauri-cli/config.schema.json +++ b/crates/tauri-cli/config.schema.json @@ -498,6 +498,13 @@ "description": "Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`.\n\n ## Note\n\n Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `://localhost` protocols used on macOS and Linux.\n\n ## Warning\n\n Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.", "default": false, "type": "boolean" + }, + "devtools": { + "description": "Enable web inspector which is usually called browser devtools. Enabled by default.\n\n This API works in **debug** builds, but requires `devtools` feature flag to enable it in **release** builds.\n\n ## Platform-specific\n\n - macOS: This will call private functions on **macOS**.\n - Android: Open `chrome://inspect/#devices` in Chrome to get the devtools window. Wry's `WebView` devtools API isn't supported on Android.\n - iOS: Open Safari > Develop > [Your Device Name] > [Your WebView] to get the devtools window.", + "type": [ + "boolean", + "null" + ] } }, "additionalProperties": false diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index 65e77ec95670..cde760ba7587 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -4274,7 +4274,7 @@ fn create_webview( #[cfg(any(debug_assertions, feature = "devtools"))] { - webview_builder = webview_builder.with_devtools(true); + webview_builder = webview_builder.with_devtools(webview_attributes.devtools.unwrap_or(true)); } #[cfg(target_os = "android")] diff --git a/crates/tauri-runtime/src/webview.rs b/crates/tauri-runtime/src/webview.rs index 149983808895..203d97b9422e 100644 --- a/crates/tauri-runtime/src/webview.rs +++ b/crates/tauri-runtime/src/webview.rs @@ -211,6 +211,7 @@ pub struct WebviewAttributes { pub zoom_hotkeys_enabled: bool, pub browser_extensions_enabled: bool, pub use_https_scheme: bool, + pub devtools: Option, } impl From<&WindowConfig> for WebviewAttributes { @@ -220,7 +221,8 @@ impl From<&WindowConfig> for WebviewAttributes { .focused(config.focus) .zoom_hotkeys_enabled(config.zoom_hotkeys_enabled) .use_https_scheme(config.use_https_scheme) - .browser_extensions_enabled(config.browser_extensions_enabled); + .browser_extensions_enabled(config.browser_extensions_enabled) + .devtools(config.devtools); #[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))] { builder = builder.transparent(config.transparent); @@ -267,6 +269,7 @@ impl WebviewAttributes { zoom_hotkeys_enabled: false, browser_extensions_enabled: false, use_https_scheme: false, + devtools: None, } } @@ -406,6 +409,21 @@ impl WebviewAttributes { self.use_https_scheme = enabled; self } + + /// Whether web inspector, which is usually called browser devtools, is enabled or not. Enabled by default. + /// + /// This API works in **debug** builds, but requires `devtools` feature flag to enable it in **release** builds. + /// + /// ## Platform-specific + /// + /// - macOS: This will call private functions on **macOS**. + /// - Android: Open `chrome://inspect/#devices` in Chrome to get the devtools window. Wry's `WebView` devtools API isn't supported on Android. + /// - iOS: Open Safari > Develop > [Your Device Name] > [Your WebView] to get the devtools window. + #[must_use] + pub fn devtools(mut self, enabled: Option) -> Self { + self.devtools = enabled; + self + } } /// IPC handler. diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json index 9efeba50db44..d6742021f9d0 100644 --- a/crates/tauri-schema-generator/schemas/config.schema.json +++ b/crates/tauri-schema-generator/schemas/config.schema.json @@ -498,6 +498,13 @@ "description": "Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`.\n\n ## Note\n\n Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `://localhost` protocols used on macOS and Linux.\n\n ## Warning\n\n Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.", "default": false, "type": "boolean" + }, + "devtools": { + "description": "Enable web inspector which is usually called browser devtools. Enabled by default.\n\n This API works in **debug** builds, but requires `devtools` feature flag to enable it in **release** builds.\n\n ## Platform-specific\n\n - macOS: This will call private functions on **macOS**.\n - Android: Open `chrome://inspect/#devices` in Chrome to get the devtools window. Wry's `WebView` devtools API isn't supported on Android.\n - iOS: Open Safari > Develop > [Your Device Name] > [Your WebView] to get the devtools window.", + "type": [ + "boolean", + "null" + ] } }, "additionalProperties": false diff --git a/crates/tauri-utils/src/config.rs b/crates/tauri-utils/src/config.rs index 1ff12495c022..390aaea90af2 100644 --- a/crates/tauri-utils/src/config.rs +++ b/crates/tauri-utils/src/config.rs @@ -1533,6 +1533,16 @@ pub struct WindowConfig { /// Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data. #[serde(default, alias = "use-https-scheme")] pub use_https_scheme: bool, + /// Enable web inspector which is usually called browser devtools. Enabled by default. + /// + /// This API works in **debug** builds, but requires `devtools` feature flag to enable it in **release** builds. + /// + /// ## Platform-specific + /// + /// - macOS: This will call private functions on **macOS**. + /// - Android: Open `chrome://inspect/#devices` in Chrome to get the devtools window. Wry's `WebView` devtools API isn't supported on Android. + /// - iOS: Open Safari > Develop > [Your Device Name] > [Your WebView] to get the devtools window. + pub devtools: Option, } impl Default for WindowConfig { @@ -1583,6 +1593,7 @@ impl Default for WindowConfig { zoom_hotkeys_enabled: false, browser_extensions_enabled: false, use_https_scheme: false, + devtools: None, } } } @@ -2556,6 +2567,7 @@ mod build { let zoom_hotkeys_enabled = self.zoom_hotkeys_enabled; let browser_extensions_enabled = self.browser_extensions_enabled; let use_https_scheme = self.use_https_scheme; + let devtools = opt_lit(self.devtools.as_ref()); literal_struct!( tokens, @@ -2604,7 +2616,8 @@ mod build { parent, zoom_hotkeys_enabled, browser_extensions_enabled, - use_https_scheme + use_https_scheme, + devtools ); } } diff --git a/crates/tauri/src/webview/mod.rs b/crates/tauri/src/webview/mod.rs index 199d5a8f90d8..bf3f1f3be4b5 100644 --- a/crates/tauri/src/webview/mod.rs +++ b/crates/tauri/src/webview/mod.rs @@ -815,6 +815,21 @@ fn main() { self.webview_attributes.use_https_scheme = enabled; self } + + /// Whether web inspector, which is usually called browser devtools, is enabled or not. Enabled by default. + /// + /// This API works in **debug** builds, but requires `devtools` feature flag to enable it in **release** builds. + /// + /// ## Platform-specific + /// + /// - macOS: This will call private functions on **macOS** + /// - Android: Open `chrome://inspect/#devices` in Chrome to get the devtools window. Wry's `WebView` devtools API isn't supported on Android. + /// - iOS: Open Safari > Develop > [Your Device Name] > [Your WebView] to get the devtools window. + #[must_use] + pub fn devtools(mut self, enabled: bool) -> Self { + self.webview_attributes.devtools.replace(enabled); + self + } } /// Webview. diff --git a/crates/tauri/src/webview/webview_window.rs b/crates/tauri/src/webview/webview_window.rs index 9909830eaa73..32799a665d8b 100644 --- a/crates/tauri/src/webview/webview_window.rs +++ b/crates/tauri/src/webview/webview_window.rs @@ -920,6 +920,21 @@ impl<'a, R: Runtime, M: Manager> WebviewWindowBuilder<'a, R, M> { self.webview_builder = self.webview_builder.use_https_scheme(enabled); self } + + /// Whether web inspector, which is usually called browser devtools, is enabled or not. Enabled by default. + /// + /// This API works in **debug** builds, but requires `devtools` feature flag to enable it in **release** builds. + /// + /// ## Platform-specific + /// + /// - macOS: This will call private functions on **macOS**. + /// - Android: Open `chrome://inspect/#devices` in Chrome to get the devtools window. Wry's `WebView` devtools API isn't supported on Android. + /// - iOS: Open Safari > Develop > [Your Device Name] > [Your WebView] to get the devtools window. + #[must_use] + pub fn devtools(mut self, enabled: bool) -> Self { + self.webview_builder = self.webview_builder.devtools(enabled); + self + } } /// A type that wraps a [`Window`] together with a [`Webview`]. diff --git a/packages/api/src/webview.ts b/packages/api/src/webview.ts index a495e135c2c2..d986de39a946 100644 --- a/packages/api/src/webview.ts +++ b/packages/api/src/webview.ts @@ -749,6 +749,20 @@ interface WebviewOptions { * @since 2.1.0 */ useHttpsScheme?: boolean + /** + * Whether web inspector, which is usually called browser devtools, is enabled or not. Enabled by default. + * + * This API works in **debug** builds, but requires `devtools` feature flag to enable it in **release** builds. + * + * #### Platform-specific + * + * - macOS: This will call private functions on **macOS**. + * - Android: Open `chrome://inspect/#devices` in Chrome to get the devtools window. Wry's `WebView` devtools API isn't supported on Android. + * - iOS: Open Safari > Develop > [Your Device Name] > [Your WebView] to get the devtools window. + * + * @since 2.1.0 + */ + devtools?: boolean } export { Webview, getCurrentWebview, getAllWebviews } diff --git a/packages/api/src/window.ts b/packages/api/src/window.ts index 923b5a3dc8c1..c242e3dd2160 100644 --- a/packages/api/src/window.ts +++ b/packages/api/src/window.ts @@ -2291,6 +2291,17 @@ interface WindowOptions { * @since 2.0.0 */ visibleOnAllWorkspaces?: boolean + /** + * Window effects. + * + * Requires the window to be transparent. + * + * #### Platform-specific: + * + * - **Windows**: If using decorations or shadows, you may want to try this workaround + * - **Linux**: Unsupported + */ + windowEffects?: Effects } function mapMonitor(m: Monitor | null): Monitor | null { From 5c4b830843ab085f8ff9db9e08d832223b027e4e Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 5 Nov 2024 23:30:17 +0200 Subject: [PATCH 18/51] feat(api): add `SERIALIZE_TO_IPC_FN` const and implement it for dpi types, add more constructors (#11191) --- .changes/api-dpi-toIPC.md | 10 + .changes/tauri-toIPC copy.md | 5 + crates/tauri/scripts/bundle.global.js | 2 +- crates/tauri/scripts/ipc.js | 45 +++ .../tauri/scripts/process-ipc-message-fn.js | 15 +- crates/tauri/src/window/mod.rs | 2 +- packages/api/eslint.config.js | 2 +- packages/api/package.json | 4 +- packages/api/src/core.ts | 57 +++- packages/api/src/dpi.ts | 309 ++++++++++++++++-- packages/api/src/menu/menu.ts | 14 +- packages/api/src/menu/submenu.ts | 11 +- packages/api/src/tray.ts | 13 +- packages/api/src/webview.ts | 50 +-- packages/api/src/window.ts | 128 ++------ 15 files changed, 462 insertions(+), 205 deletions(-) create mode 100644 .changes/api-dpi-toIPC.md create mode 100644 .changes/tauri-toIPC copy.md diff --git a/.changes/api-dpi-toIPC.md b/.changes/api-dpi-toIPC.md new file mode 100644 index 000000000000..c0258131e598 --- /dev/null +++ b/.changes/api-dpi-toIPC.md @@ -0,0 +1,10 @@ +--- +"@tauri-apps/api": "minor:feat" +"tauri": "minor:feat" +--- + +Improved support for `dpi` module types to allow these types to be used without manual conversions with `invoke`: + +- Added `SERIALIZE_TO_IPC_FN` const in `core` module which can be used to implement custom IPC serialization for types passed to `invoke`. +- Added `Size` and `Position` classes in `dpi` module. +- Implementd `SERIALIZE_TO_IPC_FN` method on `PhysicalSize`, `PhysicalPosition`, `LogicalSize` and `LogicalPosition` to convert it into a valid IPC-compatible value that can be deserialized correctly on the Rust side into its equivalent struct. diff --git a/.changes/tauri-toIPC copy.md b/.changes/tauri-toIPC copy.md new file mode 100644 index 000000000000..e4957e3ecf08 --- /dev/null +++ b/.changes/tauri-toIPC copy.md @@ -0,0 +1,5 @@ +--- +"tauri": "minor:feat" +--- + +Detect if `SERIALIZE_TO_IPC_FN`, const from the JS `core` module, is implemented on objects when serializing over IPC and use it. diff --git a/crates/tauri/scripts/bundle.global.js b/crates/tauri/scripts/bundle.global.js index 54f47c5c904b..316e09b65f99 100644 --- a/crates/tauri/scripts/bundle.global.js +++ b/crates/tauri/scripts/bundle.global.js @@ -1 +1 @@ -var __TAURI_IIFE__=function(e){"use strict";function n(e,n,t,i){if("a"===t&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof n?e!==n||!i:!n.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===t?i:"a"===t?i.call(e):i?i.value:n.get(e)}function t(e,n,t,i,r){if("m"===i)throw new TypeError("Private method is not writable");if("a"===i&&!r)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof n?e!==n||!r:!n.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===i?r.call(e,t):r?r.value=t:n.set(e,t),t}var i,r,a,s;function l(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}"function"==typeof SuppressedError&&SuppressedError;class o{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),r.set(this,0),a.set(this,{}),this.id=l((({message:e,id:s})=>{if(s===n(this,r,"f")){t(this,r,s+1,"f"),n(this,i,"f").call(this,e);const l=Object.keys(n(this,a,"f"));if(l.length>0){let e=s+1;for(const t of l.sort()){if(parseInt(t)!==e)break;{const r=n(this,a,"f")[t];delete n(this,a,"f")[t],n(this,i,"f").call(this,r),e+=1}}t(this,r,e,"f")}}else n(this,a,"f")[s.toString()]=e}))}set onmessage(e){t(this,i,e,"f")}get onmessage(){return n(this,i,"f")}toJSON(){return`__CHANNEL__:${this.id}`}}i=new WeakMap,r=new WeakMap,a=new WeakMap;class u{constructor(e,n,t){this.plugin=e,this.event=n,this.channelId=t}async unregister(){return c(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}}async function c(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}class d{get rid(){return n(this,s,"f")}constructor(e){s.set(this,void 0),t(this,s,e,"f")}async close(){return c("plugin:resources|close",{rid:this.rid})}}s=new WeakMap;var p=Object.freeze({__proto__:null,Channel:o,PluginListener:u,Resource:d,addPluginListener:async function(e,n,t){const i=new o;return i.onmessage=t,c(`plugin:${e}|registerListener`,{event:n,handler:i}).then((()=>new u(e,n,i.id)))},checkPermissions:async function(e){return c(`plugin:${e}|check_permissions`)},convertFileSrc:function(e,n="asset"){return window.__TAURI_INTERNALS__.convertFileSrc(e,n)},invoke:c,isTauri:function(){return"isTauri"in window&&!!window.isTauri},requestPermissions:async function(e){return c(`plugin:${e}|request_permissions`)},transformCallback:l});class h extends d{constructor(e){super(e)}static async new(e,n,t){return c("plugin:image|new",{rgba:w(e),width:n,height:t}).then((e=>new h(e)))}static async fromBytes(e){return c("plugin:image|from_bytes",{bytes:w(e)}).then((e=>new h(e)))}static async fromPath(e){return c("plugin:image|from_path",{path:e}).then((e=>new h(e)))}async rgba(){return c("plugin:image|rgba",{rid:this.rid}).then((e=>new Uint8Array(e)))}async size(){return c("plugin:image|size",{rid:this.rid})}}function w(e){return null==e?null:"string"==typeof e?e:e instanceof h?e.rid:e}var y=Object.freeze({__proto__:null,Image:h,transformImage:w});var g=Object.freeze({__proto__:null,defaultWindowIcon:async function(){return c("plugin:app|default_window_icon").then((e=>e?new h(e):null))},getName:async function(){return c("plugin:app|name")},getTauriVersion:async function(){return c("plugin:app|tauri_version")},getVersion:async function(){return c("plugin:app|version")},hide:async function(){return c("plugin:app|app_hide")},setTheme:async function(e){return c("plugin:app|set_app_theme",{theme:e})},show:async function(){return c("plugin:app|app_show")}});class _{constructor(e,n){this.type="Logical",this.width=e,this.height=n}toPhysical(e){return new b(this.width*e,this.height*e)}}class b{constructor(e,n){this.type="Physical",this.width=e,this.height=n}toLogical(e){return new _(this.width/e,this.height/e)}}class m{constructor(e,n){this.type="Logical",this.x=e,this.y=n}toPhysical(e){return new v(this.x*e,this.x*e)}}class v{constructor(e,n){this.type="Physical",this.x=e,this.y=n}toLogical(e){return new m(this.x/e,this.y/e)}}var f,k=Object.freeze({__proto__:null,LogicalPosition:m,LogicalSize:_,PhysicalPosition:v,PhysicalSize:b});async function A(e,n){await c("plugin:event|unlisten",{event:e,eventId:n})}async function E(e,n,t){var i;const r="string"==typeof(null==t?void 0:t.target)?{kind:"AnyLabel",label:t.target}:null!==(i=null==t?void 0:t.target)&&void 0!==i?i:{kind:"Any"};return c("plugin:event|listen",{event:e,target:r,handler:l(n)}).then((n=>async()=>A(e,n)))}async function D(e,n,t){return E(e,(t=>{A(e,t.id),n(t)}),t)}async function T(e,n){await c("plugin:event|emit",{event:e,payload:n})}async function I(e,n,t){const i="string"==typeof e?{kind:"AnyLabel",label:e}:e;await c("plugin:event|emit_to",{target:i,event:n,payload:t})}!function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG_ENTER="tauri://drag-enter",e.DRAG_OVER="tauri://drag-over",e.DRAG_DROP="tauri://drag-drop",e.DRAG_LEAVE="tauri://drag-leave"}(f||(f={}));var R,S,L,P,x,z=Object.freeze({__proto__:null,get TauriEvent(){return f},emit:T,emitTo:I,listen:E,once:D});function C(e){var n;if("items"in e)e.items=null===(n=e.items)||void 0===n?void 0:n.map((e=>"rid"in e?e:C(e)));else if("action"in e&&e.action){const n=new o;return n.onmessage=e.action,delete e.action,{...e,handler:n}}return e}async function W(e,n){const t=new o;if(n&&"object"==typeof n&&("action"in n&&n.action&&(t.onmessage=n.action,delete n.action),"items"in n&&n.items)){function i(e){var n;return"rid"in e?[e.rid,e.kind]:("item"in e&&"object"==typeof e.item&&(null===(n=e.item.About)||void 0===n?void 0:n.icon)&&(e.item.About.icon=w(e.item.About.icon)),"icon"in e&&e.icon&&(e.icon=w(e.icon)),"items"in e&&e.items&&(e.items=e.items.map(i)),C(e))}n.items=n.items.map(i)}return c("plugin:menu|new",{kind:e,options:n,handler:t})}class N extends d{get id(){return n(this,R,"f")}get kind(){return n(this,S,"f")}constructor(e,n,i){super(e),R.set(this,void 0),S.set(this,void 0),t(this,R,n,"f"),t(this,S,i,"f")}}R=new WeakMap,S=new WeakMap;class O extends N{constructor(e,n){super(e,n,"MenuItem")}static async new(e){return W("MenuItem",e).then((([e,n])=>new O(e,n)))}async text(){return c("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return c("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return c("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return c("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return c("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}}class F extends N{constructor(e,n){super(e,n,"Check")}static async new(e){return W("Check",e).then((([e,n])=>new F(e,n)))}async text(){return c("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return c("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return c("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return c("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return c("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async isChecked(){return c("plugin:menu|is_checked",{rid:this.rid})}async setChecked(e){return c("plugin:menu|set_checked",{rid:this.rid,checked:e})}}!function(e){e.Add="Add",e.Advanced="Advanced",e.Bluetooth="Bluetooth",e.Bookmarks="Bookmarks",e.Caution="Caution",e.ColorPanel="ColorPanel",e.ColumnView="ColumnView",e.Computer="Computer",e.EnterFullScreen="EnterFullScreen",e.Everyone="Everyone",e.ExitFullScreen="ExitFullScreen",e.FlowView="FlowView",e.Folder="Folder",e.FolderBurnable="FolderBurnable",e.FolderSmart="FolderSmart",e.FollowLinkFreestanding="FollowLinkFreestanding",e.FontPanel="FontPanel",e.GoLeft="GoLeft",e.GoRight="GoRight",e.Home="Home",e.IChatTheater="IChatTheater",e.IconView="IconView",e.Info="Info",e.InvalidDataFreestanding="InvalidDataFreestanding",e.LeftFacingTriangle="LeftFacingTriangle",e.ListView="ListView",e.LockLocked="LockLocked",e.LockUnlocked="LockUnlocked",e.MenuMixedState="MenuMixedState",e.MenuOnState="MenuOnState",e.MobileMe="MobileMe",e.MultipleDocuments="MultipleDocuments",e.Network="Network",e.Path="Path",e.PreferencesGeneral="PreferencesGeneral",e.QuickLook="QuickLook",e.RefreshFreestanding="RefreshFreestanding",e.Refresh="Refresh",e.Remove="Remove",e.RevealFreestanding="RevealFreestanding",e.RightFacingTriangle="RightFacingTriangle",e.Share="Share",e.Slideshow="Slideshow",e.SmartBadge="SmartBadge",e.StatusAvailable="StatusAvailable",e.StatusNone="StatusNone",e.StatusPartiallyAvailable="StatusPartiallyAvailable",e.StatusUnavailable="StatusUnavailable",e.StopProgressFreestanding="StopProgressFreestanding",e.StopProgress="StopProgress",e.TrashEmpty="TrashEmpty",e.TrashFull="TrashFull",e.User="User",e.UserAccounts="UserAccounts",e.UserGroup="UserGroup",e.UserGuest="UserGuest"}(L||(L={}));class M extends N{constructor(e,n){super(e,n,"Icon")}static async new(e){return W("Icon",e).then((([e,n])=>new M(e,n)))}async text(){return c("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return c("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return c("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return c("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return c("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async setIcon(e){return c("plugin:menu|set_icon",{rid:this.rid,icon:w(e)})}}class U extends N{constructor(e,n){super(e,n,"Predefined")}static async new(e){return W("Predefined",e).then((([e,n])=>new U(e,n)))}async text(){return c("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return c("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}}!function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"}(P||(P={}));class B{constructor(e){this._preventDefault=!1,this.event=e.event,this.id=e.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}function j(){return new H(window.__TAURI_INTERNALS__.metadata.currentWindow.label,{skip:!0})}async function V(){return c("plugin:window|get_all_windows").then((e=>e.map((e=>new H(e,{skip:!0})))))}!function(e){e.None="none",e.Normal="normal",e.Indeterminate="indeterminate",e.Paused="paused",e.Error="error"}(x||(x={}));const G=["tauri://created","tauri://error"];class H{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||c("plugin:window|create",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await V()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return j()}static async getAll(){return V()}static async getFocusedWindow(){for(const e of await V())if(await e.isFocused())return e;return null}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:E(e,n,{target:{kind:"Window",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:D(e,n,{target:{kind:"Window",label:this.label}})}async emit(e,n){if(!G.includes(e))return T(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!G.includes(n))return I(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!G.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async scaleFactor(){return c("plugin:window|scale_factor",{label:this.label})}async innerPosition(){return c("plugin:window|inner_position",{label:this.label}).then((({x:e,y:n})=>new v(e,n)))}async outerPosition(){return c("plugin:window|outer_position",{label:this.label}).then((({x:e,y:n})=>new v(e,n)))}async innerSize(){return c("plugin:window|inner_size",{label:this.label}).then((({width:e,height:n})=>new b(e,n)))}async outerSize(){return c("plugin:window|outer_size",{label:this.label}).then((({width:e,height:n})=>new b(e,n)))}async isFullscreen(){return c("plugin:window|is_fullscreen",{label:this.label})}async isMinimized(){return c("plugin:window|is_minimized",{label:this.label})}async isMaximized(){return c("plugin:window|is_maximized",{label:this.label})}async isFocused(){return c("plugin:window|is_focused",{label:this.label})}async isDecorated(){return c("plugin:window|is_decorated",{label:this.label})}async isResizable(){return c("plugin:window|is_resizable",{label:this.label})}async isMaximizable(){return c("plugin:window|is_maximizable",{label:this.label})}async isMinimizable(){return c("plugin:window|is_minimizable",{label:this.label})}async isClosable(){return c("plugin:window|is_closable",{label:this.label})}async isVisible(){return c("plugin:window|is_visible",{label:this.label})}async title(){return c("plugin:window|title",{label:this.label})}async theme(){return c("plugin:window|theme",{label:this.label})}async center(){return c("plugin:window|center",{label:this.label})}async requestUserAttention(e){let n=null;return e&&(n=e===P.Critical?{type:"Critical"}:{type:"Informational"}),c("plugin:window|request_user_attention",{label:this.label,value:n})}async setResizable(e){return c("plugin:window|set_resizable",{label:this.label,value:e})}async setEnabled(e){return c("plugin:window|set_enabled",{label:this.label,value:e})}async isEnabled(){return c("plugin:window|is_enabled",{label:this.label})}async setMaximizable(e){return c("plugin:window|set_maximizable",{label:this.label,value:e})}async setMinimizable(e){return c("plugin:window|set_minimizable",{label:this.label,value:e})}async setClosable(e){return c("plugin:window|set_closable",{label:this.label,value:e})}async setTitle(e){return c("plugin:window|set_title",{label:this.label,value:e})}async maximize(){return c("plugin:window|maximize",{label:this.label})}async unmaximize(){return c("plugin:window|unmaximize",{label:this.label})}async toggleMaximize(){return c("plugin:window|toggle_maximize",{label:this.label})}async minimize(){return c("plugin:window|minimize",{label:this.label})}async unminimize(){return c("plugin:window|unminimize",{label:this.label})}async show(){return c("plugin:window|show",{label:this.label})}async hide(){return c("plugin:window|hide",{label:this.label})}async close(){return c("plugin:window|close",{label:this.label})}async destroy(){return c("plugin:window|destroy",{label:this.label})}async setDecorations(e){return c("plugin:window|set_decorations",{label:this.label,value:e})}async setShadow(e){return c("plugin:window|set_shadow",{label:this.label,value:e})}async setEffects(e){return c("plugin:window|set_effects",{label:this.label,value:e})}async clearEffects(){return c("plugin:window|set_effects",{label:this.label,value:null})}async setAlwaysOnTop(e){return c("plugin:window|set_always_on_top",{label:this.label,value:e})}async setAlwaysOnBottom(e){return c("plugin:window|set_always_on_bottom",{label:this.label,value:e})}async setContentProtected(e){return c("plugin:window|set_content_protected",{label:this.label,value:e})}async setSize(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");const n={};return n[`${e.type}`]={width:e.width,height:e.height},c("plugin:window|set_size",{label:this.label,value:n})}async setMinSize(e){if(e&&"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");let n=null;return e&&(n={},n[`${e.type}`]={width:e.width,height:e.height}),c("plugin:window|set_min_size",{label:this.label,value:n})}async setMaxSize(e){if(e&&"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");let n=null;return e&&(n={},n[`${e.type}`]={width:e.width,height:e.height}),c("plugin:window|set_max_size",{label:this.label,value:n})}async setSizeConstraints(e){function n(e){return e?{Logical:e}:null}return c("plugin:window|set_size_constraints",{label:this.label,value:{minWidth:n(null==e?void 0:e.minWidth),minHeight:n(null==e?void 0:e.minHeight),maxWidth:n(null==e?void 0:e.maxWidth),maxHeight:n(null==e?void 0:e.maxHeight)}})}async setPosition(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");const n={};return n[`${e.type}`]={x:e.x,y:e.y},c("plugin:window|set_position",{label:this.label,value:n})}async setFullscreen(e){return c("plugin:window|set_fullscreen",{label:this.label,value:e})}async setFocus(){return c("plugin:window|set_focus",{label:this.label})}async setIcon(e){return c("plugin:window|set_icon",{label:this.label,value:w(e)})}async setSkipTaskbar(e){return c("plugin:window|set_skip_taskbar",{label:this.label,value:e})}async setCursorGrab(e){return c("plugin:window|set_cursor_grab",{label:this.label,value:e})}async setCursorVisible(e){return c("plugin:window|set_cursor_visible",{label:this.label,value:e})}async setCursorIcon(e){return c("plugin:window|set_cursor_icon",{label:this.label,value:e})}async setCursorPosition(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");const n={};return n[`${e.type}`]={x:e.x,y:e.y},c("plugin:window|set_cursor_position",{label:this.label,value:n})}async setIgnoreCursorEvents(e){return c("plugin:window|set_ignore_cursor_events",{label:this.label,value:e})}async startDragging(){return c("plugin:window|start_dragging",{label:this.label})}async startResizeDragging(e){return c("plugin:window|start_resize_dragging",{label:this.label,value:e})}async setProgressBar(e){return c("plugin:window|set_progress_bar",{label:this.label,value:e})}async setVisibleOnAllWorkspaces(e){return c("plugin:window|set_visible_on_all_workspaces",{label:this.label,value:e})}async setTitleBarStyle(e){return c("plugin:window|set_title_bar_style",{label:this.label,value:e})}async setTheme(e){return c("plugin:window|set_theme",{label:this.label,value:e})}async onResized(e){return this.listen(f.WINDOW_RESIZED,(n=>{n.payload=J(n.payload),e(n)}))}async onMoved(e){return this.listen(f.WINDOW_MOVED,(n=>{n.payload=Z(n.payload),e(n)}))}async onCloseRequested(e){return this.listen(f.WINDOW_CLOSE_REQUESTED,(async n=>{const t=new B(n);await e(t),t.isPreventDefault()||await this.destroy()}))}async onDragDropEvent(e){const n=await this.listen(f.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:Z(n.payload.position)}})})),t=await this.listen(f.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:Z(n.payload.position)}})})),i=await this.listen(f.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:Z(n.payload.position)}})})),r=await this.listen(f.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}async onFocusChanged(e){const n=await this.listen(f.WINDOW_FOCUS,(n=>{e({...n,payload:!0})})),t=await this.listen(f.WINDOW_BLUR,(n=>{e({...n,payload:!1})}));return()=>{n(),t()}}async onScaleChanged(e){return this.listen(f.WINDOW_SCALE_FACTOR_CHANGED,e)}async onThemeChanged(e){return this.listen(f.WINDOW_THEME_CHANGED,e)}}var $,q;function Q(e){return null===e?null:{name:e.name,scaleFactor:e.scaleFactor,position:Z(e.position),size:J(e.size)}}function Z(e){return new v(e.x,e.y)}function J(e){return new b(e.width,e.height)}!function(e){e.AppearanceBased="appearanceBased",e.Light="light",e.Dark="dark",e.MediumLight="mediumLight",e.UltraDark="ultraDark",e.Titlebar="titlebar",e.Selection="selection",e.Menu="menu",e.Popover="popover",e.Sidebar="sidebar",e.HeaderView="headerView",e.Sheet="sheet",e.WindowBackground="windowBackground",e.HudWindow="hudWindow",e.FullScreenUI="fullScreenUI",e.Tooltip="tooltip",e.ContentBackground="contentBackground",e.UnderWindowBackground="underWindowBackground",e.UnderPageBackground="underPageBackground",e.Mica="mica",e.Blur="blur",e.Acrylic="acrylic",e.Tabbed="tabbed",e.TabbedDark="tabbedDark",e.TabbedLight="tabbedLight"}($||($={})),function(e){e.FollowsWindowActiveState="followsWindowActiveState",e.Active="active",e.Inactive="inactive"}(q||(q={}));var K=Object.freeze({__proto__:null,CloseRequestedEvent:B,get Effect(){return $},get EffectState(){return q},LogicalPosition:m,LogicalSize:_,PhysicalPosition:v,PhysicalSize:b,get ProgressBarStatus(){return x},get UserAttentionType(){return P},Window:H,availableMonitors:async function(){return c("plugin:window|available_monitors").then((e=>e.map(Q)))},currentMonitor:async function(){return c("plugin:window|current_monitor").then(Q)},cursorPosition:async function(){return c("plugin:window|cursor_position").then(Z)},getAllWindows:V,getCurrentWindow:j,monitorFromPoint:async function(e,n){return c("plugin:window|monitor_from_point",{x:e,y:n}).then(Q)},primaryMonitor:async function(){return c("plugin:window|primary_monitor").then(Q)}});function Y([e,n,t]){switch(t){case"Submenu":return new X(e,n);case"Predefined":return new U(e,n);case"Check":return new F(e,n);case"Icon":return new M(e,n);default:return new O(e,n)}}class X extends N{constructor(e,n){super(e,n,"Submenu")}static async new(e){return W("Submenu",e).then((([e,n])=>new X(e,n)))}async text(){return c("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return c("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return c("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return c("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async append(e){return c("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return c("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return c("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return c("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return c("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(Y)}async items(){return c("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(Y)))}async get(e){return c("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?Y(e):null))}async popup(e,n){var t;let i=null;return e&&(i={},i[""+(e instanceof v?"Physical":"Logical")]={x:e.x,y:e.y}),c("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:i})}async setAsWindowsMenuForNSApp(){return c("plugin:menu|set_as_windows_menu_for_nsapp",{rid:this.rid})}async setAsHelpMenuForNSApp(){return c("plugin:menu|set_as_help_menu_for_nsapp",{rid:this.rid})}}function ee([e,n,t]){switch(t){case"Submenu":return new X(e,n);case"Predefined":return new U(e,n);case"Check":return new F(e,n);case"Icon":return new M(e,n);default:return new O(e,n)}}class ne extends N{constructor(e,n){super(e,n,"Menu")}static async new(e){return W("Menu",e).then((([e,n])=>new ne(e,n)))}static async default(){return c("plugin:menu|create_default").then((([e,n])=>new ne(e,n)))}async append(e){return c("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return c("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return c("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return c("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return c("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(ee)}async items(){return c("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(ee)))}async get(e){return c("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?ee(e):null))}async popup(e,n){var t;let i=null;return e&&(i={},i[""+(e instanceof v?"Physical":"Logical")]={x:e.x,y:e.y}),c("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:i})}async setAsAppMenu(){return c("plugin:menu|set_as_app_menu",{rid:this.rid}).then((e=>e?new ne(e[0],e[1]):null))}async setAsWindowMenu(e){var n;return c("plugin:menu|set_as_window_menu",{rid:this.rid,window:null!==(n=null==e?void 0:e.label)&&void 0!==n?n:null}).then((e=>e?new ne(e[0],e[1]):null))}}var te=Object.freeze({__proto__:null,CheckMenuItem:F,IconMenuItem:M,Menu:ne,MenuItem:O,get NativeIcon(){return L},PredefinedMenuItem:U,Submenu:X});function ie(){var e;window.__TAURI_INTERNALS__=null!==(e=window.__TAURI_INTERNALS__)&&void 0!==e?e:{}}var re,ae=Object.freeze({__proto__:null,clearMocks:function(){var e,n,t;"object"==typeof window.__TAURI_INTERNALS__&&((null===(e=window.__TAURI_INTERNALS__)||void 0===e?void 0:e.convertFileSrc)&&delete window.__TAURI_INTERNALS__.convertFileSrc,(null===(n=window.__TAURI_INTERNALS__)||void 0===n?void 0:n.invoke)&&delete window.__TAURI_INTERNALS__.invoke,(null===(t=window.__TAURI_INTERNALS__)||void 0===t?void 0:t.metadata)&&delete window.__TAURI_INTERNALS__.metadata)},mockConvertFileSrc:function(e){ie(),window.__TAURI_INTERNALS__.convertFileSrc=function(n,t="asset"){const i=encodeURIComponent(n);return"windows"===e?`http://${t}.localhost/${i}`:`${t}://localhost/${i}`}},mockIPC:function(e){ie(),window.__TAURI_INTERNALS__.transformCallback=function(e,n=!1){const t=window.crypto.getRandomValues(new Uint32Array(1))[0],i=`_${t}`;return Object.defineProperty(window,i,{value:t=>(n&&Reflect.deleteProperty(window,i),e&&e(t)),writable:!1,configurable:!0}),t},window.__TAURI_INTERNALS__.invoke=function(n,t,i){return e(n,t)}},mockWindows:function(e,...n){ie(),window.__TAURI_INTERNALS__.metadata={currentWindow:{label:e},currentWebview:{windowLabel:e,label:e}}}});!function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Document=6]="Document",e[e.Download=7]="Download",e[e.Picture=8]="Picture",e[e.Public=9]="Public",e[e.Video=10]="Video",e[e.Resource=11]="Resource",e[e.Temp=12]="Temp",e[e.AppConfig=13]="AppConfig",e[e.AppData=14]="AppData",e[e.AppLocalData=15]="AppLocalData",e[e.AppCache=16]="AppCache",e[e.AppLog=17]="AppLog",e[e.Desktop=18]="Desktop",e[e.Executable=19]="Executable",e[e.Font=20]="Font",e[e.Home=21]="Home",e[e.Runtime=22]="Runtime",e[e.Template=23]="Template"}(re||(re={}));var se=Object.freeze({__proto__:null,get BaseDirectory(){return re},appCacheDir:async function(){return c("plugin:path|resolve_directory",{directory:re.AppCache})},appConfigDir:async function(){return c("plugin:path|resolve_directory",{directory:re.AppConfig})},appDataDir:async function(){return c("plugin:path|resolve_directory",{directory:re.AppData})},appLocalDataDir:async function(){return c("plugin:path|resolve_directory",{directory:re.AppLocalData})},appLogDir:async function(){return c("plugin:path|resolve_directory",{directory:re.AppLog})},audioDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Audio})},basename:async function(e,n){return c("plugin:path|basename",{path:e,ext:n})},cacheDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Cache})},configDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Config})},dataDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Data})},delimiter:function(){return window.__TAURI_INTERNALS__.plugins.path.delimiter},desktopDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Desktop})},dirname:async function(e){return c("plugin:path|dirname",{path:e})},documentDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Document})},downloadDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Download})},executableDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Executable})},extname:async function(e){return c("plugin:path|extname",{path:e})},fontDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Font})},homeDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Home})},isAbsolute:async function(e){return c("plugin:path|isAbsolute",{path:e})},join:async function(...e){return c("plugin:path|join",{paths:e})},localDataDir:async function(){return c("plugin:path|resolve_directory",{directory:re.LocalData})},normalize:async function(e){return c("plugin:path|normalize",{path:e})},pictureDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Picture})},publicDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Public})},resolve:async function(...e){return c("plugin:path|resolve",{paths:e})},resolveResource:async function(e){return c("plugin:path|resolve_directory",{directory:re.Resource,path:e})},resourceDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Resource})},runtimeDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Runtime})},sep:function(){return window.__TAURI_INTERNALS__.plugins.path.sep},tempDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Temp})},templateDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Template})},videoDir:async function(){return c("plugin:path|resolve_directory",{directory:re.Video})}});class le extends d{constructor(e,n){super(e),this.id=n}static async getById(e){return c("plugin:tray|get_by_id",{id:e}).then((n=>n?new le(n,e):null))}static async removeById(e){return c("plugin:tray|remove_by_id",{id:e})}static async new(e){(null==e?void 0:e.menu)&&(e.menu=[e.menu.rid,e.menu.kind]),(null==e?void 0:e.icon)&&(e.icon=w(e.icon));const n=new o;if(null==e?void 0:e.action){const t=e.action;n.onmessage=e=>t(function(e){const n=e;return n.position=new v(e.position.x,e.position.y),n.rect.position=new v(e.rect.position.Physical.x,e.rect.position.Physical.y),n.rect.size=new b(e.rect.size.Physical.width,e.rect.size.Physical.height),n}(e)),delete e.action}return c("plugin:tray|new",{options:null!=e?e:{},handler:n}).then((([e,n])=>new le(e,n)))}async setIcon(e){let n=null;return e&&(n=w(e)),c("plugin:tray|set_icon",{rid:this.rid,icon:n})}async setMenu(e){return e&&(e=[e.rid,e.kind]),c("plugin:tray|set_menu",{rid:this.rid,menu:e})}async setTooltip(e){return c("plugin:tray|set_tooltip",{rid:this.rid,tooltip:e})}async setTitle(e){return c("plugin:tray|set_title",{rid:this.rid,title:e})}async setVisible(e){return c("plugin:tray|set_visible",{rid:this.rid,visible:e})}async setTempDirPath(e){return c("plugin:tray|set_temp_dir_path",{rid:this.rid,path:e})}async setIconAsTemplate(e){return c("plugin:tray|set_icon_as_template",{rid:this.rid,asTemplate:e})}async setMenuOnLeftClick(e){return c("plugin:tray|set_show_menu_on_left_click",{rid:this.rid,onLeft:e})}}var oe=Object.freeze({__proto__:null,TrayIcon:le});function ue(){return new pe(j(),window.__TAURI_INTERNALS__.metadata.currentWebview.label,{skip:!0})}async function ce(){return c("plugin:webview|get_all_webviews").then((e=>e.map((e=>new pe(new H(e.windowLabel,{skip:!0}),e.label,{skip:!0})))))}const de=["tauri://created","tauri://error"];class pe{constructor(e,n,t){this.window=e,this.label=n,this.listeners=Object.create(null),(null==t?void 0:t.skip)||c("plugin:webview|create_webview",{windowLabel:e.label,label:n,options:t}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await ce()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return ue()}static async getAll(){return ce()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:E(e,n,{target:{kind:"Webview",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:D(e,n,{target:{kind:"Webview",label:this.label}})}async emit(e,n){if(!de.includes(e))return T(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!de.includes(n))return I(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!de.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async position(){return c("plugin:webview|webview_position",{label:this.label}).then((({x:e,y:n})=>new v(e,n)))}async size(){return c("plugin:webview|webview_size",{label:this.label}).then((({width:e,height:n})=>new b(e,n)))}async close(){return c("plugin:webview|close",{label:this.label})}async setSize(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");const n={};return n[`${e.type}`]={width:e.width,height:e.height},c("plugin:webview|set_webview_size",{label:this.label,value:n})}async setPosition(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");const n={};return n[`${e.type}`]={x:e.x,y:e.y},c("plugin:webview|set_webview_position",{label:this.label,value:n})}async setFocus(){return c("plugin:webview|set_webview_focus",{label:this.label})}async hide(){return c("plugin:webview|webview_hide",{label:this.label})}async show(){return c("plugin:webview|webview_show",{label:this.label})}async setZoom(e){return c("plugin:webview|set_webview_zoom",{label:this.label,value:e})}async reparent(e){return c("plugin:webview|reparent",{label:this.label,window:"string"==typeof e?e:e.label})}async clearAllBrowsingData(){return c("plugin:webview|clear_all_browsing_data")}async onDragDropEvent(e){const n=await this.listen(f.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:he(n.payload.position)}})})),t=await this.listen(f.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:he(n.payload.position)}})})),i=await this.listen(f.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:he(n.payload.position)}})})),r=await this.listen(f.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}}function he(e){return new v(e.x,e.y)}var we,ye,ge=Object.freeze({__proto__:null,Webview:pe,getAllWebviews:ce,getCurrentWebview:ue});function _e(){const e=ue();return new me(e.label,{skip:!0})}async function be(){return c("plugin:window|get_all_windows").then((e=>e.map((e=>new me(e,{skip:!0})))))}class me{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||c("plugin:webview|create_webview_window",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;const t=null!==(n=(await be()).find((n=>n.label===e)))&&void 0!==n?n:null;return t?new me(t.label,{skip:!0}):null}static getCurrent(){return _e()}static async getAll(){return be()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:E(e,n,{target:{kind:"WebviewWindow",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:D(e,n,{target:{kind:"WebviewWindow",label:this.label}})}}we=me,ye=[H,pe],(Array.isArray(ye)?ye:[ye]).forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((n=>{var t;"object"==typeof we.prototype&&we.prototype&&n in we.prototype||Object.defineProperty(we.prototype,n,null!==(t=Object.getOwnPropertyDescriptor(e.prototype,n))&&void 0!==t?t:Object.create(null))}))}));var ve=Object.freeze({__proto__:null,WebviewWindow:me,getAllWebviewWindows:be,getCurrentWebviewWindow:_e});return e.app=g,e.core=p,e.dpi=k,e.event=z,e.image=y,e.menu=te,e.mocks=ae,e.path=se,e.tray=oe,e.webview=ge,e.webviewWindow=ve,e.window=K,e}({});window.__TAURI__=__TAURI_IIFE__; +var __TAURI_IIFE__=function(e){"use strict";function n(e,n,t,i){if("a"===t&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof n?e!==n||!i:!n.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===t?i:"a"===t?i.call(e):i?i.value:n.get(e)}function t(e,n,t,i,r){if("m"===i)throw new TypeError("Private method is not writable");if("a"===i&&!r)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof n?e!==n||!r:!n.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===i?r.call(e,t):r?r.value=t:n.set(e,t),t}var i,r,s,a;"function"==typeof SuppressedError&&SuppressedError;const l="__TAURI_TO_IPC_KEY__";function o(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}class u{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),r.set(this,0),s.set(this,{}),this.id=o((({message:e,id:a})=>{if(a===n(this,r,"f")){t(this,r,a+1,"f"),n(this,i,"f").call(this,e);const l=Object.keys(n(this,s,"f"));if(l.length>0){let e=a+1;for(const t of l.sort()){if(parseInt(t)!==e)break;{const r=n(this,s,"f")[t];delete n(this,s,"f")[t],n(this,i,"f").call(this,r),e+=1}}t(this,r,e,"f")}}else n(this,s,"f")[a.toString()]=e}))}set onmessage(e){t(this,i,e,"f")}get onmessage(){return n(this,i,"f")}[(i=new WeakMap,r=new WeakMap,s=new WeakMap,l)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[l]()}}class c{constructor(e,n,t){this.plugin=e,this.event=n,this.channelId=t}async unregister(){return d(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}}async function d(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}class h{get rid(){return n(this,a,"f")}constructor(e){a.set(this,void 0),t(this,a,e,"f")}async close(){return d("plugin:resources|close",{rid:this.rid})}}a=new WeakMap;var p=Object.freeze({__proto__:null,Channel:u,PluginListener:c,Resource:h,SERIALIZE_TO_IPC_FN:l,addPluginListener:async function(e,n,t){const i=new u;return i.onmessage=t,d(`plugin:${e}|registerListener`,{event:n,handler:i}).then((()=>new c(e,n,i.id)))},checkPermissions:async function(e){return d(`plugin:${e}|check_permissions`)},convertFileSrc:function(e,n="asset"){return window.__TAURI_INTERNALS__.convertFileSrc(e,n)},invoke:d,isTauri:function(){return"isTauri"in window&&!!window.isTauri},requestPermissions:async function(e){return d(`plugin:${e}|request_permissions`)},transformCallback:o});class w extends h{constructor(e){super(e)}static async new(e,n,t){return d("plugin:image|new",{rgba:y(e),width:n,height:t}).then((e=>new w(e)))}static async fromBytes(e){return d("plugin:image|from_bytes",{bytes:y(e)}).then((e=>new w(e)))}static async fromPath(e){return d("plugin:image|from_path",{path:e}).then((e=>new w(e)))}async rgba(){return d("plugin:image|rgba",{rid:this.rid}).then((e=>new Uint8Array(e)))}async size(){return d("plugin:image|size",{rid:this.rid})}}function y(e){return null==e?null:"string"==typeof e?e:e instanceof w?e.rid:e}var _=Object.freeze({__proto__:null,Image:w,transformImage:y});var g=Object.freeze({__proto__:null,defaultWindowIcon:async function(){return d("plugin:app|default_window_icon").then((e=>e?new w(e):null))},getName:async function(){return d("plugin:app|name")},getTauriVersion:async function(){return d("plugin:app|tauri_version")},getVersion:async function(){return d("plugin:app|version")},hide:async function(){return d("plugin:app|app_hide")},setTheme:async function(e){return d("plugin:app|set_app_theme",{theme:e})},show:async function(){return d("plugin:app|app_show")}});class b{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.width=e[0].Logical.width,this.height=e[0].Logical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toPhysical(e){return new m(this.width*e,this.height*e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class m{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.width=e[0].Physical.width,this.height=e[0].Physical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toLogical(e){return new b(this.width/e,this.height/e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class v{constructor(e){this.size=e}toLogical(e){return this.size instanceof b?this.size:this.size.toLogical(e)}toPhysical(e){return this.size instanceof m?this.size:this.size.toPhysical(e)}[l](){return{[`${this.size.type}`]:{width:this.size.width,height:this.size.height}}}toJSON(){return this[l]()}}class f{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.x=e[0].Logical.x,this.y=e[0].Logical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toPhysical(e){return new k(this.x*e,this.x*e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class k{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.x=e[0].Physical.x,this.y=e[0].Physical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toLogical(e){return new f(this.x/e,this.x/e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class A{constructor(e){this.position=e}toLogical(e){return this.position instanceof f?this.position:this.position.toLogical(e)}toPhysical(e){return this.position instanceof k?this.position:this.position.toPhysical(e)}[l](){return{[`${this.position.type}`]:{x:this.position.x,y:this.position.y}}}toJSON(){return this[l]()}}var E,T=Object.freeze({__proto__:null,LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,Position:A,Size:v});async function D(e,n){await d("plugin:event|unlisten",{event:e,eventId:n})}async function I(e,n,t){var i;const r="string"==typeof(null==t?void 0:t.target)?{kind:"AnyLabel",label:t.target}:null!==(i=null==t?void 0:t.target)&&void 0!==i?i:{kind:"Any"};return d("plugin:event|listen",{event:e,target:r,handler:o(n)}).then((n=>async()=>D(e,n)))}async function R(e,n,t){return I(e,(t=>{D(e,t.id),n(t)}),t)}async function S(e,n){await d("plugin:event|emit",{event:e,payload:n})}async function L(e,n,t){const i="string"==typeof e?{kind:"AnyLabel",label:e}:e;await d("plugin:event|emit_to",{target:i,event:n,payload:t})}!function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG_ENTER="tauri://drag-enter",e.DRAG_OVER="tauri://drag-over",e.DRAG_DROP="tauri://drag-drop",e.DRAG_LEAVE="tauri://drag-leave"}(E||(E={}));var x,N,C,P=Object.freeze({__proto__:null,get TauriEvent(){return E},emit:S,emitTo:L,listen:I,once:R});function z(e){var n;if("items"in e)e.items=null===(n=e.items)||void 0===n?void 0:n.map((e=>"rid"in e?e:z(e)));else if("action"in e&&e.action){const n=new u;return n.onmessage=e.action,delete e.action,{...e,handler:n}}return e}async function W(e,n){const t=new u;if(n&&"object"==typeof n&&("action"in n&&n.action&&(t.onmessage=n.action,delete n.action),"items"in n&&n.items)){function i(e){var n;return"rid"in e?[e.rid,e.kind]:("item"in e&&"object"==typeof e.item&&(null===(n=e.item.About)||void 0===n?void 0:n.icon)&&(e.item.About.icon=y(e.item.About.icon)),"icon"in e&&e.icon&&(e.icon=y(e.icon)),"items"in e&&e.items&&(e.items=e.items.map(i)),z(e))}n.items=n.items.map(i)}return d("plugin:menu|new",{kind:e,options:n,handler:t})}class O extends h{get id(){return n(this,x,"f")}get kind(){return n(this,N,"f")}constructor(e,n,i){super(e),x.set(this,void 0),N.set(this,void 0),t(this,x,n,"f"),t(this,N,i,"f")}}x=new WeakMap,N=new WeakMap;class F extends O{constructor(e,n){super(e,n,"MenuItem")}static async new(e){return W("MenuItem",e).then((([e,n])=>new F(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}}class M extends O{constructor(e,n){super(e,n,"Check")}static async new(e){return W("Check",e).then((([e,n])=>new M(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async isChecked(){return d("plugin:menu|is_checked",{rid:this.rid})}async setChecked(e){return d("plugin:menu|set_checked",{rid:this.rid,checked:e})}}!function(e){e.Add="Add",e.Advanced="Advanced",e.Bluetooth="Bluetooth",e.Bookmarks="Bookmarks",e.Caution="Caution",e.ColorPanel="ColorPanel",e.ColumnView="ColumnView",e.Computer="Computer",e.EnterFullScreen="EnterFullScreen",e.Everyone="Everyone",e.ExitFullScreen="ExitFullScreen",e.FlowView="FlowView",e.Folder="Folder",e.FolderBurnable="FolderBurnable",e.FolderSmart="FolderSmart",e.FollowLinkFreestanding="FollowLinkFreestanding",e.FontPanel="FontPanel",e.GoLeft="GoLeft",e.GoRight="GoRight",e.Home="Home",e.IChatTheater="IChatTheater",e.IconView="IconView",e.Info="Info",e.InvalidDataFreestanding="InvalidDataFreestanding",e.LeftFacingTriangle="LeftFacingTriangle",e.ListView="ListView",e.LockLocked="LockLocked",e.LockUnlocked="LockUnlocked",e.MenuMixedState="MenuMixedState",e.MenuOnState="MenuOnState",e.MobileMe="MobileMe",e.MultipleDocuments="MultipleDocuments",e.Network="Network",e.Path="Path",e.PreferencesGeneral="PreferencesGeneral",e.QuickLook="QuickLook",e.RefreshFreestanding="RefreshFreestanding",e.Refresh="Refresh",e.Remove="Remove",e.RevealFreestanding="RevealFreestanding",e.RightFacingTriangle="RightFacingTriangle",e.Share="Share",e.Slideshow="Slideshow",e.SmartBadge="SmartBadge",e.StatusAvailable="StatusAvailable",e.StatusNone="StatusNone",e.StatusPartiallyAvailable="StatusPartiallyAvailable",e.StatusUnavailable="StatusUnavailable",e.StopProgressFreestanding="StopProgressFreestanding",e.StopProgress="StopProgress",e.TrashEmpty="TrashEmpty",e.TrashFull="TrashFull",e.User="User",e.UserAccounts="UserAccounts",e.UserGroup="UserGroup",e.UserGuest="UserGuest"}(C||(C={}));class U extends O{constructor(e,n){super(e,n,"Icon")}static async new(e){return W("Icon",e).then((([e,n])=>new U(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async setIcon(e){return d("plugin:menu|set_icon",{rid:this.rid,icon:y(e)})}}class B extends O{constructor(e,n){super(e,n,"Predefined")}static async new(e){return W("Predefined",e).then((([e,n])=>new B(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}}function j([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class V extends O{constructor(e,n){super(e,n,"Submenu")}static async new(e){return W("Submenu",e).then((([e,n])=>new V(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(j)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(j)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?j(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsWindowsMenuForNSApp(){return d("plugin:menu|set_as_windows_menu_for_nsapp",{rid:this.rid})}async setAsHelpMenuForNSApp(){return d("plugin:menu|set_as_help_menu_for_nsapp",{rid:this.rid})}}function G([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class H extends O{constructor(e,n){super(e,n,"Menu")}static async new(e){return W("Menu",e).then((([e,n])=>new H(e,n)))}static async default(){return d("plugin:menu|create_default").then((([e,n])=>new H(e,n)))}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(G)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(G)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?G(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsAppMenu(){return d("plugin:menu|set_as_app_menu",{rid:this.rid}).then((e=>e?new H(e[0],e[1]):null))}async setAsWindowMenu(e){var n;return d("plugin:menu|set_as_window_menu",{rid:this.rid,window:null!==(n=null==e?void 0:e.label)&&void 0!==n?n:null}).then((e=>e?new H(e[0],e[1]):null))}}var $=Object.freeze({__proto__:null,CheckMenuItem:M,IconMenuItem:U,Menu:H,MenuItem:F,get NativeIcon(){return C},PredefinedMenuItem:B,Submenu:V});function q(){var e;window.__TAURI_INTERNALS__=null!==(e=window.__TAURI_INTERNALS__)&&void 0!==e?e:{}}var J,Q=Object.freeze({__proto__:null,clearMocks:function(){var e,n,t;"object"==typeof window.__TAURI_INTERNALS__&&((null===(e=window.__TAURI_INTERNALS__)||void 0===e?void 0:e.convertFileSrc)&&delete window.__TAURI_INTERNALS__.convertFileSrc,(null===(n=window.__TAURI_INTERNALS__)||void 0===n?void 0:n.invoke)&&delete window.__TAURI_INTERNALS__.invoke,(null===(t=window.__TAURI_INTERNALS__)||void 0===t?void 0:t.metadata)&&delete window.__TAURI_INTERNALS__.metadata)},mockConvertFileSrc:function(e){q(),window.__TAURI_INTERNALS__.convertFileSrc=function(n,t="asset"){const i=encodeURIComponent(n);return"windows"===e?`http://${t}.localhost/${i}`:`${t}://localhost/${i}`}},mockIPC:function(e){q(),window.__TAURI_INTERNALS__.transformCallback=function(e,n=!1){const t=window.crypto.getRandomValues(new Uint32Array(1))[0],i=`_${t}`;return Object.defineProperty(window,i,{value:t=>(n&&Reflect.deleteProperty(window,i),e&&e(t)),writable:!1,configurable:!0}),t},window.__TAURI_INTERNALS__.invoke=function(n,t,i){return e(n,t)}},mockWindows:function(e,...n){q(),window.__TAURI_INTERNALS__.metadata={currentWindow:{label:e},currentWebview:{windowLabel:e,label:e}}}});!function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Document=6]="Document",e[e.Download=7]="Download",e[e.Picture=8]="Picture",e[e.Public=9]="Public",e[e.Video=10]="Video",e[e.Resource=11]="Resource",e[e.Temp=12]="Temp",e[e.AppConfig=13]="AppConfig",e[e.AppData=14]="AppData",e[e.AppLocalData=15]="AppLocalData",e[e.AppCache=16]="AppCache",e[e.AppLog=17]="AppLog",e[e.Desktop=18]="Desktop",e[e.Executable=19]="Executable",e[e.Font=20]="Font",e[e.Home=21]="Home",e[e.Runtime=22]="Runtime",e[e.Template=23]="Template"}(J||(J={}));var Z=Object.freeze({__proto__:null,get BaseDirectory(){return J},appCacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppCache})},appConfigDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppConfig})},appDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppData})},appLocalDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLocalData})},appLogDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLog})},audioDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Audio})},basename:async function(e,n){return d("plugin:path|basename",{path:e,ext:n})},cacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Cache})},configDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Config})},dataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Data})},delimiter:function(){return window.__TAURI_INTERNALS__.plugins.path.delimiter},desktopDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Desktop})},dirname:async function(e){return d("plugin:path|dirname",{path:e})},documentDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Document})},downloadDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Download})},executableDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Executable})},extname:async function(e){return d("plugin:path|extname",{path:e})},fontDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Font})},homeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Home})},isAbsolute:async function(e){return d("plugin:path|isAbsolute",{path:e})},join:async function(...e){return d("plugin:path|join",{paths:e})},localDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.LocalData})},normalize:async function(e){return d("plugin:path|normalize",{path:e})},pictureDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Picture})},publicDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Public})},resolve:async function(...e){return d("plugin:path|resolve",{paths:e})},resolveResource:async function(e){return d("plugin:path|resolve_directory",{directory:J.Resource,path:e})},resourceDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Resource})},runtimeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Runtime})},sep:function(){return window.__TAURI_INTERNALS__.plugins.path.sep},tempDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Temp})},templateDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Template})},videoDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Video})}});class K extends h{constructor(e,n){super(e),this.id=n}static async getById(e){return d("plugin:tray|get_by_id",{id:e}).then((n=>n?new K(n,e):null))}static async removeById(e){return d("plugin:tray|remove_by_id",{id:e})}static async new(e){(null==e?void 0:e.menu)&&(e.menu=[e.menu.rid,e.menu.kind]),(null==e?void 0:e.icon)&&(e.icon=y(e.icon));const n=new u;if(null==e?void 0:e.action){const t=e.action;n.onmessage=e=>t(function(e){const n=e;return n.position=new k(e.position),n.rect.position=new k(e.rect.position),n.rect.size=new m(e.rect.size),n}(e)),delete e.action}return d("plugin:tray|new",{options:null!=e?e:{},handler:n}).then((([e,n])=>new K(e,n)))}async setIcon(e){let n=null;return e&&(n=y(e)),d("plugin:tray|set_icon",{rid:this.rid,icon:n})}async setMenu(e){return e&&(e=[e.rid,e.kind]),d("plugin:tray|set_menu",{rid:this.rid,menu:e})}async setTooltip(e){return d("plugin:tray|set_tooltip",{rid:this.rid,tooltip:e})}async setTitle(e){return d("plugin:tray|set_title",{rid:this.rid,title:e})}async setVisible(e){return d("plugin:tray|set_visible",{rid:this.rid,visible:e})}async setTempDirPath(e){return d("plugin:tray|set_temp_dir_path",{rid:this.rid,path:e})}async setIconAsTemplate(e){return d("plugin:tray|set_icon_as_template",{rid:this.rid,asTemplate:e})}async setMenuOnLeftClick(e){return d("plugin:tray|set_show_menu_on_left_click",{rid:this.rid,onLeft:e})}}var Y,X,ee=Object.freeze({__proto__:null,TrayIcon:K});!function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"}(Y||(Y={}));class ne{constructor(e){this._preventDefault=!1,this.event=e.event,this.id=e.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}function te(){return new se(window.__TAURI_INTERNALS__.metadata.currentWindow.label,{skip:!0})}async function ie(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new se(e,{skip:!0})))))}!function(e){e.None="none",e.Normal="normal",e.Indeterminate="indeterminate",e.Paused="paused",e.Error="error"}(X||(X={}));const re=["tauri://created","tauri://error"];class se{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:window|create",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await ie()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return te()}static async getAll(){return ie()}static async getFocusedWindow(){for(const e of await ie())if(await e.isFocused())return e;return null}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Window",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Window",label:this.label}})}async emit(e,n){if(!re.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!re.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!re.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async scaleFactor(){return d("plugin:window|scale_factor",{label:this.label})}async innerPosition(){return d("plugin:window|inner_position",{label:this.label}).then((e=>new k(e)))}async outerPosition(){return d("plugin:window|outer_position",{label:this.label}).then((e=>new k(e)))}async innerSize(){return d("plugin:window|inner_size",{label:this.label}).then((e=>new m(e)))}async outerSize(){return d("plugin:window|outer_size",{label:this.label}).then((e=>new m(e)))}async isFullscreen(){return d("plugin:window|is_fullscreen",{label:this.label})}async isMinimized(){return d("plugin:window|is_minimized",{label:this.label})}async isMaximized(){return d("plugin:window|is_maximized",{label:this.label})}async isFocused(){return d("plugin:window|is_focused",{label:this.label})}async isDecorated(){return d("plugin:window|is_decorated",{label:this.label})}async isResizable(){return d("plugin:window|is_resizable",{label:this.label})}async isMaximizable(){return d("plugin:window|is_maximizable",{label:this.label})}async isMinimizable(){return d("plugin:window|is_minimizable",{label:this.label})}async isClosable(){return d("plugin:window|is_closable",{label:this.label})}async isVisible(){return d("plugin:window|is_visible",{label:this.label})}async title(){return d("plugin:window|title",{label:this.label})}async theme(){return d("plugin:window|theme",{label:this.label})}async center(){return d("plugin:window|center",{label:this.label})}async requestUserAttention(e){let n=null;return e&&(n=e===Y.Critical?{type:"Critical"}:{type:"Informational"}),d("plugin:window|request_user_attention",{label:this.label,value:n})}async setResizable(e){return d("plugin:window|set_resizable",{label:this.label,value:e})}async setEnabled(e){return d("plugin:window|set_enabled",{label:this.label,value:e})}async isEnabled(){return d("plugin:window|is_enabled",{label:this.label})}async setMaximizable(e){return d("plugin:window|set_maximizable",{label:this.label,value:e})}async setMinimizable(e){return d("plugin:window|set_minimizable",{label:this.label,value:e})}async setClosable(e){return d("plugin:window|set_closable",{label:this.label,value:e})}async setTitle(e){return d("plugin:window|set_title",{label:this.label,value:e})}async maximize(){return d("plugin:window|maximize",{label:this.label})}async unmaximize(){return d("plugin:window|unmaximize",{label:this.label})}async toggleMaximize(){return d("plugin:window|toggle_maximize",{label:this.label})}async minimize(){return d("plugin:window|minimize",{label:this.label})}async unminimize(){return d("plugin:window|unminimize",{label:this.label})}async show(){return d("plugin:window|show",{label:this.label})}async hide(){return d("plugin:window|hide",{label:this.label})}async close(){return d("plugin:window|close",{label:this.label})}async destroy(){return d("plugin:window|destroy",{label:this.label})}async setDecorations(e){return d("plugin:window|set_decorations",{label:this.label,value:e})}async setShadow(e){return d("plugin:window|set_shadow",{label:this.label,value:e})}async setEffects(e){return d("plugin:window|set_effects",{label:this.label,value:e})}async clearEffects(){return d("plugin:window|set_effects",{label:this.label,value:null})}async setAlwaysOnTop(e){return d("plugin:window|set_always_on_top",{label:this.label,value:e})}async setAlwaysOnBottom(e){return d("plugin:window|set_always_on_bottom",{label:this.label,value:e})}async setContentProtected(e){return d("plugin:window|set_content_protected",{label:this.label,value:e})}async setSize(e){return d("plugin:window|set_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setMinSize(e){return d("plugin:window|set_min_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setMaxSize(e){return d("plugin:window|set_max_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setSizeConstraints(e){function n(e){return e?{Logical:e}:null}return d("plugin:window|set_size_constraints",{label:this.label,value:{minWidth:n(null==e?void 0:e.minWidth),minHeight:n(null==e?void 0:e.minHeight),maxWidth:n(null==e?void 0:e.maxWidth),maxHeight:n(null==e?void 0:e.maxHeight)}})}async setPosition(e){return d("plugin:window|set_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFullscreen(e){return d("plugin:window|set_fullscreen",{label:this.label,value:e})}async setFocus(){return d("plugin:window|set_focus",{label:this.label})}async setIcon(e){return d("plugin:window|set_icon",{label:this.label,value:y(e)})}async setSkipTaskbar(e){return d("plugin:window|set_skip_taskbar",{label:this.label,value:e})}async setCursorGrab(e){return d("plugin:window|set_cursor_grab",{label:this.label,value:e})}async setCursorVisible(e){return d("plugin:window|set_cursor_visible",{label:this.label,value:e})}async setCursorIcon(e){return d("plugin:window|set_cursor_icon",{label:this.label,value:e})}async setCursorPosition(e){return d("plugin:window|set_cursor_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setIgnoreCursorEvents(e){return d("plugin:window|set_ignore_cursor_events",{label:this.label,value:e})}async startDragging(){return d("plugin:window|start_dragging",{label:this.label})}async startResizeDragging(e){return d("plugin:window|start_resize_dragging",{label:this.label,value:e})}async setProgressBar(e){return d("plugin:window|set_progress_bar",{label:this.label,value:e})}async setVisibleOnAllWorkspaces(e){return d("plugin:window|set_visible_on_all_workspaces",{label:this.label,value:e})}async setTitleBarStyle(e){return d("plugin:window|set_title_bar_style",{label:this.label,value:e})}async setTheme(e){return d("plugin:window|set_theme",{label:this.label,value:e})}async onResized(e){return this.listen(E.WINDOW_RESIZED,(n=>{n.payload=new m(n.payload),e(n)}))}async onMoved(e){return this.listen(E.WINDOW_MOVED,(n=>{n.payload=new k(n.payload),e(n)}))}async onCloseRequested(e){return this.listen(E.WINDOW_CLOSE_REQUESTED,(async n=>{const t=new ne(n);await e(t),t.isPreventDefault()||await this.destroy()}))}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}async onFocusChanged(e){const n=await this.listen(E.WINDOW_FOCUS,(n=>{e({...n,payload:!0})})),t=await this.listen(E.WINDOW_BLUR,(n=>{e({...n,payload:!1})}));return()=>{n(),t()}}async onScaleChanged(e){return this.listen(E.WINDOW_SCALE_FACTOR_CHANGED,e)}async onThemeChanged(e){return this.listen(E.WINDOW_THEME_CHANGED,e)}}var ae,le;function oe(e){return null===e?null:{name:e.name,scaleFactor:e.scaleFactor,position:new k(e.position),size:new m(e.size)}}!function(e){e.AppearanceBased="appearanceBased",e.Light="light",e.Dark="dark",e.MediumLight="mediumLight",e.UltraDark="ultraDark",e.Titlebar="titlebar",e.Selection="selection",e.Menu="menu",e.Popover="popover",e.Sidebar="sidebar",e.HeaderView="headerView",e.Sheet="sheet",e.WindowBackground="windowBackground",e.HudWindow="hudWindow",e.FullScreenUI="fullScreenUI",e.Tooltip="tooltip",e.ContentBackground="contentBackground",e.UnderWindowBackground="underWindowBackground",e.UnderPageBackground="underPageBackground",e.Mica="mica",e.Blur="blur",e.Acrylic="acrylic",e.Tabbed="tabbed",e.TabbedDark="tabbedDark",e.TabbedLight="tabbedLight"}(ae||(ae={})),function(e){e.FollowsWindowActiveState="followsWindowActiveState",e.Active="active",e.Inactive="inactive"}(le||(le={}));var ue=Object.freeze({__proto__:null,CloseRequestedEvent:ne,get Effect(){return ae},get EffectState(){return le},LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,get ProgressBarStatus(){return X},get UserAttentionType(){return Y},Window:se,availableMonitors:async function(){return d("plugin:window|available_monitors").then((e=>e.map(oe)))},currentMonitor:async function(){return d("plugin:window|current_monitor").then(oe)},cursorPosition:async function(){return d("plugin:window|cursor_position").then((e=>new k(e)))},getAllWindows:ie,getCurrentWindow:te,monitorFromPoint:async function(e,n){return d("plugin:window|monitor_from_point",{x:e,y:n}).then(oe)},primaryMonitor:async function(){return d("plugin:window|primary_monitor").then(oe)}});function ce(){return new pe(te(),window.__TAURI_INTERNALS__.metadata.currentWebview.label,{skip:!0})}async function de(){return d("plugin:webview|get_all_webviews").then((e=>e.map((e=>new pe(new se(e.windowLabel,{skip:!0}),e.label,{skip:!0})))))}const he=["tauri://created","tauri://error"];class pe{constructor(e,n,t){this.window=e,this.label=n,this.listeners=Object.create(null),(null==t?void 0:t.skip)||d("plugin:webview|create_webview",{windowLabel:e.label,label:n,options:t}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await de()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return ce()}static async getAll(){return de()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Webview",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Webview",label:this.label}})}async emit(e,n){if(!he.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!he.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!he.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async position(){return d("plugin:webview|webview_position",{label:this.label}).then((e=>new k(e)))}async size(){return d("plugin:webview|webview_size",{label:this.label}).then((e=>new m(e)))}async close(){return d("plugin:webview|close",{label:this.label})}async setSize(e){return d("plugin:webview|set_webview_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setPosition(e){return d("plugin:webview|set_webview_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFocus(){return d("plugin:webview|set_webview_focus",{label:this.label})}async hide(){return d("plugin:webview|webview_hide",{label:this.label})}async show(){return d("plugin:webview|webview_show",{label:this.label})}async setZoom(e){return d("plugin:webview|set_webview_zoom",{label:this.label,value:e})}async reparent(e){return d("plugin:webview|reparent",{label:this.label,window:"string"==typeof e?e:e.label})}async clearAllBrowsingData(){return d("plugin:webview|clear_all_browsing_data")}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}}var we,ye,_e=Object.freeze({__proto__:null,Webview:pe,getAllWebviews:de,getCurrentWebview:ce});function ge(){const e=ce();return new me(e.label,{skip:!0})}async function be(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new me(e,{skip:!0})))))}class me{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:webview|create_webview_window",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;const t=null!==(n=(await be()).find((n=>n.label===e)))&&void 0!==n?n:null;return t?new me(t.label,{skip:!0}):null}static getCurrent(){return ge()}static async getAll(){return be()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"WebviewWindow",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"WebviewWindow",label:this.label}})}}we=me,ye=[se,pe],(Array.isArray(ye)?ye:[ye]).forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((n=>{var t;"object"==typeof we.prototype&&we.prototype&&n in we.prototype||Object.defineProperty(we.prototype,n,null!==(t=Object.getOwnPropertyDescriptor(e.prototype,n))&&void 0!==t?t:Object.create(null))}))}));var ve=Object.freeze({__proto__:null,WebviewWindow:me,getAllWebviewWindows:be,getCurrentWebviewWindow:ge});return e.app=g,e.core=p,e.dpi=T,e.event=P,e.image=_,e.menu=$,e.mocks=Q,e.path=Z,e.tray=ee,e.webview=_e,e.webviewWindow=ve,e.window=ue,e}({});window.__TAURI__=__TAURI_IIFE__; diff --git a/crates/tauri/scripts/ipc.js b/crates/tauri/scripts/ipc.js index 28cf331509e6..84013187d55e 100644 --- a/crates/tauri/scripts/ipc.js +++ b/crates/tauri/scripts/ipc.js @@ -88,6 +88,51 @@ return } + // `postMessage` uses `structuredClone` to serialize the data before sending it + // unlike `JSON.stringify`, we can't extend a type with a method similar to `toJSON` + // so that `structuredClone` would use, so until https://github.com/whatwg/html/issues/7428 + // we manually call `toIPC` + function serializeIpcPayload(data) { + // if this value changes, make sure to update it in: + // 1. process-ipc-message-fn.js + // 2. core.ts + const SERIALIZE_TO_IPC_FN = '__TAURI_TO_IPC_KEY__' + + if ( + typeof data === 'object' && + data !== null && + 'constructor' in data && + data.constructor === Array + ) { + return data.map((v) => serializeIpcPayload(v)) + } + + if ( + typeof data === 'object' && + data !== null && + SERIALIZE_TO_IPC_FN in data + ) { + return data[SERIALIZE_TO_IPC_FN]() + } + + if ( + typeof data === 'object' && + data !== null && + 'constructor' in data && + data.constructor === Object + ) { + const acc = {} + Object.entries(data).forEach(([k, v]) => { + acc[k] = serializeIpcPayload(v) + }) + return acc + } + + return data + } + + data.payload = serializeIpcPayload(data.payload) + isolation.frame.contentWindow.postMessage( data, '*' /* todo: set this to the secure origin */ diff --git a/crates/tauri/scripts/process-ipc-message-fn.js b/crates/tauri/scripts/process-ipc-message-fn.js index 42af59df9c1f..2a0ad768b8d9 100644 --- a/crates/tauri/scripts/process-ipc-message-fn.js +++ b/crates/tauri/scripts/process-ipc-message-fn.js @@ -16,21 +16,26 @@ } } else { const data = JSON.stringify(message, (_k, val) => { + // if this value changes, make sure to update it in: + // 1. ipc.js + // 2. core.ts + const SERIALIZE_TO_IPC_FN = '__TAURI_TO_IPC_KEY__' + if (val instanceof Map) { - let o = {} - val.forEach((v, k) => (o[k] = v)) - return o + return Object.fromEntries(val.entries()) } else if (val instanceof Uint8Array) { return Array.from(val) } else if (val instanceof ArrayBuffer) { return Array.from(new Uint8Array(val)) - } else if ( + } else if (typeof val === "object" && val !== null && SERIALIZE_TO_IPC_FN in val) { + return val[SERIALIZE_TO_IPC_FN]() + } else if ( val instanceof Object && '__TAURI_CHANNEL_MARKER__' in val && typeof val.id === 'number' ) { return `__CHANNEL__:${val.id}` - } else { + } else { return val } }) diff --git a/crates/tauri/src/window/mod.rs b/crates/tauri/src/window/mod.rs index 40de751171ff..7f0ffe3cf728 100644 --- a/crates/tauri/src/window/mod.rs +++ b/crates/tauri/src/window/mod.rs @@ -2052,7 +2052,7 @@ tauri::Builder::default() docsrs, doc(cfg(any(target_os = "macos", target_os = "linux", windows))) )] -#[derive(serde::Deserialize)] +#[derive(serde::Deserialize, Debug)] pub struct ProgressBarState { /// The progress bar status. pub status: Option, diff --git a/packages/api/eslint.config.js b/packages/api/eslint.config.js index 71aecc1136eb..803c0178107a 100644 --- a/packages/api/eslint.config.js +++ b/packages/api/eslint.config.js @@ -8,7 +8,7 @@ import prettierConfig from 'eslint-config-prettier' import securityPlugin from 'eslint-plugin-security' import tseslint from 'typescript-eslint' -/** @type {import('eslint').Linter.FlatConfig[]} */ +/** @type {import('eslint').Linter.Config} */ export default [ eslint.configs.recommended, prettierConfig, diff --git a/packages/api/package.json b/packages/api/package.json index 6cc4702fd46f..6187b784ede7 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -40,8 +40,8 @@ "npm-pack": "pnpm build && cd ./dist && npm pack", "npm-publish": "pnpm build && cd ./dist && pnpm publish --access public --loglevel silly --no-git-checks", "ts:check": "tsc --noEmit", - "eslint:check": "eslint src/**.ts", - "eslint:fix": "eslint src/**.ts --fix" + "eslint:check": "eslint src/**/*.ts", + "eslint:fix": "eslint src/**/*.ts --fix" }, "devDependencies": { "@eslint/js": "^9.4.0", diff --git a/packages/api/src/core.ts b/packages/api/src/core.ts index 5986e68abb72..995e5c07b21a 100644 --- a/packages/api/src/core.ts +++ b/packages/api/src/core.ts @@ -9,6 +9,56 @@ * @module */ +/** + * A key to be used to implement a special function + * on your types that define how your type should be serialized + * when passing across the IPC. + * @example + * Given a type in Rust that looks like this + * ```rs + * #[derive(serde::Serialize, serde::Deserialize) + * enum UserId { + * String(String), + * Number(u32), + * } + * ``` + * `UserId::String("id")` would be serialized into `{ String: "id" }` + * and so we need to pass the same structure back to Rust + * ```ts + * import { SERIALIZE_TO_IPC_FN } from "@tauri-apps/api/core" + * + * class UserIdString { + * id + * constructor(id) { + * this.id = id + * } + * + * [SERIALIZE_TO_IPC_FN]() { + * return { String: this.id } + * } + * } + * + * class UserIdNumber { + * id + * constructor(id) { + * this.id = id + * } + * + * [SERIALIZE_TO_IPC_FN]() { + * return { Number: this.id } + * } + * } + * + * + * type UserId = UserIdString | UserIdNumber + * ``` + * + */ +// if this value changes, make sure to update it in: +// 1. ipc.js +// 2. process-ipc-message-fn.js +export const SERIALIZE_TO_IPC_FN = '__TAURI_TO_IPC_KEY__' + /** * Transforms a callback function to a string identifier that can be passed to the backend. * The backend uses the identifier to `eval()` the callback. @@ -80,9 +130,14 @@ class Channel { return this.#onmessage } - toJSON(): string { + [SERIALIZE_TO_IPC_FN]() { return `__CHANNEL__:${this.id}` } + + toJSON(): string { + // eslint-disable-next-line security/detect-object-injection + return this[SERIALIZE_TO_IPC_FN]() + } } class PluginListener { diff --git a/packages/api/src/dpi.ts b/packages/api/src/dpi.ts index e82d7b6add41..8ea676d7dc6a 100644 --- a/packages/api/src/dpi.ts +++ b/packages/api/src/dpi.ts @@ -2,26 +2,48 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT +import { SERIALIZE_TO_IPC_FN } from './core' + /** * A size represented in logical pixels. * * @since 2.0.0 */ class LogicalSize { - type = 'Logical' + readonly type = 'Logical' width: number height: number - constructor(width: number, height: number) { - this.width = width - this.height = height + constructor(width: number, height: number) + constructor(object: { Logical: { width: number; height: number } }) + constructor(object: { width: number; height: number }) + constructor( + ...args: + | [number, number] + | [{ width: number; height: number }] + | [{ Logical: { width: number; height: number } }] + ) { + if (args.length === 1) { + if ('Logical' in args[0]) { + this.width = args[0].Logical.width + this.height = args[0].Logical.height + } else { + this.width = args[0].width + this.height = args[0].height + } + } else { + this.width = args[0] + this.height = args[1] + } } /** * Converts the logical size to a physical one. * @example * ```typescript + * import { LogicalSize } from '@tauri-apps/api/dpi'; * import { getCurrentWindow } from '@tauri-apps/api/window'; + * * const appWindow = getCurrentWindow(); * const factor = await appWindow.scaleFactor(); * const size = new LogicalSize(400, 500); @@ -33,6 +55,18 @@ class LogicalSize { toPhysical(scaleFactor: number): PhysicalSize { return new PhysicalSize(this.width * scaleFactor, this.height * scaleFactor) } + + [SERIALIZE_TO_IPC_FN]() { + return { + width: this.width, + height: this.height + } + } + + toJSON() { + // eslint-disable-next-line security/detect-object-injection + return this[SERIALIZE_TO_IPC_FN]() + } } /** @@ -41,13 +75,31 @@ class LogicalSize { * @since 2.0.0 */ class PhysicalSize { - type = 'Physical' + readonly type = 'Physical' width: number height: number - constructor(width: number, height: number) { - this.width = width - this.height = height + constructor(width: number, height: number) + constructor(object: { Physical: { width: number; height: number } }) + constructor(object: { width: number; height: number }) + constructor( + ...args: + | [number, number] + | [{ width: number; height: number }] + | [{ Physical: { width: number; height: number } }] + ) { + if (args.length === 1) { + if ('Physical' in args[0]) { + this.width = args[0].Physical.width + this.height = args[0].Physical.height + } else { + this.width = args[0].width + this.height = args[0].height + } + } else { + this.width = args[0] + this.height = args[1] + } } /** @@ -57,13 +109,90 @@ class PhysicalSize { * import { getCurrentWindow } from '@tauri-apps/api/window'; * const appWindow = getCurrentWindow(); * const factor = await appWindow.scaleFactor(); - * const size = await appWindow.innerSize(); + * const size = await appWindow.innerSize(); // PhysicalSize * const logical = size.toLogical(factor); * ``` */ toLogical(scaleFactor: number): LogicalSize { return new LogicalSize(this.width / scaleFactor, this.height / scaleFactor) } + + [SERIALIZE_TO_IPC_FN]() { + return { + width: this.width, + height: this.height + } + } + + toJSON() { + // eslint-disable-next-line security/detect-object-injection + return this[SERIALIZE_TO_IPC_FN]() + } +} + +/** + * A size represented either in physical or in logical pixels. + * + * This type is basically a union type of {@linkcode LogicalSize} and {@linkcode PhysicalSize} + * but comes in handy when using `tauri::Size` in Rust as an argument to a command, as this class + * automatically serializes into a valid format so it can be deserialized correctly into `tauri::Size` + * + * So instead of + * ```typescript + * import { invoke } from '@tauri-apps/api/core'; + * import { LogicalSize, PhysicalSize } from '@tauri-apps/api/dpi'; + * + * const size: LogicalSize | PhysicalSize = someFunction(); // where someFunction returns either LogicalSize or PhysicalSize + * const validSize = size instanceof LogicalSize + * ? { Logical: { width: size.width, height: size.height } } + * : { Physical: { width: size.width, height: size.height } } + * await invoke("do_something_with_size", { size: validSize }); + * ``` + * + * You can just use {@linkcode Size} + * ```typescript + * import { invoke } from '@tauri-apps/api/core'; + * import { LogicalSize, PhysicalSize, Size } from '@tauri-apps/api/dpi'; + * + * const size: LogicalSize | PhysicalSize = someFunction(); // where someFunction returns either LogicalSize or PhysicalSize + * const validSize = new Size(size); + * await invoke("do_something_with_size", { size: validSize }); + * ``` + * + * @since 2.1.0 + */ +class Size { + size: LogicalSize | PhysicalSize + + constructor(size: LogicalSize | PhysicalSize) { + this.size = size + } + + toLogical(scaleFactor: number): LogicalSize { + return this.size instanceof LogicalSize + ? this.size + : this.size.toLogical(scaleFactor) + } + + toPhysical(scaleFactor: number): PhysicalSize { + return this.size instanceof PhysicalSize + ? this.size + : this.size.toPhysical(scaleFactor) + } + + [SERIALIZE_TO_IPC_FN]() { + return { + [`${this.size.type}`]: { + width: this.size.width, + height: this.size.height + } + } + } + + toJSON() { + // eslint-disable-next-line security/detect-object-injection + return this[SERIALIZE_TO_IPC_FN]() + } } /** @@ -72,20 +201,40 @@ class PhysicalSize { * @since 2.0.0 */ class LogicalPosition { - type = 'Logical' + readonly type = 'Logical' x: number y: number - constructor(x: number, y: number) { - this.x = x - this.y = y + constructor(x: number, y: number) + constructor(object: { Logical: { x: number; y: number } }) + constructor(object: { x: number; y: number }) + constructor( + ...args: + | [number, number] + | [{ x: number; y: number }] + | [{ Logical: { x: number; y: number } }] + ) { + if (args.length === 1) { + if ('Logical' in args[0]) { + this.x = args[0].Logical.x + this.y = args[0].Logical.y + } else { + this.x = args[0].x + this.y = args[0].y + } + } else { + this.x = args[0] + this.y = args[1] + } } /** * Converts the logical position to a physical one. * @example * ```typescript + * import { LogicalPosition } from '@tauri-apps/api/dpi'; * import { getCurrentWindow } from '@tauri-apps/api/window'; + * * const appWindow = getCurrentWindow(); * const factor = await appWindow.scaleFactor(); * const position = new LogicalPosition(400, 500); @@ -97,6 +246,18 @@ class LogicalPosition { toPhysical(scaleFactor: number): PhysicalPosition { return new PhysicalPosition(this.x * scaleFactor, this.x * scaleFactor) } + + [SERIALIZE_TO_IPC_FN]() { + return { + x: this.x, + y: this.y + } + } + + toJSON() { + // eslint-disable-next-line security/detect-object-injection + return this[SERIALIZE_TO_IPC_FN]() + } } /** @@ -105,29 +266,135 @@ class LogicalPosition { * @since 2.0.0 */ class PhysicalPosition { - type = 'Physical' + readonly type = 'Physical' x: number y: number - constructor(x: number, y: number) { - this.x = x - this.y = y + constructor(x: number, y: number) + constructor(object: { Physical: { x: number; y: number } }) + constructor(object: { x: number; y: number }) + constructor( + ...args: + | [number, number] + | [{ x: number; y: number }] + | [{ Physical: { x: number; y: number } }] + ) { + if (args.length === 1) { + if ('Physical' in args[0]) { + this.x = args[0].Physical.x + this.y = args[0].Physical.y + } else { + this.x = args[0].x + this.y = args[0].y + } + } else { + this.x = args[0] + this.y = args[1] + } } /** * Converts the physical position to a logical one. * @example * ```typescript + * import { PhysicalPosition } from '@tauri-apps/api/dpi'; * import { getCurrentWindow } from '@tauri-apps/api/window'; + * * const appWindow = getCurrentWindow(); * const factor = await appWindow.scaleFactor(); - * const position = await appWindow.innerPosition(); - * const logical = position.toLogical(factor); + * const position = new PhysicalPosition(400, 500); + * const physical = position.toLogical(factor); * ``` + * + * @since 2.0.0 */ toLogical(scaleFactor: number): LogicalPosition { - return new LogicalPosition(this.x / scaleFactor, this.y / scaleFactor) + return new LogicalPosition(this.x / scaleFactor, this.x / scaleFactor) + } + + [SERIALIZE_TO_IPC_FN]() { + return { + x: this.x, + y: this.y + } + } + + toJSON() { + // eslint-disable-next-line security/detect-object-injection + return this[SERIALIZE_TO_IPC_FN]() } } -export { LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize } +/** + * A position represented either in physical or in logical pixels. + * + * This type is basically a union type of {@linkcode LogicalSize} and {@linkcode PhysicalSize} + * but comes in handy when using `tauri::Position` in Rust as an argument to a command, as this class + * automatically serializes into a valid format so it can be deserialized correctly into `tauri::Position` + * + * So instead of + * ```typescript + * import { invoke } from '@tauri-apps/api/core'; + * import { LogicalPosition, PhysicalPosition } from '@tauri-apps/api/dpi'; + * + * const position: LogicalPosition | PhysicalPosition = someFunction(); // where someFunction returns either LogicalPosition or PhysicalPosition + * const validPosition = position instanceof LogicalPosition + * ? { Logical: { x: position.x, y: position.y } } + * : { Physical: { x: position.x, y: position.y } } + * await invoke("do_something_with_position", { position: validPosition }); + * ``` + * + * You can just use {@linkcode Position} + * ```typescript + * import { invoke } from '@tauri-apps/api/core'; + * import { LogicalPosition, PhysicalPosition, Position } from '@tauri-apps/api/dpi'; + * + * const position: LogicalPosition | PhysicalPosition = someFunction(); // where someFunction returns either LogicalPosition or PhysicalPosition + * const validPosition = new Position(position); + * await invoke("do_something_with_position", { position: validPosition }); + * ``` + * + * @since 2.1.0 + */ +class Position { + position: LogicalPosition | PhysicalPosition + + constructor(position: LogicalPosition | PhysicalPosition) { + this.position = position + } + + toLogical(scaleFactor: number): LogicalPosition { + return this.position instanceof LogicalPosition + ? this.position + : this.position.toLogical(scaleFactor) + } + + toPhysical(scaleFactor: number): PhysicalPosition { + return this.position instanceof PhysicalPosition + ? this.position + : this.position.toPhysical(scaleFactor) + } + + [SERIALIZE_TO_IPC_FN]() { + return { + [`${this.position.type}`]: { + x: this.position.x, + y: this.position.y + } + } + } + + toJSON() { + // eslint-disable-next-line security/detect-object-injection + return this[SERIALIZE_TO_IPC_FN]() + } +} + +export { + LogicalPosition, + LogicalSize, + Size, + PhysicalPosition, + PhysicalSize, + Position +} diff --git a/packages/api/src/menu/menu.ts b/packages/api/src/menu/menu.ts index ae16701d438c..0b703c965125 100644 --- a/packages/api/src/menu/menu.ts +++ b/packages/api/src/menu/menu.ts @@ -14,7 +14,7 @@ import { CheckMenuItem } from './checkMenuItem' import { IconMenuItem } from './iconMenuItem' import { PredefinedMenuItem } from './predefinedMenuItem' import { Submenu } from './submenu' -import { type LogicalPosition, PhysicalPosition } from '../dpi' +import { type LogicalPosition, PhysicalPosition, Position } from '../dpi' import { type Window } from '../window' import { invoke } from '../core' import { type ItemKind, MenuItemBase, newMenu } from './base' @@ -244,22 +244,14 @@ export class Menu extends MenuItemBase { * If the position, is provided, it is relative to the window's top-left corner. */ async popup( - at?: PhysicalPosition | LogicalPosition, + at?: PhysicalPosition | LogicalPosition | Position, window?: Window ): Promise { - let atValue = null - if (at) { - atValue = {} as Record - atValue[`${at instanceof PhysicalPosition ? 'Physical' : 'Logical'}`] = { - x: at.x, - y: at.y - } - } return invoke('plugin:menu|popup', { rid: this.rid, kind: this.kind, window: window?.label ?? null, - at: atValue + at: at instanceof Position ? at : at ? new Position(at) : null }) } diff --git a/packages/api/src/menu/submenu.ts b/packages/api/src/menu/submenu.ts index edfd090d1246..ca594a69fdbe 100644 --- a/packages/api/src/menu/submenu.ts +++ b/packages/api/src/menu/submenu.ts @@ -15,6 +15,7 @@ import { invoke } from '../core' import { type LogicalPosition, PhysicalPosition, type Window } from '../window' import { type ItemKind, MenuItemBase, newMenu } from './base' import { type MenuOptions } from './menu' +import { Position } from '../dpi' function itemFromKind([rid, id, kind]: [number, string, ItemKind]): | Submenu @@ -243,19 +244,11 @@ export class Submenu extends MenuItemBase { at?: PhysicalPosition | LogicalPosition, window?: Window ): Promise { - let atValue = null - if (at) { - atValue = {} as Record - atValue[`${at instanceof PhysicalPosition ? 'Physical' : 'Logical'}`] = { - x: at.x, - y: at.y - } - } return invoke('plugin:menu|popup', { rid: this.rid, kind: this.kind, window: window?.label ?? null, - at: atValue + at: at instanceof Position ? at : at ? new Position(at) : null }) } diff --git a/packages/api/src/tray.ts b/packages/api/src/tray.ts index b919d8fc6124..91f748bc5a68 100644 --- a/packages/api/src/tray.ts +++ b/packages/api/src/tray.ts @@ -290,16 +290,9 @@ export class TrayIcon extends Resource { function mapEvent(e: RustTrayIconEvent): TrayIconEvent { const out = e as unknown as TrayIconEvent - out.position = new PhysicalPosition(e.position.x, e.position.y) - - out.rect.position = new PhysicalPosition( - e.rect.position.Physical.x, - e.rect.position.Physical.y - ) - out.rect.size = new PhysicalSize( - e.rect.size.Physical.width, - e.rect.size.Physical.height - ) + out.position = new PhysicalPosition(e.position) + out.rect.position = new PhysicalPosition(e.rect.position) + out.rect.size = new PhysicalSize(e.rect.size) return out } diff --git a/packages/api/src/webview.ts b/packages/api/src/webview.ts index d986de39a946..42a2643d0d05 100644 --- a/packages/api/src/webview.ts +++ b/packages/api/src/webview.ts @@ -18,6 +18,7 @@ import { PhysicalPosition, PhysicalSize } from './dpi' import type { LogicalPosition, LogicalSize } from './dpi' +import { Position, Size } from './dpi' import type { EventName, EventCallback, UnlistenFn } from './event' import { TauriEvent, @@ -361,7 +362,7 @@ class Webview { async position(): Promise { return invoke<{ x: number; y: number }>('plugin:webview|webview_position', { label: this.label - }).then(({ x, y }) => new PhysicalPosition(x, y)) + }).then((p) => new PhysicalPosition(p)) } /** @@ -381,7 +382,7 @@ class Webview { { label: this.label } - ).then(({ width, height }) => new PhysicalSize(width, height)) + ).then((s) => new PhysicalSize(s)) } // Setters @@ -413,22 +414,10 @@ class Webview { * @param size The logical or physical size. * @returns A promise indicating the success or failure of the operation. */ - async setSize(size: LogicalSize | PhysicalSize): Promise { - if (!size || (size.type !== 'Logical' && size.type !== 'Physical')) { - throw new Error( - 'the `size` argument must be either a LogicalSize or a PhysicalSize instance' - ) - } - - const value = {} as Record - value[`${size.type}`] = { - width: size.width, - height: size.height - } - + async setSize(size: LogicalSize | PhysicalSize | Size): Promise { return invoke('plugin:webview|set_webview_size', { label: this.label, - value + value: size instanceof Size ? size : new Size(size) }) } @@ -444,26 +433,11 @@ class Webview { * @returns A promise indicating the success or failure of the operation. */ async setPosition( - position: LogicalPosition | PhysicalPosition + position: LogicalPosition | PhysicalPosition | Position ): Promise { - if ( - !position || - (position.type !== 'Logical' && position.type !== 'Physical') - ) { - throw new Error( - 'the `position` argument must be either a LogicalPosition or a PhysicalPosition instance' - ) - } - - const value = {} as Record - value[`${position.type}`] = { - x: position.x, - y: position.y - } - return invoke('plugin:webview|set_webview_position', { label: this.label, - value + value: position instanceof Position ? position : new Position(position) }) } @@ -603,7 +577,7 @@ class Webview { payload: { type: 'enter', paths: event.payload.paths, - position: mapPhysicalPosition(event.payload.position) + position: new PhysicalPosition(event.payload.position) } }) } @@ -616,7 +590,7 @@ class Webview { ...event, payload: { type: 'over', - position: mapPhysicalPosition(event.payload.position) + position: new PhysicalPosition(event.payload.position) } }) } @@ -630,7 +604,7 @@ class Webview { payload: { type: 'drop', paths: event.payload.paths, - position: mapPhysicalPosition(event.payload.position) + position: new PhysicalPosition(event.payload.position) } }) } @@ -652,10 +626,6 @@ class Webview { } } -function mapPhysicalPosition(m: PhysicalPosition): PhysicalPosition { - return new PhysicalPosition(m.x, m.y) -} - /** * Configuration for the webview to create. * diff --git a/packages/api/src/window.ts b/packages/api/src/window.ts index c242e3dd2160..037f06e6523d 100644 --- a/packages/api/src/window.ts +++ b/packages/api/src/window.ts @@ -20,7 +20,9 @@ import { LogicalPosition, LogicalSize, PhysicalPosition, - PhysicalSize + PhysicalSize, + Position, + Size } from './dpi' import type { Event, EventName, EventCallback, UnlistenFn } from './event' import { @@ -530,7 +532,7 @@ class Window { async innerPosition(): Promise { return invoke<{ x: number; y: number }>('plugin:window|inner_position', { label: this.label - }).then(({ x, y }) => new PhysicalPosition(x, y)) + }).then((p) => new PhysicalPosition(p)) } /** @@ -546,7 +548,7 @@ class Window { async outerPosition(): Promise { return invoke<{ x: number; y: number }>('plugin:window|outer_position', { label: this.label - }).then(({ x, y }) => new PhysicalPosition(x, y)) + }).then((p) => new PhysicalPosition(p)) } /** @@ -566,7 +568,7 @@ class Window { { label: this.label } - ).then(({ width, height }) => new PhysicalSize(width, height)) + ).then((s) => new PhysicalSize(s)) } /** @@ -586,7 +588,7 @@ class Window { { label: this.label } - ).then(({ width, height }) => new PhysicalSize(width, height)) + ).then((s) => new PhysicalSize(s)) } /** @@ -1268,22 +1270,10 @@ class Window { * @param size The logical or physical inner size. * @returns A promise indicating the success or failure of the operation. */ - async setSize(size: LogicalSize | PhysicalSize): Promise { - if (!size || (size.type !== 'Logical' && size.type !== 'Physical')) { - throw new Error( - 'the `size` argument must be either a LogicalSize or a PhysicalSize instance' - ) - } - - const value = {} as Record - value[`${size.type}`] = { - width: size.width, - height: size.height - } - + async setSize(size: LogicalSize | PhysicalSize | Size): Promise { return invoke('plugin:window|set_size', { label: this.label, - value + value: size instanceof Size ? size : new Size(size) }) } @@ -1299,26 +1289,11 @@ class Window { * @returns A promise indicating the success or failure of the operation. */ async setMinSize( - size: LogicalSize | PhysicalSize | null | undefined + size: LogicalSize | PhysicalSize | Size | null | undefined ): Promise { - if (size && size.type !== 'Logical' && size.type !== 'Physical') { - throw new Error( - 'the `size` argument must be either a LogicalSize or a PhysicalSize instance' - ) - } - - let value = null as Record | null - if (size) { - value = {} - value[`${size.type}`] = { - width: size.width, - height: size.height - } - } - return invoke('plugin:window|set_min_size', { label: this.label, - value + value: size instanceof Size ? size : size ? new Size(size) : null }) } @@ -1334,26 +1309,11 @@ class Window { * @returns A promise indicating the success or failure of the operation. */ async setMaxSize( - size: LogicalSize | PhysicalSize | null | undefined + size: LogicalSize | PhysicalSize | Size | null | undefined ): Promise { - if (size && size.type !== 'Logical' && size.type !== 'Physical') { - throw new Error( - 'the `size` argument must be either a LogicalSize or a PhysicalSize instance' - ) - } - - let value = null as Record | null - if (size) { - value = {} - value[`${size.type}`] = { - width: size.width, - height: size.height - } - } - return invoke('plugin:window|set_max_size', { label: this.label, - value + value: size instanceof Size ? size : size ? new Size(size) : null }) } @@ -1398,26 +1358,11 @@ class Window { * @returns A promise indicating the success or failure of the operation. */ async setPosition( - position: LogicalPosition | PhysicalPosition + position: LogicalPosition | PhysicalPosition | Position ): Promise { - if ( - !position || - (position.type !== 'Logical' && position.type !== 'Physical') - ) { - throw new Error( - 'the `position` argument must be either a LogicalPosition or a PhysicalPosition instance' - ) - } - - const value = {} as Record - value[`${position.type}`] = { - x: position.x, - y: position.y - } - return invoke('plugin:window|set_position', { label: this.label, - value + value: position instanceof Position ? position : new Position(position) }) } @@ -1584,26 +1529,11 @@ class Window { * @returns A promise indicating the success or failure of the operation. */ async setCursorPosition( - position: LogicalPosition | PhysicalPosition + position: LogicalPosition | PhysicalPosition | Position ): Promise { - if ( - !position || - (position.type !== 'Logical' && position.type !== 'Physical') - ) { - throw new Error( - 'the `position` argument must be either a LogicalPosition or a PhysicalPosition instance' - ) - } - - const value = {} as Record - value[`${position.type}`] = { - x: position.x, - y: position.y - } - return invoke('plugin:window|set_cursor_position', { label: this.label, - value + value: position instanceof Position ? position : new Position(position) }) } @@ -1751,7 +1681,7 @@ class Window { */ async onResized(handler: EventCallback): Promise { return this.listen(TauriEvent.WINDOW_RESIZED, (e) => { - e.payload = mapPhysicalSize(e.payload) + e.payload = new PhysicalSize(e.payload) handler(e) }) } @@ -1775,7 +1705,7 @@ class Window { */ async onMoved(handler: EventCallback): Promise { return this.listen(TauriEvent.WINDOW_MOVED, (e) => { - e.payload = mapPhysicalPosition(e.payload) + e.payload = new PhysicalPosition(e.payload) handler(e) }) } @@ -1853,7 +1783,7 @@ class Window { payload: { type: 'enter', paths: event.payload.paths, - position: mapPhysicalPosition(event.payload.position) + position: new PhysicalPosition(event.payload.position) } }) } @@ -1866,7 +1796,7 @@ class Window { ...event, payload: { type: 'over', - position: mapPhysicalPosition(event.payload.position) + position: new PhysicalPosition(event.payload.position) } }) } @@ -1880,7 +1810,7 @@ class Window { payload: { type: 'drop', paths: event.payload.paths, - position: mapPhysicalPosition(event.payload.position) + position: new PhysicalPosition(event.payload.position) } }) } @@ -2310,19 +2240,11 @@ function mapMonitor(m: Monitor | null): Monitor | null { : { name: m.name, scaleFactor: m.scaleFactor, - position: mapPhysicalPosition(m.position), - size: mapPhysicalSize(m.size) + position: new PhysicalPosition(m.position), + size: new PhysicalSize(m.size) } } -function mapPhysicalPosition(m: PhysicalPosition): PhysicalPosition { - return new PhysicalPosition(m.x, m.y) -} - -function mapPhysicalSize(m: PhysicalSize): PhysicalSize { - return new PhysicalSize(m.width, m.height) -} - /** * Returns the monitor on which the window currently resides. * Returns `null` if current monitor can't be detected. @@ -2402,7 +2324,7 @@ async function availableMonitors(): Promise { */ async function cursorPosition(): Promise { return invoke('plugin:window|cursor_position').then( - mapPhysicalPosition + (v) => new PhysicalPosition(v) ) } From 03828587b553a585620f7362e8b2f8f048411a31 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:31:40 +0800 Subject: [PATCH 19/51] chore(deps) Update Tauri API Definitions (#11543) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/api/package.json | 4 +- pnpm-lock.yaml | 363 +++++++++++++++++++++----------------- 2 files changed, 201 insertions(+), 166 deletions(-) diff --git a/packages/api/package.json b/packages/api/package.json index 6187b784ede7..24d0a3684bd9 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -48,13 +48,13 @@ "@rollup/plugin-terser": "0.4.4", "@rollup/plugin-typescript": "12.1.1", "@types/eslint": "^9.0.0", - "@types/node": "20.17.0", + "@types/node": "20.17.3", "eslint": "^9.4.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-security": "3.0.1", "fast-glob": "3.3.2", "globals": "^15.4.0", - "rollup": "4.24.0", + "rollup": "4.24.3", "tslib": "^2.6.3", "typescript": "^5.4.5", "typescript-eslint": "^8.1.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e1c4b2dab5c..22bff7322e0b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,7 +39,7 @@ importers: version: 1.1.14 '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6)) + version: 3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) '@unocss/extractor-svelte': specifier: ^0.61.0 version: 0.61.9 @@ -48,10 +48,10 @@ importers: version: 4.2.19 unocss: specifier: ^0.61.0 - version: 0.61.9(postcss@8.4.47)(rollup@4.24.0)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6)) + version: 0.61.9(postcss@8.4.47)(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) vite: specifier: ^5.4.7 - version: 5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6) + version: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) examples/file-associations: {} @@ -64,16 +64,16 @@ importers: version: 9.13.0 '@rollup/plugin-terser': specifier: 0.4.4 - version: 0.4.4(rollup@4.24.0) + version: 0.4.4(rollup@4.24.3) '@rollup/plugin-typescript': specifier: 12.1.1 - version: 12.1.1(rollup@4.24.0)(tslib@2.8.0)(typescript@5.6.3) + version: 12.1.1(rollup@4.24.3)(tslib@2.8.0)(typescript@5.6.3) '@types/eslint': specifier: ^9.0.0 version: 9.6.1 '@types/node': - specifier: 20.17.0 - version: 20.17.0 + specifier: 20.17.3 + version: 20.17.3 eslint: specifier: ^9.4.0 version: 9.13.0(jiti@1.21.6) @@ -90,8 +90,8 @@ importers: specifier: ^15.4.0 version: 15.11.0 rollup: - specifier: 4.24.0 - version: 4.24.0 + specifier: 4.24.3 + version: 4.24.3 tslib: specifier: ^2.6.3 version: 2.8.0 @@ -100,7 +100,7 @@ importers: version: 5.6.3 typescript-eslint: specifier: ^8.1.0 - version: 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) + version: 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) packages/cli: devDependencies: @@ -734,10 +734,20 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/eslint-utils@4.4.1': + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/regexpp@4.11.1': resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + '@eslint/config-array@0.18.0': resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -874,8 +884,8 @@ packages: cpu: [arm] os: [android] - '@rollup/rollup-android-arm-eabi@4.24.0': - resolution: {integrity: sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==} + '@rollup/rollup-android-arm-eabi@4.24.3': + resolution: {integrity: sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==} cpu: [arm] os: [android] @@ -884,8 +894,8 @@ packages: cpu: [arm64] os: [android] - '@rollup/rollup-android-arm64@4.24.0': - resolution: {integrity: sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==} + '@rollup/rollup-android-arm64@4.24.3': + resolution: {integrity: sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==} cpu: [arm64] os: [android] @@ -894,8 +904,8 @@ packages: cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-arm64@4.24.0': - resolution: {integrity: sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==} + '@rollup/rollup-darwin-arm64@4.24.3': + resolution: {integrity: sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==} cpu: [arm64] os: [darwin] @@ -904,18 +914,28 @@ packages: cpu: [x64] os: [darwin] - '@rollup/rollup-darwin-x64@4.24.0': - resolution: {integrity: sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==} + '@rollup/rollup-darwin-x64@4.24.3': + resolution: {integrity: sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==} cpu: [x64] os: [darwin] + '@rollup/rollup-freebsd-arm64@4.24.3': + resolution: {integrity: sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.24.3': + resolution: {integrity: sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==} + cpu: [x64] + os: [freebsd] + '@rollup/rollup-linux-arm-gnueabihf@4.22.4': resolution: {integrity: sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-gnueabihf@4.24.0': - resolution: {integrity: sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==} + '@rollup/rollup-linux-arm-gnueabihf@4.24.3': + resolution: {integrity: sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==} cpu: [arm] os: [linux] @@ -924,8 +944,8 @@ packages: cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.24.0': - resolution: {integrity: sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==} + '@rollup/rollup-linux-arm-musleabihf@4.24.3': + resolution: {integrity: sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==} cpu: [arm] os: [linux] @@ -934,8 +954,8 @@ packages: cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.24.0': - resolution: {integrity: sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==} + '@rollup/rollup-linux-arm64-gnu@4.24.3': + resolution: {integrity: sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==} cpu: [arm64] os: [linux] @@ -944,8 +964,8 @@ packages: cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.24.0': - resolution: {integrity: sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==} + '@rollup/rollup-linux-arm64-musl@4.24.3': + resolution: {integrity: sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==} cpu: [arm64] os: [linux] @@ -954,8 +974,8 @@ packages: cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': - resolution: {integrity: sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==} + '@rollup/rollup-linux-powerpc64le-gnu@4.24.3': + resolution: {integrity: sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==} cpu: [ppc64] os: [linux] @@ -964,8 +984,8 @@ packages: cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.24.0': - resolution: {integrity: sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==} + '@rollup/rollup-linux-riscv64-gnu@4.24.3': + resolution: {integrity: sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==} cpu: [riscv64] os: [linux] @@ -974,8 +994,8 @@ packages: cpu: [s390x] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.24.0': - resolution: {integrity: sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==} + '@rollup/rollup-linux-s390x-gnu@4.24.3': + resolution: {integrity: sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==} cpu: [s390x] os: [linux] @@ -984,8 +1004,8 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.24.0': - resolution: {integrity: sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==} + '@rollup/rollup-linux-x64-gnu@4.24.3': + resolution: {integrity: sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==} cpu: [x64] os: [linux] @@ -994,8 +1014,8 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.24.0': - resolution: {integrity: sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==} + '@rollup/rollup-linux-x64-musl@4.24.3': + resolution: {integrity: sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==} cpu: [x64] os: [linux] @@ -1004,8 +1024,8 @@ packages: cpu: [arm64] os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.24.0': - resolution: {integrity: sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==} + '@rollup/rollup-win32-arm64-msvc@4.24.3': + resolution: {integrity: sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==} cpu: [arm64] os: [win32] @@ -1014,8 +1034,8 @@ packages: cpu: [ia32] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.24.0': - resolution: {integrity: sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==} + '@rollup/rollup-win32-ia32-msvc@4.24.3': + resolution: {integrity: sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==} cpu: [ia32] os: [win32] @@ -1024,8 +1044,8 @@ packages: cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.24.0': - resolution: {integrity: sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==} + '@rollup/rollup-win32-x64-msvc@4.24.3': + resolution: {integrity: sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==} cpu: [x64] os: [win32] @@ -1062,11 +1082,11 @@ packages: '@types/node@20.16.1': resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==} - '@types/node@20.17.0': - resolution: {integrity: sha512-a7zRo0f0eLo9K5X9Wp5cAqTUNGzuFLDG2R7C4HY2BhcMAsxgSPuRvAC1ZB6QkuUQXf0YZAgfOX2ZyrBa2n4nHQ==} + '@types/node@20.17.3': + resolution: {integrity: sha512-tSQrmKKatLDGnG92h40GD7FzUt0MjahaHwOME4VAFeeA/Xopayq5qLyQRy7Jg/pjgKIFBXuKcGhJo+UdYG55jQ==} - '@typescript-eslint/eslint-plugin@8.11.0': - resolution: {integrity: sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA==} + '@typescript-eslint/eslint-plugin@8.12.2': + resolution: {integrity: sha512-gQxbxM8mcxBwaEmWdtLCIGLfixBMHhQjBqR8sVWNTPpcj45WlYL2IObS/DNMLH1DBP0n8qz+aiiLTGfopPEebw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 @@ -1076,8 +1096,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@8.11.0': - resolution: {integrity: sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg==} + '@typescript-eslint/parser@8.12.2': + resolution: {integrity: sha512-MrvlXNfGPLH3Z+r7Tk+Z5moZAc0dzdVjTgUgwsdGweH7lydysQsnSww3nAmsq8blFuRD5VRlAr9YdEFw3e6PBw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -1086,12 +1106,12 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@8.11.0': - resolution: {integrity: sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==} + '@typescript-eslint/scope-manager@8.12.2': + resolution: {integrity: sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.11.0': - resolution: {integrity: sha512-ItiMfJS6pQU0NIKAaybBKkuVzo6IdnAhPFZA/2Mba/uBjuPQPet/8+zh5GtLHwmuFRShZx+8lhIs7/QeDHflOg==} + '@typescript-eslint/type-utils@8.12.2': + resolution: {integrity: sha512-bwuU4TAogPI+1q/IJSKuD4shBLc/d2vGcRT588q+jzayQyjVK2X6v/fbR4InY2U2sgf8MEvVCqEWUzYzgBNcGQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -1099,12 +1119,12 @@ packages: typescript: optional: true - '@typescript-eslint/types@8.11.0': - resolution: {integrity: sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==} + '@typescript-eslint/types@8.12.2': + resolution: {integrity: sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.11.0': - resolution: {integrity: sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==} + '@typescript-eslint/typescript-estree@8.12.2': + resolution: {integrity: sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -1112,14 +1132,14 @@ packages: typescript: optional: true - '@typescript-eslint/utils@8.11.0': - resolution: {integrity: sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==} + '@typescript-eslint/utils@8.12.2': + resolution: {integrity: sha512-UTTuDIX3fkfAz6iSVa5rTuSfWIYZ6ATtEocQ/umkRSyC9O919lbZ8dcH7mysshrCdrAM03skJOEYaBugxN+M6A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - '@typescript-eslint/visitor-keys@8.11.0': - resolution: {integrity: sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==} + '@typescript-eslint/visitor-keys@8.12.2': + resolution: {integrity: sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@unocss/astro@0.61.9': @@ -2008,8 +2028,8 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rollup@4.24.0: - resolution: {integrity: sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==} + rollup@4.24.3: + resolution: {integrity: sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -2182,8 +2202,8 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typescript-eslint@8.11.0: - resolution: {integrity: sha512-cBRGnW3FSlxaYwU8KfAewxFK5uzeOAp0l2KebIlPDOT5olVi65KDG/yjBooPBG0kGW/HLkoz1c/iuBFehcS3IA==} + typescript-eslint@8.12.2: + resolution: {integrity: sha512-UbuVUWSrHVR03q9CWx+JDHeO6B/Hr9p4U5lRH++5tq/EbFq1faYZe50ZSBePptgfIKLEti0aPQ3hFgnPVcd8ZQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -2853,8 +2873,15 @@ snapshots: eslint: 9.13.0(jiti@1.21.6) eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.4.1(eslint@9.13.0(jiti@1.21.6))': + dependencies: + eslint: 9.13.0(jiti@1.21.6) + eslint-visitor-keys: 3.4.3 + '@eslint-community/regexpp@4.11.1': {} + '@eslint-community/regexpp@4.12.1': {} + '@eslint/config-array@0.18.0': dependencies: '@eslint/object-schema': 2.1.4 @@ -2965,147 +2992,153 @@ snapshots: '@polka/url@1.0.0-next.25': {} - '@rollup/plugin-terser@0.4.4(rollup@4.24.0)': + '@rollup/plugin-terser@0.4.4(rollup@4.24.3)': dependencies: serialize-javascript: 6.0.2 smob: 1.5.0 terser: 5.31.6 optionalDependencies: - rollup: 4.24.0 + rollup: 4.24.3 - '@rollup/plugin-typescript@12.1.1(rollup@4.24.0)(tslib@2.8.0)(typescript@5.6.3)': + '@rollup/plugin-typescript@12.1.1(rollup@4.24.3)(tslib@2.8.0)(typescript@5.6.3)': dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.24.0) + '@rollup/pluginutils': 5.1.0(rollup@4.24.3) resolve: 1.22.8 typescript: 5.6.3 optionalDependencies: - rollup: 4.24.0 + rollup: 4.24.3 tslib: 2.8.0 - '@rollup/pluginutils@5.1.0(rollup@4.24.0)': + '@rollup/pluginutils@5.1.0(rollup@4.24.3)': dependencies: '@types/estree': 1.0.6 estree-walker: 2.0.2 picomatch: 2.3.1 optionalDependencies: - rollup: 4.24.0 + rollup: 4.24.3 '@rollup/rollup-android-arm-eabi@4.22.4': optional: true - '@rollup/rollup-android-arm-eabi@4.24.0': + '@rollup/rollup-android-arm-eabi@4.24.3': optional: true '@rollup/rollup-android-arm64@4.22.4': optional: true - '@rollup/rollup-android-arm64@4.24.0': + '@rollup/rollup-android-arm64@4.24.3': optional: true '@rollup/rollup-darwin-arm64@4.22.4': optional: true - '@rollup/rollup-darwin-arm64@4.24.0': + '@rollup/rollup-darwin-arm64@4.24.3': optional: true '@rollup/rollup-darwin-x64@4.22.4': optional: true - '@rollup/rollup-darwin-x64@4.24.0': + '@rollup/rollup-darwin-x64@4.24.3': + optional: true + + '@rollup/rollup-freebsd-arm64@4.24.3': + optional: true + + '@rollup/rollup-freebsd-x64@4.24.3': optional: true '@rollup/rollup-linux-arm-gnueabihf@4.22.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.24.0': + '@rollup/rollup-linux-arm-gnueabihf@4.24.3': optional: true '@rollup/rollup-linux-arm-musleabihf@4.22.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.24.0': + '@rollup/rollup-linux-arm-musleabihf@4.24.3': optional: true '@rollup/rollup-linux-arm64-gnu@4.22.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.24.0': + '@rollup/rollup-linux-arm64-gnu@4.24.3': optional: true '@rollup/rollup-linux-arm64-musl@4.22.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.24.0': + '@rollup/rollup-linux-arm64-musl@4.24.3': optional: true '@rollup/rollup-linux-powerpc64le-gnu@4.22.4': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.24.3': optional: true '@rollup/rollup-linux-riscv64-gnu@4.22.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.24.0': + '@rollup/rollup-linux-riscv64-gnu@4.24.3': optional: true '@rollup/rollup-linux-s390x-gnu@4.22.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.24.0': + '@rollup/rollup-linux-s390x-gnu@4.24.3': optional: true '@rollup/rollup-linux-x64-gnu@4.22.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.24.0': + '@rollup/rollup-linux-x64-gnu@4.24.3': optional: true '@rollup/rollup-linux-x64-musl@4.22.4': optional: true - '@rollup/rollup-linux-x64-musl@4.24.0': + '@rollup/rollup-linux-x64-musl@4.24.3': optional: true '@rollup/rollup-win32-arm64-msvc@4.22.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.24.0': + '@rollup/rollup-win32-arm64-msvc@4.24.3': optional: true '@rollup/rollup-win32-ia32-msvc@4.22.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.24.0': + '@rollup/rollup-win32-ia32-msvc@4.24.3': optional: true '@rollup/rollup-win32-x64-msvc@4.22.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.24.0': + '@rollup/rollup-win32-x64-msvc@4.24.3': optional: true - '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6)))(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6))': + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)))(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) debug: 4.3.6 svelte: 4.2.19 - vite: 5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6))': + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6)))(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6)) + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)))(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) debug: 4.3.6 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.11 svelte: 4.2.19 svelte-hmr: 0.16.0(svelte@4.2.19) - vite: 5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6) - vitefu: 0.2.5(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6)) + vite: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) + vitefu: 0.2.5(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) transitivePeerDependencies: - supports-color @@ -3122,24 +3155,24 @@ snapshots: '@types/node-forge@1.3.11': dependencies: - '@types/node': 20.17.0 + '@types/node': 20.17.3 '@types/node@20.16.1': dependencies: undici-types: 6.19.8 - '@types/node@20.17.0': + '@types/node@20.17.3': dependencies: undici-types: 6.19.8 - '@typescript-eslint/eslint-plugin@8.11.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3)': + '@typescript-eslint/eslint-plugin@8.12.2(@typescript-eslint/parser@8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3)': dependencies: - '@eslint-community/regexpp': 4.11.1 - '@typescript-eslint/parser': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) - '@typescript-eslint/scope-manager': 8.11.0 - '@typescript-eslint/type-utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) - '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 8.11.0 + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.12.2 + '@typescript-eslint/type-utils': 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/utils': 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.12.2 eslint: 9.13.0(jiti@1.21.6) graphemer: 1.4.0 ignore: 5.3.2 @@ -3150,12 +3183,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3)': + '@typescript-eslint/parser@8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3)': dependencies: - '@typescript-eslint/scope-manager': 8.11.0 - '@typescript-eslint/types': 8.11.0 - '@typescript-eslint/typescript-estree': 8.11.0(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 8.11.0 + '@typescript-eslint/scope-manager': 8.12.2 + '@typescript-eslint/types': 8.12.2 + '@typescript-eslint/typescript-estree': 8.12.2(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.12.2 debug: 4.3.7 eslint: 9.13.0(jiti@1.21.6) optionalDependencies: @@ -3163,15 +3196,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.11.0': + '@typescript-eslint/scope-manager@8.12.2': dependencies: - '@typescript-eslint/types': 8.11.0 - '@typescript-eslint/visitor-keys': 8.11.0 + '@typescript-eslint/types': 8.12.2 + '@typescript-eslint/visitor-keys': 8.12.2 - '@typescript-eslint/type-utils@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3)': + '@typescript-eslint/type-utils@8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.11.0(typescript@5.6.3) - '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 8.12.2(typescript@5.6.3) + '@typescript-eslint/utils': 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) debug: 4.3.7 ts-api-utils: 1.3.0(typescript@5.6.3) optionalDependencies: @@ -3180,12 +3213,12 @@ snapshots: - eslint - supports-color - '@typescript-eslint/types@8.11.0': {} + '@typescript-eslint/types@8.12.2': {} - '@typescript-eslint/typescript-estree@8.11.0(typescript@5.6.3)': + '@typescript-eslint/typescript-estree@8.12.2(typescript@5.6.3)': dependencies: - '@typescript-eslint/types': 8.11.0 - '@typescript-eslint/visitor-keys': 8.11.0 + '@typescript-eslint/types': 8.12.2 + '@typescript-eslint/visitor-keys': 8.12.2 debug: 4.3.7 fast-glob: 3.3.2 is-glob: 4.0.3 @@ -3197,37 +3230,37 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3)': + '@typescript-eslint/utils@8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) - '@typescript-eslint/scope-manager': 8.11.0 - '@typescript-eslint/types': 8.11.0 - '@typescript-eslint/typescript-estree': 8.11.0(typescript@5.6.3) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.13.0(jiti@1.21.6)) + '@typescript-eslint/scope-manager': 8.12.2 + '@typescript-eslint/types': 8.12.2 + '@typescript-eslint/typescript-estree': 8.12.2(typescript@5.6.3) eslint: 9.13.0(jiti@1.21.6) transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@8.11.0': + '@typescript-eslint/visitor-keys@8.12.2': dependencies: - '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/types': 8.12.2 eslint-visitor-keys: 3.4.3 - '@unocss/astro@0.61.9(rollup@4.24.0)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6))': + '@unocss/astro@0.61.9(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6))': dependencies: '@unocss/core': 0.61.9 '@unocss/reset': 0.61.9 - '@unocss/vite': 0.61.9(rollup@4.24.0)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6)) + '@unocss/vite': 0.61.9(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) optionalDependencies: - vite: 5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) transitivePeerDependencies: - rollup - supports-color - '@unocss/cli@0.61.9(rollup@4.24.0)': + '@unocss/cli@0.61.9(rollup@4.24.3)': dependencies: '@ampproject/remapping': 2.3.0 - '@rollup/pluginutils': 5.1.0(rollup@4.24.0) + '@rollup/pluginutils': 5.1.0(rollup@4.24.3) '@unocss/config': 0.61.9 '@unocss/core': 0.61.9 '@unocss/preset-uno': 0.61.9 @@ -3358,10 +3391,10 @@ snapshots: dependencies: '@unocss/core': 0.61.9 - '@unocss/vite@0.61.9(rollup@4.24.0)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6))': + '@unocss/vite@0.61.9(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6))': dependencies: '@ampproject/remapping': 2.3.0 - '@rollup/pluginutils': 5.1.0(rollup@4.24.0) + '@rollup/pluginutils': 5.1.0(rollup@4.24.3) '@unocss/config': 0.61.9 '@unocss/core': 0.61.9 '@unocss/inspector': 0.61.9 @@ -3370,7 +3403,7 @@ snapshots: chokidar: 3.6.0 fast-glob: 3.3.2 magic-string: 0.30.11 - vite: 5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) transitivePeerDependencies: - rollup - supports-color @@ -4221,26 +4254,28 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.22.4 fsevents: 2.3.3 - rollup@4.24.0: + rollup@4.24.3: dependencies: '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.24.0 - '@rollup/rollup-android-arm64': 4.24.0 - '@rollup/rollup-darwin-arm64': 4.24.0 - '@rollup/rollup-darwin-x64': 4.24.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.24.0 - '@rollup/rollup-linux-arm-musleabihf': 4.24.0 - '@rollup/rollup-linux-arm64-gnu': 4.24.0 - '@rollup/rollup-linux-arm64-musl': 4.24.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.24.0 - '@rollup/rollup-linux-riscv64-gnu': 4.24.0 - '@rollup/rollup-linux-s390x-gnu': 4.24.0 - '@rollup/rollup-linux-x64-gnu': 4.24.0 - '@rollup/rollup-linux-x64-musl': 4.24.0 - '@rollup/rollup-win32-arm64-msvc': 4.24.0 - '@rollup/rollup-win32-ia32-msvc': 4.24.0 - '@rollup/rollup-win32-x64-msvc': 4.24.0 + '@rollup/rollup-android-arm-eabi': 4.24.3 + '@rollup/rollup-android-arm64': 4.24.3 + '@rollup/rollup-darwin-arm64': 4.24.3 + '@rollup/rollup-darwin-x64': 4.24.3 + '@rollup/rollup-freebsd-arm64': 4.24.3 + '@rollup/rollup-freebsd-x64': 4.24.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.24.3 + '@rollup/rollup-linux-arm-musleabihf': 4.24.3 + '@rollup/rollup-linux-arm64-gnu': 4.24.3 + '@rollup/rollup-linux-arm64-musl': 4.24.3 + '@rollup/rollup-linux-powerpc64le-gnu': 4.24.3 + '@rollup/rollup-linux-riscv64-gnu': 4.24.3 + '@rollup/rollup-linux-s390x-gnu': 4.24.3 + '@rollup/rollup-linux-x64-gnu': 4.24.3 + '@rollup/rollup-linux-x64-musl': 4.24.3 + '@rollup/rollup-win32-arm64-msvc': 4.24.3 + '@rollup/rollup-win32-ia32-msvc': 4.24.3 + '@rollup/rollup-win32-x64-msvc': 4.24.3 fsevents: 2.3.3 run-parallel@1.2.0: @@ -4394,11 +4429,11 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3): + typescript-eslint@8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.11.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) - '@typescript-eslint/parser': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) - '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/eslint-plugin': 8.12.2(@typescript-eslint/parser@8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/parser': 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/utils': 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: @@ -4430,10 +4465,10 @@ snapshots: pathe: 1.1.2 ufo: 1.5.4 - unocss@0.61.9(postcss@8.4.47)(rollup@4.24.0)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6)): + unocss@0.61.9(postcss@8.4.47)(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)): dependencies: - '@unocss/astro': 0.61.9(rollup@4.24.0)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6)) - '@unocss/cli': 0.61.9(rollup@4.24.0) + '@unocss/astro': 0.61.9(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) + '@unocss/cli': 0.61.9(rollup@4.24.3) '@unocss/core': 0.61.9 '@unocss/extractor-arbitrary-variants': 0.61.9 '@unocss/postcss': 0.61.9(postcss@8.4.47) @@ -4451,9 +4486,9 @@ snapshots: '@unocss/transformer-compile-class': 0.61.9 '@unocss/transformer-directives': 0.61.9 '@unocss/transformer-variant-group': 0.61.9 - '@unocss/vite': 0.61.9(rollup@4.24.0)(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6)) + '@unocss/vite': 0.61.9(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) optionalDependencies: - vite: 5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) transitivePeerDependencies: - postcss - rollup @@ -4490,7 +4525,7 @@ snapshots: dependencies: esbuild: 0.21.5 postcss: 8.4.47 - rollup: 4.24.0 + rollup: 4.24.3 optionalDependencies: '@types/node': 20.16.1 fsevents: 2.3.3 @@ -4508,20 +4543,20 @@ snapshots: sass: 1.77.8 terser: 5.31.6 - vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6): + vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6): dependencies: esbuild: 0.21.5 postcss: 8.4.47 rollup: 4.22.4 optionalDependencies: - '@types/node': 20.17.0 + '@types/node': 20.17.3 fsevents: 2.3.3 sass: 1.77.8 terser: 5.31.6 - vitefu@0.2.5(vite@5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6)): + vitefu@0.2.5(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)): optionalDependencies: - vite: 5.4.7(@types/node@20.17.0)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) vitest@2.1.1(@types/node@20.16.1)(sass@1.77.8)(terser@5.31.6): dependencies: From 0a170d07168176efc37e153a9782c96a043dfb7e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:39:56 +0800 Subject: [PATCH 20/51] chore(deps) Update Rust crate anyhow to v1.0.92 (#11594) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a1ed9ccdda65..0a635a416f09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -217,9 +217,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" +checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" [[package]] name = "api" From e835751d4f2941b18a93d10681c2b6e3da704436 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:40:30 +0800 Subject: [PATCH 21/51] chore(deps) Update Rust crate syn to v2.0.87 (#11595) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 118 ++++++++++++++++++++++++++--------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a635a416f09..04257bec2f47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -422,7 +422,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -507,7 +507,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1265,7 +1265,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "syn_derive", ] @@ -1697,7 +1697,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2144,7 +2144,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2154,7 +2154,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" dependencies = [ "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2201,7 +2201,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2225,7 +2225,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2236,7 +2236,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2313,7 +2313,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2334,7 +2334,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2344,7 +2344,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" dependencies = [ "derive_builder_core", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2357,7 +2357,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2468,7 +2468,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2491,7 +2491,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2740,7 +2740,7 @@ checksum = "ba7795da175654fe16979af73f81f26a8ea27638d8d9823d317016888a63dc4c" dependencies = [ "num-traits", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3018,7 +3018,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3143,7 +3143,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3417,7 +3417,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3542,7 +3542,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -4150,7 +4150,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -4976,7 +4976,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -5116,7 +5116,7 @@ dependencies = [ "napi-derive-backend", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -5131,7 +5131,7 @@ dependencies = [ "quote", "regex", "semver", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -5362,7 +5362,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -5424,7 +5424,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -5755,7 +5755,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -5866,7 +5866,7 @@ checksum = "197b36739db0e80919e19a90785233eea5664697d4cd829bd49af34838ec43d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -6125,7 +6125,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -6184,7 +6184,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -6366,7 +6366,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -6425,7 +6425,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -6642,7 +6642,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "version_check", "yansi", ] @@ -6663,7 +6663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" dependencies = [ "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -7685,7 +7685,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -7711,7 +7711,7 @@ checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -7905,7 +7905,7 @@ checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -7916,7 +7916,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -7959,7 +7959,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8010,7 +8010,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8048,7 +8048,7 @@ checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8440,7 +8440,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8661,9 +8661,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.85" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -8679,7 +8679,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8803,7 +8803,7 @@ checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -9062,7 +9062,7 @@ dependencies = [ "serde", "serde_json", "sha2", - "syn 2.0.85", + "syn 2.0.87", "tauri-utils 2.0.2", "thiserror", "time", @@ -9136,7 +9136,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "tauri-codegen", "tauri-utils 2.0.2", ] @@ -9476,7 +9476,7 @@ checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -9603,7 +9603,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -9809,7 +9809,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -10380,7 +10380,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-shared", ] @@ -10414,7 +10414,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -10529,7 +10529,7 @@ checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -10664,7 +10664,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -10675,7 +10675,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -11051,7 +11051,7 @@ dependencies = [ "async-trait", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-macro-support", @@ -11251,7 +11251,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -11271,7 +11271,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] From 8061fb2da899ea22b1cab125ba9ed191df4fa44a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 16:04:51 +0800 Subject: [PATCH 22/51] chore(deps) Update Rust crate anyhow to v1.0.93 (#11598) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04257bec2f47..59075a8b82ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -217,9 +217,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "api" From 58392a5221e2d7407ddaa76d90e6b1a487a15f3e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 07:49:18 -0300 Subject: [PATCH 23/51] chore(deps) Update Rust crate handlebars to v6.2.0 (dev) (#11544) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59075a8b82ae..9fc52515feb2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3595,11 +3595,12 @@ dependencies = [ [[package]] name = "handlebars" -version = "6.1.0" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25b617d1375ef96eeb920ae717e3da34a02fc979fe632c75128350f9e1f74a" +checksum = "fd4ccde012831f9a071a637b0d4e31df31c0f6c525784b35ae76a9ac6bc1e315" dependencies = [ "log", + "num-order", "pest", "pest_derive", "serde", @@ -5385,6 +5386,21 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-modular" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" + +[[package]] +name = "num-order" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" +dependencies = [ + "num-modular", +] + [[package]] name = "num-rational" version = "0.4.2" From e8c0c579094138b70c0ea5f9ed4585fa53a533c8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 07:49:38 -0300 Subject: [PATCH 24/51] chore(deps) Update Tauri Codegen (dev) (#11596) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 278 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 258 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9fc52515feb2..82518943c0b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -479,7 +479,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -3931,6 +3931,124 @@ dependencies = [ "png", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "idea" version = "0.5.1" @@ -3948,12 +4066,23 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -4785,6 +4914,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "local-ip-address" version = "0.6.3" @@ -8725,6 +8860,17 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "sysctl" version = "0.4.6" @@ -9477,18 +9623,18 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", @@ -9578,6 +9724,16 @@ dependencies = [ "url", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -10066,15 +10222,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-properties" version = "0.1.3" @@ -10153,9 +10300,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" dependencies = [ "form_urlencoded", "idna", @@ -10214,12 +10361,24 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + [[package]] name = "utf8-width" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -11086,6 +11245,18 @@ dependencies = [ "web-sys", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "wry" version = "0.46.1" @@ -11249,6 +11420,30 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure 0.13.1", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -11270,6 +11465,27 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure 0.13.1", +] + [[package]] name = "zeroize" version = "1.8.1" @@ -11290,6 +11506,28 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "zip" version = "0.6.6" From b63353bd6154927ec854fbe2c49a77567ec4a78f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 07:49:59 -0300 Subject: [PATCH 25/51] chore(deps) Update Tauri API Definitions (dev) (#11597) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/api/package.json | 4 +- pnpm-lock.yaml | 503 +++++++++++++++++++------------------- 2 files changed, 248 insertions(+), 259 deletions(-) diff --git a/packages/api/package.json b/packages/api/package.json index 24d0a3684bd9..829a6c433a53 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -48,13 +48,13 @@ "@rollup/plugin-terser": "0.4.4", "@rollup/plugin-typescript": "12.1.1", "@types/eslint": "^9.0.0", - "@types/node": "20.17.3", + "@types/node": "20.17.6", "eslint": "^9.4.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-security": "3.0.1", "fast-glob": "3.3.2", "globals": "^15.4.0", - "rollup": "4.24.3", + "rollup": "4.24.4", "tslib": "^2.6.3", "typescript": "^5.4.5", "typescript-eslint": "^8.1.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 22bff7322e0b..e42d26e23c35 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,7 +39,7 @@ importers: version: 1.1.14 '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) + version: 3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) '@unocss/extractor-svelte': specifier: ^0.61.0 version: 0.61.9 @@ -48,10 +48,10 @@ importers: version: 4.2.19 unocss: specifier: ^0.61.0 - version: 0.61.9(postcss@8.4.47)(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) + version: 0.61.9(postcss@8.4.47)(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) vite: specifier: ^5.4.7 - version: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) + version: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) examples/file-associations: {} @@ -61,25 +61,25 @@ importers: devDependencies: '@eslint/js': specifier: ^9.4.0 - version: 9.13.0 + version: 9.14.0 '@rollup/plugin-terser': specifier: 0.4.4 - version: 0.4.4(rollup@4.24.3) + version: 0.4.4(rollup@4.24.4) '@rollup/plugin-typescript': specifier: 12.1.1 - version: 12.1.1(rollup@4.24.3)(tslib@2.8.0)(typescript@5.6.3) + version: 12.1.1(rollup@4.24.4)(tslib@2.8.1)(typescript@5.6.3) '@types/eslint': specifier: ^9.0.0 version: 9.6.1 '@types/node': - specifier: 20.17.3 - version: 20.17.3 + specifier: 20.17.6 + version: 20.17.6 eslint: specifier: ^9.4.0 - version: 9.13.0(jiti@1.21.6) + version: 9.14.0(jiti@1.21.6) eslint-config-prettier: specifier: 9.1.0 - version: 9.1.0(eslint@9.13.0(jiti@1.21.6)) + version: 9.1.0(eslint@9.14.0(jiti@1.21.6)) eslint-plugin-security: specifier: 3.0.1 version: 3.0.1 @@ -88,19 +88,19 @@ importers: version: 3.3.2 globals: specifier: ^15.4.0 - version: 15.11.0 + version: 15.12.0 rollup: - specifier: 4.24.3 - version: 4.24.3 + specifier: 4.24.4 + version: 4.24.4 tslib: specifier: ^2.6.3 - version: 2.8.0 + version: 2.8.1 typescript: specifier: ^5.4.5 version: 5.6.3 typescript-eslint: specifier: ^8.1.0 - version: 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) + version: 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) packages/cli: devDependencies: @@ -728,22 +728,12 @@ packages: cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.4.0': - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/eslint-utils@4.4.1': resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.11.1': - resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint-community/regexpp@4.12.1': resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -760,28 +750,28 @@ packages: resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.13.0': - resolution: {integrity: sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==} + '@eslint/js@9.14.0': + resolution: {integrity: sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.4': resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.2.1': - resolution: {integrity: sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==} + '@eslint/plugin-kit@0.2.2': + resolution: {integrity: sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@fastify/busboy@2.1.1': resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} engines: {node: '>=14'} - '@humanfs/core@0.19.0': - resolution: {integrity: sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==} + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} - '@humanfs/node@0.16.5': - resolution: {integrity: sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==} + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': @@ -792,6 +782,10 @@ packages: resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} engines: {node: '>=18.18'} + '@humanwhocodes/retry@0.4.1': + resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} + engines: {node: '>=18.18'} + '@iconify-json/codicon@1.1.51': resolution: {integrity: sha512-jNgy3mWL23r5uWdNIijlZvqXY7jARpPayNLl0qBDVfLiBbLHTFM8shPrb41z1usmSPxyKkZctsDmf5gCOzmEbw==} @@ -884,8 +878,8 @@ packages: cpu: [arm] os: [android] - '@rollup/rollup-android-arm-eabi@4.24.3': - resolution: {integrity: sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==} + '@rollup/rollup-android-arm-eabi@4.24.4': + resolution: {integrity: sha512-jfUJrFct/hTA0XDM5p/htWKoNNTbDLY0KRwEt6pyOA6k2fmk0WVwl65PdUdJZgzGEHWx+49LilkcSaumQRyNQw==} cpu: [arm] os: [android] @@ -894,8 +888,8 @@ packages: cpu: [arm64] os: [android] - '@rollup/rollup-android-arm64@4.24.3': - resolution: {integrity: sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==} + '@rollup/rollup-android-arm64@4.24.4': + resolution: {integrity: sha512-j4nrEO6nHU1nZUuCfRKoCcvh7PIywQPUCBa2UsootTHvTHIoIu2BzueInGJhhvQO/2FTRdNYpf63xsgEqH9IhA==} cpu: [arm64] os: [android] @@ -904,8 +898,8 @@ packages: cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-arm64@4.24.3': - resolution: {integrity: sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==} + '@rollup/rollup-darwin-arm64@4.24.4': + resolution: {integrity: sha512-GmU/QgGtBTeraKyldC7cDVVvAJEOr3dFLKneez/n7BvX57UdhOqDsVwzU7UOnYA7AAOt+Xb26lk79PldDHgMIQ==} cpu: [arm64] os: [darwin] @@ -914,18 +908,18 @@ packages: cpu: [x64] os: [darwin] - '@rollup/rollup-darwin-x64@4.24.3': - resolution: {integrity: sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==} + '@rollup/rollup-darwin-x64@4.24.4': + resolution: {integrity: sha512-N6oDBiZCBKlwYcsEPXGDE4g9RoxZLK6vT98M8111cW7VsVJFpNEqvJeIPfsCzbf0XEakPslh72X0gnlMi4Ddgg==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.24.3': - resolution: {integrity: sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==} + '@rollup/rollup-freebsd-arm64@4.24.4': + resolution: {integrity: sha512-py5oNShCCjCyjWXCZNrRGRpjWsF0ic8f4ieBNra5buQz0O/U6mMXCpC1LvrHuhJsNPgRt36tSYMidGzZiJF6mw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.24.3': - resolution: {integrity: sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==} + '@rollup/rollup-freebsd-x64@4.24.4': + resolution: {integrity: sha512-L7VVVW9FCnTTp4i7KrmHeDsDvjB4++KOBENYtNYAiYl96jeBThFfhP6HVxL74v4SiZEVDH/1ILscR5U9S4ms4g==} cpu: [x64] os: [freebsd] @@ -934,8 +928,8 @@ packages: cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-gnueabihf@4.24.3': - resolution: {integrity: sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==} + '@rollup/rollup-linux-arm-gnueabihf@4.24.4': + resolution: {integrity: sha512-10ICosOwYChROdQoQo589N5idQIisxjaFE/PAnX2i0Zr84mY0k9zul1ArH0rnJ/fpgiqfu13TFZR5A5YJLOYZA==} cpu: [arm] os: [linux] @@ -944,8 +938,8 @@ packages: cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.24.3': - resolution: {integrity: sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==} + '@rollup/rollup-linux-arm-musleabihf@4.24.4': + resolution: {integrity: sha512-ySAfWs69LYC7QhRDZNKqNhz2UKN8LDfbKSMAEtoEI0jitwfAG2iZwVqGACJT+kfYvvz3/JgsLlcBP+WWoKCLcw==} cpu: [arm] os: [linux] @@ -954,8 +948,8 @@ packages: cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.24.3': - resolution: {integrity: sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==} + '@rollup/rollup-linux-arm64-gnu@4.24.4': + resolution: {integrity: sha512-uHYJ0HNOI6pGEeZ/5mgm5arNVTI0nLlmrbdph+pGXpC9tFHFDQmDMOEqkmUObRfosJqpU8RliYoGz06qSdtcjg==} cpu: [arm64] os: [linux] @@ -964,8 +958,8 @@ packages: cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.24.3': - resolution: {integrity: sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==} + '@rollup/rollup-linux-arm64-musl@4.24.4': + resolution: {integrity: sha512-38yiWLemQf7aLHDgTg85fh3hW9stJ0Muk7+s6tIkSUOMmi4Xbv5pH/5Bofnsb6spIwD5FJiR+jg71f0CH5OzoA==} cpu: [arm64] os: [linux] @@ -974,8 +968,8 @@ packages: cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.24.3': - resolution: {integrity: sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==} + '@rollup/rollup-linux-powerpc64le-gnu@4.24.4': + resolution: {integrity: sha512-q73XUPnkwt9ZNF2xRS4fvneSuaHw2BXuV5rI4cw0fWYVIWIBeDZX7c7FWhFQPNTnE24172K30I+dViWRVD9TwA==} cpu: [ppc64] os: [linux] @@ -984,8 +978,8 @@ packages: cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.24.3': - resolution: {integrity: sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==} + '@rollup/rollup-linux-riscv64-gnu@4.24.4': + resolution: {integrity: sha512-Aie/TbmQi6UXokJqDZdmTJuZBCU3QBDA8oTKRGtd4ABi/nHgXICulfg1KI6n9/koDsiDbvHAiQO3YAUNa/7BCw==} cpu: [riscv64] os: [linux] @@ -994,8 +988,8 @@ packages: cpu: [s390x] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.24.3': - resolution: {integrity: sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==} + '@rollup/rollup-linux-s390x-gnu@4.24.4': + resolution: {integrity: sha512-P8MPErVO/y8ohWSP9JY7lLQ8+YMHfTI4bAdtCi3pC2hTeqFJco2jYspzOzTUB8hwUWIIu1xwOrJE11nP+0JFAQ==} cpu: [s390x] os: [linux] @@ -1004,8 +998,8 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.24.3': - resolution: {integrity: sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==} + '@rollup/rollup-linux-x64-gnu@4.24.4': + resolution: {integrity: sha512-K03TljaaoPK5FOyNMZAAEmhlyO49LaE4qCsr0lYHUKyb6QacTNF9pnfPpXnFlFD3TXuFbFbz7tJ51FujUXkXYA==} cpu: [x64] os: [linux] @@ -1014,8 +1008,8 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.24.3': - resolution: {integrity: sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==} + '@rollup/rollup-linux-x64-musl@4.24.4': + resolution: {integrity: sha512-VJYl4xSl/wqG2D5xTYncVWW+26ICV4wubwN9Gs5NrqhJtayikwCXzPL8GDsLnaLU3WwhQ8W02IinYSFJfyo34Q==} cpu: [x64] os: [linux] @@ -1024,8 +1018,8 @@ packages: cpu: [arm64] os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.24.3': - resolution: {integrity: sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==} + '@rollup/rollup-win32-arm64-msvc@4.24.4': + resolution: {integrity: sha512-ku2GvtPwQfCqoPFIJCqZ8o7bJcj+Y54cZSr43hHca6jLwAiCbZdBUOrqE6y29QFajNAzzpIOwsckaTFmN6/8TA==} cpu: [arm64] os: [win32] @@ -1034,8 +1028,8 @@ packages: cpu: [ia32] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.24.3': - resolution: {integrity: sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==} + '@rollup/rollup-win32-ia32-msvc@4.24.4': + resolution: {integrity: sha512-V3nCe+eTt/W6UYNr/wGvO1fLpHUrnlirlypZfKCT1fG6hWfqhPgQV/K/mRBXBpxc0eKLIF18pIOFVPh0mqHjlg==} cpu: [ia32] os: [win32] @@ -1044,8 +1038,8 @@ packages: cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.24.3': - resolution: {integrity: sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==} + '@rollup/rollup-win32-x64-msvc@4.24.4': + resolution: {integrity: sha512-LTw1Dfd0mBIEqUVCxbvTE/LLo+9ZxVC9k99v1v4ahg9Aak6FpqOfNu5kRkeTAn0wphoC4JU7No1/rL+bBCEwhg==} cpu: [x64] os: [win32] @@ -1082,11 +1076,11 @@ packages: '@types/node@20.16.1': resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==} - '@types/node@20.17.3': - resolution: {integrity: sha512-tSQrmKKatLDGnG92h40GD7FzUt0MjahaHwOME4VAFeeA/Xopayq5qLyQRy7Jg/pjgKIFBXuKcGhJo+UdYG55jQ==} + '@types/node@20.17.6': + resolution: {integrity: sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==} - '@typescript-eslint/eslint-plugin@8.12.2': - resolution: {integrity: sha512-gQxbxM8mcxBwaEmWdtLCIGLfixBMHhQjBqR8sVWNTPpcj45WlYL2IObS/DNMLH1DBP0n8qz+aiiLTGfopPEebw==} + '@typescript-eslint/eslint-plugin@8.13.0': + resolution: {integrity: sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 @@ -1096,8 +1090,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@8.12.2': - resolution: {integrity: sha512-MrvlXNfGPLH3Z+r7Tk+Z5moZAc0dzdVjTgUgwsdGweH7lydysQsnSww3nAmsq8blFuRD5VRlAr9YdEFw3e6PBw==} + '@typescript-eslint/parser@8.13.0': + resolution: {integrity: sha512-w0xp+xGg8u/nONcGw1UXAr6cjCPU1w0XVyBs6Zqaj5eLmxkKQAByTdV/uGgNN5tVvN/kKpoQlP2cL7R+ajZZIQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -1106,12 +1100,12 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@8.12.2': - resolution: {integrity: sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==} + '@typescript-eslint/scope-manager@8.13.0': + resolution: {integrity: sha512-XsGWww0odcUT0gJoBZ1DeulY1+jkaHUciUq4jKNv4cpInbvvrtDoyBH9rE/n2V29wQJPk8iCH1wipra9BhmiMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.12.2': - resolution: {integrity: sha512-bwuU4TAogPI+1q/IJSKuD4shBLc/d2vGcRT588q+jzayQyjVK2X6v/fbR4InY2U2sgf8MEvVCqEWUzYzgBNcGQ==} + '@typescript-eslint/type-utils@8.13.0': + resolution: {integrity: sha512-Rqnn6xXTR316fP4D2pohZenJnp+NwQ1mo7/JM+J1LWZENSLkJI8ID8QNtlvFeb0HnFSK94D6q0cnMX6SbE5/vA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -1119,12 +1113,12 @@ packages: typescript: optional: true - '@typescript-eslint/types@8.12.2': - resolution: {integrity: sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==} + '@typescript-eslint/types@8.13.0': + resolution: {integrity: sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.12.2': - resolution: {integrity: sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==} + '@typescript-eslint/typescript-estree@8.13.0': + resolution: {integrity: sha512-v7SCIGmVsRK2Cy/LTLGN22uea6SaUIlpBcO/gnMGT/7zPtxp90bphcGf4fyrCQl3ZtiBKqVTG32hb668oIYy1g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -1132,14 +1126,14 @@ packages: typescript: optional: true - '@typescript-eslint/utils@8.12.2': - resolution: {integrity: sha512-UTTuDIX3fkfAz6iSVa5rTuSfWIYZ6ATtEocQ/umkRSyC9O919lbZ8dcH7mysshrCdrAM03skJOEYaBugxN+M6A==} + '@typescript-eslint/utils@8.13.0': + resolution: {integrity: sha512-A1EeYOND6Uv250nybnLZapeXpYMl8tkzYUxqmoKAWnI4sei3ihf2XdZVd+vVOmHGcp3t+P7yRrNsyyiXTvShFQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - '@typescript-eslint/visitor-keys@8.12.2': - resolution: {integrity: sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==} + '@typescript-eslint/visitor-keys@8.13.0': + resolution: {integrity: sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@unocss/astro@0.61.9': @@ -1280,8 +1274,8 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - acorn@8.13.0: - resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} engines: {node: '>=0.4.0'} hasBin: true @@ -1525,20 +1519,20 @@ packages: resolution: {integrity: sha512-XjVGBhtDZJfyuhIxnQ/WMm385RbX3DBu7H1J7HNNhmB2tnGxMeqVSnYv79oAj992ayvIBZghsymwkYFS6cGH4Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint-scope@8.1.0: - resolution: {integrity: sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==} + eslint-scope@8.2.0: + resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-visitor-keys@4.1.0: - resolution: {integrity: sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==} + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.13.0: - resolution: {integrity: sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==} + eslint@9.14.0: + resolution: {integrity: sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -1547,8 +1541,8 @@ packages: jiti: optional: true - espree@10.2.0: - resolution: {integrity: sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==} + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} esquery@1.6.0: @@ -1663,8 +1657,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@15.11.0: - resolution: {integrity: sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==} + globals@15.12.0: + resolution: {integrity: sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==} engines: {node: '>=18'} graphemer@1.4.0: @@ -2028,8 +2022,8 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rollup@4.24.3: - resolution: {integrity: sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==} + rollup@4.24.4: + resolution: {integrity: sha512-vGorVWIsWfX3xbcyAS+I047kFKapHYivmkaT63Smj77XwvLSJos6M1xGqZnBPFQFBRZDOcG1QnYEIxAvTr/HjA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -2184,14 +2178,14 @@ packages: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} - ts-api-utils@1.3.0: - resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + ts-api-utils@1.4.0: + resolution: {integrity: sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' - tslib@2.8.0: - resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} tsx@4.17.0: resolution: {integrity: sha512-eN4mnDA5UMKDt4YZixo9tBioibaMBpoxBkD+rIPAjVmYERSG0/dWEY1CEFuV89CgASlKL499q8AhmkMnnjtOJg==} @@ -2202,8 +2196,8 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typescript-eslint@8.12.2: - resolution: {integrity: sha512-UbuVUWSrHVR03q9CWx+JDHeO6B/Hr9p4U5lRH++5tq/EbFq1faYZe50ZSBePptgfIKLEti0aPQ3hFgnPVcd8ZQ==} + typescript-eslint@8.13.0: + resolution: {integrity: sha512-vIMpDRJrQd70au2G8w34mPps0ezFSPMEX4pXkTzUkrNbRX+36ais2ksGWN0esZL+ZMaFJEneOBHzCgSqle7DHw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -2868,18 +2862,11 @@ snapshots: '@esbuild/win32-x64@0.23.0': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@9.13.0(jiti@1.21.6))': + '@eslint-community/eslint-utils@4.4.1(eslint@9.14.0(jiti@1.21.6))': dependencies: - eslint: 9.13.0(jiti@1.21.6) + eslint: 9.14.0(jiti@1.21.6) eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.4.1(eslint@9.13.0(jiti@1.21.6))': - dependencies: - eslint: 9.13.0(jiti@1.21.6) - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.11.1': {} - '@eslint-community/regexpp@4.12.1': {} '@eslint/config-array@0.18.0': @@ -2896,7 +2883,7 @@ snapshots: dependencies: ajv: 6.12.6 debug: 4.3.7 - espree: 10.2.0 + espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.0 @@ -2906,27 +2893,29 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.13.0': {} + '@eslint/js@9.14.0': {} '@eslint/object-schema@2.1.4': {} - '@eslint/plugin-kit@0.2.1': + '@eslint/plugin-kit@0.2.2': dependencies: levn: 0.4.1 '@fastify/busboy@2.1.1': {} - '@humanfs/core@0.19.0': {} + '@humanfs/core@0.19.1': {} - '@humanfs/node@0.16.5': + '@humanfs/node@0.16.6': dependencies: - '@humanfs/core': 0.19.0 + '@humanfs/core': 0.19.1 '@humanwhocodes/retry': 0.3.1 '@humanwhocodes/module-importer@1.0.1': {} '@humanwhocodes/retry@0.3.1': {} + '@humanwhocodes/retry@0.4.1': {} + '@iconify-json/codicon@1.1.51': dependencies: '@iconify/types': 2.0.0 @@ -2992,153 +2981,153 @@ snapshots: '@polka/url@1.0.0-next.25': {} - '@rollup/plugin-terser@0.4.4(rollup@4.24.3)': + '@rollup/plugin-terser@0.4.4(rollup@4.24.4)': dependencies: serialize-javascript: 6.0.2 smob: 1.5.0 terser: 5.31.6 optionalDependencies: - rollup: 4.24.3 + rollup: 4.24.4 - '@rollup/plugin-typescript@12.1.1(rollup@4.24.3)(tslib@2.8.0)(typescript@5.6.3)': + '@rollup/plugin-typescript@12.1.1(rollup@4.24.4)(tslib@2.8.1)(typescript@5.6.3)': dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.24.3) + '@rollup/pluginutils': 5.1.0(rollup@4.24.4) resolve: 1.22.8 typescript: 5.6.3 optionalDependencies: - rollup: 4.24.3 - tslib: 2.8.0 + rollup: 4.24.4 + tslib: 2.8.1 - '@rollup/pluginutils@5.1.0(rollup@4.24.3)': + '@rollup/pluginutils@5.1.0(rollup@4.24.4)': dependencies: '@types/estree': 1.0.6 estree-walker: 2.0.2 picomatch: 2.3.1 optionalDependencies: - rollup: 4.24.3 + rollup: 4.24.4 '@rollup/rollup-android-arm-eabi@4.22.4': optional: true - '@rollup/rollup-android-arm-eabi@4.24.3': + '@rollup/rollup-android-arm-eabi@4.24.4': optional: true '@rollup/rollup-android-arm64@4.22.4': optional: true - '@rollup/rollup-android-arm64@4.24.3': + '@rollup/rollup-android-arm64@4.24.4': optional: true '@rollup/rollup-darwin-arm64@4.22.4': optional: true - '@rollup/rollup-darwin-arm64@4.24.3': + '@rollup/rollup-darwin-arm64@4.24.4': optional: true '@rollup/rollup-darwin-x64@4.22.4': optional: true - '@rollup/rollup-darwin-x64@4.24.3': + '@rollup/rollup-darwin-x64@4.24.4': optional: true - '@rollup/rollup-freebsd-arm64@4.24.3': + '@rollup/rollup-freebsd-arm64@4.24.4': optional: true - '@rollup/rollup-freebsd-x64@4.24.3': + '@rollup/rollup-freebsd-x64@4.24.4': optional: true '@rollup/rollup-linux-arm-gnueabihf@4.22.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.24.3': + '@rollup/rollup-linux-arm-gnueabihf@4.24.4': optional: true '@rollup/rollup-linux-arm-musleabihf@4.22.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.24.3': + '@rollup/rollup-linux-arm-musleabihf@4.24.4': optional: true '@rollup/rollup-linux-arm64-gnu@4.22.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.24.3': + '@rollup/rollup-linux-arm64-gnu@4.24.4': optional: true '@rollup/rollup-linux-arm64-musl@4.22.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.24.3': + '@rollup/rollup-linux-arm64-musl@4.24.4': optional: true '@rollup/rollup-linux-powerpc64le-gnu@4.22.4': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.24.3': + '@rollup/rollup-linux-powerpc64le-gnu@4.24.4': optional: true '@rollup/rollup-linux-riscv64-gnu@4.22.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.24.3': + '@rollup/rollup-linux-riscv64-gnu@4.24.4': optional: true '@rollup/rollup-linux-s390x-gnu@4.22.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.24.3': + '@rollup/rollup-linux-s390x-gnu@4.24.4': optional: true '@rollup/rollup-linux-x64-gnu@4.22.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.24.3': + '@rollup/rollup-linux-x64-gnu@4.24.4': optional: true '@rollup/rollup-linux-x64-musl@4.22.4': optional: true - '@rollup/rollup-linux-x64-musl@4.24.3': + '@rollup/rollup-linux-x64-musl@4.24.4': optional: true '@rollup/rollup-win32-arm64-msvc@4.22.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.24.3': + '@rollup/rollup-win32-arm64-msvc@4.24.4': optional: true '@rollup/rollup-win32-ia32-msvc@4.22.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.24.3': + '@rollup/rollup-win32-ia32-msvc@4.24.4': optional: true '@rollup/rollup-win32-x64-msvc@4.22.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.24.3': + '@rollup/rollup-win32-x64-msvc@4.24.4': optional: true - '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)))(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6))': + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)))(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) debug: 4.3.6 svelte: 4.2.19 - vite: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6))': + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)))(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)))(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) debug: 4.3.6 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.11 svelte: 4.2.19 svelte-hmr: 0.16.0(svelte@4.2.19) - vite: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) - vitefu: 0.2.5(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) + vite: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) + vitefu: 0.2.5(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) transitivePeerDependencies: - supports-color @@ -3155,112 +3144,112 @@ snapshots: '@types/node-forge@1.3.11': dependencies: - '@types/node': 20.17.3 + '@types/node': 20.17.6 '@types/node@20.16.1': dependencies: undici-types: 6.19.8 - '@types/node@20.17.3': + '@types/node@20.17.6': dependencies: undici-types: 6.19.8 - '@typescript-eslint/eslint-plugin@8.12.2(@typescript-eslint/parser@8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3)': + '@typescript-eslint/eslint-plugin@8.13.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) - '@typescript-eslint/scope-manager': 8.12.2 - '@typescript-eslint/type-utils': 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) - '@typescript-eslint/utils': 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 8.12.2 - eslint: 9.13.0(jiti@1.21.6) + '@typescript-eslint/parser': 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.13.0 + '@typescript-eslint/type-utils': 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/utils': 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.13.0 + eslint: 9.14.0(jiti@1.21.6) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 1.4.0(typescript@5.6.3) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3)': + '@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3)': dependencies: - '@typescript-eslint/scope-manager': 8.12.2 - '@typescript-eslint/types': 8.12.2 - '@typescript-eslint/typescript-estree': 8.12.2(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 8.12.2 + '@typescript-eslint/scope-manager': 8.13.0 + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.13.0 debug: 4.3.7 - eslint: 9.13.0(jiti@1.21.6) + eslint: 9.14.0(jiti@1.21.6) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.12.2': + '@typescript-eslint/scope-manager@8.13.0': dependencies: - '@typescript-eslint/types': 8.12.2 - '@typescript-eslint/visitor-keys': 8.12.2 + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/visitor-keys': 8.13.0 - '@typescript-eslint/type-utils@8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3)': + '@typescript-eslint/type-utils@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.12.2(typescript@5.6.3) - '@typescript-eslint/utils': 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.6.3) + '@typescript-eslint/utils': 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) debug: 4.3.7 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 1.4.0(typescript@5.6.3) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: - eslint - supports-color - '@typescript-eslint/types@8.12.2': {} + '@typescript-eslint/types@8.13.0': {} - '@typescript-eslint/typescript-estree@8.12.2(typescript@5.6.3)': + '@typescript-eslint/typescript-estree@8.13.0(typescript@5.6.3)': dependencies: - '@typescript-eslint/types': 8.12.2 - '@typescript-eslint/visitor-keys': 8.12.2 + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/visitor-keys': 8.13.0 debug: 4.3.7 fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 1.4.0(typescript@5.6.3) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3)': + '@typescript-eslint/utils@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.13.0(jiti@1.21.6)) - '@typescript-eslint/scope-manager': 8.12.2 - '@typescript-eslint/types': 8.12.2 - '@typescript-eslint/typescript-estree': 8.12.2(typescript@5.6.3) - eslint: 9.13.0(jiti@1.21.6) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.14.0(jiti@1.21.6)) + '@typescript-eslint/scope-manager': 8.13.0 + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.6.3) + eslint: 9.14.0(jiti@1.21.6) transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@8.12.2': + '@typescript-eslint/visitor-keys@8.13.0': dependencies: - '@typescript-eslint/types': 8.12.2 + '@typescript-eslint/types': 8.13.0 eslint-visitor-keys: 3.4.3 - '@unocss/astro@0.61.9(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6))': + '@unocss/astro@0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6))': dependencies: '@unocss/core': 0.61.9 '@unocss/reset': 0.61.9 - '@unocss/vite': 0.61.9(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) + '@unocss/vite': 0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) optionalDependencies: - vite: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) transitivePeerDependencies: - rollup - supports-color - '@unocss/cli@0.61.9(rollup@4.24.3)': + '@unocss/cli@0.61.9(rollup@4.24.4)': dependencies: '@ampproject/remapping': 2.3.0 - '@rollup/pluginutils': 5.1.0(rollup@4.24.3) + '@rollup/pluginutils': 5.1.0(rollup@4.24.4) '@unocss/config': 0.61.9 '@unocss/core': 0.61.9 '@unocss/preset-uno': 0.61.9 @@ -3391,10 +3380,10 @@ snapshots: dependencies: '@unocss/core': 0.61.9 - '@unocss/vite@0.61.9(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6))': + '@unocss/vite@0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6))': dependencies: '@ampproject/remapping': 2.3.0 - '@rollup/pluginutils': 5.1.0(rollup@4.24.3) + '@rollup/pluginutils': 5.1.0(rollup@4.24.4) '@unocss/config': 0.61.9 '@unocss/core': 0.61.9 '@unocss/inspector': 0.61.9 @@ -3403,7 +3392,7 @@ snapshots: chokidar: 3.6.0 fast-glob: 3.3.2 magic-string: 0.30.11 - vite: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) transitivePeerDependencies: - rollup - supports-color @@ -3452,9 +3441,9 @@ snapshots: dependencies: svelte: 4.2.19 - acorn-jsx@5.3.2(acorn@8.13.0): + acorn-jsx@5.3.2(acorn@8.14.0): dependencies: - acorn: 8.13.0 + acorn: 8.14.0 acorn-walk@8.3.3: dependencies: @@ -3462,7 +3451,7 @@ snapshots: acorn@8.12.1: {} - acorn@8.13.0: {} + acorn@8.14.0: {} ajv@6.12.6: dependencies: @@ -3540,7 +3529,7 @@ snapshots: capnp-ts@0.7.0: dependencies: debug: 4.3.7 - tslib: 2.8.0 + tslib: 2.8.1 transitivePeerDependencies: - supports-color @@ -3738,35 +3727,35 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@9.1.0(eslint@9.13.0(jiti@1.21.6)): + eslint-config-prettier@9.1.0(eslint@9.14.0(jiti@1.21.6)): dependencies: - eslint: 9.13.0(jiti@1.21.6) + eslint: 9.14.0(jiti@1.21.6) eslint-plugin-security@3.0.1: dependencies: safe-regex: 2.1.1 - eslint-scope@8.1.0: + eslint-scope@8.2.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 eslint-visitor-keys@3.4.3: {} - eslint-visitor-keys@4.1.0: {} + eslint-visitor-keys@4.2.0: {} - eslint@9.13.0(jiti@1.21.6): + eslint@9.14.0(jiti@1.21.6): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) - '@eslint-community/regexpp': 4.11.1 + '@eslint-community/eslint-utils': 4.4.1(eslint@9.14.0(jiti@1.21.6)) + '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.18.0 '@eslint/core': 0.7.0 '@eslint/eslintrc': 3.1.0 - '@eslint/js': 9.13.0 - '@eslint/plugin-kit': 0.2.1 - '@humanfs/node': 0.16.5 + '@eslint/js': 9.14.0 + '@eslint/plugin-kit': 0.2.2 + '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/retry': 0.4.1 '@types/estree': 1.0.6 '@types/json-schema': 7.0.15 ajv: 6.12.6 @@ -3774,9 +3763,9 @@ snapshots: cross-spawn: 7.0.3 debug: 4.3.7 escape-string-regexp: 4.0.0 - eslint-scope: 8.1.0 - eslint-visitor-keys: 4.1.0 - espree: 10.2.0 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -3797,11 +3786,11 @@ snapshots: transitivePeerDependencies: - supports-color - espree@10.2.0: + espree@10.3.0: dependencies: - acorn: 8.13.0 - acorn-jsx: 5.3.2(acorn@8.13.0) - eslint-visitor-keys: 4.1.0 + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 esquery@1.6.0: dependencies: @@ -3909,7 +3898,7 @@ snapshots: globals@14.0.0: {} - globals@15.11.0: {} + globals@15.12.0: {} graphemer@1.4.0: {} @@ -4254,28 +4243,28 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.22.4 fsevents: 2.3.3 - rollup@4.24.3: + rollup@4.24.4: dependencies: '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.24.3 - '@rollup/rollup-android-arm64': 4.24.3 - '@rollup/rollup-darwin-arm64': 4.24.3 - '@rollup/rollup-darwin-x64': 4.24.3 - '@rollup/rollup-freebsd-arm64': 4.24.3 - '@rollup/rollup-freebsd-x64': 4.24.3 - '@rollup/rollup-linux-arm-gnueabihf': 4.24.3 - '@rollup/rollup-linux-arm-musleabihf': 4.24.3 - '@rollup/rollup-linux-arm64-gnu': 4.24.3 - '@rollup/rollup-linux-arm64-musl': 4.24.3 - '@rollup/rollup-linux-powerpc64le-gnu': 4.24.3 - '@rollup/rollup-linux-riscv64-gnu': 4.24.3 - '@rollup/rollup-linux-s390x-gnu': 4.24.3 - '@rollup/rollup-linux-x64-gnu': 4.24.3 - '@rollup/rollup-linux-x64-musl': 4.24.3 - '@rollup/rollup-win32-arm64-msvc': 4.24.3 - '@rollup/rollup-win32-ia32-msvc': 4.24.3 - '@rollup/rollup-win32-x64-msvc': 4.24.3 + '@rollup/rollup-android-arm-eabi': 4.24.4 + '@rollup/rollup-android-arm64': 4.24.4 + '@rollup/rollup-darwin-arm64': 4.24.4 + '@rollup/rollup-darwin-x64': 4.24.4 + '@rollup/rollup-freebsd-arm64': 4.24.4 + '@rollup/rollup-freebsd-x64': 4.24.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.24.4 + '@rollup/rollup-linux-arm-musleabihf': 4.24.4 + '@rollup/rollup-linux-arm64-gnu': 4.24.4 + '@rollup/rollup-linux-arm64-musl': 4.24.4 + '@rollup/rollup-linux-powerpc64le-gnu': 4.24.4 + '@rollup/rollup-linux-riscv64-gnu': 4.24.4 + '@rollup/rollup-linux-s390x-gnu': 4.24.4 + '@rollup/rollup-linux-x64-gnu': 4.24.4 + '@rollup/rollup-linux-x64-musl': 4.24.4 + '@rollup/rollup-win32-arm64-msvc': 4.24.4 + '@rollup/rollup-win32-ia32-msvc': 4.24.4 + '@rollup/rollup-win32-x64-msvc': 4.24.4 fsevents: 2.3.3 run-parallel@1.2.0: @@ -4412,11 +4401,11 @@ snapshots: totalist@3.0.1: {} - ts-api-utils@1.3.0(typescript@5.6.3): + ts-api-utils@1.4.0(typescript@5.6.3): dependencies: typescript: 5.6.3 - tslib@2.8.0: {} + tslib@2.8.1: {} tsx@4.17.0: dependencies: @@ -4429,11 +4418,11 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3): + typescript-eslint@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.12.2(@typescript-eslint/parser@8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) - '@typescript-eslint/parser': 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) - '@typescript-eslint/utils': 8.12.2(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/eslint-plugin': 8.13.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/parser': 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/utils': 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: @@ -4465,10 +4454,10 @@ snapshots: pathe: 1.1.2 ufo: 1.5.4 - unocss@0.61.9(postcss@8.4.47)(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)): + unocss@0.61.9(postcss@8.4.47)(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)): dependencies: - '@unocss/astro': 0.61.9(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) - '@unocss/cli': 0.61.9(rollup@4.24.3) + '@unocss/astro': 0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) + '@unocss/cli': 0.61.9(rollup@4.24.4) '@unocss/core': 0.61.9 '@unocss/extractor-arbitrary-variants': 0.61.9 '@unocss/postcss': 0.61.9(postcss@8.4.47) @@ -4486,9 +4475,9 @@ snapshots: '@unocss/transformer-compile-class': 0.61.9 '@unocss/transformer-directives': 0.61.9 '@unocss/transformer-variant-group': 0.61.9 - '@unocss/vite': 0.61.9(rollup@4.24.3)(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)) + '@unocss/vite': 0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) optionalDependencies: - vite: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) transitivePeerDependencies: - postcss - rollup @@ -4525,7 +4514,7 @@ snapshots: dependencies: esbuild: 0.21.5 postcss: 8.4.47 - rollup: 4.24.3 + rollup: 4.24.4 optionalDependencies: '@types/node': 20.16.1 fsevents: 2.3.3 @@ -4543,20 +4532,20 @@ snapshots: sass: 1.77.8 terser: 5.31.6 - vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6): + vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6): dependencies: esbuild: 0.21.5 postcss: 8.4.47 rollup: 4.22.4 optionalDependencies: - '@types/node': 20.17.3 + '@types/node': 20.17.6 fsevents: 2.3.3 sass: 1.77.8 terser: 5.31.6 - vitefu@0.2.5(vite@5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6)): + vitefu@0.2.5(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)): optionalDependencies: - vite: 5.4.7(@types/node@20.17.3)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) vitest@2.1.1(@types/node@20.16.1)(sass@1.77.8)(terser@5.31.6): dependencies: From 15d6515eb12ffa9dd61d3078aea30dcb79c7828c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 09:54:52 -0300 Subject: [PATCH 26/51] chore(deps) Update dependency @types/node to v22 (dev) (#11545) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/api/package.json | 2 +- pnpm-lock.yaml | 58 +++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/api/package.json b/packages/api/package.json index 829a6c433a53..2c5ff093c80f 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -48,7 +48,7 @@ "@rollup/plugin-terser": "0.4.4", "@rollup/plugin-typescript": "12.1.1", "@types/eslint": "^9.0.0", - "@types/node": "20.17.6", + "@types/node": "22.9.0", "eslint": "^9.4.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-security": "3.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e42d26e23c35..1b12458e13c9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,7 +39,7 @@ importers: version: 1.1.14 '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) + version: 3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6)) '@unocss/extractor-svelte': specifier: ^0.61.0 version: 0.61.9 @@ -48,10 +48,10 @@ importers: version: 4.2.19 unocss: specifier: ^0.61.0 - version: 0.61.9(postcss@8.4.47)(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) + version: 0.61.9(postcss@8.4.47)(rollup@4.24.4)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6)) vite: specifier: ^5.4.7 - version: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) + version: 5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6) examples/file-associations: {} @@ -72,8 +72,8 @@ importers: specifier: ^9.0.0 version: 9.6.1 '@types/node': - specifier: 20.17.6 - version: 20.17.6 + specifier: 22.9.0 + version: 22.9.0 eslint: specifier: ^9.4.0 version: 9.14.0(jiti@1.21.6) @@ -1076,8 +1076,8 @@ packages: '@types/node@20.16.1': resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==} - '@types/node@20.17.6': - resolution: {integrity: sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==} + '@types/node@22.9.0': + resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==} '@typescript-eslint/eslint-plugin@8.13.0': resolution: {integrity: sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg==} @@ -3108,26 +3108,26 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.24.4': optional: true - '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)))(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6))': + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6)))(svelte@4.2.19)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6)) debug: 4.3.6 svelte: 4.2.19 - vite: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6))': + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)))(svelte@4.2.19)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6)))(svelte@4.2.19)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6)) debug: 4.3.6 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.11 svelte: 4.2.19 svelte-hmr: 0.16.0(svelte@4.2.19) - vite: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) - vitefu: 0.2.5(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) + vite: 5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6) + vitefu: 0.2.5(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6)) transitivePeerDependencies: - supports-color @@ -3144,13 +3144,13 @@ snapshots: '@types/node-forge@1.3.11': dependencies: - '@types/node': 20.17.6 + '@types/node': 22.9.0 '@types/node@20.16.1': dependencies: undici-types: 6.19.8 - '@types/node@20.17.6': + '@types/node@22.9.0': dependencies: undici-types: 6.19.8 @@ -3235,13 +3235,13 @@ snapshots: '@typescript-eslint/types': 8.13.0 eslint-visitor-keys: 3.4.3 - '@unocss/astro@0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6))': + '@unocss/astro@0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6))': dependencies: '@unocss/core': 0.61.9 '@unocss/reset': 0.61.9 - '@unocss/vite': 0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) + '@unocss/vite': 0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6)) optionalDependencies: - vite: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6) transitivePeerDependencies: - rollup - supports-color @@ -3380,7 +3380,7 @@ snapshots: dependencies: '@unocss/core': 0.61.9 - '@unocss/vite@0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6))': + '@unocss/vite@0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6))': dependencies: '@ampproject/remapping': 2.3.0 '@rollup/pluginutils': 5.1.0(rollup@4.24.4) @@ -3392,7 +3392,7 @@ snapshots: chokidar: 3.6.0 fast-glob: 3.3.2 magic-string: 0.30.11 - vite: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6) transitivePeerDependencies: - rollup - supports-color @@ -4454,9 +4454,9 @@ snapshots: pathe: 1.1.2 ufo: 1.5.4 - unocss@0.61.9(postcss@8.4.47)(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)): + unocss@0.61.9(postcss@8.4.47)(rollup@4.24.4)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6)): dependencies: - '@unocss/astro': 0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) + '@unocss/astro': 0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6)) '@unocss/cli': 0.61.9(rollup@4.24.4) '@unocss/core': 0.61.9 '@unocss/extractor-arbitrary-variants': 0.61.9 @@ -4475,9 +4475,9 @@ snapshots: '@unocss/transformer-compile-class': 0.61.9 '@unocss/transformer-directives': 0.61.9 '@unocss/transformer-variant-group': 0.61.9 - '@unocss/vite': 0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)) + '@unocss/vite': 0.61.9(rollup@4.24.4)(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6)) optionalDependencies: - vite: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6) transitivePeerDependencies: - postcss - rollup @@ -4532,20 +4532,20 @@ snapshots: sass: 1.77.8 terser: 5.31.6 - vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6): + vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6): dependencies: esbuild: 0.21.5 postcss: 8.4.47 rollup: 4.22.4 optionalDependencies: - '@types/node': 20.17.6 + '@types/node': 22.9.0 fsevents: 2.3.3 sass: 1.77.8 terser: 5.31.6 - vitefu@0.2.5(vite@5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6)): + vitefu@0.2.5(vite@5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6)): optionalDependencies: - vite: 5.4.7(@types/node@20.17.6)(sass@1.77.8)(terser@5.31.6) + vite: 5.4.7(@types/node@22.9.0)(sass@1.77.8)(terser@5.31.6) vitest@2.1.1(@types/node@20.16.1)(sass@1.77.8)(terser@5.31.6): dependencies: From 37814291475814b4a24cc77b6fa457ec9ba7a779 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 6 Nov 2024 16:41:13 +0300 Subject: [PATCH 27/51] enhance: always check parent directory (fix #8679) (#11429) * enhance: always check parent directory (fix #8679) * Update crates/tauri-utils/src/platform.rs * add change file * fix crate --------- Co-authored-by: Lucas Fernandes Nogueira --- .changes/enhance-resource-dir-linux.md | 5 +++++ crates/tauri-utils/src/platform.rs | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 .changes/enhance-resource-dir-linux.md diff --git a/.changes/enhance-resource-dir-linux.md b/.changes/enhance-resource-dir-linux.md new file mode 100644 index 000000000000..c528bad12467 --- /dev/null +++ b/.changes/enhance-resource-dir-linux.md @@ -0,0 +1,5 @@ +--- +"tauri-utils": patch:bug +--- + +Enhance resource directory resolution to support running on distros like NixOS. diff --git a/crates/tauri-utils/src/platform.rs b/crates/tauri-utils/src/platform.rs index 162539c9692b..7a9c99431ed5 100644 --- a/crates/tauri-utils/src/platform.rs +++ b/crates/tauri-utils/src/platform.rs @@ -309,12 +309,12 @@ fn resource_dir_from>( #[cfg(target_os = "linux")] { - res = if curr_dir.ends_with("/data/usr/bin") { - // running from the deb bundle dir - exe_dir - .join(format!("../lib/{}", package_info.name)) - .canonicalize() - .map_err(Into::into) + // (canonicalize checks for existence, so there's no need for an extra check) + res = if let Ok(bundle_dir) = exe_dir + .join(format!("../lib/{}", package_info.name)) + .canonicalize() + { + Ok(bundle_dir) } else if let Some(appdir) = &env.appdir { let appdir: &std::path::Path = appdir.as_ref(); Ok(PathBuf::from(format!( From 6b3c82aa90f425fce0ebb5863a332c44865ea1ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:41:34 -0300 Subject: [PATCH 28/51] chore(deps) Update Tauri macOSSign (dev) (#11541) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 485 +++++++++-------------------- crates/tauri-macos-sign/Cargo.toml | 4 +- 2 files changed, 155 insertions(+), 334 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 82518943c0b1..1b566e108787 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,32 +237,32 @@ dependencies = [ [[package]] name = "app-store-connect" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33fb5489b9bfcfa3aec2f68cc79eafb999b5af9b9d9d70ca8dfe36acdd1b2b05" +checksum = "61321685c26bccddbeaa34d9d0108db01c7cf00bcc0fe06921fd47af26e17979" dependencies = [ "anyhow", - "base64 0.21.7", + "base64 0.22.1", "clap", "dirs", - "env_logger 0.10.2", + "env_logger 0.11.5", "jsonwebtoken", "log", "pem", "rand 0.8.5", - "reqwest 0.11.27", + "reqwest", "rsa", "serde", "serde_json", "thiserror", - "x509-certificate", + "x509-certificate 0.24.0", ] [[package]] name = "apple-bundles" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb7c27ee2ca7826adfdc84228cd4c5a84ab57b0a11d269d1d7cd0615238e5a2" +checksum = "1b06f1e42dc02f590067deabd5ecb3b8fdc13c6432d72670431614de9770832b" dependencies = [ "anyhow", "plist", @@ -272,9 +272,9 @@ dependencies = [ [[package]] name = "apple-codesign" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "329820aac7259ca0529d3cc21dd3b4c11651225dfce9e0ce25b121b23f923164" +checksum = "256649c0fce3d8628a0957235db4276bdec01fbec8dd57f5300cdda400dfe4a7" dependencies = [ "anyhow", "app-store-connect", @@ -285,7 +285,7 @@ dependencies = [ "aws-sdk-s3", "aws-smithy-http", "aws-smithy-types", - "base64 0.21.7", + "base64 0.22.1", "bcder", "bitflags 2.6.0", "bytes", @@ -298,7 +298,7 @@ dependencies = [ "digest", "dirs", "elliptic-curve 0.13.8", - "env_logger 0.10.2", + "env_logger 0.11.5", "figment", "filetime", "glob", @@ -308,7 +308,7 @@ dependencies = [ "md-5", "minicbor", "num-traits", - "object 0.32.2", + "object", "oid-registry", "once_cell", "p12", @@ -321,7 +321,7 @@ dependencies = [ "rasn", "rayon", "regex", - "reqwest 0.11.27", + "reqwest", "ring", "rsa", "scroll", @@ -340,25 +340,25 @@ dependencies = [ "tempfile", "thiserror", "tokio", - "tungstenite 0.21.0", + "tungstenite", "uuid", "walkdir", "widestring", - "windows-sys 0.52.0", + "windows-sys 0.59.0", "x509", - "x509-certificate", + "x509-certificate 0.24.0", "xml-rs", "yasna", "zeroize", - "zip 0.6.6", + "zip", "zip_structs", ] [[package]] name = "apple-flat-package" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6adc520e05304de5ec383487786fa20e9c636fe972e59719cdd93621a2db6f1" +checksum = "500b3e2ffc3e0839ef621a5a5bf8f1b5a54cee3d2a1b6fcdecdc6aba489c2f50" dependencies = [ "apple-xar", "cpio-archive", @@ -371,11 +371,11 @@ dependencies = [ [[package]] name = "apple-xar" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "844e00dc1e665b3cf0bba745aa9c6464292ca512db0c11384511586701eb0335" +checksum = "47d3fc5c875778d33991009f508004f7c9e47c62e326bf9d5e4513482efc4147" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "bcder", "bzip2", "chrono", @@ -385,7 +385,7 @@ dependencies = [ "log", "md-5", "rand 0.8.5", - "reqwest 0.11.27", + "reqwest", "scroll", "serde", "serde-xml-rs", @@ -394,7 +394,7 @@ dependencies = [ "signature 2.2.0", "thiserror", "url", - "x509-certificate", + "x509-certificate 0.24.0", "xml-rs", "xz2", ] @@ -457,9 +457,9 @@ checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" [[package]] name = "asn1-rs" -version = "0.5.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" dependencies = [ "asn1-rs-derive", "asn1-rs-impl", @@ -472,25 +472,25 @@ dependencies = [ [[package]] name = "asn1-rs-derive" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", - "synstructure 0.12.6", + "syn 2.0.87", + "synstructure", ] [[package]] name = "asn1-rs-impl" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.87", ] [[package]] @@ -579,9 +579,9 @@ dependencies = [ [[package]] name = "aws-config" -version = "1.5.5" +version = "1.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e95816a168520d72c0e7680c405a5a8c1fb6a035b4bc4b9d7b0de8e1a941697" +checksum = "2d6448cfb224dd6a9b9ac734f58622dd0d4751f3589f3b777345745f46b2eb14" dependencies = [ "aws-credential-types", "aws-runtime", @@ -682,9 +682,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.39.0" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11822090cf501c316c6f75711d77b96fba30658e3867a7762e5e2f5d32d31e81" +checksum = "ded855583fa1d22e88fe39fd6062b062376e50a8211989e07cf5e38d52eb3453" dependencies = [ "aws-credential-types", "aws-runtime", @@ -704,9 +704,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.40.0" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78a2a06ff89176123945d1bbe865603c4d7101bea216a550bb4d2e4e9ba74d74" +checksum = "9177ea1192e6601ae16c7273385690d88a7ed386a00b74a6bc894d12103cd933" dependencies = [ "aws-credential-types", "aws-runtime", @@ -726,9 +726,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.39.0" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20a91795850826a6f456f4a48eff1dfa59a0e69bdbf5b8c50518fd372106574" +checksum = "823ef553cf36713c97453e2ddff1eb8f62be7f4523544e2a5db64caf80100f0a" dependencies = [ "aws-credential-types", "aws-runtime", @@ -861,9 +861,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.7.1" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1ce695746394772e7000b39fe073095db6d45a862d0767dd5ad0ac0d7f8eb87" +checksum = "be28bd063fa91fd871d131fc8b68d7cd4c5fa0869bea68daca50dcb1cbd76be2" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -905,9 +905,9 @@ dependencies = [ [[package]] name = "aws-smithy-types" -version = "1.2.7" +version = "1.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147100a7bea70fa20ef224a6bad700358305f5dc0f84649c53769761395b355b" +checksum = "4fbd94a32b3a7d55d3806fe27d98d3ad393050439dd05eb53ece36ec5e3d3510" dependencies = [ "base64-simd", "bytes", @@ -1020,7 +1020,7 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide 0.8.0", - "object 0.36.4", + "object", "rustc-demangle", "windows-targets 0.52.6", ] @@ -1383,9 +1383,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" dependencies = [ "serde", ] @@ -1504,7 +1504,7 @@ dependencies = [ "ureq", "which 6.0.3", "windows", - "x509-certificate", + "x509-certificate 0.23.1", ] [[package]] @@ -1979,9 +1979,9 @@ checksum = "80e3adec7390c7643049466136117057188edf5f23efc5c8b4fc8079c8dc34a6" [[package]] name = "cpio-archive" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63d5133d716d3d82da8c76367ddb0ab1733e2629f1462e4f39947e13b8b4b741" +checksum = "f11d34b07689c21889fc89bd7cc885b3244b0157bbededf4a1c159832cd0df05" dependencies = [ "chrono", "is_executable", @@ -2099,19 +2099,19 @@ dependencies = [ [[package]] name = "cryptographic-message-syntax" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c324ba1028cef7e3a71a00cbf585637bb0215dec2f6a2b566d094190a1309b" +checksum = "97a99e58d7755c646cb3f2a138d99f90da4c495282e1700b82daff8a48759ce0" dependencies = [ "bcder", "bytes", "chrono", "hex", "pem", - "reqwest 0.11.27", + "reqwest", "ring", "signature 2.2.0", - "x509-certificate", + "x509-certificate 0.24.0", ] [[package]] @@ -2494,12 +2494,6 @@ dependencies = [ "syn 2.0.87", ] -[[package]] -name = "doc-comment" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" - [[package]] name = "dpi" version = "0.1.1" @@ -2691,7 +2685,7 @@ dependencies = [ "rustc_version", "toml 0.8.19", "vswhom", - "winreg 0.52.0", + "winreg", ] [[package]] @@ -2763,19 +2757,6 @@ dependencies = [ "regex", ] -[[package]] -name = "env_logger" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - [[package]] name = "env_logger" version = "0.11.5" @@ -2968,6 +2949,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + [[package]] name = "fontconfig-parser" version = "0.5.7" @@ -3462,9 +3449,9 @@ dependencies = [ [[package]] name = "goblin" -version = "0.8.2" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b363a30c165f666402fe6a3024d3bec7ebc898f96a4a23bd1c99f8dbf3f4f47" +checksum = "53ab3f32d1d77146981dea5d6b1e8fe31eedcb7013e5e00d6ccd1259a4b4d923" dependencies = [ "log", "plain", @@ -3632,6 +3619,9 @@ name = "hashbrown" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +dependencies = [ + "foldhash", +] [[package]] name = "heck" @@ -3651,12 +3641,6 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - [[package]] name = "hex" version = "0.4.3" @@ -3856,11 +3840,12 @@ dependencies = [ "hyper 1.4.1", "hyper-util", "rustls 0.23.13", + "rustls-native-certs 0.8.0", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", "tower-service", - "webpki-roots 0.26.6", + "webpki-roots", ] [[package]] @@ -4289,7 +4274,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", "windows-sys 0.48.0", ] @@ -4300,22 +4285,11 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" -[[package]] -name = "is-terminal" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" -dependencies = [ - "hermit-abi 0.4.0", - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "is_executable" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ba3d8548b8b04dafdf2f4cc6f5e379db766d0a6d9aac233ad4c9a92ea892233" +checksum = "d4a1b5bad6f9072935961dfbf1cced2f3d129963d091b6f69f007fe04e758ae2" dependencies = [ "winapi", ] @@ -4341,15 +4315,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071ed4cc1afd86650602c7b11aa2e1ce30762a1c27193201cb5cee9c6ebb1294" -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.12.1" @@ -4658,7 +4623,7 @@ dependencies = [ "parking_lot", "percent-encoding", "regex", - "reqwest 0.12.8", + "reqwest", "serde", "serde_json", "time", @@ -4681,12 +4646,6 @@ dependencies = [ "simple_asn1", ] -[[package]] -name = "jzon" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ab85f84ca42c5ec520e6f3c9966ba1fd62909ce260f8837e248857d2560509" - [[package]] name = "k256" version = "0.13.4" @@ -5123,22 +5082,22 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "minicbor" -version = "0.20.0" +version = "0.24.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d15f4203d71fdf90903c2696e55426ac97a363c67b218488a73b534ce7aca10" +checksum = "29be4f60e41fde478b36998b88821946aafac540e53591e76db53921a0cc225b" dependencies = [ "minicbor-derive", ] [[package]] name = "minicbor-derive" -version = "0.13.0" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1154809406efdb7982841adb6311b3d095b46f78342dd646736122fe6b19e267" +checksum = "bd2209fff77f705b00c737016a48e73733d7fbccb8b007194db148f03561fb70" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.87", ] [[package]] @@ -5195,7 +5154,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", @@ -5816,27 +5775,18 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "crc32fast", "flate2", - "hashbrown 0.14.5", + "hashbrown 0.15.0", "indexmap 2.6.0", "memchr", "ruzstd", ] -[[package]] -name = "object" -version = "0.36.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" -dependencies = [ - "memchr", -] - [[package]] name = "ocb3" version = "0.1.0" @@ -5851,9 +5801,9 @@ dependencies = [ [[package]] name = "oid-registry" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" dependencies = [ "asn1-rs", ] @@ -5870,12 +5820,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.1" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" @@ -6672,12 +6619,6 @@ dependencies = [ "universal-hash", ] -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - [[package]] name = "powerfmt" version = "0.2.0" @@ -7064,9 +7005,9 @@ dependencies = [ [[package]] name = "rasn" -version = "0.12.5" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9b0d03fbc7d2dcfdd35086c43ce30ac5ff62ed7eff4397e4f4f2995a2b0e2a" +checksum = "e442690f86da40561d5548e7ffb4a18af90d1c1b3536090de847ca2d5a3a6426" dependencies = [ "arrayvec", "bitvec", @@ -7074,7 +7015,7 @@ dependencies = [ "bytes", "chrono", "either", - "jzon", + "hashbrown 0.14.5", "konst", "nom", "num-bigint", @@ -7082,21 +7023,22 @@ dependencies = [ "num-traits", "once_cell", "rasn-derive", + "serde_json", "snafu", ] [[package]] name = "rasn-derive" -version = "0.12.5" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbaf7105cd254b632f4732fbcc243ce750cef87d8335826125ef6df5733b5a0c" +checksum = "96b0d374c7e4e985e6bc97ca7e7ad1d9642a8415db2017777d6e383002edaab2" dependencies = [ "either", - "itertools 0.10.5", + "itertools 0.13.0", "proc-macro2", "quote", "rayon", - "syn 1.0.109", + "syn 2.0.87", "uuid", ] @@ -7251,57 +7193,16 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.30", - "hyper-rustls 0.24.2", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.21.12", - "rustls-native-certs 0.6.3", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration", - "tokio", - "tokio-rustls 0.24.1", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots 0.25.4", - "winreg 0.50.0", -] - -[[package]] -name = "reqwest" -version = "0.12.8" +version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ "base64 0.22.1", "bytes", "futures-channel", "futures-core", "futures-util", + "h2 0.4.6", "http 1.1.0", "http-body 1.0.1", "http-body-util", @@ -7319,6 +7220,7 @@ dependencies = [ "pin-project-lite", "quinn", "rustls 0.23.13", + "rustls-native-certs 0.8.0", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", @@ -7335,7 +7237,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.26.6", + "webpki-roots", "windows-registry 0.2.0", ] @@ -7625,20 +7527,6 @@ dependencies = [ "sct", ] -[[package]] -name = "rustls" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" -dependencies = [ - "log", - "ring", - "rustls-pki-types", - "rustls-webpki 0.102.8", - "subtle", - "zeroize", -] - [[package]] name = "rustls" version = "0.23.13" @@ -7679,6 +7567,19 @@ dependencies = [ "security-framework", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" +dependencies = [ + "openssl-probe", + "rustls-pemfile 2.2.0", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -7762,12 +7663,10 @@ dependencies = [ [[package]] name = "ruzstd" -version = "0.5.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d" +checksum = "99c3938e133aac070997ddc684d4b393777d293ba170f2988c8fd5ea2ad4ce21" dependencies = [ - "byteorder", - "derive_more", "twox-hash", ] @@ -8453,25 +8352,23 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" [[package]] name = "snafu" -version = "0.7.5" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6" +checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" dependencies = [ - "backtrace", - "doc-comment", "snafu-derive", ] [[package]] name = "snafu-derive" -version = "0.7.5" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf" +checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.87", ] [[package]] @@ -8848,18 +8745,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", -] - [[package]] name = "synstructure" version = "0.13.1" @@ -8884,27 +8769,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "system-deps" version = "6.2.2" @@ -9025,7 +8889,7 @@ dependencies = [ "quickcheck", "quickcheck_macros", "raw-window-handle", - "reqwest 0.12.8", + "reqwest", "serde", "serde_json", "serde_repr", @@ -9114,7 +8978,7 @@ dependencies = [ "walkdir", "windows-registry 0.3.0", "windows-sys 0.59.0", - "zip 2.2.0", + "zip", ] [[package]] @@ -9161,7 +9025,7 @@ dependencies = [ "minisign", "notify", "notify-debouncer-mini", - "object 0.36.4", + "object", "os_info", "os_pipe", "oxc_allocator", @@ -9288,7 +9152,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "x509-certificate", + "x509-certificate 0.24.0", ] [[package]] @@ -9584,15 +9448,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - [[package]] name = "terminal_size" version = "0.2.6" @@ -9751,9 +9606,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", "bytes", @@ -9830,7 +9685,7 @@ dependencies = [ "futures-util", "log", "tokio", - "tungstenite 0.24.0", + "tungstenite", ] [[package]] @@ -10029,28 +9884,6 @@ dependencies = [ "core_maths", ] -[[package]] -name = "tungstenite" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http 1.1.0", - "httparse", - "log", - "rand 0.8.5", - "rustls 0.22.4", - "rustls-native-certs 0.7.3", - "rustls-pki-types", - "sha1", - "thiserror", - "url", - "utf-8", -] - [[package]] name = "tungstenite" version = "0.24.0" @@ -10064,6 +9897,9 @@ dependencies = [ "httparse", "log", "rand 0.8.5", + "rustls 0.23.13", + "rustls-native-certs 0.7.3", + "rustls-pki-types", "sha1", "thiserror", "utf-8", @@ -10252,12 +10088,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "universal-hash" version = "0.5.1" @@ -10295,7 +10125,7 @@ dependencies = [ "rustls-pki-types", "socks", "url", - "webpki-roots 0.26.6", + "webpki-roots", ] [[package]] @@ -10667,12 +10497,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "webpki-roots" version = "0.26.6" @@ -11144,16 +10968,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "winreg" version = "0.52.0" @@ -11370,6 +11184,25 @@ dependencies = [ "zeroize", ] +[[package]] +name = "x509-certificate" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57b9f8bcae7c1f36479821ae826d75050c60ce55146fd86d3553ed2573e2762" +dependencies = [ + "bcder", + "bytes", + "chrono", + "der 0.7.9", + "hex", + "pem", + "ring", + "signature 2.2.0", + "spki 0.7.3", + "thiserror", + "zeroize", +] + [[package]] name = "xattr" version = "1.3.1" @@ -11441,7 +11274,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.87", - "synstructure 0.13.1", + "synstructure", ] [[package]] @@ -11483,7 +11316,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.87", - "synstructure 0.13.1", + "synstructure", ] [[package]] @@ -11528,18 +11361,6 @@ dependencies = [ "syn 2.0.87", ] -[[package]] -name = "zip" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" -dependencies = [ - "byteorder", - "crc32fast", - "crossbeam-utils", - "flate2", -] - [[package]] name = "zip" version = "2.2.0" diff --git a/crates/tauri-macos-sign/Cargo.toml b/crates/tauri-macos-sign/Cargo.toml index 8fd33172827c..f293263219a9 100644 --- a/crates/tauri-macos-sign/Cargo.toml +++ b/crates/tauri-macos-sign/Cargo.toml @@ -14,13 +14,13 @@ anyhow = "1" serde = { version = "1", features = ["derive"] } serde_json = "1" tempfile = "3" -x509-certificate = "0.23" +x509-certificate = "0.24" once-cell-regex = "0.2" os_pipe = "1" plist = "1" rand = "0.8" dirs-next = "2" log = { version = "0.4.21", features = ["kv"] } -apple-codesign = "0.27" +apple-codesign = "0.28" chrono = "0.4.38" p12 = "0.6" From fabc2f283e38b62c721326e44645d47138418cbc Mon Sep 17 00:00:00 2001 From: 39zde <168634234+39zde@users.noreply.github.com> Date: Wed, 6 Nov 2024 14:16:46 +0000 Subject: [PATCH 29/51] feat: add HeaderConfig to SecurityConfig (#11485) --- .changes/add-headers-config-option.md | 5 + Cargo.lock | 1 + crates/tauri-cli/config.schema.json | 173 +++++++++ crates/tauri-cli/schema.json | 2 +- .../schemas/config.schema.json | 173 +++++++++ crates/tauri-utils/Cargo.toml | 1 + crates/tauri-utils/src/config.rs | 340 +++++++++++++++++- crates/tauri/src/protocol/isolation.rs | 6 +- crates/tauri/src/protocol/tauri.rs | 5 +- .../test/fixture/src-tauri/tauri.conf.json | 3 +- 10 files changed, 704 insertions(+), 5 deletions(-) create mode 100644 .changes/add-headers-config-option.md diff --git a/.changes/add-headers-config-option.md b/.changes/add-headers-config-option.md new file mode 100644 index 000000000000..67da5948ffea --- /dev/null +++ b/.changes/add-headers-config-option.md @@ -0,0 +1,5 @@ +--- +"tauri-utils": 'minor:feat' +"tauri": 'minor:feat' +--- +Adds a new configuration option `app > security > headers` to define headers that will be added to every http response from tauri to the web view. This doesn't include IPC messages and error responses. diff --git a/Cargo.lock b/Cargo.lock index 1b566e108787..c8242e097152 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9376,6 +9376,7 @@ dependencies = [ "getrandom 0.2.15", "glob", "html5ever", + "http 1.1.0", "infer 0.16.0", "json-patch 3.0.1", "json5", diff --git a/crates/tauri-cli/config.schema.json b/crates/tauri-cli/config.schema.json index d6742021f9d0..a856b35b7cfb 100644 --- a/crates/tauri-cli/config.schema.json +++ b/crates/tauri-cli/config.schema.json @@ -943,6 +943,17 @@ "items": { "$ref": "#/definitions/CapabilityEntry" } + }, + "headers": { + "description": "The headers, which are added to every http response from tauri to the web view\n This doesn't include IPC Messages and error responses", + "anyOf": [ + { + "$ref": "#/definitions/HeaderConfig" + }, + { + "type": "null" + } + ] } }, "additionalProperties": false @@ -1352,6 +1363,168 @@ } ] }, + "HeaderConfig": { + "description": "A struct, where the keys are some specific http header names.\n If the values to those keys are defined, then they will be send as part of a response message.\n This does not include error messages and ipc messages\n\n ## Example configuration\n ```javascript\n {\n //..\n app:{\n //..\n security: {\n headers: {\n \"Cross-Origin-Opener-Policy\": \"same-origin\",\n \"Cross-Origin-Embedder-Policy\": \"require-corp\",\n \"Timing-Allow-Origin\": [\n \"https://developer.mozilla.org\",\n \"https://example.com\",\n ],\n \"Access-Control-Expose-Headers\": \"Tauri-Custom-Header\",\n \"Tauri-Custom-Header\": {\n \"key1\": \"'value1' 'value2'\",\n \"key2\": \"'value3'\"\n }\n },\n csp: \"default-src 'self'; connect-src ipc: http://ipc.localhost\",\n }\n //..\n }\n //..\n }\n ```\n In this example `Cross-Origin-Opener-Policy` and `Cross-Origin-Embedder-Policy` are set to allow for the use of [`SharedArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer).\n The result is, that those headers are then set on every response sent via the `get_response` function in crates/tauri/src/protocol/tauri.rs.\n The Content-Security-Policy header is defined separately, because it is also handled separately.\n\n For the helloworld example, this config translates into those response headers:\n ```http\n access-control-allow-origin: http://tauri.localhost\n access-control-expose-headers: Tauri-Custom-Header\n content-security-policy: default-src 'self'; connect-src ipc: http://ipc.localhost; script-src 'self' 'sha256-Wjjrs6qinmnr+tOry8x8PPwI77eGpUFR3EEGZktjJNs='\n content-type: text/html\n cross-origin-embedder-policy: require-corp\n cross-origin-opener-policy: same-origin\n tauri-custom-header: key1 'value1' 'value2'; key2 'value3'\n timing-allow-origin: https://developer.mozilla.org, https://example.com\n ```\n Since the resulting header values are always 'string-like'. So depending on the what data type the HeaderSource is, they need to be converted.\n - `String`(JS/Rust): stay the same for the resulting header value\n - `Array`(JS)/`Vec\\`(Rust): Item are joined by \", \" for the resulting header value\n - `Object`(JS)/ `Hashmap\\`(Rust): Items are composed from: key + space + value. Item are then joined by \"; \" for the resulting header value", + "type": "object", + "properties": { + "Access-Control-Allow-Credentials": { + "description": "The Access-Control-Allow-Credentials response header tells browsers whether the\n server allows cross-origin HTTP requests to include credentials.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Access-Control-Allow-Headers": { + "description": "The Access-Control-Allow-Headers response header is used in response\n to a preflight request which includes the Access-Control-Request-Headers\n to indicate which HTTP headers can be used during the actual request.\n\n This header is required if the request has an Access-Control-Request-Headers header.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Access-Control-Allow-Methods": { + "description": "The Access-Control-Allow-Methods response header specifies one or more methods\n allowed when accessing a resource in response to a preflight request.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Access-Control-Expose-Headers": { + "description": "The Access-Control-Expose-Headers response header allows a server to indicate\n which response headers should be made available to scripts running in the browser,\n in response to a cross-origin request.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Access-Control-Max-Age": { + "description": "The Access-Control-Max-Age response header indicates how long the results of a\n preflight request (that is the information contained in the\n Access-Control-Allow-Methods and Access-Control-Allow-Headers headers) can\n be cached.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Cross-Origin-Embedder-Policy": { + "description": "The HTTP Cross-Origin-Embedder-Policy (COEP) response header configures embedding\n cross-origin resources into the document.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Cross-Origin-Opener-Policy": { + "description": "The HTTP Cross-Origin-Opener-Policy (COOP) response header allows you to ensure a\n top-level document does not share a browsing context group with cross-origin documents.\n COOP will process-isolate your document and potential attackers can't access your global\n object if they were to open it in a popup, preventing a set of cross-origin attacks dubbed XS-Leaks.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Cross-Origin-Resource-Policy": { + "description": "The HTTP Cross-Origin-Resource-Policy response header conveys a desire that the\n browser blocks no-cors cross-origin/cross-site requests to the given resource.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Permissions-Policy": { + "description": "The HTTP Permissions-Policy header provides a mechanism to allow and deny the\n use of browser features in a document or within any \\ elements in the document.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Timing-Allow-Origin": { + "description": "The Timing-Allow-Origin response header specifies origins that are allowed to see values\n of attributes retrieved via features of the Resource Timing API, which would otherwise be\n reported as zero due to cross-origin restrictions.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "X-Content-Type-Options": { + "description": "The X-Content-Type-Options response HTTP header is a marker used by the server to indicate\n that the MIME types advertised in the Content-Type headers should be followed and not be\n changed. The header allows you to avoid MIME type sniffing by saying that the MIME types\n are deliberately configured.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Tauri-Custom-Header": { + "description": "A custom header field Tauri-Custom-Header, don't use it.\n Remember to set Access-Control-Expose-Headers accordingly\n\n **NOT INTENDED FOR PRODUCTION USE**", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "HeaderSource": { + "description": "definition of a header source\n\n The header value to a header name", + "anyOf": [ + { + "description": "string version of the header Value", + "type": "string" + }, + { + "description": "list version of the header value. Item are joined by \",\" for the real header value", + "type": "array", + "items": { + "type": "string" + } + }, + { + "description": "(Rust struct | Json | JavaScript Object) equivalent of the header value. Items are composed from: key + space + value. Item are then joined by \";\" for the real header value", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + ] + }, "TrayIconConfig": { "description": "Configuration for application tray icon.\n\n See more: ", "type": "object", diff --git a/crates/tauri-cli/schema.json b/crates/tauri-cli/schema.json index 9d28874da38b..613287fc78f8 100644 --- a/crates/tauri-cli/schema.json +++ b/crates/tauri-cli/schema.json @@ -2995,4 +2995,4 @@ "additionalProperties": true } } -} \ No newline at end of file +} diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json index d6742021f9d0..a856b35b7cfb 100644 --- a/crates/tauri-schema-generator/schemas/config.schema.json +++ b/crates/tauri-schema-generator/schemas/config.schema.json @@ -943,6 +943,17 @@ "items": { "$ref": "#/definitions/CapabilityEntry" } + }, + "headers": { + "description": "The headers, which are added to every http response from tauri to the web view\n This doesn't include IPC Messages and error responses", + "anyOf": [ + { + "$ref": "#/definitions/HeaderConfig" + }, + { + "type": "null" + } + ] } }, "additionalProperties": false @@ -1352,6 +1363,168 @@ } ] }, + "HeaderConfig": { + "description": "A struct, where the keys are some specific http header names.\n If the values to those keys are defined, then they will be send as part of a response message.\n This does not include error messages and ipc messages\n\n ## Example configuration\n ```javascript\n {\n //..\n app:{\n //..\n security: {\n headers: {\n \"Cross-Origin-Opener-Policy\": \"same-origin\",\n \"Cross-Origin-Embedder-Policy\": \"require-corp\",\n \"Timing-Allow-Origin\": [\n \"https://developer.mozilla.org\",\n \"https://example.com\",\n ],\n \"Access-Control-Expose-Headers\": \"Tauri-Custom-Header\",\n \"Tauri-Custom-Header\": {\n \"key1\": \"'value1' 'value2'\",\n \"key2\": \"'value3'\"\n }\n },\n csp: \"default-src 'self'; connect-src ipc: http://ipc.localhost\",\n }\n //..\n }\n //..\n }\n ```\n In this example `Cross-Origin-Opener-Policy` and `Cross-Origin-Embedder-Policy` are set to allow for the use of [`SharedArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer).\n The result is, that those headers are then set on every response sent via the `get_response` function in crates/tauri/src/protocol/tauri.rs.\n The Content-Security-Policy header is defined separately, because it is also handled separately.\n\n For the helloworld example, this config translates into those response headers:\n ```http\n access-control-allow-origin: http://tauri.localhost\n access-control-expose-headers: Tauri-Custom-Header\n content-security-policy: default-src 'self'; connect-src ipc: http://ipc.localhost; script-src 'self' 'sha256-Wjjrs6qinmnr+tOry8x8PPwI77eGpUFR3EEGZktjJNs='\n content-type: text/html\n cross-origin-embedder-policy: require-corp\n cross-origin-opener-policy: same-origin\n tauri-custom-header: key1 'value1' 'value2'; key2 'value3'\n timing-allow-origin: https://developer.mozilla.org, https://example.com\n ```\n Since the resulting header values are always 'string-like'. So depending on the what data type the HeaderSource is, they need to be converted.\n - `String`(JS/Rust): stay the same for the resulting header value\n - `Array`(JS)/`Vec\\`(Rust): Item are joined by \", \" for the resulting header value\n - `Object`(JS)/ `Hashmap\\`(Rust): Items are composed from: key + space + value. Item are then joined by \"; \" for the resulting header value", + "type": "object", + "properties": { + "Access-Control-Allow-Credentials": { + "description": "The Access-Control-Allow-Credentials response header tells browsers whether the\n server allows cross-origin HTTP requests to include credentials.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Access-Control-Allow-Headers": { + "description": "The Access-Control-Allow-Headers response header is used in response\n to a preflight request which includes the Access-Control-Request-Headers\n to indicate which HTTP headers can be used during the actual request.\n\n This header is required if the request has an Access-Control-Request-Headers header.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Access-Control-Allow-Methods": { + "description": "The Access-Control-Allow-Methods response header specifies one or more methods\n allowed when accessing a resource in response to a preflight request.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Access-Control-Expose-Headers": { + "description": "The Access-Control-Expose-Headers response header allows a server to indicate\n which response headers should be made available to scripts running in the browser,\n in response to a cross-origin request.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Access-Control-Max-Age": { + "description": "The Access-Control-Max-Age response header indicates how long the results of a\n preflight request (that is the information contained in the\n Access-Control-Allow-Methods and Access-Control-Allow-Headers headers) can\n be cached.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Cross-Origin-Embedder-Policy": { + "description": "The HTTP Cross-Origin-Embedder-Policy (COEP) response header configures embedding\n cross-origin resources into the document.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Cross-Origin-Opener-Policy": { + "description": "The HTTP Cross-Origin-Opener-Policy (COOP) response header allows you to ensure a\n top-level document does not share a browsing context group with cross-origin documents.\n COOP will process-isolate your document and potential attackers can't access your global\n object if they were to open it in a popup, preventing a set of cross-origin attacks dubbed XS-Leaks.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Cross-Origin-Resource-Policy": { + "description": "The HTTP Cross-Origin-Resource-Policy response header conveys a desire that the\n browser blocks no-cors cross-origin/cross-site requests to the given resource.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Permissions-Policy": { + "description": "The HTTP Permissions-Policy header provides a mechanism to allow and deny the\n use of browser features in a document or within any \\ elements in the document.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Timing-Allow-Origin": { + "description": "The Timing-Allow-Origin response header specifies origins that are allowed to see values\n of attributes retrieved via features of the Resource Timing API, which would otherwise be\n reported as zero due to cross-origin restrictions.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "X-Content-Type-Options": { + "description": "The X-Content-Type-Options response HTTP header is a marker used by the server to indicate\n that the MIME types advertised in the Content-Type headers should be followed and not be\n changed. The header allows you to avoid MIME type sniffing by saying that the MIME types\n are deliberately configured.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Tauri-Custom-Header": { + "description": "A custom header field Tauri-Custom-Header, don't use it.\n Remember to set Access-Control-Expose-Headers accordingly\n\n **NOT INTENDED FOR PRODUCTION USE**", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "HeaderSource": { + "description": "definition of a header source\n\n The header value to a header name", + "anyOf": [ + { + "description": "string version of the header Value", + "type": "string" + }, + { + "description": "list version of the header value. Item are joined by \",\" for the real header value", + "type": "array", + "items": { + "type": "string" + } + }, + { + "description": "(Rust struct | Json | JavaScript Object) equivalent of the header value. Items are composed from: key + space + value. Item are then joined by \";\" for the real header value", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + ] + }, "TrayIconConfig": { "description": "Configuration for application tray icon.\n\n See more: ", "type": "object", diff --git a/crates/tauri-utils/Cargo.toml b/crates/tauri-utils/Cargo.toml index cd36d6ce217c..074b2ed4d9cb 100644 --- a/crates/tauri-utils/Cargo.toml +++ b/crates/tauri-utils/Cargo.toml @@ -46,6 +46,7 @@ log = "0.4.21" cargo_metadata = { version = "0.18", optional = true } serde-untagged = "0.1" uuid = { version = "1", features = ["serde"] } +http = "1.1.0" [target."cfg(target_os = \"macos\")".dependencies] swift-rs = { version = "1.0.7", optional = true, features = ["build"] } diff --git a/crates/tauri-utils/src/config.rs b/crates/tauri-utils/src/config.rs index 390aaea90af2..85fe4c8ac537 100644 --- a/crates/tauri-utils/src/config.rs +++ b/crates/tauri-utils/src/config.rs @@ -23,6 +23,7 @@ //! [ignore unknown fields when destructuring]: https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html#ignoring-remaining-parts-of-a-value-with- //! [Struct Update Syntax]: https://doc.rust-lang.org/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax +use http::response::Builder; #[cfg(feature = "schema")] use schemars::JsonSchema; use semver::Version; @@ -1833,6 +1834,280 @@ pub struct AssetProtocolConfig { pub enable: bool, } +/// definition of a header source +/// +/// The header value to a header name +#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", untagged)] +pub enum HeaderSource { + /// string version of the header Value + Inline(String), + /// list version of the header value. Item are joined by "," for the real header value + List(Vec), + /// (Rust struct | Json | JavaScript Object) equivalent of the header value. Items are composed from: key + space + value. Item are then joined by ";" for the real header value + Map(HashMap), +} + +impl Display for HeaderSource { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Inline(s) => write!(f, "{s}"), + Self::List(l) => write!(f, "{}", l.join(", ")), + Self::Map(m) => { + let len = m.len(); + let mut i = 0; + for (key, value) in m { + write!(f, "{} {}", key, value)?; + i += 1; + if i != len { + write!(f, "; ")?; + } + } + Ok(()) + } + } + } +} + +/// A trait which implements on the [`Builder`] of the http create +/// +/// Must add headers defined in the tauri configuration file to http responses +pub trait HeaderAddition { + /// adds all headers defined on the config file, given the current HeaderConfig + fn add_configured_headers(self, headers: Option<&HeaderConfig>) -> http::response::Builder; +} + +impl HeaderAddition for Builder { + /// Add the headers defined in the tauri configuration file to http responses + /// + /// this is a utility function, which is used in the same way as the `.header(..)` of the rust http library + fn add_configured_headers(mut self, headers: Option<&HeaderConfig>) -> http::response::Builder { + if let Some(headers) = headers { + // Add the header Access-Control-Allow-Credentials, if we find a value for it + if let Some(value) = &headers.access_control_allow_credentials { + self = self.header("Access-Control-Allow-Credentials", value.to_string()); + }; + + // Add the header Access-Control-Allow-Headers, if we find a value for it + if let Some(value) = &headers.access_control_allow_headers { + self = self.header("Access-Control-Allow-Headers", value.to_string()); + }; + + // Add the header Access-Control-Allow-Methods, if we find a value for it + if let Some(value) = &headers.access_control_allow_methods { + self = self.header("Access-Control-Allow-Methods", value.to_string()); + }; + + // Add the header Access-Control-Expose-Headers, if we find a value for it + if let Some(value) = &headers.access_control_expose_headers { + self = self.header("Access-Control-Expose-Headers", value.to_string()); + }; + + // Add the header Access-Control-Max-Age, if we find a value for it + if let Some(value) = &headers.access_control_max_age { + self = self.header("Access-Control-Max-Age", value.to_string()); + }; + + // Add the header Cross-Origin-Embedder-Policy, if we find a value for it + if let Some(value) = &headers.cross_origin_embedder_policy { + self = self.header("Cross-Origin-Embedder-Policy", value.to_string()); + }; + + // Add the header Cross-Origin-Opener-Policy, if we find a value for it + if let Some(value) = &headers.cross_origin_opener_policy { + self = self.header("Cross-Origin-Opener-Policy", value.to_string()); + }; + + // Add the header Cross-Origin-Resource-Policy, if we find a value for it + if let Some(value) = &headers.cross_origin_resource_policy { + self = self.header("Cross-Origin-Resource-Policy", value.to_string()); + }; + + // Add the header Permission-Policy, if we find a value for it + if let Some(value) = &headers.permissions_policy { + self = self.header("Permission-Policy", value.to_string()); + }; + + // Add the header Timing-Allow-Origin, if we find a value for it + if let Some(value) = &headers.timing_allow_origin { + self = self.header("Timing-Allow-Origin", value.to_string()); + }; + + // Add the header X-Content-Type-Options, if we find a value for it + if let Some(value) = &headers.x_content_type_options { + self = self.header("X-Content-Type-Options", value.to_string()); + }; + + // Add the header Tauri-Custom-Header, if we find a value for it + if let Some(value) = &headers.tauri_custom_header { + // Keep in mind to correctly set the Access-Control-Expose-Headers + self = self.header("Tauri-Custom-Header", value.to_string()); + }; + } + self + } +} + +/// A struct, where the keys are some specific http header names. +/// If the values to those keys are defined, then they will be send as part of a response message. +/// This does not include error messages and ipc messages +/// +/// ## Example configuration +/// ```javascript +/// { +/// //.. +/// app:{ +/// //.. +/// security: { +/// headers: { +/// "Cross-Origin-Opener-Policy": "same-origin", +/// "Cross-Origin-Embedder-Policy": "require-corp", +/// "Timing-Allow-Origin": [ +/// "https://developer.mozilla.org", +/// "https://example.com", +/// ], +/// "Access-Control-Expose-Headers": "Tauri-Custom-Header", +/// "Tauri-Custom-Header": { +/// "key1": "'value1' 'value2'", +/// "key2": "'value3'" +/// } +/// }, +/// csp: "default-src 'self'; connect-src ipc: http://ipc.localhost", +/// } +/// //.. +/// } +/// //.. +/// } +/// ``` +/// In this example `Cross-Origin-Opener-Policy` and `Cross-Origin-Embedder-Policy` are set to allow for the use of [`SharedArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer). +/// The result is, that those headers are then set on every response sent via the `get_response` function in crates/tauri/src/protocol/tauri.rs. +/// The Content-Security-Policy header is defined separately, because it is also handled separately. +/// +/// For the helloworld example, this config translates into those response headers: +/// ```http +/// access-control-allow-origin: http://tauri.localhost +/// access-control-expose-headers: Tauri-Custom-Header +/// content-security-policy: default-src 'self'; connect-src ipc: http://ipc.localhost; script-src 'self' 'sha256-Wjjrs6qinmnr+tOry8x8PPwI77eGpUFR3EEGZktjJNs=' +/// content-type: text/html +/// cross-origin-embedder-policy: require-corp +/// cross-origin-opener-policy: same-origin +/// tauri-custom-header: key1 'value1' 'value2'; key2 'value3' +/// timing-allow-origin: https://developer.mozilla.org, https://example.com +/// ``` +/// Since the resulting header values are always 'string-like'. So depending on the what data type the HeaderSource is, they need to be converted. +/// - `String`(JS/Rust): stay the same for the resulting header value +/// - `Array`(JS)/`Vec\`(Rust): Item are joined by ", " for the resulting header value +/// - `Object`(JS)/ `Hashmap\`(Rust): Items are composed from: key + space + value. Item are then joined by "; " for the resulting header value +#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(deny_unknown_fields)] +pub struct HeaderConfig { + /// The Access-Control-Allow-Credentials response header tells browsers whether the + /// server allows cross-origin HTTP requests to include credentials. + /// + /// See + #[serde(rename = "Access-Control-Allow-Credentials")] + pub access_control_allow_credentials: Option, + /// The Access-Control-Allow-Headers response header is used in response + /// to a preflight request which includes the Access-Control-Request-Headers + /// to indicate which HTTP headers can be used during the actual request. + /// + /// This header is required if the request has an Access-Control-Request-Headers header. + /// + /// See + #[serde(rename = "Access-Control-Allow-Headers")] + pub access_control_allow_headers: Option, + /// The Access-Control-Allow-Methods response header specifies one or more methods + /// allowed when accessing a resource in response to a preflight request. + /// + /// See + #[serde(rename = "Access-Control-Allow-Methods")] + pub access_control_allow_methods: Option, + /// The Access-Control-Expose-Headers response header allows a server to indicate + /// which response headers should be made available to scripts running in the browser, + /// in response to a cross-origin request. + /// + /// See + #[serde(rename = "Access-Control-Expose-Headers")] + pub access_control_expose_headers: Option, + /// The Access-Control-Max-Age response header indicates how long the results of a + /// preflight request (that is the information contained in the + /// Access-Control-Allow-Methods and Access-Control-Allow-Headers headers) can + /// be cached. + /// + /// See + #[serde(rename = "Access-Control-Max-Age")] + pub access_control_max_age: Option, + /// The HTTP Cross-Origin-Embedder-Policy (COEP) response header configures embedding + /// cross-origin resources into the document. + /// + /// See + #[serde(rename = "Cross-Origin-Embedder-Policy")] + pub cross_origin_embedder_policy: Option, + /// The HTTP Cross-Origin-Opener-Policy (COOP) response header allows you to ensure a + /// top-level document does not share a browsing context group with cross-origin documents. + /// COOP will process-isolate your document and potential attackers can't access your global + /// object if they were to open it in a popup, preventing a set of cross-origin attacks dubbed XS-Leaks. + /// + /// See + #[serde(rename = "Cross-Origin-Opener-Policy")] + pub cross_origin_opener_policy: Option, + /// The HTTP Cross-Origin-Resource-Policy response header conveys a desire that the + /// browser blocks no-cors cross-origin/cross-site requests to the given resource. + /// + /// See + #[serde(rename = "Cross-Origin-Resource-Policy")] + pub cross_origin_resource_policy: Option, + /// The HTTP Permissions-Policy header provides a mechanism to allow and deny the + /// use of browser features in a document or within any \ elements in the document. + /// + /// See + #[serde(rename = "Permissions-Policy")] + pub permissions_policy: Option, + /// The Timing-Allow-Origin response header specifies origins that are allowed to see values + /// of attributes retrieved via features of the Resource Timing API, which would otherwise be + /// reported as zero due to cross-origin restrictions. + /// + /// See + #[serde(rename = "Timing-Allow-Origin")] + pub timing_allow_origin: Option, + /// The X-Content-Type-Options response HTTP header is a marker used by the server to indicate + /// that the MIME types advertised in the Content-Type headers should be followed and not be + /// changed. The header allows you to avoid MIME type sniffing by saying that the MIME types + /// are deliberately configured. + /// + /// See + #[serde(rename = "X-Content-Type-Options")] + pub x_content_type_options: Option, + /// A custom header field Tauri-Custom-Header, don't use it. + /// Remember to set Access-Control-Expose-Headers accordingly + /// + /// **NOT INTENDED FOR PRODUCTION USE** + #[serde(rename = "Tauri-Custom-Header")] + pub tauri_custom_header: Option, +} + +impl HeaderConfig { + /// creates a new header config + pub fn new() -> Self { + HeaderConfig { + access_control_allow_credentials: None, + access_control_allow_methods: None, + access_control_allow_headers: None, + access_control_expose_headers: None, + access_control_max_age: None, + cross_origin_embedder_policy: None, + cross_origin_opener_policy: None, + cross_origin_resource_policy: None, + permissions_policy: None, + timing_allow_origin: None, + x_content_type_options: None, + tauri_custom_header: None, + } + } +} + /// Security configuration. /// /// See more: @@ -1881,6 +2156,10 @@ pub struct SecurityConfig { /// If the list is empty, all capabilities are included. #[serde(default)] pub capabilities: Vec, + /// The headers, which are added to every http response from tauri to the web view + /// This doesn't include IPC Messages and error responses + #[serde(default)] + pub headers: Option, } /// A capability entry which can be either an inlined capability or a reference to a capability defined on its own file. @@ -2840,6 +3119,62 @@ mod build { } } + impl ToTokens for HeaderSource { + fn to_tokens(&self, tokens: &mut TokenStream) { + let prefix = quote! { ::tauri::utils::config::HeaderSource }; + + tokens.append_all(match self { + Self::Inline(s) => { + let line = s.as_str(); + quote!(#prefix::Inline(#line.into())) + } + Self::List(l) => { + let list = vec_lit(l, str_lit); + quote!(#prefix::List(#list)) + } + Self::Map(m) => { + let map = map_lit(quote! { ::std::collections::HashMap }, m, str_lit, str_lit); + quote!(#prefix::Map(#map)) + } + }) + } + } + + impl ToTokens for HeaderConfig { + fn to_tokens(&self, tokens: &mut TokenStream) { + let access_control_allow_credentials = + opt_lit(self.access_control_allow_credentials.as_ref()); + let access_control_allow_headers = opt_lit(self.access_control_allow_headers.as_ref()); + let access_control_allow_methods = opt_lit(self.access_control_allow_methods.as_ref()); + let access_control_expose_headers = opt_lit(self.access_control_expose_headers.as_ref()); + let access_control_max_age = opt_lit(self.access_control_max_age.as_ref()); + let cross_origin_embedder_policy = opt_lit(self.cross_origin_embedder_policy.as_ref()); + let cross_origin_opener_policy = opt_lit(self.cross_origin_opener_policy.as_ref()); + let cross_origin_resource_policy = opt_lit(self.cross_origin_resource_policy.as_ref()); + let permissions_policy = opt_lit(self.permissions_policy.as_ref()); + let timing_allow_origin = opt_lit(self.timing_allow_origin.as_ref()); + let x_content_type_options = opt_lit(self.x_content_type_options.as_ref()); + let tauri_custom_header = opt_lit(self.tauri_custom_header.as_ref()); + + literal_struct!( + tokens, + ::tauri::utils::config::HeaderConfig, + access_control_allow_credentials, + access_control_allow_headers, + access_control_allow_methods, + access_control_expose_headers, + access_control_max_age, + cross_origin_embedder_policy, + cross_origin_opener_policy, + cross_origin_resource_policy, + permissions_policy, + timing_allow_origin, + x_content_type_options, + tauri_custom_header + ); + } + } + impl ToTokens for SecurityConfig { fn to_tokens(&self, tokens: &mut TokenStream) { let csp = opt_lit(self.csp.as_ref()); @@ -2849,6 +3184,7 @@ mod build { let asset_protocol = &self.asset_protocol; let pattern = &self.pattern; let capabilities = vec_lit(&self.capabilities, identity); + let headers = opt_lit(self.headers.as_ref()); literal_struct!( tokens, @@ -2859,7 +3195,8 @@ mod build { dangerous_disable_asset_csp_modification, asset_protocol, pattern, - capabilities + capabilities, + headers ); } } @@ -3003,6 +3340,7 @@ mod test { asset_protocol: AssetProtocolConfig::default(), pattern: Default::default(), capabilities: Vec::new(), + headers: None, }, tray_icon: None, macos_private_api: false, diff --git a/crates/tauri/src/protocol/isolation.rs b/crates/tauri/src/protocol/isolation.rs index f85f8e6cd3a7..53c5d9bb236a 100644 --- a/crates/tauri/src/protocol/isolation.rs +++ b/crates/tauri/src/protocol/isolation.rs @@ -5,7 +5,10 @@ use crate::Assets; use http::header::CONTENT_TYPE; use serialize_to_javascript::Template; -use tauri_utils::{assets::EmbeddedAssets, config::Csp}; +use tauri_utils::{ + assets::EmbeddedAssets, + config::{Csp, HeaderAddition}, +}; use std::sync::Arc; @@ -53,6 +56,7 @@ pub fn get( }; match template.render(asset.as_ref(), &Default::default()) { Ok(asset) => http::Response::builder() + .add_configured_headers(manager.config.app.security.headers.as_ref()) .header(CONTENT_TYPE, mime::TEXT_HTML.as_ref()) .header("Content-Security-Policy", csp) .body(asset.into_string().as_bytes().to_vec()), diff --git a/crates/tauri/src/protocol/tauri.rs b/crates/tauri/src/protocol/tauri.rs index ac33b5be2de7..cded6f615455 100644 --- a/crates/tauri/src/protocol/tauri.rs +++ b/crates/tauri/src/protocol/tauri.rs @@ -5,6 +5,7 @@ use std::{borrow::Cow, sync::Arc}; use http::{header::CONTENT_TYPE, Request, Response as HttpResponse, StatusCode}; +use tauri_utils::config::HeaderAddition; use crate::{ manager::{webview::PROXY_DEV_SERVER, AppManager}, @@ -98,7 +99,9 @@ fn get_response( // where `$P` is not `localhost/*` .unwrap_or_else(|| "".to_string()); - let mut builder = HttpResponse::builder().header("Access-Control-Allow-Origin", window_origin); + let mut builder = HttpResponse::builder() + .add_configured_headers(manager.config.app.security.headers.as_ref()) + .header("Access-Control-Allow-Origin", window_origin); #[cfg(all(dev, mobile))] let mut response = { diff --git a/crates/tauri/test/fixture/src-tauri/tauri.conf.json b/crates/tauri/test/fixture/src-tauri/tauri.conf.json index 4ae174e8e124..f5b75e3eb055 100644 --- a/crates/tauri/test/fixture/src-tauri/tauri.conf.json +++ b/crates/tauri/test/fixture/src-tauri/tauri.conf.json @@ -12,7 +12,8 @@ } ], "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'; connect-src ipc: http://ipc.localhost" + "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'; connect-src ipc: http://ipc.localhost", + "headers": null } }, "bundle": { From 4d545ab3ca228c8a21b966b709f84a0da2864479 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Wed, 6 Nov 2024 18:21:47 +0200 Subject: [PATCH 30/51] feat: background color APIs (#11486) * feat: background color APIs closes #10519 closes #1564 * clippy * git branch * bundle * fix hex color schema pattern * add missing `^` * fix iOS * revert test * revert apple-codesign bump * fmt * add change files --------- Co-authored-by: Lucas Nogueira --- .changes/background-color-apis.md | 6 + .changes/background-color.md | 8 + Cargo.lock | 436 ++++++++++++------ crates/tauri-cli/config.schema.json | 111 ++++- crates/tauri-macos-sign/Cargo.toml | 4 +- crates/tauri-runtime-wry/Cargo.toml | 2 +- crates/tauri-runtime-wry/src/lib.rs | 64 ++- crates/tauri-runtime-wry/src/window/mod.rs | 3 +- .../tauri-runtime-wry/src/window/windows.rs | 8 +- crates/tauri-runtime/src/lib.rs | 7 + crates/tauri-runtime/src/webview.rs | 18 +- crates/tauri-runtime/src/window.rs | 9 +- .../schemas/config.schema.json | 111 ++++- crates/tauri-schema-worker/src/config.rs | 2 +- crates/tauri-utils/src/config.rs | 169 ++++++- crates/tauri/scripts/bundle.global.js | 2 +- crates/tauri/src/test/mock_runtime.rs | 12 + crates/tauri/src/webview/mod.rs | 30 ++ crates/tauri/src/webview/plugin.rs | 10 +- crates/tauri/src/webview/webview_window.rs | 34 +- crates/tauri/src/window/mod.rs | 26 ++ crates/tauri/src/window/plugin.rs | 3 + examples/api/src-tauri/src/lib.rs | 3 +- packages/api/src/webview.ts | 35 +- packages/api/src/webviewWindow.ts | 26 +- packages/api/src/window.ts | 37 +- 26 files changed, 976 insertions(+), 200 deletions(-) create mode 100644 .changes/background-color-apis.md create mode 100644 .changes/background-color.md diff --git a/.changes/background-color-apis.md b/.changes/background-color-apis.md new file mode 100644 index 000000000000..853a7540e87b --- /dev/null +++ b/.changes/background-color-apis.md @@ -0,0 +1,6 @@ +--- +"@tauri-apps/api": minor:feat +--- + +Added `Webview::setBackgroundColor`, `WebviewWindow::setBackgroundColor` APIs to set the window background color dynamically +and a `backgroundColor` window option to set the background color on window creation. diff --git a/.changes/background-color.md b/.changes/background-color.md new file mode 100644 index 000000000000..35d120c4ef1e --- /dev/null +++ b/.changes/background-color.md @@ -0,0 +1,8 @@ +--- +"tauri": minor:feat +"tauri-utils": minor:feat +"tauri-runtime": minor:feat +"tauri-runtime-wry": minor:feat +--- + +Added `Window::set_background_color` and `WindowBuilder::background_color`. diff --git a/Cargo.lock b/Cargo.lock index c8242e097152..7902bfd4df58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,32 +237,32 @@ dependencies = [ [[package]] name = "app-store-connect" -version = "0.6.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61321685c26bccddbeaa34d9d0108db01c7cf00bcc0fe06921fd47af26e17979" +checksum = "33fb5489b9bfcfa3aec2f68cc79eafb999b5af9b9d9d70ca8dfe36acdd1b2b05" dependencies = [ "anyhow", - "base64 0.22.1", + "base64 0.21.7", "clap", "dirs", - "env_logger 0.11.5", + "env_logger 0.10.2", "jsonwebtoken", "log", "pem", "rand 0.8.5", - "reqwest", + "reqwest 0.11.27", "rsa", "serde", "serde_json", "thiserror", - "x509-certificate 0.24.0", + "x509-certificate", ] [[package]] name = "apple-bundles" -version = "0.20.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b06f1e42dc02f590067deabd5ecb3b8fdc13c6432d72670431614de9770832b" +checksum = "abb7c27ee2ca7826adfdc84228cd4c5a84ab57b0a11d269d1d7cd0615238e5a2" dependencies = [ "anyhow", "plist", @@ -272,9 +272,9 @@ dependencies = [ [[package]] name = "apple-codesign" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256649c0fce3d8628a0957235db4276bdec01fbec8dd57f5300cdda400dfe4a7" +checksum = "329820aac7259ca0529d3cc21dd3b4c11651225dfce9e0ce25b121b23f923164" dependencies = [ "anyhow", "app-store-connect", @@ -285,7 +285,7 @@ dependencies = [ "aws-sdk-s3", "aws-smithy-http", "aws-smithy-types", - "base64 0.22.1", + "base64 0.21.7", "bcder", "bitflags 2.6.0", "bytes", @@ -298,7 +298,7 @@ dependencies = [ "digest", "dirs", "elliptic-curve 0.13.8", - "env_logger 0.11.5", + "env_logger 0.10.2", "figment", "filetime", "glob", @@ -308,7 +308,7 @@ dependencies = [ "md-5", "minicbor", "num-traits", - "object", + "object 0.32.2", "oid-registry", "once_cell", "p12", @@ -321,7 +321,7 @@ dependencies = [ "rasn", "rayon", "regex", - "reqwest", + "reqwest 0.11.27", "ring", "rsa", "scroll", @@ -340,25 +340,25 @@ dependencies = [ "tempfile", "thiserror", "tokio", - "tungstenite", + "tungstenite 0.21.0", "uuid", "walkdir", "widestring", - "windows-sys 0.59.0", + "windows-sys 0.52.0", "x509", - "x509-certificate 0.24.0", + "x509-certificate", "xml-rs", "yasna", "zeroize", - "zip", + "zip 0.6.6", "zip_structs", ] [[package]] name = "apple-flat-package" -version = "0.19.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500b3e2ffc3e0839ef621a5a5bf8f1b5a54cee3d2a1b6fcdecdc6aba489c2f50" +checksum = "b6adc520e05304de5ec383487786fa20e9c636fe972e59719cdd93621a2db6f1" dependencies = [ "apple-xar", "cpio-archive", @@ -371,11 +371,11 @@ dependencies = [ [[package]] name = "apple-xar" -version = "0.19.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d3fc5c875778d33991009f508004f7c9e47c62e326bf9d5e4513482efc4147" +checksum = "844e00dc1e665b3cf0bba745aa9c6464292ca512db0c11384511586701eb0335" dependencies = [ - "base64 0.22.1", + "base64 0.21.7", "bcder", "bzip2", "chrono", @@ -385,7 +385,7 @@ dependencies = [ "log", "md-5", "rand 0.8.5", - "reqwest", + "reqwest 0.11.27", "scroll", "serde", "serde-xml-rs", @@ -394,7 +394,7 @@ dependencies = [ "signature 2.2.0", "thiserror", "url", - "x509-certificate 0.24.0", + "x509-certificate", "xml-rs", "xz2", ] @@ -457,9 +457,9 @@ checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" [[package]] name = "asn1-rs" -version = "0.6.2" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" dependencies = [ "asn1-rs-derive", "asn1-rs-impl", @@ -472,25 +472,25 @@ dependencies = [ [[package]] name = "asn1-rs-derive" -version = "0.5.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", - "synstructure", + "syn 1.0.109", + "synstructure 0.12.6", ] [[package]] name = "asn1-rs-impl" -version = "0.2.0" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 1.0.109", ] [[package]] @@ -1020,7 +1020,7 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide 0.8.0", - "object", + "object 0.36.5", "rustc-demangle", "windows-targets 0.52.6", ] @@ -1504,7 +1504,7 @@ dependencies = [ "ureq", "which 6.0.3", "windows", - "x509-certificate 0.23.1", + "x509-certificate", ] [[package]] @@ -1979,9 +1979,9 @@ checksum = "80e3adec7390c7643049466136117057188edf5f23efc5c8b4fc8079c8dc34a6" [[package]] name = "cpio-archive" -version = "0.10.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11d34b07689c21889fc89bd7cc885b3244b0157bbededf4a1c159832cd0df05" +checksum = "63d5133d716d3d82da8c76367ddb0ab1733e2629f1462e4f39947e13b8b4b741" dependencies = [ "chrono", "is_executable", @@ -2099,19 +2099,19 @@ dependencies = [ [[package]] name = "cryptographic-message-syntax" -version = "0.27.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a99e58d7755c646cb3f2a138d99f90da4c495282e1700b82daff8a48759ce0" +checksum = "43c324ba1028cef7e3a71a00cbf585637bb0215dec2f6a2b566d094190a1309b" dependencies = [ "bcder", "bytes", "chrono", "hex", "pem", - "reqwest", + "reqwest 0.11.27", "ring", "signature 2.2.0", - "x509-certificate 0.24.0", + "x509-certificate", ] [[package]] @@ -2494,6 +2494,12 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "dpi" version = "0.1.1" @@ -2685,7 +2691,7 @@ dependencies = [ "rustc_version", "toml 0.8.19", "vswhom", - "winreg", + "winreg 0.52.0", ] [[package]] @@ -2757,6 +2763,19 @@ dependencies = [ "regex", ] +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + [[package]] name = "env_logger" version = "0.11.5" @@ -2949,12 +2968,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" - [[package]] name = "fontconfig-parser" version = "0.5.7" @@ -3449,9 +3462,9 @@ dependencies = [ [[package]] name = "goblin" -version = "0.9.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53ab3f32d1d77146981dea5d6b1e8fe31eedcb7013e5e00d6ccd1259a4b4d923" +checksum = "1b363a30c165f666402fe6a3024d3bec7ebc898f96a4a23bd1c99f8dbf3f4f47" dependencies = [ "log", "plain", @@ -3619,9 +3632,6 @@ name = "hashbrown" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" -dependencies = [ - "foldhash", -] [[package]] name = "heck" @@ -3641,6 +3651,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -3840,12 +3856,11 @@ dependencies = [ "hyper 1.4.1", "hyper-util", "rustls 0.23.13", - "rustls-native-certs 0.8.0", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", "tower-service", - "webpki-roots", + "webpki-roots 0.26.6", ] [[package]] @@ -4274,7 +4289,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys 0.48.0", ] @@ -4285,6 +4300,17 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" +[[package]] +name = "is-terminal" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +dependencies = [ + "hermit-abi 0.4.0", + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "is_executable" version = "1.0.4" @@ -4315,6 +4341,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071ed4cc1afd86650602c7b11aa2e1ce30762a1c27193201cb5cee9c6ebb1294" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.12.1" @@ -4623,7 +4658,7 @@ dependencies = [ "parking_lot", "percent-encoding", "regex", - "reqwest", + "reqwest 0.12.9", "serde", "serde_json", "time", @@ -4646,6 +4681,12 @@ dependencies = [ "simple_asn1", ] +[[package]] +name = "jzon" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ab85f84ca42c5ec520e6f3c9966ba1fd62909ce260f8837e248857d2560509" + [[package]] name = "k256" version = "0.13.4" @@ -5082,22 +5123,22 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "minicbor" -version = "0.24.4" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29be4f60e41fde478b36998b88821946aafac540e53591e76db53921a0cc225b" +checksum = "9d15f4203d71fdf90903c2696e55426ac97a363c67b218488a73b534ce7aca10" dependencies = [ "minicbor-derive", ] [[package]] name = "minicbor-derive" -version = "0.15.3" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd2209fff77f705b00c737016a48e73733d7fbccb8b007194db148f03561fb70" +checksum = "1154809406efdb7982841adb6311b3d095b46f78342dd646736122fe6b19e267" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 1.0.109", ] [[package]] @@ -5154,7 +5195,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", @@ -5775,18 +5816,27 @@ dependencies = [ [[package]] name = "object" -version = "0.36.5" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "crc32fast", "flate2", - "hashbrown 0.15.0", + "hashbrown 0.14.5", "indexmap 2.6.0", "memchr", "ruzstd", ] +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + [[package]] name = "ocb3" version = "0.1.0" @@ -5801,9 +5851,9 @@ dependencies = [ [[package]] name = "oid-registry" -version = "0.7.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" dependencies = [ "asn1-rs", ] @@ -7005,9 +7055,9 @@ dependencies = [ [[package]] name = "rasn" -version = "0.20.2" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e442690f86da40561d5548e7ffb4a18af90d1c1b3536090de847ca2d5a3a6426" +checksum = "cf9b0d03fbc7d2dcfdd35086c43ce30ac5ff62ed7eff4397e4f4f2995a2b0e2a" dependencies = [ "arrayvec", "bitvec", @@ -7015,7 +7065,7 @@ dependencies = [ "bytes", "chrono", "either", - "hashbrown 0.14.5", + "jzon", "konst", "nom", "num-bigint", @@ -7023,22 +7073,21 @@ dependencies = [ "num-traits", "once_cell", "rasn-derive", - "serde_json", "snafu", ] [[package]] name = "rasn-derive" -version = "0.20.2" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b0d374c7e4e985e6bc97ca7e7ad1d9642a8415db2017777d6e383002edaab2" +checksum = "cbaf7105cd254b632f4732fbcc243ce750cef87d8335826125ef6df5733b5a0c" dependencies = [ "either", - "itertools 0.13.0", + "itertools 0.10.5", "proc-macro2", "quote", "rayon", - "syn 2.0.87", + "syn 1.0.109", "uuid", ] @@ -7191,6 +7240,48 @@ dependencies = [ "bytecheck", ] +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", + "hyper-rustls 0.24.2", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.12", + "rustls-native-certs 0.6.3", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "system-configuration", + "tokio", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.25.4", + "winreg 0.50.0", +] + [[package]] name = "reqwest" version = "0.12.9" @@ -7202,7 +7293,6 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.6", "http 1.1.0", "http-body 1.0.1", "http-body-util", @@ -7220,7 +7310,6 @@ dependencies = [ "pin-project-lite", "quinn", "rustls 0.23.13", - "rustls-native-certs 0.8.0", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", @@ -7237,7 +7326,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", + "webpki-roots 0.26.6", "windows-registry 0.2.0", ] @@ -7527,6 +7616,20 @@ dependencies = [ "sct", ] +[[package]] +name = "rustls" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + [[package]] name = "rustls" version = "0.23.13" @@ -7567,19 +7670,6 @@ dependencies = [ "security-framework", ] -[[package]] -name = "rustls-native-certs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" -dependencies = [ - "openssl-probe", - "rustls-pemfile 2.2.0", - "rustls-pki-types", - "schannel", - "security-framework", -] - [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -7663,10 +7753,12 @@ dependencies = [ [[package]] name = "ruzstd" -version = "0.7.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c3938e133aac070997ddc684d4b393777d293ba170f2988c8fd5ea2ad4ce21" +checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d" dependencies = [ + "byteorder", + "derive_more", "twox-hash", ] @@ -8352,23 +8444,25 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" [[package]] name = "snafu" -version = "0.8.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" +checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6" dependencies = [ + "backtrace", + "doc-comment", "snafu-derive", ] [[package]] name = "snafu-derive" -version = "0.8.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" +checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf" dependencies = [ - "heck 0.5.0", + "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.87", + "syn 1.0.109", ] [[package]] @@ -8745,6 +8839,18 @@ dependencies = [ "futures-core", ] +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + [[package]] name = "synstructure" version = "0.13.1" @@ -8769,6 +8875,27 @@ dependencies = [ "walkdir", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "system-deps" version = "6.2.2" @@ -8784,9 +8911,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.30.3" +version = "0.30.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0dbbebe82d02044dfa481adca1550d6dd7bd16e086bc34fa0fbecceb5a63751" +checksum = "63f1f6b2017cc33d7f6fc9c6186a2c0f5dfc985899a7b4fe9e64985c17533db3" dependencies = [ "bitflags 2.6.0", "cocoa 0.26.0", @@ -8889,7 +9016,7 @@ dependencies = [ "quickcheck", "quickcheck_macros", "raw-window-handle", - "reqwest", + "reqwest 0.12.9", "serde", "serde_json", "serde_repr", @@ -8978,7 +9105,7 @@ dependencies = [ "walkdir", "windows-registry 0.3.0", "windows-sys 0.59.0", - "zip", + "zip 2.2.0", ] [[package]] @@ -9025,7 +9152,7 @@ dependencies = [ "minisign", "notify", "notify-debouncer-mini", - "object", + "object 0.36.5", "os_info", "os_pipe", "oxc_allocator", @@ -9152,7 +9279,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "x509-certificate 0.24.0", + "x509-certificate", ] [[package]] @@ -9449,6 +9576,15 @@ dependencies = [ "utf-8", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "terminal_size" version = "0.2.6" @@ -9686,7 +9822,7 @@ dependencies = [ "futures-util", "log", "tokio", - "tungstenite", + "tungstenite 0.24.0", ] [[package]] @@ -9887,9 +10023,9 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.24.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" dependencies = [ "byteorder", "bytes", @@ -9898,11 +10034,30 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.23.13", + "rustls 0.22.4", "rustls-native-certs 0.7.3", "rustls-pki-types", "sha1", "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.1.0", + "httparse", + "log", + "rand 0.8.5", + "sha1", + "thiserror", "utf-8", ] @@ -10089,6 +10244,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "universal-hash" version = "0.5.1" @@ -10126,7 +10287,7 @@ dependencies = [ "rustls-pki-types", "socks", "url", - "webpki-roots", + "webpki-roots 0.26.6", ] [[package]] @@ -10498,6 +10659,12 @@ dependencies = [ "system-deps", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "webpki-roots" version = "0.26.6" @@ -10969,6 +11136,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "winreg" version = "0.52.0" @@ -11185,25 +11362,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "x509-certificate" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57b9f8bcae7c1f36479821ae826d75050c60ce55146fd86d3553ed2573e2762" -dependencies = [ - "bcder", - "bytes", - "chrono", - "der 0.7.9", - "hex", - "pem", - "ring", - "signature 2.2.0", - "spki 0.7.3", - "thiserror", - "zeroize", -] - [[package]] name = "xattr" version = "1.3.1" @@ -11275,7 +11433,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.87", - "synstructure", + "synstructure 0.13.1", ] [[package]] @@ -11317,7 +11475,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.87", - "synstructure", + "synstructure 0.13.1", ] [[package]] @@ -11362,6 +11520,18 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", + "flate2", +] + [[package]] name = "zip" version = "2.2.0" diff --git a/crates/tauri-cli/config.schema.json b/crates/tauri-cli/config.schema.json index a856b35b7cfb..4bc434e06f32 100644 --- a/crates/tauri-cli/config.schema.json +++ b/crates/tauri-cli/config.schema.json @@ -505,6 +505,17 @@ "boolean", "null" ] + }, + "backgroundColor": { + "description": "Set the window and webview background color.\n\n ## Platform-specific:\n\n - **Windows**: alpha channel is ignored for the window layer.\n - **Windows**: On Windows 7, alpha channel is ignored for the webview layer.\n - **Windows**: On Windows 8 and newer, if alpha channel is not `0`, it will be ignored for the webview layer.", + "anyOf": [ + { + "$ref": "#/definitions/Color" + }, + { + "type": "null" + } + ] } }, "additionalProperties": false @@ -846,32 +857,96 @@ ] }, "Color": { - "description": "a tuple struct of RGBA colors. Each value has minimum of 0 and maximum of 255.", - "type": "array", - "items": [ + "anyOf": [ { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Color hex string, for example: #fff, #ffffff, or #ffffffff.", + "type": "string", + "pattern": "^#?([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$" }, { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Array of RGB colors. Each value has minimum of 0 and maximum of 255.", + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + ], + "maxItems": 3, + "minItems": 3 }, { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Array of RGBA colors. Each value has minimum of 0 and maximum of 255.", + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + ], + "maxItems": 4, + "minItems": 4 }, { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Object of red, green, blue, alpha color values. Each value has minimum of 0 and maximum of 255.", + "type": "object", + "required": [ + "blue", + "green", + "red" + ], + "properties": { + "red": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "green": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "blue": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "alpha": { + "default": 255, + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + } } - ], - "maxItems": 4, - "minItems": 4 + ] }, "SecurityConfig": { "description": "Security configuration.\n\n See more: ", diff --git a/crates/tauri-macos-sign/Cargo.toml b/crates/tauri-macos-sign/Cargo.toml index f293263219a9..8fd33172827c 100644 --- a/crates/tauri-macos-sign/Cargo.toml +++ b/crates/tauri-macos-sign/Cargo.toml @@ -14,13 +14,13 @@ anyhow = "1" serde = { version = "1", features = ["derive"] } serde_json = "1" tempfile = "3" -x509-certificate = "0.24" +x509-certificate = "0.23" once-cell-regex = "0.2" os_pipe = "1" plist = "1" rand = "0.8" dirs-next = "2" log = { version = "0.4.21", features = ["kv"] } -apple-codesign = "0.28" +apple-codesign = "0.27" chrono = "0.4.38" p12 = "0.6" diff --git a/crates/tauri-runtime-wry/Cargo.toml b/crates/tauri-runtime-wry/Cargo.toml index dd7ab2009b39..9633ba0987b1 100644 --- a/crates/tauri-runtime-wry/Cargo.toml +++ b/crates/tauri-runtime-wry/Cargo.toml @@ -23,7 +23,7 @@ wry = { version = "0.46.1", default-features = false, features = [ "os-webview", "linux-body", ] } -tao = { version = "0.30.2", default-features = false, features = ["rwh_06"] } +tao = { version = "0.30.5", default-features = false, features = ["rwh_06"] } tauri-runtime = { version = "2.1.0", path = "../tauri-runtime" } tauri-utils = { version = "2.0.2", path = "../tauri-utils" } raw-window-handle = "0.6" diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index cde760ba7587..bde9d3ccd7fd 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -65,7 +65,10 @@ use tao::{ }; #[cfg(target_os = "macos")] use tauri_utils::TitleBarStyle; -use tauri_utils::{config::WindowConfig, Theme}; +use tauri_utils::{ + config::{Color, WindowConfig}, + Theme, +}; use url::Url; use wry::{ DragDropEvent as WryDragDropEvent, ProxyConfig, ProxyEndpoint, WebContext as WryWebContext, @@ -842,6 +845,9 @@ impl WindowBuilder for WindowBuilderWrapper { if let Some(max_height) = config.max_height { constraints.max_height = Some(tao::dpi::LogicalUnit::new(max_height).into()); } + if let Some(color) = config.background_color { + window = window.background_color(color); + } window = window.inner_size_constraints(constraints); if let (Some(x), Some(y)) = (config.x, config.y) { @@ -1080,6 +1086,11 @@ impl WindowBuilder for WindowBuilderWrapper { Ok(self) } + fn background_color(mut self, color: Color) -> Self { + self.inner = self.inner.with_background_color(color.into()); + self + } + #[cfg(any(windows, target_os = "linux"))] fn skip_taskbar(mut self, skip: bool) -> Self { self.inner = self.inner.with_skip_taskbar(skip); @@ -1255,6 +1266,7 @@ pub enum WindowMessage { SetProgressBar(ProgressBarState), SetTitleBarStyle(tauri_utils::TitleBarStyle), SetTheme(Option), + SetBackgroundColor(Option), DragWindow, ResizeDragWindow(tauri_runtime::ResizeDirection), RequestRedraw, @@ -1296,6 +1308,7 @@ pub enum WebviewMessage { Reparent(WindowId, Sender>), SetAutoResize(bool), SetZoom(f64), + SetBackgroundColor(Option), ClearAllBrowsingData, // Getters Url(Sender>), @@ -1612,6 +1625,17 @@ impl WebviewDispatch for WryWebviewDispatcher { ), ) } + + fn set_background_color(&self, color: Option) -> Result<()> { + send_user_message( + &self.context, + Message::Webview( + *self.window_id.lock().unwrap(), + self.webview_id, + WebviewMessage::SetBackgroundColor(color), + ), + ) + } } /// The Tauri [`WindowDispatch`] for [`Wry`]. @@ -2124,6 +2148,13 @@ impl WindowDispatch for WryWindowDispatcher { Message::Window(self.window_id, WindowMessage::SetTheme(theme)), ) } + + fn set_background_color(&self, color: Option) -> Result<()> { + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::SetBackgroundColor(color)), + ) + } } #[derive(Clone)] @@ -2172,6 +2203,8 @@ pub struct WindowWrapper { webviews: Vec, window_event_listeners: WindowEventListeners, #[cfg(windows)] + background_color: Option, + #[cfg(windows)] is_window_transparent: bool, #[cfg(windows)] surface: Option, Arc>>, @@ -3097,6 +3130,9 @@ fn handle_user_message( _ => None, }); } + WindowMessage::SetBackgroundColor(color) => { + window.set_background_color(color.map(Into::into)) + } } } } @@ -3292,6 +3328,13 @@ fn handle_user_message( log::error!("failed to set webview zoom: {e}"); } } + WebviewMessage::SetBackgroundColor(color) => { + if let Err(e) = + webview.set_background_color(color.map(Into::into).unwrap_or((255, 255, 255, 255))) + { + log::error!("failed to set webview background color: {e}"); + } + } WebviewMessage::ClearAllBrowsingData => { if let Err(e) = webview.clear_all_browsing_data() { log::error!("failed to clear webview browsing data: {e}"); @@ -3460,6 +3503,8 @@ fn handle_user_message( Message::CreateRawWindow(window_id, handler, sender) => { let (label, builder) = handler(); + #[cfg(windows)] + let background_color = builder.window.background_color; #[cfg(windows)] let is_window_transparent = builder.window.transparent; @@ -3472,7 +3517,7 @@ fn handle_user_message( let surface = if is_window_transparent { if let Ok(context) = softbuffer::Context::new(window.clone()) { if let Ok(mut surface) = softbuffer::Surface::new(&context, window.clone()) { - window.clear_surface(&mut surface); + window.draw_surface(&mut surface, background_color); Some(surface) } else { None @@ -3493,6 +3538,8 @@ fn handle_user_message( window_event_listeners: Default::default(), webviews: Vec::new(), #[cfg(windows)] + background_color, + #[cfg(windows)] is_window_transparent, #[cfg(windows)] surface, @@ -3556,9 +3603,10 @@ fn handle_event_loop( let mut windows_ref = windows.0.borrow_mut(); if let Some(window) = windows_ref.get_mut(&window_id) { if window.is_window_transparent { + let background_color = window.background_color; if let Some(surface) = &mut window.surface { if let Some(window) = &window.inner { - window.clear_surface(surface); + window.draw_surface(surface, background_color); } } } @@ -3842,6 +3890,8 @@ fn create_window( let window_event_listeners = WindowEventListeners::default(); + #[cfg(windows)] + let background_color = window_builder.inner.window.background_color; #[cfg(windows)] let is_window_transparent = window_builder.inner.window.transparent; @@ -3973,7 +4023,7 @@ fn create_window( let surface = if is_window_transparent { if let Ok(context) = softbuffer::Context::new(window.clone()) { if let Ok(mut surface) = softbuffer::Surface::new(&context, window.clone()) { - window.clear_surface(&mut surface); + window.draw_surface(&mut surface, background_color); Some(surface) } else { None @@ -3992,6 +4042,8 @@ fn create_window( webviews, window_event_listeners, #[cfg(windows)] + background_color, + #[cfg(windows)] is_window_transparent, #[cfg(windows)] surface, @@ -4079,6 +4131,10 @@ fn create_webview( webview_builder = webview_builder.with_https_scheme(webview_attributes.use_https_scheme); } + if let Some(color) = webview_attributes.background_color { + webview_builder = webview_builder.with_background_color(color.into()); + } + if webview_attributes.drag_drop_handler_enabled { let proxy = context.proxy.clone(); let window_id_ = window_id.clone(); diff --git a/crates/tauri-runtime-wry/src/window/mod.rs b/crates/tauri-runtime-wry/src/window/mod.rs index 1c649e0764dd..c2b1b448686d 100644 --- a/crates/tauri-runtime-wry/src/window/mod.rs +++ b/crates/tauri-runtime-wry/src/window/mod.rs @@ -39,12 +39,13 @@ pub trait WindowExt { /// Clears the window sufrace. i.e make it it transparent. #[cfg(windows)] - fn clear_surface( + fn draw_surface( &self, surface: &mut softbuffer::Surface< std::sync::Arc, std::sync::Arc, >, + background_color: Option, ); } diff --git a/crates/tauri-runtime-wry/src/window/windows.rs b/crates/tauri-runtime-wry/src/window/windows.rs index f7825051f777..6c032beabda8 100644 --- a/crates/tauri-runtime-wry/src/window/windows.rs +++ b/crates/tauri-runtime-wry/src/window/windows.rs @@ -43,12 +43,13 @@ impl super::WindowExt for tao::window::Window { } } - fn clear_surface( + fn draw_surface( &self, surface: &mut softbuffer::Surface< std::sync::Arc, std::sync::Arc, >, + background_color: Option, ) { let size = self.inner_size(); if let (Some(width), Some(height)) = ( @@ -57,7 +58,10 @@ impl super::WindowExt for tao::window::Window { ) { surface.resize(width, height).unwrap(); let mut buffer = surface.buffer_mut().unwrap(); - buffer.fill(0); + let color = background_color + .map(|(r, g, b, _)| (b as u32) | ((g as u32) << 8) | ((r as u32) << 16)) + .unwrap_or(0); + buffer.fill(color); let _ = buffer.present(); } } diff --git a/crates/tauri-runtime/src/lib.rs b/crates/tauri-runtime/src/lib.rs index b1e2c7184f61..1257dab15f86 100644 --- a/crates/tauri-runtime/src/lib.rs +++ b/crates/tauri-runtime/src/lib.rs @@ -18,6 +18,7 @@ use raw_window_handle::DisplayHandle; use serde::{Deserialize, Serialize}; use std::{borrow::Cow, fmt::Debug, sync::mpsc::Sender}; +use tauri_utils::config::Color; use tauri_utils::Theme; use url::Url; use webview::{DetachedWebview, PendingWebview}; @@ -523,6 +524,9 @@ pub trait WebviewDispatch: Debug + Clone + Send + Sync + Sized + ' /// Set the webview zoom level fn set_zoom(&self, scale_factor: f64) -> Result<()>; + /// Set the webview background. + fn set_background_color(&self, color: Option) -> Result<()>; + /// Clear all browsing data for this webview. fn clear_all_browsing_data(&self) -> Result<()>; } @@ -753,6 +757,9 @@ pub trait WindowDispatch: Debug + Clone + Send + Sync + Sized + 's /// Updates the window visibleOnAllWorkspaces flag. fn set_visible_on_all_workspaces(&self, visible_on_all_workspaces: bool) -> Result<()>; + /// Set the window background. + fn set_background_color(&self, color: Option) -> Result<()>; + /// Prevents the window contents from being captured by other apps. fn set_content_protected(&self, protected: bool) -> Result<()>; diff --git a/crates/tauri-runtime/src/webview.rs b/crates/tauri-runtime/src/webview.rs index 203d97b9422e..e17b9e197396 100644 --- a/crates/tauri-runtime/src/webview.rs +++ b/crates/tauri-runtime/src/webview.rs @@ -7,7 +7,7 @@ use crate::{window::is_label_valid, Rect, Runtime, UserEvent}; use http::Request; -use tauri_utils::config::{WebviewUrl, WindowConfig, WindowEffectsConfig}; +use tauri_utils::config::{Color, WebviewUrl, WindowConfig, WindowEffectsConfig}; use url::Url; use std::{ @@ -212,6 +212,7 @@ pub struct WebviewAttributes { pub browser_extensions_enabled: bool, pub use_https_scheme: bool, pub devtools: Option, + pub background_color: Option, } impl From<&WindowConfig> for WebviewAttributes { @@ -243,6 +244,9 @@ impl From<&WindowConfig> for WebviewAttributes { if let Some(url) = &config.proxy_url { builder = builder.proxy_url(url.to_owned()); } + if let Some(color) = config.background_color { + builder = builder.background_color(color); + } builder } } @@ -270,6 +274,7 @@ impl WebviewAttributes { browser_extensions_enabled: false, use_https_scheme: false, devtools: None, + background_color: None, } } @@ -424,6 +429,17 @@ impl WebviewAttributes { self.devtools = enabled; self } + + /// Set the window and webview background color. + /// ## Platform-specific: + /// + /// - **Windows**: On Windows 7, alpha channel is ignored for the webview layer. + /// - **Windows**: On Windows 8 and newer, if alpha channel is not `0`, it will be ignored. + #[must_use] + pub fn background_color(mut self, color: Color) -> Self { + self.background_color = Some(color); + self + } } /// IPC handler. diff --git a/crates/tauri-runtime/src/window.rs b/crates/tauri-runtime/src/window.rs index 69f8eaf8a5c7..dc843100da98 100644 --- a/crates/tauri-runtime/src/window.rs +++ b/crates/tauri-runtime/src/window.rs @@ -11,7 +11,10 @@ use crate::{ use dpi::PixelUnit; use serde::{Deserialize, Deserializer, Serialize}; -use tauri_utils::{config::WindowConfig, Theme}; +use tauri_utils::{ + config::{Color, WindowConfig}, + Theme, +}; #[cfg(windows)] use windows::Win32::Foundation::HWND; @@ -354,6 +357,10 @@ pub trait WindowBuilder: WindowBuilderBase { #[must_use] fn skip_taskbar(self, skip: bool) -> Self; + /// Set the window background color. + #[must_use] + fn background_color(self, color: Color) -> Self; + /// Sets whether or not the window has shadow. /// /// ## Platform-specific diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json index a856b35b7cfb..4bc434e06f32 100644 --- a/crates/tauri-schema-generator/schemas/config.schema.json +++ b/crates/tauri-schema-generator/schemas/config.schema.json @@ -505,6 +505,17 @@ "boolean", "null" ] + }, + "backgroundColor": { + "description": "Set the window and webview background color.\n\n ## Platform-specific:\n\n - **Windows**: alpha channel is ignored for the window layer.\n - **Windows**: On Windows 7, alpha channel is ignored for the webview layer.\n - **Windows**: On Windows 8 and newer, if alpha channel is not `0`, it will be ignored for the webview layer.", + "anyOf": [ + { + "$ref": "#/definitions/Color" + }, + { + "type": "null" + } + ] } }, "additionalProperties": false @@ -846,32 +857,96 @@ ] }, "Color": { - "description": "a tuple struct of RGBA colors. Each value has minimum of 0 and maximum of 255.", - "type": "array", - "items": [ + "anyOf": [ { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Color hex string, for example: #fff, #ffffff, or #ffffffff.", + "type": "string", + "pattern": "^#?([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$" }, { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Array of RGB colors. Each value has minimum of 0 and maximum of 255.", + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + ], + "maxItems": 3, + "minItems": 3 }, { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Array of RGBA colors. Each value has minimum of 0 and maximum of 255.", + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + ], + "maxItems": 4, + "minItems": 4 }, { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Object of red, green, blue, alpha color values. Each value has minimum of 0 and maximum of 255.", + "type": "object", + "required": [ + "blue", + "green", + "red" + ], + "properties": { + "red": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "green": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "blue": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "alpha": { + "default": 255, + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + } } - ], - "maxItems": 4, - "minItems": 4 + ] }, "SecurityConfig": { "description": "Security configuration.\n\n See more: ", diff --git a/crates/tauri-schema-worker/src/config.rs b/crates/tauri-schema-worker/src/config.rs index 41669eceb344..b4c818b910bf 100644 --- a/crates/tauri-schema-worker/src/config.rs +++ b/crates/tauri-schema-worker/src/config.rs @@ -106,7 +106,7 @@ async fn try_next_schema() -> anyhow::Result { async fn schema_file_for_version(version: Version) -> anyhow::Result { let cache = Cache::open("schema".to_string()).await; - let cache_key = format!("https://scheam.tauri.app/config/{version}"); + let cache_key = format!("https://schema.tauri.app/config/{version}"); if let Some(mut cached) = cache.get(cache_key.clone(), true).await? { console_log!("Serving schema for {version} from cache"); return cached.text().await.map_err(Into::into); diff --git a/crates/tauri-utils/src/config.rs b/crates/tauri-utils/src/config.rs index 85fe4c8ac537..349873126393 100644 --- a/crates/tauri-utils/src/config.rs +++ b/crates/tauri-utils/src/config.rs @@ -1276,9 +1276,8 @@ pub struct BundleConfig { pub android: AndroidConfig, } -/// a tuple struct of RGBA colors. Each value has minimum of 0 and maximum of 255. -#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)] -#[cfg_attr(feature = "schema", derive(JsonSchema))] +/// A tuple struct of RGBA colors. Each value has minimum of 0 and maximum of 255. +#[derive(Debug, PartialEq, Eq, Serialize, Default, Clone, Copy)] #[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct Color(pub u8, pub u8, pub u8, pub u8); @@ -1288,6 +1287,139 @@ impl From for (u8, u8, u8, u8) { } } +impl From for (u8, u8, u8) { + fn from(value: Color) -> Self { + (value.0, value.1, value.2) + } +} + +impl From<(u8, u8, u8, u8)> for Color { + fn from(value: (u8, u8, u8, u8)) -> Self { + Color(value.0, value.1, value.2, value.3) + } +} + +impl From<(u8, u8, u8)> for Color { + fn from(value: (u8, u8, u8)) -> Self { + Color(value.0, value.1, value.2, 255) + } +} + +impl From for [u8; 4] { + fn from(value: Color) -> Self { + [value.0, value.1, value.2, value.3] + } +} + +impl From for [u8; 3] { + fn from(value: Color) -> Self { + [value.0, value.1, value.2] + } +} + +impl From<[u8; 4]> for Color { + fn from(value: [u8; 4]) -> Self { + Color(value[0], value[1], value[2], value[3]) + } +} + +impl From<[u8; 3]> for Color { + fn from(value: [u8; 3]) -> Self { + Color(value[0], value[1], value[2], 255) + } +} + +impl FromStr for Color { + type Err = String; + fn from_str(mut color: &str) -> Result { + color = color.trim().strip_prefix('#').unwrap_or(color); + let color = match color.len() { + // TODO: use repeat_n once our MSRV is bumped to 1.82 + 3 => color.chars() + .flat_map(|c| std::iter::repeat(c).take(2)) + .chain(std::iter::repeat('f').take(2)) + .collect(), + 6 => format!("{color}FF"), + 8 => color.to_string(), + _ => return Err("Invalid hex color length, must be either 3, 6 or 8, for example: #fff, #ffffff, or #ffffffff".into()), + }; + + let r = u8::from_str_radix(&color[0..2], 16).map_err(|e| e.to_string())?; + let g = u8::from_str_radix(&color[2..4], 16).map_err(|e| e.to_string())?; + let b = u8::from_str_radix(&color[4..6], 16).map_err(|e| e.to_string())?; + let a = u8::from_str_radix(&color[6..8], 16).map_err(|e| e.to_string())?; + + Ok(Color(r, g, b, a)) + } +} + +fn default_alpha() -> u8 { + 255 +} + +#[derive(Deserialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(untagged)] +enum InnerColor { + /// Color hex string, for example: #fff, #ffffff, or #ffffffff. + String(String), + /// Array of RGB colors. Each value has minimum of 0 and maximum of 255. + Rgb((u8, u8, u8)), + /// Array of RGBA colors. Each value has minimum of 0 and maximum of 255. + Rgba((u8, u8, u8, u8)), + /// Object of red, green, blue, alpha color values. Each value has minimum of 0 and maximum of 255. + RgbaObject { + red: u8, + green: u8, + blue: u8, + #[serde(default = "default_alpha")] + alpha: u8, + }, +} + +impl<'de> Deserialize<'de> for Color { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let color = InnerColor::deserialize(deserializer)?; + let color = match color { + InnerColor::String(string) => string.parse().map_err(serde::de::Error::custom)?, + InnerColor::Rgb(rgb) => Color(rgb.0, rgb.1, rgb.2, 255), + InnerColor::Rgba(rgb) => rgb.into(), + InnerColor::RgbaObject { + red, + green, + blue, + alpha, + } => Color(red, green, blue, alpha), + }; + + Ok(color) + } +} + +#[cfg(feature = "schema")] +impl schemars::JsonSchema for Color { + fn schema_name() -> String { + "Color".to_string() + } + + fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let mut schema = schemars::schema_for!(InnerColor).schema; + schema.metadata = None; // Remove `title: InnerColor` from schema + + // add hex color pattern validation + let any_of = schema.subschemas().any_of.as_mut().unwrap(); + let schemars::schema::Schema::Object(str_schema) = any_of.first_mut().unwrap() else { + unreachable!() + }; + str_schema.string().pattern = Some("^#?([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$".into()); + + schema.into() + } +} + /// The window effects configuration object #[skip_serializing_none] #[derive(Debug, PartialEq, Clone, Deserialize, Serialize, Default)] @@ -1502,6 +1634,7 @@ pub struct WindowConfig { /// ## Platform-specific /// /// - **macOS**: Requires the `macos-proxy` feature flag and only compiles for macOS 14+. + #[serde(alias = "proxy-url")] pub proxy_url: Option, /// Whether page zooming by hotkeys is enabled /// @@ -1512,7 +1645,7 @@ pub struct WindowConfig { /// 20% in each step, ranging from 20% to 1000%. Requires `webview:allow-set-webview-zoom` permission /// /// - **Android / iOS**: Unsupported. - #[serde(default)] + #[serde(default, alias = "zoom-hotkeys-enabled")] pub zoom_hotkeys_enabled: bool, /// Whether browser extensions can be installed for the webview process /// @@ -1520,7 +1653,7 @@ pub struct WindowConfig { /// /// - **Windows**: Enables the WebView2 environment's [`AreBrowserExtensionsEnabled`](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2environmentoptions?view=webview2-winrt-1.0.2739.15#arebrowserextensionsenabled) /// - **MacOS / Linux / iOS / Android** - Unsupported. - #[serde(default)] + #[serde(default, alias = "browser-extensions-enabled")] pub browser_extensions_enabled: bool, /// Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`. @@ -1544,6 +1677,16 @@ pub struct WindowConfig { /// - Android: Open `chrome://inspect/#devices` in Chrome to get the devtools window. Wry's `WebView` devtools API isn't supported on Android. /// - iOS: Open Safari > Develop > [Your Device Name] > [Your WebView] to get the devtools window. pub devtools: Option, + + /// Set the window and webview background color. + /// + /// ## Platform-specific: + /// + /// - **Windows**: alpha channel is ignored for the window layer. + /// - **Windows**: On Windows 7, alpha channel is ignored for the webview layer. + /// - **Windows**: On Windows 8 and newer, if alpha channel is not `0`, it will be ignored for the webview layer. + #[serde(alias = "background-color")] + pub background_color: Option, } impl Default for WindowConfig { @@ -1595,6 +1738,7 @@ impl Default for WindowConfig { browser_extensions_enabled: false, use_https_scheme: false, devtools: None, + background_color: None, } } } @@ -2847,6 +2991,7 @@ mod build { let browser_extensions_enabled = self.browser_extensions_enabled; let use_https_scheme = self.use_https_scheme; let devtools = opt_lit(self.devtools.as_ref()); + let background_color = opt_lit(self.background_color.as_ref()); literal_struct!( tokens, @@ -2896,7 +3041,8 @@ mod build { zoom_hotkeys_enabled, browser_extensions_enabled, use_https_scheme, - devtools + devtools, + background_color ); } } @@ -3390,4 +3536,15 @@ mod test { assert_eq!(d_bundle, bundle); assert_eq!(d_windows, app.windows); } + + #[test] + fn parse_hex_color() { + use super::Color; + + assert_eq!(Color(255, 255, 255, 255), "fff".parse().unwrap()); + assert_eq!(Color(255, 255, 255, 255), "#fff".parse().unwrap()); + assert_eq!(Color(0, 0, 0, 255), "#000000".parse().unwrap()); + assert_eq!(Color(0, 0, 0, 255), "#000000ff".parse().unwrap()); + assert_eq!(Color(0, 255, 0, 255), "#00ff00ff".parse().unwrap()); + } } diff --git a/crates/tauri/scripts/bundle.global.js b/crates/tauri/scripts/bundle.global.js index 316e09b65f99..760a790a1605 100644 --- a/crates/tauri/scripts/bundle.global.js +++ b/crates/tauri/scripts/bundle.global.js @@ -1 +1 @@ -var __TAURI_IIFE__=function(e){"use strict";function n(e,n,t,i){if("a"===t&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof n?e!==n||!i:!n.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===t?i:"a"===t?i.call(e):i?i.value:n.get(e)}function t(e,n,t,i,r){if("m"===i)throw new TypeError("Private method is not writable");if("a"===i&&!r)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof n?e!==n||!r:!n.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===i?r.call(e,t):r?r.value=t:n.set(e,t),t}var i,r,s,a;"function"==typeof SuppressedError&&SuppressedError;const l="__TAURI_TO_IPC_KEY__";function o(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}class u{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),r.set(this,0),s.set(this,{}),this.id=o((({message:e,id:a})=>{if(a===n(this,r,"f")){t(this,r,a+1,"f"),n(this,i,"f").call(this,e);const l=Object.keys(n(this,s,"f"));if(l.length>0){let e=a+1;for(const t of l.sort()){if(parseInt(t)!==e)break;{const r=n(this,s,"f")[t];delete n(this,s,"f")[t],n(this,i,"f").call(this,r),e+=1}}t(this,r,e,"f")}}else n(this,s,"f")[a.toString()]=e}))}set onmessage(e){t(this,i,e,"f")}get onmessage(){return n(this,i,"f")}[(i=new WeakMap,r=new WeakMap,s=new WeakMap,l)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[l]()}}class c{constructor(e,n,t){this.plugin=e,this.event=n,this.channelId=t}async unregister(){return d(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}}async function d(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}class h{get rid(){return n(this,a,"f")}constructor(e){a.set(this,void 0),t(this,a,e,"f")}async close(){return d("plugin:resources|close",{rid:this.rid})}}a=new WeakMap;var p=Object.freeze({__proto__:null,Channel:u,PluginListener:c,Resource:h,SERIALIZE_TO_IPC_FN:l,addPluginListener:async function(e,n,t){const i=new u;return i.onmessage=t,d(`plugin:${e}|registerListener`,{event:n,handler:i}).then((()=>new c(e,n,i.id)))},checkPermissions:async function(e){return d(`plugin:${e}|check_permissions`)},convertFileSrc:function(e,n="asset"){return window.__TAURI_INTERNALS__.convertFileSrc(e,n)},invoke:d,isTauri:function(){return"isTauri"in window&&!!window.isTauri},requestPermissions:async function(e){return d(`plugin:${e}|request_permissions`)},transformCallback:o});class w extends h{constructor(e){super(e)}static async new(e,n,t){return d("plugin:image|new",{rgba:y(e),width:n,height:t}).then((e=>new w(e)))}static async fromBytes(e){return d("plugin:image|from_bytes",{bytes:y(e)}).then((e=>new w(e)))}static async fromPath(e){return d("plugin:image|from_path",{path:e}).then((e=>new w(e)))}async rgba(){return d("plugin:image|rgba",{rid:this.rid}).then((e=>new Uint8Array(e)))}async size(){return d("plugin:image|size",{rid:this.rid})}}function y(e){return null==e?null:"string"==typeof e?e:e instanceof w?e.rid:e}var _=Object.freeze({__proto__:null,Image:w,transformImage:y});var g=Object.freeze({__proto__:null,defaultWindowIcon:async function(){return d("plugin:app|default_window_icon").then((e=>e?new w(e):null))},getName:async function(){return d("plugin:app|name")},getTauriVersion:async function(){return d("plugin:app|tauri_version")},getVersion:async function(){return d("plugin:app|version")},hide:async function(){return d("plugin:app|app_hide")},setTheme:async function(e){return d("plugin:app|set_app_theme",{theme:e})},show:async function(){return d("plugin:app|app_show")}});class b{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.width=e[0].Logical.width,this.height=e[0].Logical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toPhysical(e){return new m(this.width*e,this.height*e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class m{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.width=e[0].Physical.width,this.height=e[0].Physical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toLogical(e){return new b(this.width/e,this.height/e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class v{constructor(e){this.size=e}toLogical(e){return this.size instanceof b?this.size:this.size.toLogical(e)}toPhysical(e){return this.size instanceof m?this.size:this.size.toPhysical(e)}[l](){return{[`${this.size.type}`]:{width:this.size.width,height:this.size.height}}}toJSON(){return this[l]()}}class f{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.x=e[0].Logical.x,this.y=e[0].Logical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toPhysical(e){return new k(this.x*e,this.x*e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class k{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.x=e[0].Physical.x,this.y=e[0].Physical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toLogical(e){return new f(this.x/e,this.x/e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class A{constructor(e){this.position=e}toLogical(e){return this.position instanceof f?this.position:this.position.toLogical(e)}toPhysical(e){return this.position instanceof k?this.position:this.position.toPhysical(e)}[l](){return{[`${this.position.type}`]:{x:this.position.x,y:this.position.y}}}toJSON(){return this[l]()}}var E,T=Object.freeze({__proto__:null,LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,Position:A,Size:v});async function D(e,n){await d("plugin:event|unlisten",{event:e,eventId:n})}async function I(e,n,t){var i;const r="string"==typeof(null==t?void 0:t.target)?{kind:"AnyLabel",label:t.target}:null!==(i=null==t?void 0:t.target)&&void 0!==i?i:{kind:"Any"};return d("plugin:event|listen",{event:e,target:r,handler:o(n)}).then((n=>async()=>D(e,n)))}async function R(e,n,t){return I(e,(t=>{D(e,t.id),n(t)}),t)}async function S(e,n){await d("plugin:event|emit",{event:e,payload:n})}async function L(e,n,t){const i="string"==typeof e?{kind:"AnyLabel",label:e}:e;await d("plugin:event|emit_to",{target:i,event:n,payload:t})}!function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG_ENTER="tauri://drag-enter",e.DRAG_OVER="tauri://drag-over",e.DRAG_DROP="tauri://drag-drop",e.DRAG_LEAVE="tauri://drag-leave"}(E||(E={}));var x,N,C,P=Object.freeze({__proto__:null,get TauriEvent(){return E},emit:S,emitTo:L,listen:I,once:R});function z(e){var n;if("items"in e)e.items=null===(n=e.items)||void 0===n?void 0:n.map((e=>"rid"in e?e:z(e)));else if("action"in e&&e.action){const n=new u;return n.onmessage=e.action,delete e.action,{...e,handler:n}}return e}async function W(e,n){const t=new u;if(n&&"object"==typeof n&&("action"in n&&n.action&&(t.onmessage=n.action,delete n.action),"items"in n&&n.items)){function i(e){var n;return"rid"in e?[e.rid,e.kind]:("item"in e&&"object"==typeof e.item&&(null===(n=e.item.About)||void 0===n?void 0:n.icon)&&(e.item.About.icon=y(e.item.About.icon)),"icon"in e&&e.icon&&(e.icon=y(e.icon)),"items"in e&&e.items&&(e.items=e.items.map(i)),z(e))}n.items=n.items.map(i)}return d("plugin:menu|new",{kind:e,options:n,handler:t})}class O extends h{get id(){return n(this,x,"f")}get kind(){return n(this,N,"f")}constructor(e,n,i){super(e),x.set(this,void 0),N.set(this,void 0),t(this,x,n,"f"),t(this,N,i,"f")}}x=new WeakMap,N=new WeakMap;class F extends O{constructor(e,n){super(e,n,"MenuItem")}static async new(e){return W("MenuItem",e).then((([e,n])=>new F(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}}class M extends O{constructor(e,n){super(e,n,"Check")}static async new(e){return W("Check",e).then((([e,n])=>new M(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async isChecked(){return d("plugin:menu|is_checked",{rid:this.rid})}async setChecked(e){return d("plugin:menu|set_checked",{rid:this.rid,checked:e})}}!function(e){e.Add="Add",e.Advanced="Advanced",e.Bluetooth="Bluetooth",e.Bookmarks="Bookmarks",e.Caution="Caution",e.ColorPanel="ColorPanel",e.ColumnView="ColumnView",e.Computer="Computer",e.EnterFullScreen="EnterFullScreen",e.Everyone="Everyone",e.ExitFullScreen="ExitFullScreen",e.FlowView="FlowView",e.Folder="Folder",e.FolderBurnable="FolderBurnable",e.FolderSmart="FolderSmart",e.FollowLinkFreestanding="FollowLinkFreestanding",e.FontPanel="FontPanel",e.GoLeft="GoLeft",e.GoRight="GoRight",e.Home="Home",e.IChatTheater="IChatTheater",e.IconView="IconView",e.Info="Info",e.InvalidDataFreestanding="InvalidDataFreestanding",e.LeftFacingTriangle="LeftFacingTriangle",e.ListView="ListView",e.LockLocked="LockLocked",e.LockUnlocked="LockUnlocked",e.MenuMixedState="MenuMixedState",e.MenuOnState="MenuOnState",e.MobileMe="MobileMe",e.MultipleDocuments="MultipleDocuments",e.Network="Network",e.Path="Path",e.PreferencesGeneral="PreferencesGeneral",e.QuickLook="QuickLook",e.RefreshFreestanding="RefreshFreestanding",e.Refresh="Refresh",e.Remove="Remove",e.RevealFreestanding="RevealFreestanding",e.RightFacingTriangle="RightFacingTriangle",e.Share="Share",e.Slideshow="Slideshow",e.SmartBadge="SmartBadge",e.StatusAvailable="StatusAvailable",e.StatusNone="StatusNone",e.StatusPartiallyAvailable="StatusPartiallyAvailable",e.StatusUnavailable="StatusUnavailable",e.StopProgressFreestanding="StopProgressFreestanding",e.StopProgress="StopProgress",e.TrashEmpty="TrashEmpty",e.TrashFull="TrashFull",e.User="User",e.UserAccounts="UserAccounts",e.UserGroup="UserGroup",e.UserGuest="UserGuest"}(C||(C={}));class U extends O{constructor(e,n){super(e,n,"Icon")}static async new(e){return W("Icon",e).then((([e,n])=>new U(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async setIcon(e){return d("plugin:menu|set_icon",{rid:this.rid,icon:y(e)})}}class B extends O{constructor(e,n){super(e,n,"Predefined")}static async new(e){return W("Predefined",e).then((([e,n])=>new B(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}}function j([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class V extends O{constructor(e,n){super(e,n,"Submenu")}static async new(e){return W("Submenu",e).then((([e,n])=>new V(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(j)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(j)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?j(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsWindowsMenuForNSApp(){return d("plugin:menu|set_as_windows_menu_for_nsapp",{rid:this.rid})}async setAsHelpMenuForNSApp(){return d("plugin:menu|set_as_help_menu_for_nsapp",{rid:this.rid})}}function G([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class H extends O{constructor(e,n){super(e,n,"Menu")}static async new(e){return W("Menu",e).then((([e,n])=>new H(e,n)))}static async default(){return d("plugin:menu|create_default").then((([e,n])=>new H(e,n)))}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(G)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(G)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?G(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsAppMenu(){return d("plugin:menu|set_as_app_menu",{rid:this.rid}).then((e=>e?new H(e[0],e[1]):null))}async setAsWindowMenu(e){var n;return d("plugin:menu|set_as_window_menu",{rid:this.rid,window:null!==(n=null==e?void 0:e.label)&&void 0!==n?n:null}).then((e=>e?new H(e[0],e[1]):null))}}var $=Object.freeze({__proto__:null,CheckMenuItem:M,IconMenuItem:U,Menu:H,MenuItem:F,get NativeIcon(){return C},PredefinedMenuItem:B,Submenu:V});function q(){var e;window.__TAURI_INTERNALS__=null!==(e=window.__TAURI_INTERNALS__)&&void 0!==e?e:{}}var J,Q=Object.freeze({__proto__:null,clearMocks:function(){var e,n,t;"object"==typeof window.__TAURI_INTERNALS__&&((null===(e=window.__TAURI_INTERNALS__)||void 0===e?void 0:e.convertFileSrc)&&delete window.__TAURI_INTERNALS__.convertFileSrc,(null===(n=window.__TAURI_INTERNALS__)||void 0===n?void 0:n.invoke)&&delete window.__TAURI_INTERNALS__.invoke,(null===(t=window.__TAURI_INTERNALS__)||void 0===t?void 0:t.metadata)&&delete window.__TAURI_INTERNALS__.metadata)},mockConvertFileSrc:function(e){q(),window.__TAURI_INTERNALS__.convertFileSrc=function(n,t="asset"){const i=encodeURIComponent(n);return"windows"===e?`http://${t}.localhost/${i}`:`${t}://localhost/${i}`}},mockIPC:function(e){q(),window.__TAURI_INTERNALS__.transformCallback=function(e,n=!1){const t=window.crypto.getRandomValues(new Uint32Array(1))[0],i=`_${t}`;return Object.defineProperty(window,i,{value:t=>(n&&Reflect.deleteProperty(window,i),e&&e(t)),writable:!1,configurable:!0}),t},window.__TAURI_INTERNALS__.invoke=function(n,t,i){return e(n,t)}},mockWindows:function(e,...n){q(),window.__TAURI_INTERNALS__.metadata={currentWindow:{label:e},currentWebview:{windowLabel:e,label:e}}}});!function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Document=6]="Document",e[e.Download=7]="Download",e[e.Picture=8]="Picture",e[e.Public=9]="Public",e[e.Video=10]="Video",e[e.Resource=11]="Resource",e[e.Temp=12]="Temp",e[e.AppConfig=13]="AppConfig",e[e.AppData=14]="AppData",e[e.AppLocalData=15]="AppLocalData",e[e.AppCache=16]="AppCache",e[e.AppLog=17]="AppLog",e[e.Desktop=18]="Desktop",e[e.Executable=19]="Executable",e[e.Font=20]="Font",e[e.Home=21]="Home",e[e.Runtime=22]="Runtime",e[e.Template=23]="Template"}(J||(J={}));var Z=Object.freeze({__proto__:null,get BaseDirectory(){return J},appCacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppCache})},appConfigDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppConfig})},appDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppData})},appLocalDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLocalData})},appLogDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLog})},audioDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Audio})},basename:async function(e,n){return d("plugin:path|basename",{path:e,ext:n})},cacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Cache})},configDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Config})},dataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Data})},delimiter:function(){return window.__TAURI_INTERNALS__.plugins.path.delimiter},desktopDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Desktop})},dirname:async function(e){return d("plugin:path|dirname",{path:e})},documentDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Document})},downloadDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Download})},executableDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Executable})},extname:async function(e){return d("plugin:path|extname",{path:e})},fontDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Font})},homeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Home})},isAbsolute:async function(e){return d("plugin:path|isAbsolute",{path:e})},join:async function(...e){return d("plugin:path|join",{paths:e})},localDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.LocalData})},normalize:async function(e){return d("plugin:path|normalize",{path:e})},pictureDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Picture})},publicDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Public})},resolve:async function(...e){return d("plugin:path|resolve",{paths:e})},resolveResource:async function(e){return d("plugin:path|resolve_directory",{directory:J.Resource,path:e})},resourceDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Resource})},runtimeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Runtime})},sep:function(){return window.__TAURI_INTERNALS__.plugins.path.sep},tempDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Temp})},templateDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Template})},videoDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Video})}});class K extends h{constructor(e,n){super(e),this.id=n}static async getById(e){return d("plugin:tray|get_by_id",{id:e}).then((n=>n?new K(n,e):null))}static async removeById(e){return d("plugin:tray|remove_by_id",{id:e})}static async new(e){(null==e?void 0:e.menu)&&(e.menu=[e.menu.rid,e.menu.kind]),(null==e?void 0:e.icon)&&(e.icon=y(e.icon));const n=new u;if(null==e?void 0:e.action){const t=e.action;n.onmessage=e=>t(function(e){const n=e;return n.position=new k(e.position),n.rect.position=new k(e.rect.position),n.rect.size=new m(e.rect.size),n}(e)),delete e.action}return d("plugin:tray|new",{options:null!=e?e:{},handler:n}).then((([e,n])=>new K(e,n)))}async setIcon(e){let n=null;return e&&(n=y(e)),d("plugin:tray|set_icon",{rid:this.rid,icon:n})}async setMenu(e){return e&&(e=[e.rid,e.kind]),d("plugin:tray|set_menu",{rid:this.rid,menu:e})}async setTooltip(e){return d("plugin:tray|set_tooltip",{rid:this.rid,tooltip:e})}async setTitle(e){return d("plugin:tray|set_title",{rid:this.rid,title:e})}async setVisible(e){return d("plugin:tray|set_visible",{rid:this.rid,visible:e})}async setTempDirPath(e){return d("plugin:tray|set_temp_dir_path",{rid:this.rid,path:e})}async setIconAsTemplate(e){return d("plugin:tray|set_icon_as_template",{rid:this.rid,asTemplate:e})}async setMenuOnLeftClick(e){return d("plugin:tray|set_show_menu_on_left_click",{rid:this.rid,onLeft:e})}}var Y,X,ee=Object.freeze({__proto__:null,TrayIcon:K});!function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"}(Y||(Y={}));class ne{constructor(e){this._preventDefault=!1,this.event=e.event,this.id=e.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}function te(){return new se(window.__TAURI_INTERNALS__.metadata.currentWindow.label,{skip:!0})}async function ie(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new se(e,{skip:!0})))))}!function(e){e.None="none",e.Normal="normal",e.Indeterminate="indeterminate",e.Paused="paused",e.Error="error"}(X||(X={}));const re=["tauri://created","tauri://error"];class se{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:window|create",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await ie()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return te()}static async getAll(){return ie()}static async getFocusedWindow(){for(const e of await ie())if(await e.isFocused())return e;return null}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Window",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Window",label:this.label}})}async emit(e,n){if(!re.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!re.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!re.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async scaleFactor(){return d("plugin:window|scale_factor",{label:this.label})}async innerPosition(){return d("plugin:window|inner_position",{label:this.label}).then((e=>new k(e)))}async outerPosition(){return d("plugin:window|outer_position",{label:this.label}).then((e=>new k(e)))}async innerSize(){return d("plugin:window|inner_size",{label:this.label}).then((e=>new m(e)))}async outerSize(){return d("plugin:window|outer_size",{label:this.label}).then((e=>new m(e)))}async isFullscreen(){return d("plugin:window|is_fullscreen",{label:this.label})}async isMinimized(){return d("plugin:window|is_minimized",{label:this.label})}async isMaximized(){return d("plugin:window|is_maximized",{label:this.label})}async isFocused(){return d("plugin:window|is_focused",{label:this.label})}async isDecorated(){return d("plugin:window|is_decorated",{label:this.label})}async isResizable(){return d("plugin:window|is_resizable",{label:this.label})}async isMaximizable(){return d("plugin:window|is_maximizable",{label:this.label})}async isMinimizable(){return d("plugin:window|is_minimizable",{label:this.label})}async isClosable(){return d("plugin:window|is_closable",{label:this.label})}async isVisible(){return d("plugin:window|is_visible",{label:this.label})}async title(){return d("plugin:window|title",{label:this.label})}async theme(){return d("plugin:window|theme",{label:this.label})}async center(){return d("plugin:window|center",{label:this.label})}async requestUserAttention(e){let n=null;return e&&(n=e===Y.Critical?{type:"Critical"}:{type:"Informational"}),d("plugin:window|request_user_attention",{label:this.label,value:n})}async setResizable(e){return d("plugin:window|set_resizable",{label:this.label,value:e})}async setEnabled(e){return d("plugin:window|set_enabled",{label:this.label,value:e})}async isEnabled(){return d("plugin:window|is_enabled",{label:this.label})}async setMaximizable(e){return d("plugin:window|set_maximizable",{label:this.label,value:e})}async setMinimizable(e){return d("plugin:window|set_minimizable",{label:this.label,value:e})}async setClosable(e){return d("plugin:window|set_closable",{label:this.label,value:e})}async setTitle(e){return d("plugin:window|set_title",{label:this.label,value:e})}async maximize(){return d("plugin:window|maximize",{label:this.label})}async unmaximize(){return d("plugin:window|unmaximize",{label:this.label})}async toggleMaximize(){return d("plugin:window|toggle_maximize",{label:this.label})}async minimize(){return d("plugin:window|minimize",{label:this.label})}async unminimize(){return d("plugin:window|unminimize",{label:this.label})}async show(){return d("plugin:window|show",{label:this.label})}async hide(){return d("plugin:window|hide",{label:this.label})}async close(){return d("plugin:window|close",{label:this.label})}async destroy(){return d("plugin:window|destroy",{label:this.label})}async setDecorations(e){return d("plugin:window|set_decorations",{label:this.label,value:e})}async setShadow(e){return d("plugin:window|set_shadow",{label:this.label,value:e})}async setEffects(e){return d("plugin:window|set_effects",{label:this.label,value:e})}async clearEffects(){return d("plugin:window|set_effects",{label:this.label,value:null})}async setAlwaysOnTop(e){return d("plugin:window|set_always_on_top",{label:this.label,value:e})}async setAlwaysOnBottom(e){return d("plugin:window|set_always_on_bottom",{label:this.label,value:e})}async setContentProtected(e){return d("plugin:window|set_content_protected",{label:this.label,value:e})}async setSize(e){return d("plugin:window|set_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setMinSize(e){return d("plugin:window|set_min_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setMaxSize(e){return d("plugin:window|set_max_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setSizeConstraints(e){function n(e){return e?{Logical:e}:null}return d("plugin:window|set_size_constraints",{label:this.label,value:{minWidth:n(null==e?void 0:e.minWidth),minHeight:n(null==e?void 0:e.minHeight),maxWidth:n(null==e?void 0:e.maxWidth),maxHeight:n(null==e?void 0:e.maxHeight)}})}async setPosition(e){return d("plugin:window|set_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFullscreen(e){return d("plugin:window|set_fullscreen",{label:this.label,value:e})}async setFocus(){return d("plugin:window|set_focus",{label:this.label})}async setIcon(e){return d("plugin:window|set_icon",{label:this.label,value:y(e)})}async setSkipTaskbar(e){return d("plugin:window|set_skip_taskbar",{label:this.label,value:e})}async setCursorGrab(e){return d("plugin:window|set_cursor_grab",{label:this.label,value:e})}async setCursorVisible(e){return d("plugin:window|set_cursor_visible",{label:this.label,value:e})}async setCursorIcon(e){return d("plugin:window|set_cursor_icon",{label:this.label,value:e})}async setCursorPosition(e){return d("plugin:window|set_cursor_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setIgnoreCursorEvents(e){return d("plugin:window|set_ignore_cursor_events",{label:this.label,value:e})}async startDragging(){return d("plugin:window|start_dragging",{label:this.label})}async startResizeDragging(e){return d("plugin:window|start_resize_dragging",{label:this.label,value:e})}async setProgressBar(e){return d("plugin:window|set_progress_bar",{label:this.label,value:e})}async setVisibleOnAllWorkspaces(e){return d("plugin:window|set_visible_on_all_workspaces",{label:this.label,value:e})}async setTitleBarStyle(e){return d("plugin:window|set_title_bar_style",{label:this.label,value:e})}async setTheme(e){return d("plugin:window|set_theme",{label:this.label,value:e})}async onResized(e){return this.listen(E.WINDOW_RESIZED,(n=>{n.payload=new m(n.payload),e(n)}))}async onMoved(e){return this.listen(E.WINDOW_MOVED,(n=>{n.payload=new k(n.payload),e(n)}))}async onCloseRequested(e){return this.listen(E.WINDOW_CLOSE_REQUESTED,(async n=>{const t=new ne(n);await e(t),t.isPreventDefault()||await this.destroy()}))}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}async onFocusChanged(e){const n=await this.listen(E.WINDOW_FOCUS,(n=>{e({...n,payload:!0})})),t=await this.listen(E.WINDOW_BLUR,(n=>{e({...n,payload:!1})}));return()=>{n(),t()}}async onScaleChanged(e){return this.listen(E.WINDOW_SCALE_FACTOR_CHANGED,e)}async onThemeChanged(e){return this.listen(E.WINDOW_THEME_CHANGED,e)}}var ae,le;function oe(e){return null===e?null:{name:e.name,scaleFactor:e.scaleFactor,position:new k(e.position),size:new m(e.size)}}!function(e){e.AppearanceBased="appearanceBased",e.Light="light",e.Dark="dark",e.MediumLight="mediumLight",e.UltraDark="ultraDark",e.Titlebar="titlebar",e.Selection="selection",e.Menu="menu",e.Popover="popover",e.Sidebar="sidebar",e.HeaderView="headerView",e.Sheet="sheet",e.WindowBackground="windowBackground",e.HudWindow="hudWindow",e.FullScreenUI="fullScreenUI",e.Tooltip="tooltip",e.ContentBackground="contentBackground",e.UnderWindowBackground="underWindowBackground",e.UnderPageBackground="underPageBackground",e.Mica="mica",e.Blur="blur",e.Acrylic="acrylic",e.Tabbed="tabbed",e.TabbedDark="tabbedDark",e.TabbedLight="tabbedLight"}(ae||(ae={})),function(e){e.FollowsWindowActiveState="followsWindowActiveState",e.Active="active",e.Inactive="inactive"}(le||(le={}));var ue=Object.freeze({__proto__:null,CloseRequestedEvent:ne,get Effect(){return ae},get EffectState(){return le},LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,get ProgressBarStatus(){return X},get UserAttentionType(){return Y},Window:se,availableMonitors:async function(){return d("plugin:window|available_monitors").then((e=>e.map(oe)))},currentMonitor:async function(){return d("plugin:window|current_monitor").then(oe)},cursorPosition:async function(){return d("plugin:window|cursor_position").then((e=>new k(e)))},getAllWindows:ie,getCurrentWindow:te,monitorFromPoint:async function(e,n){return d("plugin:window|monitor_from_point",{x:e,y:n}).then(oe)},primaryMonitor:async function(){return d("plugin:window|primary_monitor").then(oe)}});function ce(){return new pe(te(),window.__TAURI_INTERNALS__.metadata.currentWebview.label,{skip:!0})}async function de(){return d("plugin:webview|get_all_webviews").then((e=>e.map((e=>new pe(new se(e.windowLabel,{skip:!0}),e.label,{skip:!0})))))}const he=["tauri://created","tauri://error"];class pe{constructor(e,n,t){this.window=e,this.label=n,this.listeners=Object.create(null),(null==t?void 0:t.skip)||d("plugin:webview|create_webview",{windowLabel:e.label,label:n,options:t}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await de()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return ce()}static async getAll(){return de()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Webview",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Webview",label:this.label}})}async emit(e,n){if(!he.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!he.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!he.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async position(){return d("plugin:webview|webview_position",{label:this.label}).then((e=>new k(e)))}async size(){return d("plugin:webview|webview_size",{label:this.label}).then((e=>new m(e)))}async close(){return d("plugin:webview|close",{label:this.label})}async setSize(e){return d("plugin:webview|set_webview_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setPosition(e){return d("plugin:webview|set_webview_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFocus(){return d("plugin:webview|set_webview_focus",{label:this.label})}async hide(){return d("plugin:webview|webview_hide",{label:this.label})}async show(){return d("plugin:webview|webview_show",{label:this.label})}async setZoom(e){return d("plugin:webview|set_webview_zoom",{label:this.label,value:e})}async reparent(e){return d("plugin:webview|reparent",{label:this.label,window:"string"==typeof e?e:e.label})}async clearAllBrowsingData(){return d("plugin:webview|clear_all_browsing_data")}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}}var we,ye,_e=Object.freeze({__proto__:null,Webview:pe,getAllWebviews:de,getCurrentWebview:ce});function ge(){const e=ce();return new me(e.label,{skip:!0})}async function be(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new me(e,{skip:!0})))))}class me{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:webview|create_webview_window",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;const t=null!==(n=(await be()).find((n=>n.label===e)))&&void 0!==n?n:null;return t?new me(t.label,{skip:!0}):null}static getCurrent(){return ge()}static async getAll(){return be()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"WebviewWindow",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"WebviewWindow",label:this.label}})}}we=me,ye=[se,pe],(Array.isArray(ye)?ye:[ye]).forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((n=>{var t;"object"==typeof we.prototype&&we.prototype&&n in we.prototype||Object.defineProperty(we.prototype,n,null!==(t=Object.getOwnPropertyDescriptor(e.prototype,n))&&void 0!==t?t:Object.create(null))}))}));var ve=Object.freeze({__proto__:null,WebviewWindow:me,getAllWebviewWindows:be,getCurrentWebviewWindow:ge});return e.app=g,e.core=p,e.dpi=T,e.event=P,e.image=_,e.menu=$,e.mocks=Q,e.path=Z,e.tray=ee,e.webview=_e,e.webviewWindow=ve,e.window=ue,e}({});window.__TAURI__=__TAURI_IIFE__; +var __TAURI_IIFE__=function(e){"use strict";function n(e,n,t,i){if("a"===t&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof n?e!==n||!i:!n.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===t?i:"a"===t?i.call(e):i?i.value:n.get(e)}function t(e,n,t,i,r){if("m"===i)throw new TypeError("Private method is not writable");if("a"===i&&!r)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof n?e!==n||!r:!n.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===i?r.call(e,t):r?r.value=t:n.set(e,t),t}var i,r,s,a;"function"==typeof SuppressedError&&SuppressedError;const l="__TAURI_TO_IPC_KEY__";function o(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}class u{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),r.set(this,0),s.set(this,{}),this.id=o((({message:e,id:a})=>{if(a===n(this,r,"f")){t(this,r,a+1,"f"),n(this,i,"f").call(this,e);const l=Object.keys(n(this,s,"f"));if(l.length>0){let e=a+1;for(const t of l.sort()){if(parseInt(t)!==e)break;{const r=n(this,s,"f")[t];delete n(this,s,"f")[t],n(this,i,"f").call(this,r),e+=1}}t(this,r,e,"f")}}else n(this,s,"f")[a.toString()]=e}))}set onmessage(e){t(this,i,e,"f")}get onmessage(){return n(this,i,"f")}[(i=new WeakMap,r=new WeakMap,s=new WeakMap,l)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[l]()}}class c{constructor(e,n,t){this.plugin=e,this.event=n,this.channelId=t}async unregister(){return d(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}}async function d(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}class h{get rid(){return n(this,a,"f")}constructor(e){a.set(this,void 0),t(this,a,e,"f")}async close(){return d("plugin:resources|close",{rid:this.rid})}}a=new WeakMap;var p=Object.freeze({__proto__:null,Channel:u,PluginListener:c,Resource:h,SERIALIZE_TO_IPC_FN:l,addPluginListener:async function(e,n,t){const i=new u;return i.onmessage=t,d(`plugin:${e}|registerListener`,{event:n,handler:i}).then((()=>new c(e,n,i.id)))},checkPermissions:async function(e){return d(`plugin:${e}|check_permissions`)},convertFileSrc:function(e,n="asset"){return window.__TAURI_INTERNALS__.convertFileSrc(e,n)},invoke:d,isTauri:function(){return"isTauri"in window&&!!window.isTauri},requestPermissions:async function(e){return d(`plugin:${e}|request_permissions`)},transformCallback:o});class w extends h{constructor(e){super(e)}static async new(e,n,t){return d("plugin:image|new",{rgba:y(e),width:n,height:t}).then((e=>new w(e)))}static async fromBytes(e){return d("plugin:image|from_bytes",{bytes:y(e)}).then((e=>new w(e)))}static async fromPath(e){return d("plugin:image|from_path",{path:e}).then((e=>new w(e)))}async rgba(){return d("plugin:image|rgba",{rid:this.rid}).then((e=>new Uint8Array(e)))}async size(){return d("plugin:image|size",{rid:this.rid})}}function y(e){return null==e?null:"string"==typeof e?e:e instanceof w?e.rid:e}var _=Object.freeze({__proto__:null,Image:w,transformImage:y});var g=Object.freeze({__proto__:null,defaultWindowIcon:async function(){return d("plugin:app|default_window_icon").then((e=>e?new w(e):null))},getName:async function(){return d("plugin:app|name")},getTauriVersion:async function(){return d("plugin:app|tauri_version")},getVersion:async function(){return d("plugin:app|version")},hide:async function(){return d("plugin:app|app_hide")},setTheme:async function(e){return d("plugin:app|set_app_theme",{theme:e})},show:async function(){return d("plugin:app|app_show")}});class b{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.width=e[0].Logical.width,this.height=e[0].Logical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toPhysical(e){return new m(this.width*e,this.height*e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class m{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.width=e[0].Physical.width,this.height=e[0].Physical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toLogical(e){return new b(this.width/e,this.height/e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class v{constructor(e){this.size=e}toLogical(e){return this.size instanceof b?this.size:this.size.toLogical(e)}toPhysical(e){return this.size instanceof m?this.size:this.size.toPhysical(e)}[l](){return{[`${this.size.type}`]:{width:this.size.width,height:this.size.height}}}toJSON(){return this[l]()}}class f{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.x=e[0].Logical.x,this.y=e[0].Logical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toPhysical(e){return new k(this.x*e,this.x*e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class k{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.x=e[0].Physical.x,this.y=e[0].Physical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toLogical(e){return new f(this.x/e,this.x/e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class A{constructor(e){this.position=e}toLogical(e){return this.position instanceof f?this.position:this.position.toLogical(e)}toPhysical(e){return this.position instanceof k?this.position:this.position.toPhysical(e)}[l](){return{[`${this.position.type}`]:{x:this.position.x,y:this.position.y}}}toJSON(){return this[l]()}}var E,T=Object.freeze({__proto__:null,LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,Position:A,Size:v});async function D(e,n){await d("plugin:event|unlisten",{event:e,eventId:n})}async function I(e,n,t){var i;const r="string"==typeof(null==t?void 0:t.target)?{kind:"AnyLabel",label:t.target}:null!==(i=null==t?void 0:t.target)&&void 0!==i?i:{kind:"Any"};return d("plugin:event|listen",{event:e,target:r,handler:o(n)}).then((n=>async()=>D(e,n)))}async function R(e,n,t){return I(e,(t=>{D(e,t.id),n(t)}),t)}async function S(e,n){await d("plugin:event|emit",{event:e,payload:n})}async function L(e,n,t){const i="string"==typeof e?{kind:"AnyLabel",label:e}:e;await d("plugin:event|emit_to",{target:i,event:n,payload:t})}!function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG_ENTER="tauri://drag-enter",e.DRAG_OVER="tauri://drag-over",e.DRAG_DROP="tauri://drag-drop",e.DRAG_LEAVE="tauri://drag-leave"}(E||(E={}));var x,C,N,P=Object.freeze({__proto__:null,get TauriEvent(){return E},emit:S,emitTo:L,listen:I,once:R});function z(e){var n;if("items"in e)e.items=null===(n=e.items)||void 0===n?void 0:n.map((e=>"rid"in e?e:z(e)));else if("action"in e&&e.action){const n=new u;return n.onmessage=e.action,delete e.action,{...e,handler:n}}return e}async function W(e,n){const t=new u;if(n&&"object"==typeof n&&("action"in n&&n.action&&(t.onmessage=n.action,delete n.action),"items"in n&&n.items)){function i(e){var n;return"rid"in e?[e.rid,e.kind]:("item"in e&&"object"==typeof e.item&&(null===(n=e.item.About)||void 0===n?void 0:n.icon)&&(e.item.About.icon=y(e.item.About.icon)),"icon"in e&&e.icon&&(e.icon=y(e.icon)),"items"in e&&e.items&&(e.items=e.items.map(i)),z(e))}n.items=n.items.map(i)}return d("plugin:menu|new",{kind:e,options:n,handler:t})}class O extends h{get id(){return n(this,x,"f")}get kind(){return n(this,C,"f")}constructor(e,n,i){super(e),x.set(this,void 0),C.set(this,void 0),t(this,x,n,"f"),t(this,C,i,"f")}}x=new WeakMap,C=new WeakMap;class F extends O{constructor(e,n){super(e,n,"MenuItem")}static async new(e){return W("MenuItem",e).then((([e,n])=>new F(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}}class M extends O{constructor(e,n){super(e,n,"Check")}static async new(e){return W("Check",e).then((([e,n])=>new M(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async isChecked(){return d("plugin:menu|is_checked",{rid:this.rid})}async setChecked(e){return d("plugin:menu|set_checked",{rid:this.rid,checked:e})}}!function(e){e.Add="Add",e.Advanced="Advanced",e.Bluetooth="Bluetooth",e.Bookmarks="Bookmarks",e.Caution="Caution",e.ColorPanel="ColorPanel",e.ColumnView="ColumnView",e.Computer="Computer",e.EnterFullScreen="EnterFullScreen",e.Everyone="Everyone",e.ExitFullScreen="ExitFullScreen",e.FlowView="FlowView",e.Folder="Folder",e.FolderBurnable="FolderBurnable",e.FolderSmart="FolderSmart",e.FollowLinkFreestanding="FollowLinkFreestanding",e.FontPanel="FontPanel",e.GoLeft="GoLeft",e.GoRight="GoRight",e.Home="Home",e.IChatTheater="IChatTheater",e.IconView="IconView",e.Info="Info",e.InvalidDataFreestanding="InvalidDataFreestanding",e.LeftFacingTriangle="LeftFacingTriangle",e.ListView="ListView",e.LockLocked="LockLocked",e.LockUnlocked="LockUnlocked",e.MenuMixedState="MenuMixedState",e.MenuOnState="MenuOnState",e.MobileMe="MobileMe",e.MultipleDocuments="MultipleDocuments",e.Network="Network",e.Path="Path",e.PreferencesGeneral="PreferencesGeneral",e.QuickLook="QuickLook",e.RefreshFreestanding="RefreshFreestanding",e.Refresh="Refresh",e.Remove="Remove",e.RevealFreestanding="RevealFreestanding",e.RightFacingTriangle="RightFacingTriangle",e.Share="Share",e.Slideshow="Slideshow",e.SmartBadge="SmartBadge",e.StatusAvailable="StatusAvailable",e.StatusNone="StatusNone",e.StatusPartiallyAvailable="StatusPartiallyAvailable",e.StatusUnavailable="StatusUnavailable",e.StopProgressFreestanding="StopProgressFreestanding",e.StopProgress="StopProgress",e.TrashEmpty="TrashEmpty",e.TrashFull="TrashFull",e.User="User",e.UserAccounts="UserAccounts",e.UserGroup="UserGroup",e.UserGuest="UserGuest"}(N||(N={}));class U extends O{constructor(e,n){super(e,n,"Icon")}static async new(e){return W("Icon",e).then((([e,n])=>new U(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async setIcon(e){return d("plugin:menu|set_icon",{rid:this.rid,icon:y(e)})}}class B extends O{constructor(e,n){super(e,n,"Predefined")}static async new(e){return W("Predefined",e).then((([e,n])=>new B(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}}function j([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class V extends O{constructor(e,n){super(e,n,"Submenu")}static async new(e){return W("Submenu",e).then((([e,n])=>new V(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(j)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(j)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?j(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsWindowsMenuForNSApp(){return d("plugin:menu|set_as_windows_menu_for_nsapp",{rid:this.rid})}async setAsHelpMenuForNSApp(){return d("plugin:menu|set_as_help_menu_for_nsapp",{rid:this.rid})}}function G([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class H extends O{constructor(e,n){super(e,n,"Menu")}static async new(e){return W("Menu",e).then((([e,n])=>new H(e,n)))}static async default(){return d("plugin:menu|create_default").then((([e,n])=>new H(e,n)))}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(G)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(G)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?G(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsAppMenu(){return d("plugin:menu|set_as_app_menu",{rid:this.rid}).then((e=>e?new H(e[0],e[1]):null))}async setAsWindowMenu(e){var n;return d("plugin:menu|set_as_window_menu",{rid:this.rid,window:null!==(n=null==e?void 0:e.label)&&void 0!==n?n:null}).then((e=>e?new H(e[0],e[1]):null))}}var $=Object.freeze({__proto__:null,CheckMenuItem:M,IconMenuItem:U,Menu:H,MenuItem:F,get NativeIcon(){return N},PredefinedMenuItem:B,Submenu:V});function q(){var e;window.__TAURI_INTERNALS__=null!==(e=window.__TAURI_INTERNALS__)&&void 0!==e?e:{}}var J,Q=Object.freeze({__proto__:null,clearMocks:function(){var e,n,t;"object"==typeof window.__TAURI_INTERNALS__&&((null===(e=window.__TAURI_INTERNALS__)||void 0===e?void 0:e.convertFileSrc)&&delete window.__TAURI_INTERNALS__.convertFileSrc,(null===(n=window.__TAURI_INTERNALS__)||void 0===n?void 0:n.invoke)&&delete window.__TAURI_INTERNALS__.invoke,(null===(t=window.__TAURI_INTERNALS__)||void 0===t?void 0:t.metadata)&&delete window.__TAURI_INTERNALS__.metadata)},mockConvertFileSrc:function(e){q(),window.__TAURI_INTERNALS__.convertFileSrc=function(n,t="asset"){const i=encodeURIComponent(n);return"windows"===e?`http://${t}.localhost/${i}`:`${t}://localhost/${i}`}},mockIPC:function(e){q(),window.__TAURI_INTERNALS__.transformCallback=function(e,n=!1){const t=window.crypto.getRandomValues(new Uint32Array(1))[0],i=`_${t}`;return Object.defineProperty(window,i,{value:t=>(n&&Reflect.deleteProperty(window,i),e&&e(t)),writable:!1,configurable:!0}),t},window.__TAURI_INTERNALS__.invoke=function(n,t,i){return e(n,t)}},mockWindows:function(e,...n){q(),window.__TAURI_INTERNALS__.metadata={currentWindow:{label:e},currentWebview:{windowLabel:e,label:e}}}});!function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Document=6]="Document",e[e.Download=7]="Download",e[e.Picture=8]="Picture",e[e.Public=9]="Public",e[e.Video=10]="Video",e[e.Resource=11]="Resource",e[e.Temp=12]="Temp",e[e.AppConfig=13]="AppConfig",e[e.AppData=14]="AppData",e[e.AppLocalData=15]="AppLocalData",e[e.AppCache=16]="AppCache",e[e.AppLog=17]="AppLog",e[e.Desktop=18]="Desktop",e[e.Executable=19]="Executable",e[e.Font=20]="Font",e[e.Home=21]="Home",e[e.Runtime=22]="Runtime",e[e.Template=23]="Template"}(J||(J={}));var Z=Object.freeze({__proto__:null,get BaseDirectory(){return J},appCacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppCache})},appConfigDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppConfig})},appDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppData})},appLocalDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLocalData})},appLogDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLog})},audioDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Audio})},basename:async function(e,n){return d("plugin:path|basename",{path:e,ext:n})},cacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Cache})},configDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Config})},dataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Data})},delimiter:function(){return window.__TAURI_INTERNALS__.plugins.path.delimiter},desktopDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Desktop})},dirname:async function(e){return d("plugin:path|dirname",{path:e})},documentDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Document})},downloadDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Download})},executableDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Executable})},extname:async function(e){return d("plugin:path|extname",{path:e})},fontDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Font})},homeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Home})},isAbsolute:async function(e){return d("plugin:path|isAbsolute",{path:e})},join:async function(...e){return d("plugin:path|join",{paths:e})},localDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.LocalData})},normalize:async function(e){return d("plugin:path|normalize",{path:e})},pictureDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Picture})},publicDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Public})},resolve:async function(...e){return d("plugin:path|resolve",{paths:e})},resolveResource:async function(e){return d("plugin:path|resolve_directory",{directory:J.Resource,path:e})},resourceDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Resource})},runtimeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Runtime})},sep:function(){return window.__TAURI_INTERNALS__.plugins.path.sep},tempDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Temp})},templateDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Template})},videoDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Video})}});class K extends h{constructor(e,n){super(e),this.id=n}static async getById(e){return d("plugin:tray|get_by_id",{id:e}).then((n=>n?new K(n,e):null))}static async removeById(e){return d("plugin:tray|remove_by_id",{id:e})}static async new(e){(null==e?void 0:e.menu)&&(e.menu=[e.menu.rid,e.menu.kind]),(null==e?void 0:e.icon)&&(e.icon=y(e.icon));const n=new u;if(null==e?void 0:e.action){const t=e.action;n.onmessage=e=>t(function(e){const n=e;return n.position=new k(e.position),n.rect.position=new k(e.rect.position),n.rect.size=new m(e.rect.size),n}(e)),delete e.action}return d("plugin:tray|new",{options:null!=e?e:{},handler:n}).then((([e,n])=>new K(e,n)))}async setIcon(e){let n=null;return e&&(n=y(e)),d("plugin:tray|set_icon",{rid:this.rid,icon:n})}async setMenu(e){return e&&(e=[e.rid,e.kind]),d("plugin:tray|set_menu",{rid:this.rid,menu:e})}async setTooltip(e){return d("plugin:tray|set_tooltip",{rid:this.rid,tooltip:e})}async setTitle(e){return d("plugin:tray|set_title",{rid:this.rid,title:e})}async setVisible(e){return d("plugin:tray|set_visible",{rid:this.rid,visible:e})}async setTempDirPath(e){return d("plugin:tray|set_temp_dir_path",{rid:this.rid,path:e})}async setIconAsTemplate(e){return d("plugin:tray|set_icon_as_template",{rid:this.rid,asTemplate:e})}async setMenuOnLeftClick(e){return d("plugin:tray|set_show_menu_on_left_click",{rid:this.rid,onLeft:e})}}var Y,X,ee=Object.freeze({__proto__:null,TrayIcon:K});!function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"}(Y||(Y={}));class ne{constructor(e){this._preventDefault=!1,this.event=e.event,this.id=e.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}function te(){return new se(window.__TAURI_INTERNALS__.metadata.currentWindow.label,{skip:!0})}async function ie(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new se(e,{skip:!0})))))}!function(e){e.None="none",e.Normal="normal",e.Indeterminate="indeterminate",e.Paused="paused",e.Error="error"}(X||(X={}));const re=["tauri://created","tauri://error"];class se{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:window|create",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await ie()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return te()}static async getAll(){return ie()}static async getFocusedWindow(){for(const e of await ie())if(await e.isFocused())return e;return null}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Window",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Window",label:this.label}})}async emit(e,n){if(!re.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!re.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!re.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async scaleFactor(){return d("plugin:window|scale_factor",{label:this.label})}async innerPosition(){return d("plugin:window|inner_position",{label:this.label}).then((e=>new k(e)))}async outerPosition(){return d("plugin:window|outer_position",{label:this.label}).then((e=>new k(e)))}async innerSize(){return d("plugin:window|inner_size",{label:this.label}).then((e=>new m(e)))}async outerSize(){return d("plugin:window|outer_size",{label:this.label}).then((e=>new m(e)))}async isFullscreen(){return d("plugin:window|is_fullscreen",{label:this.label})}async isMinimized(){return d("plugin:window|is_minimized",{label:this.label})}async isMaximized(){return d("plugin:window|is_maximized",{label:this.label})}async isFocused(){return d("plugin:window|is_focused",{label:this.label})}async isDecorated(){return d("plugin:window|is_decorated",{label:this.label})}async isResizable(){return d("plugin:window|is_resizable",{label:this.label})}async isMaximizable(){return d("plugin:window|is_maximizable",{label:this.label})}async isMinimizable(){return d("plugin:window|is_minimizable",{label:this.label})}async isClosable(){return d("plugin:window|is_closable",{label:this.label})}async isVisible(){return d("plugin:window|is_visible",{label:this.label})}async title(){return d("plugin:window|title",{label:this.label})}async theme(){return d("plugin:window|theme",{label:this.label})}async center(){return d("plugin:window|center",{label:this.label})}async requestUserAttention(e){let n=null;return e&&(n=e===Y.Critical?{type:"Critical"}:{type:"Informational"}),d("plugin:window|request_user_attention",{label:this.label,value:n})}async setResizable(e){return d("plugin:window|set_resizable",{label:this.label,value:e})}async setEnabled(e){return d("plugin:window|set_enabled",{label:this.label,value:e})}async isEnabled(){return d("plugin:window|is_enabled",{label:this.label})}async setMaximizable(e){return d("plugin:window|set_maximizable",{label:this.label,value:e})}async setMinimizable(e){return d("plugin:window|set_minimizable",{label:this.label,value:e})}async setClosable(e){return d("plugin:window|set_closable",{label:this.label,value:e})}async setTitle(e){return d("plugin:window|set_title",{label:this.label,value:e})}async maximize(){return d("plugin:window|maximize",{label:this.label})}async unmaximize(){return d("plugin:window|unmaximize",{label:this.label})}async toggleMaximize(){return d("plugin:window|toggle_maximize",{label:this.label})}async minimize(){return d("plugin:window|minimize",{label:this.label})}async unminimize(){return d("plugin:window|unminimize",{label:this.label})}async show(){return d("plugin:window|show",{label:this.label})}async hide(){return d("plugin:window|hide",{label:this.label})}async close(){return d("plugin:window|close",{label:this.label})}async destroy(){return d("plugin:window|destroy",{label:this.label})}async setDecorations(e){return d("plugin:window|set_decorations",{label:this.label,value:e})}async setShadow(e){return d("plugin:window|set_shadow",{label:this.label,value:e})}async setEffects(e){return d("plugin:window|set_effects",{label:this.label,value:e})}async clearEffects(){return d("plugin:window|set_effects",{label:this.label,value:null})}async setAlwaysOnTop(e){return d("plugin:window|set_always_on_top",{label:this.label,value:e})}async setAlwaysOnBottom(e){return d("plugin:window|set_always_on_bottom",{label:this.label,value:e})}async setContentProtected(e){return d("plugin:window|set_content_protected",{label:this.label,value:e})}async setSize(e){return d("plugin:window|set_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setMinSize(e){return d("plugin:window|set_min_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setMaxSize(e){return d("plugin:window|set_max_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setSizeConstraints(e){function n(e){return e?{Logical:e}:null}return d("plugin:window|set_size_constraints",{label:this.label,value:{minWidth:n(null==e?void 0:e.minWidth),minHeight:n(null==e?void 0:e.minHeight),maxWidth:n(null==e?void 0:e.maxWidth),maxHeight:n(null==e?void 0:e.maxHeight)}})}async setPosition(e){return d("plugin:window|set_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFullscreen(e){return d("plugin:window|set_fullscreen",{label:this.label,value:e})}async setFocus(){return d("plugin:window|set_focus",{label:this.label})}async setIcon(e){return d("plugin:window|set_icon",{label:this.label,value:y(e)})}async setSkipTaskbar(e){return d("plugin:window|set_skip_taskbar",{label:this.label,value:e})}async setCursorGrab(e){return d("plugin:window|set_cursor_grab",{label:this.label,value:e})}async setCursorVisible(e){return d("plugin:window|set_cursor_visible",{label:this.label,value:e})}async setCursorIcon(e){return d("plugin:window|set_cursor_icon",{label:this.label,value:e})}async setBackgroundColor(e){return d("plugin:window|set_background_color",{color:e})}async setCursorPosition(e){return d("plugin:window|set_cursor_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setIgnoreCursorEvents(e){return d("plugin:window|set_ignore_cursor_events",{label:this.label,value:e})}async startDragging(){return d("plugin:window|start_dragging",{label:this.label})}async startResizeDragging(e){return d("plugin:window|start_resize_dragging",{label:this.label,value:e})}async setProgressBar(e){return d("plugin:window|set_progress_bar",{label:this.label,value:e})}async setVisibleOnAllWorkspaces(e){return d("plugin:window|set_visible_on_all_workspaces",{label:this.label,value:e})}async setTitleBarStyle(e){return d("plugin:window|set_title_bar_style",{label:this.label,value:e})}async setTheme(e){return d("plugin:window|set_theme",{label:this.label,value:e})}async onResized(e){return this.listen(E.WINDOW_RESIZED,(n=>{n.payload=new m(n.payload),e(n)}))}async onMoved(e){return this.listen(E.WINDOW_MOVED,(n=>{n.payload=new k(n.payload),e(n)}))}async onCloseRequested(e){return this.listen(E.WINDOW_CLOSE_REQUESTED,(async n=>{const t=new ne(n);await e(t),t.isPreventDefault()||await this.destroy()}))}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}async onFocusChanged(e){const n=await this.listen(E.WINDOW_FOCUS,(n=>{e({...n,payload:!0})})),t=await this.listen(E.WINDOW_BLUR,(n=>{e({...n,payload:!1})}));return()=>{n(),t()}}async onScaleChanged(e){return this.listen(E.WINDOW_SCALE_FACTOR_CHANGED,e)}async onThemeChanged(e){return this.listen(E.WINDOW_THEME_CHANGED,e)}}var ae,le;function oe(e){return null===e?null:{name:e.name,scaleFactor:e.scaleFactor,position:new k(e.position),size:new m(e.size)}}!function(e){e.AppearanceBased="appearanceBased",e.Light="light",e.Dark="dark",e.MediumLight="mediumLight",e.UltraDark="ultraDark",e.Titlebar="titlebar",e.Selection="selection",e.Menu="menu",e.Popover="popover",e.Sidebar="sidebar",e.HeaderView="headerView",e.Sheet="sheet",e.WindowBackground="windowBackground",e.HudWindow="hudWindow",e.FullScreenUI="fullScreenUI",e.Tooltip="tooltip",e.ContentBackground="contentBackground",e.UnderWindowBackground="underWindowBackground",e.UnderPageBackground="underPageBackground",e.Mica="mica",e.Blur="blur",e.Acrylic="acrylic",e.Tabbed="tabbed",e.TabbedDark="tabbedDark",e.TabbedLight="tabbedLight"}(ae||(ae={})),function(e){e.FollowsWindowActiveState="followsWindowActiveState",e.Active="active",e.Inactive="inactive"}(le||(le={}));var ue=Object.freeze({__proto__:null,CloseRequestedEvent:ne,get Effect(){return ae},get EffectState(){return le},LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,get ProgressBarStatus(){return X},get UserAttentionType(){return Y},Window:se,availableMonitors:async function(){return d("plugin:window|available_monitors").then((e=>e.map(oe)))},currentMonitor:async function(){return d("plugin:window|current_monitor").then(oe)},cursorPosition:async function(){return d("plugin:window|cursor_position").then((e=>new k(e)))},getAllWindows:ie,getCurrentWindow:te,monitorFromPoint:async function(e,n){return d("plugin:window|monitor_from_point",{x:e,y:n}).then(oe)},primaryMonitor:async function(){return d("plugin:window|primary_monitor").then(oe)}});function ce(){return new pe(te(),window.__TAURI_INTERNALS__.metadata.currentWebview.label,{skip:!0})}async function de(){return d("plugin:webview|get_all_webviews").then((e=>e.map((e=>new pe(new se(e.windowLabel,{skip:!0}),e.label,{skip:!0})))))}const he=["tauri://created","tauri://error"];class pe{constructor(e,n,t){this.window=e,this.label=n,this.listeners=Object.create(null),(null==t?void 0:t.skip)||d("plugin:webview|create_webview",{windowLabel:e.label,label:n,options:t}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await de()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return ce()}static async getAll(){return de()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Webview",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Webview",label:this.label}})}async emit(e,n){if(!he.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!he.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!he.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async position(){return d("plugin:webview|webview_position",{label:this.label}).then((e=>new k(e)))}async size(){return d("plugin:webview|webview_size",{label:this.label}).then((e=>new m(e)))}async close(){return d("plugin:webview|close",{label:this.label})}async setSize(e){return d("plugin:webview|set_webview_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setPosition(e){return d("plugin:webview|set_webview_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFocus(){return d("plugin:webview|set_webview_focus",{label:this.label})}async hide(){return d("plugin:webview|webview_hide",{label:this.label})}async show(){return d("plugin:webview|webview_show",{label:this.label})}async setZoom(e){return d("plugin:webview|set_webview_zoom",{label:this.label,value:e})}async reparent(e){return d("plugin:webview|reparent",{label:this.label,window:"string"==typeof e?e:e.label})}async clearAllBrowsingData(){return d("plugin:webview|clear_all_browsing_data")}async setBackgroundColor(e){return d("plugin:webview|set_webview_background_color",{color:e})}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}}var we,ye,_e=Object.freeze({__proto__:null,Webview:pe,getAllWebviews:de,getCurrentWebview:ce});function ge(){const e=ce();return new me(e.label,{skip:!0})}async function be(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new me(e,{skip:!0})))))}class me{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:webview|create_webview_window",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;const t=null!==(n=(await be()).find((n=>n.label===e)))&&void 0!==n?n:null;return t?new me(t.label,{skip:!0}):null}static getCurrent(){return ge()}static async getAll(){return be()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"WebviewWindow",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"WebviewWindow",label:this.label}})}async setBackgroundColor(e){return d("plugin:window|set_background_color",{color:e}).then((()=>d("plugin:webview|set_webview_background_color",{color:e})))}}we=me,ye=[se,pe],(Array.isArray(ye)?ye:[ye]).forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((n=>{var t;"object"==typeof we.prototype&&we.prototype&&n in we.prototype||Object.defineProperty(we.prototype,n,null!==(t=Object.getOwnPropertyDescriptor(e.prototype,n))&&void 0!==t?t:Object.create(null))}))}));var ve=Object.freeze({__proto__:null,WebviewWindow:me,getAllWebviewWindows:be,getCurrentWebviewWindow:ge});return e.app=g,e.core=p,e.dpi=T,e.event=P,e.image=_,e.menu=$,e.mocks=Q,e.path=Z,e.tray=ee,e.webview=_e,e.webviewWindow=ve,e.window=ue,e}({});window.__TAURI__=__TAURI_IIFE__; diff --git a/crates/tauri/src/test/mock_runtime.rs b/crates/tauri/src/test/mock_runtime.rs index 92fcb9be64c4..a1488ae38d5b 100644 --- a/crates/tauri/src/test/mock_runtime.rs +++ b/crates/tauri/src/test/mock_runtime.rs @@ -486,6 +486,10 @@ impl WindowBuilder for MockWindowBuilder { fn get_theme(&self) -> Option { None } + + fn background_color(self, _color: tauri_utils::config::Color) -> Self { + self + } } impl WebviewDispatch for MockWebviewDispatcher { @@ -597,6 +601,10 @@ impl WebviewDispatch for MockWebviewDispatcher { fn show(&self) -> Result<()> { Ok(()) } + + fn set_background_color(&self, color: Option) -> Result<()> { + Ok(()) + } } impl WindowDispatch for MockWindowDispatcher { @@ -991,6 +999,10 @@ impl WindowDispatch for MockWindowDispatcher { fn is_enabled(&self) -> Result { Ok(true) } + + fn set_background_color(&self, color: Option) -> Result<()> { + Ok(()) + } } #[derive(Debug, Clone)] diff --git a/crates/tauri/src/webview/mod.rs b/crates/tauri/src/webview/mod.rs index bf3f1f3be4b5..987186939140 100644 --- a/crates/tauri/src/webview/mod.rs +++ b/crates/tauri/src/webview/mod.rs @@ -22,6 +22,7 @@ use tauri_runtime::{ webview::{DetachedWebview, PendingWebview, WebviewAttributes}, WebviewDispatch, }; +pub use tauri_utils::config::Color; use tauri_utils::config::{WebviewUrl, WindowConfig}; pub use url::Url; @@ -830,6 +831,19 @@ fn main() { self.webview_attributes.devtools.replace(enabled); self } + + /// Set the webview background color. + /// + /// ## Platform-specific: + /// + /// - **macOS / iOS**: Not implemented. + /// - **Windows**: On Windows 7, alpha channel is ignored. + /// - **Windows**: On Windows 8 and newer, if alpha channel is not `0`, it will be ignored. + #[must_use] + pub fn background_color(mut self, color: Color) -> Self { + self.webview_attributes.background_color = Some(color); + self + } } /// Webview. @@ -1619,6 +1633,22 @@ tauri::Builder::default() .map_err(Into::into) } + /// Specify the webview background color. + /// + /// ## Platfrom-specific: + /// + /// - **macOS / iOS**: Not implemented. + /// - **Windows**: + /// - On Windows 7, transparency is not supported and the alpha value will be ignored. + /// - On Windows higher than 7: translucent colors are not supported so any alpha value other than `0` will be replaced by `255` + pub fn set_background_color(&self, color: Option) -> crate::Result<()> { + self + .webview + .dispatcher + .set_background_color(color) + .map_err(Into::into) + } + /// Clear all browsing data for this webview. pub fn clear_all_browsing_data(&self) -> crate::Result<()> { self diff --git a/crates/tauri/src/webview/plugin.rs b/crates/tauri/src/webview/plugin.rs index 0856e254e65f..aa92050e361f 100644 --- a/crates/tauri/src/webview/plugin.rs +++ b/crates/tauri/src/webview/plugin.rs @@ -18,8 +18,8 @@ mod desktop_commands { use super::*; use crate::{ - command, sealed::ManagerBase, utils::config::WindowEffectsConfig, AppHandle, Webview, - WebviewWindowBuilder, + command, sealed::ManagerBase, utils::config::WindowEffectsConfig, webview::Color, AppHandle, + Webview, WebviewWindowBuilder, }; fn default_true() -> bool { @@ -199,6 +199,11 @@ mod desktop_commands { setter!(webview_hide, hide); setter!(webview_show, show); setter!(set_webview_zoom, set_zoom, f64); + setter!( + set_webview_background_color, + set_background_color, + Option + ); setter!(clear_all_browsing_data, clear_all_browsing_data); #[command(root = "crate")] @@ -282,6 +287,7 @@ pub fn init() -> TauriPlugin { desktop_commands::set_webview_size, desktop_commands::set_webview_position, desktop_commands::set_webview_focus, + desktop_commands::set_webview_background_color, desktop_commands::set_webview_zoom, desktop_commands::webview_hide, desktop_commands::webview_show, diff --git a/crates/tauri/src/webview/webview_window.rs b/crates/tauri/src/webview/webview_window.rs index 32799a665d8b..a81599ed18dd 100644 --- a/crates/tauri/src/webview/webview_window.rs +++ b/crates/tauri/src/webview/webview_window.rs @@ -29,7 +29,7 @@ use crate::{ }; use serde::Serialize; use tauri_utils::{ - config::{WebviewUrl, WindowConfig}, + config::{Color, WebviewUrl, WindowConfig}, Theme, }; use url::Url; @@ -935,6 +935,23 @@ impl<'a, R: Runtime, M: Manager> WebviewWindowBuilder<'a, R, M> { self.webview_builder = self.webview_builder.devtools(enabled); self } + + /// Set the window and webview background color. + /// + /// ## Platform-specific: + /// + /// - **Android / iOS:** Unsupported for the window layer. + /// - **macOS / iOS**: Not implemented for the webview layer. + /// - **Windows**: + /// - alpha channel is ignored for the window layer. + /// - On Windows 7, alpha channel is ignored for the webview layer. + /// - On Windows 8 and newer, if alpha channel is not `0`, it will be ignored. + #[must_use] + pub fn background_color(mut self, color: Color) -> Self { + self.window_builder = self.window_builder.background_color(color); + self.webview_builder = self.webview_builder.background_color(color); + self + } } /// A type that wraps a [`Window`] together with a [`Webview`]. @@ -1617,6 +1634,21 @@ impl WebviewWindow { self.window.set_icon(icon) } + /// Sets the window background color. + /// + /// ## Platform-specific: + /// + /// - **iOS / Android:** Unsupported. + /// - **macOS**: Not implemented for the webview layer.. + /// - **Windows**: + /// - alpha channel is ignored for the window layer. + /// - On Windows 7, transparency is not supported and the alpha value will be ignored for the webview layer.. + /// - On Windows 8 and newer: translucent colors are not supported so any alpha value other than `0` will be replaced by `255` for the webview layer. + pub fn set_background_color(&self, color: Option) -> crate::Result<()> { + self.window.set_background_color(color)?; + self.webview.set_background_color(color) + } + /// Whether to hide the window icon from the taskbar or not. /// /// ## Platform-specific diff --git a/crates/tauri/src/window/mod.rs b/crates/tauri/src/window/mod.rs index 7f0ffe3cf728..93310fcc9d78 100644 --- a/crates/tauri/src/window/mod.rs +++ b/crates/tauri/src/window/mod.rs @@ -846,6 +846,18 @@ impl<'a, R: Runtime, M: Manager> WindowBuilder<'a, R, M> { } } +impl<'a, R: Runtime, M: Manager> WindowBuilder<'a, R, M> { + /// Set the window and webview background color. + /// + /// ## Platform-specific: + /// + /// - **Windows**: alpha channel is ignored. + #[must_use] + pub fn background_color(mut self, color: Color) -> Self { + self.window_builder = self.window_builder.background_color(color); + self + } +} /// A wrapper struct to hold the window menu state /// and whether it is global per-app or specific to this window. #[cfg(desktop)] @@ -1817,6 +1829,20 @@ tauri::Builder::default() .map_err(Into::into) } + /// Sets the window background color. + /// + /// ## Platform-specific: + /// + /// - **Windows:** alpha channel is ignored. + /// - **iOS / Android:** Unsupported. + pub fn set_background_color(&self, color: Option) -> crate::Result<()> { + self + .window + .dispatcher + .set_background_color(color) + .map_err(Into::into) + } + /// Prevents the window contents from being captured by other apps. pub fn set_content_protected(&self, protected: bool) -> crate::Result<()> { self diff --git a/crates/tauri/src/window/plugin.rs b/crates/tauri/src/window/plugin.rs index a25229e6dd69..edb44b20fc97 100644 --- a/crates/tauri/src/window/plugin.rs +++ b/crates/tauri/src/window/plugin.rs @@ -19,6 +19,7 @@ mod desktop_commands { command, sealed::ManagerBase, utils::config::{WindowConfig, WindowEffectsConfig}, + window::Color, window::{ProgressBarState, WindowBuilder}, AppHandle, CursorIcon, Manager, Monitor, PhysicalPosition, PhysicalSize, Position, Size, Theme, UserAttentionType, Webview, Window, @@ -130,6 +131,7 @@ mod desktop_commands { setter!(set_skip_taskbar, bool); setter!(set_cursor_grab, bool); setter!(set_cursor_visible, bool); + setter!(set_background_color, Option); setter!(set_cursor_icon, CursorIcon); setter!(set_cursor_position, Position); setter!(set_ignore_cursor_events, bool); @@ -291,6 +293,7 @@ pub fn init() -> TauriPlugin { desktop_commands::set_progress_bar, desktop_commands::set_icon, desktop_commands::set_visible_on_all_workspaces, + desktop_commands::set_background_color, desktop_commands::set_title_bar_style, desktop_commands::set_theme, desktop_commands::toggle_maximize, diff --git a/examples/api/src-tauri/src/lib.rs b/examples/api/src-tauri/src/lib.rs index 7f7007eef558..512f43c0aac0 100644 --- a/examples/api/src-tauri/src/lib.rs +++ b/examples/api/src-tauri/src/lib.rs @@ -66,8 +66,7 @@ pub fn run_app) + Send + 'static>( .build()?, )); - let mut window_builder = - WebviewWindowBuilder::new(app, "main", WebviewUrl::default()).use_https_scheme(true); + let mut window_builder = WebviewWindowBuilder::new(app, "main", WebviewUrl::default()); #[cfg(all(desktop, not(test)))] { diff --git a/packages/api/src/webview.ts b/packages/api/src/webview.ts index 42a2643d0d05..393fb0c4831e 100644 --- a/packages/api/src/webview.ts +++ b/packages/api/src/webview.ts @@ -30,7 +30,7 @@ import { once } from './event' import { invoke } from './core' -import { Window, getCurrentWindow } from './window' +import { Color, Window, getCurrentWindow } from './window' import { WebviewWindow } from './webviewWindow' /** The drag and drop event types. */ @@ -537,6 +537,24 @@ class Webview { return invoke('plugin:webview|clear_all_browsing_data') } + /** + * Specify the webview background color. + * + * #### Platfrom-specific: + * + * - **macOS / iOS**: Not implemented. + * - **Windows**: + * - On Windows 7, transparency is not supported and the alpha value will be ignored. + * - On Windows higher than 7: translucent colors are not supported so any alpha value other than `0` will be replaced by `255` + * + * @returns A promise indicating the success or failure of the operation. + * + * @since 2.1.0 + */ + async setBackgroundColor(color: Color | null): Promise { + return invoke('plugin:webview|set_webview_background_color', { color }) + } + // Listeners /** @@ -733,8 +751,21 @@ interface WebviewOptions { * @since 2.1.0 */ devtools?: boolean + /** + * Set the window and webview background color. + * + * #### Platform-specific: + * + * - **macOS / iOS**: Not implemented. + * - **Windows**: + * - On Windows 7, alpha channel is ignored. + * - On Windows 8 and newer, if alpha channel is not `0`, it will be ignored. + * + * @since 2.1.0 + */ + backgroundColor?: Color } export { Webview, getCurrentWebview, getAllWebviews } -export type { DragDropEvent, WebviewOptions } +export type { DragDropEvent, WebviewOptions, Color } diff --git a/packages/api/src/webviewWindow.ts b/packages/api/src/webviewWindow.ts index a103dd19ee6f..d2bfab8c28fc 100644 --- a/packages/api/src/webviewWindow.ts +++ b/packages/api/src/webviewWindow.ts @@ -13,7 +13,7 @@ import { Window } from './window' import { listen, once } from './event' import type { EventName, EventCallback, UnlistenFn } from './event' import { invoke } from './core' -import type { DragDropEvent } from './webview' +import type { Color, DragDropEvent } from './webview' /** * Get an instance of `Webview` for the current webview window. @@ -202,6 +202,28 @@ class WebviewWindow { target: { kind: 'WebviewWindow', label: this.label } }) } + + /** + * Set the window and webview background color. + * + * #### Platform-specific: + * + * - **Android / iOS:** Unsupported for the window layer. + * - **macOS / iOS**: Not implemented for the webview layer. + * - **Windows**: + * - alpha channel is ignored for the window layer. + * - On Windows 7, alpha channel is ignored for the webview layer. + * - On Windows 8 and newer, if alpha channel is not `0`, it will be ignored. + * + * @returns A promise indicating the success or failure of the operation. + * + * @since 2.1.0 + */ + async setBackgroundColor(color: Color): Promise { + return invoke('plugin:window|set_background_color', { color }).then(() => { + return invoke('plugin:webview|set_webview_background_color', { color }) + }) + } } // Order matters, we use window APIs by default @@ -235,4 +257,4 @@ function applyMixins( } export { WebviewWindow, getCurrentWebviewWindow, getAllWebviewWindows } -export type { DragDropEvent } +export type { DragDropEvent, Color } diff --git a/packages/api/src/window.ts b/packages/api/src/window.ts index 037f06e6523d..1d2ddc4b7182 100644 --- a/packages/api/src/window.ts +++ b/packages/api/src/window.ts @@ -1517,6 +1517,22 @@ class Window { }) } + /** + * Sets the window background color. + * + * #### Platform-specific: + * + * - **Windows:** alpha channel is ignored. + * - **iOS / Android:** Unsupported. + * + * @returns A promise indicating the success or failure of the operation. + * + * @since 2.1.0 + */ + async setBackgroundColor(color: Color): Promise { + return invoke('plugin:window|set_background_color', { color }) + } + /** * Changes the position of the cursor in window coordinates. * @example @@ -1920,11 +1936,17 @@ class Window { } /** - * an array RGBA colors. Each value has minimum of 0 and maximum of 255. + * An RGBA color. Each value has minimum of 0 and maximum of 255. + * + * It can be either a string `#ffffff`, an array of 3 or 4 elements or an object. * * @since 2.0.0 */ -type Color = [number, number, number, number] +type Color = + | [number, number, number] + | [number, number, number, number] + | { red: number; green: number; blue: number; alpha: number } + | string /** * Platform-specific window effects @@ -2232,6 +2254,17 @@ interface WindowOptions { * - **Linux**: Unsupported */ windowEffects?: Effects + /** + * Set the window background color. + * + * #### Platform-specific: + * + * - **Android / iOS:** Unsupported. + * - **Windows**: alpha channel is ignored. + * + * @since 2.1.0 + */ + backgroundColor?: Color } function mapMonitor(m: Monitor | null): Monitor | null { From f550a3f47176f7aa97917cff99a9b214e0e2833e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:25:49 -0300 Subject: [PATCH 31/51] chore(deps) Update Tauri Bundler (dev) (#11601) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7902bfd4df58..8640454b342f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -570,9 +570,9 @@ dependencies = [ [[package]] name = "avif-serialize" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +checksum = "e335041290c43101ca215eed6f43ec437eb5a42125573f600fc3fa42b9bddd62" dependencies = [ "arrayvec", ] @@ -4103,9 +4103,9 @@ dependencies = [ [[package]] name = "image" -version = "0.25.4" +version = "0.25.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc144d44a31d753b02ce64093d532f55ff8dc4ebf2ffb8a63c0dda691385acae" +checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" dependencies = [ "bytemuck", "byteorder-lite", @@ -4857,7 +4857,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -7128,9 +7128,9 @@ dependencies = [ [[package]] name = "ravif" -version = "0.11.5" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc13288f5ab39e6d7c9d501759712e6969fcc9734220846fc9ed26cae2cc4234" +checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6" dependencies = [ "avif-serialize", "imgref", @@ -8967,9 +8967,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ff6c40d3aedb5e06b57c6f669ad17ab063dd1e63d977c6a88e7f4dfa4f04020" +checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" dependencies = [ "filetime", "libc", @@ -10768,7 +10768,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]] From 8e8312bb8201ccc609e4bbc1a990bdc314daa00f Mon Sep 17 00:00:00 2001 From: Tony <68118705+Legend-Master@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:09:05 +0800 Subject: [PATCH 32/51] ci: unpin ravif (#11608) --- .github/workflows/test-core.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test-core.yml b/.github/workflows/test-core.yml index 0e0acef62dc4..6aef978f34bc 100644 --- a/.github/workflows/test-core.yml +++ b/.github/workflows/test-core.yml @@ -90,7 +90,6 @@ jobs: - name: downgrade crates with MSRV conflict run: | - cargo update -p ravif --precise 0.11.5 cargo update -p aws-config --precise 1.5.5 cargo update -p aws-sdk-ssooidc --precise 1.40.0 cargo update -p aws-sdk-s3 --precise 1.46.0 From 6bf917941ff0fcc49e86b3ba427340b75f3ce49c Mon Sep 17 00:00:00 2001 From: Shaun Hamilton Date: Thu, 7 Nov 2024 19:58:25 +0200 Subject: [PATCH 33/51] feat(cli): add `tauri remove` command (#11322) --- .changes/cli-remove-command.md | 6 ++ crates/tauri-cli/src/acl/permission/mod.rs | 2 +- crates/tauri-cli/src/acl/permission/rm.rs | 29 +++++++-- crates/tauri-cli/src/helpers/cargo.rs | 30 ++++++++++ crates/tauri-cli/src/lib.rs | 3 + crates/tauri-cli/src/remove.rs | 69 ++++++++++++++++++++++ 6 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 .changes/cli-remove-command.md create mode 100644 crates/tauri-cli/src/remove.rs diff --git a/.changes/cli-remove-command.md b/.changes/cli-remove-command.md new file mode 100644 index 000000000000..523c08082bc0 --- /dev/null +++ b/.changes/cli-remove-command.md @@ -0,0 +1,6 @@ +--- +"tauri-cli": minor:feat +"@tauri-apps/cli": minor:feat +--- + +Add `tauri remove` to remove plugins from projects. diff --git a/crates/tauri-cli/src/acl/permission/mod.rs b/crates/tauri-cli/src/acl/permission/mod.rs index e65295919ce4..deb82f00bec1 100644 --- a/crates/tauri-cli/src/acl/permission/mod.rs +++ b/crates/tauri-cli/src/acl/permission/mod.rs @@ -9,7 +9,7 @@ use crate::Result; pub mod add; mod ls; mod new; -mod rm; +pub mod rm; #[derive(Debug, Parser)] #[clap(about = "Manage or create permissions for your app or plugin")] diff --git a/crates/tauri-cli/src/acl/permission/rm.rs b/crates/tauri-cli/src/acl/permission/rm.rs index 4c2e11764a92..f565b6e56b6a 100644 --- a/crates/tauri-cli/src/acl/permission/rm.rs +++ b/crates/tauri-cli/src/acl/permission/rm.rs @@ -46,13 +46,15 @@ fn rm_permission_files(identifier: &str, dir: &Path) -> Result<()> { permission_file.default = None; } else { let set_len = permission_file.set.len(); - permission_file.set.retain(|s| s.identifier != identifier); + permission_file + .set + .retain(|s| !identifier_match(identifier, &s.identifier)); updated = permission_file.set.len() != set_len; let permission_len = permission_file.permission.len(); permission_file .permission - .retain(|s| s.identifier != identifier); + .retain(|s| !identifier_match(identifier, &s.identifier)); updated = updated || permission_file.permission.len() != permission_len; } @@ -84,7 +86,11 @@ fn rm_permission_from_capabilities(identifier: &str, dir: &Path) -> Result<()> { if let Ok(mut value) = content.parse::() { if let Some(permissions) = value.get_mut("permissions").and_then(|p| p.as_array_mut()) { let prev_len = permissions.len(); - permissions.retain(|p| p.as_str().map(|p| p != identifier).unwrap_or(false)); + permissions.retain(|p| { + p.as_str() + .map(|p| !identifier_match(identifier, p)) + .unwrap_or(false) + }); if prev_len != permissions.len() { std::fs::write(&path, value.to_string())?; log::info!(action = "Removed"; "permission from capability at {}", dunce::simplified(&path).display()); @@ -97,7 +103,11 @@ fn rm_permission_from_capabilities(identifier: &str, dir: &Path) -> Result<()> { if let Ok(mut value) = serde_json::from_slice::(&content) { if let Some(permissions) = value.get_mut("permissions").and_then(|p| p.as_array_mut()) { let prev_len = permissions.len(); - permissions.retain(|p| p.as_str().map(|p| p != identifier).unwrap_or(false)); + permissions.retain(|p| { + p.as_str() + .map(|p| !identifier_match(identifier, p)) + .unwrap_or(false) + }); if prev_len != permissions.len() { std::fs::write(&path, serde_json::to_vec_pretty(&value)?)?; log::info!(action = "Removed"; "permission from capability at {}", dunce::simplified(&path).display()); @@ -113,11 +123,20 @@ fn rm_permission_from_capabilities(identifier: &str, dir: &Path) -> Result<()> { Ok(()) } +fn identifier_match(identifier: &str, permission: &str) -> bool { + match identifier.split_once(':') { + Some((plugin_name, "*")) => permission.contains(plugin_name), + _ => permission == identifier, + } +} + #[derive(Debug, Parser)] #[clap(about = "Remove a permission file, and its reference from any capability")] pub struct Options { /// Permission to remove. - identifier: String, + /// + /// To remove all permissions for a given plugin, provide `:*` + pub identifier: String, } pub fn command(options: Options) -> Result<()> { diff --git a/crates/tauri-cli/src/helpers/cargo.rs b/crates/tauri-cli/src/helpers/cargo.rs index 24628bb9df9a..ffa4493b7959 100644 --- a/crates/tauri-cli/src/helpers/cargo.rs +++ b/crates/tauri-cli/src/helpers/cargo.rs @@ -61,3 +61,33 @@ pub fn install_one(options: CargoInstallOptions) -> crate::Result<()> { Ok(()) } + +#[derive(Debug, Default, Clone, Copy)] +pub struct CargoUninstallOptions<'a> { + pub name: &'a str, + pub cwd: Option<&'a std::path::Path>, + pub target: Option<&'a str>, +} + +pub fn uninstall_one(options: CargoUninstallOptions) -> crate::Result<()> { + let mut cargo = Command::new("cargo"); + cargo.arg("remove"); + + cargo.arg(options.name); + + if let Some(target) = options.target { + cargo.args(["--target", target]); + } + + if let Some(cwd) = options.cwd { + cargo.current_dir(cwd); + } + + log::info!("Uninstalling Cargo dependency \"{}\"...", options.name); + let status = cargo.status().context("failed to run `cargo remove`")?; + if !status.success() { + anyhow::bail!("Failed to remove Cargo dependency"); + } + + Ok(()) +} diff --git a/crates/tauri-cli/src/lib.rs b/crates/tauri-cli/src/lib.rs index 2ab75cf95127..4a9e11d3b44f 100644 --- a/crates/tauri-cli/src/lib.rs +++ b/crates/tauri-cli/src/lib.rs @@ -30,6 +30,7 @@ mod interface; mod migrate; mod mobile; mod plugin; +mod remove; mod signer; use clap::{ArgAction, CommandFactory, FromArgMatches, Parser, Subcommand, ValueEnum}; @@ -146,6 +147,7 @@ enum Commands { Migrate, Info(info::Options), Add(add::Options), + Remove(remove::Options), Plugin(plugin::Cli), Icon(icon::Options), Signer(signer::Cli), @@ -265,6 +267,7 @@ where Commands::Bundle(options) => bundle::command(options, cli.verbose)?, Commands::Dev(options) => dev::command(options)?, Commands::Add(options) => add::command(options)?, + Commands::Remove(options) => remove::command(options)?, Commands::Icon(options) => icon::command(options)?, Commands::Info(options) => info::command(options)?, Commands::Init(options) => init::command(options)?, diff --git a/crates/tauri-cli/src/remove.rs b/crates/tauri-cli/src/remove.rs new file mode 100644 index 000000000000..319f60e82860 --- /dev/null +++ b/crates/tauri-cli/src/remove.rs @@ -0,0 +1,69 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use clap::Parser; + +use crate::{ + acl, + helpers::{ + app_paths::{resolve_frontend_dir, tauri_dir}, + cargo, + npm::PackageManager, + }, + Result, +}; + +#[derive(Debug, Parser)] +#[clap(about = "Remove a tauri plugin from the project")] +pub struct Options { + /// The plugin to remove. + pub plugin: String, +} + +pub fn command(options: Options) -> Result<()> { + crate::helpers::app_paths::resolve(); + run(options) +} + +pub fn run(options: Options) -> Result<()> { + let plugin = options.plugin; + + let crate_name = format!("tauri-plugin-{plugin}"); + + let mut plugins = crate::helpers::plugins::known_plugins(); + let metadata = plugins.remove(plugin.as_str()).unwrap_or_default(); + + let frontend_dir = resolve_frontend_dir(); + let tauri_dir = tauri_dir(); + + let target_str = metadata + .desktop_only + .then_some(r#"cfg(not(any(target_os = "android", target_os = "ios")))"#) + .or_else(|| { + metadata + .mobile_only + .then_some(r#"cfg(any(target_os = "android", target_os = "ios"))"#) + }); + + cargo::uninstall_one(cargo::CargoUninstallOptions { + name: &crate_name, + cwd: Some(tauri_dir), + target: target_str, + })?; + + if !metadata.rust_only { + if let Some(manager) = frontend_dir.map(PackageManager::from_project) { + let npm_name = format!("@tauri-apps/plugin-{plugin}"); + manager.remove(&[npm_name], tauri_dir)?; + } + + acl::permission::rm::command(acl::permission::rm::Options { + identifier: format!("{plugin}:*"), + })?; + } + + log::info!("Now, you must manually remove the plugin from your Rust code.",); + + Ok(()) +} From c5617868448aefa3c6e14d2ce9b494cfc65ecb00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20S=C3=A4=C3=A4vuori?= Date: Fri, 8 Nov 2024 03:50:10 +0200 Subject: [PATCH 34/51] docs: fix typos in drag&drop event.payload (#11620) * fix: typo in drag&drop event.payload 'hover' -> 'over' * fix: another typo 'hover' -> 'over' --- packages/api/src/webview.ts | 2 +- packages/api/src/window.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/api/src/webview.ts b/packages/api/src/webview.ts index 393fb0c4831e..b5a63646deb9 100644 --- a/packages/api/src/webview.ts +++ b/packages/api/src/webview.ts @@ -566,7 +566,7 @@ class Webview { * ```typescript * import { getCurrentWebview } from "@tauri-apps/api/webview"; * const unlisten = await getCurrentWebview().onDragDropEvent((event) => { - * if (event.payload.type === 'hover') { + * if (event.payload.type === 'over') { * console.log('User hovering', event.payload.paths); * } else if (event.payload.type === 'drop') { * console.log('User dropped', event.payload.paths); diff --git a/packages/api/src/window.ts b/packages/api/src/window.ts index 1d2ddc4b7182..ae648f1b076d 100644 --- a/packages/api/src/window.ts +++ b/packages/api/src/window.ts @@ -1770,7 +1770,7 @@ class Window { * ```typescript * import { getCurrentWindow } from "@tauri-apps/api/webview"; * const unlisten = await getCurrentWindow().onDragDropEvent((event) => { - * if (event.payload.type === 'hover') { + * if (event.payload.type === 'over') { * console.log('User hovering', event.payload.paths); * } else if (event.payload.type === 'drop') { * console.log('User dropped', event.payload.paths); From 229d7f8e220cc8d5ca06eff1ed85cb7d047c1d6c Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Fri, 8 Nov 2024 13:04:14 +0200 Subject: [PATCH 35/51] fix(core): fix child webviews on macOS and Windows treated as full webview window (#11616) * fix(core): fix child webviews on macOS and Windows treated as full webview window closes #11452 * Update .changes/child-windows-macos.md --- .changes/child-windows-macos.md | 7 +++++++ crates/tauri-runtime-wry/src/lib.rs | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 .changes/child-windows-macos.md diff --git a/.changes/child-windows-macos.md b/.changes/child-windows-macos.md new file mode 100644 index 000000000000..4c9f52651702 --- /dev/null +++ b/.changes/child-windows-macos.md @@ -0,0 +1,7 @@ +--- +"tauri": "patch:bug" +"tauri-runtime-wry": "patch:bug" +--- + +Fix regression in creating child webviews on macOS and Windows, covering the whole window. + diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index bde9d3ccd7fd..12629db18420 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -4364,7 +4364,7 @@ fn create_webview( target_os = "ios", target_os = "android" ))] - WebviewKind::WindowChild => webview_builder.build(&window), + WebviewKind::WindowChild => webview_builder.build_as_child(&window), WebviewKind::WindowContent => { #[cfg(any( target_os = "windows", From b28435860c4b9a995d00e5d1bc6b875724b04b92 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:21:38 -0300 Subject: [PATCH 36/51] chore(deps) Update Rust crate thiserror to v2 (dev) (#11604) * chore(deps) Update Rust crate thiserror to v2 * thiserror v2 on all crates --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Lucas Nogueira --- Cargo.lock | 134 ++++++++++-------- crates/tauri-bundler/Cargo.toml | 2 +- .../templates/plugin/Cargo.crate-manifest | 2 +- crates/tauri-codegen/Cargo.toml | 2 +- crates/tauri-runtime/Cargo.toml | 2 +- crates/tauri-utils/Cargo.toml | 2 +- crates/tauri-utils/src/acl/identifier.rs | 2 +- crates/tauri/Cargo.toml | 2 +- .../src-tauri/tauri-plugin-sample/Cargo.toml | 2 +- 9 files changed, 85 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8640454b342f..05388293b076 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -254,7 +254,7 @@ dependencies = [ "rsa", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", "x509-certificate", ] @@ -338,7 +338,7 @@ dependencies = [ "spki 0.7.3", "subtle", "tempfile", - "thiserror", + "thiserror 1.0.68", "tokio", "tungstenite 0.21.0", "uuid", @@ -366,7 +366,7 @@ dependencies = [ "scroll", "serde", "serde-xml-rs", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -392,7 +392,7 @@ dependencies = [ "sha1", "sha2", "signature 2.2.0", - "thiserror", + "thiserror 1.0.68", "url", "x509-certificate", "xml-rs", @@ -467,7 +467,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -1160,7 +1160,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57792b99d555ebf109c83169228076f7d997e2b37ba1a653850ccd703ac7bab0" dependencies = [ "sysctl", - "thiserror", + "thiserror 1.0.68", "uname", "winapi", ] @@ -1438,7 +1438,7 @@ dependencies = [ "glib", "libc", "once_cell", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -1499,7 +1499,7 @@ dependencies = [ "serde", "serde_json", "textwrap", - "thiserror", + "thiserror 1.0.68", "toml 0.8.19", "ureq", "which 6.0.3", @@ -1527,7 +1527,7 @@ dependencies = [ "semver", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -1986,7 +1986,7 @@ dependencies = [ "chrono", "is_executable", "simple-file-manifest", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -2384,7 +2384,7 @@ dependencies = [ "console", "shell-words", "tempfile", - "thiserror", + "thiserror 1.0.68", "zeroize", ] @@ -3059,7 +3059,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db9c27b72f19a99a895f8ca89e2d26e4ef31013376e56fdafef697627306c3e4" dependencies = [ "nom", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -3367,7 +3367,7 @@ dependencies = [ "once_cell", "pin-project-lite", "smallvec", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -3403,7 +3403,7 @@ dependencies = [ "memchr", "once_cell", "smallvec", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -3605,7 +3605,7 @@ dependencies = [ "pest_derive", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4425,7 +4425,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.68", "walkdir", "windows-sys 0.45.0", ] @@ -4468,7 +4468,7 @@ checksum = "ec9ad60d674508f3ca8f380a928cfe7b096bc729c4e2dbfe3852bc45da3ab30b" dependencies = [ "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4480,7 +4480,7 @@ dependencies = [ "jsonptr 0.4.7", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4492,7 +4492,7 @@ dependencies = [ "jsonptr 0.6.3", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4551,7 +4551,7 @@ dependencies = [ "jsonrpsee-core", "pin-project", "soketto", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-util", "tracing", @@ -4578,7 +4578,7 @@ dependencies = [ "rustc-hash", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-stream", "tracing", @@ -4603,7 +4603,7 @@ dependencies = [ "serde", "serde_json", "soketto", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-stream", "tokio-util", @@ -4620,7 +4620,7 @@ dependencies = [ "http 1.1.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4928,7 +4928,7 @@ checksum = "3669cf5561f8d27e8fc84cc15e58350e70f557d4d65f70e3154e54cd2f8e1782" dependencies = [ "libc", "neli", - "thiserror", + "thiserror 1.0.68", "windows-sys 0.59.0", ] @@ -5100,7 +5100,7 @@ dependencies = [ "miette-derive", "owo-colors", "textwrap", - "thiserror", + "thiserror 1.0.68", "unicode-width", ] @@ -5218,7 +5218,7 @@ dependencies = [ "once_cell", "png", "serde", - "thiserror", + "thiserror 1.0.68", "windows-sys 0.59.0", ] @@ -5308,7 +5308,7 @@ dependencies = [ "ndk-sys", "num_enum", "raw-window-handle", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -6308,7 +6308,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.68", "ucd-trie", ] @@ -6404,7 +6404,7 @@ dependencies = [ "sha3", "signature 2.2.0", "smallvec", - "thiserror", + "thiserror 1.0.68", "twofish", "x25519-dalek", "zeroize", @@ -6913,7 +6913,7 @@ dependencies = [ "rustc-hash", "rustls 0.23.13", "socket2", - "thiserror", + "thiserror 1.0.68", "tokio", "tracing", ] @@ -6930,7 +6930,7 @@ dependencies = [ "rustc-hash", "rustls 0.23.13", "slab", - "thiserror", + "thiserror 1.0.68", "tinyvec", "tracing", ] @@ -7121,7 +7121,7 @@ dependencies = [ "rand_chacha 0.3.1", "simd_helpers", "system-deps", - "thiserror", + "thiserror 1.0.68", "v_frame", "wasm-bindgen", ] @@ -7193,7 +7193,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.15", "libredox", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -7496,7 +7496,7 @@ dependencies = [ "pgp", "sha1", "sha2", - "thiserror", + "thiserror 1.0.68", "xz2", "zstd", ] @@ -8035,7 +8035,7 @@ checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" dependencies = [ "log", "serde", - "thiserror", + "thiserror 1.0.68", "xml-rs", ] @@ -8387,7 +8387,7 @@ checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" dependencies = [ "num-bigint", "num-traits", - "thiserror", + "thiserror 1.0.68", "time", ] @@ -8570,7 +8570,7 @@ checksum = "4ccbb212565d2dc177bc15ecb7b039d66c4490da892436a4eee5b394d620c9bc" dependencies = [ "paste", "specta-macros", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -8871,7 +8871,7 @@ dependencies = [ "bitflags 1.3.2", "byteorder", "libc", - "thiserror", + "thiserror 1.0.68", "walkdir", ] @@ -9029,7 +9029,7 @@ dependencies = [ "tauri-runtime", "tauri-runtime-wry", "tauri-utils 2.0.2", - "thiserror", + "thiserror 2.0.0", "tokio", "tracing", "tray-icon", @@ -9097,7 +9097,7 @@ dependencies = [ "tauri-macos-sign", "tauri-utils 2.0.2", "tempfile", - "thiserror", + "thiserror 2.0.0", "time", "ureq", "url", @@ -9217,7 +9217,7 @@ dependencies = [ "sha2", "syn 2.0.87", "tauri-utils 2.0.2", - "thiserror", + "thiserror 2.0.0", "time", "url", "uuid", @@ -9344,7 +9344,7 @@ dependencies = [ "swift-rs", "tauri", "tauri-plugin 2.0.0-rc.13", - "thiserror", + "thiserror 1.0.68", "time", ] @@ -9356,7 +9356,7 @@ dependencies = [ "serde", "tauri", "tauri-plugin 2.0.2", - "thiserror", + "thiserror 2.0.0", ] [[package]] @@ -9371,7 +9371,7 @@ dependencies = [ "serde", "serde_json", "tauri-utils 2.0.2", - "thiserror", + "thiserror 2.0.0", "url", "windows", ] @@ -9451,7 +9451,7 @@ dependencies = [ "serde_json", "serde_with", "serialize-to-javascript", - "thiserror", + "thiserror 1.0.68", "toml 0.7.8", "url", "windows-version", @@ -9484,7 +9484,7 @@ dependencies = [ "serde_json", "serde_with", "swift-rs", - "thiserror", + "thiserror 1.0.68", "toml 0.8.19", "url", "urlpattern", @@ -9523,7 +9523,7 @@ dependencies = [ "serial_test", "serialize-to-javascript", "swift-rs", - "thiserror", + "thiserror 2.0.0", "toml 0.8.19", "url", "urlpattern", @@ -9619,7 +9619,16 @@ version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.68", +] + +[[package]] +name = "thiserror" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15291287e9bff1bc6f9ff3409ed9af665bec7a5fc8ac079ea96be07bca0e2668" +dependencies = [ + "thiserror-impl 2.0.0", ] [[package]] @@ -9633,6 +9642,17 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "thiserror-impl" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22efd00f33f93fa62848a7cab956c3d38c8d43095efda1decfc2b3a5dc0b8972" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "tiff" version = "0.9.1" @@ -10002,7 +10022,7 @@ dependencies = [ "once_cell", "png", "serde", - "thiserror", + "thiserror 1.0.68", "windows-sys 0.59.0", ] @@ -10038,7 +10058,7 @@ dependencies = [ "rustls-native-certs 0.7.3", "rustls-pki-types", "sha1", - "thiserror", + "thiserror 1.0.68", "url", "utf-8", ] @@ -10057,7 +10077,7 @@ dependencies = [ "log", "rand 0.8.5", "sha1", - "thiserror", + "thiserror 1.0.68", "utf-8", ] @@ -10705,7 +10725,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3a3e2eeb58f82361c93f9777014668eb3d07e7d174ee4c819575a9208011886" dependencies = [ - "thiserror", + "thiserror 1.0.68", "windows", "windows-core 0.58.0", ] @@ -11204,7 +11224,7 @@ dependencies = [ "serde", "serde-wasm-bindgen 0.5.0", "serde_json", - "thiserror", + "thiserror 1.0.68", "wasm-bindgen", "wasm-bindgen-futures", ] @@ -11280,7 +11300,7 @@ dependencies = [ "sha2", "soup3", "tao-macros", - "thiserror", + "thiserror 1.0.68", "tracing", "webkit2gtk", "webkit2gtk-sys", @@ -11358,7 +11378,7 @@ dependencies = [ "ring", "signature 2.2.0", "spki 0.7.3", - "thiserror", + "thiserror 1.0.68", "zeroize", ] @@ -11545,7 +11565,7 @@ dependencies = [ "flate2", "indexmap 2.6.0", "memchr", - "thiserror", + "thiserror 1.0.68", "zopfli", ] @@ -11557,7 +11577,7 @@ checksum = "ce824a6bfffe8942820fa36d24973b7c83a40896749a42e33de0abdd11750ee5" dependencies = [ "byteorder", "bytesize", - "thiserror", + "thiserror 1.0.68", ] [[package]] diff --git a/crates/tauri-bundler/Cargo.toml b/crates/tauri-bundler/Cargo.toml index a485f0a9ccf7..447642a1257d 100644 --- a/crates/tauri-bundler/Cargo.toml +++ b/crates/tauri-bundler/Cargo.toml @@ -21,7 +21,7 @@ tauri-utils = { version = "2.0.2", path = "../tauri-utils", features = [ image = "0.25.0" flate2 = "1.0" anyhow = "1.0" -thiserror = "1.0" +thiserror = "2" serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } strsim = "0.11.0" diff --git a/crates/tauri-cli/templates/plugin/Cargo.crate-manifest b/crates/tauri-cli/templates/plugin/Cargo.crate-manifest index 64170c165365..e8fc7774087e 100644 --- a/crates/tauri-cli/templates/plugin/Cargo.crate-manifest +++ b/crates/tauri-cli/templates/plugin/Cargo.crate-manifest @@ -11,7 +11,7 @@ links = "tauri-plugin-{{ plugin_name }}" [dependencies] tauri = {{ tauri_dep }} serde = "1.0" -thiserror = "1.0" +thiserror = "2" [build-dependencies] tauri-plugin = {{{ tauri_plugin_dep }}} diff --git a/crates/tauri-codegen/Cargo.toml b/crates/tauri-codegen/Cargo.toml index 19884121d878..637e18623cc9 100644 --- a/crates/tauri-codegen/Cargo.toml +++ b/crates/tauri-codegen/Cargo.toml @@ -23,7 +23,7 @@ serde_json = "1" tauri-utils = { version = "2.0.2", path = "../tauri-utils", features = [ "build", ] } -thiserror = "1" +thiserror = "2" walkdir = "2" brotli = { version = "7", optional = true, default-features = false, features = [ "std", diff --git a/crates/tauri-runtime/Cargo.toml b/crates/tauri-runtime/Cargo.toml index f5b6fd0814ef..ece1aa52e6ad 100644 --- a/crates/tauri-runtime/Cargo.toml +++ b/crates/tauri-runtime/Cargo.toml @@ -28,7 +28,7 @@ targets = [ [dependencies] serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -thiserror = "1.0" +thiserror = "2" tauri-utils = { version = "2.0.2", path = "../tauri-utils" } http = "1.1" raw-window-handle = "0.6" diff --git a/crates/tauri-utils/Cargo.toml b/crates/tauri-utils/Cargo.toml index 074b2ed4d9cb..b920ec9e3f70 100644 --- a/crates/tauri-utils/Cargo.toml +++ b/crates/tauri-utils/Cargo.toml @@ -15,7 +15,7 @@ rust-version.workspace = true [dependencies] serde = { version = "1", features = ["derive"] } serde_json = "1" -thiserror = "1" +thiserror = "2" phf = { version = "0.11", features = ["macros"] } brotli = { version = "7", optional = true, default-features = false, features = [ "std", diff --git a/crates/tauri-utils/src/acl/identifier.rs b/crates/tauri-utils/src/acl/identifier.rs index 64df0ed274cc..1693e4195b7c 100644 --- a/crates/tauri-utils/src/acl/identifier.rs +++ b/crates/tauri-utils/src/acl/identifier.rs @@ -122,7 +122,7 @@ pub enum ParseIdentifierError { Empty, /// Identifier is too long. - #[error("identifiers cannot be longer than {}, found {0}", MAX_LEN_IDENTIFIER)] + #[error("identifiers cannot be longer than {len}, found {0}", len = MAX_LEN_IDENTIFIER)] Humongous(usize), /// Identifier is not in a valid format. diff --git a/crates/tauri/Cargo.toml b/crates/tauri/Cargo.toml index 254660afdb9c..36610576fa0f 100644 --- a/crates/tauri/Cargo.toml +++ b/crates/tauri/Cargo.toml @@ -56,7 +56,7 @@ futures-util = "0.3" uuid = { version = "1", features = ["v4"], optional = true } url = "2" anyhow = "1.0" -thiserror = "1.0" +thiserror = "2" tauri-runtime = { version = "2.1.1", path = "../tauri-runtime" } tauri-macros = { version = "2.0.2", path = "../tauri-macros" } tauri-utils = { version = "2.0.2", features = [ diff --git a/examples/api/src-tauri/tauri-plugin-sample/Cargo.toml b/examples/api/src-tauri/tauri-plugin-sample/Cargo.toml index 095c0bd03802..15b0f050016d 100644 --- a/examples/api/src-tauri/tauri-plugin-sample/Cargo.toml +++ b/examples/api/src-tauri/tauri-plugin-sample/Cargo.toml @@ -8,7 +8,7 @@ links = "tauri-plugin-sample" tauri = { path = "../../../../crates/tauri" } log = "0.4" serde = "1" -thiserror = "1" +thiserror = "2" [build-dependencies] tauri-plugin = { path = "../../../../crates/tauri-plugin", features = [ From 60e86d5f6e0f0c769d34ef368cd8801a918d796d Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Fri, 8 Nov 2024 21:57:36 -0300 Subject: [PATCH 37/51] fix(cli): `android dev` not working on Windows without `--host` (#11624) ref https://discord.com/channels/616186924390023171/1291159454397628477 --- ...e-public-network-ip-windows-dev-android.md | 6 +++ crates/tauri-cli/src/mobile/android/dev.rs | 15 ++++--- crates/tauri-cli/src/mobile/ios/dev.rs | 16 ++++--- crates/tauri-cli/src/mobile/mod.rs | 43 ++++++++++++++++++- 4 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 .changes/use-public-network-ip-windows-dev-android.md diff --git a/.changes/use-public-network-ip-windows-dev-android.md b/.changes/use-public-network-ip-windows-dev-android.md new file mode 100644 index 000000000000..87940f566cc4 --- /dev/null +++ b/.changes/use-public-network-ip-windows-dev-android.md @@ -0,0 +1,6 @@ +--- +"tauri-cli": patch:bug +"@tauri-apps/cli": patch:bug +--- + +Use the public network IP address on `android dev` by default on Windows. diff --git a/crates/tauri-cli/src/mobile/android/dev.rs b/crates/tauri-cli/src/mobile/android/dev.rs index 1a56d737a431..6899b21a174e 100644 --- a/crates/tauri-cli/src/mobile/android/dev.rs +++ b/crates/tauri-cli/src/mobile/android/dev.rs @@ -15,7 +15,8 @@ use crate::{ }, interface::{AppInterface, Interface, MobileOptions, Options as InterfaceOptions}, mobile::{ - use_network_address_for_dev_url, write_options, CliOptions, DevChild, DevProcess, TargetDevice, + use_network_address_for_dev_url, write_options, CliOptions, DevChild, DevHost, DevProcess, + TargetDevice, }, ConfigValue, Result, }; @@ -33,7 +34,7 @@ use cargo_mobile2::{ target::TargetTrait, }; -use std::{env::set_current_dir, net::IpAddr}; +use std::env::set_current_dir; #[derive(Debug, Clone, Parser)] #[clap( @@ -70,6 +71,8 @@ pub struct Options { /// Use the public network address for the development server. /// If an actual address it provided, it is used instead of prompting to pick one. /// + /// On Windows we use the public network address by default. + /// /// This option is particularly useful along the `--open` flag when you intend on running on a physical device. /// /// This replaces the devUrl configuration value to match the public network address host, @@ -79,8 +82,8 @@ pub struct Options { /// When this is set or when running on an iOS device the CLI sets the `TAURI_DEV_HOST` /// environment variable so you can check this on your framework's configuration to expose the development server /// on the public network address. - #[clap(long)] - pub host: Option>, + #[clap(long, default_value_t, default_missing_value(""), num_args(0..=1))] + pub host: DevHost, /// Disable the built-in dev server for static files. #[clap(long)] pub no_dev_server: bool, @@ -103,7 +106,7 @@ impl From for DevOptions { no_dev_server: options.no_dev_server, port: options.port, release_mode: options.release_mode, - host: None, + host: options.host.0.unwrap_or_default(), } } } @@ -197,7 +200,7 @@ fn run_dev( noise_level: NoiseLevel, ) -> Result<()> { // when running on an actual device we must use the network IP - if options.host.is_some() + if options.host.0.is_some() || device .as_ref() .map(|device| !device.serial_no().starts_with("emulator")) diff --git a/crates/tauri-cli/src/mobile/ios/dev.rs b/crates/tauri-cli/src/mobile/ios/dev.rs index c1d57376ca74..892afa76e26e 100644 --- a/crates/tauri-cli/src/mobile/ios/dev.rs +++ b/crates/tauri-cli/src/mobile/ios/dev.rs @@ -14,7 +14,9 @@ use crate::{ flock, }, interface::{AppInterface, Interface, MobileOptions, Options as InterfaceOptions}, - mobile::{use_network_address_for_dev_url, write_options, CliOptions, DevChild, DevProcess}, + mobile::{ + use_network_address_for_dev_url, write_options, CliOptions, DevChild, DevHost, DevProcess, + }, ConfigValue, Result, }; use clap::{ArgAction, Parser}; @@ -29,7 +31,7 @@ use cargo_mobile2::{ opts::{NoiseLevel, Profile}, }; -use std::{env::set_current_dir, net::IpAddr}; +use std::env::set_current_dir; const PHYSICAL_IPHONE_DEV_WARNING: &str = "To develop on physical phones you need the `--host` option (not required for Simulators). See the documentation for more information: https://v2.tauri.app/develop/#development-server"; @@ -84,8 +86,8 @@ pub struct Options { /// When this is set or when running on an iOS device the CLI sets the `TAURI_DEV_HOST` /// environment variable so you can check this on your framework's configuration to expose the development server /// on the public network address. - #[clap(long)] - pub host: Option>, + #[clap(long, default_value_t, default_missing_value(""), num_args(0..=1))] + pub host: DevHost, /// Disable the built-in dev server for static files. #[clap(long)] pub no_dev_server: bool, @@ -108,7 +110,7 @@ impl From for DevOptions { no_dev_server: options.no_dev_server, no_dev_server_wait: options.no_dev_server_wait, port: options.port, - host: None, + host: options.host.0.unwrap_or_default(), } } } @@ -230,7 +232,7 @@ fn run_dev( noise_level: NoiseLevel, ) -> Result<()> { // when running on an actual device we must use the network IP - if options.host.is_some() + if options.host.0.is_some() || device .as_ref() .map(|device| !matches!(device.kind(), DeviceKind::Simulator)) @@ -249,7 +251,7 @@ fn run_dev( })?; let _lock = flock::open_rw(out_dir.join("lock").with_extension("ios"), "iOS")?; - let set_host = options.host.is_some(); + let set_host = options.host.0.is_some(); let open = options.open; interface.mobile_dev( diff --git a/crates/tauri-cli/src/mobile/mod.rs b/crates/tauri-cli/src/mobile/mod.rs index a9c443a5c9ca..d9e5a10dbc19 100644 --- a/crates/tauri-cli/src/mobile/mod.rs +++ b/crates/tauri-cli/src/mobile/mod.rs @@ -30,11 +30,12 @@ use std::{ collections::HashMap, env::{set_var, temp_dir}, ffi::OsString, - fmt::Write, + fmt::{Display, Write}, fs::{read_to_string, write}, - net::{IpAddr, Ipv4Addr, SocketAddr}, + net::{AddrParseError, IpAddr, Ipv4Addr, SocketAddr}, path::PathBuf, process::{exit, ExitStatus}, + str::FromStr, sync::{ atomic::{AtomicBool, Ordering}, Arc, OnceLock, @@ -141,6 +142,44 @@ pub struct TargetDevice { name: String, } +#[derive(Debug, Clone)] +pub struct DevHost(Option>); + +impl FromStr for DevHost { + type Err = AddrParseError; + fn from_str(s: &str) -> std::result::Result { + if s.is_empty() || s == "" { + Ok(Self(Some(None))) + } else if s == "" { + Ok(Self(None)) + } else { + IpAddr::from_str(s).map(|addr| Self(Some(Some(addr)))) + } + } +} + +impl Display for DevHost { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self.0 { + Some(None) => write!(f, ""), + Some(Some(addr)) => write!(f, "{addr}"), + None => write!(f, ""), + } + } +} + +impl Default for DevHost { + fn default() -> Self { + // on Windows we want to force using the public network address for the development server + // because the adb port forwarding does not work well + if cfg!(windows) { + Self(Some(None)) + } else { + Self(None) + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CliOptions { pub dev: bool, From 3f6f07a1b8dd1dfe3edefe21a7835e758834c00d Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Sat, 9 Nov 2024 04:14:22 +0200 Subject: [PATCH 38/51] chore(deps): update `wry` to `0.47` and `tao` to `0.30.6` (#11627) --- Cargo.lock | 24 ++++++++++++++++++------ crates/tauri-runtime-wry/Cargo.toml | 4 ++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 05388293b076..4c172990da12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1879,6 +1879,16 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "time", + "version_check", +] + [[package]] name = "cookie-factory" version = "0.3.3" @@ -4857,7 +4867,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -8911,9 +8921,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.30.5" +version = "0.30.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63f1f6b2017cc33d7f6fc9c6186a2c0f5dfc985899a7b4fe9e64985c17533db3" +checksum = "833b4d43383d76d5078d72f3acd977f47eb5b6751eb40baa665d13828e7b79df" dependencies = [ "bitflags 2.6.0", "cocoa 0.26.0", @@ -10788,7 +10798,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -11271,12 +11281,13 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "wry" -version = "0.46.1" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f8c948dc5f7c23bd93ba03b85b7f679852589bb78e150424d993171e4ef7b73" +checksum = "553ca1ce149982123962fac2506aa75b8b76288779a77e72b12fa2fc34938647" dependencies = [ "base64 0.22.1", "block2", + "cookie", "crossbeam-channel", "dpi", "dunce", @@ -11302,6 +11313,7 @@ dependencies = [ "tao-macros", "thiserror 1.0.68", "tracing", + "url", "webkit2gtk", "webkit2gtk-sys", "webview2-com", diff --git a/crates/tauri-runtime-wry/Cargo.toml b/crates/tauri-runtime-wry/Cargo.toml index 9633ba0987b1..577c3b28c08c 100644 --- a/crates/tauri-runtime-wry/Cargo.toml +++ b/crates/tauri-runtime-wry/Cargo.toml @@ -17,13 +17,13 @@ rustc-args = ["--cfg", "docsrs"] rustdoc-args = ["--cfg", "docsrs"] [dependencies] -wry = { version = "0.46.1", default-features = false, features = [ +wry = { version = "0.47", default-features = false, features = [ "drag-drop", "protocol", "os-webview", "linux-body", ] } -tao = { version = "0.30.5", default-features = false, features = ["rwh_06"] } +tao = { version = "0.30.6", default-features = false, features = ["rwh_06"] } tauri-runtime = { version = "2.1.0", path = "../tauri-runtime" } tauri-utils = { version = "2.0.2", path = "../tauri-utils" } raw-window-handle = "0.6" From 86f22f0ec9fae91d9dd7a02d2855d05ffee8d671 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 9 Nov 2024 15:47:39 +0200 Subject: [PATCH 39/51] apply version updates (#11440) Co-authored-by: amrbashir --- .changes/add-headers-config-option.md | 5 --- .changes/android-home-dir.md | 5 --- .changes/api-dpi-toIPC.md | 10 ----- .changes/background-color-apis.md | 6 --- .changes/background-color.md | 8 ---- .changes/bundler-fragment-handlebars.md | 7 --- .changes/bundler-linux-recommends.md | 6 --- .changes/child-windows-macos.md | 7 --- .changes/cli-migrate-deno.md | 7 --- .changes/cli-remove-command.md | 6 --- .changes/cli-updater-errorr.md | 7 --- .changes/cli-yarn-berry.md | 6 --- .changes/config-devtools.md | 8 ---- .changes/curosr-position-gtk.md | 6 --- .changes/enhance-async-commands-error.md | 6 --- .changes/enhance-resource-dir-linux.md | 5 --- .changes/event-anylabel-fix.md | 5 --- .changes/js-submenu-in-options.md | 5 --- .changes/migrate-schema.md | 6 --- .changes/permission-add-default-windows.md | 6 --- .changes/resolve_command_scope.md | 5 --- .changes/rpm-compression-level.md | 10 ----- .changes/tauri-toIPC copy.md | 5 --- .changes/tray-async-command.md | 5 --- ...e-public-network-ip-windows-dev-android.md | 6 --- .../use_https_windows-and-android-config.md | 6 --- .changes/use_https_windows-and-android.md | 7 --- .changes/utils-acl-path-errors.md | 6 --- .changes/webview-builder-devtools.md | 8 ---- .changes/webview-focus-apis.md | 5 --- .changes/webview-window-focused.md | 7 --- .changes/window-class-name-config-api.md | 5 --- .changes/window-class-name-config.md | 6 --- .changes/window-class-name.md | 7 --- Cargo.lock | 44 +++++++++---------- crates/tauri-build/CHANGELOG.md | 7 +++ crates/tauri-build/Cargo.toml | 6 +-- crates/tauri-bundler/CHANGELOG.md | 12 +++++ crates/tauri-bundler/Cargo.toml | 4 +- crates/tauri-cli/CHANGELOG.md | 25 +++++++++++ crates/tauri-cli/Cargo.toml | 6 +-- crates/tauri-cli/config.schema.json | 2 +- crates/tauri-cli/metadata-v2.json | 8 ++-- crates/tauri-codegen/CHANGELOG.md | 6 +++ crates/tauri-codegen/Cargo.toml | 4 +- crates/tauri-macros/CHANGELOG.md | 11 +++++ crates/tauri-macros/Cargo.toml | 6 +-- crates/tauri-plugin/CHANGELOG.md | 6 +++ crates/tauri-plugin/Cargo.toml | 4 +- crates/tauri-runtime-wry/CHANGELOG.md | 20 +++++++++ crates/tauri-runtime-wry/Cargo.toml | 6 +-- crates/tauri-runtime/CHANGELOG.md | 17 +++++++ crates/tauri-runtime/Cargo.toml | 4 +- .../schemas/config.schema.json | 2 +- crates/tauri-utils/CHANGELOG.md | 19 ++++++++ crates/tauri-utils/Cargo.toml | 2 +- crates/tauri/CHANGELOG.md | 43 ++++++++++++++++++ crates/tauri/Cargo.toml | 14 +++--- packages/api/CHANGELOG.md | 18 ++++++++ packages/api/package.json | 2 +- packages/cli/CHANGELOG.md | 23 ++++++++++ packages/cli/package.json | 2 +- 62 files changed, 265 insertions(+), 273 deletions(-) delete mode 100644 .changes/add-headers-config-option.md delete mode 100644 .changes/android-home-dir.md delete mode 100644 .changes/api-dpi-toIPC.md delete mode 100644 .changes/background-color-apis.md delete mode 100644 .changes/background-color.md delete mode 100644 .changes/bundler-fragment-handlebars.md delete mode 100644 .changes/bundler-linux-recommends.md delete mode 100644 .changes/child-windows-macos.md delete mode 100644 .changes/cli-migrate-deno.md delete mode 100644 .changes/cli-remove-command.md delete mode 100644 .changes/cli-updater-errorr.md delete mode 100644 .changes/cli-yarn-berry.md delete mode 100644 .changes/config-devtools.md delete mode 100644 .changes/curosr-position-gtk.md delete mode 100644 .changes/enhance-async-commands-error.md delete mode 100644 .changes/enhance-resource-dir-linux.md delete mode 100644 .changes/event-anylabel-fix.md delete mode 100644 .changes/js-submenu-in-options.md delete mode 100644 .changes/migrate-schema.md delete mode 100644 .changes/permission-add-default-windows.md delete mode 100644 .changes/resolve_command_scope.md delete mode 100644 .changes/rpm-compression-level.md delete mode 100644 .changes/tauri-toIPC copy.md delete mode 100644 .changes/tray-async-command.md delete mode 100644 .changes/use-public-network-ip-windows-dev-android.md delete mode 100644 .changes/use_https_windows-and-android-config.md delete mode 100644 .changes/use_https_windows-and-android.md delete mode 100644 .changes/utils-acl-path-errors.md delete mode 100644 .changes/webview-builder-devtools.md delete mode 100644 .changes/webview-focus-apis.md delete mode 100644 .changes/webview-window-focused.md delete mode 100644 .changes/window-class-name-config-api.md delete mode 100644 .changes/window-class-name-config.md delete mode 100644 .changes/window-class-name.md diff --git a/.changes/add-headers-config-option.md b/.changes/add-headers-config-option.md deleted file mode 100644 index 67da5948ffea..000000000000 --- a/.changes/add-headers-config-option.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-utils": 'minor:feat' -"tauri": 'minor:feat' ---- -Adds a new configuration option `app > security > headers` to define headers that will be added to every http response from tauri to the web view. This doesn't include IPC messages and error responses. diff --git a/.changes/android-home-dir.md b/.changes/android-home-dir.md deleted file mode 100644 index b2b5a5885cd0..000000000000 --- a/.changes/android-home-dir.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": "patch:feat" ---- - -Add `PathResolver::home_dir()` method on Android. diff --git a/.changes/api-dpi-toIPC.md b/.changes/api-dpi-toIPC.md deleted file mode 100644 index c0258131e598..000000000000 --- a/.changes/api-dpi-toIPC.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@tauri-apps/api": "minor:feat" -"tauri": "minor:feat" ---- - -Improved support for `dpi` module types to allow these types to be used without manual conversions with `invoke`: - -- Added `SERIALIZE_TO_IPC_FN` const in `core` module which can be used to implement custom IPC serialization for types passed to `invoke`. -- Added `Size` and `Position` classes in `dpi` module. -- Implementd `SERIALIZE_TO_IPC_FN` method on `PhysicalSize`, `PhysicalPosition`, `LogicalSize` and `LogicalPosition` to convert it into a valid IPC-compatible value that can be deserialized correctly on the Rust side into its equivalent struct. diff --git a/.changes/background-color-apis.md b/.changes/background-color-apis.md deleted file mode 100644 index 853a7540e87b..000000000000 --- a/.changes/background-color-apis.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@tauri-apps/api": minor:feat ---- - -Added `Webview::setBackgroundColor`, `WebviewWindow::setBackgroundColor` APIs to set the window background color dynamically -and a `backgroundColor` window option to set the background color on window creation. diff --git a/.changes/background-color.md b/.changes/background-color.md deleted file mode 100644 index 35d120c4ef1e..000000000000 --- a/.changes/background-color.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"tauri": minor:feat -"tauri-utils": minor:feat -"tauri-runtime": minor:feat -"tauri-runtime-wry": minor:feat ---- - -Added `Window::set_background_color` and `WindowBuilder::background_color`. diff --git a/.changes/bundler-fragment-handlebars.md b/.changes/bundler-fragment-handlebars.md deleted file mode 100644 index d836fec27ad5..000000000000 --- a/.changes/bundler-fragment-handlebars.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri-bundler": "minor:feat" -"tauri-cli": "minor:feat" ---- - -Process `bundle > windows > wix > fragmentPaths` with Handlebars to interpolate expressions within it. - diff --git a/.changes/bundler-linux-recommends.md b/.changes/bundler-linux-recommends.md deleted file mode 100644 index 13a18b9f8025..000000000000 --- a/.changes/bundler-linux-recommends.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-bundler": "patch:feat" ---- - -Add `bundle > linux > deb > recommends` and `bundle > linux > rpm > recommends` fields to declare a strong, but not absolute, dependency for your `.deb` and `.rpm` packages. - diff --git a/.changes/child-windows-macos.md b/.changes/child-windows-macos.md deleted file mode 100644 index 4c9f52651702..000000000000 --- a/.changes/child-windows-macos.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": "patch:bug" -"tauri-runtime-wry": "patch:bug" ---- - -Fix regression in creating child webviews on macOS and Windows, covering the whole window. - diff --git a/.changes/cli-migrate-deno.md b/.changes/cli-migrate-deno.md deleted file mode 100644 index 63e58dcfdb3f..000000000000 --- a/.changes/cli-migrate-deno.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri-cli": "patch:bug" -"@tauri-apps/cli": "patch:bug" ---- - -Fix `tauri migrate` failing to install NPM depenencies when running from Deno. - diff --git a/.changes/cli-remove-command.md b/.changes/cli-remove-command.md deleted file mode 100644 index 523c08082bc0..000000000000 --- a/.changes/cli-remove-command.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-cli": minor:feat -"@tauri-apps/cli": minor:feat ---- - -Add `tauri remove` to remove plugins from projects. diff --git a/.changes/cli-updater-errorr.md b/.changes/cli-updater-errorr.md deleted file mode 100644 index 8a865ac290d5..000000000000 --- a/.changes/cli-updater-errorr.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri-cli": "patch:enhance" -"@tauri-apps/cli": "patch:enhance" ---- - -Add more context for errors when decoding secret and public keys for signing updater artifacts. - diff --git a/.changes/cli-yarn-berry.md b/.changes/cli-yarn-berry.md deleted file mode 100644 index 6c75565de6b6..000000000000 --- a/.changes/cli-yarn-berry.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-cli": "patch:bug" -"@tauri-apps/cli": "patch:bug" ---- - -Fix detecting yarn berry (v2 and higher) in various tauri cli commands. diff --git a/.changes/config-devtools.md b/.changes/config-devtools.md deleted file mode 100644 index a75ecfbc1f14..000000000000 --- a/.changes/config-devtools.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"tauri": "patch:feat" -"tauri-utils": "patch:feat" -"@tauri-apps/api": "patch:feat" ---- - -Add `app > windows > devtools` config option and when creating the webview from JS, to enable or disable devtools for a specific webview. - diff --git a/.changes/curosr-position-gtk.md b/.changes/curosr-position-gtk.md deleted file mode 100644 index 4bc87b6bb9c6..000000000000 --- a/.changes/curosr-position-gtk.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": "patch:bug" -"tauri-runtime-wry": "patch:bug" ---- - -Fix `App/AppHandle/Window/Webview/WebviewWindow::cursor_position` getter method failing on Linux with `GDK may only be used from the main thread`. diff --git a/.changes/enhance-async-commands-error.md b/.changes/enhance-async-commands-error.md deleted file mode 100644 index e7be9d49383a..000000000000 --- a/.changes/enhance-async-commands-error.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": "patch:enhance" -"tauri-macros": "patch:enhance" ---- - -Enhance the error message when using `async` commands with a reference. diff --git a/.changes/enhance-resource-dir-linux.md b/.changes/enhance-resource-dir-linux.md deleted file mode 100644 index c528bad12467..000000000000 --- a/.changes/enhance-resource-dir-linux.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-utils": patch:bug ---- - -Enhance resource directory resolution to support running on distros like NixOS. diff --git a/.changes/event-anylabel-fix.md b/.changes/event-anylabel-fix.md deleted file mode 100644 index cdf47c67c7c4..000000000000 --- a/.changes/event-anylabel-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": "patch:bug" ---- - -Fix listeners created with `EventTarget::AnyLabel` never receiving events. diff --git a/.changes/js-submenu-in-options.md b/.changes/js-submenu-in-options.md deleted file mode 100644 index 3a0ae0c8a280..000000000000 --- a/.changes/js-submenu-in-options.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@tauri-apps/api": "patch:bug" ---- - -Fix submenu created as a menu item instead of a submenu when created by using an object in the `items` field in the options object passed to `Menu.new` or `Submenu.new`. diff --git a/.changes/migrate-schema.md b/.changes/migrate-schema.md deleted file mode 100644 index 1430e589853c..000000000000 --- a/.changes/migrate-schema.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@tauri-apps/cli": patch:enhance -"tauri-cli": patch:enhance ---- - -Migrate the `$schema` Tauri configuration to the v2 format. diff --git a/.changes/permission-add-default-windows.md b/.changes/permission-add-default-windows.md deleted file mode 100644 index 3540e83e44e9..000000000000 --- a/.changes/permission-add-default-windows.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@tauri-apps/cli": patch:enhance -"tauri-cli": patch:enhance ---- - -Associate a newly created capability file with the `main` window on the `tauri add` and `tauri permission add` commands. diff --git a/.changes/resolve_command_scope.md b/.changes/resolve_command_scope.md deleted file mode 100644 index 8245a8acb3aa..000000000000 --- a/.changes/resolve_command_scope.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch:feat ---- - -Added `WebviewWindow::resolve_command_scope` to check a command scope at runtime. diff --git a/.changes/rpm-compression-level.md b/.changes/rpm-compression-level.md deleted file mode 100644 index 5a2017fea94d..000000000000 --- a/.changes/rpm-compression-level.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"tauri-bundler": "minor:feat" -"tauri-cli": "minor:feat" -"@tauri-apps/cli": "minor:feat" -"tauri-utils": "minor:feat" ---- - -Add `bundle > linux > rpm > compression` config option to control RPM bundle compression type and level. - - diff --git a/.changes/tauri-toIPC copy.md b/.changes/tauri-toIPC copy.md deleted file mode 100644 index e4957e3ecf08..000000000000 --- a/.changes/tauri-toIPC copy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": "minor:feat" ---- - -Detect if `SERIALIZE_TO_IPC_FN`, const from the JS `core` module, is implemented on objects when serializing over IPC and use it. diff --git a/.changes/tray-async-command.md b/.changes/tray-async-command.md deleted file mode 100644 index 9e40178190e2..000000000000 --- a/.changes/tray-async-command.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": "patch:bug" ---- - -Fix tray events not fired for tray icons created inside an async command. diff --git a/.changes/use-public-network-ip-windows-dev-android.md b/.changes/use-public-network-ip-windows-dev-android.md deleted file mode 100644 index 87940f566cc4..000000000000 --- a/.changes/use-public-network-ip-windows-dev-android.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-cli": patch:bug -"@tauri-apps/cli": patch:bug ---- - -Use the public network IP address on `android dev` by default on Windows. diff --git a/.changes/use_https_windows-and-android-config.md b/.changes/use_https_windows-and-android-config.md deleted file mode 100644 index 3e5598a89e42..000000000000 --- a/.changes/use_https_windows-and-android-config.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": "minor:feat" -"tauri-utils": "minor:feat" ---- - -Add `app > windows > useHttpsScheme` config option to choose whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android diff --git a/.changes/use_https_windows-and-android.md b/.changes/use_https_windows-and-android.md deleted file mode 100644 index 0e1bbb1a6c6d..000000000000 --- a/.changes/use_https_windows-and-android.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": "minor:feat" -"tauri-runtime": "minor:feat" -"tauri-runtime-wry": "minor:feat" ---- - -Add `WebviewWindowBuilder/WebviewBuilder::use_https_scheme` to choose whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android diff --git a/.changes/utils-acl-path-errors.md b/.changes/utils-acl-path-errors.md deleted file mode 100644 index 95fcf0fe3be1..000000000000 --- a/.changes/utils-acl-path-errors.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": minor:enhance -"tauri-utils": minor:enhance ---- - -Include the path in ACL I/O errors. \ No newline at end of file diff --git a/.changes/webview-builder-devtools.md b/.changes/webview-builder-devtools.md deleted file mode 100644 index 5db1761729b0..000000000000 --- a/.changes/webview-builder-devtools.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"tauri": "patch:feat" -"tauri-runtime": "patch:feat" -"tauri-runtime-wry": "patch:feat" ---- - -Add `WebviewWindowBuilder::devtools` and `WebviewBuilder::devtools` to enable or disable devtools for a specific webview. - diff --git a/.changes/webview-focus-apis.md b/.changes/webview-focus-apis.md deleted file mode 100644 index 2d478fede8cd..000000000000 --- a/.changes/webview-focus-apis.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": "patch:feat" ---- - -Add `WebviewBuilder::focused` method to choose whether to focus webview or not on creation. diff --git a/.changes/webview-window-focused.md b/.changes/webview-window-focused.md deleted file mode 100644 index b95b4cf42a74..000000000000 --- a/.changes/webview-window-focused.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": "patch:bug" -"tauri-runtime": "patch:bug" -"tauri-runtime-wry": "patch:bug" ---- - -Fix webview not focused by default. diff --git a/.changes/window-class-name-config-api.md b/.changes/window-class-name-config-api.md deleted file mode 100644 index 13128871bad5..000000000000 --- a/.changes/window-class-name-config-api.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@tauri-apps/api": 'minor:feat' ---- - -Added `windowClassname` option, when constructing a `Webview` or `WebviewWindow`, to specify the name of the window class on Windows. diff --git a/.changes/window-class-name-config.md b/.changes/window-class-name-config.md deleted file mode 100644 index 66e318c0994d..000000000000 --- a/.changes/window-class-name-config.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": 'minor:feat' -"tauri-utils": 'minor:feat' ---- - -Added `app > windows > windowClassname` config option to specify the name of the window class on Windows. diff --git a/.changes/window-class-name.md b/.changes/window-class-name.md deleted file mode 100644 index 015602e820c8..000000000000 --- a/.changes/window-class-name.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": 'minor:feat' -"tauri-runtime-wry": 'minor:feat' -"tauri-runtime": 'minor:feat' ---- - -Added `WindowBuilder/WebviewWindowBuilder::window_classname` method to specify the name of the window class on Windows. diff --git a/Cargo.lock b/Cargo.lock index 4c172990da12..41d86e07fb6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,7 +14,7 @@ version = "0.1.0" dependencies = [ "insta", "serde_json", - "tauri-utils 2.0.2", + "tauri-utils 2.1.0", ] [[package]] @@ -8994,7 +8994,7 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.0.6" +version = "2.1.0" dependencies = [ "anyhow", "bytes", @@ -9038,7 +9038,7 @@ dependencies = [ "tauri-macros", "tauri-runtime", "tauri-runtime-wry", - "tauri-utils 2.0.2", + "tauri-utils 2.1.0", "thiserror 2.0.0", "tokio", "tracing", @@ -9054,7 +9054,7 @@ dependencies = [ [[package]] name = "tauri-build" -version = "2.0.2" +version = "2.0.3" dependencies = [ "anyhow", "cargo_toml", @@ -9068,7 +9068,7 @@ dependencies = [ "serde", "serde_json", "tauri-codegen", - "tauri-utils 2.0.2", + "tauri-utils 2.1.0", "tauri-winres", "toml 0.8.19", "walkdir", @@ -9076,7 +9076,7 @@ dependencies = [ [[package]] name = "tauri-bundler" -version = "2.0.4" +version = "2.1.0" dependencies = [ "anyhow", "ar", @@ -9105,7 +9105,7 @@ dependencies = [ "tar", "tauri-icns", "tauri-macos-sign", - "tauri-utils 2.0.2", + "tauri-utils 2.1.0", "tempfile", "thiserror 2.0.0", "time", @@ -9120,7 +9120,7 @@ dependencies = [ [[package]] name = "tauri-cli" -version = "2.0.4" +version = "2.1.0" dependencies = [ "anyhow", "ar", @@ -9185,7 +9185,7 @@ dependencies = [ "tauri-icns", "tauri-macos-sign", "tauri-utils 1.6.0", - "tauri-utils 2.0.2", + "tauri-utils 2.1.0", "tempfile", "tokio", "toml 0.8.19", @@ -9210,7 +9210,7 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "2.0.2" +version = "2.0.3" dependencies = [ "base64 0.22.1", "brotli", @@ -9226,7 +9226,7 @@ dependencies = [ "serde_json", "sha2", "syn 2.0.87", - "tauri-utils 2.0.2", + "tauri-utils 2.1.0", "thiserror 2.0.0", "time", "url", @@ -9294,14 +9294,14 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.0.2" +version = "2.0.3" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.87", "tauri-codegen", - "tauri-utils 2.0.2", + "tauri-utils 2.1.0", ] [[package]] @@ -9323,7 +9323,7 @@ dependencies = [ [[package]] name = "tauri-plugin" -version = "2.0.2" +version = "2.0.3" dependencies = [ "anyhow", "glob", @@ -9331,7 +9331,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "tauri-utils 2.0.2", + "tauri-utils 2.1.0", "toml 0.8.19", "walkdir", ] @@ -9365,13 +9365,13 @@ dependencies = [ "log", "serde", "tauri", - "tauri-plugin 2.0.2", + "tauri-plugin 2.0.3", "thiserror 2.0.0", ] [[package]] name = "tauri-runtime" -version = "2.1.1" +version = "2.2.0" dependencies = [ "dpi", "gtk", @@ -9380,7 +9380,7 @@ dependencies = [ "raw-window-handle", "serde", "serde_json", - "tauri-utils 2.0.2", + "tauri-utils 2.1.0", "thiserror 2.0.0", "url", "windows", @@ -9388,7 +9388,7 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "2.1.2" +version = "2.2.0" dependencies = [ "gtk", "http 1.1.0", @@ -9402,7 +9402,7 @@ dependencies = [ "softbuffer", "tao", "tauri-runtime", - "tauri-utils 2.0.2", + "tauri-utils 2.1.0", "tracing", "url", "webkit2gtk", @@ -9418,7 +9418,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "tauri-utils 2.0.2", + "tauri-utils 2.1.0", "url", ] @@ -9503,7 +9503,7 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "2.0.2" +version = "2.1.0" dependencies = [ "aes-gcm", "brotli", diff --git a/crates/tauri-build/CHANGELOG.md b/crates/tauri-build/CHANGELOG.md index 4070e0d9ea6f..43c42af79d65 100644 --- a/crates/tauri-build/CHANGELOG.md +++ b/crates/tauri-build/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## \[2.0.3] + +### Dependencies + +- Upgraded to `tauri-utils@2.1.0` +- Upgraded to `tauri-codegen@2.0.3` + ## \[2.0.2] ### Dependencies diff --git a/crates/tauri-build/Cargo.toml b/crates/tauri-build/Cargo.toml index d6557a3852f0..858e500f1787 100644 --- a/crates/tauri-build/Cargo.toml +++ b/crates/tauri-build/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tauri-build" -version = "2.0.2" +version = "2.0.3" description = "build time code to pair with https://crates.io/crates/tauri" exclude = ["CHANGELOG.md", "/target"] readme = "README.md" @@ -28,8 +28,8 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] anyhow = "1" quote = { version = "1", optional = true } -tauri-codegen = { version = "2.0.2", path = "../tauri-codegen", optional = true } -tauri-utils = { version = "2.0.2", path = "../tauri-utils", features = [ +tauri-codegen = { version = "2.0.3", path = "../tauri-codegen", optional = true } +tauri-utils = { version = "2.1.0", path = "../tauri-utils", features = [ "build", "resources", ] } diff --git a/crates/tauri-bundler/CHANGELOG.md b/crates/tauri-bundler/CHANGELOG.md index 7c914b189bac..1acb1a70b9db 100644 --- a/crates/tauri-bundler/CHANGELOG.md +++ b/crates/tauri-bundler/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## \[2.1.0] + +### New Features + +- [`1b6b2cfaa`](https://www.github.com/tauri-apps/tauri/commit/1b6b2cfaa14ab1d418c676cedbf942a812377a30) ([#11521](https://www.github.com/tauri-apps/tauri/pull/11521) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Process `bundle > windows > wix > fragmentPaths` with Handlebars to interpolate expressions within it. +- [`6dea12a06`](https://www.github.com/tauri-apps/tauri/commit/6dea12a0677a905cb1f14969fe05c53e7cd717c6) ([#11402](https://www.github.com/tauri-apps/tauri/pull/11402) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `bundle > linux > deb > recommends` and `bundle > linux > rpm > recommends` fields to declare a strong, but not absolute, dependency for your `.deb` and `.rpm` packages. +- [`058c0db72`](https://www.github.com/tauri-apps/tauri/commit/058c0db72f43fbe1574d0db654560e693755cd7e) ([#11584](https://www.github.com/tauri-apps/tauri/pull/11584) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `bundle > linux > rpm > compression` config option to control RPM bundle compression type and level. + +### Dependencies + +- Upgraded to `tauri-utils@2.1.0` + ## \[2.0.4] ### New Features diff --git a/crates/tauri-bundler/Cargo.toml b/crates/tauri-bundler/Cargo.toml index 447642a1257d..0bac40537fcd 100644 --- a/crates/tauri-bundler/Cargo.toml +++ b/crates/tauri-bundler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tauri-bundler" -version = "2.0.4" +version = "2.1.0" authors = [ "George Burton ", "Tauri Programme within The Commons Conservancy", @@ -15,7 +15,7 @@ rust-version = "1.77.2" exclude = ["CHANGELOG.md", "/target", "rustfmt.toml"] [dependencies] -tauri-utils = { version = "2.0.2", path = "../tauri-utils", features = [ +tauri-utils = { version = "2.1.0", path = "../tauri-utils", features = [ "resources", ] } image = "0.25.0" diff --git a/crates/tauri-cli/CHANGELOG.md b/crates/tauri-cli/CHANGELOG.md index 1f4d6378a038..29eae0a920cd 100644 --- a/crates/tauri-cli/CHANGELOG.md +++ b/crates/tauri-cli/CHANGELOG.md @@ -1,5 +1,30 @@ # Changelog +## \[2.1.0] + +### New Features + +- [`1b6b2cfaa`](https://www.github.com/tauri-apps/tauri/commit/1b6b2cfaa14ab1d418c676cedbf942a812377a30) ([#11521](https://www.github.com/tauri-apps/tauri/pull/11521) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Process `bundle > windows > wix > fragmentPaths` with Handlebars to interpolate expressions within it. +- [`6bf917941`](https://www.github.com/tauri-apps/tauri/commit/6bf917941ff0fcc49e86b3ba427340b75f3ce49c) ([#11322](https://www.github.com/tauri-apps/tauri/pull/11322) by [@ShaunSHamilton](https://www.github.com/tauri-apps/tauri/../../ShaunSHamilton)) Add `tauri remove` to remove plugins from projects. +- [`058c0db72`](https://www.github.com/tauri-apps/tauri/commit/058c0db72f43fbe1574d0db654560e693755cd7e) ([#11584](https://www.github.com/tauri-apps/tauri/pull/11584) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `bundle > linux > rpm > compression` config option to control RPM bundle compression type and level. + +### Enhancements + +- [`1f311832a`](https://www.github.com/tauri-apps/tauri/commit/1f311832ab5b2d62a533dfcf9b1d78bddf249ae8) ([#11405](https://www.github.com/tauri-apps/tauri/pull/11405) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add more context for errors when decoding secret and public keys for signing updater artifacts. +- [`e0d1307d3`](https://www.github.com/tauri-apps/tauri/commit/e0d1307d3f78987d0059921a5ab01ea4b26e0ef1) ([#11414](https://www.github.com/tauri-apps/tauri/pull/11414) by [@Czxck001](https://www.github.com/tauri-apps/tauri/../../Czxck001)) Migrate the `$schema` Tauri configuration to the v2 format. +- [`c43d5df15`](https://www.github.com/tauri-apps/tauri/commit/c43d5df15828ecffa606482ea2b60350c488c981) ([#11512](https://www.github.com/tauri-apps/tauri/pull/11512) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Associate a newly created capability file with the `main` window on the `tauri add` and `tauri permission add` commands. + +### Bug Fixes + +- [`7af01ff2c`](https://www.github.com/tauri-apps/tauri/commit/7af01ff2ce623d727cd13a4c8a549c1c80031882) ([#11523](https://www.github.com/tauri-apps/tauri/pull/11523) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix `tauri migrate` failing to install NPM depenencies when running from Deno. +- [`100a4455a`](https://www.github.com/tauri-apps/tauri/commit/100a4455aa48df508510bbc08273215bdf70c012) ([#11529](https://www.github.com/tauri-apps/tauri/pull/11529) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix detecting yarn berry (v2 and higher) in various tauri cli commands. +- [`60e86d5f6`](https://www.github.com/tauri-apps/tauri/commit/60e86d5f6e0f0c769d34ef368cd8801a918d796d) ([#11624](https://www.github.com/tauri-apps/tauri/pull/11624) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Use the public network IP address on `android dev` by default on Windows. + +### Dependencies + +- Upgraded to `tauri-utils@2.1.0` +- Upgraded to `tauri-bundler@2.1.0` + ## \[2.0.4] ### Enhancements diff --git a/crates/tauri-cli/Cargo.toml b/crates/tauri-cli/Cargo.toml index 464ec7dcdb20..e0756d299beb 100644 --- a/crates/tauri-cli/Cargo.toml +++ b/crates/tauri-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tauri-cli" -version = "2.0.4" +version = "2.1.0" authors = ["Tauri Programme within The Commons Conservancy"] edition = "2021" rust-version = "1.77.2" @@ -47,7 +47,7 @@ sublime_fuzzy = "0.7" clap_complete = "4" clap = { version = "4.5", features = ["derive", "env"] } anyhow = "1.0" -tauri-bundler = { version = "2.0.4", default-features = false, path = "../tauri-bundler" } +tauri-bundler = { version = "2.1.0", default-features = false, path = "../tauri-bundler" } colored = "2.1" serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", features = ["preserve_order"] } @@ -57,7 +57,7 @@ shared_child = "1.0" duct = "0.13" toml_edit = { version = "0.22", features = ["serde"] } json-patch = "3.0" -tauri-utils = { version = "2.0.2", path = "../tauri-utils", features = [ +tauri-utils = { version = "2.1.0", path = "../tauri-utils", features = [ "isolation", "schema", "config-json5", diff --git a/crates/tauri-cli/config.schema.json b/crates/tauri-cli/config.schema.json index 4bc434e06f32..8abbf0877a20 100644 --- a/crates/tauri-cli/config.schema.json +++ b/crates/tauri-cli/config.schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://schema.tauri.app/config/2.0.6", + "$id": "https://schema.tauri.app/config/2.1.0", "title": "Config", "description": "The Tauri configuration object.\n It is read from a file where you can define your frontend assets,\n configure the bundler and define a tray icon.\n\n The configuration file is generated by the\n [`tauri init`](https://v2.tauri.app/reference/cli/#init) command that lives in\n your Tauri application source directory (src-tauri).\n\n Once generated, you may modify it at will to customize your Tauri application.\n\n ## File Formats\n\n By default, the configuration is defined as a JSON file named `tauri.conf.json`.\n\n Tauri also supports JSON5 and TOML files via the `config-json5` and `config-toml` Cargo features, respectively.\n The JSON5 file name must be either `tauri.conf.json` or `tauri.conf.json5`.\n The TOML file name is `Tauri.toml`.\n\n ## Platform-Specific Configuration\n\n In addition to the default configuration file, Tauri can\n read a platform-specific configuration from `tauri.linux.conf.json`,\n `tauri.windows.conf.json`, `tauri.macos.conf.json`, `tauri.android.conf.json` and `tauri.ios.conf.json`\n (or `Tauri.linux.toml`, `Tauri.windows.toml`, `Tauri.macos.toml`, `Tauri.android.toml` and `Tauri.ios.toml` if the `Tauri.toml` format is used),\n which gets merged with the main configuration object.\n\n ## Configuration Structure\n\n The configuration is composed of the following objects:\n\n - [`app`](#appconfig): The Tauri configuration\n - [`build`](#buildconfig): The build configuration\n - [`bundle`](#bundleconfig): The bundle configurations\n - [`plugins`](#pluginconfig): The plugins configuration\n\n Example tauri.config.json file:\n\n ```json\n {\n \"productName\": \"tauri-app\",\n \"version\": \"0.1.0\",\n \"build\": {\n \"beforeBuildCommand\": \"\",\n \"beforeDevCommand\": \"\",\n \"devUrl\": \"../dist\",\n \"frontendDist\": \"../dist\"\n },\n \"app\": {\n \"security\": {\n \"csp\": null\n },\n \"windows\": [\n {\n \"fullscreen\": false,\n \"height\": 600,\n \"resizable\": true,\n \"title\": \"Tauri App\",\n \"width\": 800\n }\n ]\n },\n \"bundle\": {},\n \"plugins\": {}\n }\n ```", "type": "object", diff --git a/crates/tauri-cli/metadata-v2.json b/crates/tauri-cli/metadata-v2.json index 9aad788db254..06bb27c2c93d 100644 --- a/crates/tauri-cli/metadata-v2.json +++ b/crates/tauri-cli/metadata-v2.json @@ -1,9 +1,9 @@ { "cli.js": { - "version": "2.0.4", + "version": "2.1.0", "node": ">= 10.0.0" }, - "tauri": "2.0.6", - "tauri-build": "2.0.1", - "tauri-plugin": "2.0.1" + "tauri": "2.1.0", + "tauri-build": "2.0.2", + "tauri-plugin": "2.0.2" } diff --git a/crates/tauri-codegen/CHANGELOG.md b/crates/tauri-codegen/CHANGELOG.md index f83815365f6c..95a0fb544b90 100644 --- a/crates/tauri-codegen/CHANGELOG.md +++ b/crates/tauri-codegen/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## \[2.0.3] + +### Dependencies + +- Upgraded to `tauri-utils@2.1.0` + ## \[2.0.2] ### Dependencies diff --git a/crates/tauri-codegen/Cargo.toml b/crates/tauri-codegen/Cargo.toml index 637e18623cc9..90f0df6270e0 100644 --- a/crates/tauri-codegen/Cargo.toml +++ b/crates/tauri-codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tauri-codegen" -version = "2.0.2" +version = "2.0.3" description = "code generation meant to be consumed inside of `tauri` through `tauri-build` or `tauri-macros`" exclude = ["CHANGELOG.md", "/target"] readme = "README.md" @@ -20,7 +20,7 @@ quote = "1" syn = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" -tauri-utils = { version = "2.0.2", path = "../tauri-utils", features = [ +tauri-utils = { version = "2.1.0", path = "../tauri-utils", features = [ "build", ] } thiserror = "2" diff --git a/crates/tauri-macros/CHANGELOG.md b/crates/tauri-macros/CHANGELOG.md index a61e11044b42..3c80b3359ff7 100644 --- a/crates/tauri-macros/CHANGELOG.md +++ b/crates/tauri-macros/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## \[2.0.3] + +### Enhancements + +- [`17c6952ae`](https://www.github.com/tauri-apps/tauri/commit/17c6952aec965fa41e6695ad68461a218afc20f1) ([#11522](https://www.github.com/tauri-apps/tauri/pull/11522) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Enhance the error message when using `async` commands with a reference. + +### Dependencies + +- Upgraded to `tauri-utils@2.1.0` +- Upgraded to `tauri-codegen@2.0.3` + ## \[2.0.1] ### What's Changed diff --git a/crates/tauri-macros/Cargo.toml b/crates/tauri-macros/Cargo.toml index 543bc7f69d19..adf7d9806f76 100644 --- a/crates/tauri-macros/Cargo.toml +++ b/crates/tauri-macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tauri-macros" -version = "2.0.2" +version = "2.0.3" description = "Macros for the tauri crate." exclude = ["CHANGELOG.md", "/target"] readme = "README.md" @@ -20,8 +20,8 @@ proc-macro2 = { version = "1", features = ["span-locations"] } quote = "1" syn = { version = "2", features = ["full"] } heck = "0.5" -tauri-codegen = { version = "2.0.2", default-features = false, path = "../tauri-codegen" } -tauri-utils = { version = "2.0.2", path = "../tauri-utils" } +tauri-codegen = { version = "2.0.3", default-features = false, path = "../tauri-codegen" } +tauri-utils = { version = "2.1.0", path = "../tauri-utils" } [features] custom-protocol = [] diff --git a/crates/tauri-plugin/CHANGELOG.md b/crates/tauri-plugin/CHANGELOG.md index 482b831b6be5..26976234ab45 100644 --- a/crates/tauri-plugin/CHANGELOG.md +++ b/crates/tauri-plugin/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## \[2.0.3] + +### Dependencies + +- Upgraded to `tauri-utils@2.1.0` + ## \[2.0.2] ### Dependencies diff --git a/crates/tauri-plugin/Cargo.toml b/crates/tauri-plugin/Cargo.toml index 074e1b47b1dd..b572e55ff1ac 100644 --- a/crates/tauri-plugin/Cargo.toml +++ b/crates/tauri-plugin/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tauri-plugin" -version = "2.0.2" +version = "2.0.3" description = "Build script and runtime Tauri plugin definitions" authors.workspace = true homepage.workspace = true @@ -30,7 +30,7 @@ runtime = [] [dependencies] anyhow = { version = "1", optional = true } serde = { version = "1", optional = true } -tauri-utils = { version = "2.0.2", default-features = false, features = [ +tauri-utils = { version = "2.1.0", default-features = false, features = [ "build", ], path = "../tauri-utils" } serde_json = { version = "1", optional = true } diff --git a/crates/tauri-runtime-wry/CHANGELOG.md b/crates/tauri-runtime-wry/CHANGELOG.md index 11c4ee676cee..6fa4627d2914 100644 --- a/crates/tauri-runtime-wry/CHANGELOG.md +++ b/crates/tauri-runtime-wry/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## \[2.2.0] + +### New Features + +- [`4d545ab3c`](https://www.github.com/tauri-apps/tauri/commit/4d545ab3ca228c8a21b966b709f84a0da2864479) ([#11486](https://www.github.com/tauri-apps/tauri/pull/11486) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Added `Window::set_background_color` and `WindowBuilder::background_color`. +- [`f37e97d41`](https://www.github.com/tauri-apps/tauri/commit/f37e97d410c4a219e99f97692da05ca9d8e0ba3a) ([#11477](https://www.github.com/tauri-apps/tauri/pull/11477) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `WebviewWindowBuilder/WebviewBuilder::use_https_scheme` to choose whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android +- [`cbc095ec5`](https://www.github.com/tauri-apps/tauri/commit/cbc095ec5fe7de29b5c9265576d4e071ec159c1c) ([#11451](https://www.github.com/tauri-apps/tauri/pull/11451) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `WebviewWindowBuilder::devtools` and `WebviewBuilder::devtools` to enable or disable devtools for a specific webview. +- [`2a75c64b5`](https://www.github.com/tauri-apps/tauri/commit/2a75c64b5431284e7340e8743d4ea56a62c75466) ([#11469](https://www.github.com/tauri-apps/tauri/pull/11469) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Added `WindowBuilder/WebviewWindowBuilder::window_classname` method to specify the name of the window class on Windows. + +### Bug Fixes + +- [`229d7f8e2`](https://www.github.com/tauri-apps/tauri/commit/229d7f8e220cc8d5ca06eff1ed85cb7d047c1d6c) ([#11616](https://www.github.com/tauri-apps/tauri/pull/11616) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix regression in creating child webviews on macOS and Windows, covering the whole window. +- [`8c6d1e8e6`](https://www.github.com/tauri-apps/tauri/commit/8c6d1e8e6c852667bb223b5f4823948868c26d98) ([#11401](https://www.github.com/tauri-apps/tauri/pull/11401) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix `App/AppHandle/Window/Webview/WebviewWindow::cursor_position` getter method failing on Linux with `GDK may only be used from the main thread`. +- [`129414faa`](https://www.github.com/tauri-apps/tauri/commit/129414faa4e027c9035d56614682cacc0335a6a0) ([#11569](https://www.github.com/tauri-apps/tauri/pull/11569) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix webview not focused by default. + +### Dependencies + +- Upgraded to `tauri-utils@2.1.0` +- Upgraded to `tauri-runtime@2.2.0` + ## \[2.1.2] ### Dependencies diff --git a/crates/tauri-runtime-wry/Cargo.toml b/crates/tauri-runtime-wry/Cargo.toml index 577c3b28c08c..125b1de598cd 100644 --- a/crates/tauri-runtime-wry/Cargo.toml +++ b/crates/tauri-runtime-wry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tauri-runtime-wry" -version = "2.1.2" +version = "2.2.0" description = "Wry bindings to the Tauri runtime" exclude = ["CHANGELOG.md", "/target"] readme = "README.md" @@ -24,8 +24,8 @@ wry = { version = "0.47", default-features = false, features = [ "linux-body", ] } tao = { version = "0.30.6", default-features = false, features = ["rwh_06"] } -tauri-runtime = { version = "2.1.0", path = "../tauri-runtime" } -tauri-utils = { version = "2.0.2", path = "../tauri-utils" } +tauri-runtime = { version = "2.2.0", path = "../tauri-runtime" } +tauri-utils = { version = "2.1.0", path = "../tauri-utils" } raw-window-handle = "0.6" http = "1.1" url = "2" diff --git a/crates/tauri-runtime/CHANGELOG.md b/crates/tauri-runtime/CHANGELOG.md index c57d8b0152bf..8970d59f66fb 100644 --- a/crates/tauri-runtime/CHANGELOG.md +++ b/crates/tauri-runtime/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## \[2.2.0] + +### New Features + +- [`4d545ab3c`](https://www.github.com/tauri-apps/tauri/commit/4d545ab3ca228c8a21b966b709f84a0da2864479) ([#11486](https://www.github.com/tauri-apps/tauri/pull/11486) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Added `Window::set_background_color` and `WindowBuilder::background_color`. +- [`f37e97d41`](https://www.github.com/tauri-apps/tauri/commit/f37e97d410c4a219e99f97692da05ca9d8e0ba3a) ([#11477](https://www.github.com/tauri-apps/tauri/pull/11477) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `WebviewWindowBuilder/WebviewBuilder::use_https_scheme` to choose whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android +- [`cbc095ec5`](https://www.github.com/tauri-apps/tauri/commit/cbc095ec5fe7de29b5c9265576d4e071ec159c1c) ([#11451](https://www.github.com/tauri-apps/tauri/pull/11451) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `WebviewWindowBuilder::devtools` and `WebviewBuilder::devtools` to enable or disable devtools for a specific webview. +- [`2a75c64b5`](https://www.github.com/tauri-apps/tauri/commit/2a75c64b5431284e7340e8743d4ea56a62c75466) ([#11469](https://www.github.com/tauri-apps/tauri/pull/11469) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Added `WindowBuilder/WebviewWindowBuilder::window_classname` method to specify the name of the window class on Windows. + +### Bug Fixes + +- [`129414faa`](https://www.github.com/tauri-apps/tauri/commit/129414faa4e027c9035d56614682cacc0335a6a0) ([#11569](https://www.github.com/tauri-apps/tauri/pull/11569) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix webview not focused by default. + +### Dependencies + +- Upgraded to `tauri-utils@2.1.0` + ## \[2.1.1] ### Dependencies diff --git a/crates/tauri-runtime/Cargo.toml b/crates/tauri-runtime/Cargo.toml index ece1aa52e6ad..6a2110af08a0 100644 --- a/crates/tauri-runtime/Cargo.toml +++ b/crates/tauri-runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tauri-runtime" -version = "2.1.1" +version = "2.2.0" description = "Runtime for Tauri applications" exclude = ["CHANGELOG.md", "/target"] readme = "README.md" @@ -29,7 +29,7 @@ targets = [ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "2" -tauri-utils = { version = "2.0.2", path = "../tauri-utils" } +tauri-utils = { version = "2.1.0", path = "../tauri-utils" } http = "1.1" raw-window-handle = "0.6" url = { version = "2" } diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json index 4bc434e06f32..8abbf0877a20 100644 --- a/crates/tauri-schema-generator/schemas/config.schema.json +++ b/crates/tauri-schema-generator/schemas/config.schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://schema.tauri.app/config/2.0.6", + "$id": "https://schema.tauri.app/config/2.1.0", "title": "Config", "description": "The Tauri configuration object.\n It is read from a file where you can define your frontend assets,\n configure the bundler and define a tray icon.\n\n The configuration file is generated by the\n [`tauri init`](https://v2.tauri.app/reference/cli/#init) command that lives in\n your Tauri application source directory (src-tauri).\n\n Once generated, you may modify it at will to customize your Tauri application.\n\n ## File Formats\n\n By default, the configuration is defined as a JSON file named `tauri.conf.json`.\n\n Tauri also supports JSON5 and TOML files via the `config-json5` and `config-toml` Cargo features, respectively.\n The JSON5 file name must be either `tauri.conf.json` or `tauri.conf.json5`.\n The TOML file name is `Tauri.toml`.\n\n ## Platform-Specific Configuration\n\n In addition to the default configuration file, Tauri can\n read a platform-specific configuration from `tauri.linux.conf.json`,\n `tauri.windows.conf.json`, `tauri.macos.conf.json`, `tauri.android.conf.json` and `tauri.ios.conf.json`\n (or `Tauri.linux.toml`, `Tauri.windows.toml`, `Tauri.macos.toml`, `Tauri.android.toml` and `Tauri.ios.toml` if the `Tauri.toml` format is used),\n which gets merged with the main configuration object.\n\n ## Configuration Structure\n\n The configuration is composed of the following objects:\n\n - [`app`](#appconfig): The Tauri configuration\n - [`build`](#buildconfig): The build configuration\n - [`bundle`](#bundleconfig): The bundle configurations\n - [`plugins`](#pluginconfig): The plugins configuration\n\n Example tauri.config.json file:\n\n ```json\n {\n \"productName\": \"tauri-app\",\n \"version\": \"0.1.0\",\n \"build\": {\n \"beforeBuildCommand\": \"\",\n \"beforeDevCommand\": \"\",\n \"devUrl\": \"../dist\",\n \"frontendDist\": \"../dist\"\n },\n \"app\": {\n \"security\": {\n \"csp\": null\n },\n \"windows\": [\n {\n \"fullscreen\": false,\n \"height\": 600,\n \"resizable\": true,\n \"title\": \"Tauri App\",\n \"width\": 800\n }\n ]\n },\n \"bundle\": {},\n \"plugins\": {}\n }\n ```", "type": "object", diff --git a/crates/tauri-utils/CHANGELOG.md b/crates/tauri-utils/CHANGELOG.md index 531326454d6f..319527f97ece 100644 --- a/crates/tauri-utils/CHANGELOG.md +++ b/crates/tauri-utils/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## \[2.1.0] + +### New Features + +- [`fabc2f283`](https://www.github.com/tauri-apps/tauri/commit/fabc2f283e38b62c721326e44645d47138418cbc) ([#11485](https://www.github.com/tauri-apps/tauri/pull/11485) by [@39zde](https://www.github.com/tauri-apps/tauri/../../39zde)) Adds a new configuration option `app > security > headers` to define headers that will be added to every http response from tauri to the web view. This doesn't include IPC messages and error responses. +- [`4d545ab3c`](https://www.github.com/tauri-apps/tauri/commit/4d545ab3ca228c8a21b966b709f84a0da2864479) ([#11486](https://www.github.com/tauri-apps/tauri/pull/11486) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Added `Window::set_background_color` and `WindowBuilder::background_color`. +- [`cbc095ec5`](https://www.github.com/tauri-apps/tauri/commit/cbc095ec5fe7de29b5c9265576d4e071ec159c1c) ([#11451](https://www.github.com/tauri-apps/tauri/pull/11451) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `app > windows > devtools` config option and when creating the webview from JS, to enable or disable devtools for a specific webview. +- [`058c0db72`](https://www.github.com/tauri-apps/tauri/commit/058c0db72f43fbe1574d0db654560e693755cd7e) ([#11584](https://www.github.com/tauri-apps/tauri/pull/11584) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `bundle > linux > rpm > compression` config option to control RPM bundle compression type and level. +- [`f37e97d41`](https://www.github.com/tauri-apps/tauri/commit/f37e97d410c4a219e99f97692da05ca9d8e0ba3a) ([#11477](https://www.github.com/tauri-apps/tauri/pull/11477) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `app > windows > useHttpsScheme` config option to choose whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android +- [`2a75c64b5`](https://www.github.com/tauri-apps/tauri/commit/2a75c64b5431284e7340e8743d4ea56a62c75466) ([#11469](https://www.github.com/tauri-apps/tauri/pull/11469) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Added `app > windows > windowClassname` config option to specify the name of the window class on Windows. + +### Enhancements + +- [`c33bbf457`](https://www.github.com/tauri-apps/tauri/commit/c33bbf45740274b6918ea6c647f366fb6008e459) ([#11575](https://www.github.com/tauri-apps/tauri/pull/11575) by [@kornelski](https://www.github.com/tauri-apps/tauri/../../kornelski)) Include the path in ACL I/O errors. + +### Bug Fixes + +- [`378142914`](https://www.github.com/tauri-apps/tauri/commit/37814291475814b4a24cc77b6fa457ec9ba7a779) ([#11429](https://www.github.com/tauri-apps/tauri/pull/11429) by [@griffi-gh](https://www.github.com/tauri-apps/tauri/../../griffi-gh)) Enhance resource directory resolution to support running on distros like NixOS. + ## \[2.0.2] ### New Features diff --git a/crates/tauri-utils/Cargo.toml b/crates/tauri-utils/Cargo.toml index b920ec9e3f70..27a44f5e6646 100644 --- a/crates/tauri-utils/Cargo.toml +++ b/crates/tauri-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tauri-utils" -version = "2.0.2" +version = "2.1.0" description = "Utilities for Tauri" exclude = ["CHANGELOG.md", "/target"] readme = "README.md" diff --git a/crates/tauri/CHANGELOG.md b/crates/tauri/CHANGELOG.md index 28bf12801907..f6a9498d3019 100644 --- a/crates/tauri/CHANGELOG.md +++ b/crates/tauri/CHANGELOG.md @@ -1,5 +1,48 @@ # Changelog +## \[2.1.0] + +### New Features + +- [`fabc2f283`](https://www.github.com/tauri-apps/tauri/commit/fabc2f283e38b62c721326e44645d47138418cbc) ([#11485](https://www.github.com/tauri-apps/tauri/pull/11485) by [@39zde](https://www.github.com/tauri-apps/tauri/../../39zde)) Adds a new configuration option `app > security > headers` to define headers that will be added to every http response from tauri to the web view. This doesn't include IPC messages and error responses. +- [`8036c78e0`](https://www.github.com/tauri-apps/tauri/commit/8036c78e08715b1bc6b9fcb0c59a570eec98014f) ([#11455](https://www.github.com/tauri-apps/tauri/pull/11455) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `PathResolver::home_dir()` method on Android. +- [`5c4b83084`](https://www.github.com/tauri-apps/tauri/commit/5c4b830843ab085f8ff9db9e08d832223b027e4e) ([#11191](https://www.github.com/tauri-apps/tauri/pull/11191) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Improved support for `dpi` module types to allow these types to be used without manual conversions with `invoke`: + + - Added `SERIALIZE_TO_IPC_FN` const in `core` module which can be used to implement custom IPC serialization for types passed to `invoke`. + - Added `Size` and `Position` classes in `dpi` module. + - Implementd `SERIALIZE_TO_IPC_FN` method on `PhysicalSize`, `PhysicalPosition`, `LogicalSize` and `LogicalPosition` to convert it into a valid IPC-compatible value that can be deserialized correctly on the Rust side into its equivalent struct. +- [`4d545ab3c`](https://www.github.com/tauri-apps/tauri/commit/4d545ab3ca228c8a21b966b709f84a0da2864479) ([#11486](https://www.github.com/tauri-apps/tauri/pull/11486) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Added `Window::set_background_color` and `WindowBuilder::background_color`. +- [`cbc095ec5`](https://www.github.com/tauri-apps/tauri/commit/cbc095ec5fe7de29b5c9265576d4e071ec159c1c) ([#11451](https://www.github.com/tauri-apps/tauri/pull/11451) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `app > windows > devtools` config option and when creating the webview from JS, to enable or disable devtools for a specific webview. +- [`f0da0bde8`](https://www.github.com/tauri-apps/tauri/commit/f0da0bde87a80fdca20c588cefcad86e03b9627c) ([#11439](https://www.github.com/tauri-apps/tauri/pull/11439) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Added `WebviewWindow::resolve_command_scope` to check a command scope at runtime. +- [\`\`](https://www.github.com/tauri-apps/tauri/commit/undefined) Detect if `SERIALIZE_TO_IPC_FN`, const from the JS `core` module, is implemented on objects when serializing over IPC and use it. +- [`f37e97d41`](https://www.github.com/tauri-apps/tauri/commit/f37e97d410c4a219e99f97692da05ca9d8e0ba3a) ([#11477](https://www.github.com/tauri-apps/tauri/pull/11477) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `app > windows > useHttpsScheme` config option to choose whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android +- [`f37e97d41`](https://www.github.com/tauri-apps/tauri/commit/f37e97d410c4a219e99f97692da05ca9d8e0ba3a) ([#11477](https://www.github.com/tauri-apps/tauri/pull/11477) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `WebviewWindowBuilder/WebviewBuilder::use_https_scheme` to choose whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android +- [`cbc095ec5`](https://www.github.com/tauri-apps/tauri/commit/cbc095ec5fe7de29b5c9265576d4e071ec159c1c) ([#11451](https://www.github.com/tauri-apps/tauri/pull/11451) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `WebviewWindowBuilder::devtools` and `WebviewBuilder::devtools` to enable or disable devtools for a specific webview. +- [`129414faa`](https://www.github.com/tauri-apps/tauri/commit/129414faa4e027c9035d56614682cacc0335a6a0) ([#11569](https://www.github.com/tauri-apps/tauri/pull/11569) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `WebviewBuilder::focused` method to choose whether to focus webview or not on creation. +- [`2a75c64b5`](https://www.github.com/tauri-apps/tauri/commit/2a75c64b5431284e7340e8743d4ea56a62c75466) ([#11469](https://www.github.com/tauri-apps/tauri/pull/11469) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Added `app > windows > windowClassname` config option to specify the name of the window class on Windows. +- [`2a75c64b5`](https://www.github.com/tauri-apps/tauri/commit/2a75c64b5431284e7340e8743d4ea56a62c75466) ([#11469](https://www.github.com/tauri-apps/tauri/pull/11469) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Added `WindowBuilder/WebviewWindowBuilder::window_classname` method to specify the name of the window class on Windows. + +### Enhancements + +- [`17c6952ae`](https://www.github.com/tauri-apps/tauri/commit/17c6952aec965fa41e6695ad68461a218afc20f1) ([#11522](https://www.github.com/tauri-apps/tauri/pull/11522) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Enhance the error message when using `async` commands with a reference. +- [`c33bbf457`](https://www.github.com/tauri-apps/tauri/commit/c33bbf45740274b6918ea6c647f366fb6008e459) ([#11575](https://www.github.com/tauri-apps/tauri/pull/11575) by [@kornelski](https://www.github.com/tauri-apps/tauri/../../kornelski)) Include the path in ACL I/O errors. + +### Bug Fixes + +- [`229d7f8e2`](https://www.github.com/tauri-apps/tauri/commit/229d7f8e220cc8d5ca06eff1ed85cb7d047c1d6c) ([#11616](https://www.github.com/tauri-apps/tauri/pull/11616) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix regression in creating child webviews on macOS and Windows, covering the whole window. +- [`8c6d1e8e6`](https://www.github.com/tauri-apps/tauri/commit/8c6d1e8e6c852667bb223b5f4823948868c26d98) ([#11401](https://www.github.com/tauri-apps/tauri/pull/11401) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix `App/AppHandle/Window/Webview/WebviewWindow::cursor_position` getter method failing on Linux with `GDK may only be used from the main thread`. +- [`f8994b214`](https://www.github.com/tauri-apps/tauri/commit/f8994b214e89acc99ab5ce8dcca8485f43a62dbb) ([#11581](https://www.github.com/tauri-apps/tauri/pull/11581) by [@Mikkel-T](https://www.github.com/tauri-apps/tauri/../../Mikkel-T)) Fix listeners created with `EventTarget::AnyLabel` never receiving events. +- [`4191a7a53`](https://www.github.com/tauri-apps/tauri/commit/4191a7a53d941b179780a550638f1b4a09d17fd1) ([#11583](https://www.github.com/tauri-apps/tauri/pull/11583) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix tray events not fired for tray icons created inside an async command. +- [`129414faa`](https://www.github.com/tauri-apps/tauri/commit/129414faa4e027c9035d56614682cacc0335a6a0) ([#11569](https://www.github.com/tauri-apps/tauri/pull/11569) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix webview not focused by default. + +### Dependencies + +- Upgraded to `tauri-utils@2.1.0` +- Upgraded to `tauri-runtime@2.2.0` +- Upgraded to `tauri-runtime-wry@2.2.0` +- Upgraded to `tauri-macros@2.0.3` +- Upgraded to `tauri-build@2.0.3` + ## \[2.0.6] ### Dependencies diff --git a/crates/tauri/Cargo.toml b/crates/tauri/Cargo.toml index 36610576fa0f..90ac32a8ea1b 100644 --- a/crates/tauri/Cargo.toml +++ b/crates/tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tauri" -version = "2.0.6" +version = "2.1.0" description = "Make tiny, secure apps for all desktop platforms with Tauri" exclude = ["/test", "/.scripts", "CHANGELOG.md", "/target"] readme = "README.md" @@ -57,12 +57,12 @@ uuid = { version = "1", features = ["v4"], optional = true } url = "2" anyhow = "1.0" thiserror = "2" -tauri-runtime = { version = "2.1.1", path = "../tauri-runtime" } -tauri-macros = { version = "2.0.2", path = "../tauri-macros" } -tauri-utils = { version = "2.0.2", features = [ +tauri-runtime = { version = "2.2.0", path = "../tauri-runtime" } +tauri-macros = { version = "2.0.3", path = "../tauri-macros" } +tauri-utils = { version = "2.1.0", features = [ "resources", ], path = "../tauri-utils" } -tauri-runtime-wry = { version = "2.1.2", path = "../tauri-runtime-wry", optional = true } +tauri-runtime-wry = { version = "2.2.0", path = "../tauri-runtime-wry", optional = true } getrandom = "0.2" serde_repr = "0.1" http = "1.1" @@ -134,8 +134,8 @@ swift-rs = "1.0.7" [build-dependencies] heck = "0.5" -tauri-build = { path = "../tauri-build/", default-features = false, version = "2.0.2" } -tauri-utils = { path = "../tauri-utils/", version = "2.0.2", features = [ +tauri-build = { path = "../tauri-build/", default-features = false, version = "2.0.3" } +tauri-utils = { path = "../tauri-utils/", version = "2.1.0", features = [ "build", ] } diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md index 7a551431760f..58be499f7120 100644 --- a/packages/api/CHANGELOG.md +++ b/packages/api/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## \[2.1.0] + +### New Features + +- [`5c4b83084`](https://www.github.com/tauri-apps/tauri/commit/5c4b830843ab085f8ff9db9e08d832223b027e4e) ([#11191](https://www.github.com/tauri-apps/tauri/pull/11191) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Improved support for `dpi` module types to allow these types to be used without manual conversions with `invoke`: + + - Added `SERIALIZE_TO_IPC_FN` const in `core` module which can be used to implement custom IPC serialization for types passed to `invoke`. + - Added `Size` and `Position` classes in `dpi` module. + - Implementd `SERIALIZE_TO_IPC_FN` method on `PhysicalSize`, `PhysicalPosition`, `LogicalSize` and `LogicalPosition` to convert it into a valid IPC-compatible value that can be deserialized correctly on the Rust side into its equivalent struct. +- [`4d545ab3c`](https://www.github.com/tauri-apps/tauri/commit/4d545ab3ca228c8a21b966b709f84a0da2864479) ([#11486](https://www.github.com/tauri-apps/tauri/pull/11486) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Added `Webview::setBackgroundColor`, `WebviewWindow::setBackgroundColor` APIs to set the window background color dynamically + and a `backgroundColor` window option to set the background color on window creation. +- [`cbc095ec5`](https://www.github.com/tauri-apps/tauri/commit/cbc095ec5fe7de29b5c9265576d4e071ec159c1c) ([#11451](https://www.github.com/tauri-apps/tauri/pull/11451) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `app > windows > devtools` config option and when creating the webview from JS, to enable or disable devtools for a specific webview. +- [`2a75c64b5`](https://www.github.com/tauri-apps/tauri/commit/2a75c64b5431284e7340e8743d4ea56a62c75466) ([#11469](https://www.github.com/tauri-apps/tauri/pull/11469) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Added `windowClassname` option, when constructing a `Webview` or `WebviewWindow`, to specify the name of the window class on Windows. + +### Bug Fixes + +- [`54cbf59b5`](https://www.github.com/tauri-apps/tauri/commit/54cbf59b5a572570a47237a3b5e6505f2a9e5d5d) ([#11441](https://www.github.com/tauri-apps/tauri/pull/11441) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix submenu created as a menu item instead of a submenu when created by using an object in the `items` field in the options object passed to `Menu.new` or `Submenu.new`. + ## \[2.0.3] ### Bug Fixes diff --git a/packages/api/package.json b/packages/api/package.json index 2c5ff093c80f..8b696dd4019e 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@tauri-apps/api", - "version": "2.0.3", + "version": "2.1.0", "description": "Tauri API definitions", "funding": { "type": "opencollective", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 1a0b196ccec2..48a57a427eaf 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,28 @@ # Changelog +## \[2.1.0] + +### New Features + +- [`6bf917941`](https://www.github.com/tauri-apps/tauri/commit/6bf917941ff0fcc49e86b3ba427340b75f3ce49c) ([#11322](https://www.github.com/tauri-apps/tauri/pull/11322) by [@ShaunSHamilton](https://www.github.com/tauri-apps/tauri/../../ShaunSHamilton)) Add `tauri remove` to remove plugins from projects. +- [`058c0db72`](https://www.github.com/tauri-apps/tauri/commit/058c0db72f43fbe1574d0db654560e693755cd7e) ([#11584](https://www.github.com/tauri-apps/tauri/pull/11584) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `bundle > linux > rpm > compression` config option to control RPM bundle compression type and level. + +### Enhancements + +- [`1f311832a`](https://www.github.com/tauri-apps/tauri/commit/1f311832ab5b2d62a533dfcf9b1d78bddf249ae8) ([#11405](https://www.github.com/tauri-apps/tauri/pull/11405) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add more context for errors when decoding secret and public keys for signing updater artifacts. +- [`e0d1307d3`](https://www.github.com/tauri-apps/tauri/commit/e0d1307d3f78987d0059921a5ab01ea4b26e0ef1) ([#11414](https://www.github.com/tauri-apps/tauri/pull/11414) by [@Czxck001](https://www.github.com/tauri-apps/tauri/../../Czxck001)) Migrate the `$schema` Tauri configuration to the v2 format. +- [`c43d5df15`](https://www.github.com/tauri-apps/tauri/commit/c43d5df15828ecffa606482ea2b60350c488c981) ([#11512](https://www.github.com/tauri-apps/tauri/pull/11512) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Associate a newly created capability file with the `main` window on the `tauri add` and `tauri permission add` commands. + +### Bug Fixes + +- [`7af01ff2c`](https://www.github.com/tauri-apps/tauri/commit/7af01ff2ce623d727cd13a4c8a549c1c80031882) ([#11523](https://www.github.com/tauri-apps/tauri/pull/11523) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix `tauri migrate` failing to install NPM depenencies when running from Deno. +- [`100a4455a`](https://www.github.com/tauri-apps/tauri/commit/100a4455aa48df508510bbc08273215bdf70c012) ([#11529](https://www.github.com/tauri-apps/tauri/pull/11529) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix detecting yarn berry (v2 and higher) in various tauri cli commands. +- [`60e86d5f6`](https://www.github.com/tauri-apps/tauri/commit/60e86d5f6e0f0c769d34ef368cd8801a918d796d) ([#11624](https://www.github.com/tauri-apps/tauri/pull/11624) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Use the public network IP address on `android dev` by default on Windows. + +### Dependencies + +- Upgraded to `tauri-cli@2.1.0` + ## \[2.0.4] ### Enhancements diff --git a/packages/cli/package.json b/packages/cli/package.json index 7a68df5a3d67..14fe412a091b 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@tauri-apps/cli", - "version": "2.0.4", + "version": "2.1.0", "description": "Command line interface for building Tauri apps", "funding": { "type": "opencollective", From 0fcef3f94142cd56509c91371d6eb81c095bc6a4 Mon Sep 17 00:00:00 2001 From: Kornel Date: Mon, 11 Nov 2024 12:21:08 +0000 Subject: [PATCH 40/51] docs: document vanilla JS import alternative (#11632) --- packages/api/src/index.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index 11ddc5e4670f..03639e81c688 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -10,6 +10,16 @@ * ```typescript * import { event, window, path } from '@tauri-apps/api' * ``` + * + * ### Vanilla JS API + * + * The above import syntax is for JavaScript/TypeScript with a bundler. If you're using vanilla JavaScript, you can use the global `window.__TAURI__` object instead. It requires `app.withGlobalTauri` configuration option enabled. + * + * @example + * ```js + * const { event, window: tauriWindow, path } = window.__TAURI__; + * ``` + * * @module */ From 5e9435487544752b890a835b0b788802688bf62d Mon Sep 17 00:00:00 2001 From: Daniel Gerhardt Date: Mon, 11 Nov 2024 13:21:25 +0100 Subject: [PATCH 41/51] fix(api/dpi): fix toLogical and toPhysical for positions (#11639) --- .changes/dpi-to-logical/physical-regression.md | 5 +++++ crates/tauri/scripts/bundle.global.js | 2 +- packages/api/src/dpi.ts | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changes/dpi-to-logical/physical-regression.md diff --git a/.changes/dpi-to-logical/physical-regression.md b/.changes/dpi-to-logical/physical-regression.md new file mode 100644 index 000000000000..fc37ef177d48 --- /dev/null +++ b/.changes/dpi-to-logical/physical-regression.md @@ -0,0 +1,5 @@ +--- +"@tauri-apps/api": patch:bug +--- + +Fix regression in `toLogical` and `toPhysical` for position types in `dpi` module returning incorrect `y` value. diff --git a/crates/tauri/scripts/bundle.global.js b/crates/tauri/scripts/bundle.global.js index 760a790a1605..54446b68ba6d 100644 --- a/crates/tauri/scripts/bundle.global.js +++ b/crates/tauri/scripts/bundle.global.js @@ -1 +1 @@ -var __TAURI_IIFE__=function(e){"use strict";function n(e,n,t,i){if("a"===t&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof n?e!==n||!i:!n.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===t?i:"a"===t?i.call(e):i?i.value:n.get(e)}function t(e,n,t,i,r){if("m"===i)throw new TypeError("Private method is not writable");if("a"===i&&!r)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof n?e!==n||!r:!n.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===i?r.call(e,t):r?r.value=t:n.set(e,t),t}var i,r,s,a;"function"==typeof SuppressedError&&SuppressedError;const l="__TAURI_TO_IPC_KEY__";function o(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}class u{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),r.set(this,0),s.set(this,{}),this.id=o((({message:e,id:a})=>{if(a===n(this,r,"f")){t(this,r,a+1,"f"),n(this,i,"f").call(this,e);const l=Object.keys(n(this,s,"f"));if(l.length>0){let e=a+1;for(const t of l.sort()){if(parseInt(t)!==e)break;{const r=n(this,s,"f")[t];delete n(this,s,"f")[t],n(this,i,"f").call(this,r),e+=1}}t(this,r,e,"f")}}else n(this,s,"f")[a.toString()]=e}))}set onmessage(e){t(this,i,e,"f")}get onmessage(){return n(this,i,"f")}[(i=new WeakMap,r=new WeakMap,s=new WeakMap,l)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[l]()}}class c{constructor(e,n,t){this.plugin=e,this.event=n,this.channelId=t}async unregister(){return d(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}}async function d(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}class h{get rid(){return n(this,a,"f")}constructor(e){a.set(this,void 0),t(this,a,e,"f")}async close(){return d("plugin:resources|close",{rid:this.rid})}}a=new WeakMap;var p=Object.freeze({__proto__:null,Channel:u,PluginListener:c,Resource:h,SERIALIZE_TO_IPC_FN:l,addPluginListener:async function(e,n,t){const i=new u;return i.onmessage=t,d(`plugin:${e}|registerListener`,{event:n,handler:i}).then((()=>new c(e,n,i.id)))},checkPermissions:async function(e){return d(`plugin:${e}|check_permissions`)},convertFileSrc:function(e,n="asset"){return window.__TAURI_INTERNALS__.convertFileSrc(e,n)},invoke:d,isTauri:function(){return"isTauri"in window&&!!window.isTauri},requestPermissions:async function(e){return d(`plugin:${e}|request_permissions`)},transformCallback:o});class w extends h{constructor(e){super(e)}static async new(e,n,t){return d("plugin:image|new",{rgba:y(e),width:n,height:t}).then((e=>new w(e)))}static async fromBytes(e){return d("plugin:image|from_bytes",{bytes:y(e)}).then((e=>new w(e)))}static async fromPath(e){return d("plugin:image|from_path",{path:e}).then((e=>new w(e)))}async rgba(){return d("plugin:image|rgba",{rid:this.rid}).then((e=>new Uint8Array(e)))}async size(){return d("plugin:image|size",{rid:this.rid})}}function y(e){return null==e?null:"string"==typeof e?e:e instanceof w?e.rid:e}var _=Object.freeze({__proto__:null,Image:w,transformImage:y});var g=Object.freeze({__proto__:null,defaultWindowIcon:async function(){return d("plugin:app|default_window_icon").then((e=>e?new w(e):null))},getName:async function(){return d("plugin:app|name")},getTauriVersion:async function(){return d("plugin:app|tauri_version")},getVersion:async function(){return d("plugin:app|version")},hide:async function(){return d("plugin:app|app_hide")},setTheme:async function(e){return d("plugin:app|set_app_theme",{theme:e})},show:async function(){return d("plugin:app|app_show")}});class b{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.width=e[0].Logical.width,this.height=e[0].Logical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toPhysical(e){return new m(this.width*e,this.height*e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class m{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.width=e[0].Physical.width,this.height=e[0].Physical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toLogical(e){return new b(this.width/e,this.height/e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class v{constructor(e){this.size=e}toLogical(e){return this.size instanceof b?this.size:this.size.toLogical(e)}toPhysical(e){return this.size instanceof m?this.size:this.size.toPhysical(e)}[l](){return{[`${this.size.type}`]:{width:this.size.width,height:this.size.height}}}toJSON(){return this[l]()}}class f{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.x=e[0].Logical.x,this.y=e[0].Logical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toPhysical(e){return new k(this.x*e,this.x*e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class k{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.x=e[0].Physical.x,this.y=e[0].Physical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toLogical(e){return new f(this.x/e,this.x/e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class A{constructor(e){this.position=e}toLogical(e){return this.position instanceof f?this.position:this.position.toLogical(e)}toPhysical(e){return this.position instanceof k?this.position:this.position.toPhysical(e)}[l](){return{[`${this.position.type}`]:{x:this.position.x,y:this.position.y}}}toJSON(){return this[l]()}}var E,T=Object.freeze({__proto__:null,LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,Position:A,Size:v});async function D(e,n){await d("plugin:event|unlisten",{event:e,eventId:n})}async function I(e,n,t){var i;const r="string"==typeof(null==t?void 0:t.target)?{kind:"AnyLabel",label:t.target}:null!==(i=null==t?void 0:t.target)&&void 0!==i?i:{kind:"Any"};return d("plugin:event|listen",{event:e,target:r,handler:o(n)}).then((n=>async()=>D(e,n)))}async function R(e,n,t){return I(e,(t=>{D(e,t.id),n(t)}),t)}async function S(e,n){await d("plugin:event|emit",{event:e,payload:n})}async function L(e,n,t){const i="string"==typeof e?{kind:"AnyLabel",label:e}:e;await d("plugin:event|emit_to",{target:i,event:n,payload:t})}!function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG_ENTER="tauri://drag-enter",e.DRAG_OVER="tauri://drag-over",e.DRAG_DROP="tauri://drag-drop",e.DRAG_LEAVE="tauri://drag-leave"}(E||(E={}));var x,C,N,P=Object.freeze({__proto__:null,get TauriEvent(){return E},emit:S,emitTo:L,listen:I,once:R});function z(e){var n;if("items"in e)e.items=null===(n=e.items)||void 0===n?void 0:n.map((e=>"rid"in e?e:z(e)));else if("action"in e&&e.action){const n=new u;return n.onmessage=e.action,delete e.action,{...e,handler:n}}return e}async function W(e,n){const t=new u;if(n&&"object"==typeof n&&("action"in n&&n.action&&(t.onmessage=n.action,delete n.action),"items"in n&&n.items)){function i(e){var n;return"rid"in e?[e.rid,e.kind]:("item"in e&&"object"==typeof e.item&&(null===(n=e.item.About)||void 0===n?void 0:n.icon)&&(e.item.About.icon=y(e.item.About.icon)),"icon"in e&&e.icon&&(e.icon=y(e.icon)),"items"in e&&e.items&&(e.items=e.items.map(i)),z(e))}n.items=n.items.map(i)}return d("plugin:menu|new",{kind:e,options:n,handler:t})}class O extends h{get id(){return n(this,x,"f")}get kind(){return n(this,C,"f")}constructor(e,n,i){super(e),x.set(this,void 0),C.set(this,void 0),t(this,x,n,"f"),t(this,C,i,"f")}}x=new WeakMap,C=new WeakMap;class F extends O{constructor(e,n){super(e,n,"MenuItem")}static async new(e){return W("MenuItem",e).then((([e,n])=>new F(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}}class M extends O{constructor(e,n){super(e,n,"Check")}static async new(e){return W("Check",e).then((([e,n])=>new M(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async isChecked(){return d("plugin:menu|is_checked",{rid:this.rid})}async setChecked(e){return d("plugin:menu|set_checked",{rid:this.rid,checked:e})}}!function(e){e.Add="Add",e.Advanced="Advanced",e.Bluetooth="Bluetooth",e.Bookmarks="Bookmarks",e.Caution="Caution",e.ColorPanel="ColorPanel",e.ColumnView="ColumnView",e.Computer="Computer",e.EnterFullScreen="EnterFullScreen",e.Everyone="Everyone",e.ExitFullScreen="ExitFullScreen",e.FlowView="FlowView",e.Folder="Folder",e.FolderBurnable="FolderBurnable",e.FolderSmart="FolderSmart",e.FollowLinkFreestanding="FollowLinkFreestanding",e.FontPanel="FontPanel",e.GoLeft="GoLeft",e.GoRight="GoRight",e.Home="Home",e.IChatTheater="IChatTheater",e.IconView="IconView",e.Info="Info",e.InvalidDataFreestanding="InvalidDataFreestanding",e.LeftFacingTriangle="LeftFacingTriangle",e.ListView="ListView",e.LockLocked="LockLocked",e.LockUnlocked="LockUnlocked",e.MenuMixedState="MenuMixedState",e.MenuOnState="MenuOnState",e.MobileMe="MobileMe",e.MultipleDocuments="MultipleDocuments",e.Network="Network",e.Path="Path",e.PreferencesGeneral="PreferencesGeneral",e.QuickLook="QuickLook",e.RefreshFreestanding="RefreshFreestanding",e.Refresh="Refresh",e.Remove="Remove",e.RevealFreestanding="RevealFreestanding",e.RightFacingTriangle="RightFacingTriangle",e.Share="Share",e.Slideshow="Slideshow",e.SmartBadge="SmartBadge",e.StatusAvailable="StatusAvailable",e.StatusNone="StatusNone",e.StatusPartiallyAvailable="StatusPartiallyAvailable",e.StatusUnavailable="StatusUnavailable",e.StopProgressFreestanding="StopProgressFreestanding",e.StopProgress="StopProgress",e.TrashEmpty="TrashEmpty",e.TrashFull="TrashFull",e.User="User",e.UserAccounts="UserAccounts",e.UserGroup="UserGroup",e.UserGuest="UserGuest"}(N||(N={}));class U extends O{constructor(e,n){super(e,n,"Icon")}static async new(e){return W("Icon",e).then((([e,n])=>new U(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async setIcon(e){return d("plugin:menu|set_icon",{rid:this.rid,icon:y(e)})}}class B extends O{constructor(e,n){super(e,n,"Predefined")}static async new(e){return W("Predefined",e).then((([e,n])=>new B(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}}function j([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class V extends O{constructor(e,n){super(e,n,"Submenu")}static async new(e){return W("Submenu",e).then((([e,n])=>new V(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(j)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(j)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?j(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsWindowsMenuForNSApp(){return d("plugin:menu|set_as_windows_menu_for_nsapp",{rid:this.rid})}async setAsHelpMenuForNSApp(){return d("plugin:menu|set_as_help_menu_for_nsapp",{rid:this.rid})}}function G([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class H extends O{constructor(e,n){super(e,n,"Menu")}static async new(e){return W("Menu",e).then((([e,n])=>new H(e,n)))}static async default(){return d("plugin:menu|create_default").then((([e,n])=>new H(e,n)))}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(G)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(G)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?G(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsAppMenu(){return d("plugin:menu|set_as_app_menu",{rid:this.rid}).then((e=>e?new H(e[0],e[1]):null))}async setAsWindowMenu(e){var n;return d("plugin:menu|set_as_window_menu",{rid:this.rid,window:null!==(n=null==e?void 0:e.label)&&void 0!==n?n:null}).then((e=>e?new H(e[0],e[1]):null))}}var $=Object.freeze({__proto__:null,CheckMenuItem:M,IconMenuItem:U,Menu:H,MenuItem:F,get NativeIcon(){return N},PredefinedMenuItem:B,Submenu:V});function q(){var e;window.__TAURI_INTERNALS__=null!==(e=window.__TAURI_INTERNALS__)&&void 0!==e?e:{}}var J,Q=Object.freeze({__proto__:null,clearMocks:function(){var e,n,t;"object"==typeof window.__TAURI_INTERNALS__&&((null===(e=window.__TAURI_INTERNALS__)||void 0===e?void 0:e.convertFileSrc)&&delete window.__TAURI_INTERNALS__.convertFileSrc,(null===(n=window.__TAURI_INTERNALS__)||void 0===n?void 0:n.invoke)&&delete window.__TAURI_INTERNALS__.invoke,(null===(t=window.__TAURI_INTERNALS__)||void 0===t?void 0:t.metadata)&&delete window.__TAURI_INTERNALS__.metadata)},mockConvertFileSrc:function(e){q(),window.__TAURI_INTERNALS__.convertFileSrc=function(n,t="asset"){const i=encodeURIComponent(n);return"windows"===e?`http://${t}.localhost/${i}`:`${t}://localhost/${i}`}},mockIPC:function(e){q(),window.__TAURI_INTERNALS__.transformCallback=function(e,n=!1){const t=window.crypto.getRandomValues(new Uint32Array(1))[0],i=`_${t}`;return Object.defineProperty(window,i,{value:t=>(n&&Reflect.deleteProperty(window,i),e&&e(t)),writable:!1,configurable:!0}),t},window.__TAURI_INTERNALS__.invoke=function(n,t,i){return e(n,t)}},mockWindows:function(e,...n){q(),window.__TAURI_INTERNALS__.metadata={currentWindow:{label:e},currentWebview:{windowLabel:e,label:e}}}});!function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Document=6]="Document",e[e.Download=7]="Download",e[e.Picture=8]="Picture",e[e.Public=9]="Public",e[e.Video=10]="Video",e[e.Resource=11]="Resource",e[e.Temp=12]="Temp",e[e.AppConfig=13]="AppConfig",e[e.AppData=14]="AppData",e[e.AppLocalData=15]="AppLocalData",e[e.AppCache=16]="AppCache",e[e.AppLog=17]="AppLog",e[e.Desktop=18]="Desktop",e[e.Executable=19]="Executable",e[e.Font=20]="Font",e[e.Home=21]="Home",e[e.Runtime=22]="Runtime",e[e.Template=23]="Template"}(J||(J={}));var Z=Object.freeze({__proto__:null,get BaseDirectory(){return J},appCacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppCache})},appConfigDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppConfig})},appDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppData})},appLocalDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLocalData})},appLogDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLog})},audioDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Audio})},basename:async function(e,n){return d("plugin:path|basename",{path:e,ext:n})},cacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Cache})},configDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Config})},dataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Data})},delimiter:function(){return window.__TAURI_INTERNALS__.plugins.path.delimiter},desktopDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Desktop})},dirname:async function(e){return d("plugin:path|dirname",{path:e})},documentDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Document})},downloadDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Download})},executableDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Executable})},extname:async function(e){return d("plugin:path|extname",{path:e})},fontDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Font})},homeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Home})},isAbsolute:async function(e){return d("plugin:path|isAbsolute",{path:e})},join:async function(...e){return d("plugin:path|join",{paths:e})},localDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.LocalData})},normalize:async function(e){return d("plugin:path|normalize",{path:e})},pictureDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Picture})},publicDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Public})},resolve:async function(...e){return d("plugin:path|resolve",{paths:e})},resolveResource:async function(e){return d("plugin:path|resolve_directory",{directory:J.Resource,path:e})},resourceDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Resource})},runtimeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Runtime})},sep:function(){return window.__TAURI_INTERNALS__.plugins.path.sep},tempDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Temp})},templateDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Template})},videoDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Video})}});class K extends h{constructor(e,n){super(e),this.id=n}static async getById(e){return d("plugin:tray|get_by_id",{id:e}).then((n=>n?new K(n,e):null))}static async removeById(e){return d("plugin:tray|remove_by_id",{id:e})}static async new(e){(null==e?void 0:e.menu)&&(e.menu=[e.menu.rid,e.menu.kind]),(null==e?void 0:e.icon)&&(e.icon=y(e.icon));const n=new u;if(null==e?void 0:e.action){const t=e.action;n.onmessage=e=>t(function(e){const n=e;return n.position=new k(e.position),n.rect.position=new k(e.rect.position),n.rect.size=new m(e.rect.size),n}(e)),delete e.action}return d("plugin:tray|new",{options:null!=e?e:{},handler:n}).then((([e,n])=>new K(e,n)))}async setIcon(e){let n=null;return e&&(n=y(e)),d("plugin:tray|set_icon",{rid:this.rid,icon:n})}async setMenu(e){return e&&(e=[e.rid,e.kind]),d("plugin:tray|set_menu",{rid:this.rid,menu:e})}async setTooltip(e){return d("plugin:tray|set_tooltip",{rid:this.rid,tooltip:e})}async setTitle(e){return d("plugin:tray|set_title",{rid:this.rid,title:e})}async setVisible(e){return d("plugin:tray|set_visible",{rid:this.rid,visible:e})}async setTempDirPath(e){return d("plugin:tray|set_temp_dir_path",{rid:this.rid,path:e})}async setIconAsTemplate(e){return d("plugin:tray|set_icon_as_template",{rid:this.rid,asTemplate:e})}async setMenuOnLeftClick(e){return d("plugin:tray|set_show_menu_on_left_click",{rid:this.rid,onLeft:e})}}var Y,X,ee=Object.freeze({__proto__:null,TrayIcon:K});!function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"}(Y||(Y={}));class ne{constructor(e){this._preventDefault=!1,this.event=e.event,this.id=e.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}function te(){return new se(window.__TAURI_INTERNALS__.metadata.currentWindow.label,{skip:!0})}async function ie(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new se(e,{skip:!0})))))}!function(e){e.None="none",e.Normal="normal",e.Indeterminate="indeterminate",e.Paused="paused",e.Error="error"}(X||(X={}));const re=["tauri://created","tauri://error"];class se{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:window|create",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await ie()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return te()}static async getAll(){return ie()}static async getFocusedWindow(){for(const e of await ie())if(await e.isFocused())return e;return null}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Window",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Window",label:this.label}})}async emit(e,n){if(!re.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!re.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!re.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async scaleFactor(){return d("plugin:window|scale_factor",{label:this.label})}async innerPosition(){return d("plugin:window|inner_position",{label:this.label}).then((e=>new k(e)))}async outerPosition(){return d("plugin:window|outer_position",{label:this.label}).then((e=>new k(e)))}async innerSize(){return d("plugin:window|inner_size",{label:this.label}).then((e=>new m(e)))}async outerSize(){return d("plugin:window|outer_size",{label:this.label}).then((e=>new m(e)))}async isFullscreen(){return d("plugin:window|is_fullscreen",{label:this.label})}async isMinimized(){return d("plugin:window|is_minimized",{label:this.label})}async isMaximized(){return d("plugin:window|is_maximized",{label:this.label})}async isFocused(){return d("plugin:window|is_focused",{label:this.label})}async isDecorated(){return d("plugin:window|is_decorated",{label:this.label})}async isResizable(){return d("plugin:window|is_resizable",{label:this.label})}async isMaximizable(){return d("plugin:window|is_maximizable",{label:this.label})}async isMinimizable(){return d("plugin:window|is_minimizable",{label:this.label})}async isClosable(){return d("plugin:window|is_closable",{label:this.label})}async isVisible(){return d("plugin:window|is_visible",{label:this.label})}async title(){return d("plugin:window|title",{label:this.label})}async theme(){return d("plugin:window|theme",{label:this.label})}async center(){return d("plugin:window|center",{label:this.label})}async requestUserAttention(e){let n=null;return e&&(n=e===Y.Critical?{type:"Critical"}:{type:"Informational"}),d("plugin:window|request_user_attention",{label:this.label,value:n})}async setResizable(e){return d("plugin:window|set_resizable",{label:this.label,value:e})}async setEnabled(e){return d("plugin:window|set_enabled",{label:this.label,value:e})}async isEnabled(){return d("plugin:window|is_enabled",{label:this.label})}async setMaximizable(e){return d("plugin:window|set_maximizable",{label:this.label,value:e})}async setMinimizable(e){return d("plugin:window|set_minimizable",{label:this.label,value:e})}async setClosable(e){return d("plugin:window|set_closable",{label:this.label,value:e})}async setTitle(e){return d("plugin:window|set_title",{label:this.label,value:e})}async maximize(){return d("plugin:window|maximize",{label:this.label})}async unmaximize(){return d("plugin:window|unmaximize",{label:this.label})}async toggleMaximize(){return d("plugin:window|toggle_maximize",{label:this.label})}async minimize(){return d("plugin:window|minimize",{label:this.label})}async unminimize(){return d("plugin:window|unminimize",{label:this.label})}async show(){return d("plugin:window|show",{label:this.label})}async hide(){return d("plugin:window|hide",{label:this.label})}async close(){return d("plugin:window|close",{label:this.label})}async destroy(){return d("plugin:window|destroy",{label:this.label})}async setDecorations(e){return d("plugin:window|set_decorations",{label:this.label,value:e})}async setShadow(e){return d("plugin:window|set_shadow",{label:this.label,value:e})}async setEffects(e){return d("plugin:window|set_effects",{label:this.label,value:e})}async clearEffects(){return d("plugin:window|set_effects",{label:this.label,value:null})}async setAlwaysOnTop(e){return d("plugin:window|set_always_on_top",{label:this.label,value:e})}async setAlwaysOnBottom(e){return d("plugin:window|set_always_on_bottom",{label:this.label,value:e})}async setContentProtected(e){return d("plugin:window|set_content_protected",{label:this.label,value:e})}async setSize(e){return d("plugin:window|set_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setMinSize(e){return d("plugin:window|set_min_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setMaxSize(e){return d("plugin:window|set_max_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setSizeConstraints(e){function n(e){return e?{Logical:e}:null}return d("plugin:window|set_size_constraints",{label:this.label,value:{minWidth:n(null==e?void 0:e.minWidth),minHeight:n(null==e?void 0:e.minHeight),maxWidth:n(null==e?void 0:e.maxWidth),maxHeight:n(null==e?void 0:e.maxHeight)}})}async setPosition(e){return d("plugin:window|set_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFullscreen(e){return d("plugin:window|set_fullscreen",{label:this.label,value:e})}async setFocus(){return d("plugin:window|set_focus",{label:this.label})}async setIcon(e){return d("plugin:window|set_icon",{label:this.label,value:y(e)})}async setSkipTaskbar(e){return d("plugin:window|set_skip_taskbar",{label:this.label,value:e})}async setCursorGrab(e){return d("plugin:window|set_cursor_grab",{label:this.label,value:e})}async setCursorVisible(e){return d("plugin:window|set_cursor_visible",{label:this.label,value:e})}async setCursorIcon(e){return d("plugin:window|set_cursor_icon",{label:this.label,value:e})}async setBackgroundColor(e){return d("plugin:window|set_background_color",{color:e})}async setCursorPosition(e){return d("plugin:window|set_cursor_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setIgnoreCursorEvents(e){return d("plugin:window|set_ignore_cursor_events",{label:this.label,value:e})}async startDragging(){return d("plugin:window|start_dragging",{label:this.label})}async startResizeDragging(e){return d("plugin:window|start_resize_dragging",{label:this.label,value:e})}async setProgressBar(e){return d("plugin:window|set_progress_bar",{label:this.label,value:e})}async setVisibleOnAllWorkspaces(e){return d("plugin:window|set_visible_on_all_workspaces",{label:this.label,value:e})}async setTitleBarStyle(e){return d("plugin:window|set_title_bar_style",{label:this.label,value:e})}async setTheme(e){return d("plugin:window|set_theme",{label:this.label,value:e})}async onResized(e){return this.listen(E.WINDOW_RESIZED,(n=>{n.payload=new m(n.payload),e(n)}))}async onMoved(e){return this.listen(E.WINDOW_MOVED,(n=>{n.payload=new k(n.payload),e(n)}))}async onCloseRequested(e){return this.listen(E.WINDOW_CLOSE_REQUESTED,(async n=>{const t=new ne(n);await e(t),t.isPreventDefault()||await this.destroy()}))}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}async onFocusChanged(e){const n=await this.listen(E.WINDOW_FOCUS,(n=>{e({...n,payload:!0})})),t=await this.listen(E.WINDOW_BLUR,(n=>{e({...n,payload:!1})}));return()=>{n(),t()}}async onScaleChanged(e){return this.listen(E.WINDOW_SCALE_FACTOR_CHANGED,e)}async onThemeChanged(e){return this.listen(E.WINDOW_THEME_CHANGED,e)}}var ae,le;function oe(e){return null===e?null:{name:e.name,scaleFactor:e.scaleFactor,position:new k(e.position),size:new m(e.size)}}!function(e){e.AppearanceBased="appearanceBased",e.Light="light",e.Dark="dark",e.MediumLight="mediumLight",e.UltraDark="ultraDark",e.Titlebar="titlebar",e.Selection="selection",e.Menu="menu",e.Popover="popover",e.Sidebar="sidebar",e.HeaderView="headerView",e.Sheet="sheet",e.WindowBackground="windowBackground",e.HudWindow="hudWindow",e.FullScreenUI="fullScreenUI",e.Tooltip="tooltip",e.ContentBackground="contentBackground",e.UnderWindowBackground="underWindowBackground",e.UnderPageBackground="underPageBackground",e.Mica="mica",e.Blur="blur",e.Acrylic="acrylic",e.Tabbed="tabbed",e.TabbedDark="tabbedDark",e.TabbedLight="tabbedLight"}(ae||(ae={})),function(e){e.FollowsWindowActiveState="followsWindowActiveState",e.Active="active",e.Inactive="inactive"}(le||(le={}));var ue=Object.freeze({__proto__:null,CloseRequestedEvent:ne,get Effect(){return ae},get EffectState(){return le},LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,get ProgressBarStatus(){return X},get UserAttentionType(){return Y},Window:se,availableMonitors:async function(){return d("plugin:window|available_monitors").then((e=>e.map(oe)))},currentMonitor:async function(){return d("plugin:window|current_monitor").then(oe)},cursorPosition:async function(){return d("plugin:window|cursor_position").then((e=>new k(e)))},getAllWindows:ie,getCurrentWindow:te,monitorFromPoint:async function(e,n){return d("plugin:window|monitor_from_point",{x:e,y:n}).then(oe)},primaryMonitor:async function(){return d("plugin:window|primary_monitor").then(oe)}});function ce(){return new pe(te(),window.__TAURI_INTERNALS__.metadata.currentWebview.label,{skip:!0})}async function de(){return d("plugin:webview|get_all_webviews").then((e=>e.map((e=>new pe(new se(e.windowLabel,{skip:!0}),e.label,{skip:!0})))))}const he=["tauri://created","tauri://error"];class pe{constructor(e,n,t){this.window=e,this.label=n,this.listeners=Object.create(null),(null==t?void 0:t.skip)||d("plugin:webview|create_webview",{windowLabel:e.label,label:n,options:t}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await de()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return ce()}static async getAll(){return de()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Webview",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Webview",label:this.label}})}async emit(e,n){if(!he.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!he.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!he.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async position(){return d("plugin:webview|webview_position",{label:this.label}).then((e=>new k(e)))}async size(){return d("plugin:webview|webview_size",{label:this.label}).then((e=>new m(e)))}async close(){return d("plugin:webview|close",{label:this.label})}async setSize(e){return d("plugin:webview|set_webview_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setPosition(e){return d("plugin:webview|set_webview_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFocus(){return d("plugin:webview|set_webview_focus",{label:this.label})}async hide(){return d("plugin:webview|webview_hide",{label:this.label})}async show(){return d("plugin:webview|webview_show",{label:this.label})}async setZoom(e){return d("plugin:webview|set_webview_zoom",{label:this.label,value:e})}async reparent(e){return d("plugin:webview|reparent",{label:this.label,window:"string"==typeof e?e:e.label})}async clearAllBrowsingData(){return d("plugin:webview|clear_all_browsing_data")}async setBackgroundColor(e){return d("plugin:webview|set_webview_background_color",{color:e})}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}}var we,ye,_e=Object.freeze({__proto__:null,Webview:pe,getAllWebviews:de,getCurrentWebview:ce});function ge(){const e=ce();return new me(e.label,{skip:!0})}async function be(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new me(e,{skip:!0})))))}class me{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:webview|create_webview_window",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;const t=null!==(n=(await be()).find((n=>n.label===e)))&&void 0!==n?n:null;return t?new me(t.label,{skip:!0}):null}static getCurrent(){return ge()}static async getAll(){return be()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"WebviewWindow",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"WebviewWindow",label:this.label}})}async setBackgroundColor(e){return d("plugin:window|set_background_color",{color:e}).then((()=>d("plugin:webview|set_webview_background_color",{color:e})))}}we=me,ye=[se,pe],(Array.isArray(ye)?ye:[ye]).forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((n=>{var t;"object"==typeof we.prototype&&we.prototype&&n in we.prototype||Object.defineProperty(we.prototype,n,null!==(t=Object.getOwnPropertyDescriptor(e.prototype,n))&&void 0!==t?t:Object.create(null))}))}));var ve=Object.freeze({__proto__:null,WebviewWindow:me,getAllWebviewWindows:be,getCurrentWebviewWindow:ge});return e.app=g,e.core=p,e.dpi=T,e.event=P,e.image=_,e.menu=$,e.mocks=Q,e.path=Z,e.tray=ee,e.webview=_e,e.webviewWindow=ve,e.window=ue,e}({});window.__TAURI__=__TAURI_IIFE__; +var __TAURI_IIFE__=function(e){"use strict";function n(e,n,t,i){if("a"===t&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof n?e!==n||!i:!n.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===t?i:"a"===t?i.call(e):i?i.value:n.get(e)}function t(e,n,t,i,r){if("m"===i)throw new TypeError("Private method is not writable");if("a"===i&&!r)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof n?e!==n||!r:!n.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===i?r.call(e,t):r?r.value=t:n.set(e,t),t}var i,r,s,a;"function"==typeof SuppressedError&&SuppressedError;const l="__TAURI_TO_IPC_KEY__";function o(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}class u{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),r.set(this,0),s.set(this,{}),this.id=o((({message:e,id:a})=>{if(a===n(this,r,"f")){t(this,r,a+1,"f"),n(this,i,"f").call(this,e);const l=Object.keys(n(this,s,"f"));if(l.length>0){let e=a+1;for(const t of l.sort()){if(parseInt(t)!==e)break;{const r=n(this,s,"f")[t];delete n(this,s,"f")[t],n(this,i,"f").call(this,r),e+=1}}t(this,r,e,"f")}}else n(this,s,"f")[a.toString()]=e}))}set onmessage(e){t(this,i,e,"f")}get onmessage(){return n(this,i,"f")}[(i=new WeakMap,r=new WeakMap,s=new WeakMap,l)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[l]()}}class c{constructor(e,n,t){this.plugin=e,this.event=n,this.channelId=t}async unregister(){return d(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}}async function d(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}class h{get rid(){return n(this,a,"f")}constructor(e){a.set(this,void 0),t(this,a,e,"f")}async close(){return d("plugin:resources|close",{rid:this.rid})}}a=new WeakMap;var p=Object.freeze({__proto__:null,Channel:u,PluginListener:c,Resource:h,SERIALIZE_TO_IPC_FN:l,addPluginListener:async function(e,n,t){const i=new u;return i.onmessage=t,d(`plugin:${e}|registerListener`,{event:n,handler:i}).then((()=>new c(e,n,i.id)))},checkPermissions:async function(e){return d(`plugin:${e}|check_permissions`)},convertFileSrc:function(e,n="asset"){return window.__TAURI_INTERNALS__.convertFileSrc(e,n)},invoke:d,isTauri:function(){return"isTauri"in window&&!!window.isTauri},requestPermissions:async function(e){return d(`plugin:${e}|request_permissions`)},transformCallback:o});class w extends h{constructor(e){super(e)}static async new(e,n,t){return d("plugin:image|new",{rgba:y(e),width:n,height:t}).then((e=>new w(e)))}static async fromBytes(e){return d("plugin:image|from_bytes",{bytes:y(e)}).then((e=>new w(e)))}static async fromPath(e){return d("plugin:image|from_path",{path:e}).then((e=>new w(e)))}async rgba(){return d("plugin:image|rgba",{rid:this.rid}).then((e=>new Uint8Array(e)))}async size(){return d("plugin:image|size",{rid:this.rid})}}function y(e){return null==e?null:"string"==typeof e?e:e instanceof w?e.rid:e}var _=Object.freeze({__proto__:null,Image:w,transformImage:y});var g=Object.freeze({__proto__:null,defaultWindowIcon:async function(){return d("plugin:app|default_window_icon").then((e=>e?new w(e):null))},getName:async function(){return d("plugin:app|name")},getTauriVersion:async function(){return d("plugin:app|tauri_version")},getVersion:async function(){return d("plugin:app|version")},hide:async function(){return d("plugin:app|app_hide")},setTheme:async function(e){return d("plugin:app|set_app_theme",{theme:e})},show:async function(){return d("plugin:app|app_show")}});class b{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.width=e[0].Logical.width,this.height=e[0].Logical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toPhysical(e){return new m(this.width*e,this.height*e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class m{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.width=e[0].Physical.width,this.height=e[0].Physical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toLogical(e){return new b(this.width/e,this.height/e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class v{constructor(e){this.size=e}toLogical(e){return this.size instanceof b?this.size:this.size.toLogical(e)}toPhysical(e){return this.size instanceof m?this.size:this.size.toPhysical(e)}[l](){return{[`${this.size.type}`]:{width:this.size.width,height:this.size.height}}}toJSON(){return this[l]()}}class f{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.x=e[0].Logical.x,this.y=e[0].Logical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toPhysical(e){return new k(this.x*e,this.y*e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class k{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.x=e[0].Physical.x,this.y=e[0].Physical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toLogical(e){return new f(this.x/e,this.y/e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class A{constructor(e){this.position=e}toLogical(e){return this.position instanceof f?this.position:this.position.toLogical(e)}toPhysical(e){return this.position instanceof k?this.position:this.position.toPhysical(e)}[l](){return{[`${this.position.type}`]:{x:this.position.x,y:this.position.y}}}toJSON(){return this[l]()}}var E,T=Object.freeze({__proto__:null,LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,Position:A,Size:v});async function D(e,n){await d("plugin:event|unlisten",{event:e,eventId:n})}async function I(e,n,t){var i;const r="string"==typeof(null==t?void 0:t.target)?{kind:"AnyLabel",label:t.target}:null!==(i=null==t?void 0:t.target)&&void 0!==i?i:{kind:"Any"};return d("plugin:event|listen",{event:e,target:r,handler:o(n)}).then((n=>async()=>D(e,n)))}async function R(e,n,t){return I(e,(t=>{D(e,t.id),n(t)}),t)}async function S(e,n){await d("plugin:event|emit",{event:e,payload:n})}async function L(e,n,t){const i="string"==typeof e?{kind:"AnyLabel",label:e}:e;await d("plugin:event|emit_to",{target:i,event:n,payload:t})}!function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG_ENTER="tauri://drag-enter",e.DRAG_OVER="tauri://drag-over",e.DRAG_DROP="tauri://drag-drop",e.DRAG_LEAVE="tauri://drag-leave"}(E||(E={}));var x,C,N,P=Object.freeze({__proto__:null,get TauriEvent(){return E},emit:S,emitTo:L,listen:I,once:R});function z(e){var n;if("items"in e)e.items=null===(n=e.items)||void 0===n?void 0:n.map((e=>"rid"in e?e:z(e)));else if("action"in e&&e.action){const n=new u;return n.onmessage=e.action,delete e.action,{...e,handler:n}}return e}async function W(e,n){const t=new u;if(n&&"object"==typeof n&&("action"in n&&n.action&&(t.onmessage=n.action,delete n.action),"items"in n&&n.items)){function i(e){var n;return"rid"in e?[e.rid,e.kind]:("item"in e&&"object"==typeof e.item&&(null===(n=e.item.About)||void 0===n?void 0:n.icon)&&(e.item.About.icon=y(e.item.About.icon)),"icon"in e&&e.icon&&(e.icon=y(e.icon)),"items"in e&&e.items&&(e.items=e.items.map(i)),z(e))}n.items=n.items.map(i)}return d("plugin:menu|new",{kind:e,options:n,handler:t})}class O extends h{get id(){return n(this,x,"f")}get kind(){return n(this,C,"f")}constructor(e,n,i){super(e),x.set(this,void 0),C.set(this,void 0),t(this,x,n,"f"),t(this,C,i,"f")}}x=new WeakMap,C=new WeakMap;class F extends O{constructor(e,n){super(e,n,"MenuItem")}static async new(e){return W("MenuItem",e).then((([e,n])=>new F(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}}class M extends O{constructor(e,n){super(e,n,"Check")}static async new(e){return W("Check",e).then((([e,n])=>new M(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async isChecked(){return d("plugin:menu|is_checked",{rid:this.rid})}async setChecked(e){return d("plugin:menu|set_checked",{rid:this.rid,checked:e})}}!function(e){e.Add="Add",e.Advanced="Advanced",e.Bluetooth="Bluetooth",e.Bookmarks="Bookmarks",e.Caution="Caution",e.ColorPanel="ColorPanel",e.ColumnView="ColumnView",e.Computer="Computer",e.EnterFullScreen="EnterFullScreen",e.Everyone="Everyone",e.ExitFullScreen="ExitFullScreen",e.FlowView="FlowView",e.Folder="Folder",e.FolderBurnable="FolderBurnable",e.FolderSmart="FolderSmart",e.FollowLinkFreestanding="FollowLinkFreestanding",e.FontPanel="FontPanel",e.GoLeft="GoLeft",e.GoRight="GoRight",e.Home="Home",e.IChatTheater="IChatTheater",e.IconView="IconView",e.Info="Info",e.InvalidDataFreestanding="InvalidDataFreestanding",e.LeftFacingTriangle="LeftFacingTriangle",e.ListView="ListView",e.LockLocked="LockLocked",e.LockUnlocked="LockUnlocked",e.MenuMixedState="MenuMixedState",e.MenuOnState="MenuOnState",e.MobileMe="MobileMe",e.MultipleDocuments="MultipleDocuments",e.Network="Network",e.Path="Path",e.PreferencesGeneral="PreferencesGeneral",e.QuickLook="QuickLook",e.RefreshFreestanding="RefreshFreestanding",e.Refresh="Refresh",e.Remove="Remove",e.RevealFreestanding="RevealFreestanding",e.RightFacingTriangle="RightFacingTriangle",e.Share="Share",e.Slideshow="Slideshow",e.SmartBadge="SmartBadge",e.StatusAvailable="StatusAvailable",e.StatusNone="StatusNone",e.StatusPartiallyAvailable="StatusPartiallyAvailable",e.StatusUnavailable="StatusUnavailable",e.StopProgressFreestanding="StopProgressFreestanding",e.StopProgress="StopProgress",e.TrashEmpty="TrashEmpty",e.TrashFull="TrashFull",e.User="User",e.UserAccounts="UserAccounts",e.UserGroup="UserGroup",e.UserGuest="UserGuest"}(N||(N={}));class U extends O{constructor(e,n){super(e,n,"Icon")}static async new(e){return W("Icon",e).then((([e,n])=>new U(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async setIcon(e){return d("plugin:menu|set_icon",{rid:this.rid,icon:y(e)})}}class B extends O{constructor(e,n){super(e,n,"Predefined")}static async new(e){return W("Predefined",e).then((([e,n])=>new B(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}}function j([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class V extends O{constructor(e,n){super(e,n,"Submenu")}static async new(e){return W("Submenu",e).then((([e,n])=>new V(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(j)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(j)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?j(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsWindowsMenuForNSApp(){return d("plugin:menu|set_as_windows_menu_for_nsapp",{rid:this.rid})}async setAsHelpMenuForNSApp(){return d("plugin:menu|set_as_help_menu_for_nsapp",{rid:this.rid})}}function G([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class H extends O{constructor(e,n){super(e,n,"Menu")}static async new(e){return W("Menu",e).then((([e,n])=>new H(e,n)))}static async default(){return d("plugin:menu|create_default").then((([e,n])=>new H(e,n)))}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(G)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(G)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?G(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsAppMenu(){return d("plugin:menu|set_as_app_menu",{rid:this.rid}).then((e=>e?new H(e[0],e[1]):null))}async setAsWindowMenu(e){var n;return d("plugin:menu|set_as_window_menu",{rid:this.rid,window:null!==(n=null==e?void 0:e.label)&&void 0!==n?n:null}).then((e=>e?new H(e[0],e[1]):null))}}var $=Object.freeze({__proto__:null,CheckMenuItem:M,IconMenuItem:U,Menu:H,MenuItem:F,get NativeIcon(){return N},PredefinedMenuItem:B,Submenu:V});function q(){var e;window.__TAURI_INTERNALS__=null!==(e=window.__TAURI_INTERNALS__)&&void 0!==e?e:{}}var J,Q=Object.freeze({__proto__:null,clearMocks:function(){var e,n,t;"object"==typeof window.__TAURI_INTERNALS__&&((null===(e=window.__TAURI_INTERNALS__)||void 0===e?void 0:e.convertFileSrc)&&delete window.__TAURI_INTERNALS__.convertFileSrc,(null===(n=window.__TAURI_INTERNALS__)||void 0===n?void 0:n.invoke)&&delete window.__TAURI_INTERNALS__.invoke,(null===(t=window.__TAURI_INTERNALS__)||void 0===t?void 0:t.metadata)&&delete window.__TAURI_INTERNALS__.metadata)},mockConvertFileSrc:function(e){q(),window.__TAURI_INTERNALS__.convertFileSrc=function(n,t="asset"){const i=encodeURIComponent(n);return"windows"===e?`http://${t}.localhost/${i}`:`${t}://localhost/${i}`}},mockIPC:function(e){q(),window.__TAURI_INTERNALS__.transformCallback=function(e,n=!1){const t=window.crypto.getRandomValues(new Uint32Array(1))[0],i=`_${t}`;return Object.defineProperty(window,i,{value:t=>(n&&Reflect.deleteProperty(window,i),e&&e(t)),writable:!1,configurable:!0}),t},window.__TAURI_INTERNALS__.invoke=function(n,t,i){return e(n,t)}},mockWindows:function(e,...n){q(),window.__TAURI_INTERNALS__.metadata={currentWindow:{label:e},currentWebview:{windowLabel:e,label:e}}}});!function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Document=6]="Document",e[e.Download=7]="Download",e[e.Picture=8]="Picture",e[e.Public=9]="Public",e[e.Video=10]="Video",e[e.Resource=11]="Resource",e[e.Temp=12]="Temp",e[e.AppConfig=13]="AppConfig",e[e.AppData=14]="AppData",e[e.AppLocalData=15]="AppLocalData",e[e.AppCache=16]="AppCache",e[e.AppLog=17]="AppLog",e[e.Desktop=18]="Desktop",e[e.Executable=19]="Executable",e[e.Font=20]="Font",e[e.Home=21]="Home",e[e.Runtime=22]="Runtime",e[e.Template=23]="Template"}(J||(J={}));var Z=Object.freeze({__proto__:null,get BaseDirectory(){return J},appCacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppCache})},appConfigDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppConfig})},appDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppData})},appLocalDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLocalData})},appLogDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLog})},audioDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Audio})},basename:async function(e,n){return d("plugin:path|basename",{path:e,ext:n})},cacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Cache})},configDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Config})},dataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Data})},delimiter:function(){return window.__TAURI_INTERNALS__.plugins.path.delimiter},desktopDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Desktop})},dirname:async function(e){return d("plugin:path|dirname",{path:e})},documentDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Document})},downloadDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Download})},executableDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Executable})},extname:async function(e){return d("plugin:path|extname",{path:e})},fontDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Font})},homeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Home})},isAbsolute:async function(e){return d("plugin:path|isAbsolute",{path:e})},join:async function(...e){return d("plugin:path|join",{paths:e})},localDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.LocalData})},normalize:async function(e){return d("plugin:path|normalize",{path:e})},pictureDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Picture})},publicDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Public})},resolve:async function(...e){return d("plugin:path|resolve",{paths:e})},resolveResource:async function(e){return d("plugin:path|resolve_directory",{directory:J.Resource,path:e})},resourceDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Resource})},runtimeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Runtime})},sep:function(){return window.__TAURI_INTERNALS__.plugins.path.sep},tempDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Temp})},templateDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Template})},videoDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Video})}});class K extends h{constructor(e,n){super(e),this.id=n}static async getById(e){return d("plugin:tray|get_by_id",{id:e}).then((n=>n?new K(n,e):null))}static async removeById(e){return d("plugin:tray|remove_by_id",{id:e})}static async new(e){(null==e?void 0:e.menu)&&(e.menu=[e.menu.rid,e.menu.kind]),(null==e?void 0:e.icon)&&(e.icon=y(e.icon));const n=new u;if(null==e?void 0:e.action){const t=e.action;n.onmessage=e=>t(function(e){const n=e;return n.position=new k(e.position),n.rect.position=new k(e.rect.position),n.rect.size=new m(e.rect.size),n}(e)),delete e.action}return d("plugin:tray|new",{options:null!=e?e:{},handler:n}).then((([e,n])=>new K(e,n)))}async setIcon(e){let n=null;return e&&(n=y(e)),d("plugin:tray|set_icon",{rid:this.rid,icon:n})}async setMenu(e){return e&&(e=[e.rid,e.kind]),d("plugin:tray|set_menu",{rid:this.rid,menu:e})}async setTooltip(e){return d("plugin:tray|set_tooltip",{rid:this.rid,tooltip:e})}async setTitle(e){return d("plugin:tray|set_title",{rid:this.rid,title:e})}async setVisible(e){return d("plugin:tray|set_visible",{rid:this.rid,visible:e})}async setTempDirPath(e){return d("plugin:tray|set_temp_dir_path",{rid:this.rid,path:e})}async setIconAsTemplate(e){return d("plugin:tray|set_icon_as_template",{rid:this.rid,asTemplate:e})}async setMenuOnLeftClick(e){return d("plugin:tray|set_show_menu_on_left_click",{rid:this.rid,onLeft:e})}}var Y,X,ee=Object.freeze({__proto__:null,TrayIcon:K});!function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"}(Y||(Y={}));class ne{constructor(e){this._preventDefault=!1,this.event=e.event,this.id=e.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}function te(){return new se(window.__TAURI_INTERNALS__.metadata.currentWindow.label,{skip:!0})}async function ie(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new se(e,{skip:!0})))))}!function(e){e.None="none",e.Normal="normal",e.Indeterminate="indeterminate",e.Paused="paused",e.Error="error"}(X||(X={}));const re=["tauri://created","tauri://error"];class se{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:window|create",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await ie()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return te()}static async getAll(){return ie()}static async getFocusedWindow(){for(const e of await ie())if(await e.isFocused())return e;return null}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Window",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Window",label:this.label}})}async emit(e,n){if(!re.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!re.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!re.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async scaleFactor(){return d("plugin:window|scale_factor",{label:this.label})}async innerPosition(){return d("plugin:window|inner_position",{label:this.label}).then((e=>new k(e)))}async outerPosition(){return d("plugin:window|outer_position",{label:this.label}).then((e=>new k(e)))}async innerSize(){return d("plugin:window|inner_size",{label:this.label}).then((e=>new m(e)))}async outerSize(){return d("plugin:window|outer_size",{label:this.label}).then((e=>new m(e)))}async isFullscreen(){return d("plugin:window|is_fullscreen",{label:this.label})}async isMinimized(){return d("plugin:window|is_minimized",{label:this.label})}async isMaximized(){return d("plugin:window|is_maximized",{label:this.label})}async isFocused(){return d("plugin:window|is_focused",{label:this.label})}async isDecorated(){return d("plugin:window|is_decorated",{label:this.label})}async isResizable(){return d("plugin:window|is_resizable",{label:this.label})}async isMaximizable(){return d("plugin:window|is_maximizable",{label:this.label})}async isMinimizable(){return d("plugin:window|is_minimizable",{label:this.label})}async isClosable(){return d("plugin:window|is_closable",{label:this.label})}async isVisible(){return d("plugin:window|is_visible",{label:this.label})}async title(){return d("plugin:window|title",{label:this.label})}async theme(){return d("plugin:window|theme",{label:this.label})}async center(){return d("plugin:window|center",{label:this.label})}async requestUserAttention(e){let n=null;return e&&(n=e===Y.Critical?{type:"Critical"}:{type:"Informational"}),d("plugin:window|request_user_attention",{label:this.label,value:n})}async setResizable(e){return d("plugin:window|set_resizable",{label:this.label,value:e})}async setEnabled(e){return d("plugin:window|set_enabled",{label:this.label,value:e})}async isEnabled(){return d("plugin:window|is_enabled",{label:this.label})}async setMaximizable(e){return d("plugin:window|set_maximizable",{label:this.label,value:e})}async setMinimizable(e){return d("plugin:window|set_minimizable",{label:this.label,value:e})}async setClosable(e){return d("plugin:window|set_closable",{label:this.label,value:e})}async setTitle(e){return d("plugin:window|set_title",{label:this.label,value:e})}async maximize(){return d("plugin:window|maximize",{label:this.label})}async unmaximize(){return d("plugin:window|unmaximize",{label:this.label})}async toggleMaximize(){return d("plugin:window|toggle_maximize",{label:this.label})}async minimize(){return d("plugin:window|minimize",{label:this.label})}async unminimize(){return d("plugin:window|unminimize",{label:this.label})}async show(){return d("plugin:window|show",{label:this.label})}async hide(){return d("plugin:window|hide",{label:this.label})}async close(){return d("plugin:window|close",{label:this.label})}async destroy(){return d("plugin:window|destroy",{label:this.label})}async setDecorations(e){return d("plugin:window|set_decorations",{label:this.label,value:e})}async setShadow(e){return d("plugin:window|set_shadow",{label:this.label,value:e})}async setEffects(e){return d("plugin:window|set_effects",{label:this.label,value:e})}async clearEffects(){return d("plugin:window|set_effects",{label:this.label,value:null})}async setAlwaysOnTop(e){return d("plugin:window|set_always_on_top",{label:this.label,value:e})}async setAlwaysOnBottom(e){return d("plugin:window|set_always_on_bottom",{label:this.label,value:e})}async setContentProtected(e){return d("plugin:window|set_content_protected",{label:this.label,value:e})}async setSize(e){return d("plugin:window|set_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setMinSize(e){return d("plugin:window|set_min_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setMaxSize(e){return d("plugin:window|set_max_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setSizeConstraints(e){function n(e){return e?{Logical:e}:null}return d("plugin:window|set_size_constraints",{label:this.label,value:{minWidth:n(null==e?void 0:e.minWidth),minHeight:n(null==e?void 0:e.minHeight),maxWidth:n(null==e?void 0:e.maxWidth),maxHeight:n(null==e?void 0:e.maxHeight)}})}async setPosition(e){return d("plugin:window|set_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFullscreen(e){return d("plugin:window|set_fullscreen",{label:this.label,value:e})}async setFocus(){return d("plugin:window|set_focus",{label:this.label})}async setIcon(e){return d("plugin:window|set_icon",{label:this.label,value:y(e)})}async setSkipTaskbar(e){return d("plugin:window|set_skip_taskbar",{label:this.label,value:e})}async setCursorGrab(e){return d("plugin:window|set_cursor_grab",{label:this.label,value:e})}async setCursorVisible(e){return d("plugin:window|set_cursor_visible",{label:this.label,value:e})}async setCursorIcon(e){return d("plugin:window|set_cursor_icon",{label:this.label,value:e})}async setBackgroundColor(e){return d("plugin:window|set_background_color",{color:e})}async setCursorPosition(e){return d("plugin:window|set_cursor_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setIgnoreCursorEvents(e){return d("plugin:window|set_ignore_cursor_events",{label:this.label,value:e})}async startDragging(){return d("plugin:window|start_dragging",{label:this.label})}async startResizeDragging(e){return d("plugin:window|start_resize_dragging",{label:this.label,value:e})}async setProgressBar(e){return d("plugin:window|set_progress_bar",{label:this.label,value:e})}async setVisibleOnAllWorkspaces(e){return d("plugin:window|set_visible_on_all_workspaces",{label:this.label,value:e})}async setTitleBarStyle(e){return d("plugin:window|set_title_bar_style",{label:this.label,value:e})}async setTheme(e){return d("plugin:window|set_theme",{label:this.label,value:e})}async onResized(e){return this.listen(E.WINDOW_RESIZED,(n=>{n.payload=new m(n.payload),e(n)}))}async onMoved(e){return this.listen(E.WINDOW_MOVED,(n=>{n.payload=new k(n.payload),e(n)}))}async onCloseRequested(e){return this.listen(E.WINDOW_CLOSE_REQUESTED,(async n=>{const t=new ne(n);await e(t),t.isPreventDefault()||await this.destroy()}))}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}async onFocusChanged(e){const n=await this.listen(E.WINDOW_FOCUS,(n=>{e({...n,payload:!0})})),t=await this.listen(E.WINDOW_BLUR,(n=>{e({...n,payload:!1})}));return()=>{n(),t()}}async onScaleChanged(e){return this.listen(E.WINDOW_SCALE_FACTOR_CHANGED,e)}async onThemeChanged(e){return this.listen(E.WINDOW_THEME_CHANGED,e)}}var ae,le;function oe(e){return null===e?null:{name:e.name,scaleFactor:e.scaleFactor,position:new k(e.position),size:new m(e.size)}}!function(e){e.AppearanceBased="appearanceBased",e.Light="light",e.Dark="dark",e.MediumLight="mediumLight",e.UltraDark="ultraDark",e.Titlebar="titlebar",e.Selection="selection",e.Menu="menu",e.Popover="popover",e.Sidebar="sidebar",e.HeaderView="headerView",e.Sheet="sheet",e.WindowBackground="windowBackground",e.HudWindow="hudWindow",e.FullScreenUI="fullScreenUI",e.Tooltip="tooltip",e.ContentBackground="contentBackground",e.UnderWindowBackground="underWindowBackground",e.UnderPageBackground="underPageBackground",e.Mica="mica",e.Blur="blur",e.Acrylic="acrylic",e.Tabbed="tabbed",e.TabbedDark="tabbedDark",e.TabbedLight="tabbedLight"}(ae||(ae={})),function(e){e.FollowsWindowActiveState="followsWindowActiveState",e.Active="active",e.Inactive="inactive"}(le||(le={}));var ue=Object.freeze({__proto__:null,CloseRequestedEvent:ne,get Effect(){return ae},get EffectState(){return le},LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,get ProgressBarStatus(){return X},get UserAttentionType(){return Y},Window:se,availableMonitors:async function(){return d("plugin:window|available_monitors").then((e=>e.map(oe)))},currentMonitor:async function(){return d("plugin:window|current_monitor").then(oe)},cursorPosition:async function(){return d("plugin:window|cursor_position").then((e=>new k(e)))},getAllWindows:ie,getCurrentWindow:te,monitorFromPoint:async function(e,n){return d("plugin:window|monitor_from_point",{x:e,y:n}).then(oe)},primaryMonitor:async function(){return d("plugin:window|primary_monitor").then(oe)}});function ce(){return new pe(te(),window.__TAURI_INTERNALS__.metadata.currentWebview.label,{skip:!0})}async function de(){return d("plugin:webview|get_all_webviews").then((e=>e.map((e=>new pe(new se(e.windowLabel,{skip:!0}),e.label,{skip:!0})))))}const he=["tauri://created","tauri://error"];class pe{constructor(e,n,t){this.window=e,this.label=n,this.listeners=Object.create(null),(null==t?void 0:t.skip)||d("plugin:webview|create_webview",{windowLabel:e.label,label:n,options:t}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await de()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return ce()}static async getAll(){return de()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Webview",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Webview",label:this.label}})}async emit(e,n){if(!he.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!he.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!he.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async position(){return d("plugin:webview|webview_position",{label:this.label}).then((e=>new k(e)))}async size(){return d("plugin:webview|webview_size",{label:this.label}).then((e=>new m(e)))}async close(){return d("plugin:webview|close",{label:this.label})}async setSize(e){return d("plugin:webview|set_webview_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setPosition(e){return d("plugin:webview|set_webview_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFocus(){return d("plugin:webview|set_webview_focus",{label:this.label})}async hide(){return d("plugin:webview|webview_hide",{label:this.label})}async show(){return d("plugin:webview|webview_show",{label:this.label})}async setZoom(e){return d("plugin:webview|set_webview_zoom",{label:this.label,value:e})}async reparent(e){return d("plugin:webview|reparent",{label:this.label,window:"string"==typeof e?e:e.label})}async clearAllBrowsingData(){return d("plugin:webview|clear_all_browsing_data")}async setBackgroundColor(e){return d("plugin:webview|set_webview_background_color",{color:e})}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}}var we,ye,_e=Object.freeze({__proto__:null,Webview:pe,getAllWebviews:de,getCurrentWebview:ce});function ge(){const e=ce();return new me(e.label,{skip:!0})}async function be(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new me(e,{skip:!0})))))}class me{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:webview|create_webview_window",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;const t=null!==(n=(await be()).find((n=>n.label===e)))&&void 0!==n?n:null;return t?new me(t.label,{skip:!0}):null}static getCurrent(){return ge()}static async getAll(){return be()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"WebviewWindow",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"WebviewWindow",label:this.label}})}async setBackgroundColor(e){return d("plugin:window|set_background_color",{color:e}).then((()=>d("plugin:webview|set_webview_background_color",{color:e})))}}we=me,ye=[se,pe],(Array.isArray(ye)?ye:[ye]).forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((n=>{var t;"object"==typeof we.prototype&&we.prototype&&n in we.prototype||Object.defineProperty(we.prototype,n,null!==(t=Object.getOwnPropertyDescriptor(e.prototype,n))&&void 0!==t?t:Object.create(null))}))}));var ve=Object.freeze({__proto__:null,WebviewWindow:me,getAllWebviewWindows:be,getCurrentWebviewWindow:ge});return e.app=g,e.core=p,e.dpi=T,e.event=P,e.image=_,e.menu=$,e.mocks=Q,e.path=Z,e.tray=ee,e.webview=_e,e.webviewWindow=ve,e.window=ue,e}({});window.__TAURI__=__TAURI_IIFE__; diff --git a/packages/api/src/dpi.ts b/packages/api/src/dpi.ts index 8ea676d7dc6a..714694d60afb 100644 --- a/packages/api/src/dpi.ts +++ b/packages/api/src/dpi.ts @@ -244,7 +244,7 @@ class LogicalPosition { * @since 2.0.0 */ toPhysical(scaleFactor: number): PhysicalPosition { - return new PhysicalPosition(this.x * scaleFactor, this.x * scaleFactor) + return new PhysicalPosition(this.x * scaleFactor, this.y * scaleFactor) } [SERIALIZE_TO_IPC_FN]() { @@ -309,7 +309,7 @@ class PhysicalPosition { * @since 2.0.0 */ toLogical(scaleFactor: number): LogicalPosition { - return new LogicalPosition(this.x / scaleFactor, this.x / scaleFactor) + return new LogicalPosition(this.x / scaleFactor, this.y / scaleFactor) } [SERIALIZE_TO_IPC_FN]() { From e8a50f6d760fad4529e7abb400302a1b487f11dd Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Mon, 11 Nov 2024 14:58:16 +0200 Subject: [PATCH 42/51] fix(core): hard code `BaseDirectory` integer values to avoid regressions when reordering the variants (#11645) closes #11633 --- .changes/home-dir-regression.md | 6 +++++ crates/tauri/src/path/mod.rs | 47 ++++++++++++++++----------------- packages/api/src/path.ts | 45 +++++++++++++++---------------- 3 files changed, 51 insertions(+), 47 deletions(-) create mode 100644 .changes/home-dir-regression.md diff --git a/.changes/home-dir-regression.md b/.changes/home-dir-regression.md new file mode 100644 index 000000000000..4f2de5531e93 --- /dev/null +++ b/.changes/home-dir-regression.md @@ -0,0 +1,6 @@ +--- +"tauri": "patch:bug" +"@tauri-apps/api": "patch:bug" +--- + +Fix integer values of `BasDirectory.Home` and `BaseDirectory.Font` regression which broke path APIs in JS. diff --git a/crates/tauri/src/path/mod.rs b/crates/tauri/src/path/mod.rs index 28854fb547ff..575fa926bfd6 100644 --- a/crates/tauri/src/path/mod.rs +++ b/crates/tauri/src/path/mod.rs @@ -85,61 +85,60 @@ pub enum BaseDirectory { /// The Audio directory. Audio = 1, /// The Cache directory. - Cache, + Cache = 2, /// The Config directory. - Config, + Config = 3, /// The Data directory. - Data, + Data = 4, /// The LocalData directory. - LocalData, + LocalData = 5, /// The Document directory. - Document, + Document = 6, /// The Download directory. - Download, + Download = 7, /// The Picture directory. - Picture, + Picture = 8, /// The Public directory. - Public, + Public = 9, /// The Video directory. - Video, + Video = 10, /// The Resource directory. - Resource, + Resource = 11, /// A temporary directory. Resolves to [`std::env::temp_dir`]. - Temp, + Temp = 12, /// The default app config directory. /// Resolves to [`BaseDirectory::Config`]`/{bundle_identifier}`. - AppConfig, + AppConfig = 13, /// The default app data directory. /// Resolves to [`BaseDirectory::Data`]`/{bundle_identifier}`. - AppData, + AppData = 14, /// The default app local data directory. /// Resolves to [`BaseDirectory::LocalData`]`/{bundle_identifier}`. - AppLocalData, + AppLocalData = 15, /// The default app cache directory. /// Resolves to [`BaseDirectory::Cache`]`/{bundle_identifier}`. - AppCache, + AppCache = 16, /// The default app log directory. /// Resolves to [`BaseDirectory::Home`]`/Library/Logs/{bundle_identifier}` on macOS /// and [`BaseDirectory::Config`]`/{bundle_identifier}/logs` on linux and Windows. - AppLog, - /// The Home directory. - Home, - + AppLog = 17, /// The Desktop directory. #[cfg(not(target_os = "android"))] - Desktop, + Desktop = 18, /// The Executable directory. #[cfg(not(target_os = "android"))] - Executable, + Executable = 19, /// The Font directory. #[cfg(not(target_os = "android"))] - Font, + Font = 20, + /// The Home directory. + Home = 21, /// The Runtime directory. #[cfg(not(target_os = "android"))] - Runtime, + Runtime = 22, /// The Template directory. #[cfg(not(target_os = "android"))] - Template, + Template = 23, } impl BaseDirectory { diff --git a/packages/api/src/path.ts b/packages/api/src/path.ts index dd81affd49eb..9e8e5e034756 100644 --- a/packages/api/src/path.ts +++ b/packages/api/src/path.ts @@ -18,29 +18,28 @@ import { invoke } from './core' */ enum BaseDirectory { Audio = 1, - Cache, - Config, - Data, - LocalData, - Document, - Download, - Picture, - Public, - Video, - Resource, - Temp, - AppConfig, - AppData, - AppLocalData, - AppCache, - AppLog, - - Desktop, - Executable, - Font, - Home, - Runtime, - Template + Cache = 2, + Config = 3, + Data = 4, + LocalData = 5, + Document = 6, + Download = 7, + Picture = 8, + Public = 9, + Video = 10, + Resource = 11, + Temp = 12, + AppConfig = 13, + AppData = 14, + AppLocalData = 15, + AppCache = 16, + AppLog = 17, + Desktop = 18, + Executable = 19, + Font = 20, + Home = 21, + Runtime = 22, + Template = 23 } /** From 7f81f052365675721312aafba297a7b67fb872d2 Mon Sep 17 00:00:00 2001 From: amrbashir Date: Mon, 11 Nov 2024 15:45:22 +0200 Subject: [PATCH 43/51] chore: rename change file --- ...ysical-regression.md => dpi-to-logical-physical-regression.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .changes/{dpi-to-logical/physical-regression.md => dpi-to-logical-physical-regression.md} (100%) diff --git a/.changes/dpi-to-logical/physical-regression.md b/.changes/dpi-to-logical-physical-regression.md similarity index 100% rename from .changes/dpi-to-logical/physical-regression.md rename to .changes/dpi-to-logical-physical-regression.md From ef2592b5a881ff5e3d43fbe111873014ea712078 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:25:14 +0200 Subject: [PATCH 44/51] Apply Version Updates From Current Changes (#11646) Co-authored-by: amrbashir --- .changes/dpi-to-logical-physical-regression.md | 5 ----- .changes/home-dir-regression.md | 6 ------ Cargo.lock | 2 +- crates/tauri-cli/config.schema.json | 2 +- crates/tauri-cli/metadata-v2.json | 2 +- crates/tauri-schema-generator/schemas/config.schema.json | 2 +- crates/tauri/CHANGELOG.md | 6 ++++++ crates/tauri/Cargo.toml | 2 +- packages/api/CHANGELOG.md | 7 +++++++ packages/api/package.json | 2 +- 10 files changed, 19 insertions(+), 17 deletions(-) delete mode 100644 .changes/dpi-to-logical-physical-regression.md delete mode 100644 .changes/home-dir-regression.md diff --git a/.changes/dpi-to-logical-physical-regression.md b/.changes/dpi-to-logical-physical-regression.md deleted file mode 100644 index fc37ef177d48..000000000000 --- a/.changes/dpi-to-logical-physical-regression.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@tauri-apps/api": patch:bug ---- - -Fix regression in `toLogical` and `toPhysical` for position types in `dpi` module returning incorrect `y` value. diff --git a/.changes/home-dir-regression.md b/.changes/home-dir-regression.md deleted file mode 100644 index 4f2de5531e93..000000000000 --- a/.changes/home-dir-regression.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": "patch:bug" -"@tauri-apps/api": "patch:bug" ---- - -Fix integer values of `BasDirectory.Home` and `BaseDirectory.Font` regression which broke path APIs in JS. diff --git a/Cargo.lock b/Cargo.lock index 41d86e07fb6f..b97cf5f91a61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8994,7 +8994,7 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.1.0" +version = "2.1.1" dependencies = [ "anyhow", "bytes", diff --git a/crates/tauri-cli/config.schema.json b/crates/tauri-cli/config.schema.json index 8abbf0877a20..c701eb78c6b0 100644 --- a/crates/tauri-cli/config.schema.json +++ b/crates/tauri-cli/config.schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://schema.tauri.app/config/2.1.0", + "$id": "https://schema.tauri.app/config/2.1.1", "title": "Config", "description": "The Tauri configuration object.\n It is read from a file where you can define your frontend assets,\n configure the bundler and define a tray icon.\n\n The configuration file is generated by the\n [`tauri init`](https://v2.tauri.app/reference/cli/#init) command that lives in\n your Tauri application source directory (src-tauri).\n\n Once generated, you may modify it at will to customize your Tauri application.\n\n ## File Formats\n\n By default, the configuration is defined as a JSON file named `tauri.conf.json`.\n\n Tauri also supports JSON5 and TOML files via the `config-json5` and `config-toml` Cargo features, respectively.\n The JSON5 file name must be either `tauri.conf.json` or `tauri.conf.json5`.\n The TOML file name is `Tauri.toml`.\n\n ## Platform-Specific Configuration\n\n In addition to the default configuration file, Tauri can\n read a platform-specific configuration from `tauri.linux.conf.json`,\n `tauri.windows.conf.json`, `tauri.macos.conf.json`, `tauri.android.conf.json` and `tauri.ios.conf.json`\n (or `Tauri.linux.toml`, `Tauri.windows.toml`, `Tauri.macos.toml`, `Tauri.android.toml` and `Tauri.ios.toml` if the `Tauri.toml` format is used),\n which gets merged with the main configuration object.\n\n ## Configuration Structure\n\n The configuration is composed of the following objects:\n\n - [`app`](#appconfig): The Tauri configuration\n - [`build`](#buildconfig): The build configuration\n - [`bundle`](#bundleconfig): The bundle configurations\n - [`plugins`](#pluginconfig): The plugins configuration\n\n Example tauri.config.json file:\n\n ```json\n {\n \"productName\": \"tauri-app\",\n \"version\": \"0.1.0\",\n \"build\": {\n \"beforeBuildCommand\": \"\",\n \"beforeDevCommand\": \"\",\n \"devUrl\": \"../dist\",\n \"frontendDist\": \"../dist\"\n },\n \"app\": {\n \"security\": {\n \"csp\": null\n },\n \"windows\": [\n {\n \"fullscreen\": false,\n \"height\": 600,\n \"resizable\": true,\n \"title\": \"Tauri App\",\n \"width\": 800\n }\n ]\n },\n \"bundle\": {},\n \"plugins\": {}\n }\n ```", "type": "object", diff --git a/crates/tauri-cli/metadata-v2.json b/crates/tauri-cli/metadata-v2.json index 06bb27c2c93d..97d130b6b6dd 100644 --- a/crates/tauri-cli/metadata-v2.json +++ b/crates/tauri-cli/metadata-v2.json @@ -3,7 +3,7 @@ "version": "2.1.0", "node": ">= 10.0.0" }, - "tauri": "2.1.0", + "tauri": "2.1.1", "tauri-build": "2.0.2", "tauri-plugin": "2.0.2" } diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json index 8abbf0877a20..c701eb78c6b0 100644 --- a/crates/tauri-schema-generator/schemas/config.schema.json +++ b/crates/tauri-schema-generator/schemas/config.schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://schema.tauri.app/config/2.1.0", + "$id": "https://schema.tauri.app/config/2.1.1", "title": "Config", "description": "The Tauri configuration object.\n It is read from a file where you can define your frontend assets,\n configure the bundler and define a tray icon.\n\n The configuration file is generated by the\n [`tauri init`](https://v2.tauri.app/reference/cli/#init) command that lives in\n your Tauri application source directory (src-tauri).\n\n Once generated, you may modify it at will to customize your Tauri application.\n\n ## File Formats\n\n By default, the configuration is defined as a JSON file named `tauri.conf.json`.\n\n Tauri also supports JSON5 and TOML files via the `config-json5` and `config-toml` Cargo features, respectively.\n The JSON5 file name must be either `tauri.conf.json` or `tauri.conf.json5`.\n The TOML file name is `Tauri.toml`.\n\n ## Platform-Specific Configuration\n\n In addition to the default configuration file, Tauri can\n read a platform-specific configuration from `tauri.linux.conf.json`,\n `tauri.windows.conf.json`, `tauri.macos.conf.json`, `tauri.android.conf.json` and `tauri.ios.conf.json`\n (or `Tauri.linux.toml`, `Tauri.windows.toml`, `Tauri.macos.toml`, `Tauri.android.toml` and `Tauri.ios.toml` if the `Tauri.toml` format is used),\n which gets merged with the main configuration object.\n\n ## Configuration Structure\n\n The configuration is composed of the following objects:\n\n - [`app`](#appconfig): The Tauri configuration\n - [`build`](#buildconfig): The build configuration\n - [`bundle`](#bundleconfig): The bundle configurations\n - [`plugins`](#pluginconfig): The plugins configuration\n\n Example tauri.config.json file:\n\n ```json\n {\n \"productName\": \"tauri-app\",\n \"version\": \"0.1.0\",\n \"build\": {\n \"beforeBuildCommand\": \"\",\n \"beforeDevCommand\": \"\",\n \"devUrl\": \"../dist\",\n \"frontendDist\": \"../dist\"\n },\n \"app\": {\n \"security\": {\n \"csp\": null\n },\n \"windows\": [\n {\n \"fullscreen\": false,\n \"height\": 600,\n \"resizable\": true,\n \"title\": \"Tauri App\",\n \"width\": 800\n }\n ]\n },\n \"bundle\": {},\n \"plugins\": {}\n }\n ```", "type": "object", diff --git a/crates/tauri/CHANGELOG.md b/crates/tauri/CHANGELOG.md index f6a9498d3019..14dab6a14205 100644 --- a/crates/tauri/CHANGELOG.md +++ b/crates/tauri/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## \[2.1.1] + +### Bug Fixes + +- [`e8a50f6d7`](https://www.github.com/tauri-apps/tauri/commit/e8a50f6d760fad4529e7abb400302a1b487f11dd) ([#11645](https://www.github.com/tauri-apps/tauri/pull/11645)) Fix integer values of `BasDirectory.Home` and `BaseDirectory.Font` regression which broke path APIs in JS. + ## \[2.1.0] ### New Features diff --git a/crates/tauri/Cargo.toml b/crates/tauri/Cargo.toml index 90ac32a8ea1b..5acb944033e0 100644 --- a/crates/tauri/Cargo.toml +++ b/crates/tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tauri" -version = "2.1.0" +version = "2.1.1" description = "Make tiny, secure apps for all desktop platforms with Tauri" exclude = ["/test", "/.scripts", "CHANGELOG.md", "/target"] readme = "README.md" diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md index 58be499f7120..d7238884e69f 100644 --- a/packages/api/CHANGELOG.md +++ b/packages/api/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## \[2.1.1] + +### Bug Fixes + +- [`7f81f0523`](https://www.github.com/tauri-apps/tauri/commit/7f81f052365675721312aafba297a7b67fb872d2) Fix regression in `toLogical` and `toPhysical` for position types in `dpi` module returning incorrect `y` value. +- [`e8a50f6d7`](https://www.github.com/tauri-apps/tauri/commit/e8a50f6d760fad4529e7abb400302a1b487f11dd) ([#11645](https://www.github.com/tauri-apps/tauri/pull/11645)) Fix integer values of `BasDirectory.Home` and `BaseDirectory.Font` regression which broke path APIs in JS. + ## \[2.1.0] ### New Features diff --git a/packages/api/package.json b/packages/api/package.json index 8b696dd4019e..e861252f8518 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@tauri-apps/api", - "version": "2.1.0", + "version": "2.1.1", "description": "Tauri API definitions", "funding": { "type": "opencollective", From c3b1fced38902ed0ade6797bd33e8eb6197610dc Mon Sep 17 00:00:00 2001 From: Del <35302658+idootop@users.noreply.github.com> Date: Tue, 12 Nov 2024 00:14:36 +0800 Subject: [PATCH 45/51] docs: correct payload property for DragDropEvent.over example (#11648) --- packages/api/src/webview.ts | 2 +- packages/api/src/window.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/api/src/webview.ts b/packages/api/src/webview.ts index b5a63646deb9..28bed5b3fed8 100644 --- a/packages/api/src/webview.ts +++ b/packages/api/src/webview.ts @@ -567,7 +567,7 @@ class Webview { * import { getCurrentWebview } from "@tauri-apps/api/webview"; * const unlisten = await getCurrentWebview().onDragDropEvent((event) => { * if (event.payload.type === 'over') { - * console.log('User hovering', event.payload.paths); + * console.log('User hovering', event.payload.position); * } else if (event.payload.type === 'drop') { * console.log('User dropped', event.payload.paths); * } else { diff --git a/packages/api/src/window.ts b/packages/api/src/window.ts index ae648f1b076d..d9a02879c219 100644 --- a/packages/api/src/window.ts +++ b/packages/api/src/window.ts @@ -1771,7 +1771,7 @@ class Window { * import { getCurrentWindow } from "@tauri-apps/api/webview"; * const unlisten = await getCurrentWindow().onDragDropEvent((event) => { * if (event.payload.type === 'over') { - * console.log('User hovering', event.payload.paths); + * console.log('User hovering', event.payload.position); * } else if (event.payload.type === 'drop') { * console.log('User dropped', event.payload.paths); * } else { From 74212d40d80dba4501b3d4ae30104fa3d447bdf9 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 12 Nov 2024 15:59:47 +0200 Subject: [PATCH 46/51] feat(cli): include linux DE and session type in `tauri info` (#11653) --- .changes/info-linux-de-and-session.md | 7 ++++++ crates/tauri-cli/src/info/env_system.rs | 32 +++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 .changes/info-linux-de-and-session.md diff --git a/.changes/info-linux-de-and-session.md b/.changes/info-linux-de-and-session.md new file mode 100644 index 000000000000..024c5f23591b --- /dev/null +++ b/.changes/info-linux-de-and-session.md @@ -0,0 +1,7 @@ +--- +"tauri-cli": "patch:feat" +"@tauri-apps/cli": "patch:feat" +--- + +Include Linux destkop environment and session type in `tauri info` command. + diff --git a/crates/tauri-cli/src/info/env_system.rs b/crates/tauri-cli/src/info/env_system.rs index a0570c28afc6..9deb72844e37 100644 --- a/crates/tauri-cli/src/info/env_system.rs +++ b/crates/tauri-cli/src/info/env_system.rs @@ -175,17 +175,45 @@ fn is_xcode_command_line_tools_installed() -> bool { .map(|o| o.status.success()) .unwrap_or(false) } +fn de_and_session() -> String { + #[cfg(any( + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd" + ))] + return { + let de = std::env::var("DESKTOP_SESSION"); + let session = std::env::var("XDG_SESSION_TYPE"); + format!( + " ({} on {})", + de.as_deref().unwrap_or("Unknown DE"), + session.as_deref().unwrap_or("Unknown Session") + ) + }; + + #[cfg(not(any( + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd" + )))] + String::new() +} pub fn items() -> Vec { vec![ SectionItem::new().action(|| { let os_info = os_info::get(); format!( - "OS: {} {} {} ({:?})", + "OS: {} {} {} ({:?}){}", os_info.os_type(), os_info.version(), os_info.architecture().unwrap_or("Unknown Architecture"), - os_info.bitness() + os_info.bitness(), + de_and_session(), ).into() }), #[cfg(windows)] From 46935212b61da44dc82dfeb803fceebf5659f7b7 Mon Sep 17 00:00:00 2001 From: Tony <68118705+Legend-Master@users.noreply.github.com> Date: Tue, 12 Nov 2024 22:44:37 +0800 Subject: [PATCH 47/51] fix: parse json5 capability files when `config-json5` is enabled (#11658) --- .changes/json5-capability-files.md | 6 ++++++ crates/tauri-utils/src/acl/build.rs | 7 ++++++- crates/tauri-utils/src/acl/capability.rs | 2 ++ crates/tauri-utils/src/acl/mod.rs | 5 +++++ 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 .changes/json5-capability-files.md diff --git a/.changes/json5-capability-files.md b/.changes/json5-capability-files.md new file mode 100644 index 000000000000..b0fe7fb54699 --- /dev/null +++ b/.changes/json5-capability-files.md @@ -0,0 +1,6 @@ +--- +"tauri": patch:bug +"tauri-utils": patch:bug +--- + +Fix `.json5` capability files not recognized even with `config-json5` feature enabled diff --git a/crates/tauri-utils/src/acl/build.rs b/crates/tauri-utils/src/acl/build.rs index d32eb0232846..12ce4e9e0a84 100644 --- a/crates/tauri-utils/src/acl/build.rs +++ b/crates/tauri-utils/src/acl/build.rs @@ -34,7 +34,12 @@ pub const PERMISSION_FILE_EXTENSIONS: &[&str] = &["json", "toml"]; pub const PERMISSION_DOCS_FILE_NAME: &str = "reference.md"; /// Allowed capability file extensions -const CAPABILITY_FILE_EXTENSIONS: &[&str] = &["json", "toml"]; +const CAPABILITY_FILE_EXTENSIONS: &[&str] = &[ + "json", + #[cfg(feature = "config-json5")] + "json5", + "toml", +]; /// Known folder name of the capability schemas const CAPABILITIES_SCHEMA_FOLDER_NAME: &str = "schemas"; diff --git a/crates/tauri-utils/src/acl/capability.rs b/crates/tauri-utils/src/acl/capability.rs index 9ac56f3ed83c..d5aeb3a79eac 100644 --- a/crates/tauri-utils/src/acl/capability.rs +++ b/crates/tauri-utils/src/acl/capability.rs @@ -267,6 +267,8 @@ impl CapabilityFile { let file: Self = match ext.as_str() { "toml" => toml::from_str(&capability_file)?, "json" => serde_json::from_str(&capability_file)?, + #[cfg(feature = "config-json5")] + "json5" => json5::from_str(&capability_file)?, _ => return Err(super::Error::UnknownCapabilityFormat(ext)), }; Ok(file) diff --git a/crates/tauri-utils/src/acl/mod.rs b/crates/tauri-utils/src/acl/mod.rs index 40e475fde51c..7821b7c068ba 100644 --- a/crates/tauri-utils/src/acl/mod.rs +++ b/crates/tauri-utils/src/acl/mod.rs @@ -103,6 +103,11 @@ pub enum Error { #[error("failed to parse JSON: {0}")] Json(#[from] serde_json::Error), + /// Invalid JSON5 encountered + #[cfg(feature = "config-json5")] + #[error("failed to parse JSON5: {0}")] + Json5(#[from] json5::Error), + /// Invalid permissions file format #[error("unknown permission format {0}")] UnknownPermissionFormat(String), From 4f2209e61bdba421060f78a13d4daab300ce3da9 Mon Sep 17 00:00:00 2001 From: jLynx Date: Wed, 13 Nov 2024 12:11:59 +1300 Subject: [PATCH 48/51] Added changes file --- .changes/deb-updater-support.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/deb-updater-support.md diff --git a/.changes/deb-updater-support.md b/.changes/deb-updater-support.md new file mode 100644 index 000000000000..5f9962a027b1 --- /dev/null +++ b/.changes/deb-updater-support.md @@ -0,0 +1,6 @@ +--- +'@tauri-apps/cli': minor:feat +'@tauri-apps/bundler': minor:feat +--- + +Add support for Debian (`.deb`) packages in the updater bundle system, enabling self-contained updater functionality for Debian packages alongside existing formats like AppImage, NSIS, and Windows MSI. From dc4d79477665bc3bfefb4048772414cf5d78e3df Mon Sep 17 00:00:00 2001 From: SpikeHD <25207995+SpikeHD@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:20:06 -0800 Subject: [PATCH 49/51] feat(windows, linux): add `WebviewWindowBuilder/WebviewBuilder::extensions_path` (#11628) --- .changes/extension-path.md | 7 +++++++ crates/tauri-runtime-wry/src/lib.rs | 14 ++++++++++++++ crates/tauri-runtime/src/webview.rs | 2 ++ crates/tauri/src/webview/mod.rs | 14 +++++++++++++- crates/tauri/src/webview/webview_window.rs | 14 +++++++++++++- 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 .changes/extension-path.md diff --git a/.changes/extension-path.md b/.changes/extension-path.md new file mode 100644 index 000000000000..caec2b54d50e --- /dev/null +++ b/.changes/extension-path.md @@ -0,0 +1,7 @@ +--- +"tauri": "minor:feat" +"tauri-runtime": "minor:feat" +"tauri-runtime-wry": "minor:feat" +--- + +Add `WebviewWindowBuilder/WebviewBuilder::extensions_path` on Linux and Windows. diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index 12629db18420..6d256f1c32a8 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -4283,6 +4283,20 @@ fn create_webview( .with_browser_extensions_enabled(webview_attributes.browser_extensions_enabled); } + #[cfg(any( + windows, + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd" + ))] + { + if let Some(path) = &webview_attributes.extensions_path { + webview_builder = webview_builder.with_extension_path(path); + } + } + webview_builder = webview_builder.with_ipc_handler(create_ipc_handler( kind, window_id.clone(), diff --git a/crates/tauri-runtime/src/webview.rs b/crates/tauri-runtime/src/webview.rs index e17b9e197396..e14799bf44bf 100644 --- a/crates/tauri-runtime/src/webview.rs +++ b/crates/tauri-runtime/src/webview.rs @@ -210,6 +210,7 @@ pub struct WebviewAttributes { pub proxy_url: Option, pub zoom_hotkeys_enabled: bool, pub browser_extensions_enabled: bool, + pub extensions_path: Option, pub use_https_scheme: bool, pub devtools: Option, pub background_color: Option, @@ -272,6 +273,7 @@ impl WebviewAttributes { proxy_url: None, zoom_hotkeys_enabled: false, browser_extensions_enabled: false, + extensions_path: None, use_https_scheme: false, devtools: None, background_color: None, diff --git a/crates/tauri/src/webview/mod.rs b/crates/tauri/src/webview/mod.rs index 987186939140..feb818162910 100644 --- a/crates/tauri/src/webview/mod.rs +++ b/crates/tauri/src/webview/mod.rs @@ -42,7 +42,7 @@ use crate::{ use std::{ borrow::Cow, hash::{Hash, Hasher}, - path::PathBuf, + path::{Path, PathBuf}, sync::{Arc, Mutex, MutexGuard}, }; @@ -802,6 +802,18 @@ fn main() { self } + /// Set the path from which to load extensions from. Extensions stored in this path should be unpacked Chrome extensions on Windows, and compiled `.so` extensions on Linux. + /// + /// ## Platform-specific: + /// + /// - **Windows**: Browser extensions must first be enabled. See [`browser_extensions_enabled`](Self::browser_extensions_enabled) + /// - **MacOS / iOS / Android** - Unsupported. + #[must_use] + pub fn extensions_path(mut self, path: impl AsRef) -> Self { + self.webview_attributes.extensions_path = Some(path.as_ref().to_path_buf()); + self + } + /// Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`. /// /// ## Note diff --git a/crates/tauri/src/webview/webview_window.rs b/crates/tauri/src/webview/webview_window.rs index a81599ed18dd..b95e6a90564c 100644 --- a/crates/tauri/src/webview/webview_window.rs +++ b/crates/tauri/src/webview/webview_window.rs @@ -6,7 +6,7 @@ use std::{ borrow::Cow, - path::PathBuf, + path::{Path, PathBuf}, sync::{Arc, MutexGuard}, }; @@ -906,6 +906,18 @@ impl<'a, R: Runtime, M: Manager> WebviewWindowBuilder<'a, R, M> { self } + /// Set the path from which to load extensions from. Extensions stored in this path should be unpacked Chrome extensions on Windows, and compiled `.so` extensions on Linux. + /// + /// ## Platform-specific: + /// + /// - **Windows**: Browser extensions must first be enabled. See [`browser_extensions_enabled`](Self::browser_extensions_enabled) + /// - **MacOS / iOS / Android** - Unsupported. + #[must_use] + pub fn extensions_path(mut self, path: impl AsRef) -> Self { + self.webview_builder = self.webview_builder.extensions_path(path); + self + } + /// Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`. /// /// ## Note From c7452c38c3912a31861d5ba60a62e0bbdd7bd3a6 Mon Sep 17 00:00:00 2001 From: jLynx Date: Wed, 13 Nov 2024 13:23:39 +1300 Subject: [PATCH 50/51] Update .changes/deb-updater-support.md Co-authored-by: Amr Bashir --- .changes/deb-updater-support.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.changes/deb-updater-support.md b/.changes/deb-updater-support.md index 5f9962a027b1..f3751bd500dd 100644 --- a/.changes/deb-updater-support.md +++ b/.changes/deb-updater-support.md @@ -1,6 +1,7 @@ --- +'tauri-bundler': minor:feat +'tauri-cli': minor:feat '@tauri-apps/cli': minor:feat -'@tauri-apps/bundler': minor:feat --- Add support for Debian (`.deb`) packages in the updater bundle system, enabling self-contained updater functionality for Debian packages alongside existing formats like AppImage, NSIS, and Windows MSI. From f528070ab30463267b195b6e1e23573e95638b2d Mon Sep 17 00:00:00 2001 From: jLynx Date: Wed, 13 Nov 2024 13:23:46 +1300 Subject: [PATCH 51/51] Update .changes/deb-updater-support.md Co-authored-by: Amr Bashir --- .changes/deb-updater-support.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changes/deb-updater-support.md b/.changes/deb-updater-support.md index f3751bd500dd..001a5b1dccd7 100644 --- a/.changes/deb-updater-support.md +++ b/.changes/deb-updater-support.md @@ -4,4 +4,4 @@ '@tauri-apps/cli': minor:feat --- -Add support for Debian (`.deb`) packages in the updater bundle system, enabling self-contained updater functionality for Debian packages alongside existing formats like AppImage, NSIS, and Windows MSI. +Generate signature for `.deb` packages when `createUpdaterArtifacts` option is enabled.