cyberia 3.0.2 → 3.0.3

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 (47) hide show
  1. package/CHANGELOG.md +323 -290
  2. package/CLI-HELP.md +2 -1
  3. package/bin/build.js +0 -1
  4. package/bin/cyberia.js +98 -4
  5. package/bin/index.js +98 -4
  6. package/conf.js +192 -0
  7. package/deployment.yaml +72 -2
  8. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
  9. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  10. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  11. package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
  12. package/package.json +13 -9
  13. package/proxy.yaml +56 -9
  14. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +40 -7
  15. package/src/api/object-layer/object-layer.model.js +61 -19
  16. package/src/api/object-layer/object-layer.service.js +4 -9
  17. package/src/cli/index.js +6 -0
  18. package/src/cli/run.js +30 -2
  19. package/src/client/Underpost.index.js +36 -0
  20. package/src/client/components/core/Modal.js +2 -0
  21. package/src/client/components/core/PublicProfile.js +3 -3
  22. package/src/client/components/core/Router.js +34 -1
  23. package/src/client/components/core/Worker.js +1 -1
  24. package/src/client/components/cryptokoyn/CssCryptokoyn.js +63 -1
  25. package/src/client/components/cyberia/ObjectLayerEngineModal.js +145 -119
  26. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +64 -6
  27. package/src/client/components/itemledger/CssItemledger.js +62 -0
  28. package/src/client/components/underpost/CommonUnderpost.js +29 -0
  29. package/src/client/components/underpost/CssUnderpost.js +222 -0
  30. package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +879 -0
  31. package/src/client/components/underpost/DocumentSearchProvider.js +448 -0
  32. package/src/client/components/underpost/ElementsUnderpost.js +38 -0
  33. package/src/client/components/underpost/LabGalleryUnderpost.js +82 -0
  34. package/src/client/components/underpost/LogInUnderpost.js +20 -0
  35. package/src/client/components/underpost/LogOutUnderpost.js +13 -0
  36. package/src/client/components/underpost/MenuUnderpost.js +605 -0
  37. package/src/client/components/underpost/RoutesUnderpost.js +45 -0
  38. package/src/client/components/underpost/SettingsUnderpost.js +16 -0
  39. package/src/client/components/underpost/SignUpUnderpost.js +9 -0
  40. package/src/client/components/underpost/SocketIoUnderpost.js +54 -0
  41. package/src/client/components/underpost/TranslateUnderpost.js +10 -0
  42. package/src/client/services/object-layer/object-layer.management.js +23 -4
  43. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +83 -0
  44. package/src/client/ssr/head/UnderpostScripts.js +6 -0
  45. package/src/index.js +1 -1
  46. package/src/server/object-layer.js +13 -10
  47. package/src/server/semantic-layer-generator.js +1 -0
package/deployment.yaml CHANGED
@@ -18,7 +18,7 @@ spec:
18
18
  spec:
19
19
  containers:
20
20
  - name: dd-cyberia-development-blue
21
- image: localhost/rockylinux9-underpost:v3.0.2
21
+ image: localhost/rockylinux9-underpost:v3.0.3
22
22
 
23
23
  command:
24
24
  - /bin/sh
@@ -34,6 +34,9 @@ spec:
34
34
  - name: vol-public-dd-cyberia-dd-cyberia-development-blue
35
35
  mountPath: /home/dd/engine/src/client/public/cyberia
36
36
 
37
+ - name: vol-public-dd-cyberia-underpost-dd-cyberia-development-blue
38
+ mountPath: /home/dd/engine/src/client/public/underpost
39
+
37
40
  volumes:
38
41
  - name: config-volume-dd-cyberia-development-blue
39
42
  configMap:
@@ -45,6 +48,11 @@ spec:
45
48
  claimName: pvc-public-dd-cyberia-dd-cyberia-development-blue
46
49
 
47
50
 
51
+ - name: vol-public-dd-cyberia-underpost-dd-cyberia-development-blue
52
+ persistentVolumeClaim:
53
+ claimName: pvc-public-dd-cyberia-underpost-dd-cyberia-development-blue
54
+
55
+
48
56
  ---
