@fnd-platform/api 1.0.0-alpha.1 → 1.0.0-alpha.3

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/lib/lib/errors.js CHANGED
@@ -1,4 +1,4 @@
1
- 'use strict';
1
+ "use strict";
2
2
  /**
3
3
  * Custom error classes for API responses.
4
4
  *
@@ -7,14 +7,8 @@
7
7
  *
8
8
  * @packageDocumentation
9
9
  */
10
- Object.defineProperty(exports, '__esModule', { value: true });
11
- exports.ConflictError =
12
- exports.ForbiddenError =
13
- exports.UnauthorizedError =
14
- exports.ValidationError =
15
- exports.NotFoundError =
16
- exports.ApiError =
17
- void 0;
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.ConflictError = exports.ForbiddenError = exports.UnauthorizedError = exports.ValidationError = exports.NotFoundError = exports.ApiError = void 0;
18
12
  /**
19
13
  * Base API error class.
20
14
  *
@@ -29,38 +23,38 @@ exports.ConflictError =
29
23
  * ```
30
24
  */
31
25
  class ApiError extends Error {
32
- code;
33
- statusCode;
34
- details;
35
- /**
36
- * Creates a new ApiError.
37
- *
38
- * @param message - Human-readable error message
39
- * @param code - Machine-readable error code (UPPER_SNAKE_CASE)
40
- * @param statusCode - HTTP status code (default: 500)
41
- * @param details - Optional additional error details
42
- */
43
- constructor(message, code, statusCode = 500, details) {
44
- super(message);
45
- this.code = code;
46
- this.statusCode = statusCode;
47
- this.details = details;
48
- this.name = 'ApiError';
49
- // Maintains proper stack trace for where error was thrown
50
- Error.captureStackTrace(this, this.constructor);
51
- }
52
- /**
53
- * Converts the error to a JSON-serializable object.
54
- *
55
- * @returns Object with code, message, and details
56
- */
57
- toJSON() {
58
- return {
59
- code: this.code,
60
- message: this.message,
61
- details: this.details,
62
- };
63
- }
26
+ code;
27
+ statusCode;
28
+ details;
29
+ /**
30
+ * Creates a new ApiError.
31
+ *
32
+ * @param message - Human-readable error message
33
+ * @param code - Machine-readable error code (UPPER_SNAKE_CASE)
34
+ * @param statusCode - HTTP status code (default: 500)
35
+ * @param details - Optional additional error details
36
+ */
37
+ constructor(message, code, statusCode = 500, details) {
38
+ super(message);
39
+ this.code = code;
40
+ this.statusCode = statusCode;
41
+ this.details = details;
42
+ this.name = 'ApiError';
43
+ // Maintains proper stack trace for where error was thrown
44
+ Error.captureStackTrace(this, this.constructor);
45
+ }
46
+ /**
47
+ * Converts the error to a JSON-serializable object.
48
+ *
49
+ * @returns Object with code, message, and details
50
+ */
51
+ toJSON() {
52
+ return {
53
+ code: this.code,
54
+ message: this.message,
55
+ details: this.details,
56
+ };
57
+ }
64
58
  }
65
59
  exports.ApiError = ApiError;
66
60
  /**
@@ -74,10 +68,10 @@ exports.ApiError = ApiError;
74
68
  * ```
75
69
  */
76
70
  class NotFoundError extends ApiError {
77
- constructor(message = 'Resource not found') {
78
- super(message, 'NOT_FOUND', 404);
79
- this.name = 'NotFoundError';
80
- }
71
+ constructor(message = 'Resource not found') {
72
+ super(message, 'NOT_FOUND', 404);
73
+ this.name = 'NotFoundError';
74
+ }
81
75
  }
82
76
  exports.NotFoundError = NotFoundError;
83
77
  /**
@@ -92,10 +86,10 @@ exports.NotFoundError = NotFoundError;
92
86
  * ```
93
87
  */
94
88
  class ValidationError extends ApiError {
95
- constructor(message = 'Validation failed', details) {
96
- super(message, 'VALIDATION_ERROR', 400, details);
97
- this.name = 'ValidationError';
98
- }
89
+ constructor(message = 'Validation failed', details) {
90
+ super(message, 'VALIDATION_ERROR', 400, details);
91
+ this.name = 'ValidationError';
92
+ }
99
93
  }
