1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
const path = require('path')
const util = require('util')
const log = require('npmlog')
const npa = require('npm-package-arg')
const libaccess = require('libnpmaccess')
const npmFetch = require('npm-registry-fetch')
const libunpub = require('libnpmpublish').unpublish
const readJson = util.promisify(require('read-package-json'))
const otplease = require('./utils/otplease.js')
const getIdentity = require('./utils/get-identity.js')
const BaseCommand = require('./base-command.js')
class Unpublish extends BaseCommand {
static get description () {
return 'Remove a package from the registry'
}
/* istanbul ignore next - see test/lib/load-all-commands.js */
static get name () {
return 'unpublish'
}
/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
return ['[<@scope>/]<pkg>[@<version>]']
}
async completion (args) {
const { partialWord, conf } = args
if (conf.argv.remain.length >= 3)
return []
const opts = this.npm.flatOptions
const username = await getIdentity(this.npm, { ...opts }).catch(() => null)
if (!username)
return []
const access = await libaccess.lsPackages(username, opts)
// do a bit of filtering at this point, so that we don't need
// to fetch versions for more than one thing, but also don't
// accidentally unpublish a whole project
let pkgs = Object.keys(access || {})
if (!partialWord || !pkgs.length)
return pkgs
const pp = npa(partialWord).name
pkgs = pkgs.filter(p => !p.indexOf(pp))
if (pkgs.length > 1)
return pkgs
const json = await npmFetch.json(npa(pkgs[0]).escapedName, opts)
const versions = Object.keys(json.versions)
if (!versions.length)
return pkgs
else
return versions.map(v => `${pkgs[0]}@${v}`)
}
exec (args, cb) {
this.unpublish(args).then(() => cb()).catch(cb)
}
async unpublish (args) {
if (args.length > 1)
throw new Error(this.usage)
const spec = args.length && npa(args[0])
const force = this.npm.config.get('force')
const silent = this.npm.config.get('silent')
const loglevel = this.npm.config.get('loglevel')
let pkgName
let pkgVersion
log.silly('unpublish', 'args[0]', args[0])
log.silly('unpublish', 'spec', spec)
if (!spec.rawSpec && !force) {
throw new Error(
'Refusing to delete entire project.\n' +
'Run with --force to do this.\n' +
this.usage
)
}
const opts = this.npm.flatOptions
if (!spec || path.resolve(spec.name) === this.npm.localPrefix) {
// if there's a package.json in the current folder, then
// read the package name and version out of that.
const pkgJson = path.join(this.npm.localPrefix, 'package.json')
let manifest
try {
manifest = await readJson(pkgJson)
} catch (err) {
if (err && err.code !== 'ENOENT' && err.code !== 'ENOTDIR')
throw err
else
throw new Error(`Usage: ${this.usage}`)
}
log.verbose('unpublish', manifest)
const { name, version, publishConfig } = manifest
const pkgJsonSpec = npa.resolve(name, version)
const optsWithPub = { ...opts, publishConfig }
await otplease(opts, opts => libunpub(pkgJsonSpec, optsWithPub))
pkgName = name
pkgVersion = version ? `@${version}` : ''
} else {
await otplease(opts, opts => libunpub(spec, opts))
pkgName = spec.name
pkgVersion = spec.type === 'version' ? `@${spec.rawSpec}` : ''
}
if (!silent && loglevel !== 'silent')
this.npm.output(`- ${pkgName}${pkgVersion}`)
}
}
module.exports = Unpublish
|