From b2f6128e9c571b6cb6e09562dcd3ede723608091 Mon Sep 17 00:00:00 2001 From: Alex Kocharin Date: Sat, 26 Oct 2013 16:18:36 +0400 Subject: [PATCH] style fix --- bin/sinopia | 2 +- lib/cli.js | 128 +++++++++++++------------- lib/config.js | 110 +++++++++++------------ lib/config_gen.js | 14 +-- lib/error.js | 52 +++++------ lib/index.js | 210 +++++++++++++++++++++---------------------- lib/local-fs.js | 108 +++++++++++----------- lib/local-storage.js | 74 +++++++-------- lib/logger.js | 94 +++++++++---------- lib/middleware.js | 88 +++++++++--------- lib/storage.js | 204 ++++++++++++++++++++--------------------- lib/streams.js | 56 ++++++------ lib/up-storage.js | 154 +++++++++++++++---------------- lib/utils.js | 60 ++++++------- 14 files changed, 677 insertions(+), 677 deletions(-) diff --git a/bin/sinopia b/bin/sinopia index 207bdc1f9..32a78deaa 100755 --- a/bin/sinopia +++ b/bin/sinopia @@ -1,4 +1,4 @@ #!/usr/bin/env node -require('../lib/cli'); +require('../lib/cli') diff --git a/lib/cli.js b/lib/cli.js index 60a55377b..a26a57bfa 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -1,121 +1,121 @@ #!/usr/bin/env node -var logger = require('./logger'); -logger.setup(); // default setup +var logger = require('./logger') +logger.setup() // default setup -var pkg_file = '../package.yaml'; -var fs = require('fs'); -var yaml = require('js-yaml'); -var commander = require('commander'); -var server = require('./index'); -var crypto = require('crypto'); -var pkg = require(pkg_file); +var pkg_file = '../package.yaml' + , fs = require('fs') + , yaml = require('js-yaml') + , commander = require('commander') + , server = require('./index') + , crypto = require('crypto') + , pkg = require(pkg_file) commander .option('-l, --listen <[host:]port>', 'host:port number to listen on (default: localhost:4873)') .option('-c, --config ', 'use this configuration file (default: ./config.yaml)') .version(pkg.version) - .parse(process.argv); + .parse(process.argv) if (commander.args.length == 1 && !commander.config) { // handling "sinopia [config]" case if "-c" is missing in commandline - commander.config = commander.args.pop(); + commander.config = commander.args.pop() } if (commander.args.length != 0) { - commander.help(); + commander.help() } -var config, config_path, have_question; +var config, config_path, have_question try { if (commander.config) { - config_path = commander.config; - config = yaml.safeLoad(fs.readFileSync(config_path, 'utf8')); + config_path = commander.config + config = yaml.safeLoad(fs.readFileSync(config_path, 'utf8')) } else { - config_path = './config.yaml'; + config_path = './config.yaml' try { - config = yaml.safeLoad(fs.readFileSync(config_path, 'utf8')); + config = yaml.safeLoad(fs.readFileSync(config_path, 'utf8')) } catch(err) { - var readline = require('readline'); - var rl = readline.createInterface(process.stdin, process.stdout); + var readline = require('readline') + var rl = readline.createInterface(process.stdin, process.stdout) var timeout = setTimeout(function() { - console.log('I got tired waiting for an answer. Exitting...'); - process.exit(1); - }, 20000); + console.log('I got tired waiting for an answer. Exitting...') + process.exit(1) + }, 20000) - (function askUser() { - have_question = true; + ;(function askUser() { + have_question = true rl.question('Config file doesn\'t exist, create a new one? (Y/n) ', function(x) { - clearTimeout(timeout); + clearTimeout(timeout) if (x[0] == 'Y' || x[0] == 'y' || x === '') { - rl.close(); + rl.close() - var created_config = require('../lib/config_gen')(); - config = yaml.safeLoad(created_config.yaml); - write_config_banner(created_config, config); - fs.writeFileSync(config_path, created_config.yaml); - afterConfigLoad(); + var created_config = require('../lib/config_gen')() + config = yaml.safeLoad(created_config.yaml) + write_config_banner(created_config, config) + fs.writeFileSync(config_path, created_config.yaml) + afterConfigLoad() } else if (x[0] == 'N' || x[0] == 'n') { - rl.close(); - console.log('So, you just accidentally run me in a wrong folder. Exitting...'); - process.exit(1); + rl.close() + console.log('So, you just accidentally run me in a wrong folder. Exitting...') + process.exit(1) } else { - askUser(); + askUser() } - }); - })(); + }) + })() } } } catch(err) { - logger.logger.fatal({file: config_path, err: err}, 'cannot open config file @{file}: @{!err.message}'); - process.exit(1); + logger.logger.fatal({file: config_path, err: err}, 'cannot open config file @{file}: @{!err.message}') + process.exit(1) } -if (!have_question) afterConfigLoad(); +if (!have_question) afterConfigLoad() function get_hostport() { // command line || config file || default - var hostport = commander.listen || String(config.listen || '') || '4873'; + var hostport = commander.listen || String(config.listen || '') || '4873' - hostport = hostport.split(':'); + hostport = hostport.split(':') if (hostport.length < 2) { - hostport = [undefined, hostport[0]]; + hostport = [undefined, hostport[0]] } if (hostport[0] == null) { - hostport[0] = 'localhost'; + hostport[0] = 'localhost' } - return hostport; + return hostport } function afterConfigLoad() { - if (!config.user_agent) config.user_agent = 'Sinopia/'+pkg.version; - if (!config.self_path) config.self_path = config_path; + if (!config.user_agent) config.user_agent = 'Sinopia/'+pkg.version + if (!config.self_path) config.self_path = config_path logger.setup(config.logs) - var hostport = get_hostport(); - server(config).listen(hostport[1], hostport[0]); - logger.logger.warn({addr: 'http://'+hostport[0]+':'+hostport[1]+'/'}, 'Server is listening on @{addr}'); + var hostport = get_hostport() + server(config).listen(hostport[1], hostport[0]) + logger.logger.warn({addr: 'http://'+hostport[0]+':'+hostport[1]+'/'}, 'Server is listening on @{addr}') // undocumented stuff for tests if (typeof(process.send) === 'function') { - process.send({sinopia_started: hostport}); + process.send({sinopia_started: hostport}) } } function write_config_banner(def, config) { - var hostport = get_hostport(); - console.log('==========================================================='); - console.log(' Creating a new configuration file: "%s"', config_path); - console.log(' '); - console.log(' If you want to setup npm to work with this registry,'); - console.log(' run following commands:'); - console.log(' '); - console.log(' $ npm set registry http://%s:%s/', hostport[0], hostport[1]); - console.log(' $ npm set always-auth true'); - console.log(' $ npm adduser'); - console.log(' Username: %s', def.user); - console.log(' Password: %s', def.pass); - console.log('==========================================================='); + var hostport = get_hostport() + console.log('===========================================================') + console.log(' Creating a new configuration file: "%s"', config_path) + console.log(' ') + console.log(' If you want to setup npm to work with this registry,') + console.log(' run following commands:') + console.log(' ') + console.log(' $ npm set registry http://%s:%s/', hostport[0], hostport[1]) + console.log(' $ npm set always-auth true') + console.log(' $ npm adduser') + console.log(' Username: %s', def.user) + console.log(' Password: %s', def.pass) + console.log('===========================================================') } diff --git a/lib/config.js b/lib/config.js index e9c5478c9..b6261ddbf 100644 --- a/lib/config.js +++ b/lib/config.js @@ -5,133 +5,133 @@ var assert = require('assert') // [[a, [b, c]], d] -> [a, b, c, d] function flatten(array) { - var result = []; + var result = [] for (var i=0; i= 400 && err.status < 600) { if (calls == 1) { - res.status(err.status); - res.send({error: err.msg || err.message || 'unknown error'}); + res.status(err.status) + res.send({error: err.msg || err.message || 'unknown error'}) } } else { Logger.logger.error({err: err}, 'unexpected error: @{!err.message}\n@{err.stack}') if (calls == 1) { - res.status(500); - res.send({error: 'internal server error'}); + res.status(500) + res.send({error: 'internal server error'}) } } } - next(); - }); + next() + }) - app.use(Middleware.log_and_etagify); + app.use(Middleware.log_and_etagify) app.use(basic_auth(function(user, pass) { - return config.authenticate(user, pass); - })); - app.use(express.json({strict: false})); + return config.authenticate(user, pass) + })) + app.use(express.json({strict: false})) // TODO: npm DO NOT support compression :( - app.use(express.compress()); + app.use(express.compress()) - app.param('package', validate_name); - app.param('filename', validate_name); + app.param('package', validate_name) + app.param('filename', validate_name) /* app.get('/', function(req, res) { res.send({ error: 'unimplemented' - }); - });*/ + }) + })*/ /* app.get('/-/all', function(req, res) { - var https = require('https'); - var JSONStream = require('JSONStream'); + var https = require('https') + var JSONStream = require('JSONStream') var request = require('request')({ url: 'https://registry.npmjs.org/-/all', ca: require('./npmsslkeys'), }) .pipe(JSONStream.parse('*')) .on('data', function(d) { - console.log(d); - }); - });*/ + console.log(d) + }) + })*/ // TODO: anonymous user? app.get('/:package/:version?', can('access'), function(req, res, next) { storage.get_package(req.params.package, function(err, info) { - if (err) return next(err); - info = utils.filter_tarball_urls(info, req, config); + if (err) return next(err) + info = utils.filter_tarball_urls(info, req, config) - var version = req.params.version; + var version = req.params.version if (!version) { - return res.send(info); + return res.send(info) } if (info.versions[version] != null) { - return res.send(info.versions[version]); + return res.send(info.versions[version]) } if (info['dist-tags'] != null) { if (info['dist-tags'][version] != null) { - version = info['dist-tags'][version]; + version = info['dist-tags'][version] if (info.versions[version] != null) { - return res.send(info.versions[version]); + return res.send(info.versions[version]) } } } @@ -115,59 +115,59 @@ module.exports = function(config_hash) { return next(new UError({ status: 404, msg: 'version not found: ' + req.params.version - })); - }); - }); + })) + }) + }) app.get('/:package/-/:filename', can('access'), function(req, res, next) { - var stream = storage.get_tarball(req.params.package, req.params.filename); + var stream = storage.get_tarball(req.params.package, req.params.filename) stream.on('error', function(err) { - return res.report_error(err); - }); - res.header('content-type', 'application/octet-stream'); - stream.pipe(res); - }); - + return res.report_error(err) + }) + res.header('content-type', 'application/octet-stream') + stream.pipe(res) + }) + //app.get('/*', function(req, res) { - // proxy.request(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":"somebody","roles":[]}); - }); + }) + res.send({"ok":true,"name":"somebody","roles":[]}) + }) app.get('/-/user/:argument', function(req, res, next) { // can't put 'org.couchdb.user' in route address for some reason - if (req.params.argument.split(':')[0] !== 'org.couchdb.user') return next('route'); - res.status(200); + if (req.params.argument.split(':')[0] !== 'org.couchdb.user') return next('route') + res.status(200) return res.send({ ok: 'you are authenticated as "' + req.user + '"', - }); - }); + }) + }) app.put('/-/user/:argument', function(req, res, next) { // can't put 'org.couchdb.user' in route address for some reason - if (req.params.argument.split(':')[0] !== 'org.couchdb.user') return next('route'); - res.status(409); + if (req.params.argument.split(':')[0] !== 'org.couchdb.user') return next('route') + res.status(409) return res.send({ error: 'registration is not implemented', - }); - }); + }) + }) app.put('/-/user/:argument/-rev/*', function(req, res, next) { // can't put 'org.couchdb.user' in route address for some reason - if (req.params.argument.split(':')[0] !== 'org.couchdb.user') return next('route'); - res.status(201); + if (req.params.argument.split(':')[0] !== 'org.couchdb.user') return next('route') + res.status(201) return res.send({ ok: 'you are authenticated as "' + req.user + '"', - }); - }); + }) + }) // publishing a package app.put('/:package/:_rev?/:revision?', can('publish'), media('application/json'), expect_json, function(req, res, next) { @@ -202,7 +202,7 @@ module.exports = function(config_hash) { } else { storage.add_package(name, metadata, function(err) { if (err) return next(err) - res.status(201); + res.status(201) return res.send({ ok: 'created new package' }) @@ -213,75 +213,75 @@ module.exports = function(config_hash) { // unpublishing an entire package app.delete('/:package/-rev/*', can('publish'), function(req, res, next) { storage.remove_package(req.params.package, function(err) { - if (err) return next(err); - res.status(201); + if (err) return next(err) + res.status(201) return res.send({ ok: 'package removed' - }); - }); - }); + }) + }) + }) // removing a tarball app.delete('/:package/-/:filename/-rev/:revision', can('publish'), function(req, res, next) { storage.remove_tarball(req.params.package, req.params.filename, req.params.revision, function(err) { - if (err) return next(err); - res.status(201); + if (err) return next(err) + res.status(201) return res.send({ ok: 'tarball removed' - }); - }); - }); + }) + }) + }) // uploading package tarball app.put('/:package/-/:filename/*', can('publish'), media('application/octet-stream'), function(req, res, next) { - var name = req.params.package; + var name = req.params.package - var stream = storage.add_tarball(name, req.params.filename); - req.pipe(stream); + var stream = storage.add_tarball(name, req.params.filename) + req.pipe(stream) // checking if end event came before closing - var complete = false; + var complete = false req.on('end', function() { - complete = true; - stream.done(); - }); + complete = true + stream.done() + }) req.on('close', function() { if (!complete) { - stream.abort(); + stream.abort() } - }); + }) stream.on('error', function(err) { - return res.report_error(err); - }); + return res.report_error(err) + }) stream.on('success', function() { - res.status(201); + res.status(201) return res.send({ ok: 'tarball uploaded successfully' - }); - }); - }); - + }) + }) + }) + // adding a version app.put('/:package/:version/-tag/:tag', can('publish'), media('application/json'), expect_json, function(req, res, next) { - var name = req.params.package; - var version = req.params.version; - var tag = req.params.tag; + var name = req.params.package + , version = req.params.version + , tag = req.params.tag storage.add_version(name, version, req.body, tag, function(err) { - if (err) return next(err); - res.status(201); + if (err) return next(err) + res.status(201) return res.send({ ok: 'package published' - }); - }); - }); + }) + }) + }) - app.use(app.router); + app.use(app.router) app.use(function(err, req, res, next) { - res.report_error(err); - }); + res.report_error(err) + }) - return app; -}; + return app +} diff --git a/lib/local-fs.js b/lib/local-fs.js index a19a49a05..fd6ed7283 100644 --- a/lib/local-fs.js +++ b/lib/local-fs.js @@ -5,108 +5,108 @@ var fs = require('fs') , FSError = require('./error').FSError function make_directories(dest, cb) { - var dir = Path.dirname(dest); - if (dir === '.' || dir === '..') return cb(); + var dir = Path.dirname(dest) + if (dir === '.' || dir === '..') return cb() fs.mkdir(dir, function(err) { if (err && err.code === 'ENOENT') { make_directories(dir, function() { - fs.mkdir(dir, cb); + fs.mkdir(dir, cb) }) } else { - cb(); + cb() } - }); + }) } function write(dest, data, cb) { var safe_write = function(cb) { - var tmpname = dest + '.tmp' + String(Math.random()).substr(2); + var tmpname = dest + '.tmp' + String(Math.random()).substr(2) fs.writeFile(tmpname, data, function(err) { - if (err) return cb(err); - return fs.rename(tmpname, dest, cb); - }); + if (err) return cb(err) + return fs.rename(tmpname, dest, cb) + }) } safe_write(function(err) { if (err && err.code === 'ENOENT') { make_directories(dest, function() { - safe_write(cb); + safe_write(cb) }) } else { - cb(err); + cb(err) } - }); + }) } function write_stream(name) { - var stream = new mystreams.UploadTarballStream(); + var stream = new mystreams.UploadTarballStream() - var _ended = 0; + var _ended = 0 stream.on('end', function() { - _ended = 1; - }); + _ended = 1 + }) fs.exists(name, function(exists) { - if (exists) return stream.emit('error', new FSError('EEXISTS')); + if (exists) return stream.emit('error', new FSError('EEXISTS')) - var tmpname = name + '.tmp-'+String(Math.random()).replace(/^0\./, ''); - var file = fs.createWriteStream(tmpname); - var opened = false; - stream.pipe(file); + var tmpname = name + '.tmp-'+String(Math.random()).replace(/^0\./, '') + , file = fs.createWriteStream(tmpname) + , opened = false + stream.pipe(file) stream.done = function() { function onend() { file.on('close', function() { fs.rename(tmpname, name, function(err) { - if (err) stream.emit('error', err); - stream.emit('success'); - }); - }); - file.destroySoon(); + if (err) stream.emit('error', err) + stream.emit('success') + }) + }) + file.destroySoon() } if (_ended) { - onend(); + onend() } else { - stream.on('end', onend); + stream.on('end', onend) } - }; + } stream.abort = function() { if (opened) { - opened = false; + opened = false file.on('close', function() { - fs.unlink(tmpname, function(){}); - }); + fs.unlink(tmpname, function(){}) + }) } - file.destroySoon(); - }; + file.destroySoon() + } file.on('open', function() { - opened = true; + opened = true // re-emitting open because it's handled in storage.js - stream.emit('open'); - }); + stream.emit('open') + }) file.on('error', function(err) { - stream.emit('error', err); - }); - }); - return stream; + stream.emit('error', err) + }) + }) + return stream } function read_stream(name, stream, callback) { - return fs.createReadStream(name); + return fs.createReadStream(name) } function create(name, contents, callback) { fs.exists(name, function(exists) { - if (exists) return callback(new FSError('EEXISTS')); - write(name, contents, callback); - }); + if (exists) return callback(new FSError('EEXISTS')) + write(name, contents, callback) + }) } function update(name, contents, callback) { fs.exists(name, function(exists) { - if (!exists) return callback(new FSError('ENOENT')); - write(name, contents, callback); - }); + if (!exists) return callback(new FSError('ENOENT')) + write(name, contents, callback) + }) } function read(name, callback) { @@ -158,12 +158,12 @@ function lock_and_read(name, callback) { } function Storage(path) { - this.path = path; + this.path = path try { - fs.mkdirSync(path); - console.log('created new packages directory: ', path); + fs.mkdirSync(path) + console.log('created new packages directory: ', path) } catch(err) { - if (err.code !== 'EEXIST') throw new Error(err); + if (err.code !== 'EEXIST') throw new Error(err) } } @@ -173,7 +173,7 @@ Storage.prototype.read = function(name, cb) { Storage.prototype.read_json = function(name, cb) { read(this.path + '/' + name, function(err, res) { - if (err) return cb(err); + if (err) return cb(err) var args = [] try { @@ -247,5 +247,5 @@ Storage.prototype.rmdir = function(name, cb) { fs.rmdir(this.path + '/' + name, cb) } -module.exports = Storage; +module.exports = Storage diff --git a/lib/local-storage.js b/lib/local-storage.js index 2e78a8a48..1f3be6bd9 100644 --- a/lib/local-storage.js +++ b/lib/local-storage.js @@ -34,7 +34,7 @@ function get_boilerplate(name) { '_distfiles': {}, '_attachments': {}, '_uplinks': {}, - }; + } } Storage.prototype._internal_error = function(err, file, msg) { @@ -53,10 +53,10 @@ Storage.prototype.add_package = function(name, metadata, callback) { return callback(new UError({ status: 409, msg: 'this package is already present' - })); + })) } - callback(); - }); + callback() + }) } Storage.prototype.remove_package = function(name, callback) { @@ -107,14 +107,14 @@ Storage.prototype._read_create_package = function(name, callback) { if (err) { if (err.code === 'ENOENT') { // if package doesn't exist, we create it here - data = get_boilerplate(name); + data = get_boilerplate(name) } else { return callback(self._internal_error(err, file, 'error reading')) } } self._normalize_package(data) callback(null, data) - }); + }) } // synchronize remote package info with the local one @@ -134,7 +134,7 @@ Storage.prototype.update_versions = function(name, newdata, callback) { change = true data.versions[ver] = verdata - + if (verdata.dist && verdata.dist.tarball) { var url = utils.parse_tarball_url( verdata.dist.__sinopia_orig_tarball || verdata.dist.tarball @@ -170,7 +170,7 @@ Storage.prototype.update_versions = function(name, newdata, callback) { data._uplinks[up] = newdata._uplinks[up] } } - + if (change) { self.logger.debug('updating package info') self._write_package(name, data, callback) @@ -278,7 +278,7 @@ Storage.prototype.add_tarball = function(name, filename) { length += data.length _transform.apply(stream, arguments) } - + var self = this if (name === info_file || name === '__proto__') { stream.emit('error', new UError({ @@ -287,31 +287,31 @@ Storage.prototype.add_tarball = function(name, filename) { })) } - var wstream = this.storage.write_stream(name + '/' + filename); + var wstream = this.storage.write_stream(name + '/' + filename) wstream.on('error', function(err) { if (err.code === 'EEXISTS') { stream.emit('error', new UError({ status: 409, msg: 'this tarball is already present' - })); + })) } else if (err.code === 'ENOENT') { // check if package exists to throw an appropriate message self.get_package(name, function(_err, res) { if (_err) { - stream.emit('error', _err); + stream.emit('error', _err) } else { - stream.emit('error', err); + stream.emit('error', err) } - }); + }) } else { - stream.emit('error', err); + stream.emit('error', err) } - }); + }) wstream.on('open', function() { // re-emitting open because it's handled in storage.js - stream.emit('open'); + stream.emit('open') }) wstream.on('success', function() { self.update_package(name, function updater(data, cb) { @@ -335,40 +335,40 @@ Storage.prototype.add_tarball = function(name, filename) { stream.emit('error', new UError({ status: 422, msg: 'refusing to accept zero-length file' - })); - wstream.abort(); + })) + wstream.abort() } else { - wstream.done(); + wstream.done() } - }; - stream.pipe(wstream); + } + stream.pipe(wstream) - return stream; + return stream } Storage.prototype.get_tarball = function(name, filename, callback) { - var stream = new mystreams.ReadTarballStream(); + var stream = new mystreams.ReadTarballStream() stream.abort = function() { - rstream.close(); - }; + rstream.close() + } - var rstream = this.storage.read_stream(name + '/' + filename); + var rstream = this.storage.read_stream(name + '/' + filename) rstream.on('error', function(err) { if (err && err.code === 'ENOENT') { stream.emit('error', new UError({ status: 404, msg: 'no such file available', - })); + })) } else { - stream.emit('error', err); + stream.emit('error', err) } - }); + }) rstream.on('open', function() { // re-emitting open because it's handled in storage.js - stream.emit('open'); - rstream.pipe(stream); - }); - return stream; + stream.emit('open') + rstream.pipe(stream) + }) + return stream } Storage.prototype.get_package = function(name, callback) { @@ -452,9 +452,9 @@ Storage.prototype.update_package = function(name, updateFn, _callback) { } Storage.prototype._normalize_package = function(pkg) { - ['versions', 'dist-tags', '_distfiles', '_attachments', '_uplinks'].forEach(function(key) { + ;['versions', 'dist-tags', '_distfiles', '_attachments', '_uplinks'].forEach(function(key) { if (!utils.is_object(pkg[key])) pkg[key] = {} - }); + }) if (typeof(pkg._rev) !== 'string') pkg._rev = '0-0000000000000000' } @@ -468,5 +468,5 @@ Storage.prototype._write_package = function(name, json, callback) { this.storage.write_json(name + '/' + info_file, json, callback) } -module.exports = Storage; +module.exports = Storage diff --git a/lib/logger.js b/lib/logger.js index 65dba3bdb..f8087eebf 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -4,63 +4,63 @@ var Logger = require('bunyan') function getlvl(x) { if (x < 15) { - return 'trace'; + return 'trace' } else if (x < 25) { - return 'debug'; + return 'debug' } else if (x < 35) { - return 'info'; + return 'info' } else if (x == 35) { - return 'http'; + return 'http' } else if (x < 45) { - return 'warn'; + return 'warn' } else if (x < 55) { - return 'error'; + return 'error' } else { - return 'fatal'; + return 'fatal' } } module.exports.setup = function(logs) { - var streams = []; - if (!logs) logs = [{ type: 'stdout', format: 'pretty', level: 'http' }]; + var streams = [] + if (!logs) logs = [{ type: 'stdout', format: 'pretty', level: 'http' }] logs.forEach(function(target) { - var stream = new Stream(); - stream.writable = true; + var stream = new Stream() + stream.writable = true if (target.type === 'stdout' || target.type === 'stderr') { // destination stream - var dest = target.type === 'stdout' ? process.stdout : process.stderr; + var dest = target.type === 'stdout' ? process.stdout : process.stderr if (target.format === 'pretty') { // making fake stream for prettypritting stream.write = function(obj) { - dest.write(print(obj.level, obj.msg, obj, dest.isTTY) + "\n"); + dest.write(print(obj.level, obj.msg, obj, dest.isTTY) + "\n") } } else { stream.write = function(obj) { - dest.write(JSON.stringify(obj, Logger.safeCycles()) + "\n"); + dest.write(JSON.stringify(obj, Logger.safeCycles()) + "\n") } } } else if (target.type === 'file') { - var dest = require('fs').createWriteStream(target.path, {flags: 'a', encoding: 'utf8'}); + var dest = require('fs').createWriteStream(target.path, {flags: 'a', encoding: 'utf8'}) dest.on('error', function (err) { - Logger.emit('error', err); - }); + Logger.emit('error', err) + }) stream.write = function(obj) { - dest.write(JSON.stringify(obj, Logger.safeCycles()) + "\n"); + dest.write(JSON.stringify(obj, Logger.safeCycles()) + "\n") } } else { - throw new Error('wrong target type for a log'); + throw new Error('wrong target type for a log') } - if (target.level === 'http') target.level = 35; + if (target.level === 'http') target.level = 35 streams.push({ type: "raw", level: target.level || 35, stream: stream, - }); - }); + }) + }) var logger = new Logger({ name: 'sinopia', @@ -70,9 +70,9 @@ module.exports.setup = function(logs) { req: Logger.stdSerializers.req, res: Logger.stdSerializers.res, }, - }); + }) - module.exports.logger = logger; + module.exports.logger = logger } // adopted from socket.io @@ -88,17 +88,17 @@ var levels = { info: 36, debug: 90, trace: 90, -}; +} -var max = 0; +var max = 0 for (var l in levels) { - max = Math.max(max, l.length); + max = Math.max(max, l.length) } function pad(str) { - if (str.length < max) return str + new Array(max - str.length + 1).join(' '); - return str; -}; + if (str.length < max) return str + new Array(max - str.length + 1).join(' ') + return str +} var subsystems = [{ in: '\x1b[32m<--\x1b[39m', @@ -113,43 +113,43 @@ var subsystems = [{ }] function print(type, msg, obj, colors) { - if (typeof type === 'number') type = getlvl(type); + if (typeof type === 'number') type = getlvl(type) var finalmsg = msg.replace(/@{(!?[$A-Za-z_][$0-9A-Za-z\._]*)}/g, function(_, name) { - var str = obj, is_error; + var str = obj, is_error if (name[0] === '!') { - name = name.substr(1); - is_error = true; + name = name.substr(1) + is_error = true } - var _ref = name.split('.'); + var _ref = name.split('.') for (var _i = 0; _i < _ref.length; _i++) { - var id = _ref[_i]; + var id = _ref[_i] if (utils.is_object(str) || Array.isArray(str)) { - str = str[id]; + str = str[id] } else { - str = void 0; + str = undefined } } if (typeof(str) === 'string') { if (!colors) { - return str; + return str } else if (is_error) { - return '\x1b[31m' + str + '\x1b[39m'; + return '\x1b[31m' + str + '\x1b[39m' } else { - return '\x1b[32m' + str + '\x1b[39m'; + return '\x1b[32m' + str + '\x1b[39m' } } else { - return require('util').inspect(str, void 0, void 0, colors); + return require('util').inspect(str, void 0, void 0, colors) } - }); - var sub = subsystems[+!colors][obj.sub] || subsystems[+!colors].default; + }) + var sub = subsystems[+!colors][obj.sub] || subsystems[+!colors].default // ^^--- black magic... kidding, just "colors ? 0 : 1" if (colors) { - return " \x1b[" + levels[type] + "m" + (pad(type)) + "\x1b[39m " + sub + " " + finalmsg; + return " \x1b[" + levels[type] + "m" + (pad(type)) + "\x1b[39m " + sub + " " + finalmsg } else { - return " " + (pad(type)) + " " + sub + " " + finalmsg; + return " " + (pad(type)) + " " + sub + " " + finalmsg } -}; +} diff --git a/lib/middleware.js b/lib/middleware.js index 1d58f1324..d36b601ca 100644 --- a/lib/middleware.js +++ b/lib/middleware.js @@ -1,19 +1,19 @@ -var crypto = require('crypto'); -var utils = require('./utils'); -var UError = require('./error').UserError; -var Logger = require('./logger'); +var crypto = require('crypto') + , utils = require('./utils') + , UError = require('./error').UserError + , Logger = require('./logger') module.exports.validate_name = function validate_name(req, res, next, value, name) { if (utils.validate_name(req.params.package)) { - req.params.package = String(req.params.package); - next(); + req.params.package = String(req.params.package) + next() } else { next(new UError({ status: 403, msg: 'invalid package name', - })); + })) } -}; +} module.exports.media = function media(expect) { return function(req, res, next) { @@ -21,9 +21,9 @@ module.exports.media = function media(expect) { next(new UError({ status: 415, msg: 'wrong content-type, expect: '+expect+', got: '+req.headers['content-type'], - })); + })) } else { - next(); + next() } } } @@ -33,105 +33,105 @@ module.exports.expect_json = function expect_json(req, res, next) { return next({ status: 400, msg: 'can\'t parse incoming json', - }); + }) } - next(); + next() } module.exports.basic_auth = function basic_auth(callback) { return function(req, res, next) { - var authorization = req.headers.authorization; + var authorization = req.headers.authorization - if (req.user) return next(); + if (req.user) return next() if (authorization == null) { - req.user = req.remoteUser = undefined; - return next(); + req.user = req.remoteUser = undefined + return next() } - var parts = authorization.split(' '); + var parts = authorization.split(' ') if (parts.length !== 2) return next({ status: 400, msg: 'bad authorization header', - }); + }) var scheme = parts[0] , credentials = new Buffer(parts[1], 'base64').toString() - , index = credentials.indexOf(':'); + , index = credentials.indexOf(':') if ('Basic' != scheme || index < 0) return next({ status: 400, msg: 'bad authorization header', - }); - + }) + var user = credentials.slice(0, index) - , pass = credentials.slice(index + 1); + , pass = credentials.slice(index + 1) if (callback(user, pass)) { - req.user = req.remoteUser = user; - next(); + req.user = req.remoteUser = user + next() } else { next({ status: 403, msg: 'bad username/password, access denied', - }); + }) } } -}; +} // express doesn't do etags with requests <= 1024b // we use md5 here, it works well on 1k+ bytes, but sucks with fewer data // could improve performance using crc32 after benchmarks function md5sum(data) { - return crypto.createHash('md5').update(data).digest('hex'); + return crypto.createHash('md5').update(data).digest('hex') } module.exports.log_and_etagify = function(req, res, next) { // logger - req.log = Logger.logger.child({sub: 'in'}); + req.log = Logger.logger.child({sub: 'in'}) var _auth = req.headers.authorization if (_auth) req.headers.authorization = '' req.log.info({req: req, ip: req.ip}, '@{ip} requested \'@{req.method} @{req.url}\'') if (_auth) req.headers.authorization = _auth - var bytesin = 0; - req.on('data', function(chunk){ bytesin += chunk.length }); + var bytesin = 0 + req.on('data', function(chunk){ bytesin += chunk.length }) - var _send = res.send; + var _send = res.send res.send = function(body) { if (typeof(body) === 'string' || typeof(body) === 'object') { - res.header('Content-type', 'application/json'); + res.header('Content-type', 'application/json') if (typeof(body) === 'object' && body != null) { if (body.error) { - res._sinopia_error = body.error; + res._sinopia_error = body.error } - body = JSON.stringify(body, undefined, '\t'); + body = JSON.stringify(body, undefined, '\t') } - - res.header('ETag', '"' + md5sum(body) + '"'); + + res.header('ETag', '"' + md5sum(body) + '"') } else { // send(null), send(204), etc. } - res.send = _send; - res.send(body); + res.send = _send + res.send(body) } var bytesout = 0 - var _write = res.write + , _write = res.write res.write = function(buf) { bytesout += buf.length _write.apply(res, arguments) } function log() { - var msg = '@{status}, user: @{user}, req: \'@{request.method} @{request.url}\''; + var msg = '@{status}, user: @{user}, req: \'@{request.method} @{request.url}\'' if (res._sinopia_error) { - msg += ', error: @{!error}'; + msg += ', error: @{!error}' } else { - msg += ', bytes: @{bytes.in}/@{bytes.out}'; + msg += ', bytes: @{bytes.in}/@{bytes.out}' } req.log.warn({ request: {method: req.method, url: req.url}, @@ -143,14 +143,14 @@ module.exports.log_and_etagify = function(req, res, next) { in: bytesin, out: bytesout, } - }, msg); + }, msg) } req.on('close', function() { log(true) }) - var _end = res.end; + var _end = res.end res.end = function(buf) { if (buf) bytesout += buf.length _end.apply(res, arguments) diff --git a/lib/storage.js b/lib/storage.js index 797291cce..17ff66ea8 100644 --- a/lib/storage.js +++ b/lib/storage.js @@ -1,30 +1,30 @@ -var async = require('async'); -var semver = require('semver'); -var UError = require('./error').UserError; -var Local = require('./local-storage'); -var Proxy = require('./up-storage'); -var mystreams = require('./streams'); -var utils = require('./utils'); +var async = require('async') + , semver = require('semver') + , UError = require('./error').UserError + , Local = require('./local-storage') + , Proxy = require('./up-storage') + , mystreams = require('./streams') + , utils = require('./utils') // // Implements Storage interface // (same for storage.js, local-storage.js, up-storage.js) // 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 // we support a number of uplinks, but only one local storage // Proxy and Local classes should have similar API interfaces - this.uplinks = {}; + this.uplinks = {} for (var p in config.uplinks) { - this.uplinks[p] = new Proxy(config.uplinks[p], config); - this.uplinks[p].upname = p; + this.uplinks[p] = new Proxy(config.uplinks[p], config) + this.uplinks[p].upname = p } - this.local = new Local(config); + this.local = new Local(config) - return this; + return this } // @@ -43,19 +43,19 @@ function Storage(config) { // uplinks (proxy_publish, write) // Storage.prototype.add_package = function(name, metadata, callback) { - var self = this; + var self = this - var uplinks = []; + var uplinks = [] for (var i in self.uplinks) { if (self.config.proxy_access(name, i)) { - uplinks.push(self.uplinks[i]); + uplinks.push(self.uplinks[i]) } } async.map(uplinks, function(up, cb) { up.get_package(name, null, function(err, res) { - cb(null, [err, res]); - }); + cb(null, [err, res]) + }) }, function(err, results) { for (var i=0; i 60*1000) { - return false; + return false } else { - return true; + return true } } else { - this.is_alive = alive; - this.is_alive_time = Date.now(); + this.is_alive = alive + this.is_alive_time = Date.now() } } Storage.prototype.can_fetch_url = function(url) { - url = URL.parse(url); + url = URL.parse(url) return url.protocol === this.url.protocol && url.host === this.url.host @@ -137,12 +137,12 @@ Storage.prototype.add_package = function(name, metadata, callback) { method: 'PUT', json: metadata, }, function(err, res, body) { - if (err) return callback(err); + if (err) return callback(err) 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)) } - callback(null, body); - }); + callback(null, body) + }) } Storage.prototype.add_version = function(name, version, metadata, tag, callback) { @@ -151,17 +151,17 @@ Storage.prototype.add_version = function(name, version, metadata, tag, callback) method: 'PUT', json: metadata, }, function(err, res, body) { - if (err) return callback(err); + if (err) return callback(err) 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)) } - callback(null, body); - }); + callback(null, body) + }) } Storage.prototype.add_tarball = function(name, filename) { - var stream = new mystreams.UploadTarballStream(); - var self = this; + var stream = new mystreams.UploadTarballStream() + , self = this var wstream = this.request({ uri: '/' + escape(name) + '/-/' + escape(filename) + '/whatever', @@ -169,33 +169,33 @@ Storage.prototype.add_tarball = function(name, filename) { headers: { 'content-type': 'application/octet-stream' }, - }); + }) wstream.on('response', function(res) { if (!(res.statusCode >= 200 && res.statusCode < 300)) { return stream.emit('error', new UError({ msg: 'bad uplink status code: ' + res.statusCode, status: 500, - })); + })) } - stream.emit('success'); - }); + stream.emit('success') + }) wstream.on('error', function(err) { - stream.emit('error', err); - }); + stream.emit('error', err) + }) stream.abort = function() { process.nextTick(function() { if (wstream.req) { - wstream.req.abort(); + wstream.req.abort() } - }); - }; - stream.done = function() {}; - stream.pipe(wstream); + }) + } + stream.done = function() {} + stream.pipe(wstream) - return stream; + return stream } Storage.prototype.get_package = function(name, etag, callback) { @@ -209,55 +209,55 @@ Storage.prototype.get_package = function(name, etag, callback) { json: true, headers: headers, }, 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)) { - return callback(new Error('bad status code: ' + res.statusCode)); + return callback(new Error('bad status code: ' + res.statusCode)) } - callback(null, body, res.headers.etag); - }); + callback(null, body, res.headers.etag) + }) } Storage.prototype.get_tarball = function(name, filename) { - return this.get_url(this.config.url + '/' + name + '/-/' + filename); + return this.get_url(this.config.url + '/' + name + '/-/' + filename) } Storage.prototype.get_url = function(url) { - var stream = new mystreams.ReadTarballStream(); - stream.abort = function() {}; + var stream = new mystreams.ReadTarballStream() + stream.abort = function() {} var rstream = this.request({ uri_full: url, encoding: null, - }); - + }) + rstream.on('response', function(res) { if (res.statusCode === 404) { return stream.emit('error', new UError({ msg: 'file doesn\'t exist on uplink', status: 404, - })); + })) } if (!(res.statusCode >= 200 && res.statusCode < 300)) { return stream.emit('error', new UError({ msg: 'bad uplink status code: ' + res.statusCode, status: 500, - })); + })) } - rstream.pipe(stream); - }); + rstream.pipe(stream) + }) rstream.on('error', function(err) { - stream.emit('error', err); - }); - return stream; + stream.emit('error', err) + }) + return stream } -module.exports = Storage; +module.exports = Storage diff --git a/lib/utils.js b/lib/utils.js index 5f6df2de6..f08446228 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,9 +1,9 @@ -var assert = require('assert'); -var URL = require('url'); +var assert = require('assert') + , URL = require('url') // from normalize-package-data/lib/fixer.js module.exports.validate_name = function(name) { - name = name.toLowerCase(); + name = name.toLowerCase() if ( name.charAt(0) === "." || // ".bin", etc. name.match(/[\/@\s\+%:]/) || @@ -13,9 +13,9 @@ module.exports.validate_name = function(name) { name.toLowerCase() === "package.json" || name.toLowerCase() === "favicon.ico" ) { - return false; + return false } else { - return true; + return true } } @@ -24,31 +24,31 @@ module.exports.is_object = function(obj) { } module.exports.validate_metadata = function(object, name) { - assert(module.exports.is_object(object)); - assert.equal(object.name, name); - + assert(module.exports.is_object(object)) + assert.equal(object.name, name) + if (!module.exports.is_object(object['dist-tags'])) { - object['dist-tags'] = {}; + object['dist-tags'] = {} } - + if (!module.exports.is_object(object['versions'])) { - object['versions'] = {}; + object['versions'] = {} } - - return object; + + return object } module.exports.parse_tarball_url = function(_url) { - var url = URL.parse(_url); + var url = URL.parse(_url) - var path = url.path.replace(/^\//, '').split('/'); + var path = url.path.replace(/^\//, '').split('/') if (path.length >= 3 && path[path.length-2] === '-') { - var filename = path.pop(); - var pkgpath = '/' + filename; // tarball name - pkgpath = '/' + path.pop() + pkgpath; // "-" - pkgpath = '/' + path.pop() + pkgpath; // package.name + var filename = path.pop() + , pkgpath = '/' + filename // tarball name + pkgpath = '/' + path.pop() + pkgpath // "-" + pkgpath = '/' + path.pop() + pkgpath // package.name } else { - return null; + return null } return { @@ -57,33 +57,33 @@ module.exports.parse_tarball_url = function(_url) { prepath: '/' + path.join('/'), pkgpath: pkgpath, filename: filename, - }; + } } module.exports.filter_tarball_urls = function(pkg, req, config) { function filter(_url) { - if (!req.headers.host) return _url; + if (!req.headers.host) return _url - var url = module.exports.parse_tarball_url(_url); + var url = module.exports.parse_tarball_url(_url) // weird url, just return it - if (url == null) return _url; + if (url == null) return _url if (config.url_prefix != null) { - var result = config.url_prefix.replace(/\/$/, ''); + var result = config.url_prefix.replace(/\/$/, '') } else { - var result = req.protocol + '://' + req.headers.host; + var result = req.protocol + '://' + req.headers.host } - return result + url.pkgpath; + return result + url.pkgpath } for (var ver in pkg.versions) { if (pkg.versions[ver].dist != null && pkg.versions[ver].dist.tarball != null) { - pkg.versions[ver].dist.__sinopia_orig_tarball = pkg.versions[ver].dist.tarball; - pkg.versions[ver].dist.tarball = filter(pkg.versions[ver].dist.tarball); + pkg.versions[ver].dist.__sinopia_orig_tarball = pkg.versions[ver].dist.tarball + pkg.versions[ver].dist.tarball = filter(pkg.versions[ver].dist.tarball) } } - return pkg; + return pkg }