49
57
  apiVersion: v1
50
58
  kind: Service
@@ -135,6 +143,33 @@ spec:
135
143
  protocol: UDP
136
144
  port: 4013
137
145
  targetPort: 4013
146
+
147
+ - name: 'tcp-4014'
148
+ protocol: TCP
149
+ port: 4014
150
+ targetPort: 4014
151
+ - name: 'udp-4014'
152
+ protocol: UDP
153
+ port: 4014
154
+ targetPort: 4014
155
+
156
+ - name: 'tcp-4015'
157
+ protocol: TCP
158
+ port: 4015
159
+ targetPort: 4015
160
+ - name: 'udp-4015'
161
+ protocol: UDP
162
+ port: 4015
163
+ targetPort: 4015
164
+
165
+ - name: 'tcp-4016'
166
+ protocol: TCP
167
+ port: 4016
168
+ targetPort: 4016
169
+ - name: 'udp-4016'
170
+ protocol: UDP
171
+ port: 4016
172
+ targetPort: 4016
138
173
  type: LoadBalancer
139
174
  ---
140
175
  apiVersion: apps/v1
@@ -156,7 +191,7 @@ spec:
156
191
  spec:
157
192
  containers:
158
193
  - name: dd-cyberia-development-green
159
- image: localhost/rockylinux9-underpost:v3.0.2
194
+ image: localhost/rockylinux9-underpost:v3.0.3
160
195
 
161
196
  command:
162
197
  - /bin/sh
@@ -172,6 +207,9 @@ spec:
172
207
  - name: vol-public-dd-cyberia-dd-cyberia-development-green
173
208
  mountPath: /home/dd/engine/src/client/public/cyberia
174
209
 
210
+ - name: vol-public-dd-cyberia-underpost-dd-cyberia-development-green
211
+ mountPath: /home/dd/engine/src/client/public/underpost
212
+
175
213
  volumes:
176
214
  - name: config-volume-dd-cyberia-development-green
177
215
  configMap:
@@ -183,6 +221,11 @@ spec:
183
221
  claimName: pvc-public-dd-cyberia-dd-cyberia-development-green
184
222
 
185
223
 
224
+ - name: vol-public-dd-cyberia-underpost-dd-cyberia-development-green
225
+ persistentVolumeClaim:
226
+ claimName: pvc-public-dd-cyberia-underpost-dd-cyberia-development-green
227
+
228
+
186
229
  ---
187
230
  apiVersion: v1
188
231
  kind: Service
@@ -273,4 +316,31 @@ spec:
273
316
  protocol: UDP
274
317
  port: 4013
275
318
  targetPort: 4013
319
+
320
+ - name: 'tcp-4014'
321
+ protocol: TCP
322
+ port: 4014
323
+ targetPort: 4014
324
+ - name: 'udp-4014'
325
+ protocol: UDP
326
+ port: 4014
327
+ targetPort: 4014
328
+
329
+ - name: 'tcp-4015'
330
+ protocol: TCP
331
+ port: 4015
332
+ targetPort: 4015
333
+ - name: 'udp-4015'
334
+ protocol: UDP
335
+ port: 4015
336
+ targetPort: 4015
337
+
338
+ - name: 'tcp-4016'
339
+ protocol: TCP
340
+ port: 4016
341
+ targetPort: 4016
342
+ - name: 'udp-4016'
343
+ protocol: UDP
344
+ port: 4016
345
+ targetPort: 4016
276
346
  type: LoadBalancer
@@ -23,7 +23,7 @@ spec:
23
23
  spec:
24
24
  containers:
25
25
  - name: dd-cron-backup
26
- image: underpost/underpost-engine:v3.0.2
26
+ image: underpost/underpost-engine:v3.0.3
27
27
  command:
28
28
  - /bin/sh
29
29
  - -c
@@ -23,7 +23,7 @@ spec:
23
23
  spec:
