@resolveio/server-lib 12.5.54 → 12.5.55

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 (400) hide show
  1. package/client-server-app.d.ts +1 -0
  2. package/client-server-app.js +48 -0
  3. package/client-server-app.js.map +1 -0
  4. package/collections/app-status.collection.d.ts +3 -0
  5. package/collections/app-status.collection.js +51 -0
  6. package/collections/app-status.collection.js.map +1 -0
  7. package/collections/counter.collection.d.ts +3 -0
  8. package/collections/counter.collection.js +54 -0
  9. package/collections/counter.collection.js.map +1 -0
  10. package/collections/cron-job-history.collection.d.ts +3 -0
  11. package/collections/cron-job-history.collection.js +82 -0
  12. package/collections/cron-job-history.collection.js.map +1 -0
  13. package/collections/cron-job.collection.d.ts +3 -0
  14. package/collections/cron-job.collection.js +85 -0
  15. package/collections/cron-job.collection.js.map +1 -0
  16. package/collections/email-history.collection.d.ts +3 -0
  17. package/collections/email-history.collection.js +66 -0
  18. package/collections/email-history.collection.js.map +1 -0
  19. package/collections/email-verified.collection.d.ts +3 -0
  20. package/collections/email-verified.collection.js +61 -0
  21. package/collections/email-verified.collection.js.map +1 -0
  22. package/collections/file.collection.d.ts +3 -0
  23. package/collections/file.collection.js +73 -0
  24. package/collections/file.collection.js.map +1 -0
  25. package/collections/flag.collection.d.ts +3 -0
  26. package/collections/flag.collection.js +56 -0
  27. package/collections/flag.collection.js.map +1 -0
  28. package/collections/log-method-latency.collection.d.ts +3 -0
  29. package/collections/log-method-latency.collection.js +64 -0
  30. package/collections/log-method-latency.collection.js.map +1 -0
  31. package/collections/log-subscription.collection.d.ts +3 -0
  32. package/collections/log-subscription.collection.js +68 -0
  33. package/collections/log-subscription.collection.js.map +1 -0
  34. package/collections/log-ts.collection.d.ts +3 -0
  35. package/collections/log-ts.collection.js +78 -0
  36. package/collections/log-ts.collection.js.map +1 -0
  37. package/collections/log.collection.d.ts +3 -0
  38. package/collections/log.collection.js +77 -0
  39. package/collections/log.collection.js.map +1 -0
  40. package/collections/logged-in-users.collection.d.ts +3 -0
  41. package/collections/logged-in-users.collection.js +65 -0
  42. package/collections/logged-in-users.collection.js.map +1 -0
  43. package/collections/method-response.collection.d.ts +3 -0
  44. package/collections/method-response.collection.js +66 -0
  45. package/collections/method-response.collection.js.map +1 -0
  46. package/collections/monitor-cpu.collection.d.ts +3 -0
  47. package/collections/monitor-cpu.collection.js +63 -0
  48. package/collections/monitor-cpu.collection.js.map +1 -0
  49. package/collections/monitor-memory.collection.d.ts +3 -0
  50. package/collections/monitor-memory.collection.js +75 -0
  51. package/collections/monitor-memory.collection.js.map +1 -0
  52. package/collections/monitor-mongo.collection.d.ts +3 -0
  53. package/collections/monitor-mongo.collection.js +69 -0
  54. package/collections/monitor-mongo.collection.js.map +1 -0
  55. package/collections/notification.collection.d.ts +3 -0
  56. package/collections/notification.collection.js +51 -0
  57. package/collections/notification.collection.js.map +1 -0
  58. package/collections/report-builder-dashboard-builder.collection.d.ts +3 -0
  59. package/collections/report-builder-dashboard-builder.collection.js +109 -0
  60. package/collections/report-builder-dashboard-builder.collection.js.map +1 -0
  61. package/collections/report-builder-library.collection.d.ts +3 -0
  62. package/collections/report-builder-library.collection.js +87 -0
  63. package/collections/report-builder-library.collection.js.map +1 -0
  64. package/collections/report-builder-report.collection.d.ts +4 -0
  65. package/collections/report-builder-report.collection.js +149 -0
  66. package/collections/report-builder-report.collection.js.map +1 -0
  67. package/collections/user-group.collection.d.ts +4 -0
  68. package/collections/user-group.collection.js +90 -0
  69. package/collections/user-group.collection.js.map +1 -0
  70. package/collections/user-guide.collection.d.ts +3 -0
  71. package/collections/user-guide.collection.js +57 -0
  72. package/collections/user-guide.collection.js.map +1 -0
  73. package/collections/user.collection.d.ts +4 -0
  74. package/collections/user.collection.js +259 -0
  75. package/collections/user.collection.js.map +1 -0
  76. package/cron/cron.d.ts +5 -0
  77. package/cron/cron.js +162 -0
  78. package/cron/cron.js.map +1 -0
  79. package/fixtures/cron-jobs.d.ts +1 -0
  80. package/fixtures/cron-jobs.js +73 -0
  81. package/fixtures/cron-jobs.js.map +1 -0
  82. package/fixtures/init.d.ts +1 -0
  83. package/fixtures/init.js +59 -0
  84. package/fixtures/init.js.map +1 -0
  85. package/http/auth.d.ts +2 -0
  86. package/http/auth.js +763 -0
  87. package/http/auth.js.map +1 -0
  88. package/http/health.d.ts +1 -0
  89. package/http/health.js +12 -0
  90. package/http/health.js.map +1 -0
  91. package/http/home.d.ts +2 -0
  92. package/http/home.js +66 -0
  93. package/http/home.js.map +1 -0
  94. package/index.d.ts +23 -0
  95. package/index.js +127 -0
  96. package/index.js.map +1 -0
  97. package/managers/cron.manager.d.ts +17 -0
  98. package/managers/cron.manager.js +242 -0
  99. package/managers/cron.manager.js.map +1 -0
  100. package/managers/method.manager.d.ts +38 -0
  101. package/managers/method.manager.js +595 -0
  102. package/managers/method.manager.js.map +1 -0
  103. package/managers/mongo.manager.d.ts +178 -0
  104. package/managers/mongo.manager.js +2221 -0
  105. package/managers/mongo.manager.js.map +1 -0
  106. package/managers/monitor.manager.d.ts +59 -0
  107. package/managers/monitor.manager.js +351 -0
  108. package/managers/monitor.manager.js.map +1 -0
  109. package/managers/subscription.manager.d.ts +50 -0
  110. package/managers/subscription.manager.js +1091 -0
  111. package/managers/subscription.manager.js.map +1 -0
  112. package/managers/subscription.performance.d.ts +1 -0
  113. package/{src/managers/subscription.performance.ts → managers/subscription.performance.js} +33 -68
  114. package/managers/subscription.performance.js.map +1 -0
  115. package/methods/accounts.d.ts +2 -0
  116. package/methods/accounts.js +274 -0
  117. package/methods/accounts.js.map +1 -0
  118. package/methods/aws.d.ts +2 -0
  119. package/methods/aws.js +617 -0
  120. package/methods/aws.js.map +1 -0
  121. package/methods/collections.d.ts +2 -0
  122. package/methods/collections.js +499 -0
  123. package/methods/collections.js.map +1 -0
  124. package/methods/counters.d.ts +2 -0
  125. package/methods/counters.js +122 -0
  126. package/methods/counters.js.map +1 -0
  127. package/methods/cron-jobs.d.ts +2 -0
  128. package/methods/cron-jobs.js +1315 -0
  129. package/methods/cron-jobs.js.map +1 -0
  130. package/methods/flags.d.ts +2 -0
  131. package/methods/flags.js +9 -0
  132. package/methods/flags.js.map +1 -0
  133. package/methods/logs.d.ts +2 -0
  134. package/methods/logs.js +371 -0
  135. package/methods/logs.js.map +1 -0
  136. package/methods/monitor.d.ts +2 -0
  137. package/methods/monitor.js +565 -0
  138. package/methods/monitor.js.map +1 -0
  139. package/methods/pdf.d.ts +2 -0
  140. package/methods/pdf.js +468 -0
  141. package/methods/pdf.js.map +1 -0
  142. package/methods/report-builder.d.ts +2 -0
  143. package/methods/report-builder.js +858 -0
  144. package/methods/report-builder.js.map +1 -0
  145. package/methods/support.d.ts +2 -0
  146. package/methods/support.js +246 -0
  147. package/methods/support.js.map +1 -0
  148. package/{src/models/app-status.model.ts → models/app-status.model.d.ts} +2 -3
  149. package/models/app-status.model.js +4 -0
  150. package/models/app-status.model.js.map +1 -0
  151. package/{src/models/billing-logged-in-users.model.ts → models/billing-logged-in-users.model.d.ts} +4 -5
  152. package/models/billing-logged-in-users.model.js +4 -0
  153. package/models/billing-logged-in-users.model.js.map +1 -0
  154. package/models/collection-document.model.d.ts +19 -0
  155. package/models/collection-document.model.js +4 -0
  156. package/models/collection-document.model.js.map +1 -0
  157. package/{src/models/counter.model.ts → models/counter.model.d.ts} +3 -4
  158. package/models/counter.model.js +4 -0
  159. package/models/counter.model.js.map +1 -0
  160. package/models/cron-job-history.model.d.ts +12 -0
  161. package/models/cron-job-history.model.js +4 -0
  162. package/models/cron-job-history.model.js.map +1 -0
  163. package/models/cron-job.model.d.ts +13 -0
  164. package/models/cron-job.model.js +4 -0
  165. package/models/cron-job.model.js.map +1 -0
  166. package/models/dialog.model.d.ts +23 -0
  167. package/models/dialog.model.js +4 -0
  168. package/models/dialog.model.js.map +1 -0
  169. package/{src/models/email-history.model.ts → models/email-history.model.d.ts} +7 -8
  170. package/models/email-history.model.js +4 -0
  171. package/models/email-history.model.js.map +1 -0
  172. package/{src/models/email-verified.model.ts → models/email-verified.model.d.ts} +5 -6
  173. package/models/email-verified.model.js +4 -0
  174. package/models/email-verified.model.js.map +1 -0
  175. package/{src/models/file.model.ts → models/file.model.d.ts} +7 -8
  176. package/models/file.model.js +4 -0
  177. package/models/file.model.js.map +1 -0
  178. package/{src/models/flag.model.ts → models/flag.model.d.ts} +3 -4
  179. package/models/flag.model.js +4 -0
  180. package/models/flag.model.js.map +1 -0
  181. package/{src/models/log-method-latency.model.ts → models/log-method-latency.model.d.ts} +4 -5
  182. package/models/log-method-latency.model.js +4 -0
  183. package/models/log-method-latency.model.js.map +1 -0
  184. package/{src/models/log-subscription.model.ts → models/log-subscription.model.d.ts} +6 -8
  185. package/models/log-subscription.model.js +4 -0
  186. package/models/log-subscription.model.js.map +1 -0
  187. package/{src/models/log.model.ts → models/log.model.d.ts} +10 -12
  188. package/models/log.model.js +4 -0
  189. package/models/log.model.js.map +1 -0
  190. package/{src/models/logged-in-users.model.ts → models/logged-in-users.model.d.ts} +5 -6
  191. package/models/logged-in-users.model.js +4 -0
  192. package/models/logged-in-users.model.js.map +1 -0
  193. package/{src/models/method-response.model.ts → models/method-response.model.d.ts} +6 -7
  194. package/models/method-response.model.js +4 -0
  195. package/models/method-response.model.js.map +1 -0
  196. package/models/method.model.d.ts +9 -0
  197. package/models/method.model.js +4 -0
  198. package/models/method.model.js.map +1 -0
  199. package/{src/models/monitor-cpu.model.ts → models/monitor-cpu.model.d.ts} +7 -9
  200. package/models/monitor-cpu.model.js +4 -0
  201. package/models/monitor-cpu.model.js.map +1 -0
  202. package/models/monitor-memory.model.d.ts +15 -0
  203. package/models/monitor-memory.model.js +4 -0
  204. package/models/monitor-memory.model.js.map +1 -0
  205. package/models/monitor-mongo.model.d.ts +13 -0
  206. package/models/monitor-mongo.model.js +4 -0
  207. package/models/monitor-mongo.model.js.map +1 -0
  208. package/{src/models/notification.model.ts → models/notification.model.d.ts} +2 -3
  209. package/models/notification.model.js +4 -0
  210. package/models/notification.model.js.map +1 -0
  211. package/models/pagination.model.d.ts +10 -0
  212. package/models/pagination.model.js +24 -0
  213. package/models/pagination.model.js.map +1 -0
  214. package/models/permission.model.d.ts +12 -0
  215. package/models/permission.model.js +4 -0
  216. package/models/permission.model.js.map +1 -0
  217. package/models/report-builder-dashboard-builder.model.d.ts +25 -0
  218. package/models/report-builder-dashboard-builder.model.js +4 -0
  219. package/models/report-builder-dashboard-builder.model.js.map +1 -0
  220. package/models/report-builder-library.model.d.ts +17 -0
  221. package/models/report-builder-library.model.js +4 -0
  222. package/models/report-builder-library.model.js.map +1 -0
  223. package/models/report-builder-report.model.d.ts +98 -0
  224. package/models/report-builder-report.model.js +4 -0
  225. package/models/report-builder-report.model.js.map +1 -0
  226. package/models/report-builder.model.d.ts +61 -0
  227. package/models/report-builder.model.js +4 -0
  228. package/models/report-builder.model.js.map +1 -0
  229. package/models/select-data-label.model.d.ts +9 -0
  230. package/models/select-data-label.model.js +4 -0
  231. package/models/select-data-label.model.js.map +1 -0
  232. package/models/server-response.model.d.ts +5 -0
  233. package/models/server-response.model.js +4 -0
  234. package/models/server-response.model.js.map +1 -0
  235. package/models/subscription.model.d.ts +23 -0
  236. package/models/subscription.model.js +4 -0
  237. package/models/subscription.model.js.map +1 -0
  238. package/models/support-ticket.model.d.ts +72 -0
  239. package/models/support-ticket.model.js +4 -0
  240. package/models/support-ticket.model.js.map +1 -0
  241. package/models/user-group.model.d.ts +19 -0
  242. package/models/user-group.model.js +4 -0
  243. package/models/user-group.model.js.map +1 -0
  244. package/{src/models/user-guide.model.ts → models/user-guide.model.d.ts} +4 -5
  245. package/models/user-guide.model.js +4 -0
  246. package/models/user-guide.model.js.map +1 -0
  247. package/models/user.model.d.ts +70 -0
  248. package/models/user.model.js +4 -0
  249. package/models/user.model.js.map +1 -0
  250. package/package.json +1 -1
  251. package/{src/public_api.ts → public_api.d.ts} +1 -1
  252. package/public_api.js +75 -0
  253. package/public_api.js.map +1 -0
  254. package/publications/app-status.d.ts +2 -0
  255. package/publications/app-status.js +17 -0
  256. package/publications/app-status.js.map +1 -0
  257. package/publications/cron-jobs.d.ts +2 -0
  258. package/publications/cron-jobs.js +33 -0
  259. package/publications/cron-jobs.js.map +1 -0
  260. package/publications/files.d.ts +2 -0
  261. package/publications/files.js +37 -0
  262. package/publications/files.js.map +1 -0
  263. package/publications/flags.d.ts +2 -0
  264. package/publications/flags.js +23 -0
  265. package/publications/flags.js.map +1 -0
  266. package/publications/logs.d.ts +2 -0
  267. package/publications/logs.js +165 -0
  268. package/publications/logs.js.map +1 -0
  269. package/publications/method-responses.d.ts +2 -0
  270. package/publications/method-responses.js +17 -0
  271. package/publications/method-responses.js.map +1 -0
  272. package/publications/notifications.d.ts +2 -0
  273. package/publications/notifications.js +17 -0
  274. package/publications/notifications.js.map +1 -0
  275. package/publications/report-builder-dashboard-builders.d.ts +2 -0
  276. package/publications/report-builder-dashboard-builders.js +43 -0
  277. package/publications/report-builder-dashboard-builders.js.map +1 -0
  278. package/publications/report-builder-libraries.d.ts +2 -0
  279. package/publications/report-builder-libraries.js +90 -0
  280. package/publications/report-builder-libraries.js.map +1 -0
  281. package/publications/report-builder-reports.d.ts +2 -0
  282. package/publications/report-builder-reports.js +51 -0
  283. package/publications/report-builder-reports.js.map +1 -0
  284. package/publications/super-admin.d.ts +2 -0
  285. package/publications/super-admin.js +17 -0
  286. package/publications/super-admin.js.map +1 -0
  287. package/publications/user-groups.d.ts +1 -0
  288. package/publications/user-groups.js +17 -0
  289. package/publications/user-groups.js.map +1 -0
  290. package/publications/user-guides.d.ts +1 -0
  291. package/publications/user-guides.js +17 -0
  292. package/publications/user-guides.js.map +1 -0
  293. package/server-app.d.ts +52 -0
  294. package/server-app.js +739 -0
  295. package/server-app.js.map +1 -0
  296. package/util/common.d.ts +24 -0
  297. package/util/common.js +511 -0
  298. package/util/common.js.map +1 -0
  299. package/util/schema-report-builder.d.ts +6 -0
  300. package/util/schema-report-builder.js +453 -0
  301. package/util/schema-report-builder.js.map +1 -0
  302. package/.nodemon.json +0 -5
  303. package/.vscode/settings.json +0 -3
  304. package/README.md +0 -22
  305. package/compileDTS.pl +0 -64
  306. package/gulpfile.js +0 -127
  307. package/mongodbensurers.js +0 -2
  308. package/mongostop.js +0 -3
  309. package/settings.development.json +0 -13
  310. package/src/client-server-app.ts +0 -7
  311. package/src/collections/app-status.collection.ts +0 -51
  312. package/src/collections/counter.collection.ts +0 -54
  313. package/src/collections/cron-job-history.collection.ts +0 -82
  314. package/src/collections/cron-job.collection.ts +0 -85
  315. package/src/collections/email-history.collection.ts +0 -66
  316. package/src/collections/email-verified.collection.ts +0 -61
  317. package/src/collections/file.collection.ts +0 -73
  318. package/src/collections/flag.collection.ts +0 -56
  319. package/src/collections/log-method-latency.collection.ts +0 -64
  320. package/src/collections/log-subscription.collection.ts +0 -68
  321. package/src/collections/log-ts.collection.ts +0 -78
  322. package/src/collections/log.collection.ts +0 -77
  323. package/src/collections/logged-in-users.collection.ts +0 -65
  324. package/src/collections/method-response.collection.ts +0 -66
  325. package/src/collections/monitor-cpu.collection.ts +0 -63
  326. package/src/collections/monitor-memory.collection.ts +0 -75
  327. package/src/collections/monitor-mongo.collection.ts +0 -69
  328. package/src/collections/notification.collection.ts +0 -51
  329. package/src/collections/report-builder-dashboard-builder.collection.ts +0 -109
  330. package/src/collections/report-builder-library.collection.ts +0 -89
  331. package/src/collections/report-builder-report.collection.ts +0 -149
  332. package/src/collections/user-group.collection.ts +0 -90
  333. package/src/collections/user-guide.collection.ts +0 -57
  334. package/src/collections/user.collection.ts +0 -259
  335. package/src/cron/cron.ts +0 -188
  336. package/src/fixtures/cron-jobs.ts +0 -25
  337. package/src/fixtures/init.ts +0 -10
  338. package/src/http/auth.ts +0 -732
  339. package/src/http/health.ts +0 -7
  340. package/src/http/home.ts +0 -71
  341. package/src/index.ts +0 -71
  342. package/src/managers/cron.manager.ts +0 -208
  343. package/src/managers/method.manager.ts +0 -607
  344. package/src/managers/mongo.manager.ts +0 -2282
  345. package/src/managers/monitor.manager.ts +0 -323
  346. package/src/managers/subscription.manager.ts +0 -1196
  347. package/src/methods/accounts.ts +0 -202
  348. package/src/methods/aws.ts +0 -507
  349. package/src/methods/collections.ts +0 -512
  350. package/src/methods/counters.ts +0 -75
  351. package/src/methods/cron-jobs.ts +0 -1454
  352. package/src/methods/flags.ts +0 -7
  353. package/src/methods/logs.ts +0 -327
  354. package/src/methods/monitor.ts +0 -548
  355. package/src/methods/pdf.ts +0 -615
  356. package/src/methods/report-builder.ts +0 -876
  357. package/src/methods/support.ts +0 -146
  358. package/src/models/collection-document.model.ts +0 -22
  359. package/src/models/cron-job-history.model.ts +0 -13
  360. package/src/models/cron-job.model.ts +0 -14
  361. package/src/models/dialog.model.ts +0 -25
  362. package/src/models/method.model.ts +0 -11
  363. package/src/models/monitor-memory.model.ts +0 -17
  364. package/src/models/monitor-mongo.model.ts +0 -15
  365. package/src/models/pagination.model.ts +0 -30
  366. package/src/models/permission.model.ts +0 -14
  367. package/src/models/report-builder-dashboard-builder.model.ts +0 -29
  368. package/src/models/report-builder-library.model.ts +0 -20
  369. package/src/models/report-builder-report.model.ts +0 -110
  370. package/src/models/report-builder.model.ts +0 -68
  371. package/src/models/select-data-label.model.ts +0 -9
  372. package/src/models/server-response.model.ts +0 -5
  373. package/src/models/subscription.model.ts +0 -64
  374. package/src/models/support-ticket.model.ts +0 -81
  375. package/src/models/user-group.model.ts +0 -23
  376. package/src/models/user.model.ts +0 -79
  377. package/src/publications/app-status.ts +0 -13
  378. package/src/publications/cron-jobs.ts +0 -30
  379. package/src/publications/files.ts +0 -34
  380. package/src/publications/flags.ts +0 -20
  381. package/src/publications/logs.ts +0 -164
  382. package/src/publications/method-responses.ts +0 -13
  383. package/src/publications/notifications.ts +0 -13
  384. package/src/publications/report-builder-dashboard-builders.ts +0 -39
  385. package/src/publications/report-builder-libraries.ts +0 -41
  386. package/src/publications/report-builder-reports.ts +0 -48
  387. package/src/publications/super-admin.ts +0 -13
  388. package/src/publications/user-groups.ts +0 -12
  389. package/src/publications/user-guides.ts +0 -12
  390. package/src/server-app.ts +0 -769
  391. package/src/util/common.ts +0 -519
  392. package/src/util/schema-report-builder.ts +0 -413
  393. package/tsconfig.json +0 -30
  394. package/tslint.json +0 -143
  395. /package/{src/private → private}/email-templates/enrollment.html +0 -0
  396. /package/{src/private → private}/email-templates/forgot-password.html +0 -0
  397. /package/{src/private → private}/email-templates/support-ticket-deleted.html +0 -0
  398. /package/{src/private → private}/email-templates/support-ticket-modified.html +0 -0
  399. /package/{src/private → private}/email-templates/support-ticket.html +0 -0
  400. /package/{src/private → private}/images/ResolveIO.png +0 -0
