cyberia 3.1.3 → 3.2.9

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 (377) hide show
  1. package/.env.example +0 -2
  2. package/.github/workflows/engine-cyberia.cd.yml +10 -8
  3. package/.github/workflows/engine-cyberia.ci.yml +12 -29
  4. package/.github/workflows/ghpkg.ci.yml +4 -4
  5. package/.github/workflows/npmpkg.ci.yml +28 -11
  6. package/.github/workflows/publish.ci.yml +21 -2
  7. package/.github/workflows/pwa-microservices-template-page.cd.yml +4 -5
  8. package/.github/workflows/pwa-microservices-template-test.ci.yml +3 -3
  9. package/.github/workflows/release.cd.yml +14 -10
  10. package/CHANGELOG.md +783 -1
  11. package/CLI-HELP.md +95 -18
  12. package/Dockerfile +0 -2
  13. package/README.md +290 -220
  14. package/bin/build.js +24 -7
  15. package/bin/cyberia.js +2838 -252
  16. package/bin/deploy.js +747 -125
  17. package/bin/file.js +9 -0
  18. package/bin/index.js +2838 -252
  19. package/bin/vs.js +1 -1
  20. package/conf.js +99 -65
  21. package/deployment.yaml +18 -164
  22. package/hardhat/hardhat.config.js +13 -13
  23. package/hardhat/ignition/modules/ObjectLayerToken.js +1 -1
  24. package/hardhat/package-lock.json +2559 -5864
  25. package/hardhat/package.json +14 -23
  26. package/hardhat/scripts/deployObjectLayerToken.js +1 -1
  27. package/hardhat/test/ObjectLayerToken.js +4 -2
  28. package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
  29. package/hardhat/types/ethers-contracts/common.ts +92 -0
  30. package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
  31. package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
  32. package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
  33. package/hardhat/types/ethers-contracts/index.ts +6 -0
  34. package/jsconfig.json +1 -1
  35. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +6 -5
  36. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +6 -5
  37. package/manifests/deployment/dd-cyberia-development/deployment.yaml +18 -164
  38. package/manifests/deployment/dd-cyberia-development/proxy.yaml +7 -79
  39. package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
  40. package/manifests/deployment/dd-test-development/deployment.yaml +112 -28
  41. package/manifests/deployment/dd-test-development/proxy.yaml +46 -1
  42. package/manifests/deployment/playwright/deployment.yaml +1 -1
  43. package/nodemon.json +1 -1
  44. package/package.json +39 -24
  45. package/proxy.yaml +7 -79
  46. package/scripts/k3s-node-setup.sh +2 -2
  47. package/scripts/nat-iptables.sh +103 -18
  48. package/scripts/rhel-grpc-setup.sh +56 -0
  49. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +58 -14
  50. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +23 -14
  51. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
  52. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +148 -20
  53. package/src/api/core/core.controller.js +10 -10
  54. package/src/api/core/core.service.js +10 -10
  55. package/src/api/crypto/crypto.controller.js +8 -8
  56. package/src/api/crypto/crypto.service.js +8 -8
  57. package/src/api/cyberia-action/cyberia-action.controller.js +74 -0
  58. package/src/api/cyberia-action/cyberia-action.model.js +87 -0
  59. package/src/api/cyberia-action/cyberia-action.router.js +27 -0
  60. package/src/api/cyberia-action/cyberia-action.service.js +42 -0
  61. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +93 -0
  62. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
  63. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +29 -0
  64. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +51 -0
  65. package/src/api/cyberia-entity/cyberia-entity.controller.js +74 -0
  66. package/src/api/cyberia-entity/cyberia-entity.model.js +24 -0
  67. package/src/api/cyberia-entity/cyberia-entity.router.js +27 -0
  68. package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
  69. package/src/api/cyberia-instance/cyberia-fallback-world.js +178 -0
  70. package/src/api/cyberia-instance/cyberia-instance.controller.js +92 -0
  71. package/src/api/cyberia-instance/cyberia-instance.model.js +87 -0
  72. package/src/api/cyberia-instance/cyberia-instance.router.js +63 -0
  73. package/src/api/cyberia-instance/cyberia-instance.service.js +156 -0
  74. package/src/api/cyberia-instance/cyberia-portal-connector.js +260 -0
  75. package/src/api/cyberia-instance/cyberia-world-generator.js +505 -0
  76. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +74 -0
  77. package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +574 -0
  78. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +231 -0
  79. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +27 -0
  80. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +46 -0
  81. package/src/api/cyberia-map/cyberia-map.controller.js +79 -0
  82. package/src/api/cyberia-map/cyberia-map.model.js +30 -0
  83. package/src/api/cyberia-map/cyberia-map.router.js +40 -0
  84. package/src/api/cyberia-map/cyberia-map.service.js +74 -0
  85. package/src/api/cyberia-quest/cyberia-quest.controller.js +74 -0
  86. package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
  87. package/src/api/cyberia-quest/cyberia-quest.router.js +27 -0
  88. package/src/api/cyberia-quest/cyberia-quest.service.js +42 -0
  89. package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +74 -0
  90. package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
  91. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +27 -0
  92. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
  93. package/src/api/default/default.controller.js +10 -10
  94. package/src/api/default/default.service.js +10 -10
  95. package/src/api/document/document.controller.js +12 -12
  96. package/src/api/document/document.model.js +10 -16
  97. package/src/api/file/file.controller.js +8 -8
  98. package/src/api/file/file.model.js +10 -10
  99. package/src/api/file/file.ref.json +18 -0
  100. package/src/api/file/file.service.js +36 -36
  101. package/src/api/instance/instance.controller.js +10 -10
  102. package/src/api/instance/instance.model.js +4 -10
  103. package/src/api/instance/instance.service.js +10 -10
  104. package/src/api/ipfs/ipfs.controller.js +15 -36
  105. package/src/api/ipfs/ipfs.model.js +47 -47
  106. package/src/api/ipfs/ipfs.router.js +8 -13
  107. package/src/api/ipfs/ipfs.service.js +67 -129
  108. package/src/api/object-layer/object-layer.controller.js +12 -12
  109. package/src/api/object-layer/object-layer.model.js +4 -17
  110. package/src/api/object-layer/object-layer.router.js +30 -0
  111. package/src/api/object-layer/object-layer.service.js +126 -43
  112. package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +10 -10
  113. package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +6 -16
  114. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +18 -14
  115. package/src/api/test/test.controller.js +8 -8
  116. package/src/api/test/test.service.js +8 -8
  117. package/src/api/user/guest.service.js +99 -0
  118. package/src/api/user/user.controller.js +6 -6
  119. package/src/api/user/user.model.js +8 -13
  120. package/src/api/user/user.service.js +11 -27
  121. package/src/cli/cluster.js +68 -21
  122. package/src/cli/db.js +753 -825
  123. package/src/cli/deploy.js +215 -125
  124. package/src/cli/env.js +29 -0
  125. package/src/cli/fs.js +82 -8
  126. package/src/cli/image.js +43 -1
  127. package/src/cli/index.js +74 -3
  128. package/src/cli/kubectl.js +211 -0
  129. package/src/cli/release.js +340 -0
  130. package/src/cli/repository.js +475 -74
  131. package/src/cli/run.js +582 -43
  132. package/src/cli/secrets.js +73 -0
  133. package/src/cli/ssh.js +1 -1
  134. package/src/cli/static.js +43 -115
  135. package/src/cli/test.js +3 -3
  136. package/src/client/Cryptokoyn.index.js +18 -22
  137. package/src/client/CyberiaPortal.index.js +19 -24
  138. package/src/client/Default.index.js +21 -34
  139. package/src/client/Itemledger.index.js +20 -27
  140. package/src/client/Underpost.index.js +19 -24
  141. package/src/client/components/core/404.js +4 -4
  142. package/src/client/components/core/500.js +4 -4
  143. package/src/client/components/core/Account.js +73 -60
  144. package/src/client/components/core/AgGrid.js +23 -33
  145. package/src/client/components/core/Alert.js +12 -13
  146. package/src/client/components/core/AppStore.js +69 -0
  147. package/src/client/components/core/Auth.js +35 -37
  148. package/src/client/components/core/Badge.js +7 -13
  149. package/src/client/components/core/BtnIcon.js +15 -17
  150. package/src/client/components/core/CalendarCore.js +43 -64
  151. package/src/client/components/core/Chat.js +13 -15
  152. package/src/client/components/core/ClientEvents.js +87 -0
  153. package/src/client/components/core/ColorPaletteElement.js +309 -0
  154. package/src/client/components/core/Content.js +17 -14
  155. package/src/client/components/core/Css.js +15 -71
  156. package/src/client/components/core/CssCore.js +12 -16
  157. package/src/client/components/core/D3Chart.js +4 -4
  158. package/src/client/components/core/Docs.js +64 -91
  159. package/src/client/components/core/DropDown.js +194 -96
  160. package/src/client/components/core/EventBus.js +92 -0
  161. package/src/client/components/core/EventsUI.js +14 -17
  162. package/src/client/components/core/FileExplorer.js +96 -228
  163. package/src/client/components/core/FullScreen.js +47 -75
  164. package/src/client/components/core/Input.js +24 -69
  165. package/src/client/components/core/Keyboard.js +26 -19
  166. package/src/client/components/core/KeyboardAvoidance.js +145 -0
  167. package/src/client/components/core/LoadingAnimation.js +25 -31
  168. package/src/client/components/core/LogIn.js +43 -43
  169. package/src/client/components/core/LogOut.js +25 -16
  170. package/src/client/components/core/Modal.js +462 -179
  171. package/src/client/components/core/NotificationManager.js +14 -18
  172. package/src/client/components/core/Panel.js +54 -51
  173. package/src/client/components/core/PanelForm.js +44 -144
  174. package/src/client/components/core/Polyhedron.js +110 -214
  175. package/src/client/components/core/PublicProfile.js +39 -32
  176. package/src/client/components/core/Recover.js +48 -44
  177. package/src/client/components/core/Responsive.js +88 -32
  178. package/src/client/components/core/RichText.js +9 -18
  179. package/src/client/components/core/Router.js +24 -3
  180. package/src/client/components/core/SearchBox.js +37 -37
  181. package/src/client/components/core/SignUp.js +39 -30
  182. package/src/client/components/core/SocketIo.js +112 -30
  183. package/src/client/components/core/SocketIoHandler.js +75 -0
  184. package/src/client/components/core/Stream.js +143 -95
  185. package/src/client/components/core/ToggleSwitch.js +8 -20
  186. package/src/client/components/core/ToolTip.js +5 -17
  187. package/src/client/components/core/Translate.js +56 -59
  188. package/src/client/components/core/Validator.js +26 -16
  189. package/src/client/components/core/Wallet.js +15 -26
  190. package/src/client/components/core/Webhook.js +40 -7
  191. package/src/client/components/core/Worker.js +163 -27
  192. package/src/client/components/core/windowGetDimensions.js +7 -7
  193. package/src/client/components/cryptokoyn/{MenuCryptokoyn.js → AppShellCryptokoyn.js} +59 -59
  194. package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
  195. package/src/client/components/cryptokoyn/CssCryptokoyn.js +15 -15
  196. package/src/client/components/cryptokoyn/LogInCryptokoyn.js +9 -7
  197. package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +8 -6
  198. package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
  199. package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +4 -4
  200. package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +6 -4
  201. package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +3 -51
  202. package/src/client/components/cyberia/InstanceEngineCyberia.js +781 -0
  203. package/src/client/components/cyberia/MapEngineCyberia.js +1836 -2
  204. package/src/client/components/cyberia/ObjectLayerEngine.js +19 -0
  205. package/src/client/components/cyberia/ObjectLayerEngineModal.js +1220 -99
  206. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +252 -316
  207. package/src/client/components/cyberia-portal/{MenuCyberiaPortal.js → AppShellCyberiaPortal.js} +136 -103
  208. package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
  209. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +462 -32
  210. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +15 -15
  211. package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +9 -7
  212. package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +8 -6
  213. package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +4 -4
  214. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +60 -0
  215. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +4 -4
  216. package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +6 -4
  217. package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +3 -49
  218. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +8 -4
  219. package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +91 -91
  220. package/src/client/components/default/AppStoreDefault.js +5 -0
  221. package/src/client/components/default/CssDefault.js +12 -12
  222. package/src/client/components/default/LogInDefault.js +9 -7
  223. package/src/client/components/default/LogOutDefault.js +8 -6
  224. package/src/client/components/default/RouterDefault.js +47 -0
  225. package/src/client/components/default/SettingsDefault.js +4 -4
  226. package/src/client/components/default/SignUpDefault.js +6 -4
  227. package/src/client/components/default/SocketIoDefault.js +3 -51
  228. package/src/client/components/default/TranslateDefault.js +3 -3
  229. package/src/client/components/itemledger/{MenuItemledger.js → AppShellItemledger.js} +59 -59
  230. package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
  231. package/src/client/components/itemledger/CssItemledger.js +15 -15
  232. package/src/client/components/itemledger/LogInItemledger.js +9 -7
  233. package/src/client/components/itemledger/LogOutItemledger.js +8 -6
  234. package/src/client/components/itemledger/RouterItemledger.js +38 -0
  235. package/src/client/components/itemledger/SettingsItemledger.js +4 -4
  236. package/src/client/components/itemledger/SignUpItemledger.js +6 -4
  237. package/src/client/components/itemledger/SocketIoItemledger.js +3 -51
  238. package/src/client/components/itemledger/TranslateItemledger.js +3 -3
  239. package/src/client/components/underpost/{MenuUnderpost.js → AppShellUnderpost.js} +92 -92
  240. package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
  241. package/src/client/components/underpost/CssUnderpost.js +14 -14
  242. package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +4 -4
  243. package/src/client/components/underpost/DocumentSearchProvider.js +1 -1
  244. package/src/client/components/underpost/LabGalleryUnderpost.js +12 -15
  245. package/src/client/components/underpost/LogInUnderpost.js +9 -7
  246. package/src/client/components/underpost/LogOutUnderpost.js +8 -6
  247. package/src/client/components/underpost/RouterUnderpost.js +45 -0
  248. package/src/client/components/underpost/SettingsUnderpost.js +4 -4
  249. package/src/client/components/underpost/SignUpUnderpost.js +6 -4
  250. package/src/client/components/underpost/SocketIoUnderpost.js +3 -51
  251. package/src/client/components/underpost/TranslateUnderpost.js +4 -4
  252. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +235 -0
  253. package/src/client/public/cyberia-docs/ARCHITECTURE.md +443 -0
  254. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +417 -0
  255. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +313 -0
  256. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +260 -0
  257. package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +241 -0
  258. package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
  259. package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +279 -0
  260. package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +206 -0
  261. package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
  262. package/src/client/public/cyberia-docs/WHITE-PAPER.md +732 -0
  263. package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +14 -20
  264. package/src/client/services/core/core.service.js +35 -55
  265. package/src/client/services/crypto/crypto.service.js +8 -13
  266. package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
  267. package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +99 -0
  268. package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
  269. package/src/client/services/cyberia-entity/cyberia-entity.service.js +99 -0
  270. package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
  271. package/src/client/services/cyberia-instance/cyberia-instance.service.js +116 -0
  272. package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +99 -0
  273. package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
  274. package/src/client/services/cyberia-map/cyberia-map.service.js +120 -0
  275. package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
  276. package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
  277. package/src/client/services/default/default.management.js +159 -267
  278. package/src/client/services/default/default.service.js +10 -16
  279. package/src/client/services/document/document.service.js +14 -19
  280. package/src/client/services/file/file.service.js +8 -13
  281. package/src/client/services/instance/instance.management.js +6 -6
  282. package/src/client/services/instance/instance.service.js +10 -15
  283. package/src/client/services/ipfs/ipfs.service.js +14 -40
  284. package/src/client/services/object-layer/object-layer.management.js +14 -14
  285. package/src/client/services/object-layer/object-layer.service.js +39 -24
  286. package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +10 -16
  287. package/src/client/services/test/test.service.js +8 -13
  288. package/src/client/services/user/guest.service.js +86 -0
  289. package/src/client/services/user/user.management.js +6 -6
  290. package/src/client/services/user/user.service.js +14 -20
  291. package/src/client/ssr/body/404.js +3 -3
  292. package/src/client/ssr/body/500.js +3 -3
  293. package/src/client/ssr/body/CacheControl.js +5 -2
  294. package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
  295. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +13 -6
  296. package/src/client/ssr/head/PwaItemledger.js +197 -60
  297. package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
  298. package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
  299. package/src/client/ssr/offline/Maintenance.js +12 -11
  300. package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
  301. package/src/client/ssr/pages/CyberiaServerMetrics.js +1 -1
  302. package/src/client/ssr/pages/Test.js +2 -2
  303. package/src/client/sw/core.sw.js +212 -0
  304. package/src/grpc/cyberia/grpc-server.js +642 -0
  305. package/src/index.js +24 -1
  306. package/src/runtime/cyberia-client/Dockerfile +80 -0
  307. package/src/runtime/cyberia-server/Dockerfile +37 -0
  308. package/src/runtime/express/Dockerfile +5 -1
  309. package/src/runtime/express/Express.js +18 -1
  310. package/src/runtime/lampp/Dockerfile +17 -5
  311. package/src/runtime/lampp/Lampp.js +27 -4
  312. package/src/runtime/wp/Dockerfile +62 -0
  313. package/src/runtime/wp/Wp.js +639 -0
  314. package/src/server/atlas-sprite-sheet-generator.js +4 -2
  315. package/src/server/auth.js +24 -1
  316. package/src/server/backup.js +37 -9
  317. package/src/server/client-build-docs.js +52 -46
  318. package/src/server/client-build.js +356 -82
  319. package/src/server/client-formatted.js +140 -57
  320. package/src/server/conf.js +29 -13
  321. package/src/server/cron.js +25 -23
  322. package/src/server/data-query.js +32 -20
  323. package/src/server/dns.js +24 -1
  324. package/src/server/ipfs-client.js +253 -89
  325. package/src/server/object-layer.js +150 -114
  326. package/src/server/peer.js +8 -0
  327. package/src/server/process.js +13 -27
  328. package/src/server/runtime.js +25 -1
  329. package/src/server/semantic-layer-generator-floor.js +319 -0
  330. package/src/server/semantic-layer-generator-resource.js +259 -0
  331. package/src/server/semantic-layer-generator-skin.js +1164 -0
  332. package/src/server/semantic-layer-generator.js +211 -542
  333. package/src/server/shape-generator.js +108 -0
  334. package/src/server/start.js +19 -5
  335. package/src/server/valkey.js +141 -235
  336. package/src/ws/IoInterface.js +1 -10
  337. package/src/ws/IoServer.js +14 -33
  338. package/src/ws/core/channels/core.ws.chat.js +65 -20
  339. package/src/ws/core/channels/core.ws.mailer.js +113 -32
  340. package/src/ws/core/channels/core.ws.stream.js +90 -31
  341. package/src/ws/core/core.ws.connection.js +12 -33
  342. package/src/ws/core/core.ws.emit.js +10 -26
  343. package/src/ws/core/core.ws.server.js +25 -58
  344. package/src/ws/default/channels/default.ws.main.js +53 -12
  345. package/src/ws/default/default.ws.connection.js +26 -13
  346. package/src/ws/default/default.ws.server.js +30 -12
  347. package/tsconfig.docs.json +15 -0
  348. package/typedoc.dd-cyberia.json +29 -0
  349. package/typedoc.json +29 -0
  350. package/WHITE-PAPER.md +0 -1540
  351. package/hardhat/README.md +0 -531
  352. package/hardhat/WHITE-PAPER.md +0 -1540
  353. package/jsdoc.dd-cyberia.json +0 -59
  354. package/jsdoc.json +0 -59
  355. package/src/api/object-layer/README.md +0 -347
  356. package/src/client/components/core/ColorPalette.js +0 -5267
  357. package/src/client/components/core/JoyStick.js +0 -80
  358. package/src/client/components/cryptokoyn/CommonCryptokoyn.js +0 -29
  359. package/src/client/components/cryptokoyn/ElementsCryptokoyn.js +0 -38
  360. package/src/client/components/cryptokoyn/RoutesCryptokoyn.js +0 -39
  361. package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +0 -38
  362. package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +0 -58
  363. package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +0 -136
  364. package/src/client/components/default/ElementsDefault.js +0 -38
  365. package/src/client/components/default/RoutesDefault.js +0 -49
  366. package/src/client/components/itemledger/CommonItemledger.js +0 -29
  367. package/src/client/components/itemledger/ElementsItemledger.js +0 -38
  368. package/src/client/components/itemledger/RoutesItemledger.js +0 -40
  369. package/src/client/components/underpost/CommonUnderpost.js +0 -29
  370. package/src/client/components/underpost/ElementsUnderpost.js +0 -38
  371. package/src/client/components/underpost/RoutesUnderpost.js +0 -47
  372. package/src/client/sw/default.sw.js +0 -127
  373. package/src/client/sw/template.sw.js +0 -84
  374. package/src/ws/core/management/core.ws.chat.js +0 -8
  375. package/src/ws/core/management/core.ws.mailer.js +0 -16
  376. package/src/ws/core/management/core.ws.stream.js +0 -8
  377. package/src/ws/default/management/default.ws.main.js +0 -8
