Explorar el Código

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>
Caesar Schinas hace 2 años
padre
commit
5d89905e39

+ 6 - 0
.changes/app-dirs-api.md

@@ -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.

+ 4 - 2
core/tauri-utils/src/config.rs

@@ -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,
 

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
core/tauri/scripts/bundle.js


+ 178 - 67
core/tauri/src/api/path.rs

@@ -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)
+}

+ 37 - 4
core/tauri/src/app.rs

@@ -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.
+  /// 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 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> {
-    crate::api::path::app_dir(&self.config)
+    self.app_config_dir()
   }
 
-  /// Returns the path to the suggested log directory.
+  /// 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()
   }
 }
 

+ 1 - 1
core/tauri/src/endpoints/file_system.rs

@@ -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
       }

+ 4 - 4
examples/api/src-tauri/tauri.conf.json

@@ -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": {

+ 35 - 28
tooling/api/src/fs.ts

@@ -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

+ 113 - 22
tooling/api/src/path.ts

@@ -29,22 +29,98 @@ import { isWindows } from './helpers/os-check'
 
 /**
  * Returns the path to the suggested directory for your app config files.
+ *
+ * @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 { appDir } from '@tauri-apps/api/path';
- * const appDirPath = await appDir();
+ * import { appConfigDir } from '@tauri-apps/api/path';
+ * const appConfigDirPath = await appConfigDir();
  * ```
  *
- * @since 1.0.0
+ * @since 1.2.0
  */
-async function appDir(): Promise<string> {
+async function appConfigDir(): Promise<string> {
+  return invokeTauriCommand<string>({
+    __tauriModule: 'Path',
+    message: {
+      cmd: 'resolvePath',
+      path: '',
+      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.App
+      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,

+ 3 - 3
tooling/api/src/tauri.ts

@@ -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');

+ 2 - 2
tooling/cli/schema.json

@@ -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"
         },

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio