@archi-code/ddd 0.0.0-stage → 3.0.0-alpha.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 (312) hide show
  1. package/LICENSE +46 -0
  2. package/README.md +2693 -2
  3. package/SKILL.md +104 -0
  4. package/ddd-skills/archi-code-ddd/imports.md +84 -0
  5. package/ddd-skills/archi-code-ddd/layers.md +299 -0
  6. package/ddd-skills/archi-code-ddd/patterns.md +676 -0
  7. package/ddd-skills/archi-code-ddd/what-not-to-do.md +189 -0
  8. package/ddd-skills/archi-code-ddd/where-each-class-goes.md +63 -0
  9. package/ddd-skills/ddd-agregados/GUIA.md +114 -0
  10. package/ddd-skills/ddd-agregados/references/consistencia-eventual.md +159 -0
  11. package/ddd-skills/ddd-agregados/references/ejemplo-ecommerce.md +52 -0
  12. package/ddd-skills/ddd-agregados/references/fabricas.md +196 -0
  13. package/ddd-skills/ddd-agregados/references/implementacion-ts.md +711 -0
  14. package/ddd-skills/ddd-arquitectura/GUIA.md +80 -0
  15. package/ddd-skills/ddd-arquitectura/assets/dependency-cruiser.cjs +92 -0
  16. package/ddd-skills/ddd-arquitectura/references/estilos-adicionales.md +51 -0
  17. package/ddd-skills/ddd-arquitectura/references/estructura-hexagonal-ts.md +352 -0
  18. package/ddd-skills/ddd-arquitectura/references/modulos.md +48 -0
  19. package/ddd-skills/ddd-auditoria-refactorizacion/GUIA.md +85 -0
  20. package/ddd-skills/ddd-auditoria-refactorizacion/references/ejemplo-auditoria.md +316 -0
  21. package/ddd-skills/ddd-auditoria-refactorizacion/references/lista-comprobacion.md +54 -0
  22. package/ddd-skills/ddd-auditoria-refactorizacion/references/plan-migracion.md +73 -0
  23. package/ddd-skills/ddd-auditoria-refactorizacion/scripts/scan_ddd_smells.py +264 -0
  24. package/ddd-skills/ddd-context-mapping/GUIA.md +83 -0
  25. package/ddd-skills/ddd-context-mapping/references/anticorrupcion-ts.md +404 -0
  26. package/ddd-skills/ddd-context-mapping/references/estilos-integracion.md +155 -0
  27. package/ddd-skills/ddd-event-sourcing-cqrs/GUIA.md +92 -0
  28. package/ddd-skills/ddd-event-sourcing-cqrs/references/event-sourcing-ts.md +471 -0
  29. package/ddd-skills/ddd-event-sourcing-cqrs/references/proyecciones-cqrs-ts.md +285 -0
  30. package/ddd-skills/ddd-eventos-dominio/GUIA.md +106 -0
  31. package/ddd-skills/ddd-eventos-dominio/references/diseno-eventos.md +131 -0
  32. package/ddd-skills/ddd-eventos-dominio/references/ejemplo-ecommerce.md +240 -0
  33. package/ddd-skills/ddd-eventos-dominio/references/publicacion-ts.md +526 -0
  34. package/ddd-skills/ddd-orquestador/GUIA.md +40 -0
  35. package/ddd-skills/ddd-orquestador/references/chuleta-reglas.md +35 -0
  36. package/ddd-skills/ddd-repositorios-persistencia/GUIA.md +121 -0
  37. package/ddd-skills/ddd-repositorios-persistencia/references/implementacion-ts.md +296 -0
  38. package/ddd-skills/ddd-repositorios-persistencia/references/tests-repositorios.md +177 -0
  39. package/ddd-skills/ddd-repositorios-persistencia/references/transacciones-ts.md +294 -0
  40. package/ddd-skills/ddd-servicios-capa-aplicacion/GUIA.md +99 -0
  41. package/ddd-skills/ddd-servicios-capa-aplicacion/references/capa-aplicacion-ts.md +264 -0
  42. package/ddd-skills/ddd-servicios-capa-aplicacion/references/ejemplo-ecommerce.md +324 -0
  43. package/ddd-skills/ddd-servicios-capa-aplicacion/references/servicios-dominio-ts.md +191 -0
  44. package/ddd-skills/ddd-value-objects-entidades/GUIA.md +118 -0
  45. package/ddd-skills/ddd-value-objects-entidades/references/ejemplo-ecommerce.md +87 -0
  46. package/ddd-skills/ddd-value-objects-entidades/references/entidades-ts.md +220 -0
  47. package/ddd-skills/ddd-value-objects-entidades/references/persistencia-valores.md +88 -0
  48. package/ddd-skills/ddd-value-objects-entidades/references/specification-y-diseno-flexible.md +119 -0
  49. package/ddd-skills/ddd-value-objects-entidades/references/validacion.md +96 -0
  50. package/ddd-skills/ddd-value-objects-entidades/references/value-objects-ts.md +377 -0
  51. package/dist/cjs/application/event/event-bus.d.ts +4 -0
  52. package/dist/cjs/application/event/event-bus.js +2 -0
  53. package/dist/cjs/application/event/event-listener.d.ts +4 -0
  54. package/dist/cjs/application/event/event-listener.js +6 -0
  55. package/dist/cjs/application/event/listens-to.d.ts +15 -0
  56. package/dist/cjs/application/event/listens-to.js +28 -0
  57. package/dist/cjs/application/index.d.ts +7 -0
  58. package/dist/cjs/application/index.js +9 -0
  59. package/dist/cjs/application/ports/clock.d.ts +3 -0
  60. package/dist/cjs/application/ports/clock.js +2 -0
  61. package/dist/cjs/application/ports/logger.d.ts +8 -0
  62. package/dist/cjs/application/ports/logger.js +2 -0
  63. package/dist/cjs/application/use-case/use-case.d.ts +6 -0
  64. package/dist/cjs/application/use-case/use-case.js +24 -0
  65. package/dist/cjs/domain/aggregate/aggregate-root.d.ts +14 -0
  66. package/dist/cjs/domain/aggregate/aggregate-root.js +33 -0
  67. package/dist/cjs/domain/entity/entity.d.ts +9 -0
  68. package/dist/cjs/domain/entity/entity.js +19 -0
  69. package/dist/cjs/domain/event/event-base.d.ts +29 -0
  70. package/dist/cjs/domain/event/event-base.js +51 -0
  71. package/dist/cjs/domain/index.d.ts +10 -0
  72. package/dist/cjs/domain/index.js +24 -0
  73. package/dist/cjs/domain/primitive/primitive-types.d.ts +22 -0
  74. package/dist/cjs/domain/primitive/primitive-types.js +2 -0
  75. package/dist/cjs/domain/repository/aggregate-finder.d.ts +4 -0
  76. package/dist/cjs/domain/repository/aggregate-finder.js +2 -0
  77. package/dist/cjs/domain/repository/aggregate-remover.d.ts +4 -0
  78. package/dist/cjs/domain/repository/aggregate-remover.js +2 -0
  79. package/dist/cjs/domain/repository/aggregate-saver.d.ts +4 -0
  80. package/dist/cjs/domain/repository/aggregate-saver.js +2 -0
  81. package/dist/cjs/domain/specification/specification.d.ts +9 -0
  82. package/dist/cjs/domain/specification/specification.js +44 -0
  83. package/dist/cjs/domain/type/abstract-type.d.ts +20 -0
  84. package/dist/cjs/domain/type/abstract-type.js +69 -0
  85. package/dist/cjs/domain/type/array-type.d.ts +16 -0
  86. package/dist/cjs/domain/type/array-type.js +65 -0
  87. package/dist/cjs/domain/type/boolean-type.d.ts +4 -0
  88. package/dist/cjs/domain/type/boolean-type.js +16 -0
  89. package/dist/cjs/domain/type/composite/composite-field.d.ts +19 -0
  90. package/dist/cjs/domain/type/composite/composite-field.js +63 -0
  91. package/dist/cjs/domain/type/composite/composite.d.ts +26 -0
  92. package/dist/cjs/domain/type/composite/composite.js +55 -0
  93. package/dist/cjs/domain/type/date-type.d.ts +18 -0
  94. package/dist/cjs/domain/type/date-type.js +35 -0
  95. package/dist/cjs/domain/type/enum-type.d.ts +7 -0
  96. package/dist/cjs/domain/type/enum-type.js +30 -0
  97. package/dist/cjs/domain/type/equality/value-equality.d.ts +7 -0
  98. package/dist/cjs/domain/type/equality/value-equality.js +41 -0
  99. package/dist/cjs/domain/type/id-type.d.ts +7 -0
  100. package/dist/cjs/domain/type/id-type.js +17 -0
  101. package/dist/cjs/domain/type/immutable/immutable-date.d.ts +4 -0
  102. package/dist/cjs/domain/type/immutable/immutable-date.js +37 -0
  103. package/dist/cjs/domain/type/immutable/immutable.d.ts +4 -0
  104. package/dist/cjs/domain/type/immutable/immutable.js +19 -0
  105. package/dist/cjs/domain/type/index.d.ts +17 -0
  106. package/dist/cjs/domain/type/index.js +33 -0
  107. package/dist/cjs/domain/type/json-type.d.ts +5 -0
  108. package/dist/cjs/domain/type/json-type.js +17 -0
  109. package/dist/cjs/domain/type/number-type.d.ts +4 -0
  110. package/dist/cjs/domain/type/number-type.js +16 -0
  111. package/dist/cjs/domain/type/required/required-mark.d.ts +9 -0
  112. package/dist/cjs/domain/type/required/required-mark.js +13 -0
  113. package/dist/cjs/domain/type/required/required.d.ts +7 -0
  114. package/dist/cjs/domain/type/required/required.js +21 -0
  115. package/dist/cjs/domain/type/string-type.d.ts +4 -0
  116. package/dist/cjs/domain/type/string-type.js +16 -0
  117. package/dist/cjs/domain/type/uuid-type.d.ts +7 -0
  118. package/dist/cjs/domain/type/uuid-type.js +27 -0
  119. package/dist/cjs/domain/type/value-objects/value-objects.d.ts +16 -0
  120. package/dist/cjs/domain/type/value-objects/value-objects.js +70 -0
  121. package/dist/cjs/exceptions/abstract.exception.d.ts +23 -0
  122. package/dist/cjs/exceptions/abstract.exception.js +66 -0
  123. package/dist/cjs/exceptions/application/aggregate-not-found.exception.d.ts +5 -0
  124. package/dist/cjs/exceptions/application/aggregate-not-found.exception.js +17 -0
  125. package/dist/cjs/exceptions/application/application.exception.d.ts +6 -0
  126. package/dist/cjs/exceptions/application/application.exception.js +17 -0
  127. package/dist/cjs/exceptions/application/concurrency.exception.d.ts +5 -0
  128. package/dist/cjs/exceptions/application/concurrency.exception.js +17 -0
  129. package/dist/cjs/exceptions/application/not-allowed.exception.d.ts +5 -0
  130. package/dist/cjs/exceptions/application/not-allowed.exception.js +17 -0
  131. package/dist/cjs/exceptions/brand/exception-brand.d.ts +6 -0
  132. package/dist/cjs/exceptions/brand/exception-brand.js +29 -0
  133. package/dist/cjs/exceptions/domain/domain.exception.d.ts +6 -0
  134. package/dist/cjs/exceptions/domain/domain.exception.js +17 -0
  135. package/dist/cjs/exceptions/domain/required-value.exception.d.ts +4 -0
  136. package/dist/cjs/exceptions/domain/required-value.exception.js +21 -0
  137. package/dist/cjs/exceptions/domain/type-primitive.exception.d.ts +4 -0
  138. package/dist/cjs/exceptions/domain/type-primitive.exception.js +21 -0
  139. package/dist/cjs/exceptions/domain/validation.exception.d.ts +14 -0
  140. package/dist/cjs/exceptions/domain/validation.exception.js +23 -0
  141. package/dist/cjs/exceptions/exception-code.d.ts +15 -0
  142. package/dist/cjs/exceptions/exception-code.js +19 -0
  143. package/dist/cjs/exceptions/index.d.ts +14 -0
  144. package/dist/cjs/exceptions/index.js +30 -0
  145. package/dist/cjs/exceptions/infrastructure/event-delivery.exception.d.ts +5 -0
  146. package/dist/cjs/exceptions/infrastructure/event-delivery.exception.js +20 -0
  147. package/dist/cjs/exceptions/infrastructure/infrastructure.exception.d.ts +6 -0
  148. package/dist/cjs/exceptions/infrastructure/infrastructure.exception.js +17 -0
  149. package/dist/cjs/exceptions/infrastructure/internal-error.exception.d.ts +5 -0
  150. package/dist/cjs/exceptions/infrastructure/internal-error.exception.js +17 -0
  151. package/dist/cjs/exceptions/infrastructure/unknown-event.exception.d.ts +4 -0
  152. package/dist/cjs/exceptions/infrastructure/unknown-event.exception.js +19 -0
  153. package/dist/cjs/exceptions/received/received-value.d.ts +4 -0
  154. package/dist/cjs/exceptions/received/received-value.js +13 -0
  155. package/dist/cjs/infrastructure/clock/fixed-clock.d.ts +8 -0
  156. package/dist/cjs/infrastructure/clock/fixed-clock.js +19 -0
  157. package/dist/cjs/infrastructure/clock/system-clock.d.ts +4 -0
  158. package/dist/cjs/infrastructure/clock/system-clock.js +9 -0
  159. package/dist/cjs/infrastructure/event/domain-event-bus.d.ts +16 -0
  160. package/dist/cjs/infrastructure/event/domain-event-bus.js +60 -0
  161. package/dist/cjs/infrastructure/event/event-channel.d.ts +9 -0
  162. package/dist/cjs/infrastructure/event/event-channel.js +2 -0
  163. package/dist/cjs/infrastructure/event/event-registry.d.ts +9 -0
  164. package/dist/cjs/infrastructure/event/event-registry.js +43 -0
  165. package/dist/cjs/infrastructure/event/in-memory/emitter.d.ts +11 -0
  166. package/dist/cjs/infrastructure/event/in-memory/emitter.js +54 -0
  167. package/dist/cjs/infrastructure/event/in-memory/in-memory-event-channel.d.ts +16 -0
  168. package/dist/cjs/infrastructure/event/in-memory/in-memory-event-channel.js +51 -0
  169. package/dist/cjs/infrastructure/http/http-error-mapper.d.ts +23 -0
  170. package/dist/cjs/infrastructure/http/http-error-mapper.js +63 -0
  171. package/dist/cjs/infrastructure/index.d.ts +16 -0
  172. package/dist/cjs/infrastructure/index.js +21 -0
  173. package/dist/cjs/infrastructure/logging/console-logger.d.ts +17 -0
  174. package/dist/cjs/infrastructure/logging/console-logger.js +37 -0
  175. package/dist/cjs/infrastructure/logging/in-memory-logger.d.ts +15 -0
  176. package/dist/cjs/infrastructure/logging/in-memory-logger.js +27 -0
  177. package/dist/cjs/infrastructure/logging/log-serializer.d.ts +7 -0
  178. package/dist/cjs/infrastructure/logging/log-serializer.js +59 -0
  179. package/dist/cjs/infrastructure/logging/silent-logger.d.ts +7 -0
  180. package/dist/cjs/infrastructure/logging/silent-logger.js +18 -0
  181. package/dist/esm/application/event/event-bus.d.ts +4 -0
  182. package/dist/esm/application/event/event-bus.js +1 -0
  183. package/dist/esm/application/event/event-listener.d.ts +4 -0
  184. package/dist/esm/application/event/event-listener.js +2 -0
  185. package/dist/esm/application/event/listens-to.d.ts +15 -0
  186. package/dist/esm/application/event/listens-to.js +25 -0
  187. package/dist/esm/application/index.d.ts +7 -0
  188. package/dist/esm/application/index.js +3 -0
  189. package/dist/esm/application/ports/clock.d.ts +3 -0
  190. package/dist/esm/application/ports/clock.js +1 -0
  191. package/dist/esm/application/ports/logger.d.ts +8 -0
  192. package/dist/esm/application/ports/logger.js +1 -0
  193. package/dist/esm/application/use-case/use-case.d.ts +6 -0
  194. package/dist/esm/application/use-case/use-case.js +20 -0
  195. package/dist/esm/domain/aggregate/aggregate-root.d.ts +14 -0
  196. package/dist/esm/domain/aggregate/aggregate-root.js +29 -0
  197. package/dist/esm/domain/entity/entity.d.ts +9 -0
  198. package/dist/esm/domain/entity/entity.js +15 -0
  199. package/dist/esm/domain/event/event-base.d.ts +29 -0
  200. package/dist/esm/domain/event/event-base.js +47 -0
  201. package/dist/esm/domain/index.d.ts +10 -0
  202. package/dist/esm/domain/index.js +6 -0
  203. package/dist/esm/domain/primitive/primitive-types.d.ts +22 -0
  204. package/dist/esm/domain/primitive/primitive-types.js +1 -0
  205. package/dist/esm/domain/repository/aggregate-finder.d.ts +4 -0
  206. package/dist/esm/domain/repository/aggregate-finder.js +1 -0
  207. package/dist/esm/domain/repository/aggregate-remover.d.ts +4 -0
  208. package/dist/esm/domain/repository/aggregate-remover.js +1 -0
  209. package/dist/esm/domain/repository/aggregate-saver.d.ts +4 -0
  210. package/dist/esm/domain/repository/aggregate-saver.js +1 -0
  211. package/dist/esm/domain/specification/specification.d.ts +9 -0
  212. package/dist/esm/domain/specification/specification.js +40 -0
  213. package/dist/esm/domain/type/abstract-type.d.ts +20 -0
  214. package/dist/esm/domain/type/abstract-type.js +65 -0
  215. package/dist/esm/domain/type/array-type.d.ts +16 -0
  216. package/dist/esm/domain/type/array-type.js +61 -0
  217. package/dist/esm/domain/type/boolean-type.d.ts +4 -0
  218. package/dist/esm/domain/type/boolean-type.js +12 -0
  219. package/dist/esm/domain/type/composite/composite-field.d.ts +19 -0
  220. package/dist/esm/domain/type/composite/composite-field.js +59 -0
  221. package/dist/esm/domain/type/composite/composite.d.ts +26 -0
  222. package/dist/esm/domain/type/composite/composite.js +52 -0
  223. package/dist/esm/domain/type/date-type.d.ts +18 -0
  224. package/dist/esm/domain/type/date-type.js +29 -0
  225. package/dist/esm/domain/type/enum-type.d.ts +7 -0
  226. package/dist/esm/domain/type/enum-type.js +26 -0
  227. package/dist/esm/domain/type/equality/value-equality.d.ts +7 -0
  228. package/dist/esm/domain/type/equality/value-equality.js +37 -0
  229. package/dist/esm/domain/type/id-type.d.ts +7 -0
  230. package/dist/esm/domain/type/id-type.js +13 -0
  231. package/dist/esm/domain/type/immutable/immutable-date.d.ts +4 -0
  232. package/dist/esm/domain/type/immutable/immutable-date.js +33 -0
  233. package/dist/esm/domain/type/immutable/immutable.d.ts +4 -0
  234. package/dist/esm/domain/type/immutable/immutable.js +15 -0
  235. package/dist/esm/domain/type/index.d.ts +17 -0
  236. package/dist/esm/domain/type/index.js +14 -0
  237. package/dist/esm/domain/type/json-type.d.ts +5 -0
  238. package/dist/esm/domain/type/json-type.js +13 -0
  239. package/dist/esm/domain/type/number-type.d.ts +4 -0
  240. package/dist/esm/domain/type/number-type.js +12 -0
  241. package/dist/esm/domain/type/required/required-mark.d.ts +9 -0
  242. package/dist/esm/domain/type/required/required-mark.js +9 -0
  243. package/dist/esm/domain/type/required/required.d.ts +7 -0
  244. package/dist/esm/domain/type/required/required.js +18 -0
  245. package/dist/esm/domain/type/string-type.d.ts +4 -0
  246. package/dist/esm/domain/type/string-type.js +12 -0
  247. package/dist/esm/domain/type/uuid-type.d.ts +7 -0
  248. package/dist/esm/domain/type/uuid-type.js +23 -0
  249. package/dist/esm/domain/type/value-objects/value-objects.d.ts +16 -0
  250. package/dist/esm/domain/type/value-objects/value-objects.js +66 -0
  251. package/dist/esm/exceptions/abstract.exception.d.ts +23 -0
  252. package/dist/esm/exceptions/abstract.exception.js +62 -0
  253. package/dist/esm/exceptions/application/aggregate-not-found.exception.d.ts +5 -0
  254. package/dist/esm/exceptions/application/aggregate-not-found.exception.js +13 -0
  255. package/dist/esm/exceptions/application/application.exception.d.ts +6 -0
  256. package/dist/esm/exceptions/application/application.exception.js +13 -0
  257. package/dist/esm/exceptions/application/concurrency.exception.d.ts +5 -0
  258. package/dist/esm/exceptions/application/concurrency.exception.js +13 -0
  259. package/dist/esm/exceptions/application/not-allowed.exception.d.ts +5 -0
  260. package/dist/esm/exceptions/application/not-allowed.exception.js +13 -0
  261. package/dist/esm/exceptions/brand/exception-brand.d.ts +6 -0
  262. package/dist/esm/exceptions/brand/exception-brand.js +25 -0
  263. package/dist/esm/exceptions/domain/domain.exception.d.ts +6 -0
  264. package/dist/esm/exceptions/domain/domain.exception.js +13 -0
  265. package/dist/esm/exceptions/domain/required-value.exception.d.ts +4 -0
  266. package/dist/esm/exceptions/domain/required-value.exception.js +17 -0
  267. package/dist/esm/exceptions/domain/type-primitive.exception.d.ts +4 -0
  268. package/dist/esm/exceptions/domain/type-primitive.exception.js +17 -0
  269. package/dist/esm/exceptions/domain/validation.exception.d.ts +14 -0
  270. package/dist/esm/exceptions/domain/validation.exception.js +19 -0
  271. package/dist/esm/exceptions/exception-code.d.ts +15 -0
  272. package/dist/esm/exceptions/exception-code.js +16 -0
  273. package/dist/esm/exceptions/index.d.ts +14 -0
  274. package/dist/esm/exceptions/index.js +14 -0
  275. package/dist/esm/exceptions/infrastructure/event-delivery.exception.d.ts +5 -0
  276. package/dist/esm/exceptions/infrastructure/event-delivery.exception.js +16 -0
  277. package/dist/esm/exceptions/infrastructure/infrastructure.exception.d.ts +6 -0
  278. package/dist/esm/exceptions/infrastructure/infrastructure.exception.js +13 -0
  279. package/dist/esm/exceptions/infrastructure/internal-error.exception.d.ts +5 -0
  280. package/dist/esm/exceptions/infrastructure/internal-error.exception.js +13 -0
  281. package/dist/esm/exceptions/infrastructure/unknown-event.exception.d.ts +4 -0
  282. package/dist/esm/exceptions/infrastructure/unknown-event.exception.js +15 -0
  283. package/dist/esm/exceptions/received/received-value.d.ts +4 -0
  284. package/dist/esm/exceptions/received/received-value.js +9 -0
  285. package/dist/esm/infrastructure/clock/fixed-clock.d.ts +8 -0
  286. package/dist/esm/infrastructure/clock/fixed-clock.js +15 -0
  287. package/dist/esm/infrastructure/clock/system-clock.d.ts +4 -0
  288. package/dist/esm/infrastructure/clock/system-clock.js +5 -0
  289. package/dist/esm/infrastructure/event/domain-event-bus.d.ts +16 -0
  290. package/dist/esm/infrastructure/event/domain-event-bus.js +56 -0
  291. package/dist/esm/infrastructure/event/event-channel.d.ts +9 -0
  292. package/dist/esm/infrastructure/event/event-channel.js +1 -0
  293. package/dist/esm/infrastructure/event/event-registry.d.ts +9 -0
  294. package/dist/esm/infrastructure/event/event-registry.js +39 -0
  295. package/dist/esm/infrastructure/event/in-memory/emitter.d.ts +11 -0
  296. package/dist/esm/infrastructure/event/in-memory/emitter.js +50 -0
  297. package/dist/esm/infrastructure/event/in-memory/in-memory-event-channel.d.ts +16 -0
  298. package/dist/esm/infrastructure/event/in-memory/in-memory-event-channel.js +47 -0
  299. package/dist/esm/infrastructure/http/http-error-mapper.d.ts +23 -0
  300. package/dist/esm/infrastructure/http/http-error-mapper.js +59 -0
  301. package/dist/esm/infrastructure/index.d.ts +16 -0
  302. package/dist/esm/infrastructure/index.js +9 -0
  303. package/dist/esm/infrastructure/logging/console-logger.d.ts +17 -0
  304. package/dist/esm/infrastructure/logging/console-logger.js +33 -0
  305. package/dist/esm/infrastructure/logging/in-memory-logger.d.ts +15 -0
  306. package/dist/esm/infrastructure/logging/in-memory-logger.js +23 -0
  307. package/dist/esm/infrastructure/logging/log-serializer.d.ts +7 -0
  308. package/dist/esm/infrastructure/logging/log-serializer.js +55 -0
  309. package/dist/esm/infrastructure/logging/silent-logger.d.ts +7 -0
  310. package/dist/esm/infrastructure/logging/silent-logger.js +14 -0
  311. package/dist/esm/package.json +3 -0
  312. package/package.json +106 -4
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Emitter = void 0;
4
+ const index_1 = require("../../../exceptions/index");
5
+ class Emitter {
6
+ constructor() {
7
+ this.events = new Map();
8
+ }
9
+ on(eventName, listener) {
10
+ const listeners = this.events.get(eventName) ?? new Set();
11
+ listeners.add(listener);
12
+ this.events.set(eventName, listeners);
13
+ return () => this.off(eventName, listener);
14
+ }
15
+ off(eventName, listener) {
16
+ const listeners = this.events.get(eventName);
17
+ if (listeners === undefined) {
18
+ return;
19
+ }
20
+ listeners.delete(listener);
21
+ if (listeners.size === 0) {
22
+ this.events.delete(eventName);
23
+ }
24
+ }
25
+ async emit(eventName, data) {
26
+ const listeners = this.listenersOf(eventName);
27
+ const snapshot = Array.from(listeners);
28
+ await Emitter.resolved;
29
+ const results = await Promise.allSettled(snapshot.map(async (listener) => {
30
+ if (listeners.has(listener)) {
31
+ await listener(data);
32
+ }
33
+ }));
34
+ const errors = results.flatMap((result) => result.status === 'rejected' ? [result.reason] : []);
35
+ if (errors.length > 0) {
36
+ throw new index_1.EventDeliveryException(eventName, errors, snapshot.length);
37
+ }
38
+ }
39
+ async emitSerial(eventName, data) {
40
+ const listeners = this.listenersOf(eventName);
41
+ const snapshot = Array.from(listeners);
42
+ await Emitter.resolved;
43
+ for (const listener of snapshot) {
44
+ if (listeners.has(listener)) {
45
+ await listener(data);
46
+ }
47
+ }
48
+ }
49
+ listenersOf(eventName) {
50
+ return this.events.get(eventName) ?? new Set();
51
+ }
52
+ }
53
+ exports.Emitter = Emitter;
54
+ Emitter.resolved = Promise.resolve();
@@ -0,0 +1,16 @@
1
+ import type { ChannelHandler, ChannelSubscription, EventChannel } from '../event-channel';
2
+ import type { SerializedEvent } from '../../../domain/index';
3
+ export interface InMemoryEventChannelOptions {
4
+ readonly delivery?: 'serial' | 'parallel';
5
+ }
6
+ export declare class InMemoryEventChannel implements EventChannel {
7
+ private readonly emitter;
8
+ private readonly receivers;
9
+ private readonly sentEvents;
10
+ private readonly delivery;
11
+ constructor({ delivery }?: InMemoryEventChannelOptions);
12
+ get sent(): readonly SerializedEvent[];
13
+ send(events: readonly SerializedEvent[]): Promise<void>;
14
+ receive(eventName: string, consumer: string, handler: ChannelHandler): Promise<ChannelSubscription>;
15
+ private static frozenCopy;
16
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InMemoryEventChannel = void 0;
4
+ const index_1 = require("../../../domain/index");
5
+ const index_2 = require("../../../exceptions/index");
6
+ const emitter_1 = require("./emitter");
7
+ class InMemoryEventChannel {
8
+ constructor({ delivery = 'serial' } = {}) {
9
+ this.emitter = new emitter_1.Emitter();
10
+ this.receivers = new Set();
11
+ this.sentEvents = [];
12
+ this.delivery = delivery;
13
+ }
14
+ get sent() {
15
+ return [...this.sentEvents];
16
+ }
17
+ async send(events) {
18
+ for (const event of events) {
19
+ const copy = InMemoryEventChannel.frozenCopy(event);
20
+ this.sentEvents.push(copy);
21
+ if (this.delivery === 'parallel') {
22
+ await this.emitter.emit(copy.eventName, copy);
23
+ }
24
+ else {
25
+ await this.emitter.emitSerial(copy.eventName, copy);
26
+ }
27
+ }
28
+ }
29
+ async receive(eventName, consumer, handler) {
30
+ const receiver = JSON.stringify([eventName, consumer]);
31
+ if (this.receivers.has(receiver)) {
32
+ throw new index_2.InfrastructureException(`${consumer} already receives "${eventName}": close its subscription first.`);
33
+ }
34
+ this.receivers.add(receiver);
35
+ const off = this.emitter.on(eventName, (event) => handler(event));
36
+ let open = true;
37
+ return {
38
+ close: async () => {
39
+ if (open) {
40
+ open = false;
41
+ off();
42
+ this.receivers.delete(receiver);
43
+ }
44
+ },
45
+ };
46
+ }
47
+ static frozenCopy(event) {
48
+ return index_1.Immutable.freeze(JSON.parse(JSON.stringify(event)));
49
+ }
50
+ }
51
+ exports.InMemoryEventChannel = InMemoryEventChannel;
@@ -0,0 +1,23 @@
1
+ import type { ValidationIssue } from '../../exceptions';
2
+ import type { Logger } from '../../application/index';
3
+ export interface HttpErrorBody {
4
+ code: string;
5
+ message: string;
6
+ errors?: readonly ValidationIssue[];
7
+ }
8
+ export interface HttpError {
9
+ status: number;
10
+ body: HttpErrorBody;
11
+ }
12
+ export interface HttpErrorMapperOptions {
13
+ readonly statusByCode?: Readonly<Record<string, number>>;
14
+ readonly logger?: Logger;
15
+ }
16
+ export declare class HttpErrorMapper {
17
+ private readonly statusByCode;
18
+ private readonly logger;
19
+ constructor({ statusByCode, logger }?: HttpErrorMapperOptions);
20
+ map(error: unknown): HttpError;
21
+ private toHttpError;
22
+ private static defaultStatus;
23
+ }
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpErrorMapper = void 0;
4
+ const exceptions_1 = require("../../exceptions");
5
+ const silent_logger_1 = require("../logging/silent-logger");
6
+ const INTERNAL_MESSAGE = 'Internal server error';
7
+ class HttpErrorMapper {
8
+ constructor({ statusByCode = {}, logger = new silent_logger_1.SilentLogger() } = {}) {
9
+ this.statusByCode = statusByCode;
10
+ this.logger = logger;
11
+ }
12
+ map(error) {
13
+ const mapped = this.toHttpError(error);
14
+ const { status, body } = mapped;
15
+ if (status >= 500) {
16
+ this.logger.error('http_request_failed', { status, code: body.code, error });
17
+ }
18
+ else {
19
+ this.logger.debug('http_request_rejected', { status, code: body.code });
20
+ }
21
+ return mapped;
22
+ }
23
+ toHttpError(error) {
24
+ if (!(error instanceof exceptions_1.AbstractException)) {
25
+ return {
26
+ status: 500,
27
+ body: { code: exceptions_1.ExceptionCode.ErrorException, message: INTERNAL_MESSAGE },
28
+ };
29
+ }
30
+ const status = Object.prototype.hasOwnProperty.call(this.statusByCode, error.code)
31
+ ? this.statusByCode[error.code]
32
+ : HttpErrorMapper.defaultStatus(error);
33
+ if (status >= 500) {
34
+ return { status, body: { code: error.code, message: INTERNAL_MESSAGE } };
35
+ }
36
+ if (error instanceof exceptions_1.ValidationException) {
37
+ return { status, body: { code: error.code, message: error.message, errors: error.errors } };
38
+ }
39
+ return { status, body: { code: error.code, message: error.message } };
40
+ }
41
+ static defaultStatus(error) {
42
+ if (error instanceof exceptions_1.AggregateNotFoundException) {
43
+ return 404;
44
+ }
45
+ if (error instanceof exceptions_1.NotAllowedException) {
46
+ return 403;
47
+ }
48
+ if (error instanceof exceptions_1.ConcurrencyException) {
49
+ return 409;
50
+ }
51
+ if (error instanceof exceptions_1.TypePrimitiveException || error instanceof exceptions_1.RequiredValueException) {
52
+ return 400;
53
+ }
54
+ if (error instanceof exceptions_1.DomainException) {
55
+ return 422;
56
+ }
57
+ if (error instanceof exceptions_1.ApplicationException) {
58
+ return 400;
59
+ }
60
+ return 500;
61
+ }
62
+ }
63
+ exports.HttpErrorMapper = HttpErrorMapper;
@@ -0,0 +1,16 @@
1
+ export { SystemClock } from './clock/system-clock';
2
+ export { FixedClock } from './clock/fixed-clock';
3
+ export { DomainEventBus } from './event/domain-event-bus';
4
+ export type { Subscription } from './event/domain-event-bus';
5
+ export { EventRegistry } from './event/event-registry';
6
+ export type { EventFactory } from './event/event-registry';
7
+ export type { ChannelHandler, ChannelSubscription, EventChannel } from './event/event-channel';
8
+ export { InMemoryEventChannel } from './event/in-memory/in-memory-event-channel';
9
+ export type { InMemoryEventChannelOptions } from './event/in-memory/in-memory-event-channel';
10
+ export { HttpErrorMapper } from './http/http-error-mapper';
11
+ export type { HttpError, HttpErrorBody, HttpErrorMapperOptions } from './http/http-error-mapper';
12
+ export { ConsoleLogger } from './logging/console-logger';
13
+ export type { ConsoleLoggerOptions } from './logging/console-logger';
14
+ export { InMemoryLogger } from './logging/in-memory-logger';
15
+ export type { LogEntry } from './logging/in-memory-logger';
16
+ export { SilentLogger } from './logging/silent-logger';
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SilentLogger = exports.InMemoryLogger = exports.ConsoleLogger = exports.HttpErrorMapper = exports.InMemoryEventChannel = exports.EventRegistry = exports.DomainEventBus = exports.FixedClock = exports.SystemClock = void 0;
4
+ var system_clock_1 = require("./clock/system-clock");
5
+ Object.defineProperty(exports, "SystemClock", { enumerable: true, get: function () { return system_clock_1.SystemClock; } });
6
+ var fixed_clock_1 = require("./clock/fixed-clock");
7
+ Object.defineProperty(exports, "FixedClock", { enumerable: true, get: function () { return fixed_clock_1.FixedClock; } });
8
+ var domain_event_bus_1 = require("./event/domain-event-bus");
9
+ Object.defineProperty(exports, "DomainEventBus", { enumerable: true, get: function () { return domain_event_bus_1.DomainEventBus; } });
10
+ var event_registry_1 = require("./event/event-registry");
11
+ Object.defineProperty(exports, "EventRegistry", { enumerable: true, get: function () { return event_registry_1.EventRegistry; } });
12
+ var in_memory_event_channel_1 = require("./event/in-memory/in-memory-event-channel");
13
+ Object.defineProperty(exports, "InMemoryEventChannel", { enumerable: true, get: function () { return in_memory_event_channel_1.InMemoryEventChannel; } });
14
+ var http_error_mapper_1 = require("./http/http-error-mapper");
15
+ Object.defineProperty(exports, "HttpErrorMapper", { enumerable: true, get: function () { return http_error_mapper_1.HttpErrorMapper; } });
16
+ var console_logger_1 = require("./logging/console-logger");
17
+ Object.defineProperty(exports, "ConsoleLogger", { enumerable: true, get: function () { return console_logger_1.ConsoleLogger; } });
18
+ var in_memory_logger_1 = require("./logging/in-memory-logger");
19
+ Object.defineProperty(exports, "InMemoryLogger", { enumerable: true, get: function () { return in_memory_logger_1.InMemoryLogger; } });
20
+ var silent_logger_1 = require("./logging/silent-logger");
21
+ Object.defineProperty(exports, "SilentLogger", { enumerable: true, get: function () { return silent_logger_1.SilentLogger; } });
@@ -0,0 +1,17 @@
1
+ import type { Clock, LogContext, Logger, LogLevel } from '../../application/index';
2
+ export interface ConsoleLoggerOptions {
3
+ readonly level?: LogLevel;
4
+ readonly clock?: Clock;
5
+ }
6
+ export declare class ConsoleLogger implements Logger {
7
+ private static readonly levels;
8
+ private readonly output;
9
+ private readonly minimum;
10
+ private readonly clock;
11
+ constructor({ level, clock }?: ConsoleLoggerOptions);
12
+ debug(message: string, context?: LogContext): void;
13
+ info(message: string, context?: LogContext): void;
14
+ warn(message: string, context?: LogContext): void;
15
+ error(message: string, context?: LogContext): void;
16
+ private write;
17
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConsoleLogger = void 0;
4
+ const index_1 = require("../../exceptions/index");
5
+ const system_clock_1 = require("../clock/system-clock");
6
+ const log_serializer_1 = require("./log-serializer");
7
+ class ConsoleLogger {
8
+ constructor({ level = 'info', clock = new system_clock_1.SystemClock() } = {}) {
9
+ this.output = console;
10
+ this.minimum = ConsoleLogger.levels.indexOf(level);
11
+ if (this.minimum === -1) {
12
+ throw new index_1.InternalErrorException(`unknown log level "${String(level)}": use ${ConsoleLogger.levels.join(', ')}`);
13
+ }
14
+ this.clock = clock;
15
+ }
16
+ debug(message, context) {
17
+ this.write('debug', message, context);
18
+ }
19
+ info(message, context) {
20
+ this.write('info', message, context);
21
+ }
22
+ warn(message, context) {
23
+ this.write('warn', message, context);
24
+ }
25
+ error(message, context) {
26
+ this.write('error', message, context);
27
+ }
28
+ write(level, message, context) {
29
+ if (ConsoleLogger.levels.indexOf(level) < this.minimum) {
30
+ return;
31
+ }
32
+ const entry = { time: this.clock.now().toISOString(), level, message };
33
+ this.output[level](log_serializer_1.LogSerializer.line(entry, context));
34
+ }
35
+ }
36
+ exports.ConsoleLogger = ConsoleLogger;
37
+ ConsoleLogger.levels = ['debug', 'info', 'warn', 'error'];
@@ -0,0 +1,15 @@
1
+ import type { LogContext, Logger, LogLevel } from '../../application/index';
2
+ export interface LogEntry {
3
+ readonly level: LogLevel;
4
+ readonly message: string;
5
+ readonly context?: LogContext;
6
+ }
7
+ export declare class InMemoryLogger implements Logger {
8
+ private readonly recorded;
9
+ get entries(): readonly LogEntry[];
10
+ debug(message: string, context?: LogContext): void;
11
+ info(message: string, context?: LogContext): void;
12
+ warn(message: string, context?: LogContext): void;
13
+ error(message: string, context?: LogContext): void;
14
+ private record;
15
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InMemoryLogger = void 0;
4
+ class InMemoryLogger {
5
+ constructor() {
6
+ this.recorded = [];
7
+ }
8
+ get entries() {
9
+ return [...this.recorded];
10
+ }
11
+ debug(message, context) {
12
+ this.record('debug', message, context);
13
+ }
14
+ info(message, context) {
15
+ this.record('info', message, context);
16
+ }
17
+ warn(message, context) {
18
+ this.record('warn', message, context);
19
+ }
20
+ error(message, context) {
21
+ this.record('error', message, context);
22
+ }
23
+ record(level, message, context) {
24
+ this.recorded.push(context === undefined ? { level, message } : { level, message, context });
25
+ }
26
+ }
27
+ exports.InMemoryLogger = InMemoryLogger;
@@ -0,0 +1,7 @@
1
+ import type { LogContext } from '../../application/index';
2
+ export declare class LogSerializer {
3
+ static line(entry: Readonly<Record<string, string>>, context: LogContext | undefined): string;
4
+ private static plain;
5
+ private static plainObject;
6
+ private static plainError;
7
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LogSerializer = void 0;
4
+ class LogSerializer {
5
+ static line(entry, context) {
6
+ if (context === undefined) {
7
+ return JSON.stringify(entry);
8
+ }
9
+ try {
10
+ return JSON.stringify({ ...entry, context: LogSerializer.plain(context, new Set()) });
11
+ }
12
+ catch {
13
+ return JSON.stringify({ ...entry, context: '[Unserializable]' });
14
+ }
15
+ }
16
+ static plain(value, ancestors) {
17
+ if (typeof value === 'bigint') {
18
+ return value.toString();
19
+ }
20
+ if (typeof value !== 'object' || value === null) {
21
+ return value;
22
+ }
23
+ if (ancestors.has(value)) {
24
+ return '[Circular]';
25
+ }
26
+ ancestors.add(value);
27
+ try {
28
+ return LogSerializer.plainObject(value, ancestors);
29
+ }
30
+ finally {
31
+ ancestors.delete(value);
32
+ }
33
+ }
34
+ static plainObject(value, ancestors) {
35
+ if (value instanceof Error) {
36
+ return LogSerializer.plainError(value, ancestors);
37
+ }
38
+ if (Array.isArray(value)) {
39
+ return value.map((item) => LogSerializer.plain(item, ancestors));
40
+ }
41
+ const { toJSON } = value;
42
+ if (typeof toJSON === 'function') {
43
+ return LogSerializer.plain(toJSON.call(value), ancestors);
44
+ }
45
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, LogSerializer.plain(item, ancestors)]));
46
+ }
47
+ static plainError(error, ancestors) {
48
+ const { code, errors, cause } = error;
49
+ return {
50
+ name: error.name,
51
+ message: error.message,
52
+ ...(typeof code === 'string' ? { code } : {}),
53
+ ...(Array.isArray(errors) ? { errors: LogSerializer.plain(errors, ancestors) } : {}),
54
+ ...(error.stack === undefined ? {} : { stack: error.stack }),
55
+ ...(cause === undefined ? {} : { cause: LogSerializer.plain(cause, ancestors) }),
56
+ };
57
+ }
58
+ }
59
+ exports.LogSerializer = LogSerializer;
@@ -0,0 +1,7 @@
1
+ import type { Logger } from '../../application/index';
2
+ export declare class SilentLogger implements Logger {
3
+ debug(): void;
4
+ info(): void;
5
+ warn(): void;
6
+ error(): void;
7
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SilentLogger = void 0;
4
+ class SilentLogger {
5
+ debug() {
6
+ return undefined;
7
+ }
8
+ info() {
9
+ return undefined;
10
+ }
11
+ warn() {
12
+ return undefined;
13
+ }
14
+ error() {
15
+ return undefined;
16
+ }
17
+ }
18
+ exports.SilentLogger = SilentLogger;
@@ -0,0 +1,4 @@
1
+ import type { EventBase } from '../../domain/index.js';
2
+ export interface EventBus<Event extends EventBase = EventBase> {
3
+ publish(events: readonly Event[]): Promise<void>;
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { EventBase } from '../../domain/index.js';
2
+ export declare abstract class EventListener<Event extends EventBase = EventBase> {
3
+ abstract handle(event: Event): Promise<void> | void;
4
+ }
@@ -0,0 +1,2 @@
1
+ export class EventListener {
2
+ }
@@ -0,0 +1,15 @@
1
+ import type { EventBase, EventClass } from '../../domain/index.js';
2
+ import type { EventListener } from './event-listener.js';
3
+ type ListenerClass<Event extends EventBase> = abstract new (...args: any[]) => EventListener<Event>;
4
+ export interface ListensToOptions {
5
+ readonly consumer: string;
6
+ }
7
+ export interface ListenerSubscription {
8
+ readonly eventName: string;
9
+ readonly consumer: string;
10
+ }
11
+ export declare function ListensTo<Event extends EventBase>(event: EventClass<Event>, options: ListensToOptions): (listener: ListenerClass<Event>) => void;
12
+ export declare namespace ListensTo {
13
+ var subscriptionOf: (listener: EventListener<any>) => ListenerSubscription;
14
+ }
15
+ export {};
@@ -0,0 +1,25 @@
1
+ import { ApplicationException } from '../../exceptions/index.js';
2
+ const LISTENED_EVENT = Symbol.for('@archi-code/ddd/listens-to.v1');
3
+ export function ListensTo(event, options) {
4
+ return (listener) => {
5
+ if (Object.prototype.hasOwnProperty.call(listener, LISTENED_EVENT)) {
6
+ throw new ApplicationException(`${listener.name} already listens to an event`);
7
+ }
8
+ const consumer = options?.consumer;
9
+ if (typeof consumer !== 'string' || consumer.trim() === '') {
10
+ throw new ApplicationException(`${listener.name} needs a consumer name: @ListensTo(<event class>, { consumer: '<name>' })`);
11
+ }
12
+ const subscription = Object.freeze({
13
+ eventName: event.eventName,
14
+ consumer,
15
+ });
16
+ Object.defineProperty(listener, LISTENED_EVENT, { value: subscription });
17
+ };
18
+ }
19
+ ListensTo.subscriptionOf = (listener) => {
20
+ const listenerClass = listener.constructor;
21
+ if (!Object.prototype.hasOwnProperty.call(listenerClass, LISTENED_EVENT)) {
22
+ throw new ApplicationException(`${listenerClass.name} needs @ListensTo(<event class>, { consumer: '<name>' })`);
23
+ }
24
+ return listenerClass[LISTENED_EVENT];
25
+ };
@@ -0,0 +1,7 @@
1
+ export { UseCase } from './use-case/use-case.js';
2
+ export { EventListener } from './event/event-listener.js';
3
+ export { ListensTo } from './event/listens-to.js';
4
+ export type { ListenerSubscription, ListensToOptions } from './event/listens-to.js';
5
+ export type { EventBus } from './event/event-bus.js';
6
+ export type { Clock } from './ports/clock.js';
7
+ export type { LogContext, Logger, LogLevel } from './ports/logger.js';
@@ -0,0 +1,3 @@
1
+ export { UseCase } from './use-case/use-case.js';
2
+ export { EventListener } from './event/event-listener.js';
3
+ export { ListensTo } from './event/listens-to.js';
@@ -0,0 +1,3 @@
1
+ export interface Clock {
2
+ now(): Date;
3
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
2
+ export type LogContext = Readonly<Record<string, unknown>>;
3
+ export interface Logger {
4
+ debug(message: string, context?: LogContext): void;
5
+ info(message: string, context?: LogContext): void;
6
+ warn(message: string, context?: LogContext): void;
7
+ error(message: string, context?: LogContext): void;
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ export declare abstract class UseCase<Input, Command, Output> {
2
+ execute(input: Input): Promise<Output>;
3
+ protected abstract toCommand(input: Input): Command;
4
+ protected abstract handle(command: Command): Promise<Output> | Output;
5
+ private static describe;
6
+ }
@@ -0,0 +1,20 @@
1
+ import { anyToString } from '@archi-code/validation';
2
+ import { AbstractException, InternalErrorException } from '../../exceptions/index.js';
3
+ export class UseCase {
4
+ async execute(input) {
5
+ try {
6
+ return await this.handle(this.toCommand(input));
7
+ }
8
+ catch (error) {
9
+ if (error instanceof AbstractException) {
10
+ throw error;
11
+ }
12
+ throw new InternalErrorException(`${this.constructor.name}: ${UseCase.describe(error)}`, {
13
+ cause: error,
14
+ });
15
+ }
16
+ }
17
+ static describe(error) {
18
+ return error instanceof Error ? error.message : anyToString(error);
19
+ }
20
+ }
@@ -0,0 +1,14 @@
1
+ import { Entity } from '../entity/entity.js';
2
+ import type { EntityId } from '../entity/entity.js';
3
+ import type { EventBase } from '../event/event-base.js';
4
+ import type { IdType } from '../type/id-type.js';
5
+ export declare abstract class AggregateRoot<Id extends EntityId = IdType, Event extends EventBase = EventBase> extends Entity<Id> {
6
+ private readonly domainEvents;
7
+ private persistedVersion;
8
+ constructor(id: Id);
9
+ get version(): number;
10
+ protected record(event: Event): void;
11
+ pullDomainEvents(): Event[];
12
+ restoreVersion(version: number): this;
13
+ markPersisted(): void;
14
+ }
@@ -0,0 +1,29 @@
1
+ import { Entity } from '../entity/entity.js';
2
+ import { Immutable } from '../type/immutable/immutable.js';
3
+ import { InternalErrorException } from '../../exceptions/index.js';
4
+ export class AggregateRoot extends Entity {
5
+ constructor(id) {
6
+ super(id);
7
+ Object.defineProperty(this, 'domainEvents', { value: [] });
8
+ Object.defineProperty(this, 'persistedVersion', { value: 0, writable: true });
9
+ }
10
+ get version() {
11
+ return this.persistedVersion;
12
+ }
13
+ record(event) {
14
+ this.domainEvents.push(Immutable.freeze(event));
15
+ }
16
+ pullDomainEvents() {
17
+ return this.domainEvents.splice(0);
18
+ }
19
+ restoreVersion(version) {
20
+ if (!Number.isSafeInteger(version) || version < 0) {
21
+ throw new InternalErrorException(`${this.constructor.name} cannot be restored with version ${String(version)}`);
22
+ }
23
+ this.persistedVersion = version;
24
+ return this;
25
+ }
26
+ markPersisted() {
27
+ this.persistedVersion += 1;
28
+ }
29
+ }
@@ -0,0 +1,9 @@
1
+ import type { AbstractType } from '../type/abstract-type.js';
2
+ import type { IdType } from '../type/id-type.js';
3
+ import type { RequiredMarked } from '../type/required/required-mark.js';
4
+ export type EntityId = AbstractType<any> & RequiredMarked;
5
+ export declare abstract class Entity<Id extends EntityId = IdType> {
6
+ readonly id: Id;
7
+ constructor(id: Id);
8
+ equals(other: unknown): boolean;
9
+ }
@@ -0,0 +1,15 @@
1
+ import { RequiredValueException } from '../../exceptions/index.js';
2
+ export class Entity {
3
+ constructor(id) {
4
+ this.id = id;
5
+ if (id?.isNull !== false) {
6
+ throw new RequiredValueException(`${new.target.name}.id`, id?.value);
7
+ }
8
+ }
9
+ equals(other) {
10
+ return (typeof other === 'object' &&
11
+ other !== null &&
12
+ other.constructor === this.constructor &&
13
+ this.id.equals(other.id));
14
+ }
15
+ }