refactor, tests
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
***Requires node v4.0.0 or higher. Install the [previous release](https://github.com/75lb/local-web-server/tree/prev) for older node support.***
|
||||
|
||||
# local-web-server
|
||||
An application shell for building a simple, command-line web server for productive web development.
|
||||
An application shell for building a simple, command-line web server for productive web development. It contains no middleware of its own but will load default-stack unless you specify otherwise.
|
||||
|
||||
It is trivial is bundle and deploy with your project. Also deploys to heroku well for demo projects.
|
||||
|
||||
|
@ -4,7 +4,7 @@ exports.optionDefinitions = [
|
||||
description: 'Web server port.', group: 'server'
|
||||
},
|
||||
{
|
||||
name: 'stack', type: String,
|
||||
name: 'stack', type: String, multiple: true,
|
||||
description: 'Middleware stack.', group: 'server'
|
||||
},
|
||||
{
|
||||
|
@ -18,13 +18,14 @@ const tool = new CommandLineTool()
|
||||
* @extends module:middleware-stack
|
||||
*/
|
||||
class LocalWebServer {
|
||||
constructor (stack) {
|
||||
constructor (initOptions) {
|
||||
initOptions = initOptions || {}
|
||||
const commandLineArgs = require('command-line-args')
|
||||
const commandLineUsage = require('command-line-usage')
|
||||
const cli = require('../lib/cli-data')
|
||||
|
||||
/* manually scan for any --stack passed, as we may need to display stack options */
|
||||
const stackPaths = []
|
||||
const stackPaths = initOptions.stack || []
|
||||
const stackIndex = process.argv.indexOf('--stack')
|
||||
if (stackIndex > -1) {
|
||||
for (var i = stackIndex + 1; i < process.argv.length; i++) {
|
||||
@ -38,11 +39,30 @@ class LocalWebServer {
|
||||
}
|
||||
|
||||
/* load the stack */
|
||||
// if (!stackPaths.length) stackPaths.push('local-web-server-default-stack')
|
||||
// console.log(stackPaths)
|
||||
if (!stackPaths.length) stackPaths.push(path.resolve(__dirname, '..', 'node_modules', 'local-web-server-default-stack'))
|
||||
const stackModules = stackPaths
|
||||
.map(stackPath => loadStack(stackPath))
|
||||
.map(Middleware => new Middleware())
|
||||
.map(module => {
|
||||
if (module.stack) {
|
||||
const featureStack = module.stack()
|
||||
module.optionDefinitions = function () {
|
||||
return featureStack
|
||||
.map(Feature => new Feature())
|
||||
.map(feature => feature.optionDefinitions && feature.optionDefinitions())
|
||||
.filter(definitions => definitions)
|
||||
.reduce(flatten, [])
|
||||
}
|
||||
module.middleware = function (options) {
|
||||
return featureStack
|
||||
.map(Feature => new Feature())
|
||||
.map(feature => feature.middleware(options))
|
||||
.reduce(flatten, [])
|
||||
.filter(mw => mw)
|
||||
}
|
||||
}
|
||||
return module
|
||||
})
|
||||
|
||||
/* gather stack option definitions and parse the command line */
|
||||
const middlewareOptionDefinitions = stackModules
|
||||
@ -67,11 +87,9 @@ class LocalWebServer {
|
||||
/* combine in stored config */
|
||||
const loadConfig = require('config-master')
|
||||
const stored = loadConfig('local-web-server')
|
||||
options = Object.assign(stored, options.server, options.middleware, options.misc)
|
||||
options = Object.assign({ port: 8000 }, initOptions, stored, options.server, options.middleware, options.misc)
|
||||
this.options = options
|
||||
|
||||
// console.log(options)
|
||||
|
||||
if (options.verbose) {
|
||||
// debug.setLevel(1)
|
||||
}
|
||||
@ -95,33 +113,32 @@ class LocalWebServer {
|
||||
.filter(mw => mw.middleware)
|
||||
.map(mw => mw.middleware)
|
||||
.map(middleware => middleware(options))
|
||||
.filter(middleware => middleware)
|
||||
.reduce(flatten, [])
|
||||
.filter(middleware => middleware)
|
||||
.map(convert)
|
||||
this.stack = compose(middlewareStack)
|
||||
}
|
||||
}
|
||||
|
||||
getApplication (options) {
|
||||
getApplication () {
|
||||
const Koa = require('koa')
|
||||
const app = new Koa()
|
||||
app.use(this.stack)
|
||||
return app
|
||||
}
|
||||
|
||||
getServer (options) {
|
||||
const app = this.getApplication(options)
|
||||
options = this.options
|
||||
let key = options.key
|
||||
let cert = options.cert
|
||||
|
||||
app.on('error', err => {
|
||||
if (options['log-format']) {
|
||||
if (this.options['log-format']) {
|
||||
console.error(ansi.format(err.stack, 'red'))
|
||||
}
|
||||
})
|
||||
return app
|
||||
}
|
||||
|
||||
if (options.https) {
|
||||
getServer () {
|
||||
const app = this.getApplication()
|
||||
const options = this.options
|
||||
let key = options.key
|
||||
let cert = options.cert
|
||||
|
||||
if (options.https && !(key && cert)) {
|
||||
key = path.resolve(__dirname, '..', 'ssl', '127.0.0.1.key')
|
||||
cert = path.resolve(__dirname, '..', 'ssl', '127.0.0.1.crt')
|
||||
}
|
||||
@ -144,15 +161,19 @@ class LocalWebServer {
|
||||
return server
|
||||
}
|
||||
|
||||
listen (options, callback) {
|
||||
options = this.options
|
||||
const server = this.getServer()
|
||||
const port = options.port || 8000
|
||||
server.listen(port, () => {
|
||||
onServerUp(port, options.directory, server.isHttps)
|
||||
if (callback) callback()
|
||||
listen () {
|
||||
const options = this.options
|
||||
const server = this._server = this.getServer()
|
||||
return new Promise ((resolve, reject) => {
|
||||
server.listen(options.port, () => {
|
||||
onServerUp(options.port, options.directory, server.isHttps)
|
||||
resolve(server)
|
||||
})
|
||||
})
|
||||
return server
|
||||
}
|
||||
|
||||
close () {
|
||||
this._server.close()
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,8 +244,8 @@ function loadStack (modulePath) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!module.prototype.middleware) {
|
||||
tool.halt(new Error('Must supply a Middleware'))
|
||||
if (!(module && (module.prototype.middleware || module.prototype.stack))) {
|
||||
tool.halt(new Error('Not valid Middleware: ' + modulePath))
|
||||
}
|
||||
return module
|
||||
}
|
||||
|
@ -46,6 +46,7 @@
|
||||
"jsdoc-to-markdown": "^1.3.6",
|
||||
"koa-cache-control": "^1.0.0",
|
||||
"koa-livereload": "~0.2.0",
|
||||
"node-fetch": "^1.5.3",
|
||||
"req-then": "~0.2.4",
|
||||
"tape": "^4.6.0"
|
||||
}
|
||||
|
12
test/test-middleware.js
Normal file
12
test/test-middleware.js
Normal file
@ -0,0 +1,12 @@
|
||||
'use strict'
|
||||
|
||||
class TestMiddleware {
|
||||
middleware (option) {
|
||||
return function (ctx, next) {
|
||||
ctx.body = '1234512345'
|
||||
return next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TestMiddleware
|
36
test/test.js
Normal file
36
test/test.js
Normal file
@ -0,0 +1,36 @@
|
||||
'use strict'
|
||||
const test = require('tape')
|
||||
const request = require('req-then')
|
||||
const LocalWebServer = require('../')
|
||||
const c = require('./common')
|
||||
const path = require('path')
|
||||
|
||||
test('stack', function (t) {
|
||||
t.plan(2)
|
||||
const ws = new LocalWebServer({
|
||||
stack: [ path.resolve(__dirname, 'test-middleware.js') ]
|
||||
})
|
||||
const server = ws.getServer()
|
||||
server.listen(8100, () => {
|
||||
request('http://localhost:8100/')
|
||||
.then(c.checkResponse(t, 200, /1234512345/))
|
||||
.then(server.close.bind(server))
|
||||
.catch(c.fail(t))
|
||||
})
|
||||
})
|
||||
|
||||
test('https', function (t) {
|
||||
t.plan(2)
|
||||
const ws = new LocalWebServer({
|
||||
stack: [ path.resolve(__dirname, 'test-middleware.js') ],
|
||||
https: true,
|
||||
port: 8100
|
||||
})
|
||||
ws.listen()
|
||||
.then(() => {
|
||||
request('https://localhost:8100/')
|
||||
.then(c.checkResponse(t, 200, /1234512345/))
|
||||
.then(ws.close.bind(ws))
|
||||
.catch(c.fail(t))
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user