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