|
5 | 5 | * a virtual node_modules directory structure. |
6 | 6 | */ |
7 | 7 |
|
| 8 | +import * as semver from 'semver'; |
8 | 9 | import type { Files } from './types.js'; |
9 | 10 |
|
10 | 11 | const NPM_REGISTRY = 'https://registry.npmjs.org'; |
@@ -259,54 +260,11 @@ function resolveVersion(range: string, metadata: NpmPackageMetadata): string | u |
259 | 260 | return metadata['dist-tags'][range]; |
260 | 261 | } |
261 | 262 |
|
262 | | - // For ranges like ^1.0.0, ~1.0.0, >=1.0.0, we need to find the best match |
263 | | - // Simple implementation: find the highest version that starts with the major version |
| 263 | + // Use semver.maxSatisfying to find the best matching version |
264 | 264 | const versions = Object.keys(metadata.versions); |
| 265 | + const match = semver.maxSatisfying(versions, range); |
265 | 266 |
|
266 | | - // Parse the range to extract constraints |
267 | | - const cleanRange = range.replace(/^[\^~>=<]+/, ''); |
268 | | - const [majorStr] = cleanRange.split('.'); |
269 | | - const major = parseInt(majorStr ?? '0', 10); |
270 | | - |
271 | | - // Filter versions that match the major version (for ^ ranges) |
272 | | - // This is a simplified semver matching - in production you'd use a proper semver library |
273 | | - if (range.startsWith('^') || range.startsWith('~')) { |
274 | | - const matchingVersions = versions |
275 | | - .filter((v) => { |
276 | | - const [vMajor] = v.split('.'); |
277 | | - return parseInt(vMajor ?? '0', 10) === major; |
278 | | - }) |
279 | | - .sort(compareVersions) |
280 | | - .reverse(); |
281 | | - |
282 | | - return matchingVersions[0]; |
283 | | - } |
284 | | - |
285 | | - // For >= ranges, get the latest |
286 | | - if (range.startsWith('>=')) { |
287 | | - return metadata['dist-tags']['latest']; |
288 | | - } |
289 | | - |
290 | | - // Fallback: try to find any version that might work |
291 | | - const sortedVersions = versions.sort(compareVersions).reverse(); |
292 | | - return sortedVersions[0]; |
293 | | -} |
294 | | - |
295 | | -/** |
296 | | - * Compare two semver versions. |
297 | | - */ |
298 | | -function compareVersions(a: string, b: string): number { |
299 | | - const aParts = a.split('.').map((p) => parseInt(p.replace(/[^0-9]/g, ''), 10) || 0); |
300 | | - const bParts = b.split('.').map((p) => parseInt(p.replace(/[^0-9]/g, ''), 10) || 0); |
301 | | - |
302 | | - for (let i = 0; i < 3; i++) { |
303 | | - const aVal = aParts[i] ?? 0; |
304 | | - const bVal = bParts[i] ?? 0; |
305 | | - if (aVal !== bVal) { |
306 | | - return aVal - bVal; |
307 | | - } |
308 | | - } |
309 | | - return 0; |
| 267 | + return match ?? undefined; |
310 | 268 | } |
311 | 269 |
|
312 | 270 | /** |
|
0 commit comments