diff --git a/config.json b/config.json index 593915097..afb6ccdac 100644 --- a/config.json +++ b/config.json @@ -2,6 +2,10 @@ "definitions": { "npm": { "default": "8.13.1", + "fetchLatestFrom": { + "type": "npm", + "package": "npm" + }, "transparent": { "commands": [ [ @@ -29,6 +33,10 @@ }, "pnpm": { "default": "7.3.0", + "fetchLatestFrom": { + "type": "npm", + "package": "pnpm" + }, "transparent": { "commands": [ [ @@ -71,6 +79,10 @@ }, "yarn": { "default": "1.22.19", + "fetchLatestFrom": { + "type": "npm", + "package": "yarn" + }, "transparent": { "default": "3.2.1", "commands": [ diff --git a/sources/Engine.ts b/sources/Engine.ts index f98c049e2..1ce9a1576 100644 --- a/sources/Engine.ts +++ b/sources/Engine.ts @@ -7,7 +7,6 @@ import defaultConfig from '../config.js import * as corepackUtils from './corepackUtils'; import * as folderUtils from './folderUtils'; -import {fetchAsJson} from './httpUtils'; import * as semverUtils from './semverUtils'; import {Config, Descriptor, Locator} from './types'; import {SupportedPackageManagers, SupportedPackageManagerSet} from './types'; @@ -81,8 +80,7 @@ export class Engine { if (process.env.COREPACK_NO_LOOKUP) return definition.default; - const {[`dist-tags`]: {latest}, versions: {[latest]: {dist: {shasum}}}} = await fetchAsJson(`https://registry.npmjs.org/${packageManager}`); - const reference = `${latest}+sha1.${shasum}`; + const reference = await corepackUtils.fetchLatestStableVersion(definition.fetchLatestFrom); await this.activatePackageManager({ name: packageManager, diff --git a/sources/corepackUtils.ts b/sources/corepackUtils.ts index acd74e575..09c31ec93 100644 --- a/sources/corepackUtils.ts +++ b/sources/corepackUtils.ts @@ -9,6 +9,23 @@ import * as httpUtils from './httpUtils import * as nodeUtils from './nodeUtils'; import {RegistrySpec, Descriptor, Locator, PackageManagerSpec} from './types'; +export async function fetchLatestStableVersion(spec: RegistrySpec) { + switch (spec.type) { + case `npm`: { + const {[`dist-tags`]: {latest}, versions: {[latest]: {dist: {shasum}}}} = + await httpUtils.fetchAsJson(`https://registry.npmjs.org/${spec.package}`); + return `${latest}+sha1.${shasum}`; + } + case `url`: { + const data = await httpUtils.fetchAsJson(spec.url); + return data[spec.fields.tags].stable; + } + default: { + throw new Error(`Unsupported specification ${JSON.stringify(spec)}`); + } + } +} + export async function fetchAvailableTags(spec: RegistrySpec): Promise> { switch (spec.type) { case `npm`: { diff --git a/sources/types.ts b/sources/types.ts index 8f19f294c..8ed2cfd19 100644 --- a/sources/types.ts +++ b/sources/types.ts @@ -62,6 +62,11 @@ export interface Config { */ default: string; + /** + * Defines how to fetch the latest version from a remote registry. + */ + fetchLatestFrom: RegistrySpec; + /** * Defines a set of commands that are fine to run even if the user isn't * in a project configured for the specified package manager. For instance,