chore: update documentation

This commit is contained in:
Lucas Nogueira
2026-09-22 11:30:47 -03:00
parent d869c162a7
commit a87a3c7d44
104 changed files with 4875 additions and 222 deletions
+13
View File
@@ -66,24 +66,35 @@ pub enum Error {
/// Temp dir is not on same mount mount. This prevents our updater to rename the AppImage to a temp file.
#[error("temp directory is not on the same mount point as the AppImage")]
TempDirNotOnSameMountPoint,
/// The downloaded archive does not contain a binary for the current target.
#[error("binary for the current target not found in the archive")]
BinaryNotFoundInArchive,
/// Could not create a temporary directory to store the downloaded update.
#[error("failed to create temporary directory")]
TempDirNotFound,
/// The privilege escalation prompt shown before installing a Linux package
/// failed or was dismissed by the user.
#[error("Authentication failed or was cancelled")]
AuthenticationFailed,
/// Installing the downloaded `.deb` package failed.
#[error("Failed to install .deb package")]
DebInstallFailed,
/// The package manager could not install the downloaded Linux package.
#[error("Failed to install package")]
PackageInstallFailed,
/// The downloaded update is not in a format the updater can install on the current platform.
#[error("invalid updater binary format")]
InvalidUpdaterFormat,
/// `http` crate errors.
#[error(transparent)]
Http(#[from] http::Error),
/// A request header value is not valid.
#[error(transparent)]
InvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
/// A request header name is not valid.
#[error(transparent)]
InvalidHeaderName(#[from] http::header::InvalidHeaderName),
/// The release publish date could not be formatted as an RFC 3339 string.
#[error("Failed to format date")]
FormatDate,
/// The configured updater endpoint must use a secure protocol like `https`
@@ -105,6 +116,7 @@ pub enum Error {
"The update signature does not specify the version it was signed for, which `requireSignedVersion` requires. Re-sign and re-publish this release, or disable `requireSignedVersion`."
)]
MissingSignedVersion,
/// Tauri errors.
#[error(transparent)]
Tauri(#[from] tauri::Error),
}
@@ -118,4 +130,5 @@ impl Serialize for Error {
}
}
/// A [`Result`](std::result::Result) alias whose error type is the updater [`Error`](enum@Error).
pub type Result<T> = std::result::Result<T, Error>;
+46
View File
@@ -137,6 +137,21 @@ struct UpdaterState {
headers: HeaderMap,
}
/// Builder for the updater plugin.
///
/// The values set here are the defaults used by every [`Updater`] created through
/// [`UpdaterExt::updater`] and [`UpdaterExt::updater_builder`]; they can still be overridden
/// per updater instance on the [`UpdaterBuilder`].
///
/// # Examples
///
/// ```no_run
/// use tauri::Runtime;
///
/// fn register_updater<R: Runtime>(builder: tauri::Builder<R>) -> tauri::Builder<R> {
/// builder.plugin(tauri_plugin_updater::Builder::new().build())
/// }
/// ```
#[derive(Default)]
pub struct Builder {
target: Option<String>,
@@ -147,15 +162,26 @@ pub struct Builder {
}
impl Builder {
/// Creates a new builder with the default configuration.
pub fn new() -> Self {
Self::default()
}
/// Sets the target name used when checking for updates.
///
/// It replaces the `{{target}}` variable in the endpoint URLs and is used as the key to look
/// up the release in the `platforms` object of a static update manifest.
///
/// When it is not set, the updater uses the current operating system name (`linux`, `darwin`
/// or `windows`) in the endpoint URLs and looks for `{os}-{arch}-{bundle_type}` then
/// `{os}-{arch}` in the manifest.
pub fn target(mut self, target: impl Into<String>) -> Self {
self.target.replace(target.into());
self
}
/// Sets the public key used to verify the update signature,
/// overriding the `pubkey` value of the plugin configuration.
pub fn pubkey<S: Into<String>>(mut self, pubkey: S) -> Self {
self.pubkey.replace(pubkey.into());
self
@@ -189,6 +215,11 @@ impl Builder {
self
}
/// Adds a header to be sent on every updater request.
///
/// # Errors
///
/// Returns an error if the header name or the header value is not valid.
pub fn header<K, V>(mut self, key: K, value: V) -> Result<Self>
where
HeaderName: TryFrom<K>,
@@ -204,11 +235,22 @@ impl Builder {
Ok(self)
}
/// Replaces all the headers sent on updater requests with the given map,
/// discarding the ones previously added with [`Self::header`].
pub fn headers(mut self, headers: HeaderMap) -> Self {
self.headers = headers;
self
}
/// Sets the default function used to decide whether a remote release should be installed.
///
/// The closure receives the current application version and the remote release,
/// and must return `true` when the release should be treated as an update.
///
/// It applies to every updater created through [`UpdaterExt`] and takes precedence over the
/// `allowDowngrades` configuration value; it can still be overridden per updater instance with
/// [`UpdaterBuilder::version_comparator`]. When no comparator is set at all, a release is
/// installed only if its version is greater than the current one.
pub fn default_version_comparator<
F: Fn(Version, RemoteRelease) -> bool + Send + Sync + 'static,
>(
@@ -219,6 +261,10 @@ impl Builder {
self
}
/// Builds the updater plugin, registering the `check`, `download`, `install`
/// and `download_and_install` commands used by the JavaScript API.
///
/// Pass the returned plugin to [`tauri::Builder::plugin`].
pub fn build<R: Runtime>(self) -> TauriPlugin<R, Config> {
let pubkey = self.pubkey;
let target = self.target;
+115
View File
@@ -43,15 +43,26 @@ use crate::{
const UPDATER_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"),);
/// The kind of bundle the running application was installed from.
///
/// Its name is appended to the updater target string (`{os}-{arch}-{bundle_type}`) when looking
/// up the release in the update manifest and replaces the `{{bundle_type}}` variable in the
/// endpoint URLs.
#[derive(Copy, Clone)]
pub enum Installer {
/// Linux AppImage bundle, named `appimage`.
AppImage,
/// Debian package, named `deb`.
Deb,
/// RPM package, named `rpm`.
Rpm,
/// macOS application bundle, named `app`. Also used for applications distributed as DMG.
App,
/// Windows WiX (MSI) installer, named `msi`.
Msi,
/// Windows NSIS installer, named `nsis`.
Nsis,
}
@@ -68,6 +79,7 @@ impl Installer {
}
}
/// The update information of a single platform in the update manifest.
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct ReleaseManifestPlatform {
/// Download URL for the platform
@@ -76,11 +88,18 @@ pub struct ReleaseManifestPlatform {
pub signature: String,
}
/// The platform specific data of a [`RemoteRelease`], in either of the two supported shapes.
#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(untagged)]
pub enum RemoteReleaseInner {
/// Server Format: the endpoint resolved the platform itself and returned a single
/// download URL and signature.
Dynamic(ReleaseManifestPlatform),
/// Static Format: the manifest describes every platform it supports and the updater
/// picks the entry matching the current target.
Static {
/// Update information for each platform, keyed by the updater target string
/// (e.g. `darwin-aarch64`).
platforms: HashMap<String, ReleaseManifestPlatform>,
},
}
@@ -126,8 +145,16 @@ impl RemoteRelease {
}
}
/// Function executed right before the Windows installer is spawned and the app exits.
/// See [`UpdaterBuilder::on_before_exit`].
pub type OnBeforeExit = Arc<dyn Fn() + Send + Sync + 'static>;
/// Function that customizes the `reqwest` client builder used for the updater requests.
/// See [`UpdaterBuilder::configure_client`].
pub type OnBeforeRequest = Arc<dyn Fn(ClientBuilder) -> ClientBuilder + Send + Sync + 'static>;
/// Function that decides whether a remote release must be installed.
///
/// It receives the current application version and the remote release,
/// and returns `true` when the release should be treated as an update.
pub type VersionComparator = Arc<dyn Fn(Version, RemoteRelease) -> bool + Send + Sync>;
#[cfg(target_os = "macos")]
type MainThreadClosure = Box<dyn FnOnce() + Send + Sync + 'static>;
@@ -155,6 +182,10 @@ struct UpdaterContext {
restart_after_install: bool,
}
/// Builder for an [`Updater`] instance.
///
/// Get one from [`crate::UpdaterExt::updater_builder`], which pre-fills it with the plugin
/// configuration, then call [`UpdaterBuilder::build`].
pub struct UpdaterBuilder {
current_version: Version,
pub(crate) version_comparator: Option<VersionComparator>,
@@ -208,6 +239,12 @@ impl UpdaterBuilder {
}
}
/// Sets the function used to decide whether the remote release must be installed,
/// replacing the comparator set with [`crate::Builder::default_version_comparator`]
/// and the behavior of the `allowDowngrades` configuration value.
///
/// When no comparator is set, a release is only installed if its version is greater
/// than the current application version.
pub fn version_comparator<F: Fn(Version, RemoteRelease) -> bool + Send + Sync + 'static>(
mut self,
f: F,
@@ -216,11 +253,29 @@ impl UpdaterBuilder {
self
}
/// Sets the target name used when checking for updates.
///
/// It replaces the `{{target}}` variable in the endpoint URLs and is used as the key to look
/// up the release in the `platforms` object of a static update manifest.
///
/// When it is not set, the updater uses the current operating system name (`linux`, `darwin`
/// or `windows`) in the endpoint URLs and looks for `{os}-{arch}-{bundle_type}` then
/// `{os}-{arch}` in the manifest.
pub fn target(mut self, target: impl Into<String>) -> Self {
self.target.replace(target.into());
self
}
/// Sets the endpoints to fetch the update manifest from,
/// overriding the `endpoints` configuration value.
///
/// They are checked in order and the first one that returns a valid release wins.
///
/// # Errors
///
/// Returns [`Error::InsecureTransportProtocol`] on release builds if an endpoint does not use
/// the `https` protocol and the `dangerousInsecureTransportProtocol` configuration value is
/// not enabled. On debug builds a warning is printed instead.
pub fn endpoints(mut self, endpoints: Vec<Url>) -> Result<Self> {
crate::config::validate_endpoints(
&endpoints,
@@ -231,11 +286,19 @@ impl UpdaterBuilder {
Ok(self)
}
/// Sets the path of the application executable, which is used to determine where the update
/// must be installed. Defaults to the path of the current executable, or to the AppImage path
/// when the application runs as an AppImage.
pub fn executable_path<P: AsRef<Path>>(mut self, p: P) -> Self {
self.executable_path.replace(p.as_ref().into());
self
}
/// Adds a header to be sent on the update check and download requests.
///
/// # Errors
///
/// Returns an error if the header name or the header value is not valid.
pub fn header<K, V>(mut self, key: K, value: V) -> Result<Self>
where
HeaderName: TryFrom<K>,
@@ -251,21 +314,28 @@ impl UpdaterBuilder {
Ok(self)
}
/// Replaces all the headers sent on the update check and download requests with the given map,
/// discarding the ones previously added with [`Self::header`].
pub fn headers(mut self, headers: HeaderMap) -> Self {
self.headers = headers;
self
}
/// Removes all the headers previously set on this builder.
pub fn clear_headers(mut self) -> Self {
self.headers.clear();
self
}
/// Sets the timeout of the update check and download requests.
/// When it is not set, the requests do not time out.
pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
/// Sets the proxy used for the update check and download requests.
/// It is ignored when [`Self::no_proxy`] was called.
pub fn proxy(mut self, proxy: Url) -> Self {
self.proxy.replace(proxy);
self
@@ -277,6 +347,8 @@ impl UpdaterBuilder {
self
}
/// Sets the public key used to verify the update signature,
/// overriding the `pubkey` value of the plugin configuration.
pub fn pubkey<S: Into<String>>(mut self, pubkey: S) -> Self {
self.context.config.pubkey = pubkey.into();
self
@@ -362,6 +434,15 @@ impl UpdaterBuilder {
self
}
/// Builds the [`Updater`].
///
/// # Errors
///
/// - [`Error::EmptyEndpoints`]: neither [`Self::endpoints`] nor the `endpoints`
/// configuration value provided an endpoint to check.
/// - [`Error::UnsupportedArch`]: the updater does not support the current architecture.
/// - [`Error::FailedToDetermineExtractPath`]: the install directory could not be resolved
/// from the executable path.
pub fn build(self) -> Result<Updater> {
let endpoints = self
.endpoints
@@ -412,6 +493,9 @@ impl UpdaterBuilder {
}
}
/// Checks the configured endpoints for an application update.
///
/// Get one from [`crate::UpdaterExt::updater`] or by calling [`UpdaterBuilder::build`].
pub struct Updater {
current_version: Version,
version_comparator: Option<VersionComparator>,
@@ -429,6 +513,25 @@ pub struct Updater {
}
impl Updater {
/// Checks the endpoints for an update, returning the first release that the version
/// comparator accepts.
///
/// Each endpoint is requested in order, with the `{{current_version}}`, `{{target}}`,
/// `{{arch}}` and `{{bundle_type}}` variables replaced in its URL, until one of them
/// answers with a release manifest the updater can parse.
///
/// Resolves to `None` when an endpoint replies with `204 No Content` or when the release it
/// announced is not considered an update - by default when its version is not greater than the
/// current application version.
///
/// # Errors
///
/// - [`Error::UnsupportedOs`]: no target was set and the updater does not support the
/// current operating system.
/// - [`Error::ReleaseNotFound`]: no endpoint returned a release manifest.
/// - The last request or deserialization error when every endpoint failed.
/// - [`Error::TargetNotFound`] or [`Error::TargetsNotFound`]: the manifest has no entry
/// for the current target.
pub async fn check(&self) -> Result<Option<Update>> {
// we want JSON only
let mut headers = self.headers.clone();
@@ -638,6 +741,10 @@ impl Updater {
}
}
/// An update announced by the remote server, returned by [`Updater::check`].
///
/// Use [`Update::download`] followed by [`Update::install`], or [`Update::download_and_install`],
/// to apply it.
#[derive(Clone)]
pub struct Update {
/// Update description
@@ -1427,6 +1534,14 @@ fn updater_arch() -> Option<&'static str> {
}
}
/// Resolves the path the update must be installed to from the path of the application executable.
///
/// This is the directory holding the executable, except on macOS where the `.app` bundle path is
/// returned for executables living in `Contents/MacOS`.
///
/// # Errors
///
/// Returns [`Error::FailedToDetermineExtractPath`] when the path has no parent directory.
pub fn extract_path_from_executable(executable_path: &Path) -> Result<PathBuf> {
// Return the path of the current executable by default
// Example C:\Program Files\My App\