feat(api): add app-specific directory APIs, closes #5263 (#5272)

Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
Caesar Schinas 2022-09-28 23:34:09 +01:00 committed by GitHub
parent eedfa5e618
commit 5d89905e39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 387 additions and 137 deletions

6
.changes/app-dirs-api.md Normal file
View File

@ -0,0 +1,6 @@
---
"tauri": minor
"api": minor
---
Add new app-specific `BaseDirectory` enum variants `AppConfig`, `AppData`, `AppLocalData`, `AppCache` and `AppLog` along with equivalent functions in `path` module and deprecated ambiguous variants `Log` and `App` along with their equivalent functions in `path` module.

View File

@ -1129,7 +1129,8 @@ macro_rules! check_feature {
/// Each pattern can start with a variable that resolves to a system base directory.
/// The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`,
/// `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`,
/// `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`.
/// `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`,
/// `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(JsonSchema))]
#[serde(untagged)]
@ -1465,7 +1466,8 @@ pub struct ShellAllowedCommand {
/// It can start with a variable that resolves to a system base directory.
/// The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`,
/// `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`,
/// `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`.
/// `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`,
/// `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.
#[serde(rename = "cmd", default)] // use default just so the schema doesn't flag it as required
pub command: PathBuf,

File diff suppressed because one or more lines are too long

View File

@ -13,61 +13,94 @@ use crate::{Config, Env, PackageInfo};
use serde_repr::{Deserialize_repr, Serialize_repr};
/// A base directory to be used in [`resolve_path`].
///
/// The base directory is the optional root of a file system operation.
/// If informed by the API call, all paths will be relative to the path of the given directory.
///
/// For more information, check the [`dirs_next` documentation](https://docs.rs/dirs_next/).
#[derive(Serialize_repr, Deserialize_repr, Clone, Copy, Debug)]
#[repr(u16)]
#[non_exhaustive]
pub enum BaseDirectory {
/// The Audio directory.
Audio = 1,
/// The Cache directory.
Cache,
/// The Config directory.
Config,
/// The Data directory.
Data,
/// The LocalData directory.
LocalData,
/// The Desktop directory.
Desktop,
/// The Document directory.
Document,
/// The Download directory.
Download,
/// The Executable directory.
Executable,
/// The Font directory.
Font,
/// The Home directory.
Home,
/// The Picture directory.
Picture,
/// The Public directory.
Public,
/// The Runtime directory.
Runtime,
/// The Template directory.
Template,
/// The Video directory.
Video,
/// The Resource directory.
Resource,
/// The default App config directory.
/// Resolves to [`BaseDirectory::Config`].
App,
/// The Log directory.
/// Resolves to `BaseDirectory::Home/Library/Logs/{bundle_identifier}` on macOS
/// and `BaseDirectory::Config/{bundle_identifier}/logs` on linux and windows.
Log,
/// A temporary directory.
/// Resolves to [`temp_dir`].
Temp,
// we have to wrap the BaseDirectory enum in a module for #[allow(deprecated)]
// to work, because the procedural macros on the enum prevent it from working directly
// TODO: remove this workaround in v2 along with deprecated variants
#[allow(deprecated)]
mod base_directory {
use super::*;
/// A base directory to be used in [`resolve_path`].
///
/// The base directory is the optional root of a file system operation.
/// If informed by the API call, all paths will be relative to the path of the given directory.
///
/// For more information, check the [`dirs_next` documentation](https://docs.rs/dirs_next/).
#[derive(Serialize_repr, Deserialize_repr, Clone, Copy, Debug)]
#[repr(u16)]
#[non_exhaustive]
pub enum BaseDirectory {
/// The Audio directory.
Audio = 1,
/// The Cache directory.
Cache,
/// The Config directory.
Config,
/// The Data directory.
Data,
/// The LocalData directory.
LocalData,
/// The Desktop directory.
Desktop,
/// The Document directory.
Document,
/// The Download directory.
Download,
/// The Executable directory.
Executable,
/// The Font directory.
Font,
/// The Home directory.
Home,
/// The Picture directory.
Picture,
/// The Public directory.
Public,
/// The Runtime directory.
Runtime,
/// The Template directory.
Template,
/// The Video directory.
Video,
/// The Resource directory.
Resource,
/// The default app config directory.
/// Resolves to [`BaseDirectory::Config`]`/{bundle_identifier}`.
#[deprecated(
since = "1.2.0",
note = "Will be removed in 2.0.0. Use `BaseDirectory::AppConfig` or BaseDirectory::AppData` instead."
)]
App,
/// The default app log directory.
/// Resolves to [`BaseDirectory::Home`]`/Library/Logs/{bundle_identifier}` on macOS
/// and [`BaseDirectory::Config`]`/{bundle_identifier}/logs` on linux and Windows.
#[deprecated(
since = "1.2.0",
note = "Will be removed in 2.0.0. Use `BaseDirectory::AppLog` instead."
)]
Log,
/// A temporary directory.
/// Resolves to [`temp_dir`].
Temp,
/// The default app config directory.
/// Resolves to [`BaseDirectory::Config`]`/{bundle_identifier}`.
AppConfig,
/// The default app data directory.
/// Resolves to [`BaseDirectory::Data`]`/{bundle_identifier}`.
AppData,
/// The default app local data directory.
/// Resolves to [`BaseDirectory::LocalData`]`/{bundle_identifier}`.
AppLocalData,
/// The default app cache directory.
/// Resolves to [`BaseDirectory::Cache`]`/{bundle_identifier}`.
AppCache,
/// The default app log directory.
/// Resolves to [`BaseDirectory::Home`]`/Library/Logs/{bundle_identifier}` on macOS
/// and [`BaseDirectory::Config`]`/{bundle_identifier}/logs` on linux and Windows.
AppLog,
}
}
pub use base_directory::BaseDirectory;
impl BaseDirectory {
/// Gets the variable that represents this [`BaseDirectory`] for string paths.
@ -90,9 +123,16 @@ impl BaseDirectory {
Self::Template => "$TEMPLATE",
Self::Video => "$VIDEO",
Self::Resource => "$RESOURCE",
#[allow(deprecated)]
Self::App => "$APP",
#[allow(deprecated)]
Self::Log => "$LOG",
Self::Temp => "$TEMP",
Self::AppConfig => "$APPCONFIG",
Self::AppData => "$APPDATA",
Self::AppLocalData => "$APPLOCALDATA",
Self::AppCache => "$APPCACHE",
Self::AppLog => "$APPLOG",
}
}
@ -116,9 +156,16 @@ impl BaseDirectory {
"$TEMPLATE" => Self::Template,
"$VIDEO" => Self::Video,
"$RESOURCE" => Self::Resource,
#[allow(deprecated)]
"$APP" => Self::App,
#[allow(deprecated)]
"$LOG" => Self::Log,
"$TEMP" => Self::Temp,
"$APPCONFIG" => Self::AppConfig,
"$APPDATA" => Self::AppData,
"$APPLOCALDATA" => Self::AppLocalData,
"$APPCACHE" => Self::AppCache,
"$APPLOG" => Self::AppLog,
_ => return None,
};
Some(res)
@ -192,7 +239,7 @@ pub fn parse<P: AsRef<Path>>(
/// context.package_info(),
/// &Env::default(),
/// "db/tauri.sqlite",
/// Some(BaseDirectory::App))
/// Some(BaseDirectory::AppData))
/// .expect("failed to resolve path");
/// assert_eq!(path.to_str().unwrap(), "/home/${whoami}/.config/com.tauri.app/db/tauri.sqlite");
///
@ -242,9 +289,16 @@ pub fn resolve_path<P: AsRef<Path>>(
BaseDirectory::Template => template_dir(),
BaseDirectory::Video => video_dir(),
BaseDirectory::Resource => resource_dir(package_info, env),
BaseDirectory::App => app_dir(config),
BaseDirectory::Log => log_dir(config),
#[allow(deprecated)]
BaseDirectory::App => app_config_dir(config),
#[allow(deprecated)]
BaseDirectory::Log => app_log_dir(config),
BaseDirectory::Temp => Some(temp_dir()),
BaseDirectory::AppConfig => app_config_dir(config),
BaseDirectory::AppData => app_data_dir(config),
BaseDirectory::AppLocalData => app_local_data_dir(config),
BaseDirectory::AppCache => app_cache_dir(config),
BaseDirectory::AppLog => app_log_dir(config),
};
if let Some(mut base_dir_path_value) = base_dir_path {
// use the same path resolution mechanism as the bundler's resource injection algorithm
@ -459,25 +513,52 @@ pub fn resource_dir(package_info: &PackageInfo, env: &Env) -> Option<PathBuf> {
crate::utils::platform::resource_dir(package_info, env).ok()
}
/// Returns the path to the suggested directory for your app config files.
/// Returns the path to the suggested directory for your app's config files.
///
/// Resolves to `${config_dir}/${bundle_identifier}`.
/// Resolves to [`config_dir`]`/${bundle_identifier}`.
///
/// See [`PathResolver::app_dir`](crate::PathResolver#method.app_dir) for a more convenient helper function.
pub fn app_dir(config: &Config) -> Option<PathBuf> {
/// See [`PathResolver::app_config_dir`](crate::PathResolver#method.app_config_dir) for a more convenient helper function.
pub fn app_config_dir(config: &Config) -> Option<PathBuf> {
dirs_next::config_dir().map(|dir| dir.join(&config.tauri.bundle.identifier))
}
/// Returns the path to the suggested log directory.
/// Returns the path to the suggested directory for your app's data files.
///
/// Resolves to [`data_dir`]`/${bundle_identifier}`.
///
/// See [`PathResolver::app_data_dir`](crate::PathResolver#method.app_data_dir) for a more convenient helper function.
pub fn app_data_dir(config: &Config) -> Option<PathBuf> {
dirs_next::data_dir().map(|dir| dir.join(&config.tauri.bundle.identifier))
}
/// Returns the path to the suggested directory for your app's local data files.
///
/// Resolves to [`local_data_dir`]`/${bundle_identifier}`.
///
/// See [`PathResolver::app_data_dir`](crate::PathResolver#method.app_data_dir) for a more convenient helper function.
pub fn app_local_data_dir(config: &Config) -> Option<PathBuf> {
dirs_next::data_local_dir().map(|dir| dir.join(&config.tauri.bundle.identifier))
}
/// Returns the path to the suggested directory for your app's cache files.
///
/// Resolves to [`cache_dir`]`/${bundle_identifier}`.
///
/// See [`PathResolver::app_cache_dir`](crate::PathResolver#method.app_cache_dir) for a more convenient helper function.
pub fn app_cache_dir(config: &Config) -> Option<PathBuf> {
dirs_next::cache_dir().map(|dir| dir.join(&config.tauri.bundle.identifier))
}
/// Returns the path to the suggested directory for your app's log files.
///
/// ## Platform-specific
///
/// - **Linux:** Resolves to `${config_dir}/${bundle_identifier}/logs`.
/// - **macOS:** Resolves to `${home_dir}//Library/Logs/{bundle_identifier}`
/// - **Windows:** Resolves to `${config_dir}/${bundle_identifier}/logs`.
/// - **Linux:** Resolves to [`config_dir`]`/${bundle_identifier}/logs`.
/// - **macOS:** Resolves to [`home_dir`]`/Library/Logs/${bundle_identifier}`
/// - **Windows:** Resolves to [`config_dir`]`/${bundle_identifier}/logs`.
///
/// See [`PathResolver::log_dir`](crate::PathResolver#method.log_dir) for a more convenient helper function.
pub fn log_dir(config: &Config) -> Option<PathBuf> {
/// See [`PathResolver::app_log_dir`](crate::PathResolver#method.app_log_dir) for a more convenient helper function.
pub fn app_log_dir(config: &Config) -> Option<PathBuf> {
#[cfg(target_os = "macos")]
let path = dirs_next::home_dir().map(|dir| {
dir
@ -491,3 +572,33 @@ pub fn log_dir(config: &Config) -> Option<PathBuf> {
path
}
/// Returns the path to the suggested directory for your app's config files.
///
/// Resolves to [`config_dir`]`/${bundle_identifier}`.
///
/// See [`PathResolver::app_config_dir`](crate::PathResolver#method.app_config_dir) for a more convenient helper function.
#[deprecated(
since = "1.2.0",
note = "Will be removed in 2.0.0. Use `app_config_dir` or `app_data_dir` instead."
)]
pub fn app_dir(config: &Config) -> Option<PathBuf> {
app_config_dir(config)
}
/// Returns the path to the suggested directory for your app's log files.
///
/// ## Platform-specific
///
/// - **Linux:** Resolves to [`config_dir`]`/${bundle_identifier}`.
/// - **macOS:** Resolves to [`home_dir`]`/Library/Logs/${bundle_identifier}`
/// - **Windows:** Resolves to [`config_dir`]`/${bundle_identifier}`.
///
/// See [`PathResolver::app_log_dir`](crate::PathResolver#method.app_log_dir) for a more convenient helper function.
#[deprecated(
since = "1.2.0",
note = "Will be removed in 2.0.0. Use `app_log_dir` instead."
)]
pub fn log_dir(config: &Config) -> Option<PathBuf> {
app_log_dir(config)
}

View File

@ -288,14 +288,47 @@ impl PathResolver {
.map(|dir| dir.join(resource_relpath(path.as_ref())))
}
/// Returns the path to the suggested directory for your app config files.
pub fn app_dir(&self) -> Option<PathBuf> {
crate::api::path::app_dir(&self.config)
/// Returns the path to the suggested directory for your app's config files.
pub fn app_config_dir(&self) -> Option<PathBuf> {
crate::api::path::app_config_dir(&self.config)
}
/// Returns the path to the suggested log directory.
/// Returns the path to the suggested directory for your app's data files.
pub fn app_data_dir(&self) -> Option<PathBuf> {
crate::api::path::app_data_dir(&self.config)
}
/// Returns the path to the suggested directory for your app's local data files.
pub fn app_local_data_dir(&self) -> Option<PathBuf> {
crate::api::path::app_local_data_dir(&self.config)
}
/// Returns the path to the suggested directory for your app's cache files.
pub fn app_cache_dir(&self) -> Option<PathBuf> {
crate::api::path::app_cache_dir(&self.config)
}
/// Returns the path to the suggested directory for your app's log files.
pub fn app_log_dir(&self) -> Option<PathBuf> {
crate::api::path::app_log_dir(&self.config)
}
/// Returns the path to the suggested directory for your app's config files.
#[deprecated(
since = "1.2.0",
note = "Will be removed in 2.0.0. Use `app_config_dir` or `app_data_dir` instead."
)]
pub fn app_dir(&self) -> Option<PathBuf> {
self.app_config_dir()
}
/// Returns the path to the suggested directory for your app's log files.
#[deprecated(
since = "1.2.0",
note = "Will be removed in 2.0.0. Use `app_log_dir` instead."
)]
pub fn log_dir(&self) -> Option<PathBuf> {
crate::api::path::log_dir(&self.config)
self.app_log_dir()
}
}

