All files / src app.ts

57.74% Statements 41/71
43.47% Branches 10/23
23.8% Functions 5/21
63.07% Lines 41/65

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112  7x                 7x 63x   7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x     7x 7x 7x 7x 7x 7x       7x 7x 7x       7x 7x 7x 7x       7x 7x     7x 7x 94x 94x                                                                               7x     7x       7x        
import bodyParser from 'body-parser';
import express, { NextFunction, Response, Express, Application } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import xss from 'x-xss-protection';
import cookieParser from 'cookie-parser';
import rateLimit from 'express-rate-limit';
import { parseAPIVersion } from './config/app.config';
import HttpStatusCode from './utils/HTTPStatusCodes';
import prisma from '@/services/prisma.service';
import { ResponseHandler } from '@/utils/responseHandler';
import { join } from 'path';
import { SwaggerService } from './services/swagger.service';
import { v1Routes } from './routes/v1';
 
export class App {
  app: Application;
  swaggerInstance: SwaggerService;
 
  constructor() {
    this.app = express();
    this.setupMiddlewares();
    SwaggerService.initializeSchemas();
    this.swaggerInstance = new SwaggerService(this.app);
    this.swaggerInstance.setupSwagger();
    this.setupMainApiRoute();
    // this.printRoutes();
  }
 
  private setupMiddlewares() {
    this.app.use(bodyParser.json());
    this.app.use(bodyParser.urlencoded({ extended: true }));
    this.app.use(
      cors({
        origin: '*',
        methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
      })
    );
    this.app.use(helmet());
    this.app.use(xss());
    this.app.use(cookieParser());
 
    const limiter = rateLimit({
      windowMs: 15 * 60 * 1000,
      max: 100,
    });
    this.app.use(limiter);
 
    this.app.use(express.static(join(__dirname, '../public')));
  }
 
  private setupMainApiRoute() {
    this.app.use(parseAPIVersion(1), v1Routes);
 
    this.app.all('*', (_, res: Response, next: NextFunction) => {
      const resBody = ResponseHandler.NotFound('Route Not Found');
      res.status(HttpStatusCode.NOT_FOUND).json(resBody);
      next();
    });
  }
 
  private printRoutes() {
    interface RouteInfo {
      path: string;
      methods: string;
    }
    function cleanPath(regexPath: string): string {
      return regexPath
        .replace(/\^\\\//g, '/')
        .replace(/\\\/\?\(\?=\.\*\$\)/g, '')
        .replace(/\\\//g, '/')
        .replace(/\(\?:\(\[\^\\\/]\+\?\(\?:\\\/\)\?\)\)/g, ':id')
        .replace('/?(?=/|$)', '');
    }
    function getRoutes(stack: any[], parentPath = ''): RouteInfo[] {
      const routes: RouteInfo[] = [];
      stack.forEach((middleware) => {
        if (middleware.route) {
          // Routes registered directly on the app
          const methods = Object.keys(middleware.route.methods).join(', ').toUpperCase();
          routes.push({ path: parentPath + middleware.route.path, methods });
        } else if (middleware.name === 'router') {
          // Routes added via router middleware
          const nestedPath = cleanPath(middleware.regexp.source);
          routes.push(...getRoutes(middleware.handle.stack, parentPath + nestedPath));
        }
      });
      return routes;
    }
    const routes = getRoutes(this.app._router.stack);
    routes.forEach((route) => {
      console.log(`${route.methods}: ${route.path}`);
    });
  }

  listen() {
    this.app.listen(process.env.PORT, () => {
      console.log(`Listening to port ${process.env.PORT}`);
    });
  }
}
 
// Handle Routes

// Graceful shutdown
process.on('SIGINT', async () => {
  await prisma.$disconnect();
  process.exit(0);
});
 
export default new App();