Repository navigation
Expand file tree
/
Copy pathserver.js
More file actions
107 lines (86 loc) · 3.29 KB
/
Copy pathserver.js
File metadata and controls
107 lines (86 loc) · 3.29 KB
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
const dotenv = require('dotenv');
const cors = require('cors');
const express = require('express');
const swaggerUi = require('swagger-ui-express');
const openApiSpecification = require('./api-docs/openapi.json');
const http = require('http');
const logger = require('morgan');
const router = require('./routes/index');
const errors = require('./utils/errors');
const requestLogging = require('./utils/requestLogging');
dotenv.load();
const error = new errors.errors();
const swaggerSetupOptions = {
swaggerOptions: {
supportedSubmitMethods: []
},
customCss: `.swagger-ui .try-out { display: none }
.swagger-ui .scheme-container { display: none }
.swagger-ui .parameter__name { font-weight: bold; margin-top: 20px; }
.swagger-ui .renderedMarkdown {margin-bottom: 20px; margin-top: 20px;}
.swagger-ui tr {border-bottom: .5px solid gray;}
.swagger-ui .parameters-col_description input { display: none }`
};
function createRequestLogger() {
if (process.env.NODE_ENV === 'test') {
return (_req, _res, next) => next();
}
logger.token('redacted-url', requestLogging.getRedactedRequestPath);
logger.token('request-id', (req) => req.requestId || '-');
return logger(':method :redacted-url :status :res[content-length] - :response-time ms request-id=:request-id', {
skip: requestLogging.shouldSkipAccessLog
});
}
function handleRequestError(err, req, res, next) {
if (res.headersSent) return next(err);
if (err?.type === 'entity.parse.failed') {
return res.status(400).json(error.malformedJsonError());
}
const errorStatus = err?.status ?? err?.statusCode;
const status = Number.isInteger(errorStatus) && errorStatus >= 400 && errorStatus <= 599 ? errorStatus : 500;
if (err?.type === 'entity.too.large' || status === 413) {
return res.status(413).json(error.requestBodyTooLargeError());
}
if (status === 415) {
return res
.status(415)
.json(req.path === '/search' ? error.searchContentTypeError() : error.requestEncodingError());
}
return res.status(status).json(status < 500 ? error.invalidRequestError() : error.internalServerError());
}
function createApp() {
const app = express();
app.use(requestLogging.assignRequestId);
app.use(createRequestLogger());
app.use(cors());
app.use(express.json());
app.get('/api-docs/openapi.json', (req, res) => res.json(openApiSpecification));
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(openApiSpecification, swaggerSetupOptions));
app.use('/', router);
app.use(handleRequestError);
return app;
}
function getRuntimeConfig(port) {
return {
baseURL: process.env.BASE_URL || `http://127.0.0.1:${port}`
};
}
function startServer(port = process.env.PORT || 3000) {
const app = createApp();
const config = getRuntimeConfig(port);
return http.createServer(app).listen(port, () => {
console.log(`Listening on ${config.baseURL}`);
});
}
if (require.main === module) {
startServer();
}
module.exports = {
createApp,
createRequestLogger,
getRedactedRequestPath: requestLogging.getRedactedRequestPath,
getRuntimeConfig,
handleRequestError,
startServer,
swaggerSetupOptions
};