Repository: denoland/deno
File: libs/resolver/graph.rs (Rust)

Code before:
          }) = other_error.as_any().downcast_ref::<SpecifierError>()
          {
            maybe_specifier = Some(specifier);
          }
        }
        ResolveError::ImportMap(import_map_err) => {
          if let ImportMapErrorKind::UnmappedBareSpecifier(
            specifier,
            _referrer,
          ) = import_map_err.as_kind()
          {
            maybe_specifier = Some(specifier);
          }
        }
      }
    }
  }

  // NOTE(bartlomieju): For now, return None if a specifier contains a dot or a space. This is because
  // suggesting to `deno add bad-module.ts` makes no sense and is worse than not providing
  // a suggestion at all. This should be improved further in the future
  if let Some(specifier) = maybe_specifier {
    if specifier.contains('.') || specifier.contains(' ') {
      return None;
    }
  }

  maybe_specifier.map(|s| s.as_str())
}

fn format_range_with_colors(referrer: &deno_graph::Range) -> String {
  use deno_terminal::colors;
  format!(
    "{}:{}:{}",
    colors::cyan(referrer.specifier.as_str()),
    colors::yellow(&(referrer.range.start.line + 1).to_string()),
    colors::yellow(&(referrer.range.start.character + 1).to_string())
  )
}

pub fn format_deno_graph_error(err: &dyn std::error::Error) -> String {
  use std::fmt::Write;

  let mut message = format!("{}", err);
  let mut maybe_source = err.source();

  if maybe_source.is_some() {
    let mut past_message = message.clone();
    let mut count = 0;
    let mut display_count = 0;
    while let Some(source) = maybe_source {

Review comment (suggestion):
We weren't displaying the `hint: If you want to use a JSR or npm package, try running deno add ...` hint when there was an import map.

Code after:
    if range.specifier.scheme() == "file" {
      match error.as_ref() {
        ResolveError::Specifier(specifier_error) => {
          if let SpecifierError::ImportPrefixMissing { specifier, .. } =
            specifier_error
          {
            maybe_specifier = Some(specifier);
          }
        }
        ResolveError::Other(other_error) => {
          if let Some(SpecifierError::ImportPrefixMissing {
            specifier, ..
          }) = other_error.as_any().downcast_ref::<SpecifierError>()
          {
            maybe_specifier = Some(specifier);
          }
        }
        ResolveError::ImportMap(import_map_err) => {
          if let ImportMapErrorKind::UnmappedBareSpecifier(
            specifier,
            _referrer,
          ) = import_map_err.as_kind()
          {
            maybe_specifier = Some(specifier);
          }
        }
      }
    }
  }

  if let Some(specifier) = maybe_specifier {
    // NOTE(bartlomieju): For now, return None if a specifier contains a dot or a space. This is because
    // suggesting to `deno add bad-module.ts` makes no sense and is worse than not providing
    // a suggestion at all. This should be improved further in the future
    if specifier.contains('.') || specifier.contains(' ') {
      return None;
    }
    // Do not return a hint for specifiers starting with `@`, but not containing a `/`
    if specifier.starts_with('@') && !specifier.contains('/') {
      return None;
    }
  }

  maybe_specifier.map(|s| s.as_str())
}

fn format_range_with_colors(referrer: &deno_graph::Range) -> String {
  use deno_terminal::colors;
  format!(
    "{}:{}:{}",
    colors::cyan(referrer.specifier.as_str()),