1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-19 04:16:00 -05:00

refactor(npm): extract out some npm fs resolution code from the cli (#27607)

Moves the npm fs resolvers into the deno_resolution crate.

This does not entirely move things out, but is a step in that direction.
This commit is contained in:
David Sherret 2025-01-09 12:10:07 -05:00 committed by GitHub
parent ce0968ef3a
commit 093f3ba565
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 312 additions and 213 deletions

6
Cargo.lock generated
View file

@ -2096,12 +2096,10 @@ dependencies = [
name = "deno_npm_cache" name = "deno_npm_cache"
version = "0.3.0" version = "0.3.0"
dependencies = [ dependencies = [
"anyhow",
"async-trait", "async-trait",
"base64 0.21.7", "base64 0.21.7",
"boxed_error", "boxed_error",
"deno_cache_dir", "deno_cache_dir",
"deno_core",
"deno_error", "deno_error",
"deno_npm", "deno_npm",
"deno_path_util", "deno_path_util",
@ -2197,16 +2195,20 @@ name = "deno_resolver"
version = "0.15.0" version = "0.15.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait",
"base32", "base32",
"boxed_error", "boxed_error",
"dashmap", "dashmap",
"deno_cache_dir",
"deno_config", "deno_config",
"deno_error", "deno_error",
"deno_media_type", "deno_media_type",
"deno_npm",
"deno_package_json", "deno_package_json",
"deno_path_util", "deno_path_util",
"deno_semver", "deno_semver",
"node_resolver", "node_resolver",
"parking_lot",
"sys_traits", "sys_traits",
"test_server", "test_server",
"thiserror 2.0.3", "thiserror 2.0.3",

View file

@ -70,7 +70,7 @@ impl HttpClientProvider {
} }
} }
pub fn get_or_create(&self) -> Result<HttpClient, AnyError> { pub fn get_or_create(&self) -> Result<HttpClient, JsErrorBox> {
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
let thread_id = std::thread::current().id(); let thread_id = std::thread::current().id();
let mut clients = self.clients_by_thread_id.lock(); let mut clients = self.clients_by_thread_id.lock();
@ -87,7 +87,8 @@ impl HttpClientProvider {
}, },
..self.options.clone() ..self.options.clone()
}, },
)?; )
.map_err(JsErrorBox::from_err)?;
entry.insert(client.clone()); entry.insert(client.clone());
Ok(HttpClient::new(client)) Ok(HttpClient::new(client))
} }

View file

@ -13,13 +13,13 @@ use deno_npm::resolution::AddPkgReqsOptions;
use deno_npm::resolution::NpmResolutionError; use deno_npm::resolution::NpmResolutionError;
use deno_npm::resolution::NpmResolutionSnapshot; use deno_npm::resolution::NpmResolutionSnapshot;
use deno_npm::NpmResolutionPackage; use deno_npm::NpmResolutionPackage;
use deno_resolver::npm::managed::NpmResolution;
use deno_semver::jsr::JsrDepPackageReq; use deno_semver::jsr::JsrDepPackageReq;
use deno_semver::package::PackageNv; use deno_semver::package::PackageNv;
use deno_semver::package::PackageReq; use deno_semver::package::PackageReq;
use deno_semver::SmallStackString; use deno_semver::SmallStackString;
use deno_semver::VersionReq; use deno_semver::VersionReq;
use super::resolution::NpmResolution;
use crate::args::CliLockfile; use crate::args::CliLockfile;
use crate::npm::CliNpmRegistryInfoProvider; use crate::npm::CliNpmRegistryInfoProvider;
use crate::util::sync::TaskQueue; use crate::util::sync::TaskQueue;

View file

@ -11,8 +11,8 @@ use deno_core::futures::StreamExt;
use deno_error::JsErrorBox; use deno_error::JsErrorBox;
use deno_npm::NpmResolutionPackage; use deno_npm::NpmResolutionPackage;
use deno_npm::NpmSystemInfo; use deno_npm::NpmSystemInfo;
use deno_resolver::npm::managed::NpmResolution;
use super::super::resolution::NpmResolution;
use super::common::lifecycle_scripts::LifecycleScriptsStrategy; use super::common::lifecycle_scripts::LifecycleScriptsStrategy;
use super::common::NpmPackageFsInstaller; use super::common::NpmPackageFsInstaller;
use crate::args::LifecycleScriptsConfig; use crate::args::LifecycleScriptsConfig;

View file

@ -24,19 +24,19 @@ use deno_npm::resolution::NpmResolutionSnapshot;
use deno_npm::NpmResolutionPackage; use deno_npm::NpmResolutionPackage;
use deno_npm::NpmSystemInfo; use deno_npm::NpmSystemInfo;
use deno_path_util::fs::atomic_write_file_with_retries; use deno_path_util::fs::atomic_write_file_with_retries;
use deno_resolver::npm::get_package_folder_id_folder_name;
use deno_resolver::npm::managed::NpmResolution;
use deno_semver::package::PackageNv; use deno_semver::package::PackageNv;
use deno_semver::StackString; use deno_semver::StackString;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use super::super::resolution::NpmResolution;
use super::common::bin_entries; use super::common::bin_entries;
use super::common::NpmPackageFsInstaller; use super::common::NpmPackageFsInstaller;
use crate::args::LifecycleScriptsConfig; use crate::args::LifecycleScriptsConfig;
use crate::args::NpmInstallDepsProvider; use crate::args::NpmInstallDepsProvider;
use crate::cache::CACHE_PERM; use crate::cache::CACHE_PERM;
use crate::colors; use crate::colors;
use crate::npm::managed::resolvers::get_package_folder_id_folder_name;
use crate::npm::managed::PackageCaching; use crate::npm::managed::PackageCaching;
use crate::npm::CliNpmCache; use crate::npm::CliNpmCache;
use crate::npm::CliNpmTarballCache; use crate::npm::CliNpmTarballCache;

View file

@ -4,11 +4,11 @@ use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use deno_npm::NpmSystemInfo; use deno_npm::NpmSystemInfo;
use deno_resolver::npm::managed::NpmResolution;
pub use self::common::NpmPackageFsInstaller; pub use self::common::NpmPackageFsInstaller;
use self::global::GlobalNpmPackageInstaller; use self::global::GlobalNpmPackageInstaller;
use self::local::LocalNpmPackageInstaller; use self::local::LocalNpmPackageInstaller;
use super::resolution::NpmResolution;
use crate::args::LifecycleScriptsConfig; use crate::args::LifecycleScriptsConfig;
use crate::args::NpmInstallDepsProvider; use crate::args::NpmInstallDepsProvider;
use crate::npm::CliNpmCache; use crate::npm::CliNpmCache;

