UNPKG

7.09 kBJavaScriptView Raw
1
2module.exports = owner
3
4owner.usage = "npm owner add <username> <pkg>"
5 + "\nnpm owner rm <username> <pkg>"
6 + "\nnpm owner ls <pkg>"
7
8var npm = require("./npm.js")
9 , registry = npm.registry
10 , log = require("npmlog")
11 , readJson = require("read-package-json")
12 , mapToRegistry = require("./utils/map-to-registry.js")
13
14owner.completion = function (opts, cb) {
15 var argv = opts.conf.argv.remain
16 if (argv.length > 4) return cb()
17 if (argv.length <= 2) {
18 var subs = ["add", "rm"]
19 if (opts.partialWord === "l") subs.push("ls")
20 else subs.push("ls", "list")
21 return cb(null, subs)
22 }
23
24 npm.commands.whoami([], true, function (er, username) {
25 if (er) return cb()
26
27 var un = encodeURIComponent(username)
28 var byUser, theUser
29 switch (argv[2]) {
30 case "ls":
31 if (argv.length > 3) return cb()
32 return mapToRegistry("-/short", npm.config, function (er, uri) {
33 if (er) return cb(er)
34
35 registry.get(uri, null, cb)
36 })
37
38 case "rm":
39 if (argv.length > 3) {
40 theUser = encodeURIComponent(argv[3])
41 byUser = "-/by-user/" + theUser + "|" + un
42 return mapToRegistry(byUser, npm.config, function (er, uri) {
43 if (er) return cb(er)
44
45 console.error(uri)
46 registry.get(uri, null, function (er, d) {
47 if (er) return cb(er)
48 // return the intersection
49 return cb(null, d[theUser].filter(function (p) {
50 // kludge for server adminery.
51 return un === "isaacs" || d[un].indexOf(p) === -1
52 }))
53 })
54 })
55 }
56 // else fallthrough
57 case "add":
58 if (argv.length > 3) {
59 theUser = encodeURIComponent(argv[3])
60 byUser = "-/by-user/" + theUser + "|" + un
61 return mapToRegistry(byUser, npm.config, function (er, uri) {
62 if (er) return cb(er)
63
64 console.error(uri)
65 registry.get(uri, null, function (er, d) {
66 console.error(uri, er || d)
67 // return mine that they're not already on.
68 if (er) return cb(er)
69 var mine = d[un] || []
70 , theirs = d[theUser] || []
71 return cb(null, mine.filter(function (p) {
72 return theirs.indexOf(p) === -1
73 }))
74 })
75 })
76 }
77 // just list all users who aren't me.
78 return mapToRegistry("-/users", npm.config, function (er, uri) {
79 if (er) return cb(er)
80
81 registry.get(uri, null, function (er, list) {
82 if (er) return cb()
83 return cb(null, Object.keys(list).filter(function (n) {
84 return n !== un
85 }))
86 })
87 })
88
89 default:
90 return cb()
91 }
92 })
93}
94
95function owner (args, cb) {
96 var action = args.shift()
97 switch (action) {
98 case "ls": case "list": return ls(args[0], cb)
99 case "add": return add(args[0], args[1], cb)
100 case "rm": case "remove": return rm(args[0], args[1], cb)
101 default: return unknown(action, cb)
102 }
103}
104
105function ls (pkg, cb) {
106 if (!pkg) return readLocalPkg(function (er, pkg) {
107 if (er) return cb(er)
108 if (!pkg) return cb(owner.usage)
109 ls(pkg, cb)
110 })
111
112 mapToRegistry(pkg, npm.config, function (er, uri) {
113 if (er) return cb(er)
114
115 registry.get(uri, null, function (er, data) {
116 var msg = ""
117 if (er) {
118 log.error("owner ls", "Couldn't get owner data", pkg)
119 return cb(er)
120 }
121 var owners = data.maintainers
122 if (!owners || !owners.length) msg = "admin party!"
123 else msg = owners.map(function (o) {
124 return o.name + " <" + o.email + ">"
125 }).join("\n")
126 console.log(msg)
127 cb(er, owners)
128 })
129 })
130}
131
132function add (user, pkg, cb) {
133 if (!user) return cb(owner.usage)
134 if (!pkg) return readLocalPkg(function (er, pkg) {
135 if (er) return cb(er)
136 if (!pkg) return cb(new Error(owner.usage))
137 add(user, pkg, cb)
138 })
139
140 log.verbose("owner add", "%s to %s", user, pkg)
141 mutate(pkg, user, function (u, owners) {
142 if (!owners) owners = []
143 for (var i = 0, l = owners.length; i < l; i ++) {
144 var o = owners[i]
145 if (o.name === u.name) {
146 log.info( "owner add"
147 , "Already a package owner: " + o.name + " <" + o.email + ">")
148 return false
149 }
150 }
151 owners.push(u)
152 return owners
153 }, cb)
154}
155
156function rm (user, pkg, cb) {
157 if (!pkg) return readLocalPkg(function (er, pkg) {
158 if (er) return cb(er)
159 if (!pkg) return cb(new Error(owner.usage))
160 rm(user, pkg, cb)
161 })
162
163 log.verbose("owner rm", "%s from %s", user, pkg)
164 mutate(pkg, null, function (u, owners) {
165 var found = false
166 , m = owners.filter(function (o) {
167 var match = (o.name === user)
168 found = found || match
169 return !match
170 })
171 if (!found) {
172 log.info("owner rm", "Not a package owner: " + user)
173 return false
174 }
175 if (!m.length) return new Error(
176 "Cannot remove all owners of a package. Add someone else first.")
177 return m
178 }, cb)
179}
180
181function mutate (pkg, user, mutation, cb) {
182 if (user) {
183 var byUser = "-/user/org.couchdb.user:" + user
184 mapToRegistry(byUser, npm.config, function (er, uri) {
185 if (er) return cb(er)
186
187 registry.get(uri, null, mutate_)
188 })
189 } else {
190 mutate_(null, null)
191 }
192
193 function mutate_ (er, u) {
194 if (!er && user && (!u || u.error)) er = new Error(
195 "Couldn't get user data for " + user + ": " + JSON.stringify(u))
196
197 if (er) {
198 log.error("owner mutate", "Error getting user data for %s", user)
199 return cb(er)
200 }
201
202 if (u) u = { "name" : u.name, "email" : u.email }
203 mapToRegistry(pkg, npm.config, function (er, uri) {
204 if (er) return cb(er)
205
206 registry.get(uri, null, function (er, data) {
207 if (er) {
208 log.error("owner mutate", "Error getting package data for %s", pkg)
209 return cb(er)
210 }
211 var m = mutation(u, data.maintainers)
212 if (!m) return cb() // handled
213 if (m instanceof Error) return cb(m) // error
214 data = { _id : data._id
215 , _rev : data._rev
216 , maintainers : m
217 }
218 var dataPath = pkg + "/-rev/" + data._rev
219 mapToRegistry(dataPath, npm.config, function (er, uri) {
220 if (er) return cb(er)
221
222 registry.request("PUT", uri, { body : data }, function (er, data) {
223 if (!er && data.error) er = new Error(
224 "Failed to update package metadata: " + JSON.stringify(data))
225 if (er) {
226 log.error("owner mutate", "Failed to update package metadata")
227 }
228 cb(er, data)
229 })
230 })
231 })
232 })
233 }
234}
235
236function readLocalPkg (cb) {
237 if (npm.config.get("global")) return cb()
238 var path = require("path")
239 readJson(path.resolve(npm.prefix, "package.json"), function (er, d) {
240 return cb(er, d && d.name)
241 })
242}
243
244function unknown (action, cb) {
245 cb("Usage: \n" + owner.usage)
246}