@noony-serverless/core 0.1.1 → 0.2.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 (62) hide show
  1. package/build/core/core.d.ts +16 -48
  2. package/build/core/core.js +2 -61
  3. package/build/core/handler.d.ts +37 -16
  4. package/build/core/handler.js +131 -42
  5. package/build/core/index.d.ts +0 -1
  6. package/build/core/index.js +0 -1
  7. package/build/middlewares/ConsolidatedValidationMiddleware.d.ts +126 -0
  8. package/build/middlewares/ConsolidatedValidationMiddleware.js +330 -0
  9. package/build/middlewares/ProcessingMiddleware.d.ts +138 -0
  10. package/build/middlewares/ProcessingMiddleware.js +425 -0
  11. package/build/middlewares/SecurityMiddleware.d.ts +157 -0
  12. package/build/middlewares/SecurityMiddleware.js +307 -0
  13. package/build/middlewares/authenticationMiddleware.d.ts +379 -0
  14. package/build/middlewares/authenticationMiddleware.js +216 -0
  15. package/build/middlewares/bodyParserMiddleware.d.ts +99 -0
  16. package/build/middlewares/bodyParserMiddleware.js +99 -0
  17. package/build/middlewares/bodyValidationMiddleware.d.ts +69 -3
  18. package/build/middlewares/bodyValidationMiddleware.js +68 -2
  19. package/build/middlewares/dependencyInjectionMiddleware.d.ts +238 -0
  20. package/build/middlewares/dependencyInjectionMiddleware.js +238 -0
  21. package/build/middlewares/errorHandlerMiddleware.d.ts +94 -0
  22. package/build/middlewares/errorHandlerMiddleware.js +105 -0
  23. package/build/middlewares/guards/RouteGuards.d.ts +476 -21
  24. package/build/middlewares/guards/RouteGuards.js +418 -21
  25. package/build/middlewares/guards/adapters/CustomTokenVerificationPortAdapter.d.ts +271 -0
  26. package/build/middlewares/guards/adapters/CustomTokenVerificationPortAdapter.js +301 -0
  27. package/build/middlewares/guards/cache/CacheAdapter.d.ts +369 -28
  28. package/build/middlewares/guards/cache/CacheAdapter.js +124 -5
  29. package/build/middlewares/guards/cache/MemoryCacheAdapter.d.ts +113 -4
  30. package/build/middlewares/guards/cache/MemoryCacheAdapter.js +113 -4
  31. package/build/middlewares/guards/config/GuardConfiguration.d.ts +568 -18
  32. package/build/middlewares/guards/config/GuardConfiguration.js +266 -10
  33. package/build/middlewares/guards/guards/FastAuthGuard.d.ts +5 -5
  34. package/build/middlewares/guards/guards/PermissionGuardFactory.d.ts +5 -13
  35. package/build/middlewares/guards/guards/PermissionGuardFactory.js +4 -4
  36. package/build/middlewares/guards/index.d.ts +43 -1
  37. package/build/middlewares/guards/index.js +46 -1
  38. package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.d.ts +1 -1
  39. package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.js +1 -1
  40. package/build/middlewares/guards/resolvers/PermissionResolver.d.ts +1 -1
  41. package/build/middlewares/guards/resolvers/PlainPermissionResolver.d.ts +1 -1
  42. package/build/middlewares/guards/resolvers/WildcardPermissionResolver.d.ts +1 -1
  43. package/build/middlewares/guards/services/FastUserContextService.d.ts +20 -33
  44. package/build/middlewares/guards/services/FastUserContextService.js +19 -5
  45. package/build/middlewares/headerVariablesMiddleware.d.ts +118 -0
  46. package/build/middlewares/headerVariablesMiddleware.js +118 -0
  47. package/build/middlewares/httpAttributesMiddleware.d.ts +235 -0
  48. package/build/middlewares/httpAttributesMiddleware.js +236 -1
  49. package/build/middlewares/index.d.ts +3 -1
  50. package/build/middlewares/index.js +6 -1
  51. package/build/middlewares/queryParametersMiddleware.d.ts +105 -0
  52. package/build/middlewares/queryParametersMiddleware.js +105 -0
  53. package/build/middlewares/rateLimitingMiddleware.d.ts +601 -9
  54. package/build/middlewares/rateLimitingMiddleware.js +623 -11
  55. package/build/middlewares/responseWrapperMiddleware.d.ts +170 -1
  56. package/build/middlewares/responseWrapperMiddleware.js +170 -1
  57. package/build/middlewares/securityAuditMiddleware.js +5 -5
  58. package/package.json +11 -9
  59. package/build/core/containerPool.d.ts +0 -44
  60. package/build/core/containerPool.js +0 -103
  61. package/build/middlewares/validationMiddleware.d.ts +0 -9
  62. package/build/middlewares/validationMiddleware.js +0 -40
