cyberia 3.2.9 → 3.2.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/.github/workflows/engine-cyberia.cd.yml +7 -0
  2. package/.github/workflows/engine-cyberia.ci.yml +14 -2
  3. package/.github/workflows/ghpkg.ci.yml +1 -0
  4. package/.github/workflows/npmpkg.ci.yml +10 -5
  5. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  6. package/.github/workflows/release.cd.yml +1 -0
  7. package/.vscode/extensions.json +9 -9
  8. package/.vscode/settings.json +20 -4
  9. package/CHANGELOG.md +363 -1
  10. package/CLI-HELP.md +975 -1061
  11. package/README.md +190 -348
  12. package/bin/build.js +102 -125
  13. package/bin/build.template.js +33 -0
  14. package/bin/cyberia.js +238 -56
  15. package/bin/deploy.js +16 -3
  16. package/bin/index.js +238 -56
  17. package/bump.config.js +26 -0
  18. package/conf.js +131 -24
  19. package/deployment.yaml +76 -2
  20. package/hardhat/package-lock.json +113 -144
  21. package/hardhat/package.json +4 -3
  22. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -2
  23. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  24. package/manifests/deployment/dd-cyberia-development/deployment.yaml +76 -2
  25. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  26. package/manifests/kind-config-dev.yaml +8 -0
  27. package/manifests/lxd/lxd-admin-profile.yaml +12 -3
  28. package/manifests/mongodb/pv-pvc.yaml +44 -8
  29. package/manifests/mongodb/statefulset.yaml +55 -68
  30. package/manifests/mongodb-4.4/headless-service.yaml +10 -0
  31. package/manifests/mongodb-4.4/kustomization.yaml +3 -1
  32. package/manifests/mongodb-4.4/mongodb-nodeport.yaml +17 -0
  33. package/manifests/mongodb-4.4/pv-pvc.yaml +10 -14
  34. package/manifests/mongodb-4.4/statefulset.yaml +79 -0
  35. package/manifests/mongodb-4.4/storage-class.yaml +9 -0
  36. package/manifests/valkey/statefulset.yaml +1 -1
  37. package/manifests/valkey/valkey-nodeport.yaml +17 -0
  38. package/package.json +31 -19
  39. package/scripts/ipxe-setup.sh +52 -49
  40. package/scripts/k3s-node-setup.sh +81 -46
  41. package/scripts/link-local-underpost-cli.sh +6 -0
  42. package/scripts/lxd-vm-setup.sh +193 -8
  43. package/scripts/maas-nat-firewalld.sh +145 -0
  44. package/scripts/test-monitor.sh +250 -0
  45. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +38 -33
  46. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +16 -16
  47. package/src/api/core/core.router.js +19 -14
  48. package/src/api/core/core.service.js +5 -5
  49. package/src/api/crypto/crypto.router.js +18 -12
  50. package/src/api/crypto/crypto.service.js +3 -3
  51. package/src/api/cyberia-action/cyberia-action.model.js +1 -1
  52. package/src/api/cyberia-action/cyberia-action.router.js +22 -18
  53. package/src/api/cyberia-action/cyberia-action.service.js +5 -5
  54. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +74 -0
  55. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +99 -0
  56. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +98 -0
  57. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +152 -0
  58. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +25 -20
  59. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +6 -6
  60. package/src/api/cyberia-entity/cyberia-entity.router.js +22 -18
  61. package/src/api/cyberia-entity/cyberia-entity.service.js +5 -5
  62. package/src/api/cyberia-instance/cyberia-fallback-world.js +79 -4
  63. package/src/api/cyberia-instance/cyberia-instance.router.js +57 -52
  64. package/src/api/cyberia-instance/cyberia-instance.service.js +10 -10
  65. package/src/api/cyberia-instance/cyberia-world-generator.js +3 -3
  66. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +14 -48
  67. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +22 -18
  68. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +5 -5
  69. package/src/api/cyberia-map/cyberia-map.router.js +35 -30
  70. package/src/api/cyberia-map/cyberia-map.service.js +7 -7
  71. package/src/api/cyberia-quest/cyberia-quest.model.js +1 -1
  72. package/src/api/cyberia-quest/cyberia-quest.router.js +22 -18
  73. package/src/api/cyberia-quest/cyberia-quest.service.js +5 -5
  74. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +22 -18
  75. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +5 -5
  76. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +458 -0
  77. package/src/api/default/default.router.js +22 -18
  78. package/src/api/default/default.service.js +5 -5
  79. package/src/api/document/document.router.js +28 -23
  80. package/src/api/document/document.service.js +100 -23
  81. package/src/api/file/file.router.js +19 -13
  82. package/src/api/file/file.service.js +9 -7
  83. package/src/api/instance/instance.router.js +29 -24
  84. package/src/api/instance/instance.service.js +6 -6
  85. package/src/api/ipfs/ipfs.router.js +21 -16
  86. package/src/api/ipfs/ipfs.service.js +8 -8
  87. package/src/api/object-layer/object-layer.router.js +512 -507
  88. package/src/api/object-layer/object-layer.service.js +17 -14
  89. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +22 -18
  90. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +5 -5
  91. package/src/api/test/test.router.js +17 -12
  92. package/src/api/types.js +24 -0
  93. package/src/api/user/guest.service.js +5 -4
  94. package/src/api/user/user.router.js +297 -288
  95. package/src/api/user/user.service.js +100 -35
  96. package/src/cli/baremetal.js +132 -101
  97. package/src/cli/cluster.js +700 -232
  98. package/src/cli/db.js +59 -60
  99. package/src/cli/deploy.js +291 -294
  100. package/src/cli/env.js +1 -4
  101. package/src/cli/fs.js +13 -3
  102. package/src/cli/image.js +58 -4
  103. package/src/cli/index.js +127 -15
  104. package/src/cli/ipfs.js +4 -6
  105. package/src/cli/kubectl.js +4 -1
  106. package/src/cli/lxd.js +1099 -223
  107. package/src/cli/monitor.js +396 -9
  108. package/src/cli/release.js +355 -146
  109. package/src/cli/repository.js +169 -30
  110. package/src/cli/run.js +347 -117
  111. package/src/cli/secrets.js +11 -2
  112. package/src/cli/test.js +9 -3
  113. package/src/client/Default.index.js +9 -3
  114. package/src/client/components/core/Auth.js +5 -0
  115. package/src/client/components/core/ClientEvents.js +76 -0
  116. package/src/client/components/core/EventBus.js +4 -0
  117. package/src/client/components/core/Modal.js +82 -41
  118. package/src/client/components/core/PanelForm.js +14 -10
  119. package/src/client/components/core/Worker.js +162 -363
  120. package/src/client/components/cyberia/MapEngineCyberia.js +1 -1
  121. package/src/client/components/cyberia/SharedDefaultsCyberia.js +330 -0
  122. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +55 -1
  123. package/src/client/public/cyberia-docs/ARCHITECTURE.md +223 -361
  124. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +114 -327
  125. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +200 -222
  126. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +212 -185
  127. package/src/client/public/cyberia-docs/CYBERIA.md +259 -0
  128. package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +2 -2
  129. package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +23 -1
  130. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  131. package/src/client/public/cyberia-docs/UNDERPOST-PLATFORM.md +106 -0
  132. package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
  133. package/src/client/services/cyberia-client-hints/cyberia-client-hints.service.js +99 -0
  134. package/src/client/ssr/views/CyberiaServerMetrics.js +982 -0
  135. package/src/client/sw/core.sw.js +174 -112
  136. package/src/db/DataBaseProvider.js +115 -15
  137. package/src/db/mariadb/MariaDB.js +2 -1
  138. package/src/db/mongo/MongoBootstrap.js +657 -0
  139. package/src/db/mongo/MongooseDB.js +130 -21
  140. package/src/grpc/cyberia/grpc-server.js +25 -57
  141. package/src/index.js +1 -1
  142. package/src/runtime/cyberia-client/Dockerfile +10 -7
  143. package/src/runtime/cyberia-client/Dockerfile.dev +67 -0
  144. package/src/runtime/cyberia-server/Dockerfile +11 -6
  145. package/src/runtime/cyberia-server/Dockerfile.dev +47 -0
  146. package/src/runtime/express/Express.js +2 -2
  147. package/src/runtime/wp/Dockerfile +3 -3
  148. package/src/runtime/wp/Wp.js +8 -5
  149. package/src/server/auth.js +2 -2
  150. package/src/server/catalog-underpost.js +61 -0
  151. package/src/server/catalog.js +77 -0
  152. package/src/server/client-build-docs.js +1 -1
  153. package/src/server/client-build.js +94 -129
  154. package/src/server/conf.js +496 -135
  155. package/src/server/ipfs-client.js +5 -3
  156. package/src/server/process.js +180 -19
  157. package/src/server/proxy.js +9 -2
  158. package/src/server/runtime-status.js +235 -0
  159. package/src/server/runtime.js +1 -1
  160. package/src/server/start.js +44 -11
  161. package/src/server/valkey.js +2 -0
  162. package/src/ws/IoInterface.js +16 -16
  163. package/src/ws/core/channels/core.ws.chat.js +11 -11
  164. package/src/ws/core/channels/core.ws.mailer.js +29 -29
  165. package/src/ws/core/channels/core.ws.stream.js +19 -19
  166. package/src/ws/core/core.ws.connection.js +8 -8
  167. package/src/ws/core/core.ws.server.js +6 -5
  168. package/src/ws/default/channels/default.ws.main.js +10 -10
  169. package/src/ws/default/default.ws.connection.js +4 -4
  170. package/src/ws/default/default.ws.server.js +4 -3
  171. package/test/deploy-monitor.test.js +251 -0
  172. package/bin/file.js +0 -202
  173. package/bin/vs.js +0 -74
  174. package/bin/zed.js +0 -84
  175. package/manifests/deployment/dd-test-development/deployment.yaml +0 -254
  176. package/manifests/deployment/dd-test-development/proxy.yaml +0 -102
  177. package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +0 -574
  178. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +0 -467
  179. package/src/client/ssr/email/DefaultRecoverEmail.js +0 -21
  180. package/src/client/ssr/email/DefaultVerifyEmail.js +0 -17
  181. package/src/client/ssr/pages/CyberiaServerMetrics.js +0 -461
  182. /package/src/client/ssr/{offline → views}/Maintenance.js +0 -0
  183. /package/src/client/ssr/{offline → views}/NoNetworkConnection.js +0 -0
  184. /package/src/client/ssr/{pages → views}/Test.js +0 -0
