fix(node): correct resolution of dynamic import of esm from cjs (#27071)

Ensures a dynamic import in a CJS file will consider the referrer as an import for node resolution.

Also adds fixes (adds) support for `"resolution-mode"` in TypeScript.
This commit is contained in:
David Sherret 2024-11-26 14:38:24 -05:00 committed by Bartek Iwańczuk
parent 525d231c84
commit 8cd9fa6aae
No known key found for this signature in database
GPG key ID: 0C6BCDDC3B3AD750
92 changed files with 868 additions and 1673 deletions

View file

@ -50,26 +50,30 @@ pub static DEFAULT_CONDITIONS: &[&str] = &["deno", "node", "import"];
pub static REQUIRE_CONDITIONS: &[&str] = &["require", "node"];
static TYPES_ONLY_CONDITIONS: &[&str] = &["types"];
fn conditions_from_module_kind(
kind: NodeModuleKind,
fn conditions_from_resolution_mode(
resolution_mode: ResolutionMode,
) -> &'static [&'static str] {
match kind {
NodeModuleKind::Esm => DEFAULT_CONDITIONS,
NodeModuleKind::Cjs => REQUIRE_CONDITIONS,
match resolution_mode {
ResolutionMode::Import => DEFAULT_CONDITIONS,
ResolutionMode::Require => REQUIRE_CONDITIONS,
}
}
pub type NodeModuleKind = deno_package_json::NodeModuleKind;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ResolutionMode {
Import,
Require,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NodeResolutionMode {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum NodeResolutionKind {
Execution,
Types,
}
impl NodeResolutionMode {
impl NodeResolutionKind {
pub fn is_types(&self) -> bool {
matches!(self, NodeResolutionMode::Types)
matches!(self, NodeResolutionKind::Types)
}
}
@ -130,8 +134,8 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
&self,
specifier: &str,
referrer: &Url,
referrer_kind: NodeModuleKind,
mode: NodeResolutionMode,
resolution_mode: ResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<NodeResolution, NodeResolveError> {
// Note: if we are here, then the referrer is an esm module
// TODO(bartlomieju): skipped "policy" part as we don't plan to support it
@ -174,14 +178,18 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
let url = self.module_resolve(
specifier,
referrer,
referrer_kind,
conditions_from_module_kind(referrer_kind),
mode,
resolution_mode,
conditions_from_resolution_mode(resolution_mode),
resolution_kind,
)?;
let url = if mode.is_types() {
let url = if resolution_kind.is_types() {
let file_path = to_file_path(&url);
self.path_to_declaration_url(&file_path, Some(referrer), referrer_kind)?
self.path_to_declaration_url(
&file_path,
Some(referrer),
resolution_mode,
)?
} else {
url
};
@ -197,9 +205,9 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
&self,
specifier: &str,
referrer: &Url,
referrer_kind: NodeModuleKind,
resolution_mode: ResolutionMode,
conditions: &[&str],
mode: NodeResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, NodeResolveError> {
if should_be_treated_as_relative_or_absolute_path(specifier) {
Ok(node_join_url(referrer, specifier).map_err(|err| {
@ -218,10 +226,10 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
Ok(self.package_imports_resolve(
specifier,
Some(referrer),
referrer_kind,
resolution_mode,
pkg_config.as_deref(),
conditions,
mode,
resolution_kind,
)?)
} else if let Ok(resolved) = Url::parse(specifier) {
Ok(resolved)
@ -229,9 +237,9 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
Ok(self.package_resolve(
specifier,
referrer,
referrer_kind,
resolution_mode,
conditions,
mode,
resolution_kind,
)?)
}
}
@ -307,8 +315,8 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
package_dir: &Path,
package_subpath: Option<&str>,
maybe_referrer: Option<&Url>,
referrer_kind: NodeModuleKind,
mode: NodeResolutionMode,
resolution_mode: ResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, PackageSubpathResolveError> {
let package_subpath = package_subpath
.map(|s| format!("./{s}"))
@ -317,9 +325,9 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
package_dir,
&package_subpath,
maybe_referrer,
referrer_kind,
conditions_from_module_kind(referrer_kind),
mode,
resolution_mode,
conditions_from_resolution_mode(resolution_mode),
resolution_kind,
)?;
// TODO(bartlomieju): skipped checking errors for commonJS resolution and
// "preserveSymlinksMain"/"preserveSymlinks" options.
@ -385,13 +393,13 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
&self,
path: &Path,
maybe_referrer: Option<&Url>,
referrer_kind: NodeModuleKind,
resolution_mode: ResolutionMode,
) -> Result<Url, TypesNotFoundError> {
fn probe_extensions<TEnv: NodeResolverEnv>(
fs: &TEnv,
path: &Path,
lowercase_path: &str,
referrer_kind: NodeModuleKind,
resolution_mode: ResolutionMode,
) -> Option<PathBuf> {
let mut searched_for_d_mts = false;
let mut searched_for_d_cts = false;
@ -414,11 +422,11 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
return Some(dts_path);
}
let specific_dts_path = match referrer_kind {
NodeModuleKind::Cjs if !searched_for_d_cts => {
let specific_dts_path = match resolution_mode {
ResolutionMode::Require if !searched_for_d_cts => {
Some(with_known_extension(path, "d.cts"))
}
NodeModuleKind::Esm if !searched_for_d_mts => {
ResolutionMode::Import if !searched_for_d_mts => {
Some(with_known_extension(path, "d.mts"))
}
_ => None, // already searched above
@ -439,7 +447,7 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
return Ok(url_from_file_path(path).unwrap());
}
if let Some(path) =
probe_extensions(&self.env, path, &lowercase_path, referrer_kind)
probe_extensions(&self.env, path, &lowercase_path, resolution_mode)
{
return Ok(url_from_file_path(&path).unwrap());
}
@ -448,9 +456,9 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
path,
/* sub path */ ".",
maybe_referrer,
referrer_kind,
conditions_from_module_kind(referrer_kind),
NodeResolutionMode::Types,
resolution_mode,
conditions_from_resolution_mode(resolution_mode),
NodeResolutionKind::Types,
);
if let Ok(resolution) = resolution_result {
return Ok(resolution);
@ -460,7 +468,7 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
&self.env,
&index_path,
&index_path.to_string_lossy().to_lowercase(),
referrer_kind,
resolution_mode,
) {
return Ok(url_from_file_path(&path).unwrap());
}
@ -480,10 +488,10 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
&self,
name: &str,
maybe_referrer: Option<&Url>,
referrer_kind: NodeModuleKind,
resolution_mode: ResolutionMode,
referrer_pkg_json: Option<&PackageJson>,
conditions: &[&str],
mode: NodeResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, PackageImportsResolveError> {
if name == "#" || name.starts_with("#/") || name.ends_with('/') {
let reason = "is not a valid internal imports specifier name";
@ -509,11 +517,11 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
"",
name,
maybe_referrer,
referrer_kind,
resolution_mode,
false,
true,
conditions,
mode,
resolution_kind,
)?;
if let Some(resolved) = maybe_resolved {
return Ok(resolved);
@ -549,11 +557,11 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
best_match_subpath.unwrap(),
best_match,
maybe_referrer,
referrer_kind,
resolution_mode,
true,
true,
conditions,
mode,
resolution_kind,
)?;
if let Some(resolved) = maybe_resolved {
return Ok(resolved);
@ -581,11 +589,11 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
match_: &str,
package_json_path: &Path,
maybe_referrer: Option<&Url>,
referrer_kind: NodeModuleKind,
resolution_mode: ResolutionMode,
pattern: bool,
internal: bool,
conditions: &[&str],
mode: NodeResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, PackageTargetResolveError> {
if !subpath.is_empty() && !pattern && !target.ends_with('/') {
return Err(
@ -626,9 +634,9 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
let result = match self.package_resolve(
&export_target,
&package_json_url,
referrer_kind,
resolution_mode,
conditions,
mode,
resolution_kind,
) {
Ok(url) => Ok(url),
Err(err) => match err.code() {
@ -649,8 +657,8 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
pkg_json_path: package_json_path.to_path_buf(),
target: export_target.to_string(),
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
referrer_kind,
mode,
resolution_mode,
resolution_kind,
},
)
.into(),
@ -746,11 +754,11 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
subpath: &str,
package_subpath: &str,
maybe_referrer: Option<&Url>,
referrer_kind: NodeModuleKind,
resolution_mode: ResolutionMode,
pattern: bool,
internal: bool,
conditions: &[&str],
mode: NodeResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Option<Url>, PackageTargetResolveError> {
let result = self.resolve_package_target_inner(
package_json_path,
@ -758,16 +766,16 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
subpath,
package_subpath,
maybe_referrer,
referrer_kind,
resolution_mode,
pattern,
internal,
conditions,
mode,
resolution_kind,
);
match result {
Ok(maybe_resolved) => Ok(maybe_resolved),
Err(err) => {
if mode.is_types()
if resolution_kind.is_types()
&& err.code() == NodeJsErrorCode::ERR_TYPES_NOT_FOUND
&& conditions != TYPES_ONLY_CONDITIONS
{
@ -779,11 +787,11 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
subpath,
package_subpath,
maybe_referrer,
referrer_kind,
resolution_mode,
pattern,
internal,
TYPES_ONLY_CONDITIONS,
mode,
resolution_kind,
) {
return Ok(Some(resolved));
}
@ -802,11 +810,11 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
subpath: &str,
package_subpath: &str,
maybe_referrer: Option<&Url>,
referrer_kind: NodeModuleKind,
resolution_mode: ResolutionMode,
pattern: bool,
internal: bool,
conditions: &[&str],
mode: NodeResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Option<Url>, PackageTargetResolveError> {
if let Some(target) = target.as_str() {
let url = self.resolve_package_target_string(
@ -815,18 +823,18 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
package_subpath,
package_json_path,
maybe_referrer,
referrer_kind,
resolution_mode,
pattern,
internal,
conditions,
mode,
resolution_kind,
)?;
if mode.is_types() && url.scheme() == "file" {
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,
maybe_referrer,
referrer_kind,
resolution_mode,
)?));
} else {
return Ok(Some(url));
@ -844,11 +852,11 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
subpath,
package_subpath,
maybe_referrer,
referrer_kind,
resolution_mode,
pattern,
internal,
conditions,
mode,
resolution_kind,
);
match resolved_result {
@ -882,7 +890,7 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
if key == "default"
|| conditions.contains(&key.as_str())
|| mode.is_types() && key.as_str() == "types"
|| resolution_kind.is_types() && key.as_str() == "types"
{
let condition_target = target_obj.get(key).unwrap();
@ -892,11 +900,11 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
subpath,
package_subpath,
maybe_referrer,
referrer_kind,
resolution_mode,
pattern,
internal,
conditions,
mode,
resolution_kind,
)?;
match resolved {
Some(resolved) => return Ok(Some(resolved)),
@ -929,9 +937,9 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
package_subpath: &str,
package_exports: &Map<String, Value>,
maybe_referrer: Option<&Url>,
referrer_kind: NodeModuleKind,
resolution_mode: ResolutionMode,
conditions: &[&str],
mode: NodeResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, PackageExportsResolveError> {
if package_exports.contains_key(package_subpath)
&& package_subpath.find('*').is_none()
@ -944,11 +952,11 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
"",
package_subpath,
maybe_referrer,
referrer_kind,
resolution_mode,
false,
false,
conditions,
mode,
resolution_kind,
)?;
return match resolved {
Some(resolved) => Ok(resolved),
@ -957,7 +965,7 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
pkg_json_path: package_json_path.to_path_buf(),
subpath: package_subpath.to_string(),
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
mode,
resolution_kind,
}
.into(),
),
@ -1006,11 +1014,11 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
&best_match_subpath.unwrap(),
best_match,
maybe_referrer,
referrer_kind,
resolution_mode,
true,
false,
conditions,
mode,
resolution_kind,
)?;
if let Some(resolved) = maybe_resolved {
return Ok(resolved);
@ -1020,7 +1028,7 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
pkg_json_path: package_json_path.to_path_buf(),
subpath: package_subpath.to_string(),
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
mode,
resolution_kind,
}
.into(),
);
@ -1032,7 +1040,7 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
pkg_json_path: package_json_path.to_path_buf(),
subpath: package_subpath.to_string(),
maybe_referrer: maybe_referrer.map(ToOwned::to_owned),
mode,
resolution_kind,
}
.into(),
)
@ -1042,9 +1050,9 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
&self,
specifier: &str,
referrer: &Url,
referrer_kind: NodeModuleKind,
resolution_mode: ResolutionMode,
conditions: &[&str],
mode: NodeResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, PackageResolveError> {
let (package_name, package_subpath, _is_scoped) =
parse_npm_pkg_name(specifier, referrer)?;
@ -1061,9 +1069,9 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
&package_subpath,
exports,
Some(referrer),
referrer_kind,
resolution_mode,
conditions,
mode,
resolution_kind,
)
.map_err(|err| err.into());
}
@ -1074,9 +1082,9 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
&package_name,
&package_subpath,
referrer,
referrer_kind,
resolution_mode,
conditions,
mode,
resolution_kind,
)
}
@ -1086,28 +1094,28 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
package_name: &str,
package_subpath: &str,
referrer: &Url,
referrer_kind: NodeModuleKind,
resolution_mode: ResolutionMode,
conditions: &[&str],
mode: NodeResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, PackageResolveError> {
let result = self.resolve_package_subpath_for_package_inner(
package_name,
package_subpath,
referrer,
referrer_kind,
resolution_mode,
conditions,
mode,
resolution_kind,
);
if mode.is_types() && !matches!(result, Ok(Url { .. })) {
if resolution_kind.is_types() && !matches!(result, Ok(Url { .. })) {
// 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(
&package_name,
package_subpath,
referrer,
referrer_kind,
resolution_mode,
conditions,
mode,
resolution_kind,
) {
return Ok(result);
}
@ -1121,9 +1129,9 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
package_name: &str,
package_subpath: &str,
referrer: &Url,
referrer_kind: NodeModuleKind,
resolution_mode: ResolutionMode,
conditions: &[&str],
mode: NodeResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, PackageResolveError> {
let package_dir_path = self
.npm_pkg_folder_resolver
@ -1148,9 +1156,9 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
&package_dir_path,
package_subpath,
Some(referrer),
referrer_kind,
resolution_mode,
conditions,
mode,
resolution_kind,
)
.map_err(|err| err.into())
}
@ -1161,9 +1169,9 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
package_dir_path: &Path,
package_subpath: &str,
maybe_referrer: Option<&Url>,
referrer_kind: NodeModuleKind,
resolution_mode: ResolutionMode,
conditions: &[&str],
mode: NodeResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, PackageSubpathResolveError> {
let package_json_path = package_dir_path.join("package.json");
match self
@ -1174,17 +1182,17 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
&pkg_json,
package_subpath,
maybe_referrer,
referrer_kind,
resolution_mode,
conditions,
mode,
resolution_kind,
),
None => self
.resolve_package_subpath_no_pkg_json(
package_dir_path,
package_subpath,
maybe_referrer,
referrer_kind,
mode,
resolution_mode,
resolution_kind,
)
.map_err(|err| {
PackageSubpathResolveErrorKind::LegacyResolve(err).into()
@ -1198,9 +1206,9 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
package_json: &PackageJson,
package_subpath: &str,
referrer: Option<&Url>,
referrer_kind: NodeModuleKind,
resolution_mode: ResolutionMode,
conditions: &[&str],
mode: NodeResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, PackageSubpathResolveError> {
if let Some(exports) = &package_json.exports {
let result = self.package_exports_resolve(
@ -1208,16 +1216,21 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
package_subpath,
exports,
referrer,
referrer_kind,
resolution_mode,
conditions,
mode,
resolution_kind,
);
match result {
Ok(found) => return Ok(found),
Err(exports_err) => {
if mode.is_types() && package_subpath == "." {
if resolution_kind.is_types() && package_subpath == "." {
return self
.legacy_main_resolve(package_json, referrer, referrer_kind, mode)
.legacy_main_resolve(
package_json,
referrer,
resolution_mode,
resolution_kind,
)
.map_err(|err| {
PackageSubpathResolveErrorKind::LegacyResolve(err).into()
});
@ -1231,7 +1244,12 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
if package_subpath == "." {
return self
.legacy_main_resolve(package_json, referrer, referrer_kind, mode)
.legacy_main_resolve(
package_json,
referrer,
resolution_mode,
resolution_kind,
)
.map_err(|err| {
PackageSubpathResolveErrorKind::LegacyResolve(err).into()
});
@ -1242,8 +1260,8 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
package_json.path.parent().unwrap(),
package_subpath,
referrer,
referrer_kind,
mode,
resolution_mode,
resolution_kind,
)
.map_err(|err| {
PackageSubpathResolveErrorKind::LegacyResolve(err.into()).into()
@ -1255,13 +1273,13 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
directory: &Path,
package_subpath: &str,
referrer: Option<&Url>,
referrer_kind: NodeModuleKind,
mode: NodeResolutionMode,
resolution_mode: ResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, TypesNotFoundError> {
assert_ne!(package_subpath, ".");
let file_path = directory.join(package_subpath);
if mode.is_types() {
Ok(self.path_to_declaration_url(&file_path, referrer, referrer_kind)?)
if resolution_kind.is_types() {
Ok(self.path_to_declaration_url(&file_path, referrer, resolution_mode)?)
} else {
Ok(url_from_file_path(&file_path).unwrap())
}
@ -1272,19 +1290,24 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
directory: &Path,
package_subpath: &str,
maybe_referrer: Option<&Url>,
referrer_kind: NodeModuleKind,
mode: NodeResolutionMode,
resolution_mode: ResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, LegacyResolveError> {
if package_subpath == "." {
self.legacy_index_resolve(directory, maybe_referrer, referrer_kind, mode)
self.legacy_index_resolve(
directory,
maybe_referrer,
resolution_mode,
resolution_kind,
)
} else {
self
.resolve_subpath_exact(
directory,
package_subpath,
maybe_referrer,
referrer_kind,
mode,
resolution_mode,
resolution_kind,
)
.map_err(|err| err.into())
}
@ -1294,21 +1317,25 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
&self,
package_json: &PackageJson,
maybe_referrer: Option<&Url>,
referrer_kind: NodeModuleKind,
mode: NodeResolutionMode,
resolution_mode: ResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, LegacyResolveError> {
let maybe_main = if mode.is_types() {
let pkg_json_kind = match resolution_mode {
ResolutionMode::Require => deno_package_json::NodeModuleKind::Cjs,
ResolutionMode::Import => deno_package_json::NodeModuleKind::Esm,
};
let maybe_main = if resolution_kind.is_types() {
match package_json.types.as_ref() {
Some(types) => Some(types.as_str()),
None => {
// fallback to checking the main entrypoint for
// a corresponding declaration file
if let Some(main) = package_json.main(referrer_kind) {
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,
maybe_referrer,
referrer_kind,
resolution_mode,
);
// don't surface errors, fallback to checking the index now
if let Ok(url) = decl_url_result {
@ -1319,7 +1346,7 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
}
}
} else {
package_json.main(referrer_kind)
package_json.main(pkg_json_kind)
};
if let Some(main) = maybe_main {
@ -1329,12 +1356,12 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
}
// todo(dsherret): investigate exactly how node and typescript handles this
let endings = if mode.is_types() {
match referrer_kind {
NodeModuleKind::Cjs => {
let endings = if resolution_kind.is_types() {
match resolution_mode {
ResolutionMode::Require => {
vec![".d.ts", ".d.cts", "/index.d.ts", "/index.d.cts"]
}
NodeModuleKind::Esm => vec![
ResolutionMode::Import => vec![
".d.ts",
".d.mts",
"/index.d.ts",
@ -1363,8 +1390,8 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
self.legacy_index_resolve(
package_json.path.parent().unwrap(),
maybe_referrer,
referrer_kind,
mode,
resolution_mode,
resolution_kind,
)
}
@ -1372,14 +1399,16 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
&self,
directory: &Path,
maybe_referrer: Option<&Url>,
referrer_kind: NodeModuleKind,
mode: NodeResolutionMode,
resolution_mode: ResolutionMode,
resolution_kind: NodeResolutionKind,
) -> Result<Url, LegacyResolveError> {
let index_file_names = if mode.is_types() {
let index_file_names = if resolution_kind.is_types() {
// todo(dsherret): investigate exactly how typescript does this
match referrer_kind {
NodeModuleKind::Cjs => vec!["index.d.ts", "index.d.cts"],
NodeModuleKind::Esm => vec!["index.d.ts", "index.d.mts", "index.d.cts"],
match resolution_mode {
ResolutionMode::Require => vec!["index.d.ts", "index.d.cts"],
ResolutionMode::Import => {
vec!["index.d.ts", "index.d.mts", "index.d.cts"]
}
}
} else {
vec!["index.js"]
@ -1392,7 +1421,7 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
}
}
if mode.is_types() {
if resolution_kind.is_types() {
Err(
TypesNotFoundError(Box::new(TypesNotFoundErrorData {
code_specifier: url_from_file_path(&directory.join("index.js"))