@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.
- package/CHANGELOG.md +62 -0
- package/LICENSE +21 -0
- package/README.md +297 -0
- package/dist/client/ApiClient.d.ts +121 -0
- package/dist/client/ApiClient.d.ts.map +1 -0
- package/dist/client/ApiClient.js +289 -0
- package/dist/client/ApiClient.js.map +1 -0
- package/dist/context/Context.d.ts +71 -0
- package/dist/context/Context.d.ts.map +1 -0
- package/dist/context/Context.js +81 -0
- package/dist/context/Context.js.map +1 -0
- package/dist/docs/OpenApiGenerator.d.ts +135 -0
- package/dist/docs/OpenApiGenerator.d.ts.map +1 -0
- package/dist/docs/OpenApiGenerator.js +165 -0
- package/dist/docs/OpenApiGenerator.js.map +1 -0
- package/dist/events/Events.d.ts +52 -0
- package/dist/events/Events.d.ts.map +1 -0
- package/dist/events/Events.js +70 -0
- package/dist/events/Events.js.map +1 -0
- package/dist/events/EventsManager.d.ts +46 -0
- package/dist/events/EventsManager.d.ts.map +1 -0
- package/dist/events/EventsManager.js +137 -0
- package/dist/events/EventsManager.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/local/Local.d.ts +83 -0
- package/dist/local/Local.d.ts.map +1 -0
- package/dist/local/Local.js +114 -0
- package/dist/local/Local.js.map +1 -0
- package/dist/logger/Logger.d.ts +365 -0
- package/dist/logger/Logger.d.ts.map +1 -0
- package/dist/logger/Logger.js +582 -0
- package/dist/logger/Logger.js.map +1 -0
- package/dist/middleware/RequestLogger.d.ts +62 -0
- package/dist/middleware/RequestLogger.d.ts.map +1 -0
- package/dist/middleware/RequestLogger.js +71 -0
- package/dist/middleware/RequestLogger.js.map +1 -0
- package/dist/notifications/Slack.d.ts +19 -0
- package/dist/notifications/Slack.d.ts.map +1 -0
- package/dist/notifications/Slack.js +55 -0
- package/dist/notifications/Slack.js.map +1 -0
- package/dist/router/RouteError.d.ts +21 -0
- package/dist/router/RouteError.d.ts.map +1 -0
- package/dist/router/RouteError.js +31 -0
- package/dist/router/RouteError.js.map +1 -0
- package/dist/router/Router.d.ts +66 -0
- package/dist/router/Router.d.ts.map +1 -0
- package/dist/router/Router.js +327 -0
- package/dist/router/Router.js.map +1 -0
- package/dist/router/Routes.d.ts +30 -0
- package/dist/router/Routes.d.ts.map +1 -0
- package/dist/router/Routes.js +52 -0
- package/dist/router/Routes.js.map +1 -0
- package/dist/router/StaticFileHandler.d.ts +44 -0
- package/dist/router/StaticFileHandler.d.ts.map +1 -0
- package/dist/router/StaticFileHandler.js +148 -0
- package/dist/router/StaticFileHandler.js.map +1 -0
- package/dist/sanitizer/HtmlSanitizer.d.ts +306 -0
- package/dist/sanitizer/HtmlSanitizer.d.ts.map +1 -0
- package/dist/sanitizer/HtmlSanitizer.js +808 -0
- package/dist/sanitizer/HtmlSanitizer.js.map +1 -0
- package/dist/server/Server.d.ts +28 -0
- package/dist/server/Server.d.ts.map +1 -0
- package/dist/server/Server.js +95 -0
- package/dist/server/Server.js.map +1 -0
- package/dist/state/AppState.d.ts +64 -0
- package/dist/state/AppState.d.ts.map +1 -0
- package/dist/state/AppState.js +89 -0
- package/dist/state/AppState.js.map +1 -0
- package/dist/utils/HtmlRenderer.d.ts +6 -0
- package/dist/utils/HtmlRenderer.d.ts.map +1 -0
- package/dist/utils/HtmlRenderer.js +128 -0
- package/dist/utils/HtmlRenderer.js.map +1 -0
- package/dist/websocket/WebSocketMessageFormatter.d.ts +40 -0
- package/dist/websocket/WebSocketMessageFormatter.d.ts.map +1 -0
- package/dist/websocket/WebSocketMessageFormatter.js +99 -0
- package/dist/websocket/WebSocketMessageFormatter.js.map +1 -0
- package/dist/websocket/WebSocketServer.d.ts +14 -0
- package/dist/websocket/WebSocketServer.d.ts.map +1 -0
- package/dist/websocket/WebSocketServer.js +138 -0
- package/dist/websocket/WebSocketServer.js.map +1 -0
- 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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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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
|