@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.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +204 -0
  3. package/lib/api-project.d.ts +99 -0
  4. package/lib/api-project.d.ts.map +1 -0
  5. package/lib/api-project.js +668 -0
  6. package/lib/api-project.js.map +1 -0
  7. package/lib/handlers/content.d.ts +52 -0
  8. package/lib/handlers/content.d.ts.map +1 -0
  9. package/lib/handlers/content.js +122 -0
  10. package/lib/handlers/content.js.map +1 -0
  11. package/lib/handlers/health.d.ts +43 -0
  12. package/lib/handlers/health.d.ts.map +1 -0
  13. package/lib/handlers/health.js +43 -0
  14. package/lib/handlers/health.js.map +1 -0
  15. package/lib/handlers/media.d.ts +86 -0
  16. package/lib/handlers/media.d.ts.map +1 -0
  17. package/lib/handlers/media.js +287 -0
  18. package/lib/handlers/media.js.map +1 -0
  19. package/lib/index.d.ts +22 -0
  20. package/lib/index.d.ts.map +1 -0
  21. package/lib/index.js +50 -0
  22. package/lib/index.js.map +1 -0
  23. package/lib/lib/errors.d.ts +114 -0
  24. package/lib/lib/errors.d.ts.map +1 -0
  25. package/lib/lib/errors.js +154 -0
  26. package/lib/lib/errors.js.map +1 -0
  27. package/lib/lib/middleware.d.ts +33 -0
  28. package/lib/lib/middleware.d.ts.map +1 -0
  29. package/lib/lib/middleware.js +36 -0
  30. package/lib/lib/middleware.js.map +1 -0
  31. package/lib/lib/request.d.ts +90 -0
  32. package/lib/lib/request.d.ts.map +1 -0
  33. package/lib/lib/request.js +115 -0
  34. package/lib/lib/request.js.map +1 -0
  35. package/lib/lib/response.d.ts +131 -0
  36. package/lib/lib/response.d.ts.map +1 -0
  37. package/lib/lib/response.js +163 -0
  38. package/lib/lib/response.js.map +1 -0
  39. package/lib/middleware/auth.d.ts +57 -0
  40. package/lib/middleware/auth.d.ts.map +1 -0
  41. package/lib/middleware/auth.js +62 -0
  42. package/lib/middleware/auth.js.map +1 -0
  43. package/lib/middleware/cors.d.ts +51 -0
  44. package/lib/middleware/cors.d.ts.map +1 -0
  45. package/lib/middleware/cors.js +62 -0
  46. package/lib/middleware/cors.js.map +1 -0
  47. package/lib/middleware/error-handler.d.ts +38 -0
  48. package/lib/middleware/error-handler.d.ts.map +1 -0
  49. package/lib/middleware/error-handler.js +49 -0
  50. package/lib/middleware/error-handler.js.map +1 -0
  51. package/lib/middleware/index.d.ts +15 -0
  52. package/lib/middleware/index.d.ts.map +1 -0
  53. package/lib/middleware/index.js +49 -0
  54. package/lib/middleware/index.js.map +1 -0
  55. package/lib/middleware/logging.d.ts +48 -0
  56. package/lib/middleware/logging.d.ts.map +1 -0
  57. package/lib/middleware/logging.js +58 -0
  58. package/lib/middleware/logging.js.map +1 -0
  59. package/lib/middleware/validation.d.ts +41 -0
  60. package/lib/middleware/validation.d.ts.map +1 -0
  61. package/lib/middleware/validation.js +76 -0
  62. package/lib/middleware/validation.js.map +1 -0
  63. package/lib/options.d.ts +48 -0
  64. package/lib/options.d.ts.map +1 -0
  65. package/lib/options.js +3 -0
  66. package/lib/options.js.map +1 -0
  67. package/lib/types/api.d.ts +108 -0
  68. package/lib/types/api.d.ts.map +1 -0
  69. package/lib/types/api.js +11 -0
  70. package/lib/types/api.js.map +1 -0
  71. package/lib/types/middleware.d.ts +59 -0
  72. package/lib/types/middleware.d.ts.map +1 -0
  73. package/lib/types/middleware.js +11 -0
  74. package/lib/types/middleware.js.map +1 -0
  75. 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"}