@designofadecade/server 4.0.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 (84) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/LICENSE +21 -0
  3. package/README.md +297 -0
  4. package/dist/client/ApiClient.d.ts +121 -0
  5. package/dist/client/ApiClient.d.ts.map +1 -0
  6. package/dist/client/ApiClient.js +289 -0
  7. package/dist/client/ApiClient.js.map +1 -0
  8. package/dist/context/Context.d.ts +71 -0
  9. package/dist/context/Context.d.ts.map +1 -0
  10. package/dist/context/Context.js +81 -0
  11. package/dist/context/Context.js.map +1 -0
  12. package/dist/docs/OpenApiGenerator.d.ts +135 -0
  13. package/dist/docs/OpenApiGenerator.d.ts.map +1 -0
  14. package/dist/docs/OpenApiGenerator.js +165 -0
  15. package/dist/docs/OpenApiGenerator.js.map +1 -0
  16. package/dist/events/Events.d.ts +52 -0
  17. package/dist/events/Events.d.ts.map +1 -0
  18. package/dist/events/Events.js +70 -0
  19. package/dist/events/Events.js.map +1 -0
  20. package/dist/events/EventsManager.d.ts +46 -0
  21. package/dist/events/EventsManager.d.ts.map +1 -0
  22. package/dist/events/EventsManager.js +137 -0
  23. package/dist/events/EventsManager.js.map +1 -0
  24. package/dist/index.d.ts +32 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +38 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/local/Local.d.ts +83 -0
  29. package/dist/local/Local.d.ts.map +1 -0
  30. package/dist/local/Local.js +114 -0
  31. package/dist/local/Local.js.map +1 -0
  32. package/dist/logger/Logger.d.ts +365 -0
  33. package/dist/logger/Logger.d.ts.map +1 -0
  34. package/dist/logger/Logger.js +582 -0
  35. package/dist/logger/Logger.js.map +1 -0
  36. package/dist/middleware/RequestLogger.d.ts +62 -0
  37. package/dist/middleware/RequestLogger.d.ts.map +1 -0
  38. package/dist/middleware/RequestLogger.js +71 -0
  39. package/dist/middleware/RequestLogger.js.map +1 -0
  40. package/dist/notifications/Slack.d.ts +19 -0
  41. package/dist/notifications/Slack.d.ts.map +1 -0
  42. package/dist/notifications/Slack.js +55 -0
  43. package/dist/notifications/Slack.js.map +1 -0
  44. package/dist/router/RouteError.d.ts +21 -0
  45. package/dist/router/RouteError.d.ts.map +1 -0
  46. package/dist/router/RouteError.js +31 -0
  47. package/dist/router/RouteError.js.map +1 -0
  48. package/dist/router/Router.d.ts +66 -0
  49. package/dist/router/Router.d.ts.map +1 -0
  50. package/dist/router/Router.js +327 -0
  51. package/dist/router/Router.js.map +1 -0
  52. package/dist/router/Routes.d.ts +30 -0
  53. package/dist/router/Routes.d.ts.map +1 -0
  54. package/dist/router/Routes.js +52 -0
  55. package/dist/router/Routes.js.map +1 -0
  56. package/dist/router/StaticFileHandler.d.ts +44 -0
  57. package/dist/router/StaticFileHandler.d.ts.map +1 -0
  58. package/dist/router/StaticFileHandler.js +148 -0
  59. package/dist/router/StaticFileHandler.js.map +1 -0
  60. package/dist/sanitizer/HtmlSanitizer.d.ts +306 -0
  61. package/dist/sanitizer/HtmlSanitizer.d.ts.map +1 -0
  62. package/dist/sanitizer/HtmlSanitizer.js +808 -0
  63. package/dist/sanitizer/HtmlSanitizer.js.map +1 -0
  64. package/dist/server/Server.d.ts +28 -0
  65. package/dist/server/Server.d.ts.map +1 -0
  66. package/dist/server/Server.js +95 -0
  67. package/dist/server/Server.js.map +1 -0
  68. package/dist/state/AppState.d.ts +64 -0
  69. package/dist/state/AppState.d.ts.map +1 -0
  70. package/dist/state/AppState.js +89 -0
  71. package/dist/state/AppState.js.map +1 -0
  72. package/dist/utils/HtmlRenderer.d.ts +6 -0
  73. package/dist/utils/HtmlRenderer.d.ts.map +1 -0
  74. package/dist/utils/HtmlRenderer.js +128 -0
  75. package/dist/utils/HtmlRenderer.js.map +1 -0
  76. package/dist/websocket/WebSocketMessageFormatter.d.ts +40 -0
  77. package/dist/websocket/WebSocketMessageFormatter.d.ts.map +1 -0
  78. package/dist/websocket/WebSocketMessageFormatter.js +99 -0
  79. package/dist/websocket/WebSocketMessageFormatter.js.map +1 -0
  80. package/dist/websocket/WebSocketServer.d.ts +14 -0
  81. package/dist/websocket/WebSocketServer.d.ts.map +1 -0
  82. package/dist/websocket/WebSocketServer.js +138 -0
  83. package/dist/websocket/WebSocketServer.js.map +1 -0
  84. package/package.json +97 -0