@@ -1,11 +1,180 @@
1
1
  import { BaseMiddleware } from '../core/handler';
2
2
  import { Context } from '../core/core';
3
+ /**
4
+ * Middleware class that wraps response data in a standardized format.
5
+ * Automatically wraps the response with success flag, payload, and timestamp.
6
+ *
7
+ * @template T - The type of response data being wrapped
8
+ * @implements {BaseMiddleware}
9
+ *
10
+ * @example
11
+ * Basic response wrapping:
12
+ * ```typescript
13
+ * import { Handler, ResponseWrapperMiddleware, setResponseData } from '@noony-serverless/core';
14
+ *
15
+ * interface UserResponse {
16
+ * id: string;
17
+ * name: string;
18
+ * email: string;
19
+ * }
20
+ *
21
+ * const getUserHandler = new Handler()
22
+ * .use(new ResponseWrapperMiddleware<UserResponse>())
23
+ * .handle(async (context) => {
24
+ * const user = await getUser(context.params.id);
25
+ * setResponseData(context, user);
26
+ * // Response will be: { success: true, payload: user, timestamp: "..." }
27
+ * });
28
+ * ```
29
+ *
30
+ * @example
31
+ * API response with metadata:
32
+ * ```typescript
33
+ * interface ApiResponse {
34
+ * items: any[];
35
+ * pagination: { page: number; total: number };
36
+ * }
37
+ *
38
+ * const listItemsHandler = new Handler()
39
+ * .use(new ResponseWrapperMiddleware<ApiResponse>())
40
+ * .handle(async (context) => {
41
+ * const items = await getItems();
42
+ * const response: ApiResponse = {
43
+ * items,
44
+ * pagination: { page: 1, total: items.length }
45
+ * };
46
+ * setResponseData(context, response);
47
+ * });
48
+ * ```
49
+ *
50
+ * @example
51
+ * Combination with error handling:
52
+ * ```typescript
53
+ * const secureHandler = new Handler()
54
+ * .use(new AuthenticationMiddleware())
55
+ * .use(new ResponseWrapperMiddleware<any>())
56
+ * .use(new ErrorHandlerMiddleware())
57
+ * .handle(async (context) => {
58
+ * const data = await getSecureData(context.user.id);
59
+ * setResponseData(context, data);
60
+ * });
61
+ * ```
62
+ */
3
63
  export declare class ResponseWrapperMiddleware<T> implements BaseMiddleware {
4
64
  after(context: Context): Promise<void>;
5
65
  }
