From 789b82160d9691cb64ace5a65142ec15bef3ebab Mon Sep 17 00:00:00 2001 From: Lloyd Brookes Date: Wed, 15 Jun 2016 21:02:52 +0100 Subject: [PATCH] refactor --- bin/cli.js | 4 +-- extend/cache-control.js | 4 +-- lib/local-web-server.js | 40 ++++++++++--------------- lib/middleware-stack.js | 78 ++++++++++++++++++++++++------------------------- 4 files changed, 57 insertions(+), 69 deletions(-) diff --git a/bin/cli.js b/bin/cli.js index d12c404..49b1b98 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -1,8 +1,8 @@ #!/usr/bin/env node 'use strict' -const Cli = require('../') +const LocalWebServer = require('../') -const ws = new Cli() +const ws = new LocalWebServer() ws.middleware .addCors() .addJson() diff --git a/extend/cache-control.js b/extend/cache-control.js index db4e141..c25226e 100644 --- a/extend/cache-control.js +++ b/extend/cache-control.js @@ -1,11 +1,11 @@ 'use strict' -const Cli = require('../') +const LocalWebServer = require('../') const cacheControl = require('koa-cache-control') const cliData = require('../lib/cli-data') cliData.optionDefinitions.push({ name: 'maxage', group: 'misc' }) -const ws = new Cli() +const ws = new LocalWebServer() ws.middleware .addLogging('dev') .add(cacheControl({ diff --git a/lib/local-web-server.js b/lib/local-web-server.js index 4185ca4..24eb566 100644 --- a/lib/local-web-server.js +++ b/lib/local-web-server.js @@ -8,57 +8,47 @@ const Tool = require('command-line-tool') const tool = new Tool() class Cli { - constructor (options) { - this.options = null + constructor () { + this.options = collectOptions() this.app = null this.middleware = null - options = collectOptions() - this.options = options + const options = this.options if (options.misc.config) { tool.stop(JSON.stringify(options.server, null, ' '), 0) } else { const Koa = require('koa') const app = new Koa() - this.app = app - - const MiddlewareStack = require('./middleware-stack') - this.middleware = new MiddlewareStack(options) - const a = { - compress: options.server.compress, - mime: options.server.mime, - forbid: options.server.forbid, - spa: options.server.spa, - 'no-cache': options.server['no-cache'], - rewrite: options.server.rewrite, - verbose: options.server.verbose, - mocks: options.server.mocks - } - app.on('error', err => { if (options.server['log-format']) { console.error(ansi.format(err.message, 'red')) } }) + this.app = app + + const MiddlewareStack = require('./middleware-stack') + this.middleware = new MiddlewareStack(options) } } listen () { - this.app.use(this.middleware.getMiddleware()) + this.app.use(this.middleware.compose()) const options = this.options + const key = this.options.server.key + const cert = this.options.server.cert if (options.server.https) { - options.server.key = path.resolve(__dirname, '..', 'ssl', '127.0.0.1.key') - options.server.cert = path.resolve(__dirname, '..', 'ssl', '127.0.0.1.crt') + key = path.resolve(__dirname, '..', 'ssl', '127.0.0.1.key') + cert = path.resolve(__dirname, '..', 'ssl', '127.0.0.1.crt') } - if (options.server.key && options.server.cert) { + if (key && cert) { const https = require('https') const fs = require('fs') const serverOptions = { - key: fs.readFileSync(options.server.key), - cert: fs.readFileSync(options.server.cert) + key: fs.readFileSync(key), + cert: fs.readFileSync(cert) } const server = https.createServer(serverOptions, this.app.callback()) diff --git a/lib/middleware-stack.js b/lib/middleware-stack.js index e1a911e..94f3205 100644 --- a/lib/middleware-stack.js +++ b/lib/middleware-stack.js @@ -4,30 +4,16 @@ const path = require('path') const url = require('url') const debug = require('debug')('local-web-server') const mw = require('./middleware') +const t = require('typical') class MiddlewareStack extends Array { constructor (options) { super() this.options = options - options = Object.assign({ - cacheControl: {}, - spa: null, - compress: false, - mime: {}, - forbid: [], - rewrite: [], - verbose: false, - mocks: [] - }, options) - if (options.verbose) { process.env.DEBUG = '*' } - - options.rewrite = arrayify(options.rewrite) - options.forbid = arrayify(options.forbid) - options.mocks = arrayify(options.mocks) } add (middleware) { @@ -50,8 +36,8 @@ class MiddlewareStack extends Array { } /* rewrite rules */ - addRewrite () { - const options = this.options.rewrite + addRewrite (rewriteRules) { + const options = arrayify(this.options.server.rewrite || rewriteRules) if (options.length) { options.forEach(route => { if (route.to) { @@ -80,18 +66,26 @@ class MiddlewareStack extends Array { } /* path blacklist */ - addBlacklist () { - const options = this.options.forbid - if (options.length) { - debug('forbid', options.join(', ')) - this.push(mw.blacklist(options)) + addBlacklist (forbidList) { + forbidList = arrayify(this.options.server.forbid || forbidList) + if (forbidList.length) { + const pathToRegexp = require('path-to-regexp') + debug('forbid', forbidList.join(', ')) + this.push(function blacklist (ctx, next) { + if (forbidList.some(expression => pathToRegexp(expression).test(ctx.path))) { + ctx.throw(403, http.STATUS_CODES[403]) + } else { + return next() + } + }) } return this } /* cache */ addCache () { - if (!this.options['no-cache']) { + const noCache = this.options.server['no-cache'] + if (!noCache) { this.push(require('koa-conditional-get')()) this.push(require('koa-etag')()) } @@ -99,21 +93,23 @@ class MiddlewareStack extends Array { } /* mime-type overrides */ - addMimeType () { - const options = this.options.mime - if (options) { - debug('mime override', JSON.stringify(options)) - this.push(mw.mime(options)) + addMimeType (mime) { + mime = this.options.server.mime || mime + if (mime) { + debug('mime override', JSON.stringify(mime)) + this.push(mw.mime(mime)) } return this } /* compress response */ - addCompression () { - if (this.options.compress) { - const compress = require('koa-compress') + addCompression (compress) { + compress = t.isDefined(this.options.server.compress) + ? this.options.server.compress + : compress + if (compress) { debug('compression', 'enabled') - this.push(compress()) + this.push(require('koa-compress')()) } return this } @@ -148,10 +144,11 @@ class MiddlewareStack extends Array { } /* Mock Responses */ - addMockResponses () { - const options = this.options.mocks - options.forEach(mock => { + addMockResponses (mocks) { + mocks = arrayify(this.options.server.mocks || mocks) + mocks.forEach(mock => { if (mock.module) { + // TODO: ENSURE this.options.static.root is correct value mock.responses = require(path.resolve(path.join(this.options.static.root, mock.module))) } @@ -169,12 +166,13 @@ class MiddlewareStack extends Array { } /* for any URL not matched by static (e.g. `/search`), serve the SPA */ - addSpa () { - if (this.options.spa) { + addSpa (spa) { + spa = t.isDefined(this.options.server.spa) ? this.options.server.spa : spa + if (spa) { const historyApiFallback = require('koa-connect-history-api-fallback') - debug('SPA', this.options.spa) + debug('SPA', spa) this.push(historyApiFallback({ - index: this.options.spa, + index: spa, verbose: this.options.verbose })) } @@ -203,7 +201,7 @@ class MiddlewareStack extends Array { return this } - getMiddleware (options) { + compose (options) { const compose = require('koa-compose') const convert = require('koa-convert') const middlewareStack = this.map(convert)