mvc-common-toolkit 1.43.9 → 1.43.11

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 (201) hide show
  1. package/dist/src/constants.d.ts +42 -0
  2. package/dist/src/constants.js +50 -0
  3. package/dist/src/constants.js.map +1 -0
  4. package/dist/src/gateways/alibaba-cloud-gateway.d.ts +30 -0
  5. package/dist/src/gateways/alibaba-cloud-gateway.js +120 -0
  6. package/dist/src/gateways/alibaba-cloud-gateway.js.map +1 -0
  7. package/dist/src/gateways/http-audit-gateway.d.ts +20 -0
  8. package/dist/src/gateways/http-audit-gateway.js +76 -0
  9. package/dist/src/gateways/http-audit-gateway.js.map +1 -0
  10. package/dist/src/gateways/index.d.ts +5 -0
  11. package/dist/src/gateways/index.js +22 -0
  12. package/dist/src/gateways/index.js.map +1 -0
  13. package/dist/src/gateways/internal-auth-gateway.d.ts +8 -0
  14. package/dist/src/gateways/internal-auth-gateway.js +40 -0
  15. package/dist/src/gateways/internal-auth-gateway.js.map +1 -0
  16. package/dist/src/gateways/stdout-audit-gateway.d.ts +7 -0
  17. package/dist/src/gateways/stdout-audit-gateway.js +25 -0
  18. package/dist/src/gateways/stdout-audit-gateway.js.map +1 -0
  19. package/dist/src/gateways/webhook-audit-gateway.d.ts +14 -0
  20. package/dist/src/gateways/webhook-audit-gateway.js +27 -0
  21. package/dist/src/gateways/webhook-audit-gateway.js.map +1 -0
  22. package/dist/src/interfaces.d.ts +218 -0
  23. package/dist/src/interfaces.js +3 -0
  24. package/dist/src/interfaces.js.map +1 -0
  25. package/dist/src/models/audit-log.d.ts +77 -0
  26. package/dist/src/models/audit-log.js +92 -0
  27. package/dist/src/models/audit-log.js.map +1 -0
  28. package/dist/src/models/index.d.ts +1 -0
  29. package/dist/src/models/index.js +18 -0
  30. package/dist/src/models/index.js.map +1 -0
  31. package/dist/src/pkg/array-helper.d.ts +1 -0
  32. package/dist/src/pkg/array-helper.js +12 -0
  33. package/dist/src/pkg/array-helper.js.map +1 -0
  34. package/dist/src/pkg/bcrypt-helper.d.ts +2 -0
  35. package/dist/src/pkg/bcrypt-helper.js +36 -0
  36. package/dist/src/pkg/bcrypt-helper.js.map +1 -0
  37. package/dist/src/pkg/crypto-helper.d.ts +2 -0
  38. package/dist/src/pkg/crypto-helper.js +16 -0
  39. package/dist/src/pkg/crypto-helper.js.map +1 -0
  40. package/dist/src/pkg/encryption-helper.d.ts +18 -0
  41. package/dist/src/pkg/encryption-helper.js +89 -0
  42. package/dist/src/pkg/encryption-helper.js.map +1 -0
  43. package/dist/src/pkg/encryption-helper.spec.d.ts +1 -0
  44. package/dist/src/pkg/encryption-helper.spec.js +238 -0
  45. package/dist/src/pkg/encryption-helper.spec.js.map +1 -0
  46. package/dist/src/pkg/filter-helper.d.ts +2 -0
  47. package/dist/src/pkg/filter-helper.js +102 -0
  48. package/dist/src/pkg/filter-helper.js.map +1 -0
  49. package/dist/src/pkg/filter-helper.spec.d.ts +1 -0
  50. package/dist/src/pkg/filter-helper.spec.js +94 -0
  51. package/dist/src/pkg/filter-helper.spec.js.map +1 -0
  52. package/dist/src/pkg/geoip-helper.d.ts +2 -0
  53. package/dist/src/pkg/geoip-helper.js +32 -0
  54. package/dist/src/pkg/geoip-helper.js.map +1 -0
  55. package/dist/src/pkg/hash-helper.d.ts +1 -0
  56. package/dist/src/pkg/hash-helper.js +37 -0
  57. package/dist/src/pkg/hash-helper.js.map +1 -0
  58. package/dist/src/pkg/http-request-utils.d.ts +4 -0
  59. package/dist/src/pkg/http-request-utils.js +55 -0
  60. package/dist/src/pkg/http-request-utils.js.map +1 -0
  61. package/dist/src/pkg/index.d.ts +18 -0
  62. package/dist/src/pkg/index.js +45 -0
  63. package/dist/src/pkg/index.js.map +1 -0
  64. package/dist/src/pkg/key-helper.d.ts +2 -0
  65. package/dist/src/pkg/key-helper.js +20 -0
  66. package/dist/src/pkg/key-helper.js.map +1 -0
  67. package/dist/src/pkg/logger.d.ts +9 -0
  68. package/dist/src/pkg/logger.js +23 -0
  69. package/dist/src/pkg/logger.js.map +1 -0
  70. package/dist/src/pkg/object-helper.d.ts +2 -0
  71. package/dist/src/pkg/object-helper.js +37 -0
  72. package/dist/src/pkg/object-helper.js.map +1 -0
  73. package/dist/src/pkg/paginated-cache-registry.d.ts +8 -0
  74. package/dist/src/pkg/paginated-cache-registry.js +23 -0
  75. package/dist/src/pkg/paginated-cache-registry.js.map +1 -0
  76. package/dist/src/pkg/query-helper.d.ts +3 -0
  77. package/dist/src/pkg/query-helper.js +60 -0
  78. package/dist/src/pkg/query-helper.js.map +1 -0
  79. package/dist/src/pkg/referral-tree-utils.d.ts +33 -0
  80. package/dist/src/pkg/referral-tree-utils.js +71 -0
  81. package/dist/src/pkg/referral-tree-utils.js.map +1 -0
  82. package/dist/src/pkg/scripts/index.d.ts +1 -0
  83. package/dist/src/pkg/scripts/index.js +28 -0
  84. package/dist/src/pkg/scripts/index.js.map +1 -0
  85. package/dist/src/pkg/scripts/lua.d.ts +10 -0
  86. package/dist/src/pkg/scripts/lua.js +109 -0
  87. package/dist/src/pkg/scripts/lua.js.map +1 -0
  88. package/dist/src/pkg/sort-helper.d.ts +3 -0
  89. package/dist/src/pkg/sort-helper.js +18 -0
  90. package/dist/src/pkg/sort-helper.js.map +1 -0
  91. package/dist/src/pkg/string-utils.d.ts +10 -0
  92. package/dist/src/pkg/string-utils.js +79 -0
  93. package/dist/src/pkg/string-utils.js.map +1 -0
  94. package/dist/src/pkg/task-helper.d.ts +2 -0
  95. package/dist/src/pkg/task-helper.js +30 -0
  96. package/dist/src/pkg/task-helper.js.map +1 -0
  97. package/dist/src/pkg/workflow/delayed-task-registry.d.ts +10 -0
  98. package/dist/src/pkg/workflow/delayed-task-registry.js +67 -0
  99. package/dist/src/pkg/workflow/delayed-task-registry.js.map +1 -0
  100. package/dist/src/pkg/workflow/delayed-task.d.ts +18 -0
  101. package/dist/src/pkg/workflow/delayed-task.js +95 -0
  102. package/dist/src/pkg/workflow/delayed-task.js.map +1 -0
  103. package/dist/src/pkg/workflow/index.d.ts +5 -0
  104. package/dist/src/pkg/workflow/index.js +22 -0
  105. package/dist/src/pkg/workflow/index.js.map +1 -0
  106. package/dist/src/pkg/workflow/processing-milestone.d.ts +18 -0
  107. package/dist/src/pkg/workflow/processing-milestone.js +39 -0
  108. package/dist/src/pkg/workflow/processing-milestone.js.map +1 -0
  109. package/dist/src/pkg/workflow/retry-task.d.ts +24 -0
  110. package/dist/src/pkg/workflow/retry-task.js +89 -0
  111. package/dist/src/pkg/workflow/retry-task.js.map +1 -0
  112. package/dist/src/pkg/workflow/retry-task.spec.d.ts +1 -0
  113. package/dist/src/pkg/workflow/retry-task.spec.js +145 -0
  114. package/dist/src/pkg/workflow/retry-task.spec.js.map +1 -0
  115. package/dist/src/pkg/workflow/sync-taskqueue.d.ts +32 -0
  116. package/dist/src/pkg/workflow/sync-taskqueue.js +108 -0
  117. package/dist/src/pkg/workflow/sync-taskqueue.js.map +1 -0
  118. package/dist/src/pkg/worksheet.utils.d.ts +27 -0
  119. package/dist/src/pkg/worksheet.utils.js +116 -0
  120. package/dist/src/pkg/worksheet.utils.js.map +1 -0
  121. package/dist/src/services/audit-service.d.ts +7 -0
  122. package/dist/src/services/audit-service.js +32 -0
  123. package/dist/src/services/audit-service.js.map +1 -0
  124. package/dist/src/services/excel.service.d.ts +25 -0
  125. package/dist/src/services/excel.service.js +95 -0
  126. package/dist/src/services/excel.service.js.map +1 -0
  127. package/dist/src/services/http-service.d.ts +7 -0
  128. package/dist/src/services/http-service.js +67 -0
  129. package/dist/src/services/http-service.js.map +1 -0
  130. package/dist/src/services/index.d.ts +8 -0
  131. package/dist/src/services/index.js +25 -0
  132. package/dist/src/services/index.js.map +1 -0
  133. package/dist/src/services/kafka-service.d.ts +15 -0
  134. package/dist/src/services/kafka-service.js +68 -0
  135. package/dist/src/services/kafka-service.js.map +1 -0
  136. package/dist/src/services/mailer-service.d.ts +15 -0
  137. package/dist/src/services/mailer-service.js +44 -0
  138. package/dist/src/services/mailer-service.js.map +1 -0
  139. package/dist/src/services/paginated-cache.d.ts +16 -0
  140. package/dist/src/services/paginated-cache.js +115 -0
  141. package/dist/src/services/paginated-cache.js.map +1 -0
  142. package/dist/src/services/paginated-cache.spec.d.ts +1 -0
  143. package/dist/src/services/paginated-cache.spec.js +284 -0
  144. package/dist/src/services/paginated-cache.spec.js.map +1 -0
  145. package/dist/src/services/redis-service.d.ts +33 -0
  146. package/dist/src/services/redis-service.js +230 -0
  147. package/dist/src/services/redis-service.js.map +1 -0
  148. package/dist/src/services/security-service.d.ts +11 -0
  149. package/dist/src/services/security-service.js +68 -0
  150. package/dist/src/services/security-service.js.map +1 -0
  151. package/package.json +1 -1
  152. package/src/constants.ts +47 -0
  153. package/src/gateways/alibaba-cloud-gateway.ts +127 -0
  154. package/src/gateways/http-audit-gateway.ts +104 -0
  155. package/src/gateways/index.ts +5 -0
  156. package/src/gateways/internal-auth-gateway.ts +42 -0
  157. package/src/gateways/stdout-audit-gateway.ts +23 -0
  158. package/src/gateways/webhook-audit-gateway.ts +33 -0
  159. package/src/interfaces.ts +304 -0
  160. package/src/models/audit-log.ts +126 -0
  161. package/src/models/index.ts +1 -0
  162. package/src/pkg/array-helper.ts +7 -0
  163. package/src/pkg/bcrypt-helper.ts +9 -0
  164. package/src/pkg/crypto-helper.ts +18 -0
  165. package/src/pkg/encryption-helper.spec.ts +423 -0
  166. package/src/pkg/encryption-helper.ts +155 -0
  167. package/src/pkg/filter-helper.spec.ts +105 -0
  168. package/src/pkg/filter-helper.ts +139 -0
  169. package/src/pkg/geoip-helper.ts +5 -0
  170. package/src/pkg/hash-helper.ts +12 -0
  171. package/src/pkg/http-request-utils.ts +75 -0
  172. package/src/pkg/index.ts +18 -0
  173. package/src/pkg/key-helper.ts +20 -0
  174. package/src/pkg/logger.ts +23 -0
  175. package/src/pkg/object-helper.ts +42 -0
  176. package/src/pkg/paginated-cache-registry.ts +25 -0
  177. package/src/pkg/query-helper.ts +79 -0
  178. package/src/pkg/referral-tree-utils.ts +165 -0
  179. package/src/pkg/scripts/index.ts +1 -0
  180. package/src/pkg/scripts/lua.ts +112 -0
  181. package/src/pkg/sort-helper.ts +19 -0
  182. package/src/pkg/string-utils.ts +104 -0
  183. package/src/pkg/task-helper.ts +25 -0
  184. package/src/pkg/workflow/delayed-task-registry.ts +54 -0
  185. package/src/pkg/workflow/delayed-task.ts +106 -0
  186. package/src/pkg/workflow/index.ts +5 -0
  187. package/src/pkg/workflow/processing-milestone.ts +54 -0
  188. package/src/pkg/workflow/retry-task.spec.ts +194 -0
  189. package/src/pkg/workflow/retry-task.ts +119 -0
  190. package/src/pkg/workflow/sync-taskqueue.ts +118 -0
  191. package/src/pkg/worksheet.utils.ts +178 -0
  192. package/src/services/audit-service.ts +22 -0
  193. package/src/services/excel.service.ts +103 -0
  194. package/src/services/http-service.ts +71 -0
  195. package/src/services/index.ts +8 -0
  196. package/src/services/kafka-service.ts +81 -0
  197. package/src/services/mailer-service.ts +43 -0
  198. package/src/services/paginated-cache.spec.ts +519 -0
  199. package/src/services/paginated-cache.ts +122 -0
  200. package/src/services/redis-service.ts +238 -0
  201. package/src/services/security-service.ts +80 -0
