config_definition.rs 26 KB

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