• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1const liborg = require('libnpmorg')
2const otplease = require('../utils/otplease.js')
3const Table = require('cli-table3')
4const BaseCommand = require('../base-command.js')
5
6class Org extends BaseCommand {
7  static description = 'Manage orgs'
8  static name = 'org'
9  static usage = [
10    'set orgname username [developer | admin | owner]',
11    'rm orgname username',
12    'ls orgname [<username>]',
13  ]
14
15  static params = ['registry', 'otp', 'json', 'parseable']
16
17  static async completion (opts) {
18    const argv = opts.conf.argv.remain
19    if (argv.length === 2) {
20      return ['set', 'rm', 'ls']
21    }
22
23    switch (argv[2]) {
24      case 'ls':
25      case 'add':
26      case 'rm':
27      case 'set':
28        return []
29      default:
30        throw new Error(argv[2] + ' not recognized')
31    }
32  }
33
34  async exec ([cmd, orgname, username, role]) {
35    return otplease(this.npm, {
36      ...this.npm.flatOptions,
37    }, opts => {
38      switch (cmd) {
39        case 'add':
40        case 'set':
41          return this.set(orgname, username, role, opts)
42        case 'rm':
43          return this.rm(orgname, username, opts)
44        case 'ls':
45          return this.ls(orgname, username, opts)
46        default:
47          throw this.usageError()
48      }
49    })
50  }
51
52  async set (org, user, role, opts) {
53    role = role || 'developer'
54    if (!org) {
55      throw new Error('First argument `orgname` is required.')
56    }
57
58    if (!user) {
59      throw new Error('Second argument `username` is required.')
60    }
61
62    if (!['owner', 'admin', 'developer'].find(x => x === role)) {
63      throw new Error(
64        /* eslint-disable-next-line max-len */
65        'Third argument `role` must be one of `owner`, `admin`, or `developer`, with `developer` being the default value if omitted.'
66      )
67    }
68
69    const memDeets = await liborg.set(org, user, role, opts)
70    if (opts.json) {
71      this.npm.output(JSON.stringify(memDeets, null, 2))
72    } else if (opts.parseable) {
73      this.npm.output(['org', 'orgsize', 'user', 'role'].join('\t'))
74      this.npm.output(
75        [memDeets.org.name, memDeets.org.size, memDeets.user, memDeets.role].join('\t')
76      )
77    } else if (!this.npm.silent) {
78      this.npm.output(
79        `Added ${memDeets.user} as ${memDeets.role} to ${memDeets.org.name}. You now have ${
80            memDeets.org.size
81          } member${memDeets.org.size === 1 ? '' : 's'} in this org.`
82      )
83    }
84
85    return memDeets
86  }
87
88  async rm (org, user, opts) {
89    if (!org) {
90      throw new Error('First argument `orgname` is required.')
91    }
92
93    if (!user) {
94      throw new Error('Second argument `username` is required.')
95    }
96
97    await liborg.rm(org, user, opts)
98    const roster = await liborg.ls(org, opts)
99    user = user.replace(/^[~@]?/, '')
100    org = org.replace(/^[~@]?/, '')
101    const userCount = Object.keys(roster).length
102    if (opts.json) {
103      this.npm.output(
104        JSON.stringify({
105          user,
106          org,
107          userCount,
108          deleted: true,
109        })
110      )
111    } else if (opts.parseable) {
112      this.npm.output(['user', 'org', 'userCount', 'deleted'].join('\t'))
113      this.npm.output([user, org, userCount, true].join('\t'))
114    } else if (!this.npm.silent) {
115      this.npm.output(
116        `Successfully removed ${user} from ${org}. You now have ${userCount} member${
117          userCount === 1 ? '' : 's'
118        } in this org.`
119      )
120    }
121  }
122
123  async ls (org, user, opts) {
124    if (!org) {
125      throw new Error('First argument `orgname` is required.')
126    }
127
128    let roster = await liborg.ls(org, opts)
129    if (user) {
130      const newRoster = {}
131      if (roster[user]) {
132        newRoster[user] = roster[user]
133      }
134
135      roster = newRoster
136    }
137    if (opts.json) {
138      this.npm.output(JSON.stringify(roster, null, 2))
139    } else if (opts.parseable) {
140      this.npm.output(['user', 'role'].join('\t'))
141      Object.keys(roster).forEach(u => {
142        this.npm.output([u, roster[u]].join('\t'))
143      })
144    } else if (!this.npm.silent) {
145      const table = new Table({ head: ['user', 'role'] })
146      Object.keys(roster)
147        .sort()
148        .forEach(u => {
149          table.push([u, roster[u]])
150        })
151      this.npm.output(table.toString())
152    }
153  }
154}
155module.exports = Org
156