@leanstacks/lambda-utils 0.2.0-alpha.2 → 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.
package/README.md CHANGED
@@ -49,16 +49,16 @@ export const handler = async (event: any, context: any) => {
49
49
  ### API Response Example
50
50
 
51
51
  ```typescript
52
- import { success, badRequest } from '@leanstacks/lambda-utils';
52
+ import { ok, badRequest } from '@leanstacks/lambda-utils';
53
53
 
54
- export const handler = async (event: any) => {
54
+ export const handler = async (event: APIGatewayProxyEvent) => {
55
55
  if (!event.body) {
56
- return badRequest({ message: 'Body is required' });
56
+ return badRequest('Body is required');
57
57
  }
58
58
 
59
59
  // Process request
60
60
 
61
- return success({ message: 'Request processed successfully' });
61
+ return ok({ message: 'Request processed successfully' });
62
62
  };
63
63
  ```
64
64
 
@@ -108,10 +108,10 @@ logger.error({ message: 'Operation failed', error: err.message });
108
108
  Generate properly formatted responses for API Gateway:
109
109
 
110
110
  ```typescript
111
- import { success, error, created, badRequest } from '@leanstacks/lambda-utils';
111
+ import { ok, created, badRequest } from '@leanstacks/lambda-utils';
112
112
 
113
- export const handler = async (event: any) => {
114
- return success({
113
+ export const handler = async (event: APIGatewayProxyEvent) => {
114
+ return ok({
115
115
  data: { id: '123', name: 'Example' },
116
116
  });
117
117
  };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { Logger, LoggerConfig, withRequestTracking } from './logging/logger';
2
- export { createResponse, ok, created, noContent, badRequest, notFound, internalServerError, jsonHeaders, corsHeaders, Headers, } from './utils/apigateway-response';
2
+ export { createResponse, ok, created, noContent, badRequest, notFound, internalServerError, httpHeaders, Headers, } from './utils/apigateway-response';
package/dist/index.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- import e from"pino";import{lambdaRequestTracker as n,StructuredLogFormatter as o,CloudwatchLogFormatter as t,pinoLambdaDestination as s}from"pino-lambda";const r=n();class i{constructor(n){this._loggerConfig={enabled:!0,level:"info",format:"json"},this._instance=null,this._createLogger=()=>{const n="json"===this._loggerConfig.format?new o:new t,r=s({formatter:n});return e({enabled:this._loggerConfig.enabled,level:this._loggerConfig.level},r)},n&&(this._loggerConfig={enabled:n.enabled??!0,level:n.level??"info",format:n.format??"json"})}get instance(){return null===this._instance&&(this._instance=this._createLogger()),this._instance}}const l={"Content-Type":"application/json"},a=(e="*")=>({"Access-Control-Allow-Origin":e}),g=(e,n,o={})=>({statusCode:e,headers:{...o},body:JSON.stringify(n)}),c=(e,n={})=>g(200,e,n),f=(e,n={})=>g(201,e,n),m=(e={})=>g(204,{},e),h=(e="Bad Request",n={})=>g(400,{message:e},n),d=(e="Not Found",n={})=>g(404,{message:e},n),_=(e="Internal Server Error",n={})=>g(500,{message:e},n);export{i as Logger,h as badRequest,a as corsHeaders,g as createResponse,f as created,_ as internalServerError,l as jsonHeaders,m as noContent,d as notFound,c as ok,r as withRequestTracking};
1
+ import e from"pino";import{lambdaRequestTracker as n,StructuredLogFormatter as o,CloudwatchLogFormatter as t,pinoLambdaDestination as s}from"pino-lambda";const r=n();class i{constructor(n){this._loggerConfig={enabled:!0,level:"info",format:"json"},this._instance=null,this._createLogger=()=>{const n="json"===this._loggerConfig.format?new o:new t,r=s({formatter:n});return e({enabled:this._loggerConfig.enabled,level:this._loggerConfig.level},r)},n&&(this._loggerConfig={enabled:n.enabled??!0,level:n.level??"info",format:n.format??"json"})}get instance(){return null===this._instance&&(this._instance=this._createLogger()),this._instance}}const l={contentType:e=>({"Content-Type":e}),json:{"Content-Type":"application/json"},cors:(e="*")=>({"Access-Control-Allow-Origin":e})},a=(e,n,o={})=>({statusCode:e,headers:{...o},body:JSON.stringify(n)}),g=(e,n={})=>a(200,e,n),c=(e,n={})=>a(201,e,n),f=(e={})=>a(204,{},e),m=(e="Bad Request",n={})=>a(400,{message:e},n),h=(e="Not Found",n={})=>a(404,{message:e},n),d=(e="Internal Server Error",n={})=>a(500,{message:e},n);export{i as Logger,m as badRequest,a as createResponse,c as created,l as httpHeaders,d as internalServerError,f as noContent,h as notFound,g as ok,r as withRequestTracking};
2
2
  //# sourceMappingURL=index.esm.js.map
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("pino"),t=require("pino-lambda");const r=t.lambdaRequestTracker();const o=(e,t,r={})=>({statusCode:e,headers:{...r},body:JSON.stringify(t)});exports.Logger=class{constructor(r){this._loggerConfig={enabled:!0,level:"info",format:"json"},this._instance=null,this._createLogger=()=>{const r="json"===this._loggerConfig.format?new t.StructuredLogFormatter:new t.CloudwatchLogFormatter,o=t.pinoLambdaDestination({formatter:r});return e({enabled:this._loggerConfig.enabled,level:this._loggerConfig.level},o)},r&&(this._loggerConfig={enabled:r.enabled??!0,level:r.level??"info",format:r.format??"json"})}get instance(){return null===this._instance&&(this._instance=this._createLogger()),this._instance}},exports.badRequest=(e="Bad Request",t={})=>o(400,{message:e},t),exports.corsHeaders=(e="*")=>({"Access-Control-Allow-Origin":e}),exports.createResponse=o,exports.created=(e,t={})=>o(201,e,t),exports.internalServerError=(e="Internal Server Error",t={})=>o(500,{message:e},t),exports.jsonHeaders={"Content-Type":"application/json"},exports.noContent=(e={})=>o(204,{},e),exports.notFound=(e="Not Found",t={})=>o(404,{message:e},t),exports.ok=(e,t={})=>o(200,e,t),exports.withRequestTracking=r;
1
+ "use strict";var e=require("pino"),t=require("pino-lambda");const o=t.lambdaRequestTracker();const r=(e,t,o={})=>({statusCode:e,headers:{...o},body:JSON.stringify(t)});exports.Logger=class{constructor(o){this._loggerConfig={enabled:!0,level:"info",format:"json"},this._instance=null,this._createLogger=()=>{const o="json"===this._loggerConfig.format?new t.StructuredLogFormatter:new t.CloudwatchLogFormatter,r=t.pinoLambdaDestination({formatter:o});return e({enabled:this._loggerConfig.enabled,level:this._loggerConfig.level},r)},o&&(this._loggerConfig={enabled:o.enabled??!0,level:o.level??"info",format:o.format??"json"})}get instance(){return null===this._instance&&(this._instance=this._createLogger()),this._instance}},exports.badRequest=(e="Bad Request",t={})=>r(400,{message:e},t),exports.createResponse=r,exports.created=(e,t={})=>r(201,e,t),exports.httpHeaders={contentType:e=>({"Content-Type":e}),json:{"Content-Type":"application/json"},cors:(e="*")=>({"Access-Control-Allow-Origin":e})},exports.internalServerError=(e="Internal Server Error",t={})=>r(500,{message:e},t),exports.noContent=(e={})=>r(204,{},e),exports.notFound=(e="Not Found",t={})=>r(404,{message:e},t),exports.ok=(e,t={})=>r(200,e,t),exports.withRequestTracking=o;
2
2
  //# sourceMappingURL=index.js.map
@@ -4,15 +4,22 @@ import { APIGatewayProxyResult } from 'aws-lambda';
4
4
  */
5
5
  export type Headers = Record<string, string | number | boolean>;
6
6
  /**
7
- * Represents the headers for a JSON API Gateway response
7
+ * Commonly used headers for API Gateway responses
8
8
  */
9
- export declare const jsonHeaders: Headers;
10
- /**
11
- * Generates the headers required for CORS (Cross-Origin Resource Sharing) requests
12
- * @param origin The origin to allow for CORS requests
13
- * @returns Headers containing the CORS configuration
14
- */
15
- export declare const corsHeaders: (origin?: string) => Headers;
9
+ export declare const httpHeaders: {
10
+ /** Content-Type: <type> */
11
+ contentType: (type: string) => {
12
+ 'Content-Type': string;
13
+ };
14
+ /** Content-Type: application/json */
15
+ json: {
16
+ 'Content-Type': string;
17
+ };
18
+ /** Access-Control-Allow-Origin: <origin> */
19
+ cors: (origin?: string) => {
20
+ 'Access-Control-Allow-Origin': string;
21
+ };
22
+ };
16
23
  /**
17
24
  * Creates a standardized API Gateway response.
18
25
  * @param statusCode The HTTP status code of the response
@@ -22,7 +29,7 @@ export declare const corsHeaders: (origin?: string) => Headers;
22
29
  *
23
30
  * @example
24
31
  * ```ts
25
- * const response = createResponse(200, { message: 'Success' }, jsonHeaders);
32
+ * const response = createResponse(200, { message: 'Success' }, httpHeaders.json);
26
33
  * ```
27
34
  */
28
35
  export declare const createResponse: (statusCode: number, body: unknown, headers?: Headers) => APIGatewayProxyResult;
@@ -33,7 +40,7 @@ export declare const createResponse: (statusCode: number, body: unknown, headers
33
40
  * @returns An API Gateway proxy result
34
41
  * @example
35
42
  * ```ts
36
- * const response = ok({ message: 'Success' }, jsonHeaders);
43
+ * const response = ok({ message: 'Success' }, httpHeaders.json);
37
44
  * ```
38
45
  */
39
46
  export declare const ok: (body: unknown, headers?: Headers) => APIGatewayProxyResult;
@@ -44,7 +51,7 @@ export declare const ok: (body: unknown, headers?: Headers) => APIGatewayProxyRe
44
51
  * @returns An API Gateway proxy result
45
52
  * @example
46
53
  * ```ts
47
- * const response = created({ message: 'Resource created' }, jsonHeaders);
54
+ * const response = created({ message: 'Resource created' }, httpHeaders.json);
48
55
  * ```
49
56
  */
50
57
  export declare const created: (body: unknown, headers?: Headers) => APIGatewayProxyResult;
@@ -54,7 +61,7 @@ export declare const created: (body: unknown, headers?: Headers) => APIGatewayPr
54
61
  * @returns An API Gateway proxy result
55
62
  * @example
56
63
  * ```ts
57
- * const response = noContent(corsHeaders());
64
+ * const response = noContent(httpHeaders.cors());
58
65
  * ```
59
66
  */
60
67
  export declare const noContent: (headers?: Headers) => APIGatewayProxyResult;
@@ -65,7 +72,7 @@ export declare const noContent: (headers?: Headers) => APIGatewayProxyResult;
65
72
  * @returns An API Gateway proxy result
66
73
  * @example
67
74
  * ```ts
68
- * const response = badRequest('Invalid input', jsonHeaders);
75
+ * const response = badRequest('Invalid input', httpHeaders.json);
69
76
  * ```
70
77
  */
71
78
  export declare const badRequest: (message?: string, headers?: Headers) => APIGatewayProxyResult;
@@ -76,7 +83,7 @@ export declare const badRequest: (message?: string, headers?: Headers) => APIGat
76
83
  * @returns An API Gateway proxy result
77
84
  * @example
78
85
  * ```ts
79
- * const response = notFound('Resource not found', jsonHeaders);
86
+ * const response = notFound('Resource not found', httpHeaders.json);
80
87
  * ```
81
88
  */
82
89
  export declare const notFound: (message?: string, headers?: Headers) => APIGatewayProxyResult;
@@ -87,7 +94,7 @@ export declare const notFound: (message?: string, headers?: Headers) => APIGatew
87
94
  * @returns An API Gateway proxy result
88
95
  * @example
89
96
  * ```ts
90
- * const response = internalServerError('Something went wrong', jsonHeaders);
97
+ * const response = internalServerError('Something went wrong', httpHeaders.json);
91
98
  * ```
92
99
  */
93
100
  export declare const internalServerError: (message?: string, headers?: Headers) => APIGatewayProxyResult;
@@ -0,0 +1,451 @@
1
+ # API Gateway Responses Guide
2
+
3
+ The Lambda Utilities library provides a set of helper functions for creating properly formatted API Gateway responses. These utilities abstract away the boilerplate of response construction and ensure consistent response formatting across your Lambda functions.
4
+
5
+ ## Overview
6
+
7
+ API Gateway responses require a specific structure with a status code, headers, and a JSON-stringified body. The response helpers provided by Lambda Utilities simplify this by:
8
+
9
+ - Providing typed functions for common HTTP status codes
10
+ - Managing automatic JSON serialization
11
+ - Supporting custom headers
12
+ - Ensuring consistency with AWS Lambda proxy integration specifications
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @leanstacks/lambda-utils
18
+ ```
19
+
20
+ ## Basic Usage
21
+
22
+ ### Creating Responses
23
+
24
+ Import the response helpers from Lambda Utilities:
25
+
26
+ ```typescript
27
+ import { ok, created, badRequest, notFound, internalServerError } from '@leanstacks/lambda-utils';
28
+ ```
29
+
30
+ ### Response Functions
31
+
32
+ #### `ok(body, headers?)`
33
+
34
+ Creates a **200 OK** response.
35
+
36
+ ```typescript
37
+ export const handler = async (event: any) => {
38
+ const data = { id: '123', name: 'Example' };
39
+ return ok(data);
40
+ };
41
+
42
+ // Response:
43
+ // {
44
+ // statusCode: 200,
45
+ // body: '{"id":"123","name":"Example"}',
46
+ // headers: {}
47
+ // }
48
+ ```
49
+
50
+ #### `created(body, headers?)`
51
+
52
+ Creates a **201 Created** response, typically used when a resource is successfully created.
53
+
54
+ ```typescript
55
+ export const handler = async (event: any) => {
56
+ const newResource = { id: '456', name: 'New Resource' };
57
+ return created(newResource);
58
+ };
59
+
60
+ // Response:
61
+ // {
62
+ // statusCode: 201,
63
+ // body: '{"id":"456","name":"New Resource"}',
64
+ // headers: {}
65
+ // }
66
+ ```
67
+
68
+ #### `noContent(headers?)`
69
+
70
+ Creates a **204 No Content** response, used when the request is successful but there's no content to return.
71
+
72
+ ```typescript
73
+ export const handler = async (event: any) => {
74
+ // Delete operation
75
+ return noContent();
76
+ };
77
+
78
+ // Response:
79
+ // {
80
+ // statusCode: 204,
81
+ // body: '{}',
82
+ // headers: {}
83
+ // }
84
+ ```
85
+
86
+ #### `badRequest(message?, headers?)`
87
+
88
+ Creates a **400 Bad Request** error response.
89
+
90
+ ```typescript
91
+ export const handler = async (event: any) => {
92
+ if (!event.body) {
93
+ return badRequest('Request body is required');
94
+ }
95
+ };
96
+
97
+ // Response:
98
+ // {
99
+ // statusCode: 400,
100
+ // body: '{"message":"Request body is required"}',
101
+ // headers: {}
102
+ // }
103
+ ```
104
+
105
+ #### `notFound(message?, headers?)`
106
+
107
+ Creates a **404 Not Found** error response.
108
+
109
+ ```typescript
110
+ export const handler = async (event: any) => {
111
+ const resource = await getResource(event.pathParameters.id);
112
+
113
+ if (!resource) {
114
+ return notFound(`Resource with id ${event.pathParameters.id} not found`);
115
+ }
116
+
117
+ return ok(resource);
118
+ };
119
+
120
+ // Response:
121
+ // {
122
+ // statusCode: 404,
123
+ // body: '{"message":"Resource with id 123 not found"}',
124
+ // headers: {}
125
+ // }
126
+ ```
127
+
128
+ #### `internalServerError(message?, headers?)`
129
+
130
+ Creates a **500 Internal Server Error** response.
131
+
132
+ ```typescript
133
+ export const handler = async (event: any) => {
134
+ try {
135
+ // Process request
136
+ } catch (error) {
137
+ return internalServerError('An unexpected error occurred');
138
+ }
139
+ };
140
+
141
+ // Response:
142
+ // {
143
+ // statusCode: 500,
144
+ // body: '{"message":"An unexpected error occurred"}',
145
+ // headers: {}
146
+ // }
147
+ ```
148
+
149
+ #### `createResponse(statusCode, body, headers?)`
150
+
151
+ Creates a custom response with any status code. Use this for status codes not covered by the helper functions.
152
+
153
+ ```typescript
154
+ import { createResponse } from '@leanstacks/lambda-utils';
155
+
156
+ export const handler = async (event: any) => {
157
+ return createResponse(202, { status: 'Accepted' });
158
+ };
159
+
160
+ // Response:
161
+ // {
162
+ // statusCode: 202,
163
+ // body: '{"status":"Accepted"}',
164
+ // headers: {}
165
+ // }
166
+ ```
167
+
168
+ ## Headers
169
+
170
+ ### HTTP Headers Helpers
171
+
172
+ Lambda Utilities provides a `httpHeaders` object with common header builders:
173
+
174
+ #### `httpHeaders.json`
175
+
176
+ Sets the `Content-Type` header to `application/json`.
177
+
178
+ ```typescript
179
+ import { ok, httpHeaders } from '@leanstacks/lambda-utils';
180
+
181
+ export const handler = async (event: any) => {
182
+ return ok({ message: 'Success' }, httpHeaders.json);
183
+ };
184
+
185
+ // Response:
186
+ // {
187
+ // statusCode: 200,
188
+ // body: '{"message":"Success"}',
189
+ // headers: { 'Content-Type': 'application/json' }
190
+ // }
191
+ ```
192
+
193
+ #### `httpHeaders.contentType(type)`
194
+
195
+ Sets the `Content-Type` header to a custom MIME type.
196
+
197
+ ```typescript
198
+ import { ok, httpHeaders } from '@leanstacks/lambda-utils';
199
+
200
+ export const handler = async (event: any) => {
201
+ return ok(csvData, httpHeaders.contentType('text/csv'));
202
+ };
203
+
204
+ // Response:
205
+ // {
206
+ // statusCode: 200,
207
+ // body: '...',
208
+ // headers: { 'Content-Type': 'text/csv' }
209
+ // }
210
+ ```
211
+
212
+ #### `httpHeaders.cors(origin?)`
213
+
214
+ Sets the `Access-Control-Allow-Origin` header for CORS support. Default is `*`.
215
+
216
+ ```typescript
217
+ import { ok, httpHeaders } from '@leanstacks/lambda-utils';
218
+
219
+ export const handler = async (event: any) => {
220
+ return ok({ data: '...' }, httpHeaders.cors('https://example.com'));
221
+ };
222
+
223
+ // Response:
224
+ // {
225
+ // statusCode: 200,
226
+ // body: '{"data":"..."}',
227
+ // headers: { 'Access-Control-Allow-Origin': 'https://example.com' }
228
+ // }
229
+ ```
230
+
231
+ ### Custom Headers
232
+
233
+ Combine multiple headers or add custom ones by passing a headers object:
234
+
235
+ ```typescript
236
+ import { ok, httpHeaders } from '@leanstacks/lambda-utils';
237
+
238
+ export const handler = async (event: any) => {
239
+ const headers = {
240
+ ...httpHeaders.json,
241
+ ...httpHeaders.cors(),
242
+ 'X-Custom-Header': 'value',
243
+ };
244
+
245
+ return ok({ message: 'Success' }, headers);
246
+ };
247
+
248
+ // Response:
249
+ // {
250
+ // statusCode: 200,
251
+ // body: '{"message":"Success"}',
252
+ // headers: {
253
+ // 'Content-Type': 'application/json',
254
+ // 'Access-Control-Allow-Origin': '*',
255
+ // 'X-Custom-Header': 'value'
256
+ // }
257
+ // }
258
+ ```
259
+
260
+ ## Complete Examples
261
+
262
+ ### Validation and Error Handling
263
+
264
+ ```typescript
265
+ import { ok, badRequest, internalServerError, httpHeaders } from '@leanstacks/lambda-utils';
266
+
267
+ interface RequestBody {
268
+ email: string;
269
+ name: string;
270
+ }
271
+
272
+ export const handler = async (event: any) => {
273
+ try {
274
+ // Validate request
275
+ if (!event.body) {
276
+ return badRequest('Request body is required', httpHeaders.json);
277
+ }
278
+
279
+ const body: RequestBody = JSON.parse(event.body);
280
+
281
+ if (!body.email || !body.name) {
282
+ return badRequest('Missing required fields: email, name', httpHeaders.json);
283
+ }
284
+
285
+ // Process request
286
+ const result = { id: '123', ...body };
287
+
288
+ return ok(result, httpHeaders.json);
289
+ } catch (error) {
290
+ console.error('Handler error:', error);
291
+ return internalServerError('Failed to process request', httpHeaders.json);
292
+ }
293
+ };
294
+ ```
295
+
296
+ ### CRUD Operations
297
+
298
+ ```typescript
299
+ import {
300
+ ok,
301
+ created,
302
+ noContent,
303
+ badRequest,
304
+ notFound,
305
+ internalServerError,
306
+ httpHeaders,
307
+ } from '@leanstacks/lambda-utils';
308
+
309
+ const headers = httpHeaders.json;
310
+
311
+ export const handlers = {
312
+ // GET /items/{id}
313
+ getItem: async (event: any) => {
314
+ try {
315
+ const item = await findItem(event.pathParameters.id);
316
+ return item ? ok(item, headers) : notFound('Item not found', headers);
317
+ } catch (error) {
318
+ return internalServerError('Failed to retrieve item', headers);
319
+ }
320
+ },
321
+
322
+ // POST /items
323
+ createItem: async (event: any) => {
324
+ try {
325
+ if (!event.body) {
326
+ return badRequest('Request body is required', headers);
327
+ }
328
+
329
+ const newItem = await saveItem(JSON.parse(event.body));
330
+ return created(newItem, headers);
331
+ } catch (error) {
332
+ return internalServerError('Failed to create item', headers);
333
+ }
334
+ },
335
+
336
+ // DELETE /items/{id}
337
+ deleteItem: async (event: any) => {
338
+ try {
339
+ await removeItem(event.pathParameters.id);
340
+ return noContent(headers);
341
+ } catch (error) {
342
+ return internalServerError('Failed to delete item', headers);
343
+ }
344
+ },
345
+ };
346
+ ```
347
+
348
+ ### CORS-Enabled Handler
349
+
350
+ ```typescript
351
+ import { ok, badRequest, httpHeaders } from '@leanstacks/lambda-utils';
352
+
353
+ const corsHeaders = {
354
+ ...httpHeaders.json,
355
+ ...httpHeaders.cors('https://app.example.com'),
356
+ 'X-API-Version': '1.0',
357
+ };
358
+
359
+ export const handler = async (event: any) => {
360
+ // Handle preflight requests
361
+ if (event.requestContext.http.method === 'OPTIONS') {
362
+ return ok({}, corsHeaders);
363
+ }
364
+
365
+ if (!event.body) {
366
+ return badRequest('Body is required', corsHeaders);
367
+ }
368
+
369
+ return ok({ processed: true }, corsHeaders);
370
+ };
371
+ ```
372
+
373
+ ## Best Practices
374
+
375
+ 1. **Use Consistent Headers** – Define headers once and reuse them across handlers to maintain consistency.
376
+
377
+ ```typescript
378
+ const defaultHeaders = httpHeaders.json;
379
+ ```
380
+
381
+ 2. **Provide Meaningful Error Messages** – Include specific error details to help clients understand what went wrong.
382
+
383
+ ```typescript
384
+ return badRequest(`Missing required field: ${fieldName}`, headers);
385
+ ```
386
+
387
+ 3. **Handle Errors Gracefully** – Use try-catch blocks and return appropriate error responses.
388
+
389
+ ```typescript
390
+ try {
391
+ // Process
392
+ } catch (error) {
393
+ return internalServerError('Operation failed', headers);
394
+ }
395
+ ```
396
+
397
+ 4. **Use Appropriate Status Codes** – Choose the correct HTTP status code for each scenario:
398
+ - `200 OK` – Request successful
399
+ - `201 Created` – Resource created
400
+ - `204 No Content` – Request successful, no content
401
+ - `400 Bad Request` – Invalid input
402
+ - `404 Not Found` – Resource not found
403
+ - `500 Internal Server Error` – Unexpected error
404
+
405
+ 5. **Log Errors** – Log error details for debugging while returning user-friendly messages.
406
+
407
+ ```typescript
408
+ catch (error) {
409
+ logger.error({ message: 'Processing failed', error: error.message });
410
+ return internalServerError('Failed to process request', headers);
411
+ }
412
+ ```
413
+
414
+ 6. **Combine with Logging** – Use response helpers with structured logging for complete observability.
415
+
416
+ ```typescript
417
+ import { Logger } from '@leanstacks/lambda-utils';
418
+ const logger = new Logger().instance;
419
+
420
+ export const handler = async (event: any) => {
421
+ logger.info('Request received', { path: event.path });
422
+ return ok({ message: 'Success' }, httpHeaders.json);
423
+ };
424
+ ```
425
+
426
+ ## Type Safety
427
+
428
+ All response functions are fully typed with TypeScript. The `body` parameter accepts `unknown`, allowing you to pass any serializable value:
429
+
430
+ ```typescript
431
+ interface User {
432
+ id: string;
433
+ name: string;
434
+ email: string;
435
+ }
436
+
437
+ const user: User = { id: '1', name: 'John', email: 'john@example.com' };
438
+ return ok(user); // ✓ Type-safe
439
+ ```
440
+
441
+ Error functions accept string or number messages:
442
+
443
+ ```typescript
444
+ return badRequest('Invalid input'); // ✓ String message
445
+ return notFound(404); // ✓ Number message
446
+ ```
447
+
448
+ ## Further reading
449
+
450
+ - **[Logging Guide](./LOGGING.md)** – Structured logging for Lambda functions
451
+ - **[Back to the project documentation](README.md)**
package/docs/LOGGING.md CHANGED
@@ -327,7 +327,8 @@ describe('MyHandler', () => {
327
327
 
328
328
  ## Further reading
329
329
 
330
- - [Pino Documentation](https://getpino.io/)
331
- - [AWS Lambda Environment and Context](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html)
332
- - [CloudWatch Logs Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html)
333
- - [Back to the project documentation](README.md)
330
+ - **[Pino Documentation](https://getpino.io/)**
331
+ - **[Pino Lambda Documentation](https://github.com/FormidableLabs/pino-lambda#readme)**
332
+ - **[AWS Lambda Environment and Context](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html)**
333
+ - **[CloudWatch Logs Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html)**
334
+ - **[Back to the project documentation](README.md)**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leanstacks/lambda-utils",
3
- "version": "0.2.0-alpha.2",
3
+ "version": "0.2.0",
4
4
  "description": "A collection of utilities and helper functions designed to streamline the development of AWS Lambda functions using TypeScript.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -35,6 +35,7 @@
35
35
  "lint": "eslint src",
36
36
  "lint:fix": "eslint src --fix",
37
37
  "prepare": "husky",
38
+ "prepublish": "npm run clean && npm run build",
38
39
  "test": "jest",
39
40
  "test:watch": "jest --watch",
40
41
  "test:coverage": "jest --coverage"