node-server-engine 1.4.8 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (261) hide show
  1. package/.commitlintrc.js +27 -0
  2. package/.releaserc.js +56 -0
  3. package/README.md +154 -2
  4. package/dist/const/tokenIssuer.js +1 -0
  5. package/dist/const/tokenIssuer.js.map +1 -1
  6. package/dist/db/models/SequelizeMeta.js +3 -1
  7. package/dist/db/models/SequelizeMeta.js.map +1 -1
  8. package/dist/entities/ElasticSearch/ElasticSearch.js +1 -2
  9. package/dist/entities/ElasticSearch/ElasticSearch.js.map +1 -1
  10. package/dist/entities/SocketClient/SocketClient.js +1 -0
  11. package/dist/entities/SocketClient/SocketClient.js.map +1 -1
  12. package/dist/index.js +1 -2
  13. package/dist/index.js.map +1 -1
  14. package/dist/middleware/checkPermission/checkPermission.d.ts +1 -1
  15. package/dist/middleware/checkPermission/checkPermission.js +4 -2
  16. package/dist/middleware/checkPermission/checkPermission.js.map +1 -1
  17. package/dist/utils/createHttpServer/createHttpServer.js +1 -1
  18. package/dist/utils/createHttpServer/createHttpServer.js.map +1 -1
  19. package/dist/utils/jwt/jwt.js +1 -1
  20. package/dist/utils/jwt/jwt.js.map +1 -1
  21. package/dist/utils/semverCompare/semverCompare.js +1 -5
  22. package/dist/utils/semverCompare/semverCompare.js.map +1 -1
  23. package/package.json +30 -19
  24. package/.env.example +0 -186
  25. package/.github/workflows/publish.yml +0 -41
  26. package/.prettierrc +0 -7
  27. package/Dockerfile +0 -31
  28. package/babel.config.json +0 -34
  29. package/eslint.config.mjs +0 -11
  30. package/src/const/DebeziumEvent.ts +0 -6
  31. package/src/const/LogSeverity.ts +0 -7
  32. package/src/const/index.ts +0 -5
  33. package/src/const/metrics.ts +0 -6
  34. package/src/const/mime.ts +0 -37
  35. package/src/const/tokenIssuer.ts +0 -7
  36. package/src/db/migrations/20241030121500-create-sequelize-meta-table.ts +0 -29
  37. package/src/db/models/SequelizeMeta.ts +0 -16
  38. package/src/db/models/index.ts +0 -2
  39. package/src/entities/ElasticSearch/ElasticSearch.ts +0 -103
  40. package/src/entities/ElasticSearch/ElasticSearch.types.ts +0 -7
  41. package/src/entities/ElasticSearch/index.ts +0 -2
  42. package/src/entities/Endpoint/Endpoint.test.ts +0 -248
  43. package/src/entities/Endpoint/Endpoint.ts +0 -221
  44. package/src/entities/Endpoint/Endpoint.types.ts +0 -181
  45. package/src/entities/Endpoint/index.ts +0 -2
  46. package/src/entities/EngineError/EngineError.ts +0 -28
  47. package/src/entities/EngineError/EngineError.types.ts +0 -15
  48. package/src/entities/EngineError/index.ts +0 -2
  49. package/src/entities/KeySet/KeySet.test.ts +0 -126
  50. package/src/entities/KeySet/KeySet.ts +0 -172
  51. package/src/entities/KeySet/KeySet.types.ts +0 -28
  52. package/src/entities/KeySet/index.ts +0 -2
  53. package/src/entities/LifecycleController/LifecycleController.test.ts +0 -48
  54. package/src/entities/LifecycleController/LifecycleController.ts +0 -24
  55. package/src/entities/LifecycleController/LifecycleController.types.ts +0 -5
  56. package/src/entities/LifecycleController/index.ts +0 -2
  57. package/src/entities/Localizator/Localizator.ts +0 -139
  58. package/src/entities/Localizator/Localizator.types.ts +0 -52
  59. package/src/entities/Localizator/guessNamingConvention/guessNamingConvention.test.ts +0 -165
  60. package/src/entities/Localizator/guessNamingConvention/guessNamingConvention.ts +0 -58
  61. package/src/entities/Localizator/guessNamingConvention/index.ts +0 -1
  62. package/src/entities/Localizator/index.ts +0 -2
  63. package/src/entities/MessageHandler/MessageHandler.test.ts +0 -130
  64. package/src/entities/MessageHandler/MessageHandler.ts +0 -72
  65. package/src/entities/MessageHandler/MessageHandler.types.ts +0 -15
  66. package/src/entities/MessageHandler/index.ts +0 -2
  67. package/src/entities/PubSub/PubSub.test.ts +0 -297
  68. package/src/entities/PubSub/PubSub.ts +0 -202
  69. package/src/entities/PubSub/PubSub.types.ts +0 -76
  70. package/src/entities/PubSub/handleMessage/handleMessage.test.ts +0 -102
  71. package/src/entities/PubSub/handleMessage/handleMessage.ts +0 -65
  72. package/src/entities/PubSub/handleMessage/index.ts +0 -1
  73. package/src/entities/PubSub/index.ts +0 -2
  74. package/src/entities/PushNotification/PushNotification.test.ts +0 -35
  75. package/src/entities/PushNotification/PushNotification.ts +0 -44
  76. package/src/entities/PushNotification/PushNotification.types.ts +0 -25
  77. package/src/entities/PushNotification/index.ts +0 -2
  78. package/src/entities/Redis/Redis.ts +0 -71
  79. package/src/entities/Redis/Redis.types.ts +0 -19
  80. package/src/entities/Redis/Redis.validate.ts +0 -17
  81. package/src/entities/Redis/index.ts +0 -2
  82. package/src/entities/Sequelize/Sequelize.config.ts +0 -59
  83. package/src/entities/Sequelize/Sequelize.test.ts +0 -21
  84. package/src/entities/Sequelize/Sequelize.ts +0 -75
  85. package/src/entities/Sequelize/Sequelize.types.ts +0 -10
  86. package/src/entities/Sequelize/Sequelize.validate.ts +0 -15
  87. package/src/entities/Sequelize/index.ts +0 -2
  88. package/src/entities/Server/Server.const.ts +0 -56
  89. package/src/entities/Server/Server.test.ts +0 -272
  90. package/src/entities/Server/Server.ts +0 -471
  91. package/src/entities/Server/Server.types.ts +0 -88
  92. package/src/entities/Server/index.ts +0 -2
  93. package/src/entities/SocketClient/SocketClient.test.ts +0 -392
  94. package/src/entities/SocketClient/SocketClient.ts +0 -401
  95. package/src/entities/SocketClient/SocketClient.types.ts +0 -62
  96. package/src/entities/SocketClient/index.ts +0 -2
  97. package/src/entities/SocketClient/parseMessage/index.ts +0 -1
  98. package/src/entities/SocketClient/parseMessage/parseMessage.test.ts +0 -20
  99. package/src/entities/SocketClient/parseMessage/parseMessage.ts +0 -26
  100. package/src/entities/Storage/Storage.test.ts +0 -58
  101. package/src/entities/Storage/Storage.ts +0 -219
  102. package/src/entities/Storage/Storage.types.ts +0 -57
  103. package/src/entities/Storage/index.ts +0 -2
  104. package/src/entities/ValidationError/ValidationError.ts +0 -34
  105. package/src/entities/ValidationError/index.ts +0 -1
  106. package/src/entities/WebError/WebError.test.ts +0 -18
  107. package/src/entities/WebError/WebError.ts +0 -23
  108. package/src/entities/WebError/WebError.types.ts +0 -9
  109. package/src/entities/WebError/index.ts +0 -2
  110. package/src/entities/index.ts +0 -16
  111. package/src/index.ts +0 -6
  112. package/src/metrics/debug.ts +0 -10
  113. package/src/metrics/index.ts +0 -2
  114. package/src/metrics/request.ts +0 -17
  115. package/src/middleware/authHmac/authHmac.test.ts +0 -86
  116. package/src/middleware/authHmac/authHmac.ts +0 -56
  117. package/src/middleware/authHmac/authHmac.types.ts +0 -7
  118. package/src/middleware/authHmac/index.ts +0 -2
  119. package/src/middleware/authJwt/authJwt.test.ts +0 -54
  120. package/src/middleware/authJwt/authJwt.ts +0 -55
  121. package/src/middleware/authJwt/authJwt.types.ts +0 -14
  122. package/src/middleware/authJwt/index.ts +0 -2
  123. package/src/middleware/authStatic/authStatic.test.ts +0 -36
  124. package/src/middleware/authStatic/authStatic.ts +0 -45
  125. package/src/middleware/authStatic/index.ts +0 -1
  126. package/src/middleware/authTls/authTls.test.ts +0 -138
  127. package/src/middleware/authTls/authTls.ts +0 -119
  128. package/src/middleware/authTls/authTls.types.ts +0 -13
  129. package/src/middleware/authTls/index.ts +0 -2
  130. package/src/middleware/checkPermission/checkPermission.ts +0 -33
  131. package/src/middleware/checkPermission/index.ts +0 -1
  132. package/src/middleware/error/error.test.ts +0 -60
  133. package/src/middleware/error/error.ts +0 -25
  134. package/src/middleware/error/index.ts +0 -1
  135. package/src/middleware/fileUploader/fileUploader.ts +0 -154
  136. package/src/middleware/fileUploader/fileUploader.types.ts +0 -35
  137. package/src/middleware/fileUploader/index.ts +0 -2
  138. package/src/middleware/fileUploader/isMultiPart/index.ts +0 -1
  139. package/src/middleware/fileUploader/isMultiPart/isMultipart.ts +0 -9
  140. package/src/middleware/fileUploader/validate/index.ts +0 -1
  141. package/src/middleware/fileUploader/validate/validate.ts +0 -27
  142. package/src/middleware/fourOhFour/fourOhFour.test.ts +0 -14
  143. package/src/middleware/fourOhFour/fourOhFour.ts +0 -13
  144. package/src/middleware/fourOhFour/index.ts +0 -1
  145. package/src/middleware/geminiFileUploader/geminiFileUploader.ts +0 -68
  146. package/src/middleware/geminiFileUploader/index.ts +0 -1
  147. package/src/middleware/healthCheck/healthCheck.test.ts +0 -12
  148. package/src/middleware/healthCheck/healthCheck.ts +0 -14
  149. package/src/middleware/healthCheck/index.ts +0 -1
  150. package/src/middleware/index.ts +0 -17
  151. package/src/middleware/metrics/index.ts +0 -1
  152. package/src/middleware/metrics/metrics.test.ts +0 -46
  153. package/src/middleware/metrics/metrics.ts +0 -24
  154. package/src/middleware/multiPartFileUploader/index.ts +0 -2
  155. package/src/middleware/multiPartFileUploader/multiPartFileUploader.ts +0 -249
  156. package/src/middleware/multiPartFileUploader/multiPartFileUploader.types.ts +0 -23
  157. package/src/middleware/multiPartFileUploader/validate/index.ts +0 -1
  158. package/src/middleware/multiPartFileUploader/validate/validate.ts +0 -27
  159. package/src/middleware/requestMetrics/index.ts +0 -1
  160. package/src/middleware/requestMetrics/requestMetrics.test.ts +0 -77
  161. package/src/middleware/requestMetrics/requestMetrics.ts +0 -20
  162. package/src/middleware/swaggerDocs/index.ts +0 -2
  163. package/src/middleware/swaggerDocs/swaggerDocs.ts +0 -114
  164. package/src/middleware/swaggerDocs/swaggerDocs.types.ts +0 -41
  165. package/src/middleware/userResolver/index.ts +0 -1
  166. package/src/middleware/userResolver/userResolver.ts +0 -53
  167. package/src/middleware/validate/index.ts +0 -1
  168. package/src/middleware/validate/validate.test.ts +0 -43
  169. package/src/middleware/validate/validate.ts +0 -25
  170. package/src/middleware/version/index.ts +0 -1
  171. package/src/middleware/version/version.test.ts +0 -23
  172. package/src/middleware/version/version.ts +0 -12
  173. package/src/utils/checkEnvironment/index.ts +0 -49
  174. package/src/utils/createHttpServer/createHttpServer.test.ts +0 -24
  175. package/src/utils/createHttpServer/createHttpServer.ts +0 -34
  176. package/src/utils/createHttpServer/createHttpServer.validate.ts +0 -17
  177. package/src/utils/createHttpServer/index.ts +0 -1
  178. package/src/utils/createSortedObject/createSortedObject.ts +0 -20
  179. package/src/utils/createSortedObject/createSortedObjet.test.ts +0 -47
  180. package/src/utils/createSortedObject/index.ts +0 -1
  181. package/src/utils/dbMigration/dbMigration.test.ts +0 -209
  182. package/src/utils/dbMigration/dbMigration.ts +0 -199
  183. package/src/utils/dbMigration/dbMigration.types.ts +0 -11
  184. package/src/utils/dbMigration/index.ts +0 -2
  185. package/src/utils/dbMigration/migrateMetadataTable/index.ts +0 -1
  186. package/src/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.test.ts +0 -59
  187. package/src/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.ts +0 -102
  188. package/src/utils/envAssert/envAssert.ts +0 -31
  189. package/src/utils/envAssert/index.ts +0 -1
  190. package/src/utils/envAssert/validators/hostList.ts +0 -17
  191. package/src/utils/envAssert/validators/index.ts +0 -5
  192. package/src/utils/envAssert/validators/ipList.ts +0 -13
  193. package/src/utils/envAssert/validators/path.ts +0 -13
  194. package/src/utils/envAssert/validators/string.ts +0 -9
  195. package/src/utils/envAssert/validators/stringList.ts +0 -13
  196. package/src/utils/filter/filter.ts +0 -17
  197. package/src/utils/filter/index.ts +0 -1
  198. package/src/utils/geminiFileUpload/geminiFileUpload.ts +0 -93
  199. package/src/utils/geminiFileUpload/index.ts +0 -1
  200. package/src/utils/hmac/checkEnv/checkEnv.test.ts +0 -18
  201. package/src/utils/hmac/checkEnv/checkEnv.ts +0 -9
  202. package/src/utils/hmac/checkEnv/index.ts +0 -1
  203. package/src/utils/hmac/createHmac/createHmac.ts +0 -33
  204. package/src/utils/hmac/createHmac/index.ts +0 -1
  205. package/src/utils/hmac/index.ts +0 -4
  206. package/src/utils/hmac/index.types.ts +0 -13
  207. package/src/utils/hmac/signPayload/index.ts +0 -1
  208. package/src/utils/hmac/signPayload/signPayload.ts +0 -16
  209. package/src/utils/hmac/verifySignature/index.ts +0 -1
  210. package/src/utils/hmac/verifySignature/verifySignature.ts +0 -24
  211. package/src/utils/index.ts +0 -29
  212. package/src/utils/jwt/index.ts +0 -2
  213. package/src/utils/jwt/jwt.test.ts +0 -28
  214. package/src/utils/jwt/jwt.ts +0 -182
  215. package/src/utils/jwt/jwt.types.ts +0 -21
  216. package/src/utils/report/index.ts +0 -3
  217. package/src/utils/report/output.ts +0 -45
  218. package/src/utils/report/output.types.ts +0 -70
  219. package/src/utils/report/report.test.ts +0 -133
  220. package/src/utils/report/report.ts +0 -133
  221. package/src/utils/report/report.types.ts +0 -13
  222. package/src/utils/request/index.ts +0 -1
  223. package/src/utils/request/request.test.ts +0 -26
  224. package/src/utils/request/request.ts +0 -48
  225. package/src/utils/secretManager/index.ts +0 -2
  226. package/src/utils/secretManager/secretLoader.ts +0 -62
  227. package/src/utils/secretManager/secretResolver.ts +0 -35
  228. package/src/utils/semverCompare/index.ts +0 -1
  229. package/src/utils/semverCompare/semverCompare.test.ts +0 -49
  230. package/src/utils/semverCompare/semverCompare.ts +0 -60
  231. package/src/utils/sendEmail/index.ts +0 -2
  232. package/src/utils/sendEmail/sendEmail.ts +0 -61
  233. package/src/utils/sendEmail/sendEmail.types.ts +0 -61
  234. package/src/utils/sendPush/index.ts +0 -2
  235. package/src/utils/sendPush/sendPush.ts +0 -20
  236. package/src/utils/sendPush/sendPush.types.ts +0 -25
  237. package/src/utils/tlsConfig/index.ts +0 -2
  238. package/src/utils/tlsConfig/tlsConfig.test.ts +0 -32
  239. package/src/utils/tlsConfig/tlsConfig.ts +0 -47
  240. package/src/utils/tlsConfig/tlsConfig.types.ts +0 -11
  241. package/src/utils/tlsConfig/tlsConfig.validate.ts +0 -25
  242. package/src/utils/tlsRequest/index.ts +0 -1
  243. package/src/utils/tlsRequest/tlsRequest.test.ts +0 -63
  244. package/src/utils/tlsRequest/tlsRequest.ts +0 -12
  245. package/src/utils/trimPathSlash/index.ts +0 -1
  246. package/src/utils/trimPathSlash/trimPathSlash.test.ts +0 -26
  247. package/src/utils/trimPathSlash/trimPathSlash.ts +0 -8
  248. package/test/env.ts +0 -53
  249. package/test/factory/index.ts +0 -8
  250. package/test/factory/sequelizeMeta.ts +0 -12
  251. package/test/hooks.ts +0 -35
  252. package/test/index.ts +0 -3
  253. package/test/stub/index.ts +0 -3
  254. package/test/stub/stubLocales.ts +0 -68
  255. package/test/stub/stubPubSub.ts +0 -7
  256. package/test/stub/stubStorage.ts +0 -77
  257. package/test/stub/stubStorage.types.ts +0 -11
  258. package/test/utils/app.ts +0 -31
  259. package/test/utils/index.ts +0 -1
  260. package/tsconfig.build.json +0 -5
  261. package/tsconfig.json +0 -32
