summaryrefslogtreecommitdiff
path: root/cli/npm/resolvers/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/npm/resolvers/mod.rs')
-rw-r--r--cli/npm/resolvers/mod.rs270
1 files changed, 170 insertions, 100 deletions
diff --git a/cli/npm/resolvers/mod.rs b/cli/npm/resolvers/mod.rs
index efaad93ee..07a122a3e 100644
--- a/cli/npm/resolvers/mod.rs
+++ b/cli/npm/resolvers/mod.rs
@@ -49,17 +49,77 @@ pub struct NpmProcessState {
pub local_node_modules_path: Option<String>,
}
-/// Brings together the npm resolution with the file system.
-pub struct CliNpmResolver {
+pub enum InnerCliNpmResolverRef<'a> {
+ Managed(&'a ManagedCliNpmResolver),
+ #[allow(dead_code)]
+ Byonm(&'a ByonmCliNpmResolver),
+}
+
+pub trait CliNpmResolver: NpmResolver {
+ fn into_npm_resolver(self: Arc<Self>) -> Arc<dyn NpmResolver>;
+
+ fn root_dir_url(&self) -> &Url;
+
+ fn as_inner(&self) -> InnerCliNpmResolverRef;
+
+ fn as_managed(&self) -> Option<&ManagedCliNpmResolver> {
+ match self.as_inner() {
+ InnerCliNpmResolverRef::Managed(inner) => Some(inner),
+ InnerCliNpmResolverRef::Byonm(_) => None,
+ }
+ }
+
+ fn node_modules_path(&self) -> Option<PathBuf>;
+
+ /// Checks if the provided package req's folder is cached.
+ fn is_pkg_req_folder_cached(&self, req: &PackageReq) -> bool;
+
+ fn resolve_pkg_nv_ref_from_pkg_req_ref(
+ &self,
+ req_ref: &NpmPackageReqReference,
+ ) -> Result<NpmPackageNvReference, PackageReqNotFoundError>;
+
+ /// Resolve the root folder of the package the provided specifier is in.
+ ///
+ /// This will error when the provided specifier is not in an npm package.
+ fn resolve_pkg_folder_from_specifier(
+ &self,
+ specifier: &ModuleSpecifier,
+ ) -> Result<Option<PathBuf>, AnyError>;
+
+ fn resolve_pkg_folder_from_deno_module_req(
+ &self,
+ req: &PackageReq,
+ ) -> Result<PathBuf, AnyError>;
+
+ fn resolve_pkg_folder_from_deno_module(
+ &self,
+ nv: &PackageNv,
+ ) -> Result<PathBuf, AnyError>;
+
+ /// Gets the state of npm for the process.
+ fn get_npm_process_state(&self) -> String;
+
+ // todo(#18967): should instead return a hash state of the resolver
+ // or perhaps this could be non-BYONM only and byonm always runs deno check
+ fn package_reqs(&self) -> HashMap<PackageReq, PackageNv>;
+}
+
+// todo(dsherret): implement this
+pub struct ByonmCliNpmResolver;
+
+/// An npm resolver where the resolution is managed by Deno rather than
+/// the user bringing their own node_modules (BYONM) on the file system.
+pub struct ManagedCliNpmResolver {
fs: Arc<dyn FileSystem>,
fs_resolver: Arc<dyn NpmPackageFsResolver>,
resolution: Arc<NpmResolution>,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
}
-impl std::fmt::Debug for CliNpmResolver {
+impl std::fmt::Debug for ManagedCliNpmResolver {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.debug_struct("NpmPackageResolver")
+ f.debug_struct("ManagedNpmResolver")
.field("fs", &"<omitted>")
.field("fs_resolver", &"<omitted>")
.field("resolution", &"<omitted>")
@@ -68,7 +128,7 @@ impl std::fmt::Debug for CliNpmResolver {
}
}
-impl CliNpmResolver {
+impl ManagedCliNpmResolver {
pub fn new(
fs: Arc<dyn FileSystem>,
resolution: Arc<NpmResolution>,
@@ -83,44 +143,6 @@ impl CliNpmResolver {
}
}
- pub fn root_dir_url(&self) -> &Url {
- self.fs_resolver.root_dir_url()
- }
-
- pub fn node_modules_path(&self) -> Option<PathBuf> {
- self.fs_resolver.node_modules_path()
- }
-
- /// Checks if the provided package req's folder is cached.
- pub fn is_pkg_req_folder_cached(&self, req: &PackageReq) -> bool {
- self
- .resolve_pkg_id_from_pkg_req(req)
- .ok()
- .and_then(|id| self.fs_resolver.package_folder(&id).ok())
- .map(|folder| folder.exists())
- .unwrap_or(false)
- }
-
- pub fn resolve_pkg_nv_ref_from_pkg_req_ref(
- &self,
- req_ref: &NpmPackageReqReference,
- ) -> Result<NpmPackageNvReference, PackageReqNotFoundError> {
- let pkg_nv = self
- .resolve_pkg_id_from_pkg_req(req_ref.req())
- .map(|id| id.nv)?;
- Ok(NpmPackageNvReference::new(PackageNvReference {
- nv: pkg_nv,
- sub_path: req_ref.sub_path().map(|s| s.to_string()),
- }))
- }
-
- pub fn resolve_pkg_id_from_pkg_req(
- &self,
- req: &PackageReq,
- ) -> Result<NpmPackageId, PackageReqNotFoundError> {
- self.resolution.resolve_pkg_id_from_pkg_req(req)
- }
-
pub fn resolve_pkg_folder_from_pkg_id(
&self,
pkg_id: &NpmPackageId,
@@ -140,43 +162,6 @@ impl CliNpmResolver {
Ok(path)
}
- /// Resolve the root folder of the package the provided specifier is in.
- ///
- /// This will error when the provided specifier is not in an npm package.
- pub fn resolve_pkg_folder_from_specifier(
- &self,
- specifier: &ModuleSpecifier,
- ) -> Result<Option<PathBuf>, AnyError> {
- let Some(path) = self
- .fs_resolver
- .resolve_package_folder_from_specifier(specifier)?
- else {
- return Ok(None);
- };
- log::debug!(
- "Resolved package folder of {} to {}",
- specifier,
- path.display()
- );
- Ok(Some(path))
- }
-
- pub fn resolve_pkg_folder_from_deno_module_req(
- &self,
- req: &PackageReq,
- ) -> Result<PathBuf, AnyError> {
- let pkg_id = self.resolve_pkg_id_from_pkg_req(req)?;
- self.resolve_pkg_folder_from_pkg_id(&pkg_id)
- }
-
- pub fn resolve_pkg_folder_from_deno_module(
- &self,
- nv: &PackageNv,
- ) -> Result<PathBuf, AnyError> {
- let pkg_id = self.resolution.resolve_pkg_id_from_deno_module(nv)?;
- self.resolve_pkg_folder_from_pkg_id(&pkg_id)
- }
-
/// Resolves the package nv from the provided specifier.
pub fn resolve_pkg_id_from_specifier(
&self,
@@ -235,25 +220,6 @@ impl CliNpmResolver {
self.resolution.set_package_reqs(packages).await
}
- /// Gets the state of npm for the process.
- pub fn get_npm_process_state(&self) -> String {
- serde_json::to_string(&NpmProcessState {
- snapshot: self
- .resolution
- .serialized_valid_snapshot()
- .into_serialized(),
- local_node_modules_path: self
- .fs_resolver
- .node_modules_path()
- .map(|p| p.to_string_lossy().to_string()),
- })
- .unwrap()
- }
-
- pub fn package_reqs(&self) -> HashMap<PackageReq, PackageNv> {
- self.resolution.package_reqs()
- }
-
pub fn snapshot(&self) -> NpmResolutionSnapshot {
self.resolution.snapshot()
}
@@ -278,9 +244,16 @@ impl CliNpmResolver {
self.fs_resolver.cache_packages().await?;
Ok(())
}
+
+ fn resolve_pkg_id_from_pkg_req(
+ &self,
+ req: &PackageReq,
+ ) -> Result<NpmPackageId, PackageReqNotFoundError> {
+ self.resolution.resolve_pkg_id_from_pkg_req(req)
+ }
}
-impl NpmResolver for CliNpmResolver {
+impl NpmResolver for ManagedCliNpmResolver {
fn resolve_package_folder_from_package(
&self,
name: &str,
@@ -316,6 +289,103 @@ impl NpmResolver for CliNpmResolver {
}
}
+impl CliNpmResolver for ManagedCliNpmResolver {
+ fn into_npm_resolver(self: Arc<Self>) -> Arc<dyn NpmResolver> {
+ self
+ }
+
+ fn root_dir_url(&self) -> &Url {
+ self.fs_resolver.root_dir_url()
+ }
+
+ fn as_inner(&self) -> InnerCliNpmResolverRef {
+ InnerCliNpmResolverRef::Managed(self)
+ }
+
+ fn node_modules_path(&self) -> Option<PathBuf> {
+ self.fs_resolver.node_modules_path()
+ }
+
+ /// Checks if the provided package req's folder is cached.
+ fn is_pkg_req_folder_cached(&self, req: &PackageReq) -> bool {
+ self
+ .resolve_pkg_id_from_pkg_req(req)
+ .ok()
+ .and_then(|id| self.fs_resolver.package_folder(&id).ok())
+ .map(|folder| folder.exists())
+ .unwrap_or(false)
+ }
+
+ fn resolve_pkg_nv_ref_from_pkg_req_ref(
+ &self,
+ req_ref: &NpmPackageReqReference,
+ ) -> Result<NpmPackageNvReference, PackageReqNotFoundError> {
+ let pkg_nv = self
+ .resolve_pkg_id_from_pkg_req(req_ref.req())
+ .map(|id| id.nv)?;
+ Ok(NpmPackageNvReference::new(PackageNvReference {
+ nv: pkg_nv,
+ sub_path: req_ref.sub_path().map(|s| s.to_string()),
+ }))
+ }
+
+ /// Resolve the root folder of the package the provided specifier is in.
+ ///
+ /// This will error when the provided specifier is not in an npm package.
+ fn resolve_pkg_folder_from_specifier(
+ &self,
+ specifier: &ModuleSpecifier,
+ ) -> Result<Option<PathBuf>, AnyError> {
+ let Some(path) = self
+ .fs_resolver
+ .resolve_package_folder_from_specifier(specifier)?
+ else {
+ return Ok(None);
+ };
+ log::debug!(
+ "Resolved package folder of {} to {}",
+ specifier,
+ path.display()
+ );
+ Ok(Some(path))
+ }
+
+ fn resolve_pkg_folder_from_deno_module_req(
+ &self,
+ req: &PackageReq,
+ ) -> Result<PathBuf, AnyError> {
+ let pkg_id = self.resolve_pkg_id_from_pkg_req(req)?;
+ self.resolve_pkg_folder_from_pkg_id(&pkg_id)
+ }
+
+ fn resolve_pkg_folder_from_deno_module(
+ &self,
+ nv: &PackageNv,
+ ) -> Result<PathBuf, AnyError> {
+ let pkg_id = self.resolution.resolve_pkg_id_from_deno_module(nv)?;
+ self.resolve_pkg_folder_from_pkg_id(&pkg_id)
+ }
+
+ /// Gets the state of npm for the process.
+ fn get_npm_process_state(&self) -> String {
+ serde_json::to_string(&NpmProcessState {
+ snapshot: self
+ .resolution
+ .serialized_valid_snapshot()
+ .into_serialized(),
+ local_node_modules_path: self
+ .fs_resolver
+ .node_modules_path()
+ .map(|p| p.to_string_lossy().to_string()),
+ })
+ .unwrap()
+ }
+
+ fn package_reqs(&self) -> HashMap<PackageReq, PackageNv> {
+ self.resolution.package_reqs()
+ }
+}
+
pub fn create_npm_fs_resolver(
fs: Arc<dyn FileSystem>,
cache: Arc<NpmCache>,