summaryrefslogtreecommitdiff
path: root/ext/node
diff options
context:
space:
mode:
Diffstat (limited to 'ext/node')
-rw-r--r--ext/node/lib.rs9
-rw-r--r--ext/node/resolution.rs94
2 files changed, 74 insertions, 29 deletions
diff --git a/ext/node/lib.rs b/ext/node/lib.rs
index c365d5d7b..b2443db0b 100644
--- a/ext/node/lib.rs
+++ b/ext/node/lib.rs
@@ -30,8 +30,8 @@ pub use resolution::package_imports_resolve;
pub use resolution::package_resolve;
pub use resolution::path_to_declaration_path;
pub use resolution::NodeModuleKind;
+pub use resolution::NodeResolutionMode;
pub use resolution::DEFAULT_CONDITIONS;
-pub use resolution::TYPES_CONDITIONS;
use std::cell::RefCell;
pub trait NodePermissions {
@@ -43,7 +43,7 @@ pub trait RequireNpmResolver {
&self,
specifier: &str,
referrer: &Path,
- conditions: &[&str],
+ mode: NodeResolutionMode,
) -> Result<PathBuf, AnyError>;
fn resolve_package_folder_from_path(
@@ -292,7 +292,7 @@ fn op_require_resolve_deno_dir(
.resolve_package_folder_from_package(
&request,
&PathBuf::from(parent_filename),
- DEFAULT_CONDITIONS,
+ NodeResolutionMode::Execution,
)
.ok()
.map(|p| p.to_string_lossy().to_string())
@@ -506,6 +506,7 @@ fn op_require_try_self(
&referrer,
NodeModuleKind::Cjs,
resolution::REQUIRE_CONDITIONS,
+ NodeResolutionMode::Execution,
&*resolver,
)
.map(|r| Some(r.to_string_lossy().to_string()))
@@ -568,6 +569,7 @@ fn op_require_resolve_exports(
&referrer,
NodeModuleKind::Cjs,
resolution::REQUIRE_CONDITIONS,
+ NodeResolutionMode::Execution,
&*resolver,
)
.map(|r| Some(r.to_string_lossy().to_string()))
@@ -627,6 +629,7 @@ where
&referrer,
NodeModuleKind::Cjs,
resolution::REQUIRE_CONDITIONS,
+ NodeResolutionMode::Execution,
&*resolver,
)
.map(|r| Some(Url::from_file_path(r).unwrap().to_string()));
diff --git a/ext/node/resolution.rs b/ext/node/resolution.rs
index f2bf2ca6f..855bebc71 100644
--- a/ext/node/resolution.rs
+++ b/ext/node/resolution.rs
@@ -19,7 +19,6 @@ use crate::RequireNpmResolver;
pub static DEFAULT_CONDITIONS: &[&str] = &["deno", "node", "import"];
pub static REQUIRE_CONDITIONS: &[&str] = &["require", "node"];
-pub static TYPES_CONDITIONS: &[&str] = &["types"];
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum NodeModuleKind {
@@ -27,6 +26,18 @@ pub enum NodeModuleKind {
Cjs,
}
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum NodeResolutionMode {
+ Execution,
+ Types,
+}
+
+impl NodeResolutionMode {
+ pub fn is_types(&self) -> bool {
+ matches!(self, NodeResolutionMode::Types)
+ }
+}
+
/// Checks if the resolved file has a corresponding declaration file.
pub fn path_to_declaration_path(
path: PathBuf,
@@ -175,6 +186,7 @@ pub fn package_imports_resolve(
referrer: &ModuleSpecifier,
referrer_kind: NodeModuleKind,
conditions: &[&str],
+ mode: NodeResolutionMode,
npm_resolver: &dyn RequireNpmResolver,
) -> Result<PathBuf, AnyError> {
if name == "#" || name.starts_with("#/") || name.ends_with('/') {
@@ -202,6 +214,7 @@ pub fn package_imports_resolve(
false,
true,
conditions,
+ mode,
npm_resolver,
)?;
if let Some(resolved) = maybe_resolved {
@@ -243,6 +256,7 @@ pub fn package_imports_resolve(
true,
true,
conditions,
+ mode,
npm_resolver,
)?;
if let Some(resolved) = maybe_resolved {
@@ -306,6 +320,7 @@ fn resolve_package_target_string(
pattern: bool,
internal: bool,
conditions: &[&str],
+ mode: NodeResolutionMode,
npm_resolver: &dyn RequireNpmResolver,
) -> Result<PathBuf, AnyError> {
if !subpath.is_empty() && !pattern && !target.ends_with('/') {
@@ -338,6 +353,7 @@ fn resolve_package_target_string(
&package_json_url,
referrer_kind,
conditions,
+ mode,
npm_resolver,
) {
Ok(Some(path)) => Ok(path),
@@ -412,10 +428,11 @@ fn resolve_package_target(
pattern: bool,
internal: bool,
conditions: &[&str],
+ mode: NodeResolutionMode,
npm_resolver: &dyn RequireNpmResolver,
) -> Result<Option<PathBuf>, AnyError> {
if let Some(target) = target.as_str() {
- return Ok(Some(resolve_package_target_string(
+ return resolve_package_target_string(
target.to_string(),
subpath,
package_subpath,
@@ -425,8 +442,10 @@ fn resolve_package_target(
pattern,
internal,
conditions,
+ mode,
npm_resolver,
- )?));
+ )
+ .map(Some);
} else if let Some(target_arr) = target.as_array() {
if target_arr.is_empty() {
return Ok(None);
@@ -444,23 +463,25 @@ fn resolve_package_target(
pattern,
internal,
conditions,
+ mode,
npm_resolver,
);
- if let Err(e) = resolved_result {
- let err_string = e.to_string();
- last_error = Some(e);
- if err_string.starts_with("[ERR_INVALID_PACKAGE_TARGET]") {
+ match resolved_result {
+ Ok(Some(resolved)) => return Ok(Some(resolved)),
+ Ok(None) => {
+ last_error = None;
continue;
}
- return Err(last_error.unwrap());
- }
- let resolved = resolved_result.unwrap();
- if resolved.is_none() {
- last_error = None;
- continue;
+ Err(e) => {
+ let err_string = e.to_string();
+ last_error = Some(e);
+ if err_string.starts_with("[ERR_INVALID_PACKAGE_TARGET]") {
+ continue;
+ }
+ return Err(last_error.unwrap());
+ }
}
- return Ok(resolved);
}
if last_error.is_none() {
return Ok(None);
@@ -475,8 +496,20 @@ fn resolve_package_target(
// Some("\"exports\" cannot contain numeric property keys.".to_string()),
// ));
- if key == "default" || conditions.contains(&key.as_str()) {
+ if key == "default"
+ || conditions.contains(&key.as_str())
+ || mode.is_types() && key.as_str() == "types"
+ {
let condition_target = target_obj.get(key).unwrap().to_owned();
+
+ if mode.is_types()
+ && key.as_str() != "types"
+ && condition_target.is_string()
+ {
+ // skip because this isn't a types entry
+ continue;
+ }
+
let resolved = resolve_package_target(
package_json_path,
condition_target,
@@ -487,12 +520,15 @@ fn resolve_package_target(
pattern,
internal,
conditions,
+ mode,
npm_resolver,
)?;
- if resolved.is_none() {
- continue;
+ match resolved {
+ Some(resolved) => return Ok(Some(resolved)),
+ None => {
+ continue;
+ }
}
- return Ok(resolved);
}
}
} else if target.is_null() {
@@ -520,6 +556,7 @@ fn throw_exports_not_found(
)
}
+#[allow(clippy::too_many_arguments)]
pub fn package_exports_resolve(
package_json_path: &Path,
package_subpath: String,
@@ -527,6 +564,7 @@ pub fn package_exports_resolve(
referrer: &ModuleSpecifier,
referrer_kind: NodeModuleKind,
conditions: &[&str],
+ mode: NodeResolutionMode,
npm_resolver: &dyn RequireNpmResolver,
) -> Result<PathBuf, AnyError> {
if package_exports.contains_key(&package_subpath)
@@ -544,6 +582,7 @@ pub fn package_exports_resolve(
false,
false,
conditions,
+ mode,
npm_resolver,
)?;
if resolved.is_none() {
@@ -602,6 +641,7 @@ pub fn package_exports_resolve(
true,
false,
conditions,
+ mode,
npm_resolver,
)?;
if let Some(resolved) = maybe_resolved {
@@ -678,6 +718,7 @@ pub fn package_resolve(
referrer: &ModuleSpecifier,
referrer_kind: NodeModuleKind,
conditions: &[&str],
+ mode: NodeResolutionMode,
npm_resolver: &dyn RequireNpmResolver,
) -> Result<Option<PathBuf>, AnyError> {
let (package_name, package_subpath, _is_scoped) =
@@ -696,6 +737,7 @@ pub fn package_resolve(
referrer,
referrer_kind,
conditions,
+ mode,
npm_resolver,
)
.map(Some);
@@ -705,7 +747,7 @@ pub fn package_resolve(
let package_dir_path = npm_resolver.resolve_package_folder_from_package(
&package_name,
&referrer.to_file_path().unwrap(),
- conditions,
+ mode,
)?;
let package_json_path = package_dir_path.join("package.json");
@@ -732,17 +774,18 @@ pub fn package_resolve(
referrer,
referrer_kind,
conditions,
+ mode,
npm_resolver,
)
.map(Some);
}
if package_subpath == "." {
- return legacy_main_resolve(&package_json, referrer_kind, conditions);
+ return legacy_main_resolve(&package_json, referrer_kind, mode);
}
let file_path = package_json.path.parent().unwrap().join(&package_subpath);
- if conditions == TYPES_CONDITIONS {
+ if mode.is_types() {
let maybe_declaration_path =
path_to_declaration_path(file_path, referrer_kind);
Ok(maybe_declaration_path)
@@ -803,10 +846,9 @@ fn file_exists(path: &Path) -> bool {
pub fn legacy_main_resolve(
package_json: &PackageJson,
referrer_kind: NodeModuleKind,
- conditions: &[&str],
+ mode: NodeResolutionMode,
) -> Result<Option<PathBuf>, AnyError> {
- let is_types = conditions == TYPES_CONDITIONS;
- let maybe_main = if is_types {
+ let maybe_main = if mode.is_types() {
match package_json.types.as_ref() {
Some(types) => Some(types),
None => {
@@ -832,7 +874,7 @@ pub fn legacy_main_resolve(
}
// todo(dsherret): investigate exactly how node and typescript handles this
- let endings = if is_types {
+ let endings = if mode.is_types() {
match referrer_kind {
NodeModuleKind::Cjs => {
vec![".d.ts", ".d.cts", "/index.d.ts", "/index.d.cts"]
@@ -863,7 +905,7 @@ pub fn legacy_main_resolve(
}
}
- let index_file_names = if is_types {
+ let index_file_names = if mode.is_types() {
// todo(dsherret): investigate exactly how typescript does this
match referrer_kind {
NodeModuleKind::Cjs => vec!["index.d.ts", "index.d.cts"],