@@ -0,0 +1,582 @@
1
+ /**
2
+ * Structured logger for AWS Lambda with CloudWatch Logs
3
+ *
4
+ * @module Logger
5
+ * @description Provides JSON-formatted logging for better CloudWatch Insights queries
6
+ * with configurable log levels and structured context support. Automatically captures
7
+ * AWS Lambda request IDs and properly serializes Error objects.
8
+ *
9
+ * Best Practices for CloudWatch Alarms:
10
+ * - Add a `code` field to log entries (e.g., 'DB_CONNECTION_ERROR') for alarm filtering
11
+ * - Add a `source` field to track where logs originated (e.g., 'UserService.login')
12
+ * - Use consistent error codes across your application
13
+ * - Create CloudWatch metric filters based on specific codes
14
+ *
15
+ * Features:
16
+ * ✅ JSON-formatted logs for CloudWatch Insights
17
+ * ✅ Automatic error serialization (message, name, stack)
18
+ * ✅ AWS Lambda context (request ID, X-Ray trace ID, function name, version)
19
+ * ✅ Environment metadata (stage/environment tracking)
20
+ * ✅ Cold start detection (Lambda performance monitoring)
21
+ * ✅ Sensitive data redaction (passwords, tokens, API keys, etc.)
22
+ * ✅ Performance timing helpers (duration tracking)
23
+ * ✅ Error codes for alarm creation
24
+ * ✅ Source tracking for debugging
25
+ *
26
+ * @example
27
+ * import { logger } from './Logger';
28
+ *
29
+ * logger.info('User action completed', {
30
+ * source: 'UserController.login',
31
+ * userId: '123',
32
+ * action: 'login'
33
+ * });
34
+ *
35
+ * // Error objects are automatically serialized with message, name, and stack
36
+ * // Use 'code' field for CloudWatch alarms
37
+ * try {
38
+ * await riskyOperation();
39
+ * } catch (err) {
40
+ * logger.error('Operation failed', {
41
+ * code: 'PAYMENT_PROCESSING_ERROR', // For CloudWatch alarm filtering
42
+ * source: 'PaymentService.processPayment', // For debugging
43
+ * error: err
44
+ * });
45
+ * }
46
+ *
47
+ * // Performance timing
48
+ * const timer = logger.startTimer();
49
+ * await expensiveOperation();
50
+ * timer.end('expensiveOperation', { source: 'MyService.process' });
51
+ *
52
+ * // Sensitive data is automatically redacted
53
+ * logger.info('User logged in', {
54
+ * username: 'john',
55
+ * password: 'secret123' // Automatically redacted as [REDACTED]
56
+ * });
57
+ */
58
+ /**
59
+ * Log level enumeration
60
+ * Lower values indicate higher priority
61
+ *
62
+ * Log Level Guidelines:
63
+ *
64
+ * ERROR (0) - Critical failures requiring immediate attention
65
+ * - Application crashes or unrecoverable errors
66
+ * - Failed database connections or critical service failures
67
+ * - Data corruption or loss scenarios
68
+ * - Security violations or authentication failures
69
+ * - Use when: The application cannot continue normal operation
70
+ *
71
+ * WARN (1) - Potentially harmful situations that don't stop execution
72
+ * - Deprecated API usage or configuration issues
73
+ * - Rate limiting being approached
74
+ * - Retryable failures (e.g., temporary network issues)
75
+ * - Resource constraints (low memory, disk space)
76
+ * - Use when: Something unexpected happened but the app can continue
77
+ *
78
+ * INFO (2) - Informational messages highlighting application progress
79
+ * - Application startup/shutdown events
80
+ * - Successful business operations (user login, order placed)
81
+ * - Configuration loaded successfully
82
+ * - API request/response summaries
83
+ * - Use when: Tracking normal application flow and important milestones
84
+ *
85
+ * DEBUG (3) - Detailed diagnostic information for troubleshooting
86
+ * - Variable values and state changes
87
+ * - Cache hits/misses
88
+ * - Detailed request/response payloads
89
+ * - Function entry/exit points
90
+ * - Use when: Debugging issues in development or production
91
+ */
92
+ export var LogLevel;
93
+ (function (LogLevel) {
94
+ LogLevel[LogLevel["ERROR"] = 0] = "ERROR";
95
+ LogLevel[LogLevel["WARN"] = 1] = "WARN";
96
+ LogLevel[LogLevel["INFO"] = 2] = "INFO";
97
+ LogLevel[LogLevel["DEBUG"] = 3] = "DEBUG";
98
+ })(LogLevel || (LogLevel = {}));
99
+ /**
100
+ * Mapping of string log levels to numeric values
101
+ */
102
+ const LOG_LEVEL_MAP = {
103
+ ERROR: LogLevel.ERROR,
104
+ WARN: LogLevel.WARN,
105
+ INFO: LogLevel.INFO,
106
+ DEBUG: LogLevel.DEBUG,
107
+ };
108
+ /**
109
+ * Structured logger class for AWS Lambda with CloudWatch Logs integration
110
+ *
111
+ * @class Logger
112
+ * @description Outputs JSON-formatted logs for optimal CloudWatch Insights querying.
113
+ * Log level can be configured via LOG_LEVEL environment variable.
114
+ *
115
+ * @example
116
+ * const logger = new Logger();
117
+ * logger.info('Processing started', { requestId: '12345' });
118
+ * logger.error('Failed to process', { error: 'Connection timeout', retries: 3 });
119
+ */
120
+ export class Logger {
121
+ level;
122
+ // Sensitive field patterns - more specific to avoid false positives
123
+ sensitiveKeys = [
124
+ 'password',
125
+ 'passwd',
126
+ 'pwd',
127
+ 'token',
128
+ 'accesstoken',
129
+ 'refreshtoken',
130
+ 'bearertoken',
131
+ 'apikey',
132
+ 'api_key',
133
+ 'secret',
134
+ 'secretkey',
135
+ 'clientsecret',
136
+ 'authorization',
137
+ 'auth',
138
+ 'cookie',
139
+ 'session',
140
+ 'sessionid',
141
+ 'creditcard',
142
+ 'cardnumber',
143
+ 'cvv',
144
+ 'ccv',
145
+ 'ssn',
146
+ 'socialsecurity',
147
+ 'privatekey',
148
+ 'private_key',
149
+ ];
150
+ isColdStart = true; // Track Lambda cold starts
151
+ maxLogSize = 256000; // CloudWatch limit is 256KB per log event
152
+ /**
153
+ * Creates a new Logger instance
154
+ * Reads LOG_LEVEL from environment variable (defaults to INFO)
155
+ */
156
+ constructor() {
157
+ const envLevel = (process.env.LOG_LEVEL?.toUpperCase() || 'INFO');
158
+ this.level = LOG_LEVEL_MAP[envLevel] ?? LogLevel.INFO;
159
+ }
160
+ /**
161
+ * Determines if a message at the given level should be logged
162
+ *
163
+ * @param level - The log level to check
164
+ * @returns True if the message should be logged
165
+ * @private
166
+ */
167
+ shouldLog(level) {
168
+ return level <= this.level;
169
+ }
170
+ /**
171
+ * Serializes an Error object for CloudWatch
172
+ * Extracts message, name, and stack trace for better CloudWatch Insights queries
173
+ *
174
+ * @param error - The error to serialize
175
+ * @returns Serialized error object
176
+ * @private
177
+ */
178
+ serializeError(error) {
179
+ return {
180
+ message: error.message,
181
+ name: error.name,
182
+ stack: error.stack,
183
+ };
184
+ }
185
+ /**
186
+ * Redacts sensitive data from log context for security/compliance
187
+ * Handles circular references and prevents infinite recursion
188
+ *
189
+ * @param obj - The object to redact
190
+ * @param seen - WeakSet to track visited objects (prevents circular references)
191
+ * @param depth - Current recursion depth (prevents stack overflow)
192
+ * @returns Redacted object
193
+ * @private
194
+ */
195
+ redactSensitiveData(obj, seen = new WeakSet(), depth = 0) {
196
+ // Prevent infinite recursion
197
+ if (depth > 10)
198
+ return '[MAX_DEPTH]';
199
+ if (obj === null || obj === undefined)
200
+ return obj;
201
+ // Handle primitives and special types before object check
202
+ if (typeof obj !== 'object') {
203
+ // Handle Symbol (convert to string for JSON compatibility)
204
+ if (typeof obj === 'symbol') {
205
+ return obj.toString();
206
+ }
207
+ // Handle BigInt (convert to string for JSON compatibility)
208
+ if (typeof obj === 'bigint') {
209
+ return obj.toString() + 'n';
210
+ }
211
+ // Handle functions
212
+ if (typeof obj === 'function') {
213
+ return '[Function]';
214
+ }
215
+ return obj;
216
+ }
217
+ // Handle circular references
218
+ if (seen.has(obj)) {
219
+ return '[CIRCULAR]';
220
+ }
221
+ if (Array.isArray(obj)) {
222
+ return obj.map((item) => this.redactSensitiveData(item, seen, depth + 1));
223
+ }
224
+ // Mark this object as seen
225
+ seen.add(obj);
226
+ const redacted = {};
227
+ for (const [key, value] of Object.entries(obj)) {
228
+ const lowerKey = key.toLowerCase();
229
+ const isSensitive = this.sensitiveKeys.some((sensitive) => lowerKey.includes(sensitive.toLowerCase()));
230
+ if (isSensitive) {
231
+ redacted[key] = '[REDACTED]';
232
+ }
233
+ else {
234
+ // Always recursively process values to handle BigInt, Symbol, Function, etc.
235
+ redacted[key] = this.redactSensitiveData(value, seen, depth + 1);
236
+ }
237
+ }
238
+ return redacted;
239
+ }
240
+ /**
241
+ * Processes context to handle special types (Errors) for CloudWatch compatibility
242
+ *
243
+ * @param context - The context object to process
244
+ * @returns Processed context
245
+ * @private
246
+ */
247
+ processContext(context) {
248
+ if (!context)
249
+ return {};
250
+ const processed = {};
251
+ for (const [key, value] of Object.entries(context)) {
252
+ if (value instanceof Error) {
253
+ // Serialize Error objects properly for CloudWatch
254
+ processed[key] = this.serializeError(value);
255
+ }
256
+ else {
257
+ processed[key] = value;
258
+ }
259
+ }
260
+ // Redact sensitive data
261
+ return this.redactSensitiveData(processed);
262
+ }
263
+ /**
264
+ * Safely stringifies an object, handling BigInt, circular refs, and other edge cases
265
+ *
266
+ * @param obj - The object to stringify
267
+ * @returns JSON string
268
+ * @private
269
+ */
270
+ safeStringify(obj) {
271
+ return JSON.stringify(obj, (_key, value) => {
272
+ // Handle BigInt (convert to string with 'n' suffix)
273
+ if (typeof value === 'bigint') {
274
+ return value.toString() + 'n';
275
+ }
276
+ // Handle Symbol (convert to string)
277
+ if (typeof value === 'symbol') {
278
+ return value.toString();
279
+ }
280
+ // Handle functions (skip them)
281
+ if (typeof value === 'function') {
282
+ return '[Function]';
283
+ }
284
+ return value;
285
+ });
286
+ }
287
+ /**
288
+ * Outputs a structured log entry to stdout optimized for CloudWatch Logs
289
+ * Handles CloudWatch's 256KB log size limit
290
+ *
291
+ * @param level - The log level string
292
+ * @param message - The log message
293
+ * @param context - Additional context data to include in the log entry
294
+ * @private
295
+ */
296
+ log(level, message, context) {
297
+ try {
298
+ const processedContext = this.processContext(context);
299
+ const logEntry = {
300
+ timestamp: new Date().toISOString(),
301
+ level,
302
+ message,
303
+ // AWS Lambda context
304
+ ...(process.env.AWS_REQUEST_ID && { requestId: process.env.AWS_REQUEST_ID }),
305
+ ...(process.env._X_AMZN_TRACE_ID && { traceId: process.env._X_AMZN_TRACE_ID }),
306
+ ...(process.env.AWS_LAMBDA_FUNCTION_NAME && {
307
+ functionName: process.env.AWS_LAMBDA_FUNCTION_NAME,
308
+ }),
309
+ ...(process.env.AWS_LAMBDA_FUNCTION_VERSION && {
310
+ functionVersion: process.env.AWS_LAMBDA_FUNCTION_VERSION,
311
+ }),
312
+ // Environment metadata
313
+ ...(process.env.ENVIRONMENT && { environment: process.env.ENVIRONMENT }),
314
+ ...(process.env.STAGE && { environment: process.env.STAGE }),
315
+ // Cold start tracking
316
+ ...(this.isColdStart && level !== 'DEBUG' && { coldStart: true }),
317
+ ...processedContext,
318
+ };
319
+ // Mark cold start as false after first log
320
+ if (this.isColdStart) {
321
+ this.isColdStart = false;
322
+ }
323
+ let logString = this.safeStringify(logEntry);
324
+ // CloudWatch has a 256KB limit per log event
325
+ if (logString.length > this.maxLogSize) {
326
+ const truncated = {
327
+ ...logEntry,
328
+ _truncated: true,
329
+ _originalSize: logString.length,
330
+ message: logEntry.message.substring(0, 1000),
331
+ };
332
+ // Remove large fields if still too big
333
+ const truncatedRecord = truncated;
334
+ if (truncatedRecord.error && typeof truncatedRecord.error === 'object') {
335
+ delete truncatedRecord.error.stack;
336
+ }
337
+ logString = this.safeStringify(truncated);
338
+ // If still too large, just log basic info
339
+ if (logString.length > this.maxLogSize) {
340
+ logString = this.safeStringify({
341
+ timestamp: logEntry.timestamp,
342
+ level: logEntry.level,
343
+ message: 'Log too large to output',
344
+ _truncated: true,
345
+ _originalSize: logString.length,
346
+ });
347
+ }
348
+ }
349
+ console.log(logString);
350
+ }
351
+ catch (err) {
352
+ // Fallback to plain console.log if JSON serialization fails
353
+ try {
354
+ console.log(JSON.stringify({
355
+ timestamp: new Date().toISOString(),
356
+ level,
357
+ message,
358
+ _error: 'Failed to serialize log entry',
359
+ _errorMessage: err instanceof Error ? err.message : String(err),
360
+ }));
361
+ }
362
+ catch {
363
+ // Last resort fallback
364
+ console.log(`[${level}] ${message}`);
365
+ }
366
+ }
367
+ }
368
+ /**
369
+ * Logs an error message
370
+ *
371
+ * @param message - The error message
372
+ * @param context - Additional context data (error details, stack traces, etc.)
373
+ *
374
+ * @example
375
+ * // Pass Error objects directly - they'll be serialized automatically
376
+ * try {
377
+ * await connectToDatabase();
378
+ * } catch (err) {
379
+ * logger.error('Database connection failed', {
380
+ * code: 'DB_CONNECTION_ERROR', // For CloudWatch alarms
381
+ * source: 'DatabaseService.connect', // Track where error occurred
382
+ * error: err, // Error object is automatically serialized
383
+ * database: 'users',
384
+ * retry: 3
385
+ * });
386
+ * }
387
+ *
388
+ * @example
389
+ * // CloudWatch Alarm can filter on code field:
390
+ * // fields @timestamp, message, code
391
+ * // | filter code = "DB_CONNECTION_ERROR"
392
+ */
393
+ error(message, context) {
394
+ if (this.shouldLog(LogLevel.ERROR)) {
395
+ this.log('ERROR', message, context);
396
+ }
397
+ }
398
+ /**
399
+ * Logs a warning message
400
+ *
401
+ * @param message - The warning message
402
+ * @param context - Additional context data
403
+ *
404
+ * @example
405
+ * logger.warn('Rate limit approaching', {
406
+ * code: 'RATE_LIMIT_WARNING',
407
+ * source: 'ApiGateway.checkRateLimit',
408
+ * current: 95,
409
+ * limit: 100,
410
+ * timeWindow: '1m'
411
+ * });
412
+ */
413
+ warn(message, context) {
414
+ if (this.shouldLog(LogLevel.WARN)) {
415
+ this.log('WARN', message, context);
416
+ }
417
+ }
418
+ /**
419
+ * Logs an informational message
420
+ *
421
+ * @param message - The info message
422
+ * @param context - Additional context data
423
+ *
424
+ * @example
425
+ * logger.info('Request processed successfully', {
426
+ * source: 'ApiHandler.processRequest',
427
+ * requestId: 'req-123',
428
+ * duration: 245,
429
+ * statusCode: 200
430
+ * });
431
+ */
432
+ info(message, context) {
433
+ if (this.shouldLog(LogLevel.INFO)) {
434
+ this.log('INFO', message, context);
435
+ }
436
+ }
437
+ /**
438
+ * Logs a debug message
439
+ *
440
+ * @param message - The debug message
441
+ * @param context - Additional context data
442
+ *
443
+ * @example
444
+ * logger.debug('Cache lookup', {
445
+ * key: 'user:123',
446
+ * hit: true,
447
+ * ttl: 3600
448
+ * });
449
+ */
450
+ debug(message, context) {
451
+ if (this.shouldLog(LogLevel.DEBUG)) {
452
+ this.log('DEBUG', message, context);
453
+ }
454
+ }
455
+ /**
456
+ * Gets the current log level
457
+ *
458
+ * @returns The current log level
459
+ */
460
+ getLevel() {
461
+ return this.level;
462
+ }
463
+ /**
464
+ * Gets the current log level as a string
465
+ *
466
+ * @returns The current log level string
467
+ */
468
+ getLevelString() {
469
+ const entry = Object.entries(LogLevel).find(([, val]) => val === this.level);
470
+ return entry?.[0] || 'INFO';
471
+ }
472
+ /**
473
+ * Logs operation performance metrics
474
+ * Helper method for tracking duration of operations
475
+ *
476
+ * @param operation - Name of the operation
477
+ * @param durationMs - Duration in milliseconds
478
+ * @param context - Additional context data
479
+ *
480
+ * @example
481
+ * const start = Date.now();
482
+ * await processPayment();
483
+ * logger.performance('processPayment', Date.now() - start, {
484
+ * source: 'PaymentService.process',
485
+ * paymentId: '12345',
486
+ * amount: 99.99
487
+ * });
488
+ *
489
+ * @example
490
+ * // CloudWatch Insights - Track slow operations:
491
+ * // fields @timestamp, message, duration, source
492
+ * // | filter duration > 1000
493
+ * // | sort duration desc
494
+ */
495
+ performance(operation, durationMs, context) {
496
+ this.info(`Operation completed: ${operation}`, {
497
+ duration: durationMs,
498
+ ...context,
499
+ });
500
+ }
501
+ /**
502
+ * Creates a performance timing wrapper
503
+ * Returns start function that returns end function for measuring duration
504
+ *
505
+ * @returns Object with start method that returns end method
506
+ *
507
+ * @example
508
+ * const timer = logger.startTimer();
509
+ * await someAsyncOperation();
510
+ * timer.end('someAsyncOperation', { source: 'MyService.method', userId: '123' });
511
+ */
512
+ startTimer() {
513
+ const startTime = Date.now();
514
+ return {
515
+ /**
516
+ * Ends the timer and logs performance
517
+ * @param operation - Name of the operation
518
+ * @param context - Additional context
519
+ */
520
+ end: (operation, context) => {
521
+ this.performance(operation, Date.now() - startTime, context);
522
+ },
523
+ };
524
+ }
525
+ }
526
+ /**
527
+ * Singleton logger instance
528
+ * Use this for all logging throughout the application
529
+ *
530
+ * Environment Variables:
531
+ * - LOG_LEVEL: Set log level (ERROR, WARN, INFO, DEBUG) - defaults to INFO
532
+ * - ENVIRONMENT or STAGE: Environment name (dev/staging/prod) - auto-included in logs
533
+ * - AWS_REQUEST_ID: Lambda request ID - auto-captured
534
+ * - _X_AMZN_TRACE_ID: X-Ray trace ID - auto-captured
535
+ * - AWS_LAMBDA_FUNCTION_NAME: Function name - auto-captured
536
+ * - AWS_LAMBDA_FUNCTION_VERSION: Function version - auto-captured
537
+ *
538
+ * @example
539
+ * import { logger } from './Logger';
540
+ *
541
+ * logger.info('Application started', { source: 'App.main' });
542
+ *
543
+ * logger.error('Failed to load config', {
544
+ * code: 'CONFIG_LOAD_ERROR',
545
+ * source: 'ConfigService.load',
546
+ * error: err
547
+ * });
548
+ *
549
+ * // Performance tracking
550
+ * const timer = logger.startTimer();
551
+ * await processData();
552
+ * timer.end('processData', { source: 'DataProcessor.process', recordCount: 100 });
553
+ *
554
+ * // CloudWatch Insights query examples:
555
+ *
556
+ * // Find specific error codes:
557
+ * // fields @timestamp, message, code, source
558
+ * // | filter code = "DB_CONNECTION_ERROR"
559
+ * // | sort @timestamp desc
560
+ *
561
+ * // Track errors by source:
562
+ * // fields @timestamp, message, source
563
+ * // | filter source like /UserService/
564
+ * // | stats count() by source
565
+ *
566
+ * // Monitor cold starts:
567
+ * // fields @timestamp, message, coldStart, duration
568
+ * // | filter coldStart = true
569
+ * // | stats count() as coldStartCount
570
+ *
571
+ * // Track slow operations:
572
+ * // fields @timestamp, message, duration, source
573
+ * // | filter duration > 1000
574
+ * // | sort duration desc
575
+ * // | limit 20
576
+ */
577
+ export const logger = new Logger();
578
+ /**
579
+ * Default export for convenience
580
+ */
581
+ export default logger;
582
+ //# sourceMappingURL=Logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Logger.js","sourceRoot":"","sources":["../../src/logger/Logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Request logging middleware for API routes
3
+ * Extends the base Logger with HTTP-specific context
4
+ *
5
+ * @module RequestLogger
6
+ */
7
+ interface RequestLoggerInterface {
8
+ info: (message: string, context?: Record<string, any>) => void;
9
+ error: (message: string, context?: Record<string, any>) => void;
10
+ warn: (message: string, context?: Record<string, any>) => void;
11
+ debug: (message: string, context?: Record<string, any>) => void;
12
+ }
13
+ interface RequestEvent {
14
+ requestContext?: {
15
+ requestId?: string;
16
+ http?: {
17
+ method: string;
18
+ path: string;
19
+ };
20
+ identity?: {
21
+ sourceIp?: string;
22
+ };
23
+ };
24
+ httpMethod?: string;
25
+ path?: string;
26
+ headers?: Record<string, any>;
27
+ body?: string;
28
+ queryStringParameters?: Record<string, any>;
29
+ pathParameters?: Record<string, any>;
30
+ }
31
+ interface ResponseObject {
32
+ statusCode: number;
33
+ [key: string]: any;
34
+ }
35
+ /**
36
+ * Creates a request-scoped logger with HTTP context
37
+ *
38
+ * @param {Object} request - AWS Lambda event or custom request object
39
+ * @param {string} request.requestContext.requestId - Request ID
40
+ * @param {string} request.httpMethod - HTTP method
41
+ * @param {string} request.path - Request path
42
+ * @returns {Object} Logger with request context
43
+ */
44
+ export declare function createRequestLogger(event: RequestEvent): RequestLoggerInterface;
45
+ /**
46
+ * Middleware to automatically log incoming requests
47
+ *
48
+ * @param {Object} event - AWS Lambda event
49
+ * @returns {void}
50
+ */
51
+ export declare function logRequest(event: RequestEvent): void;
52
+ /**
53
+ * Middleware to log outgoing responses
54
+ *
55
+ * @param {Object} event - AWS Lambda event
56
+ * @param {Object} response - API response
57
+ * @param {number} durationMs - Request duration in milliseconds
58
+ * @returns {void}
59
+ */
60
+ export declare function logResponse(event: RequestEvent, response: ResponseObject, durationMs: number): void;
61
+ export {};
62
+ //# sourceMappingURL=RequestLogger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequestLogger.d.ts","sourceRoot":"","sources":["../../src/middleware/RequestLogger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,UAAU,sBAAsB;IAC9B,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IAC/D,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IAChE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IAC/D,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;CACjE;AAED,UAAU,YAAY;IACpB,cAAc,CAAC,EAAE;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE;YACL,MAAM,EAAE,MAAM,CAAC;YACf,IAAI,EAAE,MAAM,CAAC;SACd,CAAC;QACF,QAAQ,CAAC,EAAE;YACT,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACtC;AAED,UAAU,cAAc;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,sBAAsB,CAuB/E;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAQpD;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,MAAM,GACjB,IAAI,CAUN"}