@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.
Files changed (153) hide show
  1. package/.github/workflows/npmpublish.yml +1 -1
  2. package/README.md +216 -5
  3. package/dist/index.d.ts +15 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/jest.config.js +1 -1
  6. package/dist/jest.config.js.map +1 -1
  7. package/dist/package.json +13 -2
  8. package/dist/src/API/Request.d.ts +45 -82
  9. package/dist/src/API/Request.js +49 -77
  10. package/dist/src/API/Request.js.map +1 -1
  11. package/dist/src/API/Response.d.ts +94 -163
  12. package/dist/src/API/Response.js +101 -161
  13. package/dist/src/API/Response.js.map +1 -1
  14. package/dist/src/API/Utils.d.ts +21 -42
  15. package/dist/src/API/Utils.js +22 -43
  16. package/dist/src/API/Utils.js.map +1 -1
  17. package/dist/src/BaseEvent/EventProcessor.d.ts +32 -55
  18. package/dist/src/BaseEvent/EventProcessor.js +30 -38
  19. package/dist/src/BaseEvent/EventProcessor.js.map +1 -1
  20. package/dist/src/BaseEvent/Process.d.ts +20 -43
  21. package/dist/src/BaseEvent/Process.js +16 -27
  22. package/dist/src/BaseEvent/Process.js.map +1 -1
  23. package/dist/src/BaseEvent/Transaction.d.ts +104 -2
  24. package/dist/src/BaseEvent/Transaction.js +196 -41
  25. package/dist/src/BaseEvent/Transaction.js.map +1 -1
  26. package/dist/src/Config/Configuration.d.ts +48 -66
  27. package/dist/src/Config/Configuration.js +25 -42
  28. package/dist/src/Config/Configuration.js.map +1 -1
  29. package/dist/src/Config/EnvironmentVar.d.ts +30 -57
  30. package/dist/src/Config/EnvironmentVar.js +28 -41
  31. package/dist/src/Config/EnvironmentVar.js.map +1 -1
  32. package/dist/src/Crypto/Crypto.d.ts +17 -35
  33. package/dist/src/Crypto/Crypto.js +12 -21
  34. package/dist/src/Crypto/Crypto.js.map +1 -1
  35. package/dist/src/Crypto/JWT.d.ts +21 -32
  36. package/dist/src/Crypto/JWT.js +14 -22
  37. package/dist/src/Crypto/JWT.js.map +1 -1
  38. package/dist/src/Database/Database.d.ts +18 -0
  39. package/dist/src/Database/Database.js +18 -0
  40. package/dist/src/Database/Database.js.map +1 -0
  41. package/dist/src/Database/DatabaseManager.d.ts +32 -0
  42. package/dist/src/Database/DatabaseManager.js +50 -0
  43. package/dist/src/Database/DatabaseManager.js.map +1 -0
  44. package/dist/src/Database/DatabaseTransaction.d.ts +65 -0
  45. package/dist/src/Database/DatabaseTransaction.js +183 -0
  46. package/dist/src/Database/DatabaseTransaction.js.map +1 -0
  47. package/dist/src/Database/integrations/knex/KnexDatabase.d.ts +22 -0
  48. package/dist/src/Database/integrations/knex/KnexDatabase.js +108 -0
  49. package/dist/src/Database/integrations/knex/KnexDatabase.js.map +1 -0
  50. package/dist/src/Database/integrations/knex/KnexTransaction.d.ts +37 -0
  51. package/dist/src/Database/integrations/knex/KnexTransaction.js +60 -0
  52. package/dist/src/Database/integrations/knex/KnexTransaction.js.map +1 -0
  53. package/dist/src/Database/integrations/pgsql/PostgresDatabase.d.ts +30 -0
  54. package/dist/src/Database/integrations/pgsql/PostgresDatabase.js +108 -0
  55. package/dist/src/Database/integrations/pgsql/PostgresDatabase.js.map +1 -0
  56. package/dist/src/Database/integrations/pgsql/PostgresTransaction.d.ts +37 -0
  57. package/dist/src/Database/integrations/pgsql/PostgresTransaction.js +60 -0
  58. package/dist/src/Database/integrations/pgsql/PostgresTransaction.js.map +1 -0
  59. package/dist/src/Globals.d.ts +26 -94
  60. package/dist/src/Globals.js +26 -95
  61. package/dist/src/Globals.js.map +1 -1
  62. package/dist/src/Logger/Logger.d.ts +82 -105
  63. package/dist/src/Logger/Logger.js +111 -136
  64. package/dist/src/Logger/Logger.js.map +1 -1
  65. package/dist/src/Mailer/Mailer.d.ts +39 -75
  66. package/dist/src/Mailer/Mailer.js +36 -65
  67. package/dist/src/Mailer/Mailer.js.map +1 -1
  68. package/dist/src/Publisher/Publisher.d.ts +17 -25
  69. package/dist/src/Publisher/Publisher.js +21 -32
  70. package/dist/src/Publisher/Publisher.js.map +1 -1
  71. package/dist/src/Server/RouteResolver.d.ts +14 -22
  72. package/dist/src/Server/RouteResolver.js +21 -34
  73. package/dist/src/Server/RouteResolver.js.map +1 -1
  74. package/dist/src/Server/Router.d.ts +72 -51
  75. package/dist/src/Server/Router.js +8 -17
  76. package/dist/src/Server/Router.js.map +1 -1
  77. package/dist/src/Server/lib/ContainerServer.d.ts +15 -31
  78. package/dist/src/Server/lib/ContainerServer.js +13 -28
  79. package/dist/src/Server/lib/ContainerServer.js.map +1 -1
  80. package/dist/src/Server/lib/Server.d.ts +17 -32
  81. package/dist/src/Server/lib/Server.js +18 -28
  82. package/dist/src/Server/lib/Server.js.map +1 -1
  83. package/dist/src/Server/lib/container/GenericHandler.d.ts +5 -0
  84. package/dist/src/Server/lib/container/GenericHandler.js +16 -3
  85. package/dist/src/Server/lib/container/GenericHandler.js.map +1 -1
  86. package/dist/src/Server/lib/container/GenericHandlerEvent.d.ts +22 -37
  87. package/dist/src/Server/lib/container/GenericHandlerEvent.js +29 -41
  88. package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +1 -1
  89. package/dist/src/Server/lib/container/HealthHandler.d.ts +6 -0
  90. package/dist/src/Server/lib/container/HealthHandler.js +6 -0
  91. package/dist/src/Server/lib/container/HealthHandler.js.map +1 -1
  92. package/dist/src/Server/lib/container/Proxy.d.ts +24 -52
  93. package/dist/src/Server/lib/container/Proxy.js +52 -52
  94. package/dist/src/Server/lib/container/Proxy.js.map +1 -1
  95. package/dist/src/Server/lib/container/Utils.d.ts +6 -10
  96. package/dist/src/Server/lib/container/Utils.js +6 -10
  97. package/dist/src/Server/lib/container/Utils.js.map +1 -1
  98. package/dist/src/Validation/Validator.d.ts +9 -13
  99. package/dist/src/Validation/Validator.js +8 -12
  100. package/dist/src/Validation/Validator.js.map +1 -1
  101. package/index.ts +15 -0
  102. package/jest.config.ts +1 -1
  103. package/package.json +13 -2
  104. package/src/API/Request.ts +66 -84
  105. package/src/API/Response.ts +144 -203
  106. package/src/API/Utils.ts +28 -44
  107. package/src/BaseEvent/EventProcessor.ts +52 -77
  108. package/src/BaseEvent/Process.ts +27 -52
  109. package/src/BaseEvent/Transaction.ts +147 -27
  110. package/src/Config/Configuration.ts +59 -76
  111. package/src/Config/EnvironmentVar.ts +39 -62
  112. package/src/Crypto/Crypto.ts +20 -36
  113. package/src/Crypto/JWT.ts +31 -35
  114. package/src/Database/Database.ts +19 -0
  115. package/src/Database/DatabaseManager.ts +51 -0
  116. package/src/Database/DatabaseTransaction.ts +118 -0
  117. package/src/Database/integrations/knex/KnexDatabase.ts +47 -0
  118. package/src/Database/integrations/knex/KnexTransaction.ts +51 -0
  119. package/src/Database/integrations/pgsql/PostgresDatabase.ts +49 -0
  120. package/src/Database/integrations/pgsql/PostgresTransaction.ts +54 -0
  121. package/src/Database/types.d.ts +49 -0
  122. package/src/Globals.ts +28 -96
  123. package/src/Logger/Logger.ts +141 -160
  124. package/src/Mailer/Mailer.ts +43 -76
  125. package/src/Publisher/Publisher.ts +31 -40
  126. package/src/Server/RouteResolver.ts +31 -52
  127. package/src/Server/Router.ts +75 -54
  128. package/src/Server/lib/ContainerServer.ts +20 -32
  129. package/src/Server/lib/Server.ts +19 -34
  130. package/src/Server/lib/container/GenericHandler.ts +17 -3
  131. package/src/Server/lib/container/GenericHandlerEvent.ts +44 -54
  132. package/src/Server/lib/container/HealthHandler.ts +6 -0
  133. package/src/Server/lib/container/Proxy.ts +39 -58
  134. package/src/Server/lib/container/Utils.ts +7 -10
  135. package/src/Validation/Validator.ts +11 -13
  136. package/tests/API/Response.test.ts +55 -56
  137. package/tests/BaseEvent/EventProcessor.test.ts +49 -50
  138. package/tests/BaseEvent/Process.test.ts +2 -2
  139. package/tests/BaseEvent/Transaction.test.ts +102 -44
  140. package/tests/Config/Config.test.ts +27 -27
  141. package/tests/Config/EnvironmentVar.test.ts +54 -18
  142. package/tests/Database/DatabaseManager.test.ts +55 -0
  143. package/tests/Database/integrations/knex/KnexDatabase.test.ts +53 -0
  144. package/tests/Database/integrations/knex/KnexTransaction.test.ts +133 -0
  145. package/tests/Database/integrations/pg/PostgresDatabase.test.ts +50 -0
  146. package/tests/Database/integrations/pg/PostgresTransaction.test.ts +51 -0
  147. package/tests/Publisher/Publisher.test.ts +3 -3
  148. package/tests/Server/lib/ContainerServer.test.ts +21 -22
  149. package/tests/Server/lib/container/GenericHandler.test.ts +31 -32
  150. package/tests/Server/lib/container/GenericHandlerEvent.test.ts +2 -2
  151. package/tests/Server/lib/container/HealthHandler.test.ts +6 -7
  152. package/tests/Server/lib/container/Proxy.test.ts +37 -35
  153. 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
