@creator.co/wapi 1.2.1-beta6 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +29 -22
- package/.github/workflows/npmpublish.yml +11 -19
- package/.github/workflows/prs.yml +13 -0
- package/index.ts +12 -10
- package/jest.config.ts +39 -0
- package/package.json +15 -4
- package/src/API/Request.ts +136 -44
- package/src/API/Response.ts +256 -46
- package/src/API/Utils.ts +60 -7
- package/src/BaseEvent/EventProcessor.ts +93 -28
- package/src/BaseEvent/Process.ts +69 -13
- package/src/BaseEvent/Transaction.ts +29 -50
- package/src/Config/Configuration.ts +119 -19
- package/src/Config/EnvironmentVar.ts +100 -21
- package/src/Crypto/Crypto.ts +78 -19
- package/src/Crypto/JWT.ts +53 -13
- package/src/Globals.ts +159 -27
- package/src/Logger/Logger.ts +204 -65
- package/src/Mailer/Mailer.ts +114 -31
- package/src/Publisher/Publisher.ts +57 -16
- package/src/Server/RouteResolver.ts +141 -0
- package/src/Server/Router.ts +84 -12
- package/src/Server/lib/ContainerServer.ts +53 -6
- package/src/Server/lib/Server.ts +82 -54
- package/src/Server/lib/container/GenericHandler.ts +15 -18
- package/src/Server/lib/container/GenericHandlerEvent.ts +78 -50
- package/src/Server/lib/container/HealthHandler.ts +2 -2
- package/src/Server/lib/container/Proxy.ts +114 -45
- package/src/Server/lib/container/Utils.ts +18 -27
- package/src/Validation/Validator.ts +23 -7
- package/tests/API/Request.test.ts +259 -0
- package/tests/API/Response.test.ts +367 -0
- package/tests/API/Utils.test.ts +157 -0
- package/tests/BaseEvent/EventProcessor.test.ts +262 -0
- package/tests/BaseEvent/Process.test.ts +49 -0
- package/tests/BaseEvent/Transaction.test.ts +222 -0
- package/tests/Config/Config.test.ts +193 -0
- package/tests/Config/EnvironmentVar.test.ts +214 -0
- package/tests/Crypto/Crypto.test.ts +88 -0
- package/tests/Crypto/JWT.test.ts +92 -0
- package/tests/Logger/Logger.test.ts +96 -0
- package/tests/Mailer/Mailer.test.ts +59 -0
- package/tests/Publisher/Publisher.test.ts +60 -0
- package/tests/Server/RouteResolver.test.ts +103 -0
- package/tests/Server/Router.test.ts +38 -0
- package/tests/Server/lib/ContainerServer.test.ts +327 -0
- package/tests/Server/lib/Server.test.ts +12 -0
- package/tests/Server/lib/container/GenericHandler.test.ts +131 -0
- package/tests/Server/lib/container/GenericHandlerEvent.test.ts +102 -0
- package/tests/Server/lib/container/HealthHandler.test.ts +30 -0
- package/tests/Server/lib/container/Proxy.test.ts +265 -0
- package/tests/Server/lib/container/Utils.test.ts +47 -0
- package/tests/Test.utils.ts +95 -0
- package/tests/Validation/Validator.test.ts +76 -0
- package/tests/main.test.ts +15 -0
- package/tsconfig.json +1 -0
- package/dist/index.d.ts +0 -11
- package/dist/index.js +0 -24
- package/dist/index.js.map +0 -1
- package/dist/package.json +0 -53
- package/dist/src/API/Request.d.ts +0 -21
- package/dist/src/API/Request.js +0 -86
- package/dist/src/API/Request.js.map +0 -1
- package/dist/src/API/Response.d.ts +0 -39
- package/dist/src/API/Response.js +0 -232
- package/dist/src/API/Response.js.map +0 -1
- package/dist/src/API/Utils.d.ts +0 -8
- package/dist/src/API/Utils.js +0 -49
- package/dist/src/API/Utils.js.map +0 -1
- package/dist/src/BaseEvent/EventProcessor.d.ts +0 -13
- package/dist/src/BaseEvent/EventProcessor.js +0 -151
- package/dist/src/BaseEvent/EventProcessor.js.map +0 -1
- package/dist/src/BaseEvent/Process.d.ts +0 -12
- package/dist/src/BaseEvent/Process.js +0 -114
- package/dist/src/BaseEvent/Process.js.map +0 -1
- package/dist/src/BaseEvent/Transaction.d.ts +0 -29
- package/dist/src/BaseEvent/Transaction.js +0 -248
- package/dist/src/BaseEvent/Transaction.js.map +0 -1
- package/dist/src/Config/Configuration.d.ts +0 -34
- package/dist/src/Config/Configuration.js +0 -93
- package/dist/src/Config/Configuration.js.map +0 -1
- package/dist/src/Config/EnvironmentVar.d.ts +0 -17
- package/dist/src/Config/EnvironmentVar.js +0 -152
- package/dist/src/Config/EnvironmentVar.js.map +0 -1
- package/dist/src/Crypto/Crypto.d.ts +0 -8
- package/dist/src/Crypto/Crypto.js +0 -84
- package/dist/src/Crypto/Crypto.js.map +0 -1
- package/dist/src/Crypto/JWT.d.ts +0 -16
- package/dist/src/Crypto/JWT.js +0 -49
- package/dist/src/Crypto/JWT.js.map +0 -1
- package/dist/src/Globals.d.ts +0 -21
- package/dist/src/Globals.js +0 -35
- package/dist/src/Globals.js.map +0 -1
- package/dist/src/Logger/Logger.d.ts +0 -34
- package/dist/src/Logger/Logger.js +0 -345
- package/dist/src/Logger/Logger.js.map +0 -1
- package/dist/src/Mailer/Mailer.d.ts +0 -12
- package/dist/src/Mailer/Mailer.js +0 -234
- package/dist/src/Mailer/Mailer.js.map +0 -1
- package/dist/src/Publisher/Publisher.d.ts +0 -10
- package/dist/src/Publisher/Publisher.js +0 -109
- package/dist/src/Publisher/Publisher.js.map +0 -1
- package/dist/src/Server/Router.d.ts +0 -27
- package/dist/src/Server/Router.js +0 -22
- package/dist/src/Server/Router.js.map +0 -1
- package/dist/src/Server/lib/ContainerServer.d.ts +0 -11
- package/dist/src/Server/lib/ContainerServer.js +0 -103
- package/dist/src/Server/lib/ContainerServer.js.map +0 -1
- package/dist/src/Server/lib/Server.d.ts +0 -9
- package/dist/src/Server/lib/Server.js +0 -141
- package/dist/src/Server/lib/Server.js.map +0 -1
- package/dist/src/Server/lib/container/GenericHandler.d.ts +0 -4
- package/dist/src/Server/lib/container/GenericHandler.js +0 -136
- package/dist/src/Server/lib/container/GenericHandler.js.map +0 -1
- package/dist/src/Server/lib/container/GenericHandlerEvent.d.ts +0 -14
- package/dist/src/Server/lib/container/GenericHandlerEvent.js +0 -164
- package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +0 -1
- package/dist/src/Server/lib/container/HealthHandler.d.ts +0 -3
- package/dist/src/Server/lib/container/HealthHandler.js +0 -44
- package/dist/src/Server/lib/container/HealthHandler.js.map +0 -1
- package/dist/src/Server/lib/container/Proxy.d.ts +0 -15
- package/dist/src/Server/lib/container/Proxy.js +0 -157
- package/dist/src/Server/lib/container/Proxy.js.map +0 -1
- package/dist/src/Server/lib/container/Utils.d.ts +0 -6
- package/dist/src/Server/lib/container/Utils.js +0 -109
- package/dist/src/Server/lib/container/Utils.js.map +0 -1
- package/dist/src/Validation/Validator.d.ts +0 -5
- package/dist/src/Validation/Validator.js +0 -31
- package/dist/src/Validation/Validator.js.map +0 -1
|
@@ -1,41 +1,68 @@
|
|
|
1
|
-
import type { APIGatewayProxyEvent, Context } from
|
|
2
|
-
import * as cuid from
|
|
3
|
-
import { Request } from
|
|
4
|
-
import * as unflatten from "unflatten"
|
|
1
|
+
import type { APIGatewayProxyEvent, Context } from 'aws-lambda'
|
|
2
|
+
import * as cuid from 'cuid'
|
|
3
|
+
import { Request } from 'express'
|
|
5
4
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
parseQueryStringParameters,
|
|
10
|
-
nullIfEmpty,
|
|
11
|
-
} from "./Utils"
|
|
12
|
-
import Globals from "../../../Globals"
|
|
13
|
-
import Server from "../Server"
|
|
5
|
+
import { parseMultiValueQueryStringParameters, parseQueryStringParameters } from './Utils'
|
|
6
|
+
import Globals from '../../../Globals'
|
|
7
|
+
import Server from '../Server'
|
|
14
8
|
//
|
|
9
|
+
/**
|
|
10
|
+
* ${1:Description placeholder}
|
|
11
|
+
*
|
|
12
|
+
* @export
|
|
13
|
+
* @typedef {GenericHandlerEventResponse}
|
|
14
|
+
*/
|
|
15
15
|
export type GenericHandlerEventResponse = { err?: Error | string; data?: any }
|
|
16
16
|
//
|
|
17
|
+
/**
|
|
18
|
+
* ${1:Description placeholder}
|
|
19
|
+
*
|
|
20
|
+
* @export
|
|
21
|
+
* @class GenericHandlerEvent
|
|
22
|
+
* @typedef {GenericHandlerEvent}
|
|
23
|
+
*/
|
|
17
24
|
export default class GenericHandlerEvent {
|
|
25
|
+
/**
|
|
26
|
+
* ${1:Description placeholder}
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
* @type {Request}
|
|
30
|
+
*/
|
|
18
31
|
public request: Request
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
32
|
+
/**
|
|
33
|
+
* ${1:Description placeholder}
|
|
34
|
+
*
|
|
35
|
+
* @public
|
|
36
|
+
* @type {Server["handleServerlessEvent"]}
|
|
37
|
+
*/
|
|
38
|
+
public serverlessHandler: Server['handleServerlessEvent']
|
|
39
|
+
/**
|
|
40
|
+
* Creates an instance of GenericHandlerEvent.
|
|
41
|
+
*
|
|
42
|
+
* @constructor
|
|
43
|
+
* @param {Request} request
|
|
44
|
+
* @param {Server["handleServerlessEvent"]} serverlessHandler
|
|
45
|
+
*/
|
|
46
|
+
constructor(request: Request, serverlessHandler: Server['handleServerlessEvent']) {
|
|
24
47
|
this.request = request
|
|
25
48
|
this.serverlessHandler = serverlessHandler
|
|
26
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* ${1:Description placeholder}
|
|
52
|
+
*
|
|
53
|
+
* @public
|
|
54
|
+
* @async
|
|
55
|
+
* @returns {Promise<GenericHandlerEventResponse>}
|
|
56
|
+
*/
|
|
27
57
|
public async invoke(): Promise<GenericHandlerEventResponse> {
|
|
28
58
|
// eslint-disable-next-line no-async-promise-executor
|
|
29
59
|
return new Promise(async (resolve, reject) => {
|
|
30
60
|
try {
|
|
31
61
|
// Build event and context
|
|
32
62
|
const event = this.buildEvent()
|
|
33
|
-
const context = this.buildContext(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
resolve({ err, data })
|
|
37
|
-
},
|
|
38
|
-
)
|
|
63
|
+
const context = this.buildContext(event, (err?: Error | string, data?: any) => {
|
|
64
|
+
resolve({ err, data })
|
|
65
|
+
})
|
|
39
66
|
// Invoke
|
|
40
67
|
await this.serverlessHandler(event, context)
|
|
41
68
|
} catch (e) {
|
|
@@ -44,24 +71,22 @@ export default class GenericHandlerEvent {
|
|
|
44
71
|
})
|
|
45
72
|
}
|
|
46
73
|
/* private */
|
|
74
|
+
/**
|
|
75
|
+
* ${1:Description placeholder}
|
|
76
|
+
*
|
|
77
|
+
* @private
|
|
78
|
+
* @returns {APIGatewayProxyEvent}
|
|
79
|
+
*/
|
|
47
80
|
private buildEvent(): APIGatewayProxyEvent {
|
|
48
81
|
return {
|
|
49
82
|
body: this.request.body || null, //enforce key
|
|
50
|
-
headers: this.request.headers
|
|
51
|
-
httpMethod: this.request.method
|
|
52
|
-
? this.request.method.toUpperCase()
|
|
53
|
-
: null,
|
|
83
|
+
headers: <any>(this.request.headers || {}),
|
|
84
|
+
httpMethod: this.request.method?.toUpperCase(),
|
|
54
85
|
isBase64Encoded: false,
|
|
55
|
-
multiValueHeaders:
|
|
56
|
-
|
|
57
|
-
),
|
|
58
|
-
multiValueQueryStringParameters: parseMultiValueQueryStringParameters(
|
|
59
|
-
this.request.url,
|
|
60
|
-
),
|
|
86
|
+
multiValueHeaders: <any>(this.request.headers || {}),
|
|
87
|
+
multiValueQueryStringParameters: parseMultiValueQueryStringParameters(this.request.url),
|
|
61
88
|
path: this.request.path,
|
|
62
|
-
pathParameters:
|
|
63
|
-
? nullIfEmpty(this.request.params)
|
|
64
|
-
: null,
|
|
89
|
+
pathParameters: null,
|
|
65
90
|
queryStringParameters: this.request.query
|
|
66
91
|
? parseQueryStringParameters(this.request.query)
|
|
67
92
|
: null,
|
|
@@ -72,9 +97,7 @@ export default class GenericHandlerEvent {
|
|
|
72
97
|
domainName: null,
|
|
73
98
|
domainPrefix: null,
|
|
74
99
|
extendedRequestId: cuid(),
|
|
75
|
-
httpMethod: this.request.method
|
|
76
|
-
? this.request.method.toUpperCase()
|
|
77
|
-
: null,
|
|
100
|
+
httpMethod: this.request.method ? this.request.method.toUpperCase() : null,
|
|
78
101
|
identity: {
|
|
79
102
|
accessKey: null,
|
|
80
103
|
accountId: process.env.AWS_ACCOUNT_ID || null,
|
|
@@ -88,16 +111,13 @@ export default class GenericHandlerEvent {
|
|
|
88
111
|
cognitoIdentityPoolId: null,
|
|
89
112
|
principalOrgId: null,
|
|
90
113
|
sourceIp:
|
|
91
|
-
<string>this.request.headers?.[
|
|
92
|
-
this.request.socket.remoteAddress,
|
|
114
|
+
<string>this.request.headers?.['x-forwarded-for'] || this.request.socket?.remoteAddress,
|
|
93
115
|
user: null,
|
|
94
|
-
userAgent: this.request.headers
|
|
95
|
-
? this.request.headers["user-agent"]
|
|
96
|
-
: null,
|
|
116
|
+
userAgent: this.request.headers?.['user-agent'],
|
|
97
117
|
userArn: null,
|
|
98
118
|
},
|
|
99
119
|
path: this.request.path,
|
|
100
|
-
protocol:
|
|
120
|
+
protocol: 'HTTP/1.1',
|
|
101
121
|
requestId: `${cuid()}-${cuid()}`,
|
|
102
122
|
requestTime: new Date().toISOString(),
|
|
103
123
|
requestTimeEpoch: Date.now(),
|
|
@@ -109,9 +129,17 @@ export default class GenericHandlerEvent {
|
|
|
109
129
|
stageVariables: null,
|
|
110
130
|
}
|
|
111
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* ${1:Description placeholder}
|
|
134
|
+
*
|
|
135
|
+
* @private
|
|
136
|
+
* @param {APIGatewayProxyEvent} event
|
|
137
|
+
* @param {(err?: Error | string, data?: any) => void} callback
|
|
138
|
+
* @returns {Context}
|
|
139
|
+
*/
|
|
112
140
|
private buildContext(
|
|
113
141
|
event: APIGatewayProxyEvent,
|
|
114
|
-
callback: (err?: Error | string, data?: any) => void
|
|
142
|
+
callback: (err?: Error | string, data?: any) => void
|
|
115
143
|
): Context {
|
|
116
144
|
return {
|
|
117
145
|
awsRequestId: event.requestContext.requestId,
|
|
@@ -120,12 +148,12 @@ export default class GenericHandlerEvent {
|
|
|
120
148
|
return 0
|
|
121
149
|
},
|
|
122
150
|
done: (err, data) => callback(err, data),
|
|
123
|
-
fail:
|
|
124
|
-
succeed:
|
|
151
|
+
fail: err => callback(err),
|
|
152
|
+
succeed: res => callback(null, res),
|
|
125
153
|
functionName: null,
|
|
126
|
-
functionVersion:
|
|
154
|
+
functionVersion: 'LATEST',
|
|
127
155
|
invokedFunctionArn: null,
|
|
128
|
-
memoryLimitInMB:
|
|
156
|
+
memoryLimitInMB: '-1',
|
|
129
157
|
logGroupName: null,
|
|
130
158
|
logStreamName: null,
|
|
131
159
|
}
|
|
@@ -1,26 +1,70 @@
|
|
|
1
|
-
import { Server as HTTPServer, createServer } from
|
|
1
|
+
import { Server as HTTPServer, createServer } from 'http'
|
|
2
2
|
|
|
3
|
-
import * as cors from
|
|
4
|
-
import * as express from
|
|
3
|
+
import * as cors from 'cors'
|
|
4
|
+
import * as express from 'express'
|
|
5
5
|
|
|
6
|
-
import Server from
|
|
7
|
-
import GenericHandler from
|
|
8
|
-
import HealthHandler from
|
|
9
|
-
import { version as appVersion } from
|
|
10
|
-
import Utils from
|
|
11
|
-
import Globals from
|
|
12
|
-
import { RouterConfig } from
|
|
6
|
+
import Server from './../Server'
|
|
7
|
+
import GenericHandler from './GenericHandler'
|
|
8
|
+
import HealthHandler from './HealthHandler'
|
|
9
|
+
import { version as appVersion } from '../../../../package.json'
|
|
10
|
+
import Utils from '../../../API/Utils'
|
|
11
|
+
import Globals from '../../../Globals'
|
|
12
|
+
import { RouterConfig } from '../../Router'
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* ${1:Description placeholder}
|
|
16
|
+
*
|
|
17
|
+
* @export
|
|
18
|
+
* @class Proxy
|
|
19
|
+
* @typedef {Proxy}
|
|
20
|
+
*/
|
|
14
21
|
export default class Proxy {
|
|
22
|
+
/**
|
|
23
|
+
* ${1:Description placeholder}
|
|
24
|
+
*
|
|
25
|
+
* @private
|
|
26
|
+
* @type {boolean}
|
|
27
|
+
*/
|
|
15
28
|
private stopping: boolean
|
|
29
|
+
/**
|
|
30
|
+
* ${1:Description placeholder}
|
|
31
|
+
*
|
|
32
|
+
* @private
|
|
33
|
+
* @readonly
|
|
34
|
+
* @type {RouterConfig}
|
|
35
|
+
*/
|
|
16
36
|
private readonly config: RouterConfig
|
|
37
|
+
/**
|
|
38
|
+
* ${1:Description placeholder}
|
|
39
|
+
*
|
|
40
|
+
* @private
|
|
41
|
+
* @readonly
|
|
42
|
+
* @type {express.Express}
|
|
43
|
+
*/
|
|
17
44
|
private readonly app: express.Express
|
|
18
|
-
|
|
45
|
+
/**
|
|
46
|
+
* ${1:Description placeholder}
|
|
47
|
+
*
|
|
48
|
+
* @private
|
|
49
|
+
* @readonly
|
|
50
|
+
* @type {Server["handleServerlessEvent"]}
|
|
51
|
+
*/
|
|
52
|
+
private readonly serverlessHandler: Server['handleServerlessEvent']
|
|
53
|
+
/**
|
|
54
|
+
* ${1:Description placeholder}
|
|
55
|
+
*
|
|
56
|
+
* @private
|
|
57
|
+
* @type {HTTPServer}
|
|
58
|
+
*/
|
|
19
59
|
private listener: HTTPServer
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Creates an instance of Proxy.
|
|
62
|
+
*
|
|
63
|
+
* @constructor
|
|
64
|
+
* @param {RouterConfig} config
|
|
65
|
+
* @param {Server["handleServerlessEvent"]} serverlessHandler
|
|
66
|
+
*/
|
|
67
|
+
constructor(config: RouterConfig, serverlessHandler: Server['handleServerlessEvent']) {
|
|
24
68
|
this.stopping = false
|
|
25
69
|
this.config = config
|
|
26
70
|
this.serverlessHandler = serverlessHandler
|
|
@@ -28,20 +72,17 @@ export default class Proxy {
|
|
|
28
72
|
/* Opinionated Express configs */
|
|
29
73
|
this.app.use(express.json())
|
|
30
74
|
// apply cors config
|
|
31
|
-
const corsConfig =
|
|
32
|
-
this.config.cors || Utils.parseObjectNullIfEmpty(process.env.CORS)
|
|
75
|
+
const corsConfig = this.config.cors || Utils.parseObjectNullIfEmpty(process.env.CORS)
|
|
33
76
|
this.app.use(
|
|
34
77
|
cors(
|
|
35
78
|
corsConfig
|
|
36
79
|
? {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
credentials: !!corsConfig?.allowCredentials,
|
|
41
|
-
},
|
|
80
|
+
origin: corsConfig.origin,
|
|
81
|
+
allowedHeaders: corsConfig.headers,
|
|
82
|
+
credentials: !!corsConfig.allowCredentials,
|
|
42
83
|
}
|
|
43
|
-
: {}
|
|
44
|
-
)
|
|
84
|
+
: {}
|
|
85
|
+
)
|
|
45
86
|
)
|
|
46
87
|
|
|
47
88
|
// //This supposedly fix some 502 codes where nodejs socket would hang during
|
|
@@ -52,24 +93,42 @@ export default class Proxy {
|
|
|
52
93
|
// this.listener.listener.keepAliveTimeout = 120e3
|
|
53
94
|
// this.listener.listener.headersTimeout = 120e3
|
|
54
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* ${1:Description placeholder}
|
|
98
|
+
*
|
|
99
|
+
* @async
|
|
100
|
+
* @returns {*}
|
|
101
|
+
*/
|
|
55
102
|
async load() {
|
|
56
103
|
await this.startListeners()
|
|
57
104
|
this.installRoutes()
|
|
58
105
|
}
|
|
59
|
-
|
|
106
|
+
/**
|
|
107
|
+
* ${1:Description placeholder}
|
|
108
|
+
*
|
|
109
|
+
* @async
|
|
110
|
+
* @param {?*} [err]
|
|
111
|
+
* @returns {*}
|
|
112
|
+
*/
|
|
113
|
+
async unload(err?: any) {
|
|
60
114
|
await this.stopListeners(err)
|
|
61
115
|
}
|
|
62
116
|
/* lifecycle */
|
|
117
|
+
/**
|
|
118
|
+
* ${1:Description placeholder}
|
|
119
|
+
*
|
|
120
|
+
* @private
|
|
121
|
+
* @async
|
|
122
|
+
* @returns {Promise<void>}
|
|
123
|
+
*/
|
|
63
124
|
private async startListeners(): Promise<void> {
|
|
64
|
-
return new Promise(
|
|
125
|
+
return new Promise(resolve => {
|
|
65
126
|
const port = this.config.port || Globals.Listener_HTTP_DefaultPort
|
|
66
127
|
console.log(`[Proxy] - [STARTING] - v.${appVersion} - :${port}`)
|
|
67
128
|
// Create Server
|
|
68
129
|
this.listener = createServer(this.app)
|
|
69
130
|
// Set defaults
|
|
70
|
-
this.listener.setTimeout(
|
|
71
|
-
this.config.timeout || Globals.Listener_HTTP_DefaultTimeout,
|
|
72
|
-
)
|
|
131
|
+
this.listener.setTimeout(this.config.timeout || Globals.Listener_HTTP_DefaultTimeout)
|
|
73
132
|
// Start Server
|
|
74
133
|
this.listener.listen(port, () => {
|
|
75
134
|
console.log(`[Proxy] - [STARTED]`)
|
|
@@ -77,37 +136,47 @@ export default class Proxy {
|
|
|
77
136
|
})
|
|
78
137
|
})
|
|
79
138
|
}
|
|
80
|
-
|
|
139
|
+
/**
|
|
140
|
+
* ${1:Description placeholder}
|
|
141
|
+
*
|
|
142
|
+
* @private
|
|
143
|
+
* @async
|
|
144
|
+
* @param {?*} [err]
|
|
145
|
+
* @returns {unknown}
|
|
146
|
+
*/
|
|
147
|
+
private async stopListeners(err?: any) {
|
|
81
148
|
if (this.stopping) return
|
|
82
149
|
this.stopping = true
|
|
83
|
-
console.debug(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
150
|
+
console.debug('[Proxy] - [STOPPING]')
|
|
151
|
+
return new Promise(resolve => {
|
|
152
|
+
this.listener.close(_err => {
|
|
153
|
+
if (err || _err) console.log('[Proxy] - exit output:', err || _err)
|
|
154
|
+
console.log('[Proxy] - [STOPPED]')
|
|
155
|
+
process.exit(err || _err ? 1 : 0)
|
|
156
|
+
resolve(null)
|
|
157
|
+
})
|
|
88
158
|
})
|
|
89
159
|
}
|
|
90
160
|
/* routing */
|
|
161
|
+
/**
|
|
162
|
+
* ${1:Description placeholder}
|
|
163
|
+
*
|
|
164
|
+
* @private
|
|
165
|
+
*/
|
|
91
166
|
private installRoutes() {
|
|
92
167
|
//Health check route -- This is a bypass route to only check if
|
|
93
168
|
//runtime proxy is working and responding to calls.
|
|
94
169
|
console.log(
|
|
95
170
|
`[Proxy] - [HEALTH-ROUTE] - ${
|
|
96
|
-
this.config.healthCheckRoute ||
|
|
97
|
-
|
|
98
|
-
}`,
|
|
171
|
+
this.config.healthCheckRoute || Globals.Listener_HTTP_DefaultHealthCheckRoute
|
|
172
|
+
}`
|
|
99
173
|
)
|
|
100
174
|
this.app
|
|
101
|
-
.route(
|
|
102
|
-
this.config.healthCheckRoute ||
|
|
103
|
-
Globals.Listener_HTTP_DefaultHealthCheckRoute,
|
|
104
|
-
)
|
|
175
|
+
.route(this.config.healthCheckRoute || Globals.Listener_HTTP_DefaultHealthCheckRoute)
|
|
105
176
|
.get(HealthHandler)
|
|
106
177
|
//Main route -- We use a wildcard route because is not the job of the runtime and neither
|
|
107
178
|
//the task to deny/constrain routes that invoked this task; all the job is done by the
|
|
108
179
|
//load balancer and we just foward everything we have to the function.
|
|
109
|
-
this.app
|
|
110
|
-
.route(Globals.Listener_HTTP_ProxyRoute)
|
|
111
|
-
.all(GenericHandler(this.serverlessHandler))
|
|
180
|
+
this.app.route(Globals.Listener_HTTP_ProxyRoute).all(GenericHandler(this.serverlessHandler))
|
|
112
181
|
}
|
|
113
182
|
}
|
|
@@ -1,28 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
10
|
-
for (const key of Object.keys(unflattened)) {
|
|
11
|
-
const item = map.get(key)
|
|
12
|
-
if (item) item.push(unflattened[key])
|
|
13
|
-
else map.set(key, [unflattened[key]])
|
|
14
|
-
}
|
|
15
|
-
return Object.fromEntries(map)
|
|
16
|
-
}
|
|
17
|
-
// https://aws.amazon.com/blogs/compute/support-for-multi-value-parameters-in-amazon-api-gateway/
|
|
18
|
-
// [ [ 'petType', 'dog' ], [ 'petType', 'fish' ] ]
|
|
19
|
-
// => { petType: [ 'dog', 'fish' ] },
|
|
20
|
-
export function parseMultiValueQueryStringParameters(url) {
|
|
1
|
+
/**
|
|
2
|
+
* ${1:Description placeholder}
|
|
3
|
+
*
|
|
4
|
+
* @export
|
|
5
|
+
* @param {string} url
|
|
6
|
+
* @returns {*}
|
|
7
|
+
*/
|
|
8
|
+
export function parseMultiValueQueryStringParameters(url: string) {
|
|
21
9
|
// dummy placeholder url for the WHATWG URL constructor
|
|
22
10
|
// https://github.com/nodejs/node/issues/12682
|
|
23
|
-
const { searchParams } = new URL(url,
|
|
11
|
+
const { searchParams } = new URL(url, 'http://example')
|
|
24
12
|
//
|
|
25
|
-
if (Array.from(searchParams).length === 0) return
|
|
13
|
+
if (Array.from(searchParams).length === 0) return {}
|
|
26
14
|
const map = new Map()
|
|
27
15
|
// eslint-disable-next-line no-restricted-syntax
|
|
28
16
|
for (const [key, value] of searchParams) {
|
|
@@ -32,14 +20,17 @@ export function parseMultiValueQueryStringParameters(url) {
|
|
|
32
20
|
}
|
|
33
21
|
return Object.fromEntries(map)
|
|
34
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* ${1:Description placeholder}
|
|
25
|
+
*
|
|
26
|
+
* @export
|
|
27
|
+
* @param {*} url
|
|
28
|
+
* @returns {*}
|
|
29
|
+
*/
|
|
35
30
|
export function parseQueryStringParameters(url) {
|
|
36
31
|
// dummy placeholder url for the WHATWG URL constructor
|
|
37
32
|
// https://github.com/nodejs/node/issues/12682
|
|
38
|
-
const { searchParams } = new URL(url,
|
|
33
|
+
const { searchParams } = new URL(url, 'http://example')
|
|
39
34
|
if (Array.from(searchParams).length === 0) return null
|
|
40
35
|
return Object.fromEntries(searchParams)
|
|
41
36
|
}
|
|
42
|
-
//
|
|
43
|
-
export function nullIfEmpty(obj) {
|
|
44
|
-
return obj && (Object.keys(obj).length > 0 ? obj : null)
|
|
45
|
-
}
|
|
@@ -1,27 +1,43 @@
|
|
|
1
|
-
import { z } from
|
|
1
|
+
import { z } from 'zod'
|
|
2
2
|
|
|
3
|
-
import Response, { ResponseErrorType } from
|
|
4
|
-
import Globals from
|
|
3
|
+
import Response, { ResponseErrorType } from '../API/Response'
|
|
4
|
+
import Globals from '../Globals'
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Description placeholder
|
|
8
|
+
*
|
|
9
|
+
* @export
|
|
10
|
+
* @class Validator
|
|
11
|
+
* @typedef {Validator}
|
|
12
|
+
*/
|
|
6
13
|
export default class Validator {
|
|
14
|
+
/**
|
|
15
|
+
* Description placeholder
|
|
16
|
+
*
|
|
17
|
+
* @public
|
|
18
|
+
* @static
|
|
19
|
+
* @param {*} data
|
|
20
|
+
* @param {z.ZodObject<any>} schema
|
|
21
|
+
* @returns {(boolean | Response<ResponseErrorType>)}
|
|
22
|
+
*/
|
|
7
23
|
public static validateSchema(
|
|
8
24
|
data: any,
|
|
9
|
-
schema: z.ZodObject<any
|
|
25
|
+
schema: z.ZodObject<any>
|
|
10
26
|
): boolean | Response<ResponseErrorType> {
|
|
11
27
|
let error, validatedInput
|
|
12
28
|
// Validate body against known zod schema
|
|
13
29
|
try {
|
|
14
30
|
validatedInput = schema.parse(data) as typeof schema
|
|
15
31
|
} catch (err: z.ZodError | any) {
|
|
16
|
-
if (err.
|
|
17
|
-
else error =
|
|
32
|
+
if (err instanceof z.ZodError) error = JSON.parse(err.message)
|
|
33
|
+
else error = 'Unknown validation error!' //unhandled case, hard to test
|
|
18
34
|
}
|
|
19
35
|
// Error validation
|
|
20
36
|
if (!validatedInput || error) {
|
|
21
37
|
return Response.BadRequestResponse(
|
|
22
38
|
Globals.ErrorResponseValidationFail,
|
|
23
39
|
Globals.ErrorCode_InvalidInput,
|
|
24
|
-
{ validationFailure: error }
|
|
40
|
+
{ validationFailure: error }
|
|
25
41
|
)
|
|
26
42
|
} else {
|
|
27
43
|
return true
|