From 41d92948b114e7b51facfe01cd2a20e560135e65 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Tue, 9 Jun 2020 10:55:02 +0300 Subject: [PATCH] fix: installing tarballs from registry origin via non-standard URLs close #2549 PR #2620 --- .changeset/great-chairs-look.md | 5 +++ .changeset/lucky-oranges-wonder.md | 6 ++++ .changeset/nasty-wasps-rest.md | 8 +++++ .changeset/swift-glasses-impress.md | 5 +++ packages/dependency-path/src/index.ts | 2 +- packages/dependency-path/test/index.ts | 1 - packages/supi/src/install/lockfile.ts | 2 +- packages/supi/test/lockfile.ts | 48 +++++++++++++++++++++++-- packages/tarball-resolver/src/index.ts | 7 +--- packages/tarball-resolver/test/index.ts | 6 ++-- 10 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 .changeset/great-chairs-look.md create mode 100644 .changeset/lucky-oranges-wonder.md create mode 100644 .changeset/nasty-wasps-rest.md create mode 100644 .changeset/swift-glasses-impress.md diff --git a/.changeset/great-chairs-look.md b/.changeset/great-chairs-look.md new file mode 100644 index 0000000000..64de436cfe --- /dev/null +++ b/.changeset/great-chairs-look.md @@ -0,0 +1,5 @@ +--- +"dependency-path": major +--- + +relative() should always remove the registry from the IDs start. diff --git a/.changeset/lucky-oranges-wonder.md b/.changeset/lucky-oranges-wonder.md new file mode 100644 index 0000000000..72eddfb778 --- /dev/null +++ b/.changeset/lucky-oranges-wonder.md @@ -0,0 +1,6 @@ +--- +"@pnpm/default-resolver": major +"@pnpm/tarball-resolver": major +--- + +The direct tarball dependency ID starts with a @ and the tarball extension is not removed. diff --git a/.changeset/nasty-wasps-rest.md b/.changeset/nasty-wasps-rest.md new file mode 100644 index 0000000000..b150bae5a5 --- /dev/null +++ b/.changeset/nasty-wasps-rest.md @@ -0,0 +1,8 @@ +--- +"supi": minor +--- + +It should be possible to install a tarball through a non-standard URL endpoint served via the registry domain. + +For instance, the configured registry is `https://registry.npm.taobao.org/`. +It should be possible to run `pnpm add https://registry.npm.taobao.org/vue/download/vue-2.0.0.tgz` diff --git a/.changeset/swift-glasses-impress.md b/.changeset/swift-glasses-impress.md new file mode 100644 index 0000000000..81f3c294c8 --- /dev/null +++ b/.changeset/swift-glasses-impress.md @@ -0,0 +1,5 @@ +--- +"@pnpm/resolve-dependencies": major +--- + +Expects direct tarball IDs to start with @. diff --git a/packages/dependency-path/src/index.ts b/packages/dependency-path/src/index.ts index ada008a9ac..b3a84dcecc 100644 --- a/packages/dependency-path/src/index.ts +++ b/packages/dependency-path/src/index.ts @@ -65,7 +65,7 @@ export function relative ( ) { const registryName = encodeRegistry(getRegistryByPackageName(registries, packageName)) - if (absoluteResolutionLoc.startsWith(`${registryName}/`) && !absoluteResolutionLoc.includes('/-/')) { + if (absoluteResolutionLoc.startsWith(`${registryName}/`)) { return absoluteResolutionLoc.substr(absoluteResolutionLoc.indexOf('/')) } return absoluteResolutionLoc diff --git a/packages/dependency-path/test/index.ts b/packages/dependency-path/test/index.ts index 7b6fdd06c3..261fcb8c39 100644 --- a/packages/dependency-path/test/index.ts +++ b/packages/dependency-path/test/index.ts @@ -109,7 +109,6 @@ test('relative()', t => { t.equal(relative(registries, 'foo', 'registry.npmjs.org/foo/1.0.0'), '/foo/1.0.0') t.equal(relative(registries, '@foo/foo', 'localhost+4873/@foo/foo/1.0.0'), '/@foo/foo/1.0.0') t.equal(relative(registries, 'foo', 'registry.npmjs.org/foo/1.0.0/PeLdniYiO858gXNY39o5wISKyw'), '/foo/1.0.0/PeLdniYiO858gXNY39o5wISKyw') - t.equal(relative(registries, 'foo', 'registry.npmjs.org/foo/-/foo-1.0.0'), 'registry.npmjs.org/foo/-/foo-1.0.0', 'a tarball ID should remain absolute') t.end() }) diff --git a/packages/supi/src/install/lockfile.ts b/packages/supi/src/install/lockfile.ts index 12ec01ea6e..f575a0512b 100644 --- a/packages/supi/src/install/lockfile.ts +++ b/packages/supi/src/install/lockfile.ts @@ -15,7 +15,7 @@ export function depPathToRef ( if (opts.resolution.type) return depPath const registryName = encodeRegistry(getRegistryByPackageName(opts.registries, opts.realName)) - if (depPath.startsWith(`${registryName}/`) && !depPath.includes('/-/')) { + if (depPath.startsWith(`${registryName}/`)) { depPath = depPath.replace(`${registryName}/`, '/') } if (depPath[0] === '/' && opts.alias === opts.realName) { diff --git a/packages/supi/test/lockfile.ts b/packages/supi/test/lockfile.ts index cb42f017e5..13e3ef40cf 100644 --- a/packages/supi/test/lockfile.ts +++ b/packages/supi/test/lockfile.ts @@ -800,7 +800,7 @@ test('packages installed via tarball URL from the default registry are normalize t.deepEqual(lockfile, { dependencies: { - 'is-positive': 'registry.npmjs.org/is-positive/-/is-positive-1.0.0', + 'is-positive': '@registry.npmjs.org/is-positive/-/is-positive-1.0.0.tgz', 'pkg-with-tarball-dep-from-registry': '1.0.0', }, lockfileVersion: LOCKFILE_VERSION, @@ -820,7 +820,7 @@ test('packages installed via tarball URL from the default registry are normalize integrity: getIntegrity('pkg-with-tarball-dep-from-registry', '1.0.0'), }, }, - 'registry.npmjs.org/is-positive/-/is-positive-1.0.0': { + '@registry.npmjs.org/is-positive/-/is-positive-1.0.0.tgz': { dev: false, engines: { node: '>=0.10.0' }, name: 'is-positive', @@ -1185,3 +1185,47 @@ test('tarball domain differs from registry domain', async (t: tape.Test) => { specifiers: { 'is-positive': '^3.1.0' }, }) }) + +test('tarball installed through non-standard URL endpoint from the registry domain', async (t: tape.Test) => { + nock('https://registry.npmjs.org', { allowUnmocked: true }) + .get('/is-positive/download/is-positive-3.1.0.tgz') + .replyWithFile(200, tarballPath) + + const project = prepareEmpty(t) + + await addDependenciesToPackage({}, + [ + 'https://registry.npmjs.org/is-positive/download/is-positive-3.1.0.tgz', + ], await testDefaults({ + fastUnpack: false, + lockfileOnly: true, + registries: { + default: 'https://registry.npmjs.org/', + }, + save: true, + }) + ) + + const lockfile = await project.readLockfile() + + t.deepEqual(lockfile, { + dependencies: { + 'is-positive': '@registry.npmjs.org/is-positive/download/is-positive-3.1.0.tgz', + }, + lockfileVersion: LOCKFILE_VERSION, + packages: { + '@registry.npmjs.org/is-positive/download/is-positive-3.1.0.tgz': { + dev: false, + engines: { node: '>=0.10.0' }, + name: 'is-positive', + resolution: { + tarball: 'https://registry.npmjs.org/is-positive/download/is-positive-3.1.0.tgz', + }, + version: '3.1.0', + }, + }, + specifiers: { + 'is-positive': 'https://registry.npmjs.org/is-positive/download/is-positive-3.1.0.tgz', + }, + }) +}) diff --git a/packages/tarball-resolver/src/index.ts b/packages/tarball-resolver/src/index.ts index d6af54a5c9..e5ed510767 100644 --- a/packages/tarball-resolver/src/index.ts +++ b/packages/tarball-resolver/src/index.ts @@ -8,12 +8,7 @@ export default async function resolveTarball ( } return { - id: wantedDependency.pref - .replace(/^.*:\/\/(git@)?/, '') - .replace(/\.tgz$/, ''), - // TODO BREAKING CHANGE: uncomment the following: (or never remove extensions) - // .replace(/\.tar.gz$/, ''), - // .replace(/\.tar$/, ''), + id: `@${wantedDependency.pref.replace(/^.*:\/\/(git@)?/, '')}`, normalizedPref: wantedDependency.pref, resolution: { tarball: wantedDependency.pref, diff --git a/packages/tarball-resolver/test/index.ts b/packages/tarball-resolver/test/index.ts index 9217a4c8c3..c0eab25aaf 100644 --- a/packages/tarball-resolver/test/index.ts +++ b/packages/tarball-resolver/test/index.ts @@ -6,7 +6,7 @@ test('tarball from npm registry', async t => { const resolutionResult = await resolveFromTarball({ pref: 'http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz' }) t.deepEqual(resolutionResult, { - id: 'registry.npmjs.org/is-array/-/is-array-1.0.1', + id: '@registry.npmjs.org/is-array/-/is-array-1.0.1.tgz', normalizedPref: 'http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz', resolution: { tarball: 'http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz', @@ -21,7 +21,7 @@ test('tarball not from npm registry', async t => { const resolutionResult = await resolveFromTarball({ pref: 'https://github.com/hegemonic/taffydb/tarball/master' }) t.deepEqual(resolutionResult, { - id: 'github.com/hegemonic/taffydb/tarball/master', + id: '@github.com/hegemonic/taffydb/tarball/master', normalizedPref: 'https://github.com/hegemonic/taffydb/tarball/master', resolution: { tarball: 'https://github.com/hegemonic/taffydb/tarball/master', @@ -36,7 +36,7 @@ test('tarballs from GitHub (is-negative)', async t => { const resolutionResult = await resolveFromTarball({ pref: 'https://github.com/kevva/is-negative/archive/1d7e288222b53a0cab90a331f1865220ec29560c.tar.gz' }) t.deepEqual(resolutionResult, { - id: 'github.com/kevva/is-negative/archive/1d7e288222b53a0cab90a331f1865220ec29560c.tar.gz', + id: '@github.com/kevva/is-negative/archive/1d7e288222b53a0cab90a331f1865220ec29560c.tar.gz', normalizedPref: 'https://github.com/kevva/is-negative/archive/1d7e288222b53a0cab90a331f1865220ec29560c.tar.gz', resolution: { tarball: 'https://github.com/kevva/is-negative/archive/1d7e288222b53a0cab90a331f1865220ec29560c.tar.gz',