From 698864299a61401d5ce2b995869217b80b131ea4 Mon Sep 17 00:00:00 2001 From: Lloyd Brookes Date: Mon, 30 Jan 2017 22:59:50 +0000 Subject: [PATCH] refactor.. feature.ready() method.. --stack paths now scan ws modules --- lib/feature.js | 44 +++++++++++++++++++++++ lib/local-web-server.js | 93 +++++++++++++++++++++++++++---------------------- lib/middleware.js | 14 -------- package.json | 10 +++--- 4 files changed, 100 insertions(+), 61 deletions(-) create mode 100644 lib/feature.js delete mode 100644 lib/middleware.js diff --git a/lib/feature.js b/lib/feature.js new file mode 100644 index 0000000..256bd0a --- /dev/null +++ b/lib/feature.js @@ -0,0 +1,44 @@ +'use strict' + +/** + * Feature interface. + */ +class Feature { + constructor (localWebServer) {} + + /** + * Return one or more options definitions to collect command-line input + * @returns {OptionDefinition|OptionDefinition[]} + */ + optionDefinitions () {} + + /** + * Return one of more middleware functions with three args (req, res and next). Can be created by express, Koa or hand-rolled. + */ + middleware (options) {} + + expandStack () { + const flatten = require('reduce-flatten') + + if (this.stack) { + const featureStack = this.stack() + .map(Feature => new Feature()) + + this.optionDefinitions = function () { + return featureStack + .map(feature => feature.optionDefinitions && feature.optionDefinitions()) + .filter(definitions => definitions) + .reduce(flatten, []) + } + this.middleware = function (options, view) { + return featureStack + .map(feature => feature.middleware(options, view)) + .reduce(flatten, []) + .filter(mw => mw) + } + } + return this + } +} + +module.exports = Feature diff --git a/lib/local-web-server.js b/lib/local-web-server.js index 31f095e..5f4c9fb 100644 --- a/lib/local-web-server.js +++ b/lib/local-web-server.js @@ -1,22 +1,6 @@ #!/usr/bin/env node 'use strict' -// /Users/lloydb/Documents/lws/local-web-server/lib/local-web-server.js:307 -// console.error(usage) -// ^ -// -// ReferenceError: usage is not defined -// at parseCommandLineOptions (/Users/lloydb/Documents/lws/local-web-server/lib/local-web-server.js:307:19) -// at new LocalWebServer (/Users/lloydb/Documents/lws/local-web-server/lib/local-web-server.js:46:47) -// at Object. (/Users/lloydb/Documents/lws/local-web-server/bin/cli.js:4:1) -// at Module._compile (module.js:556:32) -// at Object.Module._extensions..js (module.js:565:10) -// at Module.load (module.js:473:32) -// at tryModuleLoad (module.js:432:12) -// at Function.Module._load (module.js:424:3) -// at Module.runMain (module.js:590:10) -// at run (bootstrap_node.js:394:7) - const path = require('path') const flatten = require('reduce-flatten') const arrayify = require('array-back') @@ -113,6 +97,12 @@ class LocalWebServer { } else { this.view = new CliView(this) } + + for (const feature of this.features) { + if (feature.ready) { + feature.ready(this) + } + } } } @@ -188,39 +178,25 @@ class LocalWebServer { return server } + /** + * Returns an array of Feature instances, given their module paths/names. + * @return {feature[]} + */ _buildFeatureStack (featurePaths) { + const FeatureBase = require('./feature') return featurePaths - .map(featurePath => loadStack(featurePath)) - .map(Feature => new Feature()) - .map(feature => { - if (feature.stack) { - const featureStack = feature.stack() - .map(Feature => new Feature()) - - feature.optionDefinitions = function () { - return featureStack - .map(feature => feature.optionDefinitions && feature.optionDefinitions()) - .filter(definitions => definitions) - .reduce(flatten, []) - } - feature.middleware = function (options, view) { - return featureStack - .map(feature => feature.middleware(options, view)) - .reduce(flatten, []) - .filter(mw => mw) - } - } - return feature - }) + .map(featurePath => loadFeature(featurePath)) + .map(Feature => new Feature(this)) + .map(feature => FeatureBase.prototype.expandStack.call(feature)) } } /** - * Loads a module by either path or name. - * @returns {object} + * Load a module and verify it's of the correct type + * @returns {Feature} */ -function loadStack (modulePath) { - const isModule = module => module.prototype && (module.prototype.middleware || module.prototype.stack) +function loadFeature (modulePath) { + const isModule = module => module.prototype && (module.prototype.middleware || module.prototype.stack || module.prototype.ready) if (isModule(modulePath)) return modulePath const module = loadModule(modulePath) if (module) { @@ -238,6 +214,14 @@ function loadStack (modulePath) { return module } +/** + * Returns a module, loaded by the first to succeed from + * - direct path + * - 'node_modules/local-web-server-' + path, from current folder upward + * - 'node_modules/' + path, from current folder upward + * - also search local-web-server project node_modules? (e.g. to search for a feature module without need installing it locally) + * @returns {object} + */ function loadModule (modulePath) { let module const tried = [] @@ -256,6 +240,16 @@ function loadModule (modulePath) { tried.push(modulePath) if (foundPath2) { module = require(foundPath2) + } else { + const foundPath3 = walkBack(path.resolve(__filename, '..'), path.join('node_modules', 'local-web-server-' + modulePath)) + if (foundPath3) { + return require(foundPath3) + } else { + const foundPath4 = walkBack(path.resolve(__filename, '..'), path.join('node_modules', modulePath)) + if (foundPath4) { + return require(foundPath4) + } + } } } } @@ -263,6 +257,21 @@ function loadModule (modulePath) { return module } +/** + * Returns an array of available IPv4 network interfaces + * @example + * [ { address: 'mbp.local' }, + * { address: '127.0.0.1', + * netmask: '255.0.0.0', + * family: 'IPv4', + * mac: '00:00:00:00:00:00', + * internal: true }, + * { address: '192.168.1.86', + * netmask: '255.255.255.0', + * family: 'IPv4', + * mac: 'd0:a6:37:e9:86:49', + * internal: false } ] + */ function getIPList () { const flatten = require('reduce-flatten') const os = require('os') diff --git a/lib/middleware.js b/lib/middleware.js deleted file mode 100644 index 6b654b7..0000000 --- a/lib/middleware.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict' - -class Middleware { - /** - * Return one or more options definitions to collect command-line input - * @returns {OptionDefinition|OptionDefinition[]} - */ - optionDefinitions () {} - - /** - * Return one of more middleware functions with three args (req, res and next). Can be created by express, Koa or hand-rolled. - */ - middleware (localWebServer) {} -} diff --git a/package.json b/package.json index 0b18782..8fdfb78 100644 --- a/package.json +++ b/package.json @@ -38,16 +38,16 @@ "author": "Lloyd Brookes <75pound@gmail.com>", "dependencies": { "ansi-escape-sequences": "^3.0.0", - "array-back": "^1.0.3", - "command-line-args": "^3.0.2", - "command-line-usage": "^3.0.5", + "array-back": "^1.0.4", + "command-line-args": "^3.0.5", + "command-line-usage": "^4.0.0", "config-master": "^2.1.0-0", "koa": "next", "koa-compose": "^3.1.0", "koa-convert": "^1.2.0", "local-web-server-default-stack": "github:local-web-server/default-stack", "reduce-flatten": "^1.0.1", - "table-layout": "~0.2.3", + "table-layout": "~0.4.0", "typical": "^2.6.0", "walk-back": "^2.0.1" }, @@ -56,6 +56,6 @@ "koa-cache-control": "^1.0.0", "koa-livereload": "~0.2.0", "req-then": "~0.5.1", - "tape": "^4.6.2" + "tape": "^4.6.3" } }