nestlens 0.1.0

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 (359) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +145 -0
  3. package/dist/__tests__/api/api.controller.spec.d.ts +2 -0
  4. package/dist/__tests__/api/api.controller.spec.d.ts.map +1 -0
  5. package/dist/__tests__/api/api.controller.spec.js +982 -0
  6. package/dist/__tests__/api/api.controller.spec.js.map +1 -0
  7. package/dist/__tests__/api/api.guard.spec.d.ts +2 -0
  8. package/dist/__tests__/api/api.guard.spec.d.ts.map +1 -0
  9. package/dist/__tests__/api/api.guard.spec.js +572 -0
  10. package/dist/__tests__/api/api.guard.spec.js.map +1 -0
  11. package/dist/__tests__/api/dashboard.controller.spec.d.ts +2 -0
  12. package/dist/__tests__/api/dashboard.controller.spec.d.ts.map +1 -0
  13. package/dist/__tests__/api/dashboard.controller.spec.js +474 -0
  14. package/dist/__tests__/api/dashboard.controller.spec.js.map +1 -0
  15. package/dist/__tests__/api/tag.controller.spec.d.ts +2 -0
  16. package/dist/__tests__/api/tag.controller.spec.d.ts.map +1 -0
  17. package/dist/__tests__/api/tag.controller.spec.js +280 -0
  18. package/dist/__tests__/api/tag.controller.spec.js.map +1 -0
  19. package/dist/__tests__/collector.service.spec.d.ts +2 -0
  20. package/dist/__tests__/collector.service.spec.d.ts.map +1 -0
  21. package/dist/__tests__/collector.service.spec.js +240 -0
  22. package/dist/__tests__/collector.service.spec.js.map +1 -0
  23. package/dist/__tests__/core/collector.service.spec.d.ts +2 -0
  24. package/dist/__tests__/core/collector.service.spec.d.ts.map +1 -0
  25. package/dist/__tests__/core/collector.service.spec.js +526 -0
  26. package/dist/__tests__/core/collector.service.spec.js.map +1 -0
  27. package/dist/__tests__/core/family-hash.service.spec.d.ts +2 -0
  28. package/dist/__tests__/core/family-hash.service.spec.d.ts.map +1 -0
  29. package/dist/__tests__/core/family-hash.service.spec.js +1117 -0
  30. package/dist/__tests__/core/family-hash.service.spec.js.map +1 -0
  31. package/dist/__tests__/core/pruning.service.spec.d.ts +2 -0
  32. package/dist/__tests__/core/pruning.service.spec.d.ts.map +1 -0
  33. package/dist/__tests__/core/pruning.service.spec.js +224 -0
  34. package/dist/__tests__/core/pruning.service.spec.js.map +1 -0
  35. package/dist/__tests__/core/storage/sqlite.storage.spec.d.ts +2 -0
  36. package/dist/__tests__/core/storage/sqlite.storage.spec.d.ts.map +1 -0
  37. package/dist/__tests__/core/storage/sqlite.storage.spec.js +853 -0
  38. package/dist/__tests__/core/storage/sqlite.storage.spec.js.map +1 -0
  39. package/dist/__tests__/core/tag.service.spec.d.ts +2 -0
  40. package/dist/__tests__/core/tag.service.spec.d.ts.map +1 -0
  41. package/dist/__tests__/core/tag.service.spec.js +994 -0
  42. package/dist/__tests__/core/tag.service.spec.js.map +1 -0
  43. package/dist/__tests__/family-hash.service.spec.d.ts +2 -0
  44. package/dist/__tests__/family-hash.service.spec.d.ts.map +1 -0
  45. package/dist/__tests__/family-hash.service.spec.js +325 -0
  46. package/dist/__tests__/family-hash.service.spec.js.map +1 -0
  47. package/dist/__tests__/filters/api-filters.spec.d.ts +2 -0
  48. package/dist/__tests__/filters/api-filters.spec.d.ts.map +1 -0
  49. package/dist/__tests__/filters/api-filters.spec.js +172 -0
  50. package/dist/__tests__/filters/api-filters.spec.js.map +1 -0
  51. package/dist/__tests__/filters/entry-factories.d.ts +20 -0
  52. package/dist/__tests__/filters/entry-factories.d.ts.map +1 -0
  53. package/dist/__tests__/filters/entry-factories.js +288 -0
  54. package/dist/__tests__/filters/entry-factories.js.map +1 -0
  55. package/dist/__tests__/filters/filter-contract.spec.d.ts +2 -0
  56. package/dist/__tests__/filters/filter-contract.spec.d.ts.map +1 -0
  57. package/dist/__tests__/filters/filter-contract.spec.js +230 -0
  58. package/dist/__tests__/filters/filter-contract.spec.js.map +1 -0
  59. package/dist/__tests__/filters/filter-test-data.d.ts +26 -0
  60. package/dist/__tests__/filters/filter-test-data.d.ts.map +1 -0
  61. package/dist/__tests__/filters/filter-test-data.js +374 -0
  62. package/dist/__tests__/filters/filter-test-data.js.map +1 -0
  63. package/dist/__tests__/filters/storage-filters.spec.d.ts +2 -0
  64. package/dist/__tests__/filters/storage-filters.spec.d.ts.map +1 -0
  65. package/dist/__tests__/filters/storage-filters.spec.js +699 -0
  66. package/dist/__tests__/filters/storage-filters.spec.js.map +1 -0
  67. package/dist/__tests__/filters/test-utils.d.ts +23 -0
  68. package/dist/__tests__/filters/test-utils.d.ts.map +1 -0
  69. package/dist/__tests__/filters/test-utils.js +54 -0
  70. package/dist/__tests__/filters/test-utils.js.map +1 -0
  71. package/dist/__tests__/nestlens.module.spec.d.ts +2 -0
  72. package/dist/__tests__/nestlens.module.spec.d.ts.map +1 -0
  73. package/dist/__tests__/nestlens.module.spec.js +620 -0
  74. package/dist/__tests__/nestlens.module.spec.js.map +1 -0
  75. package/dist/__tests__/pruning.service.spec.d.ts +2 -0
  76. package/dist/__tests__/pruning.service.spec.d.ts.map +1 -0
  77. package/dist/__tests__/pruning.service.spec.js +142 -0
  78. package/dist/__tests__/pruning.service.spec.js.map +1 -0
  79. package/dist/__tests__/setup.d.ts +7 -0
  80. package/dist/__tests__/setup.d.ts.map +1 -0
  81. package/dist/__tests__/setup.js +24 -0
  82. package/dist/__tests__/setup.js.map +1 -0
  83. package/dist/__tests__/tag.service.spec.d.ts +2 -0
  84. package/dist/__tests__/tag.service.spec.d.ts.map +1 -0
  85. package/dist/__tests__/tag.service.spec.js +482 -0
  86. package/dist/__tests__/tag.service.spec.js.map +1 -0
  87. package/dist/__tests__/watchers/batch.watcher.spec.d.ts +2 -0
  88. package/dist/__tests__/watchers/batch.watcher.spec.d.ts.map +1 -0
  89. package/dist/__tests__/watchers/batch.watcher.spec.js +515 -0
  90. package/dist/__tests__/watchers/batch.watcher.spec.js.map +1 -0
  91. package/dist/__tests__/watchers/cache.watcher.spec.d.ts +2 -0
  92. package/dist/__tests__/watchers/cache.watcher.spec.d.ts.map +1 -0
  93. package/dist/__tests__/watchers/cache.watcher.spec.js +395 -0
  94. package/dist/__tests__/watchers/cache.watcher.spec.js.map +1 -0
  95. package/dist/__tests__/watchers/command.watcher.spec.d.ts +2 -0
  96. package/dist/__tests__/watchers/command.watcher.spec.d.ts.map +1 -0
  97. package/dist/__tests__/watchers/command.watcher.spec.js +598 -0
  98. package/dist/__tests__/watchers/command.watcher.spec.js.map +1 -0
  99. package/dist/__tests__/watchers/dump.watcher.spec.d.ts +2 -0
  100. package/dist/__tests__/watchers/dump.watcher.spec.d.ts.map +1 -0
  101. package/dist/__tests__/watchers/dump.watcher.spec.js +724 -0
  102. package/dist/__tests__/watchers/dump.watcher.spec.js.map +1 -0
  103. package/dist/__tests__/watchers/event.watcher.spec.d.ts +2 -0
  104. package/dist/__tests__/watchers/event.watcher.spec.d.ts.map +1 -0
  105. package/dist/__tests__/watchers/event.watcher.spec.js +316 -0
  106. package/dist/__tests__/watchers/event.watcher.spec.js.map +1 -0
  107. package/dist/__tests__/watchers/exception.watcher.spec.d.ts +2 -0
  108. package/dist/__tests__/watchers/exception.watcher.spec.d.ts.map +1 -0
  109. package/dist/__tests__/watchers/exception.watcher.spec.js +495 -0
  110. package/dist/__tests__/watchers/exception.watcher.spec.js.map +1 -0
  111. package/dist/__tests__/watchers/gate.watcher.spec.d.ts +2 -0
  112. package/dist/__tests__/watchers/gate.watcher.spec.d.ts.map +1 -0
  113. package/dist/__tests__/watchers/gate.watcher.spec.js +683 -0
  114. package/dist/__tests__/watchers/gate.watcher.spec.js.map +1 -0
  115. package/dist/__tests__/watchers/http-client.watcher.spec.d.ts +2 -0
  116. package/dist/__tests__/watchers/http-client.watcher.spec.d.ts.map +1 -0
  117. package/dist/__tests__/watchers/http-client.watcher.spec.js +888 -0
  118. package/dist/__tests__/watchers/http-client.watcher.spec.js.map +1 -0
  119. package/dist/__tests__/watchers/job.watcher.spec.d.ts +2 -0
  120. package/dist/__tests__/watchers/job.watcher.spec.d.ts.map +1 -0
  121. package/dist/__tests__/watchers/job.watcher.spec.js +513 -0
  122. package/dist/__tests__/watchers/job.watcher.spec.js.map +1 -0
  123. package/dist/__tests__/watchers/log.watcher.spec.d.ts +2 -0
  124. package/dist/__tests__/watchers/log.watcher.spec.d.ts.map +1 -0
  125. package/dist/__tests__/watchers/log.watcher.spec.js +428 -0
  126. package/dist/__tests__/watchers/log.watcher.spec.js.map +1 -0
  127. package/dist/__tests__/watchers/mail.watcher.spec.d.ts +2 -0
  128. package/dist/__tests__/watchers/mail.watcher.spec.d.ts.map +1 -0
  129. package/dist/__tests__/watchers/mail.watcher.spec.js +425 -0
  130. package/dist/__tests__/watchers/mail.watcher.spec.js.map +1 -0
  131. package/dist/__tests__/watchers/model.watcher.spec.d.ts +2 -0
  132. package/dist/__tests__/watchers/model.watcher.spec.d.ts.map +1 -0
  133. package/dist/__tests__/watchers/model.watcher.spec.js +675 -0
  134. package/dist/__tests__/watchers/model.watcher.spec.js.map +1 -0
  135. package/dist/__tests__/watchers/notification.watcher.spec.d.ts +2 -0
  136. package/dist/__tests__/watchers/notification.watcher.spec.d.ts.map +1 -0
  137. package/dist/__tests__/watchers/notification.watcher.spec.js +595 -0
  138. package/dist/__tests__/watchers/notification.watcher.spec.js.map +1 -0
  139. package/dist/__tests__/watchers/query/types.spec.d.ts +2 -0
  140. package/dist/__tests__/watchers/query/types.spec.d.ts.map +1 -0
  141. package/dist/__tests__/watchers/query/types.spec.js +292 -0
  142. package/dist/__tests__/watchers/query/types.spec.js.map +1 -0
  143. package/dist/__tests__/watchers/query.watcher.spec.d.ts +2 -0
  144. package/dist/__tests__/watchers/query.watcher.spec.d.ts.map +1 -0
  145. package/dist/__tests__/watchers/query.watcher.spec.js +597 -0
  146. package/dist/__tests__/watchers/query.watcher.spec.js.map +1 -0
  147. package/dist/__tests__/watchers/redis.watcher.spec.d.ts +2 -0
  148. package/dist/__tests__/watchers/redis.watcher.spec.d.ts.map +1 -0
  149. package/dist/__tests__/watchers/redis.watcher.spec.js +634 -0
  150. package/dist/__tests__/watchers/redis.watcher.spec.js.map +1 -0
  151. package/dist/__tests__/watchers/request.watcher.spec.d.ts +2 -0
  152. package/dist/__tests__/watchers/request.watcher.spec.d.ts.map +1 -0
  153. package/dist/__tests__/watchers/request.watcher.spec.js +1017 -0
  154. package/dist/__tests__/watchers/request.watcher.spec.js.map +1 -0
  155. package/dist/__tests__/watchers/schedule.watcher.spec.d.ts +2 -0
  156. package/dist/__tests__/watchers/schedule.watcher.spec.d.ts.map +1 -0
  157. package/dist/__tests__/watchers/schedule.watcher.spec.js +338 -0
  158. package/dist/__tests__/watchers/schedule.watcher.spec.js.map +1 -0
  159. package/dist/__tests__/watchers/view.watcher.spec.d.ts +2 -0
  160. package/dist/__tests__/watchers/view.watcher.spec.d.ts.map +1 -0
  161. package/dist/__tests__/watchers/view.watcher.spec.js +564 -0
  162. package/dist/__tests__/watchers/view.watcher.spec.js.map +1 -0
  163. package/dist/api/api.controller.d.ts +193 -0
  164. package/dist/api/api.controller.d.ts.map +1 -0
  165. package/dist/api/api.controller.js +562 -0
  166. package/dist/api/api.controller.js.map +1 -0
  167. package/dist/api/api.guard.d.ts +77 -0
  168. package/dist/api/api.guard.d.ts.map +1 -0
  169. package/dist/api/api.guard.js +294 -0
  170. package/dist/api/api.guard.js.map +1 -0
  171. package/dist/api/dashboard.controller.d.ts +49 -0
  172. package/dist/api/dashboard.controller.d.ts.map +1 -0
  173. package/dist/api/dashboard.controller.js +472 -0
  174. package/dist/api/dashboard.controller.js.map +1 -0
  175. package/dist/api/index.d.ts +5 -0
  176. package/dist/api/index.d.ts.map +1 -0
  177. package/dist/api/index.js +21 -0
  178. package/dist/api/index.js.map +1 -0
  179. package/dist/api/tag.controller.d.ts +65 -0
  180. package/dist/api/tag.controller.d.ts.map +1 -0
  181. package/dist/api/tag.controller.js +149 -0
  182. package/dist/api/tag.controller.js.map +1 -0
  183. package/dist/core/collector.service.d.ts +80 -0
  184. package/dist/core/collector.service.d.ts.map +1 -0
  185. package/dist/core/collector.service.js +255 -0
  186. package/dist/core/collector.service.js.map +1 -0
  187. package/dist/core/family-hash.service.d.ts +64 -0
  188. package/dist/core/family-hash.service.d.ts.map +1 -0
  189. package/dist/core/family-hash.service.js +281 -0
  190. package/dist/core/family-hash.service.js.map +1 -0
  191. package/dist/core/index.d.ts +4 -0
  192. package/dist/core/index.d.ts.map +1 -0
  193. package/dist/core/index.js +20 -0
  194. package/dist/core/index.js.map +1 -0
  195. package/dist/core/pruning.service.d.ts +16 -0
  196. package/dist/core/pruning.service.d.ts.map +1 -0
  197. package/dist/core/pruning.service.js +71 -0
  198. package/dist/core/pruning.service.js.map +1 -0
  199. package/dist/core/storage/index.d.ts +3 -0
  200. package/dist/core/storage/index.d.ts.map +1 -0
  201. package/dist/core/storage/index.js +19 -0
  202. package/dist/core/storage/index.js.map +1 -0
  203. package/dist/core/storage/sqlite.storage.d.ts +60 -0
  204. package/dist/core/storage/sqlite.storage.d.ts.map +1 -0
  205. package/dist/core/storage/sqlite.storage.js +929 -0
  206. package/dist/core/storage/sqlite.storage.js.map +1 -0
  207. package/dist/core/storage/storage.interface.d.ts +122 -0
  208. package/dist/core/storage/storage.interface.d.ts.map +1 -0
  209. package/dist/core/storage/storage.interface.js +5 -0
  210. package/dist/core/storage/storage.interface.js.map +1 -0
  211. package/dist/core/tag.service.d.ts +71 -0
  212. package/dist/core/tag.service.d.ts.map +1 -0
  213. package/dist/core/tag.service.js +568 -0
  214. package/dist/core/tag.service.js.map +1 -0
  215. package/dist/dashboard/public/assets/BatchesPage-DFT4fKlJ.js +1 -0
  216. package/dist/dashboard/public/assets/CachePage-CRy1Tjb8.js +1 -0
  217. package/dist/dashboard/public/assets/ClickableBadge-CV5J3THx.js +1 -0
  218. package/dist/dashboard/public/assets/CommandsPage-DdRnTm-W.js +1 -0
  219. package/dist/dashboard/public/assets/DashboardPage-CjaRZXYy.js +26 -0
  220. package/dist/dashboard/public/assets/DataTable-B6o9H8lh.js +88 -0
  221. package/dist/dashboard/public/assets/DumpsPage-DO8y1RTg.js +1 -0
  222. package/dist/dashboard/public/assets/EntryDetailPage-By-YcAGL.js +125 -0
  223. package/dist/dashboard/public/assets/EventsPage-u-r4AiT4.js +1 -0
  224. package/dist/dashboard/public/assets/ExceptionsPage-DXUcARr1.js +6 -0
  225. package/dist/dashboard/public/assets/GatesPage-DpeP7CDZ.js +1 -0
  226. package/dist/dashboard/public/assets/HttpClientPage-BJ4-5E6t.js +1 -0
  227. package/dist/dashboard/public/assets/JobsPage-Dv3KaX2x.js +1 -0
  228. package/dist/dashboard/public/assets/LogsPage-D0Q3yDb1.js +1 -0
  229. package/dist/dashboard/public/assets/MailPage-Bf8C6WF6.js +1 -0
  230. package/dist/dashboard/public/assets/ModelsPage-BMHncI5y.js +1 -0
  231. package/dist/dashboard/public/assets/NotificationsPage-D5-I-Oxb.js +1 -0
  232. package/dist/dashboard/public/assets/QueriesPage-oNp0i6Gt.js +1 -0
  233. package/dist/dashboard/public/assets/RedisPage-_GeS2OD8.js +1 -0
  234. package/dist/dashboard/public/assets/RequestsPage-BCwqu9US.js +1 -0
  235. package/dist/dashboard/public/assets/SchedulePage-CR0P-oX6.js +1 -0
  236. package/dist/dashboard/public/assets/ViewsPage-Dsy5ECRA.js +1 -0
  237. package/dist/dashboard/public/assets/calendar-DfK3x-6B.js +6 -0
  238. package/dist/dashboard/public/assets/circle-check-big-DcsYW8y8.js +6 -0
  239. package/dist/dashboard/public/assets/format-BFldcnCk.js +1 -0
  240. package/dist/dashboard/public/assets/index-DmeA1maE.css +1 -0
  241. package/dist/dashboard/public/assets/index-rkbGYdU7.js +351 -0
  242. package/dist/dashboard/public/assets/types-Cldoe2db.js +1 -0
  243. package/dist/dashboard/public/assets/vendor-B2nVRih0.js +43 -0
  244. package/dist/dashboard/public/assets/zap-DqtRi0JM.js +6 -0
  245. package/dist/dashboard/public/index.html +15 -0
  246. package/dist/dashboard/public/nestlens-icon.svg +9 -0
  247. package/dist/index.d.ts +22 -0
  248. package/dist/index.d.ts.map +1 -0
  249. package/dist/index.js +69 -0
  250. package/dist/index.js.map +1 -0
  251. package/dist/nestlens.config.d.ts +216 -0
  252. package/dist/nestlens.config.d.ts.map +1 -0
  253. package/dist/nestlens.config.js +57 -0
  254. package/dist/nestlens.config.js.map +1 -0
  255. package/dist/nestlens.module.d.ts +10 -0
  256. package/dist/nestlens.module.d.ts.map +1 -0
  257. package/dist/nestlens.module.js +211 -0
  258. package/dist/nestlens.module.js.map +1 -0
  259. package/dist/types/entry.types.d.ts +368 -0
  260. package/dist/types/entry.types.d.ts.map +1 -0
  261. package/dist/types/entry.types.js +3 -0
  262. package/dist/types/entry.types.js.map +1 -0
  263. package/dist/types/index.d.ts +4 -0
  264. package/dist/types/index.d.ts.map +1 -0
  265. package/dist/types/index.js +20 -0
  266. package/dist/types/index.js.map +1 -0
  267. package/dist/types/request.types.d.ts +9 -0
  268. package/dist/types/request.types.d.ts.map +1 -0
  269. package/dist/types/request.types.js +3 -0
  270. package/dist/types/request.types.js.map +1 -0
  271. package/dist/types/tag.types.d.ts +32 -0
  272. package/dist/types/tag.types.d.ts.map +1 -0
  273. package/dist/types/tag.types.js +3 -0
  274. package/dist/types/tag.types.js.map +1 -0
  275. package/dist/watchers/batch.watcher.d.ts +48 -0
  276. package/dist/watchers/batch.watcher.d.ts.map +1 -0
  277. package/dist/watchers/batch.watcher.js +185 -0
  278. package/dist/watchers/batch.watcher.js.map +1 -0
  279. package/dist/watchers/cache.watcher.d.ts +19 -0
  280. package/dist/watchers/cache.watcher.d.ts.map +1 -0
  281. package/dist/watchers/cache.watcher.js +158 -0
  282. package/dist/watchers/cache.watcher.js.map +1 -0
  283. package/dist/watchers/command.watcher.d.ts +32 -0
  284. package/dist/watchers/command.watcher.d.ts.map +1 -0
  285. package/dist/watchers/command.watcher.js +174 -0
  286. package/dist/watchers/command.watcher.js.map +1 -0
  287. package/dist/watchers/dump.watcher.d.ts +52 -0
  288. package/dist/watchers/dump.watcher.d.ts.map +1 -0
  289. package/dist/watchers/dump.watcher.js +234 -0
  290. package/dist/watchers/dump.watcher.js.map +1 -0
  291. package/dist/watchers/event.watcher.d.ts +20 -0
  292. package/dist/watchers/event.watcher.d.ts.map +1 -0
  293. package/dist/watchers/event.watcher.js +123 -0
  294. package/dist/watchers/event.watcher.js.map +1 -0
  295. package/dist/watchers/exception.watcher.d.ts +15 -0
  296. package/dist/watchers/exception.watcher.d.ts.map +1 -0
  297. package/dist/watchers/exception.watcher.js +117 -0
  298. package/dist/watchers/exception.watcher.js.map +1 -0
  299. package/dist/watchers/gate.watcher.d.ts +40 -0
  300. package/dist/watchers/gate.watcher.d.ts.map +1 -0
  301. package/dist/watchers/gate.watcher.js +200 -0
  302. package/dist/watchers/gate.watcher.js.map +1 -0
  303. package/dist/watchers/http-client.watcher.d.ts +34 -0
  304. package/dist/watchers/http-client.watcher.d.ts.map +1 -0
  305. package/dist/watchers/http-client.watcher.js +259 -0
  306. package/dist/watchers/http-client.watcher.js.map +1 -0
  307. package/dist/watchers/index.d.ts +19 -0
  308. package/dist/watchers/index.d.ts.map +1 -0
  309. package/dist/watchers/index.js +35 -0
  310. package/dist/watchers/index.js.map +1 -0
  311. package/dist/watchers/job.watcher.d.ts +27 -0
  312. package/dist/watchers/job.watcher.d.ts.map +1 -0
  313. package/dist/watchers/job.watcher.js +190 -0
  314. package/dist/watchers/job.watcher.js.map +1 -0
  315. package/dist/watchers/log.watcher.d.ts +26 -0
  316. package/dist/watchers/log.watcher.d.ts.map +1 -0
  317. package/dist/watchers/log.watcher.js +122 -0
  318. package/dist/watchers/log.watcher.js.map +1 -0
  319. package/dist/watchers/mail.watcher.d.ts +26 -0
  320. package/dist/watchers/mail.watcher.d.ts.map +1 -0
  321. package/dist/watchers/mail.watcher.js +154 -0
  322. package/dist/watchers/mail.watcher.js.map +1 -0
  323. package/dist/watchers/model.watcher.d.ts +54 -0
  324. package/dist/watchers/model.watcher.d.ts.map +1 -0
  325. package/dist/watchers/model.watcher.js +343 -0
  326. package/dist/watchers/model.watcher.js.map +1 -0
  327. package/dist/watchers/notification.watcher.d.ts +48 -0
  328. package/dist/watchers/notification.watcher.d.ts.map +1 -0
  329. package/dist/watchers/notification.watcher.js +215 -0
  330. package/dist/watchers/notification.watcher.js.map +1 -0
  331. package/dist/watchers/query/index.d.ts +3 -0
  332. package/dist/watchers/query/index.d.ts.map +1 -0
  333. package/dist/watchers/query/index.js +19 -0
  334. package/dist/watchers/query/index.js.map +1 -0
  335. package/dist/watchers/query/query.watcher.d.ts +27 -0
  336. package/dist/watchers/query/query.watcher.d.ts.map +1 -0
  337. package/dist/watchers/query/query.watcher.js +167 -0
  338. package/dist/watchers/query/query.watcher.js.map +1 -0
  339. package/dist/watchers/query/types.d.ts +60 -0
  340. package/dist/watchers/query/types.d.ts.map +1 -0
  341. package/dist/watchers/query/types.js +55 -0
  342. package/dist/watchers/query/types.js.map +1 -0
  343. package/dist/watchers/redis.watcher.d.ts +43 -0
  344. package/dist/watchers/redis.watcher.d.ts.map +1 -0
  345. package/dist/watchers/redis.watcher.js +225 -0
  346. package/dist/watchers/redis.watcher.js.map +1 -0
  347. package/dist/watchers/request.watcher.d.ts +21 -0
  348. package/dist/watchers/request.watcher.d.ts.map +1 -0
  349. package/dist/watchers/request.watcher.js +287 -0
  350. package/dist/watchers/request.watcher.js.map +1 -0
  351. package/dist/watchers/schedule.watcher.d.ts +25 -0
  352. package/dist/watchers/schedule.watcher.d.ts.map +1 -0
  353. package/dist/watchers/schedule.watcher.js +168 -0
  354. package/dist/watchers/schedule.watcher.js.map +1 -0
  355. package/dist/watchers/view.watcher.d.ts +51 -0
  356. package/dist/watchers/view.watcher.d.ts.map +1 -0
  357. package/dist/watchers/view.watcher.js +219 -0
  358. package/dist/watchers/view.watcher.js.map +1 -0
  359. package/package.json +86 -0