24
24
  containers:
25
25
  - name: dd-cron-dns
26
- image: underpost/underpost-engine:v3.0.2
26
+ image: underpost/underpost-engine:v3.0.3
27
27
  command:
28
28
  - /bin/sh
29
29
  - -c
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-default-development-blue
20
- image: localhost/rockylinux9-underpost:v3.0.2
20
+ image: localhost/rockylinux9-underpost:v3.0.3
21
21
  # resources:
22
22
  # requests:
23
23
  # memory: "124Ki"
@@ -100,7 +100,7 @@ spec:
100
100
  spec:
101
101
  containers:
102
102
  - name: dd-default-development-green
103
- image: localhost/rockylinux9-underpost:v3.0.2
103
+ image: localhost/rockylinux9-underpost:v3.0.3
104
104
  # resources:
105
105
  # requests:
106
106
  # memory: "124Ki"
@@ -18,7 +18,7 @@ spec:
18
18
  spec:
19
19
  containers:
20
20
  - name: dd-test-development-blue
21
- image: localhost/rockylinux9-underpost:v3.0.2
21
+ image: localhost/rockylinux9-underpost:v3.0.3
22
22
 
23
23
  command:
24
24
  - /bin/sh
@@ -103,7 +103,7 @@ spec:
103
103
  spec:
104
104
  containers:
105
105
  - name: dd-test-development-green
106
- image: localhost/rockylinux9-underpost:v3.0.2
106
+ image: localhost/rockylinux9-underpost:v3.0.3
107
107
 
108
108
  command:
109
109
  - /bin/sh
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "cyberia",
5
- "version": "3.0.2",
5
+ "version": "3.0.3",
6
6
  "description": "Cyberia Engine - Object Layer and Assets Management Microservice",
7
7
  "scripts": {
8
8
  "start": "env-cmd -f .env.production node --max-old-space-size=8192 src/server",
@@ -76,24 +76,20 @@
76
76
  "http-proxy-middleware": "^2.0.6",
77
77
  "ignore-walk": "^8.0.0",
78
78
  "iovalkey": "^0.2.1",
79
- "jimp": "^1.6.0",
80
79
  "json-colorizer": "^2.2.2",
81
80
  "jsonwebtoken": "^9.0.2",
82
81
  "mariadb": "^3.2.2",
83
82
  "marked": "^12.0.2",
84
- "maxrects-packer": "^2.7.3",
85
- "mocha": "^7.2.0",
83
+ "mocha": "^11.3.0",
86
84
  "mongoose": "^8.9.5",
87
85
  "morgan": "^1.10.0",
88
86
  "nodemailer": "^7.0.9",
89
87
  "nodemon": "^3.0.1",
90
88
  "peer": "^1.0.2",
91
89
  "peerjs": "^1.5.2",
92
- "pngjs": "^7.0.0",
93
90
  "prom-client": "^15.1.2",
94
91
  "read": "^2.1.0",
95
92
  "rrule": "^2.8.1",
96
- "sharp": "^0.32.5",
97
93
  "shelljs": "^0.10.0",
98
94
  "sitemap": "^7.1.1",
99
95
  "socket.io": "^4.8.0",
@@ -104,7 +100,11 @@
104
100
  "uglify-js": "^3.17.4",
105
101
  "validator": "^13.11.0",
106
102
  "vanilla-jsoneditor": "^2.3.2",
107
- "winston": "^3.11.0"
103
+ "winston": "^3.11.0",
104
+ "maxrects-packer": "^2.7.3",
105
+ "pngjs": "^7.0.0",
106
+ "jimp": "^1.6.0",
107
+ "sharp": "^0.32.5"
108
108
  },
109
109
  "publishConfig": {
110
110
  "provenance": true,
@@ -113,6 +113,10 @@
113
113
  },
114
114
  "overrides": {
115
115
  "minimatch": "^10.2.2",
116
- "glob": "^11.0.0"
116
+ "glob": "^11.0.0",
117
+ "diff": ">=8.0.3",
118
+ "js-yaml": ">=3.14.2",
119
+ "debug": ">=4.3.6",
120
+ "serialize-javascript": ">=7.0.3"
117
121
  }
