@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
@@ -169,6 +169,93 @@ async function verifyToken(tokenVerificationPort, context, options = {}) {
169
169
  throw new errors_1.AuthenticationError('Invalid authentication');
170
170
  }
171
171
  }
172
+ /**
173
+ * Class-based authentication middleware with comprehensive security features.
174
+ * Provides JWT validation, rate limiting, token blacklisting, and security logging.
175
+ *
176
+ * @template T - The type of user data returned by the token verification port
177
+ *
178
+ * @example
179
+ * Basic JWT authentication:
180
+ * ```typescript
181
+ * import { Handler, AuthenticationMiddleware } from '@noony-serverless/core';
182
+ * import jwt from 'jsonwebtoken';
183
+ *
184
+ * interface User {
185
+ * id: string;
186
+ * email: string;
187
+ * roles: string[];
188
+ * }
189
+ *
190
+ * class JWTVerifier implements CustomTokenVerificationPort<User> {
191
+ * async verifyToken(token: string): Promise<User> {
192
+ * const payload = jwt.verify(token, process.env.JWT_SECRET!) as any;
193
+ * return {
194
+ * id: payload.sub,
195
+ * email: payload.email,
196
+ * roles: payload.roles || []
197
+ * };
198
+ * }
199
+ * }
200
+ *
201
+ * const protectedHandler = new Handler()
202
+ * .use(new AuthenticationMiddleware(new JWTVerifier()))
203
+ * .handle(async (request, context) => {
204
+ * const user = context.user as User;
205
+ * return {
206
+ * success: true,
207
+ * data: { message: `Hello ${user.email}`, userId: user.id }
208
+ * };
209
+ * });
210
+ * ```
211
+ *
212
+ * @example
213
+ * Advanced authentication with security options:
214
+ * ```typescript
215
+ * const secureAuthMiddleware = new AuthenticationMiddleware(
216
+ * new JWTVerifier(),
217
+ * {
218
+ * maxTokenAge: 1800, // 30 minutes
219
+ * rateLimiting: {
220
+ * maxAttempts: 5,
221
+ * windowMs: 15 * 60 * 1000 // 15 minutes
222
+ * },
223
+ * isTokenBlacklisted: async (tokenId) => {
224
+ * return await redis.sismember('revoked_tokens', tokenId);
225
+ * },
226
+ * requiredClaims: {
227
+ * issuer: 'my-auth-server',
228
+ * audience: 'my-api'
229
+ * }
230
+ * }
231
+ * );
232
+ *
233
+ * const secureHandler = new Handler()
234
+ * .use(secureAuthMiddleware)
235
+ * .handle(async (request, context) => {
236
+ * // Only authenticated users reach here
237
+ * return { success: true, data: 'Secure data' };
238
+ * });
239
+ * ```
240
+ *
241
+ * @example
242
+ * Google Cloud Functions integration:
243
+ * ```typescript
244
+ * import { http } from '@google-cloud/functions-framework';
245
+ *
246
+ * const userProfileHandler = new Handler()
247
+ * .use(new AuthenticationMiddleware(new JWTVerifier()))
248
+ * .handle(async (request, context) => {
249
+ * const user = context.user as User;
250
+ * const profile = await getUserProfile(user.id);
251
+ * return { success: true, data: profile };
252
+ * });
253
+ *
254
+ * export const getUserProfile = http('getUserProfile', (req, res) => {
255
+ * return userProfileHandler.execute(req, res);
256
+ * });
257
+ * ```
258
+ */
172
259
  class AuthenticationMiddleware {
173
260
  tokenVerificationPort;
174
261
  options;
@@ -181,6 +268,135 @@ class AuthenticationMiddleware {
181
268
  }
182
269
  }
183
270
  exports.AuthenticationMiddleware = AuthenticationMiddleware;
