@goatlab/node-backend 0.2.5 → 0.4.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 (44) hide show
  1. package/README.md +146 -14
  2. package/dist/container/Container.d.ts +113 -25
  3. package/dist/container/Container.js +391 -168
  4. package/dist/container/Container.js.map +1 -1
  5. package/dist/container/examples/batch-operations.example.d.ts +1 -0
  6. package/dist/container/examples/batch-operations.example.js +165 -0
  7. package/dist/container/examples/batch-operations.example.js.map +1 -0
  8. package/dist/container/helpers.d.ts +8 -0
  9. package/dist/container/helpers.js +22 -0
  10. package/dist/container/helpers.js.map +1 -1
  11. package/dist/container/types.d.ts +60 -0
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/server/bootstraps/getExpressTrpcApp.d.ts +5 -1
  15. package/dist/server/bootstraps/getExpressTrpcApp.js +216 -12
  16. package/dist/server/bootstraps/getExpressTrpcApp.js.map +1 -1
  17. package/dist/server/middleware/memoryMonitor.example.d.ts +1 -0
  18. package/dist/server/middleware/memoryMonitor.example.js +109 -0
  19. package/dist/server/middleware/memoryMonitor.example.js.map +1 -0
  20. package/dist/server/middleware/memoryMonitor.middleware.d.ts +42 -0
  21. package/dist/server/middleware/memoryMonitor.middleware.js +134 -0
  22. package/dist/server/middleware/memoryMonitor.middleware.js.map +1 -0
  23. package/dist/server/middleware/productionError.middleware.d.ts +16 -0
  24. package/dist/server/middleware/productionError.middleware.js +94 -0
  25. package/dist/server/middleware/productionError.middleware.js.map +1 -0
  26. package/dist/server/middleware/security.middleware.d.ts +28 -0
  27. package/dist/server/middleware/security.middleware.js +151 -0
  28. package/dist/server/middleware/security.middleware.js.map +1 -0
  29. package/dist/server/services/secrets/examples/container-preload.example.d.ts +1 -0
  30. package/dist/server/services/secrets/examples/container-preload.example.js +148 -0
  31. package/dist/server/services/secrets/examples/container-preload.example.js.map +1 -0
  32. package/dist/server/services/secrets/index.d.ts +1 -0
  33. package/dist/server/services/secrets/index.js +6 -0
  34. package/dist/server/services/secrets/index.js.map +1 -0
  35. package/dist/server/services/secrets/secret.service.d.ts +48 -6
  36. package/dist/server/services/secrets/secret.service.js +280 -28
  37. package/dist/server/services/secrets/secret.service.js.map +1 -1
  38. package/dist/server/services/translations/translation.model.js +2 -1
  39. package/dist/server/services/translations/translation.model.js.map +1 -1
  40. package/dist/server/services/translations/translation.service.d.ts +8 -1
  41. package/dist/server/services/translations/translation.service.js +123 -13
  42. package/dist/server/services/translations/translation.service.js.map +1 -1
  43. package/dist/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +13 -1
@@ -11,6 +11,12 @@ const cors = require('cors');
11
11
  const express = require("express");
12
12
  // eslint-disable-next-line @typescript-eslint/no-require-imports
13
13
  const helmet = require('helmet');
14
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
15
+ const compression = require('compression');
16
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
17
+ const timeout = require('connect-timeout');
18
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
19
+ const responseTime = require('response-time');
14
20
  const colors_1 = require("kleur/colors");
15
21
  const trpc_to_openapi_1 = require("trpc-to-openapi");
16
22
  const consts_1 = require("../consts");
@@ -19,6 +25,9 @@ const initOpenApiDocs_1 = require("../initOpenApiDocs");
19
25
  const error_middleware_1 = require("../middleware/error.middleware");
20
26
  const logs_middleware_1 = require("../middleware/logs.middleware");
21
27
  const trpcError_middleware_1 = require("../middleware/trpcError.middleware");
28
+ const productionError_middleware_1 = require("../middleware/productionError.middleware");
29
+ const memoryMonitor_middleware_1 = require("../middleware/memoryMonitor.middleware");
30
+ const security_middleware_1 = require("../middleware/security.middleware");
22
31
  // There is an issue returning the
23
32
  // row count in Mysql (bigint) and parsing
24
33
  // it back to JSON
