@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
@@ -3,7 +3,7 @@
3
3
  * @description End-to-end test of the two-phase deployment readiness contract
4
4
  * between the in-pod runtime (`start.js` / `runtime-status.js`) and the CD-runner
5
5
  * monitor (`Underpost.monitor.monitorReadyRunner`), exercised as real OS
6
- * processes coordinating through the shared underpost env file and a real HTTP
6
+ * processes coordinating through the shared host configuration store and a real HTTP
7
7
  * internal status endpoint.
8
8
  *
9
9
  * Contract under test:
@@ -36,12 +36,12 @@ import fs from 'fs-extra';
36
36
  import os from 'node:os';
37
37
  import path from 'node:path';
38
38
  import { fileURLToPath, pathToFileURL } from 'node:url';
39
- import Underpost from '../src/index.js';
40
- import { shellExec } from '../src/server/process.js';
41
- import { startInternalStatusServer, stopInternalStatusServer } from '../src/server/runtime-status.js';
39
+ import Underpost from '../../../../src/index.js';
40
+ import { shellExec } from '../../../../src/server/runtime/process.js';
41
+ import { startInternalStatusServer, stopInternalStatusServer } from '../../../../src/server/runtime/runtime-status.js';
42
42
 
43
43
  const node = process.execPath;
44
- const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
44
+ const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../..');
45
45
 
46
46
  const DEPLOY_ID = 'dd-test';
47
47
  const ENV = 'production';
@@ -54,24 +54,22 @@ const BUILD_STATUS = `${DEPLOY_ID}-${ENV}-build-deployment`;
54
54
  const INTERNAL_PORT = 39517; // internal status endpoint (real server bound here)
55
55
  const CLOSED_PORT = 39518; // no server — used to force a transport failure
56
56
 
