diff options
-rw-r--r-- | lib/adduser.js | 7 | ||||
-rw-r--r-- | lib/bugs.js | 14 | ||||
-rw-r--r-- | lib/cache.js | 6 | ||||
-rw-r--r-- | lib/deprecate.js | 6 | ||||
-rw-r--r-- | lib/docs.js | 6 | ||||
-rw-r--r-- | lib/install.js | 2 | ||||
-rw-r--r-- | lib/npm.js | 19 | ||||
-rw-r--r-- | lib/owner.js | 16 | ||||
-rw-r--r-- | lib/publish.js | 7 | ||||
-rw-r--r-- | lib/search.js | 4 | ||||
-rw-r--r-- | lib/star.js | 4 | ||||
-rw-r--r-- | lib/tag.js | 3 | ||||
-rw-r--r-- | lib/unpublish.js | 4 | ||||
-rw-r--r-- | lib/utils/completion/remote-packages.js | 5 | ||||
-rw-r--r-- | lib/utils/completion/users.js | 5 | ||||
-rw-r--r-- | lib/utils/npm-registry-client/adduser.js | 100 | ||||
-rw-r--r-- | lib/utils/npm-registry-client/get.js | 186 | ||||
-rw-r--r-- | lib/utils/npm-registry-client/index.js | 16 | ||||
-rw-r--r-- | lib/utils/npm-registry-client/publish.js | 155 | ||||
-rw-r--r-- | lib/utils/npm-registry-client/request.js | 245 | ||||
-rw-r--r-- | lib/utils/npm-registry-client/star.js | 32 | ||||
-rw-r--r-- | lib/utils/npm-registry-client/tag.js | 8 | ||||
-rw-r--r-- | lib/utils/npm-registry-client/unpublish.js | 105 | ||||
-rw-r--r-- | lib/view.js | 6 |
24 files changed, 70 insertions, 891 deletions
diff --git a/lib/adduser.js b/lib/adduser.js index 4aa54cf0e..f0fc8d10e 100644 --- a/lib/adduser.js +++ b/lib/adduser.js @@ -1,10 +1,10 @@ module.exports = adduser -var registry = require("./utils/npm-registry-client/index.js") - , ini = require("./utils/ini.js") +var ini = require("./utils/ini.js") , log = require("npmlog") , npm = require("./npm.js") + , registry = npm.registry , read = require("read") , promiseChain = require("./utils/promise-chain.js") , crypto @@ -39,6 +39,9 @@ function adduser (args, cb) { if (changed) npm.config.del("_auth") registry.adduser(u.u, u.p, u.e, function (er) { if (er) return cb(er) + registry.username = u.u + registry.password = u.p + registry.email = u.e ini.set("username", u.u, "user") ini.set("_password", u.p, "user") ini.set("email", u.e, "user") diff --git a/lib/bugs.js b/lib/bugs.js index 0d5460ac9..3f9de1231 100644 --- a/lib/bugs.js +++ b/lib/bugs.js @@ -3,22 +3,22 @@ module.exports = bugs bugs.usage = "npm bugs <pkgname>" +var exec = require("./utils/exec.js") + , npm = require("./npm.js") + , registry = npm.registry + , log = require("npmlog") + bugs.completion = function (opts, cb) { if (opts.conf.argv.remain.length > 2) return cb() - registry.get("/-/short", null, 60000, function (er, list) { + registry.get("/-/short", 60000, function (er, list) { return cb(null, list || []) }) } -var exec = require("./utils/exec.js") - , registry = require("./utils/npm-registry-client/index.js") - , npm = require("./npm.js") - , log = require("npmlog") - function bugs (args, cb) { if (!args.length) return cb(bugs.usage) var n = args[0].split("@").shift() - registry.get(n, "latest", 3600, function (er, d) { + registry.get(n + "/latest", 3600, function (er, d) { if (er) return cb(er) var bugs = d.bugs , repo = d.repository || d.repositories diff --git a/lib/cache.js b/lib/cache.js index 69f0c746d..e2e037ebe 100644 --- a/lib/cache.js +++ b/lib/cache.js @@ -13,7 +13,7 @@ Adding a url: 2. goto folder(2) adding a name@version: -1. registry.get(name, version) +1. registry.get(name/version) 2. if response isn't 304, add url(dist.tarball) adding a name@range: @@ -38,7 +38,7 @@ var mkdir = require("mkdirp") , fs = require("graceful-fs") , rm = require("rimraf") , readJson = require("./utils/read-json.js") - , registry = require("./utils/npm-registry-client/index.js") + , registry = npm.registry , log = require("npmlog") , path = require("path") , output @@ -520,7 +520,7 @@ function addNameVersion (name, ver, data, cb) { response = null return next() } - registry.get(name, ver, function (er, d, json, resp) { + registry.get(name + "/" + ver, function (er, d, json, resp) { if (er) return cb(er) data = d response = resp diff --git a/lib/deprecate.js b/lib/deprecate.js index 2fd18cf9f..c9e724e69 100644 --- a/lib/deprecate.js +++ b/lib/deprecate.js @@ -18,9 +18,9 @@ deprecate.completion = function (opts, cb) { }) } -var registry = require("./utils/npm-registry-client/index.js") - , semver = require("semver") +var semver = require("semver") , npm = require("./npm.js") + , registry = npm.registry function deprecate (args, cb) { var pkg = args[0] @@ -42,6 +42,6 @@ function deprecate (args, cb) { data.versions[v].deprecated = msg }) // now update the doc on the registry - registry.request.PUT(data._id, data, cb) + registry.request('PUT', data._id, data, cb) }) } diff --git a/lib/docs.js b/lib/docs.js index 275fce7e9..72c1869b9 100644 --- a/lib/docs.js +++ b/lib/docs.js @@ -5,20 +5,20 @@ docs.usage = "npm docs <pkgname>" docs.completion = function (opts, cb) { if (opts.conf.argv.remain.length > 2) return cb() - registry.get("/-/short", null, 60000, function (er, list) { + registry.get("/-/short", 60000, function (er, list) { return cb(null, list || []) }) } var exec = require("./utils/exec.js") - , registry = require("./utils/npm-registry-client/index.js") , npm = require("./npm.js") + , registry = npm.registry , log = require("npmlog") function docs (args, cb) { if (!args.length) return cb(docs.usage) var n = args[0].split("@").shift() - registry.get(n, "latest", 3600, function (er, d) { + registry.get(n + "/latest", 3600, function (er, d) { if (er) return cb(er) var homepage = d.homepage , repo = d.repository || d.repositories diff --git a/lib/install.js b/lib/install.js index ed5c4ce2b..79bad0fe9 100644 --- a/lib/install.js +++ b/lib/install.js @@ -30,7 +30,7 @@ install.completion = function (opts, cb) { // if it has a slash, then it's gotta be a folder // if it starts with https?://, then just give up, because it's a url // for now, not yet implemented. - var registry = require("./utils/npm-registry-client/index.js") + var registry = npm.registry registry.get("/-/short", function (er, pkgs) { if (er) return cb() if (!opts.partialWord) return cb(null, pkgs) diff --git a/lib/npm.js b/lib/npm.js index 1a7ae4b42..09ace1607 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -29,6 +29,7 @@ var EventEmitter = require("events").EventEmitter , mkdirp = require("mkdirp") , slide = require("slide") , chain = slide.chain + , RegClient = require("npm-registry-client") // /usr/local is often a read-only fs, which is not // well handled by node or mkdirp. Just double-check @@ -276,9 +277,25 @@ function load (npm, conf, cb) { } log.resume() - //console.error("back from config lookup", er && er.stack) if (er) return cb(er) + // at this point the configs are all set. + // go ahead and spin up the registry client. + npm.registry = new RegClient( + { registry: npm.config.get("registry") + , cache: npm.config.get("cache") + , auth: npm.config.get("_auth") + , alwaysAuth: npm.config.get("always-auth") + , email: npm.config.get("email") + , tag: npm.config.get("tag") + , ca: npm.config.get("ca") + , strictSSL: npm.config.get("strict-ssl") + , userAgent: npm.config.get("user-agent") + , E404: npm.E404 + , EPUBLISHCONFLICT: npm.EPUBLISHCONFLICT + , log: log + }) + var umask = parseInt(conf.umask, 8) npm.modes = { exec: 0777 & (~umask) , file: 0666 & (~umask) diff --git a/lib/owner.js b/lib/owner.js index ebad9ed10..6a38625e5 100644 --- a/lib/owner.js +++ b/lib/owner.js @@ -64,12 +64,10 @@ owner.completion = function (opts, cb) { } } -var registry = require("./utils/npm-registry-client/index.js") - , get = registry.request.GET - , put = registry.request.PUT +var npm = require("./npm.js") + , registry = npm.registry , log = require("npmlog") , output - , npm = require("./npm.js") function owner (args, cb) { var action = args.shift() @@ -83,7 +81,7 @@ function owner (args, cb) { function ls (pkg, cb) { if (!pkg) return cb(owner.usage) - get(pkg, function (er, data) { + registry.get(pkg, function (er, data) { var msg = "" if (er) { log.error("owner ls", "Couldn't get owner data", pkg) @@ -147,7 +145,7 @@ function rm (user, pkg, cb) { function mutate (pkg, user, mutation, cb) { if (user) { - get("/-/user/org.couchdb.user:"+user, mutate_) + registry.get("/-/user/org.couchdb.user:"+user, mutate_) } else { mutate_(null, null) } @@ -162,7 +160,7 @@ function mutate (pkg, user, mutation, cb) { } if (u) u = { "name" : u.name, "email" : u.email } - get("/"+pkg, function (er, data) { + registry.get(pkg, function (er, data) { if (er) { log.error("owner mutate", "Error getting package data for %s", pkg) return cb(er) @@ -174,7 +172,9 @@ function mutate (pkg, user, mutation, cb) { , _rev : data._rev , maintainers : m } - put("/"+pkg+"/-rev/"+data._rev, data, function (er, data) { + registry.request("PUT" + , pkg+"/-rev/"+data._rev, data + , function (er, data) { if (!er && data.error) er = new Error( "Failed to update package metadata: "+JSON.stringify(data)) if (er) { diff --git a/lib/publish.js b/lib/publish.js index 45f3908ff..ac0c2b70f 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -2,7 +2,7 @@ module.exports = publish var npm = require("./npm.js") - , registry = require("./utils/npm-registry-client/index.js") + , registry = npm.registry , log = require("npmlog") , tar = require("./utils/tar.js") , sha = require("./utils/sha.js") @@ -151,9 +151,12 @@ function regPublish (data, prebuilt, isRetry, arg, cachedir, cb) { // check to see if there's a README.md in there. var readme = path.resolve(cachedir, "README.md") + , tarball = cachedir + ".tgz" + fs.readFile(readme, function (er, readme) { // ignore error. it's an optional feature - registry.publish(data, prebuilt, readme, function (er) { + + registry.publish(data, tarball, readme, function (er) { if (er && er.errno === npm.EPUBLISHCONFLICT && npm.config.get("force") && !isRetry) { log.warn("publish", "Forced publish over "+data._id) diff --git a/lib/search.js b/lib/search.js index ba27bdb52..9ed712bcc 100644 --- a/lib/search.js +++ b/lib/search.js @@ -2,7 +2,7 @@ module.exports = exports = search var npm = require("./npm.js") - , registry = require("./utils/npm-registry-client/index.js") + , registry = npm.registry , semver = require("semver") , output @@ -59,7 +59,7 @@ function search (args, silent, staleness, cb_) { } function getFilteredData (staleness, args, notArgs, cb) { - registry.get( "/-/all", null, staleness, false + registry.get( "/-/all", staleness, false , true, 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 2ad818479..fc4fb96f1 100644 --- a/lib/star.js +++ b/lib/star.js @@ -2,7 +2,7 @@ module.exports = star var npm = require("./npm.js") - , registry = require("./utils/npm-registry-client/index.js") + , registry = npm.registry , log = require("npmlog") , asyncMap = require("slide").asyncMap , output = require("./utils/output.js") @@ -11,7 +11,7 @@ star.usage = "npm star <package> [pkg, pkg, ...]\n" + "npm unstar <package> [pkg, pkg, ...]" star.completion = function (opts, cb) { - registry.get("/-/short", null, 60000, function (er, list) { + registry.get("/-/short", 60000, function (er, list) { return cb(null, list || []) }) } diff --git a/lib/tag.js b/lib/tag.js index 06aa70c5e..8a7c51ca0 100644 --- a/lib/tag.js +++ b/lib/tag.js @@ -6,6 +6,7 @@ tag.usage = "npm tag <project>@<version> [<tag>]" tag.completion = require("./unpublish.js").completion var npm = require("./npm.js") + , registry = npm.registry function tag (args, cb) { var thing = (args.shift() || "").split("@") @@ -13,5 +14,5 @@ function tag (args, cb) { , version = thing.join("@") , t = args.shift() || npm.config.get("tag") if (!project || !version || !t) return cb("Usage:\n"+tag.usage) - require("./utils/npm-registry-client/index.js").tag(project, version, t, cb) + registry.tag(project, version, t, cb) } diff --git a/lib/unpublish.js b/lib/unpublish.js index 46c91d1ef..8aae12c3d 100644 --- a/lib/unpublish.js +++ b/lib/unpublish.js @@ -1,9 +1,9 @@ module.exports = unpublish -var registry = require("./utils/npm-registry-client/index.js") - , log = require("npmlog") +var log = require("npmlog") , npm = require("./npm.js") + , registry = npm.registry , readJson = require("./utils/read-json.js") , path = require("path") , output = require("./utils/output.js") diff --git a/lib/utils/completion/remote-packages.js b/lib/utils/completion/remote-packages.js index 4bf82d070..18d812caa 100644 --- a/lib/utils/completion/remote-packages.js +++ b/lib/utils/completion/remote-packages.js @@ -1,7 +1,8 @@ module.exports = remotePackages -var registry = require("../npm-registry-client/index.js") +var npm = require("../../npm.js") + , registry = npm.registry , containsSingleMatch = require("./contains-single-match.js") , getCompletions = require("./get-completions.js") @@ -25,7 +26,7 @@ function remotePackages (args, index, doVersion, doTag if (name === undefined) name = "" if (name.indexOf("/") !== -1) return cb(null, []) // use up-to 1 hour stale cache. not super urgent. - registry.get("/", null, 3600, function (er, d) { + registry.get("/", 3600, function (er, d) { if (er) return cb(er) var remoteList = Object.keys(d) , found = remoteList.indexOf(name) diff --git a/lib/utils/completion/users.js b/lib/utils/completion/users.js index 2c62fc6ec..1dc6dbb91 100644 --- a/lib/utils/completion/users.js +++ b/lib/utils/completion/users.js @@ -1,7 +1,8 @@ module.exports = users -var registry = require("../npm-registry-client/index.js") +var npm = require("../../npm") + , registry = npm.registry , containsSingleMatch = require("./contains-single-match.js") , getCompletions = require("./get-completions.js") , log = require("npmlog") @@ -11,7 +12,7 @@ function users (args, index, cb) { if (name === undefined) name = "" // use up-to 1 day stale cache. doesn't change much log.warn("users completion", "About to fetch") - registry.get("/-/users", null, 24*60*60, function (er, d) { + registry.get("/-/users", 24*60*60, function (er, d) { log.warn("userdata", d) log.warn("name", name) if (er) return cb(er) diff --git a/lib/utils/npm-registry-client/adduser.js b/lib/utils/npm-registry-client/adduser.js deleted file mode 100644 index 0dc582395..000000000 --- a/lib/utils/npm-registry-client/adduser.js +++ /dev/null @@ -1,100 +0,0 @@ - -module.exports = adduser - -var uuid = require("node-uuid") - , request = require("./request.js") - , log = require("npmlog") - , npm = require("../../npm.js") - , crypto - -try { - crypto = process.binding("crypto") && require("crypto") -} catch (ex) {} - -function sha (s) { - return crypto.createHash("sha1").update(s).digest("hex") -} - -function adduser (username, password, email, cb) { - if (!crypto) return cb(new Error( - "You must compile node with ssl support to use the adduser feature")) - - password = ("" + (password || "")).trim() - if (!password) return cb(new Error("No password supplied.")) - - email = ("" + (email || "")).trim() - if (!email) return cb(new Error("No email address supplied.")) - if (!email.match(/^[^@]+@[^\.]+\.[^\.]+/)) { - return cb(new Error("Please use a real email address.")) - } - - if (password.indexOf(":") !== -1) return cb(new Error( - "Sorry, ':' chars are not allowed in passwords.\n"+ - "See <https://issues.apache.org/jira/browse/COUCHDB-969> for why.")) - var salt = uuid() - , userobj = - { name : username - , salt : salt - , password_sha : sha(password + salt) - , email : email - , _id : 'org.couchdb.user:'+username - , type : "user" - , roles : [] - , date: new Date().toISOString() - } - cb = done(cb) - log.verbose("adduser", "before first PUT", userobj) - request.PUT - ( '/-/user/org.couchdb.user:'+encodeURIComponent(username) - , userobj - , function (error, data, json, response) { - // if it worked, then we just created a new user, and all is well. - // but if we're updating a current record, then it'll 409 first - if (error && !npm.config.get("_auth")) { - // must be trying to re-auth on a new machine. - // use this info as auth - npm.config.set("username", username) - npm.config.set("_password", password) - var b = new Buffer(username + ":" + password) - npm.config.set("_auth", b.toString("base64")) - } - if (!error || !response || response.statusCode !== 409) { - return cb(error, data, json, response) - } - log.verbose("adduser", "update existing user") - return request.GET - ( '/-/user/org.couchdb.user:'+encodeURIComponent(username) - , function (er, data, json, response) { - userobj._rev = data._rev - userobj.roles = data.roles - log.verbose("adduser", "userobj", userobj) - request.PUT - ( '/-/user/org.couchdb.user:'+encodeURIComponent(username) - + "/-rev/" + userobj._rev - , userobj - , cb ) - } - ) - } - ) -} - -function done (cb) { return function (error, data, json, response) { - if (!error && (!response || response.statusCode === 201)) { - return cb(error, data, json, response) - } - log.verbose("adduser", "back", [error, data, json]) - if (!error) { - error = new Error( (response && response.statusCode || "") + " "+ - "Could not create user\n"+JSON.stringify(data)) - } - if (response - && (response.statusCode === 401 || response.statusCode === 403)) { - log.warn("adduser", "Incorrect username or password\n" - +"You can reset your account by visiting:\n" - +"\n" - +" http://admin.npmjs.org/reset\n") - } - - return cb(error) -}} diff --git a/lib/utils/npm-registry-client/get.js b/lib/utils/npm-registry-client/get.js deleted file mode 100644 index 89a3d7cbc..000000000 --- a/lib/utils/npm-registry-client/get.js +++ /dev/null @@ -1,186 +0,0 @@ - -module.exports = get - -var GET = require("./request.js").GET - , fs = require("graceful-fs") - , npm = require("../../npm.js") - , path = require("path") - , log = require("npmlog") - , mkdir = require("mkdirp") - , cacheStat = null - , chownr = require("chownr") - -function get (project, version, timeout, nofollow, staleOk, cb) { - if (typeof cb !== "function") cb = staleOk, staleOk = false - if (typeof cb !== "function") cb = nofollow, nofollow = false - if (typeof cb !== "function") cb = timeout, timeout = -1 - if (typeof cb !== "function") cb = version, version = null - if (typeof cb !== "function") cb = project, project = null - if (typeof cb !== "function") { - throw new Error("No callback provided to registry.get") - } - - timeout = Math.min(timeout, npm.config.get("cache-max")) - timeout = Math.max(timeout, npm.config.get("cache-min")) - - if ( process.env.COMP_CWORD !== undefined - && process.env.COMP_LINE !== undefined - && process.env.COMP_POINT !== undefined - ) timeout = Math.max(timeout, 60000) - - var uri = [] - uri.push(project || "") - if (version) uri.push(version) - uri = uri.join("/") - - // /-/all is special. - // It uses timestamp-based caching and partial updates, - // because it is a monster. - if (uri === "/-/all") { - return requestAll(cb) - } - - var cache = path.join(npm.cache, uri, ".cache.json") - fs.stat(cache, function (er, stat) { - if (!er) fs.readFile(cache, function (er, data) { - try { data = JSON.parse(data) } - catch (ex) { data = null } - get_(uri, timeout, cache, stat, data, nofollow, staleOk, cb) - }) - else get_(uri, timeout, cache, null, null, nofollow, staleOk, cb) - }) -} - -function requestAll (cb) { - var cache = path.join(npm.cache, "/-/all", ".cache.json") - - mkdir(path.join(npm.cache, "-", "all"), function (er) { - fs.readFile(cache, function (er, data) { - if (er) return requestAll_(0, {}, cb) - try { - data = JSON.parse(data) - } catch (ex) { - fs.writeFile(cache, "{}", function (er) { - if (er) return cb(new Error("Broken cache. " - +"Please run 'npm cache clean' " - +"and try again.")) - return requestAll_(0, {}, cb) - }) - } - var t = +data._updated || 0 - requestAll_(t, data, cb) - }) - }) -} - -function requestAll_ (c, data, cb) { - // use the cache and update in the background if it's not too old - if (Date.now() - c < 60000) { - cb(null, data) - cb = function () {} - } - - var uri = "/-/all/since?stale=update_after&startkey=" + c - - if (c === 0) { - log.warn("", "Building the local index for the first time, please be patient") - uri = "/-/all" - } - - var cache = path.join(npm.cache, "-/all", ".cache.json") - GET(uri, function (er, updates, _, res) { - if (er) return cb(er, data) - var headers = res.headers - , updated = Date.parse(headers.date) - Object.keys(updates).forEach(function (p) { - data[p] = updates[p] - }) - data._updated = updated - fs.writeFile( cache, JSON.stringify(data) - , function (er) { - delete data._updated - return cb(er, data) - }) - }) -} - -function get_ (uri, timeout, cache, stat, data, nofollow, staleOk, cb) { - var etag - if (data && data._etag) etag = data._etag - if (timeout && timeout > 0 && stat && data) { - if ((Date.now() - stat.mtime.getTime())/1000 < timeout) { - log.verbose("registry.get", uri, "not expired, no request") - delete data._etag - return cb(null, data, JSON.stringify(data), {statusCode:304}) - } - if (staleOk) { - log.verbose("registry.get", uri, "staleOk, background update") - delete data._etag - process.nextTick(cb.bind( null, null, data, JSON.stringify(data) - , {statusCode: 304} )) - cb = function () {} - } - } - - GET(uri, etag, nofollow, function (er, remoteData, raw, response) { - // if we get an error talking to the registry, but we have it - // from the cache, then just pretend we got it. - if (er && cache && data && !data.error) { - er = null - response = {statusCode: 304} - } - - if (response) { - log.silly("registry.get", "cb", [response.statusCode, response.headers]) - if (response.statusCode === 304 && etag) { - remoteData = data - log.verbose("etag", uri+" from cache") - } - } - - data = remoteData - if (!data) { - er = er || new Error("failed to fetch from registry: " + uri) - } - - if (er) return cb(er, data, raw, response) - - // just give the write the old college try. if it fails, whatever. - function saved () { - delete data._etag - cb(er, data, raw, response) - } - - saveToCache(cache, data, saved) - }) -} - -function saveToCache (cache, data, saved) { - if (cacheStat) { - return saveToCache_(cache, data, cacheStat.uid, cacheStat.gid, saved) - } - fs.stat(npm.cache, function (er, st) { - if (er) { - return fs.stat(process.env.HOME || "", function (er, st) { - // if this fails, oh well. - if (er) return saved() - cacheStat = st - return saveToCache(cache, data, saved) - }) - } - cacheStat = st || { uid: null, gid: null } - return saveToCache(cache, data, saved) - }) -} - -function saveToCache_ (cache, data, uid, gid, saved) { - mkdir(path.dirname(cache), function (er, made) { - if (er) return saved() - fs.writeFile(cache, JSON.stringify(data), function (er) { - if (er || uid === null || gid === null) { - return saved() - } - chownr(made || cache, uid, gid, saved) - }) - }) -} diff --git a/lib/utils/npm-registry-client/index.js b/lib/utils/npm-registry-client/index.js deleted file mode 100644 index 2a4294745..000000000 --- a/lib/utils/npm-registry-client/index.js +++ /dev/null @@ -1,16 +0,0 @@ - -// utilities for working with the js-registry site. - -var cached = {} -function lazyGet (p) { return function () { - return cached[p] || (cached[p] = require("./"+p+".js")) -}} - -function setLazyGet (p) { - Object.defineProperty(exports, p, - { get : lazyGet(p) - , enumerable : true }) -} - -; ["publish", "unpublish", "tag", "adduser", "get", "request", "star"] - .forEach(setLazyGet) diff --git a/lib/utils/npm-registry-client/publish.js b/lib/utils/npm-registry-client/publish.js deleted file mode 100644 index 77d7c9364..000000000 --- a/lib/utils/npm-registry-client/publish.js +++ /dev/null @@ -1,155 +0,0 @@ - -module.exports = publish - -var request = require("./request.js") - , GET = request.GET - , PUT = request.PUT - , DELETE = request.DELETE - , reg = request.reg - , upload = request.upload - , log = require("npmlog") - , path = require("path") - , npm = require("../../npm.js") - , url = require("url") - -function publish (data, prebuilt, readme, cb) { - if (typeof readme === "function") cb = readme, readme = "" - if (typeof prebuilt === "function") cb = prebuilt, prebuilt = null - // add the dist-url to the data, pointing at the tarball. - // if the {name} isn't there, then create it. - // if the {version} is already there, then fail. - // then: - // PUT the data to {config.registry}/{data.name}/{data.version} - var registry = reg() - if (registry instanceof Error) return cb(registry) - - readme = readme ? "" + readme : "" - - var fullData = - { _id : data.name - , name : data.name - , description : data.description - , "dist-tags" : {} - , versions : {} - , readme: readme - , maintainers : - [ { name : npm.config.get("username") - , email : npm.config.get("email") - } - ] - } - - var tbName = data.name + "-" + data.version + ".tgz" - , bd = npm.config.get("bindist") - , pbName = data.name + "-" + data.version + "-" + bd + ".tgz" - , tbURI = data.name + "/-/" + tbName - , pbURI = data.name + "/-/" + pbName - - data._id = data.name+"@"+data.version - data.dist = data.dist || {} - data.dist.tarball = url.resolve(registry, tbURI) - .replace(/^https:\/\//, "http://") - - if (prebuilt && bd) { - data.dist.bin[bd] = data.dist.bin[bd] || {} - data.dist.bin[bd].tarball = url.resolve(registry, pbURI) - .replace(/^https:\/\//, "http://") - } - - - - - // first try to just PUT the whole fullData, and this will fail if it's - // already there, because it'll be lacking a _rev, so couch'll bounce it. - PUT(encodeURIComponent(data.name), fullData, - function (er, parsed, json, response) { - // get the rev and then upload the attachment - // a 409 is expected here, if this is a new version of an existing package. - if (er - && !(response && response.statusCode === 409) - && !( parsed - && parsed.reason === - "must supply latest _rev to update existing package" )) { - log.error("publish", "Failed PUT response " - +(response && response.statusCode)) - return cb(er) - } - var dataURI = encodeURIComponent(data.name) - + "/" + encodeURIComponent(data.version) - - var tag = data.tag || npm.config.get("tag") - if (npm.config.get("pre")) dataURI += "/-pre/true" - else if (tag) dataURI += "/-tag/" + tag - else dataURI += "/-tag/latest" - - // let's see what verions are already published. - // could be that we just need to update the bin dist values. - GET(data.name, function (er, fullData) { - if (er) return cb(er) - - var exists = fullData.versions && fullData.versions[data.version] - if (exists) { - log.info("already published", exists._id) - var ebin = exists.dist.bin || {} - , nbin = data.dist.bin || {} - , needs = Object.keys(nbin).filter(function (bd) { - return !ebin.hasOwnProperty(bd) - }) - log.verbose("upload bindist", needs) - if (!needs.length) return cb(conflictError(data._id)) - // attach the needed bindists, upload the new metadata - exists.dist.bin = ebin - needs.forEach(function (bd) { exists.dist.bin[bd] = nbin[bd] }) - return PUT(dataURI + "/-rev/" + fullData._rev, exists, function (er) { - if (er) return cb(er) - attach(data.name, prebuilt, pbName, cb) - }) - } - - // this way, it'll also get attached to packages that were previously - // published with a version of npm that lacked this feature. - if (!fullData.readme) { - data.readme = readme - } - PUT(dataURI, data, function (er) { - if (er) { - if (er.message.indexOf("conflict Document update conflict.") === 0) { - return cb(conflictError(data._id)) - } - log.error("publish", "Error sending version data") - return cb(er) - } - - var c = path.resolve(npm.cache, data.name, data.version) - , tb = path.resolve(c, "package.tgz") - - log.verbose("publish", "attach 2", [data.name, tb, tbName]) - attach(data.name, tb, tbName, function (er) { - log.verbose("publish", "attach 3", [er, data.name, prebuilt, pbName]) - if (er || !prebuilt) return cb(er) - attach(data.name, prebuilt, pbName, cb) - }) - }) - }) - }) -} - -function conflictError (pkgid) { - var e = new Error("publish fail") - e.errno = npm.EPUBLISHCONFLICT - e.pkgid = pkgid - return e -} - -function attach (doc, file, filename, cb) { - doc = encodeURIComponent(doc) - GET(doc, function (er, d) { - if (er) return cb(er) - if (!d) return cb(new Error( - "Attempting to upload to invalid doc "+doc)) - var rev = "-rev/"+d._rev - , attURI = doc + "/-/" + encodeURIComponent(filename) + "/" + rev - log.verbose("uploading", [attURI, file]) - upload(attURI, file, cb) - }) -} diff --git a/lib/utils/npm-registry-client/request.js b/lib/utils/npm-registry-client/request.js deleted file mode 100644 index 2ecae9386..000000000 --- a/lib/utils/npm-registry-client/request.js +++ /dev/null @@ -1,245 +0,0 @@ -module.exports = regRequest - -regRequest.GET = GET -regRequest.PUT = PUT -regRequest.reg = reg -regRequest.upload = upload - -var npm = require("../../npm.js") - , url = require("url") - , log = require("npmlog") - , fs = require("graceful-fs") - , rm = require("rimraf") - , asyncMap = require("slide").asyncMap - , warnedAuth = false - , newloctimeout = 0 - , stream = require("stream") - , Stream = stream.Stream - , request = require("request") - -function regRequest (method, where, what, etag, nofollow, cb_) { - if (typeof cb_ !== "function") cb_ = nofollow, nofollow = false - if (typeof cb_ !== "function") cb_ = etag, etag = null - if (typeof cb_ !== "function") cb_ = what, what = null - - // Since there are multiple places where an error could occur, - // don't let the cb be called more than once. - var errState = null - function cb (er) { - if (errState) return - if (er) errState = er - cb_.apply(null, arguments) - } - - if (where.match(/^\/?favicon.ico/)) { - return cb(new Error("favicon.ico isn't a package, it's a picture.")) - } - - var registry = reg() - if (registry instanceof Error) return cb(registry) - - var adduserChange = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)\/-rev/ - , adduserNew = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)/ - , authRequired = (what || npm.config.get("always-auth")) - && !where.match(adduserNew) - || where.match(adduserChange) - || method === "DELETE" - - // resolve to a full url on the registry - if (!where.match(/^https?:\/\//)) { - log.verbose("url raw", where) - - var q = where.split("?") - where = q.shift() - q = q.join("?") - - if (where.charAt(0) !== "/") where = "/" + where - where = "." + where.split("/").map(function (p) { - p = p.trim() - if (p.match(/^org.couchdb.user/)) { - return p.replace(/\//g, encodeURIComponent("/")) - } - return encodeURIComponent(p) - }).join("/") - if (q) where += "?" + q - log.verbose("url resolving", [registry, where]) - where = url.resolve(registry, where) - log.verbose("url resolved", where) - } - - var remote = url.parse(where) - , auth = authRequired && npm.config.get("_auth") - - if (authRequired && !auth) { - return cb(new Error( - "Cannot insert data into the registry without authorization\n" - + "See: npm-adduser(1)")) - } - - if (auth) remote.auth = new Buffer(auth, "base64").toString("utf8") - - makeRequest(method, remote, where, what, etag, nofollow, cb) -} - -function makeRequest (method, remote, where, what, etag, nofollow, cb) { - var opts = { url: remote - , method: method - , ca: npm.config.get("ca") - , strictSSL: npm.config.get("strict-ssl") } - , headers = opts.headers = {} - if (etag) { - log.verbose("etag", etag) - headers[method === "GET" ? "if-none-match" : "if-match"] = etag - } - - headers.accept = "application/json" - - headers["user-agent"] = npm.config.get("user-agent") - - opts.proxy = npm.config.get( remote.protocol === "https:" - ? "https-proxy" : "proxy" ) - - // figure out wth 'what' is - if (what) { - if (Buffer.isBuffer(what) || typeof what === "string") { - opts.body = what - headers["content-type"] = "application/json" - headers["content-length"] = Buffer.byteLength(what) - } else if (what instanceof Stream) { - headers["content-type"] = "application/octet-stream" - if (what.size) headers["content-length"] = what.size - } else { - delete what._etag - opts.json = what - } - } - - if (nofollow) { - opts.followRedirect = false - } - - log.http(method, remote.href || "/") - - var req = request(opts, requestDone(method, where, cb)) - var r = npm.config.get("registry") - if (!r) { - return new Error("Must define registry URL before accessing registry.") - } - - req.on("error", cb) - - if (what && (what instanceof Stream)) { - what.pipe(req) - } -} - -// cb(er, parsed, raw, response) -function requestDone (method, where, cb) { return function (er, response, data) { - if (er) return cb(er) - - log.http(response.statusCode, url.parse(where).href) - - var parsed - - if (Buffer.isBuffer(data)) { - data = data.toString() - } - - if (data && typeof data === "string" && response.statusCode !== 304) { - try { - parsed = JSON.parse(data) - } catch (ex) { - ex.message += "\n" + data - log.verbose("bad json", data) - log.error("registry", "error parsing json") - return cb(ex, null, data, response) - } - } else if (data) { - parsed = data - data = JSON.stringify(parsed) - } - - // expect data with any error codes - if (!data && response.statusCode >= 400) { - return cb( response.statusCode + " " - + require("http").STATUS_CODES[response.statusCode] - , null, data, response ) - } - - var er = null - if (parsed && response.headers.etag) { - parsed._etag = response.headers.etag - } - - if (parsed && parsed.error && response.statusCode >= 400) { - var w = url.parse(where).pathname.substr(1) - if (!w.match(/^-/) && parsed.error === "not_found") { - w = w.split("/") - name = w[w.indexOf("_rewrite") + 1] - er = new Error("404 Not Found: "+name) - er.errno = npm.E404 - er.pkgid = name - } else { - er = new Error( - parsed.error + " " + (parsed.reason || "") + ": " + w) - } - } else if (method !== "HEAD" && method !== "GET") { - // invalidate cache - // This is irrelevant for commands that do etag caching, but - // ls and view also have a timed cache, so this keeps the user - // from thinking that it didn't work when it did. - // Note that failure is an acceptable option here, since the - // only result will be a stale cache for some helper commands. - var path = require("path") - , p = url.parse(where).pathname.split("/") - , _ = "/" - , caches = p.map(function (part) { - return _ = path.join(_, part) - }).map(function (cache) { - return path.join(npm.cache, cache, ".cache.json") - }) - - // if the method is DELETE, then also remove the thing itself. - // Note that the search index is probably invalid. Whatever. - // That's what you get for deleting stuff. Don't do that. - if (method === "DELETE") { - p = p.slice(0, p.indexOf("-rev")) - caches.push(path.join(npm.cache, p.join("/"))) - } - - asyncMap(caches, rm, function () {}) - } - return cb(er, parsed, data, response) -}} - -function GET (where, etag, nofollow, cb) { - regRequest("GET", where, null, etag, nofollow, cb) -} - -function PUT (where, what, etag, nofollow, cb) { - regRequest("PUT", where, what, etag, nofollow, cb) -} - -function upload (where, filename, etag, nofollow, cb) { - if (typeof nofollow === "function") cb = nofollow, nofollow = false - if (typeof etag === "function") cb = etag, etag = null - - fs.stat(filename, function (er, stat) { - if (er) return cb(er) - var s = fs.createReadStream(filename) - s.size = stat.size - s.on("error", cb) - - PUT(where, s, etag, nofollow, cb) - }) -} - -function reg () { - var r = npm.config.get("registry") - if (!r) { - return new Error("Must define registry URL before accessing registry.") - } - if (r.substr(-1) !== "/") r += "/" - npm.config.set("registry", r) - return r -} diff --git a/lib/utils/npm-registry-client/star.js b/lib/utils/npm-registry-client/star.js deleted file mode 100644 index eeaca14ef..000000000 --- a/lib/utils/npm-registry-client/star.js +++ /dev/null @@ -1,32 +0,0 @@ - -module.exports = star - -var request = require("./request.js") - , GET = request.GET - , PUT = request.PUT - , log = require("npmlog") - , npm = require("../../npm.js") - -function star (package, starred, cb) { - var users = {} - - GET(package, function (er, fullData) { - if (er) return cb(er) - - fullData = { _id: fullData._id - , _rev: fullData._rev - , users: fullData.users || {} } - - if (starred) { - log.info("starring", fullData._id) - fullData.users[npm.config.get("username")] = true - log.verbose("starring", fullData) - } else { - delete fullData.users[npm.config.get("username")] - log.info("unstarring", fullData._id) - log.verbose("unstarring", fullData) - } - - return PUT(package, fullData, cb) - }) -} diff --git a/lib/utils/npm-registry-client/tag.js b/lib/utils/npm-registry-client/tag.js deleted file mode 100644 index 4d88a98db..000000000 --- a/lib/utils/npm-registry-client/tag.js +++ /dev/null @@ -1,8 +0,0 @@ - -module.exports = tag - -var PUT = require("./request.js").PUT - -function tag (project, version, tag, cb) { - PUT(project+"/"+tag, JSON.stringify(version), cb) -} diff --git a/lib/utils/npm-registry-client/unpublish.js b/lib/utils/npm-registry-client/unpublish.js deleted file mode 100644 index 4e4982c6b..000000000 --- a/lib/utils/npm-registry-client/unpublish.js +++ /dev/null @@ -1,105 +0,0 @@ - -// fetch the data -// modify to remove the version in question -// If no versions remaining, then DELETE -// else, PUT the modified data -// delete the tarball - -module.exports = unpublish - -var request = require("./request.js") - , log = require("npmlog") - , get = require("./get.js") - , semver = require("semver") - , url = require("url") - , chain = require("slide").chain - -function unpublish (name, ver, cb) { - if (!cb) cb = ver, ver = null - if (!cb) throw new Error( - "Not enough arguments for registry unpublish") - - get(name, null, -1, true, function (er, data) { - if (er) { - log.info("unpublish", name+" not published") - return cb() - } - // remove all if no version specified - if (!ver) { - log.info("unpublish", "No version specified, removing all") - return request("DELETE", name+'/-rev/'+data._rev, cb) - } - - var versions = data.versions || {} - , versionPublic = versions.hasOwnProperty(ver) - - if (!versionPublic) log.info("unpublish", name+"@"+ver+" not published") - else { - var dist = versions[ver].dist - log.verbose("unpublish", "removing attachments", dist) - } - - delete versions[ver] - // if it was the only version, then delete the whole package. - if (!Object.keys(versions).length) { - log.info("unpublish", "No versions remain, removing entire package") - return request("DELETE", name+"/-rev/"+data._rev, cb) - } - - if (!versionPublic) return cb() - - var latestVer = data["dist-tags"].latest - for (var tag in data["dist-tags"]) { - if (data["dist-tags"][tag] === ver) delete data["dist-tags"][tag] - } - - if (latestVer === ver) { - data["dist-tags"].latest = - Object.getOwnPropertyNames(versions).sort(semver.compare).pop() - } - - var rev = data._rev - delete data._revisions - delete data._attachments - var cb_ = detacher(data, dist, cb) - request.PUT(name+"/-rev/"+rev, data, function (er) { - if (er) { - log.error("unpublish", "Failed to update data") - } - cb_(er) - }) - }) -} - -function detacher (data, dist, cb) { return function (er) { - if (er) return cb(er) - get(data.name, function (er, data) { - if (er) return cb(er) - - var tb = url.parse(dist.tarball) - - detach(data, tb.pathname, data._rev, function (er) { - if (er || !dist.bin) return cb(er) - chain(Object.keys(dist.bin).map(function (bt) { - return function (cb) { - var d = dist.bin[bt] - detach(data, url.parse(d.tarball).pathname, null, cb) - } - }), cb) - }) - }) -}} - -function detach (data, path, rev, cb) { - if (rev) { - path += "/-rev/" + rev - log.info("detach", path) - return request("DELETE", path, cb) - } - get(data.name, function (er, data) { - rev = data._rev - if (!rev) return cb(new Error( - "No _rev found in "+data._id)) - detach(data, path, rev, cb) - }) -} diff --git a/lib/view.js b/lib/view.js index 646b6377f..6ffde4c28 100644 --- a/lib/view.js +++ b/lib/view.js @@ -39,12 +39,12 @@ view.completion = function (opts, cb) { } } -var registry = require("./utils/npm-registry-client/index.js") +var npm = require("./npm.js") + , registry = npm.registry , ini = require("ini") , log = require("npmlog") , util = require("util") , output - , npm = require("./npm.js") , semver = require("semver") , readJson = require("./utils/read-json.js") @@ -59,7 +59,7 @@ function view (args, silent, cb) { if (name === ".") return cb(view.usage) // get the data about this package - registry.get(name, null, 600, function (er, data) { + registry.get(name, 600, function (er, data) { if (er) return cb(er) if (data["dist-tags"].hasOwnProperty(version)) { version = data["dist-tags"][version] |