diff --git a/bin/cli.js b/bin/cli.js
index 35c5a3c..019ce92 100755
--- a/bin/cli.js
+++ b/bin/cli.js
@@ -1,5 +1,4 @@
#!/usr/bin/env node
'use strict'
const LocalWebServer = require('../')
-const ws = new LocalWebServer()
-ws.getServer()
+new LocalWebServer()
diff --git a/doc/api.md b/doc/api.md
index b476b8d..4b4ccf0 100644
--- a/doc/api.md
+++ b/doc/api.md
@@ -5,10 +5,10 @@
* [LocalWebServer](#exp_module_local-web-server--LocalWebServer) ⇐ module:middleware-stack
⏏
* [new LocalWebServer([options])](#new_module_local-web-server--LocalWebServer_new)
* _instance_
- * [.view](#module_local-web-server--LocalWebServer.LocalWebServer+view) : View
* [.features](#module_local-web-server--LocalWebServer.LocalWebServer+features) : Array.<Feature>
* [.options](#module_local-web-server--LocalWebServer.LocalWebServer+options) : object
- * [.server](#module_local-web-server--LocalWebServer+server) : Server
+ * [.view](#module_local-web-server--LocalWebServer.LocalWebServer+view) : View
+ * [.server](#module_local-web-server--LocalWebServer.LocalWebServer+server) : Server
* [.getApplication()](#module_local-web-server--LocalWebServer+getApplication) ⇒ function
* [.getServer()](#module_local-web-server--LocalWebServer+getServer) ⇒ Server
* _inner_
@@ -28,12 +28,6 @@
- .port} number
- Port
- .stack} Array.<string>
| Array.<Features>
- Port
-
-
-#### localWebServer.view : View
-Current view.
-
-**Kind**: instance property of [LocalWebServer](#exp_module_local-web-server--LocalWebServer)
#### localWebServer.features : Array.<Feature>
@@ -46,7 +40,13 @@ Loaded feature modules
Config
**Kind**: instance property of [LocalWebServer](#exp_module_local-web-server--LocalWebServer)
-
+
+
+#### localWebServer.view : View
+Current view.
+
+**Kind**: instance property of [LocalWebServer](#exp_module_local-web-server--LocalWebServer)
+
#### localWebServer.server : Server
Node.js server
diff --git a/doc/visualisation.md b/doc/visualisation.md
index c621023..c31ce9d 100644
--- a/doc/visualisation.md
+++ b/doc/visualisation.md
@@ -13,7 +13,7 @@ Then, start the server, outputting `combined` format logs to disk:
$ ws -f combined > web.log
```
-In a separate tab, point goaccess at `web.log` and it will display statistics in real time:
+In a separate terminal, point goaccess at `web.log` and it will display statistics in real time:
```
$ goaccess -p ~/.goaccessrc -f web.log
diff --git a/lib/cli-view.js b/lib/cli-view.js
index 21fabaa..07503db 100644
--- a/lib/cli-view.js
+++ b/lib/cli-view.js
@@ -1,31 +1,48 @@
+'use strict'
+
class CliView {
constructor (localWebServer) {
- this.options = localWebServer.options
+ this.localWebServer = localWebServer
}
- info (key, value) {
- if (key && value) {
- const ansi = require('ansi-escape-sequences')
- const tableLayout = require('table-layout')
- const output = tableLayout({ key: ansi.format(key, 'bold'), value: value}, {
- padding: { left: '', right: ' ' },
- columns: [
- { name: 'key', width: 18 },
- { name: 'value', nowrap: true }
- ]
- })
- process.stderr.write(output)
- } else {
- console.error(key)
- }
- }
- verbose (key, value) {
- if (this.options.verbose) {
- this.info(key, value)
- }
- }
- error (msg) {
- console.error(ansi.format(msg, 'red'))
+ write (msg) {
+ const writeToStdout = [ 'log', 'info' ]
+ Object.keys(msg).forEach(key => {
+ if (writeToStdout.includes(key)) {
+ console.log(msg[key])
+ } else if (key === 'config' && msg.config && this.localWebServer.options.verbose) {
+ printLine(msg.config)
+ } else if (key === 'error') {
+ const ansi = require('ansi-escape-sequences')
+ console.error(ansi.format(msg.error, 'red'))
+ }
+ })
}
}
module.exports = CliView
+
+function printLine (config) {
+ const output = objectToTable(config)
+ process.stderr.write(output)
+}
+
+function objectToTable (object) {
+ const ansi = require('ansi-escape-sequences')
+ const tableLayout = require('table-layout')
+ const t = require('typical')
+
+ const data = Object.keys(object).map(key => {
+ if (t.isObject(object[key])) {
+ return { key: ansi.format(key, 'bold'), value: objectToTable(object[key]) }
+ } else {
+ return { key: ansi.format(key, 'bold'), value: object[key] }
+ }
+ })
+ return tableLayout(data, {
+ padding: { left: '', right: ' ' },
+ columns: [
+ // { name: 'key', width: 18 },
+ // { name: 'value', nowrap: true }
+ ]
+ })
+}
diff --git a/lib/local-web-server.js b/lib/local-web-server.js
index f43b21e..4f8c23c 100644
--- a/lib/local-web-server.js
+++ b/lib/local-web-server.js
@@ -22,17 +22,10 @@ class LocalWebServer {
*/
constructor (initOptions) {
initOptions = initOptions || {}
- const commandLineArgs = require('command-line-args')
const commandLineUsage = require('command-line-usage')
const CliView = require('./cli-view')
const cli = require('../lib/cli-data')
- /**
- * Current view.
- * @type {View}
- */
- this.view = new CliView(this)
-
/* get stored config */
const loadConfig = require('config-master')
const stored = loadConfig('local-web-server')
@@ -47,35 +40,10 @@ class LocalWebServer {
this.features = this._buildFeatureStack(featurePaths)
/* gather feature optionDefinitions and parse the command line */
- const featureOptionDefinitions = this.features
- .filter(mw => mw.optionDefinitions)
- .map(mw => mw.optionDefinitions())
- .reduce(flatten, [])
- .filter(def => def)
- .map(def => {
- def.group = 'middleware'
- return def
- })
-
+ const featureOptionDefinitions = gatherOptionDefinitions(this.features)
const usage = commandLineUsage(cli.usage(featureOptionDefinitions))
-
- let options = {}
const allOptionDefinitions = cli.optionDefinitions.concat(featureOptionDefinitions)
- if (!initOptions.testMode) {
- try {
- options = commandLineArgs(allOptionDefinitions)
- } catch (err) {
- this.view.error(err.toString())
- if (err.name === 'DUPLICATE_NAME') {
- this.view.error('\nOption Definitions:')
- this.view.error(allOptionDefinitions.map(def => {
- return `name: ${def.name}${def.alias ? ', alias: ' + def.alias : ''}`
- }).join('\n'))
- }
- this.view.info(usage)
- process.exit(1)
- }
- }
+ let options = initOptions.testMode ? {} : parseCommandLineOptions(allOptionDefinitions, this.view)
/* combine in stored config */
options = Object.assign(
@@ -93,26 +61,41 @@ class LocalWebServer {
*/
this.options = options
- if (options.view) {
- const View = loadModule(options.view)
- this.view = new View(this)
- }
+ /**
+ * Current view.
+ * @type {View}
+ */
+ this.view = null
/* --config */
if (options.config) {
- this.view.info(JSON.stringify(options, null, ' '))
+ console.error(JSON.stringify(options, null, ' '))
process.exit(0)
/* --version */
} else if (options.version) {
const pkg = require(path.resolve(__dirname, '..', 'package.json'))
- this.view.info(pkg.version)
+ console.error(pkg.version)
process.exit(0)
/* --help */
} else if (options.help) {
- this.view.info(usage)
+ console.error(usage)
process.exit(0)
+
+ } else {
+ /**
+ * Node.js server
+ * @type {Server}
+ */
+ this.server = this.getServer()
+
+ if (options.view) {
+ const View = loadModule(options.view)
+ this.view = new View(this)
+ } else {
+ this.view = new CliView(this)
+ }
}
}
@@ -144,7 +127,7 @@ class LocalWebServer {
* Returns a listening server which processes requests using the middleware supplied.
* @returns {Server}
*/
- getServer (onListening) {
+ getServer () {
const app = this.getApplication()
const options = this.options
@@ -173,21 +156,18 @@ class LocalWebServer {
}
server.listen(options.port)
- if (onListening) server.on('listening', onListening)
+ // if (onListening) server.on('listening', onListening)
+
+ /* on server-up message */
if (!options.testMode) {
server.on('listening', () => {
const ipList = getIPList()
.map(iface => `[underline]{${server.isHttps ? 'https' : 'http'}://${iface.address}:${options.port}}`)
.join(', ')
- this.view.info('Serving at', ansi.format(ipList))
+ console.error('Serving at', ansi.format(ipList))
})
}
- /**
- * Node.js server
- * @type {Server}
- */
- this.server = server
return server
}
@@ -234,7 +214,7 @@ function loadStack (modulePath) {
process.exit(1)
}
} else {
- const msg = `No module found at: \n${tried.join('\n')}`
+ const msg = `No module found for: ${modulePath}`
console.error(msg)
process.exit(1)
}
@@ -299,4 +279,35 @@ function parseFeaturePaths (configStack) {
return featurePaths
}
+function gatherOptionDefinitions (features) {
+ return features
+ .filter(mw => mw.optionDefinitions)
+ .map(mw => mw.optionDefinitions())
+ .reduce(flatten, [])
+ .filter(def => def)
+ .map(def => {
+ def.group = 'middleware'
+ return def
+ })
+}
+
+function parseCommandLineOptions (allOptionDefinitions) {
+ const commandLineArgs = require('command-line-args')
+ try {
+ return commandLineArgs(allOptionDefinitions)
+ } catch (err) {
+ console.error(err)
+
+ /* handle duplicate option names */
+ if (err.name === 'DUPLICATE_NAME') {
+ console.error('\nOption Definitions:')
+ console.error(allOptionDefinitions.map(def => {
+ return `name: ${def.name}${def.alias ? ', alias: ' + def.alias : ''}`
+ }).join('\n'))
+ }
+ console.error(usage)
+ process.exit(1)
+ }
+}
+
module.exports = LocalWebServer
diff --git a/test/test.js b/test/test.js
index 68a6d6d..b1ba7ea 100644
--- a/test/test.js
+++ b/test/test.js
@@ -12,13 +12,13 @@ test('stack', function (t) {
port: 8100,
testMode: true
})
- const server = ws.getServer(() => {
+ ws.server.on('listening', () => {
return request('http://localhost:8100/')
.then(c.checkResponse(t, 200, /1234512345/))
- .then(server.close.bind(server))
+ .then(ws.server.close.bind(ws.server))
.catch(err => {
t.fail(err.message)
- server.close()
+ ws.server.close()
})
})
})
@@ -34,13 +34,13 @@ test('https', function (t) {
const url = require('url')
const reqOptions = url.parse('https://localhost:8100/')
reqOptions.rejectUnauthorized = false
- const server = ws.getServer(() => {
+ ws.server.on('listening', () => {
return request(reqOptions)
.then(c.checkResponse(t, 200, /1234512345/))
- .then(server.close.bind(server))
+ .then(ws.server.close.bind(ws.server))
.catch(err => {
t.fail(err.message)
- server.close()
+ ws.server.close()
})
})
})