quantum-flow 1.3.10 → 1.5.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 (67) hide show
  1. package/README.md +22 -15
  2. package/dist/app/aws/lambda.d.ts +0 -3
  3. package/dist/app/aws/lambda.js +25 -112
  4. package/dist/app/aws/utils/helpers.d.ts +4 -0
  5. package/dist/app/aws/utils/helpers.js +83 -0
  6. package/dist/app/aws/utils/index.d.ts +3 -0
  7. package/dist/app/aws/utils/index.js +19 -0
  8. package/dist/app/aws/utils/request.d.ts +23 -0
  9. package/dist/app/aws/utils/request.js +96 -0
  10. package/dist/app/aws/utils/response.d.ts +14 -0
  11. package/dist/app/aws/utils/response.js +37 -0
  12. package/dist/app/http/Application.d.ts +1 -1
  13. package/dist/app/http/Application.js +36 -21
  14. package/dist/app/http/decorators.js +1 -0
  15. package/dist/constants.d.ts +2 -0
  16. package/dist/constants.js +3 -1
  17. package/dist/core/Controller.d.ts +6 -25
  18. package/dist/core/Controller.js +84 -118
  19. package/dist/core/Endpoint.js +1 -2
  20. package/dist/core/index.d.ts +1 -1
  21. package/dist/core/utils/index.d.ts +0 -2
  22. package/dist/core/utils/index.js +0 -2
  23. package/dist/examples/app.d.ts +0 -1
  24. package/dist/examples/app.js +70 -5
  25. package/dist/examples/controllers/user.js +44 -8
  26. package/dist/examples/controllers/userMetadata.d.ts +1 -1
  27. package/dist/examples/controllers/userMetadata.js +59 -9
  28. package/dist/middlewares/catch.d.ts +2 -0
  29. package/dist/middlewares/catch.js +10 -0
  30. package/dist/middlewares/cors.d.ts +2 -0
  31. package/dist/middlewares/cors.js +21 -0
  32. package/dist/middlewares/index.d.ts +5 -0
  33. package/dist/middlewares/index.js +21 -0
  34. package/dist/middlewares/sanitize.d.ts +2 -0
  35. package/dist/middlewares/sanitize.js +15 -0
  36. package/dist/{core/utils/helpers.js → middlewares/status.js} +1 -1
  37. package/dist/middlewares/use.d.ts +2 -0
  38. package/dist/middlewares/use.js +11 -0
  39. package/dist/types/common.d.ts +15 -32
  40. package/dist/types/controller.d.ts +7 -5
  41. package/dist/types/cors.d.ts +10 -0
  42. package/dist/types/cors.js +2 -0
  43. package/dist/types/http.d.ts +4 -0
  44. package/dist/types/index.d.ts +3 -0
  45. package/dist/types/index.js +3 -0
  46. package/dist/types/lambda.d.ts +7 -17
  47. package/dist/types/multipart.d.ts +8 -0
  48. package/dist/types/multipart.js +2 -0
  49. package/dist/types/sanitize.d.ts +8 -0
  50. package/dist/types/sanitize.js +2 -0
  51. package/dist/utils/controller.d.ts +27 -3
  52. package/dist/utils/controller.js +122 -23
  53. package/dist/utils/cors.d.ts +8 -0
  54. package/dist/utils/cors.js +127 -0
  55. package/dist/utils/headers.d.ts +2 -0
  56. package/dist/utils/headers.js +9 -0
  57. package/dist/utils/index.d.ts +3 -0
  58. package/dist/utils/index.js +3 -0
  59. package/dist/utils/multipart.d.ts +2 -8
  60. package/dist/utils/multipart.js +98 -2
  61. package/dist/utils/sanitize.d.ts +30 -0
  62. package/dist/utils/sanitize.js +134 -0
  63. package/dist/utils/server.js +5 -0
  64. package/package.json +9 -2
  65. package/dist/core/utils/middlewares.d.ts +0 -3
  66. package/dist/core/utils/middlewares.js +0 -22
  67. /package/dist/{core/utils/helpers.d.ts → middlewares/status.d.ts} +0 -0
