refactor cli
This commit is contained in:
		
							
								
								
									
										187
									
								
								bin/cli.js
									
									
									
									
									
								
							
							
						
						
									
										187
									
								
								bin/cli.js
									
									
									
									
									
								
							@ -1,97 +1,91 @@
 | 
			
		||||
#!/usr/bin/env node
 | 
			
		||||
'use strict'
 | 
			
		||||
const localWebServer = require('../')
 | 
			
		||||
const cliOptions = require('../lib/cli-options')
 | 
			
		||||
const commandLineArgs = require('command-line-args')
 | 
			
		||||
const cli = require('../lib/cli-data')
 | 
			
		||||
const commandLineUsage = require('command-line-usage')
 | 
			
		||||
const ansi = require('ansi-escape-sequences')
 | 
			
		||||
const loadConfig = require('config-master')
 | 
			
		||||
const path = require('path')
 | 
			
		||||
const os = require('os')
 | 
			
		||||
const arrayify = require('array-back')
 | 
			
		||||
const t = require('typical')
 | 
			
		||||
const flatten = require('reduce-flatten')
 | 
			
		||||
 | 
			
		||||
const usage = commandLineUsage(cliOptions.usageData)
 | 
			
		||||
function ws () {
 | 
			
		||||
  const usage = commandLineUsage(cli.usageData)
 | 
			
		||||
 | 
			
		||||
let options
 | 
			
		||||
let isHttps = false
 | 
			
		||||
  let options
 | 
			
		||||
 | 
			
		||||
try {
 | 
			
		||||
  options = collectOptions()
 | 
			
		||||
} catch (err) {
 | 
			
		||||
  stop([ `[red]{Error}: ${err.message}`, usage ], 1)
 | 
			
		||||
  return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (options.misc.help) {
 | 
			
		||||
  stop(usage, 0)
 | 
			
		||||
} else if (options.misc.config) {
 | 
			
		||||
  stop(JSON.stringify(options.server, null, '  '), 0)
 | 
			
		||||
} else {
 | 
			
		||||
  const valid = validateOptions(options)
 | 
			
		||||
  if (!valid) {
 | 
			
		||||
    /* gracefully end the process */
 | 
			
		||||
  try {
 | 
			
		||||
    options = collectOptions()
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    stop([ `[red]{Error}: ${err.message}`, usage ], 1)
 | 
			
		||||
    return
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const Koa = require('koa')
 | 
			
		||||
  const app = new Koa()
 | 
			
		||||
 | 
			
		||||
  app.on('error', err => {
 | 
			
		||||
    if (options.server['log-format']) {
 | 
			
		||||
      console.error(ansi.format(err.message, 'red'))
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const ws = localWebServer({
 | 
			
		||||
    static: {
 | 
			
		||||
      root: options.server.directory,
 | 
			
		||||
      options: {
 | 
			
		||||
        hidden: true
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    serveIndex: {
 | 
			
		||||
      path: options.server.directory,
 | 
			
		||||
      options: {
 | 
			
		||||
        icons: true,
 | 
			
		||||
        hidden: true
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    log: {
 | 
			
		||||
      format: options.server['log-format']
 | 
			
		||||
    },
 | 
			
		||||
    compress: options.server.compress,
 | 
			
		||||
    mime: options.server.mime,
 | 
			
		||||
    forbid: options.server.forbid,
 | 
			
		||||
    spa: options.server.spa,
 | 
			
		||||
    'no-cache': options.server['no-cache'],
 | 
			
		||||
    rewrite: options.server.rewrite,
 | 
			
		||||
    verbose: options.server.verbose,
 | 
			
		||||
    mocks: options.server.mocks
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  app.use(ws)
 | 
			
		||||
 | 
			
		||||
  if (options.server.https) {
 | 
			
		||||
    options.server.key = path.resolve(__dirname, '..', 'ssl', '127.0.0.1.key')
 | 
			
		||||
    options.server.cert = path.resolve(__dirname, '..', 'ssl', '127.0.0.1.crt')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (options.server.key && options.server.cert) {
 | 
			
		||||
    const https = require('https')
 | 
			
		||||
    const fs = require('fs')
 | 
			
		||||
    isHttps = true
 | 
			
		||||
 | 
			
		||||
    const serverOptions = {
 | 
			
		||||
      key: fs.readFileSync(options.server.key),
 | 
			
		||||
      cert: fs.readFileSync(options.server.cert)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const server = https.createServer(serverOptions, app.callback())
 | 
			
		||||
    server.listen(options.server.port, onServerUp)
 | 
			
		||||
  if (options.misc.help) {
 | 
			
		||||
    stop(usage, 0)
 | 
			
		||||
  } else if (options.misc.config) {
 | 
			
		||||
    stop(JSON.stringify(options.server, null, '  '), 0)
 | 
			
		||||
  } else {
 | 
			
		||||
    app.listen(options.server.port, onServerUp)
 | 
			
		||||
    const localWebServer = require('../')
 | 
			
		||||
    const Koa = require('koa')
 | 
			
		||||
 | 
			
		||||
    const valid = validateOptions(options, usage)
 | 
			
		||||
    if (!valid) return
 | 
			
		||||
 | 
			
		||||
    const app = new Koa()
 | 
			
		||||
 | 
			
		||||
    app.on('error', err => {
 | 
			
		||||
      if (options.server['log-format']) {
 | 
			
		||||
        console.error(ansi.format(err.message, 'red'))
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    const ws = localWebServer({
 | 
			
		||||
      static: {
 | 
			
		||||
        root: options.server.directory,
 | 
			
		||||
        options: {
 | 
			
		||||
          hidden: true
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      serveIndex: {
 | 
			
		||||
        path: options.server.directory,
 | 
			
		||||
        options: {
 | 
			
		||||
          icons: true,
 | 
			
		||||
          hidden: true
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      log: {
 | 
			
		||||
        format: options.server['log-format']
 | 
			
		||||
      },
 | 
			
		||||
      compress: options.server.compress,
 | 
			
		||||
      mime: options.server.mime,
 | 
			
		||||
      forbid: options.server.forbid,
 | 
			
		||||
      spa: options.server.spa,
 | 
			
		||||
      'no-cache': options.server['no-cache'],
 | 
			
		||||
      rewrite: options.server.rewrite,
 | 
			
		||||
      verbose: options.server.verbose,
 | 
			
		||||
      mocks: options.server.mocks
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    app.use(ws)
 | 
			
		||||
 | 
			
		||||
    if (options.server.https) {
 | 
			
		||||
      options.server.key = path.resolve(__dirname, '..', 'ssl', '127.0.0.1.key')
 | 
			
		||||
      options.server.cert = path.resolve(__dirname, '..', 'ssl', '127.0.0.1.crt')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (options.server.key && options.server.cert) {
 | 
			
		||||
      const https = require('https')
 | 
			
		||||
      const fs = require('fs')
 | 
			
		||||
 | 
			
		||||
      const serverOptions = {
 | 
			
		||||
        key: fs.readFileSync(options.server.key),
 | 
			
		||||
        cert: fs.readFileSync(options.server.cert)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const server = https.createServer(serverOptions, app.callback())
 | 
			
		||||
      server.listen(options.server.port, onServerUp.bind(null, options, true))
 | 
			
		||||
    } else {
 | 
			
		||||
      app.listen(options.server.port, onServerUp.bind(null, options))
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -100,13 +94,8 @@ function stop (msgs, exitCode) {
 | 
			
		||||
  process.exitCode = exitCode
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function onServerUp () {
 | 
			
		||||
  let ipList = Object.keys(os.networkInterfaces())
 | 
			
		||||
    .map(key => os.networkInterfaces()[key])
 | 
			
		||||
    .reduce(flatten, [])
 | 
			
		||||
    .filter(iface => iface.family === 'IPv4')
 | 
			
		||||
  ipList.unshift({ address: os.hostname() })
 | 
			
		||||
  ipList = ipList
 | 
			
		||||
function onServerUp (options, isHttps) {
 | 
			
		||||
  const ipList = getIPList(isHttps)
 | 
			
		||||
    .map(iface => `[underline]{${isHttps ? 'https' : 'http'}://${iface.address}:${options.server.port}}`)
 | 
			
		||||
    .join(', ')
 | 
			
		||||
 | 
			
		||||
@ -117,12 +106,28 @@ function onServerUp () {
 | 
			
		||||
  ))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getIPList (isHttps) {
 | 
			
		||||
  const flatten = require('reduce-flatten')
 | 
			
		||||
  const os = require('os')
 | 
			
		||||
 | 
			
		||||
  let ipList = Object.keys(os.networkInterfaces())
 | 
			
		||||
    .map(key => os.networkInterfaces()[key])
 | 
			
		||||
    .reduce(flatten, [])
 | 
			
		||||
    .filter(iface => iface.family === 'IPv4')
 | 
			
		||||
  ipList.unshift({ address: os.hostname() })
 | 
			
		||||
  return ipList
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return default, stored and command-line options combined
 | 
			
		||||
 */
 | 
			
		||||
function collectOptions () {
 | 
			
		||||
  const commandLineArgs = require('command-line-args')
 | 
			
		||||
  const loadConfig = require('config-master')
 | 
			
		||||
  const stored = loadConfig('local-web-server')
 | 
			
		||||
  let options = {}
 | 
			
		||||
 | 
			
		||||
  /* parse command line args */
 | 
			
		||||
  options = commandLineArgs(cliOptions.definitions)
 | 
			
		||||
  let options = commandLineArgs(cli.definitions)
 | 
			
		||||
 | 
			
		||||
  const builtIn = {
 | 
			
		||||
    port: 8000,
 | 
			
		||||
@ -150,7 +155,7 @@ function parseRewriteRules (rules) {
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function validateOptions (options) {
 | 
			
		||||
function validateOptions (options, usage) {
 | 
			
		||||
  let valid = true
 | 
			
		||||
  function invalid (msg) {
 | 
			
		||||
    return `[red underline]{Invalid:} [bold]{${msg}}`
 | 
			
		||||
@ -162,3 +167,5 @@ function validateOptions (options) {
 | 
			
		||||
  }
 | 
			
		||||
  return valid
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ws()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								extend/live-reload.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								extend/live-reload.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
'use strict'
 | 
			
		||||
const Koa = require('koa')
 | 
			
		||||
const localWebServer = require('../')
 | 
			
		||||
const liveReload = require('koa-livereload')
 | 
			
		||||
const convert = require('koa-convert')
 | 
			
		||||
 | 
			
		||||
const app = new Koa()
 | 
			
		||||
const ws = localWebServer({
 | 
			
		||||
  log: { format: 'dev' }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
app.use(liveReload())
 | 
			
		||||
app.use(ws)
 | 
			
		||||
app.listen(8000)
 | 
			
		||||
@ -37,7 +37,12 @@ module.exports = localWebServer
 | 
			
		||||
function localWebServer (options) {
 | 
			
		||||
  options = Object.assign({
 | 
			
		||||
    static: {},
 | 
			
		||||
    serveIndex: {},
 | 
			
		||||
    serveIndex: {
 | 
			
		||||
      options: {
 | 
			
		||||
        icons: true,
 | 
			
		||||
        hidden: true
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    cacheControl: {},
 | 
			
		||||
    spa: null,
 | 
			
		||||
    log: {},
 | 
			
		||||
 | 
			
		||||
@ -62,6 +62,7 @@
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "jsdoc-to-markdown": "^1.3.6",
 | 
			
		||||
    "koa-cache-control": "^1.0.0",
 | 
			
		||||
    "koa-livereload": "^0.1.23",
 | 
			
		||||
    "req-then": "~0.2.4",
 | 
			
		||||
    "tape": "^4.5.1"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user