eh-commons 0.0.1-testing.1

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 (208) hide show
  1. package/.eslintrc.js +25 -0
  2. package/.prettierrc +4 -0
  3. package/README.md +0 -0
  4. package/devops.md +15 -0
  5. package/dist/clients/logger.client.d.ts +10 -0
  6. package/dist/clients/logger.client.js +42 -0
  7. package/dist/clients/logger.client.js.map +1 -0
  8. package/dist/clients/session.client.d.ts +10 -0
  9. package/dist/clients/session.client.js +37 -0
  10. package/dist/clients/session.client.js.map +1 -0
  11. package/dist/constraints/is-map-of-strings.constraint.d.ts +5 -0
  12. package/dist/constraints/is-map-of-strings.constraint.js +34 -0
  13. package/dist/constraints/is-map-of-strings.constraint.js.map +1 -0
  14. package/dist/constraints/is-route.constraint.d.ts +5 -0
  15. package/dist/constraints/is-route.constraint.js +24 -0
  16. package/dist/constraints/is-route.constraint.js.map +1 -0
  17. package/dist/decorators/is-map-of-strings.decorator.d.ts +1 -0
  18. package/dist/decorators/is-map-of-strings.decorator.js +14 -0
  19. package/dist/decorators/is-map-of-strings.decorator.js.map +1 -0
  20. package/dist/decorators/is-route.decorator.d.ts +1 -0
  21. package/dist/decorators/is-route.decorator.js +12 -0
  22. package/dist/decorators/is-route.decorator.js.map +1 -0
  23. package/dist/exceptions/custom.exception.d.ts +10 -0
  24. package/dist/exceptions/custom.exception.js +18 -0
  25. package/dist/exceptions/custom.exception.js.map +1 -0
  26. package/dist/factories/exception.factory.d.ts +4 -0
  27. package/dist/factories/exception.factory.js +15 -0
  28. package/dist/factories/exception.factory.js.map +1 -0
  29. package/dist/filters/base-exception.filter.d.ts +6 -0
  30. package/dist/filters/base-exception.filter.js +113 -0
  31. package/dist/filters/base-exception.filter.js.map +1 -0
  32. package/dist/functions/escape-regex.function.d.ts +1 -0
  33. package/dist/functions/escape-regex.function.js +8 -0
  34. package/dist/functions/escape-regex.function.js.map +1 -0
  35. package/dist/functions/generate-uuid.function.d.ts +1 -0
  36. package/dist/functions/generate-uuid.function.js +12 -0
  37. package/dist/functions/generate-uuid.function.js.map +1 -0
  38. package/dist/functions/json-size.function.d.ts +1 -0
  39. package/dist/functions/json-size.function.js +10 -0
  40. package/dist/functions/json-size.function.js.map +1 -0
  41. package/dist/functions/random-range.function.d.ts +1 -0
  42. package/dist/functions/random-range.function.js +11 -0
  43. package/dist/functions/random-range.function.js.map +1 -0
  44. package/dist/functions/transliterate-geo-to-latin.d.ts +1 -0
  45. package/dist/functions/transliterate-geo-to-latin.js +46 -0
  46. package/dist/functions/transliterate-geo-to-latin.js.map +1 -0
  47. package/dist/index.d.ts +38 -0
  48. package/dist/index.js +79 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/models/dtos/record.dto.d.ts +5 -0
  51. package/dist/models/dtos/record.dto.js +28 -0
  52. package/dist/models/dtos/record.dto.js.map +1 -0
  53. package/dist/models/dtos/state-params.dto.d.ts +5 -0
  54. package/dist/models/dtos/state-params.dto.js +26 -0
  55. package/dist/models/dtos/state-params.dto.js.map +1 -0
  56. package/dist/models/embedded/address.embedded.d.ts +39 -0
  57. package/dist/models/embedded/address.embedded.js +34 -0
  58. package/dist/models/embedded/address.embedded.js.map +1 -0
  59. package/dist/models/embedded/contact.embedded.d.ts +39 -0
  60. package/dist/models/embedded/contact.embedded.js +38 -0
  61. package/dist/models/embedded/contact.embedded.js.map +1 -0
  62. package/dist/models/embedded/geo-location.embedded.d.ts +38 -0
  63. package/dist/models/embedded/geo-location.embedded.js +33 -0
  64. package/dist/models/embedded/geo-location.embedded.js.map +1 -0
  65. package/dist/models/embedded/i18n.embedded.d.ts +38 -0
  66. package/dist/models/embedded/i18n.embedded.js +33 -0
  67. package/dist/models/embedded/i18n.embedded.js.map +1 -0
  68. package/dist/models/embedded/person.embedded.d.ts +38 -0
  69. package/dist/models/embedded/person.embedded.js +33 -0
  70. package/dist/models/embedded/person.embedded.js.map +1 -0
  71. package/dist/models/embedded/record.embedded.d.ts +41 -0
  72. package/dist/models/embedded/record.embedded.js +47 -0
  73. package/dist/models/embedded/record.embedded.js.map +1 -0
  74. package/dist/models/enums/contact-type.enum.d.ts +4 -0
  75. package/dist/models/enums/contact-type.enum.js +9 -0
  76. package/dist/models/enums/contact-type.enum.js.map +1 -0
  77. package/dist/models/enums/env.enum.d.ts +5 -0
  78. package/dist/models/enums/env.enum.js +10 -0
  79. package/dist/models/enums/env.enum.js.map +1 -0
  80. package/dist/models/enums/fail-keyword.enum.d.ts +5 -0
  81. package/dist/models/enums/fail-keyword.enum.js +10 -0
  82. package/dist/models/enums/fail-keyword.enum.js.map +1 -0
  83. package/dist/models/enums/http-method.enum.d.ts +7 -0
  84. package/dist/models/enums/http-method.enum.js +12 -0
  85. package/dist/models/enums/http-method.enum.js.map +1 -0
  86. package/dist/models/enums/permission-include-strategy.enum.d.ts +5 -0
  87. package/dist/models/enums/permission-include-strategy.enum.js +10 -0
  88. package/dist/models/enums/permission-include-strategy.enum.js.map +1 -0
  89. package/dist/models/enums/record-state.enum.d.ts +5 -0
  90. package/dist/models/enums/record-state.enum.js +10 -0
  91. package/dist/models/enums/record-state.enum.js.map +1 -0
  92. package/dist/models/interfaces/address.interface.d.ts +6 -0
  93. package/dist/models/interfaces/address.interface.js +3 -0
  94. package/dist/models/interfaces/address.interface.js.map +1 -0
  95. package/dist/models/interfaces/contact.interface.d.ts +6 -0
  96. package/dist/models/interfaces/contact.interface.js +3 -0
  97. package/dist/models/interfaces/contact.interface.js.map +1 -0
  98. package/dist/models/interfaces/geo-location.interface.d.ts +5 -0
  99. package/dist/models/interfaces/geo-location.interface.js +3 -0
  100. package/dist/models/interfaces/geo-location.interface.js.map +1 -0
  101. package/dist/models/interfaces/i18n.interface.d.ts +5 -0
  102. package/dist/models/interfaces/i18n.interface.js +3 -0
  103. package/dist/models/interfaces/i18n.interface.js.map +1 -0
  104. package/dist/models/interfaces/person.interface.d.ts +5 -0
  105. package/dist/models/interfaces/person.interface.js +3 -0
  106. package/dist/models/interfaces/person.interface.js.map +1 -0
  107. package/dist/models/interfaces/record.interface.d.ts +8 -0
  108. package/dist/models/interfaces/record.interface.js +3 -0
  109. package/dist/models/interfaces/record.interface.js.map +1 -0
  110. package/dist/models/interfaces/session/session-data.interface.d.ts +11 -0
  111. package/dist/models/interfaces/session/session-data.interface.js +3 -0
  112. package/dist/models/interfaces/session/session-data.interface.js.map +1 -0
  113. package/dist/models/interfaces/session/session.interface.d.ts +8 -0
  114. package/dist/models/interfaces/session/session.interface.js +3 -0
  115. package/dist/models/interfaces/session/session.interface.js.map +1 -0
  116. package/dist/models/wrappers/client-permissions.wrapper.d.ts +4 -0
  117. package/dist/models/wrappers/client-permissions.wrapper.js +7 -0
  118. package/dist/models/wrappers/client-permissions.wrapper.js.map +1 -0
  119. package/dist/models/wrappers/permission-guard-config.wrapper.d.ts +6 -0
  120. package/dist/models/wrappers/permission-guard-config.wrapper.js +10 -0
  121. package/dist/models/wrappers/permission-guard-config.wrapper.js.map +1 -0
  122. package/dist/models/wrappers/rest-wrapper.class.d.ts +58 -0
  123. package/dist/models/wrappers/rest-wrapper.class.js +162 -0
  124. package/dist/models/wrappers/rest-wrapper.class.js.map +1 -0
  125. package/dist/modules/cache/cache.module.d.ts +2 -0
  126. package/dist/modules/cache/cache.module.js +25 -0
  127. package/dist/modules/cache/cache.module.js.map +1 -0
  128. package/dist/modules/cache/guards/permission.guard.d.ts +14 -0
  129. package/dist/modules/cache/guards/permission.guard.js +101 -0
  130. package/dist/modules/cache/guards/permission.guard.js.map +1 -0
  131. package/dist/modules/cache/reflector/permission.reflector.d.ts +2 -0
  132. package/dist/modules/cache/reflector/permission.reflector.js +6 -0
  133. package/dist/modules/cache/reflector/permission.reflector.js.map +1 -0
  134. package/dist/modules/cache/services/redis.service.d.ts +11 -0
  135. package/dist/modules/cache/services/redis.service.js +70 -0
  136. package/dist/modules/cache/services/redis.service.js.map +1 -0
  137. package/dist/modules/cache/services/session.service.d.ts +6 -0
  138. package/dist/modules/cache/services/session.service.js +27 -0
  139. package/dist/modules/cache/services/session.service.js.map +1 -0
  140. package/dist/modules/log/log.module.d.ts +2 -0
  141. package/dist/modules/log/log.module.js +23 -0
  142. package/dist/modules/log/log.module.js.map +1 -0
  143. package/dist/modules/log/services/log.service.d.ts +6 -0
  144. package/dist/modules/log/services/log.service.js +32 -0
  145. package/dist/modules/log/services/log.service.js.map +1 -0
  146. package/dist/pipes/validate-mongo-id.pipe.d.ts +4 -0
  147. package/dist/pipes/validate-mongo-id.pipe.js +28 -0
  148. package/dist/pipes/validate-mongo-id.pipe.js.map +1 -0
  149. package/dist/tsconfig.tsbuildinfo +1 -0
  150. package/dist/utils/config-util.class.d.ts +5 -0
  151. package/dist/utils/config-util.class.js +18 -0
  152. package/dist/utils/config-util.class.js.map +1 -0
  153. package/dist/utils/console-logger.class.d.ts +9 -0
  154. package/dist/utils/console-logger.class.js +39 -0
  155. package/dist/utils/console-logger.class.js.map +1 -0
  156. package/package.json +35 -0
  157. package/src/clients/logger.client.ts +57 -0
  158. package/src/clients/session.client.ts +42 -0
  159. package/src/constraints/is-map-of-strings.constraint.ts +26 -0
  160. package/src/constraints/is-route.constraint.ts +14 -0
  161. package/src/decorators/is-map-of-strings.decorator.ts +10 -0
  162. package/src/decorators/is-route.decorator.ts +8 -0
  163. package/src/exceptions/custom.exception.ts +16 -0
  164. package/src/factories/exception.factory.ts +14 -0
  165. package/src/filters/base-exception.filter.ts +192 -0
  166. package/src/functions/escape-regex.function.ts +5 -0
  167. package/src/functions/generate-uuid.function.ts +7 -0
  168. package/src/functions/json-size.function.ts +9 -0
  169. package/src/functions/random-range.function.ts +6 -0
  170. package/src/functions/transliterate-geo-to-latin.ts +42 -0
  171. package/src/index.ts +96 -0
  172. package/src/models/dtos/record.dto.ts +12 -0
  173. package/src/models/dtos/state-params.dto.ts +10 -0
  174. package/src/models/embedded/address.embedded.ts +17 -0
  175. package/src/models/embedded/contact.embedded.ts +22 -0
  176. package/src/models/embedded/geo-location.embedded.ts +17 -0
  177. package/src/models/embedded/i18n.embedded.ts +16 -0
  178. package/src/models/embedded/person.embedded.ts +16 -0
  179. package/src/models/embedded/record.embedded.ts +30 -0
  180. package/src/models/enums/contact-type.enum.ts +4 -0
  181. package/src/models/enums/env.enum.ts +5 -0
  182. package/src/models/enums/fail-keyword.enum.ts +6 -0
  183. package/src/models/enums/http-method.enum.ts +7 -0
  184. package/src/models/enums/permission-include-strategy.enum.ts +5 -0
  185. package/src/models/enums/record-state.enum.ts +5 -0
  186. package/src/models/interfaces/address.interface.ts +7 -0
  187. package/src/models/interfaces/contact.interface.ts +7 -0
  188. package/src/models/interfaces/geo-location.interface.ts +5 -0
  189. package/src/models/interfaces/i18n.interface.ts +5 -0
  190. package/src/models/interfaces/person.interface.ts +5 -0
  191. package/src/models/interfaces/record.interface.ts +9 -0
  192. package/src/models/interfaces/session/session-data.interface.ts +11 -0
  193. package/src/models/interfaces/session/session.interface.ts +9 -0
  194. package/src/models/wrappers/client-permissions.wrapper.ts +4 -0
  195. package/src/models/wrappers/permission-guard-config.wrapper.ts +7 -0
  196. package/src/models/wrappers/rest-wrapper.class.ts +172 -0
  197. package/src/modules/cache/cache.module.ts +12 -0
  198. package/src/modules/cache/guards/permission.guard.ts +166 -0
  199. package/src/modules/cache/reflector/permission.reflector.ts +4 -0
  200. package/src/modules/cache/services/redis.service.ts +37 -0
  201. package/src/modules/cache/services/session.service.ts +11 -0
  202. package/src/modules/log/log.module.ts +10 -0
  203. package/src/modules/log/services/log.service.ts +20 -0
  204. package/src/pipes/validate-mongo-id.pipe.ts +17 -0
  205. package/src/utils/config-util.class.ts +15 -0
  206. package/src/utils/console-logger.class.ts +42 -0
  207. package/tsconfig.build.json +9 -0
  208. package/tsconfig.json +26 -0
