codekingpro/portable-devtools
114k
1const npmFetch = require('npm-registry-fetch')
2const { otplease } = require('../utils/auth.js')
3const npa = require('npm-package-arg')
4const { log } = require('proc-log')
5const semver = require('semver')
6const getIdentity = require('../utils/get-identity.js')
7const libaccess = require('libnpmaccess')
8const BaseCommand = require('../base-cmd.js')
9
10class Deprecate extends BaseCommand {
11 static description = 'Deprecate a version of a package'
12 static name = 'deprecate'
13 static usage = ['<package-spec> <message>']
14 static params = [
15 'registry',
16 'otp',
17 'dry-run',
18 ]
19
20 static ignoreImplicitWorkspace = true
21
22 static async completion (opts, npm) {
23 if (opts.conf.argv.remain.length > 1) {
24 return []
25 }
26
27 const username = await getIdentity(npm, npm.flatOptions)
28 const packages = await libaccess.getPackages(username, npm.flatOptions)
29 return Object.keys(packages)
30 .filter((name) =>
31 packages[name] === 'write' &&
32 (opts.conf.argv.remain.length === 0 ||
33 name.startsWith(opts.conf.argv.remain[0])))
34 }
35
36 async exec ([pkg, msg]) {
37 // msg == null because '' is a valid value, it indicates undeprecate
38 if (!pkg || msg == null) {
39 throw this.usageError()
40 }
41
42 // fetch the data and make sure it exists.
43 const p = npa(pkg)
44 const spec = p.rawSpec === '*' ? '*' : p.fetchSpec
45
46 if (semver.validRange(spec, true) === null) {
47 throw new Error(`invalid version range: ${spec}`)
48 }
49
50 const uri = '/' + p.escapedName
51 const packument = await npmFetch.json(uri, {
52 ...this.npm.flatOptions,
53 spec: p,
54 query: { write: true },
55 })
56
57 const versions = Object.keys(packument.versions)
58 .filter(v => semver.satisfies(v, spec, { includePrerelease: true }))
59
60 const dryRun = this.npm.config.get('dry-run')
61
62 if (versions.length) {
63 for (const v of versions) {
64 packument.versions[v].deprecated = msg
65 if (msg) {
66 log.notice(`deprecating ${packument.name}@${v} with message "${msg}"`)
67 } else {
68 log.notice(`undeprecating ${packument.name}@${v}`)
69 }
70 }
71 if (!dryRun) {
72 return otplease(this.npm, this.npm.flatOptions, opts => npmFetch(uri, {
73 ...opts,
74 spec: p,
75 method: 'PUT',
76 body: packument,
77 ignoreBody: true,
78 }))
79 }
80 } else {
81 log.warn('deprecate', 'No version found for', p.rawSpec)
82 }
83 }
84}
85
86module.exports = Deprecate
87 