@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,141 @@
1
+ 'use strict';
2
+
3
+ import { expect } from 'chai';
4
+ import { PassThrough } from 'node:stream';
5
+ import winston from 'winston';
6
+ import { loggerFormatFactory, redactSensitiveText, serializeLogValue } from '../../src/server/ops/logger.js';
7
+
8
+ const renderLog = (message, metadata) => {
9
+ const stream = new PassThrough();
10
+ let output = '';
11
+ stream.on('data', (chunk) => {
12
+ output += chunk;
13
+ });
14
+ const logger = winston.createLogger({
15
+ format: loggerFormatFactory('logger-redaction.test.js'),
16
+ transports: [new winston.transports.Stream({ stream })],
17
+ });
18
+ metadata === undefined ? logger.info(message) : logger.info(message, metadata);
19
+ logger.close();
20
+ return output;
21
+ };
22
+
23
+ describe('central logger redaction', () => {
24
+ it('filters a credential a service reports next to its name, with no delimiter between them', () => {
25
+ // Regression: `Invalid api_key 4778…` reached the terminal in full. Every rule matched on a
26
+ // delimiter — `=`, `:`, a flag — and an error message carries none, so the pair went through.
27
+ expect(redactSensitiveText('Invalid api_key 477826957851424')).to.equal('Invalid api_key [REDACTED]');
28
+ expect(redactSensitiveText('Invalid api_secret 8kQvN2mLp0XyZ_abc')).to.equal('Invalid api_secret [REDACTED]');
29
+ expect(redactSensitiveText('CLOUDINARY_API_KEY 477826957851424')).to.equal('CLOUDINARY_API_KEY [REDACTED]');
30
+ });
31
+
32
+ it('leaves prose and identifiers that merely follow a sensitive word', () => {
33
+ // The name of a thing is not the thing: redacting the next word of every sentence would cost
34
+ // more legibility than it buys protection, so the value has to be shaped like a credential.
35
+ for (const kept of [
36
+ 'token verification failed',
37
+ 'password changed successfully',
38
+ 'authorization required for this route',
39
+ 'api_secret mismatch',
40
+ 'Target pod: dd-cyberia-production-blue-5b7c67bb8f-kwhz7 | Pod status: Running',
41
+ ])
42
+ expect(redactSensitiveText(kept), kept).to.equal(kept);
43
+ });
44
+
45
+ it('reaches a credential that a non-sensitive word precedes', () => {
46
+ // The scan looks ahead rather than consuming: matching `Invalid api_key` as a pair of its own
47
+ // would advance past the real one behind it.
48
+ const rendered = renderLog('cloudinary rejected: Invalid api_key 477826957851424');
49
+ expect(rendered).to.include('[REDACTED]');
50
+ expect(rendered).to.not.include('477826957851424');
51
+ });
52
+
53
+ it('filters common secret forms from free-form messages', () => {
54
+ const rawToken = `ghp_${'A'.repeat(30)}`;
55
+ const input = [
56
+ 'node bin host set GITHUB_TOKEN positional-secret',
57
+ 'GITHUB_TOKEN=environment-secret node bin db',
58
+ 'DB_PASS=database-secret',
59
+ 'curl --api-key flag-secret',
60
+ 'Authorization: Bearer bearer-secret',
61
+ 'https://user:url-secret@example.test/repo',
62
+ '?session_id=query-secret&ok=true',
63
+ `raw ${rawToken}`,
64
+ '-----BEGIN PRIVATE KEY-----\nprivate-key-secret\n-----END PRIVATE KEY-----',
65
+ ].join(' && ');
66
+ const output = redactSensitiveText(input);
67
+
68
+ for (const secret of [
69
+ 'positional-secret',
70
+ 'environment-secret',
71
+ 'database-secret',
72
+ 'flag-secret',
73
+ 'bearer-secret',
74
+ 'url-secret',
75
+ 'query-secret',
76
+ 'private-key-secret',
77
+ rawToken,
78
+ ])
79
+ expect(output).to.not.include(secret);
80
+ expect(output).to.include('GITHUB_TOKEN=[REDACTED]');
81
+ expect(output).to.include('https://***@example.test/repo');
82
+ });
83
+
84
+ it('filters nested sensitive fields without mutating the source metadata', () => {
85
+ const metadata = {
86
+ githubToken: 'nested-secret',
87
+ auth: { client_secret: 'client-secret', username: 'operator' },
88
+ command: 'node bin host set API_KEY command-secret',
89
+ };
90
+ metadata.self = metadata;
91
+ const output = serializeLogValue(metadata);
92
+
93
+ expect(output).to.not.include('nested-secret');
94
+ expect(output).to.not.include('client-secret');
95
+ expect(output).to.not.include('command-secret');
96
+ expect(output).to.include('operator');
97
+ expect(output).to.include('[Circular]');
98
+ expect(metadata.githubToken).to.equal('nested-secret');
99
+ });
100
+
101
+ it('applies the filter in the formatter used by every logger transport', () => {
102
+ const output = renderLog('ssh node :: node bin host set GITHUB_TOKEN message-secret', {
103
+ token_secret: 'metadata-secret',
104
+ repository: 'https://user:url-secret@example.test/repo',
105
+ });
106
+
107
+ for (const secret of ['message-secret', 'metadata-secret', 'url-secret']) expect(output).to.not.include(secret);
108
+ expect(output).to.include('[REDACTED]');
109
+ });
110
+
111
+ it('leaves ordinary operational context readable', () => {
112
+ expect(redactSensitiveText('ssh operator@example.test :: uptime')).to.equal('ssh operator@example.test :: uptime');
113
+ });
114
+
115
+ it('filters Git fetch credentials from plain and escaped URLs', () => {
116
+ const token = 'opaque-git-credential_123';
117
+ for (const command of [
118
+ `GIT_TERMINAL_PROMPT=0 git fetch --force "https://x-access-token:${token}@github.com/o/r" main`,
119
+ `GIT_TERMINAL_PROMPT=0 git fetch --force "https:\\/\\/x-access-token:${token}@github.com\\/o\\/r" main`,
120
+ `GIT_TERMINAL_PROMPT=0 git fetch --force "https\\://x-access-token\\:${token}\\@github.com\\/o\\/r" main`,
121
+ `git fetch x-access-token:${token}@github.com`,
122
+ ]) {
123
+ const output = redactSensitiveText(command);
124
+ expect(output).to.not.include(token);
125
+ expect(output).to.match(/\*\*\*|\[REDACTED\]/);
126
+ }
127
+ });
128
+
129
+ it('filters every database password form used by the db workflow', () => {
130
+ for (const command of [
131
+ 'mariadb -u root -psecret database',
132
+ 'mariadb -u root -p "secret" database',
133
+ 'mariadb-dump --user=root --password=secret database',
134
+ 'mongosh -u root -p "secret"',
135
+ 'mongorestore --username root --password "secret"',
136
+ 'MYSQL_PWD=secret mariadb database',
137
+ 'mongodb://root:secret@mongo/database',
138
+ ])
139
+ expect(redactSensitiveText(command), command).to.not.include('secret');
140
+ });
141
+ });
@@ -0,0 +1,457 @@
1
+ import { expect } from 'chai';
2
+ import fs from 'fs-extra';
3
+ import shell from 'shelljs';
4
+ import { program } from '../../src/cli/index.js';
5
+ import {
6
+ STAGED_CLI_PACKAGE,
7
+ deployDependencySpecsFactory,
8
+ packageRepositoryFactory,
9
+ renamePackage,
10
+ setPackageRepository,
11
+ buildDeployPackageJson,
12
+ buildProductPackageJson,
13
+ deployPackageNameFactory,
14
+ deployPackagePathFactory,
15
+ productDevDependenciesFactory,
16
+ productPackageOptionsFactory,
17
+ publishedProductPackageJson,
18
+ stagePackageArchive,
19
+ syncDeployPackages,
20
+ } from '../../src/server/build/package.js';
21
+ import path from 'node:path';
22
+ import os from 'node:os';
23
+ import { loadDeployCatalog } from '../../src/server/build/catalog.js';
24
+
25
+ // Through the resolver, never a static import: the base template ships no product module, and a
26
+ // checkout that carries none has to load the suite rather than fail to import it.
27
+ const cyberiaCatalog = await loadDeployCatalog('dd-cyberia');
28
+
29
+ describe('generated product package dependencies', () => {
30
+ it('keeps the engine toolchain for checkout tests without duplicating runtime dependencies', () => {
31
+ expect(
32
+ productDevDependenciesFactory({
33
+ engineDependencies: {
34
+ 'runtime-shared': '1.0.0',
35
+ vitest: '4.1.11',
36
+ },
37
+ engineDevDependencies: {
38
+ 'engine-dev-only': '2.0.0',
39
+ },
40
+ productDependencies: {
41
+ 'runtime-shared': '3.0.0',
42
+ nodemailer: '^10.0.0',
43
+ },
44
+ productDevDependencies: {
45
+ 'product-dev-only': '4.0.0',
46
+ },
47
+ }),
48
+ ).to.deep.equal({
49
+ vitest: '4.1.11',
50
+ 'engine-dev-only': '2.0.0',
51
+ 'product-dev-only': '4.0.0',
52
+ });
53
+ });
54
+
55
+ it('accepts manifests without optional dependency groups', () => {
56
+ expect(productDevDependenciesFactory()).to.deep.equal({});
57
+ });
58
+
59
+ it('builds a product manifest declaratively without mutating the template', () => {
60
+ const basePackageJson = {
61
+ name: 'pwa-microservices-template',
62
+ description: 'Base template',
63
+ repository: { url: 'https://github.com/underpostnet/pwa-microservices-template.git' },
64
+ bin: { underpost: 'bin/index.js' },
65
+ dependencies: { express: '5.2.1' },
66
+ scripts: { test: 'node bin test' },
67
+ };
68
+
69
+ const result = buildProductPackageJson({
70
+ basePackageJson,
71
+ sourcePackageJson: {
72
+ dependencies: { express: '5.2.1', vitest: '4.1.11' },
73
+ },
74
+ catalog: { description: 'Cyberia CLI', keywords: ['cyberia'] },
75
+ confName: 'dd-cyberia',
76
+ customDependencies: { nodemailer: '^10.0.0' },
77
+ customScripts: { build: 'node bin client' },
78
+ customBin: { cyberia: 'bin/index.js' },
79
+ });
80
+
81
+ expect(result).to.deep.include({
82
+ name: 'cyberia',
83
+ description: 'Cyberia CLI',
84
+ keywords: ['cyberia'],
85
+ bin: { cyberia: 'bin/index.js' },
86
+ dependencies: { nodemailer: '^10.0.0' },
87
+ devDependencies: { express: '5.2.1', vitest: '4.1.11' },
88
+ scripts: { test: 'node bin test', build: 'node bin client' },
89
+ });
90
+ expect(result.repository.url).to.equal('https://github.com/underpostnet/engine-cyberia.git');
91
+ expect(basePackageJson).to.deep.equal({
92
+ name: 'pwa-microservices-template',
93
+ description: 'Base template',
94
+ repository: { url: 'https://github.com/underpostnet/pwa-microservices-template.git' },
95
+ bin: { underpost: 'bin/index.js' },
96
+ dependencies: { express: '5.2.1' },
97
+ scripts: { test: 'node bin test' },
98
+ });
99
+ });
100
+
101
+ it('preserves the base runtime manifest when no product overrides are declared', () => {
102
+ const result = buildProductPackageJson({
103
+ basePackageJson: {
104
+ name: 'template',
105
+ dependencies: { express: '5.2.1' },
106
+ devDependencies: { vitest: '4.1.11' },
107
+ scripts: { test: 'vitest' },
108
+ },
109
+ confName: 'dd-core',
110
+ });
111
+
112
+ expect(result).to.deep.include({
113
+ name: 'core',
114
+ dependencies: { express: '5.2.1' },
115
+ devDependencies: { vitest: '4.1.11' },
116
+ scripts: { test: 'vitest' },
117
+ });
118
+ });
119
+ });
120
+
121
+ describe('package archive staging', () => {
122
+ let fixturePath;
123
+
124
+ afterEach(() => {
125
+ vi.restoreAllMocks();
126
+ if (fixturePath) fs.removeSync(fixturePath);
127
+ });
128
+
129
+ it('packs in isolation and replaces the stable build-context archive', () => {
130
+ fixturePath = fs.mkdtempSync('/tmp/engine-package-stage-');
131
+ const packagePath = `${fixturePath}/source package`;
132
+ const outputPath = `${fixturePath}/build context`;
133
+ fs.outputJsonSync(`${packagePath}/package.json`, { name: 'example-package', version: '1.2.3' });
134
+ fs.outputFileSync(`${outputPath}/${STAGED_CLI_PACKAGE}`, 'old');
135
+
136
+ let temporaryPath;
137
+ const exec = vi.spyOn(shell, 'exec').mockImplementation((command) => {
138
+ temporaryPath = command.match(/--pack-destination '([^']+)'/)?.[1];
139
+ fs.outputFileSync(`${temporaryPath}/example-package-1.2.3.tgz`, 'new');
140
+ return { code: 0, stdout: '', stderr: '' };
141
+ });
142
+
143
+ const stagedPath = stagePackageArchive({
144
+ stagedFileName: STAGED_CLI_PACKAGE,
145
+ outputPath,
146
+ packagePath,
147
+ });
148
+
149
+ expect(stagedPath).to.equal(`${outputPath}/${STAGED_CLI_PACKAGE}`);
150
+ expect(fs.readFileSync(stagedPath, 'utf8')).to.equal('new');
151
+ expect(fs.existsSync(temporaryPath)).to.equal(false);
152
+ expect(exec.mock.calls[0][0]).to.include("--ignore-scripts --pack-destination '");
153
+ expect(exec.mock.calls[0][0]).to.include(`'${packagePath}'`);
154
+ expect(exec.mock.calls[0][1]).to.deep.equal({ silent: true });
155
+ });
156
+
157
+ it('rejects staged names that can escape the output directory', () => {
158
+ expect(() => stagePackageArchive({ stagedFileName: '../package.tgz' })).to.throw(
159
+ 'stagePackageArchive requires a file name without a directory',
160
+ );
161
+ });
162
+ });
163
+
164
+ describe('generated deploy package manifests', () => {
165
+ const enginePackageJson = {
166
+ name: 'underpost-engine',
167
+ type: 'module',
168
+ version: '3.3.0',
169
+ description: 'engine',
170
+ keywords: ['engine'],
171
+ bin: { underpost: 'bin/index.js' },
172
+ scripts: { start: 'node src/server', fix: 'npm audit fix --force', test: 'node bin test' },
173
+ dependencies: { express: '5.2.1' },
174
+ overrides: { ws: '^8.20.2' },
175
+ };
176
+
177
+ it('gives a deploy without a catalog the engine manifest under its own identity', () => {
178
+ // The default is the whole point: a new deploy id declares nothing and still gets a
179
+ // manifest the checkout can install and the CLI can run from.
180
+ const manifest = buildDeployPackageJson({ deployId: 'dd-new', enginePackageJson });
181
+
182
+ expect(manifest.name).to.equal('new');
183
+ expect(manifest.scripts.start).to.equal('node --max-old-space-size=8192 src/server dd-new');
184
+ expect(manifest.scripts.fix).to.equal('npm audit fix --force');
185
+ expect(manifest.dependencies).to.deep.equal({ express: '5.2.1' });
186
+ expect(manifest.overrides).to.deep.equal({ ws: '^8.20.2' });
187
+ // The engine's command stays linkable: this manifest is installed over the checkout.
188
+ expect(manifest.bin).to.deep.equal({ underpost: 'bin/index.js' });
189
+ });
190
+
191
+ it('adds exactly what the catalog declares, and nothing else', () => {
192
+ const manifest = buildDeployPackageJson({
193
+ deployId: 'dd-cyberia',
194
+ enginePackageJson,
195
+ catalog: {
196
+ packageName: 'cyberia',
197
+ description: 'Cyberia CLI',
198
+ keywords: ['cyberia'],
199
+ packageBin: { cyberia: 'bin/index.js' },
200
+ packageDependencies: { ethers: '~6.16.0' },
201
+ packageScripts: { 'docker:up': 'node bin docker-compose --up' },
202
+ },
203
+ });
204
+
205
+ expect(manifest.name).to.equal('cyberia');
206
+ expect(manifest.description).to.equal('Cyberia CLI');
207
+ expect(manifest.keywords).to.deep.equal(['cyberia']);
208
+ expect(manifest.dependencies).to.deep.equal({ express: '5.2.1', ethers: '~6.16.0' });
209
+ expect(manifest.scripts['docker:up']).to.equal('node bin docker-compose --up');
210
+ expect(manifest.bin).to.deep.equal({ underpost: 'bin/index.js' });
211
+ });
212
+
213
+ it.skipIf(!Object.keys(cyberiaCatalog.packageBin).length)(
214
+ 'publishes the product identity only when asked for it',
215
+ () => {
216
+ expect(
217
+ buildDeployPackageJson({
218
+ deployId: 'dd-cyberia',
219
+ enginePackageJson,
220
+ catalog: cyberiaCatalog,
221
+ productIdentity: true,
222
+ }).bin,
223
+ ).to.deep.equal({ cyberia: 'bin/index.js', underpost: 'bin/index.js' });
224
+ },
225
+ );
226
+
227
+ it('keeps a start script the deploy already declared', () => {
228
+ // dd-cron starts a cron applier, not the engine server; regenerating must not overwrite it.
229
+ const manifest = buildDeployPackageJson({
230
+ deployId: 'dd-cron',
231
+ enginePackageJson,
232
+ currentPackageJson: { scripts: { start: 'kubectl apply -f ./manifests/cronjobs' } },
233
+ });
234
+ expect(manifest.scripts.start).to.equal('kubectl apply -f ./manifests/cronjobs');
235
+ });
236
+
237
+ it('refuses to guess what it was not given', () => {
238
+ expect(() => buildDeployPackageJson({ enginePackageJson })).to.throw('deployId');
239
+ expect(() => buildDeployPackageJson({ deployId: 'dd-new' })).to.throw('enginePackageJson');
240
+ });
241
+
242
+ it('names each deploy manifest one way, wherever it is generated', () => {
243
+ expect(deployPackageNameFactory('dd-core')).to.equal('core');
244
+ expect(deployPackageNameFactory('dd-cyberia', { packageName: 'cyberia' })).to.equal('cyberia');
245
+ expect(deployPackagePathFactory('dd-core')).to.equal('./engine-private/conf/dd-core/package.json');
246
+ });
247
+
248
+ it('writes one manifest per deploy id in the configuration tree', async () => {
249
+ const confRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'underpost-conf-'));
250
+ try {
251
+ fs.outputJsonSync(`${confRoot}/dd-one/package.json`, { name: 'engine', scripts: { start: 'custom' } });
252
+ fs.outputJsonSync(`${confRoot}/dd-two/conf.server.json`, {});
253
+
254
+ const synced = await syncDeployPackages({ confRoot, enginePackageJson });
255
+
256
+ // Only deploy ids that carry a manifest: a conf directory without one is not a package.
257
+ expect(synced.map(({ deployId }) => deployId)).to.deep.equal(['dd-one']);
258
+ const written = fs.readJsonSync(`${confRoot}/dd-one/package.json`);
259
+ expect(written.name).to.equal('one');
260
+ expect(written.scripts.start).to.equal('custom');
261
+ expect(written.dependencies).to.deep.equal({ express: '5.2.1' });
262
+ } finally {
263
+ fs.removeSync(confRoot);
264
+ }
265
+ });
266
+ });
267
+
268
+ describe('product manifest overrides read the catalog', () => {
269
+ it('carries the engine runtime dependencies alongside the catalog pins', () => {
270
+ // Regression: the product depended on the published `underpost` package instead, which
271
+ // installed a second engine whose nested `nodemailer` `src/` could not resolve, while the
272
+ // hoistable copy survived only as a dev entry a production install omits.
273
+ const options = productPackageOptionsFactory({
274
+ catalog: {
275
+ packageDependencies: { ethers: '~6.16.0' },
276
+ packageBin: { cyberia: 'bin/index.js' },
277
+ packageScripts: { 'docker:up': 'node bin docker-compose --up' },
278
+ },
279
+ engineDependencies: { express: '^5.2.1', nodemailer: '^10.0.0' },
280
+ });
281
+
282
+ expect(options).to.deep.equal({
283
+ customDependencies: { express: '^5.2.1', nodemailer: '^10.0.0', ethers: '~6.16.0' },
284
+ customScripts: { 'docker:up': 'node bin docker-compose --up' },
285
+ customBin: { cyberia: 'bin/index.js' },
286
+ });
287
+ expect(options.customDependencies).to.not.have.property('underpost');
288
+ });
289
+
290
+ it('lets a catalog pin override the engine version of the same dependency', () => {
291
+ expect(
292
+ productPackageOptionsFactory({
293
+ catalog: { packageDependencies: { sharp: '^0.35.3' } },
294
+ engineDependencies: { sharp: '^0.34.0' },
295
+ }).customDependencies,
296
+ ).to.deep.equal({ sharp: '^0.35.3' });
297
+ });
298
+
299
+ it('leaves the base template manifest alone for a catalog that declares no package', () => {
300
+ expect(productPackageOptionsFactory({ catalog: {}, engineDependencies: { express: '^5.2.1' } })).to.deep.equal({});
301
+ });
302
+ });
303
+
304
+ describe('the manifest a product publishes to npm', () => {
305
+ it('trades the engine runtime set for the published CLI and the catalog pins', () => {
306
+ const published = publishedProductPackageJson({
307
+ packageJson: {
308
+ name: 'cyberia',
309
+ version: '3.3.73',
310
+ dependencies: { express: '^5.2.1', nodemailer: '^10.0.0', sharp: '^0.35.3' },
311
+ devDependencies: { vitest: '5.0.0' },
312
+ },
313
+ catalog: { packageDependencies: { sharp: '^0.35.3', ethers: '~6.16.0' } },
314
+ });
315
+
316
+ expect(published.dependencies).to.deep.equal({ underpost: '^3.3.73', sharp: '^0.35.3', ethers: '~6.16.0' });
317
+ expect(published.devDependencies).to.deep.equal({
318
+ express: '^5.2.1',
319
+ nodemailer: '^10.0.0',
320
+ vitest: '5.0.0',
321
+ });
322
+ expect(published.name).to.equal('cyberia');
323
+ });
324
+
325
+ it('pins the engine CLI at the version it is given, tag stripped', () => {
326
+ expect(
327
+ publishedProductPackageJson({ packageJson: { version: '3.3.73' }, underpostVersion: 'v4.0.0' }).dependencies,
328
+ ).to.deep.equal({ underpost: '^4.0.0' });
329
+ });
330
+
331
+ it('refuses a manifest it cannot pin the engine CLI from', () => {
332
+ expect(() => publishedProductPackageJson()).to.throw('packageJson');
333
+ expect(() => publishedProductPackageJson({ packageJson: { name: 'cyberia' } })).to.throw('version');
334
+ });
335
+
336
+ it('leaves the repository manifest as the checkout installs from', () => {
337
+ const packageJson = { version: '1.0.0', dependencies: { express: '^5.2.1' } };
338
+ publishedProductPackageJson({ packageJson });
339
+
340
+ expect(packageJson).to.deep.equal({ version: '1.0.0', dependencies: { express: '^5.2.1' } });
341
+ });
342
+ });
343
+
344
+ describe('the package command is the one entry point to these manifests', () => {
345
+ const packageCommand = () => program.commands.find((command) => command.name() === 'package');
346
+
347
+ it('acts on a deploy id, not on a product it names', () => {
348
+ // Regression: the same two operations lived as `deploy cyberia` and `deploy
349
+ // update-dependencies`, one of them naming a single product in a build script.
350
+ const command = packageCommand();
351
+ expect(command, 'underpost package').to.exist;
352
+ expect(command.options.map(({ long }) => long)).to.have.members([
353
+ '--sync',
354
+ '--install',
355
+ '--rename',
356
+ '--set-repo',
357
+ '--dry-run',
358
+ ]);
359
+ expect(command.registeredArguments.map((argument) => argument.name())).to.deep.equal(['deploy-id']);
360
+ });
361
+
362
+ it('pins its installs from the catalog it generates manifests from', () => {
363
+ expect(
364
+ deployDependencySpecsFactory({ packageDependencies: { ethers: '~6.16.0', sharp: '^0.35.3' } }),
365
+ ).to.deep.equal(['ethers@~6.16.0', 'sharp@^0.35.3']);
366
+ expect(deployDependencySpecsFactory()).to.deep.equal([]);
367
+ });
368
+
369
+ it('regenerates only the deploy ids it was given', async () => {
370
+ const confRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'underpost-conf-'));
371
+ try {
372
+ for (const deployId of ['dd-one', 'dd-two'])
373
+ fs.outputJsonSync(`${confRoot}/${deployId}/package.json`, { name: 'engine' });
374
+
375
+ const synced = await syncDeployPackages({
376
+ deployIds: ['dd-two'],
377
+ confRoot,
378
+ enginePackageJson: { name: 'underpost-engine', dependencies: {}, scripts: {} },
379
+ });
380
+
381
+ expect(synced.map(({ deployId }) => deployId)).to.deep.equal(['dd-two']);
382
+ expect(fs.readJsonSync(`${confRoot}/dd-one/package.json`).name).to.equal('engine');
383
+ expect(fs.readJsonSync(`${confRoot}/dd-two/package.json`).name).to.equal('two');
384
+ } finally {
385
+ fs.removeSync(confRoot);
386
+ }
387
+ });
388
+ });
389
+
390
+ describe('package identity is written in one place', () => {
391
+ const checkout = () => {
392
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'underpost-package-identity-'));
393
+ fs.outputJsonSync(path.join(root, 'package.json'), { name: 'engine', version: '1.0.0' });
394
+ return root;
395
+ };
396
+
397
+ it('renames the manifest and the lockfile together', () => {
398
+ // npm refuses an install where the two disagree, so they are one operation.
399
+ const root = checkout();
400
+ try {
401
+ fs.outputJsonSync(path.join(root, 'package-lock.json'), {
402
+ name: 'engine',
403
+ packages: { '': { name: 'engine', version: '1.0.0' } },
404
+ });
405
+
406
+ const { files } = renamePackage({
407
+ name: '@underpostnet/underpost',
408
+ packagePath: path.join(root, 'package.json'),
409
+ lockPath: path.join(root, 'package-lock.json'),
410
+ });
411
+
412
+ expect(files).to.have.lengthOf(2);
413
+ expect(fs.readJsonSync(path.join(root, 'package.json')).name).to.equal('@underpostnet/underpost');
414
+ const lock = fs.readJsonSync(path.join(root, 'package-lock.json'));
415
+ expect(lock.name).to.equal('@underpostnet/underpost');
416
+ expect(lock.packages[''].name).to.equal('@underpostnet/underpost');
417
+ } finally {
418
+ fs.removeSync(root);
419
+ }
420
+ });
421
+
422
+ it('renames a checkout that has no lockfile', () => {
423
+ const root = checkout();
424
+ try {
425
+ const { files } = renamePackage({
426
+ name: 'cyberia',
427
+ packagePath: path.join(root, 'package.json'),
428
+ lockPath: path.join(root, 'package-lock.json'),
429
+ });
430
+ expect(files).to.deep.equal([path.join(root, 'package.json')]);
431
+ expect(fs.readJsonSync(path.join(root, 'package.json')).name).to.equal('cyberia');
432
+ } finally {
433
+ fs.removeSync(root);
434
+ }
435
+ });
436
+
437
+ it('points a package at a repository, in the one form npm publishes', () => {
438
+ const root = checkout();
439
+ try {
440
+ expect(packageRepositoryFactory('underpostnet/engine')).to.deep.equal({
441
+ type: 'git',
442
+ url: 'git+https://github.com/underpostnet/engine.git',
443
+ });
444
+ setPackageRepository({ slug: 'underpostnet/engine-ghpkg', packagePath: path.join(root, 'package.json') });
445
+ expect(fs.readJsonSync(path.join(root, 'package.json')).repository.url).to.equal(
446
+ 'git+https://github.com/underpostnet/engine-ghpkg.git',
447
+ );
448
+ } finally {
449
+ fs.removeSync(root);
450
+ }
451
+ });
452
+
453
+ it('refuses to write an identity it was not given', () => {
454
+ expect(() => renamePackage({})).to.throw('name');
455
+ expect(() => setPackageRepository({})).to.throw('slug');
456
+ });
457
+ });