100
94
  exports.ValidationError = ValidationError;
101
95
  /**
@@ -109,10 +103,10 @@ exports.ValidationError = ValidationError;
109
103
  * ```
110
104
  */
111
105
  class UnauthorizedError extends ApiError {
112
- constructor(message = 'Unauthorized') {
113
- super(message, 'UNAUTHORIZED', 401);
114
- this.name = 'UnauthorizedError';
115
- }
106
+ constructor(message = 'Unauthorized') {
107
+ super(message, 'UNAUTHORIZED', 401);
108
+ this.name = 'UnauthorizedError';
109
+ }
116
110
  }
117
111
  exports.UnauthorizedError = UnauthorizedError;
118
112
  /**
@@ -127,10 +121,10 @@ exports.UnauthorizedError = UnauthorizedError;
127
121
  * ```
128
122
  */
129
123
  class ForbiddenError extends ApiError {
130
- constructor(message = 'Forbidden') {
131
- super(message, 'FORBIDDEN', 403);
132
- this.name = 'ForbiddenError';
133
- }
124
+ constructor(message = 'Forbidden') {
125
+ super(message, 'FORBIDDEN', 403);
126
+ this.name = 'ForbiddenError';
127
+ }
134
128
  }
135
129
  exports.ForbiddenError = ForbiddenError;
136
130
  /**
@@ -145,10 +139,10 @@ exports.ForbiddenError = ForbiddenError;
145
139
  * ```
146
140
  */
147
141
  class ConflictError extends ApiError {
148
- constructor(message = 'Resource conflict') {
149
- super(message, 'CONFLICT', 409);
150
- this.name = 'ConflictError';
151
- }
142
+ constructor(message = 'Resource conflict') {
143
+ super(message, 'CONFLICT', 409);
144
+ this.name = 'ConflictError';
145
+ }
152
146
  }
153
147
  exports.ConflictError = ConflictError;
