mirror of
https://github.com/denoland/deno.git
synced 2025-03-10 06:07:03 -04:00
fix(npm): handle directory resolution when resolving declaration files (#16706)
Also fixes resolving specifiers like `./something.generated` in declaration files. Closes #16695
This commit is contained in:
parent
a20fd23949
commit
f0c9e276c8
7 changed files with 88 additions and 12 deletions
|
@ -4,3 +4,7 @@ export class Class1 extends Class2 {
|
||||||
|
|
||||||
export class Class2 extends Class1 {
|
export class Class2 extends Class1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// these should be fine though
|
||||||
|
export { subDir } from "./sub_dir";
|
||||||
|
export { otherDir } from "./other_dir";
|
||||||
|
|
1
cli/tests/testdata/npm/registry/@denotest/check-error/1.0.0/other_dir.d.ts
vendored
Normal file
1
cli/tests/testdata/npm/registry/@denotest/check-error/1.0.0/other_dir.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const otherDir: 2;
|
1
cli/tests/testdata/npm/registry/@denotest/check-error/1.0.0/other_dir/index.js
vendored
Normal file
1
cli/tests/testdata/npm/registry/@denotest/check-error/1.0.0/other_dir/index.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
module.exports.otherDir = 2;
|
1
cli/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/index.d.ts
vendored
Normal file
1
cli/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/index.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from './lib';
|
1
cli/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/index.js
vendored
Normal file
1
cli/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/index.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
module.exports.subDir = 1;
|
1
cli/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/lib.d.ts
vendored
Normal file
1
cli/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/lib.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const subDir: 1;
|
|
@ -32,6 +32,25 @@ pub fn path_to_declaration_path(
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
referrer_kind: NodeModuleKind,
|
referrer_kind: NodeModuleKind,
|
||||||
) -> PathBuf {
|
) -> PathBuf {
|
||||||
|
fn probe_extensions(
|
||||||
|
path: &Path,
|
||||||
|
referrer_kind: NodeModuleKind,
|
||||||
|
) -> Option<PathBuf> {
|
||||||
|
let specific_dts_path = match referrer_kind {
|
||||||
|
NodeModuleKind::Cjs => with_known_extension(path, "d.cts"),
|
||||||
|
NodeModuleKind::Esm => with_known_extension(path, "d.mts"),
|
||||||
|
};
|
||||||
|
if specific_dts_path.exists() {
|
||||||
|
return Some(specific_dts_path);
|
||||||
|
}
|
||||||
|
let dts_path = with_known_extension(path, "d.ts");
|
||||||
|
if dts_path.exists() {
|
||||||
|
Some(dts_path)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let lowercase_path = path.to_string_lossy().to_lowercase();
|
let lowercase_path = path.to_string_lossy().to_lowercase();
|
||||||
if lowercase_path.ends_with(".d.ts")
|
if lowercase_path.ends_with(".d.ts")
|
||||||
|| lowercase_path.ends_with(".d.cts")
|
|| lowercase_path.ends_with(".d.cts")
|
||||||
|
@ -39,20 +58,54 @@ pub fn path_to_declaration_path(
|
||||||
{
|
{
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
let specific_dts_path = match referrer_kind {
|
if let Some(path) = probe_extensions(&path, referrer_kind) {
|
||||||
NodeModuleKind::Cjs => path.with_extension("d.cts"),
|
return path;
|
||||||
NodeModuleKind::Esm => path.with_extension("d.mts"),
|
}
|
||||||
};
|
if path.is_dir() {
|
||||||
if specific_dts_path.exists() {
|
if let Some(path) = probe_extensions(&path.join("index"), referrer_kind) {
|
||||||
specific_dts_path
|
return path;
|
||||||
} else {
|
|
||||||
let dts_path = path.with_extension("d.ts");
|
|
||||||
if dts_path.exists() {
|
|
||||||
dts_path
|
|
||||||
} else {
|
|
||||||
path
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
path
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Alternate `PathBuf::with_extension` that will handle known extensions
|
||||||
|
/// more intelligently.
|
||||||
|
pub fn with_known_extension(path: &Path, ext: &str) -> PathBuf {
|
||||||
|
const NON_DECL_EXTS: &[&str] = &["cjs", "js", "json", "jsx", "mjs", "tsx"];
|
||||||
|
const DECL_EXTS: &[&str] = &["cts", "mts", "ts"];
|
||||||
|
|
||||||
|
let file_name = match path.file_name() {
|
||||||
|
Some(value) => value.to_string_lossy(),
|
||||||
|
None => return path.to_path_buf(),
|
||||||
|
};
|
||||||
|
let lowercase_file_name = file_name.to_lowercase();
|
||||||
|
let period_index = lowercase_file_name.rfind('.').and_then(|period_index| {
|
||||||
|
let ext = &lowercase_file_name[period_index + 1..];
|
||||||
|
if DECL_EXTS.contains(&ext) {
|
||||||
|
if let Some(next_period_index) =
|
||||||
|
lowercase_file_name[..period_index].rfind('.')
|
||||||
|
{
|
||||||
|
if &lowercase_file_name[next_period_index + 1..period_index] == "d" {
|
||||||
|
Some(next_period_index)
|
||||||
|
} else {
|
||||||
|
Some(period_index)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Some(period_index)
|
||||||
|
}
|
||||||
|
} else if NON_DECL_EXTS.contains(&ext) {
|
||||||
|
Some(period_index)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let file_name = match period_index {
|
||||||
|
Some(period_index) => &file_name[..period_index],
|
||||||
|
None => &file_name,
|
||||||
|
};
|
||||||
|
path.with_file_name(format!("{}.{}", file_name, ext))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_specifier_display_string(url: &ModuleSpecifier) -> String {
|
fn to_specifier_display_string(url: &ModuleSpecifier) -> String {
|
||||||
|
@ -854,4 +907,18 @@ mod tests {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_with_known_extension() {
|
||||||
|
let cases = &[
|
||||||
|
("test", "d.ts", "test.d.ts"),
|
||||||
|
("test.d.ts", "ts", "test.ts"),
|
||||||
|
("test.worker", "d.ts", "test.worker.d.ts"),
|
||||||
|
("test.d.mts", "js", "test.js"),
|
||||||
|
];
|
||||||
|
for (path, ext, expected) in cases {
|
||||||
|
let actual = with_known_extension(&PathBuf::from(path), ext);
|
||||||
|
assert_eq!(actual.to_string_lossy(), *expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue