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