From 576b20aa005c233b95afe6e3692a899ae8f755f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 28 Dec 2023 20:37:10 +0100 Subject: [PATCH] fix: allow npm: specifiers in import.meta.resolve (#21716) Closes https://github.com/denoland/deno/issues/21298. "npm:" specifiers are matched against import map entries and if no match is found they are passed through. --- .../testdata/run/import_meta/importmap.json | 3 ++- cli/tests/testdata/run/import_meta/main.out | 5 +++-- cli/tests/testdata/run/import_meta/main.ts | 17 ++++++++++++----- runtime/web_worker.rs | 4 ++++ runtime/worker.rs | 15 +++++++++++++++ 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/cli/tests/testdata/run/import_meta/importmap.json b/cli/tests/testdata/run/import_meta/importmap.json index f8c056afd6..d85fe30285 100644 --- a/cli/tests/testdata/run/import_meta/importmap.json +++ b/cli/tests/testdata/run/import_meta/importmap.json @@ -6,6 +6,7 @@ "1": "https://example.com/PASS-1", "null": "https://example.com/PASS-null", "undefined": "https://example.com/PASS-undefined", - "[object Object]": "https://example.com/PASS-object" + "[object Object]": "https://example.com/PASS-object", + "npm:preact": "https://example.com/preact" } } diff --git a/cli/tests/testdata/run/import_meta/main.out b/cli/tests/testdata/run/import_meta/main.out index 1b51f1cdfe..0329dea8a7 100644 --- a/cli/tests/testdata/run/import_meta/main.out +++ b/cli/tests/testdata/run/import_meta/main.out @@ -7,5 +7,6 @@ Resolving without a value from import map https://example.com/PASS-undefined Resolving 1 from import map https://example.com/PASS-1 Resolving null from import map https://example.com/PASS-null Resolving object from import map https://example.com/PASS-object -TypeError: "npm:" specifiers are currently not supported in import.meta.resolve() - at file:///[WILDCARD]testdata/run/import_meta/main.ts:36:15 +Resolving npm:cowsay npm:cowsay +Resolving npm:cowsay@1 npm:cowsay@1 +Resolving npm:preact from import map https://example.com/preact diff --git a/cli/tests/testdata/run/import_meta/main.ts b/cli/tests/testdata/run/import_meta/main.ts index b6d9c506ec..96d63ba786 100644 --- a/cli/tests/testdata/run/import_meta/main.ts +++ b/cli/tests/testdata/run/import_meta/main.ts @@ -32,8 +32,15 @@ assertThrows(() => { assertThrows(() => { import.meta.resolve("://malformed/url?asdf"); }, TypeError); -try { - import.meta.resolve("npm:cowsay"); -} catch (e) { - console.log(e); -} +console.log( + "Resolving npm:cowsay", + import.meta.resolve("npm:cowsay"), +); +console.log( + "Resolving npm:cowsay@1", + import.meta.resolve("npm:cowsay@1"), +); +console.log( + "Resolving npm:preact from import map", + import.meta.resolve("npm:preact"), +); diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 41e6ca4fe4..308c294efa 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -5,6 +5,7 @@ use crate::ops; use crate::permissions::PermissionsContainer; use crate::shared::runtime; use crate::tokio_util::create_and_run_current_thread; +use crate::worker::import_meta_resolve_callback; use crate::worker::FormatJsErrorFn; use crate::BootstrapOptions; use deno_broadcast_channel::InMemoryBroadcastChannel; @@ -536,6 +537,9 @@ impl WebWorker { inspector: options.maybe_inspector_server.is_some(), feature_checker: Some(options.feature_checker.clone()), op_metrics_factory_fn, + import_meta_resolve_callback: Some(Box::new( + import_meta_resolve_callback, + )), ..Default::default() }); diff --git a/runtime/worker.rs b/runtime/worker.rs index 237ebfe13b..f48f81fe77 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -50,6 +50,18 @@ use crate::BootstrapOptions; pub type FormatJsErrorFn = dyn Fn(&JsError) -> String + Sync + Send; +pub fn import_meta_resolve_callback( + loader: &dyn deno_core::ModuleLoader, + specifier: String, + referrer: String, +) -> Result { + loader.resolve( + &specifier, + &referrer, + deno_core::ResolutionKind::DynamicImport, + ) +} + #[derive(Clone, Default)] pub struct ExitCode(Arc); @@ -447,6 +459,9 @@ impl MainWorker { wait_for_inspector_disconnect_callback: Some( wait_for_inspector_disconnect_callback, ), + import_meta_resolve_callback: Some(Box::new( + import_meta_resolve_callback, + )), ..Default::default() });