@creator.co/wapi 1.2.4 → 1.2.6
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/.github/workflows/npmpublish.yml +1 -1
- package/README.md +216 -5
- package/dist/index.d.ts +15 -0
- package/dist/index.js.map +1 -1
- package/dist/jest.config.js +1 -1
- package/dist/jest.config.js.map +1 -1
- package/dist/package.json +13 -2
- package/dist/src/API/Request.d.ts +45 -82
- package/dist/src/API/Request.js +49 -77
- package/dist/src/API/Request.js.map +1 -1
- package/dist/src/API/Response.d.ts +94 -163
- package/dist/src/API/Response.js +101 -161
- package/dist/src/API/Response.js.map +1 -1
- package/dist/src/API/Utils.d.ts +21 -42
- package/dist/src/API/Utils.js +22 -43
- package/dist/src/API/Utils.js.map +1 -1
- package/dist/src/BaseEvent/EventProcessor.d.ts +32 -55
- package/dist/src/BaseEvent/EventProcessor.js +30 -38
- package/dist/src/BaseEvent/EventProcessor.js.map +1 -1
- package/dist/src/BaseEvent/Process.d.ts +20 -43
- package/dist/src/BaseEvent/Process.js +16 -27
- package/dist/src/BaseEvent/Process.js.map +1 -1
- package/dist/src/BaseEvent/Transaction.d.ts +104 -2
- package/dist/src/BaseEvent/Transaction.js +196 -41
- package/dist/src/BaseEvent/Transaction.js.map +1 -1
- package/dist/src/Config/Configuration.d.ts +48 -66
- package/dist/src/Config/Configuration.js +25 -42
- package/dist/src/Config/Configuration.js.map +1 -1
- package/dist/src/Config/EnvironmentVar.d.ts +30 -57
- package/dist/src/Config/EnvironmentVar.js +28 -41
- package/dist/src/Config/EnvironmentVar.js.map +1 -1
- package/dist/src/Crypto/Crypto.d.ts +17 -35
- package/dist/src/Crypto/Crypto.js +12 -21
- package/dist/src/Crypto/Crypto.js.map +1 -1
- package/dist/src/Crypto/JWT.d.ts +21 -32
- package/dist/src/Crypto/JWT.js +14 -22
- package/dist/src/Crypto/JWT.js.map +1 -1
- package/dist/src/Database/Database.d.ts +18 -0
- package/dist/src/Database/Database.js +18 -0
- package/dist/src/Database/Database.js.map +1 -0
- package/dist/src/Database/DatabaseManager.d.ts +32 -0
- package/dist/src/Database/DatabaseManager.js +50 -0
- package/dist/src/Database/DatabaseManager.js.map +1 -0
- package/dist/src/Database/DatabaseTransaction.d.ts +65 -0
- package/dist/src/Database/DatabaseTransaction.js +183 -0
- package/dist/src/Database/DatabaseTransaction.js.map +1 -0
- package/dist/src/Database/integrations/knex/KnexDatabase.d.ts +22 -0
- package/dist/src/Database/integrations/knex/KnexDatabase.js +108 -0
- package/dist/src/Database/integrations/knex/KnexDatabase.js.map +1 -0
- package/dist/src/Database/integrations/knex/KnexTransaction.d.ts +37 -0
- package/dist/src/Database/integrations/knex/KnexTransaction.js +60 -0
- package/dist/src/Database/integrations/knex/KnexTransaction.js.map +1 -0
- package/dist/src/Database/integrations/pgsql/PostgresDatabase.d.ts +30 -0
- package/dist/src/Database/integrations/pgsql/PostgresDatabase.js +108 -0
- package/dist/src/Database/integrations/pgsql/PostgresDatabase.js.map +1 -0
- package/dist/src/Database/integrations/pgsql/PostgresTransaction.d.ts +37 -0
- package/dist/src/Database/integrations/pgsql/PostgresTransaction.js +60 -0
- package/dist/src/Database/integrations/pgsql/PostgresTransaction.js.map +1 -0
- package/dist/src/Globals.d.ts +26 -94
- package/dist/src/Globals.js +26 -95
- package/dist/src/Globals.js.map +1 -1
- package/dist/src/Logger/Logger.d.ts +82 -105
- package/dist/src/Logger/Logger.js +111 -136
- package/dist/src/Logger/Logger.js.map +1 -1
- package/dist/src/Mailer/Mailer.d.ts +39 -75
- package/dist/src/Mailer/Mailer.js +36 -65
- package/dist/src/Mailer/Mailer.js.map +1 -1
- package/dist/src/Publisher/Publisher.d.ts +17 -25
- package/dist/src/Publisher/Publisher.js +21 -32
- package/dist/src/Publisher/Publisher.js.map +1 -1
- package/dist/src/Server/RouteResolver.d.ts +14 -22
- package/dist/src/Server/RouteResolver.js +21 -34
- package/dist/src/Server/RouteResolver.js.map +1 -1
- package/dist/src/Server/Router.d.ts +72 -51
- package/dist/src/Server/Router.js +8 -17
- package/dist/src/Server/Router.js.map +1 -1
- package/dist/src/Server/lib/ContainerServer.d.ts +15 -31
- package/dist/src/Server/lib/ContainerServer.js +13 -28
- package/dist/src/Server/lib/ContainerServer.js.map +1 -1
- package/dist/src/Server/lib/Server.d.ts +17 -32
- package/dist/src/Server/lib/Server.js +18 -28
- package/dist/src/Server/lib/Server.js.map +1 -1
- package/dist/src/Server/lib/container/GenericHandler.d.ts +5 -0
- package/dist/src/Server/lib/container/GenericHandler.js +16 -3
- package/dist/src/Server/lib/container/GenericHandler.js.map +1 -1
- package/dist/src/Server/lib/container/GenericHandlerEvent.d.ts +22 -37
- package/dist/src/Server/lib/container/GenericHandlerEvent.js +29 -41
- package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +1 -1
- package/dist/src/Server/lib/container/HealthHandler.d.ts +6 -0
- package/dist/src/Server/lib/container/HealthHandler.js +6 -0
- package/dist/src/Server/lib/container/HealthHandler.js.map +1 -1
- package/dist/src/Server/lib/container/Proxy.d.ts +24 -52
- package/dist/src/Server/lib/container/Proxy.js +52 -52
- package/dist/src/Server/lib/container/Proxy.js.map +1 -1
- package/dist/src/Server/lib/container/Utils.d.ts +6 -10
- package/dist/src/Server/lib/container/Utils.js +6 -10
- package/dist/src/Server/lib/container/Utils.js.map +1 -1
- package/dist/src/Validation/Validator.d.ts +9 -13
- package/dist/src/Validation/Validator.js +8 -12
- package/dist/src/Validation/Validator.js.map +1 -1
- package/index.ts +15 -0
- package/jest.config.ts +1 -1
- package/package.json +13 -2
- package/src/API/Request.ts +66 -84
- package/src/API/Response.ts +144 -203
- package/src/API/Utils.ts +28 -44
- package/src/BaseEvent/EventProcessor.ts +52 -77
- package/src/BaseEvent/Process.ts +27 -52
- package/src/BaseEvent/Transaction.ts +147 -27
- package/src/Config/Configuration.ts +59 -76
- package/src/Config/EnvironmentVar.ts +39 -62
- package/src/Crypto/Crypto.ts +20 -36
- package/src/Crypto/JWT.ts +31 -35
- package/src/Database/Database.ts +19 -0
- package/src/Database/DatabaseManager.ts +51 -0
- package/src/Database/DatabaseTransaction.ts +118 -0
- package/src/Database/integrations/knex/KnexDatabase.ts +47 -0
- package/src/Database/integrations/knex/KnexTransaction.ts +51 -0
- package/src/Database/integrations/pgsql/PostgresDatabase.ts +49 -0
- package/src/Database/integrations/pgsql/PostgresTransaction.ts +54 -0
- package/src/Database/types.d.ts +49 -0
- package/src/Globals.ts +28 -96
- package/src/Logger/Logger.ts +141 -160
- package/src/Mailer/Mailer.ts +43 -76
- package/src/Publisher/Publisher.ts +31 -40
- package/src/Server/RouteResolver.ts +31 -52
- package/src/Server/Router.ts +75 -54
- package/src/Server/lib/ContainerServer.ts +20 -32
- package/src/Server/lib/Server.ts +19 -34
- package/src/Server/lib/container/GenericHandler.ts +17 -3
- package/src/Server/lib/container/GenericHandlerEvent.ts +44 -54
- package/src/Server/lib/container/HealthHandler.ts +6 -0
- package/src/Server/lib/container/Proxy.ts +39 -58
- package/src/Server/lib/container/Utils.ts +7 -10
- package/src/Validation/Validator.ts +11 -13
- package/tests/API/Response.test.ts +55 -56
- package/tests/BaseEvent/EventProcessor.test.ts +49 -50
- package/tests/BaseEvent/Process.test.ts +2 -2
- package/tests/BaseEvent/Transaction.test.ts +102 -44
- package/tests/Config/Config.test.ts +27 -27
- package/tests/Config/EnvironmentVar.test.ts +54 -18
- package/tests/Database/DatabaseManager.test.ts +55 -0
- package/tests/Database/integrations/knex/KnexDatabase.test.ts +53 -0
- package/tests/Database/integrations/knex/KnexTransaction.test.ts +133 -0
- package/tests/Database/integrations/pg/PostgresDatabase.test.ts +50 -0
- package/tests/Database/integrations/pg/PostgresTransaction.test.ts +51 -0
- package/tests/Publisher/Publisher.test.ts +3 -3
- package/tests/Server/lib/ContainerServer.test.ts +21 -22
- package/tests/Server/lib/container/GenericHandler.test.ts +31 -32
- package/tests/Server/lib/container/GenericHandlerEvent.test.ts +2 -2
- package/tests/Server/lib/container/HealthHandler.test.ts +6 -7
- package/tests/Server/lib/container/Proxy.test.ts +37 -35
- package/tsconfig.json +6 -1
|
@@ -5,7 +5,18 @@ import Utils from '../../../API/Utils'
|
|
|
5
5
|
import Globals from '../../../Globals'
|
|
6
6
|
import Server from '../Server'
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Creates an async function that handles serverless events and sends a response.
|
|
10
|
+
* @param {Server['handleServerlessEvent']} serverlessHandler - The serverless handler function.
|
|
11
|
+
* @returns {Function} - An async function that handles the request and sends a response.
|
|
12
|
+
*/
|
|
8
13
|
export default (serverlessHandler: Server['handleServerlessEvent']) => {
|
|
14
|
+
/**
|
|
15
|
+
* Handles an HTTP request by invoking a serverless function and processing the response.
|
|
16
|
+
* @param {Request} request - The HTTP request object.
|
|
17
|
+
* @param {Response} res - The HTTP response object.
|
|
18
|
+
* @returns None
|
|
19
|
+
*/
|
|
9
20
|
return async (request: Request, res: Response) => {
|
|
10
21
|
const startTime = Date.now()
|
|
11
22
|
try {
|
|
@@ -27,10 +38,13 @@ export default (serverlessHandler: Server['handleServerlessEvent']) => {
|
|
|
27
38
|
console.debug(`[Proxy] - Request took ${Date.now() - startTime}ms`)
|
|
28
39
|
}
|
|
29
40
|
}
|
|
41
|
+
|
|
30
42
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
|
|
43
|
+
* Processes the response received from a serverless function invocation and sends the appropriate response back to the client.
|
|
44
|
+
* @param {GenericHandlerEventResponse} invokation - The response object received from the serverless function invocation.
|
|
45
|
+
* @param {Response} res - The response object to send back to the client.
|
|
46
|
+
* @returns The response object to send back to the client.
|
|
47
|
+
*/
|
|
34
48
|
const processServerlessResponse = (invokation: GenericHandlerEventResponse, res: Response) => {
|
|
35
49
|
// translate answer to http layer
|
|
36
50
|
if (invokation && invokation.err) {
|
|
@@ -5,54 +5,45 @@ import { Request } from 'express'
|
|
|
5
5
|
import { parseMultiValueQueryStringParameters, parseQueryStringParameters } from './Utils'
|
|
6
6
|
import Globals from '../../../Globals'
|
|
7
7
|
import Server from '../Server'
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* @
|
|
13
|
-
* @
|
|
10
|
+
* Represents the response object returned by a generic event handler.
|
|
11
|
+
* @typedef {Object} GenericHandlerEventResponse
|
|
12
|
+
* @property {Error | string} [err] - An optional error object or error message.
|
|
13
|
+
* @property {*} [data] - An optional data object.
|
|
14
14
|
*/
|
|
15
15
|
export type GenericHandlerEventResponse = { err?: Error | string; data?: any }
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* @export
|
|
21
|
-
* @class GenericHandlerEvent
|
|
22
|
-
* @typedef {GenericHandlerEvent}
|
|
18
|
+
* Represents a generic handler event for serverless functions.
|
|
23
19
|
*/
|
|
24
20
|
export default class GenericHandlerEvent {
|
|
25
21
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* @public
|
|
29
|
-
* @type {Request}
|
|
22
|
+
* Represents an HTTP request.
|
|
23
|
+
* @property {Request} request - The HTTP request object.
|
|
30
24
|
*/
|
|
31
25
|
public request: Request
|
|
32
26
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* @
|
|
36
|
-
* @type {Server["handleServerlessEvent"]}
|
|
27
|
+
* The handler function for serverless events in a server.
|
|
28
|
+
* @param {Server['handleServerlessEvent']} serverlessHandler - The function that handles serverless events.
|
|
29
|
+
* @returns None
|
|
37
30
|
*/
|
|
38
31
|
public serverlessHandler: Server['handleServerlessEvent']
|
|
32
|
+
|
|
39
33
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* @
|
|
43
|
-
* @
|
|
44
|
-
* @param {Server["handleServerlessEvent"]} serverlessHandler
|
|
34
|
+
* Constructs a new instance of the class.
|
|
35
|
+
* @param {Request} request - The request object.
|
|
36
|
+
* @param {Server['handleServerlessEvent']} serverlessHandler - The serverless handler function.
|
|
37
|
+
* @returns None
|
|
45
38
|
*/
|
|
46
39
|
constructor(request: Request, serverlessHandler: Server['handleServerlessEvent']) {
|
|
47
40
|
this.request = request
|
|
48
41
|
this.serverlessHandler = serverlessHandler
|
|
49
42
|
}
|
|
43
|
+
|
|
50
44
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* @public
|
|
54
|
-
* @async
|
|
55
|
-
* @returns {Promise<GenericHandlerEventResponse>}
|
|
45
|
+
* Invokes the handler function asynchronously and returns a promise that resolves to a GenericHandlerEventResponse.
|
|
46
|
+
* @returns {Promise<GenericHandlerEventResponse>} A promise that resolves to a GenericHandlerEventResponse.
|
|
56
47
|
*/
|
|
57
48
|
public async invoke(): Promise<GenericHandlerEventResponse> {
|
|
58
49
|
// eslint-disable-next-line no-async-promise-executor
|
|
@@ -70,12 +61,10 @@ export default class GenericHandlerEvent {
|
|
|
70
61
|
}
|
|
71
62
|
})
|
|
72
63
|
}
|
|
73
|
-
|
|
64
|
+
|
|
74
65
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* @private
|
|
78
|
-
* @returns {APIGatewayProxyEvent}
|
|
66
|
+
* Builds and returns an APIGatewayProxyEvent object based on the current request.
|
|
67
|
+
* @returns {APIGatewayProxyEvent} - The constructed APIGatewayProxyEvent object.
|
|
79
68
|
*/
|
|
80
69
|
private buildEvent(): APIGatewayProxyEvent {
|
|
81
70
|
return {
|
|
@@ -91,13 +80,13 @@ export default class GenericHandlerEvent {
|
|
|
91
80
|
? parseQueryStringParameters(this.request.query)
|
|
92
81
|
: null,
|
|
93
82
|
requestContext: {
|
|
94
|
-
accountId: process.env.AWS_ACCOUNT_ID ||
|
|
95
|
-
apiId:
|
|
83
|
+
accountId: process.env.AWS_ACCOUNT_ID || 'undefined',
|
|
84
|
+
apiId: '',
|
|
96
85
|
authorizer: null,
|
|
97
|
-
domainName:
|
|
98
|
-
domainPrefix:
|
|
86
|
+
domainName: undefined,
|
|
87
|
+
domainPrefix: undefined,
|
|
99
88
|
extendedRequestId: cuid(),
|
|
100
|
-
httpMethod: this.request.method ? this.request.method.toUpperCase() :
|
|
89
|
+
httpMethod: this.request.method ? this.request.method.toUpperCase() : '',
|
|
101
90
|
identity: {
|
|
102
91
|
accessKey: null,
|
|
103
92
|
accountId: process.env.AWS_ACCOUNT_ID || null,
|
|
@@ -111,9 +100,11 @@ export default class GenericHandlerEvent {
|
|
|
111
100
|
cognitoIdentityPoolId: null,
|
|
112
101
|
principalOrgId: null,
|
|
113
102
|
sourceIp:
|
|
114
|
-
<string>this.request.headers?.['x-forwarded-for'] ||
|
|
103
|
+
<string>this.request.headers?.['x-forwarded-for'] ||
|
|
104
|
+
this.request.socket?.remoteAddress ||
|
|
105
|
+
'',
|
|
115
106
|
user: null,
|
|
116
|
-
userAgent: this.request.headers?.['user-agent'],
|
|
107
|
+
userAgent: this.request.headers?.['user-agent'] || null,
|
|
117
108
|
userArn: null,
|
|
118
109
|
},
|
|
119
110
|
path: this.request.path,
|
|
@@ -121,21 +112,20 @@ export default class GenericHandlerEvent {
|
|
|
121
112
|
requestId: `${cuid()}-${cuid()}`,
|
|
122
113
|
requestTime: new Date().toISOString(),
|
|
123
114
|
requestTimeEpoch: Date.now(),
|
|
124
|
-
resourceId:
|
|
115
|
+
resourceId: '',
|
|
125
116
|
resourcePath: Globals.Listener_HTTP_ProxyRoute,
|
|
126
|
-
stage: process.env.STAGE,
|
|
117
|
+
stage: process.env.STAGE || '',
|
|
127
118
|
},
|
|
128
119
|
resource: Globals.Listener_HTTP_ProxyRoute,
|
|
129
120
|
stageVariables: null,
|
|
130
121
|
}
|
|
131
122
|
}
|
|
123
|
+
|
|
132
124
|
/**
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
* @
|
|
136
|
-
* @
|
|
137
|
-
* @param {(err?: Error | string, data?: any) => void} callback
|
|
138
|
-
* @returns {Context}
|
|
125
|
+
* Builds and returns a context object for an AWS Lambda function.
|
|
126
|
+
* @param {APIGatewayProxyEvent} event - The event object passed to the Lambda function.
|
|
127
|
+
* @param {(err?: Error | string, data?: any) => void} callback - The callback function to be called when the Lambda function completes.
|
|
128
|
+
* @returns {Context} - The context object for the Lambda function.
|
|
139
129
|
*/
|
|
140
130
|
private buildContext(
|
|
141
131
|
event: APIGatewayProxyEvent,
|
|
@@ -149,13 +139,13 @@ export default class GenericHandlerEvent {
|
|
|
149
139
|
},
|
|
150
140
|
done: (err, data) => callback(err, data),
|
|
151
141
|
fail: err => callback(err),
|
|
152
|
-
succeed: res => callback(
|
|
153
|
-
functionName:
|
|
142
|
+
succeed: res => callback(undefined, res),
|
|
143
|
+
functionName: 'container-function',
|
|
154
144
|
functionVersion: 'LATEST',
|
|
155
|
-
invokedFunctionArn:
|
|
145
|
+
invokedFunctionArn: 'none',
|
|
156
146
|
memoryLimitInMB: '-1',
|
|
157
|
-
logGroupName:
|
|
158
|
-
logStreamName:
|
|
147
|
+
logGroupName: 'undefined',
|
|
148
|
+
logStreamName: 'undefined',
|
|
159
149
|
}
|
|
160
150
|
}
|
|
161
151
|
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { Request, Response } from 'express'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Handles a request and sends a response with the message 'Healthy!'.
|
|
5
|
+
* @param {Request} _request - The request object.
|
|
6
|
+
* @param {Response} res - The response object.
|
|
7
|
+
* @returns None
|
|
8
|
+
*/
|
|
3
9
|
export default async (_request: Request, res: Response) => {
|
|
4
10
|
res.send('Healthy!')
|
|
5
11
|
}
|
|
@@ -12,57 +12,41 @@ import Globals from '../../../Globals'
|
|
|
12
12
|
import { RouterConfig } from '../../Router'
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* @export
|
|
18
|
-
* @class Proxy
|
|
19
|
-
* @typedef {Proxy}
|
|
15
|
+
* Represents a Proxy class that handles routing and server functionality.
|
|
20
16
|
*/
|
|
21
17
|
export default class Proxy {
|
|
22
18
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* @private
|
|
26
|
-
* @type {boolean}
|
|
19
|
+
* A boolean flag indicating whether the process is currently stopping or not.
|
|
27
20
|
*/
|
|
28
21
|
private stopping: boolean
|
|
29
22
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* @private
|
|
33
|
-
* @readonly
|
|
34
|
-
* @type {RouterConfig}
|
|
23
|
+
* The configuration object for the router.
|
|
35
24
|
*/
|
|
36
25
|
private readonly config: RouterConfig
|
|
37
26
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* @private
|
|
27
|
+
* The Express application instance for the server.
|
|
41
28
|
* @readonly
|
|
42
29
|
* @type {express.Express}
|
|
43
30
|
*/
|
|
44
31
|
private readonly app: express.Express
|
|
45
32
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* @
|
|
49
|
-
* @readonly
|
|
50
|
-
* @type {Server["handleServerlessEvent"]}
|
|
33
|
+
* The handler function for serverless events in the Server class.
|
|
34
|
+
* @param {ServerlessEvent} event - The serverless event object.
|
|
35
|
+
* @returns None
|
|
51
36
|
*/
|
|
52
37
|
private readonly serverlessHandler: Server['handleServerlessEvent']
|
|
53
38
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
39
|
+
* Represents a listener for an HTTP server.
|
|
56
40
|
* @private
|
|
57
41
|
* @type {HTTPServer}
|
|
58
42
|
*/
|
|
59
43
|
private listener: HTTPServer
|
|
44
|
+
|
|
60
45
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* @
|
|
64
|
-
* @
|
|
65
|
-
* @param {Server["handleServerlessEvent"]} serverlessHandler
|
|
46
|
+
* Constructs a new instance of the Router class.
|
|
47
|
+
* @param {RouterConfig} config - The configuration object for the router.
|
|
48
|
+
* @param {Server['handleServerlessEvent']} serverlessHandler - The handler function for serverless events.
|
|
49
|
+
* @returns None
|
|
66
50
|
*/
|
|
67
51
|
constructor(config: RouterConfig, serverlessHandler: Server['handleServerlessEvent']) {
|
|
68
52
|
this.stopping = false
|
|
@@ -93,42 +77,41 @@ export default class Proxy {
|
|
|
93
77
|
// this.listener.listener.keepAliveTimeout = 120e3
|
|
94
78
|
// this.listener.listener.headersTimeout = 120e3
|
|
95
79
|
}
|
|
80
|
+
|
|
96
81
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* @async
|
|
100
|
-
* @returns {*}
|
|
82
|
+
* Loads the necessary components and initializes the application.
|
|
83
|
+
* @returns None
|
|
101
84
|
*/
|
|
102
85
|
async load() {
|
|
103
|
-
await this.startListeners()
|
|
104
86
|
this.installRoutes()
|
|
87
|
+
await this.startListeners()
|
|
105
88
|
}
|
|
89
|
+
|
|
106
90
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* @
|
|
110
|
-
* @param {?*} [err]
|
|
111
|
-
* @returns {*}
|
|
91
|
+
* Unloads the current module, stopping any active listeners.
|
|
92
|
+
* @param {any} [err] - Optional error object to pass to the stopListeners method.
|
|
93
|
+
* @returns {Promise<void>} - A promise that resolves once the listeners have been stopped.
|
|
112
94
|
*/
|
|
113
95
|
async unload(err?: any) {
|
|
114
96
|
await this.stopListeners(err)
|
|
115
97
|
}
|
|
116
|
-
|
|
98
|
+
|
|
117
99
|
/**
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* @private
|
|
121
|
-
* @async
|
|
122
|
-
* @returns {Promise<void>}
|
|
100
|
+
* Starts the listeners for the proxy server.
|
|
101
|
+
* @returns {Promise<void>} A promise that resolves when the listeners have started.
|
|
123
102
|
*/
|
|
124
103
|
private async startListeners(): Promise<void> {
|
|
125
|
-
|
|
104
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
105
|
+
return new Promise(async resolve => {
|
|
126
106
|
const port = this.config.port || Globals.Listener_HTTP_DefaultPort
|
|
127
107
|
console.log(`[Proxy] - [STARTING] - v.${appVersion} - :${port}`)
|
|
128
108
|
// Create Server
|
|
129
109
|
this.listener = createServer(this.app)
|
|
130
110
|
// Set defaults
|
|
131
111
|
this.listener.setTimeout(this.config.timeout || Globals.Listener_HTTP_DefaultTimeout)
|
|
112
|
+
// Call hook if available
|
|
113
|
+
if (this.config.containerSetupHook)
|
|
114
|
+
await this.config.containerSetupHook(this.listener, this.app)
|
|
132
115
|
// Start Server
|
|
133
116
|
this.listener.listen(port, () => {
|
|
134
117
|
console.log(`[Proxy] - [STARTED]`)
|
|
@@ -136,13 +119,11 @@ export default class Proxy {
|
|
|
136
119
|
})
|
|
137
120
|
})
|
|
138
121
|
}
|
|
122
|
+
|
|
139
123
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* @
|
|
143
|
-
* @async
|
|
144
|
-
* @param {?*} [err]
|
|
145
|
-
* @returns {unknown}
|
|
124
|
+
* Stops the listeners and exits the process.
|
|
125
|
+
* @param {any} [err] - Optional error object.
|
|
126
|
+
* @returns {Promise<void>} - A promise that resolves when the listeners are stopped and the process is exited.
|
|
146
127
|
*/
|
|
147
128
|
private async stopListeners(err?: any) {
|
|
148
129
|
if (this.stopping) return
|
|
@@ -150,18 +131,18 @@ export default class Proxy {
|
|
|
150
131
|
console.debug('[Proxy] - [STOPPING]')
|
|
151
132
|
return new Promise(resolve => {
|
|
152
133
|
this.listener.close(_err => {
|
|
153
|
-
|
|
134
|
+
const err2 = err || _err
|
|
135
|
+
if (err2) console.log('[Proxy] - exit output:', err2)
|
|
154
136
|
console.log('[Proxy] - [STOPPED]')
|
|
155
|
-
process.exit(
|
|
137
|
+
process.exit(err2 ? 1 : 0)
|
|
156
138
|
resolve(null)
|
|
157
139
|
})
|
|
158
140
|
})
|
|
159
141
|
}
|
|
160
|
-
|
|
142
|
+
|
|
161
143
|
/**
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
* @private
|
|
144
|
+
* Installs the routes for the proxy server.
|
|
145
|
+
* @returns None
|
|
165
146
|
*/
|
|
166
147
|
private installRoutes() {
|
|
167
148
|
//Health check route -- This is a bypass route to only check if
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* @
|
|
5
|
-
* @param {string} url
|
|
6
|
-
* @returns {*}
|
|
2
|
+
* Parses the multi-value query string parameters from the given URL.
|
|
3
|
+
* @param {string} url - The URL containing the query string parameters.
|
|
4
|
+
* @returns {Object} - An object representing the parsed query string parameters.
|
|
7
5
|
*/
|
|
8
6
|
export function parseMultiValueQueryStringParameters(url: string) {
|
|
9
7
|
// dummy placeholder url for the WHATWG URL constructor
|
|
@@ -20,12 +18,11 @@ export function parseMultiValueQueryStringParameters(url: string) {
|
|
|
20
18
|
}
|
|
21
19
|
return Object.fromEntries(map)
|
|
22
20
|
}
|
|
21
|
+
|
|
23
22
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* @
|
|
27
|
-
* @param {*} url
|
|
28
|
-
* @returns {*}
|
|
23
|
+
* Parses the query string parameters from a given URL.
|
|
24
|
+
* @param {string} url - The URL to parse the query string parameters from.
|
|
25
|
+
* @returns {object | null} - An object containing the parsed query string parameters, or null if there are no parameters.
|
|
29
26
|
*/
|
|
30
27
|
export function parseQueryStringParameters(url) {
|
|
31
28
|
// dummy placeholder url for the WHATWG URL constructor
|
|
@@ -4,27 +4,24 @@ import Response, { ResponseErrorType } from '../API/Response'
|
|
|
4
4
|
import Globals from '../Globals'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* @
|
|
10
|
-
* @
|
|
11
|
-
* @typedef {Validator}
|
|
7
|
+
* Validates the given data against the provided schema.
|
|
8
|
+
* @param {any} data - The data to be validated.
|
|
9
|
+
* @param {z.ZodObject<any>} schema - The schema to validate against.
|
|
10
|
+
* @returns {boolean | Response<ResponseErrorType>} - Returns true if the data is valid, otherwise returns a response object with an error message.
|
|
12
11
|
*/
|
|
13
12
|
export default class Validator {
|
|
14
13
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* @
|
|
18
|
-
* @
|
|
19
|
-
* @param {*} data
|
|
20
|
-
* @param {z.ZodObject<any>} schema
|
|
21
|
-
* @returns {(boolean | Response<ResponseErrorType>)}
|
|
14
|
+
* Validates the given data against the provided schema.
|
|
15
|
+
* @param {any} data - The data to be validated.
|
|
16
|
+
* @param {z.ZodObject<any> | z.ZodUnion<any>} schema - The schema to validate against.
|
|
17
|
+
* @returns {boolean | Response<ResponseErrorType>} - Returns either true if the data is valid or a Response object with an error message if validation fails.
|
|
22
18
|
*/
|
|
23
19
|
public static validateSchema(
|
|
24
20
|
data: any,
|
|
25
|
-
schema: z.ZodObject<any>
|
|
21
|
+
schema: z.ZodObject<any> | z.ZodUnion<any>
|
|
26
22
|
): boolean | Response<ResponseErrorType> {
|
|
27
23
|
let error, validatedInput
|
|
24
|
+
|
|
28
25
|
// Validate body against known zod schema
|
|
29
26
|
try {
|
|
30
27
|
validatedInput = schema.parse(data) as typeof schema
|
|
@@ -32,6 +29,7 @@ export default class Validator {
|
|
|
32
29
|
if (err instanceof z.ZodError) error = JSON.parse(err.message)
|
|
33
30
|
else error = 'Unknown validation error!' //unhandled case, hard to test
|
|
34
31
|
}
|
|
32
|
+
|
|
35
33
|
// Error validation
|
|
36
34
|
if (!validatedInput || error) {
|
|
37
35
|
return Response.BadRequestResponse(
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { expect as j_expect } from '@jest/globals'
|
|
2
1
|
import { APIGatewayEvent, Context } from 'aws-lambda'
|
|
3
|
-
import { expect } from 'chai'
|
|
2
|
+
import { expect as c_expect } from 'chai'
|
|
4
3
|
|
|
5
4
|
import Response from '../../src/API/Response'
|
|
6
5
|
import Transaction from '../../src/BaseEvent/Transaction'
|
|
@@ -11,11 +10,11 @@ async function testResponse(r: Response<any>, body: any, optCode?: number, optHe
|
|
|
11
10
|
const t = observableTransaction()
|
|
12
11
|
const context = t['context']
|
|
13
12
|
const buildR = await r.build(context, t, false)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
c_expect(buildR).to.be.undefined
|
|
14
|
+
expect(t.responseProxy).toBeCalledTimes(1)
|
|
15
|
+
expect(context.fail).not.toBeCalled()
|
|
16
|
+
expect(context.done).not.toBeCalled()
|
|
17
|
+
expect(context.succeed).toHaveBeenCalledWith({
|
|
19
18
|
statusCode: optCode || 400,
|
|
20
19
|
headers: {
|
|
21
20
|
...defaultHeaders,
|
|
@@ -35,28 +34,28 @@ async function testResponse(r: Response<any>, body: any, optCode?: number, optHe
|
|
|
35
34
|
describe('Response basics', () => {
|
|
36
35
|
test('Null body', () => {
|
|
37
36
|
const r = new Response<null>(200, null)
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
c_expect(r.getCode()).to.be.equals(200)
|
|
38
|
+
c_expect(r.getBody()).to.be.null
|
|
40
39
|
})
|
|
41
40
|
|
|
42
41
|
test('String body', () => {
|
|
43
42
|
const r = new Response<string>(200, 'abc')
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
c_expect(r.getCode()).to.be.equals(200)
|
|
44
|
+
c_expect(r.getBody()).to.be.equals('abc')
|
|
46
45
|
})
|
|
47
46
|
|
|
48
47
|
test('Generic body', () => {
|
|
49
48
|
const r = new Response<any>(200, { name: 'abc' })
|
|
50
49
|
r.appendIntoBody('name2', '123')
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
c_expect(r.getCode()).to.be.equals(200)
|
|
51
|
+
c_expect(r.getBody().name).to.be.equals('abc')
|
|
52
|
+
c_expect(r.getBody().name2).to.be.equals('123')
|
|
54
53
|
})
|
|
55
54
|
|
|
56
55
|
test('Append/validate header', () => {
|
|
57
56
|
const r = new Response<any>(200, {})
|
|
58
57
|
r.appendHeader('name2', '123')
|
|
59
|
-
|
|
58
|
+
c_expect(r['headers']['name2']).to.be.equals('123')
|
|
60
59
|
})
|
|
61
60
|
})
|
|
62
61
|
|
|
@@ -76,10 +75,10 @@ describe('Response build', () => {
|
|
|
76
75
|
)
|
|
77
76
|
const context = t['context']
|
|
78
77
|
const buildR = await r.build(context, t, false)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
c_expect(buildR).to.be.undefined
|
|
79
|
+
expect(context.fail).not.toBeCalled()
|
|
80
|
+
expect(context.done).not.toBeCalled()
|
|
81
|
+
expect(context.succeed).toHaveBeenCalledWith({
|
|
83
82
|
statusCode: 200,
|
|
84
83
|
headers: {
|
|
85
84
|
...defaultHeaders,
|
|
@@ -98,10 +97,10 @@ describe('Response build', () => {
|
|
|
98
97
|
const t = observableTransaction()
|
|
99
98
|
const context = t['context']
|
|
100
99
|
const buildR = await r.build(context, t, true)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
100
|
+
c_expect(buildR).to.be.undefined
|
|
101
|
+
expect(context.fail).not.toBeCalled()
|
|
102
|
+
expect(context.done).not.toBeCalled()
|
|
103
|
+
expect(context.succeed).not.toBeCalled()
|
|
105
104
|
})
|
|
106
105
|
|
|
107
106
|
test('Succeeds to transaction context as RAW', async () => {
|
|
@@ -112,10 +111,10 @@ describe('Response build', () => {
|
|
|
112
111
|
const t = observableTransaction()
|
|
113
112
|
const context = t['context']
|
|
114
113
|
const buildR = await r.build(context, t, false)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
c_expect(buildR).to.be.undefined
|
|
115
|
+
expect(context.fail).not.toBeCalled()
|
|
116
|
+
expect(context.done).not.toBeCalled()
|
|
117
|
+
expect(context.succeed).toHaveBeenCalledWith({
|
|
119
118
|
...b,
|
|
120
119
|
transactionID: 'unknown',
|
|
121
120
|
})
|
|
@@ -130,11 +129,11 @@ describe('Response build', () => {
|
|
|
130
129
|
const context = t['context']
|
|
131
130
|
const buildR = await r.build(context, t, false)
|
|
132
131
|
await r.build(context, t, false) //pipe twice, should not affect
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
132
|
+
c_expect(buildR).to.be.undefined
|
|
133
|
+
expect(context.fail).not.toBeCalled()
|
|
134
|
+
expect(context.done).not.toBeCalled()
|
|
135
|
+
expect(context.succeed).toHaveBeenCalledTimes(1)
|
|
136
|
+
expect(context.succeed).toHaveBeenCalledWith({
|
|
138
137
|
statusCode: 200,
|
|
139
138
|
headers: {
|
|
140
139
|
...defaultHeaders,
|
|
@@ -153,10 +152,10 @@ describe('Response build', () => {
|
|
|
153
152
|
const t = observableTransaction()
|
|
154
153
|
const context = t['context']
|
|
155
154
|
const buildR = await r.build(context, t, false)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
155
|
+
c_expect(buildR).to.be.undefined
|
|
156
|
+
expect(context.done).not.toBeCalled()
|
|
157
|
+
expect(context.succeed).not.toBeCalled()
|
|
158
|
+
expect(context.fail).toHaveBeenCalledTimes(1)
|
|
160
159
|
})
|
|
161
160
|
|
|
162
161
|
test('Failure exception to transaction context as RAW', async () => {
|
|
@@ -174,11 +173,11 @@ describe('Response build', () => {
|
|
|
174
173
|
} catch (e) {
|
|
175
174
|
exception = e
|
|
176
175
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
176
|
+
c_expect(buildR).to.be.null
|
|
177
|
+
c_expect(exception).to.not.be.null
|
|
178
|
+
expect(context.done).not.toBeCalled()
|
|
179
|
+
expect(context.succeed).not.toBeCalled()
|
|
180
|
+
expect(context.fail).not.toBeCalled()
|
|
182
181
|
})
|
|
183
182
|
|
|
184
183
|
test('Failure exception to transaction context as RAW and null body', async () => {
|
|
@@ -196,11 +195,11 @@ describe('Response build', () => {
|
|
|
196
195
|
} catch (e) {
|
|
197
196
|
exception = e
|
|
198
197
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
198
|
+
c_expect(buildR).to.be.null
|
|
199
|
+
c_expect(exception).to.not.be.null
|
|
200
|
+
expect(context.done).not.toBeCalled()
|
|
201
|
+
expect(context.succeed).not.toBeCalled()
|
|
202
|
+
expect(context.fail).not.toBeCalled()
|
|
204
203
|
})
|
|
205
204
|
|
|
206
205
|
test('Failure exception to transaction context as RAW and custom ero', async () => {
|
|
@@ -218,11 +217,11 @@ describe('Response build', () => {
|
|
|
218
217
|
} catch (e) {
|
|
219
218
|
exception = e
|
|
220
219
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
220
|
+
c_expect(buildR).to.be.null
|
|
221
|
+
c_expect(exception).to.not.be.null
|
|
222
|
+
expect(context.done).not.toBeCalled()
|
|
223
|
+
expect(context.succeed).not.toBeCalled()
|
|
224
|
+
expect(context.fail).not.toBeCalled()
|
|
226
225
|
})
|
|
227
226
|
})
|
|
228
227
|
|
|
@@ -346,11 +345,11 @@ describe('Response shortcuts', () => {
|
|
|
346
345
|
const context = t['context']
|
|
347
346
|
const buildR = await r.build(context, t, false)
|
|
348
347
|
await r.build(context, t, false) //pipe twice, should not affect
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
348
|
+
c_expect(buildR).to.be.undefined
|
|
349
|
+
expect(context.fail).not.toBeCalled()
|
|
350
|
+
expect(context.done).not.toBeCalled()
|
|
351
|
+
expect(context.succeed).toHaveBeenCalledTimes(1)
|
|
352
|
+
expect(context.succeed).toHaveBeenCalledWith({
|
|
354
353
|
statusCode: 200,
|
|
355
354
|
headers: {
|
|
356
355
|
...defaultHeaders,
|