@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,71 @@
1
+ /**
2
+ * Request logging middleware for API routes
3
+ * Extends the base Logger with HTTP-specific context
4
+ *
5
+ * @module RequestLogger
6
+ */
7
+ import { logger } from '../logger/Logger.js';
8
+ /**
9
+ * Creates a request-scoped logger with HTTP context
10
+ *
11
+ * @param {Object} request - AWS Lambda event or custom request object
12
+ * @param {string} request.requestContext.requestId - Request ID
13
+ * @param {string} request.httpMethod - HTTP method
14
+ * @param {string} request.path - Request path
15
+ * @returns {Object} Logger with request context
16
+ */
17
+ export function createRequestLogger(event) {
18
+ const requestContext = {
19
+ requestId: event.requestContext?.requestId || 'unknown',
20
+ method: event.httpMethod || event.requestContext?.http?.method,
21
+ path: event.path || event.requestContext?.http?.path,
22
+ sourceIp: event.requestContext?.identity?.sourceIp,
23
+ userAgent: event.headers?.['user-agent'],
24
+ };
25
+ return {
26
+ info: (message, context = {}) => {
27
+ logger.info(message, { ...requestContext, ...context });
28
+ },
29
+ error: (message, context = {}) => {
30
+ logger.error(message, { ...requestContext, ...context });
31
+ },
32
+ warn: (message, context = {}) => {
33
+ logger.warn(message, { ...requestContext, ...context });
34
+ },
35
+ debug: (message, context = {}) => {
36
+ logger.debug(message, { ...requestContext, ...context });
37
+ },
38
+ };
39
+ }
40
+ /**
41
+ * Middleware to automatically log incoming requests
42
+ *
43
+ * @param {Object} event - AWS Lambda event
44
+ * @returns {void}
45
+ */
46
+ export function logRequest(event) {
47
+ const requestLogger = createRequestLogger(event);
48
+ requestLogger.info('Incoming request', {
49
+ body: event.body ? JSON.parse(event.body) : undefined,
50
+ queryParams: event.queryStringParameters,
51
+ pathParams: event.pathParameters,
52
+ });
53
+ }
54
+ /**
55
+ * Middleware to log outgoing responses
56
+ *
57
+ * @param {Object} event - AWS Lambda event
58
+ * @param {Object} response - API response
59
+ * @param {number} durationMs - Request duration in milliseconds
60
+ * @returns {void}
61
+ */
62
+ export function logResponse(event, response, durationMs) {
63
+ const requestLogger = createRequestLogger(event);
64
+ const level = response.statusCode >= 400 ? 'error' : 'info';
65
+ requestLogger[level]('Request completed', {
66
+ statusCode: response.statusCode,
67
+ durationMs,
68
+ success: response.statusCode < 400,
69
+ });
70
+ }
71
+ //# sourceMappingURL=RequestLogger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequestLogger.js","sourceRoot":"","sources":["../../src/middleware/RequestLogger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAiC7C;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAmB;IACrD,MAAM,cAAc,GAAG;QACrB,SAAS,EAAE,KAAK,CAAC,cAAc,EAAE,SAAS,IAAI,SAAS;QACvD,MAAM,EAAE,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,MAAM;QAC9D,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI;QACpD,QAAQ,EAAE,KAAK,CAAC,cAAc,EAAE,QAAQ,EAAE,QAAQ;QAClD,SAAS,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,YAAY,CAAC;KACzC,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,CAAC,OAAe,EAAE,UAA+B,EAAE,EAAE,EAAE;YAC3D,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,KAAK,EAAE,CAAC,OAAe,EAAE,UAA+B,EAAE,EAAE,EAAE;YAC5D,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,EAAE,CAAC,OAAe,EAAE,UAA+B,EAAE,EAAE,EAAE;YAC3D,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,KAAK,EAAE,CAAC,OAAe,EAAE,UAA+B,EAAE,EAAE,EAAE;YAC5D,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;QAC3D,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,KAAmB;IAC5C,MAAM,aAAa,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAEjD,aAAa,CAAC,IAAI,CAAC,kBAAkB,EAAE;QACrC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;QACrD,WAAW,EAAE,KAAK,CAAC,qBAAqB;QACxC,UAAU,EAAE,KAAK,CAAC,cAAc;KACjC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CACzB,KAAmB,EACnB,QAAwB,EACxB,UAAkB;IAElB,MAAM,aAAa,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAEjD,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAE5D,aAAa,CAAC,KAAK,CAAC,CAAC,mBAAmB,EAAE;QACxC,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,UAAU;QACV,OAAO,EAAE,QAAQ,CAAC,UAAU,GAAG,GAAG;KACnC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,19 @@
1
+ export default class Slack {
2
+ static sendNotification(webhookUrl: string, message: string, options?: Record<string, any>): Promise<{
3
+ success: boolean;
4
+ status: number;
5
+ }>;
6
+ static sendMessage({ webhookUrl, text, channel, username, icon_emoji, blocks, attachments }: {
7
+ webhookUrl: string;
8
+ text?: string;
9
+ channel?: string;
10
+ username?: string;
11
+ icon_emoji?: string;
12
+ blocks?: any[];
13
+ attachments?: any[];
14
+ }): Promise<{
15
+ success: boolean;
16
+ status: number;
17
+ }>;
18
+ }
19
+ //# sourceMappingURL=Slack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slack.d.ts","sourceRoot":"","sources":["../../src/notifications/Slack.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,OAAO,OAAO,KAAK;WAET,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;WA0BvI,WAAW,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE;QAC/F,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;QACf,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC;KACvB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAmCpD"}
@@ -0,0 +1,55 @@
1
+ export default class Slack {
2
+ static async sendNotification(webhookUrl, message, options = {}) {
3
+ const payload = {
4
+ text: message,
5
+ ...options
6
+ };
7
+ try {
8
+ const response = await fetch(webhookUrl, {
9
+ method: 'POST',
10
+ headers: {
11
+ 'Content-Type': 'application/json',
12
+ },
13
+ body: JSON.stringify(payload)
14
+ });
15
+ if (!response.ok) {
16
+ throw new Error(`Slack API returned ${response.status}: ${response.statusText}`);
17
+ }
18
+ return { success: true, status: response.status };
19
+ }
20
+ catch (error) {
21
+ throw new Error(`Failed to send Slack notification: ${error.message}`, { cause: error });
22
+ }
23
+ }
24
+ static async sendMessage({ webhookUrl, text, channel, username, icon_emoji, blocks, attachments }) {
25
+ const payload = {
26
+ ...(text && { text }),
27
+ ...(channel && { channel }),
28
+ ...(username && { username }),
29
+ ...(icon_emoji && { icon_emoji }),
30
+ ...(blocks && { blocks }),
31
+ ...(attachments && { attachments })
32
+ };
33
+ if (!text && !blocks && !attachments) {
34
+ throw new Error('Slack message must include text, blocks, or attachments');
35
+ }
36
+ try {
37
+ const response = await fetch(webhookUrl, {
38
+ method: 'POST',
39
+ headers: {
40
+ 'Content-Type': 'application/json',
41
+ },
42
+ body: JSON.stringify(payload)
43
+ });
44
+ if (!response.ok) {
45
+ const errorText = await response.text();
46
+ throw new Error(`Slack API returned ${response.status}: ${errorText}`);
47
+ }
48
+ return { success: true, status: response.status };
49
+ }
50
+ catch (error) {
51
+ throw new Error(`Failed to send Slack message: ${error.message}`, { cause: error });
52
+ }
53
+ }
54
+ }
55
+ //# sourceMappingURL=Slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slack.js","sourceRoot":"","sources":["../../src/notifications/Slack.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,OAAO,OAAO,KAAK;IAEtB,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,UAAkB,EAAE,OAAe,EAAE,UAA+B,EAAE;QAEhG,MAAM,OAAO,GAAG;YACZ,IAAI,EAAE,OAAO;YACb,GAAG,OAAO;SACb,CAAC;QAEF,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE;gBACrC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACL,cAAc,EAAE,kBAAkB;iBACrC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;aAChC,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YACrF,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;QACtD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,sCAAsC,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7F,CAAC;IACL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAQ9F;QAEG,MAAM,OAAO,GAAwB;YACjC,GAAG,CAAC,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC;YACrB,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;YAC3B,GAAG,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,CAAC;YAC7B,GAAG,CAAC,UAAU,IAAI,EAAE,UAAU,EAAE,CAAC;YACjC,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC;YACzB,GAAG,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,CAAC;SACtC,CAAC;QAEF,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;QAC/E,CAAC;QAED,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE;gBACrC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACL,cAAc,EAAE,kBAAkB;iBACrC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;aAChC,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACf,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACxC,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC,CAAC;YAC3E,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;QACtD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACxF,CAAC;IACL,CAAC;CAEJ"}
@@ -0,0 +1,21 @@
1
+ import type { RouterResponse } from './Router.js';
2
+ /**
3
+ * Route error response utility for creating standardized error responses
4
+ *
5
+ * @class RouteError
6
+ */
7
+ export default class RouteError {
8
+ /**
9
+ * Creates a standardized error response for router handlers
10
+ *
11
+ * @param status - HTTP status code
12
+ * @param error - Error type/category
13
+ * @param message - Optional detailed error message (omitted in production for security)
14
+ * @returns RouterResponse object
15
+ *
16
+ * @example
17
+ * return RouteError.create(404, 'Not Found', 'Route does not exist');
18
+ */
19
+ static create(status: number, error: string, message?: string): RouterResponse;
20
+ }
21
+ //# sourceMappingURL=RouteError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteError.d.ts","sourceRoot":"","sources":["../../src/router/RouteError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,UAAU;IAE3B;;;;;;;;;;OAUG;IACH,MAAM,CAAC,MAAM,CACT,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,GACjB,cAAc;CAapB"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Route error response utility for creating standardized error responses
3
+ *
4
+ * @class RouteError
5
+ */
6
+ export default class RouteError {
7
+ /**
8
+ * Creates a standardized error response for router handlers
9
+ *
10
+ * @param status - HTTP status code
11
+ * @param error - Error type/category
12
+ * @param message - Optional detailed error message (omitted in production for security)
13
+ * @returns RouterResponse object
14
+ *
15
+ * @example
16
+ * return RouteError.create(404, 'Not Found', 'Route does not exist');
17
+ */
18
+ static create(status, error, message) {
19
+ const isDevelopment = process.env.NODE_ENV === 'development';
20
+ return {
21
+ status,
22
+ headers: { 'Content-Type': 'application/json' },
23
+ body: JSON.stringify({
24
+ error,
25
+ ...(isDevelopment && message && { message }),
26
+ statusCode: status
27
+ })
28
+ };
29
+ }
30
+ }
31
+ //# sourceMappingURL=RouteError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteError.js","sourceRoot":"","sources":["../../src/router/RouteError.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,UAAU;IAE3B;;;;;;;;;;OAUG;IACH,MAAM,CAAC,MAAM,CACT,MAAc,EACd,KAAa,EACb,OAAgB;QAEhB,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC;QAE7D,OAAO;YACH,MAAM;YACN,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACjB,KAAK;gBACL,GAAG,CAAC,aAAa,IAAI,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;gBAC5C,UAAU,EAAE,MAAM;aACrB,CAAC;SACL,CAAC;IACN,CAAC;CACJ"}
@@ -0,0 +1,66 @@
1
+ import { IncomingMessage, ServerResponse } from 'http';
2
+ import Context from '../context/Context.js';
3
+ interface LambdaHttpEvent {
4
+ requestContext: {
5
+ http: {
6
+ method: string;
7
+ path: string;
8
+ };
9
+ authorizer?: unknown;
10
+ };
11
+ headers: Record<string, string | string[] | undefined>;
12
+ body?: string | null;
13
+ cookies?: string[];
14
+ queryStringParameters?: Record<string, string>;
15
+ [key: string]: unknown;
16
+ }
17
+ interface RouteRegistration {
18
+ path: string;
19
+ methods: string[];
20
+ pattern: URLPattern;
21
+ handler: (request: RouterRequest) => Promise<RouterResponse>;
22
+ middleware?: RouterMiddleware[];
23
+ }
24
+ export interface RouterRequest {
25
+ path: string;
26
+ method: string;
27
+ body: unknown;
28
+ cookies: Record<string, string>;
29
+ params: Record<string, string>;
30
+ query: Record<string, string>;
31
+ headers: Record<string, string | string[] | undefined>;
32
+ authorizer?: unknown;
33
+ lambdaOptions?: unknown;
34
+ }
35
+ export interface RouterResponse {
36
+ status?: number;
37
+ headers?: Record<string, string>;
38
+ body?: unknown;
39
+ isBase64Encoded?: boolean;
40
+ }
41
+ export interface RouterOptions {
42
+ context?: Context;
43
+ initRoutes?: (new (router: Router, context?: Context) => {
44
+ routerRoutes: RouteRegistration[];
45
+ })[];
46
+ bearerToken?: string | null;
47
+ middleware?: RouterMiddleware[];
48
+ }
49
+ export type RouterMiddleware = (request: RouterRequest) => Promise<RouterResponse | void>;
50
+ export default class Router {
51
+ #private;
52
+ static MethodsWithBody: string[];
53
+ constructor({ context, initRoutes, bearerToken, middleware, }?: RouterOptions);
54
+ lambdaEvent(event: LambdaHttpEvent): Promise<{
55
+ statusCode: number;
56
+ headers?: Record<string, string>;
57
+ body: string;
58
+ isBase64Encoded?: boolean;
59
+ }>;
60
+ nodeJSRequest(req: IncomingMessage, res: ServerResponse, { cors, lambdaOptions }?: {
61
+ cors?: boolean;
62
+ lambdaOptions?: Record<string, unknown>;
63
+ }): Promise<void>;
64
+ }
65
+ export {};
66
+ //# sourceMappingURL=Router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Router.d.ts","sourceRoot":"","sources":["../../src/router/Router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,327 @@
1
+ var _a;
2
+ import { logger } from '../logger/Logger.js';
3
+ import RouteError from './RouteError.js';
4
+ class Router {
5
+ static MethodsWithBody = ['POST', 'PUT', 'PATCH'];
6
+ static #MAX_CACHE_SIZE = 1000;
7
+ static #MAX_BODY_SIZE = 1024 * 1024; // 1MB
8
+ #routes = {
9
+ cache: new Map(),
10
+ static: new Map(),
11
+ dynamic: new Map(),
12
+ };
13
+ #bearerToken = null;
14
+ #globalMiddleware = [];
15
+ constructor({ context, initRoutes = [], bearerToken = null, middleware = [], } = {}) {
16
+ this.#bearerToken = bearerToken;
17
+ this.#globalMiddleware = Array.isArray(middleware) ? middleware : [];
18
+ if (Array.isArray(initRoutes))
19
+ this.#buildRoutesPatterns(initRoutes
20
+ .map((RoutesClass) => new RoutesClass(this, context).routerRoutes)
21
+ .flat()
22
+ .filter((route) => route && route.path && route.handler));
23
+ }
24
+ #buildRoutesPatterns(routes) {
25
+ for (const route of routes) {
26
+ if (typeof route.path !== 'string' || typeof route.handler !== 'function') {
27
+ throw new Error('Each route must have a valid path string and handler function');
28
+ }
29
+ // Normalize: collapse multiple slashes, remove trailing slash (except root)
30
+ let normalizedPath = route.path.replace(/\/+/g, '/');
31
+ normalizedPath =
32
+ normalizedPath.length > 1 ? normalizedPath.replace(/\/+$/, '') : normalizedPath;
33
+ for (const method of route.methods) {
34
+ const pathMethodKey = `${normalizedPath}::${method}`;
35
+ if (this.#routes.dynamic.has(normalizedPath) || this.#routes.static.has(pathMethodKey))
36
+ throw new Error(`Duplicate route detected: ${method} ${normalizedPath}`);
37
+ if (normalizedPath.includes(':') ||
38
+ normalizedPath.includes('*') ||
39
+ normalizedPath.includes('(') ||
40
+ normalizedPath.includes('[')) {
41
+ if (!this.#routes.dynamic.has(method))
42
+ this.#routes.dynamic.set(method, []);
43
+ this.#routes.dynamic.get(method).push(route);
44
+ }
45
+ else {
46
+ this.#routes.static.set(pathMethodKey, {
47
+ handler: route.handler,
48
+ });
49
+ }
50
+ }
51
+ }
52
+ }
53
+ #findRouteHandler(path, method) {
54
+ // Normalize path: remove trailing slash (except for root "/")
55
+ const normalizedPath = path.length > 1 ? path.replace(/\/+$/, '') : path;
56
+ if (this.#routes.static.has(`${normalizedPath}::${method}`))
57
+ return this.#routes.static.get(`${normalizedPath}::${method}`);
58
+ if (this.#routes.cache.has(`${normalizedPath}::${method}`))
59
+ return this.#routes.cache.get(`${normalizedPath}::${method}`);
60
+ if (!this.#routes.dynamic.has(method))
61
+ return null;
62
+ const route = this.#routes.dynamic.get(method).find((route) => {
63
+ if (!route.methods.includes(method))
64
+ return false;
65
+ if (route.path === normalizedPath)
66
+ return true;
67
+ return route.pattern?.test(normalizedPath);
68
+ });
69
+ this.#routes.cache.set(`${normalizedPath}::${method}`, route || null);
70
+ this.#pruneCache();
71
+ return route || null;
72
+ }
73
+ #pruneCache() {
74
+ if (this.#routes.cache.size > _a.#MAX_CACHE_SIZE) {
75
+ const firstKey = this.#routes.cache.keys().next().value;
76
+ if (firstKey) {
77
+ this.#routes.cache.delete(firstKey);
78
+ }
79
+ }
80
+ }
81
+ async lambdaEvent(event) {
82
+ let body = _a.MethodsWithBody.includes(event.requestContext.http.method)
83
+ ? event.body
84
+ : null;
85
+ if (event.headers['content-type']?.includes('application/json') && body) {
86
+ try {
87
+ body = JSON.parse(body);
88
+ }
89
+ catch {
90
+ return {
91
+ statusCode: 400,
92
+ body: JSON.stringify({ error: 'Invalid JSON in request body' }),
93
+ };
94
+ }
95
+ }
96
+ const response = await this.#request({
97
+ path: event.requestContext.http.path,
98
+ method: event.requestContext.http.method,
99
+ body: body,
100
+ cookies: this.#parseLambdaCookies(event.cookies || []),
101
+ params: {},
102
+ query: event?.queryStringParameters || {},
103
+ headers: event.headers || {},
104
+ authorizer: event.requestContext.authorizer || null,
105
+ });
106
+ return {
107
+ statusCode: response.status || 200,
108
+ headers: response.headers || { 'Content-Type': 'application/json' },
109
+ body: typeof response.body === 'string' ? response.body : JSON.stringify(response.body),
110
+ isBase64Encoded: response.isBase64Encoded || false,
111
+ };
112
+ }
113
+ async nodeJSRequest(req, res, { cors, lambdaOptions } = {}) {
114
+ if (cors) {
115
+ const origin = req.headers.origin || '*';
116
+ res.setHeader('Access-Control-Allow-Origin', origin);
117
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS');
118
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
119
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
120
+ res.setHeader('Access-Control-Max-Age', '86400');
121
+ }
122
+ if (req.method === 'OPTIONS') {
123
+ res.statusCode = 204;
124
+ res.end();
125
+ return;
126
+ }
127
+ const requestUrl = new URL(req.url, `http://${req.headers.host}`);
128
+ try {
129
+ const response = await this.#request({
130
+ path: requestUrl.pathname,
131
+ method: req.method,
132
+ body: _a.MethodsWithBody.includes(req.method)
133
+ ? await this.#getNodeJSRequestBody(req)
134
+ : null,
135
+ cookies: this.#parseCookies(req.headers?.cookie || ''),
136
+ params: {},
137
+ query: Object.fromEntries(requestUrl.searchParams),
138
+ headers: req.headers,
139
+ authorizer: this.#createAuthorizerFromHeaders(req.headers),
140
+ lambdaOptions: lambdaOptions || {},
141
+ });
142
+ if (!response || typeof response !== 'object') {
143
+ res.statusCode = 500;
144
+ res.setHeader('Content-Type', 'application/json');
145
+ res.end(JSON.stringify({ error: 'Invalid response from handler' }));
146
+ return;
147
+ }
148
+ res.statusCode = response.status || 200;
149
+ const headers = response.headers || {};
150
+ if (!headers['Content-Type'] && !headers['content-type']) {
151
+ headers['Content-Type'] = 'application/json';
152
+ }
153
+ Object.entries(headers).forEach(([name, value]) => {
154
+ res.setHeader(name, value);
155
+ });
156
+ if (response.body !== null && response.body !== undefined) {
157
+ if (Buffer.isBuffer(response.body))
158
+ res.end(response.body);
159
+ else if (response.isBase64Encoded && typeof response.body === 'string')
160
+ res.end(Buffer.from(response.body, 'base64'));
161
+ else if (typeof response.body === 'string')
162
+ res.end(response.body);
163
+ else
164
+ res.end(JSON.stringify(response.body));
165
+ }
166
+ else
167
+ res.end('');
168
+ }
169
+ catch (error) {
170
+ logger.error('Router error', {
171
+ code: 'ROUTER_ERROR',
172
+ source: 'Router.nodeJSRequest',
173
+ path: req.url,
174
+ method: req.method,
175
+ error: error instanceof Error ? error : String(error),
176
+ stack: error instanceof Error ? error.stack : undefined,
177
+ });
178
+ res.statusCode = 500;
179
+ res.setHeader('Content-Type', 'application/json');
180
+ const errorResponse = RouteError.create(500, 'Internal Server Error', error instanceof Error ? error.message : String(error));
181
+ res.end(typeof errorResponse.body === 'string'
182
+ ? errorResponse.body
183
+ : JSON.stringify(errorResponse.body));
184
+ }
185
+ }
186
+ #parseCookies(cookieHeader) {
187
+ if (!cookieHeader)
188
+ return {};
189
+ return Object.fromEntries(cookieHeader.split(';').map((cookie) => {
190
+ const [key, ...rest] = cookie.trim().split('=');
191
+ return [key, rest.join('=')];
192
+ }));
193
+ }
194
+ /**
195
+ * Parse Lambda HTTP API v2.0 cookies array into key-value object
196
+ * Lambda provides cookies as an array like: ["cookie1=value1", "cookie2=value2"]
197
+ */
198
+ #parseLambdaCookies(cookies) {
199
+ if (!Array.isArray(cookies) || cookies.length === 0)
200
+ return {};
201
+ return Object.fromEntries(cookies.map((cookie) => {
202
+ const [key, ...rest] = cookie.split('=');
203
+ return [key, rest.join('=')];
204
+ }));
205
+ }
206
+ #createAuthorizerFromHeaders(headers) {
207
+ const authHeader = headers?.authorization || headers?.Authorization;
208
+ if (!authHeader)
209
+ return null;
210
+ const authValue = Array.isArray(authHeader) ? authHeader[0] : authHeader;
211
+ const token = authValue?.replace(/^Bearer\s+/i, '') || '';
212
+ if (!token)
213
+ return null;
214
+ try {
215
+ // Decode JWT (base64url decode the payload)
216
+ const parts = token.split('.');
217
+ if (parts.length !== 3)
218
+ return null;
219
+ const payload = parts[1];
220
+ const decoded = Buffer.from(payload, 'base64url').toString('utf8');
221
+ const claims = JSON.parse(decoded);
222
+ // Return in same structure as Lambda authorizer for consistency
223
+ return {
224
+ lambda: claims, // Mimic HTTP API Lambda authorizer structure
225
+ };
226
+ }
227
+ catch (error) {
228
+ logger.error('Failed to decode JWT', {
229
+ code: 'ROUTER_JWT_DECODE_ERROR',
230
+ source: 'Router.decodeJwt',
231
+ error: error instanceof Error ? error : String(error),
232
+ });
233
+ return null;
234
+ }
235
+ }
236
+ async #getNodeJSRequestBody(req) {
237
+ return new Promise((resolve, reject) => {
238
+ let body = '';
239
+ let size = 0;
240
+ req.on('data', (chunk) => {
241
+ size += chunk.length;
242
+ if (size > _a.#MAX_BODY_SIZE) {
243
+ req.destroy();
244
+ reject(new Error('Request body too large'));
245
+ return;
246
+ }
247
+ body += chunk.toString();
248
+ });
249
+ req.on('end', () => {
250
+ if (req.headers['content-type']?.includes('application/json')) {
251
+ try {
252
+ resolve(JSON.parse(body));
253
+ }
254
+ catch {
255
+ resolve(body);
256
+ }
257
+ }
258
+ else {
259
+ resolve(body);
260
+ }
261
+ });
262
+ req.on('error', (err) => {
263
+ reject(err);
264
+ });
265
+ });
266
+ }
267
+ async #request(request) {
268
+ if (this.#bearerToken) {
269
+ const authHeader = request.headers?.authorization || request.headers?.Authorization;
270
+ if (!authHeader)
271
+ return RouteError.create(401, 'Unauthorized', 'Missing Authorization header');
272
+ const authValue = Array.isArray(authHeader) ? authHeader[0] : authHeader;
273
+ const token = authValue?.replace(/^Bearer\s+/i, '') || '';
274
+ if (token !== this.#bearerToken)
275
+ return RouteError.create(403, 'Forbidden', 'Invalid authorization token');
276
+ }
277
+ const route = this.#findRouteHandler(request.path, request.method);
278
+ if (!route)
279
+ return RouteError.create(404, 'Not Found', `Route ${request.method} ${request.path} does not exist`);
280
+ // Match dynamic route parameters
281
+ if ('pattern' in route && route.path !== request.path && route.pattern) {
282
+ const match = route.pattern.exec(request.path);
283
+ if (match?.pathname?.groups) {
284
+ request.params = match.pathname.groups;
285
+ }
286
+ }
287
+ try {
288
+ // Run global middleware
289
+ for (const middleware of this.#globalMiddleware) {
290
+ const middlewareResult = await middleware(request);
291
+ if (middlewareResult) {
292
+ // Middleware returned a response, short-circuit
293
+ return middlewareResult;
294
+ }
295
+ }
296
+ // Run route-specific middleware
297
+ if ('middleware' in route && route.middleware && Array.isArray(route.middleware)) {
298
+ for (const middleware of route.middleware) {
299
+ const middlewareResult = await middleware(request);
300
+ if (middlewareResult) {
301
+ // Middleware returned a response, short-circuit
302
+ return middlewareResult;
303
+ }
304
+ }
305
+ }
306
+ // Execute route handler
307
+ const result = await route.handler(request);
308
+ if (!result || typeof result !== 'object')
309
+ throw new Error('Handler must return a response object');
310
+ return result;
311
+ }
312
+ catch (error) {
313
+ logger.error('Route handler error', {
314
+ code: 'ROUTER_HANDLER_ERROR',
315
+ source: 'Router.request',
316
+ path: request.path,
317
+ method: request.method,
318
+ error: error instanceof Error ? error : String(error),
319
+ stack: error instanceof Error ? error.stack : undefined,
320
+ });
321
+ return RouteError.create(500, 'Internal Server Error', error instanceof Error ? error.message : String(error));
322
+ }
323
+ }
324
+ }
325
+ _a = Router;
326
+ export default Router;
327
+ //# sourceMappingURL=Router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Router.js","sourceRoot":"","sources":["../../src/router/Router.ts"],"names":[],"mappings":"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"}