@@ -1,2282 +0,0 @@
1
- import SimpleSchema from 'simpl-schema';
2
- import { AggregateOptions, AggregationCursor, BulkWriteOptions, ChangeStream, ChangeStreamOptions, CollStats, CollStatsOptions, CommandOperationOptions, CountDocumentsOptions, CreateCollectionOptions, CreateIndexesOptions, CursorStreamOptions, DeleteOptions, Filter, FindCursor, FindOneAndDeleteOptions, FindOneAndReplaceOptions, FindOneAndUpdateOptions, FindOptions, IndexDescription, IndexInformationOptions, InsertOneOptions, ListIndexesCursor, ListIndexesOptions, ObjectId, RenameOptions, ReplaceOptions, UpdateOptions, OptionalId, Collection, CollectionInfo, OptionalUnlessRequiredId, AnyBulkWriteOperation, BulkWriteResult } from 'mongodb';
3
- import { LookupTables } from '../models/report-builder.model';
4
- import { ResolveIOServer } from '../index';
5
- import { Users } from '../collections/user.collection';
6
- import { buildRbLookups, buildRbSchema, dateReviver, deepCopy, getBinarySize, getMongoMergeUpdatedDoc } from '../util/common';
7
- import { UserModel } from '../models/user.model';
8
- import { Logs } from '../collections/log.collection';
9
- import * as NodeCache from 'node-cache';
10
- const crypto = require('crypto');
11
- const scmp = require('scmp');
12
- import { MonitorMongo } from './monitor.manager';
13
- import { CollectionDocument, Document } from '../models/collection-document.model';
14
- import { cpus } from 'os';
15
- const numCPUs = cpus().length;
16
- const v8 = require('v8');
17
-
18
- interface MongoQueueModel {
19
- _id: number,
20
- name_collection: string;
21
- lookup_collections: string[];
22
- name_function: string;
23
- data_function: any[];
24
- name_function_addt: string;
25
- data_function_addt: any[];
26
- cbs: Function[];
27
- cbs_next: Function[];
28
- running: boolean;
29
- cacheId: number;
30
- invalidateFlag: boolean;
31
- invalidateCount: number;
32
- }
33
-
34
- // export declare interface MongoManagerFilterOperators<T> extends Document {
35
- export declare interface MongoManagerFilterParamaterOperators<P> {
36
- $eq?: P;
37
- $gt?: P;
38
- $gte?: P;
39
- $in?: P extends Array<any> ? P : P[];
40
- $lt?: P;
41
- $lte?: P;
42
- $ne?: P;
43
- $nin?: P extends Array<any> ? P : P[];
44
- $not?: P extends string ? MongoManagerFilterParamaterOperators<P> | RegExpConstructor : MongoManagerFilterParamaterOperators<P>;
45
- $exists?: boolean;
46
- $expr?: any[]
47
- $regex?: P extends string ? RegExpConstructor | string : never;
48
- $options?: P extends string ? string : never;
49
- $geoIntersects?: {
50
- $geometry: Document;
51
- };
52
- $geoWithin?: Document;
53
- $near?: Document;
54
- $nearSphere?: Document;
55
- $maxDistance?: number;
56
- $all?: any[];
57
- $elemMatch?: Document;
58
- $size?: P extends any[] ? number : never;
59
- }
60
-
61
- export declare interface MongoManagerFilterOperators<T> extends Document { //TODO: Remove extends document when I get answer on S.O.
62
- $and?: MongoManagerFilter<T>[] | MongoManagerFilterOperators<T>;
63
- $nor?: MongoManagerFilter<T>[] | MongoManagerFilterOperators<T>;
64
- $or?: MongoManagerFilter<T>[] | MongoManagerFilterOperators<T>;
65
- $text?: {
66
- $search: string;
67
- $language?: string;
68
- $caseSensitive?: boolean;
69
- $diacriticSensitive?: boolean;
70
- };
71
- $where?: string | ((this: T) => boolean);
72
- $comment?: string | Document;
73
- }
74
-
75
- // function isDotStringRegExp(obj: Object, dotKey: string): boolean {
76
- // let keyData = dotKey.split('.');
77
- // let objData = obj;
78
-
79
- // for (let i = 0; i < keyData.length; i++) {
80
- // let key = keyData[i];
81
- // if (objData.hasOwnProperty(key)) {
82
- // objData = objData[key];
83
-
84
- // if (i === keyData.length - 1) {
85
- // return true;
86
- // }
87
- // }
88
- // else {
89
- // return false;
90
- // }
91
- // }
92
- // }
93
-
94
- // export declare type MongoManagerDotStringFilter<T> = {
95
- // [key: string]: (isDotStringRegExp(T, key) ? any : never);
96
- // };
97
-
98
- export declare type MongoManagerFilter<T> = {
99
- [P in keyof T]?: T[P] | MongoManagerFilterParamaterOperators<T[P]>;
100
- };
101
-
102
- export declare type MongoManagerUnsetFilter<T> = {
103
- [P in keyof T]?: number | boolean;
104
- };
105
-
106
- export declare type MongoManagerIncFilter<T> = {
107
- [P in keyof T]?: number;
108
- };
109
-
110
- export declare type MongoManagerUpdateFilter<T> = {
111
- $inc?: MongoManagerIncFilter<T> | Document;
112
- $set?: MongoManagerFilter<T> | Document;
113
- $setOnInsert?: MongoManagerFilter<T> | Document;
114
- $unset?: MongoManagerUnsetFilter<T> | Document;
115
- };
116
-
117
- export class MongoManager {
118
- private _collections: MongoManagerCollection<CollectionDocument>[] = [];
119
- private _mongoQueue: MongoQueueModel[] = [];
120
- private _mongoQueueId = 0;
121
- private _mongoQueueRunning = false;
122
-
123
- private _nodeCache;
124
- private _mongoQueueCacheId = 1;
125
-
126
- private _heapStats = v8.getHeapStatistics();
127
- private _heapLimit = this._heapStats.heap_size_limit / numCPUs / 8;
128
-
129
- private _serverCollections: (CollectionInfo | Pick<CollectionInfo, "name" | "type">)[] = [];
130
-
131
- private _debugMongoQueueHits = 0;
132
- private _debugRemoveCacheHits = 0;
133
- private _debugMongoQueueCollections = [];
134
-
135
- constructor() {
136
- this._nodeCache = new NodeCache( { stdTTL: 0, checkperiod: 0 } );
137
-
138
- setInterval(() => {
139
- if (ResolveIOServer.getMainServer().getSubscriptionManager().getEnableDebug()) {
140
- console.log(new Date(), 'Mongo Manager', 'Collections', this._collections.length);
141
- console.log(new Date(), 'Mongo Manager', 'Mongo Queue', this._mongoQueue.length, JSON.stringify(this._mongoQueue.sort((a, b) => a.name_collection.localeCompare(b.name_collection)), null, 2));
142
- console.log(new Date(), 'Mongo Manager', 'Server Collections', this._serverCollections.length);
143
- console.log(new Date(), 'Mongo Manager', 'Mongo Queue Hits', this._debugMongoQueueHits);
144
- console.log(new Date(), 'Mongo Manager', 'Mongo Queue Collections', this._debugMongoQueueCollections.sort((a, b) => a.collection.localeCompare(b.collection) || a.function.localeCompare(b.function)));
145
- console.log(new Date(), 'Mongo Manager', 'Cache Cleanup Hits', JSON.stringify(this._debugRemoveCacheHits, null, 2));
146
- }
147
-
148
- this._debugMongoQueueHits = 0;
149
- this._debugRemoveCacheHits = 0;
150
- this._debugMongoQueueCollections = [];
151
- }, 60000);
152
-
153
- this.initServerCollections();
154
-
155
- this.runQueue();
156
- }
157
-
158
- async initServerCollections() {
159
- let collections = await ResolveIOServer.getMainDB().listCollections().toArray();
160
- this._serverCollections = collections;
161
- }
162
-
163
- getServerCollections() {
164
- return this._serverCollections;
165
- }
166
-
167
- registerCollection(collection: MongoManagerCollection<CollectionDocument>) {
168
- if (collection.collectionOptions && collection.collectionOptions.timeseries && collection.collectionOptions.timeseries.timeField && this._serverCollections.some(a => a.name === collection.collectionName && a.type === 'collection')) {
169
- ResolveIOServer.getMainDB().dropCollection(collection.collectionName).then(() => {
170
- this.createCollection(collection);
171
- });
172
- }
173
-
174
- this._collections.push(collection);
175
- }
176
-
177
- createCollection(collection: MongoManagerCollection<CollectionDocument>) {
178
- ResolveIOServer.getMainDB().createCollection<CollectionDocument>(collection.collectionName, collection.collectionOptions);
179
- }
180
-
181
- collections() {
182
- return this._collections;
183
- }
184
-
185
- collection(collectionName: string): MongoManagerCollection<CollectionDocument> | MongoManagerUserCollection<CollectionDocument> {
186
- return this._collections.filter(a => a.collectionName === collectionName)[0];
187
- }
188
-
189
- addToQueue(mongoQueue: MongoQueueModel) {
190
- let _mongoQueue = this._mongoQueue.filter(a => a.name_collection === mongoQueue.name_collection && a.name_function === mongoQueue.name_function && a.name_function_addt === mongoQueue.name_function_addt && JSON.stringify(a.data_function) === JSON.stringify(mongoQueue.data_function) && JSON.stringify(a.data_function_addt) === JSON.stringify(mongoQueue.data_function_addt))[0];
191
-
192
- if (_mongoQueue) {
193
- if (!_mongoQueue.running) {
194
- _mongoQueue.cbs.push(mongoQueue.cbs[0]);
195
- }
196
- else {
197
- _mongoQueue.cbs_next.push(mongoQueue.cbs[0]);
198
- }
199
- }
200
- else {
201
- mongoQueue._id = this._mongoQueueId;
202
- this._mongoQueueId += 1;
203
-
204
- this._mongoQueue.splice(0, 0, mongoQueue);
205
- }
206
- }
207
-
208
- private async runQueue() {
209
- setInterval(() => {
210
- if (!this._mongoQueueRunning) {
211
- const queueArr = this._mongoQueue.filter(a => !a.running && a.cbs.length);
212
- if (queueArr.length) {
213
- this._mongoQueueRunning = true;
214
-
215
- for (let i = queueArr.length - 1; i >= 0; i--) {
216
- this._debugMongoQueueHits += 1;
217
-
218
- let mongoQueue = queueArr[i];
219
-
220
- if (!this._debugMongoQueueCollections.some(a => a.collection === mongoQueue.name_collection && a.function === mongoQueue.name_function)) {
221
- this._debugMongoQueueCollections.push({
222
- collection: mongoQueue.name_collection,
223
- function: mongoQueue.name_function,
224
- hits: 1
225
- });
226
- }
227
- else {
228
- this._debugMongoQueueCollections.filter(a => a.collection === mongoQueue.name_collection && a.function === mongoQueue.name_function)[0].hits += 1;
229
- }
230
-
231
- mongoQueue.running = true;
232
- mongoQueue.invalidateFlag = false;
233
-
234
- if (mongoQueue.cacheId) {
235
- try {
236
- let res = JSON.parse(this._nodeCache.get(mongoQueue.cacheId), dateReviver);
237
-
238
- mongoQueue.cbs.forEach(cb => {
239
- cb(null, res, true);
240
- });
241
-
242
- mongoQueue.cbs = [];
243
- mongoQueue.running = false;
244
- }
245
- catch {
246
- mongoQueue.cacheId = 0;
247
- }
248
- }
249
-
250
- if (!mongoQueue.cacheId) {
251
- if (!mongoQueue.name_function_addt) {
252
- let monitor = new MonitorMongo(mongoQueue.name_function, mongoQueue.name_collection, JSON.stringify(mongoQueue.data_function));
253
- ResolveIOServer.getMainDB().collection(mongoQueue.name_collection)[mongoQueue.name_function](...mongoQueue.data_function).then(res => {
254
- monitor.finish();
255
- if (!mongoQueue.invalidateFlag) {
256
- mongoQueue.invalidateCount = 0;
257
-
258
- let stringifyLength = 0;
259
- let stringifyFail = false;
260
-
261
- try {
262
- let stringify = JSON.stringify(res).replace(/[\[\]\,\"]/g,'');
263
- stringifyLength = stringify.length;
264
- }
265
- catch(e) {
266
- stringifyFail = true;
267
- }
268
-
269
- if (!stringifyFail && res !== null && res !== undefined && (!Array.isArray(res) || res.length) && stringifyLength < 10000000) {
270
- mongoQueue.cacheId = this._mongoQueueCacheId;
271
- this._mongoQueueCacheId += 1;
272
-
273
- this.addToCache(mongoQueue.cacheId, res);
274
- }
275
- else {
276
- mongoQueue.cacheId = 0;
277
- }
278
-
279
- mongoQueue.cbs.forEach(cb => {
280
- cb(null, res, false);
281
- });
282
-
283
- if (mongoQueue.cbs_next.length) {
284
- mongoQueue.cbs = mongoQueue.cbs_next;
285
- mongoQueue.cbs_next = [];
286
- }
287
- else {
288
- mongoQueue.cbs = [];
289
- }
290
- }
291
- else {
292
- if (mongoQueue.invalidateCount >= 5) {
293
- mongoQueue.invalidateCount = 0;
294
-
295
- mongoQueue.cbs.forEach(cb => {
296
- cb(null, res, false);
297
- });
298
- }
299
-
300
- mongoQueue.cbs = mongoQueue.cbs.concat(mongoQueue.cbs_next);
301
- mongoQueue.cbs_next = [];
302
- }
303
-
304
- mongoQueue.running = false;
305
- }, err => {
306
- monitor.finish();
307
-
308
- console.log(new Date(), 'Error ' + mongoQueue.name_function, mongoQueue.name_collection, ...mongoQueue.data_function, err);
309
-
310
- mongoQueue.cbs.forEach(cb => {
311
- cb(err, null, false);
312
- });
313
-
314
- mongoQueue.cbs_next.forEach(cb => {
315
- cb(err, null, false);
316
- });
317
-
318
- if (this._mongoQueue.map(a => a._id).indexOf(mongoQueue._id) >= 0) {
319
- this._mongoQueue.splice(this._mongoQueue.map(a => a._id).indexOf(mongoQueue._id), 1);
320
- }
321
- });
322
- }
323
- else {
324
- let monitor = new MonitorMongo(mongoQueue.name_function, mongoQueue.name_collection, JSON.stringify([...mongoQueue.data_function, mongoQueue.name_function_addt, ...mongoQueue.data_function_addt]));
325
- ResolveIOServer.getMainDB().collection(mongoQueue.name_collection)[mongoQueue.name_function](...mongoQueue.data_function)[mongoQueue.name_function_addt](...mongoQueue.data_function_addt).then(res => {
326
- monitor.finish();
327
- if (!mongoQueue.invalidateFlag) {
328
- mongoQueue.invalidateCount = 0;
329
-
330
- let stringifyLength = 0;
331
- let stringifyFail = false;
332
-
333
- try {
334
- let stringify = JSON.stringify(res).replace(/[\[\]\,\"]/g,'');
335
- stringifyLength = stringify.length;
336
- }
337
- catch(e) {
338
- stringifyFail = true;
339
- }
340
-
341
- if (!stringifyFail && res !== null && res !== undefined && (!Array.isArray(res) || res.length) && stringifyLength < 10000000) {
342
- mongoQueue.cacheId = this._mongoQueueCacheId;
343
- this._mongoQueueCacheId += 1;
344
- this.addToCache(mongoQueue.cacheId, res);
345
- }
346
- else {
347
- mongoQueue.cacheId = 0;
348
- }
349
-
350
- mongoQueue.cbs.forEach(cb => {
351
- cb(null, res, false);
352
- });
353
-
354
- if (mongoQueue.cbs_next.length) {
355
- mongoQueue.cbs = mongoQueue.cbs_next;
356
- mongoQueue.cbs_next = [];
357
- }
358
- else {
359
- mongoQueue.cbs = [];
360
- }
361
- }
362
- else {
363
- if (mongoQueue.invalidateCount >= 5) {
364
- mongoQueue.invalidateCount = 0;
365
-
366
- mongoQueue.cbs.forEach(cb => {
367
- cb(null, res, false);
368
- });
369
- }
370
-
371
- mongoQueue.cbs = mongoQueue.cbs.concat(mongoQueue.cbs_next);
372
- mongoQueue.cbs_next = [];
373
- }
374
-
375
- mongoQueue.running = false;
376
- }, err => {
377
- monitor.finish();
378
-
379
- mongoQueue.cbs.forEach(cb => {
380
- cb(err, null, false);
381
- });
382
-
383
- mongoQueue.cbs_next.forEach(cb => {
384
- cb(err, null, false);
385
- });
386
-
387
- if (this._mongoQueue.map(a => a._id).indexOf(mongoQueue._id) >= 0) {
388
- this._mongoQueue.splice(this._mongoQueue.map(a => a._id).indexOf(mongoQueue._id), 1);
389
- }
390
- });
391
- }
392
- }
393
- }
394
-
395
- this._mongoQueueRunning = false;
396
- }
397
- }
398
- }, 25);
399
- }
400
-
401
- private addToCache(id, data) {
402
- let nodeCacheSize = this._nodeCache.getStats().vsize;
403
-
404
- if (nodeCacheSize > this._heapLimit) {
405
- let deleteCount = 0;
406
-
407
- const queueArr = this._mongoQueue.filter(a => a.cacheId && !a.running && !a.cbs.length);
408
-
409
- for (let zz = queueArr.length - 1; zz >= 0; zz--) {
410
- this._debugRemoveCacheHits += 1;
411
-
412
- let queue = queueArr[zz];
413
-
414
- this._nodeCache.del(queue.cacheId);
415
- queue.cacheId = 0;
416
-
417
- if (this._mongoQueue.map(a => a._id).indexOf(queue._id) >= 0) {
418
- this._mongoQueue.splice(this._mongoQueue.map(a => a._id).indexOf(queue._id), 1);
419
- }
420
-
421
- deleteCount += 1;
422
-
423
- nodeCacheSize = this._nodeCache.getStats().vsize;
424
-
425
- if (nodeCacheSize < this._heapLimit * 0.75) {
426
- break;
427
- }
428
- }
429
-
430
- console.log('Query Cache: ' + 'Too Big, - Deleted: ' + deleteCount + ' - ' + nodeCacheSize);
431
- }
432
-
433
- this._nodeCache.set(id, JSON.stringify(data));
434
- }
435
-
436
- public invalidateQueryCache(collection: string) {
437
- let queueArr = this._mongoQueue.filter(a => (a.name_collection === collection || a.lookup_collections.includes(collection)));
438
- for (let i = queueArr.length - 1; i >= 0; i--) {
439
- let queue = queueArr[i];
440
- if (queue.cacheId) {
441
- this._nodeCache.del(queue.cacheId);
442
- queue.cacheId = 0;
443
- }
444
-
445
- if (queue.running) {
446
- queue.invalidateFlag = true;
447
- queue.invalidateCount += 1;
448
- }
449
- else if (!queue.cbs.length) {
450
- if (this._mongoQueue.map(a => a._id).indexOf(queue._id) >= 0) {
451
- this._mongoQueue.splice(this._mongoQueue.map(a => a._id).indexOf(queue._id), 1);
452
- }
453
- }
454
- }
455
- }
456
- }
457
-
458
- export class MongoManagerModel<T extends CollectionDocument> {
459
- collection_main: MongoManagerCollection<T> | MongoManagerUserCollection<T> = null;
460
- collection_version: MongoManagerCollection<T> | MongoManagerUserCollection<T> = null;
461
-
462
- constructor(options: MongoManagerCollectionOptions) {
463
- if (options.collectionName === 'users') {
464
- this.collection_main = new MongoManagerUserCollection<T>(options);
465
- }
466
- else {
467
- this.collection_main = new MongoManagerCollection<T>(options);
468
- }
469
-
470
- if (options.useVersionCollection) {
471
- this.collection_main.useVersions = true;
472
-
473
- let versionSchema = deepCopy(options.schema);
474
- versionSchema._id.type = 'Object';
475
- versionSchema._id.blackbox = true;
476
-
477
- let versionOptions: MongoManagerCollectionOptions = {
478
- collectionName: options.collectionName + '.versions',
479
- schema: versionSchema,
480
- useVersionCollection: false,
481
- useReportBuilder: false,
482
- reportBuilderLookupTables: [],
483
- timestamps: true,
484
- createLogs: false,
485
- checkSchema: false,
486
- collectionOptions: null
487
- };
488
-
489
- if (options.collectionName === 'users') {
490
- this.collection_version = new MongoManagerUserCollection<T>(versionOptions);
491
- }
492
- else {
493
- this.collection_version = new MongoManagerCollection<T>(versionOptions);
494
- }
495
-
496
- this.collection_version.createIndex({'_id._id': 1, '_id.__v': 1});
497
- this.collection_main.versionCollection = options.collectionName + '.versions';
498
- }
499
- }
500
- }
501
-
502
- export interface MongoManagerCollectionOptions {
503
- collectionName: string;
504
- schema: object;
505
- useVersionCollection: boolean;
506
- useReportBuilder: boolean;
507
- reportBuilderLookupTables: LookupTables[]
508
- timestamps: boolean;
509
- createLogs: boolean;
510
- checkSchema: boolean;
511
- collectionOptions: CreateCollectionOptions;
512
- }
513
-
514
- export class MongoManagerCollection<T extends CollectionDocument> {
515
- collectionName = '';
516
- checkSchema = false;
517
- simplschema = null;
518
- rbSchema = null;
519
- timestamps = false;
520
- useVersions = false;
521
- versionCollection = '';
522
- createLogs = true;
523
- useRB = false;
524
- collectionOptions: CreateCollectionOptions;
525
-
526
- constructor(options: MongoManagerCollectionOptions) {
527
- this.collectionName = options.collectionName;
528
- this.simplschema = new SimpleSchema(options.schema);
529
- this.timestamps = options.timestamps;
530
- this.createLogs = options.createLogs;
531
- this.checkSchema = options.checkSchema;
532
- this.collectionOptions = options.collectionOptions;
533
-
534
- if (options.useReportBuilder) {
535
- this.useRB = true;
536
- let schemaCopy = deepCopy(options.schema);
537
- let rbSchema = buildRbLookups(options.reportBuilderLookupTables, schemaCopy, []);
538
- this.rbSchema = buildRbSchema(rbSchema);
539
- }
540
-
541
- let interval = setInterval(() => {
542
- if (ResolveIOServer && ResolveIOServer.getMainServer() && ResolveIOServer.getMongoManager() && ResolveIOServer.getMongoManager().getServerCollections().length) {
543
- ResolveIOServer.getMongoManager().registerCollection(this);
544
- clearInterval(interval);
545
- }
546
- }, 1);
547
- }
548
-
549
- aggregate(pipeline: object[], options?: AggregateOptions, skipCache = false) : Promise<any[]> {
550
- return new Promise((resolve, reject) => {
551
- // if (!skipCache) {
552
- // ResolveIOServer.getMongoManager().addToQueue({
553
- // _id: 0,
554
- // name_collection: this.collectionName,
555
- // name_function: 'aggregate',
556
- // name_function_addt: 'toArray',
557
- // data_function: [pipeline, options],
558
- // data_function_addt: [],
559
- // cbs: [(err, res, cached) => {
560
- // if (err) {
561
- // reject(err);
562
- // }
563
- // else {
564
- // resolve(res);
565
- // }
566
- // }],
567
- // cbs_next: [],
568
- // running: false,
569
- // cacheId: 0,
570
- // lookup_collections: pipeline.filter(a => a['$lookup'] && a['$lookup'].from).map(a => a['$lookup'].from).filter((elem, index, self) => {
571
- // return index === self.indexOf(elem);
572
- // }),
573
- // invalidateFlag: false,
574
- // invalidateCount: 0
575
- // });
576
- // }
577
- // else {
578
- // let monitor = new MonitorMongo('aggregate', this.collectionName, JSON.stringify([pipeline, options]));
579
- // ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).aggregate(pipeline, options).toArray().then(res => {
580
- // monitor.finish();
581
- // resolve(res);
582
- // }, err => {
583
- // monitor.finish();
584
- // console.log(new Date(), 'Error Aggregate', this.collectionName, pipeline, options, err);
585
- // reject(err);
586
- // });
587
- // }
588
-
589
- let monitor = new MonitorMongo('aggregate', this.collectionName, JSON.stringify([pipeline, options]));
590
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).aggregate(pipeline, options).toArray().then(res => {
591
- monitor.finish();
592
- resolve(res);
593
- }, err => {
594
- monitor.finish();
595
- console.log(new Date(), 'Error Aggregate', this.collectionName, pipeline, options, err);
596
- reject(err);
597
- });
598
- });
599
- }
600
-
601
- aggregateCount(pipeline: object[], options?: AggregateOptions) : Promise<number> {
602
- return new Promise((resolve, reject) => {
603
- ResolveIOServer.getMongoManager().addToQueue({
604
- _id: 0,
605
- name_collection: this.collectionName,
606
- name_function: 'aggregate',
607
- name_function_addt: 'count',
608
- data_function: [pipeline, options],
609
- data_function_addt: [],
610
- cbs: [(err, res, cached) => {
611
- if (err) {
612
- reject(err);
613
- }
614
- else {
615
- resolve(res);
616
- }
617
- }],
618
- cbs_next: [],
619
- running: false,
620
- cacheId: 0,
621
- lookup_collections: pipeline.filter(a => a['$lookup'] && a['$lookup'].from).map(a => a['$lookup'].from).filter((elem, index, self) => {
622
- return index === self.indexOf(elem);
623
- }),
624
- invalidateFlag: false,
625
- invalidateCount: 0
626
- });
627
- });
628
- }
629
-
630
- aggregateCursor(pipeline: object[], options?: AggregateOptions): AggregationCursor {
631
- let monitor = new MonitorMongo('aggregateCursor', this.collectionName, JSON.stringify([pipeline, options]));
632
- let cursor = ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).aggregate(pipeline, options);
633
- cursor.on('close', ev => {
634
- monitor.finish();
635
- return ev;
636
- });
637
-
638
- return cursor;
639
- }
640
-
641
- aggregateStream(pipeline: object[], options?: AggregateOptions, streamOptions?: CursorStreamOptions) {
642
- let monitor = new MonitorMongo('aggregateStream', this.collectionName, JSON.stringify([pipeline, options, streamOptions]));
643
- let stream = ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).aggregate(pipeline, options).stream(streamOptions);
644
- stream.on('end', ev => {
645
- monitor.finish();
646
- return ev;
647
- });
648
-
649
- return stream;
650
- }
651
-
652
- // bulkWrite(operations: AnyBulkWriteOperation<T>[], options: BulkWriteOptions): Promise<BulkWriteResult> {
653
- bulkWrite(operations: any[], options?: BulkWriteOptions): Promise<BulkWriteResult> {
654
- return new Promise((resolve, reject) => {
655
- let monitor = new MonitorMongo('bulkWrite', this.collectionName, JSON.stringify([operations.slice(-100), options]));
656
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).bulkWrite(operations, options).then(res => {
657
- monitor.finish();
658
- resolve(res);
659
- }, err => {
660
- monitor.finish();
661
- console.log(new Date(), 'Error Bulk Write', this.collectionName, operations.slice(-100), options, err);
662
- reject(err);
663
- });
664
- });
665
- }
666
-
667
- countDocuments(filter: MongoManagerFilter<T> & MongoManagerFilterOperators<T> = {}, options?: CountDocumentsOptions): Promise<number> {
668
- return new Promise((resolve, reject) => {
669
- let monitor = new MonitorMongo('countDocuments', this.collectionName, JSON.stringify([filter, options]));
670
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).countDocuments(<any>filter, options).then(res => {
671
- monitor.finish();
672
- resolve(res);
673
- }, err => {
674
- monitor.finish();
675
- console.log(new Date(), 'Error Count Documents', this.collectionName, filter, options, err);
676
- reject(err);
677
- });
678
- });
679
- }
680
-
681
- //Helper Function (1 or Many) - Not Real Mongo Function
682
- create(f_docs: T | T[], options?: InsertOneOptions | BulkWriteOptions): Promise<T | T[]> {
683
- if (!Array.isArray(f_docs)) {
684
- return this.insertOne(f_docs, <InsertOneOptions>options);
685
- }
686
- else if (f_docs.length === 1) {
687
- return this.insertOne(f_docs[0], <InsertOneOptions>options);
688
- }
689
-
690
- return this.insertMany(f_docs, <BulkWriteOptions>options);
691
- }
692
-
693
- createIndex(fieldOrSpec: any, options?: CreateIndexesOptions): Promise<string> {
694
- return new Promise((resolve, reject) => {
695
- if (ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions)) {
696
- let monitor = new MonitorMongo('createIndex', this.collectionName, JSON.stringify([fieldOrSpec, options]));
697
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).createIndex(fieldOrSpec, options).then(res => {
698
- monitor.finish();
699
- resolve(res);
700
- }, err => {
701
- monitor.finish();
702
- console.log(new Date(), 'Error Setting Up Index for Collection', this.collectionName, fieldOrSpec, options, err);
703
- reject(err);
704
- });
705
- }
706
- });
707
- }
708
-
709
- createIndexes(indexSpecs: IndexDescription[], options?: CreateIndexesOptions): Promise<string[]> {
710
- return new Promise((resolve, reject) => {
711
- if (ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions)) {
712
- let monitor = new MonitorMongo('createIndexes', this.collectionName, JSON.stringify([indexSpecs, options]));
713
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).createIndexes(indexSpecs, options).then(res => {
714
- monitor.finish();
715
- resolve(res);
716
- }, err => {
717
- monitor.finish();
718
- console.log(new Date(), 'Error Setting Up Indexes for Collection', this.collectionName, indexSpecs, options, err);
719
- reject(err);
720
- });
721
- }
722
- });
723
- }
724
-
725
- deleteMany(filter: MongoManagerFilter<T> & MongoManagerFilterOperators<T> = {}, options?: DeleteOptions, bypassLogs = false): Promise<number> {
726
- return new Promise(async (resolve, reject) => {
727
- if (this.createLogs && !bypassLogs) {
728
- let docs = await this.find(filter);
729
-
730
- for (let i = 0; i < docs.length; i++) {
731
- let doc = docs[i];
732
-
733
- Logs.insertOne({
734
- _id: objectIdHexString(),
735
- type: 'document',
736
- collection: this.collectionName,
737
- id_document: doc._id,
738
- payload: getBinarySize(JSON.stringify([doc, filter, options])) < 200000 ? JSON.stringify([doc, filter, options], null, 2) : 'Too Big',
739
- method: 'deleteMany',
740
- id_user: '',
741
- user: '',
742
- messageId: 0,
743
- route: ''
744
- });
745
-
746
- if (this.useVersions) {
747
- let versionDoc = deepCopy(doc);
748
- versionDoc._id = {_id: doc._id, __v: doc.__v};
749
-
750
- ResolveIOServer.getMongoManager().collection(this.versionCollection).replaceOne(<any>{_id: { _id: doc._id, __v: doc.__v}}, versionDoc, {upsert: true});
751
- ResolveIOServer.getMongoManager().collection(this.versionCollection).deleteMany(<any>{$and: [{'_id._id': doc._id}, {'_id.__v': {$lt: doc.__v - 1}}]});
752
- }
753
- }
754
- }
755
-
756
- let monitor = new MonitorMongo('deleteMany', this.collectionName, JSON.stringify([filter, options]));
757
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).deleteMany(<any>filter, options).then(res => {
758
- monitor.finish();
759
- if (res.acknowledged) {
760
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
761
- resolve(res.deletedCount);
762
- }
763
- else {
764
- reject(res.acknowledged);
765
- }
766
- }, err => {
767
- monitor.finish();
768
- console.log(new Date(), 'Error Delete Many', this.collectionName, filter, options, err);
769
- reject(err)
770
- });
771
- });
772
- }
773
-
774
- deleteOne(filter: MongoManagerFilter<T> & MongoManagerFilterOperators<T> = {}, options?: FindOneAndDeleteOptions, bypassLogs = false): Promise<number> {
775
- return new Promise(async (resolve, reject) => {
776
- if (this.createLogs && !bypassLogs) {
777
- let monitor = new MonitorMongo('findOneAndDelete', this.collectionName, JSON.stringify([filter, options]));
778
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).findOneAndDelete(<any>filter, options).then(async returnVal => {
779
- monitor.finish();
780
- let doc = returnVal.value;
781
-
782
- if (doc) {
783
- if (this.createLogs && !bypassLogs) {
784
- Logs.insertOne({
785
- _id: objectIdHexString(),
786
- type: 'document',
787
- collection: this.collectionName,
788
- id_document: doc._id,
789
- payload: getBinarySize(JSON.stringify([doc, filter, options])) < 200000 ? JSON.stringify([doc, filter, options], null, 2) : 'Too Big',
790
- method: 'deleteOne',
791
- id_user: '',
792
- user: '',
793
- messageId: 0,
794
- route: ''
795
- });
796
- }
797
-
798
- if (this.useVersions) {
799
- let versionDoc = deepCopy(doc);
800
- versionDoc._id = {_id: doc._id, __v: doc.__v};
801
-
802
- ResolveIOServer.getMongoManager().collection(this.versionCollection).replaceOne(<any>{_id: { _id: doc._id, __v: doc.__v}}, versionDoc, {upsert: true});
803
- ResolveIOServer.getMongoManager().collection(this.versionCollection).deleteMany(<any>{$and: [{'_id._id': doc._id}, {'_id.__v': {$lt: doc.__v - 1}}]});
804
- }
805
-
806
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
807
-
808
- resolve(1);
809
- }
810
- else {
811
- resolve(0);
812
- }
813
- }, err => {
814
- monitor.finish();
815
- console.log(new Date(), 'Error Find One And Delete', this.collectionName, filter, options, err);
816
- reject(err);
817
- });
818
- }
819
- else {
820
- let monitor = new MonitorMongo('deleteOne', this.collectionName, JSON.stringify([filter, options]));
821
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).deleteOne(<any>filter, options).then(res => {
822
- monitor.finish();
823
- if (res.acknowledged) {
824
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
825
- resolve(res.deletedCount);
826
- }
827
- else {
828
- reject(res.acknowledged);
829
- }
830
- }, err => {
831
- monitor.finish();
832
- console.log(new Date(), 'Error Delete One', this.collectionName, filter, options, err);
833
- reject(err);
834
- });
835
- }
836
- });
837
- }
838
-
839
- distinct(key: string, filter?: MongoManagerFilter<T> & MongoManagerFilterOperators<T>, options?: CommandOperationOptions): Promise<T[]> {
840
- return new Promise((resolve, reject) => {
841
- let monitor = new MonitorMongo('distinct', this.collectionName, JSON.stringify([key, filter, options]));
842
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).distinct(key, <any>filter, options).then(res => {
843
- monitor.finish();
844
- resolve(res);
845
- }, err => {
846
- monitor.finish();
847
- console.log(new Date(), 'Error Distinct', this.collectionName, filter, options, err);
848
- reject(err);
849
- });
850
- });
851
- }
852
-
853
- drop(options?: CommandOperationOptions): Promise<boolean> {
854
- return new Promise((resolve, reject) => {
855
- let monitor = new MonitorMongo('drop', this.collectionName, JSON.stringify([options]));
856
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).drop(options).then(res => {
857
- monitor.finish();
858
- resolve(res);
859
- }, err => {
860
- monitor.finish();
861
- console.log(new Date(), 'Error Count Documents', this.collectionName, options, err);
862
- reject(err);
863
- });
864
- });
865
- }
866
-
867
- dropIndex(indexName: string, options?: CommandOperationOptions): Promise<Document> {
868
- return new Promise((resolve, reject) => {
869
- let monitor = new MonitorMongo('dropIndex', this.collectionName, JSON.stringify([indexName, options]));
870
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).dropIndex(indexName, options).then(res => {
871
- monitor.finish();
872
- resolve(<Document>res);
873
- }, err => {
874
- monitor.finish();
875
- console.log(new Date(), 'Error Drop Index', this.collectionName, indexName, options, err);
876
- reject(err);
877
- });
878
- });
879
- }
880
-
881
- dropIndexes(options?: CommandOperationOptions): Promise<Document> {
882
- return new Promise((resolve, reject) => {
883
- let monitor = new MonitorMongo('dropIndexes', this.collectionName, JSON.stringify([options]));
884
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).dropIndexes(options).then(res => {
885
- monitor.finish();
886
- resolve(<Document>res);
887
- }, err => {
888
- monitor.finish();
889
- console.log(new Date(), 'Error Drop Indexes', this.collectionName, options, err);
890
- reject(err);
891
- });
892
- });
893
- }
894
-
895
- find(filter: MongoManagerFilter<T> & MongoManagerFilterOperators<T> = {}, options?: FindOptions<T>, skipCache = false): Promise<T[]> {
896
- return new Promise(async (resolve, reject) => {
897
- if (!skipCache) {
898
- ResolveIOServer.getMongoManager().addToQueue({
899
- _id: 0,
900
- name_collection: this.collectionName,
901
- name_function: 'find',
902
- name_function_addt: 'toArray',
903
- data_function: [filter, options],
904
- data_function_addt: [],
905
- cbs: [(err, res, cached) => {
906
- if (err) {
907
- reject(err);
908
- }
909
- else {
910
- resolve(res);
911
- }
912
- }],
913
- cbs_next: [],
914
- running: false,
915
- cacheId: 0,
916
- lookup_collections: [],
917
- invalidateFlag: false,
918
- invalidateCount: 0
919
- });
920
- }
921
- else {
922
- let monitor = new MonitorMongo('find', this.collectionName, JSON.stringify([filter, options]));
923
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).find<T>(<any>filter, options).toArray().then(res => {
924
- monitor.finish();
925
- resolve(res);
926
- }, err => {
927
- monitor.finish();
928
- console.log(new Date(), 'Error Find', this.collectionName, filter, options, err);
929
- reject(err);
930
- });
931
- }
932
- });
933
- }
934
-
935
- findById(id: string, options?: FindOptions<T>): Promise<T> {
936
- return new Promise((resolve, reject) => {
937
- let monitor = new MonitorMongo('findById', this.collectionName, JSON.stringify([{_id: id}, options]));
938
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).findOne<T>(<any>{_id: id}, options).then(res => {
939
- monitor.finish();
940
- resolve(res);
941
- }, err => {
942
- monitor.finish();
943
- console.log(new Date(), 'Error Find By Id', this.collectionName, {_id: id}, options, err);
944
- reject(err);
945
- });
946
- });
947
- }
948
-
949
- findCount(filter: MongoManagerFilter<T> & MongoManagerFilterOperators<T> = {}, options?: FindOptions<T>): Promise<Number> {
950
- return new Promise((resolve, reject) => {
951
- let monitor = new MonitorMongo('findCount', this.collectionName, JSON.stringify([filter, options]));
952
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).find(<any>filter, options).count().then(res => {
953
- monitor.finish();
954
- resolve(res);
955
- }, err => {
956
- monitor.finish();
957
- console.log(new Date(), 'Error Find Count', this.collectionName, filter, options, err);
958
- reject(err);
959
- });
960
- });
961
- }
962
-
963
- findCursor(filter: MongoManagerFilter<T> & MongoManagerFilterOperators<T> = {}, options?: FindOptions<T>): FindCursor {
964
- let monitor = new MonitorMongo('findCursor', this.collectionName, JSON.stringify([filter, options]));
965
- let cursor = ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).find(<any>filter, options);
966
- cursor.on('close', ev => {
967
- monitor.finish();
968
- return ev;
969
- });
970
- return cursor;
971
- }
972
-
973
- findStream(filter: MongoManagerFilter<T> & MongoManagerFilterOperators<T> = {}, options?: FindOptions<T>, streamOptions?: CursorStreamOptions) {
974
- let monitor = new MonitorMongo('findStream', this.collectionName, JSON.stringify([filter, options, streamOptions]));
975
- let stream = ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).find(<any>filter, options).stream(streamOptions);
976
- stream.on('end', ev => {
977
- monitor.finish();
978
- return ev;
979
- });
980
- return stream;
981
- }
982
-
983
- findOne(filter: MongoManagerFilter<T> | MongoManagerFilterOperators<T> = {}, options?: FindOptions<T>, skipCache = false): Promise<T> {
984
- return new Promise((resolve, reject) => {
985
- if (!skipCache) {
986
- ResolveIOServer.getMongoManager().addToQueue({
987
- _id: 0,
988
- name_collection: this.collectionName,
989
- name_function: 'findOne',
990
- name_function_addt: '',
991
- data_function: [filter, options],
992
- data_function_addt: [],
993
- cbs: [(err, res, cached) => {
994
- if (err) {
995
- reject(err);
996
- }
997
- else {
998
- resolve(res);
999
- }
1000
- }],
1001
- cbs_next: [],
1002
- running: false,
1003
- cacheId: 0,
1004
- lookup_collections: [],
1005
- invalidateFlag: false,
1006
- invalidateCount: 0
1007
- });
1008
- }
1009
- else {
1010
- let monitor = new MonitorMongo('findOne', this.collectionName, JSON.stringify([filter, options]));
1011
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).findOne<T>(<any>filter, options).then(res => {
1012
- monitor.finish();
1013
- resolve(res);
1014
- }, err => {
1015
- monitor.finish();
1016
- console.log(new Date(), 'Error Find One', this.collectionName, filter, options, err);
1017
- reject(err)
1018
- });
1019
- }
1020
- });
1021
- }
1022
-
1023
- findOneAndDelete(filter: MongoManagerFilter<T> & MongoManagerFilterOperators<T> = {}, options?: FindOneAndDeleteOptions, bypassLogs = false): Promise<T> {
1024
- return new Promise(async (resolve, reject) => {
1025
- let monitor = new MonitorMongo('findOneAndDelete', this.collectionName, JSON.stringify([filter, options]));
1026
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).findOneAndDelete(<any>filter, options).then(res => {
1027
- monitor.finish();
1028
- let doc = res.value;
1029
-
1030
- if (doc) {
1031
- if (this.createLogs && !bypassLogs) {
1032
- Logs.insertOne({
1033
- _id: objectIdHexString(),
1034
- type: 'document',
1035
- collection: this.collectionName,
1036
- id_document: doc._id,
1037
- payload: getBinarySize(JSON.stringify([doc, filter, options])) < 200000 ? JSON.stringify([doc, filter, options], null, 2) : 'Too Big',
1038
- method: 'findOneAndDelete',
1039
- id_user: '',
1040
- user: '',
1041
- messageId: 0,
1042
- route: ''
1043
- });
1044
- }
1045
-
1046
- if (this.useVersions) {
1047
- let versionDoc = deepCopy(doc);
1048
- versionDoc._id = {_id: doc._id, __v: doc.__v};
1049
-
1050
- ResolveIOServer.getMongoManager().collection(this.versionCollection).replaceOne(<any>{_id: { _id: doc._id, __v: doc.__v}}, versionDoc, {upsert: true});
1051
- }
1052
-
1053
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
1054
-
1055
- resolve(<T>doc);
1056
- }
1057
- else {
1058
- resolve(null);
1059
- }
1060
- }, err => {
1061
- monitor.finish();
1062
- console.log(new Date(), 'Error Find One And Delete', this.collectionName, filter, options, err);
1063
- reject(err)
1064
- });
1065
- });
1066
- }
1067
-
1068
- findOneAndReplace(filter: MongoManagerFilter<T> & MongoManagerFilterOperators<T> = {}, replacement: T, options?: FindOneAndReplaceOptions, bypassLogs = false, bypassCheckSchema = false): Promise<T> {
1069
- return new Promise(async (resolve, reject) => {
1070
- if (this.checkSchema && !bypassCheckSchema) {
1071
- const validation = this.simplschema.newContext();
1072
- const isValid = validation.validate(replacement);
1073
-
1074
- if (!isValid) {
1075
- console.log(new Date(), this.collectionName, 'Schema Errors - findOneAndReplace', validation.validationErrors());
1076
- ResolveIOServer.getMainServer().getMethodManager().callMethodInternal.call(ResolveIOServer.getMainServer().getMethodManager(), 'insertErrorLog', 'Schema Failed on findOneAndReplace - ' + this.collectionName, [validation.validationErrors(), replacement]);
1077
-
1078
- reject(validation.validationErrors());
1079
- return;
1080
- }
1081
- }
1082
-
1083
- let date = new Date();
1084
-
1085
- if (this.timestamps) {
1086
- replacement.updatedAt = date;
1087
- }
1088
-
1089
- if (options && options.upsert) {
1090
- if (!replacement._id) {
1091
- replacement._id = objectIdHexString();
1092
- }
1093
-
1094
- if (this.useVersions) {
1095
- replacement.__v = 0;
1096
- }
1097
-
1098
- if (this.timestamps && !replacement.createdAt) {
1099
- replacement.createdAt = date;
1100
- }
1101
- }
1102
-
1103
- let monitor = new MonitorMongo('findOneAndReplace', this.collectionName, JSON.stringify([filter, replacement, options]));
1104
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).findOneAndReplace(<any>filter, replacement, options).then(res => {
1105
- monitor.finish();
1106
- let doc = res.value
1107
-
1108
- if (doc) {
1109
- if (this.createLogs && !bypassLogs) {
1110
- Logs.insertOne({
1111
- _id: objectIdHexString(),
1112
- type: 'document',
1113
- collection: this.collectionName,
1114
- id_document: doc._id,
1115
- payload: getBinarySize(JSON.stringify([doc, filter, replacement, options])) < 200000 ? JSON.stringify([doc, filter, replacement, options], null, 2) : 'Too Big',
1116
- method: 'findOneAndReplace',
1117
- id_user: '',
1118
- user: '',
1119
- messageId: 0,
1120
- route: ''
1121
- });
1122
- }
1123
-
1124
- if (this.useVersions) {
1125
- let versionDoc = deepCopy(doc);
1126
- versionDoc._id = {_id: doc._id, __v: doc.__v};
1127
-
1128
- ResolveIOServer.getMongoManager().collection(this.versionCollection).replaceOne(<any>{_id: { _id: doc._id, __v: doc.__v}}, versionDoc, {upsert: true});
1129
- }
1130
-
1131
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
1132
-
1133
- resolve(<T>doc);
1134
- }
1135
- else {
1136
- resolve(null);
1137
- }
1138
- }, err => {
1139
- monitor.finish();
1140
- console.log(new Date(), 'Error Find One And Replace', this.collectionName, filter, options, err);
1141
- reject(err)
1142
- });
1143
- });
1144
- }
1145
-
1146
- findOneAndUpdate(filter: MongoManagerFilter<T> & MongoManagerFilterOperators<T> = {}, update: MongoManagerUpdateFilter<T>, options?: FindOneAndUpdateOptions, bypassLogs = false, bypassCheckSchema = false): Promise<T> {
1147
- return new Promise(async (resolve, reject) => {
1148
- if (this.checkSchema && !bypassCheckSchema) {
1149
- const validation = this.simplschema.newContext();
1150
- const isValid = validation.validate(update, {modifier: true});
1151
-
1152
- if (!isValid) {
1153
- console.log(new Date(), this.collectionName, 'Schema Errors - findOneAndUpdate', validation.validationErrors());
1154
- ResolveIOServer.getMainServer().getMethodManager().callMethodInternal.call(ResolveIOServer.getMainServer().getMethodManager(), 'insertErrorLog', 'Schema Failed on findOneAndUpdate - ' + this.collectionName, [validation.validationErrors(), update]);
1155
- reject(validation.validationErrors());
1156
- return;
1157
- }
1158
- }
1159
-
1160
- if (this.timestamps) {
1161
- let date = new Date();
1162
-
1163
- if (!update.$set) {
1164
- update.$set = <any>{updatedAt: date};
1165
- }
1166
- else {
1167
- update.$set.updatedAt = date;
1168
- }
1169
- }
1170
-
1171
- if (options && options.upsert) {
1172
- if (!update.$setOnInsert) {
1173
- if (this.timestamps) {
1174
- update.$setOnInsert = <any>{
1175
- _id: objectIdHexString(),
1176
- createdAt: new Date()
1177
- };
1178
- }
1179
- else {
1180
- update.$setOnInsert = <any>{
1181
- _id: objectIdHexString()
1182
- };
1183
- }
1184
- }
1185
- else {
1186
- if (!update.$setOnInsert._id) {
1187
- update.$setOnInsert._id = objectIdHexString();
1188
- }
1189
-
1190
- if (this.timestamps) {
1191
- update.$setOnInsert.createdAt = new Date();
1192
- }
1193
- }
1194
- }
1195
-
1196
- let monitor = new MonitorMongo('findOneAndUpdate', this.collectionName, JSON.stringify([filter, update, options]));
1197
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).findOneAndUpdate(<any>filter, <any>update, options).then(res => {
1198
- monitor.finish();
1199
- let doc = res.value;
1200
-
1201
- if (doc) {
1202
- if (this.createLogs && !bypassLogs) {
1203
- Logs.insertOne({
1204
- _id: objectIdHexString(),
1205
- type: 'document',
1206
- collection: this.collectionName,
1207
- id_document: doc._id,
1208
- payload: getBinarySize(JSON.stringify([doc, filter, update, options])) < 200000 ? JSON.stringify([doc, filter, update, options], null, 2) : 'Too Big',
1209
- method: 'findOneAndUpdate',
1210
- id_user: '',
1211
- user: '',
1212
- messageId: 0,
1213
- route: ''
1214
- });
1215
- }
1216
-
1217
- if (this.useVersions) {
1218
- let versionDoc = deepCopy(doc);
1219
- versionDoc._id = {_id: doc._id, __v: doc.__v};
1220
-
1221
- ResolveIOServer.getMongoManager().collection(this.versionCollection).replaceOne(<any>{_id: { _id: doc._id, __v: doc.__v}}, versionDoc, {upsert: true});
1222
- }
1223
-
1224
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
1225
-
1226
- resolve(<T>doc);
1227
- }
1228
- else {
1229
- resolve(null);
1230
- }
1231
- }, err => {
1232
- monitor.finish();
1233
- console.log(new Date(), 'Error Find One And Update', this.collectionName, filter, options, err);
1234
- reject(err);
1235
- });
1236
- });
1237
- }
1238
-
1239
- indexes(options: IndexInformationOptions): Promise<any[]> {
1240
- return new Promise((resolve, reject) => {
1241
- let monitor = new MonitorMongo('indexes', this.collectionName, JSON.stringify([options]));
1242
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).indexes(options).then(res => {
1243
- monitor.finish();
1244
- resolve(res);
1245
- }, err => {
1246
- monitor.finish();
1247
- console.log(new Date(), 'Error Indexes', this.collectionName, options, err);
1248
- reject(err);
1249
- });
1250
- });
1251
- }
1252
-
1253
- indexExists(indexes: string | string[], options?: IndexInformationOptions): Promise<boolean> {
1254
- return new Promise((resolve, reject) => {
1255
- let monitor = new MonitorMongo('indexExists', this.collectionName, JSON.stringify([indexes, options]));
1256
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).indexExists(indexes, options).then(res => {
1257
- monitor.finish();
1258
- resolve(res);
1259
- }, err => {
1260
- monitor.finish();
1261
- console.log(new Date(), 'Error Index Exists', this.collectionName, indexes, options, err);
1262
- reject(err);
1263
- });
1264
- });
1265
- }
1266
-
1267
- insertMany(docs: T[], options?: BulkWriteOptions, bypassLogs = false, bypassCheckSchema = false, bypassMonitor = false): Promise<T[]> {
1268
- return new Promise(async (resolve, reject) => {
1269
- if (!docs.length) {
1270
- resolve([]);
1271
- return;
1272
- }
1273
-
1274
- let validationResults = [];
1275
-
1276
- if (this.checkSchema && !bypassCheckSchema) {
1277
- docs.forEach(doc => {
1278
- const validation = this.simplschema.newContext();
1279
- const isValid = validation.validate(doc);
1280
-
1281
- if (!isValid) {
1282
- console.log(new Date(), this.collectionName, 'Schema Errors - insertMany', validation.validationErrors());
1283
- ResolveIOServer.getMainServer().getMethodManager().callMethodInternal.call(ResolveIOServer.getMainServer().getMethodManager(), 'insertErrorLog', 'Schema Failed on insertMany - ' + this.collectionName, [validation.validationErrors(), doc]);
1284
- validationResults.push(false);
1285
- }
1286
- else {
1287
- validationResults.push(true);
1288
- }
1289
- });
1290
- }
1291
-
1292
- let validDocs = this.checkSchema ? docs.filter((a, idx) => validationResults[idx]) : docs;
1293
-
1294
- for (let i = 0; i < validDocs.length; i++) {
1295
- let doc = validDocs[i];
1296
-
1297
- if (!doc._id) {
1298
- doc._id = objectIdHexString();
1299
- }
1300
-
1301
- if (this.timestamps) {
1302
- let date = new Date();
1303
- doc.createdAt = date;
1304
- doc.updatedAt = date;
1305
- }
1306
-
1307
- if (this.createLogs && !bypassLogs) {
1308
- Logs.insertOne({
1309
- _id: objectIdHexString(),
1310
- type: 'document',
1311
- collection: this.collectionName,
1312
- id_document: doc._id,
1313
- payload: getBinarySize(JSON.stringify([doc, options])) < 200000 ? JSON.stringify([doc, options], null, 2) : 'Too Big',
1314
- method: 'insertMany',
1315
- id_user: '',
1316
- user: '',
1317
- messageId: 0,
1318
- route: ''
1319
- });
1320
- }
1321
- }
1322
-
1323
- if (validDocs.length) {
1324
- let monitor = null;
1325
-
1326
- if (!bypassMonitor) {
1327
- monitor = new MonitorMongo('insertMany', this.collectionName, JSON.stringify([validDocs, options]));
1328
- }
1329
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).insertMany(<OptionalUnlessRequiredId<T>[]>validDocs, options).then(res => {
1330
- if (monitor) {
1331
- monitor.finish();
1332
- }
1333
- if (res.acknowledged) {
1334
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
1335
- resolve(validDocs);
1336
- }
1337
- else {
1338
- reject(res.acknowledged);
1339
- }
1340
- }, err => {
1341
- if (monitor) {
1342
- monitor.finish();
1343
- }
1344
- console.log(new Date(), 'Error Insert Many', this.collectionName, validDocs, options, err);
1345
- reject(err);
1346
- });
1347
- }
1348
- });
1349
- }
1350
-
1351
- insertOne(doc: T, options?: InsertOneOptions, bypassLogs = false, bypassCheckSchema = false): Promise<T> {
1352
- return new Promise(async (resolve, reject) => {
1353
- if (!doc._id) {
1354
- doc._id = objectIdHexString();
1355
- }
1356
-
1357
- if (this.checkSchema && !bypassCheckSchema) {
1358
- const validation = this.simplschema.newContext();
1359
- const isValid = validation.validate(doc);
1360
-
1361
- if (!isValid) {
1362
- console.log(new Date(), this.collectionName, 'Schema Errors - insertOne', validation.validationErrors());
1363
- ResolveIOServer.getMainServer().getMethodManager().callMethodInternal.call(ResolveIOServer.getMainServer().getMethodManager(), 'insertErrorLog', 'Schema Failed on insertOne - ' + this.collectionName, [validation.validationErrors(), doc]);
1364
- reject(validation.validationErrors());
1365
- return;
1366
- }
1367
- }
1368
-
1369
- if (this.timestamps) {
1370
- let date = new Date();
1371
- doc.createdAt = date;
1372
- doc.updatedAt = date;
1373
- }
1374
-
1375
- if (this.createLogs && !bypassLogs) {
1376
- Logs.insertOne({
1377
- _id: objectIdHexString(),
1378
- type: 'document',
1379
- collection: this.collectionName,
1380
- id_document: doc._id,
1381
- payload: getBinarySize(JSON.stringify([doc, options])) < 200000 ? JSON.stringify([doc, options], null, 2) : 'Too Big',
1382
- method: 'insertOne',
1383
- id_user: '',
1384
- user: '',
1385
- messageId: 0,
1386
- route: ''
1387
- });
1388
- }
1389
-
1390
- if (this.useVersions && !doc.hasOwnProperty('__v')) {
1391
- doc.__v = 0;
1392
- }
1393
-
1394
- let monitor = new MonitorMongo('insertOne', this.collectionName, JSON.stringify([doc, options]));
1395
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).insertOne(<OptionalUnlessRequiredId<T>>doc, options).then(res => {
1396
- monitor.finish();
1397
- if (res.acknowledged) {
1398
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
1399
- resolve(doc);
1400
- }
1401
- else {
1402
- reject(res.acknowledged);
1403
- }
1404
- }, err => {
1405
- monitor.finish();
1406
- console.log(new Date(), 'Error Insert One', this.collectionName, doc, options, err);
1407
- reject(err);
1408
- });
1409
- });
1410
- }
1411
-
1412
- listIndexes(options?: ListIndexesOptions): ListIndexesCursor {
1413
- let monitor = new MonitorMongo('listIndexes', this.collectionName, JSON.stringify([options]));
1414
- let cursor = ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).listIndexes(options);
1415
- cursor.on('close', ev => {
1416
- monitor.finish();
1417
- return ev;
1418
- });
1419
- return cursor;
1420
- }
1421
-
1422
- rename(newName: string, options?: RenameOptions): Promise<Collection<Document>> {
1423
- return new Promise((resolve, reject) => {
1424
- let monitor = new MonitorMongo('rename', this.collectionName, JSON.stringify([newName, options]));
1425
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).rename(newName, options).then(res => {
1426
- monitor.finish();
1427
- resolve(res);
1428
- }, err => {
1429
- monitor.finish();
1430
- console.log(new Date(), 'Error Rename', this.collectionName, newName, options, err);
1431
- reject(err);
1432
- });
1433
- });
1434
- }
1435
-
1436
- replaceOne(filter: MongoManagerFilter<T> & MongoManagerFilterOperators<T>, replacement: T, options?: ReplaceOptions, bypassLogs = false, bypassCheckSchema = false, doc: T = null) : Promise<number> {
1437
- return new Promise(async (resolve, reject) => {
1438
- if (this.checkSchema && !bypassCheckSchema) {
1439
- const validation = this.simplschema.newContext();
1440
- const isValid = validation.validate(replacement);
1441
-
1442
- if (!isValid) {
1443
- console.log(new Date(), this.collectionName, 'Schema Errors - replaceOne', validation.validationErrors());
1444
- ResolveIOServer.getMainServer().getMethodManager().callMethodInternal.call(ResolveIOServer.getMainServer().getMethodManager(), 'insertErrorLog', 'Schema Failed on replaceOne - ' + this.collectionName, [validation.validationErrors(), replacement]);
1445
- reject(validation.validationErrors());
1446
- return;
1447
- }
1448
- }
1449
-
1450
- let date = new Date();
1451
-
1452
- if (this.timestamps) {
1453
- replacement.updatedAt = date;
1454
- }
1455
-
1456
- if (this.useVersions) {
1457
- if (!doc) {
1458
- doc = await this.findOne(<any>filter, null, true);
1459
- }
1460
-
1461
- if (doc) {
1462
- if (this.timestamps && !replacement.createdAt && doc.createdAt) {
1463
- replacement.createdAt = doc.createdAt;
1464
- }
1465
-
1466
- if (doc.__v === replacement.__v) {
1467
- replacement.__v += 1;
1468
-
1469
- let versionDoc = deepCopy(doc);
1470
- versionDoc._id = {_id: doc._id, __v: doc.__v};
1471
-
1472
- ResolveIOServer.getMongoManager().collection(this.versionCollection).replaceOne(<any>{_id: { _id: doc._id, __v: doc.__v}}, versionDoc, {upsert: true});
1473
-
1474
- if (doc.__v >= 4) {
1475
- ResolveIOServer.getMongoManager().collection(this.versionCollection).deleteMany(<any>{$and: [{'_id._id': doc._id}, {'_id.__v': {$lt: doc.__v - 4}}]});
1476
- }
1477
-
1478
- if (this.createLogs && !bypassLogs) {
1479
- Logs.insertOne({
1480
- _id: objectIdHexString(),
1481
- type: 'document',
1482
- collection: this.collectionName,
1483
- id_document: doc._id,
1484
- payload: getBinarySize(JSON.stringify([doc, filter, replacement, options])) < 200000 ? JSON.stringify([doc, filter, replacement, options], null, 2) : 'Too Big',
1485
- method: 'replaceOne',
1486
- id_user: '',
1487
- user: '',
1488
- messageId: 0,
1489
- route: ''
1490
- });
1491
- }
1492
-
1493
- let monitor = new MonitorMongo('replaceOne', this.collectionName, JSON.stringify([filter, replacement, options]));
1494
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).replaceOne(<any>filter, replacement, options).then(res => {
1495
- monitor.finish();
1496
- if (res.acknowledged) {
1497
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
1498
- resolve(res.modifiedCount);
1499
- }
1500
- else {
1501
- reject(res.acknowledged);
1502
- }
1503
- }, err => {
1504
- monitor.finish();
1505
- console.log(new Date(), 'Error Replace One', this.collectionName, filter, replacement, options, err);
1506
- reject(err);
1507
- });
1508
- }
1509
- else {
1510
- console.log('invalid version - ' + this.collectionName, doc.__v, replacement.__v);
1511
-
1512
- let prevDoc = await ResolveIOServer.getMongoManager().collection(this.versionCollection).findOne({
1513
- _id: <any>{
1514
- _id: doc._id,
1515
- __v: replacement.__v
1516
- }
1517
- }, null, true);
1518
-
1519
- if (prevDoc) {
1520
- let docId = doc._id;
1521
- let docVersion = doc.__v;
1522
- let updatedDoc: T = getMongoMergeUpdatedDoc(replacement, doc, prevDoc);
1523
- updatedDoc._id = docId;
1524
- updatedDoc.__v = docVersion + 1;
1525
-
1526
- if (this.createLogs && !bypassLogs) {
1527
- Logs.insertOne({
1528
- _id: objectIdHexString(),
1529
- type: 'document',
1530
- collection: this.collectionName,
1531
- id_document: docId,
1532
- payload: getBinarySize(JSON.stringify(['invalidVersion - merge', doc, filter, updatedDoc, options])) < 200000 ? JSON.stringify(['invalidVersion - merge', doc, filter, updatedDoc, options], null, 2) : 'Too Big',
1533
- method: 'replaceOne',
1534
- id_user: '',
1535
- user: '',
1536
- messageId: 0,
1537
- route: ''
1538
- });
1539
- }
1540
-
1541
- let monitor = new MonitorMongo('replaceOne', this.collectionName, JSON.stringify([filter, updatedDoc, options]));
1542
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).replaceOne(<any>filter, updatedDoc, options).then(res => {
1543
- monitor.finish();
1544
- if (res.acknowledged) {
1545
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
1546
- resolve(res.modifiedCount);
1547
- }
1548
- else {
1549
- reject(res.acknowledged);
1550
- }
1551
- }, err => {
1552
- monitor.finish();
1553
- console.log(new Date(), 'Error Replace One', this.collectionName, filter, updatedDoc, options, err);
1554
- reject(err);
1555
- });
1556
- }
1557
- else {
1558
- reject('Invalid Version And Could Not Find History - DB: ' + doc.__v + ', Trying to update with :' + replacement.__v);
1559
- }
1560
- }
1561
- }
1562
- else if (options && options.upsert) {
1563
- if (this.timestamps) {
1564
- replacement.createdAt = date;
1565
- }
1566
-
1567
- if (!replacement._id) {
1568
- replacement._id = objectIdHexString();
1569
- }
1570
-
1571
- replacement.__v = 0;
1572
-
1573
- if (this.createLogs && !bypassLogs) {
1574
- Logs.insertOne({
1575
- _id: objectIdHexString(),
1576
- type: 'document',
1577
- collection: this.collectionName,
1578
- id_document: replacement._id,
1579
- payload: getBinarySize(JSON.stringify(['upsert', filter, replacement, options])) < 200000 ? JSON.stringify(['upsert', filter, replacement, options], null, 2) : 'Too Big',
1580
- method: 'replaceOne',
1581
- id_user: '',
1582
- user: '',
1583
- messageId: 0,
1584
- route: ''
1585
- });
1586
- }
1587
-
1588
- let monitor = new MonitorMongo('replaceOne', this.collectionName, JSON.stringify([filter, replacement, options]));
1589
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).replaceOne(<any>filter, replacement, options).then(res => {
1590
- monitor.finish();
1591
- if (res.acknowledged) {
1592
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
1593
- resolve(res.modifiedCount);
1594
- }
1595
- else {
1596
- reject(res.acknowledged);
1597
- }
1598
- }, err => {
1599
- monitor.finish();
1600
- console.log(new Date(), 'Error Replace One', this.collectionName, filter, replacement, options, err);
1601
- reject(err);
1602
- });
1603
- }
1604
- else {
1605
- reject('No Document');
1606
- }
1607
- }
1608
- else {
1609
- if (options && options.upsert) {
1610
- if (this.timestamps && !replacement.createdAt) {
1611
- replacement.createdAt = date;
1612
- }
1613
-
1614
- if (!replacement._id) {
1615
- replacement._id = objectIdHexString();
1616
- }
1617
-
1618
- replacement.__v = 0;
1619
- }
1620
-
1621
- if (this.createLogs && !bypassLogs) {
1622
- if (!options) {
1623
- options = <FindOneAndReplaceOptions>{returnDocument: 'before'};
1624
- }
1625
- else {
1626
- (<FindOneAndReplaceOptions>options).returnDocument = 'before';
1627
- }
1628
-
1629
- let monitor = new MonitorMongo('findOneAndReplace', this.collectionName, JSON.stringify([filter, replacement, options]));
1630
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).findOneAndReplace(<any>filter, replacement, <FindOneAndReplaceOptions>options).then(res => {
1631
- monitor.finish();
1632
- let doc = res.value;
1633
-
1634
- if (doc) {
1635
- Logs.insertOne({
1636
- _id: objectIdHexString(),
1637
- type: 'document',
1638
- collection: this.collectionName,
1639
- id_document: doc._id,
1640
- payload: getBinarySize(JSON.stringify([doc, filter, replacement, options])) < 200000 ? JSON.stringify([doc, filter, replacement, options], null, 2) : 'Too Big',
1641
- method: 'replaceOne',
1642
- id_user: '',
1643
- user: '',
1644
- messageId: 0,
1645
- route: ''
1646
- });
1647
- }
1648
- else {
1649
- Logs.insertOne({
1650
- _id: objectIdHexString(),
1651
- type: 'document',
1652
- collection: this.collectionName,
1653
- id_document: replacement._id,
1654
- payload: getBinarySize(JSON.stringify(['upsert', filter, replacement, options])) < 200000 ? JSON.stringify(['upsert', filter, replacement, options], null, 2) : 'Too Big',
1655
- method: 'replaceOne',
1656
- id_user: '',
1657
- user: '',
1658
- messageId: 0,
1659
- route: ''
1660
- });
1661
- }
1662
-
1663
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
1664
- resolve(res.ok);
1665
- }, err => {
1666
- monitor.finish();
1667
- console.log(new Date(), 'Error Find One And Replace', this.collectionName, filter, replacement, options, err);
1668
- reject(err);
1669
- });
1670
- }
1671
- else {
1672
- let monitor = new MonitorMongo('replaceOne', this.collectionName, JSON.stringify([filter, replacement, options]));
1673
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).replaceOne(<any>filter, replacement, options).then(res => {
1674
- monitor.finish();
1675
- if (res.acknowledged) {
1676
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
1677
- resolve(res.modifiedCount);
1678
- }
1679
- else {
1680
- reject(res.acknowledged);
1681
- }
1682
- }, err => {
1683
- monitor.finish();
1684
- console.log(new Date(), 'Error Replace One', this.collectionName, filter, replacement, options, err);
1685
- reject(err);
1686
- });
1687
- }
1688
- }
1689
- });
1690
- }
1691
-
1692
- stats(options?: CollStatsOptions): Promise<CollStats> {
1693
- return new Promise((resolve, reject) => {
1694
- let monitor = new MonitorMongo('stats', this.collectionName, JSON.stringify([options]));
1695
- ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).stats(options).then(res => {
1696
- monitor.finish();
1697
- resolve(res);
1698
- }, err => {
1699
- monitor.finish();
1700
- console.log(new Date(), 'Error Stats', this.collectionName, options, err);
1701
- reject(err);
1702
- });
1703
- });
1704
- }
1705
-
1706
- updateMany(filter: MongoManagerFilter<T> & MongoManagerFilterOperators<T>, update: MongoManagerUpdateFilter<T>, options?: UpdateOptions, bypassLogs = false, bypassCheckSchema = false, bypassVersions = false) : Promise<number> {
1707
- return new Promise(async (resolve, reject) => {
1708
- if ((!update.$inc || JSON.stringify(update.$inc) === '{}') && (!update.$set || JSON.stringify(update.$set) === '{}') && (!update.$setOnInsert || JSON.stringify(update.$setOnInsert) === '{}') && (!update.$unset || JSON.stringify(update.$unset) === '{}')) {
1709
- resolve(1);
1710
- return;
1711
- }
1712
-
1713
- if (this.timestamps) {
1714
- let date = new Date();
1715
-
1716
- if (!update.$set) {
1717
- update.$set = <any>{updatedAt: date};
1718
- }
1719
- else {
1720
- update.$set.updatedAt = date;
1721
- }
1722
- }
1723
-
1724
- if (this.checkSchema && !bypassCheckSchema) {
1725
- const validation = this.simplschema.newContext();
1726
- const isValid = validation.validate(update, {modifier: true});
1727
-
1728
- if (!isValid) {
1729
- console.log(new Date(), this.collectionName, 'Schema Errors - updateMany', validation.validationErrors());
1730
- ResolveIOServer.getMainServer().getMethodManager().callMethodInternal.call(ResolveIOServer.getMainServer().getMethodManager(), 'insertErrorLog', 'Schema Failed on updateMany - ' + this.collectionName, [validation.validationErrors(), update]);
1731
- reject(validation.validationErrors());
1732
- return;
1733
- }
1734
- }
1735
-
1736
- if ((this.useVersions && !bypassVersions) || (this.createLogs && !bypassLogs)) {
1737
- let docs = await this.find(filter);
1738
-
1739
- for (let i = 0; i < docs.length; i++) {
1740
- let doc = docs[i];
1741
-
1742
- if (this.createLogs && !bypassLogs) {
1743
- Logs.insertOne({
1744
- _id: objectIdHexString(),
1745
- type: 'document',
1746
- collection: this.collectionName,
1747
- id_document: doc._id,
1748
- payload: getBinarySize(JSON.stringify([doc, filter, update, options])) < 200000 ? JSON.stringify([doc, filter, update, options], null, 2) : 'Too Big',
1749
- method: 'updateMany',
1750
- id_user: '',
1751
- user: '',
1752
- messageId: 0,
1753
- route: ''
1754
- });
1755
- }
1756
-
1757
- if (this.useVersions) {
1758
- let versionDoc = deepCopy(doc);
1759
- versionDoc._id = {_id: doc._id, __v: doc.__v};
1760
-
1761
- ResolveIOServer.getMongoManager().collection(this.versionCollection).replaceOne(<any>{_id: { _id: doc._id, __v: doc.__v}}, versionDoc, {upsert: true});
1762
-
1763
- if (doc.__v >= 4) {
1764
- ResolveIOServer.getMongoManager().collection(this.versionCollection).deleteMany(<any>{$and: [{'_id._id': doc._id}, {'_id.__v': {$lt: doc.__v - 4}}]});
1765
- }
1766
-
1767
- if (!objectContainsPropertyDeep(update, '__v')) {
1768
- if (!update.$inc) {
1769
- update.$inc = {__v: 1};
1770
- }
1771
- else if (!update.$inc.__v) {
1772
- update.$inc.__v = 1;
1773
- }
1774
- }
1775
- }
1776
- }
1777
- }
1778
-
1779
- let monitor = new MonitorMongo('updateMany', this.collectionName, JSON.stringify([filter, update, options]));
1780
- ResolveIOServer.getMainDB().collection(this.collectionName, this.collectionOptions).updateMany(<any>filter, update, options).then(res => {
1781
- monitor.finish();
1782
- if (res.acknowledged) {
1783
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
1784
- resolve(res.modifiedCount);
1785
- }
1786
- else {
1787
- reject(res.acknowledged);
1788
- }
1789
- }, err => {
1790
- monitor.finish();
1791
- console.log(new Date(), 'Error Update Many', this.collectionName, filter, update, options, err);
1792
- reject(err)
1793
- });
1794
- });
1795
- }
1796
-
1797
- updateOne(filter: MongoManagerFilter<T> & MongoManagerFilterOperators<T>, update: MongoManagerUpdateFilter<T>, options?: UpdateOptions, bypassLogs = false, bypassCheckSchema = false) : Promise<number> {
1798
- return new Promise(async (resolve, reject) => {
1799
- if (this.checkSchema && !bypassCheckSchema) {
1800
- const validation = this.simplschema.newContext();
1801
- const isValid = validation.validate(update, {modifier: true});
1802
-
1803
- if (!isValid) {
1804
- console.log(new Date(), this.collectionName, 'Schema Errors - updateOne', validation.validationErrors());
1805
- ResolveIOServer.getMainServer().getMethodManager().callMethodInternal.call(ResolveIOServer.getMainServer().getMethodManager(), 'insertErrorLog', 'Schema Failed on updateOne - ' + this.collectionName, [validation.validationErrors(), update]);
1806
- reject(validation.validationErrors());
1807
- return;
1808
- }
1809
- }
1810
-
1811
- if ((!update.$inc || JSON.stringify(update.$inc) === '{}') && (!update.$set || JSON.stringify(update.$set) === '{}') && (!update.$setOnInsert || JSON.stringify(update.$setOnInsert) === '{}') && (!update.$unset || JSON.stringify(update.$unset) === '{}')) {
1812
- resolve(1);
1813
- return;
1814
- }
1815
-
1816
- let date = new Date();
1817
-
1818
- if (this.timestamps) {
1819
- if (!update.$set) {
1820
- update.$set = <any>{updatedAt: date};
1821
- }
1822
- else {
1823
- update.$set.updatedAt = date;
1824
- }
1825
- }
1826
-
1827
- if (this.useVersions) {
1828
- let doc = await this.findOne(filter, null, true);
1829
-
1830
- if (doc) {
1831
- if (this.createLogs && !bypassLogs) {
1832
- Logs.insertOne({
1833
- _id: objectIdHexString(),
1834
- type: 'document',
1835
- collection: this.collectionName,
1836
- id_document: doc._id,
1837
- payload: getBinarySize(JSON.stringify([doc, filter, update, options])) < 200000 ? JSON.stringify([doc, filter, update, options], null, 2) : 'Too Big',
1838
- method: 'updateOne',
1839
- id_user: '',
1840
- user: '',
1841
- messageId: 0,
1842
- route: ''
1843
- });
1844
- }
1845
-
1846
- let versionDoc = deepCopy(doc);
1847
- versionDoc._id = {_id: doc._id, __v: doc.__v};
1848
-
1849
- ResolveIOServer.getMongoManager().collection(this.versionCollection).replaceOne(<any>{_id: { _id: doc._id, __v: doc.__v}}, versionDoc, {upsert: true});
1850
-
1851
- if (doc.__v >= 4) {
1852
- ResolveIOServer.getMongoManager().collection(this.versionCollection).deleteMany(<any>{$and: [{'_id._id': doc._id}, {'_id.__v': {$lt: doc.__v - 4}}]});
1853
- }
1854
-
1855
- if (!objectContainsPropertyDeep(update, '__v')) {
1856
- if (!update.$inc) {
1857
- update.$inc = {__v: 1};
1858
- }
1859
- else if (!update.$inc.__v) {
1860
- update.$inc.__v = 1;
1861
- }
1862
- }
1863
-
1864
- let monitor = new MonitorMongo('updateOne', this.collectionName, JSON.stringify([filter, update, options]));
1865
- ResolveIOServer.getMainDB().collection(this.collectionName, this.collectionOptions).updateOne(<any>filter, update, options).then(res => {
1866
- monitor.finish();
1867
- if (res.acknowledged) {
1868
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
1869
- resolve(res.modifiedCount);
1870
- }
1871
- else {
1872
- reject(res.acknowledged);
1873
- }
1874
- }, err => {
1875
- monitor.finish();
1876
- console.log(new Date(), 'Error Update One', this.collectionName, filter, update, options, err);
1877
- reject(err);
1878
- });
1879
- }
1880
- else if (options && options.upsert) {
1881
- if (!update.$setOnInsert) {
1882
- if (this.timestamps) {
1883
- update.$setOnInsert = <any>{
1884
- _id: objectIdHexString(),
1885
- __v: 0,
1886
- createdAt: new Date()
1887
- };
1888
- }
1889
- else {
1890
- update.$setOnInsert = <any>{
1891
- _id: objectIdHexString(),
1892
- __v: 0
1893
- };
1894
- }
1895
- }
1896
- else {
1897
- if (!update.$setOnInsert._id) {
1898
- update.$setOnInsert._id = objectIdHexString();
1899
- }
1900
-
1901
- if (this.timestamps) {
1902
- update.$setOnInsert.createdAt = new Date();
1903
- }
1904
- }
1905
-
1906
- if (this.createLogs && !bypassLogs) {
1907
- Logs.insertOne({
1908
- _id: objectIdHexString(),
1909
- type: 'document',
1910
- collection: this.collectionName,
1911
- id_document: update.$setOnInsert._id,
1912
- payload: getBinarySize(JSON.stringify(['upsert', filter, update, options])) < 200000 ? JSON.stringify(['upsert', filter, update, options], null, 2) : 'Too Big',
1913
- method: 'updateOne',
1914
- id_user: '',
1915
- user: '',
1916
- messageId: 0,
1917
- route: ''
1918
- });
1919
- }
1920
-
1921
- let monitor = new MonitorMongo('updateOne', this.collectionName, JSON.stringify([filter, update, options]));
1922
- ResolveIOServer.getMainDB().collection(this.collectionName, this.collectionOptions).updateOne(<any>filter, update, options).then(res => {
1923
- monitor.finish();
1924
- if (res.acknowledged) {
1925
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
1926
- resolve(res.modifiedCount);
1927
- }
1928
- else {
1929
- reject(res.acknowledged);
1930
- }
1931
- }, err => {
1932
- monitor.finish();
1933
- console.log(new Date(), 'Error Update One', this.collectionName, filter, update, options, err);
1934
- reject(err);
1935
- });
1936
- }
1937
- else {
1938
- reject('No Document');
1939
- }
1940
- }
1941
- else {
1942
- if (options && options.upsert) {
1943
- if (!update.$setOnInsert) {
1944
- if (this.timestamps) {
1945
- update.$setOnInsert = <any>{
1946
- _id: objectIdHexString(),
1947
- createdAt: new Date()
1948
- };
1949
- }
1950
- else {
1951
- update.$setOnInsert = <any>{
1952
- _id: objectIdHexString()
1953
- };
1954
- }
1955
- }
1956
- else {
1957
- if (!update.$setOnInsert._id) {
1958
- update.$setOnInsert._id = objectIdHexString();
1959
- }
1960
-
1961
- if (this.timestamps) {
1962
- update.$setOnInsert.createdAt = new Date();
1963
- }
1964
- }
1965
- }
1966
-
1967
- if (this.createLogs && !bypassLogs) {
1968
- if (!options) {
1969
- options = <FindOneAndUpdateOptions>{returnDocument: 'before'};
1970
- }
1971
- else {
1972
- (<FindOneAndUpdateOptions>options).returnDocument = 'before';
1973
- }
1974
-
1975
- let monitor = new MonitorMongo('findOneAndUpdate', this.collectionName, JSON.stringify([filter, update, options]));
1976
- ResolveIOServer.getMainDB().collection(this.collectionName, this.collectionOptions).findOneAndUpdate(<any>filter, update, <FindOneAndUpdateOptions>options).then(res => {
1977
- monitor.finish();
1978
- let doc = res.value;
1979
-
1980
- if (doc) {
1981
- Logs.insertOne({
1982
- _id: objectIdHexString(),
1983
- type: 'document',
1984
- collection: this.collectionName,
1985
- id_document: <any>doc._id,
1986
- payload: getBinarySize(JSON.stringify([doc, filter, update, options])) < 200000 ? JSON.stringify([doc, filter, update, options], null, 2) : 'Too Big',
1987
- method: 'updateOne',
1988
- id_user: '',
1989
- user: '',
1990
- messageId: 0,
1991
- route: ''
1992
- });
1993
-
1994
- resolve(res.ok);
1995
- }
1996
- else if (update.$setOnInsert) {
1997
- Logs.insertOne({
1998
- _id: objectIdHexString(),
1999
- type: 'document',
2000
- collection: this.collectionName,
2001
- id_document: update.$setOnInsert._id,
2002
- payload: getBinarySize(JSON.stringify(['upsert', filter, update, options])) < 200000 ? JSON.stringify(['upsert', filter, update, options], null, 2) : 'Too Big',
2003
- method: 'updateOne',
2004
- id_user: '',
2005
- user: '',
2006
- messageId: 0,
2007
- route: ''
2008
- });
2009
-
2010
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
2011
-
2012
- resolve(res.ok);
2013
- }
2014
- else {
2015
- resolve(0);
2016
- }
2017
- }, err => {
2018
- monitor.finish();
2019
- console.log(new Date(), 'Error Find One And Update', this.collectionName, filter, update, options, err);
2020
- reject(err)
2021
- });
2022
- }
2023
- else {
2024
- let monitor = new MonitorMongo('updateOne', this.collectionName, JSON.stringify([filter, update, options]));
2025
- ResolveIOServer.getMainDB().collection(this.collectionName, this.collectionOptions).updateOne(<any>filter, update, options).then(res => {
2026
- monitor.finish();
2027
- if (res.acknowledged) {
2028
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
2029
- resolve(res.modifiedCount);
2030
- }
2031
- else {
2032
- reject(res.acknowledged);
2033
- }
2034
- }, err => {
2035
- monitor.finish();
2036
- console.log(new Date(), 'Error Update One', this.collectionName, filter, update, options, err);
2037
- reject(err);
2038
- });
2039
- }
2040
- }
2041
- });
2042
- }
2043
-
2044
- watchCollection(pipeline = [], options?: ChangeStreamOptions): ChangeStream<T> {
2045
- let stream = ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).watch(pipeline, options);
2046
- stream.on('change', evData => {
2047
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
2048
- return evData;
2049
- });
2050
- return <ChangeStream<T>>stream;
2051
- }
2052
-
2053
- watchCollectionWithAggregate(pipeline = [], options?: ChangeStreamOptions): ChangeStream<T> {
2054
- let stream = ResolveIOServer.getMainDB().collection<T>(this.collectionName, this.collectionOptions).watch(pipeline, options);
2055
- stream.on('change', evData => {
2056
- ResolveIOServer.getMongoManager().invalidateQueryCache(this.collectionName);
2057
- return evData;
2058
- });
2059
- return <ChangeStream<T>>stream;
2060
- }
2061
- }
2062
-
2063
- export class MongoManagerUserCollection<T extends CollectionDocument> extends MongoManagerCollection<T> {
2064
- authenticateStrategy() {
2065
- return async (username, password, cb) => {
2066
- let user = await Users.findOne({username: username});
2067
- this.authenticate(user, password).then(authUser => {
2068
- if (authUser.data) {
2069
- cb(null, user, null);
2070
- }
2071
- else {
2072
- cb(null, null, authUser.error);
2073
- }
2074
- }, err => {
2075
- cb(err, null, null);
2076
- })
2077
- };
2078
- }
2079
-
2080
- authenticate(user: UserModel, password: string): Promise<{data: UserModel, error: string}> {
2081
- return new Promise(async (resolve, reject) => {
2082
- const attemptsInterval = Math.pow(100, Math.log(user.attempts + 1));
2083
- const calculatedInterval = attemptsInterval < 300000 ? attemptsInterval : 300000;
2084
-
2085
- if (user.last) {
2086
- if (Date.now() - user.last.getTime() < calculatedInterval) {
2087
- user.last = new Date();
2088
- await Users.updateOne({_id: user._id}, {$set: {last: user.last}});
2089
- resolve({
2090
- data: null,
2091
- error: 'Attempt Too Soon'
2092
- });
2093
-
2094
- return;
2095
- }
2096
- }
2097
- else {
2098
- user.last = new Date();
2099
- }
2100
-
2101
- if (user.attempts >= 5) {
2102
- resolve({
2103
- data: null,
2104
- error: 'Too Many Attempts'
2105
- });
2106
-
2107
- return;
2108
- }
2109
-
2110
- if (!user.salt) {
2111
- resolve({
2112
- data: null,
2113
- error: 'No Salt Value Stored'
2114
- });
2115
-
2116
- return;
2117
- }
2118
-
2119
- pbkdf2(password, user.salt, {
2120
- iterations: 25000,
2121
- keylen: 512,
2122
- digestAlgorithm: 'sha256'
2123
- }, async (err, hashBuffer) => {
2124
- if (err) {
2125
- return reject(err);
2126
- }
2127
-
2128
- if (scmp(hashBuffer, Buffer.from(user.hash, 'hex'))) {
2129
- user.last = new Date();
2130
- user.attempts = 0;
2131
- await Users.updateOne({_id: user._id}, {$set: {last: user.last, attempts: user.attempts}});
2132
-
2133
- resolve({
2134
- data: user,
2135
- error: ''
2136
- });
2137
- }
2138
- else {
2139
- user.last = new Date();
2140
- user.attempts = user.attempts + 1;
2141
- await Users.updateOne({_id: user._id}, {$set: {last: user.last, attempts: user.attempts}});
2142
-
2143
- if (user.attempts >= 5) {
2144
- resolve({
2145
- data: null,
2146
- error: 'Too Many Attempts'
2147
- });
2148
- }
2149
- else {
2150
- resolve({
2151
- data: null,
2152
- error: 'Invalid Username And Password'
2153
- });
2154
- }
2155
- }
2156
- });
2157
- });
2158
- }
2159
-
2160
- serializeUser() {
2161
- return (user, cb) => {
2162
- cb(null, user.username);
2163
- };
2164
- }
2165
-
2166
- deserializeUser() {
2167
- return (username, cb) => {
2168
- Users.findOne({username: username}).then(res => {
2169
- cb(null, res);
2170
- }, err => {
2171
- cb(err, null);
2172
- });
2173
- };
2174
- }
2175
-
2176
- setPassword(user: UserModel, password: string) {
2177
- return new Promise(async (resolve, reject) => {
2178
- if (!user) {
2179
- reject('No User');
2180
- }
2181
- else if (!password) {
2182
- reject('No Password');
2183
- }
2184
- else {
2185
- let saltBuffer = await randomBytes(32);
2186
- let salt = saltBuffer.toString('hex');
2187
- let hashRaw = await pbkdf2Promisified(password, salt, {
2188
- iterations: 25000,
2189
- keylen: 512,
2190
- digestAlgorithm: 'sha256'
2191
- });
2192
- let hash = Buffer.from(hashRaw, 'binary').toString('hex');
2193
- Users.updateOne({_id: user._id}, {$set: {hash: hash, salt: salt, services: {}, attempts: 0}}).then(res => resolve(res), rej => reject(rej));
2194
- }
2195
- });
2196
- };
2197
-
2198
- changePassword(user, oldPassword, newPassword) {
2199
- return new Promise(async (resolve, reject) => {
2200
- if (!user) {
2201
- reject('Missing User');
2202
- }
2203
- else if (!oldPassword || !newPassword) {
2204
- reject('Missing Password');
2205
- }
2206
- else {
2207
- let authUser = await this.authenticate(user, oldPassword);
2208
-
2209
- if (!authUser['data']) {
2210
- reject(authUser['error']);
2211
- }
2212
- else {
2213
- this.setPassword(user, newPassword).then(res => resolve(res), rej => reject(rej));
2214
- }
2215
- }
2216
- });
2217
- }
2218
-
2219
- register(user, password) {
2220
- return new Promise(async (resolve, reject) => {
2221
- if (!user.username) {
2222
- reject('Missing Username');
2223
- }
2224
- else {
2225
- let dbUser = await Users.findOne({username: user.username});
2226
-
2227
- if (dbUser) {
2228
- reject('Username Exists');
2229
- }
2230
- else {
2231
- dbUser = await Users.findOne({email: user.email});
2232
-
2233
- if (dbUser) {
2234
- reject('Email Exists');
2235
- }
2236
- else {
2237
- user.setPassword(password);
2238
- resolve(user);
2239
- }
2240
- }
2241
- }
2242
- });
2243
- }
2244
-
2245
- resetAttempts(user: UserModel) {
2246
- return Users.updateOne({_id: user._id}, {$set: {attempts: 0}});
2247
- }
2248
- }
2249
-
2250
- export function objectIdHexString() {
2251
- let objectId = new ObjectId();
2252
- return objectId.toHexString();
2253
- }
2254
-
2255
- function pbkdf2(password, salt, options, callback) {
2256
- crypto.pbkdf2(password, salt, options.iterations, options.keylen, options.digestAlgorithm, callback);
2257
- };
2258
-
2259
- function pbkdf2Promisified(password, salt, options): Promise<any> {
2260
- return new Promise((resolve, reject) => pbkdf2(password, salt, options, (err, hashRaw) => (err ? reject(err) : resolve(hashRaw))));
2261
- }
2262
-
2263
- function randomBytes(saltlen): Promise<Buffer> {
2264
- return new Promise((resolve, reject) => crypto.randomBytes(saltlen, (err, saltBuffer) => (err ? reject(err) : resolve(saltBuffer))));
2265
- }
2266
-
2267
- function objectContainsPropertyDeep(obj: Object, prop: string) {
2268
- let keys = Object.keys(obj);
2269
-
2270
- if (keys.some(a => a === prop)) {
2271
- return true;
2272
- }
2273
-
2274
- for (let i = 0; i < keys.length; i++) {
2275
- let key = keys[i];
2276
- if (obj[key] && typeof obj[key] === 'object' && objectContainsPropertyDeep(obj[key], prop)) {
2277
- return true;
2278
- }
2279
- }
2280
-
2281
- return false;
2282
- }