UNPKG

yahoi

Version:

Yet Another Highly Opinionated Isomorphic Framework

265 lines (208 loc) 8.79 kB
import './conditional-babel-polyfill'; import express from 'express'; import readdir from 'readdir'; import bodyParser from 'body-parser'; import cookieParser from 'cookie-parser'; import compression from 'compression'; const ENVIRONMENT_PATH = "Environments/"; const ROUTERS_PATH = "Routing/"; const Controller_PATH = "Controller/"; const Services_PATH = "Services/"; import path from 'path'; import ErrorController from './../Controller/ErrorController'; import TranslationController from './../Controller/TranslationController'; export default class Server { constructor(props) { this.__props = props; this.__environment = this.loadEnvironment(props.env); this.__services = this.loadServices(props.env); this.__controller = this.loadController(props.env); // Default Error Controller let defaultErrorController = new ErrorController({ app: this } ); defaultErrorController.setViewDirectory(path.resolve(__dirname, '..', 'Views')); defaultErrorController.setProjectDirectory(path.resolve(__dirname, '..')); defaultErrorController.setComponentDirectory(path.resolve(__dirname, '..', 'Components')); defaultErrorController.setContainerDirectory(path.resolve(__dirname, '..', 'Containers')); this.__controller['__defaultErrorController'] = defaultErrorController; // Default Translation Controller let defaultTranslationController = new TranslationController({ app: this } ); defaultTranslationController.setViewDirectory(path.resolve(__dirname, '..', 'Views')); defaultTranslationController.setProjectDirectory(path.resolve(__dirname, '..')); defaultTranslationController.setComponentDirectory(path.resolve(__dirname, '..', 'Components')); defaultTranslationController.setContainerDirectory(path.resolve(__dirname, '..', 'Containers')); this.__controller['DefaultTranslation'] = defaultTranslationController; this.__routers = this.loadRouters(props.env); this.__expressApp = express(); this.__expressApp.use(bodyParser.urlencoded({ extended: true })); this.__expressApp.use(bodyParser.json()) this.__expressApp.use(cookieParser()) this.getController = this.getController.bind(this); this.__defaultRouter = new (this.__routers['Default'])({ app: this }); this.__defaultRouter.addRoute({ path: '/Translations', router: 'DefaultTranslation' }); if(typeof(process.env.NODE_ENV)!='undefined' && process.env.NODE_ENV=='development') { // Development let enableHmrMidWare = require('./dev/expressMiddleware.js'); enableHmrMidWare(this, this.__expressApp); } else { // Production this.__expressApp.use(compression()); } } getDefaultRouter() { return this.__defaultRouter; } getController(name) { if(typeof(this.__controller[name])=='undefined') { throw Error(`Controller could not be found: ${name}`); } return this.__controller[name]; } getService(name) { return this.__services[name]; } loadRouters() { try { let routers = {}; readdir.readSync(`${this.getProjectPath()}/${ROUTERS_PATH}`).map(routerFile => { if(routerFile.indexOf('.js')>0) { let routerName = routerFile.substr(0, routerFile.length-9); routers[routerName] = require(`${this.getProjectPath()}/${ROUTERS_PATH}${routerFile}`).default; } }); // build-in readdir.readSync(`${__dirname}/../Routing`).map(routerFile => { if(routerFile.indexOf('.js')>0) { let routerName = routerFile.substr(0, routerFile.length-9); routers[routerName] = require(`${__dirname}/../Routing/${routerFile}`).default; } }); // console.log('initialized routers', routers); return routers; } catch(e) { throw e; } } loadController() { try { let controller = {}; readdir.readSync(`${this.getProjectPath()}/${Controller_PATH}`).map(controllerFile => { if(controllerFile.indexOf('Controller.js')>0) { let cntrlName = controllerFile.substr(0, controllerFile.length-13); let controllerObj = new (require(`${this.getProjectPath()}/${Controller_PATH}${controllerFile}`).default)( { app: this }); controllerObj.setViewDirectory(path.resolve(this.getProjectPath(), 'Views')); controllerObj.setProjectDirectory(this.getProjectPath()); controllerObj.setComponentDirectory(path.resolve(this.getProjectPath(), 'Components')); controllerObj.setContainerDirectory(path.resolve(this.getProjectPath(), 'Containers')); controller[cntrlName] = controllerObj } }); return controller; } catch(e) { throw e; } } loadServices() { try { let services = {}; readdir.readSync(`${this.getProjectPath()}/${Services_PATH}`).map(serviceFile => { if(serviceFile.indexOf('Service.js')>0) { let serviceName = serviceFile.substr(0, serviceFile.length-10); let serviceObj = new (require(`${this.getProjectPath()}/${Services_PATH}${serviceFile}`).default)( { app: this }); // controllerObj.setViewDirectory(path.resolve(this.getProjectPath(), 'Views')); serviceObj.setProjectDirectory(this.getProjectPath()); serviceObj.setComponentDirectory(path.resolve(this.getProjectPath(), 'Components')); serviceObj.setContainerDirectory(path.resolve(this.getProjectPath(), 'Containers')); services[serviceName] = serviceObj; } }); return services; } catch(e) { throw e; } } createRouter(name, props) { if(typeof(this.__routers[name])=='undefined') { throw Error(`Router ${name} not found`); } return new (this.__routers[name])(props); } getProjectPath() { return this.__props.projectPath; } getEnvironment() { return this.__environment; } loadEnvironment(name) { try { return require(`${this.getProjectPath()}/${ENVIRONMENT_PATH}${name}`).default; } catch(e) { throw e; } } start() { this.__expressApp.use('/Public', express.static(`${this.getProjectPath()}/Public`)) /* this.__expressApp.use('/Translations/get', (req, res) => { this.getController('__defaultTranslationController') .renderAction('get', req, res) .then(actionContext => { try { actionContext.getResponse().respond(req, res); } catch(e) { res.send('[1] Internal Server Error: ' + String(e)); } }) .catch(e => { res.send('[2] Internal Server Error: ' + String(e)); }) }) */ //this.__expressApp.use('/Translations', express.static(`${this.getProjectPath()}/Translations`)) this.__expressApp.all("*", (req, res) => { let matchResult = this.getDefaultRouter().match(req); if(matchResult) { matchResult.route.renderAction(req, res, matchResult).then(actionContext => { try { actionContext.getResponse().respond(req, res); } catch(e) { res.send('Error: ' + String(e)); } }).catch(e => { req.query = { error: e, controllerName: matchResult.route.getControllerName(), actionName: matchResult.route.getActionName() } this.getController('__defaultErrorController') .renderAction('actionError', req, res) .then(actionContext => { try { actionContext.getResponse().respond(req, res); } catch(e) { res.send('[1] Internal Server Error: ' + String(e)); } }) .catch(e => { res.send('[2] Internal Server Error: ' + String(e)); }) }); } else { this.getController('__defaultErrorController').renderAction('noRoute', req, res).then(actionContext => { try { actionContext.getResponse().respond(req, res); } catch(e) { console.log('Internal Server Error:', e); res.send('Internal Server Error: ' + String(e)); } }).catch(e => { console.log('renderedError', e); }); } }) this.__expressApp.listen(this.getEnvironment().server.port, () => { console.log(`Server started: ${process.env.NODE_ENV}`); console.log('Project Path: ', this.getProjectPath()); console.log('Port: ', this.getEnvironment().server.port); }) } }