From a2eef0aa93725bc06087d479798e8db940231f3f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ma=C3=ABl=20Nison?= <nison.mael@gmail.com>
Date: Mon, 11 Dec 2023 10:42:50 +0100
Subject: [PATCH] Fallbacks to npm when COREPACK_NPM_REGISTRY is set

---
 config.json              |  4 ++++
 sources/Engine.ts        | 10 ++++++++--
 sources/corepackUtils.ts |  6 ++++++
 sources/types.ts         |  1 +
 4 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/config.json b/config.json
index 74393b0ac..94adf3356 100644
--- a/config.json
+++ b/config.json
@@ -143,6 +143,10 @@
               "versions": "tags"
             }
           },
+          "npmRegistry": {
+            "type": "npm",
+            "package": "@yarnpkg/cli-dist"
+          },
           "commands": {
             "use": [
               "yarn",
diff --git a/sources/Engine.ts b/sources/Engine.ts
index 8cf551434..eaa0a8064 100644
--- a/sources/Engine.ts
+++ b/sources/Engine.ts
@@ -156,7 +156,10 @@ export class Engine {
       const ranges = Object.keys(definition.ranges);
       const tagRange = ranges[ranges.length - 1];
 
-      const tags = await corepackUtils.fetchAvailableTags(definition.ranges[tagRange].registry);
+      const packageManagerSpec = definition.ranges[tagRange];
+      const registry = corepackUtils.getRegistryFromPackageManagerSpec(packageManagerSpec);
+
+      const tags = await corepackUtils.fetchAvailableTags(registry);
       if (!Object.prototype.hasOwnProperty.call(tags, descriptor.range))
         throw new UsageError(`Tag not found (${descriptor.range})`);
 
@@ -178,7 +181,10 @@ export class Engine {
       return {name: finalDescriptor.name, reference: finalDescriptor.range};
 
     const versions = await Promise.all(Object.keys(definition.ranges).map(async range => {
-      const versions = await corepackUtils.fetchAvailableVersions(definition.ranges[range].registry);
+      const packageManagerSpec = definition.ranges[range];
+      const registry = corepackUtils.getRegistryFromPackageManagerSpec(packageManagerSpec);
+
+      const versions = await corepackUtils.fetchAvailableVersions(registry);
       return versions.filter(version => semverUtils.satisfiesWithPrereleases(version, finalDescriptor.range));
     }));
 
diff --git a/sources/corepackUtils.ts b/sources/corepackUtils.ts
index a08b9ded2..db7b39d22 100644
--- a/sources/corepackUtils.ts
+++ b/sources/corepackUtils.ts
@@ -14,6 +14,12 @@ import * as nodeUtils                                          from './nodeUtils
 import * as npmRegistryUtils                                   from './npmRegistryUtils';
 import {RegistrySpec, Descriptor, Locator, PackageManagerSpec} from './types';
 
+export function getRegistryFromPackageManagerSpec(spec: PackageManagerSpec) {
+  return process.env.COREPACK_NPM_REGISTRY
+    ? spec.npmRegistry ?? spec.registry
+    : spec.registry;
+}
+
 export async function fetchLatestStableVersion(spec: RegistrySpec): Promise<string> {
   switch (spec.type) {
     case `npm`: {
diff --git a/sources/types.ts b/sources/types.ts
index bc02792fa..abf4cdb8b 100644
--- a/sources/types.ts
+++ b/sources/types.ts
@@ -47,6 +47,7 @@ export interface PackageManagerSpec {
   url: string;
   bin: BinSpec | BinList;
   registry: RegistrySpec;
+  npmRegistry?: NpmRegistrySpec;
   commands?: {
     use?: Array<string>;
   };