@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
package/lib/index.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @fnd-platform/api
3
+ *
4
+ * Projen project class and runtime utilities for building Lambda APIs.
5
+ *
6
+ * Use FndApiProject to add a serverless API to your monorepo with Lambda
7
+ * handlers, middleware patterns, and type-safe response utilities.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ export { FndApiProject } from './api-project';
12
+ export type { FndApiProjectOptions } from './options';
13
+ export { success, error, notFound, unauthorized, forbidden, badRequest, created, } from './lib/response';
14
+ export type { SuccessResponse, ErrorResponse } from './lib/response';
15
+ export { ApiError, NotFoundError, ValidationError, UnauthorizedError, ForbiddenError, ConflictError, } from './lib/errors';
16
+ export { parseBody, requirePathParam, getQueryParam, getUserId } from './lib/request';
17
+ export type { Handler, AuthenticatedEvent, AuthenticatedHandler, CognitoClaims, PaginatedRequest, PaginatedResponse, } from './types/api';
18
+ export { compose } from './lib/middleware';
19
+ export { withErrorHandler, withAuth, withValidation, withCors, withLogging } from './middleware';
20
+ export type { ErrorHandlerOptions, AuthOptions, CorsOptions, LoggingOptions } from './middleware';
21
+ export type { MiddlewareHandler, Middleware, ValidatedEvent } from './types/middleware';
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,YAAY,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAGtD,OAAO,EACL,OAAO,EACP,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,UAAU,EACV,OAAO,GACR,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGrE,OAAO,EACL,QAAQ,EACR,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAGtF,YAAY,EACV,OAAO,EACP,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAG3C,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGjG,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGlG,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ /**
3
+ * @fnd-platform/api
4
+ *
5
+ * Projen project class and runtime utilities for building Lambda APIs.
6
+ *
7
+ * Use FndApiProject to add a serverless API to your monorepo with Lambda
8
+ * handlers, middleware patterns, and type-safe response utilities.
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.withLogging = exports.withCors = exports.withValidation = exports.withAuth = exports.withErrorHandler = exports.compose = exports.getUserId = exports.getQueryParam = exports.requirePathParam = exports.parseBody = exports.ConflictError = exports.ForbiddenError = exports.UnauthorizedError = exports.ValidationError = exports.NotFoundError = exports.ApiError = exports.created = exports.badRequest = exports.forbidden = exports.unauthorized = exports.notFound = exports.error = exports.success = exports.FndApiProject = void 0;
14
+ // Main project class
15
+ var api_project_1 = require("./api-project");
16
+ Object.defineProperty(exports, "FndApiProject", { enumerable: true, get: function () { return api_project_1.FndApiProject; } });
17
+ // Response helpers
18
+ var response_1 = require("./lib/response");
19
+ Object.defineProperty(exports, "success", { enumerable: true, get: function () { return response_1.success; } });
20
+ Object.defineProperty(exports, "error", { enumerable: true, get: function () { return response_1.error; } });
21
+ Object.defineProperty(exports, "notFound", { enumerable: true, get: function () { return response_1.notFound; } });
22
+ Object.defineProperty(exports, "unauthorized", { enumerable: true, get: function () { return response_1.unauthorized; } });
23
+ Object.defineProperty(exports, "forbidden", { enumerable: true, get: function () { return response_1.forbidden; } });
24
+ Object.defineProperty(exports, "badRequest", { enumerable: true, get: function () { return response_1.badRequest; } });
25
+ Object.defineProperty(exports, "created", { enumerable: true, get: function () { return response_1.created; } });
26
+ // Error classes
27
+ var errors_1 = require("./lib/errors");
28
+ Object.defineProperty(exports, "ApiError", { enumerable: true, get: function () { return errors_1.ApiError; } });
29
+ Object.defineProperty(exports, "NotFoundError", { enumerable: true, get: function () { return errors_1.NotFoundError; } });
30
+ Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return errors_1.ValidationError; } });
31
+ Object.defineProperty(exports, "UnauthorizedError", { enumerable: true, get: function () { return errors_1.UnauthorizedError; } });
32
+ Object.defineProperty(exports, "ForbiddenError", { enumerable: true, get: function () { return errors_1.ForbiddenError; } });
33
+ Object.defineProperty(exports, "ConflictError", { enumerable: true, get: function () { return errors_1.ConflictError; } });
34
+ // Request utilities
35
+ var request_1 = require("./lib/request");
36
+ Object.defineProperty(exports, "parseBody", { enumerable: true, get: function () { return request_1.parseBody; } });
37
+ Object.defineProperty(exports, "requirePathParam", { enumerable: true, get: function () { return request_1.requirePathParam; } });
38
+ Object.defineProperty(exports, "getQueryParam", { enumerable: true, get: function () { return request_1.getQueryParam; } });
39
+ Object.defineProperty(exports, "getUserId", { enumerable: true, get: function () { return request_1.getUserId; } });
40
+ // Middleware composition
41
+ var middleware_1 = require("./lib/middleware");
42
+ Object.defineProperty(exports, "compose", { enumerable: true, get: function () { return middleware_1.compose; } });
43
+ // Middleware functions
44
+ var middleware_2 = require("./middleware");
45
+ Object.defineProperty(exports, "withErrorHandler", { enumerable: true, get: function () { return middleware_2.withErrorHandler; } });
46
+ Object.defineProperty(exports, "withAuth", { enumerable: true, get: function () { return middleware_2.withAuth; } });
47
+ Object.defineProperty(exports, "withValidation", { enumerable: true, get: function () { return middleware_2.withValidation; } });
48
+ Object.defineProperty(exports, "withCors", { enumerable: true, get: function () { return middleware_2.withCors; } });
49
+ Object.defineProperty(exports, "withLogging", { enumerable: true, get: function () { return middleware_2.withLogging; } });
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAEH,qBAAqB;AACrB,6CAA8C;AAArC,4GAAA,aAAa,OAAA;AAKtB,mBAAmB;AACnB,2CAQwB;AAPtB,mGAAA,OAAO,OAAA;AACP,iGAAA,KAAK,OAAA;AACL,oGAAA,QAAQ,OAAA;AACR,wGAAA,YAAY,OAAA;AACZ,qGAAA,SAAS,OAAA;AACT,sGAAA,UAAU,OAAA;AACV,mGAAA,OAAO,OAAA;AAIT,gBAAgB;AAChB,uCAOsB;AANpB,kGAAA,QAAQ,OAAA;AACR,uGAAA,aAAa,OAAA;AACb,yGAAA,eAAe,OAAA;AACf,2GAAA,iBAAiB,OAAA;AACjB,wGAAA,cAAc,OAAA;AACd,uGAAA,aAAa,OAAA;AAGf,oBAAoB;AACpB,yCAAsF;AAA7E,oGAAA,SAAS,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,wGAAA,aAAa,OAAA;AAAE,oGAAA,SAAS,OAAA;AAY9D,yBAAyB;AACzB,+CAA2C;AAAlC,qGAAA,OAAO,OAAA;AAEhB,uBAAuB;AACvB,2CAAiG;AAAxF,8GAAA,gBAAgB,OAAA;AAAE,sGAAA,QAAQ,OAAA;AAAE,4GAAA,cAAc,OAAA;AAAE,sGAAA,QAAQ,OAAA;AAAE,yGAAA,WAAW,OAAA"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Custom error classes for API responses.
3
+ *
4
+ * All API errors extend ApiError and include an error code,
5
+ * HTTP status code, and optional details for structured error handling.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ /**
10
+ * Base API error class.
11
+ *
12
+ * All API errors should extend this class to ensure consistent
13
+ * error handling and serialization across the application.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const err = new ApiError('Something went wrong', 'INTERNAL_ERROR', 500);
18
+ * console.log(err.toJSON());
19
+ * // { code: 'INTERNAL_ERROR', message: 'Something went wrong', details: undefined }
20
+ * ```
21
+ */
22
+ export declare class ApiError extends Error {
23
+ readonly code: string;
24
+ readonly statusCode: number;
25
+ readonly details?: unknown | undefined;
26
+ /**
27
+ * Creates a new ApiError.
28
+ *
29
+ * @param message - Human-readable error message
30
+ * @param code - Machine-readable error code (UPPER_SNAKE_CASE)
31
+ * @param statusCode - HTTP status code (default: 500)
32
+ * @param details - Optional additional error details
33
+ */
34
+ constructor(message: string, code: string, statusCode?: number, details?: unknown | undefined);
35
+ /**
36
+ * Converts the error to a JSON-serializable object.
37
+ *
38
+ * @returns Object with code, message, and details
39
+ */
40
+ toJSON(): {
41
+ code: string;
42
+ message: string;
43
+ details?: unknown;
44
+ };
45
+ }
46
+ /**
47
+ * 404 Not Found error.
48
+ *
49
+ * Use when a requested resource does not exist.
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * throw new NotFoundError('User not found');
54
+ * ```
55
+ */
56
+ export declare class NotFoundError extends ApiError {
57
+ constructor(message?: string);
58
+ }
59
+ /**
60
+ * 400 Validation error.
61
+ *
62
+ * Use when request validation fails, such as missing required fields
63
+ * or invalid data formats.
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * throw new ValidationError('Invalid email format', { field: 'email' });
68
+ * ```
69
+ */
70
+ export declare class ValidationError extends ApiError {
71
+ constructor(message?: string, details?: unknown);
72
+ }
73
+ /**
74
+ * 401 Unauthorized error.
75
+ *
76
+ * Use when authentication is required but missing or invalid.
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * throw new UnauthorizedError('Invalid token');
81
+ * ```
82
+ */
83
+ export declare class UnauthorizedError extends ApiError {
84
+ constructor(message?: string);
85
+ }
86
+ /**
87
+ * 403 Forbidden error.
88
+ *
89
+ * Use when the user is authenticated but lacks permission
90
+ * to access the resource.
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * throw new ForbiddenError('Admin access required');
95
+ * ```
96
+ */
97
+ export declare class ForbiddenError extends ApiError {
98
+ constructor(message?: string);
99
+ }
100
+ /**
101
+ * 409 Conflict error.
102
+ *
103
+ * Use when the request conflicts with the current state of the resource,
104
+ * such as duplicate entries or version conflicts.
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * throw new ConflictError('Email already exists');
109
+ * ```
110
+ */
111
+ export declare class ConflictError extends ApiError {
112
+ constructor(message?: string);
113
+ }
114
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;;GAYG;AACH,qBAAa,QAAS,SAAQ,KAAK;aAWf,IAAI,EAAE,MAAM;aACZ,UAAU,EAAE,MAAM;aAClB,OAAO,CAAC,EAAE,OAAO;IAZnC;;;;;;;OAOG;gBAED,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,MAAY,EACxB,OAAO,CAAC,EAAE,OAAO,YAAA;IASnC;;;;OAIG;IACH,MAAM,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE;CAO/D;AAED;;;;;;;;;GASG;AACH,qBAAa,aAAc,SAAQ,QAAQ;gBAC7B,OAAO,SAAuB;CAI3C;AAED;;;;;;;;;;GAUG;AACH,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,OAAO,SAAsB,EAAE,OAAO,CAAC,EAAE,OAAO;CAI7D;AAED;;;;;;;;;GASG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;gBACjC,OAAO,SAAiB;CAIrC;AAED;;;;;;;;;;GAUG;AACH,qBAAa,cAAe,SAAQ,QAAQ;gBAC9B,OAAO,SAAc;CAIlC;AAED;;;;;;;;;;GAUG;AACH,qBAAa,aAAc,SAAQ,QAAQ;gBAC7B,OAAO,SAAsB;CAI1C"}
@@ -0,0 +1,154 @@
1
+ 'use strict';
2
+ /**
3
+ * Custom error classes for API responses.
4
+ *
5
+ * All API errors extend ApiError and include an error code,
6
+ * HTTP status code, and optional details for structured error handling.
7
+ *
8
+ * @packageDocumentation
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;
18
+ /**
19
+ * Base API error class.
20
+ *
21
+ * All API errors should extend this class to ensure consistent
22
+ * error handling and serialization across the application.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const err = new ApiError('Something went wrong', 'INTERNAL_ERROR', 500);
27
+ * console.log(err.toJSON());
28
+ * // { code: 'INTERNAL_ERROR', message: 'Something went wrong', details: undefined }
29
+ * ```
30
+ */
31
+ 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
+ }
64
+ }
65
+ exports.ApiError = ApiError;
66
+ /**
67
+ * 404 Not Found error.
68
+ *
69
+ * Use when a requested resource does not exist.
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * throw new NotFoundError('User not found');
74
+ * ```
75
+ */
76
+ class NotFoundError extends ApiError {
77
+ constructor(message = 'Resource not found') {
78
+ super(message, 'NOT_FOUND', 404);
79
+ this.name = 'NotFoundError';
80
+ }
81
+ }
82
+ exports.NotFoundError = NotFoundError;
83
+ /**
84
+ * 400 Validation error.
85
+ *
86
+ * Use when request validation fails, such as missing required fields
87
+ * or invalid data formats.
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * throw new ValidationError('Invalid email format', { field: 'email' });
92
+ * ```
93
+ */
94
+ class ValidationError extends ApiError {
95
+ constructor(message = 'Validation failed', details) {
96
+ super(message, 'VALIDATION_ERROR', 400, details);
97
+ this.name = 'ValidationError';
98
+ }
99
+ }
100
+ exports.ValidationError = ValidationError;
101
+ /**
102
+ * 401 Unauthorized error.
103
+ *
104
+ * Use when authentication is required but missing or invalid.
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * throw new UnauthorizedError('Invalid token');
109
+ * ```
110
+ */
111
+ class UnauthorizedError extends ApiError {
112
+ constructor(message = 'Unauthorized') {
113
+ super(message, 'UNAUTHORIZED', 401);
114
+ this.name = 'UnauthorizedError';
115
+ }
116
+ }
117
+ exports.UnauthorizedError = UnauthorizedError;
118
+ /**
119
+ * 403 Forbidden error.
120
+ *
121
+ * Use when the user is authenticated but lacks permission
122
+ * to access the resource.
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * throw new ForbiddenError('Admin access required');
127
+ * ```
128
+ */
129
+ class ForbiddenError extends ApiError {
130
+ constructor(message = 'Forbidden') {
131
+ super(message, 'FORBIDDEN', 403);
132
+ this.name = 'ForbiddenError';
133
+ }
134
+ }
135
+ exports.ForbiddenError = ForbiddenError;
136
+ /**
137
+ * 409 Conflict error.
138
+ *
139
+ * Use when the request conflicts with the current state of the resource,
140
+ * such as duplicate entries or version conflicts.
141
+ *
142
+ * @example
143
+ * ```typescript
144
+ * throw new ConflictError('Email already exists');
145
+ * ```
146
+ */
147
+ class ConflictError extends ApiError {
148
+ constructor(message = 'Resource conflict') {
149
+ super(message, 'CONFLICT', 409);
150
+ this.name = 'ConflictError';
151
+ }
152
+ }
153
+ exports.ConflictError = ConflictError;
154
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH;;;;;;;;;;;;GAYG;AACH,MAAa,QAAS,SAAQ,KAAK;IAWf;IACA;IACA;IAZlB;;;;;;;OAOG;IACH,YACE,OAAe,EACC,IAAY,EACZ,aAAqB,GAAG,EACxB,OAAiB;QAEjC,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAQ;QACZ,eAAU,GAAV,UAAU,CAAc;QACxB,YAAO,GAAP,OAAO,CAAU;QAGjC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QAEvB,0DAA0D;QAC1D,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC;CACF;AAlCD,4BAkCC;AAED;;;;;;;;;GASG;AACH,MAAa,aAAc,SAAQ,QAAQ;IACzC,YAAY,OAAO,GAAG,oBAAoB;QACxC,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AALD,sCAKC;AAED;;;;;;;;;;GAUG;AACH,MAAa,eAAgB,SAAQ,QAAQ;IAC3C,YAAY,OAAO,GAAG,mBAAmB,EAAE,OAAiB;QAC1D,KAAK,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AALD,0CAKC;AAED;;;;;;;;;GASG;AACH,MAAa,iBAAkB,SAAQ,QAAQ;IAC7C,YAAY,OAAO,GAAG,cAAc;QAClC,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AALD,8CAKC;AAED;;;;;;;;;;GAUG;AACH,MAAa,cAAe,SAAQ,QAAQ;IAC1C,YAAY,OAAO,GAAG,WAAW;QAC/B,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AALD,wCAKC;AAED;;;;;;;;;;GAUG;AACH,MAAa,aAAc,SAAQ,QAAQ;IACzC,YAAY,OAAO,GAAG,mBAAmB;QACvC,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AALD,sCAKC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Middleware composition for Lambda handlers.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ import type { APIGatewayProxyEvent } from 'aws-lambda';
7
+ import type { MiddlewareHandler, Middleware } from '../types/middleware';
8
+ /**
9
+ * Compose multiple middleware into a single middleware.
10
+ *
11
+ * Middleware is applied from right to left (innermost first),
12
+ * meaning the first middleware in the list will be the outermost
13
+ * wrapper and will execute first.
14
+ *
15
+ * @param middlewares - Array of middleware functions to compose
16
+ * @returns A function that takes a handler and returns a wrapped handler
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * // Error handler runs first (outermost), then auth, then validation
21
+ * const handler = compose(
22
+ * withErrorHandler(),
23
+ * withAuth(),
24
+ * withValidation(schema)
25
+ * )(async (event) => {
26
+ * return success(event.validatedBody);
27
+ * });
28
+ * ```
29
+ */
30
+ export declare function compose<TEvent = APIGatewayProxyEvent>(
31
+ ...middlewares: Middleware<any, any>[]
32
+ ): (handler: MiddlewareHandler<any>) => MiddlewareHandler<TEvent>;
33
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/lib/middleware.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,OAAO,CAAC,MAAM,GAAG,oBAAoB,EACnD,GAAG,WAAW,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GACrC,CAAC,OAAO,EAAE,iBAAiB,CAAC,GAAG,CAAC,KAAK,iBAAiB,CAAC,MAAM,CAAC,CAIhE"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ /**
3
+ * Middleware composition for Lambda handlers.
4
+ *
5
+ * @packageDocumentation
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.compose = compose;
9
+ /**
10
+ * Compose multiple middleware into a single middleware.
11
+ *
12
+ * Middleware is applied from right to left (innermost first),
13
+ * meaning the first middleware in the list will be the outermost
14
+ * wrapper and will execute first.
15
+ *
16
+ * @param middlewares - Array of middleware functions to compose
17
+ * @returns A function that takes a handler and returns a wrapped handler
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * // Error handler runs first (outermost), then auth, then validation
22
+ * const handler = compose(
23
+ * withErrorHandler(),
24
+ * withAuth(),
25
+ * withValidation(schema)
26
+ * )(async (event) => {
27
+ * return success(event.validatedBody);
28
+ * });
29
+ * ```
30
+ */
31
+ function compose(...middlewares) {
32
+ return (handler) => {
33
+ return middlewares.reduceRight((acc, middleware) => middleware(acc), handler);
34
+ };
35
+ }
36
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/lib/middleware.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AA2BH,0BAMC;AA5BD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,OAAO,CACrB,GAAG,WAAmC;IAEtC,OAAO,CAAC,OAAO,EAAE,EAAE;QACjB,OAAO,WAAW,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IAChF,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Request parsing utilities for Lambda handlers.
3
+ *
4
+ * Provides type-safe extraction of request data including
5
+ * JSON body parsing, path parameters, and query parameters.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import type { APIGatewayProxyEvent } from 'aws-lambda';
10
+ import type { AuthenticatedEvent } from '../types/api';
11
+ /**
12
+ * Parse JSON body from API Gateway event.
13
+ *
14
+ * @param event - API Gateway proxy event
15
+ * @returns Parsed JSON body as type T
16
+ * @throws {ValidationError} If body is missing or invalid JSON
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * interface CreateUserBody {
21
+ * name: string;
22
+ * email: string;
23
+ * }
24
+ *
25
+ * const handler: Handler = async (event) => {
26
+ * const body = parseBody<CreateUserBody>(event);
27
+ * // body is typed as CreateUserBody
28
+ * };
29
+ * ```
30
+ */
31
+ export declare function parseBody<T>(event: APIGatewayProxyEvent): T;
32
+ /**
33
+ * Get a required path parameter from the event.
34
+ *
35
+ * @param event - API Gateway proxy event
36
+ * @param name - Name of the path parameter
37
+ * @returns The path parameter value
38
+ * @throws {ValidationError} If the parameter is missing
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * // Route: GET /users/{id}
43
+ * const handler: Handler = async (event) => {
44
+ * const userId = requirePathParam(event, 'id');
45
+ * // userId is guaranteed to be a string
46
+ * };
47
+ * ```
48
+ */
49
+ export declare function requirePathParam(event: APIGatewayProxyEvent, name: string): string;
50
+ /**
51
+ * Get an optional query parameter from the event.
52
+ *
53
+ * @param event - API Gateway proxy event
54
+ * @param name - Name of the query parameter
55
+ * @param defaultValue - Optional default value if parameter is missing
56
+ * @returns The query parameter value or default
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * // GET /users?limit=10&status=active
61
+ * const handler: Handler = async (event) => {
62
+ * const limit = getQueryParam(event, 'limit', '20'); // '10' or '20' default
63
+ * const status = getQueryParam(event, 'status'); // 'active' or undefined
64
+ * };
65
+ * ```
66
+ */
67
+ export declare function getQueryParam(
68
+ event: APIGatewayProxyEvent,
69
+ name: string,
70
+ defaultValue?: string
71
+ ): string | undefined;
72
+ /**
73
+ * Get user ID from an authenticated request.
74
+ *
75
+ * Extracts the Cognito user ID (sub claim) from the request context.
76
+ *
77
+ * @param event - Authenticated API Gateway event
78
+ * @returns The user ID from the JWT token
79
+ * @throws {UnauthorizedError} If user ID is not found in the token
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const handler: AuthenticatedHandler = async (event) => {
84
+ * const userId = getUserId(event);
85
+ * // userId is the Cognito 'sub' claim
86
+ * };
87
+ * ```
88
+ */
89
+ export declare function getUserId(event: AuthenticatedEvent): string;
90
+ //# sourceMappingURL=request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/lib/request.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,oBAAoB,GAAG,CAAC,CAU3D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,oBAAoB,EAC3B,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,GAAG,SAAS,CAEpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAM3D"}
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ /**
3
+ * Request parsing utilities for Lambda handlers.
4
+ *
5
+ * Provides type-safe extraction of request data including
6
+ * JSON body parsing, path parameters, and query parameters.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.parseBody = parseBody;
12
+ exports.requirePathParam = requirePathParam;
13
+ exports.getQueryParam = getQueryParam;
14
+ exports.getUserId = getUserId;
15
+ const errors_1 = require("./errors");
16
+ /**
17
+ * Parse JSON body from API Gateway event.
18
+ *
19
+ * @param event - API Gateway proxy event
20
+ * @returns Parsed JSON body as type T
21
+ * @throws {ValidationError} If body is missing or invalid JSON
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * interface CreateUserBody {
26
+ * name: string;
27
+ * email: string;
28
+ * }
29
+ *
30
+ * const handler: Handler = async (event) => {
31
+ * const body = parseBody<CreateUserBody>(event);
32
+ * // body is typed as CreateUserBody
33
+ * };
34
+ * ```
35
+ */
36
+ function parseBody(event) {
37
+ if (!event.body) {
38
+ throw new errors_1.ValidationError('Request body is required');
39
+ }
40
+ try {
41
+ return JSON.parse(event.body);
42
+ }
43
+ catch {
44
+ throw new errors_1.ValidationError('Invalid JSON in request body');
45
+ }
46
+ }
47
+ /**
48
+ * Get a required path parameter from the event.
49
+ *
50
+ * @param event - API Gateway proxy event
51
+ * @param name - Name of the path parameter
52
+ * @returns The path parameter value
53
+ * @throws {ValidationError} If the parameter is missing
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * // Route: GET /users/{id}
58
+ * const handler: Handler = async (event) => {
59
+ * const userId = requirePathParam(event, 'id');
60
+ * // userId is guaranteed to be a string
61
+ * };
62
+ * ```
63
+ */
64
+ function requirePathParam(event, name) {
65
+ const value = event.pathParameters?.[name];
66
+ if (!value) {
67
+ throw new errors_1.ValidationError(`Missing path parameter: ${name}`);
68
+ }
69
+ return value;
70
+ }
71
+ /**
72
+ * Get an optional query parameter from the event.
73
+ *
74
+ * @param event - API Gateway proxy event
75
+ * @param name - Name of the query parameter
76
+ * @param defaultValue - Optional default value if parameter is missing
77
+ * @returns The query parameter value or default
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * // GET /users?limit=10&status=active
82
+ * const handler: Handler = async (event) => {
83
+ * const limit = getQueryParam(event, 'limit', '20'); // '10' or '20' default
84
+ * const status = getQueryParam(event, 'status'); // 'active' or undefined
85
+ * };
86
+ * ```
87
+ */
88
+ function getQueryParam(event, name, defaultValue) {
89
+ return event.queryStringParameters?.[name] ?? defaultValue;
90
+ }
91
+ /**
92
+ * Get user ID from an authenticated request.
93
+ *
94
+ * Extracts the Cognito user ID (sub claim) from the request context.
95
+ *
96
+ * @param event - Authenticated API Gateway event
97
+ * @returns The user ID from the JWT token
98
+ * @throws {UnauthorizedError} If user ID is not found in the token
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * const handler: AuthenticatedHandler = async (event) => {
103
+ * const userId = getUserId(event);
104
+ * // userId is the Cognito 'sub' claim
105
+ * };
106
+ * ```
107
+ */
108
+ function getUserId(event) {
109
+ const userId = event.requestContext.authorizer?.claims?.sub;
110
+ if (!userId) {
111
+ throw new errors_1.UnauthorizedError('User ID not found in token');
112
+ }
113
+ return userId;
114
+ }
115
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/lib/request.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AA0BH,8BAUC;AAmBD,4CAMC;AAmBD,sCAMC;AAmBD,8BAMC;AA5GD,qCAA8D;AAG9D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAgB,SAAS,CAAI,KAA2B;IACtD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAChB,MAAM,IAAI,wBAAe,CAAC,0BAA0B,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,wBAAe,CAAC,8BAA8B,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,gBAAgB,CAAC,KAA2B,EAAE,IAAY;IACxE,MAAM,KAAK,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,wBAAe,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,aAAa,CAC3B,KAA2B,EAC3B,IAAY,EACZ,YAAqB;IAErB,OAAO,KAAK,CAAC,qBAAqB,EAAE,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,SAAS,CAAC,KAAyB;IACjD,MAAM,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC;IAC5D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,0BAAiB,CAAC,4BAA4B,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}