@syngrisi/syngrisi 2.2.1

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 (387) hide show
  1. package/.nvmrc +1 -0
  2. package/LICENSE.md +9 -0
  3. package/README.md +139 -0
  4. package/config.js +17 -0
  5. package/dist/config.js +16 -0
  6. package/dist/src/server/models/index.js +508 -0
  7. package/dist/src/server/models/plugins/index.js +4 -0
  8. package/dist/src/server/models/plugins/paginate.plugin.js +76 -0
  9. package/dist/src/server/models/plugins/paginateDistinct.plugin.js +76 -0
  10. package/dist/src/server/models/plugins/toJSON.plugin.js +39 -0
  11. package/dist/src/server/schemas/createCheck.shema.js +17 -0
  12. package/dist/src/server/schemas/getBaseline.shema.js +12 -0
  13. package/dist/src/server/utils/paramsGuard.js +18 -0
  14. package/dist/src/tasks/backup.js +68 -0
  15. package/dist/src/tasks/lib/common.js +14 -0
  16. package/dist/src/tasks/lib/utils.js +14 -0
  17. package/dist/src/tasks/migrations/2.0.migration.js +86 -0
  18. package/dist/src/tasks/migrations/2.0.migration_mql.js +57 -0
  19. package/dist/src/tasks/reindex.js +28 -0
  20. package/dist/src/tasks/restore.js +86 -0
  21. package/dist/tsconfig.tsbuildinfo +1 -0
  22. package/docker-compose.yml +70 -0
  23. package/mvc/views/react/admin/index.html +22 -0
  24. package/mvc/views/react/assets/LogicalGroup.95929360.js +15993 -0
  25. package/mvc/views/react/assets/PasswordInput.8a73fdd2.js +299 -0
  26. package/mvc/views/react/assets/admin.94703bdc.js +14448 -0
  27. package/mvc/views/react/assets/auth.748478ef.js +673 -0
  28. package/mvc/views/react/assets/bg_2_0_dark_L2.3a31edc0.png +0 -0
  29. package/mvc/views/react/assets/favicon.bf5828d5.svg +7 -0
  30. package/mvc/views/react/assets/index.a5606313.css +23 -0
  31. package/mvc/views/react/assets/roboto-v30-latin-100.0f303f31.woff2 +0 -0
  32. package/mvc/views/react/assets/roboto-v30-latin-100.34e9582c.woff +0 -0
  33. package/mvc/views/react/assets/roboto-v30-latin-500.9ce7f3ac.woff +0 -0
  34. package/mvc/views/react/assets/roboto-v30-latin-500.b0195382.woff2 +0 -0
  35. package/mvc/views/react/assets/roboto-v30-latin-700.e0fd57c0.woff +0 -0
  36. package/mvc/views/react/assets/roboto-v30-latin-700.f5aebdfe.woff2 +0 -0
  37. package/mvc/views/react/assets/roboto-v30-latin-regular.f2abf7fb.woff +0 -0
  38. package/mvc/views/react/assets/roboto-v30-latin-regular.f6734f81.woff2 +0 -0
  39. package/mvc/views/react/assets/root.136e0ea3.js +25451 -0
  40. package/mvc/views/react/assets/use-form.57ebe175.js +24472 -0
  41. package/mvc/views/react/assets/use-form.ecb4391b.css +36 -0
  42. package/mvc/views/react/auth/index.html +22 -0
  43. package/mvc/views/react/index.html +19 -0
  44. package/mvc/views/react/index2/index.html +21 -0
  45. package/package.json +144 -0
  46. package/server.js +166 -0
  47. package/src/server/controllers/app.controller.js +21 -0
  48. package/src/server/controllers/auth.controller.js +156 -0
  49. package/src/server/controllers/baseline.controller.js +24 -0
  50. package/src/server/controllers/check.controller.js +56 -0
  51. package/src/server/controllers/client.controller.js +173 -0
  52. package/src/server/controllers/index.js +12 -0
  53. package/src/server/controllers/logs.controller.js +30 -0
  54. package/src/server/controllers/runs.controller.js +25 -0
  55. package/src/server/controllers/settings.controller.js +23 -0
  56. package/src/server/controllers/snapshots.controller.js +17 -0
  57. package/src/server/controllers/suite.controller.js +24 -0
  58. package/src/server/controllers/tasks.controller.js +47 -0
  59. package/src/server/controllers/test.controller.js +70 -0
  60. package/src/server/controllers/users.controller.js +79 -0
  61. package/src/server/data/custom_devices.json +8 -0
  62. package/src/server/data/devices.json +773 -0
  63. package/src/server/data/get_devices.sh +2 -0
  64. package/src/server/lib/AppSettings.js +56 -0
  65. package/src/server/lib/admin.json +9 -0
  66. package/src/server/lib/comparator.js +147 -0
  67. package/src/server/lib/compareImagesNode.js +60 -0
  68. package/src/server/lib/dbItems.js +215 -0
  69. package/src/server/lib/ensureLogin/ensureLoggedIn.js +223 -0
  70. package/src/server/lib/ensureLogin/ensureLoggedOut.js +44 -0
  71. package/src/server/lib/getElementsByPixPositionsFromDump.js +72 -0
  72. package/src/server/lib/guest.json +9 -0
  73. package/src/server/lib/initialAppSettings.json +18 -0
  74. package/src/server/lib/logger.js +95 -0
  75. package/src/server/lib/onStart.js +53 -0
  76. package/src/server/lib/parseDiff.js.bak +72 -0
  77. package/src/server/lib/testAdmin.json +9 -0
  78. package/src/server/lib/testUsers.json +41 -0
  79. package/src/server/middlewares/authorization.js +50 -0
  80. package/src/server/middlewares/disableCors.js +19 -0
  81. package/src/server/models/index.js +534 -0
  82. package/src/server/models/plugins/index.js +3 -0
  83. package/src/server/models/plugins/paginate.plugin.js +83 -0
  84. package/src/server/models/plugins/paginateDistinct.plugin.js +80 -0
  85. package/src/server/models/plugins/toJSON.plugin.js +44 -0
  86. package/src/server/routes/ui/admin.js +20 -0
  87. package/src/server/routes/ui/auth.js +15 -0
  88. package/src/server/routes/ui/index.js +19 -0
  89. package/src/server/routes/v1/app.route.js +9 -0
  90. package/src/server/routes/v1/auth.route.js +12 -0
  91. package/src/server/routes/v1/baselines.route.js +14 -0
  92. package/src/server/routes/v1/checks.route.js +25 -0
  93. package/src/server/routes/v1/client.route.js +39 -0
  94. package/src/server/routes/v1/index.js +82 -0
  95. package/src/server/routes/v1/logs.route.js +16 -0
  96. package/src/server/routes/v1/runs.route.js +15 -0
  97. package/src/server/routes/v1/settings.route.js +23 -0
  98. package/src/server/routes/v1/snapshots.route.js +11 -0
  99. package/src/server/routes/v1/suites.route.js +15 -0
  100. package/src/server/routes/v1/tasks.route.js +59 -0
  101. package/src/server/routes/v1/test.route.js +20 -0
  102. package/src/server/routes/v1/test_distinct.route.js +14 -0
  103. package/src/server/routes/v1/users.route.js +36 -0
  104. package/src/server/schemas/createCheck.shema.ts +17 -0
  105. package/src/server/schemas/getBaseline.shema.ts +12 -0
  106. package/src/server/services/app.service.js +23 -0
  107. package/src/server/services/check.service.js +178 -0
  108. package/src/server/services/client.service.js +648 -0
  109. package/src/server/services/generic.service.js +51 -0
  110. package/src/server/services/index.js +12 -0
  111. package/src/server/services/logs.service.js +38 -0
  112. package/src/server/services/run.service.js +40 -0
  113. package/src/server/services/suite.service.js +39 -0
  114. package/src/server/services/tasks.service.js +536 -0
  115. package/src/server/services/test.service.js +72 -0
  116. package/src/server/services/user.service.js +128 -0
  117. package/src/server/utils/ApiError.js +14 -0
  118. package/src/server/utils/catchAsync.js +8 -0
  119. package/src/server/utils/check.js +58 -0
  120. package/src/server/utils/dateToISO8601.js +2 -0
  121. package/src/server/utils/deserializeIfJSON.js +9 -0
  122. package/src/server/utils/formatISOToDateTime.js +6 -0
  123. package/src/server/utils/index.js +10 -0
  124. package/src/server/utils/isJSON.js +6 -0
  125. package/src/server/utils/paramsGuard.ts +15 -0
  126. package/src/server/utils/pick.js +15 -0
  127. package/src/server/utils/prettyCheckParams.js +13 -0
  128. package/src/server/utils/snapshots.js +73 -0
  129. package/src/server/utils/subDays.js +7 -0
  130. package/src/server/utils/tests.js +36 -0
  131. package/src/server/utils/utils.js +146 -0
  132. package/src/tasks/backup.js.bak +84 -0
  133. package/src/tasks/backup.ts +53 -0
  134. package/src/tasks/lib/common.js +24 -0
  135. package/src/tasks/lib/utils.js +15 -0
  136. package/src/tasks/migrations/2.0.migration.js +86 -0
  137. package/src/tasks/migrations/2.0.migration.ts +95 -0
  138. package/src/tasks/migrations/2.0.migration_mql.js +63 -0
  139. package/src/tasks/reindex.js +36 -0
  140. package/src/tasks/restore.js.bak +100 -0
  141. package/src/tasks/restore.ts +75 -0
  142. package/src/ui-app/.eslintrc.json +119 -0
  143. package/src/ui-app/README.md +15 -0
  144. package/src/ui-app/admin/AdminLayout.tsx +38 -0
  145. package/src/ui-app/admin/App.tsx +108 -0
  146. package/src/ui-app/admin/AppContext.ts +3 -0
  147. package/src/ui-app/admin/components/Header/AdminHeader.tsx +148 -0
  148. package/src/ui-app/admin/components/Logs/AdminLogs.tsx +142 -0
  149. package/src/ui-app/admin/components/Logs/RefreshActionIcon.tsx +60 -0
  150. package/src/ui-app/admin/components/Logs/Table/AdminLogsTable.tsx +81 -0
  151. package/src/ui-app/admin/components/Logs/Table/AdminLogsTableFilter.tsx +170 -0
  152. package/src/ui-app/admin/components/Logs/Table/AdminLogsTableHeads.tsx +50 -0
  153. package/src/ui-app/admin/components/Logs/Table/AdminLogsTableRows.tsx +207 -0
  154. package/src/ui-app/admin/components/Logs/Table/AdminLogsTableSettings.tsx +95 -0
  155. package/src/ui-app/admin/components/Logs/Table/InfinityScrollSkeleton.tsx +77 -0
  156. package/src/ui-app/admin/components/Logs/Table/InfinityScrollSkeletonFIller.tsx +57 -0
  157. package/src/ui-app/admin/components/Logs/Table/PagesCountAffix.tsx +61 -0
  158. package/src/ui-app/admin/components/Logs/Table/adminLogsCreateStyle.tsx +36 -0
  159. package/src/ui-app/admin/components/Logs/Table/adminLogsTableColumns.ts +52 -0
  160. package/src/ui-app/admin/components/Logs/UnfoldActionIcon.tsx +39 -0
  161. package/src/ui-app/admin/components/Navbar/AdminNavbar.tsx +50 -0
  162. package/src/ui-app/admin/components/Navbar/NavbarLinksGroup.tsx +104 -0
  163. package/src/ui-app/admin/components/Settings/AdminSettings.tsx +51 -0
  164. package/src/ui-app/admin/components/Settings/Forms/Boolean.tsx +59 -0
  165. package/src/ui-app/admin/components/Settings/Forms/FormWrapper.tsx +45 -0
  166. package/src/ui-app/admin/components/Settings/Forms/index.tsx +5 -0
  167. package/src/ui-app/admin/components/Settings/Forms/interfaces.tsx +17 -0
  168. package/src/ui-app/admin/components/Tasks/Task.tsx +138 -0
  169. package/src/ui-app/admin/components/Tasks/TaskWrapper.tsx +11 -0
  170. package/src/ui-app/admin/components/Tasks/tasksList.ts +59 -0
  171. package/src/ui-app/admin/components/Users/AdminUsers.tsx +182 -0
  172. package/src/ui-app/admin/components/Users/UserAddForm.tsx +137 -0
  173. package/src/ui-app/admin/components/Users/UserForm.tsx +196 -0
  174. package/src/ui-app/admin/hooks/useParams.tsx +18 -0
  175. package/src/ui-app/admin/index.html +17 -0
  176. package/src/ui-app/admin/main.tsx +24 -0
  177. package/src/ui-app/asserts/css/auth/index.css +23 -0
  178. package/src/ui-app/asserts/css/styles.css +36 -0
  179. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-100.eot +0 -0
  180. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-100.svg +313 -0
  181. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-100.ttf +0 -0
  182. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-100.woff +0 -0
  183. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-100.woff2 +0 -0
  184. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-500.eot +0 -0
  185. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-500.svg +305 -0
  186. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-500.ttf +0 -0
  187. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-500.woff +0 -0
  188. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-500.woff2 +0 -0
  189. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-700.eot +0 -0
  190. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-700.svg +309 -0
  191. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-700.ttf +0 -0
  192. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-700.woff +0 -0
  193. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-700.woff2 +0 -0
  194. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-regular.eot +0 -0
  195. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-regular.svg +308 -0
  196. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-regular.ttf +0 -0
  197. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-regular.woff +0 -0
  198. package/src/ui-app/asserts/fonts/roboto/roboto-v30-latin-regular.woff2 +0 -0
  199. package/src/ui-app/asserts/images/background.jpg +0 -0
  200. package/src/ui-app/asserts/images/bg_2_0_dark_L2.png +0 -0
  201. package/src/ui-app/asserts/images/favicon.svg +7 -0
  202. package/src/ui-app/auth/App.tsx +82 -0
  203. package/src/ui-app/auth/commonStyles.tsx +26 -0
  204. package/src/ui-app/auth/components/AuthFooter.tsx +51 -0
  205. package/src/ui-app/auth/components/AuthLogo.tsx +58 -0
  206. package/src/ui-app/auth/components/ChangePasswordForm.tsx +216 -0
  207. package/src/ui-app/auth/components/ChangePasswordSuccessForm.tsx +38 -0
  208. package/src/ui-app/auth/components/LoginForm.tsx +148 -0
  209. package/src/ui-app/auth/components/LogoutForm.tsx +89 -0
  210. package/src/ui-app/auth/components/ToggleThemeButton.tsx +41 -0
  211. package/src/ui-app/auth/components/change-password/Bars.tsx +45 -0
  212. package/src/ui-app/auth/components/change-password/PasswordRequirement.tsx +14 -0
  213. package/src/ui-app/auth/components/change-password/requirements.tsx +6 -0
  214. package/src/ui-app/auth/index.html +17 -0
  215. package/src/ui-app/auth/main.tsx +12 -0
  216. package/src/ui-app/auth/routes.tsx +26 -0
  217. package/src/ui-app/config.ts +15 -0
  218. package/src/ui-app/index.html +12 -0
  219. package/src/ui-app/index2/App.tsx +162 -0
  220. package/src/ui-app/index2/AppContext.ts +3 -0
  221. package/src/ui-app/index2/IndexLayout.tsx +34 -0
  222. package/src/ui-app/index2/components/Header/HeaderIndex.tsx +248 -0
  223. package/src/ui-app/index2/components/Header/QuickFilter.tsx +312 -0
  224. package/src/ui-app/index2/components/Navbar/Items/AcceptStatusItem.tsx +42 -0
  225. package/src/ui-app/index2/components/Navbar/Items/BaseItemWrapper.tsx +94 -0
  226. package/src/ui-app/index2/components/Navbar/Items/BrowserItem.tsx +42 -0
  227. package/src/ui-app/index2/components/Navbar/Items/PlatformItem.tsx +42 -0
  228. package/src/ui-app/index2/components/Navbar/Items/RemoveItemModalAsk.tsx +71 -0
  229. package/src/ui-app/index2/components/Navbar/Items/RemoveItemPopover.tsx +58 -0
  230. package/src/ui-app/index2/components/Navbar/Items/RemoveSuiteModalAsk.tsx +61 -0
  231. package/src/ui-app/index2/components/Navbar/Items/RunItem.tsx +149 -0
  232. package/src/ui-app/index2/components/Navbar/Items/StatusItem.tsx +42 -0
  233. package/src/ui-app/index2/components/Navbar/Items/SuiteItem.tsx +109 -0
  234. package/src/ui-app/index2/components/Navbar/Items/index.tsx +6 -0
  235. package/src/ui-app/index2/components/Navbar/NavbarFilter.tsx +93 -0
  236. package/src/ui-app/index2/components/Navbar/NavbarGroupBySelect.tsx +83 -0
  237. package/src/ui-app/index2/components/Navbar/NavbarIndex.tsx +247 -0
  238. package/src/ui-app/index2/components/Navbar/NavbarItems.tsx +38 -0
  239. package/src/ui-app/index2/components/Navbar/NavbarSort.tsx +105 -0
  240. package/src/ui-app/index2/components/Navbar/Skeletons/RunsDummySkeleton.tsx +27 -0
  241. package/src/ui-app/index2/components/Navbar/Skeletons/SimpleDummySkeleton.tsx +23 -0
  242. package/src/ui-app/index2/components/Navbar/Skeletons/SkeletonWrapper.tsx +45 -0
  243. package/src/ui-app/index2/components/Navbar/Skeletons/SuitesDummySkeleton.tsx +27 -0
  244. package/src/ui-app/index2/components/Tests/Table/AcceptTestModalAsk.tsx +68 -0
  245. package/src/ui-app/index2/components/Tests/Table/AcceptTestsButton.tsx +44 -0
  246. package/src/ui-app/index2/components/Tests/Table/Cells/Branch.tsx +35 -0
  247. package/src/ui-app/index2/components/Tests/Table/Cells/BrowserName.tsx +33 -0
  248. package/src/ui-app/index2/components/Tests/Table/Cells/BrowserVersion.tsx +31 -0
  249. package/src/ui-app/index2/components/Tests/Table/Cells/CellWrapper.tsx +49 -0
  250. package/src/ui-app/index2/components/Tests/Table/Cells/Os.tsx +32 -0
  251. package/src/ui-app/index2/components/Tests/Table/Cells/StartDate.tsx +34 -0
  252. package/src/ui-app/index2/components/Tests/Table/Cells/Status.tsx +50 -0
  253. package/src/ui-app/index2/components/Tests/Table/Cells/ViewPort.tsx +46 -0
  254. package/src/ui-app/index2/components/Tests/Table/Checks/AcceptButton.tsx +142 -0
  255. package/src/ui-app/index2/components/Tests/Table/Checks/Check.tsx +281 -0
  256. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Canvas/Canvas.tsx +36 -0
  257. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Canvas/helpers.ts +72 -0
  258. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Canvas/mainView.ts +495 -0
  259. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Canvas/sideToSideView.ts +398 -0
  260. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Canvas/simpleView.ts +21 -0
  261. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/CheckDetails.tsx +237 -0
  262. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Header.tsx +221 -0
  263. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/RelatedChecks/RelatedCheckItem.tsx +167 -0
  264. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/RelatedChecks/RelatedCheckSort.tsx +81 -0
  265. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/RelatedChecks/RelatedChecks.tsx +197 -0
  266. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/RelatedChecks/RelatedChecksItems.tsx +31 -0
  267. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/RelatedChecks/RelatedChecksSkeleton.tsx +37 -0
  268. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Toolbar/HighlightButton.tsx +56 -0
  269. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Toolbar/RegionsToolbar.tsx +150 -0
  270. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Toolbar/ScreenshotDetails.tsx +137 -0
  271. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Toolbar/Toolbar.tsx +101 -0
  272. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Toolbar/ViewSegmentedControl.tsx +159 -0
  273. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Toolbar/ZoomToolbar.tsx +326 -0
  274. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/Toolbar/highlightDiff.ts +167 -0
  275. package/src/ui-app/index2/components/Tests/Table/Checks/CheckDetails/hooks/useRelatedChecks.tsx +43 -0
  276. package/src/ui-app/index2/components/Tests/Table/Checks/CheckModal.tsx +119 -0
  277. package/src/ui-app/index2/components/Tests/Table/Checks/Checks.tsx +91 -0
  278. package/src/ui-app/index2/components/Tests/Table/Checks/ChecksSkeleton.tsx +21 -0
  279. package/src/ui-app/index2/components/Tests/Table/Checks/PreviewCheckTooltipLabel.tsx +121 -0
  280. package/src/ui-app/index2/components/Tests/Table/Checks/RemoveButton.tsx +63 -0
  281. package/src/ui-app/index2/components/Tests/Table/Checks/ViewPortLabel.tsx +94 -0
  282. package/src/ui-app/index2/components/Tests/Table/Checks/checkSizes.ts +27 -0
  283. package/src/ui-app/index2/components/Tests/Table/Filter.tsx +179 -0
  284. package/src/ui-app/index2/components/Tests/Table/Heads.tsx +54 -0
  285. package/src/ui-app/index2/components/Tests/Table/InfinityScrollSkeleton.tsx +71 -0
  286. package/src/ui-app/index2/components/Tests/Table/PagesCountAffix.tsx +61 -0
  287. package/src/ui-app/index2/components/Tests/Table/RefreshActionIcon.tsx +65 -0
  288. package/src/ui-app/index2/components/Tests/Table/RemoveTestModalAsk.tsx +66 -0
  289. package/src/ui-app/index2/components/Tests/Table/RemoveTestsButton.tsx +43 -0
  290. package/src/ui-app/index2/components/Tests/Table/Row.tsx +128 -0
  291. package/src/ui-app/index2/components/Tests/Table/Rows.tsx +87 -0
  292. package/src/ui-app/index2/components/Tests/Table/Settings.tsx +121 -0
  293. package/src/ui-app/index2/components/Tests/Table/TestsTable.tsx +140 -0
  294. package/src/ui-app/index2/components/Tests/Table/UnfoldActionIcon.tsx +39 -0
  295. package/src/ui-app/index2/components/Tests/Table/tableColumns.ts +80 -0
  296. package/src/ui-app/index2/components/Tests/Table/testsCreateStyle.tsx +35 -0
  297. package/src/ui-app/index2/components/Tests/Tests.tsx +157 -0
  298. package/src/ui-app/index2/hooks/useIndexSubpageEffect.tsx +14 -0
  299. package/src/ui-app/index2/hooks/useNavbarActiveItems.tsx +66 -0
  300. package/src/ui-app/index2/hooks/useParams.tsx +25 -0
  301. package/src/ui-app/index2/index.html +17 -0
  302. package/src/ui-app/index2/main.tsx +33 -0
  303. package/src/ui-app/package-lock.json +6150 -0
  304. package/src/ui-app/package.json +58 -0
  305. package/src/ui-app/shared/components/ActionPopoverIcon.tsx +116 -0
  306. package/src/ui-app/shared/components/Check/AcceptedStatusIcon.tsx +51 -0
  307. package/src/ui-app/shared/components/Check/BrowserIcon.tsx +50 -0
  308. package/src/ui-app/shared/components/Check/OsIcon.tsx +73 -0
  309. package/src/ui-app/shared/components/Check/Status.tsx +37 -0
  310. package/src/ui-app/shared/components/Check/StatusIcon.tsx +66 -0
  311. package/src/ui-app/shared/components/Email.tsx +83 -0
  312. package/src/ui-app/shared/components/Header/ApiKeyModalAsk.tsx +31 -0
  313. package/src/ui-app/shared/components/Header/ApiKeyModalResult.tsx +89 -0
  314. package/src/ui-app/shared/components/Header/HeaderLogo.tsx +82 -0
  315. package/src/ui-app/shared/components/Header/UserInfoModal.tsx +92 -0
  316. package/src/ui-app/shared/components/Header/UserMenu.tsx +151 -0
  317. package/src/ui-app/shared/components/Password.tsx +95 -0
  318. package/src/ui-app/shared/components/RelativeDrawer.tsx +43 -0
  319. package/src/ui-app/shared/components/SafeSelect.tsx +95 -0
  320. package/src/ui-app/shared/components/Tests/StatusesRing.tsx +66 -0
  321. package/src/ui-app/shared/components/ToggleThemeButton.tsx +33 -0
  322. package/src/ui-app/shared/components/Users/LabelUser.tsx +60 -0
  323. package/src/ui-app/shared/components/errors/ErrorFallback.tsx +66 -0
  324. package/src/ui-app/shared/components/filter/AcceptedFilter.tsx +20 -0
  325. package/src/ui-app/shared/components/filter/BrowserNameFilter.tsx +20 -0
  326. package/src/ui-app/shared/components/filter/CommonDistinctFilter.tsx +104 -0
  327. package/src/ui-app/shared/components/filter/DateFilter.tsx +54 -0
  328. package/src/ui-app/shared/components/filter/FilterWrapper.tsx +80 -0
  329. package/src/ui-app/shared/components/filter/IdFilter.tsx +60 -0
  330. package/src/ui-app/shared/components/filter/LogLevelFilter.tsx +77 -0
  331. package/src/ui-app/shared/components/filter/LogicalGroup.tsx +179 -0
  332. package/src/ui-app/shared/components/filter/OsFilter.tsx +20 -0
  333. package/src/ui-app/shared/components/filter/StatusFilter.tsx +20 -0
  334. package/src/ui-app/shared/components/filter/StringFilter.tsx +55 -0
  335. package/src/ui-app/shared/components/filter/index.ts +19 -0
  336. package/src/ui-app/shared/components/heaserLinks.tsx +4 -0
  337. package/src/ui-app/shared/hooks/index.ts +3 -0
  338. package/src/ui-app/shared/hooks/useColorSheme.ts +22 -0
  339. package/src/ui-app/shared/hooks/useDistinctLogQuery.tsx +33 -0
  340. package/src/ui-app/shared/hooks/useDistinctQuery.tsx +37 -0
  341. package/src/ui-app/shared/hooks/useInfinityScroll.tsx +163 -0
  342. package/src/ui-app/shared/hooks/useInfinityScrollRelatedChecks.tsx +60 -0
  343. package/src/ui-app/shared/hooks/useNavProgressFetchEffect.tsx +17 -0
  344. package/src/ui-app/shared/hooks/useSubpageEffect.tsx +28 -0
  345. package/src/ui-app/shared/hooks/user.hooks.ts +49 -0
  346. package/src/ui-app/shared/interfaces/ILog.tsx +13 -0
  347. package/src/ui-app/shared/interfaces/IUser.tsx +13 -0
  348. package/src/ui-app/shared/interfaces/logQueries.tsx +31 -0
  349. package/src/ui-app/shared/navigation/interfaces.tsx +7 -0
  350. package/src/ui-app/shared/navigation/navigationData.tsx +191 -0
  351. package/src/ui-app/shared/services/checks.service.ts +39 -0
  352. package/src/ui-app/shared/services/generic.service.ts +115 -0
  353. package/src/ui-app/shared/services/index.ts +6 -0
  354. package/src/ui-app/shared/services/runs.service.ts +20 -0
  355. package/src/ui-app/shared/services/suites.service.ts +20 -0
  356. package/src/ui-app/shared/services/tests.service.ts +39 -0
  357. package/src/ui-app/shared/services/users.service.ts +29 -0
  358. package/src/ui-app/shared/utils/Logger.ts +12 -0
  359. package/src/ui-app/shared/utils/SearchParams.ts +17 -0
  360. package/src/ui-app/shared/utils/filters.tsx +14 -0
  361. package/src/ui-app/shared/utils/index.ts +5 -0
  362. package/src/ui-app/shared/utils/utils.tsx +70 -0
  363. package/src/ui-app/stub.html +12 -0
  364. package/src/ui-app/stub.tsx +58 -0
  365. package/src/ui-app/stubDemoColors.tsx +47 -0
  366. package/src/ui-app/stubDemoNav.tsx +41 -0
  367. package/src/ui-app/tsconfig.json +21 -0
  368. package/src/ui-app/tsconfig.node.json +12 -0
  369. package/static/A.png +0 -0
  370. package/static/B.png +0 -0
  371. package/static/affected.html +39 -0
  372. package/static/affected_2.html +40 -0
  373. package/static/data/custom_devices.json +14 -0
  374. package/static/grids/desktop-higher.html +72 -0
  375. package/static/grids/desktop-wider.html +72 -0
  376. package/static/grids/desktop.html +61 -0
  377. package/static/grids/fit-in-view.html +62 -0
  378. package/static/js/canvasjs.min.js.bak +957 -0
  379. package/static/js/chart.js.bak +92 -0
  380. package/static/js/jquery-3.3.1.slim.js.bak +8269 -0
  381. package/static/js/jquery-3.3.1.slim.min.js.bak +2 -0
  382. package/static/js/moment.min.js.bak +2 -0
  383. package/static/low_diff_0.png +0 -0
  384. package/static/low_diff_1.png +0 -0
  385. package/static/vShift.png +0 -0
  386. package/static/vShift_bottom.png +0 -0
  387. package/static/vShift_top.png +0 -0