57
- describe('Deploy monitor — two-phase state machine (e2e, real HTTP transport)', function () {
58
- this.timeout(60000);
59
-
57
+ describe('Deploy monitor — two-phase state machine (e2e, real HTTP transport)', { timeout: 60000 }, () => {
60
58
  let prevPrefix;
61
59
  let tmpPrefix;
62
60
  let fakeBinDir;
63
- let envFile;
61
+ let stateFile;
64
62
  let monitorScriptPath;
65
63
 
66
- before(() => {
64
+ beforeAll(() => {
67
65
  prevPrefix = process.env.npm_config_prefix;
68
66
  tmpPrefix = fs.mkdtempSync(path.join(os.tmpdir(), 'underpost-e2e-'));
69
67
  process.env.npm_config_prefix = tmpPrefix;
70
68
 
71
- Underpost.env.set('container-status', 'init');
72
- Underpost.env.set('start-container-status', '');
69
+ Underpost.state.set('container-status', 'init');
70
+ Underpost.state.set('start-container-status', '');
73
71
  const npmRoot = shellExec('npm root -g', { stdout: true, silent: true, disableLog: true }).trim();
74
- envFile = path.join(npmRoot, 'underpost', '.env');
72
+ stateFile = path.join(npmRoot, 'underpost', '.state');
75
73
 
76
74
  process.env.UNDERPOST_INTERNAL_PORT = String(INTERNAL_PORT);
77
75
  startInternalStatusServer(INTERNAL_PORT);
@@ -107,7 +105,7 @@ if [[ "$verb" == "port-forward" ]]; then
107
105
  exit 0
108
106
  fi
109
107
  if [[ "$verb" == "exec" ]]; then
110
- grep -E '^container-status=' "$UNDERPOST_ENV_FILE" 2>/dev/null | tail -n1 | sed -E 's/^container-status=//'
108
+ grep -E '^container-status=' "$UNDERPOST_STATE_FILE" 2>/dev/null | tail -n1 | sed -E 's/^container-status=//'
111
109
  exit 0
112
110
  fi
113
111
  exit 0
@@ -135,7 +133,7 @@ try {
135
133
  );
136
134
  });
137
135
 
138
- after(async () => {
136
+ afterAll(async () => {
139
137
  await stopInternalStatusServer();
140
138
  delete process.env.UNDERPOST_INTERNAL_PORT;
141
139
  if (prevPrefix === undefined) delete process.env.npm_config_prefix;
@@ -145,17 +143,17 @@ try {
145
143
 
146
144
  beforeEach(() => {
147
145
  // Deploy in flight: app not yet reporting running.
148
- Underpost.env.set('container-status', INIT_STATUS);
146
+ Underpost.state.set('container-status', INIT_STATUS);
149
147
  // start-container-status is unset (empty) — the readinessProbe
150
148
  // sees 503 until the start pipeline completes and stamps this key.
151
- Underpost.env.set('start-container-status', '');
149
+ Underpost.state.set('start-container-status', '');
152
150
  });
153
151
 
154
152
  const spawnMonitor = (overrides = {}) =>
155
153
  new Promise((resolve) => {
156
154
  const envVars = {
157
155
  PATH: `${fakeBinDir}:${process.env.PATH}`,
158
- UNDERPOST_ENV_FILE: envFile,
156
+ UNDERPOST_STATE_FILE: stateFile,
159
157
  POD_NAME,
160
158
  npm_config_prefix: tmpPrefix,
161
159
  UNDERPOST_INTERNAL_PORT: String(INTERNAL_PORT),
@@ -178,7 +176,7 @@ try {
178
176
  });
179
177
 
180
178
  it('success (default exec transport): both phases satisfied → monitor exits 0', async () => {
181
- Underpost.env.set('container-status', RUNNING_STATUS);
179
+ Underpost.state.set('container-status', RUNNING_STATUS);
182
180
  // start-container-status not needed for monitor (reads container-status);
183
181
  // this test exercises the default exec transport path.
184
182
  const code = await spawnMonitor({ FAKE_POD_READY: 'True' });
@@ -186,21 +184,21 @@ try {
186
184
  });
187
185
 
188
186
  it('success (opt-in http transport): both phases satisfied → monitor exits 0', async () => {
189
- Underpost.env.set('container-status', RUNNING_STATUS);
190
- Underpost.env.set('start-container-status', RUNNING_STATUS);
187
+ Underpost.state.set('container-status', RUNNING_STATUS);
188
+ Underpost.state.set('start-container-status', RUNNING_STATUS);
191
189
  const code = await spawnMonitor({ FAKE_POD_READY: 'True', MON_TRANSPORT: 'http' });
192
190
  expect(code).to.equal(0);
193
191
  });
194
192
 
195
193
  it('runtime failure: container-status=error → monitor exits 1', async () => {
196
194
  const monitorExit = spawnMonitor({ FAKE_POD_READY: 'True' });
197
- Underpost.env.set('container-status', 'error');
195
+ Underpost.state.set('container-status', 'error');
198
196
  expect(await monitorExit).to.equal(1);
199
197
  });
200
198
 
201
199
  it('readiness mismatch: runtime running but pod not Ready → never succeeds (exits 1)', async () => {
202
200
  // Phase 2 satisfied, Phase 1 not: success requires BOTH, so it must time out.
203
- Underpost.env.set('container-status', RUNNING_STATUS);
201
+ Underpost.state.set('container-status', RUNNING_STATUS);
204
202
  // start-container-status is NOT set — the readinessProbe would fail,
205
203
  // but the monitor only checks container-status via exec/http transport.
206
204
  const code = await spawnMonitor({ FAKE_POD_READY: 'False', UNDERPOST_MONITOR_MAX_ITERATIONS: '4' });
@@ -208,7 +206,7 @@ try {
208
206
  });
209
207
 
210
208
  it('transport failure (http): endpoint unreachable is never success (exits 1)', async () => {
211
- Underpost.env.set('container-status', RUNNING_STATUS);
209
+ Underpost.state.set('container-status', RUNNING_STATUS);
212
210
  const code = await spawnMonitor({
213
211
  MON_TRANSPORT: 'http',
214
212
  UNDERPOST_INTERNAL_PORT: String(CLOSED_PORT),
@@ -219,7 +217,7 @@ try {
219
217
  });
220
218
 
221
219
  it('timeout: runtime stuck initializing → monitor exits 1', async () => {
222
- Underpost.env.set('container-status', INIT_STATUS);
220
+ Underpost.state.set('container-status', INIT_STATUS);
223
221
  // start-container-status remains unset — readinessProbe returns 503
224
222
  // (correct, since the runtime is still initializing).
225
223
  const code = await spawnMonitor({ FAKE_POD_READY: 'True', UNDERPOST_MONITOR_MAX_ITERATIONS: '4' });
@@ -229,15 +227,15 @@ try {
229
227
  it('regression: advanced pod whose runtime status falls back → monitor exits 1', async () => {
230
228
  // Pod advances past build, then its reported status regresses (pod restart);
231
229
  // the monitor must treat this as a failure rather than wait it out.
232
- Underpost.env.set('container-status', INIT_STATUS);
230
+ Underpost.state.set('container-status', INIT_STATUS);
233
231
  const monitorExit = spawnMonitor({ FAKE_POD_READY: 'False', UNDERPOST_MONITOR_MAX_ITERATIONS: '120' });
234
232
  await new Promise((r) => setTimeout(r, 1500));
235
- Underpost.env.set('container-status', BUILD_STATUS);
233
+ Underpost.state.set('container-status', BUILD_STATUS);
236
234
  expect(await monitorExit).to.equal(1);
237
235
  });
238
236
 
239
237
  it('readinessProbe: start-container-status set → returns 200 (probe passes)', async () => {
240
- Underpost.env.set('start-container-status', RUNNING_STATUS);
238
+ Underpost.state.set('start-container-status', RUNNING_STATUS);
241
239
  const res = await fetch(`http://127.0.0.1:${INTERNAL_PORT}/_internal/ready`);
242
240
  expect(res.status).to.equal(200);
243
241
  const body = await res.json();
@@ -246,7 +244,7 @@ try {
246
244
 
247
245
  it('readinessProbe: start-container-status unset → returns 503 (probe fails)', async () => {
248
246
  // Unset from beforeEach re-stamp; clear it.
249
- Underpost.env.set('start-container-status', '');
247
+ Underpost.state.set('start-container-status', '');
250
248
  const res = await fetch(`http://127.0.0.1:${INTERNAL_PORT}/_internal/ready`);
251
249
  expect(res.status).to.equal(503);
252
250
  });
@@ -254,14 +252,14 @@ try {
254
252
  // Custom instances (cyberia-*) gate on K8s Ready and read status via exec;
255
253
  // their runtime never stamps `running-deployment` (stays `initializing`).
256
254
  it('instance (kubernetes gate + exec): K8s Ready with initializing status → exits 0', async () => {
257
- Underpost.env.set('container-status', INIT_STATUS);
255
+ Underpost.state.set('container-status', INIT_STATUS);
258
256
  const code = await spawnMonitor({ FAKE_POD_READY: 'True', MON_READY_GATE: 'kubernetes', MON_TRANSPORT: 'exec' });
259
257
  expect(code).to.equal(0);
260
258
  });
261
259
 
262
260
  it('instance (kubernetes gate + exec): container-status=error → exits 1', async () => {
263
261
  const monitorExit = spawnMonitor({ FAKE_POD_READY: 'True', MON_READY_GATE: 'kubernetes', MON_TRANSPORT: 'exec' });
264
- Underpost.env.set('container-status', 'error');
262
+ Underpost.state.set('container-status', 'error');
265
263
  expect(await monitorExit).to.equal(1);
266
264
  });
267
265
  });
@@ -0,0 +1,197 @@
1
+ 'use strict';
2
+
3
+ import { expect } from 'chai';
4
+ import { MailerProviderClass } from '../../../../src/mailer/MailerProvider.js';
5
+ import { mailerInterceptorFactory } from '../../../../src/mailer/MailerInterceptor.js';
6
+ import {
7
+ EVENT_CONF_PATH,
8
+ assertNotificationRoutes,
9
+ eventNotificationRoutes,
10
+ } from '../../../../src/server/ops/event-notification.js';
11
+
12
+ const CONF = {
13
+ 'notification-providers': {
14
+ 'default-cluster-mailer-provider': {
15
+ type: 'mailer',
16
+ mailer: {
17
+ sender: { email: 'env:CLUSTER_MAILER_ADMIN_SENDER_EMAIL', name: 'env:CLUSTER_MAILER_ADMIN_SENDER_NAME' },
18
+ transport: {
19
+ host: 'env:CLUSTER_MAILER_SMTP_HOST',
20
+ port: 'env:CLUSTER_MAILER_SMTP_PORT',
21
+ secure: 'env:CLUSTER_SMTP_SECURE',
22
+ auth: { user: 'env:CLUSTER_MAILER_SMTP_AUTH_USER', pass: 'env:CLUSTER_MAILER_SMTP_AUTH_PASS' },
23
+ },
24
+ },
25
+ },
26
+ },
27
+ events: {
28
+ 'wireguard-server-down': {
29
+ notifications: [
30
+ {
31
+ 'notification-provider-id': 'default-cluster-mailer-provider',
32
+ payload: { subscribers: [{ email: 'ops@example.com', name: 'Ops' }] },
33
+ },
34
+ ],
35
+ },
36
+ },
37
+ };
38
+
39
+ const loadedProviderFactory = async () => {
40
+ const provider = new MailerProviderClass();
41
+ await provider.load({
42
+ id: 'test',
43
+ sender: { email: 'sender@example.com', name: 'Sender' },
44
+ transport: { host: 'smtp.example.com', port: 587, secure: false, auth: { user: '', pass: '' } },
45
+ templates: {},
46
+ });
47
+ return provider;
48
+ };
49
+
50
+ describe('event notification contract', () => {
51
+ it('resolves a declared route without reading any credential', () => {
52
+ const [route] = eventNotificationRoutes('wireguard-server-down', CONF);
53
+ expect(route.error).to.equal(undefined);
54
+ expect(route.providerId).to.equal('default-cluster-mailer-provider');
55
+ expect(route.type).to.equal('mailer');
56
+ expect(route.target).to.equal('smtp (env)');
57
+ expect(route.recipients).to.deep.equal([
58
+ { email: 'ops@example.com', name: 'Ops', address: 'Ops <ops@example.com>' },
59
+ ]);
60
+ });
61
+
62
+ it('reports an event that declares no notification', () => {
63
+ const [route] = eventNotificationRoutes('wireguard-spoke-down', CONF);
64
+ expect(route.error).to.include(EVENT_CONF_PATH);
65
+ expect(route.error).to.include('wireguard-spoke-down');
66
+ });
67
+
68
+ it('reports a route naming an undeclared provider', () => {
69
+ const conf = {
70
+ ...CONF,
71
+ events: { 'x-down': { notifications: [{ 'notification-provider-id': 'ghost', payload: {} }] } },
72
+ };
73
+ expect(eventNotificationRoutes('x-down', conf)[0].error).to.include("'ghost' is not declared");
74
+ });
75
+
76
+ it('reports a provider type nothing can deliver', () => {
77
+ const conf = {
78
+ 'notification-providers': { pager: { type: 'pager' } },
79
+ events: {
80
+ 'x-down': {
81
+ notifications: [{ 'notification-provider-id': 'pager', payload: { subscribers: [{ email: 'a@b.com' }] } }],
82
+ },
83
+ },
84
+ };
85
+ expect(eventNotificationRoutes('x-down', conf)[0].error).to.include(
86
+ "unsupported notification provider type 'pager'",
87
+ );
88
+ });
89
+
90
+ it('reports a route with no subscriber to deliver to', () => {
91
+ const conf = {
92
+ ...CONF,
93
+ events: {
94
+ 'x-down': {
95
+ notifications: [
96
+ {
97
+ 'notification-provider-id': 'default-cluster-mailer-provider',
98
+ payload: { subscribers: [{ name: 'Ops' }] },
99
+ },
100
+ ],
101
+ },
102
+ },
103
+ };
104
+ expect(eventNotificationRoutes('x-down', conf)[0].error).to.include('no subscriber with an email');
105
+ });
106
+
107
+ it('refuses detection whose outcome would reach nobody', () => {
108
+ expect(() => assertNotificationRoutes(eventNotificationRoutes('wireguard-spoke-down', CONF))).to.throw(
109
+ 'notification routes are unresolved',
110
+ );
111
+ expect(assertNotificationRoutes(eventNotificationRoutes('wireguard-server-down', CONF))).to.have.lengthOf(1);
112
+ });
113
+ });
114
+
115
+ describe('mailer send middleware', () => {
116
+ it('wraps a delivery in registration order and unregisters on dispose', async () => {
117
+ const provider = await loadedProviderFactory();
118
+ const order = [];
119
+ const dispose = provider.use(async (context, next) => {
120
+ order.push(`outer:${context.id}`);
121
+ return await next();
122
+ });
123
+ // Suppressing the transport keeps the assertion on ordering, not on SMTP.
124
+ provider.use(async () => {
125
+ order.push('inner');
126
+ return { messageId: 'stub' };
127
+ });
128
+
129
+ const info = await provider.send({ id: 'test', sendOptions: { to: 'a@b.com', subject: 'hi', text: 'hi' } });
130
+ expect(info).to.deep.equal({ messageId: 'stub' });
131
+ expect(order).to.deep.equal(['outer:test', 'inner']);
132
+
133
+ dispose();
134
+ order.length = 0;
135
+ await provider.send({ id: 'test', sendOptions: { to: 'a@b.com', subject: 'hi', text: 'hi' } });
136
+ expect(order).to.deep.equal(['inner']);
137
+ });
138
+
139
+ it('defaults the sender before any middleware observes the message', async () => {
140
+ const provider = await loadedProviderFactory();
141
+ let observed;
142
+ provider.use(async (context) => {
143
+ observed = context.sendOptions.from;
144
+ return { messageId: 'stub' };
145
+ });
146
+ await provider.send({ id: 'test', sendOptions: { to: 'a@b.com', subject: 'hi', text: 'hi' } });
147
+ expect(observed).to.equal('Sender <sender@example.com>');
148
+ });
149
+ });
150
+
151
+ describe('mailer interceptor', () => {
152
+ it('records what was sent and waits for a specific message', async () => {
153
+ const provider = await loadedProviderFactory();
154
+ const interceptor = mailerInterceptorFactory({ provider, suppress: true });
155
+
156
+ const pending = interceptor.waitFor((message) => message.sendOptions.subject.includes('wireguard-server-down'), {
157
+ timeoutMs: 2000,
158
+ intervalMs: 10,
159
+ });
160
+ await provider.send({
161
+ id: 'test',
162
+ sendOptions: { to: 'ops@example.com', subject: '[underpost] wireguard-server-down — hub — remediated', text: '' },
163
+ });
164
+
165
+ const message = await pending;
166
+ expect(message.accepted).to.equal(true);
167
+ expect(message.sendOptions.to).to.equal('ops@example.com');
168
+ expect(interceptor.messages).to.have.lengthOf(1);
169
+
170
+ interceptor.close();
171
+ provider.use(async () => ({ messageId: 'stub' }));
172
+ await provider.send({ id: 'test', sendOptions: { to: 'ops@example.com', subject: 'later', text: '' } });
173
+ expect(interceptor.messages).to.have.lengthOf(1);
174
+ });
175
+
176
+ it('resolves undefined when nothing matching is ever sent', async () => {
177
+ const provider = await loadedProviderFactory();
178
+ const interceptor = mailerInterceptorFactory({ provider, suppress: true });
179
+ const message = await interceptor.waitFor(() => false, { timeoutMs: 60, intervalMs: 10 });
180
+ interceptor.close();
181
+ expect(message).to.equal(undefined);
182
+ });
183
+ });
184
+
185
+ describe('mailer transport lifecycle', () => {
186
+ it('releases the instance so a one-shot process can exit', async () => {
187
+ const provider = await loadedProviderFactory();
188
+ expect(provider.instance.test).to.be.an('object');
189
+ expect(provider.close('test')).to.equal(true);
190
+ expect(provider.instance.test).to.equal(undefined);
191
+ });
192
+
193
+ it('is a no-op for an instance that was never loaded', async () => {
194
+ const provider = await loadedProviderFactory();
195
+ expect(provider.close('absent')).to.equal(false);
196
+ });
197
+ });