summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/tools/registry/api.rs14
-rw-r--r--cli/tools/registry/diagnostics.rs25
-rw-r--r--tests/integration/publish_tests.rs9
-rw-r--r--tests/testdata/publish/invalid_import_esm_sh_suggestion.out20
-rw-r--r--tests/testdata/publish/invalid_import_esm_sh_suggestion/deno.json10
-rw-r--r--tests/testdata/publish/invalid_import_esm_sh_suggestion/mod.ts5
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";
+}