@@ -4,39 +4,44 @@ import express from 'express';
4
4
 
5
5
  const logger = loggerFactory(import.meta);
6
6
 
7
- const AtlasSpriteSheetRouter = (options) => {
8
- const router = express.Router();
9
- const authMiddleware = options.authMiddleware;
10
- router.post(
11
- `/generate/:id`,
12
- authMiddleware,
13
- async (req, res) => await AtlasSpriteSheetController.generate(req, res, options),
14
- );
15
- router.delete(
16
- `/object-layer/:id`,
17
- authMiddleware,
18
- async (req, res) => await AtlasSpriteSheetController.deleteByObjectLayerId(req, res, options),
19
- );
20
- router.post(`/:id`, authMiddleware, async (req, res) => await AtlasSpriteSheetController.post(req, res, options));
21
- router.post(`/`, authMiddleware, async (req, res) => await AtlasSpriteSheetController.post(req, res, options));
22
- router.get(`/blob/:itemKey`, async (req, res) => await AtlasSpriteSheetController.blob(req, res, options));
23
- // Metadata endpoints: returns itemKey, atlasWidth, atlasHeight, cellPixelDim, frames (no fileId).
24
- // Client fetches /metadata/:itemKey once, caches it, then fetches /blob/:itemKey for the PNG.
25
- router.get(`/metadata/:itemKey`, async (req, res) => await AtlasSpriteSheetController.getMetadata(req, res, options));
26
- router.get(`/metadata`, async (req, res) => await AtlasSpriteSheetController.getMetadata(req, res, options));
27
- router.get(
28
- `/:id`,
29
- // authMiddleware,
30
- async (req, res) => await AtlasSpriteSheetController.get(req, res, options),
31
- );
32
- router.get(`/`, async (req, res) => await AtlasSpriteSheetController.get(req, res, options));
33
- router.put(`/:id`, authMiddleware, async (req, res) => await AtlasSpriteSheetController.put(req, res, options));
34
- router.put(`/`, authMiddleware, async (req, res) => await AtlasSpriteSheetController.put(req, res, options));
35
- router.delete(`/:id`, authMiddleware, async (req, res) => await AtlasSpriteSheetController.delete(req, res, options));
36
- router.delete(`/`, authMiddleware, async (req, res) => await AtlasSpriteSheetController.delete(req, res, options));
37
- return router;
38
- };
7
+ class AtlasSpriteSheetRouter {
8
+ /**
9
+ * @param {import('../types.js').RouterOptions} options
10
+ * @returns {import('express').Router}
11
+ */
12
+ static router(options) {
13
+ const router = express.Router();
14
+ router.post(
15
+ `/generate/:id`,
16
+ options.authMiddleware,
17
+ async (req, res) => await AtlasSpriteSheetController.generate(req, res, options),
18
+ );
19
+ router.delete(
20
+ `/object-layer/:id`,
21
+ options.authMiddleware,
22
+ async (req, res) => await AtlasSpriteSheetController.deleteByObjectLayerId(req, res, options),
23
+ );
24
+ router.post(`/:id`, options.authMiddleware, async (req, res) => await AtlasSpriteSheetController.post(req, res, options));
25
+ router.post(`/`, options.authMiddleware, async (req, res) => await AtlasSpriteSheetController.post(req, res, options));
26
+ router.get(`/blob/:itemKey`, async (req, res) => await AtlasSpriteSheetController.blob(req, res, options));
27
+ // Metadata endpoints: returns itemKey, atlasWidth, atlasHeight, cellPixelDim, frames (no fileId).
28
+ // Client fetches /metadata/:itemKey once, caches it, then fetches /blob/:itemKey for the PNG.
29
+ router.get(`/metadata/:itemKey`, async (req, res) => await AtlasSpriteSheetController.getMetadata(req, res, options));
30
+ router.get(`/metadata`, async (req, res) => await AtlasSpriteSheetController.getMetadata(req, res, options));
31
+ router.get(
32
+ `/:id`,
33
+ // options.authMiddleware,
34
+ async (req, res) => await AtlasSpriteSheetController.get(req, res, options),
35
+ );
36
+ router.get(`/`, async (req, res) => await AtlasSpriteSheetController.get(req, res, options));
37
+ router.put(`/:id`, options.authMiddleware, async (req, res) => await AtlasSpriteSheetController.put(req, res, options));
38
+ router.put(`/`, options.authMiddleware, async (req, res) => await AtlasSpriteSheetController.put(req, res, options));
39
+ router.delete(`/:id`, options.authMiddleware, async (req, res) => await AtlasSpriteSheetController.delete(req, res, options));
40
+ router.delete(`/`, options.authMiddleware, async (req, res) => await AtlasSpriteSheetController.delete(req, res, options));
41
+ return router;
42
+ }
43
+ }
39
44
 
