org.js 4.6 KB

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