@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
|
@@ -3,20 +3,55 @@ 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
|
+
/**
|
|
11
|
+
* ${1:Description placeholder}
|
|
12
|
+
*
|
|
13
|
+
* @type {(SNSClient | null)}
|
|
14
|
+
*/
|
|
15
|
+
let PUBLISHER_CONN: SNSClient | null = null
|
|
11
16
|
// eslint-disable-next-line no-var
|
|
12
|
-
|
|
17
|
+
/**
|
|
18
|
+
* ${1:Description placeholder}
|
|
19
|
+
*
|
|
20
|
+
* @type {(string | null)}
|
|
21
|
+
*/
|
|
22
|
+
let PUBLISHER_CONN_HASH: string | null = null
|
|
13
23
|
//
|
|
24
|
+
/**
|
|
25
|
+
* ${1:Description placeholder}
|
|
26
|
+
*
|
|
27
|
+
* @export
|
|
28
|
+
* @typedef {PublisherConfig}
|
|
29
|
+
*/
|
|
14
30
|
export type PublisherConfig = {
|
|
15
31
|
region?: string
|
|
16
32
|
}
|
|
17
33
|
//
|
|
34
|
+
/**
|
|
35
|
+
* ${1:Description placeholder}
|
|
36
|
+
*
|
|
37
|
+
* @export
|
|
38
|
+
* @class Publisher
|
|
39
|
+
* @typedef {Publisher}
|
|
40
|
+
*/
|
|
18
41
|
export default class Publisher {
|
|
42
|
+
/**
|
|
43
|
+
* ${1:Description placeholder}
|
|
44
|
+
*
|
|
45
|
+
* @private
|
|
46
|
+
* @type {string}
|
|
47
|
+
*/
|
|
19
48
|
private region: string
|
|
49
|
+
/**
|
|
50
|
+
* Creates an instance of Publisher.
|
|
51
|
+
*
|
|
52
|
+
* @constructor
|
|
53
|
+
* @param {?PublisherConfig} [config]
|
|
54
|
+
*/
|
|
20
55
|
constructor(config?: PublisherConfig) {
|
|
21
56
|
if (config && config.region) {
|
|
22
57
|
this.region = config.region
|
|
@@ -24,10 +59,19 @@ export default class Publisher {
|
|
|
24
59
|
}
|
|
25
60
|
}
|
|
26
61
|
/* Public */
|
|
62
|
+
/**
|
|
63
|
+
* ${1:Description placeholder}
|
|
64
|
+
*
|
|
65
|
+
* @async
|
|
66
|
+
* @param {*} messageObject
|
|
67
|
+
* @param {string} topic
|
|
68
|
+
* @param {?object} [additionalProps]
|
|
69
|
+
* @returns {Promise<PublishCommandOutput>}
|
|
70
|
+
*/
|
|
27
71
|
async publishOnTopic(
|
|
28
72
|
messageObject: any,
|
|
29
73
|
topic: string,
|
|
30
|
-
additionalProps?: object
|
|
74
|
+
additionalProps?: object
|
|
31
75
|
): Promise<PublishCommandOutput> {
|
|
32
76
|
let resp: null | PublishCommandOutput = null
|
|
33
77
|
try {
|
|
@@ -38,24 +82,21 @@ export default class Publisher {
|
|
|
38
82
|
TopicArn: topic,
|
|
39
83
|
...(additionalProps ? additionalProps : {}),
|
|
40
84
|
}
|
|
41
|
-
|
|
42
|
-
resp = await PUBLISHER_CONN.send(new PublishCommand(params))
|
|
85
|
+
resp = await PUBLISHER_CONN.send(new PublishCommand(params))
|
|
43
86
|
} catch (e) {
|
|
44
|
-
console.error(
|
|
45
|
-
`Error while publishing into topic ${topic} with error: ${e}`,
|
|
46
|
-
)
|
|
87
|
+
console.error(`Error while publishing into topic ${topic} with error: ${e}`)
|
|
47
88
|
}
|
|
48
|
-
console.debug(
|
|
89
|
+
console.debug('Publisher resp', resp)
|
|
49
90
|
return resp
|
|
50
91
|
}
|
|
51
92
|
/* Private */
|
|
93
|
+
/**
|
|
94
|
+
* ${1:Description placeholder}
|
|
95
|
+
*/
|
|
52
96
|
_connect() {
|
|
53
|
-
if (
|
|
54
|
-
(!PUBLISHER_CONN && !PUBLISHER_CONN_HASH) ||
|
|
55
|
-
PUBLISHER_CONN_HASH != sha1(this.region)
|
|
56
|
-
) {
|
|
97
|
+
if ((!PUBLISHER_CONN && !PUBLISHER_CONN_HASH) || PUBLISHER_CONN_HASH != sha1(this.region)) {
|
|
57
98
|
PUBLISHER_CONN = new SNSClient({
|
|
58
|
-
apiVersion:
|
|
99
|
+
apiVersion: '2010-03-31',
|
|
59
100
|
region: this.region,
|
|
60
101
|
})
|
|
61
102
|
PUBLISHER_CONN_HASH = sha1(this.region).toString()
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { Route, RouterConfig } from './Router'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ${1:Description placeholder}
|
|
5
|
+
*
|
|
6
|
+
* @class Routes
|
|
7
|
+
* @typedef {Routes}
|
|
8
|
+
*/
|
|
9
|
+
class Routes {
|
|
10
|
+
/**
|
|
11
|
+
* ${1:Description placeholder}
|
|
12
|
+
*
|
|
13
|
+
* @private
|
|
14
|
+
* @type {?Route}
|
|
15
|
+
*/
|
|
16
|
+
private current?: Route
|
|
17
|
+
/**
|
|
18
|
+
* ${1:Description placeholder}
|
|
19
|
+
*
|
|
20
|
+
* @private
|
|
21
|
+
* @type {?Routes}
|
|
22
|
+
*/
|
|
23
|
+
private variable?: Routes
|
|
24
|
+
/**
|
|
25
|
+
* ${1:Description placeholder}
|
|
26
|
+
*
|
|
27
|
+
* @private
|
|
28
|
+
* @readonly
|
|
29
|
+
* @type {{ [k: string]: Routes }\}
|
|
30
|
+
*/
|
|
31
|
+
private readonly next: { [k: string]: Routes }
|
|
32
|
+
/**
|
|
33
|
+
* Creates an instance of Routes.
|
|
34
|
+
*
|
|
35
|
+
* @constructor
|
|
36
|
+
*/
|
|
37
|
+
constructor() {
|
|
38
|
+
this.next = {}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* ${1:Description placeholder}
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
* @param {Route} route
|
|
46
|
+
* @param {string[]} parts
|
|
47
|
+
*/
|
|
48
|
+
public addRoute(route: Route, parts: string[]): void {
|
|
49
|
+
const first = parts.shift()
|
|
50
|
+
if (first) {
|
|
51
|
+
if (first.startsWith(':')) {
|
|
52
|
+
this.variable = this.variable || new Routes()
|
|
53
|
+
this.variable.addRoute(route, parts)
|
|
54
|
+
} else {
|
|
55
|
+
this.next[first] = this.next[first] || new Routes()
|
|
56
|
+
this.next[first].addRoute(route, parts)
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
if (this.current) throw new Error(`Duplicate route: ${route.method}: ${route.path}`)
|
|
60
|
+
|
|
61
|
+
this.current = route
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* ${1:Description placeholder}
|
|
67
|
+
*
|
|
68
|
+
* @public
|
|
69
|
+
* @param {string[]} parts
|
|
70
|
+
* @returns {Route}
|
|
71
|
+
*/
|
|
72
|
+
public resolveRoute(parts: string[]): Route {
|
|
73
|
+
const first = parts.shift()
|
|
74
|
+
if (first) {
|
|
75
|
+
if (first in this.next) {
|
|
76
|
+
return this.next[first].resolveRoute(parts)
|
|
77
|
+
}
|
|
78
|
+
return this.variable?.resolveRoute(parts)
|
|
79
|
+
}
|
|
80
|
+
return this.current
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* ${1:Description placeholder}
|
|
86
|
+
*
|
|
87
|
+
* @export
|
|
88
|
+
* @class RouteResolver
|
|
89
|
+
* @typedef {RouteResolver}
|
|
90
|
+
*/
|
|
91
|
+
export default class RouteResolver {
|
|
92
|
+
/**
|
|
93
|
+
* ${1:Description placeholder}
|
|
94
|
+
*
|
|
95
|
+
* @private
|
|
96
|
+
* @type {{ [method: string]: Routes }\}
|
|
97
|
+
*/
|
|
98
|
+
private routes: { [method: string]: Routes }
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Creates an instance of RouteResolver.
|
|
102
|
+
*
|
|
103
|
+
* @constructor
|
|
104
|
+
* @param {RouterConfig} config
|
|
105
|
+
*/
|
|
106
|
+
constructor(readonly config: RouterConfig) {
|
|
107
|
+
this.routes = {}
|
|
108
|
+
this.buildRoutes(config)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* ${1:Description placeholder}
|
|
113
|
+
*
|
|
114
|
+
* @public
|
|
115
|
+
* @param {string} method
|
|
116
|
+
* @param {string} path
|
|
117
|
+
* @returns {(Route | undefined)}
|
|
118
|
+
*/
|
|
119
|
+
public resolveRoute(method: string, path: string): Route | undefined {
|
|
120
|
+
method = method.toLowerCase()
|
|
121
|
+
const parts = path.split('/').filter(p => p.length)
|
|
122
|
+
|
|
123
|
+
return this.routes[method]?.resolveRoute(parts)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Description placeholder
|
|
128
|
+
*
|
|
129
|
+
* @private
|
|
130
|
+
* @param {RouterConfig} config
|
|
131
|
+
*/
|
|
132
|
+
private buildRoutes(config: RouterConfig): void {
|
|
133
|
+
for (const route of config.routes) {
|
|
134
|
+
const method = route.method.toLowerCase()
|
|
135
|
+
const parts = route.path.split('/').filter(p => p.length)
|
|
136
|
+
|
|
137
|
+
this.routes[method] = this.routes[method] || new Routes()
|
|
138
|
+
this.routes[method].addRoute(route, parts)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
package/src/Server/Router.ts
CHANGED
|
@@ -1,17 +1,33 @@
|
|
|
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
|
|
10
|
+
/**
|
|
11
|
+
* Description placeholder
|
|
12
|
+
*
|
|
13
|
+
* @export
|
|
14
|
+
* @interface Route
|
|
15
|
+
* @typedef {Route}
|
|
16
|
+
* @template [InputType=any]
|
|
17
|
+
* @template [OutputType=any]
|
|
18
|
+
*/
|
|
13
19
|
export interface Route<InputType = any, OutputType = any> {
|
|
20
|
+
/**
|
|
21
|
+
* Description placeholder
|
|
22
|
+
*
|
|
23
|
+
* @type {string}
|
|
24
|
+
*/
|
|
14
25
|
path: string
|
|
26
|
+
/**
|
|
27
|
+
* Description placeholder
|
|
28
|
+
*
|
|
29
|
+
* @type {string}
|
|
30
|
+
*/
|
|
15
31
|
method: string
|
|
16
32
|
/* If you are here to know why implementing this method
|
|
17
33
|
does not auto infer the param type, check long discussion on TS
|
|
@@ -19,14 +35,33 @@ export interface Route<InputType = any, OutputType = any> {
|
|
|
19
35
|
- https://github.com/microsoft/TypeScript/issues/23911#issuecomment-1351020050 (proposed solution)
|
|
20
36
|
- https://github.com/microsoft/TypeScript/issues/10570
|
|
21
37
|
*/
|
|
38
|
+
/**
|
|
39
|
+
* Description placeholder
|
|
40
|
+
*
|
|
41
|
+
* @type {TransactionExecution<
|
|
42
|
+
* Transaction<InputType, OutputType | ResponseErrorType>,
|
|
43
|
+
* OutputType | ResponseErrorType
|
|
44
|
+
* >}
|
|
45
|
+
*/
|
|
22
46
|
handler: TransactionExecution<
|
|
23
47
|
Transaction<InputType, OutputType | ResponseErrorType>,
|
|
24
48
|
OutputType | ResponseErrorType
|
|
25
49
|
>
|
|
50
|
+
/**
|
|
51
|
+
* Description placeholder
|
|
52
|
+
*
|
|
53
|
+
* @type {?z.ZodObject<any>}
|
|
54
|
+
*/
|
|
26
55
|
inputSchema?: z.ZodObject<any>
|
|
27
56
|
}
|
|
28
57
|
|
|
29
58
|
// Config
|
|
59
|
+
/**
|
|
60
|
+
* Description placeholder
|
|
61
|
+
*
|
|
62
|
+
* @export
|
|
63
|
+
* @typedef {RouterConfig}
|
|
64
|
+
*/
|
|
30
65
|
export type RouterConfig = TransactionConfig & {
|
|
31
66
|
routes: Route[]
|
|
32
67
|
// container based configs - otherwise enforced by serverless engine
|
|
@@ -40,18 +75,55 @@ export type RouterConfig = TransactionConfig & {
|
|
|
40
75
|
healthCheckRoute?: string
|
|
41
76
|
}
|
|
42
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Description placeholder
|
|
80
|
+
*
|
|
81
|
+
* @export
|
|
82
|
+
* @class Router
|
|
83
|
+
* @typedef {Router}
|
|
84
|
+
*/
|
|
43
85
|
export default class Router {
|
|
86
|
+
/**
|
|
87
|
+
* Description placeholder
|
|
88
|
+
*
|
|
89
|
+
* @private
|
|
90
|
+
* @readonly
|
|
91
|
+
* @type {RouterConfig}
|
|
92
|
+
*/
|
|
44
93
|
private readonly config: RouterConfig
|
|
94
|
+
/**
|
|
95
|
+
* Description placeholder
|
|
96
|
+
*
|
|
97
|
+
* @private
|
|
98
|
+
* @readonly
|
|
99
|
+
* @type {Server}
|
|
100
|
+
*/
|
|
45
101
|
private readonly server: Server
|
|
102
|
+
/**
|
|
103
|
+
* Creates an instance of Router.
|
|
104
|
+
*
|
|
105
|
+
* @constructor
|
|
106
|
+
* @param {RouterConfig} config
|
|
107
|
+
*/
|
|
46
108
|
constructor(config: RouterConfig) {
|
|
47
109
|
this.config = config
|
|
48
|
-
this.server = this.isContainer()
|
|
49
|
-
? new ContainerServer(config)
|
|
50
|
-
: new Server(config)
|
|
110
|
+
this.server = this.isContainer() ? new ContainerServer(config) : new Server(config)
|
|
51
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Description placeholder
|
|
114
|
+
*
|
|
115
|
+
* @public
|
|
116
|
+
* @returns {CallableFunction}
|
|
117
|
+
*/
|
|
52
118
|
public getExport(): CallableFunction {
|
|
53
119
|
return this.server.getExport()
|
|
54
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Description placeholder
|
|
123
|
+
*
|
|
124
|
+
* @private
|
|
125
|
+
* @returns {boolean}
|
|
126
|
+
*/
|
|
55
127
|
private isContainer(): boolean {
|
|
56
128
|
return Utils.isHybridlessContainer()
|
|
57
129
|
}
|
|
@@ -1,14 +1,41 @@
|
|
|
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
|
+
/**
|
|
6
|
+
* ${1:Description placeholder}
|
|
7
|
+
*
|
|
8
|
+
* @export
|
|
9
|
+
* @class ContainerServer
|
|
10
|
+
* @typedef {ContainerServer}
|
|
11
|
+
* @extends {Server}
|
|
12
|
+
*/
|
|
5
13
|
export default class ContainerServer extends Server {
|
|
14
|
+
/**
|
|
15
|
+
* ${1:Description placeholder}
|
|
16
|
+
*
|
|
17
|
+
* @protected
|
|
18
|
+
* @readonly
|
|
19
|
+
* @type {Proxy}
|
|
20
|
+
*/
|
|
6
21
|
protected readonly proxy: Proxy
|
|
22
|
+
/**
|
|
23
|
+
* Creates an instance of ContainerServer.
|
|
24
|
+
*
|
|
25
|
+
* @constructor
|
|
26
|
+
* @param {RouterConfig} config
|
|
27
|
+
*/
|
|
7
28
|
constructor(config: RouterConfig) {
|
|
8
29
|
super(config)
|
|
9
30
|
this.proxy = new Proxy(config, this.handleServerlessEvent.bind(this))
|
|
10
31
|
this.listenProcessEvents()
|
|
11
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* ${1:Description placeholder}
|
|
35
|
+
*
|
|
36
|
+
* @public
|
|
37
|
+
* @returns {CallableFunction}
|
|
38
|
+
*/
|
|
12
39
|
public getExport(): CallableFunction {
|
|
13
40
|
// start server socket
|
|
14
41
|
this.start()
|
|
@@ -16,15 +43,35 @@ export default class ContainerServer extends Server {
|
|
|
16
43
|
return () => {}
|
|
17
44
|
}
|
|
18
45
|
/* private */
|
|
46
|
+
/**
|
|
47
|
+
* ${1:Description placeholder}
|
|
48
|
+
*
|
|
49
|
+
* @public
|
|
50
|
+
* @async
|
|
51
|
+
* @returns {*}
|
|
52
|
+
*/
|
|
19
53
|
public async start() {
|
|
20
54
|
await this.proxy.load()
|
|
21
55
|
}
|
|
22
|
-
|
|
56
|
+
/**
|
|
57
|
+
* ${1:Description placeholder}
|
|
58
|
+
*
|
|
59
|
+
* @public
|
|
60
|
+
* @async
|
|
61
|
+
* @param {?*} [err]
|
|
62
|
+
* @returns {*}
|
|
63
|
+
*/
|
|
64
|
+
public async stop(err?: any) {
|
|
23
65
|
await this.proxy.unload(err)
|
|
24
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* ${1:Description placeholder}
|
|
69
|
+
*
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
25
72
|
private listenProcessEvents() {
|
|
26
73
|
// start process listeners
|
|
27
|
-
process.on(
|
|
28
|
-
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
|
|
29
76
|
}
|
|
30
77
|
}
|
package/src/Server/lib/Server.ts
CHANGED
|
@@ -1,73 +1,101 @@
|
|
|
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
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
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'
|
|
8
10
|
|
|
11
|
+
/**
|
|
12
|
+
* ${1:Description placeholder}
|
|
13
|
+
*
|
|
14
|
+
* @export
|
|
15
|
+
* @class Server
|
|
16
|
+
* @typedef {Server}
|
|
17
|
+
*/
|
|
9
18
|
export default class Server {
|
|
19
|
+
/**
|
|
20
|
+
* ${1:Description placeholder}
|
|
21
|
+
*
|
|
22
|
+
* @protected
|
|
23
|
+
* @readonly
|
|
24
|
+
* @type {RouterConfig}
|
|
25
|
+
*/
|
|
10
26
|
protected readonly config: RouterConfig
|
|
27
|
+
/**
|
|
28
|
+
* ${1:Description placeholder}
|
|
29
|
+
*
|
|
30
|
+
* @protected
|
|
31
|
+
* @readonly
|
|
32
|
+
* @type {RouteResolver}
|
|
33
|
+
*/
|
|
34
|
+
protected readonly routeResolver: RouteResolver
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Creates an instance of Server.
|
|
38
|
+
*
|
|
39
|
+
* @constructor
|
|
40
|
+
* @param {RouterConfig} config
|
|
41
|
+
*/
|
|
11
42
|
constructor(config: RouterConfig) {
|
|
12
43
|
this.config = config
|
|
44
|
+
this.routeResolver = new RouteResolver(config)
|
|
13
45
|
}
|
|
14
46
|
|
|
47
|
+
/**
|
|
48
|
+
* ${1:Description placeholder}
|
|
49
|
+
*
|
|
50
|
+
* @public
|
|
51
|
+
* @returns {CallableFunction}
|
|
52
|
+
*/
|
|
15
53
|
public getExport(): CallableFunction {
|
|
16
54
|
return this.handleServerlessEvent.bind(this)
|
|
17
55
|
}
|
|
18
56
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
57
|
+
/**
|
|
58
|
+
* ${1:Description placeholder}
|
|
59
|
+
*
|
|
60
|
+
* @public
|
|
61
|
+
* @async
|
|
62
|
+
* @param {APIGatewayProxyEvent} event
|
|
63
|
+
* @param {Context} context
|
|
64
|
+
* @returns {*}
|
|
65
|
+
*/
|
|
66
|
+
public async handleServerlessEvent(event: APIGatewayProxyEvent, context: Context) {
|
|
24
67
|
// init transaction
|
|
25
|
-
await new Transaction(event, context, config).execute(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
)
|
|
34
|
-
if (handler) {
|
|
35
|
-
transaction.logger.log("Router accepted route:", route.path)
|
|
36
|
-
// Validate input
|
|
37
|
-
if (route.inputSchema) {
|
|
38
|
-
const validationResp = Validator.validateSchema(
|
|
39
|
-
transaction.request.getBody(),
|
|
40
|
-
route.inputSchema,
|
|
41
|
-
)
|
|
42
|
-
if (validationResp && validationResp instanceof Response)
|
|
43
|
-
return validationResp
|
|
44
|
-
}
|
|
45
|
-
// Continue to route handler
|
|
46
|
-
return await route.handler(transaction)
|
|
47
|
-
}
|
|
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
|
|
48
77
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
+
})
|
|
53
86
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* ${1:Description placeholder}
|
|
90
|
+
*
|
|
91
|
+
* @private
|
|
92
|
+
* @param {Request<any>} req
|
|
93
|
+
* @param {string} routePath
|
|
94
|
+
*/
|
|
95
|
+
private parsePathParams(req: Request<any>, routePath: string) {
|
|
96
|
+
const path = req.getPath()
|
|
61
97
|
const keys = []
|
|
62
98
|
const result = pathToRegexp(routePath, keys).exec(path)
|
|
63
|
-
|
|
64
|
-
const reqMethod = transaction.request.getMethod()
|
|
65
|
-
if (reqMethod.toLowerCase() == routeMethod.toLowerCase()) {
|
|
66
|
-
//Fix path params on proxy
|
|
67
|
-
transaction.request.setFixedPathParams(keys, result)
|
|
68
|
-
return true
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return false
|
|
99
|
+
req.setFixedPathParams(keys, result)
|
|
72
100
|
}
|
|
73
101
|
}
|
|
@@ -1,40 +1,37 @@
|
|
|
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
|
-
let resp = null
|
|
14
11
|
try {
|
|
15
12
|
// Generate event with request stuff (http to serverless translation)
|
|
16
13
|
const event = new GenericHandlerEvent(request, serverlessHandler)
|
|
17
14
|
// Invoke
|
|
18
15
|
const invokationResp = await event.invoke()
|
|
19
16
|
// Respond
|
|
20
|
-
|
|
17
|
+
processServerlessResponse(invokationResp, res)
|
|
21
18
|
} catch (e) {
|
|
22
|
-
console.error(
|
|
19
|
+
console.error('[Proxy] - Exception during execution!', e)
|
|
23
20
|
console.error(e.stack)
|
|
24
|
-
|
|
21
|
+
res.status(Globals.Resp_STATUSCODE_EXCEPTION).json({
|
|
25
22
|
...e,
|
|
26
23
|
err: Globals.Resp_MSG_EXCEPTION,
|
|
27
24
|
errCode: Globals.Resp_CODE_EXCEPTION,
|
|
28
25
|
})
|
|
29
26
|
}
|
|
30
27
|
console.debug(`[Proxy] - Request took ${Date.now() - startTime}ms`)
|
|
31
|
-
return resp
|
|
32
28
|
}
|
|
33
29
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
/**
|
|
31
|
+
* ${1:Description placeholder}
|
|
32
|
+
*
|
|
33
|
+
**/
|
|
34
|
+
const processServerlessResponse = (invokation: GenericHandlerEventResponse, res: Response) => {
|
|
38
35
|
// translate answer to http layer
|
|
39
36
|
if (invokation && invokation.err) {
|
|
40
37
|
// err came
|
|
@@ -47,7 +44,7 @@ const processServerlessResponse = (
|
|
|
47
44
|
})
|
|
48
45
|
} else {
|
|
49
46
|
// Check for headers
|
|
50
|
-
if (invokation
|
|
47
|
+
if (invokation.data.headers) {
|
|
51
48
|
for (const hKey of Object.keys(invokation.data.headers)) {
|
|
52
49
|
res.header(hKey, invokation.data.headers[hKey])
|
|
53
50
|
}
|