@@ -30,23 +39,133 @@ const trpcError_middleware_1 = require("../middleware/trpcError.middleware");
30
39
  function getExpressTrpcApp({ trpcRouter, port, expressResources, shouldInitOpenApiDocs, baseUrl = `http://localhost:${port}`, shouldEnableSentry, sentryService, logger = console, customHandlers }) {
31
40
  logger.log(`Starting ${consts_1.pkg.name}`);
32
41
  const app = express();
33
- app.use(cors());
34
- app.use(helmet());
35
- app.disable('etag');
42
+ // Performance: Enable compression with optimized settings
43
+ app.use(compression({
44
+ // Compression level: 6 provides a good balance between speed and compression ratio
45
+ level: 6,
46
+ // Skip compression for small responses (< 1KB)
47
+ threshold: 1024,
48
+ // Optimize compression buffer sizes for better performance
49
+ chunkSize: 16 * 1024, // 16KB chunks
50
+ memLevel: 8, // Memory usage level (1-9)
51
+ // Custom filter to handle various edge cases
52
+ filter: (req, res) => {
53
+ // Skip compression for already compressed content types
54
+ const contentType = res.getHeader('Content-Type');
55
+ const compressedTypes = [
56
+ 'image/', 'audio/', 'video/', 'font/',
57
+ 'application/pdf', 'application/zip',
58
+ 'application/gzip', 'application/x-gzip',
59
+ 'application/x-rar-compressed', 'application/x-7z-compressed',
60
+ 'application/vnd.ms-fontobject', 'application/font-woff',
61
+ 'application/font-woff2', 'application/x-font-ttf',
62
+ 'application/x-font-truetype', 'application/x-font-opentype'
63
+ ];
64
+ if (contentType && compressedTypes.some(type => contentType.includes(type))) {
65
+ return false;
66
+ }
67
+ // Skip compression for Server-Sent Events
68
+ if (contentType && contentType.includes('text/event-stream')) {
69
+ return false;
70
+ }
71
+ // Skip compression for WebSocket upgrade requests
72
+ if (req.headers.upgrade === 'websocket') {
73
+ return false;
74
+ }
75
+ // Skip compression if Cache-Control contains no-transform directive
76
+ const cacheControl = req.headers['cache-control'] || res.getHeader('Cache-Control');
77
+ if (cacheControl?.includes('no-transform')) {
78
+ return false;
79
+ }
80
+ // Skip compression for HEAD requests
81
+ if (req.method === 'HEAD') {
82
+ return false;
83
+ }
84
+ // Skip compression if response already has Content-Encoding header
85
+ const encoding = res.getHeader('Content-Encoding');
86
+ if (encoding && encoding !== 'identity') {
87
+ return false;
88
+ }
89
+ // Use the default compression filter for all other cases
90
+ return compression.filter(req, res);
91
+ }
92
+ }));
93
+ // Performance: Add response time header
94
+ app.use(responseTime());
95
+ // Performance: Add memory monitoring middleware
96
+ const { middleware: memoryMiddleware, monitor: memoryMonitor } = (0, memoryMonitor_middleware_1.createMemoryMonitorMiddleware)({
97
+ logger,
98
+ warningThreshold: 90,
99
+ criticalThreshold: 95,
100
+ monitorInterval: 30000, // Check every 30 seconds
101
+ enableGarbageCollection: process.env.NODE_ENV === 'prod', // Only enable GC in production
102
+ addHeaders: process.env.NODE_ENV !== 'prod' // Add headers in non-production environments
103
+ });
104
+ app.use(memoryMiddleware);
105
+ // Security: Configure CORS with proper settings
106
+ app.use(cors((0, security_middleware_1.getCorsOptions)()));
107
+ // Security: Configure Helmet with enhanced settings
108
+ app.use(helmet((0, security_middleware_1.getHelmetOptions)()));
109
+ // Security: Additional security headers
110
+ app.use((0, security_middleware_1.additionalSecurityHeaders)());
111
+ // Security: Add request timeout (30 seconds default)
112
+ app.use(timeout(process.env.REQUEST_TIMEOUT || '30s'));
113
+ app.use((req, _res, next) => {
114
+ if (!req.timedout)
115
+ next();
116
+ });
117
+ // Security: Rate limiting - global
118
+ app.use((0, security_middleware_1.createRateLimiter)());
119
+ // Security: Stricter rate limiting for auth endpoints
120
+ app.use((req, res, next) => {
121
+ if (req.path.startsWith('/trpc/auth') || req.path.startsWith('/api/auth')) {
122
+ (0, security_middleware_1.createAuthRateLimiter)()(req, res, next);
123
+ }
124
+ else {
125
+ next();
126
+ }
127
+ });
128
+ // Security: API rate limiting
129
+ app.use('/trpc/', (0, security_middleware_1.createApiRateLimiter)());
130
+ app.use('/api/', (0, security_middleware_1.createApiRateLimiter)());
131
+ // Enable ETags for better caching
132
+ app.set('etag', 'strong');
36
133
  app.set('trust proxy', true);
37
134
  if (shouldEnableSentry) {
38
135
  Sentry.setupExpressErrorHandler(app);
39
136
  }
40
- app.use(express.json({ limit: '1mb', type: ['application/json', 'text/plain'] }));
41
- app.use(express.urlencoded({ limit: '1mb', extended: true }));
137
+ // Configure body parsing with security limits
138
+ const jsonLimit = process.env.JSON_BODY_LIMIT || '100kb';
139
+ const urlEncodedLimit = process.env.URL_ENCODED_LIMIT || '100kb';
140
+ const rawLimit = process.env.RAW_BODY_LIMIT || '100kb';
141
+ app.use(express.json({
142
+ limit: jsonLimit,
143
+ type: ['application/json', 'text/plain'],
144
+ verify: (req, res, buf) => {
145
+ // Store raw body for webhook signature verification if needed
146
+ req.rawBody = buf.toString('utf8');
147
+ }
148
+ }));
149
+ app.use(express.urlencoded({ limit: urlEncodedLimit, extended: true }));
42
150
  app.use(express.raw({
43
151
  inflate: true,
44
- limit: '100kb'
152
+ limit: rawLimit
45
153
  }));
154
+ // Add cache headers for static content
155
+ app.use((req, res, next) => {
156
+ if (req.url.match(/\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$/)) {
157
+ res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
158
+ }
159
+ next();
160
+ });
46
161
  app.use((req, resp, next) => (0, logs_middleware_1.expressRequestLogger)(req, resp, next, logger));
47
162
  app.use((0, error_middleware_1.genericErrorMiddleware)({
48
163
  sentryService: shouldEnableSentry ? sentryService : undefined
49
164
  }));
165
+ // Add production error handler for sanitized error responses
166
+ if (process.env.NODE_ENV === 'prod') {
167
+ app.use((0, productionError_middleware_1.productionErrorHandler)());
168
+ }
50
169
  customHandlers?.forEach(customHandler => {
51
170
  app.use(customHandler);
52
171
  });
@@ -82,20 +201,105 @@ function getExpressTrpcApp({ trpcRouter, port, expressResources, shouldInitOpenA
82
201
  });
83
202
  app.set('view engine', 'ejs');
84
203
  app.set('views', [(0, path_1.join)(__dirname, './api/posts/views')]);
204
+ // Health check endpoints
205
+ app.get('/health', (req, res) => {
206
+ const memoryUsage = process.memoryUsage();
207
+ const lastMetrics = memoryMonitor.getLastMetrics();
208
+ res.json({
209
+ status: 'ok',
210
+ timestamp: new Date().toISOString(),
211
+ service: consts_1.pkg.name,
212
+ version: consts_1.pkg.version,
213
+ uptime: process.uptime(),
214
+ memory: {
215
+ used: js_utils_1.Units.humanByteSize(memoryUsage.heapUsed),
216
+ total: js_utils_1.Units.humanByteSize(memoryUsage.heapTotal),
217
+ percentage: lastMetrics ? lastMetrics.heapUsedPercentage.toFixed(1) + '%' : 'N/A',
218
+ rss: js_utils_1.Units.humanByteSize(memoryUsage.rss),
219
+ external: js_utils_1.Units.humanByteSize(memoryUsage.external),
220
+ monitoring: {
221
+ lastCheck: lastMetrics ? new Date(lastMetrics.timestamp).toISOString() : 'N/A',
222
+ warningThreshold: '90%',
223
+ criticalThreshold: '95%'
224
+ }
225
+ }
226
+ });
227
+ });
228
+ // Readiness check endpoint
229
+ app.get('/ready', async (req, res) => {
230
+ try {
231
+ // Add your readiness checks here
232
+ // For example: check database connection, external services, etc.
233
+ const checks = {
234
+ service: 'ready',
235
+ timestamp: new Date().toISOString()
236
+ };
237
+ res.json(checks);
238
+ }
239
+ catch (error) {
240
+ res.status(503).json({
241
+ status: 'not ready',
242
+ error: error instanceof Error ? error.message : 'Unknown error'
243
+ });
244
+ }
245
+ });
85
246
  /**
86
- * Start the app
247
+ * Start the app with graceful shutdown support
87
248
  */
88
- if (process.env.K_SERVICE) {
89
- app.listen(port, '0.0.0.0');
249
+ let server;
250
+ // Don't start server in test environment
251
+ if (process.env.NODE_ENV !== 'test') {
252
+ if (process.env.K_SERVICE) {
253
+ server = app.listen(port, '0.0.0.0');
254
+ }
255
+ else {
256
+ server = app.listen(port, '::');
257
+ }
90
258
  }
91
- else {
92
- app.listen(port, '::');
259
+ // Graceful shutdown handler
260
+ const gracefulShutdown = () => {
261
+ logger.log('SIGTERM signal received: closing HTTP server');
262
+ // Stop memory monitoring
263
+ memoryMonitor.stopMonitoring();
264
+ if (server) {
265
+ server.close(() => {
266
+ logger.log('HTTP server closed');
267
+ // Perform cleanup tasks here
268
+ // Close database connections, message queues, etc.
269
+ process.exit(0);
270
+ });
271
+ // Force shutdown after 30 seconds
272
+ setTimeout(() => {
273
+ logger.error('Could not close connections in time, forcefully shutting down');
274
+ process.exit(1);
275
+ }, 30000);
276
+ }
277
+ };
278
+ // Only add process listeners if server was started (not in test env)
279
+ if (server) {
280
+ // Listen for termination signals
281
+ process.once('SIGTERM', gracefulShutdown);
282
+ process.once('SIGINT', gracefulShutdown);
283
+ // Handle uncaught errors
284
+ process.once('uncaughtException', (error) => {
285
+ logger.error('Uncaught Exception:', error);
286
+ if (shouldEnableSentry && sentryService) {
287
+ Sentry.captureException(error);
288
+ }
289
+ gracefulShutdown();
290
+ });
291
+ process.on('unhandledRejection', (reason, _promise) => {
292
+ logger.error('Unhandled Rejection at:', _promise, 'reason:', reason);
293
+ if (shouldEnableSentry && sentryService) {
294
+ Sentry.captureException(reason);
295
+ }
296
+ });
93
297
  }
94
298
  const address = `http://localhost:${port}`;
95
299
  const used = js_utils_1.Units.humanByteSize(process.memoryUsage().heapUsed);
96
300
  console.log(`App Local Url:
97
301
  ${(0, colors_1.yellow)(address)}
98
302
  in ${js_utils_1.Time.ms(process.uptime() * 1000)}, used ${used}`);
99
- return app;
303
+ return { app, server };
100
304
  }
101
305
  //# sourceMappingURL=getExpressTrpcApp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getExpressTrpcApp.js","sourceRoot":"","sources":["../../../src/server/bootstraps/getExpressTrpcApp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"getExpressTrpcApp.js","sourceRoot":"","sources":["../../../src/server/bootstraps/getExpressTrpcApp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ // npx ts-node ./src/server/middleware/memoryMonitor.example.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ /**
5
+ * Example demonstrating memory monitoring middleware capabilities
6
+ *
7
+ * This example shows:
8
+ * 1. How memory monitoring tracks heap usage
9
+ * 2. Warning and critical threshold alerts
10
+ * 3. Memory metrics in response headers
11
+ * 4. Automatic garbage collection triggers (when available)
12
+ *
13
+ * To run with garbage collection enabled:
14
+ * node --expose-gc -r ts-node/register ./src/server/middleware/memoryMonitor.example.ts
15
+ */
16
+ const express_1 = require("express");
17
+ const memoryMonitor_middleware_1 = require("./memoryMonitor.middleware");
18
+ const app = (0, express_1.default)();
19
+ const port = 3001;
20
+ // Create memory monitor with aggressive thresholds for demo
21
+ const { middleware: memoryMiddleware, monitor } = (0, memoryMonitor_middleware_1.createMemoryMonitorMiddleware)({
22
+ warningThreshold: 70, // Warn at 70% heap usage
23
+ criticalThreshold: 85, // Critical at 85% heap usage
24
+ monitorInterval: 5000, // Check every 5 seconds
25
+ enableGarbageCollection: true,
26
+ addHeaders: true // Add memory info to response headers
27
+ });
28
+ app.use(memoryMiddleware);
29
+ // Endpoint to check current memory status
30
+ app.get('/memory-status', (req, res) => {
31
+ const metrics = monitor.getLastMetrics();
32
+ const memUsage = process.memoryUsage();
33
+ res.json({
34
+ current: {
35
+ heapUsedMB: (memUsage.heapUsed / (1024 * 1024)).toFixed(2),
36
+ heapTotalMB: (memUsage.heapTotal / (1024 * 1024)).toFixed(2),
37
+ heapUsedPercent: ((memUsage.heapUsed / memUsage.heapTotal) * 100).toFixed(1),
38
+ rssMB: (memUsage.rss / (1024 * 1024)).toFixed(2)
39
+ },
40
+ lastMonitored: metrics ? {
41
+ heapUsedMB: metrics.heapUsedMB.toFixed(2),
42
+ heapTotalMB: metrics.heapTotalMB.toFixed(2),
43
+ heapUsedPercent: metrics.heapUsedPercentage.toFixed(1),
44
+ timestamp: new Date(metrics.timestamp).toISOString()
45
+ } : null,
46
+ thresholds: {
47
+ warning: '70%',
48
+ critical: '85%'
49
+ }
50
+ });
51
+ });
52
+ // Endpoint to simulate memory leak (for testing)
53
+ let leakedData = [];
54
+ app.get('/leak-memory', (req, res) => {
55
+ // Allocate 10MB of memory
56
+ const size = 10 * 1024 * 1024;
57
+ const buffer = Buffer.alloc(size);
58
+ leakedData.push(buffer);
59
+ res.json({
60
+ message: 'Allocated 10MB',
61
+ totalLeaked: `${leakedData.length * 10}MB`,
62
+ currentHeapMB: (process.memoryUsage().heapUsed / (1024 * 1024)).toFixed(2)
63
+ });
64
+ });
65
+ // Endpoint to clear leaked memory
66
+ app.get('/clear-memory', (req, res) => {
67
+ const beforeMB = (process.memoryUsage().heapUsed / (1024 * 1024)).toFixed(2);
68
+ leakedData = [];
69
+ // Force garbage collection if available
70
+ if (global.gc) {
71
+ global.gc();
72
+ }
73
+ setTimeout(() => {
74
+ const afterMB = (process.memoryUsage().heapUsed / (1024 * 1024)).toFixed(2);
75
+ res.json({
76
+ message: 'Memory cleared',
77
+ beforeMB,
78
+ afterMB,
79
+ freedMB: (parseFloat(beforeMB) - parseFloat(afterMB)).toFixed(2)
80
+ });
81
+ }, 100);
82
+ });
83
+ // Health endpoint showing memory in response
84
+ app.get('/health', (req, res) => {
85
+ res.json({ status: 'ok', timestamp: new Date().toISOString() });
86
+ });
87
+ const server = app.listen(port, () => {
88
+ console.log(`Memory monitoring example server running at http://localhost:${port}`);
89
+ console.log('\nEndpoints:');
90
+ console.log(' GET /memory-status - Check current memory usage');
91
+ console.log(' GET /leak-memory - Simulate memory leak (allocates 10MB)');
92
+ console.log(' GET /clear-memory - Clear leaked memory');
93
+ console.log(' GET /health - Health check (see memory headers)');
94
+ console.log('\nMemory headers added to all responses:');
95
+ console.log(' X-Memory-Heap-Used-MB');
96
+ console.log(' X-Memory-Heap-Total-MB');
97
+ console.log(' X-Memory-Heap-Used-Percent');
98
+ console.log(' X-Memory-RSS-MB');
99
+ console.log('\nWatch the console for memory warnings/alerts!');
100
+ });
101
+ // Graceful shutdown
102
+ process.on('SIGTERM', () => {
103
+ monitor.stopMonitoring();
104
+ server.close(() => {
105
+ console.log('Server closed');
106
+ process.exit(0);
107
+ });
108
+ });
109
+ //# sourceMappingURL=memoryMonitor.example.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memoryMonitor.example.js","sourceRoot":"","sources":["../../../src/server/middleware/memoryMonitor.example.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { Request, Response, NextFunction } from 'express';
2
+ import { CommonLogger } from '@goatlab/js-utils';
3
+ interface MemoryMonitorOptions {
4
+ logger?: CommonLogger;
5
+ warningThreshold?: number;
6
+ criticalThreshold?: number;
7
+ monitorInterval?: number;
8
+ enableGarbageCollection?: boolean;
9
+ addHeaders?: boolean;
10
+ }
11
+ interface MemoryMetrics {
12
+ heapUsedMB: number;
13
+ heapTotalMB: number;
14
+ heapUsedPercentage: number;
15
+ rssMB: number;
16
+ timestamp: number;
17
+ }
18
+ declare class MemoryMonitor {
19
+ private logger;
20
+ private warningThreshold;
21
+ private criticalThreshold;
22
+ private monitorInterval;
23
+ private enableGarbageCollection;
24
+ private addHeaders;
25
+ private intervalTimer?;
26
+ private lastMetrics?;
27
+ private gcAvailable;
28
+ constructor(options?: MemoryMonitorOptions);
29
+ private getMemoryMetrics;
30
+ private formatMemoryMetrics;
31
+ private checkMemoryUsage;
32
+ startMonitoring(): void;
33
+ stopMonitoring(): void;
34
+ middleware(): (_req: Request, res: Response, next: NextFunction) => void;
35
+ getLastMetrics(): MemoryMetrics | undefined;
36
+ }
37
+ export declare function createMemoryMonitorMiddleware(options?: MemoryMonitorOptions): {
38
+ middleware: (req: Request, res: Response, next: NextFunction) => void;
39
+ monitor: MemoryMonitor;
40
+ };
41
+ export declare function memoryMonitorMiddleware(options?: MemoryMonitorOptions): (req: Request, res: Response, next: NextFunction) => void;
42
+ export {};
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ // npx vitest run ./src/server/middleware/memoryMonitor.middleware.test.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.createMemoryMonitorMiddleware = createMemoryMonitorMiddleware;
5
+ exports.memoryMonitorMiddleware = memoryMonitorMiddleware;
6
+ const colors_1 = require("kleur/colors");
7
+ class MemoryMonitor {
8
+ logger;
9
+ warningThreshold;
10
+ criticalThreshold;
11
+ monitorInterval;
12
+ enableGarbageCollection;
13
+ addHeaders;
14
+ intervalTimer;
15
+ lastMetrics;
16
+ gcAvailable;
17
+ constructor(options = {}) {
18
+ this.logger = options.logger || console;
19
+ this.warningThreshold = options.warningThreshold || 90;
20
+ this.criticalThreshold = options.criticalThreshold || 95;
21
+ this.monitorInterval = options.monitorInterval || 30000; // 30 seconds default
22
+ this.enableGarbageCollection = options.enableGarbageCollection !== false;
23
+ this.addHeaders = options.addHeaders !== false;
24
+ // Check if garbage collection is available
25
+ this.gcAvailable = typeof global.gc === 'function';
26
+ if (this.enableGarbageCollection && !this.gcAvailable) {
27
+ this.logger.warn('Garbage collection is not available. Run node with --expose-gc flag to enable.');
28
+ }
29
+ }
30
+ getMemoryMetrics() {
31
+ const memUsage = process.memoryUsage();
32
+ const heapUsedMB = memUsage.heapUsed / (1024 * 1024);
33
+ const heapTotalMB = memUsage.heapTotal / (1024 * 1024);
34
+ const heapUsedPercentage = (memUsage.heapUsed / memUsage.heapTotal) * 100;
35
+ const rssMB = memUsage.rss / (1024 * 1024);
36
+ return {
37
+ heapUsedMB,
38
+ heapTotalMB,
39
+ heapUsedPercentage,
40
+ rssMB,
41
+ timestamp: Date.now()
42
+ };
43
+ }
44
+ formatMemoryMetrics(metrics) {
45
+ return `Heap: ${metrics.heapUsedMB.toFixed(2)}/${metrics.heapTotalMB.toFixed(2)}MB (${metrics.heapUsedPercentage.toFixed(1)}%) | RSS: ${metrics.rssMB.toFixed(2)}MB`;
46
+ }
47
+ checkMemoryUsage(metrics) {
48
+ const { heapUsedPercentage } = metrics;
49
+ if (heapUsedPercentage >= this.criticalThreshold) {
50
+ this.logger.error((0, colors_1.red)(`CRITICAL: Memory usage at ${heapUsedPercentage.toFixed(1)}% - ${this.formatMemoryMetrics(metrics)}`));
51
+ // Attempt garbage collection if available and enabled
52
+ if (this.enableGarbageCollection && this.gcAvailable) {
53
+ this.logger.warn('Triggering garbage collection due to critical memory usage');
54
+ global.gc();
55
+ // Log memory after GC
56
+ setTimeout(() => {
57
+ const afterGcMetrics = this.getMemoryMetrics();
58
+ this.logger.log(`Memory after GC: ${this.formatMemoryMetrics(afterGcMetrics)}`);
59
+ }, 100);
60
+ }
61
+ }
62
+ else if (heapUsedPercentage >= this.warningThreshold) {
63
+ this.logger.warn((0, colors_1.yellow)(`WARNING: Memory usage at ${heapUsedPercentage.toFixed(1)}% - ${this.formatMemoryMetrics(metrics)}`));
64
+ }
65
+ }
66
+ startMonitoring() {
67
+ if (this.intervalTimer) {
68
+ return; // Already monitoring
69
+ }
70
+ // Initial check
71
+ const initialMetrics = this.getMemoryMetrics();
72
+ this.logger.log(`Memory monitoring started - ${this.formatMemoryMetrics(initialMetrics)}`);
73
+ this.intervalTimer = setInterval(() => {
74
+ const metrics = this.getMemoryMetrics();
75
+ this.lastMetrics = metrics;
76
+ this.checkMemoryUsage(metrics);
77
+ }, this.monitorInterval);
78
+ // Ensure timer doesn't prevent process from exiting
79
+ this.intervalTimer.unref();
80
+ }
81
+ stopMonitoring() {
82
+ if (this.intervalTimer) {
83
+ clearInterval(this.intervalTimer);
84
+ this.intervalTimer = undefined;
85
+ this.logger.log('Memory monitoring stopped');
86
+ }
87
+ }
88
+ middleware() {
89
+ return (_req, res, next) => {
90
+ const metrics = this.getMemoryMetrics();
91
+ this.lastMetrics = metrics;
92
+ // Add memory metrics to response headers if enabled
93
+ if (this.addHeaders) {
94
+ res.setHeader('X-Memory-Heap-Used-MB', metrics.heapUsedMB.toFixed(2));
95
+ res.setHeader('X-Memory-Heap-Total-MB', metrics.heapTotalMB.toFixed(2));
96
+ res.setHeader('X-Memory-Heap-Used-Percent', metrics.heapUsedPercentage.toFixed(1));
97
+ res.setHeader('X-Memory-RSS-MB', metrics.rssMB.toFixed(2));
98
+ }
99
+ // Check memory usage on each request
100
+ this.checkMemoryUsage(metrics);
101
+ next();
102
+ };
103
+ }
104
+ getLastMetrics() {
105
+ return this.lastMetrics;
106
+ }
107
+ }
108
+ // Track if we've already added process listeners
109
+ let processListenersAdded = false;
110
+ // Factory function to create memory monitor middleware
111
+ function createMemoryMonitorMiddleware(options) {
112
+ const monitor = new MemoryMonitor(options);
113
+ // Start background monitoring
114
+ monitor.startMonitoring();
115
+ // Handle graceful shutdown - only add listeners once globally
116
+ if (!processListenersAdded && process.env.NODE_ENV !== 'test') {
117
+ processListenersAdded = true;
118
+ const cleanup = () => {
119
+ monitor.stopMonitoring();
120
+ };
121
+ process.once('SIGTERM', cleanup);
122
+ process.once('SIGINT', cleanup);
123
+ }
124
+ return {
125
+ middleware: monitor.middleware(),
126
+ monitor
127
+ };
128
+ }
129
+ // Convenience middleware function for simple usage
130
+ function memoryMonitorMiddleware(options) {
131
+ const { middleware } = createMemoryMonitorMiddleware(options);
132
+ return middleware;
133
+ }
134
+ //# sourceMappingURL=memoryMonitor.middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memoryMonitor.middleware.js","sourceRoot":"","sources":["../../../src/server/middleware/memoryMonitor.middleware.ts"],"names":[],"mappings":";AAAA,0EAA0E;;AA0J1E,sEAyBC;AAGD,0DAGC;AArLD,yCAA0C;AAmB1C,MAAM,aAAa;IACT,MAAM,CAAc;IACpB,gBAAgB,CAAQ;IACxB,iBAAiB,CAAQ;IACzB,eAAe,CAAQ;IACvB,uBAAuB,CAAS;IAChC,UAAU,CAAS;IACnB,aAAa,CAAiB;IAC9B,WAAW,CAAgB;IAC3B,WAAW,CAAS;IAE5B,YAAY,UAAgC,EAAE;QAC5C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAA;QACvC,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,EAAE,CAAA;QACtD,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,IAAI,EAAE,CAAA;QACxD,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,KAAK,CAAA,CAAC,qBAAqB;QAC7E,IAAI,CAAC,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,KAAK,KAAK,CAAA;QACxE,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,KAAK,KAAK,CAAA;QAE9C,2CAA2C;QAC3C,IAAI,CAAC,WAAW,GAAG,OAAO,MAAM,CAAC,EAAE,KAAK,UAAU,CAAA;QAElD,IAAI,IAAI,CAAC,uBAAuB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAA;QACpG,CAAC;IACH,CAAC;IAEO,gBAAgB;QACtB,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,EAAE,CAAA;QACtC,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;QACpD,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;QACtD,MAAM,kBAAkB,GAAG,CAAC,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,GAAG,GAAG,CAAA;QACzE,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;QAE1C,OAAO;YACL,UAAU;YACV,WAAW;YACX,kBAAkB;YAClB,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAA;IACH,CAAC;IAEO,mBAAmB,CAAC,OAAsB;QAChD,OAAO,SAAS,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;IACtK,CAAC;IAEO,gBAAgB,CAAC,OAAsB;QAC7C,MAAM,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAA;QAEtC,IAAI,kBAAkB,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,IAAA,YAAG,EAAC,6BAA6B,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC,CAC1G,CAAA;YAED,sDAAsD;YACtD,IAAI,IAAI,CAAC,uBAAuB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAA;gBAC9E,MAAM,CAAC,EAAG,EAAE,CAAA;gBAEZ,sBAAsB;gBACtB,UAAU,CAAC,GAAG,EAAE;oBACd,MAAM,cAAc,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAA;oBAC9C,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,oBAAoB,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,EAAE,CAC/D,CAAA;gBACH,CAAC,EAAE,GAAG,CAAC,CAAA;YACT,CAAC;QACH,CAAC;aAAM,IAAI,kBAAkB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACvD,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,IAAA,eAAM,EAAC,4BAA4B,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC,CAC5G,CAAA;QACH,CAAC;IACH,CAAC;IAEM,eAAe;QACpB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,OAAM,CAAC,qBAAqB;QAC9B,CAAC;QAED,gBAAgB;QAChB,MAAM,cAAc,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAA;QAC9C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,+BAA+B,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,EAAE,CAAC,CAAA;QAE1F,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;YACpC,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAA;YACvC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAA;YAC1B,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;QAChC,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;QAExB,oDAAoD;QACpD,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAA;IAC5B,CAAC;IAEM,cAAc;QACnB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YACjC,IAAI,CAAC,aAAa,GAAG,SAAS,CAAA;YAC9B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAA;QAC9C,CAAC;IACH,CAAC;IAEM,UAAU;QACf,OAAO,CAAC,IAAa,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;YAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAA;YACvC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAA;YAE1B,oDAAoD;YACpD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,GAAG,CAAC,SAAS,CAAC,uBAAuB,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;gBACrE,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;gBACvE,GAAG,CAAC,SAAS,CAAC,4BAA4B,EAAE,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;gBAClF,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;YAC5D,CAAC;YAED,qCAAqC;YACrC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;YAE9B,IAAI,EAAE,CAAA;QACR,CAAC,CAAA;IACH,CAAC;IAEM,cAAc;QACnB,OAAO,IAAI,CAAC,WAAW,CAAA;IACzB,CAAC;CACF;AAED,iDAAiD;AACjD,IAAI,qBAAqB,GAAG,KAAK,CAAA;AAEjC,uDAAuD;AACvD,SAAgB,6BAA6B,CAAC,OAA8B;IAI1E,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,CAAA;IAE1C,8BAA8B;IAC9B,OAAO,CAAC,eAAe,EAAE,CAAA;IAEzB,8DAA8D;IAC9D,IAAI,CAAC,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;QAC9D,qBAAqB,GAAG,IAAI,CAAA;QAE5B,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,OAAO,CAAC,cAAc,EAAE,CAAA;QAC1B,CAAC,CAAA;QAED,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QAChC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IACjC,CAAC;IAED,OAAO;QACL,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE;QAChC,OAAO;KACR,CAAA;AACH,CAAC;AAED,mDAAmD;AACnD,SAAgB,uBAAuB,CAAC,OAA8B;IACpE,MAAM,EAAE,UAAU,EAAE,GAAG,6BAA6B,CAAC,OAAO,CAAC,CAAA;IAC7D,OAAO,UAAU,CAAA;AACnB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { Request, Response, NextFunction } from 'express';
2
+ import type { HttpError, HttpErrorData } from '@goatlab/js-utils';
3
+ /**
4
+ * Sanitize error messages for production environment
5
+ * Prevents leaking sensitive information in error responses
6
+ */
7
+ export declare function sanitizeErrorForProduction(error: HttpError<HttpErrorData>): HttpError<HttpErrorData>;
8
+ /**
9
+ * Production-ready error handler middleware
10
+ * Ensures no sensitive information is leaked in error responses
11
+ */
12
+ export declare function productionErrorHandler(): (err: any, req: Request, res: Response, next: NextFunction) => void;
13
+ /**
14
+ * Async error wrapper to catch errors in async route handlers
15
+ */
16
+ export declare function asyncErrorHandler(fn: Function): (req: Request, res: Response, next: NextFunction) => void;