Test Failed
Branch feature/typescript5 (73fa6e)
by Lorenzo
01:54
created

ExpressBeans.listen   A

Complexity

Conditions 2

Size

Total Lines 6
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
import express, { Express } from 'express';
2
import { CreateExpressBeansOptions, ExpressBeansOptions } from '@/ExpressBeansTypes';
3
import { logger, registeredBeans } from '@/decorators';
4
5
export default class ExpressBeans {
6
  private readonly app: Express;
7
8
  private onInitialized: (() => void) | undefined;
9
10
  /**
11
   * Creates a new ExpressBeans application
12
   * @param options {ExpressBeansOptions}
13
   */
14
  static createApp(options?: Partial<CreateExpressBeansOptions>) {
15
    return new Promise((resolve, reject) => {
16
      let app: ExpressBeans;
17
      const onInitialized = () => {
18
        resolve(app);
19
      };
20
      app = new ExpressBeans({ ...options, onInitialized, onError: reject });
21
    });
22
  }
23
24
  /**
25
   * Constructor of ExpressBeans application
26
   * @constructor
27
   * @param options {ExpressBeansOptions}
28
   */
29
  constructor(options?: Partial<ExpressBeansOptions>) {
30
    this.app = express();
31
    this.app.disable('x-powered-by');
32
    this.initialize(options || {});
33
  }
34
35
  /**
36
   * Initializes the application and checks
37
   * if all beans are valid
38
   * @param listen {boolean}
39
   * @param port {number}
40
   * @param beans {Object[]}
41
   * @param onInitialized {Function}
42
   * @private
43
   */
44
  private initialize({
45
    listen = true,
46
    port = 8080,
47
    routerBeans = [],
48
    onInitialized,
49
    onError,
50
  }: Partial<ExpressBeansOptions>) {
51
    this.onInitialized = onInitialized;
52
    const invalidBeans = routerBeans
53
      .filter(((bean) => !bean.isExpressBean))
54
      .map((object) => object.prototype.constructor.name);
55
    if (invalidBeans.length > 0) {
56
      throw new Error(`Trying to use something that is not an ExpressBean: ${invalidBeans.join(', ')}`);
57
    }
58
    setImmediate(async () => {
59
      try {
60
        Array.from(registeredBeans.values())
61
          .filter((bean) => bean.routerConfig)
62
          .forEach((bean) => {
63
            try {
64
              const {
65
                path,
66
                router,
67
              } = bean.routerConfig!;
68
              logger.debug(`Registering router ${bean.className}`);
69
              this.app.use(path, router);
70
            } catch (e) {
71
              logger.error(e);
72
              throw new Error(`Router ${bean.className} not initialized correctly`);
73
            }
74
          });
75
        if (listen) {
76
          this.listen(port);
77
        }
78
      } catch (err: any) {
79
        if (onError) {
80
          onError(err);
81
        } else {
82
          throw err;
83
        }
84
      }
85
    });
86
  }
87
88
  listen(port: number) {
89
    return this.app.listen(port, () => {
90
      logger.info(`Server listening on port ${port}`);
91
      if (this.onInitialized) {
92
        this.onInitialized();
93
      }
94
    });
95
  }
96
97
  /**
98
   * Gets Express application
99
   * @returns {Express}
100
   */
101
  getApp() {
102
    return this.app;
103
  }
104
105
  /**
106
   * Exposes use function of Express application
107
   * @param handlers
108
   */
109
  use(...handlers: any) {
110
    this.app.use(...handlers);
111
  }
112
}
113