mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-03 10:11:15 +02:00
committed by
GitHub
parent
c04d0340e2
commit
ae83d008f9
11
.changes/config-toml.md
Normal file
11
.changes/config-toml.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
"tauri": minor
|
||||
"tauri-utils": minor
|
||||
"tauri-macros": minor
|
||||
"tauri-codegen": minor
|
||||
"tauri-build": minor
|
||||
"cli.rs": minor
|
||||
"cli.js": minor
|
||||
---
|
||||
|
||||
Added support to configuration files in TOML format (Tauri.toml file).
|
||||
5
.changes/utils-parse-refactor.md
Normal file
5
.changes/utils-parse-refactor.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri-utils": minor
|
||||
---
|
||||
|
||||
Refactored the `config::parse` module.
|
||||
@@ -34,3 +34,4 @@ semver = "1"
|
||||
codegen = [ "tauri-codegen", "quote" ]
|
||||
isolation = [ "tauri-codegen/isolation", "tauri-utils/isolation" ]
|
||||
config-json5 = [ "tauri-utils/config-json5" ]
|
||||
config-toml = [ "tauri-utils/config-toml" ]
|
||||
|
||||
@@ -202,6 +202,8 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
println!("cargo:rerun-if-changed=tauri.conf.json");
|
||||
#[cfg(feature = "config-json5")]
|
||||
println!("cargo:rerun-if-changed=tauri.conf.json5");
|
||||
#[cfg(feature = "config-toml")]
|
||||
println!("cargo:rerun-if-changed=Tauri.toml");
|
||||
|
||||
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
let mobile = target_os == "ios" || target_os == "android";
|
||||
|
||||
@@ -40,3 +40,4 @@ compression = [ "brotli", "tauri-utils/compression" ]
|
||||
isolation = [ "tauri-utils/isolation" ]
|
||||
shell-scope = [ "regex" ]
|
||||
config-json5 = [ "tauri-utils/config-json5" ]
|
||||
config-toml = [ "tauri-utils/config-toml" ]
|
||||
|
||||
@@ -29,3 +29,4 @@ compression = [ "tauri-codegen/compression" ]
|
||||
isolation = [ "tauri-codegen/isolation" ]
|
||||
shell-scope = [ "tauri-codegen/shell-scope" ]
|
||||
config-json5 = [ "tauri-codegen/config-json5", "tauri-utils/config-json5" ]
|
||||
config-toml = [ "tauri-codegen/config-toml", "tauri-utils/config-toml" ]
|
||||
|
||||
@@ -11,7 +11,7 @@ use syn::{
|
||||
LitStr, PathArguments, PathSegment, Token,
|
||||
};
|
||||
use tauri_codegen::{context_codegen, get_config, ContextData};
|
||||
use tauri_utils::config::parse::does_supported_extension_exist;
|
||||
use tauri_utils::config::parse::does_supported_file_name_exist;
|
||||
|
||||
pub(crate) struct ContextItems {
|
||||
config_file: PathBuf,
|
||||
@@ -36,7 +36,7 @@ impl Parse for ContextItems {
|
||||
VarError::NotUnicode(_) => "CARGO_MANIFEST_DIR env var contained invalid utf8".into(),
|
||||
})
|
||||
.and_then(|path| {
|
||||
if does_supported_extension_exist(&path) {
|
||||
if does_supported_file_name_exist(&path) {
|
||||
Ok(path)
|
||||
} else {
|
||||
Err(format!(
|
||||
|
||||
@@ -29,6 +29,7 @@ getrandom = { version = "0.2", optional = true, features = [ "std" ] }
|
||||
serialize-to-javascript = { version = "=0.1.1", optional = true }
|
||||
ctor = "0.1"
|
||||
json5 = { version = "0.4", optional = true }
|
||||
toml = { version = "0.5", optional = true }
|
||||
json-patch = "0.2"
|
||||
glob = { version = "0.3.0", optional = true }
|
||||
walkdir = { version = "2", optional = true }
|
||||
@@ -56,4 +57,5 @@ schema = [ "schemars" ]
|
||||
isolation = [ "aes-gcm", "getrandom", "serialize-to-javascript" ]
|
||||
process-relaunch-dangerous-allow-symlink-macos = [ ]
|
||||
config-json5 = [ "json5" ]
|
||||
config-toml = [ "toml" ]
|
||||
resources = [ "glob", "walkdir" ]
|
||||
|
||||
@@ -247,7 +247,7 @@ impl BundleTarget {
|
||||
pub struct AppImageConfig {
|
||||
/// Include additional gstreamer dependencies needed for audio and video playback.
|
||||
/// This increases the bundle size by ~15-35MB depending on your build system.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "bundle-media-framework")]
|
||||
pub bundle_media_framework: bool,
|
||||
}
|
||||
|
||||
@@ -293,17 +293,21 @@ pub struct MacConfig {
|
||||
/// An empty string is considered an invalid value so the default value is used.
|
||||
#[serde(
|
||||
deserialize_with = "de_minimum_system_version",
|
||||
default = "minimum_system_version"
|
||||
default = "minimum_system_version",
|
||||
alias = "minimum-system-version"
|
||||
)]
|
||||
pub minimum_system_version: Option<String>,
|
||||
/// Allows your application to communicate with the outside world.
|
||||
/// It should be a lowercase, without port and protocol domain name.
|
||||
#[serde(alias = "exception-domain")]
|
||||
pub exception_domain: Option<String>,
|
||||
/// The path to the license file to add to the DMG bundle.
|
||||
pub license: Option<String>,
|
||||
/// Identity to use for code signing.
|
||||
#[serde(alias = "signing-identity")]
|
||||
pub signing_identity: Option<String>,
|
||||
/// Provider short name for notarization.
|
||||
#[serde(alias = "provider-short-name")]
|
||||
pub provider_short_name: Option<String>,
|
||||
/// Path to the entitlements file.
|
||||
pub entitlements: Option<String>,
|
||||
@@ -333,6 +337,7 @@ fn minimum_system_version() -> Option<String> {
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct WixLanguageConfig {
|
||||
/// The path to a locale (`.wxl`) file. See <https://wixtoolset.org/documentation/manual/v3/howtos/ui_and_localization/build_a_localized_version.html>.
|
||||
#[serde(alias = "locale-path")]
|
||||
pub locale_path: Option<String>,
|
||||
}
|
||||
|
||||
@@ -366,44 +371,46 @@ pub struct WixConfig {
|
||||
/// A custom .wxs template to use.
|
||||
pub template: Option<PathBuf>,
|
||||
/// A list of paths to .wxs files with WiX fragments to use.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "fragment-paths")]
|
||||
pub fragment_paths: Vec<PathBuf>,
|
||||
/// The ComponentGroup element ids you want to reference from the fragments.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "component-group-refs")]
|
||||
pub component_group_refs: Vec<String>,
|
||||
/// The Component element ids you want to reference from the fragments.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "component-refs")]
|
||||
pub component_refs: Vec<String>,
|
||||
/// The FeatureGroup element ids you want to reference from the fragments.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "feature-group-refs")]
|
||||
pub feature_group_refs: Vec<String>,
|
||||
/// The Feature element ids you want to reference from the fragments.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "feature-refs")]
|
||||
pub feature_refs: Vec<String>,
|
||||
/// The Merge element ids you want to reference from the fragments.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "merge-refs")]
|
||||
pub merge_refs: Vec<String>,
|
||||
/// Disables the Webview2 runtime installation after app install.
|
||||
///
|
||||
/// Will be removed in v2, prefer the [`WindowsConfig::webview_install_mode`] option.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "skip-webview-install")]
|
||||
pub skip_webview_install: bool,
|
||||
/// The path to the license file to render on the installer.
|
||||
///
|
||||
/// Must be an RTF file, so if a different extension is provided, we convert it to the RTF format.
|
||||
pub license: Option<PathBuf>,
|
||||
/// Create an elevated update task within Windows Task Scheduler.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "enable-elevated-update-task")]
|
||||
pub enable_elevated_update_task: bool,
|
||||
/// Path to a bitmap file to use as the installation user interface banner.
|
||||
/// This bitmap will appear at the top of all but the first page of the installer.
|
||||
///
|
||||
/// The required dimensions are 493px × 58px.
|
||||
#[serde(alias = "banner-path")]
|
||||
pub banner_path: Option<PathBuf>,
|
||||
/// Path to a bitmap file to use on the installation user interface dialogs.
|
||||
/// It is used on the welcome and completion dialogs.
|
||||
|
||||
/// The required dimensions are 493px × 312px.
|
||||
#[serde(alias = "dialog-image-path")]
|
||||
pub dialog_image_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
@@ -471,17 +478,20 @@ impl Default for WebviewInstallMode {
|
||||
pub struct WindowsConfig {
|
||||
/// Specifies the file digest algorithm to use for creating file signatures.
|
||||
/// Required for code signing. SHA-256 is recommended.
|
||||
#[serde(alias = "digest-algorithm")]
|
||||
pub digest_algorithm: Option<String>,
|
||||
/// Specifies the SHA1 hash of the signing certificate.
|
||||
#[serde(alias = "certificate-thumbprint")]
|
||||
pub certificate_thumbprint: Option<String>,
|
||||
/// Server to use during timestamping.
|
||||
#[serde(alias = "timestamp-url")]
|
||||
pub timestamp_url: Option<String>,
|
||||
/// Whether to use Time-Stamp Protocol (TSP, a.k.a. RFC 3161) for the timestamp server. Your code signing provider may
|
||||
/// use a TSP timestamp server, like e.g. SSL.com does. If so, enable TSP by setting to true.
|
||||
#[serde(default)]
|
||||
pub tsp: bool,
|
||||
/// The installation mode for the Webview2 runtime.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "webview-install-mode")]
|
||||
pub webview_install_mode: WebviewInstallMode,
|
||||
/// Path to the webview fixed runtime to use. Overwrites [`Self::webview_install_mode`] if set.
|
||||
///
|
||||
@@ -489,13 +499,14 @@ pub struct WindowsConfig {
|
||||
///
|
||||
/// The fixed version can be downloaded [on the official website](https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download-section).
|
||||
/// The `.cab` file must be extracted to a folder and this folder path must be defined on this field.
|
||||
#[serde(alias = "webview-fixed-runtime-path")]
|
||||
pub webview_fixed_runtime_path: Option<PathBuf>,
|
||||
/// Validates a second app installation, blocking the user from installing an older version if set to `false`.
|
||||
///
|
||||
/// For instance, if `1.2.1` is installed, the user won't be able to install app version `1.2.0` or `1.1.5`.
|
||||
///
|
||||
/// The default value of this flag is `true`.
|
||||
#[serde(default = "default_allow_downgrades")]
|
||||
#[serde(default = "default_allow_downgrades", alias = "allow-downgrades")]
|
||||
pub allow_downgrades: bool,
|
||||
/// Configuration for the MSI generated with WiX.
|
||||
pub wix: Option<WixConfig>,
|
||||
@@ -553,8 +564,10 @@ pub struct BundleConfig {
|
||||
/// Business, DeveloperTool, Education, Entertainment, Finance, Game, ActionGame, AdventureGame, ArcadeGame, BoardGame, CardGame, CasinoGame, DiceGame, EducationalGame, FamilyGame, KidsGame, MusicGame, PuzzleGame, RacingGame, RolePlayingGame, SimulationGame, SportsGame, StrategyGame, TriviaGame, WordGame, GraphicsAndDesign, HealthcareAndFitness, Lifestyle, Medical, Music, News, Photography, Productivity, Reference, SocialNetworking, Sports, Travel, Utility, Video, Weather.
|
||||
pub category: Option<String>,
|
||||
/// A short description of your application.
|
||||
#[serde(alias = "short-description")]
|
||||
pub short_description: Option<String>,
|
||||
/// A longer, multi-line description of the application.
|
||||
#[serde(alias = "long-description")]
|
||||
pub long_description: Option<String>,
|
||||
/// Configuration for the AppImage bundle.
|
||||
#[serde(default)]
|
||||
@@ -576,6 +589,7 @@ pub struct BundleConfig {
|
||||
/// - "my-binary-x86_64-unknown-linux-gnu" for Linux
|
||||
///
|
||||
/// so don't forget to provide binaries for all targeted platforms.
|
||||
#[serde(alias = "external-bin")]
|
||||
pub external_bin: Option<Vec<String>>,
|
||||
/// Configuration for the Windows bundle.
|
||||
#[serde(default)]
|
||||
@@ -599,6 +613,7 @@ pub struct CliArg {
|
||||
pub description: Option<String>,
|
||||
/// The argument long description which will be shown on the help information.
|
||||
/// Typically this a more detailed (multi-line) message that describes the argument.
|
||||
#[serde(alias = "long-description")]
|
||||
pub long_description: Option<String>,
|
||||
/// Specifies that the argument takes a value at run time.
|
||||
///
|
||||
@@ -606,7 +621,7 @@ pub struct CliArg {
|
||||
/// - Using a space such as -o value or --option value
|
||||
/// - Using an equals and no space such as -o=value or --option=value
|
||||
/// - Use a short and no space such as -ovalue
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "takes-value")]
|
||||
pub takes_value: bool,
|
||||
/// Specifies that the argument may have an unknown number of multiple values. Without any other settings, this argument may appear only once.
|
||||
///
|
||||
@@ -620,7 +635,7 @@ pub struct CliArg {
|
||||
/// For options or arguments that take a value, this does not affect how many values they can accept. (i.e. only one at a time is allowed)
|
||||
///
|
||||
/// For example, --opt val1 --opt val2 is allowed, but --opt val1 val2 is not.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "multiple-occurrences")]
|
||||
pub multiple_occurrences: bool,
|
||||
/// Specifies how many values are required to satisfy this argument. For example, if you had a
|
||||
/// `-f <file>` argument where you wanted exactly 3 'files' you would set
|
||||
@@ -632,17 +647,21 @@ pub struct CliArg {
|
||||
/// as *not* setting it would only allow one occurrence of this argument.
|
||||
///
|
||||
/// **NOTE:** implicitly sets `takes_value = true` and `multiple_values = true`.
|
||||
#[serde(alias = "number-of-values")]
|
||||
pub number_of_values: Option<usize>,
|
||||
/// Specifies a list of possible values for this argument.
|
||||
/// At runtime, the CLI verifies that only one of the specified values was used, or fails with an error message.
|
||||
#[serde(alias = "possible-values")]
|
||||
pub possible_values: Option<Vec<String>>,
|
||||
/// Specifies the minimum number of values for this argument.
|
||||
/// For example, if you had a -f `<file>` argument where you wanted at least 2 'files',
|
||||
/// you would set `minValues: 2`, and this argument would be satisfied if the user provided, 2 or more values.
|
||||
#[serde(alias = "min-values")]
|
||||
pub min_values: Option<usize>,
|
||||
/// Specifies the maximum number of values are for this argument.
|
||||
/// For example, if you had a -f `<file>` argument where you wanted up to 3 'files',
|
||||
/// you would set .max_values(3), and this argument would be satisfied if the user provided, 1, 2, or 3 values.
|
||||
#[serde(alias = "max-values")]
|
||||
pub max_values: Option<usize>,
|
||||
/// Sets whether or not the argument is required by default.
|
||||
///
|
||||
@@ -652,32 +671,41 @@ pub struct CliArg {
|
||||
pub required: bool,
|
||||
/// Sets an arg that override this arg's required setting
|
||||
/// i.e. this arg will be required unless this other argument is present.
|
||||
#[serde(alias = "requred-unless-present")]
|
||||
pub required_unless_present: Option<String>,
|
||||
/// Sets args that override this arg's required setting
|
||||
/// i.e. this arg will be required unless all these other arguments are present.
|
||||
#[serde(alias = "required-unless-present-all")]
|
||||
pub required_unless_present_all: Option<Vec<String>>,
|
||||
/// Sets args that override this arg's required setting
|
||||
/// i.e. this arg will be required unless at least one of these other arguments are present.
|
||||
#[serde(alias = "required-unless-present-any")]
|
||||
pub required_unless_present_any: Option<Vec<String>>,
|
||||
/// Sets a conflicting argument by name
|
||||
/// i.e. when using this argument, the following argument can't be present and vice versa.
|
||||
#[serde(alias = "conflicts-with")]
|
||||
pub conflicts_with: Option<String>,
|
||||
/// The same as conflictsWith but allows specifying multiple two-way conflicts per argument.
|
||||
#[serde(alias = "conflicts-with-all")]
|
||||
pub conflicts_with_all: Option<Vec<String>>,
|
||||
/// Tets an argument by name that is required when this one is present
|
||||
/// i.e. when using this argument, the following argument must be present.
|
||||
pub requires: Option<String>,
|
||||
/// Sts multiple arguments by names that are required when this one is present
|
||||
/// i.e. when using this argument, the following arguments must be present.
|
||||
#[serde(alias = "requires-all")]
|
||||
pub requires_all: Option<Vec<String>>,
|
||||
/// Allows a conditional requirement with the signature [arg, value]
|
||||
/// the requirement will only become valid if `arg`'s value equals `${value}`.
|
||||
#[serde(alias = "requires-if")]
|
||||
pub requires_if: Option<Vec<String>>,
|
||||
/// Allows specifying that an argument is required conditionally with the signature [arg, value]
|
||||
/// the requirement will only become valid if the `arg`'s value equals `${value}`.
|
||||
#[serde(alias = "requires-if-eq")]
|
||||
pub required_if_eq: Option<Vec<String>>,
|
||||
/// Requires that options use the --option=val syntax
|
||||
/// i.e. an equals between the option and associated value.
|
||||
#[serde(alias = "requires-equals")]
|
||||
pub require_equals: Option<bool>,
|
||||
/// The positional argument index, starting at 1.
|
||||
///
|
||||
@@ -697,14 +725,17 @@ pub struct CliConfig {
|
||||
/// Command description which will be shown on the help information.
|
||||
pub description: Option<String>,
|
||||
/// Command long description which will be shown on the help information.
|
||||
#[serde(alias = "long-description")]
|
||||
pub long_description: Option<String>,
|
||||
/// Adds additional help information to be displayed in addition to auto-generated help.
|
||||
/// This information is displayed before the auto-generated help information.
|
||||
/// This is often used for header information.
|
||||
#[serde(alias = "before-help")]
|
||||
pub before_help: Option<String>,
|
||||
/// Adds additional help information to be displayed in addition to auto-generated help.
|
||||
/// This information is displayed after the auto-generated help information.
|
||||
/// This is often used to describe how to use the arguments, or caveats to be noted.
|
||||
#[serde(alias = "after-help")]
|
||||
pub after_help: Option<String>,
|
||||
/// List of arguments for the command
|
||||
pub args: Option<Vec<CliArg>>,
|
||||
@@ -763,7 +794,7 @@ pub struct WindowConfig {
|
||||
/// Whether the file drop is enabled or not on the webview. By default it is enabled.
|
||||
///
|
||||
/// Disabling it is required to use drag and drop on the frontend on Windows.
|
||||
#[serde(default = "default_file_drop_enabled")]
|
||||
#[serde(default = "default_file_drop_enabled", alias = "file-drop-enabled")]
|
||||
pub file_drop_enabled: bool,
|
||||
/// Whether or not the window starts centered or not.
|
||||
#[serde(default)]
|
||||
@@ -779,12 +810,16 @@ pub struct WindowConfig {
|
||||
#[serde(default = "default_height")]
|
||||
pub height: f64,
|
||||
/// The min window width.
|
||||
#[serde(alias = "min-width")]
|
||||
pub min_width: Option<f64>,
|
||||
/// The min window height.
|
||||
#[serde(alias = "min-height")]
|
||||
pub min_height: Option<f64>,
|
||||
/// The max window width.
|
||||
#[serde(alias = "max-width")]
|
||||
pub max_width: Option<f64>,
|
||||
/// The max window height.
|
||||
#[serde(alias = "max-height")]
|
||||
pub max_height: Option<f64>,
|
||||
/// Whether the window is resizable or not.
|
||||
#[serde(default = "default_resizable")]
|
||||
@@ -800,7 +835,7 @@ pub struct WindowConfig {
|
||||
pub focus: bool,
|
||||
/// Whether the window is transparent or not.
|
||||
///
|
||||
/// Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri.conf.json > tauri > macOSPrivateApi`.
|
||||
/// Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri > macOSPrivateApi`.
|
||||
/// WARNING: Using private APIs on `macOS` prevents your application from being accepted to the `App Store`.
|
||||
#[serde(default)]
|
||||
pub transparent: bool,
|
||||
@@ -814,10 +849,10 @@ pub struct WindowConfig {
|
||||
#[serde(default = "default_decorations")]
|
||||
pub decorations: bool,
|
||||
/// Whether the window should always be on top of other windows.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "always-on-top")]
|
||||
pub always_on_top: bool,
|
||||
/// Whether or not the window icon should be added to the taskbar.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "skip-taskbar")]
|
||||
pub skip_taskbar: bool,
|
||||
/// The initial window theme. Defaults to the system theme. Only implemented on Windows and macOS 10.14+.
|
||||
pub theme: Option<crate::Theme>,
|
||||
@@ -1048,9 +1083,10 @@ pub struct SecurityConfig {
|
||||
///
|
||||
/// This is a really important part of the configuration since it helps you ensure your WebView is secured.
|
||||
/// See <https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP>.
|
||||
#[serde(alias = "dev-csp")]
|
||||
pub dev_csp: Option<Csp>,
|
||||
/// Freeze the `Object.prototype` when using the custom protocol.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "freeze-prototype")]
|
||||
pub freeze_prototype: bool,
|
||||
/// Disables the Tauri-injected CSP sources.
|
||||
///
|
||||
@@ -1064,7 +1100,7 @@ pub struct SecurityConfig {
|
||||
///
|
||||
/// **WARNING:** Only disable this if you know what you are doing and have properly configured the CSP.
|
||||
/// Your application might be vulnerable to XSS attacks without this Tauri protection.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "dangerous-disable-asset-csp-modification")]
|
||||
pub dangerous_disable_asset_csp_modification: DisabledCspModificationKind,
|
||||
}
|
||||
|
||||
@@ -1145,28 +1181,28 @@ pub struct FsAllowlistConfig {
|
||||
#[serde(default)]
|
||||
pub all: bool,
|
||||
/// Read file from local filesystem.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "read-file")]
|
||||
pub read_file: bool,
|
||||
/// Write file to local filesystem.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "write-file")]
|
||||
pub write_file: bool,
|
||||
/// Read directory from local filesystem.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "read-dir")]
|
||||
pub read_dir: bool,
|
||||
/// Copy file from local filesystem.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "copy-file")]
|
||||
pub copy_file: bool,
|
||||
/// Create directory from local filesystem.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "create-dir")]
|
||||
pub create_dir: bool,
|
||||
/// Remove directory from local filesystem.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "remove-dir")]
|
||||
pub remove_dir: bool,
|
||||
/// Remove file from local filesystem.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "remove-file")]
|
||||
pub remove_file: bool,
|
||||
/// Rename file from local filesystem.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "rename-file")]
|
||||
pub rename_file: bool,
|
||||
}
|
||||
|
||||
@@ -1222,13 +1258,13 @@ pub struct WindowAllowlistConfig {
|
||||
#[serde(default)]
|
||||
pub center: bool,
|
||||
/// Allows requesting user attention on the window.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "request-user-attention")]
|
||||
pub request_user_attention: bool,
|
||||
/// Allows setting the resizable flag of the window.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "set-resizable")]
|
||||
pub set_resizable: bool,
|
||||
/// Allows changing the window title.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "set-title")]
|
||||
pub set_title: bool,
|
||||
/// Allows maximizing the window.
|
||||
#[serde(default)]
|
||||
@@ -1252,37 +1288,37 @@ pub struct WindowAllowlistConfig {
|
||||
#[serde(default)]
|
||||
pub close: bool,
|
||||
/// Allows setting the decorations flag of the window.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "set-decorations")]
|
||||
pub set_decorations: bool,
|
||||
/// Allows setting the always_on_top flag of the window.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "set-always-on-top")]
|
||||
pub set_always_on_top: bool,
|
||||
/// Allows setting the window size.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "set-size")]
|
||||
pub set_size: bool,
|
||||
/// Allows setting the window minimum size.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "set-min-size")]
|
||||
pub set_min_size: bool,
|
||||
/// Allows setting the window maximum size.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "set-max-size")]
|
||||
pub set_max_size: bool,
|
||||
/// Allows changing the position of the window.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "set-position")]
|
||||
pub set_position: bool,
|
||||
/// Allows setting the fullscreen flag of the window.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "set-fullscreen")]
|
||||
pub set_fullscreen: bool,
|
||||
/// Allows focusing the window.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "set-focus")]
|
||||
pub set_focus: bool,
|
||||
/// Allows changing the window icon.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "set-icon")]
|
||||
pub set_icon: bool,
|
||||
/// Allows setting the skip_taskbar flag of the window.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "set-skip-taskbar")]
|
||||
pub set_skip_taskbar: bool,
|
||||
/// Allows start dragging on the window.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "start-dragging")]
|
||||
pub start_dragging: bool,
|
||||
/// Allows opening the system dialog to print the window content.
|
||||
#[serde(default)]
|
||||
@@ -1779,7 +1815,7 @@ impl Allowlist for PathAllowlistConfig {
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct ProtocolAllowlistConfig {
|
||||
/// The access scope for the asset protocol.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "asset-scope")]
|
||||
pub asset_scope: FsAllowlistScope,
|
||||
/// Use this flag to enable all custom protocols.
|
||||
#[serde(default)]
|
||||
@@ -1827,7 +1863,11 @@ pub struct ProcessAllowlistConfig {
|
||||
///
|
||||
/// This is due to macOS having less symlink protection. Highly recommended to not set this flag
|
||||
/// unless you have a very specific reason too, and understand the implications of it.
|
||||
#[serde(default)]
|
||||
#[serde(
|
||||
default,
|
||||
alias = "relaunchDangerousAllowSymlinkMacOS",
|
||||
alias = "relaunch-dangerous-allow-symlink-macos"
|
||||
)]
|
||||
pub relaunch_dangerous_allow_symlink_macos: bool,
|
||||
/// Enables the exit API.
|
||||
#[serde(default)]
|
||||
@@ -1874,10 +1914,10 @@ pub struct ClipboardAllowlistConfig {
|
||||
#[serde(default)]
|
||||
pub all: bool,
|
||||
/// Enables the clipboard's `writeText` API.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "writeText")]
|
||||
pub write_text: bool,
|
||||
/// Enables the clipboard's `readText` API.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "readText")]
|
||||
pub read_text: bool,
|
||||
}
|
||||
|
||||
@@ -1932,7 +1972,7 @@ pub struct AllowlistConfig {
|
||||
#[serde(default)]
|
||||
pub notification: NotificationAllowlistConfig,
|
||||
/// Global shortcut API allowlist.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "global-shortcut")]
|
||||
pub global_shortcut: GlobalShortcutAllowlistConfig,
|
||||
/// OS allowlist.
|
||||
#[serde(default)]
|
||||
@@ -2040,9 +2080,10 @@ pub struct TauriConfig {
|
||||
#[serde(default)]
|
||||
pub updater: UpdaterConfig,
|
||||
/// Configuration for app system tray.
|
||||
#[serde(alias = "system-tray")]
|
||||
pub system_tray: Option<SystemTrayConfig>,
|
||||
/// MacOS private API configuration. Enables the transparent background API and sets the `fullScreenEnabled` preference to `true`.
|
||||
#[serde(rename = "macOSPrivateApi", default)]
|
||||
#[serde(rename = "macOSPrivateApi", alias = "macos-private-api", default)]
|
||||
pub macos_private_api: bool,
|
||||
}
|
||||
|
||||
@@ -2199,7 +2240,7 @@ impl<'de> Deserialize<'de> for WindowsUpdateInstallMode {
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct UpdaterWindowsConfig {
|
||||
/// The installation mode for the update on Windows. Defaults to `passive`.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "install-mode")]
|
||||
pub install_mode: WindowsUpdateInstallMode,
|
||||
}
|
||||
|
||||
@@ -2291,12 +2332,16 @@ pub struct SystemTrayConfig {
|
||||
/// Path to the icon to use on the system tray.
|
||||
///
|
||||
/// It is forced to be a `.png` file on Linux and macOS, and a `.ico` file on Windows.
|
||||
#[serde(alias = "icon-path")]
|
||||
pub icon_path: PathBuf,
|
||||
/// A Boolean value that determines whether the image represents a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) image on macOS.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "icon-as-template")]
|
||||
pub icon_as_template: bool,
|
||||
/// A Boolean value that determines whether the menu should appear when the tray icon receives a left click on macOS.
|
||||
#[serde(default = "default_tray_menu_on_left_click")]
|
||||
#[serde(
|
||||
default = "default_tray_menu_on_left_click",
|
||||
alias = "menu-on-left-click"
|
||||
)]
|
||||
pub menu_on_left_click: bool,
|
||||
}
|
||||
|
||||
@@ -2347,7 +2392,7 @@ pub struct BuildConfig {
|
||||
///
|
||||
/// See [vite](https://vitejs.dev/guide/), [Webpack DevServer](https://webpack.js.org/configuration/dev-server/) and [sirv](https://github.com/lukeed/sirv)
|
||||
/// for examples on how to set up a dev server.
|
||||
#[serde(default = "default_dev_path")]
|
||||
#[serde(default = "default_dev_path", alias = "dev-path")]
|
||||
pub dev_path: AppUrl,
|
||||
/// The path to the application assets or URL to load in production.
|
||||
///
|
||||
@@ -2360,20 +2405,22 @@ pub struct BuildConfig {
|
||||
///
|
||||
/// When an URL is provided, the application won't have bundled assets
|
||||
/// and the application will load that URL by default.
|
||||
#[serde(default = "default_dist_dir")]
|
||||
#[serde(default = "default_dist_dir", alias = "dist-dir")]
|
||||
pub dist_dir: AppUrl,
|
||||
/// A shell command to run before `tauri dev` kicks in.
|
||||
///
|
||||
/// The TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG environment variables are set if you perform conditional compilation.
|
||||
#[serde(alias = "before-dev-command")]
|
||||
pub before_dev_command: Option<String>,
|
||||
/// A shell command to run before `tauri build` kicks in.
|
||||
///
|
||||
/// The TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG environment variables are set if you perform conditional compilation.
|
||||
#[serde(alias = "before-build-command")]
|
||||
pub before_build_command: Option<String>,
|
||||
/// Features passed to `cargo` commands.
|
||||
pub features: Option<Vec<String>>,
|
||||
/// Whether we should inject the Tauri API on `window.__TAURI__` or not.
|
||||
#[serde(default)]
|
||||
#[serde(default, alias = "with-global-tauri")]
|
||||
pub with_global_tauri: bool,
|
||||
}
|
||||
|
||||
@@ -2463,6 +2510,7 @@ impl<'d> serde::Deserialize<'d> for PackageVersion {
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct PackageConfig {
|
||||
/// App name.
|
||||
#[serde(alias = "product-name")]
|
||||
pub product_name: Option<String>,
|
||||
/// App version. It is a semver version number or a path to a `package.json` file contaning the `version` field.
|
||||
#[serde(deserialize_with = "version_deserializer", default)]
|
||||
@@ -2491,22 +2539,36 @@ impl PackageConfig {
|
||||
}
|
||||
}
|
||||
|
||||
/// The tauri.conf.json is a file generated by the
|
||||
/// The Tauri configuration object.
|
||||
/// It is read from a file where you can define your frontend assets,
|
||||
/// configure the bundler, enable the app updater, define a system tray,
|
||||
/// enable APIs via the allowlist and more.
|
||||
///
|
||||
/// The configuration file is generated by the
|
||||
/// [`tauri init`](https://tauri.app/v1/api/cli#init) command that lives in
|
||||
/// your Tauri application source directory (src-tauri).
|
||||
///
|
||||
/// Once generated, you may modify it at will to customize your Tauri application.
|
||||
///
|
||||
/// ## File Formats
|
||||
///
|
||||
/// By default, the configuration is defined as a JSON file named `tauri.conf.json`.
|
||||
///
|
||||
/// Tauri also supports JSON5 and TOML files via the `config-json5` and `config-toml` Cargo features, respectively.
|
||||
/// The JSON5 file name must be either `tauri.conf.json` or `tauri.conf.json5`.
|
||||
/// The TOML file name is `Tauri.toml`.
|
||||
///
|
||||
/// ## Platform-Specific Configuration
|
||||
///
|
||||
/// In addition to the JSON defined on the `tauri.conf.json` file, Tauri can
|
||||
/// In addition to the default configuration file, Tauri can
|
||||
/// read a platform-specific configuration from `tauri.linux.conf.json`,
|
||||
/// `tauri.windows.conf.json`, and `tauri.macos.conf.json` and merges it with
|
||||
/// the main `tauri.conf.json` configuration.
|
||||
/// `tauri.windows.conf.json`, and `tauri.macos.conf.json`
|
||||
/// (or `Tauri.linux.toml`, `Tauri.windows.toml` and `Tauri.macos.toml` if the `Tauri.toml` format is used),
|
||||
/// which gets merged with the main configuration object.
|
||||
///
|
||||
/// ## Configuration Structure
|
||||
///
|
||||
/// `tauri.conf.json` is composed of the following objects:
|
||||
/// The configuration is composed of the following objects:
|
||||
///
|
||||
/// - [`package`](#packageconfig): Package settings
|
||||
/// - [`tauri`](#tauriconfig): The Tauri config
|
||||
|
||||
@@ -11,15 +11,75 @@ use std::path::{Path, PathBuf};
|
||||
use thiserror::Error;
|
||||
|
||||
/// All extensions that are possibly supported, but perhaps not enabled.
|
||||
pub const EXTENSIONS_SUPPORTED: &[&str] = &["json", "json5"];
|
||||
pub const EXTENSIONS_SUPPORTED: &[&str] = &["json", "json5", "toml"];
|
||||
|
||||
/// All extensions that are currently enabled.
|
||||
pub const EXTENSIONS_ENABLED: &[&str] = &[
|
||||
"json",
|
||||
/// All configuration formats that are possibly supported, but perhaps not enabled.
|
||||
pub const SUPPORTED_FORMATS: &[ConfigFormat] =
|
||||
&[ConfigFormat::Json, ConfigFormat::Json5, ConfigFormat::Toml];
|
||||
|
||||
/// All configuration formats that are currently enabled.
|
||||
pub const ENABLED_FORMATS: &[ConfigFormat] = &[
|
||||
ConfigFormat::Json,
|
||||
#[cfg(feature = "config-json5")]
|
||||
"json5",
|
||||
ConfigFormat::Json5,
|
||||
#[cfg(feature = "config-toml")]
|
||||
ConfigFormat::Toml,
|
||||
];
|
||||
|
||||
/// The available configuration formats.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ConfigFormat {
|
||||
/// The default JSON (tauri.conf.json) format.
|
||||
Json,
|
||||
/// The JSON5 (tauri.conf.json5) format.
|
||||
Json5,
|
||||
/// The TOML (Tauri.toml file) format.
|
||||
Toml,
|
||||
}
|
||||
|
||||
impl ConfigFormat {
|
||||
/// Maps the config format to its file name.
|
||||
pub fn into_file_name(self) -> &'static str {
|
||||
match self {
|
||||
Self::Json => "tauri.conf.json",
|
||||
Self::Json5 => "tauri.conf.json5",
|
||||
Self::Toml => "Tauri.toml",
|
||||
}
|
||||
}
|
||||
|
||||
fn into_platform_file_name(self) -> &'static str {
|
||||
match self {
|
||||
Self::Json => {
|
||||
if cfg!(target_os = "macos") {
|
||||
"tauri.macos.conf.json"
|
||||
} else if cfg!(windows) {
|
||||
"tauri.windows.conf.json"
|
||||
} else {
|
||||
"tauri.linux.conf.json"
|
||||
}
|
||||
}
|
||||
Self::Json5 => {
|
||||
if cfg!(target_os = "macos") {
|
||||
"tauri.macos.conf.json5"
|
||||
} else if cfg!(windows) {
|
||||
"tauri.windows.conf.json5"
|
||||
} else {
|
||||
"tauri.linux.conf.json5"
|
||||
}
|
||||
}
|
||||
Self::Toml => {
|
||||
if cfg!(target_os = "macos") {
|
||||
"Tauri.macos.toml"
|
||||
} else if cfg!(windows) {
|
||||
"Tauri.windows.toml"
|
||||
} else {
|
||||
"Tauri.linux.toml"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents all the errors that can happen while reading the config.
|
||||
#[derive(Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
@@ -45,7 +105,18 @@ pub enum ConfigError {
|
||||
error: ::json5::Error,
|
||||
},
|
||||
|
||||
/// Unknown file extension encountered.
|
||||
/// Failed to parse from TOML.
|
||||
#[cfg(feature = "config-toml")]
|
||||
#[error("unable to parse toml Tauri config file at {path} because {error}")]
|
||||
FormatToml {
|
||||
/// The path that failed to parse into TOML.
|
||||
path: PathBuf,
|
||||
|
||||
/// The parsing [`toml::Error`].
|
||||
error: ::toml::de::Error,
|
||||
},
|
||||
|
||||
/// Unknown config file name encountered.
|
||||
#[error("unsupported format encountered {0}")]
|
||||
UnsupportedFormat(String),
|
||||
|
||||
@@ -81,32 +152,21 @@ pub enum ConfigError {
|
||||
///
|
||||
/// [JSON Merge Patch (RFC 7396)]: https://datatracker.ietf.org/doc/html/rfc7396.
|
||||
pub fn read_from(root_dir: PathBuf) -> Result<Value, ConfigError> {
|
||||
let mut config: Value = parse_value(root_dir.join("tauri.conf.json"))?;
|
||||
if let Some(platform_config) = read_platform(root_dir)? {
|
||||
let mut config: Value = parse_value(root_dir.join("tauri.conf.json"))?.0;
|
||||
if let Some((platform_config, _)) = read_platform(root_dir)? {
|
||||
merge(&mut config, &platform_config);
|
||||
}
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
/// Gets the platform configuration file name.
|
||||
pub fn get_platform_config_filename() -> &'static str {
|
||||
if cfg!(target_os = "macos") {
|
||||
"tauri.macos.conf.json"
|
||||
} else if cfg!(windows) {
|
||||
"tauri.windows.conf.json"
|
||||
} else {
|
||||
"tauri.linux.conf.json"
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads the platform-specific configuration file from the given root directory if it exists.
|
||||
///
|
||||
/// Check [`read_from`] for more information.
|
||||
pub fn read_platform(root_dir: PathBuf) -> Result<Option<Value>, ConfigError> {
|
||||
let platform_config_path = root_dir.join(get_platform_config_filename());
|
||||
if does_supported_extension_exist(&platform_config_path) {
|
||||
let platform_config: Value = parse_value(platform_config_path)?;
|
||||
Ok(Some(platform_config))
|
||||
pub fn read_platform(root_dir: PathBuf) -> Result<Option<(Value, PathBuf)>, ConfigError> {
|
||||
let platform_config_path = root_dir.join(ConfigFormat::Json.into_platform_file_name());
|
||||
if does_supported_file_name_exist(&platform_config_path) {
|
||||
let (platform_config, path): (Value, PathBuf) = parse_value(platform_config_path)?;
|
||||
Ok(Some((platform_config, path)))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
@@ -116,11 +176,21 @@ pub fn read_platform(root_dir: PathBuf) -> Result<Option<Value>, ConfigError> {
|
||||
///
|
||||
/// The passed path is expected to be the path to the "default" configuration format, in this case
|
||||
/// JSON with `.json`.
|
||||
pub fn does_supported_extension_exist(path: impl Into<PathBuf>) -> bool {
|
||||
pub fn does_supported_file_name_exist(path: impl Into<PathBuf>) -> bool {
|
||||
let path = path.into();
|
||||
EXTENSIONS_ENABLED
|
||||
let source_file_name = path.file_name().unwrap().to_str().unwrap();
|
||||
let lookup_platform_config = ENABLED_FORMATS
|
||||
.iter()
|
||||
.any(|ext| path.with_extension(ext).exists())
|
||||
.any(|format| source_file_name == format.into_platform_file_name());
|
||||
ENABLED_FORMATS.iter().any(|format| {
|
||||
path
|
||||
.with_file_name(if lookup_platform_config {
|
||||
format.into_platform_file_name()
|
||||
} else {
|
||||
format.into_file_name()
|
||||
})
|
||||
.exists()
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse the config from path, including alternative formats.
|
||||
@@ -133,18 +203,39 @@ pub fn does_supported_extension_exist(path: impl Into<PathBuf>) -> bool {
|
||||
/// 2. Check if `tauri.conf.json5` exists
|
||||
/// a. Parse it with `json5`
|
||||
/// b. Return error if all above steps failed
|
||||
/// 3. Return error if all above steps failed
|
||||
pub fn parse(path: impl Into<PathBuf>) -> Result<Config, ConfigError> {
|
||||
/// 3. Check if `Tauri.json` exists
|
||||
/// a. Parse it with `toml`
|
||||
/// b. Return error if all above steps failed
|
||||
/// 4. Return error if all above steps failed
|
||||
pub fn parse(path: impl Into<PathBuf>) -> Result<(Config, PathBuf), ConfigError> {
|
||||
do_parse(path.into())
|
||||
}
|
||||
|
||||
/// See [`parse`] for specifics, returns a JSON [`Value`] instead of [`Config`].
|
||||
pub fn parse_value(path: impl Into<PathBuf>) -> Result<Value, ConfigError> {
|
||||
pub fn parse_value(path: impl Into<PathBuf>) -> Result<(Value, PathBuf), ConfigError> {
|
||||
do_parse(path.into())
|
||||
}
|
||||
|
||||
fn do_parse<D: DeserializeOwned>(path: PathBuf) -> Result<D, ConfigError> {
|
||||
let json5 = path.with_extension("json5");
|
||||
fn do_parse<D: DeserializeOwned>(path: PathBuf) -> Result<(D, PathBuf), ConfigError> {
|
||||
let file_name = path
|
||||
.file_name()
|
||||
.map(OsStr::to_string_lossy)
|
||||
.unwrap_or_default();
|
||||
let lookup_platform_config = ENABLED_FORMATS
|
||||
.iter()
|
||||
.any(|format| file_name == format.into_platform_file_name());
|
||||
|
||||
let json5 = path.with_file_name(if lookup_platform_config {
|
||||
ConfigFormat::Json5.into_platform_file_name()
|
||||
} else {
|
||||
ConfigFormat::Json5.into_file_name()
|
||||
});
|
||||
let toml = path.with_file_name(if lookup_platform_config {
|
||||
ConfigFormat::Toml.into_platform_file_name()
|
||||
} else {
|
||||
ConfigFormat::Toml.into_file_name()
|
||||
});
|
||||
|
||||
let path_ext = path
|
||||
.extension()
|
||||
.map(OsStr::to_string_lossy)
|
||||
@@ -171,12 +262,12 @@ fn do_parse<D: DeserializeOwned>(path: PathBuf) -> Result<D, ConfigError> {
|
||||
}
|
||||
};
|
||||
|
||||
json
|
||||
json.map(|j| (j, path))
|
||||
} else if json5.exists() {
|
||||
#[cfg(feature = "config-json5")]
|
||||
{
|
||||
let raw = read_to_string(&json5)?;
|
||||
do_parse_json5(&raw, &path)
|
||||
do_parse_json5(&raw, &path).map(|config| (config, json5))
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "config-json5"))]
|
||||
@@ -184,6 +275,18 @@ fn do_parse<D: DeserializeOwned>(path: PathBuf) -> Result<D, ConfigError> {
|
||||
extension: ".json5".into(),
|
||||
feature: "config-json5".into(),
|
||||
})
|
||||
} else if toml.exists() {
|
||||
#[cfg(feature = "config-toml")]
|
||||
{
|
||||
let raw = read_to_string(&toml)?;
|
||||
do_parse_toml(&raw, &path).map(|config| (config, toml))
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "config-toml"))]
|
||||
Err(ConfigError::DisabledFormat {
|
||||
extension: ".toml".into(),
|
||||
feature: "config-toml".into(),
|
||||
})
|
||||
} else if !EXTENSIONS_SUPPORTED.contains(&path_ext.as_ref()) {
|
||||
Err(ConfigError::UnsupportedFormat(path_ext.to_string()))
|
||||
} else {
|
||||
@@ -241,6 +344,14 @@ fn do_parse_json5<D: DeserializeOwned>(raw: &str, path: &Path) -> Result<D, Conf
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "config-toml")]
|
||||
fn do_parse_toml<D: DeserializeOwned>(raw: &str, path: &Path) -> Result<D, ConfigError> {
|
||||
::toml::from_str(raw).map_err(|error| ConfigError::FormatToml {
|
||||
path: path.into(),
|
||||
error,
|
||||
})
|
||||
}
|
||||
|
||||
/// Helper function to wrap IO errors from [`std::fs::read_to_string`] into a [`ConfigError`].
|
||||
fn read_to_string(path: &Path) -> Result<String, ConfigError> {
|
||||
std::fs::read_to_string(path).map_err(|error| ConfigError::Io {
|
||||
|
||||
@@ -285,6 +285,7 @@ window-set-cursor-position = [ ]
|
||||
window-start-dragging = [ ]
|
||||
window-print = [ ]
|
||||
config-json5 = [ "tauri-macros/config-json5" ]
|
||||
config-toml = [ "tauri-macros/config-toml" ]
|
||||
icon-ico = [ "infer", "ico" ]
|
||||
icon-png = [ "infer", "png" ]
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
//! - **window-data-url**: Enables usage of data URLs on the webview.
|
||||
//! - **compression** *(enabled by default): Enables asset compression. You should only disable this if you want faster compile times in release builds - it produces larger binaries.
|
||||
//! - **config-json5**: Adds support to JSON5 format for `tauri.conf.json`.
|
||||
//! - **config-toml**: Adds support to TOML format for the configuration `Tauri.toml`.
|
||||
//! - **icon-ico**: Adds support to set `.ico` window icons. Enables [`Icon::File`] and [`Icon::Raw`] variants.
|
||||
//! - **icon-png**: Adds support to set `.png` window icons. Enables [`Icon::File`] and [`Icon::Raw`] variants.
|
||||
//!
|
||||
|
||||
1
tooling/cli/Cargo.lock
generated
1
tooling/cli/Cargo.lock
generated
@@ -2933,6 +2933,7 @@ dependencies = [
|
||||
"serde_with 1.14.0",
|
||||
"serialize-to-javascript",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"url",
|
||||
"walkdir",
|
||||
"windows",
|
||||
|
||||
@@ -39,7 +39,7 @@ notify = "4.0"
|
||||
shared_child = "1.0"
|
||||
toml_edit = "0.14"
|
||||
json-patch = "0.2"
|
||||
tauri-utils = { version = "1.0.3", path = "../../core/tauri-utils", features = [ "isolation", "schema", "config-json5" ] }
|
||||
tauri-utils = { version = "1.0.3", path = "../../core/tauri-utils", features = [ "isolation", "schema", "config-json5", "config-toml" ] }
|
||||
toml = "0.5"
|
||||
valico = "3.6"
|
||||
handlebars = "4.3"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Config",
|
||||
"description": "The tauri.conf.json is a file generated by the [`tauri init`](https://tauri.app/v1/api/cli#init) command that lives in your Tauri application source directory (src-tauri).\n\nOnce generated, you may modify it at will to customize your Tauri application.\n\n## Platform-Specific Configuration\n\nIn addition to the JSON defined on the `tauri.conf.json` file, Tauri can read a platform-specific configuration from `tauri.linux.conf.json`, `tauri.windows.conf.json`, and `tauri.macos.conf.json` and merges it with the main `tauri.conf.json` configuration.\n\n## Configuration Structure\n\n`tauri.conf.json` is composed of the following objects:\n\n- [`package`](#packageconfig): Package settings - [`tauri`](#tauriconfig): The Tauri config - [`build`](#buildconfig): The build configuration - [`plugins`](#pluginconfig): The plugins config\n\n```json title=\"Example tauri.config.json file\" { \"build\": { \"beforeBuildCommand\": \"\", \"beforeDevCommand\": \"\", \"devPath\": \"../dist\", \"distDir\": \"../dist\" }, \"package\": { \"productName\": \"tauri-app\", \"version\": \"0.1.0\" }, \"tauri\": { \"allowlist\": { \"all\": true }, \"bundle\": {}, \"security\": { \"csp\": null }, \"updater\": { \"active\": false }, \"windows\": [ { \"fullscreen\": false, \"height\": 600, \"resizable\": true, \"title\": \"Tauri App\", \"width\": 800 } ] } } ```",
|
||||
"description": "The Tauri configuration object. It is read from a file where you can define your frontend assets, configure the bundler, enable the app updater, define a system tray, enable APIs via the allowlist and more.\n\nThe configuration file is generated by the [`tauri init`](https://tauri.app/v1/api/cli#init) command that lives in your Tauri application source directory (src-tauri).\n\nOnce generated, you may modify it at will to customize your Tauri application.\n\n## File Formats\n\nBy default, the configuration is defined as a JSON file named `tauri.conf.json`.\n\nTauri also supports JSON5 and TOML files via the `config-json5` and `config-toml` Cargo features, respectively. The JSON5 file name must be either `tauri.conf.json` or `tauri.conf.json5`. The TOML file name is `Tauri.toml`.\n\n## Platform-Specific Configuration\n\nIn addition to the default configuration file, Tauri can read a platform-specific configuration from `tauri.linux.conf.json`, `tauri.windows.conf.json`, and `tauri.macos.conf.json` (or `Tauri.linux.toml`, `Tauri.windows.toml` and `Tauri.macos.toml` if the `Tauri.toml` format is used), which gets merged with the main configuration object.\n\n## Configuration Structure\n\nThe configuration is composed of the following objects:\n\n- [`package`](#packageconfig): Package settings - [`tauri`](#tauriconfig): The Tauri config - [`build`](#buildconfig): The build configuration - [`plugins`](#pluginconfig): The plugins config\n\n```json title=\"Example tauri.config.json file\" { \"build\": { \"beforeBuildCommand\": \"\", \"beforeDevCommand\": \"\", \"devPath\": \"../dist\", \"distDir\": \"../dist\" }, \"package\": { \"productName\": \"tauri-app\", \"version\": \"0.1.0\" }, \"tauri\": { \"allowlist\": { \"all\": true }, \"bundle\": {}, \"security\": { \"csp\": null }, \"updater\": { \"active\": false }, \"windows\": [ { \"fullscreen\": false, \"height\": 600, \"resizable\": true, \"title\": \"Tauri App\", \"width\": 800 } ] } } ```",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"$schema": {
|
||||
@@ -587,7 +587,7 @@
|
||||
"type": "boolean"
|
||||
},
|
||||
"transparent": {
|
||||
"description": "Whether the window is transparent or not.\n\nNote that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri.conf.json > tauri > macOSPrivateApi`. WARNING: Using private APIs on `macOS` prevents your application from being accepted to the `App Store`.",
|
||||
"description": "Whether the window is transparent or not.\n\nNote that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri > macOSPrivateApi`. WARNING: Using private APIs on `macOS` prevents your application from being accepted to the `App Store`.",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
|
||||
@@ -84,10 +84,8 @@ pub fn command(mut options: Options) -> Result<()> {
|
||||
let config_ = config_guard.as_ref().unwrap();
|
||||
|
||||
let bundle_identifier_source = match config_.find_bundle_identifier_overwriter() {
|
||||
Some(source) if source == MERGE_CONFIG_EXTENSION_NAME => {
|
||||
merge_config_path.unwrap_or_else(|| source.into())
|
||||
}
|
||||
Some(source) => source.into(),
|
||||
Some(source) if source == MERGE_CONFIG_EXTENSION_NAME => merge_config_path.unwrap_or(source),
|
||||
Some(source) => source,
|
||||
None => "tauri.conf.json".into(),
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ use std::{
|
||||
use ignore::WalkBuilder;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use tauri_utils::config::parse::ConfigFormat;
|
||||
|
||||
const TAURI_GITIGNORE: &[u8] = include_bytes!("../../tauri.gitignore");
|
||||
|
||||
fn lookup<F: Fn(&PathBuf, FileType) -> bool>(dir: &Path, checker: F) -> Option<PathBuf> {
|
||||
@@ -66,14 +68,20 @@ fn get_tauri_dir() -> PathBuf {
|
||||
}
|
||||
|
||||
lookup(&cwd, |path, file_type| if file_type.is_dir() {
|
||||
path.join("tauri.conf.json").exists() || path.join("tauri.conf.json5").exists()
|
||||
path.join(ConfigFormat::Json.into_file_name()).exists() || path.join(ConfigFormat::Json5.into_file_name()).exists() || path.join(ConfigFormat::Toml.into_file_name()).exists()
|
||||
} else if let Some(file_name) = path.file_name() {
|
||||
file_name == OsStr::new("tauri.conf.json") || file_name == OsStr::new("tauri.conf.json5")
|
||||
file_name == OsStr::new(ConfigFormat::Json.into_file_name()) || file_name == OsStr::new(ConfigFormat::Json5.into_file_name()) || file_name == OsStr::new(ConfigFormat::Toml.into_file_name())
|
||||
} else {
|
||||
false
|
||||
})
|
||||
.map(|p| if p.is_dir() { p } else { p.parent().unwrap().to_path_buf() })
|
||||
.expect("Couldn't recognize the current folder as a Tauri project. It must contain a `tauri.conf.json` or `tauri.conf.json5` file in any subfolder.")
|
||||
.unwrap_or_else(||
|
||||
panic!("Couldn't recognize the current folder as a Tauri project. It must contain a `{}`, `{}` or `{}` file in any subfolder.",
|
||||
ConfigFormat::Json.into_file_name(),
|
||||
ConfigFormat::Json5.into_file_name(),
|
||||
ConfigFormat::Toml.into_file_name()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fn get_app_dir() -> Option<PathBuf> {
|
||||
|
||||
@@ -12,6 +12,7 @@ pub use tauri_utils::config::*;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
env::set_var,
|
||||
ffi::OsStr,
|
||||
process::exit,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
@@ -23,7 +24,7 @@ pub struct ConfigMetadata {
|
||||
inner: Config,
|
||||
/// The config extensions (platform-specific config files or the config CLI argument).
|
||||
/// Maps the extension name to its value.
|
||||
extensions: HashMap<&'static str, JsonValue>,
|
||||
extensions: HashMap<String, JsonValue>,
|
||||
}
|
||||
|
||||
impl std::ops::Deref for ConfigMetadata {
|
||||
@@ -37,7 +38,7 @@ impl std::ops::Deref for ConfigMetadata {
|
||||
|
||||
impl ConfigMetadata {
|
||||
/// Checks which config is overwriting the bundle identifier.
|
||||
pub fn find_bundle_identifier_overwriter(&self) -> Option<&'static str> {
|
||||
pub fn find_bundle_identifier_overwriter(&self) -> Option<String> {
|
||||
for (ext, config) in &self.extensions {
|
||||
if let Some(identifier) = config
|
||||
.as_object()
|
||||
@@ -49,7 +50,7 @@ impl ConfigMetadata {
|
||||
.and_then(|id| id.as_str())
|
||||
{
|
||||
if identifier == self.inner.tauri.bundle.identifier {
|
||||
return Some(ext);
|
||||
return Some(ext.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,13 +107,17 @@ fn get_internal(merge_config: Option<&str>, reload: bool) -> crate::Result<Confi
|
||||
}
|
||||
|
||||
let tauri_dir = super::app_paths::tauri_dir();
|
||||
let mut config = tauri_utils::config::parse::parse_value(tauri_dir.join("tauri.conf.json"))?;
|
||||
let (mut config, config_path) =
|
||||
tauri_utils::config::parse::parse_value(tauri_dir.join("tauri.conf.json"))?;
|
||||
let config_file_name = config_path.file_name().unwrap().to_string_lossy();
|
||||
let mut extensions = HashMap::new();
|
||||
|
||||
if let Some(platform_config) = tauri_utils::config::parse::read_platform(tauri_dir)? {
|
||||
if let Some((platform_config, config_path)) =
|
||||
tauri_utils::config::parse::read_platform(tauri_dir)?
|
||||
{
|
||||
merge(&mut config, &platform_config);
|
||||
extensions.insert(
|
||||
tauri_utils::config::parse::get_platform_config_filename(),
|
||||
config_path.file_name().unwrap().to_str().unwrap().into(),
|
||||
platform_config,
|
||||
);
|
||||
}
|
||||
@@ -122,35 +127,39 @@ fn get_internal(merge_config: Option<&str>, reload: bool) -> crate::Result<Confi
|
||||
let merge_config: JsonValue =
|
||||
serde_json::from_str(merge_config).with_context(|| "failed to parse config to merge")?;
|
||||
merge(&mut config, &merge_config);
|
||||
extensions.insert(MERGE_CONFIG_EXTENSION_NAME, merge_config);
|
||||
extensions.insert(MERGE_CONFIG_EXTENSION_NAME.into(), merge_config);
|
||||
};
|
||||
|
||||
let schema: JsonValue = serde_json::from_str(include_str!("../../schema.json"))?;
|
||||
let mut scope = valico::json_schema::Scope::new();
|
||||
let schema = scope.compile_and_return(schema, false).unwrap();
|
||||
let state = schema.validate(&config);
|
||||
if !state.errors.is_empty() {
|
||||
for error in state.errors {
|
||||
let path = error
|
||||
.get_path()
|
||||
.chars()
|
||||
.skip(1)
|
||||
.collect::<String>()
|
||||
.replace('/', " > ");
|
||||
if path.is_empty() {
|
||||
eprintln!(
|
||||
"`tauri.conf.json` error: {}",
|
||||
error.get_detail().unwrap_or_else(|| error.get_title()),
|
||||
);
|
||||
} else {
|
||||
eprintln!(
|
||||
"`tauri.conf.json` error on `{}`: {}",
|
||||
path,
|
||||
error.get_detail().unwrap_or_else(|| error.get_title()),
|
||||
);
|
||||
if config_path.extension() == Some(OsStr::new("json"))
|
||||
|| config_path.extension() == Some(OsStr::new("json5"))
|
||||
{
|
||||
let schema: JsonValue = serde_json::from_str(include_str!("../../schema.json"))?;
|
||||
let mut scope = valico::json_schema::Scope::new();
|
||||
let schema = scope.compile_and_return(schema, false).unwrap();
|
||||
let state = schema.validate(&config);
|
||||
if !state.errors.is_empty() {
|
||||
for error in state.errors {
|
||||
let path = error
|
||||
.get_path()
|
||||
.chars()
|
||||
.skip(1)
|
||||
.collect::<String>()
|
||||
.replace('/', " > ");
|
||||
if path.is_empty() {
|
||||
eprintln!(
|
||||
"`{config_file_name}` error: {}",
|
||||
error.get_detail().unwrap_or_else(|| error.get_title()),
|
||||
);
|
||||
} else {
|
||||
eprintln!(
|
||||
"`{config_file_name}` error on `{}`: {}",
|
||||
path,
|
||||
error.get_detail().unwrap_or_else(|| error.get_title()),
|
||||
);
|
||||
}
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
let config: Config = serde_json::from_value(config)?;
|
||||
|
||||
Reference in New Issue
Block a user