mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-01-31 00:35:19 +01:00
Merge remote-tracking branch 'origin/dev' into feat/open-harmony
This commit is contained in:
6
.changes/CHANGES.md
Normal file
6
.changes/CHANGES.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'tauri-cli': 'minor:feat'
|
||||
'tauri-bundler': 'minor:feat'
|
||||
---
|
||||
|
||||
Add a `--no-sign` flag to the `tauri build` and `tauri bundle` commands to skip the code signing step, improving the developer experience for local testing and development without requiring code signing keys.
|
||||
6
.changes/data-dir-js.md
Normal file
6
.changes/data-dir-js.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri-utils": "minor:enhance"
|
||||
"@tauri-apps/api": "minor:enhance"
|
||||
---
|
||||
|
||||
Added a config to set a data_directory relative to the app-specific data dir in JavaScript and `tauri.conf.json`.
|
||||
6
.changes/default-log-level.md
Normal file
6
.changes/default-log-level.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@tauri-apps/cli": patch:enhance
|
||||
"tauri-cli": patch:enhance
|
||||
---
|
||||
|
||||
Set a default log level filter when running `tauri add log`.
|
||||
6
.changes/install-ios-platform.md
Normal file
6
.changes/install-ios-platform.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@tauri-apps/cli": minor:enhance
|
||||
"tauri-cli": minor:enhance
|
||||
---
|
||||
|
||||
Prompt to install the iOS platform if it isn't installed yet.
|
||||
50
Cargo.lock
generated
50
Cargo.lock
generated
@@ -1057,8 +1057,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cargo-mobile2"
|
||||
version = "0.20.4"
|
||||
source = "git+https://github.com/tauri-apps/cargo-mobile2?branch=feat/ohos#b26dda2b04c1306fb0156599d3ef0f289419e6ee"
|
||||
version = "0.20.7"
|
||||
source = "git+https://github.com/tauri-apps/cargo-mobile2?branch=feat/ohos#7e25240a471c7e17b7a77e8ef215061d19866dcc"
|
||||
dependencies = [
|
||||
"colored",
|
||||
"core-foundation 0.10.0",
|
||||
@@ -1321,7 +1321,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2388,7 +2388,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4158,9 +4158,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "jsonschema"
|
||||
version = "0.32.1"
|
||||
version = "0.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24690c68dfcdde5980d676b0f1820981841016b1f29eecb4c42ad48ab4118681"
|
||||
checksum = "d46662859bc5f60a145b75f4632fbadc84e829e45df6c5de74cfc8e05acb96b5"
|
||||
dependencies = [
|
||||
"ahash 0.8.11",
|
||||
"base64 0.22.1",
|
||||
@@ -4357,7 +4357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5457,9 +5457,9 @@ checksum = "e95bb83d997b0d7f1d04e9b2ba8874a1bd8e89dc5e88d0852a4390f8b44b0703"
|
||||
|
||||
[[package]]
|
||||
name = "ohos-web-binding"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "390cbdbe97bddcb5dcd46d52654799525ef42962cf6f360c57b4bb72597ebd61"
|
||||
checksum = "b1ed1f2ba96b92179128f6b18ea5a0dd879210e483f7dcab51200219cbfa4a58"
|
||||
dependencies = [
|
||||
"bitflags 2.7.0",
|
||||
"ohos-web-sys",
|
||||
@@ -6666,7 +6666,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"socket2",
|
||||
"tracing",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6985,9 +6985,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "referencing"
|
||||
version = "0.32.1"
|
||||
version = "0.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a3d769362109497b240e66462606bc28af68116436c8669bac17069533b908e"
|
||||
checksum = "9e9c261f7ce75418b3beadfb3f0eb1299fe8eb9640deba45ffa2cb783098697d"
|
||||
dependencies = [
|
||||
"ahash 0.8.11",
|
||||
"fluent-uri",
|
||||
@@ -7385,7 +7385,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.4.15",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7398,7 +7398,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.9.4",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8766,7 +8766,7 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||
|
||||
[[package]]
|
||||
name = "tauri"
|
||||
version = "2.8.2"
|
||||
version = "2.8.5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -8829,7 +8829,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-build"
|
||||
version = "2.4.0"
|
||||
version = "2.4.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cargo_toml",
|
||||
@@ -8852,7 +8852,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-bundler"
|
||||
version = "2.6.0"
|
||||
version = "2.6.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ar",
|
||||
@@ -8898,7 +8898,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-cli"
|
||||
version = "2.8.0"
|
||||
version = "2.8.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ar",
|
||||
@@ -9101,9 +9101,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-log"
|
||||
version = "2.4.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d2b582d860eb214f28323f4ce4f2797ae3b78f197e27b11677f976f9f52aedb"
|
||||
checksum = "a59139183e0907cec1499dddee4e085f5a801dc659efa0848ee224f461371426"
|
||||
dependencies = [
|
||||
"android_logger",
|
||||
"byte-unit",
|
||||
@@ -9158,7 +9158,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime-wry"
|
||||
version = "2.8.0"
|
||||
version = "2.8.1"
|
||||
dependencies = [
|
||||
"gtk",
|
||||
"http 1.3.1",
|
||||
@@ -9281,7 +9281,7 @@ dependencies = [
|
||||
"getrandom 0.2.15",
|
||||
"once_cell",
|
||||
"rustix 0.38.43",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -10597,7 +10597,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]]
|
||||
@@ -11229,8 +11229,8 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.53.1"
|
||||
source = "git+https://github.com/richerfu/wry#136e9a9bf3052be539889608f06e80116375ecfd"
|
||||
version = "0.53.3"
|
||||
source = "git+https://github.com/richerfu/wry#3b3762817ec6d9b84db594cf11bb6dc3b95d3244"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"block2 0.6.0",
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png",
|
||||
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png"
|
||||
)]
|
||||
// file is used by multiple binaries
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::{fs::File, io::BufReader};
|
||||
mod utils;
|
||||
|
||||
@@ -106,10 +106,9 @@ fn run_max_mem_benchmark() -> Result<HashMap<String, u64>> {
|
||||
|
||||
let proc_result = proc.wait_with_output()?;
|
||||
println!("{proc_result:?}");
|
||||
results.insert(
|
||||
name.to_string(),
|
||||
utils::parse_max_mem(benchmark_file).unwrap(),
|
||||
);
|
||||
if let Some(max_mem) = utils::parse_max_mem(benchmark_file)? {
|
||||
results.insert(name.to_string(), max_mem);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(results)
|
||||
@@ -229,7 +228,7 @@ fn run_exec_time(target_dir: &Path) -> Result<HashMap<String, HashMap<String, f6
|
||||
);
|
||||
}
|
||||
|
||||
utils::run(&command.iter().map(|s| s.as_ref()).collect::<Vec<_>>());
|
||||
utils::run(&command.iter().map(|s| s.as_ref()).collect::<Vec<_>>())?;
|
||||
|
||||
let mut results = HashMap::<String, HashMap<String, f64>>::new();
|
||||
let hyperfine_results = utils::read_json(benchmark_file)?;
|
||||
@@ -264,7 +263,7 @@ fn main() -> Result<()> {
|
||||
utils::download_file(
|
||||
"https://github.com/lemarier/tauri-test/releases/download/v2.0.0/json_3mb.json",
|
||||
json_3mb,
|
||||
);
|
||||
)?;
|
||||
}
|
||||
|
||||
println!("Starting tauri benchmark");
|
||||
@@ -278,7 +277,7 @@ fn main() -> Result<()> {
|
||||
let now = time::OffsetDateTime::now_utc();
|
||||
let mut new_data = utils::BenchResult {
|
||||
created_at: now.format(&format).unwrap(),
|
||||
sha1: utils::run_collect(&["git", "rev-parse", "HEAD"])
|
||||
sha1: utils::run_collect(&["git", "rev-parse", "HEAD"])?
|
||||
.0
|
||||
.trim()
|
||||
.to_string(),
|
||||
|
||||
@@ -2,7 +2,16 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use anyhow::Result;
|
||||
//! Utility functions for benchmarking tasks in the Tauri project.
|
||||
//!
|
||||
//! This module provides helpers for:
|
||||
//! - Paths to project directories and targets
|
||||
//! - Running and collecting process outputs
|
||||
//! - Parsing memory profiler (`mprof`) and syscall profiler (`strace`) outputs
|
||||
//! - JSON read/write utilities
|
||||
//! - File download utilities (via `curl` or file copy)
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::{
|
||||
@@ -13,6 +22,7 @@ use std::{
|
||||
process::{Command, Output, Stdio},
|
||||
};
|
||||
|
||||
/// Holds the results of a benchmark run.
|
||||
#[derive(Default, Clone, Serialize, Deserialize, Debug)]
|
||||
pub struct BenchResult {
|
||||
pub created_at: String,
|
||||
@@ -25,7 +35,7 @@ pub struct BenchResult {
|
||||
pub cargo_deps: HashMap<String, usize>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
/// Represents a single line of parsed `strace` output.
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct StraceOutput {
|
||||
pub percent_time: f64,
|
||||
@@ -35,6 +45,7 @@ pub struct StraceOutput {
|
||||
pub errors: u64,
|
||||
}
|
||||
|
||||
/// Get the compilation target triple for the current platform.
|
||||
pub fn get_target() -> &'static str {
|
||||
#[cfg(target_os = "macos")]
|
||||
return if cfg!(target_arch = "aarch64") {
|
||||
@@ -42,18 +53,22 @@ pub fn get_target() -> &'static str {
|
||||
} else {
|
||||
"x86_64-apple-darwin"
|
||||
};
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
return if cfg!(target_arch = "aarch64") {
|
||||
"aarch64-apple-ios"
|
||||
} else {
|
||||
"x86_64-apple-ios"
|
||||
};
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
return "x86_64-unknown-linux-gnu";
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
unimplemented!();
|
||||
unimplemented!("Windows target not implemented yet");
|
||||
}
|
||||
|
||||
/// Get the `target/release` directory path for benchmarks.
|
||||
pub fn target_dir() -> PathBuf {
|
||||
bench_root_path()
|
||||
.join("..")
|
||||
@@ -62,83 +77,90 @@ pub fn target_dir() -> PathBuf {
|
||||
.join("release")
|
||||
}
|
||||
|
||||
/// Get the root path of the current benchmark crate.
|
||||
pub fn bench_root_path() -> PathBuf {
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
/// Get the home directory of the current user.
|
||||
pub fn home_path() -> PathBuf {
|
||||
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "linux"))]
|
||||
return PathBuf::from(env!("HOME"));
|
||||
{
|
||||
PathBuf::from(std::env::var("HOME").unwrap_or_default())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
return PathBuf::from(env!("HOMEPATH"));
|
||||
{
|
||||
PathBuf::from(std::env::var("USERPROFILE").unwrap_or_default())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
/// Get the root path of the Tauri repository.
|
||||
pub fn tauri_root_path() -> PathBuf {
|
||||
bench_root_path().parent().unwrap().to_path_buf()
|
||||
bench_root_path().parent().map(|p| p.to_path_buf()).unwrap()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn run_collect(cmd: &[&str]) -> (String, String) {
|
||||
let mut process_builder = Command::new(cmd[0]);
|
||||
process_builder
|
||||
/// Run a command and collect its stdout and stderr as strings.
|
||||
/// Returns an error if the command fails or exits with a non-zero status.
|
||||
pub fn run_collect(cmd: &[&str]) -> Result<(String, String)> {
|
||||
let output: Output = Command::new(cmd[0])
|
||||
.args(&cmd[1..])
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped());
|
||||
let prog = process_builder.spawn().expect("failed to spawn script");
|
||||
let Output {
|
||||
stdout,
|
||||
stderr,
|
||||
status,
|
||||
} = prog.wait_with_output().expect("failed to wait on child");
|
||||
let stdout = String::from_utf8_lossy(&stdout).to_string();
|
||||
let stderr = String::from_utf8_lossy(&stderr).to_string();
|
||||
if !status.success() {
|
||||
eprintln!("stdout: <<<{stdout}>>>");
|
||||
eprintln!("stderr: <<<{stderr}>>>");
|
||||
panic!("Unexpected exit code: {:?}", status.code());
|
||||
.stderr(Stdio::piped())
|
||||
.output()
|
||||
.with_context(|| format!("failed to execute command: {cmd:?}"))?;
|
||||
|
||||
if !output.status.success() {
|
||||
bail!(
|
||||
"Command {:?} exited with {:?}\nstdout:\n{}\nstderr:\n{}",
|
||||
cmd,
|
||||
output.status.code(),
|
||||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
(stdout, stderr)
|
||||
|
||||
Ok((
|
||||
String::from_utf8_lossy(&output.stdout).to_string(),
|
||||
String::from_utf8_lossy(&output.stderr).to_string(),
|
||||
))
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn parse_max_mem(file_path: &str) -> Option<u64> {
|
||||
let file = fs::File::open(file_path).unwrap();
|
||||
/// Parse a memory profiler (`mprof`) output file and return the maximum
|
||||
/// memory usage in bytes. Returns `None` if no values are found.
|
||||
pub fn parse_max_mem(file_path: &str) -> Result<Option<u64>> {
|
||||
let file = fs::File::open(file_path)
|
||||
.with_context(|| format!("failed to open mprof output file {file_path}"))?;
|
||||
let output = BufReader::new(file);
|
||||
|
||||
let mut highest: u64 = 0;
|
||||
// MEM 203.437500 1621617192.4123
|
||||
|
||||
for line in output.lines().map_while(Result::ok) {
|
||||
// split line by space
|
||||
let split = line.split(' ').collect::<Vec<_>>();
|
||||
let split: Vec<&str> = line.split(' ').collect();
|
||||
if split.len() == 3 {
|
||||
// mprof generate result in MB
|
||||
let current_bytes = str::parse::<f64>(split[1]).unwrap() as u64 * 1024 * 1024;
|
||||
if current_bytes > highest {
|
||||
highest = current_bytes;
|
||||
if let Ok(mb) = split[1].parse::<f64>() {
|
||||
let current_bytes = (mb * 1024.0 * 1024.0) as u64;
|
||||
highest = highest.max(current_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fs::remove_file(file_path).unwrap();
|
||||
// Best-effort cleanup
|
||||
let _ = fs::remove_file(file_path);
|
||||
|
||||
if highest > 0 {
|
||||
return Some(highest);
|
||||
}
|
||||
|
||||
None
|
||||
Ok(if highest > 0 { Some(highest) } else { None })
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
/// Parse the output of `strace -c` and return a summary of syscalls.
|
||||
pub fn parse_strace_output(output: &str) -> HashMap<String, StraceOutput> {
|
||||
let mut summary = HashMap::new();
|
||||
|
||||
let mut lines = output
|
||||
.lines()
|
||||
.filter(|line| !line.is_empty() && !line.contains("detached ..."));
|
||||
let count = lines.clone().count();
|
||||
|
||||
let count = lines.clone().count();
|
||||
if count < 4 {
|
||||
return summary;
|
||||
}
|
||||
@@ -148,88 +170,90 @@ pub fn parse_strace_output(output: &str) -> HashMap<String, StraceOutput> {
|
||||
let data_lines = lines.skip(2);
|
||||
|
||||
for line in data_lines {
|
||||
let syscall_fields = line.split_whitespace().collect::<Vec<_>>();
|
||||
let syscall_fields: Vec<&str> = line.split_whitespace().collect();
|
||||
let len = syscall_fields.len();
|
||||
let syscall_name = syscall_fields.last().unwrap();
|
||||
|
||||
if (5..=6).contains(&len) {
|
||||
summary.insert(
|
||||
syscall_name.to_string(),
|
||||
StraceOutput {
|
||||
percent_time: str::parse::<f64>(syscall_fields[0]).unwrap(),
|
||||
seconds: str::parse::<f64>(syscall_fields[1]).unwrap(),
|
||||
usecs_per_call: Some(str::parse::<u64>(syscall_fields[2]).unwrap()),
|
||||
calls: str::parse::<u64>(syscall_fields[3]).unwrap(),
|
||||
errors: if syscall_fields.len() < 6 {
|
||||
if let Some(&syscall_name) = syscall_fields.last() {
|
||||
if (5..=6).contains(&len) {
|
||||
let output = StraceOutput {
|
||||
percent_time: syscall_fields[0].parse().unwrap_or(0.0),
|
||||
seconds: syscall_fields[1].parse().unwrap_or(0.0),
|
||||
usecs_per_call: syscall_fields[2].parse().ok(),
|
||||
calls: syscall_fields[3].parse().unwrap_or(0),
|
||||
errors: if len < 6 {
|
||||
0
|
||||
} else {
|
||||
str::parse::<u64>(syscall_fields[4]).unwrap()
|
||||
syscall_fields[4].parse().unwrap_or(0)
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
summary.insert(syscall_name.to_string(), output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let total_fields = total_line.split_whitespace().collect::<Vec<_>>();
|
||||
|
||||
summary.insert(
|
||||
"total".to_string(),
|
||||
match total_fields.len() {
|
||||
// Old format, has no usecs/call
|
||||
5 => StraceOutput {
|
||||
percent_time: str::parse::<f64>(total_fields[0]).unwrap(),
|
||||
seconds: str::parse::<f64>(total_fields[1]).unwrap(),
|
||||
usecs_per_call: None,
|
||||
calls: str::parse::<u64>(total_fields[2]).unwrap(),
|
||||
errors: str::parse::<u64>(total_fields[3]).unwrap(),
|
||||
},
|
||||
6 => StraceOutput {
|
||||
percent_time: str::parse::<f64>(total_fields[0]).unwrap(),
|
||||
seconds: str::parse::<f64>(total_fields[1]).unwrap(),
|
||||
usecs_per_call: Some(str::parse::<u64>(total_fields[2]).unwrap()),
|
||||
calls: str::parse::<u64>(total_fields[3]).unwrap(),
|
||||
errors: str::parse::<u64>(total_fields[4]).unwrap(),
|
||||
},
|
||||
_ => panic!("Unexpected total field count: {}", total_fields.len()),
|
||||
let total_fields: Vec<&str> = total_line.split_whitespace().collect();
|
||||
let total = match total_fields.len() {
|
||||
5 => StraceOutput {
|
||||
percent_time: total_fields[0].parse().unwrap_or(0.0),
|
||||
seconds: total_fields[1].parse().unwrap_or(0.0),
|
||||
usecs_per_call: None,
|
||||
calls: total_fields[2].parse().unwrap_or(0),
|
||||
errors: total_fields[3].parse().unwrap_or(0),
|
||||
},
|
||||
);
|
||||
6 => StraceOutput {
|
||||
percent_time: total_fields[0].parse().unwrap_or(0.0),
|
||||
seconds: total_fields[1].parse().unwrap_or(0.0),
|
||||
usecs_per_call: total_fields[2].parse().ok(),
|
||||
calls: total_fields[3].parse().unwrap_or(0),
|
||||
errors: total_fields[4].parse().unwrap_or(0),
|
||||
},
|
||||
_ => {
|
||||
panic!("Unexpected total field count: {}", total_fields.len());
|
||||
}
|
||||
};
|
||||
|
||||
summary.insert("total".to_string(), total);
|
||||
summary
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn run(cmd: &[&str]) {
|
||||
let mut process_builder = Command::new(cmd[0]);
|
||||
process_builder.args(&cmd[1..]).stdin(Stdio::piped());
|
||||
let mut prog = process_builder.spawn().expect("failed to spawn script");
|
||||
let status = prog.wait().expect("failed to wait on child");
|
||||
/// Run a command and wait for completion.
|
||||
/// Returns an error if the command fails.
|
||||
pub fn run(cmd: &[&str]) -> Result<()> {
|
||||
let status = Command::new(cmd[0])
|
||||
.args(&cmd[1..])
|
||||
.stdin(Stdio::piped())
|
||||
.status()
|
||||
.with_context(|| format!("failed to execute command: {cmd:?}"))?;
|
||||
|
||||
if !status.success() {
|
||||
panic!("Unexpected exit code: {:?}", status.code());
|
||||
bail!("Command {:?} exited with {:?}", cmd, status.code());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
/// Read a JSON file into a [`serde_json::Value`].
|
||||
pub fn read_json(filename: &str) -> Result<Value> {
|
||||
let f = fs::File::open(filename)?;
|
||||
let f =
|
||||
fs::File::open(filename).with_context(|| format!("failed to open JSON file {filename}"))?;
|
||||
Ok(serde_json::from_reader(f)?)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
/// Write a [`serde_json::Value`] into a JSON file.
|
||||
pub fn write_json(filename: &str, value: &Value) -> Result<()> {
|
||||
let f = fs::File::create(filename)?;
|
||||
let f =
|
||||
fs::File::create(filename).with_context(|| format!("failed to create JSON file {filename}"))?;
|
||||
serde_json::to_writer(f, value)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn download_file(url: &str, filename: PathBuf) {
|
||||
/// Download a file from either a local path or an HTTP/HTTPS URL.
|
||||
/// Falls back to copying the file if the URL does not start with http/https.
|
||||
pub fn download_file(url: &str, filename: PathBuf) -> Result<()> {
|
||||
if !url.starts_with("http:") && !url.starts_with("https:") {
|
||||
fs::copy(url, filename).unwrap();
|
||||
return;
|
||||
fs::copy(url, &filename).with_context(|| format!("failed to copy from {url}"))?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Downloading with curl this saves us from adding
|
||||
// a Rust HTTP client dependency.
|
||||
println!("Downloading {url}");
|
||||
let status = Command::new("curl")
|
||||
.arg("-L")
|
||||
@@ -238,8 +262,14 @@ pub fn download_file(url: &str, filename: PathBuf) {
|
||||
.arg(&filename)
|
||||
.arg(url)
|
||||
.status()
|
||||
.unwrap();
|
||||
.with_context(|| format!("failed to execute curl for {url}"))?;
|
||||
|
||||
assert!(status.success());
|
||||
assert!(filename.exists());
|
||||
if !status.success() {
|
||||
bail!("curl failed with exit code {:?}", status.code());
|
||||
}
|
||||
if !filename.exists() {
|
||||
bail!("expected file {:?} to exist after download", filename);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.4.1]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`c23bec62d`](https://www.github.com/tauri-apps/tauri/commit/c23bec62d6d5724798869681aa1534423aae28e2) ([#14083](https://www.github.com/tauri-apps/tauri/pull/14083) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Tauri now ignores `macOS.minimumSystemVersion` in `tauri dev` to prevent forced rebuilds of macOS specific dependencies when using something like `rust-analyzer` at the same time as `tauri dev`.
|
||||
|
||||
## \[2.4.0]
|
||||
|
||||
### Dependencies
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-build"
|
||||
version = "2.4.0"
|
||||
version = "2.4.1"
|
||||
description = "build time code to pair with https://crates.io/crates/tauri"
|
||||
exclude = ["CHANGELOG.md", "/target"]
|
||||
readme = "README.md"
|
||||
|
||||
@@ -577,8 +577,10 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(version) = &config.bundle.macos.minimum_system_version {
|
||||
println!("cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET={version}");
|
||||
if !is_dev() {
|
||||
if let Some(version) = &config.bundle.macos.minimum_system_version {
|
||||
println!("cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET={version}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.6.1]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`f3df96fb3`](https://www.github.com/tauri-apps/tauri/commit/f3df96fb38e2f27ce6bf232fe87f35bcfec50ce4) ([#14065](https://www.github.com/tauri-apps/tauri/pull/14065) by [@Legend-Master](https://www.github.com/tauri-apps/tauri/../../Legend-Master)) Fix binary patching updater type fails on 32 bit Windows builds
|
||||
|
||||
## \[2.6.0]
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-bundler"
|
||||
version = "2.6.0"
|
||||
version = "2.6.1"
|
||||
authors = [
|
||||
"George Burton <burtonageo@gmail.com>",
|
||||
"Tauri Programme within The Commons Conservancy",
|
||||
|
||||
@@ -85,41 +85,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<Bundle>> {
|
||||
}
|
||||
|
||||
// Sign windows binaries before the bundling step in case neither wix and nsis bundles are enabled
|
||||
if matches!(target_os, TargetPlatform::Windows) {
|
||||
if settings.can_sign() {
|
||||
for bin in settings.binaries() {
|
||||
if bin.main() {
|
||||
// we will sign the main binary after patching per "package type"
|
||||
continue;
|
||||
}
|
||||
let bin_path = settings.binary_path(bin);
|
||||
windows::sign::try_sign(&bin_path, settings)?;
|
||||
}
|
||||
|
||||
// Sign the sidecar binaries
|
||||
for bin in settings.external_binaries() {
|
||||
let path = bin?;
|
||||
let skip = std::env::var("TAURI_SKIP_SIDECAR_SIGNATURE_CHECK").is_ok_and(|v| v == "true");
|
||||
if skip {
|
||||
continue;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
if windows::sign::verify(&path)? {
|
||||
log::info!(
|
||||
"sidecar at \"{}\" already signed. Skipping...",
|
||||
path.display()
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
windows::sign::try_sign(&path, settings)?;
|
||||
}
|
||||
} else {
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
log::warn!("Signing, by default, is only supported on Windows hosts, but you can specify a custom signing command in `bundler > windows > sign_command`, for now, skipping signing the installer...");
|
||||
}
|
||||
}
|
||||
sign_binaries_if_needed(settings, target_os)?;
|
||||
|
||||
let main_binary = settings
|
||||
.binaries()
|
||||
@@ -134,8 +100,9 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<Bundle>> {
|
||||
// - codesigning tools should handle calculating+updating this, we just need to ensure
|
||||
// (re)signing is performed after every `patch_binary()` operation
|
||||
// - signing an already-signed binary can result in multiple signatures, causing verification errors
|
||||
let main_binary_reset_required =
|
||||
matches!(target_os, TargetPlatform::Windows) && settings.can_sign() && package_types.len() > 1;
|
||||
let main_binary_reset_required = matches!(target_os, TargetPlatform::Windows)
|
||||
&& settings.windows().can_sign()
|
||||
&& package_types.len() > 1;
|
||||
let mut unsigned_main_binary_copy = tempfile::tempfile()?;
|
||||
if main_binary_reset_required {
|
||||
let mut unsigned_main_binary = std::fs::File::open(&main_binary_path)?;
|
||||
@@ -155,7 +122,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<Bundle>> {
|
||||
}
|
||||
|
||||
// sign main binary for every package type after patch
|
||||
if matches!(target_os, TargetPlatform::Windows) && settings.can_sign() {
|
||||
if matches!(target_os, TargetPlatform::Windows) && settings.windows().can_sign() {
|
||||
if main_binary_signed && main_binary_reset_required {
|
||||
let mut signed_main_binary = std::fs::OpenOptions::new()
|
||||
.write(true)
|
||||
@@ -305,6 +272,51 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<Bundle>> {
|
||||
Ok(bundles)
|
||||
}
|
||||
|
||||
fn sign_binaries_if_needed(settings: &Settings, target_os: &TargetPlatform) -> crate::Result<()> {
|
||||
if matches!(target_os, TargetPlatform::Windows) {
|
||||
if settings.windows().can_sign() {
|
||||
if settings.no_sign() {
|
||||
log::info!("Skipping binary signing due to --no-sign flag.");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
for bin in settings.binaries() {
|
||||
if bin.main() {
|
||||
// we will sign the main binary after patching per "package type"
|
||||
continue;
|
||||
}
|
||||
let bin_path = settings.binary_path(bin);
|
||||
windows::sign::try_sign(&bin_path, settings)?;
|
||||
}
|
||||
|
||||
// Sign the sidecar binaries
|
||||
for bin in settings.external_binaries() {
|
||||
let path = bin?;
|
||||
let skip = std::env::var("TAURI_SKIP_SIDECAR_SIGNATURE_CHECK").is_ok_and(|v| v == "true");
|
||||
if skip {
|
||||
continue;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
if windows::sign::verify(&path)? {
|
||||
log::info!(
|
||||
"sidecar at \"{}\" already signed. Skipping...",
|
||||
path.display()
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
windows::sign::try_sign(&path, settings)?;
|
||||
}
|
||||
} else {
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
log::warn!("Signing, by default, is only supported on Windows hosts, but you can specify a custom signing command in `bundler > windows > sign_command`, for now, skipping signing the installer...");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check to see if there are icons in the settings struct
|
||||
pub fn check_icons(settings: &Settings) -> crate::Result<bool> {
|
||||
// make a peekable iterator of the icon_files
|
||||
|
||||
@@ -103,7 +103,11 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
|
||||
|
||||
copy_custom_files_to_bundle(&bundle_directory, settings)?;
|
||||
|
||||
if let Some(keychain) = super::sign::keychain(settings.macos().signing_identity.as_deref())? {
|
||||
if settings.no_sign() {
|
||||
log::warn!("Skipping signing due to --no-sign flag.",);
|
||||
} else if let Some(keychain) =
|
||||
super::sign::keychain(settings.macos().signing_identity.as_deref())?
|
||||
{
|
||||
// Sign frameworks and sidecar binaries first, per apple, signing must be done inside out
|
||||
// https://developer.apple.com/forums/thread/701514
|
||||
sign_paths.push(SignTarget {
|
||||
|
||||
@@ -195,7 +195,7 @@ pub fn bundle_project(settings: &Settings, bundles: &[Bundle]) -> crate::Result<
|
||||
// Sign DMG if needed
|
||||
// skipping self-signing DMGs https://github.com/tauri-apps/tauri/issues/12288
|
||||
let identity = settings.macos().signing_identity.as_deref();
|
||||
if identity != Some("-") {
|
||||
if !settings.no_sign() && identity != Some("-") {
|
||||
if let Some(keychain) = super::sign::keychain(identity)? {
|
||||
super::sign::sign(
|
||||
&keychain,
|
||||
|
||||
@@ -572,6 +572,12 @@ pub struct WindowsSettings {
|
||||
pub sign_command: Option<CustomSignCommandSettings>,
|
||||
}
|
||||
|
||||
impl WindowsSettings {
|
||||
pub(crate) fn can_sign(&self) -> bool {
|
||||
self.sign_command.is_some() || self.certificate_thumbprint.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
mod _default {
|
||||
use super::*;
|
||||
@@ -778,6 +784,8 @@ pub struct Settings {
|
||||
target_platform: TargetPlatform,
|
||||
/// The target triple.
|
||||
target: String,
|
||||
/// Whether to disable code signing during the bundling process.
|
||||
no_sign: bool,
|
||||
}
|
||||
|
||||
/// A builder for [`Settings`].
|
||||
@@ -791,6 +799,7 @@ pub struct SettingsBuilder {
|
||||
binaries: Vec<BundleBinary>,
|
||||
target: Option<String>,
|
||||
local_tools_directory: Option<PathBuf>,
|
||||
no_sign: bool,
|
||||
}
|
||||
|
||||
impl SettingsBuilder {
|
||||
@@ -860,6 +869,13 @@ impl SettingsBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether to skip code signing.
|
||||
#[must_use]
|
||||
pub fn no_sign(mut self, no_sign: bool) -> Self {
|
||||
self.no_sign = no_sign;
|
||||
self
|
||||
}
|
||||
|
||||
/// Builds a Settings from the CLI args.
|
||||
///
|
||||
/// Package settings will be read from Cargo.toml.
|
||||
@@ -894,6 +910,7 @@ impl SettingsBuilder {
|
||||
},
|
||||
target_platform,
|
||||
target,
|
||||
no_sign: self.no_sign,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1242,4 +1259,14 @@ impl Settings {
|
||||
pub fn updater(&self) -> Option<&UpdaterSettings> {
|
||||
self.bundle_settings.updater.as_ref()
|
||||
}
|
||||
|
||||
/// Whether to skip signing.
|
||||
pub fn no_sign(&self) -> bool {
|
||||
self.no_sign
|
||||
}
|
||||
|
||||
/// Set whether to skip signing.
|
||||
pub fn set_no_sign(&mut self, no_sign: bool) {
|
||||
self.no_sign = no_sign;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,7 +470,7 @@ pub fn build_wix_app_installer(
|
||||
fs::create_dir_all(&output_path)?;
|
||||
|
||||
// when we're performing code signing, we'll sign some WiX DLLs, so we make a local copy
|
||||
let wix_toolset_path = if settings.can_sign() {
|
||||
let wix_toolset_path = if settings.windows().can_sign() {
|
||||
let wix_path = output_path.join("wix");
|
||||
crate::utils::fs_utils::copy_dir(wix_toolset_path, &wix_path)
|
||||
.context("failed to copy wix directory")?;
|
||||
@@ -771,7 +771,7 @@ pub fn build_wix_app_installer(
|
||||
let mut extensions = Vec::new();
|
||||
for cap in extension_regex.captures_iter(&fragment) {
|
||||
let path = wix_toolset_path.join(format!("Wix{}.dll", &cap[1]));
|
||||
if settings.can_sign() {
|
||||
if settings.windows().can_sign() {
|
||||
try_sign(&path, settings)?;
|
||||
}
|
||||
extensions.push(path);
|
||||
@@ -785,7 +785,7 @@ pub fn build_wix_app_installer(
|
||||
fragment_extensions.insert(wix_toolset_path.join("WixUtilExtension.dll"));
|
||||
|
||||
// sign default extensions
|
||||
if settings.can_sign() {
|
||||
if settings.windows().can_sign() {
|
||||
for path in &fragment_extensions {
|
||||
try_sign(path, settings)?;
|
||||
}
|
||||
@@ -879,7 +879,7 @@ pub fn build_wix_app_installer(
|
||||
)?;
|
||||
fs::rename(&msi_output_path, &msi_path)?;
|
||||
|
||||
if settings.can_sign() {
|
||||
if settings.windows().can_sign() {
|
||||
try_sign(&msi_path, settings)?;
|
||||
}
|
||||
|
||||
@@ -988,7 +988,7 @@ fn generate_resource_data(settings: &Settings) -> crate::Result<ResourceMap> {
|
||||
}
|
||||
added_resources.push(resource_path.clone());
|
||||
|
||||
if settings.can_sign() && should_sign(&resource_path)? {
|
||||
if settings.windows().can_sign() && should_sign(&resource_path)? {
|
||||
try_sign(&resource_path, settings)?;
|
||||
}
|
||||
|
||||
@@ -1076,7 +1076,7 @@ fn generate_resource_data(settings: &Settings) -> crate::Result<ResourceMap> {
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
if !added_resources.iter().any(|r| r.ends_with(&relative_path)) {
|
||||
if settings.can_sign() {
|
||||
if settings.windows().can_sign() {
|
||||
try_sign(resource_path, settings)?;
|
||||
}
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ fn build_nsis_app_installer(
|
||||
|
||||
// we make a copy of the NSIS directory if we're going to sign its DLLs
|
||||
// because we don't want to change the DLL hashes so the cache can reuse it
|
||||
let maybe_plugin_copy_path = if settings.can_sign() {
|
||||
let maybe_plugin_copy_path = if settings.windows().can_sign() {
|
||||
// find nsis path
|
||||
#[cfg(target_os = "linux")]
|
||||
let system_nsis_toolset_path = std::env::var_os("NSIS_PATH")
|
||||
@@ -283,7 +283,7 @@ fn build_nsis_app_installer(
|
||||
);
|
||||
data.insert("copyright", to_json(settings.copyright_string()));
|
||||
|
||||
if settings.can_sign() {
|
||||
if settings.windows().can_sign() {
|
||||
let sign_cmd = format!("{:?}", sign_command("%1", &settings.sign_params())?);
|
||||
data.insert("uninstaller_sign_cmd", to_json(sign_cmd));
|
||||
}
|
||||
@@ -600,7 +600,7 @@ fn build_nsis_app_installer(
|
||||
));
|
||||
fs::create_dir_all(nsis_installer_path.parent().unwrap())?;
|
||||
|
||||
if settings.can_sign() {
|
||||
if settings.windows().can_sign() {
|
||||
log::info!("Signing NSIS plugins");
|
||||
for dll in NSIS_PLUGIN_FILES {
|
||||
let path = additional_plugins_path.join(dll);
|
||||
@@ -640,7 +640,7 @@ fn build_nsis_app_installer(
|
||||
|
||||
fs::rename(nsis_output_path, &nsis_installer_path)?;
|
||||
|
||||
if settings.can_sign() {
|
||||
if settings.windows().can_sign() {
|
||||
try_sign(&nsis_installer_path, settings)?;
|
||||
} else {
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
@@ -718,7 +718,7 @@ fn generate_resource_data(settings: &Settings) -> crate::Result<ResourcesMap> {
|
||||
let loader_path =
|
||||
dunce::simplified(&settings.project_out_directory().join("WebView2Loader.dll")).to_path_buf();
|
||||
if loader_path.exists() {
|
||||
if settings.can_sign() {
|
||||
if settings.windows().can_sign() {
|
||||
try_sign(&loader_path, settings)?;
|
||||
}
|
||||
added_resources.push(loader_path.clone());
|
||||
@@ -743,7 +743,7 @@ fn generate_resource_data(settings: &Settings) -> crate::Result<ResourcesMap> {
|
||||
}
|
||||
added_resources.push(resource_path.clone());
|
||||
|
||||
if settings.can_sign() && should_sign(&resource_path)? {
|
||||
if settings.windows().can_sign() && should_sign(&resource_path)? {
|
||||
try_sign(&resource_path, settings)?;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,10 +14,6 @@ use std::sync::OnceLock;
|
||||
use std::{path::Path, process::Command};
|
||||
|
||||
impl Settings {
|
||||
pub(crate) fn can_sign(&self) -> bool {
|
||||
self.windows().sign_command.is_some() || self.windows().certificate_thumbprint.is_some()
|
||||
}
|
||||
|
||||
pub(crate) fn sign_params(&self) -> SignParams {
|
||||
SignParams {
|
||||
product_name: self.product_name().into(),
|
||||
@@ -251,7 +247,14 @@ pub fn sign<P: AsRef<Path>>(path: P, params: &SignParams) -> crate::Result<()> {
|
||||
}
|
||||
|
||||
pub fn try_sign<P: AsRef<Path>>(file_path: P, settings: &Settings) -> crate::Result<()> {
|
||||
if settings.can_sign() {
|
||||
if settings.no_sign() {
|
||||
log::warn!(
|
||||
"Skipping signing for {} due to --no-sign flag.",
|
||||
tauri_utils::display_path(file_path.as_ref())
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
if settings.windows().can_sign() {
|
||||
log::info!(action = "Signing"; "{}", tauri_utils::display_path(file_path.as_ref()));
|
||||
sign(file_path, &settings.sign_params())?;
|
||||
}
|
||||
|
||||
@@ -100,17 +100,16 @@ pub fn patch_binary(binary_path: &PathBuf, package_type: &crate::PackageType) ->
|
||||
.ok_or(crate::Error::MissingBundleTypeVar)?;
|
||||
|
||||
let data_offset = tauri_bundle_section.pointer_to_raw_data as usize;
|
||||
|
||||
if data_offset + 8 > file_data.len() {
|
||||
return Err(crate::Error::BinaryOffsetOutOfRange);
|
||||
}
|
||||
|
||||
let ptr_bytes = &file_data[data_offset..data_offset + 8];
|
||||
let ptr_value = u64::from_le_bytes(ptr_bytes.try_into().map_err(|_| {
|
||||
crate::Error::BinaryParseError(
|
||||
std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid pointer bytes").into(),
|
||||
)
|
||||
})?);
|
||||
let pointer_size = if pe.is_64 { 8 } else { 4 };
|
||||
let ptr_bytes = file_data
|
||||
.get(data_offset..data_offset + pointer_size)
|
||||
.ok_or(crate::Error::BinaryOffsetOutOfRange)?;
|
||||
// `try_into` is safe to `unwrap` here because we have already checked the slice's size through `get`
|
||||
let ptr_value = if pe.is_64 {
|
||||
u64::from_le_bytes(ptr_bytes.try_into().unwrap())
|
||||
} else {
|
||||
u32::from_le_bytes(ptr_bytes.try_into().unwrap()).into()
|
||||
};
|
||||
|
||||
let rdata_section = pe
|
||||
.sections
|
||||
@@ -133,12 +132,10 @@ pub fn patch_binary(binary_path: &PathBuf, package_type: &crate::PackageType) ->
|
||||
let file_offset = rdata_section.pointer_to_raw_data as usize
|
||||
+ (rva as usize).saturating_sub(rdata_section.virtual_address as usize);
|
||||
|
||||
if file_offset + 3 > file_data.len() {
|
||||
return Err(crate::Error::BinaryOffsetOutOfRange);
|
||||
}
|
||||
|
||||
// Overwrite the string at that offset
|
||||
let string_bytes = &mut file_data[file_offset..file_offset + 3];
|
||||
let string_bytes = file_data
|
||||
.get_mut(file_offset..file_offset + 3)
|
||||
.ok_or(crate::Error::BinaryOffsetOutOfRange)?;
|
||||
match package_type {
|
||||
crate::PackageType::Nsis => string_bytes.copy_from_slice(b"NSS"),
|
||||
crate::PackageType::WindowsMsi => string_bytes.copy_from_slice(b"MSI"),
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.8.4]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`f70b28529`](https://www.github.com/tauri-apps/tauri/commit/f70b28529d226a2dec2f41709d8934f8f5adab25) ([#14093](https://www.github.com/tauri-apps/tauri/pull/14093) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Ensure Rust targets for mobile are installed when running the dev and build commands (previously only checked on init).
|
||||
- [`a9b342125`](https://www.github.com/tauri-apps/tauri/commit/a9b342125d5ac1bc9a4b2e8b5f73e8ca3cbcb8b2) ([#14114](https://www.github.com/tauri-apps/tauri/pull/14114) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix iOS dev and build targeting the simulator on Intel machines.
|
||||
- [`61b9b681e`](https://www.github.com/tauri-apps/tauri/commit/61b9b681e88067a53b79d2318ae005dc25addcd6) ([#14111](https://www.github.com/tauri-apps/tauri/pull/14111) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Retain `RUST_*` environment variables when running the mobile commands.
|
||||
- [`c23bec62d`](https://www.github.com/tauri-apps/tauri/commit/c23bec62d6d5724798869681aa1534423aae28e2) ([#14083](https://www.github.com/tauri-apps/tauri/pull/14083) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Tauri now ignores `macOS.minimumSystemVersion` in `tauri dev` to prevent forced rebuilds of macOS specific dependencies when using something like `rust-analyzer` at the same time as `tauri dev`.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`c37a29833`](https://www.github.com/tauri-apps/tauri/commit/c37a298331d6d744b15d32d55a2db83c884a3d6a) ([#14112](https://www.github.com/tauri-apps/tauri/pull/14112) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix usage with Deno failing with `ReferenceError: require is not defined`.
|
||||
- [`bcf000c0a`](https://www.github.com/tauri-apps/tauri/commit/bcf000c0a8607eedf488fb949b982f519abda43d) ([#14110](https://www.github.com/tauri-apps/tauri/pull/14110) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes running `ios` commands with `deno` crashing due to incorrect current working directory resolution.
|
||||
- [`7db7142f9`](https://www.github.com/tauri-apps/tauri/commit/7db7142f9ff7dc2f5719602e199b77129ceb19d3) ([#14119](https://www.github.com/tauri-apps/tauri/pull/14119) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes empty device name when using an Android emulator causing the emulator to never be detected as running.
|
||||
- [`956b4fd6f`](https://www.github.com/tauri-apps/tauri/commit/956b4fd6ffbb4312123b107ca96c87a001359b9d) ([#14106](https://www.github.com/tauri-apps/tauri/pull/14106) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Use the correct export method on Xcode < 15.4.
|
||||
|
||||
## \[2.8.3]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`0ac89d3b6`](https://www.github.com/tauri-apps/tauri/commit/0ac89d3b6c8c4a4826a4c42726e4f4a8941b3fde) ([#14078](https://www.github.com/tauri-apps/tauri/pull/14078) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Updated `cargo-mobile2` to allow running on iOS simulators that have a higher version than the XCode SDK. This fixes compatiblity issues with Apple's recent "iOS 18.5 + iOS 18.6 Simulator" platform support component.
|
||||
|
||||
## \[2.8.1]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-bundler@2.6.1`
|
||||
|
||||
## \[2.8.0]
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-cli"
|
||||
version = "2.8.0"
|
||||
version = "2.8.4"
|
||||
authors = ["Tauri Programme within The Commons Conservancy"]
|
||||
edition = "2021"
|
||||
rust-version = "1.77.2"
|
||||
@@ -36,7 +36,7 @@ name = "cargo-tauri"
|
||||
path = "src/main.rs"
|
||||
|
||||
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\", target_os = \"windows\", target_os = \"macos\"))".dependencies]
|
||||
cargo-mobile2 = { version = "0.20.2", default-features = false }
|
||||
cargo-mobile2 = { version = "0.20.6", default-features = false }
|
||||
|
||||
[dependencies]
|
||||
jsonrpsee = { version = "0.24", features = ["server"] }
|
||||
@@ -47,7 +47,7 @@ sublime_fuzzy = "0.7"
|
||||
clap_complete = "4"
|
||||
clap = { version = "4", features = ["derive", "env"] }
|
||||
anyhow = "1"
|
||||
tauri-bundler = { version = "2.6.0", default-features = false, path = "../tauri-bundler" }
|
||||
tauri-bundler = { version = "2.6.1", default-features = false, path = "../tauri-bundler" }
|
||||
colored = "2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = { version = "1", features = ["preserve_order"] }
|
||||
@@ -66,7 +66,7 @@ tauri-utils = { version = "2.7.0", path = "../tauri-utils", features = [
|
||||
"html-manipulation",
|
||||
] }
|
||||
toml = "0.9"
|
||||
jsonschema = "0.32"
|
||||
jsonschema = "0.33"
|
||||
handlebars = "6"
|
||||
include_dir = "0.7"
|
||||
minisign = "=0.7.3"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://schema.tauri.app/config/2.8.2",
|
||||
"$id": "https://schema.tauri.app/config/2.8.5",
|
||||
"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\": \"http://localhost:3000\",\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",
|
||||
@@ -164,7 +164,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"windows": {
|
||||
"description": "The app windows configuration.",
|
||||
"description": "The app windows configuration.\n\n ## Example:\n\n To create a window at app startup\n\n ```json\n {\n \"app\": {\n \"windows\": [\n { \"width\": 800, \"height\": 600 }\n ]\n }\n }\n ```\n\n If not specified, the window's label (its identifier) defaults to \"main\",\n you can use this label to get the window through\n `app.get_webview_window` in Rust or `WebviewWindow.getByLabel` in JavaScript\n\n When working with multiple windows, each window will need an unique label\n\n ```json\n {\n \"app\": {\n \"windows\": [\n { \"label\": \"main\", \"width\": 800, \"height\": 600 },\n { \"label\": \"secondary\", \"width\": 800, \"height\": 600 }\n ]\n }\n }\n ```\n\n You can also set `create` to false and use this config through the Rust APIs\n\n ```json\n {\n \"app\": {\n \"windows\": [\n { \"create\": false, \"width\": 800, \"height\": 600 }\n ]\n }\n }\n ```\n\n and use it like this\n\n ```rust\n tauri::Builder::default()\n .setup(|app| {\n tauri::WebviewWindowBuilder::from_config(app.handle(), app.config().app.windows[0])?.build()?;\n Ok(())\n });\n ```",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -230,7 +230,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"create": {
|
||||
"description": "Whether Tauri should create this window at app startup or not.\n\n When this is set to `false` you must manually grab the config object via `app.config().app.windows`\n and create it with [`WebviewWindowBuilder::from_config`](https://docs.rs/tauri/2/tauri/webview/struct.WebviewWindowBuilder.html#method.from_config).",
|
||||
"description": "Whether Tauri should create this window at app startup or not.\n\n When this is set to `false` you must manually grab the config object via `app.config().app.windows`\n and create it with [`WebviewWindowBuilder::from_config`](https://docs.rs/tauri/2/tauri/webview/struct.WebviewWindowBuilder.html#method.from_config).\n\n ## Example:\n\n ```rust\n tauri::Builder::default()\n .setup(|app| {\n tauri::WebviewWindowBuilder::from_config(app.handle(), app.config().app.windows[0])?.build()?;\n Ok(())\n });\n ```",
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
@@ -495,7 +495,7 @@
|
||||
]
|
||||
},
|
||||
"incognito": {
|
||||
"description": "Whether or not the webview should be launched in incognito mode.\n\n ## Platform-specific:\n\n - **Android**: Unsupported.",
|
||||
"description": "Whether or not the webview should be launched in incognito mode.\n\n ## Platform-specific:\n\n - **Android**: Unsupported.",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
@@ -572,6 +572,27 @@
|
||||
"description": "Allows disabling the input accessory view on iOS.\n\n The accessory view is the view that appears above the keyboard when a text input element is focused.\n It usually displays a view with \"Done\", \"Next\" buttons.",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"dataDirectory": {
|
||||
"description": "Set a custom path for the webview's data directory (localStorage, cache, etc.) **relative to [`appDataDir()`]/${label}**.\n\n To set absolute paths, use [`WebviewWindowBuilder::data_directory`](https://docs.rs/tauri/2/tauri/webview/struct.WebviewWindowBuilder.html#method.data_directory)\n\n #### Platform-specific:\n\n - **Windows**: WebViews with different values for settings like `additionalBrowserArgs`, `browserExtensionsEnabled` or `scrollBarStyle` must have different data directories.\n - **macOS / iOS**: Unsupported, use `dataStoreIdentifier` instead.\n - **Android**: Unsupported.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"dataStoreIdentifier": {
|
||||
"description": "Initialize the WebView with a custom data store identifier. This can be seen as a replacement for `dataDirectory` which is unavailable in WKWebView.\n See https://developer.apple.com/documentation/webkit/wkwebsitedatastore/init(foridentifier:)?language=objc\n\n The array must contain 16 u8 numbers.\n\n #### Platform-specific:\n\n - **iOS**: Supported since version 17.0+.\n - **macOS**: Supported since version 14.0+.\n - **Windows / Linux / Android**: Unsupported.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "uint8",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"maxItems": 16,
|
||||
"minItems": 16
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
@@ -2078,7 +2099,7 @@
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"description": "App resources to bundle.\n Each resource is a path to a file or directory.\n Glob patterns are supported.",
|
||||
"description": "App resources to bundle.\n Each resource is a path to a file or directory.\n Glob patterns are supported.\n\n ## Examples\n\n To include a list of files:\n\n ```json\n {\n \"bundle\": {\n \"resources\": [\n \"./path/to/some-file.txt\",\n \"/absolute/path/to/textfile.txt\",\n \"../relative/path/to/jsonfile.json\",\n \"some-folder/\",\n \"resources/**/*.md\"\n ]\n }\n }\n ```\n\n The bundled files will be in `$RESOURCES/` with the original directory structure preserved,\n for example: `./path/to/some-file.txt` -> `$RESOURCE/path/to/some-file.txt`\n\n To fine control where the files will get copied to, use a map instead\n\n ```json\n {\n \"bundle\": {\n \"resources\": {\n \"/absolute/path/to/textfile.txt\": \"resources/textfile.txt\",\n \"relative/path/to/jsonfile.json\": \"resources/jsonfile.json\",\n \"resources/\": \"\",\n \"docs/**/*md\": \"website-docs/\"\n }\n }\n }\n ```\n\n Note that when using glob pattern in this case, the original directory structure is not preserved,\n everything gets copied to the target directory directly\n\n See more: <https://v2.tauri.app/develop/resources/>",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/BundleResources"
|
||||
@@ -2928,7 +2949,7 @@
|
||||
]
|
||||
},
|
||||
"installerHooks": {
|
||||
"description": "A path to a `.nsh` file that contains special NSIS macros to be hooked into the\n main installer.nsi script.\n\n Supported hooks are:\n - `NSIS_HOOK_PREINSTALL`: This hook runs before copying files, setting registry key values and creating shortcuts.\n - `NSIS_HOOK_POSTINSTALL`: This hook runs after the installer has finished copying all files, setting the registry keys and created shortcuts.\n - `NSIS_HOOK_PREUNINSTALL`: This hook runs before removing any files, registry keys and shortcuts.\n - `NSIS_HOOK_POSTUNINSTALL`: This hook runs after files, registry keys and shortcuts have been removed.\n\n\n ### Example\n\n ```nsh\n !macro NSIS_HOOK_PREINSTALL\n MessageBox MB_OK \"PreInstall\"\n !macroend\n\n !macro NSIS_HOOK_POSTINSTALL\n MessageBox MB_OK \"PostInstall\"\n !macroend\n\n !macro NSIS_HOOK_PREUNINSTALL\n MessageBox MB_OK \"PreUnInstall\"\n !macroend\n\n !macro NSIS_HOOK_POSTUNINSTALL\n MessageBox MB_OK \"PostUninstall\"\n !macroend\n\n ```",
|
||||
"description": "A path to a `.nsh` file that contains special NSIS macros to be hooked into the\n main installer.nsi script.\n\n Supported hooks are:\n\n - `NSIS_HOOK_PREINSTALL`: This hook runs before copying files, setting registry key values and creating shortcuts.\n - `NSIS_HOOK_POSTINSTALL`: This hook runs after the installer has finished copying all files, setting the registry keys and created shortcuts.\n - `NSIS_HOOK_PREUNINSTALL`: This hook runs before removing any files, registry keys and shortcuts.\n - `NSIS_HOOK_POSTUNINSTALL`: This hook runs after files, registry keys and shortcuts have been removed.\n\n ### Example\n\n ```nsh\n !macro NSIS_HOOK_PREINSTALL\n MessageBox MB_OK \"PreInstall\"\n !macroend\n\n !macro NSIS_HOOK_POSTINSTALL\n MessageBox MB_OK \"PostInstall\"\n !macroend\n\n !macro NSIS_HOOK_PREUNINSTALL\n MessageBox MB_OK \"PreUnInstall\"\n !macroend\n\n !macro NSIS_HOOK_POSTUNINSTALL\n MessageBox MB_OK \"PostUninstall\"\n !macroend\n ```",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
@@ -3490,7 +3511,7 @@
|
||||
]
|
||||
},
|
||||
"minimumSystemVersion": {
|
||||
"description": "A version string indicating the minimum macOS X version that the bundled application supports. Defaults to `10.13`.\n\n Setting it to `null` completely removes the `LSMinimumSystemVersion` field on the bundle's `Info.plist`\n and the `MACOSX_DEPLOYMENT_TARGET` environment variable.\n\n An empty string is considered an invalid value so the default value is used.",
|
||||
"description": "A version string indicating the minimum macOS X version that the bundled application supports. Defaults to `10.13`.\n\n Setting it to `null` completely removes the `LSMinimumSystemVersion` field on the bundle's `Info.plist`\n and the `MACOSX_DEPLOYMENT_TARGET` environment variable.\n\n Ignored in `tauri dev`.\n\n An empty string is considered an invalid value so the default value is used.",
|
||||
"default": "10.13",
|
||||
"type": [
|
||||
"string",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"cli.js": {
|
||||
"version": "2.8.1",
|
||||
"version": "2.8.4",
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"tauri": "2.8.2",
|
||||
"tauri-build": "2.4.0",
|
||||
"tauri": "2.8.5",
|
||||
"tauri-build": "2.4.1",
|
||||
"tauri-plugin": "2.4.0"
|
||||
}
|
||||
|
||||
@@ -132,6 +132,8 @@ pub fn run(options: Options) -> Result<()> {
|
||||
"Builder::new(todo!()).build()"
|
||||
} else if plugin == "single-instance" {
|
||||
"init(|app, args, cwd| {})"
|
||||
} else if plugin == "log" {
|
||||
"Builder::new().level(tauri_plugin_log::log::LevelFilter::Info).build()"
|
||||
} else if metadata.builder {
|
||||
"Builder::new().build()"
|
||||
} else {
|
||||
|
||||
@@ -76,11 +76,18 @@ pub struct Options {
|
||||
/// Only use this when you are sure the mismatch is incorrectly detected as version mismatched Tauri packages can lead to unknown behavior.
|
||||
#[clap(long)]
|
||||
pub ignore_version_mismatches: bool,
|
||||
/// Skip code signing when bundling the app
|
||||
#[clap(long)]
|
||||
pub no_sign: bool,
|
||||
}
|
||||
|
||||
pub fn command(mut options: Options, verbosity: u8) -> Result<()> {
|
||||
crate::helpers::app_paths::resolve();
|
||||
|
||||
if options.no_sign {
|
||||
log::warn!("--no-sign flag detected: Signing will be skipped.");
|
||||
}
|
||||
|
||||
let ci = options.ci;
|
||||
|
||||
let target = options
|
||||
@@ -104,6 +111,10 @@ pub fn command(mut options: Options, verbosity: u8) -> Result<()> {
|
||||
let config_guard = config.lock().unwrap();
|
||||
let config_ = config_guard.as_ref().unwrap();
|
||||
|
||||
if let Some(minimum_system_version) = &config_.bundle.macos.minimum_system_version {
|
||||
std::env::set_var("MACOSX_DEPLOYMENT_TARGET", minimum_system_version);
|
||||
}
|
||||
|
||||
let app_settings = interface.app_settings();
|
||||
let interface_options = options.clone().into();
|
||||
|
||||
|
||||
@@ -92,6 +92,14 @@ pub struct Options {
|
||||
/// On subsequent runs, it's recommended to disable this setting again.
|
||||
#[clap(long)]
|
||||
pub skip_stapling: bool,
|
||||
|
||||
/// Skip code signing during the build or bundling process.
|
||||
///
|
||||
/// Useful for local development and CI environments
|
||||
/// where signing certificates or environment variables
|
||||
/// are not available or not needed.
|
||||
#[clap(long)]
|
||||
pub no_sign: bool,
|
||||
}
|
||||
|
||||
impl From<crate::build::Options> for Options {
|
||||
@@ -104,6 +112,7 @@ impl From<crate::build::Options> for Options {
|
||||
ci: value.ci,
|
||||
config: value.config,
|
||||
skip_stapling: value.skip_stapling,
|
||||
no_sign: value.no_sign,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,6 +145,10 @@ pub fn command(options: Options, verbosity: u8) -> crate::Result<()> {
|
||||
let config_guard = config.lock().unwrap();
|
||||
let config_ = config_guard.as_ref().unwrap();
|
||||
|
||||
if let Some(minimum_system_version) = &config_.bundle.macos.minimum_system_version {
|
||||
std::env::set_var("MACOSX_DEPLOYMENT_TARGET", minimum_system_version);
|
||||
}
|
||||
|
||||
let app_settings = interface.app_settings();
|
||||
let interface_options = options.clone().into();
|
||||
|
||||
@@ -193,6 +206,7 @@ pub fn bundle<A: AppSettings>(
|
||||
let mut settings = app_settings
|
||||
.get_bundler_settings(options.clone().into(), config, out_dir, package_types)
|
||||
.with_context(|| "failed to build bundler settings")?;
|
||||
settings.set_no_sign(options.no_sign);
|
||||
|
||||
settings.set_log_level(match verbosity {
|
||||
0 => log::Level::Error,
|
||||
|
||||
@@ -175,6 +175,22 @@ fn is_xcode_command_line_tools_installed() -> bool {
|
||||
.map(|o| o.status.success())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn xcode_version() -> Option<String> {
|
||||
Command::new("xcodebuild")
|
||||
.arg("-version")
|
||||
.output()
|
||||
.ok()
|
||||
.map(|o| String::from_utf8_lossy(&o.stdout).into_owned())
|
||||
.and_then(|s| {
|
||||
s.split('\n')
|
||||
.filter_map(|line| line.strip_prefix("Xcode "))
|
||||
.next()
|
||||
.map(ToString::to_string)
|
||||
})
|
||||
}
|
||||
|
||||
fn de_and_session() -> String {
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
@@ -319,5 +335,11 @@ pub fn items() -> Vec<SectionItem> {
|
||||
}.into()
|
||||
},
|
||||
),
|
||||
#[cfg(target_os = "macos")]
|
||||
SectionItem::new().action(|| {
|
||||
xcode_version().map(|v| (format!("Xcode: {v}"), Status::Success)).unwrap_or_else(|| {
|
||||
(format!("Xcode: {}", "not installed!".red()), Status::Error)
|
||||
}).into()
|
||||
}),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ use std::fmt::{self, Display, Formatter};
|
||||
mod app;
|
||||
mod env_nodejs;
|
||||
mod env_rust;
|
||||
mod env_system;
|
||||
pub mod env_system;
|
||||
#[cfg(target_os = "macos")]
|
||||
mod ios;
|
||||
mod packages_nodejs;
|
||||
|
||||
@@ -157,8 +157,6 @@ impl Interface for Rust {
|
||||
"IPHONEOS_DEPLOYMENT_TARGET",
|
||||
&config.bundle.ios.minimum_system_version,
|
||||
);
|
||||
} else if let Some(minimum_system_version) = &config.bundle.macos.minimum_system_version {
|
||||
std::env::set_var("MACOSX_DEPLOYMENT_TARGET", minimum_system_version);
|
||||
}
|
||||
|
||||
let app_settings = RustAppSettings::new(config, manifest, target)?;
|
||||
|
||||
@@ -132,11 +132,21 @@ pub fn command(options: Options) -> Result<()> {
|
||||
|
||||
let mut validated_lib = false;
|
||||
|
||||
let installed_targets =
|
||||
crate::interface::rust::installation::installed_targets().unwrap_or_default();
|
||||
|
||||
call_for_targets_with_fallback(
|
||||
options.targets.unwrap_or_default().iter(),
|
||||
&detect_target_ok,
|
||||
&env,
|
||||
|target: &Target| {
|
||||
if !installed_targets.contains(&target.triple().into()) {
|
||||
log::info!("Installing target {}", target.triple());
|
||||
target
|
||||
.install()
|
||||
.context("failed to install target with rustup")?;
|
||||
}
|
||||
|
||||
target.build(
|
||||
&config,
|
||||
&metadata,
|
||||
|
||||
@@ -99,6 +99,7 @@ impl From<Options> for BuildOptions {
|
||||
ci: options.ci,
|
||||
skip_stapling: false,
|
||||
ignore_version_mismatches: options.ignore_version_mismatches,
|
||||
no_sign: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,6 +168,15 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
|
||||
crate::build::setup(&interface, &mut build_options, tauri_config.clone(), true)?;
|
||||
|
||||
let installed_targets =
|
||||
crate::interface::rust::installation::installed_targets().unwrap_or_default();
|
||||
|
||||
if !installed_targets.contains(&first_target.triple().into()) {
|
||||
log::info!("Installing target {}", first_target.triple());
|
||||
first_target
|
||||
.install()
|
||||
.context("failed to install target with rustup")?;
|
||||
}
|
||||
// run an initial build to initialize plugins
|
||||
first_target.build(&config, &metadata, &env, noise_level, true, profile)?;
|
||||
|
||||
|
||||
@@ -252,12 +252,22 @@ fn run_dev(
|
||||
|
||||
configure_cargo(&mut env, config)?;
|
||||
|
||||
let installed_targets =
|
||||
crate::interface::rust::installation::installed_targets().unwrap_or_default();
|
||||
|
||||
// run an initial build to initialize plugins
|
||||
let target_triple = dev_options.target.as_ref().unwrap();
|
||||
let target = Target::all()
|
||||
.values()
|
||||
.find(|t| t.triple == target_triple)
|
||||
.unwrap_or_else(|| Target::all().values().next().unwrap());
|
||||
if !installed_targets.contains(&target.triple().into()) {
|
||||
log::info!("Installing target {}", target.triple());
|
||||
target
|
||||
.install()
|
||||
.context("failed to install target with rustup")?;
|
||||
}
|
||||
|
||||
target.build(
|
||||
config,
|
||||
metadata,
|
||||
|
||||
@@ -45,8 +45,9 @@ pub fn gen(
|
||||
.collect::<Vec<&Target>>();
|
||||
|
||||
if !missing_targets.is_empty() {
|
||||
println!("Installing Android Rust toolchains...");
|
||||
log::info!("Installing Android Rust targets...");
|
||||
for target in missing_targets {
|
||||
log::info!("Installing target {}", target.triple());
|
||||
target
|
||||
.install()
|
||||
.context("failed to install target with rustup")?;
|
||||
|
||||
@@ -15,7 +15,7 @@ use crate::{
|
||||
flock,
|
||||
},
|
||||
interface::{AppInterface, Interface, Options as InterfaceOptions},
|
||||
mobile::{write_options, CliOptions},
|
||||
mobile::{ios::ensure_ios_runtime_installed, write_options, CliOptions},
|
||||
ConfigValue, Result,
|
||||
};
|
||||
use clap::{ArgAction, Parser, ValueEnum};
|
||||
@@ -102,6 +102,17 @@ pub enum ExportMethod {
|
||||
Debugging,
|
||||
}
|
||||
|
||||
impl ExportMethod {
|
||||
/// Xcode 15.4 deprecated these names (in this case we should use the Display impl).
|
||||
pub fn pre_xcode_15_4_name(&self) -> String {
|
||||
match self {
|
||||
Self::AppStoreConnect => "app-store".to_string(),
|
||||
Self::ReleaseTesting => "ad-hoc".to_string(),
|
||||
Self::Debugging => "development".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ExportMethod {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
@@ -139,6 +150,7 @@ impl From<Options> for BuildOptions {
|
||||
ci: options.ci,
|
||||
skip_stapling: false,
|
||||
ignore_version_mismatches: options.ignore_version_mismatches,
|
||||
no_sign: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,9 +225,33 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
|
||||
let mut env = env()?;
|
||||
|
||||
if !options.open {
|
||||
ensure_ios_runtime_installed()?;
|
||||
}
|
||||
|
||||
let mut export_options_plist = plist::Dictionary::new();
|
||||
if let Some(method) = options.export_method {
|
||||
export_options_plist.insert("method".to_string(), method.to_string().into());
|
||||
let xcode_version =
|
||||
crate::info::env_system::xcode_version().context("failed to determine Xcode version")?;
|
||||
let mut iter = xcode_version.split('.');
|
||||
let major = iter.next().context(format!(
|
||||
"failed to parse Xcode version `{xcode_version}` as semver"
|
||||
))?;
|
||||
let minor = iter.next().context(format!(
|
||||
"failed to parse Xcode version `{xcode_version}` as semver"
|
||||
))?;
|
||||
let major = major.parse::<u64>().context(format!(
|
||||
"failed to parse Xcode version `{xcode_version}` as semver: major is not a number"
|
||||
))?;
|
||||
let minor = minor.parse::<u64>().context(format!(
|
||||
"failed to parse Xcode version `{xcode_version}` as semver: minor is not a number"
|
||||
))?;
|
||||
|
||||
if major < 15 || (major == 15 && minor < 4) {
|
||||
export_options_plist.insert("method".to_string(), method.pre_xcode_15_4_name().into());
|
||||
} else {
|
||||
export_options_plist.insert("method".to_string(), method.to_string().into());
|
||||
}
|
||||
}
|
||||
|
||||
let (keychain, provisioning_profile) = super::signing_from_env()?;
|
||||
|
||||
@@ -15,7 +15,8 @@ use crate::{
|
||||
},
|
||||
interface::{AppInterface, Interface, MobileOptions, Options as InterfaceOptions},
|
||||
mobile::{
|
||||
use_network_address_for_dev_url, write_options, CliOptions, DevChild, DevHost, DevProcess,
|
||||
ios::ensure_ios_runtime_installed, use_network_address_for_dev_url, write_options, CliOptions,
|
||||
DevChild, DevHost, DevProcess,
|
||||
},
|
||||
ConfigValue, Result,
|
||||
};
|
||||
@@ -166,6 +167,10 @@ fn run_command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
}
|
||||
};
|
||||
|
||||
if device.is_some() {
|
||||
ensure_ios_runtime_installed()?;
|
||||
}
|
||||
|
||||
let mut dev_options: DevOptions = options.clone().into();
|
||||
let target_triple = device
|
||||
.as_ref()
|
||||
|
||||
@@ -19,6 +19,7 @@ use cargo_mobile2::{
|
||||
util::{prompt, relativize_path},
|
||||
};
|
||||
use clap::{Parser, Subcommand};
|
||||
use serde::Deserialize;
|
||||
use sublime_fuzzy::best_match;
|
||||
use tauri_utils::resources::ResourcePaths;
|
||||
|
||||
@@ -325,12 +326,23 @@ fn connected_device_prompt<'a>(env: &'_ Env, target: Option<&str>) -> Result<Dev
|
||||
device,
|
||||
device.target().triple,
|
||||
);
|
||||
|
||||
Ok(device)
|
||||
} else {
|
||||
Err(anyhow::anyhow!("No connected iOS devices detected"))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Deserialize)]
|
||||
struct InstalledRuntimesList {
|
||||
runtimes: Vec<InstalledRuntime>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct InstalledRuntime {
|
||||
name: String,
|
||||
}
|
||||
|
||||
fn simulator_prompt(env: &'_ Env, target: Option<&str>) -> Result<device::Simulator> {
|
||||
let simulator_list = device::list_simulators(env).map_err(|cause| {
|
||||
anyhow::anyhow!("Failed to detect connected iOS Simulator devices: {cause}")
|
||||
@@ -367,6 +379,19 @@ fn simulator_prompt(env: &'_ Env, target: Option<&str>) -> Result<device::Simula
|
||||
};
|
||||
Ok(device)
|
||||
} else {
|
||||
log::warn!("No available iOS Simulator detected");
|
||||
let install_ios = crate::helpers::prompts::confirm(
|
||||
"Would you like to install the latest iOS runtime?",
|
||||
Some(false),
|
||||
)
|
||||
.unwrap_or_default();
|
||||
if install_ios {
|
||||
duct::cmd("xcodebuild", ["-downloadPlatform", "iOS"])
|
||||
.stdout_file(os_pipe::dup_stdout().unwrap())
|
||||
.stderr_file(os_pipe::dup_stderr().unwrap())
|
||||
.run()?;
|
||||
return simulator_prompt(env, target);
|
||||
}
|
||||
Err(anyhow::anyhow!("No available iOS Simulator detected"))
|
||||
}
|
||||
}
|
||||
@@ -382,6 +407,34 @@ fn device_prompt<'a>(env: &'_ Env, target: Option<&str>) -> Result<Device<'a>> {
|
||||
}
|
||||
}
|
||||
|
||||
fn ensure_ios_runtime_installed() -> Result<()> {
|
||||
let installed_platforms_json =
|
||||
duct::cmd("xcrun", ["simctl", "list", "runtimes", "--json"]).read()?;
|
||||
let installed_platforms: InstalledRuntimesList =
|
||||
serde_json::from_str(&installed_platforms_json).unwrap_or_default();
|
||||
if !installed_platforms
|
||||
.runtimes
|
||||
.iter()
|
||||
.any(|r| r.name.starts_with("iOS"))
|
||||
{
|
||||
log::warn!("iOS platform not installed");
|
||||
let install_ios = crate::helpers::prompts::confirm(
|
||||
"Would you like to install the latest iOS runtime?",
|
||||
Some(false),
|
||||
)
|
||||
.unwrap_or_default();
|
||||
if install_ios {
|
||||
duct::cmd("xcodebuild", ["-downloadPlatform", "iOS"])
|
||||
.stdout_file(os_pipe::dup_stdout().unwrap())
|
||||
.stderr_file(os_pipe::dup_stderr().unwrap())
|
||||
.run()?;
|
||||
} else {
|
||||
anyhow::bail!("iOS platform not installed");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn detect_target_ok<'a>(env: &Env) -> Option<&'a Target<'a>> {
|
||||
device_prompt(env, None).map(|device| device.target()).ok()
|
||||
}
|
||||
|
||||
@@ -50,8 +50,9 @@ pub fn gen(
|
||||
.collect::<Vec<&Target>>();
|
||||
|
||||
if !missing_targets.is_empty() {
|
||||
println!("Installing iOS Rust toolchains...");
|
||||
log::info!("Installing iOS Rust targets...");
|
||||
for target in missing_targets {
|
||||
log::info!("Installing target {}", target.triple());
|
||||
target
|
||||
.install()
|
||||
.context("failed to install target with rustup")?;
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::{
|
||||
};
|
||||
|
||||
use anyhow::Context;
|
||||
use cargo_mobile2::{apple::target::Target, opts::Profile};
|
||||
use cargo_mobile2::{apple::target::Target, opts::Profile, target::TargetTrait};
|
||||
use clap::{ArgAction, Parser};
|
||||
use object::{Object, ObjectSymbol};
|
||||
|
||||
@@ -65,12 +65,16 @@ pub fn command(options: Options) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
// `xcode-script` is ran from the `gen/apple` folder when not using NPM/yarn/pnpm.
|
||||
let process_path = std::env::current_exe().unwrap_or_default();
|
||||
|
||||
// `xcode-script` is ran from the `gen/apple` folder when not using NPM/yarn/pnpm/deno.
|
||||
// so we must change working directory to the src-tauri folder to resolve the tauri dir
|
||||
// additionally, bun@<1.2 does not modify the current working directory, so it is also runs this script from `gen/apple`
|
||||
// bun@>1.2 now actually moves the CWD to the package root so we shouldn't modify CWD in that case
|
||||
// see https://bun.sh/blog/bun-v1.2#bun-run-uses-the-correct-directory
|
||||
if (var_os("npm_lifecycle_event").is_none() && var_os("PNPM_PACKAGE_NAME").is_none())
|
||||
if (var_os("npm_lifecycle_event").is_none()
|
||||
&& var_os("PNPM_PACKAGE_NAME").is_none()
|
||||
&& process_path.file_stem().unwrap_or_default() != "deno")
|
||||
|| var("npm_config_user_agent")
|
||||
.is_ok_and(|agent| agent.starts_with("bun/1.0") || agent.starts_with("bun/1.1"))
|
||||
{
|
||||
@@ -209,6 +213,10 @@ pub fn command(options: Options) -> Result<()> {
|
||||
} else {
|
||||
options.arches
|
||||
};
|
||||
|
||||
let installed_targets =
|
||||
crate::interface::rust::installation::installed_targets().unwrap_or_default();
|
||||
|
||||
for arch in arches {
|
||||
// Set target-specific flags
|
||||
let (env_triple, rust_triple) = match arch.as_str() {
|
||||
@@ -251,6 +259,14 @@ pub fn command(options: Options) -> Result<()> {
|
||||
)
|
||||
})?
|
||||
};
|
||||
|
||||
if !installed_targets.contains(&rust_triple.into()) {
|
||||
log::info!("Installing target {}", target.triple());
|
||||
target
|
||||
.install()
|
||||
.context("failed to install target with rustup")?;
|
||||
}
|
||||
|
||||
target.compile_lib(
|
||||
&config,
|
||||
&metadata,
|
||||
|
||||
@@ -353,6 +353,7 @@ fn env_vars() -> HashMap<String, OsString> {
|
||||
&& k != "TAURI_SIGNING_PRIVATE_KEY_PASSWORD")
|
||||
|| k.starts_with("WRY")
|
||||
|| k.starts_with("CARGO_")
|
||||
|| k.starts_with("RUST_")
|
||||
|| k == "TMPDIR"
|
||||
|| k == "PATH"
|
||||
{
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.8.1]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`03e7c1193`](https://www.github.com/tauri-apps/tauri/commit/03e7c1193208716170f120a1d4a39cea0bc21064) ([#14080](https://www.github.com/tauri-apps/tauri/pull/14080) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Ignore initial navigation to `about:blank` so `on_new_window` does not give a warning on first navigation on macOS.
|
||||
|
||||
## \[2.8.0]
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-runtime-wry"
|
||||
version = "2.8.0"
|
||||
version = "2.8.1"
|
||||
description = "Wry bindings to the Tauri runtime"
|
||||
exclude = ["CHANGELOG.md", "/target"]
|
||||
readme = "README.md"
|
||||
@@ -17,7 +17,7 @@ rustc-args = ["--cfg", "docsrs"]
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[dependencies]
|
||||
wry = { version = "0.53.1", default-features = false, features = [
|
||||
wry = { version = "0.53.2", default-features = false, features = [
|
||||
"drag-drop",
|
||||
"protocol",
|
||||
"os-webview",
|
||||
|
||||
@@ -4654,13 +4654,16 @@ You may have it installed on another user account, but it is not available for t
|
||||
let mut webview_builder = WebViewBuilder::new_with_web_context(&mut web_context.inner)
|
||||
.with_id(&label)
|
||||
.with_focused(webview_attributes.focus)
|
||||
.with_url(&url)
|
||||
.with_transparent(webview_attributes.transparent)
|
||||
.with_accept_first_mouse(webview_attributes.accept_first_mouse)
|
||||
.with_incognito(webview_attributes.incognito)
|
||||
.with_clipboard(webview_attributes.clipboard)
|
||||
.with_hotkeys_zoom(webview_attributes.zoom_hotkeys_enabled);
|
||||
|
||||
if url != "about:blank" {
|
||||
webview_builder = webview_builder.with_url(&url);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
if let Some(webview_configuration) = webview_attributes.webview_configuration {
|
||||
webview_builder = webview_builder.with_webview_configuration(webview_configuration);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://schema.tauri.app/config/2.8.2",
|
||||
"$id": "https://schema.tauri.app/config/2.8.5",
|
||||
"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\": \"http://localhost:3000\",\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",
|
||||
@@ -164,7 +164,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"windows": {
|
||||
"description": "The app windows configuration.",
|
||||
"description": "The app windows configuration.\n\n ## Example:\n\n To create a window at app startup\n\n ```json\n {\n \"app\": {\n \"windows\": [\n { \"width\": 800, \"height\": 600 }\n ]\n }\n }\n ```\n\n If not specified, the window's label (its identifier) defaults to \"main\",\n you can use this label to get the window through\n `app.get_webview_window` in Rust or `WebviewWindow.getByLabel` in JavaScript\n\n When working with multiple windows, each window will need an unique label\n\n ```json\n {\n \"app\": {\n \"windows\": [\n { \"label\": \"main\", \"width\": 800, \"height\": 600 },\n { \"label\": \"secondary\", \"width\": 800, \"height\": 600 }\n ]\n }\n }\n ```\n\n You can also set `create` to false and use this config through the Rust APIs\n\n ```json\n {\n \"app\": {\n \"windows\": [\n { \"create\": false, \"width\": 800, \"height\": 600 }\n ]\n }\n }\n ```\n\n and use it like this\n\n ```rust\n tauri::Builder::default()\n .setup(|app| {\n tauri::WebviewWindowBuilder::from_config(app.handle(), app.config().app.windows[0])?.build()?;\n Ok(())\n });\n ```",
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -230,7 +230,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"create": {
|
||||
"description": "Whether Tauri should create this window at app startup or not.\n\n When this is set to `false` you must manually grab the config object via `app.config().app.windows`\n and create it with [`WebviewWindowBuilder::from_config`](https://docs.rs/tauri/2/tauri/webview/struct.WebviewWindowBuilder.html#method.from_config).",
|
||||
"description": "Whether Tauri should create this window at app startup or not.\n\n When this is set to `false` you must manually grab the config object via `app.config().app.windows`\n and create it with [`WebviewWindowBuilder::from_config`](https://docs.rs/tauri/2/tauri/webview/struct.WebviewWindowBuilder.html#method.from_config).\n\n ## Example:\n\n ```rust\n tauri::Builder::default()\n .setup(|app| {\n tauri::WebviewWindowBuilder::from_config(app.handle(), app.config().app.windows[0])?.build()?;\n Ok(())\n });\n ```",
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
@@ -495,7 +495,7 @@
|
||||
]
|
||||
},
|
||||
"incognito": {
|
||||
"description": "Whether or not the webview should be launched in incognito mode.\n\n ## Platform-specific:\n\n - **Android**: Unsupported.",
|
||||
"description": "Whether or not the webview should be launched in incognito mode.\n\n ## Platform-specific:\n\n - **Android**: Unsupported.",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
@@ -572,6 +572,27 @@
|
||||
"description": "Allows disabling the input accessory view on iOS.\n\n The accessory view is the view that appears above the keyboard when a text input element is focused.\n It usually displays a view with \"Done\", \"Next\" buttons.",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"dataDirectory": {
|
||||
"description": "Set a custom path for the webview's data directory (localStorage, cache, etc.) **relative to [`appDataDir()`]/${label}**.\n\n To set absolute paths, use [`WebviewWindowBuilder::data_directory`](https://docs.rs/tauri/2/tauri/webview/struct.WebviewWindowBuilder.html#method.data_directory)\n\n #### Platform-specific:\n\n - **Windows**: WebViews with different values for settings like `additionalBrowserArgs`, `browserExtensionsEnabled` or `scrollBarStyle` must have different data directories.\n - **macOS / iOS**: Unsupported, use `dataStoreIdentifier` instead.\n - **Android**: Unsupported.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"dataStoreIdentifier": {
|
||||
"description": "Initialize the WebView with a custom data store identifier. This can be seen as a replacement for `dataDirectory` which is unavailable in WKWebView.\n See https://developer.apple.com/documentation/webkit/wkwebsitedatastore/init(foridentifier:)?language=objc\n\n The array must contain 16 u8 numbers.\n\n #### Platform-specific:\n\n - **iOS**: Supported since version 17.0+.\n - **macOS**: Supported since version 14.0+.\n - **Windows / Linux / Android**: Unsupported.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "uint8",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"maxItems": 16,
|
||||
"minItems": 16
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
@@ -2078,7 +2099,7 @@
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"description": "App resources to bundle.\n Each resource is a path to a file or directory.\n Glob patterns are supported.",
|
||||
"description": "App resources to bundle.\n Each resource is a path to a file or directory.\n Glob patterns are supported.\n\n ## Examples\n\n To include a list of files:\n\n ```json\n {\n \"bundle\": {\n \"resources\": [\n \"./path/to/some-file.txt\",\n \"/absolute/path/to/textfile.txt\",\n \"../relative/path/to/jsonfile.json\",\n \"some-folder/\",\n \"resources/**/*.md\"\n ]\n }\n }\n ```\n\n The bundled files will be in `$RESOURCES/` with the original directory structure preserved,\n for example: `./path/to/some-file.txt` -> `$RESOURCE/path/to/some-file.txt`\n\n To fine control where the files will get copied to, use a map instead\n\n ```json\n {\n \"bundle\": {\n \"resources\": {\n \"/absolute/path/to/textfile.txt\": \"resources/textfile.txt\",\n \"relative/path/to/jsonfile.json\": \"resources/jsonfile.json\",\n \"resources/\": \"\",\n \"docs/**/*md\": \"website-docs/\"\n }\n }\n }\n ```\n\n Note that when using glob pattern in this case, the original directory structure is not preserved,\n everything gets copied to the target directory directly\n\n See more: <https://v2.tauri.app/develop/resources/>",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/BundleResources"
|
||||
@@ -2928,7 +2949,7 @@
|
||||
]
|
||||
},
|
||||
"installerHooks": {
|
||||
"description": "A path to a `.nsh` file that contains special NSIS macros to be hooked into the\n main installer.nsi script.\n\n Supported hooks are:\n - `NSIS_HOOK_PREINSTALL`: This hook runs before copying files, setting registry key values and creating shortcuts.\n - `NSIS_HOOK_POSTINSTALL`: This hook runs after the installer has finished copying all files, setting the registry keys and created shortcuts.\n - `NSIS_HOOK_PREUNINSTALL`: This hook runs before removing any files, registry keys and shortcuts.\n - `NSIS_HOOK_POSTUNINSTALL`: This hook runs after files, registry keys and shortcuts have been removed.\n\n\n ### Example\n\n ```nsh\n !macro NSIS_HOOK_PREINSTALL\n MessageBox MB_OK \"PreInstall\"\n !macroend\n\n !macro NSIS_HOOK_POSTINSTALL\n MessageBox MB_OK \"PostInstall\"\n !macroend\n\n !macro NSIS_HOOK_PREUNINSTALL\n MessageBox MB_OK \"PreUnInstall\"\n !macroend\n\n !macro NSIS_HOOK_POSTUNINSTALL\n MessageBox MB_OK \"PostUninstall\"\n !macroend\n\n ```",
|
||||
"description": "A path to a `.nsh` file that contains special NSIS macros to be hooked into the\n main installer.nsi script.\n\n Supported hooks are:\n\n - `NSIS_HOOK_PREINSTALL`: This hook runs before copying files, setting registry key values and creating shortcuts.\n - `NSIS_HOOK_POSTINSTALL`: This hook runs after the installer has finished copying all files, setting the registry keys and created shortcuts.\n - `NSIS_HOOK_PREUNINSTALL`: This hook runs before removing any files, registry keys and shortcuts.\n - `NSIS_HOOK_POSTUNINSTALL`: This hook runs after files, registry keys and shortcuts have been removed.\n\n ### Example\n\n ```nsh\n !macro NSIS_HOOK_PREINSTALL\n MessageBox MB_OK \"PreInstall\"\n !macroend\n\n !macro NSIS_HOOK_POSTINSTALL\n MessageBox MB_OK \"PostInstall\"\n !macroend\n\n !macro NSIS_HOOK_PREUNINSTALL\n MessageBox MB_OK \"PreUnInstall\"\n !macroend\n\n !macro NSIS_HOOK_POSTUNINSTALL\n MessageBox MB_OK \"PostUninstall\"\n !macroend\n ```",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
@@ -3490,7 +3511,7 @@
|
||||
]
|
||||
},
|
||||
"minimumSystemVersion": {
|
||||
"description": "A version string indicating the minimum macOS X version that the bundled application supports. Defaults to `10.13`.\n\n Setting it to `null` completely removes the `LSMinimumSystemVersion` field on the bundle's `Info.plist`\n and the `MACOSX_DEPLOYMENT_TARGET` environment variable.\n\n An empty string is considered an invalid value so the default value is used.",
|
||||
"description": "A version string indicating the minimum macOS X version that the bundled application supports. Defaults to `10.13`.\n\n Setting it to `null` completely removes the `LSMinimumSystemVersion` field on the bundle's `Info.plist`\n and the `MACOSX_DEPLOYMENT_TARGET` environment variable.\n\n Ignored in `tauri dev`.\n\n An empty string is considered an invalid value so the default value is used.",
|
||||
"default": "10.13",
|
||||
"type": [
|
||||
"string",
|
||||
|
||||
@@ -640,6 +640,8 @@ pub struct MacConfig {
|
||||
/// Setting it to `null` completely removes the `LSMinimumSystemVersion` field on the bundle's `Info.plist`
|
||||
/// and the `MACOSX_DEPLOYMENT_TARGET` environment variable.
|
||||
///
|
||||
/// Ignored in `tauri dev`.
|
||||
///
|
||||
/// An empty string is considered an invalid value so the default value is used.
|
||||
#[serde(
|
||||
deserialize_with = "de_macos_minimum_system_version",
|
||||
@@ -906,12 +908,12 @@ pub struct NsisConfig {
|
||||
/// main installer.nsi script.
|
||||
///
|
||||
/// Supported hooks are:
|
||||
///
|
||||
/// - `NSIS_HOOK_PREINSTALL`: This hook runs before copying files, setting registry key values and creating shortcuts.
|
||||
/// - `NSIS_HOOK_POSTINSTALL`: This hook runs after the installer has finished copying all files, setting the registry keys and created shortcuts.
|
||||
/// - `NSIS_HOOK_PREUNINSTALL`: This hook runs before removing any files, registry keys and shortcuts.
|
||||
/// - `NSIS_HOOK_POSTUNINSTALL`: This hook runs after files, registry keys and shortcuts have been removed.
|
||||
///
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```nsh
|
||||
@@ -930,7 +932,6 @@ pub struct NsisConfig {
|
||||
/// !macro NSIS_HOOK_POSTUNINSTALL
|
||||
/// MessageBox MB_OK "PostUninstall"
|
||||
/// !macroend
|
||||
///
|
||||
/// ```
|
||||
#[serde(alias = "installer-hooks")]
|
||||
pub installer_hooks: Option<PathBuf>,
|
||||
@@ -1284,6 +1285,47 @@ pub struct BundleConfig {
|
||||
/// App resources to bundle.
|
||||
/// Each resource is a path to a file or directory.
|
||||
/// Glob patterns are supported.
|
||||
///
|
||||
/// ## Examples
|
||||
///
|
||||
/// To include a list of files:
|
||||
///
|
||||
/// ```json
|
||||
/// {
|
||||
/// "bundle": {
|
||||
/// "resources": [
|
||||
/// "./path/to/some-file.txt",
|
||||
/// "/absolute/path/to/textfile.txt",
|
||||
/// "../relative/path/to/jsonfile.json",
|
||||
/// "some-folder/",
|
||||
/// "resources/**/*.md"
|
||||
/// ]
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// The bundled files will be in `$RESOURCES/` with the original directory structure preserved,
|
||||
/// for example: `./path/to/some-file.txt` -> `$RESOURCE/path/to/some-file.txt`
|
||||
///
|
||||
/// To fine control where the files will get copied to, use a map instead
|
||||
///
|
||||
/// ```json
|
||||
/// {
|
||||
/// "bundle": {
|
||||
/// "resources": {
|
||||
/// "/absolute/path/to/textfile.txt": "resources/textfile.txt",
|
||||
/// "relative/path/to/jsonfile.json": "resources/jsonfile.json",
|
||||
/// "resources/": "",
|
||||
/// "docs/**/*md": "website-docs/"
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Note that when using glob pattern in this case, the original directory structure is not preserved,
|
||||
/// everything gets copied to the target directory directly
|
||||
///
|
||||
/// See more: <https://v2.tauri.app/develop/resources/>
|
||||
pub resources: Option<BundleResources>,
|
||||
/// A copyright string associated with your application.
|
||||
pub copyright: Option<String>,
|
||||
@@ -1559,6 +1601,16 @@ pub struct WindowConfig {
|
||||
///
|
||||
/// When this is set to `false` you must manually grab the config object via `app.config().app.windows`
|
||||
/// and create it with [`WebviewWindowBuilder::from_config`](https://docs.rs/tauri/2/tauri/webview/struct.WebviewWindowBuilder.html#method.from_config).
|
||||
///
|
||||
/// ## Example:
|
||||
///
|
||||
/// ```rust
|
||||
/// tauri::Builder::default()
|
||||
/// .setup(|app| {
|
||||
/// tauri::WebviewWindowBuilder::from_config(app.handle(), app.config().app.windows[0])?.build()?;
|
||||
/// Ok(())
|
||||
/// });
|
||||
/// ```
|
||||
#[serde(default = "default_true")]
|
||||
pub create: bool,
|
||||
/// The window webview URL.
|
||||
@@ -1731,9 +1783,9 @@ pub struct WindowConfig {
|
||||
pub window_effects: Option<WindowEffectsConfig>,
|
||||
/// Whether or not the webview should be launched in incognito mode.
|
||||
///
|
||||
/// ## Platform-specific:
|
||||
/// ## Platform-specific:
|
||||
///
|
||||
/// - **Android**: Unsupported.
|
||||
/// - **Android**: Unsupported.
|
||||
#[serde(default)]
|
||||
pub incognito: bool,
|
||||
/// Sets the window associated with this label to be the parent of the window to be created.
|
||||
@@ -1842,6 +1894,31 @@ pub struct WindowConfig {
|
||||
alias = "disable_input_accessory_view"
|
||||
)]
|
||||
pub disable_input_accessory_view: bool,
|
||||
///
|
||||
/// Set a custom path for the webview's data directory (localStorage, cache, etc.) **relative to [`appDataDir()`]/${label}**.
|
||||
///
|
||||
/// To set absolute paths, use [`WebviewWindowBuilder::data_directory`](https://docs.rs/tauri/2/tauri/webview/struct.WebviewWindowBuilder.html#method.data_directory)
|
||||
///
|
||||
/// #### Platform-specific:
|
||||
///
|
||||
/// - **Windows**: WebViews with different values for settings like `additionalBrowserArgs`, `browserExtensionsEnabled` or `scrollBarStyle` must have different data directories.
|
||||
/// - **macOS / iOS**: Unsupported, use `dataStoreIdentifier` instead.
|
||||
/// - **Android**: Unsupported.
|
||||
#[serde(default, alias = "data-directory")]
|
||||
pub data_directory: Option<PathBuf>,
|
||||
///
|
||||
/// Initialize the WebView with a custom data store identifier. This can be seen as a replacement for `dataDirectory` which is unavailable in WKWebView.
|
||||
/// See https://developer.apple.com/documentation/webkit/wkwebsitedatastore/init(foridentifier:)?language=objc
|
||||
///
|
||||
/// The array must contain 16 u8 numbers.
|
||||
///
|
||||
/// #### Platform-specific:
|
||||
///
|
||||
/// - **iOS**: Supported since version 17.0+.
|
||||
/// - **macOS**: Supported since version 14.0+.
|
||||
/// - **Windows / Linux / Android**: Unsupported.
|
||||
#[serde(default, alias = "data-store-identifier")]
|
||||
pub data_store_identifier: Option<[u8; 16]>,
|
||||
}
|
||||
|
||||
impl Default for WindowConfig {
|
||||
@@ -1901,6 +1978,8 @@ impl Default for WindowConfig {
|
||||
javascript_disabled: false,
|
||||
allow_link_preview: true,
|
||||
disable_input_accessory_view: false,
|
||||
data_directory: None,
|
||||
data_store_identifier: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2557,6 +2636,59 @@ impl Default for PatternKind {
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct AppConfig {
|
||||
/// The app windows configuration.
|
||||
///
|
||||
/// ## Example:
|
||||
///
|
||||
/// To create a window at app startup
|
||||
///
|
||||
/// ```json
|
||||
/// {
|
||||
/// "app": {
|
||||
/// "windows": [
|
||||
/// { "width": 800, "height": 600 }
|
||||
/// ]
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// If not specified, the window's label (its identifier) defaults to "main",
|
||||
/// you can use this label to get the window through
|
||||
/// `app.get_webview_window` in Rust or `WebviewWindow.getByLabel` in JavaScript
|
||||
///
|
||||
/// When working with multiple windows, each window will need an unique label
|
||||
///
|
||||
/// ```json
|
||||
/// {
|
||||
/// "app": {
|
||||
/// "windows": [
|
||||
/// { "label": "main", "width": 800, "height": 600 },
|
||||
/// { "label": "secondary", "width": 800, "height": 600 }
|
||||
/// ]
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// You can also set `create` to false and use this config through the Rust APIs
|
||||
///
|
||||
/// ```json
|
||||
/// {
|
||||
/// "app": {
|
||||
/// "windows": [
|
||||
/// { "create": false, "width": 800, "height": 600 }
|
||||
/// ]
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// and use it like this
|
||||
///
|
||||
/// ```rust
|
||||
/// tauri::Builder::default()
|
||||
/// .setup(|app| {
|
||||
/// tauri::WebviewWindowBuilder::from_config(app.handle(), app.config().app.windows[0])?.build()?;
|
||||
/// Ok(())
|
||||
/// });
|
||||
/// ```
|
||||
#[serde(default)]
|
||||
pub windows: Vec<WindowConfig>,
|
||||
/// Security configuration.
|
||||
@@ -3354,6 +3486,8 @@ mod build {
|
||||
let javascript_disabled = self.javascript_disabled;
|
||||
let allow_link_preview = self.allow_link_preview;
|
||||
let disable_input_accessory_view = self.disable_input_accessory_view;
|
||||
let data_directory = opt_lit(self.data_directory.as_ref().map(path_buf_lit).as_ref());
|
||||
let data_store_identifier = opt_vec_lit(self.data_store_identifier, identity);
|
||||
|
||||
literal_struct!(
|
||||
tokens,
|
||||
@@ -3411,7 +3545,9 @@ mod build {
|
||||
background_throttling,
|
||||
javascript_disabled,
|
||||
allow_link_preview,
|
||||
disable_input_accessory_view
|
||||
disable_input_accessory_view,
|
||||
data_directory,
|
||||
data_store_identifier
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,11 @@ pub struct ResourcePathsIter<'a> {
|
||||
allow_walk: bool,
|
||||
|
||||
current_path: Option<PathBuf>,
|
||||
/// The key of map when `pattern_iter` is a [`PatternIter::Map`],
|
||||
/// used for determining [`Resource::target`]
|
||||
current_pattern: Option<String>,
|
||||
/// The value of the map when `pattern_iter` is a [`PatternIter::Map`],
|
||||
/// used for determining [`Resource::target`]
|
||||
current_dest: Option<PathBuf>,
|
||||
|
||||
walk_iter: Option<walkdir::IntoIter>,
|
||||
@@ -176,28 +180,27 @@ impl ResourcePathsIter<'_> {
|
||||
|
||||
Ok(Resource {
|
||||
path: path.to_path_buf(),
|
||||
target: self
|
||||
.current_dest
|
||||
.as_ref()
|
||||
.map(|current_dest| {
|
||||
// if processing a directory, preserve directory structure under current_dest
|
||||
if self.walk_iter.is_some() {
|
||||
let current_pattern = self.current_pattern.as_ref().unwrap();
|
||||
current_dest.join(path.strip_prefix(current_pattern).unwrap_or(path))
|
||||
} else if current_dest.components().count() == 0 {
|
||||
// if current_dest is empty while processing a file pattern or glob
|
||||
// we preserve the file name as it is
|
||||
PathBuf::from(path.file_name().unwrap())
|
||||
} else if self.glob_iter.is_some() {
|
||||
// if processing a glob and current_dest is not empty
|
||||
// we put all globbed paths under current_dest
|
||||
// preserving the file name as it is
|
||||
current_dest.join(path.file_name().unwrap())
|
||||
} else {
|
||||
current_dest.clone()
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| resource_relpath(path)),
|
||||
target: if let Some(current_dest) = &self.current_dest {
|
||||
// if processing a directory, preserve directory structure under current_dest
|
||||
if self.walk_iter.is_some() {
|
||||
let current_pattern = self.current_pattern.as_ref().unwrap();
|
||||
current_dest.join(path.strip_prefix(current_pattern).unwrap_or(path))
|
||||
} else if current_dest.components().count() == 0 {
|
||||
// if current_dest is empty while processing a file pattern or glob
|
||||
// we preserve the file name as it is
|
||||
PathBuf::from(path.file_name().unwrap())
|
||||
} else if self.glob_iter.is_some() {
|
||||
// if processing a glob and current_dest is not empty
|
||||
// we put all globbed paths under current_dest
|
||||
// preserving the file name as it is
|
||||
current_dest.join(path.file_name().unwrap())
|
||||
} else {
|
||||
current_dest.clone()
|
||||
}
|
||||
} else {
|
||||
// If `pattern_iter` is a [`PatternIter::Slice`]
|
||||
resource_relpath(path)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -240,14 +243,12 @@ impl ResourcePathsIter<'_> {
|
||||
|
||||
let pattern = match &mut self.pattern_iter {
|
||||
PatternIter::Slice(iter) => iter.next()?,
|
||||
PatternIter::Map(iter) => match iter.next() {
|
||||
Some((pattern, dest)) => {
|
||||
self.current_pattern = Some(pattern.clone());
|
||||
self.current_dest = Some(resource_relpath(Path::new(dest)));
|
||||
pattern
|
||||
}
|
||||
None => return None,
|
||||
},
|
||||
PatternIter::Map(iter) => {
|
||||
let (pattern, dest) = iter.next()?;
|
||||
self.current_pattern = Some(pattern.clone());
|
||||
self.current_dest = Some(resource_relpath(Path::new(dest)));
|
||||
pattern
|
||||
}
|
||||
};
|
||||
|
||||
if pattern.contains('*') {
|
||||
@@ -339,39 +340,47 @@ mod tests {
|
||||
std::env::set_current_dir(&temp).unwrap();
|
||||
|
||||
let paths = [
|
||||
Path::new("src-tauri/tauri.conf.json"),
|
||||
Path::new("src-tauri/some-other-json.json"),
|
||||
Path::new("src-tauri/Cargo.toml"),
|
||||
Path::new("src-tauri/Tauri.toml"),
|
||||
Path::new("src-tauri/build.rs"),
|
||||
Path::new("src/assets/javascript.svg"),
|
||||
Path::new("src/assets/tauri.svg"),
|
||||
Path::new("src/assets/rust.svg"),
|
||||
Path::new("src/assets/lang/en.json"),
|
||||
Path::new("src/assets/lang/ar.json"),
|
||||
Path::new("src/sounds/lang/es.wav"),
|
||||
Path::new("src/sounds/lang/fr.wav"),
|
||||
Path::new("src/textures/ground/earth.tex"),
|
||||
Path::new("src/textures/ground/sand.tex"),
|
||||
Path::new("src/textures/water.tex"),
|
||||
Path::new("src/textures/fire.tex"),
|
||||
Path::new("src/tiles/sky/grey.tile"),
|
||||
Path::new("src/tiles/sky/yellow.tile"),
|
||||
Path::new("src/tiles/grass.tile"),
|
||||
Path::new("src/tiles/stones.tile"),
|
||||
Path::new("src/index.html"),
|
||||
Path::new("src/style.css"),
|
||||
Path::new("src/script.js"),
|
||||
Path::new("src/dir/another-dir/file1.txt"),
|
||||
Path::new("src/dir/another-dir2/file2.txt"),
|
||||
"src-tauri/tauri.conf.json",
|
||||
"src-tauri/some-other-json.json",
|
||||
"src-tauri/Cargo.toml",
|
||||
"src-tauri/Tauri.toml",
|
||||
"src-tauri/build.rs",
|
||||
"src/assets/javascript.svg",
|
||||
"src/assets/tauri.svg",
|
||||
"src/assets/rust.svg",
|
||||
"src/assets/lang/en.json",
|
||||
"src/assets/lang/ar.json",
|
||||
"src/sounds/lang/es.wav",
|
||||
"src/sounds/lang/fr.wav",
|
||||
"src/textures/ground/earth.tex",
|
||||
"src/textures/ground/sand.tex",
|
||||
"src/textures/water.tex",
|
||||
"src/textures/fire.tex",
|
||||
"src/tiles/sky/grey.tile",
|
||||
"src/tiles/sky/yellow.tile",
|
||||
"src/tiles/grass.tile",
|
||||
"src/tiles/stones.tile",
|
||||
"src/index.html",
|
||||
"src/style.css",
|
||||
"src/script.js",
|
||||
"src/dir/another-dir/file1.txt",
|
||||
"src/dir/another-dir2/file2.txt",
|
||||
];
|
||||
|
||||
for path in paths {
|
||||
let path = Path::new(path);
|
||||
fs::create_dir_all(path.parent().unwrap()).unwrap();
|
||||
fs::write(path, "").unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn resources_map(literal: &[(&str, &str)]) -> HashMap<String, String> {
|
||||
literal
|
||||
.iter()
|
||||
.map(|(from, to)| (from.to_string(), to.to_string()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial_test::serial(resources)]
|
||||
fn resource_paths_iter_slice_allow_walk() {
|
||||
@@ -386,6 +395,8 @@ mod tests {
|
||||
"../src/assets".into(),
|
||||
"../src/index.html".into(),
|
||||
"../src/sounds".into(),
|
||||
// Should be the same as `../src/textures/` or `../src/textures`
|
||||
"../src/textures/**/*".into(),
|
||||
"*.toml".into(),
|
||||
"*.conf.json".into(),
|
||||
],
|
||||
@@ -396,7 +407,9 @@ mod tests {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let expected = expected_resources(&[
|
||||
// From `../src/script.js`
|
||||
("../src/script.js", "_up_/src/script.js"),
|
||||
// From `../src/assets`
|
||||
(
|
||||
"../src/assets/javascript.svg",
|
||||
"_up_/src/assets/javascript.svg",
|
||||
@@ -405,11 +418,26 @@ mod tests {
|
||||
("../src/assets/rust.svg", "_up_/src/assets/rust.svg"),
|
||||
("../src/assets/lang/en.json", "_up_/src/assets/lang/en.json"),
|
||||
("../src/assets/lang/ar.json", "_up_/src/assets/lang/ar.json"),
|
||||
// From `../src/index.html`
|
||||
("../src/index.html", "_up_/src/index.html"),
|
||||
// From `../src/sounds`
|
||||
("../src/sounds/lang/es.wav", "_up_/src/sounds/lang/es.wav"),
|
||||
("../src/sounds/lang/fr.wav", "_up_/src/sounds/lang/fr.wav"),
|
||||
// From `../src/textures/**/*`
|
||||
(
|
||||
"../src/textures/ground/earth.tex",
|
||||
"_up_/src/textures/earth.tex",
|
||||
),
|
||||
(
|
||||
"../src/textures/ground/sand.tex",
|
||||
"_up_/src/textures/sand.tex",
|
||||
),
|
||||
("../src/textures/water.tex", "_up_/src/textures/water.tex"),
|
||||
("../src/textures/fire.tex", "_up_/src/textures/fire.tex"),
|
||||
// From `*.toml`
|
||||
("Cargo.toml", "Cargo.toml"),
|
||||
("Tauri.toml", "Tauri.toml"),
|
||||
// From `*.conf.json`
|
||||
("tauri.conf.json", "tauri.conf.json"),
|
||||
]);
|
||||
|
||||
@@ -469,17 +497,17 @@ mod tests {
|
||||
let _ = std::env::set_current_dir(dir);
|
||||
|
||||
let resources = ResourcePaths::from_map(
|
||||
&std::collections::HashMap::from_iter([
|
||||
("../src/script.js".into(), "main.js".into()),
|
||||
("../src/assets".into(), "".into()),
|
||||
("../src/index.html".into(), "frontend/index.html".into()),
|
||||
("../src/sounds".into(), "voices".into()),
|
||||
("../src/textures/*".into(), "textures".into()),
|
||||
("../src/tiles/**/*".into(), "tiles".into()),
|
||||
("*.toml".into(), "".into()),
|
||||
("*.conf.json".into(), "json".into()),
|
||||
("../non-existent-file".into(), "asd".into()), // invalid case
|
||||
("../non/*".into(), "asd".into()), // invalid case
|
||||
&resources_map(&[
|
||||
("../src/script.js", "main.js"),
|
||||
("../src/assets", ""),
|
||||
("../src/index.html", "frontend/index.html"),
|
||||
("../src/sounds", "voices"),
|
||||
("../src/textures/*", "textures"),
|
||||
("../src/tiles/**/*", "tiles"),
|
||||
("*.toml", ""),
|
||||
("*.conf.json", "json"),
|
||||
("../non-existent-file", "asd"), // invalid case
|
||||
("../non/*", "asd"), // invalid case
|
||||
]),
|
||||
true,
|
||||
)
|
||||
@@ -525,13 +553,13 @@ mod tests {
|
||||
let _ = std::env::set_current_dir(dir);
|
||||
|
||||
let resources = ResourcePaths::from_map(
|
||||
&std::collections::HashMap::from_iter([
|
||||
("../src/script.js".into(), "main.js".into()),
|
||||
("../src/assets".into(), "".into()),
|
||||
("../src/index.html".into(), "frontend/index.html".into()),
|
||||
("../src/sounds".into(), "voices".into()),
|
||||
("*.toml".into(), "".into()),
|
||||
("*.conf.json".into(), "json".into()),
|
||||
&resources_map(&[
|
||||
("../src/script.js", "main.js"),
|
||||
("../src/assets", ""),
|
||||
("../src/index.html", "frontend/index.html"),
|
||||
("../src/sounds", "voices"),
|
||||
("*.toml", ""),
|
||||
("*.conf.json", "json"),
|
||||
]),
|
||||
false,
|
||||
)
|
||||
@@ -564,15 +592,15 @@ mod tests {
|
||||
let _ = std::env::set_current_dir(dir);
|
||||
|
||||
let resources = ResourcePaths::from_map(
|
||||
&std::collections::HashMap::from_iter([
|
||||
("../non-existent-file".into(), "file".into()),
|
||||
("../non-existent-dir".into(), "dir".into()),
|
||||
&resources_map(&[
|
||||
("../non-existent-file", "file"),
|
||||
("../non-existent-dir", "dir"),
|
||||
// exists but not allowed to walk
|
||||
("../src".into(), "dir2".into()),
|
||||
("../src", "dir2"),
|
||||
// doesn't exist but it is a glob and will return an error
|
||||
("../non-existent-glob-dir/*".into(), "glob".into()),
|
||||
("../non-existent-glob-dir/*", "glob"),
|
||||
// exists but only contains directories and will not produce any values
|
||||
("../src/dir/*".into(), "dir3".into()),
|
||||
("../src/dir/*", "dir3"),
|
||||
]),
|
||||
false,
|
||||
)
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.8.5]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`07e134f70`](https://www.github.com/tauri-apps/tauri/commit/07e134f70e3a65424641f1b384a26bf059fd9c56) ([#14107](https://www.github.com/tauri-apps/tauri/pull/14107) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Improve error message for request errors on iOS when local network permission has been denied and the app tries to reach the development server.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-build@2.4.1`
|
||||
|
||||
## \[2.8.4]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`03e7c1193`](https://www.github.com/tauri-apps/tauri/commit/03e7c1193208716170f120a1d4a39cea0bc21064) ([#14080](https://www.github.com/tauri-apps/tauri/pull/14080) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Ignore initial navigation to `about:blank` so `on_new_window` does not give a warning on first navigation on macOS.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-runtime-wry@2.8.1`
|
||||
|
||||
## \[2.8.3]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`534998406`](https://www.github.com/tauri-apps/tauri/commit/534998406433a1be52caa9792d120763ab8339ac) ([#14054](https://www.github.com/tauri-apps/tauri/pull/14054) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Fixed an issue that caused the runtime WebView2 detection to fail for FixedRuntime installations.
|
||||
|
||||
## \[2.8.2]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri"
|
||||
version = "2.8.2"
|
||||
version = "2.8.5"
|
||||
description = "Make tiny, secure apps for all desktop platforms with Tauri"
|
||||
exclude = ["/test", "/.scripts", "CHANGELOG.md", "/target"]
|
||||
readme = "README.md"
|
||||
@@ -61,7 +61,7 @@ tauri-macros = { version = "2.4.0", path = "../tauri-macros" }
|
||||
tauri-utils = { version = "2.7.0", features = [
|
||||
"resources",
|
||||
], path = "../tauri-utils" }
|
||||
tauri-runtime-wry = { version = "2.8.0", path = "../tauri-runtime-wry", default-features = false, optional = true }
|
||||
tauri-runtime-wry = { version = "2.8.1", path = "../tauri-runtime-wry", default-features = false, optional = true }
|
||||
getrandom = "0.3"
|
||||
serde_repr = "0.1"
|
||||
http = "1"
|
||||
@@ -168,7 +168,7 @@ objc2-ui-kit = { version = "0.3.0", default-features = false, features = [
|
||||
[build-dependencies]
|
||||
glob = "0.3"
|
||||
heck = "0.5"
|
||||
tauri-build = { path = "../tauri-build/", default-features = false, version = "2.4.0" }
|
||||
tauri-build = { path = "../tauri-build/", default-features = false, version = "2.4.1" }
|
||||
tauri-utils = { path = "../tauri-utils/", version = "2.7.0", features = [
|
||||
"build",
|
||||
] }
|
||||
|
||||
@@ -1632,7 +1632,7 @@ impl<R: Runtime> Builder<R> {
|
||||
use tauri::Manager;
|
||||
tauri::Builder::default()
|
||||
.setup(|app| {
|
||||
let main_window = app.get_window("main").unwrap();
|
||||
let main_window = app.get_webview_window("main").unwrap();
|
||||
main_window.set_title("Tauri!")?;
|
||||
Ok(())
|
||||
});
|
||||
@@ -2178,6 +2178,26 @@ tauri::Builder::default()
|
||||
.expect("OpenHarmony app instance not initialized"),
|
||||
};
|
||||
|
||||
// The env var must be set before the Runtime is created so that GetAvailableBrowserVersionString picks it up.
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if let crate::utils::config::WebviewInstallMode::FixedRuntime { path } =
|
||||
&manager.config.bundle.windows.webview_install_mode
|
||||
{
|
||||
if let Some(exe_dir) = crate::utils::platform::current_exe()
|
||||
.ok()
|
||||
.and_then(|p| p.parent().map(|p| p.to_path_buf()))
|
||||
{
|
||||
std::env::set_var("WEBVIEW2_BROWSER_EXECUTABLE_FOLDER", exe_dir.join(path));
|
||||
} else {
|
||||
#[cfg(debug_assertions)]
|
||||
eprintln!(
|
||||
"failed to resolve resource directory; fallback to the installed Webview2 runtime."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(windows, target_os = "linux"))]
|
||||
let mut runtime = if self.runtime_any_thread {
|
||||
R::new_any_thread(runtime_args)?
|
||||
@@ -2255,25 +2275,6 @@ tauri::Builder::default()
|
||||
app.manage(ChannelDataIpcQueue::default());
|
||||
app.handle.plugin(crate::ipc::channel::plugin())?;
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if let crate::utils::config::WebviewInstallMode::FixedRuntime { path } =
|
||||
&app.manager.config().bundle.windows.webview_install_mode
|
||||
{
|
||||
if let Ok(resource_dir) = app.path().resource_dir() {
|
||||
std::env::set_var(
|
||||
"WEBVIEW2_BROWSER_EXECUTABLE_FOLDER",
|
||||
resource_dir.join(path),
|
||||
);
|
||||
} else {
|
||||
#[cfg(debug_assertions)]
|
||||
eprintln!(
|
||||
"failed to resolve resource directory; fallback to the installed Webview2 runtime."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let handle = app.handle();
|
||||
|
||||
// initialize default tray icon if defined
|
||||
|
||||
@@ -174,6 +174,7 @@ impl<R: Runtime> PathResolver<R> {
|
||||
/// - **Linux:** Resolves to `$HOME`.
|
||||
/// - **macOS:** Resolves to `$HOME`.
|
||||
/// - **Windows:** Resolves to `{FOLDERID_Profile}`.
|
||||
/// - **iOS**: Cannot be written to directly, use one of the app paths instead.
|
||||
pub fn home_dir(&self) -> Result<PathBuf> {
|
||||
self.call_resolve("getHomeDir")
|
||||
}
|
||||
|
||||
@@ -149,6 +149,7 @@ impl<R: Runtime> PathResolver<R> {
|
||||
/// - **Linux:** Resolves to `$HOME`.
|
||||
/// - **macOS:** Resolves to `$HOME`.
|
||||
/// - **Windows:** Resolves to `{FOLDERID_Profile}`.
|
||||
/// - **iOS**: Cannot be written to directly, use one of the app paths instead.
|
||||
pub fn home_dir(&self) -> Result<PathBuf> {
|
||||
dirs::home_dir().ok_or(Error::UnknownPath)
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ pub enum BaseDirectory {
|
||||
/// Resolves to [`crate::path::PathResolver::video_dir`].
|
||||
Video = 10,
|
||||
/// The Resource directory.
|
||||
/// Resolves to the resource directory of this app.
|
||||
/// Resolves to [`crate::path::PathResolver::resource_dir`].
|
||||
Resource = 11,
|
||||
/// A temporary directory.
|
||||
/// Resolves to [`std::env::temp_dir`].
|
||||
|
||||
@@ -187,8 +187,20 @@ fn get_response<R: Runtime>(
|
||||
.body(response.body.to_vec().into())?
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to request {}: {}", url.as_str(), e);
|
||||
return Err(Box::new(e));
|
||||
let error_message = format!(
|
||||
"Failed to request {}: {}{}",
|
||||
url.as_str(),
|
||||
e,
|
||||
if let Some(s) = e.status() {
|
||||
format!("status code: {}", s.as_u16())
|
||||
} else if cfg!(target_os = "ios") {
|
||||
", did you grant local network permissions? That is required to reach the development server. Please grant the permission via the prompt or in `Settings > Privacy & Security > Local Network` and restart the app. See https://support.apple.com/en-us/102229 for more information.".to_string()
|
||||
} else {
|
||||
"".to_string()
|
||||
}
|
||||
);
|
||||
log::error!("{error_message}");
|
||||
return Err(error_message.into());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -42,6 +42,7 @@ use crate::{
|
||||
InvokeError, InvokeMessage, InvokeResolver, Origin, OwnedInvokeResponder, ScopeObject,
|
||||
},
|
||||
manager::AppManager,
|
||||
path::SafePathBuf,
|
||||
sealed::{ManagerBase, RuntimeOrDispatch},
|
||||
AppHandle, Emitter, Event, EventId, EventLoopMessage, EventName, Listener, Manager,
|
||||
ResourceTable, Runtime, Window,
|
||||
@@ -390,9 +391,47 @@ async fn create_window(app: tauri::AppHandle) {
|
||||
///
|
||||
/// [the Webview2 issue]: https://github.com/tauri-apps/wry/issues/583
|
||||
pub fn from_config(config: &WindowConfig) -> Self {
|
||||
let mut config = config.to_owned();
|
||||
|
||||
if let Some(data_directory) = &config.data_directory {
|
||||
let resolve_data_dir_res = dirs::data_local_dir()
|
||||
.or({
|
||||
#[cfg(feature = "tracing")]
|
||||
tracing::error!("failed to resolve data directory");
|
||||
None
|
||||
})
|
||||
.and_then(|local_dir| {
|
||||
SafePathBuf::new(data_directory.clone())
|
||||
.inspect_err(|_err| {
|
||||
#[cfg(feature = "tracing")]
|
||||
tracing::error!(
|
||||
"data_directory `{}` is not a safe path, ignoring config. Validation error was: {_err}",
|
||||
data_directory.display()
|
||||
);
|
||||
})
|
||||
.map(|p| (local_dir, p))
|
||||
.ok()
|
||||
})
|
||||
.and_then(|(local_dir, data_directory)| {
|
||||
if data_directory.as_ref().is_relative() {
|
||||
Some(local_dir.join(&config.label).join(data_directory.as_ref()))
|
||||
} else {
|
||||
#[cfg(feature = "tracing")]
|
||||
tracing::error!(
|
||||
"data_directory `{}` is not a relative path, ignoring config.",
|
||||
data_directory.display()
|
||||
);
|
||||
None
|
||||
}
|
||||
});
|
||||
if let Some(resolved_data_directory) = resolve_data_dir_res {
|
||||
config.data_directory = Some(resolved_data_directory);
|
||||
}
|
||||
}
|
||||
|
||||
Self {
|
||||
label: config.label.clone(),
|
||||
webview_attributes: WebviewAttributes::from(config),
|
||||
webview_attributes: WebviewAttributes::from(&config),
|
||||
web_resource_request_handler: None,
|
||||
navigation_handler: None,
|
||||
new_window_handler: None,
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
"eslint-plugin-security": "3.0.1",
|
||||
"fast-glob": "3.3.3",
|
||||
"globals": "^16.2.0",
|
||||
"rollup": "4.46.4",
|
||||
"rollup": "4.50.0",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.34.1"
|
||||
|
||||
@@ -854,6 +854,33 @@ interface WebviewOptions {
|
||||
* It usually displays a view with "Done", "Next" buttons.
|
||||
*/
|
||||
disableInputAccessoryView?: boolean
|
||||
/**
|
||||
* Set a custom path for the webview's data directory (localStorage, cache, etc.) **relative to [`appDataDir()`]/${label}**.
|
||||
* For security reasons, paths outside of that location can only be configured on the Rust side.
|
||||
*
|
||||
* #### Platform-specific:
|
||||
*
|
||||
* - **Windows**: WebViews with different values for settings like `additionalBrowserArgs`, `browserExtensionsEnabled` or `scrollBarStyle` must have different data directories.
|
||||
* - **macOS / iOS**: Unsupported, use `dataStoreIdentifier` instead.
|
||||
* - **Android**: Unsupported.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*/
|
||||
dataDirectory?: string
|
||||
/**
|
||||
* Initialize the WebView with a custom data store identifier. This can be seen as a replacement for `dataDirectory` which is unavailable in WKWebView.
|
||||
* See https://developer.apple.com/documentation/webkit/wkwebsitedatastore/init(foridentifier:)?language=objc
|
||||
*
|
||||
* The array must contain 16 u8 numbers.
|
||||
*
|
||||
* #### Platform-specific:
|
||||
*
|
||||
* - **macOS / iOS**: Available on macOS >= 14 and iOS >= 17
|
||||
* - **Windows / Linux / Android**: Unsupported.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*/
|
||||
dataStoreIdentifier?: number[]
|
||||
}
|
||||
|
||||
export { Webview, getCurrentWebview, getAllWebviews }
|
||||
|
||||
@@ -1,5 +1,41 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.8.4]
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [`f70b28529`](https://www.github.com/tauri-apps/tauri/commit/f70b28529d226a2dec2f41709d8934f8f5adab25) ([#14093](https://www.github.com/tauri-apps/tauri/pull/14093) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Ensure Rust targets for mobile are installed when running the dev and build commands (previously only checked on init).
|
||||
- [`a9b342125`](https://www.github.com/tauri-apps/tauri/commit/a9b342125d5ac1bc9a4b2e8b5f73e8ca3cbcb8b2) ([#14114](https://www.github.com/tauri-apps/tauri/pull/14114) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix iOS dev and build targeting the simulator on Intel machines.
|
||||
- [`61b9b681e`](https://www.github.com/tauri-apps/tauri/commit/61b9b681e88067a53b79d2318ae005dc25addcd6) ([#14111](https://www.github.com/tauri-apps/tauri/pull/14111) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Retain `RUST_*` environment variables when running the mobile commands.
|
||||
- [`c23bec62d`](https://www.github.com/tauri-apps/tauri/commit/c23bec62d6d5724798869681aa1534423aae28e2) ([#14083](https://www.github.com/tauri-apps/tauri/pull/14083) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Tauri now ignores `macOS.minimumSystemVersion` in `tauri dev` to prevent forced rebuilds of macOS specific dependencies when using something like `rust-analyzer` at the same time as `tauri dev`.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`c37a29833`](https://www.github.com/tauri-apps/tauri/commit/c37a298331d6d744b15d32d55a2db83c884a3d6a) ([#14112](https://www.github.com/tauri-apps/tauri/pull/14112) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix usage with Deno failing with `ReferenceError: require is not defined`.
|
||||
- [`bcf000c0a`](https://www.github.com/tauri-apps/tauri/commit/bcf000c0a8607eedf488fb949b982f519abda43d) ([#14110](https://www.github.com/tauri-apps/tauri/pull/14110) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes running `ios` commands with `deno` crashing due to incorrect current working directory resolution.
|
||||
- [`7db7142f9`](https://www.github.com/tauri-apps/tauri/commit/7db7142f9ff7dc2f5719602e199b77129ceb19d3) ([#14119](https://www.github.com/tauri-apps/tauri/pull/14119) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes empty device name when using an Android emulator causing the emulator to never be detected as running.
|
||||
- [`956b4fd6f`](https://www.github.com/tauri-apps/tauri/commit/956b4fd6ffbb4312123b107ca96c87a001359b9d) ([#14106](https://www.github.com/tauri-apps/tauri/pull/14106) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Use the correct export method on Xcode < 15.4.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-cli@2.8.4`
|
||||
|
||||
## \[2.8.3]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [`0ac89d3b6`](https://www.github.com/tauri-apps/tauri/commit/0ac89d3b6c8c4a4826a4c42726e4f4a8941b3fde) ([#14078](https://www.github.com/tauri-apps/tauri/pull/14078) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Updated `cargo-mobile2` to allow running on iOS simulators that have a higher version than the XCode SDK. This fixes compatiblity issues with Apple's recent "iOS 18.5 + iOS 18.6 Simulator" platform support component.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-cli@2.8.3`
|
||||
|
||||
## \[2.8.2]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `tauri-cli@2.8.1`
|
||||
|
||||
## \[2.8.1]
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "@tauri-apps/cli",
|
||||
"version": "2.8.1",
|
||||
"version": "2.8.4",
|
||||
"description": "Command line interface for building Tauri apps",
|
||||
"type": "commonjs",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/tauri"
|
||||
|
||||
199
pnpm-lock.yaml
generated
199
pnpm-lock.yaml
generated
@@ -63,10 +63,10 @@ importers:
|
||||
version: 9.29.0
|
||||
'@rollup/plugin-terser':
|
||||
specifier: 0.4.4
|
||||
version: 0.4.4(rollup@4.46.4)
|
||||
version: 0.4.4(rollup@4.50.0)
|
||||
'@rollup/plugin-typescript':
|
||||
specifier: 12.1.4
|
||||
version: 12.1.4(rollup@4.46.4)(tslib@2.8.1)(typescript@5.8.3)
|
||||
version: 12.1.4(rollup@4.50.0)(tslib@2.8.1)(typescript@5.8.3)
|
||||
'@types/eslint':
|
||||
specifier: ^9.6.1
|
||||
version: 9.6.1
|
||||
@@ -89,8 +89,8 @@ importers:
|
||||
specifier: ^16.2.0
|
||||
version: 16.2.0
|
||||
rollup:
|
||||
specifier: 4.46.4
|
||||
version: 4.46.4
|
||||
specifier: 4.50.0
|
||||
version: 4.50.0
|
||||
tslib:
|
||||
specifier: ^2.8.1
|
||||
version: 2.8.1
|
||||
@@ -1103,103 +1103,108 @@ packages:
|
||||
rollup:
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.46.4':
|
||||
resolution: {integrity: sha512-B2wfzCJ+ps/OBzRjeds7DlJumCU3rXMxJJS1vzURyj7+KBHGONm7c9q1TfdBl4vCuNMkDvARn3PBl2wZzuR5mw==}
|
||||
'@rollup/rollup-android-arm-eabi@4.50.0':
|
||||
resolution: {integrity: sha512-lVgpeQyy4fWN5QYebtW4buT/4kn4p4IJ+kDNB4uYNT5b8c8DLJDg6titg20NIg7E8RWwdWZORW6vUFfrLyG3KQ==}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-android-arm64@4.46.4':
|
||||
resolution: {integrity: sha512-FGJYXvYdn8Bs6lAlBZYT5n+4x0ciEp4cmttsvKAZc/c8/JiPaQK8u0c/86vKX8lA7OY/+37lIQSe0YoAImvBAA==}
|
||||
'@rollup/rollup-android-arm64@4.50.0':
|
||||
resolution: {integrity: sha512-2O73dR4Dc9bp+wSYhviP6sDziurB5/HCym7xILKifWdE9UsOe2FtNcM+I4xZjKrfLJnq5UR8k9riB87gauiQtw==}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.46.4':
|
||||
resolution: {integrity: sha512-/9qwE/BM7ATw/W/OFEMTm3dmywbJyLQb4f4v5nmOjgYxPIGpw7HaxRi6LnD4Pjn/q7k55FGeHe1/OD02w63apA==}
|
||||
'@rollup/rollup-darwin-arm64@4.50.0':
|
||||
resolution: {integrity: sha512-vwSXQN8T4sKf1RHr1F0s98Pf8UPz7pS6P3LG9NSmuw0TVh7EmaE+5Ny7hJOZ0M2yuTctEsHHRTMi2wuHkdS6Hg==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.46.4':
|
||||
resolution: {integrity: sha512-QkWfNbeRuzFnv2d0aPlrzcA3Ebq2mE8kX/5Pl7VdRShbPBjSnom7dbT8E3Jmhxo2RL784hyqGvR5KHavCJQciw==}
|
||||
'@rollup/rollup-darwin-x64@4.50.0':
|
||||
resolution: {integrity: sha512-cQp/WG8HE7BCGyFVuzUg0FNmupxC+EPZEwWu2FCGGw5WDT1o2/YlENbm5e9SMvfDFR6FRhVCBePLqj0o8MN7Vw==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.46.4':
|
||||
resolution: {integrity: sha512-+ToyOMYnSfV8D+ckxO6NthPln/PDNp1P6INcNypfZ7muLmEvPKXqduUiD8DlJpMMT8LxHcE5W0dK9kXfJke9Zw==}
|
||||
'@rollup/rollup-freebsd-arm64@4.50.0':
|
||||
resolution: {integrity: sha512-UR1uTJFU/p801DvvBbtDD7z9mQL8J80xB0bR7DqW7UGQHRm/OaKzp4is7sQSdbt2pjjSS72eAtRh43hNduTnnQ==}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.46.4':
|
||||
resolution: {integrity: sha512-cGT6ey/W+sje6zywbLiqmkfkO210FgRz7tepWAzzEVgQU8Hn91JJmQWNqs55IuglG8sJdzk7XfNgmGRtcYlo1w==}
|
||||
'@rollup/rollup-freebsd-x64@4.50.0':
|
||||
resolution: {integrity: sha512-G/DKyS6PK0dD0+VEzH/6n/hWDNPDZSMBmqsElWnCRGrYOb2jC0VSupp7UAHHQ4+QILwkxSMaYIbQ72dktp8pKA==}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.46.4':
|
||||
resolution: {integrity: sha512-9fhTJyOb275w5RofPSl8lpr4jFowd+H4oQKJ9XTYzD1JWgxdZKE8bA6d4npuiMemkecQOcigX01FNZNCYnQBdA==}
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.50.0':
|
||||
resolution: {integrity: sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.46.4':
|
||||
resolution: {integrity: sha512-+6kCIM5Zjvz2HwPl/udgVs07tPMIp1VU2Y0c72ezjOvSvEfAIWsUgpcSDvnC7g9NrjYR6X9bZT92mZZ90TfvXw==}
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.50.0':
|
||||
resolution: {integrity: sha512-S4UefYdV0tnynDJV1mdkNawp0E5Qm2MtSs330IyHgaccOFrwqsvgigUD29uT+B/70PDY1eQ3t40+xf6wIvXJyg==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.46.4':
|
||||
resolution: {integrity: sha512-SWuXdnsayCZL4lXoo6jn0yyAj7TTjWE4NwDVt9s7cmu6poMhtiras5c8h6Ih6Y0Zk6Z+8t/mLumvpdSPTWub2Q==}
|
||||
'@rollup/rollup-linux-arm64-gnu@4.50.0':
|
||||
resolution: {integrity: sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.46.4':
|
||||
resolution: {integrity: sha512-vDknMDqtMhrrroa5kyX6tuC0aRZZlQ+ipDfbXd2YGz5HeV2t8HOl/FDAd2ynhs7Ki5VooWiiZcCtxiZ4IjqZwQ==}
|
||||
'@rollup/rollup-linux-arm64-musl@4.50.0':
|
||||
resolution: {integrity: sha512-EtBDIZuDtVg75xIPIK1l5vCXNNCIRM0OBPUG+tbApDuJAy9mKago6QxX+tfMzbCI6tXEhMuZuN1+CU8iDW+0UQ==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-loongarch64-gnu@4.46.4':
|
||||
resolution: {integrity: sha512-mCBkjRZWhvjtl/x+Bd4fQkWZT8canStKDxGrHlBiTnZmJnWygGcvBylzLVCZXka4dco5ymkWhZlLwKCGFF4ivw==}
|
||||
'@rollup/rollup-linux-loongarch64-gnu@4.50.0':
|
||||
resolution: {integrity: sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.46.4':
|
||||
resolution: {integrity: sha512-YMdz2phOTFF+Z66dQfGf0gmeDSi5DJzY5bpZyeg9CPBkV9QDzJ1yFRlmi/j7WWRf3hYIWrOaJj5jsfwgc8GTHQ==}
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.50.0':
|
||||
resolution: {integrity: sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.46.4':
|
||||
resolution: {integrity: sha512-r0WKLSfFAK8ucG024v2yiLSJMedoWvk8yWqfNICX28NHDGeu3F/wBf8KG6mclghx4FsLePxJr/9N8rIj1PtCnw==}
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.50.0':
|
||||
resolution: {integrity: sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.46.4':
|
||||
resolution: {integrity: sha512-IaizpPP2UQU3MNyPH1u0Xxbm73D+4OupL0bjo4Hm0496e2wg3zuvoAIhubkD1NGy9fXILEExPQy87mweujEatA==}
|
||||
'@rollup/rollup-linux-riscv64-musl@4.50.0':
|
||||
resolution: {integrity: sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.46.4':
|
||||
resolution: {integrity: sha512-aCM29orANR0a8wk896p6UEgIfupReupnmISz6SUwMIwTGaTI8MuKdE0OD2LvEg8ondDyZdMvnaN3bW4nFbATPA==}
|
||||
'@rollup/rollup-linux-s390x-gnu@4.50.0':
|
||||
resolution: {integrity: sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.46.4':
|
||||
resolution: {integrity: sha512-0Xj1vZE3cbr/wda8d/m+UeuSL+TDpuozzdD4QaSzu/xSOMK0Su5RhIkF7KVHFQsobemUNHPLEcYllL7ZTCP/Cg==}
|
||||
'@rollup/rollup-linux-x64-gnu@4.50.0':
|
||||
resolution: {integrity: sha512-8PrJJA7/VU8ToHVEPu14FzuSAqVKyo5gg/J8xUerMbyNkWkO9j2ExBho/68RnJsMGNJq4zH114iAttgm7BZVkA==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.46.4':
|
||||
resolution: {integrity: sha512-kM/orjpolfA5yxsx84kI6bnK47AAZuWxglGKcNmokw2yy9i5eHY5UAjcX45jemTJnfHAWo3/hOoRqEeeTdL5hw==}
|
||||
'@rollup/rollup-linux-x64-musl@4.50.0':
|
||||
resolution: {integrity: sha512-SkE6YQp+CzpyOrbw7Oc4MgXFvTw2UIBElvAvLCo230pyxOLmYwRPwZ/L5lBe/VW/qT1ZgND9wJfOsdy0XptRvw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.46.4':
|
||||
resolution: {integrity: sha512-cNLH4psMEsWKILW0isbpQA2OvjXLbKvnkcJFmqAptPQbtLrobiapBJVj6RoIvg6UXVp5w0wnIfd/Q56cNpF+Ew==}
|
||||
'@rollup/rollup-openharmony-arm64@4.50.0':
|
||||
resolution: {integrity: sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q==}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.50.0':
|
||||
resolution: {integrity: sha512-q7cIIdFvWQoaCbLDUyUc8YfR3Jh2xx3unO8Dn6/TTogKjfwrax9SyfmGGK6cQhKtjePI7jRfd7iRYcxYs93esg==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.46.4':
|
||||
resolution: {integrity: sha512-OiEa5lRhiANpv4SfwYVgQ3opYWi/QmPDC5ve21m8G9pf6ZO+aX1g2EEF1/IFaM1xPSP7mK0msTRXlPs6mIagkg==}
|
||||
'@rollup/rollup-win32-ia32-msvc@4.50.0':
|
||||
resolution: {integrity: sha512-XzNOVg/YnDOmFdDKcxxK410PrcbcqZkBmz+0FicpW5jtjKQxcW1BZJEQOF0NJa6JO7CZhett8GEtRN/wYLYJuw==}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.46.4':
|
||||
resolution: {integrity: sha512-IKL9mewGZ5UuuX4NQlwOmxPyqielvkAPUS2s1cl6yWjjQvyN3h5JTdVFGD5Jr5xMjRC8setOfGQDVgX8V+dkjg==}
|
||||
'@rollup/rollup-win32-x64-msvc@4.50.0':
|
||||
resolution: {integrity: sha512-xMmiWRR8sp72Zqwjgtf3QbZfF1wdh8X2ABu3EaozvZcyHJeU0r+XAnXdKgs4cCAp6ORoYoCygipYP1mjmbjrsg==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
@@ -2157,8 +2162,8 @@ packages:
|
||||
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
|
||||
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
|
||||
|
||||
rollup@4.46.4:
|
||||
resolution: {integrity: sha512-YbxoxvoqNg9zAmw4+vzh1FkGAiZRK+LhnSrbSrSXMdZYsRPDWoshcSd/pldKRO6lWzv/e9TiJAVQyirYIeSIPQ==}
|
||||
rollup@4.50.0:
|
||||
resolution: {integrity: sha512-/Zl4D8zPifNmyGzJS+3kVoyXeDeT/GrsJM94sACNg9RtUE0hrHa1bNPtRSrfHTMH5HjRzce6K7rlTh3Khiw+pw==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
@@ -3312,89 +3317,92 @@ snapshots:
|
||||
dependencies:
|
||||
quansync: 0.2.10
|
||||
|
||||
'@rollup/plugin-terser@0.4.4(rollup@4.46.4)':
|
||||
'@rollup/plugin-terser@0.4.4(rollup@4.50.0)':
|
||||
dependencies:
|
||||
serialize-javascript: 6.0.2
|
||||
smob: 1.5.0
|
||||
terser: 5.43.1
|
||||
optionalDependencies:
|
||||
rollup: 4.46.4
|
||||
rollup: 4.50.0
|
||||
|
||||
'@rollup/plugin-typescript@12.1.4(rollup@4.46.4)(tslib@2.8.1)(typescript@5.8.3)':
|
||||
'@rollup/plugin-typescript@12.1.4(rollup@4.50.0)(tslib@2.8.1)(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.2.0(rollup@4.46.4)
|
||||
'@rollup/pluginutils': 5.2.0(rollup@4.50.0)
|
||||
resolve: 1.22.10
|
||||
typescript: 5.8.3
|
||||
optionalDependencies:
|
||||
rollup: 4.46.4
|
||||
rollup: 4.50.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@rollup/pluginutils@5.2.0(rollup@4.46.4)':
|
||||
'@rollup/pluginutils@5.2.0(rollup@4.50.0)':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
estree-walker: 2.0.2
|
||||
picomatch: 4.0.2
|
||||
optionalDependencies:
|
||||
rollup: 4.46.4
|
||||
rollup: 4.50.0
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.46.4':
|
||||
'@rollup/rollup-android-arm-eabi@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm64@4.46.4':
|
||||
'@rollup/rollup-android-arm64@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.46.4':
|
||||
'@rollup/rollup-darwin-arm64@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.46.4':
|
||||
'@rollup/rollup-darwin-x64@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.46.4':
|
||||
'@rollup/rollup-freebsd-arm64@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.46.4':
|
||||
'@rollup/rollup-freebsd-x64@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.46.4':
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.46.4':
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.46.4':
|
||||
'@rollup/rollup-linux-arm64-gnu@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.46.4':
|
||||
'@rollup/rollup-linux-arm64-musl@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-loongarch64-gnu@4.46.4':
|
||||
'@rollup/rollup-linux-loongarch64-gnu@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.46.4':
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.46.4':
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.46.4':
|
||||
'@rollup/rollup-linux-riscv64-musl@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.46.4':
|
||||
'@rollup/rollup-linux-s390x-gnu@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.46.4':
|
||||
'@rollup/rollup-linux-x64-gnu@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.46.4':
|
||||
'@rollup/rollup-linux-x64-musl@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.46.4':
|
||||
'@rollup/rollup-openharmony-arm64@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.46.4':
|
||||
'@rollup/rollup-win32-arm64-msvc@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.46.4':
|
||||
'@rollup/rollup-win32-ia32-msvc@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.50.0':
|
||||
optional: true
|
||||
|
||||
'@sveltejs/acorn-typescript@1.0.5(acorn@8.15.0)':
|
||||
@@ -4448,30 +4456,31 @@ snapshots:
|
||||
|
||||
reusify@1.1.0: {}
|
||||
|
||||
rollup@4.46.4:
|
||||
rollup@4.50.0:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
optionalDependencies:
|
||||
'@rollup/rollup-android-arm-eabi': 4.46.4
|
||||
'@rollup/rollup-android-arm64': 4.46.4
|
||||
'@rollup/rollup-darwin-arm64': 4.46.4
|
||||
'@rollup/rollup-darwin-x64': 4.46.4
|
||||
'@rollup/rollup-freebsd-arm64': 4.46.4
|
||||
'@rollup/rollup-freebsd-x64': 4.46.4
|
||||
'@rollup/rollup-linux-arm-gnueabihf': 4.46.4
|
||||
'@rollup/rollup-linux-arm-musleabihf': 4.46.4
|
||||
'@rollup/rollup-linux-arm64-gnu': 4.46.4
|
||||
'@rollup/rollup-linux-arm64-musl': 4.46.4
|
||||
'@rollup/rollup-linux-loongarch64-gnu': 4.46.4
|
||||
'@rollup/rollup-linux-ppc64-gnu': 4.46.4
|
||||
'@rollup/rollup-linux-riscv64-gnu': 4.46.4
|
||||
'@rollup/rollup-linux-riscv64-musl': 4.46.4
|
||||
'@rollup/rollup-linux-s390x-gnu': 4.46.4
|
||||
'@rollup/rollup-linux-x64-gnu': 4.46.4
|
||||
'@rollup/rollup-linux-x64-musl': 4.46.4
|
||||
'@rollup/rollup-win32-arm64-msvc': 4.46.4
|
||||
'@rollup/rollup-win32-ia32-msvc': 4.46.4
|
||||
'@rollup/rollup-win32-x64-msvc': 4.46.4
|
||||
'@rollup/rollup-android-arm-eabi': 4.50.0
|
||||
'@rollup/rollup-android-arm64': 4.50.0
|
||||
'@rollup/rollup-darwin-arm64': 4.50.0
|
||||
'@rollup/rollup-darwin-x64': 4.50.0
|
||||
'@rollup/rollup-freebsd-arm64': 4.50.0
|
||||
'@rollup/rollup-freebsd-x64': 4.50.0
|
||||
'@rollup/rollup-linux-arm-gnueabihf': 4.50.0
|
||||
'@rollup/rollup-linux-arm-musleabihf': 4.50.0
|
||||
'@rollup/rollup-linux-arm64-gnu': 4.50.0
|
||||
'@rollup/rollup-linux-arm64-musl': 4.50.0
|
||||
'@rollup/rollup-linux-loongarch64-gnu': 4.50.0
|
||||
'@rollup/rollup-linux-ppc64-gnu': 4.50.0
|
||||
'@rollup/rollup-linux-riscv64-gnu': 4.50.0
|
||||
'@rollup/rollup-linux-riscv64-musl': 4.50.0
|
||||
'@rollup/rollup-linux-s390x-gnu': 4.50.0
|
||||
'@rollup/rollup-linux-x64-gnu': 4.50.0
|
||||
'@rollup/rollup-linux-x64-musl': 4.50.0
|
||||
'@rollup/rollup-openharmony-arm64': 4.50.0
|
||||
'@rollup/rollup-win32-arm64-msvc': 4.50.0
|
||||
'@rollup/rollup-win32-ia32-msvc': 4.50.0
|
||||
'@rollup/rollup-win32-x64-msvc': 4.50.0
|
||||
fsevents: 2.3.3
|
||||
|
||||
run-parallel@1.2.0:
|
||||
@@ -4748,7 +4757,7 @@ snapshots:
|
||||
fdir: 6.4.6(picomatch@4.0.2)
|
||||
picomatch: 4.0.2
|
||||
postcss: 8.5.6
|
||||
rollup: 4.46.4
|
||||
rollup: 4.50.0
|
||||
tinyglobby: 0.2.14
|
||||
optionalDependencies:
|
||||
'@types/node': 22.15.32
|
||||
|
||||
Reference in New Issue
Block a user