diff --git a/lib/local-web-server.js b/lib/local-web-server.js index 1857cbe..72c6e48 100644 --- a/lib/local-web-server.js +++ b/lib/local-web-server.js @@ -5,6 +5,7 @@ const path = require('path') const arrayify = require('array-back') const t = require('typical') const CommandLineTool = require('command-line-tool') +const flatten = require('reduce-flatten') /** * @module local-web-server @@ -22,18 +23,37 @@ class LocalWebServer { const commandLineUsage = require('command-line-usage') const cli = require('../lib/cli-data') - let stackPath + /* manually scan for any --stack passed, as we may need to display stack options */ + const stackPaths = [] const stackIndex = process.argv.indexOf('--stack') if (stackIndex > -1) { - stackPath = process.argv[stackIndex + 1] - if (/^-/.test(stackPath)) stackPath = null + for (var i = stackIndex + 1; i < process.argv.length; i++) { + const stackPath = process.argv[i] + if (/^-/.test(stackPath)) { + break + } else { + stackPaths.push(stackPath) + } + } } - const stackModule = loadStack(stackPath) || require('local-web-server-default-stack') - this.stack = new stackModule() - this.stack.addAll() - const middlewareOptionDefinitions = this.stack.getOptionDefinitions() - // console.log(middlewareOptionDefinitions) + /* load the stack */ + // if (!stackPaths.length) stackPaths.push('local-web-server-default-stack') + // console.log(stackPaths) + const stackModules = stackPaths + .map(stackPath => loadStack(stackPath)) + .map(Middleware => new Middleware()) + + /* gather stack option definitions and parse the command line */ + const middlewareOptionDefinitions = stackModules + .filter(mw => mw.optionDefinitions) + .map(mw => mw.optionDefinitions()) + .reduce(flatten, []) + .map(def => { + def.group = 'middleware' + return def + }) + const usage = commandLineUsage(cli.usage(middlewareOptionDefinitions)) let options = {} @@ -44,31 +64,48 @@ class LocalWebServer { tool.halt(err) } + /* combine in stored config */ const loadConfig = require('config-master') const stored = loadConfig('local-web-server') - /* override stored config with command line options */ options = Object.assign(stored, options.server, options.middleware, options.misc) this.options = options + // console.log(options) + if (options.verbose) { // debug.setLevel(1) } + + /* --config */ if (options.config) { tool.stop(JSON.stringify(options, null, ' '), 0) + + /* --version */ } else if (options.version) { const pkg = require(path.resolve(__dirname, '..', 'package.json')) tool.stop(pkg.version) + + /* --help */ + } else if (options.help) { + tool.stop(usage) } else { - if (this.options.help) { - tool.stop(usage) - } + const compose = require('koa-compose') + const convert = require('koa-convert') + const middlewareStack = stackModules + .filter(mw => mw.middleware) + .map(mw => mw.middleware) + .map(middleware => middleware(options)) + .filter(middleware => middleware) + .reduce(flatten, []) + .map(convert) + this.stack = compose(middlewareStack) } } getApplication (options) { const Koa = require('koa') const app = new Koa() - app.use(this.stack.compose(this.options)) + app.use(this.stack) return app } @@ -163,23 +200,32 @@ function collectUserOptions (mwOptionDefinitions) { return options } +/** + * Loads a module by either path or name. + * @returns {object} + */ function loadStack (modulePath) { let module if (modulePath) { const fs = require('fs') try { module = require(path.resolve(modulePath)) - if (!module.prototype.addAll) { - tool.halt(new Error('Must supply a MiddlewareStack')) - } } catch (err) { const walkBack = require('walk-back') - const foundPath = walkBack(path.resolve(process.cwd(), 'node_modules'), modulePath) + const foundPath = walkBack(process.cwd(), path.join('node_modules', 'local-web-server-' + modulePath)) if (foundPath) { module = require(foundPath) + } else { + const foundPath2 = walkBack(process.cwd(), path.join('node_modules', modulePath)) + if (foundPath2) { + module = require(foundPath2) + } } } } + if (!module.prototype.middleware) { + tool.halt(new Error('Must supply a Middleware')) + } return module }