-
Notifications
You must be signed in to change notification settings - Fork 29
/
server.ts
101 lines (94 loc) · 3.35 KB
/
server.ts
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
import express from "express";
import type compression from "compression";
import type fileUpload from "express-fileupload";
import http from "node:http";
import https from "node:https";
import { AppConfig, CommonConfig, ServerConfig } from "./config-type";
import {
AbstractLogger,
createLogger,
isSimplifiedWinstonConfig,
} from "./logger";
import { loadPeer } from "./peer-helpers";
import { defaultResultHandler } from "./result-handler";
import { Routing, initRouting } from "./routing";
import {
createNotFoundHandler,
createParserFailureHandler,
} from "./server-helpers";
const makeCommonEntities = async (config: CommonConfig) => {
const rootLogger: AbstractLogger = isSimplifiedWinstonConfig(config.logger)
? createLogger({ ...config.logger, winston: await loadPeer("winston") })
: config.logger;
const errorHandler = config.errorHandler || defaultResultHandler;
const { childLoggerProvider: getChildLogger } = config;
const creatorParams = { errorHandler, rootLogger, getChildLogger };
const notFoundHandler = createNotFoundHandler(creatorParams);
const parserFailureHandler = createParserFailureHandler(creatorParams);
return { rootLogger, errorHandler, notFoundHandler, parserFailureHandler };
};
export const attachRouting = async (config: AppConfig, routing: Routing) => {
const { rootLogger, notFoundHandler } = await makeCommonEntities(config);
initRouting({ app: config.app, routing, rootLogger, config });
return { notFoundHandler, logger: rootLogger };
};
export const createServer = async (config: ServerConfig, routing: Routing) => {
const app = express().disable("x-powered-by");
if (config.server.compression) {
const compressor = await loadPeer<typeof compression>("compression");
app.use(
compressor(
typeof config.server.compression === "object"
? config.server.compression
: undefined,
),
);
}
app.use(config.server.jsonParser || express.json());
if (config.server.upload) {
const uploader = await loadPeer<typeof fileUpload>("express-fileupload");
app.use(
uploader({
...(typeof config.server.upload === "object"
? config.server.upload
: {}),
abortOnLimit: false,
parseNested: true,
}),
);
}
if (config.server.rawParser) {
app.use(config.server.rawParser);
app.use((req, {}, next) => {
if (Buffer.isBuffer(req.body)) {
req.body = { raw: req.body };
}
next();
});
}
const { rootLogger, notFoundHandler, parserFailureHandler } =
await makeCommonEntities(config);
app.use(parserFailureHandler);
if (config.server.beforeRouting) {
await config.server.beforeRouting({ app, logger: rootLogger });
}
initRouting({ app, routing, rootLogger, config });
app.use(notFoundHandler);
const starter = <T extends http.Server | https.Server>(
server: T,
subject: typeof config.server.listen,
) =>
server.listen(subject, () => {
rootLogger.info("Listening", subject);
}) as T;
const servers = {
httpServer: starter(http.createServer(app), config.server.listen),
httpsServer: config.https
? starter(
https.createServer(config.https.options, app),
config.https.listen,
)
: undefined,
} satisfies Record<string, http.Server | https.Server | undefined>;
return { app, ...servers, logger: rootLogger };
};