mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-16 21:56:25 -05:00
initial development
This commit is contained in:
parent
0c80d49787
commit
af452c93d3
7 changed files with 223 additions and 16 deletions
24
bin/npmrepod
24
bin/npmrepod
|
@ -1,24 +1,24 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var fs = require('fs');
|
||||
var yaml = require('js-yaml');
|
||||
var commander = require('commander');
|
||||
var pkg = yaml.safeLoad(fs.readFileSync('../package.yaml', 'utf8'));
|
||||
var server = require('../lib/index');
|
||||
|
||||
commander
|
||||
// re-inventing the wheel because I don't want to require package.json for every run
|
||||
.option('-V, --version', 'output the version number')
|
||||
.on('version', get_version)
|
||||
|
||||
.option('-p, --port <port>', 'port number to listen on (default: 4873)', 4873)
|
||||
.option('-l, --listen <[host:]port>', 'host:port number to listen on (default: localhost:4873)', '4873')
|
||||
.option('-s, --storage <path>', 'path to package cache (default: "~/.npmrepod")')
|
||||
// todo: need something to do with invalid https certificate, but we just can't use http by default
|
||||
.option('-u, --uplink <url>', 'parent registry (default: "https://registry.npmjs.org/")')
|
||||
.option('-c, --config <file>', 'use this configuration file')
|
||||
|
||||
.option('-c, --config <file.yaml>', 'use this configuration file')
|
||||
.version(pkg.version)
|
||||
.parse(process.argv);
|
||||
|
||||
function get_version() {
|
||||
console.log(require('../package.json').version);
|
||||
process.exit(0);
|
||||
var hostport = commander.listen.split(':');
|
||||
if (hostport.length < 2) {
|
||||
hostport = [undefined, hostport[0]];
|
||||
}
|
||||
|
||||
console.log('This thing doesn\'t work yet! Come back in a few weeks...');
|
||||
server({}).listen(hostport[1], hostport[0]);
|
||||
console.log('Server is listening on http://%s:%s/', hostport[0] || 'localhost', hostport[1]);
|
||||
|
||||
|
|
132
lib/index.js
132
lib/index.js
|
@ -0,0 +1,132 @@
|
|||
var express = require('express');
|
||||
var cookies = require('cookies');
|
||||
var proxy = require('./proxy');
|
||||
var utils = require('./utils');
|
||||
var storage = require('./storage');
|
||||
|
||||
function validate_name(req, res, next, value, name) {
|
||||
if (utils.validate_name(req.params.package)) {
|
||||
req.params.package = String(req.params.package);
|
||||
next();
|
||||
} else {
|
||||
res.status(403);
|
||||
return res.send({
|
||||
error: 'invalid package name'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = function(settings) {
|
||||
var app = express();
|
||||
app.use(express.logger());
|
||||
app.use(express.bodyParser());
|
||||
app.param('package', validate_name);
|
||||
|
||||
/* app.get('/', function(req, res) {
|
||||
res.send({
|
||||
error: 'unimplemented'
|
||||
});
|
||||
});*/
|
||||
|
||||
app.get('/:package', function(req, res) {
|
||||
storage.get_package(req.params.package, function(err, info) {
|
||||
if (err) return next(err);
|
||||
if (!info) {
|
||||
res.status(404);
|
||||
return res.send({
|
||||
error: 'package not found'
|
||||
});
|
||||
}
|
||||
res.send(info);
|
||||
});
|
||||
});
|
||||
|
||||
//app.get('/*', function(req, res) {
|
||||
// proxy.request(req, res);
|
||||
//});
|
||||
|
||||
// placeholder 'cause npm require to be authenticated to publish
|
||||
// we do not do any real authentication yet
|
||||
app.post('/_session', cookies.express(), function(req, res) {
|
||||
res.cookies.set('AuthSession', String(Math.random()), {
|
||||
// npmjs.org sets 10h expire
|
||||
expires: new Date(Date.now() + 10*60*60*1000)
|
||||
});
|
||||
res.send({"ok":true,"name":"anonymous","roles":[]});
|
||||
});
|
||||
|
||||
// publishing a package
|
||||
app.put('/:package', function(req, res, next) {
|
||||
var name = req.params.package;
|
||||
if (req.headers['content-type'] !== 'application/json') {
|
||||
res.status(415);
|
||||
return res.send({
|
||||
error: 'wrong content-type, we expect application/json',
|
||||
});
|
||||
}
|
||||
if (typeof(req.body) !== 'object') {
|
||||
res.status(400);
|
||||
return res.send({
|
||||
error: 'can\'t parse incoming json',
|
||||
});
|
||||
}
|
||||
|
||||
storage.create_package(name, req.body, function(err, created) {
|
||||
if (err) return next(err);
|
||||
if (created) {
|
||||
res.status(201);
|
||||
return res.send({
|
||||
ok: 'created new package'
|
||||
});
|
||||
} else {
|
||||
res.status(409);
|
||||
return res.send({
|
||||
error: 'package already exists'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// uploading package tarball
|
||||
app.put('/:package/-/:filename/*', function(req, res, next) {
|
||||
res.status(201);
|
||||
return res.send({
|
||||
ok: 'tarball uploaded successfully'
|
||||
});
|
||||
});
|
||||
|
||||
// adding a version
|
||||
app.put('/:package/:version/-tag/:tag', function(req, res, next) {
|
||||
var name = req.params.package;
|
||||
if (req.headers['content-type'] !== 'application/json') {
|
||||
res.status(415);
|
||||
return res.send({
|
||||
error: 'wrong content-type, we expect application/json',
|
||||
});
|
||||
}
|
||||
if (typeof(req.body) !== 'object') {
|
||||
res.status(400);
|
||||
return res.send({
|
||||
error: 'can\'t parse incoming json',
|
||||
});
|
||||
}
|
||||
|
||||
storage.add_version(req.params.package, req.params.version, req.body, function(err, created) {
|
||||
if (err) return next(err);
|
||||
if (created) {
|
||||
res.status(201);
|
||||
return res.send({
|
||||
ok: 'package published'
|
||||
});
|
||||
} else {
|
||||
res.status(409);
|
||||
return res.send({
|
||||
error: 'this version already exists'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return app;
|
||||
};
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
module.exports.add_package = function(name, version, tarball) {
|
||||
|
||||
}
|
||||
|
25
lib/proxy.js
Normal file
25
lib/proxy.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
var http = require('http');
|
||||
|
||||
module.exports.request = function(req, resp) {
|
||||
console.log(req.headers);
|
||||
http.get({
|
||||
host: 'registry.npmjs.org',
|
||||
path: req.url,
|
||||
headers: {
|
||||
'User-Agent': 'npmrepod/0.0.0',
|
||||
'Authorization': req.headers.authorization,
|
||||
},
|
||||
}, function(res) {
|
||||
resp.writeHead(res.statusCode, res.headers);
|
||||
res.on('data', function(d) {
|
||||
resp.write(d);
|
||||
});
|
||||
res.on('end', function() {
|
||||
resp.end();
|
||||
});
|
||||
}).on('error', function(err) {
|
||||
console.error(err);
|
||||
resp.send(500);
|
||||
});
|
||||
}
|
||||
|
27
lib/storage.js
Normal file
27
lib/storage.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
var packages = {};
|
||||
|
||||
module.exports.create_package = function(name, metadata, callback) {
|
||||
if (packages[name] == null) {
|
||||
packages[name] = {
|
||||
meta: metadata,
|
||||
versions: {},
|
||||
};
|
||||
callback(null, true);
|
||||
} else {
|
||||
callback(null, false);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.add_version = function(name, version, metadata, callback) {
|
||||
if (packages[name] == null) {
|
||||
callback(null, false);
|
||||
} else {
|
||||
packages[name].versions[version] = metadata;
|
||||
callback(null, true);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.get_package = function(name, callback) {
|
||||
callback(null, packages[name]);
|
||||
}
|
||||
|
16
lib/utils.js
Normal file
16
lib/utils.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
// from normalize-package-data/lib/fixer.js
|
||||
module.exports.validate_name = function(name) {
|
||||
if (
|
||||
name.charAt(0) === "." ||
|
||||
name.match(/[\/@\s\+%:]/) ||
|
||||
name !== encodeURIComponent(name) ||
|
||||
name.toLowerCase() === "node_modules" ||
|
||||
name.toLowerCase() === "favicon.ico"
|
||||
) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,8 +13,10 @@ bin:
|
|||
npmrepod: ./bin/npmrepod
|
||||
|
||||
dependencies:
|
||||
express: '*'
|
||||
commander: '*'
|
||||
express: '>= 3.2.5'
|
||||
commander: '>= 1.1.1'
|
||||
js-yaml: '>= 2.0.5'
|
||||
cookies: '>= 0.3.6'
|
||||
|
||||
preferGlobal: true
|
||||
license: BSD
|
||||
|
|
Loading…
Reference in a new issue