@creator.co/wapi 1.2.2 → 1.2.4
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 +2 -5
- package/.github/workflows/prs.yml +1 -1
- package/README.md +1 -3
- package/dist/index.d.ts +11 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/jest.config.d.ts +3 -0
- package/dist/jest.config.js +34 -0
- package/dist/jest.config.js.map +1 -0
- package/dist/package.json +64 -0
- package/dist/src/API/Request.d.ts +140 -0
- package/dist/src/API/Request.js +182 -0
- package/dist/src/API/Request.js.map +1 -0
- package/dist/src/API/Response.d.ts +256 -0
- package/dist/src/API/Response.js +398 -0
- package/dist/src/API/Response.js.map +1 -0
- package/dist/src/API/Utils.d.ts +63 -0
- package/dist/src/API/Utils.js +104 -0
- package/dist/src/API/Utils.js.map +1 -0
- package/dist/src/BaseEvent/EventProcessor.d.ts +81 -0
- package/dist/src/BaseEvent/EventProcessor.js +182 -0
- package/dist/src/BaseEvent/EventProcessor.js.map +1 -0
- package/dist/src/BaseEvent/Process.d.ts +74 -0
- package/dist/src/BaseEvent/Process.js +142 -0
- package/dist/src/BaseEvent/Process.js.map +1 -0
- package/dist/src/BaseEvent/Transaction.d.ts +29 -0
- package/dist/src/BaseEvent/Transaction.js +244 -0
- package/dist/src/BaseEvent/Transaction.js.map +1 -0
- package/dist/src/Config/Configuration.d.ts +131 -0
- package/dist/src/Config/Configuration.js +153 -0
- package/dist/src/Config/Configuration.js.map +1 -0
- package/dist/src/Config/EnvironmentVar.d.ts +101 -0
- package/dist/src/Config/EnvironmentVar.js +213 -0
- package/dist/src/Config/EnvironmentVar.js.map +1 -0
- package/dist/src/Crypto/Crypto.d.ts +57 -0
- package/dist/src/Crypto/Crypto.js +126 -0
- package/dist/src/Crypto/Crypto.js.map +1 -0
- package/dist/src/Crypto/JWT.d.ts +64 -0
- package/dist/src/Crypto/JWT.js +74 -0
- package/dist/src/Crypto/JWT.js.map +1 -0
- package/dist/src/Globals.d.ts +161 -0
- package/dist/src/Globals.js +173 -0
- package/dist/src/Globals.js.map +1 -0
- package/dist/src/Logger/Logger.d.ts +180 -0
- package/dist/src/Logger/Logger.js +412 -0
- package/dist/src/Logger/Logger.js.map +1 -0
- package/dist/src/Mailer/Mailer.d.ts +107 -0
- package/dist/src/Mailer/Mailer.js +313 -0
- package/dist/src/Mailer/Mailer.js.map +1 -0
- package/dist/src/Publisher/Publisher.d.ts +47 -0
- package/dist/src/Publisher/Publisher.js +141 -0
- package/dist/src/Publisher/Publisher.js.map +1 -0
- package/dist/src/Server/RouteResolver.d.ts +41 -0
- package/dist/src/Server/RouteResolver.js +135 -0
- package/dist/src/Server/RouteResolver.js.map +1 -0
- package/dist/src/Server/Router.d.ts +104 -0
- package/dist/src/Server/Router.js +45 -0
- package/dist/src/Server/Router.js.map +1 -0
- package/dist/src/Server/lib/ContainerServer.d.ts +58 -0
- package/dist/src/Server/lib/ContainerServer.js +143 -0
- package/dist/src/Server/lib/ContainerServer.js.map +1 -0
- package/dist/src/Server/lib/Server.d.ts +60 -0
- package/dist/src/Server/lib/Server.js +137 -0
- package/dist/src/Server/lib/Server.js.map +1 -0
- package/dist/src/Server/lib/container/GenericHandler.d.ts +4 -0
- package/dist/src/Server/lib/container/GenericHandler.js +138 -0
- package/dist/src/Server/lib/container/GenericHandler.js.map +1 -0
- package/dist/src/Server/lib/container/GenericHandlerEvent.d.ts +67 -0
- package/dist/src/Server/lib/container/GenericHandlerEvent.js +189 -0
- package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +1 -0
- package/dist/src/Server/lib/container/HealthHandler.d.ts +3 -0
- package/dist/src/Server/lib/container/HealthHandler.js +45 -0
- package/dist/src/Server/lib/container/HealthHandler.js.map +1 -0
- package/dist/src/Server/lib/container/Proxy.d.ts +95 -0
- package/dist/src/Server/lib/container/Proxy.js +201 -0
- package/dist/src/Server/lib/container/Proxy.js.map +1 -0
- package/dist/src/Server/lib/container/Utils.d.ts +18 -0
- package/dist/src/Server/lib/container/Utils.js +84 -0
- package/dist/src/Server/lib/container/Utils.js.map +1 -0
- package/dist/src/Validation/Validator.d.ts +21 -0
- package/dist/src/Validation/Validator.js +48 -0
- package/dist/src/Validation/Validator.js.map +1 -0
- package/index.ts +12 -10
- package/jest.config.ts +14 -21
- package/package.json +3 -3
- package/src/API/Request.ts +17 -35
- package/src/API/Response.ts +24 -42
- package/src/API/Utils.ts +5 -7
- package/src/BaseEvent/EventProcessor.ts +16 -24
- package/src/BaseEvent/Process.ts +7 -12
- package/src/BaseEvent/Transaction.ts +25 -43
- package/src/Config/Configuration.ts +8 -14
- package/src/Config/EnvironmentVar.ts +10 -20
- package/src/Crypto/Crypto.ts +10 -10
- package/src/Crypto/JWT.ts +4 -10
- package/src/Globals.ts +19 -25
- package/src/Logger/Logger.ts +36 -51
- package/src/Mailer/Mailer.ts +19 -31
- package/src/Publisher/Publisher.ts +7 -12
- package/src/Server/RouteResolver.ts +5 -6
- package/src/Server/Router.ts +7 -12
- package/src/Server/lib/ContainerServer.ts +5 -5
- package/src/Server/lib/Server.ts +26 -38
- package/src/Server/lib/container/GenericHandler.ts +8 -13
- package/src/Server/lib/container/GenericHandlerEvent.ts +21 -35
- package/src/Server/lib/container/HealthHandler.ts +2 -2
- package/src/Server/lib/container/Proxy.ts +26 -38
- package/src/Server/lib/container/Utils.ts +2 -2
- package/src/Validation/Validator.ts +6 -6
- package/tests/API/Request.test.ts +107 -111
- package/tests/API/Response.test.ts +86 -91
- package/tests/API/Utils.test.ts +64 -64
- package/tests/BaseEvent/EventProcessor.test.ts +68 -84
- package/tests/BaseEvent/Process.test.ts +11 -11
- package/tests/BaseEvent/Transaction.test.ts +44 -53
- package/tests/Config/Config.test.ts +50 -50
- package/tests/Config/EnvironmentVar.test.ts +50 -59
- package/tests/Crypto/Crypto.test.ts +20 -22
- package/tests/Crypto/JWT.test.ts +40 -40
- package/tests/Logger/Logger.test.ts +24 -36
- package/tests/Mailer/Mailer.test.ts +21 -29
- package/tests/Publisher/Publisher.test.ts +18 -18
- package/tests/Server/RouteResolver.test.ts +56 -59
- package/tests/Server/Router.test.ts +16 -16
- package/tests/Server/lib/ContainerServer.test.ts +83 -85
- package/tests/Server/lib/Server.test.ts +4 -4
- package/tests/Server/lib/container/GenericHandler.test.ts +31 -41
- package/tests/Server/lib/container/GenericHandlerEvent.test.ts +35 -36
- package/tests/Server/lib/container/HealthHandler.test.ts +7 -7
- package/tests/Server/lib/container/Proxy.test.ts +66 -79
- package/tests/Server/lib/container/Utils.test.ts +16 -17
- package/tests/Test.utils.ts +9 -9
- package/tests/Validation/Validator.test.ts +28 -40
- package/tests/main.test.ts +2 -2
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
PublishCommand,
|
|
4
4
|
PublishCommandOutput,
|
|
5
5
|
PublishCommandInput,
|
|
6
|
-
} from
|
|
7
|
-
import * as sha1 from
|
|
6
|
+
} from '@aws-sdk/client-sns'
|
|
7
|
+
import * as sha1 from 'sha1'
|
|
8
8
|
//reusable client
|
|
9
9
|
// eslint-disable-next-line no-var
|
|
10
10
|
/**
|
|
@@ -71,7 +71,7 @@ export default class Publisher {
|
|
|
71
71
|
async publishOnTopic(
|
|
72
72
|
messageObject: any,
|
|
73
73
|
topic: string,
|
|
74
|
-
additionalProps?: object
|
|
74
|
+
additionalProps?: object
|
|
75
75
|
): Promise<PublishCommandOutput> {
|
|
76
76
|
let resp: null | PublishCommandOutput = null
|
|
77
77
|
try {
|
|
@@ -84,11 +84,9 @@ export default class Publisher {
|
|
|
84
84
|
}
|
|
85
85
|
resp = await PUBLISHER_CONN.send(new PublishCommand(params))
|
|
86
86
|
} catch (e) {
|
|
87
|
-
console.error(
|
|
88
|
-
`Error while publishing into topic ${topic} with error: ${e}`,
|
|
89
|
-
)
|
|
87
|
+
console.error(`Error while publishing into topic ${topic} with error: ${e}`)
|
|
90
88
|
}
|
|
91
|
-
console.debug(
|
|
89
|
+
console.debug('Publisher resp', resp)
|
|
92
90
|
return resp
|
|
93
91
|
}
|
|
94
92
|
/* Private */
|
|
@@ -96,12 +94,9 @@ export default class Publisher {
|
|
|
96
94
|
* ${1:Description placeholder}
|
|
97
95
|
*/
|
|
98
96
|
_connect() {
|
|
99
|
-
if (
|
|
100
|
-
(!PUBLISHER_CONN && !PUBLISHER_CONN_HASH) ||
|
|
101
|
-
PUBLISHER_CONN_HASH != sha1(this.region)
|
|
102
|
-
) {
|
|
97
|
+
if ((!PUBLISHER_CONN && !PUBLISHER_CONN_HASH) || PUBLISHER_CONN_HASH != sha1(this.region)) {
|
|
103
98
|
PUBLISHER_CONN = new SNSClient({
|
|
104
|
-
apiVersion:
|
|
99
|
+
apiVersion: '2010-03-31',
|
|
105
100
|
region: this.region,
|
|
106
101
|
})
|
|
107
102
|
PUBLISHER_CONN_HASH = sha1(this.region).toString()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Route, RouterConfig } from
|
|
1
|
+
import { Route, RouterConfig } from './Router'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* ${1:Description placeholder}
|
|
@@ -48,7 +48,7 @@ class Routes {
|
|
|
48
48
|
public addRoute(route: Route, parts: string[]): void {
|
|
49
49
|
const first = parts.shift()
|
|
50
50
|
if (first) {
|
|
51
|
-
if (first.startsWith(
|
|
51
|
+
if (first.startsWith(':')) {
|
|
52
52
|
this.variable = this.variable || new Routes()
|
|
53
53
|
this.variable.addRoute(route, parts)
|
|
54
54
|
} else {
|
|
@@ -56,8 +56,7 @@ class Routes {
|
|
|
56
56
|
this.next[first].addRoute(route, parts)
|
|
57
57
|
}
|
|
58
58
|
} else {
|
|
59
|
-
if (this.current)
|
|
60
|
-
throw new Error(`Duplicate route: ${route.method}: ${route.path}`)
|
|
59
|
+
if (this.current) throw new Error(`Duplicate route: ${route.method}: ${route.path}`)
|
|
61
60
|
|
|
62
61
|
this.current = route
|
|
63
62
|
}
|
|
@@ -119,7 +118,7 @@ export default class RouteResolver {
|
|
|
119
118
|
*/
|
|
120
119
|
public resolveRoute(method: string, path: string): Route | undefined {
|
|
121
120
|
method = method.toLowerCase()
|
|
122
|
-
const parts = path.split(
|
|
121
|
+
const parts = path.split('/').filter(p => p.length)
|
|
123
122
|
|
|
124
123
|
return this.routes[method]?.resolveRoute(parts)
|
|
125
124
|
}
|
|
@@ -133,7 +132,7 @@ export default class RouteResolver {
|
|
|
133
132
|
private buildRoutes(config: RouterConfig): void {
|
|
134
133
|
for (const route of config.routes) {
|
|
135
134
|
const method = route.method.toLowerCase()
|
|
136
|
-
const parts = route.path.split(
|
|
135
|
+
const parts = route.path.split('/').filter(p => p.length)
|
|
137
136
|
|
|
138
137
|
this.routes[method] = this.routes[method] || new Routes()
|
|
139
138
|
this.routes[method].addRoute(route, parts)
|
package/src/Server/Router.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { z } from
|
|
1
|
+
import { z } from 'zod'
|
|
2
2
|
|
|
3
|
-
import ContainerServer from
|
|
4
|
-
import Server from
|
|
5
|
-
import { ResponseErrorType } from
|
|
6
|
-
import Utils from
|
|
7
|
-
import Transaction, {
|
|
8
|
-
TransactionConfig,
|
|
9
|
-
TransactionExecution,
|
|
10
|
-
} from "../BaseEvent/Transaction"
|
|
3
|
+
import ContainerServer from './lib/ContainerServer'
|
|
4
|
+
import Server from './lib/Server'
|
|
5
|
+
import { ResponseErrorType } from '../API/Response'
|
|
6
|
+
import Utils from '../API/Utils'
|
|
7
|
+
import Transaction, { TransactionConfig, TransactionExecution } from '../BaseEvent/Transaction'
|
|
11
8
|
|
|
12
9
|
// Route
|
|
13
10
|
/**
|
|
@@ -110,9 +107,7 @@ export default class Router {
|
|
|
110
107
|
*/
|
|
111
108
|
constructor(config: RouterConfig) {
|
|
112
109
|
this.config = config
|
|
113
|
-
this.server = this.isContainer()
|
|
114
|
-
? new ContainerServer(config)
|
|
115
|
-
: new Server(config)
|
|
110
|
+
this.server = this.isContainer() ? new ContainerServer(config) : new Server(config)
|
|
116
111
|
}
|
|
117
112
|
/**
|
|
118
113
|
* Description placeholder
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import Proxy from
|
|
2
|
-
import Server from
|
|
3
|
-
import { RouterConfig } from
|
|
1
|
+
import Proxy from './container/Proxy'
|
|
2
|
+
import Server from './Server'
|
|
3
|
+
import { RouterConfig } from '../Router'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* ${1:Description placeholder}
|
|
@@ -71,7 +71,7 @@ export default class ContainerServer extends Server {
|
|
|
71
71
|
*/
|
|
72
72
|
private listenProcessEvents() {
|
|
73
73
|
// start process listeners
|
|
74
|
-
process.on(
|
|
75
|
-
process.on(
|
|
74
|
+
process.on('unhandledRejection', this.stop.bind(this)) // listen to exceptions
|
|
75
|
+
process.on('SIGINT', this.stop.bind(this)) // listen on SIGINT signal and gracefully stop the server
|
|
76
76
|
}
|
|
77
77
|
}
|
package/src/Server/lib/Server.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { APIGatewayProxyEvent, Context } from
|
|
2
|
-
import * as pathToRegexp from
|
|
1
|
+
import { APIGatewayProxyEvent, Context } from 'aws-lambda'
|
|
2
|
+
import * as pathToRegexp from 'path-to-regexp'
|
|
3
3
|
|
|
4
|
-
import Request from
|
|
5
|
-
import Response from
|
|
6
|
-
import Transaction from
|
|
7
|
-
import Validator from
|
|
8
|
-
import { RouterConfig } from
|
|
9
|
-
import RouteResolver from
|
|
4
|
+
import Request from '../../API/Request'
|
|
5
|
+
import Response from '../../API/Response'
|
|
6
|
+
import Transaction from '../../BaseEvent/Transaction'
|
|
7
|
+
import Validator from '../../Validation/Validator'
|
|
8
|
+
import { RouterConfig } from '../Router'
|
|
9
|
+
import RouteResolver from '../RouteResolver'
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* ${1:Description placeholder}
|
|
@@ -63,38 +63,26 @@ export default class Server {
|
|
|
63
63
|
* @param {Context} context
|
|
64
64
|
* @returns {*}
|
|
65
65
|
*/
|
|
66
|
-
public async handleServerlessEvent(
|
|
67
|
-
event: APIGatewayProxyEvent,
|
|
68
|
-
context: Context,
|
|
69
|
-
) {
|
|
66
|
+
public async handleServerlessEvent(event: APIGatewayProxyEvent, context: Context) {
|
|
70
67
|
// init transaction
|
|
71
|
-
await new Transaction(event, context, this.config).execute(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// Validate input
|
|
81
|
-
if (route.inputSchema) {
|
|
82
|
-
const validationResp = Validator.validateSchema(
|
|
83
|
-
request.getBody(),
|
|
84
|
-
route.inputSchema,
|
|
85
|
-
)
|
|
86
|
-
if (validationResp && validationResp instanceof Response)
|
|
87
|
-
return validationResp
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
this.parsePathParams(request, route.path)
|
|
91
|
-
// Continue to route handler
|
|
92
|
-
return await route.handler(transaction)
|
|
68
|
+
await new Transaction(event, context, this.config).execute(async transaction => {
|
|
69
|
+
const request = transaction.request
|
|
70
|
+
const route = this.routeResolver.resolveRoute(request.getMethod(), request.getPath())
|
|
71
|
+
if (route) {
|
|
72
|
+
transaction.logger.log('Router accepted route:', route.path)
|
|
73
|
+
// Validate input
|
|
74
|
+
if (route.inputSchema) {
|
|
75
|
+
const validationResp = Validator.validateSchema(request.getBody(), route.inputSchema)
|
|
76
|
+
if (validationResp && validationResp instanceof Response) return validationResp
|
|
93
77
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
78
|
+
|
|
79
|
+
this.parsePathParams(request, route.path)
|
|
80
|
+
// Continue to route handler
|
|
81
|
+
return await route.handler(transaction)
|
|
82
|
+
}
|
|
83
|
+
//No route found :/
|
|
84
|
+
return new Response(404, { err: 'Route not found!' })
|
|
85
|
+
})
|
|
98
86
|
}
|
|
99
87
|
|
|
100
88
|
/**
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import { Request, Response } from
|
|
1
|
+
import { Request, Response } from 'express'
|
|
2
2
|
|
|
3
|
-
import GenericHandlerEvent, {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
import Globals from "../../../Globals"
|
|
8
|
-
import Server from "../Server"
|
|
3
|
+
import GenericHandlerEvent, { GenericHandlerEventResponse } from './GenericHandlerEvent'
|
|
4
|
+
import Utils from '../../../API/Utils'
|
|
5
|
+
import Globals from '../../../Globals'
|
|
6
|
+
import Server from '../Server'
|
|
9
7
|
|
|
10
|
-
export default (serverlessHandler: Server[
|
|
8
|
+
export default (serverlessHandler: Server['handleServerlessEvent']) => {
|
|
11
9
|
return async (request: Request, res: Response) => {
|
|
12
10
|
const startTime = Date.now()
|
|
13
11
|
try {
|
|
@@ -18,7 +16,7 @@ export default (serverlessHandler: Server["handleServerlessEvent"]) => {
|
|
|
18
16
|
// Respond
|
|
19
17
|
processServerlessResponse(invokationResp, res)
|
|
20
18
|
} catch (e) {
|
|
21
|
-
console.error(
|
|
19
|
+
console.error('[Proxy] - Exception during execution!', e)
|
|
22
20
|
console.error(e.stack)
|
|
23
21
|
res.status(Globals.Resp_STATUSCODE_EXCEPTION).json({
|
|
24
22
|
...e,
|
|
@@ -33,10 +31,7 @@ export default (serverlessHandler: Server["handleServerlessEvent"]) => {
|
|
|
33
31
|
* ${1:Description placeholder}
|
|
34
32
|
*
|
|
35
33
|
**/
|
|
36
|
-
const processServerlessResponse = (
|
|
37
|
-
invokation: GenericHandlerEventResponse,
|
|
38
|
-
res: Response,
|
|
39
|
-
) => {
|
|
34
|
+
const processServerlessResponse = (invokation: GenericHandlerEventResponse, res: Response) => {
|
|
40
35
|
// translate answer to http layer
|
|
41
36
|
if (invokation && invokation.err) {
|
|
42
37
|
// err came
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import type { APIGatewayProxyEvent, Context } from
|
|
2
|
-
import * as cuid from
|
|
3
|
-
import { Request } from
|
|
1
|
+
import type { APIGatewayProxyEvent, Context } from 'aws-lambda'
|
|
2
|
+
import * as cuid from 'cuid'
|
|
3
|
+
import { Request } from 'express'
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from "./Utils"
|
|
9
|
-
import Globals from "../../../Globals"
|
|
10
|
-
import Server from "../Server"
|
|
5
|
+
import { parseMultiValueQueryStringParameters, parseQueryStringParameters } from './Utils'
|
|
6
|
+
import Globals from '../../../Globals'
|
|
7
|
+
import Server from '../Server'
|
|
11
8
|
//
|
|
12
9
|
/**
|
|
13
10
|
* ${1:Description placeholder}
|
|
@@ -38,7 +35,7 @@ export default class GenericHandlerEvent {
|
|
|
38
35
|
* @public
|
|
39
36
|
* @type {Server["handleServerlessEvent"]}
|
|
40
37
|
*/
|
|
41
|
-
public serverlessHandler: Server[
|
|
38
|
+
public serverlessHandler: Server['handleServerlessEvent']
|
|
42
39
|
/**
|
|
43
40
|
* Creates an instance of GenericHandlerEvent.
|
|
44
41
|
*
|
|
@@ -46,10 +43,7 @@ export default class GenericHandlerEvent {
|
|
|
46
43
|
* @param {Request} request
|
|
47
44
|
* @param {Server["handleServerlessEvent"]} serverlessHandler
|
|
48
45
|
*/
|
|
49
|
-
constructor(
|
|
50
|
-
request: Request,
|
|
51
|
-
serverlessHandler: Server["handleServerlessEvent"],
|
|
52
|
-
) {
|
|
46
|
+
constructor(request: Request, serverlessHandler: Server['handleServerlessEvent']) {
|
|
53
47
|
this.request = request
|
|
54
48
|
this.serverlessHandler = serverlessHandler
|
|
55
49
|
}
|
|
@@ -66,12 +60,9 @@ export default class GenericHandlerEvent {
|
|
|
66
60
|
try {
|
|
67
61
|
// Build event and context
|
|
68
62
|
const event = this.buildEvent()
|
|
69
|
-
const context = this.buildContext(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
resolve({ err, data })
|
|
73
|
-
},
|
|
74
|
-
)
|
|
63
|
+
const context = this.buildContext(event, (err?: Error | string, data?: any) => {
|
|
64
|
+
resolve({ err, data })
|
|
65
|
+
})
|
|
75
66
|
// Invoke
|
|
76
67
|
await this.serverlessHandler(event, context)
|
|
77
68
|
} catch (e) {
|
|
@@ -93,9 +84,7 @@ export default class GenericHandlerEvent {
|
|
|
93
84
|
httpMethod: this.request.method?.toUpperCase(),
|
|
94
85
|
isBase64Encoded: false,
|
|
95
86
|
multiValueHeaders: <any>(this.request.headers || {}),
|
|
96
|
-
multiValueQueryStringParameters: parseMultiValueQueryStringParameters(
|
|
97
|
-
this.request.url,
|
|
98
|
-
),
|
|
87
|
+
multiValueQueryStringParameters: parseMultiValueQueryStringParameters(this.request.url),
|
|
99
88
|
path: this.request.path,
|
|
100
89
|
pathParameters: null,
|
|
101
90
|
queryStringParameters: this.request.query
|
|
@@ -108,9 +97,7 @@ export default class GenericHandlerEvent {
|
|
|
108
97
|
domainName: null,
|
|
109
98
|
domainPrefix: null,
|
|
110
99
|
extendedRequestId: cuid(),
|
|
111
|
-
httpMethod: this.request.method
|
|
112
|
-
? this.request.method.toUpperCase()
|
|
113
|
-
: null,
|
|
100
|
+
httpMethod: this.request.method ? this.request.method.toUpperCase() : null,
|
|
114
101
|
identity: {
|
|
115
102
|
accessKey: null,
|
|
116
103
|
accountId: process.env.AWS_ACCOUNT_ID || null,
|
|
@@ -124,14 +111,13 @@ export default class GenericHandlerEvent {
|
|
|
124
111
|
cognitoIdentityPoolId: null,
|
|
125
112
|
principalOrgId: null,
|
|
126
113
|
sourceIp:
|
|
127
|
-
<string>this.request.headers?.[
|
|
128
|
-
this.request.socket?.remoteAddress,
|
|
114
|
+
<string>this.request.headers?.['x-forwarded-for'] || this.request.socket?.remoteAddress,
|
|
129
115
|
user: null,
|
|
130
|
-
userAgent: this.request.headers?.[
|
|
116
|
+
userAgent: this.request.headers?.['user-agent'],
|
|
131
117
|
userArn: null,
|
|
132
118
|
},
|
|
133
119
|
path: this.request.path,
|
|
134
|
-
protocol:
|
|
120
|
+
protocol: 'HTTP/1.1',
|
|
135
121
|
requestId: `${cuid()}-${cuid()}`,
|
|
136
122
|
requestTime: new Date().toISOString(),
|
|
137
123
|
requestTimeEpoch: Date.now(),
|
|
@@ -153,7 +139,7 @@ export default class GenericHandlerEvent {
|
|
|
153
139
|
*/
|
|
154
140
|
private buildContext(
|
|
155
141
|
event: APIGatewayProxyEvent,
|
|
156
|
-
callback: (err?: Error | string, data?: any) => void
|
|
142
|
+
callback: (err?: Error | string, data?: any) => void
|
|
157
143
|
): Context {
|
|
158
144
|
return {
|
|
159
145
|
awsRequestId: event.requestContext.requestId,
|
|
@@ -162,12 +148,12 @@ export default class GenericHandlerEvent {
|
|
|
162
148
|
return 0
|
|
163
149
|
},
|
|
164
150
|
done: (err, data) => callback(err, data),
|
|
165
|
-
fail:
|
|
166
|
-
succeed:
|
|
151
|
+
fail: err => callback(err),
|
|
152
|
+
succeed: res => callback(null, res),
|
|
167
153
|
functionName: null,
|
|
168
|
-
functionVersion:
|
|
154
|
+
functionVersion: 'LATEST',
|
|
169
155
|
invokedFunctionArn: null,
|
|
170
|
-
memoryLimitInMB:
|
|
156
|
+
memoryLimitInMB: '-1',
|
|
171
157
|
logGroupName: null,
|
|
172
158
|
logStreamName: null,
|
|
173
159
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
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
14
|
/**
|
|
15
15
|
* ${1:Description placeholder}
|
|
@@ -49,7 +49,7 @@ export default class Proxy {
|
|
|
49
49
|
* @readonly
|
|
50
50
|
* @type {Server["handleServerlessEvent"]}
|
|
51
51
|
*/
|
|
52
|
-
private readonly serverlessHandler: Server[
|
|
52
|
+
private readonly serverlessHandler: Server['handleServerlessEvent']
|
|
53
53
|
/**
|
|
54
54
|
* ${1:Description placeholder}
|
|
55
55
|
*
|
|
@@ -64,10 +64,7 @@ export default class Proxy {
|
|
|
64
64
|
* @param {RouterConfig} config
|
|
65
65
|
* @param {Server["handleServerlessEvent"]} serverlessHandler
|
|
66
66
|
*/
|
|
67
|
-
constructor(
|
|
68
|
-
config: RouterConfig,
|
|
69
|
-
serverlessHandler: Server["handleServerlessEvent"],
|
|
70
|
-
) {
|
|
67
|
+
constructor(config: RouterConfig, serverlessHandler: Server['handleServerlessEvent']) {
|
|
71
68
|
this.stopping = false
|
|
72
69
|
this.config = config
|
|
73
70
|
this.serverlessHandler = serverlessHandler
|
|
@@ -75,8 +72,7 @@ export default class Proxy {
|
|
|
75
72
|
/* Opinionated Express configs */
|
|
76
73
|
this.app.use(express.json())
|
|
77
74
|
// apply cors config
|
|
78
|
-
const corsConfig =
|
|
79
|
-
this.config.cors || Utils.parseObjectNullIfEmpty(process.env.CORS)
|
|
75
|
+
const corsConfig = this.config.cors || Utils.parseObjectNullIfEmpty(process.env.CORS)
|
|
80
76
|
this.app.use(
|
|
81
77
|
cors(
|
|
82
78
|
corsConfig
|
|
@@ -85,8 +81,8 @@ export default class Proxy {
|
|
|
85
81
|
allowedHeaders: corsConfig.headers,
|
|
86
82
|
credentials: !!corsConfig.allowCredentials,
|
|
87
83
|
}
|
|
88
|
-
: {}
|
|
89
|
-
)
|
|
84
|
+
: {}
|
|
85
|
+
)
|
|
90
86
|
)
|
|
91
87
|
|
|
92
88
|
// //This supposedly fix some 502 codes where nodejs socket would hang during
|
|
@@ -126,15 +122,13 @@ export default class Proxy {
|
|
|
126
122
|
* @returns {Promise<void>}
|
|
127
123
|
*/
|
|
128
124
|
private async startListeners(): Promise<void> {
|
|
129
|
-
return new Promise(
|
|
125
|
+
return new Promise(resolve => {
|
|
130
126
|
const port = this.config.port || Globals.Listener_HTTP_DefaultPort
|
|
131
127
|
console.log(`[Proxy] - [STARTING] - v.${appVersion} - :${port}`)
|
|
132
128
|
// Create Server
|
|
133
129
|
this.listener = createServer(this.app)
|
|
134
130
|
// Set defaults
|
|
135
|
-
this.listener.setTimeout(
|
|
136
|
-
this.config.timeout || Globals.Listener_HTTP_DefaultTimeout,
|
|
137
|
-
)
|
|
131
|
+
this.listener.setTimeout(this.config.timeout || Globals.Listener_HTTP_DefaultTimeout)
|
|
138
132
|
// Start Server
|
|
139
133
|
this.listener.listen(port, () => {
|
|
140
134
|
console.log(`[Proxy] - [STARTED]`)
|
|
@@ -153,11 +147,11 @@ export default class Proxy {
|
|
|
153
147
|
private async stopListeners(err?: any) {
|
|
154
148
|
if (this.stopping) return
|
|
155
149
|
this.stopping = true
|
|
156
|
-
console.debug(
|
|
157
|
-
return new Promise(
|
|
158
|
-
this.listener.close(
|
|
159
|
-
if (err || _err) console.log(
|
|
160
|
-
console.log(
|
|
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]')
|
|
161
155
|
process.exit(err || _err ? 1 : 0)
|
|
162
156
|
resolve(null)
|
|
163
157
|
})
|
|
@@ -174,21 +168,15 @@ export default class Proxy {
|
|
|
174
168
|
//runtime proxy is working and responding to calls.
|
|
175
169
|
console.log(
|
|
176
170
|
`[Proxy] - [HEALTH-ROUTE] - ${
|
|
177
|
-
this.config.healthCheckRoute ||
|
|
178
|
-
|
|
179
|
-
}`,
|
|
171
|
+
this.config.healthCheckRoute || Globals.Listener_HTTP_DefaultHealthCheckRoute
|
|
172
|
+
}`
|
|
180
173
|
)
|
|
181
174
|
this.app
|
|
182
|
-
.route(
|
|
183
|
-
this.config.healthCheckRoute ||
|
|
184
|
-
Globals.Listener_HTTP_DefaultHealthCheckRoute,
|
|
185
|
-
)
|
|
175
|
+
.route(this.config.healthCheckRoute || Globals.Listener_HTTP_DefaultHealthCheckRoute)
|
|
186
176
|
.get(HealthHandler)
|
|
187
177
|
//Main route -- We use a wildcard route because is not the job of the runtime and neither
|
|
188
178
|
//the task to deny/constrain routes that invoked this task; all the job is done by the
|
|
189
179
|
//load balancer and we just foward everything we have to the function.
|
|
190
|
-
this.app
|
|
191
|
-
.route(Globals.Listener_HTTP_ProxyRoute)
|
|
192
|
-
.all(GenericHandler(this.serverlessHandler))
|
|
180
|
+
this.app.route(Globals.Listener_HTTP_ProxyRoute).all(GenericHandler(this.serverlessHandler))
|
|
193
181
|
}
|
|
194
182
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
export function parseMultiValueQueryStringParameters(url: string) {
|
|
9
9
|
// dummy placeholder url for the WHATWG URL constructor
|
|
10
10
|
// https://github.com/nodejs/node/issues/12682
|
|
11
|
-
const { searchParams } = new URL(url,
|
|
11
|
+
const { searchParams } = new URL(url, 'http://example')
|
|
12
12
|
//
|
|
13
13
|
if (Array.from(searchParams).length === 0) return {}
|
|
14
14
|
const map = new Map()
|
|
@@ -30,7 +30,7 @@ export function parseMultiValueQueryStringParameters(url: string) {
|
|
|
30
30
|
export function parseQueryStringParameters(url) {
|
|
31
31
|
// dummy placeholder url for the WHATWG URL constructor
|
|
32
32
|
// https://github.com/nodejs/node/issues/12682
|
|
33
|
-
const { searchParams } = new URL(url,
|
|
33
|
+
const { searchParams } = new URL(url, 'http://example')
|
|
34
34
|
if (Array.from(searchParams).length === 0) return null
|
|
35
35
|
return Object.fromEntries(searchParams)
|
|
36
36
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
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
6
|
/**
|
|
7
7
|
* Description placeholder
|
|
@@ -22,7 +22,7 @@ export default class Validator {
|
|
|
22
22
|
*/
|
|
23
23
|
public static validateSchema(
|
|
24
24
|
data: any,
|
|
25
|
-
schema: z.ZodObject<any
|
|
25
|
+
schema: z.ZodObject<any>
|
|
26
26
|
): boolean | Response<ResponseErrorType> {
|
|
27
27
|
let error, validatedInput
|
|
28
28
|
// Validate body against known zod schema
|
|
@@ -30,14 +30,14 @@ export default class Validator {
|
|
|
30
30
|
validatedInput = schema.parse(data) as typeof schema
|
|
31
31
|
} catch (err: z.ZodError | any) {
|
|
32
32
|
if (err instanceof z.ZodError) error = JSON.parse(err.message)
|
|
33
|
-
else error =
|
|
33
|
+
else error = 'Unknown validation error!' //unhandled case, hard to test
|
|
34
34
|
}
|
|
35
35
|
// Error validation
|
|
36
36
|
if (!validatedInput || error) {
|
|
37
37
|
return Response.BadRequestResponse(
|
|
38
38
|
Globals.ErrorResponseValidationFail,
|
|
39
39
|
Globals.ErrorCode_InvalidInput,
|
|
40
|
-
{ validationFailure: error }
|
|
40
|
+
{ validationFailure: error }
|
|
41
41
|
)
|
|
42
42
|
} else {
|
|
43
43
|
return true
|