浏览代码

Merge branch 'dev' into feat/api/dpi-toIpc

amrbashir 9 月之前
父节点
当前提交
258fe72f3d
共有 53 个文件被更改,包括 439 次插入147 次删除
  1. 0 5
      .changes/asset-protocol-expose-content-range.md
  2. 6 0
      .changes/bundler-linux-recommends.md
  3. 0 6
      .changes/bundler-wix-version.md
  4. 7 0
      .changes/cli-updater-errorr.md
  5. 6 0
      .changes/migrate-schema.md
  6. 0 5
      .changes/predefined-menu-item-with-text-on-menu-builders.md
  7. 0 6
      .changes/remove-unused-metadata-references.md
  8. 5 0
      .changes/resolve_command_scope.md
  9. 0 5
      .changes/resources-close-fallback.md
  10. 0 7
      .changes/support-custom-repo-structure.md
  11. 22 22
      Cargo.lock
  12. 6 0
      crates/tauri-build/CHANGELOG.md
  13. 3 3
      crates/tauri-build/Cargo.toml
  14. 6 0
      crates/tauri-bundler/CHANGELOG.md
  15. 2 2
      crates/tauri-bundler/Cargo.toml
  16. 9 0
      crates/tauri-bundler/src/bundle/linux/debian.rs
  17. 11 0
      crates/tauri-bundler/src/bundle/linux/rpm.rs
  18. 4 0
      crates/tauri-bundler/src/bundle/settings.rs
  19. 11 0
      crates/tauri-cli/CHANGELOG.md
  20. 3 3
      crates/tauri-cli/Cargo.toml
  21. 1 1
      crates/tauri-cli/config.schema.json
  22. 2 2
      crates/tauri-cli/metadata-v2.json
  23. 5 7
      crates/tauri-cli/src/bundle.rs
  24. 16 5
      crates/tauri-cli/src/helpers/updater_signature.rs
  25. 2 0
      crates/tauri-cli/src/interface/rust.rs
  26. 13 0
      crates/tauri-cli/src/migrate/migrations/v1/config.rs
  27. 1 1
      crates/tauri-cli/src/mobile/init.rs
  28. 6 0
      crates/tauri-codegen/CHANGELOG.md
  29. 2 2
      crates/tauri-codegen/Cargo.toml
  30. 3 3
      crates/tauri-macros/Cargo.toml
  31. 6 0
      crates/tauri-plugin/CHANGELOG.md
  32. 2 2
      crates/tauri-plugin/Cargo.toml
  33. 6 0
      crates/tauri-runtime-wry/CHANGELOG.md
  34. 2 2
      crates/tauri-runtime-wry/Cargo.toml
  35. 6 0
      crates/tauri-runtime/CHANGELOG.md
  36. 2 2
      crates/tauri-runtime/Cargo.toml
  37. 1 1
      crates/tauri-schema-generator/schemas/config.schema.json
  38. 6 0
      crates/tauri-utils/CHANGELOG.md
  39. 1 1
      crates/tauri-utils/Cargo.toml
  40. 5 0
      crates/tauri-utils/src/config.rs
  41. 24 0
      crates/tauri/CHANGELOG.md
  42. 7 7
      crates/tauri/Cargo.toml
  43. 0 0
      crates/tauri/scripts/bundle.global.js
  44. 45 38
      crates/tauri/src/ipc/authority.rs
  45. 97 2
      crates/tauri/src/webview/mod.rs
  46. 49 2
      crates/tauri/src/webview/webview_window.rs
  47. 2 2
      examples/api/src-tauri/tauri-plugin-sample/src/desktop.rs
  48. 2 0
      examples/api/src-tauri/tauri-plugin-sample/src/error.rs
  49. 10 0
      packages/api/CHANGELOG.md
  50. 1 1
      packages/api/package.json
  51. 1 1
      packages/api/src/core.ts
  52. 11 0
      packages/cli/CHANGELOG.md
  53. 1 1
      packages/cli/package.json

+ 0 - 5
.changes/asset-protocol-expose-content-range.md

@@ -1,5 +0,0 @@
----
-"tauri": patch:bug
----
-
-Expose `content-range` header in `range` response of `asset` protocol

+ 6 - 0
.changes/bundler-linux-recommends.md

@@ -0,0 +1,6 @@
+---
+"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.
+

+ 0 - 6
.changes/bundler-wix-version.md

@@ -1,6 +0,0 @@
----
-"tauri-bundler": "patch:feat"
----
-
-Add `bundler > windows > wix > version` to manually specify a wix-compatible version.
-

+ 7 - 0
.changes/cli-updater-errorr.md

@@ -0,0 +1,7 @@
+---
+"tauri-cli": "patch:enhance"
+"@tauri-apps/cli": "patch:enhance"
+---
+
+Add more context for errors when decoding secret and public keys for signing updater artifacts.
+

+ 6 - 0
.changes/migrate-schema.md

@@ -0,0 +1,6 @@
+---
+"@tauri-apps/cli": patch:enhance
+"tauri-cli": patch:enhance
+---
+
+Migrate the `$schema` Tauri configuration to the v2 format.

+ 0 - 5
.changes/predefined-menu-item-with-text-on-menu-builders.md

@@ -1,5 +0,0 @@
----
-"tauri": "patch:feat"
----
-
-Add new methods on `tauri::menu::MenuBuilder` and `tauri::menu::SubmenuBuilder` to create predefined menu item with specific text.

+ 0 - 6
.changes/remove-unused-metadata-references.md

@@ -1,6 +0,0 @@
----
-"@tauri-apps/api": patch:changes
-"tauri": patch:changes
----
-
-Remove references to no longer used `__TAURI_INTERNALS__.metadata.windows` and `__TAURI_INTERNALS__.metadata.webviews`.