118
- }
122
+ }
package/proxy.yaml CHANGED
@@ -3,11 +3,11 @@
3
3
  apiVersion: projectcontour.io/v1
4
4
  kind: HTTPProxy
5
5
  metadata:
6
- name: www.cyberiaonline.com
6
+ name: underpost.net
7
7
  namespace: default
8
8
  spec:
9
9
  virtualhost:
10
- fqdn: www.cyberiaonline.com
10
+ fqdn: underpost.net
11
11
  routes:
12
12
  - conditions:
13
13
  - prefix: /
@@ -27,6 +27,53 @@ spec:
27
27
  port: 4006
28
28
  weight: 100
29
29
 
30
+ ---
31
+ apiVersion: projectcontour.io/v1
32
+ kind: HTTPProxy
33
+ metadata:
34
+ name: www.underpost.net
35
+ namespace: default
36
+ spec:
37
+ virtualhost:
38
+ fqdn: www.underpost.net
39
+ routes:
40
+ - conditions:
41
+ - prefix: /
42
+
43
+ enableWebsockets: true
44
+ services:
45
+ - name: dd-cyberia-development-blue-service
46
+ port: 4007
47
+ weight: 100
48
+
49
+ ---
50
+ apiVersion: projectcontour.io/v1
51
+ kind: HTTPProxy
52
+ metadata:
53
+ name: www.cyberiaonline.com
54
+ namespace: default
55
+ spec:
56
+ virtualhost:
57
+ fqdn: www.cyberiaonline.com
58
+ routes:
59
+ - conditions:
60
+ - prefix: /
61
+
62
+ enableWebsockets: true
63
+ services:
64
+ - name: dd-cyberia-development-blue-service
65
+ port: 4008
66
+ weight: 100
67
+
68
+ - conditions:
69
+ - prefix: /peer
70
+
71
+ enableWebsockets: true
72
+ services:
73
+ - name: dd-cyberia-development-blue-service
74
+ port: 4009
75
+ weight: 100
76
+
30
77
  ---
31
78
  apiVersion: projectcontour.io/v1
32
79
  kind: HTTPProxy
@@ -43,7 +90,7 @@ spec:
43
90
  enableWebsockets: true
44
91
  services:
45
92
  - name: dd-cyberia-development-blue-service
46
- port: 4007
93
+ port: 4010
47
94
  weight: 100
48
95
 
49
96
  ---
@@ -62,7 +109,7 @@ spec:
62
109
  enableWebsockets: true
63
110
  services:
64
111
  - name: dd-cyberia-development-blue-service
65
- port: 4008
112
+ port: 4011
66
113
  weight: 100
67
114
 
68
115
  - conditions:
@@ -71,7 +118,7 @@ spec:
71
118
  enableWebsockets: true
72
119
  services:
73
120
  - name: dd-cyberia-development-blue-service
74
- port: 4009
121
+ port: 4012
75
122
  weight: 100
76
123
 
77
124
  ---
@@ -90,7 +137,7 @@ spec:
90
137
  enableWebsockets: true
91
138
  services:
92
139
  - name: dd-cyberia-development-blue-service
93
- port: 4010
140
+ port: 4013
94
141
  weight: 100
95
142
 
96
143
  ---
@@ -109,7 +156,7 @@ spec:
109
156
  enableWebsockets: true
110
157
  services:
111
158
  - name: dd-cyberia-development-blue-service
112
- port: 4011
159
+ port: 4014
113
160
  weight: 100
114
161
 
115
162
  - conditions:
@@ -118,7 +165,7 @@ spec:
118
165
  enableWebsockets: true
119
166
  services:
120
167
  - name: dd-cyberia-development-blue-service
121
- port: 4012
168
+ port: 4015
122
169
  weight: 100
123
170
 
124
171
  ---
@@ -137,6 +184,6 @@ spec:
137
184
  enableWebsockets: true