package/src/cli/deploy.js CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  buildPortProxyRouter,
10
10
  buildProxyRouter,
11
11
  Config,
12
+ cronDeployIdResolve,
12
13
  deployRangePortFactory,
13
14
  getDataDeploy,
14
15
  loadConfServerJson,
@@ -124,30 +125,47 @@ class UnderpostDeploy {
124
125
  * @param {string} namespace - Kubernetes namespace for the deployment.
125
126
  * @param {Array<object>} volumes - Volume configurations for the deployment.
126
127
  * @param {Array<string>} cmd - Command to run in the deployment container.
128
+ * @param {boolean} skipFullBuild - Whether to skip the full client bundle build during deployment.
129
+ * @param {boolean} pullBundle - Whether to pull the pre-built client bundle from Cloudinary before starting. Use together with skipFullBuild to skip the local build entirely.
127
130
  * @returns {string} - YAML deployment configuration for the specified deployment.
128
131
  * @memberof UnderpostDeploy
129
132
  */
130
- deploymentYamlPartsFactory({ deployId, env, suffix, resources, replicas, image, namespace, volumes, cmd }) {
133
+ deploymentYamlPartsFactory({
134
+ deployId,
135
+ env,
136
+ suffix,
137
+ resources,
138
+ replicas,
139
+ image,
140
+ namespace,
141
+ volumes,
142
+ cmd,
143
+ skipFullBuild,
144
+ pullBundle,
145
+ }) {
131
146
  if (!cmd)
132
- cmd = [
133
- `npm install -g npm@11.2.0`,
134
- `npm install -g underpost`,
135
- `underpost secret underpost --create-from-file /etc/config/.env.${env}`,
136
- `underpost start --build --run ${deployId} ${env}`,
137
- ];
147
+ cmd =
148
+ pullBundle || skipFullBuild
149
+ ? [
150
+ // When pullBundle (or skipFullBuild) is set the container pulls the pre-built client
151
+ // bundle from Cloudinary (push-bundle must have been run on the dev machine beforehand).
152
+ `underpost secret underpost --create-from-env`,
153
+ `underpost start --build --run --pull-bundle --skip-full-build ${deployId} ${env}`,
154
+ ]
155
+ : [
156
+ // `npm install -g npm@11.2.0`,
157
+ // `npm install -g underpost`,
158
+ `underpost secret underpost --create-from-env`,
159
+ `underpost start --build --run ${deployId} ${env}`,
160
+ ];
138
161
  const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
139
- if (!volumes)
140
- volumes = [
141
- {
142
- volumeMountPath: '/etc/config',
143
- volumeName: 'config-volume',
144
- configMap: 'underpost-config',
145
- },
146
- ];
162
+ if (!volumes) volumes = [];
147
163
  const confVolume = fs.existsSync(`./engine-private/conf/${deployId}/conf.volume.json`)
148
164
  ? JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.volume.json`, 'utf8'))
149
165
  : [];
150
166
  volumes = volumes.concat(confVolume);
167
+ // const containerImage = image ? image : `localhost/rockylinux9-underpost:v${packageJson.version}`;
168
+ const containerImage = image ? image : `underpost/underpost-engine:v${packageJson.version}`;
151
169
  return `apiVersion: apps/v1
152
170
  kind: Deployment
153
171
  metadata:
@@ -155,6 +173,7 @@ metadata:
155
173
  namespace: ${namespace ? namespace : 'default'}
156
174
  labels:
157
175
  app: ${deployId}-${env}-${suffix}
176
+ deploy-id: ${deployId}-${env}
158
177
  spec:
159
178
  replicas: ${replicas}
160
179
  selector:
@@ -164,10 +183,15 @@ spec:
164
183
  metadata:
165
184
  labels:
166
185
  app: ${deployId}-${env}-${suffix}
186
+ deploy-id: ${deployId}-${env}
167
187
  spec:
168
188
  containers:
169
189
  - name: ${deployId}-${env}-${suffix}
170
- image: ${image ? image : `localhost/rockylinux9-underpost:v${packageJson.version}`}
190
+ image: ${containerImage}
191
+ imagePullPolicy: ${containerImage.startsWith('localhost/') ? 'Never' : 'IfNotPresent'}
192
+ envFrom:
193
+ - secretRef:
194
+ name: underpost-config
171
195
  ${
172
196
  resources
173
197
  ? ` resources:
@@ -183,13 +207,17 @@ ${
183
207
  - /bin/sh
184
208
  - -c
185
209
  - >
186
- ${cmd.join(` && `)}
210
+ ${cmd.join(' &&\n ')}
187
211
 
188
- ${Underpost.deploy
189
- .volumeFactory(volumes.map((v) => ((v.version = `${deployId}-${env}-${suffix}`), v)))
190
- .render.split(`\n`)
191
- .map((l) => ' ' + l)
192
- .join(`\n`)}
212
+ ${
213
+ volumes.length > 0
214
+ ? Underpost.deploy
215
+ .volumeFactory(volumes.map((v) => ((v.version = `${deployId}-${env}-${suffix}`), v)))
216
+ .render.split(`\n`)
217
+ .map((l) => ' ' + l)
218
+ .join(`\n`)
219
+ : ''
220
+ }
193
221
  ---
194
222
  apiVersion: v1
195
223
  kind: Service
@@ -218,6 +246,8 @@ spec:
218
246
  * @param {string} [options.retryPerTryTimeout] - Retry per-try timeout setting for the deployment.
219
247
  * @param {boolean} [options.disableDeploymentProxy] - Whether to disable deployment proxy.
220
248
  * @param {string} [options.traffic] - Traffic status for the deployment.
249
+ * @param {boolean} [options.skipFullBuild] - Whether to skip the full client bundle build; forwarded to deploymentYamlPartsFactory to generate a pull-bundle startup command.
250
+ * @param {boolean} [options.pullBundle] - Whether to pull the pre-built client bundle from Cloudinary; forwarded to deploymentYamlPartsFactory. Use together with skipFullBuild.
221
251
  * @returns {Promise<void>} - Promise that resolves when the manifest is built.
222
252
  * @memberof UnderpostDeploy
223
253
  */
@@ -254,12 +284,22 @@ ${Underpost.deploy
254
284
  image,
255
285
  namespace: options.namespace,
256
286
  cmd: options.cmd ? options.cmd.split(',').map((c) => c.trim()) : undefined,
287
+ skipFullBuild: options.skipFullBuild,
288
+ pullBundle: options.pullBundle,
257
289
  })
258
290
  .replace('{{ports}}', buildKindPorts(fromPort, toPort))}
259
291
  `;
260
292
  }
261
293
  fs.writeFileSync(`./engine-private/conf/${deployId}/build/${env}/deployment.yaml`, deploymentYamlParts, 'utf8');
262
294
 
295
+ Underpost.deploy.buildGrpcServiceManifest({
296
+ deployId,
297
+ env,
298
+ confServer,
299
+ namespace: options.namespace,
300
+ traffic: options.traffic && typeof options.traffic === 'string' ? options.traffic.split(',') : ['blue'],
301
+ });
302
+
263
303
  const confVolume = fs.existsSync(`./engine-private/conf/${deployId}/conf.volume.json`)
264
304
  ? JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.volume.json`, 'utf8'))
265
305
  : [];
@@ -369,6 +409,67 @@ ${Underpost.deploy
369
409
  }
370
410
  }
371
411
  },
412
+ /**
413
+ * Builds and writes a gRPC ClusterIP service YAML for a deployment.
414
+ * Scans conf.server.json for gRPC ports and emits grpc-service.yaml under
415
+ * `engine-private/conf/<deployId>/build/<env>/`. The selector always uses the
416
+ * explicit `app: <deployId>-<env>-<traffic>` label to target only the active
417
+ * colour (blue or green).
418
+ * @param {string} deployId - Deployment ID.
419
+ * @param {string} env - Environment ('development' or 'production').
420
+ * @param {object} confServer - Parsed conf.server.json content.
421
+ * @param {string} [namespace='default'] - Kubernetes namespace.
422
+ * @param {string[]} [traffic=['blue']] - Active traffic colour(s) ('blue', 'green', or both).
423
+ * @param {string|null} [host=null] - Specific host to scan for gRPC ports. If null, all hosts are scanned.
424
+ * @returns {string|null} - Path to the written YAML file, or null if no gRPC ports found.
425
+ * @memberof UnderpostDeploy
426
+ */
427
+ buildGrpcServiceManifest({ deployId, env, confServer, namespace = 'default', traffic = ['blue'], host = null }) {
428
+ const grpcPorts = new Set();
429
+ const hostsToScan = host ? [host] : Object.keys(confServer);
430
+ for (const h of hostsToScan) {
431
+ if (!confServer[h]) continue;
432
+ for (const path of Object.keys(confServer[h])) {
433
+ const grpc = confServer[h][path].grpc;
434
+ if (grpc && grpc.port) grpcPorts.add(parseInt(grpc.port));
435
+ }
436
+ }
437
+ if (grpcPorts.size === 0) return null;
438
+ const grpcPortsList = [...grpcPorts]
439
+ .map(
440
+ (port) => ` - name: grpc-${port}
441
+ protocol: TCP
442
+ port: ${port}
443
+ targetPort: ${port}`,
444
+ )
445
+ .join('\n');
446
+ let grpcServiceYaml = '';
447
+ for (const color of traffic) {
448
+ const grpcServiceName = `${deployId}-grpc-service-${env}-${color}`;
449
+ const selectorYaml = `app: ${deployId}-${env}-${color}`;
450
+ grpcServiceYaml += `---
451
+ apiVersion: v1
452
+ kind: Service
453
+ metadata:
454
+ name: ${grpcServiceName}
455
+ namespace: ${namespace}
456
+ labels:
457
+ app: ${grpcServiceName}
458
+ spec:
459
+ type: ClusterIP
460
+ selector:
461
+ ${selectorYaml}
462
+ ports:
463
+ ${grpcPortsList}
464
+ `;
465
+ logger.info(
466
+ `gRPC ClusterIP service YAML written: ${grpcServiceName} (selector: ${selectorYaml}, ports: ${[...grpcPorts].join(', ')})`,
467
+ );
468
+ }
469
+ const yamlPath = `./engine-private/conf/${deployId}/build/${env}/grpc-service.yaml`;
470
+ fs.writeFileSync(yamlPath, grpcServiceYaml, 'utf8');
471
+ return yamlPath;
472
+ },
372
473
  /**
373
474
  * Builds a Certificate resource for a host using cert-manager.
374
475
  * @param {string} host - Hostname for which the certificate is being built.
@@ -478,6 +579,13 @@ spec:
478
579
  * @param {string} [options.kindType] - Type of Kubernetes resource to retrieve information for.
479
580
  * @param {number} [options.port] - Port number for exposing the deployment.
480
581
  * @param {string} [options.cmd] - Custom initialization command for deploymentYamlPartsFactory (comma-separated commands).
582
+ * @param {number} [options.exposePort] - Local:remote port override when --expose is active (overrides auto-detected service port).
583
+ * @param {boolean} [options.k3s] - Whether to use k3s cluster context.
584
+ * @param {boolean} [options.kubeadm] - Whether to use kubeadm cluster context.
585
+ * @param {boolean} [options.kind] - Whether to use kind cluster context.
586
+ * @param {boolean} [options.gitClean] - Whether to run git clean on volume mount paths before copying.
587
+ * @param {boolean} [options.skipFullBuild] - Whether to skip the full client bundle build; passed through to buildManifest/deploymentYamlPartsFactory.
588
+ * @param {boolean} [options.pullBundle] - Whether to pull the pre-built client bundle from Cloudinary; passed through to buildManifest/deploymentYamlPartsFactory. Use together with skipFullBuild.
481
589
  * @returns {Promise<void>} - Promise that resolves when the deployment process is complete.
482
590
  * @memberof UnderpostDeploy
483
591
  */
@@ -515,6 +623,10 @@ spec:
515
623
  port: 0,
516
624
  exposePort: 0,
517
625
  cmd: '',
626
+ k3s: false,
627
+ kubeadm: false,
628
+ kind: false,
629
+ gitClean: false,
518
630
  },
519
631
  ) {
520
632
  const namespace = options.namespace ? options.namespace : 'default';
@@ -544,6 +656,8 @@ EOF`);
544
656
  path: instance.path,
545
657
  fromPort: instance.fromPort,
546
658
  toPort: instance.toPort,
659
+ fromDebugPort: instance.fromDebugPort,
660
+ toDebugPort: instance.toDebugPort,
547
661
  traffic: Underpost.deploy.getCurrentTraffic(_deployId, { namespace, hostTest: instance.host }),
548
662
  });
