0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-16 21:56:25 -05:00

initial development

This commit is contained in:
Alex Kocharin 2013-05-31 10:26:11 +04:00
parent 0c80d49787
commit af452c93d3
7 changed files with 223 additions and 16 deletions

View file

@ -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]);

View file

@ -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;
};

View file

@ -0,0 +1,5 @@
module.exports.add_package = function(name, version, tarball) {
}

25
lib/proxy.js Normal file
View 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
View 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
View 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;
}
}

View file

@ -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