package/README.md CHANGED
@@ -20,6 +20,7 @@ You can use controllers and server functionality by importing controllers and cr
20
20
  - `quantum-flow/http` - Main application source code for HTTP servers.
21
21
  - `quantum-flow/aws` - Main application source code AWS Lambda.
22
22
  - `quantum-flow/core` - Core framework components like Controller and Endpoint.
23
+ - `quantum-flow/middlewares` - Core middlewares to use within the application.
23
24
 
24
25
  ---
25
26
 
@@ -30,7 +31,6 @@ Use the `@Controller` decorator to define controllers with options such as prefi
30
31
  ```typescript
31
32
  import {
32
33
  Body,
33
- Catch,
34
34
  Controller,
35
35
  Headers,
36
36
  InjectWS,
@@ -41,9 +41,10 @@ import {
41
41
  Request,
42
42
  Response,
43
43
  Status,
44
- USE
44
+ USE,
45
45
  } from 'quantum-flow/core';
46
46
  import {IsString} from 'class-validator'
47
+ import { Catch, Cors, Sanitize, Use } from 'quantum-flow/middlewares';
47
48
 
48
49
  class UserDto {
49
50
  constructor() {}
@@ -54,14 +55,24 @@ class UserDto {
54
55
  @Controller({
55
56
  prefix: 'user',
56
57
  controllers: [UserMetadata, ...],
57
- interceptor: (data, req, res) => {
58
- return { data, intercepted: true };
59
- },
58
+ interceptor: (data, req, res) => data,
60
59
  })
60
+ @Cors({ origin: '*' })
61
61
  @Catch((err) => ({ status: 500, err }))
62
+ @Use(()=>{})
63
+ @Sanitize({
64
+ schema: Joi.object({
65
+ name: Joi.string().trim().min(2).max(50).required(),
66
+ }),
67
+ action: 'both',
68
+ options: { abortEarly: false },
69
+ stripUnknown: true,
70
+ type: 'body',
71
+ })
62
72
  export class User {
63
73
  @Status(201)
64
- @PUT(':id',[...middlewares])
74
+ @PUT(':id',[(req, res)=>{} , ...middlewares])
75
+ @Cors({ origin: '*' })
65
76
  async createUser(
66
77
  @Body(UserDto) body: UserDto,
67
78
  @Query() query: any,
@@ -84,7 +95,7 @@ export class User {
84
95
  prefix: 'api',
85
96
  controllers: [UserController, SocketController],
86
97
  middelwares: [...middlewares],
87
- interceptor: (parsedRequest, httpRequest, httpResponse) => parsedRequest,
98
+ interceptor: (data, req, res) => data,
88
99
  })
89
100
  @Catch((error) => ({ status: 400, error }))
90
101
  class RootController {}
@@ -97,11 +108,10 @@ Use the `@Server` decorator with configuration options like port, host, controll
97
108
  ```typescript
98
109
  import { Server, Port, Host, Use, Catch, HttpServer } from 'quantum-flow/http';
99
110
 
100
- @Server({ controllers: [RootController] })
111
+ @Server({ controllers: [RootController], cors: { origin: '*' } })
101
112
  @Port(3000)
102
113
  @Host('localhost')
103
114
  @Use((data) => data)
104
- @Use((data) => data)
105
115
  @Catch((error) => ({ status: 400, error }))
106
116
  class App {}
107
117
 
@@ -115,6 +125,8 @@ server.listen().catch(console.error);
115
125
  - Use `@Use` to apply middlewares.
116
126
  - Use `@Catch` to handle errors.
117
127
  - Use `@Port` and `@Host` to configure server port and host.
128
+ - Use `@Cors` to configure cors.
129
+ - Use `@Sanitize` to apply sanitization to reqest.
118
130
 
119
131
  ## Request decorators
120
132
 
