node-server-engine 1.6.0 → 1.7.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.
- package/README.md +70 -0
- package/dist/entities/Server/Server.const.js +3 -19
- package/dist/entities/Server/Server.const.js.map +1 -1
- package/dist/entities/Server/Server.d.ts +5 -0
- package/dist/entities/Server/Server.js +64 -19
- package/dist/entities/Server/Server.js.map +1 -1
- package/dist/middleware/error/error.js +0 -7
- package/dist/middleware/error/error.js.map +1 -1
- package/dist/middleware/index.d.ts +1 -0
- package/dist/middleware/index.js +11 -0
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/requestLogger/index.d.ts +1 -0
- package/dist/middleware/requestLogger/index.js +17 -0
- package/dist/middleware/requestLogger/index.js.map +1 -0
- package/dist/middleware/requestLogger/requestLogger.d.ts +6 -0
- package/dist/middleware/requestLogger/requestLogger.js +63 -0
- package/dist/middleware/requestLogger/requestLogger.js.map +1 -0
- package/dist/utils/report/output.js +35 -32
- package/dist/utils/report/output.js.map +1 -1
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -112,6 +112,76 @@ For development dependencies:
|
|
|
112
112
|
npm install --save-dev backend-test-tools
|
|
113
113
|
```
|
|
114
114
|
|
|
115
|
+
## Logging
|
|
116
|
+
|
|
117
|
+
The server provides structured logging with automatic format detection. In local development, logs are colorized and human-readable. In production (GCP, Kubernetes), logs are JSON formatted for log aggregation systems.
|
|
118
|
+
|
|
119
|
+
### Log Format
|
|
120
|
+
|
|
121
|
+
Logs automatically detect the environment:
|
|
122
|
+
- **Local Development**: Colorized, concise format with time (HH:MM:SS)
|
|
123
|
+
- **Production**: JSON structured logs for cloud log aggregation
|
|
124
|
+
|
|
125
|
+
### Environment Variables
|
|
126
|
+
|
|
127
|
+
| Variable | Values | Description | Default |
|
|
128
|
+
|----------|--------|-------------|---------|
|
|
129
|
+
| `LOG_FORMAT` | `local`, `json` | Force specific log format | Auto-detect |
|
|
130
|
+
| `DETAILED_LOGS` | `true`, `false` | Show stack traces and verbose details | `false` |
|
|
131
|
+
| `DEBUG` | `namespace:*` | Enable debug logs for specific namespaces | Off |
|
|
132
|
+
|
|
133
|
+
### Examples
|
|
134
|
+
|
|
135
|
+
**Default Local Format** (clean, concise):
|
|
136
|
+
```
|
|
137
|
+
[21:16:15] INFO SERVER_RUNNING
|
|
138
|
+
[21:16:15] INFO Connected to database successfully
|
|
139
|
+
[21:16:15] DEBUG POST /auth/login [200] 154ms
|
|
140
|
+
[21:20:15] DEBUG GET /users [304] 10ms
|
|
141
|
+
[21:20:15] WARNING No bearer token found [unauthorized 401] GET /users
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Detailed Logs** (`DETAILED_LOGS=true`):
|
|
145
|
+
```
|
|
146
|
+
[21:16:15] DEBUG POST /auth/login [200] 154ms
|
|
147
|
+
Data:
|
|
148
|
+
{
|
|
149
|
+
"responseTime": "154ms",
|
|
150
|
+
"contentLength": "1012",
|
|
151
|
+
"httpVersion": "1.1"
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
[21:20:15] WARNING No bearer token found [unauthorized 401] GET /users
|
|
155
|
+
Stack Trace:
|
|
156
|
+
Error: No bearer token found
|
|
157
|
+
at middleware (/path/to/authJwt.ts:31:13)
|
|
158
|
+
...
|
|
159
|
+
src/middleware/authJwt/authJwt.ts:31
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Production Format** (`LOG_FORMAT=json`):
|
|
163
|
+
```json
|
|
164
|
+
{"severity":"INFO","message":"SERVER_RUNNING","timestamp":"2025-12-09T21:16:15.028Z","serviceContext":{"service":"my-service","version":"1.0.0"}}
|
|
165
|
+
{"severity":"DEBUG","message":"POST /auth/login [200] 154ms","timestamp":"2025-12-09T21:16:15.182Z"}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Usage in Code
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
import { reportInfo, reportError, reportDebug } from 'node-server-engine';
|
|
172
|
+
|
|
173
|
+
// Info logging
|
|
174
|
+
reportInfo('Server started successfully');
|
|
175
|
+
reportInfo({ message: 'User login', data: { userId: '123' } });
|
|
176
|
+
|
|
177
|
+
// Error logging
|
|
178
|
+
reportError(error);
|
|
179
|
+
reportError(error, request); // Include HTTP request context
|
|
180
|
+
|
|
181
|
+
// Debug logging (requires DEBUG env var)
|
|
182
|
+
reportDebug({ namespace: 'app:auth', message: 'Token validated' });
|
|
183
|
+
```
|
|
184
|
+
|
|
115
185
|
## Entities
|
|
116
186
|
|
|
117
187
|
### Server
|
|
@@ -1,27 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
3
|
Object.defineProperty(exports, "__esModule", {
|
|
5
4
|
value: true
|
|
6
5
|
});
|
|
7
6
|
exports.shutdownSignals = exports.secondaryMiddleware = exports.defaultMiddleware = exports.defaultErrorMiddleware = void 0;
|
|
8
7
|
var _express = require("express");
|
|
9
|
-
var _morgan = _interopRequireDefault(require("morgan"));
|
|
10
8
|
var _middleware = require("../../middleware");
|
|
11
|
-
const ACCESS_LOG = JSON.stringify({
|
|
12
|
-
method: ':method',
|
|
13
|
-
status: ':status',
|
|
14
|
-
url: ':url',
|
|
15
|
-
'http-version': ':http-version',
|
|
16
|
-
ip: ':remote-addr',
|
|
17
|
-
'user-agent': ':user-agent',
|
|
18
|
-
'content-length': ':res[content-length]',
|
|
19
|
-
referrer: ':referrer',
|
|
20
|
-
'response-time': ':response-time',
|
|
21
|
-
severity: 'DEBUG',
|
|
22
|
-
message: ':method :url [:status]'
|
|
23
|
-
});
|
|
24
|
-
|
|
25
9
|
// Default middleware that are applied first thing on the primary port, before the business logic endpoints
|
|
26
10
|
const defaultMiddleware = exports.defaultMiddleware = [(0, _middleware.healthCheck)(), (0, _express.json)({
|
|
27
11
|
limit: process.env.REQUEST_SIZE_LIMIT ?? '1mb'
|
|
@@ -36,10 +20,10 @@ const defaultErrorMiddleware = exports.defaultErrorMiddleware = [_middleware.err
|
|
|
36
20
|
// Middleware that are served on the secondary port
|
|
37
21
|
const secondaryMiddleware = exports.secondaryMiddleware = [(0, _middleware.metrics)(), (0, _middleware.version)(), (0, _middleware.swaggerDocs)()];
|
|
38
22
|
|
|
39
|
-
// Add
|
|
23
|
+
// Add request logging to middleware chain when reporting is not silenced
|
|
40
24
|
if (!process.env.SILENCE_REPORT) {
|
|
41
|
-
defaultMiddleware.unshift((0,
|
|
42
|
-
secondaryMiddleware.unshift((0,
|
|
25
|
+
defaultMiddleware.unshift((0, _middleware.requestLogger)());
|
|
26
|
+
secondaryMiddleware.unshift((0, _middleware.requestLogger)());
|
|
43
27
|
}
|
|
44
28
|
const shutdownSignals = exports.shutdownSignals = ['SIGTERM', 'SIGUSR2', 'SIGINT'];
|
|
45
29
|
//# sourceMappingURL=Server.const.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Server.const.js","names":["_express","require","
|
|
1
|
+
{"version":3,"file":"Server.const.js","names":["_express","require","_middleware","defaultMiddleware","exports","healthCheck","json","limit","process","env","REQUEST_SIZE_LIMIT","urlencoded","extended","metrics","version","filter","val","defaultErrorMiddleware","error","fourOhFour","secondaryMiddleware","swaggerDocs","SILENCE_REPORT","unshift","requestLogger","shutdownSignals"],"sources":["../../../src/entities/Server/Server.const.ts"],"sourcesContent":["import { json, urlencoded, ErrorRequestHandler, RequestHandler } from 'express';\nimport {\n metrics,\n error,\n fourOhFour,\n healthCheck,\n version,\n swaggerDocs,\n requestLogger\n} from 'middleware';\n\n// Default middleware that are applied first thing on the primary port, before the business logic endpoints\nexport const defaultMiddleware: Array<RequestHandler> = [\n healthCheck(),\n json({ limit: process.env.REQUEST_SIZE_LIMIT ?? '1mb' }),\n urlencoded({\n extended: true,\n limit: process.env.REQUEST_SIZE_LIMIT ?? '1mb'\n }),\n metrics(),\n version()\n].filter((val) => val);\n\n// Error handling middleware that are run after the main business logic endpoints\nexport const defaultErrorMiddleware: Array<\n RequestHandler | ErrorRequestHandler\n> = [error, fourOhFour];\n\n// Middleware that are served on the secondary port\nexport const secondaryMiddleware: Array<RequestHandler> = [\n metrics(),\n version(),\n swaggerDocs()\n];\n\n// Add request logging to middleware chain when reporting is not silenced\nif (!process.env.SILENCE_REPORT) {\n defaultMiddleware.unshift(requestLogger());\n secondaryMiddleware.unshift(requestLogger());\n}\n\nexport const shutdownSignals = ['SIGTERM', 'SIGUSR2', 'SIGINT'];\n"],"mappings":";;;;;;AAAA,IAAAA,QAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AAUA;AACO,MAAME,iBAAwC,GAAAC,OAAA,CAAAD,iBAAA,GAAG,CACtD,IAAAE,uBAAW,EAAC,CAAC,EACb,IAAAC,aAAI,EAAC;EAAEC,KAAK,EAAEC,OAAO,CAACC,GAAG,CAACC,kBAAkB,IAAI;AAAM,CAAC,CAAC,EACxD,IAAAC,mBAAU,EAAC;EACTC,QAAQ,EAAE,IAAI;EACdL,KAAK,EAAEC,OAAO,CAACC,GAAG,CAACC,kBAAkB,IAAI;AAC3C,CAAC,CAAC,EACF,IAAAG,mBAAO,EAAC,CAAC,EACT,IAAAC,mBAAO,EAAC,CAAC,CACV,CAACC,MAAM,CAAEC,GAAG,IAAKA,GAAG,CAAC;;AAEtB;AACO,MAAMC,sBAEZ,GAAAb,OAAA,CAAAa,sBAAA,GAAG,CAACC,iBAAK,EAAEC,sBAAU,CAAC;;AAEvB;AACO,MAAMC,mBAA0C,GAAAhB,OAAA,CAAAgB,mBAAA,GAAG,CACxD,IAAAP,mBAAO,EAAC,CAAC,EACT,IAAAC,mBAAO,EAAC,CAAC,EACT,IAAAO,uBAAW,EAAC,CAAC,CACd;;AAED;AACA,IAAI,CAACb,OAAO,CAACC,GAAG,CAACa,cAAc,EAAE;EAC/BnB,iBAAiB,CAACoB,OAAO,CAAC,IAAAC,yBAAa,EAAC,CAAC,CAAC;EAC1CJ,mBAAmB,CAACG,OAAO,CAAC,IAAAC,yBAAa,EAAC,CAAC,CAAC;AAC9C;AAEO,MAAMC,eAAe,GAAArB,OAAA,CAAAqB,eAAA,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC","ignoreList":[]}
|
|
@@ -32,8 +32,13 @@ export declare class Server {
|
|
|
32
32
|
private wss?;
|
|
33
33
|
/** Abort controller that handles signals for the server */
|
|
34
34
|
private abortController;
|
|
35
|
+
/** File system watchers for TLS certificate changes */
|
|
36
|
+
private fileWatchers;
|
|
35
37
|
/** Create a server */
|
|
36
38
|
constructor(config: ServerOptions);
|
|
39
|
+
/**
|
|
40
|
+
* Setup global error handlers for uncaught exceptions and unhandled rejections
|
|
41
|
+
*/
|
|
37
42
|
private setupGlobalErrorLogging;
|
|
38
43
|
/** Start the server */
|
|
39
44
|
init(): Promise<void>;
|
|
@@ -62,6 +62,8 @@ let Server = exports.Server = /*#__PURE__*/function () {
|
|
|
62
62
|
(0, _defineProperty2.default)(this, "wss", void 0);
|
|
63
63
|
/** Abort controller that handles signals for the server */
|
|
64
64
|
(0, _defineProperty2.default)(this, "abortController", new AbortController());
|
|
65
|
+
/** File system watchers for TLS certificate changes */
|
|
66
|
+
(0, _defineProperty2.default)(this, "fileWatchers", []);
|
|
65
67
|
this.validate(config);
|
|
66
68
|
(0, _report.reportDebug)({
|
|
67
69
|
namespace,
|
|
@@ -126,31 +128,41 @@ let Server = exports.Server = /*#__PURE__*/function () {
|
|
|
126
128
|
this.attachWebSocket(config.webSocket);
|
|
127
129
|
}
|
|
128
130
|
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Setup global error handlers for uncaught exceptions and unhandled rejections
|
|
134
|
+
*/
|
|
129
135
|
return (0, _createClass2.default)(Server, [{
|
|
130
136
|
key: "setupGlobalErrorLogging",
|
|
131
137
|
value: function setupGlobalErrorLogging() {
|
|
132
138
|
process.on('uncaughtException', err => {
|
|
133
|
-
|
|
139
|
+
(0, _report.reportError)(err);
|
|
140
|
+
console.error('💥 uncaughtException:', err?.stack || err);
|
|
141
|
+
// Give time for logs to flush before exiting
|
|
142
|
+
setTimeout(() => process.exit(1), 1000);
|
|
134
143
|
});
|
|
135
144
|
process.on('unhandledRejection', reason => {
|
|
145
|
+
(0, _report.reportError)(reason instanceof Error ? reason : new Error(String(reason)));
|
|
136
146
|
if (reason instanceof Error) {
|
|
137
147
|
console.error('💥 unhandledRejection:', reason.stack || reason.message);
|
|
138
148
|
} else {
|
|
139
149
|
console.error('💥 unhandledRejection:', reason);
|
|
140
150
|
}
|
|
151
|
+
// Give time for logs to flush before exiting
|
|
152
|
+
setTimeout(() => process.exit(1), 1000);
|
|
141
153
|
});
|
|
142
|
-
process.on('beforeExit', code => console.error('process.beforeExit', code));
|
|
143
154
|
}
|
|
144
155
|
|
|
145
156
|
/** Start the server */
|
|
146
157
|
}, {
|
|
147
158
|
key: "init",
|
|
148
159
|
value: async function init() {
|
|
149
|
-
|
|
160
|
+
this.setupGlobalErrorLogging();
|
|
150
161
|
(0, _report.reportDebug)({
|
|
151
162
|
namespace,
|
|
152
163
|
message: `Starting Server`
|
|
153
164
|
});
|
|
165
|
+
|
|
154
166
|
// Fetch the keys for JWT authentication
|
|
155
167
|
// Ignore in test environment as we do symmetrical token signing
|
|
156
168
|
if (process.env.NODE_ENV !== 'test' && !this.auth.noFetch) await (0, _jwt.initKeySets)();
|
|
@@ -205,25 +217,28 @@ let Server = exports.Server = /*#__PURE__*/function () {
|
|
|
205
217
|
});
|
|
206
218
|
|
|
207
219
|
// Stop listening to HTTP requests
|
|
208
|
-
await Promise.all([this.httpServer, this.secondaryHttpServer].map(server => {
|
|
220
|
+
await Promise.all([this.httpServer, this.secondaryHttpServer].map(server => new Promise((resolve, reject) => {
|
|
209
221
|
// Ignore if the server was already stopped
|
|
210
222
|
// We have observed cases where SIGTERM was thrown multiple times
|
|
211
|
-
if (!server.listening)
|
|
223
|
+
if (!server.listening) {
|
|
224
|
+
resolve();
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
212
227
|
const {
|
|
213
228
|
port
|
|
214
229
|
} = server.address();
|
|
215
|
-
server.
|
|
230
|
+
server.close(error => {
|
|
216
231
|
if (error) {
|
|
217
232
|
(0, _report.reportError)(error);
|
|
218
|
-
|
|
233
|
+
reject(error);
|
|
219
234
|
} else {
|
|
220
235
|
(0, _report.reportInfo)({
|
|
221
236
|
message: `Stopped listening to requests on port ${port}`
|
|
222
237
|
});
|
|
238
|
+
resolve();
|
|
223
239
|
}
|
|
224
240
|
});
|
|
225
|
-
|
|
226
|
-
}));
|
|
241
|
+
})));
|
|
227
242
|
|
|
228
243
|
// Close all socket connections
|
|
229
244
|
if (this.wss) {
|
|
@@ -240,6 +255,21 @@ let Server = exports.Server = /*#__PURE__*/function () {
|
|
|
240
255
|
socket.terminate();
|
|
241
256
|
}
|
|
242
257
|
});
|
|
258
|
+
|
|
259
|
+
// Close the WebSocket server itself
|
|
260
|
+
await new Promise((resolve, reject) => {
|
|
261
|
+
this.wss?.close(error => {
|
|
262
|
+
if (error) {
|
|
263
|
+
(0, _report.reportError)(error);
|
|
264
|
+
reject(error);
|
|
265
|
+
} else {
|
|
266
|
+
(0, _report.reportInfo)({
|
|
267
|
+
message: 'WebSocket server closed'
|
|
268
|
+
});
|
|
269
|
+
resolve();
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
});
|
|
243
273
|
}
|
|
244
274
|
|
|
245
275
|
// Run all the shutdown callback
|
|
@@ -257,6 +287,9 @@ let Server = exports.Server = /*#__PURE__*/function () {
|
|
|
257
287
|
// Abort all the cronjob
|
|
258
288
|
if (this.abortController) this.abortController.abort();
|
|
259
289
|
|
|
290
|
+
// Close all file watchers
|
|
291
|
+
this.fileWatchers.forEach(watcher => watcher.close());
|
|
292
|
+
|
|
260
293
|
// Stop the keyset timers
|
|
261
294
|
(0, _jwt.shutdownKeySets)();
|
|
262
295
|
_Server2.shutdownSignals.forEach(signal => process.removeAllListeners(signal));
|
|
@@ -320,12 +353,21 @@ let Server = exports.Server = /*#__PURE__*/function () {
|
|
|
320
353
|
}, {
|
|
321
354
|
key: "handleSignal",
|
|
322
355
|
value: function handleSignal() {
|
|
356
|
+
let isShuttingDown = false;
|
|
323
357
|
_Server2.shutdownSignals.forEach(signal => process.on(signal, () => {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
358
|
+
// Prevent multiple shutdown attempts
|
|
359
|
+
if (isShuttingDown) {
|
|
360
|
+
(0, _report.reportInfo)(`Already shutting down, ignoring ${signal}`);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
isShuttingDown = true;
|
|
364
|
+
(0, _report.reportInfo)(`Received shutdown signal [${signal}]`);
|
|
365
|
+
this.shutdown().then(() => {
|
|
366
|
+
(0, _report.reportInfo)('Graceful shutdown completed successfully');
|
|
367
|
+
process.exit(0);
|
|
368
|
+
}).catch(error => {
|
|
328
369
|
(0, _report.reportError)(error);
|
|
370
|
+
process.exit(1);
|
|
329
371
|
});
|
|
330
372
|
}));
|
|
331
373
|
}
|
|
@@ -336,12 +378,15 @@ let Server = exports.Server = /*#__PURE__*/function () {
|
|
|
336
378
|
value: function watchTlsCaFileChange() {
|
|
337
379
|
['TLS_REQUEST_KEY', 'TLS_REQUEST_CERT', 'TLS_REQUEST_CA', 'TLS_SERVER_KEY', 'TLS_SERVER_CERT', 'TLS_CA'].forEach(key => {
|
|
338
380
|
const file = process.env[key];
|
|
339
|
-
if (file)
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
381
|
+
if (file) {
|
|
382
|
+
const watcher = _fs.default.watch(_path.default.resolve(file), event => {
|
|
383
|
+
if (event !== 'change') return;
|
|
384
|
+
(0, _report.reportInfo)(`Reloading TLS config [${file} changed]`);
|
|
385
|
+
(0, _tlsConfig.loadTlsConfig)();
|
|
386
|
+
this.httpServer.setSecureContext(_tlsConfig.tlsConfig);
|
|
387
|
+
});
|
|
388
|
+
this.fileWatchers.push(watcher);
|
|
389
|
+
}
|
|
345
390
|
});
|
|
346
391
|
}
|
|
347
392
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Server.js","names":["_fs","_interopRequireDefault","require","_path","_promises","_express","_cors","_ws","_SocketClient","_Server2","_Endpoint","_EngineError","_LifecycleController","_PubSub","_utils","_jwt","_report","_tlsConfig","namespace","Server","exports","config","_classCallCheck2","default","_defineProperty2","AbortController","validate","reportDebug","message","endpoints","globalMiddleware","errorMiddleware","initCallbacks","shutdownCallbacks","syncCallbacks","cron","auth","noFetch","checkEnvironment","process","env","RUN_MIGRATION","UNDO_MIGRATION","SQL_HOST","envAssert","isHost","SQL_USER","isString","SQL_PASSWORD","SQL_DB","NODE_ENV","PORT","isPort","SECONDARY_PORT","app","express","use","cors","origin","CORS_ORIGIN","methods","allowedHeaders","registerMiddleware","httpServer","createHttpServer","secondaryApp","secondaryMiddleware","defaultErrorMiddleware","forEach","middleware","secondaryHttpServer","disable","server","headersTimeout","keepAliveTimeout","webSocket","attachWebSocket","_createClass2","key","value","setupGlobalErrorLogging","on","err","console","error","stack","reason","Error","code","init","initKeySets","callback","runCallback","Promise","all","map","PubSub","job","runCronJob","resolve","listen","reportInfo","data","port","secondaryPort","nodeEnv","handleSignal","watchTlsCaFileChange","shutdown","listening","address","reportError","exit","close","wss","clients","socket","socketKillTimeout","WEBSOCKET_CLOSE_TIMEOUT","parseInt","setTimeoutPromise","readyState","CLOSING","OPEN","terminate","LifecycleController","shutdownRunningInstances","abortController","abort","shutdownKeySets","shutdownSignals","signal","removeAllListeners","getApp","getSecondaryApp","defaultMiddleware","path","endpoint","register","options","WebSocketServer","request","SocketClient","client","catch","file","fs","watch","event","loadTlsConfig","setSecureContext","tlsConfig","handler","name","interval","undefined","function","apply","parameters","some","Endpoint","EngineError","Object","values","validator","Array"],"sources":["../../../src/entities/Server/Server.ts"],"sourcesContent":["import fs from 'fs';\nimport http from 'http';\nimport https from 'https';\nimport { AddressInfo } from 'net';\nimport path from 'path';\nimport { setTimeout as setTimeoutPromise } from 'timers/promises';\nimport { ValidatorSpec } from 'envalid';\nimport express, { Application } from 'express';\nimport cors from 'cors';\nimport { Server as WebSocketServer } from 'ws';\nimport { SocketClient } from '../SocketClient';\nimport {\n defaultMiddleware,\n defaultErrorMiddleware,\n secondaryMiddleware,\n shutdownSignals\n} from './Server.const';\nimport {\n ServerOptions,\n ServerCronJon,\n ServerAuthConfig,\n ServerWebSocketConfig,\n ServerGlobalMiddleware,\n ServerErrorMiddleWare,\n ServerCallback\n} from './Server.types';\nimport { Endpoint } from 'entities/Endpoint';\nimport { EngineError } from 'entities/EngineError';\nimport { LifecycleController } from 'entities/LifecycleController';\nimport { PubSub } from 'entities/PubSub';\nimport { checkEnvironment, envAssert, createHttpServer } from 'utils';\nimport { initKeySets, shutdownKeySets } from 'utils/jwt';\nimport { reportInfo, reportError, reportDebug } from 'utils/report';\nimport { tlsConfig, loadTlsConfig, TlsConfig } from 'utils/tlsConfig';\n\nconst namespace = 'engine:Server';\n\n/** Main server class */\nexport class Server {\n /** The express application powering the main endpoints */\n private app: Application;\n /** The node HTTP(S) server, serving the main express application */\n private httpServer: http.Server | https.Server;\n /** The express application powering the support endpoints */\n private secondaryApp: Application;\n /** The node HTTP(S) server, serving the secondary express application */\n private secondaryHttpServer: http.Server | https.Server;\n /** List of endpoint instances that the server should handle */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private endpoints: Array<Endpoint<any>>;\n /** Mapping of env variable name with functions that should run to check their validity */\n private checkEnvironment: Record<string, ValidatorSpec<unknown>>;\n /** Middleware that should run on every request before the endpoint specific logic */\n private globalMiddleware: Array<ServerGlobalMiddleware>;\n /** Error middleware that should run on every request after the endpoint specific logic, but before the generic global middleware */\n private errorMiddleware: Array<\n ServerGlobalMiddleware | ServerErrorMiddleWare\n >;\n /** Functions that should be called on server startup */\n private initCallbacks: Array<ServerCallback>;\n /** Functions that should be called on server shutdown */\n private shutdownCallbacks: Array<ServerCallback>;\n /** 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 */\n private syncCallbacks: boolean;\n /** Config to set regularly running jobs on the server */\n private cron?: Array<ServerCronJon>;\n /** Global auth related configuration */\n private auth: ServerAuthConfig;\n /** WebSocket server instance, if configured */\n private wss?: WebSocketServer;\n /** Abort controller that handles signals for the server */\n private abortController = new AbortController();\n\n /** Create a server */\n public constructor(config: ServerOptions) {\n this.validate(config);\n\n reportDebug({\n namespace,\n message: `Creating server`\n });\n\n this.endpoints = config.endpoints;\n this.globalMiddleware = config.globalMiddleware ?? [];\n this.errorMiddleware = config.errorMiddleware ?? [];\n this.initCallbacks = config.initCallbacks ?? [];\n this.shutdownCallbacks = config.shutdownCallbacks ?? [];\n this.syncCallbacks = config.syncCallbacks ?? false;\n this.cron = config.cron;\n this.auth = { noFetch: false, ...config.auth };\n\n // The minimal environment check is different between the migration modes of execution and the regular server execution mode\n // When running in migration mode, we only check that we have SQL related environment variables\n this.checkEnvironment =\n process.env.RUN_MIGRATION === 'true' ||\n process.env.UNDO_MIGRATION === 'true'\n ? {\n SQL_HOST: envAssert.isHost(),\n SQL_USER: envAssert.isString(),\n SQL_PASSWORD: envAssert.isString(),\n SQL_DB: envAssert.isString()\n }\n : {\n NODE_ENV: envAssert.isString(),\n PORT: envAssert.isPort(),\n SECONDARY_PORT: envAssert.isPort(),\n ...config.checkEnvironment\n };\n\n checkEnvironment(this.checkEnvironment);\n\n // Create the primary express core that serves the business logic\n this.app = express();\n this.app.use(\n cors({\n origin: process.env.CORS_ORIGIN ?? '*',\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n allowedHeaders: ['Content-Type', 'Authorization']\n })\n );\n this.registerMiddleware(this.app);\n this.httpServer = createHttpServer(this.app);\n\n // Create a secondary express core that servers metrics and analytics\n // This will be served on a different port, allowing to specify different firewall rules for these routes\n this.secondaryApp = express();\n [...secondaryMiddleware, ...defaultErrorMiddleware].forEach(\n (middleware) => {\n if (middleware) this.secondaryApp.use(middleware);\n }\n );\n this.secondaryHttpServer = createHttpServer(this.secondaryApp);\n\n // Remove the express headers\n this.app.disable('x-powered-by');\n this.secondaryApp.disable('x-powered-by');\n\n // We remove all node timeout on connections and requests\n // This responsibility is delegated to the front-facing load balancer\n [this.httpServer, this.secondaryHttpServer].forEach((server) => {\n server.headersTimeout = 0;\n server.keepAliveTimeout = 0;\n });\n\n if (config.webSocket) {\n this.attachWebSocket(config.webSocket);\n }\n }\n\n private setupGlobalErrorLogging(): void {\n process.on('uncaughtException', (err) => {\n console.error(\n '💥 uncaughtException:',\n err && err.stack ? err.stack : err\n );\n });\n process.on('unhandledRejection', (reason: unknown) => {\n if (reason instanceof Error) {\n console.error('💥 unhandledRejection:', reason.stack || reason.message);\n } else {\n console.error('💥 unhandledRejection:', reason);\n }\n });\n process.on('beforeExit', (code) =>\n console.error('process.beforeExit', code)\n );\n }\n\n /** Start the server */\n public async init(): Promise<void> {\n // this.setupGlobalErrorLogging();\n reportDebug({ namespace, message: `Starting Server` });\n // Fetch the keys for JWT authentication\n // Ignore in test environment as we do symmetrical token signing\n if (process.env.NODE_ENV !== 'test' && !this.auth.noFetch)\n await initKeySets();\n // Run all the init callbacks\n // We can either run them all 1/1 synchronously or run them all in parallel (default)\n // Callback can either be direct function or an object with function and parameters attributes\n\n if (this.syncCallbacks) {\n for (const callback of this.initCallbacks) {\n await this.runCallback(callback);\n }\n } else {\n await Promise.all(\n this.initCallbacks.map((callback) => this.runCallback(callback))\n );\n }\n\n // Initialize the Pub/Sub module\n await PubSub.init();\n // Run all the cronjob\n if (this.cron) {\n this.cron.forEach((job) => {\n this.runCronJob(job);\n });\n }\n\n // Start listening to requests\n await Promise.all([\n new Promise<void>((resolve) =>\n this.httpServer.listen(process.env.PORT, () => {\n resolve();\n })\n ),\n new Promise<void>((resolve) =>\n this.secondaryHttpServer.listen(process.env.SECONDARY_PORT, () => {\n resolve();\n })\n )\n ]);\n reportInfo({\n message: 'SERVER_RUNNING',\n data: {\n port: process.env.PORT,\n secondaryPort: process.env.SECONDARY_PORT,\n nodeEnv: process.env.NODE_ENV\n }\n });\n\n this.handleSignal();\n\n // Watch TSL config files changing\n this.watchTlsCaFileChange();\n }\n\n /** Graceful shutdown */\n public async shutdown(): Promise<void> {\n reportDebug({ namespace, message: `Shutting down Server` });\n\n // Stop listening to HTTP requests\n await Promise.all(\n [this.httpServer, this.secondaryHttpServer].map((server) => {\n // Ignore if the server was already stopped\n // We have observed cases where SIGTERM was thrown multiple times\n if (!server.listening) return;\n const { port } = server.address() as AddressInfo;\n server.on('close', (error: unknown) => {\n if (error) {\n reportError(error);\n process.exit(1);\n } else {\n reportInfo({\n message: `Stopped listening to requests on port ${port}`\n });\n }\n });\n server.close();\n })\n );\n\n // Close all socket connections\n if (this.wss) {\n // First ask them to close gracefully\n this.wss.clients.forEach((socket) => {\n socket.close();\n });\n \n // Hard terminate all connections still open after a defined time\n const socketKillTimeout = process.env.WEBSOCKET_CLOSE_TIMEOUT\n ? parseInt(process.env.WEBSOCKET_CLOSE_TIMEOUT, 10)\n : 5000;\n \n await setTimeoutPromise(socketKillTimeout);\n \n this.wss.clients.forEach((socket) => {\n if (\n socket.readyState === socket.CLOSING ||\n socket.readyState === socket.OPEN\n ) {\n socket.terminate();\n }\n });\n }\n\n // Run all the shutdown callback\n if (this.syncCallbacks) {\n for (const callback of this.shutdownCallbacks) {\n await this.runCallback(callback);\n }\n } else {\n await Promise.all(\n this.shutdownCallbacks.map((callback) => this.runCallback(callback))\n );\n }\n\n // Shutdown all the running entities\n await LifecycleController.shutdownRunningInstances();\n\n // Abort all the cronjob\n if (this.abortController) this.abortController.abort();\n\n // Stop the keyset timers\n shutdownKeySets();\n\n shutdownSignals.forEach((signal) => process.removeAllListeners(signal));\n }\n\n /** Get the express app instance of the server */\n public getApp(): Application {\n return this.app;\n }\n\n /** Get the express app instance of the server */\n public getSecondaryApp(): Application {\n return this.secondaryApp;\n }\n\n /** Registers all the middleware with the express app */\n private registerMiddleware(app: Application): void {\n // Global middleware can specify a path to which they apply\n [...defaultMiddleware, ...this.globalMiddleware].forEach((middleware) => {\n if (typeof middleware === 'function') {\n app.use(middleware);\n } else {\n app.use(middleware.path, middleware.middleware);\n }\n });\n // Call the register method of each endpoint\n this.endpoints.forEach((endpoint) => {\n endpoint.register(app);\n });\n // Add error middleware\n [...this.errorMiddleware, ...defaultErrorMiddleware].forEach(\n (middleware) => {\n if (typeof middleware === 'function') {\n app.use(middleware);\n } else {\n app.use(middleware.path, middleware.middleware);\n }\n }\n );\n }\n\n /** Add a handler for WebSocket connections */\n private attachWebSocket(options: ServerWebSocketConfig): void {\n this.wss = new WebSocketServer({\n ...options.server,\n server: this.httpServer\n })\n .on('connection', (webSocket, request) => {\n new SocketClient(webSocket, request, options.client);\n })\n .on('error', (error) => {\n reportError(error);\n });\n }\n\n /** Call shutdown if signal gets sent to the process */\n private handleSignal(): void {\n shutdownSignals.forEach((signal) =>\n process.on(signal, () => {\n (async (): Promise<void> => {\n reportInfo(`Received shutdown signal [${signal}]`);\n await this.shutdown();\n })().catch((error) => {\n reportError(error);\n });\n })\n );\n }\n\n /** Watch the TLS certificate change event */\n private watchTlsCaFileChange(): void {\n [\n 'TLS_REQUEST_KEY',\n 'TLS_REQUEST_CERT',\n 'TLS_REQUEST_CA',\n 'TLS_SERVER_KEY',\n 'TLS_SERVER_CERT',\n 'TLS_CA'\n ].forEach((key) => {\n const file = process.env[key];\n if (file)\n fs.watch(path.resolve(file), (event) => {\n if (event !== 'change') return;\n reportInfo(`Reloading TLS config [${file} changed]`);\n loadTlsConfig();\n (this.httpServer as https.Server).setSecureContext(\n tlsConfig as TlsConfig\n );\n });\n });\n }\n\n /** Executes a recurring job */\n private runCronJob(job: ServerCronJon): void {\n (async (): Promise<void> => {\n reportInfo({ message: `Starting scheduled job \"${job.handler.name}\"` });\n try {\n await job.handler();\n reportInfo({\n message: `Job \"${job.handler.name}\" finished, starting again in ${job.interval} seconds`\n });\n await setTimeoutPromise(job.interval * 1000, undefined, {\n signal: this.abortController.signal\n });\n this.runCronJob(job);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n reportDebug({\n namespace,\n message: `Scheduled job \"${job.handler?.name}\" has been aborted`\n });\n } else {\n throw error;\n }\n }\n })().catch((error) => {\n reportError(error);\n });\n }\n\n /** Run a shutdown/init callback */\n private runCallback(callback: ServerCallback): unknown {\n return typeof callback === 'function'\n ? callback()\n : callback.function.apply(null, callback.parameters ?? []);\n }\n\n /**\n * Validate the Server constructor configuration\n */\n private validate(config: ServerOptions): void {\n if (\n !config.endpoints ||\n config.endpoints.some((endpoint) => !(endpoint instanceof Endpoint))\n )\n throw new EngineError(\n 'Server endpoints should be declared and all be Endpoint instances'\n );\n\n if (\n config.checkEnvironment &&\n Object.values(config.checkEnvironment).some(\n (validator) => typeof validator !== 'function'\n )\n )\n throw new EngineError(\n 'Some of the environment checks are not valid functions'\n );\n\n if (\n config.initCallbacks &&\n (!(config.initCallbacks instanceof Array) ||\n config.initCallbacks.some(\n (callback) =>\n !(\n typeof callback === 'function' ||\n typeof callback?.function === 'function'\n )\n ))\n )\n throw new EngineError('Init callbacks is not a list of functions');\n\n if (\n config.shutdownCallbacks &&\n (!(config.shutdownCallbacks instanceof Array) ||\n config.shutdownCallbacks.some(\n (callback) =>\n !(\n typeof callback === 'function' ||\n typeof callback?.function === 'function'\n )\n ))\n )\n throw new EngineError('Shutdown callbacks is not a list of functions');\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"Server.js","names":["_fs","_interopRequireDefault","require","_path","_promises","_express","_cors","_ws","_SocketClient","_Server2","_Endpoint","_EngineError","_LifecycleController","_PubSub","_utils","_jwt","_report","_tlsConfig","namespace","Server","exports","config","_classCallCheck2","default","_defineProperty2","AbortController","validate","reportDebug","message","endpoints","globalMiddleware","errorMiddleware","initCallbacks","shutdownCallbacks","syncCallbacks","cron","auth","noFetch","checkEnvironment","process","env","RUN_MIGRATION","UNDO_MIGRATION","SQL_HOST","envAssert","isHost","SQL_USER","isString","SQL_PASSWORD","SQL_DB","NODE_ENV","PORT","isPort","SECONDARY_PORT","app","express","use","cors","origin","CORS_ORIGIN","methods","allowedHeaders","registerMiddleware","httpServer","createHttpServer","secondaryApp","secondaryMiddleware","defaultErrorMiddleware","forEach","middleware","secondaryHttpServer","disable","server","headersTimeout","keepAliveTimeout","webSocket","attachWebSocket","_createClass2","key","value","setupGlobalErrorLogging","on","err","reportError","console","error","stack","setTimeout","exit","reason","Error","String","init","initKeySets","callback","runCallback","Promise","all","map","PubSub","job","runCronJob","resolve","listen","reportInfo","data","port","secondaryPort","nodeEnv","handleSignal","watchTlsCaFileChange","shutdown","reject","listening","address","close","wss","clients","socket","socketKillTimeout","WEBSOCKET_CLOSE_TIMEOUT","parseInt","setTimeoutPromise","readyState","CLOSING","OPEN","terminate","LifecycleController","shutdownRunningInstances","abortController","abort","fileWatchers","watcher","shutdownKeySets","shutdownSignals","signal","removeAllListeners","getApp","getSecondaryApp","defaultMiddleware","path","endpoint","register","options","WebSocketServer","request","SocketClient","client","isShuttingDown","then","catch","file","fs","watch","event","loadTlsConfig","setSecureContext","tlsConfig","push","handler","name","interval","undefined","function","apply","parameters","some","Endpoint","EngineError","Object","values","validator","Array"],"sources":["../../../src/entities/Server/Server.ts"],"sourcesContent":["import fs from 'fs';\nimport http from 'http';\nimport https from 'https';\nimport { AddressInfo } from 'net';\nimport path from 'path';\nimport { setTimeout as setTimeoutPromise } from 'timers/promises';\nimport { ValidatorSpec } from 'envalid';\nimport express, { Application } from 'express';\nimport cors from 'cors';\nimport { Server as WebSocketServer } from 'ws';\nimport { SocketClient } from '../SocketClient';\nimport {\n defaultMiddleware,\n defaultErrorMiddleware,\n secondaryMiddleware,\n shutdownSignals\n} from './Server.const';\nimport {\n ServerOptions,\n ServerCronJon,\n ServerAuthConfig,\n ServerWebSocketConfig,\n ServerGlobalMiddleware,\n ServerErrorMiddleWare,\n ServerCallback\n} from './Server.types';\nimport { Endpoint } from 'entities/Endpoint';\nimport { EngineError } from 'entities/EngineError';\nimport { LifecycleController } from 'entities/LifecycleController';\nimport { PubSub } from 'entities/PubSub';\nimport { checkEnvironment, envAssert, createHttpServer } from 'utils';\nimport { initKeySets, shutdownKeySets } from 'utils/jwt';\nimport { reportInfo, reportError, reportDebug } from 'utils/report';\nimport { tlsConfig, loadTlsConfig, TlsConfig } from 'utils/tlsConfig';\n\nconst namespace = 'engine:Server';\n\n/** Main server class */\nexport class Server {\n /** The express application powering the main endpoints */\n private app: Application;\n /** The node HTTP(S) server, serving the main express application */\n private httpServer: http.Server | https.Server;\n /** The express application powering the support endpoints */\n private secondaryApp: Application;\n /** The node HTTP(S) server, serving the secondary express application */\n private secondaryHttpServer: http.Server | https.Server;\n /** List of endpoint instances that the server should handle */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private endpoints: Array<Endpoint<any>>;\n /** Mapping of env variable name with functions that should run to check their validity */\n private checkEnvironment: Record<string, ValidatorSpec<unknown>>;\n /** Middleware that should run on every request before the endpoint specific logic */\n private globalMiddleware: Array<ServerGlobalMiddleware>;\n /** Error middleware that should run on every request after the endpoint specific logic, but before the generic global middleware */\n private errorMiddleware: Array<\n ServerGlobalMiddleware | ServerErrorMiddleWare\n >;\n /** Functions that should be called on server startup */\n private initCallbacks: Array<ServerCallback>;\n /** Functions that should be called on server shutdown */\n private shutdownCallbacks: Array<ServerCallback>;\n /** 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 */\n private syncCallbacks: boolean;\n /** Config to set regularly running jobs on the server */\n private cron?: Array<ServerCronJon>;\n /** Global auth related configuration */\n private auth: ServerAuthConfig;\n /** WebSocket server instance, if configured */\n private wss?: WebSocketServer;\n /** Abort controller that handles signals for the server */\n private abortController = new AbortController();\n /** File system watchers for TLS certificate changes */\n private fileWatchers: Array<fs.FSWatcher> = [];\n\n /** Create a server */\n public constructor(config: ServerOptions) {\n this.validate(config);\n\n reportDebug({\n namespace,\n message: `Creating server`\n });\n\n this.endpoints = config.endpoints;\n this.globalMiddleware = config.globalMiddleware ?? [];\n this.errorMiddleware = config.errorMiddleware ?? [];\n this.initCallbacks = config.initCallbacks ?? [];\n this.shutdownCallbacks = config.shutdownCallbacks ?? [];\n this.syncCallbacks = config.syncCallbacks ?? false;\n this.cron = config.cron;\n this.auth = { noFetch: false, ...config.auth };\n\n // The minimal environment check is different between the migration modes of execution and the regular server execution mode\n // When running in migration mode, we only check that we have SQL related environment variables\n this.checkEnvironment =\n process.env.RUN_MIGRATION === 'true' ||\n process.env.UNDO_MIGRATION === 'true'\n ? {\n SQL_HOST: envAssert.isHost(),\n SQL_USER: envAssert.isString(),\n SQL_PASSWORD: envAssert.isString(),\n SQL_DB: envAssert.isString()\n }\n : {\n NODE_ENV: envAssert.isString(),\n PORT: envAssert.isPort(),\n SECONDARY_PORT: envAssert.isPort(),\n ...config.checkEnvironment\n };\n\n checkEnvironment(this.checkEnvironment);\n\n // Create the primary express core that serves the business logic\n this.app = express();\n this.app.use(\n cors({\n origin: process.env.CORS_ORIGIN ?? '*',\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n allowedHeaders: ['Content-Type', 'Authorization']\n })\n );\n this.registerMiddleware(this.app);\n this.httpServer = createHttpServer(this.app);\n\n // Create a secondary express core that servers metrics and analytics\n // This will be served on a different port, allowing to specify different firewall rules for these routes\n this.secondaryApp = express();\n [...secondaryMiddleware, ...defaultErrorMiddleware].forEach(\n (middleware) => {\n if (middleware) this.secondaryApp.use(middleware);\n }\n );\n this.secondaryHttpServer = createHttpServer(this.secondaryApp);\n\n // Remove the express headers\n this.app.disable('x-powered-by');\n this.secondaryApp.disable('x-powered-by');\n\n // We remove all node timeout on connections and requests\n // This responsibility is delegated to the front-facing load balancer\n [this.httpServer, this.secondaryHttpServer].forEach((server) => {\n server.headersTimeout = 0;\n server.keepAliveTimeout = 0;\n });\n\n if (config.webSocket) {\n this.attachWebSocket(config.webSocket);\n }\n }\n\n /**\n * Setup global error handlers for uncaught exceptions and unhandled rejections\n */\n private setupGlobalErrorLogging(): void {\n process.on('uncaughtException', (err) => {\n reportError(err);\n console.error('💥 uncaughtException:', err?.stack || err);\n // Give time for logs to flush before exiting\n setTimeout(() => process.exit(1), 1000);\n });\n \n process.on('unhandledRejection', (reason: unknown) => {\n reportError(reason instanceof Error ? reason : new Error(String(reason)));\n if (reason instanceof Error) {\n console.error('💥 unhandledRejection:', reason.stack || reason.message);\n } else {\n console.error('💥 unhandledRejection:', reason);\n }\n // Give time for logs to flush before exiting\n setTimeout(() => process.exit(1), 1000);\n });\n }\n\n /** Start the server */\n public async init(): Promise<void> {\n this.setupGlobalErrorLogging();\n reportDebug({ namespace, message: `Starting Server` });\n \n // Fetch the keys for JWT authentication\n // Ignore in test environment as we do symmetrical token signing\n if (process.env.NODE_ENV !== 'test' && !this.auth.noFetch)\n await initKeySets();\n // Run all the init callbacks\n // We can either run them all 1/1 synchronously or run them all in parallel (default)\n // Callback can either be direct function or an object with function and parameters attributes\n\n if (this.syncCallbacks) {\n for (const callback of this.initCallbacks) {\n await this.runCallback(callback);\n }\n } else {\n await Promise.all(\n this.initCallbacks.map((callback) => this.runCallback(callback))\n );\n }\n\n // Initialize the Pub/Sub module\n await PubSub.init();\n // Run all the cronjob\n if (this.cron) {\n this.cron.forEach((job) => {\n this.runCronJob(job);\n });\n }\n\n // Start listening to requests\n await Promise.all([\n new Promise<void>((resolve) =>\n this.httpServer.listen(process.env.PORT, () => {\n resolve();\n })\n ),\n new Promise<void>((resolve) =>\n this.secondaryHttpServer.listen(process.env.SECONDARY_PORT, () => {\n resolve();\n })\n )\n ]);\n reportInfo({\n message: 'SERVER_RUNNING',\n data: {\n port: process.env.PORT,\n secondaryPort: process.env.SECONDARY_PORT,\n nodeEnv: process.env.NODE_ENV\n }\n });\n\n this.handleSignal();\n\n // Watch TSL config files changing\n this.watchTlsCaFileChange();\n }\n\n /** Graceful shutdown */\n public async shutdown(): Promise<void> {\n reportDebug({ namespace, message: `Shutting down Server` });\n\n // Stop listening to HTTP requests\n await Promise.all(\n [this.httpServer, this.secondaryHttpServer].map(\n (server) =>\n new Promise<void>((resolve, reject) => {\n // Ignore if the server was already stopped\n // We have observed cases where SIGTERM was thrown multiple times\n if (!server.listening) {\n resolve();\n return;\n }\n \n const { port } = server.address() as AddressInfo;\n \n server.close((error) => {\n if (error) {\n reportError(error);\n reject(error);\n } else {\n reportInfo({\n message: `Stopped listening to requests on port ${port}`\n });\n resolve();\n }\n });\n })\n )\n );\n\n // Close all socket connections\n if (this.wss) {\n // First ask them to close gracefully\n this.wss.clients.forEach((socket) => {\n socket.close();\n });\n \n // Hard terminate all connections still open after a defined time\n const socketKillTimeout = process.env.WEBSOCKET_CLOSE_TIMEOUT\n ? parseInt(process.env.WEBSOCKET_CLOSE_TIMEOUT, 10)\n : 5000;\n \n await setTimeoutPromise(socketKillTimeout);\n \n this.wss.clients.forEach((socket) => {\n if (\n socket.readyState === socket.CLOSING ||\n socket.readyState === socket.OPEN\n ) {\n socket.terminate();\n }\n });\n \n // Close the WebSocket server itself\n await new Promise<void>((resolve, reject) => {\n this.wss?.close((error) => {\n if (error) {\n reportError(error);\n reject(error);\n } else {\n reportInfo({ message: 'WebSocket server closed' });\n resolve();\n }\n });\n });\n }\n\n // Run all the shutdown callback\n if (this.syncCallbacks) {\n for (const callback of this.shutdownCallbacks) {\n await this.runCallback(callback);\n }\n } else {\n await Promise.all(\n this.shutdownCallbacks.map((callback) => this.runCallback(callback))\n );\n }\n\n // Shutdown all the running entities\n await LifecycleController.shutdownRunningInstances();\n\n // Abort all the cronjob\n if (this.abortController) this.abortController.abort();\n\n // Close all file watchers\n this.fileWatchers.forEach((watcher) => watcher.close());\n\n // Stop the keyset timers\n shutdownKeySets();\n\n shutdownSignals.forEach((signal) => process.removeAllListeners(signal));\n }\n\n /** Get the express app instance of the server */\n public getApp(): Application {\n return this.app;\n }\n\n /** Get the express app instance of the server */\n public getSecondaryApp(): Application {\n return this.secondaryApp;\n }\n\n /** Registers all the middleware with the express app */\n private registerMiddleware(app: Application): void {\n // Global middleware can specify a path to which they apply\n [...defaultMiddleware, ...this.globalMiddleware].forEach((middleware) => {\n if (typeof middleware === 'function') {\n app.use(middleware);\n } else {\n app.use(middleware.path, middleware.middleware);\n }\n });\n // Call the register method of each endpoint\n this.endpoints.forEach((endpoint) => {\n endpoint.register(app);\n });\n // Add error middleware\n [...this.errorMiddleware, ...defaultErrorMiddleware].forEach(\n (middleware) => {\n if (typeof middleware === 'function') {\n app.use(middleware);\n } else {\n app.use(middleware.path, middleware.middleware);\n }\n }\n );\n }\n\n /** Add a handler for WebSocket connections */\n private attachWebSocket(options: ServerWebSocketConfig): void {\n this.wss = new WebSocketServer({\n ...options.server,\n server: this.httpServer\n })\n .on('connection', (webSocket, request) => {\n new SocketClient(webSocket, request, options.client);\n })\n .on('error', (error) => {\n reportError(error);\n });\n }\n\n /** Call shutdown if signal gets sent to the process */\n private handleSignal(): void {\n let isShuttingDown = false;\n \n shutdownSignals.forEach((signal) =>\n process.on(signal, () => {\n // Prevent multiple shutdown attempts\n if (isShuttingDown) {\n reportInfo(`Already shutting down, ignoring ${signal}`);\n return;\n }\n \n isShuttingDown = true;\n reportInfo(`Received shutdown signal [${signal}]`);\n \n this.shutdown()\n .then(() => {\n reportInfo('Graceful shutdown completed successfully');\n process.exit(0);\n })\n .catch((error) => {\n reportError(error);\n process.exit(1);\n });\n })\n );\n }\n\n /** Watch the TLS certificate change event */\n private watchTlsCaFileChange(): void {\n [\n 'TLS_REQUEST_KEY',\n 'TLS_REQUEST_CERT',\n 'TLS_REQUEST_CA',\n 'TLS_SERVER_KEY',\n 'TLS_SERVER_CERT',\n 'TLS_CA'\n ].forEach((key) => {\n const file = process.env[key];\n if (file) {\n const watcher = fs.watch(path.resolve(file), (event) => {\n if (event !== 'change') return;\n reportInfo(`Reloading TLS config [${file} changed]`);\n loadTlsConfig();\n (this.httpServer as https.Server).setSecureContext(\n tlsConfig as TlsConfig\n );\n });\n this.fileWatchers.push(watcher);\n }\n });\n }\n\n /** Executes a recurring job */\n private runCronJob(job: ServerCronJon): void {\n (async (): Promise<void> => {\n reportInfo({ message: `Starting scheduled job \"${job.handler.name}\"` });\n try {\n await job.handler();\n reportInfo({\n message: `Job \"${job.handler.name}\" finished, starting again in ${job.interval} seconds`\n });\n await setTimeoutPromise(job.interval * 1000, undefined, {\n signal: this.abortController.signal\n });\n this.runCronJob(job);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n reportDebug({\n namespace,\n message: `Scheduled job \"${job.handler?.name}\" has been aborted`\n });\n } else {\n throw error;\n }\n }\n })().catch((error) => {\n reportError(error);\n });\n }\n\n /** Run a shutdown/init callback */\n private runCallback(callback: ServerCallback): unknown {\n return typeof callback === 'function'\n ? callback()\n : callback.function.apply(null, callback.parameters ?? []);\n }\n\n /**\n * Validate the Server constructor configuration\n */\n private validate(config: ServerOptions): void {\n if (\n !config.endpoints ||\n config.endpoints.some((endpoint) => !(endpoint instanceof Endpoint))\n )\n throw new EngineError(\n 'Server endpoints should be declared and all be Endpoint instances'\n );\n\n if (\n config.checkEnvironment &&\n Object.values(config.checkEnvironment).some(\n (validator) => typeof validator !== 'function'\n )\n )\n throw new EngineError(\n 'Some of the environment checks are not valid functions'\n );\n\n if (\n config.initCallbacks &&\n (!(config.initCallbacks instanceof Array) ||\n config.initCallbacks.some(\n (callback) =>\n !(\n typeof callback === 'function' ||\n typeof callback?.function === 'function'\n )\n ))\n )\n throw new EngineError('Init callbacks is not a list of functions');\n\n if (\n config.shutdownCallbacks &&\n (!(config.shutdownCallbacks instanceof Array) ||\n config.shutdownCallbacks.some(\n (callback) =>\n !(\n typeof callback === 'function' ||\n typeof callback?.function === 'function'\n )\n ))\n )\n throw new EngineError('Shutdown callbacks is not a list of functions');\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -12,13 +12,6 @@ const namespace = 'engine:middleware:error';
|
|
|
12
12
|
function error(error, request, response,
|
|
13
13
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
14
14
|
next) {
|
|
15
|
-
(0, _report.reportDebug)({
|
|
16
|
-
namespace,
|
|
17
|
-
message: 'Received error',
|
|
18
|
-
data: {
|
|
19
|
-
error
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
15
|
(0, _report.reportError)(error, request);
|
|
23
16
|
if (error instanceof _WebError.WebError) {
|
|
24
17
|
response.status(error.statusCode).json({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","names":["_WebError","require","_report","namespace","error","request","response","next","
|
|
1
|
+
{"version":3,"file":"error.js","names":["_WebError","require","_report","namespace","error","request","response","next","reportError","WebError","status","statusCode","json","errorCode","hint"],"sources":["../../../src/middleware/error/error.ts"],"sourcesContent":["import { Request, Response, NextFunction } from 'express';\nimport { WebError } from 'entities/WebError';\nimport { reportError, reportDebug } from 'utils/report';\n\nconst namespace = 'engine:middleware:error';\n\n/** Handle errors globally */\nexport function error(\n error: Error,\n request: Request,\n response: Response,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n next: NextFunction\n): void {\n reportError(error, request);\n if (error instanceof WebError) {\n response.status(error.statusCode).json({\n errorCode: error.errorCode,\n hint: error.hint\n });\n return;\n }\n response.status(500).json({ errorCode: 'server-error' });\n}\n"],"mappings":";;;;;;AACA,IAAAA,SAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AAEA,MAAME,SAAS,GAAG,yBAAyB;;AAE3C;AACO,SAASC,KAAKA,CACnBA,KAAY,EACZC,OAAgB,EAChBC,QAAkB;AAClB;AACAC,IAAkB,EACZ;EACN,IAAAC,mBAAW,EAACJ,KAAK,EAAEC,OAAO,CAAC;EAC3B,IAAID,KAAK,YAAYK,kBAAQ,EAAE;IAC7BH,QAAQ,CAACI,MAAM,CAACN,KAAK,CAACO,UAAU,CAAC,CAACC,IAAI,CAAC;MACrCC,SAAS,EAAET,KAAK,CAACS,SAAS;MAC1BC,IAAI,EAAEV,KAAK,CAACU;IACd,CAAC,CAAC;IACF;EACF;EACAR,QAAQ,CAACI,MAAM,CAAC,GAAG,CAAC,CAACE,IAAI,CAAC;IAAEC,SAAS,EAAE;EAAe,CAAC,CAAC;AAC1D","ignoreList":[]}
|
|
@@ -11,6 +11,7 @@ export * from './userResolver';
|
|
|
11
11
|
export * from './fileUploader';
|
|
12
12
|
export * from './metrics';
|
|
13
13
|
export * from './requestMetrics';
|
|
14
|
+
export * from './requestLogger';
|
|
14
15
|
export * from './version';
|
|
15
16
|
export * from './geminiFileUploader';
|
|
16
17
|
export * from './checkPermission';
|
package/dist/middleware/index.js
CHANGED
|
@@ -146,6 +146,17 @@ Object.keys(_requestMetrics).forEach(function (key) {
|
|
|
146
146
|
}
|
|
147
147
|
});
|
|
148
148
|
});
|
|
149
|
+
var _requestLogger = require("./requestLogger");
|
|
150
|
+
Object.keys(_requestLogger).forEach(function (key) {
|
|
151
|
+
if (key === "default" || key === "__esModule") return;
|
|
152
|
+
if (key in exports && exports[key] === _requestLogger[key]) return;
|
|
153
|
+
Object.defineProperty(exports, key, {
|
|
154
|
+
enumerable: true,
|
|
155
|
+
get: function () {
|
|
156
|
+
return _requestLogger[key];
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
});
|
|
149
160
|
var _version = require("./version");
|
|
150
161
|
Object.keys(_version).forEach(function (key) {
|
|
151
162
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_error","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_healthCheck","_validate","_fourOhFour","_authJwt","_authHmac","_authStatic","_swaggerDocs","_authTls","_userResolver","_fileUploader","_metrics","_requestMetrics","_version","_geminiFileUploader","_checkPermission","_multiPartFileUploader"],"sources":["../../src/middleware/index.ts"],"sourcesContent":["export * from './error';\nexport * from './healthCheck';\nexport * from './validate';\nexport * from './fourOhFour';\nexport * from './authJwt';\nexport * from './authHmac';\nexport * from './authStatic';\nexport * from './swaggerDocs';\nexport * from './authTls';\nexport * from './userResolver';\nexport * from './fileUploader';\nexport * from './metrics';\nexport * from './requestMetrics';\nexport * from './version';\nexport * from './geminiFileUploader';\nexport * from './checkPermission';\nexport * from './multiPartFileUploader';\n"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","names":["_error","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_healthCheck","_validate","_fourOhFour","_authJwt","_authHmac","_authStatic","_swaggerDocs","_authTls","_userResolver","_fileUploader","_metrics","_requestMetrics","_requestLogger","_version","_geminiFileUploader","_checkPermission","_multiPartFileUploader"],"sources":["../../src/middleware/index.ts"],"sourcesContent":["export * from './error';\nexport * from './healthCheck';\nexport * from './validate';\nexport * from './fourOhFour';\nexport * from './authJwt';\nexport * from './authHmac';\nexport * from './authStatic';\nexport * from './swaggerDocs';\nexport * from './authTls';\nexport * from './userResolver';\nexport * from './fileUploader';\nexport * from './metrics';\nexport * from './requestMetrics';\nexport * from './requestLogger';\nexport * from './version';\nexport * from './geminiFileUploader';\nexport * from './checkPermission';\nexport * from './multiPartFileUploader';\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './requestLogger';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _requestLogger = require("./requestLogger");
|
|
7
|
+
Object.keys(_requestLogger).forEach(function (key) {
|
|
8
|
+
if (key === "default" || key === "__esModule") return;
|
|
9
|
+
if (key in exports && exports[key] === _requestLogger[key]) return;
|
|
10
|
+
Object.defineProperty(exports, key, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function () {
|
|
13
|
+
return _requestLogger[key];
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["_requestLogger","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get"],"sources":["../../../src/middleware/requestLogger/index.ts"],"sourcesContent":["export * from './requestLogger';\n"],"mappings":";;;;;AAAA,IAAAA,cAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,cAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,cAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,cAAA,CAAAK,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.requestLogger = requestLogger;
|
|
7
|
+
var _const = require("../../const");
|
|
8
|
+
var _output = require("../../utils/report/output");
|
|
9
|
+
/**
|
|
10
|
+
* Custom request logger middleware that formats HTTP requests consistently
|
|
11
|
+
* with the rest of the application logging
|
|
12
|
+
*/
|
|
13
|
+
function requestLogger() {
|
|
14
|
+
return (request, response, next) => {
|
|
15
|
+
const startTime = Date.now();
|
|
16
|
+
|
|
17
|
+
// Log response when finished
|
|
18
|
+
response.on('finish', () => {
|
|
19
|
+
const responseTime = Date.now() - startTime;
|
|
20
|
+
const statusCode = response.statusCode;
|
|
21
|
+
const showDetailedLogs = process.env.DETAILED_LOGS === 'true';
|
|
22
|
+
|
|
23
|
+
// Determine severity based on status code
|
|
24
|
+
let severity = _const.LogSeverity.DEBUG;
|
|
25
|
+
if (statusCode >= 500) {
|
|
26
|
+
severity = _const.LogSeverity.ERROR;
|
|
27
|
+
} else if (statusCode >= 400) {
|
|
28
|
+
severity = _const.LogSeverity.WARNING;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Build the log message
|
|
32
|
+
const message = `${request.method} ${request.originalUrl || request.url} [${statusCode}] ${responseTime}ms`;
|
|
33
|
+
|
|
34
|
+
// Build log entry
|
|
35
|
+
const logEntry = {
|
|
36
|
+
severity,
|
|
37
|
+
message
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Add detailed info only if DETAILED_LOGS is enabled
|
|
41
|
+
if (showDetailedLogs) {
|
|
42
|
+
logEntry.context = {
|
|
43
|
+
httpRequest: {
|
|
44
|
+
method: request.method,
|
|
45
|
+
url: request.originalUrl || request.url,
|
|
46
|
+
userAgent: request.header('User-Agent'),
|
|
47
|
+
remoteIp: request.ip,
|
|
48
|
+
referrer: request.header('Referer'),
|
|
49
|
+
responseStatusCode: statusCode
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
logEntry.data = {
|
|
53
|
+
responseTime: `${responseTime}ms`,
|
|
54
|
+
contentLength: response.getHeader('content-length') || '-',
|
|
55
|
+
httpVersion: `${request.httpVersionMajor}.${request.httpVersionMinor}`
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
(0, _output.output)(logEntry);
|
|
59
|
+
});
|
|
60
|
+
next();
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=requestLogger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestLogger.js","names":["_const","require","_output","requestLogger","request","response","next","startTime","Date","now","on","responseTime","statusCode","showDetailedLogs","process","env","DETAILED_LOGS","severity","LogSeverity","DEBUG","ERROR","WARNING","message","method","originalUrl","url","logEntry","context","httpRequest","userAgent","header","remoteIp","ip","referrer","responseStatusCode","data","contentLength","getHeader","httpVersion","httpVersionMajor","httpVersionMinor","output"],"sources":["../../../src/middleware/requestLogger/requestLogger.ts"],"sourcesContent":["import { Request, Response, NextFunction, RequestHandler } from 'express';\nimport { LogSeverity } from 'const';\nimport { output } from 'utils/report/output';\n\n/**\n * Custom request logger middleware that formats HTTP requests consistently\n * with the rest of the application logging\n */\nexport function requestLogger(): RequestHandler {\n return (request: Request, response: Response, next: NextFunction): void => {\n const startTime = Date.now();\n\n // Log response when finished\n response.on('finish', () => {\n const responseTime = Date.now() - startTime;\n const statusCode = response.statusCode;\n const showDetailedLogs = process.env.DETAILED_LOGS === 'true';\n\n // Determine severity based on status code\n let severity = LogSeverity.DEBUG;\n if (statusCode >= 500) {\n severity = LogSeverity.ERROR;\n } else if (statusCode >= 400) {\n severity = LogSeverity.WARNING;\n }\n\n // Build the log message\n const message = `${request.method} ${request.originalUrl || request.url} [${statusCode}] ${responseTime}ms`;\n\n // Build log entry\n const logEntry: Parameters<typeof output>[0] = {\n severity,\n message\n };\n\n // Add detailed info only if DETAILED_LOGS is enabled\n if (showDetailedLogs) {\n logEntry.context = {\n httpRequest: {\n method: request.method,\n url: request.originalUrl || request.url,\n userAgent: request.header('User-Agent'),\n remoteIp: request.ip,\n referrer: request.header('Referer'),\n responseStatusCode: statusCode\n }\n };\n logEntry.data = {\n responseTime: `${responseTime}ms`,\n contentLength: response.getHeader('content-length') || '-',\n httpVersion: `${request.httpVersionMajor}.${request.httpVersionMinor}`\n };\n }\n\n output(logEntry);\n });\n\n next();\n };\n}\n"],"mappings":";;;;;;AACA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AAEA;AACA;AACA;AACA;AACO,SAASE,aAAaA,CAAA,EAAmB;EAC9C,OAAO,CAACC,OAAgB,EAAEC,QAAkB,EAAEC,IAAkB,KAAW;IACzE,MAAMC,SAAS,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC;;IAE5B;IACAJ,QAAQ,CAACK,EAAE,CAAC,QAAQ,EAAE,MAAM;MAC1B,MAAMC,YAAY,GAAGH,IAAI,CAACC,GAAG,CAAC,CAAC,GAAGF,SAAS;MAC3C,MAAMK,UAAU,GAAGP,QAAQ,CAACO,UAAU;MACtC,MAAMC,gBAAgB,GAAGC,OAAO,CAACC,GAAG,CAACC,aAAa,KAAK,MAAM;;MAE7D;MACA,IAAIC,QAAQ,GAAGC,kBAAW,CAACC,KAAK;MAChC,IAAIP,UAAU,IAAI,GAAG,EAAE;QACrBK,QAAQ,GAAGC,kBAAW,CAACE,KAAK;MAC9B,CAAC,MAAM,IAAIR,UAAU,IAAI,GAAG,EAAE;QAC5BK,QAAQ,GAAGC,kBAAW,CAACG,OAAO;MAChC;;MAEA;MACA,MAAMC,OAAO,GAAG,GAAGlB,OAAO,CAACmB,MAAM,IAAInB,OAAO,CAACoB,WAAW,IAAIpB,OAAO,CAACqB,GAAG,KAAKb,UAAU,KAAKD,YAAY,IAAI;;MAE3G;MACA,MAAMe,QAAsC,GAAG;QAC7CT,QAAQ;QACRK;MACF,CAAC;;MAED;MACA,IAAIT,gBAAgB,EAAE;QACpBa,QAAQ,CAACC,OAAO,GAAG;UACjBC,WAAW,EAAE;YACXL,MAAM,EAAEnB,OAAO,CAACmB,MAAM;YACtBE,GAAG,EAAErB,OAAO,CAACoB,WAAW,IAAIpB,OAAO,CAACqB,GAAG;YACvCI,SAAS,EAAEzB,OAAO,CAAC0B,MAAM,CAAC,YAAY,CAAC;YACvCC,QAAQ,EAAE3B,OAAO,CAAC4B,EAAE;YACpBC,QAAQ,EAAE7B,OAAO,CAAC0B,MAAM,CAAC,SAAS,CAAC;YACnCI,kBAAkB,EAAEtB;UACtB;QACF,CAAC;QACDc,QAAQ,CAACS,IAAI,GAAG;UACdxB,YAAY,EAAE,GAAGA,YAAY,IAAI;UACjCyB,aAAa,EAAE/B,QAAQ,CAACgC,SAAS,CAAC,gBAAgB,CAAC,IAAI,GAAG;UAC1DC,WAAW,EAAE,GAAGlC,OAAO,CAACmC,gBAAgB,IAAInC,OAAO,CAACoC,gBAAgB;QACtE,CAAC;MACH;MAEA,IAAAC,cAAM,EAACf,QAAQ,CAAC;IAClB,CAAC,CAAC;IAEFpB,IAAI,CAAC,CAAC;EACR,CAAC;AACH","ignoreList":[]}
|
|
@@ -48,62 +48,65 @@ function getSeverityColor(severity) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Format timestamp as HH:MM:SS
|
|
53
|
+
*/
|
|
54
|
+
function formatTime() {
|
|
55
|
+
const now = new Date();
|
|
56
|
+
return now.toTimeString().split(' ')[0];
|
|
57
|
+
}
|
|
58
|
+
|
|
51
59
|
/**
|
|
52
60
|
* Format log entry for human-readable local development output
|
|
53
61
|
*/
|
|
54
62
|
function formatLocalLog(entry) {
|
|
55
|
-
const
|
|
63
|
+
const time = formatTime();
|
|
56
64
|
const severity = entry.severity || 'INFO';
|
|
57
65
|
const severityColor = getSeverityColor(severity);
|
|
66
|
+
const showDetailedLogs = process.env.DETAILED_LOGS === 'true';
|
|
58
67
|
const parts = [];
|
|
59
68
|
|
|
60
69
|
// Timestamp and severity
|
|
61
|
-
parts.push(`${colors.gray}[${
|
|
62
|
-
|
|
63
|
-
// File location
|
|
64
|
-
if (entry.fileName) {
|
|
65
|
-
parts.push(`${colors.dim}${entry.fileName}:${entry.lineNumber || '?'}${colors.reset}`);
|
|
66
|
-
}
|
|
70
|
+
parts.push(`${colors.gray}[${time}]${colors.reset} ${severityColor}${severity.padEnd(8)}${colors.reset}`);
|
|
67
71
|
|
|
68
72
|
// Message
|
|
69
73
|
if (entry.message) {
|
|
70
|
-
parts.push(`${
|
|
74
|
+
parts.push(`${entry.message}`);
|
|
71
75
|
}
|
|
72
76
|
let output = parts.join(' ');
|
|
73
77
|
|
|
74
|
-
// Error details
|
|
75
|
-
if (entry.errorType) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
// Error details (compact format)
|
|
79
|
+
if (entry.errorType || entry.errorCode || entry.statusCode) {
|
|
80
|
+
const errorParts = [];
|
|
81
|
+
if (entry.errorCode) errorParts.push(`${colors.red}${entry.errorCode}${colors.reset}`);
|
|
82
|
+
if (entry.statusCode) {
|
|
83
|
+
const statusColor = entry.statusCode >= 500 ? colors.red : entry.statusCode >= 400 ? colors.yellow : colors.green;
|
|
84
|
+
errorParts.push(`${statusColor}${entry.statusCode}${colors.reset}`);
|
|
85
|
+
}
|
|
86
|
+
if (errorParts.length > 0) {
|
|
87
|
+
output += ` ${colors.dim}[${errorParts.join(' ')}]${colors.reset}`;
|
|
88
|
+
}
|
|
80
89
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
90
|
+
|
|
91
|
+
// HTTP request context (compact)
|
|
92
|
+
if (entry.context?.httpRequest) {
|
|
93
|
+
const req = entry.context.httpRequest;
|
|
94
|
+
output += ` ${colors.dim}${req.method} ${req.url}${colors.reset}`;
|
|
84
95
|
}
|
|
85
96
|
|
|
86
|
-
// Stack trace
|
|
87
|
-
if (entry.stack_trace) {
|
|
97
|
+
// Stack trace (only in detailed mode)
|
|
98
|
+
if (showDetailedLogs && entry.stack_trace) {
|
|
88
99
|
output += `\n${colors.gray}Stack Trace:${colors.reset}\n${colors.dim}${entry.stack_trace}${colors.reset}`;
|
|
89
100
|
}
|
|
90
101
|
|
|
91
|
-
// Additional data
|
|
92
|
-
if (entry.data && Object.keys(entry.data).length > 0) {
|
|
102
|
+
// Additional data (only in detailed mode or if no message)
|
|
103
|
+
if (showDetailedLogs && entry.data && Object.keys(entry.data).length > 0) {
|
|
93
104
|
output += `\n${colors.cyan}Data:${colors.reset}\n${colors.dim}${JSON.stringify(entry.data, null, 2)}${colors.reset}`;
|
|
94
105
|
}
|
|
95
106
|
|
|
96
|
-
//
|
|
97
|
-
if (entry.
|
|
98
|
-
|
|
99
|
-
output += `\n${colors.magenta}Request:${colors.reset}`;
|
|
100
|
-
output += `\n ${colors.dim}${req.method} ${req.url}${colors.reset}`;
|
|
101
|
-
if (req.userAgent) {
|
|
102
|
-
output += `\n ${colors.dim}User-Agent: ${req.userAgent}${colors.reset}`;
|
|
103
|
-
}
|
|
104
|
-
if (req.remoteIp) {
|
|
105
|
-
output += `\n ${colors.dim}IP: ${req.remoteIp}${colors.reset}`;
|
|
106
|
-
}
|
|
107
|
+
// File location (only in detailed mode)
|
|
108
|
+
if (showDetailedLogs && entry.fileName) {
|
|
109
|
+
output += `\n ${colors.dim}${entry.fileName}:${entry.lineNumber || '?'}${colors.reset}`;
|
|
107
110
|
}
|
|
108
111
|
return output;
|
|
109
112
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","names":["_crypto","require","_callsite","_interopRequireDefault","_jsonStringifySafe","_const","INSTANCE_ID","exports","randomUUID","colors","reset","bright","dim","red","green","yellow","blue","magenta","cyan","white","gray","getSeverityColor","severity","LogSeverity","DEBUG","INFO","WARNING","ERROR","CRITICAL","formatLocalLog","entry","timestamp","Date","toISOString","severityColor","parts","push","padEnd","fileName","lineNumber","message","output","join","errorType","errorCode","statusCode","statusColor","stack_trace","data","Object","keys","length","JSON","stringify","context","httpRequest","req","method","url","userAgent","remoteIp","isLocalDevelopment","process","env","LOG_FORMAT","NODE_ENV","KUBERNETES_POD_NAME","CLOUD_RUN_JOB","call","callsite","fullEntry","getLineNumber","getFileName","replace","serviceContext","service","CHART","HOSTNAME","version","BUILD_ID","environment","instance","SILENCE_REPORT","console","dir","depth","formattedLog","error","log"],"sources":["../../../src/utils/report/output.ts"],"sourcesContent":["import { randomUUID } from 'crypto';\nimport callsite from 'callsite';\nimport stringify from 'json-stringify-safe';\nimport { LogEntry, FullLogEntry } from './output.types';\nimport { LogSeverity } from 'const';\n\n// NOTE: Server instance id (helpful for distributed logs)\nexport const INSTANCE_ID = randomUUID();\n\n// ANSI color codes for terminal output\nconst colors = {\n reset: '\\x1b[0m',\n bright: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n magenta: '\\x1b[35m',\n cyan: '\\x1b[36m',\n white: '\\x1b[37m',\n gray: '\\x1b[90m'\n};\n\n/**\n * Get color for log severity level\n */\nfunction getSeverityColor(severity?: string): string {\n switch (severity) {\n case LogSeverity.DEBUG:\n return colors.cyan;\n case LogSeverity.INFO:\n return colors.green;\n case LogSeverity.WARNING:\n return colors.yellow;\n case LogSeverity.ERROR:\n return colors.red;\n case LogSeverity.CRITICAL:\n return `${colors.bright}${colors.red}`;\n default:\n return colors.white;\n }\n}\n\n/**\n * Format log entry for human-readable local development output\n */\nfunction formatLocalLog(entry: FullLogEntry): string {\n const timestamp = new Date().toISOString();\n const severity = entry.severity || 'INFO';\n const severityColor = getSeverityColor(severity);\n \n const parts: string[] = [];\n \n // Timestamp and severity\n parts.push(\n `${colors.gray}[${timestamp}]${colors.reset} ${severityColor}${severity.padEnd(8)}${colors.reset}`\n );\n \n // File location\n if (entry.fileName) {\n parts.push(`${colors.dim}${entry.fileName}:${entry.lineNumber || '?'}${colors.reset}`);\n }\n \n // Message\n if (entry.message) {\n parts.push(`${colors.bright}${entry.message}${colors.reset}`);\n }\n \n let output = parts.join(' ');\n \n // Error details\n if (entry.errorType) {\n output += `\\n ${colors.red}Error Type:${colors.reset} ${entry.errorType}`;\n }\n \n if (entry.errorCode) {\n output += `\\n ${colors.red}Error Code:${colors.reset} ${entry.errorCode}`;\n }\n \n if (entry.statusCode) {\n const statusColor = entry.statusCode >= 500 ? colors.red : entry.statusCode >= 400 ? colors.yellow : colors.green;\n output += `\\n ${colors.cyan}Status:${colors.reset} ${statusColor}${entry.statusCode}${colors.reset}`;\n }\n \n // Stack trace\n if (entry.stack_trace) {\n output += `\\n${colors.gray}Stack Trace:${colors.reset}\\n${colors.dim}${entry.stack_trace}${colors.reset}`;\n }\n \n // Additional data\n if (entry.data && Object.keys(entry.data).length > 0) {\n output += `\\n${colors.cyan}Data:${colors.reset}\\n${colors.dim}${JSON.stringify(entry.data, null, 2)}${colors.reset}`;\n }\n \n // HTTP request context\n if (entry.context?.httpRequest) {\n const req = entry.context.httpRequest;\n output += `\\n${colors.magenta}Request:${colors.reset}`;\n output += `\\n ${colors.dim}${req.method} ${req.url}${colors.reset}`;\n if (req.userAgent) {\n output += `\\n ${colors.dim}User-Agent: ${req.userAgent}${colors.reset}`;\n }\n if (req.remoteIp) {\n output += `\\n ${colors.dim}IP: ${req.remoteIp}${colors.reset}`;\n }\n }\n \n return output;\n}\n\n/**\n * Check if running in local development environment\n */\nfunction isLocalDevelopment(): boolean {\n // Allow forcing local format via environment variable\n if (process.env.LOG_FORMAT === 'local') return true;\n if (process.env.LOG_FORMAT === 'json') return false;\n \n return (\n process.env.NODE_ENV === 'development' ||\n process.env.NODE_ENV === 'dev' ||\n (!process.env.NODE_ENV && !process.env.KUBERNETES_POD_NAME && !process.env.CLOUD_RUN_JOB)\n );\n}\n\n/** Add metadata to the log entry and print it */\nexport function output(data: LogEntry): FullLogEntry {\n // Gather useful information about where the logger was called from\n const call = callsite()[2];\n\n // Append additional metadata to the log entry\n const fullEntry: FullLogEntry = {\n ...data,\n lineNumber: call.getLineNumber(),\n fileName: call\n .getFileName()\n .replace(/.*node_modules\\//, '')\n .replace(/.*src\\//, 'src/'),\n serviceContext: {\n service: process.env.CHART ?? process.env.HOSTNAME,\n version: process.env.BUILD_ID,\n environment: process.env.NODE_ENV,\n instance: process.env.KUBERNETES_POD_NAME ?? INSTANCE_ID\n }\n };\n\n // Ignore when silenced\n if (process.env.SILENCE_REPORT) return fullEntry;\n\n if (process.env.NODE_ENV === 'test') {\n // In test mode pretty print with full depth\n console.dir(fullEntry, { depth: 5 });\n } else if (isLocalDevelopment()) {\n // Local development: use formatted, colorized output\n const formattedLog = formatLocalLog(fullEntry);\n if (data.severity === LogSeverity.ERROR || data.severity === LogSeverity.CRITICAL || (data.statusCode && data.statusCode >= 500)) {\n console.error(formattedLog);\n } else {\n console.log(formattedLog);\n }\n } else {\n // Production/GCP: use JSON format for structured logging\n const entry = stringify(fullEntry);\n if (data.statusCode && data.statusCode >= 500) {\n console.error(entry);\n } else {\n console.log(entry);\n }\n }\n \n return fullEntry;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"output.js","names":["_crypto","require","_callsite","_interopRequireDefault","_jsonStringifySafe","_const","INSTANCE_ID","exports","randomUUID","colors","reset","bright","dim","red","green","yellow","blue","magenta","cyan","white","gray","getSeverityColor","severity","LogSeverity","DEBUG","INFO","WARNING","ERROR","CRITICAL","formatTime","now","Date","toTimeString","split","formatLocalLog","entry","time","severityColor","showDetailedLogs","process","env","DETAILED_LOGS","parts","push","padEnd","message","output","join","errorType","errorCode","statusCode","errorParts","statusColor","length","context","httpRequest","req","method","url","stack_trace","data","Object","keys","JSON","stringify","fileName","lineNumber","isLocalDevelopment","LOG_FORMAT","NODE_ENV","KUBERNETES_POD_NAME","CLOUD_RUN_JOB","call","callsite","fullEntry","getLineNumber","getFileName","replace","serviceContext","service","CHART","HOSTNAME","version","BUILD_ID","environment","instance","SILENCE_REPORT","console","dir","depth","formattedLog","error","log"],"sources":["../../../src/utils/report/output.ts"],"sourcesContent":["import { randomUUID } from 'crypto';\nimport callsite from 'callsite';\nimport stringify from 'json-stringify-safe';\nimport { LogEntry, FullLogEntry } from './output.types';\nimport { LogSeverity } from 'const';\n\n// NOTE: Server instance id (helpful for distributed logs)\nexport const INSTANCE_ID = randomUUID();\n\n// ANSI color codes for terminal output\nconst colors = {\n reset: '\\x1b[0m',\n bright: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n magenta: '\\x1b[35m',\n cyan: '\\x1b[36m',\n white: '\\x1b[37m',\n gray: '\\x1b[90m'\n};\n\n/**\n * Get color for log severity level\n */\nfunction getSeverityColor(severity?: string): string {\n switch (severity) {\n case LogSeverity.DEBUG:\n return colors.cyan;\n case LogSeverity.INFO:\n return colors.green;\n case LogSeverity.WARNING:\n return colors.yellow;\n case LogSeverity.ERROR:\n return colors.red;\n case LogSeverity.CRITICAL:\n return `${colors.bright}${colors.red}`;\n default:\n return colors.white;\n }\n}\n\n/**\n * Format timestamp as HH:MM:SS\n */\nfunction formatTime(): string {\n const now = new Date();\n return now.toTimeString().split(' ')[0];\n}\n\n/**\n * Format log entry for human-readable local development output\n */\nfunction formatLocalLog(entry: FullLogEntry): string {\n const time = formatTime();\n const severity = entry.severity || 'INFO';\n const severityColor = getSeverityColor(severity);\n const showDetailedLogs = process.env.DETAILED_LOGS === 'true';\n \n const parts: string[] = [];\n \n // Timestamp and severity\n parts.push(\n `${colors.gray}[${time}]${colors.reset} ${severityColor}${severity.padEnd(8)}${colors.reset}`\n );\n \n // Message\n if (entry.message) {\n parts.push(`${entry.message}`);\n }\n \n let output = parts.join(' ');\n \n // Error details (compact format)\n if (entry.errorType || entry.errorCode || entry.statusCode) {\n const errorParts: string[] = [];\n if (entry.errorCode) errorParts.push(`${colors.red}${entry.errorCode}${colors.reset}`);\n if (entry.statusCode) {\n const statusColor = entry.statusCode >= 500 ? colors.red : entry.statusCode >= 400 ? colors.yellow : colors.green;\n errorParts.push(`${statusColor}${entry.statusCode}${colors.reset}`);\n }\n if (errorParts.length > 0) {\n output += ` ${colors.dim}[${errorParts.join(' ')}]${colors.reset}`;\n }\n }\n \n // HTTP request context (compact)\n if (entry.context?.httpRequest) {\n const req = entry.context.httpRequest;\n output += ` ${colors.dim}${req.method} ${req.url}${colors.reset}`;\n }\n \n // Stack trace (only in detailed mode)\n if (showDetailedLogs && entry.stack_trace) {\n output += `\\n${colors.gray}Stack Trace:${colors.reset}\\n${colors.dim}${entry.stack_trace}${colors.reset}`;\n }\n \n // Additional data (only in detailed mode or if no message)\n if (showDetailedLogs && entry.data && Object.keys(entry.data).length > 0) {\n output += `\\n${colors.cyan}Data:${colors.reset}\\n${colors.dim}${JSON.stringify(entry.data, null, 2)}${colors.reset}`;\n }\n \n // File location (only in detailed mode)\n if (showDetailedLogs && entry.fileName) {\n output += `\\n ${colors.dim}${entry.fileName}:${entry.lineNumber || '?'}${colors.reset}`;\n }\n \n return output;\n}\n\n/**\n * Check if running in local development environment\n */\nfunction isLocalDevelopment(): boolean {\n // Allow forcing local format via environment variable\n if (process.env.LOG_FORMAT === 'local') return true;\n if (process.env.LOG_FORMAT === 'json') return false;\n \n return (\n process.env.NODE_ENV === 'development' ||\n process.env.NODE_ENV === 'dev' ||\n (!process.env.NODE_ENV && !process.env.KUBERNETES_POD_NAME && !process.env.CLOUD_RUN_JOB)\n );\n}\n\n/** Add metadata to the log entry and print it */\nexport function output(data: LogEntry): FullLogEntry {\n // Gather useful information about where the logger was called from\n const call = callsite()[2];\n\n // Append additional metadata to the log entry\n const fullEntry: FullLogEntry = {\n ...data,\n lineNumber: call.getLineNumber(),\n fileName: call\n .getFileName()\n .replace(/.*node_modules\\//, '')\n .replace(/.*src\\//, 'src/'),\n serviceContext: {\n service: process.env.CHART ?? process.env.HOSTNAME,\n version: process.env.BUILD_ID,\n environment: process.env.NODE_ENV,\n instance: process.env.KUBERNETES_POD_NAME ?? INSTANCE_ID\n }\n };\n\n // Ignore when silenced\n if (process.env.SILENCE_REPORT) return fullEntry;\n\n if (process.env.NODE_ENV === 'test') {\n // In test mode pretty print with full depth\n console.dir(fullEntry, { depth: 5 });\n } else if (isLocalDevelopment()) {\n // Local development: use formatted, colorized output\n const formattedLog = formatLocalLog(fullEntry);\n if (data.severity === LogSeverity.ERROR || data.severity === LogSeverity.CRITICAL || (data.statusCode && data.statusCode >= 500)) {\n console.error(formattedLog);\n } else {\n console.log(formattedLog);\n }\n } else {\n // Production/GCP: use JSON format for structured logging\n const entry = stringify(fullEntry);\n if (data.statusCode && data.statusCode >= 500) {\n console.error(entry);\n } else {\n console.log(entry);\n }\n }\n \n return fullEntry;\n}\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-server-engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Framework used to develop backend services. This package ships with a lot of features to standardize the creation of services, letting you focus on the business logic.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -74,7 +74,6 @@
|
|
|
74
74
|
"jsonwebtoken": "^9.0.2",
|
|
75
75
|
"jwks-rsa": "^3.1.0",
|
|
76
76
|
"mime-types": "^2.1.35",
|
|
77
|
-
"morgan": "^1.10.0",
|
|
78
77
|
"ms": "^2.1.3",
|
|
79
78
|
"multer": "^2.0.1",
|
|
80
79
|
"mysql2": "^3.11.5",
|