aboutsummaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/npm-registry-client/lib/publish.js
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2013-12-16 16:23:13 -0800
committerisaacs <i@izs.me>2013-12-16 23:09:16 -0800
commit97738994e0bc2f3255659ca8f27e43a90aa0a24e (patch)
tree51bc3a3a928ddcba4944b8294656158d120d3d75 /deps/npm/node_modules/npm-registry-client/lib/publish.js
parent39e2426b209799d5deaa29d2401dd98f060babda (diff)
downloadandroid-node-v8-97738994e0bc2f3255659ca8f27e43a90aa0a24e.tar.gz
android-node-v8-97738994e0bc2f3255659ca8f27e43a90aa0a24e.tar.bz2
android-node-v8-97738994e0bc2f3255659ca8f27e43a90aa0a24e.zip
npm: Upgrade to 1.3.19
Diffstat (limited to 'deps/npm/node_modules/npm-registry-client/lib/publish.js')
-rw-r--r--deps/npm/node_modules/npm-registry-client/lib/publish.js153
1 files changed, 94 insertions, 59 deletions
diff --git a/deps/npm/node_modules/npm-registry-client/lib/publish.js b/deps/npm/node_modules/npm-registry-client/lib/publish.js
index d6a7496f1f..9404a129db 100644
--- a/deps/npm/node_modules/npm-registry-client/lib/publish.js
+++ b/deps/npm/node_modules/npm-registry-client/lib/publish.js
@@ -3,9 +3,11 @@ module.exports = publish
var path = require("path")
, url = require("url")
+ , semver = require("semver")
+ , crypto = require("crypto")
+ , fs = require("fs")
function publish (data, tarball, cb) {
-
var email = this.conf.get('email')
var auth = this.conf.get('_auth')
var username = this.conf.get('username')
@@ -16,14 +18,30 @@ function publish (data, tarball, cb) {
return cb(er)
}
- // 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 = this.conf.get('registry')
+ if (data.name !== encodeURIComponent(data.name).toLowerCase())
+ return cb(new Error('invalid name: must be lowercase and url-safe'))
+
+ var ver = semver.clean(data.version)
+ if (!ver)
+ return cb(new Error('invalid semver: ' + data.version))
+ data.version = ver
+
+ var self = this
+ fs.stat(tarball, function(er, s) {
+ if (er) return cb(er)
+ fs.readFile(tarball, 'base64', function(er, tardata) {
+ if (er) return cb(er)
+ putFirst.call(self, data, tardata, s, username, email, cb)
+ })
+ })
+}
- var fullData =
+function putFirst (data, tardata, 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.
+
+ var root =
{ _id : data.name
, name : data.name
, description : data.description
@@ -37,76 +55,93 @@ function publish (data, tarball, cb) {
]
}
+ root.versions[ data.version ] = data
+ 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
data._id = data.name+"@"+data.version
data.dist = data.dist || {}
+ data.dist.shasum = crypto.createHash("sha1").update(tardata).digest("hex")
data.dist.tarball = url.resolve(registry, tbURI)
.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.
- this.request("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" )) {
- this.log.error("publish", "Failed PUT response "
- +(response && response.statusCode))
+ root._attachments = {}
+ root._attachments[ tbName ] = {
+ content_type: 'application/octet-stream',
+ data: tardata,
+ length: stat.size
+ };
+
+ this.request("PUT", data.name, root, function (er, parsed, json, res) {
+ var r409 = "must supply latest _rev to update existing package"
+ var r409b = "Document update conflict."
+ var conflict = res && res.statusCode === 409
+ if (parsed && (parsed.reason === r409 || parsed.reason === r409b))
+ conflict = true
+
+ // a 409 is typical here. GET the data and merge in.
+ if (er && !conflict) {
+ this.log.error("publish", "Failed PUT "
+ +(res && res.statusCode))
return cb(er)
}
- var dataURI = encodeURIComponent(data.name)
- + "/" + encodeURIComponent(data.version)
- var tag = data.tag || this.conf.get('tag') || "latest"
- dataURI += "/-tag/" + tag
+ if (!er && !conflict)
+ return cb(er, parsed, json, res)
// let's see what versions are already published.
- // could be that we just need to update the bin dist values.
- this.request("GET", data.name, function (er, fullData) {
- if (er) return cb(er)
-
- function handle(er) {
- if (er.message.indexOf("conflict Document update conflict.") === 0) {
- return cb(conflictError.call(this, data._id));
- }
- this.log.error("publish", "Error uploading package");
+ this.request("GET", data.name, function (er, current) {
+ if (er)
return cb(er)
- }
-
- var exists = fullData.versions && fullData.versions[data.version]
- if (exists) return cb(conflictError.call(this, data._id))
-
- var rev = fullData._rev;
- attach.call(this, data.name, tarball, tbName, rev, function (er) {
- if (er) return handle.call(this, er)
- this.log.verbose("publish", "attached", [data.name, tarball, tbName])
- this.request("PUT", dataURI, data, function (er) {
- if (er) return handle.call(this, er)
- return cb(er)
- }.bind(this))
- }.bind(this))
+ putNext.call(this, data.version, root, current, cb)
}.bind(this))
- }.bind(this)) // pining for fat arrows.
+ }.bind(this))
+}
+
+function putNext(newVersion, root, current, cb) {
+ // already have the tardata on the root object
+ // just merge in existing stuff
+ // if the version already exists, and not a --force, then raise error
+ var force = this.conf.get('force')
+ var curVers = Object.keys(current.versions || {}).map(function (v) {
+ return semver.clean(v, true)
+ })
+
+ if (!force && curVers.indexOf(newVersion) !== -1) {
+ return cb(conflictError(root.name))
+ }
+
+ current.versions[newVersion] = root.versions[newVersion]
+ for (var i in root) {
+ switch (i) {
+ // objects that copy over the new stuffs
+ case 'dist-tags':
+ case 'versions':
+ case '_attachments':
+ for (var j in root[i])
+ current[i][j] = root[i][j]
+ break
+
+ // ignore these
+ case 'maintainers':
+ break;
+
+ // copy
+ default:
+ current[i] = root[i]
+ }
+ }
+
+ this.request("PUT", root.name, current, cb)
}
function conflictError (pkgid) {
- var e = new Error("publish fail")
+ var e = new Error("cannot modify existing version")
e.code = "EPUBLISHCONFLICT"
e.pkgid = pkgid
return e
}
-
-function attach (doc, file, filename, rev, cb) {
- doc = encodeURIComponent(doc)
- var revu = "-rev/"+rev
- , attURI = doc + "/-/" + encodeURIComponent(filename) + "/" + revu
- this.log.verbose("uploading", [attURI, file])
- this.upload(attURI, file, cb)
-}