Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorForrest L Norvell <forrest@npmjs.com>2014-06-18 11:19:39 +0400
committerForrest L Norvell <forrest@npmjs.com>2014-07-02 05:43:16 +0400
commit0689ba249b92b4c6279a26804c96af6f92b3a501 (patch)
treec1d56154d44ee0f25eefbd0bdc5c8c4413007721 /lib
parent4441ea1ca17c584a12c266beacf4f9a77d763dfc (diff)
use --scope to map scope to registry
Diffstat (limited to 'lib')
-rw-r--r--lib/adduser.js40
-rw-r--r--lib/bugs.js21
-rw-r--r--lib/cache.js32
-rw-r--r--lib/cache/add-named.js98
-rw-r--r--lib/dedupe.js16
-rw-r--r--lib/deprecate.js34
-rw-r--r--lib/docs.js24
-rw-r--r--lib/install.js70
-rw-r--r--lib/outdated.js13
-rw-r--r--lib/owner.js150
-rw-r--r--lib/publish.js71
-rw-r--r--lib/repo.js27
-rw-r--r--lib/search.js13
-rw-r--r--lib/star.js30
-rw-r--r--lib/stars.js11
-rw-r--r--lib/tag.js11
-rw-r--r--lib/unpublish.js60
-rw-r--r--lib/utils/is-organized.js5
-rw-r--r--lib/utils/is-scoped.js16
-rw-r--r--lib/utils/map-name-to-registry.js28
-rw-r--r--lib/utils/map-to-registry.js51
-rw-r--r--lib/view.js108
22 files changed, 554 insertions, 375 deletions
diff --git a/lib/adduser.js b/lib/adduser.js
index 8315809c5..23c073ae7 100644
--- a/lib/adduser.js
+++ b/lib/adduser.js
@@ -95,7 +95,7 @@ function readPassword (c, u, cb) {
return readPassword(c, u, cb)
}
- c.changed = c.changed || c.p != pw
+ c.changed = c.changed || c.p !== pw
u.p = pw
cb(er)
})
@@ -133,24 +133,48 @@ function save (c, u, cb) {
registry.password = u.p
}
npm.spinner.start()
+
// save existing configs, but yank off for this PUT
- var uri = npm.config.get("registry")
+ var uri = npm.config.get("registry")
+ var scope = npm.config.get("scope")
+
+ // there may be a saved scope and no --registry (for login)
+ if (scope) {
+ if (scope.charAt(0) !== "@") scope = "@" + scope
+
+ var scopedRegistry = npm.config.get(scope + ":registry")
+ if (scopedRegistry) uri = scopedRegistry
+ }
+
registry.adduser(uri, u.u, u.p, u.e, function (er, doc) {
npm.spinner.stop()
if (er) return cb(er)
+
registry.username = u.u
registry.password = u.p
registry.email = u.e
+
// don't want this polluting the configuration
npm.config.del("_token", "user")
- npm.config.set("username", u.u, "user")
- npm.config.set("_password", u.p, "user")
+
+ if (scope) {
+ npm.config.set(scope + ":registry", uri, "user")
+ }
+
+ var munged = url.parse(uri)
+ delete munged.protocol
+ // 'nerf dart' courtesy jennmoneydollaz
+ var nerfDart = url.format(munged)
+
if (doc && doc.token) {
- var munged = url.parse(uri)
- delete munged.protocol
- npm.config.set(url.format(munged) + ":_authToken", doc.token, "user")
+ npm.config.set(nerfDart + ":_authToken", doc.token, "user")
}
- npm.config.set("email", u.e, "user")
+
+ var auth = u.u + ":" + u.p
+ var quasiSecret = new Buffer(auth, "utf8").toString("base64")
+ npm.config.set(nerfDart + ":_auth", quasiSecret, "user")
+ npm.config.set(nerfDart + ":email", u.e, "user")
+
log.info("adduser", "Authorized user %s", u.u)
npm.config.save("user", cb)
})
diff --git a/lib/bugs.js b/lib/bugs.js
index b3022bf2a..41f1386b0 100644
--- a/lib/bugs.js
+++ b/lib/bugs.js
@@ -10,13 +10,16 @@ var npm = require("./npm.js")
, path = require("path")
, readJson = require("read-package-json")
, fs = require("fs")
- , url = require("url")
+ , mapToRegistry = require("./utils/map-to-registry.js")
bugs.completion = function (opts, cb) {
if (opts.conf.argv.remain.length > 2) return cb()
- var uri = url.resolve(npm.config.get("registry"), "-/short")
- registry.get(uri, { timeout : 60000 }, function (er, list) {
- return cb(null, list || [])
+ mapToRegistry("-/short", npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, { timeout : 60000 }, function (er, list) {
+ return cb(null, list || [])
+ })
})
}
@@ -56,9 +59,13 @@ function getUrlAndOpen (d, cb) {
}
function callRegistry (n, cb) {
- var uri = url.resolve(npm.config.get("registry"), n + "/latest")
- registry.get(uri, { timeout : 3600 }, function (er, d) {
+ mapToRegistry(n, npm.config, function (er, uri) {
if (er) return cb(er)
- getUrlAndOpen (d, cb)
+
+ registry.get(uri + "/latest", { timeout : 3600 }, function (er, d) {
+ if (er) return cb(er)
+
+ getUrlAndOpen (d, cb)
+ })
})
}
diff --git a/lib/cache.js b/lib/cache.js
index 01b7d4cba..063cbe38b 100644
--- a/lib/cache.js
+++ b/lib/cache.js
@@ -343,22 +343,30 @@ function maybeFile (spec, cb) {
fs.stat(spec, function (er) {
if (!er) {
// definitely a local thing
+ log.verbose("maybeFile", "statted local spec", spec)
return addLocal(spec, {}, cb)
}
- maybeAt(spec, cb)
- })
-}
+ var pivot
+ // scoped modules might have @ as first character
+ if (spec.charAt(0) === "@") {
+ pivot = spec.slice(1).indexOf("@") + 1
+ }
+ else {
+ pivot = spec.indexOf("@")
+ }
-function maybeAt (spec, cb) {
- // scoped modules might have @ as first character
- var pivot = spec.lastIndexOf("@")
- if (pivot > 0) {
- add([spec.slice(0, pivot), spec.slice(pivot + 1)], cb)
- } else {
- // already know it's not a url, so must be local
- addLocal(spec, {}, cb)
- }
+ if (pivot > 0) {
+ var name = spec.slice(0, pivot)
+ spec = spec.slice(pivot + 1)
+ log.verbose("maybeFile", "name=%s, spec=%s", name, spec)
+ add([name, spec], cb)
+ } else {
+ // already know it's not a url, so must be local
+ log.verbose("maybeFile", "found local spec", spec)
+ addLocal(spec, {}, cb)
+ }
+ })
}
function needName(er, data) {
diff --git a/lib/cache/add-named.js b/lib/cache/add-named.js
index f8c09aa03..e595db228 100644
--- a/lib/cache/add-named.js
+++ b/lib/cache/add-named.js
@@ -15,7 +15,7 @@ var path = require("path")
, unlock = locker.unlock
, maybeGithub = require("./maybe-github.js")
, addRemoteTarball = require("./add-remote-tarball.js")
- , mapNameToRegistry = require("../utils/map-name-to-registry.js")
+ , mapToRegistry = require("../utils/map-to-registry.js")
module.exports = addNamed
@@ -57,6 +57,12 @@ function addNameTag (name, tag, data, cb_) {
tag = npm.config.get("tag")
}
+ mapToRegistry(name, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, null, next)
+ })
+
function cb(er, data) {
// might be username/project
// in that case, try it as a github url.
@@ -66,28 +72,24 @@ function addNameTag (name, tag, data, cb_) {
return cb_(er, data)
}
- mapNameToRegistry(name, npm.config, function (er, uri) {
+ function next (er, data, json, resp) {
+ if (!er) {
+ er = errorResponse(name, resp)
+ }
if (er) return cb(er)
+ engineFilter(data)
+ if (data["dist-tags"] && data["dist-tags"][tag]
+ && data.versions[data["dist-tags"][tag]]) {
+ var ver = data["dist-tags"][tag]
+ return addNamed(name, ver, data.versions[ver], cb)
+ }
+ if (!explicit && Object.keys(data.versions).length) {
+ return addNamed(name, "*", data, cb)
+ }
- registry.get(uri, null, function (er, data, json, resp) {
- if (!er) {
- er = errorResponse(name, resp)
- }
- if (er) return cb(er)
- engineFilter(data)
- if (data["dist-tags"] && data["dist-tags"][tag]
- && data.versions[data["dist-tags"][tag]]) {
- var ver = data["dist-tags"][tag]
- return addNamed(name, ver, data.versions[ver], cb)
- }
- if (!explicit && Object.keys(data.versions).length) {
- return addNamed(name, "*", data, cb)
- }
-
- er = installTargetsError(tag, data)
- return cb(er)
- })
- })
+ er = installTargetsError(tag, data)
+ return cb(er)
+ }
}
function engineFilter (data) {
@@ -119,26 +121,28 @@ function addNameVersion (name, v, data, cb) {
return next()
}
- mapNameToRegistry(name, npm.config, function (er, uri) {
+ mapToRegistry(name, npm.config, function (er, uri) {
if (er) return cb(er)
- registry.get(uri, null, function (er, d, json, resp) {
- if (!er) {
- er = errorResponse(name, resp)
- }
- if (er) return cb(er)
- data = d && d.versions[ver]
- if (!data) {
- er = new Error('version not found: ' + name + '@' + ver)
- er.package = name
- er.statusCode = 404
- return cb(er)
- }
- response = resp
- next()
- })
+ registry.get(uri, null, setData)
})
+ function setData (er, d, json, resp) {
+ if (!er) {
+ er = errorResponse(name, resp)
+ }
+ if (er) return cb(er)
+ data = d && d.versions[ver]
+ if (!data) {
+ er = new Error("version not found: "+name+"@"+ver)
+ er.package = name
+ er.statusCode = 404
+ return cb(er)
+ }
+ response = resp
+ next()
+ }
+
function next () {
deprCheck(data)
var dist = data.dist
@@ -205,19 +209,21 @@ function addNameRange (name, range, data, cb) {
if (data) return next()
- mapNameToRegistry(name, npm.config, function (er, uri) {
+ mapToRegistry(name, npm.config, function (er, uri) {
if (er) return cb(er)
- registry.get(uri, null, function (er, d, json, resp) {
- if (!er) {
- er = errorResponse(name, resp)
- }
- if (er) return cb(er)
- data = d
- next()
- })
+ registry.get(uri, null, setData)
})
+ function setData (er, d, json, resp) {
+ if (!er) {
+ er = errorResponse(name, resp)
+ }
+ if (er) return cb(er)
+ data = d
+ next()
+ }
+
function next () {
log.silly( "addNameRange", "number 2"
, {name:name, range:range, hasData:!!data})
diff --git a/lib/dedupe.js b/lib/dedupe.js
index e6762e15b..70a63a3ab 100644
--- a/lib/dedupe.js
+++ b/lib/dedupe.js
@@ -7,7 +7,6 @@
// much better "put pkg X at folder Y" abstraction. Oh well,
// whatever. Perfect enemy of the good, and all that.
-var url = require("url")
var fs = require("fs")
var asyncMap = require("slide").asyncMap
var path = require("path")
@@ -16,6 +15,7 @@ var semver = require("semver")
var rm = require("./utils/gently-rm.js")
var log = require("npmlog")
var npm = require("./npm.js")
+var mapToRegistry = require("./utils/map-to-registry.js")
module.exports = dedupe
@@ -240,13 +240,19 @@ function findVersions (npm, summary, cb) {
var versions = data.versions
var ranges = data.ranges
- var uri = url.resolve(npm.config.get("registry"), name)
- npm.registry.get(uri, null, function (er, data) {
+ mapToRegistry(name, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ npm.registry.get(uri, null, next)
+ })
+
+ function next (er, data) {
var regVersions = er ? [] : Object.keys(data.versions)
var locMatch = bestMatch(versions, ranges)
- var regMatch;
var tag = npm.config.get("tag")
var distTag = data["dist-tags"] && data["dist-tags"][tag]
+
+ var regMatch
if (distTag && data.versions[distTag] && matches(distTag, ranges)) {
regMatch = distTag
} else {
@@ -254,7 +260,7 @@ function findVersions (npm, summary, cb) {
}
cb(null, [[name, has, loc, locMatch, regMatch, locs]])
- })
+ }
}, cb)
}
diff --git a/lib/deprecate.js b/lib/deprecate.js
index 175b69ceb..17c029f92 100644
--- a/lib/deprecate.js
+++ b/lib/deprecate.js
@@ -1,5 +1,5 @@
-var url = require("url")
- , npm = require("./npm.js")
+var npm = require("./npm.js")
+ , mapToRegistry = require("./utils/map-to-registry.js")
module.exports = deprecate
@@ -13,11 +13,14 @@ deprecate.completion = function (opts, cb) {
if (opts.conf.argv.remain.length > 2) return cb()
// get the list of packages by user
var path = "/-/by-user/"+encodeURIComponent(un)
- , uri = url.resolve(npm.config.get("registry"), path)
- npm.registry.get(uri, { timeout : 60000 }, function (er, list) {
- if (er) return cb()
- console.error(list)
- return cb(null, list[un])
+ mapToRegistry(path, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ npm.registry.get(uri, { timeout : 60000 }, function (er, list) {
+ if (er) return cb()
+ console.error(list)
+ return cb(null, list[un])
+ })
})
}
@@ -25,11 +28,18 @@ function deprecate (args, cb) {
var pkg = args[0]
, msg = args[1]
if (msg === undefined) return cb("Usage: " + deprecate.usage)
+
// fetch the data and make sure it exists.
- pkg = pkg.split(/@/)
- var name = pkg.shift()
- , ver = pkg.join("@")
- , uri = url.resolve(npm.config.get("registry"), name)
+ var pivot = pkg.lastIndexOf("@")
+ if (pivot === 0) pivot = pkg.length
+ var name = pkg.substr(0, pivot)
+ , ver = pkg.substr(pivot + 1)
+
+ mapToRegistry(name, npm.config, next)
+
+ function next (er, uri) {
+ if (er) return cb(er)
- npm.registry.deprecate(uri, ver, msg, cb)
+ npm.registry.deprecate(uri, ver, msg, cb)
+ }
}
diff --git a/lib/docs.js b/lib/docs.js
index 77073fbb9..2c59b2672 100644
--- a/lib/docs.js
+++ b/lib/docs.js
@@ -5,18 +5,21 @@ docs.usage += "\n"
docs.usage += "npm docs ."
docs.completion = function (opts, cb) {
- var uri = url_.resolve(npm.config.get("registry"), "/-/short")
- registry.get(uri, { timeout : 60000 }, function (er, list) {
- return cb(null, list || [])
+ mapToRegistry("/-/short", npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, { timeout : 60000 }, function (er, list) {
+ return cb(null, list || [])
+ })
})
}
-var url_ = require("url")
- , npm = require("./npm.js")
+var npm = require("./npm.js")
, registry = npm.registry
, opener = require("opener")
, path = require("path")
, log = require("npmlog")
+ , mapToRegistry = require("./utils/map-to-registry.js")
function url (json) {
return json.homepage ? json.homepage : "https://npmjs.org/package/" + json.name
@@ -54,8 +57,13 @@ function getDoc (project, cb) {
return opener(url(json), { command: npm.config.get("browser") }, cb)
}
- var uri = url_.resolve(npm.config.get("registry"), project + "/latest")
- registry.get(uri, { timeout : 3600 }, function (er, json) {
+ mapToRegistry(project, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri + "/latest", { timeout : 3600 }, next)
+ })
+
+ function next (er, json) {
var github = "https://github.com/" + project + "#readme"
if (er) {
@@ -64,5 +72,5 @@ function getDoc (project, cb) {
}
return opener(url(json), { command: npm.config.get("browser") }, cb)
- })
+ }
}
diff --git a/lib/install.js b/lib/install.js
index 8f20bc839..6d07a8294 100644
--- a/lib/install.js
+++ b/lib/install.js
@@ -34,28 +34,34 @@ install.completion = function (opts, cb) {
// if it starts with https?://, then just give up, because it's a url
// for now, not yet implemented.
var registry = npm.registry
- , uri = url.resolve(npm.config.get("registry"), "-/short")
- registry.get(uri, null, function (er, pkgs) {
- if (er) return cb()
- if (!opts.partialWord) return cb(null, pkgs)
+ mapToRegistry("-/short", npm.config, function (er, uri) {
+ if (er) return cb(er)
- var name = opts.partialWord.split("@").shift()
- pkgs = pkgs.filter(function (p) {
- return p.indexOf(name) === 0
- })
+ registry.get(uri, null, function (er, pkgs) {
+ if (er) return cb()
+ if (!opts.partialWord) return cb(null, pkgs)
- if (pkgs.length !== 1 && opts.partialWord === name) {
- return cb(null, pkgs)
- }
+ var name = opts.partialWord.split("@").shift()
+ pkgs = pkgs.filter(function (p) {
+ return p.indexOf(name) === 0
+ })
- uri = url.resolve(npm.config.get("registry"), pkgs[0])
- registry.get(uri, null, function (er, d) {
- if (er) return cb()
- return cb(null, Object.keys(d["dist-tags"] || {})
- .concat(Object.keys(d.versions || {}))
- .map(function (t) {
- return pkgs[0] + "@" + t
- }))
+ if (pkgs.length !== 1 && opts.partialWord === name) {
+ return cb(null, pkgs)
+ }
+
+ mapToRegistry(pkgs[0], npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, null, function (er, d) {
+ if (er) return cb()
+ return cb(null, Object.keys(d["dist-tags"] || {})
+ .concat(Object.keys(d.versions || {}))
+ .map(function (t) {
+ return pkgs[0] + "@" + t
+ }))
+ })
+ })
})
})
}
@@ -77,6 +83,7 @@ var npm = require("./npm.js")
, isGitUrl = require("./utils/is-git-url.js")
, npmInstallChecks = require("npm-install-checks")
, sortedObject = require("sorted-object")
+ , mapToRegistry = require("./utils/map-to-registry.js")
function install (args, cb_) {
var hasArguments = !!args.length
@@ -412,12 +419,12 @@ function save (where, installed, tree, pretty, hasArguments, cb) {
// that the submodules are not immediately require()able.
// TODO: Show the complete tree, ls-style, but only if --long is provided
function prettify (tree, installed) {
- if (npm.config.get("json")) {
- function red (set, kv) {
- set[kv[0]] = kv[1]
- return set
- }
+ function red (set, kv) {
+ set[kv[0]] = kv[1]
+ return set
+ }
+ if (npm.config.get("json")) {
tree = Object.keys(tree).map(function (p) {
if (!tree[p]) return null
var what = tree[p].what.split("@")
@@ -771,6 +778,13 @@ function localLink (target, where, context, cb) {
, parent = context.parent
readJson(jsonFile, log.warn, function (er, data) {
+ function thenLink () {
+ npm.commands.link([target.name], function (er, d) {
+ log.silly("localLink", "back from link", [er, d])
+ cb(er, [resultList(target, where, parent && parent._id)])
+ })
+ }
+
if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
if (er || data._id === target._id) {
if (er) {
@@ -781,14 +795,6 @@ function localLink (target, where, context, cb) {
thenLink()
})
} else thenLink()
-
- function thenLink () {
- npm.commands.link([target.name], function (er, d) {
- log.silly("localLink", "back from link", [er, d])
- cb(er, [resultList(target, where, parent && parent._id)])
- })
- }
-
} else {
log.verbose("localLink", "install locally (no link)", target._id)
installOne_(target, where, context, cb)
diff --git a/lib/outdated.js b/lib/outdated.js
index b29ea9fe6..bfed369ba 100644
--- a/lib/outdated.js
+++ b/lib/outdated.js
@@ -34,6 +34,7 @@ var path = require("path")
, table = require("text-table")
, semver = require("semver")
, os = require("os")
+ , mapToRegistry = require("./utils/map-to-registry.js")
function outdated (args, silent, cb) {
if (typeof cb !== "function") cb = silent, silent = false
@@ -268,8 +269,13 @@ function shouldUpdate (args, dir, dep, has, req, depth, cb) {
return doIt("git", "git")
// search for the latest package
- var uri = url.resolve(npm.config.get("registry"), dep)
- npm.registry.get(uri, null, function (er, d) {
+ mapToRegistry(dep, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ npm.registry.get(uri, null, updateDeps)
+ })
+
+ function updateDeps (er, d) {
if (er) return cb()
if (!d || !d['dist-tags'] || !d.versions) return cb()
var l = d.versions[d['dist-tags'].latest]
@@ -315,6 +321,5 @@ function shouldUpdate (args, dir, dep, has, req, depth, cb) {
else
skip()
}
-
- })
+ }
}
diff --git a/lib/owner.js b/lib/owner.js
index 34dbbc247..1f9d79b25 100644
--- a/lib/owner.js
+++ b/lib/owner.js
@@ -15,51 +15,65 @@ owner.completion = function (opts, cb) {
return cb(null, subs)
}
var un = encodeURIComponent(npm.config.get("username"))
- var theUser, uri
+ var byUser, theUser
switch (argv[2]) {
case "ls":
if (argv.length > 3) return cb()
- uri = url.resolve(npm.config.get("registry"), "-/short")
- return registry.get(uri, null, cb)
+ return mapToRegistry("-/short", npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, null, cb)
+ })
case "rm":
if (argv.length > 3) {
theUser = encodeURIComponent(argv[3])
- uri = url.resolve(npm.config.get("registry"), "-/by-user/"+theUser+"|"+un)
- console.error(uri)
- return registry.get(uri, null, function (er, d) {
+ byUser = "-/by-user/" + theUser + "|" + un
+ return mapToRegistry(byUser, npm.config, function (er, uri) {
if (er) return cb(er)
- // return the intersection
- return cb(null, d[theUser].filter(function (p) {
- // kludge for server adminery.
- return un === "isaacs" || d[un].indexOf(p) === -1
- }))
+
+ console.error(uri)
+ registry.get(uri, null, function (er, d) {
+ if (er) return cb(er)
+ // return the intersection
+ return cb(null, d[theUser].filter(function (p) {
+ // kludge for server adminery.
+ return un === "isaacs" || d[un].indexOf(p) === -1
+ }))
+ })
})
}
// else fallthrough
case "add":
if (argv.length > 3) {
theUser = encodeURIComponent(argv[3])
- uri = url.resolve(npm.config.get("registry"), "-/by-user/"+theUser+"|"+un)
- console.error(uri)
- return registry.get(uri, null, function (er, d) {
- console.error(uri, er || d)
- // return mine that they're not already on.
+ byUser = "-/by-user/"+theUser+"|"+un
+ return mapToRegistry(byUser, npm.config, function (er, uri) {
if (er) return cb(er)
- var mine = d[un] || []
- , theirs = d[theUser] || []
- return cb(null, mine.filter(function (p) {
- return theirs.indexOf(p) === -1
- }))
+
+ console.error(uri)
+ registry.get(uri, null, function (er, d) {
+ console.error(uri, er || d)
+ // return mine that they're not already on.
+ if (er) return cb(er)
+ var mine = d[un] || []
+ , theirs = d[theUser] || []
+ return cb(null, mine.filter(function (p) {
+ return theirs.indexOf(p) === -1
+ }))
+ })
})
}
// just list all users who aren't me.
- uri = url.resolve(npm.config.get("registry"), "-/users")
- return registry.get(uri, null, function (er, list) {
- if (er) return cb()
- return cb(null, Object.keys(list).filter(function (n) {
- return n !== un
- }))
+ return mapToRegistry("-/users", npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, null, function (er, list) {
+ if (er) return cb()
+ return cb(null, Object.keys(list).filter(function (n) {
+ return n !== un
+ }))
+ })
})
default:
@@ -71,7 +85,7 @@ var npm = require("./npm.js")
, registry = npm.registry
, log = require("npmlog")
, readJson = require("read-package-json")
- , url = require("url")
+ , mapToRegistry = require("./utils/map-to-registry.js")
function owner (args, cb) {
var action = args.shift()
@@ -90,18 +104,21 @@ function ls (pkg, cb) {
ls(pkg, cb)
})
- var uri = url.resolve(npm.config.get("registry"), pkg)
- registry.get(uri, null, function (er, data) {
- var msg = ""
- if (er) {
- log.error("owner ls", "Couldn't get owner data", pkg)
- return cb(er)
- }
- var owners = data.maintainers
- if (!owners || !owners.length) msg = "admin party!"
- else msg = owners.map(function (o) { return o.name +" <"+o.email+">" }).join("\n")
- console.log(msg)
- cb(er, owners)
+ mapToRegistry(pkg, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, null, function (er, data) {
+ var msg = ""
+ if (er) {
+ log.error("owner ls", "Couldn't get owner data", pkg)
+ return cb(er)
+ }
+ var owners = data.maintainers
+ if (!owners || !owners.length) msg = "admin party!"
+ else msg = owners.map(function (o) { return o.name +" <"+o.email+">" }).join("\n")
+ console.log(msg)
+ cb(er, owners)
+ })
})
}
@@ -156,8 +173,12 @@ function rm (user, pkg, cb) {
function mutate (pkg, user, mutation, cb) {
if (user) {
- var uri = url.resolve(npm.config.get("registry"), "-/user/org.couchdb.user:"+user)
- registry.get(uri, null, mutate_)
+ var byUser = "-/user/org.couchdb.user:" + user
+ mapToRegistry(byUser, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, null, mutate_)
+ })
} else {
mutate_(null, null)
}
@@ -172,27 +193,34 @@ function mutate (pkg, user, mutation, cb) {
}
if (u) u = { "name" : u.name, "email" : u.email }
- var uri = url.resolve(npm.config.get("registry"), pkg)
- registry.get(uri, null, function (er, data) {
- if (er) {
- log.error("owner mutate", "Error getting package data for %s", pkg)
- return cb(er)
- }
- var m = mutation(u, data.maintainers)
- if (!m) return cb() // handled
- if (m instanceof Error) return cb(m) // error
- data = { _id : data._id
- , _rev : data._rev
- , maintainers : m
- }
- var uri = url.resolve(npm.config.get("registry"), pkg+"/-rev/"+data._rev)
- registry.request("PUT", uri, { body : data }, function (er, data) {
- if (!er && data.error) er = new Error(
- "Failed to update package metadata: "+JSON.stringify(data))
+ mapToRegistry(pkg, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, null, function (er, data) {
if (er) {
- log.error("owner mutate", "Failed to update package metadata")
+ log.error("owner mutate", "Error getting package data for %s", pkg)
+ return cb(er)
}
- cb(er, data)
+ var m = mutation(u, data.maintainers)
+ if (!m) return cb() // handled
+ if (m instanceof Error) return cb(m) // error
+ data = { _id : data._id
+ , _rev : data._rev
+ , maintainers : m
+ }
+ var dataPath = pkg + "/-rev/" + data._rev
+ mapToRegistry(dataPath, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.request("PUT", uri, { body : data }, function (er, data) {
+ if (!er && data.error) er = new Error(
+ "Failed to update package metadata: "+JSON.stringify(data))
+ if (er) {
+ log.error("owner mutate", "Failed to update package metadata")
+ }
+ cb(er, data)
+ })
+ })
})
})
}
diff --git a/lib/publish.js b/lib/publish.js
index 32b09f8e0..349ac00a7 100644
--- a/lib/publish.js
+++ b/lib/publish.js
@@ -1,7 +1,8 @@
module.exports = publish
-var npm = require("./npm.js")
+var url = require("url")
+ , npm = require("./npm.js")
, log = require("npmlog")
, path = require("path")
, readJson = require("read-package-json")
@@ -9,7 +10,7 @@ var npm = require("./npm.js")
, chain = require("slide").chain
, Conf = require("npmconf").Conf
, RegClient = require("npm-registry-client")
- , isOrganized = require("./utils/is-organized.js")
+ , mapToRegistry = require("./utils/map-to-registry.js")
publish.usage = "npm publish <tarball>"
+ "\nnpm publish <folder>"
@@ -84,47 +85,43 @@ function publish_ (arg, data, isRetry, cachedir, cb) {
registry = new RegClient(config)
}
- var registryURI
- if (isOrganized(data.name)) {
- var org = data.name.match(/^(@[^@\/]+)\//)[1]
- if (!org) return cb(new Error("No organization found in scoped package name"))
- log.silly("publish", "scope", org)
-
- var base = config.get(org + ":registry")
- if (!base) {
- return cb(new Error("no registry URL found for scope " + org))
- }
- registryURI = base
- }
- else {
- registryURI = config.get("registry")
- }
-
data._npmVersion = npm.version
data._npmUser = { name: npm.config.get("username")
, email: npm.config.get("email") }
delete data.modules
- if (data.private) return cb(new Error
- ("This package has been marked as private\n"
- +"Remove the 'private' field from the package.json to publish it."))
-
- var tarball = cachedir + ".tgz"
- registry.publish(registryURI, data, tarball, function (er) {
- if (er && er.code === "EPUBLISHCONFLICT"
- && npm.config.get("force") && !isRetry) {
- log.warn("publish", "Forced publish over "+data._id)
- return npm.commands.unpublish([data._id], function (er) {
- // ignore errors. Use the force. Reach out with your feelings.
- // but if it fails again, then report the first error.
- publish([arg], er || true, cb)
- })
- }
- // report the unpublish error if this was a retry and unpublish failed
- if (er && isRetry && isRetry !== true) return cb(isRetry)
+ if (data.private) return cb(
+ new Error(
+ "This package has been marked as private\n" +
+ "Remove the 'private' field from the package.json to publish it."
+ )
+ )
+
+ mapToRegistry(data.name, config, function (er, registryURI) {
if (er) return cb(er)
- console.log("+ " + data._id)
- cb()
+
+ var tarball = cachedir + ".tgz"
+
+ // we just want the base registry URL in this case
+ var registryBase = url.resolve(registryURI, ".")
+ log.verbose("publish", "registryBase", registryBase)
+
+ registry.publish(registryBase, data, tarball, function (er) {
+ if (er && er.code === "EPUBLISHCONFLICT"
+ && npm.config.get("force") && !isRetry) {
+ log.warn("publish", "Forced publish over " + data._id)
+ return npm.commands.unpublish([data._id], function (er) {
+ // ignore errors. Use the force. Reach out with your feelings.
+ // but if it fails again, then report the first error.
+ publish([arg], er || true, cb)
+ })
+ }
+ // report the unpublish error if this was a retry and unpublish failed
+ if (er && isRetry && isRetry !== true) return cb(isRetry)
+ if (er) return cb(er)
+ console.log("+ " + data._id)
+ cb()
+ })
})
}
diff --git a/lib/repo.js b/lib/repo.js
index d209c3ca8..1fe81f293 100644
--- a/lib/repo.js
+++ b/lib/repo.js
@@ -5,9 +5,12 @@ repo.usage = "npm repo <pkgname>"
repo.completion = function (opts, cb) {
if (opts.conf.argv.remain.length > 2) return cb()
- var uri = url_.resolve(npm.config.get("registry"), "/-/short")
- registry.get(uri, { timeout : 60000 }, function (er, list) {
- return cb(null, list || [])
+ mapToRegistry("/-/short", npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, { timeout : 60000 }, function (er, list) {
+ return cb(null, list || [])
+ })
})
}
@@ -19,10 +22,11 @@ var npm = require("./npm.js")
, path = require("path")
, readJson = require("read-package-json")
, fs = require("fs")
- , url_ = require('url')
+ , url_ = require("url")
+ , mapToRegistry = require("./utils/map-to-registry.js")
function repo (args, cb) {
- var n = args.length && args[0].split("@").shift() || '.'
+ var n = args.length && args[0].split("@").shift() || "."
fs.stat(n, function (er, s) {
if (er && er.code === "ENOENT") return callRegistry(n, cb)
else if (er) return cb(er)
@@ -35,8 +39,8 @@ function repo (args, cb) {
}
function getUrlAndOpen (d, cb) {
- var r = d.repository;
- if (!r) return cb(new Error('no repository'));
+ var r = d.repository
+ if (!r) return cb(new Error('no repository'))
// XXX remove this when npm@v1.3.10 from node 0.10 is deprecated
// from https://github.com/npm/npm-www/issues/418
if (githubUserRepo(r.url))
@@ -52,10 +56,13 @@ function getUrlAndOpen (d, cb) {
}
function callRegistry (n, cb) {
- var uri = url_.resolve(npm.config.get("registry"), n + "/latest")
- registry.get(uri, { timeout : 3600 }, function (er, d) {
+ mapToRegistry(n, npm.config, function (er, uri) {
if (er) return cb(er)
- getUrlAndOpen(d, cb)
+
+ registry.get(uri + "/latest", { timeout : 3600 }, function (er, d) {
+ if (er) return cb(er)
+ getUrlAndOpen(d, cb)
+ })
})
}
diff --git a/lib/search.js b/lib/search.js
index e7892350c..3be8b0d27 100644
--- a/lib/search.js
+++ b/lib/search.js
@@ -1,10 +1,10 @@
module.exports = exports = search
-var url = require("url")
- , npm = require("./npm.js")
+var npm = require("./npm.js")
, registry = npm.registry
, columnify = require('columnify')
+ , mapToRegistry = require("./utils/map-to-registry.js")
search.usage = "npm search [some search terms ...]"
@@ -63,10 +63,13 @@ function getFilteredData (staleness, args, notArgs, cb) {
follow : true,
staleOk : true
}
- var uri = url.resolve(npm.config.get("registry"), "-/all")
- registry.get(uri, opts, function (er, data) {
+ mapToRegistry("-/all", npm.config, function (er, uri) {
if (er) return cb(er)
- return cb(null, filter(data, args, notArgs))
+
+ registry.get(uri, opts, function (er, data) {
+ if (er) return cb(er)
+ return cb(null, filter(data, args, notArgs))
+ })
})
}
diff --git a/lib/star.js b/lib/star.js
index 9c0b4ea9e..123c4ebbb 100644
--- a/lib/star.js
+++ b/lib/star.js
@@ -1,19 +1,22 @@
module.exports = star
-var url = require("url")
- , npm = require("./npm.js")
+var npm = require("./npm.js")
, registry = npm.registry
, log = require("npmlog")
, asyncMap = require("slide").asyncMap
+ , mapToRegistry = require("./utils/map-to-registry.js")
star.usage = "npm star <package> [pkg, pkg, ...]\n"
+ "npm unstar <package> [pkg, pkg, ...]"
star.completion = function (opts, cb) {
- var uri = url.resolve(npm.config.get("registry"), "-/short")
- registry.get(uri, { timeout : 60000 }, function (er, list) {
- return cb(null, list || [])
+ mapToRegistry("-/short", npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, { timeout : 60000 }, function (er, list) {
+ return cb(null, list || [])
+ })
})
}
@@ -24,13 +27,16 @@ function star (args, cb) {
, using = !(npm.command.match(/^un/))
if (!using) s = u
asyncMap(args, function (pkg, cb) {
- var uri = url.resolve(npm.config.get("registry"), pkg)
- registry.star(uri, using, function (er, data, raw, req) {
- if (!er) {
- console.log(s + " "+pkg)
- log.verbose("star", data)
- }
- cb(er, data, raw, req)
+ mapToRegistry(pkg, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.star(uri, using, function (er, data, raw, req) {
+ if (!er) {
+ console.log(s + " "+pkg)
+ log.verbose("star", data)
+ }
+ cb(er, data, raw, req)
+ })
})
}, cb)
}
diff --git a/lib/stars.js b/lib/stars.js
index f0d2ef73a..a482a4b4a 100644
--- a/lib/stars.js
+++ b/lib/stars.js
@@ -2,15 +2,18 @@ module.exports = stars
stars.usage = "npm stars [username]"
-var url = require("url")
- , npm = require("./npm.js")
+var npm = require("./npm.js")
, registry = npm.registry
, log = require("npmlog")
+ , mapToRegistry = require("./utils/map-to-registry.js")
function stars (args, cb) {
var name = args.length === 1 ? args[0] : npm.config.get("username")
- , uri = url.resolve(npm.config.get("registry"), name)
- registry.stars(uri, showstars)
+ mapToRegistry(name, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.stars(uri, showstars)
+ })
function showstars (er, data) {
if (er) {
diff --git a/lib/tag.js b/lib/tag.js
index 1d04ad1f7..cf7752a69 100644
--- a/lib/tag.js
+++ b/lib/tag.js
@@ -5,9 +5,9 @@ tag.usage = "npm tag <project>@<version> [<tag>]"
tag.completion = require("./unpublish.js").completion
-var url = require("url")
- , npm = require("./npm.js")
+var npm = require("./npm.js")
, registry = npm.registry
+ , mapToRegistry = require("./utils/map-to-registry.js")
function tag (args, cb) {
var thing = (args.shift() || "").split("@")
@@ -15,6 +15,9 @@ function tag (args, cb) {
, version = thing.join("@")
, t = args.shift() || npm.config.get("tag")
if (!project || !version || !t) return cb("Usage:\n"+tag.usage)
- var uri = url.resolve(npm.config.get("registry"), project)
- registry.tag(uri, version, t, cb)
+ mapToRegistry(project, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.tag(uri, version, t, cb)
+ })
}
diff --git a/lib/unpublish.js b/lib/unpublish.js
index 225c1c3c4..cd4f18deb 100644
--- a/lib/unpublish.js
+++ b/lib/unpublish.js
@@ -1,12 +1,12 @@
module.exports = unpublish
-var url = require("url")
- , log = require("npmlog")
+var log = require("npmlog")
, npm = require("./npm.js")
, registry = npm.registry
, readJson = require("read-package-json")
, path = require("path")
+ , mapToRegistry = require("./utils/map-to-registry.js")
unpublish.usage = "npm unpublish <project>[@<version>]"
@@ -14,27 +14,34 @@ unpublish.completion = function (opts, cb) {
if (opts.conf.argv.remain.length >= 3) return cb()
var un = encodeURIComponent(npm.config.get("username"))
if (!un) return cb()
- var uri = url.resolve(npm.config.get("registry"), "-/by-user/"+un)
- registry.get(uri, null, function (er, pkgs) {
- // do a bit of filtering at this point, so that we don't need
- // to fetch versions for more than one thing, but also don't
- // accidentally a whole project.
- pkgs = pkgs[un]
- if (!pkgs || !pkgs.length) return cb()
- var partial = opts.partialWord.split("@")
- , pp = partial.shift()
- pkgs = pkgs.filter(function (p) {
- return p.indexOf(pp) === 0
- })
- if (pkgs.length > 1) return cb(null, pkgs)
- var uri = url.resolve(npm.config.get("registry"), pkgs[0])
- registry.get(uri, null, function (er, d) {
- if (er) return cb(er)
- var vers = Object.keys(d.versions)
- if (!vers.length) return cb(null, pkgs)
- return cb(null, vers.map(function (v) {
- return pkgs[0]+"@"+v
- }))
+ var byUser = "-/by-user/" + un
+ mapToRegistry(byUser, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, null, function (er, pkgs) {
+ // do a bit of filtering at this point, so that we don't need
+ // to fetch versions for more than one thing, but also don't
+ // accidentally a whole project.
+ pkgs = pkgs[un]
+ if (!pkgs || !pkgs.length) return cb()
+ var partial = opts.partialWord.split("@")
+ , pp = partial.shift()
+ pkgs = pkgs.filter(function (p) {
+ return p.indexOf(pp) === 0
+ })
+ if (pkgs.length > 1) return cb(null, pkgs)
+ mapToRegistry(pkgs[0], npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, null, function (er, d) {
+ if (er) return cb(er)
+ var vers = Object.keys(d.versions)
+ if (!vers.length) return cb(null, pkgs)
+ return cb(null, vers.map(function (v) {
+ return pkgs[0]+"@"+v
+ }))
+ })
+ })
})
})
}
@@ -79,7 +86,10 @@ function gotProject (project, version, cb_) {
return cb(er)
}
- var uri = url.resolve(npm.config.get("registry"), project)
- registry.unpublish(uri, version, cb)
+ mapToRegistry(project, npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.unpublish(uri, version, cb)
+ })
})
}
diff --git a/lib/utils/is-organized.js b/lib/utils/is-organized.js
deleted file mode 100644
index 61b45508f..000000000
--- a/lib/utils/is-organized.js
+++ /dev/null
@@ -1,5 +0,0 @@
-module.exports = isOrganized
-
-function isOrganized(spec) {
- return !!/^@[^@\/]+\//.test(spec)
-}
diff --git a/lib/utils/is-scoped.js b/lib/utils/is-scoped.js
new file mode 100644
index 000000000..fb34f558e
--- /dev/null
+++ b/lib/utils/is-scoped.js
@@ -0,0 +1,16 @@
+module.exports = isScoped
+
+function isScoped(spec) {
+ if (spec.charAt(0) !== "@") return null
+
+ var rest = spec.slice(1).split("/")
+ if (rest.length !== 2) return null
+
+ if (!(rest[0] && rest[1] &&
+ rest[0] === encodeURIComponent(rest[0]) &&
+ rest[1] === encodeURIComponent(rest[1]))) {
+ return null
+ }
+
+ return {scope : rest[0], name : rest[1]}
+}
diff --git a/lib/utils/map-name-to-registry.js b/lib/utils/map-name-to-registry.js
deleted file mode 100644
index 2b2e2a062..000000000
--- a/lib/utils/map-name-to-registry.js
+++ /dev/null
@@ -1,28 +0,0 @@
-var url = require("url")
-
-var isOrganized = require("./is-organized.js")
- , log = require("npmlog")
-
-module.exports = mapNameToRegistry
-
-function mapNameToRegistry(name, config, cb) {
- var uri
-
- if (isOrganized(name)) {
- var org = name.match(/^(@[^@\/]+)\//)[1]
- if (!org) return cb(new Error("No organization found in scoped package name"))
- log.silly("mapNameToRegistry", "org", org)
-
- var escaped = name.replace("/", "%2f")
- var orgRegistry = config.get(org + ":registry")
- if (!orgRegistry) return cb(new Error("no registry URL found for scope " + org))
-
- uri = url.resolve(orgRegistry, escaped)
- }
- else {
- uri = url.resolve(config.get("registry"), name)
- }
-
- log.verbose("mapNameToRegistry", "uri", uri)
- cb(null, uri)
-}
diff --git a/lib/utils/map-to-registry.js b/lib/utils/map-to-registry.js
new file mode 100644
index 000000000..169167f76
--- /dev/null
+++ b/lib/utils/map-to-registry.js
@@ -0,0 +1,51 @@
+var url = require("url")
+
+var isScoped = require("./is-scoped.js")
+ , log = require("npmlog")
+
+module.exports = mapToRegistry
+
+function mapToRegistry(name, config, cb) {
+ var uri
+ var scopedRegistry
+
+ // the name itself takes precedence
+ var data = isScoped(name)
+ if (data) {
+ var packageScope = "@" + data.scope
+ if (!packageScope) return cb(new Error("No scope found in scoped package named " + name))
+ log.silly("mapToRegistry", "packageScope", packageScope)
+
+ var escaped = name.replace("/", "%2f")
+ scopedRegistry = config.get(packageScope + ":registry")
+ if (scopedRegistry) {
+ uri = url.resolve(scopedRegistry, escaped)
+ }
+ else {
+ log.verbose("mapToRegistry", "no registry URL found for scope", packageScope)
+ }
+ }
+
+ // ...then --scope=@scope or --scope=scope
+ var scope = config.get("scope")
+ if (!uri && scope) {
+ // I'm an enabler, sorry
+ if (scope.charAt(0) !== "@") scope = "@" + scope
+
+ scopedRegistry = config.get(scope + ":registry")
+ if (scopedRegistry) {
+ uri = url.resolve(scopedRegistry, name)
+ }
+ else {
+ log.verbose("mapToRegistry", "no registry URL found for scope", scope)
+ }
+ }
+
+ // ...and finally use the default registry
+ if (!uri) {
+ uri = url.resolve(config.get("registry"), name)
+ }
+
+ log.verbose("mapToRegistry", "uri", uri)
+ cb(null, uri)
+}
diff --git a/lib/view.js b/lib/view.js
index 33bf550dd..8e0c97cf8 100644
--- a/lib/view.js
+++ b/lib/view.js
@@ -4,21 +4,26 @@ module.exports = view
view.usage = "npm view pkg[@version] [<field>[.subfield]...]"
view.completion = function (opts, cb) {
- var uri
if (opts.conf.argv.remain.length <= 2) {
- uri = url.resolve(npm.config.get("registry"), "-/short")
- return registry.get(uri, null, cb)
+ return mapToRegistry("-/short", npm.config, function (er, uri) {
+ if (er) return cb(er)
+
+ registry.get(uri, null, cb)
+ })
}
// have the package, get the fields.
var tag = npm.config.get("tag")
- uri = url.resolve(npm.config.get("registry"), opts.conf.argv.remain[2])
- registry.get(uri, null, function (er, d) {
+ mapToRegistry(opts.conf.argv.remain[2], npm.config, function (er, uri) {
if (er) return cb(er)
- var dv = d.versions[d["dist-tags"][tag]]
- , fields = []
- d.versions = Object.keys(d.versions).sort(semver.compareLoose)
- fields = getFields(d).concat(getFields(dv))
- cb(null, fields)
+
+ registry.get(uri, null, function (er, d) {
+ if (er) return cb(er)
+ var dv = d.versions[d["dist-tags"][tag]]
+ , fields = []
+ d.versions = Object.keys(d.versions).sort(semver.compareLoose)
+ fields = getFields(d).concat(getFields(dv))
+ cb(null, fields)
+ })
})
function getFields (d, f, pref) {
@@ -42,12 +47,12 @@ view.completion = function (opts, cb) {
}
}
-var url = require("url")
- , npm = require("./npm.js")
+var npm = require("./npm.js")
, registry = npm.registry
, log = require("npmlog")
, util = require("util")
, semver = require("semver")
+ , mapToRegistry = require("./utils/map-to-registry.js")
function view (args, silent, cb) {
if (typeof cb !== "function") cb = silent, silent = false
@@ -60,53 +65,56 @@ function view (args, silent, cb) {
if (name === ".") return cb(view.usage)
// get the data about this package
- var uri = url.resolve(npm.config.get("registry"), name)
- registry.get(uri, null, function (er, data) {
+ mapToRegistry(name, npm.config, function (er, uri) {
if (er) return cb(er)
- if (data["dist-tags"] && data["dist-tags"].hasOwnProperty(version)) {
- version = data["dist-tags"][version]
- }
- if (data.time && data.time.unpublished) {
- var u = data.time.unpublished
- er = new Error("Unpublished by " + u.name + " on " + u.time)
- er.statusCode = 404
- er.code = "E404"
- er.pkgid = data._id
- return cb(er, data)
- }
+ registry.get(uri, null, function (er, data) {
+ if (er) return cb(er)
+ if (data["dist-tags"] && data["dist-tags"].hasOwnProperty(version)) {
+ version = data["dist-tags"][version]
+ }
+ if (data.time && data.time.unpublished) {
+ var u = data.time.unpublished
+ er = new Error("Unpublished by " + u.name + " on " + u.time)
+ er.statusCode = 404
+ er.code = "E404"
+ er.pkgid = data._id
+ return cb(er, data)
+ }
- var results = []
- , error = null
- , versions = data.versions || {}
- data.versions = Object.keys(versions).sort(semver.compareLoose)
- if (!args.length) args = [""]
- // remove readme unless we asked for it
- if (-1 === args.indexOf("readme")) {
- delete data.readme
- }
+ var results = []
+ , error = null
+ , versions = data.versions || {}
+ data.versions = Object.keys(versions).sort(semver.compareLoose)
+ if (!args.length) args = [""]
+
+ // remove readme unless we asked for it
+ if (-1 === args.indexOf("readme")) {
+ delete data.readme
+ }
- Object.keys(versions).forEach(function (v) {
- if (semver.satisfies(v, version, true)) args.forEach(function (args) {
- // remove readme unless we asked for it
- if (-1 === args.indexOf("readme")) {
- delete versions[v].readme
- }
- results.push(showFields(data, versions[v], args))
+ Object.keys(versions).forEach(function (v) {
+ if (semver.satisfies(v, version, true)) args.forEach(function (args) {
+ // remove readme unless we asked for it
+ if (-1 === args.indexOf("readme")) {
+ delete versions[v].readme
+ }
+ results.push(showFields(data, versions[v], args))
+ })
})
- })
- results = results.reduce(reducer, {})
- var retval = results
+ results = results.reduce(reducer, {})
+ var retval = results
- if (args.length === 1 && args[0] === "") {
- retval = cleanBlanks(retval)
- log.silly("cleanup", retval)
- }
+ if (args.length === 1 && args[0] === "") {
+ retval = cleanBlanks(retval)
+ log.silly("cleanup", retval)
+ }
- if (error || silent) cb(error, retval)
- else printData(results, data._id, cb.bind(null, error, retval))
+ if (error || silent) cb(error, retval)
+ else printData(results, data._id, cb.bind(null, error, retval))
+ })
})
}