mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-30 22:34:10 -05:00
working on storage...
This commit is contained in:
parent
f0f1f76286
commit
1c827ebbd0
7 changed files with 103 additions and 76 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
||||||
node_modules
|
node_modules
|
||||||
package.json
|
package.json
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
|
bin/storage
|
||||||
|
bin/config.yaml
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
var store = {};
|
|
||||||
|
|
||||||
function create(name, contents, callback) {
|
|
||||||
if (store[name] != null) {
|
|
||||||
return callback(new Error({code: 'EEXISTS'}));
|
|
||||||
}
|
|
||||||
store[name] = contents;
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
function update(name, contents, callback) {
|
|
||||||
if (store[name] == null) {
|
|
||||||
return callback(new Error({code: 'ENOENT'}));
|
|
||||||
}
|
|
||||||
store[name] = contents;
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
function read(name, callback) {
|
|
||||||
if (store[name] == null) {
|
|
||||||
return callback(new Error({code: 'ENOENT'}));
|
|
||||||
}
|
|
||||||
callback(null, store[name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.read_json = read;
|
|
||||||
module.exports.read = read;
|
|
||||||
module.exports.create_json = create;
|
|
||||||
module.exports.create = create;
|
|
||||||
module.exports.update_json = update;
|
|
||||||
module.exports.update = update;
|
|
||||||
|
|
|
@ -49,7 +49,42 @@ function read(name, callback) {
|
||||||
fs.readFile(name, callback);
|
fs.readFile(name, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.read = read;
|
function Storage(path) {
|
||||||
module.exports.create = create;
|
this.path = path;
|
||||||
module.exports.update = update;
|
try {
|
||||||
|
fs.mkdirSync(path);
|
||||||
|
console.log('created new packages directory: ', path);
|
||||||
|
} catch(err) {
|
||||||
|
if (err.code !== 'EEXIST') throw new Error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage.prototype.read = function(name, cb) {
|
||||||
|
read(this.path + '/' + name, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage.prototype.read_json = function(name, cb) {
|
||||||
|
read(this.path + '/' + name, function(err, res) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
cb(null, JSON.parse(res));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage.prototype.create = function(name, value, cb) {
|
||||||
|
create(this.path + '/' + name, value, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage.prototype.create_json = function(name, value, cb) {
|
||||||
|
create(this.path + '/' + name, JSON.stringify(value), cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage.prototype.update = function(name, value, cb) {
|
||||||
|
update(this.path + '/' + name, value, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage.prototype.update_json = function(name, value, cb) {
|
||||||
|
update(this.path + '/' + name, JSON.stringify(value), cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Storage;
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
var utils = require('./utils');
|
var utils = require('./utils');
|
||||||
|
var UError = require('./error').UserError;
|
||||||
|
|
||||||
module.exports.validate_name = function validate_name(req, res, next, value, name) {
|
module.exports.validate_name = function validate_name(req, res, next, value, name) {
|
||||||
if (utils.validate_name(req.params.package)) {
|
if (utils.validate_name(req.params.package)) {
|
||||||
req.params.package = String(req.params.package);
|
req.params.package = String(req.params.package);
|
||||||
next();
|
next();
|
||||||
} else {
|
} else {
|
||||||
next(new Error({
|
next(new UError({
|
||||||
status: 403,
|
status: 403,
|
||||||
msg: 'invalid package name',
|
msg: 'invalid package name',
|
||||||
}));
|
}));
|
||||||
|
@ -15,7 +16,7 @@ module.exports.validate_name = function validate_name(req, res, next, value, nam
|
||||||
module.exports.media = function media(expect) {
|
module.exports.media = function media(expect) {
|
||||||
return function(req, res, next) {
|
return function(req, res, next) {
|
||||||
if (req.headers['content-type'] !== expect) {
|
if (req.headers['content-type'] !== expect) {
|
||||||
next(new Error({
|
next(new UError({
|
||||||
status: 415,
|
status: 415,
|
||||||
msg: 'wrong content-type, we expect '+expect,
|
msg: 'wrong content-type, we expect '+expect,
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -1,46 +1,17 @@
|
||||||
var storage = wrap(require('./drivers/fs'));
|
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';
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
function wrap(driver) {
|
|
||||||
if (typeof(driver.create_json) !== 'function') {
|
|
||||||
driver.create_json = function(name, value, cb) {
|
|
||||||
driver.create(name, JSON.stringify(value), cb);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (typeof(driver.update_json) !== 'function') {
|
|
||||||
driver.update_json = function(name, value, cb) {
|
|
||||||
driver.update(name, JSON.stringify(value), cb);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (typeof(driver.read_json) !== 'function') {
|
|
||||||
driver.read_json = function(name, cb) {
|
|
||||||
driver.read(name, function(err, res) {
|
|
||||||
if (err) return cb(err);
|
|
||||||
cb(null, JSON.parse(res));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return driver;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Storage(config) {
|
function Storage(config) {
|
||||||
if (!(this instanceof Storage)) return new Storage(config);
|
if (!(this instanceof Storage)) return new Storage(config);
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
this.storage = new fs_storage(this.config.storage);
|
||||||
try {
|
|
||||||
fs.mkdirSync(config.storage);
|
|
||||||
console.log('created new packages directory: ', config.storage);
|
|
||||||
} catch(err) {
|
|
||||||
if (err.code !== 'EEXIST') throw new Error(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Storage.prototype.add_package = function(name, metadata, callback) {
|
Storage.prototype.add_package = function(name, metadata, callback) {
|
||||||
storage.create_json(name + '/' + info_file, metadata, function(err) {
|
this.storage.create_json(name + '/' + info_file, metadata, function(err) {
|
||||||
if (err && err.code === 'EEXISTS') {
|
if (err && err.code === 'EEXISTS') {
|
||||||
return callback(new UError({
|
return callback(new UError({
|
||||||
status: 409,
|
status: 409,
|
||||||
|
@ -52,7 +23,8 @@ Storage.prototype.add_package = function(name, metadata, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Storage.prototype.add_version = function(name, version, metadata, tag, callback) {
|
Storage.prototype.add_version = function(name, version, metadata, tag, callback) {
|
||||||
storage.read_json(name + '/' + info_file, function(err, data) {
|
var self = this;
|
||||||
|
self.storage.read_json(name + '/' + info_file, function(err, data) {
|
||||||
// TODO: race condition
|
// TODO: race condition
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
|
|
||||||
|
@ -64,11 +36,12 @@ Storage.prototype.add_version = function(name, version, metadata, tag, callback)
|
||||||
}
|
}
|
||||||
data.versions[version] = metadata;
|
data.versions[version] = metadata;
|
||||||
data['dist-tags'][tag] = version;
|
data['dist-tags'][tag] = version;
|
||||||
storage.update_json(name + '/' + info_file, data, callback);
|
self.storage.update_json(name + '/' + info_file, data, callback);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Storage.prototype.add_tarball = function(name, filename, stream, callback) {
|
Storage.prototype.add_tarball = function(name, filename, stream, callback) {
|
||||||
|
var self = this;
|
||||||
if (name === info_file) {
|
if (name === info_file) {
|
||||||
return callback(new UError({
|
return callback(new UError({
|
||||||
status: 403,
|
status: 403,
|
||||||
|
@ -84,7 +57,7 @@ Storage.prototype.add_tarball = function(name, filename, stream, callback) {
|
||||||
d.copy(data, tmp.length);
|
d.copy(data, tmp.length);
|
||||||
});
|
});
|
||||||
stream.on('end', function(d) {
|
stream.on('end', function(d) {
|
||||||
storage.create(name + '/' + filename, data, function(err) {
|
self.storage.create(name + '/' + filename, data, function(err) {
|
||||||
if (err && err.code === 'EEXISTS') {
|
if (err && err.code === 'EEXISTS') {
|
||||||
return callback(new UError({
|
return callback(new UError({
|
||||||
status: 409,
|
status: 409,
|
||||||
|
@ -97,7 +70,7 @@ 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) {
|
||||||
storage.read(name + '/' + filename, function(err) {
|
this.storage.read(name + '/' + filename, function(err) {
|
||||||
if (err && err.code === 'ENOENT') {
|
if (err && err.code === 'ENOENT') {
|
||||||
return callback(new UError({
|
return callback(new UError({
|
||||||
status: 404,
|
status: 404,
|
||||||
|
@ -109,7 +82,7 @@ Storage.prototype.get_tarball = function(name, filename, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Storage.prototype.get_package = function(name, callback) {
|
Storage.prototype.get_package = function(name, callback) {
|
||||||
storage.read_json(name + '/' + info_file, function(err) {
|
this.storage.read_json(name + '/' + info_file, function(err) {
|
||||||
if (err && err.code === 'ENOENT') {
|
if (err && err.code === 'ENOENT') {
|
||||||
return callback(new UError({
|
return callback(new UError({
|
||||||
status: 404,
|
status: 404,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
var request = require('request');
|
var request = require('request');
|
||||||
|
var UError = require('./error').UserError;
|
||||||
var URL = require('url');
|
var URL = require('url');
|
||||||
|
|
||||||
function Storage(name, config) {
|
function Storage(name, config) {
|
||||||
|
@ -23,6 +24,12 @@ Storage.prototype.get_package = function(name, callback) {
|
||||||
ca: this.ca,
|
ca: this.ca,
|
||||||
}, function(err, res, body) {
|
}, function(err, res, body) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
|
if (res.statusCode === 404) {
|
||||||
|
return callback(new UError({
|
||||||
|
msg: 'package doesn\'t exist on uplink',
|
||||||
|
status: 404,
|
||||||
|
}));
|
||||||
|
}
|
||||||
if (!(res.statusCode >= 200 && res.statusCode < 300)) {
|
if (!(res.statusCode >= 200 && res.statusCode < 300)) {
|
||||||
return callback(new Error('bad status code: ' + res.statusCode));
|
return callback(new Error('bad status code: ' + res.statusCode));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,43 @@ function Storage(config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Storage.prototype.add_package = function(name, metadata, callback) {
|
Storage.prototype.add_package = function(name, metadata, callback) {
|
||||||
this.local.add_package(name, metadata, callback);
|
var self = this;
|
||||||
|
|
||||||
|
var uplinks = [];
|
||||||
|
for (var i in this.uplinks) {
|
||||||
|
if (this.config.allow_proxy(name, i)) {
|
||||||
|
uplinks.push(this.uplinks[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async.map(uplinks, function(up, cb) {
|
||||||
|
up.get_package(name, function(err, res) {
|
||||||
|
cb(null, [err, res]);
|
||||||
|
});
|
||||||
|
}, function(err, results) {
|
||||||
|
for (var i=0; i<results.length; i++) {
|
||||||
|
// checking error
|
||||||
|
// if uplink fails with a status other than 404, we report failure
|
||||||
|
if (results[i][0] != null) {
|
||||||
|
if (results[i][0].status !== 404) {
|
||||||
|
return callback(new UError({
|
||||||
|
status: 503,
|
||||||
|
msg: 'one of the uplinks is down, refuse to publish'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// checking package
|
||||||
|
if (results[i][1] != null) {
|
||||||
|
return callback(new UError({
|
||||||
|
status: 409,
|
||||||
|
msg: 'this package is already present'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.local.add_package(name, metadata, callback);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Storage.prototype.add_version = function(name, version, metadata, tag, callback) {
|
Storage.prototype.add_version = function(name, version, metadata, tag, callback) {
|
||||||
|
@ -47,6 +83,7 @@ Storage.prototype.get_package = function(name, callback) {
|
||||||
versions: {},
|
versions: {},
|
||||||
'dist-tags': {},
|
'dist-tags': {},
|
||||||
};
|
};
|
||||||
|
var exists = false;
|
||||||
var latest;
|
var latest;
|
||||||
|
|
||||||
async.map(uplinks, function(up, cb) {
|
async.map(uplinks, function(up, cb) {
|
||||||
|
@ -72,11 +109,15 @@ Storage.prototype.get_package = function(name, callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// if we got to this point, assume that the correct package exists
|
||||||
|
// on the uplink
|
||||||
|
exists = true;
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
if (Object.keys(result.versions).length === 0) {
|
if (!exists) {
|
||||||
return callback(new UError({
|
return callback(new UError({
|
||||||
status: 404,
|
status: 404,
|
||||||
msg: 'no such package available'
|
msg: 'no such package available'
|
||||||
|
|
Loading…
Reference in a new issue