cyberia 3.0.3 → 3.2.5

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 (296) hide show
  1. package/{.env.production → .env.example} +20 -4
  2. package/.github/workflows/engine-cyberia.cd.yml +43 -10
  3. package/.github/workflows/engine-cyberia.ci.yml +48 -26
  4. package/.github/workflows/ghpkg.ci.yml +5 -5
  5. package/.github/workflows/gitlab.ci.yml +1 -1
  6. package/.github/workflows/hardhat.ci.yml +82 -0
  7. package/.github/workflows/npmpkg.ci.yml +60 -14
  8. package/.github/workflows/publish.ci.yml +26 -7
  9. package/.github/workflows/publish.cyberia.ci.yml +5 -5
  10. package/.github/workflows/pwa-microservices-template-page.cd.yml +6 -7
  11. package/.github/workflows/pwa-microservices-template-test.ci.yml +4 -4
  12. package/.github/workflows/release.cd.yml +14 -8
  13. package/.vscode/extensions.json +9 -8
  14. package/.vscode/settings.json +3 -2
  15. package/CHANGELOG.md +643 -1
  16. package/CLI-HELP.md +132 -57
  17. package/Dockerfile +4 -2
  18. package/README.md +347 -22
  19. package/WHITE-PAPER.md +1540 -0
  20. package/bin/build.js +21 -12
  21. package/bin/cyberia.js +2640 -106
  22. package/bin/deploy.js +258 -372
  23. package/bin/file.js +5 -1
  24. package/bin/index.js +2640 -106
  25. package/bin/vs.js +3 -3
  26. package/conf.js +169 -105
  27. package/deployment.yaml +236 -20
  28. package/hardhat/.env.example +31 -0
  29. package/hardhat/README.md +531 -0
  30. package/hardhat/WHITE-PAPER.md +1540 -0
  31. package/hardhat/contracts/ObjectLayerToken.sol +391 -0
  32. package/hardhat/deployments/.gitkeep +0 -0
  33. package/hardhat/deployments/hardhat-ObjectLayerToken.json +11 -0
  34. package/hardhat/hardhat.config.js +136 -0
  35. package/hardhat/ignition/modules/ObjectLayerToken.js +21 -0
  36. package/hardhat/networks/besu-object-layer.network.json +138 -0
  37. package/hardhat/package-lock.json +4323 -0
  38. package/hardhat/package.json +36 -0
  39. package/hardhat/scripts/deployObjectLayerToken.js +98 -0
  40. package/hardhat/test/ObjectLayerToken.js +592 -0
  41. package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
  42. package/hardhat/types/ethers-contracts/common.ts +92 -0
  43. package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
  44. package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
  45. package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
  46. package/hardhat/types/ethers-contracts/index.ts +6 -0
  47. package/jsdoc.dd-cyberia.json +68 -0
  48. package/jsdoc.json +65 -49
  49. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +5 -4
  50. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +5 -4
  51. package/manifests/deployment/dd-cyberia-development/deployment.yaml +562 -0
  52. package/manifests/deployment/dd-cyberia-development/proxy.yaml +297 -0
  53. package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +132 -0
  54. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  55. package/manifests/deployment/dd-test-development/deployment.yaml +88 -74
  56. package/manifests/deployment/dd-test-development/proxy.yaml +13 -4
  57. package/manifests/deployment/playwright/deployment.yaml +1 -1
  58. package/manifests/pv-pvc-dd.yaml +1 -1
  59. package/nodemon.json +1 -1
  60. package/package.json +60 -48
  61. package/proxy.yaml +118 -10
  62. package/pv-pvc.yaml +132 -0
  63. package/scripts/k3s-node-setup.sh +1 -1
  64. package/scripts/ports-ls.sh +2 -0
  65. package/scripts/rhel-grpc-setup.sh +56 -0
  66. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +47 -1
  67. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +17 -2
  68. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
  69. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +80 -7
  70. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +93 -0
  71. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
  72. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +29 -0
  73. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +51 -0
  74. package/src/api/cyberia-entity/cyberia-entity.controller.js +74 -0
  75. package/src/api/cyberia-entity/cyberia-entity.model.js +24 -0
  76. package/src/api/cyberia-entity/cyberia-entity.router.js +27 -0
  77. package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
  78. package/src/api/cyberia-instance/cyberia-fallback-world.js +368 -0
  79. package/src/api/cyberia-instance/cyberia-instance.controller.js +92 -0
  80. package/src/api/cyberia-instance/cyberia-instance.model.js +84 -0
  81. package/src/api/cyberia-instance/cyberia-instance.router.js +63 -0
  82. package/src/api/cyberia-instance/cyberia-instance.service.js +191 -0
  83. package/src/api/cyberia-instance/cyberia-portal-connector.js +486 -0
  84. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +74 -0
  85. package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +413 -0
  86. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +228 -0
  87. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +27 -0
  88. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +42 -0
  89. package/src/api/cyberia-map/cyberia-map.controller.js +79 -0
  90. package/src/api/cyberia-map/cyberia-map.model.js +30 -0
  91. package/src/api/cyberia-map/cyberia-map.router.js +40 -0
  92. package/src/api/cyberia-map/cyberia-map.service.js +74 -0
  93. package/src/api/document/document.service.js +1 -1
  94. package/src/api/file/file.controller.js +3 -1
  95. package/src/api/file/file.ref.json +18 -0
  96. package/src/api/file/file.service.js +28 -5
  97. package/src/api/ipfs/ipfs.controller.js +4 -25
  98. package/src/api/ipfs/ipfs.model.js +43 -34
  99. package/src/api/ipfs/ipfs.router.js +8 -13
  100. package/src/api/ipfs/ipfs.service.js +56 -104
  101. package/src/api/object-layer/README.md +347 -22
  102. package/src/api/object-layer/object-layer.controller.js +6 -2
  103. package/src/api/object-layer/object-layer.model.js +12 -8
  104. package/src/api/object-layer/object-layer.router.js +698 -42
  105. package/src/api/object-layer/object-layer.service.js +119 -37
  106. package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +1 -2
  107. package/src/api/user/user.router.js +10 -5
  108. package/src/api/user/user.service.js +15 -14
  109. package/src/cli/baremetal.js +6 -10
  110. package/src/cli/cloud-init.js +0 -3
  111. package/src/cli/cluster.js +7 -7
  112. package/src/cli/db.js +723 -857
  113. package/src/cli/deploy.js +215 -105
  114. package/src/cli/env.js +34 -5
  115. package/src/cli/fs.js +5 -4
  116. package/src/cli/image.js +0 -3
  117. package/src/cli/index.js +83 -15
  118. package/src/cli/kubectl.js +211 -0
  119. package/src/cli/monitor.js +5 -6
  120. package/src/cli/release.js +284 -0
  121. package/src/cli/repository.js +708 -62
  122. package/src/cli/run.js +371 -151
  123. package/src/cli/secrets.js +73 -2
  124. package/src/cli/ssh.js +1 -1
  125. package/src/cli/test.js +3 -3
  126. package/src/client/Cryptokoyn.index.js +3 -4
  127. package/src/client/CyberiaPortal.index.js +3 -4
  128. package/src/client/Default.index.js +3 -4
  129. package/src/client/Itemledger.index.js +4 -963
  130. package/src/client/Underpost.index.js +3 -4
  131. package/src/client/components/core/AgGrid.js +20 -5
  132. package/src/client/components/core/Alert.js +2 -2
  133. package/src/client/components/core/AppStore.js +69 -0
  134. package/src/client/components/core/CalendarCore.js +2 -2
  135. package/src/client/components/core/Content.js +22 -3
  136. package/src/client/components/core/Docs.js +30 -6
  137. package/src/client/components/core/DropDown.js +137 -17
  138. package/src/client/components/core/FileExplorer.js +71 -4
  139. package/src/client/components/core/Input.js +1 -1
  140. package/src/client/components/core/Keyboard.js +2 -2
  141. package/src/client/components/core/LogIn.js +2 -2
  142. package/src/client/components/core/LogOut.js +2 -2
  143. package/src/client/components/core/Modal.js +20 -7
  144. package/src/client/components/core/Panel.js +0 -1
  145. package/src/client/components/core/PanelForm.js +19 -19
  146. package/src/client/components/core/RichText.js +1 -2
  147. package/src/client/components/core/SocketIo.js +82 -29
  148. package/src/client/components/core/SocketIoHandler.js +75 -0
  149. package/src/client/components/core/Stream.js +143 -95
  150. package/src/client/components/core/Webhook.js +40 -7
  151. package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
  152. package/src/client/components/cryptokoyn/LogInCryptokoyn.js +3 -3
  153. package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +2 -2
  154. package/src/client/components/cryptokoyn/MenuCryptokoyn.js +3 -3
  155. package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +3 -51
  156. package/src/client/components/cyberia/InstanceEngineCyberia.js +700 -0
  157. package/src/client/components/cyberia/MapEngineCyberia.js +1359 -2
  158. package/src/client/components/cyberia/ObjectLayerEngineModal.js +17 -6
  159. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +92 -54
  160. package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
  161. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +217 -30
  162. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +44 -2
  163. package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +3 -4
  164. package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +2 -2
  165. package/src/client/components/cyberia-portal/MenuCyberiaPortal.js +104 -9
  166. package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +5 -0
  167. package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +3 -49
  168. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +4 -0
  169. package/src/client/components/default/AppStoreDefault.js +5 -0
  170. package/src/client/components/default/LogInDefault.js +3 -3
  171. package/src/client/components/default/LogOutDefault.js +2 -2
  172. package/src/client/components/default/MenuDefault.js +5 -5
  173. package/src/client/components/default/SocketIoDefault.js +3 -51
  174. package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
  175. package/src/client/components/itemledger/LogInItemledger.js +3 -3
  176. package/src/client/components/itemledger/LogOutItemledger.js +2 -2
  177. package/src/client/components/itemledger/MenuItemledger.js +3 -3
  178. package/src/client/components/itemledger/SocketIoItemledger.js +3 -51
  179. package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
  180. package/src/client/components/underpost/CssUnderpost.js +59 -0
  181. package/src/client/components/underpost/LogInUnderpost.js +6 -3
  182. package/src/client/components/underpost/LogOutUnderpost.js +4 -2
  183. package/src/client/components/underpost/MenuUnderpost.js +104 -18
  184. package/src/client/components/underpost/RoutesUnderpost.js +2 -0
  185. package/src/client/components/underpost/SocketIoUnderpost.js +3 -51
  186. package/src/client/public/cryptokoyn/assets/logo/base-icon.png +0 -0
  187. package/src/client/public/cryptokoyn/browserconfig.xml +12 -0
  188. package/src/client/public/cryptokoyn/microdata.json +85 -0
  189. package/src/client/public/cryptokoyn/site.webmanifest +57 -0
  190. package/src/client/public/cryptokoyn/sitemap +3 -3
  191. package/src/client/public/default/sitemap +3 -3
  192. package/src/client/public/itemledger/browserconfig.xml +2 -2
  193. package/src/client/public/itemledger/manifest.webmanifest +4 -4
  194. package/src/client/public/itemledger/microdata.json +71 -0
  195. package/src/client/public/itemledger/sitemap +3 -3
  196. package/src/client/public/itemledger/yandex-browser-manifest.json +2 -2
  197. package/src/client/public/test/sitemap +3 -3
  198. package/src/client/services/core/core.service.js +20 -8
  199. package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +105 -0
  200. package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
  201. package/src/client/services/cyberia-entity/cyberia-entity.service.js +105 -0
  202. package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
  203. package/src/client/services/cyberia-instance/cyberia-instance.service.js +122 -0
  204. package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +105 -0
  205. package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
  206. package/src/client/services/cyberia-map/cyberia-map.service.js +126 -0
  207. package/src/client/services/instance/instance.management.js +2 -2
  208. package/src/client/services/ipfs/ipfs.service.js +3 -23
  209. package/src/client/services/object-layer/object-layer.management.js +3 -3
  210. package/src/client/services/object-layer/object-layer.service.js +21 -0
  211. package/src/client/services/user/user.management.js +2 -2
  212. package/src/client/ssr/body/404.js +15 -11
  213. package/src/client/ssr/body/500.js +15 -11
  214. package/src/client/ssr/body/SwaggerDarkMode.js +285 -0
  215. package/src/client/ssr/head/PwaItemledger.js +60 -0
  216. package/src/client/ssr/offline/NoNetworkConnection.js +11 -10
  217. package/src/client/ssr/pages/CyberiaServerMetrics.js +1 -1
  218. package/src/client/ssr/pages/Test.js +11 -10
  219. package/src/client.build.js +0 -3
  220. package/src/client.dev.js +0 -3
  221. package/src/db/DataBaseProvider.js +17 -2
  222. package/src/db/mariadb/MariaDB.js +14 -9
  223. package/src/db/mongo/MongooseDB.js +17 -1
  224. package/src/grpc/cyberia/OFF_CHAIN_ECONOMY.md +305 -0
  225. package/src/grpc/cyberia/README.md +326 -0
  226. package/src/grpc/cyberia/grpc-server.js +530 -0
  227. package/src/index.js +24 -1
  228. package/src/proxy.js +0 -3
  229. package/src/runtime/express/Dockerfile +4 -0
  230. package/src/runtime/express/Express.js +33 -10
  231. package/src/runtime/lampp/Dockerfile +13 -2
  232. package/src/runtime/lampp/Lampp.js +33 -17
  233. package/src/runtime/wp/Dockerfile +68 -0
  234. package/src/runtime/wp/Wp.js +639 -0
  235. package/src/server/auth.js +36 -15
  236. package/src/server/backup.js +39 -12
  237. package/src/server/besu-genesis-generator.js +1630 -0
  238. package/src/server/client-build-docs.js +133 -17
  239. package/src/server/client-build-live.js +9 -18
  240. package/src/server/client-build.js +229 -101
  241. package/src/server/client-dev-server.js +14 -13
  242. package/src/server/client-formatted.js +109 -57
  243. package/src/server/conf.js +391 -164
  244. package/src/server/cron.js +27 -24
  245. package/src/server/dns.js +29 -12
  246. package/src/server/downloader.js +0 -2
  247. package/src/server/ipfs-client.js +24 -1
  248. package/src/server/logger.js +27 -9
  249. package/src/server/object-layer.js +217 -103
  250. package/src/server/peer.js +8 -2
  251. package/src/server/process.js +1 -50
  252. package/src/server/proxy.js +4 -8
  253. package/src/server/runtime.js +30 -9
  254. package/src/server/semantic-layer-generator-floor.js +359 -0
  255. package/src/server/semantic-layer-generator-skin.js +1294 -0
  256. package/src/server/semantic-layer-generator.js +116 -555
  257. package/src/server/ssr.js +0 -3
  258. package/src/server/start.js +19 -12
  259. package/src/server/tls.js +0 -2
  260. package/src/server.js +0 -4
  261. package/src/ws/IoInterface.js +1 -10
  262. package/src/ws/IoServer.js +14 -33
  263. package/src/ws/core/channels/core.ws.chat.js +65 -20
  264. package/src/ws/core/channels/core.ws.mailer.js +113 -32
  265. package/src/ws/core/channels/core.ws.stream.js +90 -31
  266. package/src/ws/core/core.ws.connection.js +12 -33
  267. package/src/ws/core/core.ws.emit.js +10 -26
  268. package/src/ws/core/core.ws.server.js +25 -58
  269. package/src/ws/default/channels/default.ws.main.js +53 -12
  270. package/src/ws/default/default.ws.connection.js +26 -13
  271. package/src/ws/default/default.ws.server.js +30 -12
  272. package/.env.development +0 -43
  273. package/.env.test +0 -43
  274. package/hardhat/contracts/CryptoKoyn.sol +0 -59
  275. package/hardhat/contracts/ItemLedger.sol +0 -73
  276. package/hardhat/contracts/Lock.sol +0 -34
  277. package/hardhat/hardhat.config.cjs +0 -45
  278. package/hardhat/ignition/modules/Lock.js +0 -18
  279. package/hardhat/networks/cryptokoyn-itemledger.network.json +0 -29
  280. package/hardhat/scripts/deployCryptokoyn.cjs +0 -25
  281. package/hardhat/scripts/deployItemledger.cjs +0 -25
  282. package/hardhat/test/Lock.js +0 -126
  283. package/hardhat/white-paper.md +0 -581
  284. package/src/client/components/cryptokoyn/CommonCryptokoyn.js +0 -29
  285. package/src/client/components/cryptokoyn/ElementsCryptokoyn.js +0 -38
  286. package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +0 -38
  287. package/src/client/components/default/ElementsDefault.js +0 -38
  288. package/src/client/components/itemledger/CommonItemledger.js +0 -29
  289. package/src/client/components/itemledger/ElementsItemledger.js +0 -38
  290. package/src/client/components/underpost/CommonUnderpost.js +0 -29
  291. package/src/client/components/underpost/ElementsUnderpost.js +0 -38
  292. package/src/ws/core/management/core.ws.chat.js +0 -8
  293. package/src/ws/core/management/core.ws.mailer.js +0 -16
  294. package/src/ws/core/management/core.ws.stream.js +0 -8
  295. package/src/ws/default/management/default.ws.main.js +0 -8
  296. package/white-paper.md +0 -581
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Provides utilities and engine logic for processing and managing Cyberia Online's object layer assets (skins, floors, weapons, etc.).
3
- * Centralizes shared logic consumed by both the Cyberia CLI and the REST API service layer.
3
+ * Shared logic consumed by both the Cyberia CLI and the REST API service layer.
4
4
  * @module src/server/object-layer.js
