1 | const Controllers = require("./controllers");
|
2 | const Factories = require("./factories");
|
3 | const Messages = require("./messages");
|
4 | const Router = require("./router");
|
5 | const OpenApi = require("./open-api");
|
6 | const Config = require("./../config");
|
7 |
|
8 |
|
9 | class Server {
|
10 |
|
11 | constructor() {
|
12 | this.componentsModules = {
|
13 | requestInterceptors: new Set(),
|
14 | responseInterceptors: new Set(),
|
15 | controllers: new Set(),
|
16 | factories: new Set(),
|
17 | bootstrap: new Set()
|
18 | };
|
19 | }
|
20 |
|
21 | start() {
|
22 | const environment = Object.entries(Config.env).find(([env, flag]) => flag)[0];
|
23 | const Http = Config.server.protocol === "http"? require("http") : require("https");
|
24 |
|
25 | const serverAddress = Config.server.path? Config.server.path : `${Config.server.protocol}://${Config.server.host}:${Config.server.port}/`;
|
26 | if(Config.server.path) {
|
27 | delete Config.server.port;
|
28 | }
|
29 |
|
30 | componentsRegistration.call(this);
|
31 | this.server = Http.createServer(Config.server, Router.handle);
|
32 | this.server.once("error", error => {
|
33 | if (error.code === 'EADDRINUSE') {
|
34 | console.log('\x1b[31m%s\x1b[0m', `Server failed to start at ${serverAddress}. Port ${Config.server.port} is in use.`);
|
35 | } else {
|
36 | console.log(error);
|
37 | }
|
38 | });
|
39 | this.server.listen(Config.server, () => {
|
40 | componentsBootstrap.call(this);
|
41 | console.log('\x1b[32m%s\x1b[0m', `Server is running at ${serverAddress} in ${environment} mode...`);
|
42 | });
|
43 | }
|
44 |
|
45 | stop() {
|
46 | this.server.close();
|
47 | }
|
48 |
|
49 | addComponent(componentInfo) {
|
50 | Object.keys(componentInfo).forEach(type => componentInfo[type].forEach(
|
51 | path => this.componentsModules[type].add(path)
|
52 | ));
|
53 | }
|
54 |
|
55 | openApiJSON() {
|
56 | const packageJson = require.main.require("./package.json");
|
57 | return OpenApi.generate({
|
58 | "title": packageJson.name,
|
59 | "description": packageJson.description,
|
60 | "version": packageJson.version,
|
61 | "contact": packageJson.author
|
62 | });
|
63 | }
|
64 |
|
65 | openApiToFile(path = "./openapi.json") {
|
66 | const fs = require("fs");
|
67 | fs.writeFileSync(path, JSON.stringify(this.openApiJSON(), null, 4));
|
68 | }
|
69 | }
|
70 |
|
71 |
|
72 | const componentsRegistration = function () {
|
73 | this.componentsModules.factories.forEach(model => {
|
74 | Factories.define(require(model));
|
75 | });
|
76 |
|
77 | this.componentsModules.requestInterceptors.forEach(interceptor => {
|
78 | Messages.request.addInterceptor(require(interceptor));
|
79 | });
|
80 |
|
81 | this.componentsModules.responseInterceptors.forEach(interceptor => {
|
82 | Messages.response.addInterceptor(require(interceptor));
|
83 | });
|
84 |
|
85 | this.componentsModules.controllers.forEach(controller => {
|
86 | Controllers.define(require(controller));
|
87 | });
|
88 |
|
89 | };
|
90 |
|
91 | const componentsBootstrap = function () {
|
92 | this.componentsModules.bootstrap.forEach(controller => {
|
93 | const bootstrapFn = require(controller);
|
94 | (typeof bootstrapFn === "function") && bootstrapFn(this);
|
95 | });
|
96 | };
|
97 |
|
98 |
|
99 | module.exports = Server;
|