MCPcopy
hub / github.com/npmx-dev/npmx.dev / resolveDependencyTree

Function resolveDependencyTree

server/utils/dependency-resolver.ts:115–200  ·  view source on GitHub ↗
(
  rootName: string,
  rootVersion: string,
  options: { trackDepth?: boolean } = {},
)

Source from the content-addressed store, hash-verified

113 * Uses level-by-level BFS to ensure correct depth assignment when trackDepth is enabled.
114 */
115export async function resolveDependencyTree(
116 rootName: string,
117 rootVersion: string,
118 options: { trackDepth?: boolean } = {},
119): Promise<Map<string, ResolvedPackage>> {
120 const resolved = new Map<string, ResolvedPackage>()
121 const seen = new Set<string>()
122
123 // Process level by level for correct depth tracking
124 // Each entry includes the path of package names leading to this dependency
125 let currentLevel = new Map<string, { range: string; optional: boolean; path: string[] }>([
126 [rootName, { range: rootVersion, optional: false, path: [] }],
127 ])
128 let level = 0
129
130 while (currentLevel.size > 0) {
131 const nextLevel = new Map<string, { range: string; optional: boolean; path: string[] }>()
132
133 // Mark all packages in current level as seen before processing
134 for (const name of currentLevel.keys()) {
135 seen.add(name)
136 }
137
138 // Process current level with concurrency limit
139 const entries = [...currentLevel.entries()]
140 await mapWithConcurrency(
141 entries,
142 async ([name, { range, optional, path }]) => {
143 const packument = await fetchPackument(name)
144 if (!packument) return
145
146 const versions = Object.keys(packument.versions)
147 const version = resolveVersion(range, versions)
148 if (!version) return
149
150 const versionData = packument.versions[version]
151 if (!versionData) return
152
153 if (!matchesPlatform(versionData)) return
154
155 const size = (versionData.dist as { unpackedSize?: number })?.unpackedSize ?? 0
156 const tarballUrl = versionData.dist?.tarball ?? ''
157 const key = `${name}@${version}`
158
159 // Build path for this package (path to parent + this package with version)
160 const currentPath = [...path, `${name}@${version}`]
161
162 if (!resolved.has(key)) {
163 const pkg: ResolvedPackage = { name, version, size, tarballUrl, optional }
164 if (options.trackDepth) {
165 pkg.depth = level === 0 ? 'root' : level === 1 ? 'direct' : 'transitive'
166 pkg.path = currentPath
167 }
168 if (versionData.deprecated) {
169 pkg.deprecated = versionData.deprecated
170 }
171 resolved.set(key, pkg)
172 }

Callers 3

install-size.tsFile · 0.85

Calls 5

mapWithConcurrencyFunction · 0.90
fetchPackumentFunction · 0.85
resolveVersionFunction · 0.85
matchesPlatformFunction · 0.85
setMethod · 0.65

Tested by

no test coverage detected