2 module.exports = publish
4 var path = require("path")
7 function publish (data, tarball, cb) {
9 var email = this.conf.get('email')
10 var auth = this.conf.get('_auth')
11 var username = this.conf.get('username')
13 if (!email || !auth || !username) {
14 var er = new Error("auth and email required for publishing")
19 // add the dist-url to the data, pointing at the tarball.
20 // if the {name} isn't there, then create it.
21 // if the {version} is already there, then fail.
23 // PUT the data to {config.registry}/{data.name}/{data.version}
24 var registry = this.conf.get('registry')
29 , description : data.description
32 , readme: data.readme || ""
40 var tbName = data.name + "-" + data.version + ".tgz"
41 , tbURI = data.name + "/-/" + tbName
43 data._id = data.name+"@"+data.version
44 data.dist = data.dist || {}
45 data.dist.tarball = url.resolve(registry, tbURI)
46 .replace(/^https:\/\//, "http://")
49 // first try to just PUT the whole fullData, and this will fail if it's
50 // already there, because it'll be lacking a _rev, so couch'll bounce it.
51 this.request("PUT", encodeURIComponent(data.name), fullData,
52 function (er, parsed, json, response) {
53 // get the rev and then upload the attachment
54 // a 409 is expected here, if this is a new version of an existing package.
56 && !(response && response.statusCode === 409)
59 "must supply latest _rev to update existing package" )) {
60 this.log.error("publish", "Failed PUT response "
61 +(response && response.statusCode))
64 var dataURI = encodeURIComponent(data.name)
65 + "/" + encodeURIComponent(data.version)
67 var tag = data.tag || this.conf.get('tag') || "latest"
68 dataURI += "/-tag/" + tag
70 // let's see what versions are already published.
71 // could be that we just need to update the bin dist values.
72 this.request("GET", data.name, function (er, fullData) {
76 if (er.message.indexOf("conflict Document update conflict.") === 0) {
77 return cb(conflictError.call(this, data._id));
79 this.log.error("publish", "Error uploading package");
83 var exists = fullData.versions && fullData.versions[data.version]
84 if (exists) return cb(conflictError.call(this, data._id))
86 var rev = fullData._rev;
87 attach.call(this, data.name, tarball, tbName, rev, function (er) {
88 if (er) return handle.call(this, er)
89 this.log.verbose("publish", "attached", [data.name, tarball, tbName])
90 this.request("PUT", dataURI, data, function (er) {
91 if (er) return handle.call(this, er)
96 }.bind(this)) // pining for fat arrows.
99 function conflictError (pkgid) {
100 var e = new Error("publish fail")
101 e.code = "EPUBLISHCONFLICT"
106 function attach (doc, file, filename, rev, cb) {
107 doc = encodeURIComponent(doc)
108 var revu = "-rev/"+rev
109 , attURI = doc + "/-/" + encodeURIComponent(filename) + "/" + revu
110 this.log.verbose("uploading", [attURI, file])
111 this.upload(attURI, file, cb)