@creator.co/wapi 1.2.2 → 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 +1 -1
- package/.github/workflows/prs.yml +1 -1
- package/index.ts +12 -10
- package/jest.config.ts +19 -19
- package/package.json +1 -1
- 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
|
@@ -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
|