mirror of
https://github.com/denoland/deno.git
synced 2025-02-01 12:16:11 -05:00
perf(node_resolver): reduce url to/from path conversions (#27839)
Extracted out of https://github.com/denoland/deno/pull/27838/files Reduces some allocations by accepting either a pathbuf or url for the referrer for resolution and returning either a pathbuf or url at the end, which the caller can then convert into to their preferred state. This is about 4% faster when still converting the final result to a url and 6% faster when keeping the result as a path in a benchmark I ran.
This commit is contained in:
parent
92dce12af7
commit
679902a108
28 changed files with 679 additions and 417 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -5260,6 +5260,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"async-trait",
|
||||
"boxed_error",
|
||||
"dashmap",
|
||||
"deno_error",
|
||||
"deno_package_json",
|
||||
"deno_path_util",
|
||||
|
|
|
@ -7,6 +7,8 @@ use std::sync::Arc;
|
|||
|
||||
use deno_core::error::JsError;
|
||||
use deno_node::NodeRequireLoaderRc;
|
||||
use deno_path_util::url_from_file_path;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use deno_resolver::npm::NpmResolver;
|
||||
use deno_runtime::colors;
|
||||
|
@ -44,6 +46,7 @@ use deno_runtime::WorkerExecutionMode;
|
|||
use deno_runtime::WorkerLogLevel;
|
||||
use deno_runtime::UNSTABLE_GRANULAR_FLAGS;
|
||||
use node_resolver::errors::ResolvePkgJsonBinExportError;
|
||||
use node_resolver::UrlOrPath;
|
||||
use url::Url;
|
||||
|
||||
use crate::args::has_trace_permissions_enabled;
|
||||
|
@ -135,6 +138,9 @@ pub fn create_isolate_create_params() -> Option<v8::CreateParams> {
|
|||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum ResolveNpmBinaryEntrypointError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
PathToUrl(#[from] deno_path_util::PathToUrlError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ResolvePkgJsonBinExport(ResolvePkgJsonBinExportError),
|
||||
|
@ -153,7 +159,7 @@ pub enum ResolveNpmBinaryEntrypointFallbackError {
|
|||
PackageSubpathResolve(node_resolver::errors::PackageSubpathResolveError),
|
||||
#[class(generic)]
|
||||
#[error("Cannot find module '{0}'")]
|
||||
ModuleNotFound(Url),
|
||||
ModuleNotFound(UrlOrPath),
|
||||
}
|
||||
|
||||
pub struct LibMainWorkerOptions {
|
||||
|
@ -525,13 +531,13 @@ impl<TSys: DenoLibSys> LibMainWorkerFactory<TSys> {
|
|||
.node_resolver
|
||||
.resolve_binary_export(package_folder, sub_path)
|
||||
{
|
||||
Ok(specifier) => Ok(specifier),
|
||||
Ok(path) => Ok(url_from_file_path(&path)?),
|
||||
Err(original_err) => {
|
||||
// if the binary entrypoint was not found, fallback to regular node resolution
|
||||
let result =
|
||||
self.resolve_binary_entrypoint_fallback(package_folder, sub_path);
|
||||
match result {
|
||||
Ok(Some(specifier)) => Ok(specifier),
|
||||
Ok(Some(path)) => Ok(url_from_file_path(&path)?),
|
||||
Ok(None) => {
|
||||
Err(ResolveNpmBinaryEntrypointError::ResolvePkgJsonBinExport(
|
||||
original_err,
|
||||
|
@ -551,7 +557,7 @@ impl<TSys: DenoLibSys> LibMainWorkerFactory<TSys> {
|
|||
&self,
|
||||
package_folder: &Path,
|
||||
sub_path: Option<&str>,
|
||||
) -> Result<Option<Url>, ResolveNpmBinaryEntrypointFallbackError> {
|
||||
) -> Result<Option<PathBuf>, ResolveNpmBinaryEntrypointFallbackError> {
|
||||
// only fallback if the user specified a sub path
|
||||
if sub_path.is_none() {
|
||||
// it's confusing to users if the package doesn't have any binary
|
||||
|
@ -573,14 +579,22 @@ impl<TSys: DenoLibSys> LibMainWorkerFactory<TSys> {
|
|||
.map_err(
|
||||
ResolveNpmBinaryEntrypointFallbackError::PackageSubpathResolve,
|
||||
)?;
|
||||
if deno_path_util::url_to_file_path(&specifier)
|
||||
.map(|p| self.shared.sys.fs_exists_no_err(p))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
Ok(Some(specifier))
|
||||
let path = match specifier {
|
||||
UrlOrPath::Url(ref url) => match url_to_file_path(url) {
|
||||
Ok(path) => path,
|
||||
Err(_) => {
|
||||
return Err(ResolveNpmBinaryEntrypointFallbackError::ModuleNotFound(
|
||||
specifier,
|
||||
));
|
||||
}
|
||||
},
|
||||
UrlOrPath::Path(path) => path,
|
||||
};
|
||||
if self.shared.sys.fs_exists_no_err(&path) {
|
||||
Ok(Some(path))
|
||||
} else {
|
||||
Err(ResolveNpmBinaryEntrypointFallbackError::ModuleNotFound(
|
||||
specifier,
|
||||
UrlOrPath::Path(path),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -449,9 +449,7 @@ impl<'a> TsResponseImportMapper<'a> {
|
|||
.pkg_json_resolver(specifier)
|
||||
// the specifier might have a closer package.json, but we
|
||||
// want the root of the package's package.json
|
||||
.get_closest_package_json_from_file_path(
|
||||
&package_root_folder.join("package.json"),
|
||||
)
|
||||
.get_closest_package_json(&package_root_folder.join("package.json"))
|
||||
.ok()
|
||||
.flatten()?;
|
||||
let root_folder = package_json.path.parent()?;
|
||||
|
|
|
@ -207,6 +207,8 @@ impl LspScopeResolver {
|
|||
NodeResolutionKind::Execution,
|
||||
)
|
||||
})
|
||||
.ok()?
|
||||
.into_url()
|
||||
.ok()?,
|
||||
))
|
||||
.0;
|
||||
|
@ -257,7 +259,7 @@ impl LspScopeResolver {
|
|||
root_node_modules_dir: byonm_npm_resolver
|
||||
.root_node_modules_path()
|
||||
.map(|p| p.to_path_buf()),
|
||||
sys: CliSys::default(),
|
||||
sys: factory.sys.clone(),
|
||||
pkg_json_resolver: self.pkg_json_resolver.clone(),
|
||||
},
|
||||
)
|
||||
|
@ -522,6 +524,8 @@ impl LspResolver {
|
|||
resolution_mode,
|
||||
NodeResolutionKind::Types,
|
||||
)
|
||||
.ok()?
|
||||
.into_url()
|
||||
.ok()?,
|
||||
)))
|
||||
}
|
||||
|
@ -702,7 +706,7 @@ impl<'a> ResolverFactory<'a> {
|
|||
let sys = CliSys::default();
|
||||
let options = if enable_byonm {
|
||||
CliNpmResolverCreateOptions::Byonm(CliByonmNpmResolverCreateOptions {
|
||||
sys,
|
||||
sys: self.sys.clone(),
|
||||
pkg_json_resolver: self.pkg_json_resolver.clone(),
|
||||
root_node_modules_dir: self.config_data.and_then(|config_data| {
|
||||
config_data.node_modules_dir.clone().or_else(|| {
|
||||
|
|
|
@ -667,7 +667,12 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
ResolutionMode::Import,
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.map_err(|e| JsErrorBox::from_err(e).into());
|
||||
.map_err(|e| JsErrorBox::from_err(e).into())
|
||||
.and_then(|url_or_path| {
|
||||
url_or_path
|
||||
.into_url()
|
||||
.map_err(|e| JsErrorBox::from_err(e).into())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -696,6 +701,8 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
source,
|
||||
})
|
||||
})?
|
||||
.into_url()
|
||||
.map_err(JsErrorBox::from_err)?
|
||||
}
|
||||
Some(Module::Node(module)) => module.specifier.clone(),
|
||||
Some(Module::Js(module)) => module.specifier.clone(),
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
//! Code for local node_modules resolution.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::hash_map::Entry;
|
||||
|
@ -312,7 +313,7 @@ async fn sync_resolution_with_fs(
|
|||
);
|
||||
let sub_node_modules = folder_path.join("node_modules");
|
||||
let package_path =
|
||||
join_package_name(&sub_node_modules, &package.id.nv.name);
|
||||
join_package_name(Cow::Owned(sub_node_modules), &package.id.nv.name);
|
||||
let cache_folder = cache.package_folder_for_nv(&package.id.nv);
|
||||
|
||||
deno_core::unsync::spawn_blocking({
|
||||
|
@ -350,7 +351,7 @@ async fn sync_resolution_with_fs(
|
|||
|
||||
let sub_node_modules = folder_path.join("node_modules");
|
||||
let package_path =
|
||||
join_package_name(&sub_node_modules, &package.id.nv.name);
|
||||
join_package_name(Cow::Owned(sub_node_modules), &package.id.nv.name);
|
||||
lifecycle_scripts.add(package, package_path.into());
|
||||
}
|
||||
|
||||
|
@ -367,14 +368,16 @@ async fn sync_resolution_with_fs(
|
|||
if !initialized_file.exists() {
|
||||
let sub_node_modules = destination_path.join("node_modules");
|
||||
let package_path =
|
||||
join_package_name(&sub_node_modules, &package.id.nv.name);
|
||||
join_package_name(Cow::Owned(sub_node_modules), &package.id.nv.name);
|
||||
|
||||
let source_path = join_package_name(
|
||||
&deno_local_registry_dir
|
||||
.join(get_package_folder_id_folder_name(
|
||||
&package_cache_folder_id.with_no_count(),
|
||||
))
|
||||
.join("node_modules"),
|
||||
Cow::Owned(
|
||||
deno_local_registry_dir
|
||||
.join(get_package_folder_id_folder_name(
|
||||
&package_cache_folder_id.with_no_count(),
|
||||
))
|
||||
.join("node_modules"),
|
||||
),
|
||||
&package.id.nv.name,
|
||||
);
|
||||
|
||||
|
@ -407,14 +410,16 @@ async fn sync_resolution_with_fs(
|
|||
get_package_folder_id_folder_name(&dep_cache_folder_id);
|
||||
if dep_setup_cache.insert(name, &dep_folder_name) {
|
||||
let dep_folder_path = join_package_name(
|
||||
&deno_local_registry_dir
|
||||
.join(dep_folder_name)
|
||||
.join("node_modules"),
|
||||
Cow::Owned(
|
||||
deno_local_registry_dir
|
||||
.join(dep_folder_name)
|
||||
.join("node_modules"),
|
||||
),
|
||||
&dep_id.nv.name,
|
||||
);
|
||||
symlink_package_dir(
|
||||
&dep_folder_path,
|
||||
&join_package_name(&sub_node_modules, name),
|
||||
&join_package_name(Cow::Borrowed(&sub_node_modules), name),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
@ -468,9 +473,11 @@ async fn sync_resolution_with_fs(
|
|||
&remote_pkg.get_package_cache_folder_id(),
|
||||
);
|
||||
let local_registry_package_path = join_package_name(
|
||||
&deno_local_registry_dir
|
||||
.join(&target_folder_name)
|
||||
.join("node_modules"),
|
||||
Cow::Owned(
|
||||
deno_local_registry_dir
|
||||
.join(&target_folder_name)
|
||||
.join("node_modules"),
|
||||
),
|
||||
&remote_pkg.id.nv.name,
|
||||
);
|
||||
if install_in_child {
|
||||
|
@ -496,7 +503,10 @@ async fn sync_resolution_with_fs(
|
|||
{
|
||||
symlink_package_dir(
|
||||
&local_registry_package_path,
|
||||
&join_package_name(root_node_modules_dir_path, remote_alias),
|
||||
&join_package_name(
|
||||
Cow::Borrowed(root_node_modules_dir_path),
|
||||
remote_alias,
|
||||
),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
@ -526,15 +536,20 @@ async fn sync_resolution_with_fs(
|
|||
get_package_folder_id_folder_name(&package.get_package_cache_folder_id());
|
||||
if setup_cache.insert_root_symlink(&id.nv.name, &target_folder_name) {
|
||||
let local_registry_package_path = join_package_name(
|
||||
&deno_local_registry_dir
|
||||
.join(target_folder_name)
|
||||
.join("node_modules"),
|
||||
Cow::Owned(
|
||||
deno_local_registry_dir
|
||||
.join(target_folder_name)
|
||||
.join("node_modules"),
|
||||
),
|
||||
&id.nv.name,
|
||||
);
|
||||
|
||||
symlink_package_dir(
|
||||
&local_registry_package_path,
|
||||
&join_package_name(root_node_modules_dir_path, &id.nv.name),
|
||||
&join_package_name(
|
||||
Cow::Borrowed(root_node_modules_dir_path),
|
||||
&id.nv.name,
|
||||
),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
@ -556,15 +571,20 @@ async fn sync_resolution_with_fs(
|
|||
if setup_cache.insert_deno_symlink(&package.id.nv.name, &target_folder_name)
|
||||
{
|
||||
let local_registry_package_path = join_package_name(
|
||||
&deno_local_registry_dir
|
||||
.join(target_folder_name)
|
||||
.join("node_modules"),
|
||||
Cow::Owned(
|
||||
deno_local_registry_dir
|
||||
.join(target_folder_name)
|
||||
.join("node_modules"),
|
||||
),
|
||||
&package.id.nv.name,
|
||||
);
|
||||
|
||||
symlink_package_dir(
|
||||
&local_registry_package_path,
|
||||
&join_package_name(&deno_node_modules_dir, &package.id.nv.name),
|
||||
&join_package_name(
|
||||
Cow::Borrowed(&deno_node_modules_dir),
|
||||
&package.id.nv.name,
|
||||
),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
@ -986,13 +1006,17 @@ fn junction_or_symlink_dir(
|
|||
}
|
||||
}
|
||||
|
||||
fn join_package_name(path: &Path, package_name: &str) -> PathBuf {
|
||||
let mut path = path.to_path_buf();
|
||||
fn join_package_name(mut path: Cow<Path>, package_name: &str) -> PathBuf {
|
||||
// ensure backslashes are used on windows
|
||||
for part in package_name.split('/') {
|
||||
path = path.join(part);
|
||||
match path {
|
||||
Cow::Borrowed(inner) => path = Cow::Owned(inner.join(part)),
|
||||
Cow::Owned(ref mut path) => {
|
||||
path.push(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
path
|
||||
path.into_owned()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -196,8 +196,8 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?
|
||||
.into_url(),
|
||||
.and_then(|res| res.into_url())
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -225,7 +225,10 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
.map_err(JsErrorBox::from_err)
|
||||
.and_then(|url_or_path| {
|
||||
url_or_path.into_url().map_err(JsErrorBox::from_err)
|
||||
})?,
|
||||
),
|
||||
Ok(MappedResolution::PackageJson {
|
||||
dep_result,
|
||||
|
@ -236,17 +239,22 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
.as_ref()
|
||||
.map_err(|e| JsErrorBox::from_err(e.clone()))?
|
||||
{
|
||||
PackageJsonDepValue::Req(req) => self
|
||||
.shared
|
||||
.npm_req_resolver
|
||||
.resolve_req_with_sub_path(
|
||||
req,
|
||||
sub_path.as_deref(),
|
||||
&referrer,
|
||||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.map_err(|e| JsErrorBox::from_err(e).into()),
|
||||
PackageJsonDepValue::Req(req) => Ok(
|
||||
self
|
||||
.shared
|
||||
.npm_req_resolver
|
||||
.resolve_req_with_sub_path(
|
||||
req,
|
||||
sub_path.as_deref(),
|
||||
&referrer,
|
||||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)
|
||||
.and_then(|url_or_path| {
|
||||
url_or_path.into_url().map_err(JsErrorBox::from_err)
|
||||
})?,
|
||||
),
|
||||
PackageJsonDepValue::Workspace(version_req) => {
|
||||
let pkg_folder = self
|
||||
.shared
|
||||
|
@ -267,7 +275,10 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
.map_err(JsErrorBox::from_err)
|
||||
.and_then(|url_or_path| {
|
||||
url_or_path.into_url().map_err(JsErrorBox::from_err)
|
||||
})?,
|
||||
)
|
||||
}
|
||||
},
|
||||
|
@ -286,7 +297,10 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
.map_err(JsErrorBox::from_err)
|
||||
.and_then(|url_or_path| {
|
||||
url_or_path.into_url().map_err(JsErrorBox::from_err)
|
||||
})?,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -323,7 +337,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
if let Some(res) = maybe_res {
|
||||
return Ok(res.into_url());
|
||||
return Ok(res.into_url().map_err(JsErrorBox::from_err)?);
|
||||
}
|
||||
Err(JsErrorBox::from_err(err).into())
|
||||
}
|
||||
|
|
|
@ -667,7 +667,7 @@ fn resolve_npm_nv_ref(
|
|||
node_resolver::NodeResolutionKind::Types,
|
||||
)
|
||||
.ok()?;
|
||||
Some(resolved)
|
||||
resolved.into_url().ok()
|
||||
}
|
||||
|
||||
/// Matches the `@ts-check` pragma.
|
||||
|
|
|
@ -75,13 +75,17 @@ pub async fn info(
|
|||
target_pkg_json,
|
||||
sub_path,
|
||||
..
|
||||
} => Some(node_resolver.resolve_package_subpath_from_deno_module(
|
||||
target_pkg_json.clone().dir_path(),
|
||||
sub_path.as_deref(),
|
||||
Some(&cwd_url),
|
||||
node_resolver::ResolutionMode::Import,
|
||||
node_resolver::NodeResolutionKind::Execution,
|
||||
)?),
|
||||
} => Some(
|
||||
node_resolver
|
||||
.resolve_package_subpath_from_deno_module(
|
||||
target_pkg_json.clone().dir_path(),
|
||||
sub_path.as_deref(),
|
||||
Some(&cwd_url),
|
||||
node_resolver::ResolutionMode::Import,
|
||||
node_resolver::NodeResolutionKind::Execution,
|
||||
)?
|
||||
.into_url()?,
|
||||
),
|
||||
deno_config::workspace::MappedResolution::PackageJson {
|
||||
alias,
|
||||
sub_path,
|
||||
|
@ -94,13 +98,17 @@ pub async fn info(
|
|||
alias,
|
||||
version_req,
|
||||
)?;
|
||||
Some(node_resolver.resolve_package_subpath_from_deno_module(
|
||||
pkg_folder,
|
||||
sub_path.as_deref(),
|
||||
Some(&cwd_url),
|
||||
node_resolver::ResolutionMode::Import,
|
||||
node_resolver::NodeResolutionKind::Execution,
|
||||
)?)
|
||||
Some(
|
||||
node_resolver
|
||||
.resolve_package_subpath_from_deno_module(
|
||||
pkg_folder,
|
||||
sub_path.as_deref(),
|
||||
Some(&cwd_url),
|
||||
node_resolver::ResolutionMode::Import,
|
||||
node_resolver::NodeResolutionKind::Execution,
|
||||
)?
|
||||
.into_url()?,
|
||||
)
|
||||
}
|
||||
deno_package_json::PackageJsonDepValue::Req(req) => {
|
||||
Some(ModuleSpecifier::parse(&format!(
|
||||
|
|
|
@ -709,6 +709,9 @@ pub enum ResolveError {
|
|||
)]
|
||||
ModuleResolution(#[from] deno_core::ModuleResolutionError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
FilePathToUrl(#[from] deno_path_util::PathToUrlError),
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
PackageSubpathResolve(PackageSubpathResolveError),
|
||||
#[class(inherit)]
|
||||
|
@ -943,7 +946,7 @@ fn resolve_graph_specifier_types(
|
|||
NodeResolutionKind::Types,
|
||||
);
|
||||
let maybe_url = match res_result {
|
||||
Ok(url) => Some(url),
|
||||
Ok(path_or_url) => Some(path_or_url.into_url()?),
|
||||
Err(err) => match err.code() {
|
||||
NodeJsErrorCode::ERR_TYPES_NOT_FOUND
|
||||
| NodeJsErrorCode::ERR_MODULE_NOT_FOUND => None,
|
||||
|
@ -971,6 +974,9 @@ fn resolve_graph_specifier_types(
|
|||
|
||||
#[derive(Debug, Error, deno_error::JsError)]
|
||||
pub enum ResolveNonGraphSpecifierTypesError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
FilePathToUrl(#[from] deno_path_util::PathToUrlError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ResolvePkgFolderFromDenoReq(#[from] ResolvePkgFolderFromDenoReqError),
|
||||
|
@ -1003,8 +1009,8 @@ fn resolve_non_graph_specifier_types(
|
|||
resolution_mode,
|
||||
NodeResolutionKind::Types,
|
||||
)
|
||||
.ok()
|
||||
.map(|res| res.into_url()),
|
||||
.and_then(|res| res.into_url())
|
||||
.ok(),
|
||||
)))
|
||||
} else if let Ok(npm_req_ref) =
|
||||
NpmPackageReqReference::from_str(raw_specifier)
|
||||
|
@ -1025,7 +1031,7 @@ fn resolve_non_graph_specifier_types(
|
|||
NodeResolutionKind::Types,
|
||||
);
|
||||
let maybe_url = match res_result {
|
||||
Ok(url) => Some(url),
|
||||
Ok(url_or_path) => Some(url_or_path.into_url()?),
|
||||
Err(err) => match err.code() {
|
||||
NodeJsErrorCode::ERR_TYPES_NOT_FOUND
|
||||
| NodeJsErrorCode::ERR_MODULE_NOT_FOUND => None,
|
||||
|
|
|
@ -23,6 +23,8 @@ use node_resolver::InNpmPackageChecker;
|
|||
use node_resolver::NodeResolutionKind;
|
||||
use node_resolver::NpmPackageFolderResolver;
|
||||
use node_resolver::ResolutionMode;
|
||||
use node_resolver::UrlOrPath;
|
||||
use node_resolver::UrlOrPathRef;
|
||||
use node_resolver::REQUIRE_CONDITIONS;
|
||||
use sys_traits::FsCanonicalize;
|
||||
use sys_traits::FsMetadata;
|
||||
|
@ -277,11 +279,12 @@ pub fn op_require_resolve_deno_dir<
|
|||
TSys,
|
||||
>>();
|
||||
|
||||
let path = PathBuf::from(parent_filename);
|
||||
Ok(
|
||||
resolver
|
||||
.resolve_package_folder_from_package(
|
||||
&request,
|
||||
&url_from_file_path(&PathBuf::from(parent_filename))?,
|
||||
&UrlOrPathRef::from_path(&path),
|
||||
)
|
||||
.ok()
|
||||
.map(|p| p.to_string_lossy().into_owned()),
|
||||
|
@ -487,9 +490,7 @@ pub fn op_require_try_self<
|
|||
|
||||
let pkg_json_resolver = state.borrow::<PackageJsonResolverRc<TSys>>();
|
||||
let pkg = pkg_json_resolver
|
||||
.get_closest_package_json_from_file_path(&PathBuf::from(
|
||||
parent_path.unwrap(),
|
||||
))
|
||||
.get_closest_package_json(&PathBuf::from(parent_path.unwrap()))
|
||||
.ok()
|
||||
.flatten();
|
||||
if pkg.is_none() {
|
||||
|
@ -515,13 +516,13 @@ pub fn op_require_try_self<
|
|||
return Ok(None);
|
||||
}
|
||||
|
||||
let referrer = deno_core::url::Url::from_file_path(&pkg.path).unwrap();
|
||||
if let Some(exports) = &pkg.exports {
|
||||
let node_resolver = state.borrow::<NodeResolverRc<
|
||||
TInNpmPackageChecker,
|
||||
TNpmPackageFolderResolver,
|
||||
TSys,
|
||||
>>();
|
||||
let referrer = UrlOrPathRef::from_path(&pkg.path);
|
||||
let r = node_resolver.package_exports_resolve(
|
||||
&pkg.path,
|
||||
&expansion,
|
||||
|
@ -531,11 +532,7 @@ pub fn op_require_try_self<
|
|||
REQUIRE_CONDITIONS,
|
||||
NodeResolutionKind::Execution,
|
||||
)?;
|
||||
Ok(Some(if r.scheme() == "file" {
|
||||
url_to_file_path_string(&r)?
|
||||
} else {
|
||||
r.to_string()
|
||||
}))
|
||||
Ok(Some(url_or_path_to_string(r)?))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
@ -627,22 +624,21 @@ pub fn op_require_resolve_exports<
|
|||
let referrer = if parent_path.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(Url::from_file_path(parent_path).unwrap())
|
||||
Some(PathBuf::from(parent_path))
|
||||
};
|
||||
let r = node_resolver.package_exports_resolve(
|
||||
&pkg.path,
|
||||
&format!(".{expansion}"),
|
||||
exports,
|
||||
referrer.as_ref(),
|
||||
referrer
|
||||
.as_ref()
|
||||
.map(|r| UrlOrPathRef::from_path(r))
|
||||
.as_ref(),
|
||||
ResolutionMode::Require,
|
||||
REQUIRE_CONDITIONS,
|
||||
NodeResolutionKind::Execution,
|
||||
)?;
|
||||
Ok(Some(if r.scheme() == "file" {
|
||||
url_to_file_path_string(&r)?
|
||||
} else {
|
||||
r.to_string()
|
||||
}))
|
||||
Ok(Some(url_or_path_to_string(r)?))
|
||||
}
|
||||
|
||||
deno_error::js_error_wrapper!(
|
||||
|
@ -701,8 +697,7 @@ pub fn op_require_package_imports_resolve<
|
|||
let referrer_path = ensure_read_permission::<P>(state, &referrer_path)
|
||||
.map_err(RequireErrorKind::Permission)?;
|
||||
let pkg_json_resolver = state.borrow::<PackageJsonResolverRc<TSys>>();
|
||||
let Some(pkg) = pkg_json_resolver
|
||||
.get_closest_package_json_from_file_path(&referrer_path)?
|
||||
let Some(pkg) = pkg_json_resolver.get_closest_package_json(&referrer_path)?
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
@ -713,16 +708,15 @@ pub fn op_require_package_imports_resolve<
|
|||
TNpmPackageFolderResolver,
|
||||
TSys,
|
||||
>>();
|
||||
let referrer_url = Url::from_file_path(&referrer_filename).unwrap();
|
||||
let url = node_resolver.package_imports_resolve(
|
||||
&request,
|
||||
Some(&referrer_url),
|
||||
Some(&UrlOrPathRef::from_path(&referrer_path)),
|
||||
ResolutionMode::Require,
|
||||
Some(&pkg),
|
||||
REQUIRE_CONDITIONS,
|
||||
NodeResolutionKind::Execution,
|
||||
)?;
|
||||
Ok(Some(url_to_file_path_string(&url)?))
|
||||
Ok(Some(url_or_path_to_string(url)?))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
@ -738,11 +732,6 @@ pub fn op_require_break_on_next_statement(state: Rc<RefCell<OpState>>) {
|
|||
inspector.wait_for_session_and_break_on_next_statement()
|
||||
}
|
||||
|
||||
fn url_to_file_path_string(url: &Url) -> Result<String, RequireError> {
|
||||
let file_path = url_to_file_path(url)?;
|
||||
Ok(file_path.to_string_lossy().into_owned())
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_require_can_parse_as_esm(
|
||||
scope: &mut v8::HandleScope,
|
||||
|
@ -768,3 +757,13 @@ pub fn op_require_can_parse_as_esm(
|
|||
let mut source = v8::script_compiler::Source::new(source, Some(&origin));
|
||||
v8::script_compiler::compile_module(scope, &mut source).is_some()
|
||||
}
|
||||
|
||||
fn url_or_path_to_string(
|
||||
url: UrlOrPath,
|
||||
) -> Result<String, deno_path_util::UrlToFilePathError> {
|
||||
if url.is_file() {
|
||||
Ok(url.into_path()?.to_string_lossy().to_string())
|
||||
} else {
|
||||
Ok(url.to_string_lossy().to_string())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -267,8 +267,11 @@ impl<TInNpmPackageChecker: InNpmPackageChecker, TSys: FsRead>
|
|||
specifier: &Url,
|
||||
) -> Result<ResolutionMode, ClosestPkgJsonError> {
|
||||
if self.in_npm_pkg_checker.in_npm_package(specifier) {
|
||||
let Ok(path) = deno_path_util::url_to_file_path(specifier) else {
|
||||
return Ok(ResolutionMode::Require);
|
||||
};
|
||||
if let Some(pkg_json) =
|
||||
self.pkg_json_resolver.get_closest_package_json(specifier)?
|
||||
self.pkg_json_resolver.get_closest_package_json(&path)?
|
||||
{
|
||||
let is_file_location_cjs = pkg_json.typ != "module";
|
||||
Ok(if is_file_location_cjs {
|
||||
|
@ -280,8 +283,11 @@ impl<TInNpmPackageChecker: InNpmPackageChecker, TSys: FsRead>
|
|||
Ok(ResolutionMode::Require)
|
||||
}
|
||||
} else if self.mode != IsCjsResolutionMode::Disabled {
|
||||
let Ok(path) = deno_path_util::url_to_file_path(specifier) else {
|
||||
return Ok(ResolutionMode::Import);
|
||||
};
|
||||
if let Some(pkg_json) =
|
||||
self.pkg_json_resolver.get_closest_package_json(specifier)?
|
||||
self.pkg_json_resolver.get_closest_package_json(&path)?
|
||||
{
|
||||
let is_cjs_type = pkg_json.typ == "commonjs"
|
||||
|| self.mode == IsCjsResolutionMode::ImplicitTypeCommonJs
|
||||
|
|
|
@ -639,7 +639,6 @@ impl<
|
|||
options: ResolverFactoryOptions,
|
||||
) -> Self {
|
||||
Self {
|
||||
options,
|
||||
deno_resolver: Default::default(),
|
||||
in_npm_package_checker: Default::default(),
|
||||
node_resolver: Default::default(),
|
||||
|
@ -650,6 +649,7 @@ impl<
|
|||
sloppy_imports_resolver: Default::default(),
|
||||
workspace_factory,
|
||||
workspace_resolver: Default::default(),
|
||||
options,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,9 @@ pub enum DenoResolveErrorKind {
|
|||
PackageSubpathResolve(#[from] PackageSubpathResolveError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
PathToUrl(#[from] deno_path_util::PathToUrlError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ResolvePkgFolderFromDenoReq(#[from] ResolvePkgFolderFromDenoReqError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
|
@ -252,10 +255,12 @@ impl<
|
|||
{
|
||||
return node_resolver
|
||||
.resolve(raw_specifier, referrer, resolution_mode, resolution_kind)
|
||||
.map(|res| DenoResolution {
|
||||
url: res.into_url(),
|
||||
found_package_json_dep,
|
||||
maybe_diagnostic,
|
||||
.and_then(|res| {
|
||||
Ok(DenoResolution {
|
||||
url: res.into_url()?,
|
||||
found_package_json_dep,
|
||||
maybe_diagnostic,
|
||||
})
|
||||
})
|
||||
.map_err(|e| e.into());
|
||||
}
|
||||
|
@ -318,7 +323,8 @@ impl<
|
|||
resolution_mode,
|
||||
resolution_kind,
|
||||
)
|
||||
.map_err(|e| e.into()),
|
||||
.map_err(DenoResolveError::from)
|
||||
.and_then(|r| Ok(r.into_url()?)),
|
||||
MappedResolution::PackageJson {
|
||||
dep_result,
|
||||
alias,
|
||||
|
@ -372,7 +378,8 @@ impl<
|
|||
.map_err(|e| {
|
||||
DenoResolveErrorKind::PackageSubpathResolve(e).into_box()
|
||||
})
|
||||
}),
|
||||
})
|
||||
.and_then(|r| Ok(r.into_url()?)),
|
||||
})
|
||||
}
|
||||
},
|
||||
|
@ -425,12 +432,14 @@ impl<
|
|||
resolution_mode,
|
||||
resolution_kind,
|
||||
)
|
||||
.map(|url| DenoResolution {
|
||||
url,
|
||||
maybe_diagnostic,
|
||||
found_package_json_dep,
|
||||
})
|
||||
.map_err(|e| e.into());
|
||||
.map_err(DenoResolveError::from)
|
||||
.and_then(|url_or_path| {
|
||||
Ok(DenoResolution {
|
||||
url: url_or_path.into_url()?,
|
||||
maybe_diagnostic,
|
||||
found_package_json_dep,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// do npm resolution for byonm
|
||||
|
@ -442,11 +451,6 @@ impl<
|
|||
resolution_mode,
|
||||
resolution_kind,
|
||||
)
|
||||
.map(|url| DenoResolution {
|
||||
url,
|
||||
maybe_diagnostic,
|
||||
found_package_json_dep,
|
||||
})
|
||||
.map_err(|err| {
|
||||
match err.into_kind() {
|
||||
ResolveReqWithSubPathErrorKind::MissingPackageNodeModulesFolder(
|
||||
|
@ -459,7 +463,12 @@ impl<
|
|||
err.into()
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.and_then(|url_or_path| Ok(DenoResolution {
|
||||
url: url_or_path.into_url()?,
|
||||
maybe_diagnostic,
|
||||
found_package_json_dep,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -491,9 +500,9 @@ impl<
|
|||
})?;
|
||||
if let Some(res) = maybe_resolution {
|
||||
match res {
|
||||
NodeResolution::Module(url) => {
|
||||
NodeResolution::Module(ref _url) => {
|
||||
return Ok(DenoResolution {
|
||||
url,
|
||||
url: res.into_url()?,
|
||||
maybe_diagnostic,
|
||||
found_package_json_dep,
|
||||
})
|
||||
|
|
|
@ -18,6 +18,7 @@ use node_resolver::errors::PackageNotFoundError;
|
|||
use node_resolver::InNpmPackageChecker;
|
||||
use node_resolver::NpmPackageFolderResolver;
|
||||
use node_resolver::PackageJsonResolverRc;
|
||||
use node_resolver::UrlOrPathRef;
|
||||
use sys_traits::FsCanonicalize;
|
||||
use sys_traits::FsDirEntry;
|
||||
use sys_traits::FsMetadata;
|
||||
|
@ -141,7 +142,7 @@ impl<TSys: FsCanonicalize + FsRead + FsMetadata + FsReadDir>
|
|||
) -> std::io::Result<Option<PathBuf>> {
|
||||
for ancestor in start_dir.ancestors() {
|
||||
let node_modules_folder = ancestor.join("node_modules");
|
||||
let sub_dir = join_package_name(&node_modules_folder, alias);
|
||||
let sub_dir = join_package_name(Cow::Owned(node_modules_folder), alias);
|
||||
if sys.fs_is_dir_no_err(&sub_dir) {
|
||||
return Ok(Some(
|
||||
deno_path_util::fs::canonicalize_path_maybe_not_exists(
|
||||
|
@ -368,7 +369,7 @@ impl<TSys: FsCanonicalize + FsRead + FsMetadata + FsReadDir>
|
|||
|
||||
best_version.map(|(_version, entry_name)| {
|
||||
join_package_name(
|
||||
&node_modules_deno_dir.join(entry_name).join("node_modules"),
|
||||
Cow::Owned(node_modules_deno_dir.join(entry_name).join("node_modules")),
|
||||
&req.name,
|
||||
)
|
||||
})
|
||||
|
@ -381,14 +382,14 @@ impl<TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir>
|
|||
fn resolve_package_folder_from_package(
|
||||
&self,
|
||||
name: &str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
) -> Result<PathBuf, PackageFolderResolveError> {
|
||||
fn inner<TSys: FsMetadata>(
|
||||
sys: &TSys,
|
||||
name: &str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
) -> Result<PathBuf, PackageFolderResolveError> {
|
||||
let maybe_referrer_file = url_to_file_path(referrer).ok();
|
||||
let maybe_referrer_file = referrer.path().ok();
|
||||
let maybe_start_folder =
|
||||
maybe_referrer_file.as_ref().and_then(|f| f.parent());
|
||||
if let Some(start_folder) = maybe_start_folder {
|
||||
|
@ -400,7 +401,7 @@ impl<TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir>
|
|||
Cow::Owned(current_folder.join("node_modules"))
|
||||
};
|
||||
|
||||
let sub_dir = join_package_name(&node_modules_folder, name);
|
||||
let sub_dir = join_package_name(node_modules_folder, name);
|
||||
if sys.fs_is_dir_no_err(&sub_dir) {
|
||||
return Ok(sub_dir);
|
||||
}
|
||||
|
@ -410,7 +411,7 @@ impl<TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir>
|
|||
Err(
|
||||
PackageNotFoundError {
|
||||
package_name: name.to_string(),
|
||||
referrer: referrer.clone(),
|
||||
referrer: referrer.display(),
|
||||
referrer_extra: None,
|
||||
}
|
||||
.into(),
|
||||
|
@ -421,7 +422,7 @@ impl<TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir>
|
|||
self.sys.fs_canonicalize(&path).map_err(|err| {
|
||||
PackageFolderResolveIoError {
|
||||
package_name: name.to_string(),
|
||||
referrer: referrer.clone(),
|
||||
referrer: referrer.display(),
|
||||
source: err,
|
||||
}
|
||||
.into()
|
||||
|
@ -442,11 +443,15 @@ impl InNpmPackageChecker for ByonmInNpmPackageChecker {
|
|||
}
|
||||
}
|
||||
|
||||
fn join_package_name(path: &Path, package_name: &str) -> PathBuf {
|
||||
let mut path = path.to_path_buf();
|
||||
fn join_package_name(mut path: Cow<Path>, package_name: &str) -> PathBuf {
|
||||
// ensure backslashes are used on windows
|
||||
for part in package_name.split('/') {
|
||||
path = path.join(part);
|
||||
match path {
|
||||
Cow::Borrowed(inner) => path = Cow::Owned(inner.join(part)),
|
||||
Cow::Owned(ref mut path) => {
|
||||
path.push(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
path
|
||||
path.into_owned()
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use std::path::PathBuf;
|
|||
use deno_npm::NpmPackageCacheFolderId;
|
||||
use deno_npm::NpmPackageId;
|
||||
use node_resolver::NpmPackageFolderResolver;
|
||||
use node_resolver::UrlOrPathRef;
|
||||
use sys_traits::FsCanonicalize;
|
||||
use sys_traits::FsMetadata;
|
||||
use url::Url;
|
||||
|
@ -60,7 +61,7 @@ impl<TSys: FsCanonicalize + FsMetadata> NpmPackageFolderResolver
|
|||
fn resolve_package_folder_from_package(
|
||||
&self,
|
||||
specifier: &str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
) -> Result<PathBuf, node_resolver::errors::PackageFolderResolveError> {
|
||||
match self {
|
||||
NpmPackageFsResolver::Local(r) => {
|
||||
|
|
|
@ -13,6 +13,7 @@ use node_resolver::errors::PackageFolderResolveError;
|
|||
use node_resolver::errors::PackageNotFoundError;
|
||||
use node_resolver::errors::ReferrerNotFoundError;
|
||||
use node_resolver::NpmPackageFolderResolver;
|
||||
use node_resolver::UrlOrPathRef;
|
||||
use url::Url;
|
||||
|
||||
use super::resolution::NpmResolutionCellRc;
|
||||
|
@ -83,15 +84,15 @@ impl NpmPackageFolderResolver for GlobalNpmPackageResolver {
|
|||
fn resolve_package_folder_from_package(
|
||||
&self,
|
||||
name: &str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
) -> Result<PathBuf, PackageFolderResolveError> {
|
||||
use deno_npm::resolution::PackageNotFoundFromReferrerError;
|
||||
let Some(referrer_cache_folder_id) =
|
||||
self.resolve_package_cache_folder_id_from_specifier_inner(referrer)
|
||||
let Some(referrer_cache_folder_id) = self
|
||||
.resolve_package_cache_folder_id_from_specifier_inner(referrer.url()?)
|
||||
else {
|
||||
return Err(
|
||||
ReferrerNotFoundError {
|
||||
referrer: referrer.clone(),
|
||||
referrer: referrer.display(),
|
||||
referrer_extra: None,
|
||||
}
|
||||
.into(),
|
||||
|
@ -106,7 +107,7 @@ impl NpmPackageFolderResolver for GlobalNpmPackageResolver {
|
|||
None => Err(
|
||||
PackageNotFoundError {
|
||||
package_name: name.to_string(),
|
||||
referrer: referrer.clone(),
|
||||
referrer: referrer.display(),
|
||||
referrer_extra: Some(format!(
|
||||
"{} -> {}",
|
||||
referrer_cache_folder_id,
|
||||
|
@ -119,7 +120,7 @@ impl NpmPackageFolderResolver for GlobalNpmPackageResolver {
|
|||
Err(err) => match *err {
|
||||
PackageNotFoundFromReferrerError::Referrer(cache_folder_id) => Err(
|
||||
ReferrerNotFoundError {
|
||||
referrer: referrer.clone(),
|
||||
referrer: referrer.display(),
|
||||
referrer_extra: Some(cache_folder_id.to_string()),
|
||||
}
|
||||
.into(),
|
||||
|
@ -130,7 +131,7 @@ impl NpmPackageFolderResolver for GlobalNpmPackageResolver {
|
|||
} => Err(
|
||||
PackageNotFoundError {
|
||||
package_name: name,
|
||||
referrer: referrer.clone(),
|
||||
referrer: referrer.display(),
|
||||
referrer_extra: Some(cache_folder_id_referrer.to_string()),
|
||||
}
|
||||
.into(),
|
||||
|
|
|
@ -15,6 +15,7 @@ use node_resolver::errors::PackageFolderResolveIoError;
|
|||
use node_resolver::errors::PackageNotFoundError;
|
||||
use node_resolver::errors::ReferrerNotFoundError;
|
||||
use node_resolver::NpmPackageFolderResolver;
|
||||
use node_resolver::UrlOrPathRef;
|
||||
use sys_traits::FsCanonicalize;
|
||||
use sys_traits::FsMetadata;
|
||||
use url::Url;
|
||||
|
@ -149,19 +150,19 @@ impl<TSys: FsCanonicalize + FsMetadata> NpmPackageFolderResolver
|
|||
fn resolve_package_folder_from_package(
|
||||
&self,
|
||||
name: &str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
) -> Result<PathBuf, PackageFolderResolveError> {
|
||||
let maybe_local_path = self
|
||||
.resolve_folder_for_specifier(referrer)
|
||||
.resolve_folder_for_specifier(referrer.url()?)
|
||||
.map_err(|err| PackageFolderResolveIoError {
|
||||
package_name: name.to_string(),
|
||||
referrer: referrer.clone(),
|
||||
source: err,
|
||||
})?;
|
||||
package_name: name.to_string(),
|
||||
referrer: referrer.display(),
|
||||
source: err,
|
||||
})?;
|
||||
let Some(local_path) = maybe_local_path else {
|
||||
return Err(
|
||||
ReferrerNotFoundError {
|
||||
referrer: referrer.clone(),
|
||||
referrer: referrer.display(),
|
||||
referrer_extra: None,
|
||||
}
|
||||
.into(),
|
||||
|
@ -182,7 +183,7 @@ impl<TSys: FsCanonicalize + FsMetadata> NpmPackageFolderResolver
|
|||
return Ok(self.sys.fs_canonicalize(&sub_dir).map_err(|err| {
|
||||
PackageFolderResolveIoError {
|
||||
package_name: name.to_string(),
|
||||
referrer: referrer.clone(),
|
||||
referrer: referrer.display(),
|
||||
source: err,
|
||||
}
|
||||
})?);
|
||||
|
@ -196,7 +197,7 @@ impl<TSys: FsCanonicalize + FsMetadata> NpmPackageFolderResolver
|
|||
Err(
|
||||
PackageNotFoundError {
|
||||
package_name: name.to_string(),
|
||||
referrer: referrer.clone(),
|
||||
referrer: referrer.display(),
|
||||
referrer_extra: None,
|
||||
}
|
||||
.into(),
|
||||
|
|
|
@ -19,6 +19,7 @@ use deno_semver::package::PackageNv;
|
|||
use deno_semver::package::PackageReq;
|
||||
use node_resolver::InNpmPackageChecker;
|
||||
use node_resolver::NpmPackageFolderResolver;
|
||||
use node_resolver::UrlOrPathRef;
|
||||
use sys_traits::FsCanonicalize;
|
||||
use sys_traits::FsMetadata;
|
||||
use url::Url;
|
||||
|
@ -242,7 +243,7 @@ impl<TSys: FsCanonicalize + FsMetadata> NpmPackageFolderResolver
|
|||
fn resolve_package_folder_from_package(
|
||||
&self,
|
||||
specifier: &str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
) -> Result<PathBuf, node_resolver::errors::PackageFolderResolveError> {
|
||||
let path = self
|
||||
.fs_resolver
|
||||
|
@ -250,7 +251,7 @@ impl<TSys: FsCanonicalize + FsMetadata> NpmPackageFolderResolver
|
|||
log::debug!(
|
||||
"Resolved {} from {} to {}",
|
||||
specifier,
|
||||
referrer,
|
||||
referrer.display(),
|
||||
path.display()
|
||||
);
|
||||
Ok(path)
|
||||
|
|
|
@ -22,6 +22,8 @@ use node_resolver::NodeResolutionKind;
|
|||
use node_resolver::NodeResolverRc;
|
||||
use node_resolver::NpmPackageFolderResolver;
|
||||
use node_resolver::ResolutionMode;
|
||||
use node_resolver::UrlOrPath;
|
||||
use node_resolver::UrlOrPathRef;
|
||||
use sys_traits::FsCanonicalize;
|
||||
use sys_traits::FsMetadata;
|
||||
use sys_traits::FsRead;
|
||||
|
@ -234,7 +236,7 @@ impl<TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir>
|
|||
fn resolve_package_folder_from_package(
|
||||
&self,
|
||||
specifier: &str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
) -> Result<PathBuf, node_resolver::errors::PackageFolderResolveError> {
|
||||
match self {
|
||||
NpmResolver::Byonm(byonm_resolver) => {
|
||||
|
@ -331,7 +333,7 @@ impl<
|
|||
referrer: &Url,
|
||||
resolution_mode: ResolutionMode,
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, ResolveReqWithSubPathError> {
|
||||
) -> Result<UrlOrPath, ResolveReqWithSubPathError> {
|
||||
self.resolve_req_with_sub_path(
|
||||
req_ref.req(),
|
||||
req_ref.sub_path(),
|
||||
|
@ -348,7 +350,7 @@ impl<
|
|||
referrer: &Url,
|
||||
resolution_mode: ResolutionMode,
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, ResolveReqWithSubPathError> {
|
||||
) -> Result<UrlOrPath, ResolveReqWithSubPathError> {
|
||||
let package_folder = self
|
||||
.npm_resolver
|
||||
.resolve_pkg_folder_from_deno_module_req(req, referrer)?;
|
||||
|
@ -398,6 +400,8 @@ impl<
|
|||
| NodeResolveErrorKind::PackageImportsResolve(_)
|
||||
| NodeResolveErrorKind::UnsupportedEsmUrlScheme(_)
|
||||
| NodeResolveErrorKind::DataUrlReferrer(_)
|
||||
| NodeResolveErrorKind::PathToUrl(_)
|
||||
| NodeResolveErrorKind::UrlToFilePath(_)
|
||||
| NodeResolveErrorKind::TypesNotFound(_)
|
||||
| NodeResolveErrorKind::FinalizeResolution(_) => Err(
|
||||
ResolveIfForNpmPackageErrorKind::NodeResolve(err.into()).into_box(),
|
||||
|
@ -405,6 +409,12 @@ impl<
|
|||
NodeResolveErrorKind::PackageResolve(err) => {
|
||||
let err = err.into_kind();
|
||||
match err {
|
||||
PackageResolveErrorKind::UrlToFilePath(err) => Err(
|
||||
ResolveIfForNpmPackageErrorKind::NodeResolve(
|
||||
NodeResolveErrorKind::UrlToFilePath(err).into_box(),
|
||||
)
|
||||
.into_box(),
|
||||
),
|
||||
PackageResolveErrorKind::ClosestPkgJson(_)
|
||||
| PackageResolveErrorKind::InvalidModuleSpecifier(_)
|
||||
| PackageResolveErrorKind::ExportsResolve(_)
|
||||
|
@ -416,6 +426,12 @@ impl<
|
|||
),
|
||||
PackageResolveErrorKind::PackageFolderResolve(err) => {
|
||||
match err.as_kind() {
|
||||
PackageFolderResolveErrorKind::PathToUrl(err) => Err(
|
||||
ResolveIfForNpmPackageErrorKind::NodeResolve(
|
||||
NodeResolveErrorKind::PathToUrl(err.clone()).into_box(),
|
||||
)
|
||||
.into_box(),
|
||||
),
|
||||
PackageFolderResolveErrorKind::Io(
|
||||
PackageFolderResolveIoError { package_name, .. },
|
||||
)
|
||||
|
|
|
@ -20,6 +20,7 @@ sync = ["deno_package_json/sync"]
|
|||
anyhow.workspace = true
|
||||
async-trait.workspace = true
|
||||
boxed_error.workspace = true
|
||||
dashmap.workspace = true
|
||||
deno_error.workspace = true
|
||||
deno_package_json.workspace = true
|
||||
deno_path_util.workspace = true
|
||||
|
|
|
@ -7,7 +7,6 @@ use std::path::Path;
|
|||
use std::path::PathBuf;
|
||||
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_path_util::url_from_file_path;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use futures::future::LocalBoxFuture;
|
||||
use futures::stream::FuturesUnordered;
|
||||
|
@ -29,6 +28,8 @@ use crate::NpmPackageFolderResolver;
|
|||
use crate::PackageJsonResolverRc;
|
||||
use crate::PathClean;
|
||||
use crate::ResolutionMode;
|
||||
use crate::UrlOrPath;
|
||||
use crate::UrlOrPathRef;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CjsAnalysis<'a> {
|
||||
|
@ -253,14 +254,21 @@ impl<
|
|||
errors: &mut Vec<JsErrorBox>| {
|
||||
// 1. Resolve the re-exports and start a future to analyze each one
|
||||
for reexport in reexports {
|
||||
let result = self.resolve(
|
||||
&reexport,
|
||||
&referrer,
|
||||
// FIXME(bartlomieju): check if these conditions are okay, probably
|
||||
// should be `deno-require`, because `deno` is already used in `esm_resolver.rs`
|
||||
&["deno", "node", "require", "default"],
|
||||
NodeResolutionKind::Execution,
|
||||
);
|
||||
let result = self
|
||||
.resolve(
|
||||
&reexport,
|
||||
&referrer,
|
||||
// FIXME(bartlomieju): check if these conditions are okay, probably
|
||||
// should be `deno-require`, because `deno` is already used in `esm_resolver.rs`
|
||||
&["deno", "node", "require", "default"],
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.and_then(|value| {
|
||||
value
|
||||
.map(|url_or_path| url_or_path.into_url())
|
||||
.transpose()
|
||||
.map_err(JsErrorBox::from_err)
|
||||
});
|
||||
let reexport_specifier = match result {
|
||||
Ok(Some(specifier)) => specifier,
|
||||
Ok(None) => continue,
|
||||
|
@ -355,18 +363,18 @@ impl<
|
|||
referrer: &Url,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Option<Url>, JsErrorBox> {
|
||||
) -> Result<Option<UrlOrPath>, JsErrorBox> {
|
||||
if specifier.starts_with('/') {
|
||||
todo!();
|
||||
}
|
||||
|
||||
let referrer_path = url_to_file_path(referrer).unwrap();
|
||||
let referrer = UrlOrPathRef::from_url(referrer);
|
||||
let referrer_path = referrer.path().unwrap();
|
||||
if specifier.starts_with("./") || specifier.starts_with("../") {
|
||||
if let Some(parent) = referrer_path.parent() {
|
||||
return self
|
||||
.file_extension_probe(parent.join(specifier), &referrer_path)
|
||||
.and_then(|p| url_from_file_path(&p).map_err(JsErrorBox::from_err))
|
||||
.map(Some);
|
||||
.file_extension_probe(parent.join(specifier), referrer_path)
|
||||
.map(|p| Some(UrlOrPath::Path(p)));
|
||||
} else {
|
||||
todo!();
|
||||
}
|
||||
|
@ -376,20 +384,21 @@ impl<
|
|||
let (package_specifier, package_subpath) =
|
||||
parse_specifier(specifier).unwrap();
|
||||
|
||||
let module_dir = match self
|
||||
.npm_resolver
|
||||
.resolve_package_folder_from_package(package_specifier.as_str(), referrer)
|
||||
{
|
||||
Err(err)
|
||||
if matches!(
|
||||
err.as_kind(),
|
||||
crate::errors::PackageFolderResolveErrorKind::PackageNotFound(..)
|
||||
) =>
|
||||
{
|
||||
return Ok(None);
|
||||
}
|
||||
other => other.map_err(JsErrorBox::from_err)?,
|
||||
};
|
||||
let module_dir =
|
||||
match self.npm_resolver.resolve_package_folder_from_package(
|
||||
package_specifier.as_str(),
|
||||
&referrer,
|
||||
) {
|
||||
Err(err)
|
||||
if matches!(
|
||||
err.as_kind(),
|
||||
crate::errors::PackageFolderResolveErrorKind::PackageNotFound(..)
|
||||
) =>
|
||||
{
|
||||
return Ok(None);
|
||||
}
|
||||
other => other.map_err(JsErrorBox::from_err)?,
|
||||
};
|
||||
|
||||
let package_json_path = module_dir.join("package.json");
|
||||
let maybe_package_json = self
|
||||
|
@ -405,7 +414,7 @@ impl<
|
|||
&package_json_path,
|
||||
&package_subpath,
|
||||
exports,
|
||||
Some(referrer),
|
||||
Some(&referrer),
|
||||
ResolutionMode::Import,
|
||||
conditions,
|
||||
resolution_kind,
|
||||
|
@ -429,39 +438,26 @@ impl<
|
|||
if let Some(main) =
|
||||
package_json.main(deno_package_json::NodeModuleKind::Cjs)
|
||||
{
|
||||
return Ok(Some(
|
||||
url_from_file_path(&d.join(main).clean())
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
));
|
||||
return Ok(Some(UrlOrPath::Path(d.join(main).clean())));
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(Some(
|
||||
url_from_file_path(&d.join("index.js").clean())
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
));
|
||||
return Ok(Some(UrlOrPath::Path(d.join("index.js").clean())));
|
||||
}
|
||||
return self
|
||||
.file_extension_probe(d, &referrer_path)
|
||||
.and_then(|p| url_from_file_path(&p).map_err(JsErrorBox::from_err))
|
||||
.map(Some);
|
||||
.file_extension_probe(d, referrer_path)
|
||||
.map(|p| Some(UrlOrPath::Path(p)));
|
||||
} else if let Some(main) =
|
||||
package_json.main(deno_package_json::NodeModuleKind::Cjs)
|
||||
{
|
||||
return Ok(Some(
|
||||
url_from_file_path(&module_dir.join(main).clean())
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
));
|
||||
return Ok(Some(UrlOrPath::Path(module_dir.join(main).clean())));
|
||||
} else {
|
||||
return Ok(Some(
|
||||
url_from_file_path(&module_dir.join("index.js").clean())
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
));
|
||||
return Ok(Some(UrlOrPath::Path(module_dir.join("index.js").clean())));
|
||||
}
|
||||
}
|
||||
|
||||
// as a fallback, attempt to resolve it via the ancestor directories
|
||||
let mut last = referrer_path.as_path();
|
||||
let mut last = referrer_path;
|
||||
while let Some(parent) = last.parent() {
|
||||
if !self.in_npm_pkg_checker.in_npm_package_at_dir_path(parent) {
|
||||
break;
|
||||
|
@ -471,15 +467,13 @@ impl<
|
|||
} else {
|
||||
parent.join("node_modules").join(specifier)
|
||||
};
|
||||
if let Ok(path) = self.file_extension_probe(path, &referrer_path) {
|
||||
return Ok(Some(
|
||||
url_from_file_path(&path).map_err(JsErrorBox::from_err)?,
|
||||
));
|
||||
if let Ok(path) = self.file_extension_probe(path, referrer_path) {
|
||||
return Ok(Some(UrlOrPath::Path(path)));
|
||||
}
|
||||
last = parent;
|
||||
}
|
||||
|
||||
Err(not_found(specifier, &referrer_path))
|
||||
Err(not_found(specifier, referrer_path))
|
||||
}
|
||||
|
||||
fn file_extension_probe(
|
||||
|
|
|
@ -6,9 +6,11 @@ use std::path::PathBuf;
|
|||
|
||||
use boxed_error::Boxed;
|
||||
use deno_error::JsError;
|
||||
use deno_path_util::UrlToFilePathError;
|
||||
use thiserror::Error;
|
||||
use url::Url;
|
||||
|
||||
use crate::path::UrlOrPath;
|
||||
use crate::NodeResolutionKind;
|
||||
use crate::ResolutionMode;
|
||||
|
||||
|
@ -24,6 +26,7 @@ pub enum NodeJsErrorCode {
|
|||
ERR_UNKNOWN_FILE_EXTENSION,
|
||||
ERR_UNSUPPORTED_DIR_IMPORT,
|
||||
ERR_UNSUPPORTED_ESM_URL_SCHEME,
|
||||
ERR_INVALID_FILE_URL_PATH,
|
||||
/// Deno specific since Node doesn't support TypeScript.
|
||||
ERR_TYPES_NOT_FOUND,
|
||||
}
|
||||
|
@ -48,6 +51,7 @@ impl NodeJsErrorCode {
|
|||
ERR_UNSUPPORTED_DIR_IMPORT => "ERR_UNSUPPORTED_DIR_IMPORT",
|
||||
ERR_UNSUPPORTED_ESM_URL_SCHEME => "ERR_UNSUPPORTED_ESM_URL_SCHEME",
|
||||
ERR_TYPES_NOT_FOUND => "ERR_TYPES_NOT_FOUND",
|
||||
ERR_INVALID_FILE_URL_PATH => "ERR_INVALID_FILE_URL_PATH",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +113,7 @@ impl NodeJsErrorCoded for LegacyResolveError {
|
|||
#[class(generic)]
|
||||
pub struct PackageNotFoundError {
|
||||
pub package_name: String,
|
||||
pub referrer: Url,
|
||||
pub referrer: UrlOrPath,
|
||||
/// Extra information about the referrer.
|
||||
pub referrer_extra: Option<String>,
|
||||
}
|
||||
|
@ -128,7 +132,7 @@ impl NodeJsErrorCoded for PackageNotFoundError {
|
|||
)]
|
||||
#[class(generic)]
|
||||
pub struct ReferrerNotFoundError {
|
||||
pub referrer: Url,
|
||||
pub referrer: UrlOrPath,
|
||||
/// Extra information about the referrer.
|
||||
pub referrer_extra: Option<String>,
|
||||
}
|
||||
|
@ -144,7 +148,7 @@ impl NodeJsErrorCoded for ReferrerNotFoundError {
|
|||
#[error("Failed resolving '{package_name}' from referrer '{referrer}'.")]
|
||||
pub struct PackageFolderResolveIoError {
|
||||
pub package_name: String,
|
||||
pub referrer: Url,
|
||||
pub referrer: UrlOrPath,
|
||||
#[source]
|
||||
#[inherit]
|
||||
pub source: std::io::Error,
|
||||
|
@ -162,6 +166,9 @@ impl NodeJsErrorCoded for PackageFolderResolveError {
|
|||
PackageFolderResolveErrorKind::PackageNotFound(e) => e.code(),
|
||||
PackageFolderResolveErrorKind::ReferrerNotFound(e) => e.code(),
|
||||
PackageFolderResolveErrorKind::Io(e) => e.code(),
|
||||
PackageFolderResolveErrorKind::PathToUrl(_) => {
|
||||
NodeJsErrorCode::ERR_INVALID_FILE_URL_PATH
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -180,6 +187,9 @@ pub enum PackageFolderResolveErrorKind {
|
|||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Io(#[from] PackageFolderResolveIoError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
PathToUrl(#[from] deno_path_util::PathToUrlError),
|
||||
}
|
||||
|
||||
impl NodeJsErrorCoded for PackageSubpathResolveError {
|
||||
|
@ -232,7 +242,7 @@ pub enum PackageSubpathResolveErrorKind {
|
|||
pub struct PackageTargetNotFoundError {
|
||||
pub pkg_json_path: PathBuf,
|
||||
pub target: String,
|
||||
pub maybe_referrer: Option<Url>,
|
||||
pub maybe_referrer: Option<UrlOrPath>,
|
||||
pub resolution_mode: ResolutionMode,
|
||||
pub resolution_kind: NodeResolutionKind,
|
||||
}
|
||||
|
@ -251,6 +261,9 @@ impl NodeJsErrorCoded for PackageTargetResolveError {
|
|||
PackageTargetResolveErrorKind::InvalidModuleSpecifier(e) => e.code(),
|
||||
PackageTargetResolveErrorKind::PackageResolve(e) => e.code(),
|
||||
PackageTargetResolveErrorKind::TypesNotFound(e) => e.code(),
|
||||
PackageTargetResolveErrorKind::UrlToFilePath(_) => {
|
||||
NodeJsErrorCode::ERR_INVALID_FILE_URL_PATH
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -275,6 +288,9 @@ pub enum PackageTargetResolveErrorKind {
|
|||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
TypesNotFound(#[from] TypesNotFoundError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
UrlToFilePath(#[from] deno_path_util::UrlToFilePathError),
|
||||
}
|
||||
|
||||
impl NodeJsErrorCoded for PackageExportsResolveError {
|
||||
|
@ -311,8 +327,8 @@ pub struct TypesNotFoundError(pub Box<TypesNotFoundErrorData>);
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct TypesNotFoundErrorData {
|
||||
pub code_specifier: Url,
|
||||
pub maybe_referrer: Option<Url>,
|
||||
pub code_specifier: UrlOrPath,
|
||||
pub maybe_referrer: Option<UrlOrPath>,
|
||||
}
|
||||
|
||||
impl NodeJsErrorCoded for TypesNotFoundError {
|
||||
|
@ -369,7 +385,7 @@ pub enum ClosestPkgJsonErrorKind {
|
|||
pub struct PackageImportNotDefinedError {
|
||||
pub name: String,
|
||||
pub package_json_path: Option<PathBuf>,
|
||||
pub maybe_referrer: Option<Url>,
|
||||
pub maybe_referrer: Option<UrlOrPath>,
|
||||
}
|
||||
|
||||
impl NodeJsErrorCoded for PackageImportNotDefinedError {
|
||||
|
@ -416,6 +432,9 @@ impl NodeJsErrorCoded for PackageResolveError {
|
|||
PackageResolveErrorKind::PackageFolderResolve(e) => e.code(),
|
||||
PackageResolveErrorKind::ExportsResolve(e) => e.code(),
|
||||
PackageResolveErrorKind::SubpathResolve(e) => e.code(),
|
||||
PackageResolveErrorKind::UrlToFilePath(_) => {
|
||||
NodeJsErrorCode::ERR_INVALID_FILE_URL_PATH
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -440,6 +459,9 @@ pub enum PackageResolveErrorKind {
|
|||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
SubpathResolve(#[from] PackageSubpathResolveError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
UrlToFilePath(#[from] UrlToFilePathError),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, JsError)]
|
||||
|
@ -470,6 +492,12 @@ pub enum NodeResolveErrorKind {
|
|||
RelativeJoin(#[from] NodeResolveRelativeJoinError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
PathToUrl(#[from] deno_path_util::PathToUrlError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
UrlToFilePath(#[from] deno_path_util::UrlToFilePathError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
PackageImportsResolve(#[from] PackageImportsResolveError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
|
@ -502,6 +530,9 @@ pub enum FinalizeResolutionErrorKind {
|
|||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
UnsupportedDirImport(#[from] UnsupportedDirImportError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
UrlToFilePath(#[from] deno_path_util::UrlToFilePathError),
|
||||
}
|
||||
|
||||
impl NodeJsErrorCoded for FinalizeResolutionError {
|
||||
|
@ -510,6 +541,9 @@ impl NodeJsErrorCoded for FinalizeResolutionError {
|
|||
FinalizeResolutionErrorKind::InvalidModuleSpecifierError(e) => e.code(),
|
||||
FinalizeResolutionErrorKind::ModuleNotFound(e) => e.code(),
|
||||
FinalizeResolutionErrorKind::UnsupportedDirImport(e) => e.code(),
|
||||
FinalizeResolutionErrorKind::UrlToFilePath(_) => {
|
||||
NodeJsErrorCode::ERR_INVALID_FILE_URL_PATH
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -524,8 +558,8 @@ impl NodeJsErrorCoded for FinalizeResolutionError {
|
|||
maybe_referrer.as_ref().map(|referrer| format!(" imported from '{}'", referrer)).unwrap_or_default()
|
||||
)]
|
||||
pub struct ModuleNotFoundError {
|
||||
pub specifier: Url,
|
||||
pub maybe_referrer: Option<Url>,
|
||||
pub specifier: UrlOrPath,
|
||||
pub maybe_referrer: Option<UrlOrPath>,
|
||||
pub typ: &'static str,
|
||||
}
|
||||
|
||||
|
@ -544,8 +578,8 @@ impl NodeJsErrorCoded for ModuleNotFoundError {
|
|||
maybe_referrer.as_ref().map(|referrer| format!(" imported from '{}'", referrer)).unwrap_or_default(),
|
||||
)]
|
||||
pub struct UnsupportedDirImportError {
|
||||
pub dir_url: Url,
|
||||
pub maybe_referrer: Option<Url>,
|
||||
pub dir_url: UrlOrPath,
|
||||
pub maybe_referrer: Option<UrlOrPath>,
|
||||
}
|
||||
|
||||
impl NodeJsErrorCoded for UnsupportedDirImportError {
|
||||
|
@ -561,7 +595,7 @@ pub struct InvalidPackageTargetError {
|
|||
pub sub_path: String,
|
||||
pub target: String,
|
||||
pub is_import: bool,
|
||||
pub maybe_referrer: Option<Url>,
|
||||
pub maybe_referrer: Option<UrlOrPath>,
|
||||
}
|
||||
|
||||
impl std::error::Error for InvalidPackageTargetError {}
|
||||
|
@ -616,7 +650,7 @@ impl NodeJsErrorCoded for InvalidPackageTargetError {
|
|||
pub struct PackagePathNotExportedError {
|
||||
pub pkg_json_path: PathBuf,
|
||||
pub subpath: String,
|
||||
pub maybe_referrer: Option<Url>,
|
||||
pub maybe_referrer: Option<UrlOrPath>,
|
||||
pub resolution_kind: NodeResolutionKind,
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@ pub use package_json::PackageJsonResolver;
|
|||
pub use package_json::PackageJsonResolverRc;
|
||||
pub use package_json::PackageJsonThreadLocalCache;
|
||||
pub use path::PathClean;
|
||||
pub use path::UrlOrPath;
|
||||
pub use path::UrlOrPathRef;
|
||||
pub use resolution::parse_npm_pkg_name;
|
||||
pub use resolution::resolve_specifier_into_node_modules;
|
||||
pub use resolution::ConditionsFromResolutionMode;
|
||||
|
|
|
@ -9,13 +9,14 @@ use url::Url;
|
|||
|
||||
use crate::errors;
|
||||
use crate::path::PathClean;
|
||||
use crate::path::UrlOrPathRef;
|
||||
|
||||
pub trait NpmPackageFolderResolver {
|
||||
/// Resolves an npm package folder path from the specified referrer.
|
||||
fn resolve_package_folder_from_package(
|
||||
&self,
|
||||
specifier: &str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
) -> Result<PathBuf, errors::PackageFolderResolveError>;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ use std::path::PathBuf;
|
|||
use deno_package_json::PackageJson;
|
||||
use deno_package_json::PackageJsonRc;
|
||||
use sys_traits::FsRead;
|
||||
use url::Url;
|
||||
|
||||
use crate::errors::ClosestPkgJsonError;
|
||||
use crate::errors::PackageJsonLoadError;
|
||||
|
@ -51,17 +50,17 @@ pub struct PackageJsonThreadLocalCache;
|
|||
|
||||
impl PackageJsonThreadLocalCache {
|
||||
pub fn clear() {
|
||||
CACHE.with(|cache| cache.borrow_mut().clear());
|
||||
CACHE.with_borrow_mut(|cache| cache.clear());
|
||||
}
|
||||
}
|
||||
|
||||
impl deno_package_json::PackageJsonCache for PackageJsonThreadLocalCache {
|
||||
fn get(&self, path: &Path) -> Option<PackageJsonRc> {
|
||||
CACHE.with(|cache| cache.borrow().get(path).cloned())
|
||||
CACHE.with_borrow(|cache| cache.get(path).cloned())
|
||||
}
|
||||
|
||||
fn set(&self, path: PathBuf, package_json: PackageJsonRc) {
|
||||
CACHE.with(|cache| cache.borrow_mut().insert(path, package_json));
|
||||
CACHE.with_borrow_mut(|cache| cache.insert(path, package_json));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,20 +80,12 @@ impl<TSys: FsRead> PackageJsonResolver<TSys> {
|
|||
}
|
||||
|
||||
pub fn get_closest_package_json(
|
||||
&self,
|
||||
url: &Url,
|
||||
) -> Result<Option<PackageJsonRc>, ClosestPkgJsonError> {
|
||||
let Ok(file_path) = deno_path_util::url_to_file_path(url) else {
|
||||
return Ok(None);
|
||||
};
|
||||
self.get_closest_package_json_from_file_path(&file_path)
|
||||
}
|
||||
|
||||
pub fn get_closest_package_json_from_file_path(
|
||||
&self,
|
||||
file_path: &Path,
|
||||
) -> Result<Option<PackageJsonRc>, ClosestPkgJsonError> {
|
||||
let parent_dir = file_path.parent().unwrap();
|
||||
let Some(parent_dir) = file_path.parent() else {
|
||||
return Ok(None);
|
||||
};
|
||||
for current_dir in parent_dir.ancestors() {
|
||||
let package_json_path = current_dir.join("package.json");
|
||||
if let Some(pkg_json) = self.load_package_json(&package_json_path)? {
|
||||
|
|
|
@ -1,9 +1,125 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::path::Component;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use url::Url;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum UrlOrPath {
|
||||
Url(Url),
|
||||
Path(PathBuf),
|
||||
}
|
||||
|
||||
impl UrlOrPath {
|
||||
pub fn is_file(&self) -> bool {
|
||||
match self {
|
||||
UrlOrPath::Url(url) => url.scheme() == "file",
|
||||
UrlOrPath::Path(_) => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_node_url(&self) -> bool {
|
||||
match self {
|
||||
UrlOrPath::Url(url) => url.scheme() == "node",
|
||||
UrlOrPath::Path(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_path(
|
||||
self,
|
||||
) -> Result<PathBuf, deno_path_util::UrlToFilePathError> {
|
||||
match self {
|
||||
UrlOrPath::Url(url) => deno_path_util::url_to_file_path(&url),
|
||||
UrlOrPath::Path(path) => Ok(path),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_url(self) -> Result<Url, deno_path_util::PathToUrlError> {
|
||||
match self {
|
||||
UrlOrPath::Url(url) => Ok(url),
|
||||
UrlOrPath::Path(path) => deno_path_util::url_from_file_path(&path),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_string_lossy(&self) -> Cow<str> {
|
||||
match self {
|
||||
UrlOrPath::Url(url) => Cow::Borrowed(url.as_str()),
|
||||
UrlOrPath::Path(path) => path.to_string_lossy(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for UrlOrPath {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
UrlOrPath::Url(url) => url.fmt(f),
|
||||
UrlOrPath::Path(path) => {
|
||||
// prefer displaying a url
|
||||
match deno_path_util::url_from_file_path(path) {
|
||||
Ok(url) => url.fmt(f),
|
||||
Err(_) => {
|
||||
write!(f, "{}", path.display())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UrlOrPathRef<'a> {
|
||||
url: once_cell::unsync::OnceCell<Cow<'a, Url>>,
|
||||
path: once_cell::unsync::OnceCell<Cow<'a, Path>>,
|
||||
}
|
||||
|
||||
impl<'a> UrlOrPathRef<'a> {
|
||||
pub fn from_path(path: &'a Path) -> Self {
|
||||
Self {
|
||||
url: Default::default(),
|
||||
path: once_cell::unsync::OnceCell::with_value(Cow::Borrowed(path)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_url(url: &'a Url) -> Self {
|
||||
Self {
|
||||
path: Default::default(),
|
||||
url: once_cell::unsync::OnceCell::with_value(Cow::Borrowed(url)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn url(&self) -> Result<&Url, deno_path_util::PathToUrlError> {
|
||||
self
|
||||
.url
|
||||
.get_or_try_init(|| {
|
||||
deno_path_util::url_from_file_path(self.path.get().unwrap())
|
||||
.map(Cow::Owned)
|
||||
})
|
||||
.map(|v| v.as_ref())
|
||||
}
|
||||
|
||||
pub fn path(&self) -> Result<&Path, deno_path_util::UrlToFilePathError> {
|
||||
self
|
||||
.path
|
||||
.get_or_try_init(|| {
|
||||
deno_path_util::url_to_file_path(self.url.get().unwrap())
|
||||
.map(Cow::Owned)
|
||||
})
|
||||
.map(|v| v.as_ref())
|
||||
}
|
||||
|
||||
pub fn display(&self) -> UrlOrPath {
|
||||
// prefer url
|
||||
if let Ok(url) = self.url() {
|
||||
UrlOrPath::Url(url.clone())
|
||||
} else {
|
||||
// this will always be set if url is None
|
||||
UrlOrPath::Path(self.path.get().unwrap().to_path_buf())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Extension to path_clean::PathClean
|
||||
pub trait PathClean<T> {
|
||||
fn clean(&self) -> T;
|
||||
|
|
|
@ -8,7 +8,6 @@ use std::path::PathBuf;
|
|||
use anyhow::bail;
|
||||
use anyhow::Error as AnyError;
|
||||
use deno_package_json::PackageJson;
|
||||
use deno_path_util::url_from_file_path;
|
||||
use serde_json::Map;
|
||||
use serde_json::Value;
|
||||
use sys_traits::FileType;
|
||||
|
@ -46,6 +45,8 @@ use crate::errors::TypesNotFoundError;
|
|||
use crate::errors::TypesNotFoundErrorData;
|
||||
use crate::errors::UnsupportedDirImportError;
|
||||
use crate::errors::UnsupportedEsmUrlSchemeError;
|
||||
use crate::path::UrlOrPath;
|
||||
use crate::path::UrlOrPathRef;
|
||||
use crate::InNpmPackageChecker;
|
||||
use crate::IsBuiltInNodeModuleChecker;
|
||||
use crate::NpmPackageFolderResolver;
|
||||
|
@ -115,21 +116,19 @@ impl NodeResolutionKind {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub enum NodeResolution {
|
||||
Module(Url),
|
||||
Module(UrlOrPath),
|
||||
BuiltIn(String),
|
||||
}
|
||||
|
||||
impl NodeResolution {
|
||||
pub fn into_url(self) -> Url {
|
||||
pub fn into_url(self) -> Result<Url, NodeResolveError> {
|
||||
match self {
|
||||
Self::Module(u) => u,
|
||||
Self::BuiltIn(specifier) => {
|
||||
if specifier.starts_with("node:") {
|
||||
Url::parse(&specifier).unwrap()
|
||||
} else {
|
||||
Url::parse(&format!("node:{specifier}")).unwrap()
|
||||
}
|
||||
}
|
||||
Self::Module(u) => Ok(u.into_url()?),
|
||||
Self::BuiltIn(specifier) => Ok(if specifier.starts_with("node:") {
|
||||
Url::parse(&specifier).unwrap()
|
||||
} else {
|
||||
Url::parse(&format!("node:{specifier}")).unwrap()
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +219,7 @@ impl<
|
|||
|
||||
if let Ok(url) = Url::parse(specifier) {
|
||||
if url.scheme() == "data" {
|
||||
return Ok(NodeResolution::Module(url));
|
||||
return Ok(NodeResolution::Module(UrlOrPath::Url(url)));
|
||||
}
|
||||
|
||||
if let Some(module_name) =
|
||||
|
@ -245,26 +244,27 @@ impl<
|
|||
let url = referrer
|
||||
.join(specifier)
|
||||
.map_err(|source| DataUrlReferrerError { source })?;
|
||||
return Ok(NodeResolution::Module(url));
|
||||
return Ok(NodeResolution::Module(UrlOrPath::Url(url)));
|
||||
}
|
||||
}
|
||||
|
||||
let conditions = self
|
||||
.conditions_from_resolution_mode
|
||||
.resolve(resolution_mode);
|
||||
let referrer = UrlOrPathRef::from_url(referrer);
|
||||
let url = self.module_resolve(
|
||||
specifier,
|
||||
referrer,
|
||||
&referrer,
|
||||
resolution_mode,
|
||||
conditions,
|
||||
resolution_kind,
|
||||
)?;
|
||||
|
||||
let url = if resolution_kind.is_types() {
|
||||
let file_path = to_file_path(&url);
|
||||
self.path_to_declaration_url(
|
||||
&file_path,
|
||||
Some(referrer),
|
||||
let url = if resolution_kind.is_types() && url.is_file() {
|
||||
let file_path = url.into_path()?;
|
||||
self.path_to_declaration_path(
|
||||
file_path,
|
||||
Some(&referrer),
|
||||
resolution_mode,
|
||||
conditions,
|
||||
)?
|
||||
|
@ -272,8 +272,8 @@ impl<
|
|||
url
|
||||
};
|
||||
|
||||
let url = self.finalize_resolution(url, Some(referrer))?;
|
||||
let resolve_response = NodeResolution::Module(url);
|
||||
let url_or_path = self.finalize_resolution(url, Some(&referrer))?;
|
||||
let resolve_response = NodeResolution::Module(url_or_path);
|
||||
// TODO(bartlomieju): skipped checking errors for commonJS resolution and
|
||||
// "preserveSymlinksMain"/"preserveSymlinks" options.
|
||||
Ok(resolve_response)
|
||||
|
@ -282,23 +282,26 @@ impl<
|
|||
fn module_resolve(
|
||||
&self,
|
||||
specifier: &str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
resolution_mode: ResolutionMode,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, NodeResolveError> {
|
||||
) -> Result<UrlOrPath, NodeResolveError> {
|
||||
if should_be_treated_as_relative_or_absolute_path(specifier) {
|
||||
Ok(node_join_url(referrer, specifier).map_err(|err| {
|
||||
NodeResolveRelativeJoinError {
|
||||
path: specifier.to_string(),
|
||||
base: referrer.clone(),
|
||||
source: err,
|
||||
}
|
||||
})?)
|
||||
let referrer_url = referrer.url()?;
|
||||
Ok(UrlOrPath::Url(
|
||||
node_join_url(referrer_url, specifier).map_err(|err| {
|
||||
NodeResolveRelativeJoinError {
|
||||
path: specifier.to_string(),
|
||||
base: referrer_url.clone(),
|
||||
source: err,
|
||||
}
|
||||
})?,
|
||||
))
|
||||
} else if specifier.starts_with('#') {
|
||||
let pkg_config = self
|
||||
.pkg_json_resolver
|
||||
.get_closest_package_json(referrer)
|
||||
.get_closest_package_json(referrer.path()?)
|
||||
.map_err(PackageImportsResolveErrorKind::ClosestPkgJson)
|
||||
.map_err(|err| PackageImportsResolveError(Box::new(err)))?;
|
||||
Ok(self.package_imports_resolve(
|
||||
|
@ -310,7 +313,7 @@ impl<
|
|||
resolution_kind,
|
||||
)?)
|
||||
} else if let Ok(resolved) = Url::parse(specifier) {
|
||||
Ok(resolved)
|
||||
Ok(UrlOrPath::Url(resolved))
|
||||
} else {
|
||||
Ok(self.package_resolve(
|
||||
specifier,
|
||||
|
@ -324,29 +327,37 @@ impl<
|
|||
|
||||
fn finalize_resolution(
|
||||
&self,
|
||||
resolved: Url,
|
||||
maybe_referrer: Option<&Url>,
|
||||
) -> Result<Url, FinalizeResolutionError> {
|
||||
resolved: UrlOrPath,
|
||||
maybe_referrer: Option<&UrlOrPathRef>,
|
||||
) -> Result<UrlOrPath, FinalizeResolutionError> {
|
||||
let encoded_sep_re = lazy_regex::regex!(r"%2F|%2C");
|
||||
|
||||
if encoded_sep_re.is_match(resolved.path()) {
|
||||
let text = match &resolved {
|
||||
UrlOrPath::Url(url) => Cow::Borrowed(url.as_str()),
|
||||
UrlOrPath::Path(path_buf) => path_buf.to_string_lossy(),
|
||||
};
|
||||
if encoded_sep_re.is_match(&text) {
|
||||
return Err(
|
||||
errors::InvalidModuleSpecifierError {
|
||||
request: resolved.to_string(),
|
||||
reason: Cow::Borrowed(
|
||||
"must not include encoded \"/\" or \"\\\\\" characters",
|
||||
),
|
||||
maybe_referrer: maybe_referrer.map(to_file_path_string),
|
||||
maybe_referrer: maybe_referrer.map(|r| match r.path() {
|
||||
// in this case, prefer showing the path string
|
||||
Ok(path) => path.display().to_string(),
|
||||
Err(_) => r.display().to_string(),
|
||||
}),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
if resolved.scheme() == "node" {
|
||||
if resolved.is_node_url() {
|
||||
return Ok(resolved);
|
||||
}
|
||||
|
||||
let path = to_file_path(&resolved);
|
||||
let path = resolved.into_path()?;
|
||||
|
||||
// TODO(bartlomieju): currently not supported
|
||||
// if (getOptionValue('--experimental-specifier-resolution') === 'node') {
|
||||
|
@ -354,26 +365,27 @@ impl<
|
|||
// }
|
||||
|
||||
let p_str = path.to_str().unwrap();
|
||||
let p = if p_str.ends_with('/') {
|
||||
p_str[p_str.len() - 1..].to_string()
|
||||
let path = if p_str.ends_with('/') {
|
||||
// todo(dsherret): don't allocate a new string here
|
||||
PathBuf::from(p_str[p_str.len() - 1..].to_string())
|
||||
} else {
|
||||
p_str.to_string()
|
||||
path
|
||||
};
|
||||
|
||||
let maybe_file_type = self.sys.fs_metadata(p).map(|m| m.file_type());
|
||||
let maybe_file_type = self.sys.fs_metadata(&path).map(|m| m.file_type());
|
||||
match maybe_file_type {
|
||||
Ok(FileType::Dir) => Err(
|
||||
UnsupportedDirImportError {
|
||||
dir_url: resolved.clone(),
|
||||
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
|
||||
dir_url: UrlOrPath::Path(path),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
Ok(FileType::File) => Ok(resolved),
|
||||
Ok(FileType::File) => Ok(UrlOrPath::Path(path)),
|
||||
_ => Err(
|
||||
ModuleNotFoundError {
|
||||
specifier: resolved,
|
||||
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
|
||||
specifier: UrlOrPath::Path(path),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
typ: "module",
|
||||
}
|
||||
.into(),
|
||||
|
@ -388,16 +400,17 @@ impl<
|
|||
maybe_referrer: Option<&Url>,
|
||||
resolution_mode: ResolutionMode,
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, PackageSubpathResolveError> {
|
||||
) -> Result<UrlOrPath, PackageSubpathResolveError> {
|
||||
// todo(dsherret): don't allocate a string here (maybe use an
|
||||
// enum that says the subpath is not prefixed with a ./)
|
||||
let package_subpath = package_subpath
|
||||
.map(|s| format!("./{s}"))
|
||||
.unwrap_or_else(|| ".".to_string());
|
||||
let maybe_referrer = maybe_referrer.map(UrlOrPathRef::from_url);
|
||||
let resolved_url = self.resolve_package_dir_subpath(
|
||||
package_dir,
|
||||
&package_subpath,
|
||||
maybe_referrer,
|
||||
maybe_referrer.as_ref(),
|
||||
resolution_mode,
|
||||
self
|
||||
.conditions_from_resolution_mode
|
||||
|
@ -441,7 +454,7 @@ impl<
|
|||
&self,
|
||||
package_folder: &Path,
|
||||
sub_path: Option<&str>,
|
||||
) -> Result<Url, ResolvePkgJsonBinExportError> {
|
||||
) -> Result<PathBuf, ResolvePkgJsonBinExportError> {
|
||||
let pkg_json_path = package_folder.join("package.json");
|
||||
let Some(package_json) =
|
||||
self.pkg_json_resolver.load_package_json(&pkg_json_path)?
|
||||
|
@ -456,18 +469,16 @@ impl<
|
|||
message: err.to_string(),
|
||||
}
|
||||
})?;
|
||||
let url = url_from_file_path(&package_folder.join(bin_entry)).unwrap();
|
||||
|
||||
// TODO(bartlomieju): skipped checking errors for commonJS resolution and
|
||||
// "preserveSymlinksMain"/"preserveSymlinks" options.
|
||||
Ok(url)
|
||||
Ok(package_folder.join(bin_entry))
|
||||
}
|
||||
|
||||
/// Resolves an npm package folder path from the specified referrer.
|
||||
pub fn resolve_package_folder_from_package(
|
||||
&self,
|
||||
specifier: &str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
) -> Result<PathBuf, errors::PackageFolderResolveError> {
|
||||
self
|
||||
.npm_pkg_folder_resolver
|
||||
|
@ -475,13 +486,13 @@ impl<
|
|||
}
|
||||
|
||||
/// Checks if the resolved file has a corresponding declaration file.
|
||||
fn path_to_declaration_url(
|
||||
fn path_to_declaration_path(
|
||||
&self,
|
||||
path: &Path,
|
||||
maybe_referrer: Option<&Url>,
|
||||
path: PathBuf,
|
||||
maybe_referrer: Option<&UrlOrPathRef>,
|
||||
resolution_mode: ResolutionMode,
|
||||
conditions: &[&str],
|
||||
) -> Result<Url, TypesNotFoundError> {
|
||||
) -> Result<UrlOrPath, TypesNotFoundError> {
|
||||
fn probe_extensions<TSys: FsMetadata>(
|
||||
sys: &TSys,
|
||||
path: &Path,
|
||||
|
@ -492,20 +503,20 @@ impl<
|
|||
let mut searched_for_d_cts = false;
|
||||
if lowercase_path.ends_with(".mjs") {
|
||||
let d_mts_path = with_known_extension(path, "d.mts");
|
||||
if sys.fs_exists_no_err(&d_mts_path) {
|
||||
if sys.fs_is_file_no_err(&d_mts_path) {
|
||||
return Some(d_mts_path);
|
||||
}
|
||||
searched_for_d_mts = true;
|
||||
} else if lowercase_path.ends_with(".cjs") {
|
||||
let d_cts_path = with_known_extension(path, "d.cts");
|
||||
if sys.fs_exists_no_err(&d_cts_path) {
|
||||
if sys.fs_is_file_no_err(&d_cts_path) {
|
||||
return Some(d_cts_path);
|
||||
}
|
||||
searched_for_d_cts = true;
|
||||
}
|
||||
|
||||
let dts_path = with_known_extension(path, "d.ts");
|
||||
if sys.fs_exists_no_err(&dts_path) {
|
||||
if sys.fs_is_file_no_err(&dts_path) {
|
||||
return Some(dts_path);
|
||||
}
|
||||
|
||||
|
@ -519,7 +530,7 @@ impl<
|
|||
_ => None, // already searched above
|
||||
};
|
||||
if let Some(specific_dts_path) = specific_dts_path {
|
||||
if sys.fs_exists_no_err(&specific_dts_path) {
|
||||
if sys.fs_is_file_no_err(&specific_dts_path) {
|
||||
return Some(specific_dts_path);
|
||||
}
|
||||
}
|
||||
|
@ -531,16 +542,16 @@ impl<
|
|||
|| lowercase_path.ends_with(".d.cts")
|
||||
|| lowercase_path.ends_with(".d.mts")
|
||||
{
|
||||
return Ok(url_from_file_path(path).unwrap());
|
||||
return Ok(UrlOrPath::Path(path));
|
||||
}
|
||||
if let Some(path) =
|
||||
probe_extensions(&self.sys, path, &lowercase_path, resolution_mode)
|
||||
probe_extensions(&self.sys, &path, &lowercase_path, resolution_mode)
|
||||
{
|
||||
return Ok(url_from_file_path(&path).unwrap());
|
||||
return Ok(UrlOrPath::Path(path));
|
||||
}
|
||||
if self.sys.fs_is_dir_no_err(path) {
|
||||
if self.sys.fs_is_dir_no_err(&path) {
|
||||
let resolution_result = self.resolve_package_dir_subpath(
|
||||
path,
|
||||
&path,
|
||||
/* sub path */ ".",
|
||||
maybe_referrer,
|
||||
resolution_mode,
|
||||
|
@ -557,16 +568,16 @@ impl<
|
|||
&index_path.to_string_lossy().to_lowercase(),
|
||||
resolution_mode,
|
||||
) {
|
||||
return Ok(url_from_file_path(&path).unwrap());
|
||||
return Ok(UrlOrPath::Path(path));
|
||||
}
|
||||
}
|
||||
// allow resolving .css files for types resolution
|
||||
if lowercase_path.ends_with(".css") {
|
||||
return Ok(url_from_file_path(path).unwrap());
|
||||
return Ok(UrlOrPath::Path(path));
|
||||
}
|
||||
Err(TypesNotFoundError(Box::new(TypesNotFoundErrorData {
|
||||
code_specifier: url_from_file_path(path).unwrap(),
|
||||
maybe_referrer: maybe_referrer.cloned(),
|
||||
code_specifier: UrlOrPathRef::from_path(&path).display(),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
})))
|
||||
}
|
||||
|
||||
|
@ -574,12 +585,12 @@ impl<
|
|||
pub fn package_imports_resolve(
|
||||
&self,
|
||||
name: &str,
|
||||
maybe_referrer: Option<&Url>,
|
||||
maybe_referrer: Option<&UrlOrPathRef>,
|
||||
resolution_mode: ResolutionMode,
|
||||
referrer_pkg_json: Option<&PackageJson>,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, PackageImportsResolveError> {
|
||||
) -> Result<UrlOrPath, PackageImportsResolveError> {
|
||||
if name == "#" || name.starts_with("#/") || name.ends_with('/') {
|
||||
let reason = "is not a valid internal imports specifier name";
|
||||
return Err(
|
||||
|
@ -662,7 +673,7 @@ impl<
|
|||
PackageImportNotDefinedError {
|
||||
name: name.to_string(),
|
||||
package_json_path,
|
||||
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
|
@ -675,13 +686,13 @@ impl<
|
|||
subpath: &str,
|
||||
match_: &str,
|
||||
package_json_path: &Path,
|
||||
maybe_referrer: Option<&Url>,
|
||||
maybe_referrer: Option<&UrlOrPathRef>,
|
||||
resolution_mode: ResolutionMode,
|
||||
pattern: bool,
|
||||
internal: bool,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, PackageTargetResolveError> {
|
||||
) -> Result<UrlOrPath, PackageTargetResolveError> {
|
||||
if !subpath.is_empty() && !pattern && !target.ends_with('/') {
|
||||
return Err(
|
||||
InvalidPackageTargetError {
|
||||
|
@ -689,7 +700,7 @@ impl<
|
|||
sub_path: match_.to_string(),
|
||||
target: target.to_string(),
|
||||
is_import: internal,
|
||||
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
@ -705,7 +716,7 @@ impl<
|
|||
if get_module_name_from_builtin_node_module_specifier(&url)
|
||||
.is_some()
|
||||
{
|
||||
return Ok(url);
|
||||
return Ok(UrlOrPath::Url(url));
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
|
@ -716,18 +727,17 @@ impl<
|
|||
} else {
|
||||
format!("{target}{subpath}")
|
||||
};
|
||||
let package_json_url =
|
||||
url_from_file_path(package_json_path).unwrap();
|
||||
let result = match self.package_resolve(
|
||||
&export_target,
|
||||
&package_json_url,
|
||||
&UrlOrPathRef::from_path(package_json_path),
|
||||
resolution_mode,
|
||||
conditions,
|
||||
resolution_kind,
|
||||
) {
|
||||
Ok(url) => Ok(url),
|
||||
Err(err) => match err.code() {
|
||||
NodeJsErrorCode::ERR_INVALID_MODULE_SPECIFIER
|
||||
NodeJsErrorCode::ERR_INVALID_FILE_URL_PATH
|
||||
| NodeJsErrorCode::ERR_INVALID_MODULE_SPECIFIER
|
||||
| NodeJsErrorCode::ERR_INVALID_PACKAGE_CONFIG
|
||||
| NodeJsErrorCode::ERR_INVALID_PACKAGE_TARGET
|
||||
| NodeJsErrorCode::ERR_PACKAGE_IMPORT_NOT_DEFINED
|
||||
|
@ -743,7 +753,7 @@ impl<
|
|||
PackageTargetNotFoundError {
|
||||
pkg_json_path: package_json_path.to_path_buf(),
|
||||
target: export_target.to_string(),
|
||||
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
resolution_mode,
|
||||
resolution_kind,
|
||||
},
|
||||
|
@ -760,7 +770,9 @@ impl<
|
|||
.is_built_in_node_module_checker
|
||||
.is_builtin_node_module(target)
|
||||
{
|
||||
Ok(Url::parse(&format!("node:{}", target)).unwrap())
|
||||
Ok(UrlOrPath::Url(
|
||||
Url::parse(&format!("node:{}", target)).unwrap(),
|
||||
))
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
|
@ -775,7 +787,7 @@ impl<
|
|||
sub_path: match_.to_string(),
|
||||
target: target.to_string(),
|
||||
is_import: internal,
|
||||
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
@ -787,7 +799,7 @@ impl<
|
|||
sub_path: match_.to_string(),
|
||||
target: target.to_string(),
|
||||
is_import: internal,
|
||||
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
@ -801,13 +813,13 @@ impl<
|
|||
sub_path: match_.to_string(),
|
||||
target: target.to_string(),
|
||||
is_import: internal,
|
||||
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
if subpath.is_empty() {
|
||||
return Ok(url_from_file_path(&resolved_path).unwrap());
|
||||
return Ok(UrlOrPath::Path(resolved_path));
|
||||
}
|
||||
if invalid_segment_re.is_match(subpath) {
|
||||
let request = if pattern {
|
||||
|
@ -829,11 +841,9 @@ impl<
|
|||
let resolved_path_str = resolved_path.to_string_lossy();
|
||||
let replaced = pattern_re
|
||||
.replace(&resolved_path_str, |_caps: ®ex::Captures| subpath);
|
||||
return Ok(
|
||||
url_from_file_path(&PathBuf::from(replaced.to_string())).unwrap(),
|
||||
);
|
||||
return Ok(UrlOrPath::Path(PathBuf::from(replaced.to_string())));
|
||||
}
|
||||
Ok(url_from_file_path(&resolved_path.join(subpath).clean()).unwrap())
|
||||
Ok(UrlOrPath::Path(resolved_path.join(subpath).clean()))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
|
@ -843,13 +853,13 @@ impl<
|
|||
target: &Value,
|
||||
subpath: &str,
|
||||
package_subpath: &str,
|
||||
maybe_referrer: Option<&Url>,
|
||||
maybe_referrer: Option<&UrlOrPathRef>,
|
||||
resolution_mode: ResolutionMode,
|
||||
pattern: bool,
|
||||
internal: bool,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Option<Url>, PackageTargetResolveError> {
|
||||
) -> Result<Option<UrlOrPath>, PackageTargetResolveError> {
|
||||
let result = self.resolve_package_target_inner(
|
||||
package_json_path,
|
||||
target,
|
||||
|
@ -899,15 +909,15 @@ impl<
|
|||
target: &Value,
|
||||
subpath: &str,
|
||||
package_subpath: &str,
|
||||
maybe_referrer: Option<&Url>,
|
||||
maybe_referrer: Option<&UrlOrPathRef>,
|
||||
resolution_mode: ResolutionMode,
|
||||
pattern: bool,
|
||||
internal: bool,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Option<Url>, PackageTargetResolveError> {
|
||||
) -> Result<Option<UrlOrPath>, PackageTargetResolveError> {
|
||||
if let Some(target) = target.as_str() {
|
||||
let url = self.resolve_package_target_string(
|
||||
let url_or_path = self.resolve_package_target_string(
|
||||
target,
|
||||
subpath,
|
||||
package_subpath,
|
||||
|
@ -919,16 +929,16 @@ impl<
|
|||
conditions,
|
||||
resolution_kind,
|
||||
)?;
|
||||
if resolution_kind.is_types() && url.scheme() == "file" {
|
||||
let path = deno_path_util::url_to_file_path(&url).unwrap();
|
||||
return Ok(Some(self.path_to_declaration_url(
|
||||
&path,
|
||||
if resolution_kind.is_types() && url_or_path.is_file() {
|
||||
let path = url_or_path.into_path()?;
|
||||
return Ok(Some(self.path_to_declaration_path(
|
||||
path,
|
||||
maybe_referrer,
|
||||
resolution_mode,
|
||||
conditions,
|
||||
)?));
|
||||
} else {
|
||||
return Ok(Some(url));
|
||||
return Ok(Some(url_or_path));
|
||||
}
|
||||
} else if let Some(target_arr) = target.as_array() {
|
||||
if target_arr.is_empty() {
|
||||
|
@ -1013,7 +1023,7 @@ impl<
|
|||
sub_path: package_subpath.to_string(),
|
||||
target: target.to_string(),
|
||||
is_import: internal,
|
||||
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
|
@ -1025,11 +1035,11 @@ impl<
|
|||
package_json_path: &Path,
|
||||
package_subpath: &str,
|
||||
package_exports: &Map<String, Value>,
|
||||
maybe_referrer: Option<&Url>,
|
||||
maybe_referrer: Option<&UrlOrPathRef>,
|
||||
resolution_mode: ResolutionMode,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, PackageExportsResolveError> {
|
||||
) -> Result<UrlOrPath, PackageExportsResolveError> {
|
||||
if let Some(target) = package_exports.get(package_subpath) {
|
||||
if package_subpath.find('*').is_none() && !package_subpath.ends_with('/')
|
||||
{
|
||||
|
@ -1051,7 +1061,7 @@ impl<
|
|||
PackagePathNotExportedError {
|
||||
pkg_json_path: package_json_path.to_path_buf(),
|
||||
subpath: package_subpath.to_string(),
|
||||
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
resolution_kind,
|
||||
}
|
||||
.into(),
|
||||
|
@ -1116,7 +1126,7 @@ impl<
|
|||
PackagePathNotExportedError {
|
||||
pkg_json_path: package_json_path.to_path_buf(),
|
||||
subpath: package_subpath.to_string(),
|
||||
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
resolution_kind,
|
||||
}
|
||||
.into(),
|
||||
|
@ -1128,7 +1138,7 @@ impl<
|
|||
PackagePathNotExportedError {
|
||||
pkg_json_path: package_json_path.to_path_buf(),
|
||||
subpath: package_subpath.to_string(),
|
||||
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
resolution_kind,
|
||||
}
|
||||
.into(),
|
||||
|
@ -1138,16 +1148,17 @@ impl<
|
|||
pub(super) fn package_resolve(
|
||||
&self,
|
||||
specifier: &str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
resolution_mode: ResolutionMode,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, PackageResolveError> {
|
||||
) -> Result<UrlOrPath, PackageResolveError> {
|
||||
let (package_name, package_subpath, _is_scoped) =
|
||||
parse_npm_pkg_name(specifier, referrer)?;
|
||||
|
||||
if let Some(package_config) =
|
||||
self.pkg_json_resolver.get_closest_package_json(referrer)?
|
||||
if let Some(package_config) = self
|
||||
.pkg_json_resolver
|
||||
.get_closest_package_json(referrer.path()?)?
|
||||
{
|
||||
// ResolveSelf
|
||||
if package_config.name.as_deref() == Some(package_name) {
|
||||
|
@ -1182,11 +1193,11 @@ impl<
|
|||
&self,
|
||||
package_name: &str,
|
||||
package_subpath: &str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
resolution_mode: ResolutionMode,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, PackageResolveError> {
|
||||
) -> Result<UrlOrPath, PackageResolveError> {
|
||||
let result = self.resolve_package_subpath_for_package_inner(
|
||||
package_name,
|
||||
package_subpath,
|
||||
|
@ -1195,7 +1206,7 @@ impl<
|
|||
conditions,
|
||||
resolution_kind,
|
||||
);
|
||||
if resolution_kind.is_types() && !matches!(result, Ok(Url { .. })) {
|
||||
if resolution_kind.is_types() && result.is_err() {
|
||||
// try to resolve with the @types package
|
||||
let package_name = types_package_name(package_name);
|
||||
if let Ok(result) = self.resolve_package_subpath_for_package_inner(
|
||||
|
@ -1217,11 +1228,11 @@ impl<
|
|||
&self,
|
||||
package_name: &str,
|
||||
package_subpath: &str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
resolution_mode: ResolutionMode,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, PackageResolveError> {
|
||||
) -> Result<UrlOrPath, PackageResolveError> {
|
||||
let package_dir_path = self
|
||||
.npm_pkg_folder_resolver
|
||||
.resolve_package_folder_from_package(package_name, referrer)?;
|
||||
|
@ -1257,11 +1268,11 @@ impl<
|
|||
&self,
|
||||
package_dir_path: &Path,
|
||||
package_subpath: &str,
|
||||
maybe_referrer: Option<&Url>,
|
||||
maybe_referrer: Option<&UrlOrPathRef>,
|
||||
resolution_mode: ResolutionMode,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, PackageSubpathResolveError> {
|
||||
) -> Result<UrlOrPath, PackageSubpathResolveError> {
|
||||
let package_json_path = package_dir_path.join("package.json");
|
||||
match self
|
||||
.pkg_json_resolver
|
||||
|
@ -1295,11 +1306,11 @@ impl<
|
|||
&self,
|
||||
package_json: &PackageJson,
|
||||
package_subpath: &str,
|
||||
referrer: Option<&Url>,
|
||||
referrer: Option<&UrlOrPathRef>,
|
||||
resolution_mode: ResolutionMode,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, PackageSubpathResolveError> {
|
||||
) -> Result<UrlOrPath, PackageSubpathResolveError> {
|
||||
if let Some(exports) = &package_json.exports {
|
||||
let result = self.package_exports_resolve(
|
||||
&package_json.path,
|
||||
|
@ -1365,22 +1376,22 @@ impl<
|
|||
&self,
|
||||
directory: &Path,
|
||||
package_subpath: &str,
|
||||
referrer: Option<&Url>,
|
||||
referrer: Option<&UrlOrPathRef>,
|
||||
resolution_mode: ResolutionMode,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, TypesNotFoundError> {
|
||||
) -> Result<UrlOrPath, TypesNotFoundError> {
|
||||
assert_ne!(package_subpath, ".");
|
||||
let file_path = directory.join(package_subpath);
|
||||
if resolution_kind.is_types() {
|
||||
Ok(self.path_to_declaration_url(
|
||||
&file_path,
|
||||
Ok(self.path_to_declaration_path(
|
||||
file_path,
|
||||
referrer,
|
||||
resolution_mode,
|
||||
conditions,
|
||||
)?)
|
||||
} else {
|
||||
Ok(url_from_file_path(&file_path).unwrap())
|
||||
Ok(UrlOrPath::Path(file_path))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1388,18 +1399,20 @@ impl<
|
|||
&self,
|
||||
directory: &Path,
|
||||
package_subpath: &str,
|
||||
maybe_referrer: Option<&Url>,
|
||||
maybe_referrer: Option<&UrlOrPathRef>,
|
||||
resolution_mode: ResolutionMode,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, LegacyResolveError> {
|
||||
) -> Result<UrlOrPath, LegacyResolveError> {
|
||||
if package_subpath == "." {
|
||||
self.legacy_index_resolve(
|
||||
directory,
|
||||
maybe_referrer,
|
||||
resolution_mode,
|
||||
resolution_kind,
|
||||
)
|
||||
self
|
||||
.legacy_index_resolve(
|
||||
directory,
|
||||
maybe_referrer,
|
||||
resolution_mode,
|
||||
resolution_kind,
|
||||
)
|
||||
.map(UrlOrPath::Path)
|
||||
} else {
|
||||
self
|
||||
.resolve_subpath_exact(
|
||||
|
@ -1417,11 +1430,11 @@ impl<
|
|||
pub(super) fn legacy_main_resolve(
|
||||
&self,
|
||||
package_json: &PackageJson,
|
||||
maybe_referrer: Option<&Url>,
|
||||
maybe_referrer: Option<&UrlOrPathRef>,
|
||||
resolution_mode: ResolutionMode,
|
||||
conditions: &[&str],
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, LegacyResolveError> {
|
||||
) -> Result<UrlOrPath, LegacyResolveError> {
|
||||
let pkg_json_kind = match resolution_mode {
|
||||
ResolutionMode::Require => deno_package_json::NodeModuleKind::Cjs,
|
||||
ResolutionMode::Import => deno_package_json::NodeModuleKind::Esm,
|
||||
|
@ -1434,15 +1447,15 @@ impl<
|
|||
// a corresponding declaration file
|
||||
if let Some(main) = package_json.main(pkg_json_kind) {
|
||||
let main = package_json.path.parent().unwrap().join(main).clean();
|
||||
let decl_url_result = self.path_to_declaration_url(
|
||||
&main,
|
||||
let decl_path_result = self.path_to_declaration_path(
|
||||
main,
|
||||
maybe_referrer,
|
||||
resolution_mode,
|
||||
conditions,
|
||||
);
|
||||
// don't surface errors, fallback to checking the index now
|
||||
if let Ok(url) = decl_url_result {
|
||||
return Ok(url);
|
||||
if let Ok(url_or_path) = decl_path_result {
|
||||
return Ok(url_or_path);
|
||||
}
|
||||
}
|
||||
None
|
||||
|
@ -1455,7 +1468,7 @@ impl<
|
|||
if let Some(main) = maybe_main {
|
||||
let guess = package_json.path.parent().unwrap().join(main).clean();
|
||||
if self.sys.fs_is_file_no_err(&guess) {
|
||||
return Ok(url_from_file_path(&guess).unwrap());
|
||||
return Ok(UrlOrPath::Path(guess));
|
||||
}
|
||||
|
||||
// todo(dsherret): investigate exactly how node and typescript handles this
|
||||
|
@ -1485,26 +1498,28 @@ impl<
|
|||
.clean();
|
||||
if self.sys.fs_is_file_no_err(&guess) {
|
||||
// TODO(bartlomieju): emitLegacyIndexDeprecation()
|
||||
return Ok(url_from_file_path(&guess).unwrap());
|
||||
return Ok(UrlOrPath::Path(guess));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.legacy_index_resolve(
|
||||
package_json.path.parent().unwrap(),
|
||||
maybe_referrer,
|
||||
resolution_mode,
|
||||
resolution_kind,
|
||||
)
|
||||
self
|
||||
.legacy_index_resolve(
|
||||
package_json.path.parent().unwrap(),
|
||||
maybe_referrer,
|
||||
resolution_mode,
|
||||
resolution_kind,
|
||||
)
|
||||
.map(UrlOrPath::Path)
|
||||
}
|
||||
|
||||
fn legacy_index_resolve(
|
||||
&self,
|
||||
directory: &Path,
|
||||
maybe_referrer: Option<&Url>,
|
||||
maybe_referrer: Option<&UrlOrPathRef>,
|
||||
resolution_mode: ResolutionMode,
|
||||
resolution_kind: NodeResolutionKind,
|
||||
) -> Result<Url, LegacyResolveError> {
|
||||
) -> Result<PathBuf, LegacyResolveError> {
|
||||
let index_file_names = if resolution_kind.is_types() {
|
||||
// todo(dsherret): investigate exactly how typescript does this
|
||||
match resolution_mode {
|
||||
|
@ -1520,25 +1535,25 @@ impl<
|
|||
let guess = directory.join(index_file_name).clean();
|
||||
if self.sys.fs_is_file_no_err(&guess) {
|
||||
// TODO(bartlomieju): emitLegacyIndexDeprecation()
|
||||
return Ok(url_from_file_path(&guess).unwrap());
|
||||
return Ok(guess);
|
||||
}
|
||||
}
|
||||
|
||||
if resolution_kind.is_types() {
|
||||
Err(
|
||||
TypesNotFoundError(Box::new(TypesNotFoundErrorData {
|
||||
code_specifier: url_from_file_path(&directory.join("index.js"))
|
||||
.unwrap(),
|
||||
maybe_referrer: maybe_referrer.cloned(),
|
||||
code_specifier: UrlOrPathRef::from_path(&directory.join("index.js"))
|
||||
.display(),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
}))
|
||||
.into(),
|
||||
)
|
||||
} else {
|
||||
Err(
|
||||
ModuleNotFoundError {
|
||||
specifier: url_from_file_path(&directory.join("index.js")).unwrap(),
|
||||
specifier: UrlOrPath::Path(directory.join("index.js")),
|
||||
typ: "module",
|
||||
maybe_referrer: maybe_referrer.cloned(),
|
||||
maybe_referrer: maybe_referrer.map(|r| r.display()),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
|
@ -1652,14 +1667,6 @@ fn resolve_bin_entry_value<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
fn to_file_path(url: &Url) -> PathBuf {
|
||||
deno_path_util::url_to_file_path(url).unwrap()
|
||||
}
|
||||
|
||||
fn to_file_path_string(url: &Url) -> String {
|
||||
to_file_path(url).display().to_string()
|
||||
}
|
||||
|
||||
fn should_be_treated_as_relative_or_absolute_path(specifier: &str) -> bool {
|
||||
if specifier.is_empty() {
|
||||
return false;
|
||||
|
@ -1731,11 +1738,11 @@ fn with_known_extension(path: &Path, ext: &str) -> PathBuf {
|
|||
path.with_file_name(format!("{file_name}.{ext}"))
|
||||
}
|
||||
|
||||
fn to_specifier_display_string(url: &Url) -> String {
|
||||
if let Ok(path) = deno_path_util::url_to_file_path(url) {
|
||||
fn to_specifier_display_string(url: &UrlOrPathRef) -> String {
|
||||
if let Ok(path) = url.path() {
|
||||
path.display().to_string()
|
||||
} else {
|
||||
url.to_string()
|
||||
url.display().to_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1743,7 +1750,7 @@ fn throw_invalid_subpath(
|
|||
subpath: String,
|
||||
package_json_path: &Path,
|
||||
internal: bool,
|
||||
maybe_referrer: Option<&Url>,
|
||||
maybe_referrer: Option<&UrlOrPathRef>,
|
||||
) -> InvalidModuleSpecifierError {
|
||||
let ie = if internal { "imports" } else { "exports" };
|
||||
let reason = format!(
|
||||
|
@ -1760,7 +1767,7 @@ fn throw_invalid_subpath(
|
|||
|
||||
pub fn parse_npm_pkg_name<'a>(
|
||||
specifier: &'a str,
|
||||
referrer: &Url,
|
||||
referrer: &UrlOrPathRef,
|
||||
) -> Result<(&'a str, Cow<'static, str>, bool), InvalidModuleSpecifierError> {
|
||||
let mut separator_index = specifier.find('/');
|
||||
let mut valid_package_name = true;
|
||||
|
@ -2045,6 +2052,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_parse_package_name() {
|
||||
let dummy_referrer = Url::parse("http://example.com").unwrap();
|
||||
let dummy_referrer = UrlOrPathRef::from_url(&dummy_referrer);
|
||||
|
||||
assert_eq!(
|
||||
parse_npm_pkg_name("fetch-blob", &dummy_referrer).unwrap(),
|
||||
|
|
Loading…
Add table
Reference in a new issue