View file

@ -23,6 +23,10 @@ use deno_npm::NpmResolutionPackage;
use deno_npm::NpmSystemInfo; use deno_npm::NpmSystemInfo;
use deno_npm_cache::NpmCacheSetting; use deno_npm_cache::NpmCacheSetting;
use deno_path_util::fs::canonicalize_path_maybe_not_exists; use deno_path_util::fs::canonicalize_path_maybe_not_exists;
use deno_resolver::npm::managed::create_npm_fs_resolver;
use deno_resolver::npm::managed::NpmPackageFsResolver;
use deno_resolver::npm::managed::NpmPackageFsResolverPackageFolderError;
use deno_resolver::npm::managed::NpmResolution;
use deno_resolver::npm::CliNpmReqResolver; use deno_resolver::npm::CliNpmReqResolver;
use deno_runtime::colors; use deno_runtime::colors;
use deno_runtime::ops::process::NpmProcessStateProvider; use deno_runtime::ops::process::NpmProcessStateProvider;
@ -37,9 +41,6 @@ use node_resolver::errors::PackageFolderResolveIoError;
use node_resolver::InNpmPackageChecker; use node_resolver::InNpmPackageChecker;
use node_resolver::NpmPackageFolderResolver; use node_resolver::NpmPackageFolderResolver;
use self::resolution::NpmResolution;
use self::resolvers::create_npm_fs_resolver;
use self::resolvers::NpmPackageFsResolver;
use super::CliNpmCache; use super::CliNpmCache;
use super::CliNpmCacheHttpClient; use super::CliNpmCacheHttpClient;
use super::CliNpmRegistryInfoProvider; use super::CliNpmRegistryInfoProvider;
@ -60,8 +61,6 @@ use crate::util::sync::AtomicFlag;
mod installer; mod installer;
mod installers; mod installers;
mod resolution;
mod resolvers;
pub enum CliNpmResolverManagedSnapshotOption { pub enum CliNpmResolverManagedSnapshotOption {
ResolveFromLockfile(Arc<CliLockfile>), ResolveFromLockfile(Arc<CliLockfile>),
@ -104,6 +103,7 @@ pub async fn create_managed_npm_resolver_for_lsp(
create_inner( create_inner(
http_client, http_client,
npm_cache, npm_cache,
options.npm_cache_dir,
options.npm_install_deps_provider, options.npm_install_deps_provider,
npm_api, npm_api,
options.sys, options.sys,
@ -133,6 +133,7 @@ pub async fn create_managed_npm_resolver(
Ok(create_inner( Ok(create_inner(
http_client, http_client,
npm_cache, npm_cache,
options.npm_cache_dir,
options.npm_install_deps_provider, options.npm_install_deps_provider,
api, api,
options.sys, options.sys,
@ -150,6 +151,7 @@ pub async fn create_managed_npm_resolver(
fn create_inner( fn create_inner(
http_client: Arc<CliNpmCacheHttpClient>, http_client: Arc<CliNpmCacheHttpClient>,
npm_cache: Arc<CliNpmCache>, npm_cache: Arc<CliNpmCache>,
npm_cache_dir: Arc<NpmCacheDir>,
npm_install_deps_provider: Arc<NpmInstallDepsProvider>, npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
registry_info_provider: Arc<CliNpmRegistryInfoProvider>, registry_info_provider: Arc<CliNpmRegistryInfoProvider>,
sys: CliSys, sys: CliSys,
@ -181,7 +183,8 @@ fn create_inner(
lifecycle_scripts.clone(), lifecycle_scripts.clone(),
); );
let fs_resolver = create_npm_fs_resolver( let fs_resolver = create_npm_fs_resolver(
npm_cache.clone(), &npm_cache_dir,
&npm_rc,
resolution.clone(), resolution.clone(),
sys.clone(), sys.clone(),
node_modules_dir_path, node_modules_dir_path,
@ -192,7 +195,9 @@ fn create_inner(
maybe_lockfile, maybe_lockfile,
registry_info_provider, registry_info_provider,
npm_cache, npm_cache,
npm_cache_dir,
npm_install_deps_provider, npm_install_deps_provider,
npm_rc,
resolution, resolution,
sys, sys,
tarball_cache, tarball_cache,
@ -314,7 +319,9 @@ pub struct ManagedCliNpmResolver {
maybe_lockfile: Option<Arc<CliLockfile>>, maybe_lockfile: Option<Arc<CliLockfile>>,
registry_info_provider: Arc<CliNpmRegistryInfoProvider>, registry_info_provider: Arc<CliNpmRegistryInfoProvider>,
npm_cache: Arc<CliNpmCache>, npm_cache: Arc<CliNpmCache>,
npm_cache_dir: Arc<NpmCacheDir>,
npm_install_deps_provider: Arc<NpmInstallDepsProvider>, npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
npm_rc: Arc<ResolvedNpmRc>,
sys: CliSys, sys: CliSys,
resolution: Arc<NpmResolution>, resolution: Arc<NpmResolution>,
resolution_installer: NpmResolutionInstaller, resolution_installer: NpmResolutionInstaller,
@ -338,7 +345,7 @@ pub enum ResolvePkgFolderFromPkgIdError {
#[class(inherit)] #[class(inherit)]
#[error("{0}")] #[error("{0}")]
NpmPackageFsResolverPackageFolder( NpmPackageFsResolverPackageFolder(
#[from] resolvers::NpmPackageFsResolverPackageFolderError, #[from] NpmPackageFsResolverPackageFolderError,
), ),
#[class(inherit)] #[class(inherit)]
#[error("{0}")] #[error("{0}")]
@ -363,7 +370,9 @@ impl ManagedCliNpmResolver {
maybe_lockfile: Option<Arc<CliLockfile>>, maybe_lockfile: Option<Arc<CliLockfile>>,
registry_info_provider: Arc<CliNpmRegistryInfoProvider>, registry_info_provider: Arc<CliNpmRegistryInfoProvider>,
npm_cache: Arc<CliNpmCache>, npm_cache: Arc<CliNpmCache>,
npm_cache_dir: Arc<NpmCacheDir>,
npm_install_deps_provider: Arc<NpmInstallDepsProvider>, npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
npm_rc: Arc<ResolvedNpmRc>,
resolution: Arc<NpmResolution>, resolution: Arc<NpmResolution>,
sys: CliSys, sys: CliSys,
tarball_cache: Arc<CliNpmTarballCache>, tarball_cache: Arc<CliNpmTarballCache>,
@ -382,7 +391,9 @@ impl ManagedCliNpmResolver {
maybe_lockfile, maybe_lockfile,
registry_info_provider, registry_info_provider,
npm_cache, npm_cache,
npm_cache_dir,
npm_install_deps_provider, npm_install_deps_provider,
npm_rc,
text_only_progress_bar, text_only_progress_bar,
resolution, resolution,
resolution_installer, resolution_installer,
@ -671,11 +682,11 @@ impl ManagedCliNpmResolver {
} }
pub fn global_cache_root_path(&self) -> &Path { pub fn global_cache_root_path(&self) -> &Path {
self.npm_cache.root_dir_path() self.npm_cache_dir.root_dir()
} }
pub fn global_cache_root_url(&self) -> &Url { pub fn global_cache_root_url(&self) -> &Url {
self.npm_cache.root_dir_url() self.npm_cache_dir.root_dir_url()
} }
} }
@ -772,7 +783,8 @@ impl CliNpmResolver for ManagedCliNpmResolver {
self.lifecycle_scripts.clone(), self.lifecycle_scripts.clone(),
), ),
create_npm_fs_resolver( create_npm_fs_resolver(
self.npm_cache.clone(), &self.npm_cache_dir,
&self.npm_rc,
npm_resolution.clone(), npm_resolution.clone(),
self.sys.clone(), self.sys.clone(),
self.root_node_modules_path().map(ToOwned::to_owned), self.root_node_modules_path().map(ToOwned::to_owned),
@ -780,7 +792,9 @@ impl CliNpmResolver for ManagedCliNpmResolver {
self.maybe_lockfile.clone(), self.maybe_lockfile.clone(),
self.registry_info_provider.clone(), self.registry_info_provider.clone(),
self.npm_cache.clone(), self.npm_cache.clone(),
self.npm_cache_dir.clone(),
self.npm_install_deps_provider.clone(), self.npm_install_deps_provider.clone(),
self.npm_rc.clone(),
npm_resolution, npm_resolution,
self.sys.clone(), self.sys.clone(),
self.tarball_cache.clone(), self.tarball_cache.clone(),

View file

@ -1,33 +0,0 @@
// Copyright 2018-2025 the Deno authors. MIT license.
mod common;
mod global;
mod local;
use std::path::PathBuf;
use std::sync::Arc;
pub use self::common::NpmPackageFsResolver;
pub use self::common::NpmPackageFsResolverPackageFolderError;
use self::global::GlobalNpmPackageResolver;
pub use self::local::get_package_folder_id_folder_name;
use self::local::LocalNpmPackageResolver;
use super::resolution::NpmResolution;
use crate::npm::CliNpmCache;
use crate::sys::CliSys;
pub fn create_npm_fs_resolver(
npm_cache: Arc<CliNpmCache>,
resolution: Arc<NpmResolution>,
sys: CliSys,
maybe_node_modules_path: Option<PathBuf>,
) -> Arc<dyn NpmPackageFsResolver> {
match maybe_node_modules_path {
Some(node_modules_folder) => Arc::new(LocalNpmPackageResolver::new(
resolution,
sys,
node_modules_folder,
)),
None => Arc::new(GlobalNpmPackageResolver::new(npm_cache, resolution)),
}
}

View file

@ -11,6 +11,7 @@ use dashmap::DashMap;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::serde_json; use deno_core::serde_json;
use deno_core::url::Url; use deno_core::url::Url;
use deno_error::JsErrorBox;
use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::npm_rc::ResolvedNpmRc;
use deno_npm::registry::NpmPackageInfo; use deno_npm::registry::NpmPackageInfo;
use deno_resolver::npm::ByonmInNpmPackageChecker; use deno_resolver::npm::ByonmInNpmPackageChecker;
@ -100,7 +101,7 @@ impl deno_npm_cache::NpmCacheHttpClient for CliNpmCacheHttpClient {
}; };
deno_npm_cache::DownloadError { deno_npm_cache::DownloadError {
status_code, status_code,
error: err.into(), error: JsErrorBox::from_err(err),
} }
}) })
} }

View file

@ -18,18 +18,20 @@ sync = ["dashmap"]
[dependencies] [dependencies]
anyhow.workspace = true anyhow.workspace = true
async-trait.workspace = true
base32.workspace = true base32.workspace = true
boxed_error.workspace = true boxed_error.workspace = true
dashmap = { workspace = true, optional = true } dashmap = { workspace = true, optional = true }
deno_cache_dir.workspace = true
deno_config.workspace = true deno_config.workspace = true
deno_error.workspace = true deno_error.workspace = true
deno_media_type.workspace = true deno_media_type.workspace = true
deno_package_json.workspace = true deno_npm.workspace = true
deno_package_json.features = ["sync"] deno_package_json = { workspace = true, features = ["sync"] }
deno_path_util.workspace = true deno_path_util.workspace = true
deno_semver.workspace = true deno_semver.workspace = true
node_resolver.workspace = true node_resolver = { workspace = true, features = ["sync"] }
node_resolver.features = ["sync"] parking_lot.workspace = true
sys_traits.workspace = true sys_traits.workspace = true
thiserror.workspace = true thiserror.workspace = true
url.workspace = true url.workspace = true

View file

@ -6,12 +6,14 @@
use std::path::PathBuf; use std::path::PathBuf;
use boxed_error::Boxed; use boxed_error::Boxed;
use deno_cache_dir::npm::NpmCacheDir;
use deno_config::workspace::MappedResolution; use deno_config::workspace::MappedResolution;
use deno_config::workspace::MappedResolutionDiagnostic; use deno_config::workspace::MappedResolutionDiagnostic;
use deno_config::workspace::MappedResolutionError; use deno_config::workspace::MappedResolutionError;
use deno_config::workspace::WorkspaceResolvePkgJsonFolderError; use deno_config::workspace::WorkspaceResolvePkgJsonFolderError;
use deno_config::workspace::WorkspaceResolver; use deno_config::workspace::WorkspaceResolver;
use deno_error::JsError; use deno_error::JsError;
use deno_npm::npm_rc::ResolvedNpmRc;
use deno_package_json::PackageJsonDepValue; use deno_package_json::PackageJsonDepValue;
use deno_package_json::PackageJsonDepValueParseError; use deno_package_json::PackageJsonDepValueParseError;
use deno_semver::npm::NpmPackageReqReference; use deno_semver::npm::NpmPackageReqReference;
@ -47,6 +49,12 @@ mod sync;
#[allow(clippy::disallowed_types)] #[allow(clippy::disallowed_types)]
pub type WorkspaceResolverRc = crate::sync::MaybeArc<WorkspaceResolver>; pub type WorkspaceResolverRc = crate::sync::MaybeArc<WorkspaceResolver>;
#[allow(clippy::disallowed_types)]
pub(crate) type ResolvedNpmRcRc = crate::sync::MaybeArc<ResolvedNpmRc>;
#[allow(clippy::disallowed_types)]
pub(crate) type NpmCacheDirRc = crate::sync::MaybeArc<NpmCacheDir>;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DenoResolution { pub struct DenoResolution {
pub url: Url, pub url: Url,

View file

@ -2,6 +2,58 @@
use std::borrow::Cow; use std::borrow::Cow;
use deno_cache_dir::npm::mixed_case_package_name_decode;
use deno_npm::NpmPackageCacheFolderId;
use deno_semver::package::PackageNv;
use deno_semver::StackString;
#[inline]
pub fn get_package_folder_id_folder_name(
folder_id: &NpmPackageCacheFolderId,
) -> String {
get_package_folder_id_folder_name_from_parts(
&folder_id.nv,
folder_id.copy_index,
)
}
pub fn get_package_folder_id_folder_name_from_parts(
nv: &PackageNv,
copy_index: u8,
) -> String {
let copy_str = if copy_index == 0 {
Cow::Borrowed("")
} else {
Cow::Owned(format!("_{}", copy_index))
};
let name = normalize_pkg_name_for_node_modules_deno_folder(&nv.name);
format!("{}@{}{}", name, nv.version, copy_str)
}
pub fn get_package_folder_id_from_folder_name(
folder_name: &str,
) -> Option<NpmPackageCacheFolderId> {
let folder_name = folder_name.replace('+', "/");
let (name, ending) = folder_name.rsplit_once('@')?;
let name: StackString = if let Some(encoded_name) = name.strip_prefix('_') {
StackString::from_string(mixed_case_package_name_decode(encoded_name)?)
} else {
name.into()
};
let (raw_version, copy_index) = match ending.split_once('_') {
Some((raw_version, copy_index)) => {
let copy_index = copy_index.parse::<u8>().ok()?;
(raw_version, copy_index)
}
None => (ending, 0),
};
let version = deno_semver::Version::parse_from_npm(raw_version).ok()?;
Some(NpmPackageCacheFolderId {
nv: PackageNv { name, version },
copy_index,
})
}
/// Normalizes a package name for use at `node_modules/.deno/<pkg-name>@<version>[_<copy_index>]` /// Normalizes a package name for use at `node_modules/.deno/<pkg-name>@<version>[_<copy_index>]`
pub fn normalize_pkg_name_for_node_modules_deno_folder(name: &str) -> Cow<str> { pub fn normalize_pkg_name_for_node_modules_deno_folder(name: &str) -> Cow<str> {
let name = if name.to_lowercase() == name { let name = if name.to_lowercase() == name {
@ -25,3 +77,36 @@ fn mixed_case_package_name_encode(name: &str) -> String {
) )
.to_lowercase() .to_lowercase()
} }
#[cfg(test)]
mod test {
use deno_npm::NpmPackageCacheFolderId;
use deno_semver::package::PackageNv;
use super::*;
#[test]
fn test_get_package_folder_id_folder_name() {
let cases = vec![
(
NpmPackageCacheFolderId {
nv: PackageNv::from_str("@types/foo@1.2.3").unwrap(),
copy_index: 1,
},
"@types+foo@1.2.3_1".to_string(),
),
(
NpmPackageCacheFolderId {
nv: PackageNv::from_str("JSON@3.2.1").unwrap(),
copy_index: 0,
},
"_jjju6tq@3.2.1".to_string(),
),
];
for (input, output) in cases {
assert_eq!(get_package_folder_id_folder_name(&input), output);
let folder_id = get_package_folder_id_from_folder_name(&output).unwrap();
assert_eq!(folder_id, input);
}
}
}

View file

@ -4,10 +4,14 @@ use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use async_trait::async_trait; use async_trait::async_trait;
use deno_ast::ModuleSpecifier;
use deno_npm::NpmPackageCacheFolderId; use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId; use deno_npm::NpmPackageId;
use node_resolver::errors::PackageFolderResolveError; use node_resolver::errors::PackageFolderResolveError;
use url::Url;
#[allow(clippy::disallowed_types)]
pub(super) type NpmPackageFsResolverRc =
crate::sync::MaybeArc<dyn NpmPackageFsResolver>;
#[derive(Debug, thiserror::Error, deno_error::JsError)] #[derive(Debug, thiserror::Error, deno_error::JsError)]
#[class(generic)] #[class(generic)]
@ -34,11 +38,11 @@ pub trait NpmPackageFsResolver: Send + Sync {
fn resolve_package_folder_from_package( fn resolve_package_folder_from_package(
&self, &self,
name: &str, name: &str,
referrer: &ModuleSpecifier, referrer: &Url,
) -> Result<PathBuf, PackageFolderResolveError>; ) -> Result<PathBuf, PackageFolderResolveError>;
fn resolve_package_cache_folder_id_from_specifier( fn resolve_package_cache_folder_id_from_specifier(
&self, &self,
specifier: &ModuleSpecifier, specifier: &Url,
) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error>; ) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error>;
} }

View file

@ -4,30 +4,60 @@
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc;
use async_trait::async_trait; use async_trait::async_trait;
use deno_ast::ModuleSpecifier;
use deno_npm::NpmPackageCacheFolderId; use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId; use deno_npm::NpmPackageId;
use deno_semver::package::PackageNv;
use deno_semver::StackString;
use deno_semver::Version;
use node_resolver::errors::PackageFolderResolveError; use node_resolver::errors::PackageFolderResolveError;
use node_resolver::errors::PackageNotFoundError; use node_resolver::errors::PackageNotFoundError;
use node_resolver::errors::ReferrerNotFoundError; use node_resolver::errors::ReferrerNotFoundError;
use url::Url;
use super::super::resolution::NpmResolution; use super::resolution::NpmResolutionRc;
use super::common::NpmPackageFsResolver; use super::NpmCacheDirRc;
use crate::npm::CliNpmCache; use super::NpmPackageFsResolver;
use crate::ResolvedNpmRcRc;
/// Resolves packages from the global npm cache. /// Resolves packages from the global npm cache.
#[derive(Debug)] #[derive(Debug)]
pub struct GlobalNpmPackageResolver { pub struct GlobalNpmPackageResolver {
cache: Arc<CliNpmCache>, cache: NpmCacheDirRc,
resolution: Arc<NpmResolution>, npm_rc: ResolvedNpmRcRc,
resolution: NpmResolutionRc,
} }
impl GlobalNpmPackageResolver { impl GlobalNpmPackageResolver {
pub fn new(cache: Arc<CliNpmCache>, resolution: Arc<NpmResolution>) -> Self { pub fn new(
Self { cache, resolution } cache: NpmCacheDirRc,
npm_rc: ResolvedNpmRcRc,
resolution: NpmResolutionRc,
) -> Self {
Self {
cache,
npm_rc,
resolution,
}
}
fn resolve_package_cache_folder_id_from_specifier_inner(
&self,
specifier: &Url,
) -> Option<NpmPackageCacheFolderId> {
self
.cache
.resolve_package_folder_id_from_specifier(specifier)
.and_then(|cache_id| {
Some(NpmPackageCacheFolderId {
nv: PackageNv {
name: StackString::from_string(cache_id.name),
version: Version::parse_from_npm(&cache_id.version).ok()?,
},
copy_index: cache_id.copy_index,
})
})
} }
} }
@ -38,21 +68,26 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
} }
fn maybe_package_folder(&self, id: &NpmPackageId) -> Option<PathBuf> { fn maybe_package_folder(&self, id: &NpmPackageId) -> Option<PathBuf> {
let folder_id = self let folder_copy_index = self
.resolution .resolution
.resolve_pkg_cache_folder_id_from_pkg_id(id)?; .resolve_pkg_cache_folder_copy_index_from_pkg_id(id)?;
Some(self.cache.package_folder_for_id(&folder_id)) let registry_url = self.npm_rc.get_registry_url(&id.nv.name);
Some(self.cache.package_folder_for_id(
&id.nv.name,
&id.nv.version.to_string(),
folder_copy_index,
registry_url,
))
} }
fn resolve_package_folder_from_package( fn resolve_package_folder_from_package(
&self, &self,
name: &str, name: &str,
referrer: &ModuleSpecifier, referrer: &Url,
) -> Result<PathBuf, PackageFolderResolveError> { ) -> Result<PathBuf, PackageFolderResolveError> {
use deno_npm::resolution::PackageNotFoundFromReferrerError; use deno_npm::resolution::PackageNotFoundFromReferrerError;
let Some(referrer_cache_folder_id) = self let Some(referrer_cache_folder_id) =
.cache self.resolve_package_cache_folder_id_from_specifier_inner(referrer)
.resolve_package_folder_id_from_specifier(referrer)
else { else {
return Err( return Err(
ReferrerNotFoundError { ReferrerNotFoundError {
@ -106,12 +141,8 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
fn resolve_package_cache_folder_id_from_specifier( fn resolve_package_cache_folder_id_from_specifier(
&self, &self,
specifier: &ModuleSpecifier, specifier: &Url,
) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error> { ) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error> {
Ok( Ok(self.resolve_package_cache_folder_id_from_specifier_inner(specifier))
self
.cache
.resolve_package_folder_id_from_specifier(specifier),
)
} }
} }

View file

@ -5,49 +5,50 @@
use std::borrow::Cow; use std::borrow::Cow;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc;
use async_trait::async_trait; use async_trait::async_trait;
use deno_ast::ModuleSpecifier;
use deno_cache_dir::npm::mixed_case_package_name_decode;
use deno_core::url::Url;
use deno_npm::NpmPackageCacheFolderId; use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId; use deno_npm::NpmPackageId;
use deno_path_util::fs::canonicalize_path_maybe_not_exists; use deno_path_util::fs::canonicalize_path_maybe_not_exists;
use deno_resolver::npm::normalize_pkg_name_for_node_modules_deno_folder; use deno_path_util::url_from_directory_path;
use deno_semver::package::PackageNv;
use deno_semver::StackString;
use node_resolver::errors::PackageFolderResolveError; use node_resolver::errors::PackageFolderResolveError;
use node_resolver::errors::PackageFolderResolveIoError; use node_resolver::errors::PackageFolderResolveIoError;
use node_resolver::errors::PackageNotFoundError; use node_resolver::errors::PackageNotFoundError;
use node_resolver::errors::ReferrerNotFoundError; use node_resolver::errors::ReferrerNotFoundError;
use sys_traits::FsCanonicalize;
use sys_traits::FsMetadata; use sys_traits::FsMetadata;
use url::Url;
use super::super::resolution::NpmResolution; use super::resolution::NpmResolutionRc;
use super::common::NpmPackageFsResolver; use super::NpmPackageFsResolver;
use crate::sys::CliSys; use crate::npm::local::get_package_folder_id_folder_name_from_parts;
use crate::npm::local::get_package_folder_id_from_folder_name;
/// Resolver that creates a local node_modules directory /// Resolver that creates a local node_modules directory
/// and resolves packages from it. /// and resolves packages from it.
#[derive(Debug)] #[derive(Debug)]
pub struct LocalNpmPackageResolver { pub struct LocalNpmPackageResolver<
resolution: Arc<NpmResolution>, TSys: FsCanonicalize + FsMetadata + Send + Sync,
sys: CliSys, > {
resolution: NpmResolutionRc,
sys: TSys,
root_node_modules_path: PathBuf, root_node_modules_path: PathBuf,
root_node_modules_url: Url, root_node_modules_url: Url,
} }
impl LocalNpmPackageResolver { impl<TSys: FsCanonicalize + FsMetadata + Send + Sync>
LocalNpmPackageResolver<TSys>
{
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
resolution: Arc<NpmResolution>, resolution: NpmResolutionRc,
sys: CliSys, sys: TSys,
node_modules_folder: PathBuf, node_modules_folder: PathBuf,
) -> Self { ) -> Self {
Self { Self {
resolution, resolution,
sys, sys,
root_node_modules_url: Url::from_directory_path(&node_modules_folder) root_node_modules_url: url_from_directory_path(&node_modules_folder)
.unwrap(), .unwrap(),
root_node_modules_path: node_modules_folder, root_node_modules_path: node_modules_folder,
} }
@ -67,7 +68,7 @@ impl LocalNpmPackageResolver {
fn resolve_folder_for_specifier( fn resolve_folder_for_specifier(
&self, &self,
specifier: &ModuleSpecifier, specifier: &Url,
) -> Result<Option<PathBuf>, std::io::Error> { ) -> Result<Option<PathBuf>, std::io::Error> {
let Some(relative_url) = let Some(relative_url) =
self.root_node_modules_url.make_relative(specifier) self.root_node_modules_url.make_relative(specifier)
@ -78,7 +79,7 @@ impl LocalNpmPackageResolver {
return Ok(None); return Ok(None);
} }
// it's within the directory, so use it // it's within the directory, so use it
let Some(path) = specifier.to_file_path().ok() else { let Some(path) = deno_path_util::url_to_file_path(specifier).ok() else {
return Ok(None); return Ok(None);
}; };
// Canonicalize the path so it's not pointing to the symlinked directory // Canonicalize the path so it's not pointing to the symlinked directory
@ -88,7 +89,7 @@ impl LocalNpmPackageResolver {
fn resolve_package_folder_from_specifier( fn resolve_package_folder_from_specifier(
&self, &self,
specifier: &ModuleSpecifier, specifier: &Url,
) -> Result<Option<PathBuf>, std::io::Error> { ) -> Result<Option<PathBuf>, std::io::Error> {
let Some(local_path) = self.resolve_folder_for_specifier(specifier)? else { let Some(local_path) = self.resolve_folder_for_specifier(specifier)? else {
return Ok(None); return Ok(None);
@ -99,31 +100,36 @@ impl LocalNpmPackageResolver {
} }
#[async_trait(?Send)] #[async_trait(?Send)]
impl NpmPackageFsResolver for LocalNpmPackageResolver { impl<TSys: FsCanonicalize + FsMetadata + Send + Sync> NpmPackageFsResolver
for LocalNpmPackageResolver<TSys>
{
fn node_modules_path(&self) -> Option<&Path> { fn node_modules_path(&self) -> Option<&Path> {
Some(self.root_node_modules_path.as_ref()) Some(self.root_node_modules_path.as_ref())
} }
fn maybe_package_folder(&self, id: &NpmPackageId) -> Option<PathBuf> { fn maybe_package_folder(&self, id: &NpmPackageId) -> Option<PathBuf> {
let cache_folder_id = self let folder_copy_index = self
.resolution .resolution
.resolve_pkg_cache_folder_id_from_pkg_id(id)?; .resolve_pkg_cache_folder_copy_index_from_pkg_id(id)?;
// package is stored at: // package is stored at:
// node_modules/.deno/<package_cache_folder_id_folder_name>/node_modules/<package_name> // node_modules/.deno/<package_cache_folder_id_folder_name>/node_modules/<package_name>
Some( Some(
self self
.root_node_modules_path .root_node_modules_path
.join(".deno") .join(".deno")
.join(get_package_folder_id_folder_name(&cache_folder_id)) .join(get_package_folder_id_folder_name_from_parts(
&id.nv,
folder_copy_index,
))
.join("node_modules") .join("node_modules")
.join(&cache_folder_id.nv.name), .join(&id.nv.name),
) )
} }
fn resolve_package_folder_from_package( fn resolve_package_folder_from_package(
&self, &self,
name: &str, name: &str,
referrer: &ModuleSpecifier, referrer: &Url,
) -> Result<PathBuf, PackageFolderResolveError> { ) -> Result<PathBuf, PackageFolderResolveError> {
let maybe_local_path = self let maybe_local_path = self
.resolve_folder_for_specifier(referrer) .resolve_folder_for_specifier(referrer)
@ -173,7 +179,7 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
fn resolve_package_cache_folder_id_from_specifier( fn resolve_package_cache_folder_id_from_specifier(
&self, &self,
specifier: &ModuleSpecifier, specifier: &Url,
) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error> { ) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error> {
let Some(folder_path) = let Some(folder_path) =
self.resolve_package_folder_from_specifier(specifier)? self.resolve_package_folder_from_specifier(specifier)?
@ -198,43 +204,6 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
} }
} }
pub fn get_package_folder_id_folder_name(
folder_id: &NpmPackageCacheFolderId,
) -> String {
let copy_str = if folder_id.copy_index == 0 {
Cow::Borrowed("")
} else {
Cow::Owned(format!("_{}", folder_id.copy_index))
};
let nv = &folder_id.nv;
let name = normalize_pkg_name_for_node_modules_deno_folder(&nv.name);
format!("{}@{}{}", name, nv.version, copy_str)
}
fn get_package_folder_id_from_folder_name(
folder_name: &str,
) -> Option<NpmPackageCacheFolderId> {
let folder_name = folder_name.replace('+', "/");
let (name, ending) = folder_name.rsplit_once('@')?;
let name: StackString = if let Some(encoded_name) = name.strip_prefix('_') {
StackString::from_string(mixed_case_package_name_decode(encoded_name)?)
} else {
name.into()
};
let (raw_version, copy_index) = match ending.split_once('_') {
Some((raw_version, copy_index)) => {
let copy_index = copy_index.parse::<u8>().ok()?;
(raw_version, copy_index)
}
None => (ending, 0),
};
let version = deno_semver::Version::parse_from_npm(raw_version).ok()?;
Some(NpmPackageCacheFolderId {
nv: PackageNv { name, version },
copy_index,
})
}
fn join_package_name(path: &Path, package_name: &str) -> PathBuf { fn join_package_name(path: &Path, package_name: &str) -> PathBuf {
let mut path = path.to_path_buf(); let mut path = path.to_path_buf();
// ensure backslashes are used on windows // ensure backslashes are used on windows
@ -243,36 +212,3 @@ fn join_package_name(path: &Path, package_name: &str) -> PathBuf {
} }
path path
} }
#[cfg(test)]
mod test {
use deno_npm::NpmPackageCacheFolderId;
use deno_semver::package::PackageNv;
use super::*;
#[test]
fn test_get_package_folder_id_folder_name() {
let cases = vec![
(
NpmPackageCacheFolderId {
nv: PackageNv::from_str("@types/foo@1.2.3").unwrap(),
copy_index: 1,
},
"@types+foo@1.2.3_1".to_string(),
),
(
NpmPackageCacheFolderId {
nv: PackageNv::from_str("JSON@3.2.1").unwrap(),
copy_index: 0,
},
"_jjju6tq@3.2.1".to_string(),
),
];
for (input, output) in cases {
assert_eq!(get_package_folder_id_folder_name(&input), output);
let folder_id = get_package_folder_id_from_folder_name(&output).unwrap();
assert_eq!(folder_id, input);
}
}
}

View file

@ -0,0 +1,45 @@
// Copyright 2018-2025 the Deno authors. MIT license.
mod common;
mod global;
mod local;
mod resolution;
use std::path::PathBuf;
use sys_traits::FsCanonicalize;
use sys_traits::FsMetadata;
pub use self::common::NpmPackageFsResolver;
pub use self::common::NpmPackageFsResolverPackageFolderError;
use self::common::NpmPackageFsResolverRc;
use self::global::GlobalNpmPackageResolver;
use self::local::LocalNpmPackageResolver;
pub use self::resolution::NpmResolution;
use self::resolution::NpmResolutionRc;
use crate::sync::new_rc;
use crate::NpmCacheDirRc;
use crate::ResolvedNpmRcRc;
pub fn create_npm_fs_resolver<
TSys: FsCanonicalize + FsMetadata + Send + Sync + 'static,
>(
npm_cache_dir: &NpmCacheDirRc,
npm_rc: &ResolvedNpmRcRc,
resolution: NpmResolutionRc,
sys: TSys,
maybe_node_modules_path: Option<PathBuf>,
) -> NpmPackageFsResolverRc {
match maybe_node_modules_path {
Some(node_modules_folder) => new_rc(LocalNpmPackageResolver::new(
resolution,
sys,
node_modules_folder,
)),
None => new_rc(GlobalNpmPackageResolver::new(
npm_cache_dir.clone(),
npm_rc.clone(),
resolution,
)),
}
}

View file

@ -2,7 +2,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use deno_core::parking_lot::RwLock;
use deno_npm::resolution::NpmPackagesPartitioned; use deno_npm::resolution::NpmPackagesPartitioned;
use deno_npm::resolution::NpmResolutionSnapshot; use deno_npm::resolution::NpmResolutionSnapshot;
use deno_npm::resolution::PackageCacheFolderIdNotFoundError; use deno_npm::resolution::PackageCacheFolderIdNotFoundError;
@ -16,10 +15,12 @@ use deno_npm::NpmResolutionPackage;
use deno_npm::NpmSystemInfo; use deno_npm::NpmSystemInfo;
use deno_semver::package::PackageNv; use deno_semver::package::PackageNv;
use deno_semver::package::PackageReq; use deno_semver::package::PackageReq;
use parking_lot::RwLock;
/// Handles updating and storing npm resolution in memory where the underlying #[allow(clippy::disallowed_types)]
/// snapshot can be updated concurrently. Additionally handles updating the lockfile pub(super) type NpmResolutionRc = crate::sync::MaybeArc<NpmResolution>;
/// based on changes to the resolution.
/// Handles updating and storing npm resolution in memory.
/// ///
/// This does not interact with the file system. /// This does not interact with the file system.
pub struct NpmResolution { pub struct NpmResolution {
@ -50,15 +51,15 @@ impl NpmResolution {
} }
} }
pub fn resolve_pkg_cache_folder_id_from_pkg_id( pub fn resolve_pkg_cache_folder_copy_index_from_pkg_id(
&self, &self,
id: &NpmPackageId, id: &NpmPackageId,
) -> Option<NpmPackageCacheFolderId> { ) -> Option<u8> {
self self
.snapshot .snapshot
.read() .read()
.package_from_id(id) .package_from_id(id)
.map(|p| p.get_package_cache_folder_id()) .map(|p| p.copy_index)
} }
pub fn resolve_pkg_id_from_pkg_cache_folder_id( pub fn resolve_pkg_id_from_pkg_cache_folder_id(

View file

@ -4,15 +4,9 @@ use std::fmt::Debug;
use std::path::PathBuf; use std::path::PathBuf;
use boxed_error::Boxed; use boxed_error::Boxed;
pub use byonm::ByonmInNpmPackageChecker;
pub use byonm::ByonmNpmResolver;
pub use byonm::ByonmNpmResolverCreateOptions;
pub use byonm::ByonmNpmResolverRc;
pub use byonm::ByonmResolvePkgFolderFromDenoReqError;
use deno_error::JsError; use deno_error::JsError;
use deno_semver::npm::NpmPackageReqReference; use deno_semver::npm::NpmPackageReqReference;
use deno_semver::package::PackageReq; use deno_semver::package::PackageReq;
pub use local::normalize_pkg_name_for_node_modules_deno_folder;
use node_resolver::errors::NodeResolveError; use node_resolver::errors::NodeResolveError;
use node_resolver::errors::NodeResolveErrorKind; use node_resolver::errors::NodeResolveErrorKind;
use node_resolver::errors::PackageFolderResolveErrorKind; use node_resolver::errors::PackageFolderResolveErrorKind;
@ -33,8 +27,17 @@ use sys_traits::FsReadDir;
use thiserror::Error; use thiserror::Error;
use url::Url; use url::Url;
pub use self::byonm::ByonmInNpmPackageChecker;
pub use self::byonm::ByonmNpmResolver;
pub use self::byonm::ByonmNpmResolverCreateOptions;
pub use self::byonm::ByonmNpmResolverRc;
pub use self::byonm::ByonmResolvePkgFolderFromDenoReqError;
pub use self::local::get_package_folder_id_folder_name;
pub use self::local::normalize_pkg_name_for_node_modules_deno_folder;
mod byonm; mod byonm;
mod local; mod local;
pub mod managed;
#[derive(Debug, Error, JsError)] #[derive(Debug, Error, JsError)]
#[class(generic)] #[class(generic)]

View file

@ -46,3 +46,9 @@ mod inner {
} }
} }
} }
#[allow(clippy::disallowed_types)]
#[inline]
pub fn new_rc<T>(value: T) -> MaybeArc<T> {
MaybeArc::new(value)
}

View file

@ -14,11 +14,6 @@ description = "Helpers for downloading and caching npm dependencies for Deno"
path = "lib.rs" path = "lib.rs"
[dependencies] [dependencies]
# todo(dsherret): remove this dependency
anyhow.workspace = true
# todo(dsherret): remove this dependency
deno_core.workspace = true
async-trait.workspace = true async-trait.workspace = true
base64.workspace = true base64.workspace = true
boxed_error.workspace = true boxed_error.workspace = true

View file

@ -6,7 +6,6 @@ use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use anyhow::Error as AnyError;
use deno_cache_dir::file_fetcher::CacheSetting; use deno_cache_dir::file_fetcher::CacheSetting;
use deno_cache_dir::npm::NpmCacheDir; use deno_cache_dir::npm::NpmCacheDir;
use deno_error::JsErrorBox; use deno_error::JsErrorBox;
@ -51,7 +50,7 @@ pub use tarball::TarballCache;
#[class(generic)] #[class(generic)]
pub struct DownloadError { pub struct DownloadError {
pub status_code: Option<StatusCode>, pub status_code: Option<StatusCode>,
pub error: AnyError, pub error: JsErrorBox,
} }
impl std::error::Error for DownloadError { impl std::error::Error for DownloadError {
@ -312,15 +311,17 @@ impl<
&self, &self,
name: &str, name: &str,
package_info: &NpmPackageInfo, package_info: &NpmPackageInfo,
) -> Result<(), AnyError> { ) -> Result<(), JsErrorBox> {
let file_cache_path = self.get_registry_package_info_file_cache_path(name); let file_cache_path = self.get_registry_package_info_file_cache_path(name);
let file_text = serde_json::to_string(&package_info)?; let file_text =
serde_json::to_string(&package_info).map_err(JsErrorBox::from_err)?;
atomic_write_file_with_retries( atomic_write_file_with_retries(
&self.sys, &self.sys,
&file_cache_path, &file_cache_path,
file_text.as_bytes(), file_text.as_bytes(),
0o644, 0o644,
)?; )
.map_err(JsErrorBox::from_err)?;
Ok(()) Ok(())
} }

View file

@ -5,11 +5,6 @@ use std::collections::HashSet;
use std::sync::Arc; use std::sync::Arc;
use async_trait::async_trait; use async_trait::async_trait;
use deno_core::futures::future::LocalBoxFuture;
use deno_core::futures::FutureExt;
use deno_core::parking_lot::Mutex;
use deno_core::serde_json;
use deno_core::url::Url;
use deno_error::JsErrorBox; use deno_error::JsErrorBox;
use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::npm_rc::ResolvedNpmRc;
use deno_npm::registry::NpmPackageInfo; use deno_npm::registry::NpmPackageInfo;
@ -17,6 +12,9 @@ use deno_npm::registry::NpmRegistryApi;
use deno_npm::registry::NpmRegistryPackageInfoLoadError; use deno_npm::registry::NpmRegistryPackageInfoLoadError;
use deno_unsync::sync::AtomicFlag; use deno_unsync::sync::AtomicFlag;
use deno_unsync::sync::MultiRuntimeAsyncValueCreator; use deno_unsync::sync::MultiRuntimeAsyncValueCreator;
use futures::future::LocalBoxFuture;
use futures::FutureExt;
use parking_lot::Mutex;
use sys_traits::FsCreateDirAll; use sys_traits::FsCreateDirAll;
use sys_traits::FsHardLink; use sys_traits::FsHardLink;
use sys_traits::FsMetadata; use sys_traits::FsMetadata;
@ -26,6 +24,7 @@ use sys_traits::FsRemoveFile;
use sys_traits::FsRename; use sys_traits::FsRename;
use sys_traits::SystemRandom; use sys_traits::SystemRandom;
use sys_traits::ThreadSleep; use sys_traits::ThreadSleep;
use url::Url;
use crate::remote::maybe_auth_header_for_npm_registry; use crate::remote::maybe_auth_header_for_npm_registry;
use crate::NpmCache; use crate::NpmCache;

View file

@ -3,16 +3,15 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use deno_core::futures::future::LocalBoxFuture;
use deno_core::futures::FutureExt;
use deno_core::parking_lot::Mutex;
use deno_core::url::Url;
use deno_error::JsErrorBox; use deno_error::JsErrorBox;
use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::npm_rc::ResolvedNpmRc;
use deno_npm::registry::NpmPackageVersionDistInfo; use deno_npm::registry::NpmPackageVersionDistInfo;
use deno_semver::package::PackageNv; use deno_semver::package::PackageNv;
use deno_unsync::sync::MultiRuntimeAsyncValueCreator; use deno_unsync::sync::MultiRuntimeAsyncValueCreator;
use futures::future::LocalBoxFuture;
use futures::FutureExt;
use http::StatusCode; use http::StatusCode;
use parking_lot::Mutex;
use sys_traits::FsCreateDirAll; use sys_traits::FsCreateDirAll;
use sys_traits::FsHardLink; use sys_traits::FsHardLink;
use sys_traits::FsMetadata; use sys_traits::FsMetadata;
@ -22,6 +21,7 @@ use sys_traits::FsRemoveFile;
use sys_traits::FsRename; use sys_traits::FsRename;
use sys_traits::SystemRandom; use sys_traits::SystemRandom;
use sys_traits::ThreadSleep; use sys_traits::ThreadSleep;
use url::Url;
use crate::remote::maybe_auth_header_for_npm_registry; use crate::remote::maybe_auth_header_for_npm_registry;
use crate::tarball_extract::verify_and_extract_tarball; use crate::tarball_extract::verify_and_extract_tarball;

View file

@ -1,7 +1,5 @@
This crate is a work in progress: This crate is a work in progress:
1. Remove `deno_core` dependency.
1. Remove `anyhow` dependency.
1. Add a clippy.toml file that bans accessing the file system directory and 1. Add a clippy.toml file that bans accessing the file system directory and
instead does it through a trait. instead does it through a trait.
1. Make this crate work in Wasm. 1. Make this crate work in Wasm.