feat(publish): add npm: suggestion for esm.sh specifiers (#22343)

![image](https://github.com/denoland/deno/assets/34997667/f32642ed-c109-4519-84c5-6f78e9452703)

Co-authored-by: David Sherret <dsherret@users.noreply.github.com>
This commit is contained in:
Divy Srivastava 2024-03-04 09:55:28 +05:30 committed by GitHub
parent 942b2aaca5
commit 11db68ce96
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 82 additions and 1 deletions

View file

@ -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,
}
}

View file

@ -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>]> {

View file

@ -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();

View file

@ -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

View file

@ -0,0 +1,10 @@
{
"name": "@foo/bar",
"version": "1.0.0",
"imports": {
"$echo": "http://localhost:4545/echo.ts"
},
"exports": {
".": "./mod.ts"
}
}

View file

@ -0,0 +1,5 @@
import "http://esm.sh/react-dom@18.2.0/server";
export function foobar(): string {
return "string";
}