@noony-serverless/core 0.5.3 → 0.6.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.
@@ -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, setResponseData } from '@noony-serverless/core';
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
- * setResponseData(context, user);
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
- * const response: ApiResponse = {
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
- * setResponseData(context, data);
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, setResponseData } from '@noony-serverless/core';
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
- * setResponseData(context, {
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
- * setResponseData(context, {
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
- * setResponseData(context, {
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, setResponseData } from '@noony-serverless/core';
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
- * setResponseData(context, user);
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
- * const response: ApiResponse = {
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
- * setResponseData(context, data);
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, setResponseData } from '@noony-serverless/core';
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
- * setResponseData(context, {
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
- * setResponseData(context, {
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
- * setResponseData(context, {
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.5.3",
3
+ "version": "0.6.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": "^7.1.0",
44
+ "@google-cloud/firestore": "^8.2.0",
45
45
  "@google-cloud/functions-framework": "^5.0.0",
46
- "@google-cloud/pubsub": "^4.1.0",
46
+ "@google-cloud/pubsub": "^5.2.2",
47
47
  "@types/jsonwebtoken": "^9.0.10",
48
48
  "axios": "^1.11.0",
49
- "fastify": "^5.6.0",
50
- "firebase-admin": "^13.5.0",
51
- "firebase-functions": "^6.4.0",
52
- "jsonwebtoken": "^9.0.2",
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.1.5"
55
+ "zod": "^4.3.5"
56
56
  },
57
57
  "devDependencies": {
58
- "@types/jest": "^29.5.11",
58
+ "@types/jest": "^29.5.14",
59
59
  "@types/module-alias": "^2.0.4",
60
- "@types/node": "^20.10.5",
61
- "@typescript-eslint/eslint-plugin": "^6.15.0",
62
- "@typescript-eslint/parser": "^6.15.0",
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.56.0",
65
- "eslint-config-prettier": "^9.1.0",
66
- "eslint-plugin-prettier": "^5.1.2",
67
- "firebase-functions-test": "^3.1.0",
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.1.1",
71
- "ts-jest": "^29.1.1",
72
- "typescript": "^5.3.3"
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.200.0",
78
- "@opentelemetry/core": "^2.0.0",
79
- "@opentelemetry/exporter-metrics-otlp-http": "^0.205.0",
80
- "@opentelemetry/exporter-trace-otlp-http": "^0.205.0",
81
- "@opentelemetry/instrumentation-http": "^0.200.0",
82
- "@opentelemetry/resources": "^2.0.0",
83
- "@opentelemetry/sdk-node": "^2.0.0",
84
- "@opentelemetry/semantic-conventions": "^1.28.0",
85
- "dd-trace": "^5.0.0",
86
- "newrelic": "^12.0.0"
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"