40
- const ApiRouter = AtlasSpriteSheetRouter;
45
+ const ApiRouter = (options) => AtlasSpriteSheetRouter.router(options);
41
46
 
42
47
  export { ApiRouter, AtlasSpriteSheetRouter };
@@ -1,4 +1,4 @@
1
- import { DataBaseProvider } from '../../db/DataBaseProvider.js';
1
+ import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
2
2
  import { loggerFactory } from '../../server/logger.js';
3
3
  import { DataQuery } from '../../server/data-query.js';
4
4
  import { AtlasSpriteSheetGenerator } from '../../server/atlas-sprite-sheet-generator.js';
@@ -55,9 +55,9 @@ class AtlasSpriteSheetService {
55
55
  static blob = async (req, res, options) => {
56
56
  /** @type {import('./atlas-sprite-sheet.model.js').AtlasSpriteSheetModel} */
57
57
  const AtlasSpriteSheet =
58
- DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.AtlasSpriteSheet;
58
+ DataBaseProviderService.getModel("AtlasSpriteSheet", options);
59
59
  /** @type {import('../file/file.model.js').FileModel} */
60
- const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
60
+ const File = DataBaseProviderService.getModel("File", options);
61
61
 
62
62
  const itemKey = req.params.itemKey;
63
63
  const atlasDoc = await AtlasSpriteSheet.findOne({ 'metadata.itemKey': itemKey }).lean();
@@ -70,12 +70,12 @@ class AtlasSpriteSheetService {
70
70
  };
71
71
  static generate = async (req, res, options, generateOptions = {}) => {
72
72
  /** @type {import('../object-layer/object-layer.model.js').ObjectLayerModel} */
73
- const ObjectLayer = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.ObjectLayer;
73
+ const ObjectLayer = DataBaseProviderService.getModel("ObjectLayer", options);
74
74
  /** @type {import('../file/file.model.js').FileModel} */
75
- const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
75
+ const File = DataBaseProviderService.getModel("File", options);
76
76
  /** @type {import('./atlas-sprite-sheet.model.js').AtlasSpriteSheetModel} */
77
77
  const AtlasSpriteSheet =
78
- DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.AtlasSpriteSheet;
78
+ DataBaseProviderService.getModel("AtlasSpriteSheet", options);
79
79
 
80
80
  let objectLayer = req.objectLayer;
81
81
 
@@ -195,12 +195,12 @@ class AtlasSpriteSheetService {
195
195
  };
196
196
  static deleteByObjectLayerId = async (req, res, options) => {
197
197
  /** @type {import('../object-layer/object-layer.model.js').ObjectLayerModel} */
198
- const ObjectLayer = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.ObjectLayer;
198
+ const ObjectLayer = DataBaseProviderService.getModel("ObjectLayer", options);
199
199
  /** @type {import('../file/file.model.js').FileModel} */
200
- const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
200
+ const File = DataBaseProviderService.getModel("File", options);
201
201
  /** @type {import('./atlas-sprite-sheet.model.js').AtlasSpriteSheetModel} */
202
202
  const AtlasSpriteSheet =
203
- DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.AtlasSpriteSheet;
203
+ DataBaseProviderService.getModel("AtlasSpriteSheet", options);
204
204
 
205
205
  const objectLayer = await ObjectLayer.findById(req.params.id);
206
206
  if (!objectLayer) {
@@ -255,13 +255,13 @@ class AtlasSpriteSheetService {
255
255
  static post = async (req, res, options) => {
256
256
  /** @type {import('./atlas-sprite-sheet.model.js').AtlasSpriteSheetModel} */
257
257
  const AtlasSpriteSheet =
258
- DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.AtlasSpriteSheet;
258
+ DataBaseProviderService.getModel("AtlasSpriteSheet", options);
259
259
  return await new AtlasSpriteSheet(req.body).save();
260
260
  };
261
261
  static get = async (req, res, options) => {
262
262
  /** @type {import('./atlas-sprite-sheet.model.js').AtlasSpriteSheetModel} */
263
263
  const AtlasSpriteSheet =
264
- DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.AtlasSpriteSheet;
264
+ DataBaseProviderService.getModel("AtlasSpriteSheet", options);
265
265
  if (req.params.id)
266
266
  return await AtlasSpriteSheet.findById(req.params.id)
267
267
  .select(AtlasSpriteSheetDto.select.get())
@@ -287,10 +287,10 @@ class AtlasSpriteSheetService {
287
287
  // Client fetches this once per itemKey, caches it, then fetches the PNG blob.
288
288
  static getMetadata = async (req, res, options) => {
289
289
  /** @type {import('../object-layer/object-layer.model.js').ObjectLayerModel} */
290
- const ObjectLayer = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.ObjectLayer;
290
+ const ObjectLayer = DataBaseProviderService.getModel("ObjectLayer", options);
291
291
  /** @type {import('./atlas-sprite-sheet.model.js').AtlasSpriteSheetModel} */
292
292
  const AtlasSpriteSheet =
293
- DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.AtlasSpriteSheet;
293
+ DataBaseProviderService.getModel("AtlasSpriteSheet", options);
294
294
 
295
295
  if (req.params.itemKey) {
296
296
  const doc = await AtlasSpriteSheet.findOne({ 'metadata.itemKey': req.params.itemKey })
@@ -329,15 +329,15 @@ class AtlasSpriteSheetService {
329
329
  static put = async (req, res, options) => {
330
330
  /** @type {import('./atlas-sprite-sheet.model.js').AtlasSpriteSheetModel} */
331
331
  const AtlasSpriteSheet =
332
- DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.AtlasSpriteSheet;
332
+ DataBaseProviderService.getModel("AtlasSpriteSheet", options);
333
333
  return await AtlasSpriteSheet.findByIdAndUpdate(req.params.id, req.body);
334
334
  };
335
335
  static delete = async (req, res, options) => {
336
336
  /** @type {import('./atlas-sprite-sheet.model.js').AtlasSpriteSheetModel} */
337
337
  const AtlasSpriteSheet =
338
- DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.AtlasSpriteSheet;
338
+ DataBaseProviderService.getModel("AtlasSpriteSheet", options);
339
339
  /** @type {import('../file/file.model.js').FileModel} */
340
- const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
340
+ const File = DataBaseProviderService.getModel("File", options);
341
341
 
342
342
  if (req.params.id) {
343
343
  const atlasDoc = await AtlasSpriteSheet.findById(req.params.id);
@@ -5,20 +5,25 @@ import express from 'express';
5
5
 
6
6
  const logger = loggerFactory(import.meta);
7
7
 
8
- const CoreRouter = (options) => {
9
- const router = express.Router();
10
- const authMiddleware = options.authMiddleware;
11
- router.post(`/:id`, authMiddleware, adminGuard, async (req, res) => await CoreController.post(req, res, options));
12
- router.post(`/`, authMiddleware, adminGuard, async (req, res) => await CoreController.post(req, res, options));
13
- router.get(`/:id`, authMiddleware, adminGuard, async (req, res) => await CoreController.get(req, res, options));
14
- router.get(`/`, authMiddleware, adminGuard, async (req, res) => await CoreController.get(req, res, options));
15
- router.put(`/:id`, authMiddleware, adminGuard, async (req, res) => await CoreController.put(req, res, options));
16
- router.put(`/`, authMiddleware, adminGuard, async (req, res) => await CoreController.put(req, res, options));
17
- router.delete(`/:id`, authMiddleware, adminGuard, async (req, res) => await CoreController.delete(req, res, options));
18
- router.delete(`/`, authMiddleware, adminGuard, async (req, res) => await CoreController.delete(req, res, options));
19
- return router;
20
- };
8
+ class CoreRouter {
9
+ /**
10
+ * @param {import('../types.js').RouterOptions} options
11
+ * @returns {import('express').Router}
12
+ */
13
+ static router(options) {
14
+ const router = express.Router();
15
+ router.post(`/:id`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.post(req, res, options));
16
+ router.post(`/`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.post(req, res, options));
17
+ router.get(`/:id`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.get(req, res, options));
18
+ router.get(`/`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.get(req, res, options));
19
+ router.put(`/:id`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.put(req, res, options));
20
+ router.put(`/`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.put(req, res, options));
21
+ router.delete(`/:id`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.delete(req, res, options));
22
+ router.delete(`/`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.delete(req, res, options));
23
+ return router;
24
+ }
25
+ }
21
26
 
22
- const ApiRouter = CoreRouter;
27
+ const ApiRouter = (options) => CoreRouter.router(options);
23
28
 
24
29
  export { ApiRouter, CoreRouter };
@@ -1,4 +1,4 @@
1
- import { DataBaseProvider } from '../../db/DataBaseProvider.js';
1
+ import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
2
2
  import { loggerFactory } from '../../server/logger.js';
3
3
  import { shellExec } from '../../server/process.js';
4
4
 
@@ -7,22 +7,22 @@ const logger = loggerFactory(import.meta);
7
7
  class CoreService {
8
8
  static post = async (req, res, options) => {
9
9
  /** @type {import('./core.model.js').CoreModel} */
10
- const Core = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Core;
10
+ const Core = DataBaseProviderService.getModel("Core", options);
11
11
  return await new Core(req.body).save();
12
12
  };
13
13
  static get = async (req, res, options) => {
14
14
  /** @type {import('./core.model.js').CoreModel} */
15
- const Core = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Core;
15
+ const Core = DataBaseProviderService.getModel("Core", options);
16
16
  return await Core.findById(req.params.id);
17
17
  };
18
18
  static put = async (req, res, options) => {
19
19
  /** @type {import('./core.model.js').CoreModel} */
20
- const Core = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Core;
20
+ const Core = DataBaseProviderService.getModel("Core", options);
21
21
  return await Core.findByIdAndUpdate(req.params.id, req.body);
22
22
  };
23
23
  static delete = async (req, res, options) => {
24
24
  /** @type {import('./core.model.js').CoreModel} */
25
- const Core = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Core;
25
+ const Core = DataBaseProviderService.getModel("Core", options);
26
26
  return await Core.findByIdAndDelete(req.params.id);
27
27
  };
28
28
  }
@@ -1,20 +1,26 @@
1
1
  import { loggerFactory } from '../../server/logger.js';
2
2
  import { CryptoController } from './crypto.controller.js';
3
3
  import express from 'express';
4
+
4
5
  const logger = loggerFactory(import.meta);
5
6
 
6
- const CryptoRouter = (options) => {
7
- const router = express.Router();
8
- const authMiddleware = options.authMiddleware;
9
- router.post(`/:id`, async (req, res) => await CryptoController.post(req, res, options));
10
- router.post(`/`, authMiddleware, async (req, res) => await CryptoController.post(req, res, options));
11
- router.get(`/:id`, async (req, res) => await CryptoController.get(req, res, options));
12
- router.get(`/`, async (req, res) => await CryptoController.get(req, res, options));
13
- router.delete(`/:id`, async (req, res) => await CryptoController.delete(req, res, options));
14
- router.delete(`/`, async (req, res) => await CryptoController.delete(req, res, options));
15
- return router;
16
- };
7
+ class CryptoRouter {
8
+ /**
9
+ * @param {import('../types.js').RouterOptions} options
10
+ * @returns {import('express').Router}
11
+ */
12
+ static router(options) {
13
+ const router = express.Router();
14
+ router.post(`/:id`, async (req, res) => await CryptoController.post(req, res, options));
15
+ router.post(`/`, options.authMiddleware, async (req, res) => await CryptoController.post(req, res, options));
16
+ router.get(`/:id`, async (req, res) => await CryptoController.get(req, res, options));
17
+ router.get(`/`, async (req, res) => await CryptoController.get(req, res, options));
18
+ router.delete(`/:id`, async (req, res) => await CryptoController.delete(req, res, options));
19
+ router.delete(`/`, async (req, res) => await CryptoController.delete(req, res, options));
20
+ return router;
21
+ }
22
+ }
17
23
 
18
- const ApiRouter = CryptoRouter;
24
+ const ApiRouter = (options) => CryptoRouter.router(options);
19
25
 
20
26
  export { ApiRouter, CryptoRouter };
@@ -1,14 +1,14 @@
1
1
  import { loggerFactory } from '../../server/logger.js';
2
2
  import crypto from 'crypto';
3
- import { DataBaseProvider } from '../../db/DataBaseProvider.js';
3
+ import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
4
4
  const logger = loggerFactory(import.meta);
5
5
 
6
6
  class CryptoService {
7
7
  static post = async (req, res, options) => {
8
8
  /** @type {import('./crypto.model.js').CryptoModel} */
9
- const Crypto = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Crypto;
9
+ const Crypto = DataBaseProviderService.getModel("Crypto", options);
10
10
  /** @type {import('../user/user.model.js').UserModel} */
11
- const User = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.User;
11
+ const User = DataBaseProviderService.getModel("User", options);
12
12
 
13
13
  switch (req.params.id) {
14
14
  case 'verify': {
@@ -1,5 +1,5 @@
1
1
  import { Schema, model } from 'mongoose';
2
- import { CYBERIA_ACTION_TYPES } from '../../client/components/cyberia-portal/CommonCyberiaPortal.js';
2
+ import { CYBERIA_ACTION_TYPES } from '../../client/components/cyberia/SharedDefaultsCyberia.js';
3
3
 
4
4
  // https://mongoosejs.com/docs/2.7.x/docs/schematypes.html
5
5
 
@@ -4,24 +4,28 @@ import express from 'express';
4
4
 
5
5
  const logger = loggerFactory(import.meta);
6
6
 
7
- const CyberiaActionRouter = (options) => {
8
- const router = express.Router();
9
- const authMiddleware = options.authMiddleware;
10
- router.post(`/:id`, async (req, res) => await CyberiaActionController.post(req, res, options));
11
- router.post(`/`, async (req, res) => await CyberiaActionController.post(req, res, options));
12
- router.get(
13
- `/:id`,
14
- // authMiddleware,
15
- async (req, res) => await CyberiaActionController.get(req, res, options),
16
- );
17
- router.get(`/`, async (req, res) => await CyberiaActionController.get(req, res, options));
18
- router.put(`/:id`, async (req, res) => await CyberiaActionController.put(req, res, options));
19
- router.put(`/`, async (req, res) => await CyberiaActionController.put(req, res, options));
20
- router.delete(`/:id`, async (req, res) => await CyberiaActionController.delete(req, res, options));
21
- router.delete(`/`, async (req, res) => await CyberiaActionController.delete(req, res, options));
22
- return router;
23
- };
7
+ class CyberiaActionRouter {
8
+ /**
9
+ * @param {import('../types.js').RouterOptions} options
10
+ * @returns {import('express').Router}
11
+ */
12
+ static router(options) {
13
+ const router = express.Router();
14
+ router.post(`/:id`, async (req, res) => await CyberiaActionController.post(req, res, options));
15
+ router.post(`/`, async (req, res) => await CyberiaActionController.post(req, res, options));
16
+ router.get(`/:id`,
17
+ // options.authMiddleware,
18
+ async (req, res) => await CyberiaActionController.get(req, res, options),
19
+ );
20
+ router.get(`/`, async (req, res) => await CyberiaActionController.get(req, res, options));
21
+ router.put(`/:id`, async (req, res) => await CyberiaActionController.put(req, res, options));
22
+ router.put(`/`, async (req, res) => await CyberiaActionController.put(req, res, options));
23
+ router.delete(`/:id`, async (req, res) => await CyberiaActionController.delete(req, res, options));
24
+ router.delete(`/`, async (req, res) => await CyberiaActionController.delete(req, res, options));
25
+ return router;
26
+ }
27
+ }
24
28
 
25
- const ApiRouter = CyberiaActionRouter;
29
+ const ApiRouter = (options) => CyberiaActionRouter.router(options);
26
30
 
27
31
  export { ApiRouter, CyberiaActionRouter };
@@ -1,4 +1,4 @@
1
- import { DataBaseProvider } from '../../db/DataBaseProvider.js';
1
+ import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
2
2
  import { loggerFactory } from '../../server/logger.js';
3
3
  import { DataQuery } from '../../server/data-query.js';
4
4
 
@@ -7,12 +7,12 @@ const logger = loggerFactory(import.meta);
7
7
  class CyberiaActionService {
8
8
  static post = async (req, res, options) => {
9
9
  /** @type {import('./cyberia-action.model.js').CyberiaActionModel} */
10
- const CyberiaAction = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaAction;
10
+ const CyberiaAction = DataBaseProviderService.getModel("CyberiaAction", options);
11
11
  return await new CyberiaAction(req.body).save();
12
12
  };
13
13
  static get = async (req, res, options) => {
14
14
  /** @type {import('./cyberia-action.model.js').CyberiaActionModel} */
15
- const CyberiaAction = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaAction;
15
+ const CyberiaAction = DataBaseProviderService.getModel("CyberiaAction", options);
16
16
  if (req.params.id) return await CyberiaAction.findById(req.params.id);
17
17
 
18
18
  // Parse query parameters using DataQuery helper
@@ -28,12 +28,12 @@ class CyberiaActionService {
28
28
  };
29
29
  static put = async (req, res, options) => {
30
30
  /** @type {import('./cyberia-action.model.js').CyberiaActionModel} */
31
- const CyberiaAction = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaAction;
31
+ const CyberiaAction = DataBaseProviderService.getModel("CyberiaAction", options);
32
32
  return await CyberiaAction.findByIdAndUpdate(req.params.id, req.body);
33
33
  };
34
34
  static delete = async (req, res, options) => {
35
35
  /** @type {import('./cyberia-action.model.js').CyberiaActionModel} */
36
- const CyberiaAction = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaAction;
36
+ const CyberiaAction = DataBaseProviderService.getModel("CyberiaAction", options);
37
37
  if (req.params.id) return await CyberiaAction.findByIdAndDelete(req.params.id);
38
38
  else return await CyberiaAction.deleteMany();
39
39
  };
@@ -0,0 +1,74 @@
1
+ import { loggerFactory } from '../../server/logger.js';
2
+ import { CyberiaClientHintsService } from './cyberia-client-hints.service.js';
3
+
4
+ const logger = loggerFactory(import.meta);
5
+
6
+ class CyberiaClientHintsController {
7
+ static post = async (req, res, options) => {
8
+ try {
9
+ const result = await CyberiaClientHintsService.post(req, res, options);
10
+ return res.status(200).json({
11
+ status: 'success',
12
+ data: result,
13
+ });
14
+ } catch (error) {
15
+ logger.error(error, error.stack);
16
+ return res.status(400).json({
17
+ status: 'error',
18
+ message: error.message,
19
+ });
20
+ }
21
+ };
22
+ static get = async (req, res, options) => {
23
+ try {
24
+ const { page, limit } = req.query;
25
+ const result = await CyberiaClientHintsService.get(
26
+ { ...req, query: { ...req.query, page: parseInt(page), limit: parseInt(limit) } },
27
+ res,
28
+ options,
29
+ );
30
+ return res.status(200).json({
31
+ status: 'success',
32
+ data: result,
33
+ });
34
+ } catch (error) {
35
+ logger.error(error, error.stack);
36
+ return res.status(400).json({
37
+ status: 'error',
38
+ message: error.message,
39
+ });
40
+ }
41
+ };
42
+ static put = async (req, res, options) => {
43
+ try {
44
+ const result = await CyberiaClientHintsService.put(req, res, options);
45
+ return res.status(200).json({
46
+ status: 'success',
47
+ data: result,
48
+ });
49
+ } catch (error) {
50
+ logger.error(error, error.stack);
51
+ return res.status(400).json({
52
+ status: 'error',
53
+ message: error.message,
54
+ });
55
+ }
56
+ };
57
+ static delete = async (req, res, options) => {
58
+ try {
59
+ const result = await CyberiaClientHintsService.delete(req, res, options);
60
+ return res.status(200).json({
61
+ status: 'success',
62
+ data: result,
63
+ });
64
+ } catch (error) {
65
+ logger.error(error, error.stack);
66
+ return res.status(400).json({
67
+ status: 'error',
68
+ message: error.message,
69
+ });
70
+ }
71
+ };
72
+ }
73
+
74
+ export { CyberiaClientHintsController };
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Mongoose model for `CyberiaClientHints`.
3
+ *
4
+ * Dedicated collection for per-instance presentation overrides.
5
+ *
6
+ * Ownership:
7
+ * - Read by: cyberia-client (via /api/cyberia-client-hints/:code), CMS UIs.
8
+ * - Written by: CMS / editor flows. The Cyberia simulation server
9
+ * never reads or writes this collection.
10
+ * - Cacheable: yes — the service layer keeps an in-memory TTL cache.
11
+ *
12
+ * Schema scope: purely visual fields. Anything that influences simulation
13
+ * belongs in `CyberiaInstanceConf`.
14
+ *
15
+ * @module src/api/cyberia-client-hints/cyberia-client-hints.model.js
16
+ */
17
+
18
+ import { Schema, model } from 'mongoose';
19
+
20
+ const ColorRgbaSchema = new Schema(
21
+ {
22
+ r: { type: Number, default: 0 },
23
+ g: { type: Number, default: 0 },
24
+ b: { type: Number, default: 0 },
25
+ a: { type: Number, default: 255 },
26
+ },
27
+ { _id: false },
28
+ );
29
+
30
+ const PaletteEntrySchema = new Schema(
31
+ {
32
+ key: { type: String, required: true },
33
+ r: { type: Number, default: 0 },
34
+ g: { type: Number, default: 0 },
35
+ b: { type: Number, default: 0 },
36
+ a: { type: Number, default: 255 },
37
+ },
38
+ { _id: false },
39
+ );
40
+
41
+ const StatusIconHintSchema = new Schema(
42
+ {
43
+ id: { type: Number, required: true },
44
+ iconId: { type: String, default: '' },
45
+ bounce: { type: Boolean, default: false },
46
+ borderColor: { type: ColorRgbaSchema, default: () => ({ r: 100, g: 100, b: 100, a: 200 }) },
47
+ },
48
+ { _id: false },
49
+ );
50
+
51
+ const EntityColorKeySchema = new Schema(
52
+ {
53
+ entityType: { type: String, required: true },
54
+ colorKey: { type: String, required: true },
55
+ },
56
+ { _id: false },
57
+ );
58
+
59
+ const CyberiaClientHintsSchema = new Schema(
60
+ {
61
+ // Instance code this hint set is scoped to. Matches CyberiaInstance.code
62
+ // and CyberiaInstanceConf.instanceCode. Indexed and unique to make the
63
+ // service-layer cache a 1-to-1 keyed lookup.
64
+ code: { type: String, required: true, unique: true, index: true },
65
+
66
+ // Optional palette overrides. Keys not present here fall back to the
67
+ // client's compile-time defaults.
68
+ palette: { type: [PaletteEntrySchema], default: [] },
69
+
70
+ // Optional per-entity-type color-key overrides.
71
+ entityColorKeys: { type: [EntityColorKeySchema], default: [] },
72
+
73
+ // Optional status-icon visual overrides (id → iconId + borderColor).
74
+ statusIcons: { type: [StatusIconHintSchema], default: [] },
75
+
76
+ // Camera, viewport, and cell-sizing tunings — null/undefined means
77
+ // "use the SharedDefaultsCyberia.RENDER_DEFAULTS value".
78
+ cellSize: { type: Number, default: null },
79
+ defaultObjWidth: { type: Number, default: null },
80
+ defaultObjHeight: { type: Number, default: null },
81
+ cameraSmoothing: { type: Number, default: null },
82
+ cameraZoom: { type: Number, default: null },
83
+ defaultWidthScreenFactor: { type: Number, default: null },
84
+ defaultHeightScreenFactor: { type: Number, default: null },
85
+ interpolationMs: { type: Number, default: null },
86
+ devUi: { type: Boolean, default: null },
87
+ },
88
+ { timestamps: true },
89
+ );
90
+
91
+ const CyberiaClientHintsModel = model('CyberiaClientHints', CyberiaClientHintsSchema);
92
+
93
+ const ProviderSchema = CyberiaClientHintsSchema;
94
+
95
+ export {
96
+ CyberiaClientHintsSchema,
97
+ CyberiaClientHintsModel,
98
+ ProviderSchema,
99
+ };