@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
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
|
package/lib/index.js.map
ADDED
|
@@ -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"}
|