mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-16 21:56:25 -05:00
a lot of work done...
This commit is contained in:
parent
26e3e21121
commit
5aa335cd91
5 changed files with 126 additions and 6 deletions
|
@ -15,7 +15,7 @@ function make_directories(dest, cb) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function write_file(dest, data, cb) {
|
function write(dest, data, cb) {
|
||||||
var safe_write = function(cb) {
|
var safe_write = function(cb) {
|
||||||
fs.writeFile(dest, data, cb);
|
fs.writeFile(dest, data, cb);
|
||||||
}
|
}
|
||||||
|
@ -34,14 +34,14 @@ function write_file(dest, data, cb) {
|
||||||
function create(name, contents, callback) {
|
function create(name, contents, callback) {
|
||||||
fs.exists(name, function(exists) {
|
fs.exists(name, function(exists) {
|
||||||
if (exists) return callback(new Error({code: 'EEXISTS'}));
|
if (exists) return callback(new Error({code: 'EEXISTS'}));
|
||||||
write_file(name, contents, callback);
|
write(name, contents, callback);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function update(name, contents, callback) {
|
function update(name, contents, callback) {
|
||||||
fs.exists(name, function(exists) {
|
fs.exists(name, function(exists) {
|
||||||
if (!exists) return callback(new Error({code: 'ENOENT'}));
|
if (!exists) return callback(new Error({code: 'ENOENT'}));
|
||||||
write_file(name, contents, callback);
|
write(name, contents, callback);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,5 +86,13 @@ Storage.prototype.update_json = function(name, value, cb) {
|
||||||
update(this.path + '/' + name, JSON.stringify(value), cb);
|
update(this.path + '/' + name, JSON.stringify(value), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Storage.prototype.write = function(name, value, cb) {
|
||||||
|
write(this.path + '/' + name, value, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage.prototype.write_json = function(name, value, cb) {
|
||||||
|
write(this.path + '/' + name, JSON.stringify(value), cb);
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = Storage;
|
module.exports = Storage;
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ module.exports = function(config_hash) {
|
||||||
app.get('/:package/:version?', can('access'), function(req, res, next) {
|
app.get('/:package/:version?', can('access'), function(req, res, next) {
|
||||||
storage.get_package(req.params.package, function(err, info) {
|
storage.get_package(req.params.package, function(err, info) {
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
|
info = utils.filter_tarball_urls(info, req, config);
|
||||||
|
|
||||||
// XXX: in some cases npm calls for /:package and for some cases
|
// XXX: in some cases npm calls for /:package and for some cases
|
||||||
// for /:package/:version - should investigate that
|
// for /:package/:version - should investigate that
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
var semver = require('semver');
|
||||||
var fs_storage = require('./fs-storage');
|
var fs_storage = require('./fs-storage');
|
||||||
var UError = require('./error').UserError;
|
var UError = require('./error').UserError;
|
||||||
var info_file = 'package.json';
|
var info_file = 'package.json';
|
||||||
|
@ -10,8 +11,17 @@ function Storage(config) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns the minimal package file
|
||||||
|
function get_boilerplate(name) {
|
||||||
|
return {
|
||||||
|
name: name,
|
||||||
|
versions: {},
|
||||||
|
'dist-tags': {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Storage.prototype.add_package = function(name, metadata, callback) {
|
Storage.prototype.add_package = function(name, metadata, callback) {
|
||||||
this.storage.create_json(name + '/' + info_file, metadata, function(err) {
|
this.storage.create_json(name + '/' + info_file, get_boilerplace(name), function(err) {
|
||||||
if (err && err.code === 'EEXISTS') {
|
if (err && err.code === 'EEXISTS') {
|
||||||
return callback(new UError({
|
return callback(new UError({
|
||||||
status: 409,
|
status: 409,
|
||||||
|
@ -22,10 +32,59 @@ Storage.prototype.add_package = function(name, metadata, callback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Storage.prototype.add_version = function(name, version, metadata, tag, callback) {
|
Storage.prototype._read_create_package = function(name, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.storage.read_json(name + '/' + info_file, function(err, data) {
|
self.storage.read_json(name + '/' + info_file, function(err, data) {
|
||||||
// TODO: race condition
|
// TODO: race condition
|
||||||
|
if (err) {
|
||||||
|
if (err.code === 'ENOENT') {
|
||||||
|
// if package doesn't exist, we create it here
|
||||||
|
data = get_boilerplate(name);
|
||||||
|
} else {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback(null, data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// synchronize remote package info with the local one
|
||||||
|
// TODO: readfile called twice
|
||||||
|
Storage.prototype.update_versions = function(name, newdata, callback) {
|
||||||
|
var self = this;
|
||||||
|
self._read_create_package(name, function(err, data) {
|
||||||
|
if (err) return callback(err);
|
||||||
|
|
||||||
|
var change = false;
|
||||||
|
for (var ver in newdata.versions) {
|
||||||
|
if (data.versions[ver] == null) {
|
||||||
|
change = true;
|
||||||
|
data.versions[ver] = newdata.versions[ver];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var tag in newdata['dist-tags']) {
|
||||||
|
// if tag is updated to reference latter version, that's fine
|
||||||
|
var need_change =
|
||||||
|
(data['dist-tags'][tag] == null) ||
|
||||||
|
(!semver.gt(newdata['dist-tags'], data['dist-tags'][tag]));
|
||||||
|
|
||||||
|
if (need_change) {
|
||||||
|
change = true;
|
||||||
|
data['dist-tags'][tag] = newdata['dist-tags'][tag];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (change) {
|
||||||
|
self.storage.write_json(name + '/' + info_file, data, callback);
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage.prototype.add_version = function(name, version, metadata, tag, callback) {
|
||||||
|
var self = this;
|
||||||
|
self._read_create_package(name, function(err, data) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
|
|
||||||
if (data.versions[version] != null) {
|
if (data.versions[version] != null) {
|
||||||
|
|
|
@ -67,10 +67,27 @@ Storage.prototype.add_tarball = function(name, filename, stream, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Storage.prototype.get_tarball = function(name, filename, callback) {
|
Storage.prototype.get_tarball = function(name, filename, callback) {
|
||||||
this.local.get_tarball(name, filename, callback);
|
// if someone requesting tarball, it means that we should already have some
|
||||||
|
// information about it, so fetching package info is unnecessary
|
||||||
|
|
||||||
|
// trying local first
|
||||||
|
this.local.get_tarball(name, filename, function(err, results) {
|
||||||
|
if (err && err.status !== 404) return callback(err);
|
||||||
|
if (!err && results != null) return callback(err, results);
|
||||||
|
|
||||||
|
|
||||||
|
return callback(err, results);
|
||||||
|
/*TODO:// local reported 404
|
||||||
|
this.local.get_package(name, function(err, info) {
|
||||||
|
if (err) return callback(err);
|
||||||
|
|
||||||
|
|
||||||
|
});*/
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Storage.prototype.get_package = function(name, callback) {
|
Storage.prototype.get_package = function(name, callback) {
|
||||||
|
var self = this;
|
||||||
var uplinks = [this.local];
|
var uplinks = [this.local];
|
||||||
for (var i in this.uplinks) {
|
for (var i in this.uplinks) {
|
||||||
if (this.config.allow_proxy(name, i)) {
|
if (this.config.allow_proxy(name, i)) {
|
||||||
|
@ -124,6 +141,8 @@ Storage.prototype.get_package = function(name, callback) {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
callback(null, result);
|
callback(null, result);
|
||||||
|
|
||||||
|
self.local.update_versions(name, result, function(){});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
33
lib/utils.js
33
lib/utils.js
|
@ -1,4 +1,5 @@
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
|
var URL = require('url');
|
||||||
|
|
||||||
// from normalize-package-data/lib/fixer.js
|
// from normalize-package-data/lib/fixer.js
|
||||||
module.exports.validate_name = function(name) {
|
module.exports.validate_name = function(name) {
|
||||||
|
@ -35,3 +36,35 @@ module.exports.validate_metadata = function(object, name) {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports.filter_tarball_urls = function(pkg, req, config) {
|
||||||
|
function filter(_url) {
|
||||||
|
if (!req.headers.host) return _url;
|
||||||
|
|
||||||
|
var url = URL.parse(_url);
|
||||||
|
if (config.url_prefix != null) {
|
||||||
|
var result = config.url_prefix.replace(/\/$/, '');
|
||||||
|
} else {
|
||||||
|
var result = req.protocol + '://' + req.headers.host;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = url.path.replace(/^\//, '').split('/');
|
||||||
|
if (path.length >= 3 && path[path.length-2] === '-') {
|
||||||
|
result += '/' + path[path.length-3]; // package name
|
||||||
|
result += '/' + path[path.length-2]; // "-"
|
||||||
|
result += '/' + path[path.length-1]; // tarball name
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
// weird url, just return it
|
||||||
|
return _url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var ver in pkg.versions) {
|
||||||
|
if (pkg.versions[ver].dist != null
|
||||||
|
&& pkg.versions[ver].dist.tarball != null) {
|
||||||
|
pkg.versions[ver].dist.tarball = filter(pkg.versions[ver].dist.tarball);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pkg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue