diff --git a/lib/fetcher.js b/lib/fetcher.js index 65e97e20..d88724c5 100644 --- a/lib/fetcher.js +++ b/lib/fetcher.js @@ -105,8 +105,15 @@ class FetcherBase { this[_readPackageJson] = readPackageJsonFast } - // config values: npmjs (default), never - this.replaceRegistryHost = opts.replaceRegistryHost === 'never' ? 'never' : 'npmjs' + // config values: npmjs (default), never, always + // we don't want to mutate the original value + if (opts.replaceRegistryHost !== 'never' + && opts.replaceRegistryHost !== 'always' + ) { + this.replaceRegistryHost = 'npmjs' + } else { + this.replaceRegistryHost = opts.replaceRegistryHost + } this.defaultTag = opts.defaultTag || 'latest' this.registry = removeTrailingSlashes(opts.registry || 'https://registry.npmjs.org') diff --git a/lib/remote.js b/lib/remote.js index 3404ea94..14e68780 100644 --- a/lib/remote.js +++ b/lib/remote.js @@ -5,7 +5,7 @@ const pacoteVersion = require('../package.json').version const fetch = require('npm-registry-fetch') const Minipass = require('minipass') // The default registry URL is a string of great magic. -const magic = /^https?:\/\/registry\.npmjs\.org\// +const magicHost = 'https://registry.npmjs.org' const _cacheFetches = Symbol.for('pacote.Fetcher._cacheFetches') const _headers = Symbol('_headers') @@ -13,10 +13,13 @@ class RemoteFetcher extends Fetcher { constructor (spec, opts) { super(spec, opts) this.resolved = this.spec.fetchSpec - if (this.replaceRegistryHost === 'npmjs' - && magic.test(this.resolved) - && !magic.test(this.registry + '/')) { - this.resolved = this.resolved.replace(magic, this.registry + '/') + const resolvedURL = new URL(this.resolved) + if ( + (this.replaceRegistryHost === 'npmjs' + && resolvedURL.origin === magicHost) + || this.replaceRegistryHost === 'always' + ) { + this.resolved = new URL(resolvedURL.pathname, this.registry).href } // nam is a fermented pork sausage that is good to eat diff --git a/test/fetcher.js b/test/fetcher.js index 34000ab8..70811cc8 100644 --- a/test/fetcher.js +++ b/test/fetcher.js @@ -531,3 +531,10 @@ t.test('replace opts never', t => { t.equal(f.replaceRegistryHost, 'never') t.end() }) +t.test('replace opts always', t => { + const f = new FileFetcher('pkg.tgz', { + replaceRegistryHost: 'always', + }) + t.equal(f.replaceRegistryHost, 'always') + t.end() +}) diff --git a/test/remote.js b/test/remote.js index 850de2eb..a39141de 100644 --- a/test/remote.js +++ b/test/remote.js @@ -141,3 +141,49 @@ t.test('get a timeout error from the http fetch', t => { code: /FETCH_ERROR|ERR_SOCKET_TIMEOUT/, }) }) + +t.test('option replaceRegistryHost', rhTest => { + const tnock = require('./fixtures/tnock') + const { join } = require('path') + const abbrevTGZ = fs.readFileSync(abbrev) + + rhTest.test('host should be replaced if set to always on npmjs registry', async ct => { + const testdir = t.testdir() + tnock(ct, 'https://registry.github.com') + .get('/abbrev/-/abbrev-1.1.1.tgz') + .reply(200, abbrevTGZ) + + const fetcher = new RemoteFetcher( + 'https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz', + { + registry: 'https://registry.github.com', + cache: join(testdir, 'cache'), + fullReadJson: true, + replaceRegistryHost: 'always', + }) + ct.equal(fetcher.replaceRegistryHost, 'always') + const tarball = await fetcher.tarball() + ct.match(tarball, abbrevTGZ) + }) + + rhTest.test('host should be replaced if set to always on other registry', async ct => { + const testdir = t.testdir() + tnock(ct, 'https://registry.github.com') + .get('/abbrev/-/abbrev-1.1.1.tgz') + .reply(200, abbrevTGZ) + + const fetcher = new RemoteFetcher( + 'https://registry.somethingelse.org/abbrev/-/abbrev-1.1.1.tgz', + { + registry: 'https://registry.github.com', + cache: join(testdir, 'cache'), + fullReadJson: true, + replaceRegistryHost: 'always', + }) + ct.equal(fetcher.replaceRegistryHost, 'always') + const tarball = await fetcher.tarball() + ct.match(tarball, abbrevTGZ) + }) + + rhTest.end() +})