diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2024-03-04 09:55:28 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-04 09:55:28 +0530 |
commit | 11db68ce96dfe561da6d7f4938e412635dc688d7 (patch) | |
tree | bc2d380d238be3af73de8f86218025a850c725b8 | |
parent | 942b2aaca57880152877a34006b30d2e982dec00 (diff) |
feat(publish): add `npm:` suggestion for esm.sh specifiers (#22343)

Co-authored-by: David Sherret <dsherret@users.noreply.github.com>
-rw-r--r-- | cli/tools/registry/api.rs | 14 | ||||
-rw-r--r-- | cli/tools/registry/diagnostics.rs | 25 | ||||
-rw-r--r-- | tests/integration/publish_tests.rs | 9 | ||||
-rw-r--r-- | tests/testdata/publish/invalid_import_esm_sh_suggestion.out | 20 | ||||
-rw-r--r-- | tests/testdata/publish/invalid_import_esm_sh_suggestion/deno.json | 10 | ||||
-rw-r--r-- | tests/testdata/publish/invalid_import_esm_sh_suggestion/mod.ts | 5 |
6 files changed, 82 insertions, 1 deletions
diff --git a/cli/tools/registry/api.rs b/cli/tools/registry/api.rs index b8eb6c18e..de9b4a333 100644 --- a/cli/tools/registry/api.rs +++ b/cli/tools/registry/api.rs @@ -3,6 +3,7 @@ use deno_core::error::AnyError; use deno_core::serde_json; use deno_runtime::deno_fetch::reqwest; +use lsp_types::Url; use serde::de::DeserializeOwned; #[derive(serde::Deserialize)] @@ -142,3 +143,16 @@ pub async fn get_package( let response = client.get(&package_url).send().await?; Ok(response) } + +pub fn get_jsr_alternative(imported: &Url) -> Option<String> { + if !matches!(imported.host_str(), Some("esm.sh")) { + return None; + } + + let mut segments = imported.path_segments().unwrap(); + match segments.next() { + Some("gh") => None, + Some(module) => Some(format!("\"npm:{module}\"")), + None => None, + } +} diff --git a/cli/tools/registry/diagnostics.rs b/cli/tools/registry/diagnostics.rs index ff86e68fb..9e88e81de 100644 --- a/cli/tools/registry/diagnostics.rs +++ b/cli/tools/registry/diagnostics.rs @@ -287,7 +287,30 @@ impl Diagnostic for PublishDiagnostic { } fn snippet_fixed(&self) -> Option<DiagnosticSnippet<'_>> { - None + match &self { + PublishDiagnostic::InvalidExternalImport { imported, .. } => { + match super::api::get_jsr_alternative(imported) { + Some(replacement) => { + let replacement = SourceTextInfo::new(replacement.into()); + let start = replacement.line_start(0); + let end = replacement.line_end(0); + Some(DiagnosticSnippet { + source: Cow::Owned(replacement), + highlight: DiagnosticSnippetHighlight { + style: DiagnosticSnippetHighlightStyle::Hint, + range: DiagnosticSourceRange { + start: DiagnosticSourcePos::SourcePos(start), + end: DiagnosticSourcePos::SourcePos(end), + }, + description: Some("try this specifier".into()), + }, + }) + } + None => None, + } + } + _ => None, + } } fn info(&self) -> Cow<'_, [Cow<'_, str>]> { diff --git a/tests/integration/publish_tests.rs b/tests/integration/publish_tests.rs index befd3826e..ec5345553 100644 --- a/tests/integration/publish_tests.rs +++ b/tests/integration/publish_tests.rs @@ -63,6 +63,15 @@ itest!(invalid_import { http_server: true, }); +itest!(invalid_import_esm_sh_suggestion { + args: "publish --token 'sadfasdf' --dry-run", + output: "publish/invalid_import_esm_sh_suggestion.out", + cwd: Some("publish/invalid_import_esm_sh_suggestion"), + envs: env_vars_for_npm_tests(), + exit_code: 1, + http_server: true, +}); + #[test] fn publish_non_exported_files_using_import_map() { let context = publish_context_builder().build(); diff --git a/tests/testdata/publish/invalid_import_esm_sh_suggestion.out b/tests/testdata/publish/invalid_import_esm_sh_suggestion.out new file mode 100644 index 000000000..a014f3de6 --- /dev/null +++ b/tests/testdata/publish/invalid_import_esm_sh_suggestion.out @@ -0,0 +1,20 @@ +[WILDCARD] +Check file:///[WILDCARD]/mod.ts +Checking for slow types in the public API... +Check file:///[WILDCARD]mod.ts +error[invalid-external-import]: invalid import to a non-JSR 'http' specifier + --> [WILDCARD]mod.ts:1:8 + | +1 | import "http://esm.sh/react-dom@18.2.0/server"; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the specifier + = hint: replace this import with one from jsr or npm, or vendor the dependency into your package + | +1 | "npm:react-dom@18.2.0" + | ---------------------- try this specifier + + info: the import was resolved to 'http://esm.sh/react-dom@18.2.0/server' + info: this specifier is not allowed to be imported on jsr + info: jsr only supports importing `jsr:`, `npm:`, and `data:` specifiers + docs: https://jsr.io/go/invalid-external-import + +error: Found 1 problem diff --git a/tests/testdata/publish/invalid_import_esm_sh_suggestion/deno.json b/tests/testdata/publish/invalid_import_esm_sh_suggestion/deno.json new file mode 100644 index 000000000..49b666d22 --- /dev/null +++ b/tests/testdata/publish/invalid_import_esm_sh_suggestion/deno.json @@ -0,0 +1,10 @@ +{ + "name": "@foo/bar", + "version": "1.0.0", + "imports": { + "$echo": "http://localhost:4545/echo.ts" + }, + "exports": { + ".": "./mod.ts" + } +} diff --git a/tests/testdata/publish/invalid_import_esm_sh_suggestion/mod.ts b/tests/testdata/publish/invalid_import_esm_sh_suggestion/mod.ts new file mode 100644 index 000000000..e597218ed --- /dev/null +++ b/tests/testdata/publish/invalid_import_esm_sh_suggestion/mod.ts @@ -0,0 +1,5 @@ +import "http://esm.sh/react-dom@18.2.0/server"; + +export function foobar(): string { + return "string"; +} |