@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,221 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @module coverage-artifact.test
5
+ * @description Covers the coverage report as a build artifact: where a run leaves it, where an
6
+ * assembled deploy artifact carries it, and the guard that keeps a workload container from
7
+ * writing the runtime status contract while a test runner is what is executing.
8
+ *
9
+ * Uses 'chai' for assertions.
10
+ */
11
+
12
+ import { expect } from 'chai';
13
+ import fs from 'fs-extra';
14
+ import {
15
+ COVERAGE_BUNDLE_DIRECTORY,
16
+ bundleCoverageReports,
17
+ coverageReportCandidates,
18
+ coverageReportCommand,
19
+ coverageReportsFactory,
20
+ coverageUnavailablePage,
21
+ deployCoverageReports,
22
+ resolveCoverageReportPath,
23
+ } from '../../src/server/build/coverage.js';
24
+ import { EXECUTION_PROFILE_ENV_KEY } from '../../src/server/build/execution.js';
25
+ import { isTestRuntime, runtimeStatusWritable } from '../../src/server/runtime/runtime-status.js';
26
+
27
+ describe('coverage report declaration', () => {
28
+ it('reads each declared report with its label defaulting to the id', () => {
29
+ expect(coverageReportsFactory({ coverage: [{ id: 'engine', suite: 'unit' }] })).to.deep.equal([
30
+ { id: 'engine', label: 'engine', suite: 'unit', path: undefined },
31
+ ]);
32
+ });
33
+
34
+ it('declares nothing for a deploy without coverage', () => {
35
+ expect(coverageReportsFactory({})).to.deep.equal([]);
36
+ expect(coverageReportsFactory(undefined)).to.deep.equal([]);
37
+ });
38
+
39
+ it('rejects an entry without exactly one source, a non-slug id, or a repeated id', () => {
40
+ expect(() => coverageReportsFactory({ coverage: [{ id: 'x' }] })).to.throw("exactly one of 'suite' or 'path'");
41
+ expect(() => coverageReportsFactory({ coverage: [{ id: 'x', suite: 'unit', path: './' }] })).to.throw(
42
+ 'exactly one',
43
+ );
44
+ expect(() => coverageReportsFactory({ coverage: [{ id: 'Bad Id', suite: 'unit' }] })).to.throw('slug');
45
+ expect(() =>
46
+ coverageReportsFactory({
47
+ coverage: [
48
+ { id: 'x', suite: 'unit' },
49
+ { id: 'x', suite: 'app' },
50
+ ],
51
+ }),
52
+ ).to.throw('declared twice');
53
+ });
54
+
55
+ it("collects a deploy's reports across routes once each", () => {
56
+ const route = { docs: { coverage: [{ id: 'engine', suite: 'unit' }] } };
57
+ const confServer = { 'a.test': { '/': route, '/store': route }, 'b.test': { '/': {} } };
58
+ expect(deployCoverageReports(confServer).map(({ id }) => id)).to.deep.equal(['engine']);
59
+ });
60
+
61
+ it('refuses one id declared with two sources', () => {
62
+ const confServer = {
63
+ 'a.test': {
64
+ '/': { docs: { coverage: [{ id: 'engine', suite: 'unit' }] } },
65
+ '/store': { docs: { coverage: [{ id: 'engine', suite: 'app' }] } },
66
+ },
67
+ };
68
+ expect(() => deployCoverageReports(confServer)).to.throw('two different sources');
69
+ });
70
+
71
+ it('names the command that produces each kind of report', () => {
72
+ expect(coverageReportCommand({ suite: 'unit,infra,app' })).to.equal('node bin test unit,infra,app');
73
+ expect(coverageReportCommand({ path: './hardhat/' })).to.equal('npm run coverage --prefix ./hardhat');
74
+ });
75
+ });
76
+
77
+ describe('coverage report resolution', () => {
78
+ let fixturePath;
79
+ let cwd;
80
+
81
+ // The bundled candidate is cwd-relative, and a published deploy artifact (the tree a
82
+ // downstream CI runs this suite in) carries real reports under it; resolve against the
83
+ // fixture, never the tree.
84
+ beforeEach(() => {
85
+ fixturePath = fs.mkdtempSync('/tmp/engine-coverage-artifact-');
86
+ cwd = process.cwd();
87
+ process.chdir(fixturePath);
88
+ });
89
+
90
+ afterEach(() => {
91
+ process.chdir(cwd);
92
+ fs.removeSync(fixturePath);
93
+ });
94
+
95
+ it("looks for a suite's own run output first and the bundled artifact last", () => {
96
+ expect(coverageReportCandidates({ id: 'engine', suite: 'unit,infra,app' })).to.deep.equal([
97
+ 'coverage/unit-infra-app',
98
+ `${COVERAGE_BUNDLE_DIRECTORY}/engine`,
99
+ ]);
100
+ });
101
+
102
+ it("looks through an external tree's report layouts before the bundled artifact", () => {
103
+ expect(coverageReportCandidates({ id: 'hardhat', path: '/src/' })).to.deep.equal([
104
+ '/src/coverage/html',
105
+ '/src/coverage/lcov-report',
106
+ '/src/coverage',
107
+ `${COVERAGE_BUNDLE_DIRECTORY}/hardhat`,
108
+ ]);
109
+ });
110
+
111
+ it('ignores a coverage directory that carries no HTML index', () => {
112
+ fs.outputFileSync(`${fixturePath}/coverage/lcov.info`, 'TN:\n');
113
+ expect(resolveCoverageReportPath({ id: 'x', path: fixturePath })).to.equal(undefined);
114
+ });
115
+
116
+ it('resolves the report of the selection the deploy names, not the last run made', () => {
117
+ fs.outputFileSync(`${fixturePath}/coverage/unit-infra-app-cyberia/index.html`, '<!doctype html>');
118
+ fs.outputFileSync(`${fixturePath}/coverage/cyberia/index.html`, '<!doctype html>');
119
+ expect(resolveCoverageReportPath({ id: 'x', suite: 'cyberia' })).to.equal('coverage/cyberia');
120
+ expect(resolveCoverageReportPath({ id: 'x', suite: 'unit,infra,app' })).to.equal(undefined);
121
+ });
122
+
123
+ it('falls back to the report a deploy artifact already carries', () => {
124
+ fs.outputFileSync(`${fixturePath}/${COVERAGE_BUNDLE_DIRECTORY}/hardhat/index.html`, '<!doctype html>');
125
+ expect(resolveCoverageReportPath({ id: 'hardhat', path: `${fixturePath}/hardhat` })).to.equal(
126
+ `${COVERAGE_BUNDLE_DIRECTORY}/hardhat`,
127
+ );
128
+ });
129
+ });
130
+
131
+ describe('coverage bundling into a deploy artifact', () => {
132
+ let fixturePath;
133
+ let cwd;
134
+
135
+ // The bundled candidate is cwd-relative, and a published deploy artifact (the tree a
136
+ // downstream CI runs this suite in) carries real reports under it; resolve against the
137
+ // fixture, never the tree.
138
+ beforeEach(() => {
139
+ fixturePath = fs.mkdtempSync('/tmp/engine-coverage-artifact-');
140
+ cwd = process.cwd();
141
+ process.chdir(fixturePath);
142
+ });
143
+
144
+ afterEach(() => {
145
+ process.chdir(cwd);
146
+ fs.removeSync(fixturePath);
147
+ });
148
+
149
+ it('carries each report into the artifact under its own id', () => {
150
+ fs.outputFileSync(`${fixturePath}/hardhat/coverage/html/index.html`, '<!doctype html><title>report</title>');
151
+ fs.outputFileSync(`${fixturePath}/hardhat/coverage/html/base.css`, 'body {}');
152
+
153
+ const [result] = bundleCoverageReports(
154
+ [{ id: 'hardhat', path: `${fixturePath}/hardhat` }],
155
+ `${fixturePath}/template`,
156
+ );
157
+
158
+ expect(result.bundled).to.equal(true);
159
+ expect(result.to).to.equal(`${fixturePath}/template/${COVERAGE_BUNDLE_DIRECTORY}/hardhat`);
160
+ expect(fs.readFileSync(`${result.to}/index.html`, 'utf8')).to.include('report');
161
+ expect(fs.existsSync(`${result.to}/base.css`)).to.equal(true);
162
+ });
163
+
164
+ it('replaces a previously bundled report rather than merging into it', () => {
165
+ fs.outputFileSync(`${fixturePath}/template/${COVERAGE_BUNDLE_DIRECTORY}/hardhat/stale.html`, 'stale');
166
+ fs.outputFileSync(`${fixturePath}/hardhat/coverage/index.html`, '<!doctype html><title>fresh</title>');
167
+
168
+ const [{ to }] = bundleCoverageReports(
169
+ [{ id: 'hardhat', path: `${fixturePath}/hardhat` }],
170
+ `${fixturePath}/template`,
171
+ );
172
+
173
+ expect(fs.existsSync(`${to}/stale.html`)).to.equal(false);
174
+ expect(fs.readFileSync(`${to}/index.html`, 'utf8')).to.include('fresh');
175
+ });
176
+
177
+ it('reports what was not bundled without creating its directory', () => {
178
+ const [result] = bundleCoverageReports(
179
+ [{ id: 'hardhat', path: `${fixturePath}/hardhat` }],
180
+ `${fixturePath}/template`,
181
+ );
182
+
183
+ expect(result).to.deep.equal({
184
+ id: 'hardhat',
185
+ bundled: false,
186
+ to: `${fixturePath}/template/${COVERAGE_BUNDLE_DIRECTORY}/hardhat`,
187
+ });
188
+ expect(fs.existsSync(result.to)).to.equal(false);
189
+ });
190
+
191
+ it('renders a static unavailable page naming the report and the run that produces it', () => {
192
+ const page = coverageUnavailablePage({ id: 'engine', suite: 'unit,infra,app' });
193
+ expect(page).to.include('Coverage report unavailable');
194
+ expect(page).to.include('node bin test unit,infra,app');
195
+ expect(page).to.include(`${COVERAGE_BUNDLE_DIRECTORY}/engine`);
196
+ expect(page).not.to.include('<script');
197
+ });
198
+ });
199
+
200
+ // Regression: a suite run inside a pod latched `container-status=error` on every expected
201
+ // non-zero exit, and the CD monitor failed the rollout on a deployment that was healthy.
202
+ describe('runtime status contract writability', () => {
203
+ it('recognizes a test runner as the executing context', () => {
204
+ expect(isTestRuntime()).to.equal(true);
205
+ });
206
+
207
+ it('refuses to write the contract from under a test runner', () => {
208
+ expect(runtimeStatusWritable()).to.equal(false);
209
+ });
210
+
211
+ it('refuses to write the contract under a non-live execution profile', () => {
212
+ const previous = process.env[EXECUTION_PROFILE_ENV_KEY];
213
+ try {
214
+ process.env[EXECUTION_PROFILE_ENV_KEY] = 'HERMETIC_BUILD';
215
+ expect(runtimeStatusWritable()).to.equal(false);
216
+ } finally {
217
+ if (previous === undefined) delete process.env[EXECUTION_PROFILE_ENV_KEY];
218
+ else process.env[EXECUTION_PROFILE_ENV_KEY] = previous;
219
+ }
220
+ });
221
+ });
@@ -9,7 +9,7 @@
9
9
  import { expect } from 'chai';