154
- //# sourceMappingURL=errors.js.map
148
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1,122 @@
1
+ /**
2
+ * DynamoDB key builders for single-table design.
3
+ *
4
+ * These helpers generate consistent key structures for content entities
5
+ * following the fnd-platform single-table design patterns.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ /**
10
+ * Key structure for DynamoDB primary key.
11
+ */
12
+ export interface PrimaryKey {
13
+ PK: string;
14
+ SK: string;
15
+ }
16
+ /**
17
+ * Key structure for GSI1 (slug lookup).
18
+ */
19
+ export interface GSI1Key {
20
+ GSI1PK: string;
21
+ GSI1SK: string;
22
+ }
23
+ /**
24
+ * Key structure for GSI2 (type/status listing).
25
+ */
26
+ export interface GSI2Key {
27
+ GSI2PK: string;
28
+ GSI2SK: string;
29
+ }
30
+ /**
31
+ * Content key builders for DynamoDB operations.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * // Get primary key for content item
36
+ * const pk = contentKeys.pk('content-123');
37
+ * const sk = contentKeys.sk();
38
+ *
39
+ * // Build GSI1 keys for slug lookup
40
+ * const gsi1Keys = contentKeys.gsi1.bySlug('my-blog-post');
41
+ *
42
+ * // Build GSI2 keys for listing by type
43
+ * const gsi2Keys = contentKeys.gsi2.byType('blog-post', '2024-01-15T12:00:00Z');
44
+ * ```
45
+ */
46
+ export declare const contentKeys: {
47
+ /**
48
+ * Generate partition key for content item.
49
+ * @param id - Content ID
50
+ * @returns Formatted partition key
51
+ */
52
+ pk: (id: string) => string;
53
+ /**
54
+ * Generate sort key for content item.
55
+ * @returns Constant sort key for content
56
+ */
57
+ sk: () => string;
58
+ /**
59
+ * Generate full primary key for content item.
60
+ * @param id - Content ID
61
+ * @returns Primary key object
62
+ */
63
+ keys: (id: string) => PrimaryKey;
64
+ /**
65
+ * GSI1 key builders for slug-based lookups.
66
+ */
67
+ gsi1: {
68
+ /**
69
+ * Generate GSI1 keys for looking up content by slug.
70
+ * @param slug - Content slug
71
+ * @returns GSI1 key object
72
+ */
73
+ bySlug: (slug: string) => GSI1Key;
74
+ };
75
+ /**
76
+ * GSI2 key builders for listing content by type.
77
+ */
78
+ gsi2: {
79
+ /**
80
+ * Generate GSI2 keys for listing content by type with timestamp sorting.
81
+ * @param contentType - Content type (e.g., 'blog-post', 'page')
82
+ * @param timestamp - ISO 8601 timestamp for sort ordering
83
+ * @returns GSI2 key object
84
+ */
85
+ byType: (contentType: string, timestamp: string) => GSI2Key;
86
+ };
87
+ };
88
+ /**
89
+ * User key builders for DynamoDB operations.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * // Get primary key for user profile
94
+ * const pk = userKeys.pk('user-123');
95
+ * const sk = userKeys.sk.profile();
96
+ * ```
97
+ */
98
+ export declare const userKeys: {
99
+ /**
100
+ * Generate partition key for user.
101
+ * @param id - User ID (Cognito sub)
102
+ * @returns Formatted partition key
103
+ */
104
+ pk: (id: string) => string;
105
+ /**
106
+ * Sort key generators for user-related items.
107
+ */
108
+ sk: {
109
+ /**
110
+ * Generate sort key for user profile.
111
+ * @returns Profile sort key
112
+ */
113
+ profile: () => string;
114
+ };
115
+ /**
116
+ * Generate full primary key for user profile.
117
+ * @param id - User ID
118
+ * @returns Primary key object
119
+ */
120
+ keys: (id: string) => PrimaryKey;
121
+ };
122
+ //# sourceMappingURL=keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/lib/keys.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,WAAW;IACtB;;;;OAIG;aACM,MAAM,KAAG,MAAM;IAExB;;;OAGG;cACK,MAAM;IAEd;;;;OAIG;eACQ,MAAM,KAAG,UAAU;IAK9B;;OAEG;;QAED;;;;WAIG;uBACY,MAAM,KAAG,OAAO;;IAMjC;;OAEG;;QAED;;;;;WAKG;8BACmB,MAAM,aAAa,MAAM,KAAG,OAAO;;CAK5D,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ;IACnB;;;;OAIG;aACM,MAAM,KAAG,MAAM;IAExB;;OAEG;;QAED;;;WAGG;uBACU,MAAM;;IAGrB;;;;OAIG;eACQ,MAAM,KAAG,UAAU;CAI/B,CAAC"}
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ /**
3
+ * DynamoDB key builders for single-table design.
4
+ *
5
+ * These helpers generate consistent key structures for content entities
6
+ * following the fnd-platform single-table design patterns.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.userKeys = exports.contentKeys = void 0;
12
+ /**
13
+ * Content key builders for DynamoDB operations.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // Get primary key for content item
18
+ * const pk = contentKeys.pk('content-123');
19
+ * const sk = contentKeys.sk();
20
+ *
21
+ * // Build GSI1 keys for slug lookup
22
+ * const gsi1Keys = contentKeys.gsi1.bySlug('my-blog-post');
23
+ *
24
+ * // Build GSI2 keys for listing by type
25
+ * const gsi2Keys = contentKeys.gsi2.byType('blog-post', '2024-01-15T12:00:00Z');
26
+ * ```
27
+ */
28
+ exports.contentKeys = {
29
+ /**
30
+ * Generate partition key for content item.
31
+ * @param id - Content ID
32
+ * @returns Formatted partition key
33
+ */
34
+ pk: (id) => `CONTENT#${id}`,
35
+ /**
36
+ * Generate sort key for content item.
37
+ * @returns Constant sort key for content
38
+ */
39
+ sk: () => 'CONTENT',
40
+ /**
41
+ * Generate full primary key for content item.
42
+ * @param id - Content ID
43
+ * @returns Primary key object
44
+ */
45
+ keys: (id) => ({
46
+ PK: exports.contentKeys.pk(id),
47
+ SK: exports.contentKeys.sk(),
48
+ }),
49
+ /**
50
+ * GSI1 key builders for slug-based lookups.
51
+ */
52
+ gsi1: {
53
+ /**
54
+ * Generate GSI1 keys for looking up content by slug.
55
+ * @param slug - Content slug
56
+ * @returns GSI1 key object
57
+ */
58
+ bySlug: (slug) => ({
59
+ GSI1PK: `CONTENT#SLUG#${slug}`,
60
+ GSI1SK: 'CONTENT',
61
+ }),
62
+ },
63
+ /**
64
+ * GSI2 key builders for listing content by type.
65
+ */
66
+ gsi2: {
67
+ /**
68
+ * Generate GSI2 keys for listing content by type with timestamp sorting.
69
+ * @param contentType - Content type (e.g., 'blog-post', 'page')
70
+ * @param timestamp - ISO 8601 timestamp for sort ordering
71
+ * @returns GSI2 key object
72
+ */
73
+ byType: (contentType, timestamp) => ({
74
+ GSI2PK: contentType,
75
+ GSI2SK: timestamp,
76
+ }),
77
+ },
78
+ };
79
+ /**
80
+ * User key builders for DynamoDB operations.
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * // Get primary key for user profile
85
+ * const pk = userKeys.pk('user-123');
86
+ * const sk = userKeys.sk.profile();
87
+ * ```
88
+ */
89
+ exports.userKeys = {
90
+ /**
91
+ * Generate partition key for user.
92
+ * @param id - User ID (Cognito sub)
93
+ * @returns Formatted partition key
94
+ */
95
+ pk: (id) => `USER#${id}`,
96
+ /**
97
+ * Sort key generators for user-related items.
98
+ */
99
+ sk: {
100
+ /**
101
+ * Generate sort key for user profile.
102
+ * @returns Profile sort key
103
+ */
104
+ profile: () => 'PROFILE',
105
+ },
106
+ /**
107
+ * Generate full primary key for user profile.
108
+ * @param id - User ID
109
+ * @returns Primary key object
110
+ */
111
+ keys: (id) => ({
112
+ PK: exports.userKeys.pk(id),
113
+ SK: exports.userKeys.sk.profile(),
114
+ }),
115
+ };
116
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/lib/keys.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AA0BH;;;;;;;;;;;;;;;GAeG;AACU,QAAA,WAAW,GAAG;IACzB;;;;OAIG;IACH,EAAE,EAAE,CAAC,EAAU,EAAU,EAAE,CAAC,WAAW,EAAE,EAAE;IAE3C;;;OAGG;IACH,EAAE,EAAE,GAAW,EAAE,CAAC,SAAS;IAE3B;;;;OAIG;IACH,IAAI,EAAE,CAAC,EAAU,EAAc,EAAE,CAAC,CAAC;QACjC,EAAE,EAAE,mBAAW,CAAC,EAAE,CAAC,EAAE,CAAC;QACtB,EAAE,EAAE,mBAAW,CAAC,EAAE,EAAE;KACrB,CAAC;IAEF;;OAEG;IACH,IAAI,EAAE;QACJ;;;;WAIG;QACH,MAAM,EAAE,CAAC,IAAY,EAAW,EAAE,CAAC,CAAC;YAClC,MAAM,EAAE,gBAAgB,IAAI,EAAE;YAC9B,MAAM,EAAE,SAAS;SAClB,CAAC;KACH;IAED;;OAEG;IACH,IAAI,EAAE;QACJ;;;;;WAKG;QACH,MAAM,EAAE,CAAC,WAAmB,EAAE,SAAiB,EAAW,EAAE,CAAC,CAAC;YAC5D,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,SAAS;SAClB,CAAC;KACH;CACF,CAAC;AAEF;;;;;;;;;GASG;AACU,QAAA,QAAQ,GAAG;IACtB;;;;OAIG;IACH,EAAE,EAAE,CAAC,EAAU,EAAU,EAAE,CAAC,QAAQ,EAAE,EAAE;IAExC;;OAEG;IACH,EAAE,EAAE;QACF;;;WAGG;QACH,OAAO,EAAE,GAAW,EAAE,CAAC,SAAS;KACjC;IAED;;;;OAIG;IACH,IAAI,EAAE,CAAC,EAAU,EAAc,EAAE,CAAC,CAAC;QACjC,EAAE,EAAE,gBAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACnB,EAAE,EAAE,gBAAQ,CAAC,EAAE,CAAC,OAAO,EAAE;KAC1B,CAAC;CACH,CAAC"}
@@ -1,12 +1,12 @@
1
- 'use strict';
1
+ "use strict";
2
2
  /**
3
3
  * Authentication middleware for Lambda handlers.
4
4
  *
5
5
  * @packageDocumentation
6
6
  */
