use crate::error::Error;
use crate::anyhow::anyhow;
use std::path::{Path, PathBuf};
use deno_runtime::deno_core::error::AnyError;
use deno_runtime::deno_core::ModuleSpecifier;
use deno_runtime::deno_node::{NpmResolver, NodePermissions, NodeResolutionMode};
#[derive(Debug, Clone)]
pub struct BasicNpmResolver {
pub node_modules_url: ModuleSpecifier,
}
impl BasicNpmResolver {
pub fn new_from_str(path: &str) -> Result<BasicNpmResolver, Error> {
Ok(BasicNpmResolver {
node_modules_url: ModuleSpecifier::from_directory_path(path)
.map_err(|_| Error::FailedToParseFilePathToUrl(path.to_owned()))?,
})
}
}
impl NpmResolver for BasicNpmResolver {
fn ensure_read_permission(
&self,
_permissions: &dyn NodePermissions,
_path: &Path,
) -> Result<(), AnyError> {
Ok(())
}
fn resolve_package_folder_from_package(
&self,
specifier: &str,
_referrer: &ModuleSpecifier,
_mode: NodeResolutionMode,
) -> Result<PathBuf, AnyError> {
self.node_modules_url
.join(specifier)?
.to_file_path()
.map_err(|_e| anyhow!("falied to convert to file path"))
}
fn in_npm_package(&self, specifier: &ModuleSpecifier) -> bool {
specifier
.as_str()
.starts_with(self.node_modules_url.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::anyhow;
use std::str::FromStr;
#[test]
fn test_basic_npm_resolver() -> anyhow::Result<()> {
let basic_npm_resolver = BasicNpmResolver::new_from_str("/path/to/node_modules")?;
let test_path = ModuleSpecifier::from_file_path("/path/to/other_folder/file.js").unwrap();
let should_not_be_in_node_modules = basic_npm_resolver.in_npm_package(&test_path);
assert!(!should_not_be_in_node_modules);
let test_path =
ModuleSpecifier::from_file_path("/path/to/node_modules/some_lib/file.js").unwrap();
let should_be_in_node_modules = basic_npm_resolver.in_npm_package(&test_path);
assert!(should_be_in_node_modules);
let package_folder_path = basic_npm_resolver.resolve_package_folder_from_package(
"some_other_lib",
&test_path,
NodeResolutionMode::Execution,
)?;
let expected_package_folder_path =
PathBuf::from_str("/path/to/node_modules/some_other_lib").unwrap();
assert_eq!(package_folder_path, expected_package_folder_path);
Ok(())
}
}