mirror of https://github.com/tauri-apps/tauri
feat(api.js): add nodejs-inspired functions in `path` module (#2310)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
parent
1a51006673
commit
05b9d81ee6
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
"api": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
- Add new nodejs-inspired functions which are `join`, `resolve`, `normalize`, `dirname`, `basename` and `extname`.
|
||||||
|
- Add `sep` and `delimiter` constants.
|
||||||
|
- Removed `resolvePath` API, use `resolve` instead.
|
|
@ -100,7 +100,8 @@ api-all = [
|
||||||
"shell-all",
|
"shell-all",
|
||||||
"os-all",
|
"os-all",
|
||||||
"dialog-all",
|
"dialog-all",
|
||||||
"updater"
|
"updater",
|
||||||
|
"path-all"
|
||||||
]
|
]
|
||||||
updater = [ "minisign-verify", "base64" ]
|
updater = [ "minisign-verify", "base64" ]
|
||||||
menu = [ "tauri-runtime/menu", "tauri-runtime-wry/menu" ]
|
menu = [ "tauri-runtime/menu", "tauri-runtime-wry/menu" ]
|
||||||
|
@ -117,7 +118,7 @@ fs-create-dir = [ ]
|
||||||
fs-remove-dir = [ ]
|
fs-remove-dir = [ ]
|
||||||
fs-remove-file = [ ]
|
fs-remove-file = [ ]
|
||||||
fs-rename-file = [ ]
|
fs-rename-file = [ ]
|
||||||
fs-path = [ ]
|
path-all = [ ]
|
||||||
window-all = [ ]
|
window-all = [ ]
|
||||||
window-create = [ ]
|
window-create = [ ]
|
||||||
shell-all = [ "shell-open", "shell-execute" ]
|
shell-all = [ "shell-open", "shell-execute" ]
|
||||||
|
|
|
@ -23,7 +23,6 @@ fn main() {
|
||||||
fs_remove_dir: { any(fs_all, feature = "fs-remove-dir") },
|
fs_remove_dir: { any(fs_all, feature = "fs-remove-dir") },
|
||||||
fs_remove_file: { any(fs_all, feature = "fs-remove-file") },
|
fs_remove_file: { any(fs_all, feature = "fs-remove-file") },
|
||||||
fs_rename_file: { any(fs_all, feature = "fs-rename-file") },
|
fs_rename_file: { any(fs_all, feature = "fs-rename-file") },
|
||||||
fs_path: { any(fs_all, feature = "fs-path") },
|
|
||||||
|
|
||||||
// window
|
// window
|
||||||
window_all: { any(api_all, feature = "window-all") },
|
window_all: { any(api_all, feature = "window-all") },
|
||||||
|
@ -54,5 +53,8 @@ fn main() {
|
||||||
|
|
||||||
// os
|
// os
|
||||||
os_all: { any(api_all, feature = "os-all") },
|
os_all: { any(api_all, feature = "os-all") },
|
||||||
|
|
||||||
|
// path
|
||||||
|
path_all: { any(api_all, feature = "path-all") },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -25,6 +25,7 @@ mod http;
|
||||||
mod internal;
|
mod internal;
|
||||||
mod notification;
|
mod notification;
|
||||||
mod operating_system;
|
mod operating_system;
|
||||||
|
mod path;
|
||||||
mod process;
|
mod process;
|
||||||
mod shell;
|
mod shell;
|
||||||
mod window;
|
mod window;
|
||||||
|
@ -49,6 +50,7 @@ enum Module {
|
||||||
Process(process::Cmd),
|
Process(process::Cmd),
|
||||||
Fs(file_system::Cmd),
|
Fs(file_system::Cmd),
|
||||||
Os(operating_system::Cmd),
|
Os(operating_system::Cmd),
|
||||||
|
Path(path::Cmd),
|
||||||
Window(Box<window::Cmd>),
|
Window(Box<window::Cmd>),
|
||||||
Shell(shell::Cmd),
|
Shell(shell::Cmd),
|
||||||
Event(event::Cmd),
|
Event(event::Cmd),
|
||||||
|
@ -84,6 +86,12 @@ impl Module {
|
||||||
.and_then(|r| r.json)
|
.and_then(|r| r.json)
|
||||||
.map_err(InvokeError::from)
|
.map_err(InvokeError::from)
|
||||||
}),
|
}),
|
||||||
|
Self::Path(cmd) => resolver.respond_async(async move {
|
||||||
|
cmd
|
||||||
|
.run(config, &package_info)
|
||||||
|
.and_then(|r| r.json)
|
||||||
|
.map_err(InvokeError::from)
|
||||||
|
}),
|
||||||
Self::Os(cmd) => resolver
|
Self::Os(cmd) => resolver
|
||||||
.respond_async(async move { cmd.run().and_then(|r| r.json).map_err(InvokeError::from) }),
|
.respond_async(async move { cmd.run().and_then(|r| r.json).map_err(InvokeError::from) }),
|
||||||
Self::Window(cmd) => resolver.respond_async(async move {
|
Self::Window(cmd) => resolver.respond_async(async move {
|
||||||
|
|
|
@ -93,11 +93,6 @@ pub enum Cmd {
|
||||||
new_path: PathBuf,
|
new_path: PathBuf,
|
||||||
options: Option<FileOperationOptions>,
|
options: Option<FileOperationOptions>,
|
||||||
},
|
},
|
||||||
/// The resolve path API
|
|
||||||
ResolvePath {
|
|
||||||
path: String,
|
|
||||||
directory: Option<BaseDirectory>,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cmd {
|
impl Cmd {
|
||||||
|
@ -201,13 +196,6 @@ impl Cmd {
|
||||||
Self::RenameFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
Self::RenameFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
||||||
"fs > renameFile".to_string(),
|
"fs > renameFile".to_string(),
|
||||||
)),
|
)),
|
||||||
|
|
||||||
#[cfg(fs_path)]
|
|
||||||
Self::ResolvePath { path, directory } => {
|
|
||||||
resolve_path_handler(&config, package_info, path, directory).map(Into::into)
|
|
||||||
}
|
|
||||||
#[cfg(not(fs_path))]
|
|
||||||
Self::ResolvePath { .. } => Err(crate::Error::ApiNotAllowlisted("fs > path".to_string())),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -405,16 +393,6 @@ pub fn read_binary_file(
|
||||||
.map_err(crate::Error::FailedToExecuteApi)
|
.map_err(crate::Error::FailedToExecuteApi)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(fs_path)]
|
|
||||||
pub fn resolve_path_handler(
|
|
||||||
config: &Config,
|
|
||||||
package_info: &PackageInfo,
|
|
||||||
path: String,
|
|
||||||
directory: Option<BaseDirectory>,
|
|
||||||
) -> crate::Result<PathBuf> {
|
|
||||||
resolve_path(config, package_info, path, directory).map_err(Into::into)
|
|
||||||
}
|
|
||||||
|
|
||||||
// test webview functionality.
|
// test webview functionality.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|
|
@ -0,0 +1,156 @@
|
||||||
|
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
use super::InvokeResponse;
|
||||||
|
use crate::{api::path::BaseDirectory, Config, PackageInfo};
|
||||||
|
use serde::Deserialize;
|
||||||
|
#[cfg(path_all)]
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::Arc;
|
||||||
|
/// The API descriptor.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(tag = "cmd", rename_all = "camelCase")]
|
||||||
|
pub enum Cmd {
|
||||||
|
ResolvePath {
|
||||||
|
path: String,
|
||||||
|
directory: Option<BaseDirectory>,
|
||||||
|
},
|
||||||
|
Resolve {
|
||||||
|
paths: Vec<String>,
|
||||||
|
},
|
||||||
|
Normalize {
|
||||||
|
path: String,
|
||||||
|
},
|
||||||
|
Join {
|
||||||
|
paths: Vec<String>,
|
||||||
|
},
|
||||||
|
Dirname {
|
||||||
|
path: String,
|
||||||
|
},
|
||||||
|
Extname {
|
||||||
|
path: String,
|
||||||
|
},
|
||||||
|
Basename {
|
||||||
|
path: String,
|
||||||
|
ext: Option<String>,
|
||||||
|
},
|
||||||
|
IsAbsolute {
|
||||||
|
path: String,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cmd {
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
pub fn run(
|
||||||
|
self,
|
||||||
|
config: Arc<Config>,
|
||||||
|
package_info: &PackageInfo,
|
||||||
|
) -> crate::Result<InvokeResponse> {
|
||||||
|
#[cfg(path_all)]
|
||||||
|
return match self {
|
||||||
|
Cmd::ResolvePath { directory, path } => {
|
||||||
|
resolve_path_handler(&config, package_info, path, directory).map(Into::into)
|
||||||
|
}
|
||||||
|
Cmd::Resolve { paths } => resolve(paths).map(Into::into),
|
||||||
|
Cmd::Normalize { path } => normalize(path).map(Into::into),
|
||||||
|
Cmd::Join { paths } => join(paths).map(Into::into),
|
||||||
|
Cmd::Dirname { path } => dirname(path).map(Into::into),
|
||||||
|
Cmd::Extname { path } => extname(path).map(Into::into),
|
||||||
|
Cmd::Basename { path, ext } => basename(path, ext).map(Into::into),
|
||||||
|
Cmd::IsAbsolute { path } => Ok(Path::new(&path).is_absolute()).map(Into::into),
|
||||||
|
};
|
||||||
|
#[cfg(not(path_all))]
|
||||||
|
Err(crate::Error::ApiNotAllowlisted("path".into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(path_all)]
|
||||||
|
pub fn resolve_path_handler(
|
||||||
|
config: &Config,
|
||||||
|
package_info: &PackageInfo,
|
||||||
|
path: String,
|
||||||
|
directory: Option<BaseDirectory>,
|
||||||
|
) -> crate::Result<PathBuf> {
|
||||||
|
crate::api::path::resolve_path(config, package_info, path, directory).map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(path_all)]
|
||||||
|
fn resolve(paths: Vec<String>) -> crate::Result<String> {
|
||||||
|
// start with the current directory
|
||||||
|
let mut resolved_path = PathBuf::new().join(".");
|
||||||
|
|
||||||
|
for path in paths {
|
||||||
|
let path_buf = PathBuf::from(path);
|
||||||
|
|
||||||
|
// if we encounter an absolute path, we use it as the starting path for next iteration
|
||||||
|
if path_buf.is_absolute() {
|
||||||
|
resolved_path = path_buf;
|
||||||
|
} else {
|
||||||
|
resolved_path = resolved_path.join(&path_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
normalize(resolved_path.to_string_lossy().to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(path_all)]
|
||||||
|
fn normalize(path: String) -> crate::Result<String> {
|
||||||
|
let path = std::fs::canonicalize(path)?;
|
||||||
|
let path = path.to_string_lossy().to_string();
|
||||||
|
|
||||||
|
// remove `\\\\?\\` on windows, UNC path
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
let path = path.replace("\\\\?\\", "");
|
||||||
|
|
||||||
|
Ok(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(path_all)]
|
||||||
|
fn join(paths: Vec<String>) -> crate::Result<String> {
|
||||||
|
let mut joined_path = PathBuf::new();
|
||||||
|
for path in paths {
|
||||||
|
joined_path = joined_path.join(path);
|
||||||
|
}
|
||||||
|
normalize(joined_path.to_string_lossy().to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(path_all)]
|
||||||
|
fn dirname(path: String) -> crate::Result<String> {
|
||||||
|
match Path::new(&path).parent() {
|
||||||
|
Some(path) => Ok(path.to_string_lossy().to_string()),
|
||||||
|
None => Err(crate::Error::FailedToExecuteApi(crate::api::Error::Path(
|
||||||
|
"Couldn't get the parent directory".into(),
|
||||||
|
))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(path_all)]
|
||||||
|
fn extname(path: String) -> crate::Result<String> {
|
||||||
|
match Path::new(&path)
|
||||||
|
.extension()
|
||||||
|
.and_then(std::ffi::OsStr::to_str)
|
||||||
|
{
|
||||||
|
Some(path) => Ok(path.to_string()),
|
||||||
|
None => Err(crate::Error::FailedToExecuteApi(crate::api::Error::Path(
|
||||||
|
"Couldn't get the extension of the file".into(),
|
||||||
|
))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(path_all)]
|
||||||
|
fn basename(path: String, ext: Option<String>) -> crate::Result<String> {
|
||||||
|
match Path::new(&path)
|
||||||
|
.file_name()
|
||||||
|
.and_then(std::ffi::OsStr::to_str)
|
||||||
|
{
|
||||||
|
Some(path) => Ok(if let Some(ext) = ext {
|
||||||
|
path.replace(ext.as_str(), "")
|
||||||
|
} else {
|
||||||
|
path.to_string()
|
||||||
|
}),
|
||||||
|
None => Err(crate::Error::FailedToExecuteApi(crate::api::Error::Path(
|
||||||
|
"Couldn't get the basename".into(),
|
||||||
|
))),
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import { invoke } from '../tauri'
|
||||||
type TauriModule =
|
type TauriModule =
|
||||||
| 'App'
|
| 'App'
|
||||||
| 'Fs'
|
| 'Fs'
|
||||||
|
| 'Path'
|
||||||
| 'Os'
|
| 'Os'
|
||||||
| 'Window'
|
| 'Window'
|
||||||
| 'Shell'
|
| 'Shell'
|
||||||
|
|
|
@ -4,9 +4,10 @@
|
||||||
|
|
||||||
import { invokeTauriCommand } from './helpers/tauri'
|
import { invokeTauriCommand } from './helpers/tauri'
|
||||||
import { BaseDirectory } from './fs'
|
import { BaseDirectory } from './fs'
|
||||||
|
import { isWindows } from './helpers/os-check'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read common system paths such as home, config and cache directories.
|
* The path module provides utilities for working with file and directory paths.
|
||||||
*
|
*
|
||||||
* This package is also accessible with `window.__TAURI__.path` when `tauri.conf.json > build > withGlobalTauri` is set to true.
|
* This package is also accessible with `window.__TAURI__.path` when `tauri.conf.json > build > withGlobalTauri` is set to true.
|
||||||
*
|
*
|
||||||
|
@ -15,9 +16,8 @@ import { BaseDirectory } from './fs'
|
||||||
* {
|
* {
|
||||||
* "tauri": {
|
* "tauri": {
|
||||||
* "allowlist": {
|
* "allowlist": {
|
||||||
* "fs": {
|
* "path": {
|
||||||
* "all": true, // enable all FS APIs
|
* "all": true, // enable all Path APIs
|
||||||
* "path": true // enable path APIs
|
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
@ -35,7 +35,7 @@ import { BaseDirectory } from './fs'
|
||||||
*/
|
*/
|
||||||
async function appDir(): Promise<string> {
|
async function appDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -57,7 +57,7 @@ async function appDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function audioDir(): Promise<string> {
|
async function audioDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -79,7 +79,7 @@ async function audioDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function cacheDir(): Promise<string> {
|
async function cacheDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -101,7 +101,7 @@ async function cacheDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function configDir(): Promise<string> {
|
async function configDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -123,7 +123,7 @@ async function configDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function dataDir(): Promise<string> {
|
async function dataDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -145,7 +145,7 @@ async function dataDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function desktopDir(): Promise<string> {
|
async function desktopDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -167,7 +167,7 @@ async function desktopDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function documentDir(): Promise<string> {
|
async function documentDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -189,7 +189,7 @@ async function documentDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function downloadDir(): Promise<string> {
|
async function downloadDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -211,7 +211,7 @@ async function downloadDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function executableDir(): Promise<string> {
|
async function executableDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -233,7 +233,7 @@ async function executableDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function fontDir(): Promise<string> {
|
async function fontDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -255,7 +255,7 @@ async function fontDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function homeDir(): Promise<string> {
|
async function homeDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -277,7 +277,7 @@ async function homeDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function localDataDir(): Promise<string> {
|
async function localDataDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -299,7 +299,7 @@ async function localDataDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function pictureDir(): Promise<string> {
|
async function pictureDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -321,7 +321,7 @@ async function pictureDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function publicDir(): Promise<string> {
|
async function publicDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -337,7 +337,7 @@ async function publicDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function resourceDir(): Promise<string> {
|
async function resourceDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -359,7 +359,7 @@ async function resourceDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function runtimeDir(): Promise<string> {
|
async function runtimeDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -381,7 +381,7 @@ async function runtimeDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function templateDir(): Promise<string> {
|
async function templateDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -403,7 +403,7 @@ async function templateDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function videoDir(): Promise<string> {
|
async function videoDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -419,7 +419,7 @@ async function videoDir(): Promise<string> {
|
||||||
*/
|
*/
|
||||||
async function currentDir(): Promise<string> {
|
async function currentDir(): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolvePath',
|
||||||
path: '',
|
path: '',
|
||||||
|
@ -429,22 +429,110 @@ async function currentDir(): Promise<string> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the path with the optional base directory.
|
* Provides the platform-specific path segment separator:
|
||||||
*
|
* - `\` on Windows
|
||||||
* @param path A path to resolve
|
* - `/` on POSIX
|
||||||
* @param directory A base directory to use when resolving the given path
|
|
||||||
* @returns A path resolved to the given base directory.
|
|
||||||
*/
|
*/
|
||||||
async function resolvePath(
|
const sep = isWindows() ? '\\' : '/'
|
||||||
path: string,
|
|
||||||
directory: BaseDirectory
|
/**
|
||||||
): Promise<string> {
|
* Provides the platform-specific path segment delimiter:
|
||||||
|
* - `;` on Windows
|
||||||
|
* - `:` on POSIX
|
||||||
|
*/
|
||||||
|
const delimiter = isWindows() ? ';' : ':'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves a sequence of `paths` or `path` segments into an absolute path.
|
||||||
|
*
|
||||||
|
* @param paths A sequence of paths or path segments.
|
||||||
|
*/
|
||||||
|
async function resolve(...paths: string[]): Promise<string> {
|
||||||
return invokeTauriCommand<string>({
|
return invokeTauriCommand<string>({
|
||||||
__tauriModule: 'Fs',
|
__tauriModule: 'Path',
|
||||||
message: {
|
message: {
|
||||||
cmd: 'resolvePath',
|
cmd: 'resolve',
|
||||||
|
paths
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes the given `path`, resolving `'..'` and `'.'` segments and resolve symolic links.
|
||||||
|
*/
|
||||||
|
async function normalize(path: string): Promise<string> {
|
||||||
|
return invokeTauriCommand<string>({
|
||||||
|
__tauriModule: 'Path',
|
||||||
|
message: {
|
||||||
|
cmd: 'normalize',
|
||||||
|
path
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Joins all given `path` segments together using the platform-specific separator as a delimiter, then normalizes the resulting path.
|
||||||
|
*
|
||||||
|
* @param paths A sequence of path segments.
|
||||||
|
*/
|
||||||
|
async function join(...paths: string[]): Promise<string> {
|
||||||
|
return invokeTauriCommand<string>({
|
||||||
|
__tauriModule: 'Path',
|
||||||
|
message: {
|
||||||
|
cmd: 'join',
|
||||||
|
paths
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the directory name of a `path`. Trailing directory separators are ignored.
|
||||||
|
*/
|
||||||
|
async function dirname(path: string): Promise<string> {
|
||||||
|
return invokeTauriCommand<string>({
|
||||||
|
__tauriModule: 'Path',
|
||||||
|
message: {
|
||||||
|
cmd: 'dirname',
|
||||||
|
path
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the extension of the `path`.
|
||||||
|
*/
|
||||||
|
async function extname(path: string): Promise<string> {
|
||||||
|
return invokeTauriCommand<string>({
|
||||||
|
__tauriModule: 'Path',
|
||||||
|
message: {
|
||||||
|
cmd: 'extname',
|
||||||
|
path
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last portion of a `path`. Trailing directory separators are ignored.
|
||||||
|
*
|
||||||
|
* @param ext An optional file extension to be removed from the returned path.
|
||||||
|
*/
|
||||||
|
async function basename(path: string, ext?: string): Promise<string> {
|
||||||
|
return invokeTauriCommand<string>({
|
||||||
|
__tauriModule: 'Path',
|
||||||
|
message: {
|
||||||
|
cmd: 'basename',
|
||||||
path,
|
path,
|
||||||
directory
|
ext
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function isAbsolute(path: string): Promise<boolean> {
|
||||||
|
return invokeTauriCommand<boolean>({
|
||||||
|
__tauriModule: 'Path',
|
||||||
|
message: {
|
||||||
|
cmd: 'isAbsolute',
|
||||||
|
path
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -469,6 +557,14 @@ export {
|
||||||
templateDir,
|
templateDir,
|
||||||
videoDir,
|
videoDir,
|
||||||
currentDir,
|
currentDir,
|
||||||
resolvePath,
|
BaseDirectory,
|
||||||
BaseDirectory
|
sep,
|
||||||
|
delimiter,
|
||||||
|
resolve,
|
||||||
|
normalize,
|
||||||
|
join,
|
||||||
|
dirname,
|
||||||
|
extname,
|
||||||
|
basename,
|
||||||
|
isAbsolute
|
||||||
}
|
}
|
||||||
|
|
|
@ -380,8 +380,6 @@ pub struct FsAllowlistConfig {
|
||||||
pub remove_file: bool,
|
pub remove_file: bool,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub rename_file: bool,
|
pub rename_file: bool,
|
||||||
#[serde(default)]
|
|
||||||
pub path: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Allowlist for FsAllowlistConfig {
|
impl Allowlist for FsAllowlistConfig {
|
||||||
|
@ -400,7 +398,6 @@ impl Allowlist for FsAllowlistConfig {
|
||||||
check_feature!(self, features, remove_dir, "fs-remove-dir");
|
check_feature!(self, features, remove_dir, "fs-remove-dir");
|
||||||
check_feature!(self, features, remove_file, "fs-remove-file");
|
check_feature!(self, features, remove_file, "fs-remove-file");
|
||||||
check_feature!(self, features, rename_file, "fs-rename-file");
|
check_feature!(self, features, rename_file, "fs-rename-file");
|
||||||
check_feature!(self, features, path, "fs-path");
|
|
||||||
features
|
features
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -530,6 +527,40 @@ impl Allowlist for GlobalShortcutAllowlistConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||||
|
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||||
|
pub struct OsAllowlistConfig {
|
||||||
|
#[serde(default)]
|
||||||
|
pub all: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Allowlist for OsAllowlistConfig {
|
||||||
|
fn to_features(&self) -> Vec<&str> {
|
||||||
|
if self.all {
|
||||||
|
vec!["os-all"]
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||||
|
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||||
|
pub struct PathAllowlistConfig {
|
||||||
|
#[serde(default)]
|
||||||
|
pub all: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Allowlist for PathAllowlistConfig {
|
||||||
|
fn to_features(&self) -> Vec<&str> {
|
||||||
|
if self.all {
|
||||||
|
vec!["path-all"]
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||||
pub struct AllowlistConfig {
|
pub struct AllowlistConfig {
|
||||||
|
@ -549,6 +580,10 @@ pub struct AllowlistConfig {
|
||||||
pub notification: NotificationAllowlistConfig,
|
pub notification: NotificationAllowlistConfig,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub global_shortcut: GlobalShortcutAllowlistConfig,
|
pub global_shortcut: GlobalShortcutAllowlistConfig,
|
||||||
|
#[serde(default)]
|
||||||
|
pub os: OsAllowlistConfig,
|
||||||
|
#[serde(default)]
|
||||||
|
pub path: PathAllowlistConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Allowlist for AllowlistConfig {
|
impl Allowlist for AllowlistConfig {
|
||||||
|
@ -564,6 +599,8 @@ impl Allowlist for AllowlistConfig {
|
||||||
features.extend(self.http.to_features());
|
features.extend(self.http.to_features());
|
||||||
features.extend(self.notification.to_features());
|
features.extend(self.notification.to_features());
|
||||||
features.extend(self.global_shortcut.to_features());
|
features.extend(self.global_shortcut.to_features());
|
||||||
|
features.extend(self.os.to_features());
|
||||||
|
features.extend(self.path.to_features());
|
||||||
features
|
features
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@
|
||||||
"all": false,
|
"all": false,
|
||||||
"copyFile": false,
|
"copyFile": false,
|
||||||
"createDir": false,
|
"createDir": false,
|
||||||
"path": false,
|
|
||||||
"readBinaryFile": false,
|
"readBinaryFile": false,
|
||||||
"readDir": false,
|
"readDir": false,
|
||||||
"readTextFile": false,
|
"readTextFile": false,
|
||||||
|
@ -69,6 +68,12 @@
|
||||||
"notification": {
|
"notification": {
|
||||||
"all": false
|
"all": false
|
||||||
},
|
},
|
||||||
|
"os": {
|
||||||
|
"all": false
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"all": false
|
||||||
|
},
|
||||||
"shell": {
|
"shell": {
|
||||||
"all": false,
|
"all": false,
|
||||||
"execute": false,
|
"execute": false,
|
||||||
|
@ -133,7 +138,6 @@
|
||||||
"all": false,
|
"all": false,
|
||||||
"copyFile": false,
|
"copyFile": false,
|
||||||
"createDir": false,
|
"createDir": false,
|
||||||
"path": false,
|
|
||||||
"readBinaryFile": false,
|
"readBinaryFile": false,
|
||||||
"readDir": false,
|
"readDir": false,
|
||||||
"readTextFile": false,
|
"readTextFile": false,
|
||||||
|
@ -180,6 +184,26 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"os": {
|
||||||
|
"default": {
|
||||||
|
"all": false
|
||||||
|
},
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/OsAllowlistConfig"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"default": {
|
||||||
|
"all": false
|
||||||
|
},
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/PathAllowlistConfig"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"shell": {
|
"shell": {
|
||||||
"default": {
|
"default": {
|
||||||
"all": false,
|
"all": false,
|
||||||
|
@ -724,10 +748,6 @@
|
||||||
"default": false,
|
"default": false,
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"path": {
|
|
||||||
"default": false,
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"readBinaryFile": {
|
"readBinaryFile": {
|
||||||
"default": false,
|
"default": false,
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
@ -846,6 +866,16 @@
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
|
"OsAllowlistConfig": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"all": {
|
||||||
|
"default": false,
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
"PackageConfig": {
|
"PackageConfig": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -866,6 +896,16 @@
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
|
"PathAllowlistConfig": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"all": {
|
||||||
|
"default": false,
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
"SecurityConfig": {
|
"SecurityConfig": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -930,7 +970,6 @@
|
||||||
"all": false,
|
"all": false,
|
||||||
"copyFile": false,
|
"copyFile": false,
|
||||||
"createDir": false,
|
"createDir": false,
|
||||||
"path": false,
|
|
||||||
"readBinaryFile": false,
|
"readBinaryFile": false,
|
||||||
"readDir": false,
|
"readDir": false,
|
||||||
"readTextFile": false,
|
"readTextFile": false,
|
||||||
|
@ -950,6 +989,12 @@
|
||||||
"notification": {
|
"notification": {
|
||||||
"all": false
|
"all": false
|
||||||
},
|
},
|
||||||
|
"os": {
|
||||||
|
"all": false
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"all": false
|
||||||
|
},
|
||||||
"shell": {
|
"shell": {
|
||||||
"all": false,
|
"all": false,
|
||||||
"execute": false,
|
"execute": false,
|
||||||
|
|
|
@ -135,7 +135,6 @@ pub fn all_allowlist_features() -> Vec<&'static str> {
|
||||||
remove_dir: true,
|
remove_dir: true,
|
||||||
remove_file: true,
|
remove_file: true,
|
||||||
rename_file: true,
|
rename_file: true,
|
||||||
path: true,
|
|
||||||
},
|
},
|
||||||
window: WindowAllowlistConfig {
|
window: WindowAllowlistConfig {
|
||||||
all: true,
|
all: true,
|
||||||
|
@ -157,6 +156,8 @@ pub fn all_allowlist_features() -> Vec<&'static str> {
|
||||||
},
|
},
|
||||||
notification: NotificationAllowlistConfig { all: true },
|
notification: NotificationAllowlistConfig { all: true },
|
||||||
global_shortcut: GlobalShortcutAllowlistConfig { all: true },
|
global_shortcut: GlobalShortcutAllowlistConfig { all: true },
|
||||||
|
os: OsAllowlistConfig { all: true },
|
||||||
|
path: PathAllowlistConfig { all: true },
|
||||||
}
|
}
|
||||||
.to_features()
|
.to_features()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue