cyberia 3.2.5 → 3.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/.github/workflows/engine-cyberia.cd.yml +2 -2
  2. package/.github/workflows/release.cd.yml +1 -2
  3. package/CHANGELOG.md +351 -1
  4. package/CLI-HELP.md +40 -13
  5. package/Dockerfile +0 -4
  6. package/README.md +242 -497
  7. package/bin/build.js +19 -5
  8. package/bin/cyberia.js +1149 -240
  9. package/bin/deploy.js +570 -1
  10. package/bin/file.js +6 -0
  11. package/bin/index.js +1149 -240
  12. package/bin/vs.js +1 -1
  13. package/conf.js +67 -89
  14. package/deployment.yaml +4 -222
  15. package/hardhat/package-lock.json +32 -32
  16. package/hardhat/package.json +3 -3
  17. package/jsconfig.json +1 -1
  18. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -2
  19. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +2 -2
  20. package/manifests/deployment/dd-cyberia-development/deployment.yaml +4 -222
  21. package/manifests/deployment/dd-cyberia-development/proxy.yaml +10 -118
  22. package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
  23. package/manifests/deployment/dd-test-development/deployment.yaml +136 -66
  24. package/manifests/deployment/dd-test-development/proxy.yaml +41 -5
  25. package/package.json +23 -14
  26. package/proxy.yaml +10 -118
  27. package/scripts/k3s-node-setup.sh +2 -2
  28. package/scripts/nat-iptables.sh +103 -18
  29. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +18 -18
  30. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +7 -14
  31. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +76 -21
  32. package/src/api/core/core.controller.js +10 -10
  33. package/src/api/core/core.service.js +10 -10
  34. package/src/api/crypto/crypto.controller.js +8 -8
  35. package/src/api/crypto/crypto.service.js +8 -8
  36. package/src/api/cyberia-action/cyberia-action.controller.js +74 -0
  37. package/src/api/cyberia-action/cyberia-action.model.js +87 -0
  38. package/src/api/cyberia-action/cyberia-action.router.js +27 -0
  39. package/src/api/cyberia-action/cyberia-action.service.js +42 -0
  40. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +13 -13
  41. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +11 -11
  42. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +2 -2
  43. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +16 -16
  44. package/src/api/cyberia-entity/cyberia-entity.controller.js +10 -10
  45. package/src/api/cyberia-entity/cyberia-entity.service.js +10 -10
  46. package/src/api/cyberia-instance/cyberia-fallback-world.js +19 -209
  47. package/src/api/cyberia-instance/cyberia-instance.controller.js +14 -14
  48. package/src/api/cyberia-instance/cyberia-instance.model.js +3 -0
  49. package/src/api/cyberia-instance/cyberia-instance.service.js +22 -57
  50. package/src/api/cyberia-instance/cyberia-portal-connector.js +20 -246
  51. package/src/api/cyberia-instance/cyberia-world-generator.js +505 -0
  52. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +10 -10
  53. package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +216 -55
  54. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +4 -1
  55. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +18 -14
  56. package/src/api/cyberia-map/cyberia-map.controller.js +10 -10
  57. package/src/api/cyberia-map/cyberia-map.service.js +10 -10
  58. package/src/api/cyberia-quest/cyberia-quest.controller.js +74 -0
  59. package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
  60. package/src/api/cyberia-quest/cyberia-quest.router.js +27 -0
  61. package/src/api/cyberia-quest/cyberia-quest.service.js +42 -0
  62. package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +74 -0
  63. package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
  64. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +27 -0
  65. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
  66. package/src/api/default/default.controller.js +10 -10
  67. package/src/api/default/default.service.js +10 -10
  68. package/src/api/document/document.controller.js +12 -12
  69. package/src/api/document/document.model.js +10 -16
  70. package/src/api/file/file.controller.js +8 -8
  71. package/src/api/file/file.model.js +10 -10
  72. package/src/api/file/file.service.js +36 -36
  73. package/src/api/instance/instance.controller.js +10 -10
  74. package/src/api/instance/instance.model.js +4 -10
  75. package/src/api/instance/instance.service.js +10 -10
  76. package/src/api/ipfs/ipfs.controller.js +12 -12
  77. package/src/api/ipfs/ipfs.model.js +4 -13
  78. package/src/api/ipfs/ipfs.service.js +14 -28
  79. package/src/api/object-layer/object-layer.controller.js +12 -12
  80. package/src/api/object-layer/object-layer.model.js +4 -17
  81. package/src/api/object-layer/object-layer.service.js +12 -12
  82. package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +10 -10
  83. package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +6 -16
  84. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +18 -14
  85. package/src/api/test/test.controller.js +8 -8
  86. package/src/api/test/test.service.js +8 -8
  87. package/src/api/user/guest.service.js +99 -0
  88. package/src/api/user/user.controller.js +6 -6
  89. package/src/api/user/user.model.js +8 -13
  90. package/src/api/user/user.service.js +3 -20
  91. package/src/cli/cluster.js +61 -14
  92. package/src/cli/db.js +47 -2
  93. package/src/cli/deploy.js +67 -35
  94. package/src/cli/fs.js +79 -8
  95. package/src/cli/image.js +43 -1
  96. package/src/cli/index.js +26 -1
  97. package/src/cli/release.js +57 -1
  98. package/src/cli/repository.js +69 -31
  99. package/src/cli/run.js +415 -36
  100. package/src/cli/ssh.js +1 -1
  101. package/src/cli/static.js +43 -115
  102. package/src/client/Cryptokoyn.index.js +18 -21
  103. package/src/client/CyberiaPortal.index.js +19 -23
  104. package/src/client/Default.index.js +21 -33
  105. package/src/client/Itemledger.index.js +20 -26
  106. package/src/client/Underpost.index.js +19 -23
  107. package/src/client/components/core/404.js +4 -4
  108. package/src/client/components/core/500.js +4 -4
  109. package/src/client/components/core/Account.js +73 -60
  110. package/src/client/components/core/AgGrid.js +23 -33
  111. package/src/client/components/core/Alert.js +12 -13
  112. package/src/client/components/core/AppStore.js +1 -1
  113. package/src/client/components/core/Auth.js +35 -37
  114. package/src/client/components/core/Badge.js +7 -13
  115. package/src/client/components/core/BtnIcon.js +15 -17
  116. package/src/client/components/core/CalendarCore.js +42 -63
  117. package/src/client/components/core/Chat.js +13 -15
  118. package/src/client/components/core/ClientEvents.js +87 -0
  119. package/src/client/components/core/ColorPaletteElement.js +309 -0
  120. package/src/client/components/core/Content.js +17 -14
  121. package/src/client/components/core/Css.js +15 -71
  122. package/src/client/components/core/CssCore.js +12 -16
  123. package/src/client/components/core/D3Chart.js +4 -4
  124. package/src/client/components/core/Docs.js +64 -91
  125. package/src/client/components/core/DropDown.js +69 -91
  126. package/src/client/components/core/EventBus.js +92 -0
  127. package/src/client/components/core/EventsUI.js +14 -17
  128. package/src/client/components/core/FileExplorer.js +96 -228
  129. package/src/client/components/core/FullScreen.js +47 -75
  130. package/src/client/components/core/Input.js +24 -69
  131. package/src/client/components/core/Keyboard.js +25 -18
  132. package/src/client/components/core/KeyboardAvoidance.js +145 -0
  133. package/src/client/components/core/LoadingAnimation.js +25 -31
  134. package/src/client/components/core/LogIn.js +41 -41
  135. package/src/client/components/core/LogOut.js +23 -14
  136. package/src/client/components/core/Modal.js +462 -178
  137. package/src/client/components/core/NotificationManager.js +14 -18
  138. package/src/client/components/core/Panel.js +54 -50
  139. package/src/client/components/core/PanelForm.js +25 -125
  140. package/src/client/components/core/Polyhedron.js +110 -214
  141. package/src/client/components/core/PublicProfile.js +39 -32
  142. package/src/client/components/core/Recover.js +48 -44
  143. package/src/client/components/core/Responsive.js +88 -32
  144. package/src/client/components/core/RichText.js +9 -18
  145. package/src/client/components/core/Router.js +24 -3
  146. package/src/client/components/core/SearchBox.js +37 -37
  147. package/src/client/components/core/SignUp.js +39 -30
  148. package/src/client/components/core/SocketIo.js +31 -2
  149. package/src/client/components/core/SocketIoHandler.js +6 -6
  150. package/src/client/components/core/ToggleSwitch.js +8 -20
  151. package/src/client/components/core/ToolTip.js +5 -17
  152. package/src/client/components/core/Translate.js +56 -59
  153. package/src/client/components/core/Validator.js +26 -16
  154. package/src/client/components/core/Wallet.js +15 -26
  155. package/src/client/components/core/Worker.js +163 -27
  156. package/src/client/components/core/windowGetDimensions.js +7 -7
  157. package/src/client/components/cryptokoyn/{MenuCryptokoyn.js → AppShellCryptokoyn.js} +57 -57
  158. package/src/client/components/cryptokoyn/CssCryptokoyn.js +15 -15
  159. package/src/client/components/cryptokoyn/LogInCryptokoyn.js +6 -4
  160. package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +6 -4
  161. package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
  162. package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +4 -4
  163. package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +6 -4
  164. package/src/client/components/cyberia/InstanceEngineCyberia.js +141 -60
  165. package/src/client/components/cyberia/MapEngineCyberia.js +691 -214
  166. package/src/client/components/cyberia/ObjectLayerEngine.js +19 -0
  167. package/src/client/components/cyberia/ObjectLayerEngineModal.js +1204 -94
  168. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +196 -298
  169. package/src/client/components/cyberia-portal/{MenuCyberiaPortal.js → AppShellCyberiaPortal.js} +102 -102
  170. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +305 -61
  171. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +15 -15
  172. package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +6 -4
  173. package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +6 -4
  174. package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +4 -4
  175. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +60 -0
  176. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +4 -4
  177. package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +6 -4
  178. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +4 -4
  179. package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +87 -87
  180. package/src/client/components/default/CssDefault.js +12 -12
  181. package/src/client/components/default/LogInDefault.js +6 -4
  182. package/src/client/components/default/LogOutDefault.js +6 -4
  183. package/src/client/components/default/RouterDefault.js +47 -0
  184. package/src/client/components/default/SettingsDefault.js +4 -4
  185. package/src/client/components/default/SignUpDefault.js +6 -4
  186. package/src/client/components/default/TranslateDefault.js +3 -3
  187. package/src/client/components/itemledger/{MenuItemledger.js → AppShellItemledger.js} +57 -57
  188. package/src/client/components/itemledger/CssItemledger.js +15 -15
  189. package/src/client/components/itemledger/LogInItemledger.js +6 -4
  190. package/src/client/components/itemledger/LogOutItemledger.js +6 -4
  191. package/src/client/components/itemledger/RouterItemledger.js +38 -0
  192. package/src/client/components/itemledger/SettingsItemledger.js +4 -4
  193. package/src/client/components/itemledger/SignUpItemledger.js +6 -4
  194. package/src/client/components/itemledger/TranslateItemledger.js +3 -3
  195. package/src/client/components/underpost/{MenuUnderpost.js → AppShellUnderpost.js} +88 -88
  196. package/src/client/components/underpost/CssUnderpost.js +14 -14
  197. package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +4 -4
  198. package/src/client/components/underpost/DocumentSearchProvider.js +1 -1
  199. package/src/client/components/underpost/LabGalleryUnderpost.js +12 -15
  200. package/src/client/components/underpost/LogInUnderpost.js +6 -4
  201. package/src/client/components/underpost/LogOutUnderpost.js +6 -4
  202. package/src/client/components/underpost/RouterUnderpost.js +45 -0
  203. package/src/client/components/underpost/SettingsUnderpost.js +4 -4
  204. package/src/client/components/underpost/SignUpUnderpost.js +6 -4
  205. package/src/client/components/underpost/TranslateUnderpost.js +4 -4
  206. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +235 -0
  207. package/src/client/public/cyberia-docs/ARCHITECTURE.md +443 -0
  208. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +417 -0
  209. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +313 -0
  210. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +260 -0
  211. package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +241 -0
  212. package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
  213. package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +279 -0
  214. package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +206 -0
  215. package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
  216. package/src/client/public/cyberia-docs/WHITE-PAPER.md +732 -0
  217. package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +14 -20
  218. package/src/client/services/core/core.service.js +17 -49
  219. package/src/client/services/crypto/crypto.service.js +8 -13
  220. package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
  221. package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +10 -16
  222. package/src/client/services/cyberia-entity/cyberia-entity.management.js +5 -5
  223. package/src/client/services/cyberia-entity/cyberia-entity.service.js +10 -16
  224. package/src/client/services/cyberia-instance/cyberia-instance.management.js +6 -6
  225. package/src/client/services/cyberia-instance/cyberia-instance.service.js +12 -18
  226. package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +10 -16
  227. package/src/client/services/cyberia-map/cyberia-map.management.js +6 -6
  228. package/src/client/services/cyberia-map/cyberia-map.service.js +12 -18
  229. package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
  230. package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
  231. package/src/client/services/default/default.management.js +159 -267
  232. package/src/client/services/default/default.service.js +10 -16
  233. package/src/client/services/document/document.service.js +14 -19
  234. package/src/client/services/file/file.service.js +8 -13
  235. package/src/client/services/instance/instance.management.js +5 -5
  236. package/src/client/services/instance/instance.service.js +10 -15
  237. package/src/client/services/ipfs/ipfs.service.js +12 -18
  238. package/src/client/services/object-layer/object-layer.management.js +12 -12
  239. package/src/client/services/object-layer/object-layer.service.js +20 -26
  240. package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +10 -16
  241. package/src/client/services/test/test.service.js +8 -13
  242. package/src/client/services/user/guest.service.js +86 -0
  243. package/src/client/services/user/user.management.js +5 -5
  244. package/src/client/services/user/user.service.js +14 -20
  245. package/src/client/ssr/body/404.js +3 -3
  246. package/src/client/ssr/body/500.js +3 -3
  247. package/src/client/ssr/body/CacheControl.js +5 -2
  248. package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
  249. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +13 -6
  250. package/src/client/ssr/head/PwaItemledger.js +197 -60
  251. package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
  252. package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
  253. package/src/client/ssr/offline/Maintenance.js +12 -11
  254. package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
  255. package/src/client/ssr/pages/Test.js +2 -2
  256. package/src/client/sw/core.sw.js +212 -0
  257. package/src/grpc/cyberia/grpc-server.js +179 -67
  258. package/src/index.js +1 -1
  259. package/src/runtime/cyberia-client/Dockerfile +80 -0
  260. package/src/runtime/cyberia-server/Dockerfile +37 -0
  261. package/src/runtime/express/Dockerfile +4 -4
  262. package/src/runtime/lampp/Dockerfile +8 -7
  263. package/src/runtime/wp/Dockerfile +11 -17
  264. package/src/server/atlas-sprite-sheet-generator.js +4 -2
  265. package/src/server/client-build-docs.js +45 -46
  266. package/src/server/client-build.js +334 -60
  267. package/src/server/client-formatted.js +47 -16
  268. package/src/server/conf.js +5 -4
  269. package/src/server/data-query.js +32 -20
  270. package/src/server/dns.js +22 -0
  271. package/src/server/ipfs-client.js +232 -91
  272. package/src/server/object-layer.js +1 -6
  273. package/src/server/process.js +13 -27
  274. package/src/server/semantic-layer-generator-floor.js +11 -51
  275. package/src/server/semantic-layer-generator-resource.js +259 -0
  276. package/src/server/semantic-layer-generator-skin.js +41 -171
  277. package/src/server/semantic-layer-generator.js +122 -14
  278. package/src/server/shape-generator.js +108 -0
  279. package/src/server/start.js +17 -3
  280. package/src/server/valkey.js +141 -235
  281. package/tsconfig.docs.json +15 -0
  282. package/typedoc.dd-cyberia.json +29 -0
  283. package/typedoc.json +29 -0
  284. package/WHITE-PAPER.md +0 -1540
  285. package/hardhat/README.md +0 -531
  286. package/hardhat/WHITE-PAPER.md +0 -1540
  287. package/jsdoc.dd-cyberia.json +0 -68
  288. package/jsdoc.json +0 -68
  289. package/src/api/object-layer/README.md +0 -672
  290. package/src/client/components/core/ColorPalette.js +0 -5267
  291. package/src/client/components/core/JoyStick.js +0 -80
  292. package/src/client/components/cryptokoyn/RoutesCryptokoyn.js +0 -39
  293. package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +0 -62
  294. package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +0 -136
  295. package/src/client/components/default/RoutesDefault.js +0 -49
  296. package/src/client/components/itemledger/RoutesItemledger.js +0 -40
  297. package/src/client/components/underpost/RoutesUnderpost.js +0 -47
  298. package/src/client/sw/default.sw.js +0 -127
  299. package/src/client/sw/template.sw.js +0 -84
  300. package/src/grpc/cyberia/OFF_CHAIN_ECONOMY.md +0 -305
  301. package/src/grpc/cyberia/README.md +0 -326