271
+ /**
272
+ * Factory function that creates an authentication middleware with token verification.
273
+ * Provides a functional approach for authentication setup.
274
+ *
275
+ * @template T - The type of user data returned by the token verification port
276
+ * @param tokenVerificationPort - The token verification implementation
277
+ * @param options - Authentication configuration options
278
+ * @returns A BaseMiddleware object with authentication logic
279
+ *
280
+ * @example
281
+ * Simple JWT authentication:
282
+ * ```typescript
283
+ * import { Handler, verifyAuthTokenMiddleware } from '@noony-serverless/core';
284
+ *
285
+ * class SimpleJWTVerifier implements CustomTokenVerificationPort<{ userId: string }> {
286
+ * async verifyToken(token: string): Promise<{ userId: string }> {
287
+ * // Simple token verification logic
288
+ * if (token === 'valid-token') {
289
+ * return { userId: 'user-123' };
290
+ * }
291
+ * throw new Error('Invalid token');
292
+ * }
293
+ * }
294
+ *
295
+ * const handler = new Handler()
296
+ * .use(verifyAuthTokenMiddleware(new SimpleJWTVerifier()))
297
+ * .handle(async (request, context) => {
298
+ * const user = context.user as { userId: string };
299
+ * return { success: true, userId: user.userId };
300
+ * });
301
+ * ```
302
+ *
303
+ * @example
304
+ * API key authentication with rate limiting:
305
+ * ```typescript
306
+ * interface APIKeyUser {
307
+ * keyId: string;
308
+ * permissions: string[];
309
+ * organization: string;
310
+ * }
311
+ *
312
+ * class APIKeyVerifier implements CustomTokenVerificationPort<APIKeyUser> {
313
+ * async verifyToken(token: string): Promise<APIKeyUser> {
314
+ * const keyData = await this.validateAPIKey(token);
315
+ * if (!keyData) {
316
+ * throw new Error('Invalid API key');
317
+ * }
318
+ * return keyData;
319
+ * }
320
+ *
321
+ * private async validateAPIKey(key: string): Promise<APIKeyUser | null> {
322
+ * // Database lookup or external validation
323
+ * return {
324
+ * keyId: 'key-123',
325
+ * permissions: ['read', 'write'],
326
+ * organization: 'org-456'
327
+ * };
328
+ * }
329
+ * }
330
+ *
331
+ * const apiHandler = new Handler()
332
+ * .use(verifyAuthTokenMiddleware(
333
+ * new APIKeyVerifier(),
334
+ * {
335
+ * rateLimiting: {
336
+ * maxAttempts: 100,
337
+ * windowMs: 60 * 1000 // 1 minute
338
+ * }
339
+ * }
340
+ * ))
341
+ * .handle(async (request, context) => {
342
+ * const apiUser = context.user as APIKeyUser;
343
+ * return {
344
+ * success: true,
345
+ * data: { organization: apiUser.organization }
346
+ * };
347
+ * });
348
+ * ```
349
+ *
350
+ * @example
351
+ * Express-style middleware chain:
352
+ * ```typescript
353
+ * import { Handler, verifyAuthTokenMiddleware, errorHandler } from '@noony-serverless/core';
354
+ *
355
+ * const authMiddleware = verifyAuthTokenMiddleware(
356
+ * new JWTVerifier(),
357
+ * {
358
+ * maxTokenAge: 3600,
359
+ * requiredClaims: {
360
+ * issuer: 'my-app',
361
+ * audience: 'api-users'
362
+ * }
363
+ * }
364
+ * );
365
+ *
366
+ * const protectedEndpoint = new Handler()
367
+ * .use(authMiddleware)
368
+ * .use(errorHandler())
369
+ * .handle(async (request, context) => {
370
+ * // Authenticated user available in context.user
371
+ * return { success: true, data: 'Protected resource' };
372
+ * });
373
+ * ```
374
+ *
375
+ * @example
376
+ * Multiple authentication strategies:
377
+ * ```typescript
378
+ * // Different handlers for different auth types
379
+ * const jwtHandler = new Handler()
380
+ * .use(verifyAuthTokenMiddleware(new JWTVerifier()))
381
+ * .handle(jwtLogic);
382
+ *
383
+ * const apiKeyHandler = new Handler()
384
+ * .use(verifyAuthTokenMiddleware(new APIKeyVerifier()))
385
+ * .handle(apiKeyLogic);
386
+ *
387
+ * // Route based on authentication type
388
+ * export const handleRequest = (req: any, res: any) => {
389
+ * const authHeader = req.headers.authorization;
390
+ * if (authHeader?.startsWith('Bearer jwt.')) {
391
+ * return jwtHandler.execute(req, res);
392
+ * } else if (authHeader?.startsWith('Bearer ak_')) {
393
+ * return apiKeyHandler.execute(req, res);
394
+ * } else {
395
+ * res.status(401).json({ error: 'Authentication required' });
396
+ * }
397
+ * };
398
+ * ```
399
+ */
184
400
  const verifyAuthTokenMiddleware = (tokenVerificationPort, options = {}) => ({
185
401
  async before(context) {
186
402
  await verifyToken(tokenVerificationPort, context, options);
@@ -10,6 +10,58 @@ import { BaseMiddleware, Context } from '../core';
10
10
  *
11
11
  * @template T - The expected type of the parsed body. Defaults to unknown if not specified.
12
12
  * @implements {BaseMiddleware}
13
+ *
14
+ * @example
15
+ * Basic usage with typed body parsing:
16
+ * ```typescript
17
+ * import { Handler, BodyParserMiddleware } from '@noony-serverless/core';
18
+ *
19
+ * interface UserRequest {
20
+ * name: string;
21
+ * email: string;
22
+ * age: number;
23
+ * }
24
+ *
25
+ * const createUserHandler = new Handler()
26
+ * .use(new BodyParserMiddleware<UserRequest>())
27
+ * .handle(async (context) => {
28
+ * const userData = context.req.parsedBody as UserRequest;
29
+ * console.log('User data:', userData.name, userData.email);
30
+ * return { success: true, data: userData };
31
+ * });
32
+ * ```
33
+ *
34
+ * @example
35
+ * Custom size limit configuration:
36
+ * ```typescript
37
+ * const largeBodyParser = new BodyParserMiddleware<any>(2 * 1024 * 1024); // 2MB limit
38
+ *
39
+ * const uploadHandler = new Handler()
40
+ * .use(largeBodyParser)
41
+ * .handle(async (context) => {
42
+ * const uploadData = context.req.parsedBody;
43
+ * return { success: true, size: JSON.stringify(uploadData).length };
44
+ * });
45
+ * ```
46
+ *
47
+ * @example
48
+ * Google Cloud Pub/Sub message handling:
49
+ * ```typescript
50
+ * interface PubSubData {
51
+ * eventType: string;
52
+ * timestamp: string;
53
+ * payload: any;
54
+ * }
55
+ *
56
+ * const pubSubHandler = new Handler()
57
+ * .use(new BodyParserMiddleware<PubSubData>())
58
+ * .handle(async (context) => {
59
+ * // Automatically decodes base64 Pub/Sub message data
60
+ * const messageData = context.req.parsedBody as PubSubData;
61
+ * console.log('Event type:', messageData.eventType);
62
+ * return { success: true, processed: true };
63
+ * });
64
+ * ```
13
65
  */
14
66
  export declare class BodyParserMiddleware<T = unknown> implements BaseMiddleware {
15
67
  private maxSize;
@@ -25,7 +77,54 @@ export declare class BodyParserMiddleware<T = unknown> implements BaseMiddleware
25
77
  * - Size validation
26
78
  *
27
79
  * @template T - The expected type of the parsed request body.
80
+ * @param maxSize - Maximum allowed body size in bytes (default: 1MB)
28
81
  * @returns {BaseMiddleware} A middleware object containing a `before` hook.
82
+ *
83
+ * @example
84
+ * Basic body parsing with default settings:
85
+ * ```typescript
86
+ * import { Handler, bodyParser } from '@noony-serverless/core';
87
+ *
88
+ * const apiHandler = new Handler()
89
+ * .use(bodyParser<{ name: string; email: string }>())
90
+ * .handle(async (context) => {
91
+ * const body = context.req.parsedBody;
92
+ * return { success: true, received: body };
93
+ * });
94
+ * ```
95
+ *
96
+ * @example
97
+ * Custom size limit for large uploads:
98
+ * ```typescript
99
+ * const uploadHandler = new Handler()
100
+ * .use(bodyParser<any>(5 * 1024 * 1024)) // 5MB limit
101
+ * .handle(async (context) => {
102
+ * const uploadData = context.req.parsedBody;
103
+ * console.log('Upload size:', JSON.stringify(uploadData).length);
104
+ * return { success: true, uploadId: generateId() };
105
+ * });
106
+ * ```
107
+ *
108
+ * @example
109
+ * Combining with validation middleware:
110
+ * ```typescript
111
+ * import { z } from 'zod';
112
+ * import { bodyParser, validationMiddleware } from '@noony-serverless/core';
113
+ *
114
+ * const userSchema = z.object({
115
+ * name: z.string().min(1),
116
+ * email: z.string().email(),
117
+ * age: z.number().int().min(18)
118
+ * });
119
+ *
120
+ * const createUserHandler = new Handler()
121
+ * .use(bodyParser<z.infer<typeof userSchema>>())
122
+ * .use(validationMiddleware(userSchema))
123
+ * .handle(async (context) => {
124
+ * const validatedUser = context.req.validatedBody;
125
+ * return { success: true, user: validatedUser };
126
+ * });
127
+ * ```
29
128
  */
30
129
  export declare const bodyParser: <T = unknown>(maxSize?: number) => BaseMiddleware;
31
130
  //# sourceMappingURL=bodyParserMiddleware.d.ts.map
@@ -159,6 +159,58 @@ const parseBody = async (body) => {
159
159
  *
160
160
  * @template T - The expected type of the parsed body. Defaults to unknown if not specified.
161
161
  * @implements {BaseMiddleware}
162
+ *
163
+ * @example
164
+ * Basic usage with typed body parsing:
165
+ * ```typescript
166
+ * import { Handler, BodyParserMiddleware } from '@noony-serverless/core';
167
+ *
168
+ * interface UserRequest {
169
+ * name: string;
170
+ * email: string;
171
+ * age: number;
172
+ * }
173
+ *
174
+ * const createUserHandler = new Handler()
175
+ * .use(new BodyParserMiddleware<UserRequest>())
176
+ * .handle(async (context) => {
177
+ * const userData = context.req.parsedBody as UserRequest;
178
+ * console.log('User data:', userData.name, userData.email);
179
+ * return { success: true, data: userData };
180
+ * });
181
+ * ```
182
+ *
183
+ * @example
184
+ * Custom size limit configuration:
185
+ * ```typescript
186
+ * const largeBodyParser = new BodyParserMiddleware<any>(2 * 1024 * 1024); // 2MB limit
187
+ *
188
+ * const uploadHandler = new Handler()
189
+ * .use(largeBodyParser)
190
+ * .handle(async (context) => {
191
+ * const uploadData = context.req.parsedBody;
192
+ * return { success: true, size: JSON.stringify(uploadData).length };
193
+ * });
194
+ * ```
195
+ *
196
+ * @example
197
+ * Google Cloud Pub/Sub message handling:
198
+ * ```typescript
199
+ * interface PubSubData {
200
+ * eventType: string;
201
+ * timestamp: string;
202
+ * payload: any;
203
+ * }
204
+ *
205
+ * const pubSubHandler = new Handler()
206
+ * .use(new BodyParserMiddleware<PubSubData>())
207
+ * .handle(async (context) => {
208
+ * // Automatically decodes base64 Pub/Sub message data
209
+ * const messageData = context.req.parsedBody as PubSubData;
210
+ * console.log('Event type:', messageData.eventType);
211
+ * return { success: true, processed: true };
212
+ * });
213
+ * ```
162
214
  */
163
215
  class BodyParserMiddleware {
164
216
  maxSize;
@@ -190,7 +242,54 @@ exports.BodyParserMiddleware = BodyParserMiddleware;
190
242
  * - Size validation
191
243
  *
192
244
  * @template T - The expected type of the parsed request body.
245
+ * @param maxSize - Maximum allowed body size in bytes (default: 1MB)
193
246
  * @returns {BaseMiddleware} A middleware object containing a `before` hook.
247
+ *
248
+ * @example
249
+ * Basic body parsing with default settings:
250
+ * ```typescript
251
+ * import { Handler, bodyParser } from '@noony-serverless/core';
252
+ *
253
+ * const apiHandler = new Handler()
254
+ * .use(bodyParser<{ name: string; email: string }>())
255
+ * .handle(async (context) => {
256
+ * const body = context.req.parsedBody;
257
+ * return { success: true, received: body };
258
+ * });
259
+ * ```
260
+ *
261
+ * @example
262
+ * Custom size limit for large uploads:
263
+ * ```typescript
264
+ * const uploadHandler = new Handler()
265
+ * .use(bodyParser<any>(5 * 1024 * 1024)) // 5MB limit
266
+ * .handle(async (context) => {
267
+ * const uploadData = context.req.parsedBody;
268
+ * console.log('Upload size:', JSON.stringify(uploadData).length);
269
+ * return { success: true, uploadId: generateId() };
270
+ * });
271
+ * ```
272
+ *
273
+ * @example
274
+ * Combining with validation middleware:
275
+ * ```typescript
276
+ * import { z } from 'zod';
277
+ * import { bodyParser, validationMiddleware } from '@noony-serverless/core';
278
+ *
279
+ * const userSchema = z.object({
280
+ * name: z.string().min(1),
281
+ * email: z.string().email(),
282
+ * age: z.number().int().min(18)
283
+ * });
284
+ *
285
+ * const createUserHandler = new Handler()
286
+ * .use(bodyParser<z.infer<typeof userSchema>>())
287
+ * .use(validationMiddleware(userSchema))
288
+ * .handle(async (context) => {
289
+ * const validatedUser = context.req.validatedBody;
290
+ * return { success: true, user: validatedUser };
291
+ * });
292
+ * ```
194
293
  */
195
294
  const bodyParser = (maxSize = MAX_JSON_SIZE) => ({
196
295
  before: async (context) => {
@@ -1,12 +1,78 @@
1
1
  import { BaseMiddleware } from '../core/handler';
2
2
  import { Context } from '../core/core';
3
3
  import { z } from 'zod';
4
- export declare class BodyValidationMiddleware<T = unknown> implements BaseMiddleware {
4
+ /**
5
+ * Body validation middleware using Zod schemas for runtime type checking.
6
+ * Validates the parsed request body against a provided Zod schema and sets
7
+ * the validated result in context.req.validatedBody.
8
+ *
9
+ * @template T - The expected type of the validated body data
10
+ * @implements {BaseMiddleware}
11
+ *
12
+ * @example
13
+ * Simple user creation with type safety:
14
+ * ```typescript
15
+ * import { z } from 'zod';
16
+ * import { Handler, BodyValidationMiddleware } from '@noony-serverless/core';
17
+ *
18
+ * const userSchema = z.object({
19
+ * name: z.string().min(1),
20
+ * email: z.string().email(),
21
+ * age: z.number().min(18)
22
+ * });
23
+ *
24
+ * type UserRequest = z.infer<typeof userSchema>;
25
+ *
26
+ * async function handleCreateUser(context: Context<UserRequest>) {
27
+ * const user = context.req.validatedBody!; // Fully typed
28
+ * const authenticatedUser = context.user; // User type inferred from auth middleware
29
+ * return { success: true, user: { id: '123', ...user } };
30
+ * }
31
+ *
32
+ * const createUserHandler = new Handler<UserRequest>()
33
+ * .use(new BodyValidationMiddleware<UserRequest>(userSchema))
34
+ * .handle(handleCreateUser);
35
+ * ```
36
+ */
37
+ export declare class BodyValidationMiddleware<T = unknown> implements BaseMiddleware<T> {
5
38
  private readonly schema;
6
39
  constructor(schema: z.ZodSchema<T>);
7
- before(context: Context): Promise<void>;
40
+ before(context: Context<T>): Promise<void>;
8
41
  }
42
+ /**
43
+ * Factory function that creates a body validation middleware with Zod schema validation.
44
+ * This function validates and parses the request body, setting the result in context.req.parsedBody.
45
+ *
46
+ * @template T - The expected type of the validated body data
47
+ * @param schema - Zod schema to validate against
48
+ * @returns A BaseMiddleware object with validation logic
49
+ *
50
+ * @example
51
+ * Simple login validation:
52
+ * ```typescript
53
+ * import { z } from 'zod';
54
+ * import { Handler, bodyValidatorMiddleware } from '@noony-serverless/core';
55
+ *
56
+ * const loginSchema = z.object({
57
+ * username: z.string().min(3),
58
+ * password: z.string().min(8)
59
+ * });
60
+ *
61
+ * type LoginRequest = z.infer<typeof loginSchema>;
62
+ *
63
+ * async function handleLogin(context: Context<LoginRequest>) {
64
+ * const credentials = context.req.parsedBody as LoginRequest;
65
+ * const token = await authenticate(credentials.username, credentials.password);
66
+ * const authenticatedUser = context.user; // User type from auth middleware
67
+ * return { success: true, token };
68
+ * }
69
+ *
70
+ * const loginHandler = new Handler<LoginRequest>()
71
+ * .use(bodyValidatorMiddleware<LoginRequest>(loginSchema))
72
+ * .handle(handleLogin);
73
+ * ```
74
+ */
9
75
  export declare const bodyValidatorMiddleware: <T>(schema: z.ZodType<T>) => {
10
- before: (context: Context) => Promise<void>;
76
+ before: (context: Context<T>) => Promise<void>;
11
77
  };
12
78
  //# sourceMappingURL=bodyValidationMiddleware.d.ts.map
@@ -9,11 +9,44 @@ const validateBody = async (schema, data) => {
9
9
  }
10
10
  catch (error) {
11
11
  if (error instanceof zod_1.z.ZodError) {
12
- throw new errors_1.ValidationError('Validation error', error.errors);
12
+ throw new errors_1.ValidationError('Validation error', error.issues);
13
13
  }
14
14
  throw error;
15
15
  }
16
16
  };
17
+ /**
18
+ * Body validation middleware using Zod schemas for runtime type checking.
19
+ * Validates the parsed request body against a provided Zod schema and sets
20
+ * the validated result in context.req.validatedBody.
21
+ *
22
+ * @template T - The expected type of the validated body data
23
+ * @implements {BaseMiddleware}
24
+ *
25
+ * @example
26
+ * Simple user creation with type safety:
27
+ * ```typescript
28
+ * import { z } from 'zod';
29
+ * import { Handler, BodyValidationMiddleware } from '@noony-serverless/core';
30
+ *
31
+ * const userSchema = z.object({
32
+ * name: z.string().min(1),
33
+ * email: z.string().email(),
34
+ * age: z.number().min(18)
35
+ * });
36
+ *
37
+ * type UserRequest = z.infer<typeof userSchema>;
38
+ *
39
+ * async function handleCreateUser(context: Context<UserRequest>) {
40
+ * const user = context.req.validatedBody!; // Fully typed
41
+ * const authenticatedUser = context.user; // User type inferred from auth middleware
42
+ * return { success: true, user: { id: '123', ...user } };
43
+ * }
44
+ *
45
+ * const createUserHandler = new Handler<UserRequest>()
46
+ * .use(new BodyValidationMiddleware<UserRequest>(userSchema))
47
+ * .handle(handleCreateUser);
48
+ * ```
49
+ */
17
50
  class BodyValidationMiddleware {
18
51
  schema;
19
52
  constructor(schema) {
@@ -24,7 +57,40 @@ class BodyValidationMiddleware {
24
57
  }
25
58
  }
26
59
  exports.BodyValidationMiddleware = BodyValidationMiddleware;
27
- // Modified to fix type instantiation error
60
+ /**
61
+ * Factory function that creates a body validation middleware with Zod schema validation.
62
+ * This function validates and parses the request body, setting the result in context.req.parsedBody.
63
+ *
64
+ * @template T - The expected type of the validated body data
65
+ * @param schema - Zod schema to validate against
66
+ * @returns A BaseMiddleware object with validation logic
67
+ *
68
+ * @example
69
+ * Simple login validation:
70
+ * ```typescript
71
+ * import { z } from 'zod';
72
+ * import { Handler, bodyValidatorMiddleware } from '@noony-serverless/core';
73
+ *
74
+ * const loginSchema = z.object({
75
+ * username: z.string().min(3),
76
+ * password: z.string().min(8)
77
+ * });
78
+ *
79
+ * type LoginRequest = z.infer<typeof loginSchema>;
80
+ *
81
+ * async function handleLogin(context: Context<LoginRequest>) {
82
+ * const credentials = context.req.parsedBody as LoginRequest;
83
+ * const token = await authenticate(credentials.username, credentials.password);
84
+ * const authenticatedUser = context.user; // User type from auth middleware
85
+ * return { success: true, token };
86
+ * }
87
+ *
88
+ * const loginHandler = new Handler<LoginRequest>()
89
+ * .use(bodyValidatorMiddleware<LoginRequest>(loginSchema))
90
+ * .handle(handleLogin);
91
+ * ```
92
+ */
93
+ // Simplified factory function for body validation middleware
28
94
  const bodyValidatorMiddleware = (schema) => ({
29
95
  before: async (context) => {
30
96
  context.req.parsedBody = await validateBody(schema, context.req.body);