2025-01-01 04:12:39 +09:00
// Copyright 2018-2025 the Deno authors. MIT license.
2021-10-11 08:26:22 +11:00
2024-12-30 12:38:20 -05:00
use std ::sync ::Arc ;
2024-06-05 11:04:16 -04:00
use async_trait ::async_trait ;
2024-05-18 11:42:03 -04:00
use dashmap ::DashSet ;
2024-08-20 10:11:43 -04:00
use deno_config ::workspace ::MappedResolutionDiagnostic ;
2024-07-03 20:54:33 -04:00
use deno_config ::workspace ::MappedResolutionError ;
2021-10-11 08:26:22 +11:00
use deno_core ::ModuleSpecifier ;
2025-01-08 14:52:32 -08:00
use deno_error ::JsErrorBox ;
2023-10-20 13:02:08 +09:00
use deno_graph ::source ::ResolveError ;
2023-02-22 14:15:25 -05:00
use deno_graph ::source ::UnknownBuiltInNodeModuleError ;
2024-06-11 08:55:12 -04:00
use deno_graph ::NpmLoadError ;
use deno_graph ::NpmResolvePkgReqsResult ;
use deno_npm ::resolution ::NpmResolutionError ;
2025-01-14 10:01:05 -05:00
use deno_resolver ::npm ::DenoInNpmPackageChecker ;
2025-01-09 18:30:48 -05:00
use deno_resolver ::sloppy_imports ::SloppyImportsCachedFs ;
2024-09-28 19:17:48 -04:00
use deno_resolver ::sloppy_imports ::SloppyImportsResolver ;
2024-08-20 10:11:43 -04:00
use deno_runtime ::colors ;
2023-02-22 14:15:25 -05:00
use deno_runtime ::deno_node ::is_builtin_node_module ;
2024-12-30 12:38:20 -05:00
use deno_runtime ::deno_node ::RealIsBuiltInNodeModuleChecker ;
2023-08-21 11:53:52 +02:00
use deno_semver ::package ::PackageReq ;
2024-11-26 14:38:24 -05:00
use node_resolver ::NodeResolutionKind ;
use node_resolver ::ResolutionMode ;
2021-10-11 08:26:22 +11:00
2024-12-10 18:24:23 -08:00
use crate ::args ::NpmCachingStrategy ;
2024-03-07 13:59:57 +00:00
use crate ::args ::DENO_DISABLE_PEDANTIC_NODE_WARNINGS ;
2025-01-13 17:35:18 -05:00
use crate ::npm ::installer ::NpmInstaller ;
use crate ::npm ::installer ::PackageCaching ;
2025-01-14 10:01:05 -05:00
use crate ::npm ::CliNpmResolver ;
2024-12-31 12:13:39 -05:00
use crate ::sys ::CliSys ;
2023-04-11 18:10:51 -04:00
use crate ::util ::sync ::AtomicFlag ;
2022-08-24 19:36:05 +02:00
2025-01-14 10:01:05 -05:00
pub type CliCjsTracker =
deno_resolver ::cjs ::CjsTracker < DenoInNpmPackageChecker , CliSys > ;
pub type CliIsCjsResolver =
deno_resolver ::cjs ::IsCjsResolver < DenoInNpmPackageChecker , CliSys > ;
2025-01-09 18:30:48 -05:00
pub type CliSloppyImportsCachedFs = SloppyImportsCachedFs < CliSys > ;
2024-11-14 15:24:25 -05:00
pub type CliSloppyImportsResolver =
2025-01-09 18:30:48 -05:00
SloppyImportsResolver < CliSloppyImportsCachedFs > ;
2024-11-14 15:24:25 -05:00
pub type CliDenoResolver = deno_resolver ::DenoResolver <
2025-01-14 10:01:05 -05:00
DenoInNpmPackageChecker ,
2024-12-30 12:38:20 -05:00
RealIsBuiltInNodeModuleChecker ,
2025-01-14 10:01:05 -05:00
CliNpmResolver ,
2025-01-09 18:30:48 -05:00
CliSloppyImportsCachedFs ,
2024-12-31 11:29:07 -05:00
CliSys ,
2024-11-14 15:24:25 -05:00
> ;
2025-01-14 10:01:05 -05:00
pub type CliNpmReqResolver = deno_resolver ::npm ::NpmReqResolver <
DenoInNpmPackageChecker ,
RealIsBuiltInNodeModuleChecker ,
CliNpmResolver ,
CliSys ,
> ;
2024-11-14 15:24:25 -05:00
2025-01-13 17:35:18 -05:00
#[ derive(Debug, Default) ]
pub struct FoundPackageJsonDepFlag ( AtomicFlag ) ;
2024-01-27 22:40:36 +05:30
2022-11-02 15:47:02 +01:00
/// A resolver that takes care of resolution, taking into account loaded
/// import map, JSX settings.
2023-04-14 16:22:33 -04:00
#[ derive(Debug) ]
2024-11-13 10:10:09 -05:00
pub struct CliResolver {
2024-11-14 15:24:25 -05:00
deno_resolver : Arc < CliDenoResolver > ,
2025-01-13 17:35:18 -05:00
found_package_json_dep_flag : Arc < FoundPackageJsonDepFlag > ,
2024-08-20 10:11:43 -04:00
warned_pkgs : DashSet < PackageReq > ,
2023-02-22 14:15:25 -05:00
}
2024-11-13 10:10:09 -05:00
impl CliResolver {
2025-01-13 17:35:18 -05:00
pub fn new (
deno_resolver : Arc < CliDenoResolver > ,
found_package_json_dep_flag : Arc < FoundPackageJsonDepFlag > ,
) -> Self {
2023-02-15 11:30:54 -05:00
Self {
2025-01-13 17:35:18 -05:00
deno_resolver ,
found_package_json_dep_flag ,
2024-08-20 10:11:43 -04:00
warned_pkgs : Default ::default ( ) ,
2022-02-01 09:33:57 +11:00
}
2021-10-11 08:26:22 +11:00
}
2021-11-09 12:26:39 +11:00
2024-11-13 10:10:09 -05:00
pub fn resolve (
2021-11-09 12:26:39 +11:00
& self ,
2024-09-04 16:00:44 +02:00
raw_specifier : & str ,
2024-11-26 14:38:24 -05:00
referrer : & ModuleSpecifier ,
referrer_range_start : deno_graph ::Position ,
resolution_mode : ResolutionMode ,
resolution_kind : NodeResolutionKind ,
2023-10-20 13:02:08 +09:00
) -> Result < ModuleSpecifier , ResolveError > {
2024-11-14 15:24:25 -05:00
let resolution = self
. deno_resolver
2024-11-26 14:38:24 -05:00
. resolve ( raw_specifier , referrer , resolution_mode , resolution_kind )
2024-11-14 15:24:25 -05:00
. map_err ( | err | match err . into_kind ( ) {
deno_resolver ::DenoResolveErrorKind ::MappedResolution (
mapped_resolution_error ,
) = > match mapped_resolution_error {
MappedResolutionError ::Specifier ( e ) = > ResolveError ::Specifier ( e ) ,
// deno_graph checks specifically for an ImportMapError
2025-01-08 14:52:32 -08:00
MappedResolutionError ::ImportMap ( e ) = > ResolveError ::ImportMap ( e ) ,
MappedResolutionError ::Workspace ( e ) = > {
ResolveError ::Other ( JsErrorBox ::from_err ( e ) )
}
2024-11-14 15:24:25 -05:00
} ,
2025-01-08 14:52:32 -08:00
err = > ResolveError ::Other ( JsErrorBox ::from_err ( err ) ) ,
2024-11-14 15:24:25 -05:00
} ) ? ;
2024-07-23 20:22:24 -04:00
2024-11-14 15:24:25 -05:00
if resolution . found_package_json_dep {
// mark that we need to do an "npm install" later
2025-01-13 17:35:18 -05:00
self . found_package_json_dep_flag . 0. raise ( ) ;
2024-07-23 20:22:24 -04:00
}
2024-11-14 15:24:25 -05:00
if let Some ( diagnostic ) = resolution . maybe_diagnostic {
match & * diagnostic {
MappedResolutionDiagnostic ::ConstraintNotMatchedLocalVersion {
reference ,
2024-07-03 20:54:33 -04:00
..
} = > {
2024-11-14 15:24:25 -05:00
if self . warned_pkgs . insert ( reference . req ( ) . clone ( ) ) {
log ::warn! (
2024-11-26 14:38:24 -05:00
" {} {} \n at {}:{} " ,
2024-11-14 15:24:25 -05:00
colors ::yellow ( " Warning " ) ,
diagnostic ,
2024-11-26 14:38:24 -05:00
referrer ,
referrer_range_start ,
2024-11-14 15:24:25 -05:00
) ;
2023-10-25 14:39:00 -04:00
}
}
2024-05-21 17:54:15 +01:00
}
2023-10-25 14:39:00 -04:00
}
2024-11-14 15:24:25 -05:00
Ok ( resolution . url )
2021-11-09 12:26:39 +11:00
}
}
2023-02-22 14:15:25 -05:00
2024-06-05 11:04:16 -04:00
#[ derive(Debug) ]
2025-01-13 17:35:18 -05:00
pub struct CliNpmGraphResolver {
npm_installer : Option < Arc < NpmInstaller > > ,
found_package_json_dep_flag : Arc < FoundPackageJsonDepFlag > ,
2024-06-05 11:04:16 -04:00
bare_node_builtins_enabled : bool ,
2024-12-10 18:24:23 -08:00
npm_caching : NpmCachingStrategy ,
2024-06-05 11:04:16 -04:00
}
2025-01-13 17:35:18 -05:00
impl CliNpmGraphResolver {
pub fn new (
npm_installer : Option < Arc < NpmInstaller > > ,
found_package_json_dep_flag : Arc < FoundPackageJsonDepFlag > ,
bare_node_builtins_enabled : bool ,
npm_caching : NpmCachingStrategy ,
) -> Self {
Self {
npm_installer ,
found_package_json_dep_flag ,
bare_node_builtins_enabled ,
npm_caching ,
}
}
}
2024-06-05 11:04:16 -04:00
#[ async_trait(?Send) ]
2025-01-13 17:35:18 -05:00
impl deno_graph ::source ::NpmResolver for CliNpmGraphResolver {
2023-02-22 14:15:25 -05:00
fn resolve_builtin_node_module (
& self ,
specifier : & ModuleSpecifier ,
) -> Result < Option < String > , UnknownBuiltInNodeModuleError > {
if specifier . scheme ( ) ! = " node " {
return Ok ( None ) ;
}
let module_name = specifier . path ( ) . to_string ( ) ;
if is_builtin_node_module ( & module_name ) {
Ok ( Some ( module_name ) )
} else {
Err ( UnknownBuiltInNodeModuleError { module_name } )
}
}
2023-10-20 13:02:08 +09:00
fn on_resolve_bare_builtin_node_module (
& self ,
module_name : & str ,
range : & deno_graph ::Range ,
) {
2024-11-26 14:38:24 -05:00
let start = range . range . start ;
let specifier = & range . specifier ;
2024-03-07 13:59:57 +00:00
if ! * DENO_DISABLE_PEDANTIC_NODE_WARNINGS {
2024-11-26 14:38:24 -05:00
log ::warn! ( " {} Resolving \" {module_name} \" as \" node:{module_name} \" at {specifier}:{start}. If you want to use a built-in Node module, add a \" node: \" prefix. " , colors ::yellow ( " Warning " ) )
2024-03-07 13:59:57 +00:00
}
2023-10-20 13:02:08 +09:00
}
2024-06-11 08:55:12 -04:00
fn load_and_cache_npm_package_info ( & self , package_name : & str ) {
2025-01-13 17:35:18 -05:00
if let Some ( npm_installer ) = & self . npm_installer {
let npm_installer = npm_installer . clone ( ) ;
let package_name = package_name . to_string ( ) ;
deno_core ::unsync ::spawn ( async move {
let _ignore = npm_installer . cache_package_info ( & package_name ) . await ;
} ) ;
2023-02-22 14:15:25 -05:00
}
}
2024-06-05 11:04:16 -04:00
async fn resolve_pkg_reqs (
& self ,
2024-06-11 08:55:12 -04:00
package_reqs : & [ PackageReq ] ,
) -> NpmResolvePkgReqsResult {
2025-01-13 17:35:18 -05:00
match & self . npm_installer {
Some ( npm_installer ) = > {
let top_level_result = if self . found_package_json_dep_flag . 0. is_raised ( )
{
npm_installer
2024-07-02 15:00:16 -07:00
. ensure_top_level_package_json_install ( )
. await
. map ( | _ | ( ) )
2024-06-11 08:55:12 -04:00
} else {
Ok ( ( ) )
2024-06-05 11:04:16 -04:00
} ;
2024-06-11 08:55:12 -04:00
2025-01-13 17:35:18 -05:00
let result = npm_installer
2024-12-10 18:24:23 -08:00
. add_package_reqs_raw (
package_reqs ,
match self . npm_caching {
2025-01-13 17:35:18 -05:00
NpmCachingStrategy ::Eager = > Some ( PackageCaching ::All ) ,
2024-12-10 18:24:23 -08:00
NpmCachingStrategy ::Lazy = > {
2025-01-13 17:35:18 -05:00
Some ( PackageCaching ::Only ( package_reqs . into ( ) ) )
2024-12-10 18:24:23 -08:00
}
NpmCachingStrategy ::Manual = > None ,
} ,
)
. await ;
2024-06-11 08:55:12 -04:00
NpmResolvePkgReqsResult {
results : result
. results
. into_iter ( )
. map ( | r | {
r . map_err ( | err | match err {
NpmResolutionError ::Registry ( e ) = > {
2025-01-08 14:52:32 -08:00
NpmLoadError ::RegistryInfo ( Arc ::new ( e ) )
2024-06-11 08:55:12 -04:00
}
NpmResolutionError ::Resolution ( e ) = > {
2025-01-08 14:52:32 -08:00
NpmLoadError ::PackageReqResolution ( Arc ::new ( e ) )
2024-06-11 08:55:12 -04:00
}
NpmResolutionError ::DependencyEntry ( e ) = > {
2025-01-08 14:52:32 -08:00
NpmLoadError ::PackageReqResolution ( Arc ::new ( e ) )
2024-06-11 08:55:12 -04:00
}
} )
} )
. collect ( ) ,
dep_graph_result : match top_level_result {
2025-01-08 14:52:32 -08:00
Ok ( ( ) ) = > result
. dependencies_result
. map_err ( | e | Arc ::new ( e ) as Arc < dyn deno_error ::JsErrorClass > ) ,
2024-06-11 08:55:12 -04:00
Err ( err ) = > Err ( Arc ::new ( err ) ) ,
} ,
}
}
None = > {
2025-01-08 14:52:32 -08:00
let err = Arc ::new ( JsErrorBox ::generic (
" npm specifiers were requested; but --no-npm is specified " ,
2024-06-11 08:55:12 -04:00
) ) ;
NpmResolvePkgReqsResult {
results : package_reqs
. iter ( )
. map ( | _ | Err ( NpmLoadError ::RegistryInfo ( err . clone ( ) ) ) )
. collect ( ) ,
dep_graph_result : Err ( err ) ,
2023-10-03 19:05:06 -04:00
}
2024-06-05 11:04:16 -04:00
}
2023-04-06 21:41:19 -04:00
}
2023-02-22 14:15:25 -05:00
}
2023-10-20 13:02:08 +09:00
fn enables_bare_builtin_node_module ( & self ) -> bool {
self . bare_node_builtins_enabled
}
2023-02-22 14:15:25 -05:00
}