549
663
  }
@@ -553,7 +667,7 @@ EOF`);
553
667
  env,
554
668
  traffic: Underpost.deploy.getCurrentTraffic(deployId, { namespace }),
555
669
  router: await Underpost.deploy.routerFactory(deployId, env),
556
- pods: await Underpost.deploy.get(deployId),
670
+ pods: await Underpost.kubectl.get(deployId),
557
671
  instances,
558
672
  });
559
673
  }
@@ -595,7 +709,7 @@ EOF`);
595
709
  if (!deployId) continue;
596
710
  if (options.expose === true) {
597
711
  const kindType = options.kindType ? options.kindType : 'svc';
598
- const svc = Underpost.deploy.get(deployId, kindType)[0];
712
+ const svc = Underpost.kubectl.get(deployId, kindType)[0];
599
713
  const port = options.exposePort
600
714
  ? parseInt(options.exposePort)
601
715
  : options.port
@@ -634,6 +748,8 @@ EOF`);
634
748
  version,
635
749
  namespace,
636
750
  nodeName: options.node ? options.node : env === 'development' ? 'kind-worker' : os.hostname(),
751
+ clusterContext: options.k3s ? 'k3s' : options.kubeadm ? 'kubeadm' : 'kind',
752
+ gitClean: options.gitClean || false,
637
753
  });
638
754
  }
639
755
 
@@ -652,8 +768,11 @@ EOF`);
652
768
  : `manifests/deployment/${deployId}-${env}`;
