@fnd-platform/api 1.0.0-alpha.1
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/LICENSE +21 -0
- package/README.md +204 -0
- package/lib/api-project.d.ts +99 -0
- package/lib/api-project.d.ts.map +1 -0
- package/lib/api-project.js +668 -0
- package/lib/api-project.js.map +1 -0
- package/lib/handlers/content.d.ts +52 -0
- package/lib/handlers/content.d.ts.map +1 -0
- package/lib/handlers/content.js +122 -0
- package/lib/handlers/content.js.map +1 -0
- package/lib/handlers/health.d.ts +43 -0
- package/lib/handlers/health.d.ts.map +1 -0
- package/lib/handlers/health.js +43 -0
- package/lib/handlers/health.js.map +1 -0
- package/lib/handlers/media.d.ts +86 -0
- package/lib/handlers/media.d.ts.map +1 -0
- package/lib/handlers/media.js +287 -0
- package/lib/handlers/media.js.map +1 -0
- package/lib/index.d.ts +22 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +50 -0
- package/lib/index.js.map +1 -0
- package/lib/lib/errors.d.ts +114 -0
- package/lib/lib/errors.d.ts.map +1 -0
- package/lib/lib/errors.js +154 -0
- package/lib/lib/errors.js.map +1 -0
- package/lib/lib/middleware.d.ts +33 -0
- package/lib/lib/middleware.d.ts.map +1 -0
- package/lib/lib/middleware.js +36 -0
- package/lib/lib/middleware.js.map +1 -0
- package/lib/lib/request.d.ts +90 -0
- package/lib/lib/request.d.ts.map +1 -0
- package/lib/lib/request.js +115 -0
- package/lib/lib/request.js.map +1 -0
- package/lib/lib/response.d.ts +131 -0
- package/lib/lib/response.d.ts.map +1 -0
- package/lib/lib/response.js +163 -0
- package/lib/lib/response.js.map +1 -0
- package/lib/middleware/auth.d.ts +57 -0
- package/lib/middleware/auth.d.ts.map +1 -0
- package/lib/middleware/auth.js +62 -0
- package/lib/middleware/auth.js.map +1 -0
- package/lib/middleware/cors.d.ts +51 -0
- package/lib/middleware/cors.d.ts.map +1 -0
- package/lib/middleware/cors.js +62 -0
- package/lib/middleware/cors.js.map +1 -0
- package/lib/middleware/error-handler.d.ts +38 -0
- package/lib/middleware/error-handler.d.ts.map +1 -0
- package/lib/middleware/error-handler.js +49 -0
- package/lib/middleware/error-handler.js.map +1 -0
- package/lib/middleware/index.d.ts +15 -0
- package/lib/middleware/index.d.ts.map +1 -0
- package/lib/middleware/index.js +49 -0
- package/lib/middleware/index.js.map +1 -0
- package/lib/middleware/logging.d.ts +48 -0
- package/lib/middleware/logging.d.ts.map +1 -0
- package/lib/middleware/logging.js +58 -0
- package/lib/middleware/logging.js.map +1 -0
- package/lib/middleware/validation.d.ts +41 -0
- package/lib/middleware/validation.d.ts.map +1 -0
- package/lib/middleware/validation.js +76 -0
- package/lib/middleware/validation.js.map +1 -0
- package/lib/options.d.ts +48 -0
- package/lib/options.d.ts.map +1 -0
- package/lib/options.js +3 -0
- package/lib/options.js.map +1 -0
- package/lib/types/api.d.ts +108 -0
- package/lib/types/api.d.ts.map +1 -0
- package/lib/types/api.js +11 -0
- package/lib/types/api.js.map +1 -0
- package/lib/types/middleware.d.ts +59 -0
- package/lib/types/middleware.d.ts.map +1 -0
- package/lib/types/middleware.js +11 -0
- package/lib/types/middleware.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response helper functions for Lambda handlers.
|
|
3
|
+
*
|
|
4
|
+
* These helpers provide consistent response formatting with
|
|
5
|
+
* a standard envelope structure and CORS headers.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
import type { APIGatewayProxyResult } from 'aws-lambda';
|
|
10
|
+
/**
|
|
11
|
+
* Success response envelope structure.
|
|
12
|
+
*/
|
|
13
|
+
export interface SuccessResponse<T = unknown> {
|
|
14
|
+
success: true;
|
|
15
|
+
data: T;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Error response envelope structure.
|
|
19
|
+
*/
|
|
20
|
+
export interface ErrorResponse {
|
|
21
|
+
success: false;
|
|
22
|
+
error: {
|
|
23
|
+
code: string;
|
|
24
|
+
message: string;
|
|
25
|
+
details?: unknown;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Creates a successful API response.
|
|
30
|
+
*
|
|
31
|
+
* @param data - Response body data
|
|
32
|
+
* @param statusCode - HTTP status code (default: 200)
|
|
33
|
+
* @returns API Gateway proxy result with success envelope
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* return success({ user: { id: '123', name: 'John' } });
|
|
38
|
+
* // { statusCode: 200, body: '{"success":true,"data":{"user":{...}}}' }
|
|
39
|
+
*
|
|
40
|
+
* return success({ id: '123' }, 201);
|
|
41
|
+
* // { statusCode: 201, body: '{"success":true,"data":{"id":"123"}}' }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function success<T>(data: T, statusCode?: number): APIGatewayProxyResult;
|
|
45
|
+
/**
|
|
46
|
+
* Creates an error API response.
|
|
47
|
+
*
|
|
48
|
+
* @param err - Error object or message string
|
|
49
|
+
* @param statusCode - HTTP status code (default: 500)
|
|
50
|
+
* @returns API Gateway proxy result with error envelope
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* return error('Something went wrong');
|
|
55
|
+
* // { statusCode: 500, body: '{"success":false,"error":{"code":"INTERNAL_ERROR",...}}' }
|
|
56
|
+
*
|
|
57
|
+
* return error(new NotFoundError('User not found'), 404);
|
|
58
|
+
* // { statusCode: 404, body: '{"success":false,"error":{"code":"NOT_FOUND",...}}' }
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function error(err: Error | string, statusCode?: number): APIGatewayProxyResult;
|
|
62
|
+
/**
|
|
63
|
+
* Creates a 404 Not Found response.
|
|
64
|
+
*
|
|
65
|
+
* @param message - Error message (default: 'Resource not found')
|
|
66
|
+
* @returns API Gateway proxy result with 404 status
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* return notFound('User not found');
|
|
71
|
+
* // { statusCode: 404, body: '{"success":false,"error":{"code":"NOT_FOUND",...}}' }
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function notFound(message?: string): APIGatewayProxyResult;
|
|
75
|
+
/**
|
|
76
|
+
* Creates a 401 Unauthorized response.
|
|
77
|
+
*
|
|
78
|
+
* @param message - Error message (default: 'Unauthorized')
|
|
79
|
+
* @returns API Gateway proxy result with 401 status
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* return unauthorized('Invalid token');
|
|
84
|
+
* // { statusCode: 401, body: '{"success":false,"error":{"code":"UNAUTHORIZED",...}}' }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function unauthorized(message?: string): APIGatewayProxyResult;
|
|
88
|
+
/**
|
|
89
|
+
* Creates a 403 Forbidden response.
|
|
90
|
+
*
|
|
91
|
+
* @param message - Error message (default: 'Forbidden')
|
|
92
|
+
* @returns API Gateway proxy result with 403 status
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* return forbidden('Admin access required');
|
|
97
|
+
* // { statusCode: 403, body: '{"success":false,"error":{"code":"FORBIDDEN",...}}' }
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export declare function forbidden(message?: string): APIGatewayProxyResult;
|
|
101
|
+
/**
|
|
102
|
+
* Creates a 400 Bad Request response.
|
|
103
|
+
*
|
|
104
|
+
* @param message - Error message (default: 'Bad request')
|
|
105
|
+
* @param details - Optional validation error details
|
|
106
|
+
* @returns API Gateway proxy result with 400 status
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* return badRequest('Invalid email format');
|
|
111
|
+
* // { statusCode: 400, body: '{"success":false,"error":{"code":"VALIDATION_ERROR",...}}' }
|
|
112
|
+
*
|
|
113
|
+
* return badRequest('Validation failed', { fields: ['email', 'name'] });
|
|
114
|
+
* // { statusCode: 400, body: '{"success":false,"error":{"code":"VALIDATION_ERROR",...,"details":{...}}}' }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export declare function badRequest(message?: string, details?: unknown): APIGatewayProxyResult;
|
|
118
|
+
/**
|
|
119
|
+
* Creates a 201 Created response.
|
|
120
|
+
*
|
|
121
|
+
* @param data - Created resource data
|
|
122
|
+
* @returns API Gateway proxy result with 201 status
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* return created({ id: '123', name: 'New Item' });
|
|
127
|
+
* // { statusCode: 201, body: '{"success":true,"data":{"id":"123","name":"New Item"}}' }
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export declare function created<T>(data: T): APIGatewayProxyResult;
|
|
131
|
+
//# sourceMappingURL=response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/lib/response.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AASxD;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,CAAC,CAAC;CACT;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;CACH;AAcD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,SAAM,GAAG,qBAAqB,CAO3E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,KAAK,GAAG,MAAM,EAAE,UAAU,SAAM,GAAG,qBAAqB,CAelF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,OAAO,SAAuB,GAAG,qBAAqB,CAE9E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,OAAO,SAAiB,GAAG,qBAAqB,CAE5E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,OAAO,SAAc,GAAG,qBAAqB,CAEtE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,OAAO,SAAgB,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,qBAAqB,CAE5F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,qBAAqB,CAEzD"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Response helper functions for Lambda handlers.
|
|
4
|
+
*
|
|
5
|
+
* These helpers provide consistent response formatting with
|
|
6
|
+
* a standard envelope structure and CORS headers.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.success = success;
|
|
12
|
+
exports.error = error;
|
|
13
|
+
exports.notFound = notFound;
|
|
14
|
+
exports.unauthorized = unauthorized;
|
|
15
|
+
exports.forbidden = forbidden;
|
|
16
|
+
exports.badRequest = badRequest;
|
|
17
|
+
exports.created = created;
|
|
18
|
+
const errors_1 = require("./errors");
|
|
19
|
+
/**
|
|
20
|
+
* Default headers included in all responses.
|
|
21
|
+
* Includes Content-Type and CORS headers.
|
|
22
|
+
*/
|
|
23
|
+
function defaultHeaders() {
|
|
24
|
+
return {
|
|
25
|
+
'Content-Type': 'application/json',
|
|
26
|
+
'Access-Control-Allow-Origin': '*',
|
|
27
|
+
'Access-Control-Allow-Headers': 'Content-Type,Authorization',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Creates a successful API response.
|
|
32
|
+
*
|
|
33
|
+
* @param data - Response body data
|
|
34
|
+
* @param statusCode - HTTP status code (default: 200)
|
|
35
|
+
* @returns API Gateway proxy result with success envelope
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* return success({ user: { id: '123', name: 'John' } });
|
|
40
|
+
* // { statusCode: 200, body: '{"success":true,"data":{"user":{...}}}' }
|
|
41
|
+
*
|
|
42
|
+
* return success({ id: '123' }, 201);
|
|
43
|
+
* // { statusCode: 201, body: '{"success":true,"data":{"id":"123"}}' }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
function success(data, statusCode = 200) {
|
|
47
|
+
const body = { success: true, data };
|
|
48
|
+
return {
|
|
49
|
+
statusCode,
|
|
50
|
+
headers: defaultHeaders(),
|
|
51
|
+
body: JSON.stringify(body),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Creates an error API response.
|
|
56
|
+
*
|
|
57
|
+
* @param err - Error object or message string
|
|
58
|
+
* @param statusCode - HTTP status code (default: 500)
|
|
59
|
+
* @returns API Gateway proxy result with error envelope
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* return error('Something went wrong');
|
|
64
|
+
* // { statusCode: 500, body: '{"success":false,"error":{"code":"INTERNAL_ERROR",...}}' }
|
|
65
|
+
*
|
|
66
|
+
* return error(new NotFoundError('User not found'), 404);
|
|
67
|
+
* // { statusCode: 404, body: '{"success":false,"error":{"code":"NOT_FOUND",...}}' }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
function error(err, statusCode = 500) {
|
|
71
|
+
const message = typeof err === 'string' ? err : err.message;
|
|
72
|
+
const code = err instanceof errors_1.ApiError ? err.code : 'INTERNAL_ERROR';
|
|
73
|
+
const details = err instanceof errors_1.ApiError ? err.details : undefined;
|
|
74
|
+
const body = {
|
|
75
|
+
success: false,
|
|
76
|
+
error: { code, message, details },
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
statusCode,
|
|
80
|
+
headers: defaultHeaders(),
|
|
81
|
+
body: JSON.stringify(body),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Creates a 404 Not Found response.
|
|
86
|
+
*
|
|
87
|
+
* @param message - Error message (default: 'Resource not found')
|
|
88
|
+
* @returns API Gateway proxy result with 404 status
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* return notFound('User not found');
|
|
93
|
+
* // { statusCode: 404, body: '{"success":false,"error":{"code":"NOT_FOUND",...}}' }
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
function notFound(message = 'Resource not found') {
|
|
97
|
+
return error(new errors_1.NotFoundError(message), 404);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Creates a 401 Unauthorized response.
|
|
101
|
+
*
|
|
102
|
+
* @param message - Error message (default: 'Unauthorized')
|
|
103
|
+
* @returns API Gateway proxy result with 401 status
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* return unauthorized('Invalid token');
|
|
108
|
+
* // { statusCode: 401, body: '{"success":false,"error":{"code":"UNAUTHORIZED",...}}' }
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
function unauthorized(message = 'Unauthorized') {
|
|
112
|
+
return error(new errors_1.UnauthorizedError(message), 401);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Creates a 403 Forbidden response.
|
|
116
|
+
*
|
|
117
|
+
* @param message - Error message (default: 'Forbidden')
|
|
118
|
+
* @returns API Gateway proxy result with 403 status
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* return forbidden('Admin access required');
|
|
123
|
+
* // { statusCode: 403, body: '{"success":false,"error":{"code":"FORBIDDEN",...}}' }
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
function forbidden(message = 'Forbidden') {
|
|
127
|
+
return error(new errors_1.ForbiddenError(message), 403);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Creates a 400 Bad Request response.
|
|
131
|
+
*
|
|
132
|
+
* @param message - Error message (default: 'Bad request')
|
|
133
|
+
* @param details - Optional validation error details
|
|
134
|
+
* @returns API Gateway proxy result with 400 status
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* return badRequest('Invalid email format');
|
|
139
|
+
* // { statusCode: 400, body: '{"success":false,"error":{"code":"VALIDATION_ERROR",...}}' }
|
|
140
|
+
*
|
|
141
|
+
* return badRequest('Validation failed', { fields: ['email', 'name'] });
|
|
142
|
+
* // { statusCode: 400, body: '{"success":false,"error":{"code":"VALIDATION_ERROR",...,"details":{...}}}' }
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
function badRequest(message = 'Bad request', details) {
|
|
146
|
+
return error(new errors_1.ValidationError(message, details), 400);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Creates a 201 Created response.
|
|
150
|
+
*
|
|
151
|
+
* @param data - Created resource data
|
|
152
|
+
* @returns API Gateway proxy result with 201 status
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```typescript
|
|
156
|
+
* return created({ id: '123', name: 'New Item' });
|
|
157
|
+
* // { statusCode: 201, body: '{"success":true,"data":{"id":"123","name":"New Item"}}' }
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
function created(data) {
|
|
161
|
+
return success(data, 201);
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/lib/response.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AA2DH,0BAOC;AAkBD,sBAeC;AAcD,4BAEC;AAcD,oCAEC;AAcD,8BAEC;AAkBD,gCAEC;AAcD,0BAEC;AApLD,qCAMkB;AAsBlB;;;GAGG;AACH,SAAS,cAAc;IACrB,OAAO;QACL,cAAc,EAAE,kBAAkB;QAClC,6BAA6B,EAAE,GAAG;QAClC,8BAA8B,EAAE,4BAA4B;KAC7D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,OAAO,CAAI,IAAO,EAAE,UAAU,GAAG,GAAG;IAClD,MAAM,IAAI,GAAuB,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACzD,OAAO;QACL,UAAU;QACV,OAAO,EAAE,cAAc,EAAE;QACzB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,KAAK,CAAC,GAAmB,EAAE,UAAU,GAAG,GAAG;IACzD,MAAM,OAAO,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;IAC5D,MAAM,IAAI,GAAG,GAAG,YAAY,iBAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC;IACnE,MAAM,OAAO,GAAG,GAAG,YAAY,iBAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAElE,MAAM,IAAI,GAAkB;QAC1B,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE;KAClC,CAAC;IAEF,OAAO;QACL,UAAU;QACV,OAAO,EAAE,cAAc,EAAE;QACzB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,QAAQ,CAAC,OAAO,GAAG,oBAAoB;IACrD,OAAO,KAAK,CAAC,IAAI,sBAAa,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,YAAY,CAAC,OAAO,GAAG,cAAc;IACnD,OAAO,KAAK,CAAC,IAAI,0BAAiB,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,SAAS,CAAC,OAAO,GAAG,WAAW;IAC7C,OAAO,KAAK,CAAC,IAAI,uBAAc,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,UAAU,CAAC,OAAO,GAAG,aAAa,EAAE,OAAiB;IACnE,OAAO,KAAK,CAAC,IAAI,wBAAe,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,OAAO,CAAI,IAAO;IAChC,OAAO,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication middleware for Lambda handlers.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
import type { APIGatewayProxyEvent } from 'aws-lambda';
|
|
7
|
+
import type { Middleware } from '../types/middleware';
|
|
8
|
+
import type { AuthenticatedEvent } from '../types/api';
|
|
9
|
+
/**
|
|
10
|
+
* Authentication configuration options.
|
|
11
|
+
*/
|
|
12
|
+
export interface AuthOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Required roles (Cognito groups) for access.
|
|
15
|
+
* User must have at least one of the specified roles.
|
|
16
|
+
*/
|
|
17
|
+
roles?: string[];
|
|
18
|
+
/**
|
|
19
|
+
* Paths to skip authentication for.
|
|
20
|
+
* Useful for health checks or public endpoints.
|
|
21
|
+
* @default []
|
|
22
|
+
*/
|
|
23
|
+
skipPaths?: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Middleware that validates JWT tokens from Cognito.
|
|
27
|
+
*
|
|
28
|
+
* In production, API Gateway validates JWT tokens. This middleware
|
|
29
|
+
* validates that the claims are present and checks role requirements.
|
|
30
|
+
*
|
|
31
|
+
* @param options - Authentication configuration
|
|
32
|
+
* @returns Middleware that validates authentication
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // Basic auth - any authenticated user
|
|
37
|
+
* const handler = compose(
|
|
38
|
+
* withErrorHandler(),
|
|
39
|
+
* withAuth()
|
|
40
|
+
* )(async (event) => {
|
|
41
|
+
* const userId = event.requestContext.authorizer.claims.sub;
|
|
42
|
+
* return success({ userId });
|
|
43
|
+
* });
|
|
44
|
+
*
|
|
45
|
+
* // Role-based auth - admin only
|
|
46
|
+
* const adminHandler = compose(
|
|
47
|
+
* withErrorHandler(),
|
|
48
|
+
* withAuth({ roles: ['admin'] })
|
|
49
|
+
* )(async (event) => {
|
|
50
|
+
* return success({ message: 'Admin access granted' });
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare function withAuth(
|
|
55
|
+
options?: AuthOptions
|
|
56
|
+
): Middleware<APIGatewayProxyEvent, AuthenticatedEvent>;
|
|
57
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGvD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,QAAQ,CACtB,OAAO,GAAE,WAAgB,GACxB,UAAU,CAAC,oBAAoB,EAAE,kBAAkB,CAAC,CA4BtD"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* Authentication middleware for Lambda handlers.
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
8
|
+
exports.withAuth = withAuth;
|
|
9
|
+
const response_1 = require('../lib/response');
|
|
10
|
+
/**
|
|
11
|
+
* Middleware that validates JWT tokens from Cognito.
|
|
12
|
+
*
|
|
13
|
+
* In production, API Gateway validates JWT tokens. This middleware
|
|
14
|
+
* validates that the claims are present and checks role requirements.
|
|
15
|
+
*
|
|
16
|
+
* @param options - Authentication configuration
|
|
17
|
+
* @returns Middleware that validates authentication
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // Basic auth - any authenticated user
|
|
22
|
+
* const handler = compose(
|
|
23
|
+
* withErrorHandler(),
|
|
24
|
+
* withAuth()
|
|
25
|
+
* )(async (event) => {
|
|
26
|
+
* const userId = event.requestContext.authorizer.claims.sub;
|
|
27
|
+
* return success({ userId });
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* // Role-based auth - admin only
|
|
31
|
+
* const adminHandler = compose(
|
|
32
|
+
* withErrorHandler(),
|
|
33
|
+
* withAuth({ roles: ['admin'] })
|
|
34
|
+
* )(async (event) => {
|
|
35
|
+
* return success({ message: 'Admin access granted' });
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
function withAuth(options = {}) {
|
|
40
|
+
const { roles, skipPaths = [] } = options;
|
|
41
|
+
return (handler) => async (event, context) => {
|
|
42
|
+
// Skip auth for certain paths
|
|
43
|
+
if (skipPaths.some((path) => event.path?.includes(path))) {
|
|
44
|
+
return handler(event, context);
|
|
45
|
+
}
|
|
46
|
+
// Get claims from API Gateway authorizer
|
|
47
|
+
const claims = event.requestContext?.authorizer?.claims;
|
|
48
|
+
if (!claims || !claims.sub) {
|
|
49
|
+
return (0, response_1.unauthorized)('Missing or invalid authentication');
|
|
50
|
+
}
|
|
51
|
+
// Check role requirements
|
|
52
|
+
if (roles && roles.length > 0) {
|
|
53
|
+
const userGroups = claims['cognito:groups'] || [];
|
|
54
|
+
const hasRequiredRole = roles.some((role) => userGroups.includes(role));
|
|
55
|
+
if (!hasRequiredRole) {
|
|
56
|
+
return (0, response_1.forbidden)(`Required role: ${roles.join(' or ')}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return handler(event, context);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAsDH,4BA8BC;AA/ED,8CAA0D;AAoB1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,SAAgB,QAAQ,CACtB,UAAuB,EAAE;IAEzB,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IAE1C,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC3C,8BAA8B;QAC9B,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACzD,OAAO,OAAO,CAAC,KAA2B,EAAE,OAAO,CAAC,CAAC;QACvD,CAAC;QAED,yCAAyC;QACzC,MAAM,MAAM,GAAI,KAAK,CAAC,cAAsB,EAAE,UAAU,EAAE,MAAM,CAAC;QAEjE,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;YAC3B,OAAO,IAAA,uBAAY,EAAC,mCAAmC,CAAC,CAAC;QAC3D,CAAC;QAED,0BAA0B;QAC1B,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAa,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;YAC5D,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YAExE,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,OAAO,IAAA,oBAAS,EAAC,kBAAkB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC,KAA2B,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORS middleware for Lambda handlers.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
import type { Middleware } from '../types/middleware';
|
|
7
|
+
/**
|
|
8
|
+
* CORS configuration options.
|
|
9
|
+
*/
|
|
10
|
+
export interface CorsOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Allowed origin(s). Use '*' for any origin.
|
|
13
|
+
* @default '*'
|
|
14
|
+
*/
|
|
15
|
+
origin?: string | string[];
|
|
16
|
+
/**
|
|
17
|
+
* Allowed HTTP methods.
|
|
18
|
+
* @default ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']
|
|
19
|
+
*/
|
|
20
|
+
methods?: string[];
|
|
21
|
+
/**
|
|
22
|
+
* Allowed request headers.
|
|
23
|
+
* @default ['Content-Type', 'Authorization']
|
|
24
|
+
*/
|
|
25
|
+
headers?: string[];
|
|
26
|
+
/**
|
|
27
|
+
* Whether to include credentials.
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
credentials?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Middleware that adds CORS headers to responses.
|
|
34
|
+
*
|
|
35
|
+
* Also handles OPTIONS preflight requests automatically.
|
|
36
|
+
*
|
|
37
|
+
* @param options - CORS configuration
|
|
38
|
+
* @returns Middleware that adds CORS headers
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const handler = compose(
|
|
43
|
+
* withCors({ origin: 'https://example.com', credentials: true }),
|
|
44
|
+
* withErrorHandler()
|
|
45
|
+
* )(async (event) => {
|
|
46
|
+
* return success({ data: 'value' });
|
|
47
|
+
* });
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function withCors(options?: CorsOptions): Middleware;
|
|
51
|
+
//# sourceMappingURL=cors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE3B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,WAAgB,GAAG,UAAU,CAuC9D"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* CORS middleware for Lambda handlers.
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
8
|
+
exports.withCors = withCors;
|
|
9
|
+
/**
|
|
10
|
+
* Middleware that adds CORS headers to responses.
|
|
11
|
+
*
|
|
12
|
+
* Also handles OPTIONS preflight requests automatically.
|
|
13
|
+
*
|
|
14
|
+
* @param options - CORS configuration
|
|
15
|
+
* @returns Middleware that adds CORS headers
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const handler = compose(
|
|
20
|
+
* withCors({ origin: 'https://example.com', credentials: true }),
|
|
21
|
+
* withErrorHandler()
|
|
22
|
+
* )(async (event) => {
|
|
23
|
+
* return success({ data: 'value' });
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
function withCors(options = {}) {
|
|
28
|
+
const {
|
|
29
|
+
origin = '*',
|
|
30
|
+
methods = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
31
|
+
headers = ['Content-Type', 'Authorization'],
|
|
32
|
+
credentials = false,
|
|
33
|
+
} = options;
|
|
34
|
+
const corsHeaders = {
|
|
35
|
+
'Access-Control-Allow-Origin': Array.isArray(origin) ? origin[0] : origin,
|
|
36
|
+
'Access-Control-Allow-Methods': methods.join(','),
|
|
37
|
+
'Access-Control-Allow-Headers': headers.join(','),
|
|
38
|
+
};
|
|
39
|
+
if (credentials) {
|
|
40
|
+
corsHeaders['Access-Control-Allow-Credentials'] = 'true';
|
|
41
|
+
}
|
|
42
|
+
return (handler) => async (event, context) => {
|
|
43
|
+
// Handle preflight requests
|
|
44
|
+
if (event.httpMethod === 'OPTIONS') {
|
|
45
|
+
return {
|
|
46
|
+
statusCode: 204,
|
|
47
|
+
headers: corsHeaders,
|
|
48
|
+
body: '',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const response = await handler(event, context);
|
|
52
|
+
// Merge CORS headers with response headers
|
|
53
|
+
return {
|
|
54
|
+
...response,
|
|
55
|
+
headers: {
|
|
56
|
+
...response.headers,
|
|
57
|
+
...corsHeaders,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=cors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAmDH,4BAuCC;AAzDD;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,QAAQ,CAAC,UAAuB,EAAE;IAChD,MAAM,EACJ,MAAM,GAAG,GAAG,EACZ,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,EACrD,OAAO,GAAG,CAAC,cAAc,EAAE,eAAe,CAAC,EAC3C,WAAW,GAAG,KAAK,GACpB,GAAG,OAAO,CAAC;IAEZ,MAAM,WAAW,GAA2B;QAC1C,6BAA6B,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM;QACzE,8BAA8B,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;QACjD,8BAA8B,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;KAClD,CAAC;IAEF,IAAI,WAAW,EAAE,CAAC;QAChB,WAAW,CAAC,kCAAkC,CAAC,GAAG,MAAM,CAAC;IAC3D,CAAC;IAED,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC3C,4BAA4B;QAC5B,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACnC,OAAO;gBACL,UAAU,EAAE,GAAG;gBACf,OAAO,EAAE,WAAW;gBACpB,IAAI,EAAE,EAAE;aACT,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAE/C,2CAA2C;QAC3C,OAAO;YACL,GAAG,QAAQ;YACX,OAAO,EAAE;gBACP,GAAG,QAAQ,CAAC,OAAO;gBACnB,GAAG,WAAW;aACf;SACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error handling middleware for Lambda handlers.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
import type { Middleware } from '../types/middleware';
|
|
7
|
+
/**
|
|
8
|
+
* Options for error handler middleware.
|
|
9
|
+
*/
|
|
10
|
+
export interface ErrorHandlerOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Whether to log errors to console.
|
|
13
|
+
* @default true
|
|
14
|
+
*/
|
|
15
|
+
logErrors?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Middleware that catches errors and returns appropriate error responses.
|
|
19
|
+
*
|
|
20
|
+
* This should be the outermost middleware (first in compose) to catch
|
|
21
|
+
* all errors from inner middleware and the handler.
|
|
22
|
+
*
|
|
23
|
+
* @param options - Configuration options
|
|
24
|
+
* @returns Middleware that wraps handlers with error handling
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const handler = compose(
|
|
29
|
+
* withErrorHandler({ logErrors: true }),
|
|
30
|
+
* withAuth()
|
|
31
|
+
* )(async (event) => {
|
|
32
|
+
* throw new NotFoundError('User not found');
|
|
33
|
+
* });
|
|
34
|
+
* // Returns: { statusCode: 404, body: '{"success":false,"error":{...}}' }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function withErrorHandler(options?: ErrorHandlerOptions): Middleware;
|
|
38
|
+
//# sourceMappingURL=error-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAItD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,mBAAwB,GAAG,UAAU,CAoB9E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* Error handling middleware for Lambda handlers.
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
8
|
+
exports.withErrorHandler = withErrorHandler;
|
|
9
|
+
const response_1 = require('../lib/response');
|
|
10
|
+
const errors_1 = require('../lib/errors');
|
|
11
|
+
/**
|
|
12
|
+
* Middleware that catches errors and returns appropriate error responses.
|
|
13
|
+
*
|
|
14
|
+
* This should be the outermost middleware (first in compose) to catch
|
|
15
|
+
* all errors from inner middleware and the handler.
|
|
16
|
+
*
|
|
17
|
+
* @param options - Configuration options
|
|
18
|
+
* @returns Middleware that wraps handlers with error handling
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const handler = compose(
|
|
23
|
+
* withErrorHandler({ logErrors: true }),
|
|
24
|
+
* withAuth()
|
|
25
|
+
* )(async (event) => {
|
|
26
|
+
* throw new NotFoundError('User not found');
|
|
27
|
+
* });
|
|
28
|
+
* // Returns: { statusCode: 404, body: '{"success":false,"error":{...}}' }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
function withErrorHandler(options = {}) {
|
|
32
|
+
const { logErrors = true } = options;
|
|
33
|
+
return (handler) => async (event, context) => {
|
|
34
|
+
try {
|
|
35
|
+
return await handler(event, context);
|
|
36
|
+
} catch (err) {
|
|
37
|
+
if (logErrors) {
|
|
38
|
+
console.error('Handler error:', err);
|
|
39
|
+
}
|
|
40
|
+
if (err instanceof errors_1.ApiError) {
|
|
41
|
+
return (0, response_1.error)(err, err.statusCode);
|
|
42
|
+
}
|
|
43
|
+
// Unknown errors become 500
|
|
44
|
+
const message = err instanceof Error ? err.message : 'Internal server error';
|
|
45
|
+
return (0, response_1.error)(message, 500);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAqCH,4CAoBC;AAtDD,8CAAwC;AACxC,0CAAyC;AAazC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAgB,gBAAgB,CAAC,UAA+B,EAAE;IAChE,MAAM,EAAE,SAAS,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAErC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC3C,IAAI,CAAC;YACH,OAAO,MAAM,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;YACvC,CAAC;YAED,IAAI,GAAG,YAAY,iBAAQ,EAAE,CAAC;gBAC5B,OAAO,IAAA,gBAAK,EAAC,GAAG,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;YACpC,CAAC;YAED,4BAA4B;YAC5B,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;YAC7E,OAAO,IAAA,gBAAK,EAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware exports for @fnd-platform/api.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
export { withErrorHandler } from './error-handler';
|
|
7
|
+
export type { ErrorHandlerOptions } from './error-handler';
|
|
8
|
+
export { withAuth } from './auth';
|
|
9
|
+
export type { AuthOptions } from './auth';
|
|
10
|
+
export { withValidation } from './validation';
|
|
11
|
+
export { withCors } from './cors';
|
|
12
|
+
export type { CorsOptions } from './cors';
|
|
13
|
+
export { withLogging } from './logging';
|
|
14
|
+
export type { LoggingOptions } from './logging';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
|