@ikonintegration/ikapi 4.0.1 → 5.0.0
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/.eslintignore +3 -0
- package/.eslintrc.cjs +81 -0
- package/.github/workflows/npmpublish.yml +8 -19
- package/.github/workflows/prs.yml +12 -0
- package/README.md +89 -99
- package/dist/index.d.ts +16 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/package-lock.json +11881 -0
- package/dist/package.json +81 -0
- package/dist/src/API/Request.d.ts +125 -0
- package/dist/src/API/Request.js +185 -0
- package/dist/src/API/Request.js.map +1 -0
- package/dist/src/API/Response.d.ts +188 -0
- package/dist/src/API/Response.js +270 -0
- package/dist/src/API/Response.js.map +1 -0
- package/dist/src/BaseEvent/DynamoTransaction.d.ts +70 -0
- package/dist/src/BaseEvent/DynamoTransaction.js +104 -0
- package/dist/src/BaseEvent/DynamoTransaction.js.map +1 -0
- package/dist/src/BaseEvent/EventProcessor.d.ts +58 -0
- package/dist/src/BaseEvent/EventProcessor.js +101 -0
- package/dist/src/BaseEvent/EventProcessor.js.map +1 -0
- package/dist/src/BaseEvent/Process.d.ts +50 -0
- package/dist/src/BaseEvent/Process.js +64 -0
- package/dist/src/BaseEvent/Process.js.map +1 -0
- package/dist/src/BaseEvent/StepTransaction.d.ts +23 -0
- package/dist/src/BaseEvent/StepTransaction.js +27 -0
- package/dist/src/BaseEvent/StepTransaction.js.map +1 -0
- package/dist/src/BaseEvent/Transaction.d.ts +149 -0
- package/dist/src/BaseEvent/Transaction.js +224 -0
- package/dist/src/BaseEvent/Transaction.js.map +1 -0
- package/dist/src/Cache/Redis.d.ts +29 -0
- package/dist/src/Cache/Redis.js +80 -0
- package/dist/src/Cache/Redis.js.map +1 -0
- package/dist/src/Cache/types.d.ts +31 -0
- package/dist/src/Cache/types.js +2 -0
- package/dist/src/Cache/types.js.map +1 -0
- package/dist/src/Config/Configuration.d.ts +123 -0
- package/dist/src/Config/Configuration.js +109 -0
- package/dist/src/Config/Configuration.js.map +1 -0
- package/dist/src/Config/EnvironmentVar.d.ts +74 -0
- package/dist/src/Config/EnvironmentVar.js +138 -0
- package/dist/src/Config/EnvironmentVar.js.map +1 -0
- package/dist/src/Crypto/Crypto.d.ts +45 -0
- package/dist/src/Crypto/Crypto.js +72 -0
- package/dist/src/Crypto/Crypto.js.map +1 -0
- package/dist/src/Database/Database.d.ts +21 -0
- package/dist/src/Database/Database.js +15 -0
- package/dist/src/Database/Database.js.map +1 -0
- package/dist/src/Database/DatabaseManager.d.ts +47 -0
- package/dist/src/Database/DatabaseManager.js +60 -0
- package/dist/src/Database/DatabaseManager.js.map +1 -0
- package/dist/src/Database/DatabaseTransaction.d.ts +101 -0
- package/dist/src/Database/DatabaseTransaction.js +126 -0
- package/dist/src/Database/DatabaseTransaction.js.map +1 -0
- package/dist/src/Database/index.d.ts +10 -0
- package/dist/src/Database/index.js +15 -0
- package/dist/src/Database/index.js.map +1 -0
- package/dist/src/Database/integrations/dynamo/DynamoDatabase.d.ts +35 -0
- package/dist/src/Database/integrations/dynamo/DynamoDatabase.js +59 -0
- package/dist/src/Database/integrations/dynamo/DynamoDatabase.js.map +1 -0
- package/dist/src/Database/integrations/kysely/KyselyDatabase.d.ts +66 -0
- package/dist/src/Database/integrations/kysely/KyselyDatabase.js +86 -0
- package/dist/src/Database/integrations/kysely/KyselyDatabase.js.map +1 -0
- package/dist/src/Database/integrations/kysely/KyselyTransaction.d.ts +70 -0
- package/dist/src/Database/integrations/kysely/KyselyTransaction.js +118 -0
- package/dist/src/Database/integrations/kysely/KyselyTransaction.js.map +1 -0
- package/dist/src/Database/integrations/pgsql/PostgresDatabase.d.ts +36 -0
- package/dist/src/Database/integrations/pgsql/PostgresDatabase.js +54 -0
- package/dist/src/Database/integrations/pgsql/PostgresDatabase.js.map +1 -0
- package/dist/src/Database/integrations/pgsql/PostgresTransaction.d.ts +63 -0
- package/dist/src/Database/integrations/pgsql/PostgresTransaction.js +61 -0
- package/dist/src/Database/integrations/pgsql/PostgresTransaction.js.map +1 -0
- package/dist/src/Database/types.d.ts +76 -0
- package/dist/src/Database/types.js +2 -0
- package/dist/src/Database/types.js.map +1 -0
- package/dist/src/Globals.d.ts +93 -0
- package/dist/src/Globals.js +99 -0
- package/dist/src/Globals.js.map +1 -0
- package/dist/src/Logger/Logger.d.ts +161 -0
- package/dist/src/Logger/Logger.js +299 -0
- package/dist/src/Logger/Logger.js.map +1 -0
- package/dist/src/Mailer/Mailer.d.ts +78 -0
- package/dist/src/Mailer/Mailer.js +182 -0
- package/dist/src/Mailer/Mailer.js.map +1 -0
- package/dist/src/Publisher/Publisher.d.ts +39 -0
- package/dist/src/Publisher/Publisher.js +77 -0
- package/dist/src/Publisher/Publisher.js.map +1 -0
- package/dist/src/Server/RouteResolver.d.ts +33 -0
- package/dist/src/Server/RouteResolver.js +100 -0
- package/dist/src/Server/RouteResolver.js.map +1 -0
- package/dist/src/Server/Router.d.ts +157 -0
- package/dist/src/Server/Router.js +32 -0
- package/dist/src/Server/Router.js.map +1 -0
- package/dist/src/Server/lib/ContainerServer.d.ts +42 -0
- package/dist/src/Server/lib/ContainerServer.js +66 -0
- package/dist/src/Server/lib/ContainerServer.js.map +1 -0
- package/dist/src/Server/lib/Server.d.ts +45 -0
- package/dist/src/Server/lib/Server.js +93 -0
- package/dist/src/Server/lib/Server.js.map +1 -0
- package/dist/src/Server/lib/container/GenericHandler.d.ts +9 -0
- package/dist/src/Server/lib/container/GenericHandler.js +82 -0
- package/dist/src/Server/lib/container/GenericHandler.js.map +1 -0
- package/dist/src/Server/lib/container/GenericHandlerEvent.d.ts +52 -0
- package/dist/src/Server/lib/container/GenericHandlerEvent.js +132 -0
- package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +1 -0
- package/dist/src/Server/lib/container/HealthHandler.d.ts +9 -0
- package/dist/src/Server/lib/container/HealthHandler.js +19 -0
- package/dist/src/Server/lib/container/HealthHandler.js.map +1 -0
- package/dist/src/Server/lib/container/Proxy.d.ts +67 -0
- package/dist/src/Server/lib/container/Proxy.js +143 -0
- package/dist/src/Server/lib/container/Proxy.js.map +1 -0
- package/dist/src/Server/lib/container/Utils.d.ts +14 -0
- package/dist/src/Server/lib/container/Utils.js +37 -0
- package/dist/src/Server/lib/container/Utils.js.map +1 -0
- package/dist/src/Util/AsyncSingleton.d.ts +31 -0
- package/dist/src/Util/AsyncSingleton.js +83 -0
- package/dist/src/Util/AsyncSingleton.js.map +1 -0
- package/dist/src/Util/Utils.d.ts +61 -0
- package/dist/src/Util/Utils.js +147 -0
- package/dist/src/Util/Utils.js.map +1 -0
- package/dist/src/Validation/Validator.d.ts +17 -0
- package/dist/src/Validation/Validator.js +39 -0
- package/dist/src/Validation/Validator.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/index.ts +41 -0
- package/jest.config.ts +37 -0
- package/jest.smoke.config.ts +34 -0
- package/package.json +66 -22
- package/src/API/Request.ts +214 -0
- package/src/API/Response.ts +370 -0
- package/src/BaseEvent/DynamoTransaction.ts +175 -0
- package/src/BaseEvent/EventProcessor.ts +140 -0
- package/src/BaseEvent/Process.ts +78 -0
- package/src/BaseEvent/StepTransaction.ts +35 -0
- package/src/BaseEvent/Transaction.ts +323 -0
- package/src/Cache/Redis.ts +89 -0
- package/src/Cache/types.ts +33 -0
- package/src/Config/Configuration.ts +199 -0
- package/src/Config/EnvironmentVar.ts +142 -0
- package/src/Crypto/Crypto.ts +89 -0
- package/src/Database/Database.ts +22 -0
- package/src/Database/DatabaseManager.ts +67 -0
- package/src/Database/DatabaseTransaction.ts +170 -0
- package/src/Database/index.ts +27 -0
- package/src/Database/integrations/dynamo/DynamoDatabase.ts +58 -0
- package/src/Database/integrations/kysely/KyselyDatabase.ts +99 -0
- package/src/Database/integrations/kysely/KyselyTransaction.ts +172 -0
- package/src/Database/integrations/pgsql/PostgresDatabase.ts +56 -0
- package/src/Database/integrations/pgsql/PostgresTransaction.ts +87 -0
- package/src/Database/types.ts +85 -0
- package/src/Globals.ts +103 -0
- package/src/Logger/Logger.ts +363 -0
- package/src/Mailer/Mailer.ts +217 -0
- package/src/Publisher/Publisher.ts +96 -0
- package/src/Server/RouteResolver.ts +124 -0
- package/src/Server/Router.ts +200 -0
- package/src/Server/lib/ContainerServer.ts +65 -0
- package/src/Server/lib/Server.ts +109 -0
- package/src/Server/lib/container/GenericHandler.ts +76 -0
- package/src/Server/lib/container/GenericHandlerEvent.ts +154 -0
- package/src/Server/lib/container/HealthHandler.ts +11 -0
- package/src/Server/lib/container/Proxy.ts +172 -0
- package/src/Server/lib/container/Utils.ts +33 -0
- package/src/Util/AsyncSingleton.ts +86 -0
- package/src/Util/Utils.ts +131 -0
- package/src/Validation/Validator.ts +45 -0
- package/tests/API/Request.test.ts +273 -0
- package/tests/API/Response.test.ts +367 -0
- package/tests/BaseEvent/DynamoTransaction.test.ts +272 -0
- package/tests/BaseEvent/EventProcessor.test.ts +263 -0
- package/tests/BaseEvent/Process.test.ts +47 -0
- package/tests/BaseEvent/StepTransaction.test.ts +44 -0
- package/tests/BaseEvent/Transaction.test.ts +402 -0
- package/tests/Cache/Redis-client.test.ts +90 -0
- package/tests/Cache/Redis-cluster.test.ts +100 -0
- package/tests/Config/Config.test.ts +205 -0
- package/tests/Config/EnvironmentVar.test.ts +251 -0
- package/tests/Crypto/Crypto.test.ts +88 -0
- package/tests/Database/DatabaseManager.test.ts +79 -0
- package/tests/Database/integrations/dynamo/DynamoDatabase.test.ts +44 -0
- package/tests/Database/integrations/kysely/KyselyDatabase.test.ts +113 -0
- package/tests/Database/integrations/kysely/KyselyTransaction.test.ts +119 -0
- package/tests/Database/integrations/pg/PostgresDatabase.test.ts +76 -0
- package/tests/Database/integrations/pg/PostgresTransaction.test.ts +118 -0
- package/tests/Logger/Logger.test.ts +215 -0
- package/tests/Mailer/Mailer.test.ts +59 -0
- package/tests/Publisher/Publisher.test.ts +60 -0
- package/tests/Server/RouteResolver.test.ts +116 -0
- package/tests/Server/Router.test.ts +39 -0
- package/tests/Server/lib/ContainerServer.test.ts +531 -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 +103 -0
- package/tests/Server/lib/container/HealthHandler.test.ts +30 -0
- package/tests/Server/lib/container/Proxy.test.ts +268 -0
- package/tests/Server/lib/container/Utils.test.ts +47 -0
- package/tests/Test.utils.ts +78 -0
- package/tests/Utils/Utils.test.ts +229 -0
- package/tests/Validation/Validator.test.ts +82 -0
- package/tsconfig.json +26 -0
- package/tsconfig.smoke.json +26 -0
- package/index.js +0 -88
- package/src/API/IKRequest.js +0 -52
- package/src/API/IKResponse.js +0 -119
- package/src/API/IKUtils.js +0 -51
- package/src/BaseEvent/IKProcess.js +0 -77
- package/src/BaseEvent/IKTransaction.js +0 -139
- package/src/Cache/Prototype/IKCache.js +0 -17
- package/src/Cache/Redis/IKRedis.js +0 -148
- package/src/Database/DDB/IKDB.js +0 -56
- package/src/Database/DDB/IKDBBaseExpression.js +0 -130
- package/src/Database/DDB/IKDBBaseQuery.js +0 -151
- package/src/Database/DDB/IKDBQueryBatchGet.js +0 -37
- package/src/Database/DDB/IKDBQueryBatchWrite.js +0 -64
- package/src/Database/DDB/IKDBQueryDelete.js +0 -34
- package/src/Database/DDB/IKDBQueryGet.js +0 -48
- package/src/Database/DDB/IKDBQueryPut.js +0 -87
- package/src/Database/DDB/IKDBQueryScan.js +0 -45
- package/src/Database/DDB/IKDBQueryTransactionalWrite.js +0 -69
- package/src/Database/DDB/IKDBQueryUpdate.js +0 -221
- package/src/Database/DDB/_IKDBQueryTransactionalRead.js +0 -46
- package/src/Database/PSQL/IKDB.js +0 -41
- package/src/Database/PSQL/IKDBBaseQuery.js +0 -26
- package/src/Database/Prototype/IKDB.js +0 -21
- package/src/Database/Prototype/IKDBBaseQuery.js +0 -14
- package/src/IKDynamoStream.js +0 -42
- package/src/IKEventProcessor.js +0 -42
- package/src/IKGlobals.js +0 -24
- package/src/IKRouter.js +0 -47
- package/src/IKStepTransaction.js +0 -14
- package/src/Logger/IKLogger.js +0 -136
- package/src/Mailer/IKMailer.js +0 -69
- package/src/Publisher/IKPublisher.js +0 -44
- package/src/Tracker/IKExecutionTracker.js +0 -79
- package/src/Validation/IKValidation.js +0 -76
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import type { Context } from 'aws-lambda'
|
|
2
|
+
|
|
3
|
+
import Transaction from '../BaseEvent/Transaction.js'
|
|
4
|
+
import Globals from '../Globals.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* CustomError class that extends the built-in Error class.
|
|
8
|
+
* @class
|
|
9
|
+
* @extends Error
|
|
10
|
+
* @param {any} body - The body of the error, which can be an object or a string.
|
|
11
|
+
* @constructor
|
|
12
|
+
* @property {string} name - The name of the error.
|
|
13
|
+
*/
|
|
14
|
+
class CustomError extends Error {
|
|
15
|
+
constructor(body: any) {
|
|
16
|
+
super(body.message || 'Unknown error!')
|
|
17
|
+
this.name = body.error || 'UnknownError'
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Represents an error response from an API.
|
|
23
|
+
* @typedef {Object} ResponseErrorType
|
|
24
|
+
* @property {string} err - The error message.
|
|
25
|
+
* @property {string} [errCode] - The error code, if available.
|
|
26
|
+
*/
|
|
27
|
+
export type ResponseErrorType = {
|
|
28
|
+
err: string
|
|
29
|
+
errCode?: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Represents a response object with various methods for building and manipulating the response.
|
|
34
|
+
* @template BodyType - The type of the response body.
|
|
35
|
+
*/
|
|
36
|
+
export default class Response<BodyType = null> {
|
|
37
|
+
/**
|
|
38
|
+
* The private property that stores the status code.
|
|
39
|
+
* @type {number}
|
|
40
|
+
* @private
|
|
41
|
+
*/
|
|
42
|
+
private statusCode: number
|
|
43
|
+
/**
|
|
44
|
+
* Private property representing the body of an object.
|
|
45
|
+
* @type {any}
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
private body: any
|
|
49
|
+
/**
|
|
50
|
+
* Indicates whether the object is currently piping out.
|
|
51
|
+
* @type {boolean}
|
|
52
|
+
*/
|
|
53
|
+
private isPipingOut: boolean
|
|
54
|
+
/**
|
|
55
|
+
* Private property that stores the headers as an object.
|
|
56
|
+
*/
|
|
57
|
+
private headers: object
|
|
58
|
+
/**
|
|
59
|
+
* Determines whether streaming is enabled or not.
|
|
60
|
+
* @returns {boolean} - True if streaming is enabled, false otherwise.
|
|
61
|
+
*/
|
|
62
|
+
public readonly shouldStream: boolean
|
|
63
|
+
/**
|
|
64
|
+
* Indicates whether the request body should be treated as raw data.
|
|
65
|
+
* @type {boolean}
|
|
66
|
+
*/
|
|
67
|
+
public readonly rawBody: boolean
|
|
68
|
+
/**
|
|
69
|
+
* A boolean flag indicating whether to throw an error when encountering errors.
|
|
70
|
+
* If set to true, any errors encountered will result in an exception being thrown.
|
|
71
|
+
* If set to false, errors will be logged but the program will continue execution.
|
|
72
|
+
*/
|
|
73
|
+
public readonly throwOnErrors: boolean
|
|
74
|
+
/**
|
|
75
|
+
* Indicates whether the transaction ID is disabled.
|
|
76
|
+
* @type {boolean}
|
|
77
|
+
*/
|
|
78
|
+
public readonly disableTransactionID: boolean
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Constructs a new Response object with the given status code, body, and optional behavior.
|
|
82
|
+
* @param {number} statusCode - The HTTP status code of the response.
|
|
83
|
+
* @param {BodyType} body - The body of the response.
|
|
84
|
+
* @param {Object} [optBehaviour] - Optional behavior configuration for the response.
|
|
85
|
+
* @param {boolean} [optBehaviour.shouldStream] - Indicates whether the response should be streamed.
|
|
86
|
+
* @param {boolean} [optBehaviour.rawBody] - Indicates whether the response body should be treated as raw data.
|
|
87
|
+
* @param {boolean} [optBehaviour.throwOnErrors] - Indicates whether errors should be thrown for non-successful status codes.
|
|
88
|
+
* @param {boolean} [optBehaviour
|
|
89
|
+
*/
|
|
90
|
+
constructor(
|
|
91
|
+
statusCode: number,
|
|
92
|
+
body: BodyType,
|
|
93
|
+
optBehaviour?:
|
|
94
|
+
| {
|
|
95
|
+
shouldStream?: boolean
|
|
96
|
+
rawBody?: boolean
|
|
97
|
+
throwOnErrors?: boolean
|
|
98
|
+
disableTransactionID?: boolean
|
|
99
|
+
}
|
|
100
|
+
| undefined
|
|
101
|
+
) {
|
|
102
|
+
// response
|
|
103
|
+
this.statusCode = statusCode
|
|
104
|
+
this.body = body
|
|
105
|
+
this.headers = {
|
|
106
|
+
'Access-Control-Allow-Origin': '*',
|
|
107
|
+
'Access-Control-Allow-Credentials': true,
|
|
108
|
+
'Content-Type': 'application/json',
|
|
109
|
+
}
|
|
110
|
+
// behaviour
|
|
111
|
+
this.isPipingOut = false //internal -- flag to indicate streaming out has started and avoid double stream call
|
|
112
|
+
// options
|
|
113
|
+
this.shouldStream = !!optBehaviour?.shouldStream //
|
|
114
|
+
this.rawBody = !!optBehaviour?.rawBody
|
|
115
|
+
this.throwOnErrors = !!optBehaviour?.throwOnErrors
|
|
116
|
+
this.disableTransactionID = !!optBehaviour?.disableTransactionID
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Get the status code of the response.
|
|
121
|
+
* @returns {number} The status code.
|
|
122
|
+
*/
|
|
123
|
+
public getCode(): number {
|
|
124
|
+
return this.statusCode
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get the body of the object.
|
|
129
|
+
* @returns {BodyType} The body of the object.
|
|
130
|
+
*/
|
|
131
|
+
public getBody(): BodyType {
|
|
132
|
+
return this.body
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Appends a key-value pair into the body object.
|
|
137
|
+
* @param {string} key - The key to append.
|
|
138
|
+
* @param {any} value - The value to append.
|
|
139
|
+
* @returns None
|
|
140
|
+
*/
|
|
141
|
+
public appendIntoBody(key: string, value: any): void {
|
|
142
|
+
this.body[key] = value
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Appends a header to the existing headers object.
|
|
147
|
+
* @param {string} key - The key of the header.
|
|
148
|
+
* @param {any} value - The value of the header.
|
|
149
|
+
* @returns None
|
|
150
|
+
*/
|
|
151
|
+
public appendHeader(key: string, value: any): void {
|
|
152
|
+
this.headers[key] = value
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Builds the response for the given context and transaction.
|
|
157
|
+
* @param {Context} context - The context object.
|
|
158
|
+
* @param {Transaction<any, any, any>} transaction - The transaction object.
|
|
159
|
+
* @param {boolean} optDoNotCallContext - Optional flag to indicate whether to call the context or not.
|
|
160
|
+
* @returns {Promise<void>} - A promise that resolves when the response is built.
|
|
161
|
+
*/
|
|
162
|
+
public async build(
|
|
163
|
+
context: Context,
|
|
164
|
+
transaction: Transaction<any, any, any, any, any>,
|
|
165
|
+
optDoNotCallContext: boolean
|
|
166
|
+
): Promise<void> {
|
|
167
|
+
//Stream support
|
|
168
|
+
if (this.isPipingOut) return
|
|
169
|
+
if (this.shouldStream) return this.pipe(context)
|
|
170
|
+
|
|
171
|
+
//append default fields
|
|
172
|
+
if (transaction.request.getRequestID() && this.body && !this.disableTransactionID)
|
|
173
|
+
this.appendIntoBody('transactionID', transaction.request.getRequestID()) //append transaction ID
|
|
174
|
+
//Raw response support
|
|
175
|
+
if (this.rawBody) return this.rawContext(context, transaction)
|
|
176
|
+
|
|
177
|
+
//build response
|
|
178
|
+
const b = {
|
|
179
|
+
statusCode: this.statusCode,
|
|
180
|
+
headers: this.headers,
|
|
181
|
+
...(this.body ? { body: JSON.stringify(this.body) } : {}),
|
|
182
|
+
}
|
|
183
|
+
//log response and respond to context
|
|
184
|
+
transaction.logger.debug(b)
|
|
185
|
+
//Check for transaction response proxy
|
|
186
|
+
if (transaction.responseProxy) await transaction.responseProxy(this)
|
|
187
|
+
//Batch does not succeed directly just on upper transaction (which will should be a batch)
|
|
188
|
+
if (!optDoNotCallContext) context.succeed(b)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Private method that pipes the response to the given context.
|
|
193
|
+
* @param {Context} context - The context object provided by AWS Lambda.
|
|
194
|
+
* @returns None
|
|
195
|
+
*/
|
|
196
|
+
private pipe(context: Context): void {
|
|
197
|
+
//Check if not streaming
|
|
198
|
+
this.isPipingOut = true
|
|
199
|
+
//build response
|
|
200
|
+
const b = {
|
|
201
|
+
statusCode: this.statusCode,
|
|
202
|
+
body: this.body,
|
|
203
|
+
headers: this.headers,
|
|
204
|
+
}
|
|
205
|
+
//log response and respond to context
|
|
206
|
+
context.succeed(b)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Private method that handles the raw context of a transaction.
|
|
211
|
+
* @param {Context} context - The context object.
|
|
212
|
+
* @param {Transaction<null, BodyType>} transaction - The transaction object.
|
|
213
|
+
* @returns None
|
|
214
|
+
*/
|
|
215
|
+
private rawContext(context: Context, transaction: Transaction<null, BodyType, any>): void {
|
|
216
|
+
//log response and respond to context
|
|
217
|
+
transaction.logger.debug(this.body)
|
|
218
|
+
if (this.getCode() <= 200 && this.getCode() <= 299) context.succeed(this.body)
|
|
219
|
+
else {
|
|
220
|
+
if (!this.throwOnErrors) context.fail(new CustomError(this.body))
|
|
221
|
+
else throw new CustomError(this.body)
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Generates a response object for a missing path parameter error.
|
|
227
|
+
* @param {string} paramName - The name of the missing path parameter.
|
|
228
|
+
* @returns {Response<ResponseErrorType>} - The response object with error details.
|
|
229
|
+
*/
|
|
230
|
+
public static MissingParamResponse(paramName: string): Response<ResponseErrorType> {
|
|
231
|
+
console.warn(`Invalid request - Path parameter ${paramName} is missing.`)
|
|
232
|
+
return new Response<ResponseErrorType>(400, {
|
|
233
|
+
err: `Invalid request. Path parameter ${paramName} is missing.`,
|
|
234
|
+
errCode: Globals.ErrorCode_MissingParam,
|
|
235
|
+
})
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Creates a response object for a missing query parameter error.
|
|
240
|
+
* @param {string} paramName - The name of the missing query parameter.
|
|
241
|
+
* @returns {Response<ResponseErrorType>} - The response object with error details.
|
|
242
|
+
*/
|
|
243
|
+
public static MissingQueryResponse(paramName: string): Response<ResponseErrorType> {
|
|
244
|
+
console.warn(`Invalid request - Query parameter ${paramName} is missing.`)
|
|
245
|
+
return new Response<ResponseErrorType>(400, {
|
|
246
|
+
err: `Invalid request. Query parameter ${paramName} is missing.`,
|
|
247
|
+
errCode: Globals.ErrorCode_MissingParam,
|
|
248
|
+
})
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Creates a BadRequestResponse object with the given parameters.
|
|
253
|
+
* @param {string} [msg] - The error message.
|
|
254
|
+
* @param {string} [errCode] - The error code.
|
|
255
|
+
* @param {any} [optBody] - Optional additional body data.
|
|
256
|
+
* @returns {Response<ResponseErrorType>} - The BadRequestResponse object.
|
|
257
|
+
*/
|
|
258
|
+
public static BadRequestResponse(
|
|
259
|
+
msg?: string,
|
|
260
|
+
errCode?: string,
|
|
261
|
+
optBody?: any
|
|
262
|
+
): Response<ResponseErrorType> {
|
|
263
|
+
console.warn(`Bad request - ${msg}`)
|
|
264
|
+
return new Response<ResponseErrorType>(400, {
|
|
265
|
+
err: msg,
|
|
266
|
+
...(errCode ? { errCode: errCode } : {}),
|
|
267
|
+
...(optBody || {}),
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Creates a BadRequestResponse object with rollback option.
|
|
273
|
+
* @param {string} msg - The error message.
|
|
274
|
+
* @param {string} [errCode] - The error code.
|
|
275
|
+
* @param {any} [optBody] - Optional body to include in the response.
|
|
276
|
+
* @returns {Response<ResponseErrorType>} - The BadRequestResponse object.
|
|
277
|
+
*/
|
|
278
|
+
public static BadRequestResponseWithRollback(
|
|
279
|
+
msg: string,
|
|
280
|
+
errCode?: string,
|
|
281
|
+
optBody?: any
|
|
282
|
+
): Response<ResponseErrorType> {
|
|
283
|
+
console.warn(`Bad request - ${msg}`)
|
|
284
|
+
return new Response<ResponseErrorType>(400, {
|
|
285
|
+
err: msg,
|
|
286
|
+
rollback: true,
|
|
287
|
+
...(errCode ? { errCode: errCode } : {}),
|
|
288
|
+
...(optBody || {}),
|
|
289
|
+
})
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Creates an unauthorized response with the given error message and error code.
|
|
294
|
+
* @param {string} msg - The error message.
|
|
295
|
+
* @param {string} [errCode] - The error code (optional).
|
|
296
|
+
* @returns {Response<ResponseErrorType>} - The unauthorized response.
|
|
297
|
+
*/
|
|
298
|
+
public static UnauthorizedResponse(msg: string, errCode?: string): Response<ResponseErrorType> {
|
|
299
|
+
console.warn(`Denying request - ${msg}`)
|
|
300
|
+
return new Response<ResponseErrorType>(401, {
|
|
301
|
+
err: msg,
|
|
302
|
+
...(errCode ? { errCode: errCode } : {}),
|
|
303
|
+
})
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Creates a success response object with the given body.
|
|
308
|
+
* @param {BodyType} body - The body of the response.
|
|
309
|
+
* @returns {Response<BodyType>} - The success response object.
|
|
310
|
+
*/
|
|
311
|
+
public static SuccessResponse<BodyType>(body: BodyType): Response<BodyType> {
|
|
312
|
+
return new Response<BodyType>(200, (body ? body : {}) as BodyType)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Creates a redirect response with the specified URL.
|
|
317
|
+
* @param {string} url - The URL to redirect to.
|
|
318
|
+
* @returns {Response<null>} - The redirect response.
|
|
319
|
+
*/
|
|
320
|
+
public static RedirectResponse(url: string): Response<null> {
|
|
321
|
+
const resp = new Response<null>(302, null)
|
|
322
|
+
resp.appendHeader('Location', url)
|
|
323
|
+
return resp
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Creates a success response with no content.
|
|
328
|
+
* @returns {Response<null>} A response object with a status code of 204 and no content.
|
|
329
|
+
*/
|
|
330
|
+
public static SuccessNoContentResponse(): Response<null> {
|
|
331
|
+
return new Response<null>(204, null)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Creates a success response object with a streaming body and specified content type.
|
|
336
|
+
* @param {any} stream - The stream object to be used as the response body.
|
|
337
|
+
* @param {string} contentType - The content type of the response.
|
|
338
|
+
* @returns {Response} - The success response object.
|
|
339
|
+
*/
|
|
340
|
+
public static SuccessStreamResponse(stream: any, contentType: string): Response {
|
|
341
|
+
const resp = new Response(200, stream, {
|
|
342
|
+
shouldStream: true,
|
|
343
|
+
})
|
|
344
|
+
resp.appendHeader('Connection', 'keep-alive')
|
|
345
|
+
if (contentType) resp.appendHeader('Content-Type', contentType)
|
|
346
|
+
return resp
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Creates a simple HTTP response with the given body and optional status code.
|
|
351
|
+
* @param {BodyType} body - The body of the response.
|
|
352
|
+
* @param {number} [optionalCode] - The optional status code of the response. Defaults to 200.
|
|
353
|
+
* @returns {Response<BodyType>} - The created response object.
|
|
354
|
+
*/
|
|
355
|
+
public static SimpleResponse<BodyType>(
|
|
356
|
+
body: BodyType,
|
|
357
|
+
optionalCode?: number
|
|
358
|
+
): Response<BodyType> {
|
|
359
|
+
const resp = new Response<BodyType>(optionalCode || 200, body)
|
|
360
|
+
return resp
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
public static StepFunctionResponse<BodyType>(body: BodyType, optionalCode?: number) {
|
|
364
|
+
const resp = new Response<BodyType>(optionalCode || 200, body, {
|
|
365
|
+
rawBody: true,
|
|
366
|
+
throwOnErrors: true,
|
|
367
|
+
})
|
|
368
|
+
return resp
|
|
369
|
+
}
|
|
370
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Context,
|
|
3
|
+
DynamoDBBatchResponse,
|
|
4
|
+
DynamoDBRecord,
|
|
5
|
+
DynamoDBStreamEvent,
|
|
6
|
+
} from 'aws-lambda'
|
|
7
|
+
|
|
8
|
+
import Transaction, { TransactionConfig } from './Transaction.js'
|
|
9
|
+
import Response, { ResponseErrorType } from '../API/Response.js'
|
|
10
|
+
import Globals from '../Globals.js'
|
|
11
|
+
import Utils from '../Util/Utils.js'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Interface representing a DynamoDB record with marshalled data.
|
|
15
|
+
* Extends the DynamoDBRecord interface.
|
|
16
|
+
* @property {object} Keys - The keys of the record.
|
|
17
|
+
* @property {object} OldImage - The old image of the record.
|
|
18
|
+
* @property {object} NewImage - The new image of the record.
|
|
19
|
+
*/
|
|
20
|
+
export interface DynamoDBMarshalledRecord extends DynamoDBRecord {
|
|
21
|
+
marshalled: {
|
|
22
|
+
Keys?: object
|
|
23
|
+
OldImage?: object
|
|
24
|
+
NewImage?: object
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Defines a type for executing a transaction on DynamoDB.
|
|
30
|
+
* @param {Transaction<null, ResponseInnerType | ResponseErrorType, DynamoDBBatchResponse | null>} transaction - The transaction to execute.
|
|
31
|
+
* @param {DynamoDBMarshalledRecord} recordContent - The content of the DynamoDB record.
|
|
32
|
+
* @returns A promise that resolves to a response or a DynamoDB batch response.
|
|
33
|
+
*/
|
|
34
|
+
export type DynamoTransactionExecution<ResponseInnerType> = (
|
|
35
|
+
transaction: Transaction<
|
|
36
|
+
null,
|
|
37
|
+
ResponseInnerType | ResponseErrorType,
|
|
38
|
+
DynamoDBBatchResponse | null
|
|
39
|
+
>,
|
|
40
|
+
recordContent: DynamoDBMarshalledRecord
|
|
41
|
+
) => Promise<Response<ResponseInnerType | ResponseErrorType> | DynamoDBBatchResponse | null>
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Represents a DynamoDB transaction handler that processes events from a DynamoDB stream.
|
|
45
|
+
* @template ResponseInnerType - The inner type of the response.
|
|
46
|
+
*/
|
|
47
|
+
export default class DynamoTransaction<ResponseInnerType> {
|
|
48
|
+
/**
|
|
49
|
+
* A boolean flag indicating whether failures are allowed.
|
|
50
|
+
*/
|
|
51
|
+
private readonly allowFailure: boolean
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Readonly property that holds the transaction configuration.
|
|
55
|
+
*/
|
|
56
|
+
private readonly config: TransactionConfig
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The context object that provides information about the current execution context.
|
|
60
|
+
* @type {Context}
|
|
61
|
+
*/
|
|
62
|
+
private readonly context: Context
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Represents an event from a DynamoDB stream.
|
|
66
|
+
* @type {DynamoDBStreamEvent}
|
|
67
|
+
*/
|
|
68
|
+
private readonly event: DynamoDBStreamEvent
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Constructor for a TransactionHandler object.
|
|
72
|
+
* @param {DynamoDBStreamEvent} event - The DynamoDB stream event that triggered the transaction.
|
|
73
|
+
* @param {Context} context - The AWS Lambda context object.
|
|
74
|
+
* @param {TransactionConfig} [config] - Optional configuration for the transaction.
|
|
75
|
+
* @param {boolean} [allowFailure] - Flag to indicate whether to allow transaction failure.
|
|
76
|
+
* @returns None
|
|
77
|
+
*/
|
|
78
|
+
constructor(
|
|
79
|
+
event: DynamoDBStreamEvent,
|
|
80
|
+
context: Context,
|
|
81
|
+
config?: TransactionConfig,
|
|
82
|
+
allowFailure?: boolean
|
|
83
|
+
) {
|
|
84
|
+
this.event = event
|
|
85
|
+
this.context = context
|
|
86
|
+
this.config = config || {}
|
|
87
|
+
this.allowFailure = !!allowFailure
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Processes the event execution and returns a response based on the outcome.
|
|
92
|
+
* @param {DynamoTransactionExecution<ResponseInnerType>} execution - The execution object to process.
|
|
93
|
+
* @returns {Promise<Response<ResponseErrorType | null> | null | DynamoDBBatchResponse>} A promise that resolves to a response object or null.
|
|
94
|
+
* @throws {Error} If the response code is not within the success range and failure is not allowed.
|
|
95
|
+
*/
|
|
96
|
+
public async processEvent(
|
|
97
|
+
execution: DynamoTransactionExecution<ResponseInnerType>
|
|
98
|
+
): Promise<Response<ResponseErrorType | null> | null | DynamoDBBatchResponse> {
|
|
99
|
+
const resp = await this.processRawEvent(execution)
|
|
100
|
+
if (
|
|
101
|
+
!this.allowFailure &&
|
|
102
|
+
resp &&
|
|
103
|
+
resp instanceof Response &&
|
|
104
|
+
!(resp.getCode() >= 200 && resp.getCode() < 300)
|
|
105
|
+
)
|
|
106
|
+
throw new Error(JSON.stringify(resp.getBody() || {}))
|
|
107
|
+
else if (resp) return resp
|
|
108
|
+
return null
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Processes a raw event by executing a transaction on each record in the event.
|
|
113
|
+
* @param {DynamoTransactionExecution<ResponseInnerType>} execution - The transaction execution function.
|
|
114
|
+
* @returns {Promise<Response<ResponseErrorType | any> | null | DynamoDBBatchResponse>} A promise that resolves to a response object, null, or a DynamoDB batch response.
|
|
115
|
+
*/
|
|
116
|
+
private async processRawEvent(
|
|
117
|
+
execution: DynamoTransactionExecution<ResponseInnerType>
|
|
118
|
+
): Promise<Response<ResponseErrorType | any> | null | DynamoDBBatchResponse> {
|
|
119
|
+
// safe check for empty events?
|
|
120
|
+
if (this.event.Records && this.event.Records.length > 0) {
|
|
121
|
+
// Regular cleanup of tmp disk to avoid tmp overflow on reused lambdas
|
|
122
|
+
if (!this.config?.skipCleanTmp) await Utils.cleanTemporaryFolder()
|
|
123
|
+
// init transaction for all records
|
|
124
|
+
return await new Transaction<null, any, DynamoDBBatchResponse | null>(
|
|
125
|
+
this.event,
|
|
126
|
+
this.context,
|
|
127
|
+
{
|
|
128
|
+
...this.config,
|
|
129
|
+
syncReturn: true,
|
|
130
|
+
}
|
|
131
|
+
).execute(async transaction => {
|
|
132
|
+
// for each available event
|
|
133
|
+
const failureIDs: Array<string> = []
|
|
134
|
+
for (const eventRecordIdx in this.event.Records) {
|
|
135
|
+
const eventRecord = this.event.Records[eventRecordIdx]
|
|
136
|
+
const record = {
|
|
137
|
+
...eventRecord,
|
|
138
|
+
marshalled: {
|
|
139
|
+
...(eventRecord.dynamodb?.Keys
|
|
140
|
+
? { Keys: Utils.ddbUnmarshall(eventRecord.dynamodb?.Keys) }
|
|
141
|
+
: {}),
|
|
142
|
+
...(eventRecord.dynamodb?.OldImage
|
|
143
|
+
? { OldImage: Utils.ddbUnmarshall(eventRecord.dynamodb?.OldImage) }
|
|
144
|
+
: {}),
|
|
145
|
+
...(eventRecord.dynamodb?.NewImage
|
|
146
|
+
? { NewImage: Utils.ddbUnmarshall(eventRecord.dynamodb?.NewImage) }
|
|
147
|
+
: {}),
|
|
148
|
+
},
|
|
149
|
+
}
|
|
150
|
+
// Call execution with marshalled item
|
|
151
|
+
const resp = await execution(transaction, record)
|
|
152
|
+
// check for failure
|
|
153
|
+
if (
|
|
154
|
+
!resp ||
|
|
155
|
+
(resp instanceof Response && !(resp?.getCode() >= 200 && resp?.getCode() < 300))
|
|
156
|
+
) {
|
|
157
|
+
// response with failures or fail hard at first
|
|
158
|
+
if (this.allowFailure) failureIDs.push(eventRecord.eventID!)
|
|
159
|
+
else return resp
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// not errored and loop ended - succeeded (might have failures)
|
|
163
|
+
if (this.allowFailure)
|
|
164
|
+
return {
|
|
165
|
+
batchItemFailures: failureIDs.map(id => ({ itemIdentifier: id })),
|
|
166
|
+
}
|
|
167
|
+
return Response.SuccessResponse(null)
|
|
168
|
+
})
|
|
169
|
+
} else
|
|
170
|
+
return Response.BadRequestResponse(
|
|
171
|
+
Globals.ErrorResponseNoRecords,
|
|
172
|
+
Globals.ErrorCode_NoRecords
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { Context, SQSBatchResponse, SQSEvent } from 'aws-lambda'
|
|
2
|
+
|
|
3
|
+
import Transaction, { TransactionConfig } from './Transaction.js'
|
|
4
|
+
import Response, { ResponseErrorType } from '../API/Response.js'
|
|
5
|
+
import Globals from '../Globals.js'
|
|
6
|
+
import Utils from '../Util/Utils.js'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Type definition for an event processor execution function.
|
|
10
|
+
* @param {Transaction<null, ResponseInnerType | ResponseErrorType, SQSBatchResponse>} transaction - The transaction object.
|
|
11
|
+
* @param {string | object} recordContent - The content of the record being processed.
|
|
12
|
+
* @returns {Promise<Response<ResponseInnerType | ResponseErrorType> | SQSBatchResponse>} - A promise that resolves to the response or batch response.
|
|
13
|
+
*/
|
|
14
|
+
export type EventProcessorExecution<ResponseInnerType> = (
|
|
15
|
+
transaction: Transaction<null, ResponseInnerType | ResponseErrorType, SQSBatchResponse | null>,
|
|
16
|
+
recordContent: string | object
|
|
17
|
+
) => Promise<Response<ResponseInnerType | ResponseErrorType> | SQSBatchResponse | null>
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* EventProcessor class that processes events from an SQS queue.
|
|
21
|
+
* @template ResponseInnerType - The type of the inner response object.
|
|
22
|
+
*/
|
|
23
|
+
export default class EventProcessor<ResponseInnerType> {
|
|
24
|
+
/**
|
|
25
|
+
* A boolean flag indicating whether failures are allowed or not.
|
|
26
|
+
* @readonly
|
|
27
|
+
*/
|
|
28
|
+
private readonly allowFailure: boolean
|
|
29
|
+
/**
|
|
30
|
+
* The configuration object for the API transaction.
|
|
31
|
+
*/
|
|
32
|
+
private readonly config: TransactionConfig
|
|
33
|
+
/**
|
|
34
|
+
* The private readonly context property of the class.
|
|
35
|
+
* @type {Context}
|
|
36
|
+
*/
|
|
37
|
+
private readonly context: Context
|
|
38
|
+
/**
|
|
39
|
+
* The SQS event object that triggered the Lambda function.
|
|
40
|
+
*/
|
|
41
|
+
private readonly event: SQSEvent
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Constructs a new instance of the class.
|
|
45
|
+
* @param {SQSEvent} event - The event object representing the incoming SQS message.
|
|
46
|
+
* @param {Context} context - The context object representing the AWS Lambda execution context.
|
|
47
|
+
* @param {TransactionConfig} [config] - Optional configuration object for the transaction.
|
|
48
|
+
* @param {boolean} [allowFailure] - Optional flag indicating whether to allow failure for the transaction.
|
|
49
|
+
* @returns None
|
|
50
|
+
*/
|
|
51
|
+
constructor(
|
|
52
|
+
event: SQSEvent,
|
|
53
|
+
context: Context,
|
|
54
|
+
config?: TransactionConfig,
|
|
55
|
+
allowFailure?: boolean
|
|
56
|
+
) {
|
|
57
|
+
this.event = event
|
|
58
|
+
this.context = context
|
|
59
|
+
this.config = config || {}
|
|
60
|
+
this.allowFailure = !!allowFailure
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Processes an event using the provided execution object and returns a response.
|
|
65
|
+
* @param {EventProcessorExecution<ResponseInnerType>} execution - The execution object containing the event to process.
|
|
66
|
+
* @param {boolean} [doNotDecodeMessage] - Optional flag indicating whether to decode the message.
|
|
67
|
+
* @returns {Promise<Response<ResponseErrorType> | null | SQSBatchResponse>} - A promise that resolves to the response object, or null if no response is available.
|
|
68
|
+
* @throws {Error} - Throws an error if the response code is not within the range of 200 to 299 and failure is not allowed.
|
|
69
|
+
*/
|
|
70
|
+
public async processEvent(
|
|
71
|
+
execution: EventProcessorExecution<ResponseInnerType>,
|
|
72
|
+
doNotDecodeMessage?: boolean
|
|
73
|
+
): Promise<Response<ResponseErrorType | null> | null | SQSBatchResponse> {
|
|
74
|
+
const resp = await this.processRawEvent(execution, !!doNotDecodeMessage)
|
|
75
|
+
if (
|
|
76
|
+
!this.allowFailure &&
|
|
77
|
+
resp &&
|
|
78
|
+
resp instanceof Response &&
|
|
79
|
+
!(resp.getCode() >= 200 && resp.getCode() < 300)
|
|
80
|
+
)
|
|
81
|
+
throw new Error(JSON.stringify(resp.getBody() || {}))
|
|
82
|
+
else if (resp) return resp
|
|
83
|
+
return null
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Processes a raw event by executing the provided execution function and handling any errors or failures.
|
|
88
|
+
* @param {EventProcessorExecution<ResponseInnerType>} execution - The execution function to process the event.
|
|
89
|
+
* @param {boolean} doNotDecodeMessage - Flag indicating whether to decode the message or not.
|
|
90
|
+
* @returns {Promise<Response<ResponseErrorType> | null | SQSBatchResponse>} - A promise that resolves to a response object, null, or a SQS batch response.
|
|
91
|
+
*/
|
|
92
|
+
private async processRawEvent(
|
|
93
|
+
execution: EventProcessorExecution<ResponseInnerType>,
|
|
94
|
+
doNotDecodeMessage: boolean
|
|
95
|
+
): Promise<Response<ResponseErrorType | any> | null | SQSBatchResponse> {
|
|
96
|
+
// safe check for empty events?
|
|
97
|
+
if (this.event.Records && this.event.Records.length > 0) {
|
|
98
|
+
// Regular cleanup of tmp disk to avoid tmp overflow on reused lambdas
|
|
99
|
+
if (!this.config?.skipCleanTmp) await Utils.cleanTemporaryFolder()
|
|
100
|
+
// init transaction for all records
|
|
101
|
+
return await new Transaction<null, any, SQSBatchResponse | null>(this.event, this.context, {
|
|
102
|
+
...this.config,
|
|
103
|
+
syncReturn: true,
|
|
104
|
+
}).execute(async transaction => {
|
|
105
|
+
// Map records with decoded message when required
|
|
106
|
+
const decodedRecords: string[] | object[] = this.event.Records.map(eventRecord =>
|
|
107
|
+
doNotDecodeMessage ? eventRecord.body : JSON.parse(eventRecord.body)
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
// for each available event
|
|
111
|
+
const failureIDs: Array<string> = []
|
|
112
|
+
for (const eventRecordIdx in decodedRecords) {
|
|
113
|
+
const eventRecord = decodedRecords[eventRecordIdx]
|
|
114
|
+
const message = this.event.Records[eventRecordIdx]
|
|
115
|
+
// Call execution
|
|
116
|
+
const resp = await execution(transaction, eventRecord)
|
|
117
|
+
// check for failure
|
|
118
|
+
if (
|
|
119
|
+
!resp ||
|
|
120
|
+
(resp instanceof Response && !(resp?.getCode() >= 200 && resp?.getCode() < 300))
|
|
121
|
+
) {
|
|
122
|
+
// response with failures or fail hard at first
|
|
123
|
+
if (this.allowFailure) failureIDs.push(message.messageId)
|
|
124
|
+
else return resp
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// not errored and loop ended - succeeded (might have failures)
|
|
128
|
+
if (this.allowFailure)
|
|
129
|
+
return {
|
|
130
|
+
batchItemFailures: failureIDs.map(id => ({ itemIdentifier: id })),
|
|
131
|
+
}
|
|
132
|
+
return Response.SuccessResponse(null)
|
|
133
|
+
})
|
|
134
|
+
} else
|
|
135
|
+
return Response.BadRequestResponse(
|
|
136
|
+
Globals.ErrorResponseNoRecords,
|
|
137
|
+
Globals.ErrorCode_NoRecords
|
|
138
|
+
) // no event to be processed?
|
|
139
|
+
}
|
|
140
|
+
}
|