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