diff --git a/cli/tests/integration/npm_tests.rs b/cli/tests/integration/npm_tests.rs index e14da4acaa..a16dd5354e 100644 --- a/cli/tests/integration/npm_tests.rs +++ b/cli/tests/integration/npm_tests.rs @@ -2088,3 +2088,11 @@ itest!(reserved_word_exports { envs: env_vars_for_npm_tests(), http_server: true, }); + +itest!(check_package_file_dts_dmts_dcts { + args: "check npm/file_dts_dmts_dcts/main.ts", + output: "npm/file_dts_dmts_dcts/main.out", + envs: env_vars_for_npm_tests_no_sync_download(), + http_server: true, + exit_code: 1, +}); diff --git a/cli/tests/testdata/npm/file_dts_dmts_dcts/main.out b/cli/tests/testdata/npm/file_dts_dmts_dcts/main.out new file mode 100644 index 0000000000..c92043f8b5 --- /dev/null +++ b/cli/tests/testdata/npm/file_dts_dmts_dcts/main.out @@ -0,0 +1,24 @@ +Download http://localhost:4545/npm/registry/@denotest/file-dts-dmts-dcts +Download http://localhost:4545/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0.tgz +Check file:///[WILDCARD]/main.ts +error: TS2322 [ERROR]: Type '5' is not assignable to type '"dts"'. +const value1: Dts1 = 5; + ~~~~~~ + at file:///[WILDCARD] + +TS2322 [ERROR]: Type '5' is not assignable to type '"mts"'. +const value2: Mts1 = 5; + ~~~~~~ + at file:///[WILDCARD] + +TS2322 [ERROR]: Type '5' is not assignable to type '"mts"'. +const value3: Mts2 = 5; + ~~~~~~ + at file:///[WILDCARD] + +TS2322 [ERROR]: Type '5' is not assignable to type '"cts"'. +const value4: Cts1 = 5; + ~~~~~~ + at file:///[WILDCARD] + +Found 4 errors. diff --git a/cli/tests/testdata/npm/file_dts_dmts_dcts/main.ts b/cli/tests/testdata/npm/file_dts_dmts_dcts/main.ts new file mode 100644 index 0000000000..63686e2d32 --- /dev/null +++ b/cli/tests/testdata/npm/file_dts_dmts_dcts/main.ts @@ -0,0 +1,9 @@ +import { Value as Dts1 } from "npm:@denotest/file-dts-dmts-dcts/js"; +import { Value as Mts1 } from "npm:@denotest/file-dts-dmts-dcts"; +import { Value as Mts2 } from "npm:@denotest/file-dts-dmts-dcts/mjs"; +import { Value as Cts1 } from "npm:@denotest/file-dts-dmts-dcts/cjs"; + +const value1: Dts1 = 5; +const value2: Mts1 = 5; +const value3: Mts2 = 5; +const value4: Cts1 = 5; diff --git a/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.cjs b/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.cjs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.cts b/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.cts new file mode 100644 index 0000000000..43a5ebe9b1 --- /dev/null +++ b/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.cts @@ -0,0 +1 @@ +export type Value = "cts"; diff --git a/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.mts b/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.mts new file mode 100644 index 0000000000..b762ebd4af --- /dev/null +++ b/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.mts @@ -0,0 +1 @@ +export type Value = "mts"; diff --git a/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.ts b/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.ts new file mode 100644 index 0000000000..1d1cd270b7 --- /dev/null +++ b/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.ts @@ -0,0 +1 @@ +export type Value = "dts"; diff --git a/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.js b/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.mjs b/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.mjs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/package.json b/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/package.json new file mode 100644 index 0000000000..1884b65e4b --- /dev/null +++ b/cli/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/package.json @@ -0,0 +1,13 @@ +{ + "name": "@denotest/dts-and-dmts-same-file", + "version": "1.0.0", + "exports": { + ".": { + "import": "./main.mjs", + "require": "./main.js" + }, + "./mjs": "./main.mjs", + "./cjs": "./main.cjs", + "./js": "./main.js" + } +} \ No newline at end of file diff --git a/ext/node/resolution.rs b/ext/node/resolution.rs index ce02f31f27..bb25124bf1 100644 --- a/ext/node/resolution.rs +++ b/ext/node/resolution.rs @@ -527,37 +527,67 @@ impl NodeResolver { fn probe_extensions( fs: &dyn deno_fs::FileSystem, path: &Path, + lowercase_path: &str, referrer_kind: NodeModuleKind, ) -> Option { - let specific_dts_path = match referrer_kind { - NodeModuleKind::Cjs => with_known_extension(path, "d.cts"), - NodeModuleKind::Esm => with_known_extension(path, "d.mts"), - }; - if fs.exists(&specific_dts_path) { - return Some(specific_dts_path); + let mut searched_for_d_mts = false; + let mut searched_for_d_cts = false; + if lowercase_path.ends_with(".mjs") { + let d_mts_path = with_known_extension(path, "d.mts"); + if fs.exists(&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 fs.exists(&d_cts_path) { + return Some(d_cts_path); + } + searched_for_d_cts = true; } + let dts_path = with_known_extension(path, "d.ts"); if fs.exists(&dts_path) { - Some(dts_path) - } else { - None + return Some(dts_path); } + + let specific_dts_path = match referrer_kind { + NodeModuleKind::Cjs if !searched_for_d_cts => { + Some(with_known_extension(path, "d.cts")) + } + NodeModuleKind::Esm if !searched_for_d_mts => { + Some(with_known_extension(path, "d.mts")) + } + _ => None, // already searched above + }; + if let Some(specific_dts_path) = specific_dts_path { + if fs.exists(&specific_dts_path) { + return Some(specific_dts_path); + } + } + None } let lowercase_path = path.to_string_lossy().to_lowercase(); if lowercase_path.ends_with(".d.ts") || lowercase_path.ends_with(".d.cts") - || lowercase_path.ends_with(".d.ts") + || lowercase_path.ends_with(".d.mts") { return Some(path); } - if let Some(path) = probe_extensions(&*self.fs, &path, referrer_kind) { + if let Some(path) = + probe_extensions(&*self.fs, &path, &lowercase_path, referrer_kind) + { return Some(path); } if self.fs.is_dir(&path) { - if let Some(path) = - probe_extensions(&*self.fs, &path.join("index"), referrer_kind) - { + let index_path = path.join("index.js"); + if let Some(path) = probe_extensions( + &*self.fs, + &index_path, + &index_path.to_string_lossy().to_lowercase(), + referrer_kind, + ) { return Some(path); } }