66
+ /**
67
+ * Factory function that creates a response wrapper middleware.
68
+ * Automatically wraps response data in a standardized format with success flag and timestamp.
69
+ *
70
+ * @template T - The type of response data being wrapped
71
+ * @returns BaseMiddleware object with response wrapping logic
72
+ *
73
+ * @example
74
+ * Simple API endpoint:
75
+ * ```typescript
76
+ * import { Handler, responseWrapperMiddleware, setResponseData } from '@noony-serverless/core';
77
+ *
78
+ * const healthCheckHandler = new Handler()
79
+ * .use(responseWrapperMiddleware<{ status: string; uptime: number }>())
80
+ * .handle(async (context) => {
81
+ * setResponseData(context, {
82
+ * status: 'healthy',
83
+ * uptime: process.uptime()
84
+ * });
85
+ * // Response: { success: true, payload: { status: "healthy", uptime: 12345 }, timestamp: "..." }
86
+ * });
87
+ * ```
88
+ *
89
+ * @example
90
+ * RESTful CRUD operations:
91
+ * ```typescript
92
+ * const createUserHandler = new Handler()
93
+ * .use(bodyParser())
94
+ * .use(responseWrapperMiddleware<{ id: string; message: string }>())
95
+ * .handle(async (context) => {
96
+ * const userData = context.req.parsedBody;
97
+ * const newUser = await createUser(userData);
98
+ * setResponseData(context, {
99
+ * id: newUser.id,
100
+ * message: 'User created successfully'
101
+ * });
102
+ * });
103
+ * ```
104
+ *
105
+ * @example
106
+ * Microservice communication:
107
+ * ```typescript
108
+ * const orderProcessingHandler = new Handler()
109
+ * .use(authenticationMiddleware)
110
+ * .use(responseWrapperMiddleware<{ orderId: string; status: string; estimatedDelivery: string }>())
111
+ * .handle(async (context) => {
112
+ * const order = await processOrder(context.req.parsedBody);
113
+ * setResponseData(context, {
114
+ * orderId: order.id,
115
+ * status: order.status,
116
+ * estimatedDelivery: order.estimatedDelivery
117
+ * });
118
+ * });
119
+ * ```
120
+ */
6
121
  export declare const responseWrapperMiddleware: <T>() => BaseMiddleware;
7
122
  /**
8
- * Helper function to set response data in context for later wrapping
123
+ * Helper function to set response data in context for later wrapping.
124
+ * This function should be used in handlers when using ResponseWrapperMiddleware.
125
+ *
126
+ * @template T - The type of data being set
127
+ * @param context - The request context
128
+ * @param data - The data to be included in the response payload
129
+ *
130
+ * @example
131
+ * Setting simple response data:
132
+ * ```typescript
133
+ * import { setResponseData } from '@noony-serverless/core';
134
+ *
135
+ * const handler = new Handler()
136
+ * .use(responseWrapperMiddleware())
137
+ * .handle(async (context) => {
138
+ * const message = "Hello, World!";
139
+ * setResponseData(context, { message, timestamp: new Date().toISOString() });
140
+ * });
141
+ * ```
142
+ *
143
+ * @example
144
+ * Setting complex response data:
145
+ * ```typescript
146
+ * const dashboardHandler = new Handler()
147
+ * .use(responseWrapperMiddleware())
148
+ * .handle(async (context) => {
149
+ * const stats = await getDashboardStats(context.user.id);
150
+ * const notifications = await getNotifications(context.user.id);
151
+ *
152
+ * setResponseData(context, {
153
+ * user: context.user,
154
+ * stats,
155
+ * notifications,
156
+ * lastLogin: new Date().toISOString()
157
+ * });
158
+ * });
159
+ * ```
160
+ *
161
+ * @example
162
+ * Conditional response data:
163
+ * ```typescript
164
+ * const userProfileHandler = new Handler()
165
+ * .use(responseWrapperMiddleware())
166
+ * .handle(async (context) => {
167
+ * const userId = context.params.id;
168
+ * const user = await getUser(userId);
169
+ *
170
+ * if (user) {
171
+ * setResponseData(context, { user, found: true });
172
+ * } else {
173
+ * context.res.status(404);
174
+ * setResponseData(context, { message: 'User not found', found: false });
175
+ * }
176
+ * });
177
+ * ```
9
178
  */
10
179
  export declare function setResponseData<T>(context: Context, data: T): void;
11
180
  //# sourceMappingURL=responseWrapperMiddleware.d.ts.map
@@ -13,12 +13,127 @@ const wrapResponse = (context) => {
13
13
  });
14
14
  }
15
15
  };
