From c96fc63f54a5c81620ee5e21b1d37c816f9e97d6 Mon Sep 17 00:00:00 2001 From: Forrest L Norvell Date: Thu, 22 May 2014 15:47:36 -0700 Subject: [PATCH] switch API to use URLs instead of names --- lib/adduser.js | 14 ++++++------ lib/deprecate.js | 12 ++++------- lib/get.js | 14 ++++-------- lib/publish.js | 29 +++++++------------------ lib/star.js | 14 +++--------- lib/tag.js | 9 ++------ lib/unpublish.js | 42 +++++++++++++----------------------- lib/upload.js | 11 +++------- test/adduser-new.js | 13 +++++------ test/adduser-update.js | 17 +++++++-------- test/bugs.js | 1 + test/deprecate.js | 14 ++++++------ test/get-basic.js | 4 ++-- test/lib/common.js | 4 ++-- test/publish-again.js | 2 +- test/publish.js | 2 +- test/request-gzip-content.js | 4 ++-- test/retries.js | 2 +- test/star.js | 2 +- test/tag.js | 2 +- test/unpublish.js | 2 +- test/upload.js | 12 +++++------ 22 files changed, 88 insertions(+), 138 deletions(-) diff --git a/lib/adduser.js b/lib/adduser.js index 74293ee..d1fcac8 100644 --- a/lib/adduser.js +++ b/lib/adduser.js @@ -1,6 +1,12 @@ module.exports = adduser -function adduser (username, password, email, cb) { +var url = require("url") + +function adduser (base, username, password, email, cb) { + if (!base) return cb(new Error("Required base URI not supplied")) + + username = ("" + (username || "")).trim() + if (!username) return cb(new Error("No username supplied.")) password = ("" + (password || "")).trim() if (!password) return cb(new Error("No password supplied.")) @@ -48,11 +54,7 @@ function adduser (username, password, email, cb) { this.log.verbose("adduser", "before first PUT", logObj) - var uri = this.request.toRegistryURL( - this.conf.get('registry'), - '/-/user/org.couchdb.user:' + encodeURIComponent(username) - ) - + var uri = url.resolve(base, '/-/user/org.couchdb.user:' + encodeURIComponent(username)) this.request('PUT' , uri , { body : userobj } diff --git a/lib/deprecate.js b/lib/deprecate.js index d930523..4f2ebfe 100644 --- a/lib/deprecate.js +++ b/lib/deprecate.js @@ -1,9 +1,9 @@ - module.exports = deprecate +var url = require("url") var semver = require("semver") -function deprecate (name, ver, message, cb) { +function deprecate (uri, ver, message, cb) { if (!this.conf.get('username')) { return cb(new Error("Must be logged in to deprecate a package")) } @@ -12,7 +12,7 @@ function deprecate (name, ver, message, cb) { return cb(new Error("invalid version range: "+ver)) } - this.get(name + '?write=true', function (er, data) { + this.get(uri + '?write=true', function (er, data) { if (er) return cb(er) // filter all the versions that match Object.keys(data.versions).filter(function (v) { @@ -21,10 +21,6 @@ function deprecate (name, ver, message, cb) { data.versions[v].deprecated = message }) // now update the doc on the registry - var fixed = this.request.toRegistryURL( - this.conf.get('registry'), - data._id - ) - this.request('PUT', fixed, { body : data }, cb) + this.request('PUT', url.resolve(uri, data._id), { body : data }, cb) }.bind(this)) } diff --git a/lib/get.js b/lib/get.js index 7ba3e17..00718e7 100644 --- a/lib/get.js +++ b/lib/get.js @@ -5,6 +5,7 @@ var fs = require("graceful-fs") , path = require("path") , mkdir = require("mkdirp") , chownr = require("chownr") + , url = require("url") function get (uri, timeout, nofollow, staleOk, cb) { if (typeof cb !== "function") cb = staleOk, staleOk = false @@ -14,19 +15,17 @@ function get (uri, timeout, nofollow, staleOk, cb) { timeout = Math.min(timeout, this.conf.get('cache-max') || 0) timeout = Math.max(timeout, this.conf.get('cache-min') || -Infinity) - if (!this.conf.get('registry')) timeout = Infinity - if ( process.env.COMP_CWORD !== undefined && process.env.COMP_LINE !== undefined && process.env.COMP_POINT !== undefined ) timeout = Math.max(timeout, 60000) - var cache = this.cacheFile(this.registry + uri) + "/.cache.json" + var cache = this.cacheFile(uri) + "/.cache.json" // /-/all is special. // It uses timestamp-based caching and partial updates, // because it is a monster. - if (uri === "/-/all") { + if (url.parse(uri).pathname === "/-/all") { return requestAll.call(this, cache, cb) } @@ -113,12 +112,7 @@ function get_ (uri, timeout, cache, stat, data, nofollow, staleOk, cb) { } } - var fixed = this.request.toRegistryURL( - this.conf.get('registry'), - uri - ) - - this.request('GET', fixed, { etag : etag, follow : !nofollow }, function (er, remoteData, raw, response) { + this.request('GET', uri, { etag : etag, follow : !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) { diff --git a/lib/publish.js b/lib/publish.js index a5de9fa..5504658 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -6,7 +6,7 @@ var url = require("url") , crypto = require("crypto") , fs = require("fs") -function publish (data, tarball, cb) { +function publish (uri, data, tarball, cb) { var email = this.conf.get('email') var auth = this.conf.get('_auth') var username = this.conf.get('username') @@ -30,12 +30,12 @@ function publish (data, tarball, cb) { if (er) return cb(er) fs.readFile(tarball, function(er, tarbuffer) { if (er) return cb(er) - putFirst.call(self, data, tarbuffer, s, username, email, cb) + putFirst.call(self, uri, data, tarbuffer, s, username, email, cb) }) }) } -function putFirst (data, tarbuffer, stat, username, email, cb) { +function putFirst (registry, data, tarbuffer, stat, username, email, cb) { // optimistically try to PUT all in one single atomic thing. // If 409, then GET and merge, try again. // If other error, then fail. @@ -59,7 +59,6 @@ function putFirst (data, tarbuffer, stat, username, email, cb) { var tag = data.tag || this.conf.get('tag') || "latest" root["dist-tags"][tag] = data.version - var registry = this.conf.get("registry") var tbName = data.name + "-" + data.version + ".tgz" , tbURI = data.name + "/-/" + tbName @@ -76,11 +75,7 @@ function putFirst (data, tarbuffer, stat, username, email, cb) { length: stat.size }; - var fixed = this.request.toRegistryURL( - this.conf.get('registry'), - data.name - ) - + var fixed = url.resolve(registry, data.name) this.request("PUT", fixed, { body : root }, function (er, parsed, json, res) { var r409 = "must supply latest _rev to update existing package" var r409b = "Document update conflict." @@ -99,20 +94,16 @@ function putFirst (data, tarbuffer, stat, username, email, cb) { return cb(er, parsed, json, res) // let's see what versions are already published. - var getUrl = this.request.toRegistryURL( - this.conf.get('registry'), - data.name + "?write=true" - ) - + var getUrl = url.resolve(registry, data.name + "?write=true") this.request("GET", getUrl, null, function (er, current) { if (er) return cb(er) - putNext.call(this, data.version, root, current, cb) + putNext.call(this, registry, data.version, root, current, cb) }.bind(this)) }.bind(this)) } -function putNext(newVersion, root, current, cb) { +function putNext(registry, newVersion, root, current, cb) { // already have the tardata on the root object // just merge in existing stuff var curVers = Object.keys(current.versions || {}).map(function (v) { @@ -152,11 +143,7 @@ function putNext(newVersion, root, current, cb) { var maint = JSON.parse(JSON.stringify(root.maintainers)) root.versions[newVersion].maintainers = maint - var putUrl = this.request.toRegistryURL( - this.conf.get('registry'), - root.name - ) - this.request("PUT", putUrl, { body : current }, cb) + this.request("PUT", url.resolve(registry, root.name), { body : current }, cb) } function conflictError (pkgid, version) { diff --git a/lib/star.js b/lib/star.js index 0413103..c0590f1 100644 --- a/lib/star.js +++ b/lib/star.js @@ -1,15 +1,11 @@ module.exports = star -function star (package, starred, cb) { +function star (uri, starred, cb) { if (!this.conf.get('username')) return cb(new Error( "Must be logged in to star/unstar packages")) - var fixed = this.request.toRegistryURL( - this.conf.get('registry'), - package + '?write=true' - ) - this.request("GET", fixed, null, function (er, fullData) { + this.request("GET", uri+"?write=true", null, function (er, fullData) { if (er) return cb(er) fullData = { _id: fullData._id @@ -26,10 +22,6 @@ function star (package, starred, cb) { this.log.verbose("unstarring", fullData) } - var fixed = this.request.toRegistryURL( - this.conf.get('registry'), - package - ) - return this.request("PUT", fixed, { body : fullData }, cb) + return this.request("PUT", uri, { body : fullData }, cb) }.bind(this)) } diff --git a/lib/tag.js b/lib/tag.js index 1b47015..65430fe 100644 --- a/lib/tag.js +++ b/lib/tag.js @@ -1,10 +1,5 @@ - module.exports = tag -function tag (project, version, tagName, cb) { - var fixed = this.request.toRegistryURL( - this.conf.get('registry'), - project + "/" + tagName - ) - this.request("PUT", fixed, { body : JSON.stringify(version) }, cb) +function tag (uri, version, tagName, cb) { + this.request("PUT", uri+"/"+tagName, { body : JSON.stringify(version) }, cb) } diff --git a/lib/unpublish.js b/lib/unpublish.js index 912259a..cf94207 100644 --- a/lib/unpublish.js +++ b/lib/unpublish.js @@ -11,19 +11,18 @@ var semver = require("semver") , url = require("url") , chain = require("slide").chain -function unpublish (name, ver, cb) { +function unpublish (uri, ver, cb) { if (typeof cb !== "function") cb = ver, ver = null - var u = name + '?write=true' - this.get(u, null, -1, true, function (er, data) { + this.get(uri + "?write=true", null, -1, true, function (er, data) { if (er) { - this.log.info("unpublish", name+" not published") + this.log.info("unpublish", uri+" not published") return cb() } // remove all if no version specified if (!ver) { this.log.info("unpublish", "No version specified, removing all") - return this.request("DELETE", this.conf.get("registry"), name+'/-rev/'+data._rev, cb) + return this.request("DELETE", uri+'/-rev/'+data._rev, cb) } var versions = data.versions || {} @@ -31,7 +30,7 @@ function unpublish (name, ver, cb) { var dist if (!versionPublic) { - this.log.info("unpublish", name+"@"+ver+" not published") + this.log.info("unpublish", uri+"@"+ver+" not published") } else { dist = versions[ver].dist this.log.verbose("unpublish", "removing attachments", dist) @@ -39,15 +38,9 @@ function unpublish (name, ver, cb) { delete versions[ver] // if it was the only version, then delete the whole package. - var fixed if (!Object.keys(versions).length) { this.log.info("unpublish", "No versions remain, removing entire package") - fixed = this.request.toRegistryURL( - this.conf.get('registry'), - name + "/-rev/" + data._rev - ) - - return this.request("DELETE", fixed, null, cb) + return this.request("DELETE", uri + "/-rev/" + data._rev, null, cb) } if (!versionPublic) return cb() @@ -65,13 +58,9 @@ function unpublish (name, ver, cb) { var rev = data._rev delete data._revisions delete data._attachments - var cb_ = detacher.call(this, data, dist, cb) - fixed = this.request.toRegistryURL( - this.conf.get('registry'), - name + "/-rev/" + rev - ) + var cb_ = detacher.call(this, uri, data, dist, cb) - this.request("PUT", fixed, { body : data }, function (er) { + this.request("PUT", uri + "/-rev/" + rev, { body : data }, function (er) { if (er) { this.log.error("unpublish", "Failed to update data") } @@ -80,20 +69,20 @@ function unpublish (name, ver, cb) { }.bind(this)) } -function detacher (data, dist, cb) { +function detacher (uri, data, dist, cb) { return function (er) { if (er) return cb(er) - this.get(data.name, function (er, data) { + this.get(url.resolve(uri, data.name), function (er, data) { if (er) return cb(er) var tb = url.parse(dist.tarball) - detach.call(this, data, tb.pathname, data._rev, function (er) { + detach.call(this, uri, 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.call(this, data, url.parse(d.tarball).pathname, null, cb) + detach.call(this, uri, data, url.parse(d.tarball).pathname, null, cb) }.bind(this) }, this), cb) }.bind(this)) @@ -101,14 +90,13 @@ function detacher (data, dist, cb) { }.bind(this) } -function detach (data, path, rev, cb) { +function detach (uri, data, path, rev, cb) { if (rev) { path += "/-rev/" + rev this.log.info("detach", path) - var fixed = this.request.toRegistryURL(this.conf.get('registry'), path) - return this.request("DELETE", fixed, null, cb) + return this.request("DELETE", url.resolve(uri, path), null, cb) } - this.get(data.name, function (er, data) { + this.get(url.resolve(uri, data.name), function (er, data) { rev = data._rev if (!rev) return cb(new Error( "No _rev found in "+data._id)) diff --git a/lib/upload.js b/lib/upload.js index 4a18ec8..f624a26 100644 --- a/lib/upload.js +++ b/lib/upload.js @@ -3,17 +3,12 @@ module.exports = upload var fs = require('fs') , Stream = require("stream").Stream -function upload (where, file, etag, nofollow, cb) { +function upload (uri, file, etag, nofollow, cb) { if (typeof nofollow === "function") cb = nofollow, nofollow = false if (typeof etag === "function") cb = etag, etag = null - var fixed = this.request.toRegistryURL( - this.conf.get('registry'), - where - ) - if (file instanceof Stream) { - return this.request("PUT", fixed, { body : file, etag : etag, follow : !nofollow }, cb) + return this.request("PUT", uri, { body : file, etag : etag, follow : !nofollow }, cb) } fs.stat(file, function (er, stat) { @@ -22,6 +17,6 @@ function upload (where, file, etag, nofollow, cb) { s.size = stat.size s.on("error", cb) - this.request("PUT", fixed, { body : s, etag : etag, follow : !nofollow }, cb) + this.request("PUT", uri, { body : s, etag : etag, follow : !nofollow }, cb) }.bind(this)) } diff --git a/test/adduser-new.js b/test/adduser-new.js index 6e253ea..6cedf94 100644 --- a/test/adduser-new.js +++ b/test/adduser-new.js @@ -4,15 +4,16 @@ var server = require("./lib/server.js") var common = require("./lib/common.js") var client = common.freshClient() -var userdata = -{ name: "username", - email: "i@izs.me", +var password = "password" +, username = "username" +, email = "i@izs.me" +, userdata = { + name: username, + email: email, _id: "org.couchdb.user:username", type: "user", roles: [], date: "2012-06-07T04:11:21.591Z" } -, password = "password" -, username = "username" , SD = require("string_decoder").StringDecoder , decoder = new SD() @@ -35,7 +36,7 @@ tap.test("create new user account", function (t) { }) }) - client.adduser(username, password, "i@izs.me", function (er, data) { + client.adduser("http://localhost:1337/", username, password, email, function (er, data) { if (er) throw er t.deepEqual(data, { created: true }) t.end() diff --git a/test/adduser-update.js b/test/adduser-update.js index a645092..551c984 100644 --- a/test/adduser-update.js +++ b/test/adduser-update.js @@ -4,17 +4,16 @@ var server = require("./lib/server.js") var common = require("./lib/common.js") var client = common.freshClient() -var userdata = -{ name: "username", - email: "i@izs.me", +var password = "password" +, username = "username" +, email = "i@izs.me" +, userdata = { + name: username, + email: email, _id: "org.couchdb.user:username", type: "user", roles: [], - _rev: "1-15aac515ac515aac515aac515aac5125" -} - -, password = "password" -, username = "username" + date: "2012-06-07T04:11:21.591Z" } , SD = require("string_decoder").StringDecoder , decoder = new SD() @@ -50,7 +49,7 @@ tap.test("update a user acct", function (t) { }) }) - client.adduser(username, password, "i@izs.me", function (er, data) { + client.adduser("http://localhost:1337/", username, password, email, function (er, data) { if (er) throw er t.deepEqual(data, { created: true }) t.end() diff --git a/test/bugs.js b/test/bugs.js index 053c4de..092ec9f 100644 --- a/test/bugs.js +++ b/test/bugs.js @@ -30,3 +30,4 @@ tap.test("get the URL for the bugs page on a package", function (t) { t.end() }) }) + diff --git a/test/deprecate.js b/test/deprecate.js index 252a0bb..52c21b2 100644 --- a/test/deprecate.js +++ b/test/deprecate.js @@ -12,8 +12,8 @@ var client = common.freshClient({ var cache = require("./fixtures/underscore/cache.json") -var DEP_VERSION = "1.3.2" -var DEP_MESSAGE = "uhhh" +var VERSION = "1.3.2" +var MESSAGE = "uhhh" tap.test("deprecate a package", function (t) { server.expect("GET", "/underscore?write=true", function (req, res) { @@ -42,22 +42,22 @@ tap.test("deprecate a package", function (t) { var current = undeprecated[i] t.notEqual( updated.versions[current].deprecated, - DEP_MESSAGE, + MESSAGE, current + " not deprecated" ) } t.equal( - updated.versions[DEP_VERSION].deprecated, - DEP_MESSAGE, - DEP_VERSION + " deprecated" + updated.versions[VERSION].deprecated, + MESSAGE, + VERSION + " deprecated" ) res.statusCode = 201 res.json({deprecated:true}) }) }) - client.deprecate("underscore", DEP_VERSION, DEP_MESSAGE, function (error, data) { + client.deprecate("http://localhost:1337/underscore", VERSION, MESSAGE, function (error, data) { t.notOk(error, "no errors") t.ok(data.deprecated, "was deprecated") diff --git a/test/get-basic.js b/test/get-basic.js index 20ebb96..e600af2 100644 --- a/test/get-basic.js +++ b/test/get-basic.js @@ -17,11 +17,11 @@ tap.test("basic request", function (t) { }) t.plan(2) - client.get("/underscore/1.3.3", function (er, data) { + client.get("http://localhost:1337/underscore/1.3.3", function (er, data) { t.deepEqual(data, us) }) - client.get("/underscore", function (er, data) { + client.get("http://localhost:1337/underscore", function (er, data) { t.deepEqual(data, usroot) }) }) diff --git a/test/lib/common.js b/test/lib/common.js index cd141ea..f9048c0 100644 --- a/test/lib/common.js +++ b/test/lib/common.js @@ -5,12 +5,12 @@ var RC = require('../../') module.exports = { freshClient : function freshClient(config) { config = config || {} - config.cache = resolve(__dirname, '..', '/fixtures/cache') + config.cache = resolve(__dirname, '../fixtures/cache') config.registry = 'http://localhost:' + server.port var client = new RC(config) server.log = client.log - client.log.level = 'error' + client.log.level = 'silent' return client } diff --git a/test/publish-again.js b/test/publish-again.js index 63c3623..af59980 100644 --- a/test/publish-again.js +++ b/test/publish-again.js @@ -71,7 +71,7 @@ tap.test("publish again", function (t) { var tarball = require.resolve("../package.json") var pd = fs.readFileSync(tarball, "base64") var pkg = require("../package.json") - client.publish(pkg, tarball, function (er, data) { + client.publish("http://localhost:1337/", pkg, tarball, function (er, data) { if (er) throw er t.deepEqual(data, { created: true }) t.end() diff --git a/test/publish.js b/test/publish.js index ea7210b..a623390 100644 --- a/test/publish.js +++ b/test/publish.js @@ -42,7 +42,7 @@ tap.test("publish", function (t) { var tarball = require.resolve("../package.json") var pd = fs.readFileSync(tarball, "base64") var pkg = require("../package.json") - client.publish(pkg, tarball, function (er, data) { + client.publish("http://localhost:1337/", pkg, tarball, function (er, data) { if (er) throw er t.deepEqual(data, { created: true }) t.end() diff --git a/test/request-gzip-content.js b/test/request-gzip-content.js index 8019d11..cd50d76 100644 --- a/test/request-gzip-content.js +++ b/test/request-gzip-content.js @@ -24,7 +24,7 @@ zlib.gzip(JSON.stringify(pkg), function (err, pkgGzip) { res.end(pkgGzip) }) - client.get("/some-package-gzip/1.2.3", function (er, data) { + client.get("http://localhost:1337/some-package-gzip/1.2.3", function (er, data) { if (er) throw er t.deepEqual(data, pkg) t.end() @@ -39,7 +39,7 @@ zlib.gzip(JSON.stringify(pkg), function (err, pkgGzip) { res.end(new Buffer("wrong gzip content")) }) - client.get("/some-package-gzip-error/1.2.3", function (er) { + client.get("http://localhost:1337/some-package-gzip-error/1.2.3", function (er) { t.ok(er) t.end() }) diff --git a/test/retries.js b/test/retries.js index b479023..0bee1eb 100644 --- a/test/retries.js +++ b/test/retries.js @@ -41,7 +41,7 @@ tap.test("create new user account", function (t) { res.json(pkg) }) - client.get("/some-package/1.2.3", function (er, data) { + client.get("http://localhost:1337/some-package/1.2.3", function (er, data) { if (er) throw er t.deepEqual(data, pkg) t.end() diff --git a/test/star.js b/test/star.js index 6d2dd99..3e140aa 100644 --- a/test/star.js +++ b/test/star.js @@ -51,7 +51,7 @@ tap.test("star a package", function (t) { }) }) - client.star("underscore", true, function (error, data) { + client.star("http://localhost:1337/underscore", true, function (error, data) { t.notOk(error, "no errors") t.ok(data.starred, "was starred") diff --git a/test/tag.js b/test/tag.js index c8e3cb7..b8b8e19 100644 --- a/test/tag.js +++ b/test/tag.js @@ -30,7 +30,7 @@ tap.test("tag a package", function (t) { }) }) - client.tag("underscore", {"1.3.2":{}}, "not-lodash", function (error, data) { + client.tag("http://localhost:1337/underscore", {"1.3.2":{}}, "not-lodash", function (error, data) { t.notOk(error, "no errors") t.ok(data.tagged, "was tagged") diff --git a/test/unpublish.js b/test/unpublish.js index 5eda77b..e8a2093 100644 --- a/test/unpublish.js +++ b/test/unpublish.js @@ -51,7 +51,7 @@ tap.test("unpublish a package", function (t) { res.json({unpublished:true}) }) - client.unpublish("underscore", VERSION, function (error) { + client.unpublish("http://localhost:1337/underscore", VERSION, function (error) { t.notOk(error, "no errors") t.end() diff --git a/test/upload.js b/test/upload.js index 79ceb06..8884db8 100644 --- a/test/upload.js +++ b/test/upload.js @@ -1,23 +1,23 @@ var tap = require("tap") -var Readable = require('stream').Readable -var inherits = require('util').inherits +var Readable = require("stream").Readable +var inherits = require("util").inherits var common = require("./lib/common.js") var server = require("./lib/server.js") -var cache = require('./fixtures/underscore/cache.json') +var cache = require("./fixtures/underscore/cache.json") var client = common.freshClient({ username : "othiym23", password : "password", email : "ogd@aoaioxxysz.net", - _auth : new Buffer("username : password").toString('base64'), + _auth : new Buffer("username : password").toString("base64"), "always-auth" : true }) function OneA() { Readable.call(this) - this.push('A') + this.push("A") this.push(null) } inherits(OneA, Readable) @@ -29,7 +29,7 @@ tap.test("unpublish a package", function (t) { res.json(cache) }) - client.upload("underscore", new OneA(), "daedabeefa", true, function (error) { + client.upload("http://localhost:1337/underscore", new OneA(), "daedabeefa", true, function (error) { t.notOk(error, "no errors") t.end()