653
769
 
654
770
  if (!options.remove) {
655
- if (!options.disableUpdateDeployment)
771
+ if (!options.disableUpdateDeployment) {
656
772
  shellExec(`sudo kubectl apply -f ./${manifestsPath}/deployment.yaml -n ${namespace}`);
773
+ const grpcServicePath = `./${manifestsPath}/grpc-service.yaml`;
774
+ if (fs.existsSync(grpcServicePath)) shellExec(`sudo kubectl apply -f ${grpcServicePath} -n ${namespace}`);
775
+ }
657
776
  if (!options.disableUpdateProxy)
658
777
  shellExec(`sudo kubectl apply -f ./${manifestsPath}/proxy.yaml -n ${namespace}`);
659
778
 
@@ -671,65 +790,6 @@ EOF`);
671
790
  ` + renderHosts,
672
791
  );
673
792
  },
674
- /**
675
- * Retrieves information about a deployment.
676
- * @param {string} deployId - Deployment ID for which information is being retrieved.
677
- * @param {string} kindType - Type of Kubernetes resource to retrieve information for (e.g. 'pods').
678
- * @param {string} namespace - Kubernetes namespace to retrieve information from.
679
- * @returns {Array<object>} - Array of objects containing information about the deployment.
680
- * @memberof UnderpostDeploy
681
- */
682
- get(deployId, kindType = 'pods', namespace = '') {
683
- const raw = shellExec(
684
- `sudo kubectl get ${kindType}${namespace ? ` -n ${namespace}` : ` --all-namespaces`} -o wide`,
685
- {
686
- stdout: true,
687
- disableLog: true,
688
- silent: true,
689
- },
690
- );
691
-
692
- const heads = raw
693
- .split(`\n`)[0]
694
- .split(' ')
695
- .filter((_r) => _r.trim());
696
-
697
- const pods = raw
698
- .split(`\n`)
699
- .filter((r) => (deployId ? r.match(deployId) : r.trim() && !r.match('NAME')))
700
- .map((r) => r.split(' ').filter((_r) => _r.trim()));
701
-
702
- const result = [];
703
-
704
- for (const row of pods) {
705
- const pod = {};
706
- let index = -1;
707
- for (const head of heads) {
708
- index++;
709
- pod[head] = row[index];
710
- }
711
- result.push(pod);
712
- }
713
-
714
- return result;
715
- },
716
-
717
- /**
718
- * Checks if a container file exists in a pod.
719
- * @param {object} options - Options for the check.
720
- * @param {string} options.podName - Name of the pod to check.
721
- * @param {string} options.path - Path to the container file to check.
722
- * @returns {boolean} - True if the container file exists, false otherwise.
723
- * @memberof UnderpostDeploy
724
- */
725
- existsContainerFile({ podName, path }) {
726
- const result = shellExec(`kubectl exec ${podName} -- test -f ${path} && echo "true" || echo "false"`, {
727
- stdout: true,
728
- disableLog: true,
729
- silent: true,
730
- }).trim();
731
- return result === 'true';
732
- },
733
793
  /**
734
794
  * Checks the status of a deployment.
735
795
  * @param {string} deployId - Deployment ID for which the status is being checked.
@@ -742,7 +802,7 @@ EOF`);
742
802
  */
