const http = require('http') const express = require('express') const morgan = require('morgan') const bodyParser = require('body-parser') const chalk = require('chalk') const config = require('../config') const expressWs = require('express-ws') const yargs = require('yargs') const mode = yargs.argv.mode || 'development' const app = express() app.server = http.createServer(app) expressWs(app, app.server) if (mode === 'development') { const webpack = require('webpack') const webpackDevMiddleware = require('webpack-dev-middleware') const webpackHotMiddleware = require('webpack-hot-middleware') const webpackConfig = require('../webpack.config') const compiler = webpack(webpackConfig) const devMiddleware = webpackDevMiddleware(compiler, { noInfo: false, publicPath: '' }) app.use((req, res, next) => { res.set('X-Accel-Buffering', 'no') next() }) app.use(devMiddleware) app.use('/', devMiddleware) const hotMiddleware = webpackHotMiddleware(compiler, { path: '/__webpack__/__webpack_hmr' }) app.use(hotMiddleware) } app.use(morgan('combined')) app.use(bodyParser.json()) app.use(express.static('dist')) app.listen = (port = config.port || (app.settings.env === 'production' ? 80 : 3000)) => new Promise((resolve, reject) => { app.server.once('error', (err) => { if (err.message.includes('EADDRINUSE') && app.settings.env === 'development' && port < 3999) { console.warn(err.message) resolve(app.listen(port + 1)) } else { reject(err) } }) app.server.listen(port, () => { const host = [process.env.HOSTNAME || process.env.COMPUTERNAME || 'localhost', process.env.USERDNSDOMAIN].filter(x => x).join('.').toLowerCase() const url = `http://${host}:${app.server.address().port}` console.log(`Server running at ${chalk.underline(chalk.blueBright(url))}`) if (mode === 'development') { console.log('Establishing reverse proxy') const rc = require('persist-proxy/src/reverse-client') rc({ listen: { host: '127.0.0.1', port: port }, connect: [ { host: 'www.alanc.net', port: 8000 }, { host: '0.0.0.0', port: port } ] }) } }) }) const userApp = express.Router() // Handle unhandled rejection in route handlers: const appProxy = new Proxy(userApp, { get: (_, prop) => { if (prop[0] == '_') return userApp[prop] const orig = userApp[prop] if (orig instanceof Function) { return (...args) => { const newArgs = args.map(fn => { if (fn instanceof Function) { return Object.assign((...args) => { const ret = fn(...args) if (ret && ret.catch) { ret.catch(err => { const url = args[0] && args[0].url console.warn(chalk.yellow(`Unhandled Promise Rejection (${url}): ${err}`)) try { args[1].status(500).send({error: err.toString()}) } catch (err) { console.warn(chalk.yellow(`Unable to send error response`)) } }) } return ret }, fn) } else { return fn } }) return userApp[prop](...newArgs) } } else { return orig } } }) appProxy.start = () => { app.listen().catch(err => { console.log(chalk.red(err)) process.exit(1) }) } app.use(userApp) userApp._userApp = userApp userApp._app = app module.exports = appProxy