diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2024-08-16 10:42:11 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-16 10:42:11 -0400 |
commit | 4d1b263e91dc7b85e9c8cd1cb42270ddc0468396 (patch) | |
tree | 1bc685cd725652bcdaa0e35d88bf145f7a5d858a | |
parent | 57cd2951f193b02cbd3fb15f0ee14d83107a2855 (diff) |
feat(publish): suggest importing `jsr:@std/` for `deno.land/std` urls (#25046)
-rw-r--r-- | cli/tools/registry/api.rs | 62 | ||||
-rw-r--r-- | tests/specs/publish/prefer_fast_check_graph/main.out | 4 |
2 files changed, 59 insertions, 7 deletions
diff --git a/cli/tools/registry/api.rs b/cli/tools/registry/api.rs index 519800660..c382aa9ac 100644 --- a/cli/tools/registry/api.rs +++ b/cli/tools/registry/api.rs @@ -149,14 +149,62 @@ pub async fn get_package( } pub fn get_jsr_alternative(imported: &Url) -> Option<String> { - if !matches!(imported.host_str(), Some("esm.sh")) { - return None; + if matches!(imported.host_str(), Some("esm.sh")) { + let mut segments = imported.path_segments()?; + match segments.next()? { + "gh" => None, + module => Some(format!("\"npm:{module}\"")), + } + } else if imported.as_str().starts_with("https://deno.land/") { + let mut segments = imported.path_segments()?; + let maybe_std = segments.next()?; + if maybe_std != "std" && !maybe_std.starts_with("std@") { + return None; + } + let module = segments.next()?; + let export = segments + .next() + .filter(|s| *s != "mod.ts") + .map(|s| s.strip_suffix(".ts").unwrap_or(s).replace("_", "-")); + Some(format!( + "\"jsr:@std/{}@1{}\"", + module, + export.map(|s| format!("/{}", s)).unwrap_or_default() + )) + } else { + None } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_jsr_alternative() { + #[track_caller] + fn run_test(imported: &str, output: Option<&str>) { + let imported = Url::parse(imported).unwrap(); + let output = output.map(|s| s.to_string()); + assert_eq!(get_jsr_alternative(&imported), output); + } - let mut segments = imported.path_segments().unwrap(); - match segments.next() { - Some("gh") => None, - Some(module) => Some(format!("\"npm:{module}\"")), - None => None, + run_test("https://esm.sh/ts-morph", Some("\"npm:ts-morph\"")); + run_test( + "https://deno.land/std/path/mod.ts", + Some("\"jsr:@std/path@1\""), + ); + run_test( + "https://deno.land/std/path/join.ts", + Some("\"jsr:@std/path@1/join\""), + ); + run_test( + "https://deno.land/std@0.229.0/path/join.ts", + Some("\"jsr:@std/path@1/join\""), + ); + run_test( + "https://deno.land/std@0.229.0/path/something_underscore.ts", + Some("\"jsr:@std/path@1/something-underscore\""), + ); } } diff --git a/tests/specs/publish/prefer_fast_check_graph/main.out b/tests/specs/publish/prefer_fast_check_graph/main.out index 6c68dde8a..64296206f 100644 --- a/tests/specs/publish/prefer_fast_check_graph/main.out +++ b/tests/specs/publish/prefer_fast_check_graph/main.out @@ -9,6 +9,10 @@ error[invalid-external-import]: invalid import to a non-JSR 'https' specifier | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the specifier | = hint: replace this import with one from jsr or npm, or vendor the dependency into your package + | +1 | "jsr:@std/assert@1/assert" + | -------------------------- try this specifier + | info: the import was resolved to 'https://deno.land/std/assert/assert.ts' info: this specifier is not allowed to be imported on jsr |