@@ -0,0 +1,9 @@
1
+ export declare class ConsoleLogger {
2
+ private static logLevels;
3
+ static info(...msg: unknown[]): void;
4
+ static error(...msg: unknown[]): void;
5
+ static warn(...msg: unknown[]): void;
6
+ static debug(...msg: unknown[]): void;
7
+ private static _log;
8
+ private static _logPrefix;
9
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConsoleLogger = void 0;
4
+ const config_util_class_1 = require("./config-util.class");
5
+ const logsEnabledKeyword = 'APP__LOGS__ENABLE';
6
+ const logLevelsKeyword = 'APP__LOGS__LEVELS';
7
+ const levelColors = {
8
+ info: "\x1b[32m",
9
+ warn: "\x1b[33m",
10
+ error: '\x1b[31m',
11
+ debug: '\x1b[36m',
12
+ };
13
+ class ConsoleLogger {
14
+ static info(...msg) {
15
+ this._log('info', ...msg);
16
+ }
17
+ static error(...msg) {
18
+ this._log('error', ...msg);
19
+ }
20
+ static warn(...msg) {
21
+ this._log('warn', ...msg);
22
+ }
23
+ static debug(...msg) {
24
+ this._log('debug', ...msg);
25
+ }
26
+ static _log(level, ...logs) {
27
+ const enabled = config_util_class_1.ConfigUtil.get(logsEnabledKeyword);
28
+ if (!(enabled == 'true' || enabled == '1') || !this.logLevels.includes(level))
29
+ return;
30
+ if (console[level])
31
+ console[level](...this._logPrefix(level), ...logs, '\x1b[0m');
32
+ }
33
+ static _logPrefix(level) {
34
+ return ['\x1b[33m', '[G3] - ', '\x1b[0m', `${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()} `, levelColors[level], level.toUpperCase(), ' '];
35
+ }
36
+ }
37
+ exports.ConsoleLogger = ConsoleLogger;
38
+ ConsoleLogger.logLevels = config_util_class_1.ConfigUtil.get(logLevelsKeyword) || "";
39
+ //# sourceMappingURL=console-logger.class.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console-logger.class.js","sourceRoot":"","sources":["../../src/utils/console-logger.class.ts"],"names":[],"mappings":";;;AAAA,2DAAiD;AACjD,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AAC/C,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AAE7C,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,UAAU;IACjB,KAAK,EAAE,UAAU;CAClB,CAAA;AACD,MAAa,aAAa;IAGjB,MAAM,CAAC,IAAI,CAAC,GAAG,GAAc;QAClC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;IAC5B,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,GAAG,GAAc;QACnC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,CAAC;IAC7B,CAAC;IAEM,MAAM,CAAC,IAAI,CAAC,GAAG,GAAc;QAClC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;IAC5B,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,GAAG,GAAc;QACnC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,CAAC;IAC7B,CAAC;IAEO,MAAM,CAAC,IAAI,CAAC,KAA0C,EAAE,GAAG,IAAe;QAChF,MAAM,OAAO,GAAG,8BAAU,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QACnD,IAAI,CAAC,CAAC,OAAO,IAAI,MAAM,IAAI,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO;QAEtF,IAAI,OAAO,CAAC,KAAK,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,SAAS,CAAC,CAAC;IAElE,CAAC;IAEO,MAAM,CAAC,UAAU,CAAC,KAAa;QACrC,OAAO,CAAC,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,CAAA;IACzK,CAAC;;AA9BH,sCA+BC;AA9BgB,uBAAS,GAAG,8BAAU,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "eh-commons",
3
+ "type": "commonjs",
4
+ "version": "0.0.1-testing.01",
5
+ "description": "eh-commons",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "prepublish": "tsc",
10
+ "build": "tsc"
11
+ },
12
+ "author": "",
13
+ "license": "ISC",
14
+ "devDependencies": {
15
+ "@types/express": "^4.17.17",
16
+ "@types/node": "^18.15.11",
17
+ "@typescript-eslint/eslint-plugin": "^6.18.1",
18
+ "@typescript-eslint/parser": "^6.18.1",
19
+ "eslint": "^8.56.0",
20
+ "typescript": "^5.0.4"
21
+ },
22
+ "dependencies": {
23
+ "@nestjs/common": "^10.3.7",
24
+ "@nestjs/config": "^3.1.1",
25
+ "@nestjs/core": "^10.3.1",
26
+ "@nestjs/mongoose": "^10.0.2",
27
+ "class-transformer": "^0.5.1",
28
+ "class-validator": "^0.14.0",
29
+ "express": "^4.18.2",
30
+ "ioredis": "^5.3.2",
31
+ "kafkajs": "^2.2.4",
32
+ "mongoose": "^8.0.4",
33
+ "rxjs": "^7.8.1"
34
+ }
35
+ }
@@ -0,0 +1,57 @@
1
+ import { Kafka, Producer, RecordMetadata, TopicMessages } from 'kafkajs';
2
+ import { Observable, catchError, from, map, mergeMap, of } from 'rxjs';
3
+
4
+ export class LoggerClient {
5
+ private kafka: Kafka;
6
+ private kafkaTopic: string;
7
+ private producer: Producer;
8
+ constructor(
9
+ kafkaBrokers: string[],
10
+ kafkaClientId: string,
11
+ kafkaLogTopic: string,
12
+ ) {
13
+ this.kafkaTopic = kafkaLogTopic;
14
+ this.kafka = new Kafka({ brokers: kafkaBrokers, clientId: kafkaClientId });
15
+ this.producer = this.kafka.producer();
16
+ }
17
+
18
+ private connectProducer(): Observable<void> {
19
+ return from(this.producer.connect());
20
+ }
21
+ private disconnectProducer(): Observable<void> {
22
+ return from(this.producer.disconnect());
23
+ }
24
+ private sendLog(log: any, key?: string): Observable<RecordMetadata[]> {
25
+ let messageString = JSON.stringify(log);
26
+ return this.connectProducer().pipe(
27
+ mergeMap(() => {
28
+ return this.send(messageString, key).pipe(
29
+ map((recordMetadata) => {
30
+ this.disconnectProducer().subscribe();
31
+ return recordMetadata;
32
+ }),
33
+ );
34
+ }),
35
+ catchError((err) => {
36
+ return of(err);
37
+ }),
38
+ );
39
+ }
40
+
41
+ private send(
42
+ messageString: string,
43
+ key?: string,
44
+ ): Observable<RecordMetadata[]> {
45
+ return from(
46
+ this.producer.send({
47
+ topic: this.kafkaTopic,
48
+ messages: [
49
+ {
50
+ key,
51
+ value: messageString,
52
+ },
53
+ ],
54
+ }),
55
+ );
56
+ }
57
+ }
@@ -0,0 +1,42 @@
1
+ import * as IORedis from 'ioredis';
2
+
3
+ import { ISessionUserData } from '../models/interfaces/session/session-data.interface';
4
+
5
+ export class SessionClient {
6
+ private redisClient: IORedis.Redis;
7
+
8
+ constructor(client: IORedis.Redis) {
9
+ this.redisClient = client;
10
+ }
11
+
12
+ public get(key: string): Promise<string> {
13
+ return this.redisClient.get(key);
14
+ }
15
+
16
+ public set(key: string, value: string): Promise<string> {
17
+ return this.redisClient.set(key, value);
18
+ }
19
+
20
+ public delete(key: string): Promise<number> {
21
+ return this.redisClient.del(key);
22
+ }
23
+
24
+ private parseUser(jsonString: string): ISessionUserData | null {
25
+ try {
26
+ const parsedUser: ISessionUserData = JSON.parse(jsonString);
27
+ return parsedUser;
28
+ } catch (error) {
29
+ return null;
30
+ }
31
+ }
32
+
33
+ private parse<T>(jsonString: string): T | null {
34
+ try {
35
+ const result: T = JSON.parse(jsonString);
36
+ return result;
37
+ } catch (error) {
38
+ return null;
39
+ }
40
+ }
41
+
42
+ }
@@ -0,0 +1,26 @@
1
+ import { ValidationArguments, ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator';
2
+
3
+ @ValidatorConstraint({ name: 'IsMapOfStrings', async: false })
4
+ export class IsMapOfStringsConstraint implements ValidatorConstraintInterface {
5
+ validate(value: any, args: ValidationArguments): boolean {
6
+ if (!value || typeof value !== 'object') {
7
+ return false;
8
+ }
9
+
10
+ if (!Object.keys(value).length) {
11
+ return false;
12
+ }
13
+
14
+ for (let key in value) {
15
+ if (typeof value[key] !== 'string') {
16
+ return false;
17
+ }
18
+ }
19
+
20
+ return true;
21
+ }
22
+
23
+ defaultMessage(args: ValidationArguments): string {
24
+ return `${args.property} must be a map object with string values.`;
25
+ }
26
+ }
@@ -0,0 +1,14 @@
1
+ import { ValidationArguments, ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator';
2
+
3
+ @ValidatorConstraint({ name: 'IsRoute', async: false })
4
+ export class IsRouteConstraint implements ValidatorConstraintInterface {
5
+ validate(value: any, args: ValidationArguments): boolean {
6
+ //const routePattern = /^\/[\w\/]+(\?.+)?$/;
7
+ const routePattern = /^\/[\w-\/]+(\?.+)?$/;
8
+ return typeof value === 'string' && routePattern.test(value);
9
+ }
10
+
11
+ defaultMessage(args: ValidationArguments): string {
12
+ return `${args.property} must be a valid route string.`;
13
+ }
14
+ }
@@ -0,0 +1,10 @@
1
+ import { Validate } from "class-validator";
2
+ import { IsMapOfStringsConstraint } from "../constraints/is-map-of-strings.constraint";
3
+
4
+ export function IsMapOfStrings() {
5
+ return function (object: Record<string, any>, propertyName: string): void {
6
+ Validate(IsMapOfStringsConstraint, {
7
+ message: `${propertyName} must be a map object with string values.`,
8
+ })(object, propertyName);
9
+ };
10
+ }
@@ -0,0 +1,8 @@
1
+ import { Validate } from 'class-validator';
2
+ import { IsRouteConstraint } from '../constraints/is-route.constraint';
3
+
4
+ export function IsRoute() {
5
+ return function (object: Record<string, any>, propertyName: string): void {
6
+ Validate(IsRouteConstraint, { message: `${propertyName} must be a valid route string.` })(object, propertyName);
7
+ };
8
+ }
@@ -0,0 +1,16 @@
1
+ import { HttpException, HttpStatus } from '@nestjs/common';
2
+ import { Response } from 'express';
3
+ import { RESTError, RESTResponseBody } from '../models/wrappers/rest-wrapper.class';
4
+
5
+ class HandledException extends HttpException {
6
+ constructor(private readonly _errors: RESTError[], private readonly _statusCode?: HttpStatus) {
7
+ super({ errors: _errors }, _statusCode || HttpStatus.BAD_REQUEST);
8
+ }
9
+
10
+ public send(response: Response) {
11
+ const responseBody = RESTResponseBody.fail(this._errors, this._statusCode || HttpStatus.BAD_REQUEST);
12
+ response.status(this._statusCode).json(responseBody);
13
+ }
14
+ }
15
+
16
+ export { HandledException };
@@ -0,0 +1,14 @@
1
+ import { HttpStatus } from '@nestjs/common';
2
+ import { ValidationError } from 'class-validator';
3
+ import { HandledException } from '../exceptions/custom.exception';
4
+ import { RESTError } from '../models/wrappers/rest-wrapper.class';
5
+
6
+ function validationExceptionFactory(_errors: ValidationError[]): HandledException {
7
+ const error = new RESTError('DATA_VALIDATION');
8
+ _errors.forEach((i: any) => {
9
+ error.validation = i;
10
+ });
11
+ return new HandledException([error], HttpStatus.UNPROCESSABLE_ENTITY);
12
+ }
13
+
14
+ export { validationExceptionFactory };
@@ -0,0 +1,192 @@
1
+ import { ArgumentsHost, ExceptionFilter, HttpStatus } from '@nestjs/common';
2
+ import { HandledException } from '../exceptions/custom.exception';
3
+ import { RESTError } from '../models/wrappers/rest-wrapper.class';
4
+
5
+ export class BaseExceptionsFilter implements ExceptionFilter {
6
+ private _debug: boolean = false;
7
+
8
+ constructor(debug: boolean) {
9
+ this._debug = debug;
10
+ }
11
+
12
+ catch(exception: any, host: ArgumentsHost) {
13
+ const context = host.switchToHttp();
14
+ const response = context.getResponse<Response>();
15
+
16
+ if (this._debug) {
17
+ console.log('BaseExceptionsFilter - name:', exception.constructor.name);
18
+ }
19
+
20
+ let handledException: HandledException | any = null;
21
+
22
+ try {
23
+ switch (exception.constructor.name) {
24
+ case 'HandledException':
25
+ handledException = exception;
26
+ break;
27
+ case 'RESTError':
28
+ handledException = new HandledException(exception, exception.statusCode || HttpStatus.BAD_REQUEST);
29
+ break;
30
+ case 'BadRequestException':
31
+ handledException = new HandledException(
32
+ [new RESTError('BadRequestException', exception.constructor.name)],
33
+ HttpStatus.INTERNAL_SERVER_ERROR,
34
+ );
35
+ break;
36
+ case 'UnauthorizedException':
37
+ handledException = new HandledException(
38
+ [new RESTError('UnauthorizedException', exception.constructor.name)],
39
+ HttpStatus.INTERNAL_SERVER_ERROR,
40
+ );
41
+ break;
42
+ case 'NotFoundException':
43
+ handledException = new HandledException(
44
+ [new RESTError('METHOD_NOT_FOUND', exception.message)],
45
+ HttpStatus.METHOD_NOT_ALLOWED,
46
+ );
47
+ break;
48
+ case 'ForbiddenException':
49
+ handledException = new HandledException(
50
+ [new RESTError('INVALID_API_TOKEN', 'invalid X-API-TOKEN received in headers')],
51
+ HttpStatus.FORBIDDEN,
52
+ );
53
+ break;
54
+ case 'NotAcceptableException':
55
+ handledException = new HandledException(
56
+ [new RESTError('NotAcceptableException', exception.constructor.name)],
57
+ HttpStatus.INTERNAL_SERVER_ERROR,
58
+ );
59
+ break;
60
+ case 'RequestTimeoutException':
61
+ handledException = new HandledException(
62
+ [new RESTError('RequestTimeoutException', exception.constructor.name)],
63
+ HttpStatus.INTERNAL_SERVER_ERROR,
64
+ );
65
+ break;
66
+ case 'ConflictException':
67
+ handledException = new HandledException(
68
+ [new RESTError('ConflictException', exception.constructor.name)],
69
+ HttpStatus.INTERNAL_SERVER_ERROR,
70
+ );
71
+ break;
72
+ case 'GoneException':
73
+ handledException = new HandledException(
74
+ [new RESTError('GoneException', exception.constructor.name)],
75
+ HttpStatus.INTERNAL_SERVER_ERROR,
76
+ );
77
+ break;
78
+ case 'HttpVersionNotSupportedException':
79
+ handledException = new HandledException(
80
+ [new RESTError('HttpVersionNotSupportedException', exception.constructor.name)],
81
+ HttpStatus.INTERNAL_SERVER_ERROR,
82
+ );
83
+ break;
84
+ case 'PayloadTooLargeException':
85
+ handledException = new HandledException(
86
+ [new RESTError('PayloadTooLargeException', exception.constructor.name)],
87
+ HttpStatus.PAYLOAD_TOO_LARGE,
88
+ );
89
+ break;
90
+ case 'UnsupportedMediaTypeException':
91
+ handledException = new HandledException(
92
+ [new RESTError('UnsupportedMediaTypeException', exception.constructor.name)],
93
+ HttpStatus.INTERNAL_SERVER_ERROR,
94
+ );
95
+ break;
96
+ case 'UnprocessableEntityException':
97
+ handledException = new HandledException(
98
+ [new RESTError('UnprocessableEntityException', exception.constructor.name)],
99
+ HttpStatus.INTERNAL_SERVER_ERROR,
100
+ );
101
+ break;
102
+ case 'InternalServerErrorException':
103
+ handledException = new HandledException(
104
+ [new RESTError('InternalServerErrorException', exception.constructor.name)],
105
+ HttpStatus.INTERNAL_SERVER_ERROR,
106
+ );
107
+ break;
108
+ case 'NotImplementedException':
109
+ handledException = new HandledException(
110
+ [new RESTError('NotImplementedException', exception.constructor.name)],
111
+ HttpStatus.NOT_IMPLEMENTED,
112
+ );
113
+ break;
114
+ case 'ImATeapotException':
115
+ handledException = new HandledException(
116
+ [new RESTError('ImATeapotException', exception.constructor.name)],
117
+ HttpStatus.INTERNAL_SERVER_ERROR,
118
+ );
119
+ break;
120
+ case 'MethodNotAllowedException':
121
+ handledException = new HandledException(
122
+ [new RESTError('MethodNotAllowedException', exception.constructor.name)],
123
+ HttpStatus.METHOD_NOT_ALLOWED,
124
+ );
125
+ break;
126
+ case 'BadGatewayException':
127
+ handledException = new HandledException(
128
+ [new RESTError('BadGatewayException', exception.constructor.name)],
129
+ HttpStatus.INTERNAL_SERVER_ERROR,
130
+ );
131
+ break;
132
+ case 'ServiceUnavailableException':
133
+ handledException = new HandledException(
134
+ [new RESTError('ServiceUnavailableException', exception.constructor.name)],
135
+ HttpStatus.INTERNAL_SERVER_ERROR,
136
+ );
137
+ break;
138
+ case 'GatewayTimeoutException':
139
+ handledException = new HandledException(
140
+ [new RESTError('GatewayTimeoutException', exception.constructor.name)],
141
+ HttpStatus.INTERNAL_SERVER_ERROR,
142
+ );
143
+ break;
144
+ case 'PreconditionFailedException':
145
+ handledException = new HandledException(
146
+ [new RESTError('PreconditionFailedException', exception.constructor.name)],
147
+ HttpStatus.INTERNAL_SERVER_ERROR,
148
+ );
149
+ break;
150
+ case 'TypeError':
151
+ handledException = new HandledException(
152
+ [new RESTError('TYPE_ERROR', exception.message)],
153
+ HttpStatus.INTERNAL_SERVER_ERROR,
154
+ );
155
+ break;
156
+ case 'MongoError':
157
+ handledException = new HandledException(
158
+ [new RESTError('MONGO_ERROR', exception.constructor.name)],
159
+ HttpStatus.INTERNAL_SERVER_ERROR,
160
+ );
161
+ break;
162
+ case 'CastError':
163
+ handledException = new HandledException(
164
+ [new RESTError('CAST_ERROR', exception.message)],
165
+ HttpStatus.INTERNAL_SERVER_ERROR,
166
+ );
167
+ break;
168
+ case 'ValidationError':
169
+ handledException = new HandledException(
170
+ [new RESTError('VALIDATION_ERROR', exception.message)],
171
+ HttpStatus.UNPROCESSABLE_ENTITY,
172
+ );
173
+ break;
174
+ case 'MongoServerError':
175
+ handledException = new HandledException(
176
+ [new RESTError('MONGO_SERVER_ERROR', exception.message)],
177
+ HttpStatus.INTERNAL_SERVER_ERROR,
178
+ );
179
+ break;
180
+ default:
181
+ handledException = new HandledException(
182
+ [new RESTError('UNKNOWN_EXCEPTION', exception.constructor.name)],
183
+ HttpStatus.INTERNAL_SERVER_ERROR,
184
+ );
185
+ }
186
+ } catch (ex) {
187
+ handledException = new HandledException([new RESTError('FILTER_EXCEPTION', ex)], HttpStatus.INTERNAL_SERVER_ERROR);
188
+ }
189
+
190
+ handledException.send(response);
191
+ }
192
+ }
@@ -0,0 +1,5 @@
1
+ export function escapeRegex(text: string) {
2
+ // Escape characters with special meaning either inside or outside character sets.
3
+ // Use a simple backslash escape when it’s always valid, and a `\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar.
4
+ return text.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d');
5
+ }
@@ -0,0 +1,7 @@
1
+ export function generateUUID(): string {
2
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
3
+ const r = (Math.random() * 16) | 0;
4
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
5
+ return v.toString(16);
6
+ });
7
+ }
@@ -0,0 +1,9 @@
1
+ export function sizeOfJson(object: any): number {
2
+ // Convert the object to a JSON string
3
+ const jsonString = JSON.stringify(object);
4
+
5
+ // Get the length of the JSON string in bytes
6
+ const bytes = new TextEncoder().encode(jsonString).length;
7
+
8
+ return bytes;
9
+ }
@@ -0,0 +1,6 @@
1
+ export function getRandomNumberFromRange(min: number, max: number){
2
+ if (min >= max) {
3
+ throw new Error("The minimum value must be less than the maximum value");
4
+ }
5
+ return Math.floor(Math.random() * (max - min + 1)) + min;
6
+ }
@@ -0,0 +1,42 @@
1
+ export function translitGeorgiaToLatin(georgianText: string) {
2
+ const georgianChars: { [key: string]: string } = {
3
+ ა: 'a',
4
+ ბ: 'b',
5
+ გ: 'g',
6
+ დ: 'd',
7
+ ე: 'e',
8
+ ვ: 'v',
9
+ ზ: 'z',
10
+ თ: 't',
11
+ ი: 'i',
12
+ კ: 'k',
13
+ ლ: 'l',
14
+ მ: 'm',
15
+ ნ: 'n',
16
+ ო: 'o',
17
+ პ: 'p',
18
+ ჟ: 'zh',
19
+ რ: 'r',
20
+ ს: 's',
21
+ ტ: 't',
22
+ უ: 'u',
23
+ ფ: 'p',
24
+ ქ: 'q',
25
+ ღ: 'gh',
26
+ ყ: 'q',
27
+ შ: 'sh',
28
+ ჩ: 'ch',
29
+ ც: 'ts',
30
+ ძ: 'dz',
31
+ წ: 'ts',
32
+ ჭ: 'ch',
33
+ ხ: 'kh',
34
+ ჯ: 'j',
35
+ ჰ: 'h',
36
+ };
37
+
38
+ return georgianText
39
+ .split('')
40
+ .map((char) => georgianChars[char] || char)
41
+ .join('');
42
+ }
package/src/index.ts ADDED
@@ -0,0 +1,96 @@
1
+ import { IsMapOfStringsConstraint } from './constraints/is-map-of-strings.constraint';
2
+ import { IsRouteConstraint } from './constraints/is-route.constraint';
3
+ import { IsMapOfStrings } from './decorators/is-map-of-strings.decorator';
4
+ import { IsRoute } from './decorators/is-route.decorator';
5
+ import { HandledException } from './exceptions/custom.exception';
6
+ import { validationExceptionFactory } from './factories/exception.factory';
7
+ import { BaseExceptionsFilter } from './filters/base-exception.filter';
8
+ import { RecordDTO } from './models/dtos/record.dto';
9
+ import { StateParamDTO } from './models/dtos/state-params.dto';
10
+ import { RecordState } from './models/enums/record-state.enum';
11
+ //import { IBase } from './models/interfaces/base.interface';
12
+ import { IRecord } from './models/interfaces/record.interface';
13
+ import {
14
+ RESTError,
15
+ RESTPage,
16
+ RESTPaging,
17
+ RESTRequestBody,
18
+ RESTResponseBody,
19
+ RESTResult,
20
+ RESTSort,
21
+ SortDirection,
22
+ } from './models/wrappers/rest-wrapper.class';
23
+ import { ConfigUtil } from './utils/config-util.class';
24
+ import { ISession } from './models/interfaces/session/session.interface';
25
+ import { ISessionUserData } from './models/interfaces/session/session-data.interface';
26
+ import { SessionClient } from './clients/session.client';
27
+ import { RedisService } from './modules/cache/services/redis.service';
28
+ import { SessionService } from './modules/cache/services/session.service';
29
+ import { CacheModule } from './modules/cache/cache.module';
30
+ import { PermissionGuard } from './modules/cache/guards/permission.guard';
31
+ import { generateUUID } from './functions/generate-uuid.function';
32
+ import { Permission } from './modules/cache/reflector/permission.reflector';
33
+ import { PermissionsIncludeStrategy } from './models/enums/permission-include-strategy.enum';
34
+ import { PermissionGuardConfig } from './models/wrappers/permission-guard-config.wrapper';
35
+ import { ClientPermissions } from './models/wrappers/client-permissions.wrapper';
36
+ import { Record } from './models/embedded/record.embedded';
37
+ import { ValidateMongoIdPipe } from './pipes/validate-mongo-id.pipe';
38
+ import { escapeRegex } from './functions/escape-regex.function';
39
+ import { translitGeorgiaToLatin } from './functions/transliterate-geo-to-latin';
40
+ import { getRandomNumberFromRange } from './functions/random-range.function';
41
+ import { sizeOfJson } from './functions/json-size.function';
42
+ import { HTTPMethod } from './models/enums/http-method.enum';
43
+ import { LogModule } from './modules/log/log.module';
44
+ import { LogService } from './modules/log/services/log.service';
45
+ import { LoggerClient } from './clients/logger.client';
46
+ //import { Stage } from './models/enums/stage.enum';
47
+ import { Env } from './models/enums/env.enum';
48
+ import { ConsoleLogger } from './utils/console-logger.class';
49
+ export {
50
+ IsMapOfStringsConstraint,
51
+ IsRouteConstraint,
52
+ IsMapOfStrings,
53
+ IsRoute,
54
+ HandledException,
55
+ validationExceptionFactory,
56
+ BaseExceptionsFilter,
57
+ RecordDTO,
58
+ StateParamDTO,
59
+ RecordState,
60
+ //IBase,
61
+ IRecord,
62
+ SortDirection,
63
+ RESTSort,
64
+ RESTPaging,
65
+ RESTRequestBody,
66
+ RESTPage,
67
+ RESTResult,
68
+ RESTError,
69
+ RESTResponseBody,
70
+ ConfigUtil,
71
+ ISession,
72
+ ISessionUserData,
73
+ SessionClient,
74
+ RedisService,
75
+ SessionService,
76
+ CacheModule,
77
+ PermissionGuard,
78
+ generateUUID,
79
+ Permission,
80
+ PermissionsIncludeStrategy,
81
+ PermissionGuardConfig,
82
+ ClientPermissions,
83
+ Record,
84
+ ValidateMongoIdPipe,
85
+ escapeRegex,
86
+ translitGeorgiaToLatin,
87
+ getRandomNumberFromRange,
88
+ sizeOfJson,
89
+ HTTPMethod,
90
+ LogModule,
91
+ LogService,
92
+ LoggerClient,
93
+ //Stage,
94
+ Env,
95
+ ConsoleLogger,
96
+ };
@@ -0,0 +1,12 @@
1
+ import { IsBoolean, IsEnum, IsOptional } from 'class-validator';
2
+ import { RecordState } from '../enums/record-state.enum';
3
+
4
+ export class RecordDTO {
5
+ @IsOptional()
6
+ @IsEnum(RecordState, { each: true })
7
+ public states: RecordState[];
8
+
9
+ @IsOptional()
10
+ @IsBoolean()
11
+ public deleted: boolean;
12
+ }