743
803
  async checkDeploymentReadyStatus(deployId, env, traffic, ignoresNames = [], namespace = 'default') {
744
804
  const cmd = `underpost config get container-status`;
745
- const pods = Underpost.deploy.get(`${deployId}-${env}-${traffic}`, 'pods', namespace);
805
+ const pods = Underpost.kubectl.get(`${deployId}-${env}-${traffic}`, 'pods', namespace);
746
806
  const readyPods = [];
747
807
  const notReadyPods = [];
748
808
  for (const pod of pods) {
@@ -768,15 +828,17 @@ EOF`);
768
828
  };
769
829
  },
770
830
  /**
771
- * Creates a configmap for a deployment.
772
- * @param {string} env - Environment for which the configmap is being created.
773
- * @param {string} [namespace='default'] - Kubernetes namespace for the configmap.
831
+ * Creates a Kubernetes Secret for a deployment (replaces configMap for secret data).
832
+ * Secrets are mounted as tmpfs (never written to node disk) and support RBAC restrictions.
833
+ * @param {string} env - Environment for which the secret is being created.
834
+ * @param {string} [namespace='default'] - Kubernetes namespace for the secret.
774
835
  * @memberof UnderpostDeploy
775
836
  */
776
837
  configMap(env, namespace = 'default') {
777
- shellExec(`kubectl delete configmap underpost-config -n ${namespace} --ignore-not-found`);
838
+ const cronDeployId = cronDeployIdResolve() || 'dd-cron';
839
+ shellExec(`kubectl delete secret underpost-config -n ${namespace} --ignore-not-found`);
778
840
  shellExec(
779
- `kubectl create configmap underpost-config --from-file=/home/dd/engine/engine-private/conf/dd-cron/.env.${env} --dry-run=client -o yaml | kubectl apply -f - -n ${namespace}`,
841
+ `kubectl create secret generic underpost-config --from-env-file=/home/dd/engine/engine-private/conf/${cronDeployId}/.env.${env} --dry-run=client -o yaml | kubectl apply -f - -n ${namespace}`,
780
842
  );
781
843
  },
782
844
  /**
@@ -814,6 +876,9 @@ EOF`);
814
876
 
815
877
  shellExec(`sudo kubectl apply -f ./engine-private/conf/${deployId}/build/${env}/proxy.yaml -n ${namespace}`);
816
878
 
879
+ const grpcServicePath = `./engine-private/conf/${deployId}/build/${env}/grpc-service.yaml`;
880
+ if (fs.existsSync(grpcServicePath)) shellExec(`kubectl apply -f ${grpcServicePath} -n ${namespace}`);
881
+
817
882
  Underpost.env.set(`${deployId}-${env}-traffic`, targetTraffic);
818
883
  },