138
185
  services:
139
186
  - name: dd-cyberia-development-blue-service
140
- port: 4013
187
+ port: 4016
141
188
  weight: 100
142
189
 
@@ -43,6 +43,8 @@ const AtlasSpriteSheetService = {
43
43
 
44
44
  // Add atlas PNG to IPFS and obtain its CID
45
45
  let atlasCid = '';
46
+ let atlasMetadataCid = '';
47
+ const userId = req.auth && req.auth.user ? req.auth.user._id : undefined;
46
48
  try {
47
49
  const ipfsResult = await IpfsClient.addBufferToIpfs(
48
50
  buffer,
@@ -51,8 +53,6 @@ const AtlasSpriteSheetService = {
51
53
  );
52
54
  if (ipfsResult) {
53
55
  atlasCid = ipfsResult.cid;
54
- // Create pin record for the authenticated user (when available)
55
- const userId = req.auth && req.auth.user ? req.auth.user._id : undefined;
56
56
  if (userId) {
57
57
  await createPinRecord({ cid: atlasCid, userId, options });
58
58
  }
@@ -62,6 +62,24 @@ const AtlasSpriteSheetService = {
62
62
  logger.warn('Failed to add atlas sprite sheet to IPFS:', ipfsError.message);
63
63
  }
64
64
 
65
+ // Pin atlas metadata JSON to IPFS (fast-json-stable-stringify) and obtain its CID
66
+ try {
67
+ const metadataIpfsResult = await IpfsClient.addJsonToIpfs(
68
+ metadata,
69
+ `${itemKey}_atlas_sprite_sheet_metadata.json`,
70
+ `/object-layer/${itemKey}/${itemKey}_atlas_sprite_sheet_metadata.json`,
71
+ );
72
+ if (metadataIpfsResult) {
73
+ atlasMetadataCid = metadataIpfsResult.cid;
74
+ if (userId) {
75
+ await createPinRecord({ cid: atlasMetadataCid, userId, options });
76
+ }
77
+ logger.info(`Atlas metadata pinned to IPFS – CID: ${atlasMetadataCid}`);
78
+ }
79
+ } catch (ipfsError) {
80
+ logger.warn('Failed to add atlas metadata to IPFS:', ipfsError.message);
81
+ }
82
+
65
83
  let atlasDoc = await AtlasSpriteSheet.findOne({ 'metadata.itemKey': itemKey });
66
84
 
67
85
  if (atlasDoc) {
@@ -82,8 +100,10 @@ const AtlasSpriteSheetService = {
82
100
  }
83
101
 
84
102
  objectLayer.atlasSpriteSheetId = atlasDoc._id;
85
- objectLayer.data.atlasSpriteSheetCid = atlasCid;
86
- objectLayer.markModified('data.atlasSpriteSheetCid');
103
+ if (!objectLayer.data.render) objectLayer.data.render = {};
104
+ objectLayer.data.render.cid = atlasCid;
105
+ objectLayer.data.render.metadataCid = atlasMetadataCid;
106
+ objectLayer.markModified('data.render');
87
107
  await objectLayer.save();
88
108
 
89
109
  return atlasDoc;
@@ -106,7 +126,8 @@ const AtlasSpriteSheetService = {
106
126
  const atlasDoc = await AtlasSpriteSheet.findById(objectLayer.atlasSpriteSheetId);
107
127
  if (atlasDoc) {
108
128
  // Remove pin records and unpin atlas CID from IPFS
109
- const atlasCid = atlasDoc.cid || objectLayer.data.atlasSpriteSheetCid;
129
+ const atlasCid = atlasDoc.cid || objectLayer.data.render?.cid;
130
+ const atlasMetadataCid = objectLayer.data.render?.metadataCid;
110
131
  if (atlasCid) {
111
132
  try {
112
133
  await removePinRecordsAndUnpin(atlasCid, options);
@@ -118,6 +139,16 @@ const AtlasSpriteSheetService = {
118
139
  logger.warn(`Failed to clean up IPFS atlas CID ${atlasCid}: ${ipfsErr.message}`);
119
140
  }
120
141
  }
142
+ if (atlasMetadataCid) {
143
+ try {
144
+ await removePinRecordsAndUnpin(atlasMetadataCid, options);
145
+ const itemId = objectLayer.data.item.id;
146
+ await IpfsClient.removeMfsPath(`/object-layer/${itemId}/${itemId}_atlas_sprite_sheet_metadata.json`);
147
+ logger.info(`Cleaned up IPFS atlas metadata CID ${atlasMetadataCid} for ObjectLayer ${objectLayer._id}`);
148
+ } catch (ipfsErr) {
149
+ logger.warn(`Failed to clean up IPFS atlas metadata CID ${atlasMetadataCid}: ${ipfsErr.message}`);
150
+ }
151
+ }
121
152
 
122
153
  // Delete the atlas File document from MongoDB
123
154
  if (atlasDoc.fileId) {
@@ -127,8 +158,10 @@ const AtlasSpriteSheetService = {
127
158
  await AtlasSpriteSheet.findByIdAndDelete(atlasDoc._id);
128
159
  }
129
160
  objectLayer.atlasSpriteSheetId = undefined;
130
- objectLayer.data.atlasSpriteSheetCid = '';
131
- objectLayer.markModified('data.atlasSpriteSheetCid');
161
+ if (!objectLayer.data.render) objectLayer.data.render = {};
162
+ objectLayer.data.render.cid = '';
163
+ objectLayer.data.render.metadataCid = '';
164
+ objectLayer.markModified('data.render');
132
165
  await objectLayer.save();
133
166
  }
134
167
 
@@ -46,14 +46,62 @@ const ItemSchema = new Schema(
46
46
  { _id: false },
47
47
  );
48
48
 
49
+ /**
50
+ * @typedef {Object} Ledger
51
+ * Blockchain protocol metadata linking the visual object-layer prefab to its economic reality.
52
+ * @property {string} type - The token standard or off-chain designation (ERC20, ERC721, OFF_CHAIN).
53
+ * @property {string} address - The Solidity smart contract address.
54
+ * @memberof CyberiaObjectLayerModel
55
+ */
56
+ const LedgerSchema = new Schema(
57
+ {
58
+ type: {
59
+ type: String,
60
+ enum: ['ERC20', 'ERC721', 'OFF_CHAIN'],
61
+ required: true,
62
+ },
63
+ address: { type: String }, // Solidity contract address
64
+ },
65
+ { _id: false },
66
+ );
67
+
68
+ /**
69
+ * @typedef {Object} Render
70
+ * IPFS content identifiers for the consolidated atlas sprite sheet.
71
+ * @property {string} cid - IPFS Content Identifier for the consolidated atlas sprite sheet PNG
72
+ * @property {string} metadataCid - IPFS Content Identifier for the atlas sprite sheet metadata JSON (fast-json-stable-stringify)
73
+ * @memberof CyberiaObjectLayerModel
74
+ */
75
+ const RenderSchema = new Schema(
76
+ {
77
+ cid: { type: String, default: '', trim: true },
78
+ metadataCid: { type: String, default: '', trim: true },
79
+ },
80
+ { _id: false },
81
+ );
82
+
49
83
  /**
50
84
  * @typedef {Object} ObjectLayer
51
85
  * @property {Object} data - Object layer data
52
- * @property {Data.Stats} data.stats - Statistical attributes of the object layer
53
- * @property {Data.Item} data.item - Item information this layer represents
54
- * @property {string} data.seed - Random UUID for unique state generation
55
- * @property {string} [data.atlasSpriteSheetCid] - IPFS Content Identifier for the consolidated atlas sprite sheet PNG
56
- * @property {string} [cid] - IPFS Content Identifier for the object layer data JSON (fast-json-stable-stringify)
86
+ * @property {Object} data.stats - Statistical or mechanical attributes for the object layer
87
+ * @property {number} data.stats.effect - The effect attribute value
88
+ * @property {number} data.stats.resistance - The resistance attribute value
89
+ * @property {number} data.stats.agility - The agility attribute value
90
+ * @property {number} data.stats.range - The range attribute value
91
+ * @property {number} data.stats.intelligence - The intelligence attribute value
92
+ * @property {number} data.stats.utility - The utility attribute value
93
+ * @property {Object} data.item - Human-readable item information for the object layer
94
+ * @property {string} data.item.id - Unique identifier for the item
95
+ * @property {string} data.item.type - Type of the item
96
+ * @property {string} data.item.description - Description of the item
97
+ * @property {boolean} data.item.activable - Whether the item can be activated
98
+ * @property {Object} data.ledger - Blockchain protocol metadata linking the visual object-layer prefab to its economic reality
99
+ * @property {string} data.ledger.type - The token standard or off-chain designation (ERC20, ERC721, OFF_CHAIN).
100
+ * @property {string} data.ledger.address - The Solidity smart contract address.
101
+ * @property {Object} data.render - IPFS content identifiers for the consolidated atlas sprite sheet
102
+ * @property {string} data.render.cid - IPFS Content Identifier for the consolidated atlas sprite sheet PNG
103
+ * @property {string} data.render.metadataCid - IPFS Content Identifier for the atlas sprite sheet metadata JSON (fast-json-stable-stringify)
104
+ * @property {string} cid - IPFS Content Identifier for the object layer data JSON (fast-json-stable-stringify)
57
105
  * @property {Types.ObjectId} objectLayerRenderFramesId - Reference to ObjectLayerRenderFrames document
58
106
  * @property {Types.ObjectId} atlasSpriteSheetId - Reference to AtlasSpriteSheet document
59
107
  * @property {string} sha256 - SHA-256 hash of the object layer data
@@ -66,15 +114,8 @@ const ObjectLayerSchema = new Schema(
66
114
  data: {
67
115
  stats: { type: StatsSchema, required: true },
68
116
  item: { type: ItemSchema, required: true },
69
- seed: {
70
- type: String,
71
- required: true,
72
- match: [
73
- /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
74
- 'Please provide a valid UUID v4',
75
- ],
76
- },
77
- atlasSpriteSheetCid: { type: String, default: '', trim: true },
117
+ ledger: { type: LedgerSchema, required: true },
118
+ render: { type: RenderSchema, default: () => ({}) },
78
119
  },
79
120
  cid: { type: String, default: '', trim: true },
80
121
  objectLayerRenderFramesId: { type: Schema.Types.ObjectId, ref: 'ObjectLayerRenderFrames' },
@@ -116,10 +157,10 @@ ObjectLayerSchema.index(
116
157
  // Pre-save hook to ensure data consistency
117
158
  ObjectLayerSchema.pre('save', function (next) {
118
159
  // Ensure all required fields are present
119
- if (!this.data.stats || !this.data.item || !this.data.seed || !this.sha256) {
160
+ if (!this.data.stats || !this.data.item || !this.sha256) {
120
161
  throw new Error('Missing required fields');
121
162
  }
122
- // cid (object layer data JSON) and data.atlasSpriteSheetCid (atlas PNG) are optional – default to ''
163
+ // cid (object layer data JSON) and data.render.cid (atlas PNG) are optional – default to ''
123
164
  next();
124
165
  });
125
166
 
@@ -134,7 +175,8 @@ const ObjectLayerDto = {
134
175
  return {
135
176
  _id: 1,
136
177
  'data.item': 1,
137
- 'data.atlasSpriteSheetCid': 1,
178
+ 'data.ledger': 1,
179
+ 'data.render': 1,
138
180
  cid: 1,
139
181
  objectLayerRenderFramesId: 1,
140
182
  atlasSpriteSheetId: 1,
@@ -145,8 +187,8 @@ const ObjectLayerDto = {
145
187
  _id: 1,
146
188
  'data.item': 1,
147
189
  'data.stats': 1,
148
- 'data.seed': 1,
149
- 'data.atlasSpriteSheetCid': 1,
190
+ 'data.ledger': 1,
191
+ 'data.render': 1,
150
192
  cid: 1,
151
193
  objectLayerRenderFramesId: 1,
152
194
  atlasSpriteSheetId: 1,
@@ -189,14 +189,14 @@ const ObjectLayerService = {
189
189
  DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.ObjectLayerRenderFrames;
190
190
  let newObjectLayer = await new ObjectLayer(req.body).save();
191
191
 
192
- // Generate atlas sprite sheet – this sets data.atlasSpriteSheetCid and saves
192
+ // Generate atlas sprite sheet – this sets data.render.cid and saves
193
193
  try {
194
194
  await AtlasSpriteSheetService.generate({ params: { id: newObjectLayer._id }, auth: req.auth }, res, options);
195
195
  } catch (atlasError) {
196
196
  logger.error('Failed to auto-generate atlas for new ObjectLayer:', atlasError);
197
197
  }
198
198
 
199
- // Re-read so data.atlasSpriteSheetCid is up-to-date, then recompute SHA-256 & IPFS CID
199
+ // Re-read so data.render.cid is up-to-date, then recompute SHA-256 & IPFS CID
200
200
  newObjectLayer = await ObjectLayer.findById(newObjectLayer._id).populate('objectLayerRenderFramesId');
201
201
  if (newObjectLayer) {
202
202
  newObjectLayer = await ObjectLayerEngine.computeAndSaveFinalSha256({
@@ -645,11 +645,6 @@ const ObjectLayerService = {
645
645
  metadataOverride: req.body,
646
646
  });
647
647
 
648
- // Preserve the existing seed if provided in the request body
649
- if (req.body.data && req.body.data.seed) {
650
- objectLayerData.data.seed = req.body.data.seed;
651
- }
652
-
653
648
  // Update documents using centralized engine method (with atlas generation)
654
649
  const { objectLayer } = await ObjectLayerEngine.updateObjectLayerDocuments({
655
650
  objectLayerId,
@@ -677,14 +672,14 @@ const ObjectLayerService = {
677
672
  let updatedObjectLayer = await ObjectLayer.findByIdAndUpdate(req.params.id, req.body, { new: true });
678
673
 
679
674
  if (updatedObjectLayer) {
680
- // Generate atlas sprite sheet – this sets data.atlasSpriteSheetCid and saves
675
+ // Generate atlas sprite sheet – this sets data.render.cid and saves
681
676
  try {
682
677
  await AtlasSpriteSheetService.generate({ params: { id: req.params.id }, auth: req.auth }, res, options);
683
678
  } catch (atlasError) {
684
679
  logger.error('Failed to auto-update atlas for ObjectLayer:', atlasError);
685
680
  }
686
681
 
687
- // Re-read so data.atlasSpriteSheetCid is up-to-date, then recompute SHA-256 & IPFS CID
682
+ // Re-read so data.render.cid is up-to-date, then recompute SHA-256 & IPFS CID
688
683
  updatedObjectLayer = await ObjectLayer.findById(req.params.id).populate('objectLayerRenderFramesId');
689
684
  if (updatedObjectLayer) {
690
685
  updatedObjectLayer = await ObjectLayerEngine.computeAndSaveFinalSha256({
package/src/cli/index.js CHANGED
@@ -612,6 +612,12 @@ program
612
612
  '--create-job-now',
613
613
  'After applying cron manifests, immediately create a Job from each CronJob (forwarded to cron runner).',
614
614
  )
615
+ .option(
616
+ '--host-aliases <host-aliases>',
617
+ 'Adds entries to the Pod /etc/hosts via hostAliases. ' +
618
+ 'Format: semicolon-separated entries of "ip=hostname1,hostname2" ' +
619
+ '(e.g., "127.0.0.1=foo.local,bar.local;10.1.2.3=foo.remote,bar.remote").',
620
+ )
615
621
  .description('Runs specified scripts using various runners.')
616
622
  .action(Underpost.run.callback);
617
623