@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,61 @@
1
+ /**
2
+ * One audio asset: what it is, never when it plays.
3
+ *
4
+ * The asset carries its identity (`code`), its bytes (`fileId`) and the manifest the recorder
5
+ * wrote beside them. It holds no classification of its own: whether a sound behaves as a bed, a
6
+ * one-shot or a transition is a property of the context that binds it — see
7
+ * cyberia-map-audio-conf — not of the asset, which the same map or several maps may reuse.
8
+ *
9
+ * @module src/api/cyberia-audio/cyberia-audio.model.js
10
+ * @namespace CyberiaAudioModelServer
11
+ */
12
+
13
+ import { Schema, model } from 'mongoose';
14
+
15
+ // https://mongoosejs.com/docs/2.7.x/docs/schematypes.html
16
+
17
+ // Mirrors the `<name-out>.json` manifest the cyberia-audio package writes beside every recorded
18
+ // WAV. `defaults` and `parameters` are the asset's own parameter contract, so they stay
19
+ // free-form: each asset owns its parameter names and ranges.
20
+ const ManifestSchema = new Schema(
21
+ {
22
+ id: { type: String, required: true },
23
+ // The bus the module was authored on — `src/audio-module/<bus-id>/` in the cyberia-audio
24
+ // package, and the same vocabulary a binding's `settings.bus` selects. It is the asset's
25
+ // natural route, not a decision: a map binding chooses where an asset actually plays.
26
+ bus: { type: String, default: '', trim: true },
27
+ tags: [{ type: String }],
28
+ author: { type: String, required: true },
29
+ version: { type: String, required: true },
30
+ duration: { type: Number, required: true },
31
+ sampleRate: { type: Number },
32
+ channels: { type: Number },
33
+ loop: { type: Boolean, default: false },
34
+ audio: { type: String, default: '' },
35
+ defaults: { type: Schema.Types.Mixed, default: {} },
36
+ parameters: { type: Schema.Types.Mixed, default: {} },
37
+ },
38
+ { _id: false },
39
+ );
40
+
41
+ const CyberiaAudioSchema = new Schema(
42
+ {
43
+ // The asset's canonical identity across the platform: what a map binding, an import and an
44
+ // export all refer to. It is unique on its own, so a reference needs nothing beside it.
45
+ code: { type: String, required: true, trim: true },
46
+ fileId: { type: Schema.Types.ObjectId, ref: 'File' },
47
+ manifest: { type: ManifestSchema, required: true },
48
+ },
49
+ {
50
+ timestamps: true,
51
+ },
52
+ );
53
+
54
+ // Declared here rather than as `index: true` on the field, so the unique index is defined once.
55
+ CyberiaAudioSchema.index({ code: 1 }, { unique: true });
56
+
57
+ const CyberiaAudioModel = model('CyberiaAudio', CyberiaAudioSchema);
58
+
59
+ const ProviderSchema = CyberiaAudioSchema;
60
+
61
+ export { CyberiaAudioSchema, CyberiaAudioModel, ProviderSchema };
@@ -0,0 +1,21 @@
1
+ import express from 'express';
2
+ import { registerCrudRoutes } from '../../server/network/middlewares.js';
3
+ import { CyberiaAudioController } from './cyberia-audio.controller.js';
4
+
5
+ class CyberiaAudioRouter {
6
+ /**
7
+ * @param {import('../types.js').RouterOptions} options
8
+ * @returns {import('express').Router}
9
+ */
10
+ static router(options) {
11
+ // Fully unguarded (matches prior behavior).
12
+ return registerCrudRoutes(express.Router(), CyberiaAudioController, options, {
13
+ writeGuards: [],
14
+ deleteAllGuards: [],
15
+ });
16
+ }
17
+ }
18
+
19
+ const ApiRouter = (options) => CyberiaAudioRouter.router(options);
20
+
21
+ export { ApiRouter, CyberiaAudioRouter };
@@ -0,0 +1,220 @@
1
+ import crypto from 'crypto';
2
+ import fs from 'fs-extra';
3
+ import nodePath from 'path';
4
+ import { Types } from 'mongoose';
5
+ import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
6
+ import { FileCleanup } from '../file/file.service.js';
7
+ import { loggerFactory } from '../../server/ops/logger.js';
8
+ import { DataQuery } from '../../server/storage/data-query.js';
9
+ import { fileRefFields } from '../file/file.ref.js';
10
+
11
+ const logger = loggerFactory(import.meta);
12
+
13
+ const AUDIO_MIMETYPE = 'audio/wav';
14
+
15
+ /** The File-referencing fields of this model, read from the registry that owns that mapping. */
16
+ const FILE_FIELDS = fileRefFields('cyberia-audio');
17
+
18
+ /**
19
+ * The generic File `_id` an asset's bytes resolve through, derived from the asset code and the
20
+ * bytes themselves.
21
+ *
22
+ * Content-addressed on purpose. The client fetches a WAV as `/api/file/blob/<fileId>` and caches
23
+ * it, so re-recording an asset under a stable id would serve the old sound from that cache
24
+ * forever. A changed render therefore lands on a new id — and the import deletes the one it
25
+ * replaced, so the change costs nothing. Identical bytes re-derive the same id, which is what
26
+ * makes re-importing an unchanged bank a no-op rather than a churn of File documents.
27
+ *
28
+ * The code is folded in so two assets that happen to render identical bytes still own separate
29
+ * File documents; sharing one would make deleting either orphan the other.
30
+ *
31
+ * @param {string} code - Asset code.
32
+ * @param {string} md5 - Hex MD5 of the WAV bytes.
33
+ * @returns {import('mongoose').Types.ObjectId}
34
+ */
35
+ const audioFileId = (code, md5) =>
36
+ new Types.ObjectId(crypto.createHash('sha256').update(`cyberia-audio:${code}:${md5}`).digest('hex').slice(0, 24));
37
+
38
+ /**
39
+ * Validates a `<name>.json` sidecar written by the cyberia-audio package, and reads it into the
40
+ * shape this platform stores.
41
+ *
42
+ * Identity is all the import requires: `id` becomes the asset's code, and the rest is the
43
+ * recorder's own metadata — including `bus`, the `src/audio-module/<bus-id>/` directory the
44
+ * module was authored on, which is the same bus vocabulary a map binding routes through.
45
+ *
46
+ * @param {object} manifest - Parsed manifest.
47
+ * @param {string} manifestPath - Source path, for error messages.
48
+ * @returns {object} The manifest as stored.
49
+ * @throws {Error} When the manifest carries no usable asset identity.
50
+ */
51
+ const readManifest = (manifest, manifestPath) => {
52
+ if (!manifest || typeof manifest !== 'object') throw new Error(`Invalid audio manifest: ${manifestPath}`);
53
+ if (!manifest.id) throw new Error(`Audio manifest has no id: ${manifestPath}`);
54
+ const { bus = '', ...rest } = manifest;
55
+ return { ...rest, bus };
56
+ };
57
+
58
+ class CyberiaAudioService {
59
+ /**
60
+ * Imports one recorded `<name>.wav` + `<name>.json` pair, upserting both the backing
61
+ * File document and the CyberiaAudio document keyed by the asset's code.
62
+ *
63
+ * @param {{wavPath: string, manifestPath: string}} record - Absolute or cwd-relative artifact pair.
64
+ * @param {{host: string, path: string}} options - Provider context.
65
+ * @returns {Promise<object>} The upserted CyberiaAudio document.
66
+ */
67
+ static importRecord = async ({ wavPath, manifestPath }, options) => {
68
+ const CyberiaAudio = DataBaseProviderService.getModel('CyberiaAudio', options);
69
+ const File = DataBaseProviderService.getModel('file', options);
70
+
71
+ const manifest = readManifest(JSON.parse(await fs.readFile(manifestPath, 'utf8')), manifestPath);
72
+ const data = await fs.readFile(wavPath);
73
+ const md5 = crypto.createHash('md5').update(data).digest('hex');
74
+ const fileData = { name: `${manifest.id}.wav`, data, size: data.length, mimetype: AUDIO_MIMETYPE, md5 };
75
+
76
+ await new CyberiaAudio({ code: manifest.id, manifest }).validate();
77
+ if (
78
+ 44 > data.length ||
79
+ data.length > 8 * 1024 * 1024 ||
80
+ data.toString('ascii', 0, 4) !== 'RIFF' ||
81
+ data.toString('ascii', 8, 12) !== 'WAVE' ||
82
+ data.readUInt32LE(4) !== data.length - 8
83
+ )
84
+ throw new Error(`Invalid WAV: ${wavPath}`);
85
+
86
+ const existing = await CyberiaAudio.findOne({ code: manifest.id });
87
+ // Derived from the bytes, so it is the same id on an unchanged re-import and a new one the
88
+ // moment the render changes. Writing the File first leaves the bytes reachable if the run is
89
+ // interrupted before the metadata upsert; the stale document is then dropped on the next run.
90
+ const fileId = audioFileId(manifest.id, md5);
91
+ await File.findOneAndUpdate(
92
+ { _id: fileId },
93
+ { $set: fileData },
94
+ { upsert: true, returnDocument: 'after', runValidators: true },
95
+ );
96
+
97
+ const doc = await CyberiaAudio.findOneAndUpdate(
98
+ { code: manifest.id },
99
+ { $set: { code: manifest.id, fileId, manifest } },
100
+ { upsert: true, returnDocument: 'after', runValidators: true },
101
+ );
102
+
103
+ // Only once the asset points at the new bytes: the superseded blob is unreferenced from here
104
+ // on, and leaving it behind is what orphans a File document.
105
+ if (existing) {
106
+ await FileCleanup.cleanupReplacedFiles({
107
+ oldDoc: existing,
108
+ newData: { fileId },
109
+ fileFields: FILE_FIELDS,
110
+ File,
111
+ });
112
+ }
113
+ return doc;
114
+ };
115
+
116
+ /**
117
+ * Deletes an asset and the File document holding its bytes.
118
+ *
119
+ * The asset is the only reference to that blob, so dropping one without the other is exactly
120
+ * what `underpost db clean-fs` would later have to sweep up.
121
+ *
122
+ * @param {Array<object>} assets - CyberiaAudio documents about to be removed.
123
+ * @param {{host: string, path: string}} options - Provider context.
124
+ * @returns {Promise<number>} Count of File documents deleted.
125
+ */
126
+ static deleteBackingFiles = async (assets, options) => {
127
+ const File = DataBaseProviderService.getModel('file', options);
128
+ let deleted = 0;
129
+ for (const asset of assets) {
130
+ const ids = await FileCleanup.deleteDocumentFiles({ doc: asset, fileFields: FILE_FIELDS, File });
131
+ deleted += ids.length;
132
+ }
133
+ return deleted;
134
+ };
135
+
136
+ /**
137
+ * Imports every valid `<name>.wav` + `<name>.json` pair found in a records directory.
138
+ * A WAV with no manifest beside it is skipped with a warning: the pair is the unit of import.
139
+ *
140
+ * @param {{recordsPath: string, codes?: Array<string>|null}} params - Source directory and optional code filter.
141
+ * @param {{host: string, path: string}} options - Provider context.
142
+ * @returns {Promise<Array<object>>} The upserted CyberiaAudio documents.
143
+ */
144
+ static importRecords = async ({ recordsPath, codes = null }, options) => {
145
+ if (!(await fs.pathExists(recordsPath))) throw new Error(`Records directory not found: ${recordsPath}`);
146
+
147
+ const stems = (await fs.readdir(recordsPath))
148
+ .filter((name) => name.toLowerCase().endsWith('.wav'))
149
+ .map((name) => nodePath.basename(name, nodePath.extname(name)))
150
+ .filter((stem) => !codes || codes.includes(stem))
151
+ .sort();
152
+
153
+ if (codes) {
154
+ for (const code of codes) if (!stems.includes(code)) throw new Error(`No ${code}.wav found in ${recordsPath}`);
155
+ }
156
+
157
+ const imported = [];
158
+ for (const stem of stems) {
159
+ const wavPath = nodePath.join(recordsPath, `${stem}.wav`);
160
+ const manifestPath = nodePath.join(recordsPath, `${stem}.json`);
161
+ if (!(await fs.pathExists(manifestPath))) {
162
+ logger.warn(`Skipping ${stem}.wav: no ${stem}.json manifest beside it`);
163
+ continue;
164
+ }
165
+ const doc = await CyberiaAudioService.importRecord({ wavPath, manifestPath }, options);
166
+ logger.info(`Imported ${doc.code}`, { _id: doc._id.toString(), fileId: doc.fileId.toString() });
167
+ imported.push(doc);
168
+ }
169
+ return imported;
170
+ };
171
+
172
+ static post = async (req, res, options) => {
173
+ /** @type {import('./cyberia-audio.model.js').CyberiaAudioModel} */
174
+ const CyberiaAudio = DataBaseProviderService.getModel('CyberiaAudio', options);
175
+ return await new CyberiaAudio(req.body).save();
176
+ };
177
+ static get = async (req, res, options) => {
178
+ /** @type {import('./cyberia-audio.model.js').CyberiaAudioModel} */
179
+ const CyberiaAudio = DataBaseProviderService.getModel('CyberiaAudio', options);
180
+ if (req.params.id) return await CyberiaAudio.findById(req.params.id);
181
+
182
+ // Parse query parameters using DataQuery helper
183
+ const { query, sort, skip, limit, page } = DataQuery.parse(req.query);
184
+
185
+ const [data, total] = await Promise.all([
186
+ CyberiaAudio.find(query).sort(sort).limit(limit).skip(skip),
187
+ CyberiaAudio.countDocuments(query),
188
+ ]);
189
+
190
+ const totalPages = Math.ceil(total / limit);
191
+ return { data, total, page, totalPages };
192
+ };
193
+ static put = async (req, res, options) => {
194
+ /** @type {import('./cyberia-audio.model.js').CyberiaAudioModel} */
195
+ const CyberiaAudio = DataBaseProviderService.getModel('CyberiaAudio', options);
196
+ const File = DataBaseProviderService.getModel('file', options);
197
+ const existing = await CyberiaAudio.findById(req.params.id);
198
+ const updated = await CyberiaAudio.findByIdAndUpdate(req.params.id, req.body, { returnDocument: 'after' });
199
+ // Repointing an asset at other bytes leaves the previous blob referenced by nothing.
200
+ if (existing) {
201
+ await FileCleanup.cleanupReplacedFiles({
202
+ oldDoc: existing,
203
+ newData: req.body,
204
+ fileFields: FILE_FIELDS,
205
+ File,
206
+ });
207
+ }
208
+ return updated;
209
+ };
210
+ static delete = async (req, res, options) => {
211
+ /** @type {import('./cyberia-audio.model.js').CyberiaAudioModel} */
212
+ const CyberiaAudio = DataBaseProviderService.getModel('CyberiaAudio', options);
213
+ const assets = req.params.id ? await CyberiaAudio.find({ _id: req.params.id }) : await CyberiaAudio.find();
214
+ await CyberiaAudioService.deleteBackingFiles(assets, options);
215
+ if (req.params.id) return await CyberiaAudio.findByIdAndDelete(req.params.id);
216
+ return await CyberiaAudio.deleteMany();
217
+ };
218
+ }
219
+
220
+ export { CyberiaAudioService, audioFileId, readManifest };
@@ -1,4 +1,4 @@
1
- import { controllerHandler, sendSuccess } from '../../server/middlewares.js';
1
+ import { controllerHandler, sendSuccess } from '../../server/network/middlewares.js';
2
2
  import { CYBERIA_CLIENT_HINTS_DEFAULTS } from '../../client/components/cyberia/SharedDefaultsCyberia.js';
3
3
  import { resolveClientHints } from './cyberia-client-hints.service.js';
4
4
 
@@ -9,9 +9,7 @@ class CyberiaClientHintsController {
9
9
  host: options.host || 'default',
10
10
  path: options.path || '/',
11
11
  });
12
- // Surface the resolution source as a non-authoritative header so
13
- // operators can see whether the runtime fetched from the new
14
- // collection, the compatibility read on instance-conf, the cache, or defaults.
12
+ // Diagnostic header: which source answered this request.
15
13
  res.setHeader('X-Cyberia-Hints-Source', source);
16
14
  return sendSuccess(res, data);
17
15
  },
@@ -1,15 +1,9 @@
1
1
  /**
2
- * Mongoose model for `CyberiaClientHints`.
2
+ * Mongoose model for `CyberiaClientHints`, the per-instance presentation
3
+ * overrides. Editor flows write it; the game client reads it over REST. The
4
+ * simulation never touches it.
3
5
  *
4
- * Dedicated collection for per-instance presentation overrides.
5
- *
6
- * Ownership:
7
- * - Read by: cyberia-client (via /api/cyberia-client-hints/:code), CMS UIs.
8
- * - Written by: CMS / editor flows. The Cyberia simulation server
9
- * never reads or writes this collection.
10
- * - Cacheable: yes — the service layer keeps an in-memory TTL cache.
11
- *
12
- * Schema scope: purely visual fields. Anything that influences simulation
6
+ * Schema scope: visual fields only. A field that changes the simulation
13
7
  * belongs in `CyberiaInstanceConf`.
14
8
  *
15
9
  * @module src/api/cyberia-client-hints/cyberia-client-hints.model.js
@@ -58,13 +52,10 @@ const EntityColorKeySchema = new Schema(
58
52
 
59
53
  const CyberiaClientHintsSchema = new Schema(
60
54
  {
61
- // Instance code this hint set is scoped to. Matches CyberiaInstance.code
62
- // and CyberiaInstanceConf.instanceCode. Indexed and unique to make the
63
- // service-layer cache a 1-to-1 keyed lookup.
55
+ // Instance code, matching CyberiaInstance.code. Unique: one hint set per code.
64
56
  code: { type: String, required: true, unique: true, index: true },
65
57
 
66
- // Optional palette overrides. Keys not present here fall back to the
67
- // client's compile-time defaults.
58
+ // Palette overrides. An absent key keeps the client default.
68
59
  palette: { type: [PaletteEntrySchema], default: [] },
69
60
 
70
61
  // Optional per-entity-type color-key overrides.
@@ -73,8 +64,8 @@ const CyberiaClientHintsSchema = new Schema(
73
64
  // Optional status-icon visual overrides (id → iconId + borderColor).
74
65
  statusIcons: { type: [StatusIconHintSchema], default: [] },
75
66
 
76
- // Camera, viewport, and cell-sizing tunings null/undefined means
77
- // "use the SharedDefaultsCyberia.RENDER_DEFAULTS value".
67
+ // Camera, viewport and cell-size tunings. null keeps the
68
+ // SharedDefaultsCyberia.RENDER_DEFAULTS value.
78
69
  cellSize: { type: Number, default: null },
79
70
  defaultObjWidth: { type: Number, default: null },
80
71
  defaultObjHeight: { type: Number, default: null },
@@ -85,8 +76,8 @@ const CyberiaClientHintsSchema = new Schema(
85
76
  interpolationMs: { type: Number, default: null },
86
77
  devUi: { type: Boolean, default: null },
87
78
 
88
- // Main UI font: TTF file name under engine assets/fonts/ (null = built-in
89
- // raylib font) and a uniform text-size multiplier.
79
+ // Main UI font: TTF file name under engine assets/fonts/ (null = client
80
+ // built-in font) and a uniform text-size multiplier.
90
81
  fontFamily: { type: String, default: null },
91
82
  fontFactorSize: { type: Number, default: null },
92
83
  },
@@ -1,44 +1,26 @@
1
1
  /**
2
2
  * @module src/api/cyberia-client-hints
3
3
  *
4
- * Client presentation hints — read-only REST endpoint.
4
+ * Client presentation hints — read-only REST endpoint, off the simulation path.
5
+ * It serves optional per-instance overrides of render policy: palette, camera
6
+ * defaults, status-icon visuals, interpolation window, dev-overlay flag.
5
7
  *
6
- * Purpose
7
- * -------
8
- * The cyberia-server (Go authoritative simulation) and the WS init payload
9
- * carry *only* simulation contracts. Client-render policy (palette, camera
10
- * defaults, status-icon visuals, interpolation window, dev-overlay flag)
11
- * lives off the simulation path entirely.
12
- *
13
- * This endpoint exposes optional per-instance overrides of those values.
14
- * The client is required to function with no calls to this endpoint at
15
- * all (it ships built-in defaults that match the canonical engine
16
- * defaults 1-to-1 — see cyberia-client/src/domain/presentation_defaults.h).
17
- *
18
- * Endpoint
19
- * --------
8
+ * Endpoints:
20
9
  * GET /api/cyberia-client-hints/:instanceCode
21
10
  * -> 200 { palette, entityColorKeys, statusIcons, cameraSmoothing,
22
11
  * cameraZoom, defaultWidthScreenFactor,
23
12
  * defaultHeightScreenFactor, interpolationMs, devUi }
24
- * -> 404 if no instance with that code exists in the database — the
25
- * client falls back to its built-in defaults on 404 (this is
26
- * the normal path for stateless servers / fresh deployments).
27
- *
13
+ * -> 404 when no instance carries that code. The client then uses its
14
+ * own built-in defaults, the normal path for a fresh deployment.
28
15
  * GET /api/cyberia-client-hints/
29
- * -> 200 canonical defaults same shape as above, no DB read.
16
+ * -> 200 canonical defaults, same shape, no DB read.
30
17
  *
31
- * What it intentionally does NOT do
32
- * ---------------------------------
33
- * - It does not touch gameplay state (no entity, map, economy, skill,
34
- * equipment, or stat fields).
35
- * - It is not consumed by cyberia-server; the Go process never calls
36
- * this endpoint.
37
- * - It is not authenticated. Presentation hints are not secret.
18
+ * Out of scope: gameplay state and authentication. Presentation hints hold no
19
+ * simulation field and no secret.
38
20
  */
