From 4a0bbd0a719dfbd059f1a7dc8d283aee9ab8283a Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 28 Nov 2024 14:51:24 +0100 Subject: [PATCH] fix: support bun specifiers in JSR publish (#24588) Fixes https://github.com/denoland/deno/issues/26989 --------- Co-authored-by: Nathan Whitaker --- cli/graph_util.rs | 23 +++++++++++++++- cli/tools/registry/diagnostics.rs | 2 +- cli/tools/registry/graph.rs | 2 +- cli/tsc/mod.rs | 26 +++++++++++-------- .../publish/bun_specifier/__test__.jsonc | 4 +++ .../publish/bun_specifier/bun_specifier.out | 6 +++++ tests/specs/publish/bun_specifier/deno.json | 8 ++++++ tests/specs/publish/bun_specifier/mod.ts | 1 + .../publish/invalid_import/invalid_import.out | 4 +-- .../invalid_import_esm_sh_suggestion.out | 2 +- .../publish/prefer_fast_check_graph/main.out | 2 +- 11 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 tests/specs/publish/bun_specifier/__test__.jsonc create mode 100644 tests/specs/publish/bun_specifier/bun_specifier.out create mode 100644 tests/specs/publish/bun_specifier/deno.json create mode 100644 tests/specs/publish/bun_specifier/mod.ts diff --git a/cli/graph_util.rs b/cli/graph_util.rs index 360021d22d62c9..63997dc9ce8510 100644 --- a/cli/graph_util.rs +++ b/cli/graph_util.rs @@ -6,6 +6,7 @@ use crate::args::CliLockfile; use crate::args::CliOptions; use crate::args::DENO_DISABLE_PEDANTIC_NODE_WARNINGS; use crate::cache; +use crate::cache::FetchCacher; use crate::cache::GlobalHttpCache; use crate::cache::ModuleInfoCache; use crate::cache::ParsedSourceCache; @@ -254,6 +255,23 @@ impl ModuleGraphCreator { package_configs: &[JsrPackageConfig], build_fast_check_graph: bool, ) -> Result { + struct PublishLoader(FetchCacher); + impl Loader for PublishLoader { + fn load( + &self, + specifier: &deno_ast::ModuleSpecifier, + options: deno_graph::source::LoadOptions, + ) -> deno_graph::source::LoadFuture { + if specifier.scheme() == "bun" { + return Box::pin(std::future::ready(Ok(Some( + deno_graph::source::LoadResponse::External { + specifier: specifier.clone(), + }, + )))); + } + self.0.load(specifier, options) + } + } fn graph_has_external_remote(graph: &ModuleGraph) -> bool { // Earlier on, we marked external non-JSR modules as external. // If the graph contains any of those, it would cause type checking @@ -271,12 +289,15 @@ impl ModuleGraphCreator { for package_config in package_configs { roots.extend(package_config.config_file.resolve_export_value_urls()?); } + + let loader = self.module_graph_builder.create_graph_loader(); + let mut publish_loader = PublishLoader(loader); let mut graph = self .create_graph_with_options(CreateGraphOptions { is_dynamic: false, graph_kind: deno_graph::GraphKind::All, roots, - loader: None, + loader: Some(&mut publish_loader), }) .await?; self.graph_valid(&graph)?; diff --git a/cli/tools/registry/diagnostics.rs b/cli/tools/registry/diagnostics.rs index f2b630d7822f72..ef38affc30051d 100644 --- a/cli/tools/registry/diagnostics.rs +++ b/cli/tools/registry/diagnostics.rs @@ -476,7 +476,7 @@ impl Diagnostic for PublishDiagnostic { InvalidExternalImport { imported, .. } => Cow::Owned(vec![ Cow::Owned(format!("the import was resolved to '{}'", imported)), Cow::Borrowed("this specifier is not allowed to be imported on jsr"), - Cow::Borrowed("jsr only supports importing `jsr:`, `npm:`, and `data:` specifiers"), + Cow::Borrowed("jsr only supports importing `jsr:`, `npm:`, `data:`, `bun:`, and `node:` specifiers"), ]), UnsupportedJsxTsx { .. } => Cow::Owned(vec![ Cow::Borrowed("follow https://github.com/jsr-io/jsr/issues/24 for updates"), diff --git a/cli/tools/registry/graph.rs b/cli/tools/registry/graph.rs index 184557e5df7797..21962d009e1626 100644 --- a/cli/tools/registry/graph.rs +++ b/cli/tools/registry/graph.rs @@ -47,7 +47,7 @@ impl GraphDiagnosticsCollector { resolution: &ResolutionResolved| { if visited.insert(resolution.specifier.clone()) { match resolution.specifier.scheme() { - "file" | "data" | "node" => {} + "file" | "data" | "node" | "bun" => {} "jsr" => { skip_specifiers.insert(resolution.specifier.clone()); diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index 50127b093d128f..a8e8d73b68b002 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -656,17 +656,21 @@ fn op_load_inner( } Module::Npm(_) | Module::Node(_) => None, Module::External(module) => { - // means it's Deno code importing an npm module - let specifier = node::resolve_specifier_into_node_modules( - &module.specifier, - &deno_fs::RealFs, - ); - Some(Cow::Owned(load_from_node_modules( - &specifier, - state.maybe_npm.as_ref(), - &mut media_type, - &mut is_cjs, - )?)) + if module.specifier.scheme() != "file" { + None + } else { + // means it's Deno code importing an npm module + let specifier = node::resolve_specifier_into_node_modules( + &module.specifier, + &deno_fs::RealFs, + ); + Some(Cow::Owned(load_from_node_modules( + &specifier, + state.maybe_npm.as_ref(), + &mut media_type, + &mut is_cjs, + )?)) + } } } } else if let Some(npm) = state diff --git a/tests/specs/publish/bun_specifier/__test__.jsonc b/tests/specs/publish/bun_specifier/__test__.jsonc new file mode 100644 index 00000000000000..4124845ba939a3 --- /dev/null +++ b/tests/specs/publish/bun_specifier/__test__.jsonc @@ -0,0 +1,4 @@ +{ + "args": "publish --token 'sadfasdf'", + "output": "bun_specifier.out" +} diff --git a/tests/specs/publish/bun_specifier/bun_specifier.out b/tests/specs/publish/bun_specifier/bun_specifier.out new file mode 100644 index 00000000000000..af45ed598b655f --- /dev/null +++ b/tests/specs/publish/bun_specifier/bun_specifier.out @@ -0,0 +1,6 @@ +Check file:///[WILDCARD]/mod.ts +Checking for slow types in the public API... +Check file:///[WILDCARD]/mod.ts +Publishing @foo/bar@1.0.0 ... +Successfully published @foo/bar@1.0.0 +Visit http://127.0.0.1:4250/@foo/bar@1.0.0 for details diff --git a/tests/specs/publish/bun_specifier/deno.json b/tests/specs/publish/bun_specifier/deno.json new file mode 100644 index 00000000000000..0657aefdbbdd99 --- /dev/null +++ b/tests/specs/publish/bun_specifier/deno.json @@ -0,0 +1,8 @@ +{ + "name": "@foo/bar", + "version": "1.0.0", + "exports": { + ".": "./mod.ts" + }, + "license": "MIT" +} diff --git a/tests/specs/publish/bun_specifier/mod.ts b/tests/specs/publish/bun_specifier/mod.ts new file mode 100644 index 00000000000000..ad7ca6152caf4f --- /dev/null +++ b/tests/specs/publish/bun_specifier/mod.ts @@ -0,0 +1 @@ +import "bun:sqlite"; diff --git a/tests/specs/publish/invalid_import/invalid_import.out b/tests/specs/publish/invalid_import/invalid_import.out index 6914dc51e08768..3b795ba2e9f918 100644 --- a/tests/specs/publish/invalid_import/invalid_import.out +++ b/tests/specs/publish/invalid_import/invalid_import.out @@ -12,7 +12,7 @@ error[invalid-external-import]: invalid import to a non-JSR 'http' specifier info: the import was resolved to 'http://localhost:4545/welcome.ts' info: this specifier is not allowed to be imported on jsr - info: jsr only supports importing `jsr:`, `npm:`, and `data:` specifiers + info: jsr only supports importing `jsr:`, `npm:`, `data:`, `bun:`, and `node:` specifiers docs: https://jsr.io/go/invalid-external-import error[invalid-external-import]: invalid import to a non-JSR 'http' specifier @@ -25,7 +25,7 @@ error[invalid-external-import]: invalid import to a non-JSR 'http' specifier info: the import was resolved to 'http://localhost:4545/echo.ts' info: this specifier is not allowed to be imported on jsr - info: jsr only supports importing `jsr:`, `npm:`, and `data:` specifiers + info: jsr only supports importing `jsr:`, `npm:`, `data:`, `bun:`, and `node:` specifiers docs: https://jsr.io/go/invalid-external-import error: Found 2 problems diff --git a/tests/specs/publish/invalid_import_esm_sh_suggestion/invalid_import_esm_sh_suggestion.out b/tests/specs/publish/invalid_import_esm_sh_suggestion/invalid_import_esm_sh_suggestion.out index b0a544df892885..1de23c0baec44c 100644 --- a/tests/specs/publish/invalid_import_esm_sh_suggestion/invalid_import_esm_sh_suggestion.out +++ b/tests/specs/publish/invalid_import_esm_sh_suggestion/invalid_import_esm_sh_suggestion.out @@ -13,7 +13,7 @@ error[invalid-external-import]: invalid import to a non-JSR 'http' 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 + info: jsr only supports importing `jsr:`, `npm:`, `data:`, `bun:`, and `node:` specifiers docs: https://jsr.io/go/invalid-external-import error: Found 1 problem diff --git a/tests/specs/publish/prefer_fast_check_graph/main.out b/tests/specs/publish/prefer_fast_check_graph/main.out index dd7d052c923a67..3ff4d33a30c416 100644 --- a/tests/specs/publish/prefer_fast_check_graph/main.out +++ b/tests/specs/publish/prefer_fast_check_graph/main.out @@ -13,7 +13,7 @@ error[invalid-external-import]: invalid import to a non-JSR 'https' 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 - info: jsr only supports importing `jsr:`, `npm:`, and `data:` specifiers + info: jsr only supports importing `jsr:`, `npm:`, `data:`, `bun:`, and `node:` specifiers docs: https://jsr.io/go/invalid-external-import error: Found 1 problem