View File

@ -399,7 +399,7 @@ mod tests {
impl Arbitrary for BaseDirectory {
fn arbitrary(g: &mut Gen) -> Self {
if bool::arbitrary(g) {
BaseDirectory::App
BaseDirectory::AppData
} else {
BaseDirectory::Resource
}

View File

@ -87,8 +87,8 @@
"all": true,
"fs": {
"scope": {
"allow": ["$APP/db/**", "$DOWNLOAD/**", "$RESOURCE/**"],
"deny": ["$APP/db/*.stronghold"]
"allow": ["$APPDATA/db/**", "$DOWNLOAD/**", "$RESOURCE/**"],
"deny": ["$APPDATA/db/*.stronghold"]
}
},
"shell": {
@ -109,8 +109,8 @@
"protocol": {
"asset": true,
"assetScope": {
"allow": ["$APP/db/**", "$RESOURCE/**"],
"deny": ["$APP/db/*.stronghold"]
"allow": ["$APPDATA/db/**", "$RESOURCE/**"],
"deny": ["$APPDATA/db/*.stronghold"]
}
},
"http": {

View File

@ -41,21 +41,23 @@
*
* The scope configuration is an array of glob patterns describing folder paths that are allowed.
* For instance, this scope configuration only allows accessing files on the
* *databases* folder of the {@link path.appDir | $APP directory}:
* *databases* folder of the {@link path.appDataDir | $APPDATA directory}:
* ```json
* {
* "tauri": {
* "allowlist": {
* "fs": {
* "scope": ["$APP/databases/*"]
* "scope": ["$APPDATA/databases/*"]
* }
* }
* }
* }
* ```
*
* Notice the use of the `$APP` variable. The value is injected at runtime, resolving to the {@link path.appDir | app directory}.
* Notice the use of the `$APPDATA` variable. The value is injected at runtime, resolving to the {@link path.appDataDir | app data directory}.
* The available variables are:
* {@link path.appConfigDir | `$APPCONFIG`}, {@link path.appDataDir | `$APPDATA`}, {@link path.appLocalDataDir | `$APPLOCALDATA`},
* {@link path.appCacheDir | `$APPCACHE`}, {@link path.appLogDir | `$APPLOG`},
* {@link path.audioDir | `$AUDIO`}, {@link path.cacheDir | `$CACHE`}, {@link path.configDir | `$CONFIG`}, {@link path.dataDir | `$DATA`},
* {@link path.localDataDir | `$LOCALDATA`}, {@link path.desktopDir | `$DESKTOP`}, {@link path.documentDir | `$DOCUMENT`},
* {@link path.downloadDir | `$DOWNLOAD`}, {@link path.executableDir | `$EXE`}, {@link path.fontDir | `$FONT`}, {@link path.homeDir | `$HOME`},
@ -95,7 +97,12 @@ export enum BaseDirectory {
Resource,
App,
Log,
Temp
Temp,
AppConfig,
AppData,
AppLocalData,
AppCache,
AppLog
}
/**
@ -159,8 +166,8 @@ interface FileEntry {
* @example
* ```typescript
* import { readTextFile, BaseDirectory } from '@tauri-apps/api/fs';
* // Read the text file in the `$APPDIR/app.conf` path
* const contents = await readTextFile('app.conf', { dir: BaseDirectory.App });
* // Read the text file in the `$APPCONFIG/app.conf` path
* const contents = await readTextFile('app.conf', { dir: BaseDirectory.AppConfig });
* ```
*
* @since 1.0.0
@ -211,8 +218,8 @@ async function readBinaryFile(
* @example
* ```typescript
* import { writeTextFile, BaseDirectory } from '@tauri-apps/api/fs';
* // Write a text file to the `$APPDIR/app.conf` path
* await writeTextFile('app.conf', 'file contents', { dir: BaseDirectory.App });
* // Write a text file to the `$APPCONFIG/app.conf` path
* await writeTextFile('app.conf', 'file contents', { dir: BaseDirectory.AppConfig });
* ```
*
* @since 1.0.0
@ -228,8 +235,8 @@ async function writeTextFile(
* @example
* ```typescript
* import { writeTextFile, BaseDirectory } from '@tauri-apps/api/fs';
* // Write a text file to the `$APPDIR/app.conf` path
* await writeTextFile({ path: 'app.conf', contents: 'file contents' }, { dir: BaseDirectory.App });
* // Write a text file to the `$APPCONFIG/app.conf` path
* await writeTextFile({ path: 'app.conf', contents: 'file contents' }, { dir: BaseDirectory.AppConfig });
* ```
* @returns A promise indicating the success or failure of the operation.
*
@ -290,8 +297,8 @@ async function writeTextFile(
* @example
* ```typescript
* import { writeBinaryFile, BaseDirectory } from '@tauri-apps/api/fs';
* // Write a binary file to the `$APPDIR/avatar.png` path
* await writeBinaryFile('avatar.png', new Uint8Array([]), { dir: BaseDirectory.App });
* // Write a binary file to the `$APPDATA/avatar.png` path
* await writeBinaryFile('avatar.png', new Uint8Array([]), { dir: BaseDirectory.AppData });
* ```
*
* @param options Configuration object.
@ -310,8 +317,8 @@ async function writeBinaryFile(
* @example
* ```typescript
* import { writeBinaryFile, BaseDirectory } from '@tauri-apps/api/fs';
* // Write a binary file to the `$APPDIR/avatar.png` path
* await writeBinaryFile({ path: 'avatar.png', contents: new Uint8Array([]) }, { dir: BaseDirectory.App });
* // Write a binary file to the `$APPDATA/avatar.png` path
* await writeBinaryFile({ path: 'avatar.png', contents: new Uint8Array([]) }, { dir: BaseDirectory.AppData });
* ```
*
* @param file The object containing the file path and contents.
@ -380,8 +387,8 @@ async function writeBinaryFile(
* @example
* ```typescript
* import { readDir, BaseDirectory } from '@tauri-apps/api/fs';
* // Reads the `$APPDIR/users` directory recursively
* const entries = await readDir('users', { dir: BaseDirectory.App, recursive: true });
* // Reads the `$APPDATA/users` directory recursively
* const entries = await readDir('users', { dir: BaseDirectory.AppData, recursive: true });
*
* function processEntries(entries) {
* for (const entry of entries) {
@ -416,8 +423,8 @@ async function readDir(
* @example
* ```typescript
* import { createDir, BaseDirectory } from '@tauri-apps/api/fs';
* // Create the `$APPDIR/users` directory
* await createDir('users', { dir: BaseDirectory.App, recursive: true });
* // Create the `$APPDATA/users` directory
* await createDir('users', { dir: BaseDirectory.AppData, recursive: true });
* ```
*
* @returns A promise indicating the success or failure of the operation.
@ -444,8 +451,8 @@ async function createDir(
* @example
* ```typescript
* import { removeDir, BaseDirectory } from '@tauri-apps/api/fs';
* // Remove the directory `$APPDIR/users`
* await removeDir('users', { dir: BaseDirectory.App });
* // Remove the directory `$APPDATA/users`
* await removeDir('users', { dir: BaseDirectory.AppData });
* ```
*
* @returns A promise indicating the success or failure of the operation.
@ -471,8 +478,8 @@ async function removeDir(
* @example
* ```typescript
* import { copyFile, BaseDirectory } from '@tauri-apps/api/fs';
* // Copy the `$APPDIR/app.conf` file to `$APPDIR/app.conf.bk`
* await copyFile('app.conf', 'app.conf.bk', { dir: BaseDirectory.App });
* // Copy the `$APPCONFIG/app.conf` file to `$APPCONFIG/app.conf.bk`
* await copyFile('app.conf', 'app.conf.bk', { dir: BaseDirectory.AppConfig });
* ```
*
* @returns A promise indicating the success or failure of the operation.
@ -500,8 +507,8 @@ async function copyFile(
* @example
* ```typescript
* import { removeFile, BaseDirectory } from '@tauri-apps/api/fs';
* // Remove the `$APPDIR/app.conf` file
* await removeFile('app.conf', { dir: BaseDirectory.App });
* // Remove the `$APPConfig/app.conf` file
* await removeFile('app.conf', { dir: BaseDirectory.AppConfig });
* ```
*
* @returns A promise indicating the success or failure of the operation.
@ -527,8 +534,8 @@ async function removeFile(
* @example
* ```typescript
* import { renameFile, BaseDirectory } from '@tauri-apps/api/fs';
* // Rename the `$APPDIR/avatar.png` file
* await renameFile('avatar.png', 'deleted.png', { dir: BaseDirectory.App });
* // Rename the `$APPDATA/avatar.png` file
* await renameFile('avatar.png', 'deleted.png', { dir: BaseDirectory.AppData });
* ```
*
* @returns A promise indicating the success or failure of the operation.
@ -556,8 +563,8 @@ async function renameFile(
* @example
* ```typescript
* import { exists, BaseDirectory } from '@tauri-apps/api/fs';
* // Check if the `$APPDIR/avatar.png` file exists
* await exists('avatar.png', { dir: BaseDirectory.App });
* // Check if the `$APPDATA/avatar.png` file exists
* await exists('avatar.png', { dir: BaseDirectory.AppData });
* ```
*
* @since 1.1.0

View File

@ -29,22 +29,98 @@ import { isWindows } from './helpers/os-check'
/**
* Returns the path to the suggested directory for your app config files.
* Resolves to `${configDir}/${bundleIdentifier}`, where `bundleIdentifier` is the value [`tauri.bundle.identifier`](https://tauri.app/v1/api/config/#bundleconfig.identifier) is configured in `tauri.conf.json`.
* @example
* ```typescript
* import { appDir } from '@tauri-apps/api/path';
* const appDirPath = await appDir();
* ```
*
* @deprecated since 1.2.0: Will be removed in 2.0.0. Use {@link appConfigDir} or {@link appDataDir} instead.
* @since 1.0.0
*/
async function appDir(): Promise<string> {
return appConfigDir()
}
/**
* Returns the path to the suggested directory for your app's config files.
* Resolves to `${configDir}/${bundleIdentifier}`, where `bundleIdentifier` is the value [`tauri.bundle.identifier`](https://tauri.app/v1/api/config/#bundleconfig.identifier) is configured in `tauri.conf.json`.
* @example
* ```typescript
* import { appConfigDir } from '@tauri-apps/api/path';
* const appConfigDirPath = await appConfigDir();
* ```
*
* @since 1.2.0
*/
async function appConfigDir(): Promise<string> {
return invokeTauriCommand<string>({
__tauriModule: 'Path',
message: {
cmd: 'resolvePath',
path: '',
directory: BaseDirectory.App
directory: BaseDirectory.AppConfig
}
})
}
/**
* Returns the path to the suggested directory for your app's data files.
* Resolves to `${dataDir}/${bundleIdentifier}`, where `bundleIdentifier` is the value [`tauri.bundle.identifier`](https://tauri.app/v1/api/config/#bundleconfig.identifier) is configured in `tauri.conf.json`.
* @example
* ```typescript
* import { appDataDir } from '@tauri-apps/api/path';
* const appDataDirPath = await appDataDir();
* ```
*
* @since 1.2.0
*/
async function appDataDir(): Promise<string> {
return invokeTauriCommand<string>({
__tauriModule: 'Path',
message: {
cmd: 'resolvePath',
path: '',
directory: BaseDirectory.AppData
}
})
}
/**
* Returns the path to the suggested directory for your app's local data files.
* Resolves to `${localDataDir}/${bundleIdentifier}`, where `bundleIdentifier` is the value [`tauri.bundle.identifier`](https://tauri.app/v1/api/config/#bundleconfig.identifier) is configured in `tauri.conf.json`.
* @example
* ```typescript
* import { appLocalDataDir } from '@tauri-apps/api/path';
* const appLocalDataDirPath = await appLocalDataDir();
* ```
*
* @since 1.2.0
*/
async function appLocalDataDir(): Promise<string> {
return invokeTauriCommand<string>({
__tauriModule: 'Path',
message: {
cmd: 'resolvePath',
path: '',
directory: BaseDirectory.AppLocalData
}
})
}
/**
* Returns the path to the suggested directory for your app's cache files.
* Resolves to `${cacheDir}/${bundleIdentifier}`, where `bundleIdentifier` is the value [`tauri.bundle.identifier`](https://tauri.app/v1/api/config/#bundleconfig.identifier) is configured in `tauri.conf.json`.
* @example
* ```typescript
* import { appCacheDir } from '@tauri-apps/api/path';
* const appCacheDirPath = await appCacheDir();
* ```
*
* @since 1.2.0
*/
async function appCacheDir(): Promise<string> {
return invokeTauriCommand<string>({
__tauriModule: 'Path',
message: {
cmd: 'resolvePath',
path: '',
directory: BaseDirectory.AppCache
}
})
}
@ -531,6 +607,16 @@ async function videoDir(): Promise<string> {
/**
* Returns the path to the suggested log directory.
*
* @deprecated since 1.2.0: Will be removed in 2.0.0. Use {@link appLogDir} instead.
* @since 1.0.0
*/
async function logDir(): Promise<string> {
return appLogDir()
}
/**
* Returns the path to the suggested directory for your app's log files.
*
* #### Platform-specific
*
* - **Linux:** Resolves to `${configDir}/${bundleIdentifier}/logs`.
@ -538,19 +624,19 @@ async function videoDir(): Promise<string> {
* - **Windows:** Resolves to `${configDir}/${bundleIdentifier}/logs`.
* @example
* ```typescript
* import { logDir } from '@tauri-apps/api/path';
* const logDirPath = await logDir();
* import { appLogDir } from '@tauri-apps/api/path';
* const appLogDirPath = await appLogDir();
* ```
*
* @since 1.0.0
* @since 1.2.0
*/
async function logDir(): Promise<string> {
async function appLogDir(): Promise<string> {
return invokeTauriCommand<string>({
__tauriModule: 'Path',
message: {
cmd: 'resolvePath',
path: '',
directory: BaseDirectory.Log
directory: BaseDirectory.AppLog
}
})
}
@ -577,9 +663,9 @@ const delimiter = isWindows() ? ';' : ':'
* Resolves a sequence of `paths` or `path` segments into an absolute path.
* @example
* ```typescript
* import { resolve, appDir } from '@tauri-apps/api/path';
* const appDirPath = await appDir();
* const path = await resolve(appDirPath, '..', 'users', 'tauri', 'avatar.png');
* import { resolve, appDataDir } from '@tauri-apps/api/path';
* const appDataDirPath = await appDataDir();
* const path = await resolve(appDataDirPath, '..', 'users', 'tauri', 'avatar.png');
* ```
*
* @since 1.0.0
@ -598,9 +684,9 @@ async function resolve(...paths: string[]): Promise<string> {
* Normalizes the given `path`, resolving `'..'` and `'.'` segments and resolve symbolic links.
* @example
* ```typescript
* import { normalize, appDir } from '@tauri-apps/api/path';
* const appDirPath = await appDir();
* const path = await normalize(appDirPath, '..', 'users', 'tauri', 'avatar.png');
* import { normalize, appDataDir } from '@tauri-apps/api/path';
* const appDataDirPath = await appDataDir();
* const path = await normalize(appDataDirPath, '..', 'users', 'tauri', 'avatar.png');
* ```
*
* @since 1.0.0
@ -619,9 +705,9 @@ async function normalize(path: string): Promise<string> {
* Joins all given `path` segments together using the platform-specific separator as a delimiter, then normalizes the resulting path.
* @example
* ```typescript
* import { join, appDir } from '@tauri-apps/api/path';
* const appDirPath = await appDir();
* const path = await join(appDirPath, 'users', 'tauri', 'avatar.png');
* import { join, appDataDir } from '@tauri-apps/api/path';
* const appDataDirPath = await appDataDir();
* const path = await join(appDataDirPath, 'users', 'tauri', 'avatar.png');
* ```
*
* @since 1.0.0
@ -640,9 +726,9 @@ async function join(...paths: string[]): Promise<string> {
* Returns the directory name of a `path`. Trailing directory separators are ignored.
* @example
* ```typescript
* import { dirname, appDir } from '@tauri-apps/api/path';
* const appDirPath = await appDir();
* const dir = await dirname(appDirPath);
* import { dirname, appDataDir } from '@tauri-apps/api/path';
* const appDataDirPath = await appDataDir();
* const dir = await dirname(appDataDirPath);
* ```
*
* @since 1.0.0
@ -726,6 +812,11 @@ async function isAbsolute(path: string): Promise<boolean> {
export {
appDir,
appConfigDir,
appDataDir,
appLocalDataDir,
appCacheDir,
appLogDir,
audioDir,
cacheDir,
configDir,

View File

@ -110,10 +110,10 @@ async function invoke<T>(cmd: string, args: InvokeArgs = {}): Promise<T> {
* @param protocol The protocol to use. Defaults to `asset`. You only need to set this when using a custom protocol.
* @example
* ```typescript
* import { appDir, join } from '@tauri-apps/api/path';
* import { appDataDir, join } from '@tauri-apps/api/path';
* import { convertFileSrc } from '@tauri-apps/api/tauri';
* const appDirPath = await appDir();
* const filePath = await join(appDir, 'assets/video.mp4');
* const appDataDirPath = await appDataDir();
* const filePath = await join(appDataDirPath, 'assets/video.mp4');
* const assetUrl = convertFileSrc(filePath);
*
* const video = document.getElementById('my-video');

View File

@ -1771,7 +1771,7 @@
"additionalProperties": false
},
"FsAllowlistScope": {
"description": "Filesystem scope definition. It is a list of glob patterns that restrict the API access from the webview.\n\nEach pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`.",
"description": "Filesystem scope definition. It is a list of glob patterns that restrict the API access from the webview.\n\nEach pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
"anyOf": [
{
"description": "A list of paths that are allowed by this scope.",
@ -2020,7 +2020,7 @@
"type": "string"
},
"cmd": {
"description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`.",
"description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
"default": "",
"type": "string"
},