From 67f047e80474bdf18585c168f4efa8e9dc5725b9 Mon Sep 17 00:00:00 2001 From: Drew Butler Date: Thu, 11 Jan 2018 13:29:48 -0600 Subject: [PATCH 1/5] Update node engine to 8.9.4 --- package.json | 58 +++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 0a19b49..a90173a 100644 --- a/package.json +++ b/package.json @@ -1,28 +1,34 @@ { - "name": "shorty" - , "version": "0.0.1" - , "engines": { - "node": "4.x.x" - } - , "scripts": { - "start": "node app.js" - } - , "contributors": [ - { "name": "Guillermo Rauch", "email": "guillermo@learnboost.com" } - , { "name": "TJ Holowaychuk", "email": "tj@learnboost.com" } - ] - , "dependencies": { - "express": "~2.5.10" - , "socket.io": "~1.4.8" - , "redis": "~2.6.2" - , "redis-lock": "~0.0.2" - , "jade": "~0.26.3" - , "jadevu": "~0.0.7" - , "stylus": "~0.28.2" - , "nib": "~0.7.0" - } - , "repository": { - "type": "git" - , "url": "https://github.com/LearnBoost/shorty.git" - } + "name": "shorty", + "version": "0.0.1", + "engines": { + "node": "8.9.4" + }, + "scripts": { + "start": "node app.js" + }, + "contributors": [ + { + "name": "Guillermo Rauch", + "email": "guillermo@learnboost.com" + }, + { + "name": "TJ Holowaychuk", + "email": "tj@learnboost.com" + } + ], + "dependencies": { + "express": "~2.5.10", + "socket.io": "~1.4.8", + "redis": "~2.6.2", + "redis-lock": "~0.0.2", + "jade": "~0.26.3", + "jadevu": "~0.0.7", + "stylus": "~0.28.2", + "nib": "~0.7.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/LearnBoost/shorty.git" + } } From d72fe2e6de0a40edb802b7f52e67987d8d2da870 Mon Sep 17 00:00:00 2001 From: Drew Butler Date: Thu, 11 Jan 2018 13:30:20 -0600 Subject: [PATCH 2/5] Move config to a env config object for easier updating --- app.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/app.js b/app.js index d227e61..5c9255d 100644 --- a/app.js +++ b/app.js @@ -19,13 +19,19 @@ var express = require('express') var env = process.env.NODE_ENV || 'development'; +const config = { + port: process.env.PORT || 3000, + domain: process.env.SHORTY_DOMAIN || 'https://lrn.cc', + redis_url: process.env.SHORTY_REDIS_URL || 'http://localhost:2343', + basic_auth: process.env.SHORTY_BASIC_AUTH || null, + +} + /** * Create db. */ -redis = require('redis').createClient( - process.env.SHORTY_REDIS_URL -); +redis = require('redis').createClient(config.redis_url); /** * Redis lock. @@ -48,8 +54,8 @@ app = module.exports = express.createServer(); if ('development' == env) { app.use(express.logger('dev')); } -if (process.env.SHORTY_BASIC_AUTH) { - app.use(express.basicAuth.apply(null, process.env.SHORTY_BASIC_AUTH.split(':'))); +if (config.basic_auth) { + app.use(express.basicAuth.apply(null, config.basic_auth.split(':'))); } app.use(express.bodyParser()); app.use(stylus.middleware({ src: __dirname + '/public/', compile: css })); @@ -94,7 +100,7 @@ function css (str, path) { app.configure(function () { app.set('views', __dirname); app.set('view engine', 'jade'); - app.set('domain', process.env.SHORTY_DOMAIN || 'https://lrn.cc'); + app.set('domain', config.domain); }); /** @@ -293,7 +299,7 @@ app.get('/:short', function (req, res, next) { */ if (!module.parent) { - app.listen(process.env.PORT || 3000, function () { + app.listen(config.port, function () { var addr = app.address(); console.error(' app listening on ' + addr.address + ':' + addr.port); }); From 73385054fc28dca00ae00a19ae1c46c970a52d75 Mon Sep 17 00:00:00 2001 From: Drew Butler Date: Thu, 11 Jan 2018 13:59:24 -0600 Subject: [PATCH 3/5] Update dev redis url --- app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.js b/app.js index 5c9255d..55a37dc 100644 --- a/app.js +++ b/app.js @@ -22,7 +22,7 @@ var env = process.env.NODE_ENV || 'development'; const config = { port: process.env.PORT || 3000, domain: process.env.SHORTY_DOMAIN || 'https://lrn.cc', - redis_url: process.env.SHORTY_REDIS_URL || 'http://localhost:2343', + redis_url: process.env.SHORTY_REDIS_URL || 'redis:// localhost:6379', basic_auth: process.env.SHORTY_BASIC_AUTH || null, } From 11359f02eb7b058e5c57ab61356d06a35326944a Mon Sep 17 00:00:00 2001 From: Drew Butler Date: Thu, 11 Jan 2018 17:23:24 -0600 Subject: [PATCH 4/5] Updated to use the latest versions of libraries and removed the stats/socket.io functionality that we no longer need. --- 404.jade | 3 - app.js | 114 ++--- index.jade | 5 - layout.jade | 22 - base60.js => lib/base60.js | 0 package-lock.json | 991 +++++++++++++++++++++++++++++++++++++ package.json | 24 +- public/css/stats.styl | 48 -- public/js/date.js | 17 - public/js/index.js | 8 - public/js/stats.js | 25 - stats.jade | 30 -- views/404.pug | 4 + views/index.pug | 5 + views/layout.pug | 27 + 15 files changed, 1073 insertions(+), 250 deletions(-) delete mode 100644 404.jade delete mode 100644 index.jade delete mode 100644 layout.jade rename base60.js => lib/base60.js (100%) create mode 100644 package-lock.json delete mode 100644 public/css/stats.styl delete mode 100644 public/js/date.js delete mode 100644 public/js/index.js delete mode 100644 public/js/stats.js delete mode 100644 stats.jade create mode 100644 views/404.pug create mode 100644 views/index.pug create mode 100644 views/layout.pug diff --git a/404.jade b/404.jade deleted file mode 100644 index a8352a5..0000000 --- a/404.jade +++ /dev/null @@ -1,3 +0,0 @@ -link(href="/css/index.css", rel="stylesheet") - -p Sorry! that link doesn't exist. \ No newline at end of file diff --git a/app.js b/app.js index 55a37dc..30be4db 100644 --- a/app.js +++ b/app.js @@ -5,9 +5,11 @@ var express = require('express') , stylus = require('stylus') - , sio = require('socket.io') - , base60 = require('./base60') - , jadevu = require('jadevu') + , http = require('http') + , base60 = require('./lib/base60') + , morgan = require('morgan') + , bodyParser = require('body-parser') + , errorHandler = require('errorhandler') , crypto = require('crypto') , url = require('url') , nib = require('nib') @@ -22,8 +24,7 @@ var env = process.env.NODE_ENV || 'development'; const config = { port: process.env.PORT || 3000, domain: process.env.SHORTY_DOMAIN || 'https://lrn.cc', - redis_url: process.env.SHORTY_REDIS_URL || 'redis:// localhost:6379', - basic_auth: process.env.SHORTY_BASIC_AUTH || null, + redis_url: process.env.SHORTY_REDIS_URL || 'redis://localhost:6379', } @@ -45,32 +46,21 @@ var lock = require('redis-lock')(redis).bind(null, 'shorty-lock', 10000); * Create app. */ -app = module.exports = express.createServer(); - +var app = module.exports = express(); +var server = http.createServer(app); /** * Basic middleware. */ if ('development' == env) { - app.use(express.logger('dev')); -} -if (config.basic_auth) { - app.use(express.basicAuth.apply(null, config.basic_auth.split(':'))); + app.use(morgan('dev')); } -app.use(express.bodyParser()); + +app.use(bodyParser.urlencoded({ extended: true })); +app.use(bodyParser.json()); app.use(stylus.middleware({ src: __dirname + '/public/', compile: css })); app.use(express.static(__dirname + '/public')); -/** - * Socket.IO - */ - -var io = sio.listen(app); - -// quiet :) - -io.set('log level', 0); - /** * Reads a file * @@ -97,27 +87,9 @@ function css (str, path) { * Configure app. */ -app.configure(function () { - app.set('views', __dirname); - app.set('view engine', 'jade'); - app.set('domain', config.domain); -}); - -/** - * Development configuration. - */ - -app.configure('development', function () { - app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); -}); - -/** - * Production configuration. - */ - -app.configure('production', function () { - app.use(express.errorHandler()); -}); +app.set('views', __dirname + '/views'); +app.set('view engine', 'pug'); +app.set('domain', config.domain); /** * GET index page. @@ -182,8 +154,6 @@ app.post('/', validate, exists, function (req, res, next) { if (err) return next(500); obj.parsed = parsed; - io.of('/main').volatile.emit('total', length + 1); - io.of('/stats').volatile.emit('url created', short, parsed, Date.now()); res.send({ short: app.set('domain') + '/' + short }); process.nextTick(unlock); @@ -232,33 +202,6 @@ function exists (req, res, next) { }); } -/** - * GET statistics. - */ - -app.get('/stats', accept('html'), function (req, res, next) { - redis.lrange('transactions', 0, 100, function (err, vals) { - if (err) return next(err); - res.render('stats', { transactions: vals ? vals.map(function (v) { - v = JSON.parse(v); - v.parsed = url.parse(v.url); - delete v.url; - return v; - }).reverse() : [] }); - }); -}); - -/** - * GET JSON statistics. - */ - -app.get('/stats', accept('json'), function (req, res, next) { - redis.lrange('transactions', 0, 100, function (err, vals) { - if (err) return next(err); - res.send(vals.map(JSON.parse)); - }); -}); - /** * GET :short url to perform redirect. */ @@ -266,7 +209,7 @@ app.get('/stats', accept('json'), function (req, res, next) { app.get('/:short', function (req, res, next) { redis.hget('urls', req.params.short, function (err, val) { if (err) return next(err); - if (!val) return res.render('404'); + if (!val) return res.status(404).render('404'); lock(function (unlock) { redis.lpush('transactions', JSON.stringify({ @@ -280,13 +223,6 @@ app.get('/:short', function (req, res, next) { if (err) console.error(err); }); - io.of('/stats').volatile.emit( - 'url visited' - , req.params.short - , url.parse(val) - , Date.now() - ); - res.redirect(val); process.nextTick(unlock); @@ -294,14 +230,26 @@ app.get('/:short', function (req, res, next) { }); }); + +/** + * Erorr handlers + */ +if (env === 'development') { + app.use(errorHandler()); + +} else if (env === 'production') { + app.use(function (err, req, res, next) { + res.status(500).json({ status: 'error' }); + }) +} + /** * Listen. */ if (!module.parent) { - app.listen(config.port, function () { - var addr = app.address(); - console.error(' app listening on ' + addr.address + ':' + addr.port); + server.listen(config.port, function () { + console.error(' app listening on http://localhost:' + config.port); }); process.on('uncaughtException', function (e) { diff --git a/index.jade b/index.jade deleted file mode 100644 index ee30264..0000000 --- a/index.jade +++ /dev/null @@ -1,5 +0,0 @@ -link(href="/css/index.css", rel="stylesheet") -script(src="/js/index.js") - -p Welcome to the LearnBoost redirection service! -p #{count} urls generated so far! diff --git a/layout.jade b/layout.jade deleted file mode 100644 index 1944d14..0000000 --- a/layout.jade +++ /dev/null @@ -1,22 +0,0 @@ -doctype 5 -html - head - title Shorty - script(src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js") - script(src="/socket.io/socket.io.js") - script(src="/js/animation.js") - :stylus - body - padding 20px 100px - font 14px/1.4 'helvetica neue', helvetica, arial, sans-serif - h1 - font-size 26px - span - background url(/images/man.png) no-repeat right - display inline-block - padding-right 30px - h2 - color #444 - body - h1: span Shorty - #wrap!= body diff --git a/base60.js b/lib/base60.js similarity index 100% rename from base60.js rename to lib/base60.js diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d6a4271 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,991 @@ +{ + "name": "shorty", + "version": "0.0.2", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "accepts": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", + "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", + "requires": { + "mime-types": "2.1.17", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + }, + "acorn-globals": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", + "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "basic-auth": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz", + "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.1", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "1.6.15" + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", + "requires": { + "is-regex": "1.0.4" + } + }, + "clean-css": { + "version": "3.4.28", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz", + "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=", + "requires": { + "commander": "2.8.1", + "source-map": "0.4.4" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + } + }, + "commander": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", + "requires": { + "graceful-readlink": "1.0.1" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "constantinople": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.0.tgz", + "integrity": "sha1-dWnKqKo/jVk11i4fqW+fcCzYHHk=", + "requires": { + "acorn": "3.3.0", + "is-expression": "2.1.0" + } + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "css-parse": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", + "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" + }, + "double-ended-queue": { + "version": "2.1.0-0", + "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" + }, + "errorhandler": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.0.tgz", + "integrity": "sha1-6rpkyl1UKjEayUX1gt78M2Fl2fQ=", + "requires": { + "accepts": "1.3.4", + "escape-html": "1.0.3" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", + "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", + "requires": { + "accepts": "1.3.4", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "1.1.1", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.8.1", + "finalhandler": "1.1.0", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "2.0.2", + "qs": "6.5.1", + "range-parser": "1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.1", + "serve-static": "1.13.1", + "setprototypeof": "1.1.0", + "statuses": "1.3.1", + "type-is": "1.6.15", + "utils-merge": "1.0.1", + "vary": "1.1.2" + }, + "dependencies": { + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + } + } + }, + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "requires": { + "debug": "2.6.9", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.3.1", + "unpipe": "1.0.0" + }, + "dependencies": { + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + } + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "glob": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", + "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "requires": { + "function-bind": "1.1.1" + } + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.4.0" + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", + "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-expression": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-2.1.0.tgz", + "integrity": "sha1-kb6dR968/vB3l36XIr5tz7RGXvA=", + "requires": { + "acorn": "3.3.0", + "object-assign": "4.1.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "1.0.1" + } + }, + "js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" + }, + "jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", + "requires": { + "is-promise": "2.1.0", + "promise": "7.3.1" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "1.1.6" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "requires": { + "mime-db": "1.30.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "morgan": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz", + "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=", + "requires": { + "basic-auth": "2.0.0", + "debug": "2.6.9", + "depd": "1.1.1", + "on-finished": "2.3.0", + "on-headers": "1.0.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "nib": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/nib/-/nib-1.1.2.tgz", + "integrity": "sha1-amnt5AgblcDe+L4CSkyK4MLLtsc=", + "requires": { + "stylus": "0.54.5" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "2.0.6" + } + }, + "proxy-addr": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", + "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", + "requires": { + "forwarded": "0.1.2", + "ipaddr.js": "1.5.2" + } + }, + "pug": { + "version": "2.0.0-rc.4", + "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.0-rc.4.tgz", + "integrity": "sha512-SL7xovj6E2Loq9N0UgV6ynjMLW4urTFY/L/Fprhvz13Xc5vjzkjZjI1QHKq31200+6PSD8PyU6MqrtCTJj6/XA==", + "requires": { + "pug-code-gen": "2.0.0", + "pug-filters": "2.1.5", + "pug-lexer": "3.1.0", + "pug-linker": "3.0.3", + "pug-load": "2.0.9", + "pug-parser": "4.0.0", + "pug-runtime": "2.0.3", + "pug-strip-comments": "1.0.2" + } + }, + "pug-attrs": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.2.tgz", + "integrity": "sha1-i+KyIlVo/6ddG4Zpgr/59BEa/8s=", + "requires": { + "constantinople": "3.1.0", + "js-stringify": "1.0.2", + "pug-runtime": "2.0.3" + } + }, + "pug-code-gen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.0.tgz", + "integrity": "sha512-E4oiJT+Jn5tyEIloj8dIJQognbiNNp0i0cAJmYtQTFS0soJ917nlIuFtqVss3IXMEyQKUew3F4gIkBpn18KbVg==", + "requires": { + "constantinople": "3.1.0", + "doctypes": "1.1.0", + "js-stringify": "1.0.2", + "pug-attrs": "2.0.2", + "pug-error": "1.3.2", + "pug-runtime": "2.0.3", + "void-elements": "2.0.1", + "with": "5.1.1" + } + }, + "pug-error": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.2.tgz", + "integrity": "sha1-U659nSm7A89WRJOgJhCfVMR/XyY=" + }, + "pug-filters": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-2.1.5.tgz", + "integrity": "sha512-xkw71KtrC4sxleKiq+cUlQzsiLn8pM5+vCgkChW2E6oNOzaqTSIBKIQ5cl4oheuDzvJYCTSYzRaVinMUrV4YLQ==", + "requires": { + "clean-css": "3.4.28", + "constantinople": "3.1.0", + "jstransformer": "1.0.0", + "pug-error": "1.3.2", + "pug-walk": "1.1.5", + "resolve": "1.5.0", + "uglify-js": "2.8.29" + } + }, + "pug-lexer": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-3.1.0.tgz", + "integrity": "sha1-/QhzdtSmdbT1n4/vQiiDQ06VgaI=", + "requires": { + "character-parser": "2.2.0", + "is-expression": "3.0.0", + "pug-error": "1.3.2" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + }, + "is-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz", + "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=", + "requires": { + "acorn": "4.0.13", + "object-assign": "4.1.1" + } + } + } + }, + "pug-linker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.3.tgz", + "integrity": "sha512-DCKczglCXOzJ1lr4xUj/lVHYvS+lGmR2+KTCjZjtIpdwaN7lNOoX2SW6KFX5X4ElvW+6ThwB+acSUg08UJFN5A==", + "requires": { + "pug-error": "1.3.2", + "pug-walk": "1.1.5" + } + }, + "pug-load": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.9.tgz", + "integrity": "sha512-BDdZOCru4mg+1MiZwRQZh25+NTRo/R6/qArrdWIf308rHtWA5N9kpoUskRe4H6FslaQujC+DigH9LqlBA4gf6Q==", + "requires": { + "object-assign": "4.1.1", + "pug-walk": "1.1.5" + } + }, + "pug-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-4.0.0.tgz", + "integrity": "sha512-ocEUFPdLG9awwFj0sqi1uiZLNvfoodCMULZzkRqILryIWc/UUlDlxqrKhKjAIIGPX/1SNsvxy63+ayEGocGhQg==", + "requires": { + "pug-error": "1.3.2", + "token-stream": "0.0.1" + } + }, + "pug-runtime": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.3.tgz", + "integrity": "sha1-mBYmB7D86eJU1CfzOYelrucWi9o=" + }, + "pug-strip-comments": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.2.tgz", + "integrity": "sha1-0xOvoBvMN0mA4TmeI+vy65vchRM=", + "requires": { + "pug-error": "1.3.2" + } + }, + "pug-walk": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.5.tgz", + "integrity": "sha512-rJlH1lXerCIAtImXBze3dtKq/ykZMA4rpO9FnPcIgsWcxZLOvd8zltaoeOVFyBSSqCkhhJWbEbTMga8UxWUUSA==" + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + } + }, + "redis": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", + "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", + "requires": { + "double-ended-queue": "2.1.0-0", + "redis-commands": "1.3.1", + "redis-parser": "2.6.0" + } + }, + "redis-commands": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz", + "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs=" + }, + "redis-lock": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/redis-lock/-/redis-lock-0.1.4.tgz", + "integrity": "sha512-7/+zu86XVQfJVx1nHTzux5reglDiyUCDwmW7TSlvVezfhH2YLc/Rc8NE0ejQG+8/0lwKzm29/u/4+ogKeLosiA==" + }, + "redis-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", + "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "requires": { + "path-parse": "1.0.5" + } + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "requires": { + "align-text": "0.1.4" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "sax": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=" + }, + "send": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", + "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", + "requires": { + "debug": "2.6.9", + "depd": "1.1.1", + "destroy": "1.0.4", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.8.1", + "fresh": "0.5.2", + "http-errors": "1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.3.1" + }, + "dependencies": { + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + } + } + }, + "serve-static": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", + "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", + "requires": { + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "parseurl": "1.3.2", + "send": "0.16.1" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "requires": { + "amdefine": "1.0.1" + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, + "stylus": { + "version": "0.54.5", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", + "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", + "requires": { + "css-parse": "1.7.0", + "debug": "2.6.9", + "glob": "7.0.6", + "mkdirp": "0.5.1", + "sax": "0.5.8", + "source-map": "0.1.43" + } + }, + "token-stream": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz", + "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo=" + }, + "type-is": { + "version": "1.6.15", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", + "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.17" + } + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "optional": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=" + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "with": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz", + "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=", + "requires": { + "acorn": "3.3.0", + "acorn-globals": "3.1.0" + } + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } +} diff --git a/package.json b/package.json index a90173a..fb190b9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "shorty", - "version": "0.0.1", + "version": "0.0.2", + "license": "MIT", "engines": { "node": "8.9.4" }, @@ -15,17 +16,22 @@ { "name": "TJ Holowaychuk", "email": "tj@learnboost.com" + }, + { + "name": "Drew Butler", + "email": "drew.butler@automattic.com" } ], "dependencies": { - "express": "~2.5.10", - "socket.io": "~1.4.8", - "redis": "~2.6.2", - "redis-lock": "~0.0.2", - "jade": "~0.26.3", - "jadevu": "~0.0.7", - "stylus": "~0.28.2", - "nib": "~0.7.0" + "body-parser": "1.18.2", + "errorhandler": "1.5.0", + "express": "4.16.2", + "morgan": "1.9.0", + "nib": "1.1.2", + "pug": "2.0.0-rc.4", + "redis": "2.8.0", + "redis-lock": "0.1.4", + "stylus": "0.54.5" }, "repository": { "type": "git", diff --git a/public/css/stats.styl b/public/css/stats.styl deleted file mode 100644 index fc028b0..0000000 --- a/public/css/stats.styl +++ /dev/null @@ -1,48 +0,0 @@ - -.creation-stats -.visited-stats - width 460px - height 500px - float left - margin-right 20px - padding-right 20px - overflow auto - h3 - color #3B88D8 - margin-top 0 -.creation-stats - border-right 1px solid #ccc -.stat - padding 5px 10px 7px - background #fafafa - overflow hidden - div - font-size 11px - display inline-block - a - color #444 - text-decoration none - &:hover - text-decoration underline - .type - font-weight bold - text-transform uppercase - width 100px - .date - color #999 - width 80px - .short - width 40px - .url - width 220px - overflow hidden - height 15px - line-height 15px - &:nth-child(odd) - background #eee - -@keyframes fade - 0% - background-color inherit - 50% - background-color #ffff99 diff --git a/public/js/date.js b/public/js/date.js deleted file mode 100644 index e593d74..0000000 --- a/public/js/date.js +++ /dev/null @@ -1,17 +0,0 @@ -// By John Resig - licensed under MIT -function prettyDate (time) { - var date = new Date(time), - diff = (((new Date()).getTime() - date.getTime()) / 1000), - day_diff = Math.floor(diff / 86400); - if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 ) - return; - return day_diff == 0 && ( - diff < 60 && "just now" || - diff < 120 && "1 minute ago" || - diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" || - diff < 7200 && "1 hour ago" || - diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") || - day_diff == 1 && "Yesterday" || - day_diff < 7 && day_diff + " days ago" || - day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago"; -} diff --git a/public/js/index.js b/public/js/index.js deleted file mode 100644 index e39c8b0..0000000 --- a/public/js/index.js +++ /dev/null @@ -1,8 +0,0 @@ -window.onload = function () { - var el = document.getElementById('count'); - io.connect('/main') - .on('total', function (total) { - el.innerHTML = total; - $(el).animation('fade'); - }) -}; diff --git a/public/js/stats.js b/public/js/stats.js deleted file mode 100644 index a5098a4..0000000 --- a/public/js/stats.js +++ /dev/null @@ -1,25 +0,0 @@ -window.onload = function () { - function created (short, long, d, manual) { - var p = $('.creation-stats .stats'); - var t = template('url created', { short: short, url: long, date: d }).prependTo(p); - if (!manual) t.animation('fade'); - } - function visited (short, long, d, manual) { - var p = $('.visited-stats .stats'); - var t = template('url visited', { short: short, url: long, date: d }).prependTo(p); - if (!manual) t.animation('fade'); - } - - io.connect('/stats') - .on('url created', created) - .on('url visited', visited) - - for (var i = 0, l = transactions.length; i < l; i++) { - var t = transactions[i]; - if ('url created' == t.type) { - created(t.short, t.parsed, t.date, true); - } else { - visited(t.short, t.parsed, t.date, true); - } - } -}; diff --git a/stats.jade b/stats.jade deleted file mode 100644 index 3543dd4..0000000 --- a/stats.jade +++ /dev/null @@ -1,30 +0,0 @@ -link(href="/css/stats.css", rel="stylesheet") -script(src="/js/date.js") -script(src="/js/stats.js") - -h2 Real-time stats - -.creation-stats - h3 Creations - .stats - -.visited-stats - h3 Visits - .stats - -template(id="url created"): - .stat.creation - .type URL Created - .date= prettyDate(date) - .short /#{short} - .url #{url.hostname}#{url.pathname} - -template(id="url visited"): - .stat.visited - .type URL visited - .date= prettyDate(date) - .short /#{short} - .url #{url.hostname}#{url.pathname} - -script - var transactions = !{JSON.stringify(transactions)} diff --git a/views/404.pug b/views/404.pug new file mode 100644 index 0000000..92ac51a --- /dev/null +++ b/views/404.pug @@ -0,0 +1,4 @@ +extends layout.pug + +block content + p Sorry! that link doesn't exist. diff --git a/views/index.pug b/views/index.pug new file mode 100644 index 0000000..5e9996c --- /dev/null +++ b/views/index.pug @@ -0,0 +1,5 @@ +extends layout.pug + +block content + p Welcome to the LearnBoost redirection service! + p #{count} urls generated so far! diff --git a/views/layout.pug b/views/layout.pug new file mode 100644 index 0000000..3b18e90 --- /dev/null +++ b/views/layout.pug @@ -0,0 +1,27 @@ +doctype 5 +html + head + title Shorty + script(src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js") + script(src="/js/animation.js") + style(type='text/css'). + body { + padding: 20px 100px; + font: 14px/1.4 'helvetica neue', helvetica, arial, sans-serif; + } + h1 { + font-size: 26px; + } + h1 span { + background: url("/images/man.png") no-repeat right; + display: inline-block; + padding-right: 30px; + } + h2 { + color: #444; + } + block head + link(href="/css/index.css", rel="stylesheet") + body + h1: span Shorty + block content From c36eb82ec2efaaab33c493759265af7b56cc2946 Mon Sep 17 00:00:00 2001 From: Drew Butler Date: Thu, 22 Feb 2018 10:26:37 +0700 Subject: [PATCH 5/5] Change version to 6.13.0, to match LearnBoost --- .gitignore | 1 + package.json | 16 +--------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 3c3629e..eb79dd5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +.idea diff --git a/package.json b/package.json index fb190b9..5836e4e 100644 --- a/package.json +++ b/package.json @@ -3,25 +3,11 @@ "version": "0.0.2", "license": "MIT", "engines": { - "node": "8.9.4" + "node": "6.13.0" }, "scripts": { "start": "node app.js" }, - "contributors": [ - { - "name": "Guillermo Rauch", - "email": "guillermo@learnboost.com" - }, - { - "name": "TJ Holowaychuk", - "email": "tj@learnboost.com" - }, - { - "name": "Drew Butler", - "email": "drew.butler@automattic.com" - } - ], "dependencies": { "body-parser": "1.18.2", "errorhandler": "1.5.0",