16
+ /**
17
+ * Middleware class that wraps response data in a standardized format.
18
+ * Automatically wraps the response with success flag, payload, and timestamp.
19
+ *
20
+ * @template T - The type of response data being wrapped
21
+ * @implements {BaseMiddleware}
22
+ *
23
+ * @example
24
+ * Basic response wrapping:
25
+ * ```typescript
26
+ * import { Handler, ResponseWrapperMiddleware, setResponseData } from '@noony-serverless/core';
27
+ *
28
+ * interface UserResponse {
29
+ * id: string;
30
+ * name: string;
31
+ * email: string;
32
+ * }
33
+ *
34
+ * const getUserHandler = new Handler()
35
+ * .use(new ResponseWrapperMiddleware<UserResponse>())
36
+ * .handle(async (context) => {
37
+ * const user = await getUser(context.params.id);
38
+ * setResponseData(context, user);
39
+ * // Response will be: { success: true, payload: user, timestamp: "..." }
40
+ * });
41
+ * ```
42
+ *
43
+ * @example
44
+ * API response with metadata:
45
+ * ```typescript
46
+ * interface ApiResponse {
47
+ * items: any[];
48
+ * pagination: { page: number; total: number };
49
+ * }
50
+ *
51
+ * const listItemsHandler = new Handler()
52
+ * .use(new ResponseWrapperMiddleware<ApiResponse>())
53
+ * .handle(async (context) => {
54
+ * const items = await getItems();
55
+ * const response: ApiResponse = {
56
+ * items,
57
+ * pagination: { page: 1, total: items.length }
58
+ * };
59
+ * setResponseData(context, response);
60
+ * });
61
+ * ```
62
+ *
63
+ * @example
64
+ * Combination with error handling:
65
+ * ```typescript
66
+ * const secureHandler = new Handler()
67
+ * .use(new AuthenticationMiddleware())
68
+ * .use(new ResponseWrapperMiddleware<any>())
69
+ * .use(new ErrorHandlerMiddleware())
70
+ * .handle(async (context) => {
71
+ * const data = await getSecureData(context.user.id);
72
+ * setResponseData(context, data);
73
+ * });
74
+ * ```
75
+ */
16
76
  class ResponseWrapperMiddleware {
17
77
  async after(context) {
18
78
  wrapResponse(context);
19
79
  }
20
80
  }
21
81
  exports.ResponseWrapperMiddleware = ResponseWrapperMiddleware;
