refactor.. feature.ready() method.. --stack paths now scan ws modules

This commit is contained in:
Lloyd Brookes
2017-01-30 22:59:50 +00:00
parent f9b3a69f19
commit 698864299a
4 changed files with 100 additions and 61 deletions

44
lib/feature.js Normal file
View File

@ -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

View File

@ -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.<anonymous> (/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')

View File

@ -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) {}
}