import {
IMonitorLocals,
contextMiddleware,
controllerLoader,
loggerEndpointMiddleware,
loggerSetupMiddleware,
Logger,
} from '@abyss-project/monitor';
import express, { Response, Request, NextFunction, Router } from 'express';
import { json, urlencoded } from 'body-parser';
import cors from 'cors';
import cookieParser from 'cookie-parser';
import helmet from 'helmet';
import compression from 'compression';
import swaggerUi from 'swagger-ui-express';
import MyController from './controllers/my-controller.controller.ts';
import MyMiddleware from './middlewares/my-middleware.middleware.ts';
require('express-async-errors');
const PREFIX = '/api';
const PORT = 5000;
const apiLogger = new Logger({
shouldDisableRemoteLogging: process.env.NODE_ENV === 'DEVELOPMENT',
});
const init = async (): Promise<express.Application> => {
const app = express();
// Adding the ContextMiddleware
app.use(contextMiddleware);
// Disabling the PoweredBy Express header
app.disable('x-powered-by');
// Enabling CORS and set kind of request my API will accept because
// I want to make this API public
app.use(cors());
app.use((req: Request, res: Response<unknown, ILocals>, next: NextFunction) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content, Accept, Content-Type, Authorization',
);
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
res.setHeader('Access-Control-Expose-Headers', 'Content-disposition, filename');
next();
});
app.use(urlencoded({ extended: true }));
app.use(json());
app.use(cookieParser());
app.use(helmet());
app.use(compression());
// Setting logger middleware
app.use(loggerSetupMiddleware);
app.use((req, res: Response<unknown, IMonitorLocals>, next) =>
loggerEndpointMiddleware(apiLogger, req, res, next),
);
// Setting up the swagger
const {
swagger: { tags, paths },
} = await controllerLoader(app, {
prefix: PREFIX,
router: Router,
middlewares: [MyMiddleware],
controllers: [MyController],
});
app.use(
(error: Error, _req: Request, _res: Response<unknown, IMonitorLocals>, _next: NextFunction) => {
// Do what you want with the error
apiLogger.error(error);
},
);
app
.listen(PORT, () => {
apiLogger.info(`API started on port ${PORT}`);
})
.on('error', (error) => {
apiLogger.error(`API failed to start. Error: ${error}`);
});
const defaultSwagger = {
openapi: '3.0.3',
info: {
title: 'My First API',
description: '',
version: '1.0',
termsOfService: 'http://swagger.io/terms/',
contact: {
email: 'apiteam@swagger.io',
},
license: {
name: 'Apache 2.0',
},
url: 'http://www.apache.org/licenses/LICENSE-2.0.html',
},
produces: ['application/json'],
host: `http://localhost:${PORT}`,
basePath: PREFIX,
tags,
paths,
};
app.use(
'/swagger',
(req: Request, res: Response<unknown, IMonitorLocals>, next: NextFunction) => {
// Disabling the log on swagger endpoint to not spam with useless logs
res.locals.shouldNotPublishLog = true;
next();
},
swaggerUi.serve,
// eslint-disable-next-line @typescript-eslint/no-var-requires
swaggerUi.setup(defaultSwagger),
);
return app;
};
await init();