@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
@@ -3,6 +3,61 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validatedQueryParameters = exports.headerVariablesValidator = exports.pathParameters = exports.PathParametersMiddleware = void 0;
4
4
  const errors_1 = require("../core/errors");
5
5
  const zod_1 = require("zod");
6
+ /**
7
+ * Middleware class that extracts path parameters from the URL.
8
+ * Parses URL segments and extracts parameters based on colon-prefixed patterns.
9
+ *
10
+ * @implements {BaseMiddleware}
11
+ *
12
+ * @example
13
+ * Basic path parameter extraction:
14
+ * ```typescript
15
+ * import { Handler, PathParametersMiddleware } from '@noony-serverless/core';
16
+ *
17
+ * // For URL: /users/123/posts/456
18
+ * const userPostHandler = new Handler()
19
+ * .use(new PathParametersMiddleware())
20
+ * .handle(async (context) => {
21
+ * // Assuming your routing pattern is /users/:userId/posts/:postId
22
+ * const { userId, postId } = context.req.params || {};
23
+ *
24
+ * const user = await getUserById(userId);
25
+ * const post = await getPostById(postId);
26
+ *
27
+ * return { success: true, user, post };
28
+ * });
29
+ * ```
30
+ *
31
+ * @example
32
+ * RESTful API with multiple parameters:
33
+ * ```typescript
34
+ * // For URL: /api/v1/organizations/org-123/projects/proj-456/tasks/task-789
35
+ * const taskHandler = new Handler()
36
+ * .use(new PathParametersMiddleware())
37
+ * .handle(async (context) => {
38
+ * const { organizationId, projectId, taskId } = context.req.params || {};
39
+ *
40
+ * const task = await getTask(organizationId, projectId, taskId);
41
+ * return { success: true, task };
42
+ * });
43
+ * ```
44
+ *
45
+ * @example
46
+ * E-commerce product details:
47
+ * ```typescript
48
+ * // For URL: /categories/electronics/products/laptop-123
49
+ * const productHandler = new Handler()
50
+ * .use(new PathParametersMiddleware())
51
+ * .handle(async (context) => {
52
+ * const { category, productId } = context.req.params || {};
53
+ *
54
+ * const product = await getProductByCategory(category, productId);
55
+ * const recommendations = await getRecommendations(category, productId);
56
+ *
57
+ * return { success: true, product, recommendations };
58
+ * });
59
+ * ```
60
+ */
6
61
  class PathParametersMiddleware {
7
62
  async before(context) {
8
63
  const host = (Array.isArray(context.req.headers.host)
@@ -24,6 +79,54 @@ class PathParametersMiddleware {
24
79
  }
25
80
  }
26
81
  exports.PathParametersMiddleware = PathParametersMiddleware;
82
+ /**
83
+ * Factory function that creates a path parameters extraction middleware.
84
+ * Extracts URL path segments and sets them in context.req.params.
85
+ *
86
+ * @returns BaseMiddleware object with path parameter extraction logic
87
+ *
88
+ * @example
89
+ * Simple product API:
90
+ * ```typescript
91
+ * import { Handler, pathParameters } from '@noony-serverless/core';
92
+ *
93
+ * // For URL: /products/123
94
+ * const getProductHandler = new Handler()
95
+ * .use(pathParameters())
96
+ * .handle(async (context) => {
97
+ * const productId = context.req.params?.id;
98
+ * const product = await getProduct(productId);
99
+ * return { success: true, product };
100
+ * });
101
+ * ```
102
+ *
103
+ * @example
104
+ * Blog post with category:
105
+ * ```typescript
106
+ * // For URL: /blog/technology/post-123
107
+ * const blogPostHandler = new Handler()
108
+ * .use(pathParameters())
109
+ * .handle(async (context) => {
110
+ * const { category, postId } = context.req.params || {};
111
+ * const post = await getBlogPost(category, postId);
112
+ * const relatedPosts = await getRelatedPosts(category);
113
+ * return { success: true, post, relatedPosts };
114
+ * });
115
+ * ```
116
+ *
117
+ * @example
118
+ * Nested resource API:
119
+ * ```typescript
120
+ * // For URL: /users/user-123/orders/order-456/items
121
+ * const orderItemsHandler = new Handler()
122
+ * .use(pathParameters())
123
+ * .handle(async (context) => {
124
+ * const { userId, orderId } = context.req.params || {};
125
+ * const orderItems = await getOrderItems(userId, orderId);
126
+ * return { success: true, items: orderItems };
127
+ * });
128
+ * ```
129
+ */
27
130
  const pathParameters = () => ({
28
131
  before: async (context) => {
29
132
  const host = (Array.isArray(context.req.headers.host)
@@ -43,6 +146,60 @@ const pathParameters = () => ({
43
146
  },
44
147
  });
45
148
  exports.pathParameters = pathParameters;
149
+ /**
150
+ * Factory function that creates a header validation middleware.
151
+ * Validates that all required headers are present in the request.
152
+ *
153
+ * @param requiredHeaders - Array of header names that must be present
154
+ * @returns BaseMiddleware object with header validation logic
155
+ *
156
+ * @example
157
+ * API authentication headers:
158
+ * ```typescript
159
+ * import { Handler, headerVariablesValidator } from '@noony-serverless/core';
160
+ *
161
+ * const secureApiHandler = new Handler()
162
+ * .use(headerVariablesValidator(['authorization', 'x-api-key']))
163
+ * .handle(async (context) => {
164
+ * const authToken = context.req.headers.authorization;
165
+ * const apiKey = context.req.headers['x-api-key'];
166
+ *
167
+ * const isValid = await validateCredentials(authToken, apiKey);
168
+ * return { success: isValid, message: 'Access granted' };
169
+ * });
170
+ * ```
171
+ *
172
+ * @example
173
+ * Content type validation:
174
+ * ```typescript
175
+ * const uploadHandler = new Handler()
176
+ * .use(headerVariablesValidator(['content-type', 'content-length']))
177
+ * .handle(async (context) => {
178
+ * const contentType = context.req.headers['content-type'];
179
+ * const contentLength = context.req.headers['content-length'];
180
+ *
181
+ * if (contentType !== 'application/json') {
182
+ * throw new Error('Only JSON content is accepted');
183
+ * }
184
+ *
185
+ * return { success: true, received: contentLength };
186
+ * });
187
+ * ```
188
+ *
189
+ * @example
190
+ * Multi-tenant application:
191
+ * ```typescript
192
+ * const tenantHandler = new Handler()
193
+ * .use(headerVariablesValidator(['x-tenant-id', 'x-client-version']))
194
+ * .handle(async (context) => {
195
+ * const tenantId = context.req.headers['x-tenant-id'];
196
+ * const clientVersion = context.req.headers['x-client-version'];
197
+ *
198
+ * const tenantConfig = await getTenantConfig(tenantId);
199
+ * return { success: true, config: tenantConfig, version: clientVersion };
200
+ * });
201
+ * ```
202
+ */
46
203
  const headerVariablesValidator = (requiredHeaders) => ({
47
204
  before: async (context) => {
48
205
  for (const header of requiredHeaders) {
@@ -53,6 +210,84 @@ const headerVariablesValidator = (requiredHeaders) => ({
53
210
  },
54
211
  });
55
212
  exports.headerVariablesValidator = headerVariablesValidator;
213
+ /**
214
+ * Factory function that creates a query parameter validation middleware using Zod schema.
215
+ * Validates query parameters against a provided schema and throws ValidationError if invalid.
216
+ *
217
+ * @param schema - Zod schema to validate query parameters against
218
+ * @returns BaseMiddleware object with query parameter validation logic
219
+ *
220
+ * @example
221
+ * Pagination parameters validation:
222
+ * ```typescript
223
+ * import { z } from 'zod';
224
+ * import { Handler, validatedQueryParameters } from '@noony-serverless/core';
225
+ *
226
+ * const paginationSchema = z.object({
227
+ * page: z.string().regex(/^\d+$/).transform(Number).default('1'),
228
+ * limit: z.string().regex(/^\d+$/).transform(Number).default('10'),
229
+ * sort: z.enum(['asc', 'desc']).default('asc')
230
+ * });
231
+ *
232
+ * const listUsersHandler = new Handler()
233
+ * .use(validatedQueryParameters(paginationSchema))
234
+ * .handle(async (context) => {
235
+ * const { page, limit, sort } = context.req.query;
236
+ * const users = await getUsersPaginated(page, limit, sort);
237
+ * return { success: true, users, pagination: { page, limit, sort } };
238
+ * });
239
+ * ```
240
+ *
241
+ * @example
242
+ * Search and filter parameters:
243
+ * ```typescript
244
+ * const searchSchema = z.object({
245
+ * q: z.string().min(1),
246
+ * category: z.string().optional(),
247
+ * price_min: z.string().regex(/^\d+(\.\d{2})?$/).optional(),
248
+ * price_max: z.string().regex(/^\d+(\.\d{2})?$/).optional(),
249
+ * in_stock: z.enum(['true', 'false']).optional()
250
+ * });
251
+ *
252
+ * const searchProductsHandler = new Handler()
253
+ * .use(validatedQueryParameters(searchSchema))
254
+ * .handle(async (context) => {
255
+ * const { q, category, price_min, price_max, in_stock } = context.req.query;
256
+ * const filters = {
257
+ * query: q,
258
+ * category,
259
+ * priceRange: { min: price_min, max: price_max },
260
+ * inStock: in_stock === 'true'
261
+ * };
262
+ * const products = await searchProducts(filters);
263
+ * return { success: true, products, filters };
264
+ * });
265
+ * ```
266
+ *
267
+ * @example
268
+ * Date range and reporting parameters:
269
+ * ```typescript
270
+ * const reportSchema = z.object({
271
+ * start_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
272
+ * end_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
273
+ * granularity: z.enum(['day', 'week', 'month']).default('day'),
274
+ * metrics: z.string().transform(val => val.split(',')).optional()
275
+ * });
276
+ *
277
+ * const analyticsHandler = new Handler()
278
+ * .use(validatedQueryParameters(reportSchema))
279
+ * .handle(async (context) => {
280
+ * const { start_date, end_date, granularity, metrics } = context.req.query;
281
+ * const report = await generateReport({
282
+ * startDate: new Date(start_date),
283
+ * endDate: new Date(end_date),
284
+ * granularity,
285
+ * metrics
286
+ * });
287
+ * return { success: true, report };
288
+ * });
289
+ * ```
290
+ */
56
291
  const validatedQueryParameters = (schema) => ({
57
292
  before: async (context) => {
58
293
  const queryParams = context.req.query;
@@ -61,7 +296,7 @@ const validatedQueryParameters = (schema) => ({
61
296
  }
62
297
  catch (error) {
63
298
  if (error instanceof zod_1.z.ZodError) {
64
- throw new errors_1.ValidationError('Validation error', JSON.stringify(error.errors));
299
+ throw new errors_1.ValidationError('Validation error', JSON.stringify(error.issues));
65
300
  }
66
301
  throw error;
67
302
  }
@@ -1,3 +1,6 @@
1
+ export * from './SecurityMiddleware';
2
+ export * from './ConsolidatedValidationMiddleware';
3
+ export * from './ProcessingMiddleware';
1
4
  export * from './authenticationMiddleware';
2
5
  export * from './bodyParserMiddleware';
3
6
  export * from './bodyValidationMiddleware';
@@ -10,6 +13,5 @@ export * from './rateLimitingMiddleware';
10
13
  export * from './responseWrapperMiddleware';
11
14
  export * from './securityAuditMiddleware';
12
15
  export * from './securityHeadersMiddleware';
13
- export * from './validationMiddleware';
14
16
  export * from './guards';
15
17
  //# sourceMappingURL=index.d.ts.map
@@ -14,6 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ // === NEW CONSOLIDATED MIDDLEWARES ===
18
+ __exportStar(require("./SecurityMiddleware"), exports);
19
+ __exportStar(require("./ConsolidatedValidationMiddleware"), exports);
20
+ __exportStar(require("./ProcessingMiddleware"), exports);
21
+ // === EXISTING INDIVIDUAL MIDDLEWARES (for backward compatibility) ===
17
22
  __exportStar(require("./authenticationMiddleware"), exports);
18
23
  __exportStar(require("./bodyParserMiddleware"), exports);
19
24
  __exportStar(require("./bodyValidationMiddleware"), exports);
@@ -26,6 +31,6 @@ __exportStar(require("./rateLimitingMiddleware"), exports);
26
31
  __exportStar(require("./responseWrapperMiddleware"), exports);
27
32
  __exportStar(require("./securityAuditMiddleware"), exports);
28
33
  __exportStar(require("./securityHeadersMiddleware"), exports);
29
- __exportStar(require("./validationMiddleware"), exports);
34
+ // NOTE: validationMiddleware export removed due to naming conflict with new ValidationMiddleware
30
35
  __exportStar(require("./guards"), exports);
31
36
  //# sourceMappingURL=index.js.map
@@ -1,8 +1,113 @@
1
1
  import { BaseMiddleware, Context } from '../core';
2
+ /**
3
+ * Middleware class that validates and processes query parameters from the request URL.
4
+ * Extracts query parameters and validates that required parameters are present.
5
+ *
6
+ * @implements {BaseMiddleware}
7
+ *
8
+ * @example
9
+ * Basic query parameter validation:
10
+ * ```typescript
11
+ * import { Handler, QueryParametersMiddleware } from '@noony-serverless/core';
12
+ *
13
+ * const searchHandler = new Handler()
14
+ * .use(new QueryParametersMiddleware(['q', 'type']))
15
+ * .handle(async (context) => {
16
+ * const { q, type } = context.req.query;
17
+ * const results = await search(q, type);
18
+ * return { success: true, results, query: q, type };
19
+ * });
20
+ * ```
21
+ *
22
+ * @example
23
+ * Pagination with required parameters:
24
+ * ```typescript
25
+ * const listHandler = new Handler()
26
+ * .use(new QueryParametersMiddleware(['page', 'limit']))
27
+ * .handle(async (context) => {
28
+ * const { page, limit, sort } = context.req.query;
29
+ * const items = await getItems(parseInt(page), parseInt(limit), sort);
30
+ * return { success: true, items, pagination: { page, limit } };
31
+ * });
32
+ * ```
33
+ *
34
+ * @example
35
+ * Optional parameters (empty required array):
36
+ * ```typescript
37
+ * const flexibleHandler = new Handler()
38
+ * .use(new QueryParametersMiddleware([])) // No required parameters
39
+ * .handle(async (context) => {
40
+ * const { filter, sort, category } = context.req.query || {};
41
+ * const data = await getData({ filter, sort, category });
42
+ * return { success: true, data };
43
+ * });
44
+ * ```
45
+ */
2
46
  export declare class QueryParametersMiddleware implements BaseMiddleware {
3
47
  private readonly requiredParams;
4
48
  constructor(requiredParams?: string[]);
5
49
  before(context: Context): Promise<void>;
6
50
  }
51
+ /**
52
+ * Factory function that creates a query parameter processing middleware.
53
+ * Extracts and validates query parameters from the request URL.
54
+ *
55
+ * @param requiredParams - Array of parameter names that must be present (default: empty array)
56
+ * @returns BaseMiddleware object with query parameter processing logic
57
+ *
58
+ * @example
59
+ * API endpoint with required search parameters:
60
+ * ```typescript
61
+ * import { Handler, queryParametersMiddleware } from '@noony-serverless/core';
62
+ *
63
+ * const searchApiHandler = new Handler()
64
+ * .use(queryParametersMiddleware(['q'])) // 'q' parameter is required
65
+ * .handle(async (context) => {
66
+ * const { q, category, sort } = context.req.query;
67
+ * const searchResults = await performSearch(q, { category, sort });
68
+ * return { success: true, results: searchResults };
69
+ * });
70
+ * ```
71
+ *
72
+ * @example
73
+ * E-commerce product listing with filters:
74
+ * ```typescript
75
+ * const productListHandler = new Handler()
76
+ * .use(queryParametersMiddleware(['category'])) // Category is required
77
+ * .handle(async (context) => {
78
+ * const { category, price_min, price_max, brand, sort } = context.req.query;
79
+ * const products = await getProducts({
80
+ * category,
81
+ * priceRange: { min: price_min, max: price_max },
82
+ * brand,
83
+ * sortBy: sort || 'name'
84
+ * });
85
+ * return { success: true, products, filters: { category, brand, sort } };
86
+ * });
87
+ * ```
88
+ *
89
+ * @example
90
+ * Flexible API with optional parameters:
91
+ * ```typescript
92
+ * const dataHandler = new Handler()
93
+ * .use(queryParametersMiddleware()) // No required parameters
94
+ * .handle(async (context) => {
95
+ * const queryParams = context.req.query || {};
96
+ * const {
97
+ * page = '1',
98
+ * limit = '10',
99
+ * sort = 'created_at',
100
+ * order = 'desc'
101
+ * } = queryParams;
102
+ *
103
+ * const data = await fetchData({
104
+ * pagination: { page: parseInt(page), limit: parseInt(limit) },
105
+ * sorting: { field: sort, order }
106
+ * });
107
+ *
108
+ * return { success: true, data, meta: { page, limit, sort, order } };
109
+ * });
110
+ * ```
111
+ */
7
112
  export declare const queryParametersMiddleware: (requiredParams?: string[]) => BaseMiddleware;
8
113
  //# sourceMappingURL=queryParametersMiddleware.d.ts.map
@@ -20,6 +20,50 @@ const convertQueryToRecord = (query) => {
20
20
  }
21
21
  return result;
22
22
  };
23
+ /**
24
+ * Middleware class that validates and processes query parameters from the request URL.
25
+ * Extracts query parameters and validates that required parameters are present.
26
+ *
27
+ * @implements {BaseMiddleware}
28
+ *
29
+ * @example
30
+ * Basic query parameter validation:
31
+ * ```typescript
32
+ * import { Handler, QueryParametersMiddleware } from '@noony-serverless/core';
33
+ *
34
+ * const searchHandler = new Handler()
35
+ * .use(new QueryParametersMiddleware(['q', 'type']))
36
+ * .handle(async (context) => {
37
+ * const { q, type } = context.req.query;
38
+ * const results = await search(q, type);
39
+ * return { success: true, results, query: q, type };
40
+ * });
41
+ * ```
42
+ *
43
+ * @example
44
+ * Pagination with required parameters:
45
+ * ```typescript
46
+ * const listHandler = new Handler()
47
+ * .use(new QueryParametersMiddleware(['page', 'limit']))
48
+ * .handle(async (context) => {
49
+ * const { page, limit, sort } = context.req.query;
50
+ * const items = await getItems(parseInt(page), parseInt(limit), sort);
51
+ * return { success: true, items, pagination: { page, limit } };
52
+ * });
53
+ * ```
54
+ *
55
+ * @example
56
+ * Optional parameters (empty required array):
57
+ * ```typescript
58
+ * const flexibleHandler = new Handler()
59
+ * .use(new QueryParametersMiddleware([])) // No required parameters
60
+ * .handle(async (context) => {
61
+ * const { filter, sort, category } = context.req.query || {};
62
+ * const data = await getData({ filter, sort, category });
63
+ * return { success: true, data };
64
+ * });
65
+ * ```
66
+ */
23
67
  class QueryParametersMiddleware {
24
68
  requiredParams;
25
69
  constructor(requiredParams = []) {
@@ -36,6 +80,67 @@ class QueryParametersMiddleware {
36
80
  }
37
81
  }
38
82
  exports.QueryParametersMiddleware = QueryParametersMiddleware;
83
+ /**
84
+ * Factory function that creates a query parameter processing middleware.
85
+ * Extracts and validates query parameters from the request URL.
86
+ *
87
+ * @param requiredParams - Array of parameter names that must be present (default: empty array)
88
+ * @returns BaseMiddleware object with query parameter processing logic
89
+ *
90
+ * @example
91
+ * API endpoint with required search parameters:
92
+ * ```typescript
93
+ * import { Handler, queryParametersMiddleware } from '@noony-serverless/core';
94
+ *
95
+ * const searchApiHandler = new Handler()
96
+ * .use(queryParametersMiddleware(['q'])) // 'q' parameter is required
97
+ * .handle(async (context) => {
98
+ * const { q, category, sort } = context.req.query;
99
+ * const searchResults = await performSearch(q, { category, sort });
100
+ * return { success: true, results: searchResults };
101
+ * });
102
+ * ```
103
+ *
104
+ * @example
105
+ * E-commerce product listing with filters:
106
+ * ```typescript
107
+ * const productListHandler = new Handler()
108
+ * .use(queryParametersMiddleware(['category'])) // Category is required
109
+ * .handle(async (context) => {
110
+ * const { category, price_min, price_max, brand, sort } = context.req.query;
111
+ * const products = await getProducts({
112
+ * category,
113
+ * priceRange: { min: price_min, max: price_max },
114
+ * brand,
115
+ * sortBy: sort || 'name'
116
+ * });
117
+ * return { success: true, products, filters: { category, brand, sort } };
118
+ * });
119
+ * ```
120
+ *
121
+ * @example
122
+ * Flexible API with optional parameters:
123
+ * ```typescript
124
+ * const dataHandler = new Handler()
125
+ * .use(queryParametersMiddleware()) // No required parameters
126
+ * .handle(async (context) => {
127
+ * const queryParams = context.req.query || {};
128
+ * const {
129
+ * page = '1',
130
+ * limit = '10',
131
+ * sort = 'created_at',
132
+ * order = 'desc'
133
+ * } = queryParams;
134
+ *
135
+ * const data = await fetchData({
136
+ * pagination: { page: parseInt(page), limit: parseInt(limit) },
137
+ * sorting: { field: sort, order }
138
+ * });
139
+ *
140
+ * return { success: true, data, meta: { page, limit, sort, order } };
141
+ * });
142
+ * ```
143
+ */
39
144
  const queryParametersMiddleware = (requiredParams = []) => ({
40
145
  async before(context) {
41
146
  const host = (Array.isArray(context.req.headers.host)