@underpostnet/cyberia 3.3.0 → 3.3.76

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 (568) hide show
  1. package/.dockerignore +1 -0
  2. package/.env.example +17 -5
  3. package/.github/workflows/coverall.cyberia.ci.yml +39 -14
  4. package/.github/workflows/cyberia-client.cd.yml +5 -0
  5. package/.github/workflows/cyberia-server.cd.yml +5 -0
  6. package/.github/workflows/docker-image.cyberia-client.ci.yml +8 -5
  7. package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +8 -3
  8. package/.github/workflows/docker-image.cyberia-server.ci.yml +8 -5
  9. package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +8 -5
  10. package/.github/workflows/docker-image.engine-cyberia.ci.yml +15 -1
  11. package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +15 -1
  12. package/.github/workflows/engine-cyberia.cd.yml +3 -0
  13. package/.github/workflows/engine-cyberia.ci.yml +4 -5
  14. package/.github/workflows/ghpkg.ci.yml +35 -20
  15. package/.github/workflows/hardhat.ci.yml +12 -11
  16. package/.github/workflows/npmpkg.ci.yml +17 -15
  17. package/.github/workflows/publish.cyberia.ci.yml +44 -0
  18. package/.github/workflows/pwa-microservices-template-test.ci.yml +2 -2
  19. package/.github/workflows/release.cd.yml +1 -0
  20. package/.prettierignore +1 -0
  21. package/AGENTS.md +96 -0
  22. package/CHANGELOG.md +653 -2513
  23. package/CLI-HELP.md +323 -157
  24. package/Dockerfile +25 -9
  25. package/Dockerfile.dev +25 -9
  26. package/Dockerfile.test +5 -5
  27. package/README.md +48 -28
  28. package/bin/build.js +86 -41
  29. package/bin/build.template.js +8 -3
  30. package/bin/cyberia.js +1494 -1403
  31. package/bin/deploy.js +18 -104
  32. package/bin/index.js +1494 -1403
  33. package/compose.env +17 -5
  34. package/conf.js +98 -7
  35. package/deploy/cyberia-client/deploy.sh +46 -0
  36. package/deploy/cyberia-client/package.sh +17 -0
  37. package/deploy/cyberia-client/state.sh +15 -0
  38. package/deploy/cyberia-server/deploy.sh +46 -0
  39. package/deploy/cyberia-server/package.sh +17 -0
  40. package/deploy/cyberia-server/state.sh +15 -0
  41. package/deploy/dd-cyberia/deploy.sh +9 -29
  42. package/deploy/dd-cyberia/init.sh +38 -45
  43. package/deploy/dd-cyberia/package.sh +16 -0
  44. package/deploy/dd-cyberia/state.sh +14 -0
  45. package/deploy/dd-cyberia/sync-deploy.sh +133 -147
  46. package/deploy/lib/config.sh +29 -0
  47. package/deploy/lib/github-actions-logging.sh +610 -0
  48. package/deploy/lib/host.sh +194 -0
  49. package/deploy/lib/state.sh +65 -0
  50. package/deploy/pwa-microservices-template/deploy.sh +17 -42
  51. package/deploy/release/deploy.sh +9 -41
  52. package/deployment.yaml +7 -2
  53. package/docker-compose.yml +23 -17
  54. package/examples/static-page/README.md +19 -19
  55. package/examples/static-page/ssr-components/CustomPage.js +2 -2
  56. package/hardhat/hardhat.config.js +1 -6
  57. package/hardhat/package-lock.json +101 -40
  58. package/hardhat/package.json +2 -2
  59. package/manifests/alertmanager/deployment.yaml +81 -0
  60. package/manifests/blackbox-exporter/deployment.yaml +75 -0
  61. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +32 -7
  62. package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +32 -7
  63. package/manifests/deployment/dd-cyberia-development/deployment.yaml +7 -2
  64. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  65. package/manifests/deployment/mongo-express/deployment.yaml +46 -27
  66. package/manifests/deployment/mongo-express/kustomization.yaml +9 -0
  67. package/manifests/deployment/mongo-express/mongo-express-nodeport.yaml +18 -0
  68. package/manifests/deployment/mongo-express/service.yaml +16 -0
  69. package/manifests/deployment/mongo-express-no-auth/disable-mongodb-auth.yaml +16 -0
  70. package/manifests/deployment/mongo-express-no-auth/kustomization.yaml +16 -0
  71. package/manifests/grafana/deployment.yaml +26 -7
  72. package/manifests/grafana/kustomization.yaml +1 -0
  73. package/manifests/grafana/service.yaml +6 -1
  74. package/manifests/mariadb/pv.yaml +1 -0
  75. package/manifests/mongodb/statefulset.yaml +9 -2
  76. package/manifests/mysql/pv-pvc.yaml +14 -1
  77. package/manifests/postgresql/pv.yaml +12 -1
  78. package/manifests/postgresql/pvc.yaml +1 -0
  79. package/manifests/prometheus/deployment.yaml +18 -22
  80. package/package.json +87 -12
  81. package/scripts/event-monitor.sh +56 -0
  82. package/scripts/k3s-node-setup.sh +27 -14
  83. package/scripts/kubeadm-node-setup.sh +31 -11
  84. package/scripts/maas-setup.sh +8 -8
  85. package/scripts/selinux-normalize.sh +907 -0
  86. package/scripts/shutdown-machine.sh +843 -0
  87. package/scripts/test-monitor.sh +5 -5
  88. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +15 -10
  89. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +36 -5
  90. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +7 -2
  91. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +90 -186
  92. package/src/api/core/core.controller.js +1 -1
  93. package/src/api/core/core.router.js +2 -2
  94. package/src/api/core/core.service.js +2 -2
  95. package/src/api/crypto/crypto.controller.js +1 -1
  96. package/src/api/crypto/crypto.service.js +1 -1
  97. package/src/api/cyberia-action/cyberia-action.controller.js +1 -1
  98. package/src/api/cyberia-action/cyberia-action.router.js +3 -3
  99. package/src/api/cyberia-action/cyberia-action.service.js +5 -6
  100. package/src/api/cyberia-audio/cyberia-audio.controller.js +6 -0
  101. package/src/api/cyberia-audio/cyberia-audio.model.js +61 -0
  102. package/src/api/cyberia-audio/cyberia-audio.router.js +21 -0
  103. package/src/api/cyberia-audio/cyberia-audio.service.js +220 -0
  104. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +2 -4
  105. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +10 -19
  106. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +13 -35
  107. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +17 -34
  108. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +1 -1
  109. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +1 -1
  110. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +2 -2
  111. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +2 -2
  112. package/src/api/cyberia-entity/cyberia-entity.controller.js +1 -1
  113. package/src/api/cyberia-entity/cyberia-entity.model.js +2 -0
  114. package/src/api/cyberia-entity/cyberia-entity.router.js +1 -1
  115. package/src/api/cyberia-entity/cyberia-entity.service.js +3 -3
  116. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +8 -2
  117. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +31 -20
  118. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +17 -2
  119. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +468 -5
  120. package/src/api/cyberia-instance/cyberia-fallback-capture.js +502 -0
  121. package/src/api/cyberia-instance/cyberia-fallback-world.js +29 -40
  122. package/src/api/cyberia-instance/cyberia-instance-boot.service.js +5 -5
  123. package/src/api/cyberia-instance/cyberia-instance-items.js +98 -0
  124. package/src/api/cyberia-instance/cyberia-instance-map.service.js +35 -142
  125. package/src/api/cyberia-instance/cyberia-instance.controller.js +2 -5
  126. package/src/api/cyberia-instance/cyberia-instance.model.js +0 -14
  127. package/src/api/cyberia-instance/cyberia-instance.router.js +5 -18
  128. package/src/api/cyberia-instance/cyberia-instance.service.js +5 -45
  129. package/src/api/cyberia-instance/cyberia-world-generator.js +8 -13
  130. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +1 -1
  131. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +49 -75
  132. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +1 -1
  133. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +76 -3
  134. package/src/api/cyberia-map/cyberia-map.controller.js +1 -1
  135. package/src/api/cyberia-map/cyberia-map.router.js +1 -1
  136. package/src/api/cyberia-map/cyberia-map.service.js +8 -4
  137. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.controller.js +31 -0
  138. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.model.js +56 -0
  139. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.router.js +33 -0
  140. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +189 -0
  141. package/src/api/cyberia-quest/cyberia-quest.controller.js +1 -1
  142. package/src/api/cyberia-quest/cyberia-quest.router.js +4 -4
  143. package/src/api/cyberia-quest/cyberia-quest.service.js +5 -5
  144. package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +1 -1
  145. package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +1 -1
  146. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +1 -1
  147. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +2 -2
  148. package/src/api/cyberia-saga/cyberia-saga.controller.js +1 -1
  149. package/src/api/cyberia-saga/cyberia-saga.router.js +1 -1
  150. package/src/api/cyberia-saga/cyberia-saga.service.js +2 -2
  151. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +403 -214
  152. package/src/api/cyberia-skill/cyberia-skill.controller.js +1 -1
  153. package/src/api/cyberia-skill/cyberia-skill.model.js +6 -6
  154. package/src/api/cyberia-skill/cyberia-skill.router.js +1 -1
  155. package/src/api/cyberia-skill/cyberia-skill.service.js +2 -2
  156. package/src/api/default/default.controller.js +1 -1
  157. package/src/api/default/default.router.js +1 -1
  158. package/src/api/default/default.service.js +2 -2
  159. package/src/api/document/document.controller.js +1 -1
  160. package/src/api/document/document.router.js +1 -1
  161. package/src/api/document/document.service.js +2 -2
  162. package/src/api/file/file.controller.js +1 -1
  163. package/src/api/file/file.ref.js +153 -0
  164. package/src/api/file/file.ref.json +11 -2
  165. package/src/api/file/file.router.js +1 -1
  166. package/src/api/file/file.service.js +2 -2
  167. package/src/api/instance/instance.controller.js +1 -1
  168. package/src/api/instance/instance.router.js +1 -1
  169. package/src/api/instance/instance.service.js +2 -2
  170. package/src/api/ipfs/ipfs.controller.js +1 -1
  171. package/src/api/ipfs/ipfs.router.js +2 -2
  172. package/src/api/ipfs/ipfs.service.js +2 -2
  173. package/src/api/object-layer/object-layer.controller.js +1 -1
  174. package/src/api/object-layer/object-layer.model.js +47 -12
  175. package/src/api/object-layer/object-layer.router.js +12 -5
  176. package/src/api/object-layer/object-layer.service.js +116 -123
  177. package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +1 -1
  178. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +1 -1
  179. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +2 -2
  180. package/src/api/test/test.controller.js +1 -1
  181. package/src/api/test/test.service.js +1 -1
  182. package/src/api/user/guest.service.js +3 -3
  183. package/src/api/user/user.controller.js +1 -1
  184. package/src/api/user/user.router.js +2 -2
  185. package/src/api/user/user.service.js +4 -4
  186. package/src/api.js +5 -9
  187. package/src/cli/app.js +402 -0
  188. package/src/cli/baremetal.js +30 -35
  189. package/src/cli/client.js +306 -0
  190. package/src/cli/cloud-init.js +3 -3
  191. package/src/cli/cluster.js +191 -82
  192. package/src/cli/db.js +120 -68
  193. package/src/cli/deploy.js +157 -75
  194. package/src/cli/docker-compose.js +5 -5
  195. package/src/cli/domains.js +184 -0
  196. package/src/cli/dotenv-store.js +143 -0
  197. package/src/cli/event.js +2281 -0
  198. package/src/cli/fs-selection.js +115 -0
  199. package/src/cli/fs.js +159 -343
  200. package/src/cli/host.js +672 -0
  201. package/src/cli/image.js +4 -6
  202. package/src/cli/index.js +343 -151
  203. package/src/cli/ipfs.js +34 -30
  204. package/src/cli/kickstart.js +1 -1
  205. package/src/cli/kubectl.js +218 -41
  206. package/src/cli/lxd.js +3 -3
  207. package/src/cli/monitor.js +1359 -26
  208. package/src/cli/package.js +90 -0
  209. package/src/cli/release.js +16 -12
  210. package/src/cli/repository.js +586 -363
  211. package/src/cli/run.js +398 -843
  212. package/src/cli/secrets.js +2158 -964
  213. package/src/cli/ssh.js +478 -279
  214. package/src/cli/state.js +394 -0
  215. package/src/cli/static.js +2 -2
  216. package/src/cli/system.js +1 -1
  217. package/src/cli/test.js +203 -125
  218. package/src/cli/vultr.js +61 -21
  219. package/src/cli/wireguard.js +1112 -306
  220. package/src/client/components/core/CalendarCore.js +53 -96
  221. package/src/client/components/core/Docs.js +327 -303
  222. package/src/client/components/core/FileExplorer.js +0 -21
  223. package/src/client/components/core/Modal.js +56 -1
  224. package/src/client/components/core/PanelForm.js +4 -4
  225. package/src/client/components/core/Repository.js +56 -0
  226. package/src/client/components/core/Translate.js +7 -0
  227. package/src/client/components/core/{FullScreen.js → ViewModeController.js} +42 -39
  228. package/src/client/components/core/Wallet.js +0 -11
  229. package/src/client/components/core/Worker.js +7 -1
  230. package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +2 -2
  231. package/src/client/components/cyberia/ActionEngineCyberia.js +12 -36
  232. package/src/client/components/cyberia/EntityEngineCyberia.js +492 -121
  233. package/src/client/components/cyberia/InstanceEngineCyberia.js +129 -160
  234. package/src/client/components/cyberia/InstanceSelectionView.js +7 -1
  235. package/src/client/components/cyberia/MapEngineCyberia.js +175 -69
  236. package/src/client/components/cyberia/ObjectLayerEngine.js +1011 -97
  237. package/src/client/components/cyberia/ObjectLayerEngineModal.js +81 -155
  238. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +113 -98
  239. package/src/client/components/cyberia/SharedDefaultsCyberia.js +215 -56
  240. package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +2 -35
  241. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +1 -1
  242. package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +712 -76
  243. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +2 -2
  244. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +0 -4
  245. package/src/client/components/default/AppShellDefault.js +1 -1
  246. package/src/client/components/default/SettingsDefault.js +2 -2
  247. package/src/client/components/itemledger/SettingsItemledger.js +2 -2
  248. package/src/client/components/underpost/AppShellUnderpost.js +3 -2
  249. package/src/client/components/underpost/SettingsUnderpost.js +2 -2
  250. package/src/client/public/cyberia-docs/ARCHITECTURE.md +15 -15
  251. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +313 -30
  252. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +51 -29
  253. package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +52 -53
  254. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +16 -11
  255. package/src/client/public/cyberia-docs/CYBERIA.md +48 -28
  256. package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +11 -5
  257. package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +23 -6
  258. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  259. package/src/client/public/cyberia-docs/STATS-PROGRESSION.md +217 -0
  260. package/src/client/public/cyberia-docs/WHITE-PAPER.md +20 -12
  261. package/src/client/public/default/android-chrome-144x144.png +0 -0
  262. package/src/client/public/default/android-chrome-192x192.png +0 -0
  263. package/src/client/public/default/android-chrome-256x256.png +0 -0
  264. package/src/client/public/default/android-chrome-36x36.png +0 -0
  265. package/src/client/public/default/android-chrome-384x384.png +0 -0
  266. package/src/client/public/default/android-chrome-48x48.png +0 -0
  267. package/src/client/public/default/android-chrome-512x512.png +0 -0
  268. package/src/client/public/default/android-chrome-72x72.png +0 -0
  269. package/src/client/public/default/android-chrome-96x96.png +0 -0
  270. package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
  271. package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
  272. package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
  273. package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
  274. package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
  275. package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
  276. package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
  277. package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
  278. package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
  279. package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
  280. package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
  281. package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
  282. package/src/client/public/default/apple-touch-icon.png +0 -0
  283. package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
  284. package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
  285. package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
  286. package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
  287. package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
  288. package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
  289. package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
  290. package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
  291. package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
  292. package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
  293. package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
  294. package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
  295. package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
  296. package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
  297. package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
  298. package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
  299. package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
  300. package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
  301. package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
  302. package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
  303. package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
  304. package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
  305. package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
  306. package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
  307. package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
  308. package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
  309. package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
  310. package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
  311. package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
  312. package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
  313. package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
  314. package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
  315. package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
  316. package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
  317. package/src/client/public/default/assets/background/white.jpg +0 -0
  318. package/src/client/public/default/browserconfig.xml +1 -1
  319. package/src/client/public/default/favicon-16x16.png +0 -0
  320. package/src/client/public/default/favicon-32x32.png +0 -0
  321. package/src/client/public/default/favicon-48x48.png +0 -0
  322. package/src/client/public/default/favicon.ico +0 -0
  323. package/src/client/public/default/manifest.webmanifest +5 -5
  324. package/src/client/public/default/mstile-144x144.png +0 -0
  325. package/src/client/public/default/mstile-150x150.png +0 -0
  326. package/src/client/public/default/mstile-310x150.png +0 -0
  327. package/src/client/public/default/mstile-310x310.png +0 -0
  328. package/src/client/public/default/mstile-70x70.png +0 -0
  329. package/src/client/public/default/yandex-browser-50x50.png +0 -0
  330. package/src/client/public/default/yandex-browser-manifest.json +1 -1
  331. package/src/client/services/cyberia-audio/cyberia-audio.service.js +99 -0
  332. package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +38 -0
  333. package/src/client/services/cyberia-instance/cyberia-instance.management.js +5 -4
  334. package/src/client/services/cyberia-instance/cyberia-instance.service.js +0 -40
  335. package/src/client/services/cyberia-map/cyberia-map.management.js +5 -4
  336. package/src/client/services/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +138 -0
  337. package/src/client/services/object-layer/object-layer.management.js +6 -10
  338. package/src/client/services/object-layer/object-layer.service.js +3 -1
  339. package/src/client/ssr/RootDocument.js +1 -1
  340. package/src/client/ssr/body/404.js +1 -1
  341. package/src/client/ssr/body/500.js +1 -1
  342. package/src/client/ssr/body/CacheControl.js +1 -1
  343. package/src/client/ssr/body/CyberiaDefaultSplashScreen.js +1 -1
  344. package/src/client/ssr/body/DefaultSplashScreen.js +1 -1
  345. package/src/client/ssr/body/SwaggerDarkMode.js +1 -1
  346. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +1 -1
  347. package/src/client/ssr/head/CryptokoynScripts.js +1 -1
  348. package/src/client/ssr/head/Css.js +1 -1
  349. package/src/client/ssr/head/CyberiaPortalScripts.js +1 -1
  350. package/src/client/ssr/head/DefaultScripts.js +1 -1
  351. package/src/client/ssr/head/ItemledgerScripts.js +1 -1
  352. package/src/client/ssr/head/Microdata.js +1 -1
  353. package/src/client/ssr/head/Production.js +1 -1
  354. package/src/client/ssr/head/Pwa.js +1 -1
  355. package/src/client/ssr/head/PwaItemledger.js +1 -1
  356. package/src/client/ssr/head/Seo.js +1 -1
  357. package/src/client/ssr/head/UnderpostScripts.js +1 -1
  358. package/src/client/ssr/mailer/DefaultRecoverEmail.js +1 -1
  359. package/src/client/ssr/mailer/DefaultVerifyEmail.js +1 -1
  360. package/src/client/ssr/views/Cyberia404.js +7 -5
  361. package/src/client/ssr/views/CyberiaServerMetrics.js +1 -1
  362. package/src/client/ssr/views/Maintenance.js +1 -1
  363. package/src/client/ssr/views/NoNetworkConnection.js +1 -1
  364. package/src/client/ssr/views/Test.js +1 -1
  365. package/src/client/sw/core.sw.js +20 -14
  366. package/src/client-builder/client-build-docs.js +92 -77
  367. package/src/client-builder/client-build-live.js +2 -2
  368. package/src/client-builder/client-build.js +105 -74
  369. package/src/client-builder/client-bundle.js +347 -0
  370. package/src/client-builder/client-dev-server.js +3 -3
  371. package/src/client-builder/client-icons.js +2 -2
  372. package/src/client-builder/ssr.js +3 -3
  373. package/src/client.build.js +3 -6
  374. package/src/client.dev.js +3 -6
  375. package/src/db/DataBaseProvider.js +186 -3
  376. package/src/db/mariadb/MariaDB.js +3 -2
  377. package/src/db/mongo/MongoBootstrap.js +273 -101
  378. package/src/db/mongo/MongoExpress.js +187 -0
  379. package/src/db/mongo/MongooseDB.js +7 -8
  380. package/src/{server/valkey.js → db/valkey/Valkey.js} +5 -4
  381. package/src/grpc/cyberia/grpc-server.js +6 -8
  382. package/src/index.js +79 -23
  383. package/src/mailer/EmailRender.js +2 -2
  384. package/src/mailer/MailerInterceptor.js +87 -0
  385. package/src/mailer/MailerProvider.js +50 -6
  386. package/src/projects/cyberia/atlas-sprite-sheet-generator.js +144 -147
  387. package/src/projects/cyberia/atlas-sprite-sheet-store.js +391 -0
  388. package/src/projects/cyberia/besu-genesis-generator.js +8 -17
  389. package/src/projects/cyberia/boot-contract-fixtures.js +32 -0
  390. package/src/projects/cyberia/catalog-cyberia.js +54 -10
  391. package/src/projects/cyberia/gemini-client.js +4 -4
  392. package/src/projects/cyberia/generate-saga.js +5 -12
  393. package/src/projects/cyberia/hot-reload-trigger.js +18 -29
  394. package/src/projects/cyberia/instance-backup.js +210 -0
  395. package/src/projects/cyberia/instance-data.js +178 -258
  396. package/src/projects/cyberia/ipfs-client.js +4 -4
  397. package/src/projects/cyberia/map-preview-generator.js +33 -69
  398. package/src/projects/cyberia/object-layer.js +153 -320
  399. package/src/projects/cyberia/seed-audio.js +139 -0
  400. package/src/projects/cyberia/semantic-layer-generator-skin.js +2 -8
  401. package/src/projects/cyberia/semantic-layer-generator.js +3 -19
  402. package/src/projects/cyberia/stat-balance.js +81 -0
  403. package/src/projects/cyberia/stat-commands.js +23 -0
  404. package/src/projects/cyberia/stat-contract-generator.js +101 -0
  405. package/src/projects/underpost/catalog-underpost.js +9 -1
  406. package/src/proxy.js +4 -7
  407. package/src/runtime/cyberia-client/Dockerfile +17 -8
  408. package/src/runtime/cyberia-client/Dockerfile.dev +13 -4
  409. package/src/runtime/cyberia-server/Dockerfile +18 -6
  410. package/src/runtime/cyberia-server/Dockerfile.dev +16 -3
  411. package/src/runtime/engine-cyberia/Dockerfile +25 -9
  412. package/src/runtime/engine-cyberia/Dockerfile.dev +25 -9
  413. package/src/runtime/engine-cyberia/Dockerfile.test +5 -5
  414. package/src/runtime/engine-cyberia/compose.env +17 -5
  415. package/src/runtime/engine-cyberia/docker-compose.yml +23 -17
  416. package/src/runtime/express/Express.js +32 -27
  417. package/src/runtime/lampp/Lampp.js +22 -70
  418. package/src/runtime/nginx/Nginx.js +1 -1
  419. package/src/runtime/wp/Wp.js +16 -48
  420. package/src/server/{catalog.js → build/catalog.js} +15 -5
  421. package/src/server/build/coverage.js +188 -0
  422. package/src/server/build/execution.js +402 -0
  423. package/src/server/build/package.js +508 -0
  424. package/src/server/build/testing.js +578 -0
  425. package/src/server/{dns.js → network/dns.js} +144 -11
  426. package/src/server/{forward-proxy.js → network/forward-proxy.js} +10 -18
  427. package/src/server/{middlewares.js → network/middlewares.js} +11 -5
  428. package/src/server/network/node-capability.js +98 -0
  429. package/src/server/{peer.js → network/peer.js} +3 -3
  430. package/src/server/{proxy.js → network/proxy.js} +7 -13
  431. package/src/server/network/router.js +356 -0
  432. package/src/server/{tls.js → network/tls.js} +2 -2
  433. package/src/server/{underpost-compression.js → network/underpost-compression.js} +1 -1
  434. package/src/server/{underpost-gateway.js → network/underpost-gateway.js} +7 -7
  435. package/src/server/{underpost-ingress.js → network/underpost-ingress.js} +2 -2
  436. package/src/server/{cri.js → ops/cri.js} +2 -2
  437. package/src/server/{cron.js → ops/cron.js} +349 -74
  438. package/src/server/ops/event-notification.js +284 -0
  439. package/src/server/{logger.js → ops/logger.js} +143 -23
  440. package/src/server/ops/monitoring.js +1724 -0
  441. package/src/server/{systemd.js → ops/systemd.js} +55 -1
  442. package/src/server/{conf.js → runtime/conf.js} +516 -423
  443. package/src/server/runtime/config-scope.js +215 -0
  444. package/src/server/runtime/environment.js +149 -0
  445. package/src/server/{process.js → runtime/process.js} +153 -12
  446. package/src/server/{runtime-status.js → runtime/runtime-status.js} +155 -16
  447. package/src/server/{runtime.js → runtime/runtime.js} +12 -8
  448. package/src/server/{start.js → runtime/start.js} +128 -39
  449. package/src/server/{auth.js → security/auth.js} +7 -8
  450. package/src/server/security/container-storage.js +382 -0
  451. package/src/server/{crypto.js → security/crypto.js} +1 -1
  452. package/src/server/{selinux.js → security/selinux.js} +1 -1
  453. package/src/server/{backup.js → storage/backup.js} +17 -8
  454. package/src/server/{data-query.js → storage/data-query.js} +17 -1
  455. package/src/server/storage/downloader.js +121 -0
  456. package/src/server/storage/repository.js +68 -0
  457. package/src/server/storage/zip.js +153 -0
  458. package/src/server.js +4 -7
  459. package/src/ws/IoInterface.js +1 -1
  460. package/src/ws/IoServer.js +1 -1
  461. package/src/ws/core/core.ws.connection.js +1 -1
  462. package/src/ws/core/core.ws.emit.js +1 -1
  463. package/src/ws/core/core.ws.server.js +1 -1
  464. package/src/ws/default/default.ws.connection.js +1 -1
  465. package/src/ws/default/default.ws.emit.js +1 -1
  466. package/src/ws/default/default.ws.server.js +1 -1
  467. package/test/e2e/event-e2e-public-ingress-down.js +45 -0
  468. package/test/e2e/event-e2e-wireguard-server-down.js +38 -0
  469. package/test/e2e/event-e2e-wireguard-spoke-down.js +40 -0
  470. package/test/{api.test.js → integration/app/api.test.js} +33 -14
  471. package/test/integration/app/cyberia/atlas-sprite-sheet-store.test.js +402 -0
  472. package/test/integration/app/cyberia/atlas-sprite-sheet.test.js +86 -0
  473. package/test/integration/app/cyberia/cyberia-cli-plain-reads.test.js +64 -0
  474. package/test/integration/app/cyberia/cyberia-entity-type-default.test.js +842 -0
  475. package/test/integration/app/cyberia/cyberia-instance-conf-coerce.test.js +53 -0
  476. package/test/{cyberia-instance-conf-defaults.test.js → integration/app/cyberia/cyberia-instance-conf-defaults.test.js} +17 -23
  477. package/test/integration/app/cyberia/cyberia-instance-items.test.js +90 -0
  478. package/test/integration/app/cyberia/cyberia-load.test.js +466 -0
  479. package/test/integration/app/cyberia/cyberia-map-audio-conf.test.js +256 -0
  480. package/test/integration/app/cyberia/cyberia-stats.test.js +150 -0
  481. package/test/integration/app/cyberia/fallback-world-capture.test.js +338 -0
  482. package/test/integration/app/cyberia/object-layer-item-id.test.js +327 -0
  483. package/test/integration/app/cyberia/object-layer-item-selection.test.js +56 -0
  484. package/test/integration/app/cyberia/object-layer-natural-key.test.js +32 -0
  485. package/test/integration/app/cyberia/seed-audio.test.js +275 -0
  486. package/test/{shape-generator.test.js → integration/app/cyberia/shape-generator.test.js} +1 -1
  487. package/test/integration/infra/1-security/config-scope.test.js +305 -0
  488. package/test/integration/infra/1-security/container-storage.test.js +356 -0
  489. package/test/integration/infra/1-security/in-pod-cli-surface.test.js +86 -0
  490. package/test/integration/infra/1-security/secret-onboarding.test.js +930 -0
  491. package/test/{selinux.test.js → integration/infra/1-security/selinux.test.js} +2 -4
  492. package/test/{sops-secret-store.test.js → integration/infra/1-security/sops-secret-store.test.js} +415 -61
  493. package/test/integration/infra/1-security/systemd-service.test.js +70 -0
  494. package/test/integration/infra/1-security/underpost-config-secret.test.js +367 -0
  495. package/test/integration/infra/2-network/dns-firewall.test.js +566 -0
  496. package/test/integration/infra/2-network/node-capability.test.js +182 -0
  497. package/test/integration/infra/2-network/wireguard-cli.test.js +1187 -0
  498. package/test/{wireguard-edge.test.js → integration/infra/2-network/wireguard-edge.test.js} +649 -55
  499. package/test/{cluster-instances.test.js → integration/infra/3-cluster/cluster-instances.test.js} +11 -15
  500. package/test/{deploy-node-placement.test.js → integration/infra/3-cluster/deploy-node-placement.test.js} +3 -3
  501. package/test/integration/infra/3-cluster/docker-compose-stack.test.js +313 -0
  502. package/test/integration/infra/3-cluster/mongo-express-deploy.test.js +156 -0
  503. package/test/integration/infra/4-ingress/api-cross-origin.test.js +79 -0
  504. package/test/integration/infra/4-ingress/deploy-routes.test.js +379 -0
  505. package/test/integration/infra/4-ingress/gateway-static-assets.test.js +453 -0
  506. package/test/{instance-traffic-plan.test.js → integration/infra/4-ingress/instance-traffic-plan.test.js} +10 -6
  507. package/test/{underpost-gateway.test.js → integration/infra/4-ingress/underpost-gateway.test.js} +6 -6
  508. package/test/{underpost-ingress.test.js → integration/infra/4-ingress/underpost-ingress.test.js} +4 -4
  509. package/test/integration/infra/5-observability/cron-jobs.test.js +652 -0
  510. package/test/{deploy-monitor.test.js → integration/infra/5-observability/deploy-monitor.test.js} +29 -31
  511. package/test/integration/infra/5-observability/event-notification.test.js +197 -0
  512. package/test/integration/infra/5-observability/event-remediation.test.js +502 -0
  513. package/test/integration/infra/5-observability/event-targets.test.js +1174 -0
  514. package/test/integration/infra/5-observability/monitoring-stack.test.js +902 -0
  515. package/test/support/shell-harness.js +73 -0
  516. package/test/unit/build-template.test.js +97 -0
  517. package/test/unit/build-workflow-offline.test.js +132 -0
  518. package/test/unit/catalog.test.js +71 -0
  519. package/test/unit/client-build-docs.test.js +361 -0
  520. package/test/unit/client-bundle.test.js +313 -0
  521. package/test/unit/conf-loading.test.js +303 -0
  522. package/test/unit/conf-resolution.test.js +996 -0
  523. package/test/unit/coverage-artifact.test.js +221 -0
  524. package/test/{crypto.test.js → unit/crypto.test.js} +1 -1
  525. package/test/unit/cyberia/instance-backup.test.js +183 -0
  526. package/test/unit/cyberia/instance-object-layer-items.test.js +46 -0
  527. package/test/unit/cyberia/publish-workflow.test.js +22 -0
  528. package/test/unit/cyberia/stat-balance.test.js +69 -0
  529. package/test/unit/deploy-env-resolution.test.js +38 -0
  530. package/test/unit/deploy-log-table.test.js +518 -0
  531. package/test/unit/downloader-integrity.test.js +98 -0
  532. package/test/unit/execution-profiles.test.js +219 -0
  533. package/test/unit/file-reference-registry.test.js +141 -0
  534. package/test/unit/fleet-sync-source.test.js +149 -0
  535. package/test/unit/fs-storage-paths.test.js +596 -0
  536. package/test/unit/logger-redaction.test.js +141 -0
  537. package/test/unit/package.test.js +457 -0
  538. package/test/unit/prepare-host.test.js +382 -0
  539. package/test/unit/process-environment.test.js +18 -0
  540. package/test/unit/propagation-message.test.js +78 -0
  541. package/test/unit/redeploy-plan.test.js +24 -0
  542. package/test/unit/release-bump.test.js +474 -0
  543. package/test/unit/ssh-output-redaction.test.js +28 -0
  544. package/test/unit/start-options.test.js +46 -0
  545. package/test/unit/test-tiers.test.js +220 -0
  546. package/test/unit/zip-archive.test.js +142 -0
  547. package/vitest.config.js +66 -0
  548. package/.nycrc +0 -9
  549. package/deploy/lib/logging.sh +0 -96
  550. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +0 -48
  551. package/manifests/mongodb/pv-pvc.yaml +0 -59
  552. package/scripts/coverall-test-cyberia.sh +0 -24
  553. package/scripts/coverall-test.sh +0 -24
  554. package/scripts/link-local-underpost-cli.sh +0 -6
  555. package/src/api/cyberia-instance/cyberia-fallback-default-items.js +0 -63
  556. package/src/api/user/user.build.js +0 -16
  557. package/src/cli/env.js +0 -177
  558. package/src/client/components/core/Blockchain.js +0 -41
  559. package/src/client/components/core/Blog.js +0 -9
  560. package/src/client/components/core/KeyboardAvoidance.js +0 -145
  561. package/src/client/components/cyberia/FallbackWorldEngineCyberia.js +0 -368
  562. package/src/client/public/default/assets/background/dark.jpg +0 -0
  563. package/src/client/public/default/assets/background/white0-min.jpg +0 -0
  564. package/src/client/public/default/assets/background/white0.jpg +0 -0
  565. package/src/client/public/doc/favicon.ico +0 -0
  566. package/src/client/public/doc/sitemap +0 -148
  567. package/src/server/downloader.js +0 -73
  568. package/src/server/environment.js +0 -98
@@ -0,0 +1,578 @@
1
+ /**
2
+ * The test tier contract: which suites exist, the order they run in, and the
3
+ * in-cluster surfaces that execute and report them.
4
+ *
5
+ * Tiers are a lifecycle, not a taxonomy. A gateway assertion that fails because
6
+ * SELinux denied a bind is a security failure reported at the ingress layer, so
7
+ * the lower tier has to have run — and passed — before the higher one is worth
8
+ * reading. Vitest expresses that with one project per tier and an ascending
9
+ * `sequence.groupOrder`; nothing outside this table decides what runs when.
10
+ *
11
+ * This module is pure: it renders the runner configuration, the argument vector
12
+ * and the manifests from values it is given. Resolving deploy configuration,
13
+ * spawning the runner and talking to the cluster belong to `src/cli/test.js`.
14
+ *
15
+ * @module src/server/build/testing.js
16
+ * @namespace UnderpostTesting
17
+ */
18
+
19
+ /**
20
+ * @constant UNDERPOST_TESTING
21
+ * @description Identity of the test execution and reporting surfaces. One
22
+ * dashboard serves every deploy on the cluster, so these names are cluster-wide
23
+ * constants rather than per-deploy.
24
+ * @memberof UnderpostTesting
25
+ */
26
+ const UNDERPOST_TESTING = {
27
+ coverageDirectory: 'coverage',
28
+ lcovPath: 'coverage/lcov.info',
29
+ // Minimum total line coverage a gated run must reach — the same metric Coveralls
30
+ // reports, so a green build and a green badge mean the same thing. It is a
31
+ // ratchet: the floor the measured surface already holds (85% for the platform
32
+ // tiers, 85% with cyberia), raised as suites land, never a target no run meets.
33
+ // `COVERAGE_MIN` moves it for one repository without moving it for every one.
34
+ coverageThreshold: 80,
35
+ // Read by vitest.config.js to decide whether the Allure reporter is attached.
36
+ // Absent means a plain local run, so no result files are written at all.
37
+ allureResultsEnvKey: 'UNDERPOST_ALLURE_RESULTS',
38
+ allureResultsDirectory: 'allure-results',
39
+ allure: {
40
+ name: 'allure',
41
+ image: 'frankescobar/allure-docker-service:2.27.0',
42
+ port: 5050,
43
+ nodePort: 32350,
44
+ pvcName: 'allure-pvc',
45
+ pvcStorage: '2Gi',
46
+ resultsPath: '/app/allure-results',
47
+ reportsPath: '/app/default-reports',
48
+ routeName: 'allure-route',
49
+ // Sub-path under an existing hostname, so the dashboard rides the edge
50
+ // certificate already issued for that host instead of needing one of its own.
51
+ subPath: '/allure',
52
+ // Reports are rebuilt from the results directory on this cadence, which is
53
+ // how a Job that finishes after the page is open still shows up.
54
+ checkResultsEverySeconds: 5,
55
+ keepHistory: true,
56
+ },
57
+ job: {
58
+ namePrefix: 'underpost-test',
59
+ // A test run is a diagnostic, not a workload: a crash loop would hide the
60
+ // failure it is meant to report.
61
+ restartPolicy: 'Never',
62
+ backoffLimit: 0,
63
+ ttlSecondsAfterFinished: 3600,
64
+ workingDirectory: '/home/dd/engine',
65
+ },
66
+ };
67
+
68
+ /**
69
+ * @constant TEST_TIERS
70
+ * @description Every runnable tier, in lifecycle order.
71
+ *
72
+ * `name` doubles as the Vitest project id, and its prefix before `:` is the
73
+ * suite it belongs to — so `--suite infra` needs no second table to expand.
74
+ *
75
+ * `groupOrder` is what Vitest sequences on: equal values run in parallel, lower
76
+ * values run to completion first. It starts at 1, never 0 — Vitest routes a
77
+ * project left on the default 0 with a single worker into a bucket it appends
78
+ * after every ordered group, which would run the first tier last.
79
+ *
80
+ * A tier with a `delegate` runs on its own runner instead of as a Vitest
81
+ * project, after the Vitest run — so a delegated tier belongs in the last
82
+ * group, where the order it is declared in still matches the order it runs in.
83
+ *
84
+ * `sources` are the modules the tier's suites drive directly, and they are what
85
+ * coverage is measured over when the tier is selected. A module reached only as
86
+ * a collaborator — everything the `src/index.js` barrel pulls in behind one CLI
87
+ * call, everything a suite spawns into its own process — belongs to whichever
88
+ * tier asserts against it, or to none: counting it here reports a floor no test
89
+ * in the selection can move. A delegated tier declares none, because its runner
90
+ * reports its own coverage.
91
+ * @memberof UnderpostTesting
92
+ */
93
+ const TEST_TIERS = [
94
+ {
95
+ name: 'unit',
96
+ directory: 'test/unit',
97
+ groupOrder: 1,
98
+ sources: [
99
+ 'conf.js',
100
+ 'src/cli/release.js',
101
+ 'src/client-builder/client-build-docs.js',
102
+ 'src/projects/underpost/*.js',
103
+ 'src/server/runtime/conf.js',
104
+ 'src/server/security/crypto.js',
105
+ ],
106
+ // Non-recursive: the cyberia extension underneath is its own tier, so a
107
+ // tree that strips the product keeps a unit tier that imports none of it.
108
+ recursive: false,
109
+ description: 'Pure functions with no host, cluster or network dependency.',
110
+ },
111
+ {
112
+ name: 'cyberia:unit',
113
+ directory: 'test/unit/cyberia',
114
+ groupOrder: 1,
115
+ sources: [
116
+ 'src/projects/cyberia/instance-backup.js',
117
+ 'src/projects/cyberia/instance-data.js',
118
+ 'src/projects/cyberia/stat-balance.js',
119
+ ],
120
+ description: 'Cyberia MMO extension: pure functions over instance data, backups and stat policies.',
121
+ },
122
+ {
123
+ name: 'infra:1-security',
124
+ directory: 'test/integration/infra/1-security',
125
+ groupOrder: 2,
126
+ sources: [
127
+ 'src/cli/secrets.js',
128
+ 'src/server/ops/systemd.js',
129
+ 'src/server/security/container-storage.js',
130
+ 'src/server/security/selinux.js',
131
+ ],
132
+ description: 'SELinux policy, systemd units and the SOPS secret store.',
133
+ },
134
+ {
135
+ name: 'infra:2-network',
136
+ directory: 'test/integration/infra/2-network',
137
+ groupOrder: 3,
138
+ sources: ['src/cli/wireguard.js', 'src/server/network/dns.js', 'src/server/network/forward-proxy.js'],
139
+ description: 'WireGuard edge connectivity the cluster is reachable over.',
140
+ },
141
+ {
142
+ name: 'infra:3-cluster',
143
+ directory: 'test/integration/infra/3-cluster',
144
+ groupOrder: 4,
145
+ sources: ['src/cli/docker-compose.js', 'src/db/mongo/MongoExpress.js', 'src/server/runtime/conf.js'],
146
+ description: 'Instance clustering, node assignment and compute scheduling.',
147
+ },
148
+ {
149
+ name: 'infra:4-ingress',
150
+ directory: 'test/integration/infra/4-ingress',
151
+ groupOrder: 5,
152
+ sources: [
153
+ 'src/server/network/middlewares.js',
154
+ 'src/server/network/router.js',
155
+ 'src/server/network/underpost-compression.js',
156
+ 'src/server/network/underpost-gateway.js',
157
+ 'src/server/network/underpost-ingress.js',
158
+ 'src/server/runtime/conf.js',
159
+ ],
160
+ description: 'Gateways, ingress controllers, deploy routes and traffic plans.',
161
+ },
162
+ {
163
+ name: 'infra:5-observability',
164
+ directory: 'test/integration/infra/5-observability',
165
+ groupOrder: 6,
166
+ sources: [
167
+ 'src/cli/event.js',
168
+ 'src/mailer/*.js',
169
+ 'src/server/ops/cron.js',
170
+ 'src/server/ops/event-notification.js',
171
+ 'src/server/ops/monitoring.js',
172
+ 'src/server/runtime/runtime-status.js',
173
+ ],
174
+ description: 'Monitoring stack, deploy monitor, notifications and remediation.',
175
+ },
176
+ {
177
+ name: 'app',
178
+ directory: 'test/integration/app',
179
+ groupOrder: 7,
180
+ sources: ['src/api/test/*.js', 'src/server/ops/logger.js'],
181
+ // Non-recursive: the cyberia extension underneath is its own tier, because
182
+ // it ships in a separate product CLI and must stay separately runnable.
183
+ recursive: false,
184
+ description: 'Platform application layer served over the provisioned stack.',
185
+ },
186
+ {
187
+ name: 'cyberia:app',
188
+ directory: 'test/integration/app/cyberia',
189
+ groupOrder: 7,
190
+ sources: [
191
+ 'src/api/cyberia-server-defaults/*.js',
192
+ 'src/api/cyberia-instance/cyberia-fallback-capture.js',
193
+ 'src/api/object-layer/object-layer.model.js',
194
+ 'src/projects/cyberia/atlas-sprite-sheet-generator.js',
195
+ 'src/projects/cyberia/shape-generator.js',
196
+ ],
197
+ description: 'Cyberia MMO extension: content, persistence, sprite atlases and shape generation.',
198
+ },
199
+ {
200
+ name: 'contracts',
201
+ directory: 'hardhat',
202
+ groupOrder: 7,
203
+ description: 'ObjectLayerToken ERC-1155 behaviour on the in-process EVM.',
204
+ // Hardhat owns Solidity compilation and the EVM these run against, so they
205
+ // cannot be collected by Vitest. Hardhat's own `test` task pins a reporter
206
+ // with no machine-readable output, so the suites — plain `node:test` files —
207
+ // are run on Node's runner directly, which can emit the JUnit results the
208
+ // dashboard ingests while still printing a readable run.
209
+ delegate: ({ resultsPath = '', grep = '' } = {}) =>
210
+ [
211
+ '[ -x node_modules/.bin/hardhat ] || npm ci --no-audit --no-fund',
212
+ './node_modules/.bin/hardhat build',
213
+ [
214
+ // Set by Hardhat's own test task; plugins branch on them.
215
+ 'HH_TEST=true NODE_ENV=test node --test',
216
+ '--test-reporter=spec --test-reporter-destination=stdout',
217
+ ...(resultsPath ? [`--test-reporter=junit --test-reporter-destination=${resultsPath}`] : []),
218
+ ...(grep ? [`--test-name-pattern=${JSON.stringify(grep)}`] : []),
219
+ "'test/**/*.js'",
220
+ ].join(' '),
221
+ ].join(' && '),
222
+ },
223
+ ];
224
+
225
+ /**
226
+ * @method testSuiteNames
227
+ * @description Suite selectors `--suite` accepts, derived from the tier names
228
+ * so a new tier is selectable the moment it is declared.
229
+ * @returns {string[]} Suite names, plus the `all` selector.
230
+ * @memberof UnderpostTesting
231
+ */
232
+ const testSuiteNames = () => [...new Set(TEST_TIERS.map(({ name }) => name.split(':')[0])), 'all'];
233
+
234
+ /**
235
+ * @method resolveTestTiers
236
+ * @description Expands a comma separated selector into tiers.
237
+ *
238
+ * Expansion happens here rather than being passed through as a glob so an
239
+ * unknown selector fails with the list of valid ones instead of silently
240
+ * matching nothing and reporting a green run.
241
+ * @param {string} [selector] - Suite names, tier names, or empty for every tier.
242
+ * @returns {object[]} Selected tiers, in declaration order.
243
+ * @throws {Error} When a selector matches no declared tier.
244
+ * @memberof UnderpostTesting
245
+ */
246
+ const resolveTestTiers = (selector = '') => {
247
+ const selectors = selector
248
+ .split(',')
249
+ .map((value) => value.trim())
250
+ .filter(Boolean);
251
+ if (selectors.length === 0 || selectors.includes('all')) return TEST_TIERS;
252
+
253
+ const selected = new Set();
254
+ for (const value of selectors) {
255
+ const matched = TEST_TIERS.filter(({ name }) => name === value || name.startsWith(`${value}:`));
256
+ if (matched.length === 0)
257
+ throw new Error(
258
+ `[test] unknown suite '${value}' — expected one of ${testSuiteNames().join(', ')} ` +
259
+ `or a tier: ${TEST_TIERS.map(({ name }) => name).join(', ')}`,
260
+ );
261
+ for (const tier of matched) selected.add(tier);
262
+ }
263
+ return TEST_TIERS.filter((tier) => selected.has(tier));
264
+ };
265
+
266
+ /**
267
+ * @method resolveTestSelection
268
+ * @description Splits a selector into the two runners that serve it.
269
+ * @param {string} [selector] - Suite names, tier names, or empty for every tier.
270
+ * @returns {{projects: string[], runVitest: boolean, delegated: object[]}} Selection.
271
+ * @throws {Error} When a selector matches no declared tier.
272
+ * @memberof UnderpostTesting
273
+ */
274
+ const resolveTestSelection = (selector = '') => {
275
+ const tiers = resolveTestTiers(selector);
276
+ const vitestTiers = tiers.filter(({ delegate }) => !delegate);
277
+ const everyVitestTier = vitestTiers.length === TEST_TIERS.filter(({ delegate }) => !delegate).length;
278
+ return {
279
+ // No `--project` flags when every tier is selected: Vitest runs them all by
280
+ // default, and an explicit list would fail a template that strips one.
281
+ projects: everyVitestTier ? [] : vitestTiers.map(({ name }) => name),
282
+ runVitest: vitestTiers.length > 0,
283
+ delegated: tiers.filter(({ delegate }) => delegate),
284
+ };
285
+ };
286
+
287
+ /**
288
+ * @method testProjectsFactory
289
+ * @description Renders the Vitest `projects` array from the tier table.
290
+ *
291
+ * A Vitest project is a standalone configuration and inherits nothing from the
292
+ * root `test` block, so whatever every tier needs is spread in here rather than
293
+ * declared once at the root and silently dropped.
294
+ * @param {object} [defaults] - Per-project `test` options shared by every tier.
295
+ * @returns {object[]} Vitest inline project configurations.
296
+ * @memberof UnderpostTesting
297
+ */
298
+ const testProjectsFactory = (defaults = {}) =>
299
+ TEST_TIERS.filter(({ delegate }) => !delegate).map(({ name, directory, groupOrder, recursive = true }) => ({
300
+ test: {
301
+ ...defaults,
302
+ name,
303
+ include: [`${directory}/${recursive ? '**/' : ''}*.test.js`],
304
+ sequence: { ...defaults.sequence, groupOrder },
305
+ },
306
+ }));
307
+
308
+ /**
309
+ * @method vitestArgsFactory
310
+ * @description Builds the Vitest argument vector for one run.
311
+ * @param {object} [params]
312
+ * @param {string[]} [params.projects] - Vitest project ids, empty for every project.
313
+ * @param {string} [params.grep] - Substring filter on test names.
314
+ * @param {boolean} [params.watch] - Keep the runner open and re-run on change.
315
+ * @param {boolean} [params.coverage] - Emit the coverage reporters.
316
+ * @returns {string[]} Arguments for the `vitest` binary.
317
+ * @memberof UnderpostTesting
318
+ */
319
+ const vitestArgsFactory = ({ projects = [], grep = '', watch = false, coverage = true } = {}) => [
320
+ // Subcommands, not flags: `vitest run --watch` is contradictory and Vitest
321
+ // resolves it to a single non-watching run.
322
+ watch ? 'watch' : 'run',
323
+ ...projects.flatMap((project) => ['--project', project]),
324
+ ...(grep ? ['--testNamePattern', grep] : []),
325
+ ...(coverage ? ['--coverage'] : ['--coverage.enabled=false']),
326
+ ];
327
+
328
+ /**
329
+ * @method coverageThresholdFactory
330
+ * @description Resolves the minimum total line coverage a run must reach, or `null`
331
+ * when the run reports without gating.
332
+ *
333
+ * Gating is opt-in because a tier selection measures a slice of the tree: holding
334
+ * every partial local run to the whole-suite number would fail runs that never
335
+ * loaded the code being counted. `npm run test:coverage` and CI opt in; `COVERAGE_MIN`
336
+ * lowers the bar for a repository whose suite is still catching up to it.
337
+ * @param {object} [env] - Environment to read `COVERAGE_ENFORCE` and `COVERAGE_MIN` from.
338
+ * @returns {number|null} Threshold percentage, or `null` to report without gating.
339
+ * @throws {Error} When `COVERAGE_MIN` is not a percentage.
340
+ * @memberof UnderpostTesting
341
+ */
342
+ const coverageThresholdFactory = ({ COVERAGE_ENFORCE, COVERAGE_MIN } = {}) => {
343
+ if (COVERAGE_MIN !== undefined && COVERAGE_MIN !== '') {
344
+ const threshold = Number(COVERAGE_MIN);
345
+ if (!Number.isFinite(threshold) || threshold < 0 || threshold > 100)
346
+ throw new Error(`[test] COVERAGE_MIN must be a percentage between 0 and 100, got '${COVERAGE_MIN}'`);
347
+ return threshold;
348
+ }
349
+ return COVERAGE_ENFORCE === '1' || COVERAGE_ENFORCE === 'true' ? UNDERPOST_TESTING.coverageThreshold : null;
350
+ };
351
+
352
+ /**
353
+ * @method coverageIncludeFactory
354
+ * @description Source globs a run measures coverage over, from the tier selection
355
+ * on its own command line.
356
+ *
357
+ * Read from the argument vector rather than passed in, because the runner's config
358
+ * is loaded by the Vitest process the arguments were handed to — a `--project` the
359
+ * caller added by hand is as authoritative as one `vitestArgsFactory` rendered.
360
+ * @param {string[]} [argv] - Argument vector carrying the `--project` selection.
361
+ * @returns {string[]} Globs for `coverage.include`, every selected tier's sources.
362
+ * @throws {Error} When a selected project matches no declared tier.
363
+ * @memberof UnderpostTesting
364
+ */
365
+ const coverageIncludeFactory = (argv = []) => [
366
+ ...new Set(resolveTestTiers(vitestProjectSelector(argv)).flatMap(({ sources = [] }) => sources)),
367
+ ];
368
+
369
+ /**
370
+ * @method vitestProjectSelector
371
+ * @description The tier selector a Vitest argument vector carries, as `--project` flags.
372
+ * @param {string[]} [argv] - Argument vector.
373
+ * @returns {string} Comma separated selector, empty when no project was named.
374
+ * @memberof UnderpostTesting
375
+ */
376
+ const vitestProjectSelector = (argv = []) =>
377
+ argv
378
+ .flatMap((arg, index) =>
379
+ arg === '--project' ? [argv[index + 1]] : arg.startsWith('--project=') ? [arg.slice('--project='.length)] : [],
380
+ )
381
+ .filter(Boolean)
382
+ .join(',');
383
+
384
+ /**
385
+ * @method coverageReportKey
386
+ * @description The directory under `coverage/` a selection's HTML report is written to,
387
+ * derived from the suites the selection spans so a deploy that names `unit,infra,app` and
388
+ * a run that was handed the same tiers as `--project` flags address one report — and so
389
+ * two selections never overwrite each other's on a host that serves both.
390
+ * @param {string} [selector] - Suite names, tier names, or empty for every tier.
391
+ * @returns {string} Suite names in declaration order, joined with `-`.
392
+ * @throws {Error} When a selector matches no declared tier.
393
+ * @memberof UnderpostTesting
394
+ */
395
+ const coverageReportKey = (selector = '') =>
396
+ [
397
+ ...new Set(
398
+ resolveTestTiers(selector)
399
+ .filter(({ delegate }) => !delegate)
400
+ .map(({ name }) => name.split(':')[0]),
401
+ ),
402
+ ].join('-');
403
+
404
+ /**
405
+ * @method allureManifestsFactory
406
+ * @description Renders the Allure dashboard: a claim for the results the runs
407
+ * write, the report server, and the ways in.
408
+ *
409
+ * The server watches the results directory rather than being pushed a report,
410
+ * so a Job that writes its results and exits needs no callback and no ordering
411
+ * against the dashboard's own lifecycle.
412
+ * @param {object} params
413
+ * @param {string} params.namespace - Target namespace.
414
+ * @param {string} [params.host] - Hostname to route `/allure` on; omitted means NodePort only.
415
+ * @returns {string} Concatenated YAML documents.
416
+ * @memberof UnderpostTesting
417
+ */
418
+ const allureManifestsFactory = ({ namespace, host = '' }) => {
419
+ const { allure } = UNDERPOST_TESTING;
420
+ const manifests = [
421
+ `apiVersion: v1
422
+ kind: PersistentVolumeClaim
423
+ metadata:
424
+ name: ${allure.pvcName}
425
+ namespace: ${namespace}
426
+ spec:
427
+ accessModes:
428
+ - ReadWriteOnce
429
+ resources:
430
+ requests:
431
+ storage: ${allure.pvcStorage}`,
432
+ `apiVersion: apps/v1
433
+ kind: Deployment
434
+ metadata:
435
+ name: ${allure.name}
436
+ namespace: ${namespace}
437
+ spec:
438
+ replicas: 1
439
+ selector:
440
+ matchLabels:
441
+ app: ${allure.name}
442
+ template:
443
+ metadata:
444
+ labels:
445
+ app: ${allure.name}
446
+ spec:
447
+ containers:
448
+ - name: ${allure.name}
449
+ image: ${allure.image}
450
+ ports:
451
+ - containerPort: ${allure.port}
452
+ env:
453
+ - name: CHECK_RESULTS_EVERY_SECONDS
454
+ value: '${allure.checkResultsEverySeconds}'
455
+ - name: KEEP_HISTORY
456
+ value: '${allure.keepHistory ? 1 : 0}'
457
+ - name: URL_PREFIX
458
+ value: '${host ? allure.subPath : ''}'
459
+ volumeMounts:
460
+ - name: results
461
+ mountPath: ${allure.resultsPath}
462
+ - name: reports
463
+ mountPath: ${allure.reportsPath}
464
+ readinessProbe:
465
+ httpGet:
466
+ path: ${host ? allure.subPath : ''}/allure-docker-service/version
467
+ port: ${allure.port}
468
+ initialDelaySeconds: 10
469
+ periodSeconds: 10
470
+ volumes:
471
+ - name: results
472
+ persistentVolumeClaim:
473
+ claimName: ${allure.pvcName}
474
+ - name: reports
475
+ emptyDir: {}`,
476
+ `apiVersion: v1
477
+ kind: Service
478
+ metadata:
479
+ name: ${allure.name}
480
+ namespace: ${namespace}
481
+ spec:
482
+ type: NodePort
483
+ selector:
484
+ app: ${allure.name}
485
+ ports:
486
+ - port: ${allure.port}
487
+ targetPort: ${allure.port}
488
+ nodePort: ${allure.nodePort}`,
489
+ ];
490
+
491
+ if (host)
492
+ manifests.push(`apiVersion: projectcontour.io/v1
493
+ kind: HTTPProxy
494
+ metadata:
495
+ name: ${allure.routeName}
496
+ namespace: ${namespace}
497
+ spec:
498
+ virtualhost:
499
+ fqdn: ${host}
500
+ tls:
501
+ secretName: ${host}
502
+ routes:
503
+ - conditions:
504
+ - prefix: ${allure.subPath}
505
+ services:
506
+ - name: ${allure.name}
507
+ port: ${allure.port}`);
508
+
509
+ return manifests.join('\n---\n');
510
+ };
511
+
512
+ /**
513
+ * @method testJobManifestFactory
514
+ * @description Renders a Job that runs one suite inside the cluster.
515
+ *
516
+ * The Job mounts the same results claim the dashboard reads, so its output is
517
+ * on the dashboard the moment it exits — no artifact upload step, and no
518
+ * dependency on the Job's own pod outliving the run.
519
+ * @param {object} params
520
+ * @param {string} params.name - Job name.
521
+ * @param {string} params.namespace - Target namespace.
522
+ * @param {string} params.image - Image carrying the engine and its dependencies.
523
+ * @param {string} params.suite - Suite or tier selector passed to `underpost test`.
524
+ * @param {string} [params.nodeName] - Pins the pod to one node.
525
+ * @returns {string} Job YAML.
526
+ * @memberof UnderpostTesting
527
+ */
528
+ const testJobManifestFactory = ({ name, namespace, image, suite, nodeName = '' }) => {
529
+ const { allure, job } = UNDERPOST_TESTING;
530
+ const command = ['underpost', 'test', ...(suite ? [suite] : []), '--itc', '--allure'].join(' ');
531
+ return `apiVersion: batch/v1
532
+ kind: Job
533
+ metadata:
534
+ name: ${name}
535
+ namespace: ${namespace}
536
+ spec:
537
+ backoffLimit: ${job.backoffLimit}
538
+ ttlSecondsAfterFinished: ${job.ttlSecondsAfterFinished}
539
+ template:
540
+ metadata:
541
+ labels:
542
+ app: ${job.namePrefix}
543
+ spec:
544
+ restartPolicy: ${job.restartPolicy}
545
+ ${nodeName ? ` nodeName: ${nodeName}\n` : ''} containers:
546
+ - name: ${job.namePrefix}
547
+ image: ${image}
548
+ workingDir: ${job.workingDirectory}
549
+ command: ['sh', '-lc', '${command}']
550
+ env:
551
+ - name: NODE_ENV
552
+ value: test
553
+ - name: ${UNDERPOST_TESTING.allureResultsEnvKey}
554
+ value: ${allure.resultsPath}
555
+ volumeMounts:
556
+ - name: results
557
+ mountPath: ${allure.resultsPath}
558
+ volumes:
559
+ - name: results
560
+ persistentVolumeClaim:
561
+ claimName: ${allure.pvcName}`;
562
+ };
563
+
564
+ export {
565
+ UNDERPOST_TESTING,
566
+ TEST_TIERS,
567
+ allureManifestsFactory,
568
+ coverageIncludeFactory,
569
+ coverageReportKey,
570
+ coverageThresholdFactory,
571
+ resolveTestSelection,
572
+ resolveTestTiers,
573
+ testJobManifestFactory,
574
+ testProjectsFactory,
575
+ testSuiteNames,
576
+ vitestArgsFactory,
577
+ vitestProjectSelector,
578
+ };