@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,4289 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/server/controllers/index.ts
31
+ var controllers_exports = {};
32
+ __export(controllers_exports, {
33
+ appController: () => app_controller_exports,
34
+ baselineController: () => baseline_controller_exports,
35
+ checkController: () => check_controller_exports,
36
+ clientController: () => client_controller_exports,
37
+ logsController: () => logs_controller_exports,
38
+ runsController: () => runs_controller_exports,
39
+ settingsController: () => settings_controller_exports,
40
+ snapshotsController: () => snapshots_controller_exports,
41
+ suiteController: () => suite_controller_exports,
42
+ tasksController: () => tasks_controller_exports,
43
+ testController: () => test_controller_exports,
44
+ usersController: () => users_controller_exports
45
+ });
46
+ module.exports = __toCommonJS(controllers_exports);
47
+
48
+ // src/server/controllers/baseline.controller.ts
49
+ var baseline_controller_exports = {};
50
+ __export(baseline_controller_exports, {
51
+ get: () => get3,
52
+ put: () => put2
53
+ });
54
+ var import_http_status6 = __toESM(require("http-status"));
55
+
56
+ // src/server/utils/pick.ts
57
+ var pick = (object, keys) => {
58
+ return keys.reduce((obj, key) => {
59
+ if (object && Object.prototype.hasOwnProperty.call(object, key)) {
60
+ if (object[key] !== void 0) obj[key] = object[key];
61
+ }
62
+ return obj;
63
+ }, {});
64
+ };
65
+ var pick_default = pick;
66
+
67
+ // src/server/utils/isJSON.ts
68
+ var isJSON = (text) => {
69
+ if (!text) return false;
70
+ const isValid = /^[\],:{}\s]*$/.test(
71
+ text.replace(/\\["\\\/bfnrtu]/g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, "")
72
+ );
73
+ return isValid;
74
+ };
75
+ var isJSON_default = isJSON;
76
+
77
+ // src/server/utils/catchAsync.ts
78
+ var catchAsync = (fn) => (req, res, next) => {
79
+ Promise.resolve(fn(req, res, next)).catch((err) => {
80
+ return next(err);
81
+ });
82
+ };
83
+ var catchAsync_default = catchAsync;
84
+
85
+ // src/server/utils/dateToISO8601.ts
86
+ var dateToISO8601 = (date) => {
87
+ return new Date(new Date(date)).toISOString().split("T")[0];
88
+ };
89
+ var dateToISO8601_default = dateToISO8601;
90
+
91
+ // src/server/utils/ProgressBar.ts
92
+ var ProgressBar = class {
93
+ constructor(length) {
94
+ this.length = length;
95
+ this.percentLenght = parseFloat((length / 100).toString());
96
+ this.prevPercent = 0;
97
+ this.currentPercent = 0;
98
+ this.progressString = "";
99
+ }
100
+ isChange(current2) {
101
+ this.currentPercent = parseInt((current2 / this.percentLenght).toString(), 10);
102
+ if (this.prevPercent === this.currentPercent) {
103
+ return false;
104
+ }
105
+ this.prevPercent = this.currentPercent;
106
+ this.progressString += "#";
107
+ return true;
108
+ }
109
+ writeIfChange(index, count, fn, res) {
110
+ if (this.isChange(index)) {
111
+ const placeholderString = Array.from(new Array(99 - this.currentPercent)).reduce((accum) => accum += ".", "");
112
+ fn(`[${this.progressString}${placeholderString}](${index}/${count})`, res);
113
+ }
114
+ }
115
+ };
116
+
117
+ // src/server/utils/ApiError.ts
118
+ var ApiError = class extends Error {
119
+ constructor(statusCode, message, isOperational = true, stack = "") {
120
+ super(message);
121
+ this.statusCode = statusCode;
122
+ this.isOperational = isOperational;
123
+ if (stack) {
124
+ this.stack = stack;
125
+ } else {
126
+ Error.captureStackTrace(this, this.constructor);
127
+ }
128
+ }
129
+ };
130
+ var ApiError_default = ApiError;
131
+
132
+ // src/server/utils/removeEmptyProperties.ts
133
+ var removeEmptyProperties = (obj) => Object.fromEntries(
134
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
135
+ Object.entries(obj).filter(([_, v]) => v != null && v !== "")
136
+ );
137
+
138
+ // src/server/utils/deserializeIfJSON.ts
139
+ var import_bson = require("bson");
140
+ var deserializeIfJSON = (text) => {
141
+ if (isJSON_default(text)) return import_bson.EJSON.parse(text) || void 0;
142
+ return text;
143
+ };
144
+ var deserializeIfJSON_default = deserializeIfJSON;
145
+
146
+ // src/server/utils/prettyCheckParams.ts
147
+ var prettyCheckParams = (result) => {
148
+ if (!result.domDump) {
149
+ return JSON.stringify(result);
150
+ }
151
+ const dump = JSON.parse(result.domDump);
152
+ const resObs = { ...result };
153
+ delete resObs.domDump;
154
+ resObs.domDump = `${JSON.stringify(dump).substr(0, 20)}... and about ${dump.length} items]`;
155
+ return JSON.stringify(resObs);
156
+ };
157
+ var prettyCheckParams_default = prettyCheckParams;
158
+
159
+ // src/server/utils/waitUntil.ts
160
+ var waitUntil = async (cb, attempts = 5, interval = 700) => {
161
+ let result = false;
162
+ let iteration = 0;
163
+ while (result === false) {
164
+ result = await cb();
165
+ await new Promise((r) => setTimeout(r, interval));
166
+ iteration += 1;
167
+ if (iteration > attempts) {
168
+ result = true;
169
+ }
170
+ }
171
+ return result;
172
+ };
173
+
174
+ // src/server/utils/paramsGuard.ts
175
+ var paramsGuard = (params, functionName, schema) => {
176
+ const result = schema.safeParse(params);
177
+ if (result.success) {
178
+ return true;
179
+ } else {
180
+ const errorDetails = result.error.format();
181
+ throw new Error(`
182
+ Invalid '${functionName}' parameters: ${JSON.stringify(errorDetails)}
183
+
184
+ error: ${result.error.stack || result.error}
185
+
186
+ params: ${JSON.stringify(params, null, 2)}
187
+ `);
188
+ }
189
+ };
190
+
191
+ // src/server/utils/ident.ts
192
+ var ident = ["name", "viewport", "browserName", "os", "app", "branch"];
193
+
194
+ // src/server/utils/buildIdentObject.ts
195
+ var MissingIdentFieldError = class extends Error {
196
+ constructor(field) {
197
+ super(`Missing required ident field: ${field}`);
198
+ this.name = "MissingIdentFieldError";
199
+ }
200
+ };
201
+ var buildIdentObject = (params) => {
202
+ const result = {};
203
+ for (const key of ident) {
204
+ if (key in params && params[key] !== void 0) {
205
+ result[key] = params[key];
206
+ } else {
207
+ throw new MissingIdentFieldError(key);
208
+ }
209
+ }
210
+ return result;
211
+ };
212
+
213
+ // src/server/models/Check.model.ts
214
+ var import_mongoose = __toESM(require("mongoose"));
215
+
216
+ // src/server/models/plugins/paginate.plugin.ts
217
+ var paginate = (schema) => {
218
+ schema.statics.paginate = async function(filter, options) {
219
+ let sort;
220
+ if (options.sortBy) {
221
+ const sortingCriteria = [];
222
+ options.sortBy.split(",").forEach((sortOption) => {
223
+ const [key, order] = sortOption.split(":");
224
+ sortingCriteria.push((order === "desc" ? "-" : "") + key);
225
+ });
226
+ sort = sortingCriteria.join(" ");
227
+ } else {
228
+ sort = { _id: -1 };
229
+ }
230
+ const limit = options.limit && parseInt(options.limit.toString(), 10) >= 0 ? parseInt(options.limit.toString(), 10) : 10;
231
+ const page = options.page && parseInt(options.page.toString(), 10) > 0 ? parseInt(options.page.toString(), 10) : 1;
232
+ const skip = (page - 1) * limit;
233
+ const countPromise = this.countDocuments(filter).exec();
234
+ let docsPromise = this.find(filter).sort(sort).skip(skip).limit(limit);
235
+ if (options.populate) {
236
+ options.populate.split(",").forEach((populateOption) => {
237
+ docsPromise = docsPromise.populate(
238
+ populateOption.split(".").reverse().reduce((a, b) => ({ path: b, populate: a }))
239
+ );
240
+ });
241
+ }
242
+ docsPromise = docsPromise.exec();
243
+ return Promise.all([countPromise, docsPromise]).then((values) => {
244
+ const [totalResults, results] = values;
245
+ const totalPages = Math.ceil(totalResults / limit);
246
+ const result = {
247
+ results,
248
+ page,
249
+ limit,
250
+ totalPages,
251
+ totalResults,
252
+ timestamp: Number(Date.now() + String(process.hrtime()[1]).slice(3, 6))
253
+ };
254
+ return Promise.resolve(result);
255
+ });
256
+ };
257
+ };
258
+ var paginate_plugin_default = paginate;
259
+
260
+ // src/server/models/plugins/toJSON.plugin.ts
261
+ var deleteAtPath = (obj, path3, index) => {
262
+ if (index === path3.length - 1) {
263
+ delete obj[path3[index]];
264
+ return;
265
+ }
266
+ deleteAtPath(obj[path3[index]], path3, index + 1);
267
+ };
268
+ var toJSON = (schema) => {
269
+ let transform;
270
+ if (schema.options.toJSON && schema.options.toJSON.transform) {
271
+ transform = schema.options.toJSON.transform;
272
+ }
273
+ schema.options.toJSON = Object.assign(schema.options.toJSON || {}, {
274
+ transform(doc, ret, options) {
275
+ Object.keys(schema.paths).forEach((path3) => {
276
+ if (schema.paths[path3].options && schema.paths[path3].options.private) {
277
+ deleteAtPath(ret, path3.split("."), 0);
278
+ }
279
+ });
280
+ ret.id = ret._id.toString();
281
+ delete ret.__v;
282
+ delete ret.createdAt;
283
+ delete ret.updatedAt;
284
+ if (transform) {
285
+ return transform(doc, ret, options);
286
+ }
287
+ }
288
+ });
289
+ };
290
+ var toJSON_plugin_default = toJSON;
291
+
292
+ // src/server/models/plugins/paginateDistinct.plugin.ts
293
+ var import_bson2 = require("bson");
294
+ var paginateDistinct = (schema) => {
295
+ schema.statics.paginateDistinct = async function(filter, options) {
296
+ let sort;
297
+ if (options.sortBy) {
298
+ options.sortBy.split(",").forEach((sortOption) => {
299
+ const [key, order] = sortOption.split(":");
300
+ sort[key] = order === "desc" ? -1 : 1;
301
+ });
302
+ } else {
303
+ sort = { _id: -1 };
304
+ }
305
+ let limit = options.limit && parseInt(options.limit.toString(), 10) >= 0 ? parseInt(options.limit.toString(), 10) : 10;
306
+ limit = limit === 0 ? 9007199254740991 : limit;
307
+ const page = options.page && parseInt(options.page.toString(), 10) > 0 ? parseInt(options.page.toString(), 10) : 1;
308
+ const skip = (page - 1) * limit;
309
+ const groupAggregateObj = { $group: { _id: `$${options.field}` } };
310
+ const documentsCount = (await this.aggregate([groupAggregateObj]).exec()).length;
311
+ const aggregateArr = [
312
+ { $match: import_bson2.EJSON.parse(filter.filter || "{}") },
313
+ groupAggregateObj,
314
+ { $sort: sort },
315
+ { $skip: skip },
316
+ { $limit: limit }
317
+ ];
318
+ const aggregatedDocs = (await this.aggregate(aggregateArr)).filter((x) => x._id).map((x) => {
319
+ if (x[options.field]) {
320
+ return x[options.field][0];
321
+ }
322
+ return { name: x._id };
323
+ });
324
+ return Promise.all([documentsCount, aggregatedDocs]).then((values) => {
325
+ const [totalResults, results] = values;
326
+ const totalPages = Math.ceil(totalResults / limit);
327
+ const result = {
328
+ results,
329
+ page,
330
+ limit,
331
+ totalPages,
332
+ totalResults,
333
+ timestamp: (/* @__PURE__ */ new Date()).getTime()
334
+ };
335
+ return Promise.resolve(result);
336
+ });
337
+ };
338
+ };
339
+ var paginateDistinct_plugin_default = paginateDistinct;
340
+
341
+ // src/server/models/Check.model.ts
342
+ var CheckSchema = new import_mongoose.Schema({
343
+ name: {
344
+ type: String,
345
+ required: [true, 'CheckSchema: The "name" field must be required']
346
+ },
347
+ test: {
348
+ type: import_mongoose.Schema.Types.ObjectId,
349
+ ref: "VRSTest",
350
+ required: [true, 'CheckSchema: The "test" field must be required']
351
+ },
352
+ suite: {
353
+ type: import_mongoose.Schema.Types.ObjectId,
354
+ ref: "VRSSuite",
355
+ required: [true, 'CheckSchema: The "suite" field must be required']
356
+ },
357
+ app: {
358
+ type: import_mongoose.Schema.Types.ObjectId,
359
+ ref: "VRSApp",
360
+ required: [true, 'CheckSchema: The "app" field must be required']
361
+ },
362
+ branch: {
363
+ type: String
364
+ },
365
+ realBaselineId: {
366
+ type: import_mongoose.Schema.Types.ObjectId,
367
+ ref: "VRSBaseline"
368
+ },
369
+ baselineId: {
370
+ type: import_mongoose.Schema.Types.ObjectId,
371
+ ref: "VRSSnapshot"
372
+ },
373
+ actualSnapshotId: {
374
+ type: import_mongoose.Schema.Types.ObjectId,
375
+ ref: "VRSSnapshot"
376
+ },
377
+ diffId: {
378
+ type: import_mongoose.Schema.Types.ObjectId,
379
+ ref: "VRSSnapshot"
380
+ },
381
+ createdDate: {
382
+ type: Date,
383
+ required: true,
384
+ default: Date.now
385
+ },
386
+ updatedDate: {
387
+ type: Date
388
+ },
389
+ status: {
390
+ type: [{
391
+ type: String,
392
+ enum: {
393
+ values: ["new", "pending", "approved", "running", "passed", "failed", "aborted"],
394
+ message: "status is required"
395
+ }
396
+ }],
397
+ default: ["new"]
398
+ },
399
+ browserName: {
400
+ type: String
401
+ },
402
+ browserVersion: {
403
+ type: String
404
+ },
405
+ browserFullVersion: {
406
+ type: String
407
+ },
408
+ viewport: {
409
+ type: String
410
+ },
411
+ os: {
412
+ type: String
413
+ },
414
+ domDump: {
415
+ type: String
416
+ },
417
+ result: {
418
+ type: String,
419
+ default: "{}"
420
+ },
421
+ run: {
422
+ type: import_mongoose.Schema.Types.ObjectId
423
+ },
424
+ markedAs: {
425
+ type: String,
426
+ enum: ["bug", "accepted"]
427
+ },
428
+ markedDate: {
429
+ type: Date
430
+ },
431
+ markedById: {
432
+ type: import_mongoose.Schema.Types.ObjectId,
433
+ ref: "VRSUser"
434
+ },
435
+ markedByUsername: {
436
+ type: String
437
+ },
438
+ markedBugComment: {
439
+ type: String
440
+ },
441
+ creatorId: {
442
+ type: import_mongoose.Schema.Types.ObjectId,
443
+ ref: "VRSUser"
444
+ },
445
+ creatorUsername: {
446
+ type: String
447
+ },
448
+ failReasons: {
449
+ type: [String]
450
+ },
451
+ vOffset: {
452
+ type: String
453
+ },
454
+ topStablePixels: {
455
+ type: String
456
+ },
457
+ meta: {
458
+ type: Object
459
+ }
460
+ });
461
+ CheckSchema.plugin(toJSON_plugin_default);
462
+ CheckSchema.plugin(paginate_plugin_default);
463
+ var Check = import_mongoose.default.model("VRSCheck", CheckSchema);
464
+ var Check_model_default = Check;
465
+
466
+ // src/server/models/Log.model.ts
467
+ var import_mongoose2 = __toESM(require("mongoose"));
468
+ var LogSchema = new import_mongoose2.Schema({
469
+ timestamp: {
470
+ type: Date
471
+ },
472
+ level: {
473
+ type: String
474
+ },
475
+ message: {
476
+ type: String
477
+ },
478
+ meta: {
479
+ type: Object
480
+ },
481
+ hostname: {
482
+ type: Object
483
+ }
484
+ });
485
+ LogSchema.plugin(toJSON_plugin_default);
486
+ LogSchema.plugin(paginate_plugin_default);
487
+ var Log = import_mongoose2.default.model("VRSLog", LogSchema);
488
+ var Log_model_default = Log;
489
+
490
+ // src/server/models/App.model.ts
491
+ var import_mongoose3 = __toESM(require("mongoose"));
492
+ var AppSchema = new import_mongoose3.Schema({
493
+ name: {
494
+ type: String,
495
+ default: "Others",
496
+ unique: true,
497
+ required: [true, 'AppSchema: The "name" field must be required']
498
+ },
499
+ description: {
500
+ type: String
501
+ },
502
+ version: {
503
+ type: String
504
+ },
505
+ updatedDate: {
506
+ type: Date
507
+ },
508
+ createdDate: {
509
+ type: Date
510
+ },
511
+ meta: {
512
+ type: Object
513
+ }
514
+ });
515
+ AppSchema.plugin(paginate_plugin_default);
516
+ AppSchema.plugin(toJSON_plugin_default);
517
+ var App = import_mongoose3.default.model("VRSApp", AppSchema);
518
+ var App_model_default = App;
519
+
520
+ // src/server/models/Snapshot.model.ts
521
+ var import_mongoose4 = __toESM(require("mongoose"));
522
+ var SnapshotSchema = new import_mongoose4.Schema({
523
+ name: {
524
+ type: String,
525
+ required: [true, 'SnapshotSchema: The "name" field must be required']
526
+ },
527
+ path: {
528
+ type: String
529
+ },
530
+ filename: {
531
+ type: String
532
+ },
533
+ imghash: {
534
+ type: String,
535
+ required: [true, 'SnapshotSchema: The "imghash" field must be required']
536
+ },
537
+ createdDate: {
538
+ type: Date,
539
+ default: Date.now
540
+ },
541
+ vOffset: {
542
+ type: Number
543
+ },
544
+ hOffset: {
545
+ type: Number
546
+ }
547
+ });
548
+ SnapshotSchema.plugin(toJSON_plugin_default);
549
+ SnapshotSchema.plugin(paginate_plugin_default);
550
+ var Snapshot = import_mongoose4.default.model("VRSSnapshot", SnapshotSchema);
551
+ var Snapshot_model_default = Snapshot;
552
+
553
+ // src/server/models/AppSettings.model.ts
554
+ var import_mongoose5 = __toESM(require("mongoose"));
555
+ var AppSettingsSchema = new import_mongoose5.Schema({
556
+ name: {
557
+ type: String,
558
+ unique: true,
559
+ required: [true, 'AppSettingsSchema: The "name" field must be required']
560
+ },
561
+ label: {
562
+ type: String,
563
+ required: [true, 'AppSettingsSchema: The "label" field must be required']
564
+ },
565
+ description: {
566
+ type: String
567
+ },
568
+ type: {
569
+ type: String,
570
+ required: [true, 'AppSettingsSchema: The "type" field must be required']
571
+ },
572
+ value: {
573
+ type: import_mongoose5.Schema.Types.Mixed,
574
+ required: [true, 'AppSettingsSchema: The "value" field must be required']
575
+ },
576
+ env_variable: {
577
+ type: String
578
+ },
579
+ enabled: {
580
+ type: Boolean
581
+ }
582
+ });
583
+ AppSettingsSchema.plugin(toJSON_plugin_default);
584
+ var AppSettings = import_mongoose5.default.model("VRSAppSettings", AppSettingsSchema);
585
+ var AppSettings_model_default = AppSettings;
586
+
587
+ // src/server/models/Suite.model.ts
588
+ var import_mongoose6 = __toESM(require("mongoose"));
589
+ var SuiteSchema = new import_mongoose6.Schema({
590
+ name: {
591
+ type: String,
592
+ default: "Others",
593
+ unique: true,
594
+ required: [true, 'SuiteSchema: The "name" field must be required']
595
+ },
596
+ tags: {
597
+ type: [String]
598
+ },
599
+ app: {
600
+ type: import_mongoose6.Schema.Types.ObjectId,
601
+ ref: "VRSApp",
602
+ required: [true, 'SuiteSchema: The "app" field must be required']
603
+ },
604
+ description: {
605
+ type: String
606
+ },
607
+ updatedDate: {
608
+ type: Date,
609
+ default: Date.now
610
+ },
611
+ createdDate: {
612
+ type: Date
613
+ },
614
+ meta: {
615
+ type: Object
616
+ }
617
+ });
618
+ SuiteSchema.plugin(paginate_plugin_default);
619
+ SuiteSchema.plugin(toJSON_plugin_default);
620
+ var Suite = import_mongoose6.default.model("VRSSuite", SuiteSchema);
621
+ var Suite_model_default = Suite;
622
+
623
+ // src/server/models/Run.model.ts
624
+ var import_mongoose7 = __toESM(require("mongoose"));
625
+ var RunSchema = new import_mongoose7.Schema({
626
+ name: {
627
+ type: String,
628
+ required: [true, 'RunSchema: The "name" field must be required']
629
+ },
630
+ app: {
631
+ type: import_mongoose7.Schema.Types.ObjectId,
632
+ ref: "VRSApp",
633
+ required: [true, 'RunSchema: The "app" field must be required']
634
+ },
635
+ ident: {
636
+ type: String,
637
+ unique: true,
638
+ required: [true, 'RunSchema: The "ident" field must be required']
639
+ },
640
+ description: {
641
+ type: String
642
+ },
643
+ updatedDate: {
644
+ type: Date,
645
+ default: Date.now
646
+ },
647
+ createdDate: {
648
+ type: Date
649
+ },
650
+ parameters: {
651
+ type: [String]
652
+ },
653
+ meta: {
654
+ type: Object
655
+ }
656
+ });
657
+ RunSchema.plugin(paginate_plugin_default);
658
+ RunSchema.plugin(toJSON_plugin_default);
659
+ var Run = import_mongoose7.default.model("VRSRun", RunSchema);
660
+ var Run_model_default = Run;
661
+
662
+ // src/server/models/User.model.ts
663
+ var import_mongoose8 = __toESM(require("mongoose"));
664
+ var import_passport_local_mongoose = __toESM(require("passport-local-mongoose"));
665
+ var UserSchema = new import_mongoose8.Schema({
666
+ username: {
667
+ type: String,
668
+ unique: true,
669
+ required: [true, 'UserSchema: The "username" field must be required']
670
+ },
671
+ firstName: {
672
+ type: String,
673
+ required: [true, 'UserSchema: The "firstName" field must be required']
674
+ },
675
+ lastName: {
676
+ type: String,
677
+ required: [true, 'UserSchema: The "lastName" field must be required']
678
+ },
679
+ role: {
680
+ type: String,
681
+ enum: ["admin", "reviewer", "user"],
682
+ required: [true, 'UserSchema: The "role" field must be required']
683
+ },
684
+ password: {
685
+ type: String
686
+ },
687
+ token: {
688
+ type: String
689
+ },
690
+ apiKey: {
691
+ type: String
692
+ },
693
+ createdDate: {
694
+ type: Date
695
+ },
696
+ updatedDate: {
697
+ type: Date
698
+ },
699
+ expiration: {
700
+ type: Date
701
+ },
702
+ meta: {
703
+ type: Object
704
+ }
705
+ });
706
+ UserSchema.statics.isEmailTaken = async function(username, excludeUserId) {
707
+ const user = await this.findOne({ username, _id: { $ne: excludeUserId } });
708
+ return !!user;
709
+ };
710
+ UserSchema.plugin(toJSON_plugin_default);
711
+ UserSchema.plugin(paginate_plugin_default);
712
+ UserSchema.plugin(import_passport_local_mongoose.default, { hashField: "password" });
713
+ var User = import_mongoose8.default.model("VRSUser", UserSchema);
714
+ var User_model_default = User;
715
+
716
+ // src/server/models/Baseline.model.ts
717
+ var import_mongoose9 = __toESM(require("mongoose"));
718
+ var BaselineSchema = new import_mongoose9.Schema({
719
+ snapshootId: {
720
+ type: import_mongoose9.Schema.Types.ObjectId
721
+ },
722
+ name: {
723
+ type: String,
724
+ required: [true, 'VRSBaselineSchema: The "name" field must be required']
725
+ },
726
+ app: {
727
+ type: import_mongoose9.Schema.Types.ObjectId,
728
+ ref: "VRSApp",
729
+ required: [true, 'VRSBaselineSchema: The "app" field must be required']
730
+ },
731
+ branch: {
732
+ type: String
733
+ },
734
+ browserName: {
735
+ type: String
736
+ },
737
+ browserVersion: {
738
+ type: String
739
+ },
740
+ browserFullVersion: {
741
+ type: String
742
+ },
743
+ viewport: {
744
+ type: String
745
+ },
746
+ os: {
747
+ type: String
748
+ },
749
+ markedAs: {
750
+ type: String,
751
+ enum: ["bug", "accepted"]
752
+ },
753
+ lastMarkedDate: {
754
+ type: Date
755
+ },
756
+ createdDate: {
757
+ type: Date
758
+ },
759
+ updatedDate: {
760
+ type: Date
761
+ },
762
+ markedById: {
763
+ type: import_mongoose9.Schema.Types.ObjectId,
764
+ ref: "VRSUser"
765
+ },
766
+ markedByUsername: {
767
+ type: String
768
+ },
769
+ ignoreRegions: {
770
+ type: String
771
+ },
772
+ boundRegions: {
773
+ type: String
774
+ },
775
+ matchType: {
776
+ type: String,
777
+ enum: ["antialiasing", "nothing", "colors"]
778
+ },
779
+ meta: {
780
+ type: Object
781
+ }
782
+ });
783
+ BaselineSchema.plugin(toJSON_plugin_default);
784
+ BaselineSchema.plugin(paginate_plugin_default);
785
+ var Baseline = import_mongoose9.default.model("VRSBaseline", BaselineSchema);
786
+ var Baseline_model_default = Baseline;
787
+
788
+ // src/server/models/Test.model.ts
789
+ var import_mongoose10 = __toESM(require("mongoose"));
790
+ var TestSchema = new import_mongoose10.Schema(
791
+ {
792
+ name: {
793
+ type: String,
794
+ required: "TestSchema: the test name is empty"
795
+ },
796
+ description: {
797
+ type: String
798
+ },
799
+ status: {
800
+ type: String
801
+ },
802
+ browserName: {
803
+ type: String
804
+ },
805
+ browserVersion: {
806
+ type: String
807
+ },
808
+ branch: {
809
+ type: String
810
+ },
811
+ tags: {
812
+ type: [String]
813
+ },
814
+ viewport: {
815
+ type: String
816
+ },
817
+ calculatedViewport: {
818
+ type: String
819
+ },
820
+ os: {
821
+ type: String
822
+ },
823
+ app: {
824
+ type: import_mongoose10.Schema.Types.ObjectId,
825
+ ref: "VRSApp",
826
+ required: [true, 'TestSchema: The "app" field must be required']
827
+ },
828
+ blinking: {
829
+ type: Number,
830
+ default: 0
831
+ },
832
+ updatedDate: {
833
+ type: Date
834
+ },
835
+ startDate: {
836
+ type: Date
837
+ },
838
+ checks: [
839
+ {
840
+ type: import_mongoose10.default.Schema.Types.ObjectId,
841
+ ref: "VRSCheck"
842
+ }
843
+ ],
844
+ suite: {
845
+ type: import_mongoose10.Schema.Types.ObjectId,
846
+ ref: "VRSSuite"
847
+ },
848
+ run: {
849
+ type: import_mongoose10.Schema.Types.ObjectId,
850
+ ref: "VRSRun"
851
+ },
852
+ markedAs: {
853
+ type: String,
854
+ enum: ["Bug", "Accepted", "Unaccepted", "Partially"]
855
+ },
856
+ creatorId: {
857
+ type: import_mongoose10.Schema.Types.ObjectId,
858
+ ref: "VRSUser"
859
+ },
860
+ creatorUsername: {
861
+ type: String
862
+ },
863
+ meta: {
864
+ type: Object
865
+ }
866
+ },
867
+ { strictQuery: true }
868
+ );
869
+ TestSchema.plugin(toJSON_plugin_default);
870
+ TestSchema.plugin(paginate_plugin_default);
871
+ TestSchema.plugin(paginateDistinct_plugin_default);
872
+ var Test = import_mongoose10.default.model("VRSTest", TestSchema);
873
+ var Test_model_default = Test;
874
+
875
+ // src/server/utils/calculateAcceptedStatus.ts
876
+ var calculateAcceptedStatus = async function calculateAcceptedStatus2(testId) {
877
+ const checksInTest = await Check_model_default.find({ test: testId });
878
+ const statuses = checksInTest.map((x) => x.markedAs);
879
+ if (statuses.length < 1) {
880
+ return "Unaccepted";
881
+ }
882
+ let testCalculatedStatus = "Unaccepted";
883
+ if (statuses.some((x) => x === "accepted")) {
884
+ testCalculatedStatus = "Partially";
885
+ }
886
+ if (statuses.every((x) => x === "accepted")) {
887
+ testCalculatedStatus = "Accepted";
888
+ }
889
+ return testCalculatedStatus;
890
+ };
891
+
892
+ // src/server/utils/subDays.ts
893
+ var subDays = (date, days) => {
894
+ const result = new Date(date);
895
+ result.setDate(result.getDate() - days);
896
+ return result;
897
+ };
898
+ var subDays_default = subDays;
899
+
900
+ // src/server/utils/errMsg.ts
901
+ var errMsg = (e) => {
902
+ return String(e instanceof Error ? e.stack : e);
903
+ };
904
+
905
+ // src/server/services/run.service.ts
906
+ var run_service_exports = {};
907
+ __export(run_service_exports, {
908
+ remove: () => remove2
909
+ });
910
+
911
+ // src/server/lib/logger.ts
912
+ var import_winston = __toESM(require("winston"));
913
+ var import_winston_mongodb = require("winston-mongodb");
914
+ var import_chalk = require("chalk");
915
+
916
+ // src/server/utils/formatISOToDateTime.ts
917
+ function formatISOToDateTime(isoDateString) {
918
+ const date = new Date(isoDateString);
919
+ return `${date.toISOString().slice(0, 10)} ${date.toTimeString().slice(0, 8)}`;
920
+ }
921
+ var formatISOToDateTime_default = formatISOToDateTime;
922
+
923
+ // src/server/config.ts
924
+ var import_fs = __toESM(require("fs"));
925
+ var import_dotenv2 = __toESM(require("dotenv"));
926
+
927
+ // package.json
928
+ var version = "2.2.3";
929
+
930
+ // src/server/config.ts
931
+ var import_crypto2 = __toESM(require("crypto"));
932
+
933
+ // src/server/envConfig.ts
934
+ var import_envalid = require("envalid");
935
+ var import_crypto = __toESM(require("crypto"));
936
+ var import_path = __toESM(require("path"));
937
+ var import_dotenv = __toESM(require("dotenv"));
938
+ import_dotenv.default.config();
939
+ var env = (0, import_envalid.cleanEnv)(process.env, {
940
+ NODE_ENV: (0, import_envalid.str)({ choices: ["development", "production", "test"] }),
941
+ SYNGRISI_DB_URI: (0, import_envalid.str)({ devDefault: "mongodb://127.0.0.1:27017/SyngrisiDb" }),
942
+ SYNGRISI_APP_PORT: (0, import_envalid.port)({ devDefault: 3e3 }),
943
+ SYNGRISI_IMAGES_PATH: (0, import_envalid.str)({ devDefault: "./.snapshots-images/" }),
944
+ SYNGRISI_TMP_DIR: (0, import_envalid.str)({ default: import_path.default.join(process.cwd(), ".tmp") }),
945
+ SYNGRISI_HTTP_LOG: (0, import_envalid.bool)({ devDefault: false }),
946
+ SYNGRISI_COVERAGE: (0, import_envalid.bool)({ devDefault: false }),
947
+ SYNGRISI_HOSTNAME: (0, import_envalid.host)({ devDefault: "localhost" }),
948
+ SYNGRISI_AUTH: (0, import_envalid.bool)({ default: true }),
949
+ SYNGRISI_TEST_MODE: (0, import_envalid.bool)({ default: false }),
950
+ SYNGRISI_DISABLE_FIRST_RUN: (0, import_envalid.bool)({ default: false }),
951
+ MONGODB_ROOT_USERNAME: (0, import_envalid.str)({ default: "" }),
952
+ MONGODB_ROOT_PASSWORD: (0, import_envalid.str)({ default: "" }),
953
+ LOGLEVEL: (0, import_envalid.str)({ choices: ["error", "warn", "info", "verbose", "debug", "silly"], default: "debug" }),
954
+ SYNGRISI_PAGINATION_SIZE: (0, import_envalid.num)({ default: 50 }),
955
+ SYNGRISI_DISABLE_DEV_CORS: (0, import_envalid.bool)({ default: false, devDefault: true }),
956
+ SYNGRISI_SESSION_STORE_KEY: (0, import_envalid.str)({ default: import_crypto.default.randomBytes(64).toString("hex") }),
957
+ SYNGRISI_LOG_LEVEL: (0, import_envalid.str)({ default: "debug" }),
958
+ // trunk features
959
+ SYNGRISI_TRUNK_FEATURE_AI_SEVERITY: (0, import_envalid.bool)({ default: false }),
960
+ SYNGRISI_AI_KEY: (0, import_envalid.str)({ default: "" }),
961
+ OPENAI_API_BASE_URL: (0, import_envalid.str)({ default: "https://api.openai.com/v1" }),
962
+ OPENAI_API_KEY: (0, import_envalid.str)({ default: "" })
963
+ });
964
+
965
+ // src/server/data/devices.json
966
+ var devices_default = [
967
+ {
968
+ os: "ios",
969
+ os_version: "16",
970
+ device: "iPhone 14 Pro Max",
971
+ realMobile: true
972
+ },
973
+ {
974
+ os: "ios",
975
+ os_version: "16",
976
+ device: "iPhone 14 Pro",
977
+ realMobile: true
978
+ },
979
+ {
980
+ os: "ios",
981
+ os_version: "16",
982
+ device: "iPhone 14 Plus",
983
+ realMobile: true
984
+ },
985
+ {
986
+ os: "ios",
987
+ os_version: "16",
988
+ device: "iPhone 14",
989
+ realMobile: true
990
+ },
991
+ {
992
+ os: "ios",
993
+ os_version: "16",
994
+ device: "iPhone 12 Pro Max",
995
+ realMobile: true
996
+ },
997
+ {
998
+ os: "ios",
999
+ os_version: "16",
1000
+ device: "iPhone 12 Pro",
1001
+ realMobile: true
1002
+ },
1003
+ {
1004
+ os: "ios",
1005
+ os_version: "16",
1006
+ device: "iPhone 12 Mini",
1007
+ realMobile: true
1008
+ },
1009
+ {
1010
+ os: "ios",
1011
+ os_version: "16",
1012
+ device: "iPhone 11 Pro Max",
1013
+ realMobile: true
1014
+ },
1015
+ {
1016
+ os: "ios",
1017
+ os_version: "15",
1018
+ device: "iPhone XS",
1019
+ realMobile: true
1020
+ },
1021
+ {
1022
+ os: "ios",
1023
+ os_version: "15",
1024
+ device: "iPhone 13 Pro Max",
1025
+ realMobile: true
1026
+ },
1027
+ {
1028
+ os: "ios",
1029
+ os_version: "15",
1030
+ device: "iPhone 13 Pro",
1031
+ realMobile: true
1032
+ },
1033
+ {
1034
+ os: "ios",
1035
+ os_version: "15",
1036
+ device: "iPhone 13 Mini",
1037
+ realMobile: true
1038
+ },
1039
+ {
1040
+ os: "ios",
1041
+ os_version: "15",
1042
+ device: "iPhone 13",
1043
+ realMobile: true
1044
+ },
1045
+ {
1046
+ os: "ios",
1047
+ os_version: "15",
1048
+ device: "iPhone 11 Pro",
1049
+ realMobile: true
1050
+ },
1051
+ {
1052
+ os: "ios",
1053
+ os_version: "15",
1054
+ device: "iPhone 11",
1055
+ realMobile: true
1056
+ },
1057
+ {
1058
+ os: "ios",
1059
+ os_version: "14",
1060
+ device: "iPhone XS",
1061
+ realMobile: true
1062
+ },
1063
+ {
1064
+ os: "ios",
1065
+ os_version: "14",
1066
+ device: "iPhone 12 Pro Max",
1067
+ realMobile: true
1068
+ },
1069
+ {
1070
+ os: "ios",
1071
+ os_version: "14",
1072
+ device: "iPhone 12 Pro",
1073
+ realMobile: true
1074
+ },
1075
+ {
1076
+ os: "ios",
1077
+ os_version: "14",
1078
+ device: "iPhone 12 Mini",
1079
+ realMobile: true
1080
+ },
1081
+ {
1082
+ os: "ios",
1083
+ os_version: "14",
1084
+ device: "iPhone 12",
1085
+ realMobile: true
1086
+ },
1087
+ {
1088
+ os: "ios",
1089
+ os_version: "14",
1090
+ device: "iPhone 11 Pro Max",
1091
+ realMobile: true
1092
+ },
1093
+ {
1094
+ os: "ios",
1095
+ os_version: "14",
1096
+ device: "iPhone 11",
1097
+ realMobile: true
1098
+ },
1099
+ {
1100
+ os: "ios",
1101
+ os_version: "13",
1102
+ device: "iPhone XS",
1103
+ realMobile: true
1104
+ },
1105
+ {
1106
+ os: "ios",
1107
+ os_version: "13",
1108
+ device: "iPhone 11 Pro Max",
1109
+ realMobile: true
1110
+ },
1111
+ {
1112
+ os: "ios",
1113
+ os_version: "13",
1114
+ device: "iPhone 11 Pro",
1115
+ realMobile: true
1116
+ },
1117
+ {
1118
+ os: "ios",
1119
+ os_version: "13",
1120
+ device: "iPhone 11",
1121
+ realMobile: true
1122
+ },
1123
+ {
1124
+ os: "ios",
1125
+ os_version: "12",
1126
+ device: "iPhone XS",
1127
+ realMobile: true
1128
+ },
1129
+ {
1130
+ os: "ios",
1131
+ os_version: "12",
1132
+ device: "iPhone XS Max",
1133
+ realMobile: true
1134
+ },
1135
+ {
1136
+ os: "ios",
1137
+ os_version: "15",
1138
+ device: "iPhone XR",
1139
+ realMobile: true
1140
+ },
1141
+ {
1142
+ os: "ios",
1143
+ os_version: "12",
1144
+ device: "iPhone XR",
1145
+ realMobile: true
1146
+ },
1147
+ {
1148
+ os: "ios",
1149
+ os_version: "11",
1150
+ device: "iPhone X",
1151
+ realMobile: true
1152
+ },
1153
+ {
1154
+ os: "ios",
1155
+ os_version: "15",
1156
+ device: "iPhone 8",
1157
+ realMobile: true
1158
+ },
1159
+ {
1160
+ os: "ios",
1161
+ os_version: "13",
1162
+ device: "iPhone 8",
1163
+ realMobile: true
1164
+ },
1165
+ {
1166
+ os: "ios",
1167
+ os_version: "12",
1168
+ device: "iPhone 8",
1169
+ realMobile: true
1170
+ },
1171
+ {
1172
+ os: "ios",
1173
+ os_version: "11",
1174
+ device: "iPhone 8",
1175
+ realMobile: true
1176
+ },
1177
+ {
1178
+ os: "ios",
1179
+ os_version: "12",
1180
+ device: "iPhone 8 Plus",
1181
+ realMobile: true
1182
+ },
1183
+ {
1184
+ os: "ios",
1185
+ os_version: "11",
1186
+ device: "iPhone 8 Plus",
1187
+ realMobile: true
1188
+ },
1189
+ {
1190
+ os: "ios",
1191
+ os_version: "12",
1192
+ device: "iPhone 7",
1193
+ realMobile: true
1194
+ },
1195
+ {
1196
+ os: "ios",
1197
+ os_version: "10",
1198
+ device: "iPhone 7",
1199
+ realMobile: true
1200
+ },
1201
+ {
1202
+ os: "ios",
1203
+ os_version: "12",
1204
+ device: "iPhone 6S",
1205
+ realMobile: true
1206
+ },
1207
+ {
1208
+ os: "ios",
1209
+ os_version: "11",
1210
+ device: "iPhone 6S",
1211
+ realMobile: true
1212
+ },
1213
+ {
1214
+ os: "ios",
1215
+ os_version: "11",
1216
+ device: "iPhone 6S Plus",
1217
+ realMobile: true
1218
+ },
1219
+ {
1220
+ os: "ios",
1221
+ os_version: "11",
1222
+ device: "iPhone 6",
1223
+ realMobile: true
1224
+ },
1225
+ {
1226
+ os: "ios",
1227
+ os_version: "15",
1228
+ device: "iPhone SE 2022",
1229
+ realMobile: true
1230
+ },
1231
+ {
1232
+ os: "ios",
1233
+ os_version: "13",
1234
+ device: "iPhone SE 2020",
1235
+ realMobile: true
1236
+ },
1237
+ {
1238
+ os: "ios",
1239
+ os_version: "11",
1240
+ device: "iPhone SE",
1241
+ realMobile: true
1242
+ },
1243
+ {
1244
+ os: "ios",
1245
+ os_version: "14",
1246
+ device: "iPad Air 4",
1247
+ realMobile: true
1248
+ },
1249
+ {
1250
+ os: "ios",
1251
+ os_version: "15",
1252
+ device: "iPad 9th",
1253
+ realMobile: true
1254
+ },
1255
+ {
1256
+ os: "ios",
1257
+ os_version: "16",
1258
+ device: "iPad Pro 12.9 2022",
1259
+ realMobile: true
1260
+ },
1261
+ {
1262
+ os: "ios",
1263
+ os_version: "16",
1264
+ device: "iPad Pro 12.9 2020",
1265
+ realMobile: true
1266
+ },
1267
+ {
1268
+ os: "ios",
1269
+ os_version: "16",
1270
+ device: "iPad Pro 11 2022",
1271
+ realMobile: true
1272
+ },
1273
+ {
1274
+ os: "ios",
1275
+ os_version: "16",
1276
+ device: "iPad 10th",
1277
+ realMobile: true
1278
+ },
1279
+ {
1280
+ os: "ios",
1281
+ os_version: "15",
1282
+ device: "iPad Air 5",
1283
+ realMobile: true
1284
+ },
1285
+ {
1286
+ os: "ios",
1287
+ os_version: "14",
1288
+ device: "iPad Pro 12.9 2021",
1289
+ realMobile: true
1290
+ },
1291
+ {
1292
+ os: "ios",
1293
+ os_version: "14",
1294
+ device: "iPad Pro 12.9 2020",
1295
+ realMobile: true
1296
+ },
1297
+ {
1298
+ os: "ios",
1299
+ os_version: "14",
1300
+ device: "iPad Pro 11 2021",
1301
+ realMobile: true
1302
+ },
1303
+ {
1304
+ os: "ios",
1305
+ os_version: "13",
1306
+ device: "iPad Pro 12.9 2020",
1307
+ realMobile: true
1308
+ },
1309
+ {
1310
+ os: "ios",
1311
+ os_version: "16",
1312
+ device: "iPad 8th",
1313
+ realMobile: true
1314
+ },
1315
+ {
1316
+ os: "ios",
1317
+ os_version: "15",
1318
+ device: "iPad Pro 12.9 2018",
1319
+ realMobile: true
1320
+ },
1321
+ {
1322
+ os: "ios",
1323
+ os_version: "15",
1324
+ device: "iPad Mini 2021",
1325
+ realMobile: true
1326
+ },
1327
+ {
1328
+ os: "ios",
1329
+ os_version: "14",
1330
+ device: "iPad 8th",
1331
+ realMobile: true
1332
+ },
1333
+ {
1334
+ os: "ios",
1335
+ os_version: "13",
1336
+ device: "iPad Pro 12.9 2018",
1337
+ realMobile: true
1338
+ },
1339
+ {
1340
+ os: "ios",
1341
+ os_version: "13",
1342
+ device: "iPad Pro 11 2020",
1343
+ realMobile: true
1344
+ },
1345
+ {
1346
+ os: "ios",
1347
+ os_version: "13",
1348
+ device: "iPad Mini 2019",
1349
+ realMobile: true
1350
+ },
1351
+ {
1352
+ os: "ios",
1353
+ os_version: "13",
1354
+ device: "iPad Air 2019",
1355
+ realMobile: true
1356
+ },
1357
+ {
1358
+ os: "ios",
1359
+ os_version: "13",
1360
+ device: "iPad 7th",
1361
+ realMobile: true
1362
+ },
1363
+ {
1364
+ os: "ios",
1365
+ os_version: "12",
1366
+ device: "iPad Pro 12.9 2018",
1367
+ realMobile: true
1368
+ },
1369
+ {
1370
+ os: "ios",
1371
+ os_version: "12",
1372
+ device: "iPad Pro 11 2018",
1373
+ realMobile: true
1374
+ },
1375
+ {
1376
+ os: "ios",
1377
+ os_version: "12",
1378
+ device: "iPad Mini 2019",
1379
+ realMobile: true
1380
+ },
1381
+ {
1382
+ os: "ios",
1383
+ os_version: "12",
1384
+ device: "iPad Air 2019",
1385
+ realMobile: true
1386
+ },
1387
+ {
1388
+ os: "ios",
1389
+ os_version: "11",
1390
+ device: "iPad Pro 9.7 2016",
1391
+ realMobile: true
1392
+ },
1393
+ {
1394
+ os: "ios",
1395
+ os_version: "11",
1396
+ device: "iPad Pro 12.9 2017",
1397
+ realMobile: true
1398
+ },
1399
+ {
1400
+ os: "ios",
1401
+ os_version: "11",
1402
+ device: "iPad Mini 4",
1403
+ realMobile: true
1404
+ },
1405
+ {
1406
+ os: "ios",
1407
+ os_version: "11",
1408
+ device: "iPad 6th",
1409
+ realMobile: true
1410
+ },
1411
+ {
1412
+ os: "ios",
1413
+ os_version: "11",
1414
+ device: "iPad 5th",
1415
+ realMobile: true
1416
+ },
1417
+ {
1418
+ os: "android",
1419
+ os_version: "12.0",
1420
+ device: "Samsung Galaxy S22 Ultra",
1421
+ realMobile: true
1422
+ },
1423
+ {
1424
+ os: "android",
1425
+ os_version: "12.0",
1426
+ device: "Samsung Galaxy S22 Plus",
1427
+ realMobile: true
1428
+ },
1429
+ {
1430
+ os: "android",
1431
+ os_version: "12.0",
1432
+ device: "Samsung Galaxy S22",
1433
+ realMobile: true
1434
+ },
1435
+ {
1436
+ os: "android",
1437
+ os_version: "12.0",
1438
+ device: "Samsung Galaxy S21",
1439
+ realMobile: true
1440
+ },
1441
+ {
1442
+ os: "android",
1443
+ os_version: "11.0",
1444
+ device: "Samsung Galaxy S21 Ultra",
1445
+ realMobile: true
1446
+ },
1447
+ {
1448
+ os: "android",
1449
+ os_version: "11.0",
1450
+ device: "Samsung Galaxy S21",
1451
+ realMobile: true
1452
+ },
1453
+ {
1454
+ os: "android",
1455
+ os_version: "11.0",
1456
+ device: "Samsung Galaxy S21 Plus",
1457
+ realMobile: true
1458
+ },
1459
+ {
1460
+ os: "android",
1461
+ os_version: "10.0",
1462
+ device: "Samsung Galaxy S20",
1463
+ realMobile: true
1464
+ },
1465
+ {
1466
+ os: "android",
1467
+ os_version: "10.0",
1468
+ device: "Samsung Galaxy S20 Plus",
1469
+ realMobile: true
1470
+ },
1471
+ {
1472
+ os: "android",
1473
+ os_version: "10.0",
1474
+ device: "Samsung Galaxy S20 Ultra",
1475
+ realMobile: true
1476
+ },
1477
+ {
1478
+ os: "android",
1479
+ os_version: "11.0",
1480
+ device: "Samsung Galaxy M52",
1481
+ realMobile: true
1482
+ },
1483
+ {
1484
+ os: "android",
1485
+ os_version: "11.0",
1486
+ device: "Samsung Galaxy M32",
1487
+ realMobile: true
1488
+ },
1489
+ {
1490
+ os: "android",
1491
+ os_version: "11.0",
1492
+ device: "Samsung Galaxy A52",
1493
+ realMobile: true
1494
+ },
1495
+ {
1496
+ os: "android",
1497
+ os_version: "10.0",
1498
+ device: "Samsung Galaxy Note 20 Ultra",
1499
+ realMobile: true
1500
+ },
1501
+ {
1502
+ os: "android",
1503
+ os_version: "10.0",
1504
+ device: "Samsung Galaxy Note 20",
1505
+ realMobile: true
1506
+ },
1507
+ {
1508
+ os: "android",
1509
+ os_version: "10.0",
1510
+ device: "Samsung Galaxy A51",
1511
+ realMobile: true
1512
+ },
1513
+ {
1514
+ os: "android",
1515
+ os_version: "10.0",
1516
+ device: "Samsung Galaxy A11",
1517
+ realMobile: true
1518
+ },
1519
+ {
1520
+ os: "android",
1521
+ os_version: "9.0",
1522
+ device: "Samsung Galaxy S9 Plus",
1523
+ realMobile: true
1524
+ },
1525
+ {
1526
+ os: "android",
1527
+ os_version: "9.0",
1528
+ device: "Samsung Galaxy S10e",
1529
+ realMobile: true
1530
+ },
1531
+ {
1532
+ os: "android",
1533
+ os_version: "9.0",
1534
+ device: "Samsung Galaxy S10 Plus",
1535
+ realMobile: true
1536
+ },
1537
+ {
1538
+ os: "android",
1539
+ os_version: "9.0",
1540
+ device: "Samsung Galaxy S10",
1541
+ realMobile: true
1542
+ },
1543
+ {
1544
+ os: "android",
1545
+ os_version: "9.0",
1546
+ device: "Samsung Galaxy Note 10 Plus",
1547
+ realMobile: true
1548
+ },
1549
+ {
1550
+ os: "android",
1551
+ os_version: "9.0",
1552
+ device: "Samsung Galaxy Note 10",
1553
+ realMobile: true
1554
+ },
1555
+ {
1556
+ os: "android",
1557
+ os_version: "9.0",
1558
+ device: "Samsung Galaxy A10",
1559
+ realMobile: true
1560
+ },
1561
+ {
1562
+ os: "android",
1563
+ os_version: "8.1",
1564
+ device: "Samsung Galaxy Note 9",
1565
+ realMobile: true
1566
+ },
1567
+ {
1568
+ os: "android",
1569
+ os_version: "8.1",
1570
+ device: "Samsung Galaxy J7 Prime",
1571
+ realMobile: true
1572
+ },
1573
+ {
1574
+ os: "android",
1575
+ os_version: "8.0",
1576
+ device: "Samsung Galaxy S9 Plus",
1577
+ realMobile: true
1578
+ },
1579
+ {
1580
+ os: "android",
1581
+ os_version: "8.0",
1582
+ device: "Samsung Galaxy S9",
1583
+ realMobile: true
1584
+ },
1585
+ {
1586
+ os: "android",
1587
+ os_version: "7.1",
1588
+ device: "Samsung Galaxy Note 8",
1589
+ realMobile: true
1590
+ },
1591
+ {
1592
+ os: "android",
1593
+ os_version: "7.1",
1594
+ device: "Samsung Galaxy A8",
1595
+ realMobile: true
1596
+ },
1597
+ {
1598
+ os: "android",
1599
+ os_version: "7.0",
1600
+ device: "Samsung Galaxy S8 Plus",
1601
+ realMobile: true
1602
+ },
1603
+ {
1604
+ os: "android",
1605
+ os_version: "7.0",
1606
+ device: "Samsung Galaxy S8",
1607
+ realMobile: true
1608
+ },
1609
+ {
1610
+ os: "android",
1611
+ os_version: "6.0",
1612
+ device: "Samsung Galaxy S7",
1613
+ realMobile: true
1614
+ },
1615
+ {
1616
+ os: "android",
1617
+ os_version: "5.0",
1618
+ device: "Samsung Galaxy S6",
1619
+ realMobile: true
1620
+ },
1621
+ {
1622
+ os: "android",
1623
+ os_version: "13.0",
1624
+ device: "Google Pixel 7 Pro",
1625
+ realMobile: true
1626
+ },
1627
+ {
1628
+ os: "android",
1629
+ os_version: "13.0",
1630
+ device: "Google Pixel 7",
1631
+ realMobile: true
1632
+ },
1633
+ {
1634
+ os: "android",
1635
+ os_version: "13.0",
1636
+ device: "Google Pixel 6 Pro",
1637
+ realMobile: true
1638
+ },
1639
+ {
1640
+ os: "android",
1641
+ os_version: "12.0",
1642
+ device: "Google Pixel 6 Pro",
1643
+ realMobile: true
1644
+ },
1645
+ {
1646
+ os: "android",
1647
+ os_version: "12.0",
1648
+ device: "Google Pixel 6",
1649
+ realMobile: true
1650
+ },
1651
+ {
1652
+ os: "android",
1653
+ os_version: "12.0",
1654
+ device: "Google Pixel 5",
1655
+ realMobile: true
1656
+ },
1657
+ {
1658
+ os: "android",
1659
+ os_version: "11.0",
1660
+ device: "Google Pixel 5",
1661
+ realMobile: true
1662
+ },
1663
+ {
1664
+ os: "android",
1665
+ os_version: "11.0",
1666
+ device: "Google Pixel 4",
1667
+ realMobile: true
1668
+ },
1669
+ {
1670
+ os: "android",
1671
+ os_version: "10.0",
1672
+ device: "Google Pixel 4 XL",
1673
+ realMobile: true
1674
+ },
1675
+ {
1676
+ os: "android",
1677
+ os_version: "10.0",
1678
+ device: "Google Pixel 4",
1679
+ realMobile: true
1680
+ },
1681
+ {
1682
+ os: "android",
1683
+ os_version: "10.0",
1684
+ device: "Google Pixel 3",
1685
+ realMobile: true
1686
+ },
1687
+ {
1688
+ os: "android",
1689
+ os_version: "9.0",
1690
+ device: "Google Pixel 3a XL",
1691
+ realMobile: true
1692
+ },
1693
+ {
1694
+ os: "android",
1695
+ os_version: "9.0",
1696
+ device: "Google Pixel 3a",
1697
+ realMobile: true
1698
+ },
1699
+ {
1700
+ os: "android",
1701
+ os_version: "9.0",
1702
+ device: "Google Pixel 3 XL",
1703
+ realMobile: true
1704
+ },
1705
+ {
1706
+ os: "android",
1707
+ os_version: "9.0",
1708
+ device: "Google Pixel 3",
1709
+ realMobile: true
1710
+ },
1711
+ {
1712
+ os: "android",
1713
+ os_version: "9.0",
1714
+ device: "Google Pixel 2",
1715
+ realMobile: true
1716
+ },
1717
+ {
1718
+ os: "android",
1719
+ os_version: "8.0",
1720
+ device: "Google Pixel 2",
1721
+ realMobile: true
1722
+ },
1723
+ {
1724
+ os: "android",
1725
+ os_version: "7.1",
1726
+ device: "Google Pixel",
1727
+ realMobile: true
1728
+ },
1729
+ {
1730
+ os: "android",
1731
+ os_version: "6.0",
1732
+ device: "Google Nexus 6",
1733
+ realMobile: true
1734
+ },
1735
+ {
1736
+ os: "android",
1737
+ os_version: "4.4",
1738
+ device: "Google Nexus 5",
1739
+ realMobile: true
1740
+ },
1741
+ {
1742
+ os: "android",
1743
+ os_version: "11.0",
1744
+ device: "OnePlus 9",
1745
+ realMobile: true
1746
+ },
1747
+ {
1748
+ os: "android",
1749
+ os_version: "10.0",
1750
+ device: "OnePlus 8",
1751
+ realMobile: true
1752
+ },
1753
+ {
1754
+ os: "android",
1755
+ os_version: "10.0",
1756
+ device: "OnePlus 7T",
1757
+ realMobile: true
1758
+ },
1759
+ {
1760
+ os: "android",
1761
+ os_version: "9.0",
1762
+ device: "OnePlus 7",
1763
+ realMobile: true
1764
+ },
1765
+ {
1766
+ os: "android",
1767
+ os_version: "9.0",
1768
+ device: "OnePlus 6T",
1769
+ realMobile: true
1770
+ },
1771
+ {
1772
+ os: "android",
1773
+ os_version: "11.0",
1774
+ device: "Xiaomi Redmi Note 11",
1775
+ realMobile: true
1776
+ },
1777
+ {
1778
+ os: "android",
1779
+ os_version: "10.0",
1780
+ device: "Xiaomi Redmi Note 9",
1781
+ realMobile: true
1782
+ },
1783
+ {
1784
+ os: "android",
1785
+ os_version: "9.0",
1786
+ device: "Xiaomi Redmi Note 8",
1787
+ realMobile: true
1788
+ },
1789
+ {
1790
+ os: "android",
1791
+ os_version: "9.0",
1792
+ device: "Xiaomi Redmi Note 7",
1793
+ realMobile: true
1794
+ },
1795
+ {
1796
+ os: "android",
1797
+ os_version: "11.0",
1798
+ device: "Vivo Y21",
1799
+ realMobile: true
1800
+ },
1801
+ {
1802
+ os: "android",
1803
+ os_version: "11.0",
1804
+ device: "Vivo V21",
1805
+ realMobile: true
1806
+ },
1807
+ {
1808
+ os: "android",
1809
+ os_version: "10.0",
1810
+ device: "Vivo Y50",
1811
+ realMobile: true
1812
+ },
1813
+ {
1814
+ os: "android",
1815
+ os_version: "11.0",
1816
+ device: "Oppo Reno 6",
1817
+ realMobile: true
1818
+ },
1819
+ {
1820
+ os: "android",
1821
+ os_version: "11.0",
1822
+ device: "Oppo A96",
1823
+ realMobile: true
1824
+ },
1825
+ {
1826
+ os: "android",
1827
+ os_version: "10.0",
1828
+ device: "Oppo Reno 3 Pro",
1829
+ realMobile: true
1830
+ },
1831
+ {
1832
+ os: "android",
1833
+ os_version: "11.0",
1834
+ device: "Motorola Moto G71 5G",
1835
+ realMobile: true
1836
+ },
1837
+ {
1838
+ os: "android",
1839
+ os_version: "10.0",
1840
+ device: "Motorola Moto G9 Play",
1841
+ realMobile: true
1842
+ },
1843
+ {
1844
+ os: "android",
1845
+ os_version: "9.0",
1846
+ device: "Motorola Moto G7 Play",
1847
+ realMobile: true
1848
+ },
1849
+ {
1850
+ os: "android",
1851
+ os_version: "9.0",
1852
+ device: "Huawei P30",
1853
+ realMobile: true
1854
+ },
1855
+ {
1856
+ os: "android",
1857
+ os_version: "12.0",
1858
+ device: "Samsung Galaxy Tab S8",
1859
+ realMobile: true
1860
+ },
1861
+ {
1862
+ os: "android",
1863
+ os_version: "11.0",
1864
+ device: "Samsung Galaxy Tab S7",
1865
+ realMobile: true
1866
+ },
1867
+ {
1868
+ os: "android",
1869
+ os_version: "10.0",
1870
+ device: "Samsung Galaxy Tab S7",
1871
+ realMobile: true
1872
+ },
1873
+ {
1874
+ os: "android",
1875
+ os_version: "9.0",
1876
+ device: "Samsung Galaxy Tab S6",
1877
+ realMobile: true
1878
+ },
1879
+ {
1880
+ os: "android",
1881
+ os_version: "9.0",
1882
+ device: "Samsung Galaxy Tab S5e",
1883
+ realMobile: true
1884
+ },
1885
+ {
1886
+ os: "android",
1887
+ os_version: "8.1",
1888
+ device: "Samsung Galaxy Tab S4",
1889
+ realMobile: true
1890
+ }
1891
+ ];
1892
+
1893
+ // src/server/config.ts
1894
+ var customDevicesPath = "./server/data/custom_devices.json";
1895
+ var logsFolder = "./logs";
1896
+ import_dotenv2.default.config();
1897
+ var config = {
1898
+ version,
1899
+ // this isn't used
1900
+ getDevices: async () => {
1901
+ if (import_fs.default.existsSync(customDevicesPath)) {
1902
+ return [...devices_default, ...(await import(customDevicesPath)).default];
1903
+ }
1904
+ return devices_default;
1905
+ },
1906
+ defaultImagesPath: env.SYNGRISI_IMAGES_PATH,
1907
+ connectionString: env.SYNGRISI_DB_URI || "mongodb://127.0.0.1:27017/SyngrisiDb",
1908
+ host: env.SYNGRISI_HOSTNAME,
1909
+ port: env.SYNGRISI_APP_PORT || 3e3,
1910
+ backupsFolder: "./backups",
1911
+ enableHttpLogger: env.SYNGRISI_HTTP_LOG,
1912
+ httpLoggerFilePath: `${logsFolder}/http.log`,
1913
+ storeSessionKey: env.SYNGRISI_SESSION_STORE_KEY || import_crypto2.default.randomBytes(64).toString("hex"),
1914
+ codeCoverage: env.SYNGRISI_COVERAGE,
1915
+ disableCors: env.SYNGRISI_DISABLE_DEV_CORS,
1916
+ fileUploadMaxSize: 50 * 1024 * 1024,
1917
+ testMode: env.SYNGRISI_TEST_MODE,
1918
+ jsonLimit: "50mb",
1919
+ tmpDir: env.SYNGRISI_TMP_DIR,
1920
+ helmet: {
1921
+ crossOriginEmbedderPolicy: !env.SYNGRISI_DISABLE_DEV_CORS,
1922
+ crossOriginResourcePolicy: !env.SYNGRISI_DISABLE_DEV_CORS,
1923
+ contentSecurityPolicy: {
1924
+ directives: {
1925
+ frameAncestors: ["'self'", "vscode-webview:", "vscode-resource:", "https:", "http:"],
1926
+ frameSrc: ["'self'", "vscode-webview:", "https:", "http:"],
1927
+ scriptSrc: ["'self'", "'unsafe-inline'"],
1928
+ styleSrc: ["'self'", "'unsafe-inline'"]
1929
+ }
1930
+ }
1931
+ }
1932
+ };
1933
+ if (!import_fs.default.existsSync(config.defaultImagesPath)) {
1934
+ import_fs.default.mkdirSync(config.defaultImagesPath, { recursive: true });
1935
+ }
1936
+ if (!import_fs.default.existsSync(logsFolder)) {
1937
+ import_fs.default.mkdirSync(logsFolder, { recursive: true });
1938
+ }
1939
+
1940
+ // src/server/lib/logger.ts
1941
+ var import_path2 = __toESM(require("path"));
1942
+ var logLevel = env.SYNGRISI_LOG_LEVEL;
1943
+ function getScriptLine() {
1944
+ const stack = new Error().stack;
1945
+ if (stack) {
1946
+ const stackLines = stack.split("\n");
1947
+ let loggerLineIndex = -1;
1948
+ for (let i = 0; i < stackLines.length; i++) {
1949
+ if (stackLines[i].includes("lib/logger")) {
1950
+ loggerLineIndex = i;
1951
+ }
1952
+ }
1953
+ const targetLineIndex = loggerLineIndex + 1;
1954
+ if (targetLineIndex >= 0 && targetLineIndex < stackLines.length) {
1955
+ const targetLine = stackLines[targetLineIndex];
1956
+ const match = targetLine.match(/at\s+(?:.+\s+\()?(.+):(\d+):(\d+)\)?/);
1957
+ if (match) {
1958
+ const scriptPath = match[1];
1959
+ const relativePath = import_path2.default.relative(process.cwd(), scriptPath);
1960
+ const lineNumber = match[2];
1961
+ return `${relativePath}:${lineNumber}`;
1962
+ }
1963
+ }
1964
+ }
1965
+ return "unknown";
1966
+ }
1967
+ function createWinstonLogger(opts) {
1968
+ return import_winston.default.createLogger({
1969
+ transports: [
1970
+ new import_winston.default.transports.Console({
1971
+ level: logLevel || "silly",
1972
+ format: import_winston.default.format.combine(
1973
+ import_winston.default.format.colorize(),
1974
+ import_winston.default.format.timestamp(),
1975
+ import_winston.default.format.ms(),
1976
+ import_winston.default.format.metadata(),
1977
+ import_winston.default.format.printf((info2) => {
1978
+ const user = info2.metadata.user ? (0, import_chalk.blue)(` <${info2.metadata.user}>`) : "";
1979
+ const ref = info2.metadata.ref ? (0, import_chalk.gray)(` ${info2.metadata.ref}`) : "";
1980
+ const msgType = info2.metadata.msgType ? ` ${info2.metadata.msgType}` : "";
1981
+ const itemType = info2.metadata.itemType ? (0, import_chalk.magenta)(` ${info2.metadata.itemType}`) : "";
1982
+ const scope = info2.metadata.scope ? (0, import_chalk.magenta)(` [${info2.metadata.scope}] `) : (0, import_chalk.magenta)(` [${getScriptLine()}] `);
1983
+ const msg = typeof info2.message === "object" ? `
1984
+ ${JSON.stringify(info2.message, null, 2)}` : info2.message;
1985
+ return `${info2.level} ${scope}${formatISOToDateTime_default(info2.metadata.timestamp)} ${info2.metadata.ms}${user}${ref}${msgType}${itemType} '${msg}'`;
1986
+ }),
1987
+ import_winston.default.format.padLevels()
1988
+ )
1989
+ }),
1990
+ new import_winston.default.transports.MongoDB({
1991
+ level: logLevel || "debug",
1992
+ format: import_winston.default.format.combine(
1993
+ import_winston.default.format.timestamp(),
1994
+ import_winston.default.format.json(),
1995
+ import_winston.default.format.metadata()
1996
+ ),
1997
+ options: {
1998
+ useUnifiedTopology: true
1999
+ },
2000
+ db: opts.dbConnectionString,
2001
+ collection: "vrslogs"
2002
+ })
2003
+ ]
2004
+ });
2005
+ }
2006
+ var Logger = class _Logger {
2007
+ constructor(opts = { dbConnectionString: config.connectionString }) {
2008
+ this.winstonLogger = createWinstonLogger(opts);
2009
+ }
2010
+ static mergeMeta(objects) {
2011
+ return objects.reduce((acc, obj) => {
2012
+ return { ...acc, ...obj };
2013
+ }, {});
2014
+ }
2015
+ log(severity, msg, meta) {
2016
+ const mergedMeta = _Logger.mergeMeta(meta);
2017
+ if (!mergedMeta.scope) {
2018
+ mergedMeta.scope = getScriptLine();
2019
+ }
2020
+ const formattedMsg = typeof msg === "object" ? JSON.stringify(msg, null, 2) : msg;
2021
+ this.winstonLogger.log(severity, formattedMsg, mergedMeta);
2022
+ }
2023
+ error(msg, ...meta) {
2024
+ let message = String(msg);
2025
+ let code = 0;
2026
+ if (msg instanceof Object) {
2027
+ message = JSON.stringify(msg);
2028
+ }
2029
+ if (msg instanceof Error) {
2030
+ message = msg.stack;
2031
+ }
2032
+ if (msg instanceof ApiError_default) {
2033
+ code = msg.statusCode;
2034
+ }
2035
+ this.log("error", `${code !== 0 ? "[" + code + "]" : ""}${message}
2036
+ stacktrace: ${new Error().stack}`, meta);
2037
+ }
2038
+ warn(msg, ...meta) {
2039
+ this.log("warn", `${msg}
2040
+ stacktrace: ${new Error().stack}`, meta);
2041
+ }
2042
+ info(msg, ...meta) {
2043
+ this.log("info", msg, meta);
2044
+ }
2045
+ verbose(msg, ...meta) {
2046
+ this.log("verbose", msg, meta);
2047
+ }
2048
+ debug(msg, ...meta) {
2049
+ this.log("debug", msg, meta);
2050
+ }
2051
+ silly(msg, ...meta) {
2052
+ this.log("silly", msg, meta);
2053
+ }
2054
+ };
2055
+ var logger_default = new Logger();
2056
+
2057
+ // src/server/services/test.service.ts
2058
+ var test_service_exports = {};
2059
+ __export(test_service_exports, {
2060
+ accept: () => accept,
2061
+ queryTests: () => queryTests,
2062
+ queryTestsDistinct: () => queryTestsDistinct,
2063
+ remove: () => remove
2064
+ });
2065
+ var queryTests = async (filter, options) => {
2066
+ const tests = await Test_model_default.paginate(filter, options);
2067
+ return tests;
2068
+ };
2069
+ var queryTestsDistinct = async (filter, options) => {
2070
+ const tests = await Test_model_default.paginateDistinct({ filter: filter ? JSON.stringify(filter) : null }, options);
2071
+ return tests;
2072
+ };
2073
+ var remove = async (id2, user) => {
2074
+ const logOpts4 = {
2075
+ scope: "removeTest",
2076
+ itemType: "test",
2077
+ ref: id2,
2078
+ user: user?.username,
2079
+ msgType: "REMOVE"
2080
+ };
2081
+ logger_default.info(`remove test with, id: '${id2}', user: '${user.username}'`, logOpts4);
2082
+ try {
2083
+ logger_default.debug(`try to delete all checks associated to test with ID: '${id2}'`, logOpts4);
2084
+ const checks = await Check_model_default.find({ test: id2 });
2085
+ for (const check of checks) {
2086
+ await check_service_exports.remove(check._id, user);
2087
+ }
2088
+ return Test_model_default.findByIdAndDelete(id2);
2089
+ } catch (e) {
2090
+ logger_default.error(`cannot remove test with id: ${id2} error: ${e instanceof Error ? e.stack : String(e)}`, logOpts4);
2091
+ throw new Error();
2092
+ }
2093
+ };
2094
+ var accept = async (id2, user) => {
2095
+ const logOpts4 = {
2096
+ scope: "acceptTest",
2097
+ itemType: "test",
2098
+ ref: id2,
2099
+ user: user?.username,
2100
+ msgType: "ACCEPT"
2101
+ };
2102
+ logger_default.info(`accept test with, id: '${id2}', user: '${user.username}'`, logOpts4);
2103
+ const checks = await Check_model_default.find({ test: id2 }).exec();
2104
+ for (const check of checks) {
2105
+ await check_service_exports.accept(check._id, String(check.actualSnapshotId), user);
2106
+ }
2107
+ return { message: "success" };
2108
+ };
2109
+
2110
+ // src/server/services/run.service.ts
2111
+ var import_http_status = __toESM(require("http-status"));
2112
+ var remove2 = async (id2, user) => {
2113
+ const logOpts4 = {
2114
+ scope: "removeRun",
2115
+ itemType: "run",
2116
+ ref: id2,
2117
+ user: user?.username,
2118
+ msgType: "REMOVE"
2119
+ };
2120
+ logger_default.info(`remove run with, id: '${id2}', user: '${user.username}'`, logOpts4);
2121
+ const tests = await Test_model_default.find({ run: id2 }).exec();
2122
+ for (const test of tests) {
2123
+ await remove(test._id, user);
2124
+ }
2125
+ const run = await Run_model_default.findByIdAndDelete(id2).exec();
2126
+ if (!run) {
2127
+ throw new ApiError_default(import_http_status.default.NOT_FOUND, `cannot remove run with id: '${id2}', not found`);
2128
+ }
2129
+ return run;
2130
+ };
2131
+
2132
+ // src/server/services/suite.service.ts
2133
+ var suite_service_exports = {};
2134
+ __export(suite_service_exports, {
2135
+ remove: () => remove3
2136
+ });
2137
+ var import_http_status2 = __toESM(require("http-status"));
2138
+ var remove3 = async (id2, user) => {
2139
+ const logOpts4 = {
2140
+ scope: "removeSuite",
2141
+ itemType: "suite",
2142
+ ref: id2,
2143
+ user: user?.username,
2144
+ msgType: "REMOVE"
2145
+ };
2146
+ logger_default.info(`remove suite with, id: '${id2}', user: '${user.username}'`, logOpts4);
2147
+ const tests = await Test_model_default.find({ suite: id2 }).exec();
2148
+ for (const test of tests) {
2149
+ await remove(test._id, user);
2150
+ }
2151
+ const suite = await Suite_model_default.findByIdAndDelete(id2).exec();
2152
+ if (!suite) throw new ApiError_default(import_http_status2.default.NOT_FOUND, `cannot remove suite with id: '${id2}', not found`);
2153
+ return suite;
2154
+ };
2155
+
2156
+ // src/server/services/logs.service.ts
2157
+ var logs_service_exports = {};
2158
+ __export(logs_service_exports, {
2159
+ createLogs: () => createLogs,
2160
+ distinct: () => distinct,
2161
+ queryLogs: () => queryLogs
2162
+ });
2163
+ var queryLogs = async (filter, options) => Log_model_default.paginate(filter, options);
2164
+ var distinct = async (field) => Log_model_default.distinct(field);
2165
+ var createLogs = async (body) => {
2166
+ logger_default[body.level || "debug"](body.message, {
2167
+ user: body.user,
2168
+ scope: body.scope || "test_scope",
2169
+ msgType: body.msgType || "TEST_MSG_TYPE"
2170
+ });
2171
+ return { message: "success" };
2172
+ };
2173
+
2174
+ // src/server/services/generic.service.ts
2175
+ var generic_service_exports = {};
2176
+ __export(generic_service_exports, {
2177
+ get: () => get,
2178
+ put: () => put
2179
+ });
2180
+ var import_mongoose11 = __toESM(require("mongoose"));
2181
+ var get = async (modelName, filter, options) => {
2182
+ const itemModel = import_mongoose11.default.model(modelName);
2183
+ return itemModel.paginate(filter, options);
2184
+ };
2185
+ var put = async (modelName, id2, options, user) => {
2186
+ const itemModel = import_mongoose11.default.model(modelName);
2187
+ const logOpts4 = {
2188
+ scope: "generic.service.put",
2189
+ ref: id2,
2190
+ itemType: modelName,
2191
+ msgType: "UPDATE",
2192
+ user: user?.username
2193
+ };
2194
+ const opts = removeEmptyProperties(options);
2195
+ logger_default.debug(`start update '${modelName}' with id: '${id2}', body: '${JSON.stringify(opts)}'`, logOpts4);
2196
+ const item = await itemModel.findByIdAndUpdate(id2, options).exec();
2197
+ if (!item) throw new Error(`cannot find the item: ${modelName}, id: ${id2}, options: ${JSON.stringify(options)}`);
2198
+ await item.save();
2199
+ logger_default.debug(`baseline with id: '${id2}' and opts: '${JSON.stringify(opts)}' was updated`, logOpts4);
2200
+ return item;
2201
+ };
2202
+
2203
+ // src/server/services/app.service.ts
2204
+ var app_service_exports = {};
2205
+ __export(app_service_exports, {
2206
+ get: () => get2
2207
+ });
2208
+ var get2 = async (filter, options) => App_model_default.paginate(filter, options);
2209
+
2210
+ // src/server/services/tasks.service.ts
2211
+ var tasks_service_exports = {};
2212
+ __export(tasks_service_exports, {
2213
+ loadTestUser: () => loadTestUser,
2214
+ screenshots: () => screenshots,
2215
+ status: () => status,
2216
+ task_handle_database_consistency: () => task_handle_database_consistency,
2217
+ task_handle_old_checks: () => task_handle_old_checks,
2218
+ task_remove_old_logs: () => task_remove_old_logs,
2219
+ task_test: () => task_test
2220
+ });
2221
+ var import_fs2 = __toESM(require("fs"));
2222
+ var import_string_table = __toESM(require("string-table"));
2223
+
2224
+ // src/seeds/testAdmin.json
2225
+ var testAdmin_default = {
2226
+ username: "Test",
2227
+ firstName: "Test",
2228
+ lastName: "Admin",
2229
+ role: "admin",
2230
+ openPassw: "123456aA-",
2231
+ password: "5b8d4960316d1fb0c92498c90da6c397cdf247cae71f01467a88e2b42d7af6f5ac7ca75d3bea6e3e0078111a2e5dfc1611f9a9a8908a5a3af5bcd64c42989608977de192829bdf8ada113a60f8f0704443c659789761865e29a3103dbf0773f5bf31e4685d475ece56afaceb949b6e7467eaa287a02e4142d095bcbf84acaefe47ee080799a28188890d39d3397e285d8b46c9a0efe9517428825b64ee1ebcc96d92c084733db866c767341381b6254aaa1ef36d1bf3d24e3f5b8d8b6b4080589b130e9c90914a3da74e5b6adf5f569bfd77460abae8ae4f87c2a375397a37f09861b9e114cead0cc34fff2d631fd4294260dea17e4fe098940dbee2cb80c62eb3701d40f5b204de776b8252d55e5f567c599b1fbcdae79278d1f375a4c8244a26a3b721dbeec56c8f39b3eb810942d392aae371ea81ded6b820dd4b489566a33c495f5c291ff238d07202d2ff04c52426828e44af98ec056a42d13f4b166ec170083e2fff9efe2b8cfdde529f3bce56b8427cf2d188861808ad07fd13e073b2a804e818b2882c13f559d52420b49f301263a9de34fe22b6df4a82ae70e7e4c29c88479878d2c21fbb810532532e7ad9a28f610b63033520e703f178e7b44d3e101ec0d4339c085ccc8bb290b3cb996c75c2b8deaacba8098b9ec02c7e47542891da3bd887c31cd8e0bdfa56bb844b1703368afe8dc42d668ff2e3374b939b4f",
2232
+ apiKey: "",
2233
+ salt: "c6211751bdc372f491a86bcbd8e4196dc393d14e14e5f17019d5c317afd5bc27"
2234
+ };
2235
+
2236
+ // src/server/services/tasks.service.ts
2237
+ var stringTable = import_string_table.default;
2238
+ function taskOutput(msg, res) {
2239
+ res.write(`${msg.toString()}
2240
+ `);
2241
+ logger_default.debug(msg.toString());
2242
+ }
2243
+ function parseHrtimeToSeconds(hrtime) {
2244
+ return (hrtime[0] + hrtime[1] / 1e9).toFixed(3);
2245
+ }
2246
+ var status = async (currentUser) => {
2247
+ const count = await User_model_default.countDocuments().exec();
2248
+ logger_default.silly(`server status: check users counts: ${count}`);
2249
+ if (count > 1) {
2250
+ return { alive: true, currentUser: currentUser?.username };
2251
+ }
2252
+ return { alive: false };
2253
+ };
2254
+ var screenshots = async () => {
2255
+ const files = import_fs2.default.readdirSync(config.defaultImagesPath);
2256
+ return files;
2257
+ };
2258
+ var loadTestUser = async () => {
2259
+ const logOpts4 = {
2260
+ itemType: "user",
2261
+ msgType: "LOAD",
2262
+ ref: "Administrator"
2263
+ };
2264
+ if (!env.SYNGRISI_TEST_MODE) {
2265
+ return { message: "the feature works only in test mode" };
2266
+ }
2267
+ const testAdmin = await User_model_default.findOne({ username: "Test" }).exec();
2268
+ if (!testAdmin) {
2269
+ logger_default.info("create the test Administrator", logOpts4);
2270
+ const admin = await User_model_default.create(testAdmin_default);
2271
+ logger_default.info(`test Administrator with id: '${admin._id}' was created`, logOpts4);
2272
+ return admin;
2273
+ }
2274
+ logger_default.info(`test admin is exists: ${JSON.stringify(testAdmin, null, 2)}`, logOpts4);
2275
+ return { msg: `already exist '${testAdmin}'` };
2276
+ };
2277
+ var task_handle_database_consistency = async (options, res) => {
2278
+ res.writeHead(200, {
2279
+ "Content-Type": "text/event-stream",
2280
+ "Cache-Control": "no-cache",
2281
+ "Content-Encoding": "none",
2282
+ "x-no-compression": "true"
2283
+ });
2284
+ try {
2285
+ const startTime = process.hrtime();
2286
+ taskOutput("- starting...\n", res);
2287
+ taskOutput("---------------------------------", res);
2288
+ taskOutput("STAGE #1: Calculate Common stats", res);
2289
+ taskOutput("get runs data", res);
2290
+ const allRunsBefore = await Run_model_default.find().exec();
2291
+ taskOutput("get suites data", res);
2292
+ const allSuitesBefore = await Suite_model_default.find().exec();
2293
+ taskOutput("get tests data", res);
2294
+ const allTestsBefore = await Test_model_default.find().lean().exec();
2295
+ taskOutput("get checks data", res);
2296
+ const allChecksBefore = await Check_model_default.find().lean().exec();
2297
+ taskOutput("get snapshots data", res);
2298
+ const allSnapshotsBefore = await Snapshot_model_default.find().lean().exec();
2299
+ taskOutput("get files data", res);
2300
+ const allFilesBefore = (await import_fs2.promises.readdir(config.defaultImagesPath, { withFileTypes: true })).filter((item) => !item.isDirectory()).map((x) => x.name).filter((x) => x.includes(".png"));
2301
+ taskOutput("-----------------------------", res);
2302
+ const beforeStatTable = stringTable.create([
2303
+ { item: "suites", count: allSuitesBefore.length },
2304
+ { item: "runs", count: allRunsBefore.length },
2305
+ { item: "tests", count: allTestsBefore.length },
2306
+ { item: "checks", count: allChecksBefore.length },
2307
+ { item: "snapshots", count: allSnapshotsBefore.length },
2308
+ { item: "files", count: allFilesBefore.length }
2309
+ ]);
2310
+ res.flush();
2311
+ taskOutput(beforeStatTable, res);
2312
+ taskOutput("---------------------------------", res);
2313
+ taskOutput("STAGE #2: Calculate Inconsistent Items", res);
2314
+ taskOutput("> calculate abandoned snapshots", res);
2315
+ const abandonedSnapshots = allSnapshotsBefore.filter((sn) => !import_fs2.default.existsSync(`${config.defaultImagesPath}/${sn.filename}`));
2316
+ taskOutput("> calculate abandoned files", res);
2317
+ const snapshotsUniqueFiles = Array.from(new Set(allSnapshotsBefore.map((x) => x.filename)));
2318
+ const abandonedFiles = [];
2319
+ const progress = new ProgressBar(allFilesBefore.length);
2320
+ for (const [index, file] of allFilesBefore.entries()) {
2321
+ setTimeout(() => {
2322
+ progress.writeIfChange(index, allFilesBefore.length, taskOutput, res);
2323
+ }, 10);
2324
+ if (!snapshotsUniqueFiles.includes(file.toString())) {
2325
+ abandonedFiles.push(file);
2326
+ }
2327
+ }
2328
+ taskOutput("> calculate abandoned checks", res);
2329
+ const allSnapshotsBeforeIds = allSnapshotsBefore.map((x) => x._id.valueOf());
2330
+ const allChecksBeforeLight = allChecksBefore.map((x) => ({
2331
+ _id: x._id.valueOf(),
2332
+ baselineId: x.baselineId.valueOf(),
2333
+ actualSnapshotId: x.actualSnapshotId.valueOf()
2334
+ }));
2335
+ const abandonedChecks = [];
2336
+ const progressChecks = new ProgressBar(allChecksBefore.length);
2337
+ for (const [index, check] of allChecksBeforeLight.entries()) {
2338
+ progressChecks.writeIfChange(index, allChecksBeforeLight.length, taskOutput, res);
2339
+ if (!allSnapshotsBeforeIds.includes(check.baselineId) || !allSnapshotsBeforeIds.includes(check.actualSnapshotId.valueOf())) {
2340
+ abandonedChecks.push(check._id.valueOf());
2341
+ }
2342
+ }
2343
+ taskOutput("> calculate empty tests", res);
2344
+ const checksUniqueTests = (await Check_model_default.find().lean().distinct("test").exec()).map((x) => x.valueOf());
2345
+ const emptyTests = [];
2346
+ for (const [index, test] of allTestsBefore.entries()) {
2347
+ if (!checksUniqueTests.includes(test._id.valueOf())) {
2348
+ emptyTests.push(test._id.valueOf());
2349
+ }
2350
+ }
2351
+ taskOutput("> calculate empty runs", res);
2352
+ const checksUniqueRuns = (await Check_model_default.find().distinct("run").exec()).map((x) => x.valueOf());
2353
+ const emptyRuns = [];
2354
+ for (const run of allRunsBefore) {
2355
+ if (!checksUniqueRuns.includes(run._id.valueOf())) {
2356
+ emptyRuns.push(run._id.valueOf());
2357
+ }
2358
+ }
2359
+ taskOutput("> calculate empty suites", res);
2360
+ const checksUniqueSuites = (await Check_model_default.find().distinct("suite").exec()).map((x) => x.valueOf());
2361
+ const emptySuites = [];
2362
+ for (const suite of allSuitesBefore) {
2363
+ if (!checksUniqueSuites.includes(suite._id.valueOf())) {
2364
+ emptySuites.push(suite._id.valueOf());
2365
+ }
2366
+ }
2367
+ taskOutput("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", res);
2368
+ taskOutput("Current inconsistent items:", res);
2369
+ const inconsistentStatTable = stringTable.create([
2370
+ { item: "empty suites", count: emptySuites.length },
2371
+ { item: "empty runs", count: emptyRuns.length },
2372
+ { item: "empty tests", count: emptyTests.length },
2373
+ { item: "abandoned checks", count: abandonedChecks.length },
2374
+ { item: "abandoned snapshots", count: abandonedSnapshots.length },
2375
+ { item: "abandoned files", count: abandonedFiles.length }
2376
+ ]);
2377
+ taskOutput(inconsistentStatTable, res);
2378
+ if (options.clean) {
2379
+ taskOutput("---------------------------------", res);
2380
+ taskOutput("STAGE #3: Remove non consistent items", res);
2381
+ taskOutput("> remove empty suites", res);
2382
+ await Suite_model_default.deleteMany({ _id: { $in: emptySuites } });
2383
+ taskOutput("> remove empty runs", res);
2384
+ await Run_model_default.deleteMany({ _id: { $in: emptyRuns } });
2385
+ taskOutput("> remove empty tests", res);
2386
+ await Test_model_default.deleteMany({ _id: { $in: emptyTests } });
2387
+ taskOutput("> remove abandoned checks", res);
2388
+ await Check_model_default.deleteMany({ _id: { $in: abandonedChecks } });
2389
+ taskOutput("> remove abandoned snapshots", res);
2390
+ await Snapshot_model_default.deleteMany({ _id: { $in: abandonedSnapshots } });
2391
+ taskOutput("> remove abandoned files", res);
2392
+ await Promise.all(abandonedFiles.map((filename) => import_fs2.promises.unlink(`${config.defaultImagesPath}/${filename}`)));
2393
+ const allFilesAfter = import_fs2.default.readdirSync(config.defaultImagesPath, { withFileTypes: true }).filter((item) => !item.isDirectory()).map((x) => x.name).filter((x) => x.includes(".png"));
2394
+ taskOutput("STAGE #4: Calculate Common stats after cleaning", res);
2395
+ taskOutput("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", res);
2396
+ taskOutput("Current items:", res);
2397
+ const afterStatTable = stringTable.create([
2398
+ { item: "suites", count: await Suite_model_default.countDocuments() },
2399
+ { item: "runs", count: await Run_model_default.countDocuments() },
2400
+ { item: "tests", count: await Test_model_default.countDocuments() },
2401
+ { item: "checks", count: await Check_model_default.countDocuments() },
2402
+ { item: "snapshots", count: await Snapshot_model_default.countDocuments() },
2403
+ { item: "files", count: allFilesAfter.length }
2404
+ ]);
2405
+ taskOutput(afterStatTable, res);
2406
+ }
2407
+ const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime));
2408
+ taskOutput(`> Done in ${elapsedSeconds} seconds, ${elapsedSeconds / 60} min`, res);
2409
+ taskOutput("- end...\n", res);
2410
+ } catch (e) {
2411
+ const errMsg2 = e instanceof Error ? e.message : String(e);
2412
+ logger_default.error(errMsg2);
2413
+ taskOutput(errMsg2, res);
2414
+ } finally {
2415
+ res.end();
2416
+ }
2417
+ };
2418
+ var task_remove_old_logs = async (options, res) => {
2419
+ res.writeHead(200, {
2420
+ "Content-Type": "text/event-stream",
2421
+ "Cache-Control": "no-cache",
2422
+ "Content-Encoding": "none"
2423
+ });
2424
+ const trashHoldDate = subDays_default(/* @__PURE__ */ new Date(), parseInt(options.days, 10));
2425
+ const filter = { timestamp: { $lt: trashHoldDate } };
2426
+ const allLogsCountBefore = await Log_model_default.find({}).countDocuments();
2427
+ const oldLogsCount = await Log_model_default.find(filter).countDocuments();
2428
+ taskOutput(`- the count of all documents is: '${allLogsCountBefore}'
2429
+ `, res);
2430
+ taskOutput(`- the count of documents to be removed is: '${oldLogsCount}'
2431
+ `, res);
2432
+ if (options.statistics === "false") {
2433
+ taskOutput(`- will remove all logs older that: '${options.days}' days, '${dateToISO8601_default(trashHoldDate)}'
2434
+ `, res);
2435
+ await Log_model_default.deleteMany(filter);
2436
+ const allLogsCountAfter = await Log_model_default.find({}).countDocuments();
2437
+ taskOutput(`- the count of all documents now is: '${allLogsCountAfter}'
2438
+ `, res);
2439
+ }
2440
+ taskOutput("> Done", res);
2441
+ res.end();
2442
+ };
2443
+ var task_handle_old_checks = async (options, res) => {
2444
+ res.writeHead(200, {
2445
+ "Content-Type": "text/event-stream",
2446
+ "Cache-Control": "no-cache",
2447
+ "Content-Encoding": "none"
2448
+ });
2449
+ try {
2450
+ const startTime = process.hrtime();
2451
+ taskOutput("- starting...\n", res);
2452
+ taskOutput("STAGE #1 Calculate common stats", res);
2453
+ const trashHoldDate = subDays_default(/* @__PURE__ */ new Date(), parseInt(options.days, 10));
2454
+ taskOutput("> get all checks data", res);
2455
+ const allChecksBefore = await Check_model_default.find().lean().exec();
2456
+ taskOutput("> get snapshots data", res);
2457
+ const allSnapshotsBefore = await Snapshot_model_default.find().lean().exec();
2458
+ taskOutput("> get files data", res);
2459
+ const allFilesBefore = (await import_fs2.promises.readdir(config.defaultImagesPath, { withFileTypes: true })).filter((item) => !item.isDirectory()).map((x) => x.name).filter((x) => x.includes(".png"));
2460
+ taskOutput("> get old checks data", res);
2461
+ const oldChecks = await Check_model_default.find({ createdDate: { $lt: trashHoldDate } }).lean().exec();
2462
+ taskOutput(">>> collect all baselineIds for old Checks ", res);
2463
+ const oldSnapshotsBaselineIdIds = oldChecks.map((x) => x.baselineId).filter((x) => x);
2464
+ taskOutput(">>> collect all actualSnapshotId for old Checks ", res);
2465
+ const oldSnapshotsActualSnapshotIdIds = oldChecks.map((x) => x.actualSnapshotId).filter((x) => x);
2466
+ taskOutput(">>> collect all diffId for old Checks ", res);
2467
+ const oldSnapshotsDiffIds = oldChecks.map((x) => x.diffId).filter((x) => x);
2468
+ taskOutput(">>> calculate all unique snapshots ids for old Checks ", res);
2469
+ const allOldSnapshotsUniqueIds = Array.from(/* @__PURE__ */ new Set([...oldSnapshotsBaselineIdIds, ...oldSnapshotsActualSnapshotIdIds, ...oldSnapshotsDiffIds])).map((x) => x.valueOf());
2470
+ taskOutput(">>> collect all old snapshots", res);
2471
+ const oldSnapshots = await Snapshot_model_default.find({ _id: { $in: allOldSnapshotsUniqueIds } }).lean();
2472
+ const outTable = stringTable.create([
2473
+ { item: "all checks", count: allChecksBefore.length },
2474
+ { item: "all snapshots", count: allSnapshotsBefore.length },
2475
+ { item: "all files", count: allFilesBefore.length },
2476
+ { item: `checks older than: '${options.days}' days`, count: oldChecks.length },
2477
+ { item: "old snapshots baseline ids", count: oldSnapshotsBaselineIdIds.length },
2478
+ { item: "old snapshots actual snapshotId", count: oldSnapshotsActualSnapshotIdIds.length },
2479
+ { item: "old snapshots diffIds", count: oldSnapshotsDiffIds.length },
2480
+ { item: "all old snapshots unique Ids", count: allOldSnapshotsUniqueIds.length },
2481
+ { item: "all old snapshots", count: oldSnapshots.length }
2482
+ ]);
2483
+ taskOutput(outTable, res);
2484
+ if (options.remove === "true") {
2485
+ taskOutput(`STAGE #2 Remove checks that older that: '${options.days}' days, '${dateToISO8601_default(trashHoldDate)}'
2486
+ `, res);
2487
+ taskOutput("> remove checks", res);
2488
+ const checkRemovingResult = await Check_model_default.deleteMany({ createdDate: { $lt: trashHoldDate } });
2489
+ taskOutput(`>>> removed: '${checkRemovingResult.deletedCount}'`, res);
2490
+ taskOutput("> remove snapshots", res);
2491
+ taskOutput(">> collect data to removing", res);
2492
+ taskOutput(">>> get all baselines snapshots id`s", res);
2493
+ const baselinesSnapshotsIds = await Baseline_model_default.find({}).distinct("snapshootId");
2494
+ taskOutput(">>> get all checks snapshots baselineId", res);
2495
+ const checksSnapshotsBaselineId = await Check_model_default.find({}).distinct("baselineId");
2496
+ taskOutput(">>> get all checks snapshots actualSnapshotId", res);
2497
+ const checksSnapshotsActualSnapshotId = await Check_model_default.find({}).distinct("actualSnapshotId");
2498
+ taskOutput(">> remove baselines snapshots", res);
2499
+ taskOutput(">> remove all old snapshots that not related to new baseline and check items", res);
2500
+ const removedByBaselineSnapshotsResult = await Snapshot_model_default.deleteMany({
2501
+ $and: [
2502
+ { _id: { $nin: checksSnapshotsBaselineId } },
2503
+ { _id: { $nin: checksSnapshotsActualSnapshotId } },
2504
+ { _id: { $nin: baselinesSnapshotsIds } },
2505
+ { _id: { $in: oldSnapshotsBaselineIdIds } }
2506
+ ]
2507
+ });
2508
+ taskOutput(`>>> removed: '${removedByBaselineSnapshotsResult.deletedCount}'`, res);
2509
+ taskOutput(">> remove actual snapshots", res);
2510
+ taskOutput(">> remove all old snapshots that not related to new baseline and check items", res);
2511
+ const removedByActualSnapshotsResult = await Snapshot_model_default.deleteMany({
2512
+ $and: [
2513
+ { _id: { $nin: checksSnapshotsBaselineId } },
2514
+ { _id: { $nin: checksSnapshotsActualSnapshotId } },
2515
+ { _id: { $nin: baselinesSnapshotsIds } },
2516
+ { _id: { $in: oldSnapshotsActualSnapshotIdIds } }
2517
+ ]
2518
+ });
2519
+ taskOutput(`>>> removed: '${removedByActualSnapshotsResult.deletedCount}'`, res);
2520
+ taskOutput(">> remove all old diff snapshots", res);
2521
+ const removedByDiffSnapshotsResult = await Snapshot_model_default.deleteMany({
2522
+ $and: [
2523
+ { _id: { $in: oldSnapshotsDiffIds } }
2524
+ ]
2525
+ });
2526
+ taskOutput(`>>> removed: '${removedByDiffSnapshotsResult.deletedCount}'`, res);
2527
+ taskOutput("> remove files", res);
2528
+ taskOutput(">>> collect all old snapshots filenames", res);
2529
+ const oldSnapshotsUniqueFilenames = Array.from(new Set(oldSnapshots.map((x) => x.filename)));
2530
+ taskOutput(`>> found: ${oldSnapshotsUniqueFilenames.length}`, res);
2531
+ taskOutput("> get all current snapshots filenames", res);
2532
+ const allCurrentSnapshotsFilenames = await Snapshot_model_default.find().distinct("filename").exec();
2533
+ taskOutput(">> calculate interception between all current snapshot filenames and old shapshots filenames", res);
2534
+ const arrayIntersection = (arr1, arr2) => arr1.filter((x) => arr2.includes(x));
2535
+ const filesInterception = arrayIntersection(allCurrentSnapshotsFilenames, oldSnapshotsUniqueFilenames);
2536
+ taskOutput(`>> found: ${filesInterception.length}`, res);
2537
+ taskOutput(">> calculate filenames to remove", res);
2538
+ const arrayDiff = (arr1, arr2) => arr1.filter((x) => !arr2.includes(x));
2539
+ const filesToDelete = arrayDiff(oldSnapshotsUniqueFilenames, filesInterception);
2540
+ taskOutput(`>> found: ${filesToDelete.length}`, res);
2541
+ taskOutput(`>> remove these files: ${filesToDelete.length}`, res);
2542
+ await Promise.all(filesToDelete.map((filename) => import_fs2.promises.unlink(`${config.defaultImagesPath}/${filename}`)));
2543
+ taskOutput(`>> done: ${filesToDelete.length}`, res);
2544
+ taskOutput("STAGE #3 Calculate common stats after Removing", res);
2545
+ taskOutput("> get all checks data", res);
2546
+ const allChecksAfter = await Check_model_default.find().lean().exec();
2547
+ taskOutput("> get snapshots data", res);
2548
+ const allSnapshotsAfter = await Snapshot_model_default.find().lean().exec();
2549
+ taskOutput("> get files data", res);
2550
+ const allFilesAfter = (await import_fs2.promises.readdir(config.defaultImagesPath, { withFileTypes: true })).filter((item) => !item.isDirectory()).map((x) => x.name).filter((x) => x.includes(".png"));
2551
+ const outTableAfter = stringTable.create([
2552
+ { item: "all checks", count: allChecksAfter.length },
2553
+ { item: "all snapshots", count: allSnapshotsAfter.length },
2554
+ { item: "all files", count: allFilesAfter.length }
2555
+ ]);
2556
+ taskOutput(outTableAfter, res);
2557
+ }
2558
+ const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime));
2559
+ taskOutput(`> done in ${elapsedSeconds} seconds ${elapsedSeconds / 60} min`, res);
2560
+ } catch (e) {
2561
+ const errMsg2 = e instanceof Error ? e.message : String(e);
2562
+ logger_default.error(errMsg2);
2563
+ taskOutput(errMsg2, res);
2564
+ } finally {
2565
+ res.end();
2566
+ }
2567
+ };
2568
+ var task_test = async (options = "empty", req, res) => {
2569
+ res.writeHead(200, {
2570
+ "Content-Type": "text/event-stream",
2571
+ "Cache-Control": "no-cache",
2572
+ "Content-Encoding": "none"
2573
+ });
2574
+ const x = 1e3;
2575
+ let isAborted = false;
2576
+ req.on("close", () => {
2577
+ isAborted = true;
2578
+ });
2579
+ for (let i = 0; i < x; i += 1) {
2580
+ taskOutput(`- Task Output: '${i}', options: ${options}
2581
+ `, res);
2582
+ if (isAborted) {
2583
+ taskOutput("the task was aborted\n", res);
2584
+ logger_default.warn("the task was aborted");
2585
+ res.flush();
2586
+ return res.end();
2587
+ }
2588
+ }
2589
+ return res.end();
2590
+ };
2591
+
2592
+ // src/server/services/client.service.ts
2593
+ var client_service_exports = {};
2594
+ __export(client_service_exports, {
2595
+ createCheck: () => createCheck,
2596
+ endSession: () => endSession,
2597
+ getBaselines: () => getBaselines,
2598
+ getIdent: () => getIdent,
2599
+ startSession: () => startSession
2600
+ });
2601
+ var import_fs3 = __toESM(require("fs"));
2602
+ var import_hasha = __toESM(require("hasha"));
2603
+
2604
+ // src/server/lib/dbItems/updateItem.ts
2605
+ var import_mongoose12 = __toESM(require("mongoose"));
2606
+ async function updateItem(itemType, filter, params) {
2607
+ const logOpts4 = {
2608
+ scope: "updateItem",
2609
+ msgType: "UPDATE",
2610
+ itemType
2611
+ };
2612
+ logger_default.debug(`update item type: '${itemType}', filter: '${JSON.stringify(filter)}', params: '${JSON.stringify(params)}'`, logOpts4);
2613
+ const itemModel = await import_mongoose12.default.model(itemType).findOne(filter);
2614
+ const updatedItem = await itemModel?.updateOne(params);
2615
+ logger_default.debug(`'${itemType}' was updated: '${JSON.stringify(updatedItem)}'`, { ...logOpts4, ...{ ref: String(itemModel?._id) } });
2616
+ return updatedItem;
2617
+ }
2618
+
2619
+ // src/server/lib/dbItems/updateItemDate.ts
2620
+ var import_mongoose13 = __toESM(require("mongoose"));
2621
+ var logOpts = {
2622
+ scope: "dbitems",
2623
+ msgType: "DB"
2624
+ };
2625
+ async function updateItemDate(mdClass, id2) {
2626
+ logger_default.debug(`update date for the item: '${mdClass}' with id: '${id2}'`, logOpts);
2627
+ const itemModel = await import_mongoose13.default.model(mdClass).findById(id2);
2628
+ const updatedItem = await itemModel?.updateOne({ updatedDate: Date.now() });
2629
+ logger_default.debug(`'${mdClass}' date updated: '${JSON.stringify(itemModel)}'`, logOpts);
2630
+ return updatedItem;
2631
+ }
2632
+
2633
+ // src/server/lib/dbItems/createItemIfNotExist.ts
2634
+ var import_mongoose14 = __toESM(require("mongoose"));
2635
+ async function createItemIfNotExist(modelName, params, logsMeta = {}) {
2636
+ const logOpts4 = {
2637
+ scope: "createItemIfNotExist",
2638
+ msgType: "CREATE",
2639
+ itemType: modelName
2640
+ };
2641
+ try {
2642
+ const itemModel = import_mongoose14.default.model(modelName);
2643
+ const options = {
2644
+ upsert: true,
2645
+ new: true,
2646
+ setDefaultsOnInsert: true
2647
+ };
2648
+ await itemModel.init();
2649
+ const item = await itemModel.findOneAndUpdate(params, params, options);
2650
+ logger_default.info(`ORM item '${modelName}' was created: '${JSON.stringify(item)}'`, { ...logOpts4, ...{ ref: String(item?._id) }, ...logsMeta });
2651
+ return item;
2652
+ } catch (e) {
2653
+ logger_default.debug(`cannot create '${modelName}' ORM item, error: '${e.stack || e}'`, { ...logOpts4, ...logsMeta });
2654
+ }
2655
+ return null;
2656
+ }
2657
+
2658
+ // src/server/lib/dbItems/createItemProm.ts
2659
+ var import_mongoose15 = __toESM(require("mongoose"));
2660
+ var logOpts2 = {
2661
+ scope: "dbitems",
2662
+ msgType: "DB"
2663
+ };
2664
+ async function createItemProm(modelName, params) {
2665
+ try {
2666
+ const itemModel = import_mongoose15.default.model(modelName);
2667
+ logger_default.debug(`start to create ORM item via promise: '${modelName}', params: '${JSON.stringify(params)}'`, logOpts2);
2668
+ const item = await itemModel.create(params);
2669
+ return item;
2670
+ } catch (e) {
2671
+ const errMsg2 = `cannot create '${modelName}', error: '${e.stack || e}'`;
2672
+ logger_default.error(errMsg2, logOpts2);
2673
+ throw new Error(errMsg2);
2674
+ }
2675
+ }
2676
+
2677
+ // src/server/lib/dbItems/createTest.ts
2678
+ async function createTest(params) {
2679
+ return createItemProm("VRSTest", params);
2680
+ }
2681
+
2682
+ // src/server/lib/dbItems/createSuiteIfNotExist.ts
2683
+ async function createSuiteIfNotExist(params, logsMeta = {}) {
2684
+ const logOpts4 = {
2685
+ scope: "createSuiteIfNotExist",
2686
+ msgType: "CREATE",
2687
+ itemType: "VRSSuite"
2688
+ };
2689
+ if (!params.name || !params.app) throw new Error(`Cannot create suite, wrong params: '${JSON.stringify(params)}'`);
2690
+ logger_default.debug(`try to create suite if exist, params: '${JSON.stringify(params)}'`, { ...logOpts4, ...logsMeta });
2691
+ let suite = await Suite_model_default.findOne({ name: params.name }).exec();
2692
+ if (suite) {
2693
+ logger_default.debug(`suite already exist: '${JSON.stringify(params)}'`, { ...logOpts4, ...logsMeta });
2694
+ return suite;
2695
+ }
2696
+ suite = await Suite_model_default.create(params);
2697
+ logger_default.debug(`suite with name: '${params.name}' was created`, { ...logOpts4, ...logsMeta });
2698
+ return suite;
2699
+ }
2700
+
2701
+ // src/server/lib/dbItems/createRunIfNotExist.ts
2702
+ async function createRunIfNotExist(params, logsMeta = {}) {
2703
+ const logOpts4 = {
2704
+ scope: "createRunIfNotExist",
2705
+ msgType: "CREATE",
2706
+ itemType: "VRSRun"
2707
+ };
2708
+ let run;
2709
+ try {
2710
+ if (!params.name || !params.app || !params.ident) {
2711
+ throw new Error(`Cannot create run, wrong params: '${JSON.stringify(params)}'`);
2712
+ }
2713
+ logger_default.debug(`try to create run if exist, params: '${JSON.stringify(params)}'`, { ...logOpts4, ...logsMeta });
2714
+ run = await Run_model_default.findOne({ ident: params.ident }).exec();
2715
+ if (run) {
2716
+ logger_default.debug(`run already exist: '${JSON.stringify(params)}'`, { ...logOpts4, ...logsMeta });
2717
+ return run;
2718
+ }
2719
+ run = await Run_model_default.create({
2720
+ ...params,
2721
+ createdDate: params.createdDate || /* @__PURE__ */ new Date()
2722
+ });
2723
+ logger_default.debug(`run with name: '${params.name}' was created: ${run}`, { ...logOpts4, ...logsMeta });
2724
+ return run;
2725
+ } catch (e) {
2726
+ if (e.code === 11e3) {
2727
+ logger_default.warn(`run key duplication collision: '${JSON.stringify(params)}', error: '${errMsg(e)}'`, { ...logOpts4, ...logsMeta });
2728
+ run = await Run_model_default.findOne({ name: params.name, ident: params.ident });
2729
+ logger_default.warn(`run key duplication collision, found: '${JSON.stringify(run)}'`, { ...logOpts4, ...logsMeta });
2730
+ if (run) return run;
2731
+ }
2732
+ logger_default.error(`cannot create run, params: '${JSON.stringify(params)}', error: '${errMsg(e)}', obj: ${JSON.stringify(e)}`, { ...logOpts4, ...logsMeta });
2733
+ throw e;
2734
+ }
2735
+ }
2736
+
2737
+ // src/server/lib/сomparison/compareImagesNode.ts
2738
+ var import_node_resemble = __toESM(require("@syngrisi/node-resemble.js"));
2739
+ async function streamToBuffer(stream) {
2740
+ return new Promise((resolve, reject) => {
2741
+ const data = [];
2742
+ stream.on("data", (chunk) => {
2743
+ data.push(chunk);
2744
+ });
2745
+ stream.on("end", () => {
2746
+ resolve(Buffer.concat(data));
2747
+ });
2748
+ stream.on("error", (err) => {
2749
+ reject(err);
2750
+ });
2751
+ });
2752
+ }
2753
+ function compareImages(image1, image2, options) {
2754
+ return new Promise((resolve, reject) => {
2755
+ try {
2756
+ const ignoreTransform = {
2757
+ antialiasing: "ignoreAntialiasing",
2758
+ colors: "ignoreColors",
2759
+ nothing: "ignoreNothing"
2760
+ };
2761
+ const ignoreMethod = ignoreTransform[options.ignore] ? ignoreTransform[options.ignore] : "ignoreNothing";
2762
+ console.log("ignoreMethod", ignoreMethod);
2763
+ console.log("ignoreMethod", ignoreMethod);
2764
+ console.log("ignoreMethod", ignoreMethod);
2765
+ console.log("ignoreMethod", ignoreMethod);
2766
+ console.log("ignoreMethod", ignoreMethod);
2767
+ console.log("ignoreMethod", ignoreMethod);
2768
+ console.log("ignoreMethod", ignoreMethod);
2769
+ console.log("ignoreMethod", ignoreMethod);
2770
+ const outputOpts = options.output;
2771
+ import_node_resemble.default.outputSettings(outputOpts);
2772
+ let ignoredRect;
2773
+ if (options.ignoreRectangles) {
2774
+ ignoredRect = options.ignoreRectangles.map((it) => {
2775
+ delete it.name;
2776
+ return [it.left, it.top, it.right - it.left, it.bottom - it.top];
2777
+ });
2778
+ }
2779
+ (0, import_node_resemble.default)(image1).compareTo(image2)[ignoreMethod]().ignoreRectangles(ignoredRect).onComplete(async (data) => {
2780
+ console.log(data);
2781
+ const stream = await data.getDiffImage();
2782
+ const buffer = await streamToBuffer(stream.pack());
2783
+ data.getBuffer = function() {
2784
+ return buffer;
2785
+ };
2786
+ resolve(data);
2787
+ });
2788
+ } catch (e) {
2789
+ reject(e);
2790
+ }
2791
+ });
2792
+ }
2793
+
2794
+ // src/server/lib/сomparison/comparator.ts
2795
+ var DEFAULT_OPTIONS = {
2796
+ output: {
2797
+ largeImageThreshold: 0,
2798
+ outputDiff: true,
2799
+ errorType: "flat",
2800
+ transparency: 0
2801
+ },
2802
+ ignore: "nothing"
2803
+ };
2804
+ async function makeDiff(imgData1, imgData2, options = {}) {
2805
+ const opts = Object.assign(DEFAULT_OPTIONS, options);
2806
+ opts.ignoreRectangles = options.ignoredBoxes;
2807
+ const compareData = await compareImages(imgData1, imgData2, opts);
2808
+ return compareData;
2809
+ }
2810
+ async function getDiff(baselineOrigin, actualOrigin, opts = {}) {
2811
+ const logOpts4 = {
2812
+ scope: "getDiff",
2813
+ itemType: "image",
2814
+ msgType: "GET_DIFF"
2815
+ };
2816
+ try {
2817
+ const executionTimer = process.hrtime();
2818
+ logger_default.debug(`SAMPLE #1: ${process.hrtime(executionTimer).toString()}`, logOpts4);
2819
+ const directDiff = await makeDiff(baselineOrigin, actualOrigin, opts);
2820
+ logger_default.debug(`SAMPLE #2: ${process.hrtime(executionTimer).toString()}`, logOpts4);
2821
+ directDiff.executionTotalTime = process.hrtime(executionTimer).toString();
2822
+ logger_default.debug(`SAMPLE #3: ${process.hrtime(executionTimer).toString()}`, logOpts4);
2823
+ logger_default.debug(`the diff is: ${JSON.stringify(directDiff, null, 4)}`, logOpts4);
2824
+ return directDiff;
2825
+ } catch (e) {
2826
+ logger_default.error(errMsg(e), logOpts4);
2827
+ throw new Error(errMsg(e));
2828
+ }
2829
+ }
2830
+
2831
+ // src/server/services/client.service.ts
2832
+ var import_http_status3 = __toESM(require("http-status"));
2833
+ var import_http_status4 = __toESM(require("http-status"));
2834
+ async function updateTest(id2, update4) {
2835
+ const logOpts4 = {
2836
+ scope: "updateTest",
2837
+ itemType: "test",
2838
+ msgType: "UPDATE",
2839
+ ref: id2
2840
+ };
2841
+ logger_default.debug(`update test id '${id2}' with params '${JSON.stringify(update4)}'`, logOpts4);
2842
+ const updatedDate = update4.updatedDate || Date.now();
2843
+ const test = await Test_model_default.findByIdAndUpdate(
2844
+ id2,
2845
+ { ...update4, updatedDate }
2846
+ ).exec();
2847
+ await test?.save();
2848
+ return test;
2849
+ }
2850
+ var startSession = async (params, username) => {
2851
+ const logOpts4 = {
2852
+ scope: "createTest",
2853
+ user: username,
2854
+ itemType: "test",
2855
+ msgType: "CREATE"
2856
+ };
2857
+ logger_default.info(`create test with name '${params.name}', params: '${JSON.stringify(params)}'`, logOpts4);
2858
+ const opts = removeEmptyProperties({
2859
+ name: params.name,
2860
+ status: "Running",
2861
+ app: params.app,
2862
+ tags: params.tags && JSON.parse(params.tags),
2863
+ branch: params.branch,
2864
+ viewport: params.viewport,
2865
+ browserName: params.browser,
2866
+ browserVersion: params.browserVersion,
2867
+ browserFullVersion: params.browserFullVersion,
2868
+ os: params.os,
2869
+ startDate: /* @__PURE__ */ new Date(),
2870
+ updatedDate: /* @__PURE__ */ new Date()
2871
+ });
2872
+ try {
2873
+ const app = await createItemIfNotExist(
2874
+ "VRSApp",
2875
+ { name: params.app },
2876
+ { user: username, itemType: "app" }
2877
+ );
2878
+ opts.app = app._id;
2879
+ const run = await createRunIfNotExist(
2880
+ { name: params.run, ident: params.runident, app: app._id },
2881
+ { user: username, itemType: "run" }
2882
+ );
2883
+ opts.run = run._id;
2884
+ const suite = await createSuiteIfNotExist(
2885
+ { name: params.suite || "Others", app: app._id, createdDate: /* @__PURE__ */ new Date() },
2886
+ { user: username, itemType: "suite" }
2887
+ );
2888
+ opts.suite = suite._id;
2889
+ const test = await createTest(opts);
2890
+ return test;
2891
+ } catch (e) {
2892
+ logger_default.error(`cannot start session '${params.name}', params: '${JSON.stringify(params)}', error: ${errMsg(e)}`, logOpts4);
2893
+ throw e;
2894
+ }
2895
+ };
2896
+ var endSession = async (testId, username) => {
2897
+ const logOpts4 = {
2898
+ scope: "stopSession",
2899
+ msgType: "END_SESSION",
2900
+ user: username,
2901
+ itemType: "test",
2902
+ ref: testId
2903
+ };
2904
+ await waitUntil(async () => (await Check_model_default.find({ test: testId }).exec()).filter((ch) => ch.status.toString() !== "pending").length > 0);
2905
+ const sessionChecks = await Check_model_default.find({ test: testId }).lean().exec();
2906
+ const checksStatuses = sessionChecks.map((x) => x.status[0]);
2907
+ let status3 = "not set";
2908
+ if (checksStatuses.some((st2) => st2 === "failed")) {
2909
+ status3 = "Failed";
2910
+ }
2911
+ if (checksStatuses.some((st2) => st2 === "passed") && !checksStatuses.some((st2) => st2 === "failed")) {
2912
+ status3 = "Passed";
2913
+ }
2914
+ if (checksStatuses.some((st2) => st2 === "new") && !checksStatuses.some((st2) => st2 === "failed")) {
2915
+ status3 = "Passed";
2916
+ }
2917
+ if (checksStatuses.some((st2) => st2 === "blinking") && !checksStatuses.some((st2) => st2 === "failed")) {
2918
+ status3 = "Passed";
2919
+ }
2920
+ if (checksStatuses.every((st2) => st2 === "new")) {
2921
+ status3 = "New";
2922
+ }
2923
+ const blinking = checksStatuses.filter((g) => g === "blinking").length;
2924
+ const testParams = {
2925
+ status: status3,
2926
+ blinking
2927
+ // calculatedViewport,
2928
+ };
2929
+ logger_default.info(`the session is over, the test will be updated with parameters: '${JSON.stringify(testParams)}'`, logOpts4);
2930
+ const updatedTest = await updateTest(testId, testParams);
2931
+ const result = updatedTest?.toObject();
2932
+ return result;
2933
+ };
2934
+ async function getAcceptedBaseline(params) {
2935
+ const identFieldsAccepted = Object.assign(buildIdentObject(params), { markedAs: "accepted" });
2936
+ const acceptedBaseline = await Baseline_model_default.findOne(identFieldsAccepted, {}, { sort: { createdDate: -1 } });
2937
+ logger_default.debug(`acceptedBaseline: '${acceptedBaseline ? JSON.stringify(acceptedBaseline) : "not found"}'`, { itemType: "baseline" });
2938
+ if (acceptedBaseline) return acceptedBaseline;
2939
+ return null;
2940
+ }
2941
+ async function getLastSuccessCheck(identifier) {
2942
+ const condition = [{
2943
+ ...identifier,
2944
+ status: "new"
2945
+ }, {
2946
+ ...identifier,
2947
+ status: "passed"
2948
+ }];
2949
+ return (await Check_model_default.find({ $or: condition }).sort({ updatedDate: -1 }).limit(1))[0];
2950
+ }
2951
+ async function getNotPendingChecksByIdent(identifier) {
2952
+ return Check_model_default.find({
2953
+ ...identifier,
2954
+ status: { $ne: "pending" }
2955
+ }).sort({ updatedDate: -1 }).exec();
2956
+ }
2957
+ async function getSnapshotByImgHash(hash) {
2958
+ return Snapshot_model_default.findOne({ imghash: hash });
2959
+ }
2960
+ async function createSnapshot(parameters) {
2961
+ const logOpts4 = {
2962
+ scope: "createSnapshot",
2963
+ itemType: "snapshot",
2964
+ msgType: "CREATE"
2965
+ };
2966
+ const { name, fileData, hashCode } = parameters;
2967
+ const opts = { name };
2968
+ if (fileData === null) throw new ApiError_default(import_http_status3.default.BAD_REQUEST, `cannot create the snapshot, the 'fileData' is not set, name: '${name}'`);
2969
+ opts.imghash = hashCode || (0, import_hasha.default)(fileData);
2970
+ const snapshot = new Snapshot_model_default(opts);
2971
+ const filename = `${snapshot.id}.png`;
2972
+ const path3 = `${config.defaultImagesPath}${filename}`;
2973
+ logger_default.debug(`save screenshot for: '${name}' snapshot to: '${path3}'`, logOpts4);
2974
+ await import_fs3.promises.writeFile(path3, fileData);
2975
+ snapshot.filename = filename;
2976
+ await snapshot.save();
2977
+ logger_default.debug(`snapshot was saved: '${JSON.stringify(snapshot)}'`, { ...logOpts4, ...{ ref: snapshot._id } });
2978
+ return snapshot;
2979
+ }
2980
+ async function cloneSnapshot(sourceSnapshot, name) {
2981
+ const { filename } = sourceSnapshot;
2982
+ const hashCode = sourceSnapshot.imghash;
2983
+ const newSnapshot = new Snapshot_model_default({ name, filename, imghash: hashCode });
2984
+ await newSnapshot.save();
2985
+ return newSnapshot;
2986
+ }
2987
+ async function compareSnapshots(baselineSnapshot, actual, opts = {}) {
2988
+ const logOpts4 = {
2989
+ scope: "compareSnapshots",
2990
+ ref: baselineSnapshot.id,
2991
+ itemType: "snapshot",
2992
+ msgType: "COMPARE"
2993
+ };
2994
+ try {
2995
+ logger_default.debug(`compare baseline and actual snapshots with ids: [${baselineSnapshot.id}, ${actual.id}]`, logOpts4);
2996
+ logger_default.debug(`current baseline snapshot: ${JSON.stringify(baselineSnapshot)}`, logOpts4);
2997
+ let diff;
2998
+ if (baselineSnapshot.imghash === actual.imghash) {
2999
+ logger_default.debug(`baseline and actual snapshot have the identical image hashes: '${baselineSnapshot.imghash}'`, logOpts4);
3000
+ diff = {
3001
+ isSameDimensions: true,
3002
+ dimensionDifference: { width: 0, height: 0 },
3003
+ rawMisMatchPercentage: 0,
3004
+ misMatchPercentage: "0.00",
3005
+ analysisTime: 0,
3006
+ executionTotalTime: "0",
3007
+ getBuffer: null
3008
+ };
3009
+ } else {
3010
+ const baselinePath = `${config.defaultImagesPath}${baselineSnapshot.filename}`;
3011
+ const actualPath = `${config.defaultImagesPath}${actual.filename}`;
3012
+ const baselineData = await import_fs3.promises.readFile(baselinePath);
3013
+ const actualData = await import_fs3.promises.readFile(actualPath);
3014
+ logger_default.debug(`baseline path: ${baselinePath}`, logOpts4);
3015
+ logger_default.debug(`actual path: ${actualPath}`, logOpts4);
3016
+ const options = opts;
3017
+ const baseline = await Baseline_model_default.findOne({ snapshootId: baselineSnapshot._id }).exec();
3018
+ if (baseline) {
3019
+ if (baseline.ignoreRegions) {
3020
+ logger_default.debug(`ignore regions: '${baseline.ignoreRegions}', type: '${typeof baseline.ignoreRegions}'`);
3021
+ options.ignoredBoxes = JSON.parse(baseline.ignoreRegions);
3022
+ }
3023
+ options.ignore = baseline.matchType || "nothing";
3024
+ }
3025
+ diff = await getDiff(baselineData, actualData, options);
3026
+ }
3027
+ logger_default.silly(`the diff is: '${JSON.stringify(diff, null, 2)}'`);
3028
+ if (diff.rawMisMatchPercentage.toString() !== "0") {
3029
+ logger_default.debug(`images are different, ids: [${baselineSnapshot.id}, ${actual.id}], rawMisMatchPercentage: '${diff.rawMisMatchPercentage}'`);
3030
+ }
3031
+ if (diff.stabMethod && diff.vOffset) {
3032
+ if (diff.stabMethod === "downup") {
3033
+ actual.vOffset = -diff.vOffset;
3034
+ await actual.save();
3035
+ }
3036
+ if (diff.stabMethod === "updown") {
3037
+ baselineSnapshot.vOffset = -diff.vOffset;
3038
+ await baselineSnapshot.save();
3039
+ }
3040
+ }
3041
+ return diff;
3042
+ } catch (e) {
3043
+ const errMsg2 = `cannot compare snapshots: ${e}
3044
+ ${e instanceof Error ? e.stack : e}`;
3045
+ logger_default.error(errMsg2, logOpts4);
3046
+ throw new Error(String(e));
3047
+ }
3048
+ }
3049
+ var isBaselineValid = (baseline) => {
3050
+ const keys = [
3051
+ "name",
3052
+ "app",
3053
+ "branch",
3054
+ "browserName",
3055
+ "viewport",
3056
+ "os",
3057
+ "createdDate",
3058
+ "lastMarkedDate",
3059
+ "markedAs",
3060
+ "markedById",
3061
+ "markedByUsername",
3062
+ "snapshootId"
3063
+ ];
3064
+ for (const key of keys) {
3065
+ if (!baseline[key]) {
3066
+ logger_default.error(`invalid baseline, the '${key}' property is empty`);
3067
+ return false;
3068
+ }
3069
+ }
3070
+ return true;
3071
+ };
3072
+ var updateCheckParamsFromBaseline = (params, baseline) => {
3073
+ const updatedParams = { ...params };
3074
+ updatedParams.baselineId = baseline.snapshootId.toString();
3075
+ updatedParams.markedAs = baseline.markedAs;
3076
+ updatedParams.markedDate = baseline.lastMarkedDate?.toString();
3077
+ updatedParams.markedByUsername = baseline.markedByUsername;
3078
+ return updatedParams;
3079
+ };
3080
+ var prepareActualSnapshot = async (checkParam, snapshotFoundedByHashcode, logOpts4) => {
3081
+ let currentSnapshot;
3082
+ const fileData = checkParam.files ? checkParam.files.file.data : null;
3083
+ if (snapshotFoundedByHashcode) {
3084
+ const fullFilename = `${config.defaultImagesPath}${snapshotFoundedByHashcode.filename}`;
3085
+ if (!import_fs3.default.existsSync(fullFilename)) {
3086
+ throw new Error(`Couldn't find the baseline file: '${fullFilename}'`);
3087
+ }
3088
+ logger_default.debug(`snapshot with such hashcode: '${checkParam.hashCode}' is already exists, will clone it`, logOpts4);
3089
+ if (!checkParam.name) throw new ApiError_default(import_http_status3.default.BAD_REQUEST, `Cannot prepareActualSnapshot name is empty, hashe: ${checkParam.hashCode}`);
3090
+ currentSnapshot = await cloneSnapshot(snapshotFoundedByHashcode, checkParam.name);
3091
+ } else {
3092
+ logger_default.debug(`snapshot with such hashcode: '${checkParam.hashCode}' does not exists, will create it`, logOpts4);
3093
+ currentSnapshot = await createSnapshot({ name: checkParam.name, fileData, hashCode: checkParam.hashCode });
3094
+ }
3095
+ return currentSnapshot;
3096
+ };
3097
+ async function isNeedFiles(checkParam, logOpts4) {
3098
+ const snapshotFoundedByHashcode = await getSnapshotByImgHash(checkParam.hashCode);
3099
+ if (!checkParam.hashCode && !checkParam.files) {
3100
+ logger_default.debug("hashCode or files parameters should be present", logOpts4);
3101
+ return { needFilesStatus: true, snapshotFoundedByHashcode };
3102
+ }
3103
+ if (!checkParam.files && !snapshotFoundedByHashcode) {
3104
+ logger_default.debug(`cannot find the snapshot with hash: '${checkParam.hashCode}'`, logOpts4);
3105
+ return { needFilesStatus: true, snapshotFoundedByHashcode };
3106
+ }
3107
+ return { needFilesStatus: false, snapshotFoundedByHashcode };
3108
+ }
3109
+ async function inspectBaseline(newCheckParams, storedBaseline, checkIdent, currentSnapshot, logOpts4) {
3110
+ let currentBaselineSnapshot = null;
3111
+ const params = {};
3112
+ params.failReasons = [];
3113
+ if (storedBaseline !== null) {
3114
+ logger_default.debug(`a baseline for check name: '${newCheckParams.name}', id: '${storedBaseline.snapshootId}' is already exists`, logOpts4);
3115
+ if (!isBaselineValid(storedBaseline)) {
3116
+ newCheckParams.failReasons.push("invalid_baseline");
3117
+ }
3118
+ Object.assign(params, updateCheckParamsFromBaseline(newCheckParams, storedBaseline));
3119
+ currentBaselineSnapshot = await Snapshot_model_default.findById(storedBaseline.snapshootId);
3120
+ if (!currentBaselineSnapshot) throw new ApiError_default(import_http_status3.default.INTERNAL_SERVER_ERROR, `Cannot find the snapshot with id: ${storedBaseline.snapshootId}`);
3121
+ } else {
3122
+ const checksWithSameIdent = await getNotPendingChecksByIdent(checkIdent);
3123
+ if (checksWithSameIdent.length > 0) {
3124
+ logger_default.error(`checks with ident'${JSON.stringify(checkIdent)}' exist, but baseline is absent`, logOpts4);
3125
+ params.failReasons.push("not_accepted");
3126
+ params.baselineId = currentSnapshot.id.toString();
3127
+ currentBaselineSnapshot = currentSnapshot;
3128
+ } else {
3129
+ params.baselineId = currentSnapshot.id;
3130
+ params.status = "new";
3131
+ currentBaselineSnapshot = currentSnapshot;
3132
+ logger_default.debug(`create the new check with params: '${prettyCheckParams_default(params)}'`, logOpts4);
3133
+ }
3134
+ }
3135
+ return { inspectBaselineParams: params, currentBaselineSnapshot };
3136
+ }
3137
+ var ignoreDifferentResolutions = ({ height, width }) => {
3138
+ if (width === 0 && height === -1) return true;
3139
+ if (width === 0 && height === 1) return true;
3140
+ return false;
3141
+ };
3142
+ var compare = async (expectedSnapshot, actualSnapshot, newCheckParams, skipSaveOnCompareError, currentUser) => {
3143
+ const logOpts4 = {
3144
+ scope: "createCheck.compare",
3145
+ user: currentUser.username,
3146
+ itemType: "check",
3147
+ msgType: "COMPARE"
3148
+ };
3149
+ const executionTimer = process.hrtime();
3150
+ const compareResult = {};
3151
+ compareResult.failReasons = [...newCheckParams.failReasons];
3152
+ let checkCompareResult;
3153
+ let diffSnapshot = null;
3154
+ const areSnapshotsDifferent = (result) => result.rawMisMatchPercentage.toString() !== "0";
3155
+ const areSnapshotsWrongDimensions = (result) => !result.isSameDimensions && !ignoreDifferentResolutions(result.dimensionDifference);
3156
+ if (newCheckParams.status !== "new" && !compareResult.failReasons.includes("not_accepted")) {
3157
+ try {
3158
+ logger_default.debug(`'the check with name: '${newCheckParams.name}' isn't new, make comparing'`, logOpts4);
3159
+ checkCompareResult = await compareSnapshots(expectedSnapshot, actualSnapshot, { vShifting: newCheckParams.vShifting });
3160
+ logger_default.silly(`ignoreDifferentResolutions: '${ignoreDifferentResolutions(checkCompareResult.dimensionDifference)}'`);
3161
+ logger_default.silly(`dimensionDifference: '${JSON.stringify(checkCompareResult.dimensionDifference)}`);
3162
+ if (areSnapshotsDifferent(checkCompareResult) || areSnapshotsWrongDimensions(checkCompareResult)) {
3163
+ let logMsg;
3164
+ if (areSnapshotsWrongDimensions(checkCompareResult)) {
3165
+ logMsg = "snapshots have different dimensions";
3166
+ compareResult.failReasons.push("wrong_dimensions");
3167
+ }
3168
+ if (areSnapshotsDifferent(checkCompareResult)) {
3169
+ logMsg = "snapshots have differences";
3170
+ compareResult.failReasons.push("different_images");
3171
+ }
3172
+ if (logMsg) logger_default.debug(logMsg, logOpts4);
3173
+ logger_default.debug(`saving diff snapshot for check with name: '${newCheckParams.name}'`, logOpts4);
3174
+ if (!skipSaveOnCompareError) {
3175
+ diffSnapshot = await createSnapshot({
3176
+ name: newCheckParams.name,
3177
+ fileData: checkCompareResult.getBuffer()
3178
+ });
3179
+ compareResult.diffId = diffSnapshot.id;
3180
+ compareResult.diffSnapshot = diffSnapshot;
3181
+ }
3182
+ compareResult.status = "failed";
3183
+ } else {
3184
+ compareResult.status = "passed";
3185
+ }
3186
+ checkCompareResult.totalCheckHandleTime = process.hrtime(executionTimer).toString();
3187
+ compareResult.result = JSON.stringify(checkCompareResult, null, " ");
3188
+ } catch (e) {
3189
+ compareResult.status = "failed";
3190
+ compareResult.result = JSON.stringify({ server_error: `error during comparing - ${errMsg(e)}` });
3191
+ compareResult.failReasons.push("internal_server_error");
3192
+ throw new ApiError_default(import_http_status3.default.INTERNAL_SERVER_ERROR, `error during comparing: ${errMsg(e)}`);
3193
+ }
3194
+ }
3195
+ if (compareResult.failReasons.length > 0) {
3196
+ compareResult.status = "failed";
3197
+ }
3198
+ return compareResult;
3199
+ };
3200
+ var createCheckParams = (checkParam, suite, app, test, currentUser) => ({
3201
+ test: test.id,
3202
+ name: checkParam.name,
3203
+ status: "pending",
3204
+ viewport: checkParam.viewport,
3205
+ browserName: checkParam.browserName,
3206
+ browserVersion: checkParam.browserVersion,
3207
+ browserFullVersion: checkParam.browserFullVersion,
3208
+ os: checkParam.os,
3209
+ updatedDate: Date.now(),
3210
+ suite: suite.id,
3211
+ app: app.id,
3212
+ branch: checkParam.branch,
3213
+ domDump: checkParam.domDump,
3214
+ run: test.run.toString(),
3215
+ creatorId: currentUser._id.toString(),
3216
+ creatorUsername: currentUser.username,
3217
+ hashCode: checkParam.hashCode,
3218
+ failReasons: []
3219
+ });
3220
+ var createCheck = async (checkParam, test, suite, app, currentUser, skipSaveOnCompareError = false) => {
3221
+ const logOpts4 = {
3222
+ scope: "createCheck",
3223
+ user: currentUser.username,
3224
+ itemType: "check",
3225
+ msgType: "CREATE"
3226
+ };
3227
+ let actualSnapshot;
3228
+ let currentBaselineSnapshot;
3229
+ const newCheckParams = createCheckParams(checkParam, suite, app, test, currentUser);
3230
+ const checkIdent = buildIdentObject(newCheckParams);
3231
+ let check = null;
3232
+ const totalCheckHandleTime = 0;
3233
+ const addCheck = (test2, check2) => {
3234
+ if (test2.checks) {
3235
+ test2.checks.push(check2.id);
3236
+ } else {
3237
+ test2.checks = [check2.id];
3238
+ }
3239
+ };
3240
+ try {
3241
+ const { needFilesStatus, snapshotFoundedByHashcode } = await isNeedFiles(checkParam, logOpts4);
3242
+ if (needFilesStatus) return { status: "needFiles" };
3243
+ actualSnapshot = await prepareActualSnapshot(checkParam, snapshotFoundedByHashcode, logOpts4);
3244
+ newCheckParams.actualSnapshotId = actualSnapshot.id;
3245
+ logger_default.info(`find a baseline for the check with identifier: '${JSON.stringify(checkIdent)}'`, logOpts4);
3246
+ const storedBaseline = await getAcceptedBaseline(checkIdent);
3247
+ const inspectBaselineResult = await inspectBaseline(newCheckParams, storedBaseline, checkIdent, actualSnapshot, logOpts4);
3248
+ Object.assign(newCheckParams, inspectBaselineResult.inspectBaselineParams);
3249
+ currentBaselineSnapshot = inspectBaselineResult.currentBaselineSnapshot;
3250
+ const compareResult = await compare(currentBaselineSnapshot, actualSnapshot, newCheckParams, skipSaveOnCompareError, currentUser);
3251
+ Object.assign(newCheckParams, compareResult);
3252
+ logger_default.debug(`create the new check document with params: '${prettyCheckParams_default(newCheckParams)}'`, logOpts4);
3253
+ check = await Check_model_default.create(newCheckParams);
3254
+ const savedCheck = await check.save();
3255
+ logger_default.debug(`the check with id: '${check.id}', was created, will updated with data during creating process`, logOpts4);
3256
+ logOpts4.ref = String(check.id);
3257
+ logger_default.debug(`update test with check id: '${check.id}'`, logOpts4);
3258
+ addCheck(test, check);
3259
+ test.markedAs = await calculateAcceptedStatus(check.test);
3260
+ test.updatedDate = /* @__PURE__ */ new Date();
3261
+ await test.save();
3262
+ logger_default.debug("update suite and run", logOpts4);
3263
+ await updateItemDate("VRSSuite", check.suite);
3264
+ await updateItemDate("VRSRun", check.run);
3265
+ const lastSuccessCheck = await getLastSuccessCheck(checkIdent);
3266
+ const checkObject = savedCheck.toObject();
3267
+ const result = {
3268
+ ...checkObject,
3269
+ currentSnapshot: actualSnapshot,
3270
+ expectedSnapshot: currentBaselineSnapshot,
3271
+ diffSnapshot: compareResult.diffSnapshot,
3272
+ executeTime: totalCheckHandleTime,
3273
+ lastSuccess: lastSuccessCheck ? lastSuccessCheck.id : null
3274
+ };
3275
+ return result;
3276
+ } catch (e) {
3277
+ newCheckParams.status = "failed";
3278
+ newCheckParams.result = `{ "server error": "${errMsg(e)}" }`;
3279
+ newCheckParams.failReasons.push("internal_server_error");
3280
+ if (!check) {
3281
+ logger_default.debug(`create the new check document with params: '${prettyCheckParams_default(newCheckParams)}'`, logOpts4);
3282
+ check = await Check_model_default.create(newCheckParams);
3283
+ await check.save();
3284
+ } else {
3285
+ check.set(newCheckParams);
3286
+ await check.save();
3287
+ }
3288
+ logger_default.debug(`the check with id: '${check.id}', was created, will updated with data during creating process`, logOpts4);
3289
+ logOpts4.ref = check.id;
3290
+ logger_default.debug(`update test with check id: '${check.id}'`, logOpts4);
3291
+ addCheck(test, check);
3292
+ await test.save();
3293
+ throw new ApiError_default(import_http_status4.default.INTERNAL_SERVER_ERROR, errMsg(e));
3294
+ }
3295
+ };
3296
+ var getIdent = () => ident;
3297
+ var getBaselines = async (filter, options) => {
3298
+ const logOpts4 = {
3299
+ scope: "getBaselines",
3300
+ itemType: "baseline",
3301
+ msgType: "GET"
3302
+ };
3303
+ const app = await App_model_default.findOne({ name: filter.app });
3304
+ if (!app) {
3305
+ logger_default.error(`Cannot find the app: '${filter.app}'`, logOpts4);
3306
+ return {};
3307
+ }
3308
+ filter.app = app._id;
3309
+ logger_default.debug(`Get baselines with filter: '${JSON.stringify(filter)}', options: '${JSON.stringify(options)}'`, logOpts4);
3310
+ return Baseline_model_default.paginate(filter, options);
3311
+ };
3312
+
3313
+ // src/server/services/user.service.ts
3314
+ var user_service_exports = {};
3315
+ __export(user_service_exports, {
3316
+ createUser: () => createUser2,
3317
+ deleteUserById: () => deleteUserById,
3318
+ getUserByEmail: () => getUserByEmail,
3319
+ getUserById: () => getUserById,
3320
+ queryUsers: () => queryUsers,
3321
+ updateUserById: () => updateUserById
3322
+ });
3323
+ var import_http_status5 = __toESM(require("http-status"));
3324
+ var createUser2 = async (userBody) => {
3325
+ if (await User_model_default.isEmailTaken(userBody.username)) {
3326
+ throw new ApiError_default(import_http_status5.default.BAD_REQUEST, "Email already taken");
3327
+ }
3328
+ const logOpts4 = {
3329
+ msgType: "CREATE",
3330
+ itemType: "user",
3331
+ ref: userBody.username,
3332
+ scope: "createUser"
3333
+ };
3334
+ logger_default.debug(`create the user with name '${userBody.username}', params: '${JSON.stringify(userBody)}'`, logOpts4);
3335
+ const user = await User_model_default.create({ ...userBody, createdDate: Date.now() });
3336
+ const updatedUser = await user.setPassword(userBody.password);
3337
+ await updatedUser.save();
3338
+ logger_default.debug(`password for user: '${userBody.username}' set successfully`, logOpts4);
3339
+ const userWithSelectedFields = await User_model_default.findById(updatedUser._id).select("username firstName lastName role createdDate updatedDate createdDate").exec();
3340
+ return userWithSelectedFields;
3341
+ };
3342
+ var queryUsers = async (filter, options) => {
3343
+ const users = await User_model_default.paginate(filter, options);
3344
+ return users;
3345
+ };
3346
+ var getUserById = async (id2) => User_model_default.findById(id2).select("username firstName lastName role createdDate updatedDate createdDate").exec();
3347
+ var getUserByEmail = async (email) => User_model_default.findOne({ email });
3348
+ var updateUserById = async (userId, updateBody) => {
3349
+ const logOpts4 = {
3350
+ msgType: "UPDATE",
3351
+ itemType: "user",
3352
+ scope: "updateUserById",
3353
+ ref: userId
3354
+ };
3355
+ logger_default.info(`update user with id: '${userId}' name '${updateBody.username}', params: '${JSON.stringify(updateBody)}'`, logOpts4);
3356
+ const user = await getUserById(userId);
3357
+ if (!user) {
3358
+ throw new ApiError_default(import_http_status5.default.NOT_FOUND, "User not found");
3359
+ }
3360
+ if (updateBody.email && await User_model_default.isEmailTaken(updateBody.email, userId)) {
3361
+ throw new ApiError_default(import_http_status5.default.BAD_REQUEST, "Email already taken");
3362
+ }
3363
+ if (updateBody.password) {
3364
+ logger_default.debug(`update password for '${updateBody.username}'`, logOpts4);
3365
+ await user.setPassword(updateBody.password);
3366
+ await user.save();
3367
+ logger_default.debug(`password for '${updateBody.username}' was updated`, logOpts4);
3368
+ }
3369
+ logger_default.debug(`user '${updateBody.username}' was updated successfully`, logOpts4);
3370
+ const { password, ...newupdateBody } = updateBody;
3371
+ Object.assign(user, {
3372
+ ...newupdateBody,
3373
+ updatedDate: Date.now()
3374
+ });
3375
+ await user.save();
3376
+ return user;
3377
+ };
3378
+ var deleteUserById = async (userId) => User_model_default.findByIdAndDelete(userId).exec();
3379
+
3380
+ // src/server/services/check.service.ts
3381
+ var check_service_exports = {};
3382
+ __export(check_service_exports, {
3383
+ accept: () => accept2,
3384
+ remove: () => remove5,
3385
+ update: () => update
3386
+ });
3387
+
3388
+ // src/server/services/snapshot.service.ts
3389
+ var import_fs4 = __toESM(require("fs"));
3390
+ var logOpts3 = {
3391
+ scope: "snapshot_helper",
3392
+ msgType: "API"
3393
+ };
3394
+ var removeSnapshotFile = async (snapshot) => {
3395
+ let relatedSnapshots;
3396
+ if (snapshot.filename) {
3397
+ relatedSnapshots = await Snapshot_model_default.find({ filename: snapshot.filename });
3398
+ logger_default.debug(`there are '${relatedSnapshots.length}' snapshots with filename: '${snapshot.filename}'`, logOpts3);
3399
+ }
3400
+ const isLastSnapshotFile = () => {
3401
+ if (!snapshot.filename) {
3402
+ return true;
3403
+ }
3404
+ return relatedSnapshots.length === 0;
3405
+ };
3406
+ logger_default.debug({ isLastSnapshotFile: isLastSnapshotFile() });
3407
+ if (isLastSnapshotFile()) {
3408
+ const path3 = `${config.defaultImagesPath}${snapshot.filename}`;
3409
+ logger_default.silly(`path: ${path3}`, logOpts3);
3410
+ if (import_fs4.default.existsSync(path3)) {
3411
+ logger_default.debug(`removing file: '${path3}'`, logOpts3, {
3412
+ msgType: "REMOVE",
3413
+ itemType: "file"
3414
+ });
3415
+ import_fs4.default.unlinkSync(path3);
3416
+ }
3417
+ }
3418
+ };
3419
+ var remove4 = async (id2) => {
3420
+ const logOpts4 = {
3421
+ scope: "removeSnapshot",
3422
+ msgType: "REMOVE",
3423
+ itemType: "snapshot",
3424
+ ref: id2
3425
+ };
3426
+ logger_default.silly(`deleting snapshot with id: '${id2}'`, logOpts4);
3427
+ if (!id2) {
3428
+ logger_default.warn("id is empty");
3429
+ return;
3430
+ }
3431
+ const snapshot = await Snapshot_model_default.findById(id2).lean().exec();
3432
+ if (!snapshot) {
3433
+ logger_default.warn(`cannot find snapshot with id: '${id2}'`);
3434
+ return;
3435
+ }
3436
+ const baseline = await Baseline_model_default.findOne({ snapshootId: id2 });
3437
+ if (baseline) {
3438
+ logger_default.debug(`snapshot: '${id2}' is related to a baseline, skipping deletion`, logOpts4);
3439
+ return;
3440
+ }
3441
+ logger_default.debug(`snapshot: '${id2}' is not related to a baseline, attempting to remove it`, logOpts4);
3442
+ await Snapshot_model_default.findByIdAndDelete(id2);
3443
+ logger_default.debug(`snapshot: '${id2}' was removed`, logOpts4);
3444
+ const path3 = `${config.defaultImagesPath}${snapshot.filename}`;
3445
+ logger_default.debug(`attempting to remove snapshot file, id: '${snapshot._id}', filename: '${path3}'`, logOpts4);
3446
+ await removeSnapshotFile(snapshot);
3447
+ };
3448
+
3449
+ // src/server/services/check.service.ts
3450
+ async function calculateTestStatus(testId) {
3451
+ const checksInTest = await Check_model_default.find({ test: testId });
3452
+ const statuses = checksInTest.map((x) => x.status[0]);
3453
+ let testCalculatedStatus = "Failed";
3454
+ if (statuses.every((x) => x === "new" || x === "passed")) {
3455
+ testCalculatedStatus = "Passed";
3456
+ }
3457
+ if (statuses.every((x) => x === "new")) {
3458
+ testCalculatedStatus = "New";
3459
+ }
3460
+ return testCalculatedStatus;
3461
+ }
3462
+ var validateBaselineParam = (params) => {
3463
+ const mandatoryParams = ["markedAs", "markedById", "markedByUsername", "markedDate"];
3464
+ for (const param of mandatoryParams) {
3465
+ if (!params[param]) {
3466
+ const errMsg2 = `invalid baseline parameters, '${param}' is empty, params: ${JSON.stringify(params)}`;
3467
+ logger_default.error(errMsg2);
3468
+ throw new Error(errMsg2);
3469
+ }
3470
+ }
3471
+ };
3472
+ async function createNewBaseline(params) {
3473
+ const logOpts4 = {
3474
+ scope: "createNewBaseline",
3475
+ msgType: "CREATE"
3476
+ };
3477
+ validateBaselineParam(params);
3478
+ const identFields = buildIdentObject(params);
3479
+ const lastBaseline = await Baseline_model_default.findOne(identFields).exec();
3480
+ const sameBaseline = await Baseline_model_default.findOne({ ...identFields, snapshootId: params.actualSnapshotId }).exec();
3481
+ const baselineParams = lastBaseline?.ignoreRegions ? { ...identFields, ignoreRegions: lastBaseline.ignoreRegions } : identFields;
3482
+ if (sameBaseline) {
3483
+ logger_default.debug(`the baseline with same ident and snapshot id: ${params.actualSnapshotId} already exist`, logOpts4);
3484
+ } else {
3485
+ logger_default.debug(`the baseline with same ident and snapshot id: ${params.actualSnapshotId} does not exist,
3486
+ create new one, baselineParams: ${JSON.stringify(baselineParams)}`, logOpts4);
3487
+ }
3488
+ logger_default.silly({ sameBaseline });
3489
+ const resultedBaseline = sameBaseline || await Baseline_model_default.create(baselineParams);
3490
+ resultedBaseline.markedAs = params.markedAs;
3491
+ resultedBaseline.markedById = params.markedById;
3492
+ resultedBaseline.markedByUsername = params.markedByUsername;
3493
+ resultedBaseline.lastMarkedDate = params.markedDate;
3494
+ resultedBaseline.createdDate = /* @__PURE__ */ new Date();
3495
+ resultedBaseline.snapshootId = params.actualSnapshotId;
3496
+ return resultedBaseline.save();
3497
+ }
3498
+ var accept2 = async (id2, baselineId, user) => {
3499
+ const logOpts4 = {
3500
+ msgType: "ACCEPT",
3501
+ itemType: "check",
3502
+ ref: id2,
3503
+ user: user?.username,
3504
+ scope: "accept"
3505
+ };
3506
+ logger_default.debug(`accept check: ${id2}`, logOpts4);
3507
+ const check = await Check_model_default.findById(id2).exec();
3508
+ if (!check) throw new Error(`cannot find check with id: ${id2}`);
3509
+ const test = await Test_model_default.findById(check.test).exec();
3510
+ if (!test) throw new Error(`cannot find test with id: ${check.test}`);
3511
+ check.markedById = user._id;
3512
+ check.markedByUsername = user.username;
3513
+ check.markedDate = /* @__PURE__ */ new Date();
3514
+ check.markedAs = "accepted";
3515
+ check.status = check.status[0] === "new" ? ["new"] : ["passed"];
3516
+ check.updatedDate = /* @__PURE__ */ new Date();
3517
+ logger_default.debug(`update check with options: '${JSON.stringify(check.toObject())}'`, logOpts4);
3518
+ await createNewBaseline(check.toObject());
3519
+ await check.save();
3520
+ const testCalculatedStatus = await calculateTestStatus(String(check.test));
3521
+ const testCalculatedAcceptedStatus = await calculateAcceptedStatus(check.test);
3522
+ test.status = testCalculatedStatus;
3523
+ test.markedAs = testCalculatedAcceptedStatus;
3524
+ test.updatedDate = /* @__PURE__ */ new Date();
3525
+ await Suite_model_default.findByIdAndUpdate(check.suite, { updatedDate: Date.now() });
3526
+ logger_default.debug(`update test with status: '${testCalculatedStatus}', marked: '${testCalculatedAcceptedStatus}'`, logOpts4, {
3527
+ msgType: "UPDATE",
3528
+ itemType: "test",
3529
+ ref: test._id
3530
+ });
3531
+ await test.save();
3532
+ await check.save();
3533
+ logger_default.debug(`check with id: '${id2}' was updated`, logOpts4);
3534
+ return check;
3535
+ };
3536
+ async function removeCheck(id2, user) {
3537
+ const logMeta = {
3538
+ scope: "removeCheck",
3539
+ itemType: "check",
3540
+ ref: id2,
3541
+ msgType: "REMOVE",
3542
+ user: user?.username
3543
+ };
3544
+ try {
3545
+ const check = await Check_model_default.findByIdAndDelete(id2).exec();
3546
+ if (!check) throw new Error(`cannot find check with id: ${id2}`);
3547
+ logger_default.debug(`check with id: '${id2}' was removed, update test: ${check.test}`, logMeta);
3548
+ const test = await Test_model_default.findById(check.test).exec();
3549
+ if (!test) throw new Error(`cannot find test with id: ${check.test}`);
3550
+ const testCalculatedStatus = await calculateTestStatus(String(check.test));
3551
+ const testCalculatedAcceptedStatus = await calculateAcceptedStatus(check.test);
3552
+ test.status = testCalculatedStatus;
3553
+ test.markedAs = testCalculatedAcceptedStatus;
3554
+ test.updatedDate = /* @__PURE__ */ new Date();
3555
+ await updateItemDate("VRSSuite", check.suite);
3556
+ await test.save();
3557
+ if (check.baselineId && String(check.baselineId) !== "undefined") {
3558
+ logger_default.debug(`try to remove the snapshot, baseline: ${check.baselineId}`, logMeta);
3559
+ await remove4(check.baselineId.toString());
3560
+ }
3561
+ if (check.actualSnapshotId && String(check.baselineId) !== "undefined") {
3562
+ logger_default.debug(`try to remove the snapshot, actual: ${check.actualSnapshotId}`, logMeta);
3563
+ await remove4(check.actualSnapshotId.toString());
3564
+ }
3565
+ if (check.diffId && String(check.baselineId) !== "undefined") {
3566
+ logger_default.debug(`try to remove snapshot, diff: ${check.diffId}`, logMeta);
3567
+ await remove4(check.diffId.toString());
3568
+ }
3569
+ return check;
3570
+ } catch (e) {
3571
+ const errMsg2 = `cannot remove a check with id: '${id2}', error: '${e instanceof Error ? e.stack : String(e)}'`;
3572
+ logger_default.error(errMsg2, logMeta);
3573
+ throw new Error(errMsg2);
3574
+ }
3575
+ }
3576
+ var remove5 = async (id2, user) => {
3577
+ const logOpts4 = {
3578
+ scope: "removeCheck",
3579
+ itemType: "check",
3580
+ ref: id2,
3581
+ user: user?.username,
3582
+ msgType: "REMOVE"
3583
+ };
3584
+ logger_default.info(`remove check with, id: '${id2}', user: '${user.username}'`, logOpts4);
3585
+ return removeCheck(id2, user);
3586
+ };
3587
+ var update = async (id2, opts, user) => {
3588
+ const logMeta = {
3589
+ msgType: "UPDATE",
3590
+ itemType: "check",
3591
+ ref: id2,
3592
+ user,
3593
+ scope: "updateCheck"
3594
+ };
3595
+ logger_default.debug(`update check with id '${id2}' with params '${JSON.stringify(opts, null, 2)}'`, logMeta);
3596
+ const check = await Check_model_default.findOneAndUpdate({ _id: id2 }, opts, { new: true }).exec();
3597
+ if (!check) throw new Error(`cannot find check with id: ${id2}`);
3598
+ const test = await Test_model_default.findOne({ _id: check.test }).exec();
3599
+ if (!test) throw new Error(`cannot find test with id: ${check.test}`);
3600
+ test.status = await calculateTestStatus(String(check.test));
3601
+ await updateItemDate("VRSCheck", check);
3602
+ await updateItemDate("VRSTest", test);
3603
+ await test.save();
3604
+ await check.save();
3605
+ return check;
3606
+ };
3607
+
3608
+ // src/server/controllers/baseline.controller.ts
3609
+ var get3 = catchAsync_default(async (req, res) => {
3610
+ const filter = typeof req.query.filter === "string" ? deserializeIfJSON_default(req.query.filter) : {};
3611
+ const options = pick_default(req.query, ["sortBy", "limit", "page", "populate"]);
3612
+ const result = await generic_service_exports.get("VRSBaseline", filter, options);
3613
+ res.send(result);
3614
+ });
3615
+ var put2 = catchAsync_default(async (req, res) => {
3616
+ const { id: id2 } = req.params;
3617
+ if (!id2) throw new ApiError_default(import_http_status6.default.BAD_REQUEST, "Cannot update the baseline - Id not found");
3618
+ const result = await generic_service_exports.put("VRSBaseline", id2, req.body, req?.user);
3619
+ res.send(result);
3620
+ });
3621
+
3622
+ // src/server/controllers/check.controller.ts
3623
+ var check_controller_exports = {};
3624
+ __export(check_controller_exports, {
3625
+ accept: () => accept3,
3626
+ get: () => get4,
3627
+ getViaPost: () => getViaPost,
3628
+ remove: () => remove6,
3629
+ update: () => update2
3630
+ });
3631
+ var import_http_status7 = __toESM(require("http-status"));
3632
+ var get4 = catchAsync_default(async (req, res) => {
3633
+ const filter = typeof req.query.filter === "string" ? deserializeIfJSON_default(req.query.filter) : {};
3634
+ if (req.user?.role === "user") {
3635
+ filter.creatorUsername = req.user?.username;
3636
+ }
3637
+ const options = pick_default(req.query, ["sortBy", "limit", "page", "populate"]);
3638
+ const result = await generic_service_exports.get("VRSCheck", filter, options);
3639
+ res.send(result);
3640
+ });
3641
+ var getViaPost = catchAsync_default(async (req, res) => {
3642
+ const filter = req.body.filter ? pick_default(req.body, ["filter"]).filter : {};
3643
+ const options = req.body.options ? pick_default(req.body, ["options"]).options : {};
3644
+ const result = await generic_service_exports.get("VRSCheck", filter, options);
3645
+ res.send(result);
3646
+ });
3647
+ var update2 = catchAsync_default(async (req, res) => {
3648
+ const { id: id2 } = req.params;
3649
+ if (!id2) throw new ApiError_default(import_http_status7.default.BAD_REQUEST, "Cannot accept the check - Id not found");
3650
+ const opts = removeEmptyProperties(req.body);
3651
+ const user = req?.user?.username;
3652
+ const result = await check_service_exports.update(id2, opts, user);
3653
+ res.send(result);
3654
+ });
3655
+ var accept3 = catchAsync_default(async (req, res) => {
3656
+ const { id: id2 } = req.params;
3657
+ if (!id2) throw new ApiError_default(import_http_status7.default.BAD_REQUEST, "Cannot accept the check - Id not found");
3658
+ if (!req.body.baselineId) throw new ApiError_default(import_http_status7.default.BAD_REQUEST, `Cannot accept the check: ${id2} - new Baseline Id not found`);
3659
+ const result = await check_service_exports.accept(id2, req.body.baselineId, req?.user);
3660
+ res.send(result);
3661
+ });
3662
+ var remove6 = catchAsync_default(async (req, res) => {
3663
+ const { id: id2 } = req.params;
3664
+ if (!id2) throw new ApiError_default(import_http_status7.default.BAD_REQUEST, "Cannot remove the check - Id not found");
3665
+ const result = await check_service_exports.remove(id2, req?.user);
3666
+ res.send(result);
3667
+ });
3668
+
3669
+ // src/server/controllers/client.controller.ts
3670
+ var client_controller_exports = {};
3671
+ __export(client_controller_exports, {
3672
+ createCheck: () => createCheck2,
3673
+ endSession: () => endSession2,
3674
+ getBaselines: () => getBaselines2,
3675
+ getIdent: () => getIdent2,
3676
+ getSnapshots: () => getSnapshots,
3677
+ startSession: () => startSession2
3678
+ });
3679
+ var import_http_status8 = __toESM(require("http-status"));
3680
+
3681
+ // src/server/schemas/CreateCheck.shema.ts
3682
+ var import_zod = require("zod");
3683
+ var createCheckParamsSchema = import_zod.z.object({
3684
+ branch: import_zod.z.string().min(1),
3685
+ appName: import_zod.z.string().min(1),
3686
+ suitename: import_zod.z.string().min(1),
3687
+ testid: import_zod.z.string().regex(/^[a-f0-9]{24}$/),
3688
+ // Regex for 24 hex characters
3689
+ name: import_zod.z.string().min(1),
3690
+ viewport: import_zod.z.string().regex(/^\d+x\d+$/),
3691
+ // "WidthxHeight" format
3692
+ browserName: import_zod.z.string().min(1),
3693
+ browserVersion: import_zod.z.string().min(1),
3694
+ browserFullVersion: import_zod.z.string(),
3695
+ os: import_zod.z.string().min(1),
3696
+ hashcode: import_zod.z.string().length(128)
3697
+ // Assuming hashcode is always 128 chars length
3698
+ });
3699
+
3700
+ // src/server/schemas/GetBaseline.shema.ts
3701
+ var import_zod2 = require("zod");
3702
+ var RequiredIdentOptionsSchema = import_zod2.z.object({
3703
+ name: import_zod2.z.string().min(1),
3704
+ viewport: import_zod2.z.string().min(3),
3705
+ browserName: import_zod2.z.string().min(1),
3706
+ os: import_zod2.z.string().min(1),
3707
+ app: import_zod2.z.string().min(1),
3708
+ branch: import_zod2.z.string().min(1)
3709
+ });
3710
+ var IdentJSONStringSchema = import_zod2.z.string().optional().refine((data) => {
3711
+ if (!data) return false;
3712
+ try {
3713
+ const parsed = JSON.parse(data);
3714
+ RequiredIdentOptionsSchema.parse(parsed);
3715
+ return true;
3716
+ } catch (e) {
3717
+ return false;
3718
+ }
3719
+ }, {
3720
+ message: "Invalid JSON string or does not match the required schema"
3721
+ }).openapi({
3722
+ description: "baseline filter based on ident",
3723
+ example: '{"name": "Login page", "viewport": "1366x768", "browserName": "chrome", "os": "macOS", "app": "My App", "branch": "master"}'
3724
+ });
3725
+
3726
+ // src/server/schemas/App.schema.ts
3727
+ var import_zod_to_openapi2 = require("@asteasolutions/zod-to-openapi");
3728
+
3729
+ // src/server/schemas/utils/commonValidations.ts
3730
+ var import_zod4 = require("zod");
3731
+ var import_zod_to_openapi = require("@asteasolutions/zod-to-openapi");
3732
+
3733
+ // src/server/schemas/common/Version.schema.ts
3734
+ var import_zod3 = require("zod");
3735
+ var VersionSchema = import_zod3.z.string().regex(/^\d+\.\d+\.\d+$/, 'Version must be in the format "x.y.z"').transform((value) => {
3736
+ const parts = value.split(".");
3737
+ return {
3738
+ major: parseInt(parts[0]),
3739
+ minor: parseInt(parts[1]),
3740
+ patch: parseInt(parts[2])
3741
+ };
3742
+ });
3743
+ var Version_schema_default = VersionSchema;
3744
+
3745
+ // src/server/schemas/utils/commonValidations.ts
3746
+ (0, import_zod_to_openapi.extendZodWithOpenApi)(import_zod4.z);
3747
+ var mongooseIdRegex = /^[0-9a-fA-F]{24}$/;
3748
+ var id = import_zod4.z.string().regex(mongooseIdRegex, {
3749
+ message: "Invalid Mongoose ObjectId format: /^[0-9a-fA-F]{24}$/"
3750
+ }).openapi({
3751
+ description: "baseline ID",
3752
+ example: "6bbF35cAB3C59dA969edAe79"
3753
+ });
3754
+ var commonValidations = {
3755
+ id,
3756
+ version: Version_schema_default.openapi({ example: "1.1.2" }),
3757
+ positiveNumberString: import_zod4.z.string().refine((value) => {
3758
+ const num2 = Number(value);
3759
+ return Number.isInteger(num2) && num2 >= 0;
3760
+ }, {
3761
+ message: "String must be a positive number or 0"
3762
+ }),
3763
+ password: import_zod4.z.string().min(6).regex(/(?=.*[0-9])/, "Password must include a number").regex(/(?=.*[a-z])/, "Password must include a lowercase letter").regex(/(?=.*[A-Z])/, "Password must include an uppercase letter").refine((value) => {
3764
+ return /(?=.*[!@#$%^&*(),.?":{}|<>-])/.test(value);
3765
+ }, {
3766
+ message: "Password must include a special symbol"
3767
+ }).openapi({ example: "Aa1!IJASSNOJ" }),
3768
+ username: import_zod4.z.string().min(1).openapi({ example: "john.doe@example.com" }),
3769
+ // TODO: workaround TBD
3770
+ date: import_zod4.z.string().refine((val) => {
3771
+ const date = new Date(val);
3772
+ return !isNaN(date.getTime());
3773
+ }, {
3774
+ message: "Invalid date format"
3775
+ }),
3776
+ paramsId: { params: import_zod4.z.object({ id }) },
3777
+ paramsTestId: { params: import_zod4.z.object({ testid: id }) },
3778
+ success: import_zod4.z.object({
3779
+ message: import_zod4.z.literal("success")
3780
+ })
3781
+ };
3782
+
3783
+ // src/server/schemas/App.schema.ts
3784
+ var import_zod5 = require("zod");
3785
+ (0, import_zod_to_openapi2.extendZodWithOpenApi)(import_zod5.z);
3786
+ var registry = new import_zod_to_openapi2.OpenAPIRegistry();
3787
+ var AppInfoRespSchema = import_zod5.z.object({
3788
+ version: commonValidations.version
3789
+ });
3790
+ var AppRespSchema = import_zod5.z.object({
3791
+ _id: commonValidations.id,
3792
+ id: commonValidations.id,
3793
+ name: import_zod5.z.string().min(1, "AppRespSchema: the name is empty").openapi({ example: "Admin Panel" })
3794
+ });
3795
+
3796
+ // src/server/controllers/client.controller.ts
3797
+ var startSession2 = catchAsync_default(async (req, res) => {
3798
+ const params = pick_default(
3799
+ req.body,
3800
+ [
3801
+ "name",
3802
+ "status",
3803
+ "app",
3804
+ "tags",
3805
+ "branch",
3806
+ "viewport",
3807
+ "browser",
3808
+ "browserVersion",
3809
+ "browserFullVersion",
3810
+ "os",
3811
+ "run",
3812
+ "runident",
3813
+ "suite"
3814
+ ]
3815
+ );
3816
+ const result = await client_service_exports.startSession(params, String(req?.user?.username));
3817
+ res.send(result);
3818
+ });
3819
+ var endSession2 = catchAsync_default(async (req, res) => {
3820
+ const testId = req.params.testid;
3821
+ if (!testId || testId === "undefined") {
3822
+ throw new ApiError_default(import_http_status8.default.BAD_REQUEST, "Cannot stop test Session testId is empty");
3823
+ }
3824
+ const result = await client_service_exports.endSession(testId, String(req?.user?.username));
3825
+ res.send(result);
3826
+ });
3827
+ var createCheck2 = catchAsync_default(async (req, res) => {
3828
+ const params = req.body;
3829
+ paramsGuard(params, "createCheck, params", createCheckParamsSchema);
3830
+ const apiKey = req.headers.apikey;
3831
+ const currentUser = await User_model_default.findOne({ apiKey });
3832
+ if (!currentUser) throw new ApiError_default(import_http_status8.default.NOT_FOUND, `cannot get current user by API`);
3833
+ const logOpts4 = {
3834
+ scope: "createCheck",
3835
+ user: currentUser.username,
3836
+ itemType: "check",
3837
+ msgType: "CREATE"
3838
+ };
3839
+ logger_default.info(`start to create check: '${params.name}'`, logOpts4);
3840
+ logger_default.debug(`try to find test with id: '${params.testid}'`, logOpts4);
3841
+ const test = await Test_model_default.findById(params.testid);
3842
+ if (!test) {
3843
+ const errMsg2 = `can't find test with id: '${params.testid}', parameters: '${JSON.stringify(req.body)}', username: '${currentUser.username}', apiKey: ${apiKey}`;
3844
+ throw new ApiError_default(import_http_status8.default.NOT_FOUND, errMsg2);
3845
+ }
3846
+ const app = await App_model_default.findOne({ name: params.appName });
3847
+ if (!app) throw new ApiError_default(import_http_status8.default.NOT_FOUND, `cannot get the app: ${params.appName}`);
3848
+ const suite = await Suite_model_default.findOne({ name: params.suitename });
3849
+ if (!suite) throw new ApiError_default(import_http_status8.default.NOT_FOUND, `cannot get the suite: ${params.suitename}`);
3850
+ await updateItem("VRSTest", { _id: test.id }, {
3851
+ suite: suite.id,
3852
+ creatorId: currentUser._id,
3853
+ creatorUsername: currentUser.username
3854
+ });
3855
+ const result = await client_service_exports.createCheck(
3856
+ {
3857
+ branch: params.branch,
3858
+ hashCode: params.hashcode,
3859
+ // testId: params.testid,
3860
+ name: params.name,
3861
+ viewport: params.viewport,
3862
+ browserName: params.browserName,
3863
+ browserVersion: params.browserVersion,
3864
+ browserFullVersion: params.browserFullVersion,
3865
+ os: params.os,
3866
+ files: req.files,
3867
+ domDump: params.domdump,
3868
+ vShifting: params.vShifting
3869
+ },
3870
+ test,
3871
+ suite,
3872
+ app,
3873
+ currentUser
3874
+ );
3875
+ if (result.status === "needFiles") {
3876
+ res.status(206).json({
3877
+ status: "requiredFileData",
3878
+ message: "could not find a snapshot with such a hash code, please add image file data and resend request",
3879
+ hashCode: params.hashcode
3880
+ });
3881
+ return;
3882
+ }
3883
+ res.json(result);
3884
+ });
3885
+ var getIdent2 = catchAsync_default(async (req, res) => {
3886
+ const result = client_service_exports.getIdent();
3887
+ res.send(result);
3888
+ });
3889
+ var getBaselines2 = catchAsync_default(async (req, res) => {
3890
+ const filter = pick_default(
3891
+ req.query.filter ? deserializeIfJSON_default(String(req.query.filter)) : {},
3892
+ ["name", "viewport", "browserName", "os", "app", "branch"]
3893
+ );
3894
+ paramsGuard(filter, "getBaseline, filter", RequiredIdentOptionsSchema);
3895
+ const options = pick_default(req.query, ["sortBy", "limit", "page", "populate"]);
3896
+ const result = await client_service_exports.getBaselines(filter, options);
3897
+ res.send(result);
3898
+ });
3899
+ var getSnapshots = catchAsync_default(async (req, res) => {
3900
+ const filter = pick_default(
3901
+ req.query.filter ? deserializeIfJSON_default(String(req.query.filter)) : {},
3902
+ ["_id", "name", "imghash", "createdDate", "filename", "id"]
3903
+ );
3904
+ const options = pick_default(req.query, ["sortBy", "limit", "page", "populate"]);
3905
+ const result = await generic_service_exports.get("VRSSnapshot", filter, options);
3906
+ res.send(result);
3907
+ });
3908
+
3909
+ // src/server/controllers/logs.controller.ts
3910
+ var logs_controller_exports = {};
3911
+ __export(logs_controller_exports, {
3912
+ createLog: () => createLog,
3913
+ distinct: () => distinct2,
3914
+ getLogs: () => getLogs
3915
+ });
3916
+ var import_http_status9 = __toESM(require("http-status"));
3917
+ var import_bson3 = require("bson");
3918
+ var getLogs = catchAsync_default(async (req, res) => {
3919
+ const filter = typeof req.query.filter === "string" ? import_bson3.EJSON.parse(req.query.filter) : {};
3920
+ const options = pick_default(req.query, ["sortBy", "limit", "page"]);
3921
+ const result = await logs_service_exports.queryLogs(filter, options);
3922
+ res.send(result);
3923
+ });
3924
+ var distinct2 = catchAsync_default(async (req, res) => {
3925
+ const { field } = pick_default(req.query, ["field"]);
3926
+ const result = await logs_service_exports.distinct(String(field));
3927
+ res.send(result);
3928
+ });
3929
+ var createLog = catchAsync_default(async (req, res) => {
3930
+ const user = await logs_service_exports.createLogs(req.body);
3931
+ res.status(import_http_status9.default.CREATED).send(user);
3932
+ });
3933
+
3934
+ // src/server/controllers/snapshots.controller.ts
3935
+ var snapshots_controller_exports = {};
3936
+ __export(snapshots_controller_exports, {
3937
+ get: () => get5
3938
+ });
3939
+ var import_bson4 = require("bson");
3940
+ var get5 = catchAsync_default(async (req, res) => {
3941
+ const filter = typeof req.query.filter === "string" ? import_bson4.EJSON.parse(req.query.filter) : {};
3942
+ const options = pick_default(req.query, ["sortBy", "limit", "page"]);
3943
+ const result = await generic_service_exports.get("VRSSnapshot", filter, options);
3944
+ res.send(result);
3945
+ });
3946
+
3947
+ // src/server/controllers/tasks.controller.ts
3948
+ var tasks_controller_exports = {};
3949
+ __export(tasks_controller_exports, {
3950
+ loadTestUser: () => loadTestUser2,
3951
+ screenshots: () => screenshots2,
3952
+ status: () => status2,
3953
+ task_handle_database_consistency: () => task_handle_database_consistency2,
3954
+ task_handle_old_checks: () => task_handle_old_checks2,
3955
+ task_remove_old_logs: () => task_remove_old_logs2,
3956
+ task_test: () => task_test2
3957
+ });
3958
+ var task_test2 = catchAsync_default(async (req, res) => {
3959
+ const { options } = pick_default(req.query, ["options"]);
3960
+ await tasks_service_exports.task_test(String(options), req, res);
3961
+ });
3962
+ var task_handle_old_checks2 = catchAsync_default(async (req, res) => {
3963
+ const options = pick_default(req.query, ["days", "remove"]);
3964
+ await tasks_service_exports.task_handle_old_checks(options, res);
3965
+ });
3966
+ var task_handle_database_consistency2 = catchAsync_default(async (req, res) => {
3967
+ const options = pick_default(req.query, ["days", "clean"]);
3968
+ await tasks_service_exports.task_handle_database_consistency(options, res);
3969
+ });
3970
+ var task_remove_old_logs2 = catchAsync_default(async (req, res) => {
3971
+ const options = pick_default(req.query, ["days", "statistics"]);
3972
+ await tasks_service_exports.task_remove_old_logs(options, res);
3973
+ });
3974
+ var status2 = catchAsync_default(async (req, res) => {
3975
+ res.send(await tasks_service_exports.status(req.user));
3976
+ });
3977
+ var screenshots2 = catchAsync_default(async (req, res) => {
3978
+ res.send(await tasks_service_exports.screenshots());
3979
+ });
3980
+ var loadTestUser2 = catchAsync_default(async (req, res) => {
3981
+ res.send(await tasks_service_exports.loadTestUser());
3982
+ });
3983
+
3984
+ // src/server/controllers/test.controller.ts
3985
+ var test_controller_exports = {};
3986
+ __export(test_controller_exports, {
3987
+ accept: () => accept4,
3988
+ distinct: () => distinct3,
3989
+ distinct_with_filter: () => distinct_with_filter,
3990
+ getTest: () => getTest,
3991
+ remove: () => remove7
3992
+ });
3993
+ var import_http_status10 = __toESM(require("http-status"));
3994
+ var getTest = catchAsync_default(async (req, res) => {
3995
+ const filter = {
3996
+ ...deserializeIfJSON_default(String(req.query.base_filter)),
3997
+ ...deserializeIfJSON_default(String(req.query.filter))
3998
+ };
3999
+ if (req.user?.role === "user") {
4000
+ filter.creatorUsername = req.user?.username;
4001
+ }
4002
+ const options = pick_default(req.query, ["sortBy", "limit", "page", "populate"]);
4003
+ const result = await test_service_exports.queryTests(filter, options);
4004
+ res.status(import_http_status10.default.OK).send(result);
4005
+ });
4006
+ var distinct_with_filter = catchAsync_default(async (req, res) => {
4007
+ const filter = req.query.filter ? deserializeIfJSON_default(String(req.query.filter)) : void 0;
4008
+ const options = { ...pick_default(req.query, ["sortBy", "limit", "page", "populate"]), field: req.params.field };
4009
+ const result = await test_service_exports.queryTestsDistinct(filter, options);
4010
+ res.status(import_http_status10.default.OK).send(result);
4011
+ });
4012
+ var distinct3 = catchAsync_default(async (req, res) => {
4013
+ const filter = {};
4014
+ const options = { ...pick_default(req.query, ["sortBy", "limit", "page", "populate"]), field: req.params.id };
4015
+ const result = await test_service_exports.queryTestsDistinct(filter, options);
4016
+ res.status(import_http_status10.default.OK).send(result);
4017
+ });
4018
+ var remove7 = catchAsync_default(async (req, res) => {
4019
+ const { id: id2 } = req.params;
4020
+ if (!id2) throw new ApiError_default(import_http_status10.default.BAD_REQUEST, "Cannot remove the test - Id not found");
4021
+ if (!req.user) throw new ApiError_default(import_http_status10.default.BAD_REQUEST, "Cannot remove the test - req.user is empty");
4022
+ const result = await test_service_exports.remove(id2, req?.user);
4023
+ res.send(result);
4024
+ });
4025
+ var accept4 = catchAsync_default(async (req, res) => {
4026
+ const { id: id2 } = req.params;
4027
+ if (!id2) throw new ApiError_default(import_http_status10.default.BAD_REQUEST, "Cannot accept the check - Id not found");
4028
+ if (!req.user) throw new ApiError_default(import_http_status10.default.BAD_REQUEST, "Cannot accept the check - req.user is empty");
4029
+ const result = await test_service_exports.accept(id2, req?.user);
4030
+ res.send(result);
4031
+ });
4032
+
4033
+ // src/server/controllers/users.controller.ts
4034
+ var users_controller_exports = {};
4035
+ __export(users_controller_exports, {
4036
+ create: () => create,
4037
+ current: () => current,
4038
+ get: () => get6,
4039
+ getById: () => getById,
4040
+ remove: () => remove8,
4041
+ update: () => update3
4042
+ });
4043
+ var import_http_status11 = __toESM(require("http-status"));
4044
+ var import_bson5 = require("bson");
4045
+ var current = catchAsync_default(async (req, res) => {
4046
+ const logOpts4 = {
4047
+ scope: "users",
4048
+ msgType: "GET_CURRENT_USER"
4049
+ };
4050
+ logger_default.debug(`current user is: '${req?.user?.username || "not_logged"}'`, logOpts4);
4051
+ res.status(import_http_status11.default.OK).json({
4052
+ id: req?.user?.id,
4053
+ username: req?.user?.username,
4054
+ firstName: req?.user?.firstName,
4055
+ lastName: req?.user?.lastName,
4056
+ role: req?.user?.role
4057
+ });
4058
+ });
4059
+ var get6 = catchAsync_default(async (req, res) => {
4060
+ const filter = typeof req.query.filter === "string" ? import_bson5.EJSON.parse(req.query.filter) : {};
4061
+ const options = pick_default(req.query, ["sortBy", "limit", "page"]);
4062
+ const result = await user_service_exports.queryUsers(filter, options);
4063
+ res.send(result);
4064
+ });
4065
+ var getById = catchAsync_default(async (req, res) => {
4066
+ const user = await user_service_exports.getUserById(req.params.userId);
4067
+ res.send(user);
4068
+ });
4069
+ var create = catchAsync_default(async (req, res) => {
4070
+ const logOpts4 = {
4071
+ scope: "users",
4072
+ msgType: "CREATE"
4073
+ };
4074
+ try {
4075
+ const userData = pick_default(req.body, [
4076
+ "username",
4077
+ "firstName",
4078
+ "lastName",
4079
+ "role",
4080
+ "password",
4081
+ "apiKey",
4082
+ "expiration",
4083
+ "meta"
4084
+ ]);
4085
+ const user = await user_service_exports.createUser(userData);
4086
+ res.status(import_http_status11.default.CREATED).send(user);
4087
+ } catch (e) {
4088
+ if (e instanceof ApiError_default && e.statusCode) {
4089
+ logger_default.error(e, logOpts4);
4090
+ res.status(e.statusCode).json({ message: e.message });
4091
+ } else {
4092
+ logger_default.error(errMsg(e), logOpts4);
4093
+ throw e;
4094
+ }
4095
+ }
4096
+ });
4097
+ var update3 = catchAsync_default(async (req, res) => {
4098
+ const user = await user_service_exports.updateUserById(req.params.userId, req.body);
4099
+ res.send(user);
4100
+ });
4101
+ var remove8 = catchAsync_default(async (req, res) => {
4102
+ await user_service_exports.deleteUserById(req.params.userId);
4103
+ res.status(import_http_status11.default.NO_CONTENT).send();
4104
+ });
4105
+
4106
+ // src/server/controllers/app.controller.ts
4107
+ var app_controller_exports = {};
4108
+ __export(app_controller_exports, {
4109
+ get: () => get7,
4110
+ info: () => info
4111
+ });
4112
+ var import_http_status12 = __toESM(require("http-status"));
4113
+ var info = catchAsync_default(async (req, res) => {
4114
+ res.status(import_http_status12.default.OK).json({ version: config.version });
4115
+ });
4116
+ var get7 = catchAsync_default(async (req, res) => {
4117
+ const filter = typeof req.query.filter === "string" ? deserializeIfJSON_default(req.query.filter) : {};
4118
+ const options = pick_default(req.query, ["sortBy", "limit", "page"]);
4119
+ const result = await app_service_exports.get(filter, options);
4120
+ res.send(result);
4121
+ });
4122
+
4123
+ // src/server/controllers/settings.controller.ts
4124
+ var settings_controller_exports = {};
4125
+ __export(settings_controller_exports, {
4126
+ getSettings: () => getSettings,
4127
+ updateSetting: () => updateSetting
4128
+ });
4129
+
4130
+ // src/seeds/initialAppSettings.json
4131
+ var initialAppSettings_default = [
4132
+ {
4133
+ name: "first_run",
4134
+ label: "First Run",
4135
+ description: "Indicates if the application is running the first time",
4136
+ type: "Boolean",
4137
+ value: "true",
4138
+ enabled: true
4139
+ },
4140
+ {
4141
+ name: "authentication",
4142
+ label: "Authentication",
4143
+ description: "Enable application authentication",
4144
+ type: "Boolean",
4145
+ value: "false",
4146
+ enabled: true
4147
+ }
4148
+ ];
4149
+
4150
+ // src/server/lib/AppSettings/AppSettings.ts
4151
+ var AppSettings2 = class {
4152
+ constructor() {
4153
+ this.model = AppSettings_model_default;
4154
+ this.cache = null;
4155
+ }
4156
+ async init() {
4157
+ this.cache = await this.model.find().lean().exec();
4158
+ return this;
4159
+ }
4160
+ ensureInitialized() {
4161
+ if (!this.cache) {
4162
+ throw new Error("AppSettings is not initialized. Please call init() before using this method.");
4163
+ }
4164
+ }
4165
+ async count() {
4166
+ this.ensureInitialized();
4167
+ return this.model.countDocuments().exec();
4168
+ }
4169
+ async loadInitialFromFile() {
4170
+ this.ensureInitialized();
4171
+ const settings = initialAppSettings_default;
4172
+ await this.model.insertMany(settings);
4173
+ this.cache = settings;
4174
+ }
4175
+ async get(name) {
4176
+ this.ensureInitialized();
4177
+ return this.cache.find((x) => x.name === name) || this.model.findOne({ name }).exec();
4178
+ }
4179
+ async set(name, value) {
4180
+ this.ensureInitialized();
4181
+ const item = await this.model.findOneAndUpdate({ name }, { value });
4182
+ await item.save();
4183
+ const cachedItem = this.cache.find((x) => x.name === name);
4184
+ if (cachedItem) {
4185
+ cachedItem["value"] = value;
4186
+ }
4187
+ }
4188
+ async enable(name) {
4189
+ this.ensureInitialized();
4190
+ const item = await this.model.findOneAndUpdate({ name }, { enabled: true });
4191
+ await item.save();
4192
+ const cachedItem = this.cache.find((x) => x.name === name);
4193
+ if (cachedItem) {
4194
+ cachedItem["enabled"] = true;
4195
+ }
4196
+ }
4197
+ async disable(name) {
4198
+ this.ensureInitialized();
4199
+ const item = await this.model.findOneAndUpdate({ name }, { enabled: false });
4200
+ await item.save();
4201
+ const cachedItem = this.cache.find((x) => x.name === name);
4202
+ if (cachedItem) {
4203
+ cachedItem["enabled"] = false;
4204
+ }
4205
+ }
4206
+ async isAuthEnabled() {
4207
+ this.ensureInitialized();
4208
+ return env.SYNGRISI_AUTH || (await this.get("authentication"))?.value === "true";
4209
+ }
4210
+ async isFirstRun() {
4211
+ this.ensureInitialized();
4212
+ return (await this.get("first_run"))?.value === "true";
4213
+ }
4214
+ };
4215
+ var appSettings = new AppSettings2().init();
4216
+
4217
+ // src/server/controllers/settings.controller.ts
4218
+ var getSettings = catchAsync_default(async (req, res) => {
4219
+ const AppSettings3 = await appSettings;
4220
+ const result = AppSettings3.cache;
4221
+ res.json(result);
4222
+ });
4223
+ var updateSetting = catchAsync_default(async (req, res) => {
4224
+ const AppSettings3 = await appSettings;
4225
+ const { name } = req.params;
4226
+ await AppSettings3.set(name, req.body.value);
4227
+ if (req.body.enabled === false) {
4228
+ await AppSettings3.disable(name);
4229
+ } else {
4230
+ await AppSettings3.enable(name);
4231
+ }
4232
+ res.json({ message: "success" });
4233
+ });
4234
+
4235
+ // src/server/controllers/runs.controller.ts
4236
+ var runs_controller_exports = {};
4237
+ __export(runs_controller_exports, {
4238
+ get: () => get8,
4239
+ remove: () => remove9
4240
+ });
4241
+ var import_bson6 = require("bson");
4242
+ var get8 = catchAsync_default(async (req, res) => {
4243
+ const filter = typeof req.query.filter === "string" ? import_bson6.EJSON.parse(req.query.filter) : {};
4244
+ const options = pick_default(req.query, ["sortBy", "limit", "page"]);
4245
+ const result = await generic_service_exports.get("VRSRun", filter, options);
4246
+ res.send(result);
4247
+ });
4248
+ var remove9 = catchAsync_default(async (req, res) => {
4249
+ const { id: id2 } = req.params;
4250
+ if (!req.user) throw new Error("req.user is empty");
4251
+ const result = await run_service_exports.remove(id2, req?.user);
4252
+ res.send(result);
4253
+ });
4254
+
4255
+ // src/server/controllers/suite.controller.ts
4256
+ var suite_controller_exports = {};
4257
+ __export(suite_controller_exports, {
4258
+ get: () => get9,
4259
+ remove: () => remove10
4260
+ });
4261
+ var import_bson7 = require("bson");
4262
+ var get9 = catchAsync_default(async (req, res) => {
4263
+ const filter = typeof req.query.filter === "string" ? import_bson7.EJSON.parse(req.query.filter) : {};
4264
+ const options = pick_default(req.query, ["sortBy", "limit", "page"]);
4265
+ const result = await generic_service_exports.get("VRSSuite", filter, options);
4266
+ res.send(result);
4267
+ });
4268
+ var remove10 = catchAsync_default(async (req, res) => {
4269
+ const { id: id2 } = req.params;
4270
+ if (!req.user) throw new Error("req.user is empty");
4271
+ const result = await suite_service_exports.remove(id2, req?.user);
4272
+ res.send(result);
4273
+ });
4274
+ // Annotate the CommonJS export names for ESM import in node:
4275
+ 0 && (module.exports = {
4276
+ appController,
4277
+ baselineController,
4278
+ checkController,
4279
+ clientController,
4280
+ logsController,
4281
+ runsController,
4282
+ settingsController,
4283
+ snapshotsController,
4284
+ suiteController,
4285
+ tasksController,
4286
+ testController,
4287
+ usersController
4288
+ });
4289
+ //# sourceMappingURL=index.js.map