refactor.. feature.ready() method.. --stack paths now scan ws modules
This commit is contained in:
44
lib/feature.js
Normal file
44
lib/feature.js
Normal 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
|
@ -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')
|
||||
|
@ -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) {}
|
||||
}
|
Reference in New Issue
Block a user