diff options
Diffstat (limited to 'cli/util/path.rs')
-rw-r--r-- | cli/util/path.rs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/cli/util/path.rs b/cli/util/path.rs index 69c52bf6e..39ba96d6d 100644 --- a/cli/util/path.rs +++ b/cli/util/path.rs @@ -4,6 +4,7 @@ use std::borrow::Cow; use std::path::Path; use std::path::PathBuf; +use deno_ast::MediaType; use deno_ast::ModuleSpecifier; use deno_core::error::uri_error; use deno_core::error::AnyError; @@ -28,6 +29,44 @@ pub fn get_extension(file_path: &Path) -> Option<String> { .map(|e| e.to_lowercase()); } +/// TypeScript figures out the type of file based on the extension, but we take +/// other factors into account like the file headers. The hack here is to map the +/// specifier passed to TypeScript to a new specifier with the file extension. +pub fn mapped_specifier_for_tsc( + specifier: &ModuleSpecifier, + media_type: MediaType, +) -> Option<String> { + let ext_media_type = MediaType::from_specifier(specifier); + if media_type != ext_media_type { + // we can't just add on the extension because typescript considers + // all .d.*.ts files as declaration files in TS 5.0+ + if media_type != MediaType::Dts + && media_type == MediaType::TypeScript + && specifier + .path() + .split('/') + .last() + .map(|last| last.contains(".d.")) + .unwrap_or(false) + { + let mut path_parts = specifier + .path() + .split('/') + .map(ToOwned::to_owned) + .collect::<Vec<_>>(); + let last_part = path_parts.last_mut().unwrap(); + *last_part = last_part.replace(".d.", "$d$"); + let mut specifier = specifier.clone(); + specifier.set_path(&path_parts.join("/")); + Some(format!("{}{}", specifier, media_type.as_ts_extension())) + } else { + Some(format!("{}{}", specifier, media_type.as_ts_extension())) + } + } else { + None + } +} + /// Attempts to convert a specifier to a file path. By default, uses the Url /// crate's `to_file_path()` method, but falls back to try and resolve unix-style /// paths on Windows. |