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