'use strict'; const Hapi = require('@hapi/hapi'); const Joi = require('joi'); const Path = require('path'); const Rfr = require('rfr'); const ComSrv = Rfr('/server/comsrv'); const Db = Rfr('/server/db'); const PTable = Rfr('/server/ptable'); const Originate = Rfr('/server/originate'); const AMI = Rfr('/server/ami'); let server; const initServer = async() => { server = Hapi.server({ port: process.env.PORT, host: '0.0.0.0', routes: { files: { relativeTo: global.appRoot }, json: { space: 4 } }, router: { isCaseSensitive: false, stripTrailingSlash: true }, ...ComSrv.isDebugMode() && { debug: { log: ['error'], request: ['error'] } }, ...process.env.ADDRESS && {address: process.env.ADDRESS} }); await server.register({ plugin: require('hapi-favicon'), options: { path: './client/favicon.ico' } }); await server.register([require('@hapi/vision'), require('@hapi/inert')]); server.route(Rfr('/server/route')); server.views({ engines: { pug: require('pug') }, path: './templates', relativeTo: Path.join(global.appRoot, 'server'), isCached: !ComSrv.isDebugMode(), compileOptions: { pretty: ComSrv.isDebugMode() } }); }; module.exports = { init: async () => { // Initialize all known configs Rfr('/server/config')([ Rfr('/server/recording').config, Db.config, PTable.config, AMI.config, Originate.config, Joi.object({ PORT: Joi.number().port().optional().default(80) }) ]); const results = await Promise.allSettled([initServer(), Db.initDB(), AMI.initAMI()]); const errors = results.filter(p => p.status === 'rejected') .map(p => p.reason) .forEach( r => { throw new Error(r); } ); await PTable.initPTable(); await server.start(); if (process.connected && process.send) { process.send('ready'); } console.log(`Server running on ${server.info.uri} in ${ComSrv.isDebugMode() ? 'debug' : 'production'} mode`); } }; ['unhandledRejection', 'uncaughtException'].forEach( (eventName) => { process.on(eventName, e => { console.log(e); process.exit(1); }); }); process.on('SIGINT', () => { process.exit(0); });