@resolveio/server-lib 22.2.34 → 22.2.36

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 (649) hide show
  1. package/ai/assistant-core-heuristics.d.ts +11 -0
  2. package/ai/assistant-core-heuristics.js +531 -0
  3. package/ai/assistant-core-heuristics.js.map +1 -0
  4. package/client-server-app.d.ts +1 -0
  5. package/client-server-app.js +68 -0
  6. package/client-server-app.js.map +1 -0
  7. package/collections/ai-terminal-conversation.collection.d.ts +2 -0
  8. package/collections/ai-terminal-conversation.collection.js +140 -0
  9. package/collections/ai-terminal-conversation.collection.js.map +1 -0
  10. package/collections/ai-terminal-issue-report.collection.d.ts +2 -0
  11. package/collections/ai-terminal-issue-report.collection.js +148 -0
  12. package/collections/ai-terminal-issue-report.collection.js.map +1 -0
  13. package/collections/ai-terminal-message.collection.d.ts +2 -0
  14. package/collections/ai-terminal-message.collection.js +121 -0
  15. package/collections/ai-terminal-message.collection.js.map +1 -0
  16. package/collections/app-setting.collection.d.ts +3 -0
  17. package/collections/app-setting.collection.js +103 -0
  18. package/collections/app-setting.collection.js.map +1 -0
  19. package/collections/app-status.collection.d.ts +3 -0
  20. package/collections/app-status.collection.js +57 -0
  21. package/collections/app-status.collection.js.map +1 -0
  22. package/collections/communication-metric.collection.d.ts +2 -0
  23. package/collections/communication-metric.collection.js +133 -0
  24. package/collections/communication-metric.collection.js.map +1 -0
  25. package/collections/counter.collection.d.ts +3 -0
  26. package/collections/counter.collection.js +56 -0
  27. package/collections/counter.collection.js.map +1 -0
  28. package/collections/cron-job-history.collection.d.ts +3 -0
  29. package/collections/cron-job-history.collection.js +137 -0
  30. package/collections/cron-job-history.collection.js.map +1 -0
  31. package/collections/cron-job.collection.d.ts +3 -0
  32. package/collections/cron-job.collection.js +92 -0
  33. package/collections/cron-job.collection.js.map +1 -0
  34. package/collections/customer-notification.collection.d.ts +3 -0
  35. package/collections/customer-notification.collection.js +130 -0
  36. package/collections/customer-notification.collection.js.map +1 -0
  37. package/collections/customer-portal-password.collection.d.ts +3 -0
  38. package/collections/customer-portal-password.collection.js +75 -0
  39. package/collections/customer-portal-password.collection.js.map +1 -0
  40. package/collections/email-history.collection.d.ts +3 -0
  41. package/collections/email-history.collection.js +121 -0
  42. package/collections/email-history.collection.js.map +1 -0
  43. package/collections/email-verified.collection.d.ts +3 -0
  44. package/collections/email-verified.collection.js +61 -0
  45. package/collections/email-verified.collection.js.map +1 -0
  46. package/collections/file.collection.d.ts +3 -0
  47. package/collections/file.collection.js +74 -0
  48. package/collections/file.collection.js.map +1 -0
  49. package/collections/flag-update.collection.d.ts +3 -0
  50. package/collections/flag-update.collection.js +57 -0
  51. package/collections/flag-update.collection.js.map +1 -0
  52. package/collections/flag.collection.d.ts +3 -0
  53. package/collections/flag.collection.js +57 -0
  54. package/collections/flag.collection.js.map +1 -0
  55. package/collections/log-method-latency.collection.d.ts +3 -0
  56. package/collections/log-method-latency.collection.js +77 -0
  57. package/collections/log-method-latency.collection.js.map +1 -0
  58. package/collections/log-subscription.collection.d.ts +3 -0
  59. package/collections/log-subscription.collection.js +80 -0
  60. package/collections/log-subscription.collection.js.map +1 -0
  61. package/collections/log.collection.d.ts +3 -0
  62. package/collections/log.collection.js +93 -0
  63. package/collections/log.collection.js.map +1 -0
  64. package/collections/logged-in-users.collection.d.ts +3 -0
  65. package/collections/logged-in-users.collection.js +67 -0
  66. package/collections/logged-in-users.collection.js.map +1 -0
  67. package/collections/monitor-cpu.collection.d.ts +3 -0
  68. package/collections/monitor-cpu.collection.js +65 -0
  69. package/collections/monitor-cpu.collection.js.map +1 -0
  70. package/collections/monitor-function.collection.d.ts +3 -0
  71. package/collections/monitor-function.collection.js +74 -0
  72. package/collections/monitor-function.collection.js.map +1 -0
  73. package/collections/monitor-memory.collection.d.ts +3 -0
  74. package/collections/monitor-memory.collection.js +77 -0
  75. package/collections/monitor-memory.collection.js.map +1 -0
  76. package/collections/monitor-mongo.collection.d.ts +3 -0
  77. package/collections/monitor-mongo.collection.js +71 -0
  78. package/collections/monitor-mongo.collection.js.map +1 -0
  79. package/collections/notification.collection.d.ts +3 -0
  80. package/collections/notification.collection.js +57 -0
  81. package/collections/notification.collection.js.map +1 -0
  82. package/collections/openai-usage-ledger.collection.d.ts +2 -0
  83. package/collections/openai-usage-ledger.collection.js +124 -0
  84. package/collections/openai-usage-ledger.collection.js.map +1 -0
  85. package/collections/report-builder-dashboard-builder.collection.d.ts +3 -0
  86. package/collections/report-builder-dashboard-builder.collection.js +109 -0
  87. package/collections/report-builder-dashboard-builder.collection.js.map +1 -0
  88. package/collections/report-builder-library.collection.d.ts +3 -0
  89. package/collections/report-builder-library.collection.js +87 -0
  90. package/collections/report-builder-library.collection.js.map +1 -0
  91. package/collections/report-builder-report.collection.d.ts +4 -0
  92. package/collections/report-builder-report.collection.js +180 -0
  93. package/collections/report-builder-report.collection.js.map +1 -0
  94. package/collections/user-group.collection.d.ts +4 -0
  95. package/collections/user-group.collection.js +89 -0
  96. package/collections/user-group.collection.js.map +1 -0
  97. package/collections/user-guide.collection.d.ts +3 -0
  98. package/collections/user-guide.collection.js +57 -0
  99. package/collections/user-guide.collection.js.map +1 -0
  100. package/collections/user.collection.d.ts +4 -0
  101. package/collections/user.collection.js +180 -0
  102. package/collections/user.collection.js.map +1 -0
  103. package/cron/cron.d.ts +14 -0
  104. package/cron/cron.js +216 -0
  105. package/cron/cron.js.map +1 -0
  106. package/fixtures/cron-jobs.d.ts +1 -0
  107. package/fixtures/cron-jobs.js +150 -0
  108. package/fixtures/cron-jobs.js.map +1 -0
  109. package/fixtures/init.d.ts +1 -0
  110. package/fixtures/init.js +91 -0
  111. package/fixtures/init.js.map +1 -0
  112. package/http/auth.d.ts +2 -0
  113. package/http/auth.js +903 -0
  114. package/http/auth.js.map +1 -0
  115. package/http/health.d.ts +1 -0
  116. package/http/health.js +11 -0
  117. package/http/health.js.map +1 -0
  118. package/http/home.d.ts +1 -0
  119. package/http/home.js +134 -0
  120. package/http/home.js.map +1 -0
  121. package/http/slow-query-publication.d.ts +2 -0
  122. package/http/slow-query-publication.js +99 -0
  123. package/http/slow-query-publication.js.map +1 -0
  124. package/index.d.ts +1 -0
  125. package/index.js +19 -0
  126. package/index.js.map +1 -0
  127. package/managers/communication-metric.manager.d.ts +16 -0
  128. package/managers/communication-metric.manager.js +134 -0
  129. package/managers/communication-metric.manager.js.map +1 -0
  130. package/managers/cron.manager.d.ts +20 -0
  131. package/managers/cron.manager.js +534 -0
  132. package/managers/cron.manager.js.map +1 -0
  133. package/managers/customer-notification-content.manager.d.ts +55 -0
  134. package/managers/customer-notification-content.manager.js +158 -0
  135. package/managers/customer-notification-content.manager.js.map +1 -0
  136. package/managers/diagnostic-manager-bootstrap.d.ts +9 -0
  137. package/managers/diagnostic-manager-bootstrap.js +260 -0
  138. package/managers/diagnostic-manager-bootstrap.js.map +1 -0
  139. package/managers/error-auto-fix.manager.d.ts +149 -0
  140. package/managers/error-auto-fix.manager.js +3064 -0
  141. package/managers/error-auto-fix.manager.js.map +1 -0
  142. package/managers/local-log.manager.d.ts +18 -0
  143. package/managers/local-log.manager.js +88 -0
  144. package/managers/local-log.manager.js.map +1 -0
  145. package/managers/method.manager.d.ts +77 -0
  146. package/managers/method.manager.js +1701 -0
  147. package/managers/method.manager.js.map +1 -0
  148. package/managers/mongo.manager.d.ts +222 -0
  149. package/managers/mongo.manager.js +4984 -0
  150. package/managers/mongo.manager.js.map +1 -0
  151. package/managers/monitor.manager.d.ts +69 -0
  152. package/managers/monitor.manager.js +534 -0
  153. package/managers/monitor.manager.js.map +1 -0
  154. package/managers/openai-usage-ledger.manager.d.ts +15 -0
  155. package/managers/openai-usage-ledger.manager.js +144 -0
  156. package/managers/openai-usage-ledger.manager.js.map +1 -0
  157. package/managers/slow-query-verifier.manager.d.ts +144 -0
  158. package/managers/slow-query-verifier.manager.js +3857 -0
  159. package/managers/slow-query-verifier.manager.js.map +1 -0
  160. package/managers/slow-query.manager.d.ts +28 -0
  161. package/managers/slow-query.manager.js +468 -0
  162. package/managers/slow-query.manager.js.map +1 -0
  163. package/managers/subscription.manager.d.ts +169 -0
  164. package/managers/subscription.manager.js +3422 -0
  165. package/managers/subscription.manager.js.map +1 -0
  166. package/managers/websocket.manager.d.ts +73 -0
  167. package/managers/websocket.manager.js +673 -0
  168. package/managers/websocket.manager.js.map +1 -0
  169. package/managers/worker-dispatcher.manager.d.ts +117 -0
  170. package/managers/worker-dispatcher.manager.js +1210 -0
  171. package/managers/worker-dispatcher.manager.js.map +1 -0
  172. package/managers/worker-server.manager.d.ts +16 -0
  173. package/managers/worker-server.manager.js +530 -0
  174. package/managers/worker-server.manager.js.map +1 -0
  175. package/methods/accounts.d.ts +2 -0
  176. package/methods/accounts.js +624 -0
  177. package/methods/accounts.js.map +1 -0
  178. package/methods/ai-terminal.d.ts +304 -0
  179. package/methods/ai-terminal.js +25096 -0
  180. package/methods/ai-terminal.js.map +1 -0
  181. package/methods/app-settings.d.ts +2 -0
  182. package/methods/app-settings.js +169 -0
  183. package/methods/app-settings.js.map +1 -0
  184. package/methods/aws.d.ts +2 -0
  185. package/methods/aws.js +874 -0
  186. package/methods/aws.js.map +1 -0
  187. package/methods/collections.d.ts +2 -0
  188. package/methods/collections.js +626 -0
  189. package/methods/collections.js.map +1 -0
  190. package/methods/counters.d.ts +2 -0
  191. package/methods/counters.js +111 -0
  192. package/methods/counters.js.map +1 -0
  193. package/methods/cron-jobs.d.ts +2 -0
  194. package/methods/cron-jobs.js +2471 -0
  195. package/methods/cron-jobs.js.map +1 -0
  196. package/methods/customer-notifications.d.ts +2 -0
  197. package/methods/customer-notifications.js +528 -0
  198. package/methods/customer-notifications.js.map +1 -0
  199. package/methods/diagnostics.d.ts +2 -0
  200. package/methods/diagnostics.js +514 -0
  201. package/methods/diagnostics.js.map +1 -0
  202. package/methods/flag-updates.d.ts +2 -0
  203. package/methods/flag-updates.js +8 -0
  204. package/methods/flag-updates.js.map +1 -0
  205. package/methods/flags.d.ts +2 -0
  206. package/methods/flags.js +8 -0
  207. package/methods/flags.js.map +1 -0
  208. package/methods/logs.d.ts +2 -0
  209. package/methods/logs.js +750 -0
  210. package/methods/logs.js.map +1 -0
  211. package/methods/mongo-explorer.d.ts +2 -0
  212. package/methods/mongo-explorer.js +1811 -0
  213. package/methods/mongo-explorer.js.map +1 -0
  214. package/methods/monitor.d.ts +2 -0
  215. package/methods/monitor.js +543 -0
  216. package/methods/monitor.js.map +1 -0
  217. package/methods/pdf.d.ts +2 -0
  218. package/methods/pdf.js +1195 -0
  219. package/methods/pdf.js.map +1 -0
  220. package/methods/publications.d.ts +1 -0
  221. package/methods/publications.js +183 -0
  222. package/methods/publications.js.map +1 -0
  223. package/methods/report-builder.d.ts +2 -0
  224. package/methods/report-builder.js +3099 -0
  225. package/methods/report-builder.js.map +1 -0
  226. package/methods/support.d.ts +2 -0
  227. package/methods/support.js +322 -0
  228. package/methods/support.js.map +1 -0
  229. package/models/ai-terminal-conversation.model.d.ts +17 -0
  230. package/models/ai-terminal-conversation.model.js +4 -0
  231. package/models/ai-terminal-conversation.model.js.map +1 -0
  232. package/models/ai-terminal-issue-report.model.d.ts +19 -0
  233. package/models/ai-terminal-issue-report.model.js +4 -0
  234. package/models/ai-terminal-issue-report.model.js.map +1 -0
  235. package/models/ai-terminal-message.model.d.ts +22 -0
  236. package/models/ai-terminal-message.model.js +4 -0
  237. package/models/ai-terminal-message.model.js.map +1 -0
  238. package/models/app-setting.model.d.ts +16 -0
  239. package/models/app-setting.model.js +4 -0
  240. package/models/app-setting.model.js.map +1 -0
  241. package/{src/models/app-status.model.ts → models/app-status.model.d.ts} +2 -3
  242. package/models/app-status.model.js +4 -0
  243. package/models/app-status.model.js.map +1 -0
  244. package/{src/models/billing-logged-in-users.model.ts → models/billing-logged-in-users.model.d.ts} +4 -5
  245. package/models/billing-logged-in-users.model.js +4 -0
  246. package/models/billing-logged-in-users.model.js.map +1 -0
  247. package/models/collection-document.model.d.ts +21 -0
  248. package/models/collection-document.model.js +4 -0
  249. package/models/collection-document.model.js.map +1 -0
  250. package/models/communication-metric.model.d.ts +20 -0
  251. package/models/communication-metric.model.js +4 -0
  252. package/models/communication-metric.model.js.map +1 -0
  253. package/{src/models/counter.model.ts → models/counter.model.d.ts} +3 -4
  254. package/models/counter.model.js +4 -0
  255. package/models/counter.model.js.map +1 -0
  256. package/models/cron-job-history.model.d.ts +15 -0
  257. package/models/cron-job-history.model.js +4 -0
  258. package/models/cron-job-history.model.js.map +1 -0
  259. package/models/cron-job.model.d.ts +14 -0
  260. package/models/cron-job.model.js +4 -0
  261. package/models/cron-job.model.js.map +1 -0
  262. package/models/customer-notification.model.d.ts +26 -0
  263. package/models/customer-notification.model.js +4 -0
  264. package/models/customer-notification.model.js.map +1 -0
  265. package/models/customer-portal-password.model.d.ts +11 -0
  266. package/models/customer-portal-password.model.js +4 -0
  267. package/models/customer-portal-password.model.js.map +1 -0
  268. package/models/dialog.model.d.ts +23 -0
  269. package/models/dialog.model.js +4 -0
  270. package/models/dialog.model.js.map +1 -0
  271. package/models/email-history.model.d.ts +30 -0
  272. package/{src/models/email-history.model.ts → models/email-history.model.js} +4 -34
  273. package/models/email-history.model.js.map +1 -0
  274. package/{src/models/email-verified.model.ts → models/email-verified.model.d.ts} +5 -6
  275. package/models/email-verified.model.js +4 -0
  276. package/models/email-verified.model.js.map +1 -0
  277. package/{src/models/file.model.ts → models/file.model.d.ts} +7 -8
  278. package/models/file.model.js +4 -0
  279. package/models/file.model.js.map +1 -0
  280. package/{src/models/flag-update.model.ts → models/flag-update.model.d.ts} +3 -4
  281. package/models/flag-update.model.js +4 -0
  282. package/models/flag-update.model.js.map +1 -0
  283. package/{src/models/flag.model.ts → models/flag.model.d.ts} +3 -4
  284. package/models/flag.model.js +4 -0
  285. package/models/flag.model.js.map +1 -0
  286. package/models/log-method-latency.model.d.ts +10 -0
  287. package/models/log-method-latency.model.js +4 -0
  288. package/models/log-method-latency.model.js.map +1 -0
  289. package/{src/models/log-subscription.model.ts → models/log-subscription.model.d.ts} +9 -11
  290. package/models/log-subscription.model.js +4 -0
  291. package/models/log-subscription.model.js.map +1 -0
  292. package/models/log.model.d.ts +17 -0
  293. package/models/log.model.js +4 -0
  294. package/models/log.model.js.map +1 -0
  295. package/{src/models/logged-in-users.model.ts → models/logged-in-users.model.d.ts} +5 -6
  296. package/models/logged-in-users.model.js +4 -0
  297. package/models/logged-in-users.model.js.map +1 -0
  298. package/{src/models/method-response.model.ts → models/method-response.model.d.ts} +6 -7
  299. package/models/method-response.model.js +4 -0
  300. package/models/method-response.model.js.map +1 -0
  301. package/models/method.model.d.ts +24 -0
  302. package/models/method.model.js +4 -0
  303. package/models/method.model.js.map +1 -0
  304. package/{src/models/monitor-cpu.model.ts → models/monitor-cpu.model.d.ts} +7 -9
  305. package/models/monitor-cpu.model.js +4 -0
  306. package/models/monitor-cpu.model.js.map +1 -0
  307. package/models/monitor-function.model.d.ts +14 -0
  308. package/models/monitor-function.model.js +4 -0
  309. package/models/monitor-function.model.js.map +1 -0
  310. package/models/monitor-memory.model.d.ts +15 -0
  311. package/models/monitor-memory.model.js +4 -0
  312. package/models/monitor-memory.model.js.map +1 -0
  313. package/models/monitor-mongo.model.d.ts +13 -0
  314. package/models/monitor-mongo.model.js +4 -0
  315. package/models/monitor-mongo.model.js.map +1 -0
  316. package/{src/models/notification.model.ts → models/notification.model.d.ts} +4 -6
  317. package/models/notification.model.js +4 -0
  318. package/models/notification.model.js.map +1 -0
  319. package/models/openai-usage-ledger.model.d.ts +15 -0
  320. package/models/openai-usage-ledger.model.js +4 -0
  321. package/models/openai-usage-ledger.model.js.map +1 -0
  322. package/models/pagination.model.d.ts +11 -0
  323. package/models/pagination.model.js +28 -0
  324. package/models/pagination.model.js.map +1 -0
  325. package/models/permission.model.d.ts +12 -0
  326. package/models/permission.model.js +4 -0
  327. package/models/permission.model.js.map +1 -0
  328. package/models/report-builder-dashboard-builder.model.d.ts +25 -0
  329. package/models/report-builder-dashboard-builder.model.js +4 -0
  330. package/models/report-builder-dashboard-builder.model.js.map +1 -0
  331. package/models/report-builder-library.model.d.ts +17 -0
  332. package/models/report-builder-library.model.js +4 -0
  333. package/models/report-builder-library.model.js.map +1 -0
  334. package/models/report-builder-report.model.d.ts +120 -0
  335. package/models/report-builder-report.model.js +4 -0
  336. package/models/report-builder-report.model.js.map +1 -0
  337. package/models/report-builder.model.d.ts +61 -0
  338. package/models/report-builder.model.js +4 -0
  339. package/models/report-builder.model.js.map +1 -0
  340. package/models/select-data-label.model.d.ts +9 -0
  341. package/models/select-data-label.model.js +4 -0
  342. package/models/select-data-label.model.js.map +1 -0
  343. package/models/server-message.model.d.ts +32 -0
  344. package/models/server-message.model.js +4 -0
  345. package/models/server-message.model.js.map +1 -0
  346. package/models/slow-query-report.model.d.ts +23 -0
  347. package/models/slow-query-report.model.js +4 -0
  348. package/models/slow-query-report.model.js.map +1 -0
  349. package/models/subscription.model.d.ts +31 -0
  350. package/models/subscription.model.js +4 -0
  351. package/models/subscription.model.js.map +1 -0
  352. package/models/support-ticket.model.d.ts +87 -0
  353. package/models/support-ticket.model.js +4 -0
  354. package/models/support-ticket.model.js.map +1 -0
  355. package/models/user-group.model.d.ts +20 -0
  356. package/models/user-group.model.js +4 -0
  357. package/models/user-group.model.js.map +1 -0
  358. package/{src/models/user-guide.model.ts → models/user-guide.model.d.ts} +4 -5
  359. package/models/user-guide.model.js +4 -0
  360. package/models/user-guide.model.js.map +1 -0
  361. package/models/user.model.d.ts +84 -0
  362. package/models/user.model.js +4 -0
  363. package/models/user.model.js.map +1 -0
  364. package/package.json +1 -1
  365. package/private/images/ResolveIO.png +0 -0
  366. package/public_api.js +107 -0
  367. package/public_api.js.map +1 -0
  368. package/publications/ai-terminal.d.ts +1 -0
  369. package/publications/ai-terminal.js +122 -0
  370. package/publications/ai-terminal.js.map +1 -0
  371. package/publications/app-settings.d.ts +2 -0
  372. package/publications/app-settings.js +28 -0
  373. package/publications/app-settings.js.map +1 -0
  374. package/publications/app-status.d.ts +2 -0
  375. package/publications/app-status.js +16 -0
  376. package/publications/app-status.js.map +1 -0
  377. package/publications/cron-jobs.d.ts +2 -0
  378. package/publications/cron-jobs.js +32 -0
  379. package/publications/cron-jobs.js.map +1 -0
  380. package/publications/customer-notifications.d.ts +2 -0
  381. package/publications/customer-notifications.js +161 -0
  382. package/publications/customer-notifications.js.map +1 -0
  383. package/publications/files.d.ts +2 -0
  384. package/publications/files.js +36 -0
  385. package/publications/files.js.map +1 -0
  386. package/publications/flags-update.d.ts +2 -0
  387. package/publications/flags-update.js +22 -0
  388. package/publications/flags-update.js.map +1 -0
  389. package/publications/flags.d.ts +2 -0
  390. package/publications/flags.js +22 -0
  391. package/publications/flags.js.map +1 -0
  392. package/publications/logs.d.ts +2 -0
  393. package/publications/logs.js +164 -0
  394. package/publications/logs.js.map +1 -0
  395. package/publications/notifications.d.ts +2 -0
  396. package/publications/notifications.js +16 -0
  397. package/publications/notifications.js.map +1 -0
  398. package/publications/report-builder-dashboard-builders.d.ts +2 -0
  399. package/publications/report-builder-dashboard-builders.js +42 -0
  400. package/publications/report-builder-dashboard-builders.js.map +1 -0
  401. package/publications/report-builder-libraries.d.ts +2 -0
  402. package/publications/report-builder-libraries.js +90 -0
  403. package/publications/report-builder-libraries.js.map +1 -0
  404. package/publications/report-builder-reports.d.ts +2 -0
  405. package/publications/report-builder-reports.js +50 -0
  406. package/publications/report-builder-reports.js.map +1 -0
  407. package/publications/super-admin.d.ts +2 -0
  408. package/publications/super-admin.js +16 -0
  409. package/publications/super-admin.js.map +1 -0
  410. package/publications/user-groups.d.ts +1 -0
  411. package/publications/user-groups.js +16 -0
  412. package/publications/user-groups.js.map +1 -0
  413. package/publications/user-guides.d.ts +1 -0
  414. package/publications/user-guides.js +16 -0
  415. package/publications/user-guides.js.map +1 -0
  416. package/resolveio-server-app.d.ts +70 -0
  417. package/resolveio-server-app.js +801 -0
  418. package/resolveio-server-app.js.map +1 -0
  419. package/server-app.d.ts +167 -0
  420. package/server-app.js +2784 -0
  421. package/server-app.js.map +1 -0
  422. package/services/codex-client.d.ts +119 -0
  423. package/services/codex-client.js +1470 -0
  424. package/services/codex-client.js.map +1 -0
  425. package/services/openai-client.d.ts +46 -0
  426. package/services/openai-client.js +318 -0
  427. package/services/openai-client.js.map +1 -0
  428. package/types/error-report.d.ts +25 -0
  429. package/types/error-report.js +4 -0
  430. package/types/error-report.js.map +1 -0
  431. package/types/slow-query-report.d.ts +27 -0
  432. package/types/slow-query-report.js +6 -0
  433. package/types/slow-query-report.js.map +1 -0
  434. package/util/common.d.ts +31 -0
  435. package/util/common.js +683 -0
  436. package/util/common.js.map +1 -0
  437. package/util/customer-portal-password.d.ts +13 -0
  438. package/util/customer-portal-password.js +209 -0
  439. package/util/customer-portal-password.js.map +1 -0
  440. package/util/error-reporter.d.ts +52 -0
  441. package/util/error-reporter.js +326 -0
  442. package/util/error-reporter.js.map +1 -0
  443. package/util/error-tracking.d.ts +13 -0
  444. package/util/error-tracking.js +120 -0
  445. package/util/error-tracking.js.map +1 -0
  446. package/util/report-builder-unwinds.d.ts +15 -0
  447. package/util/report-builder-unwinds.js +156 -0
  448. package/util/report-builder-unwinds.js.map +1 -0
  449. package/util/schema-report-builder.d.ts +6 -0
  450. package/util/schema-report-builder.js +481 -0
  451. package/util/schema-report-builder.js.map +1 -0
  452. package/util/slow-query-reporter.d.ts +28 -0
  453. package/util/slow-query-reporter.js +226 -0
  454. package/util/slow-query-reporter.js.map +1 -0
  455. package/util/subscription-dependency-context.d.ts +34 -0
  456. package/util/subscription-dependency-context.js +1283 -0
  457. package/util/subscription-dependency-context.js.map +1 -0
  458. package/util/tokenizer.d.ts +5 -0
  459. package/util/tokenizer.js +41 -0
  460. package/util/tokenizer.js.map +1 -0
  461. package/workers/codex-runner.worker.d.ts +1 -0
  462. package/workers/codex-runner.worker.js +192 -0
  463. package/workers/codex-runner.worker.js.map +1 -0
  464. package/.github/workflows/ai-assistant-nightly-eval.yml +0 -224
  465. package/.github/workflows/ai-assistant-pr-guardrails.yml +0 -60
  466. package/.nodemon.json +0 -5
  467. package/.vscode/settings.json +0 -21
  468. package/AGENTS.md +0 -179
  469. package/README.md +0 -22
  470. package/build_package.sh +0 -5
  471. package/compileDTS.pl +0 -64
  472. package/docs/ai-assistant-nightly-eval.md +0 -65
  473. package/docs/ai-assistant-preflight-checklist.md +0 -23
  474. package/docs/ai-assistant-report-builder-bridge-playbook.md +0 -115
  475. package/eslint-plugin-custom/index.js +0 -7
  476. package/eslint-plugin-custom/rules/no-filter-zero-index.js +0 -44
  477. package/eslint.config.js +0 -103
  478. package/gulpfile.js +0 -216
  479. package/methodAndPublicationListGenerator.py +0 -319
  480. package/mongodbensurers.js +0 -2
  481. package/mongostop.js +0 -3
  482. package/settings.development.json +0 -25
  483. package/settings.development.redacted.json +0 -25
  484. package/src/.env +0 -12
  485. package/src/ai/assistant-core-heuristics.ts +0 -577
  486. package/src/client-server-app.ts +0 -12
  487. package/src/collections/ai-terminal-conversation.collection.ts +0 -91
  488. package/src/collections/ai-terminal-issue-report.collection.ts +0 -99
  489. package/src/collections/ai-terminal-message.collection.ts +0 -77
  490. package/src/collections/app-setting.collection.ts +0 -104
  491. package/src/collections/app-status.collection.ts +0 -58
  492. package/src/collections/communication-metric.collection.ts +0 -84
  493. package/src/collections/counter.collection.ts +0 -56
  494. package/src/collections/cron-job-history.collection.ts +0 -94
  495. package/src/collections/cron-job.collection.ts +0 -92
  496. package/src/collections/customer-notification.collection.ts +0 -131
  497. package/src/collections/customer-portal-password.collection.ts +0 -76
  498. package/src/collections/email-history.collection.ts +0 -121
  499. package/src/collections/email-verified.collection.ts +0 -61
  500. package/src/collections/file.collection.ts +0 -74
  501. package/src/collections/flag-update.collection.ts +0 -57
  502. package/src/collections/flag.collection.ts +0 -57
  503. package/src/collections/log-method-latency.collection.ts +0 -77
  504. package/src/collections/log-subscription.collection.ts +0 -80
  505. package/src/collections/log.collection.ts +0 -93
  506. package/src/collections/logged-in-users.collection.ts +0 -67
  507. package/src/collections/monitor-cpu.collection.ts +0 -65
  508. package/src/collections/monitor-function.collection.ts +0 -74
  509. package/src/collections/monitor-memory.collection.ts +0 -77
  510. package/src/collections/monitor-mongo.collection.ts +0 -71
  511. package/src/collections/notification.collection.ts +0 -57
  512. package/src/collections/openai-usage-ledger.collection.ts +0 -77
  513. package/src/collections/report-builder-dashboard-builder.collection.ts +0 -109
  514. package/src/collections/report-builder-library.collection.ts +0 -89
  515. package/src/collections/report-builder-report.collection.ts +0 -180
  516. package/src/collections/user-group.collection.ts +0 -89
  517. package/src/collections/user-guide.collection.ts +0 -57
  518. package/src/collections/user.collection.ts +0 -181
  519. package/src/cron/cron.ts +0 -117
  520. package/src/fixtures/cron-jobs.ts +0 -95
  521. package/src/fixtures/init.ts +0 -35
  522. package/src/http/auth.ts +0 -764
  523. package/src/http/health.ts +0 -7
  524. package/src/http/home.ts +0 -90
  525. package/src/http/slow-query-publication.ts +0 -49
  526. package/src/index.ts +0 -1
  527. package/src/managers/communication-metric.manager.ts +0 -82
  528. package/src/managers/cron.manager.ts +0 -333
  529. package/src/managers/customer-notification-content.manager.ts +0 -236
  530. package/src/managers/diagnostic-manager-bootstrap.ts +0 -165
  531. package/src/managers/error-auto-fix.manager.ts +0 -2767
  532. package/src/managers/local-log.manager.ts +0 -113
  533. package/src/managers/method.manager.ts +0 -1557
  534. package/src/managers/mongo.manager.ts +0 -4566
  535. package/src/managers/monitor.manager.ts +0 -489
  536. package/src/managers/openai-usage-ledger.manager.ts +0 -116
  537. package/src/managers/slow-query-verifier.manager.ts +0 -3590
  538. package/src/managers/slow-query.manager.ts +0 -519
  539. package/src/managers/subscription.manager.ts +0 -3120
  540. package/src/managers/websocket.manager.ts +0 -746
  541. package/src/managers/worker-dispatcher.manager.ts +0 -1318
  542. package/src/managers/worker-server.manager.ts +0 -468
  543. package/src/methods/accounts.ts +0 -532
  544. package/src/methods/ai-terminal.ts +0 -25505
  545. package/src/methods/app-settings.ts +0 -114
  546. package/src/methods/aws.ts +0 -646
  547. package/src/methods/collections.ts +0 -544
  548. package/src/methods/counters.ts +0 -67
  549. package/src/methods/cron-jobs.ts +0 -2610
  550. package/src/methods/customer-notifications.ts +0 -458
  551. package/src/methods/diagnostics.ts +0 -447
  552. package/src/methods/flag-updates.ts +0 -7
  553. package/src/methods/flags.ts +0 -7
  554. package/src/methods/logs.ts +0 -656
  555. package/src/methods/mongo-explorer.ts +0 -1883
  556. package/src/methods/monitor.ts +0 -540
  557. package/src/methods/pdf.ts +0 -1210
  558. package/src/methods/publications.ts +0 -128
  559. package/src/methods/report-builder.ts +0 -3305
  560. package/src/methods/support.ts +0 -210
  561. package/src/models/ai-terminal-conversation.model.ts +0 -19
  562. package/src/models/ai-terminal-issue-report.model.ts +0 -21
  563. package/src/models/ai-terminal-message.model.ts +0 -24
  564. package/src/models/app-setting.model.ts +0 -17
  565. package/src/models/collection-document.model.ts +0 -24
  566. package/src/models/communication-metric.model.ts +0 -23
  567. package/src/models/cron-job-history.model.ts +0 -16
  568. package/src/models/cron-job.model.ts +0 -15
  569. package/src/models/customer-notification.model.ts +0 -28
  570. package/src/models/customer-portal-password.model.ts +0 -12
  571. package/src/models/dialog.model.ts +0 -25
  572. package/src/models/log-method-latency.model.ts +0 -11
  573. package/src/models/log.model.ts +0 -19
  574. package/src/models/method.model.ts +0 -23
  575. package/src/models/monitor-function.model.ts +0 -16
  576. package/src/models/monitor-memory.model.ts +0 -17
  577. package/src/models/monitor-mongo.model.ts +0 -15
  578. package/src/models/openai-usage-ledger.model.ts +0 -16
  579. package/src/models/pagination.model.ts +0 -35
  580. package/src/models/permission.model.ts +0 -14
  581. package/src/models/report-builder-dashboard-builder.model.ts +0 -29
  582. package/src/models/report-builder-library.model.ts +0 -20
  583. package/src/models/report-builder-report.model.ts +0 -135
  584. package/src/models/report-builder.model.ts +0 -68
  585. package/src/models/select-data-label.model.ts +0 -9
  586. package/src/models/server-message.model.ts +0 -31
  587. package/src/models/slow-query-report.model.ts +0 -23
  588. package/src/models/subscription.model.ts +0 -73
  589. package/src/models/support-ticket.model.ts +0 -96
  590. package/src/models/user-group.model.ts +0 -24
  591. package/src/models/user.model.ts +0 -96
  592. package/src/private/images/ResolveIO.png +0 -0
  593. package/src/publications/ai-terminal.ts +0 -73
  594. package/src/publications/app-settings.ts +0 -25
  595. package/src/publications/app-status.ts +0 -13
  596. package/src/publications/cron-jobs.ts +0 -29
  597. package/src/publications/customer-notifications.ts +0 -101
  598. package/src/publications/files.ts +0 -33
  599. package/src/publications/flags-update.ts +0 -19
  600. package/src/publications/flags.ts +0 -19
  601. package/src/publications/logs.ts +0 -163
  602. package/src/publications/notifications.ts +0 -13
  603. package/src/publications/report-builder-dashboard-builders.ts +0 -39
  604. package/src/publications/report-builder-libraries.ts +0 -41
  605. package/src/publications/report-builder-reports.ts +0 -47
  606. package/src/publications/super-admin.ts +0 -13
  607. package/src/publications/user-groups.ts +0 -12
  608. package/src/publications/user-guides.ts +0 -12
  609. package/src/resolveio-server-app.ts +0 -617
  610. package/src/server-app.ts +0 -2616
  611. package/src/services/codex-client.ts +0 -1117
  612. package/src/services/openai-client.ts +0 -265
  613. package/src/types/error-report.ts +0 -26
  614. package/src/types/js-tiktoken.d.ts +0 -11
  615. package/src/types/slow-query-report.ts +0 -28
  616. package/src/util/common.ts +0 -649
  617. package/src/util/customer-portal-password.ts +0 -183
  618. package/src/util/error-reporter.ts +0 -332
  619. package/src/util/error-tracking.ts +0 -79
  620. package/src/util/report-builder-unwinds.ts +0 -180
  621. package/src/util/schema-report-builder.ts +0 -448
  622. package/src/util/slow-query-reporter.ts +0 -216
  623. package/src/util/subscription-dependency-context.ts +0 -1096
  624. package/src/util/tokenizer.ts +0 -38
  625. package/src/workers/codex-runner.worker.ts +0 -142
  626. package/start_server.sh +0 -5
  627. package/tests/ai-assistant-corpus-build.ts +0 -484
  628. package/tests/ai-assistant-corpus-replay-e2e.ts +0 -773
  629. package/tests/ai-assistant-data-parity-e2e.ts +0 -2018
  630. package/tests/ai-assistant-eval-triage.ts +0 -831
  631. package/tests/ai-assistant-openai-e2e.ts +0 -1061
  632. package/tests/ai-assistant-openai-git-e2e.ts +0 -155
  633. package/tests/ai-assistant-preflight-matrix.ts +0 -215
  634. package/tests/ai-assistant-routing-eval.test.ts +0 -560
  635. package/tests/ai-assistant-snf-live-eval.ts +0 -921
  636. package/tests/ai-assistant-utils.test.ts +0 -2165
  637. package/tests/error-reporter.test.ts +0 -145
  638. package/tests/report-builder-linking.test.ts +0 -79
  639. package/tests/subscription-connect-race.test.ts +0 -157
  640. package/tests/subscription-dependency-context.test.ts +0 -324
  641. package/tests/subscription-manager-collection-tracking.test.ts +0 -86
  642. package/tests/subscription-manager-invalidation.test.ts +0 -85
  643. package/tsconfig.json +0 -34
  644. /package/{src/private → private}/email-templates/enrollment.html +0 -0
  645. /package/{src/private → private}/email-templates/forgot-password.html +0 -0
  646. /package/{src/private → private}/email-templates/support-ticket-deleted.html +0 -0
  647. /package/{src/private → private}/email-templates/support-ticket-modified.html +0 -0
  648. /package/{src/private → private}/email-templates/support-ticket.html +0 -0
  649. /package/{src/public_api.ts → public_api.d.ts} +0 -0
