@noony-serverless/core 0.5.3 → 0.7.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.
package/build/core/handler.d.ts
CHANGED
|
@@ -23,6 +23,30 @@ export interface BaseMiddleware<T = unknown, U = unknown> {
|
|
|
23
23
|
* process a request/response flow either before the main handler (via `before`),
|
|
24
24
|
* after the main handler (via `after`), or handle errors (via `onError`).
|
|
25
25
|
*
|
|
26
|
+
* @example Type-safe handler with explicit types
|
|
27
|
+
* interface LoginRequest {
|
|
28
|
+
* email: string;
|
|
29
|
+
* password: string;
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* interface AuthUser extends BaseAuthenticatedUser {
|
|
33
|
+
* role: 'admin' | 'user';
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* const handler = new Handler<LoginRequest, AuthUser>()
|
|
37
|
+
* .use(new ErrorHandlerMiddleware<LoginRequest, AuthUser>())
|
|
38
|
+
* .use(new BodyValidationMiddleware<LoginRequest, AuthUser>(loginSchema))
|
|
39
|
+
* .handle(loginController); // ✅ No 'as any' needed
|
|
40
|
+
*
|
|
41
|
+
* @example Type inference with createTypedHandler
|
|
42
|
+
* async function loginController(context: Context<LoginRequest, AuthUser>) {
|
|
43
|
+
* // controller logic
|
|
44
|
+
* }
|
|
45
|
+
*
|
|
46
|
+
* const handler = createTypedHandler(loginController)
|
|
47
|
+
* .use(new ErrorHandlerMiddleware()) // Types inferred
|
|
48
|
+
* .handle(loginController); // ✅ No 'as any' needed
|
|
49
|
+
*
|
|
26
50
|
* interface MessagePayload {
|
|
27
51
|
* action: string;
|
|
28
52
|
* data: Record<string, unknown>;
|
|
@@ -45,7 +69,7 @@ export declare class Handler<T = unknown, U = unknown> {
|
|
|
45
69
|
private errorMiddlewares;
|
|
46
70
|
private middlewaresPrecomputed;
|
|
47
71
|
static use<T = unknown, U = unknown>(middleware: BaseMiddleware<T, U>): Handler<T, U>;
|
|
48
|
-
use
|
|
72
|
+
use(middleware: BaseMiddleware<T, U>): Handler<T, U>;
|
|
49
73
|
handle(handler: (context: Context<T, U>) => Promise<void | unknown>): Handler<T, U>;
|
|
50
74
|
/**
|
|
51
75
|
* Performance optimization: Pre-compute middleware arrays to avoid runtime array operations
|
|
@@ -69,4 +93,30 @@ export declare class Handler<T = unknown, U = unknown> {
|
|
|
69
93
|
*/
|
|
70
94
|
executeGeneric(req: GenericRequest<T>, res: GenericResponse): Promise<void>;
|
|
71
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Helper to infer types automatically from the controller function.
|
|
98
|
+
*
|
|
99
|
+
* This helper is a permanent feature that improves Developer Experience (DX).
|
|
100
|
+
* It eliminates the need to write explicit generic type parameters when they
|
|
101
|
+
* are already defined in the controller signature.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* // Controller with explicit types
|
|
105
|
+
* async function loginController(context: Context<LoginRequest, AuthUser>) {
|
|
106
|
+
* const { email, password } = context.req.validatedBody!;
|
|
107
|
+
* // ... authentication logic
|
|
108
|
+
* }
|
|
109
|
+
*
|
|
110
|
+
* // Helper infers LoginRequest and AuthUser automatically
|
|
111
|
+
* const handler = createTypedHandler(loginController)
|
|
112
|
+
* .use(new ErrorHandlerMiddleware()) // Types inferred
|
|
113
|
+
* .use(new BodyValidationMiddleware(loginSchema))
|
|
114
|
+
* .handle(loginController); // ✅ Types match perfectly, no 'as any' needed
|
|
115
|
+
*
|
|
116
|
+
* @template T - The request body type (inferred from controller's Context<T, U>)
|
|
117
|
+
* @template U - The user type (inferred from controller's Context<T, U>)
|
|
118
|
+
* @param controller - The controller function with explicit Context<T, U> types
|
|
119
|
+
* @returns A new Handler instance with types inferred from the controller
|
|
120
|
+
*/
|
|
121
|
+
export declare function createTypedHandler<T, U>(_controller: (context: Context<T, U>) => Promise<void | unknown>): Handler<T, U>;
|
|
72
122
|
//# sourceMappingURL=handler.d.ts.map
|
package/build/core/handler.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Handler = void 0;
|
|
4
|
+
exports.createTypedHandler = createTypedHandler;
|
|
4
5
|
// Container import removed - now using containerPool for performance
|
|
5
6
|
const core_1 = require("./core");
|
|
6
7
|
const containerPool_1 = require("./containerPool");
|
|
@@ -12,6 +13,30 @@ const containerPool_1 = require("./containerPool");
|
|
|
12
13
|
* process a request/response flow either before the main handler (via `before`),
|
|
13
14
|
* after the main handler (via `after`), or handle errors (via `onError`).
|
|
14
15
|
*
|
|
16
|
+
* @example Type-safe handler with explicit types
|
|
17
|
+
* interface LoginRequest {
|
|
18
|
+
* email: string;
|
|
19
|
+
* password: string;
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* interface AuthUser extends BaseAuthenticatedUser {
|
|
23
|
+
* role: 'admin' | 'user';
|
|
24
|
+
* }
|
|
25
|
+
*
|
|
26
|
+
* const handler = new Handler<LoginRequest, AuthUser>()
|
|
27
|
+
* .use(new ErrorHandlerMiddleware<LoginRequest, AuthUser>())
|
|
28
|
+
* .use(new BodyValidationMiddleware<LoginRequest, AuthUser>(loginSchema))
|
|
29
|
+
* .handle(loginController); // ✅ No 'as any' needed
|
|
30
|
+
*
|
|
31
|
+
* @example Type inference with createTypedHandler
|
|
32
|
+
* async function loginController(context: Context<LoginRequest, AuthUser>) {
|
|
33
|
+
* // controller logic
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* const handler = createTypedHandler(loginController)
|
|
37
|
+
* .use(new ErrorHandlerMiddleware()) // Types inferred
|
|
38
|
+
* .handle(loginController); // ✅ No 'as any' needed
|
|
39
|
+
*
|
|
15
40
|
* interface MessagePayload {
|
|
16
41
|
* action: string;
|
|
17
42
|
* data: Record<string, unknown>;
|
|
@@ -40,12 +65,8 @@ class Handler {
|
|
|
40
65
|
return handler;
|
|
41
66
|
}
|
|
42
67
|
use(middleware) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
...this.baseMiddlewares,
|
|
46
|
-
middleware,
|
|
47
|
-
];
|
|
48
|
-
return handler;
|
|
68
|
+
this.baseMiddlewares.push(middleware);
|
|
69
|
+
return this;
|
|
49
70
|
}
|
|
50
71
|
handle(handler) {
|
|
51
72
|
this.handler = handler;
|
|
@@ -152,4 +173,32 @@ class Handler {
|
|
|
152
173
|
}
|
|
153
174
|
}
|
|
154
175
|
exports.Handler = Handler;
|
|
176
|
+
/**
|
|
177
|
+
* Helper to infer types automatically from the controller function.
|
|
178
|
+
*
|
|
179
|
+
* This helper is a permanent feature that improves Developer Experience (DX).
|
|
180
|
+
* It eliminates the need to write explicit generic type parameters when they
|
|
181
|
+
* are already defined in the controller signature.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* // Controller with explicit types
|
|
185
|
+
* async function loginController(context: Context<LoginRequest, AuthUser>) {
|
|
186
|
+
* const { email, password } = context.req.validatedBody!;
|
|
187
|
+
* // ... authentication logic
|
|
188
|
+
* }
|
|
189
|
+
*
|
|
190
|
+
* // Helper infers LoginRequest and AuthUser automatically
|
|
191
|
+
* const handler = createTypedHandler(loginController)
|
|
192
|
+
* .use(new ErrorHandlerMiddleware()) // Types inferred
|
|
193
|
+
* .use(new BodyValidationMiddleware(loginSchema))
|
|
194
|
+
* .handle(loginController); // ✅ Types match perfectly, no 'as any' needed
|
|
195
|
+
*
|
|
196
|
+
* @template T - The request body type (inferred from controller's Context<T, U>)
|
|
197
|
+
* @template U - The user type (inferred from controller's Context<T, U>)
|
|
198
|
+
* @param controller - The controller function with explicit Context<T, U> types
|
|
199
|
+
* @returns A new Handler instance with types inferred from the controller
|
|
200
|
+
*/
|
|
201
|
+
function createTypedHandler(_controller) {
|
|
202
|
+
return new Handler();
|
|
203
|
+
}
|
|
155
204
|
//# sourceMappingURL=handler.js.map
|
|
@@ -128,8 +128,8 @@ const handleError = async (error, context, options) => {
|
|
|
128
128
|
if (DEBUG_API_RESPONSE) {
|
|
129
129
|
responsePayload.payload.debug = {
|
|
130
130
|
originalError: error.message,
|
|
131
|
-
stack: error.stack,
|
|
132
|
-
errorType: error.constructor?.name,
|
|
131
|
+
stack: error.stack || 'No stack trace available',
|
|
132
|
+
errorType: error.constructor?.name || 'UnknownError',
|
|
133
133
|
};
|
|
134
134
|
}
|
|
135
135
|
context.res.status(category.httpStatus).json(responsePayload);
|
|
@@ -9,10 +9,14 @@ import { Context } from '../core/core';
|
|
|
9
9
|
* @template TUser - The type of the authenticated user (preserves type chain)
|
|
10
10
|
* @implements {BaseMiddleware}
|
|
11
11
|
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* **Important:** Do not use the deprecated `setResponseData()` helper function.
|
|
14
|
+
* Simply return values from your handler - the Handler automatically sets context.responseData.
|
|
15
|
+
*
|
|
12
16
|
* @example
|
|
13
17
|
* Basic response wrapping:
|
|
14
18
|
* ```typescript
|
|
15
|
-
* import { Handler, ResponseWrapperMiddleware
|
|
19
|
+
* import { Handler, ResponseWrapperMiddleware } from '@noony-serverless/core';
|
|
16
20
|
*
|
|
17
21
|
* interface UserResponse {
|
|
18
22
|
* id: string;
|
|
@@ -24,7 +28,7 @@ import { Context } from '../core/core';
|
|
|
24
28
|
* .use(new ResponseWrapperMiddleware<UserResponse>())
|
|
25
29
|
* .handle(async (context) => {
|
|
26
30
|
* const user = await getUser(context.params.id);
|
|
27
|
-
*
|
|
31
|
+
* return user; // Handler automatically sets context.responseData
|
|
28
32
|
* // Response will be: { success: true, payload: user, timestamp: "..." }
|
|
29
33
|
* });
|
|
30
34
|
* ```
|
|
@@ -41,11 +45,10 @@ import { Context } from '../core/core';
|
|
|
41
45
|
* .use(new ResponseWrapperMiddleware<ApiResponse>())
|
|
42
46
|
* .handle(async (context) => {
|
|
43
47
|
* const items = await getItems();
|
|
44
|
-
*
|
|
48
|
+
* return {
|
|
45
49
|
* items,
|
|
46
50
|
* pagination: { page: 1, total: items.length }
|
|
47
51
|
* };
|
|
48
|
-
* setResponseData(context, response);
|
|
49
52
|
* });
|
|
50
53
|
* ```
|
|
51
54
|
*
|
|
@@ -58,7 +61,7 @@ import { Context } from '../core/core';
|
|
|
58
61
|
* .use(new ErrorHandlerMiddleware())
|
|
59
62
|
* .handle(async (context) => {
|
|
60
63
|
* const data = await getSecureData(context.user.id);
|
|
61
|
-
*
|
|
64
|
+
* return data;
|
|
62
65
|
* });
|
|
63
66
|
* ```
|
|
64
67
|
*/
|
|
@@ -76,18 +79,22 @@ export declare class ResponseWrapperMiddleware<T = unknown, TBody = unknown, TUs
|
|
|
76
79
|
* @template TUser - The type of the authenticated user (preserves type chain)
|
|
77
80
|
* @returns BaseMiddleware object with response wrapping logic
|
|
78
81
|
*
|
|
82
|
+
* @remarks
|
|
83
|
+
* **Important:** Do not use the deprecated `setResponseData()` helper function.
|
|
84
|
+
* Simply return values from your handler - the Handler automatically sets context.responseData.
|
|
85
|
+
*
|
|
79
86
|
* @example
|
|
80
87
|
* Simple API endpoint:
|
|
81
88
|
* ```typescript
|
|
82
|
-
* import { Handler, responseWrapperMiddleware
|
|
89
|
+
* import { Handler, responseWrapperMiddleware } from '@noony-serverless/core';
|
|
83
90
|
*
|
|
84
91
|
* const healthCheckHandler = new Handler()
|
|
85
92
|
* .use(responseWrapperMiddleware<{ status: string; uptime: number }>())
|
|
86
93
|
* .handle(async (context) => {
|
|
87
|
-
*
|
|
94
|
+
* return {
|
|
88
95
|
* status: 'healthy',
|
|
89
96
|
* uptime: process.uptime()
|
|
90
|
-
* }
|
|
97
|
+
* };
|
|
91
98
|
* // Response: { success: true, payload: { status: "healthy", uptime: 12345 }, timestamp: "..." }
|
|
92
99
|
* });
|
|
93
100
|
* ```
|
|
@@ -101,10 +108,10 @@ export declare class ResponseWrapperMiddleware<T = unknown, TBody = unknown, TUs
|
|
|
101
108
|
* .handle(async (context) => {
|
|
102
109
|
* const userData = context.req.parsedBody;
|
|
103
110
|
* const newUser = await createUser(userData);
|
|
104
|
-
*
|
|
111
|
+
* return {
|
|
105
112
|
* id: newUser.id,
|
|
106
113
|
* message: 'User created successfully'
|
|
107
|
-
* }
|
|
114
|
+
* };
|
|
108
115
|
* });
|
|
109
116
|
* ```
|
|
110
117
|
*
|
|
@@ -116,73 +123,13 @@ export declare class ResponseWrapperMiddleware<T = unknown, TBody = unknown, TUs
|
|
|
116
123
|
* .use(responseWrapperMiddleware<{ orderId: string; status: string; estimatedDelivery: string }>())
|
|
117
124
|
* .handle(async (context) => {
|
|
118
125
|
* const order = await processOrder(context.req.parsedBody);
|
|
119
|
-
*
|
|
126
|
+
* return {
|
|
120
127
|
* orderId: order.id,
|
|
121
128
|
* status: order.status,
|
|
122
129
|
* estimatedDelivery: order.estimatedDelivery
|
|
123
|
-
* }
|
|
130
|
+
* };
|
|
124
131
|
* });
|
|
125
132
|
* ```
|
|
126
133
|
*/
|
|
127
134
|
export declare const responseWrapperMiddleware: <T = unknown, TBody = unknown, TUser = unknown>(defaultStatusCode?: number) => BaseMiddleware<TBody, TUser>;
|
|
128
|
-
/**
|
|
129
|
-
* Helper function to set response data in context for later wrapping.
|
|
130
|
-
* This function should be used in handlers when using ResponseWrapperMiddleware.
|
|
131
|
-
*
|
|
132
|
-
* @template T - The type of data being set
|
|
133
|
-
* @template TBody - The type of the request body payload (preserves type chain)
|
|
134
|
-
* @template TUser - The type of the authenticated user (preserves type chain)
|
|
135
|
-
* @param context - The request context
|
|
136
|
-
* @param data - The data to be included in the response payload
|
|
137
|
-
*
|
|
138
|
-
* @example
|
|
139
|
-
* Setting simple response data:
|
|
140
|
-
* ```typescript
|
|
141
|
-
* import { setResponseData } from '@noony-serverless/core';
|
|
142
|
-
*
|
|
143
|
-
* const handler = new Handler()
|
|
144
|
-
* .use(responseWrapperMiddleware())
|
|
145
|
-
* .handle(async (context) => {
|
|
146
|
-
* const message = "Hello, World!";
|
|
147
|
-
* setResponseData(context, { message, timestamp: new Date().toISOString() });
|
|
148
|
-
* });
|
|
149
|
-
* ```
|
|
150
|
-
*
|
|
151
|
-
* @example
|
|
152
|
-
* Setting complex response data:
|
|
153
|
-
* ```typescript
|
|
154
|
-
* const dashboardHandler = new Handler()
|
|
155
|
-
* .use(responseWrapperMiddleware())
|
|
156
|
-
* .handle(async (context) => {
|
|
157
|
-
* const stats = await getDashboardStats(context.user.id);
|
|
158
|
-
* const notifications = await getNotifications(context.user.id);
|
|
159
|
-
*
|
|
160
|
-
* setResponseData(context, {
|
|
161
|
-
* user: context.user,
|
|
162
|
-
* stats,
|
|
163
|
-
* notifications,
|
|
164
|
-
* lastLogin: new Date().toISOString()
|
|
165
|
-
* });
|
|
166
|
-
* });
|
|
167
|
-
* ```
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* Conditional response data:
|
|
171
|
-
* ```typescript
|
|
172
|
-
* const userProfileHandler = new Handler()
|
|
173
|
-
* .use(responseWrapperMiddleware())
|
|
174
|
-
* .handle(async (context) => {
|
|
175
|
-
* const userId = context.params.id;
|
|
176
|
-
* const user = await getUser(userId);
|
|
177
|
-
*
|
|
178
|
-
* if (user) {
|
|
179
|
-
* setResponseData(context, { user, found: true });
|
|
180
|
-
* } else {
|
|
181
|
-
* context.res.status(404);
|
|
182
|
-
* setResponseData(context, { message: 'User not found', found: false });
|
|
183
|
-
* }
|
|
184
|
-
* });
|
|
185
|
-
* ```
|
|
186
|
-
*/
|
|
187
|
-
export declare function setResponseData<T, TBody = unknown, TUser = unknown>(context: Context<TBody, TUser>, data: T): void;
|
|
188
135
|
//# sourceMappingURL=responseWrapperMiddleware.d.ts.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.responseWrapperMiddleware = exports.ResponseWrapperMiddleware = void 0;
|
|
4
|
-
exports.setResponseData = setResponseData;
|
|
5
4
|
const wrapResponse = (context, defaultStatusCode) => {
|
|
6
5
|
if (!context.res.headersSent) {
|
|
7
6
|
// Use defaultStatusCode if provided, otherwise use context.res.statusCode, finally default to 200
|
|
@@ -23,10 +22,14 @@ const wrapResponse = (context, defaultStatusCode) => {
|
|
|
23
22
|
* @template TUser - The type of the authenticated user (preserves type chain)
|
|
24
23
|
* @implements {BaseMiddleware}
|
|
25
24
|
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* **Important:** Do not use the deprecated `setResponseData()` helper function.
|
|
27
|
+
* Simply return values from your handler - the Handler automatically sets context.responseData.
|
|
28
|
+
*
|
|
26
29
|
* @example
|
|
27
30
|
* Basic response wrapping:
|
|
28
31
|
* ```typescript
|
|
29
|
-
* import { Handler, ResponseWrapperMiddleware
|
|
32
|
+
* import { Handler, ResponseWrapperMiddleware } from '@noony-serverless/core';
|
|
30
33
|
*
|
|
31
34
|
* interface UserResponse {
|
|
32
35
|
* id: string;
|
|
@@ -38,7 +41,7 @@ const wrapResponse = (context, defaultStatusCode) => {
|
|
|
38
41
|
* .use(new ResponseWrapperMiddleware<UserResponse>())
|
|
39
42
|
* .handle(async (context) => {
|
|
40
43
|
* const user = await getUser(context.params.id);
|
|
41
|
-
*
|
|
44
|
+
* return user; // Handler automatically sets context.responseData
|
|
42
45
|
* // Response will be: { success: true, payload: user, timestamp: "..." }
|
|
43
46
|
* });
|
|
44
47
|
* ```
|
|
@@ -55,11 +58,10 @@ const wrapResponse = (context, defaultStatusCode) => {
|
|
|
55
58
|
* .use(new ResponseWrapperMiddleware<ApiResponse>())
|
|
56
59
|
* .handle(async (context) => {
|
|
57
60
|
* const items = await getItems();
|
|
58
|
-
*
|
|
61
|
+
* return {
|
|
59
62
|
* items,
|
|
60
63
|
* pagination: { page: 1, total: items.length }
|
|
61
64
|
* };
|
|
62
|
-
* setResponseData(context, response);
|
|
63
65
|
* });
|
|
64
66
|
* ```
|
|
65
67
|
*
|
|
@@ -72,7 +74,7 @@ const wrapResponse = (context, defaultStatusCode) => {
|
|
|
72
74
|
* .use(new ErrorHandlerMiddleware())
|
|
73
75
|
* .handle(async (context) => {
|
|
74
76
|
* const data = await getSecureData(context.user.id);
|
|
75
|
-
*
|
|
77
|
+
* return data;
|
|
76
78
|
* });
|
|
77
79
|
* ```
|
|
78
80
|
*/
|
|
@@ -95,18 +97,22 @@ exports.ResponseWrapperMiddleware = ResponseWrapperMiddleware;
|
|
|
95
97
|
* @template TUser - The type of the authenticated user (preserves type chain)
|
|
96
98
|
* @returns BaseMiddleware object with response wrapping logic
|
|
97
99
|
*
|
|
100
|
+
* @remarks
|
|
101
|
+
* **Important:** Do not use the deprecated `setResponseData()` helper function.
|
|
102
|
+
* Simply return values from your handler - the Handler automatically sets context.responseData.
|
|
103
|
+
*
|
|
98
104
|
* @example
|
|
99
105
|
* Simple API endpoint:
|
|
100
106
|
* ```typescript
|
|
101
|
-
* import { Handler, responseWrapperMiddleware
|
|
107
|
+
* import { Handler, responseWrapperMiddleware } from '@noony-serverless/core';
|
|
102
108
|
*
|
|
103
109
|
* const healthCheckHandler = new Handler()
|
|
104
110
|
* .use(responseWrapperMiddleware<{ status: string; uptime: number }>())
|
|
105
111
|
* .handle(async (context) => {
|
|
106
|
-
*
|
|
112
|
+
* return {
|
|
107
113
|
* status: 'healthy',
|
|
108
114
|
* uptime: process.uptime()
|
|
109
|
-
* }
|
|
115
|
+
* };
|
|
110
116
|
* // Response: { success: true, payload: { status: "healthy", uptime: 12345 }, timestamp: "..." }
|
|
111
117
|
* });
|
|
112
118
|
* ```
|
|
@@ -120,10 +126,10 @@ exports.ResponseWrapperMiddleware = ResponseWrapperMiddleware;
|
|
|
120
126
|
* .handle(async (context) => {
|
|
121
127
|
* const userData = context.req.parsedBody;
|
|
122
128
|
* const newUser = await createUser(userData);
|
|
123
|
-
*
|
|
129
|
+
* return {
|
|
124
130
|
* id: newUser.id,
|
|
125
131
|
* message: 'User created successfully'
|
|
126
|
-
* }
|
|
132
|
+
* };
|
|
127
133
|
* });
|
|
128
134
|
* ```
|
|
129
135
|
*
|
|
@@ -135,11 +141,11 @@ exports.ResponseWrapperMiddleware = ResponseWrapperMiddleware;
|
|
|
135
141
|
* .use(responseWrapperMiddleware<{ orderId: string; status: string; estimatedDelivery: string }>())
|
|
136
142
|
* .handle(async (context) => {
|
|
137
143
|
* const order = await processOrder(context.req.parsedBody);
|
|
138
|
-
*
|
|
144
|
+
* return {
|
|
139
145
|
* orderId: order.id,
|
|
140
146
|
* status: order.status,
|
|
141
147
|
* estimatedDelivery: order.estimatedDelivery
|
|
142
|
-
* }
|
|
148
|
+
* };
|
|
143
149
|
* });
|
|
144
150
|
* ```
|
|
145
151
|
*/
|
|
@@ -149,66 +155,4 @@ const responseWrapperMiddleware = (defaultStatusCode) => ({
|
|
|
149
155
|
},
|
|
150
156
|
});
|
|
151
157
|
exports.responseWrapperMiddleware = responseWrapperMiddleware;
|
|
152
|
-
/**
|
|
153
|
-
* Helper function to set response data in context for later wrapping.
|
|
154
|
-
* This function should be used in handlers when using ResponseWrapperMiddleware.
|
|
155
|
-
*
|
|
156
|
-
* @template T - The type of data being set
|
|
157
|
-
* @template TBody - The type of the request body payload (preserves type chain)
|
|
158
|
-
* @template TUser - The type of the authenticated user (preserves type chain)
|
|
159
|
-
* @param context - The request context
|
|
160
|
-
* @param data - The data to be included in the response payload
|
|
161
|
-
*
|
|
162
|
-
* @example
|
|
163
|
-
* Setting simple response data:
|
|
164
|
-
* ```typescript
|
|
165
|
-
* import { setResponseData } from '@noony-serverless/core';
|
|
166
|
-
*
|
|
167
|
-
* const handler = new Handler()
|
|
168
|
-
* .use(responseWrapperMiddleware())
|
|
169
|
-
* .handle(async (context) => {
|
|
170
|
-
* const message = "Hello, World!";
|
|
171
|
-
* setResponseData(context, { message, timestamp: new Date().toISOString() });
|
|
172
|
-
* });
|
|
173
|
-
* ```
|
|
174
|
-
*
|
|
175
|
-
* @example
|
|
176
|
-
* Setting complex response data:
|
|
177
|
-
* ```typescript
|
|
178
|
-
* const dashboardHandler = new Handler()
|
|
179
|
-
* .use(responseWrapperMiddleware())
|
|
180
|
-
* .handle(async (context) => {
|
|
181
|
-
* const stats = await getDashboardStats(context.user.id);
|
|
182
|
-
* const notifications = await getNotifications(context.user.id);
|
|
183
|
-
*
|
|
184
|
-
* setResponseData(context, {
|
|
185
|
-
* user: context.user,
|
|
186
|
-
* stats,
|
|
187
|
-
* notifications,
|
|
188
|
-
* lastLogin: new Date().toISOString()
|
|
189
|
-
* });
|
|
190
|
-
* });
|
|
191
|
-
* ```
|
|
192
|
-
*
|
|
193
|
-
* @example
|
|
194
|
-
* Conditional response data:
|
|
195
|
-
* ```typescript
|
|
196
|
-
* const userProfileHandler = new Handler()
|
|
197
|
-
* .use(responseWrapperMiddleware())
|
|
198
|
-
* .handle(async (context) => {
|
|
199
|
-
* const userId = context.params.id;
|
|
200
|
-
* const user = await getUser(userId);
|
|
201
|
-
*
|
|
202
|
-
* if (user) {
|
|
203
|
-
* setResponseData(context, { user, found: true });
|
|
204
|
-
* } else {
|
|
205
|
-
* context.res.status(404);
|
|
206
|
-
* setResponseData(context, { message: 'User not found', found: false });
|
|
207
|
-
* }
|
|
208
|
-
* });
|
|
209
|
-
* ```
|
|
210
|
-
*/
|
|
211
|
-
function setResponseData(context, data) {
|
|
212
|
-
context.responseData = data;
|
|
213
|
-
}
|
|
214
158
|
//# sourceMappingURL=responseWrapperMiddleware.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noony-serverless/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.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",
|
|
@@ -41,49 +41,49 @@
|
|
|
41
41
|
"format:check": "prettier --check \"src/**/*.{ts,js,json}\""
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@google-cloud/firestore": "^
|
|
44
|
+
"@google-cloud/firestore": "^8.2.0",
|
|
45
45
|
"@google-cloud/functions-framework": "^5.0.0",
|
|
46
|
-
"@google-cloud/pubsub": "^
|
|
46
|
+
"@google-cloud/pubsub": "^5.2.2",
|
|
47
47
|
"@types/jsonwebtoken": "^9.0.10",
|
|
48
48
|
"axios": "^1.11.0",
|
|
49
|
-
"fastify": "^5.
|
|
50
|
-
"firebase-admin": "^13.
|
|
51
|
-
"firebase-functions": "^6.
|
|
52
|
-
"jsonwebtoken": "^9.0.
|
|
49
|
+
"fastify": "^5.7.1",
|
|
50
|
+
"firebase-admin": "^13.6.0",
|
|
51
|
+
"firebase-functions": "^6.6.0",
|
|
52
|
+
"jsonwebtoken": "^9.0.3",
|
|
53
53
|
"reflect-metadata": "^0.2.2",
|
|
54
54
|
"typedi": "^0.10.0",
|
|
55
|
-
"zod": "^4.
|
|
55
|
+
"zod": "^4.3.5"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@types/jest": "^29.5.
|
|
58
|
+
"@types/jest": "^29.5.14",
|
|
59
59
|
"@types/module-alias": "^2.0.4",
|
|
60
|
-
"@types/node": "^20.
|
|
61
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
62
|
-
"@typescript-eslint/parser": "^6.
|
|
60
|
+
"@types/node": "^20.19.30",
|
|
61
|
+
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
|
62
|
+
"@typescript-eslint/parser": "^6.21.0",
|
|
63
63
|
"concurrently": "^9.2.1",
|
|
64
|
-
"eslint": "^8.
|
|
65
|
-
"eslint-config-prettier": "^9.1.
|
|
66
|
-
"eslint-plugin-prettier": "^5.
|
|
67
|
-
"firebase-functions-test": "^3.1
|
|
64
|
+
"eslint": "^8.57.1",
|
|
65
|
+
"eslint-config-prettier": "^9.1.2",
|
|
66
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
67
|
+
"firebase-functions-test": "^3.4.1",
|
|
68
68
|
"jest": "^29.7.0",
|
|
69
69
|
"module-alias": "^2.2.3",
|
|
70
|
-
"prettier": "^3.
|
|
71
|
-
"ts-jest": "^29.
|
|
72
|
-
"typescript": "^5.
|
|
70
|
+
"prettier": "^3.8.0",
|
|
71
|
+
"ts-jest": "^29.4.6",
|
|
72
|
+
"typescript": "^5.9.3"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
75
|
"@google-cloud/opentelemetry-cloud-trace-propagator": "^0.21.0",
|
|
76
76
|
"@opentelemetry/api": "^1.9.0",
|
|
77
|
-
"@opentelemetry/auto-instrumentations-node": "^0.
|
|
78
|
-
"@opentelemetry/core": "^2.
|
|
79
|
-
"@opentelemetry/exporter-metrics-otlp-http": "^0.
|
|
80
|
-
"@opentelemetry/exporter-trace-otlp-http": "^0.
|
|
81
|
-
"@opentelemetry/instrumentation-http": "^0.
|
|
82
|
-
"@opentelemetry/resources": "^2.
|
|
83
|
-
"@opentelemetry/sdk-node": "^2.
|
|
84
|
-
"@opentelemetry/semantic-conventions": "^1.
|
|
85
|
-
"dd-trace": "^5.
|
|
86
|
-
"newrelic": "^
|
|
77
|
+
"@opentelemetry/auto-instrumentations-node": "^0.210.0",
|
|
78
|
+
"@opentelemetry/core": "^2.4.0",
|
|
79
|
+
"@opentelemetry/exporter-metrics-otlp-http": "^0.210.0",
|
|
80
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.210.0",
|
|
81
|
+
"@opentelemetry/instrumentation-http": "^0.210.0",
|
|
82
|
+
"@opentelemetry/resources": "^2.4.0",
|
|
83
|
+
"@opentelemetry/sdk-node": "^2.4.0",
|
|
84
|
+
"@opentelemetry/semantic-conventions": "^1.39.0",
|
|
85
|
+
"dd-trace": "^5.82.0",
|
|
86
|
+
"newrelic": "^13.10.0"
|
|
87
87
|
},
|
|
88
88
|
"peerDependenciesMeta": {
|
|
89
89
|
"@google-cloud/opentelemetry-cloud-trace-propagator": {
|
|
@@ -124,12 +124,12 @@
|
|
|
124
124
|
}
|
|
125
125
|
},
|
|
126
126
|
"private": false,
|
|
127
|
-
"overrides": {
|
|
128
|
-
"body-parser": "2.2.2"
|
|
129
|
-
},
|
|
130
127
|
"optionalDependencies": {
|
|
131
128
|
"@google-cloud/opentelemetry-cloud-trace-propagator": "^0.21.0"
|
|
132
129
|
},
|
|
130
|
+
"overrides": {
|
|
131
|
+
"body-parser": "^2.2.2"
|
|
132
|
+
},
|
|
133
133
|
"directories": {
|
|
134
134
|
"doc": "docs",
|
|
135
135
|
"example": "examples"
|