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,1017 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const testing_1 = require("@nestjs/testing");
4
+ const rxjs_1 = require("rxjs");
5
+ const request_watcher_1 = require("../../watchers/request.watcher");
6
+ const collector_service_1 = require("../../core/collector.service");
7
+ const nestlens_config_1 = require("../../nestlens.config");
8
+ describe('RequestWatcher', () => {
9
+ let watcher;
10
+ let mockCollector;
11
+ const createMockContext = (overrides = {}) => {
12
+ const mockRequest = {
13
+ method: 'GET',
14
+ url: '/api/users',
15
+ originalUrl: '/api/users',
16
+ path: '/api/users',
17
+ query: {},
18
+ params: {},
19
+ headers: { 'user-agent': 'test-agent' },
20
+ body: undefined,
21
+ ip: '127.0.0.1',
22
+ socket: { remoteAddress: '127.0.0.1' },
23
+ ...overrides.request,
24
+ };
25
+ const mockResponse = {
26
+ statusCode: 200,
27
+ setHeader: jest.fn(),
28
+ getHeaders: jest.fn().mockReturnValue({}),
29
+ ...overrides.response,
30
+ };
31
+ return {
32
+ switchToHttp: () => ({
33
+ getRequest: () => mockRequest,
34
+ getResponse: () => mockResponse,
35
+ }),
36
+ getClass: () => ({ name: 'TestController' }),
37
+ getHandler: () => ({ name: 'testMethod' }),
38
+ ...overrides.context,
39
+ };
40
+ };
41
+ const createMockHandler = (returnValue = {}) => ({
42
+ handle: () => (0, rxjs_1.of)(returnValue),
43
+ });
44
+ beforeEach(async () => {
45
+ mockCollector = {
46
+ collect: jest.fn(),
47
+ collectImmediate: jest.fn(),
48
+ shutdown: jest.fn(),
49
+ };
50
+ const module = await testing_1.Test.createTestingModule({
51
+ providers: [
52
+ request_watcher_1.RequestWatcher,
53
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
54
+ {
55
+ provide: nestlens_config_1.NESTLENS_CONFIG,
56
+ useValue: {
57
+ path: '/nestlens',
58
+ watchers: {
59
+ request: { enabled: true },
60
+ },
61
+ },
62
+ },
63
+ ],
64
+ }).compile();
65
+ watcher = module.get(request_watcher_1.RequestWatcher);
66
+ });
67
+ // ============================================================================
68
+ // Enabled/Disabled
69
+ // ============================================================================
70
+ describe('enabled/disabled', () => {
71
+ it('should skip interception when disabled', async () => {
72
+ // Arrange
73
+ const module = await testing_1.Test.createTestingModule({
74
+ providers: [
75
+ request_watcher_1.RequestWatcher,
76
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
77
+ {
78
+ provide: nestlens_config_1.NESTLENS_CONFIG,
79
+ useValue: {
80
+ watchers: { request: { enabled: false } },
81
+ },
82
+ },
83
+ ],
84
+ }).compile();
85
+ const disabledWatcher = module.get(request_watcher_1.RequestWatcher);
86
+ const context = createMockContext();
87
+ const handler = createMockHandler({ result: 'test' });
88
+ // Act
89
+ const result = await disabledWatcher.intercept(context, handler).toPromise();
90
+ // Assert
91
+ expect(result).toEqual({ result: 'test' });
92
+ expect(mockCollector.collect).not.toHaveBeenCalled();
93
+ });
94
+ it('should intercept when enabled', async () => {
95
+ // Arrange
96
+ const context = createMockContext();
97
+ const handler = createMockHandler({ data: 'response' });
98
+ // Act
99
+ await watcher.intercept(context, handler).toPromise();
100
+ // Assert
101
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.any(Object), expect.any(String));
102
+ });
103
+ });
104
+ // ============================================================================
105
+ // Request ID
106
+ // ============================================================================
107
+ describe('request ID', () => {
108
+ it('should set request ID header on response', async () => {
109
+ // Arrange
110
+ const mockSetHeader = jest.fn();
111
+ const context = createMockContext({
112
+ response: { setHeader: mockSetHeader, statusCode: 200, getHeaders: jest.fn().mockReturnValue({}) },
113
+ });
114
+ const handler = createMockHandler();
115
+ // Act
116
+ await watcher.intercept(context, handler).toPromise();
117
+ // Assert
118
+ expect(mockSetHeader).toHaveBeenCalledWith(request_watcher_1.REQUEST_ID_HEADER, expect.any(String));
119
+ });
120
+ it('should generate unique request IDs', async () => {
121
+ // Arrange
122
+ const requestIds = [];
123
+ mockCollector.collect.mockImplementation((type, payload, requestId) => {
124
+ if (requestId)
125
+ requestIds.push(requestId);
126
+ return Promise.resolve();
127
+ });
128
+ // Act
129
+ await watcher.intercept(createMockContext(), createMockHandler()).toPromise();
130
+ await watcher.intercept(createMockContext(), createMockHandler()).toPromise();
131
+ // Assert
132
+ expect(requestIds[0]).not.toEqual(requestIds[1]);
133
+ });
134
+ });
135
+ // ============================================================================
136
+ // Path Skipping
137
+ // ============================================================================
138
+ describe('path skipping', () => {
139
+ it('should skip NestLens dashboard routes', async () => {
140
+ // Arrange
141
+ const context = createMockContext({
142
+ request: { path: '/nestlens/requests' },
143
+ });
144
+ const handler = createMockHandler();
145
+ // Act
146
+ await watcher.intercept(context, handler).toPromise();
147
+ // Assert
148
+ expect(mockCollector.collect).not.toHaveBeenCalled();
149
+ });
150
+ it('should skip NestLens API routes', async () => {
151
+ // Arrange
152
+ const context = createMockContext({
153
+ request: { path: '/nestlens/api/entries' },
154
+ });
155
+ const handler = createMockHandler();
156
+ // Act
157
+ await watcher.intercept(context, handler).toPromise();
158
+ // Assert
159
+ expect(mockCollector.collect).not.toHaveBeenCalled();
160
+ });
161
+ it('should skip configured ignore paths', async () => {
162
+ // Arrange
163
+ const module = await testing_1.Test.createTestingModule({
164
+ providers: [
165
+ request_watcher_1.RequestWatcher,
166
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
167
+ {
168
+ provide: nestlens_config_1.NESTLENS_CONFIG,
169
+ useValue: {
170
+ path: '/nestlens',
171
+ watchers: {
172
+ request: {
173
+ enabled: true,
174
+ ignorePaths: ['/health', '/metrics'],
175
+ },
176
+ },
177
+ },
178
+ },
179
+ ],
180
+ }).compile();
181
+ const watcherWithIgnore = module.get(request_watcher_1.RequestWatcher);
182
+ const context = createMockContext({
183
+ request: { path: '/health' },
184
+ });
185
+ // Act
186
+ await watcherWithIgnore.intercept(context, createMockHandler()).toPromise();
187
+ // Assert
188
+ expect(mockCollector.collect).not.toHaveBeenCalled();
189
+ });
190
+ });
191
+ // ============================================================================
192
+ // Request Data Capture
193
+ // ============================================================================
194
+ describe('request data capture', () => {
195
+ it('should capture HTTP method', async () => {
196
+ // Arrange
197
+ const context = createMockContext({
198
+ request: { method: 'POST' },
199
+ });
200
+ // Act
201
+ await watcher.intercept(context, createMockHandler()).toPromise();
202
+ // Assert
203
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({ method: 'POST' }), expect.any(String));
204
+ });
205
+ it('should capture URL and path', async () => {
206
+ // Arrange
207
+ const context = createMockContext({
208
+ request: {
209
+ url: '/api/users?page=1',
210
+ originalUrl: '/api/users?page=1',
211
+ path: '/api/users',
212
+ },
213
+ });
214
+ // Act
215
+ await watcher.intercept(context, createMockHandler()).toPromise();
216
+ // Assert
217
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
218
+ url: '/api/users?page=1',
219
+ path: '/api/users',
220
+ }), expect.any(String));
221
+ });
222
+ it('should capture query parameters', async () => {
223
+ // Arrange
224
+ const context = createMockContext({
225
+ request: { query: { page: '1', limit: '10' } },
226
+ });
227
+ // Act
228
+ await watcher.intercept(context, createMockHandler()).toPromise();
229
+ // Assert
230
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
231
+ query: { page: '1', limit: '10' },
232
+ }), expect.any(String));
233
+ });
234
+ it('should capture route parameters', async () => {
235
+ // Arrange
236
+ const context = createMockContext({
237
+ request: { params: { id: '123' } },
238
+ });
239
+ // Act
240
+ await watcher.intercept(context, createMockHandler()).toPromise();
241
+ // Assert
242
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
243
+ params: { id: '123' },
244
+ }), expect.any(String));
245
+ });
246
+ it('should capture user agent', async () => {
247
+ // Arrange
248
+ const context = createMockContext({
249
+ request: { headers: { 'user-agent': 'Mozilla/5.0' } },
250
+ });
251
+ // Act
252
+ await watcher.intercept(context, createMockHandler()).toPromise();
253
+ // Assert
254
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
255
+ userAgent: 'Mozilla/5.0',
256
+ }), expect.any(String));
257
+ });
258
+ it('should capture client IP', async () => {
259
+ // Arrange
260
+ const context = createMockContext({
261
+ request: { ip: '192.168.1.100' },
262
+ });
263
+ // Act
264
+ await watcher.intercept(context, createMockHandler()).toPromise();
265
+ // Assert
266
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
267
+ ip: '192.168.1.100',
268
+ }), expect.any(String));
269
+ });
270
+ it('should get IP from x-forwarded-for header', async () => {
271
+ // Arrange
272
+ const context = createMockContext({
273
+ request: {
274
+ ip: '127.0.0.1',
275
+ headers: { 'x-forwarded-for': '203.0.113.195, 70.41.3.18' },
276
+ },
277
+ });
278
+ // Act
279
+ await watcher.intercept(context, createMockHandler()).toPromise();
280
+ // Assert
281
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
282
+ ip: '203.0.113.195',
283
+ }), expect.any(String));
284
+ });
285
+ });
286
+ // ============================================================================
287
+ // Header Capture
288
+ // ============================================================================
289
+ describe('header capture', () => {
290
+ it('should capture headers', async () => {
291
+ // Arrange
292
+ const context = createMockContext({
293
+ request: {
294
+ headers: {
295
+ 'content-type': 'application/json',
296
+ 'accept': 'application/json',
297
+ },
298
+ },
299
+ });
300
+ // Act
301
+ await watcher.intercept(context, createMockHandler()).toPromise();
302
+ // Assert
303
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
304
+ headers: expect.objectContaining({
305
+ 'content-type': 'application/json',
306
+ 'accept': 'application/json',
307
+ }),
308
+ }), expect.any(String));
309
+ });
310
+ it('should redact sensitive headers', async () => {
311
+ // Arrange
312
+ const context = createMockContext({
313
+ request: {
314
+ headers: {
315
+ 'authorization': 'Bearer secret-token',
316
+ 'cookie': 'session=abc123',
317
+ 'x-api-key': 'api-key-value',
318
+ 'content-type': 'application/json',
319
+ },
320
+ },
321
+ });
322
+ // Act
323
+ await watcher.intercept(context, createMockHandler()).toPromise();
324
+ // Assert
325
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
326
+ headers: expect.objectContaining({
327
+ 'authorization': '***',
328
+ 'cookie': '***',
329
+ 'x-api-key': '***',
330
+ 'content-type': 'application/json',
331
+ }),
332
+ }), expect.any(String));
333
+ });
334
+ it('should join array headers', async () => {
335
+ // Arrange
336
+ const context = createMockContext({
337
+ request: {
338
+ headers: {
339
+ 'accept': ['text/html', 'application/json'],
340
+ },
341
+ },
342
+ });
343
+ // Act
344
+ await watcher.intercept(context, createMockHandler()).toPromise();
345
+ // Assert
346
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
347
+ headers: expect.objectContaining({
348
+ 'accept': 'text/html, application/json',
349
+ }),
350
+ }), expect.any(String));
351
+ });
352
+ });
353
+ // ============================================================================
354
+ // Body Capture
355
+ // ============================================================================
356
+ describe('body capture', () => {
357
+ it('should capture request body', async () => {
358
+ // Arrange
359
+ const context = createMockContext({
360
+ request: { body: { name: 'John', email: 'john@example.com' } },
361
+ });
362
+ // Act
363
+ await watcher.intercept(context, createMockHandler()).toPromise();
364
+ // Assert
365
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
366
+ body: { name: 'John', email: 'john@example.com' },
367
+ }), expect.any(String));
368
+ });
369
+ it('should capture response body', async () => {
370
+ // Arrange
371
+ const context = createMockContext();
372
+ const handler = createMockHandler({ id: 1, name: 'Created User' });
373
+ // Act
374
+ await watcher.intercept(context, handler).toPromise();
375
+ // Assert
376
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
377
+ responseBody: { id: 1, name: 'Created User' },
378
+ }), expect.any(String));
379
+ });
380
+ it('should handle empty body', async () => {
381
+ // Arrange
382
+ const context = createMockContext({
383
+ request: { body: undefined },
384
+ });
385
+ // Act
386
+ await watcher.intercept(context, createMockHandler()).toPromise();
387
+ // Assert
388
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
389
+ body: undefined,
390
+ }), expect.any(String));
391
+ });
392
+ });
393
+ // ============================================================================
394
+ // Response Status
395
+ // ============================================================================
396
+ describe('response status', () => {
397
+ it('should capture success status code', async () => {
398
+ // Arrange
399
+ const context = createMockContext({
400
+ response: { statusCode: 200, setHeader: jest.fn(), getHeaders: jest.fn().mockReturnValue({}) },
401
+ });
402
+ // Act
403
+ await watcher.intercept(context, createMockHandler()).toPromise();
404
+ // Assert
405
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
406
+ statusCode: 200,
407
+ }), expect.any(String));
408
+ });
409
+ it('should capture created status code', async () => {
410
+ // Arrange
411
+ const context = createMockContext({
412
+ response: { statusCode: 201, setHeader: jest.fn(), getHeaders: jest.fn().mockReturnValue({}) },
413
+ });
414
+ // Act
415
+ await watcher.intercept(context, createMockHandler()).toPromise();
416
+ // Assert
417
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
418
+ statusCode: 201,
419
+ }), expect.any(String));
420
+ });
421
+ });
422
+ // ============================================================================
423
+ // Error Handling
424
+ // ============================================================================
425
+ describe('error handling', () => {
426
+ it('should capture error response', async () => {
427
+ // Arrange
428
+ const context = createMockContext();
429
+ const error = { status: 500, message: 'Internal Server Error', name: 'Error' };
430
+ const handler = {
431
+ handle: () => (0, rxjs_1.throwError)(() => error),
432
+ };
433
+ // Act
434
+ try {
435
+ await watcher.intercept(context, handler).toPromise();
436
+ }
437
+ catch (e) {
438
+ // Expected
439
+ }
440
+ // Assert
441
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
442
+ statusCode: 500,
443
+ responseBody: expect.objectContaining({
444
+ error: 'Internal Server Error',
445
+ name: 'Error',
446
+ }),
447
+ }), expect.any(String));
448
+ });
449
+ it('should default to 500 status when error has no status', async () => {
450
+ // Arrange
451
+ const context = createMockContext();
452
+ const error = { message: 'Unknown error', name: 'Error' };
453
+ const handler = {
454
+ handle: () => (0, rxjs_1.throwError)(() => error),
455
+ };
456
+ // Act
457
+ try {
458
+ await watcher.intercept(context, handler).toPromise();
459
+ }
460
+ catch (e) {
461
+ // Expected
462
+ }
463
+ // Assert
464
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
465
+ statusCode: 500,
466
+ }), expect.any(String));
467
+ });
468
+ });
469
+ // ============================================================================
470
+ // Controller Info
471
+ // ============================================================================
472
+ describe('controller info', () => {
473
+ it('should capture controller action', async () => {
474
+ // Arrange
475
+ const context = createMockContext({
476
+ context: {
477
+ getClass: () => ({ name: 'UserController' }),
478
+ getHandler: () => ({ name: 'findAll' }),
479
+ },
480
+ });
481
+ // Act
482
+ await watcher.intercept(context, createMockHandler()).toPromise();
483
+ // Assert
484
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
485
+ controllerAction: 'UserController.findAll',
486
+ handler: 'findAll',
487
+ }), expect.any(String));
488
+ });
489
+ });
490
+ // ============================================================================
491
+ // Duration and Memory
492
+ // ============================================================================
493
+ describe('duration and memory', () => {
494
+ it('should capture request duration', async () => {
495
+ // Arrange
496
+ const context = createMockContext();
497
+ // Act
498
+ await watcher.intercept(context, createMockHandler()).toPromise();
499
+ // Assert
500
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
501
+ duration: expect.any(Number),
502
+ }), expect.any(String));
503
+ });
504
+ it('should capture memory usage', async () => {
505
+ // Arrange
506
+ const context = createMockContext();
507
+ // Act
508
+ await watcher.intercept(context, createMockHandler()).toPromise();
509
+ // Assert
510
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
511
+ memory: expect.any(Number),
512
+ }), expect.any(String));
513
+ });
514
+ });
515
+ // ============================================================================
516
+ // Body Size Limit (captureBody)
517
+ // ============================================================================
518
+ describe('body size limit', () => {
519
+ it('should truncate large request body', async () => {
520
+ // Arrange
521
+ const largeBody = { data: 'x'.repeat(100000) }; // >64KB
522
+ const module = await testing_1.Test.createTestingModule({
523
+ providers: [
524
+ request_watcher_1.RequestWatcher,
525
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
526
+ {
527
+ provide: nestlens_config_1.NESTLENS_CONFIG,
528
+ useValue: {
529
+ path: '/nestlens',
530
+ watchers: {
531
+ request: { enabled: true, maxBodySize: 1000 },
532
+ },
533
+ },
534
+ },
535
+ ],
536
+ }).compile();
537
+ const watcherWithLimit = module.get(request_watcher_1.RequestWatcher);
538
+ const context = createMockContext({
539
+ request: { body: largeBody },
540
+ });
541
+ // Act
542
+ await watcherWithLimit.intercept(context, createMockHandler()).toPromise();
543
+ // Assert
544
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
545
+ body: expect.objectContaining({
546
+ _truncated: true,
547
+ _size: expect.any(Number),
548
+ }),
549
+ }), expect.any(String));
550
+ });
551
+ it('should handle non-serializable body', async () => {
552
+ // Arrange - circular reference
553
+ const circularBody = { name: 'test' };
554
+ circularBody.self = circularBody;
555
+ const context = createMockContext({
556
+ request: { body: circularBody },
557
+ });
558
+ // Act
559
+ await watcher.intercept(context, createMockHandler()).toPromise();
560
+ // Assert
561
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
562
+ body: expect.objectContaining({
563
+ _error: 'Unable to serialize body',
564
+ }),
565
+ }), expect.any(String));
566
+ });
567
+ });
568
+ // ============================================================================
569
+ // Controller Info Config
570
+ // ============================================================================
571
+ describe('controller info config', () => {
572
+ it('should skip controller info when captureControllerInfo is false', async () => {
573
+ // Arrange
574
+ const module = await testing_1.Test.createTestingModule({
575
+ providers: [
576
+ request_watcher_1.RequestWatcher,
577
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
578
+ {
579
+ provide: nestlens_config_1.NESTLENS_CONFIG,
580
+ useValue: {
581
+ path: '/nestlens',
582
+ watchers: {
583
+ request: { enabled: true, captureControllerInfo: false },
584
+ },
585
+ },
586
+ },
587
+ ],
588
+ }).compile();
589
+ const watcherNoController = module.get(request_watcher_1.RequestWatcher);
590
+ const context = createMockContext();
591
+ // Act
592
+ await watcherNoController.intercept(context, createMockHandler()).toPromise();
593
+ // Assert
594
+ const callArg = mockCollector.collect.mock.calls[0][1];
595
+ expect(callArg.controllerAction).toBeUndefined();
596
+ expect(callArg.handler).toBeUndefined();
597
+ });
598
+ it('should handle error when getting controller info', async () => {
599
+ // Arrange
600
+ const context = createMockContext({
601
+ context: {
602
+ getClass: () => { throw new Error('No controller'); },
603
+ getHandler: () => ({ name: 'test' }),
604
+ },
605
+ });
606
+ // Act
607
+ await watcher.intercept(context, createMockHandler()).toPromise();
608
+ // Assert - should not throw and should still collect
609
+ expect(mockCollector.collect).toHaveBeenCalled();
610
+ });
611
+ });
612
+ // ============================================================================
613
+ // User Capture
614
+ // ============================================================================
615
+ describe('user capture', () => {
616
+ it('should skip user capture when captureUser is false', async () => {
617
+ // Arrange
618
+ const module = await testing_1.Test.createTestingModule({
619
+ providers: [
620
+ request_watcher_1.RequestWatcher,
621
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
622
+ {
623
+ provide: nestlens_config_1.NESTLENS_CONFIG,
624
+ useValue: {
625
+ path: '/nestlens',
626
+ watchers: {
627
+ request: { enabled: true, captureUser: false },
628
+ },
629
+ },
630
+ },
631
+ ],
632
+ }).compile();
633
+ const watcherNoUser = module.get(request_watcher_1.RequestWatcher);
634
+ const context = createMockContext({
635
+ request: { user: { id: 1, name: 'John' } },
636
+ });
637
+ // Act
638
+ await watcherNoUser.intercept(context, createMockHandler()).toPromise();
639
+ // Assert
640
+ const callArg = mockCollector.collect.mock.calls[0][1];
641
+ expect(callArg.user).toBeUndefined();
642
+ });
643
+ it('should capture user with id, name, email', async () => {
644
+ // Arrange
645
+ const module = await testing_1.Test.createTestingModule({
646
+ providers: [
647
+ request_watcher_1.RequestWatcher,
648
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
649
+ {
650
+ provide: nestlens_config_1.NESTLENS_CONFIG,
651
+ useValue: {
652
+ path: '/nestlens',
653
+ watchers: {
654
+ request: { enabled: true, captureUser: true },
655
+ },
656
+ },
657
+ },
658
+ ],
659
+ }).compile();
660
+ const watcherWithUser = module.get(request_watcher_1.RequestWatcher);
661
+ const context = createMockContext({
662
+ request: { user: { id: 123, name: 'John Doe', email: 'john@example.com' } },
663
+ });
664
+ // Act
665
+ await watcherWithUser.intercept(context, createMockHandler()).toPromise();
666
+ // Assert
667
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
668
+ user: { id: 123, name: 'John Doe', email: 'john@example.com' },
669
+ }), expect.any(String));
670
+ });
671
+ it('should capture user with alternative field names', async () => {
672
+ // Arrange
673
+ const module = await testing_1.Test.createTestingModule({
674
+ providers: [
675
+ request_watcher_1.RequestWatcher,
676
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
677
+ {
678
+ provide: nestlens_config_1.NESTLENS_CONFIG,
679
+ useValue: {
680
+ path: '/nestlens',
681
+ watchers: {
682
+ request: { enabled: true, captureUser: true },
683
+ },
684
+ },
685
+ },
686
+ ],
687
+ }).compile();
688
+ const watcherWithUser = module.get(request_watcher_1.RequestWatcher);
689
+ const context = createMockContext({
690
+ request: { user: { _id: 'mongo-id', username: 'johndoe', emailAddress: 'john@test.com' } },
691
+ });
692
+ // Act
693
+ await watcherWithUser.intercept(context, createMockHandler()).toPromise();
694
+ // Assert
695
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
696
+ user: { id: 'mongo-id', name: 'johndoe', email: 'john@test.com' },
697
+ }), expect.any(String));
698
+ });
699
+ });
700
+ // ============================================================================
701
+ // Session Capture
702
+ // ============================================================================
703
+ describe('session capture', () => {
704
+ it('should skip session capture when captureSession is false', async () => {
705
+ // Arrange
706
+ const module = await testing_1.Test.createTestingModule({
707
+ providers: [
708
+ request_watcher_1.RequestWatcher,
709
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
710
+ {
711
+ provide: nestlens_config_1.NESTLENS_CONFIG,
712
+ useValue: {
713
+ path: '/nestlens',
714
+ watchers: {
715
+ request: { enabled: true, captureSession: false },
716
+ },
717
+ },
718
+ },
719
+ ],
720
+ }).compile();
721
+ const watcherNoSession = module.get(request_watcher_1.RequestWatcher);
722
+ const context = createMockContext({
723
+ request: { session: { userId: 1 } },
724
+ });
725
+ // Act
726
+ await watcherNoSession.intercept(context, createMockHandler()).toPromise();
727
+ // Assert
728
+ const callArg = mockCollector.collect.mock.calls[0][1];
729
+ expect(callArg.session).toBeUndefined();
730
+ });
731
+ it('should capture session and filter internal properties', async () => {
732
+ // Arrange
733
+ const module = await testing_1.Test.createTestingModule({
734
+ providers: [
735
+ request_watcher_1.RequestWatcher,
736
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
737
+ {
738
+ provide: nestlens_config_1.NESTLENS_CONFIG,
739
+ useValue: {
740
+ path: '/nestlens',
741
+ watchers: {
742
+ request: { enabled: true, captureSession: true },
743
+ },
744
+ },
745
+ },
746
+ ],
747
+ }).compile();
748
+ const watcherWithSession = module.get(request_watcher_1.RequestWatcher);
749
+ const context = createMockContext({
750
+ request: {
751
+ session: {
752
+ userId: 123,
753
+ role: 'admin',
754
+ _internal: 'should-be-filtered',
755
+ cookie: 'should-be-filtered',
756
+ },
757
+ },
758
+ });
759
+ // Act
760
+ await watcherWithSession.intercept(context, createMockHandler()).toPromise();
761
+ // Assert
762
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
763
+ session: { userId: 123, role: 'admin' },
764
+ }), expect.any(String));
765
+ });
766
+ it('should return undefined for empty session after filtering', async () => {
767
+ // Arrange
768
+ const module = await testing_1.Test.createTestingModule({
769
+ providers: [
770
+ request_watcher_1.RequestWatcher,
771
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
772
+ {
773
+ provide: nestlens_config_1.NESTLENS_CONFIG,
774
+ useValue: {
775
+ path: '/nestlens',
776
+ watchers: {
777
+ request: { enabled: true, captureSession: true },
778
+ },
779
+ },
780
+ },
781
+ ],
782
+ }).compile();
783
+ const watcherWithSession = module.get(request_watcher_1.RequestWatcher);
784
+ const context = createMockContext({
785
+ request: {
786
+ session: { _private: 'value', cookie: 'session-cookie' },
787
+ },
788
+ });
789
+ // Act
790
+ await watcherWithSession.intercept(context, createMockHandler()).toPromise();
791
+ // Assert
792
+ const callArg = mockCollector.collect.mock.calls[0][1];
793
+ expect(callArg.session).toBeUndefined();
794
+ });
795
+ });
796
+ // ============================================================================
797
+ // Response Headers Capture
798
+ // ============================================================================
799
+ describe('response headers capture', () => {
800
+ it('should skip response headers when captureResponseHeaders is false', async () => {
801
+ // Arrange
802
+ const module = await testing_1.Test.createTestingModule({
803
+ providers: [
804
+ request_watcher_1.RequestWatcher,
805
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
806
+ {
807
+ provide: nestlens_config_1.NESTLENS_CONFIG,
808
+ useValue: {
809
+ path: '/nestlens',
810
+ watchers: {
811
+ request: { enabled: true, captureResponseHeaders: false },
812
+ },
813
+ },
814
+ },
815
+ ],
816
+ }).compile();
817
+ const watcherNoRespHeaders = module.get(request_watcher_1.RequestWatcher);
818
+ const context = createMockContext({
819
+ response: {
820
+ statusCode: 200,
821
+ setHeader: jest.fn(),
822
+ getHeaders: jest.fn().mockReturnValue({ 'content-type': 'application/json' }),
823
+ },
824
+ });
825
+ // Act
826
+ await watcherNoRespHeaders.intercept(context, createMockHandler()).toPromise();
827
+ // Assert
828
+ const callArg = mockCollector.collect.mock.calls[0][1];
829
+ expect(callArg.responseHeaders).toBeUndefined();
830
+ });
831
+ it('should capture response headers with different value types', async () => {
832
+ // Arrange
833
+ const module = await testing_1.Test.createTestingModule({
834
+ providers: [
835
+ request_watcher_1.RequestWatcher,
836
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
837
+ {
838
+ provide: nestlens_config_1.NESTLENS_CONFIG,
839
+ useValue: {
840
+ path: '/nestlens',
841
+ watchers: {
842
+ request: { enabled: true, captureResponseHeaders: true },
843
+ },
844
+ },
845
+ },
846
+ ],
847
+ }).compile();
848
+ const watcherWithRespHeaders = module.get(request_watcher_1.RequestWatcher);
849
+ const context = createMockContext({
850
+ response: {
851
+ statusCode: 200,
852
+ setHeader: jest.fn(),
853
+ getHeaders: jest.fn().mockReturnValue({
854
+ 'content-type': 'application/json',
855
+ 'content-length': 1234,
856
+ 'set-cookie': ['cookie1=value1', 'cookie2=value2'],
857
+ }),
858
+ },
859
+ });
860
+ // Act
861
+ await watcherWithRespHeaders.intercept(context, createMockHandler()).toPromise();
862
+ // Assert
863
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
864
+ responseHeaders: {
865
+ 'content-type': 'application/json',
866
+ 'content-length': '1234',
867
+ 'set-cookie': 'cookie1=value1, cookie2=value2',
868
+ },
869
+ }), expect.any(String));
870
+ });
871
+ it('should handle error when capturing response headers', async () => {
872
+ // Arrange
873
+ const module = await testing_1.Test.createTestingModule({
874
+ providers: [
875
+ request_watcher_1.RequestWatcher,
876
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
877
+ {
878
+ provide: nestlens_config_1.NESTLENS_CONFIG,
879
+ useValue: {
880
+ path: '/nestlens',
881
+ watchers: {
882
+ request: { enabled: true, captureResponseHeaders: true },
883
+ },
884
+ },
885
+ },
886
+ ],
887
+ }).compile();
888
+ const watcherWithRespHeaders = module.get(request_watcher_1.RequestWatcher);
889
+ const context = createMockContext({
890
+ response: {
891
+ statusCode: 200,
892
+ setHeader: jest.fn(),
893
+ getHeaders: jest.fn().mockImplementation(() => { throw new Error('Header error'); }),
894
+ },
895
+ });
896
+ // Act
897
+ await watcherWithRespHeaders.intercept(context, createMockHandler()).toPromise();
898
+ // Assert - should not throw and should still collect
899
+ expect(mockCollector.collect).toHaveBeenCalled();
900
+ });
901
+ });
902
+ // ============================================================================
903
+ // Custom Tags
904
+ // ============================================================================
905
+ describe('custom tags', () => {
906
+ it('should call tags function when configured', async () => {
907
+ // Arrange
908
+ const tagsFn = jest.fn().mockResolvedValue(['important', 'api-v2']);
909
+ const module = await testing_1.Test.createTestingModule({
910
+ providers: [
911
+ request_watcher_1.RequestWatcher,
912
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
913
+ {
914
+ provide: nestlens_config_1.NESTLENS_CONFIG,
915
+ useValue: {
916
+ path: '/nestlens',
917
+ watchers: {
918
+ request: { enabled: true, tags: tagsFn },
919
+ },
920
+ },
921
+ },
922
+ ],
923
+ }).compile();
924
+ const watcherWithTags = module.get(request_watcher_1.RequestWatcher);
925
+ const context = createMockContext();
926
+ // Act
927
+ await watcherWithTags.intercept(context, createMockHandler()).toPromise();
928
+ // Assert - tags function was called with request
929
+ expect(tagsFn).toHaveBeenCalled();
930
+ });
931
+ it('should not throw when tags function returns empty array', async () => {
932
+ // Arrange
933
+ const tagsFn = jest.fn().mockResolvedValue([]);
934
+ const module = await testing_1.Test.createTestingModule({
935
+ providers: [
936
+ request_watcher_1.RequestWatcher,
937
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
938
+ {
939
+ provide: nestlens_config_1.NESTLENS_CONFIG,
940
+ useValue: {
941
+ path: '/nestlens',
942
+ watchers: {
943
+ request: { enabled: true, tags: tagsFn },
944
+ },
945
+ },
946
+ },
947
+ ],
948
+ }).compile();
949
+ const watcherWithTags = module.get(request_watcher_1.RequestWatcher);
950
+ const context = createMockContext();
951
+ // Act & Assert - should complete without throwing
952
+ await expect(watcherWithTags.intercept(context, createMockHandler()).toPromise()).resolves.toBeDefined();
953
+ expect(tagsFn).toHaveBeenCalled();
954
+ });
955
+ it('should not throw when tags function throws error', async () => {
956
+ // Arrange
957
+ const tagsFn = jest.fn().mockRejectedValue(new Error('Tags error'));
958
+ const module = await testing_1.Test.createTestingModule({
959
+ providers: [
960
+ request_watcher_1.RequestWatcher,
961
+ { provide: collector_service_1.CollectorService, useValue: mockCollector },
962
+ {
963
+ provide: nestlens_config_1.NESTLENS_CONFIG,
964
+ useValue: {
965
+ path: '/nestlens',
966
+ watchers: {
967
+ request: { enabled: true, tags: tagsFn },
968
+ },
969
+ },
970
+ },
971
+ ],
972
+ }).compile();
973
+ const watcherWithTags = module.get(request_watcher_1.RequestWatcher);
974
+ const context = createMockContext();
975
+ // Act & Assert - should complete without throwing
976
+ await expect(watcherWithTags.intercept(context, createMockHandler()).toPromise()).resolves.toBeDefined();
977
+ expect(tagsFn).toHaveBeenCalled();
978
+ });
979
+ });
980
+ // ============================================================================
981
+ // X-Forwarded-For Edge Cases
982
+ // ============================================================================
983
+ describe('x-forwarded-for edge cases', () => {
984
+ it('should handle array x-forwarded-for header', async () => {
985
+ // Arrange
986
+ const context = createMockContext({
987
+ request: {
988
+ ip: '127.0.0.1',
989
+ headers: { 'x-forwarded-for': ['10.0.0.1', '192.168.1.1'] },
990
+ },
991
+ });
992
+ // Act
993
+ await watcher.intercept(context, createMockHandler()).toPromise();
994
+ // Assert
995
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
996
+ ip: '10.0.0.1',
997
+ }), expect.any(String));
998
+ });
999
+ it('should use socket remoteAddress when ip is undefined', async () => {
1000
+ // Arrange
1001
+ const context = createMockContext({
1002
+ request: {
1003
+ ip: undefined,
1004
+ socket: { remoteAddress: '172.16.0.1' },
1005
+ headers: {},
1006
+ },
1007
+ });
1008
+ // Act
1009
+ await watcher.intercept(context, createMockHandler()).toPromise();
1010
+ // Assert
1011
+ expect(mockCollector.collect).toHaveBeenCalledWith('request', expect.objectContaining({
1012
+ ip: '172.16.0.1',
1013
+ }), expect.any(String));
1014
+ });
1015
+ });
1016
+ });
1017
+ //# sourceMappingURL=request.watcher.spec.js.map