7
- Object.defineProperty(exports, '__esModule', { value: true });
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
8
  exports.withAuth = withAuth;
9
- const response_1 = require('../lib/response');
9
+ const response_1 = require("../lib/response");
10
10
  /**
11
11
  * Middleware that validates JWT tokens from Cognito.
12
12
  *
@@ -37,26 +37,26 @@ const response_1 = require('../lib/response');
37
37
  * ```
38
38
  */
39
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
- };
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
61
  }
62
- //# sourceMappingURL=auth.js.map
62
+ //# sourceMappingURL=auth.js.map
@@ -1,10 +1,10 @@
1
- 'use strict';
1
+ "use strict";
2
2
  /**
3
3
  * CORS middleware for Lambda handlers.
4
4
  *
5
5
  * @packageDocumentation
6
6
  */
7
- Object.defineProperty(exports, '__esModule', { value: true });
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
8
  exports.withCors = withCors;
9
9
  /**
10
10
  * Middleware that adds CORS headers to responses.
@@ -25,38 +25,33 @@ exports.withCors = withCors;
25
25
  * ```
26
26
  */
27
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
- };
28
+ const { origin = '*', methods = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], headers = ['Content-Type', 'Authorization'], credentials = false, } = options;
29
+ const corsHeaders = {
30
+ 'Access-Control-Allow-Origin': Array.isArray(origin) ? origin[0] : origin,
31
+ 'Access-Control-Allow-Methods': methods.join(','),
32
+ 'Access-Control-Allow-Headers': headers.join(','),
33
+ };
34
+ if (credentials) {
35
+ corsHeaders['Access-Control-Allow-Credentials'] = 'true';
50
36
  }
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
- },
37
+ return (handler) => async (event, context) => {
38
+ // Handle preflight requests
39
+ if (event.httpMethod === 'OPTIONS') {
40
+ return {
41
+ statusCode: 204,
42
+ headers: corsHeaders,
43
+ body: '',
44
+ };
45
+ }
46
+ const response = await handler(event, context);
47
+ // Merge CORS headers with response headers
48
+ return {
49
+ ...response,
50
+ headers: {
51
+ ...response.headers,
52
+ ...corsHeaders,
53
+ },
54
+ };
59
55
  };
