@koalarx/nest 1.19.0 → 3.0.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 (311) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/package.json +5 -37
  3. package/src/core/backgroud-services/cron-service/cron-job.handler.base.ts +66 -0
  4. package/src/core/backgroud-services/cron-service/cron-job.handler.spec.ts +38 -0
  5. package/src/core/backgroud-services/event-service/event-class.ts +5 -0
  6. package/src/core/backgroud-services/event-service/event-handler.base.ts +17 -0
  7. package/src/core/backgroud-services/event-service/event-is-trigger.ts +3 -0
  8. package/src/core/backgroud-services/event-service/event-job.ts +28 -0
  9. package/src/core/backgroud-services/event-service/event-queue.spec.ts +47 -0
  10. package/src/core/backgroud-services/event-service/event-queue.ts +107 -0
  11. package/src/core/constants/query-params.ts +7 -0
  12. package/src/core/controllers/base.controller.ts +9 -0
  13. package/src/core/controllers/controller.decorator.ts +10 -0
  14. package/src/core/controllers/created-registre-response.base.ts +17 -0
  15. package/src/core/controllers/list-response.base.ts +8 -0
  16. package/src/core/controllers/pagination.request.ts +41 -0
  17. package/src/core/controllers/router-config.base.ts +14 -0
  18. package/src/core/controllers/schemas/boolean.schema.ts +10 -0
  19. package/src/core/controllers/schemas/document-number.schema.ts +23 -0
  20. package/src/core/controllers/schemas/email.schema.ts +13 -0
  21. package/src/core/controllers/schemas/list-query.schema.ts +17 -0
  22. package/src/core/controllers/schemas/native-enum.schema.ts +34 -0
  23. package/src/core/controllers/schemas/set-mask-document-number.schema.ts +13 -0
  24. package/src/core/database/entity.base.ts +95 -0
  25. package/src/core/database/entity.decorator.spec.ts +71 -0
  26. package/src/core/database/entity.decorator.ts +39 -0
  27. package/src/core/database/prisma-client-with-custom-transaction.interface.ts +13 -0
  28. package/src/core/database/prisma-resolver.ts +99 -0
  29. package/src/core/database/prisma-transactional-client.ts +43 -0
  30. package/src/core/database/prisma.service.ts +136 -0
  31. package/src/core/database/repository.base.ts +548 -0
  32. package/src/core/dtos/pagination.dto.ts +35 -0
  33. package/src/core/errors/bad-request.error.ts +8 -0
  34. package/src/core/errors/conflict.error.ts +7 -0
  35. package/src/core/errors/error.base.ts +5 -0
  36. package/src/core/errors/no-content.error.ts +8 -0
  37. package/src/core/errors/not-allowed.error.ts +8 -0
  38. package/src/core/errors/resource-not-found.error.ts +8 -0
  39. package/{core/errors/use-case-error.d.ts → src/core/errors/use-case-error.ts} +1 -1
  40. package/src/core/errors/user-already-exist.error.ts +7 -0
  41. package/src/core/errors/wrong-credentials.error.ts +7 -0
  42. package/src/core/health-check/health-check.controller.ts +13 -0
  43. package/src/core/health-check/health-check.module.ts +7 -0
  44. package/src/core/index.ts +56 -0
  45. package/src/core/koala-app.ts +379 -0
  46. package/src/core/koala-global-vars.ts +8 -0
  47. package/src/core/koala-nest-database.module.ts +65 -0
  48. package/src/core/koala-nest-http.module.ts +44 -0
  49. package/src/core/koala-nest.module.ts +67 -0
  50. package/src/core/mapping/auto-mapping-class-context.ts +28 -0
  51. package/src/core/mapping/auto-mapping-context.ts +26 -0
  52. package/src/core/mapping/auto-mapping-list.ts +154 -0
  53. package/src/core/mapping/auto-mapping-profile.ts +3 -0
  54. package/src/core/mapping/auto-mapping.decorator.ts +54 -0
  55. package/src/core/mapping/auto-mapping.module.ts +17 -0
  56. package/src/core/mapping/auto-mapping.service.ts +187 -0
  57. package/src/core/mapping/create-map.ts +11 -0
  58. package/src/core/mapping/for-member.ts +16 -0
  59. package/src/core/request-overflow/request-handler.base.ts +8 -0
  60. package/src/core/request-overflow/request-result.spec.ts +23 -0
  61. package/src/core/request-overflow/request-result.ts +41 -0
  62. package/src/core/request-overflow/request-validator.base.ts +33 -0
  63. package/src/core/security/strategies/api-key.strategy.ts +45 -0
  64. package/src/core/utils/assing-object.ts +9 -0
  65. package/src/core/utils/env.config.ts +17 -0
  66. package/src/core/utils/filter-request-params.ts +23 -0
  67. package/src/core/utils/find-on-list.ts +18 -0
  68. package/src/core/utils/get-type-by-prop.ts +9 -0
  69. package/src/core/utils/instanciate-class-with-dependencies-injection.ts +12 -0
  70. package/src/core/utils/interfaces/icomparable.ts +6 -0
  71. package/src/core/utils/list.spec.ts +81 -0
  72. package/src/core/utils/list.ts +223 -0
  73. package/src/core/utils/promise-all.ts +24 -0
  74. package/src/core/utils/set-mask-document-number.ts +13 -0
  75. package/src/core/validators/file-validator.ts +113 -0
  76. package/src/decorators/api-exclude-endpoint-diff-develop.decorator.ts +15 -0
  77. package/src/decorators/api-property-enum.decorator.ts +58 -0
  78. package/src/decorators/api-property-only-develop.decorator.ts +6 -0
  79. package/src/decorators/cookies.decorator.ts +8 -0
  80. package/src/decorators/is-public.decorator.ts +5 -0
  81. package/src/decorators/upload.decorator.ts +31 -0
  82. package/src/env/env.module.ts +8 -0
  83. package/src/env/env.service.ts +12 -0
  84. package/src/env/env.ts +14 -0
  85. package/src/filters/domain-errors.filter.ts +97 -0
  86. package/src/filters/global-exception.filter.ts +60 -0
  87. package/src/filters/prisma-validation-exception.filter.ts +73 -0
  88. package/src/filters/zod-errors.filter.ts +48 -0
  89. package/src/services/logging/ilogging.service.ts +17 -0
  90. package/src/services/logging/logging.service.ts +10 -0
  91. package/src/services/redis/iredis.service.ts +11 -0
  92. package/src/services/redis/redis.service.ts +70 -0
  93. package/src/services/redlock/ired-lock.service.ts +4 -0
  94. package/src/services/redlock/red-lock.service.ts +36 -0
  95. package/src/test/koala-app-test-dependencies.ts +15 -0
  96. package/src/test/koala-app-test.ts +103 -0
  97. package/src/test/repositories/in-memory-base.repository.ts +90 -0
  98. package/src/test/services/fake-logging.service.ts +7 -0
  99. package/src/test/services/fake-red-lock.service.ts +11 -0
  100. package/src/test/utils/create-e2e-database.ts +55 -0
  101. package/src/test/utils/drop-e2e-database.ts +36 -0
  102. package/src/test/utils/wait-for.ts +31 -0
  103. package/tsconfig.lib.json +11 -0
  104. package/LICENSE +0 -21
  105. package/README.md +0 -499
  106. package/core/backgroud-services/cron-service/cron-job.handler.base.d.ts +0 -16
  107. package/core/backgroud-services/cron-service/cron-job.handler.base.js +0 -49
  108. package/core/backgroud-services/event-service/event-class.d.ts +0 -5
  109. package/core/backgroud-services/event-service/event-class.js +0 -11
  110. package/core/backgroud-services/event-service/event-handler.base.d.ts +0 -8
  111. package/core/backgroud-services/event-service/event-handler.base.js +0 -14
  112. package/core/backgroud-services/event-service/event-is-trigger.d.ts +0 -3
  113. package/core/backgroud-services/event-service/event-is-trigger.js +0 -7
  114. package/core/backgroud-services/event-service/event-job.d.ts +0 -13
  115. package/core/backgroud-services/event-service/event-job.js +0 -21
  116. package/core/backgroud-services/event-service/event-queue.d.ts +0 -17
  117. package/core/backgroud-services/event-service/event-queue.js +0 -62
  118. package/core/constants/query-params.d.ts +0 -6
  119. package/core/constants/query-params.js +0 -8
  120. package/core/controllers/base.controller.d.ts +0 -4
  121. package/core/controllers/base.controller.js +0 -6
  122. package/core/controllers/controller.decorator.d.ts +0 -2
  123. package/core/controllers/controller.decorator.js +0 -11
  124. package/core/controllers/created-registre-response.base.d.ts +0 -10
  125. package/core/controllers/created-registre-response.base.js +0 -35
  126. package/core/controllers/list-response.base.d.ts +0 -4
  127. package/core/controllers/list-response.base.js +0 -21
  128. package/core/controllers/pagination.request.d.ts +0 -10
  129. package/core/controllers/pagination.request.js +0 -56
  130. package/core/controllers/router-config.base.d.ts +0 -7
  131. package/core/controllers/router-config.base.js +0 -18
  132. package/core/controllers/schemas/boolean.schema.d.ts +0 -2
  133. package/core/controllers/schemas/boolean.schema.js +0 -12
  134. package/core/controllers/schemas/document-number.schema.d.ts +0 -1
  135. package/core/controllers/schemas/document-number.schema.js +0 -26
  136. package/core/controllers/schemas/email.schema.d.ts +0 -1
  137. package/core/controllers/schemas/email.schema.js +0 -13
  138. package/core/controllers/schemas/list-query.schema.d.ts +0 -17
  139. package/core/controllers/schemas/list-query.schema.js +0 -19
  140. package/core/controllers/schemas/native-enum.schema.d.ts +0 -7
  141. package/core/controllers/schemas/native-enum.schema.js +0 -28
  142. package/core/controllers/schemas/set-mask-document-number.schema.d.ts +0 -1
  143. package/core/controllers/schemas/set-mask-document-number.schema.js +0 -13
  144. package/core/database/entity.base.d.ts +0 -20
  145. package/core/database/entity.base.js +0 -71
  146. package/core/database/entity.decorator.d.ts +0 -13
  147. package/core/database/entity.decorator.js +0 -23
  148. package/core/database/prisma-client-with-custom-transaction.interface.d.ts +0 -8
  149. package/core/database/prisma-client-with-custom-transaction.interface.js +0 -2
  150. package/core/database/prisma-resolver.d.ts +0 -2
  151. package/core/database/prisma-resolver.js +0 -74
  152. package/core/database/prisma-transactional-client.d.ts +0 -11
  153. package/core/database/prisma-transactional-client.js +0 -25
  154. package/core/database/prisma.service.d.ts +0 -24
  155. package/core/database/prisma.service.js +0 -104
  156. package/core/database/repository.base.d.ts +0 -44
  157. package/core/database/repository.base.js +0 -360
  158. package/core/dtos/pagination.dto.d.ts +0 -9
  159. package/core/dtos/pagination.dto.js +0 -49
  160. package/core/errors/bad-request.error.d.ts +0 -5
  161. package/core/errors/bad-request.error.js +0 -10
  162. package/core/errors/conflict.error.d.ts +0 -4
  163. package/core/errors/conflict.error.js +0 -10
  164. package/core/errors/error.base.d.ts +0 -4
  165. package/core/errors/error.base.js +0 -11
  166. package/core/errors/no-content.error.d.ts +0 -5
  167. package/core/errors/no-content.error.js +0 -10
  168. package/core/errors/not-allowed.error.d.ts +0 -5
  169. package/core/errors/not-allowed.error.js +0 -10
  170. package/core/errors/resource-not-found.error.d.ts +0 -5
  171. package/core/errors/resource-not-found.error.js +0 -10
  172. package/core/errors/use-case-error.js +0 -2
  173. package/core/errors/user-already-exist.error.d.ts +0 -4
  174. package/core/errors/user-already-exist.error.js +0 -10
  175. package/core/errors/wrong-credentials.error.d.ts +0 -4
  176. package/core/errors/wrong-credentials.error.js +0 -10
  177. package/core/health-check/health-check.controller.d.ts +0 -5
  178. package/core/health-check/health-check.controller.js +0 -32
  179. package/core/health-check/health-check.module.d.ts +0 -2
  180. package/core/health-check/health-check.module.js +0 -19
  181. package/core/index.d.ts +0 -18
  182. package/core/index.js +0 -7
  183. package/core/koala-app.d.ts +0 -64
  184. package/core/koala-app.js +0 -252
  185. package/core/koala-global-vars.d.ts +0 -7
  186. package/core/koala-global-vars.js +0 -9
  187. package/core/koala-nest-database.module.d.ts +0 -16
  188. package/core/koala-nest-database.module.js +0 -52
  189. package/core/koala-nest-http.module.d.ts +0 -13
  190. package/core/koala-nest-http.module.js +0 -37
  191. package/core/koala-nest.module.d.ts +0 -17
  192. package/core/koala-nest.module.js +0 -66
  193. package/core/mapping/auto-mapping-class-context.d.ts +0 -16
  194. package/core/mapping/auto-mapping-class-context.js +0 -18
  195. package/core/mapping/auto-mapping-context.d.ts +0 -11
  196. package/core/mapping/auto-mapping-context.js +0 -24
  197. package/core/mapping/auto-mapping-list.d.ts +0 -27
  198. package/core/mapping/auto-mapping-list.js +0 -94
  199. package/core/mapping/auto-mapping-profile.d.ts +0 -3
  200. package/core/mapping/auto-mapping-profile.js +0 -6
  201. package/core/mapping/auto-mapping.decorator.d.ts +0 -9
  202. package/core/mapping/auto-mapping.decorator.js +0 -27
  203. package/core/mapping/auto-mapping.module.d.ts +0 -5
  204. package/core/mapping/auto-mapping.module.js +0 -29
  205. package/core/mapping/auto-mapping.service.d.ts +0 -14
  206. package/core/mapping/auto-mapping.service.js +0 -140
  207. package/core/mapping/create-map.d.ts +0 -3
  208. package/core/mapping/create-map.js +0 -7
  209. package/core/mapping/for-member.d.ts +0 -5
  210. package/core/mapping/for-member.js +0 -8
  211. package/core/request-overflow/request-handler.base.d.ts +0 -4
  212. package/core/request-overflow/request-handler.base.js +0 -6
  213. package/core/request-overflow/request-result.d.ts +0 -15
  214. package/core/request-overflow/request-result.js +0 -37
  215. package/core/request-overflow/request-validator.base.d.ts +0 -7
  216. package/core/request-overflow/request-validator.base.js +0 -26
  217. package/core/security/strategies/api-key.strategy.d.ts +0 -16
  218. package/core/security/strategies/api-key.strategy.js +0 -31
  219. package/core/utils/assing-object.d.ts +0 -5
  220. package/core/utils/assing-object.js +0 -6
  221. package/core/utils/env.config.d.ts +0 -6
  222. package/core/utils/env.config.js +0 -18
  223. package/core/utils/filter-request-params.d.ts +0 -13
  224. package/core/utils/filter-request-params.js +0 -22
  225. package/core/utils/find-on-list.d.ts +0 -2
  226. package/core/utils/find-on-list.js +0 -13
  227. package/core/utils/get-type-by-prop.d.ts +0 -2
  228. package/core/utils/get-type-by-prop.js +0 -11
  229. package/core/utils/instanciate-class-with-dependencies-injection.d.ts +0 -2
  230. package/core/utils/instanciate-class-with-dependencies-injection.js +0 -10
  231. package/core/utils/interfaces/icomparable.d.ts +0 -5
  232. package/core/utils/interfaces/icomparable.js +0 -6
  233. package/core/utils/list.d.ts +0 -39
  234. package/core/utils/list.js +0 -168
  235. package/core/utils/promise-all.d.ts +0 -7
  236. package/core/utils/promise-all.js +0 -19
  237. package/core/utils/set-mask-document-number.d.ts +0 -1
  238. package/core/utils/set-mask-document-number.js +0 -13
  239. package/core/validators/file-validator.d.ts +0 -27
  240. package/core/validators/file-validator.js +0 -94
  241. package/decorators/api-exclude-endpoint-diff-develop.decorator.d.ts +0 -1
  242. package/decorators/api-exclude-endpoint-diff-develop.decorator.js +0 -9
  243. package/decorators/api-property-enum.decorator.d.ts +0 -8
  244. package/decorators/api-property-enum.decorator.js +0 -21
  245. package/decorators/api-property-only-develop.decorator.d.ts +0 -2
  246. package/decorators/api-property-only-develop.decorator.js +0 -9
  247. package/decorators/cookies.decorator.d.ts +0 -1
  248. package/decorators/cookies.decorator.js +0 -8
  249. package/decorators/is-public.decorator.d.ts +0 -2
  250. package/decorators/is-public.decorator.js +0 -7
  251. package/decorators/upload.decorator.d.ts +0 -1
  252. package/decorators/upload.decorator.js +0 -18
  253. package/docs/00-cli-reference.md +0 -201
  254. package/docs/01-guia-instalacao.md +0 -113
  255. package/docs/02-configuracao-inicial.md +0 -176
  256. package/docs/04-tratamento-erros.md +0 -303
  257. package/docs/05-features-avancadas.md +0 -969
  258. package/docs/06-decoradores.md +0 -220
  259. package/docs/07-guia-bun.md +0 -176
  260. package/docs/08-prisma-client.md +0 -487
  261. package/docs/09-mcp-vscode-extension.md +0 -437
  262. package/docs/EXAMPLE.md +0 -1671
  263. package/docs/README.md +0 -59
  264. package/env/env.d.ts +0 -25
  265. package/env/env.js +0 -14
  266. package/env/env.module.d.ts +0 -2
  267. package/env/env.module.js +0 -20
  268. package/env/env.service.d.ts +0 -7
  269. package/env/env.service.js +0 -28
  270. package/filters/domain-errors.filter.d.ts +0 -18
  271. package/filters/domain-errors.filter.js +0 -92
  272. package/filters/global-exception.filter.d.ts +0 -8
  273. package/filters/global-exception.filter.js +0 -68
  274. package/filters/prisma-validation-exception.filter.d.ts +0 -10
  275. package/filters/prisma-validation-exception.filter.js +0 -82
  276. package/filters/zod-errors.filter.d.ts +0 -9
  277. package/filters/zod-errors.filter.js +0 -60
  278. package/mcp-server/mcp.json.example +0 -27
  279. package/mcp-server/server.d.ts +0 -2
  280. package/mcp-server/server.d.ts.map +0 -1
  281. package/mcp-server/server.js +0 -248
  282. package/mcp-server/server.js.map +0 -1
  283. package/services/logging/ilogging.service.d.ts +0 -16
  284. package/services/logging/ilogging.service.js +0 -6
  285. package/services/logging/logging.service.d.ts +0 -4
  286. package/services/logging/logging.service.js +0 -20
  287. package/services/redis/iredis.service.d.ts +0 -6
  288. package/services/redis/iredis.service.js +0 -6
  289. package/services/redis/redis.service.d.ts +0 -14
  290. package/services/redis/redis.service.js +0 -65
  291. package/services/redlock/ired-lock.service.d.ts +0 -4
  292. package/services/redlock/ired-lock.service.js +0 -6
  293. package/services/redlock/red-lock.service.d.ts +0 -9
  294. package/services/redlock/red-lock.service.js +0 -46
  295. package/test/koala-app-test-dependencies.d.ts +0 -10
  296. package/test/koala-app-test-dependencies.js +0 -13
  297. package/test/koala-app-test.d.ts +0 -22
  298. package/test/koala-app-test.js +0 -77
  299. package/test/repositories/in-memory-base.repository.d.ts +0 -17
  300. package/test/repositories/in-memory-base.repository.js +0 -65
  301. package/test/services/fake-logging.service.d.ts +0 -4
  302. package/test/services/fake-logging.service.js +0 -9
  303. package/test/services/fake-red-lock.service.d.ts +0 -5
  304. package/test/services/fake-red-lock.service.js +0 -11
  305. package/test/utils/create-e2e-database.d.ts +0 -2
  306. package/test/utils/create-e2e-database.js +0 -47
  307. package/test/utils/drop-e2e-database.d.ts +0 -2
  308. package/test/utils/drop-e2e-database.js +0 -33
  309. package/test/utils/wait-for.d.ts +0 -1
  310. package/test/utils/wait-for.js +0 -21
  311. package/tsconfig.lib.tsbuildinfo +0 -1