+ 5 - 0
.changes/resolve_command_scope.md

@@ -0,0 +1,5 @@
+---
+"tauri": patch:feat
+---
+
+Added `WebviewWindow::resolve_command_scope` to check a command scope at runtime.

+ 0 - 5
.changes/resources-close-fallback.md

@@ -1,5 +0,0 @@
----
-"tauri": patch:enhance
----
-
-Fallback to the Window and AppHandle resource table when closing a resource by ID.

+ 0 - 7
.changes/support-custom-repo-structure.md

@@ -1,7 +0,0 @@
----
-"@tauri-apps/cli": patch:enhance
-"tauri-cli": patch:enhance
----
-
-Support custom project directory structure where the Tauri app folder is not a subfolder of the frontend project.
-The frontend and Tauri app project paths can be set with the `TAURI_FRONTEND_PATH` and the `TAURI_APP_PATH` environment variables respectively.

+ 22 - 22
Cargo.lock

@@ -14,7 +14,7 @@ version = "0.1.0"
 dependencies = [
  "insta",
  "serde_json",
- "tauri-utils 2.0.1",
+ "tauri-utils 2.0.2",
 ]
 
 [[package]]
@@ -8821,7 +8821,7 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
 
 [[package]]
 name = "tauri"
-version = "2.0.4"
+version = "2.0.6"
 dependencies = [
  "anyhow",
  "bytes",
@@ -8865,7 +8865,7 @@ dependencies = [
  "tauri-macros",
  "tauri-runtime",
  "tauri-runtime-wry",
- "tauri-utils 2.0.1",
+ "tauri-utils 2.0.2",
  "thiserror",
  "tokio",
  "tracing",
@@ -8881,7 +8881,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-build"
-version = "2.0.1"
+version = "2.0.2"
 dependencies = [
  "anyhow",
  "cargo_toml",
@@ -8895,7 +8895,7 @@ dependencies = [
  "serde",
  "serde_json",
  "tauri-codegen",
- "tauri-utils 2.0.1",
+ "tauri-utils 2.0.2",
  "tauri-winres",
  "toml 0.8.19",
  "walkdir",
@@ -8903,7 +8903,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-bundler"
-version = "2.0.3"
+version = "2.0.4"
 dependencies = [
  "anyhow",
  "ar",
@@ -8932,7 +8932,7 @@ dependencies = [
  "tar",
  "tauri-icns",
  "tauri-macos-sign",
- "tauri-utils 2.0.1",
+ "tauri-utils 2.0.2",
  "tempfile",
  "thiserror",
  "time",
@@ -8947,7 +8947,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-cli"
-version = "2.0.3"
+version = "2.0.4"
 dependencies = [
  "anyhow",
  "ar",
@@ -9012,7 +9012,7 @@ dependencies = [
  "tauri-icns",
  "tauri-macos-sign",
  "tauri-utils 1.6.0",
- "tauri-utils 2.0.1",
+ "tauri-utils 2.0.2",
  "tempfile",
  "tokio",
  "toml 0.8.19",
@@ -9037,7 +9037,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-codegen"
-version = "2.0.1"
+version = "2.0.2"
 dependencies = [
  "base64 0.22.1",
  "brotli",
@@ -9053,7 +9053,7 @@ dependencies = [
  "serde_json",
  "sha2",
  "syn 2.0.79",
- "tauri-utils 2.0.1",
+ "tauri-utils 2.0.2",
  "thiserror",
  "time",
  "url",
@@ -9121,14 +9121,14 @@ dependencies = [
 
 [[package]]
 name = "tauri-macros"
-version = "2.0.1"
+version = "2.0.2"
 dependencies = [
  "heck 0.5.0",
  "proc-macro2",
  "quote",
  "syn 2.0.79",
  "tauri-codegen",
- "tauri-utils 2.0.1",
+ "tauri-utils 2.0.2",
 ]
 
 [[package]]
@@ -9150,7 +9150,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-plugin"
-version = "2.0.1"
+version = "2.0.2"
 dependencies = [
  "anyhow",
  "glob",
@@ -9158,7 +9158,7 @@ dependencies = [
  "schemars",
  "serde",
  "serde_json",
- "tauri-utils 2.0.1",
+ "tauri-utils 2.0.2",
  "toml 0.8.19",
  "walkdir",
 ]
@@ -9192,13 +9192,13 @@ dependencies = [
  "log",
  "serde",
  "tauri",
- "tauri-plugin 2.0.1",
+ "tauri-plugin 2.0.2",
  "thiserror",
 ]
 
 [[package]]
 name = "tauri-runtime"
-version = "2.1.0"
+version = "2.1.1"
 dependencies = [
  "dpi",
  "gtk",
@@ -9207,7 +9207,7 @@ dependencies = [
  "raw-window-handle",
  "serde",
  "serde_json",
- "tauri-utils 2.0.1",
+ "tauri-utils 2.0.2",
  "thiserror",
  "url",
  "windows",
@@ -9215,7 +9215,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-runtime-wry"
-version = "2.1.1"
+version = "2.1.2"
 dependencies = [
  "gtk",
  "http 1.1.0",
@@ -9229,7 +9229,7 @@ dependencies = [
  "softbuffer",
  "tao",
  "tauri-runtime",
- "tauri-utils 2.0.1",
+ "tauri-utils 2.0.2",
  "tracing",
  "url",
  "webkit2gtk",
@@ -9245,7 +9245,7 @@ dependencies = [
  "schemars",
  "serde",
  "serde_json",
- "tauri-utils 2.0.1",
+ "tauri-utils 2.0.2",
  "url",
 ]
 
@@ -9330,7 +9330,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-utils"
-version = "2.0.1"
+version = "2.0.2"
 dependencies = [
  "aes-gcm",
  "brotli",

+ 6 - 0
crates/tauri-build/CHANGELOG.md

@@ -1,5 +1,11 @@
 # Changelog
 
+## \[2.0.2]
+
+### Dependencies
+
+- Upgraded to `tauri-utils@2.0.2`
+
 ## \[2.0.1]
 
 ### What's Changed

+ 3 - 3
crates/tauri-build/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "tauri-build"
-version = "2.0.1"
+version = "2.0.2"
 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.1", path = "../tauri-codegen", optional = true }
-tauri-utils = { version = "2.0.1", path = "../tauri-utils", features = [
+tauri-codegen = { version = "2.0.2", path = "../tauri-codegen", optional = true }
+tauri-utils = { version = "2.0.2", path = "../tauri-utils", features = [
   "build",
   "resources",
 ] }

+ 6 - 0
crates/tauri-bundler/CHANGELOG.md

@@ -1,5 +1,11 @@
 # Changelog
 
+## \[2.0.4]
+
+### New Features
+
+- [`c8f55b615`](https://www.github.com/tauri-apps/tauri/commit/c8f55b615d2d98ade5c0f1896139dc283382a176) ([#11388](https://www.github.com/tauri-apps/tauri/pull/11388) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `bundler > windows > wix > version` to manually specify a wix-compatible version.
+
 ## \[2.0.3]
 
 ### New Features

+ 2 - 2
crates/tauri-bundler/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "tauri-bundler"
-version = "2.0.3"
+version = "2.0.4"
 authors = [
   "George Burton <burtonageo@gmail.com>",
   "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.1", path = "../tauri-utils", features = [
+tauri-utils = { version = "2.0.2", path = "../tauri-utils", features = [
   "resources",
 ] }
 image = "0.25.0"

+ 9 - 0
crates/tauri-bundler/src/bundle/linux/debian.rs

@@ -198,6 +198,15 @@ fn generate_control_file(
   if !dependencies.is_empty() {
     writeln!(file, "Depends: {}", dependencies.join(", "))?;
   }
+  let dependencies = settings
+    .deb()
+    .recommends
+    .as_ref()
+    .cloned()
+    .unwrap_or_default();
+  if !dependencies.is_empty() {
+    writeln!(file, "Recommends: {}", dependencies.join(", "))?;
+  }
   let provides = settings
     .deb()
     .provides

+ 11 - 0
crates/tauri-bundler/src/bundle/linux/rpm.rs

@@ -84,6 +84,17 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
     builder = builder.provides(Dependency::any(dep));
   }
 
+  // Add recommends
+  for dep in settings
+    .rpm()
+    .recommends
+    .as_ref()
+    .cloned()
+    .unwrap_or_default()
+  {
+    builder = builder.recommends(Dependency::any(dep));
+  }
+
   // Add conflicts
   for dep in settings
     .rpm()

+ 4 - 0
crates/tauri-bundler/src/bundle/settings.rs

@@ -170,6 +170,8 @@ pub struct DebianSettings {
   // OS-specific settings:
   /// the list of debian dependencies.
   pub depends: Option<Vec<String>>,
+  /// the list of debian dependencies recommendations.
+  pub recommends: Option<Vec<String>>,
   /// the list of dependencies the package provides.
   pub provides: Option<Vec<String>>,
   /// the list of package conflicts.
@@ -222,6 +224,8 @@ pub struct AppImageSettings {
 pub struct RpmSettings {
   /// The list of RPM dependencies your application relies on.
   pub depends: Option<Vec<String>>,
+  /// the list of of RPM dependencies your application recommends.
+  pub recommends: Option<Vec<String>>,
   /// The list of RPM dependencies your application provides.
   pub provides: Option<Vec<String>>,
   /// The list of RPM dependencies your application conflicts with. They must not be present

+ 11 - 0
crates/tauri-cli/CHANGELOG.md

@@ -1,5 +1,16 @@
 # Changelog
 
+## \[2.0.4]
+
+### Enhancements
+
+- [`e4c9268b1`](https://www.github.com/tauri-apps/tauri/commit/e4c9268b19c614dc9ebb0895448fd16de7efee80) ([#11258](https://www.github.com/tauri-apps/tauri/pull/11258) by [@regexident](https://www.github.com/tauri-apps/tauri/../../regexident)) Support custom project directory structure where the Tauri app folder is not a subfolder of the frontend project.
+  The frontend and Tauri app project paths can be set with the `TAURI_FRONTEND_PATH` and the `TAURI_APP_PATH` environment variables respectively.
+
+### Dependencies
+
+- Upgraded to `tauri-bundler@2.0.4`
+
 ## \[2.0.3]
 
 ### New Features

+ 3 - 3
crates/tauri-cli/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "tauri-cli"
-version = "2.0.3"
+version = "2.0.4"
 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.3", default-features = false, path = "../tauri-bundler" }
+tauri-bundler = { version = "2.0.4", 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 = "2.0"
-tauri-utils = { version = "2.0.1", path = "../tauri-utils", features = [
+tauri-utils = { version = "2.0.2", path = "../tauri-utils", features = [
   "isolation",
   "schema",
   "config-json5",

文件差异内容过多而无法显示
+ 1 - 1
crates/tauri-cli/config.schema.json


+ 2 - 2
crates/tauri-cli/metadata-v2.json

@@ -1,9 +1,9 @@
 {
   "cli.js": {
-    "version": "2.0.3",
+    "version": "2.0.4",
     "node": ">= 10.0.0"
   },
-  "tauri": "2.0.4",
+  "tauri": "2.0.6",
   "tauri-build": "2.0.1",
   "tauri-plugin": "2.0.1"
 }

+ 5 - 7
crates/tauri-cli/src/bundle.rs

@@ -9,7 +9,6 @@ use std::{
 };
 
 use anyhow::Context;
-use base64::Engine;
 use clap::{builder::PossibleValue, ArgAction, Parser, ValueEnum};
 use tauri_bundler::PackageType;
 use tauri_utils::platform::Target;
@@ -257,15 +256,14 @@ fn sign_updaters(
   // check if private_key points to a file...
   let maybe_path = Path::new(&private_key);
   let private_key = if maybe_path.exists() {
-    std::fs::read_to_string(maybe_path)?
+    std::fs::read_to_string(maybe_path)
+      .with_context(|| format!("faild to read {}", maybe_path.display()))?
   } else {
     private_key
   };
-  let secret_key = updater_signature::secret_key(private_key, password)?;
-
-  let pubkey = base64::engine::general_purpose::STANDARD.decode(pubkey)?;
-  let pub_key_decoded = String::from_utf8_lossy(&pubkey);
-  let public_key = minisign::PublicKeyBox::from_string(&pub_key_decoded)?.into_public_key()?;
+  let secret_key =
+    updater_signature::secret_key(private_key, password).context("failed to decode secret key")?;
+  let public_key = updater_signature::pub_key(pubkey).context("failed to decode pubkey")?;
 
   let mut signed_paths = Vec::new();
   for bundle in update_enabled_bundles {

+ 16 - 5
crates/tauri-cli/src/helpers/updater_signature.rs

@@ -4,7 +4,9 @@
 
 use anyhow::Context;
 use base64::Engine;
-use minisign::{sign, KeyPair as KP, SecretKey, SecretKeyBox, SignatureBox};
+use minisign::{
+  sign, KeyPair as KP, PublicKey, PublicKeyBox, SecretKey, SecretKeyBox, SignatureBox,
+};
 use std::{
   fs::{self, File, OpenOptions},
   io::{BufReader, BufWriter, Write},
@@ -132,15 +134,24 @@ pub fn secret_key<S: AsRef<[u8]>>(
   private_key: S,
   password: Option<String>,
 ) -> crate::Result<SecretKey> {
-  let decoded_secret = decode_key(private_key)?;
-  let sk_box = SecretKeyBox::from_string(&decoded_secret)
-    .with_context(|| "failed to load updater private key")?;
+  let decoded_secret = decode_key(private_key).context("failed to decode base64 secret key")?;
+  let sk_box =
+    SecretKeyBox::from_string(&decoded_secret).context("failed to load updater private key")?;
   let sk = sk_box
     .into_secret_key(password)
-    .with_context(|| "incorrect updater private key password")?;
+    .context("incorrect updater private key password")?;
   Ok(sk)
 }
 
+/// Gets the updater secret key from the given private key and password.
+pub fn pub_key<S: AsRef<[u8]>>(public_key: S) -> crate::Result<PublicKey> {
+  let decoded_publick = decode_key(public_key).context("failed to decode base64 pubkey")?;
+  let pk_box =
+    PublicKeyBox::from_string(&decoded_publick).context("failed to load updater pubkey")?;
+  let pk = pk_box.into_public_key()?;
+  Ok(pk)
+}
+
 fn unix_timestamp() -> u64 {
   let start = SystemTime::now();
   let since_the_epoch = start

+ 2 - 0
crates/tauri-cli/src/interface/rust.rs

@@ -1346,6 +1346,7 @@ fn tauri_config_to_bundle_settings(
       } else {
         Some(depends_deb)
       },
+      recommends: config.linux.deb.recommends,
       provides: config.linux.deb.provides,
       conflicts: config.linux.deb.conflicts,
       replaces: config.linux.deb.replaces,
@@ -1368,6 +1369,7 @@ fn tauri_config_to_bundle_settings(
       } else {
         Some(depends_rpm)
       },
+      recommends: config.linux.rpm.recommends,
       provides: config.linux.rpm.provides,
       conflicts: config.linux.rpm.conflicts,
       obsoletes: config.linux.rpm.obsoletes,

+ 13 - 0
crates/tauri-cli/src/migrate/migrations/v1/config.rs

@@ -684,6 +684,15 @@ mod test {
     let mut migrated = original.clone();
     super::migrate_config(&mut migrated).expect("failed to migrate config");
 
+    if original.get("$schema").is_some() {
+      if let Some(map) = migrated.as_object_mut() {
+        map.insert(
+          "$schema".to_string(),
+          serde_json::Value::String("https://schema.tauri.app/config/2".to_string()),
+        );
+      }
+    }
+
     if original
       .get("tauri")
       .and_then(|v| v.get("bundle"))
@@ -708,6 +717,7 @@ mod test {
   #[test]
   fn migrate_full() {
     let original = serde_json::json!({
+      "$schema": "../node_modules/@tauri-apps/cli/schema.json",
       "build": {
         "distDir": "../dist",
         "devPath": "http://localhost:1240",
@@ -798,6 +808,9 @@ mod test {
 
     let migrated = migrate(&original);
 
+    // $schema
+    assert_eq!(migrated["$schema"], "https://schema.tauri.app/config/2");
+
     // plugins > updater
     assert_eq!(
       migrated["plugins"]["updater"]["endpoints"],

+ 1 - 1
crates/tauri-cli/src/mobile/init.rs

@@ -204,7 +204,7 @@ fn get_str_array(helper: &Helper, formatter: impl Fn(&str) -> String) -> Option<
         .map(|val| {
           val.as_str().map(
             #[allow(clippy::redundant_closure)]
-            |s| formatter(s),
+            &formatter,
           )
         })
         .collect()

+ 6 - 0
crates/tauri-codegen/CHANGELOG.md

@@ -1,5 +1,11 @@
 # Changelog
 
+## \[2.0.2]
+
+### Dependencies
+
+- Upgraded to `tauri-utils@2.0.2`
+
 ## \[2.0.1]
 
 ### What's Changed

+ 2 - 2
crates/tauri-codegen/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "tauri-codegen"
-version = "2.0.1"
+version = "2.0.2"
 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.1", path = "../tauri-utils", features = [
+tauri-utils = { version = "2.0.2", path = "../tauri-utils", features = [
   "build",
 ] }
 thiserror = "1"

+ 3 - 3
crates/tauri-macros/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "tauri-macros"
-version = "2.0.1"
+version = "2.0.2"
 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.1", default-features = false, path = "../tauri-codegen" }
-tauri-utils = { version = "2.0.1", path = "../tauri-utils" }
+tauri-codegen = { version = "2.0.2", default-features = false, path = "../tauri-codegen" }
+tauri-utils = { version = "2.0.2", path = "../tauri-utils" }
 
 [features]
 custom-protocol = []

+ 6 - 0
crates/tauri-plugin/CHANGELOG.md

@@ -1,5 +1,11 @@
 # Changelog
 
+## \[2.0.2]
+
+### Dependencies
+
+- Upgraded to `tauri-utils@2.0.2`
+
 ## \[2.0.1]
 
 ### What's Changed

+ 2 - 2
crates/tauri-plugin/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "tauri-plugin"
-version = "2.0.1"
+version = "2.0.2"
 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.1", default-features = false, features = [
+tauri-utils = { version = "2.0.2", default-features = false, features = [
   "build",
 ], path = "../tauri-utils" }
 serde_json = { version = "1", optional = true }

+ 6 - 0
crates/tauri-runtime-wry/CHANGELOG.md

@@ -1,5 +1,11 @@
 # Changelog
 
+## \[2.1.2]
+
+### Dependencies
+
+- Upgraded to `tauri-utils@2.0.2`
+
 ## \[2.1.1]
 
 ### Bug Fixes

+ 2 - 2
crates/tauri-runtime-wry/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "tauri-runtime-wry"
-version = "2.1.1"
+version = "2.1.2"
 description = "Wry bindings to the Tauri runtime"
 exclude = ["CHANGELOG.md", "/target"]
 readme = "README.md"
@@ -25,7 +25,7 @@ wry = { version = "0.46.1", default-features = false, features = [
 ] }
 tao = { version = "0.30.2", default-features = false, features = ["rwh_06"] }
 tauri-runtime = { version = "2.1.0", path = "../tauri-runtime" }
-tauri-utils = { version = "2.0.1", path = "../tauri-utils" }
+tauri-utils = { version = "2.0.2", path = "../tauri-utils" }
 raw-window-handle = "0.6"
 http = "1.1"
 url = "2"

+ 6 - 0
crates/tauri-runtime/CHANGELOG.md

@@ -1,5 +1,11 @@
 # Changelog
 
+## \[2.1.1]
+
+### Dependencies
+
+- Upgraded to `tauri-utils@2.0.2`
+
 ## \[2.1.0]
 
 ### Bug Fixes

+ 2 - 2
crates/tauri-runtime/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "tauri-runtime"
-version = "2.1.0"
+version = "2.1.1"
 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 = "1.0"
-tauri-utils = { version = "2.0.1", path = "../tauri-utils" }
+tauri-utils = { version = "2.0.2", path = "../tauri-utils" }
 http = "1.1"
 raw-window-handle = "0.6"
 url = { version = "2" }

文件差异内容过多而无法显示
+ 1 - 1
crates/tauri-schema-generator/schemas/config.schema.json


+ 6 - 0
crates/tauri-utils/CHANGELOG.md

@@ -1,5 +1,11 @@
 # Changelog
 
+## \[2.0.2]
+
+### New Features
+
+- Add `bundler > windows > wix > version` to manually specify a wix-compatible version.
+
 ## \[2.0.1]
 
 ### What's Changed

+ 1 - 1
crates/tauri-utils/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "tauri-utils"
-version = "2.0.1"
+version = "2.0.2"
 description = "Utilities for Tauri"
 exclude = ["CHANGELOG.md", "/target"]
 readme = "README.md"

+ 5 - 0
crates/tauri-utils/src/config.rs

@@ -331,6 +331,8 @@ pub struct AppImageConfig {
 pub struct DebConfig {
   /// The list of deb dependencies your application relies on.
   pub depends: Option<Vec<String>>,
+  /// The list of deb dependencies your application recommends.
+  pub recommends: Option<Vec<String>>,
   /// The list of dependencies the package provides.
   pub provides: Option<Vec<String>>,
   /// The list of package conflicts.
@@ -398,6 +400,8 @@ pub struct LinuxConfig {
 pub struct RpmConfig {
   /// The list of RPM dependencies your application relies on.
   pub depends: Option<Vec<String>>,
+  /// The list of RPM dependencies your application recommends.
+  pub recommends: Option<Vec<String>>,
   /// The list of RPM dependencies your application provides.
   pub provides: Option<Vec<String>>,
   /// The list of RPM dependencies your application conflicts with. They must not be present
@@ -442,6 +446,7 @@ impl Default for RpmConfig {
   fn default() -> Self {
     Self {
       depends: None,
+      recommends: None,
       provides: None,
       conflicts: None,
       obsoletes: None,

+ 24 - 0
crates/tauri/CHANGELOG.md

@@ -1,5 +1,29 @@
 # Changelog
 
+## \[2.0.6]
+
+### Dependencies
+
+- Upgraded to `tauri-utils@2.0.2`
+
+## \[2.0.5]
+
+### New Features
+
+- [`6cd917c22`](https://www.github.com/tauri-apps/tauri/commit/6cd917c227596e4e557496347ccae8ef579f6ea0) ([#11390](https://www.github.com/tauri-apps/tauri/pull/11390) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add new methods on `tauri::menu::MenuBuilder` and `tauri::menu::SubmenuBuilder` to create predefined menu item with specific text.
+
+### Enhancements
+
+- [`eb61d44f9`](https://www.github.com/tauri-apps/tauri/commit/eb61d44f9fc1be591c3d10a6ac1451aa39e6a77b) ([#11398](https://www.github.com/tauri-apps/tauri/pull/11398) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fallback to the Window and AppHandle resource table when closing a resource by ID.
+
+### Bug Fixes
+
+- [`e1bf6ef8c`](https://www.github.com/tauri-apps/tauri/commit/e1bf6ef8cbe3421eeaec47a222446121bcc28354) ([#11374](https://www.github.com/tauri-apps/tauri/pull/11374) by [@chrox](https://www.github.com/tauri-apps/tauri/../../chrox)) Expose `content-range` header in `range` response of `asset` protocol
+
+### What's Changed
+
+- [`2e88633ba`](https://www.github.com/tauri-apps/tauri/commit/2e88633ba4da8fc289c6d8a29c36f3327f9b576e) ([#11369](https://www.github.com/tauri-apps/tauri/pull/11369) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Remove references to no longer used `__TAURI_INTERNALS__.metadata.windows` and `__TAURI_INTERNALS__.metadata.webviews`.
+
 ## \[2.0.4]
 
 ### New Features

+ 7 - 7
crates/tauri/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "tauri"
-version = "2.0.4"
+version = "2.0.6"
 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 = "1.0"
-tauri-runtime = { version = "2.1.0", path = "../tauri-runtime" }
-tauri-macros = { version = "2.0.1", path = "../tauri-macros" }
-tauri-utils = { version = "2.0.1", features = [
+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 = [
   "resources",
 ], path = "../tauri-utils" }
-tauri-runtime-wry = { version = "2.1.1", path = "../tauri-runtime-wry", optional = true }
+tauri-runtime-wry = { version = "2.1.2", 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.1" }
-tauri-utils = { path = "../tauri-utils/", version = "2.0.1", features = [
+tauri-build = { path = "../tauri-build/", default-features = false, version = "2.0.2" }
+tauri-utils = { path = "../tauri-utils/", version = "2.0.2", features = [
   "build",
 ] }
 

文件差异内容过多而无法显示
+ 0 - 0
crates/tauri/scripts/bundle.global.js


+ 45 - 38
crates/tauri/src/ipc/authority.rs

@@ -23,7 +23,7 @@ use tauri_utils::platform::Target;
 use url::Url;
 
 use crate::{ipc::InvokeError, sealed::ManagerBase, Runtime};
-use crate::{AppHandle, Manager, StateManager};
+use crate::{AppHandle, Manager, StateManager, Webview};
 
 use super::{CommandArg, CommandItem};
 
@@ -614,6 +614,33 @@ pub struct CommandScope<T: ScopeObject> {
 }
 
 impl<T: ScopeObject> CommandScope<T> {
+  pub(crate) fn resolve<R: Runtime>(
+    webview: &Webview<R>,
+    scope_ids: Vec<u64>,
+  ) -> crate::Result<Self> {
+    let mut allow = Vec::new();
+    let mut deny = Vec::new();
+
+    for scope_id in scope_ids {
+      let scope = webview
+        .manager()
+        .runtime_authority
+        .lock()
+        .unwrap()
+        .scope_manager
+        .get_command_scope_typed::<R, T>(webview.app_handle(), &scope_id)?;
+
+      for s in scope.allows() {
+        allow.push(s.clone());
+      }
+      for s in scope.denies() {
+        deny.push(s.clone());
+      }
+    }
+
+    Ok(CommandScope { allow, deny })
+  }
+
   /// What this access scope allows.
   pub fn allows(&self) -> &Vec<Arc<T>> {
     &self.allow
@@ -698,29 +725,7 @@ impl<'a, R: Runtime, T: ScopeObject> CommandArg<'a, R> for CommandScope<T> {
         .collect::<Vec<_>>()
     });
     if let Some(scope_ids) = scope_ids {
-      let mut allow = Vec::new();
-      let mut deny = Vec::new();
-
-      for scope_id in scope_ids {
-        let scope = command
-          .message
-          .webview
-          .manager()
-          .runtime_authority
-          .lock()
-          .unwrap()
-          .scope_manager
-          .get_command_scope_typed::<R, T>(command.message.webview.app_handle(), &scope_id)?;
-
-        for s in scope.allows() {
-          allow.push(s.clone());
-        }
-        for s in scope.denies() {
-          deny.push(s.clone());
-        }
-      }
-
-      Ok(CommandScope { allow, deny })
+      CommandScope::resolve(&command.message.webview, scope_ids).map_err(Into::into)
     } else {
       Ok(CommandScope {
         allow: Default::default(),
@@ -735,6 +740,17 @@ impl<'a, R: Runtime, T: ScopeObject> CommandArg<'a, R> for CommandScope<T> {
 pub struct GlobalScope<T: ScopeObject>(ScopeValue<T>);
 
 impl<T: ScopeObject> GlobalScope<T> {
+  pub(crate) fn resolve<R: Runtime>(webview: &Webview<R>, plugin: &str) -> crate::Result<Self> {
+    webview
+      .manager()
+      .runtime_authority
+      .lock()
+      .unwrap()
+      .scope_manager
+      .get_global_scope_typed(webview.app_handle(), plugin)
+      .map(Self)
+  }
+
   /// What this access scope allows.
   pub fn allows(&self) -> &Vec<Arc<T>> {
     &self.0.allow
@@ -749,20 +765,11 @@ impl<T: ScopeObject> GlobalScope<T> {
 impl<'a, R: Runtime, T: ScopeObject> CommandArg<'a, R> for GlobalScope<T> {
   /// Grabs the [`ResolvedScope`] from the [`CommandItem`] and returns the associated [`GlobalScope`].
   fn from_command(command: CommandItem<'a, R>) -> Result<Self, InvokeError> {
-    command
-      .message
-      .webview
-      .manager()
-      .runtime_authority
-      .lock()
-      .unwrap()
-      .scope_manager
-      .get_global_scope_typed(
-        command.message.webview.app_handle(),
-        command.plugin.unwrap_or(APP_ACL_KEY),
-      )
-      .map_err(InvokeError::from_error)
-      .map(GlobalScope)
+    GlobalScope::resolve(
+      &command.message.webview,
+      command.plugin.unwrap_or(APP_ACL_KEY),
+    )
+    .map_err(InvokeError::from_error)
   }
 }
 

+ 97 - 2
crates/tauri/src/webview/mod.rs

@@ -29,8 +29,8 @@ use crate::{
   app::{UriSchemeResponder, WebviewEvent},
   event::{EmitArgs, EventTarget},
   ipc::{
-    CallbackFn, CommandArg, CommandItem, Invoke, InvokeBody, InvokeError, InvokeMessage,
-    InvokeResolver, Origin, OwnedInvokeResponder,
+    CallbackFn, CommandArg, CommandItem, CommandScope, GlobalScope, Invoke, InvokeBody,
+    InvokeError, InvokeMessage, InvokeResolver, Origin, OwnedInvokeResponder, ScopeObject,
   },
   manager::AppManager,
   sealed::{ManagerBase, RuntimeOrDispatch},
@@ -880,6 +880,83 @@ impl<R: Runtime> Webview<R> {
       .dispatcher
       .on_webview_event(move |event| f(&event.clone().into()));
   }
+
+  /// Resolves the given command scope for this webview on the currently loaded URL.
+  ///
+  /// If the command is not allowed, returns None.
+  ///
+  /// If the scope cannot be deserialized to the given type, an error is returned.
+  ///
+  /// In a command context this can be directly resolved from the command arguments via [CommandScope]:
+  ///
+  /// ```
+  /// use tauri::ipc::CommandScope;
+  ///
+  /// #[derive(Debug, serde::Deserialize)]
+  /// struct ScopeType {
+  ///   some_value: String,
+  /// }
+  /// #[tauri::command]
+  /// fn my_command(scope: CommandScope<ScopeType>) {
+  ///   // check scope
+  /// }
+  /// ```
+  ///
+  /// # Examples
+  ///
+  /// ```
+  /// use tauri::Manager;
+  ///
+  /// #[derive(Debug, serde::Deserialize)]
+  /// struct ScopeType {
+  ///   some_value: String,
+  /// }
+  ///
+  /// tauri::Builder::default()
+  ///   .setup(|app| {
+  ///     let webview = app.get_webview_window("main").unwrap();
+  ///     let scope = webview.resolve_command_scope::<ScopeType>("my-plugin", "read");
+  ///     Ok(())
+  ///   });
+  /// ```
+  pub fn resolve_command_scope<T: ScopeObject>(
+    &self,
+    plugin: &str,
+    command: &str,
+  ) -> crate::Result<Option<ResolvedScope<T>>> {
+    let current_url = self.url()?;
+    let is_local = self.is_local_url(&current_url);
+    let origin = if is_local {
+      Origin::Local
+    } else {
+      Origin::Remote { url: current_url }
+    };
+
+    let cmd_name = format!("plugin:{plugin}|{command}");
+    let resolved_access = self
+      .manager()
+      .runtime_authority
+      .lock()
+      .unwrap()
+      .resolve_access(&cmd_name, self.window().label(), self.label(), &origin);
+
+    if let Some(access) = resolved_access {
+      let scope_ids = access
+        .iter()
+        .filter_map(|cmd| cmd.scope_id)
+        .collect::<Vec<_>>();
+
+      let command_scope = CommandScope::resolve(self, scope_ids)?;
+      let global_scope = GlobalScope::resolve(self, plugin)?;
+
+      Ok(Some(ResolvedScope {
+        global_scope,
+        command_scope,
+      }))
+    } else {
+      Ok(None)
+    }
+  }
 }
 
 /// Desktop webview setters and actions.
@@ -1702,6 +1779,24 @@ impl<'de, R: Runtime> CommandArg<'de, R> for Webview<R> {
   }
 }
 
+/// Resolved scope that can be obtained via [`Webview::resolve_command_scope`].
+pub struct ResolvedScope<T: ScopeObject> {
+  command_scope: CommandScope<T>,
+  global_scope: GlobalScope<T>,
+}
+
+impl<T: ScopeObject> ResolvedScope<T> {
+  /// The global plugin scope.
+  pub fn global_scope(&self) -> &GlobalScope<T> {
+    &self.global_scope
+  }
+
+  /// The command-specific scope.
+  pub fn command_scope(&self) -> &CommandScope<T> {
+    &self.command_scope
+  }
+}
+
 #[cfg(test)]
 mod tests {
   #[test]

+ 49 - 2
crates/tauri/src/webview/webview_window.rs

@@ -12,6 +12,7 @@ use std::{
 
 use crate::{
   event::EventTarget,
+  ipc::ScopeObject,
   runtime::dpi::{PhysicalPosition, PhysicalSize},
   window::Monitor,
   Emitter, Listener, ResourceTable, Window,
@@ -48,7 +49,7 @@ use tauri_macros::default_runtime;
 #[cfg(windows)]
 use windows::Win32::Foundation::HWND;
 
-use super::DownloadEvent;
+use super::{DownloadEvent, ResolvedScope};
 
 /// A builder for [`WebviewWindow`], a window that hosts a single webview.
 pub struct WebviewWindowBuilder<'a, R: Runtime, M: Manager<R>> {
@@ -989,6 +990,52 @@ impl<R: Runtime> WebviewWindow<R> {
   pub fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) {
     self.window.on_window_event(f);
   }
+
+  /// Resolves the given command scope for this webview on the currently loaded URL.
+  ///
+  /// If the command is not allowed, returns None.
+  ///
+  /// If the scope cannot be deserialized to the given type, an error is returned.
+  ///
+  /// In a command context this can be directly resolved from the command arguments via [crate::ipc::CommandScope]:
+  ///
+  /// ```
+  /// use tauri::ipc::CommandScope;
+  ///
+  /// #[derive(Debug, serde::Deserialize)]
+  /// struct ScopeType {
+  ///   some_value: String,
+  /// }
+  /// #[tauri::command]
+  /// fn my_command(scope: CommandScope<ScopeType>) {
+  ///   // check scope
+  /// }
+  /// ```
+  ///
+  /// # Examples
+  ///
+  /// ```
+  /// use tauri::Manager;
+  ///
+  /// #[derive(Debug, serde::Deserialize)]
+  /// struct ScopeType {
+  ///   some_value: String,
+  /// }
+  ///
+  /// tauri::Builder::default()
+  ///   .setup(|app| {
+  ///     let webview = app.get_webview_window("main").unwrap();
+  ///     let scope = webview.resolve_command_scope::<ScopeType>("my-plugin", "read");
+  ///     Ok(())
+  ///   });
+  /// ```
+  pub fn resolve_command_scope<T: ScopeObject>(
+    &self,
+    plugin: &str,
+    command: &str,
+  ) -> crate::Result<Option<ResolvedScope<T>>> {
+    self.webview.resolve_command_scope(plugin, command)
+  }
 }
 
 /// Menu APIs
@@ -1038,7 +1085,7 @@ impl<R: Runtime> WebviewWindow<R> {
     self.window.on_menu_event(f)
   }
 
-  /// Returns this window menu .
+  /// Returns this window menu.
   pub fn menu(&self) -> Option<Menu<R>> {
     self.window.menu()
   }

+ 2 - 2
examples/api/src-tauri/tauri-plugin-sample/src/desktop.rs

@@ -19,10 +19,10 @@ pub struct Sample<R: Runtime>(AppHandle<R>);
 
 impl<R: Runtime> Sample<R> {
   pub fn ping(&self, payload: PingRequest) -> crate::Result<PingResponse> {
-    let _ = payload.on_event.send(Event {
+    payload.on_event.send(Event {
       kind: "ping".to_string(),
       value: payload.value.clone(),
-    });
+    })?;
     Ok(PingResponse {
       value: payload.value,
     })

+ 2 - 0
examples/api/src-tauri/tauri-plugin-sample/src/error.rs

@@ -7,6 +7,8 @@ pub enum Error {
   #[cfg(mobile)]
   #[error(transparent)]
   PluginInvoke(#[from] tauri::plugin::mobile::PluginInvokeError),
+  #[error(transparent)]
+  Tauri(#[from] tauri::Error),
 }
 
 pub type Result<T> = std::result::Result<T, Error>;

+ 10 - 0
packages/api/CHANGELOG.md

@@ -1,5 +1,15 @@
 # Changelog
 
+## \[2.0.3]
+
+### Bug Fixes
+
+- [`fbb45c674`](https://www.github.com/tauri-apps/tauri/commit/fbb45c674ca92fbbe04f1a8360e5f2e477dd4297) ([#11423](https://www.github.com/tauri-apps/tauri/pull/11423) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes `addPluginListener` not working.
+
+### What's Changed
+
+- [`2e88633ba`](https://www.github.com/tauri-apps/tauri/commit/2e88633ba4da8fc289c6d8a29c36f3327f9b576e) ([#11369](https://www.github.com/tauri-apps/tauri/pull/11369) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Remove references to no longer used `__TAURI_INTERNALS__.metadata.windows` and `__TAURI_INTERNALS__.metadata.webviews`.
+
 ## \[2.0.2]
 
 ### What's Changed

+ 1 - 1
packages/api/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@tauri-apps/api",
-  "version": "2.0.2",
+  "version": "2.0.3",
   "description": "Tauri API definitions",
   "funding": {
     "type": "opencollective",

+ 1 - 1
packages/api/src/core.ts

@@ -171,7 +171,7 @@ async function addPluginListener<T>(
 ): Promise<PluginListener> {
   const handler = new Channel<T>()
   handler.onmessage = cb
-  return invoke(`plugin:${plugin}|register_listener`, { event, handler }).then(
+  return invoke(`plugin:${plugin}|registerListener`, { event, handler }).then(
     () => new PluginListener(plugin, event, handler.id)
   )
 }

+ 11 - 0
packages/cli/CHANGELOG.md

@@ -1,5 +1,16 @@
 # Changelog
 
+## \[2.0.4]
+
+### Enhancements
+
+- [`e4c9268b1`](https://www.github.com/tauri-apps/tauri/commit/e4c9268b19c614dc9ebb0895448fd16de7efee80) ([#11258](https://www.github.com/tauri-apps/tauri/pull/11258) by [@regexident](https://www.github.com/tauri-apps/tauri/../../regexident)) Support custom project directory structure where the Tauri app folder is not a subfolder of the frontend project.
+  The frontend and Tauri app project paths can be set with the `TAURI_FRONTEND_PATH` and the `TAURI_APP_PATH` environment variables respectively.
+
+### Dependencies
+
+- Upgraded to `tauri-cli@2.0.4`
+
 ## \[2.0.3]
 
 ### New Features

+ 1 - 1
packages/cli/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@tauri-apps/cli",
-  "version": "2.0.3",
+  "version": "2.0.4",
   "description": "Command line interface for building Tauri apps",
   "funding": {
     "type": "opencollective",

部分文件因为文件数量过多而无法显示