- * ${1:Description placeholder}
10
- *
11
- * @export
12
- * @typedef {EventProcessorExecution}
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
- * ${1:Description placeholder}
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
- * ${1:Description placeholder}
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 _allowFailure: boolean
27
+ private readonly allowFailure: boolean
37
28
  /**
38
- * ${1:Description placeholder}
39
- *
40
- * @private
41
- * @readonly
42
- * @type {TransactionConfig}
29
+ * The configuration object for the API transaction.
43
30
  */
44
- private readonly _apiConfig: TransactionConfig
31
+ private readonly config: TransactionConfig
45
32
  /**
46
- * ${1:Description placeholder}
47
- *
48
- * @private
49
- * @readonly
33
+ * The private readonly context property of the class.
50
34
  * @type {Context}
51
35
  */
52
- private readonly _context: Context
36
+ private readonly context: Context
53
37
  /**
54
- * ${1:Description placeholder}
55
- *
56
- * @private
57
- * @readonly
58
- * @type {SQSEvent}
38
+ * The SQS event object that triggered the Lambda function.
59
39
  */
60
- private readonly _event: SQSEvent
40
+ private readonly event: SQSEvent
41
+
61
42
  /**
62
- * Creates an instance of EventProcessor.
63
- *
64
- * @constructor
65
- * @param {SQSEvent} event
66
- * @param {Context} context
67
- * @param {?TransactionConfig} [config]
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._event = event
77
- this._context = context
78
- this._apiConfig = config || {}
79
- this._allowFailure = allowFailure
56
+ this.event = event
57
+ this.context = context
58
+ this.config = config || {}
59
+ this.allowFailure = !!allowFailure
80
60
  }
61
+
81
62
  /**
82
- * ${1:Description placeholder}
83
- *
84
- * @async
85
- * @param {EventProcessorExecution<ResponseInnerType>} execution
86
- * @param {?boolean} [doNotDecodeMessage]
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._processRawEvent(execution, !!doNotDecodeMessage)
72
+ ): Promise<Response<ResponseErrorType | null> | null | SQSBatchResponse> {
73
+ const resp = await this.processRawEvent(execution, !!doNotDecodeMessage)
94
74
  if (
95
- !this._allowFailure &&
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
- * ${1:Description placeholder}
106
- *
107
- * @async
108
- * @param {EventProcessorExecution<ResponseInnerType>} execution
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 _processRawEvent(
91
+ private async processRawEvent(
113
92
  execution: EventProcessorExecution<ResponseInnerType>,
114
93
  doNotDecodeMessage: boolean
115
- ): Promise<Response<ResponseErrorType> | null | SQSBatchResponse> {
116
- if (this._event.Records && this._event.Records.length > 0) {
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, ResponseErrorType, SQSBatchResponse>(
120
- this._event,
121
- this._context,
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._event.Records.map(eventRecord =>
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._event.Records[eventRecordIdx]
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._allowFailure) failureIDs.push(message.messageId)
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._allowFailure)
125
+ if (this.allowFailure)
151
126
  return {
152
127
  batchItemFailures: failureIDs.map(id => ({ itemIdentifier: id })),
153
128
  }
@@ -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
- * ${1:Description placeholder}
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
- * ${1:Description placeholder}
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
- * ${1:Description placeholder}
24
- *
25
- * @private
15
+ * Private member variable representing the interval value.
26
16
  * @type {number}
17
+ * @private
27
18
  */
