@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,165 @@
1
+ /**
2
+ * OpenAPI/Swagger Documentation Generator
3
+ *
4
+ * This utility helps generate OpenAPI 3.0 documentation for your API routes.
5
+ *
6
+ * Installation:
7
+ * ```bash
8
+ * npm install --save-dev swagger-jsdoc swagger-ui-dist
9
+ * ```
10
+ *
11
+ * Usage:
12
+ * ```typescript
13
+ * import { OpenApiGenerator } from '@designofadecade/server';
14
+ *
15
+ * const generator = new OpenApiGenerator({
16
+ * title: 'My API',
17
+ * version: '1.0.0',
18
+ * description: 'My API description'
19
+ * });
20
+ *
21
+ * // Add route documentation
22
+ * generator.addRoute({
23
+ * path: '/api/users',
24
+ * method: 'GET',
25
+ * summary: 'Get all users',
26
+ * responses: {
27
+ * 200: { description: 'Success', schema: { type: 'array' } }
28
+ * }
29
+ * });
30
+ *
31
+ * // Generate OpenAPI spec
32
+ * const spec = generator.generate();
33
+ * ```
34
+ */
35
+ export class OpenApiGenerator {
36
+ config;
37
+ routes = [];
38
+ constructor(config) {
39
+ this.config = config;
40
+ }
41
+ /**
42
+ * Add a route to the OpenAPI documentation
43
+ */
44
+ addRoute(route) {
45
+ this.routes.push(route);
46
+ }
47
+ /**
48
+ * Add multiple routes at once
49
+ */
50
+ addRoutes(routes) {
51
+ this.routes.push(...routes);
52
+ }
53
+ /**
54
+ * Generate the complete OpenAPI specification
55
+ */
56
+ generate() {
57
+ const paths = {};
58
+ // Group routes by path
59
+ for (const route of this.routes) {
60
+ if (!paths[route.path]) {
61
+ paths[route.path] = {};
62
+ }
63
+ const pathItem = paths[route.path];
64
+ const method = route.method.toLowerCase();
65
+ pathItem[method] = {
66
+ summary: route.summary,
67
+ description: route.description,
68
+ operationId: route.operationId,
69
+ tags: route.tags,
70
+ parameters: route.parameters,
71
+ requestBody: route.requestBody,
72
+ responses: route.responses,
73
+ security: route.security,
74
+ };
75
+ }
76
+ return {
77
+ openapi: '3.0.0',
78
+ info: this.config.info,
79
+ servers: this.config.servers || [],
80
+ tags: this.config.tags || [],
81
+ paths,
82
+ components: this.config.components || {},
83
+ };
84
+ }
85
+ /**
86
+ * Generate OpenAPI spec as JSON string
87
+ */
88
+ toJSON() {
89
+ return JSON.stringify(this.generate(), null, 2);
90
+ }
91
+ /**
92
+ * Generate OpenAPI spec as YAML string (basic implementation)
93
+ */
94
+ toYAML() {
95
+ const spec = this.generate();
96
+ // Basic YAML conversion - for production use a proper YAML library
97
+ return this.objectToYaml(spec, 0);
98
+ }
99
+ objectToYaml(obj, indent) {
100
+ const spaces = ' '.repeat(indent);
101
+ let yaml = '';
102
+ if (typeof obj === 'object' && obj !== null) {
103
+ if (Array.isArray(obj)) {
104
+ for (const item of obj) {
105
+ yaml += `${spaces}- ${this.objectToYaml(item, indent + 1)}\n`;
106
+ }
107
+ }
108
+ else {
109
+ for (const [key, value] of Object.entries(obj)) {
110
+ if (value === undefined)
111
+ continue;
112
+ if (typeof value === 'object' && value !== null) {
113
+ yaml += `${spaces}${key}:\n`;
114
+ yaml += this.objectToYaml(value, indent + 1);
115
+ }
116
+ else if (typeof value === 'string') {
117
+ yaml += `${spaces}${key}: "${value}"\n`;
118
+ }
119
+ else {
120
+ yaml += `${spaces}${key}: ${value}\n`;
121
+ }
122
+ }
123
+ }
124
+ }
125
+ else {
126
+ yaml = String(obj);
127
+ }
128
+ return yaml;
129
+ }
130
+ }
131
+ /**
132
+ * Helper function to create Swagger UI HTML page
133
+ */
134
+ export function generateSwaggerUI(specUrl) {
135
+ const specConfig = typeof specUrl === 'string' ? `url: "${specUrl}"` : `spec: ${JSON.stringify(specUrl)}`;
136
+ return `<!DOCTYPE html>
137
+ <html lang="en">
138
+ <head>
139
+ <meta charset="UTF-8">
140
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
141
+ <title>API Documentation</title>
142
+ <link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.10.0/swagger-ui.css">
143
+ </head>
144
+ <body>
145
+ <div id="swagger-ui"></div>
146
+ <script src="https://unpkg.com/swagger-ui-dist@5.10.0/swagger-ui-bundle.js"></script>
147
+ <script src="https://unpkg.com/swagger-ui-dist@5.10.0/swagger-ui-standalone-preset.js"></script>
148
+ <script>
149
+ window.onload = function() {
150
+ SwaggerUIBundle({
151
+ ${specConfig},
152
+ dom_id: '#swagger-ui',
153
+ deepLinking: true,
154
+ presets: [
155
+ SwaggerUIBundle.presets.apis,
156
+ SwaggerUIStandalonePreset
157
+ ],
158
+ layout: "StandaloneLayout"
159
+ });
160
+ };
161
+ </script>
162
+ </body>
163
+ </html>`;
164
+ }
165
+ //# sourceMappingURL=OpenApiGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenApiGenerator.js","sourceRoot":"","sources":["../../src/docs/OpenApiGenerator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Event handler registration for EventsManager
3
+ *
4
+ * Abstract base class for organizing event handlers. Extend this class
5
+ * to group related WebSocket event handlers together and register them
6
+ * with the EventsManager.
7
+ *
8
+ * @class Events
9
+ * @example
10
+ * class ChatEvents extends Events {
11
+ * constructor(manager: EventsManager) {
12
+ * super(manager);
13
+ *
14
+ * this.addListener('chat:message', async (msg) => {
15
+ * console.log('Received message:', msg.payload);
16
+ * manager.broadcast('chat:new', msg.payload);
17
+ * });
18
+ * }
19
+ * }
20
+ *
21
+ * // Register with EventsManager
22
+ * const eventsManager = new EventsManager({
23
+ * registerWebSocketServer: wss,
24
+ * initEvents: [ChatEvents]
25
+ * });
26
+ */
27
+ interface EventRegistration {
28
+ type: string;
29
+ handler: (parsedMessage: any) => void | Promise<void>;
30
+ }
31
+ export default class Events {
32
+ #private;
33
+ /**
34
+ * Array of nested event classes to register
35
+ * @type {Array}
36
+ */
37
+ static register: (new (manager: any) => Events)[];
38
+ constructor(manager: any);
39
+ get managerEvents(): EventRegistration[];
40
+ /**
41
+ * Returns the events manager instance
42
+ */
43
+ get manager(): any;
44
+ /**
45
+ * Adds an event listener
46
+ * @param {string} type - Event type to listen for
47
+ * @param {Function} handler - Handler function to execute
48
+ */
49
+ addListener(type: string, handler: (parsedMessage: any) => void | Promise<void>): void;
50
+ }
51
+ export {};
52
+ //# sourceMappingURL=Events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Events.d.ts","sourceRoot":"","sources":["../../src/events/Events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,aAAa,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvD;AAED,MAAM,CAAC,OAAO,OAAO,MAAM;;IACzB;;;OAGG;IACH,MAAM,CAAC,QAAQ,EAAE,CAAC,KAAK,OAAO,EAAE,GAAG,KAAK,MAAM,CAAC,EAAE,CAAM;gBAK3C,OAAO,EAAE,GAAG;IAWxB,IAAI,aAAa,IAAI,iBAAiB,EAAE,CAEvC;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,GAAG,CAEjB;IAED;;;;OAIG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,aAAa,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;CAevF"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Event handler registration for EventsManager
3
+ *
4
+ * Abstract base class for organizing event handlers. Extend this class
5
+ * to group related WebSocket event handlers together and register them
6
+ * with the EventsManager.
7
+ *
8
+ * @class Events
9
+ * @example
10
+ * class ChatEvents extends Events {
11
+ * constructor(manager: EventsManager) {
12
+ * super(manager);
13
+ *
14
+ * this.addListener('chat:message', async (msg) => {
15
+ * console.log('Received message:', msg.payload);
16
+ * manager.broadcast('chat:new', msg.payload);
17
+ * });
18
+ * }
19
+ * }
20
+ *
21
+ * // Register with EventsManager
22
+ * const eventsManager = new EventsManager({
23
+ * registerWebSocketServer: wss,
24
+ * initEvents: [ChatEvents]
25
+ * });
26
+ */
27
+ export default class Events {
28
+ /**
29
+ * Array of nested event classes to register
30
+ * @type {Array}
31
+ */
32
+ static register = [];
33
+ #managerEvents = [];
34
+ #manager;
35
+ constructor(manager) {
36
+ this.#manager = manager;
37
+ this.constructor.register.forEach((EventsClass) => {
38
+ const events = new EventsClass(manager);
39
+ this.#managerEvents.push(...events.managerEvents);
40
+ });
41
+ }
42
+ get managerEvents() {
43
+ return this.#managerEvents;
44
+ }
45
+ /**
46
+ * Returns the events manager instance
47
+ */
48
+ get manager() {
49
+ return this.#manager;
50
+ }
51
+ /**
52
+ * Adds an event listener
53
+ * @param {string} type - Event type to listen for
54
+ * @param {Function} handler - Handler function to execute
55
+ */
56
+ addListener(type, handler) {
57
+ // Validate inputs
58
+ if (typeof type !== 'string' || !type.trim()) {
59
+ throw new Error('Event type must be a non-empty string');
60
+ }
61
+ if (typeof handler !== 'function') {
62
+ throw new Error('Handler must be a function');
63
+ }
64
+ this.#managerEvents.push({
65
+ type,
66
+ handler,
67
+ });
68
+ }
69
+ }
70
+ //# sourceMappingURL=Events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Events.js","sourceRoot":"","sources":["../../src/events/Events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAOH,MAAM,CAAC,OAAO,OAAO,MAAM;IACzB;;;OAGG;IACH,MAAM,CAAC,QAAQ,GAAqC,EAAE,CAAC;IAEvD,cAAc,GAAwB,EAAE,CAAC;IACzC,QAAQ,CAAM;IAEd,YAAY,OAAY;QACtB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QAEvB,IAAI,CAAC,WAA6B,CAAC,QAAQ,CAAC,OAAO,CAClD,CAAC,WAAyC,EAAE,EAAE;YAC5C,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;QACpD,CAAC,CACF,CAAC;IACJ,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,WAAW,CAAC,IAAY,EAAE,OAAqD;QAC7E,kBAAkB;QAClB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YACvB,IAAI;YACJ,OAAO;SACR,CAAC,CAAC;IACL,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * WebSocket event management system
3
+ *
4
+ * Manages WebSocket event handlers and message broadcasting.
5
+ * Integrates with WebSocketServer to handle incoming messages
6
+ * and provides organized event handling through Events classes.
7
+ *
8
+ * @class EventsManager
9
+ * @example
10
+ * const eventsManager = new EventsManager({
11
+ * registerWebSocketServer: wss,
12
+ * initEvents: [UserEvents, ChatEvents]
13
+ * });
14
+ *
15
+ * // Broadcast to all connected clients
16
+ * eventsManager.broadcast('notification', { message: 'Hello!' });
17
+ *
18
+ * @example
19
+ * // Register individual events
20
+ * eventsManager.registerEvents([
21
+ * { type: 'ping', handler: async (msg) => console.log('Ping!') },
22
+ * { type: 'update', handler: async (msg) => handleUpdate(msg) }
23
+ * ]);
24
+ */
25
+ import type Events from './Events.js';
26
+ interface ParsedMessage {
27
+ id?: string;
28
+ type: string;
29
+ payload: any;
30
+ }
31
+ interface EventsManagerOptions {
32
+ registerWebSocketServer?: any;
33
+ initEvents?: (new (manager: EventsManager) => Events)[];
34
+ }
35
+ export default class EventsManager {
36
+ #private;
37
+ constructor({ registerWebSocketServer, initEvents }?: EventsManagerOptions);
38
+ registerEvents(events: {
39
+ type: string;
40
+ handler: (parsedMessage: ParsedMessage) => void | Promise<void>;
41
+ }[]): void;
42
+ broadcast(type: string, message: any): void;
43
+ close(): void;
44
+ }
45
+ export {};
46
+ //# sourceMappingURL=EventsManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventsManager.d.ts","sourceRoot":"","sources":["../../src/events/EventsManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAEtC,UAAU,aAAa;IACrB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,GAAG,CAAC;CACd;AAED,UAAU,oBAAoB;IAC5B,uBAAuB,CAAC,EAAE,GAAG,CAAC;IAC9B,UAAU,CAAC,EAAE,CAAC,KAAK,OAAO,EAAE,aAAa,KAAK,MAAM,CAAC,EAAE,CAAC;CACzD;AAED,MAAM,CAAC,OAAO,OAAO,aAAa;;gBAKpB,EAAE,uBAA8B,EAAE,UAAe,EAAE,GAAE,oBAAyB;IAS1F,cAAc,CACZ,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,EAAE,GAC1F,IAAI;IAwBP,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI;IA8E3C,KAAK,IAAI,IAAI;CAUd"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * WebSocket event management system
3
+ *
4
+ * Manages WebSocket event handlers and message broadcasting.
5
+ * Integrates with WebSocketServer to handle incoming messages
6
+ * and provides organized event handling through Events classes.
7
+ *
8
+ * @class EventsManager
9
+ * @example
10
+ * const eventsManager = new EventsManager({
11
+ * registerWebSocketServer: wss,
12
+ * initEvents: [UserEvents, ChatEvents]
13
+ * });
14
+ *
15
+ * // Broadcast to all connected clients
16
+ * eventsManager.broadcast('notification', { message: 'Hello!' });
17
+ *
18
+ * @example
19
+ * // Register individual events
20
+ * eventsManager.registerEvents([
21
+ * { type: 'ping', handler: async (msg) => console.log('Ping!') },
22
+ * { type: 'update', handler: async (msg) => handleUpdate(msg) }
23
+ * ]);
24
+ */
25
+ import WebSocketMessageFormatter from '../websocket/WebSocketMessageFormatter.js';
26
+ import { logger } from '../logger/Logger.js';
27
+ export default class EventsManager {
28
+ #wss;
29
+ #events = new Map();
30
+ #messageListener = null;
31
+ constructor({ registerWebSocketServer = null, initEvents = [] } = {}) {
32
+ if (Array.isArray(initEvents) && initEvents.length > 0)
33
+ this.registerEvents(initEvents.map((EventClass) => new EventClass(this).managerEvents).flat());
34
+ if (registerWebSocketServer)
35
+ this.#registerWebSocketServer(registerWebSocketServer);
36
+ }
37
+ registerEvents(events) {
38
+ if (!Array.isArray(events)) {
39
+ throw new Error('Events must be an array');
40
+ }
41
+ events.forEach((event) => {
42
+ // Validate event structure
43
+ if (!event || !event.type || typeof event.handler !== 'function') {
44
+ logger.warn('Invalid event registration', {
45
+ code: 'EVENT_INVALID_REGISTRATION',
46
+ source: 'EventsManager.registerEvents',
47
+ event,
48
+ });
49
+ return;
50
+ }
51
+ if (!this.#events.has(event.type)) {
52
+ this.#events.set(event.type, []);
53
+ }
54
+ this.#events.get(event.type).push(event.handler);
55
+ });
56
+ }
57
+ broadcast(type, message) {
58
+ if (!this.#wss) {
59
+ logger.warn('Cannot broadcast: WebSocket server not registered', {
60
+ code: 'EVENT_NO_WEBSOCKET',
61
+ source: 'EventsManager.broadcast',
62
+ messageType: type,
63
+ });
64
+ return;
65
+ }
66
+ if (typeof type !== 'string') {
67
+ throw new Error('Broadcast type must be a string');
68
+ }
69
+ try {
70
+ this.#wss.broadcast(WebSocketMessageFormatter.format(type, message));
71
+ }
72
+ catch (error) {
73
+ logger.error('Broadcast error', {
74
+ code: 'EVENT_BROADCAST_ERROR',
75
+ source: 'EventsManager.broadcast',
76
+ messageType: type,
77
+ error,
78
+ });
79
+ }
80
+ }
81
+ #registerWebSocketServer(wss) {
82
+ this.#wss = wss;
83
+ this.#messageListener = async (parsedMessage) => {
84
+ try {
85
+ // Message is already parsed from WebSocketServer
86
+ logger.debug('Received message', {
87
+ source: 'EventsManager.onMessage',
88
+ type: parsedMessage.type,
89
+ id: parsedMessage.id,
90
+ });
91
+ if (this.#events.has(parsedMessage.type)) {
92
+ const handlers = this.#events.get(parsedMessage.type);
93
+ // Execute handlers with proper error handling
94
+ await Promise.allSettled(handlers.map((handler) => handler(parsedMessage))).then((results) => {
95
+ results.forEach((result, index) => {
96
+ if (result.status === 'rejected') {
97
+ logger.error('Event handler failed', {
98
+ code: 'EVENT_HANDLER_ERROR',
99
+ source: 'EventsManager.onMessage',
100
+ handlerIndex: index,
101
+ messageType: parsedMessage.type,
102
+ error: result.reason,
103
+ });
104
+ }
105
+ });
106
+ });
107
+ return;
108
+ }
109
+ logger.warn('No handlers registered for event type', {
110
+ code: 'EVENT_NO_HANDLERS',
111
+ source: 'EventsManager.onMessage',
112
+ eventType: parsedMessage.type,
113
+ });
114
+ }
115
+ catch (error) {
116
+ logger.error('Error processing WebSocket message', {
117
+ code: 'EVENT_PROCESSING_ERROR',
118
+ source: 'EventsManager.onMessage',
119
+ messageType: parsedMessage.type,
120
+ error,
121
+ });
122
+ }
123
+ };
124
+ wss.on('message', this.#messageListener);
125
+ }
126
+ close() {
127
+ // Cleanup
128
+ if (this.#wss && this.#messageListener) {
129
+ this.#wss.off('message', this.#messageListener);
130
+ }
131
+ this.#events.clear();
132
+ logger.info('Events manager closed', {
133
+ source: 'EventsManager.close',
134
+ });
135
+ }
136
+ }
137
+ //# sourceMappingURL=EventsManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventsManager.js","sourceRoot":"","sources":["../../src/events/EventsManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ export { default as Server } from './server/Server.js';
2
+ export { default as Router } from './router/Router.js';
3
+ export { default as Routes } from './router/Routes.js';
4
+ export { default as StaticFileHandler } from './router/StaticFileHandler.js';
5
+ export { default as Context } from './context/Context.js';
6
+ export type { RouterRequest, RouterResponse, RouterOptions, RouterMiddleware, } from './router/Router.js';
7
+ export { default as WebSocketServer } from './websocket/WebSocketServer.js';
8
+ export { default as WebSocketMessageFormatter } from './websocket/WebSocketMessageFormatter.js';
9
+ export * from './middleware/RequestLogger.js';
10
+ export { default as AppState } from './state/AppState.js';
11
+ export { default as Events } from './events/Events.js';
12
+ export { default as EventsManager } from './events/EventsManager.js';
13
+ export { default as HtmlSanitizer } from './sanitizer/HtmlSanitizer.js';
14
+ export { default as HtmlRenderer } from './utils/HtmlRenderer.js';
15
+ export { default as Local } from './local/Local.js';
16
+ export { logger } from './logger/Logger.js';
17
+ export { default as ApiClient } from './client/ApiClient.js';
18
+ export { default as RouteError } from './router/RouteError.js';
19
+ export { OpenApiGenerator, generateSwaggerUI } from './docs/OpenApiGenerator.js';
20
+ export type { OpenApiInfo, OpenApiServer, OpenApiParameter, OpenApiResponse, OpenApiRouteConfig, OpenApiConfig, } from './docs/OpenApiGenerator.js';
21
+ import HtmlSanitizer from './sanitizer/HtmlSanitizer.js';
22
+ import HtmlRenderer from './utils/HtmlRenderer.js';
23
+ import Local from './local/Local.js';
24
+ import ApiClient from './client/ApiClient.js';
25
+ export declare const Utils: {
26
+ HtmlSanitizer: typeof HtmlSanitizer;
27
+ HtmlRenderer: typeof HtmlRenderer;
28
+ Local: typeof Local;
29
+ ApiClient: typeof ApiClient;
30
+ };
31
+ export { default as Slack } from './notifications/Slack.js';
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAG1D,YAAY,EACV,aAAa,EACb,cAAc,EACd,aAAa,EACb,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AAGhG,cAAc,+BAA+B,CAAC;AAG9C,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAGrE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAG/D,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACjF,YAAY,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,aAAa,GACd,MAAM,4BAA4B,CAAC;AAGpC,OAAO,aAAa,MAAM,8BAA8B,CAAC;AACzD,OAAO,YAAY,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,MAAM,kBAAkB,CAAC;AACrC,OAAO,SAAS,MAAM,uBAAuB,CAAC;AAE9C,eAAO,MAAM,KAAK;;;;;CAKjB,CAAC;AAGF,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,38 @@
1
+ // Server Core
2
+ export { default as Server } from './server/Server.js';
3
+ export { default as Router } from './router/Router.js';
4
+ export { default as Routes } from './router/Routes.js';
5
+ export { default as StaticFileHandler } from './router/StaticFileHandler.js';
6
+ export { default as Context } from './context/Context.js';
7
+ // WebSocket
8
+ export { default as WebSocketServer } from './websocket/WebSocketServer.js';
9
+ export { default as WebSocketMessageFormatter } from './websocket/WebSocketMessageFormatter.js';
10
+ // Middleware
11
+ export * from './middleware/RequestLogger.js';
12
+ // State & Events
13
+ export { default as AppState } from './state/AppState.js';
14
+ export { default as Events } from './events/Events.js';
15
+ export { default as EventsManager } from './events/EventsManager.js';
16
+ // Utilities (individual exports)
17
+ export { default as HtmlSanitizer } from './sanitizer/HtmlSanitizer.js';
18
+ export { default as HtmlRenderer } from './utils/HtmlRenderer.js';
19
+ export { default as Local } from './local/Local.js';
20
+ export { logger } from './logger/Logger.js';
21
+ export { default as ApiClient } from './client/ApiClient.js';
22
+ export { default as RouteError } from './router/RouteError.js';
23
+ // Documentation
24
+ export { OpenApiGenerator, generateSwaggerUI } from './docs/OpenApiGenerator.js';
25
+ // Utilities (grouped namespace - classes only)
26
+ import HtmlSanitizer from './sanitizer/HtmlSanitizer.js';
27
+ import HtmlRenderer from './utils/HtmlRenderer.js';
28
+ import Local from './local/Local.js';
29
+ import ApiClient from './client/ApiClient.js';
30
+ export const Utils = {
31
+ HtmlSanitizer,
32
+ HtmlRenderer,
33
+ Local,
34
+ ApiClient,
35
+ };
36
+ // Integrations
37
+ export { default as Slack } from './notifications/Slack.js';
38
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAU1D,YAAY;AACZ,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AAEhG,aAAa;AACb,cAAc,+BAA+B,CAAC;AAE9C,iBAAiB;AACjB,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAErE,iCAAiC;AACjC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAE/D,gBAAgB;AAChB,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAUjF,+CAA+C;AAC/C,OAAO,aAAa,MAAM,8BAA8B,CAAC;AACzD,OAAO,YAAY,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,MAAM,kBAAkB,CAAC;AACrC,OAAO,SAAS,MAAM,uBAAuB,CAAC;AAE9C,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,aAAa;IACb,YAAY;IACZ,KAAK;IACL,SAAS;CACV,CAAC;AAEF,eAAe;AACf,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Local development utilities for Lambda handlers
3
+ *
4
+ * Provides utilities to run AWS Lambda handlers locally using a Node.js server.
5
+ * Converts HTTP requests to Lambda event format and responses back to HTTP.
6
+ *
7
+ * @class Local
8
+ * @example
9
+ * // Wrap your Lambda handler for local development
10
+ * import { handler } from './lambda/handler.js';
11
+ * import Local from '@designofadecade/local';
12
+ *
13
+ * const localHandler = Local.LambdaProxyRouter(handler, {
14
+ * requestContext: { stage: 'dev' }
15
+ * });
16
+ *
17
+ * // Use with Node.js http server
18
+ * http.createServer((req, res) => {
19
+ * localHandler.request(req, res);
20
+ * }).listen(3000);
21
+ */
22
+ import type { IncomingMessage, ServerResponse } from 'http';
23
+ interface LambdaProxyRouterOptions {
24
+ requestContext?: Record<string, unknown>;
25
+ event?: Record<string, unknown>;
26
+ }
27
+ interface LambdaEvent {
28
+ rawPath: string;
29
+ headers: Record<string, string | string[] | undefined>;
30
+ queryStringParameters: Record<string, string>;
31
+ cookies: Record<string, string>;
32
+ requestContext: {
33
+ http: {
34
+ method: string;
35
+ path: string;
36
+ };
37
+ authorizer: unknown;
38
+ [key: string]: unknown;
39
+ };
40
+ body: string | null;
41
+ [key: string]: unknown;
42
+ }
43
+ interface LambdaResponse {
44
+ statusCode: number;
45
+ headers?: Record<string, string>;
46
+ cookies?: string[];
47
+ body?: string;
48
+ isBase64Encoded?: boolean;
49
+ }
50
+ export default class Local {
51
+ /**
52
+ * Lambda proxy router for local development
53
+ *
54
+ * Creates a router that wraps AWS Lambda handlers and allows them to be
55
+ * run locally with a Node.js HTTP server. Automatically converts between
56
+ * HTTP requests and Lambda event format.
57
+ *
58
+ * @param {Function} LambdaHandler - AWS Lambda handler function
59
+ * @param {Object} options - Configuration options
60
+ * @param {Object} options.requestContext - Additional requestContext fields for Lambda event
61
+ * @param {Object} options.event - Additional event fields for Lambda event
62
+ * @returns {Object} Object with request method for handling HTTP requests
63
+ *
64
+ * @example
65
+ * const handler = Local.LambdaProxyRouter(
66
+ * async (event) => {
67
+ * return {
68
+ * statusCode: 200,
69
+ * body: JSON.stringify({ message: 'Hello!' })
70
+ * };
71
+ * },
72
+ * { requestContext: { stage: 'local' } }
73
+ * );
74
+ */
75
+ static LambdaProxyRouter(LambdaHandler: (event: LambdaEvent) => Promise<LambdaResponse>, options?: LambdaProxyRouterOptions): {
76
+ request: (req: IncomingMessage, res: ServerResponse, requestOptions?: {
77
+ requestContext?: Record<string, unknown>;
78
+ event?: Record<string, unknown>;
79
+ }) => Promise<void>;
80
+ };
81
+ }
82
+ export {};
83
+ //# sourceMappingURL=Local.d.ts.map