@@ -0,0 +1,56 @@
1
+ import { Multer } from 'multer'
2
+ import { Express } from 'express'
3
+
4
+ export type FileType = Express.Multer.File
5
+
6
+ /**
7
+ * Make some property optional on type
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * type Post {
12
+ * id: string;
13
+ * name: string;
14
+ * email: string;
15
+ * }
16
+ *
17
+ * Optional<Post, 'id' | 'email' >
18
+ * ```
19
+ */
20
+ export type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
21
+
22
+ /**
23
+ * Override props on type
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * type Post {
28
+ * id: string;
29
+ * name: string;
30
+ * email: string;
31
+ * }
32
+ *
33
+ * Overwrite<Post, { id: number }>
34
+ * ```
35
+ */
36
+ export type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U
37
+
38
+ export type CreatedRegister<TypeId = string> = {
39
+ id: TypeId
40
+ }
41
+
42
+ export type ListResponse<TItem = any> = {
43
+ items: Array<TItem>
44
+ count: number
45
+ }
46
+
47
+ export type FileResponse = {
48
+ filename: string
49
+ type: string
50
+ base64: string
51
+ }
52
+
53
+ export type QueryDirectionType = 'asc' | 'desc'
54
+ // Exportar funções para resolver Prisma
55
+ export { setPrismaClient } from './database/prisma-resolver'
56
+ export { setPrismaClientOptions } from './database/prisma.service'
@@ -0,0 +1,379 @@
1
+ import {
2
+ CanActivate,
3
+ INestApplication,
4
+ InternalServerErrorException,
5
+ Type,
6
+ } from '@nestjs/common'
7
+ import { BaseExceptionFilter } from '@nestjs/core'
8
+ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'
9
+ import { SecuritySchemeObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface'
10
+ import { apiReference } from '@scalar/nestjs-api-reference'
11
+ import * as consola from 'consola'
12
+ import * as expressBasicAuth from 'express-basic-auth'
13
+ import * as ngrok from 'ngrok'
14
+ import { EnvService } from '../env/env.service'
15
+ import { DomainErrorsFilter } from '../filters/domain-errors.filter'
16
+ import { GlobalExceptionsFilter } from '../filters/global-exception.filter'
17
+ import { PrismaValidationExceptionFilter } from '../filters/prisma-validation-exception.filter'
18
+ import { ZodErrorsFilter } from '../filters/zod-errors.filter'
19
+ import { ILoggingService } from '../services/logging/ilogging.service'
20
+ import { CronJobHandlerBase } from './backgroud-services/cron-service/cron-job.handler.base'
21
+ import { EventHandlerBase } from './backgroud-services/event-service/event-handler.base'
22
+ import { PrismaTransactionalClient } from './database/prisma-transactional-client'
23
+ import { KoalaGlobalVars } from './koala-global-vars'
24
+ import { EnvConfig } from './utils/env.config'
25
+ import { instanciateClassWithDependenciesInjection } from './utils/instanciate-class-with-dependencies-injection'
26
+ import { delay } from '@koalarx/utils'
27
+
28
+ interface ApiDocAuthorizationConfig {
29
+ name: string
30
+ config: SecuritySchemeObject
31
+ }
32
+
33
+ interface ApiDocServerConfig {
34
+ url: string
35
+ description: string
36
+ }
37
+
38
+ type ScalarTheme =
39
+ | 'alternate'
40
+ | 'default'
41
+ | 'moon'
42
+ | 'purple'
43
+ | 'solarized'
44
+ | 'bluePlanet'
45
+ | 'saturn'
46
+ | 'kepler'
47
+ | 'mars'
48
+ | 'deepSpace'
49
+ | 'none'
50
+
51
+ interface ApiDocConfig {
52
+ endpoint: string
53
+ title: string
54
+ ui?: 'swagger' | 'scalar'
55
+ theme?: ScalarTheme
56
+ description?: string
57
+ externalDoc?: {
58
+ message: string
59
+ url: string
60
+ }
61
+ servers?: ApiDocServerConfig[]
62
+ version: string
63
+ authorizations?: boolean | ApiDocAuthorizationConfig[]
64
+ }
65
+
66
+ type CronJobClass = string | symbol | Function | Type<CronJobHandlerBase>
67
+ type EventJobClass = string | symbol | Function | Type<EventHandlerBase>
68
+
69
+ export class KoalaApp {
70
+ private _globalExceptionFilter: BaseExceptionFilter
71
+ private _prismaValidationExceptionFilter: BaseExceptionFilter
72
+ private _domainExceptionFilter: BaseExceptionFilter
73
+ private _zodExceptionFilter: BaseExceptionFilter
74
+
75
+ private _guards: CanActivate[] = []
76
+ private _cronJobs: CronJobClass[] = []
77
+ private _eventJobs: EventJobClass[] = []
78
+ private _apiReferenceEndpoint: string
79
+ private _ngrokKey: string
80
+ private _ngrokUrl: string
81
+
82
+ constructor(private readonly app: INestApplication<any>) {
83
+ let loggingService = this.app.get(ILoggingService)
84
+
85
+ if (!loggingService.report) {
86
+ loggingService = instanciateClassWithDependenciesInjection(
87
+ this.app,
88
+ loggingService,
89
+ )
90
+ }
91
+
92
+ this._globalExceptionFilter = new GlobalExceptionsFilter(loggingService)
93
+ this._prismaValidationExceptionFilter = new PrismaValidationExceptionFilter(
94
+ loggingService,
95
+ )
96
+ this._domainExceptionFilter = new DomainErrorsFilter(loggingService)
97
+ this._zodExceptionFilter = new ZodErrorsFilter(loggingService)
98
+ }
99
+
100
+ private showListeningMessage(port: number, host: string = 'localhost') {
101
+ const envService = this.app.get(EnvService)
102
+
103
+ console.log('------------------------------')
104
+
105
+ if (this._apiReferenceEndpoint) {
106
+ consola.info(
107
+ 'API Reference:',
108
+ `http://${host}:${port}${this._apiReferenceEndpoint}`,
109
+ )
110
+ }
111
+
112
+ consola.info('Health Check:', `http://${host}:${port}/health`)
113
+ consola.info('Internal Host:', `http://${host}:${port}`)
114
+
115
+ if (this._ngrokUrl) {
116
+ consola.info('External Host:', this._ngrokUrl)
117
+ consola.info('External Inspect:', `http://${host}:4040/inspect/http`)
118
+ }
119
+
120
+ consola.box('Environment:', envService.get('NODE_ENV'))
121
+
122
+ console.log('------------------------------')
123
+ }
124
+
125
+ private async startJobs() {
126
+ await delay(5000) // Aguarda 5 segundos para garantir que a aplicação esteja totalmente inicializada
127
+
128
+ const cronJobs = await Promise.all(
129
+ this._cronJobs.map((job) => this.app.resolve(job)),
130
+ )
131
+
132
+ for (const cronJob of cronJobs) {
133
+ cronJob.start()
134
+ }
135
+
136
+ const eventJobs = await Promise.all(
137
+ this._eventJobs.map((job) => this.app.resolve(job)),
138
+ )
139
+
140
+ for (const eventJob of eventJobs) {
141
+ eventJob.setupSubscriptions()
142
+ }
143
+ }
144
+
145
+ addGlobalGuard(Guard: Type<CanActivate>) {
146
+ this._guards.push(
147
+ instanciateClassWithDependenciesInjection(this.app, Guard),
148
+ )
149
+ return this
150
+ }
151
+
152
+ addCronJob(job: CronJobClass) {
153
+ this._cronJobs.push(job)
154
+ return this
155
+ }
156
+
157
+ addEventJob(eventJob: EventJobClass) {
158
+ this._eventJobs.push(eventJob)
159
+ return this
160
+ }
161
+
162
+ addCustomGlobalExceptionFilter(filter: BaseExceptionFilter) {
163
+ this._globalExceptionFilter = filter
164
+ return this
165
+ }
166
+
167
+ addCustomPrismaValidationExceptionFilter(filter: BaseExceptionFilter) {
168
+ this._prismaValidationExceptionFilter = filter
169
+ return this
170
+ }
171
+
172
+ addCustomDomainExceptionFilter(filter: BaseExceptionFilter) {
173
+ this._domainExceptionFilter = filter
174
+ return this
175
+ }
176
+
177
+ addCustomZodExceptionFilter(filter: BaseExceptionFilter) {
178
+ this._zodExceptionFilter = filter
179
+ return this
180
+ }
181
+
182
+ useDoc(config: ApiDocConfig) {
183
+ const credentials = {
184
+ username: process.env.SWAGGER_USERNAME ?? '',
185
+ password: process.env.SWAGGER_PASSWORD ?? '',
186
+ }
187
+
188
+ if (
189
+ EnvConfig.isEnvDevelop &&
190
+ credentials.username &&
191
+ credentials.password
192
+ ) {
193
+ this.app.use(
194
+ [config.endpoint],
195
+ expressBasicAuth({
196
+ challenge: true,
197
+ users: {
198
+ [credentials.username]: credentials.password,
199
+ },
200
+ }),
201
+ )
202
+ }
203
+
204
+ const documentBuilder = new DocumentBuilder()
205
+ .setTitle(config.title)
206
+ .setVersion(config.version)
207
+
208
+ if (config.description) {
209
+ if (config.externalDoc) {
210
+ documentBuilder.setDescription(
211
+ `${config.description}\n\n[${config.externalDoc.message}](${config.externalDoc.url})`,
212
+ )
213
+ } else {
214
+ documentBuilder.setDescription(config.description)
215
+ }
216
+ }
217
+
218
+ if (config.authorizations) {
219
+ if (Array.isArray(config.authorizations)) {
220
+ for (const auth of config.authorizations) {
221
+ documentBuilder.addBearerAuth(auth.config, auth.name)
222
+ documentBuilder.addSecurityRequirements(auth.name)
223
+ }
224
+ } else {
225
+ documentBuilder.addBearerAuth()
226
+ }
227
+ }
228
+
229
+ if (config.servers) {
230
+ for (const server of config.servers) {
231
+ documentBuilder.addServer(server.url, server.description)
232
+ }
233
+ }
234
+
235
+ const document = SwaggerModule.createDocument(
236
+ this.app,
237
+ documentBuilder.build(),
238
+ )
239
+ const swaggerEndpoint = config.endpoint
240
+ this._apiReferenceEndpoint = swaggerEndpoint
241
+
242
+ if (config.ui === 'scalar' && swaggerEndpoint === '/') {
243
+ throw new InternalServerErrorException(
244
+ "O endpoint de documentação não pode ser '/' para UI Scalar.",
245
+ )
246
+ }
247
+
248
+ SwaggerModule.setup(swaggerEndpoint, this.app, document, {
249
+ swaggerUiEnabled: config.ui !== 'scalar',
250
+ })
251
+
252
+ if (config.ui === 'scalar') {
253
+ this.app.use(
254
+ swaggerEndpoint,
255
+ apiReference({
256
+ spec: {
257
+ content: document,
258
+ },
259
+ hideModels: true,
260
+ hideDownloadButton: true,
261
+ hideClientButton: true,
262
+ theme: config.theme ?? 'default',
263
+ hiddenClients: [
264
+ 'libcurl',
265
+ 'clj_http',
266
+ 'restsharp',
267
+ 'native',
268
+ 'http1.1',
269
+ 'asynchttp',
270
+ 'nethttp',
271
+ 'okhttp',
272
+ 'unirest',
273
+ 'xhr',
274
+ 'okhttp',
275
+ 'native',
276
+ 'request',
277
+ 'unirest',
278
+ 'nsurlsession',
279
+ 'cohttp',
280
+ 'guzzle',
281
+ 'http1',
282
+ 'http2',
283
+ 'webrequest',
284
+ 'restmethod',
285
+ 'requests',
286
+ 'httr',
287
+ 'native',
288
+ 'httpie',
289
+ 'wget',
290
+ 'nsurlsession',
291
+ 'undici',
292
+ ],
293
+ metaData: {
294
+ title: config.title,
295
+ description: config.description,
296
+ },
297
+ }),
298
+ )
299
+ }
300
+
301
+ return this
302
+ }
303
+
304
+ useNgrok(key: string) {
305
+ this._ngrokKey = key
306
+ return this
307
+ }
308
+
309
+ enableCors() {
310
+ this.app.enableCors({
311
+ credentials: true,
312
+ origin: true,
313
+ optionsSuccessStatus: 200,
314
+ })
315
+
316
+ return this
317
+ }
318
+
319
+ setAppName(name: string) {
320
+ KoalaGlobalVars.appName = name
321
+ return this
322
+ }
323
+
324
+ setInternalUserName(name: string) {
325
+ KoalaGlobalVars.internalUserName = name
326
+ return this
327
+ }
328
+
329
+ setDbTransactionContext(transactionContext: Type<PrismaTransactionalClient>) {
330
+ KoalaGlobalVars.dbTransactionContext = transactionContext
331
+ return this
332
+ }
333
+
334
+ async build() {
335
+ if (KoalaGlobalVars.dbTransactionContext) {
336
+ this.app.useGlobalFilters(this._prismaValidationExceptionFilter)
337
+ }
338
+
339
+ this.app.useGlobalFilters(
340
+ this._globalExceptionFilter,
341
+ this._domainExceptionFilter,
342
+ this._zodExceptionFilter,
343
+ )
344
+
345
+ for (const guard of this._guards) {
346
+ this.app.useGlobalGuards(guard)
347
+ }
348
+
349
+ if (this._ngrokKey) {
350
+ const envService = this.app.get(EnvService)
351
+ const port = envService.get('PORT') ?? 3000
352
+
353
+ await ngrok
354
+ .connect({
355
+ authtoken: this._ngrokKey,
356
+ addr: port,
357
+ })
358
+ .then((url) => {
359
+ this._ngrokUrl = url
360
+ })
361
+ }
362
+
363
+ this.startJobs()
364
+
365
+ return this.app
366
+ }
367
+
368
+ async serve(host?: string) {
369
+ const envService = this.app.get(EnvService)
370
+ const port = envService.get('PORT') ?? 3000
371
+
372
+ this.app.listen(port).then(() => this.showListeningMessage(port, host))
373
+ }
374
+
375
+ async buildAndServe(host?: string) {
376
+ await this.build()
377
+ await this.serve(host)
378
+ }
379
+ }
@@ -0,0 +1,8 @@
1
+ import { Type } from '@nestjs/common'
2
+ import { PrismaTransactionalClient } from './database/prisma-transactional-client'
3
+
4
+ export class KoalaGlobalVars {
5
+ static appName: string = 'koala-nest'
6
+ static internalUserName: string = 'internal'
7
+ static dbTransactionContext?: Type<PrismaTransactionalClient>
8
+ }
@@ -0,0 +1,65 @@
1
+ import {
2
+ DynamicModule,
3
+ ForwardReference,
4
+ InjectionToken,
5
+ Module,
6
+ Type,
7
+ } from '@nestjs/common'
8
+ import { RepositoryBase } from '../core/database/repository.base'
9
+ import { EnvService } from '../env/env.service'
10
+ import { PrismaService } from './database/prisma.service'
11
+
12
+ export const PRISMA_TOKEN = 'PRISMA_SERVICE_TOKEN'
13
+
14
+ export interface KoalaNestDatabaseProviderConfig<T> {
15
+ interface: InjectionToken
16
+ class: Type<T>
17
+ }
18
+
19
+ interface KoalaNestDatabaseModuleConfig {
20
+ repositories: KoalaNestDatabaseProviderConfig<RepositoryBase<any>>[]
21
+ services: KoalaNestDatabaseProviderConfig<any>[]
22
+ imports?: Array<Type<any> | DynamicModule | ForwardReference<any>>
23
+ }
24
+
25
+ @Module({})
26
+ export class KoalaNestDatabaseModule {
27
+ static register(config: KoalaNestDatabaseModuleConfig): DynamicModule {
28
+ const imports = config.imports ?? []
29
+ const repositoriesToExport =
30
+ config.repositories?.map((repository) => repository.interface) ?? []
31
+ const repositoriesToProvide =
32
+ config.repositories?.map((repository) => ({
33
+ provide: repository.interface,
34
+ useClass: repository.class,
35
+ })) ?? []
36
+
37
+ const servicesToExport =
38
+ config.services?.map((service) => service.interface) ?? []
39
+ const servicesToProvide =
40
+ config.services?.map((service) => ({
41
+ provide: service.interface,
42
+ useClass: service.class,
43
+ })) ?? []
44
+
45
+ return {
46
+ module: KoalaNestDatabaseModule,
47
+ imports,
48
+ providers: [
49
+ {
50
+ provide: PRISMA_TOKEN,
51
+ useClass: PrismaService,
52
+ },
53
+ ...repositoriesToProvide,
54
+ ...servicesToProvide,
55
+ EnvService,
56
+ ],
57
+ exports: [
58
+ PRISMA_TOKEN,
59
+ ...repositoriesToExport,
60
+ ...servicesToExport,
61
+ ...imports,
62
+ ],
63
+ }
64
+ }
65
+ }
@@ -0,0 +1,44 @@
1
+ import {
2
+ DynamicModule,
3
+ ForwardReference,
4
+ MiddlewareConsumer,
5
+ Module,
6
+ NestMiddleware,
7
+ NestModule,
8
+ Type,
9
+ } from '@nestjs/common'
10
+ import { EnvService } from '../env/env.service'
11
+ import { AutoMappingProfile } from './mapping/auto-mapping-profile'
12
+ import { AutoMappingModule } from './mapping/auto-mapping.module'
13
+
14
+ interface KoalaNestHttpModuleConfig {
15
+ imports?: Array<Type<any> | DynamicModule | ForwardReference<any>>
16
+ automapperProfile: Type<AutoMappingProfile>
17
+ middlewares?: Type<NestMiddleware>[]
18
+ }
19
+
20
+ @Module({})
21
+ export class KoalaNestHttpModule implements NestModule {
22
+ private static _config: KoalaNestHttpModuleConfig
23
+
24
+ static register(config: KoalaNestHttpModuleConfig): DynamicModule {
25
+ this._config = config
26
+ const imports = config.imports ?? []
27
+
28
+ return {
29
+ module: KoalaNestHttpModule,
30
+ imports: [
31
+ ...imports,
32
+ AutoMappingModule.register(config.automapperProfile),
33
+ ],
34
+ providers: [EnvService],
35
+ exports: [AutoMappingModule, ...imports],
36
+ }
37
+ }
38
+
39
+ configure(consumer: MiddlewareConsumer) {
40
+ KoalaNestHttpModule._config.middlewares?.forEach((middleware) =>
41
+ consumer.apply(middleware).forRoutes('*'),
42
+ )
43
+ }
44
+ }
@@ -0,0 +1,67 @@
1
+ import { DynamicModule, Module, Provider, Type } from '@nestjs/common'
2
+ import { ConfigModule } from '@nestjs/config'
3
+ import { ZodType } from 'zod'
4
+ import { envSchema } from '../env/env'
5
+ import { EnvModule } from '../env/env.module'
6
+ import { EnvService } from '../env/env.service'
7
+ import { ILoggingService } from '../services/logging/ilogging.service'
8
+ import { LoggingService } from '../services/logging/logging.service'
9
+ import { IRedisService } from '../services/redis/iredis.service'
10
+ import { RedisService } from '../services/redis/redis.service'
11
+ import { IRedLockService } from '../services/redlock/ired-lock.service'
12
+ import { RedLockService } from '../services/redlock/red-lock.service'
13
+ import { CronJobHandlerBase } from './backgroud-services/cron-service/cron-job.handler.base'
14
+ import { EventHandlerBase } from './backgroud-services/event-service/event-handler.base'
15
+ import { HealthCheckModule } from './health-check/health-check.module'
16
+
17
+ interface KoalaNestModuleConfig {
18
+ logging?: Provider<ILoggingService>
19
+ env?: ZodType
20
+ controllers?: Type<any>[]
21
+ healthCheck?: Type<any>
22
+ cronJobs?: Type<CronJobHandlerBase>[]
23
+ eventJobs?: Type<EventHandlerBase>[]
24
+ }
25
+
26
+ @Module({})
27
+ export class KoalaNestModule {
28
+ static register(config?: KoalaNestModuleConfig): DynamicModule {
29
+ const controllers = config?.controllers ?? []
30
+ const healthCheck = config?.healthCheck ?? HealthCheckModule
31
+ const cronJobsProviders = config?.cronJobs ?? []
32
+ const eventJobsProviders = config?.eventJobs ?? []
33
+ const loggingServiceClass = config?.logging ?? LoggingService
34
+
35
+ return {
36
+ module: KoalaNestModule,
37
+ imports: [
38
+ ConfigModule.forRoot({
39
+ validate: (envData) => (config?.env ?? envSchema).parse(envData),
40
+ isGlobal: true,
41
+ }),
42
+ EnvModule,
43
+ healthCheck,
44
+ ...controllers,
45
+ ],
46
+ providers: [
47
+ ...cronJobsProviders,
48
+ ...eventJobsProviders,
49
+ {
50
+ provide: ILoggingService,
51
+ useValue: loggingServiceClass,
52
+ },
53
+ { provide: IRedisService, useClass: RedisService },
54
+ { provide: IRedLockService, useClass: RedLockService },
55
+ EnvService,
56
+ ],
57
+ exports: [
58
+ ...cronJobsProviders,
59
+ ...eventJobsProviders,
60
+ ILoggingService,
61
+ IRedisService,
62
+ IRedLockService,
63
+ EnvService,
64
+ ],
65
+ }
66
+ }
67
+ }
@@ -0,0 +1,28 @@
1
+ import { Type } from '@nestjs/common'
2
+ import { IComparable, IComparableId } from '../utils/interfaces/icomparable'
3
+ import { List } from '../utils/list'
4
+ import { randomUUID } from 'crypto'
5
+
6
+ export interface AutoMappingClassProp {
7
+ name: string
8
+ type: () => Type<any> | ArrayConstructor
9
+ compositionType?: () => Type<any> | ArrayConstructor
10
+ compositionAction?: 'onlySet' | 'addTo'
11
+ }
12
+
13
+ export class AutoMappingClassContext
14
+ implements IComparable<AutoMappingClassContext>
15
+ {
16
+ _id: IComparableId
17
+ source: Type<any>
18
+ props = new List<AutoMappingClassProp>()
19
+
20
+ constructor(source: Type<any>) {
21
+ this._id = randomUUID()
22
+ this.source = source
23
+ }
24
+
25
+ equals(obj: AutoMappingClassContext): boolean {
26
+ return obj._id === this._id && this.source instanceof obj.source
27
+ }
28
+ }
@@ -0,0 +1,26 @@
1
+ import { Type } from '@nestjs/common'
2
+ import { randomUUID } from 'node:crypto'
3
+ import { IComparable, IComparableId } from '../utils/interfaces/icomparable'
4
+ import { ForMemberDefinition } from './for-member'
5
+
6
+ export class AutoMappingContext implements IComparable<AutoMappingContext> {
7
+ _id: IComparableId
8
+
9
+ constructor(
10
+ public source: Type<any>,
11
+ public target: Type<any>,
12
+ public forMemberDifinitions: ForMemberDefinition<any, any>,
13
+ ) {
14
+ this._id = randomUUID()
15
+ this.source = source
16
+ this.target = target
17
+ }
18
+
19
+ equals(obj: AutoMappingContext): boolean {
20
+ return (
21
+ obj._id === this._id &&
22
+ this.source instanceof obj.source &&
23
+ this.target instanceof obj.target
24
+ )
25
+ }
26
+ }