diff --git a/cli/args/import_map.rs b/cli/args/import_map.rs index 200336c433..bac31c080e 100644 --- a/cli/args/import_map.rs +++ b/cli/args/import_map.rs @@ -3,11 +3,40 @@ use deno_core::error::AnyError; use deno_core::serde_json; use deno_core::url::Url; +use deno_runtime::permissions::PermissionsContainer; use import_map::ImportMap; use import_map::ImportMapDiagnostic; use log::warn; -pub fn import_map_from_value( +use super::ConfigFile; +use crate::file_fetcher::get_source_from_data_url; +use crate::file_fetcher::FileFetcher; + +pub async fn resolve_import_map_from_specifier( + specifier: &Url, + maybe_config_file: Option<&ConfigFile>, + file_fetcher: &FileFetcher, +) -> Result { + let value: serde_json::Value = if specifier.scheme() == "data" { + serde_json::from_str(&get_source_from_data_url(specifier)?.0)? + } else { + let import_map_config = maybe_config_file + .as_ref() + .filter(|c| c.specifier == *specifier); + match import_map_config { + Some(config) => config.to_import_map_value(), + None => { + let file = file_fetcher + .fetch(specifier, PermissionsContainer::allow_all()) + .await?; + serde_json::from_str(&file.source)? + } + } + }; + import_map_from_value(specifier, value) +} + +fn import_map_from_value( specifier: &Url, json_value: serde_json::Value, ) -> Result { diff --git a/cli/args/mod.rs b/cli/args/mod.rs index 1bf2940180..5cb29cab21 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -6,7 +6,7 @@ mod flags_allow_net; mod import_map; mod lockfile; -pub use self::import_map::import_map_from_value; +pub use self::import_map::resolve_import_map_from_specifier; use ::import_map::ImportMap; pub use config_file::BenchConfig; pub use config_file::CompilerOptions; @@ -21,8 +21,6 @@ pub use config_file::TsConfig; pub use config_file::TsConfigForEmit; pub use config_file::TsConfigType; pub use config_file::TsTypeLib; -use deno_core::serde_json; -use deno_runtime::permissions::PermissionsContainer; pub use flags::*; pub use lockfile::Lockfile; pub use lockfile::LockfileError; @@ -574,35 +572,17 @@ impl CliOptions { Some(specifier) => specifier, None => return Ok(None), }; - self - .resolve_import_map_from_specifier(&import_map_specifier, file_fetcher) - .await - .context(format!( - "Unable to load '{}' import map", - import_map_specifier - )) - .map(Some) - } - - async fn resolve_import_map_from_specifier( - &self, - import_map_specifier: &ModuleSpecifier, - file_fetcher: &FileFetcher, - ) -> Result { - let import_map_config = self - .get_maybe_config_file() - .as_ref() - .filter(|c| c.specifier == *import_map_specifier); - let value: serde_json::Value = match import_map_config { - Some(config) => config.to_import_map_value(), - None => { - let file = file_fetcher - .fetch(import_map_specifier, PermissionsContainer::allow_all()) - .await?; - serde_json::from_str(&file.source)? - } - }; - import_map_from_value(import_map_specifier, value) + resolve_import_map_from_specifier( + &import_map_specifier, + self.get_maybe_config_file().as_ref(), + file_fetcher, + ) + .await + .context(format!( + "Unable to load '{}' import map", + import_map_specifier + )) + .map(Some) } /// Overrides the import map specifier to use. diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs index 2376133f56..21140c66d9 100644 --- a/cli/file_fetcher.rs +++ b/cli/file_fetcher.rs @@ -193,8 +193,8 @@ impl FileFetcher { http_client: HttpClient, blob_store: BlobStore, progress_bar: Option, - ) -> Result { - Ok(Self { + ) -> Self { + Self { auth_tokens: AuthTokens::new(env::var("DENO_AUTH_TOKENS").ok()), allow_remote, cache: Default::default(), @@ -204,7 +204,7 @@ impl FileFetcher { blob_store, download_log_level: log::Level::Info, progress_bar, - }) + } } /// Sets the log level to use when outputting the download message. @@ -778,8 +778,7 @@ mod tests { HttpClient::new(None, None).unwrap(), blob_store.clone(), None, - ) - .unwrap(); + ); (file_fetcher, temp_dir, blob_store) } @@ -1215,8 +1214,7 @@ mod tests { HttpClient::new(None, None).unwrap(), BlobStore::default(), None, - ) - .unwrap(); + ); let result = file_fetcher .fetch(&specifier, PermissionsContainer::allow_all()) .await; @@ -1241,8 +1239,7 @@ mod tests { HttpClient::new(None, None).unwrap(), BlobStore::default(), None, - ) - .unwrap(); + ); let specifier = resolve_url("http://localhost:4545/subdir/mismatch_ext.ts").unwrap(); let cache_filename = file_fetcher_01 @@ -1267,8 +1264,7 @@ mod tests { HttpClient::new(None, None).unwrap(), BlobStore::default(), None, - ) - .unwrap(); + ); let result = file_fetcher_02 .fetch(&specifier, PermissionsContainer::allow_all()) .await; @@ -1409,8 +1405,7 @@ mod tests { HttpClient::new(None, None).unwrap(), BlobStore::default(), None, - ) - .unwrap(); + ); let specifier = resolve_url("http://localhost:4548/subdir/mismatch_ext.ts").unwrap(); let redirected_specifier = @@ -1438,8 +1433,7 @@ mod tests { HttpClient::new(None, None).unwrap(), BlobStore::default(), None, - ) - .unwrap(); + ); let result = file_fetcher_02 .fetch(&redirected_specifier, PermissionsContainer::allow_all()) .await; @@ -1538,8 +1532,7 @@ mod tests { HttpClient::new(None, None).unwrap(), BlobStore::default(), None, - ) - .unwrap(); + ); let specifier = resolve_url("http://localhost:4545/run/002_hello.ts").unwrap(); @@ -1564,8 +1557,7 @@ mod tests { HttpClient::new(None, None).unwrap(), BlobStore::default(), None, - ) - .unwrap(); + ); let file_fetcher_02 = FileFetcher::new( HttpCache::new(&location), CacheSetting::Use, @@ -1573,8 +1565,7 @@ mod tests { HttpClient::new(None, None).unwrap(), BlobStore::default(), None, - ) - .unwrap(); + ); let specifier = resolve_url("http://localhost:4545/run/002_hello.ts").unwrap(); diff --git a/cli/lsp/cache.rs b/cli/lsp/cache.rs index 23469a583f..bad9321767 100644 --- a/cli/lsp/cache.rs +++ b/cli/lsp/cache.rs @@ -55,9 +55,9 @@ pub struct CacheMetadata { } impl CacheMetadata { - pub fn new(location: &Path) -> Self { + pub fn new(cache: HttpCache) -> Self { Self { - cache: HttpCache::new(location), + cache, metadata: Default::default(), } } diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 7f53b17f3d..ccaed0a274 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -8,6 +8,7 @@ use deno_core::serde_json; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::ModuleSpecifier; +use deno_runtime::deno_web::BlobStore; use import_map::ImportMap; use log::error; use log::warn; @@ -17,7 +18,6 @@ use std::env; use std::fmt::Write as _; use std::path::PathBuf; use std::sync::Arc; -use tokio::fs; use tower_lsp::jsonrpc::Error as LspError; use tower_lsp::jsonrpc::Result as LspResult; use tower_lsp::lsp_types::request::*; @@ -57,7 +57,7 @@ use super::tsc::AssetsSnapshot; use super::tsc::TsServer; use super::urls; use crate::args::get_root_cert_store; -use crate::args::import_map_from_value; +use crate::args::resolve_import_map_from_specifier; use crate::args::CaData; use crate::args::CacheSetting; use crate::args::CliOptions; @@ -67,7 +67,8 @@ use crate::args::FmtOptions; use crate::args::LintOptions; use crate::args::TsConfig; use crate::cache::DenoDir; -use crate::file_fetcher::get_source_from_data_url; +use crate::cache::HttpCache; +use crate::file_fetcher::FileFetcher; use crate::graph_util::graph_valid; use crate::http_util::HttpClient; use crate::npm::NpmCache; @@ -108,10 +109,12 @@ pub struct Inner { pub client: Client, /// Configuration information. pub config: Config, + deps_http_cache: HttpCache, diagnostics_server: diagnostics::DiagnosticsServer, /// The collection of documents that the server is currently handling, either /// on disk or "open" within the client. pub documents: Documents, + http_client: HttpClient, /// Handles module registries, which allow discovery of modules module_registries: ModuleRegistry, /// The path to the module registries cache @@ -123,7 +126,7 @@ pub struct Inner { /// options. maybe_config_file: Option, /// An optional import map which is used to resolve modules. - pub maybe_import_map: Option>, + maybe_import_map: Option>, /// The URL for the import map which is used to determine relative imports. maybe_import_map_uri: Option, /// Configuration for formatter which has been taken from specified config file. @@ -324,7 +327,8 @@ impl Inner { .unwrap(); let location = dir.deps_folder_path(); let documents = Documents::new(&location); - let cache_metadata = cache::CacheMetadata::new(&location); + let deps_http_cache = HttpCache::new(&location); + let cache_metadata = cache::CacheMetadata::new(deps_http_cache.clone()); let performance = Arc::new(Performance::default()); let ts_server = Arc::new(TsServer::new(performance.clone())); let config = Config::new(); @@ -334,15 +338,17 @@ impl Inner { ts_server.clone(), ); let assets = Assets::new(ts_server.clone()); - let npm_resolver = create_lsp_npm_resolver(&dir, http_client); + let npm_resolver = create_lsp_npm_resolver(&dir, http_client.clone()); Self { assets, cache_metadata, client, config, + deps_http_cache, diagnostics_server, documents, + http_client, maybe_cache_path: None, maybe_config_file: None, maybe_import_map: None, @@ -581,15 +587,17 @@ impl Inner { workspace_settings.certificate_stores, workspace_settings.tls_certificate.map(CaData::File), )?); - let client = HttpClient::new( + let module_registries_location = dir.registries_folder_path(); + self.http_client = HttpClient::new( root_cert_store, workspace_settings.unsafely_ignore_certificate_errors, )?; - let module_registries_location = dir.registries_folder_path(); - self.module_registries = - ModuleRegistry::new(&module_registries_location, client.clone())?; + self.module_registries = ModuleRegistry::new( + &module_registries_location, + self.http_client.clone(), + )?; self.module_registries_location = module_registries_location; - self.npm_resolver = create_lsp_npm_resolver(&dir, client); + self.npm_resolver = create_lsp_npm_resolver(&dir, self.http_client.clone()); // update the cache path let location = dir.deps_folder_path(); self.documents.set_location(&location); @@ -603,16 +611,13 @@ impl Inner { let maybe_import_map_url = self.resolve_import_map_specifier()?; if let Some(import_map_url) = maybe_import_map_url { + if import_map_url.scheme() != "data" { + lsp_log!(" Resolved import map: \"{}\"", import_map_url); + } + let import_map = self - .resolve_import_map_from_specifier(&import_map_url) - .await - .map_err(|err| { - anyhow!( - "Failed to load the import map at: {}. {:#}", - import_map_url, - err - ) - })?; + .fetch_import_map(&import_map_url, CacheSetting::RespectHeaders) + .await?; self.maybe_import_map_uri = Some(import_map_url); self.maybe_import_map = Some(Arc::new(import_map)); } else { @@ -623,6 +628,39 @@ impl Inner { Ok(()) } + async fn fetch_import_map( + &self, + import_map_url: &ModuleSpecifier, + cache_setting: CacheSetting, + ) -> Result { + resolve_import_map_from_specifier( + import_map_url, + self.maybe_config_file.as_ref(), + &self.create_file_fetcher(cache_setting), + ) + .await + .map_err(|err| { + anyhow!( + "Failed to load the import map at: {}. {:#}", + import_map_url, + err + ) + }) + } + + fn create_file_fetcher(&self, cache_setting: CacheSetting) -> FileFetcher { + let mut file_fetcher = FileFetcher::new( + self.deps_http_cache.clone(), + cache_setting, + true, + self.http_client.clone(), + BlobStore::default(), + None, + ); + file_fetcher.set_download_log_level(super::logging::lsp_log_level()); + file_fetcher + } + fn resolve_import_map_specifier( &self, ) -> Result, AnyError> { @@ -702,33 +740,6 @@ impl Inner { ) } - async fn resolve_import_map_from_specifier( - &self, - import_map_url: &ModuleSpecifier, - ) -> Result { - let import_map_json: Value = if import_map_url.scheme() == "data" { - serde_json::from_str(&get_source_from_data_url(import_map_url)?.0)? - } else { - let import_map_path = specifier_to_file_path(import_map_url)?; - lsp_log!( - " Resolved import map: \"{}\"", - import_map_path.to_string_lossy() - ); - let import_map_config_file = self - .maybe_config_file - .as_ref() - .filter(|c| c.specifier == *import_map_url); - match import_map_config_file { - Some(c) => c.to_import_map_value(), - None => { - serde_json::from_str(&fs::read_to_string(import_map_path).await?)? - } - } - }; - - import_map_from_value(import_map_url, import_map_json) - } - pub fn update_debug_flag(&self) { let internal_debug = self.config.get_workspace_settings().internal_debug; super::logging::set_lsp_debug_flag(internal_debug) diff --git a/cli/lsp/registries.rs b/cli/lsp/registries.rs index c8e5dad60f..ca7b6368e9 100644 --- a/cli/lsp/registries.rs +++ b/cli/lsp/registries.rs @@ -442,7 +442,7 @@ impl ModuleRegistry { http_client, BlobStore::default(), None, - )?; + ); file_fetcher.set_download_log_level(super::logging::lsp_log_level()); Ok(Self { diff --git a/cli/proc_state.rs b/cli/proc_state.rs index e979ffd6b8..eca4579c83 100644 --- a/cli/proc_state.rs +++ b/cli/proc_state.rs @@ -202,7 +202,7 @@ impl ProcState { http_client.clone(), blob_store.clone(), Some(progress_bar.clone()), - )?; + ); let lockfile = cli_options.maybe_lock_file(); diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs index 62bfe136f2..fd6644326a 100644 --- a/cli/tests/integration/run_tests.rs +++ b/cli/tests/integration/run_tests.rs @@ -182,6 +182,13 @@ itest!(_033_import_map_remote { http_server: true, }); +itest!(_033_import_map_data_uri { + args: + "run --quiet --reload --import-map=data:application/json;charset=utf-8;base64,ewogICJpbXBvcnRzIjogewogICAgInRlc3Rfc2VydmVyLyI6ICJodHRwOi8vbG9jYWxob3N0OjQ1NDUvIgogIH0KfQ== run/import_maps/test_data.ts", + output: "run/import_maps/test_data.ts.out", + http_server: true, +}); + itest!(onload { args: "run --quiet --reload run/onload/main.ts", output: "run/onload/main.out", diff --git a/cli/tests/testdata/run/import_maps/test_data.ts b/cli/tests/testdata/run/import_maps/test_data.ts new file mode 100644 index 0000000000..5e8efea69b --- /dev/null +++ b/cli/tests/testdata/run/import_maps/test_data.ts @@ -0,0 +1 @@ +import "test_server/import_maps/lodash/lodash.ts"; diff --git a/cli/tests/testdata/run/import_maps/test_data.ts.out b/cli/tests/testdata/run/import_maps/test_data.ts.out new file mode 100644 index 0000000000..da996dc0d9 --- /dev/null +++ b/cli/tests/testdata/run/import_maps/test_data.ts.out @@ -0,0 +1 @@ +Hello from remapped lodash!