5
5
  * @namespace CyberiaObjectLayer
6
6
  */
@@ -82,7 +82,7 @@ const logger = loggerFactory(import.meta);
82
82
 
83
83
  /**
84
84
  * Engine class providing static utilities for Cyberia Online object layer asset processing,
85
- * frame extraction, directory iteration, image building, and centralized document creation logic.
85
+ * frame extraction, directory iteration, image building, and document creation logic.
86
86
  * @class ObjectLayerEngine
87
87
  * @memberof CyberiaObjectLayer
88
88
  */
@@ -374,7 +374,7 @@ export class ObjectLayerEngine {
374
374
  }
375
375
 
376
376
  // ──────────────────────────────────────────────────────────────────────────
377
- // Centralized document lifecycle methods
377
+ // Document lifecycle methods
378
378
  // ──────────────────────────────────────────────────────────────────────────
379
379
 
380
380
  /**
@@ -639,11 +639,12 @@ export class ObjectLayerEngine {
639
639
 
640
640
  /**
641
641
  * Creates new ObjectLayerRenderFrames and ObjectLayer documents in MongoDB from the
642
- * provided data, computes an initial SHA-256, and optionally generates the atlas sprite sheet.
642
+ * provided data, with cut-over consistency: all CIDs (atlas PNG, atlas metadata, data JSON)
643
+ * are computed and pinned to IPFS BEFORE the ObjectLayer document is created or updated in
644
+ * MongoDB, so the object layer is never visible in queries with empty CIDs.
643
645
  *
644
- * When `generateAtlas` is `true` (the default) the method delegates to
645
- * `AtlasSpriteSheetService.generate` and then recomputes the definitive SHA-256
646
- * (which now includes `data.render.cid`) and persists an IPFS CID.
646
+ * If an existing ObjectLayer with the same `data.item.id` is found, it is atomically
647
+ * replaced (findByIdAndUpdate) and the old ObjectLayerRenderFrames is cleaned up.
647
648
  *
648
649
  * @static
649
650
  * @param {Object} params - Parameters.
@@ -664,44 +665,95 @@ export class ObjectLayerEngine {
664
665
  }) {
665
666
  const { generateAtlas = true, atlasServiceContext = null } = createOptions;
666
667
 
667
- // 1. Persist ObjectLayerRenderFrames
668
+ // 1. Persist ObjectLayerRenderFrames (not queried by the viewer table)
668
669
  const objectLayerRenderFramesDoc = await ObjectLayerRenderFrames.create(objectLayerRenderFramesData);
669
670
 
670
- // 2. Attach reference + compute temporary SHA-256
671
+ // 2. Set up references in memory
671
672
  objectLayerData.objectLayerRenderFramesId = objectLayerRenderFramesDoc._id;
672
673
  if (!objectLayerData.data.render) objectLayerData.data.render = {};
673
- objectLayerData.data.render.cid = objectLayerData.data.render.cid || '';
674
- objectLayerData.sha256 = ObjectLayerEngine.computeSha256(objectLayerData.data);
674
+ objectLayerData.data.render.cid = '';
675
+ objectLayerData.data.render.metadataCid = '';
675
676
 
676
- // 3. Upsert ObjectLayer (handle duplicate sha256 gracefully)
677
+ // 3. Stage atlas + IPFS CIDs BEFORE creating/updating the ObjectLayer
678
+ if (generateAtlas && atlasServiceContext) {
679
+ const {
680
+ req,
681
+ res,
682
+ options,
683
+ AtlasSpriteSheetService,
684
+ IpfsClient: ipfsClient,
685
+ createPinRecord,
686
+ } = atlasServiceContext;
687
+
688
+ try {
689
+ const stagingOL = {
690
+ data: objectLayerData.data,
691
+ objectLayerRenderFramesId: objectLayerRenderFramesDoc,
692
+ };
693
+ const result = await AtlasSpriteSheetService.generate(
694
+ { objectLayer: stagingOL, auth: req ? req.auth : undefined },
695
+ res,
696
+ options,
697
+ { skipObjectLayerSave: true },
698
+ );
699
+ objectLayerData.data.render.cid = result.atlasCid;
700
+ objectLayerData.data.render.metadataCid = result.atlasMetadataCid;
701
+ objectLayerData.atlasSpriteSheetId = result.atlasDoc._id;
702
+ } catch (atlasError) {
703
+ logger.error('Failed to generate atlas during staging:', atlasError);
704
+ }
705
+
706
+ // Compute final SHA-256 (includes render CIDs)
707
+ objectLayerData.sha256 = ObjectLayerEngine.computeSha256(objectLayerData.data);
708
+
709
+ // Pin data JSON to IPFS
710
+ if (ipfsClient) {
711
+ try {
712
+ const itemId = objectLayerData.data.item.id;
713
+ const mfsPath = `/object-layer/${itemId}/${itemId}_data.json`;
714
+ const ipfsResult = await ipfsClient.addJsonToIpfs(objectLayerData.data, `${itemId}_data.json`, mfsPath);
715
+ if (ipfsResult) {
716
+ objectLayerData.cid = ipfsResult.cid;
717
+ if (createPinRecord) {
718
+ await createPinRecord({ cid: ipfsResult.cid, resourceType: 'object-layer-data', mfsPath, options });
719
+ }
720
+ }
721
+ } catch (ipfsError) {
722
+ logger.warn('Failed to pin data JSON to IPFS:', ipfsError.message);
723
+ }
724
+ }
725
+ } else {
726
+ // No atlas generation - compute SHA-256 without render CIDs
727
+ objectLayerData.sha256 = ObjectLayerEngine.computeSha256(objectLayerData.data);
728
+ }
729
+
730
+ // 4. Atomic create/upsert - ObjectLayer is fully populated with all CIDs
677
731
  let objectLayer;
678
- const existingObjectLayer = await ObjectLayer.findOne({ sha256: objectLayerData.sha256 });
679
- if (existingObjectLayer) {
680
- logger.info(`ObjectLayer with sha256 ${objectLayerData.sha256} already exists, updating...`);
681
- objectLayer = await ObjectLayer.findByIdAndUpdate(existingObjectLayer._id, objectLayerData, {
682
- new: true,
732
+ const existingByItemId = await ObjectLayer.findOne({ 'data.item.id': objectLayerData.data.item.id });
733
+ if (existingByItemId) {
734
+ const oldRenderFramesId = existingByItemId.objectLayerRenderFramesId;
735
+ logger.info(
736
+ `ObjectLayer for item "${objectLayerData.data.item.id}" exists (${existingByItemId._id}), replacing atomically...`,
737
+ );
738
+ objectLayer = await ObjectLayer.findByIdAndUpdate(existingByItemId._id, objectLayerData, {
739
+ returnDocument: 'after',
683
740
  }).populate('objectLayerRenderFramesId');
741
+ if (oldRenderFramesId && !oldRenderFramesId.equals(objectLayerRenderFramesDoc._id)) {
742
+ await ObjectLayerRenderFrames.findByIdAndDelete(oldRenderFramesId);
743
+ }
684
744
  } else {
685
745
  objectLayer = await (await ObjectLayer.create(objectLayerData)).populate('objectLayerRenderFramesId');
686
746
  logger.info(`ObjectLayer created successfully with id: ${objectLayer._id}`);
687
747
  }
688
748
 
689
- // 4. Optional atlas generation + final SHA-256 / IPFS CID
690
- if (generateAtlas && atlasServiceContext) {
691
- objectLayer = await ObjectLayerEngine._generateAtlasAndFinalize({
692
- objectLayer,
693
- ObjectLayer,
694
- atlasServiceContext,
695
- isNew: true,
696
- });
697
- }
698
-
699
749
  return { objectLayer, objectLayerRenderFramesDoc };
700
750
  }
701
751
 
702
752
  /**
703
753
  * Updates an existing ObjectLayer and its ObjectLayerRenderFrames from the provided data,
704
- * recomputes SHA-256, and optionally regenerates the atlas sprite sheet.
754
+ * with cut-over consistency: a new ObjectLayerRenderFrames is created, then atlas and all
755
+ * CIDs are staged BEFORE the live ObjectLayer is touched. The live document is updated
756
+ * atomically via findByIdAndUpdate only after all CIDs are computed.
705
757
  *
706
758
  * @static
707
759
  * @param {Object} params - Parameters.
@@ -724,49 +776,92 @@ export class ObjectLayerEngine {
724
776
  }) {
725
777
  const { generateAtlas = true, atlasServiceContext = null } = updateOptions;
726
778
 
727
- // 1. Update or create ObjectLayerRenderFrames
728
- let objectLayerRenderFramesDoc;
779
+ // 1. Load existing ObjectLayer to get old references
729
780
  const existingObjectLayer = await ObjectLayer.findById(objectLayerId);
730
- if (existingObjectLayer && existingObjectLayer.objectLayerRenderFramesId) {
731
- objectLayerRenderFramesDoc = await ObjectLayerRenderFrames.findByIdAndUpdate(
732
- existingObjectLayer.objectLayerRenderFramesId,
733
- objectLayerRenderFramesData,
734
- { new: true },
735
- );
736
- objectLayerData.objectLayerRenderFramesId = existingObjectLayer.objectLayerRenderFramesId;
737
- } else {
738
- objectLayerRenderFramesDoc = await ObjectLayerRenderFrames.create(objectLayerRenderFramesData);
739
- objectLayerData.objectLayerRenderFramesId = objectLayerRenderFramesDoc._id;
781
+ if (!existingObjectLayer) {
782
+ throw new Error('ObjectLayer not found for update');
740
783
  }
784
+ const oldRenderFramesId = existingObjectLayer.objectLayerRenderFramesId;
785
+
786
+ // 2. Create NEW RenderFrames (avoid mutating old doc mid-update)
787
+ const objectLayerRenderFramesDoc = await ObjectLayerRenderFrames.create(objectLayerRenderFramesData);
788
+ objectLayerData.objectLayerRenderFramesId = objectLayerRenderFramesDoc._id;
741
789
 
742
- // 2. Compute temporary SHA-256
790
+ // 3. Set up render CIDs
743
791
  if (!objectLayerData.data.render) objectLayerData.data.render = {};
744
- objectLayerData.data.render.cid = objectLayerData.data.render.cid || '';
745
- objectLayerData.sha256 = ObjectLayerEngine.computeSha256(objectLayerData.data);
792
+ objectLayerData.data.render.cid = '';
793
+ objectLayerData.data.render.metadataCid = '';
746
794
 
747
- // 3. Persist ObjectLayer update
795
+ // 4. Stage atlas + IPFS CIDs BEFORE updating the ObjectLayer
796
+ if (generateAtlas && atlasServiceContext) {
797
+ const {
798
+ req,
799
+ res,
800
+ options,
801
+ AtlasSpriteSheetService,
802
+ IpfsClient: ipfsClient,
803
+ createPinRecord,
804
+ } = atlasServiceContext;
805
+
806
+ try {
807
+ const stagingOL = {
808
+ data: objectLayerData.data,
809
+ objectLayerRenderFramesId: objectLayerRenderFramesDoc,
810
+ };
811
+ const result = await AtlasSpriteSheetService.generate(
812
+ { objectLayer: stagingOL, auth: req ? req.auth : undefined },
813
+ res,
814
+ options,
815
+ { skipObjectLayerSave: true },
816
+ );
817
+ objectLayerData.data.render.cid = result.atlasCid;
818
+ objectLayerData.data.render.metadataCid = result.atlasMetadataCid;
819
+ objectLayerData.atlasSpriteSheetId = result.atlasDoc._id;
820
+ } catch (atlasError) {
821
+ logger.error('Failed to generate atlas during update staging:', atlasError);
822
+ }
823
+
824
+ // Compute final SHA-256 (includes render CIDs)
825
+ objectLayerData.sha256 = ObjectLayerEngine.computeSha256(objectLayerData.data);
826
+
827
+ // Pin data JSON to IPFS
828
+ if (ipfsClient) {
829
+ try {
830
+ const itemId = objectLayerData.data.item.id;
831
+ const mfsPath = `/object-layer/${itemId}/${itemId}_data.json`;
832
+ const ipfsResult = await ipfsClient.addJsonToIpfs(objectLayerData.data, `${itemId}_data.json`, mfsPath);
833
+ if (ipfsResult) {
834
+ objectLayerData.cid = ipfsResult.cid;
835
+ if (createPinRecord) {
836
+ await createPinRecord({ cid: ipfsResult.cid, resourceType: 'object-layer-data', mfsPath, options });
837
+ }
838
+ }
839
+ } catch (ipfsError) {
840
+ logger.warn('Failed to pin data JSON to IPFS:', ipfsError.message);
841
+ }
842
+ }
843
+ } else {
844
+ objectLayerData.sha256 = ObjectLayerEngine.computeSha256(objectLayerData.data);
845
+ }
846
+
847
+ // 5. Atomic update - ObjectLayer is fully populated with all CIDs
748
848
  let objectLayer;
749
849
  try {
750
850
  objectLayer = await ObjectLayer.findByIdAndUpdate(objectLayerId, objectLayerData, {
751
- new: true,
851
+ returnDocument: 'after',
752
852
  }).populate('objectLayerRenderFramesId');
753
853
  if (!objectLayer) {
754
854
  throw new Error('ObjectLayer not found for update');
755
855
  }
756
- logger.info(`ObjectLayer updated successfully with id: ${objectLayerId}`);
856
+ logger.info(`ObjectLayer updated atomically with id: ${objectLayerId}`);
757
857
  } catch (error) {
758
858
  logger.error('Error updating ObjectLayer:', error);
759
859
  throw error;
760
860
  }
761
861
 
762
- // 4. Optional atlas generation + final SHA-256 / IPFS CID
763
- if (generateAtlas && atlasServiceContext) {
764
- objectLayer = await ObjectLayerEngine._generateAtlasAndFinalize({
765
- objectLayer,
766
- ObjectLayer,
767
- atlasServiceContext,
768
- isNew: false,
769
- });
862
+ // 6. Clean up old RenderFrames
863
+ if (oldRenderFramesId && !oldRenderFramesId.equals(objectLayerRenderFramesDoc._id)) {
864
+ await ObjectLayerRenderFrames.findByIdAndDelete(oldRenderFramesId);
770
865
  }
771
866
 
772
867
  return { objectLayer, objectLayerRenderFramesDoc };
@@ -783,26 +878,22 @@ export class ObjectLayerEngine {
783
878
  * @param {Object} params.objectLayer - The mongoose ObjectLayer document (must be populated).
784
879
  * @param {Object} [params.ipfsClient=null] - The IpfsClient module; when `null`, IPFS pinning is skipped.
785
880
  * @param {function} [params.createPinRecord=null] - The `createPinRecord` helper; when `null`, pin records are skipped.
786
- * @param {string} [params.userId] - Authenticated user ID for IPFS pin record creation.
787
881
  * @param {Object} [params.options] - Server options (host, path) forwarded to `createPinRecord`.
788
882
  * @returns {Promise<Object>} The saved ObjectLayer document.
789
883
  * @memberof CyberiaObjectLayer
790
884
  */