82
+ /**
83
+ * Factory function that creates a response wrapper middleware.
84
+ * Automatically wraps response data in a standardized format with success flag and timestamp.
85
+ *
86
+ * @template T - The type of response data being wrapped
87
+ * @returns BaseMiddleware object with response wrapping logic
88
+ *
89
+ * @example
90
+ * Simple API endpoint:
91
+ * ```typescript
92
+ * import { Handler, responseWrapperMiddleware, setResponseData } from '@noony-serverless/core';
93
+ *
94
+ * const healthCheckHandler = new Handler()
95
+ * .use(responseWrapperMiddleware<{ status: string; uptime: number }>())
96
+ * .handle(async (context) => {
97
+ * setResponseData(context, {
98
+ * status: 'healthy',
99
+ * uptime: process.uptime()
100
+ * });
101
+ * // Response: { success: true, payload: { status: "healthy", uptime: 12345 }, timestamp: "..." }
102
+ * });
103
+ * ```
104
+ *
105
+ * @example
106
+ * RESTful CRUD operations:
107
+ * ```typescript
108
+ * const createUserHandler = new Handler()
109
+ * .use(bodyParser())
110
+ * .use(responseWrapperMiddleware<{ id: string; message: string }>())
111
+ * .handle(async (context) => {
112
+ * const userData = context.req.parsedBody;
113
+ * const newUser = await createUser(userData);
114
+ * setResponseData(context, {
115
+ * id: newUser.id,
116
+ * message: 'User created successfully'
117
+ * });
118
+ * });
119
+ * ```
120
+ *
121
+ * @example
122
+ * Microservice communication:
123
+ * ```typescript
124
+ * const orderProcessingHandler = new Handler()
125
+ * .use(authenticationMiddleware)
126
+ * .use(responseWrapperMiddleware<{ orderId: string; status: string; estimatedDelivery: string }>())
127
+ * .handle(async (context) => {
128
+ * const order = await processOrder(context.req.parsedBody);
129
+ * setResponseData(context, {
130
+ * orderId: order.id,
131
+ * status: order.status,
132
+ * estimatedDelivery: order.estimatedDelivery
133
+ * });
134
+ * });
135
+ * ```
136
+ */
22
137
  const responseWrapperMiddleware = () => ({
23
138
  after: async (context) => {
24
139
  wrapResponse(context);
@@ -26,7 +141,61 @@ const responseWrapperMiddleware = () => ({
26
141
  });
27
142
  exports.responseWrapperMiddleware = responseWrapperMiddleware;
28
143
  /**
29
- * Helper function to set response data in context for later wrapping
144
+ * Helper function to set response data in context for later wrapping.
145
+ * This function should be used in handlers when using ResponseWrapperMiddleware.
146
+ *
147
+ * @template T - The type of data being set
148
+ * @param context - The request context
149
+ * @param data - The data to be included in the response payload
150
+ *
151
+ * @example
152
+ * Setting simple response data:
153
+ * ```typescript
154
+ * import { setResponseData } from '@noony-serverless/core';
155
+ *
156
+ * const handler = new Handler()
157
+ * .use(responseWrapperMiddleware())
158
+ * .handle(async (context) => {
159
+ * const message = "Hello, World!";
160
+ * setResponseData(context, { message, timestamp: new Date().toISOString() });
161
+ * });
162
+ * ```
163
+ *
164
+ * @example
165
+ * Setting complex response data:
166
+ * ```typescript
167
+ * const dashboardHandler = new Handler()
168
+ * .use(responseWrapperMiddleware())
169
+ * .handle(async (context) => {
170
+ * const stats = await getDashboardStats(context.user.id);
171
+ * const notifications = await getNotifications(context.user.id);
172
+ *
173
+ * setResponseData(context, {
174
+ * user: context.user,
175
+ * stats,
176
+ * notifications,
177
+ * lastLogin: new Date().toISOString()
178
+ * });
179
+ * });
180
+ * ```
181
+ *
182
+ * @example
183
+ * Conditional response data:
184
+ * ```typescript
185
+ * const userProfileHandler = new Handler()
186
+ * .use(responseWrapperMiddleware())
187
+ * .handle(async (context) => {
188
+ * const userId = context.params.id;
189
+ * const user = await getUser(userId);
190
+ *
191
+ * if (user) {
192
+ * setResponseData(context, { user, found: true });
193
+ * } else {
194
+ * context.res.status(404);
195
+ * setResponseData(context, { message: 'User not found', found: false });
196
+ * }
197
+ * });
198
+ * ```
30
199
  */
31
200
  function setResponseData(context, data) {
32
201
  context.responseData = data;
@@ -161,15 +161,15 @@ class SecurityAuditMiddleware {
161
161
  options;
162
162
  constructor(options = {}) {
163
163
  this.options = {
164
- logRequests: false,
165
- logResponses: false,
166
- logBodies: false,
167
- maxBodyLogSize: 1024,
164
+ logRequests: options.logRequests ?? false,
165
+ logResponses: options.logResponses ?? false,
166
+ logBodies: options.logBodies ?? false,
167
+ maxBodyLogSize: options.maxBodyLogSize ?? 1024,
168
168
  excludeHeaders: [
169
169
  ...DEFAULT_EXCLUDE_HEADERS,
170
170
  ...(options.excludeHeaders || []),
171
171
  ],
172
- enableAnomalyDetection: true,
172
+ enableAnomalyDetection: options.enableAnomalyDetection ?? true,
173
173
  onSecurityEvent: options.onSecurityEvent,
174
174
  suspiciousPatterns: {
175
175
  ...DEFAULT_SUSPICIOUS_PATTERNS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noony-serverless/core",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "A Middy base framework compatible with Firebase and GCP Cloud Functions with TypeScript",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -40,17 +40,19 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@google-cloud/firestore": "^7.1.0",
43
- "@google-cloud/functions-framework": "^3.3.0",
43
+ "@google-cloud/functions-framework": "^4.0.0",
44
44
  "@google-cloud/pubsub": "^4.1.0",
45
- "@types/jsonwebtoken": "^9.0.8",
46
- "axios": "^1.7.9",
47
- "fastify": "^5.3.3",
48
- "firebase-admin": "^12.6.0",
49
- "firebase-functions": "^6.3.1",
45
+ "@types/jsonwebtoken": "^9.0.10",
46
+ "@types/qs": "^6.14.0",
47
+ "axios": "^1.11.0",
48
+ "fastify": "^5.6.0",
49
+ "firebase-admin": "^13.5.0",
50
+ "firebase-functions": "^6.4.0",
50
51
  "jsonwebtoken": "^9.0.2",
52
+ "qs": "^6.14.0",
51
53
  "reflect-metadata": "^0.2.2",
52
54
  "typedi": "^0.10.0",
53
- "zod": "^3.22.4"
55
+ "zod": "^4.1.5"
54
56
  },
55
57
  "devDependencies": {
56
58
  "@types/jest": "^29.5.11",
@@ -58,7 +60,7 @@
58
60
  "@types/node": "^20.10.5",
59
61
  "@typescript-eslint/eslint-plugin": "^6.15.0",
60
62
  "@typescript-eslint/parser": "^6.15.0",
61
- "concurrently": "^8.2.2",
63
+ "concurrently": "^9.2.1",
62
64
  "eslint": "^8.56.0",
63
65
  "eslint-config-prettier": "^9.1.0",
64
66
  "eslint-plugin-prettier": "^5.1.2",
@@ -1,44 +0,0 @@
1
- import Container from 'typedi';
2
- /**
3
- * Performance optimization: Container Pool for reusing TypeDI containers
4
- * This reduces object creation overhead and improves memory efficiency
5
- */
6
- declare class ContainerPool {
7
- private availableContainers;
8
- private maxPoolSize;
9
- private createdContainers;
10
- constructor(maxPoolSize?: number);
11
- /**
12
- * Get a container from the pool or create a new one
13
- */
14
- acquire(): Container;
15
- /**
16
- * Return a container to the pool for reuse
17
- */
18
- release(container: Container): void;
19
- /**
20
- * Reset container state to prevent cross-request contamination
21
- * Note: TypeDI containers are isolated by default, so we mainly need
22
- * to clear any manually set values
23
- */
24
- private resetContainer;
25
- /**
26
- * Get pool statistics for monitoring
27
- */
28
- getStats(): {
29
- available: number;
30
- created: number;
31
- maxSize: number;
32
- };
33
- /**
34
- * Warm up the pool by pre-creating containers
35
- */
36
- warmUp(count?: number): void;
37
- /**
38
- * Clear all containers from the pool
39
- */
40
- clear(): void;
41
- }
42
- declare const containerPool: ContainerPool;
43
- export { ContainerPool, containerPool };
44
- //# sourceMappingURL=containerPool.d.ts.map
@@ -1,103 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.containerPool = exports.ContainerPool = void 0;
7
- const typedi_1 = __importDefault(require("typedi"));
8
- /**
9
- * Performance optimization: Container Pool for reusing TypeDI containers
10
- * This reduces object creation overhead and improves memory efficiency
11
- */
12
- class ContainerPool {
13
- availableContainers = [];
14
- maxPoolSize = 10;
15
- createdContainers = 0;
16
- constructor(maxPoolSize = 10) {
17
- this.maxPoolSize = maxPoolSize;
18
- }
19
- /**
20
- * Get a container from the pool or create a new one
21
- */
22
- acquire() {
23
- if (this.availableContainers.length > 0) {
24
- return this.availableContainers.pop();
25
- }
26
- // Create new container if pool is empty and under limit
27
- if (this.createdContainers < this.maxPoolSize) {
28
- this.createdContainers++;
29
- return typedi_1.default.of();
30
- }
31
- // If pool is at capacity, create a temporary container
32
- // This should rarely happen in normal usage
33
- return typedi_1.default.of();
34
- }
35
- /**
36
- * Return a container to the pool for reuse
37
- */
38
- release(container) {
39
- if (this.availableContainers.length < this.maxPoolSize) {
40
- // Reset container state by removing all instances
41
- // This prevents memory leaks and cross-request contamination
42
- this.resetContainer(container);
43
- this.availableContainers.push(container);
44
- }
45
- // If pool is full, let the container be garbage collected
46
- }
47
- /**
48
- * Reset container state to prevent cross-request contamination
49
- * Note: TypeDI containers are isolated by default, so we mainly need
50
- * to clear any manually set values
51
- */
52
- resetContainer(_container) {
53
- try {
54
- // For TypeDI containers created with Container.of(), each container
55
- // is already isolated. We just need to ensure no memory leaks.
56
- // The container will be garbage collected when released from pool
57
- // if it contains too much data
58
- // TypeDI containers are self-contained and don't need explicit reset
59
- // This is a placeholder for future enhancements if needed
60
- }
61
- catch (error) {
62
- // If any issues occur, don't add back to pool
63
- console.warn('Failed to reset container, discarding:', error);
64
- }
65
- }
66
- /**
67
- * Get pool statistics for monitoring
68
- */
69
- getStats() {
70
- return {
71
- available: this.availableContainers.length,
72
- created: this.createdContainers,
73
- maxSize: this.maxPoolSize,
74
- };
75
- }
76
- /**
77
- * Warm up the pool by pre-creating containers
78
- */
79
- warmUp(count = 5) {
80
- const warmUpCount = Math.min(count, this.maxPoolSize);
81
- for (let i = 0; i < warmUpCount; i++) {
82
- if (this.createdContainers < this.maxPoolSize) {
83
- const container = typedi_1.default.of();
84
- this.createdContainers++;
85
- this.availableContainers.push(container);
86
- }
87
- }
88
- }
89
- /**
90
- * Clear all containers from the pool
91
- */
92
- clear() {
93
- this.availableContainers = [];
94
- this.createdContainers = 0;
95
- }
96
- }
97
- exports.ContainerPool = ContainerPool;
98
- // Global container pool instance
99
- const containerPool = new ContainerPool(15); // Slightly higher limit for serverless
100
- exports.containerPool = containerPool;
101
- // Warm up the pool for better cold start performance
102
- containerPool.warmUp(3);
103
- //# sourceMappingURL=containerPool.js.map
@@ -1,9 +0,0 @@
1
- import { BaseMiddleware, Context } from '../core';
2
- import { z } from 'zod';
3
- export declare class ValidationMiddleware implements BaseMiddleware {
4
- private readonly schema;
5
- constructor(schema: z.ZodSchema);
6
- before(context: Context): Promise<void>;
7
- }
8
- export declare const validationMiddleware: (schema: z.ZodSchema) => BaseMiddleware;
9
- //# sourceMappingURL=validationMiddleware.d.ts.map
@@ -1,40 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validationMiddleware = exports.ValidationMiddleware = void 0;
4
- const core_1 = require("../core");
5
- const zod_1 = require("zod");
6
- const validate = async (schema, context) => {
7
- try {
8
- const data = context.req.method === 'GET' ? context.req.query : context.req.parsedBody;
9
- const validated = await schema.parseAsync(data);
10
- if (context.req.method === 'GET') {
11
- context.req.query = validated;
12
- }
13
- else {
14
- context.req.validatedBody = validated;
15
- }
16
- }
17
- catch (error) {
18
- if (error instanceof zod_1.z.ZodError) {
19
- throw new core_1.ValidationError('Validation error', JSON.stringify(error.errors));
20
- }
21
- throw error;
22
- }
23
- };
24
- class ValidationMiddleware {
25
- schema;
26
- constructor(schema) {
27
- this.schema = schema;
28
- }
29
- async before(context) {
30
- await validate(this.schema, context);
31
- }
32
- }
33
- exports.ValidationMiddleware = ValidationMiddleware;
34
- const validationMiddleware = (schema) => ({
35
- before: async (context) => {
36
- await validate(schema, context);
37
- },
38
- });
39
- exports.validationMiddleware = validationMiddleware;
40
- //# sourceMappingURL=validationMiddleware.js.map