819
884
 
@@ -829,6 +894,8 @@ EOF`);
829
894
  * @param {string} options.version - Version of the deployment.
830
895
  * @param {string} options.namespace - Kubernetes namespace for the deployment.
831
896
  * @param {string} options.nodeName - Node name for the deployment.
897
+ * @param {string} [options.clusterContext='kind'] - Cluster context type ('kind', 'kubeadm', or 'k3s').
898
+ * @param {boolean} [options.gitClean=false] - Whether to run git clean on volumeMountPath before copying.
832
899
  * @memberof UnderpostDeploy
833
900
  */
834
901
  deployVolume(
@@ -839,6 +906,8 @@ EOF`);
839
906
  version: '',
840
907
  namespace: '',
841
908
  nodeName: '',
909
+ clusterContext: 'kind',
910
+ gitClean: false,
842
911
  },
843
912
  ) {
844
913
  if (!volume.claimName) {
@@ -846,19 +915,26 @@ EOF`);
846
915
  return;
847
916
  }
848
917
  const { deployId, env, version, namespace } = options;
918
+ const clusterContext = options.clusterContext || 'kind';
849
919
  const pvcId = `${volume.claimName}-${deployId}-${env}-${version}`;
850
920
  const pvId = `${volume.claimName.replace('pvc-', 'pv-')}-${deployId}-${env}-${version}`;
851
921
  const rootVolumeHostPath = `/home/dd/engine/volume/${pvId}`;
922
+ if (options.gitClean && volume.volumeMountPath) {
923
+ Underpost.repo.clean({ paths: [volume.volumeMountPath] });
924
+ }
852
925
  if (options.nodeName) {
853
926
  if (!fs.existsSync(rootVolumeHostPath)) fs.mkdirSync(rootVolumeHostPath, { recursive: true });
854
927
  fs.copySync(volume.volumeMountPath, rootVolumeHostPath);
855
- } else {
928
+ } else if (clusterContext === 'kind') {
856
929
  shellExec(`docker exec -i kind-worker bash -c "mkdir -p ${rootVolumeHostPath}"`);
857
930
  // shellExec(`docker cp ${volume.volumeMountPath} kind-worker:${rootVolumeHostPath}`);
858
931
  shellExec(`tar -C ${volume.volumeMountPath} -c . | docker cp - kind-worker:${rootVolumeHostPath}`);
859
932
  shellExec(
860
933
  `docker exec -i kind-worker bash -c "chown -R 1000:1000 ${rootVolumeHostPath}; chmod -R 755 ${rootVolumeHostPath}"`,
861
934
  );
935
+ } else {
936
+ if (!fs.existsSync(rootVolumeHostPath)) fs.mkdirSync(rootVolumeHostPath, { recursive: true });
937
+ fs.copySync(volume.volumeMountPath, rootVolumeHostPath);
862
938
  }
863
939
  shellExec(`kubectl delete pvc ${pvcId} -n ${namespace} --ignore-not-found`);
864
940
  shellExec(`kubectl delete pv ${pvId} --ignore-not-found`);
@@ -881,6 +957,8 @@ EOF
881
957
  * @param {string} volume.volumeType - Type of the volume (e.g. 'Directory').
882
958
  * @param {string|null} volume.claimName - Name of the persistent volume claim (if applicable).
883
959
  * @param {string|null} volume.configMap - Name of the config map (if applicable).
960
+ * @param {string|null} volume.secret - Name of the Kubernetes Secret (if applicable). Mounts as readOnly.
961
+ * @param {boolean} [volume.emptyDir=false] - If true, uses an emptyDir volume (writable tmpfs).
884
962
  * @returns {object} - Object containing the rendered volume mounts and volumes.
885
963
  * @memberof UnderpostDeploy
886
964
  */
@@ -902,7 +980,17 @@ EOF
902
980
  let _volumes = `
903
981
  volumes:`;
904
982
  volumes.map((volumeData) => {
905
- let { volumeName, volumeMountPath, volumeHostPath, volumeType, claimName, configMap, version } = volumeData;
983
+ let {
984
+ volumeName,
985
+ volumeMountPath,
986
+ volumeHostPath,
987
+ volumeType,
988
+ claimName,
989
+ configMap,
990
+ secret,
991
+ emptyDir,
992
+ version,
993
+ } = volumeData;
906
994
  if (version) {
907
995
  volumeName = `${volumeName}-${version}`;
908
996
  claimName = claimName ? `${claimName}-${version}` : null;
@@ -910,18 +998,23 @@ EOF
910
998
  _volumeMounts += `
911
999
  - name: ${volumeName}
912
1000
  mountPath: ${volumeMountPath}
913
- `;
1001
+ ${secret ? ` readOnly: true\n` : ''}`;
914
1002
 
915
1003
  _volumes += `
916
1004
  - name: ${volumeName}
917
1005
  ${
918
- configMap
919
- ? ` configMap:
1006
+ emptyDir
1007
+ ? ` emptyDir: {}`
1008
+ : secret
1009
+ ? ` secret:
1010
+ secretName: ${secret}`
1011
+ : configMap
1012
+ ? ` configMap:
920
1013
  name: ${configMap}`
921
- : claimName
922
- ? ` persistentVolumeClaim:
1014
+ : claimName
1015
+ ? ` persistentVolumeClaim:
923
1016
  claimName: ${claimName}`
924
- : ` hostPath:
1017
+ : ` hostPath:
925
1018
  path: ${volumeHostPath}
926
1019
  type: ${volumeType}
927
1020
  `
@@ -1034,14 +1127,13 @@ ${renderHosts}`,
1034
1127
  * @param {string} targetTraffic - Target traffic status for the deployment.
1035
1128
  * @param {Array<string>} ignorePods - List of pod names to ignore.
1036
1129
  * @param {string} [namespace='default'] - Kubernetes namespace for the deployment.
1037
- * @param {string} [outLogType=''] - Type of log output.
1038
1130
  * @returns {object} - Object containing the ready status of the deployment.
1039
1131
  * @memberof UnderpostDeploy
1040
1132
  */
1041
- async monitorReadyRunner(deployId, env, targetTraffic, ignorePods = [], namespace = 'default', outLogType = '') {
1133
+ async monitorReadyRunner(deployId, env, targetTraffic, ignorePods = [], namespace = 'default') {
1042
1134
  let checkStatusIteration = 0;
1043
1135
  const checkStatusIterationMsDelay = 1000;
1044
- const maxIterations = 500;
1136
+ const maxIterations = 3000;
1045
1137
  const deploymentId = `${deployId}-${env}-${targetTraffic}`;
1046
1138
  const iteratorTag = `[${deploymentId}]`;
1047
1139
  logger.info('Deployment init', { deployId, env, targetTraffic, checkStatusIterationMsDelay, namespace });
@@ -1076,32 +1168,30 @@ ${renderHosts}`,
1076
1168
  }
1077
1169
  }
