Browse Source

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

master
Lloyd Brookes 8 years ago
parent
commit
698864299a
  1. 44
      lib/feature.js
  2. 93
      lib/local-web-server.js
  3. 14
      lib/middleware.js
  4. 10
      package.json

44
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

93
lib/local-web-server.js

@ -1,22 +1,6 @@
#!/usr/bin/env node #!/usr/bin/env node
'use strict' '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 path = require('path')
const flatten = require('reduce-flatten') const flatten = require('reduce-flatten')
const arrayify = require('array-back') const arrayify = require('array-back')
@ -113,6 +97,12 @@ class LocalWebServer {
} else { } else {
this.view = new CliView(this) 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 return server
} }
/**
* Returns an array of Feature instances, given their module paths/names.
* @return {feature[]}
*/
_buildFeatureStack (featurePaths) { _buildFeatureStack (featurePaths) {
const FeatureBase = require('./feature')
return featurePaths 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 if (isModule(modulePath)) return modulePath
const module = loadModule(modulePath) const module = loadModule(modulePath)
if (module) { if (module) {
@ -238,6 +214,14 @@ function loadStack (modulePath) {
return module 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) { function loadModule (modulePath) {
let module let module
const tried = [] const tried = []
@ -256,6 +240,16 @@ function loadModule (modulePath) {
tried.push(modulePath) tried.push(modulePath)
if (foundPath2) { if (foundPath2) {
module = require(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 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 () { function getIPList () {
const flatten = require('reduce-flatten') const flatten = require('reduce-flatten')
const os = require('os') const os = require('os')

14
lib/middleware.js

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

10
package.json

@ -38,16 +38,16 @@
"author": "Lloyd Brookes <75pound@gmail.com>", "author": "Lloyd Brookes <75pound@gmail.com>",
"dependencies": { "dependencies": {
"ansi-escape-sequences": "^3.0.0", "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", "config-master": "^2.1.0-0",
"koa": "next", "koa": "next",
"koa-compose": "^3.1.0", "koa-compose": "^3.1.0",
"koa-convert": "^1.2.0", "koa-convert": "^1.2.0",
"local-web-server-default-stack": "github:local-web-server/default-stack", "local-web-server-default-stack": "github:local-web-server/default-stack",
"reduce-flatten": "^1.0.1", "reduce-flatten": "^1.0.1",
"table-layout": "~0.2.3",
"table-layout": "~0.4.0",
"typical": "^2.6.0", "typical": "^2.6.0",
"walk-back": "^2.0.1" "walk-back": "^2.0.1"
}, },
@ -56,6 +56,6 @@
"koa-cache-control": "^1.0.0", "koa-cache-control": "^1.0.0",
"koa-livereload": "~0.2.0", "koa-livereload": "~0.2.0",
"req-then": "~0.5.1", "req-then": "~0.5.1",
"tape": "^4.6.2"
"tape": "^4.6.3"
} }
} }
Loading…
Cancel
Save