0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 17:34:47 -05:00

fix: support import map specified as data uri (#17531)

This commit is contained in:
David Sherret 2023-01-25 16:51:04 -05:00 committed by GitHub
parent c6c8c91a6e
commit 34c14dbf99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 125 additions and 105 deletions

View file

@ -3,11 +3,40 @@
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::serde_json; use deno_core::serde_json;
use deno_core::url::Url; use deno_core::url::Url;
use deno_runtime::permissions::PermissionsContainer;
use import_map::ImportMap; use import_map::ImportMap;
use import_map::ImportMapDiagnostic; use import_map::ImportMapDiagnostic;
use log::warn; 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<ImportMap, AnyError> {
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, specifier: &Url,
json_value: serde_json::Value, json_value: serde_json::Value,
) -> Result<ImportMap, AnyError> { ) -> Result<ImportMap, AnyError> {

View file

@ -6,7 +6,7 @@ mod flags_allow_net;
mod import_map; mod import_map;
mod lockfile; 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; use ::import_map::ImportMap;
pub use config_file::BenchConfig; pub use config_file::BenchConfig;
pub use config_file::CompilerOptions; pub use config_file::CompilerOptions;
@ -21,8 +21,6 @@ pub use config_file::TsConfig;
pub use config_file::TsConfigForEmit; pub use config_file::TsConfigForEmit;
pub use config_file::TsConfigType; pub use config_file::TsConfigType;
pub use config_file::TsTypeLib; pub use config_file::TsTypeLib;
use deno_core::serde_json;
use deno_runtime::permissions::PermissionsContainer;
pub use flags::*; pub use flags::*;
pub use lockfile::Lockfile; pub use lockfile::Lockfile;
pub use lockfile::LockfileError; pub use lockfile::LockfileError;
@ -574,8 +572,11 @@ impl CliOptions {
Some(specifier) => specifier, Some(specifier) => specifier,
None => return Ok(None), None => return Ok(None),
}; };
self resolve_import_map_from_specifier(
.resolve_import_map_from_specifier(&import_map_specifier, file_fetcher) &import_map_specifier,
self.get_maybe_config_file().as_ref(),
file_fetcher,
)
.await .await
.context(format!( .context(format!(
"Unable to load '{}' import map", "Unable to load '{}' import map",
@ -584,27 +585,6 @@ impl CliOptions {
.map(Some) .map(Some)
} }
async fn resolve_import_map_from_specifier(
&self,
import_map_specifier: &ModuleSpecifier,
file_fetcher: &FileFetcher,
) -> Result<ImportMap, AnyError> {
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)
}
/// Overrides the import map specifier to use. /// Overrides the import map specifier to use.
pub fn set_import_map_specifier(&mut self, path: Option<ModuleSpecifier>) { pub fn set_import_map_specifier(&mut self, path: Option<ModuleSpecifier>) {
self.overrides.import_map_specifier = Some(path); self.overrides.import_map_specifier = Some(path);

View file

@ -193,8 +193,8 @@ impl FileFetcher {
http_client: HttpClient, http_client: HttpClient,
blob_store: BlobStore, blob_store: BlobStore,
progress_bar: Option<ProgressBar>, progress_bar: Option<ProgressBar>,
) -> Result<Self, AnyError> { ) -> Self {
Ok(Self { Self {
auth_tokens: AuthTokens::new(env::var("DENO_AUTH_TOKENS").ok()), auth_tokens: AuthTokens::new(env::var("DENO_AUTH_TOKENS").ok()),
allow_remote, allow_remote,
cache: Default::default(), cache: Default::default(),
@ -204,7 +204,7 @@ impl FileFetcher {
blob_store, blob_store,
download_log_level: log::Level::Info, download_log_level: log::Level::Info,
progress_bar, progress_bar,
}) }
} }
/// Sets the log level to use when outputting the download message. /// Sets the log level to use when outputting the download message.
@ -778,8 +778,7 @@ mod tests {
HttpClient::new(None, None).unwrap(), HttpClient::new(None, None).unwrap(),
blob_store.clone(), blob_store.clone(),
None, None,
) );
.unwrap();
(file_fetcher, temp_dir, blob_store) (file_fetcher, temp_dir, blob_store)
} }
@ -1215,8 +1214,7 @@ mod tests {
HttpClient::new(None, None).unwrap(), HttpClient::new(None, None).unwrap(),
BlobStore::default(), BlobStore::default(),
None, None,
) );
.unwrap();
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, PermissionsContainer::allow_all())
.await; .await;
@ -1241,8 +1239,7 @@ mod tests {
HttpClient::new(None, None).unwrap(), HttpClient::new(None, None).unwrap(),
BlobStore::default(), BlobStore::default(),
None, None,
) );
.unwrap();
let specifier = let specifier =
resolve_url("http://localhost:4545/subdir/mismatch_ext.ts").unwrap(); resolve_url("http://localhost:4545/subdir/mismatch_ext.ts").unwrap();
let cache_filename = file_fetcher_01 let cache_filename = file_fetcher_01
@ -1267,8 +1264,7 @@ mod tests {
HttpClient::new(None, None).unwrap(), HttpClient::new(None, None).unwrap(),
BlobStore::default(), BlobStore::default(),
None, None,
) );
.unwrap();
let result = file_fetcher_02 let result = file_fetcher_02
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, PermissionsContainer::allow_all())
.await; .await;
@ -1409,8 +1405,7 @@ mod tests {
HttpClient::new(None, None).unwrap(), HttpClient::new(None, None).unwrap(),
BlobStore::default(), BlobStore::default(),
None, None,
) );
.unwrap();
let specifier = let specifier =
resolve_url("http://localhost:4548/subdir/mismatch_ext.ts").unwrap(); resolve_url("http://localhost:4548/subdir/mismatch_ext.ts").unwrap();
let redirected_specifier = let redirected_specifier =
@ -1438,8 +1433,7 @@ mod tests {
HttpClient::new(None, None).unwrap(), HttpClient::new(None, None).unwrap(),
BlobStore::default(), BlobStore::default(),
None, None,
) );
.unwrap();
let result = file_fetcher_02 let result = file_fetcher_02
.fetch(&redirected_specifier, PermissionsContainer::allow_all()) .fetch(&redirected_specifier, PermissionsContainer::allow_all())
.await; .await;
@ -1538,8 +1532,7 @@ mod tests {
HttpClient::new(None, None).unwrap(), HttpClient::new(None, None).unwrap(),
BlobStore::default(), BlobStore::default(),
None, None,
) );
.unwrap();
let specifier = let specifier =
resolve_url("http://localhost:4545/run/002_hello.ts").unwrap(); resolve_url("http://localhost:4545/run/002_hello.ts").unwrap();
@ -1564,8 +1557,7 @@ mod tests {
HttpClient::new(None, None).unwrap(), HttpClient::new(None, None).unwrap(),
BlobStore::default(), BlobStore::default(),
None, None,
) );
.unwrap();
let file_fetcher_02 = FileFetcher::new( let file_fetcher_02 = FileFetcher::new(
HttpCache::new(&location), HttpCache::new(&location),
CacheSetting::Use, CacheSetting::Use,
@ -1573,8 +1565,7 @@ mod tests {
HttpClient::new(None, None).unwrap(), HttpClient::new(None, None).unwrap(),
BlobStore::default(), BlobStore::default(),
None, None,
) );
.unwrap();
let specifier = let specifier =
resolve_url("http://localhost:4545/run/002_hello.ts").unwrap(); resolve_url("http://localhost:4545/run/002_hello.ts").unwrap();

View file

@ -55,9 +55,9 @@ pub struct CacheMetadata {
} }
impl CacheMetadata { impl CacheMetadata {
pub fn new(location: &Path) -> Self { pub fn new(cache: HttpCache) -> Self {
Self { Self {
cache: HttpCache::new(location), cache,
metadata: Default::default(), metadata: Default::default(),
} }
} }

View file

@ -8,6 +8,7 @@ use deno_core::serde_json;
use deno_core::serde_json::json; use deno_core::serde_json::json;
use deno_core::serde_json::Value; use deno_core::serde_json::Value;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_runtime::deno_web::BlobStore;
use import_map::ImportMap; use import_map::ImportMap;
use log::error; use log::error;
use log::warn; use log::warn;
@ -17,7 +18,6 @@ use std::env;
use std::fmt::Write as _; use std::fmt::Write as _;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use tokio::fs;
use tower_lsp::jsonrpc::Error as LspError; use tower_lsp::jsonrpc::Error as LspError;
use tower_lsp::jsonrpc::Result as LspResult; use tower_lsp::jsonrpc::Result as LspResult;
use tower_lsp::lsp_types::request::*; use tower_lsp::lsp_types::request::*;
@ -57,7 +57,7 @@ use super::tsc::AssetsSnapshot;
use super::tsc::TsServer; use super::tsc::TsServer;
use super::urls; use super::urls;
use crate::args::get_root_cert_store; 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::CaData;
use crate::args::CacheSetting; use crate::args::CacheSetting;
use crate::args::CliOptions; use crate::args::CliOptions;
@ -67,7 +67,8 @@ use crate::args::FmtOptions;
use crate::args::LintOptions; use crate::args::LintOptions;
use crate::args::TsConfig; use crate::args::TsConfig;
use crate::cache::DenoDir; 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::graph_util::graph_valid;
use crate::http_util::HttpClient; use crate::http_util::HttpClient;
use crate::npm::NpmCache; use crate::npm::NpmCache;
@ -108,10 +109,12 @@ pub struct Inner {
pub client: Client, pub client: Client,
/// Configuration information. /// Configuration information.
pub config: Config, pub config: Config,
deps_http_cache: HttpCache,
diagnostics_server: diagnostics::DiagnosticsServer, diagnostics_server: diagnostics::DiagnosticsServer,
/// The collection of documents that the server is currently handling, either /// The collection of documents that the server is currently handling, either
/// on disk or "open" within the client. /// on disk or "open" within the client.
pub documents: Documents, pub documents: Documents,
http_client: HttpClient,
/// Handles module registries, which allow discovery of modules /// Handles module registries, which allow discovery of modules
module_registries: ModuleRegistry, module_registries: ModuleRegistry,
/// The path to the module registries cache /// The path to the module registries cache
@ -123,7 +126,7 @@ pub struct Inner {
/// options. /// options.
maybe_config_file: Option<ConfigFile>, maybe_config_file: Option<ConfigFile>,
/// An optional import map which is used to resolve modules. /// An optional import map which is used to resolve modules.
pub maybe_import_map: Option<Arc<ImportMap>>, maybe_import_map: Option<Arc<ImportMap>>,
/// The URL for the import map which is used to determine relative imports. /// The URL for the import map which is used to determine relative imports.
maybe_import_map_uri: Option<Url>, maybe_import_map_uri: Option<Url>,
/// Configuration for formatter which has been taken from specified config file. /// Configuration for formatter which has been taken from specified config file.
@ -324,7 +327,8 @@ impl Inner {
.unwrap(); .unwrap();
let location = dir.deps_folder_path(); let location = dir.deps_folder_path();
let documents = Documents::new(&location); 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 performance = Arc::new(Performance::default());
let ts_server = Arc::new(TsServer::new(performance.clone())); let ts_server = Arc::new(TsServer::new(performance.clone()));
let config = Config::new(); let config = Config::new();
@ -334,15 +338,17 @@ impl Inner {
ts_server.clone(), ts_server.clone(),
); );
let assets = Assets::new(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 { Self {
assets, assets,
cache_metadata, cache_metadata,
client, client,
config, config,
deps_http_cache,
diagnostics_server, diagnostics_server,
documents, documents,
http_client,
maybe_cache_path: None, maybe_cache_path: None,
maybe_config_file: None, maybe_config_file: None,
maybe_import_map: None, maybe_import_map: None,
@ -581,15 +587,17 @@ impl Inner {
workspace_settings.certificate_stores, workspace_settings.certificate_stores,
workspace_settings.tls_certificate.map(CaData::File), 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, root_cert_store,
workspace_settings.unsafely_ignore_certificate_errors, workspace_settings.unsafely_ignore_certificate_errors,
)?; )?;
let module_registries_location = dir.registries_folder_path(); self.module_registries = ModuleRegistry::new(
self.module_registries = &module_registries_location,
ModuleRegistry::new(&module_registries_location, client.clone())?; self.http_client.clone(),
)?;
self.module_registries_location = module_registries_location; 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 // update the cache path
let location = dir.deps_folder_path(); let location = dir.deps_folder_path();
self.documents.set_location(&location); self.documents.set_location(&location);
@ -603,16 +611,13 @@ impl Inner {
let maybe_import_map_url = self.resolve_import_map_specifier()?; let maybe_import_map_url = self.resolve_import_map_specifier()?;
if let Some(import_map_url) = maybe_import_map_url { 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 let import_map = self
.resolve_import_map_from_specifier(&import_map_url) .fetch_import_map(&import_map_url, CacheSetting::RespectHeaders)
.await .await?;
.map_err(|err| {
anyhow!(
"Failed to load the import map at: {}. {:#}",
import_map_url,
err
)
})?;
self.maybe_import_map_uri = Some(import_map_url); self.maybe_import_map_uri = Some(import_map_url);
self.maybe_import_map = Some(Arc::new(import_map)); self.maybe_import_map = Some(Arc::new(import_map));
} else { } else {
@ -623,6 +628,39 @@ impl Inner {
Ok(()) Ok(())
} }
async fn fetch_import_map(
&self,
import_map_url: &ModuleSpecifier,
cache_setting: CacheSetting,
) -> Result<ImportMap, AnyError> {
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( fn resolve_import_map_specifier(
&self, &self,
) -> Result<Option<ModuleSpecifier>, AnyError> { ) -> Result<Option<ModuleSpecifier>, AnyError> {
@ -702,33 +740,6 @@ impl Inner {
) )
} }
async fn resolve_import_map_from_specifier(
&self,
import_map_url: &ModuleSpecifier,
) -> Result<ImportMap, AnyError> {
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) { pub fn update_debug_flag(&self) {
let internal_debug = self.config.get_workspace_settings().internal_debug; let internal_debug = self.config.get_workspace_settings().internal_debug;
super::logging::set_lsp_debug_flag(internal_debug) super::logging::set_lsp_debug_flag(internal_debug)

View file

@ -442,7 +442,7 @@ impl ModuleRegistry {
http_client, http_client,
BlobStore::default(), BlobStore::default(),
None, None,
)?; );
file_fetcher.set_download_log_level(super::logging::lsp_log_level()); file_fetcher.set_download_log_level(super::logging::lsp_log_level());
Ok(Self { Ok(Self {

View file

@ -202,7 +202,7 @@ impl ProcState {
http_client.clone(), http_client.clone(),
blob_store.clone(), blob_store.clone(),
Some(progress_bar.clone()), Some(progress_bar.clone()),
)?; );
let lockfile = cli_options.maybe_lock_file(); let lockfile = cli_options.maybe_lock_file();

View file

@ -182,6 +182,13 @@ itest!(_033_import_map_remote {
http_server: true, 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 { itest!(onload {
args: "run --quiet --reload run/onload/main.ts", args: "run --quiet --reload run/onload/main.ts",
output: "run/onload/main.out", output: "run/onload/main.out",

View file

@ -0,0 +1 @@
import "test_server/import_maps/lodash/lodash.ts";

View file

@ -0,0 +1 @@
Hello from remapped lodash!