28
- private _interval: number
29
- //
19
+ private interval: number
30
20
  /**
31
- * ${1:Description placeholder}
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
- * ${1:Description placeholder}
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
- * ${1:Description placeholder}
48
- *
49
- * @public
50
- * @type {NodeJS.Timeout}
30
+ * A reference to the NodeJS.Timeout object representing the interval timer.
51
31
  */
52
- public interval: NodeJS.Timeout
32
+ public timeout: NodeJS.Timeout
33
+
53
34
  /**
54
- * Creates an instance of Process.
55
- *
56
- * @constructor
57
- * @param {ProcessConfig} config
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._interval = interval
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
- * ${1:Description placeholder}
69
- *
70
- * @async
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.interval = setInterval(async () => {
80
- await this._execute(executionFunc)
81
- }, this._interval)
56
+ this.timeout = setInterval(async () => {
57
+ await this.iexecute(executionFunc)
58
+ }, this.interval)
82
59
  }
83
- //Executions
60
+
84
61
  /**
85
- * ${1:Description placeholder}
86
- *
87
- * @async
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 _execute(executionFunc) {
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
- // Request
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
- // Config
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
- public responseProxy: (response: Response<ResponseInnerType>) => Promise<void>
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
- //Main interface
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
- //Executions
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
- private async executeDBTransactions(safeExecution) {
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
- // //start DB
125
- // if (this.db) await this.db.connect();
126
- // //start transaction
127
- // if (this.db) await this.db.beginTransaction();
128
- // //
129
- // let executionFailed =
130
- await safeExecution()
131
- // //Commit if not failed, rollback if failed
132
- // if (!executionFailed) {
133
- // if (this.db) await this.db.commit();
134
- // } else {
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
- private async executeLoggerFlush(safeExecution) {
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
- /* Response support */
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
  }