@creator.co/wapi 1.2.4 → 1.2.6
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 +1 -1
- package/README.md +216 -5
- package/dist/index.d.ts +15 -0
- package/dist/index.js.map +1 -1
- package/dist/jest.config.js +1 -1
- package/dist/jest.config.js.map +1 -1
- package/dist/package.json +13 -2
- package/dist/src/API/Request.d.ts +45 -82
- package/dist/src/API/Request.js +49 -77
- package/dist/src/API/Request.js.map +1 -1
- package/dist/src/API/Response.d.ts +94 -163
- package/dist/src/API/Response.js +101 -161
- package/dist/src/API/Response.js.map +1 -1
- package/dist/src/API/Utils.d.ts +21 -42
- package/dist/src/API/Utils.js +22 -43
- package/dist/src/API/Utils.js.map +1 -1
- package/dist/src/BaseEvent/EventProcessor.d.ts +32 -55
- package/dist/src/BaseEvent/EventProcessor.js +30 -38
- package/dist/src/BaseEvent/EventProcessor.js.map +1 -1
- package/dist/src/BaseEvent/Process.d.ts +20 -43
- package/dist/src/BaseEvent/Process.js +16 -27
- package/dist/src/BaseEvent/Process.js.map +1 -1
- package/dist/src/BaseEvent/Transaction.d.ts +104 -2
- package/dist/src/BaseEvent/Transaction.js +196 -41
- package/dist/src/BaseEvent/Transaction.js.map +1 -1
- package/dist/src/Config/Configuration.d.ts +48 -66
- package/dist/src/Config/Configuration.js +25 -42
- package/dist/src/Config/Configuration.js.map +1 -1
- package/dist/src/Config/EnvironmentVar.d.ts +30 -57
- package/dist/src/Config/EnvironmentVar.js +28 -41
- package/dist/src/Config/EnvironmentVar.js.map +1 -1
- package/dist/src/Crypto/Crypto.d.ts +17 -35
- package/dist/src/Crypto/Crypto.js +12 -21
- package/dist/src/Crypto/Crypto.js.map +1 -1
- package/dist/src/Crypto/JWT.d.ts +21 -32
- package/dist/src/Crypto/JWT.js +14 -22
- package/dist/src/Crypto/JWT.js.map +1 -1
- package/dist/src/Database/Database.d.ts +18 -0
- package/dist/src/Database/Database.js +18 -0
- package/dist/src/Database/Database.js.map +1 -0
- package/dist/src/Database/DatabaseManager.d.ts +32 -0
- package/dist/src/Database/DatabaseManager.js +50 -0
- package/dist/src/Database/DatabaseManager.js.map +1 -0
- package/dist/src/Database/DatabaseTransaction.d.ts +65 -0
- package/dist/src/Database/DatabaseTransaction.js +183 -0
- package/dist/src/Database/DatabaseTransaction.js.map +1 -0
- package/dist/src/Database/integrations/knex/KnexDatabase.d.ts +22 -0
- package/dist/src/Database/integrations/knex/KnexDatabase.js +108 -0
- package/dist/src/Database/integrations/knex/KnexDatabase.js.map +1 -0
- package/dist/src/Database/integrations/knex/KnexTransaction.d.ts +37 -0
- package/dist/src/Database/integrations/knex/KnexTransaction.js +60 -0
- package/dist/src/Database/integrations/knex/KnexTransaction.js.map +1 -0
- package/dist/src/Database/integrations/pgsql/PostgresDatabase.d.ts +30 -0
- package/dist/src/Database/integrations/pgsql/PostgresDatabase.js +108 -0
- package/dist/src/Database/integrations/pgsql/PostgresDatabase.js.map +1 -0
- package/dist/src/Database/integrations/pgsql/PostgresTransaction.d.ts +37 -0
- package/dist/src/Database/integrations/pgsql/PostgresTransaction.js +60 -0
- package/dist/src/Database/integrations/pgsql/PostgresTransaction.js.map +1 -0
- package/dist/src/Globals.d.ts +26 -94
- package/dist/src/Globals.js +26 -95
- package/dist/src/Globals.js.map +1 -1
- package/dist/src/Logger/Logger.d.ts +82 -105
- package/dist/src/Logger/Logger.js +111 -136
- package/dist/src/Logger/Logger.js.map +1 -1
- package/dist/src/Mailer/Mailer.d.ts +39 -75
- package/dist/src/Mailer/Mailer.js +36 -65
- package/dist/src/Mailer/Mailer.js.map +1 -1
- package/dist/src/Publisher/Publisher.d.ts +17 -25
- package/dist/src/Publisher/Publisher.js +21 -32
- package/dist/src/Publisher/Publisher.js.map +1 -1
- package/dist/src/Server/RouteResolver.d.ts +14 -22
- package/dist/src/Server/RouteResolver.js +21 -34
- package/dist/src/Server/RouteResolver.js.map +1 -1
- package/dist/src/Server/Router.d.ts +72 -51
- package/dist/src/Server/Router.js +8 -17
- package/dist/src/Server/Router.js.map +1 -1
- package/dist/src/Server/lib/ContainerServer.d.ts +15 -31
- package/dist/src/Server/lib/ContainerServer.js +13 -28
- package/dist/src/Server/lib/ContainerServer.js.map +1 -1
- package/dist/src/Server/lib/Server.d.ts +17 -32
- package/dist/src/Server/lib/Server.js +18 -28
- package/dist/src/Server/lib/Server.js.map +1 -1
- package/dist/src/Server/lib/container/GenericHandler.d.ts +5 -0
- package/dist/src/Server/lib/container/GenericHandler.js +16 -3
- package/dist/src/Server/lib/container/GenericHandler.js.map +1 -1
- package/dist/src/Server/lib/container/GenericHandlerEvent.d.ts +22 -37
- package/dist/src/Server/lib/container/GenericHandlerEvent.js +29 -41
- package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +1 -1
- package/dist/src/Server/lib/container/HealthHandler.d.ts +6 -0
- package/dist/src/Server/lib/container/HealthHandler.js +6 -0
- package/dist/src/Server/lib/container/HealthHandler.js.map +1 -1
- package/dist/src/Server/lib/container/Proxy.d.ts +24 -52
- package/dist/src/Server/lib/container/Proxy.js +52 -52
- package/dist/src/Server/lib/container/Proxy.js.map +1 -1
- package/dist/src/Server/lib/container/Utils.d.ts +6 -10
- package/dist/src/Server/lib/container/Utils.js +6 -10
- package/dist/src/Server/lib/container/Utils.js.map +1 -1
- package/dist/src/Validation/Validator.d.ts +9 -13
- package/dist/src/Validation/Validator.js +8 -12
- package/dist/src/Validation/Validator.js.map +1 -1
- package/index.ts +15 -0
- package/jest.config.ts +1 -1
- package/package.json +13 -2
- package/src/API/Request.ts +66 -84
- package/src/API/Response.ts +144 -203
- package/src/API/Utils.ts +28 -44
- package/src/BaseEvent/EventProcessor.ts +52 -77
- package/src/BaseEvent/Process.ts +27 -52
- package/src/BaseEvent/Transaction.ts +147 -27
- package/src/Config/Configuration.ts +59 -76
- package/src/Config/EnvironmentVar.ts +39 -62
- package/src/Crypto/Crypto.ts +20 -36
- package/src/Crypto/JWT.ts +31 -35
- package/src/Database/Database.ts +19 -0
- package/src/Database/DatabaseManager.ts +51 -0
- package/src/Database/DatabaseTransaction.ts +118 -0
- package/src/Database/integrations/knex/KnexDatabase.ts +47 -0
- package/src/Database/integrations/knex/KnexTransaction.ts +51 -0
- package/src/Database/integrations/pgsql/PostgresDatabase.ts +49 -0
- package/src/Database/integrations/pgsql/PostgresTransaction.ts +54 -0
- package/src/Database/types.d.ts +49 -0
- package/src/Globals.ts +28 -96
- package/src/Logger/Logger.ts +141 -160
- package/src/Mailer/Mailer.ts +43 -76
- package/src/Publisher/Publisher.ts +31 -40
- package/src/Server/RouteResolver.ts +31 -52
- package/src/Server/Router.ts +75 -54
- package/src/Server/lib/ContainerServer.ts +20 -32
- package/src/Server/lib/Server.ts +19 -34
- package/src/Server/lib/container/GenericHandler.ts +17 -3
- package/src/Server/lib/container/GenericHandlerEvent.ts +44 -54
- package/src/Server/lib/container/HealthHandler.ts +6 -0
- package/src/Server/lib/container/Proxy.ts +39 -58
- package/src/Server/lib/container/Utils.ts +7 -10
- package/src/Validation/Validator.ts +11 -13
- package/tests/API/Response.test.ts +55 -56
- package/tests/BaseEvent/EventProcessor.test.ts +49 -50
- package/tests/BaseEvent/Process.test.ts +2 -2
- package/tests/BaseEvent/Transaction.test.ts +102 -44
- package/tests/Config/Config.test.ts +27 -27
- package/tests/Config/EnvironmentVar.test.ts +54 -18
- package/tests/Database/DatabaseManager.test.ts +55 -0
- package/tests/Database/integrations/knex/KnexDatabase.test.ts +53 -0
- package/tests/Database/integrations/knex/KnexTransaction.test.ts +133 -0
- package/tests/Database/integrations/pg/PostgresDatabase.test.ts +50 -0
- package/tests/Database/integrations/pg/PostgresTransaction.test.ts +51 -0
- package/tests/Publisher/Publisher.test.ts +3 -3
- package/tests/Server/lib/ContainerServer.test.ts +21 -22
- package/tests/Server/lib/container/GenericHandler.test.ts +31 -32
- package/tests/Server/lib/container/GenericHandlerEvent.test.ts +2 -2
- package/tests/Server/lib/container/HealthHandler.test.ts +6 -7
- package/tests/Server/lib/container/Proxy.test.ts +37 -35
- package/tsconfig.json +6 -1
|
@@ -4,68 +4,48 @@ import Transaction, { TransactionConfig } from './Transaction'
|
|
|
4
4
|
import Response, { ResponseErrorType } from '../API/Response'
|
|
5
5
|
import Globals from '../Globals'
|
|
6
6
|
|
|
7
|
-
// Handler
|
|
8
7
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* @
|
|
12
|
-
* @
|
|
13
|
-
* @template ResponseInnerType
|
|
8
|
+
* Type definition for an event processor execution function.
|
|
9
|
+
* @param {Transaction<null, ResponseInnerType | ResponseErrorType, SQSBatchResponse>} transaction - The transaction object.
|
|
10
|
+
* @param {string | object} recordContent - The content of the record being processed.
|
|
11
|
+
* @returns {Promise<Response<ResponseInnerType | ResponseErrorType> | SQSBatchResponse>} - A promise that resolves to the response or batch response.
|
|
14
12
|
*/
|
|
15
13
|
export type EventProcessorExecution<ResponseInnerType> = (
|
|
16
|
-
transaction: Transaction<null, ResponseInnerType | ResponseErrorType, SQSBatchResponse>,
|
|
14
|
+
transaction: Transaction<null, ResponseInnerType | ResponseErrorType, SQSBatchResponse | null>,
|
|
17
15
|
recordContent: string | object
|
|
18
|
-
) => Promise<Response<ResponseInnerType | ResponseErrorType> | SQSBatchResponse>
|
|
16
|
+
) => Promise<Response<ResponseInnerType | ResponseErrorType> | SQSBatchResponse | null>
|
|
19
17
|
|
|
20
18
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* @export
|
|
24
|
-
* @class EventProcessor
|
|
25
|
-
* @typedef {EventProcessor}
|
|
26
|
-
* @template ResponseInnerType
|
|
19
|
+
* EventProcessor class that processes events from an SQS queue.
|
|
20
|
+
* @template ResponseInnerType - The type of the inner response object.
|
|
27
21
|
*/
|
|
28
22
|
export default class EventProcessor<ResponseInnerType> {
|
|
29
23
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* @private
|
|
24
|
+
* A boolean flag indicating whether failures are allowed or not.
|
|
33
25
|
* @readonly
|
|
34
|
-
* @type {boolean}
|
|
35
26
|
*/
|
|
36
|
-
private readonly
|
|
27
|
+
private readonly allowFailure: boolean
|
|
37
28
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* @private
|
|
41
|
-
* @readonly
|
|
42
|
-
* @type {TransactionConfig}
|
|
29
|
+
* The configuration object for the API transaction.
|
|
43
30
|
*/
|
|
44
|
-
private readonly
|
|
31
|
+
private readonly config: TransactionConfig
|
|
45
32
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* @private
|
|
49
|
-
* @readonly
|
|
33
|
+
* The private readonly context property of the class.
|
|
50
34
|
* @type {Context}
|
|
51
35
|
*/
|
|
52
|
-
private readonly
|
|
36
|
+
private readonly context: Context
|
|
53
37
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* @private
|
|
57
|
-
* @readonly
|
|
58
|
-
* @type {SQSEvent}
|
|
38
|
+
* The SQS event object that triggered the Lambda function.
|
|
59
39
|
*/
|
|
60
|
-
private readonly
|
|
40
|
+
private readonly event: SQSEvent
|
|
41
|
+
|
|
61
42
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* @
|
|
65
|
-
* @param {
|
|
66
|
-
* @param {
|
|
67
|
-
* @
|
|
68
|
-
* @param {?boolean} [allowFailure]
|
|
43
|
+
* Constructs a new instance of the class.
|
|
44
|
+
* @param {SQSEvent} event - The event object representing the incoming SQS message.
|
|
45
|
+
* @param {Context} context - The context object representing the AWS Lambda execution context.
|
|
46
|
+
* @param {TransactionConfig} [config] - Optional configuration object for the transaction.
|
|
47
|
+
* @param {boolean} [allowFailure] - Optional flag indicating whether to allow failure for the transaction.
|
|
48
|
+
* @returns None
|
|
69
49
|
*/
|
|
70
50
|
constructor(
|
|
71
51
|
event: SQSEvent,
|
|
@@ -73,26 +53,26 @@ export default class EventProcessor<ResponseInnerType> {
|
|
|
73
53
|
config?: TransactionConfig,
|
|
74
54
|
allowFailure?: boolean
|
|
75
55
|
) {
|
|
76
|
-
this.
|
|
77
|
-
this.
|
|
78
|
-
this.
|
|
79
|
-
this.
|
|
56
|
+
this.event = event
|
|
57
|
+
this.context = context
|
|
58
|
+
this.config = config || {}
|
|
59
|
+
this.allowFailure = !!allowFailure
|
|
80
60
|
}
|
|
61
|
+
|
|
81
62
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* @
|
|
85
|
-
* @
|
|
86
|
-
* @
|
|
87
|
-
* @returns {(Promise<Response<ResponseErrorType> | null | SQSBatchResponse>)}
|
|
63
|
+
* Processes an event using the provided execution object and returns a response.
|
|
64
|
+
* @param {EventProcessorExecution<ResponseInnerType>} execution - The execution object containing the event to process.
|
|
65
|
+
* @param {boolean} [doNotDecodeMessage] - Optional flag indicating whether to decode the message.
|
|
66
|
+
* @returns {Promise<Response<ResponseErrorType> | null | SQSBatchResponse>} - A promise that resolves to the response object, or null if no response is available.
|
|
67
|
+
* @throws {Error} - Throws an error if the response code is not within the range of 200 to 299 and failure is not allowed.
|
|
88
68
|
*/
|
|
89
69
|
async processEvent(
|
|
90
70
|
execution: EventProcessorExecution<ResponseInnerType>,
|
|
91
71
|
doNotDecodeMessage?: boolean
|
|
92
|
-
): Promise<Response<ResponseErrorType> | null | SQSBatchResponse> {
|
|
93
|
-
const resp = await this.
|
|
72
|
+
): Promise<Response<ResponseErrorType | null> | null | SQSBatchResponse> {
|
|
73
|
+
const resp = await this.processRawEvent(execution, !!doNotDecodeMessage)
|
|
94
74
|
if (
|
|
95
|
-
!this.
|
|
75
|
+
!this.allowFailure &&
|
|
96
76
|
resp &&
|
|
97
77
|
resp instanceof Response &&
|
|
98
78
|
!(resp.getCode() >= 200 && resp.getCode() < 300)
|
|
@@ -101,31 +81,26 @@ export default class EventProcessor<ResponseInnerType> {
|
|
|
101
81
|
else if (resp) return resp
|
|
102
82
|
return null
|
|
103
83
|
}
|
|
84
|
+
|
|
104
85
|
/**
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* @
|
|
108
|
-
* @
|
|
109
|
-
* @param {boolean} doNotDecodeMessage
|
|
110
|
-
* @returns {(Promise<Response<ResponseErrorType> | null | SQSBatchResponse>)}
|
|
86
|
+
* Processes a raw event by executing the provided execution function and handling any errors or failures.
|
|
87
|
+
* @param {EventProcessorExecution<ResponseInnerType>} execution - The execution function to process the event.
|
|
88
|
+
* @param {boolean} doNotDecodeMessage - Flag indicating whether to decode the message or not.
|
|
89
|
+
* @returns {Promise<Response<ResponseErrorType> | null | SQSBatchResponse>} - A promise that resolves to a response object, null, or a SQS batch response.
|
|
111
90
|
*/
|
|
112
|
-
async
|
|
91
|
+
private async processRawEvent(
|
|
113
92
|
execution: EventProcessorExecution<ResponseInnerType>,
|
|
114
93
|
doNotDecodeMessage: boolean
|
|
115
|
-
): Promise<Response<ResponseErrorType> | null | SQSBatchResponse> {
|
|
116
|
-
if (this.
|
|
94
|
+
): Promise<Response<ResponseErrorType | any> | null | SQSBatchResponse> {
|
|
95
|
+
if (this.event.Records && this.event.Records.length > 0) {
|
|
117
96
|
//safe check for empty events?
|
|
118
97
|
//init transaction for all records
|
|
119
|
-
return await new Transaction<null,
|
|
120
|
-
this.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
...this._apiConfig,
|
|
124
|
-
syncReturn: true,
|
|
125
|
-
}
|
|
126
|
-
).execute(async transaction => {
|
|
98
|
+
return await new Transaction<null, any, SQSBatchResponse | null>(this.event, this.context, {
|
|
99
|
+
...this.config,
|
|
100
|
+
syncReturn: true,
|
|
101
|
+
}).execute(async transaction => {
|
|
127
102
|
//Map records with decoded message when required
|
|
128
|
-
const decodedRecords: string[] | object[] = this.
|
|
103
|
+
const decodedRecords: string[] | object[] = this.event.Records.map(eventRecord =>
|
|
129
104
|
doNotDecodeMessage ? eventRecord.body : JSON.parse(eventRecord.body)
|
|
130
105
|
)
|
|
131
106
|
|
|
@@ -133,7 +108,7 @@ export default class EventProcessor<ResponseInnerType> {
|
|
|
133
108
|
const failureIDs: Array<string> = []
|
|
134
109
|
for (const eventRecordIdx in decodedRecords) {
|
|
135
110
|
const eventRecord = decodedRecords[eventRecordIdx]
|
|
136
|
-
const message = this.
|
|
111
|
+
const message = this.event.Records[eventRecordIdx]
|
|
137
112
|
//Call execution
|
|
138
113
|
const resp = await execution(transaction, eventRecord)
|
|
139
114
|
//check for failure
|
|
@@ -142,12 +117,12 @@ export default class EventProcessor<ResponseInnerType> {
|
|
|
142
117
|
(resp instanceof Response && !(resp?.getCode() >= 200 && resp?.getCode() < 300))
|
|
143
118
|
) {
|
|
144
119
|
//response with failures or fail hard at first
|
|
145
|
-
if (this.
|
|
120
|
+
if (this.allowFailure) failureIDs.push(message.messageId)
|
|
146
121
|
else return resp
|
|
147
122
|
}
|
|
148
123
|
}
|
|
149
124
|
//not errored and loop ended - succeeded (might have failures)
|
|
150
|
-
if (this.
|
|
125
|
+
if (this.allowFailure)
|
|
151
126
|
return {
|
|
152
127
|
batchItemFailures: failureIDs.map(id => ({ itemIdentifier: id })),
|
|
153
128
|
}
|
package/src/BaseEvent/Process.ts
CHANGED
|
@@ -2,93 +2,68 @@ import { TransactionConfig } from './Transaction'
|
|
|
2
2
|
import Logger from '../Logger/Logger'
|
|
3
3
|
import Publisher from '../Publisher/Publisher'
|
|
4
4
|
|
|
5
|
-
// Config
|
|
6
5
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* @export
|
|
10
|
-
* @typedef {ProcessConfig}
|
|
6
|
+
* A type that represents a modified version of the TransactionConfig type, excluding the 'throwOnErrors' and 'syncReturn' properties.
|
|
11
7
|
*/
|
|
12
8
|
export type ProcessConfig = Omit<TransactionConfig, 'throwOnErrors' | 'syncReturn'>
|
|
13
9
|
|
|
14
10
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* @export
|
|
18
|
-
* @class Process
|
|
19
|
-
* @typedef {Process}
|
|
11
|
+
* Represents a long-running process that executes a given function at a specified interval.
|
|
20
12
|
*/
|
|
21
13
|
export default class Process {
|
|
22
14
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* @private
|
|
15
|
+
* Private member variable representing the interval value.
|
|
26
16
|
* @type {number}
|
|
17
|
+
* @private
|
|
27
18
|
*/
|
|
28
|
-
private
|
|
29
|
-
//
|
|
19
|
+
private interval: number
|
|
30
20
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* @public
|
|
21
|
+
* A logger object used for logging messages, errors, and other information.
|
|
34
22
|
* @readonly
|
|
35
|
-
* @type {Logger}
|
|
36
23
|
*/
|
|
37
24
|
public readonly logger: Logger
|
|
38
25
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* @public
|
|
42
|
-
* @readonly
|
|
43
|
-
* @type {Publisher}
|
|
26
|
+
* The publisher of the content.
|
|
44
27
|
*/
|
|
45
28
|
public readonly publisher: Publisher
|
|
46
29
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* @public
|
|
50
|
-
* @type {NodeJS.Timeout}
|
|
30
|
+
* A reference to the NodeJS.Timeout object representing the interval timer.
|
|
51
31
|
*/
|
|
52
|
-
public
|
|
32
|
+
public timeout: NodeJS.Timeout
|
|
33
|
+
|
|
53
34
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* @
|
|
57
|
-
* @
|
|
58
|
-
* @param {number} interval
|
|
35
|
+
* Constructs a new instance of the LongRunningProcess class.
|
|
36
|
+
* @param {ProcessConfig} config - The configuration object for the process.
|
|
37
|
+
* @param {number} interval - The interval at which the process should run.
|
|
38
|
+
* @returns None
|
|
59
39
|
*/
|
|
60
40
|
constructor(config: ProcessConfig, interval: number) {
|
|
61
|
-
this.
|
|
41
|
+
this.interval = interval
|
|
62
42
|
this.logger = new Logger(config.logger, 'long-running-process')
|
|
63
43
|
this.publisher = new Publisher(config.publisher)
|
|
64
44
|
}
|
|
65
45
|
|
|
66
|
-
//Main interface
|
|
67
46
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* @
|
|
71
|
-
* @param {*} executionFunc
|
|
72
|
-
* @returns {*}
|
|
47
|
+
* Executes the provided execution function at a specified interval.
|
|
48
|
+
* @param {Function} executionFunc - The function to execute.
|
|
49
|
+
* @returns None
|
|
73
50
|
*/
|
|
74
|
-
async execute(executionFunc) {
|
|
51
|
+
public async execute(executionFunc) {
|
|
75
52
|
this.logger.debug('Starting main process code')
|
|
76
53
|
//Connect DB
|
|
77
54
|
// if (this.db) await this.db.connect();
|
|
78
55
|
//Program loop
|
|
79
|
-
this.
|
|
80
|
-
await this.
|
|
81
|
-
}, this.
|
|
56
|
+
this.timeout = setInterval(async () => {
|
|
57
|
+
await this.iexecute(executionFunc)
|
|
58
|
+
}, this.interval)
|
|
82
59
|
}
|
|
83
|
-
|
|
60
|
+
|
|
84
61
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* @
|
|
88
|
-
* @param {*} executionFunc
|
|
89
|
-
* @returns {unknown}
|
|
62
|
+
* Executes the given execution function asynchronously and handles any exceptions that occur.
|
|
63
|
+
* @param {Function} executionFunc - The function to execute.
|
|
64
|
+
* @returns {boolean} - Returns true if the execution failed, false otherwise.
|
|
90
65
|
*/
|
|
91
|
-
async
|
|
66
|
+
private async iexecute(executionFunc) {
|
|
92
67
|
let executionFailed = true //failled til we say no!
|
|
93
68
|
//safe execution handler
|
|
94
69
|
try {
|
|
@@ -2,15 +2,29 @@ import type { APIGatewayEvent, Context, SQSEvent } from 'aws-lambda'
|
|
|
2
2
|
|
|
3
3
|
import Request from '../API/Request'
|
|
4
4
|
import Response, { ResponseErrorType } from '../API/Response'
|
|
5
|
+
import { DatabaseManager } from '../Database/DatabaseManager'
|
|
6
|
+
import { DatabaseTransaction } from '../Database/DatabaseTransaction'
|
|
7
|
+
import type { DatabaseTransactionType, DatabaseType, DbConfig } from '../Database/types'
|
|
5
8
|
import Globals from '../Globals'
|
|
6
9
|
import Logger, { LoggerConfig } from '../Logger/Logger'
|
|
7
10
|
import Publisher, { PublisherConfig } from '../Publisher/Publisher'
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Defines a type for executing a transaction and returning a promise with the response.
|
|
14
|
+
* @param {TransactionType} transaction - The transaction to execute.
|
|
15
|
+
* @returns A promise that resolves to the response of the transaction.
|
|
16
|
+
*/
|
|
10
17
|
export type TransactionExecution<TransactionType, ResponseInnerType, MiscRespType = null> = (
|
|
11
18
|
transaction: TransactionType
|
|
12
19
|
) => Promise<Response<ResponseInnerType> | Response<ResponseErrorType> | MiscRespType>
|
|
13
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Represents the configuration options for a transaction.
|
|
22
|
+
* @typedef {Object} TransactionConfig
|
|
23
|
+
* @property {boolean} [throwOnErrors] - Whether to throw an error if there are any errors during the transaction.
|
|
24
|
+
* @property {boolean} [syncReturn] - Whether to return the result of the transaction synchronously.
|
|
25
|
+
* @property {LoggerConfig} [logger] - The configuration options for the logger.
|
|
26
|
+
* @property {PublisherConfig} [publisher] - The configuration options for the publisher.
|
|
27
|
+
*/
|
|
14
28
|
export type TransactionConfig = {
|
|
15
29
|
throwOnErrors?: boolean
|
|
16
30
|
syncReturn?: boolean
|
|
@@ -19,22 +33,79 @@ export type TransactionConfig = {
|
|
|
19
33
|
publisher?: PublisherConfig
|
|
20
34
|
}
|
|
21
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Represents a transaction object that handles the execution of a request and manages the response.
|
|
38
|
+
* @template InputType - The type of the input data for the transaction.
|
|
39
|
+
* @template ResponseInnerType - The type of the inner response data for the transaction.
|
|
40
|
+
* @template MiscRespType - The type of miscellaneous response data for the transaction.
|
|
41
|
+
*/
|
|
22
42
|
export default class Transaction<
|
|
23
43
|
InputType = object,
|
|
24
44
|
ResponseInnerType = null,
|
|
25
45
|
MiscRespType = null,
|
|
26
46
|
> {
|
|
47
|
+
/**
|
|
48
|
+
* The instance of the DatabaseManager class used for managing the database.
|
|
49
|
+
*/
|
|
50
|
+
private databaseManager: DatabaseManager = DatabaseManager.INSTANCE
|
|
51
|
+
/**
|
|
52
|
+
* An array of database transactions.
|
|
53
|
+
* @type {DatabaseTransaction[]}
|
|
54
|
+
*/
|
|
55
|
+
private transactions: DatabaseTransaction[] = []
|
|
56
|
+
/**
|
|
57
|
+
* Represents an event object.
|
|
58
|
+
* @private
|
|
59
|
+
* @type {any}
|
|
60
|
+
*/
|
|
27
61
|
private event: any
|
|
62
|
+
/**
|
|
63
|
+
* The context object for the current instance.
|
|
64
|
+
*/
|
|
28
65
|
private context: Context
|
|
66
|
+
/**
|
|
67
|
+
* The response object that can hold different types of responses.
|
|
68
|
+
* @type {Response<ResponseInnerType | ResponseErrorType> | MiscRespType | null}
|
|
69
|
+
*/
|
|
29
70
|
private response: Response<ResponseInnerType | ResponseErrorType> | MiscRespType | null
|
|
71
|
+
/**
|
|
72
|
+
* A private boolean variable indicating whether the return value of a synchronous operation
|
|
73
|
+
* should be synchronized with the calling thread.
|
|
74
|
+
*/
|
|
30
75
|
private syncReturn: boolean
|
|
76
|
+
/**
|
|
77
|
+
* A boolean flag indicating whether retroactive errors are enabled or not.
|
|
78
|
+
* @private
|
|
79
|
+
*/
|
|
31
80
|
private retrowErrors: boolean
|
|
32
|
-
|
|
81
|
+
/**
|
|
82
|
+
* A logger object used for logging messages, errors, and other information.
|
|
83
|
+
* @readonly
|
|
84
|
+
*/
|
|
33
85
|
public readonly logger: Logger
|
|
86
|
+
/**
|
|
87
|
+
* The request object for making a request of type InputType.
|
|
88
|
+
* @readonly
|
|
89
|
+
*/
|
|
34
90
|
public readonly request: Request<InputType>
|
|
91
|
+
/**
|
|
92
|
+
* The publisher of the content.
|
|
93
|
+
*/
|
|
35
94
|
public readonly publisher: Publisher
|
|
36
|
-
|
|
37
|
-
|
|
95
|
+
/**
|
|
96
|
+
* A function that acts as a response proxy for a given response object.
|
|
97
|
+
* @param {Response<ResponseInnerType>} response - The response object to proxy.
|
|
98
|
+
* @returns A promise that resolves to void.
|
|
99
|
+
*/
|
|
100
|
+
public responseProxy: ((response: Response<ResponseInnerType>) => Promise<void>) | null
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Constructs a new instance of the Transaction class.
|
|
104
|
+
* @param {APIGatewayEvent | SQSEvent} event - The event object passed to the Lambda function.
|
|
105
|
+
* @param {Context} context - The context object passed to the Lambda function.
|
|
106
|
+
* @param {TransactionConfig} [config] - Optional configuration object for the transaction.
|
|
107
|
+
* @returns None
|
|
108
|
+
*/
|
|
38
109
|
constructor(event: APIGatewayEvent | SQSEvent, context: Context, config?: TransactionConfig) {
|
|
39
110
|
const transactionId = context.awsRequestId
|
|
40
111
|
? context.awsRequestId
|
|
@@ -56,14 +127,19 @@ export default class Transaction<
|
|
|
56
127
|
this.publisher = new Publisher(config?.publisher)
|
|
57
128
|
}
|
|
58
129
|
|
|
59
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Executes a transaction using the provided execution function and returns a promise
|
|
132
|
+
* that resolves to the response or miscellaneous response.
|
|
133
|
+
* @param {TransactionExecution<Transaction<InputType, ResponseInnerType, MiscRespType>, ResponseInnerType, MiscRespType>} executionFunc - The execution function to be executed.
|
|
134
|
+
* @returns {Promise<Response<ResponseInnerType | ResponseErrorType> | MiscRespType>} - A promise that resolves to the response or miscellaneous response.
|
|
135
|
+
*/
|
|
60
136
|
public async execute(
|
|
61
137
|
executionFunc: TransactionExecution<
|
|
62
138
|
Transaction<InputType, ResponseInnerType, MiscRespType>,
|
|
63
139
|
ResponseInnerType,
|
|
64
140
|
MiscRespType
|
|
65
141
|
>
|
|
66
|
-
): Promise<Response<ResponseInnerType | ResponseErrorType> | MiscRespType> {
|
|
142
|
+
): Promise<Response<ResponseInnerType | ResponseErrorType> | MiscRespType | null> {
|
|
67
143
|
await this.executeLoggerFlush(async () => {
|
|
68
144
|
await this.executeDBTransactions(async () => {
|
|
69
145
|
return await this.iexecute(executionFunc)
|
|
@@ -74,7 +150,12 @@ export default class Transaction<
|
|
|
74
150
|
// allow request to async succeed through lambda context
|
|
75
151
|
return null
|
|
76
152
|
}
|
|
77
|
-
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Executes a transaction using the provided execution function and handles the response.
|
|
156
|
+
* @param {TransactionExecution<Transaction<InputType, ResponseInnerType, MiscRespType>, ResponseInnerType, MiscRespType>} executionFunc - The function to execute the transaction.
|
|
157
|
+
* @returns {Promise<boolean>} - A promise that resolves to a boolean indicating whether the execution failed or not.
|
|
158
|
+
*/
|
|
78
159
|
private async iexecute(
|
|
79
160
|
executionFunc: TransactionExecution<
|
|
80
161
|
Transaction<InputType, ResponseInnerType, MiscRespType>,
|
|
@@ -119,32 +200,65 @@ export default class Transaction<
|
|
|
119
200
|
}
|
|
120
201
|
return executionFailed
|
|
121
202
|
}
|
|
122
|
-
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Retrieves a database transaction for the specified database configuration.
|
|
206
|
+
* @async
|
|
207
|
+
* @param {DbConfig<S>} config - The configuration object for the database.
|
|
208
|
+
* @returns {Promise<DatabaseTransactionType<S>>} A promise that resolves to the database transaction.
|
|
209
|
+
*/
|
|
210
|
+
public async getDbTransaction<S extends DatabaseType>(
|
|
211
|
+
config: DbConfig<S>
|
|
212
|
+
): Promise<DatabaseTransactionType<S>> {
|
|
213
|
+
const db = this.databaseManager.create(config)
|
|
214
|
+
const dbTrans = await db.transaction()
|
|
215
|
+
this.transactions.push(dbTrans)
|
|
216
|
+
return dbTrans as any
|
|
217
|
+
}
|
|
218
|
+
/*
|
|
219
|
+
* Executes a series of database transactions in a safe manner.
|
|
220
|
+
* @param {Function} safeExecution - The function that contains the database transactions to be executed.
|
|
221
|
+
* @returns None
|
|
222
|
+
* @throws {Error} - If an exception occurs during the execution of the transactions and `retrowErrors` is true.
|
|
223
|
+
*/
|
|
224
|
+
private async executeDBTransactions(safeExecution: () => Promise<boolean>): Promise<void> {
|
|
123
225
|
try {
|
|
124
|
-
//
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
// this.logger.log("Rolling back DB transactions. Main code failed!");
|
|
136
|
-
// if (this.db) await this.db.rollback();
|
|
137
|
-
// }
|
|
138
|
-
// //Cleanup DB after execution
|
|
139
|
-
// if (this.db) await this.db.cleanup();
|
|
226
|
+
// Execute
|
|
227
|
+
const execFailed = await safeExecution()
|
|
228
|
+
for (const transaction of [...this.transactions].reverse()) {
|
|
229
|
+
try {
|
|
230
|
+
await transaction[execFailed ? 'closeFailure' : 'closeSuccess']()
|
|
231
|
+
} catch (e) {
|
|
232
|
+
// TODO: should we keep committing transactions even if one fails?
|
|
233
|
+
this.logger.error('Exception when closing DB transactions after success.')
|
|
234
|
+
this.logger.exception(e)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
140
237
|
} catch (e) {
|
|
238
|
+
/* this part of the code handle exceptions at transaction level,
|
|
239
|
+
so probably a bug but we still handle such */
|
|
240
|
+
for (const transaction of [...this.transactions].reverse()) {
|
|
241
|
+
try {
|
|
242
|
+
await transaction.closeFailure()
|
|
243
|
+
} catch (e) {
|
|
244
|
+
this.logger.error('Exception when closing DB transactions after failure.')
|
|
245
|
+
this.logger.exception(e)
|
|
246
|
+
}
|
|
247
|
+
}
|
|
141
248
|
this.logger.error('Exception when executing DB transactions.')
|
|
142
249
|
this.logger.log(e.stack)
|
|
143
250
|
//retrow?
|
|
144
251
|
if (this.retrowErrors) throw e
|
|
145
252
|
}
|
|
146
253
|
}
|
|
147
|
-
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Executes a logger flush operation with error handling and logging.
|
|
257
|
+
* @param {Function} safeExecution - The function to execute safely.
|
|
258
|
+
* @returns None
|
|
259
|
+
* @throws {Error} - If `retrowErrors` is true and an error occurs during execution.
|
|
260
|
+
*/
|
|
261
|
+
private async executeLoggerFlush(safeExecution): Promise<void> {
|
|
148
262
|
try {
|
|
149
263
|
await safeExecution()
|
|
150
264
|
} catch (e) {
|
|
@@ -156,7 +270,13 @@ export default class Transaction<
|
|
|
156
270
|
this.logger.debug('Transaction ended')
|
|
157
271
|
}
|
|
158
272
|
}
|
|
159
|
-
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Returns an error response with the specified error message and error code.
|
|
276
|
+
* @param {string} error - The error message.
|
|
277
|
+
* @param {string} code - The error code.
|
|
278
|
+
* @returns {Response<ResponseErrorType>} - The error response.
|
|
279
|
+
*/
|
|
160
280
|
private getErrorResponse(error: string, code: string): Response<ResponseErrorType> {
|
|
161
281
|
return Response.BadRequestResponseWithRollback(error, code)
|
|
162
282
|
}
|