@@ -160,8 +172,6 @@ Enable WebSocket in the server configuration and register WebSocket controllers.
160
172
  export class Socket {
161
173
  @OnConnection()
162
174
  onConnection(event: WebSocketEvent) {
163
- console.log(`✅ Connected: ${event.client.id}`);
164
-
165
175
  // Send greeting ONLY to this client
166
176
  event.client.socket.send(
167
177
  JSON.stringify({
@@ -181,8 +191,6 @@ export class Socket {
181
191
  // The message is ALREADY automatically broadcast to all!
182
192
 
183
193
  const msg = event.message?.data;
184
- console.log(`💬 Message in chat: ${msg?.text}`);
185
-
186
194
  // You can add logic, but no need to broadcast
187
195
  if (msg?.text.includes('bad')) {
188
196
  // If return empty, the message will not be sent
@@ -197,7 +205,6 @@ export class Socket {
197
205
  */
198
206
  @Subscribe('news')
199
207
  onNewsMessage(event: WebSocketEvent) {
200
- console.log(`📰 News: ${event.message?.data.title}`);
201
208
  // Automatic broadcast to all subscribed to 'news'
202
209
  }
203
210
 
@@ -221,7 +228,6 @@ export class Socket {
221
228
  @OnMessage('subscribe')
222
229
  onSubscribe(event: WebSocketEvent) {
223
230
  const topic = event.message?.data.topic;
224
- console.log(`📌 Client ${event.client.id} subscribed to ${topic}`);
225
231
 
226
232
  // Server will save the subscription automatically, no need to do anything!
227
233
  // Just confirm
@@ -241,6 +247,7 @@ export class Socket {
241
247
  ### Use
242
248
 
243
249
  Class decorator to add global middlewares to the server.
250
+ Should be used only with @Server decorator
244
251
 
245
252
  ```typescript
246
253
  @Use(middleware)
@@ -2,9 +2,6 @@ import { LambdaApp } from '../../types/index.js';
2
2
  import { Handler } from 'aws-lambda';
3
3
  export declare class LambdaAdapter {
4
4
  static createHandler(Controller: new (...args: any[]) => LambdaApp): Handler;
5
- private static getEventType;
6
- private static toRequest;
7
5
  private static toLambdaResponse;
8
6
  private static handleError;
9
- private static getSourceIp;
10
7
  }
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LambdaAdapter = void 0;
4
+ const _constants_1 = require("../../constants.js");
4
5
  const _utils_1 = require("../../utils/index.js");
6
+ const utils_1 = require("./utils");
5
7
  class LambdaAdapter {
6
8
  static createHandler(Controller) {
7
9
  return async (event, context) => {
@@ -9,112 +11,39 @@ class LambdaAdapter {
9
11
  if (Object.hasOwn(instance, 'beforeStart')) {
10
12
  await instance.beforeStart?.();
11
13
  }
14
+ const eventType = (0, utils_1.getEventType)(event);
12
15
  try {
13
- const eventType = this.getEventType(event);
14
- const normalizedEvent = (0, _utils_1.normalizeEvent)(event, eventType);
15
- const request = this.toRequest(normalizedEvent, context);
16
+ const cors = Reflect.getMetadata(_constants_1.CORS_METADATA, instance);
17
+ const request = new utils_1.LRequest(event, context);
18
+ const response = new utils_1.LResponse();
19
+ let handledCors = { permitted: true, continue: true };
20
+ if (cors) {
21
+ handledCors = (0, _utils_1.handleCORS)(request, response, cors);
22
+ }
23
+ if (!handledCors.permitted) {
24
+ return this.toLambdaResponse({ status: 403, message: 'Cors: Origin not allowed' }, request, response, eventType);
25
+ }
26
+ if (!handledCors.continue && handledCors.permitted) {
27
+ return this.toLambdaResponse({ status: 204 }, request, response, eventType);
28
+ }
16
29
  if (typeof instance.handleRequest !== 'function') {
17
30
  throw new Error('Controller must have handleRequest method');
18
31
  }
19
- const response = await instance.handleRequest(request);
20
- return this.toLambdaResponse(response, request, eventType);
32
+ const data = await instance.handleRequest(request, response);
33
+ return this.toLambdaResponse(data, request, response, eventType);
21
34
  }
22
35
  catch (error) {
23
36
  return this.handleError(error, event, context);
24
37
  }
25
38
  };
26
39
  }
27
- static getEventType(event) {
28
- if (event.httpMethod && event.resource) {
29
- return 'rest';
30
- }
31
- if (event.version === '2.0' || event.requestContext?.http) {
32
- return 'http';
33
- }
34
- if (event.version && event.rawPath && !event.requestContext?.http) {
35
- return 'url';
36
- }
37
- return 'rest';
38
- }
39
- static toRequest(event, context) {
40
- const query = {};
41
- if (event.multiValueQueryStringParameters) {
42
- Object.entries(event.multiValueQueryStringParameters).forEach(([key, value]) => {
43
- query[key] = value;
44
- });
45
- }
46
- else {
47
- Object.entries(event.queryStringParameters).forEach(([key, value]) => {
48
- query[key] = value;
49
- });
50
- }
51
- const cookies = {};
52
- const cookieHeader = event.headers?.Cookie || event.headers?.cookie || event.headers?.cookies;
53
- if (cookieHeader) {
54
- if (Array.isArray(cookieHeader)) {
55
- cookieHeader.forEach((cookie) => {
56
- const [name, value] = cookie.split('=');
57
- if (name && value)
58
- cookies[name] = decodeURIComponent(value);
59
- });
60
- }
61
- else {
62
- cookieHeader.split(';').forEach((cookie) => {
63
- const [name, value] = cookie.trim().split('=');
64
- if (name && value)
65
- cookies[name] = decodeURIComponent(value);
66
- });
67
- }
68
- }
69
- let rawBody = Buffer.from(event.body ?? '', 'base64');
70
- let body = event.body || {};
71
- if (event.body && event.isBase64Encoded) {
72
- body = rawBody.toString('utf-8');
73
- }
74
- if (typeof body === 'string' && body.trim().startsWith('{')) {
75
- try {
76
- body = JSON.parse(body);
77
- }
78
- catch (e) { }
79
- }
80
- const xForvarded = Array.isArray(event.headers['x-forwarded-proto'])
81
- ? event.headers['x-forwarded-proto']?.[0]
82
- : event.headers['x-forwarded-proto'];
83
- const xhost = Array.isArray(event.headers['host'])
84
- ? event.headers['host']?.[0]
85
- : event.headers['host'];
86
- const protocol = xForvarded || 'https';
87
- const host = xhost || 'localhost:3000';
88
- const fullUrl = `${protocol}://${host}${event.path}`;
89
- let url = new URL(fullUrl);
90
- return {
91
- method: event.httpMethod.toUpperCase(),
92
- url,
93
- headers: event.headers,
94
- query,
95
- body,
96
- params: event.pathParameters,
97
- cookies,
98
- event,
99
- context,
100
- rawBody,
101
- path: event.path,
102
- isBase64Encoded: event.isBase64Encoded,
103
- requestId: context.awsRequestId,
104
- stage: event.requestContext?.stage || '$default',
105
- sourceIp: this.getSourceIp(event),
106
- _startTime: Date.now(),
107
- userAgent: typeof event.headers['user-agent'] === 'string'
108
- ? event.headers['user-agent']
109
- : event.headers['user-agent']?.[0] || 'unknown',
110
- };
111
- }
112
- static toLambdaResponse(response, request, eventType) {
113
- const statusCode = response.status || 200;
40
+ static toLambdaResponse(data, request, response, eventType) {
41
+ const statusCode = data.status || 200;
114
42
  const headers = {
115
43
  'Content-Type': 'application/json',
116
44
  'X-Request-Id': request.requestId,
117
- ...(response.headers || {}),
45
+ ...(data.headers || {}),
46
+ ...response.headers,
118
47
  };
119
48
  const originHeader = request.headers['origin'] || request.headers['Origin'];
120
49
  let origin;
@@ -135,13 +64,13 @@ class LambdaAdapter {
135
64
  }
136
65
  const body = JSON.stringify({
137
66
  success: statusCode < 400,
138
- data: response.data,
67
+ data: data.data ?? data.error,
139
68
  timestamp: new Date().toISOString(),
140
69
  });
141
70
  const commonResponse = {
142
71
  statusCode,
143
72
  headers,
144
- body: response.data,
73
+ body: data.data ?? data.error,
145
74
  timestamp: new Date().toISOString(),
146
75
  };
147
76
  switch (eventType) {
@@ -170,7 +99,7 @@ class LambdaAdapter {
170
99
  }
171
100
  }
172
101
  static handleError(error, event, context) {
173
- const eventType = this.getEventType(event);
102
+ const eventType = (0, utils_1.getEventType)(event);
174
103
  const statusCode = error.status || 500;
175
104
  const body = JSON.stringify({
176
105
  success: false,
@@ -199,21 +128,5 @@ class LambdaAdapter {
199
128
  };
200
129
  }
201
130
  }
202
- static getSourceIp(event) {
203
- const forwardedFor = event.headers['x-forwarded-for'];
204
- if (forwardedFor) {
205
- if (Array.isArray(forwardedFor)) {
206
- return forwardedFor[0].split(',')[0].trim();
207
- }
208
- return forwardedFor.split(',')[0].trim();
209
- }
210
- if (event.requestContext?.identity?.sourceIp) {
211
- return event.requestContext.identity.sourceIp;
212
- }
213
- if (event.requestContext?.http?.sourceIp) {
214
- return event.requestContext.http.sourceIp;
215
- }
216
- return '0.0.0.0';
217
- }
218
131
  }
219
132
  exports.LambdaAdapter = LambdaAdapter;
@@ -0,0 +1,4 @@
1
+ import { NormalizedEvent } from '../../../types/index.js';
2
+ export declare const getEventType: (event: any) => "rest" | "http" | "url";
3
+ export declare const getSourceIp: (event: NormalizedEvent) => string;
4
+ export declare const normalizeEvent: (event: any, type: string) => NormalizedEvent;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeEvent = exports.getSourceIp = exports.getEventType = void 0;
4
+ const getEventType = (event) => {
5
+ if (event.httpMethod && event.resource) {
6
+ return 'rest';
7
+ }
8
+ if (event.version === '2.0' || event.requestContext?.http) {
9
+ return 'http';
10
+ }
11
+ if (event.version && event.rawPath && !event.requestContext?.http) {
12
+ return 'url';
13
+ }
14
+ return 'rest';
15
+ };
16
+ exports.getEventType = getEventType;
17
+ const getSourceIp = (event) => {
18
+ const forwardedFor = event.headers['x-forwarded-for'];
19
+ if (forwardedFor) {
20
+ if (Array.isArray(forwardedFor)) {
21
+ return forwardedFor[0].split(',')[0].trim();
22
+ }
23
+ return forwardedFor.split(',')[0].trim();
24
+ }
25
+ if (event.requestContext?.identity?.sourceIp) {
26
+ return event.requestContext.identity.sourceIp;
27
+ }
28
+ if (event.requestContext?.http?.sourceIp) {
29
+ return event.requestContext.http.sourceIp;
30
+ }
31
+ return '0.0.0.0';
32
+ };
33
+ exports.getSourceIp = getSourceIp;
34
+ const parseQueryString = (queryString) => {
35
+ const params = {};
36
+ if (!queryString)
37
+ return params;
38
+ new URLSearchParams(queryString).forEach((value, key) => {
39
+ params[key] = value;
40
+ });
41
+ return params;
42
+ };
43
+ const normalizeEvent = (event, type) => {
44
+ const base = {
45
+ headers: event.headers || {},
46
+ body: event.body || null,
47
+ isBase64Encoded: event.isBase64Encoded || false,
48
+ requestContext: event.requestContext,
49
+ };
50
+ switch (type) {
51
+ case 'rest':
52
+ return {
53
+ ...base,
54
+ httpMethod: event.httpMethod,
55
+ path: event.path,
56
+ queryStringParameters: event.queryStringParameters || {},
57
+ multiValueQueryStringParameters: event.multiValueQueryStringParameters,
58
+ pathParameters: event.pathParameters || {},
59
+ cookies: event.headers?.Cookie ? [event.headers.Cookie] : [],
60
+ };
61
+ case 'http':
62
+ return {
63
+ ...base,
64
+ httpMethod: event.requestContext?.http?.method || 'GET',
65
+ path: event.rawPath,
66
+ queryStringParameters: event.queryStringParameters || {},
67
+ pathParameters: event.pathParameters || {},
68
+ cookies: event.cookies || [],
69
+ };
70
+ case 'url':
71
+ return {
72
+ ...base,
73
+ httpMethod: event.requestContext?.http?.method || 'GET',
74
+ path: event.rawPath,
75
+ queryStringParameters: parseQueryString(event.rawQueryString),
76
+ pathParameters: {},
77
+ cookies: [],
78
+ };
79
+ default:
80
+ throw new Error(`Unsupported event type: ${type}`);
81
+ }
82
+ };
83
+ exports.normalizeEvent = normalizeEvent;
@@ -0,0 +1,3 @@
1
+ export * from './helpers';
2
+ export * from './request';
3
+ export * from './response';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./helpers"), exports);
18
+ __exportStar(require("./request"), exports);
19
+ __exportStar(require("./response"), exports);
@@ -0,0 +1,23 @@
1
+ import { HTTP_METHODS, LambdaEvent, MultipartFile } from '../../../types/index.js';
2
+ import { Context } from 'aws-lambda';
3
+ export declare class LRequest {
4
+ requestUrl: URL;
5
+ method: HTTP_METHODS;
6
+ path?: string;
7
+ headers: Record<string, string | string[]>;
8
+ query?: Record<string, string | string[]>;
9
+ params?: Record<string, string>;
10
+ body: any;
11
+ rawBody: Buffer<ArrayBufferLike>;
12
+ isBase64Encoded?: boolean;
13
+ cookies: Record<string, string>;
14
+ multipart?: Record<string, MultipartFile | MultipartFile[]>;
15
+ _startTime: number;
16
+ url: string;
17
+ requestId: string;
18
+ stage?: string;
19
+ userAgent: string;
20
+ sourceIp: string;
21
+ constructor(lambdaEvent: LambdaEvent, context: Context);
22
+ end(): void;
23
+ }
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LRequest = void 0;
4
+ const helpers_1 = require("./helpers");
5
+ class LRequest {
6
+ requestUrl;
7
+ method;
8
+ path;
9
+ headers;
10
+ query;
11
+ params;
12
+ body;
13
+ rawBody;
14
+ isBase64Encoded;
15
+ cookies;
16
+ multipart;
17
+ _startTime;
18
+ url;
19
+ requestId;
20
+ stage;
21
+ userAgent;
22
+ sourceIp;
23
+ constructor(lambdaEvent, context) {
24
+ const event = (0, helpers_1.normalizeEvent)(lambdaEvent, (0, helpers_1.getEventType)(lambdaEvent));
25
+ const query = {};
26
+ if (event.multiValueQueryStringParameters) {
27
+ Object.entries(event.multiValueQueryStringParameters).forEach(([key, value]) => {
28
+ query[key] = value;
29
+ });
30
+ }
31
+ else {
32
+ Object.entries(event.queryStringParameters).forEach(([key, value]) => {
33
+ query[key] = value;
34
+ });
35
+ }
36
+ const cookies = {};
37
+ const cookieHeader = event.headers?.Cookie || event.headers?.cookie || event.headers?.cookies;
38
+ if (cookieHeader) {
39
+ if (Array.isArray(cookieHeader)) {
40
+ cookieHeader.forEach((cookie) => {
41
+ const [name, value] = cookie.split('=');
42
+ if (name && value)
43
+ cookies[name] = decodeURIComponent(value);
44
+ });
45
+ }
46
+ else {
47
+ cookieHeader.split(';').forEach((cookie) => {
48
+ const [name, value] = cookie.trim().split('=');
49
+ if (name && value)
50
+ cookies[name] = decodeURIComponent(value);
51
+ });
52
+ }
53
+ }
54
+ let rawBody = Buffer.from(event.body ?? '', 'base64');
55
+ let body = event.body || {};
56
+ if (event.body && event.isBase64Encoded) {
57
+ body = rawBody.toString('utf-8');
58
+ }
59
+ if (typeof body === 'string' && body.trim().startsWith('{')) {
60
+ try {
61
+ body = JSON.parse(body);
62
+ }
63
+ catch (e) { }
64
+ }
65
+ const xForvarded = Array.isArray(event.headers['x-forwarded-proto'])
66
+ ? event.headers['x-forwarded-proto']?.[0]
67
+ : event.headers['x-forwarded-proto'];
68
+ const xhost = Array.isArray(event.headers['host'])
69
+ ? event.headers['host']?.[0]
70
+ : event.headers['host'];
71
+ const protocol = xForvarded || 'https';
72
+ const host = xhost || 'localhost:3000';
73
+ const fullUrl = `${protocol}://${host}${event.path}`;
74
+ let url = new URL(fullUrl);
75
+ this.method = event.httpMethod.toUpperCase();
76
+ this.url = fullUrl;
77
+ this.headers = event.headers;
78
+ this.cookies = cookies;
79
+ this.params = event.pathParameters;
80
+ this.rawBody = rawBody;
81
+ this.path = event.path;
82
+ this.isBase64Encoded = event.isBase64Encoded;
83
+ this.requestId = context.awsRequestId;
84
+ this.requestUrl = url;
85
+ this.stage = event.requestContext?.stage || '$default';
86
+ this.sourceIp = (0, helpers_1.getSourceIp)(event);
87
+ this.userAgent =
88
+ typeof event.headers['user-agent'] === 'string'
89
+ ? event.headers['user-agent']
90
+ : event.headers['user-agent']?.[0] || 'unknown';
91
+ }
92
+ end() {
93
+ console.log('NOT implemented for lambda');
94
+ }
95
+ }
96
+ exports.LRequest = LRequest;
@@ -0,0 +1,14 @@
1
+ import { ServerResponse } from 'http';
2
+ export declare class LResponse {
3
+ private originalResponse?;
4
+ private _statusCode;
5
+ private _headers;
6
+ private _body;
7
+ constructor(originalResponse?: ServerResponse | undefined);
8
+ setHeader(name: string, value: string): void;
9
+ set statusCode(code: number);
10
+ get statusCode(): number;
11
+ get headers(): Record<string, string>;
12
+ send(): void;
13
+ get original(): ServerResponse | undefined;
14
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LResponse = void 0;
4
+ class LResponse {
5
+ originalResponse;
6
+ _statusCode = 200;
7
+ _headers = {};
8
+ _body = null;
9
+ constructor(originalResponse) {
10
+ this.originalResponse = originalResponse;
11
+ }
12
+ setHeader(name, value) {
13
+ this._headers[name] = value;
14
+ if (this.originalResponse) {
15
+ this.originalResponse.setHeader(name, value);
16
+ }
17
+ }
18
+ set statusCode(code) {
19
+ this._statusCode = code;
20
+ if (this.originalResponse) {
21
+ this.originalResponse.statusCode = code;
22
+ }
23
+ }
24
+ get statusCode() {
25
+ return this._statusCode;
26
+ }
27
+ get headers() {
28
+ return { ...this._headers };
29
+ }
30
+ send() {
31
+ throw `Lambda response doesn't have "send" method`;
32
+ }
33
+ get original() {
34
+ return this.originalResponse;
35
+ }
36
+ }
37
+ exports.LResponse = LResponse;
@@ -15,7 +15,7 @@ export declare class HttpServer extends Socket {
15
15
  };
16
16
  private requestHandler;
17
17
  private createRequest;
18
- private applyMiddlewares;
18
+ private beforeRequest;
19
19
  private findController;
20
20
  private sendResponse;
21
21
  private handleError;