@noony-serverless/core 0.1.0 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/middlewares/authenticationMiddleware.d.ts +379 -0
- package/build/middlewares/authenticationMiddleware.js +216 -0
- package/build/middlewares/bodyParserMiddleware.d.ts +99 -0
- package/build/middlewares/bodyParserMiddleware.js +99 -0
- package/build/middlewares/bodyValidationMiddleware.d.ts +68 -4
- package/build/middlewares/bodyValidationMiddleware.js +64 -0
- package/build/middlewares/dependencyInjectionMiddleware.d.ts +238 -0
- package/build/middlewares/dependencyInjectionMiddleware.js +238 -0
- package/build/middlewares/errorHandlerMiddleware.d.ts +94 -0
- package/build/middlewares/errorHandlerMiddleware.js +105 -0
- package/build/middlewares/guards/RouteGuards.d.ts +475 -0
- package/build/middlewares/guards/RouteGuards.js +604 -0
- package/build/middlewares/guards/cache/CacheAdapter.d.ts +473 -0
- package/build/middlewares/guards/cache/CacheAdapter.js +205 -0
- package/build/middlewares/guards/cache/ConservativeCacheInvalidation.d.ts +191 -0
- package/build/middlewares/guards/cache/ConservativeCacheInvalidation.js +510 -0
- package/build/middlewares/guards/cache/MemoryCacheAdapter.d.ts +228 -0
- package/build/middlewares/guards/cache/MemoryCacheAdapter.js +403 -0
- package/build/middlewares/guards/cache/NoopCacheAdapter.d.ts +95 -0
- package/build/middlewares/guards/cache/NoopCacheAdapter.js +131 -0
- package/build/middlewares/guards/config/GuardConfiguration.d.ts +612 -0
- package/build/middlewares/guards/config/GuardConfiguration.js +334 -0
- package/build/middlewares/guards/guards/FastAuthGuard.d.ts +201 -0
- package/build/middlewares/guards/guards/FastAuthGuard.js +460 -0
- package/build/middlewares/guards/guards/PermissionGuardFactory.d.ts +202 -0
- package/build/middlewares/guards/guards/PermissionGuardFactory.js +563 -0
- package/build/middlewares/guards/index.d.ts +67 -0
- package/build/middlewares/guards/index.js +192 -0
- package/build/middlewares/guards/registry/PermissionRegistry.d.ts +188 -0
- package/build/middlewares/guards/registry/PermissionRegistry.js +425 -0
- package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.d.ts +129 -0
- package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.js +451 -0
- package/build/middlewares/guards/resolvers/PermissionResolver.d.ts +155 -0
- package/build/middlewares/guards/resolvers/PermissionResolver.js +176 -0
- package/build/middlewares/guards/resolvers/PlainPermissionResolver.d.ts +101 -0
- package/build/middlewares/guards/resolvers/PlainPermissionResolver.js +248 -0
- package/build/middlewares/guards/resolvers/WildcardPermissionResolver.d.ts +146 -0
- package/build/middlewares/guards/resolvers/WildcardPermissionResolver.js +377 -0
- package/build/middlewares/guards/services/FastUserContextService.d.ts +216 -0
- package/build/middlewares/guards/services/FastUserContextService.js +435 -0
- package/build/middlewares/headerVariablesMiddleware.d.ts +118 -0
- package/build/middlewares/headerVariablesMiddleware.js +118 -0
- package/build/middlewares/httpAttributesMiddleware.d.ts +235 -0
- package/build/middlewares/httpAttributesMiddleware.js +235 -0
- package/build/middlewares/index.d.ts +1 -0
- package/build/middlewares/index.js +1 -0
- package/build/middlewares/queryParametersMiddleware.d.ts +105 -0
- package/build/middlewares/queryParametersMiddleware.js +105 -0
- package/build/middlewares/rateLimitingMiddleware.d.ts +109 -5
- package/build/middlewares/rateLimitingMiddleware.js +109 -5
- package/build/middlewares/responseWrapperMiddleware.d.ts +170 -1
- package/build/middlewares/responseWrapperMiddleware.js +170 -1
- package/build/middlewares/securityAuditMiddleware.js +5 -5
- package/build/middlewares/validationMiddleware.d.ts +145 -0
- package/build/middlewares/validationMiddleware.js +145 -0
- package/package.json +2 -2
|
@@ -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)
|
|
@@ -86,8 +86,69 @@ declare class MemoryStore implements RateLimitStore {
|
|
|
86
86
|
destroy(): void;
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
89
|
-
* Rate Limiting Middleware
|
|
90
|
-
* Implements
|
|
89
|
+
* Rate Limiting Middleware with sliding window implementation.
|
|
90
|
+
* Implements comprehensive rate limiting with dynamic limits, custom storage, and security features.
|
|
91
|
+
*
|
|
92
|
+
* @implements {BaseMiddleware}
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* Basic API rate limiting:
|
|
96
|
+
* ```typescript
|
|
97
|
+
* import { Handler, RateLimitingMiddleware } from '@noony-serverless/core';
|
|
98
|
+
*
|
|
99
|
+
* const apiHandler = new Handler()
|
|
100
|
+
* .use(new RateLimitingMiddleware({
|
|
101
|
+
* maxRequests: 100,
|
|
102
|
+
* windowMs: 60000, // 1 minute
|
|
103
|
+
* message: 'Too many API requests'
|
|
104
|
+
* }))
|
|
105
|
+
* .handle(async (context) => {
|
|
106
|
+
* const data = await getApiData();
|
|
107
|
+
* return { success: true, data };
|
|
108
|
+
* });
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* Authentication endpoint with strict limits:
|
|
113
|
+
* ```typescript
|
|
114
|
+
* const loginHandler = new Handler()
|
|
115
|
+
* .use(new RateLimitingMiddleware({
|
|
116
|
+
* maxRequests: 5,
|
|
117
|
+
* windowMs: 60000, // 1 minute
|
|
118
|
+
* message: 'Too many login attempts',
|
|
119
|
+
* statusCode: 429
|
|
120
|
+
* }))
|
|
121
|
+
* .handle(async (context) => {
|
|
122
|
+
* const { email, password } = context.req.parsedBody;
|
|
123
|
+
* const token = await authenticate(email, password);
|
|
124
|
+
* return { success: true, token };
|
|
125
|
+
* });
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* Dynamic limits based on user authentication:
|
|
130
|
+
* ```typescript
|
|
131
|
+
* const smartApiHandler = new Handler()
|
|
132
|
+
* .use(new RateLimitingMiddleware({
|
|
133
|
+
* maxRequests: 50, // Default for unauthenticated
|
|
134
|
+
* windowMs: 60000,
|
|
135
|
+
* dynamicLimits: {
|
|
136
|
+
* authenticated: {
|
|
137
|
+
* maxRequests: 1000,
|
|
138
|
+
* windowMs: 60000,
|
|
139
|
+
* matcher: (context) => !!context.user
|
|
140
|
+
* },
|
|
141
|
+
* premium: {
|
|
142
|
+
* maxRequests: 5000,
|
|
143
|
+
* windowMs: 60000,
|
|
144
|
+
* matcher: (context) => context.user?.plan === 'premium'
|
|
145
|
+
* }
|
|
146
|
+
* }
|
|
147
|
+
* }))
|
|
148
|
+
* .handle(async (context) => {
|
|
149
|
+
* return { success: true, limit: 'applied dynamically' };
|
|
150
|
+
* });
|
|
151
|
+
* ```
|
|
91
152
|
*/
|
|
92
153
|
export declare class RateLimitingMiddleware implements BaseMiddleware {
|
|
93
154
|
private store;
|
|
@@ -96,9 +157,52 @@ export declare class RateLimitingMiddleware implements BaseMiddleware {
|
|
|
96
157
|
before(context: Context): Promise<void>;
|
|
97
158
|
}
|
|
98
159
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
160
|
+
* Factory function that creates a rate limiting middleware.
|
|
161
|
+
* Provides flexible rate limiting with configurable options and presets.
|
|
162
|
+
*
|
|
163
|
+
* @param options - Rate limiting configuration options
|
|
164
|
+
* @returns BaseMiddleware instance
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* Using preset configurations:
|
|
168
|
+
* ```typescript
|
|
169
|
+
* import { Handler, rateLimiting, RateLimitPresets } from '@noony-serverless/core';
|
|
170
|
+
*
|
|
171
|
+
* // Strict limits for sensitive endpoints
|
|
172
|
+
* const authHandler = new Handler()
|
|
173
|
+
* .use(rateLimiting(RateLimitPresets.AUTH))
|
|
174
|
+
* .handle(async (context) => {
|
|
175
|
+
* return await handleAuthentication(context.req.parsedBody);
|
|
176
|
+
* });
|
|
177
|
+
*
|
|
178
|
+
* // Standard API limits
|
|
179
|
+
* const apiHandler = new Handler()
|
|
180
|
+
* .use(rateLimiting(RateLimitPresets.API))
|
|
181
|
+
* .handle(async (context) => {
|
|
182
|
+
* return await handleApiRequest(context);
|
|
183
|
+
* });
|
|
184
|
+
* ```
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* Custom rate limiting with skip conditions:
|
|
188
|
+
* ```typescript
|
|
189
|
+
* const conditionalHandler = new Handler()
|
|
190
|
+
* .use(rateLimiting({
|
|
191
|
+
* maxRequests: 100,
|
|
192
|
+
* windowMs: 60000,
|
|
193
|
+
* skip: (context) => {
|
|
194
|
+
* // Skip rate limiting for admin users
|
|
195
|
+
* return context.user?.role === 'admin';
|
|
196
|
+
* },
|
|
197
|
+
* keyGenerator: (context) => {
|
|
198
|
+
* // Rate limit per user instead of IP
|
|
199
|
+
* return context.user?.id || context.req.ip || 'anonymous';
|
|
200
|
+
* }
|
|
201
|
+
* }))
|
|
202
|
+
* .handle(async (context) => {
|
|
203
|
+
* return { success: true, message: 'Request processed' };
|
|
204
|
+
* });
|
|
205
|
+
* ```
|
|
102
206
|
*/
|
|
103
207
|
export declare const rateLimiting: (options?: RateLimitOptions) => BaseMiddleware;
|
|
104
208
|
/**
|
|
@@ -104,8 +104,69 @@ const getRateLimit = (context, options) => {
|
|
|
104
104
|
};
|
|
105
105
|
};
|
|
106
106
|
/**
|
|
107
|
-
* Rate Limiting Middleware
|
|
108
|
-
* Implements
|
|
107
|
+
* Rate Limiting Middleware with sliding window implementation.
|
|
108
|
+
* Implements comprehensive rate limiting with dynamic limits, custom storage, and security features.
|
|
109
|
+
*
|
|
110
|
+
* @implements {BaseMiddleware}
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* Basic API rate limiting:
|
|
114
|
+
* ```typescript
|
|
115
|
+
* import { Handler, RateLimitingMiddleware } from '@noony-serverless/core';
|
|
116
|
+
*
|
|
117
|
+
* const apiHandler = new Handler()
|
|
118
|
+
* .use(new RateLimitingMiddleware({
|
|
119
|
+
* maxRequests: 100,
|
|
120
|
+
* windowMs: 60000, // 1 minute
|
|
121
|
+
* message: 'Too many API requests'
|
|
122
|
+
* }))
|
|
123
|
+
* .handle(async (context) => {
|
|
124
|
+
* const data = await getApiData();
|
|
125
|
+
* return { success: true, data };
|
|
126
|
+
* });
|
|
127
|
+
* ```
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* Authentication endpoint with strict limits:
|
|
131
|
+
* ```typescript
|
|
132
|
+
* const loginHandler = new Handler()
|
|
133
|
+
* .use(new RateLimitingMiddleware({
|
|
134
|
+
* maxRequests: 5,
|
|
135
|
+
* windowMs: 60000, // 1 minute
|
|
136
|
+
* message: 'Too many login attempts',
|
|
137
|
+
* statusCode: 429
|
|
138
|
+
* }))
|
|
139
|
+
* .handle(async (context) => {
|
|
140
|
+
* const { email, password } = context.req.parsedBody;
|
|
141
|
+
* const token = await authenticate(email, password);
|
|
142
|
+
* return { success: true, token };
|
|
143
|
+
* });
|
|
144
|
+
* ```
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* Dynamic limits based on user authentication:
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const smartApiHandler = new Handler()
|
|
150
|
+
* .use(new RateLimitingMiddleware({
|
|
151
|
+
* maxRequests: 50, // Default for unauthenticated
|
|
152
|
+
* windowMs: 60000,
|
|
153
|
+
* dynamicLimits: {
|
|
154
|
+
* authenticated: {
|
|
155
|
+
* maxRequests: 1000,
|
|
156
|
+
* windowMs: 60000,
|
|
157
|
+
* matcher: (context) => !!context.user
|
|
158
|
+
* },
|
|
159
|
+
* premium: {
|
|
160
|
+
* maxRequests: 5000,
|
|
161
|
+
* windowMs: 60000,
|
|
162
|
+
* matcher: (context) => context.user?.plan === 'premium'
|
|
163
|
+
* }
|
|
164
|
+
* }
|
|
165
|
+
* }))
|
|
166
|
+
* .handle(async (context) => {
|
|
167
|
+
* return { success: true, limit: 'applied dynamically' };
|
|
168
|
+
* });
|
|
169
|
+
* ```
|
|
109
170
|
*/
|
|
110
171
|
class RateLimitingMiddleware {
|
|
111
172
|
store;
|
|
@@ -179,9 +240,52 @@ class RateLimitingMiddleware {
|
|
|
179
240
|
}
|
|
180
241
|
exports.RateLimitingMiddleware = RateLimitingMiddleware;
|
|
181
242
|
/**
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
243
|
+
* Factory function that creates a rate limiting middleware.
|
|
244
|
+
* Provides flexible rate limiting with configurable options and presets.
|
|
245
|
+
*
|
|
246
|
+
* @param options - Rate limiting configuration options
|
|
247
|
+
* @returns BaseMiddleware instance
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* Using preset configurations:
|
|
251
|
+
* ```typescript
|
|
252
|
+
* import { Handler, rateLimiting, RateLimitPresets } from '@noony-serverless/core';
|
|
253
|
+
*
|
|
254
|
+
* // Strict limits for sensitive endpoints
|
|
255
|
+
* const authHandler = new Handler()
|
|
256
|
+
* .use(rateLimiting(RateLimitPresets.AUTH))
|
|
257
|
+
* .handle(async (context) => {
|
|
258
|
+
* return await handleAuthentication(context.req.parsedBody);
|
|
259
|
+
* });
|
|
260
|
+
*
|
|
261
|
+
* // Standard API limits
|
|
262
|
+
* const apiHandler = new Handler()
|
|
263
|
+
* .use(rateLimiting(RateLimitPresets.API))
|
|
264
|
+
* .handle(async (context) => {
|
|
265
|
+
* return await handleApiRequest(context);
|
|
266
|
+
* });
|
|
267
|
+
* ```
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* Custom rate limiting with skip conditions:
|
|
271
|
+
* ```typescript
|
|
272
|
+
* const conditionalHandler = new Handler()
|
|
273
|
+
* .use(rateLimiting({
|
|
274
|
+
* maxRequests: 100,
|
|
275
|
+
* windowMs: 60000,
|
|
276
|
+
* skip: (context) => {
|
|
277
|
+
* // Skip rate limiting for admin users
|
|
278
|
+
* return context.user?.role === 'admin';
|
|
279
|
+
* },
|
|
280
|
+
* keyGenerator: (context) => {
|
|
281
|
+
* // Rate limit per user instead of IP
|
|
282
|
+
* return context.user?.id || context.req.ip || 'anonymous';
|
|
283
|
+
* }
|
|
284
|
+
* }))
|
|
285
|
+
* .handle(async (context) => {
|
|
286
|
+
* return { success: true, message: 'Request processed' };
|
|
287
|
+
* });
|
|
288
|
+
* ```
|
|
185
289
|
*/
|
|
186
290
|
const rateLimiting = (options = {}) => new RateLimitingMiddleware(options);
|
|
187
291
|
exports.rateLimiting = rateLimiting;
|
|
@@ -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
|