@@ -0,0 +1,1117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const family_hash_service_1 = require("../../core/family-hash.service");
4
+ describe('FamilyHashService', () => {
5
+ let service;
6
+ beforeEach(() => {
7
+ service = new family_hash_service_1.FamilyHashService();
8
+ });
9
+ describe('generateFamilyHash', () => {
10
+ describe('Exception Entries', () => {
11
+ it('should generate hash for exception with stack trace', () => {
12
+ // Arrange
13
+ const entry = {
14
+ id: 1,
15
+ type: 'exception',
16
+ timestamp: new Date().toISOString(),
17
+ payload: {
18
+ name: 'TypeError',
19
+ message: 'Cannot read property "id" of undefined',
20
+ stack: 'TypeError: Cannot read property "id" of undefined\n at UserService.getUser (/src/services/user.service.ts:42:15)',
21
+ },
22
+ };
23
+ // Act
24
+ const hash = service.generateFamilyHash(entry);
25
+ // Assert
26
+ expect(hash).toBeDefined();
27
+ expect(hash).toHaveLength(16);
28
+ });
29
+ it('should generate same hash for similar exceptions', () => {
30
+ // Arrange
31
+ const entry1 = {
32
+ id: 1,
33
+ type: 'exception',
34
+ timestamp: new Date().toISOString(),
35
+ payload: {
36
+ name: 'TypeError',
37
+ message: 'Cannot read property "id" of undefined',
38
+ stack: 'at UserService.getUser (/src/services/user.service.ts:42:15)',
39
+ },
40
+ };
41
+ const entry2 = {
42
+ id: 2,
43
+ type: 'exception',
44
+ timestamp: new Date().toISOString(),
45
+ payload: {
46
+ name: 'TypeError',
47
+ message: 'Cannot read property "id" of undefined',
48
+ stack: 'at UserService.getUser (/src/services/user.service.ts:42:15)',
49
+ },
50
+ };
51
+ // Act
52
+ const hash1 = service.generateFamilyHash(entry1);
53
+ const hash2 = service.generateFamilyHash(entry2);
54
+ // Assert
55
+ expect(hash1).toBe(hash2);
56
+ });
57
+ it('should generate different hash for different exception types', () => {
58
+ // Arrange
59
+ const entry1 = {
60
+ id: 1,
61
+ type: 'exception',
62
+ timestamp: new Date().toISOString(),
63
+ payload: {
64
+ name: 'TypeError',
65
+ message: 'Error message',
66
+ stack: 'at file.ts:10:5',
67
+ },
68
+ };
69
+ const entry2 = {
70
+ id: 2,
71
+ type: 'exception',
72
+ timestamp: new Date().toISOString(),
73
+ payload: {
74
+ name: 'RangeError',
75
+ message: 'Error message',
76
+ stack: 'at file.ts:10:5',
77
+ },
78
+ };
79
+ // Act
80
+ const hash1 = service.generateFamilyHash(entry1);
81
+ const hash2 = service.generateFamilyHash(entry2);
82
+ // Assert
83
+ expect(hash1).not.toBe(hash2);
84
+ });
85
+ it('should normalize error messages with UUIDs', () => {
86
+ // Arrange
87
+ const entry1 = {
88
+ id: 1,
89
+ type: 'exception',
90
+ timestamp: new Date().toISOString(),
91
+ payload: {
92
+ name: 'NotFoundError',
93
+ message: 'User 123e4567-e89b-12d3-a456-426614174000 not found',
94
+ },
95
+ };
96
+ const entry2 = {
97
+ id: 2,
98
+ type: 'exception',
99
+ timestamp: new Date().toISOString(),
100
+ payload: {
101
+ name: 'NotFoundError',
102
+ message: 'User 987fcdeb-51a2-3b4c-d567-890123456789 not found',
103
+ },
104
+ };
105
+ // Act
106
+ const hash1 = service.generateFamilyHash(entry1);
107
+ const hash2 = service.generateFamilyHash(entry2);
108
+ // Assert
109
+ expect(hash1).toBe(hash2);
110
+ });
111
+ it('should normalize error messages with numbers', () => {
112
+ // Arrange
113
+ const entry1 = {
114
+ id: 1,
115
+ type: 'exception',
116
+ timestamp: new Date().toISOString(),
117
+ payload: {
118
+ name: 'Error',
119
+ message: 'Failed to process item 12345',
120
+ },
121
+ };
122
+ const entry2 = {
123
+ id: 2,
124
+ type: 'exception',
125
+ timestamp: new Date().toISOString(),
126
+ payload: {
127
+ name: 'Error',
128
+ message: 'Failed to process item 67890',
129
+ },
130
+ };
131
+ // Act
132
+ const hash1 = service.generateFamilyHash(entry1);
133
+ const hash2 = service.generateFamilyHash(entry2);
134
+ // Assert
135
+ expect(hash1).toBe(hash2);
136
+ });
137
+ });
138
+ describe('Query Entries', () => {
139
+ it('should generate hash for query', () => {
140
+ // Arrange
141
+ const entry = {
142
+ id: 1,
143
+ type: 'query',
144
+ timestamp: new Date().toISOString(),
145
+ payload: {
146
+ query: 'SELECT * FROM users WHERE id = 1',
147
+ duration: 10,
148
+ slow: false,
149
+ },
150
+ };
151
+ // Act
152
+ const hash = service.generateFamilyHash(entry);
153
+ // Assert
154
+ expect(hash).toBeDefined();
155
+ expect(hash).toHaveLength(16);
156
+ });
157
+ it('should generate same hash for queries with different parameter values', () => {
158
+ // Arrange
159
+ const entry1 = {
160
+ id: 1,
161
+ type: 'query',
162
+ timestamp: new Date().toISOString(),
163
+ payload: {
164
+ query: 'SELECT * FROM users WHERE id = 1',
165
+ duration: 10,
166
+ slow: false,
167
+ },
168
+ };
169
+ const entry2 = {
170
+ id: 2,
171
+ type: 'query',
172
+ timestamp: new Date().toISOString(),
173
+ payload: {
174
+ query: 'SELECT * FROM users WHERE id = 999',
175
+ duration: 15,
176
+ slow: false,
177
+ },
178
+ };
179
+ // Act
180
+ const hash1 = service.generateFamilyHash(entry1);
181
+ const hash2 = service.generateFamilyHash(entry2);
182
+ // Assert
183
+ expect(hash1).toBe(hash2);
184
+ });
185
+ it('should generate same hash for queries with different string values', () => {
186
+ // Arrange
187
+ const entry1 = {
188
+ id: 1,
189
+ type: 'query',
190
+ timestamp: new Date().toISOString(),
191
+ payload: {
192
+ query: "SELECT * FROM users WHERE name = 'John'",
193
+ duration: 10,
194
+ slow: false,
195
+ },
196
+ };
197
+ const entry2 = {
198
+ id: 2,
199
+ type: 'query',
200
+ timestamp: new Date().toISOString(),
201
+ payload: {
202
+ query: "SELECT * FROM users WHERE name = 'Jane'",
203
+ duration: 10,
204
+ slow: false,
205
+ },
206
+ };
207
+ // Act
208
+ const hash1 = service.generateFamilyHash(entry1);
209
+ const hash2 = service.generateFamilyHash(entry2);
210
+ // Assert
211
+ expect(hash1).toBe(hash2);
212
+ });
213
+ it('should normalize parameter placeholders ($1, :param, @param)', () => {
214
+ // Arrange
215
+ const entry1 = {
216
+ id: 1,
217
+ type: 'query',
218
+ timestamp: new Date().toISOString(),
219
+ payload: {
220
+ query: 'SELECT * FROM users WHERE id = :id',
221
+ duration: 10,
222
+ slow: false,
223
+ },
224
+ };
225
+ const entry2 = {
226
+ id: 2,
227
+ type: 'query',
228
+ timestamp: new Date().toISOString(),
229
+ payload: {
230
+ query: 'SELECT * FROM users WHERE id = @id',
231
+ duration: 10,
232
+ slow: false,
233
+ },
234
+ };
235
+ // Act
236
+ const hash1 = service.generateFamilyHash(entry1);
237
+ const hash2 = service.generateFamilyHash(entry2);
238
+ // Assert - named parameters should normalize to same hash
239
+ expect(hash1).toBe(hash2);
240
+ });
241
+ it('should include source in hash', () => {
242
+ // Arrange
243
+ const entry1 = {
244
+ id: 1,
245
+ type: 'query',
246
+ timestamp: new Date().toISOString(),
247
+ payload: {
248
+ query: 'SELECT * FROM users',
249
+ source: 'TypeORM',
250
+ duration: 10,
251
+ slow: false,
252
+ },
253
+ };
254
+ const entry2 = {
255
+ id: 2,
256
+ type: 'query',
257
+ timestamp: new Date().toISOString(),
258
+ payload: {
259
+ query: 'SELECT * FROM users',
260
+ source: 'Prisma',
261
+ duration: 10,
262
+ slow: false,
263
+ },
264
+ };
265
+ // Act
266
+ const hash1 = service.generateFamilyHash(entry1);
267
+ const hash2 = service.generateFamilyHash(entry2);
268
+ // Assert
269
+ expect(hash1).not.toBe(hash2);
270
+ });
271
+ });
272
+ describe('Log Entries', () => {
273
+ it('should generate hash for error logs', () => {
274
+ // Arrange
275
+ const entry = {
276
+ id: 1,
277
+ type: 'log',
278
+ timestamp: new Date().toISOString(),
279
+ payload: {
280
+ level: 'error',
281
+ message: 'Database connection failed',
282
+ context: 'DatabaseService',
283
+ },
284
+ };
285
+ // Act
286
+ const hash = service.generateFamilyHash(entry);
287
+ // Assert
288
+ expect(hash).toBeDefined();
289
+ expect(hash).toHaveLength(16);
290
+ });
291
+ it('should generate hash for warn logs', () => {
292
+ // Arrange
293
+ const entry = {
294
+ id: 1,
295
+ type: 'log',
296
+ timestamp: new Date().toISOString(),
297
+ payload: {
298
+ level: 'warn',
299
+ message: 'Deprecated API usage',
300
+ context: 'ApiController',
301
+ },
302
+ };
303
+ // Act
304
+ const hash = service.generateFamilyHash(entry);
305
+ // Assert
306
+ expect(hash).toBeDefined();
307
+ });
308
+ it('should return undefined for info/debug/log levels', () => {
309
+ // Arrange
310
+ const entry = {
311
+ id: 1,
312
+ type: 'log',
313
+ timestamp: new Date().toISOString(),
314
+ payload: {
315
+ level: 'log',
316
+ message: 'Application started',
317
+ },
318
+ };
319
+ // Act
320
+ const hash = service.generateFamilyHash(entry);
321
+ // Assert
322
+ expect(hash).toBeUndefined();
323
+ });
324
+ it('should generate same hash for similar error logs with different dynamic values', () => {
325
+ // Arrange
326
+ const entry1 = {
327
+ id: 1,
328
+ type: 'log',
329
+ timestamp: new Date().toISOString(),
330
+ payload: {
331
+ level: 'error',
332
+ message: 'Failed to process user 123',
333
+ context: 'UserService',
334
+ },
335
+ };
336
+ const entry2 = {
337
+ id: 2,
338
+ type: 'log',
339
+ timestamp: new Date().toISOString(),
340
+ payload: {
341
+ level: 'error',
342
+ message: 'Failed to process user 456',
343
+ context: 'UserService',
344
+ },
345
+ };
346
+ // Act
347
+ const hash1 = service.generateFamilyHash(entry1);
348
+ const hash2 = service.generateFamilyHash(entry2);
349
+ // Assert
350
+ expect(hash1).toBe(hash2);
351
+ });
352
+ });
353
+ describe('Command Entries', () => {
354
+ it('should generate hash for command', () => {
355
+ // Arrange
356
+ const entry = {
357
+ id: 1,
358
+ type: 'command',
359
+ timestamp: new Date().toISOString(),
360
+ payload: {
361
+ name: 'CreateUserCommand',
362
+ handler: 'CreateUserHandler',
363
+ status: 'completed',
364
+ },
365
+ };
366
+ // Act
367
+ const hash = service.generateFamilyHash(entry);
368
+ // Assert
369
+ expect(hash).toBeDefined();
370
+ expect(hash).toHaveLength(16);
371
+ });
372
+ it('should generate same hash for same command with different parameters', () => {
373
+ // Arrange
374
+ const entry1 = {
375
+ id: 1,
376
+ type: 'command',
377
+ timestamp: new Date().toISOString(),
378
+ payload: {
379
+ name: 'CreateUserCommand',
380
+ handler: 'CreateUserHandler',
381
+ status: 'completed',
382
+ payload: { name: 'John' },
383
+ },
384
+ };
385
+ const entry2 = {
386
+ id: 2,
387
+ type: 'command',
388
+ timestamp: new Date().toISOString(),
389
+ payload: {
390
+ name: 'CreateUserCommand',
391
+ handler: 'CreateUserHandler',
392
+ status: 'completed',
393
+ payload: { name: 'Jane' },
394
+ },
395
+ };
396
+ // Act
397
+ const hash1 = service.generateFamilyHash(entry1);
398
+ const hash2 = service.generateFamilyHash(entry2);
399
+ // Assert
400
+ expect(hash1).toBe(hash2);
401
+ });
402
+ });
403
+ describe('Gate Entries', () => {
404
+ it('should generate hash for gate check', () => {
405
+ // Arrange
406
+ const entry = {
407
+ id: 1,
408
+ type: 'gate',
409
+ timestamp: new Date().toISOString(),
410
+ payload: {
411
+ gate: 'CanEditPost',
412
+ action: 'edit',
413
+ subject: 'Post:123',
414
+ allowed: true,
415
+ duration: 5,
416
+ },
417
+ };
418
+ // Act
419
+ const hash = service.generateFamilyHash(entry);
420
+ // Assert
421
+ expect(hash).toBeDefined();
422
+ expect(hash).toHaveLength(16);
423
+ });
424
+ it('should normalize subject IDs', () => {
425
+ // Arrange
426
+ const entry1 = {
427
+ id: 1,
428
+ type: 'gate',
429
+ timestamp: new Date().toISOString(),
430
+ payload: {
431
+ gate: 'CanEditPost',
432
+ action: 'edit',
433
+ subject: 'Post:123',
434
+ allowed: true,
435
+ duration: 5,
436
+ },
437
+ };
438
+ const entry2 = {
439
+ id: 2,
440
+ type: 'gate',
441
+ timestamp: new Date().toISOString(),
442
+ payload: {
443
+ gate: 'CanEditPost',
444
+ action: 'edit',
445
+ subject: 'Post:456',
446
+ allowed: false,
447
+ duration: 5,
448
+ },
449
+ };
450
+ // Act
451
+ const hash1 = service.generateFamilyHash(entry1);
452
+ const hash2 = service.generateFamilyHash(entry2);
453
+ // Assert
454
+ expect(hash1).toBe(hash2);
455
+ });
456
+ });
457
+ describe('Batch Entries', () => {
458
+ it('should generate hash for batch operation', () => {
459
+ // Arrange
460
+ const entry = {
461
+ id: 1,
462
+ type: 'batch',
463
+ timestamp: new Date().toISOString(),
464
+ payload: {
465
+ name: 'ImportUsers',
466
+ operation: 'import',
467
+ totalItems: 100,
468
+ status: 'completed',
469
+ },
470
+ };
471
+ // Act
472
+ const hash = service.generateFamilyHash(entry);
473
+ // Assert
474
+ expect(hash).toBeDefined();
475
+ expect(hash).toHaveLength(16);
476
+ });
477
+ it('should generate same hash for same batch type', () => {
478
+ // Arrange
479
+ const entry1 = {
480
+ id: 1,
481
+ type: 'batch',
482
+ timestamp: new Date().toISOString(),
483
+ payload: {
484
+ name: 'ImportUsers',
485
+ operation: 'import',
486
+ totalItems: 100,
487
+ status: 'completed',
488
+ },
489
+ };
490
+ const entry2 = {
491
+ id: 2,
492
+ type: 'batch',
493
+ timestamp: new Date().toISOString(),
494
+ payload: {
495
+ name: 'ImportUsers',
496
+ operation: 'import',
497
+ totalItems: 500,
498
+ status: 'failed',
499
+ },
500
+ };
501
+ // Act
502
+ const hash1 = service.generateFamilyHash(entry1);
503
+ const hash2 = service.generateFamilyHash(entry2);
504
+ // Assert
505
+ expect(hash1).toBe(hash2);
506
+ });
507
+ });
508
+ describe('Unsupported Entry Types', () => {
509
+ it('should return undefined for request entries', () => {
510
+ // Arrange
511
+ const entry = {
512
+ id: 1,
513
+ type: 'request',
514
+ timestamp: new Date().toISOString(),
515
+ payload: {
516
+ method: 'GET',
517
+ url: '/api/users',
518
+ path: '/api/users',
519
+ query: {},
520
+ params: {},
521
+ headers: {},
522
+ statusCode: 200,
523
+ duration: 50,
524
+ memory: 0,
525
+ },
526
+ };
527
+ // Act
528
+ const hash = service.generateFamilyHash(entry);
529
+ // Assert
530
+ expect(hash).toBeUndefined();
531
+ });
532
+ it('should return undefined for cache entries', () => {
533
+ // Arrange
534
+ const entry = {
535
+ id: 1,
536
+ type: 'cache',
537
+ timestamp: new Date().toISOString(),
538
+ payload: {
539
+ key: 'user:1',
540
+ operation: 'get',
541
+ hit: true,
542
+ },
543
+ };
544
+ // Act
545
+ const hash = service.generateFamilyHash(entry);
546
+ // Assert
547
+ expect(hash).toBeUndefined();
548
+ });
549
+ it('should return undefined for event entries', () => {
550
+ // Arrange
551
+ const entry = {
552
+ id: 1,
553
+ type: 'event',
554
+ timestamp: new Date().toISOString(),
555
+ payload: {
556
+ name: 'user.created',
557
+ payload: {},
558
+ listeners: ['Handler1'],
559
+ duration: 10,
560
+ },
561
+ };
562
+ // Act
563
+ const hash = service.generateFamilyHash(entry);
564
+ // Assert
565
+ expect(hash).toBeUndefined();
566
+ });
567
+ });
568
+ });
569
+ describe('extractStackInfo', () => {
570
+ it('should extract file and line from Node.js stack trace', () => {
571
+ // Arrange
572
+ const stack = 'Error: Something went wrong\n at Function.name (/path/to/src/service.ts:42:15)';
573
+ // Act
574
+ const result = service['extractStackInfo'](stack);
575
+ // Assert
576
+ expect(result).toBeDefined();
577
+ expect(result?.file).toContain('src/service.ts');
578
+ expect(result?.line).toBe('42');
579
+ });
580
+ it('should return undefined for empty stack', () => {
581
+ // Act
582
+ const result = service['extractStackInfo'](undefined);
583
+ // Assert
584
+ expect(result).toBeUndefined();
585
+ });
586
+ it('should return undefined for invalid stack format', () => {
587
+ // Arrange
588
+ const stack = 'Not a valid stack trace';
589
+ // Act
590
+ const result = service['extractStackInfo'](stack);
591
+ // Assert
592
+ expect(result).toBeUndefined();
593
+ });
594
+ });
595
+ describe('normalizeFilePath', () => {
596
+ it('should remove absolute path prefix before src', () => {
597
+ // Arrange
598
+ const path = '/Users/user/project/src/services/user.service.ts';
599
+ // Act
600
+ const result = service['normalizeFilePath'](path);
601
+ // Assert
602
+ expect(result).toBe('src/services/user.service.ts');
603
+ });
604
+ it('should mark node_modules as external', () => {
605
+ // Arrange
606
+ const path = '/path/to/node_modules/lodash/index.js';
607
+ // Act
608
+ const result = service['normalizeFilePath'](path);
609
+ // Assert
610
+ expect(result).toBe('[node_modules]/lodash');
611
+ });
612
+ });
613
+ describe('normalizeQuery', () => {
614
+ it('should normalize whitespace', () => {
615
+ // Arrange
616
+ const query = 'SELECT * FROM users WHERE id = 1';
617
+ // Act
618
+ const result = service['normalizeQuery'](query);
619
+ // Assert
620
+ expect(result).toBe('select * from users where id = ?');
621
+ });
622
+ it('should replace string literals', () => {
623
+ // Arrange
624
+ const query = "SELECT * FROM users WHERE name = 'John'";
625
+ // Act
626
+ const result = service['normalizeQuery'](query);
627
+ // Assert
628
+ expect(result).toBe('select * from users where name = ?');
629
+ });
630
+ it('should replace numeric literals', () => {
631
+ // Arrange
632
+ const query = 'SELECT * FROM users WHERE id = 123 AND age > 18';
633
+ // Act
634
+ const result = service['normalizeQuery'](query);
635
+ // Assert
636
+ expect(result).toBe('select * from users where id = ? and age > ?');
637
+ });
638
+ it('should replace PostgreSQL parameter placeholders ($1, $2)', () => {
639
+ // Arrange
640
+ const query = 'SELECT * FROM users WHERE id = $1 AND name = $2';
641
+ // Act
642
+ const result = service['normalizeQuery'](query);
643
+ // Assert - numeric replacement runs first, so $1 becomes $?
644
+ expect(result).toBe('select * from users where id = $? and name = $?');
645
+ });
646
+ it('should replace named parameters (:param)', () => {
647
+ // Arrange
648
+ const query = 'SELECT * FROM users WHERE id = :id AND name = :name';
649
+ // Act
650
+ const result = service['normalizeQuery'](query);
651
+ // Assert
652
+ expect(result).toBe('select * from users where id = ? and name = ?');
653
+ });
654
+ });
655
+ describe('normalizeErrorMessage', () => {
656
+ it('should replace UUIDs', () => {
657
+ // Arrange
658
+ const message = 'User 123e4567-e89b-12d3-a456-426614174000 not found';
659
+ // Act
660
+ const result = service['normalizeErrorMessage'](message);
661
+ // Assert
662
+ expect(result).toBe('User [UUID] not found');
663
+ });
664
+ it('should replace numbers', () => {
665
+ // Arrange
666
+ const message = 'Failed to process order 12345';
667
+ // Act
668
+ const result = service['normalizeErrorMessage'](message);
669
+ // Assert
670
+ expect(result).toBe('Failed to process order [N]');
671
+ });
672
+ it('should replace email addresses', () => {
673
+ // Arrange
674
+ const message = 'Failed to send email to user@example.com';
675
+ // Act
676
+ const result = service['normalizeErrorMessage'](message);
677
+ // Assert
678
+ expect(result).toBe('Failed to send email to [EMAIL]');
679
+ });
680
+ it('should replace URLs', () => {
681
+ // Arrange
682
+ const message = 'Failed to connect to https://api.example.com/v1/users';
683
+ // Act
684
+ const result = service['normalizeErrorMessage'](message);
685
+ // Assert
686
+ expect(result).toBe('Failed to connect to [URL]');
687
+ });
688
+ it('should replace file paths', () => {
689
+ // Arrange
690
+ const message = 'Cannot read file /path/to/file.txt';
691
+ // Act
692
+ const result = service['normalizeErrorMessage'](message);
693
+ // Assert
694
+ expect(result).toBe('Cannot read file [PATH]');
695
+ });
696
+ it('should replace quoted strings', () => {
697
+ // Arrange
698
+ const message = "Failed to parse 'invalid json' value";
699
+ // Act
700
+ const result = service['normalizeErrorMessage'](message);
701
+ // Assert
702
+ expect(result).toBe('Failed to parse [STR] value');
703
+ });
704
+ });
705
+ describe('normalizeSubject', () => {
706
+ it('should replace UUIDs in subject', () => {
707
+ // Arrange
708
+ const subject = 'User:123e4567-e89b-12d3-a456-426614174000';
709
+ // Act
710
+ const result = service['normalizeSubject'](subject);
711
+ // Assert
712
+ expect(result).toBe('User:[ID]');
713
+ });
714
+ it('should replace numeric IDs', () => {
715
+ // Arrange
716
+ const subject = 'Post:12345';
717
+ // Act
718
+ const result = service['normalizeSubject'](subject);
719
+ // Assert
720
+ expect(result).toBe('Post:[ID]');
721
+ });
722
+ });
723
+ describe('hash', () => {
724
+ it('should generate consistent 16-character hash', () => {
725
+ // Arrange
726
+ const input = 'test input';
727
+ // Act
728
+ const hash1 = service['hash'](input);
729
+ const hash2 = service['hash'](input);
730
+ // Assert
731
+ expect(hash1).toBe(hash2);
732
+ expect(hash1).toHaveLength(16);
733
+ });
734
+ it('should generate different hash for different inputs', () => {
735
+ // Arrange
736
+ const input1 = 'input one';
737
+ const input2 = 'input two';
738
+ // Act
739
+ const hash1 = service['hash'](input1);
740
+ const hash2 = service['hash'](input2);
741
+ // Assert
742
+ expect(hash1).not.toBe(hash2);
743
+ });
744
+ });
745
+ // ============================================================================
746
+ // Edge Cases and Branch Coverage
747
+ // ============================================================================
748
+ describe('edge cases', () => {
749
+ describe('log entries', () => {
750
+ it('should return undefined for log level logs', () => {
751
+ // Arrange - 'log' level (not error/warn) should return undefined
752
+ const entry = {
753
+ id: 1,
754
+ type: 'log',
755
+ payload: {
756
+ level: 'log',
757
+ message: 'Log message',
758
+ context: 'TestContext',
759
+ },
760
+ };
761
+ // Act
762
+ const hash = service.generateFamilyHash(entry);
763
+ // Assert
764
+ expect(hash).toBeUndefined();
765
+ });
766
+ it('should return undefined for debug level logs', () => {
767
+ // Arrange
768
+ const entry = {
769
+ id: 1,
770
+ type: 'log',
771
+ payload: {
772
+ level: 'debug',
773
+ message: 'Debug message',
774
+ context: 'TestContext',
775
+ },
776
+ };
777
+ // Act
778
+ const hash = service.generateFamilyHash(entry);
779
+ // Assert
780
+ expect(hash).toBeUndefined();
781
+ });
782
+ it('should return undefined for verbose level logs', () => {
783
+ // Arrange
784
+ const entry = {
785
+ id: 1,
786
+ type: 'log',
787
+ payload: {
788
+ level: 'verbose',
789
+ message: 'Verbose message',
790
+ context: 'TestContext',
791
+ },
792
+ };
793
+ // Act
794
+ const hash = service.generateFamilyHash(entry);
795
+ // Assert
796
+ expect(hash).toBeUndefined();
797
+ });
798
+ it('should generate hash for warn level logs', () => {
799
+ // Arrange
800
+ const entry = {
801
+ id: 1,
802
+ type: 'log',
803
+ payload: {
804
+ level: 'warn',
805
+ message: 'Warning message',
806
+ context: 'TestContext',
807
+ },
808
+ };
809
+ // Act
810
+ const hash = service.generateFamilyHash(entry);
811
+ // Assert
812
+ expect(hash).toBeDefined();
813
+ expect(hash).toHaveLength(16);
814
+ });
815
+ it('should handle log without context', () => {
816
+ // Arrange
817
+ const entry = {
818
+ id: 1,
819
+ type: 'log',
820
+ payload: {
821
+ level: 'error',
822
+ message: 'Error without context',
823
+ },
824
+ };
825
+ // Act
826
+ const hash = service.generateFamilyHash(entry);
827
+ // Assert
828
+ expect(hash).toBeDefined();
829
+ });
830
+ });
831
+ describe('exception entries', () => {
832
+ it('should handle exception without stack trace', () => {
833
+ // Arrange
834
+ const entry = {
835
+ id: 1,
836
+ type: 'exception',
837
+ payload: {
838
+ name: 'Error',
839
+ message: 'Error without stack',
840
+ },
841
+ };
842
+ // Act
843
+ const hash = service.generateFamilyHash(entry);
844
+ // Assert
845
+ expect(hash).toBeDefined();
846
+ });
847
+ it('should handle exception with empty stack', () => {
848
+ // Arrange
849
+ const entry = {
850
+ id: 1,
851
+ type: 'exception',
852
+ payload: {
853
+ name: 'Error',
854
+ message: 'Error message',
855
+ stack: '',
856
+ },
857
+ };
858
+ // Act
859
+ const hash = service.generateFamilyHash(entry);
860
+ // Assert
861
+ expect(hash).toBeDefined();
862
+ });
863
+ it('should handle exception with malformed stack', () => {
864
+ // Arrange
865
+ const entry = {
866
+ id: 1,
867
+ type: 'exception',
868
+ payload: {
869
+ name: 'Error',
870
+ message: 'Error message',
871
+ stack: 'Just some random text without file info',
872
+ },
873
+ };
874
+ // Act
875
+ const hash = service.generateFamilyHash(entry);
876
+ // Assert
877
+ expect(hash).toBeDefined();
878
+ });
879
+ });
880
+ describe('query entries', () => {
881
+ it('should handle query without source', () => {
882
+ // Arrange
883
+ const entry = {
884
+ id: 1,
885
+ type: 'query',
886
+ payload: {
887
+ query: 'SELECT * FROM users',
888
+ duration: 10,
889
+ slow: false,
890
+ },
891
+ };
892
+ // Act
893
+ const hash = service.generateFamilyHash(entry);
894
+ // Assert
895
+ expect(hash).toBeDefined();
896
+ });
897
+ it('should handle query with source', () => {
898
+ // Arrange
899
+ const entry = {
900
+ id: 1,
901
+ type: 'query',
902
+ payload: {
903
+ query: 'SELECT * FROM users',
904
+ duration: 10,
905
+ slow: false,
906
+ source: 'UserRepository',
907
+ },
908
+ };
909
+ // Act
910
+ const hash = service.generateFamilyHash(entry);
911
+ // Assert
912
+ expect(hash).toBeDefined();
913
+ });
914
+ });
915
+ describe('command entries', () => {
916
+ it('should handle command without handler', () => {
917
+ // Arrange
918
+ const entry = {
919
+ id: 1,
920
+ type: 'command',
921
+ payload: {
922
+ name: 'create:user',
923
+ exitCode: 0,
924
+ duration: 100,
925
+ },
926
+ };
927
+ // Act
928
+ const hash = service.generateFamilyHash(entry);
929
+ // Assert
930
+ expect(hash).toBeDefined();
931
+ });
932
+ it('should handle command with handler', () => {
933
+ // Arrange
934
+ const entry = {
935
+ id: 1,
936
+ type: 'command',
937
+ payload: {
938
+ name: 'create:user',
939
+ handler: 'CreateUserHandler',
940
+ exitCode: 0,
941
+ duration: 100,
942
+ },
943
+ };
944
+ // Act
945
+ const hash = service.generateFamilyHash(entry);
946
+ // Assert
947
+ expect(hash).toBeDefined();
948
+ });
949
+ });
950
+ describe('gate entries', () => {
951
+ it('should handle gate without subject', () => {
952
+ // Arrange
953
+ const entry = {
954
+ id: 1,
955
+ type: 'gate',
956
+ payload: {
957
+ gate: 'UserGate',
958
+ action: 'view',
959
+ result: true,
960
+ duration: 5,
961
+ },
962
+ };
963
+ // Act
964
+ const hash = service.generateFamilyHash(entry);
965
+ // Assert
966
+ expect(hash).toBeDefined();
967
+ });
968
+ it('should handle gate with subject', () => {
969
+ // Arrange
970
+ const entry = {
971
+ id: 1,
972
+ type: 'gate',
973
+ payload: {
974
+ gate: 'UserGate',
975
+ action: 'edit',
976
+ subject: 'User:123',
977
+ result: true,
978
+ duration: 5,
979
+ },
980
+ };
981
+ // Act
982
+ const hash = service.generateFamilyHash(entry);
983
+ // Assert
984
+ expect(hash).toBeDefined();
985
+ });
986
+ it('should normalize gate subjects with IDs', () => {
987
+ // Arrange
988
+ const entry1 = {
989
+ id: 1,
990
+ type: 'gate',
991
+ payload: {
992
+ gate: 'PostGate',
993
+ action: 'delete',
994
+ subject: 'Post:12345',
995
+ result: false,
996
+ duration: 5,
997
+ },
998
+ };
999
+ const entry2 = {
1000
+ id: 2,
1001
+ type: 'gate',
1002
+ payload: {
1003
+ gate: 'PostGate',
1004
+ action: 'delete',
1005
+ subject: 'Post:67890',
1006
+ result: true,
1007
+ duration: 3,
1008
+ },
1009
+ };
1010
+ // Act
1011
+ const hash1 = service.generateFamilyHash(entry1);
1012
+ const hash2 = service.generateFamilyHash(entry2);
1013
+ // Assert - should have same hash (ID normalized)
1014
+ expect(hash1).toBe(hash2);
1015
+ });
1016
+ });
1017
+ describe('unsupported entry types', () => {
1018
+ it('should return undefined for request entries', () => {
1019
+ // Arrange
1020
+ const entry = {
1021
+ id: 1,
1022
+ type: 'request',
1023
+ payload: {
1024
+ method: 'GET',
1025
+ url: '/api',
1026
+ path: '/api',
1027
+ query: {},
1028
+ params: {},
1029
+ headers: {},
1030
+ statusCode: 200,
1031
+ duration: 50,
1032
+ memory: 1024,
1033
+ },
1034
+ };
1035
+ // Act
1036
+ const hash = service.generateFamilyHash(entry);
1037
+ // Assert
1038
+ expect(hash).toBeUndefined();
1039
+ });
1040
+ it('should return undefined for cache entries', () => {
1041
+ // Arrange
1042
+ const entry = {
1043
+ id: 1,
1044
+ type: 'cache',
1045
+ payload: {
1046
+ action: 'get',
1047
+ key: 'user:123',
1048
+ hit: true,
1049
+ duration: 2,
1050
+ },
1051
+ };
1052
+ // Act
1053
+ const hash = service.generateFamilyHash(entry);
1054
+ // Assert
1055
+ expect(hash).toBeUndefined();
1056
+ });
1057
+ it('should return undefined for event entries', () => {
1058
+ // Arrange
1059
+ const entry = {
1060
+ id: 1,
1061
+ type: 'event',
1062
+ payload: {
1063
+ name: 'user.created',
1064
+ payload: {},
1065
+ listeners: [],
1066
+ duration: 10,
1067
+ },
1068
+ };
1069
+ // Act
1070
+ const hash = service.generateFamilyHash(entry);
1071
+ // Assert
1072
+ expect(hash).toBeUndefined();
1073
+ });
1074
+ });
1075
+ });
1076
+ describe('normalizeSubject', () => {
1077
+ it('should normalize subject with numeric ID', () => {
1078
+ // Act
1079
+ const result = service['normalizeSubject']('User:12345');
1080
+ // Assert - actual implementation uses [ID] placeholder
1081
+ expect(result).toBe('User:[ID]');
1082
+ });
1083
+ it('should normalize subject with UUID', () => {
1084
+ // Act
1085
+ const result = service['normalizeSubject']('User:550e8400-e29b-41d4-a716-446655440000');
1086
+ // Assert
1087
+ expect(result).toBe('User:[ID]');
1088
+ });
1089
+ it('should handle subject without ID separator', () => {
1090
+ // Act
1091
+ const result = service['normalizeSubject']('SomeClass');
1092
+ // Assert
1093
+ expect(result).toBe('SomeClass');
1094
+ });
1095
+ });
1096
+ describe('normalizeFilePath', () => {
1097
+ it('should normalize file paths', () => {
1098
+ // Act
1099
+ const result = service['normalizeFilePath']('/Users/dev/project/src/services/user.service.ts');
1100
+ // Assert - implementation extracts from src/
1101
+ expect(result).toContain('user.service.ts');
1102
+ });
1103
+ it('should handle Windows paths', () => {
1104
+ // Act
1105
+ const result = service['normalizeFilePath']('C:\\Projects\\app\\src\\service.ts');
1106
+ // Assert
1107
+ expect(result).toContain('service.ts');
1108
+ });
1109
+ it('should handle simple filename', () => {
1110
+ // Act
1111
+ const result = service['normalizeFilePath']('file.ts');
1112
+ // Assert
1113
+ expect(result).toBe('file.ts');
1114
+ });
1115
+ });
1116
+ });
1117
+ //# sourceMappingURL=family-hash.service.spec.js.map