@adaptivestone/framework 5.0.0-beta.4 → 5.0.0-beta.41

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 (301) hide show
  1. package/CHANGELOG.md +1117 -528
  2. package/LICENCE +1 -1
  3. package/dist/Cli.d.ts +7 -0
  4. package/dist/Cli.js +19 -0
  5. package/dist/Cli.js.map +1 -0
  6. package/dist/cluster.d.ts +1 -0
  7. package/dist/cluster.js +18 -0
  8. package/dist/cluster.js.map +1 -0
  9. package/dist/commands/CreateUser.d.ts +32 -0
  10. package/dist/commands/CreateUser.js +83 -0
  11. package/dist/commands/CreateUser.js.map +1 -0
  12. package/dist/commands/Documentation.d.ts +5 -0
  13. package/dist/commands/Documentation.js +15 -0
  14. package/dist/commands/Documentation.js.map +1 -0
  15. package/dist/commands/DropIndex.d.ts +16 -0
  16. package/dist/commands/DropIndex.js +30 -0
  17. package/dist/commands/DropIndex.js.map +1 -0
  18. package/dist/commands/GenerateRandomBytes.d.ts +7 -0
  19. package/dist/commands/GenerateRandomBytes.js +18 -0
  20. package/dist/commands/GenerateRandomBytes.js.map +1 -0
  21. package/dist/commands/GenerateTypes.d.ts +11 -0
  22. package/dist/commands/GenerateTypes.js +52 -0
  23. package/dist/commands/GenerateTypes.js.map +1 -0
  24. package/dist/commands/GetOpenApiJson.d.ts +17 -0
  25. package/dist/commands/GetOpenApiJson.js +272 -0
  26. package/dist/commands/GetOpenApiJson.js.map +1 -0
  27. package/dist/commands/SyncIndexes.d.ts +6 -0
  28. package/dist/commands/SyncIndexes.js +31 -0
  29. package/dist/commands/SyncIndexes.js.map +1 -0
  30. package/dist/commands/migration/Create.d.ts +18 -0
  31. package/dist/commands/migration/Create.js +57 -0
  32. package/dist/commands/migration/Create.js.map +1 -0
  33. package/dist/commands/migration/Migrate.d.ts +6 -0
  34. package/dist/commands/migration/Migrate.js +43 -0
  35. package/dist/commands/migration/Migrate.js.map +1 -0
  36. package/dist/config/auth.d.ts +6 -0
  37. package/dist/config/auth.js +7 -0
  38. package/dist/config/auth.js.map +1 -0
  39. package/dist/config/http.d.ts +8 -0
  40. package/dist/config/http.js +10 -0
  41. package/dist/config/http.js.map +1 -0
  42. package/dist/config/i18n.d.ts +13 -0
  43. package/dist/config/i18n.js +13 -0
  44. package/dist/config/i18n.js.map +1 -0
  45. package/dist/config/ipDetector.d.ts +5 -0
  46. package/dist/config/ipDetector.js +15 -0
  47. package/dist/config/ipDetector.js.map +1 -0
  48. package/dist/config/log.d.ts +11 -0
  49. package/dist/config/log.js +20 -0
  50. package/dist/config/log.js.map +1 -0
  51. package/dist/config/mongo.d.ts +4 -0
  52. package/dist/config/mongo.js +4 -0
  53. package/dist/config/mongo.js.map +1 -0
  54. package/dist/config/rateLimiter.d.ts +13 -0
  55. package/dist/config/rateLimiter.js +17 -0
  56. package/dist/config/rateLimiter.js.map +1 -0
  57. package/dist/config/redis.d.ts +5 -0
  58. package/dist/config/redis.js +5 -0
  59. package/dist/config/redis.js.map +1 -0
  60. package/dist/config/validate.d.ts +4 -0
  61. package/dist/config/validate.js +4 -0
  62. package/dist/config/validate.js.map +1 -0
  63. package/dist/controllers/Auth.d.ts +131 -0
  64. package/dist/controllers/Auth.js +186 -0
  65. package/dist/controllers/Auth.js.map +1 -0
  66. package/dist/controllers/Home.d.ts +15 -0
  67. package/dist/controllers/Home.js +22 -0
  68. package/dist/controllers/Home.js.map +1 -0
  69. package/dist/controllers/index.d.ts +16 -0
  70. package/dist/controllers/index.js +59 -0
  71. package/dist/controllers/index.js.map +1 -0
  72. package/dist/folderConfig.d.ts +34 -0
  73. package/dist/folderConfig.js +14 -0
  74. package/dist/folderConfig.js.map +1 -0
  75. package/dist/helpers/appInstance.d.ts +3 -0
  76. package/dist/helpers/appInstance.js +8 -0
  77. package/dist/helpers/appInstance.js.map +1 -0
  78. package/dist/helpers/crypto.d.ts +3 -0
  79. package/dist/helpers/crypto.js +17 -0
  80. package/dist/helpers/crypto.js.map +1 -0
  81. package/dist/helpers/files.d.ts +16 -0
  82. package/dist/helpers/files.js +76 -0
  83. package/dist/helpers/files.js.map +1 -0
  84. package/dist/helpers/logger.d.ts +4 -0
  85. package/dist/helpers/logger.js +20 -0
  86. package/dist/helpers/logger.js.map +1 -0
  87. package/dist/helpers/redis/clearNamespace.d.ts +2 -0
  88. package/dist/helpers/redis/clearNamespace.js +14 -0
  89. package/dist/helpers/redis/clearNamespace.js.map +1 -0
  90. package/dist/helpers/redis/redisConnection.d.ts +6 -0
  91. package/dist/helpers/redis/redisConnection.js +48 -0
  92. package/dist/helpers/redis/redisConnection.js.map +1 -0
  93. package/dist/helpers/yup.d.ts +13 -0
  94. package/dist/helpers/yup.js +21 -0
  95. package/dist/helpers/yup.js.map +1 -0
  96. package/dist/index.d.ts +1 -0
  97. package/dist/index.js +7 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/models/Lock.d.ts +90 -0
  100. package/dist/models/Lock.js +97 -0
  101. package/dist/models/Lock.js.map +1 -0
  102. package/dist/models/Migration.d.ts +13 -0
  103. package/dist/models/Migration.js +14 -0
  104. package/dist/models/Migration.js.map +1 -0
  105. package/dist/models/Sequence.d.ts +28 -0
  106. package/dist/models/Sequence.js +19 -0
  107. package/dist/models/Sequence.js.map +1 -0
  108. package/dist/models/User.d.ts +656 -0
  109. package/dist/models/User.js +291 -0
  110. package/dist/models/User.js.map +1 -0
  111. package/dist/models/UserOld.d.ts +179 -0
  112. package/dist/models/UserOld.js +230 -0
  113. package/dist/models/UserOld.js.map +1 -0
  114. package/dist/modules/AbstractCommand.d.ts +51 -0
  115. package/dist/modules/AbstractCommand.js +60 -0
  116. package/dist/modules/AbstractCommand.js.map +1 -0
  117. package/dist/modules/AbstractConnector.d.ts +5 -0
  118. package/dist/modules/AbstractConnector.js +8 -0
  119. package/dist/modules/AbstractConnector.js.map +1 -0
  120. package/dist/modules/AbstractController.d.ts +95 -0
  121. package/dist/modules/AbstractController.js +323 -0
  122. package/dist/modules/AbstractController.js.map +1 -0
  123. package/dist/modules/AbstractModel.d.ts +29 -0
  124. package/dist/modules/AbstractModel.js +42 -0
  125. package/dist/modules/AbstractModel.js.map +1 -0
  126. package/dist/modules/Base.d.ts +29 -0
  127. package/dist/modules/Base.js +58 -0
  128. package/dist/modules/Base.js.map +1 -0
  129. package/dist/modules/BaseCli.d.ts +25 -0
  130. package/dist/modules/BaseCli.js +147 -0
  131. package/dist/modules/BaseCli.js.map +1 -0
  132. package/dist/modules/BaseModel.d.ts +55 -0
  133. package/dist/modules/BaseModel.js +37 -0
  134. package/dist/modules/BaseModel.js.map +1 -0
  135. package/dist/server.d.ts +123 -0
  136. package/dist/server.js +468 -0
  137. package/dist/server.js.map +1 -0
  138. package/dist/services/cache/Cache.d.ts +31 -0
  139. package/dist/services/cache/Cache.js +102 -0
  140. package/dist/services/cache/Cache.js.map +1 -0
  141. package/dist/services/documentation/DocumentationGenerator.d.ts +11 -0
  142. package/dist/services/documentation/DocumentationGenerator.js +130 -0
  143. package/dist/services/documentation/DocumentationGenerator.js.map +1 -0
  144. package/dist/services/http/HttpServer.d.ts +35 -0
  145. package/dist/services/http/HttpServer.js +70 -0
  146. package/dist/services/http/HttpServer.js.map +1 -0
  147. package/dist/services/http/middleware/AbstractMiddleware.d.ts +26 -0
  148. package/dist/services/http/middleware/AbstractMiddleware.js +41 -0
  149. package/dist/services/http/middleware/AbstractMiddleware.js.map +1 -0
  150. package/dist/services/http/middleware/Auth.d.ts +9 -0
  151. package/dist/services/http/middleware/Auth.js +18 -0
  152. package/dist/services/http/middleware/Auth.js.map +1 -0
  153. package/dist/services/http/middleware/Cors.d.ts +12 -0
  154. package/dist/services/http/middleware/Cors.js +36 -0
  155. package/dist/services/http/middleware/Cors.js.map +1 -0
  156. package/dist/services/http/middleware/GetUserByToken.d.ts +27 -0
  157. package/dist/services/http/middleware/GetUserByToken.js +47 -0
  158. package/dist/services/http/middleware/GetUserByToken.js.map +1 -0
  159. package/dist/services/http/middleware/I18n.d.ts +23 -0
  160. package/dist/services/http/middleware/I18n.js +61 -0
  161. package/dist/services/http/middleware/I18n.js.map +1 -0
  162. package/dist/services/http/middleware/IpDetector.d.ts +14 -0
  163. package/dist/services/http/middleware/IpDetector.js +55 -0
  164. package/dist/services/http/middleware/IpDetector.js.map +1 -0
  165. package/dist/services/http/middleware/Pagination.d.ts +27 -0
  166. package/dist/services/http/middleware/Pagination.js +46 -0
  167. package/dist/services/http/middleware/Pagination.js.map +1 -0
  168. package/dist/services/http/middleware/PrepareAppInfo.d.ts +8 -0
  169. package/dist/services/http/middleware/PrepareAppInfo.js +17 -0
  170. package/dist/services/http/middleware/PrepareAppInfo.js.map +1 -0
  171. package/dist/services/http/middleware/RateLimiter.d.ts +26 -0
  172. package/dist/services/http/middleware/RateLimiter.js +102 -0
  173. package/dist/services/http/middleware/RateLimiter.js.map +1 -0
  174. package/dist/services/http/middleware/RequestLogger.d.ts +8 -0
  175. package/dist/services/http/middleware/RequestLogger.js +18 -0
  176. package/dist/services/http/middleware/RequestLogger.js.map +1 -0
  177. package/dist/services/http/middleware/RequestParser.d.ts +8 -0
  178. package/dist/services/http/middleware/RequestParser.js +35 -0
  179. package/dist/services/http/middleware/RequestParser.js.map +1 -0
  180. package/dist/services/http/middleware/Role.d.ts +12 -0
  181. package/dist/services/http/middleware/Role.js +24 -0
  182. package/dist/services/http/middleware/Role.js.map +1 -0
  183. package/dist/services/i18n/I18n.d.ts +15 -0
  184. package/dist/services/i18n/I18n.js +58 -0
  185. package/dist/services/i18n/I18n.js.map +1 -0
  186. package/dist/services/logging/SentryTransport.d.ts +13 -0
  187. package/dist/services/logging/SentryTransport.js +121 -0
  188. package/dist/services/logging/SentryTransport.js.map +1 -0
  189. package/dist/services/validate/ValidateService.d.ts +31 -0
  190. package/dist/services/validate/ValidateService.js +95 -0
  191. package/dist/services/validate/ValidateService.js.map +1 -0
  192. package/dist/services/validate/drivers/AbstractValidator.d.ts +14 -0
  193. package/dist/services/validate/drivers/AbstractValidator.js +29 -0
  194. package/dist/services/validate/drivers/AbstractValidator.js.map +1 -0
  195. package/dist/services/validate/drivers/CustomValidator.d.ts +14 -0
  196. package/dist/services/validate/drivers/CustomValidator.js +48 -0
  197. package/dist/services/validate/drivers/CustomValidator.js.map +1 -0
  198. package/dist/services/validate/drivers/YupValidator.d.ts +13 -0
  199. package/dist/services/validate/drivers/YupValidator.js +86 -0
  200. package/dist/services/validate/drivers/YupValidator.js.map +1 -0
  201. package/dist/tests/frameworkVitestSetup.d.ts +1 -0
  202. package/dist/tests/frameworkVitestSetup.js +9 -0
  203. package/dist/tests/frameworkVitestSetup.js.map +1 -0
  204. package/dist/tests/globalSetupVitest.d.ts +3 -0
  205. package/dist/tests/globalSetupVitest.js +29 -0
  206. package/dist/tests/globalSetupVitest.js.map +1 -0
  207. package/dist/tests/setupVitest.d.ts +1 -0
  208. package/dist/tests/setupVitest.js +91 -0
  209. package/dist/tests/setupVitest.js.map +1 -0
  210. package/dist/tests/testHelpers.d.ts +340 -0
  211. package/dist/tests/testHelpers.js +48 -0
  212. package/dist/tests/testHelpers.js.map +1 -0
  213. package/package.json +53 -40
  214. package/Cli.js +0 -22
  215. package/cluster.js +0 -27
  216. package/commands/CreateUser.js +0 -75
  217. package/commands/Documentation.js +0 -17
  218. package/commands/DropIndex.js +0 -29
  219. package/commands/GenerateRandomBytes.js +0 -21
  220. package/commands/GetOpenApiJson.js +0 -325
  221. package/commands/SyncIndexes.js +0 -39
  222. package/commands/migration/Create.js +0 -61
  223. package/commands/migration/Migrate.js +0 -55
  224. package/config/auth.js +0 -9
  225. package/config/http.js +0 -9
  226. package/config/i18n.js +0 -12
  227. package/config/ipDetector.js +0 -14
  228. package/config/log.js +0 -22
  229. package/config/mail.js +0 -29
  230. package/config/mongo.js +0 -3
  231. package/config/rateLimiter.js +0 -16
  232. package/config/redis.js +0 -4
  233. package/config/validate.js +0 -3
  234. package/controllers/Auth.js +0 -210
  235. package/controllers/Home.js +0 -28
  236. package/controllers/index.js +0 -60
  237. package/folderConfig.js +0 -14
  238. package/helpers/files.js +0 -79
  239. package/helpers/logger.js +0 -17
  240. package/helpers/redis/clearNamespace.js +0 -14
  241. package/helpers/yup.js +0 -24
  242. package/index.js +0 -8
  243. package/jsconfig.json +0 -9
  244. package/locales/en/translation.json +0 -27
  245. package/locales/ru/translation.json +0 -27
  246. package/migrations/.gitkeep +0 -0
  247. package/models/Migration.js +0 -15
  248. package/models/Sequence.js +0 -22
  249. package/models/User.js +0 -263
  250. package/modules/AbstractCommand.js +0 -43
  251. package/modules/AbstractConnector.js +0 -9
  252. package/modules/AbstractController.js +0 -413
  253. package/modules/AbstractModel.d.ts +0 -48
  254. package/modules/AbstractModel.js +0 -92
  255. package/modules/Base.d.ts +0 -37
  256. package/modules/Base.js +0 -63
  257. package/modules/BaseCli.js +0 -97
  258. package/server.d.ts +0 -98
  259. package/server.js +0 -438
  260. package/services/cache/Cache.d.ts +0 -35
  261. package/services/cache/Cache.js +0 -124
  262. package/services/documentation/DocumentationGenerator.js +0 -169
  263. package/services/http/HttpServer.js +0 -96
  264. package/services/http/middleware/AbstractMiddleware.js +0 -51
  265. package/services/http/middleware/Auth.js +0 -20
  266. package/services/http/middleware/Cors.js +0 -46
  267. package/services/http/middleware/GetUserByToken.js +0 -47
  268. package/services/http/middleware/I18n.js +0 -117
  269. package/services/http/middleware/IpDetector.js +0 -59
  270. package/services/http/middleware/Pagination.js +0 -57
  271. package/services/http/middleware/PrepareAppInfo.js +0 -18
  272. package/services/http/middleware/RateLimiter.js +0 -134
  273. package/services/http/middleware/RequestLogger.js +0 -22
  274. package/services/http/middleware/RequestParser.js +0 -40
  275. package/services/http/middleware/Role.js +0 -29
  276. package/services/messaging/email/index.js +0 -217
  277. package/services/messaging/email/resources/.gitkeep +0 -1
  278. package/services/messaging/email/templates/emptyTemplate/html.pug +0 -9
  279. package/services/messaging/email/templates/emptyTemplate/subject.pug +0 -1
  280. package/services/messaging/email/templates/emptyTemplate/text.pug +0 -1
  281. package/services/messaging/email/templates/recovery/html.pug +0 -8
  282. package/services/messaging/email/templates/recovery/subject.pug +0 -2
  283. package/services/messaging/email/templates/recovery/text.pug +0 -3
  284. package/services/messaging/email/templates/verification/html.pug +0 -10
  285. package/services/messaging/email/templates/verification/subject.pug +0 -1
  286. package/services/messaging/email/templates/verification/text.pug +0 -1
  287. package/services/messaging/index.js +0 -3
  288. package/services/validate/ValidateService.js +0 -157
  289. package/services/validate/drivers/AbstractValidator.js +0 -37
  290. package/services/validate/drivers/CustomValidator.js +0 -51
  291. package/services/validate/drivers/YupValidator.js +0 -103
  292. package/tests/globalSetupVitest.js +0 -35
  293. package/tests/setup.js +0 -118
  294. package/tests/setupVitest.js +0 -109
  295. package/types/Expand.d.ts +0 -11
  296. package/types/TFoldersConfig.d.ts +0 -17
  297. package/views/404.pug +0 -3
  298. package/views/home.pug +0 -3
  299. package/views/layouts/base.pug +0 -39
  300. package/vitest.config.js +0 -16
  301. /package/{commands → dist/migrations}/.gitkeep +0 -0
