1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
// utilities for working with the js-registry site.
exports.publish = publish;
exports.tag = tag;
exports.adduser = adduser;
var npm = require("../../npm"),
http = require("http"),
url = require("url"),
log = require("./log"),
uuid = require("./uuid"),
sha = require("./sha"),
sys = require("sys"),
ini = require("./ini");
function tag (project, version, tag, cb) { PUT(project+"/"+tag, version, cb) }
function publish (data, tarball, cb) {
// 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}
try {
reg();
} catch (ex) {
return cb(ex);
}
var fullData =
{ "_id" : data.name
, "name" : data.name
, "description" : data.description
, "dist-tags" : {}
, "versions" : {}
};
fullData.versions[ data.version ] = data;
data._id = data.name+"-"+data.version;
data.dist = { "tarball" : tarball };
// 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(data.name, fullData, function (er) {
if (!er) return cb();
// there was an error, so assume the fullData is already there.
// now try to create just this version. This time, failure
// is not ok.
// Note: the first might've failed for a down host or something,
// in which case this will likely fail, too. If the host was down for the
// first req, but now it's up, then this may fail for not having the
// project created yet, or because the user doesn't have access to it.
PUT(data.name+"/"+data.version, data, function (er) {
if (er) return cb(er);
cb();
});
});
}
function PUT (where, what, cb) {
reg();
what = JSON.stringify(what);
log(where, "registryPUT");
where = ini.config.registry + where;
var u = url.parse(where),
headers = { "content-type" : "application/json"
, "host" : u.host
, "content-length" : what.length
};
if (ini.config.auth) {
headers.authorization = 'Basic ' + ini.config.auth;
}
var client = http.createClient(u.port || (u.protocol === "https:" ? 443 : 80), u.hostname);
var request = client.request("PUT", u.pathname, headers);
log(sys.inspect(headers), "registryPUT headers");
request.addListener("response", function (response) {
// if (response.statusCode !== 200) return cb(new Error(
// "Status code " + response.statusCode + " from PUT "+where));
var data = "";
response.setBodyEncoding("utf8");
response.addListener("data", function (chunk) { data += chunk });
response.addListener("end", function () {
log(data, "registryPUT");
try {
data = JSON.parse(data);
} catch (ex) {
ex.message += "\n" + data;
return cb(ex, data, response);
}
if (data.error) return cb(new Error(
data.error + (" "+data.reason || "")));
cb(null, data, response);
});
});
request.write(what, "utf8");
request.close();
}
function reg () {
if (!ini.config.registry) throw new Error(
"Must define registry before publishing.");
log(ini.config.registry, "registry");
if (ini.config.registry.substr(-1) !== "/") {
ini.config.registry += "/";
}
}
function adduser (username, password, email, callback) {
var salt = uuid.generate()
var userobj =
{ '_id' : 'org.couchdb.user:'+username
, name : username
, type : "user"
, roles : []
, salt : salt
, password_sha : sha.hex_sha1(password + salt)
, email : email
};
PUT('/adduser/org.couchdb.user:'+username, userobj, function (error, data, response) {
// if the error is a 409, then update the rev.
if (error || response.statusCode !== 201) {
callback(new Error(
"Could not create user "+error+'\n'+data));
} else {
callback();
}
});
}
|