@@ -1,1557 +0,0 @@
1
- import { S3 } from '@aws-sdk/client-s3';
2
- import { SESv2Client, SendEmailCommand } from '@aws-sdk/client-sesv2';
3
- import { EventEmitter, once } from 'events';
4
- import * as fs from 'fs';
5
- import * as nodemailer from 'nodemailer';
6
- import * as path from 'path';
7
- import { setTimeout as delay } from 'timers/promises';
8
- import { EmailHistories } from '../collections/email-history.collection';
9
- import { Flags } from '../collections/flag.collection';
10
- import { Logs } from '../collections/log.collection';
11
- import { loadServerCronJobs } from '../fixtures/cron-jobs';
12
- import { loadServerInit } from '../fixtures/init';
13
- import { loadAccountMethods } from '../methods/accounts';
14
- import { loadAppSettingsMethods } from '../methods/app-settings';
15
- import { loadAWSMethods } from '../methods/aws';
16
- import { loadAiTerminalMethods } from '../methods/ai-terminal';
17
- import { loadCollectionMethods } from '../methods/collections';
18
- import { loadCustomerNotificationMethods } from '../methods/customer-notifications';
19
- import { loadCounterMethods } from '../methods/counters';
20
- import { loadCronJobMethods } from '../methods/cron-jobs';
21
- import { loadDiagnosticMethods } from '../methods/diagnostics';
22
- import { loadFlagUpdatesMethods } from '../methods/flag-updates';
23
- import { loadFlagMethods } from '../methods/flags';
24
- import { loadLogMethods } from '../methods/logs';
25
- import { loadMonitorMethods } from '../methods/monitor';
26
- import { loadMongoExplorerMethods } from '../methods/mongo-explorer';
27
- import { loadPublicationMethods } from '../methods/publications';
28
- import { loadPDFMethods } from '../methods/pdf';
29
- import { loadReportBuilderMethods } from '../methods/report-builder';
30
- import { loadSupportMethods } from '../methods/support';
31
- import { EmailHistoryModel, EmailHistoryOccurrence } from '../models/email-history.model';
32
- import { MethodAllModel, MethodModel } from '../models/method.model';
33
- import { ResolveIOServer } from '../resolveio-server-app';
34
- import { getBinarySize, objectIdHexString } from '../util/common';
35
- import { ErrorReporter } from '../util/error-reporter';
36
- import { ensureErrorWithCorrelation, getCorrelationId, runWithCorrelationContext } from '../util/error-tracking';
37
- import { MonitorManagerFunction } from './monitor.manager';
38
- import { WebSocketManager } from './websocket.manager';
39
- import { recordEmailMetric, recordTextMessageMetric } from './communication-metric.manager';
40
-
41
- interface SendEmailOptions {
42
- correlationId?: string;
43
- meta?: Record<string, any>;
44
- }
45
-
46
- function appendCorrelationIdToSubject(subject: string, correlationId?: string): string {
47
- if (!correlationId) {
48
- return subject;
49
- }
50
-
51
- const correlationTag = `[${correlationId}]`;
52
-
53
- if (subject && subject.includes(correlationTag)) {
54
- return subject;
55
- }
56
-
57
- return `${subject} ${correlationTag}`.trim();
58
- }
59
-
60
- function createEmailOccurrence(subject: string, text?: string, html?: string, meta?: Record<string, any>): EmailHistoryOccurrence {
61
- return {
62
- _id: objectIdHexString(),
63
- createdAt: new Date(),
64
- subject,
65
- text,
66
- html,
67
- meta
68
- };
69
- }
70
-
71
- function formatGroupedEmailContent(correlationId: string, occurrences: EmailHistoryOccurrence[]): { text: string; html: string } {
72
- const lines: string[] = [];
73
- lines.push(`Correlation ID: ${correlationId}`);
74
-
75
- occurrences.forEach((occurrence, index) => {
76
- const timestamp = occurrence.createdAt instanceof Date ? occurrence.createdAt.toISOString() : new Date(occurrence.createdAt).toISOString();
77
- lines.push('');
78
- lines.push(`Occurrence #${index + 1} (${timestamp})`);
79
- lines.push(`Subject: ${occurrence.subject}`);
80
- if (occurrence.text) {
81
- lines.push(occurrence.text);
82
- }
83
- });
84
-
85
- const htmlSections = occurrences.map((occurrence, index) => {
86
- const timestamp = occurrence.createdAt instanceof Date ? occurrence.createdAt.toISOString() : new Date(occurrence.createdAt).toISOString();
87
- const escapedText = occurrence.text ? occurrence.text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;') : '';
88
- return `<div><h4>Occurrence #${index + 1} (${timestamp})</h4><p><strong>Subject:</strong> ${occurrence.subject}</p>${escapedText ? `<pre>${escapedText}</pre>` : ''}</div>`;
89
- });
90
-
91
- const html = [
92
- `<p><strong>Correlation ID:</strong> ${correlationId}</p>`,
93
- ...htmlSections
94
- ].join('');
95
-
96
- return {
97
- text: lines.join('\n'),
98
- html
99
- };
100
- }
101
-
102
- function createNodeMailerSESV2Transport(sesClient: SESv2Client): nodemailer.Transporter {
103
- const transport: any = {
104
- name: 'resolveio-sesv2-transport',
105
- version: '1.0.0',
106
- send: (mail: any, callback: any) => {
107
- const stream = mail.message.createReadStream();
108
- const chunks: Uint8Array[] = [];
109
- let didFinish = false;
110
-
111
- const finish = (error: any, info?: any) => {
112
- if (didFinish) {
113
- return;
114
- }
115
-
116
- didFinish = true;
117
- callback(error, info);
118
- };
119
-
120
- stream.on('data', (chunk) => {
121
- const chunkData = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
122
- chunks.push(new Uint8Array(chunkData));
123
- });
124
-
125
- stream.on('error', (error) => {
126
- finish(error);
127
- });
128
-
129
- stream.on('end', async () => {
130
- try {
131
- const rawData = Buffer.concat(chunks);
132
- const rawMessageData = new Uint8Array(rawData);
133
- const envelope = typeof mail.message.getEnvelope === 'function' ? mail.message.getEnvelope() : mail.data?.envelope;
134
-
135
- const fromEmailAddress = envelope?.from || undefined;
136
- const toAddresses = envelope?.to
137
- ? (Array.isArray(envelope.to) ? envelope.to : [envelope.to]).filter(Boolean)
138
- : [];
139
-
140
- const replyToAddresses = mail.data?.replyTo
141
- ? (Array.isArray(mail.data.replyTo) ? mail.data.replyTo : [mail.data.replyTo]).filter(Boolean)
142
- : undefined;
143
-
144
- const response = await sesClient.send(new SendEmailCommand({
145
- FromEmailAddress: fromEmailAddress,
146
- Destination: toAddresses.length ? { ToAddresses: toAddresses } : undefined,
147
- ReplyToAddresses: replyToAddresses,
148
- Content: {
149
- Raw: {
150
- Data: rawMessageData
151
- }
152
- }
153
- }));
154
-
155
- finish(null, {
156
- envelope,
157
- messageId: response.MessageId,
158
- response: response.MessageId
159
- });
160
- }
161
- catch (error) {
162
- finish(error);
163
- }
164
- });
165
- }
166
- };
167
-
168
- return nodemailer.createTransport(transport);
169
- }
170
-
171
- export class AWS {
172
- private _s3: S3 = null;
173
- private _s3USEast1: S3 = null;
174
-
175
- constructor() {}
176
-
177
- public create() {
178
- const aws = new AWS();
179
- aws.initialize();
180
- return aws;
181
- }
182
-
183
- private initialize() {
184
-
185
- }
186
-
187
- public s3(): S3 {
188
- if (this._s3) {
189
- return this._s3;
190
- }
191
-
192
- this._s3 = new S3({
193
- credentials: {
194
- accessKeyId: process.env.AWS_ACCESS_KEY,
195
- secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
196
- },
197
- region: process.env.AWS_REGION,
198
- apiVersion: '2006-03-01'
199
- });
200
-
201
- return this._s3;
202
- }
203
-
204
- public s3USEast1(): S3 {
205
- if (process.env.AWS_REGION === 'us-east-1') {
206
- return this.s3();
207
- }
208
- else {
209
- if (this._s3USEast1) {
210
- return this._s3USEast1;
211
- }
212
-
213
- this._s3USEast1 = new S3({
214
- credentials: {
215
- accessKeyId: process.env.AWS_ACCESS_KEY,
216
- secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
217
- },
218
- region: 'us-east-1',
219
- apiVersion: '2006-03-01'
220
- });
221
-
222
- return this._s3USEast1;
223
- }
224
- }
225
- }
226
-
227
- export class MethodManager {
228
- private _websocketManager: WebSocketManager;
229
- public _methods: MethodModel = {};
230
- private _mailerSES: nodemailer.Transporter;
231
- private _mailerCustom: nodemailer.Transporter;
232
- private _aws: AWS;
233
- private _monitorManagerFunction: MonitorManagerFunction;
234
- private _isWorkersEnabled = false;
235
- private _isWorkerInstance = false;
236
-
237
- private emailQueue: Set<string> = new Set(); // Set to store pending email IDs
238
- private isEmailProcessing = false;
239
- private readonly _emailProcessingDelayMs = 5000;
240
-
241
- private _debugcallMethodHits = 0;
242
- private _debugCallMethodHits = 0;
243
- private _debugCallMethodCronJobHits = 0;
244
- private _debugSendQueueHits = 0;
245
- private _enableDebug = false;
246
- private _ready = false;
247
- private _readyEmitter = new EventEmitter();
248
- private _readyError: any = null;
249
-
250
- private _localActiveCounts: Map<string, number> = new Map();
251
- private _localWaitQueues: Map<string, Array<() => void>> = new Map();
252
-
253
- public clientDir = '';
254
- public serverConfig: Record<string, any> = {};
255
-
256
- constructor() {}
257
-
258
- static create(websocketManager: WebSocketManager, monitorManagerFunction: MonitorManagerFunction, isWorkersEnabled, isWorkerInstance) {
259
- const methodManager = new MethodManager();
260
- methodManager.initialize(websocketManager, monitorManagerFunction, isWorkersEnabled, isWorkerInstance);
261
- return methodManager;
262
- }
263
-
264
- private initialize(websocketManager: WebSocketManager, monitorManagerFunction: MonitorManagerFunction, isWorkersEnabled, isWorkerInstance) {
265
- this._websocketManager = websocketManager;
266
- this._monitorManagerFunction = monitorManagerFunction;
267
- this._isWorkersEnabled = isWorkersEnabled;
268
- this._isWorkerInstance = isWorkerInstance;
269
-
270
- this.clientDir = ResolveIOServer.getClientDir();
271
- this.serverConfig = ResolveIOServer.getServerConfig();
272
-
273
- // Fixtures
274
- if (!process.env.IS_WORKERS_ENABLED || process.env.IS_WORKERS_ENABLED === 'false' || (process.env.IS_WORKER_INSTANCE === 'true' && process.env.WORKER_INDEX === '0')) {
275
- if (process.env.IS_WORKERS_ENABLED === 'false' || process.env.NODE_APP_INSTANCE === '1') {
276
- setTimeout(async () => {
277
- console.log(new Date(), 'Start Server Fixture');
278
- await loadServerInit();
279
- console.log(new Date(), 'End Server Fixture');
280
- }, 5000);
281
- }
282
- }
283
-
284
- setImmediate(async () => {
285
- try {
286
- // Methods
287
- await loadServerCronJobs();
288
-
289
- loadAccountMethods(this);
290
- loadAppSettingsMethods(this);
291
- loadAWSMethods(this);
292
- loadAiTerminalMethods(this);
293
- loadCollectionMethods(this);
294
- loadCustomerNotificationMethods(this);
295
- loadCounterMethods(this);
296
- loadLogMethods(this);
297
- loadPDFMethods(this);
298
- loadCronJobMethods(this);
299
- loadFlagMethods(this);
300
- loadFlagUpdatesMethods(this);
301
- loadReportBuilderMethods(this);
302
- loadSupportMethods(this);
303
- loadMonitorMethods(this);
304
- loadMongoExplorerMethods(this);
305
- loadPublicationMethods(this);
306
- loadDiagnosticMethods(this);
307
-
308
- let flag = await Flags.findOne({type: 'Enable Debug'});
309
-
310
- if (flag && flag.value) {
311
- this._enableDebug = true;
312
- }
313
- else {
314
- this._enableDebug = false;
315
- }
316
-
317
- await this.loadPendingEmails();
318
- this.markReady();
319
- }
320
- catch (error) {
321
- console.error(new Date(), 'Method Manager init failed', error);
322
- this.markReadyFailure(error);
323
- }
324
- });
325
-
326
- this._aws = new AWS();
327
-
328
- const sesRegion = process.env.AWS_SES_REGION || process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || 'us-east-1';
329
- const sesCredentials = process.env.AWS_ACCESS_KEY && process.env.AWS_SECRET_ACCESS_KEY ? {
330
- accessKeyId: process.env.AWS_ACCESS_KEY,
331
- secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
332
- sessionToken: process.env.AWS_SESSION_TOKEN
333
- } : undefined;
334
-
335
- this._mailerSES = createNodeMailerSESV2Transport(new SESv2Client({
336
- region: sesRegion,
337
- credentials: sesCredentials
338
- }));
339
-
340
- if (!ResolveIOServer.getSESMail()) {
341
- this._mailerCustom = nodemailer.createTransport({
342
- host: ResolveIOServer.getServerConfig()['MAIL_HOST'], // 'smtp.office365.com', // Office 365 server
343
- port: ResolveIOServer.getServerConfig()['MAIL_PORT'], //587, // secure SMTP
344
- secure: false, // false for TLS - as a boolean not string - but the default is false so just remove this completely
345
- auth: {
346
- user: ResolveIOServer.getServerConfig()['MAIL_USERNAME'],
347
- pass: ResolveIOServer.getServerConfig()['MAIL_PASSWORD']
348
- },
349
- tls: {
350
- ciphers: 'SSLv3'
351
- }
352
- });
353
- }
354
-
355
- setInterval(async () => {
356
- let flag = await Flags.findOne({type: 'Enable Debug'});
357
-
358
- if (flag && flag.value) {
359
- this._enableDebug = true;
360
- }
361
- else {
362
- this._enableDebug = false;
363
- }
364
-
365
- if (this._enableDebug) {
366
- console.log(new Date(), 'Method Manager', 'Send Queue Hits', this._debugSendQueueHits);
367
- console.log(new Date(), 'Method Manager', 'Call Method Internal Hits', this._debugcallMethodHits);
368
- console.log(new Date(), 'Method Manager', 'Call Method Hits', this._debugCallMethodHits);
369
- console.log(new Date(), 'Method Manager', 'Call Method Cron Hits', this._debugCallMethodCronJobHits);
370
- }
371
-
372
- this._debugcallMethodHits = 0;
373
- this._debugCallMethodHits = 0;
374
- this._debugCallMethodCronJobHits = 0;
375
- this._debugSendQueueHits = 0;
376
- }, 60000);
377
-
378
- if (!this._isWorkersEnabled || this._isWorkerInstance) {
379
- this.setupEmailWatcher();
380
- }
381
- }
382
-
383
- private markReady(): void {
384
- if (this._ready) {
385
- return;
386
- }
387
- this._ready = true;
388
- this._readyEmitter.emit('ready');
389
- this._readyEmitter.removeAllListeners('ready');
390
- this._readyEmitter.removeAllListeners('readyError');
391
- }
392
-
393
- private markReadyFailure(error: any): void {
394
- if (this._ready) {
395
- return;
396
- }
397
- this._readyError = error;
398
- this._readyEmitter.emit('readyError', error);
399
- this._readyEmitter.removeAllListeners('ready');
400
- this._readyEmitter.removeAllListeners('readyError');
401
- }
402
-
403
- public onReady(callback: () => void): () => void {
404
- if (this._ready) {
405
- callback();
406
- return () => {};
407
- }
408
- if (this._readyError) {
409
- return () => {};
410
- }
411
-
412
- const handleReady = () => {
413
- callback();
414
- };
415
-
416
- this._readyEmitter.once('ready', handleReady);
417
-
418
- return () => {
419
- this._readyEmitter.removeListener('ready', handleReady);
420
- };
421
- }
422
-
423
- private async waitForReadyEvent(): Promise<void> {
424
- await once(this._readyEmitter, 'ready');
425
- }
426
-
427
- private async waitForReadyError(): Promise<void> {
428
- const [error] = await once(this._readyEmitter, 'readyError');
429
- throw error || new Error('MethodManager failed to initialize');
430
- }
431
-
432
- private async waitForReadyTimeout(timeoutMs: number): Promise<void> {
433
- await delay(timeoutMs);
434
- throw new Error('MethodManager ready timeout');
435
- }
436
-
437
- public isReady(): boolean {
438
- return this._ready;
439
- }
440
-
441
- public getReadyError(): any {
442
- return this._readyError;
443
- }
444
-
445
- public async waitUntilReady(timeoutMs: number = 30000): Promise<void> {
446
- if (this._ready) {
447
- return;
448
- }
449
- if (this._readyError) {
450
- throw this._readyError;
451
- }
452
- if (!timeoutMs || timeoutMs <= 0) {
453
- await Promise.race([
454
- this.waitForReadyEvent(),
455
- this.waitForReadyError()
456
- ]);
457
- return;
458
- }
459
- await Promise.race([
460
- this.waitForReadyEvent(),
461
- this.waitForReadyError(),
462
- this.waitForReadyTimeout(timeoutMs)
463
- ]);
464
- }
465
-
466
- public getMethod(methodName: string): MethodAllModel {
467
- return this._methods[methodName];
468
- }
469
-
470
- // Add methods to private methods object
471
- public methods(method: MethodModel) {
472
- this._methods = Object.assign(this._methods, method);
473
- }
474
-
475
- private async reportMethodError(
476
- subject: string,
477
- correlationId: string,
478
- context: Record<string, any> | string,
479
- meta: Record<string, any>,
480
- stack?: string
481
- ) {
482
- const metadata = Object.assign({}, meta || {});
483
- if (correlationId && !metadata.correlationId) {
484
- metadata.correlationId = correlationId;
485
- }
486
-
487
- await ErrorReporter.report({
488
- sourceApp: 'method-manager',
489
- message: subject,
490
- environment: this.serverConfig?.ROOT_URL,
491
- clientSlug: ResolveIOServer.getClientName(),
492
- clientName: this.serverConfig?.CLIENT_NAME,
493
- severity: 'error',
494
- stack,
495
- context,
496
- metadata,
497
- correlationId
498
- });
499
- }
500
-
501
- public async callMethodCron(method: string, ...methodData: any[]) {
502
- this._debugCallMethodCronJobHits += 1;
503
-
504
- const existingCorrelationId = getCorrelationId();
505
- const correlationId = existingCorrelationId || objectIdHexString();
506
-
507
- const execute = async () => {
508
- const cronMethod = this._methods[method];
509
-
510
- if (!cronMethod) {
511
- console.log('No Method: ' + method);
512
-
513
- await this.reportMethodError(
514
- 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'],
515
- correlationId,
516
- { message: 'No Method registered for cron execution', method },
517
- { context: 'callMethodCron', method }
518
- );
519
-
520
- throw new Error('No Method: ' + method);
521
- }
522
-
523
- if ((methodData.length > 1 || methodData[0]) && !cronMethod.skipValidation) {
524
- if (!cronMethod.check) {
525
- console.error(new Date(), 'No Check Function For Cron Method ' + method);
526
-
527
- await this.reportMethodError(
528
- 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'],
529
- correlationId,
530
- { message: 'Missing check function for cron method', method },
531
- { context: 'callMethodCron-validation', method }
532
- );
533
-
534
- throw new Error('No Check Function For Cron Method ' + method);
535
- }
536
- else if (!cronMethod.check._schema) {
537
- console.error(new Date(), 'No Check Schema For Cron Method ' + method);
538
-
539
- await this.reportMethodError(
540
- 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'],
541
- correlationId,
542
- { message: 'Missing check schema for cron method', method },
543
- { context: 'callMethodCron-validation', method }
544
- );
545
-
546
- throw new Error('No Check Schema For Cron Method ' + method);
547
- }
548
- else {
549
- const valObj = {};
550
- const valKeys = Object.keys(cronMethod.check._schema);
551
-
552
- const rootKeys = valKeys.filter(a => !a.includes('.'));
553
-
554
- for (let i = 0; i < methodData.length; i++) {
555
- valObj[rootKeys[i]] = methodData[i];
556
- }
557
-
558
- try {
559
- cronMethod.check.validate(valObj);
560
- }
561
- catch (err) {
562
- console.error(new Date(), 'Error in Cron Method Check (' + method + ')', err);
563
-
564
- const { error: normalizedError, correlationId: resolvedCorrelationId } = ensureErrorWithCorrelation(err, correlationId);
565
-
566
- await this.reportMethodError(
567
- 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'],
568
- resolvedCorrelationId,
569
- {
570
- message: 'Match error on cron method',
571
- method,
572
- data: valObj,
573
- validationError: normalizedError
574
- },
575
- { context: 'callMethodCron-validation-error', method },
576
- normalizedError.stack
577
- );
578
- normalizedError.message = `${new Date().toISOString()} - Error in Cron Method Check (${method}): ${normalizedError.message}`;
579
-
580
- throw normalizedError;
581
- }
582
- }
583
- }
584
-
585
- const monitor = this._monitorManagerFunction.startMonitorFunction('Cron Method', method, '', '', methodData);
586
-
587
- try {
588
- const res = await cronMethod.function.call(Object.assign({}, this, MethodManager.prototype, {id_user: '', user: '', id_ws: ''}), ...methodData);
589
- return res;
590
- }
591
- catch (err) {
592
- const { error: normalizedError, correlationId: resolvedCorrelationId } = ensureErrorWithCorrelation(err, correlationId);
593
-
594
- await this.reportMethodError(
595
- 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'],
596
- resolvedCorrelationId,
597
- {
598
- message: 'Error detected during cron method execution',
599
- method,
600
- data: methodData,
601
- error: normalizedError
602
- },
603
- { context: 'callMethodCron-execution', method },
604
- normalizedError.stack
605
- );
606
-
607
- normalizedError.message = `${new Date().toISOString()} - Error in Cron Method (${method}): ${normalizedError.message}`;
608
-
609
- throw normalizedError;
610
- }
611
- finally {
612
- await this._monitorManagerFunction.finishMonitorFunction(monitor);
613
- }
614
- };
615
-
616
- return await runWithCorrelationContext(correlationId, execute);
617
- }
618
-
619
- // Call/run method internal (No Emit on Socket)
620
- public async callMethod(methodName: string, ...methodData: any[]): Promise<any> {
621
- this._debugcallMethodHits += 1;
622
-
623
- const existingCorrelationId = getCorrelationId();
624
- const correlationId = existingCorrelationId || objectIdHexString();
625
-
626
- return await runWithCorrelationContext(correlationId, async () => await this.callMethodInternal(correlationId, methodName, methodData));
627
- }
628
-
629
- private async callMethodInternal(correlationId: string, methodName: string, methodData: any[]): Promise<any> {
630
- const method = this.getMethod(methodName);
631
-
632
- if (!method) {
633
- console.log('No Method: ' + methodName);
634
- throw new Error(`No Method: ${methodName}`);
635
- }
636
-
637
- const shouldTrackTextMetric = this.shouldTrackTextMessageMetric(methodName);
638
- const textMetricProvider = shouldTrackTextMetric ? this.getTextMessageProvider() : undefined;
639
-
640
- let releaseLocalConcurrency = await this.acquireLocalConcurrency(methodName, method.maxConcurrency);
641
-
642
- try {
643
- if ((methodData.length > 1 || (methodData[0] && typeof methodData[0] !== 'function')) && !method.skipValidation) {
644
- if (!method.check) {
645
- console.error(new Date(), 'No Check Function For Method ' + methodName);
646
- throw new Error(`No Check Function For Method: ${methodName}`);
647
- }
648
- else if (!method.check._schema) {
649
- console.error(new Date(), 'No Check Schema For Method ' + methodName);
650
- throw new Error(`No Check Schema For Method: ${methodName}`);
651
- }
652
- }
653
-
654
- if (methodName !== 'insertSubscriptionLog' &&
655
- methodName !== 'getDataURIfromURL' &&
656
- methodName !== 'processAirdropDistribution' &&
657
- methodName !== 'incCounter' &&
658
- methodName !== 'supportCreateBillingUser' &&
659
- methodName !== 'countCollectionWithQuery' &&
660
- methodName !== 'countWithQuery' &&
661
- methodName !== 'qbFetchRequests' &&
662
- methodName !== 'qbHandleResponse'
663
- ) {
664
- if (
665
- ResolveIOServer.shouldWriteLogsOffline()
666
- ) {
667
- ResolveIOServer.getLocalLogManager().writeLog({
668
- type: 'log',
669
- data: {
670
- _id: objectIdHexString(),
671
- createdAt: new Date(),
672
- type: 'callMethod',
673
- collection: '',
674
- id_document: '',
675
- payload: getBinarySize(JSON.stringify([methodData])) < 1000000 ? JSON.stringify([methodData], null, 2) : 'Too Big',
676
- method: methodName,
677
- id_user: this['id_user'] || '',
678
- user: this['user'] || '',
679
- messageId: 0,
680
- route: '',
681
- instance_index: process.env.NODE_APP_INSTANCE || '0',
682
- correlationId
683
- }
684
- });
685
- }
686
- else {
687
- await Logs.insertOne({
688
- _id: objectIdHexString(),
689
- type: 'callMethod',
690
- collection: '',
691
- id_document: '',
692
- payload: getBinarySize(JSON.stringify([methodData])) < 1000000 ? JSON.stringify([methodData], null, 2) : 'Too Big',
693
- method: methodName,
694
- id_user: this['id_user'] || '',
695
- user: this['user'] || '',
696
- messageId: 0,
697
- route: '',
698
- client: 'ResolveIO',
699
- instance: ResolveIOServer.getInstanceHost(),
700
- instance_index: process.env.NODE_APP_INSTANCE || '0',
701
- correlationId
702
- })
703
- };
704
- }
705
-
706
- const methodCallback = typeof(methodData[methodData.length - 1]) === 'function' ? methodData[methodData.length - 1] : null;
707
- const functionMethodData = methodCallback ? methodData.slice(0, -1) : methodData;
708
-
709
- const session = ResolveIOServer.getMongoManager().getSession();
710
- const shouldStartTransaction = !method.bypassSession &&
711
- !session &&
712
- ![
713
- 'insertErrorLog', // CIRCULAR LOOP - DO NOT REMOVE
714
- 'countWithQuery', // MONGO SESSIONS/TRANSACTIONS DONT WORK WITH COUNTS
715
- 'sendEmail' // ALWAYS SEND SO ALWAYS HAVE RECORD - DONT ROLL BACK - BYPASS SESSION
716
- ].includes(methodName) &&
717
- !methodName.startsWith('monitor-') &&
718
- !methodName.startsWith('log');
719
-
720
- const executeWithExistingSession = async () => {
721
- // console.log(new Date(), 'Calling Method - Existing Session', methodName);
722
- let monitor = this._monitorManagerFunction.startMonitorFunction('Method', methodName, this['user'] || '', '', functionMethodData);
723
-
724
- try {
725
- let res = await method.function.call(Object.assign({}, this, MethodManager.prototype), ...functionMethodData);
726
-
727
- if (methodCallback) {
728
- methodCallback(null, res);
729
- }
730
-
731
- if (shouldTrackTextMetric) {
732
- try {
733
- await recordTextMessageMetric({
734
- status: 'sent',
735
- provider: textMetricProvider,
736
- metadata: {
737
- method: methodName
738
- }
739
- });
740
- }
741
- catch (error) {
742
- console.error('Error recording text message metric:', error);
743
- }
744
- }
745
-
746
- return res;
747
- }
748
- catch (err) {
749
- if (err.code === 112 || err.codeName === 'WriteConflict' || err.code === 251 || err.codeName === 'NoSuchTransaction') {
750
- throw err; // Write error, retry
751
- }
752
-
753
- const { error: normalizedError, correlationId: resolvedCorrelationId } = ensureErrorWithCorrelation(err, correlationId);
754
-
755
- console.log(JSON.stringify([new Date(), 'Error Method Manager - Run Method - Existing Session', methodName, {
756
- code: normalizedError.code,
757
- codeName: normalizedError.codeName,
758
- message: normalizedError.message,
759
- stack: normalizedError.stack,
760
- correlationId: resolvedCorrelationId
761
- }], null, 2));
762
-
763
- await this.reportMethodError(
764
- 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'],
765
- resolvedCorrelationId,
766
- {
767
- message: 'Error detected during method execution (existing session)',
768
- method: methodName,
769
- data: methodData,
770
- error: normalizedError
771
- },
772
- { context: 'callMethod-existing-session', methodName },
773
- normalizedError.stack
774
- );
775
- normalizedError.message = `${new Date().toISOString()} - Error in Method (${methodName}) - Existing Session: ${normalizedError.message}`;
776
-
777
- if (methodCallback) {
778
- methodCallback(normalizedError, null);
779
- }
780
-
781
- if (shouldTrackTextMetric) {
782
- try {
783
- await recordTextMessageMetric({
784
- status: 'failed',
785
- provider: textMetricProvider,
786
- metadata: {
787
- method: methodName
788
- }
789
- });
790
- }
791
- catch (error) {
792
- console.error('Error recording text message metric:', error);
793
- }
794
- }
795
-
796
- if (!process.env.IS_WORKER_INSTANCE) {
797
- await this.callMethod(
798
- 'insertErrorLog',
799
- `Error in Method: ${methodName}`,
800
- {
801
- method: methodName,
802
- methodData,
803
- error: {
804
- message: normalizedError.message,
805
- stack: normalizedError.stack,
806
- code: normalizedError.code,
807
- codeName: normalizedError.codeName
808
- },
809
- correlationId: resolvedCorrelationId
810
- }
811
- );
812
- }
813
-
814
- throw normalizedError;
815
- }
816
- finally {
817
- await this._monitorManagerFunction.finishMonitorFunction(monitor);
818
- }
819
- };
820
-
821
- if (shouldStartTransaction) {
822
- let monitor = null;
823
-
824
- return ResolveIOServer.getMongoManager().oneTimeTransaction(async () => {
825
- // console.log(new Date(), 'Calling Method - New Session', methodName);
826
-
827
- monitor = this._monitorManagerFunction.startMonitorFunction('Method', methodName, this['user'] || '', '', functionMethodData);
828
-
829
- try {
830
- let res = await method.function.call(Object.assign({}, this, MethodManager.prototype), ...functionMethodData);
831
-
832
- if (methodCallback) {
833
- methodCallback(null, res);
834
- }
835
-
836
- if (shouldTrackTextMetric) {
837
- try {
838
- await recordTextMessageMetric({
839
- status: 'sent',
840
- provider: textMetricProvider,
841
- metadata: {
842
- method: methodName
843
- }
844
- });
845
- }
846
- catch (error) {
847
- console.error('Error recording text message metric:', error);
848
- }
849
- }
850
-
851
- return res;
852
- }
853
- catch (err) {
854
- if (err.code === 112 || err.codeName === 'WriteConflict' || err.code === 251 || err.codeName === 'NoSuchTransaction') {
855
- throw err; // Write error, retry
856
- }
857
-
858
- const { error: normalizedError, correlationId: resolvedCorrelationId } = ensureErrorWithCorrelation(err, correlationId);
859
-
860
- console.log(JSON.stringify([new Date(), 'Error Method Manager - Run Method - New Session', methodName, {
861
- code: normalizedError.code,
862
- codeName: normalizedError.codeName,
863
- message: normalizedError.message,
864
- stack: normalizedError.stack,
865
- correlationId: resolvedCorrelationId
866
- }], null, 2));
867
-
868
- await this.reportMethodError(
869
- 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'],
870
- resolvedCorrelationId,
871
- {
872
- message: 'Error detected during method execution (new session)',
873
- method: methodName,
874
- data: methodData,
875
- error: normalizedError
876
- },
877
- { context: 'callMethod-new-session', methodName },
878
- normalizedError.stack
879
- );
880
- normalizedError.message = `${new Date().toISOString()} - Error in Method With Session (${methodName}) - New Session: ${normalizedError.message}`;
881
-
882
- if (methodCallback) {
883
- methodCallback(normalizedError, null);
884
- }
885
-
886
- if (shouldTrackTextMetric) {
887
- try {
888
- await recordTextMessageMetric({
889
- status: 'failed',
890
- provider: textMetricProvider,
891
- metadata: {
892
- method: methodName
893
- }
894
- });
895
- }
896
- catch (error) {
897
- console.error('Error recording text message metric:', error);
898
- }
899
- }
900
-
901
- if (!process.env.IS_WORKER_INSTANCE) {
902
- await this.callMethod(
903
- 'insertErrorLog',
904
- `Error in Method: ${methodName}`,
905
- {
906
- method: methodName,
907
- methodData,
908
- error: {
909
- message: normalizedError.message,
910
- stack: normalizedError.stack,
911
- code: normalizedError.code,
912
- codeName: normalizedError.codeName
913
- },
914
- correlationId: resolvedCorrelationId
915
- }
916
- );
917
- }
918
-
919
- throw normalizedError;
920
- }
921
- finally {
922
- await this._monitorManagerFunction.finishMonitorFunction(monitor);
923
- }
924
- });
925
- }
926
- else if (method.bypassSession && session) {
927
- return ResolveIOServer.getMongoManager().runWithoutSession(async () => await executeWithExistingSession());
928
- }
929
- else {
930
- return executeWithExistingSession();
931
- }
932
- }
933
- finally {
934
- releaseLocalConcurrency();
935
- }
936
- }
937
-
938
- private async acquireLocalConcurrency(methodName: string, maxConcurrency?: number): Promise<() => void> {
939
- if (!maxConcurrency || maxConcurrency < 1) {
940
- return () => {};
941
- }
942
-
943
- let current = this._localActiveCounts.get(methodName) || 0;
944
-
945
- if (current < maxConcurrency) {
946
- this._localActiveCounts.set(methodName, current + 1);
947
- return this.createLocalRelease(methodName);
948
- }
949
-
950
- // eslint-disable-next-line no-restricted-syntax
951
- return new Promise((resolve) => {
952
- let queue = this._localWaitQueues.get(methodName);
953
-
954
- if (!queue) {
955
- queue = [];
956
- this._localWaitQueues.set(methodName, queue);
957
- }
958
-
959
- queue.push(() => {
960
- let curr = this._localActiveCounts.get(methodName) || 0;
961
- this._localActiveCounts.set(methodName, curr + 1);
962
- resolve(this.createLocalRelease(methodName));
963
- });
964
- });
965
- }
966
-
967
- private createLocalRelease(methodName: string): () => void {
968
- let released = false;
969
-
970
- return () => {
971
- if (released) {
972
- return;
973
- }
974
-
975
- released = true;
976
-
977
- let current = this._localActiveCounts.get(methodName) || 0;
978
- this._localActiveCounts.set(methodName, current > 0 ? current - 1 : 0);
979
-
980
- let queue = this._localWaitQueues.get(methodName);
981
-
982
- if (queue && queue.length) {
983
- let next = queue.shift();
984
-
985
- if (next) {
986
- next();
987
- }
988
- }
989
- };
990
- }
991
-
992
- setupEmailWatcher() {
993
- const changeStream = EmailHistories.watchCollection([]);
994
-
995
- changeStream.on('change', async (change) => {
996
- if (change.operationType === 'insert' && change.fullDocument && change.fullDocument.status === 'pending') {
997
- this.emailQueue.add(change.fullDocument._id.toString());
998
- await this.tryProcessEmail();
999
- }
1000
- else if (change.operationType === 'update' || change.operationType === 'replace') {
1001
- const updatedEmail = change.fullDocument;
1002
- if (updatedEmail && updatedEmail.status !== 'pending' && this.emailQueue.has(updatedEmail._id.toString())) {
1003
- this.emailQueue.delete(updatedEmail._id.toString());
1004
- }
1005
- }
1006
- })
1007
- .on('error', async err => {
1008
- console.error('Email history changestream error', err);
1009
- await changeStream.close();
1010
- })
1011
- .on('close', () => {
1012
- this.setupEmailWatcher();
1013
- });
1014
- }
1015
-
1016
- async loadPendingEmails() {
1017
- // Load any pending emails on startup
1018
- const pendingEmails = await EmailHistories.find({ status: 'pending' }, {sort: {_id: 1}});
1019
- for (const email of pendingEmails) {
1020
- this.emailQueue.add(email._id.toString());
1021
- }
1022
- // Try to process emails
1023
- await this.tryProcessEmail();
1024
- }
1025
-
1026
- async tryProcessEmail() {
1027
- if (this.isEmailProcessing || this.emailQueue.size === 0) {
1028
- return;
1029
- }
1030
-
1031
- this.isEmailProcessing = true;
1032
-
1033
- try {
1034
- while (this.emailQueue.size > 0) {
1035
- const emailId = this.emailQueue.values().next().value;
1036
- this.emailQueue.delete(emailId);
1037
-
1038
- const pendingEmail = await EmailHistories.findOne(
1039
- {
1040
- _id: emailId,
1041
- status: 'pending',
1042
- }
1043
- );
1044
-
1045
- if (!pendingEmail) {
1046
- continue;
1047
- }
1048
-
1049
- let queuedAt: Date;
1050
- if (pendingEmail.date instanceof Date) {
1051
- queuedAt = pendingEmail.date;
1052
- }
1053
- else if (pendingEmail.createdAt instanceof Date) {
1054
- queuedAt = pendingEmail.createdAt;
1055
- }
1056
- else {
1057
- queuedAt = new Date();
1058
- }
1059
-
1060
- const timeSinceQueued = Date.now() - queuedAt.getTime();
1061
- const remainingDelay = this._emailProcessingDelayMs - timeSinceQueued;
1062
-
1063
- if (remainingDelay > 0) {
1064
- // eslint-disable-next-line no-restricted-syntax
1065
- await new Promise(resolve => setTimeout(resolve, remainingDelay));
1066
- }
1067
-
1068
- const emailHistory = await EmailHistories.findOneAndUpdate(
1069
- {
1070
- _id: emailId,
1071
- status: 'pending',
1072
- },
1073
- {
1074
- $set: { status: 'processing', processingAt: new Date() },
1075
- }
1076
- );
1077
-
1078
- if (!emailHistory) {
1079
- continue;
1080
- }
1081
-
1082
- // Fetch and process attachments
1083
- if (emailHistory.attachments && emailHistory.attachments.length > 0) {
1084
- const validAttachments: any[] = [];
1085
- let attachmentError = false;
1086
-
1087
- for (const att of emailHistory.attachments) {
1088
- if (att.path && att.path.startsWith('http')) {
1089
- try {
1090
- const response = await fetch(att.path);
1091
- if (!response.ok) {
1092
- attachmentError = true;
1093
- continue;
1094
- }
1095
- const arrayBuffer = await response.arrayBuffer();
1096
- const buffer = Buffer.from(arrayBuffer);
1097
-
1098
- // Check the size of the attachment
1099
- const maxSize = 20 * 1024 * 1024; // 20MB in bytes
1100
- if (buffer.length <= maxSize) {
1101
- // Attachment is within size limits, include it
1102
- att.content = buffer;
1103
- delete att.path;
1104
- validAttachments.push(att);
1105
- }
1106
- }
1107
- catch (err) {
1108
- console.error('Failed to fetch attachment:', err);
1109
- attachmentError = true;
1110
- }
1111
- }
1112
- else {
1113
- validAttachments.push(att);
1114
- }
1115
- }
1116
-
1117
- emailHistory.attachments = validAttachments;
1118
- if (attachmentError) {
1119
- emailHistory.text =
1120
- (typeof emailHistory.text === 'string' ? emailHistory.text : '') +
1121
- '\n\nCould not load attachments.';
1122
- emailHistory.html =
1123
- (typeof emailHistory.html === 'string' ? emailHistory.html : '') +
1124
- '<p>Could not load attachments.</p>';
1125
- }
1126
- }
1127
-
1128
- // Prepare email options
1129
- const mailOptions: any = {
1130
- replyTo: emailHistory.reply_to || (ResolveIOServer.getServerConfig()['MAIL_REPLY_TO'] || undefined),
1131
- from: emailHistory.send_from || ResolveIOServer.getServerConfig().MAIL_FROM,
1132
- to: emailHistory.email,
1133
- subject:
1134
- (ResolveIOServer.getServerConfig()['ROOT_URL'].match(/https:\/\/dev\./) ||
1135
- ResolveIOServer.getServerConfig()['ROOT_URL'].match(/https:\/\/www\.dev\./)
1136
- ? '(DEV SERVER) - '
1137
- : '') + emailHistory.subject,
1138
- text: typeof emailHistory.text === 'string' ? emailHistory.text : '',
1139
- html: typeof emailHistory.html === 'string' ? emailHistory.html : '',
1140
- attachments: emailHistory.attachments || [],
1141
- force_ses: emailHistory.force_ses
1142
- };
1143
-
1144
- // Process attachments before sending
1145
- if (mailOptions.attachments && mailOptions.attachments.length > 0) {
1146
- mailOptions.attachments = mailOptions.attachments.map((att) => {
1147
- const newAtt = { ...att };
1148
- // Handle attachments stored as BinData or Buffer
1149
- if (newAtt.content && typeof newAtt.content === 'object' && !(newAtt.content instanceof Buffer)) {
1150
- // Convert MongoDB's Binary data to Buffer
1151
- if (newAtt.content._bsontype === 'Binary' && newAtt.content.sub_type === 0) {
1152
- newAtt.content = Buffer.from(newAtt.content.buffer);
1153
- }
1154
- else {
1155
- // Handle other types if necessary
1156
- newAtt.content = Buffer.from(newAtt.content);
1157
- }
1158
- }
1159
- // Handle attachments stored as Base64 strings
1160
- else if (typeof newAtt.content === 'string' && newAtt.encoding === 'base64') {
1161
- newAtt.content = Buffer.from(newAtt.content, 'base64');
1162
- delete newAtt.encoding;
1163
- }
1164
- // Ensure the content is a Buffer
1165
- else if (typeof newAtt.content === 'string') {
1166
- newAtt.content = Buffer.from(newAtt.content);
1167
- }
1168
- return newAtt;
1169
- });
1170
- }
1171
-
1172
- // Send the email
1173
- const emailProvider = (!mailOptions.force_ses && this._mailerCustom) ? 'custom' : 'ses';
1174
- (!mailOptions.force_ses && this._mailerCustom ? this._mailerCustom : this._mailerSES).sendMail(mailOptions, async err => {
1175
- const metricStatus = err ? 'failed' : 'sent';
1176
-
1177
- try {
1178
- if (err) {
1179
- console.error('Failed to send email:', err);
1180
- await EmailHistories.updateOne(
1181
- { _id: emailHistory._id },
1182
- {
1183
- $set: {
1184
- status: 'failed',
1185
- error: typeof err === 'string' ? err : this.safeStringify(err),
1186
- completedAt: new Date(),
1187
- },
1188
- }
1189
- );
1190
- }
1191
- else {
1192
- if (emailHistory.email === 'dev@resolveio.com') {
1193
- await EmailHistories.deleteOne({ _id: emailHistory._id });
1194
- }
1195
- else {
1196
- await EmailHistories.updateOne(
1197
- { _id: emailHistory._id },
1198
- {
1199
- $set: {
1200
- status: 'completed',
1201
- completedAt: new Date(),
1202
- },
1203
- }
1204
- );
1205
- }
1206
- }
1207
- }
1208
- catch (error) {
1209
- console.error('Error in sendMail callback:', error);
1210
- await EmailHistories.updateOne(
1211
- { _id: emailHistory._id },
1212
- {
1213
- $set: {
1214
- status: 'failed',
1215
- error: typeof error === 'string' ? error : this.safeStringify(error),
1216
- completedAt: new Date(),
1217
- },
1218
- }
1219
- );
1220
- }
1221
- finally {
1222
- try {
1223
- await recordEmailMetric({
1224
- status: metricStatus,
1225
- provider: emailProvider,
1226
- metadata: {
1227
- method: 'sendEmail'
1228
- }
1229
- });
1230
- }
1231
- catch (error) {
1232
- console.error('Error recording email metric:', error);
1233
- }
1234
- }
1235
- });
1236
-
1237
- // Wait for at least one second before sending the next email
1238
- // eslint-disable-next-line no-restricted-syntax
1239
- await new Promise((resolve) => setTimeout(resolve, 1000));
1240
- }
1241
- }
1242
- catch (err) {
1243
- console.error('Error processing email queue:', err);
1244
- }
1245
- finally {
1246
- this.isEmailProcessing = false;
1247
- // Check if new emails arrived while processing
1248
- if (this.emailQueue.size > 0) {
1249
- await this.tryProcessEmail();
1250
- }
1251
- }
1252
- }
1253
-
1254
- private shouldTrackTextMessageMetric(methodName: string): boolean {
1255
- const normalized = String(methodName || '').trim().toLowerCase();
1256
- if (!normalized) {
1257
- return false;
1258
- }
1259
-
1260
- return normalized.startsWith('sendsms') || normalized.startsWith('sendtext');
1261
- }
1262
-
1263
- private getTextMessageProvider(): string | undefined {
1264
- const provider = this.serverConfig?.['SMS_PROVIDER'] || '';
1265
- if (typeof provider === 'string' && provider.trim().length) {
1266
- return provider.trim().toLowerCase();
1267
- }
1268
-
1269
- if (this.serverConfig?.['TWILIO_SID'] || this.serverConfig?.['TWILIO_AUTH_TOKEN']) {
1270
- return 'twilio';
1271
- }
1272
-
1273
- return undefined;
1274
- }
1275
-
1276
- safeStringify(obj)
1277
- {
1278
- try
1279
- {
1280
- return JSON.stringify(obj, this.getCircularReplacer());
1281
- }
1282
- catch (e)
1283
- {
1284
- return `Error in JSON stringifying: ${e.message}`;
1285
- }
1286
- }
1287
-
1288
- getCircularReplacer()
1289
- {
1290
- const seen = new WeakSet();
1291
- return (key, value) =>
1292
- {
1293
- if (typeof value === "object" && value !== null)
1294
- {
1295
- if (seen.has(value))
1296
- {
1297
- return "[Circular]";
1298
- }
1299
- seen.add(value);
1300
- }
1301
- return value;
1302
- };
1303
- }
1304
-
1305
- private async tryMergeEmailOccurrence(
1306
- email: string,
1307
- subject: string,
1308
- correlationId: string,
1309
- occurrence: EmailHistoryOccurrence,
1310
- meta?: Record<string, any>
1311
- ): Promise<EmailHistoryModel | null> {
1312
- const existing = await EmailHistories.findOne(
1313
- {
1314
- email,
1315
- correlationId,
1316
- status: 'pending'
1317
- },
1318
- { sort: { date: 1 } }
1319
- );
1320
-
1321
- if (!existing) {
1322
- return null;
1323
- }
1324
-
1325
- const normalizedOccurrences: EmailHistoryOccurrence[] = Array.isArray(existing.occurrences) && existing.occurrences.length
1326
- ? existing.occurrences.map((item: EmailHistoryOccurrence) => ({
1327
- _id: item._id || objectIdHexString(),
1328
- createdAt: item.createdAt instanceof Date ? item.createdAt : new Date(item.createdAt),
1329
- subject: item.subject || existing.subject || '',
1330
- text: item.text,
1331
- html: item.html,
1332
- meta: item.meta
1333
- }))
1334
- : [createEmailOccurrence(
1335
- existing.subject || '',
1336
- typeof existing.text === 'string' ? existing.text : undefined,
1337
- typeof existing.html === 'string' ? existing.html : undefined,
1338
- existing.meta
1339
- )];
1340
-
1341
- normalizedOccurrences.push(occurrence);
1342
-
1343
- const { text: aggregatedText, html: aggregatedHtml } = formatGroupedEmailContent(correlationId, normalizedOccurrences);
1344
-
1345
- const updated = await EmailHistories.findOneAndUpdate(
1346
- {
1347
- _id: existing._id,
1348
- status: 'pending'
1349
- },
1350
- {
1351
- $set: {
1352
- subject,
1353
- text: aggregatedText,
1354
- html: aggregatedHtml,
1355
- occurrences: normalizedOccurrences,
1356
- meta: meta || existing.meta,
1357
- updatedAt: new Date()
1358
- }
1359
- },
1360
- { returnDocument: 'after' }
1361
- );
1362
-
1363
- return updated || null;
1364
- }
1365
-
1366
- public async sendEmail(
1367
- sendTo: string,
1368
- subject: string,
1369
- text?: string | null,
1370
- html?: string | null,
1371
- attachments?: any[] | null,
1372
- send_from?: string | null,
1373
- reply_to?: string | null,
1374
- force_ses = false,
1375
- local_override = false,
1376
- options?: SendEmailOptions
1377
- ) {
1378
- // Modify sendTo in development environments
1379
- if (
1380
- (ResolveIOServer.getServerConfig()['ROOT_URL'].match(/https:\/\/dev\./) ||
1381
- ResolveIOServer.getServerConfig()['ROOT_URL'].match(/https:\/\/www\.dev\./) ||
1382
- ResolveIOServer.getServerConfig()['ROOT_URL'] === 'http://localhost:4200') &&
1383
- !sendTo.match(/\@resolveio\.com/)
1384
- ) {
1385
- sendTo = 'dev@resolveio.com';
1386
- }
1387
-
1388
- const normalizedSubject = subject || '';
1389
- const correlationId = options?.correlationId;
1390
- const finalSubject = appendCorrelationIdToSubject(normalizedSubject, correlationId);
1391
- const groupByCorrelationId = !!correlationId;
1392
- const normalizedText = typeof text === 'string' ? text : '';
1393
- const normalizedHtml = typeof html === 'string' ? html : '';
1394
- const occurrence = groupByCorrelationId
1395
- ? createEmailOccurrence(normalizedSubject, normalizedText, normalizedHtml, options?.meta)
1396
- : null;
1397
- let allowGrouping = groupByCorrelationId;
1398
-
1399
- if (sendTo) {
1400
- if (
1401
- ResolveIOServer.getServerConfig()['ROOT_URL'] !== 'http://localhost:4200' ||
1402
- local_override
1403
- ) {
1404
- let normalizedAttachments: any[] = [];
1405
- if (Array.isArray(attachments)) {
1406
- normalizedAttachments = attachments.slice();
1407
- }
1408
- else if (attachments) {
1409
- normalizedAttachments = [attachments];
1410
- }
1411
-
1412
- normalizedAttachments = normalizedAttachments.map(att => {
1413
- const newAtt = { ...att };
1414
- if (Buffer.isBuffer(newAtt.content)) {
1415
- newAtt.content = newAtt.content.toString('base64');
1416
- newAtt.encoding = 'base64';
1417
- }
1418
- return newAtt;
1419
- });
1420
-
1421
- if (normalizedAttachments.length > 0) {
1422
- allowGrouping = false;
1423
- }
1424
-
1425
- if (allowGrouping && occurrence && correlationId) {
1426
- const merged = await this.tryMergeEmailOccurrence(sendTo, finalSubject, correlationId, occurrence, options?.meta);
1427
- if (merged) {
1428
- return merged;
1429
- }
1430
- }
1431
-
1432
- const emailHistory: EmailHistoryModel = {
1433
- _id: objectIdHexString(),
1434
- __v: 0,
1435
- date: new Date(),
1436
- id_user: this['id_user'] || '',
1437
- user: this['user'] || '',
1438
- email: sendTo,
1439
- subject: finalSubject,
1440
- text: normalizedText,
1441
- html: normalizedHtml,
1442
- attachments: normalizedAttachments,
1443
- send_from: send_from || '',
1444
- reply_to: reply_to || '',
1445
- status: 'pending',
1446
- error: '',
1447
- force_ses
1448
- };
1449
-
1450
- if (allowGrouping && occurrence && correlationId) {
1451
- const { text: aggregatedText, html: aggregatedHtml } = formatGroupedEmailContent(correlationId, [occurrence]);
1452
- emailHistory.text = aggregatedText;
1453
- emailHistory.html = aggregatedHtml;
1454
- emailHistory.occurrences = [occurrence];
1455
- emailHistory.correlationId = correlationId;
1456
- if (options?.meta) {
1457
- emailHistory.meta = options.meta;
1458
- }
1459
- }
1460
- else {
1461
- if (correlationId) {
1462
- emailHistory.correlationId = correlationId;
1463
- }
1464
- if (options?.meta) {
1465
- emailHistory.meta = options.meta;
1466
- }
1467
- }
1468
-
1469
- try {
1470
- let history = await EmailHistories.insertOne(emailHistory);
1471
- return history;
1472
- }
1473
- catch (err) {
1474
- console.error('Failed to queue email:', err);
1475
- err.message = `Failed to queue email: ${err.message}`;
1476
- throw err;
1477
- }
1478
- }
1479
- else {
1480
- console.log(
1481
- 'Send email',
1482
- sendTo,
1483
- finalSubject,
1484
- normalizedText,
1485
- normalizedHtml,
1486
- attachments,
1487
- send_from,
1488
- force_ses,
1489
- correlationId
1490
- );
1491
-
1492
- return true;
1493
- }
1494
- }
1495
- else {
1496
- return true;
1497
- }
1498
- }
1499
-
1500
- public getAWS(): AWS {
1501
- return this._aws;
1502
- }
1503
-
1504
- public readFile(fileName) {
1505
- if (fs.existsSync(path.join(__dirname, ('../private/' + fileName)))) {
1506
- try {
1507
- return fs.readFileSync(path.join(__dirname, ('../private/' + fileName)), 'utf-8');
1508
- }
1509
- catch (err) {
1510
- err.message = `Error in readFile: ${err.message}`;
1511
- throw err;
1512
- }
1513
- }
1514
- else {
1515
- if (fs.existsSync(path.join(ResolveIOServer.getClientDir(), ('./private/' + fileName)))) {
1516
- try {
1517
- return fs.readFileSync(path.join(ResolveIOServer.getClientDir(), ('./private/' + fileName)), 'utf-8');
1518
- }
1519
- catch (err) {
1520
- err.message = `Error in readFile: ${err.message}`;
1521
- throw err;
1522
- }
1523
- }
1524
- }
1525
-
1526
- throw new Error ('Error in readFile: File Not Found');
1527
- }
1528
-
1529
- public readImage(fileName) {
1530
- if (fs.existsSync(path.join(__dirname, ('../private/' + fileName)))) {
1531
- try {
1532
- return fs.readFileSync(path.join(__dirname, ('../private/' + fileName)), 'base64');
1533
- }
1534
- catch (err) {
1535
- err.message = `Error in readImage: ${err.message}`;
1536
- throw err;
1537
- }
1538
- }
1539
- else {
1540
- if (fs.existsSync(path.join(ResolveIOServer.getClientDir(), ('./private/' + fileName)))) {
1541
- try {
1542
- return fs.readFileSync(path.join(ResolveIOServer.getClientDir(), ('./private/' + fileName)), 'base64');
1543
- }
1544
- catch (err) {
1545
- err.message = `Error in readImage: ${err.message}`;
1546
- throw err;
1547
- }
1548
- }
1549
- }
1550
-
1551
- throw new Error ('Error in readImage: File Not Found');
1552
- }
1553
-
1554
- public getEnableDebug() {
1555
- return this._enableDebug;
1556
- }
1557
- }