791
- static async computeAndSaveFinalSha256({ objectLayer, ipfsClient = null, createPinRecord = null, userId, options }) {
885
+ static async computeAndSaveFinalSha256({ objectLayer, ipfsClient = null, createPinRecord = null, options }) {
792
886
  const finalSha256 = ObjectLayerEngine.computeSha256(objectLayer.data);
793
887
 
794
888
  if (ipfsClient) {
795
889
  try {
796
890
  const itemId = objectLayer.data.item.id;
797
- const ipfsResult = await ipfsClient.addJsonToIpfs(
798
- objectLayer.data,
799
- `${itemId}_data.json`,
800
- `/object-layer/${itemId}/${itemId}_data.json`,
801
- );
891
+ const mfsPath = `/object-layer/${itemId}/${itemId}_data.json`;
892
+ const ipfsResult = await ipfsClient.addJsonToIpfs(objectLayer.data, `${itemId}_data.json`, mfsPath);
802
893
  if (ipfsResult) {
803
894
  objectLayer.cid = ipfsResult.cid;
804
- if (userId && createPinRecord) {
805
- await createPinRecord({ cid: ipfsResult.cid, userId, options });
895
+ if (createPinRecord) {
896
+ await createPinRecord({ cid: ipfsResult.cid, resourceType: 'object-layer-data', mfsPath, options });
806
897
  }
807
898
  }
808
899
  } catch (ipfsError) {
@@ -818,56 +909,72 @@ export class ObjectLayerEngine {
818
909
  }
819
910
 
820
911
  /**
821
- * Internal helper that generates an atlas sprite sheet and then finalizes the SHA-256 / IPFS CID.
912
+ * Resolve the canonical CID for an Object Layer item from the database.
913
+ *
914
+ * The canonical CID is the IPFS content identifier of the stable-JSON-serialised
915
+ * `objectLayer.data` document (produced by `fast-json-stable-stringify`). This is
916
+ * the CID that MUST be stored on-chain as the metadata CID so that any party can
917
+ * independently reproduce the hash from the same semantic payload.
918
+ *
919
+ * Resolution order:
920
+ * 1. If the ObjectLayer document already has a `.cid` field, use it.
921
+ * 2. Otherwise compute it on-the-fly via `ipfsClient.addJsonToIpfs` (pins the
922
+ * data to IPFS as a side-effect) and persist it back to the document.
923
+ * 3. If IPFS is unreachable, fall back to a local SHA-256 so the caller at
924
+ * least gets a content hash (prefixed with `sha256:` to distinguish it
925
+ * from a real IPFS CID).
926
+ *
822
927
  * @static
823
- * @param {Object} params - Parameters.
824
- * @param {Object} params.objectLayer - The mongoose ObjectLayer document.
825
- * @param {Object} params.ObjectLayer - Mongoose ObjectLayer model (for re-reading).
826
- * @param {Object} params.atlasServiceContext - Context with `{ req, res, options, AtlasSpriteSheetService, IpfsClient, createPinRecord }`.
827
- * @param {boolean} params.isNew - Whether this is a newly created object layer (used for logging).
828
- * @returns {Promise<Object>} The finalized ObjectLayer document.
928
+ * @param {Object} params
929
+ * @param {string} params.itemId – human-readable item identifier.
930
+ * @param {import('mongoose').Model} params.ObjectLayer Mongoose ObjectLayer model.
931
+ * @param {Object} [params.ipfsClient=null] The IpfsClient module; when `null`, IPFS pinning is skipped and only SHA-256 fallback is returned.
932
+ * @param {Object} [params.options] – `{ host, path }` forwarded to pin helpers.
933
+ * @returns {Promise<{ cid: string, sha256: string, source: string }>}
829
934
  * @memberof CyberiaObjectLayer
830
- * @private
831
935
  */
832
- static async _generateAtlasAndFinalize({ objectLayer, ObjectLayer, atlasServiceContext, isNew }) {
833
- const { req, res, options, AtlasSpriteSheetService, IpfsClient: ipfsClient, createPinRecord } = atlasServiceContext;
936
+ static async resolveCanonicalCid({ itemId, ObjectLayer, ipfsClient = null, options }) {
937
+ const objectLayer = await ObjectLayer.findOne({ 'data.item.id': itemId });
938
+ if (!objectLayer) {
939
+ throw new Error(`ObjectLayer "${itemId}" not found in database`);
940
+ }
834
941
 
835
- // Generate atlas sprite sheet
836
- try {
837
- await AtlasSpriteSheetService.generate(
838
- { params: { id: objectLayer._id }, objectLayer, auth: req ? req.auth : undefined },
839
- res,
840
- options,
841
- );
842
- } catch (atlasError) {
843
- logger.error(`Failed to auto-${isNew ? 'generate' : 'update'} atlas for ObjectLayer:`, atlasError);
942
+ const sha256 = ObjectLayerEngine.computeSha256(objectLayer.data);
943
+
944
+ // 1. Already have a canonical CID persisted
945
+ if (objectLayer.cid) {
946
+ return { cid: objectLayer.cid, sha256, source: 'db' };
844
947
  }
845
948
 
846
- // Re-read the objectLayer so data.render.cid is up-to-date
847
- objectLayer = await ObjectLayer.findById(objectLayer._id).populate('objectLayerRenderFramesId');
848
-
849
- // Compute definitive SHA-256 and IPFS CID
850
- const userId = req && req.auth && req.auth.user ? req.auth.user._id : undefined;
851
- objectLayer = await ObjectLayerEngine.computeAndSaveFinalSha256({
852
- objectLayer,
853
- ipfsClient: ipfsClient || null,
854
- createPinRecord: createPinRecord || null,
855
- userId,
856
- options,
857
- });
949
+ // 2. Try to compute and persist via IPFS
950
+ if (ipfsClient) {
951
+ try {
952
+ const ipfsResult = await ipfsClient.addJsonToIpfs(
953
+ objectLayer.data,
954
+ `${itemId}_data.json`,
955
+ `/object-layer/${itemId}/${itemId}_data.json`,
956
+ );
957
+ if (ipfsResult) {
958
+ objectLayer.cid = ipfsResult.cid;
959
+ objectLayer.sha256 = sha256;
960
+ objectLayer.markModified('data');
961
+ await objectLayer.save();
962
+ logger.info(`Canonical CID computed and persisted for "${itemId}": ${ipfsResult.cid}`);
963
+ return { cid: ipfsResult.cid, sha256, source: 'ipfs' };
964
+ }
965
+ } catch (err) {
966
+ logger.warn(`IPFS unreachable while resolving canonical CID for "${itemId}": ${err.message}`);
967
+ }
968
+ }
858
969
 
859
- return objectLayer;
970
+ // 3. Fallback – return a sha256:-prefixed content hash
971
+ logger.warn(
972
+ `Using SHA-256 fallback for "${itemId}" (IPFS unavailable). On-chain CID will not resolve via gateway.`,
973
+ );
974
+ return { cid: `sha256:${sha256}`, sha256, source: 'sha256-fallback' };
860
975
  }
861
976
  }
862
977
 
863
- /**
864
- * Mapping of item type names to numerical IDs.
865
- * @constant
866
- * @type {{floor: number, skin: number, weapon: number, skill: number, coin: number}}
867
- * @memberof CyberiaObjectLayer
868
- */
869
- export const itemTypes = { floor: 0, skin: 1, weapon: 2, skill: 3, coin: 4 };
870
-
871
978
  // ──────────────────────────────────────────────────────────────────────────
872
979
  // Backward-compatible named exports matching the original destructured imports.
873
980
  // ──────────────────────────────────────────────────────────────────────────
@@ -963,3 +1070,10 @@ export const computeAndSaveFinalSha256 = ObjectLayerEngine.computeAndSaveFinalSh
963
1070
  * @memberof CyberiaObjectLayer
964
1071
  */
965
1072
  export const writeStaticFrameAssets = ObjectLayerEngine.writeStaticFrameAssets;
1073
+
1074
+ /**
1075
+ * @see {@link ObjectLayerEngine.resolveCanonicalCid}
1076
+ * @function resolveCanonicalCid
1077
+ * @memberof CyberiaObjectLayer
1078
+ */
1079
+ export const resolveCanonicalCid = ObjectLayerEngine.resolveCanonicalCid;
@@ -12,8 +12,6 @@ import dotenv from 'dotenv';
12
12
  import { loggerFactory } from './logger.js';
13
13
  import Underpost from '../index.js';
14
14
 
15
- dotenv.config();
16
-
17
15
  /**
18
16
  * Logger instance for this module, utilizing the framework's factory.
19
17
  * @type {function(*): void}
@@ -46,6 +44,14 @@ const logger = loggerFactory(import.meta);
46
44
  */
47
45
  const createPeerServer = async ({ port, origins, path }) => {
48
46
  logger.info('origins', origins);
47
+
48
+ // In development, allow the local client origin (peer runs on port+1 relative to the client)
49
+ if (process.env.NODE_ENV === 'development') {
50
+ const clientPort = port - 1;
51
+ const devOrigin = `http://localhost:${clientPort}`;
52
+ if (!origins.includes(devOrigin)) origins.push(devOrigin);
53
+ }
54
+
49
55
  /** @type {import('peer').IConfig} */
50
56
  const options = {
51
57
  port,
@@ -8,14 +8,11 @@
8
8
  // https://nodejs.org/api/process
9
9
 
10
10
  import shell from 'shelljs';
11
- import dotenv from 'dotenv';
12
11
  import { loggerFactory } from './logger.js';
13
12
  import clipboard from 'clipboardy';
14
13
  import Underpost from '../index.js';
15
14
  import { getNpmRootPath } from './conf.js';
16
15
 
17
- dotenv.config();
18
-
19
16
  const logger = loggerFactory(import.meta);
20
17
 
21
18
  /**
@@ -122,52 +119,6 @@ const shellCd = (cd, options = { disableLog: false }) => {
122
119
  return shell.cd(cd);
123
120
  };
124
121
 
125
- /**
126
- * Opens a new GNOME terminal and executes a command.
127
- * Note: This function is environment-specific (GNOME/Linux).
128
- * @memberof Process
129
- * @param {string} cmd - The command to execute in the new terminal.
130
- * @param {Object} [options] - Options for the terminal opening.
131
- * @param {boolean} [options.single=false] - If true, execute as a single session process using `setsid`.
132
- * @param {string} [options.chown] - Path to change ownership to the target user.
133
- * @returns {void}
134
- */
135
- const openTerminal = (cmd, options = { single: false }) => {
136
- // Find the graphical user's UID from /run/user (prefer non-root UID, usually 1000)
137
- const IDS = shellExec(`ls -1 /run/user`, { stdout: true, silent: true })
138
- .split('\n')
139
- .map((v) => v.trim())
140
- .filter(Boolean);
141
-
142
- const nonRootIds = IDS.filter((id) => id !== '0');
143
- const ID = nonRootIds.length > 0 ? nonRootIds[0] : IDS[0];
144
-
145
- if (!options.chown) options.chown = `/home/dd ${getNpmRootPath()}/underpost`;
146
-
147
- shellExec(`chown -R ${ID}:${ID} ${options.chown}`);
148
-
149
- // Run the terminal as the graphical user and use THAT user's runtime dir/bus.
150
- const confCmd = `USER_GRAPHICAL=$(getent passwd "${ID}" | cut -d: -f1); \
151
- sudo -u "$USER_GRAPHICAL" env DISPLAY="$DISPLAY" \
152
- XDG_RUNTIME_DIR="/run/user/${ID}" \
153
- DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${ID}/bus" \
154
- PATH="$PATH" \
155
- `;
156
-
157
- if (options.single === true) {
158
- // Run as a single session process
159
- shellExec(`${confCmd} setsid gnome-terminal -- bash -ic '${cmd}; exec bash' >/dev/null 2>&1 &`, {
160
- async: true,
161
- });
162
- return;
163
- }
164
- // Run asynchronously and disown
165
- shellExec(`${confCmd} gnome-terminal -- bash -c '${cmd}; exec bash' >/dev/null 2>&1 & disown`, {
166
- async: true,
167
- stdout: true,
168
- });
169
- };
170
-
171
122
  /**
172
123
  * Wraps a command to run it as a daemon process in a shell (keeping the process alive/terminal open).
173
124
  * @memberof Process
@@ -198,4 +149,4 @@ function pbcopy(data) {
198
149
  logger.info(`copied to clipboard`, clipboard.readSync());
199
150
  }
200
151
 
201
- export { ProcessController, getRootDirectory, shellExec, shellCd, pbcopy, openTerminal, getTerminalPid, daemonProcess };
152
+ export { ProcessController, getRootDirectory, shellExec, shellCd, pbcopy, getTerminalPid, daemonProcess };
@@ -7,8 +7,6 @@
7
7
  'use strict';
8
8
 
9
9
  import express from 'express';
10
- import dotenv from 'dotenv';
11
-
12
10
  import { createProxyMiddleware } from 'http-proxy-middleware';
13
11
  import { loggerFactory, loggerMiddleware } from './logger.js';
14
12
  import { buildPortProxyRouter, buildProxyRouter, getTlsHosts, isDevProxyContext, isTlsDevProxy } from './conf.js';
@@ -17,8 +15,6 @@ import { shellExec } from './process.js';
17
15
  import fs from 'fs-extra';
18
16
  import Underpost from '../index.js';
19
17
 
20
- dotenv.config();
21
-
22
18
  const logger = loggerFactory(import.meta);
23
19
 
24
20
  /**
@@ -56,11 +52,12 @@ class ProxyService {
56
52
  // Proxy middleware options
57
53
  /** @type {import('http-proxy-middleware/dist/types').Options} */
58
54
  const options = {
55
+ pathFilter: proxyPath, // Use '/' as the general filter (v3 API)
59
56
  ws: true, // Enable websocket proxying
60
57
  target: `http://localhost:${parseInt(process.env.PORT - 1)}`, // Default target (should be overridden by router)
61
58
  router: {},
62
59
  // changeOrigin: true,
63
- logLevel: 'debug',
60
+ logger: logger,
64
61
  xfwd: true, // Adds x-forward headers (Host, Proto, etc.)
65
62
  onProxyReq: (proxyReq, req, res, options) => {},
66
63
  pathRewrite: {},
@@ -74,8 +71,7 @@ class ProxyService {
74
71
  devProxyContext: process.env.NODE_ENV !== 'production',
75
72
  });
76
73
 
77
- const filter = proxyPath; // Use '/' as the general filter
78
- app.use(proxyPath, createProxyMiddleware(filter, options));
74
+ app.use(proxyPath, createProxyMiddleware(options));
79
75
 
80
76
  // Determine which server to start (HTTP or HTTPS) based on port and environment
81
77
  switch (process.env.NODE_ENV) {
@@ -115,7 +111,7 @@ class ProxyService {
115
111
  break;
116
112
  }
117
113
  }
118
- logger.info('Proxy running', { port, options });
114
+ logger.info('Proxy running', { port, router: options.router });
119
115
  if (process.env.NODE_ENV === 'development')
120
116
  logger.info(
121
117
  Underpost.deploy.etcHostFactory(Object.keys(options.router), {