@@ -0,0 +1,67 @@
1
+ import { Schema, model } from 'mongoose';
2
+ import { QUEST_STEPS_TYPES } from '../../client/components/cyberia-portal/CommonCyberiaPortal.js';
3
+
4
+ // https://mongoosejs.com/docs/2.7.x/docs/schematypes.html
5
+
6
+ const CyberiaQuestSchema = new Schema(
7
+ {
8
+ // Spatial origin: the NPC/entity cell that grants this quest.
9
+ // Matched against map entity initCellX/initCellY during instance init
10
+ // and assignable from ObjectLayerEngineModal.
11
+ sourceMapCode: { type: String, trim: true },
12
+ sourceCellX: { type: Number },
13
+ sourceCellY: { type: Number },
14
+
15
+ // Stable slug, e.g. "fallback-intro-quest"
16
+ code: { type: String, required: true, trim: true },
17
+ title: { type: String, required: true, trim: true },
18
+ description: { type: String, default: '' },
19
+
20
+ // ── Chain / tree unlock structure ─────────────────────────────────────
21
+ // All listed quest codes must be completed before this quest becomes
22
+ // available (AND logic). Empty array = no prerequisites.
23
+ prerequisiteCodes: { type: [String], default: [] },
24
+
25
+ // Quest codes unlocked when this quest is completed.
26
+ // Supports both chain (one successor) and tree (multiple successors).
27
+ // The server re-checks prerequisiteCodes on each target before activating it.
28
+ unlocksQuestCodes: { type: [String], default: [] },
29
+
30
+ // ── Steps ─────────────────────────────────────────────────────────────
31
+ // Ordered linear sequence. The active step is always the first incomplete one.
32
+ steps: [
33
+ {
34
+ id: { type: String, required: true },
35
+ description: { type: String, default: '' },
36
+ objectives: [
37
+ {
38
+ // collect — itemId = item that must appear in the player's inventory
39
+ // talk — itemId = provideItemId of the CyberiaAction to interact with
40
+ // kill — itemId = skin item ID of the target entity
41
+ type: { type: String, required: true, enum: QUEST_STEPS_TYPES },
42
+ itemId: { type: String, required: true, trim: true },
43
+ quantity: { type: Number, default: 1, min: 1 },
44
+ },
45
+ ],
46
+ },
47
+ ],
48
+
49
+ // ── Rewards ───────────────────────────────────────────────────────────
50
+ rewards: [
51
+ {
52
+ itemId: { type: String, required: true, trim: true },
53
+ quantity: { type: Number, default: 1, min: 1 },
54
+ },
55
+ ],
56
+ },
57
+ { timestamps: true },
58
+ );
59
+
60
+ CyberiaQuestSchema.index({ code: 1 }, { unique: true });
61
+ CyberiaQuestSchema.index({ sourceMapCode: 1, sourceCellX: 1, sourceCellY: 1 });
62
+
63
+ const CyberiaQuestModel = model('CyberiaQuest', CyberiaQuestSchema);
64
+
65
+ const ProviderSchema = CyberiaQuestSchema;
66
+
67
+ export { CyberiaQuestSchema, CyberiaQuestModel, ProviderSchema };
@@ -0,0 +1,27 @@
1
+ import { loggerFactory } from '../../server/logger.js';
2
+ import { CyberiaQuestController } from './cyberia-quest.controller.js';
3
+ import express from 'express';
4
+
5
+ const logger = loggerFactory(import.meta);
6
+
7
+ const CyberiaQuestRouter = (options) => {
8
+ const router = express.Router();
9
+ const authMiddleware = options.authMiddleware;
10
+ router.post(`/:id`, async (req, res) => await CyberiaQuestController.post(req, res, options));
11
+ router.post(`/`, async (req, res) => await CyberiaQuestController.post(req, res, options));
12
+ router.get(
13
+ `/:id`,
14
+ // authMiddleware,
15
+ async (req, res) => await CyberiaQuestController.get(req, res, options),
16
+ );
17
+ router.get(`/`, async (req, res) => await CyberiaQuestController.get(req, res, options));
18
+ router.put(`/:id`, async (req, res) => await CyberiaQuestController.put(req, res, options));
19
+ router.put(`/`, async (req, res) => await CyberiaQuestController.put(req, res, options));
20
+ router.delete(`/:id`, async (req, res) => await CyberiaQuestController.delete(req, res, options));
21
+ router.delete(`/`, async (req, res) => await CyberiaQuestController.delete(req, res, options));
22
+ return router;
23
+ };
24
+
25
+ const ApiRouter = CyberiaQuestRouter;
26
+
27
+ export { ApiRouter, CyberiaQuestRouter };
@@ -0,0 +1,42 @@
1
+ import { DataBaseProvider } from '../../db/DataBaseProvider.js';
2
+ import { loggerFactory } from '../../server/logger.js';
3
+ import { DataQuery } from '../../server/data-query.js';
4
+
5
+ const logger = loggerFactory(import.meta);
6
+
7
+ class CyberiaQuestService {
8
+ static post = async (req, res, options) => {
9
+ /** @type {import('./cyberia-quest.model.js').CyberiaQuestModel} */
10
+ const CyberiaQuest = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaQuest;
11
+ return await new CyberiaQuest(req.body).save();
12
+ };
13
+ static get = async (req, res, options) => {
14
+ /** @type {import('./cyberia-quest.model.js').CyberiaQuestModel} */
15
+ const CyberiaQuest = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaQuest;
16
+ if (req.params.id) return await CyberiaQuest.findById(req.params.id);
17
+
18
+ // Parse query parameters using DataQuery helper
19
+ const { query, sort, skip, limit, page } = DataQuery.parse(req.query);
20
+
21
+ const [data, total] = await Promise.all([
22
+ CyberiaQuest.find(query).sort(sort).limit(limit).skip(skip),
23
+ CyberiaQuest.countDocuments(query),
24
+ ]);
25
+
26
+ const totalPages = Math.ceil(total / limit);
27
+ return { data, total, page, totalPages };
28
+ };
29
+ static put = async (req, res, options) => {
30
+ /** @type {import('./cyberia-quest.model.js').CyberiaQuestModel} */
31
+ const CyberiaQuest = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaQuest;
32
+ return await CyberiaQuest.findByIdAndUpdate(req.params.id, req.body);
33
+ };
34
+ static delete = async (req, res, options) => {
35
+ /** @type {import('./cyberia-quest.model.js').CyberiaQuestModel} */
36
+ const CyberiaQuest = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaQuest;
37
+ if (req.params.id) return await CyberiaQuest.findByIdAndDelete(req.params.id);
38
+ else return await CyberiaQuest.deleteMany();
39
+ };
40
+ }
41
+
42
+ export { CyberiaQuestService };
@@ -0,0 +1,74 @@
1
+ import { loggerFactory } from '../../server/logger.js';
2
+ import { CyberiaQuestProgressService } from './cyberia-quest-progress.service.js';
3
+
4
+ const logger = loggerFactory(import.meta);
5
+
6
+ class CyberiaQuestProgressController {
7
+ static post = async (req, res, options) => {
8
+ try {
9
+ const result = await CyberiaQuestProgressService.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 CyberiaQuestProgressService.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 CyberiaQuestProgressService.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 CyberiaQuestProgressService.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 { CyberiaQuestProgressController };
@@ -0,0 +1,49 @@
1
+ import { Schema, model } from 'mongoose';
2
+
3
+ // https://mongoosejs.com/docs/2.7.x/docs/schematypes.html
4
+
5
+ const CyberiaQuestProgressSchema = new Schema(
6
+ {
7
+ // Matches the Go relay server's player UUID
8
+ playerId: { type: String, required: true, trim: true },
9
+ // References CyberiaQuest.code
10
+ questCode: { type: String, required: true, trim: true },
11
+ // active | completed
12
+ // Quests do not fail — they stay active until completed or abandoned by the player.
13
+ status: {
14
+ type: String,
15
+ required: true,
16
+ enum: ['active', 'completed'],
17
+ default: 'active',
18
+ },
19
+ // One entry per step in the corresponding CyberiaQuest.steps[].
20
+ // A step is complete when all its objectiveProgress entries satisfy current >= required.
21
+ // The active step is the first step where not all objectives are done.
22
+ // done flags are intentionally omitted — completeness is always computed, never stored.
23
+ stepProgress: [
24
+ {
25
+ stepId: { type: String, required: true },
26
+ // One entry per objective in CyberiaQuest.steps[i].objectives[].
27
+ // `required` is denormalized from the quest definition for efficient server checks.
28
+ objectiveProgress: [
29
+ {
30
+ current: { type: Number, default: 0, min: 0 },
31
+ required: { type: Number, default: 1, min: 1 },
32
+ },
33
+ ],
34
+ },
35
+ ],
36
+ startedAt: { type: Date, default: Date.now },
37
+ completedAt: { type: Date, default: null },
38
+ },
39
+ { timestamps: true },
40
+ );
41
+
42
+ CyberiaQuestProgressSchema.index({ playerId: 1, questCode: 1 }, { unique: true });
43
+ CyberiaQuestProgressSchema.index({ playerId: 1, status: 1 });
44
+
45
+ const CyberiaQuestProgressModel = model('CyberiaQuestProgress', CyberiaQuestProgressSchema);
46
+
47
+ const ProviderSchema = CyberiaQuestProgressSchema;
48
+
49
+ export { CyberiaQuestProgressSchema, CyberiaQuestProgressModel, ProviderSchema };
@@ -0,0 +1,27 @@
1
+ import { loggerFactory } from '../../server/logger.js';
2
+ import { CyberiaQuestProgressController } from './cyberia-quest-progress.controller.js';
3
+ import express from 'express';
4
+
5
+ const logger = loggerFactory(import.meta);
6
+
7
+ const CyberiaQuestProgressRouter = (options) => {
8
+ const router = express.Router();
9
+ const authMiddleware = options.authMiddleware;
10
+ router.post(`/:id`, async (req, res) => await CyberiaQuestProgressController.post(req, res, options));
11
+ router.post(`/`, async (req, res) => await CyberiaQuestProgressController.post(req, res, options));
12
+ router.get(
13
+ `/:id`,
14
+ // authMiddleware,
15
+ async (req, res) => await CyberiaQuestProgressController.get(req, res, options),
16
+ );
17
+ router.get(`/`, async (req, res) => await CyberiaQuestProgressController.get(req, res, options));
18
+ router.put(`/:id`, async (req, res) => await CyberiaQuestProgressController.put(req, res, options));
19
+ router.put(`/`, async (req, res) => await CyberiaQuestProgressController.put(req, res, options));
20
+ router.delete(`/:id`, async (req, res) => await CyberiaQuestProgressController.delete(req, res, options));
21
+ router.delete(`/`, async (req, res) => await CyberiaQuestProgressController.delete(req, res, options));
22
+ return router;
23
+ };
24
+
25
+ const ApiRouter = CyberiaQuestProgressRouter;
26
+
27
+ export { ApiRouter, CyberiaQuestProgressRouter };
@@ -0,0 +1,42 @@
1
+ import { DataBaseProvider } from '../../db/DataBaseProvider.js';
2
+ import { loggerFactory } from '../../server/logger.js';
3
+ import { DataQuery } from '../../server/data-query.js';
4
+
5
+ const logger = loggerFactory(import.meta);
6
+
7
+ class CyberiaQuestProgressService {
8
+ static post = async (req, res, options) => {
9
+ /** @type {import('./cyberia-quest-progress.model.js').CyberiaQuestProgressModel} */
10
+ const CyberiaQuestProgress = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaQuestProgress;
11
+ return await new CyberiaQuestProgress(req.body).save();
12
+ };
13
+ static get = async (req, res, options) => {
14
+ /** @type {import('./cyberia-quest-progress.model.js').CyberiaQuestProgressModel} */
15
+ const CyberiaQuestProgress = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaQuestProgress;
16
+ if (req.params.id) return await CyberiaQuestProgress.findById(req.params.id);
17
+
18
+ // Parse query parameters using DataQuery helper
19
+ const { query, sort, skip, limit, page } = DataQuery.parse(req.query);
20
+
21
+ const [data, total] = await Promise.all([
22
+ CyberiaQuestProgress.find(query).sort(sort).limit(limit).skip(skip),
23
+ CyberiaQuestProgress.countDocuments(query),
24
+ ]);
25
+
26
+ const totalPages = Math.ceil(total / limit);
27
+ return { data, total, page, totalPages };
28
+ };
29
+ static put = async (req, res, options) => {
30
+ /** @type {import('./cyberia-quest-progress.model.js').CyberiaQuestProgressModel} */
31
+ const CyberiaQuestProgress = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaQuestProgress;
32
+ return await CyberiaQuestProgress.findByIdAndUpdate(req.params.id, req.body);
33
+ };
34
+ static delete = async (req, res, options) => {
35
+ /** @type {import('./cyberia-quest-progress.model.js').CyberiaQuestProgressModel} */
36
+ const CyberiaQuestProgress = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaQuestProgress;
37
+ if (req.params.id) return await CyberiaQuestProgress.findByIdAndDelete(req.params.id);
38
+ else return await CyberiaQuestProgress.deleteMany();
39
+ };
40
+ }
41
+
42
+ export { CyberiaQuestProgressService };
@@ -3,8 +3,8 @@ import { DefaultService } from './default.service.js';
3
3
 
4
4
  const logger = loggerFactory(import.meta);
5
5
 
6
- const DefaultController = {
7
- post: async (req, res, options) => {
6
+ class DefaultController {
7
+ static post = async (req, res, options) => {
8
8
  try {
9
9
  const result = await DefaultService.post(req, res, options);
10
10
  return res.status(200).json({
@@ -18,8 +18,8 @@ const DefaultController = {
18
18
  message: error.message,
19
19
  });
20
20
  }
21
- },
22
- get: async (req, res, options) => {
21
+ };
22
+ static get = async (req, res, options) => {
23
23
  try {
24
24
  const { page, limit } = req.query;
25
25
  const result = await DefaultService.get(
@@ -38,8 +38,8 @@ const DefaultController = {
38
38
  message: error.message,
39
39
  });
40
40
  }
41
- },
42
- put: async (req, res, options) => {
41
+ };
42
+ static put = async (req, res, options) => {
43
43
  try {
44
44
  const result = await DefaultService.put(req, res, options);
45
45
  return res.status(200).json({
@@ -53,8 +53,8 @@ const DefaultController = {
53
53
  message: error.message,
54
54
  });
55
55
  }
56
- },
57
- delete: async (req, res, options) => {
56
+ };
57
+ static delete = async (req, res, options) => {
58
58
  try {
59
59
  const result = await DefaultService.delete(req, res, options);
60
60
  return res.status(200).json({
@@ -68,7 +68,7 @@ const DefaultController = {
68
68
  message: error.message,
69
69
  });
70
70
  }
71
- },
72
- };
71
+ };
72
+ }
73
73
 
74
74
  export { DefaultController };
@@ -4,13 +4,13 @@ import { DataQuery } from '../../server/data-query.js';
4
4
 
5
5
  const logger = loggerFactory(import.meta);
6
6
 
7
- const DefaultService = {
8
- post: async (req, res, options) => {
7
+ class DefaultService {
8
+ static post = async (req, res, options) => {
9
9
  /** @type {import('./default.model.js').DefaultModel} */
10
10
  const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Default;
11
11
  return await new Default(req.body).save();
12
- },
13
- get: async (req, res, options) => {
12
+ };
13
+ static get = async (req, res, options) => {
14
14
  /** @type {import('./default.model.js').DefaultModel} */
15
15
  const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Default;
16
16
  if (req.params.id) return await Default.findById(req.params.id);
@@ -25,18 +25,18 @@ const DefaultService = {
25
25
 
26
26
  const totalPages = Math.ceil(total / limit);
27
27
  return { data, total, page, totalPages };
28
- },
29
- put: async (req, res, options) => {
28
+ };
29
+ static put = async (req, res, options) => {
30
30
  /** @type {import('./default.model.js').DefaultModel} */
31
31
  const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Default;
32
32
  return await Default.findByIdAndUpdate(req.params.id, req.body);
33
- },
34
- delete: async (req, res, options) => {
33
+ };
34
+ static delete = async (req, res, options) => {
35
35
  /** @type {import('./default.model.js').DefaultModel} */
36
36
  const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Default;
37
37
  if (req.params.id) return await Default.findByIdAndDelete(req.params.id);
38
38
  else return await Default.deleteMany();
39
- },
40
- };
39
+ };
40
+ }
41
41
 
42
42
  export { DefaultService };
@@ -2,8 +2,8 @@ import { loggerFactory } from '../../server/logger.js';
2
2
  import { DocumentService } from './document.service.js';
3
3
  const logger = loggerFactory(import.meta);
4
4
 
5
- const DocumentController = {
6
- post: async (req, res, options) => {
5
+ class DocumentController {
6
+ static post = async (req, res, options) => {
7
7
  try {
8
8
  return res.status(200).json({
9
9
  status: 'success',
@@ -16,8 +16,8 @@ const DocumentController = {
16
16
  message: error.message,
17
17
  });
18
18
  }
19
- },
20
- get: async (req, res, options) => {
19
+ };
20
+ static get = async (req, res, options) => {
21
21
  try {
22
22
  return res.status(200).json({
23
23
  status: 'success',
@@ -30,8 +30,8 @@ const DocumentController = {
30
30
  message: error.message,
31
31
  });
32
32
  }
33
- },
34
- delete: async (req, res, options) => {
33
+ };
34
+ static delete = async (req, res, options) => {
35
35
  try {
36
36
  const result = await DocumentService.delete(req, res, options);
37
37
  return res.status(200).json({
@@ -45,8 +45,8 @@ const DocumentController = {
45
45
  message: error.message,
46
46
  });
47
47
  }
48
- },
49
- put: async (req, res, options) => {
48
+ };
49
+ static put = async (req, res, options) => {
50
50
  try {
51
51
  const result = await DocumentService.put(req, res, options);
52
52
  return res.status(200).json({
@@ -60,8 +60,8 @@ const DocumentController = {
60
60
  message: error.message,
61
61
  });
62
62
  }
63
- },
64
- patch: async (req, res, options) => {
63
+ };
64
+ static patch = async (req, res, options) => {
65
65
  try {
66
66
  const result = await DocumentService.patch(req, res, options);
67
67
  return res.status(200).json({
@@ -75,7 +75,7 @@ const DocumentController = {
75
75
  message: error.message,
76
76
  });
77
77
  }
78
- },
79
- };
78
+ };
79
+ }
80
80
 
81
81
  export { DocumentController };
@@ -1,7 +1,5 @@
1
1
  import { Schema, model, Types } from 'mongoose';
2
-
3
2
  // https://mongoosejs.com/docs/2.7.x/docs/schematypes.html
4
-
5
3
  const DocumentSchema = new Schema(
6
4
  {
7
5
  userId: {
@@ -35,13 +33,10 @@ const DocumentSchema = new Schema(
35
33
  timestamps: true,
36
34
  },
37
35
  );
38
-
39
36
  const DocumentModel = model('Document', DocumentSchema);
40
-
41
37
  const ProviderSchema = DocumentSchema;
42
-
43
- const DocumentDto = {
44
- populate: {
38
+ class DocumentDto {
39
+ static populate = {
45
40
  file: () => {
46
41
  return {
47
42
  path: 'fileId',
@@ -68,34 +63,33 @@ const DocumentDto = {
68
63
  },
69
64
  };
70
65
  },
71
- },
72
- getTotalCopyShareLinkCount: (document) => {
66
+ };
67
+ static getTotalCopyShareLinkCount = (document) => {
73
68
  if (!document.share || !document.share.copyShareLinkEvent) return 0;
74
69
  return document.share.copyShareLinkEvent.reduce((total, event) => total + (event.count || 0), 0);
75
- },
70
+ };
76
71
  /**
77
72
  * Filter 'public' tag from tags array
78
73
  * The 'public' tag is internal and should not be rendered to users
79
74
  * @param {string[]} tags - Array of tags
80
75
  * @returns {string[]} - Filtered tags without 'public'
81
76
  */
82
- filterPublicTag: (tags) => {
77
+ static filterPublicTag = (tags) => {
83
78
  if (!tags || !Array.isArray(tags)) return [];
84
79
  return tags.filter((tag) => tag !== 'public');
85
- },
80
+ };
86
81
  /**
87
82
  * Extract isPublic boolean from tags array and return cleaned tags
88
83
  * @param {string[]} tags - Array of tags potentially containing 'public'
89
84
  * @returns {{ isPublic: boolean, tags: string[] }} - Object with isPublic flag and cleaned tags
90
85
  */
91
- extractPublicFromTags: (tags) => {
86
+ static extractPublicFromTags = (tags) => {
92
87
  if (!tags || !Array.isArray(tags)) {
93
88
  return { isPublic: false, tags: [] };
94
89
  }
95
90
  const hasPublicTag = tags.includes('public');
96
91
  const cleanedTags = tags.filter((tag) => tag !== 'public');
97
92
  return { isPublic: hasPublicTag, tags: cleanedTags };
98
- },
99
- };
100
-
93
+ };
94
+ }
101
95
  export { DocumentSchema, DocumentModel, ProviderSchema, DocumentDto };
@@ -2,8 +2,8 @@ import { loggerFactory } from '../../server/logger.js';
2
2
  import { FileService } from './file.service.js';
3
3
  const logger = loggerFactory(import.meta);
4
4
 
5
- const FileController = {
6
- post: async (req, res, options) => {
5
+ class FileController {
6
+ static post = async (req, res, options) => {
7
7
  try {
8
8
  return res.status(200).json({
9
9
  status: 'success',
@@ -16,8 +16,8 @@ const FileController = {
16
16
  message: error.message,
17
17
  });
18
18
  }
19
- },
20
- get: async (req, res, options) => {
19
+ };
20
+ static get = async (req, res, options) => {
21
21
  try {
22
22
  if (req && req.headers && req.headers.origin) {
23
23
  res.set('Access-Control-Allow-Origin', req.headers.origin);
@@ -38,8 +38,8 @@ const FileController = {
38
38
  message: error.message,
39
39
  });
40
40
  }
41
- },
42
- delete: async (req, res, options) => {
41
+ };
42
+ static delete = async (req, res, options) => {
43
43
  try {
44
44
  const result = await FileService.delete(req, res, options);
45
45
  return res.status(200).json({
@@ -53,7 +53,7 @@ const FileController = {
53
53
  message: error.message,
54
54
  });
55
55
  }
56
- },
57
- };
56
+ };
57
+ }
58
58
 
59
59
  export { FileController };
@@ -47,7 +47,7 @@ const ProviderSchema = FileSchema;
47
47
  * @namespace FileModelServer.FileModelDto
48
48
  * @memberof FileModelServer
49
49
  */
50
- const FileModelDto = {
50
+ class FileModelDto {
51
51
  /**
52
52
  * Returns file metadata only (no buffer data).
53
53
  * Used for list responses and API integration.
@@ -56,7 +56,7 @@ const FileModelDto = {
56
56
  * @param {Object} file - File document from database.
57
57
  * @returns {Object|null} File metadata object, or null if file is falsy.
58
58
  */
59
- toMetadata: (file) => {
59
+ static toMetadata = (file) => {
60
60
  if (!file) return null;
61
61
  return {
62
62
  _id: file._id,
@@ -68,7 +68,7 @@ const FileModelDto = {
68
68
  createdAt: file.createdAt,
69
69
  updatedAt: file.updatedAt,
70
70
  };
71
- },
71
+ };
72
72
 
73
73
  /**
74
74
  * Returns file with complete data.
@@ -78,7 +78,7 @@ const FileModelDto = {
78
78
  * @param {Object} file - File document from database.
79
79
  * @returns {Object|null} Complete file object with buffer data, or null if file is falsy.
80
80
  */
81
- toFull: (file) => {
81
+ static toFull = (file) => {
82
82
  if (!file) return null;
83
83
  return {
84
84
  _id: file._id,
@@ -92,7 +92,7 @@ const FileModelDto = {
92
92
  createdAt: file.createdAt,
93
93
  updatedAt: file.updatedAt,
94
94
  };
95
- },
95
+ };
96
96
 
97
97
  /**
98
98
  * Transforms array of files to metadata only.
@@ -101,10 +101,10 @@ const FileModelDto = {
101
101
  * @param {Array} files - Array of file documents.
102
102
  * @returns {Array} Array of file metadata objects.
103
103
  */
104
- toMetadataArray: (files) => {
104
+ static toMetadataArray = (files) => {
105
105
  if (!Array.isArray(files)) return [];
106
106
  return files.map((file) => FileModelDto.toMetadata(file));
107
- },
107
+ };
108
108
 
109
109
  /**
110
110
  * Ensures UTF-8 encoding for filenames.
@@ -114,14 +114,14 @@ const FileModelDto = {
114
114
  * @param {string} filename - Raw filename from upload.
115
115
  * @returns {string} UTF-8 encoded filename.
116
116
  */
117
- normalizeFilename: (filename) => {
117
+ static normalizeFilename = (filename) => {
118
118
  if (!filename) return '';
119
119
  // Ensure string and normalize to UTF-8
120
120
  let normalized = String(filename);
121
121
  // Replace any incorrectly encoded sequences
122
122
  normalized = Buffer.from(normalized, 'utf8').toString('utf8');
123
123
  return normalized;
124
- },
125
- };
124
+ };
125
+ }
126
126
 
127
127
  export { FileSchema, FileModel, ProviderSchema, FileModelDto };