cyberia 3.0.2 → 3.1.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.
- package/{.env.production → .env.example} +20 -2
- package/.github/workflows/engine-cyberia.cd.yml +41 -10
- package/.github/workflows/engine-cyberia.ci.yml +53 -14
- package/.github/workflows/ghpkg.ci.yml +1 -1
- package/.github/workflows/gitlab.ci.yml +1 -1
- package/.github/workflows/hardhat.ci.yml +82 -0
- package/.github/workflows/npmpkg.ci.yml +37 -8
- package/.github/workflows/publish.ci.yml +5 -5
- package/.github/workflows/publish.cyberia.ci.yml +5 -5
- package/.github/workflows/pwa-microservices-template-page.cd.yml +3 -3
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/.github/workflows/release.cd.yml +3 -2
- package/.vscode/extensions.json +9 -8
- package/.vscode/settings.json +3 -2
- package/CHANGELOG.md +533 -290
- package/CLI-HELP.md +79 -53
- package/WHITE-PAPER.md +1540 -0
- package/bin/build.js +16 -11
- package/bin/cyberia.js +959 -8
- package/bin/deploy.js +103 -270
- package/bin/file.js +2 -1
- package/bin/index.js +959 -8
- package/bin/vs.js +3 -3
- package/conf.js +277 -77
- package/deployment.yaml +218 -4
- package/hardhat/.env.example +31 -0
- package/hardhat/README.md +531 -0
- package/hardhat/WHITE-PAPER.md +1540 -0
- package/hardhat/contracts/ObjectLayerToken.sol +391 -0
- package/hardhat/deployments/.gitkeep +0 -0
- package/hardhat/deployments/hardhat-ObjectLayerToken.json +11 -0
- package/hardhat/hardhat.config.js +136 -0
- package/hardhat/ignition/modules/ObjectLayerToken.js +21 -0
- package/hardhat/networks/besu-object-layer.network.json +138 -0
- package/hardhat/package-lock.json +7628 -0
- package/hardhat/package.json +45 -0
- package/hardhat/scripts/deployObjectLayerToken.js +98 -0
- package/hardhat/test/ObjectLayerToken.js +590 -0
- package/jsdoc.dd-cyberia.json +59 -0
- package/jsdoc.json +20 -13
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +490 -0
- package/manifests/deployment/dd-cyberia-development/proxy.yaml +261 -0
- package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +132 -0
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +52 -52
- package/manifests/deployment/dd-test-development/proxy.yaml +4 -4
- package/manifests/pv-pvc-dd.yaml +1 -1
- package/package.json +60 -50
- package/proxy.yaml +128 -9
- package/pv-pvc.yaml +132 -0
- package/scripts/k3s-node-setup.sh +1 -1
- package/scripts/ports-ls.sh +2 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +3 -1
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +1 -2
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +40 -7
- package/src/api/document/document.service.js +1 -1
- package/src/api/file/file.controller.js +3 -1
- package/src/api/file/file.service.js +28 -5
- package/src/api/ipfs/ipfs.service.js +2 -2
- package/src/api/object-layer/object-layer.controller.js +6 -2
- package/src/api/object-layer/object-layer.model.js +67 -21
- package/src/api/object-layer/object-layer.router.js +668 -42
- package/src/api/object-layer/object-layer.service.js +10 -16
- package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +1 -2
- package/src/api/user/user.router.js +10 -5
- package/src/api/user/user.service.js +7 -7
- package/src/cli/baremetal.js +6 -10
- package/src/cli/cloud-init.js +0 -3
- package/src/cli/db.js +54 -71
- package/src/cli/deploy.js +64 -12
- package/src/cli/env.js +5 -5
- package/src/cli/fs.js +0 -2
- package/src/cli/image.js +0 -3
- package/src/cli/index.js +41 -13
- package/src/cli/monitor.js +5 -6
- package/src/cli/repository.js +329 -46
- package/src/cli/run.js +210 -122
- package/src/cli/secrets.js +1 -3
- package/src/cli/ssh.js +1 -1
- package/src/client/Itemledger.index.js +1 -959
- package/src/client/Underpost.index.js +36 -0
- package/src/client/components/core/AgGrid.js +20 -5
- package/src/client/components/core/Alert.js +2 -2
- package/src/client/components/core/Content.js +22 -3
- package/src/client/components/core/Docs.js +30 -6
- package/src/client/components/core/FileExplorer.js +71 -4
- package/src/client/components/core/Input.js +1 -1
- package/src/client/components/core/Modal.js +22 -6
- package/src/client/components/core/PublicProfile.js +3 -3
- package/src/client/components/core/RichText.js +1 -2
- package/src/client/components/core/Router.js +34 -1
- package/src/client/components/core/Worker.js +1 -1
- package/src/client/components/cryptokoyn/CssCryptokoyn.js +63 -1
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +145 -119
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +64 -6
- package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +1 -0
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +44 -2
- package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +0 -1
- package/src/client/components/cyberia-portal/MenuCyberiaPortal.js +64 -2
- package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +1 -0
- package/src/client/components/itemledger/CssItemledger.js +62 -0
- package/src/client/components/underpost/CommonUnderpost.js +29 -0
- package/src/client/components/underpost/CssUnderpost.js +281 -0
- package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +879 -0
- package/src/client/components/underpost/DocumentSearchProvider.js +448 -0
- package/src/client/components/underpost/ElementsUnderpost.js +38 -0
- package/src/client/components/underpost/LabGalleryUnderpost.js +82 -0
- package/src/client/components/underpost/LogInUnderpost.js +23 -0
- package/src/client/components/underpost/LogOutUnderpost.js +15 -0
- package/src/client/components/underpost/MenuUnderpost.js +691 -0
- package/src/client/components/underpost/RoutesUnderpost.js +47 -0
- package/src/client/components/underpost/SettingsUnderpost.js +16 -0
- package/src/client/components/underpost/SignUpUnderpost.js +9 -0
- package/src/client/components/underpost/SocketIoUnderpost.js +54 -0
- package/src/client/components/underpost/TranslateUnderpost.js +10 -0
- package/src/client/public/cryptokoyn/assets/logo/base-icon.png +0 -0
- package/src/client/public/cryptokoyn/browserconfig.xml +12 -0
- package/src/client/public/cryptokoyn/microdata.json +85 -0
- package/src/client/public/cryptokoyn/site.webmanifest +57 -0
- package/src/client/public/cryptokoyn/sitemap +3 -3
- package/src/client/public/default/sitemap +3 -3
- package/src/client/public/itemledger/browserconfig.xml +2 -2
- package/src/client/public/itemledger/manifest.webmanifest +4 -4
- package/src/client/public/itemledger/microdata.json +71 -0
- package/src/client/public/itemledger/sitemap +3 -3
- package/src/client/public/itemledger/yandex-browser-manifest.json +2 -2
- package/src/client/public/test/sitemap +3 -3
- package/src/client/services/object-layer/object-layer.management.js +23 -4
- package/src/client/ssr/body/404.js +15 -11
- package/src/client/ssr/body/500.js +15 -11
- package/src/client/ssr/body/SwaggerDarkMode.js +285 -0
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +83 -0
- package/src/client/ssr/head/PwaItemledger.js +60 -0
- package/src/client/ssr/head/UnderpostScripts.js +6 -0
- package/src/client/ssr/offline/NoNetworkConnection.js +11 -10
- package/src/client/ssr/pages/Test.js +11 -10
- package/src/client.build.js +0 -3
- package/src/client.dev.js +0 -3
- package/src/db/DataBaseProvider.js +17 -2
- package/src/db/mariadb/MariaDB.js +14 -9
- package/src/db/mongo/MongooseDB.js +17 -1
- package/src/index.js +1 -1
- package/src/proxy.js +0 -3
- package/src/runtime/express/Express.js +15 -9
- package/src/runtime/lampp/Lampp.js +6 -13
- package/src/server/auth.js +12 -14
- package/src/server/backup.js +2 -3
- package/src/server/besu-genesis-generator.js +1630 -0
- package/src/server/client-build-docs.js +126 -17
- package/src/server/client-build-live.js +9 -18
- package/src/server/client-build.js +203 -75
- package/src/server/client-dev-server.js +14 -13
- package/src/server/conf.js +376 -164
- package/src/server/cron.js +2 -1
- package/src/server/dns.js +28 -12
- package/src/server/downloader.js +0 -2
- package/src/server/logger.js +27 -9
- package/src/server/object-layer.js +92 -16
- package/src/server/peer.js +0 -2
- package/src/server/process.js +1 -50
- package/src/server/proxy.js +4 -8
- package/src/server/runtime.js +5 -8
- package/src/server/semantic-layer-generator.js +1 -0
- package/src/server/ssr.js +0 -3
- package/src/server/start.js +19 -12
- package/src/server/tls.js +0 -2
- package/src/server.js +0 -4
- package/.env.development +0 -43
- package/.env.test +0 -43
- package/hardhat/contracts/CryptoKoyn.sol +0 -59
- package/hardhat/contracts/ItemLedger.sol +0 -73
- package/hardhat/contracts/Lock.sol +0 -34
- package/hardhat/hardhat.config.cjs +0 -45
- package/hardhat/ignition/modules/Lock.js +0 -18
- package/hardhat/networks/cryptokoyn-itemledger.network.json +0 -29
- package/hardhat/scripts/deployCryptokoyn.cjs +0 -25
- package/hardhat/scripts/deployItemledger.cjs +0 -25
- package/hardhat/test/Lock.js +0 -126
- package/hardhat/white-paper.md +0 -581
- package/white-paper.md +0 -581
package/src/server/cron.js
CHANGED
|
@@ -8,7 +8,7 @@ import { loggerFactory } from './logger.js';
|
|
|
8
8
|
import { shellExec } from './process.js';
|
|
9
9
|
import fs from 'fs-extra';
|
|
10
10
|
import Underpost from '../index.js';
|
|
11
|
-
import { getUnderpostRootPath } from './conf.js';
|
|
11
|
+
import { getUnderpostRootPath, loadCronDeployEnv } from './conf.js';
|
|
12
12
|
|
|
13
13
|
const logger = loggerFactory(import.meta);
|
|
14
14
|
|
|
@@ -191,6 +191,7 @@ class UnderpostCron {
|
|
|
191
191
|
jobList = Object.keys(Underpost.cron.JOB).join(','),
|
|
192
192
|
options = {},
|
|
193
193
|
) {
|
|
194
|
+
loadCronDeployEnv();
|
|
194
195
|
if (options.setupStart) return await Underpost.cron.setupDeployStart(options.setupStart, options);
|
|
195
196
|
|
|
196
197
|
if (options.generateK8sCronjobs) return await Underpost.cron.generateK8sCronJobs(options);
|
package/src/server/dns.js
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* @namespace UnderpostDns
|
|
6
6
|
*/
|
|
7
7
|
import axios from 'axios';
|
|
8
|
-
import dotenv from 'dotenv';
|
|
9
8
|
import fs from 'fs';
|
|
10
9
|
import validator from 'validator';
|
|
11
10
|
import { loggerFactory } from './logger.js';
|
|
@@ -13,11 +12,9 @@ import dns from 'node:dns';
|
|
|
13
12
|
import os from 'node:os';
|
|
14
13
|
import { shellExec, pbcopy } from './process.js';
|
|
15
14
|
import Underpost from '../index.js';
|
|
16
|
-
import { writeEnv } from './conf.js';
|
|
15
|
+
import { writeEnv, readConfJson, loadCronDeployEnv } from './conf.js';
|
|
17
16
|
import { resolveDeployId } from './cron.js';
|
|
18
17
|
|
|
19
|
-
dotenv.config();
|
|
20
|
-
|
|
21
18
|
const logger = loggerFactory(import.meta);
|
|
22
19
|
|
|
23
20
|
/**
|
|
@@ -268,6 +265,7 @@ class Dns {
|
|
|
268
265
|
* @returns {Promise<void>}
|
|
269
266
|
*/
|
|
270
267
|
static async callback(deployList) {
|
|
268
|
+
loadCronDeployEnv();
|
|
271
269
|
const isOnline = await Dns.isInternetConnection();
|
|
272
270
|
|
|
273
271
|
if (!isOnline) return;
|
|
@@ -288,16 +286,15 @@ class Dns {
|
|
|
288
286
|
|
|
289
287
|
for (const _deployId of deployList.split(',')) {
|
|
290
288
|
const deployId = _deployId.trim();
|
|
291
|
-
const privateCronConfPath = `./engine-private/conf/${deployId}/conf.cron.json`;
|
|
292
|
-
const confCronPath = fs.existsSync(privateCronConfPath) ? privateCronConfPath : './conf/conf.cron.json';
|
|
293
289
|
|
|
294
|
-
|
|
295
|
-
|
|
290
|
+
let confCronData;
|
|
291
|
+
try {
|
|
292
|
+
confCronData = readConfJson(deployId, 'cron', { resolve: true });
|
|
293
|
+
} catch (error) {
|
|
294
|
+
logger.warn(`Cron config file not found for deployId: ${deployId}`, { message: error.message });
|
|
296
295
|
continue;
|
|
297
296
|
}
|
|
298
297
|
|
|
299
|
-
const confCronData = JSON.parse(fs.readFileSync(confCronPath, 'utf8'));
|
|
300
|
-
|
|
301
298
|
if (!confCronData.records) {
|
|
302
299
|
logger.warn(`'records' field missing in cron config for deployId: ${deployId}`);
|
|
303
300
|
continue;
|
|
@@ -365,8 +362,26 @@ class Dns {
|
|
|
365
362
|
*/
|
|
366
363
|
dondominio: (options) => {
|
|
367
364
|
const { user, api_key, host, dns, ip } = options;
|
|
365
|
+
|
|
366
|
+
// Validate that required credentials are present before making any request
|
|
367
|
+
if (!user || !api_key) {
|
|
368
|
+
logger.error(
|
|
369
|
+
`${dns} update aborted: missing credentials. ` +
|
|
370
|
+
`Ensure DDNS_USER and DDNS_API_KEY environment variables are set ` +
|
|
371
|
+
`or provide 'user' and 'api_key' in cron records configuration.`,
|
|
372
|
+
{ host, hasUser: !!user, hasApiKey: !!api_key },
|
|
373
|
+
);
|
|
374
|
+
return Promise.resolve(false);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (!host) {
|
|
378
|
+
logger.error(`${dns} update aborted: missing host. Set DDNS_HOST or provide 'host' in cron records.`);
|
|
379
|
+
return Promise.resolve(false);
|
|
380
|
+
}
|
|
381
|
+
|
|
368
382
|
const url = `https://dondns.dondominio.com/json/?user=${user}&password=${api_key}&host=${host}&ip=${ip}`;
|
|
369
|
-
|
|
383
|
+
// Log the update attempt without exposing the full URL containing credentials
|
|
384
|
+
logger.info(`${dns} update ip request`, { host, ip });
|
|
370
385
|
|
|
371
386
|
// Prevent live IP update in non-production environments
|
|
372
387
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -382,7 +397,8 @@ class Dns {
|
|
|
382
397
|
return resolve(true);
|
|
383
398
|
})
|
|
384
399
|
.catch((error) => {
|
|
385
|
-
|
|
400
|
+
// Only log the error message — the full error object contains the request URL with credentials
|
|
401
|
+
logger.error(`${dns} update ip error`, { message: error.message, host, ip });
|
|
386
402
|
return resolve(false);
|
|
387
403
|
});
|
|
388
404
|
});
|
package/src/server/downloader.js
CHANGED
package/src/server/logger.js
CHANGED
|
@@ -6,16 +6,14 @@
|
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
import dotenv from 'dotenv';
|
|
10
9
|
import winston from 'winston';
|
|
11
10
|
import morgan from 'morgan';
|
|
12
|
-
import colorize from 'json-colorizer';
|
|
11
|
+
import { colorize, color } from 'json-colorizer';
|
|
13
12
|
import colors from 'colors';
|
|
14
13
|
import v8 from 'v8';
|
|
15
14
|
import { clearTerminalStringColor, formatBytes } from '../client/components/core/CommonJs.js';
|
|
16
15
|
|
|
17
16
|
colors.enable();
|
|
18
|
-
dotenv.config();
|
|
19
17
|
|
|
20
18
|
// Define your severity levels.
|
|
21
19
|
// With them, You can create log files,
|
|
@@ -60,14 +58,34 @@ const format = (meta) =>
|
|
|
60
58
|
winston.format.colorize({ all: true }),
|
|
61
59
|
// Define the format of the message showing the timestamp, the level and the message
|
|
62
60
|
winston.format.printf((info) => {
|
|
63
|
-
const
|
|
61
|
+
const splatKey = Symbol.for('splat');
|
|
62
|
+
const splat = info[splatKey];
|
|
63
|
+
const hasSplat = Array.isArray(splat) && splat.length > 0 && splat[0] !== undefined;
|
|
64
|
+
let splatStr = '';
|
|
65
|
+
if (hasSplat) {
|
|
66
|
+
const seen = new WeakSet();
|
|
67
|
+
splatStr = JSON.stringify(
|
|
68
|
+
splat[0],
|
|
69
|
+
(key, value) => {
|
|
70
|
+
if (typeof value === 'function') return `[Function: ${value.name || 'anonymous'}]`;
|
|
71
|
+
if (typeof value === 'object' && value !== null) {
|
|
72
|
+
if (seen.has(value)) return '[Circular]';
|
|
73
|
+
seen.add(value);
|
|
74
|
+
}
|
|
75
|
+
return value;
|
|
76
|
+
},
|
|
77
|
+
4,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
64
80
|
return `${`[${meta}]`.green} ${info.timestamp} ${info.level} ${
|
|
65
|
-
|
|
66
|
-
? `${clearTerminalStringColor(info.message)}: ${colorize(
|
|
81
|
+
hasSplat
|
|
82
|
+
? `${clearTerminalStringColor(info.message)}: ${colorize(splatStr, {
|
|
67
83
|
colors: {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
84
|
+
StringKey: color.green,
|
|
85
|
+
StringLiteral: color.magenta,
|
|
86
|
+
NumberLiteral: color.red,
|
|
87
|
+
BooleanLiteral: color.cyan,
|
|
88
|
+
NullLiteral: color.white,
|
|
71
89
|
},
|
|
72
90
|
})}`
|
|
73
91
|
: info.message
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Provides utilities and engine logic for processing and managing Cyberia Online's object layer assets (skins, floors, weapons, etc.).
|
|
3
|
-
*
|
|
3
|
+
* Shared logic consumed by both the Cyberia CLI and the REST API service layer.
|
|
4
4
|
* @module src/server/object-layer.js
|
|
5
5
|
* @namespace CyberiaObjectLayer
|
|
6
6
|
*/
|
|
@@ -47,8 +47,9 @@ const logger = loggerFactory(import.meta);
|
|
|
47
47
|
* @property {string} [data.item.description] - Human-readable description.
|
|
48
48
|
* @property {boolean} [data.item.activable] - Whether the item can be activated.
|
|
49
49
|
* @property {Object} data.stats - Statistical attributes of the object layer.
|
|
50
|
-
* @property {
|
|
51
|
-
* @property {string} [data.
|
|
50
|
+
* @property {Object} [data.render] - IPFS content identifiers for the consolidated atlas sprite sheet.
|
|
51
|
+
* @property {string} [data.render.cid] - IPFS CID for the consolidated atlas sprite sheet PNG.
|
|
52
|
+
* @property {string} [data.render.metadataCid] - IPFS CID for the atlas sprite sheet metadata JSON (fast-json-stable-stringify).
|
|
52
53
|
* @property {ObjectLayerRenderFramesData} [objectLayerRenderFramesData] - Render frames data (transient, used before persisting).
|
|
53
54
|
* @property {import('mongoose').Types.ObjectId} [objectLayerRenderFramesId] - Reference to persisted ObjectLayerRenderFrames document.
|
|
54
55
|
* @property {string} [sha256] - SHA-256 hash of the object layer data.
|
|
@@ -81,7 +82,7 @@ const logger = loggerFactory(import.meta);
|
|
|
81
82
|
|
|
82
83
|
/**
|
|
83
84
|
* Engine class providing static utilities for Cyberia Online object layer asset processing,
|
|
84
|
-
* frame extraction, directory iteration, image building, and
|
|
85
|
+
* frame extraction, directory iteration, image building, and document creation logic.
|
|
85
86
|
* @class ObjectLayerEngine
|
|
86
87
|
* @memberof CyberiaObjectLayer
|
|
87
88
|
*/
|
|
@@ -373,7 +374,7 @@ export class ObjectLayerEngine {
|
|
|
373
374
|
}
|
|
374
375
|
|
|
375
376
|
// ──────────────────────────────────────────────────────────────────────────
|
|
376
|
-
//
|
|
377
|
+
// Document lifecycle methods
|
|
377
378
|
// ──────────────────────────────────────────────────────────────────────────
|
|
378
379
|
|
|
379
380
|
/**
|
|
@@ -445,7 +446,7 @@ export class ObjectLayerEngine {
|
|
|
445
446
|
activable: true,
|
|
446
447
|
},
|
|
447
448
|
stats: metadata.data.stats || ObjectLayerEngine.generateRandomStats(),
|
|
448
|
-
|
|
449
|
+
ledger: metadata.data.ledger || { type: 'OFF_CHAIN' },
|
|
449
450
|
},
|
|
450
451
|
};
|
|
451
452
|
} else {
|
|
@@ -458,7 +459,7 @@ export class ObjectLayerEngine {
|
|
|
458
459
|
activable: true,
|
|
459
460
|
},
|
|
460
461
|
stats: ObjectLayerEngine.generateRandomStats(),
|
|
461
|
-
|
|
462
|
+
ledger: { type: 'OFF_CHAIN' },
|
|
462
463
|
},
|
|
463
464
|
};
|
|
464
465
|
}
|
|
@@ -501,7 +502,7 @@ export class ObjectLayerEngine {
|
|
|
501
502
|
/**
|
|
502
503
|
* Computes a SHA-256 hash of the given object layer data using deterministic JSON serialisation.
|
|
503
504
|
* @static
|
|
504
|
-
* @param {Object} data - The `data` sub-document of an ObjectLayer (item, stats,
|
|
505
|
+
* @param {Object} data - The `data` sub-document of an ObjectLayer (item, stats, render).
|
|
505
506
|
* @returns {string} Hex-encoded SHA-256 hash.
|
|
506
507
|
* @memberof CyberiaObjectLayer
|
|
507
508
|
*/
|
|
@@ -642,7 +643,7 @@ export class ObjectLayerEngine {
|
|
|
642
643
|
*
|
|
643
644
|
* When `generateAtlas` is `true` (the default) the method delegates to
|
|
644
645
|
* `AtlasSpriteSheetService.generate` and then recomputes the definitive SHA-256
|
|
645
|
-
* (which now includes `data.
|
|
646
|
+
* (which now includes `data.render.cid`) and persists an IPFS CID.
|
|
646
647
|
*
|
|
647
648
|
* @static
|
|
648
649
|
* @param {Object} params - Parameters.
|
|
@@ -668,7 +669,8 @@ export class ObjectLayerEngine {
|
|
|
668
669
|
|
|
669
670
|
// 2. Attach reference + compute temporary SHA-256
|
|
670
671
|
objectLayerData.objectLayerRenderFramesId = objectLayerRenderFramesDoc._id;
|
|
671
|
-
objectLayerData.data.
|
|
672
|
+
if (!objectLayerData.data.render) objectLayerData.data.render = {};
|
|
673
|
+
objectLayerData.data.render.cid = objectLayerData.data.render.cid || '';
|
|
672
674
|
objectLayerData.sha256 = ObjectLayerEngine.computeSha256(objectLayerData.data);
|
|
673
675
|
|
|
674
676
|
// 3. Upsert ObjectLayer (handle duplicate sha256 gracefully)
|
|
@@ -677,7 +679,7 @@ export class ObjectLayerEngine {
|
|
|
677
679
|
if (existingObjectLayer) {
|
|
678
680
|
logger.info(`ObjectLayer with sha256 ${objectLayerData.sha256} already exists, updating...`);
|
|
679
681
|
objectLayer = await ObjectLayer.findByIdAndUpdate(existingObjectLayer._id, objectLayerData, {
|
|
680
|
-
|
|
682
|
+
returnDocument: 'after',
|
|
681
683
|
}).populate('objectLayerRenderFramesId');
|
|
682
684
|
} else {
|
|
683
685
|
objectLayer = await (await ObjectLayer.create(objectLayerData)).populate('objectLayerRenderFramesId');
|
|
@@ -729,7 +731,7 @@ export class ObjectLayerEngine {
|
|
|
729
731
|
objectLayerRenderFramesDoc = await ObjectLayerRenderFrames.findByIdAndUpdate(
|
|
730
732
|
existingObjectLayer.objectLayerRenderFramesId,
|
|
731
733
|
objectLayerRenderFramesData,
|
|
732
|
-
{
|
|
734
|
+
{ returnDocument: 'after' },
|
|
733
735
|
);
|
|
734
736
|
objectLayerData.objectLayerRenderFramesId = existingObjectLayer.objectLayerRenderFramesId;
|
|
735
737
|
} else {
|
|
@@ -738,14 +740,15 @@ export class ObjectLayerEngine {
|
|
|
738
740
|
}
|
|
739
741
|
|
|
740
742
|
// 2. Compute temporary SHA-256
|
|
741
|
-
objectLayerData.data.
|
|
743
|
+
if (!objectLayerData.data.render) objectLayerData.data.render = {};
|
|
744
|
+
objectLayerData.data.render.cid = objectLayerData.data.render.cid || '';
|
|
742
745
|
objectLayerData.sha256 = ObjectLayerEngine.computeSha256(objectLayerData.data);
|
|
743
746
|
|
|
744
747
|
// 3. Persist ObjectLayer update
|
|
745
748
|
let objectLayer;
|
|
746
749
|
try {
|
|
747
750
|
objectLayer = await ObjectLayer.findByIdAndUpdate(objectLayerId, objectLayerData, {
|
|
748
|
-
|
|
751
|
+
returnDocument: 'after',
|
|
749
752
|
}).populate('objectLayerRenderFramesId');
|
|
750
753
|
if (!objectLayer) {
|
|
751
754
|
throw new Error('ObjectLayer not found for update');
|
|
@@ -773,7 +776,7 @@ export class ObjectLayerEngine {
|
|
|
773
776
|
* Recomputes the definitive SHA-256, pins the object layer data JSON to IPFS,
|
|
774
777
|
* and persists both fields on the ObjectLayer document.
|
|
775
778
|
*
|
|
776
|
-
* Intended for use after atlas generation has set `data.
|
|
779
|
+
* Intended for use after atlas generation has set `data.render.cid`.
|
|
777
780
|
*
|
|
778
781
|
* @static
|
|
779
782
|
* @param {Object} params - Parameters.
|
|
@@ -814,6 +817,72 @@ export class ObjectLayerEngine {
|
|
|
814
817
|
return objectLayer;
|
|
815
818
|
}
|
|
816
819
|
|
|
820
|
+
/**
|
|
821
|
+
* Resolve the canonical CID for an Object Layer item from the database.
|
|
822
|
+
*
|
|
823
|
+
* The canonical CID is the IPFS content identifier of the stable-JSON-serialised
|
|
824
|
+
* `objectLayer.data` document (produced by `fast-json-stable-stringify`). This is
|
|
825
|
+
* the CID that MUST be stored on-chain as the metadata CID so that any party can
|
|
826
|
+
* independently reproduce the hash from the same semantic payload.
|
|
827
|
+
*
|
|
828
|
+
* Resolution order:
|
|
829
|
+
* 1. If the ObjectLayer document already has a `.cid` field, use it.
|
|
830
|
+
* 2. Otherwise compute it on-the-fly via `ipfsClient.addJsonToIpfs` (pins the
|
|
831
|
+
* data to IPFS as a side-effect) and persist it back to the document.
|
|
832
|
+
* 3. If IPFS is unreachable, fall back to a local SHA-256 so the caller at
|
|
833
|
+
* least gets a content hash (prefixed with `sha256:` to distinguish it
|
|
834
|
+
* from a real IPFS CID).
|
|
835
|
+
*
|
|
836
|
+
* @static
|
|
837
|
+
* @param {Object} params
|
|
838
|
+
* @param {string} params.itemId – human-readable item identifier.
|
|
839
|
+
* @param {import('mongoose').Model} params.ObjectLayer – Mongoose ObjectLayer model.
|
|
840
|
+
* @param {Object} [params.ipfsClient=null] – The IpfsClient module; when `null`, IPFS pinning is skipped and only SHA-256 fallback is returned.
|
|
841
|
+
* @param {Object} [params.options] – `{ host, path }` forwarded to pin helpers.
|
|
842
|
+
* @returns {Promise<{ cid: string, sha256: string, source: string }>}
|
|
843
|
+
* @memberof CyberiaObjectLayer
|
|
844
|
+
*/
|
|
845
|
+
static async resolveCanonicalCid({ itemId, ObjectLayer, ipfsClient = null, options }) {
|
|
846
|
+
const objectLayer = await ObjectLayer.findOne({ 'data.item.id': itemId });
|
|
847
|
+
if (!objectLayer) {
|
|
848
|
+
throw new Error(`ObjectLayer "${itemId}" not found in database`);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
const sha256 = ObjectLayerEngine.computeSha256(objectLayer.data);
|
|
852
|
+
|
|
853
|
+
// 1. Already have a canonical CID persisted
|
|
854
|
+
if (objectLayer.cid) {
|
|
855
|
+
return { cid: objectLayer.cid, sha256, source: 'db' };
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
// 2. Try to compute and persist via IPFS
|
|
859
|
+
if (ipfsClient) {
|
|
860
|
+
try {
|
|
861
|
+
const ipfsResult = await ipfsClient.addJsonToIpfs(
|
|
862
|
+
objectLayer.data,
|
|
863
|
+
`${itemId}_data.json`,
|
|
864
|
+
`/object-layer/${itemId}/${itemId}_data.json`,
|
|
865
|
+
);
|
|
866
|
+
if (ipfsResult) {
|
|
867
|
+
objectLayer.cid = ipfsResult.cid;
|
|
868
|
+
objectLayer.sha256 = sha256;
|
|
869
|
+
objectLayer.markModified('data');
|
|
870
|
+
await objectLayer.save();
|
|
871
|
+
logger.info(`Canonical CID computed and persisted for "${itemId}": ${ipfsResult.cid}`);
|
|
872
|
+
return { cid: ipfsResult.cid, sha256, source: 'ipfs' };
|
|
873
|
+
}
|
|
874
|
+
} catch (err) {
|
|
875
|
+
logger.warn(`IPFS unreachable while resolving canonical CID for "${itemId}": ${err.message}`);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
// 3. Fallback – return a sha256:-prefixed content hash
|
|
880
|
+
logger.warn(
|
|
881
|
+
`Using SHA-256 fallback for "${itemId}" (IPFS unavailable). On-chain CID will not resolve via gateway.`,
|
|
882
|
+
);
|
|
883
|
+
return { cid: `sha256:${sha256}`, sha256, source: 'sha256-fallback' };
|
|
884
|
+
}
|
|
885
|
+
|
|
817
886
|
/**
|
|
818
887
|
* Internal helper that generates an atlas sprite sheet and then finalizes the SHA-256 / IPFS CID.
|
|
819
888
|
* @static
|
|
@@ -840,7 +909,7 @@ export class ObjectLayerEngine {
|
|
|
840
909
|
logger.error(`Failed to auto-${isNew ? 'generate' : 'update'} atlas for ObjectLayer:`, atlasError);
|
|
841
910
|
}
|
|
842
911
|
|
|
843
|
-
// Re-read the objectLayer so data.
|
|
912
|
+
// Re-read the objectLayer so data.render.cid is up-to-date
|
|
844
913
|
objectLayer = await ObjectLayer.findById(objectLayer._id).populate('objectLayerRenderFramesId');
|
|
845
914
|
|
|
846
915
|
// Compute definitive SHA-256 and IPFS CID
|
|
@@ -960,3 +1029,10 @@ export const computeAndSaveFinalSha256 = ObjectLayerEngine.computeAndSaveFinalSh
|
|
|
960
1029
|
* @memberof CyberiaObjectLayer
|
|
961
1030
|
*/
|
|
962
1031
|
export const writeStaticFrameAssets = ObjectLayerEngine.writeStaticFrameAssets;
|
|
1032
|
+
|
|
1033
|
+
/**
|
|
1034
|
+
* @see {@link ObjectLayerEngine.resolveCanonicalCid}
|
|
1035
|
+
* @function resolveCanonicalCid
|
|
1036
|
+
* @memberof CyberiaObjectLayer
|
|
1037
|
+
*/
|
|
1038
|
+
export const resolveCanonicalCid = ObjectLayerEngine.resolveCanonicalCid;
|
package/src/server/peer.js
CHANGED
package/src/server/process.js
CHANGED
|
@@ -8,14 +8,11 @@
|
|
|
8
8
|
// https://nodejs.org/api/process
|
|
9
9
|
|
|
10
10
|
import shell from 'shelljs';
|
|
11
|
-
import dotenv from 'dotenv';
|
|
12
11
|
import { loggerFactory } from './logger.js';
|
|
13
12
|
import clipboard from 'clipboardy';
|
|
14
13
|
import Underpost from '../index.js';
|
|
15
14
|
import { getNpmRootPath } from './conf.js';
|
|
16
15
|
|
|
17
|
-
dotenv.config();
|
|
18
|
-
|
|
19
16
|
const logger = loggerFactory(import.meta);
|
|
20
17
|
|
|
21
18
|
/**
|
|
@@ -122,52 +119,6 @@ const shellCd = (cd, options = { disableLog: false }) => {
|
|
|
122
119
|
return shell.cd(cd);
|
|
123
120
|
};
|
|
124
121
|
|
|
125
|
-
/**
|
|
126
|
-
* Opens a new GNOME terminal and executes a command.
|
|
127
|
-
* Note: This function is environment-specific (GNOME/Linux).
|
|
128
|
-
* @memberof Process
|
|
129
|
-
* @param {string} cmd - The command to execute in the new terminal.
|
|
130
|
-
* @param {Object} [options] - Options for the terminal opening.
|
|
131
|
-
* @param {boolean} [options.single=false] - If true, execute as a single session process using `setsid`.
|
|
132
|
-
* @param {string} [options.chown] - Path to change ownership to the target user.
|
|
133
|
-
* @returns {void}
|
|
134
|
-
*/
|
|
135
|
-
const openTerminal = (cmd, options = { single: false }) => {
|
|
136
|
-
// Find the graphical user's UID from /run/user (prefer non-root UID, usually 1000)
|
|
137
|
-
const IDS = shellExec(`ls -1 /run/user`, { stdout: true, silent: true })
|
|
138
|
-
.split('\n')
|
|
139
|
-
.map((v) => v.trim())
|
|
140
|
-
.filter(Boolean);
|
|
141
|
-
|
|
142
|
-
const nonRootIds = IDS.filter((id) => id !== '0');
|
|
143
|
-
const ID = nonRootIds.length > 0 ? nonRootIds[0] : IDS[0];
|
|
144
|
-
|
|
145
|
-
if (!options.chown) options.chown = `/home/dd ${getNpmRootPath()}/underpost`;
|
|
146
|
-
|
|
147
|
-
shellExec(`chown -R ${ID}:${ID} ${options.chown}`);
|
|
148
|
-
|
|
149
|
-
// Run the terminal as the graphical user and use THAT user's runtime dir/bus.
|
|
150
|
-
const confCmd = `USER_GRAPHICAL=$(getent passwd "${ID}" | cut -d: -f1); \
|
|
151
|
-
sudo -u "$USER_GRAPHICAL" env DISPLAY="$DISPLAY" \
|
|
152
|
-
XDG_RUNTIME_DIR="/run/user/${ID}" \
|
|
153
|
-
DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${ID}/bus" \
|
|
154
|
-
PATH="$PATH" \
|
|
155
|
-
`;
|
|
156
|
-
|
|
157
|
-
if (options.single === true) {
|
|
158
|
-
// Run as a single session process
|
|
159
|
-
shellExec(`${confCmd} setsid gnome-terminal -- bash -ic '${cmd}; exec bash' >/dev/null 2>&1 &`, {
|
|
160
|
-
async: true,
|
|
161
|
-
});
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
// Run asynchronously and disown
|
|
165
|
-
shellExec(`${confCmd} gnome-terminal -- bash -c '${cmd}; exec bash' >/dev/null 2>&1 & disown`, {
|
|
166
|
-
async: true,
|
|
167
|
-
stdout: true,
|
|
168
|
-
});
|
|
169
|
-
};
|
|
170
|
-
|
|
171
122
|
/**
|
|
172
123
|
* Wraps a command to run it as a daemon process in a shell (keeping the process alive/terminal open).
|
|
173
124
|
* @memberof Process
|
|
@@ -198,4 +149,4 @@ function pbcopy(data) {
|
|
|
198
149
|
logger.info(`copied to clipboard`, clipboard.readSync());
|
|
199
150
|
}
|
|
200
151
|
|
|
201
|
-
export { ProcessController, getRootDirectory, shellExec, shellCd, pbcopy,
|
|
152
|
+
export { ProcessController, getRootDirectory, shellExec, shellCd, pbcopy, getTerminalPid, daemonProcess };
|
package/src/server/proxy.js
CHANGED
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
9
|
import express from 'express';
|
|
10
|
-
import dotenv from 'dotenv';
|
|
11
|
-
|
|
12
10
|
import { createProxyMiddleware } from 'http-proxy-middleware';
|
|
13
11
|
import { loggerFactory, loggerMiddleware } from './logger.js';
|
|
14
12
|
import { buildPortProxyRouter, buildProxyRouter, getTlsHosts, isDevProxyContext, isTlsDevProxy } from './conf.js';
|
|
@@ -17,8 +15,6 @@ import { shellExec } from './process.js';
|
|
|
17
15
|
import fs from 'fs-extra';
|
|
18
16
|
import Underpost from '../index.js';
|
|
19
17
|
|
|
20
|
-
dotenv.config();
|
|
21
|
-
|
|
22
18
|
const logger = loggerFactory(import.meta);
|
|
23
19
|
|
|
24
20
|
/**
|
|
@@ -56,11 +52,12 @@ class ProxyService {
|
|
|
56
52
|
// Proxy middleware options
|
|
57
53
|
/** @type {import('http-proxy-middleware/dist/types').Options} */
|
|
58
54
|
const options = {
|
|
55
|
+
pathFilter: proxyPath, // Use '/' as the general filter (v3 API)
|
|
59
56
|
ws: true, // Enable websocket proxying
|
|
60
57
|
target: `http://localhost:${parseInt(process.env.PORT - 1)}`, // Default target (should be overridden by router)
|
|
61
58
|
router: {},
|
|
62
59
|
// changeOrigin: true,
|
|
63
|
-
|
|
60
|
+
logger: logger,
|
|
64
61
|
xfwd: true, // Adds x-forward headers (Host, Proto, etc.)
|
|
65
62
|
onProxyReq: (proxyReq, req, res, options) => {},
|
|
66
63
|
pathRewrite: {},
|
|
@@ -74,8 +71,7 @@ class ProxyService {
|
|
|
74
71
|
devProxyContext: process.env.NODE_ENV !== 'production',
|
|
75
72
|
});
|
|
76
73
|
|
|
77
|
-
|
|
78
|
-
app.use(proxyPath, createProxyMiddleware(filter, options));
|
|
74
|
+
app.use(proxyPath, createProxyMiddleware(options));
|
|
79
75
|
|
|
80
76
|
// Determine which server to start (HTTP or HTTPS) based on port and environment
|
|
81
77
|
switch (process.env.NODE_ENV) {
|
|
@@ -115,7 +111,7 @@ class ProxyService {
|
|
|
115
111
|
break;
|
|
116
112
|
}
|
|
117
113
|
}
|
|
118
|
-
logger.info('Proxy running', { port, options });
|
|
114
|
+
logger.info('Proxy running', { port, router: options.router });
|
|
119
115
|
if (process.env.NODE_ENV === 'development')
|
|
120
116
|
logger.info(
|
|
121
117
|
Underpost.deploy.etcHostFactory(Object.keys(options.router), {
|
package/src/server/runtime.js
CHANGED
|
@@ -6,21 +6,17 @@
|
|
|
6
6
|
* @namespace Runtime
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import fs from 'fs-extra';
|
|
10
|
-
import dotenv from 'dotenv';
|
|
11
9
|
import * as promClient from 'prom-client';
|
|
12
10
|
|
|
13
11
|
import { loggerFactory } from './logger.js';
|
|
14
12
|
import { newInstance } from '../client/components/core/CommonJs.js';
|
|
15
13
|
import { Lampp } from '../runtime/lampp/Lampp.js';
|
|
16
|
-
import { getInstanceContext } from './conf.js';
|
|
14
|
+
import { getInstanceContext, readConfJson } from './conf.js';
|
|
17
15
|
|
|
18
16
|
import ExpressService from '../runtime/express/Express.js';
|
|
19
17
|
|
|
20
18
|
import Underpost from '../index.js';
|
|
21
19
|
|
|
22
|
-
dotenv.config();
|
|
23
|
-
|
|
24
20
|
const logger = loggerFactory(import.meta);
|
|
25
21
|
|
|
26
22
|
/**
|
|
@@ -48,9 +44,9 @@ const buildRuntime = async () => {
|
|
|
48
44
|
const initPort = parseInt(process.env.PORT) + 1;
|
|
49
45
|
let currentPort = initPort;
|
|
50
46
|
|
|
51
|
-
// Load Configuration
|
|
52
|
-
const confServer =
|
|
53
|
-
const confSSR =
|
|
47
|
+
// Load Configuration — resolve env: secret references at actual server runtime
|
|
48
|
+
const confServer = readConfJson(deployId, 'server', { resolve: true, loadReplicas: true });
|
|
49
|
+
const confSSR = readConfJson(deployId, 'ssr');
|
|
54
50
|
|
|
55
51
|
// Iterate through hosts and paths
|
|
56
52
|
for (const host of Object.keys(confServer)) {
|
|
@@ -83,6 +79,7 @@ const buildRuntime = async () => {
|
|
|
83
79
|
redirect,
|
|
84
80
|
singleReplica,
|
|
85
81
|
replicas,
|
|
82
|
+
peer,
|
|
86
83
|
});
|
|
87
84
|
|
|
88
85
|
if (singleReplicaOffsetPortSum > 0) {
|
|
@@ -1052,6 +1052,7 @@ export function generateMultiFrame(options) {
|
|
|
1052
1052
|
intelligence: hashMod(seed + ':intelligence', 11),
|
|
1053
1053
|
utility: hashMod(seed + ':utility', 11),
|
|
1054
1054
|
},
|
|
1055
|
+
ledger: { type: 'OFF_CHAIN' },
|
|
1055
1056
|
seed: seedToUUIDv4(seed + ':' + itemId),
|
|
1056
1057
|
},
|
|
1057
1058
|
};
|
package/src/server/ssr.js
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import fs from 'fs-extra';
|
|
8
|
-
import dotenv from 'dotenv';
|
|
9
8
|
import vm from 'node:vm';
|
|
10
9
|
|
|
11
10
|
import Underpost from '../index.js';
|
|
@@ -14,8 +13,6 @@ import { srcFormatted, JSONweb } from './client-formatted.js';
|
|
|
14
13
|
import { loggerFactory } from './logger.js';
|
|
15
14
|
import { getRootDirectory } from './process.js';
|
|
16
15
|
|
|
17
|
-
dotenv.config();
|
|
18
|
-
|
|
19
16
|
const logger = loggerFactory(import.meta);
|
|
20
17
|
|
|
21
18
|
/**
|
package/src/server/start.js
CHANGED
|
@@ -147,27 +147,34 @@ class UnderpostStartUp {
|
|
|
147
147
|
* @param {string} deployId - The ID of the deployment.
|
|
148
148
|
* @param {string} env - The environment of the deployment.
|
|
149
149
|
* @param {Object} options - Options for the build.
|
|
150
|
+
* @param {boolean} options.skipPullBase - Whether to skip pulling the base code and use the current workspace code directly.
|
|
150
151
|
* @param {boolean} options.underpostQuicklyInstall - Whether to use underpost quickly install.
|
|
151
152
|
* @memberof UnderpostStartUp
|
|
152
153
|
*/
|
|
153
|
-
async build(
|
|
154
|
+
async build(
|
|
155
|
+
deployId = 'dd-default',
|
|
156
|
+
env = 'development',
|
|
157
|
+
options = { underpostQuicklyInstall: false, skipPullBase: false },
|
|
158
|
+
) {
|
|
154
159
|
const buildBasePath = `/home/dd`;
|
|
155
160
|
const repoName = `engine-${deployId.split('-')[1]}`;
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
161
|
+
if (!options.skipPullBase) {
|
|
162
|
+
shellExec(`cd ${buildBasePath} && underpost clone ${process.env.GITHUB_USERNAME}/${repoName}`);
|
|
163
|
+
shellExec(`mkdir -p ${buildBasePath}/engine`);
|
|
164
|
+
shellExec(`cd ${buildBasePath} && sudo cp -a ./${repoName}/. ./engine`);
|
|
165
|
+
shellExec(`cd ${buildBasePath} && sudo rm -rf ./${repoName}`);
|
|
166
|
+
shellExec(`cd ${buildBasePath}/engine && underpost clone ${process.env.GITHUB_USERNAME}/${repoName}-private`);
|
|
167
|
+
shellExec(`cd ${buildBasePath}/engine && sudo mv ./${repoName}-private ./engine-private`);
|
|
168
|
+
}
|
|
162
169
|
shellCd(`${buildBasePath}/engine`);
|
|
163
170
|
shellExec(options?.underpostQuicklyInstall ? `underpost install` : `npm install`);
|
|
164
|
-
shellExec(`node bin
|
|
171
|
+
shellExec(`node bin env ${deployId} ${env}`);
|
|
165
172
|
if (fs.existsSync('./engine-private/itc-scripts')) {
|
|
166
173
|
const itcScripts = await fs.readdir('./engine-private/itc-scripts');
|
|
167
174
|
for (const itcScript of itcScripts)
|
|
168
175
|
if (itcScript.match(deployId)) shellExec(`node ./engine-private/itc-scripts/${itcScript}`);
|
|
169
176
|
}
|
|
170
|
-
shellExec(`node bin
|
|
177
|
+
shellExec(`node bin client ${deployId}`);
|
|
171
178
|
},
|
|
172
179
|
/**
|
|
173
180
|
* Runs a deployment.
|
|
@@ -177,17 +184,17 @@ class UnderpostStartUp {
|
|
|
177
184
|
* @memberof UnderpostStartUp
|
|
178
185
|
*/
|
|
179
186
|
async run(deployId = 'dd-default', env = 'development', options = {}) {
|
|
180
|
-
const runCmd = env === 'production' ? 'run prod
|
|
187
|
+
const runCmd = env === 'production' ? 'run prod:container' : 'run dev:container';
|
|
181
188
|
if (fs.existsSync(`./engine-private/replica`)) {
|
|
182
189
|
const replicas = await fs.readdir(`./engine-private/replica`);
|
|
183
190
|
for (const replica of replicas) {
|
|
184
191
|
if (!replica.match(deployId)) continue;
|
|
185
|
-
shellExec(`node bin
|
|
192
|
+
shellExec(`node bin env ${replica} ${env}`);
|
|
186
193
|
shellExec(`npm ${runCmd} ${replica}`, { async: true });
|
|
187
194
|
await awaitDeployMonitor(true);
|
|
188
195
|
}
|
|
189
196
|
}
|
|
190
|
-
shellExec(`node bin
|
|
197
|
+
shellExec(`node bin env ${deployId} ${env}`);
|
|
191
198
|
shellExec(`npm ${runCmd} ${deployId}`, { async: true });
|
|
192
199
|
await awaitDeployMonitor(true);
|
|
193
200
|
Underpost.env.set('container-status', `${deployId}-${env}-running-deployment`);
|