@@ -0,0 +1,55 @@
1
+ import { BlockList } from 'node:net';
2
+ import AbstractMiddleware from "./AbstractMiddleware.js";
3
+ class IpDetector extends AbstractMiddleware {
4
+ static get description() {
5
+ return 'Detect real user IP address. Support proxy and load balancer';
6
+ }
7
+ blockList;
8
+ constructor(app, params) {
9
+ super(app, params);
10
+ const { trustedProxy } = this.app.getConfig('ipDetector');
11
+ this.blockList = new BlockList();
12
+ for (const subnet of trustedProxy) {
13
+ const addressType = subnet.includes(':') ? 'ipv6' : 'ipv4';
14
+ if (subnet.includes('/')) {
15
+ // CIDR
16
+ const [realSubnet, prefixLength] = subnet.split('/');
17
+ this.blockList.addSubnet(realSubnet, parseInt(prefixLength, 10), addressType);
18
+ }
19
+ else if (subnet.includes('-')) {
20
+ // RANGE
21
+ const [start, end] = subnet.split('-');
22
+ this.blockList.addRange(start, end, addressType);
23
+ }
24
+ else {
25
+ // just an address
26
+ this.blockList.addAddress(subnet, addressType);
27
+ }
28
+ }
29
+ }
30
+ getIpAdressFromIncomingMessage(req) {
31
+ const { headers } = this.app.getConfig('ipDetector');
32
+ const initialIp = req.socket.remoteAddress;
33
+ let ip = initialIp;
34
+ const addressType = initialIp?.includes(':') ? 'ipv6' : 'ipv4';
35
+ if (this.blockList.check(initialIp ?? '', addressType)) {
36
+ // we can trust this source
37
+ for (const header of headers) {
38
+ // in a range
39
+ const ipHeader = req.headers[header.toLowerCase()];
40
+ if (ipHeader) {
41
+ const [firstIp] = ipHeader.split(',').map((ip) => ip.trim());
42
+ ip = firstIp;
43
+ break;
44
+ }
45
+ }
46
+ }
47
+ return ip;
48
+ }
49
+ async middleware(req, _res, next) {
50
+ req.appInfo.ip = this.getIpAdressFromIncomingMessage(req);
51
+ next();
52
+ }
53
+ }
54
+ export default IpDetector;
55
+ //# sourceMappingURL=IpDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IpDetector.js","sourceRoot":"","sources":["../../../../src/services/http/middleware/IpDetector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { NextFunction, Response } from 'express';
2
+ import type { FrameworkRequest } from '../HttpServer.ts';
3
+ import AbstractMiddleware from './AbstractMiddleware.ts';
4
+ export interface PaginationMiddlewareAppInfo {
5
+ appInfo: {
6
+ pagination: {
7
+ page: number;
8
+ limit: number;
9
+ skip: number;
10
+ };
11
+ };
12
+ }
13
+ /**
14
+ * Middleware for reusing pagination
15
+ */
16
+ declare class Pagination extends AbstractMiddleware {
17
+ static get description(): string;
18
+ get relatedQueryParameters(): import("yup").ObjectSchema<{
19
+ page: number | undefined;
20
+ limit: number | undefined;
21
+ }, import("yup").AnyObject, {
22
+ page: undefined;
23
+ limit: undefined;
24
+ }, "">;
25
+ middleware(req: FrameworkRequest & PaginationMiddlewareAppInfo, _res: Response, next: NextFunction): Promise<void>;
26
+ }
27
+ export default Pagination;
@@ -0,0 +1,46 @@
1
+ import { number, object } from 'yup';
2
+ import AbstractMiddleware from "./AbstractMiddleware.js";
3
+ /**
4
+ * Middleware for reusing pagination
5
+ */
6
+ class Pagination extends AbstractMiddleware {
7
+ static get description() {
8
+ return 'Pagination middleware. You can use limit=10 and maxLimit=100 parameters';
9
+ }
10
+ get relatedQueryParameters() {
11
+ return object().shape({
12
+ page: number(),
13
+ limit: number(),
14
+ });
15
+ }
16
+ async middleware(req, _res, next) {
17
+ let { limit, maxLimit } = this.params;
18
+ limit = (typeof limit !== 'number' ? parseInt(limit, 10) : limit) || 10;
19
+ maxLimit =
20
+ (typeof maxLimit !== 'number' ? parseInt(maxLimit, 10) : maxLimit) || 100;
21
+ req.appInfo.pagination = {
22
+ page: typeof req?.query?.page === 'string'
23
+ ? parseInt(req?.query?.page, 10) || 1
24
+ : 1,
25
+ limit: typeof req?.query?.limit === 'string'
26
+ ? parseInt(req?.query?.limit, 10) || 0
27
+ : limit,
28
+ skip: 0,
29
+ };
30
+ if (req.appInfo.pagination.limit > maxLimit) {
31
+ req.appInfo.pagination.limit = maxLimit;
32
+ }
33
+ if (req.appInfo.pagination.page < 1) {
34
+ req.appInfo.pagination.page = 1;
35
+ }
36
+ if (req.appInfo.pagination.limit < 0) {
37
+ req.appInfo.pagination.limit = 0;
38
+ }
39
+ req.appInfo.pagination.skip =
40
+ req.appInfo.pagination.page * req.appInfo.pagination.limit -
41
+ req.appInfo.pagination.limit;
42
+ return next();
43
+ }
44
+ }
45
+ export default Pagination;
46
+ //# sourceMappingURL=Pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pagination.js","sourceRoot":"","sources":["../../../../src/services/http/middleware/Pagination.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAErC,OAAO,kBAAkB,MAAM,yBAAyB,CAAC;AAYzD;;GAEG;AACH,MAAM,UAAW,SAAQ,kBAAkB;IACzC,MAAM,KAAK,WAAW;QACpB,OAAO,yEAAyE,CAAC;IACnF,CAAC;IAED,IAAI,sBAAsB;QACxB,OAAO,MAAM,EAAE,CAAC,KAAK,CAAC;YACpB,IAAI,EAAE,MAAM,EAAE;YACd,KAAK,EAAE,MAAM,EAAE;SAChB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU,CACd,GAAmD,EACnD,IAAc,EACd,IAAkB;QAElB,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,MAG9B,CAAC;QAEF,KAAK,GAAG,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACxE,QAAQ;YACN,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC;QAE5E,GAAG,CAAC,OAAO,CAAC,UAAU,GAAG;YACvB,IAAI,EACF,OAAO,GAAG,EAAE,KAAK,EAAE,IAAI,KAAK,QAAQ;gBAClC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;gBACrC,CAAC,CAAC,CAAC;YAEP,KAAK,EACH,OAAO,GAAG,EAAE,KAAK,EAAE,KAAK,KAAK,QAAQ;gBACnC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC;gBACtC,CAAC,CAAC,KAAK;YACX,IAAI,EAAE,CAAC;SACR,CAAC;QAEF,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,GAAG,QAAQ,EAAE,CAAC;YAC5C,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,GAAG,QAAQ,CAAC;QAC1C,CAAC;QAED,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACpC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC;QAClC,CAAC;QAED,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YACrC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC;QACnC,CAAC;QAED,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI;YACzB,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK;gBAC1D,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC;QAE/B,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;CACF;AAED,eAAe,UAAU,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { NextFunction, Response } from 'express';
2
+ import type { FrameworkRequest } from '../HttpServer.ts';
3
+ import AbstractMiddleware from './AbstractMiddleware.ts';
4
+ declare class PrepareAppInfo extends AbstractMiddleware {
5
+ static get description(): string;
6
+ middleware(req: FrameworkRequest, _res: Response, next: NextFunction): Promise<void>;
7
+ }
8
+ export default PrepareAppInfo;
@@ -0,0 +1,17 @@
1
+ import AbstractMiddleware from "./AbstractMiddleware.js";
2
+ class PrepareAppInfo extends AbstractMiddleware {
3
+ static get description() {
4
+ return 'Basic middleware that creates "req.appInfo" object';
5
+ }
6
+ async middleware(req, _res, next) {
7
+ if (!req.appInfo) {
8
+ //@ts-expect-error extending
9
+ req.appInfo = {
10
+ app: this.app,
11
+ };
12
+ }
13
+ next();
14
+ }
15
+ }
16
+ export default PrepareAppInfo;
17
+ //# sourceMappingURL=PrepareAppInfo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PrepareAppInfo.js","sourceRoot":"","sources":["../../../../src/services/http/middleware/PrepareAppInfo.ts"],"names":[],"mappings":"AAEA,OAAO,kBAAkB,MAAM,yBAAyB,CAAC;AAEzD,MAAM,cAAe,SAAQ,kBAAkB;IAC7C,MAAM,KAAK,WAAW;QACpB,OAAO,oDAAoD,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAqB,EAAE,IAAc,EAAE,IAAkB;QACxE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACjB,4BAA4B;YAC5B,GAAG,CAAC,OAAO,GAAG;gBACZ,GAAG,EAAE,IAAI,CAAC,GAAG;aACd,CAAC;QACJ,CAAC;QACD,IAAI,EAAE,CAAC;IACT,CAAC;CACF;AAED,eAAe,cAAc,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { NextFunction, Response } from 'express';
2
+ import type { RateLimiterAbstract } from 'rate-limiter-flexible';
3
+ import { RateLimiterRedis } from 'rate-limiter-flexible';
4
+ import type rateLimiterConfig from '../../../config/rateLimiter.js';
5
+ import type { IApp } from '../../../server.ts';
6
+ import type { FrameworkRequest } from '../HttpServer.ts';
7
+ import AbstractMiddleware from './AbstractMiddleware.ts';
8
+ import type { GetUserByTokenAppInfo } from './GetUserByToken.ts';
9
+ declare class RateLimiter extends AbstractMiddleware {
10
+ static get description(): string;
11
+ finalOptions: typeof rateLimiterConfig;
12
+ limiter: RateLimiterAbstract;
13
+ constructor(app: IApp, params?: Record<string, unknown>);
14
+ initRedisLimiter(): RateLimiterRedis;
15
+ gerenateConsumeKey(req: FrameworkRequest & GetUserByTokenAppInfo): string;
16
+ consumeResult(consumeKey: string, consumePoints?: number): Promise<{
17
+ msBeforeNext: number;
18
+ remainingPoints: number;
19
+ consumedPoints: number;
20
+ isFirstInDuration: boolean;
21
+ isAllowed: boolean;
22
+ retryAfter: number;
23
+ }>;
24
+ middleware(req: FrameworkRequest, res: Response, next: NextFunction): Promise<void | Response<any, Record<string, any>>>;
25
+ }
26
+ export default RateLimiter;
@@ -0,0 +1,102 @@
1
+ import merge from 'deepmerge';
2
+ import mongoose from 'mongoose';
3
+ import { RateLimiterMemory, RateLimiterMongo, RateLimiterRedis, } from 'rate-limiter-flexible';
4
+ import { getRedisClientSync } from "../../../helpers/redis/redisConnection.js";
5
+ import AbstractMiddleware from "./AbstractMiddleware.js";
6
+ class RateLimiter extends AbstractMiddleware {
7
+ static get description() {
8
+ return 'Rate limiter middleware. Limit amount of request. Please refer to documentation';
9
+ }
10
+ finalOptions;
11
+ limiter;
12
+ constructor(app, params) {
13
+ super(app, params);
14
+ const limiterOptions = this.app.getConfig('rateLimiter');
15
+ this.finalOptions = merge(limiterOptions, params || {});
16
+ switch (this.finalOptions.driver) {
17
+ case 'memory':
18
+ this.limiter = new RateLimiterMemory(this.finalOptions.limiterOptions);
19
+ break;
20
+ case 'redis':
21
+ this.limiter = this.initRedisLimiter();
22
+ break;
23
+ case 'mongo':
24
+ this.limiter = new RateLimiterMongo({
25
+ storeClient: mongoose.connection,
26
+ disableIndexesCreation: process.env.TEST === 'true', // disable in test env, but we can still overrite it later
27
+ ...this.finalOptions.limiterOptions,
28
+ });
29
+ break;
30
+ default:
31
+ this.logger?.error(`Unknwon option for driver ${this.finalOptions.driver}`);
32
+ break;
33
+ }
34
+ }
35
+ initRedisLimiter() {
36
+ const redisClient = getRedisClientSync();
37
+ return new RateLimiterRedis({
38
+ storeClient: redisClient,
39
+ useRedisPackage: true,
40
+ ...this.finalOptions.limiterOptions,
41
+ });
42
+ }
43
+ gerenateConsumeKey(req) {
44
+ const { ip, route, user, request } = this.finalOptions.consumeKeyComponents;
45
+ const key = [];
46
+ if (ip) {
47
+ if (!req.appInfo.ip) {
48
+ this.logger?.error(`RateLimiter: Can't get remote address from request. Please check that you used IpDetecor middleware before RateLimiter`);
49
+ }
50
+ else {
51
+ key.push(req.appInfo.ip);
52
+ }
53
+ }
54
+ if (route) {
55
+ key.push(`${req.baseUrl ?? ''}${req.path ?? ''}`); // to avoid quesry params
56
+ }
57
+ if (user && req.appInfo?.user) {
58
+ key.push(req.appInfo?.user.id);
59
+ }
60
+ if (request?.length) {
61
+ request.forEach((val) => {
62
+ if (req?.body[val]) {
63
+ key.push(req.body[val]);
64
+ }
65
+ // if (req.appInfo.request && req.appInfo.request[val]) {
66
+ // key.push(req.appInfo.request[val]);
67
+ // }
68
+ });
69
+ }
70
+ return key.join('_');
71
+ }
72
+ async consumeResult(consumeKey, consumePoints = 0) {
73
+ try {
74
+ const result = await this.limiter.consume(consumeKey, consumePoints || this.finalOptions.consumePoints);
75
+ return { isAllowed: true, retryAfter: 0, ...result };
76
+ }
77
+ catch (e) {
78
+ this.logger?.warn(`Too many requests. Consume key: ${consumeKey}`);
79
+ const result = e;
80
+ const retryAfter = Math.round(result.msBeforeNext / 1000) || 1;
81
+ return { isAllowed: false, retryAfter, ...result };
82
+ }
83
+ }
84
+ async middleware(req, res, next) {
85
+ if (!this.limiter) {
86
+ this.logger?.info(`RateLimiter not inited correclty! Please check init logs `);
87
+ return res.status(500).json({ message: 'RateLimiter error' });
88
+ }
89
+ const { namespace } = this.app.getConfig('redis');
90
+ const consumeKey = `${namespace}-${this.gerenateConsumeKey(req)}`;
91
+ const consumeResult = await this.consumeResult(consumeKey);
92
+ if (consumeResult.isAllowed) {
93
+ return next();
94
+ }
95
+ return res
96
+ .status(429)
97
+ .setHeader('Retry-After', String(consumeResult.retryAfter))
98
+ .json({ message: 'Too Many Requests' });
99
+ }
100
+ }
101
+ export default RateLimiter;
102
+ //# sourceMappingURL=RateLimiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../../../src/services/http/middleware/RateLimiter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { NextFunction, Response } from 'express';
2
+ import type { FrameworkRequest } from '../HttpServer.ts';
3
+ import AbstractMiddleware from './AbstractMiddleware.ts';
4
+ declare class RequestLogger extends AbstractMiddleware {
5
+ static get description(): string;
6
+ middleware(req: FrameworkRequest, res: Response, next: NextFunction): Promise<void>;
7
+ }
8
+ export default RequestLogger;
@@ -0,0 +1,18 @@
1
+ import AbstractMiddleware from "./AbstractMiddleware.js";
2
+ class RequestLogger extends AbstractMiddleware {
3
+ static get description() {
4
+ return 'Log info about the request';
5
+ }
6
+ async middleware(req, res, next) {
7
+ const startTime = performance.now();
8
+ const text = `Request is [${req.method}] ${req.url}`;
9
+ this.logger?.info(text);
10
+ res.on('finish', () => {
11
+ const end = performance.now();
12
+ this.logger?.info(`Finished ${text}. Status: ${res.statusCode}. [${(end - startTime).toFixed(2)} ms]`);
13
+ });
14
+ next();
15
+ }
16
+ }
17
+ export default RequestLogger;
18
+ //# sourceMappingURL=RequestLogger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequestLogger.js","sourceRoot":"","sources":["../../../../src/services/http/middleware/RequestLogger.ts"],"names":[],"mappings":"AAEA,OAAO,kBAAkB,MAAM,yBAAyB,CAAC;AAEzD,MAAM,aAAc,SAAQ,kBAAkB;IAC5C,MAAM,KAAK,WAAW;QACpB,OAAO,4BAA4B,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAqB,EAAE,GAAa,EAAE,IAAkB;QACvE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,gBAAgB,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,CAAC;QACtD,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACpB,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,EAAE,IAAI,CACf,YAAY,IAAI,aAAa,GAAG,CAAC,UAAU,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CACrF,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,IAAI,EAAE,CAAC;IACT,CAAC;CACF;AAED,eAAe,aAAa,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { NextFunction, Response } from 'express';
2
+ import type { FrameworkRequest } from '../HttpServer.ts';
3
+ import AbstractMiddleware from './AbstractMiddleware.ts';
4
+ declare class RequestParser extends AbstractMiddleware {
5
+ static get description(): string;
6
+ middleware(req: FrameworkRequest, res: Response, next: NextFunction): Promise<void | Response<any, Record<string, any>>>;
7
+ }
8
+ export default RequestParser;
@@ -0,0 +1,35 @@
1
+ import formidable from 'formidable';
2
+ import AbstractMiddleware from "./AbstractMiddleware.js";
3
+ class RequestParser extends AbstractMiddleware {
4
+ static get description() {
5
+ return 'Parses incoming request. Based on Formidable library';
6
+ }
7
+ async middleware(req, res, next) {
8
+ const time = Date.now();
9
+ this.logger?.verbose(`Parsing request`);
10
+ // TODO update this to https://github.com/node-formidable/formidable/issues/412#issuecomment-1367914268 in node v20 (in 2023?)
11
+ const form = formidable(this.params); // not in construstor as reuse formidable affects performance
12
+ let fields;
13
+ let files;
14
+ try {
15
+ [fields, files] = await form.parse(req);
16
+ }
17
+ catch (err) {
18
+ this.logger?.error(`Parsing failed ${err}`);
19
+ return res.status(400).json({
20
+ message: `Error to parse your request. You provided invalid content type or content-length. Please check your request headers and content type.`,
21
+ });
22
+ // return next(err);
23
+ }
24
+ this.logger?.verbose(`Parsing multipart/formdata request DONE ${Date.now() - time}ms`);
25
+ req.body = {
26
+ // todo avoid body in next versions
27
+ ...(req.body || {}),
28
+ ...fields,
29
+ ...files,
30
+ };
31
+ return next();
32
+ }
33
+ }
34
+ export default RequestParser;
35
+ //# sourceMappingURL=RequestParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequestParser.js","sourceRoot":"","sources":["../../../../src/services/http/middleware/RequestParser.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,OAAO,kBAAkB,MAAM,yBAAyB,CAAC;AAEzD,MAAM,aAAc,SAAQ,kBAAkB;IAC5C,MAAM,KAAK,WAAW;QACpB,OAAO,sDAAsD,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAqB,EAAE,GAAa,EAAE,IAAkB;QACvE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACxC,8HAA8H;QAE9H,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,6DAA6D;QACnG,IAAI,MAAiC,CAAC;QACtC,IAAI,KAA+B,CAAC;QACpC,IAAI,CAAC;YACH,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC;YAC5C,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC1B,OAAO,EAAE,uIAAuI;aACjJ,CAAC,CAAC;YACH,oBAAoB;QACtB,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,OAAO,CAClB,2CAA2C,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CACjE,CAAC;QAEF,GAAG,CAAC,IAAI,GAAG;YACT,mCAAmC;YACnC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;YACnB,GAAG,MAAM;YACT,GAAG,KAAK;SACT,CAAC;QACF,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;CACF;AAED,eAAe,aAAa,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { NextFunction, Response } from 'express';
2
+ import type { TUser } from '../../../models/User.ts';
3
+ import type { FrameworkRequest } from '../HttpServer.ts';
4
+ import AbstractMiddleware from './AbstractMiddleware.ts';
5
+ import type { GetUserByTokenAppInfo } from './GetUserByToken.ts';
6
+ declare class RoleMiddleware extends AbstractMiddleware {
7
+ static get description(): string;
8
+ middleware(req: FrameworkRequest & GetUserByTokenAppInfo & {
9
+ user: InstanceType<TUser>;
10
+ }, res: Response, next: NextFunction): Promise<void | Response<any, Record<string, any>>>;
11
+ }
12
+ export default RoleMiddleware;
@@ -0,0 +1,24 @@
1
+ import AbstractMiddleware from "./AbstractMiddleware.js";
2
+ class RoleMiddleware extends AbstractMiddleware {
3
+ static get description() {
4
+ return 'Check user role (user.roles property). If the user has no role then stop request and return error. OR logic (any role will pass user)';
5
+ }
6
+ async middleware(req, res, next) {
7
+ const { user } = req.appInfo;
8
+ if (!user) {
9
+ return res.status(401).json({ message: 'User should be provided' });
10
+ }
11
+ let hasRole = false;
12
+ user.roles?.forEach((role) => {
13
+ if ((this.params?.roles).includes(role)) {
14
+ hasRole = true;
15
+ }
16
+ });
17
+ if (!hasRole) {
18
+ return res.status(403).json({ message: 'You do not have access' });
19
+ }
20
+ return next();
21
+ }
22
+ }
23
+ export default RoleMiddleware;
24
+ //# sourceMappingURL=Role.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Role.js","sourceRoot":"","sources":["../../../../src/services/http/middleware/Role.ts"],"names":[],"mappings":"AAGA,OAAO,kBAAkB,MAAM,yBAAyB,CAAC;AAGzD,MAAM,cAAe,SAAQ,kBAAkB;IAC7C,MAAM,KAAK,WAAW;QACpB,OAAO,uIAAuI,CAAC;IACjJ,CAAC;IAED,KAAK,CAAC,UAAU,CACd,GACuD,EACvD,GAAa,EACb,IAAkB;QAElB,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC;QAE7B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,IAAY,EAAE,EAAE;YACnC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAuB,CAAA,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzD,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;CACF;AAED,eAAe,cAAc,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { i18n, TFunction } from 'i18next';
2
+ import Base from '../../modules/Base.ts';
3
+ export type TI18n = {
4
+ t: TFunction;
5
+ language: string;
6
+ };
7
+ export declare class I18n extends Base {
8
+ #private;
9
+ getI18nForLang(lang?: string): Promise<{
10
+ t: TFunction;
11
+ language: string;
12
+ }>;
13
+ getI18nBaseInstance(): Promise<i18n>;
14
+ static get loggerGroup(): string;
15
+ }
@@ -0,0 +1,58 @@
1
+ import Base from "../../modules/Base.js";
2
+ export class I18n extends Base {
3
+ #cache = {};
4
+ #i18nBase;
5
+ #i18nBasePromise;
6
+ #i18nFallback = {
7
+ t: ((text) => text),
8
+ language: 'en',
9
+ };
10
+ async getI18nForLang(lang) {
11
+ const i18NConfig = this.app.getConfig('i18n');
12
+ if (!i18NConfig.enabled) {
13
+ return this.#i18nFallback;
14
+ }
15
+ if (!lang || i18NConfig.supportedLngs.indexOf(lang) === -1) {
16
+ this.logger?.verbose(`Language "${lang}" is not supported or not provided. Using fallback on ${i18NConfig.fallbackLng}`);
17
+ lang = i18NConfig.fallbackLng;
18
+ }
19
+ if (!this.#cache[lang]) {
20
+ this.#cache[lang] = (await this.getI18nBaseInstance()).cloneInstance({
21
+ initAsync: false,
22
+ lng: lang,
23
+ });
24
+ }
25
+ return this.#cache[lang];
26
+ }
27
+ async getI18nBaseInstance() {
28
+ if (this.#i18nBase) {
29
+ return this.#i18nBase;
30
+ }
31
+ if (!this.#i18nBasePromise) {
32
+ this.#i18nBasePromise = (async () => {
33
+ const [{ default: i18next }, { default: BackendFS }] = await Promise.all([
34
+ import('i18next'), // Speed optimisation
35
+ import('i18next-fs-backend'), // Speed optimisation
36
+ ]);
37
+ const i18NConfig = this.app.getConfig('i18n');
38
+ await i18next.use(BackendFS).init({
39
+ backend: {
40
+ loadPath: `${this.app.foldersConfig.locales}/{{lng}}/{{ns}}.json`,
41
+ addPath: `${this.app.foldersConfig.locales}/{{lng}}/{{ns}}.missing.json`,
42
+ },
43
+ fallbackLng: i18NConfig.fallbackLng,
44
+ preload: i18NConfig.preload,
45
+ saveMissing: i18NConfig.saveMissing,
46
+ debug: i18NConfig.debug,
47
+ });
48
+ this.#i18nBase = i18next;
49
+ return this.#i18nBase;
50
+ })();
51
+ }
52
+ return this.#i18nBasePromise;
53
+ }
54
+ static get loggerGroup() {
55
+ return 'I18n_';
56
+ }
57
+ }
58
+ //# sourceMappingURL=I18n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"I18n.js","sourceRoot":"","sources":["../../../src/services/i18n/I18n.ts"],"names":[],"mappings":"AAEA,OAAO,IAAI,MAAM,uBAAuB,CAAC;AAIzC,MAAM,OAAO,IAAK,SAAQ,IAAI;IAC5B,MAAM,GAA4B,EAAE,CAAC;IAErC,SAAS,CAAQ;IACjB,gBAAgB,CAAiB;IAEjC,aAAa,GAAuC;QAClD,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAc;QAChC,QAAQ,EAAE,IAAI;KACf,CAAC;IAEF,KAAK,CAAC,cAAc,CAAC,IAAa;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAsB,CAAC;QACnE,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,aAAa,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC,IAAI,IAAI,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC3D,IAAI,CAAC,MAAM,EAAE,OAAO,CAClB,aAAa,IAAI,yDAAyD,UAAU,CAAC,WAAW,EAAE,CACnG,CAAC;YACF,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC,aAAa,CAAC;gBACnE,SAAS,EAAE,KAAK;gBAChB,GAAG,EAAE,IAAI;aACV,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,mBAAmB;QACvB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC,SAAS,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC3B,IAAI,CAAC,gBAAgB,GAAG,CAAC,KAAK,IAAI,EAAE;gBAClC,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,GAClD,MAAM,OAAO,CAAC,GAAG,CAAC;oBAChB,MAAM,CAAC,SAAS,CAAC,EAAE,qBAAqB;oBACxC,MAAM,CAAC,oBAAoB,CAAC,EAAE,qBAAqB;iBACpD,CAAC,CAAC;gBACL,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAsB,CAAC;gBAEnE,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;oBAChC,OAAO,EAAE;wBACP,QAAQ,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,sBAAsB;wBACjE,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,8BAA8B;qBACzE;oBACD,WAAW,EAAE,UAAU,CAAC,WAAW;oBACnC,OAAO,EAAE,UAAU,CAAC,OAAO;oBAC3B,WAAW,EAAE,UAAU,CAAC,WAAW;oBACnC,KAAK,EAAE,UAAU,CAAC,KAAK;iBACxB,CAAC,CAAC;gBACH,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC;gBACzB,OAAO,IAAI,CAAC,SAAS,CAAC;YACxB,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;QACD,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAED,MAAM,KAAK,WAAW;QACpB,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import Transport from 'winston-transport';
2
+ /**
3
+ * Winston transport wrapper for Sentry that conditionally loads @sentry/node
4
+ * Assumes Sentry is already initialized in the consuming application
5
+ * Only loads the Winston transport if @sentry/node is installed
6
+ */
7
+ declare class SentryTransport extends Transport {
8
+ #private;
9
+ constructor(opts?: Transport.TransportStreamOptions);
10
+ private loadSentryTransport;
11
+ log(info: unknown, callback: () => void): void;
12
+ }
13
+ export default SentryTransport;