@h4ad/serverless-adapter 1.0.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/@types/binary-settings.d.ts +23 -0
- package/lib/@types/binary-settings.js +2 -0
- package/lib/@types/headers.d.ts +24 -0
- package/lib/@types/headers.js +2 -0
- package/lib/@types/helpers.d.ts +6 -0
- package/lib/@types/helpers.js +2 -0
- package/lib/@types/index.d.ts +3 -0
- package/lib/@types/index.js +15 -0
- package/lib/@types/proxy-params.d.ts +8 -0
- package/lib/@types/proxy-params.js +2 -0
- package/lib/adapters/aws/alb.adapter.d.ts +58 -0
- package/lib/adapters/aws/alb.adapter.js +119 -0
- package/lib/adapters/aws/api-gateway-v1.adapter.d.ts +63 -0
- package/lib/adapters/aws/api-gateway-v1.adapter.js +126 -0
- package/lib/adapters/aws/api-gateway-v2.adapter.d.ts +61 -0
- package/lib/adapters/aws/api-gateway-v2.adapter.js +123 -0
- package/lib/adapters/aws/dynamodb.adapter.d.ts +62 -0
- package/lib/adapters/aws/dynamodb.adapter.js +81 -0
- package/lib/adapters/aws/event-bridge.adapter.d.ts +66 -0
- package/lib/adapters/aws/event-bridge.adapter.js +91 -0
- package/lib/adapters/aws/index.d.ts +8 -0
- package/lib/adapters/aws/index.js +20 -0
- package/lib/adapters/aws/lambda-edge.adapter.d.ts +179 -0
- package/lib/adapters/aws/lambda-edge.adapter.js +248 -0
- package/lib/adapters/aws/sns.adapter.d.ts +62 -0
- package/lib/adapters/aws/sns.adapter.js +81 -0
- package/lib/adapters/aws/sqs.adapter.d.ts +62 -0
- package/lib/adapters/aws/sqs.adapter.js +81 -0
- package/lib/adapters/index.d.ts +1 -0
- package/lib/adapters/index.js +13 -0
- package/lib/contracts/adapter.contract.d.ts +152 -0
- package/lib/contracts/adapter.contract.js +2 -0
- package/lib/contracts/framework.contract.d.ts +15 -0
- package/lib/contracts/framework.contract.js +3 -0
- package/lib/contracts/handler.contract.d.ts +18 -0
- package/lib/contracts/handler.contract.js +3 -0
- package/lib/contracts/index.d.ts +4 -0
- package/lib/contracts/index.js +16 -0
- package/lib/contracts/resolver.contract.d.ts +70 -0
- package/lib/contracts/resolver.contract.js +3 -0
- package/lib/core/constants.d.ts +4 -0
- package/lib/core/constants.js +10 -0
- package/lib/core/current-invoke.d.ts +37 -0
- package/lib/core/current-invoke.js +34 -0
- package/lib/core/event-body.d.ts +16 -0
- package/lib/core/event-body.js +24 -0
- package/lib/core/headers.d.ts +27 -0
- package/lib/core/headers.js +53 -0
- package/lib/core/index.d.ts +10 -0
- package/lib/core/index.js +22 -0
- package/lib/core/is-binary.d.ts +55 -0
- package/lib/core/is-binary.js +91 -0
- package/lib/core/logger.d.ts +38 -0
- package/lib/core/logger.js +51 -0
- package/lib/core/no-op.d.ts +4 -0
- package/lib/core/no-op.js +8 -0
- package/lib/core/optional.d.ts +17 -0
- package/lib/core/optional.js +25 -0
- package/lib/core/path.d.ts +28 -0
- package/lib/core/path.js +56 -0
- package/lib/core/stream.d.ts +8 -0
- package/lib/core/stream.js +39 -0
- package/lib/frameworks/express.framework.d.ts +13 -0
- package/lib/frameworks/express.framework.js +17 -0
- package/lib/frameworks/fastify.framework.d.ts +13 -0
- package/lib/frameworks/fastify.framework.js +18 -0
- package/lib/frameworks/hapi.framework.d.ts +13 -0
- package/lib/frameworks/hapi.framework.js +18 -0
- package/lib/frameworks/index.d.ts +4 -0
- package/lib/frameworks/index.js +16 -0
- package/lib/frameworks/koa.framework.d.ts +13 -0
- package/lib/frameworks/koa.framework.js +17 -0
- package/lib/handlers/base/base.handler.d.ts +28 -0
- package/lib/handlers/base/base.handler.js +52 -0
- package/lib/handlers/base/index.d.ts +1 -0
- package/lib/handlers/base/index.js +13 -0
- package/lib/handlers/default.handler.d.ts +85 -0
- package/lib/handlers/default.handler.js +183 -0
- package/lib/handlers/index.d.ts +2 -0
- package/lib/handlers/index.js +14 -0
- package/lib/index.d.ts +9 -0
- package/lib/index.js +21 -0
- package/lib/network/index.d.ts +2 -0
- package/lib/network/index.js +14 -0
- package/lib/network/request.d.ts +15 -0
- package/lib/network/request.js +40 -0
- package/lib/network/response.d.ts +22 -0
- package/lib/network/response.js +104 -0
- package/lib/resolvers/aws-context.resolver.d.ts +21 -0
- package/lib/resolvers/aws-context.resolver.js +55 -0
- package/lib/resolvers/callback.resolver.d.ts +16 -0
- package/lib/resolvers/callback.resolver.js +40 -0
- package/lib/resolvers/index.d.ts +3 -0
- package/lib/resolvers/index.js +15 -0
- package/lib/resolvers/promise.resolver.d.ts +10 -0
- package/lib/resolvers/promise.resolver.js +38 -0
- package/lib/serverless-adapter.d.ts +114 -0
- package/lib/serverless-adapter.js +158 -0
- package/package.json +130 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.ApiGatewayV1Adapter = void 0;
|
|
5
|
+
const core_1 = require("../../core");
|
|
6
|
+
/**
|
|
7
|
+
* The adapter to handle requests from AWS Api Gateway V1
|
|
8
|
+
*
|
|
9
|
+
* As per {@link https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-known-issues.html know issues}, we throw an exception when you send the `transfer-encoding=chunked`, currently, API Gateway doesn't support chunked transfer.
|
|
10
|
+
*
|
|
11
|
+
* @note This adapter is not fully compatible with @vendia/serverless-express, on @vendia they filter `transfer-encoding=chunked` but we throw an exception.
|
|
12
|
+
*
|
|
13
|
+
* @example```typescript
|
|
14
|
+
* const stripBasePath = '/any/custom/base/path'; // default ''
|
|
15
|
+
* const adapter = new ApiGatewayV1Adapter({ stripBasePath });
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* {@link https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html Event Reference}
|
|
19
|
+
*/
|
|
20
|
+
class ApiGatewayV1Adapter {
|
|
21
|
+
//#region Constructor
|
|
22
|
+
/**
|
|
23
|
+
* Default constructor
|
|
24
|
+
*
|
|
25
|
+
* @param options The options to customize the {@link ApiGatewayV1Adapter}
|
|
26
|
+
*/
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.options = options;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region Public Methods
|
|
32
|
+
/**
|
|
33
|
+
* @inheritDoc
|
|
34
|
+
*/
|
|
35
|
+
getAdapterName() {
|
|
36
|
+
return ApiGatewayV1Adapter.name;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @inheritDoc
|
|
40
|
+
*/
|
|
41
|
+
canHandle(event) {
|
|
42
|
+
const partialEventV1 = event;
|
|
43
|
+
return !!((partialEventV1 === null || partialEventV1 === void 0 ? void 0 : partialEventV1.requestContext) &&
|
|
44
|
+
partialEventV1.version !== '2.0' &&
|
|
45
|
+
partialEventV1.headers &&
|
|
46
|
+
partialEventV1.multiValueHeaders &&
|
|
47
|
+
(partialEventV1.queryStringParameters ===
|
|
48
|
+
partialEventV1.multiValueQueryStringParameters ||
|
|
49
|
+
(partialEventV1.queryStringParameters &&
|
|
50
|
+
partialEventV1.multiValueQueryStringParameters)));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* @inheritDoc
|
|
54
|
+
*/
|
|
55
|
+
getRequest(event) {
|
|
56
|
+
const method = event.httpMethod;
|
|
57
|
+
const headers = event.headers;
|
|
58
|
+
const path = this.getPathFromEvent(event);
|
|
59
|
+
let body;
|
|
60
|
+
if (event.body) {
|
|
61
|
+
const [bufferBody, contentLength] = (0, core_1.getEventBodyAsBuffer)(event.body, event.isBase64Encoded);
|
|
62
|
+
body = bufferBody;
|
|
63
|
+
headers['content-length'] = String(contentLength);
|
|
64
|
+
}
|
|
65
|
+
const remoteAddress = event.requestContext.identity.sourceIp;
|
|
66
|
+
return {
|
|
67
|
+
method,
|
|
68
|
+
headers,
|
|
69
|
+
body,
|
|
70
|
+
remoteAddress,
|
|
71
|
+
path,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* @inheritDoc
|
|
76
|
+
*/
|
|
77
|
+
getResponse({ headers: responseHeaders, body, isBase64Encoded, statusCode, response, }) {
|
|
78
|
+
const multiValueHeaders = (0, core_1.getMultiValueHeadersMap)(responseHeaders);
|
|
79
|
+
const transferEncodingHeader = multiValueHeaders['transfer-encoding'];
|
|
80
|
+
const hasTransferEncodingChunked = transferEncodingHeader &&
|
|
81
|
+
transferEncodingHeader.some(value => value.includes('chunked'));
|
|
82
|
+
if (hasTransferEncodingChunked) {
|
|
83
|
+
throw new Error('chunked encoding in headers is not supported by API Gateway V1');
|
|
84
|
+
}
|
|
85
|
+
if (response === null || response === void 0 ? void 0 : response.chunkedEncoding) {
|
|
86
|
+
throw new Error('chunked encoding in response is not supported by API Gateway V1');
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
statusCode,
|
|
90
|
+
body,
|
|
91
|
+
multiValueHeaders,
|
|
92
|
+
isBase64Encoded,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* @inheritDoc
|
|
97
|
+
*/
|
|
98
|
+
onErrorWhileForwarding({ error, delegatedResolver, respondWithErrors, event, log, }) {
|
|
99
|
+
const body = respondWithErrors ? error.stack : '';
|
|
100
|
+
const errorResponse = this.getResponse({
|
|
101
|
+
event,
|
|
102
|
+
statusCode: 500,
|
|
103
|
+
body: body || '',
|
|
104
|
+
headers: {},
|
|
105
|
+
isBase64Encoded: false,
|
|
106
|
+
log,
|
|
107
|
+
});
|
|
108
|
+
delegatedResolver.succeed(errorResponse);
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
111
|
+
//#region Protected Methods
|
|
112
|
+
/**
|
|
113
|
+
* Get path from event with query strings
|
|
114
|
+
*
|
|
115
|
+
* @param event The event sent by serverless
|
|
116
|
+
*/
|
|
117
|
+
getPathFromEvent(event) {
|
|
118
|
+
var _a;
|
|
119
|
+
const stripBasePath = (0, core_1.getDefaultIfUndefined)((_a = this.options) === null || _a === void 0 ? void 0 : _a.stripBasePath, '');
|
|
120
|
+
const replaceRegex = new RegExp(`^${stripBasePath}`);
|
|
121
|
+
const path = event.path.replace(replaceRegex, '');
|
|
122
|
+
const queryParams = event.queryStringParameters || {};
|
|
123
|
+
return (0, core_1.getPathWithQueryStringParams)(path, queryParams);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.ApiGatewayV1Adapter = ApiGatewayV1Adapter;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { APIGatewayProxyEventV2, Context } from 'aws-lambda';
|
|
2
|
+
import type { APIGatewayProxyStructuredResultV2 } from 'aws-lambda/trigger/api-gateway-proxy';
|
|
3
|
+
import { AdapterContract, AdapterRequest, GetResponseAdapterProps, OnErrorProps } from '../../contracts';
|
|
4
|
+
/**
|
|
5
|
+
* The options to customize the {@link ApiGatewayV2Adapter}
|
|
6
|
+
*/
|
|
7
|
+
export interface ApiGatewayV2Options {
|
|
8
|
+
/**
|
|
9
|
+
* Strip base path for custom domains
|
|
10
|
+
*
|
|
11
|
+
* @default ''
|
|
12
|
+
*/
|
|
13
|
+
stripBasePath?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The adapter to handle requests from AWS Api Gateway V2
|
|
17
|
+
*
|
|
18
|
+
* As per {@link https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-known-issues.html know issues}, we throw an exception when you send the `transfer-encoding=chunked`, currently, API Gateway doesn't support chunked transfer.
|
|
19
|
+
*
|
|
20
|
+
* @example```typescript
|
|
21
|
+
* const stripBasePath = '/any/custom/base/path'; // default ''
|
|
22
|
+
* const adapter = new ApiGatewayV2Adapter({ stripBasePath });
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* {@link https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html Event Reference}
|
|
26
|
+
*/
|
|
27
|
+
export declare class ApiGatewayV2Adapter implements AdapterContract<APIGatewayProxyEventV2, Context, APIGatewayProxyStructuredResultV2> {
|
|
28
|
+
protected readonly options?: ApiGatewayV2Options | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Default constructor
|
|
31
|
+
*
|
|
32
|
+
* @param options The options to customize the {@link ApiGatewayV2Adapter}
|
|
33
|
+
*/
|
|
34
|
+
constructor(options?: ApiGatewayV2Options | undefined);
|
|
35
|
+
/**
|
|
36
|
+
* @inheritDoc
|
|
37
|
+
*/
|
|
38
|
+
getAdapterName(): string;
|
|
39
|
+
/**
|
|
40
|
+
* @inheritDoc
|
|
41
|
+
*/
|
|
42
|
+
canHandle(event: unknown): event is APIGatewayProxyEventV2;
|
|
43
|
+
/**
|
|
44
|
+
* @inheritDoc
|
|
45
|
+
*/
|
|
46
|
+
getRequest(event: APIGatewayProxyEventV2): AdapterRequest;
|
|
47
|
+
/**
|
|
48
|
+
* @inheritDoc
|
|
49
|
+
*/
|
|
50
|
+
getResponse({ headers: responseHeaders, body, isBase64Encoded, statusCode, response, }: GetResponseAdapterProps<APIGatewayProxyEventV2>): APIGatewayProxyStructuredResultV2;
|
|
51
|
+
/**
|
|
52
|
+
* @inheritDoc
|
|
53
|
+
*/
|
|
54
|
+
onErrorWhileForwarding({ error, delegatedResolver, respondWithErrors, event, log, }: OnErrorProps<APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2>): void;
|
|
55
|
+
/**
|
|
56
|
+
* Get path from event with query strings
|
|
57
|
+
*
|
|
58
|
+
* @param event The event sent by serverless
|
|
59
|
+
*/
|
|
60
|
+
protected getPathFromEvent(event: APIGatewayProxyEventV2): string;
|
|
61
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.ApiGatewayV2Adapter = void 0;
|
|
5
|
+
const core_1 = require("../../core");
|
|
6
|
+
/**
|
|
7
|
+
* The adapter to handle requests from AWS Api Gateway V2
|
|
8
|
+
*
|
|
9
|
+
* As per {@link https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-known-issues.html know issues}, we throw an exception when you send the `transfer-encoding=chunked`, currently, API Gateway doesn't support chunked transfer.
|
|
10
|
+
*
|
|
11
|
+
* @example```typescript
|
|
12
|
+
* const stripBasePath = '/any/custom/base/path'; // default ''
|
|
13
|
+
* const adapter = new ApiGatewayV2Adapter({ stripBasePath });
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* {@link https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html Event Reference}
|
|
17
|
+
*/
|
|
18
|
+
class ApiGatewayV2Adapter {
|
|
19
|
+
//#region Constructor
|
|
20
|
+
/**
|
|
21
|
+
* Default constructor
|
|
22
|
+
*
|
|
23
|
+
* @param options The options to customize the {@link ApiGatewayV2Adapter}
|
|
24
|
+
*/
|
|
25
|
+
constructor(options) {
|
|
26
|
+
this.options = options;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region Public Methods
|
|
30
|
+
/**
|
|
31
|
+
* @inheritDoc
|
|
32
|
+
*/
|
|
33
|
+
getAdapterName() {
|
|
34
|
+
return ApiGatewayV2Adapter.name;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @inheritDoc
|
|
38
|
+
*/
|
|
39
|
+
canHandle(event) {
|
|
40
|
+
const apiGatewayEvent = event;
|
|
41
|
+
return !!((apiGatewayEvent === null || apiGatewayEvent === void 0 ? void 0 : apiGatewayEvent.requestContext) && apiGatewayEvent.version === '2.0');
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* @inheritDoc
|
|
45
|
+
*/
|
|
46
|
+
getRequest(event) {
|
|
47
|
+
const method = event.requestContext.http.method;
|
|
48
|
+
const path = this.getPathFromEvent(event);
|
|
49
|
+
const headers = (0, core_1.getFlattenedHeadersMap)(event.headers, ',', true);
|
|
50
|
+
if (event.cookies)
|
|
51
|
+
headers.cookie = event.cookies.join('; ');
|
|
52
|
+
let body;
|
|
53
|
+
if (event.body) {
|
|
54
|
+
const [bufferBody, contentLength] = (0, core_1.getEventBodyAsBuffer)(event.body, event.isBase64Encoded);
|
|
55
|
+
body = bufferBody;
|
|
56
|
+
headers['content-length'] = String(contentLength);
|
|
57
|
+
}
|
|
58
|
+
const remoteAddress = event.requestContext.http.sourceIp;
|
|
59
|
+
return {
|
|
60
|
+
method,
|
|
61
|
+
headers,
|
|
62
|
+
body,
|
|
63
|
+
remoteAddress,
|
|
64
|
+
path,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* @inheritDoc
|
|
69
|
+
*/
|
|
70
|
+
getResponse({ headers: responseHeaders, body, isBase64Encoded, statusCode, response, }) {
|
|
71
|
+
const headers = (0, core_1.getFlattenedHeadersMap)(responseHeaders);
|
|
72
|
+
const transferEncodingHeader = headers['transfer-encoding'];
|
|
73
|
+
const hasTransferEncodingChunked = transferEncodingHeader && transferEncodingHeader.includes('chunked');
|
|
74
|
+
if (hasTransferEncodingChunked) {
|
|
75
|
+
throw new Error('chunked encoding in headers is not supported by API Gateway V1');
|
|
76
|
+
}
|
|
77
|
+
if (response === null || response === void 0 ? void 0 : response.chunkedEncoding) {
|
|
78
|
+
throw new Error('chunked encoding in response is not supported by API Gateway V1');
|
|
79
|
+
}
|
|
80
|
+
const cookies = headers['set-cookie'];
|
|
81
|
+
if (cookies) {
|
|
82
|
+
headers.cookies = cookies;
|
|
83
|
+
delete headers['set-cookie'];
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
statusCode,
|
|
87
|
+
body,
|
|
88
|
+
headers,
|
|
89
|
+
isBase64Encoded,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* @inheritDoc
|
|
94
|
+
*/
|
|
95
|
+
onErrorWhileForwarding({ error, delegatedResolver, respondWithErrors, event, log, }) {
|
|
96
|
+
const body = respondWithErrors ? error.stack : '';
|
|
97
|
+
const errorResponse = this.getResponse({
|
|
98
|
+
event,
|
|
99
|
+
statusCode: 500,
|
|
100
|
+
body: body || '',
|
|
101
|
+
headers: {},
|
|
102
|
+
isBase64Encoded: false,
|
|
103
|
+
log,
|
|
104
|
+
});
|
|
105
|
+
delegatedResolver.succeed(errorResponse);
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region Protected Methods
|
|
109
|
+
/**
|
|
110
|
+
* Get path from event with query strings
|
|
111
|
+
*
|
|
112
|
+
* @param event The event sent by serverless
|
|
113
|
+
*/
|
|
114
|
+
getPathFromEvent(event) {
|
|
115
|
+
var _a;
|
|
116
|
+
const stripBasePath = (0, core_1.getDefaultIfUndefined)((_a = this.options) === null || _a === void 0 ? void 0 : _a.stripBasePath, '');
|
|
117
|
+
const replaceRegex = new RegExp(`^${stripBasePath}`);
|
|
118
|
+
const path = event.rawPath.replace(replaceRegex, '');
|
|
119
|
+
const queryParams = event.rawQueryString;
|
|
120
|
+
return (0, core_1.getPathWithQueryStringParams)(path, queryParams || {});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.ApiGatewayV2Adapter = ApiGatewayV2Adapter;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { Context, DynamoDBStreamEvent } from 'aws-lambda';
|
|
2
|
+
import { AdapterContract, AdapterRequest, OnErrorProps } from '../../contracts';
|
|
3
|
+
import { IEmptyResponse } from '../../core';
|
|
4
|
+
/**
|
|
5
|
+
* The options to customize the {@link DynamoDBAdapter}
|
|
6
|
+
*/
|
|
7
|
+
export interface DynamoDBAdapterOptions {
|
|
8
|
+
/**
|
|
9
|
+
* The path that will be used to create a request to be forwarded to the framework.
|
|
10
|
+
*
|
|
11
|
+
* @default /dynamo
|
|
12
|
+
*/
|
|
13
|
+
dynamoDBForwardPath?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The http method that will be used to create a request to be forwarded to the framework.
|
|
16
|
+
*
|
|
17
|
+
* @default POST
|
|
18
|
+
*/
|
|
19
|
+
dynamoDBForwardMethod?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The adapter to handle requests from AWS DynamoDB.
|
|
23
|
+
*
|
|
24
|
+
* The option of `responseWithErrors` is ignored by this adapter and we always call `resolver.fail` with the error.
|
|
25
|
+
*
|
|
26
|
+
* {@link https://docs.aws.amazon.com/lambda/latest/dg/with-ddb.html Event Reference}
|
|
27
|
+
*
|
|
28
|
+
* @example```typescript
|
|
29
|
+
* const dynamoDBForwardPath = '/your/route/dynamo'; // default /dynamo
|
|
30
|
+
* const dynamoDBForwardMethod = 'POST'; // default POST
|
|
31
|
+
* const adapter = new DynamoDBAdapter({ dynamoDBForwardPath, dynamoDBForwardMethod });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class DynamoDBAdapter implements AdapterContract<DynamoDBStreamEvent, Context, IEmptyResponse> {
|
|
35
|
+
protected readonly options?: DynamoDBAdapterOptions | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Default constructor
|
|
38
|
+
*
|
|
39
|
+
* @param options The options to customize the {@link DynamoDBAdapter}
|
|
40
|
+
*/
|
|
41
|
+
constructor(options?: DynamoDBAdapterOptions | undefined);
|
|
42
|
+
/**
|
|
43
|
+
* @inheritDoc
|
|
44
|
+
*/
|
|
45
|
+
getAdapterName(): string;
|
|
46
|
+
/**
|
|
47
|
+
* @inheritDoc
|
|
48
|
+
*/
|
|
49
|
+
canHandle(event: unknown): event is DynamoDBStreamEvent;
|
|
50
|
+
/**
|
|
51
|
+
* @inheritDoc
|
|
52
|
+
*/
|
|
53
|
+
getRequest(event: DynamoDBStreamEvent): AdapterRequest;
|
|
54
|
+
/**
|
|
55
|
+
* @inheritDoc
|
|
56
|
+
*/
|
|
57
|
+
getResponse(): IEmptyResponse;
|
|
58
|
+
/**
|
|
59
|
+
* @inheritDoc
|
|
60
|
+
*/
|
|
61
|
+
onErrorWhileForwarding({ error, delegatedResolver, }: OnErrorProps<DynamoDBStreamEvent, IEmptyResponse>): void;
|
|
62
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.DynamoDBAdapter = void 0;
|
|
5
|
+
const core_1 = require("../../core");
|
|
6
|
+
/**
|
|
7
|
+
* The adapter to handle requests from AWS DynamoDB.
|
|
8
|
+
*
|
|
9
|
+
* The option of `responseWithErrors` is ignored by this adapter and we always call `resolver.fail` with the error.
|
|
10
|
+
*
|
|
11
|
+
* {@link https://docs.aws.amazon.com/lambda/latest/dg/with-ddb.html Event Reference}
|
|
12
|
+
*
|
|
13
|
+
* @example```typescript
|
|
14
|
+
* const dynamoDBForwardPath = '/your/route/dynamo'; // default /dynamo
|
|
15
|
+
* const dynamoDBForwardMethod = 'POST'; // default POST
|
|
16
|
+
* const adapter = new DynamoDBAdapter({ dynamoDBForwardPath, dynamoDBForwardMethod });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
class DynamoDBAdapter {
|
|
20
|
+
//#region Constructor
|
|
21
|
+
/**
|
|
22
|
+
* Default constructor
|
|
23
|
+
*
|
|
24
|
+
* @param options The options to customize the {@link DynamoDBAdapter}
|
|
25
|
+
*/
|
|
26
|
+
constructor(options) {
|
|
27
|
+
this.options = options;
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region Public Methods
|
|
31
|
+
/**
|
|
32
|
+
* @inheritDoc
|
|
33
|
+
*/
|
|
34
|
+
getAdapterName() {
|
|
35
|
+
return DynamoDBAdapter.name;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* @inheritDoc
|
|
39
|
+
*/
|
|
40
|
+
canHandle(event) {
|
|
41
|
+
var _a;
|
|
42
|
+
const dynamoDBevent = event;
|
|
43
|
+
if (!Array.isArray(dynamoDBevent === null || dynamoDBevent === void 0 ? void 0 : dynamoDBevent.Records))
|
|
44
|
+
return false;
|
|
45
|
+
const eventSource = (_a = dynamoDBevent.Records[0]) === null || _a === void 0 ? void 0 : _a.eventSource;
|
|
46
|
+
return eventSource === 'aws:dynamodb';
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* @inheritDoc
|
|
50
|
+
*/
|
|
51
|
+
getRequest(event) {
|
|
52
|
+
var _a, _b;
|
|
53
|
+
const path = (0, core_1.getDefaultIfUndefined)((_a = this.options) === null || _a === void 0 ? void 0 : _a.dynamoDBForwardPath, '/dynamo');
|
|
54
|
+
const method = (0, core_1.getDefaultIfUndefined)((_b = this.options) === null || _b === void 0 ? void 0 : _b.dynamoDBForwardMethod, 'POST');
|
|
55
|
+
const [body, contentLength] = (0, core_1.getEventBodyAsBuffer)(JSON.stringify(event), false);
|
|
56
|
+
const headers = {
|
|
57
|
+
host: 'dynamodb.amazonaws.com',
|
|
58
|
+
'content-type': 'application/json',
|
|
59
|
+
'content-length': String(contentLength),
|
|
60
|
+
};
|
|
61
|
+
return {
|
|
62
|
+
method,
|
|
63
|
+
headers,
|
|
64
|
+
body,
|
|
65
|
+
path,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* @inheritDoc
|
|
70
|
+
*/
|
|
71
|
+
getResponse() {
|
|
72
|
+
return core_1.EmptyResponse;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* @inheritDoc
|
|
76
|
+
*/
|
|
77
|
+
onErrorWhileForwarding({ error, delegatedResolver, }) {
|
|
78
|
+
delegatedResolver.fail(error);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.DynamoDBAdapter = DynamoDBAdapter;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Context, EventBridgeEvent } from 'aws-lambda';
|
|
2
|
+
import { AdapterContract, AdapterRequest, OnErrorProps } from '../../contracts';
|
|
3
|
+
import { IEmptyResponse } from '../../core';
|
|
4
|
+
/**
|
|
5
|
+
* The options to customize the {@link EventBridgeAdapter}
|
|
6
|
+
*/
|
|
7
|
+
export interface EventBridgeOptions {
|
|
8
|
+
/**
|
|
9
|
+
* The path that will be used to create a request to be forwarded to the framework.
|
|
10
|
+
*
|
|
11
|
+
* @default /eventbridge
|
|
12
|
+
*/
|
|
13
|
+
eventBridgeForwardPath?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The http method that will be used to create a request to be forwarded to the framework.
|
|
16
|
+
*
|
|
17
|
+
* @default POST
|
|
18
|
+
*/
|
|
19
|
+
eventBridgeForwardMethod?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Just a type alias to ignore generic types in the event
|
|
23
|
+
*/
|
|
24
|
+
export declare type EventBridgeEventAll = EventBridgeEvent<any, any>;
|
|
25
|
+
/**
|
|
26
|
+
* The adapter to handle requests from AWS EventBridge (Cloudwatch Events).
|
|
27
|
+
*
|
|
28
|
+
* The option of `responseWithErrors` is ignored by this adapter and we always call `resolver.fail` with the error.
|
|
29
|
+
*
|
|
30
|
+
* {@link https://docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents.html Event Reference}
|
|
31
|
+
*
|
|
32
|
+
* @example```typescript
|
|
33
|
+
* const eventBridgeForwardPath = '/your/route/eventbridge'; // default /eventbridge
|
|
34
|
+
* const eventBridgeForwardMethod = 'POST'; // default POST
|
|
35
|
+
* const adapter = new EventBridgeAdapter({ eventBridgeForwardPath, eventBridgeForwardMethod });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare class EventBridgeAdapter implements AdapterContract<EventBridgeEventAll, Context, IEmptyResponse> {
|
|
39
|
+
protected readonly options?: EventBridgeOptions | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Default constructor
|
|
42
|
+
*
|
|
43
|
+
* @param options The options to customize the {@link EventBridgeAdapter}
|
|
44
|
+
*/
|
|
45
|
+
constructor(options?: EventBridgeOptions | undefined);
|
|
46
|
+
/**
|
|
47
|
+
* @inheritDoc
|
|
48
|
+
*/
|
|
49
|
+
getAdapterName(): string;
|
|
50
|
+
/**
|
|
51
|
+
* @inheritDoc
|
|
52
|
+
*/
|
|
53
|
+
canHandle(event: unknown): event is EventBridgeEventAll;
|
|
54
|
+
/**
|
|
55
|
+
* @inheritDoc
|
|
56
|
+
*/
|
|
57
|
+
getRequest(event: EventBridgeEventAll): AdapterRequest;
|
|
58
|
+
/**
|
|
59
|
+
* @inheritDoc
|
|
60
|
+
*/
|
|
61
|
+
getResponse(): IEmptyResponse;
|
|
62
|
+
/**
|
|
63
|
+
* @inheritDoc
|
|
64
|
+
*/
|
|
65
|
+
onErrorWhileForwarding({ error, delegatedResolver, }: OnErrorProps<EventBridgeEventAll, IEmptyResponse>): void;
|
|
66
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.EventBridgeAdapter = void 0;
|
|
5
|
+
const core_1 = require("../../core");
|
|
6
|
+
/**
|
|
7
|
+
* The adapter to handle requests from AWS EventBridge (Cloudwatch Events).
|
|
8
|
+
*
|
|
9
|
+
* The option of `responseWithErrors` is ignored by this adapter and we always call `resolver.fail` with the error.
|
|
10
|
+
*
|
|
11
|
+
* {@link https://docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents.html Event Reference}
|
|
12
|
+
*
|
|
13
|
+
* @example```typescript
|
|
14
|
+
* const eventBridgeForwardPath = '/your/route/eventbridge'; // default /eventbridge
|
|
15
|
+
* const eventBridgeForwardMethod = 'POST'; // default POST
|
|
16
|
+
* const adapter = new EventBridgeAdapter({ eventBridgeForwardPath, eventBridgeForwardMethod });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
class EventBridgeAdapter {
|
|
20
|
+
//#region Constructor
|
|
21
|
+
/**
|
|
22
|
+
* Default constructor
|
|
23
|
+
*
|
|
24
|
+
* @param options The options to customize the {@link EventBridgeAdapter}
|
|
25
|
+
*/
|
|
26
|
+
constructor(options) {
|
|
27
|
+
this.options = options;
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region Public Methods
|
|
31
|
+
/**
|
|
32
|
+
* @inheritDoc
|
|
33
|
+
*/
|
|
34
|
+
getAdapterName() {
|
|
35
|
+
return EventBridgeAdapter.name;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* @inheritDoc
|
|
39
|
+
*/
|
|
40
|
+
canHandle(event) {
|
|
41
|
+
const eventBridgeEvent = event;
|
|
42
|
+
// thanks to @cnuss in https://github.com/vendia/serverless-express/blob/b5da6070b8dd2fb674c1f7035dd7edfef1dc83a2/src/event-sources/utils.js#L87
|
|
43
|
+
return !!(eventBridgeEvent &&
|
|
44
|
+
eventBridgeEvent.version &&
|
|
45
|
+
eventBridgeEvent.version === '0' &&
|
|
46
|
+
eventBridgeEvent.id &&
|
|
47
|
+
eventBridgeEvent['detail-type'] &&
|
|
48
|
+
eventBridgeEvent.source &&
|
|
49
|
+
eventBridgeEvent.account &&
|
|
50
|
+
eventBridgeEvent.time &&
|
|
51
|
+
eventBridgeEvent.region &&
|
|
52
|
+
eventBridgeEvent.resources &&
|
|
53
|
+
Array.isArray(eventBridgeEvent.resources) &&
|
|
54
|
+
eventBridgeEvent.detail &&
|
|
55
|
+
typeof eventBridgeEvent.detail === 'object' &&
|
|
56
|
+
!Array.isArray(eventBridgeEvent.detail));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* @inheritDoc
|
|
60
|
+
*/
|
|
61
|
+
getRequest(event) {
|
|
62
|
+
var _a, _b;
|
|
63
|
+
const path = (0, core_1.getDefaultIfUndefined)((_a = this.options) === null || _a === void 0 ? void 0 : _a.eventBridgeForwardPath, '/eventbridge');
|
|
64
|
+
const method = (0, core_1.getDefaultIfUndefined)((_b = this.options) === null || _b === void 0 ? void 0 : _b.eventBridgeForwardMethod, 'POST');
|
|
65
|
+
const [body, contentLength] = (0, core_1.getEventBodyAsBuffer)(JSON.stringify(event), false);
|
|
66
|
+
const headers = {
|
|
67
|
+
host: 'events.amazonaws.com',
|
|
68
|
+
'content-type': 'application/json',
|
|
69
|
+
'content-length': String(contentLength),
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
method,
|
|
73
|
+
headers,
|
|
74
|
+
body,
|
|
75
|
+
path,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* @inheritDoc
|
|
80
|
+
*/
|
|
81
|
+
getResponse() {
|
|
82
|
+
return core_1.EmptyResponse;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* @inheritDoc
|
|
86
|
+
*/
|
|
87
|
+
onErrorWhileForwarding({ error, delegatedResolver, }) {
|
|
88
|
+
delegatedResolver.fail(error);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.EventBridgeAdapter = EventBridgeAdapter;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './alb.adapter';
|
|
2
|
+
export * from './api-gateway-v1.adapter';
|
|
3
|
+
export * from './api-gateway-v2.adapter';
|
|
4
|
+
export * from './dynamodb.adapter';
|
|
5
|
+
export * from './event-bridge.adapter';
|
|
6
|
+
export * from './lambda-edge.adapter';
|
|
7
|
+
export * from './sns.adapter';
|
|
8
|
+
export * from './sqs.adapter';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./alb.adapter"), exports);
|
|
14
|
+
__exportStar(require("./api-gateway-v1.adapter"), exports);
|
|
15
|
+
__exportStar(require("./api-gateway-v2.adapter"), exports);
|
|
16
|
+
__exportStar(require("./dynamodb.adapter"), exports);
|
|
17
|
+
__exportStar(require("./event-bridge.adapter"), exports);
|
|
18
|
+
__exportStar(require("./lambda-edge.adapter"), exports);
|
|
19
|
+
__exportStar(require("./sns.adapter"), exports);
|
|
20
|
+
__exportStar(require("./sqs.adapter"), exports);
|