@@ -1,471 +0,0 @@
1
- import fs from 'fs';
2
- import http from 'http';
3
- import https from 'https';
4
- import { AddressInfo } from 'net';
5
- import path from 'path';
6
- import { setTimeout as setTimeoutPromise } from 'timers/promises';
7
- import { ValidatorSpec } from 'envalid';
8
- import express, { Application } from 'express';
9
- import cors from 'cors';
10
- import { Server as WebSocketServer } from 'ws';
11
- import { SocketClient } from '../SocketClient';
12
- import {
13
- defaultMiddleware,
14
- defaultErrorMiddleware,
15
- secondaryMiddleware,
16
- shutdownSignals
17
- } from './Server.const';
18
- import {
19
- ServerOptions,
20
- ServerCronJon,
21
- ServerAuthConfig,
22
- ServerWebSocketConfig,
23
- ServerGlobalMiddleware,
24
- ServerErrorMiddleWare,
25
- ServerCallback
26
- } from './Server.types';
27
- import { Endpoint } from 'entities/Endpoint';
28
- import { EngineError } from 'entities/EngineError';
29
- import { LifecycleController } from 'entities/LifecycleController';
30
- import { PubSub } from 'entities/PubSub';
31
- import { checkEnvironment, envAssert, createHttpServer } from 'utils';
32
- import { initKeySets, shutdownKeySets } from 'utils/jwt';
33
- import { reportInfo, reportError, reportDebug } from 'utils/report';
34
- import { tlsConfig, loadTlsConfig, TlsConfig } from 'utils/tlsConfig';
35
-
36
- const namespace = 'engine:Server';
37
-
38
- /** Main server class */
39
- export class Server {
40
- /** The express application powering the main endpoints */
41
- private app: Application;
42
- /** The node HTTP(S) server, serving the main express application */
43
- private httpServer: http.Server | https.Server;
44
- /** The express application powering the support endpoints */
45
- private secondaryApp: Application;
46
- /** The node HTTP(S) server, serving the secondary express application */
47
- private secondaryHttpServer: http.Server | https.Server;
48
- /** List of endpoint instances that the server should handle */
49
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
- private endpoints: Array<Endpoint<any>>;
51
- /** Mapping of env variable name with functions that should run to check their validity */
52
- private checkEnvironment: Record<string, ValidatorSpec<unknown>>;
53
- /** Middleware that should run on every request before the endpoint specific logic */
54
- private globalMiddleware: Array<ServerGlobalMiddleware>;
55
- /** Error middleware that should run on every request after the endpoint specific logic, but before the generic global middleware */
56
- private errorMiddleware: Array<
57
- ServerGlobalMiddleware | ServerErrorMiddleWare
58
- >;
59
- /** Functions that should be called on server startup */
60
- private initCallbacks: Array<ServerCallback>;
61
- /** Functions that should be called on server shutdown */
62
- private shutdownCallbacks: Array<ServerCallback>;
63
- /** When set to true, this indicates that init callbacks should run synchronously in the order they are declared. By default they all run in parallel */
64
- private syncCallbacks: boolean;
65
- /** Config to set regularly running jobs on the server */
66
- private cron?: Array<ServerCronJon>;
67
- /** Global auth related configuration */
68
- private auth: ServerAuthConfig;
69
- /** WebSocket server instance, if configured */
70
- private wss?: WebSocketServer;
71
- /** Abort controller that handles signals for the server */
72
- private abortController = new AbortController();
73
-
74
- /** Create a server */
75
- public constructor(config: ServerOptions) {
76
- this.validate(config);
77
-
78
- reportDebug({
79
- namespace,
80
- message: `Creating server`
81
- });
82
-
83
- this.endpoints = config.endpoints;
84
- this.globalMiddleware = config.globalMiddleware ?? [];
85
- this.errorMiddleware = config.errorMiddleware ?? [];
86
- this.initCallbacks = config.initCallbacks ?? [];
87
- this.shutdownCallbacks = config.shutdownCallbacks ?? [];
88
- this.syncCallbacks = config.syncCallbacks ?? false;
89
- this.cron = config.cron;
90
- this.auth = { noFetch: false, ...config.auth };
91
-
92
- // The minimal environment check is different between the migration modes of execution and the regular server execution mode
93
- // When running in migration mode, we only check that we have SQL related environment variables
94
- this.checkEnvironment =
95
- process.env.RUN_MIGRATION === 'true' ||
96
- process.env.UNDO_MIGRATION === 'true'
97
- ? {
98
- SQL_HOST: envAssert.isHost(),
99
- SQL_USER: envAssert.isString(),
100
- SQL_PASSWORD: envAssert.isString(),
101
- SQL_DB: envAssert.isString()
102
- }
103
- : {
104
- NODE_ENV: envAssert.isString(),
105
- PORT: envAssert.isPort(),
106
- SECONDARY_PORT: envAssert.isPort(),
107
- ...config.checkEnvironment
108
- };
109
-
110
- checkEnvironment(this.checkEnvironment);
111
-
112
- // Create the primary express core that serves the business logic
113
- this.app = express();
114
- this.app.use(
115
- cors({
116
- origin: process.env.CORS_ORIGIN ?? '*',
117
- methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
118
- allowedHeaders: ['Content-Type', 'Authorization']
119
- })
120
- );
121
- this.registerMiddleware(this.app);
122
- this.httpServer = createHttpServer(this.app);
123
-
124
- // Create a secondary express core that servers metrics and analytics
125
- // This will be served on a different port, allowing to specify different firewall rules for these routes
126
- this.secondaryApp = express();
127
- [...secondaryMiddleware, ...defaultErrorMiddleware].forEach(
128
- (middleware) => {
129
- if (middleware) this.secondaryApp.use(middleware);
130
- }
131
- );
132
- this.secondaryHttpServer = createHttpServer(this.secondaryApp);
133
-
134
- // Remove the express headers
135
- this.app.disable('x-powered-by');
136
- this.secondaryApp.disable('x-powered-by');
137
-
138
- // We remove all node timeout on connections and requests
139
- // This responsibility is delegated to the front-facing load balancer
140
- [this.httpServer, this.secondaryHttpServer].forEach((server) => {
141
- server.headersTimeout = 0;
142
- server.keepAliveTimeout = 0;
143
- });
144
-
145
- if (config.webSocket) {
146
- this.attachWebSocket(config.webSocket);
147
- }
148
- }
149
-
150
- private setupGlobalErrorLogging(): void {
151
- process.on('uncaughtException', (err) => {
152
- console.error(
153
- '💥 uncaughtException:',
154
- err && err.stack ? err.stack : err
155
- );
156
- });
157
- process.on('unhandledRejection', (reason: unknown) => {
158
- if (reason instanceof Error) {
159
- console.error('💥 unhandledRejection:', reason.stack || reason.message);
160
- } else {
161
- console.error('💥 unhandledRejection:', reason);
162
- }
163
- });
164
- process.on('beforeExit', (code) =>
165
- console.error('process.beforeExit', code)
166
- );
167
- }
168
-
169
- /** Start the server */
170
- public async init(): Promise<void> {
171
- // this.setupGlobalErrorLogging();
172
- reportDebug({ namespace, message: `Starting Server` });
173
- // Fetch the keys for JWT authentication
174
- // Ignore in test environment as we do symmetrical token signing
175
- if (process.env.NODE_ENV !== 'test' && !this.auth.noFetch)
176
- await initKeySets();
177
- // Run all the init callbacks
178
- // We can either run them all 1/1 synchronously or run them all in parallel (default)
179
- // Callback can either be direct function or an object with function and parameters attributes
180
-
181
- if (this.syncCallbacks) {
182
- for (const callback of this.initCallbacks) {
183
- await this.runCallback(callback);
184
- }
185
- } else {
186
- await Promise.all(
187
- this.initCallbacks.map((callback) => this.runCallback(callback))
188
- );
189
- }
190
-
191
- // Initialize the Pub/Sub module
192
- await PubSub.init();
193
- // Run all the cronjob
194
- if (this.cron) {
195
- this.cron.forEach((job) => {
196
- this.runCronJob(job);
197
- });
198
- }
199
-
200
- // Start listening to requests
201
- await Promise.all([
202
- new Promise<void>((resolve) =>
203
- this.httpServer.listen(process.env.PORT, () => {
204
- resolve();
205
- })
206
- ),
207
- new Promise<void>((resolve) =>
208
- this.secondaryHttpServer.listen(process.env.SECONDARY_PORT, () => {
209
- resolve();
210
- })
211
- )
212
- ]);
213
- reportInfo({
214
- message: 'SERVER_RUNNING',
215
- data: {
216
- port: process.env.PORT,
217
- secondaryPort: process.env.SECONDARY_PORT,
218
- nodeEnv: process.env.NODE_ENV
219
- }
220
- });
221
-
222
- this.handleSignal();
223
-
224
- // Watch TSL config files changing
225
- this.watchTlsCaFileChange();
226
- }
227
-
228
- /** Graceful shutdown */
229
- public async shutdown(): Promise<void> {
230
- reportDebug({ namespace, message: `Shutting down Server` });
231
-
232
- // Stop listening to HTTP requests
233
- await Promise.all(
234
- [this.httpServer, this.secondaryHttpServer].map((server) => {
235
- // Ignore if the server was already stopped
236
- // We have observed cases where SIGTERM was thrown multiple times
237
- if (!server.listening) return;
238
- const { port } = server.address() as AddressInfo;
239
- server.on('close', (error: unknown) => {
240
- if (error) {
241
- reportError(error);
242
- process.exit(1);
243
- } else {
244
- reportInfo({
245
- message: `Stopped listening to requests on port ${port}`
246
- });
247
- }
248
- });
249
- server.close();
250
- })
251
- );
252
-
253
- // Close all socket connections
254
- if (this.wss) {
255
- // First ask then to close gracefully
256
- this.wss.clients.forEach((socket) => {
257
- socket.close();
258
- });
259
- // Hard terminate all connections still open after a defined time
260
- const socketKillTimeout = process.env.WEBSOCKET_CLOSE_TIMEOUT
261
- ? parseInt(process.env.WEBSOCKET_CLOSE_TIMEOUT)
262
- : 5000;
263
- await new Promise<void>((resolve) => {
264
- setTimeout(() => {
265
- (this.wss as WebSocketServer).clients.forEach((socket) => {
266
- if (
267
- socket.readyState === socket.CLOSING ||
268
- socket.readyState === socket.OPEN
269
- ) {
270
- socket.terminate();
271
- }
272
- });
273
- resolve();
274
- }, socketKillTimeout);
275
- });
276
- }
277
-
278
- // Run all the shutdown callback
279
- if (this.syncCallbacks) {
280
- for (const callback of this.shutdownCallbacks) {
281
- await this.runCallback(callback);
282
- }
283
- } else {
284
- await Promise.all(
285
- this.shutdownCallbacks.map((callback) => this.runCallback(callback))
286
- );
287
- }
288
-
289
- // Shutdown all the running entities
290
- await LifecycleController.shutdownRunningInstances();
291
-
292
- // Abort all the cronjob
293
- if (this.abortController) this.abortController.abort();
294
-
295
- // Stop the keyset timers
296
- shutdownKeySets();
297
-
298
- shutdownSignals.forEach((signal) => process.removeAllListeners(signal));
299
- }
300
-
301
- /** Get the express app instance of the server */
302
- public getApp(): Application {
303
- return this.app;
304
- }
305
-
306
- /** Get the express app instance of the server */
307
- public getSecondaryApp(): Application {
308
- return this.secondaryApp;
309
- }
310
-
311
- /** Registers all the middleware with the express app */
312
- private registerMiddleware(app: Application): void {
313
- // Global middleware can specify a path to which they apply
314
- [...defaultMiddleware, ...this.globalMiddleware].forEach((middleware) => {
315
- if (typeof middleware === 'function') {
316
- app.use(middleware);
317
- } else {
318
- app.use(middleware.path, middleware.middleware);
319
- }
320
- });
321
- // Call the register method of each endpoint
322
- this.endpoints.forEach((endpoint) => {
323
- endpoint.register(app);
324
- });
325
- // Add error middleware
326
- [...this.errorMiddleware, ...defaultErrorMiddleware].forEach(
327
- (middleware) => {
328
- if (typeof middleware === 'function') {
329
- app.use(middleware);
330
- } else {
331
- app.use(middleware.path, middleware.middleware);
332
- }
333
- }
334
- );
335
- }
336
-
337
- /** Add a handler for WebSocket connections */
338
- private attachWebSocket(options: ServerWebSocketConfig): void {
339
- this.wss = new WebSocketServer({
340
- ...options.server,
341
- server: this.httpServer
342
- })
343
- .on('connection', (webSocket, request) => {
344
- new SocketClient(webSocket, request, options.client);
345
- })
346
- .on('error', (error) => {
347
- reportError(error);
348
- });
349
- }
350
-
351
- /** Call shutdown if signal gets sent to the process */
352
- private handleSignal(): void {
353
- shutdownSignals.forEach((signal) =>
354
- process.on(signal, () => {
355
- (async (): Promise<void> => {
356
- reportInfo(`Received shutdown signal [${signal}]`);
357
- await this.shutdown();
358
- })().catch((error) => {
359
- reportError(error);
360
- });
361
- })
362
- );
363
- }
364
-
365
- /** Watch the TLS certificate change event */
366
- private watchTlsCaFileChange(): void {
367
- [
368
- 'TLS_REQUEST_KEY',
369
- 'TLS_REQUEST_CERT',
370
- 'TLS_REQUEST_CA',
371
- 'TLS_SERVER_KEY',
372
- 'TLS_SERVER_CERT',
373
- 'TLS_CA'
374
- ].forEach((key) => {
375
- const file = process.env[key];
376
- if (file)
377
- fs.watch(path.resolve(file), (event) => {
378
- if (event !== 'change') return;
379
- reportInfo(`Reloading TLS config [${file} changed]`);
380
- loadTlsConfig();
381
- (this.httpServer as https.Server).setSecureContext(
382
- tlsConfig as TlsConfig
383
- );
384
- });
385
- });
386
- }
387
-
388
- /** Executes a recurring job */
389
- private runCronJob(job: ServerCronJon): void {
390
- (async (): Promise<void> => {
391
- reportInfo({ message: `Starting scheduled job "${job.handler.name}"` });
392
- try {
393
- await job.handler();
394
- reportInfo({
395
- message: `Job "${job.handler.name}" finished, starting again in ${job.interval} seconds`
396
- });
397
- await setTimeoutPromise(job.interval * 1000, undefined, {
398
- signal: this.abortController.signal
399
- });
400
- this.runCronJob(job);
401
- } catch (error) {
402
- if (error instanceof Error && error.name === 'AbortError') {
403
- reportDebug({
404
- namespace,
405
- message: `Scheduled job "${job.handler?.name}" has been aborted`
406
- });
407
- } else {
408
- throw error;
409
- }
410
- }
411
- })().catch((error) => {
412
- reportError(error);
413
- });
414
- }
415
-
416
- /** Run a shutdown/init callback */
417
- private runCallback(callback: ServerCallback): unknown {
418
- return typeof callback === 'function'
419
- ? callback()
420
- : callback.function.apply(null, callback.parameters ?? []);
421
- }
422
-
423
- /**
424
- * Validate the Server constructor configuration
425
- */
426
- private validate(config: ServerOptions): void {
427
- if (
428
- !config.endpoints ||
429
- config.endpoints.some((endpoint) => !(endpoint instanceof Endpoint))
430
- )
431
- throw new EngineError(
432
- 'Server endpoints should be declared and all be Endpoint instances'
433
- );
434
-
435
- if (
436
- config.checkEnvironment &&
437
- Object.values(config.checkEnvironment).some(
438
- (validator) => typeof validator !== 'function'
439
- )
440
- )
441
- throw new EngineError(
442
- 'Some of the environment checks are not valid functions'
443
- );
444
-
445
- if (
446
- config.initCallbacks &&
447
- (!(config.initCallbacks instanceof Array) ||
448
- config.initCallbacks.some(
449
- (callback) =>
450
- !(
451
- typeof callback === 'function' ||
452
- typeof callback?.function === 'function'
453
- )
454
- ))
455
- )
456
- throw new EngineError('Init callbacks is not a list of functions');
457
-
458
- if (
459
- config.shutdownCallbacks &&
460
- (!(config.shutdownCallbacks instanceof Array) ||
461
- config.shutdownCallbacks.some(
462
- (callback) =>
463
- !(
464
- typeof callback === 'function' ||
465
- typeof callback?.function === 'function'
466
- )
467
- ))
468
- )
469
- throw new EngineError('Shutdown callbacks is not a list of functions');
470
- }
471
- }
@@ -1,88 +0,0 @@
1
- import { ValidatorSpec } from 'envalid';
2
- import { ErrorRequestHandler, RequestHandler } from 'express';
3
- import { ServerOptions as WebSocketServerOptions } from 'ws';
4
- import { Endpoint } from 'entities/Endpoint';
5
- import { SocketClientOptions } from 'entities/SocketClient';
6
-
7
- /** Options to create a server */
8
- export interface ServerOptions {
9
- /** List of endpoint instances that the server should handle */
10
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
- endpoints: Array<Endpoint<any>>;
12
- /** Mapping of env variable name with functions that should run to check their validity */
13
- checkEnvironment?: Record<string, ValidatorSpec<unknown>>;
14
- /** Middleware that should run on every request before the endpoint specific logic */
15
- globalMiddleware?: Array<ServerGlobalMiddleware>;
16
- /** Error middleware that should run on every request after the endpoint specific logic, but before the generic global middleware */
17
- errorMiddleware?: Array<ServerGlobalMiddleware | ServerErrorMiddleWare>;
18
- /** Functions that should be called on server startup */
19
- initCallbacks?: Array<ServerCallback>;
20
- /** Functions that should be called on server shutdown */
21
- shutdownCallbacks?: Array<ServerCallback>;
22
- /** When set to true, this indicates that init callbacks should run synchronously in the order they are declared. By default they all run in parallel */
23
- syncCallbacks?: boolean;
24
- /** Config to set regularly running jobs on the server */
25
- cron?: Array<ServerCronJon>;
26
- /** Global auth related configuration */
27
- auth?: ServerAuthConfig;
28
- /** Configuration to enable webSocket connections to the server */
29
- webSocket?: ServerWebSocketConfig;
30
- }
31
-
32
- /** Options for a CRON task on the server */
33
- export interface ServerCronJon {
34
- /** Function that is called when the job needs to run */
35
- handler: () => unknown;
36
- /** Interval (in seconds) between each job execution. The interval starts after the previous execution finished */
37
- interval: number;
38
- /** When this is set, the job is only run on the instance that is that has been elected leader of the service */
39
- leaderOnly?: boolean;
40
- }
41
-
42
- /** Common server authentication related config */
43
- export interface ServerAuthConfig {
44
- /** Do not fetch JWT authentication parameters, this should be used on servers that do not receive public requests and therefore do not need access to the authentication service */
45
- noFetch?: boolean;
46
- }
47
-
48
- /** Configuration for WebSocket on this server */
49
- export interface ServerWebSocketConfig {
50
- /** Options to pass to create the webSocket server */
51
- server: WebSocketServerOptions;
52
- /** Options to pass when creating socket client instances */
53
- client: SocketClientOptions;
54
- }
55
-
56
- /** Middleware function definition with path */
57
- export interface ServerObjectGlobalMiddleware {
58
- /** Path on which the middleware is used */
59
- path: string;
60
- /** Middleware function */
61
- middleware: RequestHandler;
62
- }
63
- export type ServerGlobalMiddleware =
64
- | RequestHandler
65
- | ServerObjectGlobalMiddleware;
66
-
67
- /** Error middleware function definition with path */
68
- export interface ServerObjectErrorMiddleware {
69
- /** Path on which the middleware is used */
70
- path: string;
71
- /** Middleware function */
72
- middleware: ErrorRequestHandler;
73
- }
74
- export type ServerErrorMiddleWare =
75
- | ErrorRequestHandler
76
- | ServerObjectErrorMiddleware;
77
-
78
- type ServerFunctionCallback = (...args: Array<unknown>) => unknown;
79
-
80
- /** Callback definition with parameters */
81
- interface ServerObjectCallback {
82
- /** Callback function */
83
- function: ServerFunctionCallback;
84
- /** Parameters to pass to the callback function */
85
- parameters?: Parameters<ServerFunctionCallback>;
86
- }
87
-
88
- export type ServerCallback = ServerFunctionCallback | ServerObjectCallback;
@@ -1,2 +0,0 @@
1
- export * from './Server';
2
- export * from './Server.types';