#!/usr/bin/env node 'use strict'; const { EventEmitter } = require('events'); const http = require('http'); const { toLower } = require('lodash'); const utils = require('./utils'); const { express, logger, nestedConfigurations, appConfigurations } = require('./core'); class Server extends EventEmitter { constructor() { super(); this.setMaxListeners(100); // Logger. this.log = logger; // Default configurations. this.config = { launchedAt: Date.now(), appPath: process.cwd(), host: process.env.HOST || process.env.HOSTNAME || 'localhost', port: process.env.PORT || 1337, environment: toLower(process.env.NODE_ENV) || 'development', environments: {}, }; // Bind context functions. this.loadFile = utils.loadFile.bind(this); } async init() { this.emit('server:init'); await nestedConfigurations.call(this); await appConfigurations.call(this); /*await Promise.all([ modules.call(this), ]).then(results => { this.modules = results[0]; });*/ } async start() { try { // Emit starting event. this.emit('server:starting'); await this.init(); // Expose `express`. this.app = await express.call(this); // Mount the HTTP server. this.server = http.createServer(this.app); await this.enhancer.call(this); // Launch server. this.server.listen(this.config.port, async (err) => { if (err) { this.log.debug(`⚠️ Server wasn't able to start properly.`); this.log.error(err); return this.stop(); } this.log.info('Time: ' + new Date()); this.log.info('Launched in: ' + (Date.now() - this.config.launchedAt) + ' ms'); this.log.info('Environment: ' + this.config.environment); this.log.info('Process PID: ' + process.pid); //this.log.info(`Version: ${this.config.info.strapi} (node v${this.config.info.node})`); this.log.info('To shut down your server, press + C at any time'); this.log.info(`⚡️ Server: ${this.config.url}`); // Emit started event. this.emit('server:started'); }); } catch (err) { this.log.debug(`⛔️ Server wasn't able to start properly.`); this.log.error(err); console.log(err); this.stop(); } } async enhancer() { this.connections = {}; this.server.on('connection', conn => { const key = conn.remoteAddress + ':' + conn.remotePort; this.connections[key] = conn; conn.on('close', () => { delete this.connections[key]; }); }); this.server.on('error', err => { if (err.code === 'EADDRINUSE') { this.log.debug(`⛔️ Server wasn't able to start properly.`); this.log.error(`The port ${err.port} is already used by another application.`); this.stop(); return; } console.error(err); }); } stop() { this.emit('server:stoping'); // Destroy server and available connections. if (this.server) { this.server.close(); } process.send('stop'); // Kill process. process.exit(1); } } (() => { const server = new Server(); server.start(); })();