summaryrefslogtreecommitdiff
path: root/cli/import_map.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/import_map.rs')
-rw-r--r--cli/import_map.rs63
1 files changed, 34 insertions, 29 deletions
diff --git a/cli/import_map.rs b/cli/import_map.rs
index d18633545..f2126bed9 100644
--- a/cli/import_map.rs
+++ b/cli/import_map.rs
@@ -14,11 +14,25 @@ use std::error::Error;
use std::fmt;
#[derive(Debug)]
-pub struct ImportMapError(String);
+pub enum ImportMapError {
+ UnmappedBareSpecifier(String, Option<String>),
+ Other(String),
+}
impl fmt::Display for ImportMapError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.pad(&self.0)
+ match self {
+ ImportMapError::UnmappedBareSpecifier(specifier, maybe_referrer) => write!(
+ f,
+ "Relative import path \"{}\" not prefixed with / or ./ or ../ and not in import map{}",
+ specifier,
+ match maybe_referrer {
+ Some(referrer) => format!(" from \"{}\"", referrer),
+ None => format!(""),
+ }
+ ),
+ ImportMapError::Other(message) => f.pad(message),
+ }
}
}
@@ -51,7 +65,7 @@ impl ImportMap {
let v: Value = match serde_json::from_str(json_string) {
Ok(v) => v,
Err(_) => {
- return Err(ImportMapError(
+ return Err(ImportMapError::Other(
"Unable to parse import map JSON".to_string(),
));
}
@@ -60,7 +74,7 @@ impl ImportMap {
match v {
Value::Object(_) => {}
_ => {
- return Err(ImportMapError(
+ return Err(ImportMapError::Other(
"Import map JSON must be an object".to_string(),
));
}
@@ -70,7 +84,7 @@ impl ImportMap {
let normalized_imports = match &v.get("imports") {
Some(imports_map) => {
if !imports_map.is_object() {
- return Err(ImportMapError(
+ return Err(ImportMapError::Other(
"Import map's 'imports' must be an object".to_string(),
));
}
@@ -84,7 +98,7 @@ impl ImportMap {
let normalized_scopes = match &v.get("scopes") {
Some(scope_map) => {
if !scope_map.is_object() {
- return Err(ImportMapError(
+ return Err(ImportMapError::Other(
"Import map's 'scopes' must be an object".to_string(),
));
}
@@ -252,7 +266,7 @@ impl ImportMap {
// Order is preserved because of "preserve_order" feature of "serde_json".
for (scope_prefix, potential_specifier_map) in scope_map.iter() {
if !potential_specifier_map.is_object() {
- return Err(ImportMapError(format!(
+ return Err(ImportMapError::Other(format!(
"The value for the {:?} scope prefix must be an object",
scope_prefix
)));
@@ -341,7 +355,7 @@ impl ImportMap {
if let Some(address) = maybe_address {
return Ok(Some(address.clone()));
} else {
- return Err(ImportMapError(format!(
+ return Err(ImportMapError::Other(format!(
"Blocked by null entry for \"{:?}\"",
normalized_specifier
)));
@@ -367,7 +381,7 @@ impl ImportMap {
}
if maybe_address.is_none() {
- return Err(ImportMapError(format!(
+ return Err(ImportMapError::Other(format!(
"Blocked by null entry for \"{:?}\"",
specifier_key
)));
@@ -383,7 +397,7 @@ impl ImportMap {
let url = match resolution_result.join(after_prefix) {
Ok(url) => url,
Err(_) => {
- return Err(ImportMapError(format!(
+ return Err(ImportMapError::Other(format!(
"Failed to resolve the specifier \"{:?}\" as its after-prefix
portion \"{:?}\" could not be URL-parsed relative to the URL prefix
\"{:?}\" mapped to by the prefix \"{:?}\"",
@@ -396,7 +410,7 @@ impl ImportMap {
};
if !url.as_str().starts_with(resolution_result.as_str()) {
- return Err(ImportMapError(format!(
+ return Err(ImportMapError::Other(format!(
"The specifier \"{:?}\" backtracks above its prefix \"{:?}\"",
normalized_specifier, specifier_key
)));
@@ -417,7 +431,7 @@ impl ImportMap {
&self,
specifier: &str,
referrer: &str,
- ) -> Result<Option<Url>, ImportMapError> {
+ ) -> Result<Url, ImportMapError> {
let as_url: Option<Url> =
ImportMap::try_url_like_specifier(specifier, referrer);
let normalized_specifier = if let Some(url) = as_url.as_ref() {
@@ -434,7 +448,7 @@ impl ImportMap {
)?;
// match found in scopes map
- if scopes_match.is_some() {
+ if let Some(scopes_match) = scopes_match {
return Ok(scopes_match);
}
@@ -445,19 +459,19 @@ impl ImportMap {
)?;
// match found in import map
- if imports_match.is_some() {
+ if let Some(imports_match) = imports_match {
return Ok(imports_match);
}
// The specifier was able to be turned into a URL, but wasn't remapped into anything.
- if as_url.is_some() {
+ if let Some(as_url) = as_url {
return Ok(as_url);
}
- Err(ImportMapError(format!(
- "Unmapped bare specifier {:?}",
- specifier
- )))
+ Err(ImportMapError::UnmappedBareSpecifier(
+ specifier.to_string(),
+ Some(referrer.to_string()),
+ ))
}
}
@@ -465,7 +479,6 @@ impl ImportMap {
mod tests {
use super::*;
- use deno_core::resolve_import;
use std::path::Path;
use std::path::PathBuf;
use walkdir::WalkDir;
@@ -652,15 +665,7 @@ mod tests {
let maybe_resolved = import_map
.resolve(&given_specifier, &base_url)
.ok()
- .map(|maybe_resolved| {
- if let Some(specifier) = maybe_resolved {
- specifier.to_string()
- } else {
- resolve_import(&given_specifier, &base_url)
- .unwrap()
- .to_string()
- }
- });
+ .map(|url| url.to_string());
assert_eq!(expected_specifier, &maybe_resolved, "{}", test.name);
}
TestKind::Parse {