@underpostnet/cyberia 3.2.80
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.
- package/.dockerignore +14 -0
- package/.env.example +144 -0
- package/.github/workflows/cyberia-client.cd.yml +40 -0
- package/.github/workflows/cyberia-server.cd.yml +40 -0
- package/.github/workflows/docker-image.cyberia-client.ci.yml +71 -0
- package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +70 -0
- package/.github/workflows/docker-image.cyberia-server.ci.yml +71 -0
- package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +71 -0
- package/.github/workflows/docker-image.engine-cyberia.ci.yml +53 -0
- package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +53 -0
- package/.github/workflows/engine-cyberia.cd.yml +157 -0
- package/.github/workflows/engine-cyberia.ci.yml +125 -0
- package/.github/workflows/ghpkg.ci.yml +160 -0
- package/.github/workflows/gitlab.ci.yml +20 -0
- package/.github/workflows/hardhat.ci.yml +82 -0
- package/.github/workflows/npmpkg.ci.yml +126 -0
- package/.github/workflows/publish.ci.yml +87 -0
- package/.github/workflows/publish.cyberia.ci.yml +79 -0
- package/.github/workflows/pwa-microservices-template-page.cd.yml +65 -0
- package/.github/workflows/pwa-microservices-template-test.ci.yml +33 -0
- package/.github/workflows/release.cd.yml +46 -0
- package/.nycrc +9 -0
- package/.prettierignore +12 -0
- package/.prettierrc +9 -0
- package/.vscode/extensions.json +10 -0
- package/.vscode/settings.json +26 -0
- package/CHANGELOG.md +2516 -0
- package/CLI-HELP.md +1099 -0
- package/Dockerfile +161 -0
- package/Dockerfile.dev +161 -0
- package/Dockerfile.test +165 -0
- package/LICENSE +21 -0
- package/README.md +259 -0
- package/baremetal/commission-workflows.json +211 -0
- package/baremetal/packer-workflows.json +24 -0
- package/bin/build.js +261 -0
- package/bin/build.template.js +33 -0
- package/bin/cyberia.js +5627 -0
- package/bin/deploy.js +1547 -0
- package/bin/index.js +5627 -0
- package/bump.config.js +27 -0
- package/compose.env +144 -0
- package/conf.js +952 -0
- package/deployment.yaml +418 -0
- package/docker-compose.yml +434 -0
- package/examples/static-page/README.md +150 -0
- package/examples/static-page/ssr-components/CustomPage.js +554 -0
- package/examples/static-page/static-config-example.json +57 -0
- package/hardhat/.env.example +31 -0
- package/hardhat/contracts/ObjectLayerToken.sol +391 -0
- package/hardhat/deployments/.gitkeep +0 -0
- package/hardhat/deployments/hardhat-ObjectLayerToken.json +11 -0
- package/hardhat/hardhat.config.js +136 -0
- package/hardhat/ignition/modules/.gitkeep +0 -0
- package/hardhat/ignition/modules/ObjectLayerToken.js +21 -0
- package/hardhat/networks/besu-object-layer.network.json +138 -0
- package/hardhat/package-lock.json +2871 -0
- package/hardhat/package.json +43 -0
- package/hardhat/scripts/deployObjectLayerToken.js +98 -0
- package/hardhat/test/ObjectLayerToken.js +696 -0
- package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
- package/hardhat/types/ethers-contracts/common.ts +92 -0
- package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
- package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
- package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
- package/hardhat/types/ethers-contracts/index.ts +6 -0
- package/ipfs/configure-ipfs.sh +13 -0
- package/jsconfig.json +9 -0
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +48 -0
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +48 -0
- package/manifests/deployment/adminer/deployment.yaml +32 -0
- package/manifests/deployment/adminer/kustomization.yaml +7 -0
- package/manifests/deployment/adminer/service.yaml +13 -0
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +418 -0
- package/manifests/deployment/dd-cyberia-development/grpc-service.yaml +17 -0
- package/manifests/deployment/dd-cyberia-development/proxy.yaml +189 -0
- package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +164 -0
- package/manifests/deployment/dd-default-development/deployment.yaml +163 -0
- package/manifests/deployment/dd-default-development/proxy.yaml +46 -0
- package/manifests/deployment/fastapi/backend-deployment.yml +120 -0
- package/manifests/deployment/fastapi/backend-service.yml +19 -0
- package/manifests/deployment/fastapi/frontend-deployment.yml +54 -0
- package/manifests/deployment/fastapi/frontend-service.yml +15 -0
- package/manifests/deployment/fastapi/initial_data.sh +8 -0
- package/manifests/deployment/kafka/deployment.yaml +67 -0
- package/manifests/deployment/mongo-express/deployment.yaml +62 -0
- package/manifests/deployment/phpmyadmin/deployment.yaml +54 -0
- package/manifests/deployment/playwright/deployment.yaml +52 -0
- package/manifests/deployment/spark/spark-pi-py.yaml +20 -0
- package/manifests/deployment/tensorflow/tf-gpu-test.yaml +63 -0
- package/manifests/envoy-service-nodeport.yaml +22 -0
- package/manifests/grafana/deployment.yaml +64 -0
- package/manifests/grafana/kustomization.yaml +7 -0
- package/manifests/grafana/pvc.yaml +12 -0
- package/manifests/grafana/service.yaml +14 -0
- package/manifests/grafana/storage-class.yaml +9 -0
- package/manifests/ipfs/configmap.yaml +64 -0
- package/manifests/ipfs/headless-service.yaml +35 -0
- package/manifests/ipfs/kustomization.yaml +8 -0
- package/manifests/ipfs/statefulset.yaml +149 -0
- package/manifests/ipfs/storage-class.yaml +9 -0
- package/manifests/kind-config-dev.yaml +20 -0
- package/manifests/kind-config.yaml +12 -0
- package/manifests/kubeadm-calico-config.yaml +14 -0
- package/manifests/letsencrypt-prod.yaml +14 -0
- package/manifests/lxd/lxd-admin-profile.yaml +26 -0
- package/manifests/lxd/lxd-preseed.yaml +30 -0
- package/manifests/mariadb/kustomization.yaml +9 -0
- package/manifests/mariadb/pv.yaml +12 -0
- package/manifests/mariadb/pvc.yaml +10 -0
- package/manifests/mariadb/service.yaml +10 -0
- package/manifests/mariadb/statefulset.yaml +56 -0
- package/manifests/mariadb/storage-class.yaml +10 -0
- package/manifests/mongodb/headless-service.yaml +10 -0
- package/manifests/mongodb/kustomization.yaml +11 -0
- package/manifests/mongodb/pv-pvc.yaml +59 -0
- package/manifests/mongodb/statefulset.yaml +113 -0
- package/manifests/mongodb/storage-class.yaml +9 -0
- package/manifests/mongodb-4.4/headless-service.yaml +10 -0
- package/manifests/mongodb-4.4/kustomization.yaml +9 -0
- package/manifests/mongodb-4.4/mongodb-nodeport.yaml +17 -0
- package/manifests/mongodb-4.4/pv-pvc.yaml +19 -0
- package/manifests/mongodb-4.4/service-deployment.yaml +61 -0
- package/manifests/mongodb-4.4/statefulset.yaml +79 -0
- package/manifests/mongodb-4.4/storage-class.yaml +9 -0
- package/manifests/mysql/kustomization.yaml +7 -0
- package/manifests/mysql/pv-pvc.yaml +27 -0
- package/manifests/mysql/statefulset.yaml +55 -0
- package/manifests/postgresql/configmap.yaml +9 -0
- package/manifests/postgresql/kustomization.yaml +10 -0
- package/manifests/postgresql/pv.yaml +15 -0
- package/manifests/postgresql/pvc.yaml +13 -0
- package/manifests/postgresql/service.yaml +10 -0
- package/manifests/postgresql/statefulset.yaml +37 -0
- package/manifests/prometheus/deployment.yaml +82 -0
- package/manifests/pv-pvc-dd.yaml +34 -0
- package/manifests/valkey/kustomization.yaml +7 -0
- package/manifests/valkey/service.yaml +10 -0
- package/manifests/valkey/statefulset.yaml +37 -0
- package/manifests/valkey/valkey-nodeport.yaml +17 -0
- package/mongodb/entrypoint.sh +76 -0
- package/nginx.conf +128 -0
- package/nodemon.json +6 -0
- package/package.json +101 -0
- package/packer/images/Rocky9Amd64/Makefile +62 -0
- package/packer/images/Rocky9Amd64/QUICKSTART.md +113 -0
- package/packer/images/Rocky9Amd64/README.md +122 -0
- package/packer/images/Rocky9Amd64/http/rocky9.ks.pkrtpl.hcl +114 -0
- package/packer/images/Rocky9Amd64/rocky9.pkr.hcl +164 -0
- package/packer/images/Rocky9Arm64/Makefile +69 -0
- package/packer/images/Rocky9Arm64/README.md +122 -0
- package/packer/images/Rocky9Arm64/http/rocky9.ks.pkrtpl.hcl +114 -0
- package/packer/images/Rocky9Arm64/rocky9.pkr.hcl +171 -0
- package/packer/scripts/fuse-nbd +64 -0
- package/packer/scripts/fuse-tar-root +63 -0
- package/proxy.yaml +189 -0
- package/pv-pvc.yaml +164 -0
- package/scripts/device-scan.sh +65 -0
- package/scripts/disk-clean.sh +182 -0
- package/scripts/disk-devices.sh +13 -0
- package/scripts/gen-fqdns.sh +14 -0
- package/scripts/gpu-diag.sh +19 -0
- package/scripts/ip-info.sh +118 -0
- package/scripts/ipxe-setup.sh +200 -0
- package/scripts/k3s-node-setup.sh +124 -0
- package/scripts/kubeadm-node-setup.sh +317 -0
- package/scripts/link-local-underpost-cli.sh +6 -0
- package/scripts/lxd-vm-setup.sh +208 -0
- package/scripts/maas-nat-firewalld.sh +145 -0
- package/scripts/maas-setup.sh +135 -0
- package/scripts/maas-upload-boot-resource.sh +183 -0
- package/scripts/nat-iptables.sh +111 -0
- package/scripts/nvim.sh +91 -0
- package/scripts/packer-init-vars-file.sh +40 -0
- package/scripts/packer-setup.sh +289 -0
- package/scripts/ports-ls.sh +33 -0
- package/scripts/quick-tftp.sh +19 -0
- package/scripts/rhel-grpc-setup.sh +56 -0
- package/scripts/rocky-kickstart.sh +986 -0
- package/scripts/rocky-pwa.sh +200 -0
- package/scripts/rocky-setup.sh +106 -0
- package/scripts/rpmfusion-ffmpeg-setup.sh +32 -0
- package/scripts/ssl.sh +170 -0
- package/scripts/test-monitor.sh +248 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +30 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +155 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +39 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +382 -0
- package/src/api/core/core.controller.js +8 -0
- package/src/api/core/core.model.js +11 -0
- package/src/api/core/core.router.js +23 -0
- package/src/api/core/core.service.js +30 -0
- package/src/api/crypto/crypto.controller.js +10 -0
- package/src/api/crypto/crypto.model.js +23 -0
- package/src/api/crypto/crypto.router.js +23 -0
- package/src/api/crypto/crypto.service.js +64 -0
- package/src/api/cyberia-action/cyberia-action.controller.js +8 -0
- package/src/api/cyberia-action/cyberia-action.model.js +79 -0
- package/src/api/cyberia-action/cyberia-action.router.js +21 -0
- package/src/api/cyberia-action/cyberia-action.service.js +58 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +27 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +100 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +70 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +152 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +8 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +20 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +57 -0
- package/src/api/cyberia-entity/cyberia-entity.controller.js +6 -0
- package/src/api/cyberia-entity/cyberia-entity.model.js +25 -0
- package/src/api/cyberia-entity/cyberia-entity.router.js +17 -0
- package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +6 -0
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +67 -0
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +17 -0
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +46 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +337 -0
- package/src/api/cyberia-instance/cyberia-instance-boot.service.js +57 -0
- package/src/api/cyberia-instance/cyberia-instance-map.service.js +583 -0
- package/src/api/cyberia-instance/cyberia-instance.controller.js +42 -0
- package/src/api/cyberia-instance/cyberia-instance.model.js +117 -0
- package/src/api/cyberia-instance/cyberia-instance.router.js +75 -0
- package/src/api/cyberia-instance/cyberia-instance.service.js +190 -0
- package/src/api/cyberia-instance/cyberia-portal-connector.js +260 -0
- package/src/api/cyberia-instance/cyberia-world-generator.js +618 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +6 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +200 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +17 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +46 -0
- package/src/api/cyberia-map/cyberia-map.controller.js +6 -0
- package/src/api/cyberia-map/cyberia-map.model.js +33 -0
- package/src/api/cyberia-map/cyberia-map.router.js +19 -0
- package/src/api/cyberia-map/cyberia-map.service.js +76 -0
- package/src/api/cyberia-quest/cyberia-quest.controller.js +9 -0
- package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
- package/src/api/cyberia-quest/cyberia-quest.router.js +26 -0
- package/src/api/cyberia-quest/cyberia-quest.service.js +97 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +6 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +21 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
- package/src/api/cyberia-saga/cyberia-saga.controller.js +6 -0
- package/src/api/cyberia-saga/cyberia-saga.model.js +59 -0
- package/src/api/cyberia-saga/cyberia-saga.router.js +17 -0
- package/src/api/cyberia-saga/cyberia-saga.service.js +42 -0
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +1076 -0
- package/src/api/cyberia-skill/cyberia-skill.controller.js +6 -0
- package/src/api/cyberia-skill/cyberia-skill.model.js +50 -0
- package/src/api/cyberia-skill/cyberia-skill.router.js +17 -0
- package/src/api/cyberia-skill/cyberia-skill.service.js +42 -0
- package/src/api/default/default.controller.js +6 -0
- package/src/api/default/default.model.js +20 -0
- package/src/api/default/default.router.js +21 -0
- package/src/api/default/default.service.js +42 -0
- package/src/api/document/document.controller.js +9 -0
- package/src/api/document/document.model.js +95 -0
- package/src/api/document/document.router.js +32 -0
- package/src/api/document/document.service.js +633 -0
- package/src/api/file/file.controller.js +15 -0
- package/src/api/file/file.model.js +127 -0
- package/src/api/file/file.ref.json +39 -0
- package/src/api/file/file.router.js +36 -0
- package/src/api/file/file.service.js +499 -0
- package/src/api/instance/instance.controller.js +8 -0
- package/src/api/instance/instance.model.js +34 -0
- package/src/api/instance/instance.router.js +27 -0
- package/src/api/instance/instance.service.js +75 -0
- package/src/api/ipfs/ipfs.controller.js +8 -0
- package/src/api/ipfs/ipfs.model.js +77 -0
- package/src/api/ipfs/ipfs.router.js +26 -0
- package/src/api/ipfs/ipfs.service.js +145 -0
- package/src/api/object-layer/object-layer.controller.js +18 -0
- package/src/api/object-layer/object-layer.model.js +200 -0
- package/src/api/object-layer/object-layer.router.js +729 -0
- package/src/api/object-layer/object-layer.service.js +894 -0
- package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +6 -0
- package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +93 -0
- package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +17 -0
- package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +46 -0
- package/src/api/test/test.controller.js +14 -0
- package/src/api/test/test.model.js +14 -0
- package/src/api/test/test.router.js +23 -0
- package/src/api/test/test.service.js +35 -0
- package/src/api/types.js +24 -0
- package/src/api/user/guest.service.js +100 -0
- package/src/api/user/postman_collection.json +216 -0
- package/src/api/user/user.build.js +16 -0
- package/src/api/user/user.controller.js +35 -0
- package/src/api/user/user.model.js +142 -0
- package/src/api/user/user.router.js +367 -0
- package/src/api/user/user.service.js +582 -0
- package/src/api.js +23 -0
- package/src/cli/baremetal.js +3947 -0
- package/src/cli/cloud-init.js +673 -0
- package/src/cli/cluster.js +1395 -0
- package/src/cli/db.js +1533 -0
- package/src/cli/deploy.js +1542 -0
- package/src/cli/docker-compose.js +802 -0
- package/src/cli/env.js +177 -0
- package/src/cli/fs.js +380 -0
- package/src/cli/image.js +389 -0
- package/src/cli/index.js +1059 -0
- package/src/cli/ipfs.js +182 -0
- package/src/cli/kickstart.js +271 -0
- package/src/cli/kubectl.js +214 -0
- package/src/cli/lxd.js +1232 -0
- package/src/cli/monitor.js +659 -0
- package/src/cli/release.js +595 -0
- package/src/cli/repository.js +1969 -0
- package/src/cli/run.js +3326 -0
- package/src/cli/secrets.js +151 -0
- package/src/cli/ssh.js +975 -0
- package/src/cli/static.js +653 -0
- package/src/cli/system.js +332 -0
- package/src/cli/test.js +176 -0
- package/src/client/Cryptokoyn.index.js +30 -0
- package/src/client/CyberiaPortal.index.js +31 -0
- package/src/client/Default.index.js +77 -0
- package/src/client/Itemledger.index.js +35 -0
- package/src/client/Underpost.index.js +31 -0
- package/src/client/components/core/404.js +20 -0
- package/src/client/components/core/500.js +20 -0
- package/src/client/components/core/Account.js +630 -0
- package/src/client/components/core/AgGrid.js +238 -0
- package/src/client/components/core/Alert.js +76 -0
- package/src/client/components/core/AppStore.js +69 -0
- package/src/client/components/core/Auth.js +353 -0
- package/src/client/components/core/Badge.js +26 -0
- package/src/client/components/core/Blockchain.js +41 -0
- package/src/client/components/core/Blog.js +9 -0
- package/src/client/components/core/BtnIcon.js +109 -0
- package/src/client/components/core/CalendarCore.js +437 -0
- package/src/client/components/core/Chat.js +62 -0
- package/src/client/components/core/ClientEvents.js +163 -0
- package/src/client/components/core/ColorPaletteElement.js +309 -0
- package/src/client/components/core/CommonJs.js +1014 -0
- package/src/client/components/core/Content.js +349 -0
- package/src/client/components/core/Css.js +1134 -0
- package/src/client/components/core/CssCore.js +881 -0
- package/src/client/components/core/D3Chart.js +44 -0
- package/src/client/components/core/Docs.js +478 -0
- package/src/client/components/core/DropDown.js +321 -0
- package/src/client/components/core/EventBus.js +96 -0
- package/src/client/components/core/EventsUI.js +130 -0
- package/src/client/components/core/FileExplorer.js +1406 -0
- package/src/client/components/core/FullScreen.js +201 -0
- package/src/client/components/core/Input.js +537 -0
- package/src/client/components/core/Keyboard.js +80 -0
- package/src/client/components/core/KeyboardAvoidance.js +145 -0
- package/src/client/components/core/LoadingAnimation.js +152 -0
- package/src/client/components/core/LogIn.js +212 -0
- package/src/client/components/core/LogOut.js +72 -0
- package/src/client/components/core/Logger.js +22 -0
- package/src/client/components/core/Modal.js +2956 -0
- package/src/client/components/core/NotificationManager.js +80 -0
- package/src/client/components/core/Pagination.js +252 -0
- package/src/client/components/core/Panel.js +1308 -0
- package/src/client/components/core/PanelForm.js +915 -0
- package/src/client/components/core/Polyhedron.js +947 -0
- package/src/client/components/core/PublicProfile.js +895 -0
- package/src/client/components/core/Recover.js +211 -0
- package/src/client/components/core/Responsive.js +146 -0
- package/src/client/components/core/RichText.js +33 -0
- package/src/client/components/core/Router.js +523 -0
- package/src/client/components/core/Scroll.js +76 -0
- package/src/client/components/core/SearchBox.js +1007 -0
- package/src/client/components/core/SignUp.js +153 -0
- package/src/client/components/core/SocketIo.js +163 -0
- package/src/client/components/core/SocketIoHandler.js +75 -0
- package/src/client/components/core/Stream.js +161 -0
- package/src/client/components/core/ToggleSwitch.js +89 -0
- package/src/client/components/core/ToolTip.js +78 -0
- package/src/client/components/core/Translate.js +694 -0
- package/src/client/components/core/Validator.js +140 -0
- package/src/client/components/core/VanillaJs.js +485 -0
- package/src/client/components/core/Wallet.js +95 -0
- package/src/client/components/core/WebComponent.js +44 -0
- package/src/client/components/core/Webhook.js +58 -0
- package/src/client/components/core/Worker.js +313 -0
- package/src/client/components/core/windowGetDimensions.js +269 -0
- package/src/client/components/cryptokoyn/AppShellCryptokoyn.js +352 -0
- package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
- package/src/client/components/cryptokoyn/CssCryptokoyn.js +212 -0
- package/src/client/components/cryptokoyn/LogInCryptokoyn.js +16 -0
- package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +12 -0
- package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
- package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +16 -0
- package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +11 -0
- package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +6 -0
- package/src/client/components/cyberia/ActionEngineCyberia.js +1867 -0
- package/src/client/components/cyberia/EntityEngineCyberia.js +585 -0
- package/src/client/components/cyberia/InstanceEngineCyberia.js +1088 -0
- package/src/client/components/cyberia/InstanceSelectionView.js +900 -0
- package/src/client/components/cyberia/MapEngineCyberia.js +1976 -0
- package/src/client/components/cyberia/ObjectLayerEngine.js +1540 -0
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +2420 -0
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +1522 -0
- package/src/client/components/cyberia/SharedDefaultsCyberia.js +528 -0
- package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +772 -0
- package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +254 -0
- package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +21 -0
- package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +16 -0
- package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +518 -0
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +72 -0
- package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +16 -0
- package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +13 -0
- package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +6 -0
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +48 -0
- package/src/client/components/default/AppShellDefault.js +765 -0
- package/src/client/components/default/AppStoreDefault.js +5 -0
- package/src/client/components/default/CommonDefault.js +29 -0
- package/src/client/components/default/CssDefault.js +27 -0
- package/src/client/components/default/LogInDefault.js +16 -0
- package/src/client/components/default/LogOutDefault.js +12 -0
- package/src/client/components/default/RouterDefault.js +47 -0
- package/src/client/components/default/SettingsDefault.js +16 -0
- package/src/client/components/default/SignUpDefault.js +11 -0
- package/src/client/components/default/SocketIoDefault.js +6 -0
- package/src/client/components/default/TranslateDefault.js +7 -0
- package/src/client/components/itemledger/AppShellItemledger.js +353 -0
- package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
- package/src/client/components/itemledger/CssItemledger.js +212 -0
- package/src/client/components/itemledger/LogInItemledger.js +17 -0
- package/src/client/components/itemledger/LogOutItemledger.js +12 -0
- package/src/client/components/itemledger/RouterItemledger.js +38 -0
- package/src/client/components/itemledger/SettingsItemledger.js +16 -0
- package/src/client/components/itemledger/SignUpItemledger.js +11 -0
- package/src/client/components/itemledger/SocketIoItemledger.js +6 -0
- package/src/client/components/itemledger/TranslateItemledger.js +7 -0
- package/src/client/components/underpost/AppShellUnderpost.js +691 -0
- package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
- package/src/client/components/underpost/CssUnderpost.js +281 -0
- package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +879 -0
- package/src/client/components/underpost/DocumentSearchProvider.js +448 -0
- package/src/client/components/underpost/LabGalleryUnderpost.js +79 -0
- package/src/client/components/underpost/LogInUnderpost.js +25 -0
- package/src/client/components/underpost/LogOutUnderpost.js +17 -0
- package/src/client/components/underpost/RouterUnderpost.js +45 -0
- package/src/client/components/underpost/SettingsUnderpost.js +16 -0
- package/src/client/components/underpost/SignUpUnderpost.js +11 -0
- package/src/client/components/underpost/SocketIoUnderpost.js +6 -0
- package/src/client/components/underpost/TranslateUnderpost.js +10 -0
- package/src/client/public/cryptokoyn/assets/banner/koyn-social.png +0 -0
- package/src/client/public/cryptokoyn/assets/logo/base-icon.png +0 -0
- package/src/client/public/cryptokoyn/assets/logo/cryptokoyn.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/android-chrome-144x144.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/android-chrome-192x192.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/android-chrome-256x256.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/android-chrome-36x36.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/android-chrome-48x48.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/android-chrome-72x72.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/android-chrome-96x96.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-114x114-precomposed.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-114x114.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-120x120-precomposed.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-120x120.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-144x144-precomposed.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-144x144.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-152x152-precomposed.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-152x152.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-180x180-precomposed.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-180x180.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-57x57-precomposed.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-57x57.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-60x60-precomposed.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-60x60.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-72x72-precomposed.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-72x72.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-76x76-precomposed.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-76x76.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-precomposed.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/favicon-16x16.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/favicon-32x32.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/mstile-144x144.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/mstile-150x150.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/mstile-310x150.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/mstile-310x310.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/mstile-70x70.png +0 -0
- package/src/client/public/cryptokoyn/assets/splash/safari-pinned-tab.svg +42 -0
- package/src/client/public/cryptokoyn/browserconfig.xml +12 -0
- package/src/client/public/cryptokoyn/favicon.ico +0 -0
- package/src/client/public/cryptokoyn/microdata.json +85 -0
- package/src/client/public/cryptokoyn/site.webmanifest +57 -0
- package/src/client/public/cryptokoyn/sitemap +148 -0
- package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +307 -0
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +309 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +204 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +341 -0
- package/src/client/public/cyberia-docs/CYBERIA-LORE.md +84 -0
- package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +394 -0
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +294 -0
- package/src/client/public/cyberia-docs/CYBERIA.md +259 -0
- package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +242 -0
- package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
- package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +309 -0
- package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +228 -0
- package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
- package/src/client/public/cyberia-docs/UNDERPOST-PLATFORM.md +106 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +740 -0
- package/src/client/public/default/android-chrome-144x144.png +0 -0
- package/src/client/public/default/android-chrome-192x192.png +0 -0
- package/src/client/public/default/android-chrome-256x256.png +0 -0
- package/src/client/public/default/android-chrome-36x36.png +0 -0
- package/src/client/public/default/android-chrome-384x384.png +0 -0
- package/src/client/public/default/android-chrome-48x48.png +0 -0
- package/src/client/public/default/android-chrome-512x512.png +0 -0
- package/src/client/public/default/android-chrome-72x72.png +0 -0
- package/src/client/public/default/android-chrome-96x96.png +0 -0
- package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
- package/src/client/public/default/apple-touch-icon-114x114-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
- package/src/client/public/default/apple-touch-icon-120x120-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
- package/src/client/public/default/apple-touch-icon-144x144-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
- package/src/client/public/default/apple-touch-icon-152x152-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
- package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
- package/src/client/public/default/apple-touch-icon-180x180-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
- package/src/client/public/default/apple-touch-icon-57x57-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
- package/src/client/public/default/apple-touch-icon-60x60-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
- package/src/client/public/default/apple-touch-icon-72x72-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
- package/src/client/public/default/apple-touch-icon-76x76-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
- package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
- package/src/client/public/default/assets/background/dark.jpg +0 -0
- package/src/client/public/default/assets/background/dark.svg +557 -0
- package/src/client/public/default/assets/background/white.jpg +0 -0
- package/src/client/public/default/assets/background/white0-min.jpg +0 -0
- package/src/client/public/default/assets/background/white0.jpg +0 -0
- package/src/client/public/default/assets/logo/base-icon.png +0 -0
- package/src/client/public/default/assets/logo/underpost.gif +0 -0
- package/src/client/public/default/assets/mailer/api-user-check.png +0 -0
- package/src/client/public/default/assets/mailer/api-user-default-avatar.png +0 -0
- package/src/client/public/default/assets/mailer/api-user-invalid-token.png +0 -0
- package/src/client/public/default/assets/mailer/api-user-recover.png +0 -0
- package/src/client/public/default/browserconfig.xml +12 -0
- package/src/client/public/default/favicon-16x16.png +0 -0
- package/src/client/public/default/favicon-32x32.png +0 -0
- package/src/client/public/default/favicon-48x48.png +0 -0
- package/src/client/public/default/favicon.ico +0 -0
- package/src/client/public/default/manifest.webmanifest +69 -0
- package/src/client/public/default/mstile-144x144.png +0 -0
- package/src/client/public/default/mstile-150x150.png +0 -0
- package/src/client/public/default/mstile-310x150.png +0 -0
- package/src/client/public/default/mstile-310x310.png +0 -0
- package/src/client/public/default/mstile-70x70.png +0 -0
- package/src/client/public/default/safari-pinned-tab.svg +24 -0
- package/src/client/public/default/site.webmanifest +69 -0
- package/src/client/public/default/sitemap +148 -0
- package/src/client/public/default/yandex-browser-50x50.png +0 -0
- package/src/client/public/default/yandex-browser-manifest.json +9 -0
- package/src/client/public/doc/favicon.ico +0 -0
- package/src/client/public/doc/sitemap +148 -0
- package/src/client/public/itemledger/android-chrome-144x144.png +0 -0
- package/src/client/public/itemledger/android-chrome-192x192.png +0 -0
- package/src/client/public/itemledger/android-chrome-256x256.png +0 -0
- package/src/client/public/itemledger/android-chrome-36x36.png +0 -0
- package/src/client/public/itemledger/android-chrome-384x384.png +0 -0
- package/src/client/public/itemledger/android-chrome-48x48.png +0 -0
- package/src/client/public/itemledger/android-chrome-512x512.png +0 -0
- package/src/client/public/itemledger/android-chrome-72x72.png +0 -0
- package/src/client/public/itemledger/android-chrome-96x96.png +0 -0
- package/src/client/public/itemledger/apple-touch-icon-1024x1024.png +0 -0
- package/src/client/public/itemledger/apple-touch-icon-114x114.png +0 -0
- package/src/client/public/itemledger/apple-touch-icon-120x120.png +0 -0
- package/src/client/public/itemledger/apple-touch-icon-144x144.png +0 -0
- package/src/client/public/itemledger/apple-touch-icon-152x152.png +0 -0
- package/src/client/public/itemledger/apple-touch-icon-167x167.png +0 -0
- package/src/client/public/itemledger/apple-touch-icon-180x180.png +0 -0
- package/src/client/public/itemledger/apple-touch-icon-57x57.png +0 -0
- package/src/client/public/itemledger/apple-touch-icon-60x60.png +0 -0
- package/src/client/public/itemledger/apple-touch-icon-72x72.png +0 -0
- package/src/client/public/itemledger/apple-touch-icon-76x76.png +0 -0
- package/src/client/public/itemledger/apple-touch-icon-precomposed.png +0 -0
- package/src/client/public/itemledger/apple-touch-icon.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1125x2436.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1136x640.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1170x2532.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1179x2556.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1242x2208.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1242x2688.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1284x2778.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1290x2796.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1334x750.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1488x2266.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1536x2048.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1620x2160.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1640x2160.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1668x2224.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1668x2388.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-1792x828.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2048x1536.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2048x2732.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2160x1620.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2160x1640.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2208x1242.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2224x1668.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2266x1488.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2388x1668.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2436x1125.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2532x1170.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2556x1179.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2688x1242.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2732x2048.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2778x1284.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-2796x1290.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-640x1136.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-750x1334.png +0 -0
- package/src/client/public/itemledger/apple-touch-startup-image-828x1792.png +0 -0
- package/src/client/public/itemledger/assets/logo/base-icon.png +0 -0
- package/src/client/public/itemledger/browserconfig.xml +12 -0
- package/src/client/public/itemledger/favicon-16x16.png +0 -0
- package/src/client/public/itemledger/favicon-32x32.png +0 -0
- package/src/client/public/itemledger/favicon-48x48.png +0 -0
- package/src/client/public/itemledger/favicon.ico +0 -0
- package/src/client/public/itemledger/manifest.webmanifest +69 -0
- package/src/client/public/itemledger/microdata.json +71 -0
- package/src/client/public/itemledger/mstile-144x144.png +0 -0
- package/src/client/public/itemledger/mstile-150x150.png +0 -0
- package/src/client/public/itemledger/mstile-310x150.png +0 -0
- package/src/client/public/itemledger/mstile-310x310.png +0 -0
- package/src/client/public/itemledger/mstile-70x70.png +0 -0
- package/src/client/public/itemledger/sitemap +148 -0
- package/src/client/public/itemledger/yandex-browser-50x50.png +0 -0
- package/src/client/public/itemledger/yandex-browser-manifest.json +9 -0
- package/src/client/public/test/favicon.ico +0 -0
- package/src/client/public/test/sitemap +148 -0
- package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +137 -0
- package/src/client/services/core/core.service.js +309 -0
- package/src/client/services/crypto/crypto.service.js +68 -0
- package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
- package/src/client/services/cyberia-client-hints/cyberia-client-hints.service.js +99 -0
- package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +99 -0
- package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
- package/src/client/services/cyberia-entity/cyberia-entity.service.js +99 -0
- package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +99 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +137 -0
- package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +99 -0
- package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
- package/src/client/services/cyberia-map/cyberia-map.service.js +120 -0
- package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
- package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
- package/src/client/services/cyberia-saga/cyberia-saga.service.js +99 -0
- package/src/client/services/cyberia-skill/cyberia-skill.service.js +99 -0
- package/src/client/services/default/default.management.js +1015 -0
- package/src/client/services/default/default.service.js +99 -0
- package/src/client/services/document/document.service.js +134 -0
- package/src/client/services/file/file.service.js +94 -0
- package/src/client/services/instance/instance.management.js +78 -0
- package/src/client/services/instance/instance.service.js +107 -0
- package/src/client/services/ipfs/ipfs.service.js +118 -0
- package/src/client/services/object-layer/object-layer.management.js +414 -0
- package/src/client/services/object-layer/object-layer.service.js +208 -0
- package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +99 -0
- package/src/client/services/test/test.service.js +68 -0
- package/src/client/services/user/guest.service.js +86 -0
- package/src/client/services/user/user.management.js +51 -0
- package/src/client/services/user/user.service.js +106 -0
- package/src/client/ssr/RootDocument.js +237 -0
- package/src/client/ssr/body/404.js +77 -0
- package/src/client/ssr/body/500.js +76 -0
- package/src/client/ssr/body/CacheControl.js +117 -0
- package/src/client/ssr/body/CyberiaDefaultSplashScreen.js +97 -0
- package/src/client/ssr/body/DefaultSplashScreen.js +97 -0
- package/src/client/ssr/body/SwaggerDarkMode.js +285 -0
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +90 -0
- package/src/client/ssr/head/CryptokoynScripts.js +4 -0
- package/src/client/ssr/head/Css.js +241 -0
- package/src/client/ssr/head/CyberiaPortalScripts.js +6 -0
- package/src/client/ssr/head/DefaultScripts.js +6 -0
- package/src/client/ssr/head/ItemledgerScripts.js +4 -0
- package/src/client/ssr/head/Microdata.js +11 -0
- package/src/client/ssr/head/Production.js +1 -0
- package/src/client/ssr/head/Pwa.js +146 -0
- package/src/client/ssr/head/PwaItemledger.js +197 -0
- package/src/client/ssr/head/Seo.js +15 -0
- package/src/client/ssr/head/UnderpostScripts.js +6 -0
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +20 -0
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +16 -0
- package/src/client/ssr/views/Cyberia404.js +328 -0
- package/src/client/ssr/views/CyberiaServerMetrics.js +1070 -0
- package/src/client/ssr/views/Maintenance.js +64 -0
- package/src/client/ssr/views/NoNetworkConnection.js +68 -0
- package/src/client/ssr/views/Test.js +199 -0
- package/src/client/sw/core.sw.js +274 -0
- package/src/client-builder/client-build-docs.js +493 -0
- package/src/client-builder/client-build-live.js +100 -0
- package/src/client-builder/client-build.js +1092 -0
- package/src/client-builder/client-dev-server.js +88 -0
- package/src/client-builder/client-formatted.js +170 -0
- package/src/client-builder/client-icons.js +108 -0
- package/src/client-builder/ssr.js +124 -0
- package/src/client.build.js +17 -0
- package/src/client.dev.js +21 -0
- package/src/db/DataBaseProvider.js +213 -0
- package/src/db/mariadb/MariaDB.js +72 -0
- package/src/db/mongo/MongoBootstrap.js +657 -0
- package/src/db/mongo/MongooseDB.js +199 -0
- package/src/grpc/cyberia/grpc-server.js +162 -0
- package/src/index.js +357 -0
- package/src/mailer/EmailRender.js +116 -0
- package/src/mailer/MailerProvider.js +213 -0
- package/src/projects/cyberia/atlas-sprite-sheet-generator.js +413 -0
- package/src/projects/cyberia/besu-genesis-generator.js +1630 -0
- package/src/projects/cyberia/catalog-cyberia.js +90 -0
- package/src/projects/cyberia/gemini-client.js +175 -0
- package/src/projects/cyberia/generate-saga.js +2137 -0
- package/src/projects/cyberia/hot-reload-trigger.js +163 -0
- package/src/projects/cyberia/instance-data.js +719 -0
- package/src/projects/cyberia/ipfs-client.js +599 -0
- package/src/projects/cyberia/map-preview-generator.js +304 -0
- package/src/projects/cyberia/object-layer.js +978 -0
- package/src/projects/cyberia/semantic-layer-generator-floor.js +319 -0
- package/src/projects/cyberia/semantic-layer-generator-resource.js +259 -0
- package/src/projects/cyberia/semantic-layer-generator-skin.js +1164 -0
- package/src/projects/cyberia/semantic-layer-generator.js +753 -0
- package/src/projects/cyberia/shape-generator.js +1060 -0
- package/src/projects/underpost/catalog-underpost.js +60 -0
- package/src/proxy.js +19 -0
- package/src/runtime/cyberia-client/Dockerfile +49 -0
- package/src/runtime/cyberia-client/Dockerfile.dev +75 -0
- package/src/runtime/cyberia-server/Dockerfile +43 -0
- package/src/runtime/cyberia-server/Dockerfile.dev +56 -0
- package/src/runtime/engine-cyberia/Dockerfile +161 -0
- package/src/runtime/engine-cyberia/Dockerfile.dev +161 -0
- package/src/runtime/engine-cyberia/Dockerfile.test +165 -0
- package/src/runtime/engine-cyberia/compose.env +144 -0
- package/src/runtime/engine-cyberia/docker-compose.yml +434 -0
- package/src/runtime/engine-cyberia/ipfs/configure-ipfs.sh +13 -0
- package/src/runtime/engine-cyberia/mongodb/entrypoint.sh +76 -0
- package/src/runtime/engine-cyberia/nginx.conf +128 -0
- package/src/runtime/express/Dockerfile +45 -0
- package/src/runtime/express/Express.js +285 -0
- package/src/runtime/lampp/Dockerfile +62 -0
- package/src/runtime/lampp/Lampp.js +359 -0
- package/src/runtime/nginx/Nginx.js +250 -0
- package/src/runtime/wp/Dockerfile +62 -0
- package/src/runtime/wp/Wp.js +642 -0
- package/src/server/auth.js +713 -0
- package/src/server/backup.js +102 -0
- package/src/server/catalog.js +72 -0
- package/src/server/conf.js +2316 -0
- package/src/server/cron.js +476 -0
- package/src/server/crypto.js +210 -0
- package/src/server/data-query.js +461 -0
- package/src/server/dns.js +553 -0
- package/src/server/downloader.js +73 -0
- package/src/server/logger.js +229 -0
- package/src/server/middlewares.js +152 -0
- package/src/server/peer.js +75 -0
- package/src/server/process.js +299 -0
- package/src/server/proxy.js +139 -0
- package/src/server/runtime-status.js +252 -0
- package/src/server/runtime.js +183 -0
- package/src/server/start.js +272 -0
- package/src/server/tls.js +254 -0
- package/src/server/valkey.js +201 -0
- package/src/server.js +25 -0
- package/src/ws/IoInterface.js +129 -0
- package/src/ws/IoServer.js +68 -0
- package/src/ws/core/channels/core.ws.chat.js +68 -0
- package/src/ws/core/channels/core.ws.mailer.js +116 -0
- package/src/ws/core/channels/core.ws.stream.js +90 -0
- package/src/ws/core/core.ws.connection.js +41 -0
- package/src/ws/core/core.ws.emit.js +37 -0
- package/src/ws/core/core.ws.server.js +44 -0
- package/src/ws/default/channels/default.ws.main.js +57 -0
- package/src/ws/default/default.ws.connection.js +35 -0
- package/src/ws/default/default.ws.emit.js +14 -0
- package/src/ws/default/default.ws.server.js +39 -0
- package/test/api.test.js +53 -0
- package/test/crypto.test.js +117 -0
- package/test/cyberia-instance-conf-defaults.test.js +140 -0
- package/test/deploy-monitor.test.js +267 -0
- package/test/shape-generator.test.js +463 -0
- package/tsconfig.docs.json +15 -0
- package/typedoc.dd-cyberia.json +31 -0
- package/typedoc.json +31 -0
|
@@ -0,0 +1,894 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Object Layer service module for handling CRUD operations on object layer assets.
|
|
3
|
+
* Provides REST API handlers for creating, reading, updating, and deleting object layers
|
|
4
|
+
* including frame image management, metadata processing, and WebP animation generation.
|
|
5
|
+
*
|
|
6
|
+
* Delegates shared object layer creation and update logic to {@link ObjectLayerEngine} in
|
|
7
|
+
* `src/projects/cyberia/object-layer.js` to keep a single source of truth shared with the Cyberia CLI.
|
|
8
|
+
*
|
|
9
|
+
* @module src/api/object-layer/object-layer.service.js
|
|
10
|
+
* @namespace CyberiaObjectLayerService
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
|
|
14
|
+
import { loggerFactory } from '../../server/logger.js';
|
|
15
|
+
import { ObjectLayerRenderFramesDto } from '../object-layer-render-frames/object-layer-render-frames.model.js';
|
|
16
|
+
import { FileFactory } from '../file/file.service.js';
|
|
17
|
+
import fs from 'fs-extra';
|
|
18
|
+
import { ObjectLayerDto } from './object-layer.model.js';
|
|
19
|
+
import { ObjectLayerEngine } from '../../projects/cyberia/object-layer.js';
|
|
20
|
+
import { shellExec } from '../../server/process.js';
|
|
21
|
+
import { DataQuery } from '../../server/data-query.js';
|
|
22
|
+
import { AtlasSpriteSheetService } from '../atlas-sprite-sheet/atlas-sprite-sheet.service.js';
|
|
23
|
+
import { IpfsClient } from '../../projects/cyberia/ipfs-client.js';
|
|
24
|
+
import { createPinRecord, removePinRecordsAndUnpin } from '../ipfs/ipfs.service.js';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Logger instance for this module.
|
|
28
|
+
* @type {Function}
|
|
29
|
+
* @memberof CyberiaObjectLayerService
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
32
|
+
const logger = loggerFactory(import.meta);
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Object Layer Service providing REST API handlers for object layer operations.
|
|
36
|
+
* @namespace CyberiaObjectLayerService.ObjectLayerService
|
|
37
|
+
* @memberof CyberiaObjectLayerService
|
|
38
|
+
*/
|
|
39
|
+
class ObjectLayerService {
|
|
40
|
+
/**
|
|
41
|
+
* POST handler for creating object layers and uploading frame images.
|
|
42
|
+
*
|
|
43
|
+
* Supports three sub-routes:
|
|
44
|
+
* - `/frame-image/:itemType/:itemId/:directionCode` — Upload PNG frame images for a direction.
|
|
45
|
+
* - `/metadata/:itemType/:itemId` — Create an object layer from uploaded frames and metadata.
|
|
46
|
+
* - Default — Create an object layer directly from the request body.
|
|
47
|
+
*
|
|
48
|
+
* The `/metadata` and default routes delegate to {@link ObjectLayerEngine.createObjectLayerDocuments}
|
|
49
|
+
* for document creation, atlas generation, SHA-256 computation, and IPFS pinning.
|
|
50
|
+
*
|
|
51
|
+
* @async
|
|
52
|
+
* @function post
|
|
53
|
+
* @memberof CyberiaObjectLayerService.ObjectLayerService
|
|
54
|
+
* @param {Object} req - Express request object.
|
|
55
|
+
* @param {Object} res - Express response object.
|
|
56
|
+
* @param {Object} options - Server options containing host and path.
|
|
57
|
+
* @param {string} options.host - The deployment host.
|
|
58
|
+
* @param {string} options.path - The deployment path.
|
|
59
|
+
* @returns {Promise<Object>} The created object layer document or frame upload result.
|
|
60
|
+
* @throws {Error} If file validation fails or required parameters are missing.
|
|
61
|
+
*/
|
|
62
|
+
static post = async (req, res, options) => {
|
|
63
|
+
/** @type {import('./object-layer.model.js').ObjectLayerModel} */
|
|
64
|
+
|
|
65
|
+
if (req.path.startsWith('/frame-image')) {
|
|
66
|
+
const itemType = req.params.itemType;
|
|
67
|
+
const itemId = req.params.itemId;
|
|
68
|
+
const directionCode = req.params.directionCode;
|
|
69
|
+
|
|
70
|
+
// Debug: Log request files structure
|
|
71
|
+
logger.info(`POST Request files for direction ${directionCode}:`, {
|
|
72
|
+
filesKeys: req.files ? Object.keys(req.files) : [],
|
|
73
|
+
filesCount: req.files ? Object.keys(req.files).length : 0,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Extract all frames for this direction
|
|
77
|
+
const files = FileFactory.filesExtract(req);
|
|
78
|
+
|
|
79
|
+
// Allow empty files to remove all frames from direction
|
|
80
|
+
if (!files || files.length === 0) {
|
|
81
|
+
logger.info(`No files received for direction ${directionCode} - will remove all frames from this direction`);
|
|
82
|
+
} else {
|
|
83
|
+
// Validate each file has data
|
|
84
|
+
for (let i = 0; i < files.length; i++) {
|
|
85
|
+
if (!files[i].data) {
|
|
86
|
+
logger.error(`File ${files[i].name || i} has no data for direction ${directionCode}`);
|
|
87
|
+
throw new Error(`File ${files[i].name || i} has no data`);
|
|
88
|
+
}
|
|
89
|
+
if (!Buffer.isBuffer(files[i].data)) {
|
|
90
|
+
logger.error(`File ${files[i].name || i} data is not a Buffer for direction ${directionCode}`);
|
|
91
|
+
throw new Error(`File ${files[i].name || i} data is not a Buffer`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
logger.info(
|
|
97
|
+
`Processing ${files?.length || 0} file(s) for direction ${directionCode}: ${files?.map((f) => f.name).join(', ') || 'none'}`,
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// Always clear and rewrite ALL frames for this direction code
|
|
101
|
+
for (const basePath of ['./src/client/public/cyberia/', `./public/${options.host}${options.path}`]) {
|
|
102
|
+
const folder = `${basePath}assets/${itemType}/${itemId}/${directionCode}`;
|
|
103
|
+
|
|
104
|
+
// Always remove entire direction folder to ensure clean state
|
|
105
|
+
if (fs.existsSync(folder)) {
|
|
106
|
+
await fs.remove(folder);
|
|
107
|
+
logger.info(`Cleared folder: ${folder}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Only create and write files if we have frames to upload
|
|
111
|
+
if (files && files.length > 0) {
|
|
112
|
+
// Create fresh folder
|
|
113
|
+
fs.mkdirSync(folder, { recursive: true });
|
|
114
|
+
|
|
115
|
+
// Write all frames sent in this request
|
|
116
|
+
for (const file of files) {
|
|
117
|
+
const filePath = `${folder}/${file.name}`;
|
|
118
|
+
try {
|
|
119
|
+
fs.writeFileSync(filePath, file.data);
|
|
120
|
+
logger.info(`Wrote file: ${filePath} (${file.data.length} bytes)`);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
logger.error(`Error writing file ${filePath}:`, error);
|
|
123
|
+
throw new Error(`Failed to write ${file.name}: ${error.message}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
logger.info(`No frames to write for direction ${directionCode} - folder removed`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
logger.info(`Successfully processed ${files?.length || 0} frame(s) for direction ${directionCode}`);
|
|
132
|
+
|
|
133
|
+
return { success: true, directionCode, frameCount: files?.length || 0 };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (req.path.startsWith('/metadata')) {
|
|
137
|
+
const itemType = req.params.itemType;
|
|
138
|
+
const itemId = req.params.itemId;
|
|
139
|
+
const folder = `./src/client/public/cyberia/assets/${itemType}/${itemId}`;
|
|
140
|
+
const publicFolder = `./public/${options.host}${options.path}/assets/${itemType}/${itemId}`;
|
|
141
|
+
|
|
142
|
+
// Ensure both folders exist
|
|
143
|
+
if (!fs.existsSync(folder)) fs.mkdirSync(folder, { recursive: true });
|
|
144
|
+
if (!fs.existsSync(publicFolder)) fs.mkdirSync(publicFolder, { recursive: true });
|
|
145
|
+
|
|
146
|
+
// Write metadata.json to both locations
|
|
147
|
+
const metadataContent = JSON.stringify(req.body);
|
|
148
|
+
fs.writeFileSync(`${folder}/metadata.json`, metadataContent);
|
|
149
|
+
fs.writeFileSync(`${publicFolder}/metadata.json`, metadataContent);
|
|
150
|
+
|
|
151
|
+
// Build object layer data from the asset directory
|
|
152
|
+
const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
|
|
153
|
+
const ObjectLayerRenderFrames = DataBaseProviderService.getModel('ObjectLayerRenderFrames', options);
|
|
154
|
+
|
|
155
|
+
const { objectLayerRenderFramesData, objectLayerData } =
|
|
156
|
+
await ObjectLayerEngine.buildObjectLayerDataFromDirectory({
|
|
157
|
+
folder,
|
|
158
|
+
objectLayerType: itemType,
|
|
159
|
+
objectLayerId: itemId,
|
|
160
|
+
metadataOverride: req.body,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const { objectLayer } = await ObjectLayerEngine.createObjectLayerDocuments({
|
|
164
|
+
ObjectLayer,
|
|
165
|
+
ObjectLayerRenderFrames,
|
|
166
|
+
objectLayerRenderFramesData,
|
|
167
|
+
objectLayerData,
|
|
168
|
+
createOptions: {
|
|
169
|
+
generateAtlas: true,
|
|
170
|
+
atlasServiceContext: {
|
|
171
|
+
req,
|
|
172
|
+
res,
|
|
173
|
+
options,
|
|
174
|
+
AtlasSpriteSheetService,
|
|
175
|
+
IpfsClient,
|
|
176
|
+
createPinRecord,
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
return objectLayer;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// create object layer from body – cut-over consistency: stage all CIDs before writing to DB
|
|
185
|
+
const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
|
|
186
|
+
const ObjectLayerRenderFrames = DataBaseProviderService.getModel('ObjectLayerRenderFrames', options);
|
|
187
|
+
|
|
188
|
+
const bodyData = { ...req.body };
|
|
189
|
+
if (!bodyData.data) bodyData.data = {};
|
|
190
|
+
if (!bodyData.data.render) bodyData.data.render = {};
|
|
191
|
+
bodyData.data.render.cid = '';
|
|
192
|
+
bodyData.data.render.metadataCid = '';
|
|
193
|
+
|
|
194
|
+
// If has render frames, generate atlas + CIDs BEFORE creating the ObjectLayer
|
|
195
|
+
if (bodyData.objectLayerRenderFramesId) {
|
|
196
|
+
const renderFramesDoc = await ObjectLayerRenderFrames.findById(bodyData.objectLayerRenderFramesId);
|
|
197
|
+
if (renderFramesDoc) {
|
|
198
|
+
try {
|
|
199
|
+
const stagingOL = {
|
|
200
|
+
data: bodyData.data,
|
|
201
|
+
objectLayerRenderFramesId: renderFramesDoc,
|
|
202
|
+
};
|
|
203
|
+
const result = await AtlasSpriteSheetService.generate(
|
|
204
|
+
{ objectLayer: stagingOL, auth: req.auth },
|
|
205
|
+
res,
|
|
206
|
+
options,
|
|
207
|
+
{ skipObjectLayerSave: true },
|
|
208
|
+
);
|
|
209
|
+
bodyData.data.render.cid = result.atlasCid;
|
|
210
|
+
bodyData.data.render.metadataCid = result.atlasMetadataCid;
|
|
211
|
+
bodyData.atlasSpriteSheetId = result.atlasDoc._id;
|
|
212
|
+
} catch (atlasError) {
|
|
213
|
+
logger.error('Failed to auto-generate atlas for new ObjectLayer:', atlasError);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Compute final SHA-256 with all CIDs
|
|
219
|
+
bodyData.sha256 = ObjectLayerEngine.computeSha256(bodyData.data);
|
|
220
|
+
|
|
221
|
+
// Pin data JSON to IPFS
|
|
222
|
+
try {
|
|
223
|
+
const itemId = bodyData.data.item.id;
|
|
224
|
+
const mfsPath = `/object-layer/${itemId}/${itemId}_data.json`;
|
|
225
|
+
const ipfsResult = await IpfsClient.addJsonToIpfs(bodyData.data, `${itemId}_data.json`, mfsPath);
|
|
226
|
+
if (ipfsResult) {
|
|
227
|
+
bodyData.cid = ipfsResult.cid;
|
|
228
|
+
await createPinRecord({ cid: ipfsResult.cid, resourceType: 'object-layer-data', mfsPath, options });
|
|
229
|
+
}
|
|
230
|
+
} catch (ipfsError) {
|
|
231
|
+
logger.warn('Failed to pin data JSON to IPFS:', ipfsError.message);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Atomic create/replace – ObjectLayer is fully populated with all CIDs
|
|
235
|
+
let newObjectLayer;
|
|
236
|
+
const existingByItemId = await ObjectLayer.findOne({ 'data.item.id': bodyData.data.item.id });
|
|
237
|
+
if (existingByItemId) {
|
|
238
|
+
newObjectLayer = await ObjectLayer.findByIdAndUpdate(existingByItemId._id, bodyData, {
|
|
239
|
+
returnDocument: 'after',
|
|
240
|
+
}).populate('objectLayerRenderFramesId');
|
|
241
|
+
} else {
|
|
242
|
+
newObjectLayer = await (await new ObjectLayer(bodyData).save()).populate('objectLayerRenderFramesId');
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return newObjectLayer;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* GET handler for retrieving object layers.
|
|
250
|
+
*
|
|
251
|
+
* Supports multiple sub-routes:
|
|
252
|
+
* - `/frame-counts/:id` — Get frame counts for each direction using numeric codes.
|
|
253
|
+
* - `/render/:id` — Get only render data (populated ObjectLayerRenderFrames) for a specific object layer.
|
|
254
|
+
* - `/metadata/:id` — Get metadata (no full render frames/colors) with atlas sprite sheet validation.
|
|
255
|
+
* - `/:id` — Get a single object layer by ID.
|
|
256
|
+
* - `/` — Get a paginated list of object layers.
|
|
257
|
+
*
|
|
258
|
+
* @async
|
|
259
|
+
* @function get
|
|
260
|
+
* @memberof CyberiaObjectLayerService.ObjectLayerService
|
|
261
|
+
* @param {Object} req - Express request object.
|
|
262
|
+
* @param {Object} res - Express response object.
|
|
263
|
+
* @param {Object} options - Server options containing host and path.
|
|
264
|
+
* @param {string} options.host - The deployment host.
|
|
265
|
+
* @param {string} options.path - The deployment path.
|
|
266
|
+
* @returns {Promise<Object>} The requested object layer data, list, or frame counts.
|
|
267
|
+
* @throws {Error} If the requested object layer is not found.
|
|
268
|
+
*/
|
|
269
|
+
static get = async (req, res, options) => {
|
|
270
|
+
/** @type {import('./object-layer.model.js').ObjectLayerModel} */
|
|
271
|
+
const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
|
|
272
|
+
|
|
273
|
+
// GET /search-item-ids?q=<partial> - Fast partial match search on data.item.id
|
|
274
|
+
if (req.path.startsWith('/search-item-ids')) {
|
|
275
|
+
const q = (req.query.q || '').trim();
|
|
276
|
+
if (!q) return { itemIds: [] };
|
|
277
|
+
// Escape regex special characters for safe partial matching
|
|
278
|
+
const escaped = q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
279
|
+
const results = await ObjectLayer.find(
|
|
280
|
+
{ 'data.item.id': { $regex: escaped, $options: 'i' } },
|
|
281
|
+
{ 'data.item.id': 1, _id: 0 },
|
|
282
|
+
)
|
|
283
|
+
.limit(20)
|
|
284
|
+
.lean();
|
|
285
|
+
const itemIds = [...new Set(results.map((r) => r.data.item.id))];
|
|
286
|
+
return { itemIds };
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// GET /frame-counts/:id - Get frame counts for each direction using numeric codes
|
|
290
|
+
if (req.path.startsWith('/frame-counts/')) {
|
|
291
|
+
const objectLayer = await ObjectLayer.findById(req.params.id)
|
|
292
|
+
.select(ObjectLayerDto.select.getMetadata())
|
|
293
|
+
.populate('objectLayerRenderFramesId');
|
|
294
|
+
if (!objectLayer) {
|
|
295
|
+
throw new Error('ObjectLayer not found');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const itemType = objectLayer.data.item.type;
|
|
299
|
+
const itemId = objectLayer.data.item.id;
|
|
300
|
+
const frameCounts = {};
|
|
301
|
+
|
|
302
|
+
// Define numeric direction codes (as used in file system)
|
|
303
|
+
const numericDirectionCodes = ['08', '18', '02', '12', '04', '14', '06', '16'];
|
|
304
|
+
|
|
305
|
+
// Check each numeric direction code folder and count PNG files
|
|
306
|
+
for (const numericCode of numericDirectionCodes) {
|
|
307
|
+
const folder = `./src/client/public/cyberia/assets/${itemType}/${itemId}/${numericCode}`;
|
|
308
|
+
|
|
309
|
+
if (fs.existsSync(folder)) {
|
|
310
|
+
try {
|
|
311
|
+
const files = await fs.readdir(folder);
|
|
312
|
+
const pngFiles = files.filter((file) => file.endsWith('.png'));
|
|
313
|
+
frameCounts[numericCode] = pngFiles.length;
|
|
314
|
+
} catch (error) {
|
|
315
|
+
logger.warn(`Error reading folder ${folder}:`, error);
|
|
316
|
+
frameCounts[numericCode] = 0;
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
frameCounts[numericCode] = 0;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return {
|
|
324
|
+
_id: objectLayer._id,
|
|
325
|
+
itemType,
|
|
326
|
+
itemId,
|
|
327
|
+
frameDuration: objectLayer.objectLayerRenderFramesId?.frame_duration || 250,
|
|
328
|
+
frameCounts,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// GET /render/:id - Get only render data for specific object layer
|
|
333
|
+
if (req.path.startsWith('/render/')) {
|
|
334
|
+
const objectLayer = await ObjectLayer.findById(req.params.id)
|
|
335
|
+
.select(ObjectLayerDto.select.getRender())
|
|
336
|
+
.populate('objectLayerRenderFramesId');
|
|
337
|
+
if (!objectLayer) {
|
|
338
|
+
throw new Error('ObjectLayer not found');
|
|
339
|
+
}
|
|
340
|
+
// Return the populated render frames data with consistent naming
|
|
341
|
+
return {
|
|
342
|
+
_id: objectLayer._id,
|
|
343
|
+
objectLayerRenderFramesId: objectLayer.objectLayerRenderFramesId,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// GET /metadata/:id - Get only metadata (no render frames/colors) for specific object layer
|
|
348
|
+
if (req.path.startsWith('/metadata/')) {
|
|
349
|
+
const objectLayer = await ObjectLayer.findById(req.params.id)
|
|
350
|
+
.select(ObjectLayerDto.select.getMetadata())
|
|
351
|
+
.populate('objectLayerRenderFramesId', ObjectLayerRenderFramesDto.select.get());
|
|
352
|
+
if (!objectLayer) {
|
|
353
|
+
throw new Error('ObjectLayer not found');
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// If object layer references an atlas sprite sheet, validate that the atlas and its file actually exist.
|
|
357
|
+
// If the atlas or its file is missing, clear the reference so the UI can offer to generate a new atlas.
|
|
358
|
+
if (objectLayer.atlasSpriteSheetId) {
|
|
359
|
+
try {
|
|
360
|
+
const AtlasSpriteSheet = DataBaseProviderService.getModel('AtlasSpriteSheet', options);
|
|
361
|
+
const File = DataBaseProviderService.getModel('File', options);
|
|
362
|
+
|
|
363
|
+
const atlasDoc = await AtlasSpriteSheet.findById(objectLayer.atlasSpriteSheetId);
|
|
364
|
+
|
|
365
|
+
// If the atlas doc is gone, clear the reference
|
|
366
|
+
if (!atlasDoc) {
|
|
367
|
+
logger.warn(
|
|
368
|
+
`ObjectLayer ${objectLayer._id} referenced missing AtlasSpriteSheet ${objectLayer.atlasSpriteSheetId} - clearing reference`,
|
|
369
|
+
);
|
|
370
|
+
objectLayer.atlasSpriteSheetId = undefined;
|
|
371
|
+
await objectLayer.save();
|
|
372
|
+
} else if (!atlasDoc.fileId) {
|
|
373
|
+
// Atlas exists but has no fileId - remove atlas and clear reference
|
|
374
|
+
logger.warn(
|
|
375
|
+
`AtlasSpriteSheet ${atlasDoc._id} has no fileId - deleting atlas and clearing ObjectLayer reference`,
|
|
376
|
+
);
|
|
377
|
+
await AtlasSpriteSheet.findByIdAndDelete(atlasDoc._id);
|
|
378
|
+
objectLayer.atlasSpriteSheetId = undefined;
|
|
379
|
+
await objectLayer.save();
|
|
380
|
+
} else {
|
|
381
|
+
// Atlas has a fileId - verify the File exists
|
|
382
|
+
const fileDoc = await File.findById(atlasDoc.fileId);
|
|
383
|
+
if (!fileDoc) {
|
|
384
|
+
logger.warn(
|
|
385
|
+
`AtlasSpriteSheet ${atlasDoc._id} references missing File ${atlasDoc.fileId} - deleting atlas and clearing reference on ObjectLayer ${objectLayer._id}`,
|
|
386
|
+
);
|
|
387
|
+
await AtlasSpriteSheet.findByIdAndDelete(atlasDoc._id);
|
|
388
|
+
objectLayer.atlasSpriteSheetId = undefined;
|
|
389
|
+
await objectLayer.save();
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
} catch (err) {
|
|
393
|
+
logger.warn('Error validating atlas sprite sheet reference:', err);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return objectLayer;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// GET / - Get paginated list of object layers
|
|
401
|
+
const id = req.params.id || req.query.id;
|
|
402
|
+
logger.info(`ObjectLayerService.get - filtering check - id: ${id}`);
|
|
403
|
+
if (id && id !== 'undefined' && !['render', 'metadata', 'frame-counts'].includes(id)) {
|
|
404
|
+
try {
|
|
405
|
+
const objectLayer = await ObjectLayer.findById(id)
|
|
406
|
+
.select(ObjectLayerDto.select.get())
|
|
407
|
+
.populate('atlasSpriteSheetId', 'cid')
|
|
408
|
+
.populate('objectLayerRenderFramesId', ObjectLayerRenderFramesDto.select.get());
|
|
409
|
+
if (objectLayer) {
|
|
410
|
+
logger.info(`ObjectLayerService.get - found record by id: ${id}`);
|
|
411
|
+
return { data: [objectLayer], total: 1, page: 1, totalPages: 1 };
|
|
412
|
+
}
|
|
413
|
+
logger.warn(`ObjectLayerService.get - record NOT found for id: ${id}`);
|
|
414
|
+
} catch (e) {
|
|
415
|
+
logger.warn(`Invalid ID format or not found: ${id}`);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const { query, sort, skip, limit, page } = DataQuery.parse(req.query);
|
|
420
|
+
|
|
421
|
+
const [data, total] = await Promise.all([
|
|
422
|
+
ObjectLayer.find(query) // { userId: req.auth.user._id }
|
|
423
|
+
.sort(sort)
|
|
424
|
+
.limit(limit)
|
|
425
|
+
.skip(skip)
|
|
426
|
+
.select(ObjectLayerDto.select.get())
|
|
427
|
+
.populate('atlasSpriteSheetId', 'cid')
|
|
428
|
+
.populate('objectLayerRenderFramesId', ObjectLayerRenderFramesDto.select.get()),
|
|
429
|
+
ObjectLayer.countDocuments(query), // { userId: req.auth.user._id }
|
|
430
|
+
]);
|
|
431
|
+
return { data, total, page, totalPages: Math.ceil(total / limit) };
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Generates a WebP animation from PNG frame images for a specific direction of an object layer.
|
|
436
|
+
* Uses the `img2webp` CLI tool to assemble the animation.
|
|
437
|
+
*
|
|
438
|
+
* @async
|
|
439
|
+
* @function generateWebp
|
|
440
|
+
* @memberof CyberiaObjectLayerService.ObjectLayerService
|
|
441
|
+
* @param {Object} req - Express request object with params: itemType, itemId, directionCode.
|
|
442
|
+
* @param {Object} res - Express response object.
|
|
443
|
+
* @param {Object} options - Server options containing host and path.
|
|
444
|
+
* @param {string} options.host - The deployment host.
|
|
445
|
+
* @param {string} options.path - The deployment path.
|
|
446
|
+
* @returns {Promise<Buffer>} The generated WebP animation as a Buffer.
|
|
447
|
+
* @throws {Error} If required parameters are missing, frames directory is not found, or img2webp fails.
|
|
448
|
+
*/
|
|
449
|
+
static generateWebp = async (req, res, options) => {
|
|
450
|
+
/** @type {import('./object-layer.model.js').ObjectLayerModel} */
|
|
451
|
+
const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
|
|
452
|
+
|
|
453
|
+
// GET /generate-webp/:itemType/:itemId/:directionCode - Generate webp animation from PNG frames
|
|
454
|
+
const itemType = req.params.itemType;
|
|
455
|
+
const itemId = req.params.itemId;
|
|
456
|
+
const directionCode = req.params.directionCode;
|
|
457
|
+
|
|
458
|
+
if (!itemType || !itemId || !directionCode) {
|
|
459
|
+
throw new Error('Missing required parameters: itemType, itemId, directionCode');
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Path to the PNG frames directory
|
|
463
|
+
const framesFolder = `./src/client/public/cyberia/assets/${itemType}/${itemId}/${directionCode}`;
|
|
464
|
+
|
|
465
|
+
// Check if the folder exists
|
|
466
|
+
if (!fs.existsSync(framesFolder)) {
|
|
467
|
+
throw new Error(`Frames directory not found: ${framesFolder}`);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// Check if there are PNG files in the directory
|
|
471
|
+
const files = await fs.readdir(framesFolder);
|
|
472
|
+
const pngFiles = files.filter((file) => file.endsWith('.png')).sort();
|
|
473
|
+
|
|
474
|
+
if (pngFiles.length === 0) {
|
|
475
|
+
throw new Error(`No PNG frames found in directory: ${framesFolder}`);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
logger.info(`Found ${pngFiles.length} PNG frames in ${framesFolder}`);
|
|
479
|
+
|
|
480
|
+
// Get frame duration from the object layer metadata
|
|
481
|
+
let frameDuration = 100; // Default to 100ms
|
|
482
|
+
|
|
483
|
+
try {
|
|
484
|
+
// Find object layer by itemType and itemId
|
|
485
|
+
const objectLayer = await ObjectLayer.findOne({
|
|
486
|
+
'data.item.type': itemType,
|
|
487
|
+
'data.item.id': itemId,
|
|
488
|
+
})
|
|
489
|
+
.select(ObjectLayerDto.select.getMetadata())
|
|
490
|
+
.populate('objectLayerRenderFramesId');
|
|
491
|
+
|
|
492
|
+
if (objectLayer && objectLayer.objectLayerRenderFramesId?.frame_duration) {
|
|
493
|
+
frameDuration = objectLayer.objectLayerRenderFramesId.frame_duration;
|
|
494
|
+
logger.info(`Using frame duration from object layer: ${frameDuration}ms`);
|
|
495
|
+
} else {
|
|
496
|
+
logger.warn(`Object layer not found or no frame_duration set, using default: ${frameDuration}ms`);
|
|
497
|
+
}
|
|
498
|
+
} catch (error) {
|
|
499
|
+
logger.warn(
|
|
500
|
+
`Error fetching object layer metadata: ${error.message}. Using default frame duration: ${frameDuration}ms`,
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
const tmpOutputFileName = `output_${Date.now()}_${Math.floor(Math.random() * 1000)}.webp`;
|
|
505
|
+
|
|
506
|
+
// Create temporary output file path
|
|
507
|
+
const tempOutputPath = `${framesFolder}/${tmpOutputFileName}`;
|
|
508
|
+
|
|
509
|
+
try {
|
|
510
|
+
// Change to the frames directory and execute img2webp command
|
|
511
|
+
const cmd = `cd "${framesFolder}" && img2webp -d ${frameDuration} -loop 0 *.png -o ${tmpOutputFileName}`;
|
|
512
|
+
|
|
513
|
+
logger.info(`Executing command: ${cmd}`);
|
|
514
|
+
|
|
515
|
+
// silentOnError so we can build a domain-specific Error with the
|
|
516
|
+
// captured stderr/stdout context (callers want a friendly message,
|
|
517
|
+
// not a generic ShellExecError).
|
|
518
|
+
const result = shellExec(cmd, { silent: false, silentOnError: true });
|
|
519
|
+
|
|
520
|
+
if (result.code !== 0) {
|
|
521
|
+
throw new Error(`img2webp command failed: ${result.stderr || result.stdout}`);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
logger.info(`Successfully generated webp: ${tempOutputPath}`);
|
|
525
|
+
|
|
526
|
+
// Check if the output file was created
|
|
527
|
+
if (!fs.existsSync(tempOutputPath)) {
|
|
528
|
+
throw new Error(`Output file was not created: ${tempOutputPath}`);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// Read the webp file as a buffer
|
|
532
|
+
const webpBuffer = await fs.readFile(tempOutputPath);
|
|
533
|
+
|
|
534
|
+
logger.info(`WebP file size: ${webpBuffer.length} bytes`);
|
|
535
|
+
|
|
536
|
+
// Delete the temporary file after sending the response
|
|
537
|
+
// Use setImmediate to ensure the response is fully sent before cleanup
|
|
538
|
+
setImmediate(async () => {
|
|
539
|
+
try {
|
|
540
|
+
if (fs.existsSync(tempOutputPath)) {
|
|
541
|
+
await fs.remove(tempOutputPath);
|
|
542
|
+
logger.info(`Cleaned up temporary file: ${tempOutputPath}`);
|
|
543
|
+
}
|
|
544
|
+
} catch (cleanupError) {
|
|
545
|
+
logger.error(`Error cleaning up temporary file: ${cleanupError.message}`);
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
return webpBuffer;
|
|
550
|
+
} catch (error) {
|
|
551
|
+
// Clean up on error
|
|
552
|
+
try {
|
|
553
|
+
if (fs.existsSync(tempOutputPath)) {
|
|
554
|
+
await fs.remove(tempOutputPath);
|
|
555
|
+
logger.info(`Cleaned up temporary file after error: ${tempOutputPath}`);
|
|
556
|
+
}
|
|
557
|
+
} catch (cleanupError) {
|
|
558
|
+
logger.error(`Error cleaning up temporary file after error: ${cleanupError.message}`);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
throw error;
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* PUT handler for updating object layers, their frame images, and metadata.
|
|
567
|
+
*
|
|
568
|
+
* Supports three sub-routes:
|
|
569
|
+
* - `/:id/frame-image/:itemType/:itemId/:directionCode` — Replace frame images for a direction.
|
|
570
|
+
* - `/:id/metadata/:itemType/:itemId` — Update metadata and reprocess all frames.
|
|
571
|
+
* - `/:id` — Standard update from request body.
|
|
572
|
+
*
|
|
573
|
+
* The `/metadata` route delegates to {@link ObjectLayerEngine.updateObjectLayerDocuments}
|
|
574
|
+
* for document update, atlas regeneration, SHA-256 computation, and IPFS pinning.
|
|
575
|
+
*
|
|
576
|
+
* @async
|
|
577
|
+
* @function put
|
|
578
|
+
* @memberof CyberiaObjectLayerService.ObjectLayerService
|
|
579
|
+
* @param {Object} req - Express request object.
|
|
580
|
+
* @param {Object} res - Express response object.
|
|
581
|
+
* @param {Object} options - Server options containing host and path.
|
|
582
|
+
* @param {string} options.host - The deployment host.
|
|
583
|
+
* @param {string} options.path - The deployment path.
|
|
584
|
+
* @returns {Promise<Object>} The updated object layer document or frame upload result.
|
|
585
|
+
* @throws {Error} If file validation fails, object layer is not found, or required parameters are missing.
|
|
586
|
+
*/
|
|
587
|
+
static put = async (req, res, options) => {
|
|
588
|
+
/** @type {import('./object-layer.model.js').ObjectLayerModel} */
|
|
589
|
+
const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
|
|
590
|
+
|
|
591
|
+
// PUT /:id/frame-image/:itemType/:itemId/:directionCode - Update frame images for specific direction
|
|
592
|
+
if (req.path.includes('/frame-image/')) {
|
|
593
|
+
const objectLayerId = req.params.id;
|
|
594
|
+
const itemType = req.params.itemType;
|
|
595
|
+
const itemId = req.params.itemId;
|
|
596
|
+
const directionCode = req.params.directionCode;
|
|
597
|
+
|
|
598
|
+
// Debug: Log request files structure
|
|
599
|
+
logger.info(`Request files for direction ${directionCode}:`, {
|
|
600
|
+
filesKeys: req.files ? Object.keys(req.files) : [],
|
|
601
|
+
filesCount: req.files ? Object.keys(req.files).length : 0,
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
// Extract all frames for this direction
|
|
605
|
+
const files = FileFactory.filesExtract(req);
|
|
606
|
+
|
|
607
|
+
// Allow empty files to remove all frames from direction
|
|
608
|
+
if (!files || files.length === 0) {
|
|
609
|
+
logger.info(`No files received for direction ${directionCode} - will remove all frames from this direction`);
|
|
610
|
+
} else {
|
|
611
|
+
// Validate each file has data
|
|
612
|
+
for (let i = 0; i < files.length; i++) {
|
|
613
|
+
if (!files[i].data) {
|
|
614
|
+
logger.error(`File ${files[i].name || i} has no data for direction ${directionCode}`);
|
|
615
|
+
throw new Error(`File ${files[i].name || i} has no data`);
|
|
616
|
+
}
|
|
617
|
+
if (!Buffer.isBuffer(files[i].data)) {
|
|
618
|
+
logger.error(`File ${files[i].name || i} data is not a Buffer for direction ${directionCode}`);
|
|
619
|
+
throw new Error(`File ${files[i].name || i} data is not a Buffer`);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
logger.info(
|
|
625
|
+
`Processing ${files?.length || 0} file(s) for direction ${directionCode}: ${files?.map((f) => f.name).join(', ') || 'none'}`,
|
|
626
|
+
);
|
|
627
|
+
|
|
628
|
+
// Always clear and rewrite ALL frames for this direction code
|
|
629
|
+
for (const basePath of ['./src/client/public/cyberia/', `./public/${options.host}${options.path}`]) {
|
|
630
|
+
const folder = `${basePath}assets/${itemType}/${itemId}/${directionCode}`;
|
|
631
|
+
|
|
632
|
+
// Always remove entire direction folder to ensure clean state
|
|
633
|
+
if (fs.existsSync(folder)) {
|
|
634
|
+
await fs.remove(folder);
|
|
635
|
+
logger.info(`Cleared folder: ${folder}`);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// Only create and write files if we have frames to upload
|
|
639
|
+
if (files && files.length > 0) {
|
|
640
|
+
// Create fresh folder
|
|
641
|
+
fs.mkdirSync(folder, { recursive: true });
|
|
642
|
+
|
|
643
|
+
// Write all frames sent in this request
|
|
644
|
+
for (const file of files) {
|
|
645
|
+
const filePath = `${folder}/${file.name}`;
|
|
646
|
+
try {
|
|
647
|
+
fs.writeFileSync(filePath, file.data);
|
|
648
|
+
logger.info(`Wrote file: ${filePath}`);
|
|
649
|
+
} catch (error) {
|
|
650
|
+
logger.error(`Error writing file ${filePath}:`, error);
|
|
651
|
+
throw new Error(`Failed to write ${file.name}: ${error.message}`);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
} else {
|
|
655
|
+
logger.info(`No frames to write for direction ${directionCode} - folder removed`);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
logger.info(
|
|
660
|
+
`Successfully processed ${files?.length || 0} frame(s) for direction ${directionCode} in object layer ${objectLayerId}`,
|
|
661
|
+
);
|
|
662
|
+
|
|
663
|
+
return { success: true, directionCode, frameCount: files?.length || 0 };
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// PUT /:id/metadata/:itemType/:itemId - Update object layer metadata and reprocess all frames
|
|
667
|
+
if (req.path.includes('/metadata/')) {
|
|
668
|
+
const objectLayerId = req.params.id;
|
|
669
|
+
const itemType = req.params.itemType;
|
|
670
|
+
const itemId = req.params.itemId;
|
|
671
|
+
|
|
672
|
+
const folder = `./src/client/public/cyberia/assets/${itemType}/${itemId}`;
|
|
673
|
+
const publicFolder = `./public/${options.host}${options.path}/assets/${itemType}/${itemId}`;
|
|
674
|
+
|
|
675
|
+
// Ensure both folders exist
|
|
676
|
+
if (!fs.existsSync(folder)) {
|
|
677
|
+
fs.mkdirSync(folder, { recursive: true });
|
|
678
|
+
}
|
|
679
|
+
if (!fs.existsSync(publicFolder)) {
|
|
680
|
+
fs.mkdirSync(publicFolder, { recursive: true });
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
// Write metadata.json to both locations
|
|
684
|
+
const metadataContent = JSON.stringify(req.body);
|
|
685
|
+
fs.writeFileSync(`${folder}/metadata.json`, metadataContent);
|
|
686
|
+
fs.writeFileSync(`${publicFolder}/metadata.json`, metadataContent);
|
|
687
|
+
|
|
688
|
+
const ObjectLayerRenderFrames = DataBaseProviderService.getModel('ObjectLayerRenderFrames', options);
|
|
689
|
+
|
|
690
|
+
// Build object layer data from the asset directory
|
|
691
|
+
const { objectLayerRenderFramesData, objectLayerData } =
|
|
692
|
+
await ObjectLayerEngine.buildObjectLayerDataFromDirectory({
|
|
693
|
+
folder,
|
|
694
|
+
objectLayerType: itemType,
|
|
695
|
+
objectLayerId: itemId,
|
|
696
|
+
metadataOverride: req.body,
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
// Update documents using engine method (with atlas generation)
|
|
700
|
+
const { objectLayer } = await ObjectLayerEngine.updateObjectLayerDocuments({
|
|
701
|
+
objectLayerId,
|
|
702
|
+
ObjectLayer,
|
|
703
|
+
ObjectLayerRenderFrames,
|
|
704
|
+
objectLayerRenderFramesData,
|
|
705
|
+
objectLayerData,
|
|
706
|
+
updateOptions: {
|
|
707
|
+
generateAtlas: true,
|
|
708
|
+
atlasServiceContext: {
|
|
709
|
+
req,
|
|
710
|
+
res,
|
|
711
|
+
options,
|
|
712
|
+
AtlasSpriteSheetService,
|
|
713
|
+
IpfsClient,
|
|
714
|
+
createPinRecord,
|
|
715
|
+
},
|
|
716
|
+
},
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
return objectLayer;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
// PUT /:id - Standard update with cut-over consistency
|
|
723
|
+
const existingOL = await ObjectLayer.findById(req.params.id).populate('objectLayerRenderFramesId');
|
|
724
|
+
if (!existingOL) {
|
|
725
|
+
throw new Error('ObjectLayer not found');
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
// Apply body updates to staging data in memory
|
|
729
|
+
const updateData = { ...req.body };
|
|
730
|
+
const stagingData = updateData.data || existingOL.data.toObject();
|
|
731
|
+
if (!stagingData.render) stagingData.render = {};
|
|
732
|
+
|
|
733
|
+
// Use existing render frames if available
|
|
734
|
+
const renderFramesData = existingOL.objectLayerRenderFramesId;
|
|
735
|
+
if (renderFramesData) {
|
|
736
|
+
try {
|
|
737
|
+
const stagingOL = {
|
|
738
|
+
data: stagingData,
|
|
739
|
+
objectLayerRenderFramesId: renderFramesData,
|
|
740
|
+
};
|
|
741
|
+
const result = await AtlasSpriteSheetService.generate(
|
|
742
|
+
{ objectLayer: stagingOL, auth: req.auth },
|
|
743
|
+
res,
|
|
744
|
+
options,
|
|
745
|
+
{ skipObjectLayerSave: true },
|
|
746
|
+
);
|
|
747
|
+
stagingData.render.cid = result.atlasCid;
|
|
748
|
+
stagingData.render.metadataCid = result.atlasMetadataCid;
|
|
749
|
+
updateData.atlasSpriteSheetId = result.atlasDoc._id;
|
|
750
|
+
} catch (atlasError) {
|
|
751
|
+
logger.error('Failed to auto-update atlas for ObjectLayer:', atlasError);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
updateData.data = stagingData;
|
|
756
|
+
updateData.sha256 = ObjectLayerEngine.computeSha256(stagingData);
|
|
757
|
+
|
|
758
|
+
// Pin data JSON to IPFS
|
|
759
|
+
try {
|
|
760
|
+
const itemId = stagingData.item.id;
|
|
761
|
+
const mfsPath = `/object-layer/${itemId}/${itemId}_data.json`;
|
|
762
|
+
const ipfsResult = await IpfsClient.addJsonToIpfs(stagingData, `${itemId}_data.json`, mfsPath);
|
|
763
|
+
if (ipfsResult) {
|
|
764
|
+
updateData.cid = ipfsResult.cid;
|
|
765
|
+
await createPinRecord({ cid: ipfsResult.cid, resourceType: 'object-layer-data', mfsPath, options });
|
|
766
|
+
}
|
|
767
|
+
} catch (ipfsError) {
|
|
768
|
+
logger.warn('Failed to pin data JSON to IPFS:', ipfsError.message);
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
// Atomic update with all CIDs populated
|
|
772
|
+
let updatedObjectLayer = await ObjectLayer.findByIdAndUpdate(req.params.id, updateData, {
|
|
773
|
+
returnDocument: 'after',
|
|
774
|
+
}).populate('objectLayerRenderFramesId');
|
|
775
|
+
|
|
776
|
+
return updatedObjectLayer;
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
/**
|
|
780
|
+
* DELETE handler for removing object layers and all associated resources.
|
|
781
|
+
*
|
|
782
|
+
* When a specific ID is provided, performs a cascading delete that removes:
|
|
783
|
+
* 1. The AtlasSpriteSheet and its File document.
|
|
784
|
+
* 2. The ObjectLayerRenderFrames document.
|
|
785
|
+
* 3. IPFS pin records and CIDs (both data JSON and atlas PNG).
|
|
786
|
+
* 4. The MFS directory for this object layer.
|
|
787
|
+
* 5. Static asset files from disk.
|
|
788
|
+
* 6. The ObjectLayer document itself.
|
|
789
|
+
*
|
|
790
|
+
* When no ID is provided, performs a bulk delete of all object layers.
|
|
791
|
+
*
|
|
792
|
+
* @async
|
|
793
|
+
* @function delete
|
|
794
|
+
* @memberof CyberiaObjectLayerService.ObjectLayerService
|
|
795
|
+
* @param {Object} req - Express request object.
|
|
796
|
+
* @param {Object} res - Express response object.
|
|
797
|
+
* @param {Object} options - Server options containing host and path.
|
|
798
|
+
* @param {string} options.host - The deployment host.
|
|
799
|
+
* @param {string} options.path - The deployment path.
|
|
800
|
+
* @returns {Promise<Object>} The deleted object layer document or bulk delete count.
|
|
801
|
+
* @throws {Error} If the object layer is not found.
|
|
802
|
+
*/
|
|
803
|
+
static delete = async (req, res, options) => {
|
|
804
|
+
/** @type {import('./object-layer.model.js').ObjectLayerModel} */
|
|
805
|
+
const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
|
|
806
|
+
const ObjectLayerRenderFrames = DataBaseProviderService.getModel('ObjectLayerRenderFrames', options);
|
|
807
|
+
|
|
808
|
+
if (req.params.id) {
|
|
809
|
+
// Load the full object layer so we can access all references
|
|
810
|
+
const objectLayer = await ObjectLayer.findById(req.params.id);
|
|
811
|
+
if (!objectLayer) {
|
|
812
|
+
throw new Error('ObjectLayer not found');
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
const itemType = objectLayer.data?.item?.type;
|
|
816
|
+
const itemId = objectLayer.data?.item?.id;
|
|
817
|
+
|
|
818
|
+
// ── 1. Clean up AtlasSpriteSheet, its File, and atlas IPFS CID ──
|
|
819
|
+
try {
|
|
820
|
+
await AtlasSpriteSheetService.deleteByObjectLayerId(req, res, options);
|
|
821
|
+
} catch (atlasError) {
|
|
822
|
+
logger.error('Failed to clean up atlas during ObjectLayer deletion:', atlasError);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// ── 2. Clean up ObjectLayerRenderFrames document ──
|
|
826
|
+
if (objectLayer.objectLayerRenderFramesId) {
|
|
827
|
+
try {
|
|
828
|
+
await ObjectLayerRenderFrames.findByIdAndDelete(objectLayer.objectLayerRenderFramesId);
|
|
829
|
+
logger.info(
|
|
830
|
+
`Deleted ObjectLayerRenderFrames ${objectLayer.objectLayerRenderFramesId} for ObjectLayer ${req.params.id}`,
|
|
831
|
+
);
|
|
832
|
+
} catch (renderFramesError) {
|
|
833
|
+
logger.error('Failed to delete ObjectLayerRenderFrames:', renderFramesError);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// ── 3. Remove pin records and unpin object layer data JSON CID from IPFS ──
|
|
838
|
+
if (objectLayer.cid) {
|
|
839
|
+
try {
|
|
840
|
+
await removePinRecordsAndUnpin(objectLayer.cid, options);
|
|
841
|
+
logger.info(`Cleaned up IPFS data CID ${objectLayer.cid} for ObjectLayer ${req.params.id}`);
|
|
842
|
+
} catch (ipfsError) {
|
|
843
|
+
logger.warn(`Failed to clean up IPFS data CID ${objectLayer.cid}: ${ipfsError.message}`);
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
// ── 4. Remove MFS directory for this object layer (covers both data JSON and atlas PNG) ──
|
|
848
|
+
if (itemId) {
|
|
849
|
+
try {
|
|
850
|
+
await IpfsClient.removeMfsPath(`/object-layer/${itemId}`);
|
|
851
|
+
logger.info(`Removed MFS directory /object-layer/${itemId}`);
|
|
852
|
+
} catch (mfsError) {
|
|
853
|
+
logger.warn(`Failed to remove MFS path /object-layer/${itemId}: ${mfsError.message}`);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
// ── 5. Remove static asset files from disk ──
|
|
858
|
+
if (itemType && itemId) {
|
|
859
|
+
const staticPaths = [
|
|
860
|
+
`./src/client/public/cyberia/assets/${itemType}/${itemId}`,
|
|
861
|
+
`./public/${options.host}${options.path}/assets/${itemType}/${itemId}`,
|
|
862
|
+
];
|
|
863
|
+
for (const assetDir of staticPaths) {
|
|
864
|
+
try {
|
|
865
|
+
if (fs.existsSync(assetDir)) {
|
|
866
|
+
await fs.remove(assetDir);
|
|
867
|
+
logger.info(`Removed static asset directory: ${assetDir}`);
|
|
868
|
+
}
|
|
869
|
+
} catch (fsError) {
|
|
870
|
+
logger.warn(`Failed to remove static asset directory ${assetDir}: ${fsError.message}`);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// ── 6. Delete the ObjectLayer document itself ──
|
|
876
|
+
const deleted = await ObjectLayer.findByIdAndDelete(req.params.id);
|
|
877
|
+
logger.info(`ObjectLayer ${req.params.id} and all associated resources deleted successfully`);
|
|
878
|
+
return deleted;
|
|
879
|
+
} else {
|
|
880
|
+
// Bulk delete: clean up all object layers
|
|
881
|
+
const allObjectLayers = await ObjectLayer.find({});
|
|
882
|
+
for (const ol of allObjectLayers) {
|
|
883
|
+
try {
|
|
884
|
+
await ObjectLayerService.delete({ params: { id: ol._id.toString() }, auth: req.auth }, res, options);
|
|
885
|
+
} catch (err) {
|
|
886
|
+
logger.error(`Failed to delete ObjectLayer ${ol._id} during bulk delete: ${err.message}`);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
return { deletedCount: allObjectLayers.length };
|
|
890
|
+
}
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
export { ObjectLayerService };
|