39
21
 
40
22
  import express from 'express';
41
- import { crossOriginMiddleware } from '../../server/middlewares.js';
23
+ import { crossOriginMiddleware } from '../../server/network/middlewares.js';
42
24
  import { CyberiaClientHintsController } from './cyberia-client-hints.controller.js';
43
25
 
44
26
  class CyberiaClientHintsRouter {
@@ -50,15 +32,11 @@ class CyberiaClientHintsRouter {
50
32
  const router = express.Router();
51
33
  router.use(crossOriginMiddleware);
52
34
 
53
- // GET /:code -> resolved hints.
54
- // Resolution order is documented in cyberia-client-hints.service.js:
55
- // 1. In-memory TTL cache.
56
- // 2. CyberiaClientHints collection (preferred).
57
- // 3. Legacy presentation fields on CyberiaInstanceConf (back-compat).
58
- // 4. Canonical client defaults (never cached so a later DB insert wins).
35
+ // GET /:code -> resolved hints. See the resolution order in
36
+ // cyberia-client-hints.service.js.
59
37
  router.get('/:code', async (req, res) => await CyberiaClientHintsController.getByCode(req, res, options));
60
38
 
61
- // GET / -> canonical defaults. No DB read. Documentation/diagnostic.
39
+ // GET / -> canonical defaults. No DB read.
62
40
  router.get('/', async (req, res) => await CyberiaClientHintsController.getDefaults(req, res, options));
63
41
 
64
42
  return router;
@@ -3,27 +3,19 @@
3
3
  *
4
4
  * Read-only service layer for client presentation hints.
5
5
  *
6
- * Resolution order (highest priority first):
7
- * 1. CyberiaClientHints collection the dedicated presentation-overrides
8
- * collection. Always preferred when present.
9
- * 2. Compatibility read on CyberiaInstanceConf with the same `code`
10
- * covers instances seeded before CyberiaClientHints existed.
11
- * 3. Canonical compile-time defaults from
12
- * SharedDefaultsCyberia.js. The C client bakes the
13
- * same defaults at compile time, so this branch returns exactly the
14
- * values the client already has.
6
+ * Resolution order, highest priority first:
7
+ * 1. CyberiaClientHints collection, the dedicated overrides collection.
8
+ * 2. Presentation fields on CyberiaInstanceConf with the same `code`.
9
+ * 3. Canonical defaults from SharedDefaultsCyberia.js, the same values the
10
+ * client holds built in.
15
11
  *
16
- * Caching: in-memory TTL cache keyed by instance code. Read-only on the
17
- * hot path; cache writes happen on cache miss + DB hit. CMS writes that
18
- * mutate the underlying collection should call `clientHintsInvalidate(code)`.
19
- *
20
- * Output is a plain JSON-friendly object whose shape matches the C
21
- * client's compile-time layout.
12
+ * An in-memory TTL cache keyed by instance code serves the hot path. A write
13
+ * to either collection must call `clientHintsInvalidate(code)`.
22
14
  */
23
15
 
24
16
  import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
25
- import { loggerFactory } from '../../server/logger.js';
26
- import { resolveHostKeyContext } from '../../server/conf.js';
17
+ import { loggerFactory } from '../../server/ops/logger.js';
18
+ import { resolveHostKeyContext } from '../../server/runtime/conf.js';
27
19
  import {
28
20
  buildClientHints,
29
21
  CYBERIA_CLIENT_HINTS_DEFAULTS,
@@ -31,8 +23,7 @@ import {
31
23
 
32
24
  const logger = loggerFactory(import.meta);
33
25
 
34
- // TTL chosen long enough that bursty client fetches are absorbed, short
35
- // enough that an editor change shows up within ~30s without manual flush.
26
+ // TTL absorbs bursty client fetches and still shows an editor change in ~30s.
36
27
  const CACHE_TTL_MS = 30_000;
37
28
 
38
29
  // One per instance code. value: { data, expiresAt }
@@ -56,9 +47,7 @@ function cacheSet(code, data) {
56
47
  cache.set(code, { data, expiresAt: now() + CACHE_TTL_MS });
57
48
  }
58
49
 
59
- /** Invalidate a cache entry. CMS write paths should call this after
60
- * mutating either CyberiaClientHints or CyberiaInstanceConf for
61
- * the given code. */
50
+ /** Invalidate one cache entry, or the whole cache when `code` is empty. */
62
51
  export function clientHintsInvalidate(code) {
63
52
  if (code) {
64
53
  cache.delete(code);
@@ -107,7 +96,7 @@ export async function resolveClientHints(code, options = {}) {
107
96
  return { data: CYBERIA_CLIENT_HINTS_DEFAULTS, source: 'defaults' };
108
97
  }
109
98
 
110
- // 1. Preferred CyberiaClientHints collection (src/api/cyberia-client-hints/cyberia-client-hints.model.js).
99
+ // 1. Preferred source: the CyberiaClientHints collection.
111
100
  if (HintsModel && code) {
112
101
  const hint = await HintsModel.findOne({ code }).lean().catch(() => null);
113
102
  if (hint) {
@@ -117,9 +106,7 @@ export async function resolveClientHints(code, options = {}) {
117
106
  }
118
107
  }
119
108
 
120
- // 2. Compatibility read for instances seeded before CyberiaClientHints
121
- // existed, look up the same code in CyberiaInstanceConf and read its
122
- // presentation-shaped fields directly.
109
+ // 2. Instances that keep their presentation fields on CyberiaInstanceConf.
123
110
  if (ConfModel && code) {
124
111
  const fromConf =
125
112
  (await ConfModel.findOne({ code }).lean().catch(() => null)) ||
@@ -131,22 +118,18 @@ export async function resolveClientHints(code, options = {}) {
131
118
  }
132
119
  }
133
120
 
134
- // 3. Any available CyberiaClientHints document — used when the requested
135
- // code has no record yet but another instance (e.g. the one the Go
136
- // server is currently running) does. This avoids pure built-in
137
- // defaults in fresh environments where only a different code is seeded.
121
+ // 3. Any CyberiaClientHints document, when the requested code has none but
122
+ // another instance does. Beats falling straight through to defaults.
138
123
  if (HintsModel) {
139
124
  const anyHint = await HintsModel.findOne({}).lean().catch(() => null);
140
125
  if (anyHint) {
141
126
  const merged = buildClientHints(anyHint);
142
- // Cache under the requested code so subsequent requests are fast,
143
- // but with a shorter TTL (5 s) so a proper seed wins quickly.
127
+ // Short TTL under the requested code so a later seed wins quickly.
144
128
  if (code) cache.set(code, { data: merged, expiresAt: now() + 5_000 });
145
129
  return { data: merged, source: 'presentation-hints-fallback' };
146
130
  }
147
131
  }
148
132
 
149
- // 4. Canonical defaults. Not cached we do not poison the cache with
150
- // a default that could mask a later DB insert.
133
+ // 4. Canonical defaults. Never cached, so a later DB insert wins.
151
134
  return { data: CYBERIA_CLIENT_HINTS_DEFAULTS, source: 'defaults' };
152
135
  }
@@ -1,4 +1,4 @@
1
- import { buildCrudController, serviceHandler } from '../../server/middlewares.js';
1
+ import { buildCrudController, serviceHandler } from '../../server/network/middlewares.js';
2
2
  import { CyberiaDialogueService } from './cyberia-dialogue.service.js';
3
3
 
4
4
  const CyberiaDialogueController = buildCrudController(CyberiaDialogueService, {
@@ -8,7 +8,7 @@ import { Schema, model, Types } from 'mongoose';
8
8
  *
9
9
  * Schema fields:
10
10
  * code – primary grouping key, e.g. "default-lain" or "wason-intro".
11
- * The C client fetches all lines for a given code in one request.
11
+ * The client fetches every line of one code in a single request.
12
12
  * order – zero-based display sequence within the code group.
13
13
  * speaker – display name shown above the dialogue line.
14
14
  * text – the dialogue line itself.
@@ -1,5 +1,5 @@
1
1
  import express from 'express';
2
- import { registerCrudRoutes } from '../../server/middlewares.js';
2
+ import { registerCrudRoutes } from '../../server/network/middlewares.js';
3
3
  import { CyberiaDialogueController } from './cyberia-dialogue.controller.js';
4
4
 
5
5
  class CyberiaDialogueRouter {
@@ -9,7 +9,7 @@ class CyberiaDialogueRouter {
9
9
  */
10
10
  static router(options) {
11
11
  const router = express.Router();
12
- // Direct lookup by code — C client fetches dialogue by code (e.g. "default-lain")
12
+ // Direct lookup by code, e.g. "default-lain".
13
13
  router.get(`/code/:code`, async (req, res) => await CyberiaDialogueController.getByCode(req, res, options));
14
14
  return registerCrudRoutes(router, CyberiaDialogueController, options);
15
15
  }
@@ -1,6 +1,6 @@
1
1
  import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
2
- import { loggerFactory } from '../../server/logger.js';
3
- import { DataQuery } from '../../server/data-query.js';
2
+ import { loggerFactory } from '../../server/ops/logger.js';
3
+ import { DataQuery } from '../../server/storage/data-query.js';
4
4
  import { DefaultCyberiaDialogues } from '../cyberia-server-defaults/cyberia-server-defaults.js';
5
5
 
6
6
  const logger = loggerFactory(import.meta);
@@ -1,4 +1,4 @@
1
- import { buildCrudController } from '../../server/middlewares.js';
1
+ import { buildCrudController } from '../../server/network/middlewares.js';
2
2
  import { CyberiaEntityService } from './cyberia-entity.service.js';
3
3
 
4
4
  const CyberiaEntityController = buildCrudController(CyberiaEntityService);
@@ -1,9 +1,11 @@
1
1
  import { Schema, model, Types } from 'mongoose';
2
+ import { ENTITY_LEVEL_MIN, ENTITY_LEVEL_MAX } from '../../client/components/cyberia/SharedDefaultsCyberia.js';
2
3
 
3
4
  // https://mongoosejs.com/docs/2.7.x/docs/schematypes.html
4
5
 
5
6
  const CyberiaEntitySchema = new Schema({
6
7
  entityType: { type: String, default: 'floor' },
8
+ level: { type: Number, min: ENTITY_LEVEL_MIN, max: ENTITY_LEVEL_MAX, validate: Number.isInteger },
7
9
  initCellX: { type: Number, default: 0 },
8
10
  initCellY: { type: Number, default: 0 },
9
11
  dimX: { type: Number, default: 1 },
@@ -1,5 +1,5 @@
1
1
  import express from 'express';
2
- import { registerCrudRoutes } from '../../server/middlewares.js';
2
+ import { registerCrudRoutes } from '../../server/network/middlewares.js';
3
3
  import { CyberiaEntityController } from './cyberia-entity.controller.js';
4
4
 
5
5
  class CyberiaEntityRouter {
@@ -1,6 +1,6 @@
1
1
  import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
2
- import { loggerFactory } from '../../server/logger.js';
3
- import { DataQuery } from '../../server/data-query.js';
2
+ import { loggerFactory } from '../../server/ops/logger.js';
3
+ import { DataQuery } from '../../server/storage/data-query.js';
4
4
 
5
5
  const logger = loggerFactory(import.meta);
6
6
 
@@ -29,7 +29,7 @@ class CyberiaEntityService {
29
29
  static put = async (req, res, options) => {
30
30
  /** @type {import('./cyberia-entity.model.js').CyberiaEntityModel} */
31
31
  const CyberiaEntity = DataBaseProviderService.getModel("CyberiaEntity", options);
32
- return await CyberiaEntity.findByIdAndUpdate(req.params.id, req.body);
32
+ return await CyberiaEntity.findByIdAndUpdate(req.params.id, req.body, { runValidators: true });
33
33
  };
34
34
  static delete = async (req, res, options) => {
35
35
  /** @type {import('./cyberia-entity.model.js').CyberiaEntityModel} */