@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,2648 @@
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/services/client.service.ts
31
+ var client_service_exports = {};
32
+ __export(client_service_exports, {
33
+ createCheck: () => createCheck,
34
+ endSession: () => endSession,
35
+ getBaselines: () => getBaselines,
36
+ getIdent: () => getIdent,
37
+ startSession: () => startSession
38
+ });
39
+ module.exports = __toCommonJS(client_service_exports);
40
+ var import_fs2 = __toESM(require("fs"));
41
+ var import_hasha = __toESM(require("hasha"));
42
+
43
+ // src/server/models/Check.model.ts
44
+ var import_mongoose = __toESM(require("mongoose"));
45
+
46
+ // src/server/models/plugins/paginate.plugin.ts
47
+ var paginate = (schema) => {
48
+ schema.statics.paginate = async function(filter, options) {
49
+ let sort;
50
+ if (options.sortBy) {
51
+ const sortingCriteria = [];
52
+ options.sortBy.split(",").forEach((sortOption) => {
53
+ const [key, order] = sortOption.split(":");
54
+ sortingCriteria.push((order === "desc" ? "-" : "") + key);
55
+ });
56
+ sort = sortingCriteria.join(" ");
57
+ } else {
58
+ sort = { _id: -1 };
59
+ }
60
+ const limit = options.limit && parseInt(options.limit.toString(), 10) >= 0 ? parseInt(options.limit.toString(), 10) : 10;
61
+ const page = options.page && parseInt(options.page.toString(), 10) > 0 ? parseInt(options.page.toString(), 10) : 1;
62
+ const skip = (page - 1) * limit;
63
+ const countPromise = this.countDocuments(filter).exec();
64
+ let docsPromise = this.find(filter).sort(sort).skip(skip).limit(limit);
65
+ if (options.populate) {
66
+ options.populate.split(",").forEach((populateOption) => {
67
+ docsPromise = docsPromise.populate(
68
+ populateOption.split(".").reverse().reduce((a, b) => ({ path: b, populate: a }))
69
+ );
70
+ });
71
+ }
72
+ docsPromise = docsPromise.exec();
73
+ return Promise.all([countPromise, docsPromise]).then((values) => {
74
+ const [totalResults, results] = values;
75
+ const totalPages = Math.ceil(totalResults / limit);
76
+ const result = {
77
+ results,
78
+ page,
79
+ limit,
80
+ totalPages,
81
+ totalResults,
82
+ timestamp: Number(Date.now() + String(process.hrtime()[1]).slice(3, 6))
83
+ };
84
+ return Promise.resolve(result);
85
+ });
86
+ };
87
+ };
88
+ var paginate_plugin_default = paginate;
89
+
90
+ // src/server/models/plugins/toJSON.plugin.ts
91
+ var deleteAtPath = (obj, path3, index) => {
92
+ if (index === path3.length - 1) {
93
+ delete obj[path3[index]];
94
+ return;
95
+ }
96
+ deleteAtPath(obj[path3[index]], path3, index + 1);
97
+ };
98
+ var toJSON = (schema) => {
99
+ let transform;
100
+ if (schema.options.toJSON && schema.options.toJSON.transform) {
101
+ transform = schema.options.toJSON.transform;
102
+ }
103
+ schema.options.toJSON = Object.assign(schema.options.toJSON || {}, {
104
+ transform(doc, ret, options) {
105
+ Object.keys(schema.paths).forEach((path3) => {
106
+ if (schema.paths[path3].options && schema.paths[path3].options.private) {
107
+ deleteAtPath(ret, path3.split("."), 0);
108
+ }
109
+ });
110
+ ret.id = ret._id.toString();
111
+ delete ret.__v;
112
+ delete ret.createdAt;
113
+ delete ret.updatedAt;
114
+ if (transform) {
115
+ return transform(doc, ret, options);
116
+ }
117
+ }
118
+ });
119
+ };
120
+ var toJSON_plugin_default = toJSON;
121
+
122
+ // src/server/models/plugins/paginateDistinct.plugin.ts
123
+ var import_bson = require("bson");
124
+ var paginateDistinct = (schema) => {
125
+ schema.statics.paginateDistinct = async function(filter, options) {
126
+ let sort;
127
+ if (options.sortBy) {
128
+ options.sortBy.split(",").forEach((sortOption) => {
129
+ const [key, order] = sortOption.split(":");
130
+ sort[key] = order === "desc" ? -1 : 1;
131
+ });
132
+ } else {
133
+ sort = { _id: -1 };
134
+ }
135
+ let limit = options.limit && parseInt(options.limit.toString(), 10) >= 0 ? parseInt(options.limit.toString(), 10) : 10;
136
+ limit = limit === 0 ? 9007199254740991 : limit;
137
+ const page = options.page && parseInt(options.page.toString(), 10) > 0 ? parseInt(options.page.toString(), 10) : 1;
138
+ const skip = (page - 1) * limit;
139
+ const groupAggregateObj = { $group: { _id: `$${options.field}` } };
140
+ const documentsCount = (await this.aggregate([groupAggregateObj]).exec()).length;
141
+ const aggregateArr = [
142
+ { $match: import_bson.EJSON.parse(filter.filter || "{}") },
143
+ groupAggregateObj,
144
+ { $sort: sort },
145
+ { $skip: skip },
146
+ { $limit: limit }
147
+ ];
148
+ const aggregatedDocs = (await this.aggregate(aggregateArr)).filter((x) => x._id).map((x) => {
149
+ if (x[options.field]) {
150
+ return x[options.field][0];
151
+ }
152
+ return { name: x._id };
153
+ });
154
+ return Promise.all([documentsCount, aggregatedDocs]).then((values) => {
155
+ const [totalResults, results] = values;
156
+ const totalPages = Math.ceil(totalResults / limit);
157
+ const result = {
158
+ results,
159
+ page,
160
+ limit,
161
+ totalPages,
162
+ totalResults,
163
+ timestamp: (/* @__PURE__ */ new Date()).getTime()
164
+ };
165
+ return Promise.resolve(result);
166
+ });
167
+ };
168
+ };
169
+ var paginateDistinct_plugin_default = paginateDistinct;
170
+
171
+ // src/server/models/Check.model.ts
172
+ var CheckSchema = new import_mongoose.Schema({
173
+ name: {
174
+ type: String,
175
+ required: [true, 'CheckSchema: The "name" field must be required']
176
+ },
177
+ test: {
178
+ type: import_mongoose.Schema.Types.ObjectId,
179
+ ref: "VRSTest",
180
+ required: [true, 'CheckSchema: The "test" field must be required']
181
+ },
182
+ suite: {
183
+ type: import_mongoose.Schema.Types.ObjectId,
184
+ ref: "VRSSuite",
185
+ required: [true, 'CheckSchema: The "suite" field must be required']
186
+ },
187
+ app: {
188
+ type: import_mongoose.Schema.Types.ObjectId,
189
+ ref: "VRSApp",
190
+ required: [true, 'CheckSchema: The "app" field must be required']
191
+ },
192
+ branch: {
193
+ type: String
194
+ },
195
+ realBaselineId: {
196
+ type: import_mongoose.Schema.Types.ObjectId,
197
+ ref: "VRSBaseline"
198
+ },
199
+ baselineId: {
200
+ type: import_mongoose.Schema.Types.ObjectId,
201
+ ref: "VRSSnapshot"
202
+ },
203
+ actualSnapshotId: {
204
+ type: import_mongoose.Schema.Types.ObjectId,
205
+ ref: "VRSSnapshot"
206
+ },
207
+ diffId: {
208
+ type: import_mongoose.Schema.Types.ObjectId,
209
+ ref: "VRSSnapshot"
210
+ },
211
+ createdDate: {
212
+ type: Date,
213
+ required: true,
214
+ default: Date.now
215
+ },
216
+ updatedDate: {
217
+ type: Date
218
+ },
219
+ status: {
220
+ type: [{
221
+ type: String,
222
+ enum: {
223
+ values: ["new", "pending", "approved", "running", "passed", "failed", "aborted"],
224
+ message: "status is required"
225
+ }
226
+ }],
227
+ default: ["new"]
228
+ },
229
+ browserName: {
230
+ type: String
231
+ },
232
+ browserVersion: {
233
+ type: String
234
+ },
235
+ browserFullVersion: {
236
+ type: String
237
+ },
238
+ viewport: {
239
+ type: String
240
+ },
241
+ os: {
242
+ type: String
243
+ },
244
+ domDump: {
245
+ type: String
246
+ },
247
+ result: {
248
+ type: String,
249
+ default: "{}"
250
+ },
251
+ run: {
252
+ type: import_mongoose.Schema.Types.ObjectId
253
+ },
254
+ markedAs: {
255
+ type: String,
256
+ enum: ["bug", "accepted"]
257
+ },
258
+ markedDate: {
259
+ type: Date
260
+ },
261
+ markedById: {
262
+ type: import_mongoose.Schema.Types.ObjectId,
263
+ ref: "VRSUser"
264
+ },
265
+ markedByUsername: {
266
+ type: String
267
+ },
268
+ markedBugComment: {
269
+ type: String
270
+ },
271
+ creatorId: {
272
+ type: import_mongoose.Schema.Types.ObjectId,
273
+ ref: "VRSUser"
274
+ },
275
+ creatorUsername: {
276
+ type: String
277
+ },
278
+ failReasons: {
279
+ type: [String]
280
+ },
281
+ vOffset: {
282
+ type: String
283
+ },
284
+ topStablePixels: {
285
+ type: String
286
+ },
287
+ meta: {
288
+ type: Object
289
+ }
290
+ });
291
+ CheckSchema.plugin(toJSON_plugin_default);
292
+ CheckSchema.plugin(paginate_plugin_default);
293
+ var Check = import_mongoose.default.model("VRSCheck", CheckSchema);
294
+ var Check_model_default = Check;
295
+
296
+ // src/server/models/Log.model.ts
297
+ var import_mongoose2 = __toESM(require("mongoose"));
298
+ var LogSchema = new import_mongoose2.Schema({
299
+ timestamp: {
300
+ type: Date
301
+ },
302
+ level: {
303
+ type: String
304
+ },
305
+ message: {
306
+ type: String
307
+ },
308
+ meta: {
309
+ type: Object
310
+ },
311
+ hostname: {
312
+ type: Object
313
+ }
314
+ });
315
+ LogSchema.plugin(toJSON_plugin_default);
316
+ LogSchema.plugin(paginate_plugin_default);
317
+ var Log = import_mongoose2.default.model("VRSLog", LogSchema);
318
+
319
+ // src/server/models/App.model.ts
320
+ var import_mongoose3 = __toESM(require("mongoose"));
321
+ var AppSchema = new import_mongoose3.Schema({
322
+ name: {
323
+ type: String,
324
+ default: "Others",
325
+ unique: true,
326
+ required: [true, 'AppSchema: The "name" field must be required']
327
+ },
328
+ description: {
329
+ type: String
330
+ },
331
+ version: {
332
+ type: String
333
+ },
334
+ updatedDate: {
335
+ type: Date
336
+ },
337
+ createdDate: {
338
+ type: Date
339
+ },
340
+ meta: {
341
+ type: Object
342
+ }
343
+ });
344
+ AppSchema.plugin(paginate_plugin_default);
345
+ AppSchema.plugin(toJSON_plugin_default);
346
+ var App = import_mongoose3.default.model("VRSApp", AppSchema);
347
+ var App_model_default = App;
348
+
349
+ // src/server/models/Snapshot.model.ts
350
+ var import_mongoose4 = __toESM(require("mongoose"));
351
+ var SnapshotSchema = new import_mongoose4.Schema({
352
+ name: {
353
+ type: String,
354
+ required: [true, 'SnapshotSchema: The "name" field must be required']
355
+ },
356
+ path: {
357
+ type: String
358
+ },
359
+ filename: {
360
+ type: String
361
+ },
362
+ imghash: {
363
+ type: String,
364
+ required: [true, 'SnapshotSchema: The "imghash" field must be required']
365
+ },
366
+ createdDate: {
367
+ type: Date,
368
+ default: Date.now
369
+ },
370
+ vOffset: {
371
+ type: Number
372
+ },
373
+ hOffset: {
374
+ type: Number
375
+ }
376
+ });
377
+ SnapshotSchema.plugin(toJSON_plugin_default);
378
+ SnapshotSchema.plugin(paginate_plugin_default);
379
+ var Snapshot = import_mongoose4.default.model("VRSSnapshot", SnapshotSchema);
380
+ var Snapshot_model_default = Snapshot;
381
+
382
+ // src/server/models/AppSettings.model.ts
383
+ var import_mongoose5 = __toESM(require("mongoose"));
384
+ var AppSettingsSchema = new import_mongoose5.Schema({
385
+ name: {
386
+ type: String,
387
+ unique: true,
388
+ required: [true, 'AppSettingsSchema: The "name" field must be required']
389
+ },
390
+ label: {
391
+ type: String,
392
+ required: [true, 'AppSettingsSchema: The "label" field must be required']
393
+ },
394
+ description: {
395
+ type: String
396
+ },
397
+ type: {
398
+ type: String,
399
+ required: [true, 'AppSettingsSchema: The "type" field must be required']
400
+ },
401
+ value: {
402
+ type: import_mongoose5.Schema.Types.Mixed,
403
+ required: [true, 'AppSettingsSchema: The "value" field must be required']
404
+ },
405
+ env_variable: {
406
+ type: String
407
+ },
408
+ enabled: {
409
+ type: Boolean
410
+ }
411
+ });
412
+ AppSettingsSchema.plugin(toJSON_plugin_default);
413
+ var AppSettings = import_mongoose5.default.model("VRSAppSettings", AppSettingsSchema);
414
+
415
+ // src/server/models/Suite.model.ts
416
+ var import_mongoose6 = __toESM(require("mongoose"));
417
+ var SuiteSchema = new import_mongoose6.Schema({
418
+ name: {
419
+ type: String,
420
+ default: "Others",
421
+ unique: true,
422
+ required: [true, 'SuiteSchema: The "name" field must be required']
423
+ },
424
+ tags: {
425
+ type: [String]
426
+ },
427
+ app: {
428
+ type: import_mongoose6.Schema.Types.ObjectId,
429
+ ref: "VRSApp",
430
+ required: [true, 'SuiteSchema: The "app" field must be required']
431
+ },
432
+ description: {
433
+ type: String
434
+ },
435
+ updatedDate: {
436
+ type: Date,
437
+ default: Date.now
438
+ },
439
+ createdDate: {
440
+ type: Date
441
+ },
442
+ meta: {
443
+ type: Object
444
+ }
445
+ });
446
+ SuiteSchema.plugin(paginate_plugin_default);
447
+ SuiteSchema.plugin(toJSON_plugin_default);
448
+ var Suite = import_mongoose6.default.model("VRSSuite", SuiteSchema);
449
+ var Suite_model_default = Suite;
450
+
451
+ // src/server/models/Run.model.ts
452
+ var import_mongoose7 = __toESM(require("mongoose"));
453
+ var RunSchema = new import_mongoose7.Schema({
454
+ name: {
455
+ type: String,
456
+ required: [true, 'RunSchema: The "name" field must be required']
457
+ },
458
+ app: {
459
+ type: import_mongoose7.Schema.Types.ObjectId,
460
+ ref: "VRSApp",
461
+ required: [true, 'RunSchema: The "app" field must be required']
462
+ },
463
+ ident: {
464
+ type: String,
465
+ unique: true,
466
+ required: [true, 'RunSchema: The "ident" field must be required']
467
+ },
468
+ description: {
469
+ type: String
470
+ },
471
+ updatedDate: {
472
+ type: Date,
473
+ default: Date.now
474
+ },
475
+ createdDate: {
476
+ type: Date
477
+ },
478
+ parameters: {
479
+ type: [String]
480
+ },
481
+ meta: {
482
+ type: Object
483
+ }
484
+ });
485
+ RunSchema.plugin(paginate_plugin_default);
486
+ RunSchema.plugin(toJSON_plugin_default);
487
+ var Run = import_mongoose7.default.model("VRSRun", RunSchema);
488
+ var Run_model_default = Run;
489
+
490
+ // src/server/models/User.model.ts
491
+ var import_mongoose8 = __toESM(require("mongoose"));
492
+ var import_passport_local_mongoose = __toESM(require("passport-local-mongoose"));
493
+ var UserSchema = new import_mongoose8.Schema({
494
+ username: {
495
+ type: String,
496
+ unique: true,
497
+ required: [true, 'UserSchema: The "username" field must be required']
498
+ },
499
+ firstName: {
500
+ type: String,
501
+ required: [true, 'UserSchema: The "firstName" field must be required']
502
+ },
503
+ lastName: {
504
+ type: String,
505
+ required: [true, 'UserSchema: The "lastName" field must be required']
506
+ },
507
+ role: {
508
+ type: String,
509
+ enum: ["admin", "reviewer", "user"],
510
+ required: [true, 'UserSchema: The "role" field must be required']
511
+ },
512
+ password: {
513
+ type: String
514
+ },
515
+ token: {
516
+ type: String
517
+ },
518
+ apiKey: {
519
+ type: String
520
+ },
521
+ createdDate: {
522
+ type: Date
523
+ },
524
+ updatedDate: {
525
+ type: Date
526
+ },
527
+ expiration: {
528
+ type: Date
529
+ },
530
+ meta: {
531
+ type: Object
532
+ }
533
+ });
534
+ UserSchema.statics.isEmailTaken = async function(username, excludeUserId) {
535
+ const user = await this.findOne({ username, _id: { $ne: excludeUserId } });
536
+ return !!user;
537
+ };
538
+ UserSchema.plugin(toJSON_plugin_default);
539
+ UserSchema.plugin(paginate_plugin_default);
540
+ UserSchema.plugin(import_passport_local_mongoose.default, { hashField: "password" });
541
+ var User = import_mongoose8.default.model("VRSUser", UserSchema);
542
+
543
+ // src/server/models/Baseline.model.ts
544
+ var import_mongoose9 = __toESM(require("mongoose"));
545
+ var BaselineSchema = new import_mongoose9.Schema({
546
+ snapshootId: {
547
+ type: import_mongoose9.Schema.Types.ObjectId
548
+ },
549
+ name: {
550
+ type: String,
551
+ required: [true, 'VRSBaselineSchema: The "name" field must be required']
552
+ },
553
+ app: {
554
+ type: import_mongoose9.Schema.Types.ObjectId,
555
+ ref: "VRSApp",
556
+ required: [true, 'VRSBaselineSchema: The "app" field must be required']
557
+ },
558
+ branch: {
559
+ type: String
560
+ },
561
+ browserName: {
562
+ type: String
563
+ },
564
+ browserVersion: {
565
+ type: String
566
+ },
567
+ browserFullVersion: {
568
+ type: String
569
+ },
570
+ viewport: {
571
+ type: String
572
+ },
573
+ os: {
574
+ type: String
575
+ },
576
+ markedAs: {
577
+ type: String,
578
+ enum: ["bug", "accepted"]
579
+ },
580
+ lastMarkedDate: {
581
+ type: Date
582
+ },
583
+ createdDate: {
584
+ type: Date
585
+ },
586
+ updatedDate: {
587
+ type: Date
588
+ },
589
+ markedById: {
590
+ type: import_mongoose9.Schema.Types.ObjectId,
591
+ ref: "VRSUser"
592
+ },
593
+ markedByUsername: {
594
+ type: String
595
+ },
596
+ ignoreRegions: {
597
+ type: String
598
+ },
599
+ boundRegions: {
600
+ type: String
601
+ },
602
+ matchType: {
603
+ type: String,
604
+ enum: ["antialiasing", "nothing", "colors"]
605
+ },
606
+ meta: {
607
+ type: Object
608
+ }
609
+ });
610
+ BaselineSchema.plugin(toJSON_plugin_default);
611
+ BaselineSchema.plugin(paginate_plugin_default);
612
+ var Baseline = import_mongoose9.default.model("VRSBaseline", BaselineSchema);
613
+ var Baseline_model_default = Baseline;
614
+
615
+ // src/server/models/Test.model.ts
616
+ var import_mongoose10 = __toESM(require("mongoose"));
617
+ var TestSchema = new import_mongoose10.Schema(
618
+ {
619
+ name: {
620
+ type: String,
621
+ required: "TestSchema: the test name is empty"
622
+ },
623
+ description: {
624
+ type: String
625
+ },
626
+ status: {
627
+ type: String
628
+ },
629
+ browserName: {
630
+ type: String
631
+ },
632
+ browserVersion: {
633
+ type: String
634
+ },
635
+ branch: {
636
+ type: String
637
+ },
638
+ tags: {
639
+ type: [String]
640
+ },
641
+ viewport: {
642
+ type: String
643
+ },
644
+ calculatedViewport: {
645
+ type: String
646
+ },
647
+ os: {
648
+ type: String
649
+ },
650
+ app: {
651
+ type: import_mongoose10.Schema.Types.ObjectId,
652
+ ref: "VRSApp",
653
+ required: [true, 'TestSchema: The "app" field must be required']
654
+ },
655
+ blinking: {
656
+ type: Number,
657
+ default: 0
658
+ },
659
+ updatedDate: {
660
+ type: Date
661
+ },
662
+ startDate: {
663
+ type: Date
664
+ },
665
+ checks: [
666
+ {
667
+ type: import_mongoose10.default.Schema.Types.ObjectId,
668
+ ref: "VRSCheck"
669
+ }
670
+ ],
671
+ suite: {
672
+ type: import_mongoose10.Schema.Types.ObjectId,
673
+ ref: "VRSSuite"
674
+ },
675
+ run: {
676
+ type: import_mongoose10.Schema.Types.ObjectId,
677
+ ref: "VRSRun"
678
+ },
679
+ markedAs: {
680
+ type: String,
681
+ enum: ["Bug", "Accepted", "Unaccepted", "Partially"]
682
+ },
683
+ creatorId: {
684
+ type: import_mongoose10.Schema.Types.ObjectId,
685
+ ref: "VRSUser"
686
+ },
687
+ creatorUsername: {
688
+ type: String
689
+ },
690
+ meta: {
691
+ type: Object
692
+ }
693
+ },
694
+ { strictQuery: true }
695
+ );
696
+ TestSchema.plugin(toJSON_plugin_default);
697
+ TestSchema.plugin(paginate_plugin_default);
698
+ TestSchema.plugin(paginateDistinct_plugin_default);
699
+ var Test = import_mongoose10.default.model("VRSTest", TestSchema);
700
+ var Test_model_default = Test;
701
+
702
+ // src/server/utils/ApiError.ts
703
+ var ApiError = class extends Error {
704
+ constructor(statusCode, message, isOperational = true, stack = "") {
705
+ super(message);
706
+ this.statusCode = statusCode;
707
+ this.isOperational = isOperational;
708
+ if (stack) {
709
+ this.stack = stack;
710
+ } else {
711
+ Error.captureStackTrace(this, this.constructor);
712
+ }
713
+ }
714
+ };
715
+ var ApiError_default = ApiError;
716
+
717
+ // src/server/utils/removeEmptyProperties.ts
718
+ var removeEmptyProperties = (obj) => Object.fromEntries(
719
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
720
+ Object.entries(obj).filter(([_, v]) => v != null && v !== "")
721
+ );
722
+
723
+ // src/server/utils/deserializeIfJSON.ts
724
+ var import_bson2 = require("bson");
725
+
726
+ // src/server/utils/prettyCheckParams.ts
727
+ var prettyCheckParams = (result) => {
728
+ if (!result.domDump) {
729
+ return JSON.stringify(result);
730
+ }
731
+ const dump = JSON.parse(result.domDump);
732
+ const resObs = { ...result };
733
+ delete resObs.domDump;
734
+ resObs.domDump = `${JSON.stringify(dump).substr(0, 20)}... and about ${dump.length} items]`;
735
+ return JSON.stringify(resObs);
736
+ };
737
+ var prettyCheckParams_default = prettyCheckParams;
738
+
739
+ // src/server/utils/waitUntil.ts
740
+ var waitUntil = async (cb, attempts = 5, interval = 700) => {
741
+ let result = false;
742
+ let iteration = 0;
743
+ while (result === false) {
744
+ result = await cb();
745
+ await new Promise((r) => setTimeout(r, interval));
746
+ iteration += 1;
747
+ if (iteration > attempts) {
748
+ result = true;
749
+ }
750
+ }
751
+ return result;
752
+ };
753
+
754
+ // src/server/utils/ident.ts
755
+ var ident = ["name", "viewport", "browserName", "os", "app", "branch"];
756
+
757
+ // src/server/utils/buildIdentObject.ts
758
+ var MissingIdentFieldError = class extends Error {
759
+ constructor(field) {
760
+ super(`Missing required ident field: ${field}`);
761
+ this.name = "MissingIdentFieldError";
762
+ }
763
+ };
764
+ var buildIdentObject = (params) => {
765
+ const result = {};
766
+ for (const key of ident) {
767
+ if (key in params && params[key] !== void 0) {
768
+ result[key] = params[key];
769
+ } else {
770
+ throw new MissingIdentFieldError(key);
771
+ }
772
+ }
773
+ return result;
774
+ };
775
+
776
+ // src/server/utils/calculateAcceptedStatus.ts
777
+ var calculateAcceptedStatus = async function calculateAcceptedStatus2(testId) {
778
+ const checksInTest = await Check_model_default.find({ test: testId });
779
+ const statuses = checksInTest.map((x) => x.markedAs);
780
+ if (statuses.length < 1) {
781
+ return "Unaccepted";
782
+ }
783
+ let testCalculatedStatus = "Unaccepted";
784
+ if (statuses.some((x) => x === "accepted")) {
785
+ testCalculatedStatus = "Partially";
786
+ }
787
+ if (statuses.every((x) => x === "accepted")) {
788
+ testCalculatedStatus = "Accepted";
789
+ }
790
+ return testCalculatedStatus;
791
+ };
792
+
793
+ // src/server/utils/errMsg.ts
794
+ var errMsg = (e) => {
795
+ return String(e instanceof Error ? e.stack : e);
796
+ };
797
+
798
+ // src/server/lib/dbItems/updateItem.ts
799
+ var import_mongoose11 = __toESM(require("mongoose"));
800
+
801
+ // src/server/lib/logger.ts
802
+ var import_winston = __toESM(require("winston"));
803
+ var import_winston_mongodb = require("winston-mongodb");
804
+ var import_chalk = require("chalk");
805
+
806
+ // src/server/utils/formatISOToDateTime.ts
807
+ function formatISOToDateTime(isoDateString) {
808
+ const date = new Date(isoDateString);
809
+ return `${date.toISOString().slice(0, 10)} ${date.toTimeString().slice(0, 8)}`;
810
+ }
811
+ var formatISOToDateTime_default = formatISOToDateTime;
812
+
813
+ // src/server/config.ts
814
+ var import_fs = __toESM(require("fs"));
815
+ var import_dotenv2 = __toESM(require("dotenv"));
816
+
817
+ // package.json
818
+ var version = "2.2.3";
819
+
820
+ // src/server/config.ts
821
+ var import_crypto2 = __toESM(require("crypto"));
822
+
823
+ // src/server/envConfig.ts
824
+ var import_envalid = require("envalid");
825
+ var import_crypto = __toESM(require("crypto"));
826
+ var import_path = __toESM(require("path"));
827
+ var import_dotenv = __toESM(require("dotenv"));
828
+ import_dotenv.default.config();
829
+ var env = (0, import_envalid.cleanEnv)(process.env, {
830
+ NODE_ENV: (0, import_envalid.str)({ choices: ["development", "production", "test"] }),
831
+ SYNGRISI_DB_URI: (0, import_envalid.str)({ devDefault: "mongodb://127.0.0.1:27017/SyngrisiDb" }),
832
+ SYNGRISI_APP_PORT: (0, import_envalid.port)({ devDefault: 3e3 }),
833
+ SYNGRISI_IMAGES_PATH: (0, import_envalid.str)({ devDefault: "./.snapshots-images/" }),
834
+ SYNGRISI_TMP_DIR: (0, import_envalid.str)({ default: import_path.default.join(process.cwd(), ".tmp") }),
835
+ SYNGRISI_HTTP_LOG: (0, import_envalid.bool)({ devDefault: false }),
836
+ SYNGRISI_COVERAGE: (0, import_envalid.bool)({ devDefault: false }),
837
+ SYNGRISI_HOSTNAME: (0, import_envalid.host)({ devDefault: "localhost" }),
838
+ SYNGRISI_AUTH: (0, import_envalid.bool)({ default: true }),
839
+ SYNGRISI_TEST_MODE: (0, import_envalid.bool)({ default: false }),
840
+ SYNGRISI_DISABLE_FIRST_RUN: (0, import_envalid.bool)({ default: false }),
841
+ MONGODB_ROOT_USERNAME: (0, import_envalid.str)({ default: "" }),
842
+ MONGODB_ROOT_PASSWORD: (0, import_envalid.str)({ default: "" }),
843
+ LOGLEVEL: (0, import_envalid.str)({ choices: ["error", "warn", "info", "verbose", "debug", "silly"], default: "debug" }),
844
+ SYNGRISI_PAGINATION_SIZE: (0, import_envalid.num)({ default: 50 }),
845
+ SYNGRISI_DISABLE_DEV_CORS: (0, import_envalid.bool)({ default: false, devDefault: true }),
846
+ SYNGRISI_SESSION_STORE_KEY: (0, import_envalid.str)({ default: import_crypto.default.randomBytes(64).toString("hex") }),
847
+ SYNGRISI_LOG_LEVEL: (0, import_envalid.str)({ default: "debug" }),
848
+ // trunk features
849
+ SYNGRISI_TRUNK_FEATURE_AI_SEVERITY: (0, import_envalid.bool)({ default: false }),
850
+ SYNGRISI_AI_KEY: (0, import_envalid.str)({ default: "" }),
851
+ OPENAI_API_BASE_URL: (0, import_envalid.str)({ default: "https://api.openai.com/v1" }),
852
+ OPENAI_API_KEY: (0, import_envalid.str)({ default: "" })
853
+ });
854
+
855
+ // src/server/data/devices.json
856
+ var devices_default = [
857
+ {
858
+ os: "ios",
859
+ os_version: "16",
860
+ device: "iPhone 14 Pro Max",
861
+ realMobile: true
862
+ },
863
+ {
864
+ os: "ios",
865
+ os_version: "16",
866
+ device: "iPhone 14 Pro",
867
+ realMobile: true
868
+ },
869
+ {
870
+ os: "ios",
871
+ os_version: "16",
872
+ device: "iPhone 14 Plus",
873
+ realMobile: true
874
+ },
875
+ {
876
+ os: "ios",
877
+ os_version: "16",
878
+ device: "iPhone 14",
879
+ realMobile: true
880
+ },
881
+ {
882
+ os: "ios",
883
+ os_version: "16",
884
+ device: "iPhone 12 Pro Max",
885
+ realMobile: true
886
+ },
887
+ {
888
+ os: "ios",
889
+ os_version: "16",
890
+ device: "iPhone 12 Pro",
891
+ realMobile: true
892
+ },
893
+ {
894
+ os: "ios",
895
+ os_version: "16",
896
+ device: "iPhone 12 Mini",
897
+ realMobile: true
898
+ },
899
+ {
900
+ os: "ios",
901
+ os_version: "16",
902
+ device: "iPhone 11 Pro Max",
903
+ realMobile: true
904
+ },
905
+ {
906
+ os: "ios",
907
+ os_version: "15",
908
+ device: "iPhone XS",
909
+ realMobile: true
910
+ },
911
+ {
912
+ os: "ios",
913
+ os_version: "15",
914
+ device: "iPhone 13 Pro Max",
915
+ realMobile: true
916
+ },
917
+ {
918
+ os: "ios",
919
+ os_version: "15",
920
+ device: "iPhone 13 Pro",
921
+ realMobile: true
922
+ },
923
+ {
924
+ os: "ios",
925
+ os_version: "15",
926
+ device: "iPhone 13 Mini",
927
+ realMobile: true
928
+ },
929
+ {
930
+ os: "ios",
931
+ os_version: "15",
932
+ device: "iPhone 13",
933
+ realMobile: true
934
+ },
935
+ {
936
+ os: "ios",
937
+ os_version: "15",
938
+ device: "iPhone 11 Pro",
939
+ realMobile: true
940
+ },
941
+ {
942
+ os: "ios",
943
+ os_version: "15",
944
+ device: "iPhone 11",
945
+ realMobile: true
946
+ },
947
+ {
948
+ os: "ios",
949
+ os_version: "14",
950
+ device: "iPhone XS",
951
+ realMobile: true
952
+ },
953
+ {
954
+ os: "ios",
955
+ os_version: "14",
956
+ device: "iPhone 12 Pro Max",
957
+ realMobile: true
958
+ },
959
+ {
960
+ os: "ios",
961
+ os_version: "14",
962
+ device: "iPhone 12 Pro",
963
+ realMobile: true
964
+ },
965
+ {
966
+ os: "ios",
967
+ os_version: "14",
968
+ device: "iPhone 12 Mini",
969
+ realMobile: true
970
+ },
971
+ {
972
+ os: "ios",
973
+ os_version: "14",
974
+ device: "iPhone 12",
975
+ realMobile: true
976
+ },
977
+ {
978
+ os: "ios",
979
+ os_version: "14",
980
+ device: "iPhone 11 Pro Max",
981
+ realMobile: true
982
+ },
983
+ {
984
+ os: "ios",
985
+ os_version: "14",
986
+ device: "iPhone 11",
987
+ realMobile: true
988
+ },
989
+ {
990
+ os: "ios",
991
+ os_version: "13",
992
+ device: "iPhone XS",
993
+ realMobile: true
994
+ },
995
+ {
996
+ os: "ios",
997
+ os_version: "13",
998
+ device: "iPhone 11 Pro Max",
999
+ realMobile: true
1000
+ },
1001
+ {
1002
+ os: "ios",
1003
+ os_version: "13",
1004
+ device: "iPhone 11 Pro",
1005
+ realMobile: true
1006
+ },
1007
+ {
1008
+ os: "ios",
1009
+ os_version: "13",
1010
+ device: "iPhone 11",
1011
+ realMobile: true
1012
+ },
1013
+ {
1014
+ os: "ios",
1015
+ os_version: "12",
1016
+ device: "iPhone XS",
1017
+ realMobile: true
1018
+ },
1019
+ {
1020
+ os: "ios",
1021
+ os_version: "12",
1022
+ device: "iPhone XS Max",
1023
+ realMobile: true
1024
+ },
1025
+ {
1026
+ os: "ios",
1027
+ os_version: "15",
1028
+ device: "iPhone XR",
1029
+ realMobile: true
1030
+ },
1031
+ {
1032
+ os: "ios",
1033
+ os_version: "12",
1034
+ device: "iPhone XR",
1035
+ realMobile: true
1036
+ },
1037
+ {
1038
+ os: "ios",
1039
+ os_version: "11",
1040
+ device: "iPhone X",
1041
+ realMobile: true
1042
+ },
1043
+ {
1044
+ os: "ios",
1045
+ os_version: "15",
1046
+ device: "iPhone 8",
1047
+ realMobile: true
1048
+ },
1049
+ {
1050
+ os: "ios",
1051
+ os_version: "13",
1052
+ device: "iPhone 8",
1053
+ realMobile: true
1054
+ },
1055
+ {
1056
+ os: "ios",
1057
+ os_version: "12",
1058
+ device: "iPhone 8",
1059
+ realMobile: true
1060
+ },
1061
+ {
1062
+ os: "ios",
1063
+ os_version: "11",
1064
+ device: "iPhone 8",
1065
+ realMobile: true
1066
+ },
1067
+ {
1068
+ os: "ios",
1069
+ os_version: "12",
1070
+ device: "iPhone 8 Plus",
1071
+ realMobile: true
1072
+ },
1073
+ {
1074
+ os: "ios",
1075
+ os_version: "11",
1076
+ device: "iPhone 8 Plus",
1077
+ realMobile: true
1078
+ },
1079
+ {
1080
+ os: "ios",
1081
+ os_version: "12",
1082
+ device: "iPhone 7",
1083
+ realMobile: true
1084
+ },
1085
+ {
1086
+ os: "ios",
1087
+ os_version: "10",
1088
+ device: "iPhone 7",
1089
+ realMobile: true
1090
+ },
1091
+ {
1092
+ os: "ios",
1093
+ os_version: "12",
1094
+ device: "iPhone 6S",
1095
+ realMobile: true
1096
+ },
1097
+ {
1098
+ os: "ios",
1099
+ os_version: "11",
1100
+ device: "iPhone 6S",
1101
+ realMobile: true
1102
+ },
1103
+ {
1104
+ os: "ios",
1105
+ os_version: "11",
1106
+ device: "iPhone 6S Plus",
1107
+ realMobile: true
1108
+ },
1109
+ {
1110
+ os: "ios",
1111
+ os_version: "11",
1112
+ device: "iPhone 6",
1113
+ realMobile: true
1114
+ },
1115
+ {
1116
+ os: "ios",
1117
+ os_version: "15",
1118
+ device: "iPhone SE 2022",
1119
+ realMobile: true
1120
+ },
1121
+ {
1122
+ os: "ios",
1123
+ os_version: "13",
1124
+ device: "iPhone SE 2020",
1125
+ realMobile: true
1126
+ },
1127
+ {
1128
+ os: "ios",
1129
+ os_version: "11",
1130
+ device: "iPhone SE",
1131
+ realMobile: true
1132
+ },
1133
+ {
1134
+ os: "ios",
1135
+ os_version: "14",
1136
+ device: "iPad Air 4",
1137
+ realMobile: true
1138
+ },
1139
+ {
1140
+ os: "ios",
1141
+ os_version: "15",
1142
+ device: "iPad 9th",
1143
+ realMobile: true
1144
+ },
1145
+ {
1146
+ os: "ios",
1147
+ os_version: "16",
1148
+ device: "iPad Pro 12.9 2022",
1149
+ realMobile: true
1150
+ },
1151
+ {
1152
+ os: "ios",
1153
+ os_version: "16",
1154
+ device: "iPad Pro 12.9 2020",
1155
+ realMobile: true
1156
+ },
1157
+ {
1158
+ os: "ios",
1159
+ os_version: "16",
1160
+ device: "iPad Pro 11 2022",
1161
+ realMobile: true
1162
+ },
1163
+ {
1164
+ os: "ios",
1165
+ os_version: "16",
1166
+ device: "iPad 10th",
1167
+ realMobile: true
1168
+ },
1169
+ {
1170
+ os: "ios",
1171
+ os_version: "15",
1172
+ device: "iPad Air 5",
1173
+ realMobile: true
1174
+ },
1175
+ {
1176
+ os: "ios",
1177
+ os_version: "14",
1178
+ device: "iPad Pro 12.9 2021",
1179
+ realMobile: true
1180
+ },
1181
+ {
1182
+ os: "ios",
1183
+ os_version: "14",
1184
+ device: "iPad Pro 12.9 2020",
1185
+ realMobile: true
1186
+ },
1187
+ {
1188
+ os: "ios",
1189
+ os_version: "14",
1190
+ device: "iPad Pro 11 2021",
1191
+ realMobile: true
1192
+ },
1193
+ {
1194
+ os: "ios",
1195
+ os_version: "13",
1196
+ device: "iPad Pro 12.9 2020",
1197
+ realMobile: true
1198
+ },
1199
+ {
1200
+ os: "ios",
1201
+ os_version: "16",
1202
+ device: "iPad 8th",
1203
+ realMobile: true
1204
+ },
1205
+ {
1206
+ os: "ios",
1207
+ os_version: "15",
1208
+ device: "iPad Pro 12.9 2018",
1209
+ realMobile: true
1210
+ },
1211
+ {
1212
+ os: "ios",
1213
+ os_version: "15",
1214
+ device: "iPad Mini 2021",
1215
+ realMobile: true
1216
+ },
1217
+ {
1218
+ os: "ios",
1219
+ os_version: "14",
1220
+ device: "iPad 8th",
1221
+ realMobile: true
1222
+ },
1223
+ {
1224
+ os: "ios",
1225
+ os_version: "13",
1226
+ device: "iPad Pro 12.9 2018",
1227
+ realMobile: true
1228
+ },
1229
+ {
1230
+ os: "ios",
1231
+ os_version: "13",
1232
+ device: "iPad Pro 11 2020",
1233
+ realMobile: true
1234
+ },
1235
+ {
1236
+ os: "ios",
1237
+ os_version: "13",
1238
+ device: "iPad Mini 2019",
1239
+ realMobile: true
1240
+ },
1241
+ {
1242
+ os: "ios",
1243
+ os_version: "13",
1244
+ device: "iPad Air 2019",
1245
+ realMobile: true
1246
+ },
1247
+ {
1248
+ os: "ios",
1249
+ os_version: "13",
1250
+ device: "iPad 7th",
1251
+ realMobile: true
1252
+ },
1253
+ {
1254
+ os: "ios",
1255
+ os_version: "12",
1256
+ device: "iPad Pro 12.9 2018",
1257
+ realMobile: true
1258
+ },
1259
+ {
1260
+ os: "ios",
1261
+ os_version: "12",
1262
+ device: "iPad Pro 11 2018",
1263
+ realMobile: true
1264
+ },
1265
+ {
1266
+ os: "ios",
1267
+ os_version: "12",
1268
+ device: "iPad Mini 2019",
1269
+ realMobile: true
1270
+ },
1271
+ {
1272
+ os: "ios",
1273
+ os_version: "12",
1274
+ device: "iPad Air 2019",
1275
+ realMobile: true
1276
+ },
1277
+ {
1278
+ os: "ios",
1279
+ os_version: "11",
1280
+ device: "iPad Pro 9.7 2016",
1281
+ realMobile: true
1282
+ },
1283
+ {
1284
+ os: "ios",
1285
+ os_version: "11",
1286
+ device: "iPad Pro 12.9 2017",
1287
+ realMobile: true
1288
+ },
1289
+ {
1290
+ os: "ios",
1291
+ os_version: "11",
1292
+ device: "iPad Mini 4",
1293
+ realMobile: true
1294
+ },
1295
+ {
1296
+ os: "ios",
1297
+ os_version: "11",
1298
+ device: "iPad 6th",
1299
+ realMobile: true
1300
+ },
1301
+ {
1302
+ os: "ios",
1303
+ os_version: "11",
1304
+ device: "iPad 5th",
1305
+ realMobile: true
1306
+ },
1307
+ {
1308
+ os: "android",
1309
+ os_version: "12.0",
1310
+ device: "Samsung Galaxy S22 Ultra",
1311
+ realMobile: true
1312
+ },
1313
+ {
1314
+ os: "android",
1315
+ os_version: "12.0",
1316
+ device: "Samsung Galaxy S22 Plus",
1317
+ realMobile: true
1318
+ },
1319
+ {
1320
+ os: "android",
1321
+ os_version: "12.0",
1322
+ device: "Samsung Galaxy S22",
1323
+ realMobile: true
1324
+ },
1325
+ {
1326
+ os: "android",
1327
+ os_version: "12.0",
1328
+ device: "Samsung Galaxy S21",
1329
+ realMobile: true
1330
+ },
1331
+ {
1332
+ os: "android",
1333
+ os_version: "11.0",
1334
+ device: "Samsung Galaxy S21 Ultra",
1335
+ realMobile: true
1336
+ },
1337
+ {
1338
+ os: "android",
1339
+ os_version: "11.0",
1340
+ device: "Samsung Galaxy S21",
1341
+ realMobile: true
1342
+ },
1343
+ {
1344
+ os: "android",
1345
+ os_version: "11.0",
1346
+ device: "Samsung Galaxy S21 Plus",
1347
+ realMobile: true
1348
+ },
1349
+ {
1350
+ os: "android",
1351
+ os_version: "10.0",
1352
+ device: "Samsung Galaxy S20",
1353
+ realMobile: true
1354
+ },
1355
+ {
1356
+ os: "android",
1357
+ os_version: "10.0",
1358
+ device: "Samsung Galaxy S20 Plus",
1359
+ realMobile: true
1360
+ },
1361
+ {
1362
+ os: "android",
1363
+ os_version: "10.0",
1364
+ device: "Samsung Galaxy S20 Ultra",
1365
+ realMobile: true
1366
+ },
1367
+ {
1368
+ os: "android",
1369
+ os_version: "11.0",
1370
+ device: "Samsung Galaxy M52",
1371
+ realMobile: true
1372
+ },
1373
+ {
1374
+ os: "android",
1375
+ os_version: "11.0",
1376
+ device: "Samsung Galaxy M32",
1377
+ realMobile: true
1378
+ },
1379
+ {
1380
+ os: "android",
1381
+ os_version: "11.0",
1382
+ device: "Samsung Galaxy A52",
1383
+ realMobile: true
1384
+ },
1385
+ {
1386
+ os: "android",
1387
+ os_version: "10.0",
1388
+ device: "Samsung Galaxy Note 20 Ultra",
1389
+ realMobile: true
1390
+ },
1391
+ {
1392
+ os: "android",
1393
+ os_version: "10.0",
1394
+ device: "Samsung Galaxy Note 20",
1395
+ realMobile: true
1396
+ },
1397
+ {
1398
+ os: "android",
1399
+ os_version: "10.0",
1400
+ device: "Samsung Galaxy A51",
1401
+ realMobile: true
1402
+ },
1403
+ {
1404
+ os: "android",
1405
+ os_version: "10.0",
1406
+ device: "Samsung Galaxy A11",
1407
+ realMobile: true
1408
+ },
1409
+ {
1410
+ os: "android",
1411
+ os_version: "9.0",
1412
+ device: "Samsung Galaxy S9 Plus",
1413
+ realMobile: true
1414
+ },
1415
+ {
1416
+ os: "android",
1417
+ os_version: "9.0",
1418
+ device: "Samsung Galaxy S10e",
1419
+ realMobile: true
1420
+ },
1421
+ {
1422
+ os: "android",
1423
+ os_version: "9.0",
1424
+ device: "Samsung Galaxy S10 Plus",
1425
+ realMobile: true
1426
+ },
1427
+ {
1428
+ os: "android",
1429
+ os_version: "9.0",
1430
+ device: "Samsung Galaxy S10",
1431
+ realMobile: true
1432
+ },
1433
+ {
1434
+ os: "android",
1435
+ os_version: "9.0",
1436
+ device: "Samsung Galaxy Note 10 Plus",
1437
+ realMobile: true
1438
+ },
1439
+ {
1440
+ os: "android",
1441
+ os_version: "9.0",
1442
+ device: "Samsung Galaxy Note 10",
1443
+ realMobile: true
1444
+ },
1445
+ {
1446
+ os: "android",
1447
+ os_version: "9.0",
1448
+ device: "Samsung Galaxy A10",
1449
+ realMobile: true
1450
+ },
1451
+ {
1452
+ os: "android",
1453
+ os_version: "8.1",
1454
+ device: "Samsung Galaxy Note 9",
1455
+ realMobile: true
1456
+ },
1457
+ {
1458
+ os: "android",
1459
+ os_version: "8.1",
1460
+ device: "Samsung Galaxy J7 Prime",
1461
+ realMobile: true
1462
+ },
1463
+ {
1464
+ os: "android",
1465
+ os_version: "8.0",
1466
+ device: "Samsung Galaxy S9 Plus",
1467
+ realMobile: true
1468
+ },
1469
+ {
1470
+ os: "android",
1471
+ os_version: "8.0",
1472
+ device: "Samsung Galaxy S9",
1473
+ realMobile: true
1474
+ },
1475
+ {
1476
+ os: "android",
1477
+ os_version: "7.1",
1478
+ device: "Samsung Galaxy Note 8",
1479
+ realMobile: true
1480
+ },
1481
+ {
1482
+ os: "android",
1483
+ os_version: "7.1",
1484
+ device: "Samsung Galaxy A8",
1485
+ realMobile: true
1486
+ },
1487
+ {
1488
+ os: "android",
1489
+ os_version: "7.0",
1490
+ device: "Samsung Galaxy S8 Plus",
1491
+ realMobile: true
1492
+ },
1493
+ {
1494
+ os: "android",
1495
+ os_version: "7.0",
1496
+ device: "Samsung Galaxy S8",
1497
+ realMobile: true
1498
+ },
1499
+ {
1500
+ os: "android",
1501
+ os_version: "6.0",
1502
+ device: "Samsung Galaxy S7",
1503
+ realMobile: true
1504
+ },
1505
+ {
1506
+ os: "android",
1507
+ os_version: "5.0",
1508
+ device: "Samsung Galaxy S6",
1509
+ realMobile: true
1510
+ },
1511
+ {
1512
+ os: "android",
1513
+ os_version: "13.0",
1514
+ device: "Google Pixel 7 Pro",
1515
+ realMobile: true
1516
+ },
1517
+ {
1518
+ os: "android",
1519
+ os_version: "13.0",
1520
+ device: "Google Pixel 7",
1521
+ realMobile: true
1522
+ },
1523
+ {
1524
+ os: "android",
1525
+ os_version: "13.0",
1526
+ device: "Google Pixel 6 Pro",
1527
+ realMobile: true
1528
+ },
1529
+ {
1530
+ os: "android",
1531
+ os_version: "12.0",
1532
+ device: "Google Pixel 6 Pro",
1533
+ realMobile: true
1534
+ },
1535
+ {
1536
+ os: "android",
1537
+ os_version: "12.0",
1538
+ device: "Google Pixel 6",
1539
+ realMobile: true
1540
+ },
1541
+ {
1542
+ os: "android",
1543
+ os_version: "12.0",
1544
+ device: "Google Pixel 5",
1545
+ realMobile: true
1546
+ },
1547
+ {
1548
+ os: "android",
1549
+ os_version: "11.0",
1550
+ device: "Google Pixel 5",
1551
+ realMobile: true
1552
+ },
1553
+ {
1554
+ os: "android",
1555
+ os_version: "11.0",
1556
+ device: "Google Pixel 4",
1557
+ realMobile: true
1558
+ },
1559
+ {
1560
+ os: "android",
1561
+ os_version: "10.0",
1562
+ device: "Google Pixel 4 XL",
1563
+ realMobile: true
1564
+ },
1565
+ {
1566
+ os: "android",
1567
+ os_version: "10.0",
1568
+ device: "Google Pixel 4",
1569
+ realMobile: true
1570
+ },
1571
+ {
1572
+ os: "android",
1573
+ os_version: "10.0",
1574
+ device: "Google Pixel 3",
1575
+ realMobile: true
1576
+ },
1577
+ {
1578
+ os: "android",
1579
+ os_version: "9.0",
1580
+ device: "Google Pixel 3a XL",
1581
+ realMobile: true
1582
+ },
1583
+ {
1584
+ os: "android",
1585
+ os_version: "9.0",
1586
+ device: "Google Pixel 3a",
1587
+ realMobile: true
1588
+ },
1589
+ {
1590
+ os: "android",
1591
+ os_version: "9.0",
1592
+ device: "Google Pixel 3 XL",
1593
+ realMobile: true
1594
+ },
1595
+ {
1596
+ os: "android",
1597
+ os_version: "9.0",
1598
+ device: "Google Pixel 3",
1599
+ realMobile: true
1600
+ },
1601
+ {
1602
+ os: "android",
1603
+ os_version: "9.0",
1604
+ device: "Google Pixel 2",
1605
+ realMobile: true
1606
+ },
1607
+ {
1608
+ os: "android",
1609
+ os_version: "8.0",
1610
+ device: "Google Pixel 2",
1611
+ realMobile: true
1612
+ },
1613
+ {
1614
+ os: "android",
1615
+ os_version: "7.1",
1616
+ device: "Google Pixel",
1617
+ realMobile: true
1618
+ },
1619
+ {
1620
+ os: "android",
1621
+ os_version: "6.0",
1622
+ device: "Google Nexus 6",
1623
+ realMobile: true
1624
+ },
1625
+ {
1626
+ os: "android",
1627
+ os_version: "4.4",
1628
+ device: "Google Nexus 5",
1629
+ realMobile: true
1630
+ },
1631
+ {
1632
+ os: "android",
1633
+ os_version: "11.0",
1634
+ device: "OnePlus 9",
1635
+ realMobile: true
1636
+ },
1637
+ {
1638
+ os: "android",
1639
+ os_version: "10.0",
1640
+ device: "OnePlus 8",
1641
+ realMobile: true
1642
+ },
1643
+ {
1644
+ os: "android",
1645
+ os_version: "10.0",
1646
+ device: "OnePlus 7T",
1647
+ realMobile: true
1648
+ },
1649
+ {
1650
+ os: "android",
1651
+ os_version: "9.0",
1652
+ device: "OnePlus 7",
1653
+ realMobile: true
1654
+ },
1655
+ {
1656
+ os: "android",
1657
+ os_version: "9.0",
1658
+ device: "OnePlus 6T",
1659
+ realMobile: true
1660
+ },
1661
+ {
1662
+ os: "android",
1663
+ os_version: "11.0",
1664
+ device: "Xiaomi Redmi Note 11",
1665
+ realMobile: true
1666
+ },
1667
+ {
1668
+ os: "android",
1669
+ os_version: "10.0",
1670
+ device: "Xiaomi Redmi Note 9",
1671
+ realMobile: true
1672
+ },
1673
+ {
1674
+ os: "android",
1675
+ os_version: "9.0",
1676
+ device: "Xiaomi Redmi Note 8",
1677
+ realMobile: true
1678
+ },
1679
+ {
1680
+ os: "android",
1681
+ os_version: "9.0",
1682
+ device: "Xiaomi Redmi Note 7",
1683
+ realMobile: true
1684
+ },
1685
+ {
1686
+ os: "android",
1687
+ os_version: "11.0",
1688
+ device: "Vivo Y21",
1689
+ realMobile: true
1690
+ },
1691
+ {
1692
+ os: "android",
1693
+ os_version: "11.0",
1694
+ device: "Vivo V21",
1695
+ realMobile: true
1696
+ },
1697
+ {
1698
+ os: "android",
1699
+ os_version: "10.0",
1700
+ device: "Vivo Y50",
1701
+ realMobile: true
1702
+ },
1703
+ {
1704
+ os: "android",
1705
+ os_version: "11.0",
1706
+ device: "Oppo Reno 6",
1707
+ realMobile: true
1708
+ },
1709
+ {
1710
+ os: "android",
1711
+ os_version: "11.0",
1712
+ device: "Oppo A96",
1713
+ realMobile: true
1714
+ },
1715
+ {
1716
+ os: "android",
1717
+ os_version: "10.0",
1718
+ device: "Oppo Reno 3 Pro",
1719
+ realMobile: true
1720
+ },
1721
+ {
1722
+ os: "android",
1723
+ os_version: "11.0",
1724
+ device: "Motorola Moto G71 5G",
1725
+ realMobile: true
1726
+ },
1727
+ {
1728
+ os: "android",
1729
+ os_version: "10.0",
1730
+ device: "Motorola Moto G9 Play",
1731
+ realMobile: true
1732
+ },
1733
+ {
1734
+ os: "android",
1735
+ os_version: "9.0",
1736
+ device: "Motorola Moto G7 Play",
1737
+ realMobile: true
1738
+ },
1739
+ {
1740
+ os: "android",
1741
+ os_version: "9.0",
1742
+ device: "Huawei P30",
1743
+ realMobile: true
1744
+ },
1745
+ {
1746
+ os: "android",
1747
+ os_version: "12.0",
1748
+ device: "Samsung Galaxy Tab S8",
1749
+ realMobile: true
1750
+ },
1751
+ {
1752
+ os: "android",
1753
+ os_version: "11.0",
1754
+ device: "Samsung Galaxy Tab S7",
1755
+ realMobile: true
1756
+ },
1757
+ {
1758
+ os: "android",
1759
+ os_version: "10.0",
1760
+ device: "Samsung Galaxy Tab S7",
1761
+ realMobile: true
1762
+ },
1763
+ {
1764
+ os: "android",
1765
+ os_version: "9.0",
1766
+ device: "Samsung Galaxy Tab S6",
1767
+ realMobile: true
1768
+ },
1769
+ {
1770
+ os: "android",
1771
+ os_version: "9.0",
1772
+ device: "Samsung Galaxy Tab S5e",
1773
+ realMobile: true
1774
+ },
1775
+ {
1776
+ os: "android",
1777
+ os_version: "8.1",
1778
+ device: "Samsung Galaxy Tab S4",
1779
+ realMobile: true
1780
+ }
1781
+ ];
1782
+
1783
+ // src/server/config.ts
1784
+ var customDevicesPath = "./server/data/custom_devices.json";
1785
+ var logsFolder = "./logs";
1786
+ import_dotenv2.default.config();
1787
+ var config = {
1788
+ version,
1789
+ // this isn't used
1790
+ getDevices: async () => {
1791
+ if (import_fs.default.existsSync(customDevicesPath)) {
1792
+ return [...devices_default, ...(await import(customDevicesPath)).default];
1793
+ }
1794
+ return devices_default;
1795
+ },
1796
+ defaultImagesPath: env.SYNGRISI_IMAGES_PATH,
1797
+ connectionString: env.SYNGRISI_DB_URI || "mongodb://127.0.0.1:27017/SyngrisiDb",
1798
+ host: env.SYNGRISI_HOSTNAME,
1799
+ port: env.SYNGRISI_APP_PORT || 3e3,
1800
+ backupsFolder: "./backups",
1801
+ enableHttpLogger: env.SYNGRISI_HTTP_LOG,
1802
+ httpLoggerFilePath: `${logsFolder}/http.log`,
1803
+ storeSessionKey: env.SYNGRISI_SESSION_STORE_KEY || import_crypto2.default.randomBytes(64).toString("hex"),
1804
+ codeCoverage: env.SYNGRISI_COVERAGE,
1805
+ disableCors: env.SYNGRISI_DISABLE_DEV_CORS,
1806
+ fileUploadMaxSize: 50 * 1024 * 1024,
1807
+ testMode: env.SYNGRISI_TEST_MODE,
1808
+ jsonLimit: "50mb",
1809
+ tmpDir: env.SYNGRISI_TMP_DIR,
1810
+ helmet: {
1811
+ crossOriginEmbedderPolicy: !env.SYNGRISI_DISABLE_DEV_CORS,
1812
+ crossOriginResourcePolicy: !env.SYNGRISI_DISABLE_DEV_CORS,
1813
+ contentSecurityPolicy: {
1814
+ directives: {
1815
+ frameAncestors: ["'self'", "vscode-webview:", "vscode-resource:", "https:", "http:"],
1816
+ frameSrc: ["'self'", "vscode-webview:", "https:", "http:"],
1817
+ scriptSrc: ["'self'", "'unsafe-inline'"],
1818
+ styleSrc: ["'self'", "'unsafe-inline'"]
1819
+ }
1820
+ }
1821
+ }
1822
+ };
1823
+ if (!import_fs.default.existsSync(config.defaultImagesPath)) {
1824
+ import_fs.default.mkdirSync(config.defaultImagesPath, { recursive: true });
1825
+ }
1826
+ if (!import_fs.default.existsSync(logsFolder)) {
1827
+ import_fs.default.mkdirSync(logsFolder, { recursive: true });
1828
+ }
1829
+
1830
+ // src/server/lib/logger.ts
1831
+ var import_path2 = __toESM(require("path"));
1832
+ var logLevel = env.SYNGRISI_LOG_LEVEL;
1833
+ function getScriptLine() {
1834
+ const stack = new Error().stack;
1835
+ if (stack) {
1836
+ const stackLines = stack.split("\n");
1837
+ let loggerLineIndex = -1;
1838
+ for (let i = 0; i < stackLines.length; i++) {
1839
+ if (stackLines[i].includes("lib/logger")) {
1840
+ loggerLineIndex = i;
1841
+ }
1842
+ }
1843
+ const targetLineIndex = loggerLineIndex + 1;
1844
+ if (targetLineIndex >= 0 && targetLineIndex < stackLines.length) {
1845
+ const targetLine = stackLines[targetLineIndex];
1846
+ const match = targetLine.match(/at\s+(?:.+\s+\()?(.+):(\d+):(\d+)\)?/);
1847
+ if (match) {
1848
+ const scriptPath = match[1];
1849
+ const relativePath = import_path2.default.relative(process.cwd(), scriptPath);
1850
+ const lineNumber = match[2];
1851
+ return `${relativePath}:${lineNumber}`;
1852
+ }
1853
+ }
1854
+ }
1855
+ return "unknown";
1856
+ }
1857
+ function createWinstonLogger(opts) {
1858
+ return import_winston.default.createLogger({
1859
+ transports: [
1860
+ new import_winston.default.transports.Console({
1861
+ level: logLevel || "silly",
1862
+ format: import_winston.default.format.combine(
1863
+ import_winston.default.format.colorize(),
1864
+ import_winston.default.format.timestamp(),
1865
+ import_winston.default.format.ms(),
1866
+ import_winston.default.format.metadata(),
1867
+ import_winston.default.format.printf((info) => {
1868
+ const user = info.metadata.user ? (0, import_chalk.blue)(` <${info.metadata.user}>`) : "";
1869
+ const ref = info.metadata.ref ? (0, import_chalk.gray)(` ${info.metadata.ref}`) : "";
1870
+ const msgType = info.metadata.msgType ? ` ${info.metadata.msgType}` : "";
1871
+ const itemType = info.metadata.itemType ? (0, import_chalk.magenta)(` ${info.metadata.itemType}`) : "";
1872
+ const scope = info.metadata.scope ? (0, import_chalk.magenta)(` [${info.metadata.scope}] `) : (0, import_chalk.magenta)(` [${getScriptLine()}] `);
1873
+ const msg = typeof info.message === "object" ? `
1874
+ ${JSON.stringify(info.message, null, 2)}` : info.message;
1875
+ return `${info.level} ${scope}${formatISOToDateTime_default(info.metadata.timestamp)} ${info.metadata.ms}${user}${ref}${msgType}${itemType} '${msg}'`;
1876
+ }),
1877
+ import_winston.default.format.padLevels()
1878
+ )
1879
+ }),
1880
+ new import_winston.default.transports.MongoDB({
1881
+ level: logLevel || "debug",
1882
+ format: import_winston.default.format.combine(
1883
+ import_winston.default.format.timestamp(),
1884
+ import_winston.default.format.json(),
1885
+ import_winston.default.format.metadata()
1886
+ ),
1887
+ options: {
1888
+ useUnifiedTopology: true
1889
+ },
1890
+ db: opts.dbConnectionString,
1891
+ collection: "vrslogs"
1892
+ })
1893
+ ]
1894
+ });
1895
+ }
1896
+ var Logger = class _Logger {
1897
+ constructor(opts = { dbConnectionString: config.connectionString }) {
1898
+ this.winstonLogger = createWinstonLogger(opts);
1899
+ }
1900
+ static mergeMeta(objects) {
1901
+ return objects.reduce((acc, obj) => {
1902
+ return { ...acc, ...obj };
1903
+ }, {});
1904
+ }
1905
+ log(severity, msg, meta) {
1906
+ const mergedMeta = _Logger.mergeMeta(meta);
1907
+ if (!mergedMeta.scope) {
1908
+ mergedMeta.scope = getScriptLine();
1909
+ }
1910
+ const formattedMsg = typeof msg === "object" ? JSON.stringify(msg, null, 2) : msg;
1911
+ this.winstonLogger.log(severity, formattedMsg, mergedMeta);
1912
+ }
1913
+ error(msg, ...meta) {
1914
+ let message = String(msg);
1915
+ let code = 0;
1916
+ if (msg instanceof Object) {
1917
+ message = JSON.stringify(msg);
1918
+ }
1919
+ if (msg instanceof Error) {
1920
+ message = msg.stack;
1921
+ }
1922
+ if (msg instanceof ApiError_default) {
1923
+ code = msg.statusCode;
1924
+ }
1925
+ this.log("error", `${code !== 0 ? "[" + code + "]" : ""}${message}
1926
+ stacktrace: ${new Error().stack}`, meta);
1927
+ }
1928
+ warn(msg, ...meta) {
1929
+ this.log("warn", `${msg}
1930
+ stacktrace: ${new Error().stack}`, meta);
1931
+ }
1932
+ info(msg, ...meta) {
1933
+ this.log("info", msg, meta);
1934
+ }
1935
+ verbose(msg, ...meta) {
1936
+ this.log("verbose", msg, meta);
1937
+ }
1938
+ debug(msg, ...meta) {
1939
+ this.log("debug", msg, meta);
1940
+ }
1941
+ silly(msg, ...meta) {
1942
+ this.log("silly", msg, meta);
1943
+ }
1944
+ };
1945
+ var logger_default = new Logger();
1946
+
1947
+ // src/server/lib/dbItems/updateItemDate.ts
1948
+ var import_mongoose12 = __toESM(require("mongoose"));
1949
+ var logOpts = {
1950
+ scope: "dbitems",
1951
+ msgType: "DB"
1952
+ };
1953
+ async function updateItemDate(mdClass, id) {
1954
+ logger_default.debug(`update date for the item: '${mdClass}' with id: '${id}'`, logOpts);
1955
+ const itemModel = await import_mongoose12.default.model(mdClass).findById(id);
1956
+ const updatedItem = await itemModel?.updateOne({ updatedDate: Date.now() });
1957
+ logger_default.debug(`'${mdClass}' date updated: '${JSON.stringify(itemModel)}'`, logOpts);
1958
+ return updatedItem;
1959
+ }
1960
+
1961
+ // src/server/lib/dbItems/createItemIfNotExist.ts
1962
+ var import_mongoose13 = __toESM(require("mongoose"));
1963
+ async function createItemIfNotExist(modelName, params, logsMeta = {}) {
1964
+ const logOpts3 = {
1965
+ scope: "createItemIfNotExist",
1966
+ msgType: "CREATE",
1967
+ itemType: modelName
1968
+ };
1969
+ try {
1970
+ const itemModel = import_mongoose13.default.model(modelName);
1971
+ const options = {
1972
+ upsert: true,
1973
+ new: true,
1974
+ setDefaultsOnInsert: true
1975
+ };
1976
+ await itemModel.init();
1977
+ const item = await itemModel.findOneAndUpdate(params, params, options);
1978
+ logger_default.info(`ORM item '${modelName}' was created: '${JSON.stringify(item)}'`, { ...logOpts3, ...{ ref: String(item?._id) }, ...logsMeta });
1979
+ return item;
1980
+ } catch (e) {
1981
+ logger_default.debug(`cannot create '${modelName}' ORM item, error: '${e.stack || e}'`, { ...logOpts3, ...logsMeta });
1982
+ }
1983
+ return null;
1984
+ }
1985
+
1986
+ // src/server/lib/dbItems/createItemProm.ts
1987
+ var import_mongoose14 = __toESM(require("mongoose"));
1988
+ var logOpts2 = {
1989
+ scope: "dbitems",
1990
+ msgType: "DB"
1991
+ };
1992
+ async function createItemProm(modelName, params) {
1993
+ try {
1994
+ const itemModel = import_mongoose14.default.model(modelName);
1995
+ logger_default.debug(`start to create ORM item via promise: '${modelName}', params: '${JSON.stringify(params)}'`, logOpts2);
1996
+ const item = await itemModel.create(params);
1997
+ return item;
1998
+ } catch (e) {
1999
+ const errMsg2 = `cannot create '${modelName}', error: '${e.stack || e}'`;
2000
+ logger_default.error(errMsg2, logOpts2);
2001
+ throw new Error(errMsg2);
2002
+ }
2003
+ }
2004
+
2005
+ // src/server/lib/dbItems/createTest.ts
2006
+ async function createTest(params) {
2007
+ return createItemProm("VRSTest", params);
2008
+ }
2009
+
2010
+ // src/server/lib/dbItems/createSuiteIfNotExist.ts
2011
+ async function createSuiteIfNotExist(params, logsMeta = {}) {
2012
+ const logOpts3 = {
2013
+ scope: "createSuiteIfNotExist",
2014
+ msgType: "CREATE",
2015
+ itemType: "VRSSuite"
2016
+ };
2017
+ if (!params.name || !params.app) throw new Error(`Cannot create suite, wrong params: '${JSON.stringify(params)}'`);
2018
+ logger_default.debug(`try to create suite if exist, params: '${JSON.stringify(params)}'`, { ...logOpts3, ...logsMeta });
2019
+ let suite = await Suite_model_default.findOne({ name: params.name }).exec();
2020
+ if (suite) {
2021
+ logger_default.debug(`suite already exist: '${JSON.stringify(params)}'`, { ...logOpts3, ...logsMeta });
2022
+ return suite;
2023
+ }
2024
+ suite = await Suite_model_default.create(params);
2025
+ logger_default.debug(`suite with name: '${params.name}' was created`, { ...logOpts3, ...logsMeta });
2026
+ return suite;
2027
+ }
2028
+
2029
+ // src/server/lib/dbItems/createRunIfNotExist.ts
2030
+ async function createRunIfNotExist(params, logsMeta = {}) {
2031
+ const logOpts3 = {
2032
+ scope: "createRunIfNotExist",
2033
+ msgType: "CREATE",
2034
+ itemType: "VRSRun"
2035
+ };
2036
+ let run;
2037
+ try {
2038
+ if (!params.name || !params.app || !params.ident) {
2039
+ throw new Error(`Cannot create run, wrong params: '${JSON.stringify(params)}'`);
2040
+ }
2041
+ logger_default.debug(`try to create run if exist, params: '${JSON.stringify(params)}'`, { ...logOpts3, ...logsMeta });
2042
+ run = await Run_model_default.findOne({ ident: params.ident }).exec();
2043
+ if (run) {
2044
+ logger_default.debug(`run already exist: '${JSON.stringify(params)}'`, { ...logOpts3, ...logsMeta });
2045
+ return run;
2046
+ }
2047
+ run = await Run_model_default.create({
2048
+ ...params,
2049
+ createdDate: params.createdDate || /* @__PURE__ */ new Date()
2050
+ });
2051
+ logger_default.debug(`run with name: '${params.name}' was created: ${run}`, { ...logOpts3, ...logsMeta });
2052
+ return run;
2053
+ } catch (e) {
2054
+ if (e.code === 11e3) {
2055
+ logger_default.warn(`run key duplication collision: '${JSON.stringify(params)}', error: '${errMsg(e)}'`, { ...logOpts3, ...logsMeta });
2056
+ run = await Run_model_default.findOne({ name: params.name, ident: params.ident });
2057
+ logger_default.warn(`run key duplication collision, found: '${JSON.stringify(run)}'`, { ...logOpts3, ...logsMeta });
2058
+ if (run) return run;
2059
+ }
2060
+ logger_default.error(`cannot create run, params: '${JSON.stringify(params)}', error: '${errMsg(e)}', obj: ${JSON.stringify(e)}`, { ...logOpts3, ...logsMeta });
2061
+ throw e;
2062
+ }
2063
+ }
2064
+
2065
+ // src/server/lib/сomparison/compareImagesNode.ts
2066
+ var import_node_resemble = __toESM(require("@syngrisi/node-resemble.js"));
2067
+ async function streamToBuffer(stream) {
2068
+ return new Promise((resolve, reject) => {
2069
+ const data = [];
2070
+ stream.on("data", (chunk) => {
2071
+ data.push(chunk);
2072
+ });
2073
+ stream.on("end", () => {
2074
+ resolve(Buffer.concat(data));
2075
+ });
2076
+ stream.on("error", (err) => {
2077
+ reject(err);
2078
+ });
2079
+ });
2080
+ }
2081
+ function compareImages(image1, image2, options) {
2082
+ return new Promise((resolve, reject) => {
2083
+ try {
2084
+ const ignoreTransform = {
2085
+ antialiasing: "ignoreAntialiasing",
2086
+ colors: "ignoreColors",
2087
+ nothing: "ignoreNothing"
2088
+ };
2089
+ const ignoreMethod = ignoreTransform[options.ignore] ? ignoreTransform[options.ignore] : "ignoreNothing";
2090
+ console.log("ignoreMethod", ignoreMethod);
2091
+ console.log("ignoreMethod", ignoreMethod);
2092
+ console.log("ignoreMethod", ignoreMethod);
2093
+ console.log("ignoreMethod", ignoreMethod);
2094
+ console.log("ignoreMethod", ignoreMethod);
2095
+ console.log("ignoreMethod", ignoreMethod);
2096
+ console.log("ignoreMethod", ignoreMethod);
2097
+ console.log("ignoreMethod", ignoreMethod);
2098
+ const outputOpts = options.output;
2099
+ import_node_resemble.default.outputSettings(outputOpts);
2100
+ let ignoredRect;
2101
+ if (options.ignoreRectangles) {
2102
+ ignoredRect = options.ignoreRectangles.map((it) => {
2103
+ delete it.name;
2104
+ return [it.left, it.top, it.right - it.left, it.bottom - it.top];
2105
+ });
2106
+ }
2107
+ (0, import_node_resemble.default)(image1).compareTo(image2)[ignoreMethod]().ignoreRectangles(ignoredRect).onComplete(async (data) => {
2108
+ console.log(data);
2109
+ const stream = await data.getDiffImage();
2110
+ const buffer = await streamToBuffer(stream.pack());
2111
+ data.getBuffer = function() {
2112
+ return buffer;
2113
+ };
2114
+ resolve(data);
2115
+ });
2116
+ } catch (e) {
2117
+ reject(e);
2118
+ }
2119
+ });
2120
+ }
2121
+
2122
+ // src/server/lib/сomparison/comparator.ts
2123
+ var DEFAULT_OPTIONS = {
2124
+ output: {
2125
+ largeImageThreshold: 0,
2126
+ outputDiff: true,
2127
+ errorType: "flat",
2128
+ transparency: 0
2129
+ },
2130
+ ignore: "nothing"
2131
+ };
2132
+ async function makeDiff(imgData1, imgData2, options = {}) {
2133
+ const opts = Object.assign(DEFAULT_OPTIONS, options);
2134
+ opts.ignoreRectangles = options.ignoredBoxes;
2135
+ const compareData = await compareImages(imgData1, imgData2, opts);
2136
+ return compareData;
2137
+ }
2138
+ async function getDiff(baselineOrigin, actualOrigin, opts = {}) {
2139
+ const logOpts3 = {
2140
+ scope: "getDiff",
2141
+ itemType: "image",
2142
+ msgType: "GET_DIFF"
2143
+ };
2144
+ try {
2145
+ const executionTimer = process.hrtime();
2146
+ logger_default.debug(`SAMPLE #1: ${process.hrtime(executionTimer).toString()}`, logOpts3);
2147
+ const directDiff = await makeDiff(baselineOrigin, actualOrigin, opts);
2148
+ logger_default.debug(`SAMPLE #2: ${process.hrtime(executionTimer).toString()}`, logOpts3);
2149
+ directDiff.executionTotalTime = process.hrtime(executionTimer).toString();
2150
+ logger_default.debug(`SAMPLE #3: ${process.hrtime(executionTimer).toString()}`, logOpts3);
2151
+ logger_default.debug(`the diff is: ${JSON.stringify(directDiff, null, 4)}`, logOpts3);
2152
+ return directDiff;
2153
+ } catch (e) {
2154
+ logger_default.error(errMsg(e), logOpts3);
2155
+ throw new Error(errMsg(e));
2156
+ }
2157
+ }
2158
+
2159
+ // src/server/services/client.service.ts
2160
+ var import_http_status = __toESM(require("http-status"));
2161
+ var import_http_status2 = __toESM(require("http-status"));
2162
+ async function updateTest(id, update) {
2163
+ const logOpts3 = {
2164
+ scope: "updateTest",
2165
+ itemType: "test",
2166
+ msgType: "UPDATE",
2167
+ ref: id
2168
+ };
2169
+ logger_default.debug(`update test id '${id}' with params '${JSON.stringify(update)}'`, logOpts3);
2170
+ const updatedDate = update.updatedDate || Date.now();
2171
+ const test = await Test_model_default.findByIdAndUpdate(
2172
+ id,
2173
+ { ...update, updatedDate }
2174
+ ).exec();
2175
+ await test?.save();
2176
+ return test;
2177
+ }
2178
+ var startSession = async (params, username) => {
2179
+ const logOpts3 = {
2180
+ scope: "createTest",
2181
+ user: username,
2182
+ itemType: "test",
2183
+ msgType: "CREATE"
2184
+ };
2185
+ logger_default.info(`create test with name '${params.name}', params: '${JSON.stringify(params)}'`, logOpts3);
2186
+ const opts = removeEmptyProperties({
2187
+ name: params.name,
2188
+ status: "Running",
2189
+ app: params.app,
2190
+ tags: params.tags && JSON.parse(params.tags),
2191
+ branch: params.branch,
2192
+ viewport: params.viewport,
2193
+ browserName: params.browser,
2194
+ browserVersion: params.browserVersion,
2195
+ browserFullVersion: params.browserFullVersion,
2196
+ os: params.os,
2197
+ startDate: /* @__PURE__ */ new Date(),
2198
+ updatedDate: /* @__PURE__ */ new Date()
2199
+ });
2200
+ try {
2201
+ const app = await createItemIfNotExist(
2202
+ "VRSApp",
2203
+ { name: params.app },
2204
+ { user: username, itemType: "app" }
2205
+ );
2206
+ opts.app = app._id;
2207
+ const run = await createRunIfNotExist(
2208
+ { name: params.run, ident: params.runident, app: app._id },
2209
+ { user: username, itemType: "run" }
2210
+ );
2211
+ opts.run = run._id;
2212
+ const suite = await createSuiteIfNotExist(
2213
+ { name: params.suite || "Others", app: app._id, createdDate: /* @__PURE__ */ new Date() },
2214
+ { user: username, itemType: "suite" }
2215
+ );
2216
+ opts.suite = suite._id;
2217
+ const test = await createTest(opts);
2218
+ return test;
2219
+ } catch (e) {
2220
+ logger_default.error(`cannot start session '${params.name}', params: '${JSON.stringify(params)}', error: ${errMsg(e)}`, logOpts3);
2221
+ throw e;
2222
+ }
2223
+ };
2224
+ var endSession = async (testId, username) => {
2225
+ const logOpts3 = {
2226
+ scope: "stopSession",
2227
+ msgType: "END_SESSION",
2228
+ user: username,
2229
+ itemType: "test",
2230
+ ref: testId
2231
+ };
2232
+ await waitUntil(async () => (await Check_model_default.find({ test: testId }).exec()).filter((ch) => ch.status.toString() !== "pending").length > 0);
2233
+ const sessionChecks = await Check_model_default.find({ test: testId }).lean().exec();
2234
+ const checksStatuses = sessionChecks.map((x) => x.status[0]);
2235
+ let status = "not set";
2236
+ if (checksStatuses.some((st) => st === "failed")) {
2237
+ status = "Failed";
2238
+ }
2239
+ if (checksStatuses.some((st) => st === "passed") && !checksStatuses.some((st) => st === "failed")) {
2240
+ status = "Passed";
2241
+ }
2242
+ if (checksStatuses.some((st) => st === "new") && !checksStatuses.some((st) => st === "failed")) {
2243
+ status = "Passed";
2244
+ }
2245
+ if (checksStatuses.some((st) => st === "blinking") && !checksStatuses.some((st) => st === "failed")) {
2246
+ status = "Passed";
2247
+ }
2248
+ if (checksStatuses.every((st) => st === "new")) {
2249
+ status = "New";
2250
+ }
2251
+ const blinking = checksStatuses.filter((g) => g === "blinking").length;
2252
+ const testParams = {
2253
+ status,
2254
+ blinking
2255
+ // calculatedViewport,
2256
+ };
2257
+ logger_default.info(`the session is over, the test will be updated with parameters: '${JSON.stringify(testParams)}'`, logOpts3);
2258
+ const updatedTest = await updateTest(testId, testParams);
2259
+ const result = updatedTest?.toObject();
2260
+ return result;
2261
+ };
2262
+ async function getAcceptedBaseline(params) {
2263
+ const identFieldsAccepted = Object.assign(buildIdentObject(params), { markedAs: "accepted" });
2264
+ const acceptedBaseline = await Baseline_model_default.findOne(identFieldsAccepted, {}, { sort: { createdDate: -1 } });
2265
+ logger_default.debug(`acceptedBaseline: '${acceptedBaseline ? JSON.stringify(acceptedBaseline) : "not found"}'`, { itemType: "baseline" });
2266
+ if (acceptedBaseline) return acceptedBaseline;
2267
+ return null;
2268
+ }
2269
+ async function getLastSuccessCheck(identifier) {
2270
+ const condition = [{
2271
+ ...identifier,
2272
+ status: "new"
2273
+ }, {
2274
+ ...identifier,
2275
+ status: "passed"
2276
+ }];
2277
+ return (await Check_model_default.find({ $or: condition }).sort({ updatedDate: -1 }).limit(1))[0];
2278
+ }
2279
+ async function getNotPendingChecksByIdent(identifier) {
2280
+ return Check_model_default.find({
2281
+ ...identifier,
2282
+ status: { $ne: "pending" }
2283
+ }).sort({ updatedDate: -1 }).exec();
2284
+ }
2285
+ async function getSnapshotByImgHash(hash) {
2286
+ return Snapshot_model_default.findOne({ imghash: hash });
2287
+ }
2288
+ async function createSnapshot(parameters) {
2289
+ const logOpts3 = {
2290
+ scope: "createSnapshot",
2291
+ itemType: "snapshot",
2292
+ msgType: "CREATE"
2293
+ };
2294
+ const { name, fileData, hashCode } = parameters;
2295
+ const opts = { name };
2296
+ if (fileData === null) throw new ApiError_default(import_http_status.default.BAD_REQUEST, `cannot create the snapshot, the 'fileData' is not set, name: '${name}'`);
2297
+ opts.imghash = hashCode || (0, import_hasha.default)(fileData);
2298
+ const snapshot = new Snapshot_model_default(opts);
2299
+ const filename = `${snapshot.id}.png`;
2300
+ const path3 = `${config.defaultImagesPath}${filename}`;
2301
+ logger_default.debug(`save screenshot for: '${name}' snapshot to: '${path3}'`, logOpts3);
2302
+ await import_fs2.promises.writeFile(path3, fileData);
2303
+ snapshot.filename = filename;
2304
+ await snapshot.save();
2305
+ logger_default.debug(`snapshot was saved: '${JSON.stringify(snapshot)}'`, { ...logOpts3, ...{ ref: snapshot._id } });
2306
+ return snapshot;
2307
+ }
2308
+ async function cloneSnapshot(sourceSnapshot, name) {
2309
+ const { filename } = sourceSnapshot;
2310
+ const hashCode = sourceSnapshot.imghash;
2311
+ const newSnapshot = new Snapshot_model_default({ name, filename, imghash: hashCode });
2312
+ await newSnapshot.save();
2313
+ return newSnapshot;
2314
+ }
2315
+ async function compareSnapshots(baselineSnapshot, actual, opts = {}) {
2316
+ const logOpts3 = {
2317
+ scope: "compareSnapshots",
2318
+ ref: baselineSnapshot.id,
2319
+ itemType: "snapshot",
2320
+ msgType: "COMPARE"
2321
+ };
2322
+ try {
2323
+ logger_default.debug(`compare baseline and actual snapshots with ids: [${baselineSnapshot.id}, ${actual.id}]`, logOpts3);
2324
+ logger_default.debug(`current baseline snapshot: ${JSON.stringify(baselineSnapshot)}`, logOpts3);
2325
+ let diff;
2326
+ if (baselineSnapshot.imghash === actual.imghash) {
2327
+ logger_default.debug(`baseline and actual snapshot have the identical image hashes: '${baselineSnapshot.imghash}'`, logOpts3);
2328
+ diff = {
2329
+ isSameDimensions: true,
2330
+ dimensionDifference: { width: 0, height: 0 },
2331
+ rawMisMatchPercentage: 0,
2332
+ misMatchPercentage: "0.00",
2333
+ analysisTime: 0,
2334
+ executionTotalTime: "0",
2335
+ getBuffer: null
2336
+ };
2337
+ } else {
2338
+ const baselinePath = `${config.defaultImagesPath}${baselineSnapshot.filename}`;
2339
+ const actualPath = `${config.defaultImagesPath}${actual.filename}`;
2340
+ const baselineData = await import_fs2.promises.readFile(baselinePath);
2341
+ const actualData = await import_fs2.promises.readFile(actualPath);
2342
+ logger_default.debug(`baseline path: ${baselinePath}`, logOpts3);
2343
+ logger_default.debug(`actual path: ${actualPath}`, logOpts3);
2344
+ const options = opts;
2345
+ const baseline = await Baseline_model_default.findOne({ snapshootId: baselineSnapshot._id }).exec();
2346
+ if (baseline) {
2347
+ if (baseline.ignoreRegions) {
2348
+ logger_default.debug(`ignore regions: '${baseline.ignoreRegions}', type: '${typeof baseline.ignoreRegions}'`);
2349
+ options.ignoredBoxes = JSON.parse(baseline.ignoreRegions);
2350
+ }
2351
+ options.ignore = baseline.matchType || "nothing";
2352
+ }
2353
+ diff = await getDiff(baselineData, actualData, options);
2354
+ }
2355
+ logger_default.silly(`the diff is: '${JSON.stringify(diff, null, 2)}'`);
2356
+ if (diff.rawMisMatchPercentage.toString() !== "0") {
2357
+ logger_default.debug(`images are different, ids: [${baselineSnapshot.id}, ${actual.id}], rawMisMatchPercentage: '${diff.rawMisMatchPercentage}'`);
2358
+ }
2359
+ if (diff.stabMethod && diff.vOffset) {
2360
+ if (diff.stabMethod === "downup") {
2361
+ actual.vOffset = -diff.vOffset;
2362
+ await actual.save();
2363
+ }
2364
+ if (diff.stabMethod === "updown") {
2365
+ baselineSnapshot.vOffset = -diff.vOffset;
2366
+ await baselineSnapshot.save();
2367
+ }
2368
+ }
2369
+ return diff;
2370
+ } catch (e) {
2371
+ const errMsg2 = `cannot compare snapshots: ${e}
2372
+ ${e instanceof Error ? e.stack : e}`;
2373
+ logger_default.error(errMsg2, logOpts3);
2374
+ throw new Error(String(e));
2375
+ }
2376
+ }
2377
+ var isBaselineValid = (baseline) => {
2378
+ const keys = [
2379
+ "name",
2380
+ "app",
2381
+ "branch",
2382
+ "browserName",
2383
+ "viewport",
2384
+ "os",
2385
+ "createdDate",
2386
+ "lastMarkedDate",
2387
+ "markedAs",
2388
+ "markedById",
2389
+ "markedByUsername",
2390
+ "snapshootId"
2391
+ ];
2392
+ for (const key of keys) {
2393
+ if (!baseline[key]) {
2394
+ logger_default.error(`invalid baseline, the '${key}' property is empty`);
2395
+ return false;
2396
+ }
2397
+ }
2398
+ return true;
2399
+ };
2400
+ var updateCheckParamsFromBaseline = (params, baseline) => {
2401
+ const updatedParams = { ...params };
2402
+ updatedParams.baselineId = baseline.snapshootId.toString();
2403
+ updatedParams.markedAs = baseline.markedAs;
2404
+ updatedParams.markedDate = baseline.lastMarkedDate?.toString();
2405
+ updatedParams.markedByUsername = baseline.markedByUsername;
2406
+ return updatedParams;
2407
+ };
2408
+ var prepareActualSnapshot = async (checkParam, snapshotFoundedByHashcode, logOpts3) => {
2409
+ let currentSnapshot;
2410
+ const fileData = checkParam.files ? checkParam.files.file.data : null;
2411
+ if (snapshotFoundedByHashcode) {
2412
+ const fullFilename = `${config.defaultImagesPath}${snapshotFoundedByHashcode.filename}`;
2413
+ if (!import_fs2.default.existsSync(fullFilename)) {
2414
+ throw new Error(`Couldn't find the baseline file: '${fullFilename}'`);
2415
+ }
2416
+ logger_default.debug(`snapshot with such hashcode: '${checkParam.hashCode}' is already exists, will clone it`, logOpts3);
2417
+ if (!checkParam.name) throw new ApiError_default(import_http_status.default.BAD_REQUEST, `Cannot prepareActualSnapshot name is empty, hashe: ${checkParam.hashCode}`);
2418
+ currentSnapshot = await cloneSnapshot(snapshotFoundedByHashcode, checkParam.name);
2419
+ } else {
2420
+ logger_default.debug(`snapshot with such hashcode: '${checkParam.hashCode}' does not exists, will create it`, logOpts3);
2421
+ currentSnapshot = await createSnapshot({ name: checkParam.name, fileData, hashCode: checkParam.hashCode });
2422
+ }
2423
+ return currentSnapshot;
2424
+ };
2425
+ async function isNeedFiles(checkParam, logOpts3) {
2426
+ const snapshotFoundedByHashcode = await getSnapshotByImgHash(checkParam.hashCode);
2427
+ if (!checkParam.hashCode && !checkParam.files) {
2428
+ logger_default.debug("hashCode or files parameters should be present", logOpts3);
2429
+ return { needFilesStatus: true, snapshotFoundedByHashcode };
2430
+ }
2431
+ if (!checkParam.files && !snapshotFoundedByHashcode) {
2432
+ logger_default.debug(`cannot find the snapshot with hash: '${checkParam.hashCode}'`, logOpts3);
2433
+ return { needFilesStatus: true, snapshotFoundedByHashcode };
2434
+ }
2435
+ return { needFilesStatus: false, snapshotFoundedByHashcode };
2436
+ }
2437
+ async function inspectBaseline(newCheckParams, storedBaseline, checkIdent, currentSnapshot, logOpts3) {
2438
+ let currentBaselineSnapshot = null;
2439
+ const params = {};
2440
+ params.failReasons = [];
2441
+ if (storedBaseline !== null) {
2442
+ logger_default.debug(`a baseline for check name: '${newCheckParams.name}', id: '${storedBaseline.snapshootId}' is already exists`, logOpts3);
2443
+ if (!isBaselineValid(storedBaseline)) {
2444
+ newCheckParams.failReasons.push("invalid_baseline");
2445
+ }
2446
+ Object.assign(params, updateCheckParamsFromBaseline(newCheckParams, storedBaseline));
2447
+ currentBaselineSnapshot = await Snapshot_model_default.findById(storedBaseline.snapshootId);
2448
+ if (!currentBaselineSnapshot) throw new ApiError_default(import_http_status.default.INTERNAL_SERVER_ERROR, `Cannot find the snapshot with id: ${storedBaseline.snapshootId}`);
2449
+ } else {
2450
+ const checksWithSameIdent = await getNotPendingChecksByIdent(checkIdent);
2451
+ if (checksWithSameIdent.length > 0) {
2452
+ logger_default.error(`checks with ident'${JSON.stringify(checkIdent)}' exist, but baseline is absent`, logOpts3);
2453
+ params.failReasons.push("not_accepted");
2454
+ params.baselineId = currentSnapshot.id.toString();
2455
+ currentBaselineSnapshot = currentSnapshot;
2456
+ } else {
2457
+ params.baselineId = currentSnapshot.id;
2458
+ params.status = "new";
2459
+ currentBaselineSnapshot = currentSnapshot;
2460
+ logger_default.debug(`create the new check with params: '${prettyCheckParams_default(params)}'`, logOpts3);
2461
+ }
2462
+ }
2463
+ return { inspectBaselineParams: params, currentBaselineSnapshot };
2464
+ }
2465
+ var ignoreDifferentResolutions = ({ height, width }) => {
2466
+ if (width === 0 && height === -1) return true;
2467
+ if (width === 0 && height === 1) return true;
2468
+ return false;
2469
+ };
2470
+ var compare = async (expectedSnapshot, actualSnapshot, newCheckParams, skipSaveOnCompareError, currentUser) => {
2471
+ const logOpts3 = {
2472
+ scope: "createCheck.compare",
2473
+ user: currentUser.username,
2474
+ itemType: "check",
2475
+ msgType: "COMPARE"
2476
+ };
2477
+ const executionTimer = process.hrtime();
2478
+ const compareResult = {};
2479
+ compareResult.failReasons = [...newCheckParams.failReasons];
2480
+ let checkCompareResult;
2481
+ let diffSnapshot = null;
2482
+ const areSnapshotsDifferent = (result) => result.rawMisMatchPercentage.toString() !== "0";
2483
+ const areSnapshotsWrongDimensions = (result) => !result.isSameDimensions && !ignoreDifferentResolutions(result.dimensionDifference);
2484
+ if (newCheckParams.status !== "new" && !compareResult.failReasons.includes("not_accepted")) {
2485
+ try {
2486
+ logger_default.debug(`'the check with name: '${newCheckParams.name}' isn't new, make comparing'`, logOpts3);
2487
+ checkCompareResult = await compareSnapshots(expectedSnapshot, actualSnapshot, { vShifting: newCheckParams.vShifting });
2488
+ logger_default.silly(`ignoreDifferentResolutions: '${ignoreDifferentResolutions(checkCompareResult.dimensionDifference)}'`);
2489
+ logger_default.silly(`dimensionDifference: '${JSON.stringify(checkCompareResult.dimensionDifference)}`);
2490
+ if (areSnapshotsDifferent(checkCompareResult) || areSnapshotsWrongDimensions(checkCompareResult)) {
2491
+ let logMsg;
2492
+ if (areSnapshotsWrongDimensions(checkCompareResult)) {
2493
+ logMsg = "snapshots have different dimensions";
2494
+ compareResult.failReasons.push("wrong_dimensions");
2495
+ }
2496
+ if (areSnapshotsDifferent(checkCompareResult)) {
2497
+ logMsg = "snapshots have differences";
2498
+ compareResult.failReasons.push("different_images");
2499
+ }
2500
+ if (logMsg) logger_default.debug(logMsg, logOpts3);
2501
+ logger_default.debug(`saving diff snapshot for check with name: '${newCheckParams.name}'`, logOpts3);
2502
+ if (!skipSaveOnCompareError) {
2503
+ diffSnapshot = await createSnapshot({
2504
+ name: newCheckParams.name,
2505
+ fileData: checkCompareResult.getBuffer()
2506
+ });
2507
+ compareResult.diffId = diffSnapshot.id;
2508
+ compareResult.diffSnapshot = diffSnapshot;
2509
+ }
2510
+ compareResult.status = "failed";
2511
+ } else {
2512
+ compareResult.status = "passed";
2513
+ }
2514
+ checkCompareResult.totalCheckHandleTime = process.hrtime(executionTimer).toString();
2515
+ compareResult.result = JSON.stringify(checkCompareResult, null, " ");
2516
+ } catch (e) {
2517
+ compareResult.status = "failed";
2518
+ compareResult.result = JSON.stringify({ server_error: `error during comparing - ${errMsg(e)}` });
2519
+ compareResult.failReasons.push("internal_server_error");
2520
+ throw new ApiError_default(import_http_status.default.INTERNAL_SERVER_ERROR, `error during comparing: ${errMsg(e)}`);
2521
+ }
2522
+ }
2523
+ if (compareResult.failReasons.length > 0) {
2524
+ compareResult.status = "failed";
2525
+ }
2526
+ return compareResult;
2527
+ };
2528
+ var createCheckParams = (checkParam, suite, app, test, currentUser) => ({
2529
+ test: test.id,
2530
+ name: checkParam.name,
2531
+ status: "pending",
2532
+ viewport: checkParam.viewport,
2533
+ browserName: checkParam.browserName,
2534
+ browserVersion: checkParam.browserVersion,
2535
+ browserFullVersion: checkParam.browserFullVersion,
2536
+ os: checkParam.os,
2537
+ updatedDate: Date.now(),
2538
+ suite: suite.id,
2539
+ app: app.id,
2540
+ branch: checkParam.branch,
2541
+ domDump: checkParam.domDump,
2542
+ run: test.run.toString(),
2543
+ creatorId: currentUser._id.toString(),
2544
+ creatorUsername: currentUser.username,
2545
+ hashCode: checkParam.hashCode,
2546
+ failReasons: []
2547
+ });
2548
+ var createCheck = async (checkParam, test, suite, app, currentUser, skipSaveOnCompareError = false) => {
2549
+ const logOpts3 = {
2550
+ scope: "createCheck",
2551
+ user: currentUser.username,
2552
+ itemType: "check",
2553
+ msgType: "CREATE"
2554
+ };
2555
+ let actualSnapshot;
2556
+ let currentBaselineSnapshot;
2557
+ const newCheckParams = createCheckParams(checkParam, suite, app, test, currentUser);
2558
+ const checkIdent = buildIdentObject(newCheckParams);
2559
+ let check = null;
2560
+ const totalCheckHandleTime = 0;
2561
+ const addCheck = (test2, check2) => {
2562
+ if (test2.checks) {
2563
+ test2.checks.push(check2.id);
2564
+ } else {
2565
+ test2.checks = [check2.id];
2566
+ }
2567
+ };
2568
+ try {
2569
+ const { needFilesStatus, snapshotFoundedByHashcode } = await isNeedFiles(checkParam, logOpts3);
2570
+ if (needFilesStatus) return { status: "needFiles" };
2571
+ actualSnapshot = await prepareActualSnapshot(checkParam, snapshotFoundedByHashcode, logOpts3);
2572
+ newCheckParams.actualSnapshotId = actualSnapshot.id;
2573
+ logger_default.info(`find a baseline for the check with identifier: '${JSON.stringify(checkIdent)}'`, logOpts3);
2574
+ const storedBaseline = await getAcceptedBaseline(checkIdent);
2575
+ const inspectBaselineResult = await inspectBaseline(newCheckParams, storedBaseline, checkIdent, actualSnapshot, logOpts3);
2576
+ Object.assign(newCheckParams, inspectBaselineResult.inspectBaselineParams);
2577
+ currentBaselineSnapshot = inspectBaselineResult.currentBaselineSnapshot;
2578
+ const compareResult = await compare(currentBaselineSnapshot, actualSnapshot, newCheckParams, skipSaveOnCompareError, currentUser);
2579
+ Object.assign(newCheckParams, compareResult);
2580
+ logger_default.debug(`create the new check document with params: '${prettyCheckParams_default(newCheckParams)}'`, logOpts3);
2581
+ check = await Check_model_default.create(newCheckParams);
2582
+ const savedCheck = await check.save();
2583
+ logger_default.debug(`the check with id: '${check.id}', was created, will updated with data during creating process`, logOpts3);
2584
+ logOpts3.ref = String(check.id);
2585
+ logger_default.debug(`update test with check id: '${check.id}'`, logOpts3);
2586
+ addCheck(test, check);
2587
+ test.markedAs = await calculateAcceptedStatus(check.test);
2588
+ test.updatedDate = /* @__PURE__ */ new Date();
2589
+ await test.save();
2590
+ logger_default.debug("update suite and run", logOpts3);
2591
+ await updateItemDate("VRSSuite", check.suite);
2592
+ await updateItemDate("VRSRun", check.run);
2593
+ const lastSuccessCheck = await getLastSuccessCheck(checkIdent);
2594
+ const checkObject = savedCheck.toObject();
2595
+ const result = {
2596
+ ...checkObject,
2597
+ currentSnapshot: actualSnapshot,
2598
+ expectedSnapshot: currentBaselineSnapshot,
2599
+ diffSnapshot: compareResult.diffSnapshot,
2600
+ executeTime: totalCheckHandleTime,
2601
+ lastSuccess: lastSuccessCheck ? lastSuccessCheck.id : null
2602
+ };
2603
+ return result;
2604
+ } catch (e) {
2605
+ newCheckParams.status = "failed";
2606
+ newCheckParams.result = `{ "server error": "${errMsg(e)}" }`;
2607
+ newCheckParams.failReasons.push("internal_server_error");
2608
+ if (!check) {
2609
+ logger_default.debug(`create the new check document with params: '${prettyCheckParams_default(newCheckParams)}'`, logOpts3);
2610
+ check = await Check_model_default.create(newCheckParams);
2611
+ await check.save();
2612
+ } else {
2613
+ check.set(newCheckParams);
2614
+ await check.save();
2615
+ }
2616
+ logger_default.debug(`the check with id: '${check.id}', was created, will updated with data during creating process`, logOpts3);
2617
+ logOpts3.ref = check.id;
2618
+ logger_default.debug(`update test with check id: '${check.id}'`, logOpts3);
2619
+ addCheck(test, check);
2620
+ await test.save();
2621
+ throw new ApiError_default(import_http_status2.default.INTERNAL_SERVER_ERROR, errMsg(e));
2622
+ }
2623
+ };
2624
+ var getIdent = () => ident;
2625
+ var getBaselines = async (filter, options) => {
2626
+ const logOpts3 = {
2627
+ scope: "getBaselines",
2628
+ itemType: "baseline",
2629
+ msgType: "GET"
2630
+ };
2631
+ const app = await App_model_default.findOne({ name: filter.app });
2632
+ if (!app) {
2633
+ logger_default.error(`Cannot find the app: '${filter.app}'`, logOpts3);
2634
+ return {};
2635
+ }
2636
+ filter.app = app._id;
2637
+ logger_default.debug(`Get baselines with filter: '${JSON.stringify(filter)}', options: '${JSON.stringify(options)}'`, logOpts3);
2638
+ return Baseline_model_default.paginate(filter, options);
2639
+ };
2640
+ // Annotate the CommonJS export names for ESM import in node:
2641
+ 0 && (module.exports = {
2642
+ createCheck,
2643
+ endSession,
2644
+ getBaselines,
2645
+ getIdent,
2646
+ startSession
2647
+ });
2648
+ //# sourceMappingURL=client.service.js.map