10
10
 
11
11
  // Import the cryptographic classes from the Canvas's refactored module
12
- import { SymmetricCrypto, AsymmetricCrypto } from '../src/server/crypto.js';
12
+ import { SymmetricCrypto, AsymmetricCrypto } from '../../src/server/security/crypto.js';
13
13
 
14
14
  // Define a common plaintext message for testing
15
15
  const plaintext = 'This is a secret message for testing cryptographic operations.';
@@ -0,0 +1,183 @@
1
+ import { describe, it, expect, beforeAll, afterAll, beforeEach, vi } from 'vitest';
2
+ import { mkdtemp, rm, mkdir, writeFile } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+
6
+ // The restore path only routes documents; the collections are in-memory stand-ins, IPFS is
7
+ // unreachable, and the static frame writer is a no-op, so what is asserted is the routing.
8
+ const models = {};
9
+ vi.mock('../../../src/db/DataBaseProvider.js', () => ({
10
+ DataBaseProviderService: { getModel: (name) => models[name] },
11
+ }));
12
+ vi.mock('../../../src/api/ipfs/ipfs.service.js', () => ({ createPinRecord: async () => ({}) }));
13
+ vi.mock('../../../src/projects/cyberia/ipfs-client.js', () => ({ IpfsClient: { addToIpfs: async () => null } }));
14
+ vi.mock('../../../src/projects/cyberia/object-layer.js', () => ({
15
+ ObjectLayerEngine: { writeStaticFrameAssets: async () => [], computeAndSaveFinalSha256: async () => ({}) },
16
+ }));
17
+ // The generator pulls in jimp, a cyberia product dependency the engine runner does not install;
18
+ // every store method that would reach it is spied out below, so only the constant is needed.
19
+ vi.mock('../../../src/projects/cyberia/atlas-sprite-sheet-generator.js', () => ({
20
+ AtlasSpriteSheetGenerator: {},
21
+ DEFAULT_ATLAS_UPSCALE_FACTOR: 20,
22
+ }));
23
+
24
+ const { AtlasSpriteSheetStore } = await import('../../../src/projects/cyberia/atlas-sprite-sheet-store.js');
25
+ const { atlasBackupFileKey, readObjectLayerBackup, restoreObjectLayerBackup } =
26
+ await import('../../../src/projects/cyberia/instance-backup.js');
27
+
28
+ /** A collection that remembers what was created and hands the last upsert back as the live document. */
29
+ const collection = () => {
30
+ const created = [];
31
+ let live = null;
32
+ const query = (value) => Object.assign(Promise.resolve(value), { populate: () => Promise.resolve(value) });
33
+ return {
34
+ created,
35
+ deleteOne: async () => ({ deletedCount: 0 }),
36
+ create: async (doc) => (created.push(doc), doc),
37
+ findByItemId: () => query(live),
38
+ upsertByItemId: async (doc) => {
39
+ live = { ...doc, markModified() {}, save: async () => live };
40
+ return live;
41
+ },
42
+ get live() {
43
+ return live;
44
+ },
45
+ };
46
+ };
47
+
48
+ let backupDir;
49
+ const write = (rel, value) => writeFile(join(backupDir, rel), Buffer.isBuffer(value) ? value : JSON.stringify(value));
50
+
51
+ beforeAll(async () => {
52
+ backupDir = await mkdtemp(join(tmpdir(), 'cyberia-backup-'));
53
+ for (const dir of ['object-layers', 'render-frames', 'atlas-sprite-sheets', 'files', 'ipfs/content']) {
54
+ await mkdir(join(backupDir, dir), { recursive: true });
55
+ }
56
+ await write('object-layers/hatchet.json', {
57
+ _id: 'ol1',
58
+ cid: 'cid-data',
59
+ objectLayerRenderFramesId: 'rf1',
60
+ atlasSpriteSheetId: 'at1',
61
+ data: { item: { id: 'hatchet', type: 'weapon' }, render: { cid: 'cid-png', metadataCid: 'cid-meta' } },
62
+ });
63
+ await write('render-frames/hatchet.json', { _id: 'rf1', frames: {}, colors: [], frame_duration: 100 });
64
+ await write('atlas-sprite-sheets/hatchet.json', {
65
+ _id: 'at1',
66
+ fileId: 'f-full',
67
+ minifyFileId: 'f-min',
68
+ idlePreviewFileId: 'f-idle',
69
+ cid: 'cid-png',
70
+ });
71
+ // Files are matched on _id, never on name: one is misnamed on purpose, one is a bystander.
72
+ await write('files/whatever.json', {
73
+ _id: 'f-full',
74
+ name: 'hatchet-atlas.png',
75
+ data: { $base64: Buffer.from('PNG').toString('base64') },
76
+ });
77
+ await write('files/atlas-minify-hatchet.json', {
78
+ _id: 'f-min',
79
+ name: 'hatchet-minify.png',
80
+ data: { type: 'Buffer', data: [1, 2, 3] },
81
+ });
82
+ await write('files/atlas-idle-hatchet.json', { _id: 'f-idle', name: 'hatchet-idle.png', data: { $base64: 'AA==' } });
83
+ await write('files/atlas-sword.json', { _id: 'f-other', name: 'sword-atlas.png', data: { $base64: 'AA==' } });
84
+ await write('ipfs/content/cid-data.bin', Buffer.from('data'));
85
+ await write('ipfs/content/cid-png.bin', Buffer.from('png'));
86
+ // cid-meta has no payload on purpose.
87
+ });
88
+
89
+ afterAll(() => rm(backupDir, { recursive: true, force: true }));
90
+
91
+ describe('reading one object layer out of an instance backup', () => {
92
+ it('gathers the object layer and every document it references', () => {
93
+ const backup = readObjectLayerBackup({ backupDir, itemId: 'hatchet' });
94
+ expect(backup.objectLayer.data.item.id).toBe('hatchet');
95
+ expect(backup.renderFrames._id).toBe('rf1');
96
+ expect(backup.atlas._id).toBe('at1');
97
+ });
98
+
99
+ it('resolves the atlas render Files by _id and leaves other Files alone', () => {
100
+ const { files } = readObjectLayerBackup({ backupDir, itemId: 'hatchet' });
101
+ expect(files.map((f) => f._id).sort()).toEqual(['f-full', 'f-idle', 'f-min']);
102
+ });
103
+
104
+ it('names each exported render after its atlas field', () => {
105
+ expect(atlasBackupFileKey('fileId', 'hatchet')).toBe('atlas-hatchet');
106
+ expect(atlasBackupFileKey('minifyFileId', 'hatchet')).toBe('atlas-minify-hatchet');
107
+ expect(atlasBackupFileKey('idlePreviewFileId', 'hatchet')).toBe('atlas-idle-hatchet');
108
+ });
109
+
110
+ it('decodes both File byte encodings the export can write', () => {
111
+ const { files } = readObjectLayerBackup({ backupDir, itemId: 'hatchet' });
112
+ const byId = Object.fromEntries(files.map((f) => [f._id, f.data]));
113
+ expect(Buffer.isBuffer(byId['f-full']) && byId['f-full'].toString()).toBe('PNG');
114
+ expect(Buffer.isBuffer(byId['f-min']) && [...byId['f-min']]).toEqual([1, 2, 3]);
115
+ });
116
+
117
+ it('collects only the payloads the backup actually carries', () => {
118
+ const { payloads } = readObjectLayerBackup({ backupDir, itemId: 'hatchet' });
119
+ expect([...payloads.keys()].sort()).toEqual(['cid-data', 'cid-png']);
120
+ expect(payloads.get('cid-png').toString()).toBe('png');
121
+ });
122
+
123
+ it('names the backup and item when the item is missing', () => {
124
+ expect(() => readObjectLayerBackup({ backupDir, itemId: 'ghost' })).toThrow(/no object layer 'ghost'/);
125
+ });
126
+
127
+ it('tolerates an item with no atlas or render frames yet', async () => {
128
+ await write('object-layers/bare.json', { _id: 'ol2', data: { item: { id: 'bare', type: 'floor' } } });
129
+ const backup = readObjectLayerBackup({ backupDir, itemId: 'bare' });
130
+ expect(backup.atlas).toBeNull();
131
+ expect(backup.renderFrames).toBeNull();
132
+ expect(backup.files).toEqual([]);
133
+ expect(backup.payloads.size).toBe(0);
134
+ });
135
+ });
136
+
137
+ describe('restoring one object layer from an instance backup', () => {
138
+ let persist;
139
+ let idle;
140
+
141
+ beforeEach(() => {
142
+ for (const name of ['ObjectLayer', 'ObjectLayerRenderFrames', 'AtlasSpriteSheet', 'File'])
143
+ models[name] = collection();
144
+ persist = vi.spyOn(AtlasSpriteSheetStore, 'persist').mockResolvedValue({
145
+ atlasDoc: { _id: 'at-rebuilt' },
146
+ atlasCid: 'cid-rebuilt-png',
147
+ atlasMetadataCid: 'cid-rebuilt-meta',
148
+ });
149
+ idle = vi.spyOn(AtlasSpriteSheetStore, 'syncIdlePreview').mockResolvedValue({ status: 'unchanged' });
150
+ vi.spyOn(AtlasSpriteSheetStore, 'pruneOrphanRenders').mockResolvedValue(0);
151
+ });
152
+
153
+ afterAll(() => vi.restoreAllMocks());
154
+
155
+ it('keeps the atlas the backup carries when it holds its minified render', async () => {
156
+ await restoreObjectLayerBackup({ backupDir, itemId: 'hatchet', options: {} });
157
+ expect(models.AtlasSpriteSheet.created[0].minifyFileId).toBe('f-min');
158
+ expect(persist).not.toHaveBeenCalled();
159
+ expect(idle).toHaveBeenCalledWith({ itemKey: 'hatchet', options: {} });
160
+ expect(models.ObjectLayer.live.data.render).toEqual({ cid: 'cid-png', metadataCid: 'cid-meta' });
161
+ });
162
+
163
+ // Regression: a backup written before the minified render existed restored an atlas the
164
+ // blob route could not serve, and the client runtime got a 500 for every entity wearing it.
165
+ it('rebuilds the atlas a backup restores without its minified render and relinks the item', async () => {
166
+ await write('object-layers/relic.json', {
167
+ _id: 'ol3',
168
+ objectLayerRenderFramesId: 'rf3',
169
+ atlasSpriteSheetId: 'at3',
170
+ data: { item: { id: 'relic', type: 'skin' }, render: { cid: 'cid-old-png', metadataCid: 'cid-old-meta' } },
171
+ });
172
+ const frames = { _id: 'rf3', frames: { down_idle: [] }, colors: [], frame_duration: 100 };
173
+ await write('render-frames/relic.json', frames);
174
+ await write('atlas-sprite-sheets/relic.json', { _id: 'at3', fileId: 'f-relic', minifyFileId: null });
175
+
176
+ await restoreObjectLayerBackup({ backupDir, itemId: 'relic', options: {} });
177
+
178
+ expect(persist).toHaveBeenCalledWith({ itemKey: 'relic', objectLayerRenderFrames: frames, options: {} });
179
+ const { live } = models.ObjectLayer;
180
+ expect(live.atlasSpriteSheetId).toBe('at-rebuilt');
181
+ expect(live.data.render).toEqual({ cid: 'cid-rebuilt-png', metadataCid: 'cid-rebuilt-meta' });
182
+ });
183
+ });
@@ -0,0 +1,46 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { fetchInstanceObjectLayerItemIds } from '../../../src/projects/cyberia/instance-data.js';
3
+
4
+ const lean = (value) => ({ lean: async () => value, populate: () => lean(value) });
5
+
6
+ const buildModels = ({ instance, maps = [], storedItemIds = [] }) => ({
7
+ CyberiaInstance: { findOne: () => lean(instance) },
8
+ CyberiaInstanceConf: { findOne: () => lean({ instanceCode: instance?.code, entityDefaults: [] }) },
9
+ CyberiaMap: { find: () => lean(maps) },
10
+ CyberiaEntityTypeDefault: { find: () => lean([]) },
11
+ CyberiaAction: { find: () => lean([]) },
12
+ CyberiaQuest: { find: () => lean([]) },
13
+ CyberiaSkill: { find: () => lean([]) },
14
+ ObjectLayer: {
15
+ find: (filter) => {
16
+ const wanted = new Set(filter['data.item.id'].$in);
17
+ return lean(storedItemIds.filter((id) => wanted.has(id)).map((id) => ({ _id: id, data: { item: { id } } })));
18
+ },
19
+ },
20
+ });
21
+
22
+ describe('instance object layer item ids', () => {
23
+ it('collects the item ids the instance maps place, limited to stored documents', async () => {
24
+ const models = buildModels({
25
+ instance: { _id: 'i1', code: 'FOREST', cyberiaMapCodes: ['forest-1'] },
26
+ maps: [
27
+ {
28
+ code: 'forest-1',
29
+ entities: [{ objectLayerItemIds: ['anon', 'hatchet'] }, { objectLayerItemIds: ['hatchet', '$runtime'] }],
30
+ },
31
+ ],
32
+ storedItemIds: ['anon', 'hatchet', 'unrelated'],
33
+ });
34
+ const itemIds = await fetchInstanceObjectLayerItemIds(models, 'FOREST');
35
+ expect(itemIds).toContain('anon');
36
+ expect(itemIds).toContain('hatchet');
37
+ expect(itemIds).not.toContain('unrelated');
38
+ expect(itemIds).not.toContain('$runtime');
39
+ expect(new Set(itemIds).size).toBe(itemIds.length);
40
+ });
41
+
42
+ it('fails on an unknown instance code instead of returning the fallback world', async () => {
43
+ const models = buildModels({ instance: null });
44
+ await expect(fetchInstanceObjectLayerItemIds(models, 'GHOST')).rejects.toThrow('"GHOST" not found');
45
+ });
46
+ });
@@ -0,0 +1,22 @@
1
+ import { expect } from 'chai';
2
+ import fs from 'fs-extra';
3
+ // Named import: js-yaml's ESM build exports no default.
4
+ import { load } from 'js-yaml';
5
+
6
+ describe('the cyberia publish workflow', () => {
7
+ it('rewrites the published manifest after the install and before every publish', () => {
8
+ // The rewrite is the publish step's alone: a checkout that installed the published shape
9
+ // would run the engine source against a second engine in node_modules.
10
+ const workflow = load(fs.readFileSync('./.github/workflows/publish.cyberia.ci.yml', 'utf8'));
11
+
12
+ for (const [job, { steps }] of Object.entries(workflow.jobs)) {
13
+ const commands = steps.map(({ run }) => `${run ?? ''}`);
14
+ const restore = commands.findIndex((command) => command.includes('publishedProductPackageJson'));
15
+ const install = commands.findIndex((command) => command.trim().startsWith('npm ci'));
16
+ const publish = commands.findIndex((command) => command.includes('npm publish'));
17
+
18
+ expect(restore, `${job}: restores the published manifest`).to.be.greaterThan(install);
19
+ expect(restore, `${job}: restores it before publishing`).to.be.lessThan(publish);
20
+ }
21
+ });
22
+ });
@@ -0,0 +1,69 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { balanceStats, resolveStatBounds, statPolicyActive } from '../../../src/projects/cyberia/stat-balance.js';
3
+ import {
4
+ STAT_TYPE_BOUNDS,
5
+ STAT_TYPES,
6
+ statBoundsForType,
7
+ } from '../../../src/client/components/cyberia/SharedDefaultsCyberia.js';
8
+
9
+ const wild = { effect: 60, resistance: -40, agility: 3, range: 25, intelligence: 9, utility: -2 };
10
+ const lcg = (seed) => () => (seed = (Math.imul(seed, 1664525) + 1013904223) >>> 0) / 4294967296;
11
+
12
+ describe('stat balancing policy', () => {
13
+ it('is inert without normalize or random', () => {
14
+ expect(statPolicyActive({})).toBe(false);
15
+ expect(balanceStats({ stats: wild, itemType: 'weapon' })).toEqual(wild);
16
+ });
17
+
18
+ it('clamps into the semantic bounds of the item type', () => {
19
+ expect(balanceStats({ stats: wild, itemType: 'weapon', policy: { normalize: true } })).toEqual({
20
+ effect: 20,
21
+ resistance: -10,
22
+ agility: 3,
23
+ range: 10,
24
+ intelligence: 5,
25
+ utility: 0,
26
+ });
27
+ expect(balanceStats({ stats: wild, itemType: 'skin', policy: { normalize: true } })).toEqual({
28
+ effect: 1,
29
+ resistance: 0,
30
+ agility: 3,
31
+ range: 0,
32
+ intelligence: 2,
33
+ utility: 0,
34
+ });
35
+ });
36
+
37
+ it('keeps the contract bounds for a type without semantic bounds', () => {
38
+ expect(statBoundsForType('unknown')).toEqual(Object.fromEntries(STAT_TYPES.map((key) => [key, [-100, 100]])));
39
+ expect(balanceStats({ stats: wild, itemType: 'unknown', policy: { normalize: true } })).toEqual(wild);
40
+ });
41
+
42
+ it('is idempotent and deterministic', () => {
43
+ const once = balanceStats({ stats: wild, itemType: 'weapon', policy: { normalize: true } });
44
+ expect(balanceStats({ stats: once, itemType: 'weapon', policy: { normalize: true } })).toEqual(once);
45
+ const policy = { normalize: true, random: true, min: 0, max: 8 };
46
+ const first = balanceStats({ stats: wild, itemType: 'weapon', policy, random: lcg(7) });
47
+ expect(balanceStats({ stats: wild, itemType: 'weapon', policy, random: lcg(7) })).toEqual(first);
48
+ for (const key of STAT_TYPES) {
49
+ const [lo, hi] = resolveStatBounds('weapon', policy)[key];
50
+ expect(first[key]).toBeGreaterThanOrEqual(lo);
51
+ expect(first[key]).toBeLessThanOrEqual(hi);
52
+ }
53
+ });
54
+
55
+ it('lets min and max narrow the semantic range and pins a request outside it', () => {
56
+ expect(resolveStatBounds('weapon', { normalize: true, min: 12, max: 30 }).effect).toEqual([12, 20]);
57
+ expect(resolveStatBounds('weapon', { normalize: true, min: 50 }).effect).toEqual([20, 20]);
58
+ expect(resolveStatBounds('weapon', { normalize: true, max: -50 }).resistance).toEqual([-10, -10]);
59
+ expect(resolveStatBounds('weapon', { min: -20, max: 20 }).effect).toEqual([-20, 20]);
60
+ expect(() => resolveStatBounds('weapon', { min: 5, max: 1 })).toThrow('minimum');
61
+ expect(() => resolveStatBounds('weapon', { min: -101 })).toThrow();
62
+ });
63
+
64
+ it('declares every semantic bound inside the contract and in order', () => {
65
+ for (const bounds of Object.values(STAT_TYPE_BOUNDS)) {
66
+ for (const [lo, hi] of Object.values(bounds)) expect(lo <= hi && lo >= -100 && hi <= 100).toBe(true);
67
+ }
68
+ });
69
+ });
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ import { expect } from 'chai';
4
+ import { deployEnvFactory } from '../../src/server/runtime/environment.js';
5
+
6
+ describe('deploy environment resolution', () => {
7
+ const originalNodeEnv = process.env.NODE_ENV;
8
+
9
+ afterEach(() => {
10
+ if (originalNodeEnv === undefined) delete process.env.NODE_ENV;
11
+ else process.env.NODE_ENV = originalNodeEnv;
12
+ });
13
+
14
+ it('prefers an explicit --env over every other signal', () => {
15
+ process.env.NODE_ENV = 'development';
16
+ expect(deployEnvFactory({ env: 'production', dev: true }, 'test')).to.equal('production');
17
+ expect(deployEnvFactory({ env: ' staging ' })).to.equal('staging');
18
+ });
19
+
20
+ it('treats --dev as the development shorthand', () => {
21
+ expect(deployEnvFactory({ dev: true })).to.equal('development');
22
+ expect(deployEnvFactory({ dev: true }, 'test')).to.equal('development');
23
+ });
24
+
25
+ it('falls back to the caller-supplied default, never to ambient NODE_ENV', () => {
26
+ process.env.NODE_ENV = 'development';
27
+ expect(deployEnvFactory({})).to.equal('production');
28
+ expect(deployEnvFactory()).to.equal('production');
29
+ expect(deployEnvFactory({ env: '' }, 'test')).to.equal('test');
30
+ });
31
+
32
+ it('lets a caller opt into the ambient environment by passing it as the fallback', () => {
33
+ process.env.NODE_ENV = 'production';
34
+ expect(deployEnvFactory({}, process.env.NODE_ENV || 'development')).to.equal('production');
35
+ delete process.env.NODE_ENV;
36
+ expect(deployEnvFactory({}, process.env.NODE_ENV || 'development')).to.equal('development');
37
+ });
38
+ });