config.rs 96 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751
  1. // Copyright 2019-2024 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. //! The Tauri configuration used at runtime.
  5. //!
  6. //! It is pulled from a `tauri.conf.json` file and the [`Config`] struct is generated at compile time.
  7. //!
  8. //! # Stability
  9. //! This is a core functionality that is not considered part of the stable API.
  10. //! If you use it, note that it may include breaking changes in the future.
  11. #[cfg(target_os = "linux")]
  12. use heck::ToKebabCase;
  13. #[cfg(feature = "schema")]
  14. use schemars::JsonSchema;
  15. use semver::Version;
  16. use serde::{
  17. de::{Deserializer, Error as DeError, Visitor},
  18. Deserialize, Serialize, Serializer,
  19. };
  20. use serde_json::Value as JsonValue;
  21. use serde_with::skip_serializing_none;
  22. use url::Url;
  23. use std::{
  24. collections::HashMap,
  25. fmt::{self, Display},
  26. fs::read_to_string,
  27. path::PathBuf,
  28. str::FromStr,
  29. };
  30. /// Items to help with parsing content into a [`Config`].
  31. pub mod parse;
  32. use crate::{acl::capability::Capability, TitleBarStyle, WindowEffect, WindowEffectState};
  33. pub use self::parse::parse;
  34. fn default_true() -> bool {
  35. true
  36. }
  37. /// An URL to open on a Tauri webview window.
  38. #[derive(PartialEq, Eq, Debug, Clone, Serialize)]
  39. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  40. #[serde(untagged)]
  41. #[non_exhaustive]
  42. pub enum WebviewUrl {
  43. /// An external URL. Must use either the `http` or `https` schemes.
  44. External(Url),
  45. /// The path portion of an app URL.
  46. /// For instance, to load `tauri://localhost/users/john`,
  47. /// you can simply provide `users/john` in this configuration.
  48. App(PathBuf),
  49. /// A custom protocol url, for example, `doom://index.html`
  50. CustomProtocol(Url),
  51. }
  52. impl<'de> Deserialize<'de> for WebviewUrl {
  53. fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
  54. where
  55. D: Deserializer<'de>,
  56. {
  57. #[derive(Deserialize)]
  58. #[serde(untagged)]
  59. enum WebviewUrlDeserializer {
  60. Url(Url),
  61. Path(PathBuf),
  62. }
  63. match WebviewUrlDeserializer::deserialize(deserializer)? {
  64. WebviewUrlDeserializer::Url(u) => {
  65. if u.scheme() == "https" || u.scheme() == "http" {
  66. Ok(Self::External(u))
  67. } else {
  68. Ok(Self::CustomProtocol(u))
  69. }
  70. }
  71. WebviewUrlDeserializer::Path(p) => Ok(Self::App(p)),
  72. }
  73. }
  74. }
  75. impl fmt::Display for WebviewUrl {
  76. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  77. match self {
  78. Self::External(url) | Self::CustomProtocol(url) => write!(f, "{url}"),
  79. Self::App(path) => write!(f, "{}", path.display()),
  80. }
  81. }
  82. }
  83. impl Default for WebviewUrl {
  84. fn default() -> Self {
  85. Self::App("index.html".into())
  86. }
  87. }
  88. /// A bundle referenced by tauri-bundler.
  89. #[derive(Debug, PartialEq, Eq, Clone)]
  90. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  91. #[cfg_attr(feature = "schema", schemars(rename_all = "lowercase"))]
  92. pub enum BundleType {
  93. /// The debian bundle (.deb).
  94. Deb,
  95. /// The RPM bundle (.rpm).
  96. Rpm,
  97. /// The AppImage bundle (.appimage).
  98. AppImage,
  99. /// The Microsoft Installer bundle (.msi).
  100. Msi,
  101. /// The NSIS bundle (.exe).
  102. Nsis,
  103. /// The macOS application bundle (.app).
  104. App,
  105. /// The Apple Disk Image bundle (.dmg).
  106. Dmg,
  107. /// The Tauri updater bundle.
  108. Updater,
  109. }
  110. impl BundleType {
  111. /// All bundle types.
  112. fn all() -> &'static [Self] {
  113. &[
  114. BundleType::Deb,
  115. BundleType::Rpm,
  116. BundleType::AppImage,
  117. BundleType::Msi,
  118. BundleType::Nsis,
  119. BundleType::App,
  120. BundleType::Dmg,
  121. BundleType::Updater,
  122. ]
  123. }
  124. }
  125. impl Display for BundleType {
  126. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  127. write!(
  128. f,
  129. "{}",
  130. match self {
  131. Self::Deb => "deb",
  132. Self::Rpm => "rpm",
  133. Self::AppImage => "appimage",
  134. Self::Msi => "msi",
  135. Self::Nsis => "nsis",
  136. Self::App => "app",
  137. Self::Dmg => "dmg",
  138. Self::Updater => "updater",
  139. }
  140. )
  141. }
  142. }
  143. impl Serialize for BundleType {
  144. fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
  145. where
  146. S: Serializer,
  147. {
  148. serializer.serialize_str(self.to_string().as_ref())
  149. }
  150. }
  151. impl<'de> Deserialize<'de> for BundleType {
  152. fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
  153. where
  154. D: Deserializer<'de>,
  155. {
  156. let s = String::deserialize(deserializer)?;
  157. match s.to_lowercase().as_str() {
  158. "deb" => Ok(Self::Deb),
  159. "rpm" => Ok(Self::Rpm),
  160. "appimage" => Ok(Self::AppImage),
  161. "msi" => Ok(Self::Msi),
  162. "nsis" => Ok(Self::Nsis),
  163. "app" => Ok(Self::App),
  164. "dmg" => Ok(Self::Dmg),
  165. "updater" => Ok(Self::Updater),
  166. _ => Err(DeError::custom(format!("unknown bundle target '{s}'"))),
  167. }
  168. }
  169. }
  170. /// Targets to bundle. Each value is case insensitive.
  171. #[derive(Debug, PartialEq, Eq, Clone)]
  172. pub enum BundleTarget {
  173. /// Bundle all targets.
  174. All,
  175. /// A list of bundle targets.
  176. List(Vec<BundleType>),
  177. /// A single bundle target.
  178. One(BundleType),
  179. }
  180. #[cfg(feature = "schema")]
  181. impl schemars::JsonSchema for BundleTarget {
  182. fn schema_name() -> std::string::String {
  183. "BundleTarget".to_owned()
  184. }
  185. fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
  186. let any_of = vec![
  187. schemars::schema::SchemaObject {
  188. enum_values: Some(vec!["all".into()]),
  189. metadata: Some(Box::new(schemars::schema::Metadata {
  190. description: Some("Bundle all targets.".to_owned()),
  191. ..Default::default()
  192. })),
  193. ..Default::default()
  194. }
  195. .into(),
  196. schemars::_private::metadata::add_description(
  197. gen.subschema_for::<Vec<BundleType>>(),
  198. "A list of bundle targets.",
  199. ),
  200. schemars::_private::metadata::add_description(
  201. gen.subschema_for::<BundleType>(),
  202. "A single bundle target.",
  203. ),
  204. ];
  205. schemars::schema::SchemaObject {
  206. subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
  207. any_of: Some(any_of),
  208. ..Default::default()
  209. })),
  210. metadata: Some(Box::new(schemars::schema::Metadata {
  211. description: Some("Targets to bundle. Each value is case insensitive.".to_owned()),
  212. ..Default::default()
  213. })),
  214. ..Default::default()
  215. }
  216. .into()
  217. }
  218. }
  219. impl Default for BundleTarget {
  220. fn default() -> Self {
  221. Self::All
  222. }
  223. }
  224. impl Serialize for BundleTarget {
  225. fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
  226. where
  227. S: Serializer,
  228. {
  229. match self {
  230. Self::All => serializer.serialize_str("all"),
  231. Self::List(l) => l.serialize(serializer),
  232. Self::One(t) => serializer.serialize_str(t.to_string().as_ref()),
  233. }
  234. }
  235. }
  236. impl<'de> Deserialize<'de> for BundleTarget {
  237. fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
  238. where
  239. D: Deserializer<'de>,
  240. {
  241. #[derive(Deserialize, Serialize)]
  242. #[serde(untagged)]
  243. pub enum BundleTargetInner {
  244. List(Vec<BundleType>),
  245. One(BundleType),
  246. All(String),
  247. }
  248. match BundleTargetInner::deserialize(deserializer)? {
  249. BundleTargetInner::All(s) if s.to_lowercase() == "all" => Ok(Self::All),
  250. BundleTargetInner::All(t) => Err(DeError::custom(format!("invalid bundle type {t}"))),
  251. BundleTargetInner::List(l) => Ok(Self::List(l)),
  252. BundleTargetInner::One(t) => Ok(Self::One(t)),
  253. }
  254. }
  255. }
  256. impl BundleTarget {
  257. /// Gets the bundle targets as a [`Vec`]. The vector is empty when set to [`BundleTarget::All`].
  258. #[allow(dead_code)]
  259. pub fn to_vec(&self) -> Vec<BundleType> {
  260. match self {
  261. Self::All => BundleType::all().to_vec(),
  262. Self::List(list) => list.clone(),
  263. Self::One(i) => vec![i.clone()],
  264. }
  265. }
  266. }
  267. /// Configuration for AppImage bundles.
  268. ///
  269. /// See more: <https://tauri.app/v1/api/config#appimageconfig>
  270. #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
  271. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  272. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  273. pub struct AppImageConfig {
  274. /// Include additional gstreamer dependencies needed for audio and video playback.
  275. /// This increases the bundle size by ~15-35MB depending on your build system.
  276. #[serde(default, alias = "bundle-media-framework")]
  277. pub bundle_media_framework: bool,
  278. /// The files to include in the Appimage Binary.
  279. #[serde(default)]
  280. pub files: HashMap<PathBuf, PathBuf>,
  281. }
  282. /// Configuration for Debian (.deb) bundles.
  283. ///
  284. /// See more: <https://tauri.app/v1/api/config#debconfig>
  285. #[skip_serializing_none]
  286. #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
  287. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  288. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  289. pub struct DebConfig {
  290. /// The list of deb dependencies your application relies on.
  291. pub depends: Option<Vec<String>>,
  292. /// The list of dependencies the package provides.
  293. pub provides: Option<Vec<String>>,
  294. /// The list of package conflicts.
  295. pub conflicts: Option<Vec<String>>,
  296. /// The list of package replaces.
  297. pub replaces: Option<Vec<String>>,
  298. /// The files to include on the package.
  299. #[serde(default)]
  300. pub files: HashMap<PathBuf, PathBuf>,
  301. /// Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections
  302. pub section: Option<String>,
  303. /// Change the priority of the Debian Package. By default, it is set to `optional`.
  304. /// Recognized Priorities as of now are : `required`, `important`, `standard`, `optional`, `extra`
  305. pub priority: Option<String>,
  306. /// Path of the uncompressed Changelog file, to be stored at /usr/share/doc/package-name/changelog.gz. See
  307. /// https://www.debian.org/doc/debian-policy/ch-docs.html#changelog-files-and-release-notes
  308. pub changelog: Option<PathBuf>,
  309. /// Path to a custom desktop file Handlebars template.
  310. ///
  311. /// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.
  312. #[serde(alias = "desktop-template")]
  313. pub desktop_template: Option<PathBuf>,
  314. /// Path to script that will be executed before the package is unpacked. See
  315. /// https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html
  316. #[serde(alias = "pre-install-script")]
  317. pub pre_install_script: Option<PathBuf>,
  318. /// Path to script that will be executed after the package is unpacked. See
  319. /// https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html
  320. #[serde(alias = "post-install-script")]
  321. pub post_install_script: Option<PathBuf>,
  322. /// Path to script that will be executed before the package is removed. See
  323. /// https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html
  324. #[serde(alias = "pre-remove-script")]
  325. pub pre_remove_script: Option<PathBuf>,
  326. /// Path to script that will be executed after the package is removed. See
  327. /// https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html
  328. #[serde(alias = "post-remove-script")]
  329. pub post_remove_script: Option<PathBuf>,
  330. }
  331. /// Configuration for Linux bundles.
  332. ///
  333. /// See more: <https://tauri.app/v1/api/config#linuxconfig>
  334. #[skip_serializing_none]
  335. #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
  336. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  337. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  338. pub struct LinuxConfig {
  339. /// Configuration for the AppImage bundle.
  340. #[serde(default)]
  341. pub appimage: AppImageConfig,
  342. /// Configuration for the Debian bundle.
  343. #[serde(default)]
  344. pub deb: DebConfig,
  345. /// Configuration for the RPM bundle.
  346. #[serde(default)]
  347. pub rpm: RpmConfig,
  348. }
  349. /// Configuration for RPM bundles.
  350. #[skip_serializing_none]
  351. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  352. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  353. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  354. pub struct RpmConfig {
  355. /// The list of RPM dependencies your application relies on.
  356. pub depends: Option<Vec<String>>,
  357. /// The list of RPM dependencies your application provides.
  358. pub provides: Option<Vec<String>>,
  359. /// The list of RPM dependencies your application conflicts with. They must not be present
  360. /// in order for the package to be installed.
  361. pub conflicts: Option<Vec<String>>,
  362. /// The list of RPM dependencies your application supersedes - if this package is installed,
  363. /// packages listed as “obsoletes” will be automatically removed (if they are present).
  364. pub obsoletes: Option<Vec<String>>,
  365. /// The RPM release tag.
  366. #[serde(default = "default_release")]
  367. pub release: String,
  368. /// The RPM epoch.
  369. #[serde(default)]
  370. pub epoch: u32,
  371. /// The files to include on the package.
  372. #[serde(default)]
  373. pub files: HashMap<PathBuf, PathBuf>,
  374. /// Path to a custom desktop file Handlebars template.
  375. ///
  376. /// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.
  377. #[serde(alias = "desktop-template")]
  378. pub desktop_template: Option<PathBuf>,
  379. /// Path to script that will be executed before the package is unpacked. See
  380. /// http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html
  381. #[serde(alias = "pre-install-script")]
  382. pub pre_install_script: Option<PathBuf>,
  383. /// Path to script that will be executed after the package is unpacked. See
  384. /// http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html
  385. #[serde(alias = "post-install-script")]
  386. pub post_install_script: Option<PathBuf>,
  387. /// Path to script that will be executed before the package is removed. See
  388. /// http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html
  389. #[serde(alias = "pre-remove-script")]
  390. pub pre_remove_script: Option<PathBuf>,
  391. /// Path to script that will be executed after the package is removed. See
  392. /// http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html
  393. #[serde(alias = "post-remove-script")]
  394. pub post_remove_script: Option<PathBuf>,
  395. }
  396. impl Default for RpmConfig {
  397. fn default() -> Self {
  398. Self {
  399. depends: None,
  400. provides: None,
  401. conflicts: None,
  402. obsoletes: None,
  403. release: default_release(),
  404. epoch: 0,
  405. files: Default::default(),
  406. desktop_template: None,
  407. pre_install_script: None,
  408. post_install_script: None,
  409. pre_remove_script: None,
  410. post_remove_script: None,
  411. }
  412. }
  413. }
  414. fn default_release() -> String {
  415. "1".into()
  416. }
  417. /// Position coordinates struct.
  418. #[derive(Default, Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  419. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  420. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  421. pub struct Position {
  422. /// X coordinate.
  423. pub x: u32,
  424. /// Y coordinate.
  425. pub y: u32,
  426. }
  427. /// Size of the window.
  428. #[derive(Default, Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  429. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  430. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  431. pub struct Size {
  432. /// Width of the window.
  433. pub width: u32,
  434. /// Height of the window.
  435. pub height: u32,
  436. }
  437. /// Configuration for Apple Disk Image (.dmg) bundles.
  438. ///
  439. /// See more: <https://tauri.app/v1/api/config#dmgconfig>
  440. #[skip_serializing_none]
  441. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  442. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  443. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  444. pub struct DmgConfig {
  445. /// Image to use as the background in dmg file. Accepted formats: `png`/`jpg`/`gif`.
  446. pub background: Option<PathBuf>,
  447. /// Position of volume window on screen.
  448. pub window_position: Option<Position>,
  449. /// Size of volume window.
  450. #[serde(default = "dmg_window_size", alias = "window-size")]
  451. pub window_size: Size,
  452. /// Position of app file on window.
  453. #[serde(default = "dmg_app_position", alias = "app-position")]
  454. pub app_position: Position,
  455. /// Position of application folder on window.
  456. #[serde(
  457. default = "dmg_application_folder_position",
  458. alias = "application-folder-position"
  459. )]
  460. pub application_folder_position: Position,
  461. }
  462. impl Default for DmgConfig {
  463. fn default() -> Self {
  464. Self {
  465. background: None,
  466. window_position: None,
  467. window_size: dmg_window_size(),
  468. app_position: dmg_app_position(),
  469. application_folder_position: dmg_application_folder_position(),
  470. }
  471. }
  472. }
  473. fn dmg_window_size() -> Size {
  474. Size {
  475. width: 660,
  476. height: 400,
  477. }
  478. }
  479. fn dmg_app_position() -> Position {
  480. Position { x: 180, y: 170 }
  481. }
  482. fn dmg_application_folder_position() -> Position {
  483. Position { x: 480, y: 170 }
  484. }
  485. fn de_minimum_system_version<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
  486. where
  487. D: Deserializer<'de>,
  488. {
  489. let version = Option::<String>::deserialize(deserializer)?;
  490. match version {
  491. Some(v) if v.is_empty() => Ok(minimum_system_version()),
  492. e => Ok(e),
  493. }
  494. }
  495. /// Configuration for the macOS bundles.
  496. ///
  497. /// See more: <https://tauri.app/v1/api/config#macconfig>
  498. #[skip_serializing_none]
  499. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  500. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  501. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  502. pub struct MacConfig {
  503. /// A list of strings indicating any macOS X frameworks that need to be bundled with the application.
  504. ///
  505. /// If a name is used, ".framework" must be omitted and it will look for standard install locations. You may also use a path to a specific framework.
  506. pub frameworks: Option<Vec<String>>,
  507. /// The files to include in the application relative to the Contents directory.
  508. #[serde(default)]
  509. pub files: HashMap<PathBuf, PathBuf>,
  510. /// A version string indicating the minimum macOS X version that the bundled application supports. Defaults to `10.13`.
  511. ///
  512. /// Setting it to `null` completely removes the `LSMinimumSystemVersion` field on the bundle's `Info.plist`
  513. /// and the `MACOSX_DEPLOYMENT_TARGET` environment variable.
  514. ///
  515. /// An empty string is considered an invalid value so the default value is used.
  516. #[serde(
  517. deserialize_with = "de_minimum_system_version",
  518. default = "minimum_system_version",
  519. alias = "minimum-system-version"
  520. )]
  521. pub minimum_system_version: Option<String>,
  522. /// Allows your application to communicate with the outside world.
  523. /// It should be a lowercase, without port and protocol domain name.
  524. #[serde(alias = "exception-domain")]
  525. pub exception_domain: Option<String>,
  526. /// Identity to use for code signing.
  527. #[serde(alias = "signing-identity")]
  528. pub signing_identity: Option<String>,
  529. /// Provider short name for notarization.
  530. #[serde(alias = "provider-short-name")]
  531. pub provider_short_name: Option<String>,
  532. /// Path to the entitlements file.
  533. pub entitlements: Option<String>,
  534. /// DMG-specific settings.
  535. #[serde(default)]
  536. pub dmg: DmgConfig,
  537. }
  538. impl Default for MacConfig {
  539. fn default() -> Self {
  540. Self {
  541. frameworks: None,
  542. files: HashMap::new(),
  543. minimum_system_version: minimum_system_version(),
  544. exception_domain: None,
  545. signing_identity: None,
  546. provider_short_name: None,
  547. entitlements: None,
  548. dmg: Default::default(),
  549. }
  550. }
  551. }
  552. fn minimum_system_version() -> Option<String> {
  553. Some("10.13".into())
  554. }
  555. /// Configuration for a target language for the WiX build.
  556. ///
  557. /// See more: <https://tauri.app/v1/api/config#wixlanguageconfig>
  558. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  559. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  560. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  561. pub struct WixLanguageConfig {
  562. /// The path to a locale (`.wxl`) file. See <https://wixtoolset.org/documentation/manual/v3/howtos/ui_and_localization/build_a_localized_version.html>.
  563. #[serde(alias = "locale-path")]
  564. pub locale_path: Option<String>,
  565. }
  566. /// The languages to build using WiX.
  567. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  568. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  569. #[serde(untagged)]
  570. pub enum WixLanguage {
  571. /// A single language to build, without configuration.
  572. One(String),
  573. /// A list of languages to build, without configuration.
  574. List(Vec<String>),
  575. /// A map of languages and its configuration.
  576. Localized(HashMap<String, WixLanguageConfig>),
  577. }
  578. impl Default for WixLanguage {
  579. fn default() -> Self {
  580. Self::One("en-US".into())
  581. }
  582. }
  583. /// Configuration for the MSI bundle using WiX.
  584. ///
  585. /// See more: <https://tauri.app/v1/api/config#wixconfig>
  586. #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
  587. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  588. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  589. pub struct WixConfig {
  590. /// The installer languages to build. See <https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables>.
  591. #[serde(default)]
  592. pub language: WixLanguage,
  593. /// A custom .wxs template to use.
  594. pub template: Option<PathBuf>,
  595. /// A list of paths to .wxs files with WiX fragments to use.
  596. #[serde(default, alias = "fragment-paths")]
  597. pub fragment_paths: Vec<PathBuf>,
  598. /// The ComponentGroup element ids you want to reference from the fragments.
  599. #[serde(default, alias = "component-group-refs")]
  600. pub component_group_refs: Vec<String>,
  601. /// The Component element ids you want to reference from the fragments.
  602. #[serde(default, alias = "component-refs")]
  603. pub component_refs: Vec<String>,
  604. /// The FeatureGroup element ids you want to reference from the fragments.
  605. #[serde(default, alias = "feature-group-refs")]
  606. pub feature_group_refs: Vec<String>,
  607. /// The Feature element ids you want to reference from the fragments.
  608. #[serde(default, alias = "feature-refs")]
  609. pub feature_refs: Vec<String>,
  610. /// The Merge element ids you want to reference from the fragments.
  611. #[serde(default, alias = "merge-refs")]
  612. pub merge_refs: Vec<String>,
  613. /// Create an elevated update task within Windows Task Scheduler.
  614. #[serde(default, alias = "enable-elevated-update-task")]
  615. pub enable_elevated_update_task: bool,
  616. /// Path to a bitmap file to use as the installation user interface banner.
  617. /// This bitmap will appear at the top of all but the first page of the installer.
  618. ///
  619. /// The required dimensions are 493px × 58px.
  620. #[serde(alias = "banner-path")]
  621. pub banner_path: Option<PathBuf>,
  622. /// Path to a bitmap file to use on the installation user interface dialogs.
  623. /// It is used on the welcome and completion dialogs.
  624. /// The required dimensions are 493px × 312px.
  625. #[serde(alias = "dialog-image-path")]
  626. pub dialog_image_path: Option<PathBuf>,
  627. }
  628. /// Compression algorithms used in the NSIS installer.
  629. ///
  630. /// See <https://nsis.sourceforge.io/Reference/SetCompressor>
  631. #[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
  632. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  633. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  634. pub enum NsisCompression {
  635. /// ZLIB uses the deflate algorithm, it is a quick and simple method. With the default compression level it uses about 300 KB of memory.
  636. Zlib,
  637. /// BZIP2 usually gives better compression ratios than ZLIB, but it is a bit slower and uses more memory. With the default compression level it uses about 4 MB of memory.
  638. Bzip2,
  639. /// LZMA (default) is a new compression method that gives very good compression ratios. The decompression speed is high (10-20 MB/s on a 2 GHz CPU), the compression speed is lower. The memory size that will be used for decompression is the dictionary size plus a few KBs, the default is 8 MB.
  640. Lzma,
  641. }
  642. /// Configuration for the Installer bundle using NSIS.
  643. #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
  644. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  645. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  646. pub struct NsisConfig {
  647. /// A custom .nsi template to use.
  648. pub template: Option<PathBuf>,
  649. /// The path to a bitmap file to display on the header of installers pages.
  650. ///
  651. /// The recommended dimensions are 150px x 57px.
  652. #[serde(alias = "header-image")]
  653. pub header_image: Option<PathBuf>,
  654. /// The path to a bitmap file for the Welcome page and the Finish page.
  655. ///
  656. /// The recommended dimensions are 164px x 314px.
  657. #[serde(alias = "sidebar-image")]
  658. pub sidebar_image: Option<PathBuf>,
  659. /// The path to an icon file used as the installer icon.
  660. #[serde(alias = "install-icon")]
  661. pub installer_icon: Option<PathBuf>,
  662. /// Whether the installation will be for all users or just the current user.
  663. #[serde(default, alias = "install-mode")]
  664. pub install_mode: NSISInstallerMode,
  665. /// A list of installer languages.
  666. /// By default the OS language is used. If the OS language is not in the list of languages, the first language will be used.
  667. /// To allow the user to select the language, set `display_language_selector` to `true`.
  668. ///
  669. /// See <https://github.com/kichik/nsis/tree/9465c08046f00ccb6eda985abbdbf52c275c6c4d/Contrib/Language%20files> for the complete list of languages.
  670. pub languages: Option<Vec<String>>,
  671. /// A key-value pair where the key is the language and the
  672. /// value is the path to a custom `.nsh` file that holds the translated text for tauri's custom messages.
  673. ///
  674. /// See <https://github.com/tauri-apps/tauri/blob/dev/tooling/bundler/src/bundle/windows/templates/nsis-languages/English.nsh> for an example `.nsh` file.
  675. ///
  676. /// **Note**: the key must be a valid NSIS language and it must be added to [`NsisConfig`] languages array,
  677. pub custom_language_files: Option<HashMap<String, PathBuf>>,
  678. /// Whether to display a language selector dialog before the installer and uninstaller windows are rendered or not.
  679. /// By default the OS language is selected, with a fallback to the first language in the `languages` array.
  680. #[serde(default, alias = "display-language-selector")]
  681. pub display_language_selector: bool,
  682. /// Set the compression algorithm used to compress files in the installer.
  683. ///
  684. /// See <https://nsis.sourceforge.io/Reference/SetCompressor>
  685. pub compression: Option<NsisCompression>,
  686. }
  687. /// Install Modes for the NSIS installer.
  688. #[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
  689. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  690. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  691. pub enum NSISInstallerMode {
  692. /// Default mode for the installer.
  693. ///
  694. /// Install the app by default in a directory that doesn't require Administrator access.
  695. ///
  696. /// Installer metadata will be saved under the `HKCU` registry path.
  697. CurrentUser,
  698. /// Install the app by default in the `Program Files` folder directory requires Administrator
  699. /// access for the installation.
  700. ///
  701. /// Installer metadata will be saved under the `HKLM` registry path.
  702. PerMachine,
  703. /// Combines both modes and allows the user to choose at install time
  704. /// whether to install for the current user or per machine. Note that this mode
  705. /// will require Administrator access even if the user wants to install it for the current user only.
  706. ///
  707. /// Installer metadata will be saved under the `HKLM` or `HKCU` registry path based on the user's choice.
  708. Both,
  709. }
  710. impl Default for NSISInstallerMode {
  711. fn default() -> Self {
  712. Self::CurrentUser
  713. }
  714. }
  715. /// Install modes for the Webview2 runtime.
  716. /// Note that for the updater bundle [`Self::DownloadBootstrapper`] is used.
  717. ///
  718. /// For more information see <https://tauri.app/v1/guides/building/windows>.
  719. #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
  720. #[serde(tag = "type", rename_all = "camelCase", deny_unknown_fields)]
  721. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  722. pub enum WebviewInstallMode {
  723. /// Do not install the Webview2 as part of the Windows Installer.
  724. Skip,
  725. /// Download the bootstrapper and run it.
  726. /// Requires an internet connection.
  727. /// Results in a smaller installer size, but is not recommended on Windows 7.
  728. DownloadBootstrapper {
  729. /// Instructs the installer to run the bootstrapper in silent mode. Defaults to `true`.
  730. #[serde(default = "default_true")]
  731. silent: bool,
  732. },
  733. /// Embed the bootstrapper and run it.
  734. /// Requires an internet connection.
  735. /// Increases the installer size by around 1.8MB, but offers better support on Windows 7.
  736. EmbedBootstrapper {
  737. /// Instructs the installer to run the bootstrapper in silent mode. Defaults to `true`.
  738. #[serde(default = "default_true")]
  739. silent: bool,
  740. },
  741. /// Embed the offline installer and run it.
  742. /// Does not require an internet connection.
  743. /// Increases the installer size by around 127MB.
  744. OfflineInstaller {
  745. /// Instructs the installer to run the installer in silent mode. Defaults to `true`.
  746. #[serde(default = "default_true")]
  747. silent: bool,
  748. },
  749. /// Embed a fixed webview2 version and use it at runtime.
  750. /// Increases the installer size by around 180MB.
  751. FixedRuntime {
  752. /// The path to the fixed runtime to use.
  753. ///
  754. /// The fixed version can be downloaded [on the official website](https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download-section).
  755. /// The `.cab` file must be extracted to a folder and this folder path must be defined on this field.
  756. path: PathBuf,
  757. },
  758. }
  759. impl Default for WebviewInstallMode {
  760. fn default() -> Self {
  761. Self::DownloadBootstrapper { silent: true }
  762. }
  763. }
  764. /// Windows bundler configuration.
  765. ///
  766. /// See more: <https://tauri.app/v1/api/config#windowsconfig>
  767. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  768. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  769. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  770. pub struct WindowsConfig {
  771. /// Specifies the file digest algorithm to use for creating file signatures.
  772. /// Required for code signing. SHA-256 is recommended.
  773. #[serde(alias = "digest-algorithm")]
  774. pub digest_algorithm: Option<String>,
  775. /// Specifies the SHA1 hash of the signing certificate.
  776. #[serde(alias = "certificate-thumbprint")]
  777. pub certificate_thumbprint: Option<String>,
  778. /// Server to use during timestamping.
  779. #[serde(alias = "timestamp-url")]
  780. pub timestamp_url: Option<String>,
  781. /// Whether to use Time-Stamp Protocol (TSP, a.k.a. RFC 3161) for the timestamp server. Your code signing provider may
  782. /// use a TSP timestamp server, like e.g. SSL.com does. If so, enable TSP by setting to true.
  783. #[serde(default)]
  784. pub tsp: bool,
  785. /// The installation mode for the Webview2 runtime.
  786. #[serde(default, alias = "webview-install-mode")]
  787. pub webview_install_mode: WebviewInstallMode,
  788. /// Path to the webview fixed runtime to use. Overwrites [`Self::webview_install_mode`] if set.
  789. ///
  790. /// Will be removed in v2, prefer the [`Self::webview_install_mode`] option.
  791. ///
  792. /// The fixed version can be downloaded [on the official website](https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download-section).
  793. /// The `.cab` file must be extracted to a folder and this folder path must be defined on this field.
  794. #[serde(alias = "webview-fixed-runtime-path")]
  795. pub webview_fixed_runtime_path: Option<PathBuf>,
  796. /// Validates a second app installation, blocking the user from installing an older version if set to `false`.
  797. ///
  798. /// 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`.
  799. ///
  800. /// The default value of this flag is `true`.
  801. #[serde(default = "default_true", alias = "allow-downgrades")]
  802. pub allow_downgrades: bool,
  803. /// Configuration for the MSI generated with WiX.
  804. pub wix: Option<WixConfig>,
  805. /// Configuration for the installer generated with NSIS.
  806. pub nsis: Option<NsisConfig>,
  807. /// Specify a custom command to sign the binaries.
  808. /// This command needs to have a `%1` in it which is just a placeholder for the binary path,
  809. /// which we will detect and replace before calling the command.
  810. ///
  811. /// Example:
  812. /// ```text
  813. /// sign-cli --arg1 --arg2 %1
  814. /// ```
  815. ///
  816. /// By Default we use `signtool.exe` which can be found only on Windows so
  817. /// if you are on another platform and want to cross-compile and sign you will
  818. /// need to use another tool like `osslsigncode`.
  819. #[serde(alias = "sign-command")]
  820. pub sign_command: Option<String>,
  821. }
  822. impl Default for WindowsConfig {
  823. fn default() -> Self {
  824. Self {
  825. digest_algorithm: None,
  826. certificate_thumbprint: None,
  827. timestamp_url: None,
  828. tsp: false,
  829. webview_install_mode: Default::default(),
  830. webview_fixed_runtime_path: None,
  831. allow_downgrades: true,
  832. wix: None,
  833. nsis: None,
  834. sign_command: None,
  835. }
  836. }
  837. }
  838. /// macOS-only. Corresponds to CFBundleTypeRole
  839. #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
  840. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  841. pub enum BundleTypeRole {
  842. /// CFBundleTypeRole.Editor. Files can be read and edited.
  843. #[default]
  844. Editor,
  845. /// CFBundleTypeRole.Viewer. Files can be read.
  846. Viewer,
  847. /// CFBundleTypeRole.Shell
  848. Shell,
  849. /// CFBundleTypeRole.QLGenerator
  850. QLGenerator,
  851. /// CFBundleTypeRole.None
  852. None,
  853. }
  854. impl Display for BundleTypeRole {
  855. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  856. match self {
  857. Self::Editor => write!(f, "Editor"),
  858. Self::Viewer => write!(f, "Viewer"),
  859. Self::Shell => write!(f, "Shell"),
  860. Self::QLGenerator => write!(f, "QLGenerator"),
  861. Self::None => write!(f, "None"),
  862. }
  863. }
  864. }
  865. /// An extension for a [`FileAssociation`].
  866. ///
  867. /// A leading `.` is automatically stripped.
  868. #[derive(Debug, PartialEq, Eq, Clone, Serialize)]
  869. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  870. pub struct AssociationExt(pub String);
  871. impl fmt::Display for AssociationExt {
  872. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  873. write!(f, "{}", self.0)
  874. }
  875. }
  876. impl<'d> serde::Deserialize<'d> for AssociationExt {
  877. fn deserialize<D: Deserializer<'d>>(deserializer: D) -> Result<Self, D::Error> {
  878. let ext = String::deserialize(deserializer)?;
  879. if let Some(ext) = ext.strip_prefix('.') {
  880. Ok(AssociationExt(ext.into()))
  881. } else {
  882. Ok(AssociationExt(ext))
  883. }
  884. }
  885. }
  886. /// File association
  887. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  888. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  889. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  890. pub struct FileAssociation {
  891. /// File extensions to associate with this app. e.g. 'png'
  892. pub ext: Vec<AssociationExt>,
  893. /// The name. Maps to `CFBundleTypeName` on macOS. Default to `ext[0]`
  894. pub name: Option<String>,
  895. /// The association description. Windows-only. It is displayed on the `Type` column on Windows Explorer.
  896. pub description: Option<String>,
  897. /// The app's role with respect to the type. Maps to `CFBundleTypeRole` on macOS.
  898. #[serde(default)]
  899. pub role: BundleTypeRole,
  900. /// The mime-type e.g. 'image/png' or 'text/plain'. Linux-only.
  901. #[serde(alias = "mime-type")]
  902. pub mime_type: Option<String>,
  903. }
  904. /// File association
  905. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  906. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  907. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  908. pub struct DeepLinkProtocol {
  909. /// URL schemes to associate with this app without `://`. For example `my-app`
  910. pub schemes: Vec<String>,
  911. /// The protocol name. **macOS-only** and maps to `CFBundleTypeName`. Defaults to `<bundle-id>.<schemes[0]>`
  912. pub name: Option<String>,
  913. /// The app's role for these schemes. **macOS-only** and maps to `CFBundleTypeRole`.
  914. #[serde(default)]
  915. pub role: BundleTypeRole,
  916. }
  917. /// Definition for bundle resources.
  918. /// Can be either a list of paths to include or a map of source to target paths.
  919. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  920. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  921. #[serde(rename_all = "camelCase", deny_unknown_fields, untagged)]
  922. pub enum BundleResources {
  923. /// A list of paths to include.
  924. List(Vec<String>),
  925. /// A map of source to target paths.
  926. Map(HashMap<String, String>),
  927. }
  928. impl BundleResources {
  929. /// Adds a path to the resource collection.
  930. pub fn push(&mut self, path: impl Into<String>) {
  931. match self {
  932. Self::List(l) => l.push(path.into()),
  933. Self::Map(l) => {
  934. let path = path.into();
  935. l.insert(path.clone(), path);
  936. }
  937. }
  938. }
  939. }
  940. /// Configuration for tauri-bundler.
  941. ///
  942. /// See more: <https://tauri.app/v1/api/config#bundleconfig>
  943. #[skip_serializing_none]
  944. #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
  945. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  946. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  947. pub struct BundleConfig {
  948. /// Whether Tauri should bundle your application or just output the executable.
  949. #[serde(default)]
  950. pub active: bool,
  951. /// The bundle targets, currently supports ["deb", "rpm", "appimage", "nsis", "msi", "app", "dmg", "updater"] or "all".
  952. #[serde(default)]
  953. pub targets: BundleTarget,
  954. /// The application's publisher. Defaults to the second element in the identifier string.
  955. /// Currently maps to the Manufacturer property of the Windows Installer.
  956. pub publisher: Option<String>,
  957. /// The app's icons
  958. #[serde(default)]
  959. pub icon: Vec<String>,
  960. /// App resources to bundle.
  961. /// Each resource is a path to a file or directory.
  962. /// Glob patterns are supported.
  963. pub resources: Option<BundleResources>,
  964. /// A copyright string associated with your application.
  965. pub copyright: Option<String>,
  966. /// The package's license identifier to be included in the appropriate bundles.
  967. /// If not set, defaults to the license from the Cargo.toml file.
  968. pub license: Option<String>,
  969. /// The path to the license file to be included in the appropriate bundles.
  970. #[serde(alias = "license-file")]
  971. pub license_file: Option<PathBuf>,
  972. /// The application kind.
  973. ///
  974. /// Should be one of the following:
  975. /// 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.
  976. pub category: Option<String>,
  977. /// File associations to application.
  978. pub file_associations: Option<Vec<FileAssociation>>,
  979. /// A short description of your application.
  980. #[serde(alias = "short-description")]
  981. pub short_description: Option<String>,
  982. /// A longer, multi-line description of the application.
  983. #[serde(alias = "long-description")]
  984. pub long_description: Option<String>,
  985. /// A list of—either absolute or relative—paths to binaries to embed with your application.
  986. ///
  987. /// Note that Tauri will look for system-specific binaries following the pattern "binary-name{-target-triple}{.system-extension}".
  988. ///
  989. /// E.g. for the external binary "my-binary", Tauri looks for:
  990. ///
  991. /// - "my-binary-x86_64-pc-windows-msvc.exe" for Windows
  992. /// - "my-binary-x86_64-apple-darwin" for macOS
  993. /// - "my-binary-x86_64-unknown-linux-gnu" for Linux
  994. ///
  995. /// so don't forget to provide binaries for all targeted platforms.
  996. #[serde(alias = "external-bin")]
  997. pub external_bin: Option<Vec<String>>,
  998. /// Configuration for the Windows bundles.
  999. #[serde(default)]
  1000. pub windows: WindowsConfig,
  1001. /// Configuration for the Linux bundles.
  1002. #[serde(default)]
  1003. pub linux: LinuxConfig,
  1004. /// Configuration for the macOS bundles.
  1005. #[serde(rename = "macOS", alias = "macos", default)]
  1006. pub macos: MacConfig,
  1007. /// iOS configuration.
  1008. #[serde(rename = "iOS", alias = "ios", default)]
  1009. pub ios: IosConfig,
  1010. /// Android configuration.
  1011. #[serde(default)]
  1012. pub android: AndroidConfig,
  1013. }
  1014. /// a tuple struct of RGBA colors. Each value has minimum of 0 and maximum of 255.
  1015. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
  1016. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1017. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  1018. pub struct Color(pub u8, pub u8, pub u8, pub u8);
  1019. impl From<Color> for (u8, u8, u8, u8) {
  1020. fn from(value: Color) -> Self {
  1021. (value.0, value.1, value.2, value.3)
  1022. }
  1023. }
  1024. /// The window effects configuration object
  1025. #[skip_serializing_none]
  1026. #[derive(Debug, PartialEq, Clone, Deserialize, Serialize, Default)]
  1027. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1028. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  1029. pub struct WindowEffectsConfig {
  1030. /// List of Window effects to apply to the Window.
  1031. /// Conflicting effects will apply the first one and ignore the rest.
  1032. pub effects: Vec<WindowEffect>,
  1033. /// Window effect state **macOS Only**
  1034. pub state: Option<WindowEffectState>,
  1035. /// Window effect corner radius **macOS Only**
  1036. pub radius: Option<f64>,
  1037. /// Window effect color. Affects [`WindowEffect::Blur`] and [`WindowEffect::Acrylic`] only
  1038. /// on Windows 10 v1903+. Doesn't have any effect on Windows 7 or Windows 11.
  1039. pub color: Option<Color>,
  1040. }
  1041. /// The window configuration object.
  1042. ///
  1043. /// See more: <https://tauri.app/v1/api/config#windowconfig>
  1044. #[skip_serializing_none]
  1045. #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
  1046. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1047. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  1048. pub struct WindowConfig {
  1049. /// The window identifier. It must be alphanumeric.
  1050. #[serde(default = "default_window_label")]
  1051. pub label: String,
  1052. /// The window webview URL.
  1053. #[serde(default)]
  1054. pub url: WebviewUrl,
  1055. /// The user agent for the webview
  1056. #[serde(alias = "user-agent")]
  1057. pub user_agent: Option<String>,
  1058. /// Whether the drag and drop is enabled or not on the webview. By default it is enabled.
  1059. ///
  1060. /// Disabling it is required to use HTML5 drag and drop on the frontend on Windows.
  1061. #[serde(default = "default_true", alias = "drag-drop-enabled")]
  1062. pub drag_drop_enabled: bool,
  1063. /// Whether or not the window starts centered or not.
  1064. #[serde(default)]
  1065. pub center: bool,
  1066. /// The horizontal position of the window's top left corner
  1067. pub x: Option<f64>,
  1068. /// The vertical position of the window's top left corner
  1069. pub y: Option<f64>,
  1070. /// The window width.
  1071. #[serde(default = "default_width")]
  1072. pub width: f64,
  1073. /// The window height.
  1074. #[serde(default = "default_height")]
  1075. pub height: f64,
  1076. /// The min window width.
  1077. #[serde(alias = "min-width")]
  1078. pub min_width: Option<f64>,
  1079. /// The min window height.
  1080. #[serde(alias = "min-height")]
  1081. pub min_height: Option<f64>,
  1082. /// The max window width.
  1083. #[serde(alias = "max-width")]
  1084. pub max_width: Option<f64>,
  1085. /// The max window height.
  1086. #[serde(alias = "max-height")]
  1087. pub max_height: Option<f64>,
  1088. /// Whether the window is resizable or not. When resizable is set to false, native window's maximize button is automatically disabled.
  1089. #[serde(default = "default_true")]
  1090. pub resizable: bool,
  1091. /// Whether the window's native maximize button is enabled or not.
  1092. /// If resizable is set to false, this setting is ignored.
  1093. ///
  1094. /// ## Platform-specific
  1095. ///
  1096. /// - **macOS:** Disables the "zoom" button in the window titlebar, which is also used to enter fullscreen mode.
  1097. /// - **Linux / iOS / Android:** Unsupported.
  1098. #[serde(default = "default_true")]
  1099. pub maximizable: bool,
  1100. /// Whether the window's native minimize button is enabled or not.
  1101. ///
  1102. /// ## Platform-specific
  1103. ///
  1104. /// - **Linux / iOS / Android:** Unsupported.
  1105. #[serde(default = "default_true")]
  1106. pub minimizable: bool,
  1107. /// Whether the window's native close button is enabled or not.
  1108. ///
  1109. /// ## Platform-specific
  1110. ///
  1111. /// - **Linux:** "GTK+ will do its best to convince the window manager not to show a close button.
  1112. /// Depending on the system, this function may not have any effect when called on a window that is already visible"
  1113. /// - **iOS / Android:** Unsupported.
  1114. #[serde(default = "default_true")]
  1115. pub closable: bool,
  1116. /// The window title.
  1117. #[serde(default = "default_title")]
  1118. pub title: String,
  1119. /// Whether the window starts as fullscreen or not.
  1120. #[serde(default)]
  1121. pub fullscreen: bool,
  1122. /// Whether the window will be initially focused or not.
  1123. #[serde(default = "default_true")]
  1124. pub focus: bool,
  1125. /// Whether the window is transparent or not.
  1126. ///
  1127. /// Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri > macOSPrivateApi`.
  1128. /// WARNING: Using private APIs on `macOS` prevents your application from being accepted to the `App Store`.
  1129. #[serde(default)]
  1130. pub transparent: bool,
  1131. /// Whether the window is maximized or not.
  1132. #[serde(default)]
  1133. pub maximized: bool,
  1134. /// Whether the window is visible or not.
  1135. #[serde(default = "default_true")]
  1136. pub visible: bool,
  1137. /// Whether the window should have borders and bars.
  1138. #[serde(default = "default_true")]
  1139. pub decorations: bool,
  1140. /// Whether the window should always be below other windows.
  1141. #[serde(default, alias = "always-on-bottom")]
  1142. pub always_on_bottom: bool,
  1143. /// Whether the window should always be on top of other windows.
  1144. #[serde(default, alias = "always-on-top")]
  1145. pub always_on_top: bool,
  1146. /// Whether the window should be visible on all workspaces or virtual desktops.
  1147. ///
  1148. /// ## Platform-specific
  1149. ///
  1150. /// - **Windows / iOS / Android:** Unsupported.
  1151. #[serde(default, alias = "visible-on-all-workspaces")]
  1152. pub visible_on_all_workspaces: bool,
  1153. /// Prevents the window contents from being captured by other apps.
  1154. #[serde(default, alias = "content-protected")]
  1155. pub content_protected: bool,
  1156. /// If `true`, hides the window icon from the taskbar on Windows and Linux.
  1157. #[serde(default, alias = "skip-taskbar")]
  1158. pub skip_taskbar: bool,
  1159. /// The initial window theme. Defaults to the system theme. Only implemented on Windows and macOS 10.14+.
  1160. pub theme: Option<crate::Theme>,
  1161. /// The style of the macOS title bar.
  1162. #[serde(default, alias = "title-bar-style")]
  1163. pub title_bar_style: TitleBarStyle,
  1164. /// If `true`, sets the window title to be hidden on macOS.
  1165. #[serde(default, alias = "hidden-title")]
  1166. pub hidden_title: bool,
  1167. /// Whether clicking an inactive window also clicks through to the webview on macOS.
  1168. #[serde(default, alias = "accept-first-mouse")]
  1169. pub accept_first_mouse: bool,
  1170. /// Defines the window [tabbing identifier] for macOS.
  1171. ///
  1172. /// Windows with matching tabbing identifiers will be grouped together.
  1173. /// If the tabbing identifier is not set, automatic tabbing will be disabled.
  1174. ///
  1175. /// [tabbing identifier]: <https://developer.apple.com/documentation/appkit/nswindow/1644704-tabbingidentifier>
  1176. #[serde(default, alias = "tabbing-identifier")]
  1177. pub tabbing_identifier: Option<String>,
  1178. /// Defines additional browser arguments on Windows. By default wry passes `--disable-features=msWebOOUI,msPdfOOUI,msSmartScreenProtection`
  1179. /// so if you use this method, you also need to disable these components by yourself if you want.
  1180. #[serde(default, alias = "additional-browser-args")]
  1181. pub additional_browser_args: Option<String>,
  1182. /// Whether or not the window has shadow.
  1183. ///
  1184. /// ## Platform-specific
  1185. ///
  1186. /// - **Windows:**
  1187. /// - `false` has no effect on decorated window, shadow are always ON.
  1188. /// - `true` will make ndecorated window have a 1px white border,
  1189. /// and on Windows 11, it will have a rounded corners.
  1190. /// - **Linux:** Unsupported.
  1191. #[serde(default = "default_true")]
  1192. pub shadow: bool,
  1193. /// Window effects.
  1194. ///
  1195. /// Requires the window to be transparent.
  1196. ///
  1197. /// ## Platform-specific:
  1198. ///
  1199. /// - **Windows**: If using decorations or shadows, you may want to try this workaround <https://github.com/tauri-apps/tao/issues/72#issuecomment-975607891>
  1200. /// - **Linux**: Unsupported
  1201. #[serde(default, alias = "window-effects")]
  1202. pub window_effects: Option<WindowEffectsConfig>,
  1203. /// Whether or not the webview should be launched in incognito mode.
  1204. ///
  1205. /// ## Platform-specific:
  1206. ///
  1207. /// - **Android**: Unsupported.
  1208. #[serde(default)]
  1209. pub incognito: bool,
  1210. /// Sets the window associated with this label to be the parent of the window to be created.
  1211. ///
  1212. /// ## Platform-specific
  1213. ///
  1214. /// - **Windows**: This sets the passed parent as an owner window to the window to be created.
  1215. /// From [MSDN owned windows docs](https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows):
  1216. /// - An owned window is always above its owner in the z-order.
  1217. /// - The system automatically destroys an owned window when its owner is destroyed.
  1218. /// - An owned window is hidden when its owner is minimized.
  1219. /// - **Linux**: This makes the new window transient for parent, see <https://docs.gtk.org/gtk3/method.Window.set_transient_for.html>
  1220. /// - **macOS**: This adds the window as a child of parent, see <https://developer.apple.com/documentation/appkit/nswindow/1419152-addchildwindow?language=objc>
  1221. pub parent: Option<String>,
  1222. /// The proxy URL for the WebView for all network requests.
  1223. ///
  1224. /// Must be either a `http://` or a `socks5://` URL.
  1225. ///
  1226. /// ## Platform-specific
  1227. ///
  1228. /// - **macOS**: Requires the `macos-proxy` feature flag and only compiles for macOS 14+.
  1229. pub proxy_url: Option<Url>,
  1230. /// Whether page zooming by hotkeys is enabled
  1231. ///
  1232. /// ## Platform-specific:
  1233. ///
  1234. /// - **Windows**: Controls WebView2's [`IsZoomControlEnabled`](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2settings?view=webview2-winrt-1.0.2420.47#iszoomcontrolenabled) setting.
  1235. /// - **MacOS / Linux**: Injects a polyfill that zooms in and out with `ctrl/command` + `-/=`,
  1236. /// 20% in each step, ranging from 20% to 1000%. Requires `webview:allow-set-webview-zoom` permission
  1237. ///
  1238. /// - **Android / iOS**: Unsupported.
  1239. #[serde(default)]
  1240. pub zoom_hotkeys_enabled: bool,
  1241. }
  1242. impl Default for WindowConfig {
  1243. fn default() -> Self {
  1244. Self {
  1245. label: default_window_label(),
  1246. url: WebviewUrl::default(),
  1247. user_agent: None,
  1248. drag_drop_enabled: true,
  1249. center: false,
  1250. x: None,
  1251. y: None,
  1252. width: default_width(),
  1253. height: default_height(),
  1254. min_width: None,
  1255. min_height: None,
  1256. max_width: None,
  1257. max_height: None,
  1258. resizable: true,
  1259. maximizable: true,
  1260. minimizable: true,
  1261. closable: true,
  1262. title: default_title(),
  1263. fullscreen: false,
  1264. focus: false,
  1265. transparent: false,
  1266. maximized: false,
  1267. visible: true,
  1268. decorations: true,
  1269. always_on_bottom: false,
  1270. always_on_top: false,
  1271. visible_on_all_workspaces: false,
  1272. content_protected: false,
  1273. skip_taskbar: false,
  1274. theme: None,
  1275. title_bar_style: Default::default(),
  1276. hidden_title: false,
  1277. accept_first_mouse: false,
  1278. tabbing_identifier: None,
  1279. additional_browser_args: None,
  1280. shadow: true,
  1281. window_effects: None,
  1282. incognito: false,
  1283. parent: None,
  1284. proxy_url: None,
  1285. zoom_hotkeys_enabled: false,
  1286. }
  1287. }
  1288. }
  1289. fn default_window_label() -> String {
  1290. "main".to_string()
  1291. }
  1292. fn default_width() -> f64 {
  1293. 800f64
  1294. }
  1295. fn default_height() -> f64 {
  1296. 600f64
  1297. }
  1298. fn default_title() -> String {
  1299. "Tauri App".to_string()
  1300. }
  1301. /// A Content-Security-Policy directive source list.
  1302. /// See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#sources>.
  1303. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  1304. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1305. #[serde(rename_all = "camelCase", untagged)]
  1306. pub enum CspDirectiveSources {
  1307. /// An inline list of CSP sources. Same as [`Self::List`], but concatenated with a space separator.
  1308. Inline(String),
  1309. /// A list of CSP sources. The collection will be concatenated with a space separator for the CSP string.
  1310. List(Vec<String>),
  1311. }
  1312. impl Default for CspDirectiveSources {
  1313. fn default() -> Self {
  1314. Self::List(Vec::new())
  1315. }
  1316. }
  1317. impl From<CspDirectiveSources> for Vec<String> {
  1318. fn from(sources: CspDirectiveSources) -> Self {
  1319. match sources {
  1320. CspDirectiveSources::Inline(source) => source.split(' ').map(|s| s.to_string()).collect(),
  1321. CspDirectiveSources::List(l) => l,
  1322. }
  1323. }
  1324. }
  1325. impl CspDirectiveSources {
  1326. /// Whether the given source is configured on this directive or not.
  1327. pub fn contains(&self, source: &str) -> bool {
  1328. match self {
  1329. Self::Inline(s) => s.contains(&format!("{source} ")) || s.contains(&format!(" {source}")),
  1330. Self::List(l) => l.contains(&source.into()),
  1331. }
  1332. }
  1333. /// Appends the given source to this directive.
  1334. pub fn push<S: AsRef<str>>(&mut self, source: S) {
  1335. match self {
  1336. Self::Inline(s) => {
  1337. s.push(' ');
  1338. s.push_str(source.as_ref());
  1339. }
  1340. Self::List(l) => {
  1341. l.push(source.as_ref().to_string());
  1342. }
  1343. }
  1344. }
  1345. /// Extends this CSP directive source list with the given array of sources.
  1346. pub fn extend(&mut self, sources: Vec<String>) {
  1347. for s in sources {
  1348. self.push(s);
  1349. }
  1350. }
  1351. }
  1352. /// A Content-Security-Policy definition.
  1353. /// See <https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP>.
  1354. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  1355. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1356. #[serde(rename_all = "camelCase", untagged)]
  1357. pub enum Csp {
  1358. /// The entire CSP policy in a single text string.
  1359. Policy(String),
  1360. /// An object mapping a directive with its sources values as a list of strings.
  1361. DirectiveMap(HashMap<String, CspDirectiveSources>),
  1362. }
  1363. impl From<HashMap<String, CspDirectiveSources>> for Csp {
  1364. fn from(map: HashMap<String, CspDirectiveSources>) -> Self {
  1365. Self::DirectiveMap(map)
  1366. }
  1367. }
  1368. impl From<Csp> for HashMap<String, CspDirectiveSources> {
  1369. fn from(csp: Csp) -> Self {
  1370. match csp {
  1371. Csp::Policy(policy) => {
  1372. let mut map = HashMap::new();
  1373. for directive in policy.split(';') {
  1374. let mut tokens = directive.trim().split(' ');
  1375. if let Some(directive) = tokens.next() {
  1376. let sources = tokens.map(|s| s.to_string()).collect::<Vec<String>>();
  1377. map.insert(directive.to_string(), CspDirectiveSources::List(sources));
  1378. }
  1379. }
  1380. map
  1381. }
  1382. Csp::DirectiveMap(m) => m,
  1383. }
  1384. }
  1385. }
  1386. impl Display for Csp {
  1387. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  1388. match self {
  1389. Self::Policy(s) => write!(f, "{s}"),
  1390. Self::DirectiveMap(m) => {
  1391. let len = m.len();
  1392. let mut i = 0;
  1393. for (directive, sources) in m {
  1394. let sources: Vec<String> = sources.clone().into();
  1395. write!(f, "{} {}", directive, sources.join(" "))?;
  1396. i += 1;
  1397. if i != len {
  1398. write!(f, "; ")?;
  1399. }
  1400. }
  1401. Ok(())
  1402. }
  1403. }
  1404. }
  1405. }
  1406. /// The possible values for the `dangerous_disable_asset_csp_modification` config option.
  1407. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  1408. #[serde(untagged)]
  1409. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1410. pub enum DisabledCspModificationKind {
  1411. /// If `true`, disables all CSP modification.
  1412. /// `false` is the default value and it configures Tauri to control the CSP.
  1413. Flag(bool),
  1414. /// Disables the given list of CSP directives modifications.
  1415. List(Vec<String>),
  1416. }
  1417. impl DisabledCspModificationKind {
  1418. /// Determines whether the given CSP directive can be modified or not.
  1419. pub fn can_modify(&self, directive: &str) -> bool {
  1420. match self {
  1421. Self::Flag(f) => !f,
  1422. Self::List(l) => !l.contains(&directive.into()),
  1423. }
  1424. }
  1425. }
  1426. impl Default for DisabledCspModificationKind {
  1427. fn default() -> Self {
  1428. Self::Flag(false)
  1429. }
  1430. }
  1431. /// Protocol scope definition.
  1432. /// It is a list of glob patterns that restrict the API access from the webview.
  1433. ///
  1434. /// Each pattern can start with a variable that resolves to a system base directory.
  1435. /// The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`,
  1436. /// `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`,
  1437. /// `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`,
  1438. /// `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.
  1439. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  1440. #[serde(untagged)]
  1441. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1442. pub enum FsScope {
  1443. /// A list of paths that are allowed by this scope.
  1444. AllowedPaths(Vec<PathBuf>),
  1445. /// A complete scope configuration.
  1446. #[serde(rename_all = "camelCase")]
  1447. Scope {
  1448. /// A list of paths that are allowed by this scope.
  1449. #[serde(default)]
  1450. allow: Vec<PathBuf>,
  1451. /// A list of paths that are not allowed by this scope.
  1452. /// This gets precedence over the [`Self::Scope::allow`] list.
  1453. #[serde(default)]
  1454. deny: Vec<PathBuf>,
  1455. /// Whether or not paths that contain components that start with a `.`
  1456. /// will require that `.` appears literally in the pattern; `*`, `?`, `**`,
  1457. /// or `[...]` will not match. This is useful because such files are
  1458. /// conventionally considered hidden on Unix systems and it might be
  1459. /// desirable to skip them when listing files.
  1460. ///
  1461. /// Defaults to `true` on Unix systems and `false` on Windows
  1462. // dotfiles are not supposed to be exposed by default on unix
  1463. #[serde(alias = "require-literal-leading-dot")]
  1464. require_literal_leading_dot: Option<bool>,
  1465. },
  1466. }
  1467. impl Default for FsScope {
  1468. fn default() -> Self {
  1469. Self::AllowedPaths(Vec::new())
  1470. }
  1471. }
  1472. impl FsScope {
  1473. /// The list of allowed paths.
  1474. pub fn allowed_paths(&self) -> &Vec<PathBuf> {
  1475. match self {
  1476. Self::AllowedPaths(p) => p,
  1477. Self::Scope { allow, .. } => allow,
  1478. }
  1479. }
  1480. /// The list of forbidden paths.
  1481. pub fn forbidden_paths(&self) -> Option<&Vec<PathBuf>> {
  1482. match self {
  1483. Self::AllowedPaths(_) => None,
  1484. Self::Scope { deny, .. } => Some(deny),
  1485. }
  1486. }
  1487. }
  1488. /// Config for the asset custom protocol.
  1489. ///
  1490. /// See more: <https://tauri.app/v1/api/config#assetprotocolconfig>
  1491. #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
  1492. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1493. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  1494. pub struct AssetProtocolConfig {
  1495. /// The access scope for the asset protocol.
  1496. #[serde(default)]
  1497. pub scope: FsScope,
  1498. /// Enables the asset protocol.
  1499. #[serde(default)]
  1500. pub enable: bool,
  1501. }
  1502. /// Security configuration.
  1503. ///
  1504. /// See more: <https://tauri.app/v1/api/config#securityconfig>
  1505. #[skip_serializing_none]
  1506. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
  1507. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1508. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  1509. pub struct SecurityConfig {
  1510. /// The Content Security Policy that will be injected on all HTML files on the built application.
  1511. /// If [`dev_csp`](#SecurityConfig.devCsp) is not specified, this value is also injected on dev.
  1512. ///
  1513. /// This is a really important part of the configuration since it helps you ensure your WebView is secured.
  1514. /// See <https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP>.
  1515. pub csp: Option<Csp>,
  1516. /// The Content Security Policy that will be injected on all HTML files on development.
  1517. ///
  1518. /// This is a really important part of the configuration since it helps you ensure your WebView is secured.
  1519. /// See <https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP>.
  1520. #[serde(alias = "dev-csp")]
  1521. pub dev_csp: Option<Csp>,
  1522. /// Freeze the `Object.prototype` when using the custom protocol.
  1523. #[serde(default, alias = "freeze-prototype")]
  1524. pub freeze_prototype: bool,
  1525. /// Disables the Tauri-injected CSP sources.
  1526. ///
  1527. /// At compile time, Tauri parses all the frontend assets and changes the Content-Security-Policy
  1528. /// to only allow loading of your own scripts and styles by injecting nonce and hash sources.
  1529. /// This stricts your CSP, which may introduce issues when using along with other flexing sources.
  1530. ///
  1531. /// This configuration option allows both a boolean and a list of strings as value.
  1532. /// A boolean instructs Tauri to disable the injection for all CSP injections,
  1533. /// and a list of strings indicates the CSP directives that Tauri cannot inject.
  1534. ///
  1535. /// **WARNING:** Only disable this if you know what you are doing and have properly configured the CSP.
  1536. /// Your application might be vulnerable to XSS attacks without this Tauri protection.
  1537. #[serde(default, alias = "dangerous-disable-asset-csp-modification")]
  1538. pub dangerous_disable_asset_csp_modification: DisabledCspModificationKind,
  1539. /// Custom protocol config.
  1540. #[serde(default, alias = "asset-protocol")]
  1541. pub asset_protocol: AssetProtocolConfig,
  1542. /// The pattern to use.
  1543. #[serde(default)]
  1544. pub pattern: PatternKind,
  1545. /// List of capabilities that are enabled on the application.
  1546. ///
  1547. /// If the list is empty, all capabilities are included.
  1548. #[serde(default)]
  1549. pub capabilities: Vec<CapabilityEntry>,
  1550. }
  1551. /// A capability entry which can be either an inlined capability or a reference to a capability defined on its own file.
  1552. #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
  1553. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1554. #[serde(rename_all = "camelCase", untagged)]
  1555. pub enum CapabilityEntry {
  1556. /// An inlined capability.
  1557. Inlined(Capability),
  1558. /// Reference to a capability identifier.
  1559. Reference(String),
  1560. }
  1561. /// The application pattern.
  1562. #[skip_serializing_none]
  1563. #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
  1564. #[serde(rename_all = "lowercase", tag = "use", content = "options")]
  1565. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1566. pub enum PatternKind {
  1567. /// Brownfield pattern.
  1568. Brownfield,
  1569. /// Isolation pattern. Recommended for security purposes.
  1570. Isolation {
  1571. /// The dir containing the index.html file that contains the secure isolation application.
  1572. dir: PathBuf,
  1573. },
  1574. }
  1575. impl Default for PatternKind {
  1576. fn default() -> Self {
  1577. Self::Brownfield
  1578. }
  1579. }
  1580. /// The App configuration object.
  1581. ///
  1582. /// See more: <https://tauri.app/v1/api/config#appconfig>
  1583. #[skip_serializing_none]
  1584. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
  1585. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1586. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  1587. pub struct AppConfig {
  1588. /// The windows configuration.
  1589. #[serde(default)]
  1590. pub windows: Vec<WindowConfig>,
  1591. /// Security configuration.
  1592. #[serde(default)]
  1593. pub security: SecurityConfig,
  1594. /// Configuration for app tray icon.
  1595. #[serde(alias = "tray-icon")]
  1596. pub tray_icon: Option<TrayIconConfig>,
  1597. /// MacOS private API configuration. Enables the transparent background API and sets the `fullScreenEnabled` preference to `true`.
  1598. #[serde(rename = "macOSPrivateApi", alias = "macos-private-api", default)]
  1599. pub macos_private_api: bool,
  1600. /// Whether we should inject the Tauri API on `window.__TAURI__` or not.
  1601. #[serde(default, alias = "with-global-tauri")]
  1602. pub with_global_tauri: bool,
  1603. }
  1604. impl AppConfig {
  1605. /// Returns all Cargo features.
  1606. pub fn all_features() -> Vec<&'static str> {
  1607. vec![
  1608. "tray-icon",
  1609. "macos-private-api",
  1610. "protocol-asset",
  1611. "isolation",
  1612. ]
  1613. }
  1614. /// Returns the enabled Cargo features.
  1615. pub fn features(&self) -> Vec<&str> {
  1616. let mut features = Vec::new();
  1617. if self.tray_icon.is_some() {
  1618. features.push("tray-icon");
  1619. }
  1620. if self.macos_private_api {
  1621. features.push("macos-private-api");
  1622. }
  1623. if self.security.asset_protocol.enable {
  1624. features.push("protocol-asset");
  1625. }
  1626. if let PatternKind::Isolation { .. } = self.security.pattern {
  1627. features.push("isolation");
  1628. }
  1629. features.sort_unstable();
  1630. features
  1631. }
  1632. }
  1633. /// Configuration for application tray icon.
  1634. ///
  1635. /// See more: <https://tauri.app/v1/api/config#trayiconconfig>
  1636. #[skip_serializing_none]
  1637. #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
  1638. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1639. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  1640. pub struct TrayIconConfig {
  1641. /// Set an id for this tray icon so you can reference it later, defaults to `main`.
  1642. pub id: Option<String>,
  1643. /// Path to the default icon to use for the tray icon.
  1644. #[serde(alias = "icon-path")]
  1645. pub icon_path: PathBuf,
  1646. /// 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.
  1647. #[serde(default, alias = "icon-as-template")]
  1648. pub icon_as_template: bool,
  1649. /// A Boolean value that determines whether the menu should appear when the tray icon receives a left click on macOS.
  1650. #[serde(default = "default_true", alias = "menu-on-left-click")]
  1651. pub menu_on_left_click: bool,
  1652. /// Title for MacOS tray
  1653. pub title: Option<String>,
  1654. /// Tray icon tooltip on Windows and macOS
  1655. pub tooltip: Option<String>,
  1656. }
  1657. /// General configuration for the iOS target.
  1658. #[skip_serializing_none]
  1659. #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]
  1660. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1661. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  1662. pub struct IosConfig {
  1663. /// The development team. This value is required for iOS development because code signing is enforced.
  1664. /// The `APPLE_DEVELOPMENT_TEAM` environment variable can be set to overwrite it.
  1665. #[serde(alias = "development-team")]
  1666. pub development_team: Option<String>,
  1667. }
  1668. /// General configuration for the iOS target.
  1669. #[skip_serializing_none]
  1670. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  1671. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1672. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  1673. pub struct AndroidConfig {
  1674. /// The minimum API level required for the application to run.
  1675. /// The Android system will prevent the user from installing the application if the system's API level is lower than the value specified.
  1676. #[serde(alias = "min-sdk-version", default = "default_min_sdk_version")]
  1677. pub min_sdk_version: u32,
  1678. }
  1679. impl Default for AndroidConfig {
  1680. fn default() -> Self {
  1681. Self {
  1682. min_sdk_version: default_min_sdk_version(),
  1683. }
  1684. }
  1685. }
  1686. fn default_min_sdk_version() -> u32 {
  1687. 24
  1688. }
  1689. /// Defines the URL or assets to embed in the application.
  1690. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  1691. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1692. #[serde(untagged, deny_unknown_fields)]
  1693. #[non_exhaustive]
  1694. pub enum FrontendDist {
  1695. /// An external URL that should be used as the default application URL.
  1696. Url(Url),
  1697. /// Path to a directory containing the frontend dist assets.
  1698. Directory(PathBuf),
  1699. /// An array of files to embed on the app.
  1700. Files(Vec<PathBuf>),
  1701. }
  1702. impl std::fmt::Display for FrontendDist {
  1703. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  1704. match self {
  1705. Self::Url(url) => write!(f, "{url}"),
  1706. Self::Directory(p) => write!(f, "{}", p.display()),
  1707. Self::Files(files) => write!(f, "{}", serde_json::to_string(files).unwrap()),
  1708. }
  1709. }
  1710. }
  1711. /// Describes the shell command to run before `tauri dev`.
  1712. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  1713. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1714. #[serde(rename_all = "camelCase", untagged)]
  1715. pub enum BeforeDevCommand {
  1716. /// Run the given script with the default options.
  1717. Script(String),
  1718. /// Run the given script with custom options.
  1719. ScriptWithOptions {
  1720. /// The script to execute.
  1721. script: String,
  1722. /// The current working directory.
  1723. cwd: Option<String>,
  1724. /// Whether `tauri dev` should wait for the command to finish or not. Defaults to `false`.
  1725. #[serde(default)]
  1726. wait: bool,
  1727. },
  1728. }
  1729. /// Describes a shell command to be executed when a CLI hook is triggered.
  1730. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
  1731. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1732. #[serde(rename_all = "camelCase", untagged)]
  1733. pub enum HookCommand {
  1734. /// Run the given script with the default options.
  1735. Script(String),
  1736. /// Run the given script with custom options.
  1737. ScriptWithOptions {
  1738. /// The script to execute.
  1739. script: String,
  1740. /// The current working directory.
  1741. cwd: Option<String>,
  1742. },
  1743. }
  1744. /// The Build configuration object.
  1745. ///
  1746. /// See more: <https://tauri.app/v1/api/config#buildconfig>
  1747. #[skip_serializing_none]
  1748. #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
  1749. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1750. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  1751. pub struct BuildConfig {
  1752. /// The binary used to build and run the application.
  1753. pub runner: Option<String>,
  1754. /// The URL to load in development.
  1755. ///
  1756. /// This is usually an URL to a dev server, which serves your application assets with hot-reload and HMR.
  1757. /// Most modern JavaScript bundlers like [vite](https://vitejs.dev/guide/) provides a way to start a dev server by default.
  1758. ///
  1759. /// If you don't have a dev server or don't want to use one, ignore this option and use [`frontendDist`](BuildConfig::frontend_dist)
  1760. /// and point to a web assets directory, and Tauri CLI will run its built-in dev server and provide a simple hot-reload experience.
  1761. #[serde(alias = "dev-url")]
  1762. pub dev_url: Option<Url>,
  1763. /// The path to the application assets (usually the `dist` folder of your javascript bundler)
  1764. /// or a URL that could be either a custom protocol registered in the tauri app (for example: `myprotocol://`)
  1765. /// or a remote URL (for example: `https://site.com/app`).
  1766. ///
  1767. /// When a path relative to the configuration file is provided,
  1768. /// it is read recursively and all files are embedded in the application binary.
  1769. /// Tauri then looks for an `index.html` and serves it as the default entry point for your application.
  1770. ///
  1771. /// You can also provide a list of paths to be embedded, which allows granular control over what files are added to the binary.
  1772. /// In this case, all files are added to the root and you must reference it that way in your HTML files.
  1773. ///
  1774. /// When a URL is provided, the application won't have bundled assets
  1775. /// and the application will load that URL by default.
  1776. #[serde(alias = "frontend-dist")]
  1777. pub frontend_dist: Option<FrontendDist>,
  1778. /// A shell command to run before `tauri dev` kicks in.
  1779. ///
  1780. /// The TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG environment variables are set if you perform conditional compilation.
  1781. #[serde(alias = "before-dev-command")]
  1782. pub before_dev_command: Option<BeforeDevCommand>,
  1783. /// A shell command to run before `tauri build` kicks in.
  1784. ///
  1785. /// The TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG environment variables are set if you perform conditional compilation.
  1786. #[serde(alias = "before-build-command")]
  1787. pub before_build_command: Option<HookCommand>,
  1788. /// A shell command to run before the bundling phase in `tauri build` kicks in.
  1789. ///
  1790. /// The TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG environment variables are set if you perform conditional compilation.
  1791. #[serde(alias = "before-bundle-command")]
  1792. pub before_bundle_command: Option<HookCommand>,
  1793. /// Features passed to `cargo` commands.
  1794. pub features: Option<Vec<String>>,
  1795. }
  1796. #[derive(Debug, PartialEq, Eq)]
  1797. struct PackageVersion(String);
  1798. impl<'d> serde::Deserialize<'d> for PackageVersion {
  1799. fn deserialize<D: Deserializer<'d>>(deserializer: D) -> Result<Self, D::Error> {
  1800. struct PackageVersionVisitor;
  1801. impl<'d> Visitor<'d> for PackageVersionVisitor {
  1802. type Value = PackageVersion;
  1803. fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
  1804. write!(
  1805. formatter,
  1806. "a semver string or a path to a package.json file"
  1807. )
  1808. }
  1809. fn visit_str<E: DeError>(self, value: &str) -> Result<PackageVersion, E> {
  1810. let path = PathBuf::from(value);
  1811. if path.exists() {
  1812. let json_str = read_to_string(&path)
  1813. .map_err(|e| DeError::custom(format!("failed to read version JSON file: {e}")))?;
  1814. let package_json: serde_json::Value = serde_json::from_str(&json_str)
  1815. .map_err(|e| DeError::custom(format!("failed to read version JSON file: {e}")))?;
  1816. if let Some(obj) = package_json.as_object() {
  1817. let version = obj
  1818. .get("version")
  1819. .ok_or_else(|| DeError::custom("JSON must contain a `version` field"))?
  1820. .as_str()
  1821. .ok_or_else(|| {
  1822. DeError::custom(format!("`{} > version` must be a string", path.display()))
  1823. })?;
  1824. Ok(PackageVersion(
  1825. Version::from_str(version)
  1826. .map_err(|_| DeError::custom("`package > version` must be a semver string"))?
  1827. .to_string(),
  1828. ))
  1829. } else {
  1830. Err(DeError::custom(
  1831. "`package > version` value is not a path to a JSON object",
  1832. ))
  1833. }
  1834. } else {
  1835. Ok(PackageVersion(
  1836. Version::from_str(value)
  1837. .map_err(|_| DeError::custom("`package > version` must be a semver string"))?
  1838. .to_string(),
  1839. ))
  1840. }
  1841. }
  1842. }
  1843. deserializer.deserialize_string(PackageVersionVisitor {})
  1844. }
  1845. }
  1846. fn version_deserializer<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
  1847. where
  1848. D: Deserializer<'de>,
  1849. {
  1850. Option::<PackageVersion>::deserialize(deserializer).map(|v| v.map(|v| v.0))
  1851. }
  1852. /// The Tauri configuration object.
  1853. /// It is read from a file where you can define your frontend assets,
  1854. /// configure the bundler and define a tray icon.
  1855. ///
  1856. /// The configuration file is generated by the
  1857. /// [`tauri init`](https://tauri.app/v1/api/cli#init) command that lives in
  1858. /// your Tauri application source directory (src-tauri).
  1859. ///
  1860. /// Once generated, you may modify it at will to customize your Tauri application.
  1861. ///
  1862. /// ## File Formats
  1863. ///
  1864. /// By default, the configuration is defined as a JSON file named `tauri.conf.json`.
  1865. ///
  1866. /// Tauri also supports JSON5 and TOML files via the `config-json5` and `config-toml` Cargo features, respectively.
  1867. /// The JSON5 file name must be either `tauri.conf.json` or `tauri.conf.json5`.
  1868. /// The TOML file name is `Tauri.toml`.
  1869. ///
  1870. /// ## Platform-Specific Configuration
  1871. ///
  1872. /// In addition to the default configuration file, Tauri can
  1873. /// read a platform-specific configuration from `tauri.linux.conf.json`,
  1874. /// `tauri.windows.conf.json`, `tauri.macos.conf.json`, `tauri.android.conf.json` and `tauri.ios.conf.json`
  1875. /// (or `Tauri.linux.toml`, `Tauri.windows.toml`, `Tauri.macos.toml`, `Tauri.android.toml` and `Tauri.ios.toml` if the `Tauri.toml` format is used),
  1876. /// which gets merged with the main configuration object.
  1877. ///
  1878. /// ## Configuration Structure
  1879. ///
  1880. /// The configuration is composed of the following objects:
  1881. ///
  1882. /// - [`app`](#appconfig): The Tauri configuration
  1883. /// - [`build`](#buildconfig): The build configuration
  1884. /// - [`bundle`](#bundleconfig): The bundle configurations
  1885. /// - [`plugins`](#pluginconfig): The plugins configuration
  1886. ///
  1887. /// ```json title="Example tauri.config.json file"
  1888. /// {
  1889. /// "productName": "tauri-app",
  1890. /// "version": "0.1.0"
  1891. /// "build": {
  1892. /// "beforeBuildCommand": "",
  1893. /// "beforeDevCommand": "",
  1894. /// "devUrl": "../dist",
  1895. /// "frontendDist": "../dist"
  1896. /// },
  1897. /// "app": {
  1898. /// "security": {
  1899. /// "csp": null
  1900. /// },
  1901. /// "windows": [
  1902. /// {
  1903. /// "fullscreen": false,
  1904. /// "height": 600,
  1905. /// "resizable": true,
  1906. /// "title": "Tauri App",
  1907. /// "width": 800
  1908. /// }
  1909. /// ]
  1910. /// },
  1911. /// "bundle": {},
  1912. /// "plugins": {}
  1913. /// }
  1914. /// ```
  1915. #[skip_serializing_none]
  1916. #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
  1917. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1918. #[serde(rename_all = "camelCase", deny_unknown_fields)]
  1919. pub struct Config {
  1920. /// The JSON schema for the Tauri config.
  1921. #[serde(rename = "$schema")]
  1922. pub schema: Option<String>,
  1923. /// App name.
  1924. #[serde(alias = "product-name")]
  1925. #[cfg_attr(feature = "schema", validate(regex(pattern = "^[^/\\:*?\"<>|]+$")))]
  1926. pub product_name: Option<String>,
  1927. /// App version. It is a semver version number or a path to a `package.json` file containing the `version` field. If removed the version number from `Cargo.toml` is used.
  1928. #[serde(deserialize_with = "version_deserializer", default)]
  1929. pub version: Option<String>,
  1930. /// The application identifier in reverse domain name notation (e.g. `com.tauri.example`).
  1931. /// This string must be unique across applications since it is used in system configurations like
  1932. /// the bundle ID and path to the webview data directory.
  1933. /// This string must contain only alphanumeric characters (A–Z, a–z, and 0–9), hyphens (-),
  1934. /// and periods (.).
  1935. #[serde(default)]
  1936. pub identifier: String,
  1937. /// The App configuration.
  1938. #[serde(default)]
  1939. pub app: AppConfig,
  1940. /// The build configuration.
  1941. #[serde(default = "default_build")]
  1942. pub build: BuildConfig,
  1943. /// The bundler configuration.
  1944. #[serde(default)]
  1945. pub bundle: BundleConfig,
  1946. /// The plugins config.
  1947. #[serde(default)]
  1948. pub plugins: PluginConfig,
  1949. }
  1950. impl Config {
  1951. /// The binary name. Returns the product name as kebab-case on Linux,
  1952. /// and returns it as is on all other platforms.
  1953. pub fn binary_name(&self) -> Option<String> {
  1954. #[cfg(target_os = "linux")]
  1955. {
  1956. self.product_name.as_ref().map(|n| n.to_kebab_case())
  1957. }
  1958. #[cfg(not(target_os = "linux"))]
  1959. {
  1960. self.product_name.clone()
  1961. }
  1962. }
  1963. }
  1964. /// The plugin configs holds a HashMap mapping a plugin name to its configuration object.
  1965. ///
  1966. /// See more: <https://tauri.app/v1/api/config#pluginconfig>
  1967. #[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize)]
  1968. #[cfg_attr(feature = "schema", derive(JsonSchema))]
  1969. pub struct PluginConfig(pub HashMap<String, JsonValue>);
  1970. fn default_build() -> BuildConfig {
  1971. BuildConfig {
  1972. runner: None,
  1973. dev_url: None,
  1974. frontend_dist: None,
  1975. before_dev_command: None,
  1976. before_build_command: None,
  1977. before_bundle_command: None,
  1978. features: None,
  1979. }
  1980. }
  1981. /// Implement `ToTokens` for all config structs, allowing a literal `Config` to be built.
  1982. ///
  1983. /// This allows for a build script to output the values in a `Config` to a `TokenStream`, which can
  1984. /// then be consumed by another crate. Useful for passing a config to both the build script and the
  1985. /// application using tauri while only parsing it once (in the build script).
  1986. #[cfg(feature = "build")]
  1987. mod build {
  1988. use super::*;
  1989. use crate::{literal_struct, tokens::*};
  1990. use proc_macro2::TokenStream;
  1991. use quote::{quote, ToTokens, TokenStreamExt};
  1992. use std::convert::identity;
  1993. impl ToTokens for WebviewUrl {
  1994. fn to_tokens(&self, tokens: &mut TokenStream) {
  1995. let prefix = quote! { ::tauri::utils::config::WebviewUrl };
  1996. tokens.append_all(match self {
  1997. Self::App(path) => {
  1998. let path = path_buf_lit(path);
  1999. quote! { #prefix::App(#path) }
  2000. }
  2001. Self::External(url) => {
  2002. let url = url_lit(url);
  2003. quote! { #prefix::External(#url) }
  2004. }
  2005. Self::CustomProtocol(url) => {
  2006. let url = url_lit(url);
  2007. quote! { #prefix::CustomProtocol(#url) }
  2008. }
  2009. })
  2010. }
  2011. }
  2012. impl ToTokens for crate::Theme {
  2013. fn to_tokens(&self, tokens: &mut TokenStream) {
  2014. let prefix = quote! { ::tauri::utils::Theme };
  2015. tokens.append_all(match self {
  2016. Self::Light => quote! { #prefix::Light },
  2017. Self::Dark => quote! { #prefix::Dark },
  2018. })
  2019. }
  2020. }
  2021. impl ToTokens for Color {
  2022. fn to_tokens(&self, tokens: &mut TokenStream) {
  2023. let Color(r, g, b, a) = self;
  2024. tokens.append_all(quote! {::tauri::utils::config::Color(#r,#g,#b,#a)});
  2025. }
  2026. }
  2027. impl ToTokens for WindowEffectsConfig {
  2028. fn to_tokens(&self, tokens: &mut TokenStream) {
  2029. let effects = vec_lit(self.effects.clone(), |d| d);
  2030. let state = opt_lit(self.state.as_ref());
  2031. let radius = opt_lit(self.radius.as_ref());
  2032. let color = opt_lit(self.color.as_ref());
  2033. literal_struct!(
  2034. tokens,
  2035. ::tauri::utils::config::WindowEffectsConfig,
  2036. effects,
  2037. state,
  2038. radius,
  2039. color
  2040. )
  2041. }
  2042. }
  2043. impl ToTokens for crate::TitleBarStyle {
  2044. fn to_tokens(&self, tokens: &mut TokenStream) {
  2045. let prefix = quote! { ::tauri::utils::TitleBarStyle };
  2046. tokens.append_all(match self {
  2047. Self::Visible => quote! { #prefix::Visible },
  2048. Self::Transparent => quote! { #prefix::Transparent },
  2049. Self::Overlay => quote! { #prefix::Overlay },
  2050. })
  2051. }
  2052. }
  2053. impl ToTokens for crate::WindowEffect {
  2054. fn to_tokens(&self, tokens: &mut TokenStream) {
  2055. let prefix = quote! { ::tauri::utils::WindowEffect };
  2056. #[allow(deprecated)]
  2057. tokens.append_all(match self {
  2058. WindowEffect::AppearanceBased => quote! { #prefix::AppearanceBased},
  2059. WindowEffect::Light => quote! { #prefix::Light},
  2060. WindowEffect::Dark => quote! { #prefix::Dark},
  2061. WindowEffect::MediumLight => quote! { #prefix::MediumLight},
  2062. WindowEffect::UltraDark => quote! { #prefix::UltraDark},
  2063. WindowEffect::Titlebar => quote! { #prefix::Titlebar},
  2064. WindowEffect::Selection => quote! { #prefix::Selection},
  2065. WindowEffect::Menu => quote! { #prefix::Menu},
  2066. WindowEffect::Popover => quote! { #prefix::Popover},
  2067. WindowEffect::Sidebar => quote! { #prefix::Sidebar},
  2068. WindowEffect::HeaderView => quote! { #prefix::HeaderView},
  2069. WindowEffect::Sheet => quote! { #prefix::Sheet},
  2070. WindowEffect::WindowBackground => quote! { #prefix::WindowBackground},
  2071. WindowEffect::HudWindow => quote! { #prefix::HudWindow},
  2072. WindowEffect::FullScreenUI => quote! { #prefix::FullScreenUI},
  2073. WindowEffect::Tooltip => quote! { #prefix::Tooltip},
  2074. WindowEffect::ContentBackground => quote! { #prefix::ContentBackground},
  2075. WindowEffect::UnderWindowBackground => quote! { #prefix::UnderWindowBackground},
  2076. WindowEffect::UnderPageBackground => quote! { #prefix::UnderPageBackground},
  2077. WindowEffect::Mica => quote! { #prefix::Mica},
  2078. WindowEffect::MicaDark => quote! { #prefix::MicaDark},
  2079. WindowEffect::MicaLight => quote! { #prefix::MicaLight},
  2080. WindowEffect::Blur => quote! { #prefix::Blur},
  2081. WindowEffect::Acrylic => quote! { #prefix::Acrylic},
  2082. WindowEffect::Tabbed => quote! { #prefix::Tabbed },
  2083. WindowEffect::TabbedDark => quote! { #prefix::TabbedDark },
  2084. WindowEffect::TabbedLight => quote! { #prefix::TabbedLight },
  2085. })
  2086. }
  2087. }
  2088. impl ToTokens for crate::WindowEffectState {
  2089. fn to_tokens(&self, tokens: &mut TokenStream) {
  2090. let prefix = quote! { ::tauri::utils::WindowEffectState };
  2091. #[allow(deprecated)]
  2092. tokens.append_all(match self {
  2093. WindowEffectState::Active => quote! { #prefix::Active},
  2094. WindowEffectState::FollowsWindowActiveState => quote! { #prefix::FollowsWindowActiveState},
  2095. WindowEffectState::Inactive => quote! { #prefix::Inactive},
  2096. })
  2097. }
  2098. }
  2099. impl ToTokens for WindowConfig {
  2100. fn to_tokens(&self, tokens: &mut TokenStream) {
  2101. let label = str_lit(&self.label);
  2102. let url = &self.url;
  2103. let user_agent = opt_str_lit(self.user_agent.as_ref());
  2104. let drag_drop_enabled = self.drag_drop_enabled;
  2105. let center = self.center;
  2106. let x = opt_lit(self.x.as_ref());
  2107. let y = opt_lit(self.y.as_ref());
  2108. let width = self.width;
  2109. let height = self.height;
  2110. let min_width = opt_lit(self.min_width.as_ref());
  2111. let min_height = opt_lit(self.min_height.as_ref());
  2112. let max_width = opt_lit(self.max_width.as_ref());
  2113. let max_height = opt_lit(self.max_height.as_ref());
  2114. let resizable = self.resizable;
  2115. let maximizable = self.maximizable;
  2116. let minimizable = self.minimizable;
  2117. let closable = self.closable;
  2118. let title = str_lit(&self.title);
  2119. let proxy_url = opt_lit(self.proxy_url.as_ref().map(url_lit).as_ref());
  2120. let fullscreen = self.fullscreen;
  2121. let focus = self.focus;
  2122. let transparent = self.transparent;
  2123. let maximized = self.maximized;
  2124. let visible = self.visible;
  2125. let decorations = self.decorations;
  2126. let always_on_bottom = self.always_on_bottom;
  2127. let always_on_top = self.always_on_top;
  2128. let visible_on_all_workspaces = self.visible_on_all_workspaces;
  2129. let content_protected = self.content_protected;
  2130. let skip_taskbar = self.skip_taskbar;
  2131. let theme = opt_lit(self.theme.as_ref());
  2132. let title_bar_style = &self.title_bar_style;
  2133. let hidden_title = self.hidden_title;
  2134. let accept_first_mouse = self.accept_first_mouse;
  2135. let tabbing_identifier = opt_str_lit(self.tabbing_identifier.as_ref());
  2136. let additional_browser_args = opt_str_lit(self.additional_browser_args.as_ref());
  2137. let shadow = self.shadow;
  2138. let window_effects = opt_lit(self.window_effects.as_ref());
  2139. let incognito = self.incognito;
  2140. let parent = opt_str_lit(self.parent.as_ref());
  2141. let zoom_hotkeys_enabled = self.zoom_hotkeys_enabled;
  2142. literal_struct!(
  2143. tokens,
  2144. ::tauri::utils::config::WindowConfig,
  2145. label,
  2146. url,
  2147. user_agent,
  2148. drag_drop_enabled,
  2149. center,
  2150. x,
  2151. y,
  2152. width,
  2153. height,
  2154. min_width,
  2155. min_height,
  2156. max_width,
  2157. max_height,
  2158. resizable,
  2159. maximizable,
  2160. minimizable,
  2161. closable,
  2162. title,
  2163. proxy_url,
  2164. fullscreen,
  2165. focus,
  2166. transparent,
  2167. maximized,
  2168. visible,
  2169. decorations,
  2170. always_on_bottom,
  2171. always_on_top,
  2172. visible_on_all_workspaces,
  2173. content_protected,
  2174. skip_taskbar,
  2175. theme,
  2176. title_bar_style,
  2177. hidden_title,
  2178. accept_first_mouse,
  2179. tabbing_identifier,
  2180. additional_browser_args,
  2181. shadow,
  2182. window_effects,
  2183. incognito,
  2184. parent,
  2185. zoom_hotkeys_enabled
  2186. );
  2187. }
  2188. }
  2189. impl ToTokens for PatternKind {
  2190. fn to_tokens(&self, tokens: &mut TokenStream) {
  2191. let prefix = quote! { ::tauri::utils::config::PatternKind };
  2192. tokens.append_all(match self {
  2193. Self::Brownfield => quote! { #prefix::Brownfield },
  2194. #[cfg(not(feature = "isolation"))]
  2195. Self::Isolation { dir: _ } => quote! { #prefix::Brownfield },
  2196. #[cfg(feature = "isolation")]
  2197. Self::Isolation { dir } => {
  2198. let dir = path_buf_lit(dir);
  2199. quote! { #prefix::Isolation { dir: #dir } }
  2200. }
  2201. })
  2202. }
  2203. }
  2204. impl ToTokens for WebviewInstallMode {
  2205. fn to_tokens(&self, tokens: &mut TokenStream) {
  2206. let prefix = quote! { ::tauri::utils::config::WebviewInstallMode };
  2207. tokens.append_all(match self {
  2208. Self::Skip => quote! { #prefix::Skip },
  2209. Self::DownloadBootstrapper { silent } => {
  2210. quote! { #prefix::DownloadBootstrapper { silent: #silent } }
  2211. }
  2212. Self::EmbedBootstrapper { silent } => {
  2213. quote! { #prefix::EmbedBootstrapper { silent: #silent } }
  2214. }
  2215. Self::OfflineInstaller { silent } => {
  2216. quote! { #prefix::OfflineInstaller { silent: #silent } }
  2217. }
  2218. Self::FixedRuntime { path } => {
  2219. let path = path_buf_lit(path);
  2220. quote! { #prefix::FixedRuntime { path: #path } }
  2221. }
  2222. })
  2223. }
  2224. }
  2225. impl ToTokens for WindowsConfig {
  2226. fn to_tokens(&self, tokens: &mut TokenStream) {
  2227. let webview_install_mode = if let Some(fixed_runtime_path) = &self.webview_fixed_runtime_path
  2228. {
  2229. WebviewInstallMode::FixedRuntime {
  2230. path: fixed_runtime_path.clone(),
  2231. }
  2232. } else {
  2233. self.webview_install_mode.clone()
  2234. };
  2235. tokens.append_all(quote! { ::tauri::utils::config::WindowsConfig {
  2236. webview_install_mode: #webview_install_mode,
  2237. ..Default::default()
  2238. }})
  2239. }
  2240. }
  2241. impl ToTokens for BundleConfig {
  2242. fn to_tokens(&self, tokens: &mut TokenStream) {
  2243. let publisher = quote!(None);
  2244. let icon = vec_lit(&self.icon, str_lit);
  2245. let active = self.active;
  2246. let targets = quote!(Default::default());
  2247. let resources = quote!(None);
  2248. let copyright = quote!(None);
  2249. let category = quote!(None);
  2250. let file_associations = quote!(None);
  2251. let short_description = quote!(None);
  2252. let long_description = quote!(None);
  2253. let external_bin = opt_vec_lit(self.external_bin.as_ref(), str_lit);
  2254. let windows = &self.windows;
  2255. let license = opt_str_lit(self.license.as_ref());
  2256. let license_file = opt_lit(self.license_file.as_ref().map(path_buf_lit).as_ref());
  2257. let linux = quote!(Default::default());
  2258. let macos = quote!(Default::default());
  2259. let ios = quote!(Default::default());
  2260. let android = quote!(Default::default());
  2261. literal_struct!(
  2262. tokens,
  2263. ::tauri::utils::config::BundleConfig,
  2264. active,
  2265. publisher,
  2266. icon,
  2267. targets,
  2268. resources,
  2269. copyright,
  2270. category,
  2271. license,
  2272. license_file,
  2273. file_associations,
  2274. short_description,
  2275. long_description,
  2276. external_bin,
  2277. windows,
  2278. linux,
  2279. macos,
  2280. ios,
  2281. android
  2282. );
  2283. }
  2284. }
  2285. impl ToTokens for FrontendDist {
  2286. fn to_tokens(&self, tokens: &mut TokenStream) {
  2287. let prefix = quote! { ::tauri::utils::config::FrontendDist };
  2288. tokens.append_all(match self {
  2289. Self::Url(url) => {
  2290. let url = url_lit(url);
  2291. quote! { #prefix::Url(#url) }
  2292. }
  2293. Self::Directory(path) => {
  2294. let path = path_buf_lit(path);
  2295. quote! { #prefix::Directory(#path) }
  2296. }
  2297. Self::Files(files) => {
  2298. let files = vec_lit(files, path_buf_lit);
  2299. quote! { #prefix::Files(#files) }
  2300. }
  2301. })
  2302. }
  2303. }
  2304. impl ToTokens for BuildConfig {
  2305. fn to_tokens(&self, tokens: &mut TokenStream) {
  2306. let dev_url = opt_lit(self.dev_url.as_ref().map(url_lit).as_ref());
  2307. let frontend_dist = opt_lit(self.frontend_dist.as_ref());
  2308. let runner = quote!(None);
  2309. let before_dev_command = quote!(None);
  2310. let before_build_command = quote!(None);
  2311. let before_bundle_command = quote!(None);
  2312. let features = quote!(None);
  2313. literal_struct!(
  2314. tokens,
  2315. ::tauri::utils::config::BuildConfig,
  2316. runner,
  2317. dev_url,
  2318. frontend_dist,
  2319. before_dev_command,
  2320. before_build_command,
  2321. before_bundle_command,
  2322. features
  2323. );
  2324. }
  2325. }
  2326. impl ToTokens for CspDirectiveSources {
  2327. fn to_tokens(&self, tokens: &mut TokenStream) {
  2328. let prefix = quote! { ::tauri::utils::config::CspDirectiveSources };
  2329. tokens.append_all(match self {
  2330. Self::Inline(sources) => {
  2331. let sources = sources.as_str();
  2332. quote!(#prefix::Inline(#sources.into()))
  2333. }
  2334. Self::List(list) => {
  2335. let list = vec_lit(list, str_lit);
  2336. quote!(#prefix::List(#list))
  2337. }
  2338. })
  2339. }
  2340. }
  2341. impl ToTokens for Csp {
  2342. fn to_tokens(&self, tokens: &mut TokenStream) {
  2343. let prefix = quote! { ::tauri::utils::config::Csp };
  2344. tokens.append_all(match self {
  2345. Self::Policy(policy) => {
  2346. let policy = policy.as_str();
  2347. quote!(#prefix::Policy(#policy.into()))
  2348. }
  2349. Self::DirectiveMap(list) => {
  2350. let map = map_lit(
  2351. quote! { ::std::collections::HashMap },
  2352. list,
  2353. str_lit,
  2354. identity,
  2355. );
  2356. quote!(#prefix::DirectiveMap(#map))
  2357. }
  2358. })
  2359. }
  2360. }
  2361. impl ToTokens for DisabledCspModificationKind {
  2362. fn to_tokens(&self, tokens: &mut TokenStream) {
  2363. let prefix = quote! { ::tauri::utils::config::DisabledCspModificationKind };
  2364. tokens.append_all(match self {
  2365. Self::Flag(flag) => {
  2366. quote! { #prefix::Flag(#flag) }
  2367. }
  2368. Self::List(directives) => {
  2369. let directives = vec_lit(directives, str_lit);
  2370. quote! { #prefix::List(#directives) }
  2371. }
  2372. });
  2373. }
  2374. }
  2375. impl ToTokens for CapabilityEntry {
  2376. fn to_tokens(&self, tokens: &mut TokenStream) {
  2377. let prefix = quote! { ::tauri::utils::config::CapabilityEntry };
  2378. tokens.append_all(match self {
  2379. Self::Inlined(capability) => {
  2380. quote! { #prefix::Inlined(#capability) }
  2381. }
  2382. Self::Reference(id) => {
  2383. let id = str_lit(id);
  2384. quote! { #prefix::Reference(#id) }
  2385. }
  2386. });
  2387. }
  2388. }
  2389. impl ToTokens for SecurityConfig {
  2390. fn to_tokens(&self, tokens: &mut TokenStream) {
  2391. let csp = opt_lit(self.csp.as_ref());
  2392. let dev_csp = opt_lit(self.dev_csp.as_ref());
  2393. let freeze_prototype = self.freeze_prototype;
  2394. let dangerous_disable_asset_csp_modification = &self.dangerous_disable_asset_csp_modification;
  2395. let asset_protocol = &self.asset_protocol;
  2396. let pattern = &self.pattern;
  2397. let capabilities = vec_lit(&self.capabilities, identity);
  2398. literal_struct!(
  2399. tokens,
  2400. ::tauri::utils::config::SecurityConfig,
  2401. csp,
  2402. dev_csp,
  2403. freeze_prototype,
  2404. dangerous_disable_asset_csp_modification,
  2405. asset_protocol,
  2406. pattern,
  2407. capabilities
  2408. );
  2409. }
  2410. }
  2411. impl ToTokens for TrayIconConfig {
  2412. fn to_tokens(&self, tokens: &mut TokenStream) {
  2413. let id = opt_str_lit(self.id.as_ref());
  2414. let icon_as_template = self.icon_as_template;
  2415. let menu_on_left_click = self.menu_on_left_click;
  2416. let icon_path = path_buf_lit(&self.icon_path);
  2417. let title = opt_str_lit(self.title.as_ref());
  2418. let tooltip = opt_str_lit(self.tooltip.as_ref());
  2419. literal_struct!(
  2420. tokens,
  2421. ::tauri::utils::config::TrayIconConfig,
  2422. id,
  2423. icon_path,
  2424. icon_as_template,
  2425. menu_on_left_click,
  2426. title,
  2427. tooltip
  2428. );
  2429. }
  2430. }
  2431. impl ToTokens for FsScope {
  2432. fn to_tokens(&self, tokens: &mut TokenStream) {
  2433. let prefix = quote! { ::tauri::utils::config::FsScope };
  2434. tokens.append_all(match self {
  2435. Self::AllowedPaths(allow) => {
  2436. let allowed_paths = vec_lit(allow, path_buf_lit);
  2437. quote! { #prefix::AllowedPaths(#allowed_paths) }
  2438. }
  2439. Self::Scope { allow, deny , require_literal_leading_dot} => {
  2440. let allow = vec_lit(allow, path_buf_lit);
  2441. let deny = vec_lit(deny, path_buf_lit);
  2442. let require_literal_leading_dot = opt_lit(require_literal_leading_dot.as_ref());
  2443. quote! { #prefix::Scope { allow: #allow, deny: #deny, require_literal_leading_dot: #require_literal_leading_dot } }
  2444. }
  2445. });
  2446. }
  2447. }
  2448. impl ToTokens for AssetProtocolConfig {
  2449. fn to_tokens(&self, tokens: &mut TokenStream) {
  2450. let scope = &self.scope;
  2451. tokens.append_all(quote! { ::tauri::utils::config::AssetProtocolConfig { scope: #scope, ..Default::default() } })
  2452. }
  2453. }
  2454. impl ToTokens for AppConfig {
  2455. fn to_tokens(&self, tokens: &mut TokenStream) {
  2456. let windows = vec_lit(&self.windows, identity);
  2457. let security = &self.security;
  2458. let tray_icon = opt_lit(self.tray_icon.as_ref());
  2459. let macos_private_api = self.macos_private_api;
  2460. let with_global_tauri = self.with_global_tauri;
  2461. literal_struct!(
  2462. tokens,
  2463. ::tauri::utils::config::AppConfig,
  2464. windows,
  2465. security,
  2466. tray_icon,
  2467. macos_private_api,
  2468. with_global_tauri
  2469. );
  2470. }
  2471. }
  2472. impl ToTokens for PluginConfig {
  2473. fn to_tokens(&self, tokens: &mut TokenStream) {
  2474. let config = map_lit(
  2475. quote! { ::std::collections::HashMap },
  2476. &self.0,
  2477. str_lit,
  2478. json_value_lit,
  2479. );
  2480. tokens.append_all(quote! { ::tauri::utils::config::PluginConfig(#config) })
  2481. }
  2482. }
  2483. impl ToTokens for Config {
  2484. fn to_tokens(&self, tokens: &mut TokenStream) {
  2485. let schema = quote!(None);
  2486. let product_name = opt_str_lit(self.product_name.as_ref());
  2487. let version = opt_str_lit(self.version.as_ref());
  2488. let identifier = str_lit(&self.identifier);
  2489. let app = &self.app;
  2490. let build = &self.build;
  2491. let bundle = &self.bundle;
  2492. let plugins = &self.plugins;
  2493. literal_struct!(
  2494. tokens,
  2495. ::tauri::utils::config::Config,
  2496. schema,
  2497. product_name,
  2498. version,
  2499. identifier,
  2500. app,
  2501. build,
  2502. bundle,
  2503. plugins
  2504. );
  2505. }
  2506. }
  2507. }
  2508. #[cfg(test)]
  2509. mod test {
  2510. use super::*;
  2511. // TODO: create a test that compares a config to a json config
  2512. #[test]
  2513. // test all of the default functions
  2514. fn test_defaults() {
  2515. // get default app config
  2516. let a_config = AppConfig::default();
  2517. // get default build config
  2518. let b_config = BuildConfig::default();
  2519. // get default window
  2520. let d_windows: Vec<WindowConfig> = vec![];
  2521. // get default bundle
  2522. let d_bundle = BundleConfig::default();
  2523. // create a tauri config.
  2524. let app = AppConfig {
  2525. windows: vec![],
  2526. security: SecurityConfig {
  2527. csp: None,
  2528. dev_csp: None,
  2529. freeze_prototype: false,
  2530. dangerous_disable_asset_csp_modification: DisabledCspModificationKind::Flag(false),
  2531. asset_protocol: AssetProtocolConfig::default(),
  2532. pattern: Default::default(),
  2533. capabilities: Vec::new(),
  2534. },
  2535. tray_icon: None,
  2536. macos_private_api: false,
  2537. with_global_tauri: false,
  2538. };
  2539. // create a build config
  2540. let build = BuildConfig {
  2541. runner: None,
  2542. dev_url: None,
  2543. frontend_dist: None,
  2544. before_dev_command: None,
  2545. before_build_command: None,
  2546. before_bundle_command: None,
  2547. features: None,
  2548. };
  2549. // create a bundle config
  2550. let bundle = BundleConfig {
  2551. active: false,
  2552. targets: Default::default(),
  2553. publisher: None,
  2554. icon: Vec::new(),
  2555. resources: None,
  2556. copyright: None,
  2557. category: None,
  2558. file_associations: None,
  2559. short_description: None,
  2560. long_description: None,
  2561. license: None,
  2562. license_file: None,
  2563. linux: Default::default(),
  2564. macos: Default::default(),
  2565. external_bin: None,
  2566. windows: Default::default(),
  2567. ios: Default::default(),
  2568. android: Default::default(),
  2569. };
  2570. // test the configs
  2571. assert_eq!(a_config, app);
  2572. assert_eq!(b_config, build);
  2573. assert_eq!(d_bundle, bundle);
  2574. assert_eq!(d_windows, app.windows);
  2575. }
  2576. }