summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock84
-rw-r--r--Cargo.toml2
-rw-r--r--cli/Cargo.toml2
-rw-r--r--cli/graph_util.rs9
-rw-r--r--cli/lsp/diagnostics.rs3
-rw-r--r--cli/lsp/documents.rs72
-rw-r--r--cli/resolver.rs205
-rw-r--r--cli/tools/registry/unfurl.rs2
-rw-r--r--tests/integration/check_tests.rs102
-rw-r--r--tests/testdata/publish/sloppy_imports.out2
10 files changed, 348 insertions, 135 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8cbbe2a63..ca0194858 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1124,9 +1124,9 @@ dependencies = [
[[package]]
name = "deno_ast"
-version = "0.34.0"
+version = "0.34.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84b28da6d573c30a63e4a6b66b91fa32773ed2cf4c0f26aa19b91f6c542b1a57"
+checksum = "a73fa2b215c93d44b55228a6c69aa92ffa200cfa683ebaf45202ecfbd749bf52"
dependencies = [
"anyhow",
"base64",
@@ -1434,9 +1434,9 @@ dependencies = [
[[package]]
name = "deno_graph"
-version = "0.69.4"
+version = "0.69.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73c83b0538ee10854dcf0f24aa05ec79f62e308b358cefd65d30f9d0959a9dc3"
+checksum = "d49d7cfd7eb14200f2d91b9ff3330b7bd86334060367d47248871c78374a2897"
dependencies = [
"anyhow",
"async-trait",
@@ -2251,9 +2251,9 @@ dependencies = [
[[package]]
name = "dprint-swc-ext"
-version = "0.15.0"
+version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fcd02c378803dba687471a9f1f1b758c33e53f616333faaddbaeb8840d9b6dd"
+checksum = "5bad772f9e49af3a613fcddf1671d1e2e877e0a6d94f2b7162bfea4ac8140bee"
dependencies = [
"allocator-api2",
"bumpalo",
@@ -5945,9 +5945,9 @@ dependencies = [
[[package]]
name = "swc_bundler"
-version = "0.225.6"
+version = "0.225.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84a10c82d574fd928182f90962e280967b23b692d7e21ec9484dc6cbdaa73bab"
+checksum = "21736fd17b258d4324f576e1d151d997fd5370a04b68dcb59f3e5050828de33f"
dependencies = [
"anyhow",
"crc",
@@ -5989,9 +5989,9 @@ dependencies = [
[[package]]
name = "swc_common"
-version = "0.33.17"
+version = "0.33.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "095c158fe55b36faeebb4274692643a6d7cdc5b7902e1d5968ddbe52b7de1d1c"
+checksum = "c85e8b15d0fb87691e27c8f3cf953748db3ccd2a39e165d6d5275a48fb0d29e3"
dependencies = [
"ast_node",
"better_scoped_tls",
@@ -6041,9 +6041,9 @@ dependencies = [
[[package]]
name = "swc_ecma_ast"
-version = "0.112.2"
+version = "0.112.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "852a48a24a2533de88298c6b25355bc68fdee31ac21cb4fb8939b7001715353c"
+checksum = "36226eb87bfd2f5620bde04f149a4b869ab34e78496d60cb0d8eb9da765d0732"
dependencies = [
"bitflags 2.4.1",
"is-macro",
@@ -6059,9 +6059,9 @@ dependencies = [
[[package]]
name = "swc_ecma_codegen"
-version = "0.148.3"
+version = "0.148.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d79df3f8c5ed028fce5dc24acb83002c0854f8b9d7e893292aeee394a6b9eaf4"
+checksum = "5ba8669ab28bb5d1e65c1e8690257c026745ac368e0101c2c6544d4a03afc95e"
dependencies = [
"memchr",
"num-bigint",
@@ -6090,9 +6090,9 @@ dependencies = [
[[package]]
name = "swc_ecma_loader"
-version = "0.45.19"
+version = "0.45.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c16051bce5421992a1b49350735bf4d110f761fd68ae7098af17a64ad639b8d"
+checksum = "d0058cf970880f5382effe43eb2b727a73ba09ae41922fa140c2c3fa6ca9b2d1"
dependencies = [
"anyhow",
"pathdiff",
@@ -6104,9 +6104,9 @@ dependencies = [
[[package]]
name = "swc_ecma_parser"
-version = "0.143.3"
+version = "0.143.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90ff55811ed5de14b05e9a2979bae2bce3c807582f559b4325948463265307d9"
+checksum = "20823cac99a9adbd4c03fb5e126aaccbf92446afedad99252a0e1fc76e2ffc43"
dependencies = [
"either",
"new_debug_unreachable",
@@ -6126,9 +6126,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_base"
-version = "0.137.6"
+version = "0.137.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9489f8f5c6c08e8291bd93eb354aa91903d4eba5eeb72e1b90adf43c8fe7a29"
+checksum = "66539401f619730b26d380a120b91b499f80cbdd9bb15d00aa73bc3a4d4cc394"
dependencies = [
"better_scoped_tls",
"bitflags 2.4.1",
@@ -6149,9 +6149,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_classes"
-version = "0.126.6"
+version = "0.126.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c00fecbd333497362f75f475ca467beb486ae381968c9bd67315dddacc9ee67c"
+checksum = "ebf9048e687b746d2bbe6149601c3eedd819fef08d7657e5fddcef99b22febba"
dependencies = [
"swc_atoms",
"swc_common",
@@ -6175,9 +6175,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_optimization"
-version = "0.198.6"
+version = "0.198.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db73c718c737c58ed7265fea79aff38578012269398d856264ddc4e764dfb192"
+checksum = "17889816334ce9d05ab0c292f93514fdd863b8537a35852dda609ebe3f48071d"
dependencies = [
"dashmap",
"indexmap",
@@ -6199,9 +6199,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_proposal"
-version = "0.171.6"
+version = "0.171.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39920f44aa30ab997dd7cfdc364addd54e4a5fcc3807ae69a6fe283f306bc5a5"
+checksum = "35f0a72ee781aa9208836046fd2c12e483f5515898858511b68863290cb97b45"
dependencies = [
"either",
"rustc-hash",
@@ -6219,9 +6219,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_react"
-version = "0.183.6"
+version = "0.183.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33d8d36fc8dbfd96dd1ef17f989175e60a291399c6168b20a74951085b0075df"
+checksum = "f0ec75c1194365abe4d44d94e58f918ec853469ecd39733b381a089cfdcdee1a"
dependencies = [
"base64",
"dashmap",
@@ -6243,9 +6243,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_typescript"
-version = "0.188.6"
+version = "0.188.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "432cf63b05d3ec435199bfbf7ba50793c6cb777bfcd8ad9f055f501aa9048d9c"
+checksum = "fec5e95a9c840eb13562884123eaa627cb6e05e0461c94a2ce69ae7e70313010"
dependencies = [
"ryu-js",
"serde",
@@ -6260,9 +6260,9 @@ dependencies = [
[[package]]
name = "swc_ecma_utils"
-version = "0.127.5"
+version = "0.127.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2de25ac5cc8c8375476985e854054f05d9e841886f3c290716a0eec32eedce3"
+checksum = "14482e455df85486d68a51533a31645d511e56df93a35cadf0eabbe7abe96b98"
dependencies = [
"indexmap",
"num_cpus",
@@ -6278,9 +6278,9 @@ dependencies = [
[[package]]
name = "swc_ecma_visit"
-version = "0.98.2"
+version = "0.98.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdb71511a816c7c84ddc96e6939389be261caf20858486a5e76948551f110e1f"
+checksum = "df0127694c36d656ea9eab5c170cdd8ab398246ae2a335de26961c913a4aca47"
dependencies = [
"num-bigint",
"swc_atoms",
@@ -6303,9 +6303,9 @@ dependencies = [
[[package]]
name = "swc_fast_graph"
-version = "0.21.17"
+version = "0.21.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffd32eda2dd2c725f8d4448d0013c3b5466118e4ff5c30aff2c04f6750f7238b"
+checksum = "91bea847755eb7b131edb83c1a437d353e9d25cabd92ac27655420dd13c7267b"
dependencies = [
"indexmap",
"petgraph",
@@ -6315,9 +6315,9 @@ dependencies = [
[[package]]
name = "swc_graph_analyzer"
-version = "0.22.19"
+version = "0.22.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52ae1172960aa3b0cdbe94a1d5edf3efa9f1199cbd8384f48dedd0c5bdb5d6bd"
+checksum = "1f1469d9d6d5c6f3b469348262ab6bda2c8a9d8e3db7298d9f71f6d17986895d"
dependencies = [
"auto_impl",
"petgraph",
@@ -6339,9 +6339,9 @@ dependencies = [
[[package]]
name = "swc_visit"
-version = "0.5.8"
+version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b27078d8571abe23aa52ef608dd1df89096a37d867cf691cbb4f4c392322b7c9"
+checksum = "358e246dedeb4ae8efacebcce1360dc2f9b6c0b4c1ad8b737cc60f5b6633691a"
dependencies = [
"either",
"swc_visit_macros",
@@ -6349,9 +6349,9 @@ dependencies = [
[[package]]
name = "swc_visit_macros"
-version = "0.5.9"
+version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa8bb05975506741555ea4d10c3a3bdb0e2357cd58e1a4a4332b8ebb4b44c34d"
+checksum = "fbbbb9d77d5112f90ed7ea00477135b16c4370c872b93a0b63b766e8710650ad"
dependencies = [
"Inflector",
"pmutil",
diff --git a/Cargo.toml b/Cargo.toml
index 9949ad06c..be13eca7d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -42,7 +42,7 @@ license = "MIT"
repository = "https://github.com/denoland/deno"
[workspace.dependencies]
-deno_ast = { version = "0.34.0", features = ["transpiling"] }
+deno_ast = { version = "0.34.1", features = ["transpiling"] }
deno_core = { version = "0.265.0", features = ["snapshot_data_bincode"] }
deno_bench_util = { version = "0.133.0", path = "./bench_util" }
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index 0d71eae1e..18bafb77e 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -68,7 +68,7 @@ deno_config = "=0.12.0"
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
deno_doc = { version = "=0.113.1", features = ["html"] }
deno_emit = "=0.38.2"
-deno_graph = { version = "=0.69.4", features = ["tokio_executor"] }
+deno_graph = { version = "=0.69.5", features = ["tokio_executor"] }
deno_lint = { version = "=0.57.1", features = ["docs"] }
deno_lockfile.workspace = true
deno_npm = "=0.17.0"
diff --git a/cli/graph_util.rs b/cli/graph_util.rs
index facff0af5..0ed591fb7 100644
--- a/cli/graph_util.rs
+++ b/cli/graph_util.rs
@@ -30,6 +30,7 @@ use deno_core::parking_lot::Mutex;
use deno_core::parking_lot::RwLock;
use deno_core::ModuleSpecifier;
use deno_graph::source::Loader;
+use deno_graph::source::ResolutionMode;
use deno_graph::source::ResolveError;
use deno_graph::GraphKind;
use deno_graph::Module;
@@ -694,8 +695,12 @@ pub fn enhanced_module_error_message(
) -> String {
let additional_message = match error {
ModuleError::Missing(specifier, _) => {
- SloppyImportsResolver::resolve_with_fs(fs, specifier)
- .as_suggestion_message()
+ SloppyImportsResolver::resolve_with_fs(
+ fs,
+ specifier,
+ ResolutionMode::Execution,
+ )
+ .as_suggestion_message()
}
_ => None,
};
diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs
index e3e206a52..25cfd94e2 100644
--- a/cli/lsp/diagnostics.rs
+++ b/cli/lsp/diagnostics.rs
@@ -35,6 +35,7 @@ use deno_core::unsync::spawn;
use deno_core::unsync::spawn_blocking;
use deno_core::unsync::JoinHandle;
use deno_core::ModuleSpecifier;
+use deno_graph::source::ResolutionMode;
use deno_graph::Resolution;
use deno_graph::ResolutionError;
use deno_graph::SpecifierError;
@@ -1240,7 +1241,7 @@ impl DenoDiagnostic {
Self::NoCacheJsr(pkg_req, specifier) => (lsp::DiagnosticSeverity::ERROR, format!("Uncached or missing jsr package: {}", pkg_req), Some(json!({ "specifier": specifier }))),
Self::NoCacheNpm(pkg_req, specifier) => (lsp::DiagnosticSeverity::ERROR, format!("Uncached or missing npm package: {}", pkg_req), Some(json!({ "specifier": specifier }))),
Self::NoLocal(specifier) => {
- let sloppy_resolution = SloppyImportsResolver::resolve_with_fs(&deno_fs::RealFs, specifier);
+ let sloppy_resolution = SloppyImportsResolver::resolve_with_fs(&deno_fs::RealFs, specifier, ResolutionMode::Execution);
let data = sloppy_resolution.as_lsp_quick_fix_message().map(|message| {
json!({
"specifier": specifier,
diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs
index 66ebe5115..419d08d50 100644
--- a/cli/lsp/documents.rs
+++ b/cli/lsp/documents.rs
@@ -1101,24 +1101,28 @@ impl Documents {
&self,
specifier: &'a ModuleSpecifier,
) -> SloppyImportsResolution<'a> {
- SloppyImportsResolver::resolve_with_stat_sync(specifier, |path| {
- if let Ok(specifier) = ModuleSpecifier::from_file_path(path) {
- if self.open_docs.contains_key(&specifier)
- || self.cache.contains(&specifier)
- {
- return Some(SloppyImportsFsEntry::File);
- }
- }
- path.metadata().ok().and_then(|m| {
- if m.is_file() {
- Some(SloppyImportsFsEntry::File)
- } else if m.is_dir() {
- Some(SloppyImportsFsEntry::Dir)
- } else {
- None
+ SloppyImportsResolver::resolve_with_stat_sync(
+ specifier,
+ ResolutionMode::Types,
+ |path| {
+ if let Ok(specifier) = ModuleSpecifier::from_file_path(path) {
+ if self.open_docs.contains_key(&specifier)
+ || self.cache.contains(&specifier)
+ {
+ return Some(SloppyImportsFsEntry::File);
+ }
}
- })
- })
+ path.metadata().ok().and_then(|m| {
+ if m.is_file() {
+ Some(SloppyImportsFsEntry::File)
+ } else if m.is_dir() {
+ Some(SloppyImportsFsEntry::Dir)
+ } else {
+ None
+ }
+ })
+ },
+ )
}
/// Return `true` if the specifier can be resolved to a document.
@@ -1800,22 +1804,26 @@ impl<'a> OpenDocumentsGraphLoader<'a> {
&self,
specifier: &'b ModuleSpecifier,
) -> SloppyImportsResolution<'b> {
- SloppyImportsResolver::resolve_with_stat_sync(specifier, |path| {
- if let Ok(specifier) = ModuleSpecifier::from_file_path(path) {
- if self.open_docs.contains_key(&specifier) {
- return Some(SloppyImportsFsEntry::File);
- }
- }
- path.metadata().ok().and_then(|m| {
- if m.is_file() {
- Some(SloppyImportsFsEntry::File)
- } else if m.is_dir() {
- Some(SloppyImportsFsEntry::Dir)
- } else {
- None
+ SloppyImportsResolver::resolve_with_stat_sync(
+ specifier,
+ ResolutionMode::Types,
+ |path| {
+ if let Ok(specifier) = ModuleSpecifier::from_file_path(path) {
+ if self.open_docs.contains_key(&specifier) {
+ return Some(SloppyImportsFsEntry::File);
+ }
}
- })
- })
+ path.metadata().ok().and_then(|m| {
+ if m.is_file() {
+ Some(SloppyImportsFsEntry::File)
+ } else if m.is_dir() {
+ Some(SloppyImportsFsEntry::Dir)
+ } else {
+ None
+ }
+ })
+ },
+ )
}
}
diff --git a/cli/resolver.rs b/cli/resolver.rs
index 5bb9e66d0..de85992a7 100644
--- a/cli/resolver.rs
+++ b/cli/resolver.rs
@@ -522,6 +522,7 @@ impl Resolver for CliGraphResolver {
sloppy_imports_resolver,
specifier,
referrer_range,
+ mode,
)
})
} else {
@@ -646,12 +647,22 @@ fn sloppy_imports_resolve(
resolver: &SloppyImportsResolver,
specifier: ModuleSpecifier,
referrer_range: &deno_graph::Range,
+ mode: ResolutionMode,
) -> ModuleSpecifier {
- let resolution = resolver.resolve(&specifier);
+ let resolution = resolver.resolve(&specifier, mode);
+ if mode.is_types() {
+ // don't bother warning for types resolution because
+ // we already probably warned during execution resolution
+ match resolution {
+ SloppyImportsResolution::None(_) => return specifier, // avoid a clone
+ _ => return resolution.into_specifier().into_owned(),
+ }
+ }
+
let hint_message = match &resolution {
SloppyImportsResolution::JsToTs(to_specifier) => {
- let from_media_type = MediaType::from_specifier(&specifier);
let to_media_type = MediaType::from_specifier(to_specifier);
+ let from_media_type = MediaType::from_specifier(&specifier);
format!(
"update {} extension to {}",
from_media_type.as_ts_extension(),
@@ -677,7 +688,7 @@ fn sloppy_imports_resolve(
log::warn!(
"{} Sloppy module resolution {}\n at {}",
crate::colors::yellow("Warning"),
- crate::colors::gray(format!("(hint: {})", hint_message)),
+ crate::colors::gray(format!("(hint: {})", hint_message)).to_string(),
if referrer_range.end == deno_graph::Position::zeroed() {
// not worth showing the range in this case
crate::colors::cyan(referrer_range.specifier.as_str()).to_string()
@@ -928,8 +939,9 @@ impl SloppyImportsResolver {
pub fn resolve_with_fs<'a>(
fs: &dyn FileSystem,
specifier: &'a ModuleSpecifier,
+ mode: ResolutionMode,
) -> SloppyImportsResolution<'a> {
- Self::resolve_with_stat_sync(specifier, |path| {
+ Self::resolve_with_stat_sync(specifier, mode, |path| {
fs.stat_sync(path)
.ok()
.and_then(|stat| SloppyImportsFsEntry::from_fs_stat(&stat))
@@ -938,8 +950,38 @@ impl SloppyImportsResolver {
pub fn resolve_with_stat_sync(
specifier: &ModuleSpecifier,
+ mode: ResolutionMode,
stat_sync: impl Fn(&Path) -> Option<SloppyImportsFsEntry>,
) -> SloppyImportsResolution {
+ fn path_without_ext(
+ path: &Path,
+ media_type: MediaType,
+ ) -> Option<Cow<str>> {
+ let old_path_str = path.to_string_lossy();
+ match media_type {
+ MediaType::Unknown => Some(old_path_str),
+ _ => old_path_str
+ .strip_suffix(media_type.as_ts_extension())
+ .map(|s| Cow::Owned(s.to_string())),
+ }
+ }
+
+ fn media_types_to_paths(
+ path_no_ext: &str,
+ probe_media_type_types: Vec<MediaType>,
+ ) -> Vec<PathBuf> {
+ probe_media_type_types
+ .into_iter()
+ .map(|media_type| {
+ PathBuf::from(format!(
+ "{}{}",
+ path_no_ext,
+ media_type.as_ts_extension()
+ ))
+ })
+ .collect::<Vec<_>>()
+ }
+
if specifier.scheme() != "file" {
return SloppyImportsResolution::None(specifier);
}
@@ -951,27 +993,79 @@ impl SloppyImportsResolver {
let mut is_no_ext_resolution = false;
let probe_paths = match (stat_sync)(&path) {
Some(SloppyImportsFsEntry::File) => {
- return SloppyImportsResolution::None(specifier);
+ if mode.is_types() {
+ let media_type = MediaType::from_specifier(specifier);
+ // attempt to resolve the .d.ts file before the .js file
+ let probe_media_type_types = match media_type {
+ MediaType::JavaScript => {
+ vec![MediaType::Dts, MediaType::JavaScript]
+ }
+ MediaType::Mjs => {
+ vec![MediaType::Dmts, MediaType::Dts, MediaType::Mjs]
+ }
+ MediaType::Cjs => {
+ vec![MediaType::Dcts, MediaType::Dts, MediaType::Cjs]
+ }
+ _ => return SloppyImportsResolution::None(specifier),
+ };
+ let Some(path_no_ext) = path_without_ext(&path, media_type) else {
+ return SloppyImportsResolution::None(specifier);
+ };
+ media_types_to_paths(&path_no_ext, probe_media_type_types)
+ } else {
+ return SloppyImportsResolution::None(specifier);
+ }
}
Some(SloppyImportsFsEntry::Dir) => {
is_dir_resolution = true;
// try to resolve at the index file
- vec![
- path.join("index.ts"),
- path.join("index.js"),
- path.join("index.mts"),
- path.join("index.mjs"),
- path.join("index.tsx"),
- path.join("index.jsx"),
- ]
+ if mode.is_types() {
+ vec![
+ path.join("index.ts"),
+ path.join("index.mts"),
+ path.join("index.d.ts"),
+ path.join("index.d.mts"),
+ path.join("index.js"),
+ path.join("index.mjs"),
+ path.join("index.tsx"),
+ path.join("index.jsx"),
+ ]
+ } else {
+ vec![
+ path.join("index.ts"),
+ path.join("index.mts"),
+ path.join("index.tsx"),
+ path.join("index.js"),
+ path.join("index.mjs"),
+ path.join("index.jsx"),
+ ]
+ }
}
None => {
let media_type = MediaType::from_specifier(specifier);
let probe_media_type_types = match media_type {
- MediaType::JavaScript => vec![MediaType::TypeScript, MediaType::Tsx],
+ MediaType::JavaScript => {
+ if mode.is_types() {
+ vec![MediaType::TypeScript, MediaType::Tsx, MediaType::Dts]
+ } else {
+ vec![MediaType::TypeScript, MediaType::Tsx]
+ }
+ }
MediaType::Jsx => vec![MediaType::Tsx],
- MediaType::Mjs => vec![MediaType::Mts],
- MediaType::Cjs => vec![MediaType::Cts],
+ MediaType::Mjs => {
+ if mode.is_types() {
+ vec![MediaType::Mts, MediaType::Dmts, MediaType::Dts]
+ } else {
+ vec![MediaType::Mts]
+ }
+ }
+ MediaType::Cjs => {
+ if mode.is_types() {
+ vec![MediaType::Cts, MediaType::Dcts, MediaType::Dts]
+ } else {
+ vec![MediaType::Cts]
+ }
+ }
MediaType::TypeScript
| MediaType::Mts
| MediaType::Cts
@@ -987,34 +1081,34 @@ impl SloppyImportsResolver {
}
MediaType::Unknown => {
is_no_ext_resolution = true;
- vec![
- MediaType::TypeScript,
- MediaType::JavaScript,
- MediaType::Tsx,
- MediaType::Jsx,
- MediaType::Mts,
- MediaType::Mjs,
- ]
+ if mode.is_types() {
+ vec![
+ MediaType::TypeScript,
+ MediaType::Tsx,
+ MediaType::Mts,
+ MediaType::Dts,
+ MediaType::Dmts,
+ MediaType::Dcts,
+ MediaType::JavaScript,
+ MediaType::Jsx,
+ MediaType::Mjs,
+ ]
+ } else {
+ vec![
+ MediaType::TypeScript,
+ MediaType::JavaScript,
+ MediaType::Tsx,
+ MediaType::Jsx,
+ MediaType::Mts,
+ MediaType::Mjs,
+ ]
+ }
}
};
- let old_path_str = path.to_string_lossy();
- let old_path_str = match media_type {
- MediaType::Unknown => old_path_str,
- _ => match old_path_str.strip_suffix(media_type.as_ts_extension()) {
- Some(s) => Cow::Borrowed(s),
- None => return SloppyImportsResolution::None(specifier),
- },
+ let Some(path_no_ext) = path_without_ext(&path, media_type) else {
+ return SloppyImportsResolution::None(specifier);
};
- probe_media_type_types
- .into_iter()
- .map(|media_type| {
- PathBuf::from(format!(
- "{}{}",
- old_path_str,
- media_type.as_ts_extension()
- ))
- })
- .collect::<Vec<_>>()
+ media_types_to_paths(&path_no_ext, probe_media_type_types)
}
};
@@ -1038,8 +1132,9 @@ impl SloppyImportsResolver {
pub fn resolve<'a>(
&self,
specifier: &'a ModuleSpecifier,
+ mode: ResolutionMode,
) -> SloppyImportsResolution<'a> {
- Self::resolve_with_stat_sync(specifier, |path| {
+ Self::resolve_with_stat_sync(specifier, mode, |path| {
self.stat_cache.stat_sync(path)
})
}
@@ -1117,17 +1212,21 @@ mod test {
#[test]
fn test_unstable_sloppy_imports() {
fn resolve(specifier: &ModuleSpecifier) -> SloppyImportsResolution {
- SloppyImportsResolver::resolve_with_stat_sync(specifier, |path| {
- RealFs.stat_sync(path).ok().and_then(|stat| {
- if stat.is_file {
- Some(SloppyImportsFsEntry::File)
- } else if stat.is_directory {
- Some(SloppyImportsFsEntry::Dir)
- } else {
- None
- }
- })
- })
+ SloppyImportsResolver::resolve_with_stat_sync(
+ specifier,
+ ResolutionMode::Execution,
+ |path| {
+ RealFs.stat_sync(path).ok().and_then(|stat| {
+ if stat.is_file {
+ Some(SloppyImportsFsEntry::File)
+ } else if stat.is_directory {
+ Some(SloppyImportsFsEntry::Dir)
+ } else {
+ None
+ }
+ })
+ },
+ )
}
let context = TestContext::default();
diff --git a/cli/tools/registry/unfurl.rs b/cli/tools/registry/unfurl.rs
index abea2bd0c..6ed8bf99b 100644
--- a/cli/tools/registry/unfurl.rs
+++ b/cli/tools/registry/unfurl.rs
@@ -151,7 +151,7 @@ impl<'a> SpecifierUnfurler<'a> {
let resolved =
if let Some(sloppy_imports_resolver) = self.sloppy_imports_resolver {
sloppy_imports_resolver
- .resolve(&resolved)
+ .resolve(&resolved, deno_graph::source::ResolutionMode::Execution)
.as_specifier()
.clone()
} else {
diff --git a/tests/integration/check_tests.rs b/tests/integration/check_tests.rs
index d4d996b00..e97a40141 100644
--- a/tests/integration/check_tests.rs
+++ b/tests/integration/check_tests.rs
@@ -418,3 +418,105 @@ fn npm_module_check_then_error() {
.assert_matches_text("Check [WILDCARD]main.ts\nerror: TS2305[WILDCARD]has no exported member 'oldName'[WILDCARD]")
.assert_exit_code(1);
}
+
+#[test]
+fn test_unstable_sloppy_imports_dts_files() {
+ let context = TestContextBuilder::new().use_temp_cwd().build();
+ let temp_dir = context.temp_dir();
+ temp_dir.write("a.ts", "export class A {}"); // resolves this
+ temp_dir.write("a.d.ts", "export class A2 {}");
+
+ temp_dir.write("b.js", "export class B {}");
+ temp_dir.write("b.d.ts", "export class B2 {}"); // this
+
+ temp_dir.write("c.mts", "export class C {}"); // this
+ temp_dir.write("c.d.mts", "export class C2 {}");
+
+ temp_dir.write("d.mjs", "export class D {}");
+ temp_dir.write("d.d.mts", "export class D2 {}"); // this
+
+ let temp_dir = temp_dir.path();
+
+ let dir = temp_dir.join("dir_ts");
+ dir.create_dir_all();
+ dir.join("index.ts").write("export class Dir {}"); // this
+ dir.join("index.d.ts").write("export class Dir2 {}");
+
+ let dir = temp_dir.join("dir_js");
+ dir.create_dir_all();
+ dir.join("index.js").write("export class Dir {}");
+ dir.join("index.d.ts").write("export class Dir2 {}"); // this
+
+ let dir = temp_dir.join("dir_mts");
+ dir.create_dir_all();
+ dir.join("index.mts").write("export class Dir {}"); // this
+ dir.join("index.d.ts").write("export class Dir2 {}");
+
+ let dir = temp_dir.join("dir_mjs");
+ dir.create_dir_all();
+ dir.join("index.mjs").write("export class Dir {}");
+ dir.join("index.d.ts").write("export class Dir2 {}"); // this
+
+ temp_dir.join("main.ts").write(
+ r#"import * as a from "./a.js";
+import * as b from "./b.js";
+import * as c from "./c.mjs";
+import * as d from "./d.mjs";
+
+console.log(a.A);
+console.log(b.B2);
+console.log(c.C);
+console.log(d.D2);
+
+import * as a2 from "./a";
+import * as b2 from "./b";
+import * as c2 from "./c";
+import * as d2 from "./d";
+
+console.log(a2.A);
+console.log(b2.B2);
+console.log(c2.C);
+console.log(d2.D2);
+
+import * as dirTs from "./dir_ts";
+import * as dirJs from "./dir_js";
+import * as dirMts from "./dir_mts";
+import * as dirMjs from "./dir_mjs";
+
+console.log(dirTs.Dir);
+console.log(dirJs.Dir2);
+console.log(dirMts.Dir);
+console.log(dirMjs.Dir2);
+"#,
+ );
+
+ context
+ .new_command()
+ .args("check --unstable-sloppy-imports main.ts")
+ .run()
+ .assert_matches_text(
+ r#"Warning Sloppy module resolution (hint: update .js extension to .ts)
+ at file:///[WILDCARD]/main.ts:1:20
+Warning Sloppy module resolution (hint: update .mjs extension to .mts)
+ at file:///[WILDCARD]/main.ts:3:20
+Warning Sloppy module resolution (hint: add .ts extension)
+ at file:///[WILDCARD]/main.ts:11:21
+Warning Sloppy module resolution (hint: add .js extension)
+ at file:///[WILDCARD]/main.ts:12:21
+Warning Sloppy module resolution (hint: add .mts extension)
+ at file:///[WILDCARD]/main.ts:13:21
+Warning Sloppy module resolution (hint: add .mjs extension)
+ at file:///[WILDCARD]/main.ts:14:21
+Warning Sloppy module resolution (hint: specify path to index.ts file in directory instead)
+ at file:///[WILDCARD]/main.ts:21:24
+Warning Sloppy module resolution (hint: specify path to index.js file in directory instead)
+ at file:///[WILDCARD]/main.ts:22:24
+Warning Sloppy module resolution (hint: specify path to index.mts file in directory instead)
+ at file:///[WILDCARD]/main.ts:23:25
+Warning Sloppy module resolution (hint: specify path to index.mjs file in directory instead)
+ at file:///[WILDCARD]/main.ts:24:25
+Check [WILDCARD]main.ts
+"#,
+ )
+ .assert_exit_code(0);
+}
diff --git a/tests/testdata/publish/sloppy_imports.out b/tests/testdata/publish/sloppy_imports.out
index a3af86575..342eccdc3 100644
--- a/tests/testdata/publish/sloppy_imports.out
+++ b/tests/testdata/publish/sloppy_imports.out
@@ -1,7 +1,5 @@
Warning Sloppy module resolution (hint: specify path to index.ts file in directory instead)
at file:///[WILDCARD]/publish/sloppy_imports/mod.ts:1:20
-Warning Sloppy module resolution (hint: specify path to index.ts file in directory instead)
- at file:///[WILDCARD]/publish/sloppy_imports/mod.ts:1:20
Check file:///[WILDCARD]/publish/sloppy_imports/mod.ts
Checking for slow types in the public API...
Check file:///[WILDCARD]/publish/sloppy_imports/mod.ts