diff --git a/workspaces/arborist/lib/arborist/reify.js b/workspaces/arborist/lib/arborist/reify.js index 7ce22ff86b721..796be4fa507c4 100644 --- a/workspaces/arborist/lib/arborist/reify.js +++ b/workspaces/arborist/lib/arborist/reify.js @@ -9,6 +9,7 @@ const debug = require('../debug.js') const { walkUp } = require('walk-up-path') const { log, time } = require('proc-log') const rpj = require('read-package-json-fast') +const hgi = require('hosted-git-info') const { dirname, resolve, relative, join } = require('node:path') const { depth: dfwalk } = require('treeverse') @@ -886,7 +887,7 @@ module.exports = cls => class Reifier extends cls { // Shrinkwrap and Node classes carefully, so for now, just treat // the default reg as the magical animal that it has been. try { - const resolvedURL = new URL(resolved) + const resolvedURL = hgi.parseUrl(resolved) if ((this.options.replaceRegistryHost === resolvedURL.hostname) || this.options.replaceRegistryHost === 'always') { diff --git a/workspaces/arborist/test/arborist/reify.js b/workspaces/arborist/test/arborist/reify.js index 4f565ffc80860..566a62273e710 100644 --- a/workspaces/arborist/test/arborist/reify.js +++ b/workspaces/arborist/test/arborist/reify.js @@ -3343,6 +3343,24 @@ t.test('should preserve exact ranges, missing actual tree', async (t) => { }, }) + const customGitSshPackument = JSON.stringify({ + _id: 'gitssh', + _rev: 'lkjadflkjasdf', + name: 'gitssh', + 'dist-tags': { latest: '1.1.1' }, + versions: { + '1.1.1': { + name: 'gitssh', + version: '1.1.1', + dist: { + // this is a url that `new URL()` cant parse + // https://github.com/npm/cli/issues/5278 + tarball: 'git+ssh://git@customgit.com:a/b/c.git#lkjadflkjasdf', + }, + }, + }, + }) + const notAUrlPackument = JSON.stringify({ _id: 'notaurl', _rev: 'lkjadflkjasdf', @@ -3359,6 +3377,36 @@ t.test('should preserve exact ranges, missing actual tree', async (t) => { }, }) + t.test('valid custom hosted git url', async (t) => { + const testdir = t.testdir({ + project: { + 'package.json': JSON.stringify({ + name: 'myproject', + version: '1.0.0', + dependencies: { + gitssh: '1.1.1', + }, + }), + }, + }) + + tnock(t, 'https://registry.github.com') + .get('/gitssh') + .reply(200, customGitSshPackument) + + const getLogs = warningTracker() + + const arb = new Arborist({ + path: resolve(testdir, 'project'), + registry: 'https://registry.github.com', + cache: resolve(testdir, 'cache'), + }) + await arb.reify() + // since it's not throwing an error on invalid url and returning undefined + // which trashes the node, so here we can only check if it has no warnings + t.strictSame(getLogs(), [], 'did not get warnings') + }) + t.test('host should not be replaced replaceRegistryHost=never', async (t) => { const testdir = t.testdir({ project: {