underpost 3.0.3 → 3.1.0
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/ghpkg.ci.yml +1 -1
- package/.github/workflows/gitlab.ci.yml +1 -1
- package/.github/workflows/npmpkg.ci.yml +22 -7
- package/.github/workflows/publish.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 +146 -1
- package/CLI-HELP.md +71 -52
- package/README.md +2 -2
- package/bin/build.js +4 -1
- package/bin/deploy.js +150 -208
- package/bin/file.js +2 -1
- package/bin/vs.js +3 -3
- package/conf.js +30 -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-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 +48 -43
- package/scripts/k3s-node-setup.sh +1 -1
- 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/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 +4 -4
- package/src/cli/fs.js +0 -2
- package/src/cli/image.js +0 -3
- package/src/cli/index.js +27 -13
- package/src/cli/monitor.js +5 -6
- package/src/cli/repository.js +322 -35
- package/src/cli/run.js +118 -69
- package/src/cli/secrets.js +0 -3
- package/src/cli/ssh.js +1 -1
- package/src/client/components/core/AgGrid.js +20 -5
- package/src/client/components/core/Content.js +22 -3
- package/src/client/components/core/Docs.js +21 -4
- 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/public/default/sitemap +3 -3
- package/src/client/public/test/sitemap +3 -3
- 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 +7 -1
- package/src/runtime/lampp/Lampp.js +6 -13
- package/src/server/auth.js +6 -9
- package/src/server/backup.js +2 -3
- package/src/server/client-build-docs.js +178 -3
- package/src/server/client-build-live.js +9 -18
- package/src/server/client-build.js +175 -38
- package/src/server/client-dev-server.js +14 -13
- package/src/server/conf.js +357 -149
- 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/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 +5 -5
- package/src/server/tls.js +0 -2
- package/src/server.js +0 -4
- package/.env.development +0 -43
- package/.env.test +0 -43
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}/`))
|
|
@@ -1102,10 +1320,7 @@ const mergeFile = async (parts = [], outputFilePath) => {
|
|
|
1102
1320
|
* @memberof ServerConfBuilder
|
|
1103
1321
|
*/
|
|
1104
1322
|
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
|
-
);
|
|
1323
|
+
const confServer = loadReplicas(deployId, loadConfServerJson(`./engine-private/conf/${deployId}/conf.server.json`));
|
|
1109
1324
|
const hosts = {};
|
|
1110
1325
|
for (const host of Object.keys(confServer)) {
|
|
1111
1326
|
hosts[host] = {};
|
|
@@ -1116,9 +1331,7 @@ const rebuildConfFactory = ({ deployId, valkey, mongo }) => {
|
|
|
1116
1331
|
if (singleReplica) {
|
|
1117
1332
|
for (const replica of replicas) {
|
|
1118
1333
|
const deployIdReplica = buildReplicaId({ replica, deployId });
|
|
1119
|
-
const confServerReplica =
|
|
1120
|
-
fs.readFileSync(`./engine-private/replica/${deployIdReplica}/conf.server.json`, 'utf8'),
|
|
1121
|
-
);
|
|
1334
|
+
const confServerReplica = loadConfServerJson(`./engine-private/replica/${deployIdReplica}/conf.server.json`);
|
|
1122
1335
|
for (const _host of Object.keys(confServerReplica)) {
|
|
1123
1336
|
for (const _path of Object.keys(confServerReplica[_host])) {
|
|
1124
1337
|
hosts[host][_path] = { replica: { host, path } };
|
|
@@ -1166,56 +1379,6 @@ const getPathsSSR = (conf) => {
|
|
|
1166
1379
|
return paths;
|
|
1167
1380
|
};
|
|
1168
1381
|
|
|
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
1382
|
/**
|
|
1220
1383
|
* @method splitFileFactory
|
|
1221
1384
|
* @description Splits the file factory.
|
|
@@ -1348,19 +1511,26 @@ const buildCliDoc = (program, oldVersion, newVersion) => {
|
|
|
1348
1511
|
* @param {boolean} options.singleReplica - The single replica.
|
|
1349
1512
|
* @param {Array} options.replicas - The replicas.
|
|
1350
1513
|
* @param {string} options.redirect - The redirect.
|
|
1514
|
+
* @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
1515
|
* @returns {object} - The instance context.
|
|
1352
1516
|
* @memberof ServerConfBuilder
|
|
1353
1517
|
*/
|
|
1354
|
-
const getInstanceContext = async (options = { deployId, singleReplica, replicas, redirect: '' }) => {
|
|
1355
|
-
const { deployId, singleReplica, replicas, redirect } = options;
|
|
1518
|
+
const getInstanceContext = async (options = { deployId, singleReplica, replicas, redirect: '', peer: false }) => {
|
|
1519
|
+
const { deployId, singleReplica, replicas, redirect, peer } = options;
|
|
1356
1520
|
let singleReplicaOffsetPortSum = 0;
|
|
1357
1521
|
|
|
1358
1522
|
if (singleReplica && replicas && replicas.length > 0) {
|
|
1359
1523
|
for (const replica of replicas) {
|
|
1360
1524
|
const replicaDeployId = buildReplicaId({ deployId, replica });
|
|
1361
|
-
const
|
|
1362
|
-
|
|
1363
|
-
|
|
1525
|
+
const replicaConfPath = `./engine-private/replica/${replicaDeployId}/conf.server.json`;
|
|
1526
|
+
if (!fs.existsSync(replicaConfPath)) {
|
|
1527
|
+
// Replica folder not built yet (e.g. dev mode without prior build);
|
|
1528
|
+
// estimate port offset: 1 per replica path + 1 extra if peer is enabled on the parent singleReplica config
|
|
1529
|
+
singleReplicaOffsetPortSum++;
|
|
1530
|
+
if (peer) singleReplicaOffsetPortSum++;
|
|
1531
|
+
continue;
|
|
1532
|
+
}
|
|
1533
|
+
const confReplicaServer = loadConfServerJson(replicaConfPath);
|
|
1364
1534
|
for (const host of Object.keys(confReplicaServer)) {
|
|
1365
1535
|
for (const path of Object.keys(confReplicaServer[host])) {
|
|
1366
1536
|
singleReplicaOffsetPortSum++;
|
|
@@ -1480,15 +1650,7 @@ const isDeployRunnerContext = (path, options) => !options.build && path && path
|
|
|
1480
1650
|
* @returns {boolean} - The dev proxy context.
|
|
1481
1651
|
* @memberof ServerConfBuilder
|
|
1482
1652
|
*/
|
|
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
|
-
};
|
|
1653
|
+
const isDevProxyContext = () => (process.argv.find((arg) => arg === 'proxy') ? true : false);
|
|
1492
1654
|
|
|
1493
1655
|
/**
|
|
1494
1656
|
* @method devProxyHostFactory
|
|
@@ -1501,10 +1663,14 @@ const isDevProxyContext = () => {
|
|
|
1501
1663
|
* @returns {string} - The dev proxy host.
|
|
1502
1664
|
* @memberof ServerConfBuilder
|
|
1503
1665
|
*/
|
|
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
|
-
|
|
1666
|
+
const devProxyHostFactory = (options = { host: 'default.net', includeHttp: false, port: 80, tls: false }) => {
|
|
1667
|
+
const resolvedPort =
|
|
1668
|
+
(options.port ? options.port : options.tls ? 443 : 80) + parseInt(process.env.DEV_PROXY_PORT_OFFSET);
|
|
1669
|
+
const isDefaultPort = (options.tls && resolvedPort === 443) || (!options.tls && resolvedPort === 80);
|
|
1670
|
+
const protocol = options.includeHttp ? (options.tls ? 'https://' : 'http://') : '';
|
|
1671
|
+
const hostname = options.host ? options.host : 'localhost';
|
|
1672
|
+
return `${protocol}${hostname}${isDefaultPort ? '' : `:${resolvedPort}`}`;
|
|
1673
|
+
};
|
|
1508
1674
|
|
|
1509
1675
|
/**
|
|
1510
1676
|
* @method isTlsDevProxy
|
|
@@ -1512,7 +1678,7 @@ const devProxyHostFactory = (options = { host: 'default.net', includeHttp: false
|
|
|
1512
1678
|
* @returns {boolean} - The TLS dev proxy status.
|
|
1513
1679
|
* @memberof ServerConfBuilder
|
|
1514
1680
|
*/
|
|
1515
|
-
const isTlsDevProxy = () => process.env.NODE_ENV !== 'production' && process.argv
|
|
1681
|
+
const isTlsDevProxy = () => process.env.NODE_ENV !== 'production' && !!process.argv.find((arg) => arg === 'tls');
|
|
1516
1682
|
|
|
1517
1683
|
/**
|
|
1518
1684
|
* @method getTlsHosts
|
|
@@ -1524,17 +1690,52 @@ const isTlsDevProxy = () => process.env.NODE_ENV !== 'production' && process.arg
|
|
|
1524
1690
|
const getTlsHosts = (confServer) =>
|
|
1525
1691
|
Array.from(new Set(Object.keys(confServer).map((h) => new URL('https://' + h).hostname)));
|
|
1526
1692
|
|
|
1693
|
+
/**
|
|
1694
|
+
* Reads a `conf.server.json` file from disk, parses it, and resolves all `env:` secret
|
|
1695
|
+
* references using {@link resolveConfSecrets}.
|
|
1696
|
+
*
|
|
1697
|
+
* Reads and parses a `conf.server.json` file from disk. The `env:` secret
|
|
1698
|
+
* references are **preserved** by default so that build/deploy tooling never
|
|
1699
|
+
* accidentally strips them. Callers that need the actual secret values
|
|
1700
|
+
* (e.g. database or mailer modules) should explicitly wrap the result with
|
|
1701
|
+
* {@link resolveConfSecrets}.
|
|
1702
|
+
*
|
|
1703
|
+
* @method loadConfServerJson
|
|
1704
|
+
* @param {string} jsonPath - Absolute or relative path to the `conf.server.json` file.
|
|
1705
|
+
* @param {object} [options] - Optional settings.
|
|
1706
|
+
* @param {boolean} [options.resolve=false] - When `true`, resolves `env:` references
|
|
1707
|
+
* via {@link resolveConfSecrets} before returning.
|
|
1708
|
+
* @returns {object} The parsed server configuration object (secrets unresolved unless
|
|
1709
|
+
* `options.resolve` is `true`).
|
|
1710
|
+
* @throws {Error} If the file does not exist or cannot be parsed.
|
|
1711
|
+
* @memberof ServerConfBuilder
|
|
1712
|
+
*
|
|
1713
|
+
* @example
|
|
1714
|
+
* // Structure-only read (env: strings preserved)
|
|
1715
|
+
* const confServer = loadConfServerJson(`./engine-private/conf/${deployId}/conf.server.json`);
|
|
1716
|
+
*
|
|
1717
|
+
* @example
|
|
1718
|
+
* // Resolved read (env: strings replaced with process.env values)
|
|
1719
|
+
* const confServer = loadConfServerJson(`./engine-private/conf/${deployId}/conf.server.json`, { resolve: true });
|
|
1720
|
+
*/
|
|
1721
|
+
const loadConfServerJson = (jsonPath, options) => {
|
|
1722
|
+
if (!fs.existsSync(jsonPath)) {
|
|
1723
|
+
throw new Error(`loadConfServerJson: configuration file not found: ${jsonPath}`);
|
|
1724
|
+
}
|
|
1725
|
+
const raw = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
|
|
1726
|
+
return options && options.resolve === true ? resolveConfSecrets(raw) : raw;
|
|
1727
|
+
};
|
|
1728
|
+
|
|
1527
1729
|
export {
|
|
1528
|
-
Cmd,
|
|
1529
1730
|
Config,
|
|
1530
1731
|
loadConf,
|
|
1531
1732
|
loadReplicas,
|
|
1532
1733
|
cloneConf,
|
|
1533
1734
|
getCapVariableName,
|
|
1735
|
+
addClientConf,
|
|
1534
1736
|
buildClientSrc,
|
|
1535
1737
|
buildApiSrc,
|
|
1536
1738
|
addApiConf,
|
|
1537
|
-
addClientConf,
|
|
1538
1739
|
addWsConf,
|
|
1539
1740
|
buildWsSrc,
|
|
1540
1741
|
cloneSrcComponents,
|
|
@@ -1564,4 +1765,11 @@ export {
|
|
|
1564
1765
|
devProxyHostFactory,
|
|
1565
1766
|
isTlsDevProxy,
|
|
1566
1767
|
getTlsHosts,
|
|
1768
|
+
resolveConfSecrets,
|
|
1769
|
+
loadConfServerJson,
|
|
1770
|
+
getConfFolder,
|
|
1771
|
+
getConfFilePath,
|
|
1772
|
+
readConfJson,
|
|
1773
|
+
DEFAULT_DEPLOY_ID,
|
|
1774
|
+
loadCronDeployEnv,
|
|
1567
1775
|
};
|