|
| 1 | +import cors from 'cors' |
| 2 | +import helmet from 'helmet' |
1 | 3 | import express from 'express'
|
2 | 4 | import config from './config'
|
| 5 | +import { readdirSync } from 'fs' |
| 6 | +import { join } from 'path/posix' |
| 7 | +import bearerToken from 'express-bearer-token' |
| 8 | + |
| 9 | +import identity from './middlewares/identity' |
| 10 | +import errorHandler from './middlewares/error' |
| 11 | +import validator from './middlewares/validator' |
3 | 12 |
|
4 | 13 | import type { Application } from 'express'
|
| 14 | +import type { Routers } from './interface/app' |
| 15 | +import type { Request, Response, NextFunction } from 'express' |
5 | 16 |
|
6 | 17 | export default class {
|
7 | 18 | public app: Application
|
8 | 19 |
|
9 | 20 | constructor() {
|
10 | 21 | this.app = express()
|
| 22 | + this.initializeMiddlewares() |
| 23 | + this.initializeRouters() |
| 24 | + this.initializeErrorHandler() |
| 25 | + } |
| 26 | + |
| 27 | + private errorWrapper( |
| 28 | + handler: ( |
| 29 | + req: Request, |
| 30 | + res: Response, |
| 31 | + next: NextFunction |
| 32 | + ) => Promise<void> | void |
| 33 | + ) { |
| 34 | + return (req: Request, res: Response, next: NextFunction) => { |
| 35 | + Promise.resolve(handler(req, res, next)).catch(next) |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + private initializeMiddlewares(): void { |
| 40 | + this.app.use(cors()) |
| 41 | + this.app.use(helmet()) |
| 42 | + this.app.use( |
| 43 | + bearerToken({ |
| 44 | + reqKey: 'token', |
| 45 | + headerKey: 'Bearer', |
| 46 | + }) |
| 47 | + ) |
| 48 | + this.app.use(express.json()) |
| 49 | + this.app.use(express.urlencoded({ extended: true })) |
| 50 | + } |
| 51 | + |
| 52 | + private initializeRouters(): void { |
| 53 | + const routerPath = join(__dirname, 'routers') |
| 54 | + const servicePath = (name: string) => join(routerPath, name, 'index.ts') |
| 55 | + |
| 56 | + const roots = readdirSync(routerPath, { withFileTypes: true }) |
| 57 | + |
| 58 | + for (const root of roots) { |
| 59 | + if (!root.isDirectory()) { |
| 60 | + continue |
| 61 | + } |
| 62 | + |
| 63 | + const { default: service } = require(servicePath(root.name)) |
| 64 | + for (const { |
| 65 | + method, |
| 66 | + path, |
| 67 | + middlewares = [], |
| 68 | + handler, |
| 69 | + needAuth, |
| 70 | + validation, |
| 71 | + } of (service as Routers).routers) { |
| 72 | + this.app[method](join(service.root, path), [ |
| 73 | + ...(needAuth ? [this.errorWrapper(identity)] : []), |
| 74 | + ...(validation ? [this.errorWrapper(validator(validation))] : []), |
| 75 | + ...middlewares.map(this.errorWrapper), |
| 76 | + this.errorWrapper(handler), |
| 77 | + ]) |
| 78 | + } |
| 79 | + } |
| 80 | + } |
| 81 | + |
| 82 | + private initializeErrorHandler(): void { |
| 83 | + this.app.use(errorHandler) |
11 | 84 | }
|
12 | 85 |
|
13 | 86 | public listen(port = config.port): void {
|
|
0 commit comments