60
- };
61
56
  }
62
- //# sourceMappingURL=cors.js.map
57
+ //# sourceMappingURL=cors.js.map
@@ -1,13 +1,13 @@
1
- 'use strict';
1
+ "use strict";
2
2
  /**
3
3
  * Error handling middleware for Lambda handlers.
4
4
  *
5
5
  * @packageDocumentation
6
6
  */
7
- Object.defineProperty(exports, '__esModule', { value: true });
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
8
  exports.withErrorHandler = withErrorHandler;
9
- const response_1 = require('../lib/response');
10
- const errors_1 = require('../lib/errors');
9
+ const response_1 = require("../lib/response");
10
+ const errors_1 = require("../lib/errors");
11
11
  /**
12
12
  * Middleware that catches errors and returns appropriate error responses.
13
13
  *
@@ -29,21 +29,22 @@ const errors_1 = require('../lib/errors');
29
29
  * ```
30
30
  */
31
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
- };
32
+ const { logErrors = true } = options;
33
+ return (handler) => async (event, context) => {
34
+ try {
35
+ return await handler(event, context);
36
+ }
37
+ catch (err) {
38
+ if (logErrors) {
39
+ console.error('Handler error:', err);
40
+ }
41
+ if (err instanceof errors_1.ApiError) {
42
+ return (0, response_1.error)(err, err.statusCode);
43
+ }
44
+ // Unknown errors become 500
45
+ const message = err instanceof Error ? err.message : 'Internal server error';
46
+ return (0, response_1.error)(message, 500);
47
+ }
48
+ };
48
49
  }
49
- //# sourceMappingURL=error-handler.js.map
50
+ //# sourceMappingURL=error-handler.js.map