diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/Cargo.toml | 1 | ||||
-rw-r--r-- | cli/npm/mod.rs | 1 | ||||
-rw-r--r-- | cli/npm/resolution/graph.rs | 434 | ||||
-rw-r--r-- | cli/npm/resolution/mod.rs | 214 | ||||
-rw-r--r-- | cli/npm/resolution/snapshot.rs | 49 | ||||
-rw-r--r-- | cli/npm/resolvers/common.rs | 7 | ||||
-rw-r--r-- | cli/npm/resolvers/global.rs | 9 | ||||
-rw-r--r-- | cli/npm/resolvers/local.rs | 9 | ||||
-rw-r--r-- | cli/npm/resolvers/mod.rs | 4 | ||||
-rw-r--r-- | cli/tools/info.rs | 8 |
10 files changed, 493 insertions, 243 deletions
diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 91fbd5bb6..1a5ab72f0 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -99,6 +99,7 @@ shell-escape = "=0.1.5" tar.workspace = true text-size = "=1.1.0" text_lines = "=0.6.0" +thiserror = "=1.0.38" tokio.workspace = true tokio-util.workspace = true tower-lsp = { version = "=0.17.0", features = ["proposed"] } diff --git a/cli/npm/mod.rs b/cli/npm/mod.rs index 7fdf57fbf..4be13707e 100644 --- a/cli/npm/mod.rs +++ b/cli/npm/mod.rs @@ -12,6 +12,7 @@ pub use registry::NpmPackageVersionDistInfo; pub use registry::NpmRegistryApi; pub use registry::RealNpmRegistryApi; pub use resolution::resolve_graph_npm_info; +pub use resolution::NpmPackageNodeId; pub use resolution::NpmResolutionPackage; pub use resolution::NpmResolutionSnapshot; pub use resolvers::NpmPackageResolver; diff --git a/cli/npm/resolution/graph.rs b/cli/npm/resolution/graph.rs index 2f102746a..32c00826b 100644 --- a/cli/npm/resolution/graph.rs +++ b/cli/npm/resolution/graph.rs @@ -13,7 +13,6 @@ use deno_core::error::AnyError; use deno_core::futures; use deno_core::parking_lot::Mutex; use deno_core::parking_lot::MutexGuard; -use deno_graph::npm::NpmPackageId; use deno_graph::npm::NpmPackageReq; use deno_graph::semver::Version; use deno_graph::semver::VersionReq; @@ -29,6 +28,7 @@ use crate::npm::NpmRegistryApi; use super::snapshot::NpmResolutionSnapshot; use super::snapshot::SnapshotPackageCopyIndexResolver; +use super::NpmPackageNodeId; use super::NpmResolutionPackage; pub static LATEST_VERSION_REQ: Lazy<VersionReq> = @@ -47,7 +47,7 @@ struct VisitedVersionsPath { } impl VisitedVersionsPath { - pub fn new(id: &NpmPackageId) -> Arc<Self> { + pub fn new(id: &NpmPackageNodeId) -> Arc<Self> { Arc::new(Self { previous_node: None, visited_version_key: Self::id_to_key(id), @@ -66,7 +66,7 @@ impl VisitedVersionsPath { pub fn with_id( self: &Arc<VisitedVersionsPath>, - id: &NpmPackageId, + id: &NpmPackageNodeId, ) -> Option<Arc<Self>> { if self.has_visited(id) { None @@ -78,7 +78,7 @@ impl VisitedVersionsPath { } } - pub fn has_visited(self: &Arc<Self>, id: &NpmPackageId) -> bool { + pub fn has_visited(self: &Arc<Self>, id: &NpmPackageNodeId) -> bool { let mut maybe_next_node = Some(self); let key = Self::id_to_key(id); while let Some(next_node) = maybe_next_node { @@ -90,7 +90,7 @@ impl VisitedVersionsPath { false } - fn id_to_key(id: &NpmPackageId) -> String { + fn id_to_key(id: &NpmPackageNodeId) -> String { format!("{}@{}", id.name, id.version) } } @@ -128,19 +128,19 @@ enum NodeParent { /// as specified in Deno code. Req, /// A reference to another node, which is a resolved package. - Node(NpmPackageId), + Node(NpmPackageNodeId), } /// A resolved package in the resolution graph. #[derive(Debug)] struct Node { - pub id: NpmPackageId, + pub id: NpmPackageNodeId, /// If the node was forgotten due to having no parents. pub forgotten: bool, // Use BTreeMap and BTreeSet in order to create determinism // when going up and down the tree pub parents: BTreeMap<String, BTreeSet<NodeParent>>, - pub children: BTreeMap<String, NpmPackageId>, + pub children: BTreeMap<String, NpmPackageNodeId>, pub deps: Arc<Vec<NpmDependencyEntry>>, /// Whether the node has demonstrated to have no peer dependencies in its /// descendants. If this is true then we can skip analyzing this node @@ -166,23 +166,23 @@ impl Node { #[derive(Debug, Default)] pub struct Graph { - package_reqs: HashMap<String, NpmPackageId>, - packages_by_name: HashMap<String, Vec<NpmPackageId>>, + package_reqs: HashMap<String, NpmPackageNodeId>, + packages_by_name: HashMap<String, Vec<NpmPackageNodeId>>, // Ideally this value would be Rc<RefCell<Node>>, but we need to use a Mutex // because the lsp requires Send and this code is executed in the lsp. // Would be nice if the lsp wasn't Send. - packages: HashMap<NpmPackageId, Arc<Mutex<Node>>>, + packages: HashMap<NpmPackageNodeId, Arc<Mutex<Node>>>, // This will be set when creating from a snapshot, then // inform the final snapshot creation. - packages_to_copy_index: HashMap<NpmPackageId, usize>, + packages_to_copy_index: HashMap<NpmPackageNodeId, usize>, } impl Graph { pub fn from_snapshot(snapshot: NpmResolutionSnapshot) -> Self { fn fill_for_id( graph: &mut Graph, - id: &NpmPackageId, - packages: &HashMap<NpmPackageId, NpmResolutionPackage>, + id: &NpmPackageNodeId, + packages: &HashMap<NpmPackageNodeId, NpmResolutionPackage>, ) -> Arc<Mutex<Node>> { let resolution = packages.get(id).unwrap(); let (created, node) = graph.get_or_create_for_id(id); @@ -222,7 +222,7 @@ impl Graph { fn get_or_create_for_id( &mut self, - id: &NpmPackageId, + id: &NpmPackageNodeId, ) -> (bool, Arc<Mutex<Node>>) { if let Some(node) = self.packages.get(id) { (false, node.clone()) @@ -245,14 +245,14 @@ impl Graph { } } - fn borrow_node(&self, id: &NpmPackageId) -> MutexGuard<Node> { + fn borrow_node(&self, id: &NpmPackageNodeId) -> MutexGuard<Node> { (**self.packages.get(id).unwrap_or_else(|| { panic!("could not find id {} in the tree", id.as_serialized()) })) .lock() } - fn forget_orphan(&mut self, node_id: &NpmPackageId) { + fn forget_orphan(&mut self, node_id: &NpmPackageNodeId) { if let Some(node) = self.packages.remove(node_id) { let mut node = (*node).lock(); node.forgotten = true; @@ -303,7 +303,7 @@ impl Graph { &mut self, specifier: &str, child: &Mutex<Node>, - parent_id: &NpmPackageId, + parent_id: &NpmPackageNodeId, ) { let mut child = (*child).lock(); assert_ne!(child.id, *parent_id); @@ -325,7 +325,7 @@ impl Graph { fn remove_child_parent( &mut self, specifier: &str, - child_id: &NpmPackageId, + child_id: &NpmPackageNodeId, parent: &NodeParent, ) { match parent { @@ -500,7 +500,7 @@ impl<'a, TNpmRegistryApi: NpmRegistryApi> &mut self, entry: &NpmDependencyEntry, package_info: &NpmPackageInfo, - parent_id: &NpmPackageId, + parent_id: &NpmPackageNodeId, visited_versions: &Arc<VisitedVersionsPath>, ) -> Result<Arc<Mutex<Node>>, AnyError> { let (id, node) = self.resolve_node_from_info( @@ -564,11 +564,11 @@ impl<'a, TNpmRegistryApi: NpmRegistryApi> pkg_req_name: &str, version_req: &VersionReq, package_info: &NpmPackageInfo, - parent_id: Option<&NpmPackageId>, - ) -> Result<(NpmPackageId, Arc<Mutex<Node>>), AnyError> { + parent_id: Option<&NpmPackageNodeId>, + ) -> Result<(NpmPackageNodeId, Arc<Mutex<Node>>), AnyError> { let version_and_info = self.resolve_best_package_version_and_info(version_req, package_info)?; - let id = NpmPackageId { + let id = NpmPackageNodeId { name: package_info.name.to_string(), version: version_and_info.version.clone(), peer_dependencies: Vec::new(), @@ -690,17 +690,17 @@ impl<'a, TNpmRegistryApi: NpmRegistryApi> fn resolve_peer_dep( &mut self, specifier: &str, - parent_id: &NpmPackageId, + parent_id: &NpmPackageNodeId, peer_dep: &NpmDependencyEntry, peer_package_info: &NpmPackageInfo, visited_ancestor_versions: &Arc<VisitedVersionsPath>, - existing_dep_id: Option<&NpmPackageId>, - ) -> Result<Option<NpmPackageId>, AnyError> { + existing_dep_id: Option<&NpmPackageNodeId>, + ) -> Result<Option<NpmPackageNodeId>, AnyError> { fn find_matching_child<'a>( peer_dep: &NpmDependencyEntry, peer_package_info: &NpmPackageInfo, - children: impl Iterator<Item = &'a NpmPackageId>, - ) -> Result<Option<NpmPackageId>, AnyError> { + children: impl Iterator<Item = &'a NpmPackageNodeId>, + ) -> Result<Option<NpmPackageNodeId>, AnyError> { for child_id in children { if child_id.name == peer_dep.name && version_req_satisfies( @@ -863,8 +863,8 @@ impl<'a, TNpmRegistryApi: NpmRegistryApi> /// the entire sub tree. fn set_previously_unresolved_optional_dependency( &mut self, - peer_dep_id: &NpmPackageId, - parent_id: &NpmPackageId, + peer_dep_id: &NpmPackageNodeId, + parent_id: &NpmPackageNodeId, peer_dep: &NpmDependencyEntry, visited_ancestor_versions: &Arc<VisitedVersionsPath>, ) { @@ -881,11 +881,11 @@ impl<'a, TNpmRegistryApi: NpmRegistryApi> fn set_new_peer_dep( &mut self, previous_parents: BTreeMap<String, BTreeSet<NodeParent>>, - node_id: &NpmPackageId, - peer_dep_id: &NpmPackageId, + node_id: &NpmPackageNodeId, + peer_dep_id: &NpmPackageNodeId, path: &Arc<GraphSpecifierPath>, visited_ancestor_versions: &Arc<VisitedVersionsPath>, - ) -> NpmPackageId { + ) -> NpmPackageNodeId { let peer_dep_id = Cow::Borrowed(peer_dep_id); let old_id = node_id; let (new_id, mut old_node_children) = @@ -1008,7 +1008,7 @@ struct VersionAndInfo<'a> { fn get_resolved_package_version_and_info<'a>( version_req: &VersionReq, info: &'a NpmPackageInfo, - parent: Option<&NpmPackageId>, + parent: Option<&NpmPackageNodeId>, ) -> Result<VersionAndInfo<'a>, AnyError> { if let Some(tag) = version_req.tag() { tag_to_version_info(info, tag, parent) @@ -1061,7 +1061,7 @@ fn version_req_satisfies( version_req: &VersionReq, version: &Version, package_info: &NpmPackageInfo, - parent: Option<&NpmPackageId>, + parent: Option<&NpmPackageNodeId>, ) -> Result<bool, AnyError> { match version_req.tag() { Some(tag) => { @@ -1075,7 +1075,7 @@ fn version_req_satisfies( fn tag_to_version_info<'a>( info: &'a NpmPackageInfo, tag: &str, - parent: Option<&NpmPackageId>, + parent: Option<&NpmPackageNodeId>, ) -> Result<VersionAndInfo<'a>, AnyError> { // For when someone just specifies @types/node, we want to pull in a // "known good" version of @types/node that works well with Deno and @@ -1196,37 +1196,37 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([ ( "package-b".to_string(), - NpmPackageId::from_serialized("package-b@2.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-b@2.0.0").unwrap(), ), ( "package-c".to_string(), - NpmPackageId::from_serialized("package-c@0.1.0").unwrap(), + NpmPackageNodeId::from_serialized("package-c@0.1.0").unwrap(), ), ]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-b@2.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-b@2.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-c@0.1.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-c@0.1.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::from([( "package-d".to_string(), - NpmPackageId::from_serialized("package-d@3.2.1").unwrap(), + NpmPackageNodeId::from_serialized("package-d@3.2.1").unwrap(), )]) }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-d@3.2.1").unwrap(), + id: NpmPackageNodeId::from_serialized("package-d@3.2.1").unwrap(), copy_index: 0, dist: Default::default(), dependencies: Default::default(), @@ -1253,20 +1253,20 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-b".to_string(), - NpmPackageId::from_serialized("package-b@2.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-b@2.0.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-b@2.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-b@2.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-a".to_string(), - NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), )]), dist: Default::default(), }, @@ -1302,7 +1302,7 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-a@1.0.0_package-peer@4.0.0" ) .unwrap(), @@ -1310,14 +1310,14 @@ mod test { dependencies: HashMap::from([ ( "package-b".to_string(), - NpmPackageId::from_serialized( + NpmPackageNodeId::from_serialized( "package-b@2.0.0_package-peer@4.0.0" ) .unwrap(), ), ( "package-c".to_string(), - NpmPackageId::from_serialized( + NpmPackageNodeId::from_serialized( "package-c@3.0.0_package-peer@4.0.0" ) .unwrap(), @@ -1326,7 +1326,7 @@ mod test { dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-b@2.0.0_package-peer@4.0.0" ) .unwrap(), @@ -1334,11 +1334,11 @@ mod test { dist: Default::default(), dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@4.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@4.0.0").unwrap(), )]) }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-c@3.0.0_package-peer@4.0.0" ) .unwrap(), @@ -1346,11 +1346,11 @@ mod test { dist: Default::default(), dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@4.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@4.0.0").unwrap(), )]) }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@4.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@4.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: Default::default(), @@ -1396,17 +1396,19 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-0@1.1.1").unwrap(), + id: NpmPackageNodeId::from_serialized("package-0@1.1.1").unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-a".to_string(), - NpmPackageId::from_serialized("package-a@1.0.0_package-peer@4.0.0") - .unwrap(), + NpmPackageNodeId::from_serialized( + "package-a@1.0.0_package-peer@4.0.0" + ) + .unwrap(), ),]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-a@1.0.0_package-peer@4.0.0" ) .unwrap(), @@ -1414,27 +1416,27 @@ mod test { dependencies: HashMap::from([ ( "package-b".to_string(), - NpmPackageId::from_serialized( + NpmPackageNodeId::from_serialized( "package-b@2.0.0_package-peer@4.0.0" ) .unwrap(), ), ( "package-c".to_string(), - NpmPackageId::from_serialized( + NpmPackageNodeId::from_serialized( "package-c@3.0.0_package-peer@4.0.0" ) .unwrap(), ), ( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@4.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@4.0.0").unwrap(), ), ]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-b@2.0.0_package-peer@4.0.0" ) .unwrap(), @@ -1442,11 +1444,11 @@ mod test { dist: Default::default(), dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@4.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@4.0.0").unwrap(), )]) }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-c@3.0.0_package-peer@4.0.0" ) .unwrap(), @@ -1454,11 +1456,11 @@ mod test { dist: Default::default(), dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@4.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@4.0.0").unwrap(), )]) }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@4.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@4.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: Default::default(), @@ -1492,40 +1494,40 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([ ( "package-b".to_string(), - NpmPackageId::from_serialized("package-b@2.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-b@2.0.0").unwrap(), ), ( "package-c".to_string(), - NpmPackageId::from_serialized("package-c@3.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-c@3.0.0").unwrap(), ), ]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-b@2.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-b@2.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@4.1.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@4.1.0").unwrap(), )]) }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-c@3.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-c@3.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@4.1.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@4.1.0").unwrap(), )]) }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@4.1.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@4.1.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: Default::default(), @@ -1565,28 +1567,28 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([ ( "package-b".to_string(), - NpmPackageId::from_serialized("package-b@2.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-b@2.0.0").unwrap(), ), ( "package-c".to_string(), - NpmPackageId::from_serialized("package-c@3.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-c@3.0.0").unwrap(), ), ]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-b@2.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-b@2.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::new(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-c@3.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-c@3.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::new(), @@ -1627,40 +1629,40 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([ ( "package-b".to_string(), - NpmPackageId::from_serialized("package-b@2.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-b@2.0.0").unwrap(), ), ( "package-c".to_string(), - NpmPackageId::from_serialized("package-c@3.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-c@3.0.0").unwrap(), ), ]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-b@2.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-b@2.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@4.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@4.0.0").unwrap(), )]) }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-c@3.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-c@3.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@4.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@4.0.0").unwrap(), )]) }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@4.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@4.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: Default::default(), @@ -1705,31 +1707,31 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([ ( "package-b".to_string(), - NpmPackageId::from_serialized("package-b@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-b@1.0.0").unwrap(), ), ( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@1.0.0").unwrap(), ), ]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-b@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-b@1.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@1.0.0").unwrap(), )]), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@1.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::new(), @@ -1768,31 +1770,31 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@2.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@2.0.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-b@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-b@1.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::from([ ( "package-a".to_string(), - NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), ), ( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@2.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@2.0.0").unwrap(), ) ]), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@2.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@2.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::new(), @@ -1827,16 +1829,16 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@1.0.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@1.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::new(), @@ -1882,28 +1884,28 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@1.0.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-a@1.0.0_package-peer@2.0.0" ) .unwrap(), copy_index: 1, dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@2.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@2.0.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-b@1.0.0_package-peer@2.0.0" ) .unwrap(), @@ -1912,11 +1914,11 @@ mod test { dependencies: HashMap::from([ ( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@2.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@2.0.0").unwrap(), ), ( "package-a".to_string(), - NpmPackageId::from_serialized( + NpmPackageNodeId::from_serialized( "package-a@1.0.0_package-peer@2.0.0" ) .unwrap(), @@ -1924,13 +1926,13 @@ mod test { ]), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@1.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::new(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@2.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@2.0.0").unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::new(), @@ -1971,25 +1973,27 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-0@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-0@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-peer-a".to_string(), - NpmPackageId::from_serialized("package-peer-a@2.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer-a@2.0.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer-a@2.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer-a@2.0.0") + .unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-peer-b".to_string(), - NpmPackageId::from_serialized("package-peer-b@3.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer-b@3.0.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer-b@3.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer-b@3.0.0") + .unwrap(), copy_index: 0, dependencies: HashMap::new(), dist: Default::default(), @@ -2028,7 +2032,7 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-0@1.0.0_package-peer-a@2.0.0_package-peer-b@3.0.0" ) .unwrap(), @@ -2036,32 +2040,34 @@ mod test { dependencies: HashMap::from([ ( "package-peer-a".to_string(), - NpmPackageId::from_serialized( + NpmPackageNodeId::from_serialized( "package-peer-a@2.0.0_package-peer-b@3.0.0" ) .unwrap(), ), ( "package-peer-b".to_string(), - NpmPackageId::from_serialized("package-peer-b@3.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer-b@3.0.0") + .unwrap(), ) ]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-peer-a@2.0.0_package-peer-b@3.0.0" ) .unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-peer-b".to_string(), - NpmPackageId::from_serialized("package-peer-b@3.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer-b@3.0.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer-b@3.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer-b@3.0.0") + .unwrap(), copy_index: 0, dependencies: HashMap::new(), dist: Default::default(), @@ -2127,11 +2133,11 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-0@1.1.1").unwrap(), + id: NpmPackageNodeId::from_serialized("package-0@1.1.1").unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-a".to_string(), - NpmPackageId::from_serialized( + NpmPackageNodeId::from_serialized( "package-a@1.0.0_package-peer-a@4.0.0" ) .unwrap(), @@ -2139,7 +2145,7 @@ mod test { dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-a@1.0.0_package-peer-a@4.0.0" ) .unwrap(), @@ -2147,31 +2153,32 @@ mod test { dependencies: HashMap::from([ ( "package-b".to_string(), - NpmPackageId::from_serialized( + NpmPackageNodeId::from_serialized( "package-b@2.0.0_package-peer-a@4.0.0" ) .unwrap(), ), ( "package-c".to_string(), - NpmPackageId::from_serialized( + NpmPackageNodeId::from_serialized( "package-c@3.0.0_package-peer-a@4.0.0" ) .unwrap(), ), ( "package-d".to_string(), - NpmPackageId::from_serialized("package-d@3.5.0").unwrap(), + NpmPackageNodeId::from_serialized("package-d@3.5.0").unwrap(), ), ( "package-peer-a".to_string(), - NpmPackageId::from_serialized("package-peer-a@4.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer-a@4.0.0") + .unwrap(), ), ]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-b@2.0.0_package-peer-a@4.0.0" ) .unwrap(), @@ -2180,16 +2187,18 @@ mod test { dependencies: HashMap::from([ ( "package-peer-a".to_string(), - NpmPackageId::from_serialized("package-peer-a@4.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer-a@4.0.0") + .unwrap(), ), ( "package-peer-c".to_string(), - NpmPackageId::from_serialized("package-peer-c@6.2.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer-c@6.2.0") + .unwrap(), ) ]) }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-c@3.0.0_package-peer-a@4.0.0" ) .unwrap(), @@ -2197,38 +2206,41 @@ mod test { dist: Default::default(), dependencies: HashMap::from([( "package-peer-a".to_string(), - NpmPackageId::from_serialized("package-peer-a@4.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer-a@4.0.0").unwrap(), )]) }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-d@3.5.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-d@3.5.0").unwrap(), copy_index: 0, dependencies: HashMap::from([]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-e@3.6.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-e@3.6.0").unwrap(), copy_index: 0, dependencies: HashMap::from([]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer-a@4.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer-a@4.0.0") + .unwrap(), copy_index: 0, dist: Default::default(), dependencies: HashMap::from([( "package-peer-b".to_string(), - NpmPackageId::from_serialized("package-peer-b@5.4.1").unwrap(), + NpmPackageNodeId::from_serialized("package-peer-b@5.4.1").unwrap(), )]) }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer-b@5.4.1").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer-b@5.4.1") + .unwrap(), copy_index: 0, dist: Default::default(), dependencies: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer-c@6.2.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer-c@6.2.0") + .unwrap(), copy_index: 0, dist: Default::default(), dependencies: Default::default(), @@ -2258,22 +2270,26 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-b".to_string(), - NpmPackageId::from_serialized("package-b@2.0.0_package-a@1.0.0") - .unwrap(), + NpmPackageNodeId::from_serialized( + "package-b@2.0.0_package-a@1.0.0" + ) + .unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-b@2.0.0_package-a@1.0.0") - .unwrap(), + id: NpmPackageNodeId::from_serialized( + "package-b@2.0.0_package-a@1.0.0" + ) + .unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-a".to_string(), - NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), )]), dist: Default::default(), }, @@ -2310,7 +2326,7 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-a@1.0.0_package-peer@4.0.0" ) .unwrap(), @@ -2318,20 +2334,21 @@ mod test { dependencies: HashMap::from([ ( "package-dep".to_string(), - NpmPackageId::from_serialized( + NpmPackageNodeId::from_serialized( "package-dep@3.0.0_package-peer@4.0.0" ) .unwrap(), ), ( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@4.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@4.0.0") + .unwrap(), ), ]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-b@2.0.0_package-peer@5.0.0" ) .unwrap(), @@ -2339,50 +2356,53 @@ mod test { dependencies: HashMap::from([ ( "package-dep".to_string(), - NpmPackageId::from_serialized( + NpmPackageNodeId::from_serialized( "package-dep@3.0.0_package-peer@5.0.0" ) .unwrap(), ), ( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@5.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@5.0.0") + .unwrap(), ), ]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-dep@3.0.0_package-peer@4.0.0" ) .unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@4.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@4.0.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-dep@3.0.0_package-peer@5.0.0" ) .unwrap(), copy_index: 1, dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@5.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@5.0.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@4.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@4.0.0") + .unwrap(), copy_index: 0, dependencies: HashMap::new(), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@5.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@5.0.0") + .unwrap(), copy_index: 0, dependencies: HashMap::new(), dist: Default::default(), @@ -2426,43 +2446,49 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0_package-b@1.0.0") - .unwrap(), + id: NpmPackageNodeId::from_serialized( + "package-a@1.0.0_package-b@1.0.0" + ) + .unwrap(), copy_index: 0, dependencies: HashMap::from([ ( "package-c".to_string(), - NpmPackageId::from_serialized("package-c@1.0.0_package-b@1.0.0") - .unwrap(), + NpmPackageNodeId::from_serialized( + "package-c@1.0.0_package-b@1.0.0" + ) + .unwrap(), ), ( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@1.0.0").unwrap(), ) ]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-b@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-b@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@1.0.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-c@1.0.0_package-b@1.0.0") - .unwrap(), + id: NpmPackageNodeId::from_serialized( + "package-c@1.0.0_package-b@1.0.0" + ) + .unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-b".to_string(), - NpmPackageId::from_serialized("package-b@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-b@1.0.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([]), dist: Default::default(), @@ -2503,28 +2529,28 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@1.2.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@1.2.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-a@1.0.0_package-peer@1.1.0" ) .unwrap(), copy_index: 1, dependencies: HashMap::from([( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@1.1.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@1.1.0").unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-b@1.0.0_package-a@1.0.0_package-peer@1.1.0" ) .unwrap(), @@ -2532,39 +2558,41 @@ mod test { dependencies: HashMap::from([ ( "package-c".to_string(), - NpmPackageId::from_serialized( + NpmPackageNodeId::from_serialized( "package-c@1.0.0_package-a@1.0.0_package-peer@1.1.0" ) .unwrap(), ), ( "package-peer".to_string(), - NpmPackageId::from_serialized("package-peer@1.1.0").unwrap(), + NpmPackageNodeId::from_serialized("package-peer@1.1.0").unwrap(), ) ]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized( + id: NpmPackageNodeId::from_serialized( "package-c@1.0.0_package-a@1.0.0_package-peer@1.1.0" ) .unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-a".to_string(), - NpmPackageId::from_serialized("package-a@1.0.0_package-peer@1.1.0") - .unwrap(), + NpmPackageNodeId::from_serialized( + "package-a@1.0.0_package-peer@1.1.0" + ) + .unwrap(), )]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@1.1.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@1.1.0").unwrap(), copy_index: 0, dependencies: HashMap::from([]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-peer@1.2.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-peer@1.2.0").unwrap(), copy_index: 0, dependencies: HashMap::from([]), dist: Default::default(), @@ -2607,58 +2635,64 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0_package-d@1.0.0") - .unwrap(), + id: NpmPackageNodeId::from_serialized( + "package-a@1.0.0_package-d@1.0.0" + ) + .unwrap(), copy_index: 0, dependencies: HashMap::from([ ( "package-b".to_string(), - NpmPackageId::from_serialized("package-b@2.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-b@2.0.0").unwrap(), ), ( "package-c".to_string(), - NpmPackageId::from_serialized("package-c@1.0.0_package-d@1.0.0") - .unwrap(), + NpmPackageNodeId::from_serialized( + "package-c@1.0.0_package-d@1.0.0" + ) + .unwrap(), ), ( "package-d".to_string(), - NpmPackageId::from_serialized("package-d@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-d@1.0.0").unwrap(), ), ( "package-e".to_string(), - NpmPackageId::from_serialized("package-e@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-e@1.0.0").unwrap(), ), ]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-b@2.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-b@2.0.0").unwrap(), copy_index: 0, dependencies: HashMap::new(), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-c@1.0.0_package-d@1.0.0") - .unwrap(), + id: NpmPackageNodeId::from_serialized( + "package-c@1.0.0_package-d@1.0.0" + ) + .unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-d".to_string(), - NpmPackageId::from_serialized("package-d@1.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-d@1.0.0").unwrap(), ),]), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-d@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-d@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::new(), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-e@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-e@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-b".to_string(), - NpmPackageId::from_serialized("package-b@2.0.0").unwrap(), + NpmPackageNodeId::from_serialized("package-b@2.0.0").unwrap(), )]), dist: Default::default(), }, @@ -2684,7 +2718,7 @@ mod test { assert_eq!( packages, vec![NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), copy_index: 0, // in this case, we just ignore that the package did this dependencies: Default::default(), @@ -2710,17 +2744,17 @@ mod test { packages, vec![ NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@0.5.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@0.5.0").unwrap(), copy_index: 0, dependencies: Default::default(), dist: Default::default(), }, NpmResolutionPackage { - id: NpmPackageId::from_serialized("package-a@1.0.0").unwrap(), + id: NpmPackageNodeId::from_serialized("package-a@1.0.0").unwrap(), copy_index: 0, dependencies: HashMap::from([( "package-a".to_string(), - NpmPackageId::from_serialized("package-a@0.5.0").unwrap(), + NpmPackageNodeId::from_serialized("package-a@0.5.0").unwrap(), )]), dist: Default::default(), }, diff --git a/cli/npm/resolution/mod.rs b/cli/npm/resolution/mod.rs index 0f6dcb910..ec6ee0dda 100644 --- a/cli/npm/resolution/mod.rs +++ b/cli/npm/resolution/mod.rs @@ -6,10 +6,11 @@ use std::collections::HashSet; use deno_core::error::AnyError; use deno_core::futures; use deno_core::parking_lot::RwLock; -use deno_graph::npm::NpmPackageId; use deno_graph::npm::NpmPackageReq; +use deno_graph::semver::Version; use serde::Deserialize; use serde::Serialize; +use thiserror::Error; use crate::args::Lockfile; @@ -30,9 +31,165 @@ use graph::Graph; pub use snapshot::NpmResolutionSnapshot; pub use specifier::resolve_graph_npm_info; +#[derive(Debug, Error)] +#[error("Invalid npm package id '{text}'. {message}")] +pub struct NpmPackageNodeIdDeserializationError { + message: String, + text: String, +} + +/// A resolved unique identifier for an npm package. This contains +/// the resolved name, version, and peer dependency resolution identifiers. +#[derive( + Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize, +)] +pub struct NpmPackageNodeId { + pub name: String, + pub version: Version, + pub peer_dependencies: Vec<NpmPackageNodeId>, +} + +impl NpmPackageNodeId { + #[allow(unused)] + pub fn scope(&self) -> Option<&str> { + if self.name.starts_with('@') && self.name.contains('/') { + self.name.split('/').next() + } else { + None + } + } + + pub fn as_serialized(&self) -> String { + self.as_serialized_with_level(0) + } + + fn as_serialized_with_level(&self, level: usize) -> String { + // WARNING: This should not change because it's used in the lockfile + let mut result = format!( + "{}@{}", + if level == 0 { + self.name.to_string() + } else { + self.name.replace('/', "+") + }, + self.version + ); + for peer in &self.peer_dependencies { + // unfortunately we can't do something like `_3` when + // this gets deep because npm package names can start + // with a number + result.push_str(&"_".repeat(level + 1)); + result.push_str(&peer.as_serialized_with_level(level + 1)); + } + result + } + + pub fn from_serialized( + id: &str, + ) -> Result<Self, NpmPackageNodeIdDeserializationError> { + use monch::*; + + fn parse_name(input: &str) -> ParseResult<&str> { + if_not_empty(substring(move |input| { + for (pos, c) in input.char_indices() { + // first character might be a scope, so skip it + if pos > 0 && c == '@' { + return Ok((&input[pos..], ())); + } + } + ParseError::backtrace() + }))(input) + } + + fn parse_version(input: &str) -> ParseResult<&str> { + if_not_empty(substring(skip_while(|c| c != '_')))(input) + } + + fn parse_name_and_version(input: &str) -> ParseResult<(String, Version)> { + let (input, name) = parse_name(input)?; + let (input, _) = ch('@')(input)?; + let at_version_input = input; + let (input, version) = parse_version(input)?; + match Version::parse_from_npm(version) { + Ok(version) => Ok((input, (name.to_string(), version))), + Err(err) => ParseError::fail(at_version_input, format!("{err:#}")), + } + } + + fn parse_level_at_level<'a>( + level: usize, + ) -> impl Fn(&'a str) -> ParseResult<'a, ()> { + fn parse_level(input: &str) -> ParseResult<usize> { + let level = input.chars().take_while(|c| *c == '_').count(); + Ok((&input[level..], level)) + } + + move |input| { + let (input, parsed_level) = parse_level(input)?; + if parsed_level == level { + Ok((input, ())) + } else { + ParseError::backtrace() + } + } + } + + fn parse_peers_at_level<'a>( + level: usize, + ) -> impl Fn(&'a str) -> ParseResult<'a, Vec<NpmPackageNodeId>> { + move |mut input| { + let mut peers = Vec::new(); + while let Ok((level_input, _)) = parse_level_at_level(level)(input) { + input = level_input; + let peer_result = parse_id_at_level(level)(input)?; + input = peer_result.0; + peers.push(peer_result.1); + } + Ok((input, peers)) + } + } + + fn parse_id_at_level<'a>( + level: usize, + ) -> impl Fn(&'a str) -> ParseResult<'a, NpmPackageNodeId> { + move |input| { + let (input, (name, version)) = parse_name_and_version(input)?; + let name = if level > 0 { + name.replace('+', "/") + } else { + name + }; + let (input, peer_dependencies) = + parse_peers_at_level(level + 1)(input)?; + Ok(( + input, + NpmPackageNodeId { + name, + version, + peer_dependencies, + }, + )) + } + } + + with_failure_handling(parse_id_at_level(0))(id).map_err(|err| { + NpmPackageNodeIdDeserializationError { + message: format!("{err:#}"), + text: id.to_string(), + } + }) + } + + pub fn display(&self) -> String { + // Don't implement std::fmt::Display because we don't + // want this to be used by accident in certain scenarios. + format!("{}@{}", self.name, self.version) + } +} + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct NpmResolutionPackage { - pub id: NpmPackageId, + pub id: NpmPackageNodeId, /// The peer dependency resolution can differ for the same /// package (name and version) depending on where it is in /// the resolution tree. This copy index indicates which @@ -41,7 +198,7 @@ pub struct NpmResolutionPackage { pub dist: NpmPackageVersionDistInfo, /// Key is what the package refers to the other package as, /// which could be different from the package name. - pub dependencies: HashMap<String, NpmPackageId>, + pub dependencies: HashMap<String, NpmPackageNodeId>, } impl NpmResolutionPackage { @@ -189,14 +346,14 @@ impl NpmResolution { pub fn resolve_package_from_id( &self, - id: &NpmPackageId, + id: &NpmPackageNodeId, ) -> Option<NpmResolutionPackage> { self.snapshot.read().package_from_id(id).cloned() } pub fn resolve_package_cache_folder_id_from_id( &self, - id: &NpmPackageId, + id: &NpmPackageNodeId, ) -> Option<NpmPackageCacheFolderId> { self .snapshot @@ -255,3 +412,50 @@ impl NpmResolution { Ok(()) } } + +#[cfg(test)] +mod test { + use deno_graph::semver::Version; + + use super::NpmPackageNodeId; + + #[test] + fn serialize_npm_package_id() { + let id = NpmPackageNodeId { + name: "pkg-a".to_string(), + version: Version::parse_from_npm("1.2.3").unwrap(), + peer_dependencies: vec![ + NpmPackageNodeId { + name: "pkg-b".to_string(), + version: Version::parse_from_npm("3.2.1").unwrap(), + peer_dependencies: vec![ + NpmPackageNodeId { + name: "pkg-c".to_string(), + version: Version::parse_from_npm("1.3.2").unwrap(), + peer_dependencies: vec![], + }, + NpmPackageNodeId { + name: "pkg-d".to_string(), + version: Version::parse_from_npm("2.3.4").unwrap(), + peer_dependencies: vec![], + }, + ], + }, + NpmPackageNodeId { + name: "pkg-e".to_string(), + version: Version::parse_from_npm("2.3.1").unwrap(), + peer_dependencies: vec![NpmPackageNodeId { + name: "pkg-f".to_string(), + version: Version::parse_from_npm("2.3.1").unwrap(), + peer_dependencies: vec![], + }], + }, + ], + }; + + // this shouldn't change because it's used in the lockfile + let serialized = id.as_serialized(); + assert_eq!(serialized, "pkg-a@1.2.3_pkg-b@3.2.1__pkg-c@1.3.2__pkg-d@2.3.4_pkg-e@2.3.1__pkg-f@2.3.1"); + assert_eq!(NpmPackageNodeId::from_serialized(&serialized).unwrap(), id); + } +} diff --git a/cli/npm/resolution/snapshot.rs b/cli/npm/resolution/snapshot.rs index 957f5d6d8..c717e74a8 100644 --- a/cli/npm/resolution/snapshot.rs +++ b/cli/npm/resolution/snapshot.rs @@ -10,7 +10,6 @@ use deno_core::anyhow::Context; use deno_core::error::AnyError; use deno_core::futures; use deno_core::parking_lot::Mutex; -use deno_graph::npm::NpmPackageId; use deno_graph::npm::NpmPackageReq; use deno_graph::semver::VersionReq; use serde::Deserialize; @@ -23,6 +22,7 @@ use crate::npm::registry::NpmPackageVersionDistInfo; use crate::npm::registry::NpmRegistryApi; use crate::npm::registry::RealNpmRegistryApi; +use super::NpmPackageNodeId; use super::NpmResolutionPackage; /// Packages partitioned by if they are "copy" packages or not. @@ -47,10 +47,10 @@ impl NpmPackagesPartitioned { #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct NpmResolutionSnapshot { #[serde(with = "map_to_vec")] - pub(super) package_reqs: HashMap<NpmPackageReq, NpmPackageId>, - pub(super) packages_by_name: HashMap<String, Vec<NpmPackageId>>, + pub(super) package_reqs: HashMap<NpmPackageReq, NpmPackageNodeId>, + pub(super) packages_by_name: HashMap<String, Vec<NpmPackageNodeId>>, #[serde(with = "map_to_vec")] - pub(super) packages: HashMap<NpmPackageId, NpmResolutionPackage>, + pub(super) packages: HashMap<NpmPackageNodeId, NpmResolutionPackage>, } // This is done so the maps with non-string keys get serialized and deserialized as vectors. @@ -104,7 +104,7 @@ impl NpmResolutionSnapshot { } } - pub fn top_level_packages(&self) -> Vec<NpmPackageId> { + pub fn top_level_packages(&self) -> Vec<NpmPackageNodeId> { self .package_reqs .values() @@ -116,7 +116,7 @@ impl NpmResolutionSnapshot { pub fn package_from_id( &self, - id: &NpmPackageId, + id: &NpmPackageNodeId, ) -> Option<&NpmResolutionPackage> { self.packages.get(id) } @@ -198,10 +198,10 @@ impl NpmResolutionSnapshot { &self, name: &str, version_req: &VersionReq, - ) -> Option<NpmPackageId> { + ) -> Option<NpmPackageNodeId> { // todo(dsherret): this is not exactly correct because some ids // will be better than others due to peer dependencies - let mut maybe_best_id: Option<&NpmPackageId> = None; + let mut maybe_best_id: Option<&NpmPackageNodeId> = None; if let Some(ids) = self.packages_by_name.get(name) { for id in ids { if version_req.matches(&id.version) { @@ -222,9 +222,9 @@ impl NpmResolutionSnapshot { lockfile: Arc<Mutex<Lockfile>>, api: &RealNpmRegistryApi, ) -> Result<Self, AnyError> { - let mut package_reqs: HashMap<NpmPackageReq, NpmPackageId>; - let mut packages_by_name: HashMap<String, Vec<NpmPackageId>>; - let mut packages: HashMap<NpmPackageId, NpmResolutionPackage>; + let mut package_reqs: HashMap<NpmPackageReq, NpmPackageNodeId>; + let mut packages_by_name: HashMap<String, Vec<NpmPackageNodeId>>; + let mut packages: HashMap<NpmPackageNodeId, NpmResolutionPackage>; let mut copy_index_resolver: SnapshotPackageCopyIndexResolver; { @@ -244,14 +244,14 @@ impl NpmResolutionSnapshot { for (key, value) in &lockfile.content.npm.specifiers { let package_req = NpmPackageReq::from_str(key) .with_context(|| format!("Unable to parse npm specifier: {key}"))?; - let package_id = NpmPackageId::from_serialized(value)?; + let package_id = NpmPackageNodeId::from_serialized(value)?; package_reqs.insert(package_req, package_id.clone()); verify_ids.insert(package_id.clone()); } // then the packages for (key, value) in &lockfile.content.npm.packages { - let package_id = NpmPackageId::from_serialized(key)?; + let package_id = NpmPackageNodeId::from_serialized(key)?; // collect the dependencies let mut dependencies = HashMap::default(); @@ -262,7 +262,7 @@ impl NpmResolutionSnapshot { .push(package_id.clone()); for (name, specifier) in &value.dependencies { - let dep_id = NpmPackageId::from_serialized(specifier)?; + let dep_id = NpmPackageNodeId::from_serialized(specifier)?; dependencies.insert(name.to_string(), dep_id.clone()); verify_ids.insert(dep_id); } @@ -336,7 +336,7 @@ impl NpmResolutionSnapshot { } pub struct SnapshotPackageCopyIndexResolver { - packages_to_copy_index: HashMap<NpmPackageId, usize>, + packages_to_copy_index: HashMap<NpmPackageNodeId, usize>, package_name_version_to_copy_count: HashMap<(String, String), usize>, } @@ -349,7 +349,7 @@ impl SnapshotPackageCopyIndexResolver { } pub fn from_map_with_capacity( - mut packages_to_copy_index: HashMap<NpmPackageId, usize>, + mut packages_to_copy_index: HashMap<NpmPackageNodeId, usize>, capacity: usize, ) -> Self { let mut package_name_version_to_copy_count = @@ -372,7 +372,7 @@ impl SnapshotPackageCopyIndexResolver { } } - pub fn resolve(&mut self, id: &NpmPackageId) -> usize { + pub fn resolve(&mut self, id: &NpmPackageNodeId) -> usize { if let Some(index) = self.packages_to_copy_index.get(id) { *index } else { @@ -422,24 +422,24 @@ mod tests { SnapshotPackageCopyIndexResolver::with_capacity(10); assert_eq!( copy_index_resolver - .resolve(&NpmPackageId::from_serialized("package@1.0.0").unwrap()), + .resolve(&NpmPackageNodeId::from_serialized("package@1.0.0").unwrap()), 0 ); assert_eq!( copy_index_resolver - .resolve(&NpmPackageId::from_serialized("package@1.0.0").unwrap()), + .resolve(&NpmPackageNodeId::from_serialized("package@1.0.0").unwrap()), 0 ); assert_eq!( copy_index_resolver.resolve( - &NpmPackageId::from_serialized("package@1.0.0_package-b@1.0.0") + &NpmPackageNodeId::from_serialized("package@1.0.0_package-b@1.0.0") .unwrap() ), 1 ); assert_eq!( copy_index_resolver.resolve( - &NpmPackageId::from_serialized( + &NpmPackageNodeId::from_serialized( "package@1.0.0_package-b@1.0.0__package-c@2.0.0" ) .unwrap() @@ -448,14 +448,15 @@ mod tests { ); assert_eq!( copy_index_resolver.resolve( - &NpmPackageId::from_serialized("package@1.0.0_package-b@1.0.0") + &NpmPackageNodeId::from_serialized("package@1.0.0_package-b@1.0.0") .unwrap() ), 1 ); assert_eq!( - copy_index_resolver - .resolve(&NpmPackageId::from_serialized("package-b@1.0.0").unwrap()), + copy_index_resolver.resolve( + &NpmPackageNodeId::from_serialized("package-b@1.0.0").unwrap() + ), 0 ); } diff --git a/cli/npm/resolvers/common.rs b/cli/npm/resolvers/common.rs index 99af7352b..69950bee9 100644 --- a/cli/npm/resolvers/common.rs +++ b/cli/npm/resolvers/common.rs @@ -10,7 +10,6 @@ use deno_core::error::AnyError; use deno_core::futures; use deno_core::futures::future::BoxFuture; use deno_core::url::Url; -use deno_graph::npm::NpmPackageId; use deno_graph::npm::NpmPackageReq; use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodeResolutionMode; @@ -19,6 +18,7 @@ use crate::args::Lockfile; use crate::npm::cache::should_sync_download; use crate::npm::resolution::NpmResolutionSnapshot; use crate::npm::NpmCache; +use crate::npm::NpmPackageNodeId; use crate::npm::NpmResolutionPackage; pub trait InnerNpmPackageResolver: Send + Sync { @@ -39,7 +39,10 @@ pub trait InnerNpmPackageResolver: Send + Sync { specifier: &ModuleSpecifier, ) -> Result<PathBuf, AnyError>; - fn package_size(&self, package_id: &NpmPackageId) -> Result<u64, AnyError>; + fn package_size( + &self, + package_id: &NpmPackageNodeId, + ) -> Result<u64, AnyError>; fn has_packages(&self) -> bool; diff --git a/cli/npm/resolvers/global.rs b/cli/npm/resolvers/global.rs index bc358fee2..c8e2c2bb0 100644 --- a/cli/npm/resolvers/global.rs +++ b/cli/npm/resolvers/global.rs @@ -12,7 +12,6 @@ use deno_core::error::AnyError; use deno_core::futures::future::BoxFuture; use deno_core::futures::FutureExt; use deno_core::url::Url; -use deno_graph::npm::NpmPackageId; use deno_graph::npm::NpmPackageReq; use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodeResolutionMode; @@ -23,6 +22,7 @@ use crate::npm::resolution::NpmResolution; use crate::npm::resolution::NpmResolutionSnapshot; use crate::npm::resolvers::common::cache_packages; use crate::npm::NpmCache; +use crate::npm::NpmPackageNodeId; use crate::npm::NpmResolutionPackage; use crate::npm::RealNpmRegistryApi; @@ -54,7 +54,7 @@ impl GlobalNpmPackageResolver { } } - fn package_folder(&self, id: &NpmPackageId) -> PathBuf { + fn package_folder(&self, id: &NpmPackageNodeId) -> PathBuf { let folder_id = self .resolution .resolve_package_cache_folder_id_from_id(id) @@ -125,7 +125,10 @@ impl InnerNpmPackageResolver for GlobalNpmPackageResolver { ) } - fn package_size(&self, package_id: &NpmPackageId) -> Result<u64, AnyError> { + fn package_size( + &self, + package_id: &NpmPackageNodeId, + ) -> Result<u64, AnyError> { let package_folder = self.package_folder(package_id); Ok(crate::util::fs::dir_size(&package_folder)?) } diff --git a/cli/npm/resolvers/local.rs b/cli/npm/resolvers/local.rs index dab367f3d..0eb2c24ca 100644 --- a/cli/npm/resolvers/local.rs +++ b/cli/npm/resolvers/local.rs @@ -18,7 +18,6 @@ use deno_core::error::AnyError; use deno_core::futures::future::BoxFuture; use deno_core::futures::FutureExt; use deno_core::url::Url; -use deno_graph::npm::NpmPackageId; use deno_graph::npm::NpmPackageReq; use deno_runtime::deno_core::futures; use deno_runtime::deno_node::NodePermissions; @@ -33,6 +32,7 @@ use crate::npm::cache::NpmPackageCacheFolderId; use crate::npm::resolution::NpmResolution; use crate::npm::resolution::NpmResolutionSnapshot; use crate::npm::NpmCache; +use crate::npm::NpmPackageNodeId; use crate::npm::NpmResolutionPackage; use crate::npm::RealNpmRegistryApi; use crate::util::fs::copy_dir_recursive; @@ -112,7 +112,7 @@ impl LocalNpmPackageResolver { fn get_package_id_folder( &self, - package_id: &NpmPackageId, + package_id: &NpmPackageNodeId, ) -> Result<PathBuf, AnyError> { match self.resolution.resolve_package_from_id(package_id) { Some(package) => Ok(self.get_package_id_folder_from_package(&package)), @@ -203,7 +203,10 @@ impl InnerNpmPackageResolver for LocalNpmPackageResolver { Ok(package_root_path) } - fn package_size(&self, package_id: &NpmPackageId) -> Result<u64, AnyError> { + fn package_size( + &self, + package_id: &NpmPackageNodeId, + ) -> Result<u64, AnyError> { let package_folder_path = self.get_package_id_folder(package_id)?; Ok(crate::util::fs::dir_size(&package_folder_path)?) diff --git a/cli/npm/resolvers/mod.rs b/cli/npm/resolvers/mod.rs index 31c6c0b05..9dda160b0 100644 --- a/cli/npm/resolvers/mod.rs +++ b/cli/npm/resolvers/mod.rs @@ -11,7 +11,6 @@ use deno_core::error::custom_error; use deno_core::error::AnyError; use deno_core::parking_lot::Mutex; use deno_core::serde_json; -use deno_graph::npm::NpmPackageId; use deno_graph::npm::NpmPackageReq; use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodeResolutionMode; @@ -32,6 +31,7 @@ use crate::util::fs::canonicalize_path_maybe_not_exists; use self::common::InnerNpmPackageResolver; use self::local::LocalNpmPackageResolver; use super::NpmCache; +use super::NpmPackageNodeId; use super::NpmResolutionSnapshot; use super::RealNpmRegistryApi; @@ -225,7 +225,7 @@ impl NpmPackageResolver { /// Attempts to get the package size in bytes. pub fn package_size( &self, - package_id: &NpmPackageId, + package_id: &NpmPackageNodeId, ) -> Result<u64, AnyError> { self.inner.package_size(package_id) } diff --git a/cli/tools/info.rs b/cli/tools/info.rs index 76c5c3880..ffd276417 100644 --- a/cli/tools/info.rs +++ b/cli/tools/info.rs @@ -10,7 +10,6 @@ use deno_core::error::AnyError; use deno_core::resolve_url_or_path; use deno_core::serde_json; use deno_core::serde_json::json; -use deno_graph::npm::NpmPackageId; use deno_graph::npm::NpmPackageReference; use deno_graph::npm::NpmPackageReq; use deno_graph::Dependency; @@ -23,6 +22,7 @@ use deno_runtime::colors; use crate::args::Flags; use crate::args::InfoFlags; use crate::display; +use crate::npm::NpmPackageNodeId; use crate::npm::NpmPackageResolver; use crate::npm::NpmResolutionPackage; use crate::npm::NpmResolutionSnapshot; @@ -297,9 +297,9 @@ fn print_tree_node<TWrite: Write>( /// Precached information about npm packages that are used in deno info. #[derive(Default)] struct NpmInfo { - package_sizes: HashMap<NpmPackageId, u64>, - resolved_reqs: HashMap<NpmPackageReq, NpmPackageId>, - packages: HashMap<NpmPackageId, NpmResolutionPackage>, + package_sizes: HashMap<NpmPackageNodeId, u64>, + resolved_reqs: HashMap<NpmPackageReq, NpmPackageNodeId>, + packages: HashMap<NpmPackageNodeId, NpmResolutionPackage>, specifiers: HashMap<ModuleSpecifier, NpmPackageReq>, } |