(descriptor: Descriptor, {allowTags = false, useCache = true}: {allowTags?: boolean, useCache?: boolean} = {})
| 359 | } |
| 360 | |
| 361 | async resolveDescriptor(descriptor: Descriptor, {allowTags = false, useCache = true}: {allowTags?: boolean, useCache?: boolean} = {}): Promise<Locator | null> { |
| 362 | if (!corepackUtils.isSupportedPackageManagerDescriptor(descriptor)) { |
| 363 | if (process.env.COREPACK_ENABLE_UNSAFE_CUSTOM_URLS !== `1` && isSupportedPackageManager(descriptor.name)) |
| 364 | throw new UsageError(`Illegal use of URL for known package manager. Instead, select a specific version, or set COREPACK_ENABLE_UNSAFE_CUSTOM_URLS=1 in your environment (${descriptor.name}@${descriptor.range})`); |
| 365 | |
| 366 | return { |
| 367 | name: descriptor.name, |
| 368 | reference: descriptor.range, |
| 369 | }; |
| 370 | } |
| 371 | |
| 372 | const definition = this.config.definitions[descriptor.name as SupportedPackageManagers]; |
| 373 | if (typeof definition === `undefined`) |
| 374 | throw new UsageError(`This package manager (${descriptor.name}) isn't supported by this corepack build`); |
| 375 | |
| 376 | let finalDescriptor = descriptor; |
| 377 | if (!semverValid(descriptor.range) && !semverValidRange(descriptor.range)) { |
| 378 | if (!allowTags) |
| 379 | throw new UsageError(`Packages managers can't be referenced via tags in this context`); |
| 380 | |
| 381 | // We only resolve tags from the latest registry entry |
| 382 | const ranges = Object.keys(definition.ranges); |
| 383 | const tagRange = ranges[ranges.length - 1]; |
| 384 | |
| 385 | const packageManagerSpec = definition.ranges[tagRange]; |
| 386 | const registry = corepackUtils.getRegistryFromPackageManagerSpec(packageManagerSpec); |
| 387 | |
| 388 | const tags = await corepackUtils.fetchAvailableTags(registry); |
| 389 | if (!Object.hasOwn(tags, descriptor.range)) |
| 390 | throw new UsageError(`Tag not found (${descriptor.range})`); |
| 391 | |
| 392 | finalDescriptor = { |
| 393 | name: descriptor.name, |
| 394 | range: tags[descriptor.range], |
| 395 | }; |
| 396 | } |
| 397 | |
| 398 | // If a compatible version is already installed, no need to query one |
| 399 | // from the remote listings |
| 400 | const cachedVersion = await corepackUtils.findInstalledVersion(folderUtils.getInstallFolder(), finalDescriptor); |
| 401 | if (cachedVersion !== null && useCache) |
| 402 | return {name: finalDescriptor.name, reference: cachedVersion}; |
| 403 | |
| 404 | // If the user asked for a specific version, no need to request the list of |
| 405 | // available versions from the registry. |
| 406 | if (semverValid(finalDescriptor.range)) |
| 407 | return {name: finalDescriptor.name, reference: finalDescriptor.range}; |
| 408 | |
| 409 | const versions = await Promise.all(Object.keys(definition.ranges).map(async range => { |
| 410 | const packageManagerSpec = definition.ranges[range]; |
| 411 | const registry = corepackUtils.getRegistryFromPackageManagerSpec(packageManagerSpec); |
| 412 | |
| 413 | const versions = await corepackUtils.fetchAvailableVersions(registry); |
| 414 | return versions.filter(version => semverUtils.satisfiesWithPrereleases(version, finalDescriptor.range)); |
| 415 | })); |
| 416 | |
| 417 | const highestVersion = [...new Set(versions.flat())].sort(semverRcompare); |
| 418 | if (highestVersion.length === 0) |
no test coverage detected