@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
package/.eslintrc.cjs
CHANGED
|
@@ -1,42 +1,49 @@
|
|
|
1
1
|
/* eslint-env node */
|
|
2
2
|
module.exports = {
|
|
3
3
|
extends: [
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
'eslint:recommended',
|
|
5
|
+
'plugin:@typescript-eslint/recommended',
|
|
6
|
+
'plugin:prettier/recommended',
|
|
7
|
+
'plugin:import/recommended',
|
|
8
|
+
'plugin:import/typescript',
|
|
9
9
|
],
|
|
10
|
-
parser:
|
|
11
|
-
plugins: [
|
|
10
|
+
parser: '@typescript-eslint/parser',
|
|
11
|
+
plugins: ['@typescript-eslint', 'prettier'],
|
|
12
12
|
root: true,
|
|
13
13
|
rules: {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
'prettier/prettier': [
|
|
15
|
+
'error',
|
|
16
16
|
{
|
|
17
17
|
semi: false,
|
|
18
|
+
printWidth: 100,
|
|
19
|
+
tabWidth: 2,
|
|
20
|
+
useTabs: false,
|
|
21
|
+
bracketSameLine: true,
|
|
22
|
+
arrowParens: 'avoid',
|
|
23
|
+
singleQuote: true,
|
|
24
|
+
trailingComma: 'es5',
|
|
18
25
|
},
|
|
19
26
|
],
|
|
20
|
-
|
|
21
|
-
|
|
27
|
+
'@typescript-eslint/ban-ts-comment': 0,
|
|
28
|
+
'@typescript-eslint/no-explicit-any': 0,
|
|
22
29
|
// turn on errors for missing imports
|
|
23
|
-
|
|
30
|
+
'import/no-unresolved': 'error',
|
|
24
31
|
// 'import/no-named-as-default-member': 'off',
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
'import/order': [
|
|
33
|
+
'error',
|
|
27
34
|
{
|
|
28
35
|
groups: [
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
[
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
'builtin', // Built-in imports (come from NodeJS native) go first
|
|
37
|
+
'external', // <- External imports
|
|
38
|
+
'internal', // <- Absolute imports
|
|
39
|
+
['sibling', 'parent'], // <- Relative imports, the sibling and parent types they can be mingled together
|
|
40
|
+
'index', // <- index imports
|
|
41
|
+
'unknown', // <- unknown
|
|
35
42
|
],
|
|
36
|
-
|
|
43
|
+
'newlines-between': 'always',
|
|
37
44
|
alphabetize: {
|
|
38
45
|
/* sort in ascending order. Options: ["ignore", "asc", "desc"] */
|
|
39
|
-
order:
|
|
46
|
+
order: 'asc',
|
|
40
47
|
/* ignore case. Options: [true, false] */
|
|
41
48
|
caseInsensitive: true,
|
|
42
49
|
},
|
package/index.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import Response from
|
|
2
|
-
import Utils from
|
|
3
|
-
import EventProcessor from
|
|
4
|
-
import Process from
|
|
5
|
-
import Transaction from
|
|
6
|
-
import Configuration from
|
|
7
|
-
import Crypto from
|
|
8
|
-
import JWT from
|
|
9
|
-
import Mailer from
|
|
10
|
-
import Router, { Route } from
|
|
1
|
+
import Response, { ResponseErrorType } from './src/API/Response'
|
|
2
|
+
import Utils from './src/API/Utils'
|
|
3
|
+
import EventProcessor from './src/BaseEvent/EventProcessor'
|
|
4
|
+
import Process from './src/BaseEvent/Process'
|
|
5
|
+
import Transaction from './src/BaseEvent/Transaction'
|
|
6
|
+
import Configuration from './src/Config/Configuration'
|
|
7
|
+
import Crypto from './src/Crypto/Crypto'
|
|
8
|
+
import JWT from './src/Crypto/JWT'
|
|
9
|
+
import Mailer from './src/Mailer/Mailer'
|
|
10
|
+
import Router, { Route } from './src/Server/Router'
|
|
11
11
|
|
|
12
12
|
export {
|
|
13
13
|
// Base Events
|
|
@@ -25,4 +25,6 @@ export {
|
|
|
25
25
|
// Helpers
|
|
26
26
|
Utils,
|
|
27
27
|
Route,
|
|
28
|
+
// Misc types
|
|
29
|
+
ResponseErrorType,
|
|
28
30
|
}
|
package/jest.config.ts
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import type { Config } from
|
|
1
|
+
import type { Config } from '@jest/types'
|
|
2
2
|
/* eslint-env node */
|
|
3
3
|
const config: Config.InitialOptions = {
|
|
4
|
-
preset:
|
|
5
|
-
testEnvironment:
|
|
4
|
+
preset: 'ts-jest',
|
|
5
|
+
testEnvironment: 'node',
|
|
6
6
|
reporters: [
|
|
7
|
-
|
|
7
|
+
'default',
|
|
8
8
|
[
|
|
9
|
-
|
|
9
|
+
'jest-junit',
|
|
10
10
|
{
|
|
11
|
-
outputDirectory:
|
|
12
|
-
outputName:
|
|
13
|
-
ancestorSeparator:
|
|
14
|
-
uniqueOutputName:
|
|
15
|
-
suiteNameTemplate:
|
|
16
|
-
classNameTemplate:
|
|
17
|
-
titleTemplate:
|
|
11
|
+
outputDirectory: 'coverage',
|
|
12
|
+
outputName: 'jest-junit.xml',
|
|
13
|
+
ancestorSeparator: ' › ',
|
|
14
|
+
uniqueOutputName: 'false',
|
|
15
|
+
suiteNameTemplate: '{filepath}',
|
|
16
|
+
classNameTemplate: '{classname}',
|
|
17
|
+
titleTemplate: '{title}',
|
|
18
18
|
},
|
|
19
19
|
],
|
|
20
20
|
],
|
|
21
21
|
coverageReporters: [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
[
|
|
27
|
-
|
|
22
|
+
'clover',
|
|
23
|
+
'json',
|
|
24
|
+
'lcov',
|
|
25
|
+
'text',
|
|
26
|
+
['text', { file: 'coverage.txt' }],
|
|
27
|
+
'json-summary',
|
|
28
28
|
],
|
|
29
|
-
collectCoverageFrom: [
|
|
29
|
+
collectCoverageFrom: ['src/**/*.(t|j)s'],
|
|
30
30
|
coverageThreshold: {
|
|
31
31
|
global: {
|
|
32
32
|
branches: 80,
|
package/package.json
CHANGED
package/src/API/Request.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Context, APIGatewayEvent } from
|
|
1
|
+
import type { Context, APIGatewayEvent } from 'aws-lambda'
|
|
2
2
|
|
|
3
|
-
import Utils from
|
|
4
|
-
import Logger from
|
|
3
|
+
import Utils from './Utils'
|
|
4
|
+
import Logger from '../Logger/Logger'
|
|
5
5
|
/**
|
|
6
6
|
* ${1:Description placeholder}
|
|
7
7
|
*
|
|
@@ -36,8 +36,8 @@ export default class Request<InputType> {
|
|
|
36
36
|
constructor(requestEvent: APIGatewayEvent, context: Context, logger: Logger) {
|
|
37
37
|
this.requestEvent = requestEvent
|
|
38
38
|
this.context = context
|
|
39
|
-
logger.debug(
|
|
40
|
-
logger.debug(
|
|
39
|
+
logger.debug('Request info:', JSON.stringify(requestEvent))
|
|
40
|
+
logger.debug('Request context:', JSON.stringify(context))
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
43
|
* ${1:Description placeholder}
|
|
@@ -58,10 +58,7 @@ export default class Request<InputType> {
|
|
|
58
58
|
* @returns {(string | null)}
|
|
59
59
|
*/
|
|
60
60
|
public getQueryParam(paramName: string): string | null {
|
|
61
|
-
return Utils.caseInsensitiveObjectForKey(
|
|
62
|
-
this.requestEvent.queryStringParameters,
|
|
63
|
-
paramName,
|
|
64
|
-
)
|
|
61
|
+
return Utils.caseInsensitiveObjectForKey(this.requestEvent.queryStringParameters, paramName)
|
|
65
62
|
}
|
|
66
63
|
/**
|
|
67
64
|
* ${1:Description placeholder}
|
|
@@ -71,10 +68,7 @@ export default class Request<InputType> {
|
|
|
71
68
|
* @returns {(string | null)}
|
|
72
69
|
*/
|
|
73
70
|
public getHeader(headerName: string): string | null {
|
|
74
|
-
return Utils.caseInsensitiveObjectForKey(
|
|
75
|
-
this.requestEvent.headers,
|
|
76
|
-
headerName,
|
|
77
|
-
)
|
|
71
|
+
return Utils.caseInsensitiveObjectForKey(this.requestEvent.headers, headerName)
|
|
78
72
|
}
|
|
79
73
|
//context params
|
|
80
74
|
/**
|
|
@@ -85,10 +79,7 @@ export default class Request<InputType> {
|
|
|
85
79
|
* @returns {(any | null)}
|
|
86
80
|
*/
|
|
87
81
|
public getContextParam(cxtParam: string): any | null {
|
|
88
|
-
return Utils.caseInsensitiveObjectForKey(
|
|
89
|
-
this.requestEvent.requestContext,
|
|
90
|
-
cxtParam,
|
|
91
|
-
)
|
|
82
|
+
return Utils.caseInsensitiveObjectForKey(this.requestEvent.requestContext, cxtParam)
|
|
92
83
|
}
|
|
93
84
|
/**
|
|
94
85
|
* ${1:Description placeholder}
|
|
@@ -109,10 +100,7 @@ export default class Request<InputType> {
|
|
|
109
100
|
* @returns {(string | null)}
|
|
110
101
|
*/
|
|
111
102
|
public getPathParam(paramName: string): string | null {
|
|
112
|
-
return Utils.caseInsensitiveObjectForKey(
|
|
113
|
-
this.requestEvent.pathParameters,
|
|
114
|
-
paramName,
|
|
115
|
-
)
|
|
103
|
+
return Utils.caseInsensitiveObjectForKey(this.requestEvent.pathParameters, paramName)
|
|
116
104
|
}
|
|
117
105
|
/**
|
|
118
106
|
* ${1:Description placeholder}
|
|
@@ -124,10 +112,9 @@ export default class Request<InputType> {
|
|
|
124
112
|
let b: any = null
|
|
125
113
|
try {
|
|
126
114
|
b = this.requestEvent.body
|
|
127
|
-
if (typeof b ===
|
|
128
|
-
b = JSON.parse(b as string)
|
|
115
|
+
if (typeof b === 'string' || b instanceof String) b = JSON.parse(b as string)
|
|
129
116
|
} catch (e) {
|
|
130
|
-
console.error(
|
|
117
|
+
console.error('Error while getting request body!', e)
|
|
131
118
|
}
|
|
132
119
|
return b
|
|
133
120
|
}
|
|
@@ -165,7 +152,7 @@ export default class Request<InputType> {
|
|
|
165
152
|
* @returns {(string | null)}
|
|
166
153
|
*/
|
|
167
154
|
public getAuthorizationHeader(): string | null {
|
|
168
|
-
return this.getHeader(
|
|
155
|
+
return this.getHeader('Authorization')
|
|
169
156
|
}
|
|
170
157
|
/**
|
|
171
158
|
* ${1:Description placeholder}
|
|
@@ -175,9 +162,7 @@ export default class Request<InputType> {
|
|
|
175
162
|
*/
|
|
176
163
|
public getRequestID(): string {
|
|
177
164
|
if (this.context.awsRequestId) return this.context.awsRequestId
|
|
178
|
-
return this.requestEvent.requestContext
|
|
179
|
-
? this.requestEvent.requestContext.requestId
|
|
180
|
-
: "unknown"
|
|
165
|
+
return this.requestEvent.requestContext ? this.requestEvent.requestContext.requestId : 'unknown'
|
|
181
166
|
}
|
|
182
167
|
/**
|
|
183
168
|
* ${1:Description placeholder}
|
|
@@ -186,9 +171,9 @@ export default class Request<InputType> {
|
|
|
186
171
|
* @returns {string}
|
|
187
172
|
*/
|
|
188
173
|
public getOriginIP(): string {
|
|
189
|
-
const origin = this.getContextParam(
|
|
190
|
-
const hOrigin = this.getHeader(
|
|
191
|
-
return origin ? origin : hOrigin ? hOrigin :
|
|
174
|
+
const origin = this.getContextParam('identity')?.sourceIp
|
|
175
|
+
const hOrigin = this.getHeader('X-Forwarded-For')
|
|
176
|
+
return origin ? origin : hOrigin ? hOrigin : 'unknown'
|
|
192
177
|
}
|
|
193
178
|
/**
|
|
194
179
|
* ${1:Description placeholder}
|
|
@@ -199,9 +184,6 @@ export default class Request<InputType> {
|
|
|
199
184
|
*/
|
|
200
185
|
public setFixedPathParams(keys: any[], result: any[]): void {
|
|
201
186
|
this.requestEvent.pathParameters = {}
|
|
202
|
-
keys.forEach(
|
|
203
|
-
(key, index) =>
|
|
204
|
-
(this.requestEvent.pathParameters[key.name] = result[index + 1]),
|
|
205
|
-
)
|
|
187
|
+
keys.forEach((key, index) => (this.requestEvent.pathParameters[key.name] = result[index + 1]))
|
|
206
188
|
}
|
|
207
189
|
}
|
package/src/API/Response.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Context } from
|
|
1
|
+
import type { Context } from 'aws-lambda'
|
|
2
2
|
|
|
3
|
-
import Transaction from
|
|
4
|
-
import Globals from
|
|
3
|
+
import Transaction from '../BaseEvent/Transaction'
|
|
4
|
+
import Globals from '../Globals'
|
|
5
5
|
//
|
|
6
6
|
/**
|
|
7
7
|
* ${1:Description placeholder}
|
|
@@ -18,8 +18,8 @@ class CustomError extends Error {
|
|
|
18
18
|
* @param {*} body
|
|
19
19
|
*/
|
|
20
20
|
constructor(body: any) {
|
|
21
|
-
super(body.message ||
|
|
22
|
-
this.name = body.error ||
|
|
21
|
+
super(body.message || 'Unknown error!')
|
|
22
|
+
this.name = body.error || 'UnknownError'
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
//
|
|
@@ -128,15 +128,15 @@ export default class Response<BodyType = null> {
|
|
|
128
128
|
throwOnErrors?: boolean
|
|
129
129
|
disableTransactionID?: boolean
|
|
130
130
|
}
|
|
131
|
-
| undefined
|
|
131
|
+
| undefined
|
|
132
132
|
) {
|
|
133
133
|
// response
|
|
134
134
|
this._statusCode = statusCode
|
|
135
135
|
this._body = body
|
|
136
136
|
this._headers = {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
'Access-Control-Allow-Origin': '*',
|
|
138
|
+
'Access-Control-Allow-Credentials': true,
|
|
139
|
+
'Content-Type': 'application/json',
|
|
140
140
|
}
|
|
141
141
|
// behaviour
|
|
142
142
|
this._isPipingOut = false //internal -- flag to indicate streaming out has started and avoid double stream call
|
|
@@ -197,19 +197,15 @@ export default class Response<BodyType = null> {
|
|
|
197
197
|
public async build(
|
|
198
198
|
context: Context,
|
|
199
199
|
transaction: Transaction<any, any, any>,
|
|
200
|
-
_optDoNotCallContext: boolean
|
|
200
|
+
_optDoNotCallContext: boolean
|
|
201
201
|
): Promise<void> {
|
|
202
202
|
//Stream support
|
|
203
203
|
if (this._isPipingOut) return
|
|
204
204
|
if (this.shouldStream) return this._pipe(context)
|
|
205
205
|
|
|
206
206
|
//append default fields
|
|
207
|
-
if (
|
|
208
|
-
transaction.request.getRequestID()
|
|
209
|
-
this._body &&
|
|
210
|
-
!this.disableTransactionID
|
|
211
|
-
)
|
|
212
|
-
this.appendIntoBody("transactionID", transaction.request.getRequestID()) //append transaction ID
|
|
207
|
+
if (transaction.request.getRequestID() && this._body && !this.disableTransactionID)
|
|
208
|
+
this.appendIntoBody('transactionID', transaction.request.getRequestID()) //append transaction ID
|
|
213
209
|
//Raw response support
|
|
214
210
|
if (this.rawBody) return this._rawContext(context, transaction)
|
|
215
211
|
|
|
@@ -251,14 +247,10 @@ export default class Response<BodyType = null> {
|
|
|
251
247
|
* @param {Context} context
|
|
252
248
|
* @param {Transaction<null, BodyType>} transaction
|
|
253
249
|
*/
|
|
254
|
-
private _rawContext(
|
|
255
|
-
context: Context,
|
|
256
|
-
transaction: Transaction<null, BodyType>,
|
|
257
|
-
): void {
|
|
250
|
+
private _rawContext(context: Context, transaction: Transaction<null, BodyType>): void {
|
|
258
251
|
//log response and respond to context
|
|
259
252
|
transaction.logger.debug(this._body)
|
|
260
|
-
if (this.getCode() <= 200 && this.getCode() <= 299)
|
|
261
|
-
context.succeed(this._body)
|
|
253
|
+
if (this.getCode() <= 200 && this.getCode() <= 299) context.succeed(this._body)
|
|
262
254
|
else {
|
|
263
255
|
if (!this.throwOnErrors) context.fail(new CustomError(this._body))
|
|
264
256
|
else throw new CustomError(this._body)
|
|
@@ -274,9 +266,7 @@ export default class Response<BodyType = null> {
|
|
|
274
266
|
* @param {string} paramName
|
|
275
267
|
* @returns {Response<ResponseErrorType>}
|
|
276
268
|
*/
|
|
277
|
-
public static MissingParamResponse(
|
|
278
|
-
paramName: string,
|
|
279
|
-
): Response<ResponseErrorType> {
|
|
269
|
+
public static MissingParamResponse(paramName: string): Response<ResponseErrorType> {
|
|
280
270
|
console.warn(`Invalid request - Path parameter ${paramName} is missing.`)
|
|
281
271
|
return new Response<ResponseErrorType>(400, {
|
|
282
272
|
err: `Invalid request. Path parameter ${paramName} is missing.`,
|
|
@@ -291,9 +281,7 @@ export default class Response<BodyType = null> {
|
|
|
291
281
|
* @param {string} paramName
|
|
292
282
|
* @returns {Response<ResponseErrorType>}
|
|
293
283
|
*/
|
|
294
|
-
public static MissingQueryResponse(
|
|
295
|
-
paramName: string,
|
|
296
|
-
): Response<ResponseErrorType> {
|
|
284
|
+
public static MissingQueryResponse(paramName: string): Response<ResponseErrorType> {
|
|
297
285
|
console.warn(`Invalid request - Query parameter ${paramName} is missing.`)
|
|
298
286
|
return new Response<ResponseErrorType>(400, {
|
|
299
287
|
err: `Invalid request. Query parameter ${paramName} is missing.`,
|
|
@@ -313,7 +301,7 @@ export default class Response<BodyType = null> {
|
|
|
313
301
|
public static BadRequestResponse(
|
|
314
302
|
msg?: string,
|
|
315
303
|
errCode?: string,
|
|
316
|
-
optBody?: any
|
|
304
|
+
optBody?: any
|
|
317
305
|
): Response<ResponseErrorType> {
|
|
318
306
|
console.warn(`Bad request - ${msg}`)
|
|
319
307
|
return new Response<ResponseErrorType>(400, {
|
|
@@ -335,7 +323,7 @@ export default class Response<BodyType = null> {
|
|
|
335
323
|
public static BadRequestResponseWithRollback(
|
|
336
324
|
msg: string,
|
|
337
325
|
errCode?: string,
|
|
338
|
-
optBody?: any
|
|
326
|
+
optBody?: any
|
|
339
327
|
): Response<ResponseErrorType> {
|
|
340
328
|
console.warn(`Bad request - ${msg}`)
|
|
341
329
|
return new Response<ResponseErrorType>(400, {
|
|
@@ -354,10 +342,7 @@ export default class Response<BodyType = null> {
|
|
|
354
342
|
* @param {?string} [errCode]
|
|
355
343
|
* @returns {Response<ResponseErrorType>}
|
|
356
344
|
*/
|
|
357
|
-
public static UnauthorizedResponse(
|
|
358
|
-
msg: string,
|
|
359
|
-
errCode?: string,
|
|
360
|
-
): Response<ResponseErrorType> {
|
|
345
|
+
public static UnauthorizedResponse(msg: string, errCode?: string): Response<ResponseErrorType> {
|
|
361
346
|
console.warn(`Denying request - ${msg}`)
|
|
362
347
|
return new Response<ResponseErrorType>(401, {
|
|
363
348
|
err: msg,
|
|
@@ -386,7 +371,7 @@ export default class Response<BodyType = null> {
|
|
|
386
371
|
*/
|
|
387
372
|
public static RedirectResponse(url: string): Response<null> {
|
|
388
373
|
const resp = new Response<null>(302, null)
|
|
389
|
-
resp.appendHeader(
|
|
374
|
+
resp.appendHeader('Location', url)
|
|
390
375
|
return resp
|
|
391
376
|
}
|
|
392
377
|
/**
|
|
@@ -408,15 +393,12 @@ export default class Response<BodyType = null> {
|
|
|
408
393
|
* @param {string} contentType
|
|
409
394
|
* @returns {Response}
|
|
410
395
|
*/
|
|
411
|
-
public static SuccessStreamResponse(
|
|
412
|
-
stream: any,
|
|
413
|
-
contentType: string,
|
|
414
|
-
): Response {
|
|
396
|
+
public static SuccessStreamResponse(stream: any, contentType: string): Response {
|
|
415
397
|
const resp = new Response(200, stream, {
|
|
416
398
|
shouldStream: true,
|
|
417
399
|
})
|
|
418
|
-
resp.appendHeader(
|
|
419
|
-
if (contentType) resp.appendHeader(
|
|
400
|
+
resp.appendHeader('Connection', 'keep-alive')
|
|
401
|
+
if (contentType) resp.appendHeader('Content-Type', contentType)
|
|
420
402
|
return resp
|
|
421
403
|
}
|
|
422
404
|
/**
|
|
@@ -431,7 +413,7 @@ export default class Response<BodyType = null> {
|
|
|
431
413
|
*/
|
|
432
414
|
public static SimpleResponse<BodyType>(
|
|
433
415
|
body: BodyType,
|
|
434
|
-
optionalCode?: number
|
|
416
|
+
optionalCode?: number
|
|
435
417
|
): Response<BodyType> {
|
|
436
418
|
const resp = new Response<BodyType>(optionalCode || 200, body)
|
|
437
419
|
return resp
|
package/src/API/Utils.ts
CHANGED
|
@@ -14,7 +14,7 @@ export default class Utils {
|
|
|
14
14
|
* @returns {boolean}
|
|
15
15
|
*/
|
|
16
16
|
public static isHybridlessContainer(): boolean {
|
|
17
|
-
return process.env.HYBRIDLESS_RUNTIME ==
|
|
17
|
+
return process.env.HYBRIDLESS_RUNTIME == 'true'
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* ${1:Description placeholder}
|
|
@@ -68,9 +68,9 @@ export default class Utils {
|
|
|
68
68
|
public static isValidNumber(number: string): boolean {
|
|
69
69
|
let validNumb = NaN
|
|
70
70
|
try {
|
|
71
|
-
validNumb = parseInt(number +
|
|
71
|
+
validNumb = parseInt(number + '')
|
|
72
72
|
} catch (e) {
|
|
73
|
-
console.error(
|
|
73
|
+
console.error('Error while validating number', e)
|
|
74
74
|
}
|
|
75
75
|
return !isNaN(validNumb) && !Array.isArray(number)
|
|
76
76
|
}
|
|
@@ -85,10 +85,8 @@ export default class Utils {
|
|
|
85
85
|
*/
|
|
86
86
|
public static caseInsensitiveObjectForKey(obj: any, key: string): any | null {
|
|
87
87
|
if (!obj) return null
|
|
88
|
-
const insensitiveKey = Object.keys(obj).find(
|
|
89
|
-
|
|
90
|
-
)
|
|
91
|
-
if (insensitiveKey && insensitiveKey != "") return obj[insensitiveKey]
|
|
88
|
+
const insensitiveKey = Object.keys(obj).find(k => k.toLowerCase() === key.toLowerCase())
|
|
89
|
+
if (insensitiveKey && insensitiveKey != '') return obj[insensitiveKey]
|
|
92
90
|
return null
|
|
93
91
|
}
|
|
94
92
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { Context, SQSBatchResponse, SQSEvent } from
|
|
1
|
+
import type { Context, SQSBatchResponse, SQSEvent } from 'aws-lambda'
|
|
2
2
|
|
|
3
|
-
import Transaction, { TransactionConfig } from
|
|
4
|
-
import Response, { ResponseErrorType } from
|
|
5
|
-
import Globals from
|
|
3
|
+
import Transaction, { TransactionConfig } from './Transaction'
|
|
4
|
+
import Response, { ResponseErrorType } from '../API/Response'
|
|
5
|
+
import Globals from '../Globals'
|
|
6
6
|
|
|
7
7
|
// Handler
|
|
8
8
|
/**
|
|
@@ -13,12 +13,8 @@ import Globals from "../Globals"
|
|
|
13
13
|
* @template ResponseInnerType
|
|
14
14
|
*/
|
|
15
15
|
export type EventProcessorExecution<ResponseInnerType> = (
|
|
16
|
-
transaction: Transaction<
|
|
17
|
-
|
|
18
|
-
ResponseInnerType | ResponseErrorType,
|
|
19
|
-
SQSBatchResponse
|
|
20
|
-
>,
|
|
21
|
-
recordContent: string | object,
|
|
16
|
+
transaction: Transaction<null, ResponseInnerType | ResponseErrorType, SQSBatchResponse>,
|
|
17
|
+
recordContent: string | object
|
|
22
18
|
) => Promise<Response<ResponseInnerType | ResponseErrorType> | SQSBatchResponse>
|
|
23
19
|
|
|
24
20
|
/**
|
|
@@ -75,7 +71,7 @@ export default class EventProcessor<ResponseInnerType> {
|
|
|
75
71
|
event: SQSEvent,
|
|
76
72
|
context: Context,
|
|
77
73
|
config?: TransactionConfig,
|
|
78
|
-
allowFailure?: boolean
|
|
74
|
+
allowFailure?: boolean
|
|
79
75
|
) {
|
|
80
76
|
this._event = event
|
|
81
77
|
this._context = context
|
|
@@ -92,7 +88,7 @@ export default class EventProcessor<ResponseInnerType> {
|
|
|
92
88
|
*/
|
|
93
89
|
async processEvent(
|
|
94
90
|
execution: EventProcessorExecution<ResponseInnerType>,
|
|
95
|
-
doNotDecodeMessage?: boolean
|
|
91
|
+
doNotDecodeMessage?: boolean
|
|
96
92
|
): Promise<Response<ResponseErrorType> | null | SQSBatchResponse> {
|
|
97
93
|
const resp = await this._processRawEvent(execution, !!doNotDecodeMessage)
|
|
98
94
|
if (
|
|
@@ -115,7 +111,7 @@ export default class EventProcessor<ResponseInnerType> {
|
|
|
115
111
|
*/
|
|
116
112
|
async _processRawEvent(
|
|
117
113
|
execution: EventProcessorExecution<ResponseInnerType>,
|
|
118
|
-
doNotDecodeMessage: boolean
|
|
114
|
+
doNotDecodeMessage: boolean
|
|
119
115
|
): Promise<Response<ResponseErrorType> | null | SQSBatchResponse> {
|
|
120
116
|
if (this._event.Records && this._event.Records.length > 0) {
|
|
121
117
|
//safe check for empty events?
|
|
@@ -126,14 +122,11 @@ export default class EventProcessor<ResponseInnerType> {
|
|
|
126
122
|
{
|
|
127
123
|
...this._apiConfig,
|
|
128
124
|
syncReturn: true,
|
|
129
|
-
}
|
|
130
|
-
).execute(async
|
|
125
|
+
}
|
|
126
|
+
).execute(async transaction => {
|
|
131
127
|
//Map records with decoded message when required
|
|
132
|
-
const decodedRecords: string[] | object[] = this._event.Records.map(
|
|
133
|
-
(eventRecord)
|
|
134
|
-
doNotDecodeMessage
|
|
135
|
-
? eventRecord.body
|
|
136
|
-
: JSON.parse(eventRecord.body),
|
|
128
|
+
const decodedRecords: string[] | object[] = this._event.Records.map(eventRecord =>
|
|
129
|
+
doNotDecodeMessage ? eventRecord.body : JSON.parse(eventRecord.body)
|
|
137
130
|
)
|
|
138
131
|
|
|
139
132
|
//for each available event
|
|
@@ -146,8 +139,7 @@ export default class EventProcessor<ResponseInnerType> {
|
|
|
146
139
|
//check for failure
|
|
147
140
|
if (
|
|
148
141
|
!resp ||
|
|
149
|
-
(resp instanceof Response &&
|
|
150
|
-
!(resp?.getCode() >= 200 && resp?.getCode() < 300))
|
|
142
|
+
(resp instanceof Response && !(resp?.getCode() >= 200 && resp?.getCode() < 300))
|
|
151
143
|
) {
|
|
152
144
|
//response with failures or fail hard at first
|
|
153
145
|
if (this._allowFailure) failureIDs.push(message.messageId)
|
|
@@ -157,14 +149,14 @@ export default class EventProcessor<ResponseInnerType> {
|
|
|
157
149
|
//not errored and loop ended - succeeded (might have failures)
|
|
158
150
|
if (this._allowFailure)
|
|
159
151
|
return {
|
|
160
|
-
batchItemFailures: failureIDs.map(
|
|
152
|
+
batchItemFailures: failureIDs.map(id => ({ itemIdentifier: id })),
|
|
161
153
|
}
|
|
162
154
|
return Response.SuccessResponse(null)
|
|
163
155
|
})
|
|
164
156
|
} else
|
|
165
157
|
return Response.BadRequestResponse(
|
|
166
158
|
Globals.ErrorResponseNoRecords,
|
|
167
|
-
Globals.ErrorCode_NoRecords
|
|
159
|
+
Globals.ErrorCode_NoRecords
|
|
168
160
|
) //no event to be processed?
|
|
169
161
|
}
|
|
170
162
|
}
|
package/src/BaseEvent/Process.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { TransactionConfig } from
|
|
2
|
-
import Logger from
|
|
3
|
-
import Publisher from
|
|
1
|
+
import { TransactionConfig } from './Transaction'
|
|
2
|
+
import Logger from '../Logger/Logger'
|
|
3
|
+
import Publisher from '../Publisher/Publisher'
|
|
4
4
|
|
|
5
5
|
// Config
|
|
6
6
|
/**
|
|
@@ -9,10 +9,7 @@ import Publisher from "../Publisher/Publisher"
|
|
|
9
9
|
* @export
|
|
10
10
|
* @typedef {ProcessConfig}
|
|
11
11
|
*/
|
|
12
|
-
export type ProcessConfig = Omit<
|
|
13
|
-
TransactionConfig,
|
|
14
|
-
"throwOnErrors" | "syncReturn"
|
|
15
|
-
>
|
|
12
|
+
export type ProcessConfig = Omit<TransactionConfig, 'throwOnErrors' | 'syncReturn'>
|
|
16
13
|
|
|
17
14
|
/**
|
|
18
15
|
* ${1:Description placeholder}
|
|
@@ -62,7 +59,7 @@ export default class Process {
|
|
|
62
59
|
*/
|
|
63
60
|
constructor(config: ProcessConfig, interval: number) {
|
|
64
61
|
this._interval = interval
|
|
65
|
-
this.logger = new Logger(config.logger,
|
|
62
|
+
this.logger = new Logger(config.logger, 'long-running-process')
|
|
66
63
|
this.publisher = new Publisher(config.publisher)
|
|
67
64
|
}
|
|
68
65
|
|
|
@@ -75,7 +72,7 @@ export default class Process {
|
|
|
75
72
|
* @returns {*}
|
|
76
73
|
*/
|
|
77
74
|
async execute(executionFunc) {
|
|
78
|
-
this.logger.debug(
|
|
75
|
+
this.logger.debug('Starting main process code')
|
|
79
76
|
//Connect DB
|
|
80
77
|
// if (this.db) await this.db.connect();
|
|
81
78
|
//Program loop
|
|
@@ -105,9 +102,7 @@ export default class Process {
|
|
|
105
102
|
executionFailed = false
|
|
106
103
|
} catch (e) {
|
|
107
104
|
/*EXECUTION FAIL*/
|
|
108
|
-
this.logger.error(
|
|
109
|
-
"Exception when executing main process code. Rolling back DB!",
|
|
110
|
-
)
|
|
105
|
+
this.logger.error('Exception when executing main process code. Rolling back DB!')
|
|
111
106
|
this.logger.exception(e)
|
|
112
107
|
//Rollback DB
|
|
113
108
|
// if (this.db) await this.db.rollback();
|