1078
1170
 
1079
- switch (outLogType) {
1080
- case 'underpost': {
1081
- let indexOf = -1;
1082
- for (const pod of result.notReadyPods) {
1083
- indexOf++;
1084
- const { NAME, out } = pod;
1171
+ {
1172
+ let indexOf = -1;
1173
+ for (const pod of result.notReadyPods) {
1174
+ indexOf++;
1175
+ const { NAME, out } = pod;
1085
1176
 
1086
- if (out.match('not') && out.match('found') && checkStatusIteration <= 20 && out.match(deploymentId))
1087
- lastMsg[NAME] = 'Starting deployment';
1088
- else if (out.match('not') && out.match('found') && checkStatusIteration <= 20 && out.match('underpost'))
1089
- lastMsg[NAME] = 'Installing underpost cli';
1090
- else if (out.match('not') && out.match('found') && checkStatusIteration <= 20 && out.match('task'))
1091
- lastMsg[NAME] = 'Initializing setup task';
1092
- else if (out.match('Empty environment variables')) lastMsg[NAME] = 'Setup environment';
1093
- else if (out.match(`${deployId}-${env}-build-deployment`)) lastMsg[NAME] = 'Building apps/services';
1094
- else if (out.match(`${deployId}-${env}-initializing-deployment`))
1095
- lastMsg[NAME] = 'Initializing apps/services';
1096
- else if (!lastMsg[NAME]) lastMsg[NAME] = `Waiting for status`;
1177
+ if (out.match('not') && out.match('found') && checkStatusIteration <= 20 && out.match(deploymentId))
1178
+ lastMsg[NAME] = 'Starting deployment';
1179
+ // else if (out.match('not') && out.match('found') && checkStatusIteration <= 20 && out.match('underpost'))
1180
+ // lastMsg[NAME] = 'Installing underpost cli';
1181
+ else if (out.match('not') && out.match('found') && checkStatusIteration <= 20 && out.match('task'))
1182
+ lastMsg[NAME] = 'Initializing setup task';
1183
+ else if (out.match('Empty environment variables')) lastMsg[NAME] = 'Setup environment';
1184
+ else if (out.match(`${deployId}-${env}-build-deployment`)) lastMsg[NAME] = 'Building apps/services';
1185
+ else if (out.match(`${deployId}-${env}-initializing-deployment`))
1186
+ lastMsg[NAME] = 'Initializing apps/services';
1187
+ else if (!lastMsg[NAME]) lastMsg[NAME] = `Waiting for status`;
1097
1188
 
1098
- console.log(
1099
- 'Target pod:',
1100
- NAME[NAME.match('green') ? 'bgGreen' : 'bgBlue'].bold.black,
1101
- '| Status:',
1102
- lastMsg[NAME].bold.magenta,
1103
- );
1104
- }
1189
+ console.log(
1190
+ 'Target pod:',
1191
+ NAME[NAME.match('green') ? 'bgGreen' : 'bgBlue'].bold.black,
1192
+ '| Status:',
1193
+ lastMsg[NAME].bold.magenta,
1194
+ );
1105
1195
  }
1106
1196
  }
1107
1197
  await timer(checkStatusIterationMsDelay);
package/src/cli/env.js CHANGED
@@ -12,6 +12,19 @@ import { pbcopy } from '../server/process.js';
12
12
 
13
13
  const logger = loggerFactory(import.meta);
14
14
 
15
+ /**
16
+ * Guards an env file path against stale directory artifacts.
17
+ * Removes the path if it exists as a directory (e.g. `.env/` created by a previous EISDIR bug).
18
+ * @param {string} envPath - The path to the environment file.
19
+ * @memberof UnderpostEnv
20
+ */
21
+ const guardEnvPath = (envPath) => {
22
+ if (fs.existsSync(envPath) && !fs.statSync(envPath).isFile()) {
23
+ logger.warn(`Removing stale directory at env path: ${envPath}`);
24
+ fs.removeSync(envPath);
25
+ }
26
+ };
27
+
15
28
  /**
16
29
  * @class UnderpostRootEnv
17
30
  * @description Manages the environment variables of the underpost root.
@@ -31,6 +44,7 @@ class UnderpostRootEnv {
31
44
  */
32
45
  set(key, value, options = { deployId: '', build: false }) {
33
46
  const _set = (envPath, key, value) => {
47
+ guardEnvPath(envPath);
34
48
  let env = {};
35
49
  if (fs.existsSync(envPath)) env = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
36
50
  env[key] = value;
@@ -48,6 +62,7 @@ class UnderpostRootEnv {
48
62
  return;
49
63
  }
50
64
  const exeRootPath = `${getNpmRootPath()}/underpost`;
65
+ fs.ensureDirSync(exeRootPath);
51
66
  const envPath = `${exeRootPath}/.env`;
52
67
  _set(envPath, key, value);
53
68
  },
@@ -60,6 +75,7 @@ class UnderpostRootEnv {
60
75
  delete(key) {
61
76
  const exeRootPath = `${getNpmRootPath()}/underpost`;
62
77
  const envPath = `${exeRootPath}/.env`;
78
+ guardEnvPath(envPath);
63
79
  let env = {};
64
80
  if (fs.existsSync(envPath)) env = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
65
81
  delete env[key];
@@ -101,6 +117,7 @@ class UnderpostRootEnv {
101
117
  list(key, value, options = {}) {
102
118
  const exeRootPath = `${getNpmRootPath()}/underpost`;
103
119
  const envPath = `${exeRootPath}/.env`;
120
+ guardEnvPath(envPath);
104
121
  if (!fs.existsSync(envPath)) {
105
122
  logger.warn(`Empty environment variables`);
106
123
  return {};
@@ -136,7 +153,19 @@ class UnderpostRootEnv {
136
153
  const envPath = `${exeRootPath}/.env`;
137
154
  fs.removeSync(envPath);
138
155
  },
156
+ /**
157
+ * @method isInsideContainer
158
+ * @description Detects whether the current process is running inside a container.
159
+ * Checks for Kubernetes service injection or Docker's .dockerenv marker.
160
+ * @returns {boolean} True if running inside a container.
161
+ * @memberof UnderpostEnv
162
+ */
163
+ isInsideContainer() {
164
+ return !!process.env.KUBERNETES_SERVICE_HOST || fs.existsSync('/.dockerenv');
165
+ },
139
166
  };
140
167
  }
141
168
 
142
169
  export default UnderpostRootEnv;
170
+
171
+ export { guardEnvPath };