config_definition.rs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. // Copyright 2019-2021 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. #![allow(clippy::field_reassign_with_default)]
  5. use schemars::JsonSchema;
  6. use serde::{Deserialize, Serialize};
  7. use serde_json::Value as JsonValue;
  8. use serde_with::skip_serializing_none;
  9. use std::{collections::HashMap, path::PathBuf};
  10. #[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  11. #[serde(untagged)]
  12. pub enum BundleTarget {
  13. All(Vec<String>),
  14. One(String),
  15. }
  16. impl BundleTarget {
  17. #[allow(dead_code)]
  18. pub fn to_vec(&self) -> Vec<String> {
  19. match self {
  20. Self::All(list) => list.clone(),
  21. Self::One(i) => vec![i.clone()],
  22. }
  23. }
  24. }
  25. #[skip_serializing_none]
  26. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  27. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  28. pub struct DebConfig {
  29. pub depends: Option<Vec<String>>,
  30. #[serde(default)]
  31. pub use_bootstrapper: bool,
  32. #[serde(default)]
  33. pub files: HashMap<PathBuf, PathBuf>,
  34. }
  35. #[skip_serializing_none]
  36. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  37. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  38. pub struct MacConfig {
  39. pub frameworks: Option<Vec<String>>,
  40. pub minimum_system_version: Option<String>,
  41. pub exception_domain: Option<String>,
  42. pub license: Option<String>,
  43. #[serde(default)]
  44. pub use_bootstrapper: bool,
  45. pub signing_identity: Option<String>,
  46. pub entitlements: Option<String>,
  47. }
  48. fn default_language() -> String {
  49. "en-US".into()
  50. }
  51. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  52. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  53. pub struct WixConfig {
  54. /// App language. See https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables.
  55. #[serde(default = "default_language")]
  56. pub language: String,
  57. pub template: Option<PathBuf>,
  58. #[serde(default)]
  59. pub fragment_paths: Vec<PathBuf>,
  60. #[serde(default)]
  61. pub component_group_refs: Vec<String>,
  62. #[serde(default)]
  63. pub component_refs: Vec<String>,
  64. #[serde(default)]
  65. pub feature_group_refs: Vec<String>,
  66. #[serde(default)]
  67. pub feature_refs: Vec<String>,
  68. #[serde(default)]
  69. pub merge_refs: Vec<String>,
  70. #[serde(default)]
  71. pub skip_webview_install: bool,
  72. /// Path to the license file.
  73. pub license: Option<String>,
  74. #[serde(default)]
  75. pub enable_elevated_update_task: bool,
  76. }
  77. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  78. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  79. pub struct WindowsConfig {
  80. pub digest_algorithm: Option<String>,
  81. pub certificate_thumbprint: Option<String>,
  82. pub timestamp_url: Option<String>,
  83. pub wix: Option<WixConfig>,
  84. }
  85. #[skip_serializing_none]
  86. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  87. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  88. pub struct PackageConfig {
  89. /// App name. Automatically converted to kebab-case on Linux.
  90. pub product_name: Option<String>,
  91. /// App version.
  92. pub version: Option<String>,
  93. }
  94. #[skip_serializing_none]
  95. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  96. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  97. pub struct BundleConfig {
  98. /// Whether we should build your app with tauri-bundler or plain `cargo build`
  99. #[serde(default)]
  100. pub active: bool,
  101. /// The bundle targets, currently supports ["deb", "app", "msi", "appimage", "dmg"] or "all"
  102. pub targets: Option<BundleTarget>,
  103. /// The app's identifier
  104. pub identifier: Option<String>,
  105. /// The app's icons
  106. pub icon: Option<Vec<String>>,
  107. /// App resources to bundle.
  108. /// Each resource is a path to a file or directory.
  109. /// Glob patterns are supported.
  110. pub resources: Option<Vec<String>>,
  111. pub copyright: Option<String>,
  112. pub category: Option<String>,
  113. pub short_description: Option<String>,
  114. pub long_description: Option<String>,
  115. #[serde(default)]
  116. pub deb: DebConfig,
  117. #[serde(rename = "macOS", default)]
  118. pub macos: MacConfig,
  119. pub external_bin: Option<Vec<String>>,
  120. #[serde(default)]
  121. pub windows: WindowsConfig,
  122. }
  123. /// A CLI argument definition
  124. #[skip_serializing_none]
  125. #[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  126. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  127. pub struct CliArg {
  128. /// The short version of the argument, without the preceding -.
  129. ///
  130. /// NOTE: Any leading - characters will be stripped, and only the first non - character will be used as the short version.
  131. pub short: Option<char>,
  132. /// The unique argument name
  133. pub name: String,
  134. /// The argument description which will be shown on the help information.
  135. /// Typically, this is a short (one line) description of the arg.
  136. pub description: Option<String>,
  137. /// The argument long description which will be shown on the help information.
  138. /// Typically this a more detailed (multi-line) message that describes the argument.
  139. pub long_description: Option<String>,
  140. /// Specifies that the argument takes a value at run time.
  141. ///
  142. /// NOTE: values for arguments may be specified in any of the following methods
  143. /// - Using a space such as -o value or --option value
  144. /// - Using an equals and no space such as -o=value or --option=value
  145. /// - Use a short and no space such as -ovalue
  146. pub takes_value: Option<bool>,
  147. /// Specifies that the argument may appear more than once.
  148. ///
  149. /// - For flags, this results in the number of occurrences of the flag being recorded.
  150. /// For example -ddd or -d -d -d would count as three occurrences.
  151. /// - For options there is a distinct difference in multiple occurrences vs multiple values.
  152. /// For example, --opt val1 val2 is one occurrence, but two values. Whereas --opt val1 --opt val2 is two occurrences.
  153. pub multiple: Option<bool>,
  154. /// specifies that the argument may appear more than once.
  155. pub multiple_occurrences: Option<bool>,
  156. ///
  157. pub number_of_values: Option<u64>,
  158. /// Specifies a list of possible values for this argument.
  159. /// At runtime, the CLI verifies that only one of the specified values was used, or fails with an error message.
  160. pub possible_values: Option<Vec<String>>,
  161. /// Specifies the minimum number of values for this argument.
  162. /// For example, if you had a -f <file> argument where you wanted at least 2 'files',
  163. /// you would set `minValues: 2`, and this argument would be satisfied if the user provided, 2 or more values.
  164. pub min_values: Option<u64>,
  165. /// Specifies the maximum number of values are for this argument.
  166. /// For example, if you had a -f <file> argument where you wanted up to 3 'files',
  167. /// you would set .max_values(3), and this argument would be satisfied if the user provided, 1, 2, or 3 values.
  168. pub max_values: Option<u64>,
  169. /// Sets whether or not the argument is required by default.
  170. ///
  171. /// - Required by default means it is required, when no other conflicting rules have been evaluated
  172. /// - Conflicting rules take precedence over being required.
  173. pub required: Option<bool>,
  174. /// Sets an arg that override this arg's required setting
  175. /// i.e. this arg will be required unless this other argument is present.
  176. pub required_unless_present: Option<String>,
  177. /// Sets args that override this arg's required setting
  178. /// i.e. this arg will be required unless all these other arguments are present.
  179. pub required_unless_present_all: Option<Vec<String>>,
  180. /// Sets args that override this arg's required setting
  181. /// i.e. this arg will be required unless at least one of these other arguments are present.
  182. pub required_unless_present_any: Option<Vec<String>>,
  183. /// Sets a conflicting argument by name
  184. /// i.e. when using this argument, the following argument can't be present and vice versa.
  185. pub conflicts_with: Option<String>,
  186. /// The same as conflictsWith but allows specifying multiple two-way conflicts per argument.
  187. pub conflicts_with_all: Option<Vec<String>>,
  188. /// Tets an argument by name that is required when this one is present
  189. /// i.e. when using this argument, the following argument must be present.
  190. pub requires: Option<String>,
  191. /// Sts multiple arguments by names that are required when this one is present
  192. /// i.e. when using this argument, the following arguments must be present.
  193. pub requires_all: Option<Vec<String>>,
  194. /// Allows a conditional requirement with the signature [arg, value]
  195. /// the requirement will only become valid if `arg`'s value equals `${value}`.
  196. pub requires_if: Option<Vec<String>>,
  197. /// Allows specifying that an argument is required conditionally with the signature [arg, value]
  198. /// the requirement will only become valid if the `arg`'s value equals `${value}`.
  199. pub required_if_eq: Option<Vec<String>>,
  200. /// Requires that options use the --option=val syntax
  201. /// i.e. an equals between the option and associated value.
  202. pub require_equals: Option<bool>,
  203. /// The positional argument index, starting at 1.
  204. ///
  205. /// The index refers to position according to other positional argument.
  206. /// It does not define position in the argument list as a whole. When utilized with multiple=true,
  207. /// only the last positional argument may be defined as multiple (i.e. the one with the highest index).
  208. pub index: Option<u64>,
  209. }
  210. /// describes a CLI configuration
  211. #[skip_serializing_none]
  212. #[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  213. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  214. pub struct CliConfig {
  215. /// command description which will be shown on the help information
  216. description: Option<String>,
  217. /// command long description which will be shown on the help information
  218. long_description: Option<String>,
  219. /// adds additional help information to be displayed in addition to auto-generated help
  220. /// this information is displayed before the auto-generated help information.
  221. /// this is often used for header information
  222. before_help: Option<String>,
  223. /// adds additional help information to be displayed in addition to auto-generated help
  224. /// this information is displayed after the auto-generated help information
  225. /// this is often used to describe how to use the arguments, or caveats to be noted.
  226. after_help: Option<String>,
  227. /// list of args for the command
  228. args: Option<Vec<CliArg>>,
  229. /// list of subcommands of this command.
  230. ///
  231. /// subcommands are effectively sub-apps, because they can contain their own arguments, subcommands, usage, etc.
  232. /// they also function just like the app command, in that they get their own auto generated help and usage
  233. subcommands: Option<HashMap<String, CliConfig>>,
  234. }
  235. #[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  236. #[serde(untagged)]
  237. pub enum Port {
  238. /// Port with a numeric value.
  239. Value(u16),
  240. /// Random port.
  241. Random,
  242. }
  243. /// The window configuration object.
  244. #[skip_serializing_none]
  245. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  246. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  247. pub struct WindowConfig {
  248. /// The window identifier.
  249. pub label: Option<String>,
  250. /// The window webview URL.
  251. pub url: Option<String>,
  252. /// Whether the file drop is enabled or not on the webview. By default it is enabled.
  253. ///
  254. /// Disabling it is required to use drag and drop on the frontend on Windows.
  255. #[serde(default = "default_file_drop_enabled")]
  256. pub file_drop_enabled: bool,
  257. /// Whether or not the window starts centered or not.
  258. #[serde(default)]
  259. pub center: bool,
  260. /// The horizontal position of the window's top left corner
  261. pub x: Option<f64>,
  262. /// The vertical position of the window's top left corner
  263. pub y: Option<f64>,
  264. /// The window width.
  265. pub width: Option<f64>,
  266. /// The window height.
  267. pub height: Option<f64>,
  268. /// The min window width.
  269. pub min_width: Option<f64>,
  270. /// The min window height.
  271. pub min_height: Option<f64>,
  272. /// The max window width.
  273. pub max_width: Option<f64>,
  274. /// The max window height.
  275. pub max_height: Option<f64>,
  276. /// Whether the window is resizable or not.
  277. #[serde(default)]
  278. pub resizable: bool,
  279. /// The window title.
  280. pub title: Option<String>,
  281. /// Whether the window starts as fullscreen or not.
  282. #[serde(default)]
  283. pub fullscreen: bool,
  284. /// Whether the window will be initially hidden or focused.
  285. #[serde(default = "default_focus")]
  286. pub focus: bool,
  287. /// Whether the window is transparent or not.
  288. #[serde(default)]
  289. pub transparent: bool,
  290. /// Whether the window is maximized or not.
  291. #[serde(default)]
  292. pub maximized: bool,
  293. /// Whether the window is visible or not.
  294. #[serde(default = "default_visible")]
  295. pub visible: bool,
  296. /// Whether the window should have borders and bars.
  297. #[serde(default = "default_decorations")]
  298. pub decorations: bool,
  299. /// Whether the window should always be on top of other windows.
  300. #[serde(default)]
  301. pub always_on_top: bool,
  302. /// Whether or not the window icon should be added to the taskbar.
  303. #[serde(default)]
  304. pub skip_taskbar: bool,
  305. }
  306. fn default_focus() -> bool {
  307. true
  308. }
  309. fn default_visible() -> bool {
  310. true
  311. }
  312. fn default_decorations() -> bool {
  313. true
  314. }
  315. fn default_file_drop_enabled() -> bool {
  316. true
  317. }
  318. #[skip_serializing_none]
  319. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  320. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  321. pub struct SecurityConfig {
  322. pub csp: Option<String>,
  323. }
  324. pub trait Allowlist {
  325. fn to_features(&self) -> Vec<&str>;
  326. }
  327. macro_rules! check_feature {
  328. ($self:ident, $features:ident, $flag:ident, $feature_name: expr) => {
  329. if $self.$flag {
  330. $features.push($feature_name)
  331. }
  332. };
  333. }
  334. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  335. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  336. pub struct FsAllowlistConfig {
  337. #[serde(default)]
  338. pub all: bool,
  339. #[serde(default)]
  340. pub read_text_file: bool,
  341. #[serde(default)]
  342. pub read_binary_file: bool,
  343. #[serde(default)]
  344. pub write_file: bool,
  345. #[serde(default)]
  346. pub write_binary_file: bool,
  347. #[serde(default)]
  348. pub read_dir: bool,
  349. #[serde(default)]
  350. pub copy_file: bool,
  351. #[serde(default)]
  352. pub create_dir: bool,
  353. #[serde(default)]
  354. pub remove_dir: bool,
  355. #[serde(default)]
  356. pub remove_file: bool,
  357. #[serde(default)]
  358. pub rename_file: bool,
  359. #[serde(default)]
  360. pub path: bool,
  361. }
  362. impl Allowlist for FsAllowlistConfig {
  363. fn to_features(&self) -> Vec<&str> {
  364. if self.all {
  365. vec!["fs-all"]
  366. } else {
  367. let mut features = Vec::new();
  368. check_feature!(self, features, read_text_file, "fs-read-text-file");
  369. check_feature!(self, features, read_binary_file, "fs-read-binary-file");
  370. check_feature!(self, features, write_file, "fs-write-file");
  371. check_feature!(self, features, write_binary_file, "fs-write-binary-file");
  372. check_feature!(self, features, read_dir, "fs-read-dir");
  373. check_feature!(self, features, copy_file, "fs-copy-file");
  374. check_feature!(self, features, create_dir, "fs-create-dir");
  375. check_feature!(self, features, remove_dir, "fs-remove-dir");
  376. check_feature!(self, features, remove_file, "fs-remove-file");
  377. check_feature!(self, features, rename_file, "fs-rename-file");
  378. check_feature!(self, features, path, "fs-path");
  379. features
  380. }
  381. }
  382. }
  383. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  384. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  385. pub struct WindowAllowlistConfig {
  386. #[serde(default)]
  387. pub all: bool,
  388. #[serde(default)]
  389. pub create: bool,
  390. }
  391. impl Allowlist for WindowAllowlistConfig {
  392. fn to_features(&self) -> Vec<&str> {
  393. if self.all {
  394. vec!["window-all"]
  395. } else {
  396. let mut features = Vec::new();
  397. check_feature!(self, features, create, "window-create");
  398. features
  399. }
  400. }
  401. }
  402. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  403. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  404. pub struct ShellAllowlistConfig {
  405. #[serde(default)]
  406. pub all: bool,
  407. #[serde(default)]
  408. pub execute: bool,
  409. #[serde(default)]
  410. pub open: bool,
  411. }
  412. impl Allowlist for ShellAllowlistConfig {
  413. fn to_features(&self) -> Vec<&str> {
  414. if self.all {
  415. vec!["shell-all"]
  416. } else {
  417. let mut features = Vec::new();
  418. check_feature!(self, features, execute, "shell-execute");
  419. check_feature!(self, features, open, "shell-open");
  420. features
  421. }
  422. }
  423. }
  424. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  425. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  426. pub struct DialogAllowlistConfig {
  427. #[serde(default)]
  428. pub all: bool,
  429. #[serde(default)]
  430. pub open: bool,
  431. #[serde(default)]
  432. pub save: bool,
  433. }
  434. impl Allowlist for DialogAllowlistConfig {
  435. fn to_features(&self) -> Vec<&str> {
  436. if self.all {
  437. vec!["dialog-all"]
  438. } else {
  439. let mut features = Vec::new();
  440. check_feature!(self, features, open, "dialog-open");
  441. check_feature!(self, features, save, "dialog-save");
  442. features
  443. }
  444. }
  445. }
  446. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  447. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  448. pub struct HttpAllowlistConfig {
  449. #[serde(default)]
  450. pub all: bool,
  451. #[serde(default)]
  452. pub request: bool,
  453. }
  454. impl Allowlist for HttpAllowlistConfig {
  455. fn to_features(&self) -> Vec<&str> {
  456. if self.all {
  457. vec!["http-all"]
  458. } else {
  459. let mut features = Vec::new();
  460. check_feature!(self, features, request, "http-request");
  461. features
  462. }
  463. }
  464. }
  465. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  466. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  467. pub struct NotificationAllowlistConfig {
  468. #[serde(default)]
  469. pub all: bool,
  470. }
  471. impl Allowlist for NotificationAllowlistConfig {
  472. fn to_features(&self) -> Vec<&str> {
  473. if self.all {
  474. vec!["notification-all"]
  475. } else {
  476. vec![]
  477. }
  478. }
  479. }
  480. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  481. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  482. pub struct GlobalShortcutAllowlistConfig {
  483. #[serde(default)]
  484. pub all: bool,
  485. }
  486. impl Allowlist for GlobalShortcutAllowlistConfig {
  487. fn to_features(&self) -> Vec<&str> {
  488. if self.all {
  489. vec!["global-shortcut-all"]
  490. } else {
  491. vec![]
  492. }
  493. }
  494. }
  495. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  496. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  497. pub struct AllowlistConfig {
  498. #[serde(default)]
  499. pub all: bool,
  500. #[serde(default)]
  501. pub fs: FsAllowlistConfig,
  502. #[serde(default)]
  503. pub window: WindowAllowlistConfig,
  504. #[serde(default)]
  505. pub shell: ShellAllowlistConfig,
  506. #[serde(default)]
  507. pub dialog: DialogAllowlistConfig,
  508. #[serde(default)]
  509. pub http: HttpAllowlistConfig,
  510. #[serde(default)]
  511. pub notification: NotificationAllowlistConfig,
  512. #[serde(default)]
  513. pub global_shortcut: GlobalShortcutAllowlistConfig,
  514. }
  515. impl Allowlist for AllowlistConfig {
  516. fn to_features(&self) -> Vec<&str> {
  517. if self.all {
  518. vec!["api-all"]
  519. } else {
  520. let mut features = Vec::new();
  521. features.extend(self.fs.to_features());
  522. features.extend(self.window.to_features());
  523. features.extend(self.shell.to_features());
  524. features.extend(self.dialog.to_features());
  525. features.extend(self.http.to_features());
  526. features.extend(self.notification.to_features());
  527. features.extend(self.global_shortcut.to_features());
  528. features
  529. }
  530. }
  531. }
  532. /// The Tauri configuration object.
  533. #[skip_serializing_none]
  534. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  535. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  536. pub struct TauriConfig {
  537. /// The windows configuration.
  538. #[serde(default)]
  539. pub windows: Vec<WindowConfig>,
  540. /// The CLI configuration.
  541. pub cli: Option<CliConfig>,
  542. /// The bundler configuration.
  543. #[serde(default)]
  544. pub bundle: BundleConfig,
  545. #[serde(default)]
  546. allowlist: AllowlistConfig,
  547. pub security: Option<SecurityConfig>,
  548. /// The updater configuration.
  549. #[serde(default = "default_updater")]
  550. pub updater: UpdaterConfig,
  551. /// Configuration for app system tray.
  552. pub system_tray: Option<SystemTrayConfig>,
  553. }
  554. impl TauriConfig {
  555. #[allow(dead_code)]
  556. pub fn features(&self) -> Vec<&str> {
  557. self.allowlist.to_features()
  558. }
  559. }
  560. #[skip_serializing_none]
  561. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  562. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  563. pub struct UpdaterConfig {
  564. /// Whether the updater is active or not.
  565. #[serde(default)]
  566. pub active: bool,
  567. /// Display built-in dialog or use event system if disabled.
  568. #[serde(default = "default_dialog")]
  569. pub dialog: Option<bool>,
  570. /// The updater endpoints.
  571. pub endpoints: Option<Vec<String>>,
  572. /// Optional pubkey.
  573. pub pubkey: Option<String>,
  574. }
  575. #[skip_serializing_none]
  576. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  577. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  578. pub struct SystemTrayConfig {
  579. /// Path to the icon to use on the system tray.
  580. ///
  581. /// It is forced to be a `.png` file on Linux and macOS, and a `.ico` file on Windows.
  582. pub icon_path: PathBuf,
  583. /// 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.
  584. #[serde(default)]
  585. pub icon_as_template: bool,
  586. }
  587. // We enable the unnecessary_wraps because we need
  588. // to use an Option for dialog otherwise the CLI schema will mark
  589. // the dialog as a required field which is not as we default it to true.
  590. #[allow(clippy::unnecessary_wraps)]
  591. fn default_dialog() -> Option<bool> {
  592. Some(true)
  593. }
  594. /// The `dev_path` and `dist_dir` options.
  595. #[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  596. #[serde(untagged, deny_unknown_fields)]
  597. pub enum AppUrl {
  598. /// The app's external URL, or the path to the directory containing the app assets.
  599. Url(String),
  600. /// An array of files to embed on the app.
  601. Files(Vec<PathBuf>),
  602. }
  603. impl std::fmt::Display for AppUrl {
  604. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  605. match self {
  606. Self::Url(url) => write!(f, "{}", url),
  607. Self::Files(files) => write!(f, "{}", serde_json::to_string(files).unwrap()),
  608. }
  609. }
  610. }
  611. /// The Build configuration object.
  612. #[skip_serializing_none]
  613. #[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  614. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  615. pub struct BuildConfig {
  616. /// The binary used to build and run the application.
  617. pub runner: Option<String>,
  618. /// The path or URL to use on development.
  619. #[serde(default = "default_dev_path")]
  620. pub dev_path: AppUrl,
  621. /// the path to the app's dist dir. This path must contain your index.html file.
  622. #[serde(default = "default_dist_dir")]
  623. pub dist_dir: AppUrl,
  624. /// a shell command to run before `tauri dev` kicks in
  625. pub before_dev_command: Option<String>,
  626. /// a shell command to run before `tauri build` kicks in
  627. pub before_build_command: Option<String>,
  628. /// features passed to `cargo` commands
  629. pub features: Option<Vec<String>>,
  630. /// Whether we should inject the Tauri API on `window.__TAURI__` or not.
  631. #[serde(default)]
  632. pub with_global_tauri: bool,
  633. }
  634. fn default_dev_path() -> AppUrl {
  635. AppUrl::Url("".to_string())
  636. }
  637. fn default_dist_dir() -> AppUrl {
  638. AppUrl::Url("../dist".to_string())
  639. }
  640. type JsonObject = HashMap<String, JsonValue>;
  641. /// The tauri.conf.json mapper.
  642. #[skip_serializing_none]
  643. #[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
  644. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  645. pub struct Config {
  646. /// Package settings.
  647. #[serde(default)]
  648. pub package: PackageConfig,
  649. /// The Tauri configuration.
  650. #[serde(default)]
  651. pub tauri: TauriConfig,
  652. /// The build configuration.
  653. #[serde(default = "default_build")]
  654. pub build: BuildConfig,
  655. /// The plugins config.
  656. #[serde(default)]
  657. pub plugins: HashMap<String, JsonObject>,
  658. }
  659. fn default_build() -> BuildConfig {
  660. BuildConfig {
  661. runner: None,
  662. dev_path: default_dev_path(),
  663. dist_dir: default_dist_dir(),
  664. before_dev_command: None,
  665. before_build_command: None,
  666. features: None,
  667. with_global_tauri: false,
  668. }
  669. }
  670. fn default_updater() -> UpdaterConfig {
  671. UpdaterConfig {
  672. active: false,
  673. dialog: Some(true),
  674. endpoints: None,
  675. pubkey: None,
  676. }
  677. }