mirror of
https://github.com/denoland/deno.git
synced 2025-02-23 13:43:31 -05:00

This splits away some npm resolution code from installation. It will allow for more easily extracting out resolution code in the future.
117 lines
3.2 KiB
Rust
117 lines
3.2 KiB
Rust
// Copyright 2018-2025 the Deno authors. MIT license.
|
|
|
|
//! Code for global npm cache resolution.
|
|
|
|
use std::path::Path;
|
|
use std::path::PathBuf;
|
|
use std::sync::Arc;
|
|
|
|
use async_trait::async_trait;
|
|
use deno_ast::ModuleSpecifier;
|
|
use deno_npm::NpmPackageCacheFolderId;
|
|
use deno_npm::NpmPackageId;
|
|
use node_resolver::errors::PackageFolderResolveError;
|
|
use node_resolver::errors::PackageNotFoundError;
|
|
use node_resolver::errors::ReferrerNotFoundError;
|
|
|
|
use super::super::resolution::NpmResolution;
|
|
use super::common::NpmPackageFsResolver;
|
|
use crate::npm::CliNpmCache;
|
|
|
|
/// Resolves packages from the global npm cache.
|
|
#[derive(Debug)]
|
|
pub struct GlobalNpmPackageResolver {
|
|
cache: Arc<CliNpmCache>,
|
|
resolution: Arc<NpmResolution>,
|
|
}
|
|
|
|
impl GlobalNpmPackageResolver {
|
|
pub fn new(cache: Arc<CliNpmCache>, resolution: Arc<NpmResolution>) -> Self {
|
|
Self { cache, resolution }
|
|
}
|
|
}
|
|
|
|
#[async_trait(?Send)]
|
|
impl NpmPackageFsResolver for GlobalNpmPackageResolver {
|
|
fn node_modules_path(&self) -> Option<&Path> {
|
|
None
|
|
}
|
|
|
|
fn maybe_package_folder(&self, id: &NpmPackageId) -> Option<PathBuf> {
|
|
let folder_id = self
|
|
.resolution
|
|
.resolve_pkg_cache_folder_id_from_pkg_id(id)?;
|
|
Some(self.cache.package_folder_for_id(&folder_id))
|
|
}
|
|
|
|
fn resolve_package_folder_from_package(
|
|
&self,
|
|
name: &str,
|
|
referrer: &ModuleSpecifier,
|
|
) -> Result<PathBuf, PackageFolderResolveError> {
|
|
use deno_npm::resolution::PackageNotFoundFromReferrerError;
|
|
let Some(referrer_cache_folder_id) = self
|
|
.cache
|
|
.resolve_package_folder_id_from_specifier(referrer)
|
|
else {
|
|
return Err(
|
|
ReferrerNotFoundError {
|
|
referrer: referrer.clone(),
|
|
referrer_extra: None,
|
|
}
|
|
.into(),
|
|
);
|
|
};
|
|
let resolve_result = self
|
|
.resolution
|
|
.resolve_package_from_package(name, &referrer_cache_folder_id);
|
|
match resolve_result {
|
|
Ok(pkg) => match self.maybe_package_folder(&pkg.id) {
|
|
Some(folder) => Ok(folder),
|
|
None => Err(
|
|
PackageNotFoundError {
|
|
package_name: name.to_string(),
|
|
referrer: referrer.clone(),
|
|
referrer_extra: Some(format!(
|
|
"{} -> {}",
|
|
referrer_cache_folder_id,
|
|
pkg.id.as_serialized()
|
|
)),
|
|
}
|
|
.into(),
|
|
),
|
|
},
|
|
Err(err) => match *err {
|
|
PackageNotFoundFromReferrerError::Referrer(cache_folder_id) => Err(
|
|
ReferrerNotFoundError {
|
|
referrer: referrer.clone(),
|
|
referrer_extra: Some(cache_folder_id.to_string()),
|
|
}
|
|
.into(),
|
|
),
|
|
PackageNotFoundFromReferrerError::Package {
|
|
name,
|
|
referrer: cache_folder_id_referrer,
|
|
} => Err(
|
|
PackageNotFoundError {
|
|
package_name: name,
|
|
referrer: referrer.clone(),
|
|
referrer_extra: Some(cache_folder_id_referrer.to_string()),
|
|
}
|
|
.into(),
|
|
),
|
|
},
|
|
}
|
|
}
|
|
|
|
fn resolve_package_cache_folder_id_from_specifier(
|
|
&self,
|
|
specifier: &ModuleSpecifier,
|
|
) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error> {
|
|
Ok(
|
|
self
|
|
.cache
|
|
.resolve_package_folder_id_from_specifier(specifier),
|
|
)
|
|
}
|
|
}
|