@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,55 @@
|
|
|
1
|
+
import { BinarySettings, BothValueHeaders } from '../@types';
|
|
2
|
+
/**
|
|
3
|
+
* The function that determines by the content encoding whether the response should be treated as binary
|
|
4
|
+
*
|
|
5
|
+
* @example```typescript
|
|
6
|
+
* const headers = { 'Content-Encoding': 'gzip' };
|
|
7
|
+
* const isBinary = isContentEncodingBinary(headers, ['gzip']);
|
|
8
|
+
* console.log(isBinary);
|
|
9
|
+
* // true
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* @param headers The headers of the response
|
|
13
|
+
* @param binaryEncodingTypes The list of content encodings that will be treated as binary
|
|
14
|
+
*/
|
|
15
|
+
export declare function isContentEncodingBinary(headers: BothValueHeaders, binaryEncodingTypes: string[]): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* The function that returns the content type of headers
|
|
18
|
+
*
|
|
19
|
+
* @example```typescript
|
|
20
|
+
* const headers = { 'Content-Type': 'application/json' };
|
|
21
|
+
* const contentType = getContentType(headers);
|
|
22
|
+
* console.log(contentType);
|
|
23
|
+
* // application/json
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @param headers The headers of the response
|
|
27
|
+
*/
|
|
28
|
+
export declare function getContentType(headers: BothValueHeaders): string;
|
|
29
|
+
/**
|
|
30
|
+
* The function that determines by the content type whether the response should be treated as binary
|
|
31
|
+
*
|
|
32
|
+
* @example```typescript
|
|
33
|
+
* const headers = { 'Content-Type': 'image/png' };
|
|
34
|
+
* const isBinary = isContentTypeBinary(headers, [new RegExp('^image/.*$')]);
|
|
35
|
+
* console.log(isBinary);
|
|
36
|
+
* // true
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @param headers The headers of the response
|
|
40
|
+
* @param binaryContentTypes The list of content types that will be treated as binary
|
|
41
|
+
*/
|
|
42
|
+
export declare function isContentTypeBinary(headers: BothValueHeaders, binaryContentTypes: (string | RegExp)[]): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* The function used to determine from the headers and the binary settings if a response should be encoded or not
|
|
45
|
+
*
|
|
46
|
+
* @example```typescript
|
|
47
|
+
* const headers = { 'Content-Type': 'image/png', 'Content-Encoding': 'gzip' };
|
|
48
|
+
* const isContentBinary = isBinary(headers, { contentEncodings: ['gzip'], contentTypes: [new RegExp('^image/.*$')] });
|
|
49
|
+
* console.log(isContentBinary);
|
|
50
|
+
* // true
|
|
51
|
+
*
|
|
52
|
+
* @param headers The headers of the response
|
|
53
|
+
* @param binarySettings The settings for the validation
|
|
54
|
+
*/
|
|
55
|
+
export declare function isBinary(headers: BothValueHeaders, binarySettings: BinarySettings): boolean;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ATTRIBUTION: https://github.com/dougmoscrop/serverless-http
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.isBinary = exports.isContentTypeBinary = exports.getContentType = exports.isContentEncodingBinary = void 0;
|
|
5
|
+
const headers_1 = require("./headers");
|
|
6
|
+
//#endregion
|
|
7
|
+
/**
|
|
8
|
+
* The function that determines by the content encoding whether the response should be treated as binary
|
|
9
|
+
*
|
|
10
|
+
* @example```typescript
|
|
11
|
+
* const headers = { 'Content-Encoding': 'gzip' };
|
|
12
|
+
* const isBinary = isContentEncodingBinary(headers, ['gzip']);
|
|
13
|
+
* console.log(isBinary);
|
|
14
|
+
* // true
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @param headers The headers of the response
|
|
18
|
+
* @param binaryEncodingTypes The list of content encodings that will be treated as binary
|
|
19
|
+
*/
|
|
20
|
+
function isContentEncodingBinary(headers, binaryEncodingTypes) {
|
|
21
|
+
const multiValueHeaders = (0, headers_1.getMultiValueHeadersMap)(headers);
|
|
22
|
+
const contentEncodings = multiValueHeaders['content-encoding'];
|
|
23
|
+
if (!Array.isArray(contentEncodings))
|
|
24
|
+
return false;
|
|
25
|
+
return contentEncodings.some(value => binaryEncodingTypes.some(binaryEncoding => value.includes(binaryEncoding)));
|
|
26
|
+
}
|
|
27
|
+
exports.isContentEncodingBinary = isContentEncodingBinary;
|
|
28
|
+
/**
|
|
29
|
+
* The function that returns the content type of headers
|
|
30
|
+
*
|
|
31
|
+
* @example```typescript
|
|
32
|
+
* const headers = { 'Content-Type': 'application/json' };
|
|
33
|
+
* const contentType = getContentType(headers);
|
|
34
|
+
* console.log(contentType);
|
|
35
|
+
* // application/json
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @param headers The headers of the response
|
|
39
|
+
*/
|
|
40
|
+
function getContentType(headers) {
|
|
41
|
+
const flattenedHeaders = (0, headers_1.getFlattenedHeadersMap)(headers, ';', true);
|
|
42
|
+
const contentTypeHeader = flattenedHeaders['content-type'] || '';
|
|
43
|
+
// only compare mime type; ignore encoding part
|
|
44
|
+
return contentTypeHeader.split(';')[0];
|
|
45
|
+
}
|
|
46
|
+
exports.getContentType = getContentType;
|
|
47
|
+
/**
|
|
48
|
+
* The function that determines by the content type whether the response should be treated as binary
|
|
49
|
+
*
|
|
50
|
+
* @example```typescript
|
|
51
|
+
* const headers = { 'Content-Type': 'image/png' };
|
|
52
|
+
* const isBinary = isContentTypeBinary(headers, [new RegExp('^image/.*$')]);
|
|
53
|
+
* console.log(isBinary);
|
|
54
|
+
* // true
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @param headers The headers of the response
|
|
58
|
+
* @param binaryContentTypes The list of content types that will be treated as binary
|
|
59
|
+
*/
|
|
60
|
+
function isContentTypeBinary(headers, binaryContentTypes) {
|
|
61
|
+
const binaryContentTypesRegexes = binaryContentTypes.map(binaryContentType => binaryContentType instanceof RegExp
|
|
62
|
+
? binaryContentType
|
|
63
|
+
: new RegExp(`${binaryContentType}`));
|
|
64
|
+
const contentType = getContentType(headers);
|
|
65
|
+
if (!contentType)
|
|
66
|
+
return false;
|
|
67
|
+
return binaryContentTypesRegexes.some(binaryContentType => binaryContentType.test(contentType));
|
|
68
|
+
}
|
|
69
|
+
exports.isContentTypeBinary = isContentTypeBinary;
|
|
70
|
+
/**
|
|
71
|
+
* The function used to determine from the headers and the binary settings if a response should be encoded or not
|
|
72
|
+
*
|
|
73
|
+
* @example```typescript
|
|
74
|
+
* const headers = { 'Content-Type': 'image/png', 'Content-Encoding': 'gzip' };
|
|
75
|
+
* const isContentBinary = isBinary(headers, { contentEncodings: ['gzip'], contentTypes: [new RegExp('^image/.*$')] });
|
|
76
|
+
* console.log(isContentBinary);
|
|
77
|
+
* // true
|
|
78
|
+
*
|
|
79
|
+
* @param headers The headers of the response
|
|
80
|
+
* @param binarySettings The settings for the validation
|
|
81
|
+
*/
|
|
82
|
+
function isBinary(headers, binarySettings) {
|
|
83
|
+
if ('isBinary' in binarySettings) {
|
|
84
|
+
if (binarySettings.isBinary === false)
|
|
85
|
+
return false;
|
|
86
|
+
return binarySettings.isBinary(headers);
|
|
87
|
+
}
|
|
88
|
+
return (isContentEncodingBinary(headers, binarySettings.contentEncodings) ||
|
|
89
|
+
isContentTypeBinary(headers, binarySettings.contentTypes));
|
|
90
|
+
}
|
|
91
|
+
exports.isBinary = isBinary;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The type representing the possible log levels to choose from.
|
|
3
|
+
*/
|
|
4
|
+
export declare type LogLevels = 'debug' | 'verbose' | 'info' | 'warn' | 'error' | 'none';
|
|
5
|
+
/**
|
|
6
|
+
* The options to customize {@link ILogger}
|
|
7
|
+
*/
|
|
8
|
+
export declare type LoggerOptions = {
|
|
9
|
+
/**
|
|
10
|
+
* Select the log level, {@link LogLevels see more}.
|
|
11
|
+
*
|
|
12
|
+
* @default error
|
|
13
|
+
*/
|
|
14
|
+
level: LogLevels;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* The log function used in any level.
|
|
18
|
+
*/
|
|
19
|
+
export declare type LoggerFN = (message: any, ...additional: any[]) => void;
|
|
20
|
+
/**
|
|
21
|
+
* The interface representing the logger, you can provide a custom logger by implementing this interface.
|
|
22
|
+
*/
|
|
23
|
+
export declare type ILogger = Record<Exclude<LogLevels, 'none'>, LoggerFN>;
|
|
24
|
+
/**
|
|
25
|
+
* The method used to create a simple logger instance to use in this library.
|
|
26
|
+
*
|
|
27
|
+
* @note Behind the scenes, this simple logger sends the message to the `console` methods.
|
|
28
|
+
*
|
|
29
|
+
* @example```typescript
|
|
30
|
+
* const logger = createDefaultLogger();
|
|
31
|
+
*
|
|
32
|
+
* logger.error('An error happens.');
|
|
33
|
+
* // An error happens.
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @param level Select the level of the log
|
|
37
|
+
*/
|
|
38
|
+
export declare function createDefaultLogger({ level }?: LoggerOptions): ILogger;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDefaultLogger = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* The method used to create a simple logger instance to use in this library.
|
|
6
|
+
*
|
|
7
|
+
* @note Behind the scenes, this simple logger sends the message to the `console` methods.
|
|
8
|
+
*
|
|
9
|
+
* @example```typescript
|
|
10
|
+
* const logger = createDefaultLogger();
|
|
11
|
+
*
|
|
12
|
+
* logger.error('An error happens.');
|
|
13
|
+
* // An error happens.
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @param level Select the level of the log
|
|
17
|
+
*/
|
|
18
|
+
function createDefaultLogger({ level } = { level: 'error' }) {
|
|
19
|
+
const errorLogLevel = ['debug', 'verbose', 'info', 'warn', 'error'];
|
|
20
|
+
const warnLogLevel = ['debug', 'verbose', 'info', 'warn'];
|
|
21
|
+
const infoLogLevel = ['debug', 'verbose', 'info'];
|
|
22
|
+
const verboseLogLevel = ['debug', 'verbose'];
|
|
23
|
+
return {
|
|
24
|
+
error: (message, ...additional) => {
|
|
25
|
+
if (!errorLogLevel.includes(level))
|
|
26
|
+
return;
|
|
27
|
+
console.error(message, ...additional);
|
|
28
|
+
},
|
|
29
|
+
warn: (message, ...additional) => {
|
|
30
|
+
if (!warnLogLevel.includes(level))
|
|
31
|
+
return;
|
|
32
|
+
console.warn(message, ...additional);
|
|
33
|
+
},
|
|
34
|
+
info: (message, ...additional) => {
|
|
35
|
+
if (!infoLogLevel.includes(level))
|
|
36
|
+
return;
|
|
37
|
+
console.info(message, ...additional);
|
|
38
|
+
},
|
|
39
|
+
verbose: (message, ...additional) => {
|
|
40
|
+
if (!verboseLogLevel.includes(level))
|
|
41
|
+
return;
|
|
42
|
+
console.debug(message, ...additional);
|
|
43
|
+
},
|
|
44
|
+
debug: (message, ...additional) => {
|
|
45
|
+
if (level !== 'debug')
|
|
46
|
+
return;
|
|
47
|
+
console.debug(message, ...additional);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
exports.createDefaultLogger = createDefaultLogger;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NO_OP = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* No operation function is used when we need to pass a function, but we don't want to specify any behavior.
|
|
6
|
+
*/
|
|
7
|
+
const NO_OP = () => void 0;
|
|
8
|
+
exports.NO_OP = NO_OP;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Return the defaultValue whether the value is undefined, otherwise, return the value.
|
|
3
|
+
*
|
|
4
|
+
* @example```typescript
|
|
5
|
+
* const value1 = getDefaultIfUndefined(undefined, true);
|
|
6
|
+
* const value2 = getDefaultIfUndefined(false, true);
|
|
7
|
+
*
|
|
8
|
+
* console.log(value1);
|
|
9
|
+
* // true
|
|
10
|
+
* console.log(value2);
|
|
11
|
+
* // false
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @param value The value to be checked
|
|
15
|
+
* @param defaultValue The default value when value is undefined
|
|
16
|
+
*/
|
|
17
|
+
export declare function getDefaultIfUndefined<T>(value: T | undefined, defaultValue: T): T;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDefaultIfUndefined = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Return the defaultValue whether the value is undefined, otherwise, return the value.
|
|
6
|
+
*
|
|
7
|
+
* @example```typescript
|
|
8
|
+
* const value1 = getDefaultIfUndefined(undefined, true);
|
|
9
|
+
* const value2 = getDefaultIfUndefined(false, true);
|
|
10
|
+
*
|
|
11
|
+
* console.log(value1);
|
|
12
|
+
* // true
|
|
13
|
+
* console.log(value2);
|
|
14
|
+
* // false
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @param value The value to be checked
|
|
18
|
+
* @param defaultValue The default value when value is undefined
|
|
19
|
+
*/
|
|
20
|
+
function getDefaultIfUndefined(value, defaultValue) {
|
|
21
|
+
if (typeof value === 'undefined')
|
|
22
|
+
return defaultValue;
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
exports.getDefaultIfUndefined = getDefaultIfUndefined;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transform the path and a map of query params to a string with formatted query params
|
|
3
|
+
*
|
|
4
|
+
* @example```typescript
|
|
5
|
+
* const path = '/pets/search';
|
|
6
|
+
* const queryParams = { batata: undefined, petType: [ 'dog', 'fish' ] };
|
|
7
|
+
* const result = getPathWithQueryStringParams(path, queryParams);
|
|
8
|
+
* console.log(result);
|
|
9
|
+
* // /pets/search?batata=&petType=dog&petType=fish
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* @param path The path
|
|
13
|
+
* @param queryParams The query params
|
|
14
|
+
*/
|
|
15
|
+
export declare function getPathWithQueryStringParams(path: string, queryParams: string | Record<string, string | string[] | undefined> | undefined | null): string;
|
|
16
|
+
/**
|
|
17
|
+
* Map query params to a string with formatted query params
|
|
18
|
+
*
|
|
19
|
+
* @example```typescript
|
|
20
|
+
* const queryParams = { batata: undefined, petType: [ 'dog', 'fish' ] };
|
|
21
|
+
* const result = getQueryParamsStringFromRecord(queryParams);
|
|
22
|
+
* console.log(result);
|
|
23
|
+
* // batata=&petType=dog&petType=fish
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @param queryParamsRecord The query params record
|
|
27
|
+
*/
|
|
28
|
+
export declare function getQueryParamsStringFromRecord(queryParamsRecord: Record<string, string | string[] | undefined> | undefined | null): string;
|
package/lib/core/path.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getQueryParamsStringFromRecord = exports.getPathWithQueryStringParams = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Transform the path and a map of query params to a string with formatted query params
|
|
6
|
+
*
|
|
7
|
+
* @example```typescript
|
|
8
|
+
* const path = '/pets/search';
|
|
9
|
+
* const queryParams = { batata: undefined, petType: [ 'dog', 'fish' ] };
|
|
10
|
+
* const result = getPathWithQueryStringParams(path, queryParams);
|
|
11
|
+
* console.log(result);
|
|
12
|
+
* // /pets/search?batata=&petType=dog&petType=fish
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* @param path The path
|
|
16
|
+
* @param queryParams The query params
|
|
17
|
+
*/
|
|
18
|
+
function getPathWithQueryStringParams(path, queryParams) {
|
|
19
|
+
if (String(queryParams || '').length === 0)
|
|
20
|
+
return path;
|
|
21
|
+
if (typeof queryParams === 'string')
|
|
22
|
+
return `${path}?${queryParams}`;
|
|
23
|
+
const queryParamsString = getQueryParamsStringFromRecord(queryParams);
|
|
24
|
+
if (!queryParamsString)
|
|
25
|
+
return path;
|
|
26
|
+
return `${path}?${queryParamsString}`;
|
|
27
|
+
}
|
|
28
|
+
exports.getPathWithQueryStringParams = getPathWithQueryStringParams;
|
|
29
|
+
/**
|
|
30
|
+
* Map query params to a string with formatted query params
|
|
31
|
+
*
|
|
32
|
+
* @example```typescript
|
|
33
|
+
* const queryParams = { batata: undefined, petType: [ 'dog', 'fish' ] };
|
|
34
|
+
* const result = getQueryParamsStringFromRecord(queryParams);
|
|
35
|
+
* console.log(result);
|
|
36
|
+
* // batata=&petType=dog&petType=fish
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @param queryParamsRecord The query params record
|
|
40
|
+
*/
|
|
41
|
+
function getQueryParamsStringFromRecord(queryParamsRecord) {
|
|
42
|
+
const searchParams = new URLSearchParams();
|
|
43
|
+
const multiValueHeadersEntries = Object.entries(queryParamsRecord || {});
|
|
44
|
+
if (multiValueHeadersEntries.length === 0)
|
|
45
|
+
return '';
|
|
46
|
+
for (const [key, value] of multiValueHeadersEntries) {
|
|
47
|
+
if (!Array.isArray(value)) {
|
|
48
|
+
searchParams.append(key, value || '');
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
for (const arrayValue of value)
|
|
52
|
+
searchParams.append(key, arrayValue);
|
|
53
|
+
}
|
|
54
|
+
return searchParams.toString();
|
|
55
|
+
}
|
|
56
|
+
exports.getQueryParamsStringFromRecord = getQueryParamsStringFromRecord;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Readable, Writable } from 'stream';
|
|
3
|
+
/**
|
|
4
|
+
* Wait asynchronous the stream to complete
|
|
5
|
+
*
|
|
6
|
+
* @param stream The stream
|
|
7
|
+
*/
|
|
8
|
+
export declare function waitForStreamComplete<TStream extends Readable | Writable>(stream: TStream): Promise<TStream>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.waitForStreamComplete = void 0;
|
|
5
|
+
//#endregion
|
|
6
|
+
/**
|
|
7
|
+
* Wait asynchronous the stream to complete
|
|
8
|
+
*
|
|
9
|
+
* @param stream The stream
|
|
10
|
+
*/
|
|
11
|
+
function waitForStreamComplete(stream) {
|
|
12
|
+
if ('readableEnded' in stream && stream.readableEnded)
|
|
13
|
+
return Promise.resolve(stream);
|
|
14
|
+
if ('writableEnded' in stream && stream.writableEnded)
|
|
15
|
+
return Promise.resolve(stream);
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
// Reading the {@link https://github.com/nodejs/node/blob/v12.22.9/lib/events.js#L262 emit source code},
|
|
18
|
+
// it's almost impossible to complete being called twice because the emit function runs synchronously and removes the other listeners,
|
|
19
|
+
// but I'll leave it at that because I didn't write that code, so I couldn't figure out what the author thought when he wrote this.
|
|
20
|
+
let isComplete = false;
|
|
21
|
+
function complete(err) {
|
|
22
|
+
/* istanbul ignore next */
|
|
23
|
+
if (isComplete)
|
|
24
|
+
return;
|
|
25
|
+
isComplete = true;
|
|
26
|
+
stream.removeListener('error', complete);
|
|
27
|
+
stream.removeListener('end', complete);
|
|
28
|
+
stream.removeListener('finish', complete);
|
|
29
|
+
if (err)
|
|
30
|
+
reject(err);
|
|
31
|
+
else
|
|
32
|
+
resolve(stream);
|
|
33
|
+
}
|
|
34
|
+
stream.once('error', complete);
|
|
35
|
+
stream.once('end', complete);
|
|
36
|
+
stream.once('finish', complete);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
exports.waitForStreamComplete = waitForStreamComplete;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
3
|
+
import type { Express } from 'express';
|
|
4
|
+
import { FrameworkContract } from '../contracts';
|
|
5
|
+
/**
|
|
6
|
+
* The framework that forwards requests to express handler
|
|
7
|
+
*/
|
|
8
|
+
export declare class ExpressFramework implements FrameworkContract<Express> {
|
|
9
|
+
/**
|
|
10
|
+
* @inheritDoc
|
|
11
|
+
*/
|
|
12
|
+
sendRequest(app: Express, request: IncomingMessage, response: ServerResponse): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.ExpressFramework = void 0;
|
|
5
|
+
//#endregion
|
|
6
|
+
/**
|
|
7
|
+
* The framework that forwards requests to express handler
|
|
8
|
+
*/
|
|
9
|
+
class ExpressFramework {
|
|
10
|
+
/**
|
|
11
|
+
* @inheritDoc
|
|
12
|
+
*/
|
|
13
|
+
sendRequest(app, request, response) {
|
|
14
|
+
app(request, response);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.ExpressFramework = ExpressFramework;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
3
|
+
import type { FastifyInstance } from 'fastify';
|
|
4
|
+
import { FrameworkContract } from '../contracts';
|
|
5
|
+
/**
|
|
6
|
+
* The framework that forwards requests to fastify handler
|
|
7
|
+
*/
|
|
8
|
+
export declare class FastifyFramework implements FrameworkContract<FastifyInstance> {
|
|
9
|
+
/**
|
|
10
|
+
* @inheritDoc
|
|
11
|
+
*/
|
|
12
|
+
sendRequest(app: FastifyInstance, request: IncomingMessage, response: ServerResponse): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.FastifyFramework = void 0;
|
|
5
|
+
//#endregion
|
|
6
|
+
/**
|
|
7
|
+
* The framework that forwards requests to fastify handler
|
|
8
|
+
*/
|
|
9
|
+
class FastifyFramework {
|
|
10
|
+
/**
|
|
11
|
+
* @inheritDoc
|
|
12
|
+
*/
|
|
13
|
+
sendRequest(app, request, response) {
|
|
14
|
+
// ref: https://www.fastify.io/docs/latest/Guides/Serverless/#implement-and-export-the-function
|
|
15
|
+
app.ready().then(() => app.server.emit('request', request, response));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.FastifyFramework = FastifyFramework;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
3
|
+
import type { Server } from 'hapi';
|
|
4
|
+
import { FrameworkContract } from '../contracts';
|
|
5
|
+
/**
|
|
6
|
+
* The framework that forwards requests to hapi handler
|
|
7
|
+
*/
|
|
8
|
+
export declare class HapiFramework implements FrameworkContract<Server> {
|
|
9
|
+
/**
|
|
10
|
+
* @inheritDoc
|
|
11
|
+
*/
|
|
12
|
+
sendRequest(app: Server, request: IncomingMessage, response: ServerResponse): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.HapiFramework = void 0;
|
|
5
|
+
//#endregion
|
|
6
|
+
/**
|
|
7
|
+
* The framework that forwards requests to hapi handler
|
|
8
|
+
*/
|
|
9
|
+
class HapiFramework {
|
|
10
|
+
/**
|
|
11
|
+
* @inheritDoc
|
|
12
|
+
*/
|
|
13
|
+
sendRequest(app, request, response) {
|
|
14
|
+
const httpServer = app.listener;
|
|
15
|
+
httpServer._events.request(request, response);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.HapiFramework = HapiFramework;
|
|
@@ -0,0 +1,16 @@
|
|
|
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("./express.framework"), exports);
|
|
14
|
+
__exportStar(require("./fastify.framework"), exports);
|
|
15
|
+
__exportStar(require("./hapi.framework"), exports);
|
|
16
|
+
__exportStar(require("./koa.framework"), exports);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
3
|
+
import type Application from 'koa';
|
|
4
|
+
import { FrameworkContract } from '../contracts';
|
|
5
|
+
/**
|
|
6
|
+
* The framework that forwards requests to koa handler
|
|
7
|
+
*/
|
|
8
|
+
export declare class KoaFramework implements FrameworkContract<Application> {
|
|
9
|
+
/**
|
|
10
|
+
* @inheritDoc
|
|
11
|
+
*/
|
|
12
|
+
sendRequest(app: Application, request: IncomingMessage, response: ServerResponse): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region Imports
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.KoaFramework = void 0;
|
|
5
|
+
//#endregion
|
|
6
|
+
/**
|
|
7
|
+
* The framework that forwards requests to koa handler
|
|
8
|
+
*/
|
|
9
|
+
class KoaFramework {
|
|
10
|
+
/**
|
|
11
|
+
* @inheritDoc
|
|
12
|
+
*/
|
|
13
|
+
sendRequest(app, request, response) {
|
|
14
|
+
app.callback()(request, response);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.KoaFramework = KoaFramework;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { BinarySettings } from '../../@types';
|
|
2
|
+
import { AdapterContract, AdapterRequest, FrameworkContract, HandlerContract, ResolverContract, ServerlessHandler } from '../../contracts';
|
|
3
|
+
import { ILogger } from '../../core';
|
|
4
|
+
import { ServerlessRequest, ServerlessResponse } from '../../network';
|
|
5
|
+
/**
|
|
6
|
+
* The abstract class that represents the base class for a handler
|
|
7
|
+
*/
|
|
8
|
+
export declare abstract class BaseHandler<TApp, TEvent, TContext, TCallback, TResponse, TReturn> implements HandlerContract<TApp, TEvent, TContext, TCallback, TResponse, TReturn> {
|
|
9
|
+
/**
|
|
10
|
+
* Get the handler that will handle serverless requests
|
|
11
|
+
*/
|
|
12
|
+
abstract getHandler(app: TApp, framework: FrameworkContract<TApp>, adapters: AdapterContract<TEvent, TContext, TResponse>[], resolverFactory: ResolverContract<TEvent, TContext, TCallback, TResponse, TReturn>, binarySettings: BinarySettings, respondWithErrors: boolean, log: ILogger): ServerlessHandler<TReturn>;
|
|
13
|
+
/**
|
|
14
|
+
* Get the adapter to handle a specific event and context
|
|
15
|
+
*
|
|
16
|
+
* @param event The event sent by serverless
|
|
17
|
+
* @param context The context sent by serverless
|
|
18
|
+
* @param adapters The list of adapters
|
|
19
|
+
* @param log The instance of logger
|
|
20
|
+
*/
|
|
21
|
+
protected getAdapterByEventAndContext(event: TEvent, context: TContext, adapters: AdapterContract<TEvent, TContext, TResponse>[], log: ILogger): AdapterContract<TEvent, TContext, TResponse>;
|
|
22
|
+
/**
|
|
23
|
+
* Get serverless request and response frmo the adapter request
|
|
24
|
+
*
|
|
25
|
+
* @param requestValues The request values from adapter
|
|
26
|
+
*/
|
|
27
|
+
protected getServerlessRequestResponseFromAdapterRequest(requestValues: AdapterRequest): [request: ServerlessRequest, response: ServerlessResponse];
|
|
28
|
+
}
|