diff --git a/Cargo.lock b/Cargo.lock index 6ef9cd2e62..3d8641e168 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1174,6 +1174,7 @@ dependencies = [ "deno_lockfile", "deno_npm", "deno_package_json", + "deno_path_util", "deno_runtime", "deno_semver", "deno_task_shell", @@ -1570,6 +1571,7 @@ dependencies = [ "base32", "deno_core", "deno_io", + "deno_path_util", "deno_permissions", "filetime", "junction", @@ -1682,6 +1684,7 @@ dependencies = [ "chrono", "deno_core", "deno_fetch", + "deno_path_util", "deno_permissions", "deno_tls", "denokv_proto", @@ -1800,6 +1803,7 @@ dependencies = [ "deno_media_type", "deno_net", "deno_package_json", + "deno_path_util", "deno_permissions", "deno_whoami", "der", @@ -1916,11 +1920,23 @@ dependencies = [ "url", ] +[[package]] +name = "deno_path_util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625b490bc4734ff778926d7034650a2ddcef2fd42b71e30bb722249156d5a144" +dependencies = [ + "percent-encoding", + "thiserror", + "url", +] + [[package]] name = "deno_permissions" version = "0.28.0" dependencies = [ "deno_core", + "deno_path_util", "deno_terminal 0.2.0", "fqdn", "libc", @@ -1953,6 +1969,7 @@ dependencies = [ "deno_napi", "deno_net", "deno_node", + "deno_path_util", "deno_permissions", "deno_terminal 0.2.0", "deno_tls", diff --git a/Cargo.toml b/Cargo.toml index 81cbf8b4c6..3bb9f2d46e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ deno_core = { version = "0.311.0" } deno_bench_util = { version = "0.162.0", path = "./bench_util" } deno_lockfile = "=0.23.1" deno_media_type = { version = "0.1.4", features = ["module_specifier"] } +deno_path_util = "=0.1.1" deno_permissions = { version = "0.28.0", path = "./runtime/permissions" } deno_runtime = { version = "0.177.0", path = "./runtime" } deno_semver = "=0.5.13" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index f5a8624e1d..ddcf7119f4 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -73,6 +73,7 @@ deno_lint = { version = "=0.67.0", features = ["docs"] } deno_lockfile.workspace = true deno_npm = "=0.25.2" deno_package_json.workspace = true +deno_path_util.workspace = true deno_runtime = { workspace = true, features = ["include_js_files_for_snapshotting"] } deno_semver.workspace = true deno_task_shell = "=0.17.0" diff --git a/cli/args/flags.rs b/cli/args/flags.rs index 9938a09552..13c93fa831 100644 --- a/cli/args/flags.rs +++ b/cli/args/flags.rs @@ -29,13 +29,13 @@ use deno_config::glob::PathOrPatternSet; use deno_core::anyhow::bail; use deno_core::anyhow::Context; use deno_core::error::AnyError; -use deno_core::normalize_path; use deno_core::resolve_url_or_path; use deno_core::url::Url; use deno_graph::GraphKind; +use deno_path_util::normalize_path; +use deno_path_util::url_to_file_path; use deno_runtime::deno_permissions::parse_sys_kind; use deno_runtime::deno_permissions::PermissionsOptions; -use deno_runtime::fs_util::specifier_to_file_path; use log::debug; use log::Level; use serde::Deserialize; @@ -1002,7 +1002,7 @@ impl Flags { if module_specifier.scheme() == "file" || module_specifier.scheme() == "npm" { - if let Ok(p) = specifier_to_file_path(&module_specifier) { + if let Ok(p) = url_to_file_path(&module_specifier) { Some(vec![p.parent().unwrap().to_path_buf()]) } else { Some(vec![current_dir.to_path_buf()]) diff --git a/cli/args/mod.rs b/cli/args/mod.rs index c3a4c29377..3ff2a427fb 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -20,13 +20,13 @@ use deno_config::workspace::WorkspaceDiscoverOptions; use deno_config::workspace::WorkspaceDiscoverStart; use deno_config::workspace::WorkspaceLintConfig; use deno_config::workspace::WorkspaceResolver; -use deno_core::normalize_path; use deno_core::resolve_url_or_path; use deno_graph::GraphKind; use deno_npm::npm_rc::NpmRc; use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; use deno_npm::NpmSystemInfo; +use deno_path_util::normalize_path; use deno_semver::npm::NpmPackageReqReference; use import_map::resolve_import_map_value_from_specifier; diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs index ca11449393..1bf7635949 100644 --- a/cli/file_fetcher.rs +++ b/cli/file_fetcher.rs @@ -21,9 +21,9 @@ use deno_core::url::Url; use deno_core::ModuleSpecifier; use deno_graph::source::LoaderChecksum; +use deno_path_util::url_to_file_path; use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_web::BlobStore; -use deno_runtime::fs_util::specifier_to_file_path; use log::debug; use std::borrow::Cow; use std::collections::HashMap; @@ -136,7 +136,7 @@ impl MemoryFiles { /// Fetch a source file from the local file system. fn fetch_local(specifier: &ModuleSpecifier) -> Result { - let local = specifier_to_file_path(specifier).map_err(|_| { + let local = url_to_file_path(specifier).map_err(|_| { uri_error(format!("Invalid file path.\n Specifier: {specifier}")) })?; // If it doesnt have a extension, we want to treat it as typescript by default diff --git a/cli/graph_util.rs b/cli/graph_util.rs index 17f7d6739f..7d03d3c0b2 100644 --- a/cli/graph_util.rs +++ b/cli/graph_util.rs @@ -39,10 +39,10 @@ use deno_graph::ModuleGraph; use deno_graph::ModuleGraphError; use deno_graph::ResolutionError; use deno_graph::SpecifierError; +use deno_path_util::url_to_file_path; use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_node; use deno_runtime::deno_permissions::PermissionsContainer; -use deno_runtime::fs_util::specifier_to_file_path; use deno_semver::jsr::JsrDepPackageReq; use deno_semver::package::PackageNv; use import_map::ImportMapError; @@ -948,7 +948,7 @@ pub fn has_graph_root_local_dependent_changed( }, ); while let Some((s, _)) = dependent_specifiers.next() { - if let Ok(path) = specifier_to_file_path(s) { + if let Ok(path) = url_to_file_path(s) { if let Ok(path) = canonicalize_path(&path) { if canonicalized_changed_paths.contains(&path) { return true; diff --git a/cli/lsp/analysis.rs b/cli/lsp/analysis.rs index fee9c86cbe..80db66d64c 100644 --- a/cli/lsp/analysis.rs +++ b/cli/lsp/analysis.rs @@ -23,8 +23,8 @@ use deno_core::serde::Serialize; use deno_core::serde_json; use deno_core::serde_json::json; use deno_core::ModuleSpecifier; +use deno_path_util::url_to_file_path; use deno_runtime::deno_node::PathClean; -use deno_runtime::fs_util::specifier_to_file_path; use deno_semver::jsr::JsrPackageNvReference; use deno_semver::jsr::JsrPackageReqReference; use deno_semver::npm::NpmPackageReqReference; @@ -401,7 +401,7 @@ impl<'a> TsResponseImportMapper<'a> { .flatten()?; let root_folder = package_json.path.parent()?; - let specifier_path = specifier_to_file_path(specifier).ok()?; + let specifier_path = url_to_file_path(specifier).ok()?; let mut search_paths = vec![specifier_path.clone()]; // TypeScript will provide a .js extension for quick fixes, so do // a search for the .d.ts file instead diff --git a/cli/lsp/cache.rs b/cli/lsp/cache.rs index a32087842d..db10dc9677 100644 --- a/cli/lsp/cache.rs +++ b/cli/lsp/cache.rs @@ -10,7 +10,7 @@ use crate::lsp::logging::lsp_warn; use deno_core::url::Url; use deno_core::ModuleSpecifier; -use deno_runtime::fs_util::specifier_to_file_path; +use deno_path_util::url_to_file_path; use std::collections::BTreeMap; use std::fs; use std::path::Path; @@ -24,7 +24,7 @@ pub fn calculate_fs_version( ) -> Option { match specifier.scheme() { "npm" | "node" | "data" | "blob" => None, - "file" => specifier_to_file_path(specifier) + "file" => url_to_file_path(specifier) .ok() .and_then(|path| calculate_fs_version_at_path(&path)), _ => calculate_fs_version_in_cache(cache, specifier, file_referrer), @@ -82,7 +82,7 @@ impl Default for LspCache { impl LspCache { pub fn new(global_cache_url: Option) -> Self { let global_cache_path = global_cache_url.and_then(|s| { - specifier_to_file_path(&s) + url_to_file_path(&s) .inspect(|p| { lsp_log!("Resolved global cache path: \"{}\"", p.to_string_lossy()); }) @@ -165,7 +165,7 @@ impl LspCache { &self, specifier: &ModuleSpecifier, ) -> Option { - let path = specifier_to_file_path(specifier).ok()?; + let path = url_to_file_path(specifier).ok()?; let vendor = self .vendors_by_scope .iter() @@ -176,7 +176,7 @@ impl LspCache { } pub fn is_valid_file_referrer(&self, specifier: &ModuleSpecifier) -> bool { - if let Ok(path) = specifier_to_file_path(specifier) { + if let Ok(path) = url_to_file_path(specifier) { if !path.starts_with(&self.deno_dir().root) { return true; } diff --git a/cli/lsp/completions.rs b/cli/lsp/completions.rs index b3d6fbbd04..a040be5691 100644 --- a/cli/lsp/completions.rs +++ b/cli/lsp/completions.rs @@ -29,7 +29,7 @@ use deno_core::serde::Serialize; use deno_core::serde_json::json; use deno_core::url::Position; use deno_core::ModuleSpecifier; -use deno_runtime::fs_util::specifier_to_file_path; +use deno_path_util::url_to_file_path; use deno_semver::jsr::JsrPackageReqReference; use deno_semver::package::PackageNv; use import_map::ImportMap; @@ -380,7 +380,7 @@ fn get_local_completions( ResolutionMode::Execution, ) .ok()?; - let resolved_parent_path = specifier_to_file_path(&resolved_parent).ok()?; + let resolved_parent_path = url_to_file_path(&resolved_parent).ok()?; let raw_parent = &text[..text.char_indices().rfind(|(_, c)| *c == '/')?.0 + 1]; if resolved_parent_path.is_dir() { diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs index e55e7b734d..dcb6120a45 100644 --- a/cli/lsp/config.rs +++ b/cli/lsp/config.rs @@ -36,8 +36,8 @@ use deno_core::ModuleSpecifier; use deno_lint::linter::LintConfig as DenoLintConfig; use deno_npm::npm_rc::ResolvedNpmRc; use deno_package_json::PackageJsonCache; +use deno_path_util::url_to_file_path; use deno_runtime::deno_node::PackageJson; -use deno_runtime::fs_util::specifier_to_file_path; use indexmap::IndexSet; use lsp_types::ClientCapabilities; use std::collections::BTreeMap; @@ -801,7 +801,7 @@ impl Settings { /// Returns `None` if the value should be deferred to the presence of a /// `deno.json` file. pub fn specifier_enabled(&self, specifier: &ModuleSpecifier) -> Option { - let Ok(path) = specifier_to_file_path(specifier) else { + let Ok(path) = url_to_file_path(specifier) else { // Non-file URLs are not disabled by these settings. return Some(true); }; @@ -810,7 +810,7 @@ impl Settings { let mut disable_paths = vec![]; let mut enable_paths = None; if let Some(folder_uri) = folder_uri { - if let Ok(folder_path) = specifier_to_file_path(folder_uri) { + if let Ok(folder_path) = url_to_file_path(folder_uri) { disable_paths = settings .disable_paths .iter() @@ -847,12 +847,12 @@ impl Settings { &self, specifier: &ModuleSpecifier, ) -> (&WorkspaceSettings, Option<&ModuleSpecifier>) { - let Ok(path) = specifier_to_file_path(specifier) else { + let Ok(path) = url_to_file_path(specifier) else { return (&self.unscoped, self.first_folder.as_ref()); }; for (folder_uri, settings) in self.by_workspace_folder.iter().rev() { if let Some(settings) = settings { - let Ok(folder_path) = specifier_to_file_path(folder_uri) else { + let Ok(folder_path) = url_to_file_path(folder_uri) else { continue; }; if path.starts_with(folder_path) { @@ -1767,7 +1767,7 @@ impl ConfigTree { let config_file_path = (|| { let config_setting = ws_settings.config.as_ref()?; let config_uri = folder_uri.join(config_setting).ok()?; - specifier_to_file_path(&config_uri).ok() + url_to_file_path(&config_uri).ok() })(); if config_file_path.is_some() || ws_settings.import_map.is_some() { scopes.insert( @@ -1844,7 +1844,7 @@ impl ConfigTree { let scope = config_file.specifier.join(".").unwrap(); let json_text = serde_json::to_string(&config_file.json).unwrap(); let test_fs = deno_runtime::deno_fs::InMemoryFs::default(); - let config_path = specifier_to_file_path(&config_file.specifier).unwrap(); + let config_path = url_to_file_path(&config_file.specifier).unwrap(); test_fs.setup_text_files(vec![( config_path.to_string_lossy().to_string(), json_text, diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs index e96b8831bb..7d1ca6810d 100644 --- a/cli/lsp/documents.rs +++ b/cli/lsp/documents.rs @@ -26,8 +26,8 @@ use deno_core::parking_lot::Mutex; use deno_core::ModuleSpecifier; use deno_graph::source::ResolutionMode; use deno_graph::Resolution; +use deno_path_util::url_to_file_path; use deno_runtime::deno_node; -use deno_runtime::fs_util::specifier_to_file_path; use deno_semver::jsr::JsrPackageReqReference; use deno_semver::npm::NpmPackageReqReference; use deno_semver::package::PackageReq; @@ -849,7 +849,7 @@ impl FileSystemDocuments { file_referrer: Option<&ModuleSpecifier>, ) -> Option> { let doc = if specifier.scheme() == "file" { - let path = specifier_to_file_path(specifier).ok()?; + let path = url_to_file_path(specifier).ok()?; let bytes = fs::read(path).ok()?; let content = deno_graph::source::decode_owned_source(specifier, bytes, None).ok()?; @@ -1136,7 +1136,7 @@ impl Documents { return true; } if specifier.scheme() == "file" { - return specifier_to_file_path(&specifier) + return url_to_file_path(&specifier) .map(|p| p.is_file()) .unwrap_or(false); } @@ -1325,7 +1325,7 @@ impl Documents { let fs_docs = &self.file_system_docs; // Clean up non-existent documents. fs_docs.docs.retain(|specifier, _| { - let Ok(path) = specifier_to_file_path(specifier) else { + let Ok(path) = url_to_file_path(specifier) else { // Remove non-file schemed docs (deps). They may not be dependencies // anymore after updating resolvers. return false; diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 216b14de62..3fe969ba3d 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -15,9 +15,9 @@ use deno_core::url::Url; use deno_core::ModuleSpecifier; use deno_graph::GraphKind; use deno_graph::Resolution; +use deno_path_util::url_to_file_path; use deno_runtime::deno_tls::rustls::RootCertStore; use deno_runtime::deno_tls::RootCertStoreProvider; -use deno_runtime::fs_util::specifier_to_file_path; use deno_semver::jsr::JsrPackageReqReference; use indexmap::Equivalent; use indexmap::IndexSet; @@ -626,7 +626,7 @@ impl Inner { let maybe_root_path = self .config .root_uri() - .and_then(|uri| specifier_to_file_path(uri).ok()); + .and_then(|uri| url_to_file_path(uri).ok()); let root_cert_store = get_root_cert_store( maybe_root_path, workspace_settings.certificate_stores.clone(), @@ -802,7 +802,7 @@ impl Inner { let mut roots = config .workspace_folders .iter() - .filter_map(|p| specifier_to_file_path(&p.0).ok()) + .filter_map(|p| url_to_file_path(&p.0).ok()) .collect::>(); roots.sort(); let roots = roots @@ -1124,7 +1124,7 @@ impl Inner { { return; } - match specifier_to_file_path(&specifier) { + match url_to_file_path(&specifier) { Ok(path) if is_importable_ext(&path) => {} _ => return, } @@ -1362,7 +1362,7 @@ impl Inner { { specifier = uri_to_url(¶ms.text_document.uri); } - let file_path = specifier_to_file_path(&specifier).map_err(|err| { + let file_path = url_to_file_path(&specifier).map_err(|err| { error!("{:#}", err); LspError::invalid_request() })?; @@ -2508,7 +2508,7 @@ impl Inner { let maybe_root_path_owned = self .config .root_uri() - .and_then(|uri| specifier_to_file_path(uri).ok()); + .and_then(|uri| url_to_file_path(uri).ok()); let mut resolved_items = Vec::::new(); for item in incoming_calls.iter() { if let Some(resolved) = item.try_resolve_call_hierarchy_incoming_call( @@ -2554,7 +2554,7 @@ impl Inner { let maybe_root_path_owned = self .config .root_uri() - .and_then(|uri| specifier_to_file_path(uri).ok()); + .and_then(|uri| url_to_file_path(uri).ok()); let mut resolved_items = Vec::::new(); for item in outgoing_calls.iter() { if let Some(resolved) = item.try_resolve_call_hierarchy_outgoing_call( @@ -2603,7 +2603,7 @@ impl Inner { let maybe_root_path_owned = self .config .root_uri() - .and_then(|uri| specifier_to_file_path(uri).ok()); + .and_then(|uri| url_to_file_path(uri).ok()); let mut resolved_items = Vec::::new(); match one_or_many { tsc::OneOrMany::One(item) => { diff --git a/cli/lsp/resolver.rs b/cli/lsp/resolver.rs index 2844eb6f98..f98b23a3f9 100644 --- a/cli/lsp/resolver.rs +++ b/cli/lsp/resolver.rs @@ -10,10 +10,10 @@ use deno_graph::source::Resolver; use deno_graph::GraphImport; use deno_graph::ModuleSpecifier; use deno_npm::NpmSystemInfo; +use deno_path_util::url_to_file_path; use deno_runtime::deno_fs; use deno_runtime::deno_node::NodeResolver; use deno_runtime::deno_node::PackageJson; -use deno_runtime::fs_util::specifier_to_file_path; use deno_semver::jsr::JsrPackageReqReference; use deno_semver::npm::NpmPackageReqReference; use deno_semver::package::PackageNv; @@ -443,7 +443,7 @@ async fn create_npm_resolver( fs: Arc::new(deno_fs::RealFs), root_node_modules_dir: config_data.and_then(|config_data| { config_data.node_modules_dir.clone().or_else(|| { - specifier_to_file_path(&config_data.scope) + url_to_file_path(&config_data.scope) .ok() .map(|p| p.join("node_modules/")) }) diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index fe3708d3cb..c8b5c47f83 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -62,7 +62,7 @@ use deno_core::ModuleSpecifier; use deno_core::OpState; use deno_core::PollEventLoopOptions; use deno_core::RuntimeOptions; -use deno_runtime::fs_util::specifier_to_file_path; +use deno_path_util::url_to_file_path; use deno_runtime::inspector_server::InspectorServer; use deno_runtime::tokio_util::create_basic_runtime; use indexmap::IndexMap; @@ -3191,7 +3191,7 @@ impl CallHierarchyItem { let use_file_name = self.is_source_file_item(); let maybe_file_path = if uri.scheme().is_some_and(|s| s.as_str() == "file") { - specifier_to_file_path(&uri_to_url(&uri)).ok() + url_to_file_path(&uri_to_url(&uri)).ok() } else { None }; diff --git a/cli/npm/byonm.rs b/cli/npm/byonm.rs index 4c8bbd3948..83c4067655 100644 --- a/cli/npm/byonm.rs +++ b/cli/npm/byonm.rs @@ -10,12 +10,12 @@ use deno_core::anyhow::bail; use deno_core::error::AnyError; use deno_core::serde_json; use deno_package_json::PackageJsonDepValue; +use deno_path_util::url_to_file_path; use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_node::DenoPkgJsonFsAdapter; use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodeRequireResolver; use deno_runtime::deno_node::PackageJson; -use deno_runtime::fs_util::specifier_to_file_path; use deno_runtime::ops::process::NpmProcessStateProvider; use deno_semver::package::PackageReq; use deno_semver::Version; @@ -126,7 +126,7 @@ impl ByonmCliNpmResolver { } // attempt to resolve the npm specifier from the referrer's package.json, - if let Ok(file_path) = specifier_to_file_path(referrer) { + if let Ok(file_path) = url_to_file_path(referrer) { let mut current_path = file_path.as_path(); while let Some(dir_path) = current_path.parent() { let package_json_path = dir_path.join("package.json"); @@ -221,7 +221,7 @@ impl NpmResolver for ByonmCliNpmResolver { name: &str, referrer: &ModuleSpecifier, ) -> Result { - let maybe_referrer_file = specifier_to_file_path(referrer).ok(); + let maybe_referrer_file = url_to_file_path(referrer).ok(); let maybe_start_folder = maybe_referrer_file.as_ref().and_then(|f| f.parent()); if let Some(start_folder) = maybe_start_folder { diff --git a/cli/resolver.rs b/cli/resolver.rs index 07cb6931df..cf4cd8b74a 100644 --- a/cli/resolver.rs +++ b/cli/resolver.rs @@ -22,12 +22,12 @@ use deno_graph::NpmLoadError; use deno_graph::NpmResolvePkgReqsResult; use deno_npm::resolution::NpmResolutionError; use deno_package_json::PackageJsonDepValue; +use deno_path_util::url_to_file_path; use deno_runtime::colors; use deno_runtime::deno_fs; use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_node::is_builtin_node_module; use deno_runtime::deno_node::NodeResolver; -use deno_runtime::fs_util::specifier_to_file_path; use deno_semver::npm::NpmPackageReqReference; use deno_semver::package::PackageReq; use node_resolver::errors::ClosestPkgJsonError; @@ -992,7 +992,7 @@ impl SloppyImportsResolver { return None; } - let path = specifier_to_file_path(specifier).ok()?; + let path = url_to_file_path(specifier).ok()?; #[derive(Clone, Copy)] enum SloppyImportsResolutionReason { diff --git a/cli/tools/task.rs b/cli/tools/task.rs index ae91f53a7a..a5a5027d0f 100644 --- a/cli/tools/task.rs +++ b/cli/tools/task.rs @@ -16,7 +16,7 @@ use deno_core::anyhow::anyhow; use deno_core::anyhow::bail; use deno_core::anyhow::Context; use deno_core::error::AnyError; -use deno_core::normalize_path; +use deno_path_util::normalize_path; use deno_task_shell::ShellCommand; use crate::args::CliOptions; diff --git a/cli/util/fs.rs b/cli/util/fs.rs index fdf6035ecd..7cf91bbb59 100644 --- a/cli/util/fs.rs +++ b/cli/util/fs.rs @@ -708,8 +708,8 @@ pub fn specifier_from_file_path( mod tests { use super::*; use deno_core::futures; - use deno_core::normalize_path; use deno_core::parking_lot::Mutex; + use deno_path_util::normalize_path; use pretty_assertions::assert_eq; use test_util::PathRef; use test_util::TempDir; diff --git a/ext/fs/Cargo.toml b/ext/fs/Cargo.toml index 894b307efa..42717dccb0 100644 --- a/ext/fs/Cargo.toml +++ b/ext/fs/Cargo.toml @@ -21,6 +21,7 @@ async-trait.workspace = true base32.workspace = true deno_core.workspace = true deno_io.workspace = true +deno_path_util.workspace = true deno_permissions.workspace = true filetime.workspace = true libc.workspace = true diff --git a/ext/fs/in_memory_fs.rs b/ext/fs/in_memory_fs.rs index 027539e849..2692023860 100644 --- a/ext/fs/in_memory_fs.rs +++ b/ext/fs/in_memory_fs.rs @@ -12,12 +12,12 @@ use std::path::PathBuf; use std::rc::Rc; use std::sync::Arc; -use deno_core::normalize_path; use deno_core::parking_lot::Mutex; use deno_io::fs::File; use deno_io::fs::FsError; use deno_io::fs::FsResult; use deno_io::fs::FsStat; +use deno_path_util::normalize_path; use crate::interface::AccessCheckCb; use crate::interface::FsDirEntry; diff --git a/ext/fs/std_fs.rs b/ext/fs/std_fs.rs index d8d5f65027..443c26819d 100644 --- a/ext/fs/std_fs.rs +++ b/ext/fs/std_fs.rs @@ -11,13 +11,13 @@ use std::path::Path; use std::path::PathBuf; use std::rc::Rc; -use deno_core::normalize_path; use deno_core::unsync::spawn_blocking; use deno_io::fs::File; use deno_io::fs::FsError; use deno_io::fs::FsResult; use deno_io::fs::FsStat; use deno_io::StdFileResourceInner; +use deno_path_util::normalize_path; use crate::interface::AccessCheckCb; use crate::interface::FsDirEntry; diff --git a/ext/kv/Cargo.toml b/ext/kv/Cargo.toml index eee4762eb4..9b2d596d06 100644 --- a/ext/kv/Cargo.toml +++ b/ext/kv/Cargo.toml @@ -21,6 +21,7 @@ bytes.workspace = true chrono = { workspace = true, features = ["now"] } deno_core.workspace = true deno_fetch.workspace = true +deno_path_util.workspace = true deno_permissions.workspace = true deno_tls.workspace = true denokv_proto.workspace = true diff --git a/ext/kv/sqlite.rs b/ext/kv/sqlite.rs index 8027ff03d4..0b4a3693c4 100644 --- a/ext/kv/sqlite.rs +++ b/ext/kv/sqlite.rs @@ -16,9 +16,9 @@ use std::sync::OnceLock; use async_trait::async_trait; use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::normalize_path; use deno_core::unsync::spawn_blocking; use deno_core::OpState; +use deno_path_util::normalize_path; pub use denokv_sqlite::SqliteBackendError; use denokv_sqlite::SqliteConfig; use denokv_sqlite::SqliteNotifier; diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index 17da17cd81..06a91c501f 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -34,6 +34,7 @@ deno_io.workspace = true deno_media_type.workspace = true deno_net.workspace = true deno_package_json.workspace = true +deno_path_util.workspace = true deno_permissions.workspace = true deno_whoami = "0.1.0" der = { version = "0.7.9", features = ["derive"] } diff --git a/ext/node/ops/require.rs b/ext/node/ops/require.rs index 3578719d0c..15667aae73 100644 --- a/ext/node/ops/require.rs +++ b/ext/node/ops/require.rs @@ -3,7 +3,6 @@ use deno_core::anyhow::Context; use deno_core::error::generic_error; use deno_core::error::AnyError; -use deno_core::normalize_path; use deno_core::op2; use deno_core::url::Url; use deno_core::v8; @@ -12,6 +11,7 @@ use deno_core::ModuleSpecifier; use deno_core::OpState; use deno_fs::FileSystemRc; use deno_package_json::PackageJsonRc; +use deno_path_util::normalize_path; use node_resolver::NodeModuleKind; use node_resolver::NodeResolutionMode; use node_resolver::REQUIRE_CONDITIONS; @@ -104,7 +104,7 @@ where } else { let current_dir = &(fs.cwd().map_err(AnyError::from)).context("Unable to get CWD")?; - deno_core::normalize_path(current_dir.join(from)) + deno_path_util::normalize_path(current_dir.join(from)) }; ensure_read_permission::

(state, &from)?; diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index ea2978c49b..d999513d28 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -88,6 +88,7 @@ deno_kv.workspace = true deno_napi.workspace = true deno_net.workspace = true deno_node.workspace = true +deno_path_util.workspace = true deno_permissions.workspace = true deno_terminal.workspace = true deno_tls.workspace = true diff --git a/runtime/fs_util.rs b/runtime/fs_util.rs index 15ebafdf61..a858e9770d 100644 --- a/runtime/fs_util.rs +++ b/runtime/fs_util.rs @@ -2,12 +2,10 @@ use deno_core::anyhow::Context; use deno_core::error::AnyError; +use deno_path_util::normalize_path; use std::path::Path; use std::path::PathBuf; -pub use deno_core::normalize_path; -pub use deno_permissions::specifier_to_file_path; - #[inline] pub fn resolve_from_cwd(path: &Path) -> Result { if path.is_absolute() { diff --git a/runtime/ops/os/mod.rs b/runtime/ops/os/mod.rs index 544031dd7b..bd9260e97e 100644 --- a/runtime/ops/os/mod.rs +++ b/runtime/ops/os/mod.rs @@ -4,11 +4,11 @@ use super::utils::into_string; use crate::worker::ExitCode; use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::normalize_path; use deno_core::op2; use deno_core::v8; use deno_core::OpState; use deno_node::NODE_ENV_VAR_ALLOWLIST; +use deno_path_util::normalize_path; use deno_permissions::PermissionsContainer; use serde::Serialize; use std::collections::HashMap; diff --git a/runtime/ops/process.rs b/runtime/ops/process.rs index 530dcf49be..f6555e9324 100644 --- a/runtime/ops/process.rs +++ b/runtime/ops/process.rs @@ -689,7 +689,7 @@ fn resolve_cmd(cmd: &str, env: &RunEnv) -> Result { } fn resolve_path(path: &str, cwd: &Path) -> PathBuf { - deno_core::normalize_path(cwd.join(path)) + deno_path_util::normalize_path(cwd.join(path)) } fn check_run_permission( diff --git a/runtime/permissions.rs b/runtime/permissions.rs index 9b2737b4fc..533319c4ef 100644 --- a/runtime/permissions.rs +++ b/runtime/permissions.rs @@ -6,7 +6,7 @@ use std::path::PathBuf; use deno_core::anyhow::bail; use deno_core::anyhow::Context; use deno_core::error::AnyError; -use deno_core::normalize_path; +use deno_path_util::normalize_path; use deno_permissions::AllowRunDescriptor; use deno_permissions::AllowRunDescriptorParseResult; use deno_permissions::DenyRunDescriptor; diff --git a/runtime/permissions/Cargo.toml b/runtime/permissions/Cargo.toml index 9821b61484..37500d3ebb 100644 --- a/runtime/permissions/Cargo.toml +++ b/runtime/permissions/Cargo.toml @@ -15,6 +15,7 @@ path = "lib.rs" [dependencies] deno_core.workspace = true +deno_path_util.workspace = true deno_terminal.workspace = true fqdn = "0.3.4" libc.workspace = true diff --git a/runtime/permissions/lib.rs b/runtime/permissions/lib.rs index 5d8e76125e..e919b81b60 100644 --- a/runtime/permissions/lib.rs +++ b/runtime/permissions/lib.rs @@ -6,7 +6,6 @@ use deno_core::error::custom_error; use deno_core::error::type_error; use deno_core::error::uri_error; use deno_core::error::AnyError; -use deno_core::normalize_path; use deno_core::parking_lot::Mutex; use deno_core::serde::de; use deno_core::serde::Deserialize; @@ -16,6 +15,8 @@ use deno_core::serde_json; use deno_core::unsync::sync::AtomicFlag; use deno_core::url::Url; use deno_core::ModuleSpecifier; +use deno_path_util::normalize_path; +use deno_path_util::url_to_file_path; use deno_terminal::colors; use fqdn::FQDN; use once_cell::sync::Lazy; @@ -2032,52 +2033,6 @@ impl Permissions { } } -/// Attempts to convert a specifier to a file path. By default, uses the Url -/// crate's `to_file_path()` method, but falls back to try and resolve unix-style -/// paths on Windows. -pub fn specifier_to_file_path( - specifier: &ModuleSpecifier, -) -> Result { - let result = if specifier.scheme() != "file" { - Err(()) - } else if cfg!(windows) { - if specifier.host().is_some() { - Err(()) - } else { - match specifier.to_file_path() { - Ok(path) => Ok(path), - Err(()) => { - // This might be a unix-style path which is used in the tests even on Windows. - // Attempt to see if we can convert it to a `PathBuf`. This code should be removed - // once/if https://github.com/servo/rust-url/issues/730 is implemented. - if specifier.scheme() == "file" - && specifier.port().is_none() - && specifier.path_segments().is_some() - { - let path_str = specifier.path(); - match String::from_utf8( - percent_encoding::percent_decode(path_str.as_bytes()).collect(), - ) { - Ok(path_str) => Ok(PathBuf::from(path_str)), - Err(_) => Err(()), - } - } else { - Err(()) - } - } - } - } - } else { - specifier.to_file_path() - }; - match result { - Ok(path) => Ok(path), - Err(()) => Err(uri_error(format!( - "Invalid file path.\n Specifier: {specifier}" - ))), - } -} - #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum CheckSpecifierKind { Static, @@ -2130,7 +2085,7 @@ impl PermissionsContainer { return Ok(()); } - match specifier_to_file_path(specifier) { + match url_to_file_path(specifier) { Ok(path) => inner.read.check( &PathQueryDescriptor { requested: path.to_string_lossy().into_owned(), @@ -4453,38 +4408,4 @@ mod tests { ); } } - - #[test] - fn test_specifier_to_file_path() { - run_success_test("file:///", "/"); - run_success_test("file:///test", "/test"); - run_success_test("file:///dir/test/test.txt", "/dir/test/test.txt"); - run_success_test( - "file:///dir/test%20test/test.txt", - "/dir/test test/test.txt", - ); - - assert_no_panic_specifier_to_file_path("file:/"); - assert_no_panic_specifier_to_file_path("file://"); - assert_no_panic_specifier_to_file_path("file://asdf/"); - assert_no_panic_specifier_to_file_path("file://asdf/66666/a.ts"); - - fn run_success_test(specifier: &str, expected_path: &str) { - let result = - specifier_to_file_path(&ModuleSpecifier::parse(specifier).unwrap()) - .unwrap(); - assert_eq!(result, PathBuf::from(expected_path)); - } - fn assert_no_panic_specifier_to_file_path(specifier: &str) { - let result = - specifier_to_file_path(&ModuleSpecifier::parse(specifier).unwrap()); - match result { - Ok(_) => (), - Err(err) => assert_eq!( - err.to_string(), - format!("Invalid file path.\n Specifier: {specifier}") - ), - } - } - } }