@@ -0,0 +1,119 @@
1
+ import { TaskFn } from "../../interfaces";
2
+
3
+ type TaskErrorHandler = (err: Error) => void | Promise<void>;
4
+ type DoneFn<T = any> = (err: Error, data: T) => void;
5
+
6
+ interface RetryTaskOptions {
7
+ taskName: string;
8
+ retryCount?: number;
9
+ retryIntervalInMs?: number;
10
+ returnOperationResult?: boolean;
11
+ }
12
+
13
+ export class RetryTask {
14
+ constructor(task: TaskFn, protected opts: RetryTaskOptions) {
15
+ this._task = task;
16
+ this._retryCount = opts?.retryCount || 3;
17
+ this._retryIntervalInMs = opts?.retryIntervalInMs || 500;
18
+ this._currentRetryCount = this._retryCount;
19
+ this.taskName = opts?.taskName;
20
+ }
21
+
22
+ protected _task: TaskFn;
23
+ protected _retryCount: number;
24
+ protected _currentRetryCount: number;
25
+ protected _retryIntervalInMs: number;
26
+
27
+ public taskName: string;
28
+
29
+ public get maxRetryCount(): number {
30
+ return this._retryCount;
31
+ }
32
+
33
+ public get retryCount(): number {
34
+ return this._currentRetryCount;
35
+ }
36
+
37
+ public get retryIntervalInMs(): number {
38
+ return this._retryIntervalInMs;
39
+ }
40
+
41
+ public async run<T = any>(
42
+ eachErrorHandler?: TaskErrorHandler,
43
+ allFailedHandler?: TaskErrorHandler
44
+ ): Promise<T> {
45
+ if (this._currentRetryCount === 0) {
46
+ throw new Error("retry task already run");
47
+ }
48
+
49
+ return new Promise(async (resolve, reject) => {
50
+ const doneFn = (err: Error, data: T) => {
51
+ if (err) {
52
+ reject(err);
53
+
54
+ return;
55
+ }
56
+
57
+ resolve(data);
58
+ };
59
+
60
+ this.execTask(doneFn, eachErrorHandler, allFailedHandler);
61
+ });
62
+ }
63
+
64
+ protected async execTask<T = any>(
65
+ done: DoneFn<T>,
66
+ eachErrorHandler: TaskErrorHandler,
67
+ allFailedHandler: TaskErrorHandler
68
+ ): Promise<void> {
69
+ // Max retry reached
70
+ if (this._currentRetryCount === 0) {
71
+ if (this.opts?.returnOperationResult) {
72
+ done(null, {
73
+ success: false,
74
+ message: `retry task ${this.taskName} failed after ${this.maxRetryCount} retries`,
75
+ } as any);
76
+
77
+ return;
78
+ }
79
+
80
+ const error = new Error(
81
+ `retry task ${this.taskName} failed after ${this.maxRetryCount} retries`
82
+ );
83
+
84
+ allFailedHandler?.(error);
85
+ done(error, null);
86
+
87
+ return;
88
+ }
89
+
90
+ try {
91
+ const result = await this._task();
92
+
93
+ // If operation result is returned
94
+ if (result?.success === false) {
95
+ throw new Error(result.message || "execution failed");
96
+ }
97
+
98
+ if (this.opts?.returnOperationResult && !result?.success) {
99
+ done(null, {
100
+ success: true,
101
+ data: result,
102
+ } as any);
103
+
104
+ return;
105
+ }
106
+
107
+ done(null, result);
108
+ } catch (error: any) {
109
+ eachErrorHandler?.(error);
110
+
111
+ setTimeout(
112
+ () => this.execTask(done, eachErrorHandler, allFailedHandler),
113
+ this.retryIntervalInMs
114
+ );
115
+ } finally {
116
+ this._currentRetryCount--;
117
+ }
118
+ }
119
+ }
@@ -0,0 +1,118 @@
1
+ import { EventEmitter } from "stream";
2
+
3
+ import { PinoLogger } from "../logger";
4
+ import { TaskQueue } from "../../interfaces";
5
+
6
+ class Task {
7
+ protected logger = new PinoLogger();
8
+ public isDone = false;
9
+
10
+ constructor(
11
+ public name: string,
12
+ protected handler: any,
13
+ protected doneFn: any
14
+ ) {}
15
+
16
+ public async run() {
17
+ try {
18
+ const data = await this.handler();
19
+
20
+ this.doneFn(null, data);
21
+ } catch (error) {
22
+ this.doneFn(error);
23
+ } finally {
24
+ this.isDone = true;
25
+ }
26
+ }
27
+ }
28
+
29
+ class Queue {
30
+ protected logger = new PinoLogger();
31
+ protected eventEmitter = new EventEmitter();
32
+
33
+ public isRunning: boolean = false;
34
+ public tasks: Task[] = [];
35
+
36
+ protected _interval: any;
37
+
38
+ constructor(protected queueName: string) {}
39
+
40
+ public onExhausted(callback: any) {
41
+ this.eventEmitter.once("exhausted", callback);
42
+ }
43
+
44
+ protected async runNextTask(): Promise<void> {
45
+ try {
46
+ const taskToRun = this.tasks.shift();
47
+ if (!taskToRun) {
48
+ this.isRunning = false;
49
+
50
+ this.eventEmitter.emit("exhausted");
51
+
52
+ return;
53
+ }
54
+
55
+ // Execute the task
56
+ await taskToRun.run();
57
+
58
+ // Run next task
59
+ // Don't want to block the callstack.
60
+ setTimeout(this.runNextTask.bind(this), 0);
61
+ } catch (error: any) {
62
+ this.logger.error(error.message, error.stack);
63
+
64
+ setTimeout(this.runNextTask.bind(this), 0);
65
+ }
66
+ }
67
+
68
+ protected async run(): Promise<void> {
69
+ // The queue is running, don't start new loop
70
+ if (this.isRunning) {
71
+ return;
72
+ }
73
+ this.isRunning = true;
74
+
75
+ // Task queue is exhausted. Start new loop
76
+ await this.runNextTask();
77
+ }
78
+
79
+ public add(task: Task): void {
80
+ this.tasks.push(task);
81
+
82
+ this.run();
83
+ }
84
+ }
85
+
86
+ export class SyncTaskQueue implements TaskQueue {
87
+ protected logger = new PinoLogger();
88
+ protected queueList: Map<string, Queue> = new Map();
89
+
90
+ public push<T>(queueName: string, name: string, handler: any): Promise<T> {
91
+ const queue = this.queueList.get(queueName) || new Queue(queueName);
92
+
93
+ return new Promise((resolve, reject) => {
94
+ const doneFn = (err: Error | null, data: T) => {
95
+ if (err) {
96
+ reject(err);
97
+
98
+ return;
99
+ }
100
+
101
+ resolve(data);
102
+ };
103
+
104
+ const task = new Task(name, handler, doneFn);
105
+
106
+ queue.add(task);
107
+
108
+ if (!this.queueList.has(queueName)) {
109
+ this.queueList.set(queueName, queue);
110
+
111
+ // Once the queue is exhausted, delete the queue to save memory
112
+ queue.onExhausted(() => {
113
+ this.queueList.delete(queueName);
114
+ });
115
+ }
116
+ });
117
+ }
118
+ }
@@ -0,0 +1,178 @@
1
+ import { Worksheet, Cell, Row, Column } from "exceljs";
2
+
3
+ import { ICellData, ICellOptions } from "../interfaces";
4
+
5
+ export class WorksheetUtils {
6
+ protected isAlive = true;
7
+
8
+ public id: number;
9
+
10
+ constructor(protected worksheet: Worksheet) {
11
+ this.id = worksheet.id;
12
+ }
13
+
14
+ public markRemoved(): void {
15
+ this.isAlive = false;
16
+ }
17
+
18
+ public rename(newName: string): void {
19
+ this.worksheet.name = newName;
20
+ }
21
+
22
+ public setRowHeight(rowNumber: number, height: number): void {
23
+ const row = this.getRow(rowNumber);
24
+
25
+ row.height = height;
26
+ }
27
+
28
+ public setColumnSize(columnName: string, width: number): void {
29
+ const column = this.getColumn(columnName);
30
+
31
+ column.width = width;
32
+ }
33
+
34
+ public getCellByAddress(
35
+ rowIndexOrName: string | number,
36
+ colIndexOrName: string | number
37
+ ): Cell {
38
+ const targetCell = this.worksheet.getCell(rowIndexOrName, colIndexOrName);
39
+
40
+ return targetCell;
41
+ }
42
+
43
+ public writeCellByAddress(
44
+ cellAddress: string,
45
+ cellData: Partial<ICellData>
46
+ ): Cell {
47
+ const targetCell = this.worksheet.getCell(cellAddress);
48
+
49
+ this.writeCell(targetCell, cellData);
50
+
51
+ return targetCell;
52
+ }
53
+
54
+ public writeRow(
55
+ rowNumber: number,
56
+ startColumnNumber: number,
57
+ writeData: any[]
58
+ ): Row {
59
+ const emptyArrayWithLength = Array(startColumnNumber);
60
+ const rowData = emptyArrayWithLength.concat(writeData);
61
+ const newRow = this.worksheet.insertRow(rowNumber, rowData, "o+");
62
+
63
+ newRow.commit();
64
+
65
+ return newRow;
66
+ }
67
+
68
+ public duplicateRow(rowNumber: number, amount = 1, insert = true): void {
69
+ this.worksheet.duplicateRow(rowNumber, amount, insert);
70
+ }
71
+
72
+ public duplicateColumn(colIndex: number): void {
73
+ const columnValues = this.worksheet.getColumn(colIndex).values;
74
+
75
+ this.cutAndOptionallyAddColumns(colIndex, 0, columnValues.slice());
76
+ }
77
+
78
+ public cutAndOptionallyAddColumns(
79
+ startColIndex: number,
80
+ cutCount: number,
81
+ ...args: any[][]
82
+ ) {
83
+ return this.worksheet.spliceColumns(startColIndex, cutCount, ...args);
84
+ }
85
+
86
+ public mergeCells(
87
+ startCellName: string,
88
+ endCellName: string,
89
+ ignoreStyle?: boolean
90
+ ): void {
91
+ this.throwIfNotAlive();
92
+
93
+ return this.worksheet.mergeCells(`${startCellName}:${endCellName}`);
94
+ }
95
+
96
+ public getRow(rowNumber1Based: number): Row {
97
+ this.throwIfNotAlive();
98
+
99
+ return this.worksheet.getRow(rowNumber1Based);
100
+ }
101
+
102
+ public getColumn(columnName: string): Partial<Column> {
103
+ this.throwIfNotAlive();
104
+
105
+ return this.worksheet.getColumn(columnName);
106
+ }
107
+
108
+ public commit(): void {
109
+ this.worksheet.commit();
110
+ }
111
+
112
+ public getColumnData(columnName: string, startIndex = 0): any[] {
113
+ this.throwIfNotAlive();
114
+
115
+ const column = this.getColumn(columnName);
116
+ const columnValues = column.values;
117
+
118
+ if (!columnValues || !columnValues.length) {
119
+ return [];
120
+ }
121
+
122
+ return columnValues.map((i) => i.valueOf()).slice(startIndex);
123
+ }
124
+
125
+ public getRowData(
126
+ rowNumber1Based: number,
127
+ startColIndex = 0,
128
+ endColIndex: number
129
+ ): any[] {
130
+ this.throwIfNotAlive();
131
+
132
+ const row = this.getRow(rowNumber1Based);
133
+ const rowValues = row.values;
134
+
135
+ if (!rowValues || !rowValues.length) {
136
+ return [];
137
+ }
138
+
139
+ if (Array.isArray(rowValues)) {
140
+ return rowValues
141
+ .map((cellValue) => cellValue.valueOf())
142
+ .slice(startColIndex, endColIndex);
143
+ } else {
144
+ return Object.values(rowValues)
145
+ .map((i) => i.valueOf())
146
+ .slice(startColIndex, endColIndex);
147
+ }
148
+ }
149
+
150
+ protected applyOptionsToCell(cell: Cell, options?: ICellOptions): void {
151
+ const { style, border } = options;
152
+
153
+ if (style) {
154
+ cell.style = style;
155
+ }
156
+
157
+ if (border) {
158
+ cell.border = border;
159
+ }
160
+ }
161
+
162
+ protected writeCell(cell: Cell, cellData: Partial<ICellData>): void {
163
+ const { value, options } = cellData;
164
+
165
+ cell.value = value;
166
+ if (options) {
167
+ this.applyOptionsToCell(cell, options);
168
+ }
169
+ }
170
+
171
+ protected throwIfNotAlive(): void {
172
+ if (this.isAlive) {
173
+ return;
174
+ }
175
+
176
+ throw new Error("Worksheet has been destroyed.");
177
+ }
178
+ }
@@ -0,0 +1,22 @@
1
+ import { AuditGateway } from "../interfaces";
2
+ import { LogObject } from "../models/audit-log";
3
+
4
+ export class AuditService {
5
+ constructor(protected auditCarrier: AuditGateway) {}
6
+
7
+ public async emitLog(log: LogObject): Promise<any> {
8
+ let result = null;
9
+ try {
10
+ result = await this.auditCarrier.publish(
11
+ log.logId,
12
+ log.level,
13
+ log.toJSON()
14
+ );
15
+ } catch (error) {
16
+ console.error(`[${log.logId}]failed to emit log: ` + log.toJSON());
17
+ console.error(error);
18
+ }
19
+
20
+ return result;
21
+ }
22
+ }
@@ -0,0 +1,103 @@
1
+ import "core-js/modules/es.promise";
2
+ import "core-js/modules/es.string.includes";
3
+ import "core-js/modules/es.object.assign";
4
+ import "core-js/modules/es.object.keys";
5
+ import "core-js/modules/es.symbol";
6
+ import "core-js/modules/es.symbol.async-iterator";
7
+ import "regenerator-runtime/runtime"; // For exceljs es5 to work.
8
+
9
+ import { AddWorksheetOptions, Buffer, Workbook as IWorkbook } from "exceljs";
10
+ import * as stream from "stream";
11
+ import { WorksheetUtils } from "../pkg/worksheet.utils";
12
+
13
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
14
+ const Workbook = require("exceljs/dist/es5/doc/workbook.js");
15
+
16
+ export class ExcelService {
17
+ protected workbook: IWorkbook;
18
+ protected workSheetMap = new Map() as Map<string, WorksheetUtils>;
19
+
20
+ public async loadTemplate(templatePath: string): Promise<this> {
21
+ try {
22
+ if (!templatePath) {
23
+ throw new Error("Missing excel template path");
24
+ }
25
+
26
+ const newWorkbook = new Workbook();
27
+ this.workbook = await newWorkbook.xlsx.readFile(templatePath);
28
+
29
+ return this;
30
+ } catch (error: any) {
31
+ throw new Error(`Error loading excel template: ${error.message}`);
32
+ }
33
+ }
34
+
35
+ public async loadFromBuffer(buffer: Buffer): Promise<this> {
36
+ try {
37
+ if (!buffer || !buffer.byteLength) {
38
+ throw new Error("Excel buffer is empty!");
39
+ }
40
+
41
+ const newWorkbook = new Workbook();
42
+ this.workbook = await newWorkbook.xlsx.load(buffer);
43
+
44
+ return this;
45
+ } catch (error: any) {
46
+ throw new Error(`Error loading excel from buffer: ${error.message}`);
47
+ }
48
+ }
49
+
50
+ public addWorkSheet(
51
+ workSheetName: string,
52
+ options?: Partial<AddWorksheetOptions>
53
+ ): WorksheetUtils {
54
+ const newWorksheet = this.workbook.addWorksheet(workSheetName, options);
55
+ const wrappedWorksheet = new WorksheetUtils(newWorksheet);
56
+
57
+ this.workSheetMap.set(workSheetName, wrappedWorksheet);
58
+
59
+ return wrappedWorksheet;
60
+ }
61
+
62
+ public getWorkSheet(workSheetName: string): WorksheetUtils {
63
+ const worksheet = this.workbook.getWorksheet(workSheetName);
64
+
65
+ if (worksheet) {
66
+ const newWorkSheetUtil = new WorksheetUtils(worksheet);
67
+ this.workSheetMap.set(workSheetName, newWorkSheetUtil);
68
+
69
+ return newWorkSheetUtil;
70
+ }
71
+
72
+ return this.addWorkSheet(workSheetName);
73
+ }
74
+
75
+ public writeToStream(readStream: stream.Stream): Promise<void> {
76
+ return this.workbook.xlsx.write(readStream);
77
+ }
78
+
79
+ public writeToFile(path: string): Promise<void> {
80
+ return this.workbook.xlsx.writeFile(path);
81
+ }
82
+
83
+ public write(stream: stream.Stream): Promise<void> {
84
+ return this.writeToStream(stream);
85
+ }
86
+
87
+ public writeToBuffer(): Promise<Buffer> {
88
+ return this.workbook.xlsx.writeBuffer();
89
+ }
90
+
91
+ public removeWorkSheet(worksheet: WorksheetUtils): void {
92
+ worksheet.markRemoved();
93
+ return this.workbook.removeWorksheet(worksheet.id);
94
+ }
95
+
96
+ protected throwIfTemplateNotLoaded(): void {
97
+ if (this.workbook) {
98
+ return;
99
+ }
100
+
101
+ throw new Error("Template not loaded. Please load template.");
102
+ }
103
+ }
@@ -0,0 +1,71 @@
1
+ import axios from "axios";
2
+
3
+ import { PinoLogger } from "../pkg/logger";
4
+ import { APP_ERROR, HttpMethod } from "../constants";
5
+ import {
6
+ HttpRequestOption,
7
+ HttpService,
8
+ Logger,
9
+ OperationResult,
10
+ } from "../interfaces";
11
+
12
+ export class AxiosHttpService implements HttpService {
13
+ constructor(protected logger: Logger = new PinoLogger()) {}
14
+
15
+ public async send<T = any>(
16
+ method: HttpMethod,
17
+ url: string,
18
+ options: HttpRequestOption = {}
19
+ ): Promise<OperationResult<T>> {
20
+ let response: any;
21
+
22
+ try {
23
+ response = await axios.request({
24
+ method,
25
+ url,
26
+ headers: options.headers,
27
+ data: options.body,
28
+ params: options.query,
29
+ ...options,
30
+ });
31
+
32
+ if (response.status >= 400) {
33
+ return {
34
+ success: false,
35
+ httpCode: response.status,
36
+ data: response.data,
37
+ };
38
+ }
39
+
40
+ return {
41
+ success: true,
42
+ data: response.data,
43
+ };
44
+ } catch (error: any) {
45
+ const errMsg =
46
+ error?.message ||
47
+ response?.data?.message ||
48
+ "error sending http request";
49
+
50
+ const errDetails = response?.data?.data ||
51
+ response?.data || { stack: error.stack };
52
+ this.logger.error(errMsg, errDetails);
53
+
54
+ // Due to timeout
55
+ if (error?.code && error.code === APP_ERROR.HTTP_REQ_TIMEOUT) {
56
+ return {
57
+ success: false,
58
+ code: APP_ERROR.HTTP_REQ_TIMEOUT,
59
+ httpCode: 408,
60
+ message: "request timeout",
61
+ };
62
+ }
63
+
64
+ return {
65
+ success: false,
66
+ message: error.message,
67
+ data: response?.data || {},
68
+ };
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,8 @@
1
+ export * from "./audit-service";
2
+ export * from "./excel.service";
3
+ export * from "./mailer-service";
4
+ export * from "./kafka-service";
5
+ export * from "./redis-service";
6
+ export * from "./security-service";
7
+ export * from "./http-service";
8
+ export * from "./paginated-cache";
@@ -0,0 +1,81 @@
1
+ import { IMessageQueueService } from "../interfaces";
2
+ import {
3
+ Consumer,
4
+ ConsumerConfig,
5
+ ConsumerSubscribeTopics,
6
+ Kafka,
7
+ KafkaConfig,
8
+ Producer,
9
+ ProducerConfig,
10
+ ConsumerRunConfig,
11
+ ProducerRecord,
12
+ TopicPartitionOffsetAndMetadata,
13
+ } from "kafkajs";
14
+
15
+ export class KafkaService implements IMessageQueueService {
16
+ protected _kafka: Kafka;
17
+
18
+ protected _producer: Producer;
19
+ protected _consumer: Consumer;
20
+
21
+ public get producer() {
22
+ if (!this._producer) {
23
+ throw new Error("producer not yet init");
24
+ }
25
+
26
+ return this._producer;
27
+ }
28
+
29
+ public get consumer() {
30
+ if (!this._consumer) {
31
+ throw new Error("consumer not yet init");
32
+ }
33
+
34
+ return this._consumer;
35
+ }
36
+
37
+ constructor(config: KafkaConfig) {
38
+ this._kafka = new Kafka(config);
39
+ }
40
+
41
+ async initProducer(config?: ProducerConfig) {
42
+ if (this._producer) {
43
+ console.warn("producer already initialized");
44
+
45
+ return;
46
+ }
47
+
48
+ this._producer = this._kafka.producer(config);
49
+
50
+ await this._producer.connect();
51
+ }
52
+
53
+ async initConsumer(config?: ConsumerConfig) {
54
+ if (this._consumer) {
55
+ console.warn("consumer already initialized");
56
+
57
+ return;
58
+ }
59
+
60
+ this._consumer = this._kafka.consumer(config);
61
+
62
+ await this._consumer.connect();
63
+ }
64
+
65
+ async listen(
66
+ subscribeConfig: ConsumerSubscribeTopics,
67
+ runConfig: ConsumerRunConfig
68
+ ): Promise<void> {
69
+ await this.consumer.subscribe(subscribeConfig);
70
+
71
+ return this.consumer.run(runConfig);
72
+ }
73
+
74
+ async publish(record: ProducerRecord): Promise<void> {
75
+ this._producer.send(record);
76
+ }
77
+
78
+ async commitOffsets(data: TopicPartitionOffsetAndMetadata[]): Promise<void> {
79
+ return this.consumer.commitOffsets(data);
80
+ }
81
+ }