cyberia 3.0.3 → 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 +211 -1
- package/CLI-HELP.md +78 -53
- package/WHITE-PAPER.md +1540 -0
- package/bin/build.js +16 -10
- package/bin/cyberia.js +861 -4
- package/bin/deploy.js +103 -270
- package/bin/file.js +2 -1
- package/bin/index.js +861 -4
- package/bin/vs.js +3 -3
- package/conf.js +105 -97
- package/deployment.yaml +148 -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 +50 -44
- package/proxy.yaml +79 -7
- 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/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 +12 -8
- package/src/api/object-layer/object-layer.router.js +668 -42
- package/src/api/object-layer/object-layer.service.js +6 -7
- 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 +35 -13
- package/src/cli/monitor.js +5 -6
- package/src/cli/repository.js +329 -46
- package/src/cli/run.js +180 -120
- 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/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 +20 -6
- package/src/client/components/core/RichText.js +1 -2
- 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/underpost/CssUnderpost.js +59 -0
- package/src/client/components/underpost/LogInUnderpost.js +3 -0
- package/src/client/components/underpost/LogOutUnderpost.js +2 -0
- package/src/client/components/underpost/MenuUnderpost.js +99 -13
- package/src/client/components/underpost/RoutesUnderpost.js +2 -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/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/head/PwaItemledger.js +60 -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 +79 -6
- 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/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/conf.js
CHANGED
|
@@ -26,10 +26,235 @@ import Underpost from '../index.js';
|
|
|
26
26
|
|
|
27
27
|
colors.enable();
|
|
28
28
|
|
|
29
|
-
dotenv.config();
|
|
30
|
-
|
|
31
29
|
const logger = loggerFactory(import.meta);
|
|
32
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Prefix used in JSON configuration files to denote an environment variable reference.
|
|
33
|
+
* Any string value in a config object that starts with this prefix will be resolved
|
|
34
|
+
* to the corresponding `process.env` value at runtime.
|
|
35
|
+
*
|
|
36
|
+
* @constant {string}
|
|
37
|
+
* @memberof ServerConfBuilder
|
|
38
|
+
* @example
|
|
39
|
+
* // In conf.server.json:
|
|
40
|
+
* { "db": { "password": "env:MARIADB_PASSWORD" } }
|
|
41
|
+
*/
|
|
42
|
+
const ENV_REF_PREFIX = 'env:';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Recursively walks a configuration object and replaces every string value that
|
|
46
|
+
* starts with {@link ENV_REF_PREFIX} (`"env:"`) with the corresponding
|
|
47
|
+
* `process.env[VAR_NAME]` value.
|
|
48
|
+
*
|
|
49
|
+
* Non-string values and strings that do not start with the prefix are left untouched.
|
|
50
|
+
*
|
|
51
|
+
* Supports three reference formats:
|
|
52
|
+
* - `"env:VAR_NAME"` — resolves to `process.env.VAR_NAME`, returns `''` if unset.
|
|
53
|
+
* - `"env:VAR_NAME:default_value"` — resolves to `process.env.VAR_NAME`, falls back to `default_value` if unset.
|
|
54
|
+
* - Type-coerced defaults:
|
|
55
|
+
* - `"env:VAR_NAME:int:465"` — resolved value is parsed as integer (`parseInt`), falls back to `465`.
|
|
56
|
+
* - `"env:VAR_NAME:bool:true"` — resolved value is coerced to boolean (`value !== 'false'`), falls back to `true`.
|
|
57
|
+
*
|
|
58
|
+
* @method resolveConfSecrets
|
|
59
|
+
* @param {any} obj - The configuration object (or value) to resolve.
|
|
60
|
+
* @returns {any} A **new** object with all `env:` references replaced by their runtime values.
|
|
61
|
+
* @memberof ServerConfBuilder
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* // Given process.env.MARIADB_PASSWORD = 'supersecret'
|
|
65
|
+
* resolveConfSecrets({ db: { password: 'env:MARIADB_PASSWORD' } });
|
|
66
|
+
* // => { db: { password: 'supersecret' } }
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* // With default value fallback (env var not set)
|
|
70
|
+
* resolveConfSecrets({ db: { provider: 'env:DB_PROVIDER:mongoose' } });
|
|
71
|
+
* // => { db: { provider: 'mongoose' } }
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* // With int type coercion
|
|
75
|
+
* resolveConfSecrets({ port: 'env:SMTP_PORT:int:465' });
|
|
76
|
+
* // => { port: 465 }
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* // With bool type coercion
|
|
80
|
+
* resolveConfSecrets({ secure: 'env:SMTP_SECURE:bool:true' });
|
|
81
|
+
* // => { secure: true }
|
|
82
|
+
*/
|
|
83
|
+
const resolveConfSecrets = (obj) => {
|
|
84
|
+
if (obj === null || obj === undefined) return obj;
|
|
85
|
+
if (typeof obj === 'string') {
|
|
86
|
+
if (obj.startsWith(ENV_REF_PREFIX)) {
|
|
87
|
+
const ref = obj.slice(ENV_REF_PREFIX.length);
|
|
88
|
+
// Support env:VAR_NAME:default_value syntax (first colon separates key from default)
|
|
89
|
+
const colonIdx = ref.indexOf(':');
|
|
90
|
+
const envKey = colonIdx !== -1 ? ref.slice(0, colonIdx) : ref;
|
|
91
|
+
const defaultValue = colonIdx !== -1 ? ref.slice(colonIdx + 1) : undefined;
|
|
92
|
+
const envValue = process.env[envKey];
|
|
93
|
+
|
|
94
|
+
let resolved;
|
|
95
|
+
if (envValue !== undefined) {
|
|
96
|
+
resolved = envValue;
|
|
97
|
+
} else if (defaultValue !== undefined) {
|
|
98
|
+
resolved = defaultValue;
|
|
99
|
+
} else {
|
|
100
|
+
logger.warn(`resolveConfSecrets: environment variable "${envKey}" is not set (referenced as "${obj}")`);
|
|
101
|
+
return '';
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Type coercion via prefix in default value: int:N or bool:B
|
|
105
|
+
// Also apply coercion when an env value is present and a typed default is declared
|
|
106
|
+
if (defaultValue !== undefined) {
|
|
107
|
+
if (defaultValue.startsWith('int:')) {
|
|
108
|
+
return parseInt(resolved, 10) || parseInt(defaultValue.slice(4), 10) || 0;
|
|
109
|
+
}
|
|
110
|
+
if (defaultValue.startsWith('bool:')) {
|
|
111
|
+
const boolDefault = defaultValue.slice(5);
|
|
112
|
+
if (envValue !== undefined) return envValue !== 'false';
|
|
113
|
+
return boolDefault !== 'false';
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return resolved;
|
|
118
|
+
}
|
|
119
|
+
return obj;
|
|
120
|
+
}
|
|
121
|
+
if (Array.isArray(obj)) return obj.map((item) => resolveConfSecrets(item));
|
|
122
|
+
if (typeof obj === 'object') {
|
|
123
|
+
const resolved = {};
|
|
124
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
125
|
+
resolved[key] = resolveConfSecrets(value);
|
|
126
|
+
}
|
|
127
|
+
return resolved;
|
|
128
|
+
}
|
|
129
|
+
return obj;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Returns the private configuration folder for a given deploy ID.
|
|
134
|
+
* Checks for a replica folder first, then falls back to the standard conf folder.
|
|
135
|
+
*
|
|
136
|
+
* @method getConfFolder
|
|
137
|
+
* @param {string} deployId - The deploy ID.
|
|
138
|
+
* @returns {string} The path to the private configuration folder.
|
|
139
|
+
* @memberof ServerConfBuilder
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* getConfFolder('dd-myapp');
|
|
143
|
+
* // => './engine-private/conf/dd-myapp' (or './engine-private/replica/dd-myapp' if it exists)
|
|
144
|
+
*/
|
|
145
|
+
const getConfFolder = (deployId) => {
|
|
146
|
+
return fs.existsSync(`./engine-private/replica/${deployId}`)
|
|
147
|
+
? `./engine-private/replica/${deployId}`
|
|
148
|
+
: `./engine-private/conf/${deployId}`;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Loads the deployment-specific `.env` file referenced by `engine-private/deploy/dd.cron`
|
|
153
|
+
* into `process.env`. Uses `NODE_ENV` to select the environment variant
|
|
154
|
+
* (defaults to `production`).
|
|
155
|
+
*
|
|
156
|
+
* Safe to call multiple times; subsequent calls are no-ops once the env is loaded.
|
|
157
|
+
*
|
|
158
|
+
* @method loadCronDeployEnv
|
|
159
|
+
* @memberof ServerConfBuilder
|
|
160
|
+
*/
|
|
161
|
+
function loadCronDeployEnv() {
|
|
162
|
+
const envName = process.env.NODE_ENV || 'production';
|
|
163
|
+
|
|
164
|
+
// 1) Load dd.cron env (takes full precedence)
|
|
165
|
+
const cronDeployFile = './engine-private/deploy/dd.cron';
|
|
166
|
+
if (fs.existsSync(cronDeployFile)) {
|
|
167
|
+
const cronDeployId = fs.readFileSync(cronDeployFile, 'utf8').trim();
|
|
168
|
+
if (cronDeployId) {
|
|
169
|
+
const cronEnvPath = `./engine-private/conf/${cronDeployId}/.env.${envName}`;
|
|
170
|
+
if (fs.existsSync(cronEnvPath)) {
|
|
171
|
+
const cronEnv = dotenv.parse(fs.readFileSync(cronEnvPath, 'utf8'));
|
|
172
|
+
process.env = { ...process.env, ...cronEnv };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 2) Load dd.router envs — only keys not already present
|
|
178
|
+
const routerDeployFile = './engine-private/deploy/dd.router';
|
|
179
|
+
if (fs.existsSync(routerDeployFile)) {
|
|
180
|
+
const routerIds = fs.readFileSync(routerDeployFile, 'utf8').trim().split(',');
|
|
181
|
+
for (const deployId of routerIds) {
|
|
182
|
+
const id = deployId.trim();
|
|
183
|
+
if (!id) continue;
|
|
184
|
+
const envPath = `./engine-private/conf/${id}/.env.${envName}`;
|
|
185
|
+
if (!fs.existsSync(envPath)) continue;
|
|
186
|
+
const env = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
|
|
187
|
+
for (const key of Object.keys(env)) {
|
|
188
|
+
if (!(key in process.env)) process.env[key] = env[key];
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Resolves the full path to a specific configuration JSON file for a deploy ID.
|
|
196
|
+
* For `server` configs in development mode with a subConf, it will prefer the
|
|
197
|
+
* dev-specific variant if it exists.
|
|
198
|
+
*
|
|
199
|
+
* @method getConfFilePath
|
|
200
|
+
* @param {string} deployId - The deploy ID.
|
|
201
|
+
* @param {string} confType - The configuration type (e.g. 'server', 'client', 'cron', 'ssr').
|
|
202
|
+
* @param {string} [subConf=''] - Optional sub-configuration identifier (used for dev server variants).
|
|
203
|
+
* @returns {string} The resolved path to the configuration JSON file.
|
|
204
|
+
* @memberof ServerConfBuilder
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* getConfFilePath('dd-myapp', 'server');
|
|
208
|
+
* // => './engine-private/conf/dd-myapp/conf.server.json'
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* // In development with subConf 'local':
|
|
212
|
+
* getConfFilePath('dd-myapp', 'server', 'local');
|
|
213
|
+
* // => './engine-private/conf/dd-myapp/conf.server.dev.local.json' (if it exists)
|
|
214
|
+
*/
|
|
215
|
+
const getConfFilePath = (deployId, confType, subConf = '') => {
|
|
216
|
+
const folder = getConfFolder(deployId);
|
|
217
|
+
// When no explicit subConf is given, fall back to the env var set by loadConf()
|
|
218
|
+
const effectiveSubConf = subConf || process.env.DEPLOY_SUB_CONF || '';
|
|
219
|
+
if (confType === 'server' && effectiveSubConf) {
|
|
220
|
+
const devConfPath = `${folder}/conf.${confType}.dev.${effectiveSubConf}.json`;
|
|
221
|
+
if (fs.existsSync(devConfPath)) return devConfPath;
|
|
222
|
+
}
|
|
223
|
+
return `${folder}/conf.${confType}.json`;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Reads and parses a configuration JSON file for a given deploy ID and config type.
|
|
228
|
+
* Optionally resolves `env:` secret references and/or applies replica expansion.
|
|
229
|
+
*
|
|
230
|
+
* @method readConfJson
|
|
231
|
+
* @param {string} deployId - The deploy ID.
|
|
232
|
+
* @param {string} confType - The configuration type (e.g. 'server', 'client', 'cron', 'ssr').
|
|
233
|
+
* @param {object} [options={}] - Options.
|
|
234
|
+
* @param {string} [options.subConf=''] - Sub-configuration identifier for dev variants.
|
|
235
|
+
* @param {boolean} [options.resolve=false] - Whether to resolve `env:` references.
|
|
236
|
+
* @param {boolean} [options.loadReplicas=false] - Whether to expand replica entries (server configs).
|
|
237
|
+
* @returns {object} The parsed (and optionally resolved) configuration object.
|
|
238
|
+
* @memberof ServerConfBuilder
|
|
239
|
+
*/
|
|
240
|
+
const readConfJson = (deployId, confType, options = {}) => {
|
|
241
|
+
const filePath = getConfFilePath(deployId, confType, options.subConf || '');
|
|
242
|
+
if (!fs.existsSync(filePath)) {
|
|
243
|
+
throw new Error(`readConfJson: configuration file not found: ${filePath}`);
|
|
244
|
+
}
|
|
245
|
+
let parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
246
|
+
if (options.loadReplicas && confType === 'server') parsed = loadReplicas(deployId, parsed);
|
|
247
|
+
if (options.resolve) parsed = resolveConfSecrets(parsed);
|
|
248
|
+
return parsed;
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Default deploy ID used when no deploy ID is specified.
|
|
253
|
+
* @constant {string}
|
|
254
|
+
* @memberof ServerConfBuilder
|
|
255
|
+
*/
|
|
256
|
+
const DEFAULT_DEPLOY_ID = 'dd-default';
|
|
257
|
+
|
|
33
258
|
/**
|
|
34
259
|
* @class Config
|
|
35
260
|
* @description Manages the configuration of the server.
|
|
@@ -53,12 +278,13 @@ const Config = {
|
|
|
53
278
|
* @param {string} [subConf=''] - The sub configuration.
|
|
54
279
|
* @memberof ServerConfBuilder
|
|
55
280
|
*/
|
|
56
|
-
build: async function (deployContext =
|
|
281
|
+
build: async function (deployContext = DEFAULT_DEPLOY_ID, deployList, subConf) {
|
|
57
282
|
if (process.argv[2] && typeof process.argv[2] === 'string' && process.argv[2].startsWith('dd-'))
|
|
58
283
|
deployContext = process.argv[2];
|
|
284
|
+
else if (deployContext !== 'proxy' && process.env.DEPLOY_ID && process.env.DEPLOY_ID.startsWith('dd-'))
|
|
285
|
+
deployContext = process.env.DEPLOY_ID;
|
|
59
286
|
if (!subConf && process.argv[3] && typeof process.argv[3] === 'string') subConf = process.argv[3];
|
|
60
|
-
|
|
61
|
-
if (!fs.existsSync(`./conf`)) fs.mkdirSync(`./conf`);
|
|
287
|
+
|
|
62
288
|
Underpost.env.set('await-deploy', new Date().toISOString());
|
|
63
289
|
if (deployContext.startsWith('dd-')) loadConf(deployContext, subConf);
|
|
64
290
|
if (deployContext === 'proxy') await Config.buildProxy(deployList, subConf);
|
|
@@ -70,7 +296,7 @@ const Config = {
|
|
|
70
296
|
* @param {object} [options={ subConf: '', cluster: false }] - The options.
|
|
71
297
|
* @memberof ServerConfBuilder
|
|
72
298
|
*/
|
|
73
|
-
deployIdFactory: function (deployId =
|
|
299
|
+
deployIdFactory: function (deployId = DEFAULT_DEPLOY_ID, options = { subConf: '', cluster: false }) {
|
|
74
300
|
if (!deployId.startsWith('dd-')) deployId = `dd-${deployId}`;
|
|
75
301
|
|
|
76
302
|
logger.info('Build deployId', deployId);
|
|
@@ -79,28 +305,39 @@ const Config = {
|
|
|
79
305
|
const repoName = `engine-${deployId.split('dd-')[1]}`;
|
|
80
306
|
|
|
81
307
|
if (!fs.existsSync(folder)) fs.mkdirSync(folder, { recursive: true });
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
fs.readFileSync('./.env.
|
|
85
|
-
'
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
'
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
308
|
+
|
|
309
|
+
const envTemplate = fs.existsSync('./.env.example')
|
|
310
|
+
? fs.readFileSync('./.env.example', 'utf8')
|
|
311
|
+
: fs.existsSync('./.env.production')
|
|
312
|
+
? fs.readFileSync('./.env.production', 'utf8')
|
|
313
|
+
: '';
|
|
314
|
+
|
|
315
|
+
if (envTemplate) {
|
|
316
|
+
const prodEnv = envTemplate.replaceAll('dd-default', deployId);
|
|
317
|
+
fs.writeFileSync(`${folder}/.env.production`, prodEnv, 'utf8');
|
|
318
|
+
fs.writeFileSync(
|
|
319
|
+
`${folder}/.env.development`,
|
|
320
|
+
prodEnv.replace('NODE_ENV=production', 'NODE_ENV=development').replace('PORT=3000', 'PORT=4000'),
|
|
321
|
+
'utf8',
|
|
322
|
+
);
|
|
323
|
+
fs.writeFileSync(
|
|
324
|
+
`${folder}/.env.test`,
|
|
325
|
+
prodEnv.replace('NODE_ENV=production', 'NODE_ENV=test').replace('PORT=3000', 'PORT=5000'),
|
|
326
|
+
'utf8',
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
97
330
|
fs.writeFileSync(
|
|
98
331
|
`${folder}/package.json`,
|
|
99
332
|
fs.readFileSync('./package.json', 'utf8').replaceAll('dd-default', deployId),
|
|
100
333
|
'utf8',
|
|
101
334
|
);
|
|
102
335
|
|
|
103
|
-
|
|
336
|
+
// Write default conf JSON files if they don't exist
|
|
337
|
+
for (const confType of Object.keys(this.default)) {
|
|
338
|
+
const confPath = `${folder}/conf.${confType}.json`;
|
|
339
|
+
if (!fs.existsSync(confPath)) fs.writeFileSync(confPath, JSON.stringify(this.default[confType], null, 4), 'utf8');
|
|
340
|
+
}
|
|
104
341
|
|
|
105
342
|
if (options.subConf) {
|
|
106
343
|
logger.info('Creating sub conf', {
|
|
@@ -127,38 +364,17 @@ const Config = {
|
|
|
127
364
|
shellExec(`node bin new --default-conf --deploy-id ${deployId}`);
|
|
128
365
|
|
|
129
366
|
if (!fs.existsSync(`./engine-private/deploy/dd.router`))
|
|
130
|
-
fs.writeFileSync(`./engine-private/deploy/dd.router`,
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
);
|
|
137
|
-
const updateRepo = (stage = 1) => {
|
|
138
|
-
shellExec(`git add . && git commit -m "Add base deployId ${deployId} cluster files stage:${stage}"`);
|
|
139
|
-
shellExec(
|
|
140
|
-
`cd engine-private && git add . && git commit -m "Add base deployId ${deployId} cluster files stage:${stage}"`,
|
|
367
|
+
fs.writeFileSync(`./engine-private/deploy/dd.router`, deployId, 'utf8');
|
|
368
|
+
else
|
|
369
|
+
fs.writeFileSync(
|
|
370
|
+
`./engine-private/deploy/dd.router`,
|
|
371
|
+
fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8').trim() + `,${deployId}`,
|
|
372
|
+
'utf8',
|
|
141
373
|
);
|
|
142
|
-
};
|
|
143
|
-
updateRepo(1);
|
|
144
|
-
shellExec(`node bin run --build --dev sync`);
|
|
145
|
-
updateRepo(2);
|
|
146
|
-
shellExec(`node bin run --build sync`);
|
|
147
|
-
updateRepo(3);
|
|
148
374
|
}
|
|
149
375
|
|
|
150
376
|
return { deployIdFolder: folder, deployId };
|
|
151
377
|
},
|
|
152
|
-
/**
|
|
153
|
-
* @method buildTmpConf
|
|
154
|
-
* @description Builds the temporary configuration of the server.
|
|
155
|
-
* @param {string} [folder='./conf'] - The folder.
|
|
156
|
-
* @memberof ServerConfBuilder
|
|
157
|
-
*/
|
|
158
|
-
buildTmpConf: function (folder = './conf') {
|
|
159
|
-
for (const confType of Object.keys(this.default))
|
|
160
|
-
fs.writeFileSync(`${folder}/conf.${confType}.json`, JSON.stringify(this.default[confType], null, 4), 'utf8');
|
|
161
|
-
},
|
|
162
378
|
/**
|
|
163
379
|
* @method buildProxyByDeployId
|
|
164
380
|
* @description Builds the proxy by deploy ID.
|
|
@@ -178,7 +394,7 @@ const Config = {
|
|
|
178
394
|
)
|
|
179
395
|
confPath = `./engine-private/conf/${deployId}/conf.server.dev.${subConf}.json`;
|
|
180
396
|
|
|
181
|
-
const serverConf =
|
|
397
|
+
const serverConf = loadConfServerJson(confPath);
|
|
182
398
|
|
|
183
399
|
for (const host of Object.keys(loadReplicas(deployId, serverConf)))
|
|
184
400
|
this.default.server[host] = {
|
|
@@ -206,7 +422,6 @@ const Config = {
|
|
|
206
422
|
}
|
|
207
423
|
}
|
|
208
424
|
}
|
|
209
|
-
this.buildTmpConf();
|
|
210
425
|
},
|
|
211
426
|
};
|
|
212
427
|
|
|
@@ -217,7 +432,7 @@ const Config = {
|
|
|
217
432
|
* @param {string} [subConf=''] - The sub configuration.
|
|
218
433
|
* @memberof ServerConfBuilder
|
|
219
434
|
*/
|
|
220
|
-
const loadConf = (deployId =
|
|
435
|
+
const loadConf = (deployId = DEFAULT_DEPLOY_ID, subConf) => {
|
|
221
436
|
if (deployId === 'current') {
|
|
222
437
|
console.log(process.env.DEPLOY_ID);
|
|
223
438
|
return;
|
|
@@ -225,20 +440,19 @@ const loadConf = (deployId = 'dd-default', subConf) => {
|
|
|
225
440
|
if (deployId === 'clean') {
|
|
226
441
|
const path = '.';
|
|
227
442
|
fs.removeSync(`${path}/.env`);
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
443
|
+
fs.removeSync(`${path}/.env.production`);
|
|
444
|
+
fs.removeSync(`${path}/.env.development`);
|
|
445
|
+
fs.removeSync(`${path}/.env.test`);
|
|
231
446
|
if (fs.existsSync(`${path}/jsdoc.json`)) shellExec(`git checkout ${path}/jsdoc.json`);
|
|
232
447
|
shellExec(`git checkout ${path}/package.json`);
|
|
233
448
|
shellExec(`git checkout ${path}/package-lock.json`);
|
|
234
449
|
return;
|
|
235
450
|
}
|
|
236
|
-
const folder =
|
|
237
|
-
|
|
238
|
-
: `./engine-private/conf/${deployId}`;
|
|
451
|
+
const folder = getConfFolder(deployId);
|
|
452
|
+
|
|
239
453
|
if (!fs.existsSync(folder)) Config.deployIdFactory(deployId);
|
|
240
|
-
|
|
241
|
-
if (
|
|
454
|
+
|
|
455
|
+
if (subConf) process.env.DEPLOY_SUB_CONF = subConf;
|
|
242
456
|
|
|
243
457
|
for (const typeConf of Object.keys(Config.default)) {
|
|
244
458
|
let srcConf = fs.readFileSync(`${folder}/conf.${typeConf}.json`, 'utf8');
|
|
@@ -246,13 +460,14 @@ const loadConf = (deployId = 'dd-default', subConf) => {
|
|
|
246
460
|
const devConfPath = `${folder}/conf.${typeConf}.dev${subConf ? `.${subConf}` : ''}.json`;
|
|
247
461
|
if (fs.existsSync(devConfPath)) srcConf = fs.readFileSync(devConfPath, 'utf8');
|
|
248
462
|
}
|
|
249
|
-
|
|
250
|
-
|
|
463
|
+
let parsed = JSON.parse(srcConf);
|
|
464
|
+
if (typeConf === 'server') parsed = loadReplicas(deployId, parsed);
|
|
465
|
+
Config.default[typeConf] = parsed;
|
|
251
466
|
}
|
|
252
467
|
fs.writeFileSync(`./.env.production`, fs.readFileSync(`${folder}/.env.production`, 'utf8'), 'utf8');
|
|
253
468
|
fs.writeFileSync(`./.env.development`, fs.readFileSync(`${folder}/.env.development`, 'utf8'), 'utf8');
|
|
254
469
|
fs.writeFileSync(`./.env.test`, fs.readFileSync(`${folder}/.env.test`, 'utf8'), 'utf8');
|
|
255
|
-
const NODE_ENV = process.env.NODE_ENV;
|
|
470
|
+
const NODE_ENV = process.env.NODE_ENV || 'development';
|
|
256
471
|
if (NODE_ENV) {
|
|
257
472
|
const subPathEnv = fs.existsSync(`${folder}/.env.${NODE_ENV}.${subConf}`)
|
|
258
473
|
? `${folder}/.env.${NODE_ENV}.${subConf}`
|
|
@@ -644,7 +859,7 @@ const cloneSrcComponents = async ({ toOptions, fromOptions }) => {
|
|
|
644
859
|
* @memberof ServerConfBuilder
|
|
645
860
|
*/
|
|
646
861
|
const buildProxyRouter = () => {
|
|
647
|
-
const confServer =
|
|
862
|
+
const confServer = newInstance(Config.default.server);
|
|
648
863
|
let currentPort = parseInt(process.env.PORT) + 1;
|
|
649
864
|
const proxyRouter = {};
|
|
650
865
|
for (const host of Object.keys(confServer)) {
|
|
@@ -726,9 +941,7 @@ const pathPortAssignmentFactory = async (deployId, router, confServer) => {
|
|
|
726
941
|
const singleReplicas = await fs.readdir(`./engine-private/replica`);
|
|
727
942
|
for (let replica of singleReplicas) {
|
|
728
943
|
if (replica.startsWith(deployId)) {
|
|
729
|
-
const replicaServerConf =
|
|
730
|
-
fs.readFileSync(`./engine-private/replica/${replica}/conf.server.json`, 'utf8'),
|
|
731
|
-
);
|
|
944
|
+
const replicaServerConf = loadConfServerJson(`./engine-private/replica/${replica}/conf.server.json`);
|
|
732
945
|
for (const host of Object.keys(replicaServerConf)) {
|
|
733
946
|
const pathPortAssignment = [];
|
|
734
947
|
for (const path of Object.keys(replicaServerConf[host])) {
|
|
@@ -906,7 +1119,7 @@ const buildReplicaId = ({ deployId, replica }) => `${deployId}-${replica.slice(1
|
|
|
906
1119
|
* @returns {object} - The data deploy.
|
|
907
1120
|
* @memberof ServerConfBuilder
|
|
908
1121
|
*/
|
|
909
|
-
const getDataDeploy = (
|
|
1122
|
+
const getDataDeploy = async (
|
|
910
1123
|
options = {
|
|
911
1124
|
buildSingleReplica: false,
|
|
912
1125
|
disableSyncEnvPort: false,
|
|
@@ -931,13 +1144,16 @@ const getDataDeploy = (
|
|
|
931
1144
|
for (const deployObj of dataDeploy) {
|
|
932
1145
|
const serverConf = loadReplicas(
|
|
933
1146
|
deployObj.deployId,
|
|
934
|
-
|
|
1147
|
+
loadConfServerJson(`./engine-private/conf/${deployObj.deployId}/conf.server.json`),
|
|
935
1148
|
);
|
|
936
1149
|
let replicaDataDeploy = [];
|
|
937
1150
|
for (const host of Object.keys(serverConf))
|
|
938
1151
|
for (const path of Object.keys(serverConf[host])) {
|
|
939
1152
|
if (serverConf[host][path].replicas && serverConf[host][path].singleReplica) {
|
|
940
|
-
if (options && options.buildSingleReplica)
|
|
1153
|
+
if (options && options.buildSingleReplica)
|
|
1154
|
+
await Underpost.repo.client(deployObj.deployId, '', host, path, {
|
|
1155
|
+
singleReplica: true,
|
|
1156
|
+
});
|
|
941
1157
|
replicaDataDeploy = replicaDataDeploy.concat(
|
|
942
1158
|
serverConf[host][path].replicas.map((r) => {
|
|
943
1159
|
return {
|
|
@@ -952,7 +1168,8 @@ const getDataDeploy = (
|
|
|
952
1168
|
if (replicaDataDeploy.length > 0) buildDataDeploy = buildDataDeploy.concat(replicaDataDeploy);
|
|
953
1169
|
}
|
|
954
1170
|
|
|
955
|
-
if (!options.disableSyncEnvPort && options.buildSingleReplica)
|
|
1171
|
+
if (!options.disableSyncEnvPort && options.buildSingleReplica)
|
|
1172
|
+
await Underpost.repo.client(undefined, '', '', '', { syncEnvPort: true });
|
|
956
1173
|
|
|
957
1174
|
logger.info('Deployments configured', buildDataDeploy);
|
|
958
1175
|
|
|
@@ -980,6 +1197,7 @@ const validateTemplatePath = (absolutePath = '') => {
|
|
|
980
1197
|
return false;
|
|
981
1198
|
}
|
|
982
1199
|
if (absolutePath.match('conf.dd-') && absolutePath.match('.js')) return false;
|
|
1200
|
+
if (absolutePath.match('jsdoc.dd-') && absolutePath.match('.json')) return false;
|
|
983
1201
|
if (
|
|
984
1202
|
absolutePath.match('src/client/services/') &&
|
|
985
1203
|
!clients.find((p) => absolutePath.match(`src/client/services/${p}/`))
|
|
@@ -1057,18 +1275,6 @@ const awaitDeployMonitor = async (init = false, deltaMs = 1000) => {
|
|
|
1057
1275
|
if (Underpost.env.get('await-deploy')) return await awaitDeployMonitor();
|
|
1058
1276
|
};
|
|
1059
1277
|
|
|
1060
|
-
/**
|
|
1061
|
-
* @method getCronBackUpFolder
|
|
1062
|
-
* @description Gets the cron back up folder.
|
|
1063
|
-
* @param {string} host - The host.
|
|
1064
|
-
* @param {string} path - The path.
|
|
1065
|
-
* @returns {string} - The cron back up folder.
|
|
1066
|
-
* @memberof ServerConfBuilder
|
|
1067
|
-
*/
|
|
1068
|
-
const getCronBackUpFolder = (host = '', path = '') => {
|
|
1069
|
-
return `${host}${path.replace(/\\/g, '/').replace(`/`, '-')}`;
|
|
1070
|
-
};
|
|
1071
|
-
|
|
1072
1278
|
/**
|
|
1073
1279
|
* @method mergeFile
|
|
1074
1280
|
* @description Merges the file.
|
|
@@ -1102,10 +1308,7 @@ const mergeFile = async (parts = [], outputFilePath) => {
|
|
|
1102
1308
|
* @memberof ServerConfBuilder
|
|
1103
1309
|
*/
|
|
1104
1310
|
const rebuildConfFactory = ({ deployId, valkey, mongo }) => {
|
|
1105
|
-
const confServer = loadReplicas(
|
|
1106
|
-
deployId,
|
|
1107
|
-
JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
|
|
1108
|
-
);
|
|
1311
|
+
const confServer = loadReplicas(deployId, loadConfServerJson(`./engine-private/conf/${deployId}/conf.server.json`));
|
|
1109
1312
|
const hosts = {};
|
|
1110
1313
|
for (const host of Object.keys(confServer)) {
|
|
1111
1314
|
hosts[host] = {};
|
|
@@ -1116,9 +1319,7 @@ const rebuildConfFactory = ({ deployId, valkey, mongo }) => {
|
|
|
1116
1319
|
if (singleReplica) {
|
|
1117
1320
|
for (const replica of replicas) {
|
|
1118
1321
|
const deployIdReplica = buildReplicaId({ replica, deployId });
|
|
1119
|
-
const confServerReplica =
|
|
1120
|
-
fs.readFileSync(`./engine-private/replica/${deployIdReplica}/conf.server.json`, 'utf8'),
|
|
1121
|
-
);
|
|
1322
|
+
const confServerReplica = loadConfServerJson(`./engine-private/replica/${deployIdReplica}/conf.server.json`);
|
|
1122
1323
|
for (const _host of Object.keys(confServerReplica)) {
|
|
1123
1324
|
for (const _path of Object.keys(confServerReplica[_host])) {
|
|
1124
1325
|
hosts[host][_path] = { replica: { host, path } };
|
|
@@ -1166,56 +1367,6 @@ const getPathsSSR = (conf) => {
|
|
|
1166
1367
|
return paths;
|
|
1167
1368
|
};
|
|
1168
1369
|
|
|
1169
|
-
/**
|
|
1170
|
-
* @method CmdUnderpost
|
|
1171
|
-
* @description The command factory.
|
|
1172
|
-
* @memberof ServerConfBuilder
|
|
1173
|
-
* @namespace CmdUnderpost
|
|
1174
|
-
*/
|
|
1175
|
-
const Cmd = {
|
|
1176
|
-
/**
|
|
1177
|
-
* @method run
|
|
1178
|
-
* @description Runs the deploy.
|
|
1179
|
-
* @returns {string} - The run command.
|
|
1180
|
-
* @memberof Cmd
|
|
1181
|
-
*/
|
|
1182
|
-
run: () => `npm start`,
|
|
1183
|
-
/**
|
|
1184
|
-
* @method build
|
|
1185
|
-
* @description Builds the deploy.
|
|
1186
|
-
* @param {string} deployId - The deploy ID.
|
|
1187
|
-
* @returns {string} - The build command.
|
|
1188
|
-
* @memberof CmdUnderpost
|
|
1189
|
-
*/
|
|
1190
|
-
build: (deployId) => `node bin/deploy build-full-client ${deployId}`,
|
|
1191
|
-
/**
|
|
1192
|
-
* @method conf
|
|
1193
|
-
* @description Configures the deploy.
|
|
1194
|
-
* @param {string} deployId - The deploy ID.
|
|
1195
|
-
* @param {string} env - The environment.
|
|
1196
|
-
* @returns {string} - The conf command.
|
|
1197
|
-
* @memberof CmdUnderpost
|
|
1198
|
-
*/
|
|
1199
|
-
conf: (deployId, env) => `node bin/deploy conf ${deployId} ${env ? env : 'production'}`,
|
|
1200
|
-
/**
|
|
1201
|
-
* @method replica
|
|
1202
|
-
* @description Builds the replica.
|
|
1203
|
-
* @param {string} deployId - The deploy ID.
|
|
1204
|
-
* @param {string} host - The host.
|
|
1205
|
-
* @param {string} path - The path.
|
|
1206
|
-
* @returns {string} - The replica command.
|
|
1207
|
-
* @memberof CmdUnderpost
|
|
1208
|
-
*/
|
|
1209
|
-
replica: (deployId, host, path) => `node bin/deploy build-single-replica ${deployId} ${host} ${path}`,
|
|
1210
|
-
/**
|
|
1211
|
-
* @method syncPorts
|
|
1212
|
-
* @description Syncs the ports.
|
|
1213
|
-
* @returns {string} - The sync ports command.
|
|
1214
|
-
* @memberof CmdUnderpost
|
|
1215
|
-
*/
|
|
1216
|
-
syncPorts: () => `node bin/deploy sync-env-port`,
|
|
1217
|
-
};
|
|
1218
|
-
|
|
1219
1370
|
/**
|
|
1220
1371
|
* @method splitFileFactory
|
|
1221
1372
|
* @description Splits the file factory.
|
|
@@ -1336,8 +1487,25 @@ const buildCliDoc = (program, oldVersion, newVersion) => {
|
|
|
1336
1487
|
md = md.replaceAll(oldVersion, newVersion);
|
|
1337
1488
|
fs.writeFileSync(`./src/client/public/nexodev/docs/references/Command Line Interface.md`, md, 'utf8');
|
|
1338
1489
|
fs.writeFileSync(`./CLI-HELP.md`, md, 'utf8');
|
|
1339
|
-
|
|
1340
|
-
|
|
1490
|
+
|
|
1491
|
+
// Update README.md: replace version and CLI index section between comment tags
|
|
1492
|
+
let readme = fs.readFileSync(`./README.md`, 'utf8');
|
|
1493
|
+
readme = readme.replaceAll(oldVersion, newVersion);
|
|
1494
|
+
const cliStartTag = '<!-- cli-index-start -->';
|
|
1495
|
+
const cliEndTag = '<!-- cli-index-end -->';
|
|
1496
|
+
const startIdx = readme.indexOf(cliStartTag);
|
|
1497
|
+
const endIdx = readme.indexOf(cliEndTag);
|
|
1498
|
+
if (startIdx !== -1 && endIdx !== -1) {
|
|
1499
|
+
readme =
|
|
1500
|
+
readme.substring(0, startIdx) +
|
|
1501
|
+
cliStartTag +
|
|
1502
|
+
'\n' +
|
|
1503
|
+
baseOptions +
|
|
1504
|
+
'\n' +
|
|
1505
|
+
cliEndTag +
|
|
1506
|
+
readme.substring(endIdx + cliEndTag.length);
|
|
1507
|
+
}
|
|
1508
|
+
fs.writeFileSync('./README.md', readme, 'utf8');
|
|
1341
1509
|
};
|
|
1342
1510
|
|
|
1343
1511
|
/**
|
|
@@ -1348,19 +1516,26 @@ const buildCliDoc = (program, oldVersion, newVersion) => {
|
|
|
1348
1516
|
* @param {boolean} options.singleReplica - The single replica.
|
|
1349
1517
|
* @param {Array} options.replicas - The replicas.
|
|
1350
1518
|
* @param {string} options.redirect - The redirect.
|
|
1519
|
+
* @param {boolean} [options.peer=false] - Whether peer is enabled on the parent singleReplica path (used for port offset estimation when replica conf is not yet built).
|
|
1351
1520
|
* @returns {object} - The instance context.
|
|
1352
1521
|
* @memberof ServerConfBuilder
|
|
1353
1522
|
*/
|
|
1354
|
-
const getInstanceContext = async (options = { deployId, singleReplica, replicas, redirect: '' }) => {
|
|
1355
|
-
const { deployId, singleReplica, replicas, redirect } = options;
|
|
1523
|
+
const getInstanceContext = async (options = { deployId, singleReplica, replicas, redirect: '', peer: false }) => {
|
|
1524
|
+
const { deployId, singleReplica, replicas, redirect, peer } = options;
|
|
1356
1525
|
let singleReplicaOffsetPortSum = 0;
|
|
1357
1526
|
|
|
1358
1527
|
if (singleReplica && replicas && replicas.length > 0) {
|
|
1359
1528
|
for (const replica of replicas) {
|
|
1360
1529
|
const replicaDeployId = buildReplicaId({ deployId, replica });
|
|
1361
|
-
const
|
|
1362
|
-
|
|
1363
|
-
|
|
1530
|
+
const replicaConfPath = `./engine-private/replica/${replicaDeployId}/conf.server.json`;
|
|
1531
|
+
if (!fs.existsSync(replicaConfPath)) {
|
|
1532
|
+
// Replica folder not built yet (e.g. dev mode without prior build);
|
|
1533
|
+
// estimate port offset: 1 per replica path + 1 extra if peer is enabled on the parent singleReplica config
|
|
1534
|
+
singleReplicaOffsetPortSum++;
|
|
1535
|
+
if (peer) singleReplicaOffsetPortSum++;
|
|
1536
|
+
continue;
|
|
1537
|
+
}
|
|
1538
|
+
const confReplicaServer = loadConfServerJson(replicaConfPath);
|
|
1364
1539
|
for (const host of Object.keys(confReplicaServer)) {
|
|
1365
1540
|
for (const path of Object.keys(confReplicaServer[host])) {
|
|
1366
1541
|
singleReplicaOffsetPortSum++;
|
|
@@ -1480,15 +1655,7 @@ const isDeployRunnerContext = (path, options) => !options.build && path && path
|
|
|
1480
1655
|
* @returns {boolean} - The dev proxy context.
|
|
1481
1656
|
* @memberof ServerConfBuilder
|
|
1482
1657
|
*/
|
|
1483
|
-
const isDevProxyContext = () =>
|
|
1484
|
-
try {
|
|
1485
|
-
if (process.argv[2] === 'proxy') return true;
|
|
1486
|
-
if (!process.argv[6].startsWith('localhost')) return false;
|
|
1487
|
-
return new URL('http://' + process.argv[6]).hostname ? true : false;
|
|
1488
|
-
} catch {
|
|
1489
|
-
return false;
|
|
1490
|
-
}
|
|
1491
|
-
};
|
|
1658
|
+
const isDevProxyContext = () => (process.argv.find((arg) => arg === 'proxy') ? true : false);
|
|
1492
1659
|
|
|
1493
1660
|
/**
|
|
1494
1661
|
* @method devProxyHostFactory
|
|
@@ -1501,10 +1668,14 @@ const isDevProxyContext = () => {
|
|
|
1501
1668
|
* @returns {string} - The dev proxy host.
|
|
1502
1669
|
* @memberof ServerConfBuilder
|
|
1503
1670
|
*/
|
|
1504
|
-
const devProxyHostFactory = (options = { host: 'default.net', includeHttp: false, port: 80, tls: false }) =>
|
|
1505
|
-
|
|
1506
|
-
(options.port ? options.port : options.tls ? 443 : 80) + parseInt(process.env.DEV_PROXY_PORT_OFFSET)
|
|
1507
|
-
|
|
1671
|
+
const devProxyHostFactory = (options = { host: 'default.net', includeHttp: false, port: 80, tls: false }) => {
|
|
1672
|
+
const resolvedPort =
|
|
1673
|
+
(options.port ? options.port : options.tls ? 443 : 80) + parseInt(process.env.DEV_PROXY_PORT_OFFSET);
|
|
1674
|
+
const isDefaultPort = (options.tls && resolvedPort === 443) || (!options.tls && resolvedPort === 80);
|
|
1675
|
+
const protocol = options.includeHttp ? (options.tls ? 'https://' : 'http://') : '';
|
|
1676
|
+
const hostname = options.host ? options.host : 'localhost';
|
|
1677
|
+
return `${protocol}${hostname}${isDefaultPort ? '' : `:${resolvedPort}`}`;
|
|
1678
|
+
};
|
|
1508
1679
|
|
|
1509
1680
|
/**
|
|
1510
1681
|
* @method isTlsDevProxy
|
|
@@ -1512,7 +1683,7 @@ const devProxyHostFactory = (options = { host: 'default.net', includeHttp: false
|
|
|
1512
1683
|
* @returns {boolean} - The TLS dev proxy status.
|
|
1513
1684
|
* @memberof ServerConfBuilder
|
|
1514
1685
|
*/
|
|
1515
|
-
const isTlsDevProxy = () => process.env.NODE_ENV !== 'production' && process.argv
|
|
1686
|
+
const isTlsDevProxy = () => process.env.NODE_ENV !== 'production' && !!process.argv.find((arg) => arg === 'tls');
|
|
1516
1687
|
|
|
1517
1688
|
/**
|
|
1518
1689
|
* @method getTlsHosts
|
|
@@ -1524,17 +1695,52 @@ const isTlsDevProxy = () => process.env.NODE_ENV !== 'production' && process.arg
|
|
|
1524
1695
|
const getTlsHosts = (confServer) =>
|
|
1525
1696
|
Array.from(new Set(Object.keys(confServer).map((h) => new URL('https://' + h).hostname)));
|
|
1526
1697
|
|
|
1698
|
+
/**
|
|
1699
|
+
* Reads a `conf.server.json` file from disk, parses it, and resolves all `env:` secret
|
|
1700
|
+
* references using {@link resolveConfSecrets}.
|
|
1701
|
+
*
|
|
1702
|
+
* Reads and parses a `conf.server.json` file from disk. The `env:` secret
|
|
1703
|
+
* references are **preserved** by default so that build/deploy tooling never
|
|
1704
|
+
* accidentally strips them. Callers that need the actual secret values
|
|
1705
|
+
* (e.g. database or mailer modules) should explicitly wrap the result with
|
|
1706
|
+
* {@link resolveConfSecrets}.
|
|
1707
|
+
*
|
|
1708
|
+
* @method loadConfServerJson
|
|
1709
|
+
* @param {string} jsonPath - Absolute or relative path to the `conf.server.json` file.
|
|
1710
|
+
* @param {object} [options] - Optional settings.
|
|
1711
|
+
* @param {boolean} [options.resolve=false] - When `true`, resolves `env:` references
|
|
1712
|
+
* via {@link resolveConfSecrets} before returning.
|
|
1713
|
+
* @returns {object} The parsed server configuration object (secrets unresolved unless
|
|
1714
|
+
* `options.resolve` is `true`).
|
|
1715
|
+
* @throws {Error} If the file does not exist or cannot be parsed.
|
|
1716
|
+
* @memberof ServerConfBuilder
|
|
1717
|
+
*
|
|
1718
|
+
* @example
|
|
1719
|
+
* // Structure-only read (env: strings preserved)
|
|
1720
|
+
* const confServer = loadConfServerJson(`./engine-private/conf/${deployId}/conf.server.json`);
|
|
1721
|
+
*
|
|
1722
|
+
* @example
|
|
1723
|
+
* // Resolved read (env: strings replaced with process.env values)
|
|
1724
|
+
* const confServer = loadConfServerJson(`./engine-private/conf/${deployId}/conf.server.json`, { resolve: true });
|
|
1725
|
+
*/
|
|
1726
|
+
const loadConfServerJson = (jsonPath, options) => {
|
|
1727
|
+
if (!fs.existsSync(jsonPath)) {
|
|
1728
|
+
throw new Error(`loadConfServerJson: configuration file not found: ${jsonPath}`);
|
|
1729
|
+
}
|
|
1730
|
+
const raw = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
|
|
1731
|
+
return options && options.resolve === true ? resolveConfSecrets(raw) : raw;
|
|
1732
|
+
};
|
|
1733
|
+
|
|
1527
1734
|
export {
|
|
1528
|
-
Cmd,
|
|
1529
1735
|
Config,
|
|
1530
1736
|
loadConf,
|
|
1531
1737
|
loadReplicas,
|
|
1532
1738
|
cloneConf,
|
|
1533
1739
|
getCapVariableName,
|
|
1740
|
+
addClientConf,
|
|
1534
1741
|
buildClientSrc,
|
|
1535
1742
|
buildApiSrc,
|
|
1536
1743
|
addApiConf,
|
|
1537
|
-
addClientConf,
|
|
1538
1744
|
addWsConf,
|
|
1539
1745
|
buildWsSrc,
|
|
1540
1746
|
cloneSrcComponents,
|
|
@@ -1542,7 +1748,6 @@ export {
|
|
|
1542
1748
|
getDataDeploy,
|
|
1543
1749
|
validateTemplatePath,
|
|
1544
1750
|
buildReplicaId,
|
|
1545
|
-
getCronBackUpFolder,
|
|
1546
1751
|
mergeFile,
|
|
1547
1752
|
getPathsSSR,
|
|
1548
1753
|
buildKindPorts,
|
|
@@ -1564,4 +1769,11 @@ export {
|
|
|
1564
1769
|
devProxyHostFactory,
|
|
1565
1770
|
isTlsDevProxy,
|
|
1566
1771
|
getTlsHosts,
|
|
1772
|
+
resolveConfSecrets,
|
|
1773
|
+
loadConfServerJson,
|
|
1774
|
+
getConfFolder,
|
|
1775
|
+
getConfFilePath,
|
|
1776
|
+
readConfJson,
|
|
1777
|
+
DEFAULT_DEPLOY_ID,
|
|
1778
|
+
loadCronDeployEnv,
|
|
1567
1779
|
};
|