@@ -0,0 +1,84 @@
1
+ /* eslint-disable no-console */
2
+ // const inquirer = require('inquirer');
3
+ const inquirer2 = require('@inquirer/prompts');
4
+ const { input, confirm } = require('@inquirer/prompts');
5
+ console.log(inquirer2)
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const { execSync } = require('child_process');
10
+ const { config } = require('../../config');
11
+
12
+ const backupFolder = config.backupsFolder;
13
+ if (!fs.existsSync(backupFolder)) {
14
+ fs.mkdirSync(backupFolder, { recursive: true });
15
+ }
16
+
17
+ console.log('Please be sure that \'mongodump\', \'mongorestore\' and \'rsync\' tools are present in your system.');
18
+ const currDate = new Date().toLocaleString('en-US', { year: 'numeric', month: '2-digit', day: 'numeric' })
19
+ .replace(/[/]/gm, '_');
20
+ const backupSubFolder = `${currDate}_${Date.now()}`;
21
+
22
+ const answers = {
23
+ firstName: input({ message: "What's your first name?" }),
24
+ allowEmail: confirm({ message: 'Do you allow us to send you email?' }),
25
+ };
26
+
27
+ console.log(answers.firstName);
28
+
29
+ inquirer2
30
+ .confirm([
31
+ { type: 'string', name: 'folder', message: 'Enter the Backup Folder name Filename', default: backupSubFolder },
32
+ {
33
+ type: 'string',
34
+ name: 'connectionString',
35
+ message: 'Enter the Database Connection String URI',
36
+ default: config.connectionString,
37
+ },
38
+ {
39
+ type: 'string',
40
+ name: 'imagesPath',
41
+ message: 'Enter the Images Folder',
42
+ default: config.defaultImagesPath,
43
+ },
44
+ {
45
+ type: 'string',
46
+ name: 'confirm',
47
+ message: 'Continue? (y/N)',
48
+ },
49
+
50
+ ])
51
+ .then(async (answers) => {
52
+ const { confirm } = answers;
53
+
54
+ if (!confirm) return;
55
+
56
+ const fullBackupPath = path.join(backupFolder, answers.folder);
57
+
58
+ if (fs.existsSync(fullBackupPath)) {
59
+ console.log('The folder is already exists, please enter another folder ');
60
+ return;
61
+ }
62
+ fs.mkdirSync(fullBackupPath, { recursive: true });
63
+ const destDatabasePath = path.join(fullBackupPath, 'database');
64
+ fs.mkdirSync(destDatabasePath, { recursive: true });
65
+
66
+ const destImagesPath = path.join(fullBackupPath, 'images');
67
+ fs.mkdirSync(fullBackupPath, { recursive: true });
68
+
69
+ console.log('Backup the Database');
70
+ const dbDumpResult = execSync(`mongodump --uri=${answers.connectionString} --gzip --out ${destDatabasePath}`).toString();
71
+ console.log(dbDumpResult);
72
+
73
+ console.log('Backup the Images');
74
+ const imagesBackupResult = execSync(`rsync -vah --progress ${answers.imagesPath} ${destImagesPath}`)
75
+ .toString('utf8');
76
+ console.log(imagesBackupResult);
77
+ })
78
+ .catch((e) => {
79
+ if (e.isTtyError) {
80
+ console.log('cannot render the menu on this environment', e);
81
+ } else {
82
+ console.log(e);
83
+ }
84
+ });
@@ -0,0 +1,53 @@
1
+ import { input, confirm } from '@inquirer/prompts';
2
+ import * as fs from 'node:fs'
3
+ import * as path from 'node:path';
4
+ import { execSync } from 'child_process';
5
+ import { config } from '../../config';
6
+
7
+ const run = async () => {
8
+ const backupFolder: string = config.backupsFolder;
9
+ if (!fs.existsSync(backupFolder)) {
10
+ fs.mkdirSync(backupFolder, { recursive: true });
11
+ }
12
+
13
+ console.log('Please be sure that \'mongodump\', \'mongorestore\' and \'rsync\' tools are present in your system.');
14
+ const currDate: string = new Date().toLocaleString('en-US', { year: 'numeric', month: '2-digit', day: 'numeric' })
15
+ .replace(/[/]/gm, '_');
16
+ const backupSubFolder: string = `${currDate}_${Date.now()}`;
17
+
18
+ const answers = {
19
+ folder: await input({ message: 'Enter the Backup Folder name Filename', default: backupSubFolder }),
20
+ connectionString: await input({ message: 'Enter the Database Connection String URI', default: config.connectionString }),
21
+ imagesPath: await input({ message: 'Enter the Images Folder Path', default: config.defaultImagesPath }),
22
+ confirm: await confirm({ message: 'Continue?' }),
23
+ };
24
+
25
+ if (!answers.confirm) {
26
+ return "Skipped"
27
+ }
28
+
29
+ const fullBackupPath: string = path.join(backupFolder, answers.folder);
30
+
31
+ if (fs.existsSync(fullBackupPath)) {
32
+ console.log('The folder is already exists, please enter another folder ');
33
+ return;
34
+ }
35
+ fs.mkdirSync(fullBackupPath, { recursive: true });
36
+ const destDatabasePath: string = path.join(fullBackupPath, 'database');
37
+ fs.mkdirSync(destDatabasePath, { recursive: true });
38
+
39
+ const destImagesPath: string = path.join(fullBackupPath, 'images');
40
+ fs.mkdirSync(fullBackupPath, { recursive: true });
41
+
42
+ console.log('Backup the Database');
43
+ const dbDumpResult: string = execSync(`mongodump --uri=${answers.connectionString} --gzip --out ${destDatabasePath}`).toString();
44
+ console.log(dbDumpResult);
45
+
46
+ console.log('Backup Images');
47
+ const imagesBackupResult: string = execSync(`rsync -vah --progress ${answers.imagesPath} ${destImagesPath}`)
48
+ .toString('utf8');
49
+ console.log(imagesBackupResult);
50
+ return '✅ Success'
51
+ }
52
+
53
+ run().then((result) => console.log(`operation complete: ${result}`));
@@ -0,0 +1,24 @@
1
+ const {
2
+ Snapshot,
3
+ Check,
4
+ Test,
5
+ Run,
6
+ App,
7
+ Suite,
8
+ User,
9
+ Baseline,
10
+ } = require('../../server/models');
11
+
12
+ // const url = 'mongodb://localhost/VRSdb';
13
+
14
+ module.exports = {
15
+ // url,
16
+ User,
17
+ Snapshot,
18
+ Check,
19
+ Test,
20
+ Run,
21
+ App,
22
+ Suite,
23
+ Baseline,
24
+ };
@@ -0,0 +1,15 @@
1
+ const mongoose = require('mongoose');
2
+ const { url } = require('./common');
3
+
4
+ const connect = async () => {
5
+ const connection = await mongoose.connect(url, {});
6
+ console.log(`Mongoose default connection open to: '${url}', models: '${Object.keys(connection.models)
7
+ .join(', ')}'`);
8
+ return connection;
9
+ };
10
+
11
+ module.exports.runMongoCode = async (cb) => {
12
+ await connect();
13
+ await cb();
14
+ await mongoose.connection.close();
15
+ };
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ /* eslint-disable no-await-in-loop,no-restricted-syntax */
3
+ require('../../server/models');
4
+ const utils = require('../lib/utils');
5
+ const { Check, Test, Run, Suite } = require('../lib/common');
6
+ async function task() {
7
+ await utils.runMongoCode(async () => {
8
+ try {
9
+ /**
10
+ * 0. fill test collection with 'checks' field array
11
+ * */
12
+ console.log('\nStage: 0');
13
+ const checks = await Check.find({});
14
+ // console.log(checks);
15
+ for (const check of checks) {
16
+ const testId = check.test;
17
+ const test = await Test.findOne({ _id: testId });
18
+ if (test && testId && !test.checks.map((x) => x.toString()).includes(check?._id.toString())) {
19
+ const newChecksArray = test.checks || [];
20
+ newChecksArray.push(check._id);
21
+ await test.update({ _id: test._id }, { $set: { checks: newChecksArray } });
22
+ await test.save();
23
+ process.stdout.write('.');
24
+ }
25
+ else {
26
+ process.stdout.write('x');
27
+ }
28
+ }
29
+ /**
30
+ * 1. fill test suite fields
31
+ * */
32
+ console.log('\nStage: 1');
33
+ const tests = await Test.find({});
34
+ for (const test of tests) {
35
+ // console.log(test.checks[0]);
36
+ const firstCheckId = test.checks[0];
37
+ if (firstCheckId) {
38
+ // @ts-ignore
39
+ const firstCheck = await Check.findOne({ _id: test.checks[0] });
40
+ if (firstCheck) {
41
+ const { suite } = firstCheck;
42
+ if (suite) {
43
+ test.suite = suite;
44
+ await Test.update({ _id: test._id }, { $set: { suite } });
45
+ }
46
+ }
47
+ }
48
+ else {
49
+ process.stdout.write('x');
50
+ }
51
+ process.stdout.write('.');
52
+ }
53
+ /**
54
+ * 2. set app id for runs and suites
55
+ * */
56
+ console.log('\nStage: 2');
57
+ for (const x of tests) {
58
+ const appId = x.app;
59
+ await Run.update({ _id: x.run }, { $set: { app: appId } });
60
+ await Suite.update({ _id: x.suite }, { $set: { app: appId } });
61
+ process.stdout.write('.');
62
+ }
63
+ /**
64
+ * 3. populate 'runs' and 'suites' with 'createdDate' field
65
+ * */
66
+ console.log('\nStage: 3');
67
+ const suites = await Suite.find({});
68
+ for (const x of suites) {
69
+ await Suite.update({ _id: x._id }, { $set: { createdDate: x._id.getTimestamp() } });
70
+ process.stdout.write('+');
71
+ }
72
+ const runs = await Run.find({});
73
+ for (const x of runs) {
74
+ await Run.update({ _id: x._id }, { $set: { createdDate: x._id.getTimestamp() } });
75
+ process.stdout.write('>');
76
+ }
77
+ }
78
+ catch (err) {
79
+ console.error(err);
80
+ }
81
+ finally {
82
+ console.log('\nDone');
83
+ }
84
+ });
85
+ }
86
+ task();
@@ -0,0 +1,95 @@
1
+ /* eslint-disable no-await-in-loop,no-restricted-syntax */
2
+ require('../../server/models');
3
+
4
+ const utils = require('../lib/utils');
5
+ const { Check, Test, Run, Suite } = require('../lib/common');
6
+
7
+ async function task() {
8
+ await utils.runMongoCode(async () => {
9
+ try {
10
+ /**
11
+ * 0. fill test collection with 'checks' field array
12
+ * */
13
+ console.log('\nStage: 0');
14
+
15
+ const checks = await Check.find({});
16
+ // console.log(checks);
17
+ for (const check of checks) {
18
+ const testId = check.test;
19
+ const test = await Test.findOne({ _id: testId });
20
+ if (test && testId && !test.checks.map((x: any) => x.toString()).includes(check?._id.toString())) {
21
+ const newChecksArray = test.checks || [];
22
+ newChecksArray.push(check._id);
23
+ await test.update({ _id: test._id }, { $set: { checks: newChecksArray } });
24
+ await test.save();
25
+ process.stdout.write('.');
26
+ } else {
27
+ process.stdout.write('x');
28
+ }
29
+ }
30
+
31
+ /**
32
+ * 1. fill test suite fields
33
+ * */
34
+ console.log('\nStage: 1');
35
+
36
+ const tests: any = await Test.find({});
37
+
38
+ for (const test of tests) {
39
+ // console.log(test.checks[0]);
40
+ const firstCheckId = test.checks[0];
41
+ if (firstCheckId) {
42
+ // @ts-ignore
43
+ const firstCheck = await Check.findOne({ _id: test.checks[0] });
44
+
45
+ if (firstCheck) {
46
+ const { suite } = firstCheck;
47
+ if (suite) {
48
+ test.suite = suite;
49
+ await Test.update({ _id: test._id }, { $set: { suite } });
50
+ }
51
+ }
52
+ } else {
53
+ process.stdout.write('x');
54
+ }
55
+ process.stdout.write('.');
56
+ }
57
+
58
+ /**
59
+ * 2. set app id for runs and suites
60
+ * */
61
+
62
+ console.log('\nStage: 2');
63
+
64
+ for (const x of tests) {
65
+ const appId = x.app;
66
+ await Run.update({ _id: x.run }, { $set: { app: appId } });
67
+ await Suite.update({ _id: x.suite }, { $set: { app: appId } });
68
+ process.stdout.write('.');
69
+ }
70
+
71
+ /**
72
+ * 3. populate 'runs' and 'suites' with 'createdDate' field
73
+ * */
74
+ console.log('\nStage: 3');
75
+
76
+ const suites = await Suite.find({});
77
+ for (const x of suites) {
78
+ await Suite.update({ _id: x._id }, { $set: { createdDate: x._id.getTimestamp() } });
79
+ process.stdout.write('+');
80
+ }
81
+
82
+ const runs = await Run.find({});
83
+ for (const x of runs) {
84
+ await Run.update({ _id: x._id }, { $set: { createdDate: x._id.getTimestamp() } });
85
+ process.stdout.write('>');
86
+ }
87
+ } catch (err) {
88
+ console.error(err);
89
+ } finally {
90
+ console.log('\nDone');
91
+ }
92
+ });
93
+ }
94
+
95
+ task();
@@ -0,0 +1,63 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * 0. fill test collection with 'checks' field array
4
+ **/
5
+ const checks = db.vrschecks.find({}).toArray();
6
+
7
+ for (const check of checks) {
8
+ const testId = check.test;
9
+ if (testId) {
10
+ const test = db.vrstests.findOne({ _id: testId });
11
+ const newChecksArray = test.checks || [];
12
+ newChecksArray.push(check._id);
13
+ db.vrstests.update({ _id: test._id }, { $set: { "checks": newChecksArray } });
14
+ }
15
+ }
16
+
17
+ /**
18
+ * 1. fill test suite fields
19
+ **/
20
+ const tests = db.vrstests.find({}).toArray();
21
+
22
+ tests.forEach((test) => {
23
+ console.log(test.checks[0]);
24
+ const firstCheckId = test.checks[0];
25
+ if (firstCheckId) {
26
+ const firstCheck = db.vrschecks.findOne({ _id: test.checks[0] });
27
+
28
+ if (firstCheck) {
29
+ const suite = firstCheck.suite;
30
+ if (suite) {
31
+ test.suite = suite;
32
+ }
33
+ }
34
+ }
35
+ else {
36
+ console.log('Cannot find checks')
37
+ }
38
+ })
39
+
40
+ /**
41
+ * 2. set app id for runs and suites
42
+ **/
43
+ db.vrstests.find({}).forEach((x) => {
44
+ const appId = x.app;
45
+ console.log({ appId });
46
+ db.vrsruns.update({ _id: x.run }, { $set: { "app": appId } });
47
+ db.vrssuites.update({ _id: x.suite }, { $set: { "app": appId } });
48
+ })
49
+
50
+ /**
51
+ * 3. populate 'runs' and 'suites' with 'createdDate' field
52
+ **/
53
+ db.vrssuites.find({}).forEach((x) => {
54
+ // x.createdDate = x._id.getTimestamp();
55
+ db.vrssuites.update({ _id: x._id }, { $set: { "createdDate": x._id.getTimestamp() } });
56
+ console.log(x.updatedDate);
57
+ })
58
+
59
+ db.vrsruns.find({}).forEach((x) => {
60
+ // x.createdDate = x._id.getTimestamp();
61
+ db.vrsruns.update({ _id: x._id }, { $set: { "createdDate": x._id.getTimestamp() } });
62
+ console.log(x.updatedDate);
63
+ })
@@ -0,0 +1,36 @@
1
+ require('../server/models');
2
+ const utils = require('./lib/utils');
3
+ const {
4
+ User, Snapshot, Check, Test, Run, Log, App, Suite, Baseline,
5
+ } = require('./lib/common');
6
+
7
+ (async () => {
8
+ await utils.runMongoCode(() => {
9
+ return new Promise(async (resolve, reject) => {
10
+ const result = [];
11
+ [User, Snapshot, Check, Test, Run, Log, App, Suite, Baseline].forEach((model) => {
12
+ result.push(model.collection.dropIndexes()
13
+ .then(
14
+ () => {
15
+ console.log(`Drop: '${model.collection.name}'`);
16
+ }
17
+ )
18
+ .catch((err) => {
19
+ console.log(`Cannot drop index '${model.collection.name}', error: '${err}' `);
20
+ })
21
+ );
22
+ });
23
+
24
+ return resolve(
25
+ await Promise.all(result)
26
+ .catch((err) => {
27
+ console.log('ERROR:');
28
+ console.error(err);
29
+ })
30
+ .then(() => {
31
+ console.log('End of reindex task');
32
+ })
33
+ );
34
+ });
35
+ });
36
+ })();
@@ -0,0 +1,100 @@
1
+ /* eslint-disable no-console */
2
+ const inquirer = require('inquirer');
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { execSync } = require('child_process');
6
+ const { config } = require('../../config');
7
+
8
+ const backupFolder = config.backupsFolder;
9
+ if (!fs.existsSync(backupFolder)) {
10
+ fs.mkdirSync(backupFolder, { recursive: true });
11
+ }
12
+
13
+ console.log('Be sure that Application is down and \'mongodump\', \'mongorestore\' and \'rsync\' tools are present in your system.');
14
+
15
+ const backupsFolders = fs.readdirSync(backupFolder, { withFileTypes: true })
16
+ .filter((x) => x.isDirectory())
17
+ .map((x) => x.name);
18
+
19
+ const questions = [
20
+ {
21
+ type: 'list',
22
+ name: 'backupSubFolder',
23
+ message: 'Choose the Backup Folder',
24
+ choices: backupsFolders,
25
+
26
+ },
27
+ {
28
+ type: 'string',
29
+ name: 'destConnectionString',
30
+ message: 'Enter the Destination Database Connection String URI',
31
+ default: config.connectionString,
32
+ },
33
+ {
34
+ type: 'string',
35
+ name: 'destImagesSubFolder',
36
+ message: 'Enter the Destination Images Folder',
37
+ default: config.defaultImagesPath,
38
+ },
39
+ {
40
+ type: 'string',
41
+ name: 'confirm',
42
+ message: '⚠️ Caution! All current Application Data will be removed, before the Restoring! Continue? (y/N)',
43
+ },
44
+ ];
45
+
46
+ inquirer
47
+ .prompt(questions)
48
+ .then(async (answers) => {
49
+ console.log({ answers });
50
+ if (!answers.confirm) return;
51
+
52
+ const fullBackupPath = path.join(backupFolder, answers.backupSubFolder);
53
+ console.log({ fullBackupPath });
54
+
55
+ const fullSourceDatabasePath = path.join(fullBackupPath, 'database');
56
+ if (!fs.existsSync(fullSourceDatabasePath)) {
57
+ console.log('The Source Database Folder is not exists, please select tha another folder');
58
+ return;
59
+ }
60
+
61
+ const fullSourceImagesPath = path.join(fullBackupPath, 'images');
62
+ if (!fs.existsSync(fullSourceImagesPath)) {
63
+ console.log('The Source Images Folder is not exists, please select tha another folder');
64
+ return;
65
+ }
66
+
67
+ if (!fs.existsSync(answers.destImagesSubFolder)) {
68
+ console.log('The Destination Images Folder is not exists, please select tha another folder');
69
+ return;
70
+ }
71
+
72
+ console.log('Remove the Destination Database');
73
+ const removeDbResult = execSync(`mongosh '${answers.destConnectionString}' --eval "db.dropDatabase();"`)
74
+ .toString();
75
+ console.log(removeDbResult);
76
+
77
+ console.log('Restore the Database');
78
+ const restoreDbResult = execSync(`mongorestore --uri ${answers.destConnectionString} --gzip ${fullSourceDatabasePath}/*`)
79
+ .toString();
80
+ console.log(restoreDbResult);
81
+
82
+ console.log('Clean the Destination Images Folder');
83
+ // eslint-disable-next-line max-len
84
+ const removeImagesResult = execSync(`ls ${answers.destImagesSubFolder};rm -rfv ${answers.destImagesSubFolder} && mkdir ${answers.destImagesSubFolder}`)
85
+ .toString();
86
+ console.log(removeImagesResult);
87
+
88
+ console.log('Restore the Images');
89
+ console.log({ fullSourceImagesPath });
90
+ const restoreImagesResult = execSync(`rsync -vah --progress ${fullSourceImagesPath}/ ${answers.destImagesSubFolder}`)
91
+ .toString('utf8');
92
+ console.log(restoreImagesResult);
93
+ })
94
+ .catch((e) => {
95
+ if (e.isTtyError) {
96
+ console.log('cannot render the menu on this environment', e);
97
+ } else {
98
+ console.log(e);
99
+ }
100
+ });
@@ -0,0 +1,75 @@
1
+ /* eslint-disable no-console */
2
+ import { input, confirm, select } from '@inquirer/prompts';
3
+ import * as fs from 'node:fs'
4
+ import * as path from 'node:path';
5
+ import { execSync } from 'child_process';
6
+ import { config } from '../../config';
7
+
8
+ const run = async () => {
9
+ const backupFolder = config.backupsFolder;
10
+ if (!fs.existsSync(backupFolder)) {
11
+ fs.mkdirSync(backupFolder, { recursive: true });
12
+ }
13
+
14
+ console.log('Be sure that Application is down and \'mongodump\', \'mongorestore\' and \'rsync\' tools are present in your system.');
15
+
16
+ const backupsFolders = fs.readdirSync(backupFolder, { withFileTypes: true })
17
+ .filter((x) => x.isDirectory())
18
+ .map((x) => ({ name: x.name, value: x.name }));
19
+
20
+ const answers = {
21
+ backupSubFolder: await select({ message: 'Enter the Backup Folder name Filename', choices: backupsFolders }),
22
+ destConnectionString: await input({ message: 'Enter the Destination Database Connection String URI', default: config.connectionString }),
23
+ destImagesSubFolder: await input({ message: 'Enter the Images Folder Path', default: config.defaultImagesPath }),
24
+ confirm: await confirm({ message: '⚠️ Caution! All current Application Data will be removed, before the Restoring! Continue?', default: false }),
25
+ };
26
+
27
+ if (!answers.confirm) {
28
+ return 'Skipped'
29
+ }
30
+ const fullBackupPath = path.join(backupFolder, answers.backupSubFolder);
31
+ console.log({ fullBackupPath });
32
+
33
+ const fullSourceDatabasePath = path.join(fullBackupPath, 'database');
34
+ if (!fs.existsSync(fullSourceDatabasePath)) {
35
+ console.log('The Source Database Folder is not exists, please select tha another folder');
36
+ return;
37
+ }
38
+
39
+ const fullSourceImagesPath = path.join(fullBackupPath, 'images');
40
+ if (!fs.existsSync(fullSourceImagesPath)) {
41
+ console.log('The Source Images Folder is not exists, please select tha another folder');
42
+ return;
43
+ }
44
+
45
+ if (!fs.existsSync(answers.destImagesSubFolder)) {
46
+ console.log('The Destination Images Folder is not exists, please select tha another folder');
47
+ return;
48
+ }
49
+
50
+ console.log('Remove the Destination Database');
51
+ const removeDbResult = execSync(`mongosh '${answers.destConnectionString}' --eval "db.dropDatabase();"`)
52
+ .toString();
53
+ console.log(removeDbResult);
54
+
55
+ console.log('Restore the Database');
56
+ const restoreDbResult = execSync(`mongorestore --uri ${answers.destConnectionString} --gzip ${fullSourceDatabasePath}/*`)
57
+ .toString();
58
+ console.log(restoreDbResult);
59
+
60
+ console.log('Clean the Destination Images Folder');
61
+ // eslint-disable-next-line max-len
62
+ const removeImagesResult = execSync(`ls ${answers.destImagesSubFolder};rm -rfv ${answers.destImagesSubFolder} && mkdir ${answers.destImagesSubFolder}`)
63
+ .toString();
64
+ console.log(removeImagesResult);
65
+
66
+ console.log('Restore the Images');
67
+ console.log({ fullSourceImagesPath });
68
+ const restoreImagesResult = execSync(`rsync -vah --progress ${fullSourceImagesPath}/ ${answers.destImagesSubFolder}`)
69
+ .toString('utf8');
70
+ console.log(restoreImagesResult);
71
+
72
+ return '✅ Success'
73
+ }
74
+
75
+ run().then((result) => console.log(`operation complete: ${result}`));