diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2023-01-27 17:36:23 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-27 22:36:23 +0000 |
commit | 2b247be517d789a37e532849e2e40b724af0918f (patch) | |
tree | 1f689a0b872a5b05a4ce812f9f120df7134ba69d /cli/graph_util.rs | |
parent | f5840bdcd360ec0bac2501f333e58e25742b1537 (diff) |
fix: ensure "fs" -> "node:fs" error/quick fix works when user has import map (#17566)
Closes #17563
Diffstat (limited to 'cli/graph_util.rs')
-rw-r--r-- | cli/graph_util.rs | 87 |
1 files changed, 82 insertions, 5 deletions
diff --git a/cli/graph_util.rs b/cli/graph_util.rs index c216ba503..3c5545a50 100644 --- a/cli/graph_util.rs +++ b/cli/graph_util.rs @@ -31,6 +31,7 @@ use deno_graph::ResolutionError; use deno_graph::Resolved; use deno_graph::SpecifierError; use deno_runtime::permissions::PermissionsContainer; +use import_map::ImportMapError; use std::collections::BTreeMap; use std::collections::HashMap; use std::collections::HashSet; @@ -646,17 +647,93 @@ fn handle_check_error( pub fn enhanced_resolution_error_message(error: &ResolutionError) -> String { let mut message = format!("{error}"); + if let Some(specifier) = get_resolution_error_bare_node_specifier(error) { + message.push_str(&format!( + "\nIf you want to use a built-in Node module, add a \"node:\" prefix (ex. \"node:{specifier}\")." + )); + } + + message +} + +pub fn get_resolution_error_bare_node_specifier( + error: &ResolutionError, +) -> Option<&str> { + get_resolution_error_bare_specifier(error).filter(|specifier| { + crate::node::resolve_builtin_node_module(specifier).is_ok() + }) +} + +fn get_resolution_error_bare_specifier( + error: &ResolutionError, +) -> Option<&str> { if let ResolutionError::InvalidSpecifier { error: SpecifierError::ImportPrefixMissing(specifier, _), .. } = error { - if crate::node::resolve_builtin_node_module(specifier).is_ok() { - message.push_str(&format!( - "\nIf you want to use a built-in Node module, add a \"node:\" prefix (ex. \"node:{specifier}\")." - )); + Some(specifier.as_str()) + } else if let ResolutionError::ResolverError { error, .. } = error { + if let Some(ImportMapError::UnmappedBareSpecifier(specifier, _)) = + error.downcast_ref::<ImportMapError>() + { + Some(specifier.as_str()) + } else { + None } + } else { + None } +} - message +#[cfg(test)] +mod test { + use std::sync::Arc; + + use deno_ast::ModuleSpecifier; + use deno_graph::Position; + use deno_graph::Range; + use deno_graph::ResolutionError; + use deno_graph::SpecifierError; + + use crate::graph_util::get_resolution_error_bare_node_specifier; + + #[test] + fn import_map_node_resolution_error() { + let cases = vec![("fs", Some("fs")), ("other", None)]; + for (input, output) in cases { + let import_map = import_map::ImportMap::new( + ModuleSpecifier::parse("file:///deno.json").unwrap(), + ); + let specifier = ModuleSpecifier::parse("file:///file.ts").unwrap(); + let err = import_map.resolve(input, &specifier).err().unwrap(); + let err = ResolutionError::ResolverError { + error: Arc::new(err.into()), + specifier: input.to_string(), + range: Range { + specifier, + start: Position::zeroed(), + end: Position::zeroed(), + }, + }; + assert_eq!(get_resolution_error_bare_node_specifier(&err), output); + } + } + + #[test] + fn bare_specifier_node_resolution_error() { + let cases = vec![("process", Some("process")), ("other", None)]; + for (input, output) in cases { + let specifier = ModuleSpecifier::parse("file:///file.ts").unwrap(); + let err = ResolutionError::InvalidSpecifier { + range: Range { + specifier, + start: Position::zeroed(), + end: Position::zeroed(), + }, + error: SpecifierError::ImportPrefixMissing(input.to_string(), None), + }; + assert_eq!(get_resolution_error_bare_node_specifier(&err), output,); + } + } } |