@syngrisi/syngrisi 2.2.2 → 2.2.6-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (613) hide show
  1. package/README.md +49 -27
  2. package/dist/server/api-docs/openAPIDocumentGenerator.js +6489 -0
  3. package/dist/server/api-docs/openAPIDocumentGenerator.js.map +1 -0
  4. package/dist/server/api-docs/openAPIResponseBuilders.js +89 -0
  5. package/dist/server/api-docs/openAPIResponseBuilders.js.map +1 -0
  6. package/dist/server/api-docs/openAPIRouter.js +6505 -0
  7. package/dist/server/api-docs/openAPIRouter.js.map +1 -0
  8. package/dist/server/api-docs/serviceResponse.js +39 -0
  9. package/dist/server/api-docs/serviceResponse.js.map +1 -0
  10. package/dist/server/app.js +6751 -0
  11. package/dist/server/app.js.map +1 -0
  12. package/dist/server/config.js +1055 -0
  13. package/dist/server/config.js.map +1 -0
  14. package/dist/server/controllers/app.controller.js +1949 -0
  15. package/dist/server/controllers/app.controller.js.map +1 -0
  16. package/dist/server/controllers/auth.controller.js +2079 -0
  17. package/dist/server/controllers/auth.controller.js.map +1 -0
  18. package/dist/server/controllers/baseline.controller.js +1976 -0
  19. package/dist/server/controllers/baseline.controller.js.map +1 -0
  20. package/dist/server/controllers/check.controller.js +2289 -0
  21. package/dist/server/controllers/check.controller.js.map +1 -0
  22. package/dist/server/controllers/client.controller.js +2994 -0
  23. package/dist/server/controllers/client.controller.js.map +1 -0
  24. package/dist/server/controllers/index.js +4289 -0
  25. package/dist/server/controllers/index.js.map +1 -0
  26. package/dist/server/controllers/logs.controller.js +1954 -0
  27. package/dist/server/controllers/logs.controller.js.map +1 -0
  28. package/dist/server/controllers/runs.controller.js +2293 -0
  29. package/dist/server/controllers/runs.controller.js.map +1 -0
  30. package/dist/server/controllers/settings.controller.js +843 -0
  31. package/dist/server/controllers/settings.controller.js.map +1 -0
  32. package/dist/server/controllers/snapshots.controller.js +1953 -0
  33. package/dist/server/controllers/snapshots.controller.js.map +1 -0
  34. package/dist/server/controllers/suite.controller.js +2288 -0
  35. package/dist/server/controllers/suite.controller.js.map +1 -0
  36. package/dist/server/controllers/tasks.controller.js +2378 -0
  37. package/dist/server/controllers/tasks.controller.js.map +1 -0
  38. package/dist/server/controllers/test.controller.js +2312 -0
  39. package/dist/server/controllers/test.controller.js.map +1 -0
  40. package/dist/server/controllers/users.controller.js +2056 -0
  41. package/dist/server/controllers/users.controller.js.map +1 -0
  42. package/dist/server/envConfig.js +70 -0
  43. package/dist/server/envConfig.js.map +1 -0
  44. package/dist/server/lib/AppSettings/AppSettings.js +814 -0
  45. package/dist/server/lib/AppSettings/AppSettings.js.map +1 -0
  46. package/dist/server/lib/AppSettings/index.js +814 -0
  47. package/dist/server/lib/AppSettings/index.js.map +1 -0
  48. package/dist/server/lib/connectDb.js +1873 -0
  49. package/dist/server/lib/connectDb.js.map +1 -0
  50. package/dist/server/lib/dbItems/createAppIfNotExist.js +1878 -0
  51. package/dist/server/lib/dbItems/createAppIfNotExist.js.map +1 -0
  52. package/dist/server/lib/dbItems/createItemIfNotExist.js +1883 -0
  53. package/dist/server/lib/dbItems/createItemIfNotExist.js.map +1 -0
  54. package/dist/server/lib/dbItems/createItemProm.js +1877 -0
  55. package/dist/server/lib/dbItems/createItemProm.js.map +1 -0
  56. package/dist/server/lib/dbItems/createRunIfNotExist.js +1898 -0
  57. package/dist/server/lib/dbItems/createRunIfNotExist.js.map +1 -0
  58. package/dist/server/lib/dbItems/createSuiteIfNotExist.js +1878 -0
  59. package/dist/server/lib/dbItems/createSuiteIfNotExist.js.map +1 -0
  60. package/dist/server/lib/dbItems/createTest.js +1884 -0
  61. package/dist/server/lib/dbItems/createTest.js.map +1 -0
  62. package/dist/server/lib/dbItems/createUser.js +1884 -0
  63. package/dist/server/lib/dbItems/createUser.js.map +1 -0
  64. package/dist/server/lib/dbItems/index.js +2043 -0
  65. package/dist/server/lib/dbItems/index.js.map +1 -0
  66. package/dist/server/lib/dbItems/updateItem.js +1873 -0
  67. package/dist/server/lib/dbItems/updateItem.js.map +1 -0
  68. package/dist/server/lib/dbItems/updateItemDate.js +1872 -0
  69. package/dist/server/lib/dbItems/updateItemDate.js.map +1 -0
  70. package/dist/server/lib/httpLogger.js +1066 -0
  71. package/dist/server/lib/httpLogger.js.map +1 -0
  72. package/dist/server/lib/logger.js +1852 -0
  73. package/dist/server/lib/logger.js.map +1 -0
  74. package/dist/server/lib/startup/createBasicUsers.js +1901 -0
  75. package/dist/server/lib/startup/createBasicUsers.js.map +1 -0
  76. package/dist/server/lib/startup/createInitialSettings.js +820 -0
  77. package/dist/server/lib/startup/createInitialSettings.js.map +1 -0
  78. package/dist/server/lib/startup/createTempDir.js +1066 -0
  79. package/dist/server/lib/startup/createTempDir.js.map +1 -0
  80. package/dist/server/lib/startup/createTestsUsers.js +1916 -0
  81. package/dist/server/lib/startup/createTestsUsers.js.map +1 -0
  82. package/dist/server/lib/startup/index.js +2071 -0
  83. package/dist/server/lib/startup/index.js.map +1 -0
  84. package/dist/server/lib//321/201omparison/comparator.js +1955 -0
  85. package/dist/server/lib//321/201omparison/comparator.js.map +1 -0
  86. package/dist/server/lib//321/201omparison/compareImagesNode.js +91 -0
  87. package/dist/server/lib//321/201omparison/compareImagesNode.js.map +1 -0
  88. package/dist/server/lib//321/201omparison/index.js +1955 -0
  89. package/dist/server/lib//321/201omparison/index.js.map +1 -0
  90. package/dist/server/middlewares/authorization.js +1994 -0
  91. package/dist/server/middlewares/authorization.js.map +1 -0
  92. package/dist/server/middlewares/compressionFilter.js +47 -0
  93. package/dist/server/middlewares/compressionFilter.js.map +1 -0
  94. package/dist/server/middlewares/disableCors.js +1073 -0
  95. package/dist/server/middlewares/disableCors.js.map +1 -0
  96. package/dist/server/middlewares/ensureLogin/ensureLoggedIn.js +2103 -0
  97. package/dist/server/middlewares/ensureLogin/ensureLoggedIn.js.map +1 -0
  98. package/dist/server/middlewares/ensureLogin/index.js +2087 -0
  99. package/dist/server/middlewares/ensureLogin/index.js.map +1 -0
  100. package/dist/server/middlewares/errorHandler.js +1886 -0
  101. package/dist/server/middlewares/errorHandler.js.map +1 -0
  102. package/dist/server/middlewares/index.js +2025 -0
  103. package/dist/server/middlewares/index.js.map +1 -0
  104. package/dist/server/models/App.model.js +145 -0
  105. package/dist/server/models/App.model.js.map +1 -0
  106. package/dist/server/models/AppSettings.model.js +105 -0
  107. package/dist/server/models/AppSettings.model.js.map +1 -0
  108. package/dist/server/models/Baseline.model.js +187 -0
  109. package/dist/server/models/Baseline.model.js.map +1 -0
  110. package/dist/server/models/Check.model.js +241 -0
  111. package/dist/server/models/Check.model.js.map +1 -0
  112. package/dist/server/models/Log.model.js +139 -0
  113. package/dist/server/models/Log.model.js.map +1 -0
  114. package/dist/server/models/Run.model.js +154 -0
  115. package/dist/server/models/Run.model.js.map +1 -0
  116. package/dist/server/models/Snapshot.model.js +148 -0
  117. package/dist/server/models/Snapshot.model.js.map +1 -0
  118. package/dist/server/models/Suite.model.js +151 -0
  119. package/dist/server/models/Suite.model.js.map +1 -0
  120. package/dist/server/models/Test.model.js +248 -0
  121. package/dist/server/models/Test.model.js.map +1 -0
  122. package/dist/server/models/User.model.js +169 -0
  123. package/dist/server/models/User.model.js.map +1 -0
  124. package/dist/server/models/index.js +720 -0
  125. package/dist/server/models/index.js.map +1 -0
  126. package/dist/server/models/plugins/index.js +159 -0
  127. package/dist/server/models/plugins/index.js.map +1 -0
  128. package/dist/server/models/plugins/paginate.plugin.js +68 -0
  129. package/dist/server/models/plugins/paginate.plugin.js.map +1 -0
  130. package/dist/server/models/plugins/paginateDistinct.plugin.js +73 -0
  131. package/dist/server/models/plugins/paginateDistinct.plugin.js.map +1 -0
  132. package/dist/server/models/plugins/toJSON.plugin.js +56 -0
  133. package/dist/server/models/plugins/toJSON.plugin.js.map +1 -0
  134. package/dist/server/models/plugins/utils.js +19 -0
  135. package/dist/server/models/plugins/utils.js.map +1 -0
  136. package/dist/server/routes/ui/admin.js +2082 -0
  137. package/dist/server/routes/ui/admin.js.map +1 -0
  138. package/dist/server/routes/ui/auth.js +711 -0
  139. package/dist/server/routes/ui/auth.js.map +1 -0
  140. package/dist/server/routes/ui/index.js +2036 -0
  141. package/dist/server/routes/ui/index.js.map +1 -0
  142. package/dist/server/routes/v1/app.route.js +4372 -0
  143. package/dist/server/routes/v1/app.route.js.map +1 -0
  144. package/dist/server/routes/v1/auth.route.js +2325 -0
  145. package/dist/server/routes/v1/auth.route.js.map +1 -0
  146. package/dist/server/routes/v1/baselines.route.js +2487 -0
  147. package/dist/server/routes/v1/baselines.route.js.map +1 -0
  148. package/dist/server/routes/v1/checks.route.js +2840 -0
  149. package/dist/server/routes/v1/checks.route.js.map +1 -0
  150. package/dist/server/routes/v1/client.route.js +3764 -0
  151. package/dist/server/routes/v1/client.route.js.map +1 -0
  152. package/dist/server/routes/v1/index.route.js +6536 -0
  153. package/dist/server/routes/v1/index.route.js.map +1 -0
  154. package/dist/server/routes/v1/logs.route.js +2426 -0
  155. package/dist/server/routes/v1/logs.route.js.map +1 -0
  156. package/dist/server/routes/v1/runs.route.js +2771 -0
  157. package/dist/server/routes/v1/runs.route.js.map +1 -0
  158. package/dist/server/routes/v1/settings.route.js +2349 -0
  159. package/dist/server/routes/v1/settings.route.js.map +1 -0
  160. package/dist/server/routes/v1/snapshots.route.js +2361 -0
  161. package/dist/server/routes/v1/snapshots.route.js.map +1 -0
  162. package/dist/server/routes/v1/suites.route.js +2713 -0
  163. package/dist/server/routes/v1/suites.route.js.map +1 -0
  164. package/dist/server/routes/v1/tasks.route.js +2761 -0
  165. package/dist/server/routes/v1/tasks.route.js.map +1 -0
  166. package/dist/server/routes/v1/test_distinct.route.js +2714 -0
  167. package/dist/server/routes/v1/test_distinct.route.js.map +1 -0
  168. package/dist/server/routes/v1/tests.route.js +2895 -0
  169. package/dist/server/routes/v1/tests.route.js.map +1 -0
  170. package/dist/server/routes/v1/users.route.js +4619 -0
  171. package/dist/server/routes/v1/users.route.js.map +1 -0
  172. package/dist/server/schemas/App.schema.js +102 -0
  173. package/dist/server/schemas/App.schema.js.map +1 -0
  174. package/dist/server/schemas/Auth.schema.js +116 -0
  175. package/dist/server/schemas/Auth.schema.js.map +1 -0
  176. package/dist/server/schemas/Baseline.schema.js +183 -0
  177. package/dist/server/schemas/Baseline.schema.js.map +1 -0
  178. package/dist/server/schemas/Check.schema.js +198 -0
  179. package/dist/server/schemas/Check.schema.js.map +1 -0
  180. package/dist/server/schemas/Client.schema.js +455 -0
  181. package/dist/server/schemas/Client.schema.js.map +1 -0
  182. package/dist/server/schemas/CreateCheck.shema.js +47 -0
  183. package/dist/server/schemas/CreateCheck.shema.js.map +1 -0
  184. package/dist/server/schemas/GetBaseline.shema.js +56 -0
  185. package/dist/server/schemas/GetBaseline.shema.js.map +1 -0
  186. package/dist/server/schemas/Logs.schema.js +140 -0
  187. package/dist/server/schemas/Logs.schema.js.map +1 -0
  188. package/dist/server/schemas/Runs.schema.js +128 -0
  189. package/dist/server/schemas/Runs.schema.js.map +1 -0
  190. package/dist/server/schemas/Settings.schema.js +156 -0
  191. package/dist/server/schemas/Settings.schema.js.map +1 -0
  192. package/dist/server/schemas/SkipValid.schema.js +32 -0
  193. package/dist/server/schemas/SkipValid.schema.js.map +1 -0
  194. package/dist/server/schemas/SnapshotDiff.schema.js +44 -0
  195. package/dist/server/schemas/SnapshotDiff.schema.js.map +1 -0
  196. package/dist/server/schemas/Snapshots.schema.js +115 -0
  197. package/dist/server/schemas/Snapshots.schema.js.map +1 -0
  198. package/dist/server/schemas/Suite.schema.js +114 -0
  199. package/dist/server/schemas/Suite.schema.js.map +1 -0
  200. package/dist/server/schemas/Test.schema.js +204 -0
  201. package/dist/server/schemas/Test.schema.js.map +1 -0
  202. package/dist/server/schemas/TestDistinct.schema.js +63 -0
  203. package/dist/server/schemas/TestDistinct.schema.js.map +1 -0
  204. package/dist/server/schemas/User.schema.js +139 -0
  205. package/dist/server/schemas/User.schema.js.map +1 -0
  206. package/dist/server/schemas/common/ApiError.schema.js +51 -0
  207. package/dist/server/schemas/common/ApiError.schema.js.map +1 -0
  208. package/dist/server/schemas/common/Error.schema.js +47 -0
  209. package/dist/server/schemas/common/Error.schema.js.map +1 -0
  210. package/dist/server/schemas/common/RequestPagination.schema.js +121 -0
  211. package/dist/server/schemas/common/RequestPagination.schema.js.map +1 -0
  212. package/dist/server/schemas/common/Version.schema.js +36 -0
  213. package/dist/server/schemas/common/Version.schema.js.map +1 -0
  214. package/dist/server/schemas/common/requestQueryFilterSchema.schema.js +53 -0
  215. package/dist/server/schemas/common/requestQueryFilterSchema.schema.js.map +1 -0
  216. package/dist/server/schemas/index.js +155 -0
  217. package/dist/server/schemas/index.js.map +1 -0
  218. package/dist/server/schemas/utils/commonValidations.js +82 -0
  219. package/dist/server/schemas/utils/commonValidations.js.map +1 -0
  220. package/dist/server/schemas/utils/createRequestBodySchema.js +32 -0
  221. package/dist/server/schemas/utils/createRequestBodySchema.js.map +1 -0
  222. package/dist/server/schemas/utils/createRequestOpenApiBodySchema.js +35 -0
  223. package/dist/server/schemas/utils/createRequestOpenApiBodySchema.js.map +1 -0
  224. package/dist/server/schemas/utils/createRequestParamsSchema.js +93 -0
  225. package/dist/server/schemas/utils/createRequestParamsSchema.js.map +1 -0
  226. package/dist/server/schemas/utils/createRequestQuerySchema.js +32 -0
  227. package/dist/server/schemas/utils/createRequestQuerySchema.js.map +1 -0
  228. package/dist/server/schemas/utils/index.js +84 -0
  229. package/dist/server/schemas/utils/index.js.map +1 -0
  230. package/dist/server/server.js +6921 -0
  231. package/dist/server/server.js.map +1 -0
  232. package/dist/server/server_old.js +7284 -0
  233. package/dist/server/server_old.js.map +1 -0
  234. package/dist/server/services/app.service.js +696 -0
  235. package/dist/server/services/app.service.js.map +1 -0
  236. package/dist/server/services/auth.service.js +2025 -0
  237. package/dist/server/services/auth.service.js.map +1 -0
  238. package/dist/server/services/check.service.js +2149 -0
  239. package/dist/server/services/check.service.js.map +1 -0
  240. package/dist/server/services/client.service.js +2648 -0
  241. package/dist/server/services/client.service.js.map +1 -0
  242. package/dist/server/services/generic.service.js +1888 -0
  243. package/dist/server/services/generic.service.js.map +1 -0
  244. package/dist/server/services/index.js +3548 -0
  245. package/dist/server/services/index.js.map +1 -0
  246. package/dist/server/services/logs.service.js +1875 -0
  247. package/dist/server/services/logs.service.js.map +1 -0
  248. package/dist/server/services/run.service.js +2221 -0
  249. package/dist/server/services/run.service.js.map +1 -0
  250. package/dist/server/services/snapshot.service.js +1921 -0
  251. package/dist/server/services/snapshot.service.js.map +1 -0
  252. package/dist/server/services/suite.service.js +2218 -0
  253. package/dist/server/services/suite.service.js.map +1 -0
  254. package/dist/server/services/tasks.service.js +2288 -0
  255. package/dist/server/services/tasks.service.js.map +1 -0
  256. package/dist/server/services/test.service.js +2230 -0
  257. package/dist/server/services/test.service.js.map +1 -0
  258. package/dist/server/services/user.service.js +1925 -0
  259. package/dist/server/services/user.service.js.map +1 -0
  260. package/dist/server/utils/ApiError.js +39 -0
  261. package/dist/server/utils/ApiError.js.map +1 -0
  262. package/dist/server/utils/ProgressBar.js +54 -0
  263. package/dist/server/utils/ProgressBar.js.map +1 -0
  264. package/dist/server/utils/ServiceResponse.js +45 -0
  265. package/dist/server/utils/ServiceResponse.js.map +1 -0
  266. package/dist/server/utils/buildIdentObject.js +52 -0
  267. package/dist/server/utils/buildIdentObject.js.map +1 -0
  268. package/dist/server/utils/calculateAcceptedStatus.js +710 -0
  269. package/dist/server/utils/calculateAcceptedStatus.js.map +1 -0
  270. package/dist/server/utils/catchAsync.js +32 -0
  271. package/dist/server/utils/catchAsync.js.map +1 -0
  272. package/dist/server/utils/checkIdent.js +36 -0
  273. package/dist/server/utils/checkIdent.js.map +1 -0
  274. package/dist/server/utils/dateToISO8601.js +30 -0
  275. package/dist/server/utils/dateToISO8601.js.map +1 -0
  276. package/dist/server/utils/deserializeIfJSON.js +706 -0
  277. package/dist/server/utils/deserializeIfJSON.js.map +1 -0
  278. package/dist/server/utils/errMsg.js +33 -0
  279. package/dist/server/utils/errMsg.js.map +1 -0
  280. package/dist/server/utils/formatISOToDateTime.js +31 -0
  281. package/dist/server/utils/formatISOToDateTime.js.map +1 -0
  282. package/dist/server/utils/ident.js +31 -0
  283. package/dist/server/utils/ident.js.map +1 -0
  284. package/dist/server/utils/index.js +910 -0
  285. package/dist/server/utils/index.js.map +1 -0
  286. package/dist/server/utils/isJSON.js +34 -0
  287. package/dist/server/utils/isJSON.js.map +1 -0
  288. package/dist/server/utils/paramsGuard.js +45 -0
  289. package/dist/server/utils/paramsGuard.js.map +1 -0
  290. package/dist/server/utils/pick.js +35 -0
  291. package/dist/server/utils/pick.js.map +1 -0
  292. package/dist/server/utils/prettyCheckParams.js +37 -0
  293. package/dist/server/utils/prettyCheckParams.js.map +1 -0
  294. package/dist/server/utils/removeEmptyProperties.js +34 -0
  295. package/dist/server/utils/removeEmptyProperties.js.map +1 -0
  296. package/dist/server/utils/subDays.js +32 -0
  297. package/dist/server/utils/subDays.js.map +1 -0
  298. package/dist/server/utils/validateRequest.js +1922 -0
  299. package/dist/server/utils/validateRequest.js.map +1 -0
  300. package/dist/server/utils/waitUntil.js +43 -0
  301. package/dist/server/utils/waitUntil.js.map +1 -0
  302. package/dist/tasks/backup.js +1085 -0
  303. package/dist/tasks/backup.js.map +1 -0
  304. package/dist/tasks/lib/index.js +717 -0
  305. package/dist/tasks/lib/index.js.map +1 -0
  306. package/dist/tasks/lib/utils.js +1070 -0
  307. package/dist/tasks/lib/utils.js.map +1 -0
  308. package/dist/tasks/migrations/2.0.migration.js +908 -0
  309. package/dist/tasks/migrations/2.0.migration.js.map +1 -0
  310. package/dist/tasks/reindex.js +1742 -0
  311. package/dist/tasks/reindex.js.map +1 -0
  312. package/dist/tasks/restore.js +1097 -0
  313. package/dist/tasks/restore.js.map +1 -0
  314. package/docker-compose.yml +3 -3
  315. package/mvc/views/react/admin/index.html +4 -4
  316. package/mvc/views/react/assets/{LogicalGroup.6c0a9f4a.js → LogicalGroup.80e37bbf.js} +1 -22
  317. package/mvc/views/react/assets/{PasswordInput.b97a4ef7.js → PasswordInput.eb05d2ed.js} +1 -1
  318. package/mvc/views/react/assets/{admin.6d843d1b.js → admin.d6aa02f7.js} +3 -3
  319. package/mvc/views/react/assets/{auth.ecf25364.js → auth.e49d0968.js} +3 -2
  320. package/mvc/views/react/assets/{root.25abcc85.js → root.b071750f.js} +7 -9
  321. package/mvc/views/react/assets/{use-form.10003abf.js → use-form.c4a2cf47.js} +203 -151
  322. package/mvc/views/react/auth/index.html +3 -3
  323. package/mvc/views/react/index2/index.html +3 -3
  324. package/package.json +45 -14
  325. package/src/seeds/testAdmin.json +10 -0
  326. package/src/server/api-docs/openAPIDocumentGenerator.ts +48 -0
  327. package/src/server/api-docs/openAPIResponseBuilders.ts +38 -0
  328. package/src/server/api-docs/openAPIRouter.ts +18 -0
  329. package/src/server/api-docs/serviceResponse.ts +11 -0
  330. package/src/server/app.ts +77 -0
  331. package/src/server/config.ts +57 -0
  332. package/src/server/controllers/app.controller.ts +23 -0
  333. package/src/server/controllers/auth.controller.ts +149 -0
  334. package/src/server/controllers/baseline.controller.ts +32 -0
  335. package/src/server/controllers/{check.controller.js → check.controller.ts} +17 -14
  336. package/src/server/controllers/client.controller.ts +134 -0
  337. package/src/server/controllers/index.ts +27 -0
  338. package/src/server/controllers/logs.controller.ts +36 -0
  339. package/src/server/controllers/runs.controller.ts +32 -0
  340. package/src/server/controllers/settings.controller.ts +28 -0
  341. package/src/server/controllers/snapshots.controller.ts +24 -0
  342. package/src/server/controllers/suite.controller.ts +30 -0
  343. package/src/server/controllers/tasks.controller.ts +47 -0
  344. package/src/server/controllers/test.controller.ts +62 -0
  345. package/src/server/controllers/users.controller.ts +89 -0
  346. package/src/server/envConfig.ts +36 -0
  347. package/src/server/lib/AppSettings/AppSettings.ts +88 -0
  348. package/src/server/lib/AppSettings/index.ts +1 -0
  349. package/src/server/lib/connectDb.ts +18 -0
  350. package/src/server/lib/dbItems/createAppIfNotExist.ts +26 -0
  351. package/src/server/lib/dbItems/createItemIfNotExist.ts +29 -0
  352. package/src/server/lib/dbItems/createItemProm.ts +22 -0
  353. package/src/server/lib/dbItems/createRunIfNotExist.ts +44 -0
  354. package/src/server/lib/dbItems/createSuiteIfNotExist.ts +26 -0
  355. package/src/server/lib/dbItems/createTest.ts +7 -0
  356. package/src/server/lib/dbItems/createUser.ts +7 -0
  357. package/src/server/lib/dbItems/index.ts +12 -0
  358. package/src/server/lib/dbItems/updateItem.ts +17 -0
  359. package/src/server/lib/dbItems/updateItemDate.ts +18 -0
  360. package/src/server/lib/httpLogger.ts +14 -0
  361. package/src/server/lib/logger.ts +147 -0
  362. package/src/server/lib/startup/createBasicUsers.ts +25 -0
  363. package/src/server/lib/startup/createInitialSettings.ts +8 -0
  364. package/src/server/lib/startup/createTempDir.ts +9 -0
  365. package/src/server/lib/startup/createTestsUsers.ts +17 -0
  366. package/src/server/lib/startup/index.ts +4 -0
  367. package/src/server/lib//321/201omparison/comparator.ts +49 -0
  368. package/src/server/lib//321/201omparison/compareImagesNode.ts +61 -0
  369. package/src/server/lib//321/201omparison/index.ts +1 -0
  370. package/src/server/middlewares/{authorization.js → authorization.ts} +23 -14
  371. package/src/server/middlewares/compressionFilter.ts +9 -0
  372. package/src/server/middlewares/disableCors.ts +32 -0
  373. package/src/server/{lib/ensureLogin/ensureLoggedIn.js → middlewares/ensureLogin/ensureLoggedIn.ts} +60 -63
  374. package/src/server/middlewares/ensureLogin/index.ts +2 -0
  375. package/src/server/middlewares/errorHandler.ts +42 -0
  376. package/src/server/middlewares/index.ts +4 -0
  377. package/src/server/models/App.model.ts +42 -0
  378. package/src/server/models/AppSettings.model.ts +48 -0
  379. package/src/server/models/Baseline.model.ts +98 -0
  380. package/src/server/models/Check.model.ts +166 -0
  381. package/src/server/models/Log.model.ts +36 -0
  382. package/src/server/models/Run.model.ts +55 -0
  383. package/src/server/models/Snapshot.model.ts +47 -0
  384. package/src/server/models/Suite.model.ts +50 -0
  385. package/src/server/models/Test.model.ts +117 -0
  386. package/src/server/models/User.model.ts +77 -0
  387. package/src/server/models/index.ts +11 -0
  388. package/src/server/models/plugins/index.ts +3 -0
  389. package/src/server/models/plugins/paginate.plugin.ts +74 -0
  390. package/src/server/models/plugins/paginateDistinct.plugin.ts +90 -0
  391. package/src/server/models/plugins/toJSON.plugin.ts +41 -0
  392. package/src/server/models/plugins/utils.ts +34 -0
  393. package/src/server/routes/ui/admin.ts +29 -0
  394. package/src/server/routes/ui/auth.ts +22 -0
  395. package/src/server/routes/ui/index.ts +25 -0
  396. package/src/server/routes/v1/app.route.ts +48 -0
  397. package/src/server/routes/v1/auth.route.ts +88 -0
  398. package/src/server/routes/v1/baselines.route.ts +52 -0
  399. package/src/server/routes/v1/checks.route.ts +85 -0
  400. package/src/server/routes/v1/client.route.ts +123 -0
  401. package/src/server/routes/v1/{index.js → index.route.ts} +16 -16
  402. package/src/server/routes/v1/logs.route.ts +65 -0
  403. package/src/server/routes/v1/runs.route.ts +55 -0
  404. package/src/server/routes/v1/settings.route.ts +54 -0
  405. package/src/server/routes/v1/snapshots.route.ts +32 -0
  406. package/src/server/routes/v1/suites.route.ts +52 -0
  407. package/src/server/routes/v1/tasks.route.ts +121 -0
  408. package/src/server/routes/v1/test_distinct.route.ts +32 -0
  409. package/src/server/routes/v1/tests.route.ts +90 -0
  410. package/src/server/routes/v1/users.route.ts +115 -0
  411. package/src/server/schemas/App.schema.ts +19 -0
  412. package/src/server/schemas/Auth.schema.ts +27 -0
  413. package/src/server/schemas/Baseline.schema.ts +106 -0
  414. package/src/server/schemas/Check.schema.ts +117 -0
  415. package/src/server/schemas/Client.schema.ts +380 -0
  416. package/src/server/schemas/GetBaseline.shema.ts +34 -0
  417. package/src/server/schemas/Logs.schema.ts +61 -0
  418. package/src/server/schemas/Runs.schema.ts +45 -0
  419. package/src/server/schemas/Settings.schema.ts +71 -0
  420. package/src/server/schemas/SkipValid.schema.ts +2 -0
  421. package/src/server/schemas/SnapshotDiff.schema.ts +18 -0
  422. package/src/server/schemas/Snapshots.schema.ts +42 -0
  423. package/src/server/schemas/Suite.schema.ts +34 -0
  424. package/src/server/schemas/Test.schema.ts +126 -0
  425. package/src/server/schemas/TestDistinct.schema.ts +36 -0
  426. package/src/server/schemas/User.schema.ts +59 -0
  427. package/src/server/schemas/common/ApiError.schema.ts +23 -0
  428. package/src/server/schemas/common/Error.schema.ts +19 -0
  429. package/src/server/schemas/common/RequestPagination.schema.ts +16 -0
  430. package/src/server/schemas/common/Version.schema.ts +14 -0
  431. package/src/server/schemas/common/requestQueryFilterSchema.schema.ts +32 -0
  432. package/src/server/schemas/index.ts +4 -0
  433. package/src/server/schemas/utils/commonValidations.ts +51 -0
  434. package/src/server/schemas/utils/createRequestBodySchema.ts +2 -0
  435. package/src/server/schemas/utils/createRequestOpenApiBodySchema.ts +6 -0
  436. package/src/server/schemas/utils/createRequestParamsSchema.ts +7 -0
  437. package/src/server/schemas/utils/createRequestQuerySchema.ts +2 -0
  438. package/src/server/schemas/utils/index.ts +3 -0
  439. package/src/server/server.ts +54 -0
  440. package/src/server/server_old.ts +185 -0
  441. package/src/server/services/app.service.ts +9 -0
  442. package/src/server/services/auth.service.ts +94 -0
  443. package/src/server/services/check.service.ts +241 -0
  444. package/src/server/services/client.service.ts +691 -0
  445. package/src/server/services/generic.service.ts +37 -0
  446. package/src/server/services/index.ts +24 -0
  447. package/src/server/services/logs.service.ts +27 -0
  448. package/src/server/services/run.service.ts +32 -0
  449. package/src/server/services/snapshot.service.ts +78 -0
  450. package/src/server/services/suite.service.ts +30 -0
  451. package/src/server/services/{tasks.service.js → tasks.service.ts} +157 -228
  452. package/src/server/services/test.service.ts +65 -0
  453. package/src/server/services/user.service.ts +90 -0
  454. package/src/server/utils/{ApiError.js → ApiError.ts} +5 -2
  455. package/src/server/utils/ProgressBar.ts +35 -0
  456. package/src/server/utils/ServiceResponse.ts +18 -0
  457. package/src/server/utils/buildIdentObject.ts +34 -0
  458. package/src/server/utils/calculateAcceptedStatus.ts +22 -0
  459. package/src/server/utils/catchAsync.ts +11 -0
  460. package/src/server/utils/checkIdent.ts +4 -0
  461. package/src/server/utils/dateToISO8601.ts +5 -0
  462. package/src/server/utils/deserializeIfJSON.ts +9 -0
  463. package/src/server/utils/errMsg.ts +3 -0
  464. package/src/server/utils/{formatISOToDateTime.js → formatISOToDateTime.ts} +2 -2
  465. package/src/server/utils/ident.ts +1 -0
  466. package/src/server/utils/index.ts +24 -0
  467. package/src/server/utils/isJSON.ts +14 -0
  468. package/src/server/utils/paramsGuard.ts +7 -6
  469. package/src/server/utils/pick.ts +17 -0
  470. package/src/server/utils/prettyCheckParams.ts +18 -0
  471. package/src/server/utils/removeEmptyProperties.ts +5 -0
  472. package/src/server/utils/{subDays.js → subDays.ts} +2 -2
  473. package/src/server/utils/validateRequest.ts +56 -0
  474. package/src/server/utils/waitUntil.ts +14 -0
  475. package/src/tasks/backup.ts +1 -1
  476. package/src/tasks/lib/index.ts +13 -0
  477. package/src/tasks/lib/utils.ts +14 -0
  478. package/src/tasks/migrations/2.0.migration.ts +2 -2
  479. package/src/tasks/reindex.ts +34 -0
  480. package/src/tasks/restore.ts +1 -1
  481. package/src/types/ExtRequest.ts +10 -0
  482. package/src/types/LogOpts.ts +20 -0
  483. package/src/types/Midleware.ts +3 -0
  484. package/src/types/RequestUser.ts +14 -0
  485. package/src/types/index.ts +4 -0
  486. package/src/ui-app/README.md +2 -2
  487. package/src/ui-app/auth/components/ChangePasswordForm.tsx +1 -1
  488. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Canvas/mainView.ts +3 -3
  489. package/src/ui-app/index2/components/Tests/Table/Checks/Checks.tsx +30 -2
  490. package/src/ui-app/package-lock.json +10 -16
  491. package/src/ui-app/package.json +2 -2
  492. package/src/ui-app/shared/services/checks.service.ts +1 -1
  493. package/src/ui-app/shared/services/generic.service.ts +0 -28
  494. package/src/ui-app/tsconfig.json +3 -2
  495. package/config.js +0 -17
  496. package/dist/config.js +0 -16
  497. package/dist/src/server/models/index.js +0 -508
  498. package/dist/src/server/models/plugins/index.js +0 -4
  499. package/dist/src/server/models/plugins/paginate.plugin.js +0 -76
  500. package/dist/src/server/models/plugins/paginateDistinct.plugin.js +0 -76
  501. package/dist/src/server/models/plugins/toJSON.plugin.js +0 -39
  502. package/dist/src/server/schemas/createCheck.shema.js +0 -17
  503. package/dist/src/server/schemas/getBaseline.shema.js +0 -12
  504. package/dist/src/server/utils/paramsGuard.js +0 -18
  505. package/dist/src/tasks/backup.js +0 -68
  506. package/dist/src/tasks/lib/common.js +0 -14
  507. package/dist/src/tasks/lib/utils.js +0 -14
  508. package/dist/src/tasks/migrations/2.0.migration.js +0 -86
  509. package/dist/src/tasks/migrations/2.0.migration_mql.js +0 -57
  510. package/dist/src/tasks/reindex.js +0 -28
  511. package/dist/src/tasks/restore.js +0 -86
  512. package/dist/tsconfig.tsbuildinfo +0 -1
  513. package/mvc/views/react/index.html +0 -19
  514. package/server.js +0 -166
  515. package/src/server/controllers/app.controller.js +0 -21
  516. package/src/server/controllers/auth.controller.js +0 -156
  517. package/src/server/controllers/baseline.controller.js +0 -24
  518. package/src/server/controllers/client.controller.js +0 -173
  519. package/src/server/controllers/index.js +0 -12
  520. package/src/server/controllers/logs.controller.js +0 -30
  521. package/src/server/controllers/runs.controller.js +0 -25
  522. package/src/server/controllers/settings.controller.js +0 -23
  523. package/src/server/controllers/snapshots.controller.js +0 -17
  524. package/src/server/controllers/suite.controller.js +0 -24
  525. package/src/server/controllers/tasks.controller.js +0 -47
  526. package/src/server/controllers/test.controller.js +0 -70
  527. package/src/server/controllers/users.controller.js +0 -79
  528. package/src/server/data/custom_devices.json +0 -8
  529. package/src/server/lib/AppSettings.js +0 -56
  530. package/src/server/lib/comparator.js +0 -147
  531. package/src/server/lib/compareImagesNode.js +0 -60
  532. package/src/server/lib/dbItems.js +0 -215
  533. package/src/server/lib/ensureLogin/ensureLoggedOut.js +0 -44
  534. package/src/server/lib/getElementsByPixPositionsFromDump.js +0 -72
  535. package/src/server/lib/logger.js +0 -95
  536. package/src/server/lib/onStart.js +0 -53
  537. package/src/server/lib/parseDiff.js.bak +0 -72
  538. package/src/server/middlewares/disableCors.js +0 -19
  539. package/src/server/models/index.js +0 -534
  540. package/src/server/models/plugins/index.js +0 -3
  541. package/src/server/models/plugins/paginate.plugin.js +0 -83
  542. package/src/server/models/plugins/paginateDistinct.plugin.js +0 -80
  543. package/src/server/models/plugins/toJSON.plugin.js +0 -44
  544. package/src/server/routes/ui/admin.js +0 -20
  545. package/src/server/routes/ui/auth.js +0 -15
  546. package/src/server/routes/ui/index.js +0 -19
  547. package/src/server/routes/v1/app.route.js +0 -9
  548. package/src/server/routes/v1/auth.route.js +0 -12
  549. package/src/server/routes/v1/baselines.route.js +0 -14
  550. package/src/server/routes/v1/checks.route.js +0 -25
  551. package/src/server/routes/v1/client.route.js +0 -39
  552. package/src/server/routes/v1/logs.route.js +0 -16
  553. package/src/server/routes/v1/runs.route.js +0 -15
  554. package/src/server/routes/v1/settings.route.js +0 -23
  555. package/src/server/routes/v1/snapshots.route.js +0 -11
  556. package/src/server/routes/v1/suites.route.js +0 -15
  557. package/src/server/routes/v1/tasks.route.js +0 -59
  558. package/src/server/routes/v1/test.route.js +0 -20
  559. package/src/server/routes/v1/test_distinct.route.js +0 -14
  560. package/src/server/routes/v1/users.route.js +0 -36
  561. package/src/server/schemas/getBaseline.shema.ts +0 -12
  562. package/src/server/services/app.service.js +0 -23
  563. package/src/server/services/check.service.js +0 -178
  564. package/src/server/services/client.service.js +0 -648
  565. package/src/server/services/generic.service.js +0 -51
  566. package/src/server/services/index.js +0 -12
  567. package/src/server/services/logs.service.js +0 -38
  568. package/src/server/services/run.service.js +0 -40
  569. package/src/server/services/suite.service.js +0 -39
  570. package/src/server/services/test.service.js +0 -72
  571. package/src/server/services/user.service.js +0 -128
  572. package/src/server/utils/catchAsync.js +0 -8
  573. package/src/server/utils/check.js +0 -58
  574. package/src/server/utils/dateToISO8601.js +0 -2
  575. package/src/server/utils/deserializeIfJSON.js +0 -9
  576. package/src/server/utils/index.js +0 -10
  577. package/src/server/utils/isJSON.js +0 -6
  578. package/src/server/utils/pick.js +0 -15
  579. package/src/server/utils/prettyCheckParams.js +0 -13
  580. package/src/server/utils/snapshots.js +0 -73
  581. package/src/server/utils/tests.js +0 -36
  582. package/src/server/utils/utils.js +0 -146
  583. package/src/tasks/backup.js.bak +0 -84
  584. package/src/tasks/lib/common.js +0 -24
  585. package/src/tasks/lib/utils.js +0 -15
  586. package/src/tasks/reindex.js +0 -36
  587. package/src/tasks/restore.js.bak +0 -100
  588. package/src/ui-app/tsconfig.node.json +0 -12
  589. package/static/js/canvasjs.min.js.bak +0 -957
  590. package/static/js/chart.js.bak +0 -92
  591. package/static/js/jquery-3.3.1.slim.js.bak +0 -8269
  592. package/static/js/jquery-3.3.1.slim.min.js.bak +0 -2
  593. package/static/js/moment.min.js.bak +0 -2
  594. /package/src/{server/lib → seeds}/admin.json +0 -0
  595. /package/src/{server/lib → seeds}/guest.json +0 -0
  596. /package/src/{server/lib → seeds}/initialAppSettings.json +0 -0
  597. /package/src/{server/lib/testAdmin.json → seeds/testAdmin copy.json} +0 -0
  598. /package/src/{server/lib → seeds}/testUsers.json +0 -0
  599. /package/src/server/schemas/{createCheck.shema.ts → CreateCheck.shema.ts} +0 -0
  600. /package/{static → src/server/static/static}/A.png +0 -0
  601. /package/{static → src/server/static/static}/B.png +0 -0
  602. /package/{static → src/server/static/static}/affected.html +0 -0
  603. /package/{static → src/server/static/static}/affected_2.html +0 -0
  604. /package/{static → src/server/static/static}/data/custom_devices.json +0 -0
  605. /package/{static → src/server/static/static}/grids/desktop-higher.html +0 -0
  606. /package/{static → src/server/static/static}/grids/desktop-wider.html +0 -0
  607. /package/{static → src/server/static/static}/grids/desktop.html +0 -0
  608. /package/{static → src/server/static/static}/grids/fit-in-view.html +0 -0
  609. /package/{static → src/server/static/static}/low_diff_0.png +0 -0
  610. /package/{static → src/server/static/static}/low_diff_1.png +0 -0
  611. /package/{static → src/server/static/static}/vShift.png +0 -0
  612. /package/{static → src/server/static/static}/vShift_bottom.png +0 -0
  613. /package/{static → src/server/static/static}/vShift_top.png +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/server/controllers/tasks.controller.ts","../../../src/server/utils/pick.ts","../../../src/server/utils/catchAsync.ts","../../../src/server/utils/dateToISO8601.ts","../../../src/server/utils/ProgressBar.ts","../../../src/server/utils/ApiError.ts","../../../src/server/utils/deserializeIfJSON.ts","../../../src/server/models/Check.model.ts","../../../src/server/models/plugins/paginate.plugin.ts","../../../src/server/models/plugins/toJSON.plugin.ts","../../../src/server/models/plugins/paginateDistinct.plugin.ts","../../../src/server/models/Log.model.ts","../../../src/server/models/App.model.ts","../../../src/server/models/Snapshot.model.ts","../../../src/server/models/AppSettings.model.ts","../../../src/server/models/Suite.model.ts","../../../src/server/models/Run.model.ts","../../../src/server/models/User.model.ts","../../../src/server/models/Baseline.model.ts","../../../src/server/models/Test.model.ts","../../../src/server/utils/subDays.ts","../../../src/server/lib/logger.ts","../../../src/server/utils/formatISOToDateTime.ts","../../../src/server/config.ts","../../../package.json","../../../src/server/envConfig.ts","../../../src/server/data/devices.json","../../../src/server/services/run.service.ts","../../../src/server/services/suite.service.ts","../../../src/server/services/generic.service.ts","../../../src/server/services/tasks.service.ts","../../../src/seeds/testAdmin.json","../../../src/server/services/client.service.ts","../../../src/server/lib/dbItems/updateItem.ts","../../../src/server/lib/dbItems/updateItemDate.ts","../../../src/server/lib/dbItems/createItemIfNotExist.ts","../../../src/server/lib/dbItems/createItemProm.ts","../../../src/server/lib/сomparison/compareImagesNode.ts","../../../src/server/services/user.service.ts"],"sourcesContent":["import { catchAsync, pick } from '@utils';\nimport { tasksService } from '@services';\nimport { Response } from \"express\";\nimport { ExtRequest } from '@types';\n\n\nconst task_test = catchAsync(async (req: ExtRequest, res: Response) => {\n const { options } = pick(req.query, ['options']);\n await tasksService.task_test(String(options), req, res);\n});\n\nconst task_handle_old_checks = catchAsync(async (req: ExtRequest, res: Response) => {\n const options = pick(req.query, ['days', 'remove']);\n await tasksService.task_handle_old_checks(options, res);\n});\n\nconst task_handle_database_consistency = catchAsync(async (req: ExtRequest, res: Response) => {\n const options = pick(req.query, ['days', 'clean']);\n await tasksService.task_handle_database_consistency(options, res);\n});\n\nconst task_remove_old_logs = catchAsync(async (req: ExtRequest, res: Response) => {\n const options = pick(req.query, ['days', 'statistics']);\n await tasksService.task_remove_old_logs(options, res);\n});\n\nconst status = catchAsync(async (req: ExtRequest, res: Response) => {\n res.send(await tasksService.status(req.user));\n});\n\nconst screenshots = catchAsync(async (req: ExtRequest, res: Response) => {\n res.send(await tasksService.screenshots());\n});\n\nconst loadTestUser = catchAsync(async (req: ExtRequest, res: Response) => {\n res.send(await tasksService.loadTestUser());\n});\n\nexport {\n task_test,\n task_handle_old_checks,\n task_handle_database_consistency,\n task_remove_old_logs,\n status,\n loadTestUser,\n screenshots,\n};\n","/**\n * Create an object composed of the picked object properties\n * @param {T} object input object\n * @param {Array<keyof T>} keys fields to pick\n * @returns {Partial<T>} new object\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst pick = <T extends Record<string, any>>(object: T, keys: Array<keyof T>): Partial<T> => {\n return keys.reduce((obj, key) => {\n if (object && Object.prototype.hasOwnProperty.call(object, key)) {\n if (object[key] !== undefined) obj[key] = object[key];\n }\n return obj;\n }, {} as Partial<T>);\n};\n\nexport default pick;\n","import { Response, NextFunction } from 'express';\nimport { ExtRequest } from '@types';\n\nconst catchAsync = (fn: (req: ExtRequest, res: Response, next: NextFunction) => Promise<void>) =>\n (req: ExtRequest, res: Response, next: NextFunction) => {\n Promise.resolve(fn(req, res, next)).catch((err) => {\n return next(err);\n });\n };\n\nexport default catchAsync;\n","const dateToISO8601 = (date: string | Date): string => {\n return new Date(new Date(date)).toISOString().split('T')[0];\n};\n\nexport default dateToISO8601;\n","import { Response } from 'express';\n\nexport class ProgressBar {\n length: number;\n percentLenght: number;\n prevPercent: number;\n currentPercent: number;\n progressString: string;\n\n constructor(length: number) {\n this.length = length;\n this.percentLenght = parseFloat((length / 100).toString());\n this.prevPercent = 0;\n this.currentPercent = 0;\n this.progressString = '';\n }\n\n isChange(current: number): boolean {\n this.currentPercent = parseInt((current / this.percentLenght).toString(), 10);\n if (this.prevPercent === this.currentPercent) {\n return false;\n }\n this.prevPercent = this.currentPercent;\n this.progressString += '#';\n return true;\n }\n\n writeIfChange(index: number, count: number, fn: (message: string, res: Response) => void, res: Response): void {\n if (this.isChange(index)) {\n const placeholderString = Array.from(new Array(99 - this.currentPercent))\n .reduce((accum) => accum += '.', '');\n fn(`[${this.progressString}${placeholderString}](${index}/${count})`, res);\n }\n }\n}\n","class ApiError extends Error {\n statusCode: number;\n isOperational: boolean;\n\n constructor(statusCode: number, message: string, isOperational: boolean = true, stack: string = '') {\n super(message);\n this.statusCode = statusCode;\n this.isOperational = isOperational;\n if (stack) {\n this.stack = stack;\n } else {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\nexport default ApiError;\n","import { EJSON } from 'bson';\nimport { isJSON } from '.';\n\nconst deserializeIfJSON = (text: string) => {\n if (isJSON(text)) return EJSON.parse(text) || undefined;\n return text;\n};\n\nexport default deserializeIfJSON;\n","import mongoose, { Schema, Document, Model } from 'mongoose';\nimport { toJSON, paginate } from './plugins';\nimport { PluginExtededModel } from './plugins/utils';\n\nexport interface CheckDocument extends Document {\n name: string;\n test: Schema.Types.ObjectId;\n suite: Schema.Types.ObjectId;\n app: Schema.Types.ObjectId;\n branch?: string;\n realBaselineId?: Schema.Types.ObjectId;\n baselineId?: Schema.Types.ObjectId;\n actualSnapshotId?: Schema.Types.ObjectId;\n diffId?: Schema.Types.ObjectId;\n createdDate: Date;\n updatedDate?: Date;\n // status: ['new', 'pending', 'approved', 'running', 'passed', 'failed', 'aborted'];\n status: ('new' | 'pending' | 'approved' | 'running' | 'passed' | 'failed' | 'aborted' | 'blinking')[];\n browserName?: string;\n browserVersion?: string;\n browserFullVersion?: string;\n viewport?: string;\n os?: string;\n domDump?: string;\n result?: string;\n run?: Schema.Types.ObjectId;\n markedAs?: 'bug' | 'accepted';\n markedDate?: Date;\n markedById?: Schema.Types.ObjectId;\n markedByUsername?: string;\n markedBugComment?: string;\n creatorId?: Schema.Types.ObjectId;\n creatorUsername?: string;\n failReasons?: string[];\n vOffset?: string;\n topStablePixels?: string;\n meta?: Record<string, unknown>;\n}\n\n// const CheckSchema: Schema<CheckDocument> = new Schema({\nconst CheckSchema = new Schema<CheckDocument>({\n name: {\n type: String,\n required: [true, 'CheckSchema: The \"name\" field must be required'],\n },\n test: {\n type: Schema.Types.ObjectId,\n ref: 'VRSTest',\n required: [true, 'CheckSchema: The \"test\" field must be required'],\n },\n suite: {\n type: Schema.Types.ObjectId,\n ref: 'VRSSuite',\n required: [true, 'CheckSchema: The \"suite\" field must be required'],\n },\n app: {\n type: Schema.Types.ObjectId,\n ref: 'VRSApp',\n required: [true, 'CheckSchema: The \"app\" field must be required'],\n },\n branch: {\n type: String,\n },\n realBaselineId: {\n type: Schema.Types.ObjectId,\n ref: 'VRSBaseline',\n },\n baselineId: {\n type: Schema.Types.ObjectId,\n ref: 'VRSSnapshot',\n },\n actualSnapshotId: {\n type: Schema.Types.ObjectId,\n ref: 'VRSSnapshot',\n },\n diffId: {\n type: Schema.Types.ObjectId,\n ref: 'VRSSnapshot',\n },\n createdDate: {\n type: Date,\n required: true,\n default: Date.now,\n },\n updatedDate: {\n type: Date,\n },\n status: {\n type: [{\n type: String,\n enum: {\n values: ['new', 'pending', 'approved', 'running', 'passed', 'failed', 'aborted'],\n message: 'status is required',\n },\n }],\n default: ['new'],\n },\n browserName: {\n type: String,\n },\n browserVersion: {\n type: String,\n },\n browserFullVersion: {\n type: String,\n },\n viewport: {\n type: String,\n },\n os: {\n type: String,\n },\n domDump: {\n type: String,\n },\n result: {\n type: String,\n default: '{}',\n },\n run: {\n type: Schema.Types.ObjectId,\n },\n markedAs: {\n type: String,\n enum: ['bug', 'accepted'],\n },\n markedDate: {\n type: Date,\n },\n markedById: {\n type: Schema.Types.ObjectId,\n ref: 'VRSUser',\n },\n markedByUsername: {\n type: String,\n },\n markedBugComment: {\n type: String,\n },\n creatorId: {\n type: Schema.Types.ObjectId,\n ref: 'VRSUser',\n },\n creatorUsername: {\n type: String,\n },\n failReasons: {\n type: [String],\n },\n vOffset: {\n type: String,\n },\n topStablePixels: {\n type: String,\n },\n meta: {\n type: Object,\n },\n});\n\nCheckSchema.plugin(toJSON);\nCheckSchema.plugin(paginate);\n\nconst Check: Model<CheckDocument> = mongoose.model<CheckDocument>('VRSCheck', CheckSchema);\nexport default Check as PluginExtededModel<CheckDocument>;\n\n","import { Schema, Document, FilterQuery } from 'mongoose';\nimport { PaginateOptions, QueryResult } from './utils';\n\nconst paginate = (schema: Schema) => {\n /**\n * Query for documents with pagination\n * @param {Object} [filter] - Mongo filter\n * @param {Object} [options] - Query options\n * @param {string} [options.sortBy] - Sorting criteria using the format: sortField:(desc|asc).\n * Multiple sorting criteria should be separated by commas (,)\n * @param {string} [options.populate] - Populate data fields. Hierarchy of fields should be separated by (.).\n * Multiple populating criteria should be separated by commas (,)\n * @param {number} [options.limit] - Maximum number of results per page (default = 10)\n * @param {number} [options.page] - Current page (default = 1)\n * @returns {Promise<QueryResult>}\n */\n schema.statics.paginate = async function (filter: FilterQuery<unknown>, options: PaginateOptions): Promise<QueryResult> {\n let sort: string | object;\n if (options.sortBy) {\n const sortingCriteria: string[] = [];\n options.sortBy.split(',')\n .forEach((sortOption: string) => {\n const [key, order] = sortOption.split(':');\n sortingCriteria.push((order === 'desc' ? '-' : '') + key);\n });\n sort = sortingCriteria.join(' ');\n } else {\n sort = { _id: -1 };\n }\n\n const limit = options.limit && parseInt(options.limit.toString(), 10) >= 0 ? parseInt(options.limit.toString(), 10) : 10;\n const page = options.page && parseInt(options.page.toString(), 10) > 0 ? parseInt(options.page.toString(), 10) : 1;\n const skip = (page - 1) * limit;\n\n const countPromise = this.countDocuments(filter).exec();\n let docsPromise = this.find(filter)\n .sort(sort)\n .skip(skip)\n .limit(limit);\n\n if (options.populate) {\n options.populate.split(',')\n .forEach((populateOption: string) => {\n docsPromise = docsPromise.populate(\n populateOption\n .split('.')\n .reverse()\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n .reduce((a, b) => ({ path: b, populate: a }))\n );\n });\n }\n\n docsPromise = docsPromise.exec();\n\n return Promise.all([countPromise, docsPromise])\n .then((values: [number, Document[]]) => {\n const [totalResults, results] = values;\n const totalPages = Math.ceil(totalResults / limit);\n const result: QueryResult = {\n results,\n page,\n limit,\n totalPages,\n totalResults,\n timestamp: Number(Date.now() + String(process.hrtime()[1]).slice(3, 6)),\n };\n return Promise.resolve(result);\n });\n };\n};\n\nexport default paginate;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable no-param-reassign */\n\n// import { Schema } from 'mongoose';\n\nconst deleteAtPath = (obj: any, path: string[], index: number): void => {\n if (index === path.length - 1) {\n delete obj[path[index]];\n return;\n }\n deleteAtPath(obj[path[index]], path, index + 1);\n};\n\nconst toJSON = (schema: any): void => {\n let transform: any;\n if (schema.options.toJSON && schema.options.toJSON.transform) {\n transform = schema.options.toJSON.transform;\n }\n\n schema.options.toJSON = Object.assign(schema.options.toJSON || {}, {\n transform(doc: any, ret: any, options: any) {\n Object.keys(schema.paths).forEach((path) => {\n if (schema.paths[path].options && schema.paths[path].options.private) {\n deleteAtPath(ret, path.split('.'), 0);\n }\n });\n\n ret.id = ret._id.toString();\n // delete ret._id;\n // eslint-disable-next-line no-underscore-dangle\n delete ret.__v;\n delete ret.createdAt;\n delete ret.updatedAt;\n if (transform) {\n return transform(doc, ret, options);\n }\n },\n });\n};\n\nexport default toJSON;\n","import { Schema, Document, FilterQuery } from 'mongoose';\nimport { EJSON } from 'bson';\nimport { PaginateOptions, QueryResult } from './utils';\n\n// type QueryResult = {\n// results: Document[];\n// page: number;\n// limit: number;\n// totalPages: number;\n// totalResults: number;\n// timestamp: number;\n// };\n\n// type PaginateOptions = {\n// sortBy?: string;\n// populate?: string;\n// limit?: number;\n// page?: number;\n// field: string;\n// };\n\nconst paginateDistinct = (schema: Schema): void => {\n /**\n * Query for documents with pagination\n * @param {Object} [filter] - Mongo filter\n * @param {Object} [options] - Query options\n * @param {string} [options.sortBy] - Sorting criteria using the format: sortField:(desc|asc).\n * Multiple sorting criteria should be separated by commas (,)\n * @param {string} [options.populate] - Populate data fields. Hierarchy of fields should be separated by (.).\n * Multiple populating criteria should be separated by commas (,)\n * @param {number} [options.limit] - Maximum number of results per page (default = 10)\n * @param {number} [options.page] - Current page (default = 1)\n * @returns {Promise<QueryResult>}\n */\n schema.statics.paginateDistinct = async function (filter: FilterQuery<unknown>, options: PaginateOptions): Promise<QueryResult> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let sort: any;\n if (options.sortBy) {\n options.sortBy.split(',')\n .forEach((sortOption: string) => {\n const [key, order] = sortOption.split(':');\n sort[key] = (order === 'desc') ? -1 : 1;\n });\n } else {\n sort = { _id: -1 };\n }\n\n let limit = options.limit && parseInt(options.limit.toString(), 10) >= 0 ? parseInt(options.limit.toString(), 10) : 10;\n limit = limit === 0 ? 9007199254740991 : limit;\n const page = options.page && parseInt(options.page.toString(), 10) > 0 ? parseInt(options.page.toString(), 10) : 1;\n const skip = (page - 1) * limit;\n\n const groupAggregateObj = { $group: { _id: `$${options.field}` } };\n\n const documentsCount = (await this.aggregate([groupAggregateObj])\n .exec()).length;\n const aggregateArr = [\n { $match: EJSON.parse(filter.filter || '{}') },\n groupAggregateObj,\n { $sort: sort },\n { $skip: skip },\n { $limit: limit },\n ];\n const aggregatedDocs = (await this.aggregate(aggregateArr))\n .filter((x) => x._id)\n .map((x) => {\n if (x[options.field!]) {\n return x[options.field!][0];\n }\n return { name: x._id };\n });\n\n return Promise.all([documentsCount, aggregatedDocs])\n .then((values: [number, Document[]]) => {\n const [totalResults, results] = values;\n const totalPages = Math.ceil(totalResults / limit);\n const result: QueryResult = {\n results,\n page,\n limit,\n totalPages,\n totalResults,\n timestamp: new Date().getTime(),\n };\n return Promise.resolve(result);\n });\n };\n};\n\nexport default paginateDistinct;\n","import mongoose, { Schema, Document, Model } from 'mongoose';\nimport { toJSON, paginate } from './plugins';\nimport { PluginExtededModel } from './plugins/utils';\n\nexport interface LogDocument extends Document {\n timestamp?: Date;\n level?: string;\n message?: string;\n meta?: Record<string, unknown>;\n hostname?: string;\n}\n\nconst LogSchema: Schema<LogDocument> = new Schema({\n timestamp: {\n type: Date,\n },\n level: {\n type: String,\n },\n message: {\n type: String,\n },\n meta: {\n type: Object,\n },\n hostname: {\n type: Object,\n },\n});\n\nLogSchema.plugin(toJSON);\nLogSchema.plugin(paginate);\n\nconst Log: Model<LogDocument> = mongoose.model<LogDocument>('VRSLog', LogSchema);\nexport default Log as PluginExtededModel<LogDocument>;\n\n","import mongoose, { Schema, Document, Model } from 'mongoose';\nimport { toJSON, paginate } from './plugins';\nimport { PluginExtededModel } from './plugins/utils';\n\nexport interface AppDocument extends Document {\n name: string;\n description?: string;\n version?: string;\n updatedDate?: Date;\n createdDate?: Date;\n meta?: Record<string, unknown>;\n}\n\nconst AppSchema: Schema<AppDocument> = new Schema({\n name: {\n type: String,\n default: 'Others',\n unique: true,\n required: [true, 'AppSchema: The \"name\" field must be required'],\n },\n description: {\n type: String,\n },\n version: {\n type: String,\n },\n updatedDate: {\n type: Date,\n },\n createdDate: {\n type: Date,\n },\n meta: {\n type: Object,\n },\n});\n\nAppSchema.plugin(paginate);\nAppSchema.plugin(toJSON);\n\nconst App: Model<AppDocument> = mongoose.model<AppDocument>('VRSApp', AppSchema);\nexport default App as PluginExtededModel<AppDocument>;\n","import mongoose, { Schema, Document, Model } from 'mongoose';\nimport { toJSON, paginate } from './plugins';\nimport { PluginExtededModel } from './plugins/utils';\n\nexport interface SnapshotDocument extends Document {\n name: string;\n path?: string;\n filename?: string;\n imghash: string;\n createdDate?: Date;\n vOffset?: number;\n hOffset?: number;\n}\n\nconst SnapshotSchema: Schema<SnapshotDocument> = new Schema({\n name: {\n type: String,\n required: [true, 'SnapshotSchema: The \"name\" field must be required'],\n },\n path: {\n type: String,\n },\n filename: {\n type: String,\n },\n imghash: {\n type: String,\n required: [true, 'SnapshotSchema: The \"imghash\" field must be required'],\n },\n createdDate: {\n type: Date,\n default: Date.now,\n },\n vOffset: {\n type: Number,\n },\n hOffset: {\n type: Number,\n },\n});\n\nSnapshotSchema.plugin(toJSON);\nSnapshotSchema.plugin(paginate);\n\nconst Snapshot: Model<SnapshotDocument> = mongoose.model<SnapshotDocument>('VRSSnapshot', SnapshotSchema);\n\nexport default Snapshot as PluginExtededModel<SnapshotDocument>;\n","import mongoose, { Schema, Document, Model } from 'mongoose';\nimport { toJSON } from './plugins';\nimport { PluginExtededModel } from './plugins/utils';\n\nexport interface AppSettingsDocument extends Document {\n name: string;\n label: string;\n description?: string;\n type: { [key: string]: string };\n value: Schema.Types.Mixed;\n env_variable?: string;\n enabled?: boolean;\n}\n\nconst AppSettingsSchema: Schema<AppSettingsDocument> = new Schema({\n name: {\n type: String,\n unique: true,\n required: [true, 'AppSettingsSchema: The \"name\" field must be required'],\n },\n label: {\n type: String,\n required: [true, 'AppSettingsSchema: The \"label\" field must be required'],\n },\n description: {\n type: String,\n },\n type: {\n type: String,\n required: [true, 'AppSettingsSchema: The \"type\" field must be required'],\n },\n value: {\n type: Schema.Types.Mixed,\n required: [true, 'AppSettingsSchema: The \"value\" field must be required'],\n },\n env_variable: {\n type: String,\n },\n enabled: {\n type: Boolean,\n },\n});\n\nAppSettingsSchema.plugin(toJSON);\n\nconst AppSettings: Model<AppSettingsDocument> = mongoose.model<AppSettingsDocument>('VRSAppSettings', AppSettingsSchema);\nexport default AppSettings as PluginExtededModel<AppSettingsDocument>;\n\n","import mongoose, { Schema, Document, Model } from 'mongoose';\nimport { toJSON, paginate } from './plugins';\nimport { PluginExtededModel } from './plugins/utils';\n\nexport interface SuiteDocument extends Document {\n name: string;\n tags?: string[];\n app: Schema.Types.ObjectId;\n description?: string;\n updatedDate?: Date;\n createdDate?: Date;\n meta?: Record<string, unknown>;\n}\n\nconst SuiteSchema: Schema<SuiteDocument> = new Schema({\n name: {\n type: String,\n default: 'Others',\n unique: true,\n required: [true, 'SuiteSchema: The \"name\" field must be required'],\n },\n tags: {\n type: [String],\n },\n app: {\n type: Schema.Types.ObjectId,\n ref: 'VRSApp',\n required: [true, 'SuiteSchema: The \"app\" field must be required'],\n },\n description: {\n type: String,\n },\n updatedDate: {\n type: Date,\n default: Date.now,\n },\n createdDate: {\n type: Date,\n },\n meta: {\n type: Object,\n },\n});\n\nSuiteSchema.plugin(paginate);\nSuiteSchema.plugin(toJSON);\n\nconst Suite: Model<SuiteDocument> = mongoose.model<SuiteDocument>('VRSSuite', SuiteSchema);\n\nexport default Suite as PluginExtededModel<SuiteDocument>;\n","\nimport mongoose, { Schema, Document, Model } from 'mongoose';\nimport { toJSON, paginate } from './plugins';\nimport { PluginExtededModel } from './plugins/utils';\n\nexport interface RunDocument extends Document {\n name: string;\n app: Schema.Types.ObjectId;\n ident: string;\n description?: string;\n updatedDate?: Date;\n createdDate?: Date;\n parameters?: string[];\n meta?: Record<string, unknown>;\n}\n\nconst RunSchema: Schema<RunDocument> = new Schema({\n name: {\n type: String,\n required: [true, 'RunSchema: The \"name\" field must be required'],\n },\n app: {\n type: Schema.Types.ObjectId,\n ref: 'VRSApp',\n required: [true, 'RunSchema: The \"app\" field must be required'],\n },\n ident: {\n type: String,\n unique: true,\n required: [true, 'RunSchema: The \"ident\" field must be required'],\n },\n description: {\n type: String,\n },\n updatedDate: {\n type: Date,\n default: Date.now,\n },\n createdDate: {\n type: Date,\n },\n parameters: {\n type: [String],\n },\n meta: {\n type: Object,\n },\n});\n\nRunSchema.plugin(paginate);\nRunSchema.plugin(toJSON);\n\nconst Run: Model<RunDocument> = mongoose.model<RunDocument>('VRSRun', RunSchema);\nexport default Run as PluginExtededModel<RunDocument>;\n\n","import mongoose, { Schema, Document, Model } from 'mongoose';\nimport passportLocalMongoose from 'passport-local-mongoose';\nimport { toJSON, paginate } from './plugins';\nimport { PluginExtededModel } from './plugins/utils';\n\nexport type UserRole = 'admin' | 'reviewer' | 'user';\n\nexport interface UserDocument extends Document {\n username: string;\n firstName: string;\n lastName: string;\n role: UserRole;\n password?: string;\n token?: string;\n apiKey?: string;\n createdDate?: Date;\n updatedDate?: Date;\n expiration?: Date;\n meta?: Record<string, unknown>;\n isEmailTaken: (username: string) => Promise<boolean>;\n setPassword: (password: string) => Promise<UserDocument>;\n}\n\nconst UserSchema = new Schema<UserDocument>({\n username: {\n type: String,\n unique: true,\n required: [true, 'UserSchema: The \"username\" field must be required'],\n },\n firstName: {\n type: String,\n required: [true, 'UserSchema: The \"firstName\" field must be required'],\n },\n lastName: {\n type: String,\n required: [true, 'UserSchema: The \"lastName\" field must be required'],\n },\n role: {\n type: String,\n enum: ['admin', 'reviewer', 'user'],\n required: [true, 'UserSchema: The \"role\" field must be required'],\n },\n password: {\n type: String,\n },\n token: {\n type: String,\n },\n apiKey: {\n type: String,\n },\n createdDate: {\n type: Date,\n },\n updatedDate: {\n type: Date,\n },\n expiration: {\n type: Date,\n },\n meta: {\n type: Object,\n },\n});\n\nUserSchema.statics.isEmailTaken = async function (username, excludeUserId) {\n const user = await this.findOne({ username, _id: { $ne: excludeUserId } });\n return !!user;\n};\n\nUserSchema.plugin(toJSON);\nUserSchema.plugin(paginate);\nUserSchema.plugin(passportLocalMongoose, { hashField: 'password' });\n\nconst User: Model<UserDocument> = mongoose.model<UserDocument>('VRSUser', UserSchema);\n\nexport default User as PluginExtededModel<UserDocument>;","import mongoose, { Schema, Document, Model } from 'mongoose';\nimport { toJSON, paginate } from './plugins';\nimport { PluginExtededModel } from './plugins/utils';\n\nexport interface BaselineDocument extends Document {\n snapshootId: Schema.Types.ObjectId;\n name: string;\n app: Schema.Types.ObjectId;\n branch?: string;\n browserName?: string;\n browserVersion?: string;\n browserFullVersion?: string;\n viewport?: string;\n os?: string;\n markedAs?: 'bug' | 'accepted';\n lastMarkedDate?: Date;\n createdDate?: Date;\n updatedDate?: Date;\n markedById?: Schema.Types.ObjectId;\n markedByUsername?: string;\n ignoreRegions?: string;\n boundRegions?: string;\n matchType?: 'antialiasing' | 'nothing' | 'colors';\n meta?: Record<string, unknown>;\n}\n\nconst BaselineSchema: Schema<BaselineDocument> = new Schema({\n snapshootId: {\n type: Schema.Types.ObjectId,\n },\n name: {\n type: String,\n required: [true, 'VRSBaselineSchema: The \"name\" field must be required'],\n },\n app: {\n type: Schema.Types.ObjectId,\n ref: 'VRSApp',\n required: [true, 'VRSBaselineSchema: The \"app\" field must be required'],\n },\n branch: {\n type: String,\n },\n browserName: {\n type: String,\n },\n browserVersion: {\n type: String,\n },\n browserFullVersion: {\n type: String,\n },\n viewport: {\n type: String,\n },\n os: {\n type: String,\n },\n markedAs: {\n type: String,\n enum: ['bug', 'accepted'],\n },\n lastMarkedDate: {\n type: Date,\n },\n createdDate: {\n type: Date,\n },\n updatedDate: {\n type: Date,\n },\n markedById: {\n type: Schema.Types.ObjectId,\n ref: 'VRSUser',\n },\n markedByUsername: {\n type: String,\n },\n ignoreRegions: {\n type: String,\n },\n boundRegions: {\n type: String,\n },\n matchType: {\n type: String,\n enum: ['antialiasing', 'nothing', 'colors'],\n },\n meta: {\n type: Object,\n },\n});\n\nBaselineSchema.plugin(toJSON);\nBaselineSchema.plugin(paginate);\n\nconst Baseline: Model<BaselineDocument> = mongoose.model<BaselineDocument>('VRSBaseline', BaselineSchema);\nexport default Baseline as PluginExtededModel<BaselineDocument>;\n\n","import mongoose, { Schema, Document, Model } from 'mongoose';\nimport { toJSON, paginate, paginateDistinct } from './plugins';\nimport { PluginExtededModel } from './plugins/utils';\n\nexport interface TestDocument extends Document {\n name: string;\n description?: string;\n status?: string;\n browserName: string;\n browserVersion: string;\n branch?: string;\n tags?: string[];\n viewport: string;\n calculatedViewport?: string;\n // calculatedStatus?: string;\n os: string;\n app: Schema.Types.ObjectId;\n blinking?: number;\n updatedDate: Date;\n startDate: Date;\n checks?: Schema.Types.ObjectId[];\n suite?: Schema.Types.ObjectId;\n run: Schema.Types.ObjectId;\n markedAs?: 'Bug' | 'Accepted' | 'Unaccepted' | 'Partially';\n creatorId?: Schema.Types.ObjectId;\n creatorUsername?: string;\n meta?: Record<string, unknown>;\n}\n\nconst TestSchema: Schema<TestDocument> = new Schema(\n {\n name: {\n type: String,\n required: 'TestSchema: the test name is empty',\n },\n description: {\n type: String,\n },\n status: {\n type: String,\n },\n browserName: {\n type: String,\n },\n browserVersion: {\n type: String,\n },\n branch: {\n type: String,\n },\n tags: {\n type: [String],\n },\n viewport: {\n type: String,\n },\n calculatedViewport: {\n type: String,\n },\n os: {\n type: String,\n },\n app: {\n type: Schema.Types.ObjectId,\n ref: 'VRSApp',\n required: [true, 'TestSchema: The \"app\" field must be required'],\n\n },\n blinking: {\n type: Number,\n default: 0,\n },\n updatedDate: {\n type: Date,\n },\n startDate: {\n type: Date,\n },\n checks: [\n {\n type: mongoose.Schema.Types.ObjectId,\n ref: 'VRSCheck',\n },\n ],\n suite: {\n type: Schema.Types.ObjectId,\n ref: 'VRSSuite',\n },\n run: {\n type: Schema.Types.ObjectId,\n ref: 'VRSRun',\n },\n markedAs: {\n type: String,\n enum: ['Bug', 'Accepted', 'Unaccepted', 'Partially'],\n },\n creatorId: {\n type: Schema.Types.ObjectId,\n ref: 'VRSUser',\n },\n creatorUsername: {\n type: String,\n },\n meta: {\n type: Object,\n },\n },\n { strictQuery: true }\n);\n\nTestSchema.plugin(toJSON);\nTestSchema.plugin(paginate);\nTestSchema.plugin(paginateDistinct);\n\nconst Test: Model<TestDocument> = mongoose.model<TestDocument>('VRSTest', TestSchema);\n\nexport default Test as PluginExtededModel<TestDocument>;\n","const subDays = (date: Date, days: number): Date => {\n const result = new Date(date);\n result.setDate(result.getDate() - days);\n return result;\n};\n\nexport default subDays;\n","import winston, { Logger as WinstonLogger } from 'winston';\nimport 'winston-mongodb';\nimport { blue, gray, magenta } from 'chalk';\nimport formatISOToDateTime from '@utils/formatISOToDateTime';\nimport { config } from '@config';\nimport path from 'path';\nimport { LogOpts } from '@types';\nimport { ApiError } from '../utils';\nimport { env } from \"@env\";\n\nconst logLevel: string = env.SYNGRISI_LOG_LEVEL;\n\ninterface LoggerOptions {\n dbConnectionString: string;\n}\nfunction getScriptLine(): string {\n const stack = new Error().stack;\n\n if (stack) {\n const stackLines = stack.split('\\n');\n let loggerLineIndex = -1;\n\n // last string contains 'lib/logger'\n for (let i = 0; i < stackLines.length; i++) {\n if (stackLines[i].includes('lib/logger')) {\n loggerLineIndex = i;\n }\n }\n\n // check string after 'lib/logger'\n const targetLineIndex = loggerLineIndex + 1;\n if (targetLineIndex >= 0 && targetLineIndex < stackLines.length) {\n const targetLine = stackLines[targetLineIndex];\n const match = targetLine.match(/at\\s+(?:.+\\s+\\()?(.+):(\\d+):(\\d+)\\)?/);\n if (match) {\n const scriptPath = match[1];\n const relativePath = path.relative(process.cwd(), scriptPath);\n const lineNumber = match[2];\n return `${relativePath}:${lineNumber}`;\n }\n }\n }\n return 'unknown';\n}\n\nfunction createWinstonLogger(opts: LoggerOptions): WinstonLogger {\n return winston.createLogger({\n transports: [\n new winston.transports.Console({\n level: logLevel || 'silly',\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.timestamp(),\n winston.format.ms(),\n winston.format.metadata(),\n winston.format.printf((info) => {\n const user = info.metadata.user ? blue(` <${info.metadata.user}>`) : '';\n const ref = info.metadata.ref ? gray(` ${info.metadata.ref}`) : '';\n const msgType = info.metadata.msgType ? ` ${info.metadata.msgType}` : '';\n const itemType = info.metadata.itemType ? magenta(` ${info.metadata.itemType}`) : '';\n const scope = info.metadata.scope ? magenta(` [${info.metadata.scope}] `) : magenta(` [${getScriptLine()}] `);\n const msg = typeof info.message === 'object'\n ? `\\n${JSON.stringify(info.message, null, 2)}`\n : info.message;\n\n return `${info.level} ${scope}${formatISOToDateTime(info.metadata.timestamp)} `\n + `${info.metadata.ms}${user}${ref}${msgType}${itemType} '${msg}'`;\n }),\n winston.format.padLevels(),\n ),\n }),\n new winston.transports.MongoDB({\n level: logLevel || 'debug',\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.json(),\n winston.format.metadata(),\n ),\n options: {\n useUnifiedTopology: true,\n },\n db: opts.dbConnectionString,\n collection: 'vrslogs',\n }),\n ],\n });\n}\n\nclass Logger {\n private winstonLogger: WinstonLogger;\n\n constructor(opts: LoggerOptions = { dbConnectionString: config.connectionString }) {\n this.winstonLogger = createWinstonLogger(opts);\n }\n\n private static mergeMeta(objects: LogOpts[]): LogOpts {\n return objects.reduce((acc, obj) => {\n return { ...acc, ...obj };\n }, {});\n }\n\n private log(severity: string, msg: string | object, meta: LogOpts[]): void {\n const mergedMeta = Logger.mergeMeta(meta);\n if (!mergedMeta.scope) {\n mergedMeta.scope = getScriptLine();\n }\n const formattedMsg = typeof msg === 'object' ? JSON.stringify(msg, null, 2) : msg;\n this.winstonLogger.log(severity, formattedMsg, mergedMeta);\n }\n\n public error(msg: string | object | unknown, ...meta: LogOpts[]): void {\n let message: unknown = String(msg);\n let code = 0;\n if ((msg instanceof Object)) {\n message = JSON.stringify(msg);\n }\n if ((msg instanceof Error)) {\n message = msg.stack;\n }\n if ((msg instanceof ApiError)) {\n code = msg.statusCode;\n }\n this.log('error', `${code !== 0 ? '[' + code + ']' : ''}${message}\\n stacktrace: ${new Error().stack}`, meta);\n }\n\n public warn(msg: string | object, ...meta: LogOpts[]): void {\n this.log('warn', `${msg}\\n stacktrace: ${new Error().stack}`, meta);\n }\n\n public info(msg: string | object, ...meta: LogOpts[]): void {\n this.log('info', msg, meta);\n }\n\n public verbose(msg: string | object, ...meta: LogOpts[]): void {\n this.log('verbose', msg, meta);\n }\n\n public debug(msg: string | object, ...meta: LogOpts[]): void {\n this.log('debug', msg, meta);\n }\n\n public silly(msg: string | object, ...meta: LogOpts[]): void {\n this.log('silly', msg, meta);\n }\n}\n\nexport default new Logger();\n","function formatISOToDateTime(isoDateString: string): string {\n const date = new Date(isoDateString);\n return `${date.toISOString().slice(0, 10)} ${date.toTimeString().slice(0, 8)}`;\n}\n\nexport default formatISOToDateTime;\n","import fs from 'fs';\nimport dotenv from 'dotenv';\nimport { version } from '@root/package.json';\nimport crypto from 'crypto';\nimport { env } from \"./envConfig\";\n\nimport devices from \"./data/devices.json\";\nconst customDevicesPath = './server/data/custom_devices.json';\nconst logsFolder = './logs';\ndotenv.config();\n\nexport const config = {\n version,\n // this isn't used \n getDevices: async () => {\n if (fs.existsSync(customDevicesPath)) {\n return [...devices, ...(await import(customDevicesPath)).default];\n }\n return devices;\n },\n defaultImagesPath: env.SYNGRISI_IMAGES_PATH,\n connectionString: env.SYNGRISI_DB_URI || 'mongodb://127.0.0.1:27017/SyngrisiDb',\n host: env.SYNGRISI_HOSTNAME,\n port: env.SYNGRISI_APP_PORT || 3000,\n backupsFolder: './backups',\n enableHttpLogger: env.SYNGRISI_HTTP_LOG,\n httpLoggerFilePath: `${logsFolder}/http.log`,\n storeSessionKey: env.SYNGRISI_SESSION_STORE_KEY || crypto.randomBytes(64).toString('hex'),\n codeCoverage: env.SYNGRISI_COVERAGE,\n disableCors: env.SYNGRISI_DISABLE_DEV_CORS,\n fileUploadMaxSize: 50 * 1024 * 1024,\n testMode: env.SYNGRISI_TEST_MODE,\n jsonLimit: '50mb',\n tmpDir: env.SYNGRISI_TMP_DIR,\n helmet: {\n crossOriginEmbedderPolicy: !env.SYNGRISI_DISABLE_DEV_CORS,\n crossOriginResourcePolicy: !env.SYNGRISI_DISABLE_DEV_CORS,\n contentSecurityPolicy: {\n directives: {\n frameAncestors: [\"'self'\", \"vscode-webview:\", \"vscode-resource:\", \"https:\", \"http:\"],\n frameSrc: [\"'self'\", \"vscode-webview:\", \"https:\", \"http:\"],\n scriptSrc: [\"'self'\", \"'unsafe-inline'\"],\n styleSrc: [\"'self'\", \"'unsafe-inline'\"]\n },\n },\n }\n};\n\nif (!fs.existsSync(config.defaultImagesPath)) {\n fs.mkdirSync(config.defaultImagesPath, { recursive: true });\n}\n\nif (!fs.existsSync(logsFolder)) {\n fs.mkdirSync(logsFolder, { recursive: true });\n}\n\n\n","{\n \"name\": \"@syngrisi/syngrisi\",\n \"version\": \"2.2.3\",\n \"description\": \"Syngrisi - Visual Testing Tool\",\n \"main\": \"./dist/server/server.js\",\n \"type\": \"commonjs\",\n \"bin\": {\n \"sy\": \"server.js\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/syngrisi/syngrisi\"\n },\n \"engines\": {\n \"node\": \">=20\"\n },\n \"files\": [\n \"src\",\n \"dist\",\n \"mvc\",\n \"static\",\n \"src/tasks\",\n \"config.js\",\n \"server.js\",\n \"docker-compose.yml\",\n \".nvmrc\"\n ],\n \"homepage\": \"https://github.com/syngrisi/syngrisi/tree/main/packages/syngrisi\",\n \"keywords\": [\n \"testing\",\n \"regression\",\n \"visual\",\n \"screenshots\",\n \"comparison\"\n ],\n \"nodemonConfig\": {\n \"ignore\": [\n \"mvc/views/lib/*.js\"\n ],\n \"include\": [\n \"dist\"\n ],\n \"delay\": 500\n },\n \"scripts\": {\n \"server:watch\": \"npx tsup --watch --onSuccess \\\"node ./dist/server/server.js\\\" # compile all server ts files changes\",\n \"start\": \"if [ \\\"$NODE_ENV\\\" = \\\"development\\\" ]; then npm run server:watch; else node ./dist/server/server.js; fi\",\n \"start_old\": \"SYNGRISI_AUTH=false nodemon --ignore 'mvc/views/lib/*.js' --ignore 'tests'\",\n \"test\": \"npm run build && cd tests && npm run test\",\n \"build\": \"npm run build:ui && npm run build:server\",\n \"clean:server\": \"rimraf dist\",\n \"build:ui\": \"rm -rf mvc/views/react/assets && cross-env VITE_ROOT_PATH='./src/ui-app/' vite build\",\n \"build:server\": \"npm run clean:server&& npx tsup\",\n \"install:server\": \"npm i\",\n \"install:ui\": \"cd src/ui-app && npm i && cd --\",\n \"install:all\": \"npm run install:server && npm run install:ui\",\n \"test:docker\": \"cd tests && npm run test:docker\",\n \"smoke\": \"cd tests && npm run smoke\",\n \"dev\": \"cross-env VITE_SYNGRISI_BASED_URL='http://localhost:3000' VITE_INDEX_ROUTE='index2/' vite\",\n \"dev:admin\": \"cross-env VITE_SYNGRISI_BASED_URL='http://localhost:3000' VITE_INDEX_ROUTE='admin/' vite/' vite #(!) open http://localhost:8080/admin/ \",\n \"build:watch\": \"cross-env VITE_ROOT_PATH='./src/ui-app/' vite build --watch\",\n \"pub\": \"np --yolo --no-publish\",\n \"starttest\": \"node server.js\",\n \"tasks:reindex\": \"node src/tasks/reindex.js\",\n \"tasks:backup\": \"node dist/src/tasks/backup.js\",\n \"tasks:restore\": \"node dist/src/tasks/restore.js\",\n \"tasks:migration_2_0\": \"node src/tasks/migrations/2.0.migration.js\",\n \"startservice\": \"forever start -l forever.log -o out.log -e err.log server.js\",\n \"clean\": \"read -p \\\"Are you sure you want to clean the project? [y/n] \\\" REPLY; if [[ $REPLY =~ ^[Yy]$ ]]; then mongosh SyngrisiDb --eval \\\"db.dropDatabase();\\\" && rm -f ./baselines/*.png; fi\",\n \"start_test\": \"cross-env SYNGRISI_DB_URI='mongodb://localhost/SyngrisiDbTest' nodemon server.js\",\n \"clear_test\": \"mongosh SyngrisiDbTest$CID --eval \\\"db.dropDatabase();\\\" && rm -rf ./baselinesTest/$CID\",\n \"clear_test_db_only\": \"mongosh SyngrisiDbTest$CID --eval \\\"db.dropDatabase();\\\"\",\n \"docker_clear_test\": \"rm -rf ./data/db_data && rm -rf ./baselinesTest/$CID\",\n \"docker_clear_test_db_only\": \"rm -rf ./data/db_data\",\n \"clear_test_screenshots_only\": \"rm -rf ./baselinesTest/$CID/*\",\n \"deadfile:be\": \"npx deadfile ./server.js --exclude tests src/tasks backups data docs mvc/views/react src/ui-app baseline*\",\n \"deadfile:fe\": \"deadfile ./mvc/views/react/index2/index.html ./mvc/views/react/auth/index.html --dir ./mvc/views/react\",\n \"pkglist\": \"npx npm-packlist # list of files that will be published in syngrisi package, show the files section\"\n },\n \"author\": {\n \"name\": \"Viktar Silakou\",\n \"email\": \"1105714@gmail.com\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/syngrisi/syngrisi/issues\"\n },\n \"license\": \"MIT\",\n \"dependencies\": {\n \"@asteasolutions/zod-to-openapi\": \"^7.0.0\",\n \"@inquirer/prompts\": \"^3.3.0\",\n \"@syngrisi/node-resemble.js\": \"^2.1.36-alpha.0\",\n \"@types/compression\": \"^1.7.5\",\n \"body-parser\": \"^1.19.0\",\n \"bottleneck\": \"^2.19.5\",\n \"bson\": \"^5.5.1\",\n \"chalk\": \"^4.1.2\",\n \"compression\": \"^1.7.4\",\n \"connect-mongo\": \"^5.1.0\",\n \"cookie-parser\": \"^1.4.6\",\n \"dotenv\": \"^16.0.0\",\n \"envalid\": \"^8.0.0\",\n \"eslint-plugin-custom-rules\": \"^0.0.0\",\n \"express\": \"^4.18.2\",\n \"express-fileupload\": \"^1.5.0\",\n \"express-session\": \"^1.17.1\",\n \"hasha\": \"^5.1.0\",\n \"helmet\": \"^7.1.0\",\n \"http-status\": \"^1.5.2\",\n \"mongoose\": \"^7.6.4\",\n \"nodemon\": \"^3.0.1\",\n \"p-queue\": \"^6.4.0\",\n \"passport\": \"^0.6.0\",\n \"passport-local\": \"^1.0.0\",\n \"passport-local-mongoose\": \"^8.0.0\",\n \"pino\": \"^8.16.1\",\n \"pino-http\": \"^8.5.1\",\n \"source-map-support\": \"^0.5.21\",\n \"string-table\": \"^0.1.5\",\n \"swagger-ui-express\": \"^5.0.1\",\n \"uuid-apikey\": \"^1.5.2\",\n \"winston\": \"^3.11.0\",\n \"winston-mongodb\": \"^5.1.1\",\n \"zod\": \"^3.23.8\"\n },\n \"devDependencies\": {\n \"@playwright/test\": \"^1.43.1\",\n \"@types/cookie-parser\": \"^1.4.7\",\n \"@types/express\": \"^4.17.21\",\n \"@types/express-fileupload\": \"^1.5.0\",\n \"@types/express-session\": \"^1.18.0\",\n \"@types/fabric\": \"^4.5.12\",\n \"@types/jquery\": \"^3.5.14\",\n \"@types/mongoose\": \"^5.11.97\",\n \"@types/node\": \"^20.9.0\",\n \"@types/passport\": \"^1.0.16\",\n \"@types/passport-local\": \"^1.0.38\",\n \"@types/react\": \"^18.0.15\",\n \"@types/react-dom\": \"^18.0.6\",\n \"@types/swagger-ui-express\": \"^4.1.6\",\n \"@typescript-eslint/eslint-plugin\": \"^6.21.0\",\n \"@typescript-eslint/parser\": \"^6.21.0\",\n \"@vitejs/plugin-react\": \"^2.0.0\",\n \"babel-eslint\": \"^10.1.0\",\n \"c8\": \"^8.0.1\",\n \"cross-env\": \"^7.0.3\",\n \"eslint\": \"^8.57.0\",\n \"eslint-plugin-custom\": \"file:.eslint\",\n \"form-data\": \"^4.0.0\",\n \"parcel\": \"^2.10.2\",\n \"rimraf\": \"^5.0.7\",\n \"sass\": \"^1.54.0\",\n \"tsup\": \"^8.1.0\",\n \"typescript\": \"^5.2.2\",\n \"vite\": \"^3.0.9\",\n \"vite-tsconfig-paths\": \"^4.3.2\"\n },\n \"nyc\": {\n \"all\": true,\n \"include\": [\n \"src/server/**/*.js\"\n ],\n \"exclude\": [\n \"**/*.test.js\",\n \"coverage/**\",\n \"node_modules/**\"\n ],\n \"reporter\": [\n \"json\"\n ],\n \"extension\": [\n \".js\"\n ]\n },\n \"gitHead\": \"a0d3926ab3ce0c104e75f1e41f3be19211442142\"\n}\n","import { cleanEnv, host, num, port, str, bool } from 'envalid';\nimport crypto from 'crypto';\nimport path from 'path';\n\nimport dotenv from 'dotenv';\ndotenv.config();\n\nexport const env = cleanEnv(process.env, {\n NODE_ENV: str({ choices: ['development', 'production', 'test'] }),\n SYNGRISI_DB_URI: str({ devDefault: 'mongodb://127.0.0.1:27017/SyngrisiDb' }),\n SYNGRISI_APP_PORT: port({ devDefault: 3000 }),\n SYNGRISI_IMAGES_PATH: str({ devDefault: \"./.snapshots-images/\" }),\n SYNGRISI_TMP_DIR: str({ default: path.join(process.cwd(), '.tmp') }),\n SYNGRISI_HTTP_LOG: bool({ devDefault: false }),\n SYNGRISI_COVERAGE: bool({ devDefault: false }),\n\n SYNGRISI_HOSTNAME: host({ devDefault: 'localhost' }),\n\n SYNGRISI_AUTH: bool({ default: true }),\n SYNGRISI_TEST_MODE: bool({ default: false }),\n SYNGRISI_DISABLE_FIRST_RUN: bool({ default: false }),\n\n MONGODB_ROOT_USERNAME: str({ default: '' }),\n MONGODB_ROOT_PASSWORD: str({ default: '' }),\n LOGLEVEL: str({ choices: ['error', 'warn', 'info', 'verbose', 'debug', 'silly'], default: 'debug' }),\n SYNGRISI_PAGINATION_SIZE: num({ default: 50 }),\n SYNGRISI_DISABLE_DEV_CORS: bool({ default: false, devDefault: true }),\n SYNGRISI_SESSION_STORE_KEY: str({ default: crypto.randomBytes(64).toString('hex') }),\n SYNGRISI_LOG_LEVEL: str({ default: 'debug' }),\n\n // trunk features\n SYNGRISI_TRUNK_FEATURE_AI_SEVERITY: bool({ default: false }),\n SYNGRISI_AI_KEY: str({ default: '' }),\n OPENAI_API_BASE_URL: str({ default: 'https://api.openai.com/v1' }),\n OPENAI_API_KEY: str({ default: '' }),\n});\n","[\n {\n \"os\": \"ios\",\n \"os_version\": \"16\",\n \"device\": \"iPhone 14 Pro Max\",\n \"realMobile\": true\n }, {\n \"os\": \"ios\",\n \"os_version\": \"16\",\n \"device\": \"iPhone 14 Pro\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"16\",\n \"device\": \"iPhone 14 Plus\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"16\",\n \"device\": \"iPhone 14\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"16\",\n \"device\": \"iPhone 12 Pro Max\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"16\",\n \"device\": \"iPhone 12 Pro\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"16\",\n \"device\": \"iPhone 12 Mini\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"16\",\n \"device\": \"iPhone 11 Pro Max\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPhone XS\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPhone 13 Pro Max\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPhone 13 Pro\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPhone 13 Mini\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPhone 13\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPhone 11 Pro\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPhone 11\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"14\",\n \"device\": \"iPhone XS\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"14\",\n \"device\": \"iPhone 12 Pro Max\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"14\",\n \"device\": \"iPhone 12 Pro\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"14\",\n \"device\": \"iPhone 12 Mini\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"14\",\n \"device\": \"iPhone 12\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"14\",\n \"device\": \"iPhone 11 Pro Max\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"14\",\n \"device\": \"iPhone 11\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"13\",\n \"device\": \"iPhone XS\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"13\",\n \"device\": \"iPhone 11 Pro Max\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"13\",\n \"device\": \"iPhone 11 Pro\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"13\",\n \"device\": \"iPhone 11\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"12\",\n \"device\": \"iPhone XS\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"12\",\n \"device\": \"iPhone XS Max\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPhone XR\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"12\",\n \"device\": \"iPhone XR\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"11\",\n \"device\": \"iPhone X\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPhone 8\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"13\",\n \"device\": \"iPhone 8\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"12\",\n \"device\": \"iPhone 8\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"11\",\n \"device\": \"iPhone 8\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"12\",\n \"device\": \"iPhone 8 Plus\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"11\",\n \"device\": \"iPhone 8 Plus\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"12\",\n \"device\": \"iPhone 7\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"10\",\n \"device\": \"iPhone 7\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"12\",\n \"device\": \"iPhone 6S\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"11\",\n \"device\": \"iPhone 6S\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"11\",\n \"device\": \"iPhone 6S Plus\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"11\",\n \"device\": \"iPhone 6\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPhone SE 2022\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"13\",\n \"device\": \"iPhone SE 2020\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"11\",\n \"device\": \"iPhone SE\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"14\",\n \"device\": \"iPad Air 4\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPad 9th\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"16\",\n \"device\": \"iPad Pro 12.9 2022\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"16\",\n \"device\": \"iPad Pro 12.9 2020\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"16\",\n \"device\": \"iPad Pro 11 2022\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"16\",\n \"device\": \"iPad 10th\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPad Air 5\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"14\",\n \"device\": \"iPad Pro 12.9 2021\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"14\",\n \"device\": \"iPad Pro 12.9 2020\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"14\",\n \"device\": \"iPad Pro 11 2021\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"13\",\n \"device\": \"iPad Pro 12.9 2020\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"16\",\n \"device\": \"iPad 8th\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPad Pro 12.9 2018\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"15\",\n \"device\": \"iPad Mini 2021\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"14\",\n \"device\": \"iPad 8th\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"13\",\n \"device\": \"iPad Pro 12.9 2018\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"13\",\n \"device\": \"iPad Pro 11 2020\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"13\",\n \"device\": \"iPad Mini 2019\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"13\",\n \"device\": \"iPad Air 2019\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"13\",\n \"device\": \"iPad 7th\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"12\",\n \"device\": \"iPad Pro 12.9 2018\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"12\",\n \"device\": \"iPad Pro 11 2018\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"12\",\n \"device\": \"iPad Mini 2019\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"12\",\n \"device\": \"iPad Air 2019\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"11\",\n \"device\": \"iPad Pro 9.7 2016\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"11\",\n \"device\": \"iPad Pro 12.9 2017\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"11\",\n \"device\": \"iPad Mini 4\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"11\",\n \"device\": \"iPad 6th\",\n \"realMobile\": true\n}, {\n \"os\": \"ios\",\n \"os_version\": \"11\",\n \"device\": \"iPad 5th\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"12.0\",\n \"device\": \"Samsung Galaxy S22 Ultra\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"12.0\",\n \"device\": \"Samsung Galaxy S22 Plus\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"12.0\",\n \"device\": \"Samsung Galaxy S22\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"12.0\",\n \"device\": \"Samsung Galaxy S21\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Samsung Galaxy S21 Ultra\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Samsung Galaxy S21\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Samsung Galaxy S21 Plus\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Samsung Galaxy S20\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Samsung Galaxy S20 Plus\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Samsung Galaxy S20 Ultra\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Samsung Galaxy M52\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Samsung Galaxy M32\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Samsung Galaxy A52\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Samsung Galaxy Note 20 Ultra\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Samsung Galaxy Note 20\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Samsung Galaxy A51\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Samsung Galaxy A11\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Samsung Galaxy S9 Plus\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Samsung Galaxy S10e\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Samsung Galaxy S10 Plus\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Samsung Galaxy S10\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Samsung Galaxy Note 10 Plus\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Samsung Galaxy Note 10\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Samsung Galaxy A10\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"8.1\",\n \"device\": \"Samsung Galaxy Note 9\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"8.1\",\n \"device\": \"Samsung Galaxy J7 Prime\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"8.0\",\n \"device\": \"Samsung Galaxy S9 Plus\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"8.0\",\n \"device\": \"Samsung Galaxy S9\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"7.1\",\n \"device\": \"Samsung Galaxy Note 8\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"7.1\",\n \"device\": \"Samsung Galaxy A8\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"7.0\",\n \"device\": \"Samsung Galaxy S8 Plus\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"7.0\",\n \"device\": \"Samsung Galaxy S8\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"6.0\",\n \"device\": \"Samsung Galaxy S7\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"5.0\",\n \"device\": \"Samsung Galaxy S6\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"13.0\",\n \"device\": \"Google Pixel 7 Pro\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"13.0\",\n \"device\": \"Google Pixel 7\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"13.0\",\n \"device\": \"Google Pixel 6 Pro\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"12.0\",\n \"device\": \"Google Pixel 6 Pro\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"12.0\",\n \"device\": \"Google Pixel 6\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"12.0\",\n \"device\": \"Google Pixel 5\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Google Pixel 5\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Google Pixel 4\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Google Pixel 4 XL\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Google Pixel 4\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Google Pixel 3\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Google Pixel 3a XL\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Google Pixel 3a\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Google Pixel 3 XL\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Google Pixel 3\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Google Pixel 2\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"8.0\",\n \"device\": \"Google Pixel 2\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"7.1\",\n \"device\": \"Google Pixel\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"6.0\",\n \"device\": \"Google Nexus 6\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"4.4\",\n \"device\": \"Google Nexus 5\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"OnePlus 9\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"OnePlus 8\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"OnePlus 7T\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"OnePlus 7\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"OnePlus 6T\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Xiaomi Redmi Note 11\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Xiaomi Redmi Note 9\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Xiaomi Redmi Note 8\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Xiaomi Redmi Note 7\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Vivo Y21\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Vivo V21\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Vivo Y50\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Oppo Reno 6\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Oppo A96\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Oppo Reno 3 Pro\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Motorola Moto G71 5G\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Motorola Moto G9 Play\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Motorola Moto G7 Play\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Huawei P30\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"12.0\",\n \"device\": \"Samsung Galaxy Tab S8\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"11.0\",\n \"device\": \"Samsung Galaxy Tab S7\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"10.0\",\n \"device\": \"Samsung Galaxy Tab S7\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Samsung Galaxy Tab S6\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"9.0\",\n \"device\": \"Samsung Galaxy Tab S5e\",\n \"realMobile\": true\n}, {\n \"os\": \"android\",\n \"os_version\": \"8.1\",\n \"device\": \"Samsung Galaxy Tab S4\",\n \"realMobile\": true\n}\n]\n","import { Test, Run } from '@models';\nimport log from '@lib/logger';\nimport * as testService from './test.service';\nimport { RequestUser } from '@types';\nimport httpStatus from 'http-status';\nimport { ApiError } from '../utils';\n\nconst remove = async (id: string, user: RequestUser) => {\n \n const logOpts = {\n scope: 'removeRun',\n itemType: 'run',\n ref: id,\n user: user?.username,\n msgType: 'REMOVE',\n };\n log.info(`remove run with, id: '${id}', user: '${user.username}'`, logOpts);\n const tests = await Test.find({ run: id }).exec();\n\n for (const test of tests) {\n await testService.remove(test._id, user);\n }\n const run = await Run.findByIdAndDelete(id).exec();\n if (!run) {\n throw new ApiError(httpStatus.NOT_FOUND, `cannot remove run with id: '${id}', not found`);\n }\n return run;\n};\n\nexport {\n remove,\n};\n","import { Test, Suite } from '@models';\nimport * as testService from './test.service';\nimport log from '@lib/logger';\nimport { RequestUser } from '@types';\nimport { ApiError } from '../utils';\nimport httpStatus from 'http-status';\n\nconst remove = async (id: string, user: RequestUser) => {\n const logOpts = {\n scope: 'removeSuite',\n itemType: 'suite',\n ref: id,\n user: user?.username,\n msgType: 'REMOVE',\n };\n log.info(`remove suite with, id: '${id}', user: '${user.username}'`, logOpts);\n const tests = await Test.find({ suite: id }).exec();\n\n for (const test of tests) {\n await testService.remove(test._id, user);\n }\n const suite = await Suite.findByIdAndDelete(id).exec();\n if (!suite) throw new ApiError(httpStatus.NOT_FOUND, `cannot remove suite with id: '${id}', not found`);\n \n return suite;\n};\n\nexport {\n remove,\n};\n","import mongoose, { FilterQuery } from 'mongoose';\nimport { removeEmptyProperties } from '@utils';\nimport log from '@logger';\nimport { ExtededModelMembers, PaginateOptions } from '@models/plugins/utils';\nimport { RequestUser } from '@root/src/types';\n\nconst get = async (modelName: string, filter: FilterQuery<typeof Test>, options: PaginateOptions) => {\n const itemModel = mongoose.model(modelName);\n return (itemModel as unknown as ExtededModelMembers<typeof itemModel>).paginate(filter, options);\n};\n\nconst put = async (modelName: string, id: string, options: { [key: string]: unknown }, user: RequestUser) => {\n const itemModel = mongoose.model(modelName);\n\n const logOpts = {\n scope: 'generic.service.put',\n ref: id,\n itemType: modelName,\n msgType: 'UPDATE',\n user: user?.username,\n };\n\n const opts = removeEmptyProperties(options);\n log.debug(`start update '${modelName}' with id: '${id}', body: '${JSON.stringify(opts)}'`, logOpts);\n const item = await itemModel.findByIdAndUpdate(id, options).exec();\n if (!item) throw new Error(`cannot find the item: ${modelName}, id: ${id}, options: ${JSON.stringify(options)}`);\n\n\n await item.save();\n log.debug(`baseline with id: '${id}' and opts: '${JSON.stringify(opts)}' was updated`, logOpts);\n return item;\n};\n\nexport {\n get,\n put,\n};\n","/* eslint-disable @typescript-eslint/ban-ts-comment */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable camelcase */\nimport { Response } from \"express\";\nimport { env } from \"@/server/envConfig\";\n\ninterface StringTable {\n create(data: { [key: string]: any }[]): string;\n}\n\nimport fs, { promises as fsp } from 'fs';\n// @ts-ignore\nimport st from 'string-table';\nimport { config } from '@config';\nimport { subDays, dateToISO8601 } from '@utils';\nimport { ProgressBar } from '@utils';\nimport log from \"../lib/logger\";\nimport testAdminUser from '../../seeds/testAdmin.json'\nconst stringTable: StringTable = st;\n\nimport {\n Snapshot,\n Check,\n Test,\n Run,\n Suite,\n User,\n Log,\n Baseline,\n} from '@models';\nimport { ExtRequest } from '@types';\n\nfunction taskOutput(msg: any, res: any) {\n res.write(`${msg.toString()}\\n`);\n log.debug(msg.toString());\n}\n\nfunction parseHrtimeToSeconds(hrtime: any) {\n return (hrtime[0] + (hrtime[1] / 1e9)).toFixed(3);\n}\n\nconst status = async (currentUser: any) => {\n const count = await User.countDocuments().exec();\n\n log.silly(`server status: check users counts: ${count}`);\n if (count > 1) {\n return { alive: true, currentUser: currentUser?.username };\n }\n return { alive: false };\n};\n\nconst screenshots = async () => {\n const files = fs.readdirSync(config.defaultImagesPath);\n return files;\n};\n\nconst loadTestUser = async () => {\n const logOpts = {\n itemType: 'user',\n msgType: 'LOAD',\n ref: 'Administrator',\n };\n if (!env.SYNGRISI_TEST_MODE) {\n return { message: 'the feature works only in test mode' };\n }\n const testAdmin = await User.findOne({ username: 'Test' }).exec();\n if (!testAdmin) {\n log.info('create the test Administrator', logOpts);\n const admin = await User.create(testAdminUser);\n log.info(`test Administrator with id: '${admin._id}' was created`, logOpts);\n return admin;\n }\n\n log.info(`test admin is exists: ${JSON.stringify(testAdmin, null, 2)}`, logOpts);\n return { msg: `already exist '${testAdmin}'` };\n};\n\nconst task_handle_database_consistency = async (options: any, res: any) => {\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Content-Encoding': 'none',\n 'x-no-compression': 'true',\n });\n try {\n const startTime = process.hrtime();\n taskOutput('- starting...\\n', res);\n taskOutput('---------------------------------', res);\n taskOutput('STAGE #1: Calculate Common stats', res);\n taskOutput('get runs data', res);\n const allRunsBefore = await Run.find().exec();\n taskOutput('get suites data', res);\n const allSuitesBefore = await Suite.find().exec();\n taskOutput('get tests data', res);\n const allTestsBefore = await Test.find().lean().exec();\n taskOutput('get checks data', res);\n const allChecksBefore = await Check.find().lean().exec();\n taskOutput('get snapshots data', res);\n const allSnapshotsBefore = await Snapshot.find().lean().exec();\n taskOutput('get files data', res);\n const allFilesBefore = (await fsp.readdir(config.defaultImagesPath, { withFileTypes: true }))\n .filter((item: any) => !item.isDirectory())\n .map((x: any) => x.name)\n .filter((x: any) => x.includes('.png'));\n\n taskOutput('-----------------------------', res);\n const beforeStatTable = stringTable.create([\n { item: 'suites', count: allSuitesBefore.length },\n { item: 'runs', count: allRunsBefore.length },\n { item: 'tests', count: allTestsBefore.length },\n { item: 'checks', count: allChecksBefore.length },\n { item: 'snapshots', count: allSnapshotsBefore.length },\n { item: 'files', count: allFilesBefore.length },\n ]);\n res.flush();\n taskOutput(beforeStatTable, res);\n\n taskOutput('---------------------------------', res);\n taskOutput('STAGE #2: Calculate Inconsistent Items', res);\n taskOutput('> calculate abandoned snapshots', res);\n const abandonedSnapshots = allSnapshotsBefore.filter((sn: any) => !fs.existsSync(`${config.defaultImagesPath}/${sn.filename}`));\n\n taskOutput('> calculate abandoned files', res);\n const snapshotsUniqueFiles = Array.from(new Set(allSnapshotsBefore.map((x: any) => x.filename)));\n const abandonedFiles: any[] = [];\n const progress = new ProgressBar(allFilesBefore.length);\n for (const [index, file] of allFilesBefore.entries()) {\n setTimeout(() => {\n progress.writeIfChange(index, allFilesBefore.length, taskOutput, res);\n }, 10);\n\n if (!snapshotsUniqueFiles.includes(file.toString())) {\n abandonedFiles.push(file);\n }\n }\n taskOutput('> calculate abandoned checks', res);\n const allSnapshotsBeforeIds = allSnapshotsBefore.map((x: any) => x._id.valueOf());\n\n const allChecksBeforeLight = allChecksBefore.map((x: any) => ({\n _id: x._id.valueOf(), baselineId: x.baselineId.valueOf(), actualSnapshotId: x.actualSnapshotId.valueOf(),\n }));\n const abandonedChecks: any[] = [];\n const progressChecks = new ProgressBar(allChecksBefore.length);\n for (const [index, check] of allChecksBeforeLight.entries()) {\n progressChecks.writeIfChange(index, allChecksBeforeLight.length, taskOutput, res);\n if (!allSnapshotsBeforeIds.includes(check.baselineId) || !allSnapshotsBeforeIds.includes(check.actualSnapshotId.valueOf())) {\n abandonedChecks.push(check._id.valueOf());\n }\n }\n\n taskOutput('> calculate empty tests', res);\n const checksUniqueTests = (await Check.find().lean().distinct('test').exec()).map((x: any) => x.valueOf());\n\n const emptyTests: any[] = [];\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for (const [index, test] of allTestsBefore.entries()) {\n if (!checksUniqueTests.includes(test._id.valueOf())) {\n emptyTests.push(test._id.valueOf());\n }\n }\n\n taskOutput('> calculate empty runs', res);\n\n const checksUniqueRuns = (await Check.find().distinct('run').exec()).map((x: any) => x.valueOf());\n\n const emptyRuns: any[] = [];\n for (const run of allRunsBefore) {\n if (!checksUniqueRuns.includes(run._id.valueOf())) {\n emptyRuns.push(run._id.valueOf());\n }\n }\n\n taskOutput('> calculate empty suites', res);\n\n const checksUniqueSuites = (await Check.find().distinct('suite').exec()).map((x: any) => x.valueOf());\n\n const emptySuites: any[] = [];\n for (const suite of allSuitesBefore) {\n if (!checksUniqueSuites.includes(suite._id.valueOf())) {\n emptySuites.push(suite._id.valueOf());\n }\n }\n taskOutput('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~', res);\n taskOutput('Current inconsistent items:', res);\n const inconsistentStatTable = stringTable.create([\n { item: 'empty suites', count: emptySuites.length },\n { item: 'empty runs', count: emptyRuns.length },\n { item: 'empty tests', count: emptyTests.length },\n { item: 'abandoned checks', count: abandonedChecks.length },\n { item: 'abandoned snapshots', count: abandonedSnapshots.length },\n { item: 'abandoned files', count: abandonedFiles.length },\n ]);\n taskOutput(inconsistentStatTable, res);\n\n if (options.clean) {\n taskOutput('---------------------------------', res);\n taskOutput('STAGE #3: Remove non consistent items', res);\n\n taskOutput('> remove empty suites', res);\n await Suite.deleteMany({ _id: { $in: emptySuites } });\n taskOutput('> remove empty runs', res);\n await Run.deleteMany({ _id: { $in: emptyRuns } });\n taskOutput('> remove empty tests', res);\n await Test.deleteMany({ _id: { $in: emptyTests } });\n taskOutput('> remove abandoned checks', res);\n await Check.deleteMany({ _id: { $in: abandonedChecks } });\n taskOutput('> remove abandoned snapshots', res);\n await Snapshot.deleteMany({ _id: { $in: abandonedSnapshots } });\n taskOutput('> remove abandoned files', res);\n await Promise.all(abandonedFiles.map((filename) => fsp.unlink(`${config.defaultImagesPath}/${filename}`)));\n const allFilesAfter = fs.readdirSync(config.defaultImagesPath, { withFileTypes: true })\n .filter((item: any) => !item.isDirectory())\n .map((x: any) => x.name)\n .filter((x: any) => x.includes('.png'));\n\n taskOutput('STAGE #4: Calculate Common stats after cleaning', res);\n taskOutput('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~', res);\n taskOutput('Current items:', res);\n const afterStatTable = stringTable.create([\n { item: 'suites', count: await Suite.countDocuments() },\n { item: 'runs', count: await Run.countDocuments() },\n { item: 'tests', count: await Test.countDocuments() },\n { item: 'checks', count: await Check.countDocuments() },\n { item: 'snapshots', count: await Snapshot.countDocuments() },\n { item: 'files', count: allFilesAfter.length },\n ]);\n taskOutput(afterStatTable, res);\n }\n\n const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime));\n taskOutput(`> Done in ${elapsedSeconds} seconds, ${elapsedSeconds / 60} min`, res);\n taskOutput('- end...\\n', res);\n } catch (e: unknown) {\n const errMsg = e instanceof Error ? e.message : String(e);\n log.error(errMsg);\n taskOutput(errMsg, res);\n } finally {\n res.end();\n }\n};\n\nconst task_remove_old_logs = async (options: any, res: any) => {\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Content-Encoding': 'none',\n });\n const trashHoldDate = subDays(new Date(), parseInt(options.days, 10));\n const filter = { timestamp: { $lt: trashHoldDate } };\n const allLogsCountBefore = await Log.find({}).countDocuments();\n const oldLogsCount = await Log.find(filter).countDocuments();\n taskOutput(`- the count of all documents is: '${allLogsCountBefore}'\\n`, res);\n taskOutput(`- the count of documents to be removed is: '${oldLogsCount}'\\n`, res);\n if (options.statistics === 'false') {\n taskOutput(`- will remove all logs older that: '${options.days}' days, '${dateToISO8601(trashHoldDate)}'\\n`, res);\n await Log.deleteMany(filter);\n const allLogsCountAfter = await Log.find({}).countDocuments();\n taskOutput(`- the count of all documents now is: '${allLogsCountAfter}'\\n`, res);\n }\n\n taskOutput('> Done', res);\n res.end();\n};\n\nconst task_handle_old_checks = async (options: any, res: any) => {\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Content-Encoding': 'none',\n });\n try {\n const startTime = process.hrtime();\n taskOutput('- starting...\\n', res);\n\n taskOutput('STAGE #1 Calculate common stats', res);\n\n const trashHoldDate = subDays(new Date(), parseInt(options.days, 10));\n\n taskOutput('> get all checks data', res);\n const allChecksBefore = await Check.find().lean().exec();\n taskOutput('> get snapshots data', res);\n const allSnapshotsBefore = await Snapshot.find().lean().exec();\n taskOutput('> get files data', res);\n const allFilesBefore = (await fsp.readdir(config.defaultImagesPath, { withFileTypes: true }))\n .filter((item: any) => !item.isDirectory())\n .map((x: any) => x.name)\n .filter((x: any) => x.includes('.png'));\n\n taskOutput('> get old checks data', res);\n const oldChecks = await Check.find({ createdDate: { $lt: trashHoldDate } }).lean().exec();\n\n taskOutput('>>> collect all baselineIds for old Checks ', res);\n const oldSnapshotsBaselineIdIds = oldChecks.map((x: any) => x.baselineId).filter((x: any) => x);\n\n taskOutput('>>> collect all actualSnapshotId for old Checks ', res);\n const oldSnapshotsActualSnapshotIdIds = oldChecks.map((x: any) => x.actualSnapshotId).filter((x: any) => x);\n\n taskOutput('>>> collect all diffId for old Checks ', res);\n const oldSnapshotsDiffIds = oldChecks.map((x: any) => x.diffId).filter((x: any) => x);\n\n taskOutput('>>> calculate all unique snapshots ids for old Checks ', res);\n\n const allOldSnapshotsUniqueIds = Array.from(new Set([...oldSnapshotsBaselineIdIds, ...oldSnapshotsActualSnapshotIdIds, ...oldSnapshotsDiffIds]))\n .map((x: any) => x.valueOf());\n\n taskOutput('>>> collect all old snapshots', res);\n const oldSnapshots = await Snapshot.find({ _id: { $in: allOldSnapshotsUniqueIds } }).lean();\n\n const outTable = stringTable.create([\n { item: 'all checks', count: allChecksBefore.length },\n { item: 'all snapshots', count: allSnapshotsBefore.length },\n { item: 'all files', count: allFilesBefore.length },\n { item: `checks older than: '${options.days}' days`, count: oldChecks.length },\n { item: 'old snapshots baseline ids', count: oldSnapshotsBaselineIdIds.length },\n { item: 'old snapshots actual snapshotId', count: oldSnapshotsActualSnapshotIdIds.length },\n { item: 'old snapshots diffIds', count: oldSnapshotsDiffIds.length },\n { item: 'all old snapshots unique Ids', count: allOldSnapshotsUniqueIds.length },\n { item: 'all old snapshots', count: oldSnapshots.length },\n ]);\n\n taskOutput(outTable, res);\n\n if (options.remove === 'true') {\n taskOutput(`STAGE #2 Remove checks that older that: '${options.days}' days, '${dateToISO8601(trashHoldDate)}'\\n`, res);\n\n taskOutput('> remove checks', res);\n const checkRemovingResult = await Check.deleteMany({ createdDate: { $lt: trashHoldDate } });\n taskOutput(`>>> removed: '${checkRemovingResult.deletedCount}'`, res);\n\n taskOutput('> remove snapshots', res);\n\n taskOutput('>> collect data to removing', res);\n taskOutput('>>> get all baselines snapshots id`s', res);\n const baselinesSnapshotsIds = (await Baseline.find({}).distinct('snapshootId'));\n\n taskOutput('>>> get all checks snapshots baselineId', res);\n const checksSnapshotsBaselineId = (await Check.find({}).distinct('baselineId'));\n\n taskOutput('>>> get all checks snapshots actualSnapshotId', res);\n const checksSnapshotsActualSnapshotId = (await Check.find({}).distinct('actualSnapshotId'));\n\n taskOutput('>> remove baselines snapshots', res);\n\n taskOutput('>> remove all old snapshots that not related to new baseline and check items', res);\n const removedByBaselineSnapshotsResult = await Snapshot.deleteMany({\n $and: [\n { _id: { $nin: checksSnapshotsBaselineId } },\n { _id: { $nin: checksSnapshotsActualSnapshotId } },\n { _id: { $nin: baselinesSnapshotsIds } },\n { _id: { $in: oldSnapshotsBaselineIdIds } },\n ],\n });\n taskOutput(`>>> removed: '${removedByBaselineSnapshotsResult.deletedCount}'`, res);\n\n taskOutput('>> remove actual snapshots', res);\n taskOutput('>> remove all old snapshots that not related to new baseline and check items', res);\n const removedByActualSnapshotsResult = await Snapshot.deleteMany({\n $and: [\n { _id: { $nin: checksSnapshotsBaselineId } },\n { _id: { $nin: checksSnapshotsActualSnapshotId } },\n { _id: { $nin: baselinesSnapshotsIds } },\n { _id: { $in: oldSnapshotsActualSnapshotIdIds } },\n ],\n });\n taskOutput(`>>> removed: '${removedByActualSnapshotsResult.deletedCount}'`, res);\n\n taskOutput('>> remove all old diff snapshots', res);\n const removedByDiffSnapshotsResult = await Snapshot.deleteMany({\n $and: [\n { _id: { $in: oldSnapshotsDiffIds } },\n ],\n });\n taskOutput(`>>> removed: '${removedByDiffSnapshotsResult.deletedCount}'`, res);\n\n taskOutput('> remove files', res);\n taskOutput('>>> collect all old snapshots filenames', res);\n const oldSnapshotsUniqueFilenames = Array.from(new Set(oldSnapshots.map((x: any) => x.filename)));\n taskOutput(`>> found: ${oldSnapshotsUniqueFilenames.length}`, res);\n\n taskOutput('> get all current snapshots filenames', res);\n const allCurrentSnapshotsFilenames = await Snapshot.find().distinct('filename').exec();\n\n taskOutput('>> calculate interception between all current snapshot filenames and old shapshots filenames', res);\n const arrayIntersection = (arr1: any, arr2: any) => arr1.filter((x: any) => arr2.includes(x));\n const filesInterception = arrayIntersection(allCurrentSnapshotsFilenames, oldSnapshotsUniqueFilenames);\n taskOutput(`>> found: ${filesInterception.length}`, res);\n\n taskOutput('>> calculate filenames to remove', res);\n const arrayDiff = (arr1: any, arr2: any) => arr1.filter((x: any) => !arr2.includes(x));\n const filesToDelete = arrayDiff(oldSnapshotsUniqueFilenames, filesInterception);\n taskOutput(`>> found: ${filesToDelete.length}`, res);\n\n taskOutput(`>> remove these files: ${filesToDelete.length}`, res);\n await Promise.all(filesToDelete.map((filename: string) => fsp.unlink(`${config.defaultImagesPath}/${filename}`)));\n taskOutput(`>> done: ${filesToDelete.length}`, res);\n\n taskOutput('STAGE #3 Calculate common stats after Removing', res);\n\n taskOutput('> get all checks data', res);\n const allChecksAfter = await Check.find().lean().exec();\n taskOutput('> get snapshots data', res);\n const allSnapshotsAfter = await Snapshot.find().lean().exec();\n taskOutput('> get files data', res);\n const allFilesAfter = (await fsp.readdir(config.defaultImagesPath, { withFileTypes: true }))\n .filter((item: any) => !item.isDirectory())\n .map((x: any) => x.name)\n .filter((x: any) => x.includes('.png'));\n\n const outTableAfter = stringTable.create([\n { item: 'all checks', count: allChecksAfter.length },\n { item: 'all snapshots', count: allSnapshotsAfter.length },\n { item: 'all files', count: allFilesAfter.length },\n ]);\n\n taskOutput(outTableAfter, res);\n }\n const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime));\n\n taskOutput(`> done in ${elapsedSeconds} seconds ${elapsedSeconds / 60} min`, res);\n } catch (e: unknown) {\n const errMsg = e instanceof Error ? e.message : String(e);\n log.error(errMsg);\n taskOutput(errMsg, res);\n } finally {\n res.end();\n }\n};\n\nconst task_test = async (options = 'empty', req: ExtRequest, res: Response) => {\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Content-Encoding': 'none',\n });\n\n const x = 1000;\n // const interval = 30;\n let isAborted = false;\n\n req.on('close', () => {\n isAborted = true;\n });\n\n for (let i = 0; i < x; i += 1) {\n // await new Promise((r) => setTimeout(() => r(), interval));\n taskOutput(`- Task Output: '${i}', options: ${options}\\n`, res);\n if (isAborted) {\n taskOutput('the task was aborted\\n', res);\n log.warn('the task was aborted');\n (res as any).flush();\n return res.end();\n }\n }\n return res.end();\n};\n\nexport {\n task_test,\n task_handle_old_checks,\n task_handle_database_consistency,\n task_remove_old_logs,\n status,\n loadTestUser,\n screenshots,\n};\n","{\n\t\"username\" : \"Test\",\n \"firstName\": \"Test\",\n \"lastName\": \"Admin\",\n\t\"role\" : \"admin\",\n \"openPassw\": \"123456aA-\",\n\t\"password\" : \"5b8d4960316d1fb0c92498c90da6c397cdf247cae71f01467a88e2b42d7af6f5ac7ca75d3bea6e3e0078111a2e5dfc1611f9a9a8908a5a3af5bcd64c42989608977de192829bdf8ada113a60f8f0704443c659789761865e29a3103dbf0773f5bf31e4685d475ece56afaceb949b6e7467eaa287a02e4142d095bcbf84acaefe47ee080799a28188890d39d3397e285d8b46c9a0efe9517428825b64ee1ebcc96d92c084733db866c767341381b6254aaa1ef36d1bf3d24e3f5b8d8b6b4080589b130e9c90914a3da74e5b6adf5f569bfd77460abae8ae4f87c2a375397a37f09861b9e114cead0cc34fff2d631fd4294260dea17e4fe098940dbee2cb80c62eb3701d40f5b204de776b8252d55e5f567c599b1fbcdae79278d1f375a4c8244a26a3b721dbeec56c8f39b3eb810942d392aae371ea81ded6b820dd4b489566a33c495f5c291ff238d07202d2ff04c52426828e44af98ec056a42d13f4b166ec170083e2fff9efe2b8cfdde529f3bce56b8427cf2d188861808ad07fd13e073b2a804e818b2882c13f559d52420b49f301263a9de34fe22b6df4a82ae70e7e4c29c88479878d2c21fbb810532532e7ad9a28f610b63033520e703f178e7b44d3e101ec0d4339c085ccc8bb290b3cb996c75c2b8deaacba8098b9ec02c7e47542891da3bd887c31cd8e0bdfa56bb844b1703368afe8dc42d668ff2e3374b939b4f\",\n\t\"apiKey\" : \"\",\n\t\"salt\" : \"c6211751bdc372f491a86bcbd8e4196dc393d14e14e5f17019d5c317afd5bc27\"\n}","import fs, { promises as fsp } from 'fs';\nimport hasha from 'hasha';\nimport { Snapshot, Check, Test, App, Baseline, CheckDocument } from '@models';\nimport { removeEmptyProperties, waitUntil, buildIdentObject, calculateAcceptedStatus, ident, errMsg, ApiError } from '@utils';\nimport { updateItemDate, createTest, createItemIfNotExistAsync, createRunIfNotExist, createSuiteIfNotExist } from '@lib/dbItems';\nimport { config } from '@config';\nimport { prettyCheckParams } from '@utils';\nimport { getDiff } from '@lib/сomparison';\nimport log from \"@logger\";\nimport { LogOpts } from '@types';\nimport { UpdateTestType } from '@schemas/Test.schema';\nimport { ClientStartSessionType } from '@schemas/Client.schema';\nimport { RequiredIdentOptionsType } from '@schemas';\nimport { SnapshotDiff } from '@schemas/SnapshotDiff.schema';\nimport { SnapshotDocument } from '@models/Snapshot.model';\n// import { BaselineType } from '@schemas/Baseline.schema';\nimport { PaginateOptions } from '@models/plugins/utils';\nimport httpStatus from 'http-status';\nimport { UserDocument } from '@models/User.model';\nimport { UploadedFile } from 'express-fileupload';\nimport { TestDocument } from '@models/Test.model';\nimport { AppDocument } from '@models/App.model';\nimport { IdentType } from '@utils/buildIdentObject';\nimport StatusCodes from 'http-status';\nimport { SuiteDocument } from '@models/Suite.model';\nimport { BaselineDocument } from '../models/Baseline.model';\n\n\nasync function updateTest(id: string, update: UpdateTestType) {\n const logOpts: LogOpts = {\n scope: 'updateTest',\n itemType: 'test',\n msgType: 'UPDATE',\n ref: id,\n };\n log.debug(`update test id '${id}' with params '${JSON.stringify(update)}'`, logOpts);\n const updatedDate = update.updatedDate || Date.now();\n const test = await Test.findByIdAndUpdate(\n id,\n { ...update, updatedDate }\n ).exec();\n await test?.save();\n return test;\n}\n\nconst startSession = async (params: ClientStartSessionType, username: string) => {\n const logOpts = {\n scope: 'createTest',\n user: username,\n itemType: 'test',\n msgType: 'CREATE',\n };\n log.info(`create test with name '${params.name}', params: '${JSON.stringify(params)}'`, logOpts);\n const opts = removeEmptyProperties({\n name: params.name,\n status: 'Running',\n app: params.app,\n tags: params.tags && JSON.parse(params.tags),\n branch: params.branch,\n viewport: params.viewport,\n browserName: params.browser,\n browserVersion: params.browserVersion,\n browserFullVersion: params.browserFullVersion,\n os: params.os,\n startDate: new Date(),\n updatedDate: new Date(),\n });\n try {\n const app = await createItemIfNotExistAsync(\n 'VRSApp',\n { name: params.app },\n { user: username, itemType: 'app' }\n );\n opts.app = app._id;\n\n const run = await createRunIfNotExist(\n { name: params.run, ident: params.runident, app: app._id },\n { user: username, itemType: 'run' }\n );\n opts.run = run._id;\n\n const suite = await createSuiteIfNotExist(\n { name: params.suite || 'Others', app: app._id, createdDate: new Date() },\n { user: username, itemType: 'suite' }\n );\n\n opts.suite = suite._id;\n\n const test = await createTest(opts);\n return test;\n } catch (e: unknown) {\n log.error(`cannot start session '${params.name}', params: '${JSON.stringify(params)}', error: ${errMsg(e)}`, logOpts);\n throw e;\n }\n};\n\nconst endSession = async (testId: string, username: string) => {\n const logOpts = {\n scope: 'stopSession',\n msgType: 'END_SESSION',\n user: username,\n itemType: 'test',\n ref: testId,\n };\n await waitUntil(async () => (await Check.find({ test: testId }).exec()).filter((ch) => ch.status.toString() !== 'pending').length > 0);\n const sessionChecks = await Check.find({ test: testId }).lean().exec();\n\n const checksStatuses = sessionChecks.map((x) => x.status[0]);\n // const checksViewports = sessionChecks.map((x) => x.viewport);\n\n // const uniqueChecksViewports = Array.from(new Set(checksViewports));\n // let calculatedViewport: string | undefined;\n // if (uniqueChecksViewports.length === 1) {\n // calculatedViewport = uniqueChecksViewports[0];\n // } else {\n // calculatedViewport = String(uniqueChecksViewports.length);\n // }\n\n let status = 'not set';\n if (checksStatuses.some((st) => st === 'failed')) {\n status = 'Failed';\n }\n if (checksStatuses.some((st) => st === 'passed') && !checksStatuses.some((st) => st === 'failed')) {\n status = 'Passed';\n }\n if (checksStatuses.some((st) => st === 'new') && !checksStatuses.some((st) => st === 'failed')) {\n status = 'Passed';\n }\n if (checksStatuses.some((st) => st === 'blinking') && !checksStatuses.some((st) => st === 'failed')) {\n status = 'Passed';\n }\n if (checksStatuses.every((st) => st === 'new')) {\n status = 'New';\n }\n const blinking = checksStatuses.filter((g) => g === 'blinking').length;\n const testParams = {\n status,\n blinking,\n // calculatedViewport,\n };\n log.info(`the session is over, the test will be updated with parameters: '${JSON.stringify(testParams)}'`, logOpts);\n const updatedTest = await updateTest(testId, testParams);\n const result = updatedTest?.toObject();\n // result.calculatedStatus = status;\n return result;\n};\n\nasync function getAcceptedBaseline(params: IdentType) {\n const identFieldsAccepted = Object.assign(buildIdentObject(params), { markedAs: 'accepted' });\n const acceptedBaseline = await Baseline.findOne(identFieldsAccepted, {}, { sort: { createdDate: -1 } });\n log.debug(`acceptedBaseline: '${acceptedBaseline ? JSON.stringify(acceptedBaseline) : 'not found'}'`, { itemType: 'baseline' });\n if (acceptedBaseline) return acceptedBaseline;\n return null;\n}\n\nasync function getLastSuccessCheck(identifier: RequiredIdentOptionsType) {\n const condition = [{\n ...identifier,\n status: 'new',\n }, {\n ...identifier,\n status: 'passed',\n }];\n return (await Check.find({ $or: condition }).sort({ updatedDate: -1 }).limit(1))[0];\n}\n\nasync function getNotPendingChecksByIdent(identifier: RequiredIdentOptionsType) {\n return Check.find({\n ...identifier,\n status: { $ne: 'pending' },\n }).sort({ updatedDate: -1 }).exec();\n}\n\nasync function getSnapshotByImgHash(hash: string): Promise<SnapshotDocument | null> {\n return Snapshot.findOne({ imghash: hash });\n}\n\ninterface CreateSnapshotParameters {\n name: string;\n fileData: Buffer | null;\n hashCode?: string;\n}\n\nasync function createSnapshot(parameters: CreateSnapshotParameters) {\n const logOpts: LogOpts = {\n scope: 'createSnapshot',\n itemType: 'snapshot',\n msgType: 'CREATE'\n };\n\n const { name, fileData, hashCode } = parameters;\n\n const opts: Partial<SnapshotDocument> = { name };\n // const opts: SnapshotUpdateType = { name };\n\n // if (!fileData) throw new Error(`cannot create the snapshot, the 'fileData' is not set, name: '${name}'`);\n if (fileData === null) throw new ApiError(httpStatus.BAD_REQUEST, `cannot create the snapshot, the 'fileData' is not set, name: '${name}'`);\n\n\n opts.imghash = hashCode || hasha(fileData);\n const snapshot = new Snapshot(opts);\n const filename = `${snapshot.id}.png`;\n const path = `${config.defaultImagesPath}${filename}`;\n log.debug(`save screenshot for: '${name}' snapshot to: '${path}'`, logOpts);\n await fsp.writeFile(path, fileData);\n snapshot.filename = filename;\n await snapshot.save();\n log.debug(`snapshot was saved: '${JSON.stringify(snapshot)}'`, { ...logOpts, ...{ ref: snapshot._id } });\n return snapshot;\n}\n\nasync function cloneSnapshot(sourceSnapshot: SnapshotDocument, name: string) {\n const { filename } = sourceSnapshot;\n const hashCode = sourceSnapshot.imghash;\n const newSnapshot = new Snapshot({ name, filename, imghash: hashCode });\n await newSnapshot.save();\n return newSnapshot;\n}\n\ninterface CompareSnapshotsOptions {\n vShifting?: boolean;\n ignore?: string;\n ignoredBoxes?: string;\n}\n\nasync function compareSnapshots(baselineSnapshot: SnapshotDocument, actual: SnapshotDocument, opts: CompareSnapshotsOptions = {}) {\n const logOpts = {\n scope: 'compareSnapshots',\n ref: baselineSnapshot.id,\n itemType: 'snapshot',\n msgType: 'COMPARE',\n };\n try {\n log.debug(`compare baseline and actual snapshots with ids: [${baselineSnapshot.id}, ${actual.id}]`, logOpts);\n log.debug(`current baseline snapshot: ${JSON.stringify(baselineSnapshot)}`, logOpts);\n let diff: SnapshotDiff;\n if (baselineSnapshot.imghash === actual.imghash) {\n log.debug(`baseline and actual snapshot have the identical image hashes: '${baselineSnapshot.imghash}'`, logOpts);\n diff = {\n isSameDimensions: true,\n dimensionDifference: { width: 0, height: 0 },\n rawMisMatchPercentage: 0,\n misMatchPercentage: '0.00',\n analysisTime: 0,\n executionTotalTime: '0',\n getBuffer: null\n };\n } else {\n const baselinePath = `${config.defaultImagesPath}${baselineSnapshot.filename}`;\n const actualPath = `${config.defaultImagesPath}${actual.filename}`;\n const baselineData = await fsp.readFile(baselinePath);\n const actualData = await fsp.readFile(actualPath);\n log.debug(`baseline path: ${baselinePath}`, logOpts);\n log.debug(`actual path: ${actualPath}`, logOpts);\n const options = opts;\n const baseline = await Baseline.findOne({ snapshootId: baselineSnapshot._id }).exec();\n\n if (baseline) { // ts refactoring TODO: find out a proper way\n if (baseline.ignoreRegions) {\n log.debug(`ignore regions: '${baseline.ignoreRegions}', type: '${typeof baseline.ignoreRegions}'`);\n options.ignoredBoxes = JSON.parse(baseline.ignoreRegions);\n }\n options.ignore = baseline.matchType || 'nothing';\n }\n\n diff = await getDiff(baselineData, actualData, options);\n }\n\n log.silly(`the diff is: '${JSON.stringify(diff, null, 2)}'`);\n if (diff.rawMisMatchPercentage.toString() !== '0') {\n log.debug(`images are different, ids: [${baselineSnapshot.id}, ${actual.id}], rawMisMatchPercentage: '${diff.rawMisMatchPercentage}'`);\n }\n if (diff.stabMethod && diff.vOffset) {\n if (diff.stabMethod === 'downup') {\n actual.vOffset = -diff.vOffset;\n await actual.save();\n }\n if (diff.stabMethod === 'updown') {\n baselineSnapshot.vOffset = -diff.vOffset;\n await baselineSnapshot.save();\n }\n }\n return diff;\n } catch (e: unknown) {\n const errMsg = `cannot compare snapshots: ${e}\\n ${e instanceof Error ? e.stack : e}`;\n log.error(errMsg, logOpts);\n throw new Error(String(e));\n }\n}\n\nconst isBaselineValid = (baseline: BaselineDocument) => {\n const keys = [\n 'name', 'app', 'branch', 'browserName', 'viewport', 'os',\n 'createdDate', 'lastMarkedDate', 'markedAs', 'markedById', 'markedByUsername', 'snapshootId',\n ];\n for (const key of keys) {\n if (!baseline[key as keyof BaselineDocument]) {\n log.error(`invalid baseline, the '${key}' property is empty`);\n return false;\n }\n }\n return true;\n};\n\nconst updateCheckParamsFromBaseline = (params: CreateCheckParamsExtended, baseline: BaselineDocument): CreateCheckParamsExtended => {\n const updatedParams = { ...params };\n updatedParams.baselineId = baseline.snapshootId.toString();\n updatedParams.markedAs = baseline.markedAs;\n updatedParams.markedDate = baseline.lastMarkedDate?.toString();\n updatedParams.markedByUsername = baseline.markedByUsername;\n return updatedParams;\n};\n\nconst prepareActualSnapshot = async (checkParam: CreateCheckParams, snapshotFoundedByHashcode: SnapshotDocument | null, logOpts: LogOpts) => {\n let currentSnapshot: SnapshotDocument;\n const fileData = checkParam.files ? checkParam.files.file.data : null;\n\n if (snapshotFoundedByHashcode) {\n const fullFilename = `${config.defaultImagesPath}${snapshotFoundedByHashcode.filename}`;\n if (!fs.existsSync(fullFilename)) {\n throw new Error(`Couldn't find the baseline file: '${fullFilename}'`);\n }\n\n log.debug(`snapshot with such hashcode: '${checkParam.hashCode}' is already exists, will clone it`, logOpts);\n\n if (!checkParam.name) throw new ApiError(httpStatus.BAD_REQUEST, `Cannot prepareActualSnapshot name is empty, hashe: ${checkParam.hashCode}`);\n currentSnapshot = await cloneSnapshot(snapshotFoundedByHashcode, checkParam.name);\n } else {\n log.debug(`snapshot with such hashcode: '${checkParam.hashCode}' does not exists, will create it`, logOpts);\n currentSnapshot = await createSnapshot({ name: checkParam.name!, fileData, hashCode: checkParam.hashCode });\n }\n\n return currentSnapshot;\n};\n\nasync function isNeedFiles(checkParam: CreateCheckParams, logOpts: LogOpts)\n : Promise<{ needFilesStatus: boolean; snapshotFoundedByHashcode: SnapshotDocument | null; }> {\n const snapshotFoundedByHashcode = await getSnapshotByImgHash(checkParam.hashCode);\n\n if (!checkParam.hashCode && !checkParam.files) {\n log.debug('hashCode or files parameters should be present', logOpts);\n return { needFilesStatus: true, snapshotFoundedByHashcode };\n }\n\n if (!checkParam.files && !snapshotFoundedByHashcode) {\n log.debug(`cannot find the snapshot with hash: '${checkParam.hashCode}'`, logOpts);\n return { needFilesStatus: true, snapshotFoundedByHashcode };\n }\n return { needFilesStatus: false, snapshotFoundedByHashcode };\n}\n\nasync function inspectBaseline(\n newCheckParams: CreateCheckParamsExtended,\n storedBaseline: BaselineDocument | null,\n checkIdent: IdentType,\n currentSnapshot: SnapshotDocument,\n logOpts: LogOpts\n): Promise<{ inspectBaselineParams: CreateCheckParamsExtended, currentBaselineSnapshot: SnapshotDocument }> {\n\n let currentBaselineSnapshot: SnapshotDocument | null = null;\n const params: Partial<(CreateCheckParamsExtended)> = {};\n params.failReasons = [];\n if (storedBaseline !== null) {\n log.debug(`a baseline for check name: '${newCheckParams.name}', id: '${storedBaseline.snapshootId}' is already exists`, logOpts);\n if (!isBaselineValid(storedBaseline)) {\n newCheckParams.failReasons.push('invalid_baseline');\n }\n Object.assign(params, updateCheckParamsFromBaseline(newCheckParams, storedBaseline));\n currentBaselineSnapshot = await Snapshot.findById(storedBaseline.snapshootId);\n if (!currentBaselineSnapshot) throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, `Cannot find the snapshot with id: ${storedBaseline.snapshootId}`);\n } else {\n const checksWithSameIdent = await getNotPendingChecksByIdent(checkIdent);\n if (checksWithSameIdent.length > 0) {\n log.error(`checks with ident'${JSON.stringify(checkIdent)}' exist, but baseline is absent`, logOpts);\n params.failReasons.push('not_accepted');\n params.baselineId = currentSnapshot.id.toString();\n currentBaselineSnapshot = currentSnapshot;\n } else {\n params.baselineId = currentSnapshot.id;\n params.status = 'new';\n currentBaselineSnapshot = currentSnapshot;\n log.debug(`create the new check with params: '${prettyCheckParams(params)}'`, logOpts);\n }\n }\n\n return { inspectBaselineParams: params as CreateCheckParamsExtended, currentBaselineSnapshot };\n}\n\ntype DimensionType = { height: number, width: number };\n\nconst ignoreDifferentResolutions = ({ height, width }: DimensionType) => {\n if ((width === 0) && (height === -1)) return true;\n if ((width === 0) && (height === 1)) return true;\n return false;\n};\n\ninterface CompareResult {\n failReasons: string[];\n diffId: string;\n diffSnapshot: SnapshotDocument;\n status: string;\n result: string;\n isSameDimensions: boolean;\n dimensionDifference: DimensionType;\n}\n\nconst compare = async (\n expectedSnapshot: SnapshotDocument,\n actualSnapshot: SnapshotDocument,\n newCheckParams: CreateCheckParamsExtended,\n // vShifting: boolean,\n skipSaveOnCompareError: boolean,\n currentUser: UserDocument\n): Promise<CompareResult> => {\n const logOpts: LogOpts = {\n scope: 'createCheck.compare',\n user: currentUser.username,\n itemType: 'check',\n msgType: 'COMPARE',\n };\n\n const executionTimer = process.hrtime();\n const compareResult: Partial<CompareResult> = {};\n compareResult.failReasons = [...newCheckParams.failReasons];\n\n let checkCompareResult: SnapshotDiff;\n let diffSnapshot: SnapshotDocument | null = null;\n\n const areSnapshotsDifferent = (result: SnapshotDiff) => result.rawMisMatchPercentage.toString() !== '0';\n const areSnapshotsWrongDimensions = (result: Partial<CompareResult>) => !result.isSameDimensions && !ignoreDifferentResolutions(result.dimensionDifference!);\n\n if ((newCheckParams.status !== 'new') && (!compareResult.failReasons.includes('not_accepted'))) {\n try {\n log.debug(`'the check with name: '${newCheckParams.name}' isn't new, make comparing'`, logOpts);\n checkCompareResult = await compareSnapshots(expectedSnapshot, actualSnapshot, { vShifting: newCheckParams.vShifting });\n log.silly(`ignoreDifferentResolutions: '${ignoreDifferentResolutions(checkCompareResult.dimensionDifference)}'`);\n log.silly(`dimensionDifference: '${JSON.stringify(checkCompareResult.dimensionDifference)}`);\n\n if (areSnapshotsDifferent(checkCompareResult) || areSnapshotsWrongDimensions(checkCompareResult)) {\n let logMsg;\n if (areSnapshotsWrongDimensions(checkCompareResult)) {\n logMsg = 'snapshots have different dimensions';\n compareResult.failReasons.push('wrong_dimensions');\n }\n if (areSnapshotsDifferent(checkCompareResult)) {\n logMsg = 'snapshots have differences';\n compareResult.failReasons.push('different_images');\n }\n\n if (logMsg) log.debug(logMsg, logOpts);\n log.debug(`saving diff snapshot for check with name: '${newCheckParams.name}'`, logOpts);\n if (!skipSaveOnCompareError) {\n diffSnapshot = await createSnapshot({\n name: newCheckParams.name,\n fileData: checkCompareResult.getBuffer!(),\n });\n compareResult.diffId = diffSnapshot.id;\n compareResult.diffSnapshot = diffSnapshot;\n }\n compareResult.status = 'failed';\n } else {\n compareResult.status = 'passed';\n }\n\n checkCompareResult.totalCheckHandleTime = process.hrtime(executionTimer).toString();\n compareResult.result = JSON.stringify(checkCompareResult, null, '\\t');\n } catch (e: unknown) {\n // compareResult.updatedDate = Date.now();\n compareResult.status = 'failed';\n compareResult.result = JSON.stringify({ server_error: `error during comparing - ${errMsg(e)}` });\n compareResult.failReasons.push('internal_server_error');\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, `error during comparing: ${errMsg(e)}`);\n }\n }\n\n if (compareResult.failReasons.length > 0) {\n compareResult.status = 'failed';\n }\n return compareResult as CompareResult;\n};\n\nexport interface CreateCheckParams {\n name: string;\n // status: 'new' | 'pending' | 'passed' | 'failed' | 'blinking';\n status: 'new' | 'pending' | 'passed' | 'failed';\n viewport: string;\n browserName: string;\n browserVersion: string;\n browserFullVersion: string;\n os: string;\n updatedDate: number;\n suite: string;\n app: string;\n branch: string;\n domDump?: string;\n run: string;\n creatorId: string;\n creatorUsername: string;\n failReasons: string[];\n actualSnapshotId?: string\n result?: string,\n files?: { file: UploadedFile },\n hashCode: string,\n vShifting?: boolean\n}\nexport interface CreateCheckParamsExtended {\n test: string;\n name: string;\n // status: 'new' | 'pending' | 'passed' | 'failed' | 'blinking';\n status: 'new' | 'pending' | 'passed' | 'failed';\n viewport: string;\n browserName: string;\n browserVersion: string;\n browserFullVersion: string;\n os: string;\n updatedDate: number;\n suite: string;\n app: string;\n branch: string;\n domDump?: string;\n run: string;\n creatorId: string;\n creatorUsername: string;\n failReasons: string[];\n actualSnapshotId?: string\n result?: string,\n files?: { file: UploadedFile },\n hashCode: string,\n vShifting?: boolean,\n baselineId?: string,\n markedAs?: string\n markedDate?: string,\n markedByUsername?: string,\n}\n\nconst createCheckParams = (checkParam: CreateCheckParams, suite: SuiteDocument, app: AppDocument, test: TestDocument, currentUser: UserDocument): CreateCheckParamsExtended => ({\n test: test.id,\n name: checkParam.name,\n status: 'pending',\n viewport: checkParam.viewport,\n browserName: checkParam.browserName,\n browserVersion: checkParam.browserVersion,\n browserFullVersion: checkParam.browserFullVersion,\n os: checkParam.os,\n updatedDate: Date.now(),\n suite: suite.id,\n app: app.id,\n branch: checkParam.branch,\n domDump: checkParam.domDump,\n run: test.run.toString(),\n creatorId: currentUser._id.toString(),\n creatorUsername: currentUser.username,\n hashCode: checkParam.hashCode,\n failReasons: [],\n});\n\n\nconst createCheck = async (checkParam: CreateCheckParams, test: TestDocument, suite: SuiteDocument, app: AppDocument, currentUser: UserDocument, skipSaveOnCompareError = false) => {\n const logOpts: LogOpts = {\n scope: 'createCheck',\n user: currentUser.username,\n itemType: 'check',\n msgType: 'CREATE',\n };\n let actualSnapshot: SnapshotDocument;\n let currentBaselineSnapshot: SnapshotDocument;\n\n const newCheckParams = createCheckParams(checkParam, suite, app, test, currentUser);\n const checkIdent = buildIdentObject(newCheckParams);\n\n let check: CheckDocument | null = null;\n const totalCheckHandleTime = 0;\n // const diffSnapshot: object | null = null;\n\n const addCheck = (test: TestDocument, check: CheckDocument) => {\n if (test.checks) {\n test.checks.push(check.id);\n } else {\n test.checks = [check.id];\n }\n }\n\n try {\n const { needFilesStatus, snapshotFoundedByHashcode } = await isNeedFiles(checkParam, logOpts);\n if (needFilesStatus) return { status: 'needFiles' };\n\n actualSnapshot = await prepareActualSnapshot(checkParam, snapshotFoundedByHashcode, logOpts);\n newCheckParams.actualSnapshotId = actualSnapshot.id;\n\n log.info(`find a baseline for the check with identifier: '${JSON.stringify(checkIdent)}'`, logOpts);\n const storedBaseline = await getAcceptedBaseline(checkIdent);\n\n const inspectBaselineResult = await inspectBaseline(newCheckParams, storedBaseline, checkIdent, actualSnapshot, logOpts);\n Object.assign(newCheckParams, inspectBaselineResult.inspectBaselineParams);\n currentBaselineSnapshot = inspectBaselineResult.currentBaselineSnapshot;\n\n const compareResult = await compare(currentBaselineSnapshot, actualSnapshot, newCheckParams, skipSaveOnCompareError, currentUser);\n\n Object.assign(newCheckParams, compareResult);\n\n log.debug(`create the new check document with params: '${prettyCheckParams(newCheckParams)}'`, logOpts);\n check = await Check.create(newCheckParams);\n const savedCheck = await check.save();\n\n log.debug(`the check with id: '${check.id}', was created, will updated with data during creating process`, logOpts);\n logOpts.ref = String(check.id);\n log.debug(`update test with check id: '${check.id}'`, logOpts);\n\n addCheck(test, check);\n\n test.markedAs = await calculateAcceptedStatus(check.test);\n test.updatedDate = new Date();\n\n await test.save();\n\n log.debug('update suite and run', logOpts);\n\n await updateItemDate('VRSSuite', check.suite);\n await updateItemDate('VRSRun', check.run);\n\n const lastSuccessCheck = await getLastSuccessCheck(checkIdent);\n\n const checkObject = savedCheck.toObject();\n\n type CheckResult = (typeof checkObject) & {\n currentSnapshot: SnapshotDocument,\n expectedSnapshot: SnapshotDocument,\n diffSnapshot: SnapshotDocument,\n executeTime: number,\n lastSuccess: string,\n }\n\n const result: CheckResult = {\n ...checkObject,\n currentSnapshot: actualSnapshot,\n expectedSnapshot: currentBaselineSnapshot,\n diffSnapshot: compareResult.diffSnapshot,\n executeTime: totalCheckHandleTime,\n lastSuccess: lastSuccessCheck ? lastSuccessCheck.id : null,\n };\n\n return result;\n } catch (e: unknown) {\n newCheckParams.status = 'failed';\n newCheckParams.result = `{ \"server error\": \"${errMsg(e)}\" }`;\n newCheckParams.failReasons.push('internal_server_error');\n\n if (!check) {\n log.debug(`create the new check document with params: '${prettyCheckParams(newCheckParams)}'`, logOpts);\n check = await Check.create(newCheckParams);\n await check.save();\n } else {\n check.set(newCheckParams)\n await check.save();\n }\n\n log.debug(`the check with id: '${check.id}', was created, will updated with data during creating process`, logOpts);\n logOpts.ref = check.id;\n log.debug(`update test with check id: '${check.id}'`, logOpts);\n addCheck(test, check);\n await test.save();\n\n throw new ApiError(StatusCodes.INTERNAL_SERVER_ERROR, errMsg(e));\n }\n};\n\nconst getIdent = () => ident;\n\nconst getBaselines = async (filter: RequiredIdentOptionsType, options: PaginateOptions) => {\n const logOpts: LogOpts = {\n scope: 'getBaselines',\n itemType: 'baseline',\n msgType: 'GET',\n };\n const app = await App.findOne({ name: filter.app });\n if (!app) {\n log.error(`Cannot find the app: '${filter.app}'`, logOpts);\n return {};\n }\n filter.app = app._id;\n log.debug(`Get baselines with filter: '${JSON.stringify(filter)}', options: '${JSON.stringify(options)}'`, logOpts);\n return Baseline.paginate(filter, options);\n};\n\nexport {\n startSession,\n endSession,\n createCheck,\n getIdent,\n getBaselines,\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport mongoose from 'mongoose';\nimport log from \"@logger\";\n\n\nexport async function updateItem(itemType: string, filter: any, params: any): Promise<any> {\n const logOpts = {\n scope: 'updateItem',\n msgType: 'UPDATE',\n itemType,\n };\n log.debug(`update item type: '${itemType}', filter: '${JSON.stringify(filter)}', params: '${JSON.stringify(params)}'`, logOpts);\n const itemModel = await mongoose.model(itemType).findOne(filter);\n const updatedItem = await itemModel?.updateOne(params);\n log.debug(`'${itemType}' was updated: '${JSON.stringify(updatedItem)}'`, { ...logOpts, ...{ ref: String(itemModel?._id) } });\n return updatedItem;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport mongoose from 'mongoose';\nimport log from \"@logger\";\n\n\nconst logOpts = {\n scope: 'dbitems',\n msgType: 'DB',\n};\n\nexport async function updateItemDate(mdClass: string, id: any): Promise<any> {\n log.debug(`update date for the item: '${mdClass}' with id: '${id}'`, logOpts);\n const itemModel = await mongoose.model(mdClass).findById(id);\n const updatedItem = await itemModel?.updateOne({ updatedDate: Date.now() });\n log.debug(`'${mdClass}' date updated: '${JSON.stringify(itemModel)}'`, logOpts);\n return updatedItem;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport mongoose from 'mongoose';\nimport log from \"@logger\";\n\nexport async function createItemIfNotExist(modelName: string, params: any, logsMeta = {}): Promise<any> {\n const logOpts = {\n scope: 'createItemIfNotExist',\n msgType: 'CREATE',\n itemType: modelName,\n };\n try {\n const itemModel = mongoose.model(modelName);\n const options = {\n upsert: true,\n new: true,\n setDefaultsOnInsert: true,\n };\n\n await itemModel.init();\n const item = await itemModel.findOneAndUpdate(params, params, options);\n\n log.info(`ORM item '${modelName}' was created: '${JSON.stringify(item)}'`, { ...logOpts, ...{ ref: String(item?._id) }, ...logsMeta });\n return item;\n } catch (e: any) {\n log.debug(`cannot create '${modelName}' ORM item, error: '${e.stack || e}'`, { ...logOpts, ...logsMeta });\n }\n return null;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport mongoose from 'mongoose';\nimport log from \"@logger\";\n\nconst logOpts = {\n scope: 'dbitems',\n msgType: 'DB',\n};\n\nexport async function createItemProm(modelName: string, params: any): Promise<any> {\n try {\n const itemModel = mongoose.model(modelName);\n log.debug(`start to create ORM item via promise: '${modelName}', params: '${JSON.stringify(params)}'`, logOpts);\n const item = await itemModel.create(params);\n return item;\n } catch (e: any) {\n const errMsg = `cannot create '${modelName}', error: '${e.stack || e}'`;\n log.error(errMsg, logOpts);\n throw new Error(errMsg);\n }\n}\n","/* eslint-disable @typescript-eslint/ban-ts-comment */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n// @ts-ignore\nimport resemble from '@syngrisi/node-resemble.js';\n\nasync function streamToBuffer(stream: any): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const data: Buffer[] = [];\n\n stream.on('data', (chunk: Buffer) => {\n data.push(chunk);\n });\n\n stream.on('end', () => {\n resolve(Buffer.concat(data));\n });\n\n stream.on('error', (err: Error) => {\n reject(err);\n });\n });\n}\n\nexport default function compareImages(image1: any, image2: any, options: any): Promise<any> {\n return new Promise((resolve, reject) => {\n try {\n const ignoreTransform: any = {\n antialiasing: 'ignoreAntialiasing',\n colors: 'ignoreColors',\n nothing: 'ignoreNothing',\n };\n const ignoreMethod = ignoreTransform[options.ignore] ? ignoreTransform[options.ignore] : 'ignoreNothing';\n console.log('ignoreMethod', ignoreMethod);\n console.log('ignoreMethod', ignoreMethod);\n console.log('ignoreMethod', ignoreMethod);\n console.log('ignoreMethod', ignoreMethod);\n console.log('ignoreMethod', ignoreMethod);\n console.log('ignoreMethod', ignoreMethod);\n console.log('ignoreMethod', ignoreMethod);\n console.log('ignoreMethod', ignoreMethod);\n\n const outputOpts = options.output;\n resemble.outputSettings(outputOpts);\n let ignoredRect;\n if (options.ignoreRectangles) {\n ignoredRect = options.ignoreRectangles.map((it: any) => {\n delete it.name;\n return [it.left, it.top, it.right - it.left, it.bottom - it.top];\n });\n }\n\n resemble(image1)\n .compareTo(image2)[ignoreMethod]()\n .ignoreRectangles(ignoredRect)\n .onComplete(async (data: any) => {\n console.log(data);\n const stream = await data.getDiffImage();\n const buffer = await streamToBuffer(stream.pack());\n data.getBuffer = function () {\n return buffer;\n };\n resolve(data);\n });\n } catch (e) {\n reject(e);\n }\n });\n}\n","/* eslint-disable @typescript-eslint/ban-ts-comment */\nimport httpStatus from 'http-status';\nimport { User } from '@models';\nimport { ApiError } from '@utils';\nimport log from \"../lib/logger\";\nimport { UserCreateReq } from '../schemas/User.schema';\nimport { FilterQuery } from 'mongoose';\nimport { PaginateOptions } from '../models/plugins/utils';\n\nconst createUser = async (userBody: UserCreateReq) => {\n // @ts-ignore\n if (await User.isEmailTaken(userBody.username)) {\n throw new ApiError(httpStatus.BAD_REQUEST, 'Email already taken');\n }\n const logOpts = {\n msgType: 'CREATE',\n itemType: 'user',\n ref: userBody.username,\n scope: 'createUser',\n };\n log.debug(`create the user with name '${userBody.username}', params: '${JSON.stringify(userBody)}'`, logOpts);\n\n const user = await User.create({ ...userBody, createdDate: Date.now() });\n\n const updatedUser = await user.setPassword(userBody.password);\n await updatedUser.save();\n\n log.debug(`password for user: '${userBody.username}' set successfully`, logOpts);\n\n const userWithSelectedFields = await User.findById(updatedUser._id)\n .select('username firstName lastName role createdDate updatedDate createdDate')\n .exec();\n\n return userWithSelectedFields;\n};\nconst queryUsers = async (filter: FilterQuery<typeof Test>, options: PaginateOptions) => {\n const users = await User.paginate(filter, options);\n return users;\n};\n\nconst getUserById = async (id: string) => User.findById(id)\n .select('username firstName lastName role createdDate updatedDate createdDate')\n .exec();\n\nconst getUserByEmail = async (email: string) => User.findOne({ email });\n\nconst updateUserById = async (userId: string, updateBody: UserCreateReq) => {\n const logOpts = {\n msgType: 'UPDATE',\n itemType: 'user',\n scope: 'updateUserById',\n ref: userId,\n };\n\n log.info(`update user with id: '${userId}' name '${updateBody.username}', params: '${JSON.stringify(updateBody)}'`, logOpts);\n const user = await getUserById(userId);\n if (!user) {\n throw new ApiError(httpStatus.NOT_FOUND, 'User not found');\n }\n // @ts-ignore\n if (updateBody.email && (await User.isEmailTaken(updateBody.email, userId))) {\n throw new ApiError(httpStatus.BAD_REQUEST, 'Email already taken');\n }\n if (updateBody.password) {\n log.debug(`update password for '${updateBody.username}'`, logOpts);\n await user.setPassword(updateBody.password);\n await user.save();\n log.debug(`password for '${updateBody.username}' was updated`, logOpts);\n }\n log.debug(`user '${updateBody.username}' was updated successfully`, logOpts);\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { password, ...newupdateBody } = updateBody;\n Object.assign(user, {\n ...newupdateBody, updatedDate: Date.now(),\n });\n await user.save();\n return user;\n};\n\nconst deleteUserById = async (userId: string) => User.findByIdAndDelete(userId).exec();\n\nexport {\n createUser,\n queryUsers,\n getUserById,\n getUserByEmail,\n updateUserById,\n deleteUserById,\n};\n"],"mappings":"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","names":["loadTestUser","screenshots","status","task_handle_database_consistency","task_handle_old_checks","task_remove_old_logs","task_test","path","import_bson","mongoose","import_mongoose","mongoose","import_mongoose","mongoose","import_mongoose","mongoose","import_mongoose","mongoose","import_mongoose","mongoose","import_mongoose","mongoose","import_mongoose","passportLocalMongoose","mongoose","import_mongoose","mongoose","import_mongoose","mongoose","import_dotenv","import_crypto","dotenv","path","crypto","dotenv","fs","crypto","import_path","path","winston","import_http_status","import_mongoose","import_fs","st","fs","fsp","errMsg","import_mongoose","import_mongoose","import_mongoose","import_mongoose","import_http_status","import_http_status","task_test","task_handle_old_checks","task_handle_database_consistency","task_remove_old_logs","status","screenshots","loadTestUser"]}