Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuy Adorno <ruyadorno@hotmail.com>2022-04-26 23:16:36 +0300
committerGitHub <noreply@github.com>2022-04-26 23:16:36 +0300
commite9163b48d8e46a80d2a4cc98c492b94dfa152cb8 (patch)
treebaa36b8aa9f7297b5ef216956fd6af6dc1267072 /workspaces/libnpmpublish
parentfa3d82989df7071cfe500c5f9cc09c597bcc17ee (diff)
fix(libnpmpublish): unpublish from custom reg (#4657)
Fixes unpublishing a package from a registry url that has pathnames after its hostname. Fixes: https://github.com/npm/cli/issues/4253
Diffstat (limited to 'workspaces/libnpmpublish')
-rw-r--r--workspaces/libnpmpublish/lib/unpublish.js21
-rw-r--r--workspaces/libnpmpublish/test/unpublish.js55
2 files changed, 74 insertions, 2 deletions
diff --git a/workspaces/libnpmpublish/lib/unpublish.js b/workspaces/libnpmpublish/lib/unpublish.js
index 91f5252aa..9b124c114 100644
--- a/workspaces/libnpmpublish/lib/unpublish.js
+++ b/workspaces/libnpmpublish/lib/unpublish.js
@@ -1,9 +1,26 @@
'use strict'
+const { URL } = require('url')
const npa = require('npm-package-arg')
const npmFetch = require('npm-registry-fetch')
const semver = require('semver')
-const { URL } = require('url')
+
+// given a tarball url and a registry url, returns just the
+// relevant pathname portion of it, so that it can be handled
+// elegantly by npm-registry-fetch which only expects pathnames
+// and handles the registry hostname via opts
+const getPathname = (tarball, registry) => {
+ const registryUrl = new URL(registry).pathname.slice(1)
+ let tarballUrl = new URL(tarball).pathname.slice(1)
+
+ // test the tarball url to see if it starts with a possible
+ // pathname from the registry url, in that case strips that portion
+ // of it so that we only return the post-registry-url pathname
+ if (registryUrl) {
+ tarballUrl = tarballUrl.slice(registryUrl.length)
+ }
+ return tarballUrl
+}
const unpublish = async (spec, opts) => {
spec = npa(spec)
@@ -82,7 +99,7 @@ const unpublish = async (spec, opts) => {
...opts,
query: { write: true },
})
- const tarballUrl = new URL(dist.tarball).pathname.slice(1)
+ const tarballUrl = getPathname(dist.tarball, opts.registry)
await npmFetch(`${tarballUrl}/-rev/${_rev}`, {
...opts,
method: 'DELETE',
diff --git a/workspaces/libnpmpublish/test/unpublish.js b/workspaces/libnpmpublish/test/unpublish.js
index 6fbe80276..b59dad6d3 100644
--- a/workspaces/libnpmpublish/test/unpublish.js
+++ b/workspaces/libnpmpublish/test/unpublish.js
@@ -134,6 +134,61 @@ t.test('unpublish specific version', async t => {
t.ok(ret, 'foo was unpublished')
})
+t.test('unpublishing from a custom registry', async t => {
+ const opt = {
+ registry: 'https://artifactory.example.com/api/npm/npm-snapshots/',
+ }
+ const reg = opt.registry
+ const doc = {
+ _id: 'foo',
+ _rev: REV,
+ _revisions: [1, 2, 3],
+ _attachments: [1, 2, 3],
+ name: 'foo',
+ 'dist-tags': {
+ latest: '1.0.1',
+ },
+ versions: {
+ '1.0.0': {
+ name: 'foo',
+ dist: {
+ tarball: `${reg}/foo/-/foo-1.0.0.tgz`,
+ },
+ },
+ '1.0.1': {
+ name: 'foo',
+ dist: {
+ tarball: `${reg}/foo/-/foo-1.0.1.tgz`,
+ },
+ },
+ },
+ }
+ const postEdit = {
+ _id: 'foo',
+ _rev: REV,
+ name: 'foo',
+ 'dist-tags': {
+ latest: '1.0.0',
+ },
+ versions: {
+ '1.0.0': {
+ name: 'foo',
+ dist: {
+ tarball: `${reg}/foo/-/foo-1.0.0.tgz`,
+ },
+ },
+ },
+ }
+
+ const srv = tnock(t, reg)
+ srv.get('/foo?write=true').reply(200, doc)
+ srv.put(`/foo/-rev/${REV}`, postEdit).reply(200)
+ srv.get('/foo?write=true').reply(200, postEdit)
+ srv.delete(`/foo/-/foo-1.0.1.tgz/-rev/${REV}`).reply(200)
+ const ret = await unpub('foo@1.0.1', opt)
+ t.ok(ret, 'foo was unpublished')
+})
+
t.test('404 considered a success', async t => {
const srv = tnock(t, REG)
srv.get('/foo?write=true').reply(404)