mirror of
https://github.com/denoland/deno.git
synced 2024-11-28 16:20:57 -05:00
refactor(npm): add CliNodeResolver (#18742)
This commit is contained in:
parent
7762566a6a
commit
772e4c033f
16 changed files with 474 additions and 442 deletions
|
@ -17,11 +17,9 @@ use crate::file_fetcher::get_source_from_bytes;
|
||||||
use crate::file_fetcher::map_content_type;
|
use crate::file_fetcher::map_content_type;
|
||||||
use crate::file_fetcher::SUPPORTED_SCHEMES;
|
use crate::file_fetcher::SUPPORTED_SCHEMES;
|
||||||
use crate::lsp::logging::lsp_warn;
|
use crate::lsp::logging::lsp_warn;
|
||||||
use crate::node;
|
use crate::node::CliNodeResolver;
|
||||||
use crate::node::node_resolve_npm_reference;
|
|
||||||
use crate::node::NodeResolution;
|
use crate::node::NodeResolution;
|
||||||
use crate::npm::CliNpmRegistryApi;
|
use crate::npm::CliNpmRegistryApi;
|
||||||
use crate::npm::NpmPackageResolver;
|
|
||||||
use crate::npm::NpmResolution;
|
use crate::npm::NpmResolution;
|
||||||
use crate::npm::PackageJsonDepsInstaller;
|
use crate::npm::PackageJsonDepsInstaller;
|
||||||
use crate::resolver::CliGraphResolver;
|
use crate::resolver::CliGraphResolver;
|
||||||
|
@ -1057,7 +1055,7 @@ impl Documents {
|
||||||
&self,
|
&self,
|
||||||
specifiers: Vec<String>,
|
specifiers: Vec<String>,
|
||||||
referrer_doc: &AssetOrDocument,
|
referrer_doc: &AssetOrDocument,
|
||||||
maybe_npm_resolver: Option<&Arc<NpmPackageResolver>>,
|
maybe_node_resolver: Option<&Arc<CliNodeResolver>>,
|
||||||
) -> Vec<Option<(ModuleSpecifier, MediaType)>> {
|
) -> Vec<Option<(ModuleSpecifier, MediaType)>> {
|
||||||
let referrer = referrer_doc.specifier();
|
let referrer = referrer_doc.specifier();
|
||||||
let dependencies = match referrer_doc {
|
let dependencies = match referrer_doc {
|
||||||
|
@ -1066,19 +1064,19 @@ impl Documents {
|
||||||
};
|
};
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
for specifier in specifiers {
|
for specifier in specifiers {
|
||||||
if let Some(npm_resolver) = maybe_npm_resolver {
|
if let Some(node_resolver) = maybe_node_resolver {
|
||||||
if npm_resolver.in_npm_package(referrer) {
|
if node_resolver.in_npm_package(referrer) {
|
||||||
// we're in an npm package, so use node resolution
|
// we're in an npm package, so use node resolution
|
||||||
results.push(Some(NodeResolution::into_specifier_and_media_type(
|
results.push(Some(NodeResolution::into_specifier_and_media_type(
|
||||||
node::node_resolve(
|
node_resolver
|
||||||
&specifier,
|
.resolve(
|
||||||
referrer,
|
&specifier,
|
||||||
NodeResolutionMode::Types,
|
referrer,
|
||||||
&npm_resolver.as_require_npm_resolver(),
|
NodeResolutionMode::Types,
|
||||||
&mut PermissionsContainer::allow_all(),
|
&mut PermissionsContainer::allow_all(),
|
||||||
)
|
)
|
||||||
.ok()
|
.ok()
|
||||||
.flatten(),
|
.flatten(),
|
||||||
)));
|
)));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1106,9 +1104,9 @@ impl Documents {
|
||||||
dependencies.as_ref().and_then(|d| d.deps.get(&specifier))
|
dependencies.as_ref().and_then(|d| d.deps.get(&specifier))
|
||||||
{
|
{
|
||||||
if let Some(specifier) = dep.maybe_type.maybe_specifier() {
|
if let Some(specifier) = dep.maybe_type.maybe_specifier() {
|
||||||
results.push(self.resolve_dependency(specifier, maybe_npm_resolver));
|
results.push(self.resolve_dependency(specifier, maybe_node_resolver));
|
||||||
} else if let Some(specifier) = dep.maybe_code.maybe_specifier() {
|
} else if let Some(specifier) = dep.maybe_code.maybe_specifier() {
|
||||||
results.push(self.resolve_dependency(specifier, maybe_npm_resolver));
|
results.push(self.resolve_dependency(specifier, maybe_node_resolver));
|
||||||
} else {
|
} else {
|
||||||
results.push(None);
|
results.push(None);
|
||||||
}
|
}
|
||||||
|
@ -1116,11 +1114,12 @@ impl Documents {
|
||||||
.resolve_imports_dependency(&specifier)
|
.resolve_imports_dependency(&specifier)
|
||||||
.and_then(|r| r.maybe_specifier())
|
.and_then(|r| r.maybe_specifier())
|
||||||
{
|
{
|
||||||
results.push(self.resolve_dependency(specifier, maybe_npm_resolver));
|
results.push(self.resolve_dependency(specifier, maybe_node_resolver));
|
||||||
} else if let Ok(npm_req_ref) =
|
} else if let Ok(npm_req_ref) =
|
||||||
NpmPackageReqReference::from_str(&specifier)
|
NpmPackageReqReference::from_str(&specifier)
|
||||||
{
|
{
|
||||||
results.push(node_resolve_npm_req_ref(npm_req_ref, maybe_npm_resolver));
|
results
|
||||||
|
.push(node_resolve_npm_req_ref(npm_req_ref, maybe_node_resolver));
|
||||||
} else {
|
} else {
|
||||||
results.push(None);
|
results.push(None);
|
||||||
}
|
}
|
||||||
|
@ -1418,10 +1417,10 @@ impl Documents {
|
||||||
fn resolve_dependency(
|
fn resolve_dependency(
|
||||||
&self,
|
&self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
maybe_npm_resolver: Option<&Arc<NpmPackageResolver>>,
|
maybe_node_resolver: Option<&Arc<CliNodeResolver>>,
|
||||||
) -> Option<(ModuleSpecifier, MediaType)> {
|
) -> Option<(ModuleSpecifier, MediaType)> {
|
||||||
if let Ok(npm_ref) = NpmPackageReqReference::from_specifier(specifier) {
|
if let Ok(npm_ref) = NpmPackageReqReference::from_specifier(specifier) {
|
||||||
return node_resolve_npm_req_ref(npm_ref, maybe_npm_resolver);
|
return node_resolve_npm_req_ref(npm_ref, maybe_node_resolver);
|
||||||
}
|
}
|
||||||
let doc = self.get(specifier)?;
|
let doc = self.get(specifier)?;
|
||||||
let maybe_module = doc.maybe_esm_module().and_then(|r| r.as_ref().ok());
|
let maybe_module = doc.maybe_esm_module().and_then(|r| r.as_ref().ok());
|
||||||
|
@ -1430,7 +1429,7 @@ impl Documents {
|
||||||
if let Some(specifier) =
|
if let Some(specifier) =
|
||||||
maybe_types_dependency.and_then(|d| d.maybe_specifier())
|
maybe_types_dependency.and_then(|d| d.maybe_specifier())
|
||||||
{
|
{
|
||||||
self.resolve_dependency(specifier, maybe_npm_resolver)
|
self.resolve_dependency(specifier, maybe_node_resolver)
|
||||||
} else {
|
} else {
|
||||||
let media_type = doc.media_type();
|
let media_type = doc.media_type();
|
||||||
Some((specifier.clone(), media_type))
|
Some((specifier.clone(), media_type))
|
||||||
|
@ -1453,23 +1452,18 @@ impl Documents {
|
||||||
|
|
||||||
fn node_resolve_npm_req_ref(
|
fn node_resolve_npm_req_ref(
|
||||||
npm_req_ref: NpmPackageReqReference,
|
npm_req_ref: NpmPackageReqReference,
|
||||||
maybe_npm_resolver: Option<&Arc<NpmPackageResolver>>,
|
maybe_node_resolver: Option<&Arc<CliNodeResolver>>,
|
||||||
) -> Option<(ModuleSpecifier, MediaType)> {
|
) -> Option<(ModuleSpecifier, MediaType)> {
|
||||||
maybe_npm_resolver.map(|npm_resolver| {
|
maybe_node_resolver.map(|node_resolver| {
|
||||||
NodeResolution::into_specifier_and_media_type(
|
NodeResolution::into_specifier_and_media_type(
|
||||||
npm_resolver
|
node_resolver
|
||||||
.pkg_req_ref_to_nv_ref(npm_req_ref)
|
.resolve_npm_req_reference(
|
||||||
|
&npm_req_ref,
|
||||||
|
NodeResolutionMode::Types,
|
||||||
|
&mut PermissionsContainer::allow_all(),
|
||||||
|
)
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|pkg_id_ref| {
|
.flatten(),
|
||||||
node_resolve_npm_reference(
|
|
||||||
&pkg_id_ref,
|
|
||||||
NodeResolutionMode::Types,
|
|
||||||
npm_resolver,
|
|
||||||
&mut PermissionsContainer::allow_all(),
|
|
||||||
)
|
|
||||||
.ok()
|
|
||||||
.flatten()
|
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@ use crate::file_fetcher::FileFetcher;
|
||||||
use crate::graph_util;
|
use crate::graph_util;
|
||||||
use crate::http_util::HttpClient;
|
use crate::http_util::HttpClient;
|
||||||
use crate::lsp::urls::LspUrlKind;
|
use crate::lsp::urls::LspUrlKind;
|
||||||
|
use crate::node::CliNodeResolver;
|
||||||
use crate::npm::create_npm_fs_resolver;
|
use crate::npm::create_npm_fs_resolver;
|
||||||
use crate::npm::CliNpmRegistryApi;
|
use crate::npm::CliNpmRegistryApi;
|
||||||
use crate::npm::NpmCache;
|
use crate::npm::NpmCache;
|
||||||
|
@ -101,6 +102,7 @@ pub struct StateSnapshot {
|
||||||
pub cache_metadata: cache::CacheMetadata,
|
pub cache_metadata: cache::CacheMetadata,
|
||||||
pub documents: Documents,
|
pub documents: Documents,
|
||||||
pub maybe_import_map: Option<Arc<ImportMap>>,
|
pub maybe_import_map: Option<Arc<ImportMap>>,
|
||||||
|
pub maybe_node_resolver: Option<Arc<CliNodeResolver>>,
|
||||||
pub maybe_npm_resolver: Option<Arc<NpmPackageResolver>>,
|
pub maybe_npm_resolver: Option<Arc<NpmPackageResolver>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,30 +697,32 @@ impl Inner {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn snapshot(&self) -> Arc<StateSnapshot> {
|
pub fn snapshot(&self) -> Arc<StateSnapshot> {
|
||||||
|
// create a new snapshotted npm resolution and resolver
|
||||||
|
let npm_resolution = Arc::new(NpmResolution::new(
|
||||||
|
self.npm_api.clone(),
|
||||||
|
self.npm_resolution.snapshot(),
|
||||||
|
None,
|
||||||
|
));
|
||||||
|
let npm_resolver = Arc::new(NpmPackageResolver::new(
|
||||||
|
npm_resolution.clone(),
|
||||||
|
create_npm_fs_resolver(
|
||||||
|
self.npm_cache.clone(),
|
||||||
|
&ProgressBar::new(ProgressBarStyle::TextOnly),
|
||||||
|
self.npm_api.base_url().clone(),
|
||||||
|
npm_resolution.clone(),
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
));
|
||||||
|
let node_resolver =
|
||||||
|
Arc::new(CliNodeResolver::new(npm_resolution, npm_resolver.clone()));
|
||||||
Arc::new(StateSnapshot {
|
Arc::new(StateSnapshot {
|
||||||
assets: self.assets.snapshot(),
|
assets: self.assets.snapshot(),
|
||||||
cache_metadata: self.cache_metadata.clone(),
|
cache_metadata: self.cache_metadata.clone(),
|
||||||
documents: self.documents.clone(),
|
documents: self.documents.clone(),
|
||||||
maybe_import_map: self.maybe_import_map.clone(),
|
maybe_import_map: self.maybe_import_map.clone(),
|
||||||
maybe_npm_resolver: Some({
|
maybe_node_resolver: Some(node_resolver),
|
||||||
// create a new snapshotted npm resolution and resolver
|
maybe_npm_resolver: Some(npm_resolver),
|
||||||
let resolution = Arc::new(NpmResolution::new(
|
|
||||||
self.npm_api.clone(),
|
|
||||||
self.npm_resolution.snapshot(),
|
|
||||||
None,
|
|
||||||
));
|
|
||||||
Arc::new(NpmPackageResolver::new(
|
|
||||||
resolution.clone(),
|
|
||||||
create_npm_fs_resolver(
|
|
||||||
self.npm_cache.clone(),
|
|
||||||
&ProgressBar::new(ProgressBarStyle::TextOnly),
|
|
||||||
self.npm_api.base_url().clone(),
|
|
||||||
resolution,
|
|
||||||
None,
|
|
||||||
),
|
|
||||||
None,
|
|
||||||
))
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2763,7 +2763,7 @@ fn op_resolve(
|
||||||
let resolved = state.state_snapshot.documents.resolve(
|
let resolved = state.state_snapshot.documents.resolve(
|
||||||
args.specifiers,
|
args.specifiers,
|
||||||
&referrer_doc,
|
&referrer_doc,
|
||||||
state.state_snapshot.maybe_npm_resolver.as_ref(),
|
state.state_snapshot.maybe_node_resolver.as_ref(),
|
||||||
);
|
);
|
||||||
Ok(
|
Ok(
|
||||||
resolved
|
resolved
|
||||||
|
|
|
@ -11,10 +11,9 @@ use crate::graph_util::graph_valid_with_cli_options;
|
||||||
use crate::graph_util::ModuleGraphBuilder;
|
use crate::graph_util::ModuleGraphBuilder;
|
||||||
use crate::graph_util::ModuleGraphContainer;
|
use crate::graph_util::ModuleGraphContainer;
|
||||||
use crate::node;
|
use crate::node;
|
||||||
|
use crate::node::CliNodeResolver;
|
||||||
use crate::node::NodeCodeTranslator;
|
use crate::node::NodeCodeTranslator;
|
||||||
use crate::node::NodeResolution;
|
use crate::node::NodeResolution;
|
||||||
use crate::npm::NpmPackageResolver;
|
|
||||||
use crate::npm::NpmResolution;
|
|
||||||
use crate::proc_state::CjsResolutionStore;
|
use crate::proc_state::CjsResolutionStore;
|
||||||
use crate::proc_state::FileWatcherReporter;
|
use crate::proc_state::FileWatcherReporter;
|
||||||
use crate::proc_state::ProcState;
|
use crate::proc_state::ProcState;
|
||||||
|
@ -243,8 +242,7 @@ pub struct CliModuleLoader {
|
||||||
graph_container: Arc<ModuleGraphContainer>,
|
graph_container: Arc<ModuleGraphContainer>,
|
||||||
module_load_preparer: Arc<ModuleLoadPreparer>,
|
module_load_preparer: Arc<ModuleLoadPreparer>,
|
||||||
node_code_translator: Arc<NodeCodeTranslator>,
|
node_code_translator: Arc<NodeCodeTranslator>,
|
||||||
npm_resolution: Arc<NpmResolution>,
|
node_resolver: Arc<CliNodeResolver>,
|
||||||
npm_resolver: Arc<NpmPackageResolver>,
|
|
||||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||||
resolver: Arc<CliGraphResolver>,
|
resolver: Arc<CliGraphResolver>,
|
||||||
}
|
}
|
||||||
|
@ -265,8 +263,7 @@ impl CliModuleLoader {
|
||||||
graph_container: ps.graph_container.clone(),
|
graph_container: ps.graph_container.clone(),
|
||||||
module_load_preparer: ps.module_load_preparer.clone(),
|
module_load_preparer: ps.module_load_preparer.clone(),
|
||||||
node_code_translator: ps.node_code_translator.clone(),
|
node_code_translator: ps.node_code_translator.clone(),
|
||||||
npm_resolution: ps.npm_resolution.clone(),
|
node_resolver: ps.node_resolver.clone(),
|
||||||
npm_resolver: ps.npm_resolver.clone(),
|
|
||||||
parsed_source_cache: ps.parsed_source_cache.clone(),
|
parsed_source_cache: ps.parsed_source_cache.clone(),
|
||||||
resolver: ps.resolver.clone(),
|
resolver: ps.resolver.clone(),
|
||||||
})
|
})
|
||||||
|
@ -287,8 +284,7 @@ impl CliModuleLoader {
|
||||||
graph_container: ps.graph_container.clone(),
|
graph_container: ps.graph_container.clone(),
|
||||||
module_load_preparer: ps.module_load_preparer.clone(),
|
module_load_preparer: ps.module_load_preparer.clone(),
|
||||||
node_code_translator: ps.node_code_translator.clone(),
|
node_code_translator: ps.node_code_translator.clone(),
|
||||||
npm_resolution: ps.npm_resolution.clone(),
|
node_resolver: ps.node_resolver.clone(),
|
||||||
npm_resolver: ps.npm_resolver.clone(),
|
|
||||||
parsed_source_cache: ps.parsed_source_cache.clone(),
|
parsed_source_cache: ps.parsed_source_cache.clone(),
|
||||||
resolver: ps.resolver.clone(),
|
resolver: ps.resolver.clone(),
|
||||||
})
|
})
|
||||||
|
@ -370,7 +366,7 @@ impl CliModuleLoader {
|
||||||
maybe_referrer: Option<&ModuleSpecifier>,
|
maybe_referrer: Option<&ModuleSpecifier>,
|
||||||
is_dynamic: bool,
|
is_dynamic: bool,
|
||||||
) -> Result<ModuleSource, AnyError> {
|
) -> Result<ModuleSource, AnyError> {
|
||||||
let code_source = if self.npm_resolver.in_npm_package(specifier) {
|
let code_source = if self.node_resolver.in_npm_package(specifier) {
|
||||||
let file_path = specifier.to_file_path().unwrap();
|
let file_path = specifier.to_file_path().unwrap();
|
||||||
let code = std::fs::read_to_string(&file_path).with_context(|| {
|
let code = std::fs::read_to_string(&file_path).with_context(|| {
|
||||||
let mut msg = "Unable to load ".to_string();
|
let mut msg = "Unable to load ".to_string();
|
||||||
|
@ -466,14 +462,13 @@ impl ModuleLoader for CliModuleLoader {
|
||||||
let referrer_result = deno_core::resolve_url_or_path(referrer, &cwd);
|
let referrer_result = deno_core::resolve_url_or_path(referrer, &cwd);
|
||||||
|
|
||||||
if let Ok(referrer) = referrer_result.as_ref() {
|
if let Ok(referrer) = referrer_result.as_ref() {
|
||||||
if self.npm_resolver.in_npm_package(referrer) {
|
if self.node_resolver.in_npm_package(referrer) {
|
||||||
// we're in an npm package, so use node resolution
|
// we're in an npm package, so use node resolution
|
||||||
return self
|
return self
|
||||||
.handle_node_resolve_result(node::node_resolve(
|
.handle_node_resolve_result(self.node_resolver.resolve(
|
||||||
specifier,
|
specifier,
|
||||||
referrer,
|
referrer,
|
||||||
NodeResolutionMode::Execution,
|
NodeResolutionMode::Execution,
|
||||||
&self.npm_resolver.as_require_npm_resolver(),
|
|
||||||
&mut permissions,
|
&mut permissions,
|
||||||
))
|
))
|
||||||
.with_context(|| {
|
.with_context(|| {
|
||||||
|
@ -495,12 +490,13 @@ impl ModuleLoader for CliModuleLoader {
|
||||||
|
|
||||||
return match graph.get(specifier) {
|
return match graph.get(specifier) {
|
||||||
Some(Module::Npm(module)) => self
|
Some(Module::Npm(module)) => self
|
||||||
.handle_node_resolve_result(node::node_resolve_npm_reference(
|
.handle_node_resolve_result(
|
||||||
&module.nv_reference,
|
self.node_resolver.resolve_npm_reference(
|
||||||
NodeResolutionMode::Execution,
|
&module.nv_reference,
|
||||||
&self.npm_resolver,
|
NodeResolutionMode::Execution,
|
||||||
&mut permissions,
|
&mut permissions,
|
||||||
))
|
),
|
||||||
|
)
|
||||||
.with_context(|| {
|
.with_context(|| {
|
||||||
format!("Could not resolve '{}'.", module.nv_reference)
|
format!("Could not resolve '{}'.", module.nv_reference)
|
||||||
}),
|
}),
|
||||||
|
@ -555,15 +551,14 @@ impl ModuleLoader for CliModuleLoader {
|
||||||
if let Ok(reference) =
|
if let Ok(reference) =
|
||||||
NpmPackageReqReference::from_specifier(&specifier)
|
NpmPackageReqReference::from_specifier(&specifier)
|
||||||
{
|
{
|
||||||
let reference =
|
|
||||||
self.npm_resolution.pkg_req_ref_to_nv_ref(reference)?;
|
|
||||||
return self
|
return self
|
||||||
.handle_node_resolve_result(node::node_resolve_npm_reference(
|
.handle_node_resolve_result(
|
||||||
&reference,
|
self.node_resolver.resolve_npm_req_reference(
|
||||||
deno_runtime::deno_node::NodeResolutionMode::Execution,
|
&reference,
|
||||||
&self.npm_resolver,
|
deno_runtime::deno_node::NodeResolutionMode::Execution,
|
||||||
&mut permissions,
|
&mut permissions,
|
||||||
))
|
),
|
||||||
|
)
|
||||||
.with_context(|| format!("Could not resolve '{reference}'."));
|
.with_context(|| format!("Could not resolve '{reference}'."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -595,7 +590,7 @@ impl ModuleLoader for CliModuleLoader {
|
||||||
_maybe_referrer: Option<String>,
|
_maybe_referrer: Option<String>,
|
||||||
is_dynamic: bool,
|
is_dynamic: bool,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<(), AnyError>>>> {
|
) -> Pin<Box<dyn Future<Output = Result<(), AnyError>>>> {
|
||||||
if self.npm_resolver.in_npm_package(specifier) {
|
if self.node_resolver.in_npm_package(specifier) {
|
||||||
// nothing to prepare
|
// nothing to prepare
|
||||||
return Box::pin(deno_core::futures::future::ready(Ok(())));
|
return Box::pin(deno_core::futures::future::ready(Ok(())));
|
||||||
}
|
}
|
||||||
|
|
553
cli/node/mod.rs
553
cli/node/mod.rs
|
@ -31,8 +31,11 @@ use deno_runtime::deno_node::DEFAULT_CONDITIONS;
|
||||||
use deno_runtime::permissions::PermissionsContainer;
|
use deno_runtime::permissions::PermissionsContainer;
|
||||||
use deno_semver::npm::NpmPackageNv;
|
use deno_semver::npm::NpmPackageNv;
|
||||||
use deno_semver::npm::NpmPackageNvReference;
|
use deno_semver::npm::NpmPackageNvReference;
|
||||||
|
use deno_semver::npm::NpmPackageReqReference;
|
||||||
|
|
||||||
use crate::npm::NpmPackageResolver;
|
use crate::npm::NpmPackageResolver;
|
||||||
|
use crate::npm::NpmResolution;
|
||||||
|
use crate::npm::RequireNpmPackageResolver;
|
||||||
use crate::util::fs::canonicalize_path_maybe_not_exists;
|
use crate::util::fs::canonicalize_path_maybe_not_exists;
|
||||||
|
|
||||||
mod analyze;
|
mod analyze;
|
||||||
|
@ -109,127 +112,305 @@ pub fn resolve_builtin_node_module(module_name: &str) -> Result<Url, AnyError> {
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function is an implementation of `defaultResolve` in
|
#[derive(Debug)]
|
||||||
/// `lib/internal/modules/esm/resolve.js` from Node.
|
pub struct CliNodeResolver {
|
||||||
pub fn node_resolve(
|
npm_resolution: Arc<NpmResolution>,
|
||||||
specifier: &str,
|
npm_resolver: Arc<NpmPackageResolver>,
|
||||||
referrer: &ModuleSpecifier,
|
require_npm_resolver: RequireNpmPackageResolver,
|
||||||
mode: NodeResolutionMode,
|
|
||||||
npm_resolver: &dyn RequireNpmResolver,
|
|
||||||
permissions: &mut dyn NodePermissions,
|
|
||||||
) -> Result<Option<NodeResolution>, AnyError> {
|
|
||||||
// Note: if we are here, then the referrer is an esm module
|
|
||||||
// TODO(bartlomieju): skipped "policy" part as we don't plan to support it
|
|
||||||
|
|
||||||
if deno_node::is_builtin_node_module(specifier) {
|
|
||||||
return Ok(Some(NodeResolution::BuiltIn(specifier.to_string())));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(url) = Url::parse(specifier) {
|
|
||||||
if url.scheme() == "data" {
|
|
||||||
return Ok(Some(NodeResolution::Esm(url)));
|
|
||||||
}
|
|
||||||
|
|
||||||
let protocol = url.scheme();
|
|
||||||
|
|
||||||
if protocol == "node" {
|
|
||||||
let split_specifier = url.as_str().split(':');
|
|
||||||
let specifier = split_specifier.skip(1).collect::<String>();
|
|
||||||
|
|
||||||
if deno_node::is_builtin_node_module(&specifier) {
|
|
||||||
return Ok(Some(NodeResolution::BuiltIn(specifier)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if protocol != "file" && protocol != "data" {
|
|
||||||
return Err(errors::err_unsupported_esm_url_scheme(&url));
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo(dsherret): this seems wrong
|
|
||||||
if referrer.scheme() == "data" {
|
|
||||||
let url = referrer.join(specifier).map_err(AnyError::from)?;
|
|
||||||
return Ok(Some(NodeResolution::Esm(url)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let url = module_resolve(
|
|
||||||
specifier,
|
|
||||||
referrer,
|
|
||||||
DEFAULT_CONDITIONS,
|
|
||||||
mode,
|
|
||||||
npm_resolver,
|
|
||||||
permissions,
|
|
||||||
)?;
|
|
||||||
let url = match url {
|
|
||||||
Some(url) => url,
|
|
||||||
None => return Ok(None),
|
|
||||||
};
|
|
||||||
let url = match mode {
|
|
||||||
NodeResolutionMode::Execution => url,
|
|
||||||
NodeResolutionMode::Types => {
|
|
||||||
let path = url.to_file_path().unwrap();
|
|
||||||
// todo(16370): the module kind is not correct here. I think we need
|
|
||||||
// typescript to tell us if the referrer is esm or cjs
|
|
||||||
let path =
|
|
||||||
match path_to_declaration_path::<RealFs>(path, NodeModuleKind::Esm) {
|
|
||||||
Some(path) => path,
|
|
||||||
None => return Ok(None),
|
|
||||||
};
|
|
||||||
ModuleSpecifier::from_file_path(path).unwrap()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let resolve_response = url_to_node_resolution(url, npm_resolver)?;
|
|
||||||
// TODO(bartlomieju): skipped checking errors for commonJS resolution and
|
|
||||||
// "preserveSymlinksMain"/"preserveSymlinks" options.
|
|
||||||
Ok(Some(resolve_response))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_resolve_npm_reference(
|
impl CliNodeResolver {
|
||||||
reference: &NpmPackageNvReference,
|
pub fn new(
|
||||||
mode: NodeResolutionMode,
|
npm_resolution: Arc<NpmResolution>,
|
||||||
npm_resolver: &Arc<NpmPackageResolver>,
|
npm_package_resolver: Arc<NpmPackageResolver>,
|
||||||
permissions: &mut dyn NodePermissions,
|
) -> Self {
|
||||||
) -> Result<Option<NodeResolution>, AnyError> {
|
Self {
|
||||||
let package_folder =
|
npm_resolution,
|
||||||
npm_resolver.resolve_package_folder_from_deno_module(&reference.nv)?;
|
require_npm_resolver: npm_package_resolver.as_require_npm_resolver(),
|
||||||
let node_module_kind = NodeModuleKind::Esm;
|
npm_resolver: npm_package_resolver,
|
||||||
let maybe_resolved_path = package_config_resolve(
|
}
|
||||||
&reference
|
}
|
||||||
.sub_path
|
|
||||||
.as_ref()
|
pub fn in_npm_package(&self, specifier: &ModuleSpecifier) -> bool {
|
||||||
.map(|s| format!("./{s}"))
|
self.npm_resolver.in_npm_package(specifier)
|
||||||
.unwrap_or_else(|| ".".to_string()),
|
}
|
||||||
&package_folder,
|
|
||||||
node_module_kind,
|
/// This function is an implementation of `defaultResolve` in
|
||||||
DEFAULT_CONDITIONS,
|
/// `lib/internal/modules/esm/resolve.js` from Node.
|
||||||
mode,
|
pub fn resolve(
|
||||||
&npm_resolver.as_require_npm_resolver(),
|
&self,
|
||||||
permissions,
|
specifier: &str,
|
||||||
)
|
referrer: &ModuleSpecifier,
|
||||||
.with_context(|| {
|
mode: NodeResolutionMode,
|
||||||
format!("Error resolving package config for '{reference}'")
|
permissions: &mut dyn NodePermissions,
|
||||||
})?;
|
) -> Result<Option<NodeResolution>, AnyError> {
|
||||||
let resolved_path = match maybe_resolved_path {
|
// Note: if we are here, then the referrer is an esm module
|
||||||
Some(resolved_path) => resolved_path,
|
// TODO(bartlomieju): skipped "policy" part as we don't plan to support it
|
||||||
None => return Ok(None),
|
|
||||||
};
|
if deno_node::is_builtin_node_module(specifier) {
|
||||||
let resolved_path = match mode {
|
return Ok(Some(NodeResolution::BuiltIn(specifier.to_string())));
|
||||||
NodeResolutionMode::Execution => resolved_path,
|
}
|
||||||
NodeResolutionMode::Types => {
|
|
||||||
match path_to_declaration_path::<RealFs>(resolved_path, node_module_kind)
|
if let Ok(url) = Url::parse(specifier) {
|
||||||
{
|
if url.scheme() == "data" {
|
||||||
Some(path) => path,
|
return Ok(Some(NodeResolution::Esm(url)));
|
||||||
None => return Ok(None),
|
}
|
||||||
|
|
||||||
|
let protocol = url.scheme();
|
||||||
|
|
||||||
|
if protocol == "node" {
|
||||||
|
let split_specifier = url.as_str().split(':');
|
||||||
|
let specifier = split_specifier.skip(1).collect::<String>();
|
||||||
|
|
||||||
|
if deno_node::is_builtin_node_module(&specifier) {
|
||||||
|
return Ok(Some(NodeResolution::BuiltIn(specifier)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if protocol != "file" && protocol != "data" {
|
||||||
|
return Err(errors::err_unsupported_esm_url_scheme(&url));
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo(dsherret): this seems wrong
|
||||||
|
if referrer.scheme() == "data" {
|
||||||
|
let url = referrer.join(specifier).map_err(AnyError::from)?;
|
||||||
|
return Ok(Some(NodeResolution::Esm(url)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
let url = ModuleSpecifier::from_file_path(resolved_path).unwrap();
|
let url = self.module_resolve(
|
||||||
let resolve_response =
|
specifier,
|
||||||
url_to_node_resolution(url, &npm_resolver.as_require_npm_resolver())?;
|
referrer,
|
||||||
// TODO(bartlomieju): skipped checking errors for commonJS resolution and
|
DEFAULT_CONDITIONS,
|
||||||
// "preserveSymlinksMain"/"preserveSymlinks" options.
|
mode,
|
||||||
Ok(Some(resolve_response))
|
permissions,
|
||||||
|
)?;
|
||||||
|
let url = match url {
|
||||||
|
Some(url) => url,
|
||||||
|
None => return Ok(None),
|
||||||
|
};
|
||||||
|
let url = match mode {
|
||||||
|
NodeResolutionMode::Execution => url,
|
||||||
|
NodeResolutionMode::Types => {
|
||||||
|
let path = url.to_file_path().unwrap();
|
||||||
|
// todo(16370): the module kind is not correct here. I think we need
|
||||||
|
// typescript to tell us if the referrer is esm or cjs
|
||||||
|
let path =
|
||||||
|
match path_to_declaration_path::<RealFs>(path, NodeModuleKind::Esm) {
|
||||||
|
Some(path) => path,
|
||||||
|
None => return Ok(None),
|
||||||
|
};
|
||||||
|
ModuleSpecifier::from_file_path(path).unwrap()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let resolve_response = self.url_to_node_resolution(url)?;
|
||||||
|
// TODO(bartlomieju): skipped checking errors for commonJS resolution and
|
||||||
|
// "preserveSymlinksMain"/"preserveSymlinks" options.
|
||||||
|
Ok(Some(resolve_response))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn module_resolve(
|
||||||
|
&self,
|
||||||
|
specifier: &str,
|
||||||
|
referrer: &ModuleSpecifier,
|
||||||
|
conditions: &[&str],
|
||||||
|
mode: NodeResolutionMode,
|
||||||
|
permissions: &mut dyn NodePermissions,
|
||||||
|
) -> Result<Option<ModuleSpecifier>, AnyError> {
|
||||||
|
// note: if we're here, the referrer is an esm module
|
||||||
|
let url = if should_be_treated_as_relative_or_absolute_path(specifier) {
|
||||||
|
let resolved_specifier = referrer.join(specifier)?;
|
||||||
|
if mode.is_types() {
|
||||||
|
let file_path = to_file_path(&resolved_specifier);
|
||||||
|
// todo(dsherret): the node module kind is not correct and we
|
||||||
|
// should use the value provided by typescript instead
|
||||||
|
let declaration_path =
|
||||||
|
path_to_declaration_path::<RealFs>(file_path, NodeModuleKind::Esm);
|
||||||
|
declaration_path.map(|declaration_path| {
|
||||||
|
ModuleSpecifier::from_file_path(declaration_path).unwrap()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Some(resolved_specifier)
|
||||||
|
}
|
||||||
|
} else if specifier.starts_with('#') {
|
||||||
|
Some(
|
||||||
|
package_imports_resolve::<RealFs>(
|
||||||
|
specifier,
|
||||||
|
referrer,
|
||||||
|
NodeModuleKind::Esm,
|
||||||
|
conditions,
|
||||||
|
mode,
|
||||||
|
&self.require_npm_resolver,
|
||||||
|
permissions,
|
||||||
|
)
|
||||||
|
.map(|p| ModuleSpecifier::from_file_path(p).unwrap())?,
|
||||||
|
)
|
||||||
|
} else if let Ok(resolved) = Url::parse(specifier) {
|
||||||
|
Some(resolved)
|
||||||
|
} else {
|
||||||
|
package_resolve::<RealFs>(
|
||||||
|
specifier,
|
||||||
|
referrer,
|
||||||
|
NodeModuleKind::Esm,
|
||||||
|
conditions,
|
||||||
|
mode,
|
||||||
|
&self.require_npm_resolver,
|
||||||
|
permissions,
|
||||||
|
)?
|
||||||
|
.map(|p| ModuleSpecifier::from_file_path(p).unwrap())
|
||||||
|
};
|
||||||
|
Ok(match url {
|
||||||
|
Some(url) => Some(finalize_resolution(url, referrer)?),
|
||||||
|
None => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolve_npm_req_reference(
|
||||||
|
&self,
|
||||||
|
reference: &NpmPackageReqReference,
|
||||||
|
mode: NodeResolutionMode,
|
||||||
|
permissions: &mut dyn NodePermissions,
|
||||||
|
) -> Result<Option<NodeResolution>, AnyError> {
|
||||||
|
let reference = self.npm_resolution.pkg_req_ref_to_nv_ref(reference)?;
|
||||||
|
self.resolve_npm_reference(&reference, mode, permissions)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolve_npm_reference(
|
||||||
|
&self,
|
||||||
|
reference: &NpmPackageNvReference,
|
||||||
|
mode: NodeResolutionMode,
|
||||||
|
permissions: &mut dyn NodePermissions,
|
||||||
|
) -> Result<Option<NodeResolution>, AnyError> {
|
||||||
|
let package_folder = self
|
||||||
|
.npm_resolver
|
||||||
|
.resolve_package_folder_from_deno_module(&reference.nv)?;
|
||||||
|
let node_module_kind = NodeModuleKind::Esm;
|
||||||
|
let maybe_resolved_path = package_config_resolve(
|
||||||
|
&reference
|
||||||
|
.sub_path
|
||||||
|
.as_ref()
|
||||||
|
.map(|s| format!("./{s}"))
|
||||||
|
.unwrap_or_else(|| ".".to_string()),
|
||||||
|
&package_folder,
|
||||||
|
node_module_kind,
|
||||||
|
DEFAULT_CONDITIONS,
|
||||||
|
mode,
|
||||||
|
&self.require_npm_resolver,
|
||||||
|
permissions,
|
||||||
|
)
|
||||||
|
.with_context(|| {
|
||||||
|
format!("Error resolving package config for '{reference}'")
|
||||||
|
})?;
|
||||||
|
let resolved_path = match maybe_resolved_path {
|
||||||
|
Some(resolved_path) => resolved_path,
|
||||||
|
None => return Ok(None),
|
||||||
|
};
|
||||||
|
let resolved_path = match mode {
|
||||||
|
NodeResolutionMode::Execution => resolved_path,
|
||||||
|
NodeResolutionMode::Types => {
|
||||||
|
match path_to_declaration_path::<RealFs>(
|
||||||
|
resolved_path,
|
||||||
|
node_module_kind,
|
||||||
|
) {
|
||||||
|
Some(path) => path,
|
||||||
|
None => return Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let url = ModuleSpecifier::from_file_path(resolved_path).unwrap();
|
||||||
|
let resolve_response = self.url_to_node_resolution(url)?;
|
||||||
|
// TODO(bartlomieju): skipped checking errors for commonJS resolution and
|
||||||
|
// "preserveSymlinksMain"/"preserveSymlinks" options.
|
||||||
|
Ok(Some(resolve_response))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolve_binary_commands(
|
||||||
|
&self,
|
||||||
|
pkg_nv: &NpmPackageNv,
|
||||||
|
) -> Result<Vec<String>, AnyError> {
|
||||||
|
let package_folder = self
|
||||||
|
.npm_resolver
|
||||||
|
.resolve_package_folder_from_deno_module(pkg_nv)?;
|
||||||
|
let package_json_path = package_folder.join("package.json");
|
||||||
|
let package_json = PackageJson::load::<RealFs>(
|
||||||
|
&self.require_npm_resolver,
|
||||||
|
&mut PermissionsContainer::allow_all(),
|
||||||
|
package_json_path,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(match package_json.bin {
|
||||||
|
Some(Value::String(_)) => vec![pkg_nv.name.to_string()],
|
||||||
|
Some(Value::Object(o)) => {
|
||||||
|
o.into_iter().map(|(key, _)| key).collect::<Vec<_>>()
|
||||||
|
}
|
||||||
|
_ => Vec::new(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolve_binary_export(
|
||||||
|
&self,
|
||||||
|
pkg_ref: &NpmPackageReqReference,
|
||||||
|
) -> Result<NodeResolution, AnyError> {
|
||||||
|
let pkg_nv = self
|
||||||
|
.npm_resolution
|
||||||
|
.resolve_pkg_id_from_pkg_req(&pkg_ref.req)?
|
||||||
|
.nv;
|
||||||
|
let bin_name = pkg_ref.sub_path.as_deref();
|
||||||
|
let package_folder = self
|
||||||
|
.npm_resolver
|
||||||
|
.resolve_package_folder_from_deno_module(&pkg_nv)?;
|
||||||
|
let package_json_path = package_folder.join("package.json");
|
||||||
|
let package_json = PackageJson::load::<RealFs>(
|
||||||
|
&self.require_npm_resolver,
|
||||||
|
&mut PermissionsContainer::allow_all(),
|
||||||
|
package_json_path,
|
||||||
|
)?;
|
||||||
|
let bin = match &package_json.bin {
|
||||||
|
Some(bin) => bin,
|
||||||
|
None => bail!(
|
||||||
|
"package '{}' did not have a bin property in its package.json",
|
||||||
|
&pkg_nv.name,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
let bin_entry = resolve_bin_entry_value(&pkg_nv, bin_name, bin)?;
|
||||||
|
let url =
|
||||||
|
ModuleSpecifier::from_file_path(package_folder.join(bin_entry)).unwrap();
|
||||||
|
|
||||||
|
let resolve_response = self.url_to_node_resolution(url)?;
|
||||||
|
// TODO(bartlomieju): skipped checking errors for commonJS resolution and
|
||||||
|
// "preserveSymlinksMain"/"preserveSymlinks" options.
|
||||||
|
Ok(resolve_response)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn url_to_node_resolution(
|
||||||
|
&self,
|
||||||
|
url: ModuleSpecifier,
|
||||||
|
) -> Result<NodeResolution, AnyError> {
|
||||||
|
let url_str = url.as_str().to_lowercase();
|
||||||
|
if url_str.starts_with("http") {
|
||||||
|
Ok(NodeResolution::Esm(url))
|
||||||
|
} else if url_str.ends_with(".js") || url_str.ends_with(".d.ts") {
|
||||||
|
let package_config = get_closest_package_json::<RealFs>(
|
||||||
|
&url,
|
||||||
|
&self.require_npm_resolver,
|
||||||
|
&mut PermissionsContainer::allow_all(),
|
||||||
|
)?;
|
||||||
|
if package_config.typ == "module" {
|
||||||
|
Ok(NodeResolution::Esm(url))
|
||||||
|
} else {
|
||||||
|
Ok(NodeResolution::CommonJs(url))
|
||||||
|
}
|
||||||
|
} else if url_str.ends_with(".mjs") || url_str.ends_with(".d.mts") {
|
||||||
|
Ok(NodeResolution::Esm(url))
|
||||||
|
} else if url_str.ends_with(".ts") {
|
||||||
|
Err(generic_error(format!(
|
||||||
|
"TypeScript files are not supported in npm packages: {url}"
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
Ok(NodeResolution::CommonJs(url))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolves a specifier that is pointing into a node_modules folder.
|
/// Resolves a specifier that is pointing into a node_modules folder.
|
||||||
|
@ -251,59 +432,6 @@ pub fn resolve_specifier_into_node_modules(
|
||||||
.unwrap_or_else(|| specifier.clone())
|
.unwrap_or_else(|| specifier.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_resolve_binary_commands(
|
|
||||||
pkg_nv: &NpmPackageNv,
|
|
||||||
npm_resolver: &Arc<NpmPackageResolver>,
|
|
||||||
) -> Result<Vec<String>, AnyError> {
|
|
||||||
let package_folder =
|
|
||||||
npm_resolver.resolve_package_folder_from_deno_module(pkg_nv)?;
|
|
||||||
let package_json_path = package_folder.join("package.json");
|
|
||||||
let package_json = PackageJson::load::<RealFs>(
|
|
||||||
&npm_resolver.as_require_npm_resolver(),
|
|
||||||
&mut PermissionsContainer::allow_all(),
|
|
||||||
package_json_path,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(match package_json.bin {
|
|
||||||
Some(Value::String(_)) => vec![pkg_nv.name.to_string()],
|
|
||||||
Some(Value::Object(o)) => {
|
|
||||||
o.into_iter().map(|(key, _)| key).collect::<Vec<_>>()
|
|
||||||
}
|
|
||||||
_ => Vec::new(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn node_resolve_binary_export(
|
|
||||||
pkg_nv: &NpmPackageNv,
|
|
||||||
bin_name: Option<&str>,
|
|
||||||
npm_resolver: &Arc<NpmPackageResolver>,
|
|
||||||
) -> Result<NodeResolution, AnyError> {
|
|
||||||
let package_folder =
|
|
||||||
npm_resolver.resolve_package_folder_from_deno_module(pkg_nv)?;
|
|
||||||
let package_json_path = package_folder.join("package.json");
|
|
||||||
let package_json = PackageJson::load::<RealFs>(
|
|
||||||
&npm_resolver.as_require_npm_resolver(),
|
|
||||||
&mut PermissionsContainer::allow_all(),
|
|
||||||
package_json_path,
|
|
||||||
)?;
|
|
||||||
let bin = match &package_json.bin {
|
|
||||||
Some(bin) => bin,
|
|
||||||
None => bail!(
|
|
||||||
"package '{}' did not have a bin property in its package.json",
|
|
||||||
&pkg_nv.name,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
let bin_entry = resolve_bin_entry_value(pkg_nv, bin_name, bin)?;
|
|
||||||
let url =
|
|
||||||
ModuleSpecifier::from_file_path(package_folder.join(bin_entry)).unwrap();
|
|
||||||
|
|
||||||
let resolve_response =
|
|
||||||
url_to_node_resolution(url, &npm_resolver.as_require_npm_resolver())?;
|
|
||||||
// TODO(bartlomieju): skipped checking errors for commonJS resolution and
|
|
||||||
// "preserveSymlinksMain"/"preserveSymlinks" options.
|
|
||||||
Ok(resolve_response)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_bin_entry_value<'a>(
|
fn resolve_bin_entry_value<'a>(
|
||||||
pkg_nv: &NpmPackageNv,
|
pkg_nv: &NpmPackageNv,
|
||||||
bin_name: Option<&str>,
|
bin_name: Option<&str>,
|
||||||
|
@ -411,35 +539,6 @@ fn package_config_resolve(
|
||||||
Ok(Some(package_dir.join(package_subpath)))
|
Ok(Some(package_dir.join(package_subpath)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn url_to_node_resolution(
|
|
||||||
url: ModuleSpecifier,
|
|
||||||
npm_resolver: &dyn RequireNpmResolver,
|
|
||||||
) -> Result<NodeResolution, AnyError> {
|
|
||||||
let url_str = url.as_str().to_lowercase();
|
|
||||||
if url_str.starts_with("http") {
|
|
||||||
Ok(NodeResolution::Esm(url))
|
|
||||||
} else if url_str.ends_with(".js") || url_str.ends_with(".d.ts") {
|
|
||||||
let package_config = get_closest_package_json::<RealFs>(
|
|
||||||
&url,
|
|
||||||
npm_resolver,
|
|
||||||
&mut PermissionsContainer::allow_all(),
|
|
||||||
)?;
|
|
||||||
if package_config.typ == "module" {
|
|
||||||
Ok(NodeResolution::Esm(url))
|
|
||||||
} else {
|
|
||||||
Ok(NodeResolution::CommonJs(url))
|
|
||||||
}
|
|
||||||
} else if url_str.ends_with(".mjs") || url_str.ends_with(".d.mts") {
|
|
||||||
Ok(NodeResolution::Esm(url))
|
|
||||||
} else if url_str.ends_with(".ts") {
|
|
||||||
Err(generic_error(format!(
|
|
||||||
"TypeScript files are not supported in npm packages: {url}"
|
|
||||||
)))
|
|
||||||
} else {
|
|
||||||
Ok(NodeResolution::CommonJs(url))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn finalize_resolution(
|
fn finalize_resolution(
|
||||||
resolved: ModuleSpecifier,
|
resolved: ModuleSpecifier,
|
||||||
base: &ModuleSpecifier,
|
base: &ModuleSpecifier,
|
||||||
|
@ -489,62 +588,6 @@ fn finalize_resolution(
|
||||||
Ok(resolved)
|
Ok(resolved)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn module_resolve(
|
|
||||||
specifier: &str,
|
|
||||||
referrer: &ModuleSpecifier,
|
|
||||||
conditions: &[&str],
|
|
||||||
mode: NodeResolutionMode,
|
|
||||||
npm_resolver: &dyn RequireNpmResolver,
|
|
||||||
permissions: &mut dyn NodePermissions,
|
|
||||||
) -> Result<Option<ModuleSpecifier>, AnyError> {
|
|
||||||
// note: if we're here, the referrer is an esm module
|
|
||||||
let url = if should_be_treated_as_relative_or_absolute_path(specifier) {
|
|
||||||
let resolved_specifier = referrer.join(specifier)?;
|
|
||||||
if mode.is_types() {
|
|
||||||
let file_path = to_file_path(&resolved_specifier);
|
|
||||||
// todo(dsherret): the node module kind is not correct and we
|
|
||||||
// should use the value provided by typescript instead
|
|
||||||
let declaration_path =
|
|
||||||
path_to_declaration_path::<RealFs>(file_path, NodeModuleKind::Esm);
|
|
||||||
declaration_path.map(|declaration_path| {
|
|
||||||
ModuleSpecifier::from_file_path(declaration_path).unwrap()
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Some(resolved_specifier)
|
|
||||||
}
|
|
||||||
} else if specifier.starts_with('#') {
|
|
||||||
Some(
|
|
||||||
package_imports_resolve::<RealFs>(
|
|
||||||
specifier,
|
|
||||||
referrer,
|
|
||||||
NodeModuleKind::Esm,
|
|
||||||
conditions,
|
|
||||||
mode,
|
|
||||||
npm_resolver,
|
|
||||||
permissions,
|
|
||||||
)
|
|
||||||
.map(|p| ModuleSpecifier::from_file_path(p).unwrap())?,
|
|
||||||
)
|
|
||||||
} else if let Ok(resolved) = Url::parse(specifier) {
|
|
||||||
Some(resolved)
|
|
||||||
} else {
|
|
||||||
package_resolve::<RealFs>(
|
|
||||||
specifier,
|
|
||||||
referrer,
|
|
||||||
NodeModuleKind::Esm,
|
|
||||||
conditions,
|
|
||||||
mode,
|
|
||||||
npm_resolver,
|
|
||||||
permissions,
|
|
||||||
)?
|
|
||||||
.map(|p| ModuleSpecifier::from_file_path(p).unwrap())
|
|
||||||
};
|
|
||||||
Ok(match url {
|
|
||||||
Some(url) => Some(finalize_resolution(url, referrer)?),
|
|
||||||
None => None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_file_path(url: &ModuleSpecifier) -> PathBuf {
|
fn to_file_path(url: &ModuleSpecifier) -> PathBuf {
|
||||||
url
|
url
|
||||||
.to_file_path()
|
.to_file_path()
|
||||||
|
|
|
@ -15,3 +15,4 @@ pub use resolution::NpmResolution;
|
||||||
pub use resolvers::create_npm_fs_resolver;
|
pub use resolvers::create_npm_fs_resolver;
|
||||||
pub use resolvers::NpmPackageResolver;
|
pub use resolvers::NpmPackageResolver;
|
||||||
pub use resolvers::NpmProcessState;
|
pub use resolvers::NpmProcessState;
|
||||||
|
pub use resolvers::RequireNpmPackageResolver;
|
||||||
|
|
|
@ -156,12 +156,12 @@ impl NpmResolution {
|
||||||
|
|
||||||
pub fn pkg_req_ref_to_nv_ref(
|
pub fn pkg_req_ref_to_nv_ref(
|
||||||
&self,
|
&self,
|
||||||
req_ref: NpmPackageReqReference,
|
req_ref: &NpmPackageReqReference,
|
||||||
) -> Result<NpmPackageNvReference, PackageReqNotFoundError> {
|
) -> Result<NpmPackageNvReference, PackageReqNotFoundError> {
|
||||||
let node_id = self.resolve_pkg_id_from_pkg_req(&req_ref.req)?;
|
let node_id = self.resolve_pkg_id_from_pkg_req(&req_ref.req)?;
|
||||||
Ok(NpmPackageNvReference {
|
Ok(NpmPackageNvReference {
|
||||||
nv: node_id.nv,
|
nv: node_id.nv,
|
||||||
sub_path: req_ref.sub_path,
|
sub_path: req_ref.sub_path.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,7 @@ use deno_runtime::deno_node::NodeResolutionMode;
|
||||||
use deno_runtime::deno_node::PathClean;
|
use deno_runtime::deno_node::PathClean;
|
||||||
use deno_runtime::deno_node::RequireNpmResolver;
|
use deno_runtime::deno_node::RequireNpmResolver;
|
||||||
use deno_semver::npm::NpmPackageNv;
|
use deno_semver::npm::NpmPackageNv;
|
||||||
use deno_semver::npm::NpmPackageNvReference;
|
|
||||||
use deno_semver::npm::NpmPackageReq;
|
use deno_semver::npm::NpmPackageReq;
|
||||||
use deno_semver::npm::NpmPackageReqReference;
|
|
||||||
use global::GlobalNpmPackageResolver;
|
use global::GlobalNpmPackageResolver;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
@ -87,13 +85,6 @@ impl NpmPackageResolver {
|
||||||
self.resolution.resolve_pkg_id_from_pkg_req(req)
|
self.resolution.resolve_pkg_id_from_pkg_req(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pkg_req_ref_to_nv_ref(
|
|
||||||
&self,
|
|
||||||
req_ref: NpmPackageReqReference,
|
|
||||||
) -> Result<NpmPackageNvReference, PackageReqNotFoundError> {
|
|
||||||
self.resolution.pkg_req_ref_to_nv_ref(req_ref)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resolves an npm package folder path from a Deno module.
|
/// Resolves an npm package folder path from a Deno module.
|
||||||
pub fn resolve_package_folder_from_deno_module(
|
pub fn resolve_package_folder_from_deno_module(
|
||||||
&self,
|
&self,
|
||||||
|
@ -245,6 +236,7 @@ impl NpmPackageResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct RequireNpmPackageResolver(Arc<NpmPackageResolver>);
|
pub struct RequireNpmPackageResolver(Arc<NpmPackageResolver>);
|
||||||
|
|
||||||
impl RequireNpmResolver for RequireNpmPackageResolver {
|
impl RequireNpmResolver for RequireNpmPackageResolver {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use crate::proc_state::ProcState;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::npm::NpmPackageResolver;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::op;
|
use deno_core::op;
|
||||||
use deno_core::Extension;
|
use deno_core::Extension;
|
||||||
|
@ -9,17 +11,17 @@ use deno_core::OpState;
|
||||||
pub mod bench;
|
pub mod bench;
|
||||||
pub mod testing;
|
pub mod testing;
|
||||||
|
|
||||||
pub fn cli_exts(ps: ProcState) -> Vec<Extension> {
|
pub fn cli_exts(npm_resolver: Arc<NpmPackageResolver>) -> Vec<Extension> {
|
||||||
vec![deno_cli::init_ops(ps)]
|
vec![deno_cli::init_ops(npm_resolver)]
|
||||||
}
|
}
|
||||||
|
|
||||||
deno_core::extension!(deno_cli,
|
deno_core::extension!(deno_cli,
|
||||||
ops = [op_npm_process_state],
|
ops = [op_npm_process_state],
|
||||||
options = {
|
options = {
|
||||||
ps: ProcState,
|
npm_resolver: Arc<NpmPackageResolver>,
|
||||||
},
|
},
|
||||||
state = |state, options| {
|
state = |state, options| {
|
||||||
state.put(options.ps);
|
state.put(options.npm_resolver);
|
||||||
},
|
},
|
||||||
customizer = |ext: &mut deno_core::ExtensionBuilder| {
|
customizer = |ext: &mut deno_core::ExtensionBuilder| {
|
||||||
ext.force_op_registration();
|
ext.force_op_registration();
|
||||||
|
@ -28,6 +30,6 @@ deno_core::extension!(deno_cli,
|
||||||
|
|
||||||
#[op]
|
#[op]
|
||||||
fn op_npm_process_state(state: &mut OpState) -> Result<String, AnyError> {
|
fn op_npm_process_state(state: &mut OpState) -> Result<String, AnyError> {
|
||||||
let proc_state = state.borrow_mut::<ProcState>();
|
let npm_resolver = state.borrow_mut::<Arc<NpmPackageResolver>>();
|
||||||
Ok(proc_state.npm_resolver.get_npm_process_state())
|
Ok(npm_resolver.get_npm_process_state())
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ use crate::graph_util::ModuleGraphBuilder;
|
||||||
use crate::graph_util::ModuleGraphContainer;
|
use crate::graph_util::ModuleGraphContainer;
|
||||||
use crate::http_util::HttpClient;
|
use crate::http_util::HttpClient;
|
||||||
use crate::module_loader::ModuleLoadPreparer;
|
use crate::module_loader::ModuleLoadPreparer;
|
||||||
|
use crate::node::CliNodeResolver;
|
||||||
use crate::node::NodeCodeTranslator;
|
use crate::node::NodeCodeTranslator;
|
||||||
use crate::npm::create_npm_fs_resolver;
|
use crate::npm::create_npm_fs_resolver;
|
||||||
use crate::npm::CliNpmRegistryApi;
|
use crate::npm::CliNpmRegistryApi;
|
||||||
|
@ -75,6 +76,7 @@ pub struct Inner {
|
||||||
pub module_graph_builder: Arc<ModuleGraphBuilder>,
|
pub module_graph_builder: Arc<ModuleGraphBuilder>,
|
||||||
pub module_load_preparer: Arc<ModuleLoadPreparer>,
|
pub module_load_preparer: Arc<ModuleLoadPreparer>,
|
||||||
pub node_code_translator: Arc<NodeCodeTranslator>,
|
pub node_code_translator: Arc<NodeCodeTranslator>,
|
||||||
|
pub node_resolver: Arc<CliNodeResolver>,
|
||||||
pub npm_api: Arc<CliNpmRegistryApi>,
|
pub npm_api: Arc<CliNpmRegistryApi>,
|
||||||
pub npm_cache: Arc<NpmCache>,
|
pub npm_cache: Arc<NpmCache>,
|
||||||
pub npm_resolver: Arc<NpmPackageResolver>,
|
pub npm_resolver: Arc<NpmPackageResolver>,
|
||||||
|
@ -145,6 +147,7 @@ impl ProcState {
|
||||||
module_graph_builder: self.module_graph_builder.clone(),
|
module_graph_builder: self.module_graph_builder.clone(),
|
||||||
module_load_preparer: self.module_load_preparer.clone(),
|
module_load_preparer: self.module_load_preparer.clone(),
|
||||||
node_code_translator: self.node_code_translator.clone(),
|
node_code_translator: self.node_code_translator.clone(),
|
||||||
|
node_resolver: self.node_resolver.clone(),
|
||||||
npm_api: self.npm_api.clone(),
|
npm_api: self.npm_api.clone(),
|
||||||
npm_cache: self.npm_cache.clone(),
|
npm_cache: self.npm_cache.clone(),
|
||||||
npm_resolver: self.npm_resolver.clone(),
|
npm_resolver: self.npm_resolver.clone(),
|
||||||
|
@ -306,10 +309,15 @@ impl ProcState {
|
||||||
file_fetcher.clone(),
|
file_fetcher.clone(),
|
||||||
npm_resolver.clone(),
|
npm_resolver.clone(),
|
||||||
));
|
));
|
||||||
|
let node_resolver = Arc::new(CliNodeResolver::new(
|
||||||
|
npm_resolution.clone(),
|
||||||
|
npm_resolver.clone(),
|
||||||
|
));
|
||||||
let type_checker = Arc::new(TypeChecker::new(
|
let type_checker = Arc::new(TypeChecker::new(
|
||||||
dir.clone(),
|
dir.clone(),
|
||||||
caches.clone(),
|
caches.clone(),
|
||||||
cli_options.clone(),
|
cli_options.clone(),
|
||||||
|
node_resolver.clone(),
|
||||||
npm_resolver.clone(),
|
npm_resolver.clone(),
|
||||||
));
|
));
|
||||||
let module_graph_builder = Arc::new(ModuleGraphBuilder::new(
|
let module_graph_builder = Arc::new(ModuleGraphBuilder::new(
|
||||||
|
@ -357,6 +365,7 @@ impl ProcState {
|
||||||
maybe_file_watcher_reporter,
|
maybe_file_watcher_reporter,
|
||||||
module_graph_builder,
|
module_graph_builder,
|
||||||
node_code_translator,
|
node_code_translator,
|
||||||
|
node_resolver,
|
||||||
npm_api,
|
npm_api,
|
||||||
npm_cache,
|
npm_cache,
|
||||||
npm_resolver,
|
npm_resolver,
|
||||||
|
|
|
@ -265,7 +265,7 @@ fn create_web_worker_callback(
|
||||||
user_agent: version::get_user_agent().to_string(),
|
user_agent: version::get_user_agent().to_string(),
|
||||||
inspect: ps.options.is_inspecting(),
|
inspect: ps.options.is_inspecting(),
|
||||||
},
|
},
|
||||||
extensions: ops::cli_exts(ps.clone()),
|
extensions: ops::cli_exts(ps.npm_resolver.clone()),
|
||||||
startup_snapshot: Some(crate::js::deno_isolate_init()),
|
startup_snapshot: Some(crate::js::deno_isolate_init()),
|
||||||
unsafely_ignore_certificate_errors: ps
|
unsafely_ignore_certificate_errors: ps
|
||||||
.options
|
.options
|
||||||
|
@ -354,7 +354,7 @@ pub async fn run(
|
||||||
user_agent: version::get_user_agent().to_string(),
|
user_agent: version::get_user_agent().to_string(),
|
||||||
inspect: ps.options.is_inspecting(),
|
inspect: ps.options.is_inspecting(),
|
||||||
},
|
},
|
||||||
extensions: ops::cli_exts(ps.clone()),
|
extensions: ops::cli_exts(ps.npm_resolver.clone()),
|
||||||
startup_snapshot: Some(crate::js::deno_isolate_init()),
|
startup_snapshot: Some(crate::js::deno_isolate_init()),
|
||||||
unsafely_ignore_certificate_errors: metadata
|
unsafely_ignore_certificate_errors: metadata
|
||||||
.unsafely_ignore_certificate_errors,
|
.unsafely_ignore_certificate_errors,
|
||||||
|
|
|
@ -21,6 +21,7 @@ use crate::cache::Caches;
|
||||||
use crate::cache::DenoDir;
|
use crate::cache::DenoDir;
|
||||||
use crate::cache::FastInsecureHasher;
|
use crate::cache::FastInsecureHasher;
|
||||||
use crate::cache::TypeCheckCache;
|
use crate::cache::TypeCheckCache;
|
||||||
|
use crate::node::CliNodeResolver;
|
||||||
use crate::npm::NpmPackageResolver;
|
use crate::npm::NpmPackageResolver;
|
||||||
use crate::tsc;
|
use crate::tsc;
|
||||||
use crate::version;
|
use crate::version;
|
||||||
|
@ -41,6 +42,7 @@ pub struct TypeChecker {
|
||||||
deno_dir: DenoDir,
|
deno_dir: DenoDir,
|
||||||
caches: Arc<Caches>,
|
caches: Arc<Caches>,
|
||||||
cli_options: Arc<CliOptions>,
|
cli_options: Arc<CliOptions>,
|
||||||
|
node_resolver: Arc<CliNodeResolver>,
|
||||||
npm_resolver: Arc<NpmPackageResolver>,
|
npm_resolver: Arc<NpmPackageResolver>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,12 +51,14 @@ impl TypeChecker {
|
||||||
deno_dir: DenoDir,
|
deno_dir: DenoDir,
|
||||||
caches: Arc<Caches>,
|
caches: Arc<Caches>,
|
||||||
cli_options: Arc<CliOptions>,
|
cli_options: Arc<CliOptions>,
|
||||||
|
node_resolver: Arc<CliNodeResolver>,
|
||||||
npm_resolver: Arc<NpmPackageResolver>,
|
npm_resolver: Arc<NpmPackageResolver>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
deno_dir,
|
deno_dir,
|
||||||
caches,
|
caches,
|
||||||
cli_options,
|
cli_options,
|
||||||
|
node_resolver,
|
||||||
npm_resolver,
|
npm_resolver,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,7 +137,7 @@ impl TypeChecker {
|
||||||
debug,
|
debug,
|
||||||
graph: graph.clone(),
|
graph: graph.clone(),
|
||||||
hash_data,
|
hash_data,
|
||||||
maybe_npm_resolver: Some(self.npm_resolver.clone()),
|
maybe_node_resolver: Some(self.node_resolver.clone()),
|
||||||
maybe_tsbuildinfo,
|
maybe_tsbuildinfo,
|
||||||
root_names,
|
root_names,
|
||||||
check_mode: type_check_mode,
|
check_mode: type_check_mode,
|
||||||
|
@ -144,7 +148,7 @@ impl TypeChecker {
|
||||||
if let Some(file_name) = &d.file_name {
|
if let Some(file_name) = &d.file_name {
|
||||||
if !file_name.starts_with("http") {
|
if !file_name.starts_with("http") {
|
||||||
if ModuleSpecifier::parse(file_name)
|
if ModuleSpecifier::parse(file_name)
|
||||||
.map(|specifier| !self.npm_resolver.in_npm_package(&specifier))
|
.map(|specifier| !self.node_resolver.in_npm_package(&specifier))
|
||||||
.unwrap_or(true)
|
.unwrap_or(true)
|
||||||
{
|
{
|
||||||
Some(d.clone())
|
Some(d.clone())
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use crate::args::CliOptions;
|
||||||
use crate::args::Flags;
|
use crate::args::Flags;
|
||||||
use crate::args::TaskFlags;
|
use crate::args::TaskFlags;
|
||||||
use crate::colors;
|
use crate::colors;
|
||||||
|
use crate::node::CliNodeResolver;
|
||||||
|
use crate::npm::NpmPackageResolver;
|
||||||
use crate::proc_state::ProcState;
|
use crate::proc_state::ProcState;
|
||||||
use crate::util::fs::canonicalize_path;
|
use crate::util::fs::canonicalize_path;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
|
@ -50,7 +53,7 @@ pub async fn execute_script(
|
||||||
Some(path) => canonicalize_path(&PathBuf::from(path))?,
|
Some(path) => canonicalize_path(&PathBuf::from(path))?,
|
||||||
None => config_file_path.parent().unwrap().to_owned(),
|
None => config_file_path.parent().unwrap().to_owned(),
|
||||||
};
|
};
|
||||||
let script = get_script_with_args(script, &ps);
|
let script = get_script_with_args(script, &ps.options);
|
||||||
output_task(task_name, &script);
|
output_task(task_name, &script);
|
||||||
let seq_list = deno_task_shell::parser::parse(&script)
|
let seq_list = deno_task_shell::parser::parse(&script)
|
||||||
.with_context(|| format!("Error parsing script '{task_name}'."))?;
|
.with_context(|| format!("Error parsing script '{task_name}'."))?;
|
||||||
|
@ -92,11 +95,12 @@ pub async fn execute_script(
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_owned(),
|
.to_owned(),
|
||||||
};
|
};
|
||||||
let script = get_script_with_args(script, &ps);
|
let script = get_script_with_args(script, &ps.options);
|
||||||
output_task(task_name, &script);
|
output_task(task_name, &script);
|
||||||
let seq_list = deno_task_shell::parser::parse(&script)
|
let seq_list = deno_task_shell::parser::parse(&script)
|
||||||
.with_context(|| format!("Error parsing script '{task_name}'."))?;
|
.with_context(|| format!("Error parsing script '{task_name}'."))?;
|
||||||
let npx_commands = resolve_npm_commands(&ps)?;
|
let npx_commands =
|
||||||
|
resolve_npm_commands(&ps.npm_resolver, &ps.node_resolver)?;
|
||||||
let env_vars = collect_env_vars();
|
let env_vars = collect_env_vars();
|
||||||
let exit_code =
|
let exit_code =
|
||||||
deno_task_shell::execute(seq_list, env_vars, &cwd, npx_commands).await;
|
deno_task_shell::execute(seq_list, env_vars, &cwd, npx_commands).await;
|
||||||
|
@ -108,9 +112,8 @@ pub async fn execute_script(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_script_with_args(script: &str, ps: &ProcState) -> String {
|
fn get_script_with_args(script: &str, options: &CliOptions) -> String {
|
||||||
let additional_args = ps
|
let additional_args = options
|
||||||
.options
|
|
||||||
.argv()
|
.argv()
|
||||||
.iter()
|
.iter()
|
||||||
// surround all the additional arguments in double quotes
|
// surround all the additional arguments in double quotes
|
||||||
|
@ -231,13 +234,13 @@ impl ShellCommand for NpmPackageBinCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_npm_commands(
|
fn resolve_npm_commands(
|
||||||
ps: &ProcState,
|
npm_resolver: &NpmPackageResolver,
|
||||||
|
node_resolver: &CliNodeResolver,
|
||||||
) -> Result<HashMap<String, Rc<dyn ShellCommand>>, AnyError> {
|
) -> Result<HashMap<String, Rc<dyn ShellCommand>>, AnyError> {
|
||||||
let mut result = HashMap::new();
|
let mut result = HashMap::new();
|
||||||
let snapshot = ps.npm_resolver.snapshot();
|
let snapshot = npm_resolver.snapshot();
|
||||||
for id in snapshot.top_level_packages() {
|
for id in snapshot.top_level_packages() {
|
||||||
let bin_commands =
|
let bin_commands = node_resolver.resolve_binary_commands(&id.nv)?;
|
||||||
crate::node::node_resolve_binary_commands(&id.nv, &ps.npm_resolver)?;
|
|
||||||
for bin_command in bin_commands {
|
for bin_command in bin_commands {
|
||||||
result.insert(
|
result.insert(
|
||||||
bin_command.to_string(),
|
bin_command.to_string(),
|
||||||
|
|
15
cli/tools/vendor/mod.rs
vendored
15
cli/tools/vendor/mod.rs
vendored
|
@ -15,6 +15,7 @@ use crate::args::CliOptions;
|
||||||
use crate::args::Flags;
|
use crate::args::Flags;
|
||||||
use crate::args::FmtOptionsConfig;
|
use crate::args::FmtOptionsConfig;
|
||||||
use crate::args::VendorFlags;
|
use crate::args::VendorFlags;
|
||||||
|
use crate::graph_util::ModuleGraphBuilder;
|
||||||
use crate::proc_state::ProcState;
|
use crate::proc_state::ProcState;
|
||||||
use crate::tools::fmt::format_json;
|
use crate::tools::fmt::format_json;
|
||||||
use crate::util::fs::canonicalize_path;
|
use crate::util::fs::canonicalize_path;
|
||||||
|
@ -43,7 +44,12 @@ pub async fn vendor(
|
||||||
validate_output_dir(&output_dir, &vendor_flags)?;
|
validate_output_dir(&output_dir, &vendor_flags)?;
|
||||||
validate_options(&mut cli_options, &output_dir)?;
|
validate_options(&mut cli_options, &output_dir)?;
|
||||||
let ps = ProcState::from_cli_options(Arc::new(cli_options)).await?;
|
let ps = ProcState::from_cli_options(Arc::new(cli_options)).await?;
|
||||||
let graph = create_graph(&ps, &vendor_flags).await?;
|
let graph = create_graph(
|
||||||
|
&ps.module_graph_builder,
|
||||||
|
&vendor_flags,
|
||||||
|
ps.options.initial_cwd(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
let vendored_count = build::build(
|
let vendored_count = build::build(
|
||||||
graph,
|
graph,
|
||||||
&ps.parsed_source_cache,
|
&ps.parsed_source_cache,
|
||||||
|
@ -261,16 +267,17 @@ fn is_dir_empty(dir_path: &Path) -> Result<bool, AnyError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_graph(
|
async fn create_graph(
|
||||||
ps: &ProcState,
|
module_graph_builder: &ModuleGraphBuilder,
|
||||||
flags: &VendorFlags,
|
flags: &VendorFlags,
|
||||||
|
initial_cwd: &Path,
|
||||||
) -> Result<deno_graph::ModuleGraph, AnyError> {
|
) -> Result<deno_graph::ModuleGraph, AnyError> {
|
||||||
let entry_points = flags
|
let entry_points = flags
|
||||||
.specifiers
|
.specifiers
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| resolve_url_or_path(p, ps.options.initial_cwd()))
|
.map(|p| resolve_url_or_path(p, initial_cwd))
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
ps.module_graph_builder.create_graph(entry_points).await
|
module_graph_builder.create_graph(entry_points).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -4,9 +4,8 @@ use crate::args::TsConfig;
|
||||||
use crate::args::TypeCheckMode;
|
use crate::args::TypeCheckMode;
|
||||||
use crate::cache::FastInsecureHasher;
|
use crate::cache::FastInsecureHasher;
|
||||||
use crate::node;
|
use crate::node;
|
||||||
use crate::node::node_resolve_npm_reference;
|
use crate::node::CliNodeResolver;
|
||||||
use crate::node::NodeResolution;
|
use crate::node::NodeResolution;
|
||||||
use crate::npm::NpmPackageResolver;
|
|
||||||
use crate::util::checksum;
|
use crate::util::checksum;
|
||||||
use crate::util::path::mapped_specifier_for_tsc;
|
use crate::util::path::mapped_specifier_for_tsc;
|
||||||
|
|
||||||
|
@ -36,7 +35,6 @@ use deno_graph::ModuleGraph;
|
||||||
use deno_graph::ResolutionResolved;
|
use deno_graph::ResolutionResolved;
|
||||||
use deno_runtime::deno_node::NodeResolutionMode;
|
use deno_runtime::deno_node::NodeResolutionMode;
|
||||||
use deno_runtime::permissions::PermissionsContainer;
|
use deno_runtime::permissions::PermissionsContainer;
|
||||||
use deno_semver::npm::NpmPackageNvReference;
|
|
||||||
use deno_semver::npm::NpmPackageReqReference;
|
use deno_semver::npm::NpmPackageReqReference;
|
||||||
use lsp_types::Url;
|
use lsp_types::Url;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
@ -307,7 +305,7 @@ pub struct Request {
|
||||||
pub debug: bool,
|
pub debug: bool,
|
||||||
pub graph: Arc<ModuleGraph>,
|
pub graph: Arc<ModuleGraph>,
|
||||||
pub hash_data: u64,
|
pub hash_data: u64,
|
||||||
pub maybe_npm_resolver: Option<Arc<NpmPackageResolver>>,
|
pub maybe_node_resolver: Option<Arc<CliNodeResolver>>,
|
||||||
pub maybe_tsbuildinfo: Option<String>,
|
pub maybe_tsbuildinfo: Option<String>,
|
||||||
/// A vector of strings that represent the root/entry point modules for the
|
/// A vector of strings that represent the root/entry point modules for the
|
||||||
/// program.
|
/// program.
|
||||||
|
@ -331,7 +329,7 @@ struct State {
|
||||||
graph: Arc<ModuleGraph>,
|
graph: Arc<ModuleGraph>,
|
||||||
maybe_tsbuildinfo: Option<String>,
|
maybe_tsbuildinfo: Option<String>,
|
||||||
maybe_response: Option<RespondArgs>,
|
maybe_response: Option<RespondArgs>,
|
||||||
maybe_npm_resolver: Option<Arc<NpmPackageResolver>>,
|
maybe_node_resolver: Option<Arc<CliNodeResolver>>,
|
||||||
remapped_specifiers: HashMap<String, ModuleSpecifier>,
|
remapped_specifiers: HashMap<String, ModuleSpecifier>,
|
||||||
root_map: HashMap<String, ModuleSpecifier>,
|
root_map: HashMap<String, ModuleSpecifier>,
|
||||||
current_dir: PathBuf,
|
current_dir: PathBuf,
|
||||||
|
@ -341,7 +339,7 @@ impl State {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
graph: Arc<ModuleGraph>,
|
graph: Arc<ModuleGraph>,
|
||||||
hash_data: u64,
|
hash_data: u64,
|
||||||
maybe_npm_resolver: Option<Arc<NpmPackageResolver>>,
|
maybe_node_resolver: Option<Arc<CliNodeResolver>>,
|
||||||
maybe_tsbuildinfo: Option<String>,
|
maybe_tsbuildinfo: Option<String>,
|
||||||
root_map: HashMap<String, ModuleSpecifier>,
|
root_map: HashMap<String, ModuleSpecifier>,
|
||||||
remapped_specifiers: HashMap<String, ModuleSpecifier>,
|
remapped_specifiers: HashMap<String, ModuleSpecifier>,
|
||||||
|
@ -350,7 +348,7 @@ impl State {
|
||||||
State {
|
State {
|
||||||
hash_data,
|
hash_data,
|
||||||
graph,
|
graph,
|
||||||
maybe_npm_resolver,
|
maybe_node_resolver,
|
||||||
maybe_tsbuildinfo,
|
maybe_tsbuildinfo,
|
||||||
maybe_response: None,
|
maybe_response: None,
|
||||||
remapped_specifiers,
|
remapped_specifiers,
|
||||||
|
@ -483,7 +481,7 @@ fn op_load(state: &mut OpState, args: Value) -> Result<Value, AnyError> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if state
|
} else if state
|
||||||
.maybe_npm_resolver
|
.maybe_node_resolver
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|resolver| resolver.in_npm_package(specifier))
|
.map(|resolver| resolver.in_npm_package(specifier))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
|
@ -636,24 +634,26 @@ fn resolve_graph_specifier_types(
|
||||||
Ok(Some((module.specifier.clone(), module.media_type)))
|
Ok(Some((module.specifier.clone(), module.media_type)))
|
||||||
}
|
}
|
||||||
Some(Module::Npm(module)) => {
|
Some(Module::Npm(module)) => {
|
||||||
if let Some(npm_resolver) = &state.maybe_npm_resolver {
|
if let Some(node_resolver) = &state.maybe_node_resolver {
|
||||||
resolve_npm_package_reference_types(&module.nv_reference, npm_resolver)
|
let maybe_resolution = node_resolver.resolve_npm_reference(
|
||||||
.map(Some)
|
&module.nv_reference,
|
||||||
|
NodeResolutionMode::Types,
|
||||||
|
&mut PermissionsContainer::allow_all(),
|
||||||
|
)?;
|
||||||
|
Ok(Some(NodeResolution::into_specifier_and_media_type(
|
||||||
|
maybe_resolution,
|
||||||
|
)))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(Module::External(module)) => {
|
Some(Module::External(module)) => {
|
||||||
// we currently only use "External" for when the module is in an npm package
|
// we currently only use "External" for when the module is in an npm package
|
||||||
Ok(state.maybe_npm_resolver.as_ref().map(|npm_resolver| {
|
Ok(state.maybe_node_resolver.as_ref().map(|node_resolver| {
|
||||||
let specifier =
|
let specifier =
|
||||||
node::resolve_specifier_into_node_modules(&module.specifier);
|
node::resolve_specifier_into_node_modules(&module.specifier);
|
||||||
NodeResolution::into_specifier_and_media_type(
|
NodeResolution::into_specifier_and_media_type(
|
||||||
node::url_to_node_resolution(
|
node_resolver.url_to_node_resolution(specifier).ok(),
|
||||||
specifier,
|
|
||||||
&npm_resolver.as_require_npm_resolver(),
|
|
||||||
)
|
|
||||||
.ok(),
|
|
||||||
)
|
)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -666,60 +666,47 @@ fn resolve_non_graph_specifier_types(
|
||||||
referrer: &ModuleSpecifier,
|
referrer: &ModuleSpecifier,
|
||||||
state: &State,
|
state: &State,
|
||||||
) -> Result<Option<(ModuleSpecifier, MediaType)>, AnyError> {
|
) -> Result<Option<(ModuleSpecifier, MediaType)>, AnyError> {
|
||||||
let npm_resolver = match state.maybe_npm_resolver.as_ref() {
|
let node_resolver = match state.maybe_node_resolver.as_ref() {
|
||||||
Some(npm_resolver) => npm_resolver,
|
Some(node_resolver) => node_resolver,
|
||||||
None => return Ok(None), // we only support non-graph types for npm packages
|
None => return Ok(None), // we only support non-graph types for npm packages
|
||||||
};
|
};
|
||||||
if npm_resolver.in_npm_package(referrer) {
|
if node_resolver.in_npm_package(referrer) {
|
||||||
// we're in an npm package, so use node resolution
|
// we're in an npm package, so use node resolution
|
||||||
Ok(Some(NodeResolution::into_specifier_and_media_type(
|
Ok(Some(NodeResolution::into_specifier_and_media_type(
|
||||||
node::node_resolve(
|
node_resolver
|
||||||
specifier,
|
.resolve(
|
||||||
referrer,
|
specifier,
|
||||||
NodeResolutionMode::Types,
|
referrer,
|
||||||
&npm_resolver.as_require_npm_resolver(),
|
NodeResolutionMode::Types,
|
||||||
&mut PermissionsContainer::allow_all(),
|
&mut PermissionsContainer::allow_all(),
|
||||||
)
|
)
|
||||||
.ok()
|
.ok()
|
||||||
.flatten(),
|
.flatten(),
|
||||||
)))
|
)))
|
||||||
} else if let Ok(npm_ref) = NpmPackageReqReference::from_str(specifier) {
|
} else if let Ok(npm_ref) = NpmPackageReqReference::from_str(specifier) {
|
||||||
// todo(dsherret): add support for injecting this in the graph so
|
// todo(dsherret): add support for injecting this in the graph so
|
||||||
// we don't need this special code here.
|
// we don't need this special code here.
|
||||||
// This could occur when resolving npm:@types/node when it is
|
// This could occur when resolving npm:@types/node when it is
|
||||||
// injected and not part of the graph
|
// injected and not part of the graph
|
||||||
let node_id = npm_resolver.resolve_pkg_id_from_pkg_req(&npm_ref.req)?;
|
let maybe_resolution = node_resolver.resolve_npm_req_reference(
|
||||||
let npm_id_ref = NpmPackageNvReference {
|
&npm_ref,
|
||||||
nv: node_id.nv,
|
NodeResolutionMode::Types,
|
||||||
sub_path: npm_ref.sub_path,
|
&mut PermissionsContainer::allow_all(),
|
||||||
};
|
)?;
|
||||||
resolve_npm_package_reference_types(&npm_id_ref, npm_resolver).map(Some)
|
Ok(Some(NodeResolution::into_specifier_and_media_type(
|
||||||
|
maybe_resolution,
|
||||||
|
)))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_npm_package_reference_types(
|
|
||||||
npm_ref: &NpmPackageNvReference,
|
|
||||||
npm_resolver: &Arc<NpmPackageResolver>,
|
|
||||||
) -> Result<(ModuleSpecifier, MediaType), AnyError> {
|
|
||||||
let maybe_resolution = node_resolve_npm_reference(
|
|
||||||
npm_ref,
|
|
||||||
NodeResolutionMode::Types,
|
|
||||||
npm_resolver,
|
|
||||||
&mut PermissionsContainer::allow_all(),
|
|
||||||
)?;
|
|
||||||
Ok(NodeResolution::into_specifier_and_media_type(
|
|
||||||
maybe_resolution,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op]
|
#[op]
|
||||||
fn op_is_node_file(state: &mut OpState, path: &str) -> bool {
|
fn op_is_node_file(state: &mut OpState, path: &str) -> bool {
|
||||||
let state = state.borrow::<State>();
|
let state = state.borrow::<State>();
|
||||||
match ModuleSpecifier::parse(path) {
|
match ModuleSpecifier::parse(path) {
|
||||||
Ok(specifier) => state
|
Ok(specifier) => state
|
||||||
.maybe_npm_resolver
|
.maybe_node_resolver
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|r| r.in_npm_package(&specifier))
|
.map(|r| r.in_npm_package(&specifier))
|
||||||
.unwrap_or(false),
|
.unwrap_or(false),
|
||||||
|
@ -783,7 +770,7 @@ pub fn exec(request: Request) -> Result<Response, AnyError> {
|
||||||
state.put(State::new(
|
state.put(State::new(
|
||||||
options.request.graph,
|
options.request.graph,
|
||||||
options.request.hash_data,
|
options.request.hash_data,
|
||||||
options.request.maybe_npm_resolver,
|
options.request.maybe_node_resolver,
|
||||||
options.request.maybe_tsbuildinfo,
|
options.request.maybe_tsbuildinfo,
|
||||||
options.root_map,
|
options.root_map,
|
||||||
options.remapped_specifiers,
|
options.remapped_specifiers,
|
||||||
|
@ -955,7 +942,7 @@ mod tests {
|
||||||
debug: false,
|
debug: false,
|
||||||
graph: Arc::new(graph),
|
graph: Arc::new(graph),
|
||||||
hash_data,
|
hash_data,
|
||||||
maybe_npm_resolver: None,
|
maybe_node_resolver: None,
|
||||||
maybe_tsbuildinfo: None,
|
maybe_tsbuildinfo: None,
|
||||||
root_names: vec![(specifier.clone(), MediaType::TypeScript)],
|
root_names: vec![(specifier.clone(), MediaType::TypeScript)],
|
||||||
check_mode: TypeCheckMode::All,
|
check_mode: TypeCheckMode::All,
|
||||||
|
|
|
@ -258,23 +258,14 @@ pub async fn create_custom_worker(
|
||||||
ps.npm_resolver
|
ps.npm_resolver
|
||||||
.add_package_reqs(vec![package_ref.req.clone()])
|
.add_package_reqs(vec![package_ref.req.clone()])
|
||||||
.await?;
|
.await?;
|
||||||
let pkg_nv = ps
|
let node_resolution =
|
||||||
.npm_resolution
|
ps.node_resolver.resolve_binary_export(&package_ref)?;
|
||||||
.resolve_pkg_id_from_pkg_req(&package_ref.req)?
|
|
||||||
.nv;
|
|
||||||
let node_resolution = node::node_resolve_binary_export(
|
|
||||||
&pkg_nv,
|
|
||||||
package_ref.sub_path.as_deref(),
|
|
||||||
&ps.npm_resolver,
|
|
||||||
)?;
|
|
||||||
let is_main_cjs =
|
let is_main_cjs =
|
||||||
matches!(node_resolution, node::NodeResolution::CommonJs(_));
|
matches!(node_resolution, node::NodeResolution::CommonJs(_));
|
||||||
(node_resolution.into_url(), is_main_cjs)
|
(node_resolution.into_url(), is_main_cjs)
|
||||||
} else if ps.options.is_npm_main() {
|
} else if ps.options.is_npm_main() {
|
||||||
let node_resolution = node::url_to_node_resolution(
|
let node_resolution =
|
||||||
main_module,
|
ps.node_resolver.url_to_node_resolution(main_module)?;
|
||||||
&ps.npm_resolver.as_require_npm_resolver(),
|
|
||||||
)?;
|
|
||||||
let is_main_cjs =
|
let is_main_cjs =
|
||||||
matches!(node_resolution, node::NodeResolution::CommonJs(_));
|
matches!(node_resolution, node::NodeResolution::CommonJs(_));
|
||||||
(node_resolution.into_url(), is_main_cjs)
|
(node_resolution.into_url(), is_main_cjs)
|
||||||
|
@ -311,7 +302,7 @@ pub async fn create_custom_worker(
|
||||||
.join(checksum::gen(&[key.as_bytes()]))
|
.join(checksum::gen(&[key.as_bytes()]))
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut extensions = ops::cli_exts(ps.clone());
|
let mut extensions = ops::cli_exts(ps.npm_resolver.clone());
|
||||||
extensions.append(&mut custom_extensions);
|
extensions.append(&mut custom_extensions);
|
||||||
|
|
||||||
let options = WorkerOptions {
|
let options = WorkerOptions {
|
||||||
|
@ -429,7 +420,7 @@ fn create_web_worker_callback(
|
||||||
let pre_execute_module_cb =
|
let pre_execute_module_cb =
|
||||||
create_web_worker_pre_execute_module_callback(ps.clone());
|
create_web_worker_pre_execute_module_callback(ps.clone());
|
||||||
|
|
||||||
let extensions = ops::cli_exts(ps.clone());
|
let extensions = ops::cli_exts(ps.npm_resolver.clone());
|
||||||
|
|
||||||
let maybe_storage_key = ps.options.resolve_storage_key(&args.main_module);
|
let maybe_storage_key = ps.options.resolve_storage_key(&args.main_module);
|
||||||
let cache_storage_dir = maybe_storage_key.map(|key| {
|
let cache_storage_dir = maybe_storage_key.map(|key| {
|
||||||
|
|
Loading…
Reference in a new issue