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,139 @@
1
+ import { FILTER_OPERATOR } from "../constants";
2
+ import { IFilter } from "../interfaces";
3
+
4
+ export const toSimpleMongooseFilter = (
5
+ filters: IFilter[]
6
+ ): Record<string, any> => {
7
+ return filters.reduce((agg, current) => {
8
+ switch (current.operator) {
9
+ case FILTER_OPERATOR.EQUAL:
10
+ agg[current.field] = current.value;
11
+
12
+ break;
13
+ case FILTER_OPERATOR.NOT_EQUAL:
14
+ agg[current.field] = {
15
+ $ne: current.value,
16
+ };
17
+
18
+ break;
19
+
20
+ case FILTER_OPERATOR.NOT:
21
+ agg[current.field] = {
22
+ $ne: current.value,
23
+ };
24
+
25
+ break;
26
+
27
+ case FILTER_OPERATOR.LIKE:
28
+ agg[current.field] = {
29
+ $regex: `.*${current.value}.*`,
30
+ };
31
+
32
+ break;
33
+
34
+ case FILTER_OPERATOR.INS_LIKE:
35
+ agg[current.field] = {
36
+ $regex: `.*${current.value}.*`,
37
+ $options: "i",
38
+ };
39
+
40
+ break;
41
+
42
+ case FILTER_OPERATOR.STARTS_WITH:
43
+ agg[current.field] = {
44
+ $regex: `^${current.value}.*$`,
45
+ };
46
+
47
+ break;
48
+ case FILTER_OPERATOR.ENDS_WITH:
49
+ agg[current.field] = {
50
+ $regex: `.*${current.value}$`,
51
+ };
52
+
53
+ break;
54
+ case FILTER_OPERATOR.INS_STARTS_WITH:
55
+ agg[current.field] = {
56
+ $regex: `^${current.value}.*$`,
57
+ $options: "i",
58
+ };
59
+
60
+ break;
61
+ case FILTER_OPERATOR.INS_ENDS_WITH:
62
+ agg[current.field] = {
63
+ $regex: `.*${current.value}$`,
64
+ $options: "i",
65
+ };
66
+
67
+ break;
68
+ case FILTER_OPERATOR.GREATER_THAN:
69
+ agg[current.field] = {
70
+ $gt: current.value,
71
+ };
72
+
73
+ break;
74
+
75
+ case FILTER_OPERATOR.GREATER_THAN_OR_EQUAL:
76
+ agg[current.field] = {
77
+ $gte: current.value,
78
+ };
79
+
80
+ break;
81
+
82
+ case FILTER_OPERATOR.LESS_THAN:
83
+ agg[current.field] = {
84
+ $lt: current.value,
85
+ };
86
+
87
+ break;
88
+
89
+ case FILTER_OPERATOR.LESS_THAN_OR_EQUAL:
90
+ agg[current.field] = {
91
+ $lte: current.value,
92
+ };
93
+
94
+ break;
95
+
96
+ case FILTER_OPERATOR.IN:
97
+ agg[current.field] = current.value;
98
+
99
+ break;
100
+
101
+ case FILTER_OPERATOR.NOT_IN:
102
+ agg[current.field] = {
103
+ $nin: current.value,
104
+ };
105
+
106
+ break;
107
+
108
+ case FILTER_OPERATOR.OR:
109
+ const parsedOr =
110
+ current.value?.map((filterCondition: IFilter) =>
111
+ toSimpleMongooseFilter([filterCondition])
112
+ ) || [];
113
+
114
+ if (!parsedOr.length) {
115
+ break;
116
+ }
117
+
118
+ agg.$or = parsedOr;
119
+
120
+ break;
121
+
122
+ case FILTER_OPERATOR.NOR:
123
+ const parsedNor =
124
+ current.value?.map((filterCondition: IFilter) =>
125
+ toSimpleMongooseFilter([filterCondition])
126
+ ) || [];
127
+
128
+ if (!parsedNor.length) {
129
+ break;
130
+ }
131
+
132
+ agg.$nor = parsedNor;
133
+
134
+ break;
135
+ }
136
+
137
+ return agg;
138
+ }, {} as Record<string, any>);
139
+ };
@@ -0,0 +1,5 @@
1
+ import * as geoip from "geoip-country";
2
+
3
+ export function lookupIp(address: string): geoip.Lookup {
4
+ return geoip.lookup(address);
5
+ }
@@ -0,0 +1,12 @@
1
+ import * as crypto from "crypto";
2
+
3
+ import jsonS = require("fast-json-stable-stringify");
4
+
5
+ export const generateHashFromJSON = (data: Record<string, any>): string => {
6
+ if (!data || typeof data !== "object") {
7
+ throw new Error("Input must be a non-null object");
8
+ }
9
+
10
+ const jsonString = jsonS(data);
11
+ return crypto.createHash("sha256").update(jsonString).digest("hex");
12
+ };
@@ -0,0 +1,75 @@
1
+ export function constructUrlQueryString(
2
+ url: string,
3
+ queryStringData: any,
4
+ options?: { encodeUrl?: boolean }
5
+ ): string {
6
+ if (!queryStringData) {
7
+ return url;
8
+ }
9
+
10
+ const encoder = options?.encodeUrl
11
+ ? encodeURIComponent
12
+ : (value: any) => value;
13
+
14
+ const rawQueryString = [];
15
+ for (const props in queryStringData) {
16
+ const propValue = queryStringData[props];
17
+ if (propValue === undefined || propValue === null) {
18
+ continue;
19
+ }
20
+
21
+ if (typeof propValue === "object") {
22
+ rawQueryString.push(`${props}=${encoder(JSON.stringify(propValue))}`);
23
+ } else {
24
+ rawQueryString.push(`${props}=${encoder(propValue)}`);
25
+ }
26
+ }
27
+
28
+ return `${url}?${rawQueryString.join("&")}`;
29
+ }
30
+
31
+ const MASK_FIELDS = ["password", "secret"];
32
+
33
+ export function maskSensitiveData(
34
+ data: any,
35
+ maskFields: string[] = MASK_FIELDS
36
+ ): Record<string, any> {
37
+ // It is a string, number, or whatever. We don't process
38
+ if (typeof data !== "object") {
39
+ return data;
40
+ }
41
+
42
+ // Data is an object
43
+ if (!Array.isArray(data)) {
44
+ const maskedData = Object.assign({}, data || {});
45
+ const keys = Object.keys(data);
46
+
47
+ keys.forEach((key) => {
48
+ let value = data[key];
49
+
50
+ if (!value) {
51
+ return;
52
+ }
53
+
54
+ if (typeof value === "object") {
55
+ value = maskSensitiveData(value, maskFields);
56
+
57
+ maskedData[key] = value;
58
+
59
+ return;
60
+ }
61
+
62
+ // Key is not sensitive
63
+ if (!maskFields.includes(key)) {
64
+ return;
65
+ }
66
+
67
+ maskedData[key] = "***";
68
+ });
69
+
70
+ return maskedData;
71
+ }
72
+
73
+ // Data is an array
74
+ return data.map((i) => maskSensitiveData(i, maskFields));
75
+ }
@@ -0,0 +1,18 @@
1
+ export * as bcryptHelper from "./bcrypt-helper";
2
+ export * as httpRequestUtils from "./http-request-utils";
3
+ export * as objectHelper from "./object-helper";
4
+ export * as queryHelper from "./query-helper";
5
+ export * as stringUtils from "./string-utils";
6
+ export * as worksheetUtils from "./worksheet.utils";
7
+ export * as cryptoHelpers from "./crypto-helper";
8
+ export * as sortHelpers from "./sort-helper";
9
+ export * as filterHelpers from "./filter-helper";
10
+ export * as loggers from "./logger";
11
+ export * as workflows from "./workflow";
12
+ export * as geoipHelpers from "./geoip-helper";
13
+ export * as arrayHelpers from "./array-helper";
14
+ export * as referralTreeHelpers from "./referral-tree-utils";
15
+ export * as timeoutHelper from "./task-helper";
16
+ export * as cacheHelper from "./paginated-cache-registry";
17
+ export * as encryptionHelper from "./encryption-helper";
18
+ export * as scripts from "./scripts";
@@ -0,0 +1,20 @@
1
+ const versionPlaceholder = '_version';
2
+
3
+ // Helper functions for versioned cache keys
4
+ export const getVersionedCacheKey = (key: string, version: number) => {
5
+ if (key.includes(versionPlaceholder)) {
6
+ return key.replace(versionPlaceholder, version.toString());
7
+ }
8
+
9
+ return `${key}:version:${version}`;
10
+ };
11
+
12
+ export const getVersionCacheKeyForKey = (key: string) => {
13
+ if (key.includes(versionPlaceholder)) {
14
+ const indexOfPlaceholder = key.indexOf(versionPlaceholder);
15
+
16
+ return key.substring(0, indexOfPlaceholder);
17
+ }
18
+
19
+ return `${key}:version`;
20
+ };
@@ -0,0 +1,23 @@
1
+ import pino from "pino";
2
+
3
+ import { Logger } from "../interfaces";
4
+
5
+ export class PinoLogger implements Logger {
6
+ protected _logger: pino.Logger;
7
+
8
+ constructor() {
9
+ this._logger = pino();
10
+ }
11
+
12
+ public info(message: string, ...args: any[]): void {
13
+ return this._logger.info(message, ...args);
14
+ }
15
+
16
+ public error(message: string, ...args: any[]): void {
17
+ return this._logger.error(message, ...args);
18
+ }
19
+
20
+ public warn(message: string, ...args: any[]): void {
21
+ return this._logger.warn(message, ...args);
22
+ }
23
+ }
@@ -0,0 +1,42 @@
1
+ export function removeUndefinedProps(data: any): any {
2
+ const allKeys = Object.keys(data);
3
+
4
+ return allKeys.reduce((aggregated, current) => {
5
+ if (data[current] !== undefined) {
6
+ aggregated[current] = data[current];
7
+ }
8
+
9
+ return aggregated;
10
+ }, {});
11
+ }
12
+
13
+ export const tryParseStringIntoCorrectData = (data: string): any => {
14
+ if (!data?.length) {
15
+ return;
16
+ }
17
+
18
+ try {
19
+ // Parse boolean
20
+ if (data === "true") {
21
+ return true;
22
+ }
23
+
24
+ if (data === "false") {
25
+ return false;
26
+ }
27
+
28
+ // Parse number
29
+ const dataAsNumber = Number(data);
30
+
31
+ if (!Number.isNaN(dataAsNumber)) {
32
+ return dataAsNumber;
33
+ }
34
+
35
+ // Parse object
36
+ const parsedObject = JSON.parse(data);
37
+
38
+ return parsedObject;
39
+ } catch (error) {
40
+ return data;
41
+ }
42
+ };
@@ -0,0 +1,25 @@
1
+ import { CacheService, IPaginatedDataCache } from "../interfaces";
2
+ import { PaginatedDataCache } from "../services/paginated-cache";
3
+
4
+ export class PaginatedCacheRegistry {
5
+ protected _registry = new Map<string, IPaginatedDataCache>();
6
+
7
+ constructor(protected cacheService: CacheService) {}
8
+
9
+ public has(dataName: string): boolean {
10
+ return this._registry.has(dataName);
11
+ }
12
+
13
+ public getOrCreatePaginatedCache<T = any>(
14
+ dataName: string
15
+ ): IPaginatedDataCache<T> {
16
+ if (this._registry.has(dataName)) {
17
+ return this._registry.get(dataName);
18
+ }
19
+
20
+ const service = new PaginatedDataCache(dataName, this.cacheService);
21
+ this._registry.set(dataName, service);
22
+
23
+ return service;
24
+ }
25
+ }
@@ -0,0 +1,79 @@
1
+ import { FILTER_OPERATOR } from "../constants";
2
+ import { IFilter, ISort } from "../interfaces";
3
+
4
+ /**
5
+ * Parses a sort data such as "-price name date" into an array of generic sort data
6
+ * @param data the sort string
7
+ * @returns ISort[]
8
+ */
9
+ export function parseSort(data: string): ISort[] {
10
+ if (!data) {
11
+ return [];
12
+ }
13
+
14
+ const sortConditions: ISort[] = data.split(" ").map((item) => {
15
+ if (item[0] === "-") {
16
+ return {
17
+ columnName: item.slice(1, item.length - 1),
18
+ direction: "DESC",
19
+ };
20
+ }
21
+
22
+ return {
23
+ columnName: item,
24
+ direction: "ASC",
25
+ };
26
+ });
27
+
28
+ return sortConditions;
29
+ }
30
+
31
+ /**
32
+ * Parses filter expression for a field name
33
+ * @param field The fieldname in query string ?email=
34
+ * @param filterData The filter expression. Ex: eq:123 lt:100 gt:400
35
+ * @returns IFilter
36
+ */
37
+ export function parseFilter(field: string, filterData: string): IFilter {
38
+ if (!filterData) {
39
+ throw new Error("missing filter data");
40
+ }
41
+
42
+ const splittedData = filterData.split(":");
43
+ if (splittedData.length === 1) {
44
+ return {
45
+ field,
46
+ operator: FILTER_OPERATOR.EQUAL,
47
+ value: splittedData[0],
48
+ };
49
+ }
50
+
51
+ if (splittedData.length === 2) {
52
+ const [operator, value] = splittedData;
53
+
54
+ if (!Object.keys(FILTER_OPERATOR).includes(operator)) {
55
+ throw new Error(`invalid filter operator ${operator}`);
56
+ }
57
+
58
+ if (operator === FILTER_OPERATOR.OR || operator === FILTER_OPERATOR.AND) {
59
+ throw new Error("operator $or and $and are only for internal use");
60
+ }
61
+
62
+ if (
63
+ operator === FILTER_OPERATOR.IN ||
64
+ operator === FILTER_OPERATOR.NOT_IN
65
+ ) {
66
+ return {
67
+ field,
68
+ operator: operator as FILTER_OPERATOR,
69
+ value: value.split(","),
70
+ };
71
+ }
72
+
73
+ return {
74
+ field,
75
+ operator: operator as FILTER_OPERATOR,
76
+ value,
77
+ };
78
+ }
79
+ }
@@ -0,0 +1,165 @@
1
+ import { faker } from "@faker-js/faker";
2
+
3
+ import { stringUtils } from ".";
4
+
5
+ interface UserConfig {
6
+ rootRefCode?: string;
7
+ password: string;
8
+ }
9
+
10
+ interface User {
11
+ parentRefCode: string;
12
+ refCode: string;
13
+ password: string;
14
+ email: string;
15
+ children: User[];
16
+ }
17
+
18
+ interface NormalizedUser {
19
+ parentRefCode: string;
20
+ refCode: string;
21
+ password: string;
22
+ email: string;
23
+ }
24
+
25
+ interface ReferralTreeConfig {
26
+ noOfLevels: number;
27
+ minChildPerNode: number;
28
+ maxChildPerNode: number;
29
+ mustHaveChildPerNode: number;
30
+ userConfig: UserConfig;
31
+ passwordHasher?: (password: string) => Promise<string>;
32
+ refCodeGenerator?: () => string;
33
+ addAdditionalData?: () => Promise<Record<string, any>>;
34
+ }
35
+
36
+ const defaultRefcodeGenerator = () =>
37
+ stringUtils.generateRandomId().slice(10).toUpperCase();
38
+
39
+ export const generateReferralTree = async (data: ReferralTreeConfig) => {
40
+ const {
41
+ maxChildPerNode,
42
+ minChildPerNode,
43
+ mustHaveChildPerNode,
44
+ noOfLevels,
45
+ userConfig,
46
+ passwordHasher,
47
+ refCodeGenerator,
48
+ addAdditionalData = () => {},
49
+ } = data;
50
+
51
+ const hashedPassword = await passwordHasher(userConfig.password);
52
+
53
+ const rootUser = await genNewUser(null, {
54
+ hashedPassword,
55
+ additionalDataGenerator: addAdditionalData,
56
+ refCodeGenerator: refCodeGenerator || defaultRefcodeGenerator,
57
+ });
58
+
59
+ const totalUsersToInsert: NormalizedUser[] = [normalizeUser(rootUser)];
60
+
61
+ let currentLayerUsers: User[] = [rootUser];
62
+ let totalUsersCount = currentLayerUsers.length;
63
+
64
+ for (let currentLevel = 0; currentLevel < noOfLevels; currentLevel++) {
65
+ const allChildUserCreated: User[] = [];
66
+
67
+ // Handle the node where the number of children is required
68
+ const nodeSelectedAsRequired = currentLayerUsers[0];
69
+ for (let i = 0; i < mustHaveChildPerNode; i++) {
70
+ const newUser = await genNewUser(nodeSelectedAsRequired.refCode, {
71
+ hashedPassword,
72
+ refCodeGenerator: refCodeGenerator || defaultRefcodeGenerator,
73
+ additionalDataGenerator: addAdditionalData,
74
+ });
75
+
76
+ allChildUserCreated.push(newUser);
77
+ nodeSelectedAsRequired.children.push(newUser);
78
+ }
79
+
80
+ // Handle the nodes where the number of children is within range.
81
+ // Exclude the first user as it's already processed
82
+ await Promise.all(
83
+ currentLayerUsers.slice(1, currentLayerUsers.length).map(async (user) => {
84
+ const noOfChildNodes = faker.helpers.rangeToNumber({
85
+ min: minChildPerNode,
86
+ max: maxChildPerNode,
87
+ });
88
+
89
+ for (let i = 0; i < noOfChildNodes; i++) {
90
+ const newUser = await genNewUser(user.refCode, {
91
+ hashedPassword,
92
+ refCodeGenerator: refCodeGenerator || defaultRefcodeGenerator,
93
+ additionalDataGenerator: addAdditionalData,
94
+ });
95
+
96
+ allChildUserCreated.push(newUser);
97
+ user.children.push(newUser);
98
+ }
99
+ })
100
+ );
101
+
102
+ // Move on to next layer
103
+ const normalizedUsers: Omit<User, "children">[] =
104
+ allChildUserCreated.map(normalizeUser);
105
+
106
+ totalUsersToInsert.push(...normalizedUsers);
107
+ currentLayerUsers = allChildUserCreated;
108
+ totalUsersCount += currentLayerUsers.length;
109
+ }
110
+
111
+ return { rootUser, totalUsersCount, totalUsersToInsert };
112
+ };
113
+
114
+ const normalizeUser = (user: User) => {
115
+ const cloned = JSON.parse(JSON.stringify(user));
116
+ delete cloned.children;
117
+
118
+ return cloned;
119
+ };
120
+
121
+ const genNewUser = async (
122
+ parentRefCode: string,
123
+ { hashedPassword, refCodeGenerator, additionalDataGenerator }
124
+ ): Promise<User> => {
125
+ const additionalData = await additionalDataGenerator();
126
+
127
+ return {
128
+ parentRefCode,
129
+ password: hashedPassword,
130
+ email: faker.internet.email().toLowerCase(),
131
+ children: [],
132
+ refCode: refCodeGenerator(),
133
+ ...additionalData,
134
+ };
135
+ };
136
+
137
+ // generateReferralTree({
138
+ // maxChildPerNode: 2,
139
+ // minChildPerNode: 1,
140
+ // mustHaveChildPerNode: 5,
141
+ // noOfLevels: 5,
142
+ // passwordHasher: async (data) => data,
143
+ // addAdditionalData: async () => {
144
+ // return {
145
+ // fullName: faker.person.fullName(),
146
+ // };
147
+ // },
148
+ // userConfig: {
149
+ // password: "12345",
150
+ // rootRefCode: "ABCD1234",
151
+ // },
152
+ // })
153
+ // .then((data) => {
154
+ // console.log(data.totalUsersCount);
155
+ // fs.writeFileSync(
156
+ // path.resolve(__dirname, "referral_tree.json"),
157
+ // Buffer.from(JSON.stringify(data.rootUser))
158
+ // );
159
+
160
+ // fs.writeFileSync(
161
+ // path.resolve(__dirname, "referral_users.json"),
162
+ // Buffer.from(JSON.stringify(data.totalUsersToInsert))
163
+ // );
164
+ // })
165
+ // .catch((e) => console.error(e));
@@ -0,0 +1 @@
1
+ export * as luaScripts from "./lua";