@creator.co/wapi 1.2.1-beta5 → 1.2.2
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 +11 -19
- package/.github/workflows/prs.yml +13 -0
- package/jest.config.ts +39 -0
- package/package.json +15 -4
- package/src/API/Request.ts +120 -10
- package/src/API/Response.ts +236 -8
- package/src/API/Utils.ts +56 -1
- package/src/BaseEvent/EventProcessor.ts +84 -11
- package/src/BaseEvent/Process.ts +62 -1
- package/src/BaseEvent/Transaction.ts +5 -8
- package/src/Config/Configuration.ts +111 -5
- package/src/Config/EnvironmentVar.ts +90 -1
- package/src/Crypto/Crypto.ts +77 -18
- package/src/Crypto/JWT.ts +49 -3
- package/src/Globals.ts +141 -3
- package/src/Logger/Logger.ts +173 -19
- package/src/Mailer/Mailer.ts +95 -0
- package/src/Publisher/Publisher.ts +50 -4
- package/src/Server/RouteResolver.ts +142 -0
- package/src/Server/Router.ts +77 -0
- package/src/Server/lib/ContainerServer.ts +48 -1
- package/src/Server/lib/Server.ts +78 -38
- package/src/Server/lib/container/GenericHandler.ts +7 -5
- package/src/Server/lib/container/GenericHandlerEvent.ts +59 -17
- package/src/Server/lib/container/HealthHandler.ts +1 -1
- package/src/Server/lib/container/Proxy.ts +92 -11
- package/src/Server/lib/container/Utils.ts +16 -25
- package/src/Validation/Validator.ts +18 -2
- package/tests/API/Request.test.ts +263 -0
- package/tests/API/Response.test.ts +372 -0
- package/tests/API/Utils.test.ts +157 -0
- package/tests/BaseEvent/EventProcessor.test.ts +278 -0
- package/tests/BaseEvent/Process.test.ts +49 -0
- package/tests/BaseEvent/Transaction.test.ts +231 -0
- package/tests/Config/Config.test.ts +193 -0
- package/tests/Config/EnvironmentVar.test.ts +223 -0
- package/tests/Crypto/Crypto.test.ts +90 -0
- package/tests/Crypto/JWT.test.ts +92 -0
- package/tests/Logger/Logger.test.ts +108 -0
- package/tests/Mailer/Mailer.test.ts +67 -0
- package/tests/Publisher/Publisher.test.ts +60 -0
- package/tests/Server/RouteResolver.test.ts +106 -0
- package/tests/Server/Router.test.ts +38 -0
- package/tests/Server/lib/ContainerServer.test.ts +329 -0
- package/tests/Server/lib/Server.test.ts +12 -0
- package/tests/Server/lib/container/GenericHandler.test.ts +141 -0
- package/tests/Server/lib/container/GenericHandlerEvent.test.ts +103 -0
- package/tests/Server/lib/container/HealthHandler.test.ts +30 -0
- package/tests/Server/lib/container/Proxy.test.ts +278 -0
- package/tests/Server/lib/container/Utils.test.ts +48 -0
- package/tests/Test.utils.ts +95 -0
- package/tests/Validation/Validator.test.ts +88 -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
package/src/Mailer/Mailer.ts
CHANGED
|
@@ -4,12 +4,49 @@ import * as Email from "email-templates"
|
|
|
4
4
|
import * as nodemailer from "nodemailer"
|
|
5
5
|
import type * as SESTransport from "nodemailer/lib/ses-transport"
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* ${1:Description placeholder}
|
|
9
|
+
*
|
|
10
|
+
* @export
|
|
11
|
+
* @class Mailer
|
|
12
|
+
* @typedef {Mailer}
|
|
13
|
+
*/
|
|
7
14
|
export default class Mailer {
|
|
15
|
+
/**
|
|
16
|
+
* ${1:Description placeholder}
|
|
17
|
+
*
|
|
18
|
+
* @private
|
|
19
|
+
* @readonly
|
|
20
|
+
* @type {string}
|
|
21
|
+
*/
|
|
8
22
|
private readonly from: string
|
|
23
|
+
/**
|
|
24
|
+
* ${1:Description placeholder}
|
|
25
|
+
*
|
|
26
|
+
* @private
|
|
27
|
+
* @readonly
|
|
28
|
+
* @type {string}
|
|
29
|
+
*/
|
|
9
30
|
private readonly templateDefaultFile: string = "html"
|
|
31
|
+
/**
|
|
32
|
+
* ${1:Description placeholder}
|
|
33
|
+
*
|
|
34
|
+
* @private
|
|
35
|
+
* @readonly
|
|
36
|
+
* @type {ReturnType<
|
|
37
|
+
* typeof nodemailer.createTransport<SESTransport.SentMessageInfo>
|
|
38
|
+
* >}
|
|
39
|
+
*/
|
|
10
40
|
private readonly transporter: ReturnType<
|
|
11
41
|
typeof nodemailer.createTransport<SESTransport.SentMessageInfo>
|
|
12
42
|
>
|
|
43
|
+
/**
|
|
44
|
+
* Creates an instance of Mailer.
|
|
45
|
+
*
|
|
46
|
+
* @constructor
|
|
47
|
+
* @param {string} defaultFrom
|
|
48
|
+
* @param {string} region
|
|
49
|
+
*/
|
|
13
50
|
constructor(defaultFrom: string, region: string) {
|
|
14
51
|
this.from = defaultFrom
|
|
15
52
|
this.transporter = nodemailer.createTransport({
|
|
@@ -24,6 +61,21 @@ export default class Mailer {
|
|
|
24
61
|
})
|
|
25
62
|
}
|
|
26
63
|
|
|
64
|
+
/**
|
|
65
|
+
* ${1:Description placeholder}
|
|
66
|
+
*
|
|
67
|
+
* @public
|
|
68
|
+
* @async
|
|
69
|
+
* @param {(string | Array<string>)} to
|
|
70
|
+
* @param {string} htmlMessage
|
|
71
|
+
* @param {string} subject
|
|
72
|
+
* @param {?(string | Array<string>)} [optionalCC]
|
|
73
|
+
* @param {?string} [optionalFrom]
|
|
74
|
+
* @param {?string} [optionalReplyTo]
|
|
75
|
+
* @param {?any[]} [optionalAttachments]
|
|
76
|
+
* @param {?Email.NodeMailerTransportOptions} [optionalTransport]
|
|
77
|
+
* @returns {unknown}
|
|
78
|
+
*/
|
|
27
79
|
public async sendRawEmail(
|
|
28
80
|
to: string | Array<string>,
|
|
29
81
|
htmlMessage: string,
|
|
@@ -60,6 +112,21 @@ export default class Mailer {
|
|
|
60
112
|
}
|
|
61
113
|
return resp
|
|
62
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* ${1:Description placeholder}
|
|
117
|
+
*
|
|
118
|
+
* @public
|
|
119
|
+
* @async
|
|
120
|
+
* @param {(string | Array<string>)} to
|
|
121
|
+
* @param {(string | Array<string>)} templates
|
|
122
|
+
* @param {object} data
|
|
123
|
+
* @param {?(string | Array<string>)} [optionalCC]
|
|
124
|
+
* @param {?string} [optionalFrom]
|
|
125
|
+
* @param {?string} [optionalReplyTo]
|
|
126
|
+
* @param {?any[]} [optionalAttachments]
|
|
127
|
+
* @param {?Email.NodeMailerTransportOptions} [optionalTransport]
|
|
128
|
+
* @returns {unknown}
|
|
129
|
+
*/
|
|
63
130
|
public async sendTemplatedEmail(
|
|
64
131
|
to: string | Array<string>,
|
|
65
132
|
templates: string | Array<string>,
|
|
@@ -95,6 +162,16 @@ export default class Mailer {
|
|
|
95
162
|
}
|
|
96
163
|
return resp
|
|
97
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* ${1:Description placeholder}
|
|
167
|
+
*
|
|
168
|
+
* @public
|
|
169
|
+
* @param {string} host
|
|
170
|
+
* @param {number} portNumber
|
|
171
|
+
* @param {string} user
|
|
172
|
+
* @param {string} password
|
|
173
|
+
* @returns {Email.NodeMailerTransportOptions}
|
|
174
|
+
*/
|
|
98
175
|
public newSMTPTransporter(
|
|
99
176
|
host: string,
|
|
100
177
|
portNumber: number,
|
|
@@ -114,6 +191,15 @@ export default class Mailer {
|
|
|
114
191
|
}
|
|
115
192
|
|
|
116
193
|
/* private */
|
|
194
|
+
/**
|
|
195
|
+
* ${1:Description placeholder}
|
|
196
|
+
*
|
|
197
|
+
* @private
|
|
198
|
+
* @async
|
|
199
|
+
* @param {(string | Array<string>)} templates
|
|
200
|
+
* @param {object} data
|
|
201
|
+
* @returns {Promise<string>}
|
|
202
|
+
*/
|
|
117
203
|
private async chooseTemplate(
|
|
118
204
|
templates: string | Array<string>,
|
|
119
205
|
data: object,
|
|
@@ -131,6 +217,15 @@ export default class Mailer {
|
|
|
131
217
|
JSON.stringify(data, null, 2),
|
|
132
218
|
)
|
|
133
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* ${1:Description placeholder}
|
|
222
|
+
*
|
|
223
|
+
* @private
|
|
224
|
+
* @async
|
|
225
|
+
* @param {string} template
|
|
226
|
+
* @param {object} data
|
|
227
|
+
* @returns {Promise<boolean>}
|
|
228
|
+
*/
|
|
134
229
|
private async canRenderTemplate(
|
|
135
230
|
template: string,
|
|
136
231
|
data: object,
|
|
@@ -7,16 +7,51 @@ import {
|
|
|
7
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,6 +59,15 @@ 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,
|
|
@@ -38,8 +82,7 @@ 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
87
|
console.error(
|
|
45
88
|
`Error while publishing into topic ${topic} with error: ${e}`,
|
|
@@ -49,6 +92,9 @@ export default class Publisher {
|
|
|
49
92
|
return resp
|
|
50
93
|
}
|
|
51
94
|
/* Private */
|
|
95
|
+
/**
|
|
96
|
+
* ${1:Description placeholder}
|
|
97
|
+
*/
|
|
52
98
|
_connect() {
|
|
53
99
|
if (
|
|
54
100
|
(!PUBLISHER_CONN && !PUBLISHER_CONN_HASH) ||
|
|
@@ -0,0 +1,142 @@
|
|
|
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)
|
|
60
|
+
throw new Error(`Duplicate route: ${route.method}: ${route.path}`)
|
|
61
|
+
|
|
62
|
+
this.current = route
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* ${1:Description placeholder}
|
|
68
|
+
*
|
|
69
|
+
* @public
|
|
70
|
+
* @param {string[]} parts
|
|
71
|
+
* @returns {Route}
|
|
72
|
+
*/
|
|
73
|
+
public resolveRoute(parts: string[]): Route {
|
|
74
|
+
const first = parts.shift()
|
|
75
|
+
if (first) {
|
|
76
|
+
if (first in this.next) {
|
|
77
|
+
return this.next[first].resolveRoute(parts)
|
|
78
|
+
}
|
|
79
|
+
return this.variable?.resolveRoute(parts)
|
|
80
|
+
}
|
|
81
|
+
return this.current
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* ${1:Description placeholder}
|
|
87
|
+
*
|
|
88
|
+
* @export
|
|
89
|
+
* @class RouteResolver
|
|
90
|
+
* @typedef {RouteResolver}
|
|
91
|
+
*/
|
|
92
|
+
export default class RouteResolver {
|
|
93
|
+
/**
|
|
94
|
+
* ${1:Description placeholder}
|
|
95
|
+
*
|
|
96
|
+
* @private
|
|
97
|
+
* @type {{ [method: string]: Routes }\}
|
|
98
|
+
*/
|
|
99
|
+
private routes: { [method: string]: Routes }
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Creates an instance of RouteResolver.
|
|
103
|
+
*
|
|
104
|
+
* @constructor
|
|
105
|
+
* @param {RouterConfig} config
|
|
106
|
+
*/
|
|
107
|
+
constructor(readonly config: RouterConfig) {
|
|
108
|
+
this.routes = {}
|
|
109
|
+
this.buildRoutes(config)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* ${1:Description placeholder}
|
|
114
|
+
*
|
|
115
|
+
* @public
|
|
116
|
+
* @param {string} method
|
|
117
|
+
* @param {string} path
|
|
118
|
+
* @returns {(Route | undefined)}
|
|
119
|
+
*/
|
|
120
|
+
public resolveRoute(method: string, path: string): Route | undefined {
|
|
121
|
+
method = method.toLowerCase()
|
|
122
|
+
const parts = path.split("/").filter((p) => p.length)
|
|
123
|
+
|
|
124
|
+
return this.routes[method]?.resolveRoute(parts)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Description placeholder
|
|
129
|
+
*
|
|
130
|
+
* @private
|
|
131
|
+
* @param {RouterConfig} config
|
|
132
|
+
*/
|
|
133
|
+
private buildRoutes(config: RouterConfig): void {
|
|
134
|
+
for (const route of config.routes) {
|
|
135
|
+
const method = route.method.toLowerCase()
|
|
136
|
+
const parts = route.path.split("/").filter((p) => p.length)
|
|
137
|
+
|
|
138
|
+
this.routes[method] = this.routes[method] || new Routes()
|
|
139
|
+
this.routes[method].addRoute(route, parts)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
package/src/Server/Router.ts
CHANGED
|
@@ -10,8 +10,27 @@ import Transaction, {
|
|
|
10
10
|
} from "../BaseEvent/Transaction"
|
|
11
11
|
|
|
12
12
|
// Route
|
|
13
|
+
/**
|
|
14
|
+
* Description placeholder
|
|
15
|
+
*
|
|
16
|
+
* @export
|
|
17
|
+
* @interface Route
|
|
18
|
+
* @typedef {Route}
|
|
19
|
+
* @template [InputType=any]
|
|
20
|
+
* @template [OutputType=any]
|
|
21
|
+
*/
|
|
13
22
|
export interface Route<InputType = any, OutputType = any> {
|
|
23
|
+
/**
|
|
24
|
+
* Description placeholder
|
|
25
|
+
*
|
|
26
|
+
* @type {string}
|
|
27
|
+
*/
|
|
14
28
|
path: string
|
|
29
|
+
/**
|
|
30
|
+
* Description placeholder
|
|
31
|
+
*
|
|
32
|
+
* @type {string}
|
|
33
|
+
*/
|
|
15
34
|
method: string
|
|
16
35
|
/* If you are here to know why implementing this method
|
|
17
36
|
does not auto infer the param type, check long discussion on TS
|
|
@@ -19,14 +38,33 @@ export interface Route<InputType = any, OutputType = any> {
|
|
|
19
38
|
- https://github.com/microsoft/TypeScript/issues/23911#issuecomment-1351020050 (proposed solution)
|
|
20
39
|
- https://github.com/microsoft/TypeScript/issues/10570
|
|
21
40
|
*/
|
|
41
|
+
/**
|
|
42
|
+
* Description placeholder
|
|
43
|
+
*
|
|
44
|
+
* @type {TransactionExecution<
|
|
45
|
+
* Transaction<InputType, OutputType | ResponseErrorType>,
|
|
46
|
+
* OutputType | ResponseErrorType
|
|
47
|
+
* >}
|
|
48
|
+
*/
|
|
22
49
|
handler: TransactionExecution<
|
|
23
50
|
Transaction<InputType, OutputType | ResponseErrorType>,
|
|
24
51
|
OutputType | ResponseErrorType
|
|
25
52
|
>
|
|
53
|
+
/**
|
|
54
|
+
* Description placeholder
|
|
55
|
+
*
|
|
56
|
+
* @type {?z.ZodObject<any>}
|
|
57
|
+
*/
|
|
26
58
|
inputSchema?: z.ZodObject<any>
|
|
27
59
|
}
|
|
28
60
|
|
|
29
61
|
// Config
|
|
62
|
+
/**
|
|
63
|
+
* Description placeholder
|
|
64
|
+
*
|
|
65
|
+
* @export
|
|
66
|
+
* @typedef {RouterConfig}
|
|
67
|
+
*/
|
|
30
68
|
export type RouterConfig = TransactionConfig & {
|
|
31
69
|
routes: Route[]
|
|
32
70
|
// container based configs - otherwise enforced by serverless engine
|
|
@@ -40,18 +78,57 @@ export type RouterConfig = TransactionConfig & {
|
|
|
40
78
|
healthCheckRoute?: string
|
|
41
79
|
}
|
|
42
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Description placeholder
|
|
83
|
+
*
|
|
84
|
+
* @export
|
|
85
|
+
* @class Router
|
|
86
|
+
* @typedef {Router}
|
|
87
|
+
*/
|
|
43
88
|
export default class Router {
|
|
89
|
+
/**
|
|
90
|
+
* Description placeholder
|
|
91
|
+
*
|
|
92
|
+
* @private
|
|
93
|
+
* @readonly
|
|
94
|
+
* @type {RouterConfig}
|
|
95
|
+
*/
|
|
44
96
|
private readonly config: RouterConfig
|
|
97
|
+
/**
|
|
98
|
+
* Description placeholder
|
|
99
|
+
*
|
|
100
|
+
* @private
|
|
101
|
+
* @readonly
|
|
102
|
+
* @type {Server}
|
|
103
|
+
*/
|
|
45
104
|
private readonly server: Server
|
|
105
|
+
/**
|
|
106
|
+
* Creates an instance of Router.
|
|
107
|
+
*
|
|
108
|
+
* @constructor
|
|
109
|
+
* @param {RouterConfig} config
|
|
110
|
+
*/
|
|
46
111
|
constructor(config: RouterConfig) {
|
|
47
112
|
this.config = config
|
|
48
113
|
this.server = this.isContainer()
|
|
49
114
|
? new ContainerServer(config)
|
|
50
115
|
: new Server(config)
|
|
51
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Description placeholder
|
|
119
|
+
*
|
|
120
|
+
* @public
|
|
121
|
+
* @returns {CallableFunction}
|
|
122
|
+
*/
|
|
52
123
|
public getExport(): CallableFunction {
|
|
53
124
|
return this.server.getExport()
|
|
54
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Description placeholder
|
|
128
|
+
*
|
|
129
|
+
* @private
|
|
130
|
+
* @returns {boolean}
|
|
131
|
+
*/
|
|
55
132
|
private isContainer(): boolean {
|
|
56
133
|
return Utils.isHybridlessContainer()
|
|
57
134
|
}
|
|
@@ -2,13 +2,40 @@ import Proxy from "./container/Proxy"
|
|
|
2
2
|
import Server from "./Server"
|
|
3
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,12 +43,32 @@ 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
74
|
process.on("unhandledRejection", this.stop.bind(this)) // listen to exceptions
|
package/src/Server/lib/Server.ts
CHANGED
|
@@ -1,73 +1,113 @@
|
|
|
1
1
|
import { APIGatewayProxyEvent, Context } from "aws-lambda"
|
|
2
2
|
import * as pathToRegexp from "path-to-regexp"
|
|
3
3
|
|
|
4
|
+
import Request from "../../API/Request"
|
|
4
5
|
import Response from "../../API/Response"
|
|
5
6
|
import Transaction from "../../BaseEvent/Transaction"
|
|
6
7
|
import Validator from "../../Validation/Validator"
|
|
7
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
|
|
|
57
|
+
/**
|
|
58
|
+
* ${1:Description placeholder}
|
|
59
|
+
*
|
|
60
|
+
* @public
|
|
61
|
+
* @async
|
|
62
|
+
* @param {APIGatewayProxyEvent} event
|
|
63
|
+
* @param {Context} context
|
|
64
|
+
* @returns {*}
|
|
65
|
+
*/
|
|
19
66
|
public async handleServerlessEvent(
|
|
20
67
|
event: APIGatewayProxyEvent,
|
|
21
68
|
context: Context,
|
|
22
69
|
) {
|
|
23
|
-
const config = this.config
|
|
24
70
|
// init transaction
|
|
25
|
-
await new Transaction(event, context, config).execute(
|
|
71
|
+
await new Transaction(event, context, this.config).execute(
|
|
26
72
|
async (transaction) => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (validationResp && validationResp instanceof Response)
|
|
43
|
-
return validationResp
|
|
44
|
-
}
|
|
45
|
-
// Continue to route handler
|
|
46
|
-
return await route.handler(transaction)
|
|
73
|
+
const request = transaction.request
|
|
74
|
+
const route = this.routeResolver.resolveRoute(
|
|
75
|
+
request.getMethod(),
|
|
76
|
+
request.getPath(),
|
|
77
|
+
)
|
|
78
|
+
if (route) {
|
|
79
|
+
transaction.logger.log("Router accepted route:", route.path)
|
|
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
|
|
47
88
|
}
|
|
89
|
+
|
|
90
|
+
this.parsePathParams(request, route.path)
|
|
91
|
+
// Continue to route handler
|
|
92
|
+
return await route.handler(transaction)
|
|
48
93
|
}
|
|
49
94
|
//No route found :/
|
|
50
95
|
return new Response(404, { err: "Route not found!" })
|
|
51
96
|
},
|
|
52
97
|
)
|
|
53
98
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* ${1:Description placeholder}
|
|
102
|
+
*
|
|
103
|
+
* @private
|
|
104
|
+
* @param {Request<any>} req
|
|
105
|
+
* @param {string} routePath
|
|
106
|
+
*/
|
|
107
|
+
private parsePathParams(req: Request<any>, routePath: string) {
|
|
108
|
+
const path = req.getPath()
|
|
61
109
|
const keys = []
|
|
62
110
|
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
|
|
111
|
+
req.setFixedPathParams(keys, result)
|
|
72
112
|
}
|
|
73
113
|
}
|