@creator.co/wapi 1.8.8 → 1.9.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 +0 -1
- package/dist/package-lock.json +2597 -925
- package/dist/package.json +16 -12
- package/dist/src/API/Request.d.ts +10 -0
- package/dist/src/API/Request.js +43 -3
- package/dist/src/API/Request.js.map +1 -1
- package/dist/src/Server/Router.d.ts +6 -0
- package/dist/src/Server/Router.js.map +1 -1
- package/dist/src/Server/lib/ContainerServer.js +52 -5
- package/dist/src/Server/lib/ContainerServer.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +16 -12
- package/src/API/Request.ts +56 -2
- package/src/Server/Router.ts +6 -0
- package/src/Server/lib/ContainerServer.ts +54 -5
- package/tests/AwsSdkTest.utils.ts +13 -0
- package/tests/Config/Config.test.ts +42 -32
- package/tests/Config/EnvironmentVar.test.ts +85 -73
- package/tests/Crypto/Crypto.test.ts +24 -16
- package/tests/Mailer/Mailer.test.ts +13 -9
- package/tests/Publisher/Publisher.test.ts +22 -16
package/dist/package.json
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@creator.co/wapi",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public",
|
|
10
|
+
"registry": "https://registry.npmjs.org/"
|
|
11
|
+
},
|
|
8
12
|
"scripts": {
|
|
9
13
|
"build": "task build",
|
|
10
14
|
"clean": "task clean",
|
|
@@ -19,14 +23,14 @@
|
|
|
19
23
|
"author": "",
|
|
20
24
|
"license": "ISC",
|
|
21
25
|
"dependencies": {
|
|
22
|
-
"@aws-sdk/client-dynamodb": "^3.
|
|
23
|
-
"@aws-sdk/client-kms": "^3.
|
|
24
|
-
"@aws-sdk/client-secrets-manager": "^3.
|
|
25
|
-
"@aws-sdk/client-sesv2": "^3.
|
|
26
|
-
"@aws-sdk/client-sns": "^3.
|
|
27
|
-
"@aws-sdk/client-ssm": "^3.
|
|
28
|
-
"@aws-sdk/credential-provider-node": "^3.
|
|
29
|
-
"@aws-sdk/util-dynamodb": "^3.
|
|
26
|
+
"@aws-sdk/client-dynamodb": "^3.730.0",
|
|
27
|
+
"@aws-sdk/client-kms": "^3.730.0",
|
|
28
|
+
"@aws-sdk/client-secrets-manager": "^3.730.0",
|
|
29
|
+
"@aws-sdk/client-sesv2": "^3.730.0",
|
|
30
|
+
"@aws-sdk/client-sns": "^3.730.0",
|
|
31
|
+
"@aws-sdk/client-ssm": "^3.730.0",
|
|
32
|
+
"@aws-sdk/credential-provider-node": "^3.730.0",
|
|
33
|
+
"@aws-sdk/util-dynamodb": "^3.730.0",
|
|
30
34
|
"@smithy/node-http-handler": "^3.2.2",
|
|
31
35
|
"@types/email-templates": "^10.0.4",
|
|
32
36
|
"@types/nodemailer": "^6.4.10",
|
|
@@ -42,12 +46,12 @@
|
|
|
42
46
|
"jsonwebtoken": "^9.0.2",
|
|
43
47
|
"knex": "^3.0.1",
|
|
44
48
|
"knex-stringcase": "^1.4.6",
|
|
45
|
-
"kysely": "^0.
|
|
49
|
+
"kysely": "^0.28.14",
|
|
46
50
|
"node-cache": "^5.1.2",
|
|
47
|
-
"nodemailer": "^
|
|
51
|
+
"nodemailer": "^8.0.4",
|
|
48
52
|
"object-hash": "^3.0.0",
|
|
49
53
|
"parse-duration": "^2.1.3",
|
|
50
|
-
"path-to-regexp": "^8.
|
|
54
|
+
"path-to-regexp": "^8.4.0",
|
|
51
55
|
"pg": "^8.11.3",
|
|
52
56
|
"rate-limit-redis": "^4.2.0",
|
|
53
57
|
"redis": "^4.7.0",
|
|
@@ -8,6 +8,10 @@ import Logger from '../Logger/Logger.js';
|
|
|
8
8
|
* @template QueryParamsType - The type of the query parameters for the request.
|
|
9
9
|
*/
|
|
10
10
|
export default class Request<InputType, PathParamsType, QueryParamsType> {
|
|
11
|
+
/**
|
|
12
|
+
* Default paths to exclude from verbose logging (health checks, monitoring, etc.)
|
|
13
|
+
*/
|
|
14
|
+
private static readonly DEFAULT_NO_LOG_PATHS;
|
|
11
15
|
/**
|
|
12
16
|
* Represents an API Gateway event for a request.
|
|
13
17
|
* @type {APIGatewayEvent}
|
|
@@ -25,6 +29,12 @@ export default class Request<InputType, PathParamsType, QueryParamsType> {
|
|
|
25
29
|
* @returns None
|
|
26
30
|
*/
|
|
27
31
|
constructor(requestEvent: APIGatewayEvent, context: Context, logger: Logger);
|
|
32
|
+
/**
|
|
33
|
+
* Checks if the path is a health check or monitoring endpoint that should not be logged verbosely.
|
|
34
|
+
* @param {string} path - The request path
|
|
35
|
+
* @returns {boolean} - True if it's a health/monitoring endpoint
|
|
36
|
+
*/
|
|
37
|
+
private isHealthOrMonitoringPath;
|
|
28
38
|
/**
|
|
29
39
|
* Checks if the specified query parameter exists and has a valid value.
|
|
30
40
|
* @param {keyof QueryParamsType} paramName - The name of the query parameter to check.
|
package/dist/src/API/Request.js
CHANGED
|
@@ -6,7 +6,7 @@ import Utils from '../Util/Utils.js';
|
|
|
6
6
|
* @template PathParamsType - The type of the path parameters for the request.
|
|
7
7
|
* @template QueryParamsType - The type of the query parameters for the request.
|
|
8
8
|
*/
|
|
9
|
-
|
|
9
|
+
class Request {
|
|
10
10
|
/**
|
|
11
11
|
* Constructs a new instance of the class.
|
|
12
12
|
* @param {APIGatewayEvent} requestEvent - The API Gateway event object.
|
|
@@ -15,10 +15,33 @@ export default class Request {
|
|
|
15
15
|
* @returns None
|
|
16
16
|
*/
|
|
17
17
|
constructor(requestEvent, context, logger) {
|
|
18
|
+
var _a, _b, _c, _d;
|
|
18
19
|
this.requestEvent = requestEvent;
|
|
19
20
|
this.context = context;
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
// Skip verbose logging for health check and monitoring endpoints
|
|
22
|
+
const path = requestEvent.path || '';
|
|
23
|
+
const isHealthCheck = this.isHealthOrMonitoringPath(path);
|
|
24
|
+
if (!isHealthCheck) {
|
|
25
|
+
// Only log essential info for actual business requests (not full event object)
|
|
26
|
+
logger.debug('Request:', Object.assign({ method: requestEvent.httpMethod, path, requestId: context.awsRequestId, sourceIp: (_b = (_a = requestEvent.requestContext) === null || _a === void 0 ? void 0 : _a.identity) === null || _b === void 0 ? void 0 : _b.sourceIp, userAgent: ((_c = requestEvent.headers) === null || _c === void 0 ? void 0 : _c['User-Agent']) || ((_d = requestEvent.headers) === null || _d === void 0 ? void 0 : _d['user-agent']) }, (requestEvent.queryStringParameters &&
|
|
27
|
+
Object.keys(requestEvent.queryStringParameters).length > 0
|
|
28
|
+
? { queryParams: Object.keys(requestEvent.queryStringParameters) }
|
|
29
|
+
: {})));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Checks if the path is a health check or monitoring endpoint that should not be logged verbosely.
|
|
34
|
+
* @param {string} path - The request path
|
|
35
|
+
* @returns {boolean} - True if it's a health/monitoring endpoint
|
|
36
|
+
*/
|
|
37
|
+
isHealthOrMonitoringPath(path) {
|
|
38
|
+
// Check environment variable for custom no-log paths
|
|
39
|
+
const envNoLogPaths = process.env.NO_LOG_PATHS;
|
|
40
|
+
const customPaths = envNoLogPaths ? envNoLogPaths.split(',').map(p => p.trim()) : [];
|
|
41
|
+
// Combine default and custom paths
|
|
42
|
+
const ignoredPaths = [...Request.DEFAULT_NO_LOG_PATHS, ...customPaths];
|
|
43
|
+
const lowerPath = path.toLowerCase();
|
|
44
|
+
return ignoredPaths.some(ignored => lowerPath === ignored || lowerPath.startsWith(ignored + '/'));
|
|
22
45
|
}
|
|
23
46
|
/**
|
|
24
47
|
* Checks if the specified query parameter exists and has a valid value.
|
|
@@ -167,6 +190,23 @@ export default class Request {
|
|
|
167
190
|
});
|
|
168
191
|
}
|
|
169
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Default paths to exclude from verbose logging (health checks, monitoring, etc.)
|
|
195
|
+
*/
|
|
196
|
+
Request.DEFAULT_NO_LOG_PATHS = [
|
|
197
|
+
'/health',
|
|
198
|
+
'/healthcheck',
|
|
199
|
+
'/health-check',
|
|
200
|
+
'/ping',
|
|
201
|
+
'/status',
|
|
202
|
+
'/ready',
|
|
203
|
+
'/readiness',
|
|
204
|
+
'/liveness',
|
|
205
|
+
'/metrics',
|
|
206
|
+
'/_health',
|
|
207
|
+
'/',
|
|
208
|
+
];
|
|
209
|
+
export default Request;
|
|
170
210
|
/**
|
|
171
211
|
* Enum representing the HTTP methods.
|
|
172
212
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Request.js","sourceRoot":"","sources":["../../../src/API/Request.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,kBAAkB,CAAA;AAEpC;;;;;;GAMG;AACH,
|
|
1
|
+
{"version":3,"file":"Request.js","sourceRoot":"","sources":["../../../src/API/Request.ts"],"names":[],"mappings":"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"}
|
|
@@ -160,6 +160,12 @@ export type RouterConfig = TransactionConfig & {
|
|
|
160
160
|
* @type {string | undefined}
|
|
161
161
|
*/
|
|
162
162
|
healthCheckRoute?: string;
|
|
163
|
+
/**
|
|
164
|
+
* Paths that should not be logged (e.g., health checks, metrics).
|
|
165
|
+
* These requests will still be processed but won't create verbose logs.
|
|
166
|
+
* @type {string[] | undefined}
|
|
167
|
+
*/
|
|
168
|
+
noLogPaths?: string[];
|
|
163
169
|
/**
|
|
164
170
|
* Global rate limiting configuration for all routes.
|
|
165
171
|
* Individual routes can override this with their own rateLimit config.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Router.js","sourceRoot":"","sources":["../../../src/Server/Router.ts"],"names":[],"mappings":"AAMA,OAAO,eAAe,MAAM,0BAA0B,CAAA;AACtD,OAAO,MAAM,MAAM,iBAAiB,CAAA;AAQpC,OAAO,KAAK,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"Router.js","sourceRoot":"","sources":["../../../src/Server/Router.ts"],"names":[],"mappings":"AAMA,OAAO,eAAe,MAAM,0BAA0B,CAAA;AACtD,OAAO,MAAM,MAAM,iBAAiB,CAAA;AAQpC,OAAO,KAAK,MAAM,kBAAkB,CAAA;AAqMpC;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,MAAM;IAUzB;;;;OAIG;IACH,YAAY,MAAoB;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,CAAA;IACrF,CAAC;IAED;;;OAGG;IACI,SAAS;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAA;IAChC,CAAC;IAED;;;OAGG;IACK,WAAW;QACjB,OAAO,KAAK,CAAC,qBAAqB,EAAE,CAAA;IACtC,CAAC;CACF"}
|
|
@@ -39,7 +39,15 @@ export default class ContainerServer extends Server {
|
|
|
39
39
|
*/
|
|
40
40
|
start() {
|
|
41
41
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
-
|
|
42
|
+
try {
|
|
43
|
+
console.log('[ContainerServer] Starting server...');
|
|
44
|
+
yield this.proxy.load();
|
|
45
|
+
console.log('[ContainerServer] Server started successfully');
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error('[ContainerServer] Failed to start server:', error);
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
43
51
|
});
|
|
44
52
|
}
|
|
45
53
|
/**
|
|
@@ -49,7 +57,16 @@ export default class ContainerServer extends Server {
|
|
|
49
57
|
*/
|
|
50
58
|
stop(err) {
|
|
51
59
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
-
|
|
60
|
+
try {
|
|
61
|
+
console.log('[ContainerServer] Stopping server...');
|
|
62
|
+
yield this.proxy.unload(err);
|
|
63
|
+
console.log('[ContainerServer] Server stopped successfully');
|
|
64
|
+
}
|
|
65
|
+
catch (stopError) {
|
|
66
|
+
console.error('[ContainerServer] Error during server shutdown:', stopError);
|
|
67
|
+
// Force exit if graceful shutdown fails
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
53
70
|
});
|
|
54
71
|
}
|
|
55
72
|
/**
|
|
@@ -58,9 +75,39 @@ export default class ContainerServer extends Server {
|
|
|
58
75
|
* @returns None
|
|
59
76
|
*/
|
|
60
77
|
listenProcessEvents() {
|
|
61
|
-
//
|
|
62
|
-
process.on('unhandledRejection',
|
|
63
|
-
|
|
78
|
+
// Handle unhandled promise rejections
|
|
79
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
80
|
+
console.error('[ContainerServer] CRITICAL: Unhandled Promise Rejection');
|
|
81
|
+
console.error('[ContainerServer] Reason:', reason);
|
|
82
|
+
if (reason instanceof Error) {
|
|
83
|
+
console.error('[ContainerServer] Stack:', reason.stack);
|
|
84
|
+
}
|
|
85
|
+
console.error('[ContainerServer] Promise:', promise);
|
|
86
|
+
console.error('[ContainerServer] Shutting down server due to unhandled rejection...');
|
|
87
|
+
this.stop(reason);
|
|
88
|
+
});
|
|
89
|
+
// Handle uncaught exceptions
|
|
90
|
+
process.on('uncaughtException', error => {
|
|
91
|
+
console.error('[ContainerServer] CRITICAL: Uncaught Exception');
|
|
92
|
+
console.error('[ContainerServer] Error:', error);
|
|
93
|
+
console.error('[ContainerServer] Stack:', error.stack);
|
|
94
|
+
console.error('[ContainerServer] Shutting down server due to uncaught exception...');
|
|
95
|
+
this.stop(error);
|
|
96
|
+
});
|
|
97
|
+
// Handle SIGINT (Ctrl+C)
|
|
98
|
+
process.on('SIGINT', () => {
|
|
99
|
+
console.log('[ContainerServer] SIGINT received, shutting down gracefully...');
|
|
100
|
+
this.stop();
|
|
101
|
+
});
|
|
102
|
+
// Handle SIGTERM (Docker/ECS stop)
|
|
103
|
+
process.on('SIGTERM', () => {
|
|
104
|
+
console.log('[ContainerServer] SIGTERM received, shutting down gracefully...');
|
|
105
|
+
this.stop();
|
|
106
|
+
});
|
|
107
|
+
// Log when process is about to exit
|
|
108
|
+
process.on('exit', code => {
|
|
109
|
+
console.log(`[ContainerServer] 🚪 Process exiting with code: ${code}`);
|
|
110
|
+
});
|
|
64
111
|
}
|
|
65
112
|
}
|
|
66
113
|
//# sourceMappingURL=ContainerServer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContainerServer.js","sourceRoot":"","sources":["../../../../src/Server/lib/ContainerServer.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,KAAK,MAAM,sBAAsB,CAAA;AACxC,OAAO,MAAM,MAAM,aAAa,CAAA;AAGhC;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,MAAM;IAQjD;;;;OAIG;IACH,YAAY,MAAoB;QAC9B,KAAK,CAAC,MAAM,CAAC,CAAA;QACb,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACrE,IAAI,CAAC,mBAAmB,EAAE,CAAA;IAC5B,CAAC;IAED;;;OAGG;IACI,SAAS;QACd,sBAAsB;QACtB,IAAI,CAAC,KAAK,EAAE,CAAA;QACZ,yCAAyC;QACzC,OAAO,GAAG,EAAE,GAAE,CAAC,CAAA;IACjB,CAAC;IAED;;;OAGG;IACU,KAAK;;YAChB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"ContainerServer.js","sourceRoot":"","sources":["../../../../src/Server/lib/ContainerServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../index.ts","../src/
|
|
1
|
+
{"root":["../index.ts","../src/globals.ts","../src/api/request.ts","../src/api/response.ts","../src/baseevent/dynamotransaction.ts","../src/baseevent/eventprocessor.ts","../src/baseevent/process.ts","../src/baseevent/transaction.ts","../src/cache/redis.ts","../src/cache/types.ts","../src/config/configuration.ts","../src/config/environmentvar.ts","../src/crypto/crypto.ts","../src/crypto/jwt.ts","../src/database/database.ts","../src/database/databasemanager.ts","../src/database/databasetransaction.ts","../src/database/index.ts","../src/database/types.ts","../src/database/integrations/dynamo/dynamodatabase.ts","../src/database/integrations/knex/knexdatabase.ts","../src/database/integrations/knex/knextransaction.ts","../src/database/integrations/kysely/kyselydatabase.ts","../src/database/integrations/kysely/kyselytransaction.ts","../src/database/integrations/pgsql/postgresdatabase.ts","../src/database/integrations/pgsql/postgrestransaction.ts","../src/logger/logger.ts","../src/mailer/mailer.ts","../src/publisher/publisher.ts","../src/server/routeresolver.ts","../src/server/router.ts","../src/server/lib/containerserver.ts","../src/server/lib/server.ts","../src/server/lib/container/generichandler.ts","../src/server/lib/container/generichandlerevent.ts","../src/server/lib/container/healthhandler.ts","../src/server/lib/container/proxy.ts","../src/server/lib/container/utils.ts","../src/util/asyncsingleton.ts","../src/util/utils.ts","../src/validation/validator.ts","../package-lock.json","../package.json"],"version":"5.6.2"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@creator.co/wapi",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public",
|
|
10
|
+
"registry": "https://registry.npmjs.org/"
|
|
11
|
+
},
|
|
8
12
|
"scripts": {
|
|
9
13
|
"build": "task build",
|
|
10
14
|
"clean": "task clean",
|
|
@@ -19,14 +23,14 @@
|
|
|
19
23
|
"author": "",
|
|
20
24
|
"license": "ISC",
|
|
21
25
|
"dependencies": {
|
|
22
|
-
"@aws-sdk/client-dynamodb": "^3.
|
|
23
|
-
"@aws-sdk/client-kms": "^3.
|
|
24
|
-
"@aws-sdk/client-secrets-manager": "^3.
|
|
25
|
-
"@aws-sdk/client-sesv2": "^3.
|
|
26
|
-
"@aws-sdk/client-sns": "^3.
|
|
27
|
-
"@aws-sdk/client-ssm": "^3.
|
|
28
|
-
"@aws-sdk/credential-provider-node": "^3.
|
|
29
|
-
"@aws-sdk/util-dynamodb": "^3.
|
|
26
|
+
"@aws-sdk/client-dynamodb": "^3.730.0",
|
|
27
|
+
"@aws-sdk/client-kms": "^3.730.0",
|
|
28
|
+
"@aws-sdk/client-secrets-manager": "^3.730.0",
|
|
29
|
+
"@aws-sdk/client-sesv2": "^3.730.0",
|
|
30
|
+
"@aws-sdk/client-sns": "^3.730.0",
|
|
31
|
+
"@aws-sdk/client-ssm": "^3.730.0",
|
|
32
|
+
"@aws-sdk/credential-provider-node": "^3.730.0",
|
|
33
|
+
"@aws-sdk/util-dynamodb": "^3.730.0",
|
|
30
34
|
"@smithy/node-http-handler": "^3.2.2",
|
|
31
35
|
"@types/email-templates": "^10.0.4",
|
|
32
36
|
"@types/nodemailer": "^6.4.10",
|
|
@@ -42,12 +46,12 @@
|
|
|
42
46
|
"jsonwebtoken": "^9.0.2",
|
|
43
47
|
"knex": "^3.0.1",
|
|
44
48
|
"knex-stringcase": "^1.4.6",
|
|
45
|
-
"kysely": "^0.
|
|
49
|
+
"kysely": "^0.28.14",
|
|
46
50
|
"node-cache": "^5.1.2",
|
|
47
|
-
"nodemailer": "^
|
|
51
|
+
"nodemailer": "^8.0.4",
|
|
48
52
|
"object-hash": "^3.0.0",
|
|
49
53
|
"parse-duration": "^2.1.3",
|
|
50
|
-
"path-to-regexp": "^8.
|
|
54
|
+
"path-to-regexp": "^8.4.0",
|
|
51
55
|
"pg": "^8.11.3",
|
|
52
56
|
"rate-limit-redis": "^4.2.0",
|
|
53
57
|
"redis": "^4.7.0",
|
package/src/API/Request.ts
CHANGED
|
@@ -11,6 +11,23 @@ import Utils from '../Util/Utils.js'
|
|
|
11
11
|
* @template QueryParamsType - The type of the query parameters for the request.
|
|
12
12
|
*/
|
|
13
13
|
export default class Request<InputType, PathParamsType, QueryParamsType> {
|
|
14
|
+
/**
|
|
15
|
+
* Default paths to exclude from verbose logging (health checks, monitoring, etc.)
|
|
16
|
+
*/
|
|
17
|
+
private static readonly DEFAULT_NO_LOG_PATHS = [
|
|
18
|
+
'/health',
|
|
19
|
+
'/healthcheck',
|
|
20
|
+
'/health-check',
|
|
21
|
+
'/ping',
|
|
22
|
+
'/status',
|
|
23
|
+
'/ready',
|
|
24
|
+
'/readiness',
|
|
25
|
+
'/liveness',
|
|
26
|
+
'/metrics',
|
|
27
|
+
'/_health',
|
|
28
|
+
'/',
|
|
29
|
+
]
|
|
30
|
+
|
|
14
31
|
/**
|
|
15
32
|
* Represents an API Gateway event for a request.
|
|
16
33
|
* @type {APIGatewayEvent}
|
|
@@ -31,8 +48,45 @@ export default class Request<InputType, PathParamsType, QueryParamsType> {
|
|
|
31
48
|
constructor(requestEvent: APIGatewayEvent, context: Context, logger: Logger) {
|
|
32
49
|
this.requestEvent = requestEvent
|
|
33
50
|
this.context = context
|
|
34
|
-
|
|
35
|
-
|
|
51
|
+
|
|
52
|
+
// Skip verbose logging for health check and monitoring endpoints
|
|
53
|
+
const path = requestEvent.path || ''
|
|
54
|
+
const isHealthCheck = this.isHealthOrMonitoringPath(path)
|
|
55
|
+
|
|
56
|
+
if (!isHealthCheck) {
|
|
57
|
+
// Only log essential info for actual business requests (not full event object)
|
|
58
|
+
logger.debug('Request:', {
|
|
59
|
+
method: requestEvent.httpMethod,
|
|
60
|
+
path,
|
|
61
|
+
requestId: context.awsRequestId,
|
|
62
|
+
sourceIp: requestEvent.requestContext?.identity?.sourceIp,
|
|
63
|
+
userAgent: requestEvent.headers?.['User-Agent'] || requestEvent.headers?.['user-agent'],
|
|
64
|
+
// Only log if query params exist
|
|
65
|
+
...(requestEvent.queryStringParameters &&
|
|
66
|
+
Object.keys(requestEvent.queryStringParameters).length > 0
|
|
67
|
+
? { queryParams: Object.keys(requestEvent.queryStringParameters) }
|
|
68
|
+
: {}),
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Checks if the path is a health check or monitoring endpoint that should not be logged verbosely.
|
|
75
|
+
* @param {string} path - The request path
|
|
76
|
+
* @returns {boolean} - True if it's a health/monitoring endpoint
|
|
77
|
+
*/
|
|
78
|
+
private isHealthOrMonitoringPath(path: string): boolean {
|
|
79
|
+
// Check environment variable for custom no-log paths
|
|
80
|
+
const envNoLogPaths = process.env.NO_LOG_PATHS
|
|
81
|
+
const customPaths = envNoLogPaths ? envNoLogPaths.split(',').map(p => p.trim()) : []
|
|
82
|
+
|
|
83
|
+
// Combine default and custom paths
|
|
84
|
+
const ignoredPaths = [...Request.DEFAULT_NO_LOG_PATHS, ...customPaths]
|
|
85
|
+
|
|
86
|
+
const lowerPath = path.toLowerCase()
|
|
87
|
+
return ignoredPaths.some(
|
|
88
|
+
ignored => lowerPath === ignored || lowerPath.startsWith(ignored + '/')
|
|
89
|
+
)
|
|
36
90
|
}
|
|
37
91
|
|
|
38
92
|
/**
|
package/src/Server/Router.ts
CHANGED
|
@@ -195,6 +195,12 @@ export type RouterConfig = TransactionConfig & {
|
|
|
195
195
|
* @type {string | undefined}
|
|
196
196
|
*/
|
|
197
197
|
healthCheckRoute?: string
|
|
198
|
+
/**
|
|
199
|
+
* Paths that should not be logged (e.g., health checks, metrics).
|
|
200
|
+
* These requests will still be processed but won't create verbose logs.
|
|
201
|
+
* @type {string[] | undefined}
|
|
202
|
+
*/
|
|
203
|
+
noLogPaths?: string[]
|
|
198
204
|
/**
|
|
199
205
|
* Global rate limiting configuration for all routes.
|
|
200
206
|
* Individual routes can override this with their own rateLimit config.
|
|
@@ -40,7 +40,14 @@ export default class ContainerServer extends Server {
|
|
|
40
40
|
* @returns {Promise<void>} - A promise that resolves when the proxy is loaded.
|
|
41
41
|
*/
|
|
42
42
|
public async start() {
|
|
43
|
-
|
|
43
|
+
try {
|
|
44
|
+
console.log('[ContainerServer] Starting server...')
|
|
45
|
+
await this.proxy.load()
|
|
46
|
+
console.log('[ContainerServer] Server started successfully')
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error('[ContainerServer] Failed to start server:', error)
|
|
49
|
+
throw error
|
|
50
|
+
}
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
/**
|
|
@@ -49,7 +56,15 @@ export default class ContainerServer extends Server {
|
|
|
49
56
|
* @returns {Promise<void>} - A promise that resolves once the proxy is unloaded.
|
|
50
57
|
*/
|
|
51
58
|
public async stop(err?: any) {
|
|
52
|
-
|
|
59
|
+
try {
|
|
60
|
+
console.log('[ContainerServer] Stopping server...')
|
|
61
|
+
await this.proxy.unload(err)
|
|
62
|
+
console.log('[ContainerServer] Server stopped successfully')
|
|
63
|
+
} catch (stopError) {
|
|
64
|
+
console.error('[ContainerServer] Error during server shutdown:', stopError)
|
|
65
|
+
// Force exit if graceful shutdown fails
|
|
66
|
+
process.exit(1)
|
|
67
|
+
}
|
|
53
68
|
}
|
|
54
69
|
|
|
55
70
|
/**
|
|
@@ -58,8 +73,42 @@ export default class ContainerServer extends Server {
|
|
|
58
73
|
* @returns None
|
|
59
74
|
*/
|
|
60
75
|
private listenProcessEvents() {
|
|
61
|
-
//
|
|
62
|
-
process.on('unhandledRejection',
|
|
63
|
-
|
|
76
|
+
// Handle unhandled promise rejections
|
|
77
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
78
|
+
console.error('[ContainerServer] CRITICAL: Unhandled Promise Rejection')
|
|
79
|
+
console.error('[ContainerServer] Reason:', reason)
|
|
80
|
+
if (reason instanceof Error) {
|
|
81
|
+
console.error('[ContainerServer] Stack:', reason.stack)
|
|
82
|
+
}
|
|
83
|
+
console.error('[ContainerServer] Promise:', promise)
|
|
84
|
+
console.error('[ContainerServer] Shutting down server due to unhandled rejection...')
|
|
85
|
+
this.stop(reason)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
// Handle uncaught exceptions
|
|
89
|
+
process.on('uncaughtException', error => {
|
|
90
|
+
console.error('[ContainerServer] CRITICAL: Uncaught Exception')
|
|
91
|
+
console.error('[ContainerServer] Error:', error)
|
|
92
|
+
console.error('[ContainerServer] Stack:', error.stack)
|
|
93
|
+
console.error('[ContainerServer] Shutting down server due to uncaught exception...')
|
|
94
|
+
this.stop(error)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
// Handle SIGINT (Ctrl+C)
|
|
98
|
+
process.on('SIGINT', () => {
|
|
99
|
+
console.log('[ContainerServer] SIGINT received, shutting down gracefully...')
|
|
100
|
+
this.stop()
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
// Handle SIGTERM (Docker/ECS stop)
|
|
104
|
+
process.on('SIGTERM', () => {
|
|
105
|
+
console.log('[ContainerServer] SIGTERM received, shutting down gracefully...')
|
|
106
|
+
this.stop()
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
// Log when process is about to exit
|
|
110
|
+
process.on('exit', code => {
|
|
111
|
+
console.log(`[ContainerServer] 🚪 Process exiting with code: ${code}`)
|
|
112
|
+
})
|
|
64
113
|
}
|
|
65
114
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { mockClient } from 'aws-sdk-client-mock'
|
|
2
|
+
|
|
3
|
+
export function mockAwsClient<TClient>(client: TClient) {
|
|
4
|
+
return mockClient(client as any) as any
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function mockAwsCommand<TCommand>(command: TCommand) {
|
|
8
|
+
return command as any
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function mockAwsResult<TResult>(result: TResult) {
|
|
12
|
+
return result as any
|
|
13
|
+
}
|