underpost 2.8.1 → 2.8.7
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/.dockerignore +1 -0
- package/.github/workflows/ghpkg.yml +19 -49
- package/.github/workflows/npmpkg.yml +67 -0
- package/.github/workflows/publish.yml +5 -5
- package/.github/workflows/pwa-microservices-template.page.yml +12 -4
- package/.github/workflows/pwa-microservices-template.test.yml +2 -2
- package/.vscode/extensions.json +18 -71
- package/.vscode/settings.json +20 -3
- package/AUTHORS.md +16 -5
- package/CHANGELOG.md +123 -3
- package/Dockerfile +27 -70
- package/README.md +39 -29
- package/bin/build.js +186 -0
- package/bin/db.js +2 -24
- package/bin/deploy.js +1467 -236
- package/bin/file.js +67 -16
- package/bin/hwt.js +0 -10
- package/bin/index.js +1 -77
- package/bin/ssl.js +19 -11
- package/bin/util.js +9 -104
- package/bin/vs.js +26 -2
- package/cli.md +451 -0
- package/conf.js +29 -138
- package/docker-compose.yml +1 -1
- package/jsdoc.json +1 -1
- package/manifests/calico-custom-resources.yaml +25 -0
- package/manifests/deployment/adminer/deployment.yaml +32 -0
- package/manifests/deployment/adminer/kustomization.yaml +7 -0
- package/manifests/deployment/adminer/service.yaml +13 -0
- package/manifests/deployment/fastapi/backend-deployment.yml +120 -0
- package/manifests/deployment/fastapi/backend-service.yml +19 -0
- package/manifests/deployment/fastapi/frontend-deployment.yml +54 -0
- package/manifests/deployment/fastapi/frontend-service.yml +15 -0
- package/manifests/deployment/kafka/deployment.yaml +69 -0
- package/manifests/deployment/mongo-express/deployment.yaml +60 -0
- package/manifests/deployment/phpmyadmin/deployment.yaml +54 -0
- package/manifests/kind-config-dev.yaml +12 -0
- package/manifests/kind-config.yaml +12 -0
- package/manifests/kubeadm-calico-config.yaml +119 -0
- package/manifests/letsencrypt-prod.yaml +15 -0
- package/manifests/mariadb/config.yaml +10 -0
- package/manifests/mariadb/kustomization.yaml +9 -0
- package/manifests/mariadb/pv.yaml +12 -0
- package/manifests/mariadb/pvc.yaml +10 -0
- package/manifests/mariadb/secret.yaml +8 -0
- package/manifests/mariadb/service.yaml +10 -0
- package/manifests/mariadb/statefulset.yaml +55 -0
- package/manifests/mongodb/backup-access.yaml +16 -0
- package/manifests/mongodb/backup-cronjob.yaml +42 -0
- package/manifests/mongodb/backup-pv-pvc.yaml +22 -0
- package/manifests/mongodb/configmap.yaml +26 -0
- package/manifests/mongodb/headless-service.yaml +10 -0
- package/manifests/mongodb/kustomization.yaml +11 -0
- package/manifests/mongodb/pv-pvc.yaml +23 -0
- package/manifests/mongodb/statefulset.yaml +125 -0
- package/manifests/mongodb-4.4/kustomization.yaml +7 -0
- package/manifests/mongodb-4.4/pv-pvc.yaml +23 -0
- package/manifests/mongodb-4.4/service-deployment.yaml +63 -0
- package/manifests/postgresql/configmap.yaml +9 -0
- package/manifests/postgresql/kustomization.yaml +10 -0
- package/manifests/postgresql/pv.yaml +15 -0
- package/manifests/postgresql/pvc.yaml +13 -0
- package/manifests/postgresql/service.yaml +10 -0
- package/manifests/postgresql/statefulset.yaml +37 -0
- package/manifests/valkey/kustomization.yaml +7 -0
- package/manifests/valkey/service.yaml +17 -0
- package/manifests/valkey/statefulset.yaml +41 -0
- package/package.json +127 -136
- package/src/api/core/core.service.js +1 -1
- package/src/api/default/default.service.js +1 -1
- package/src/api/user/user.model.js +16 -3
- package/src/api/user/user.service.js +15 -12
- package/src/cli/cluster.js +389 -0
- package/src/cli/cron.js +121 -0
- package/src/cli/db.js +222 -0
- package/src/cli/deploy.js +487 -0
- package/src/cli/env.js +58 -0
- package/src/cli/fs.js +161 -0
- package/src/cli/image.js +66 -0
- package/src/cli/index.js +312 -0
- package/src/cli/monitor.js +236 -0
- package/src/cli/repository.js +128 -0
- package/src/cli/script.js +53 -0
- package/src/cli/secrets.js +37 -0
- package/src/cli/test.js +118 -0
- package/src/client/components/core/Account.js +28 -24
- package/src/client/components/core/Auth.js +22 -4
- package/src/client/components/core/Blockchain.js +1 -1
- package/src/client/components/core/CalendarCore.js +128 -121
- package/src/client/components/core/CommonJs.js +283 -19
- package/src/client/components/core/CssCore.js +16 -4
- package/src/client/components/core/Docs.js +1 -2
- package/src/client/components/core/DropDown.js +5 -1
- package/src/client/components/core/EventsUI.js +3 -3
- package/src/client/components/core/FileExplorer.js +86 -78
- package/src/client/components/core/Input.js +22 -6
- package/src/client/components/core/JoyStick.js +2 -2
- package/src/client/components/core/LoadingAnimation.js +3 -12
- package/src/client/components/core/LogIn.js +3 -3
- package/src/client/components/core/LogOut.js +1 -1
- package/src/client/components/core/Modal.js +54 -20
- package/src/client/components/core/Panel.js +109 -90
- package/src/client/components/core/PanelForm.js +23 -30
- package/src/client/components/core/Recover.js +3 -3
- package/src/client/components/core/RichText.js +1 -11
- package/src/client/components/core/Router.js +3 -1
- package/src/client/components/core/Scroll.js +1 -0
- package/src/client/components/core/SignUp.js +2 -2
- package/src/client/components/core/Translate.js +47 -9
- package/src/client/components/core/Validator.js +9 -1
- package/src/client/components/core/VanillaJs.js +0 -9
- package/src/client/components/core/Worker.js +34 -31
- package/src/client/components/default/RoutesDefault.js +3 -2
- package/src/client/services/core/core.service.js +15 -10
- package/src/client/services/default/default.management.js +46 -37
- package/src/client/ssr/Render.js +6 -1
- package/src/client/ssr/body/CacheControl.js +2 -3
- package/src/client/sw/default.sw.js +3 -3
- package/src/db/mongo/MongooseDB.js +29 -1
- package/src/index.js +101 -19
- package/src/mailer/MailerProvider.js +3 -0
- package/src/runtime/lampp/Dockerfile +65 -0
- package/src/runtime/lampp/Lampp.js +1 -13
- package/src/runtime/xampp/Xampp.js +0 -13
- package/src/server/auth.js +3 -3
- package/src/server/backup.js +49 -93
- package/src/server/client-build.js +49 -46
- package/src/server/client-formatted.js +6 -3
- package/src/server/conf.js +297 -55
- package/src/server/dns.js +75 -62
- package/src/server/downloader.js +0 -8
- package/src/server/json-schema.js +77 -0
- package/src/server/logger.js +15 -10
- package/src/server/network.js +20 -161
- package/src/server/peer.js +2 -2
- package/src/server/process.js +25 -2
- package/src/server/proxy.js +7 -29
- package/src/server/runtime.js +53 -40
- package/src/server/ssl.js +1 -1
- package/src/server/start.js +122 -0
- package/src/server/valkey.js +27 -11
- package/test/api.test.js +0 -8
- package/src/dns.js +0 -22
- package/src/server/prompt-optimizer.js +0 -28
- package/startup.js +0 -11
package/src/server/conf.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import dotenv from 'dotenv';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
capFirst,
|
|
5
|
+
getCapVariableName,
|
|
6
|
+
newInstance,
|
|
7
|
+
orderArrayFromAttrInt,
|
|
8
|
+
range,
|
|
9
|
+
timer,
|
|
10
|
+
} from '../client/components/core/CommonJs.js';
|
|
4
11
|
import * as dir from 'path';
|
|
5
12
|
import cliProgress from 'cli-progress';
|
|
6
13
|
import cliSpinners from 'cli-spinners';
|
|
@@ -9,22 +16,13 @@ import colors from 'colors';
|
|
|
9
16
|
import { loggerFactory } from './logger.js';
|
|
10
17
|
import { shellExec } from './process.js';
|
|
11
18
|
import { DefaultConf } from '../../conf.js';
|
|
12
|
-
import ncp from 'copy-paste';
|
|
13
19
|
import read from 'read';
|
|
14
20
|
import splitFile from 'split-file';
|
|
15
21
|
import axios from 'axios';
|
|
16
|
-
import https from 'https';
|
|
17
22
|
import { ssrFactory } from './client-formatted.js';
|
|
18
23
|
|
|
19
|
-
// axios.defaults.baseURL = BASE_URL;
|
|
20
|
-
|
|
21
|
-
const httpsAgent = new https.Agent({
|
|
22
|
-
rejectUnauthorized: false,
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
axios.defaults.httpsAgent = httpsAgent;
|
|
26
|
-
|
|
27
24
|
colors.enable();
|
|
25
|
+
|
|
28
26
|
dotenv.config();
|
|
29
27
|
|
|
30
28
|
const logger = loggerFactory(import.meta);
|
|
@@ -33,21 +31,26 @@ const logger = loggerFactory(import.meta);
|
|
|
33
31
|
|
|
34
32
|
const Config = {
|
|
35
33
|
default: DefaultConf,
|
|
36
|
-
build: async function (options = { folder: '' }) {
|
|
34
|
+
build: async function (options = { folder: '' }, deployContext, deployList, subConf) {
|
|
35
|
+
if (!deployContext) deployContext = process.argv[2];
|
|
37
36
|
if (!fs.existsSync(`./tmp`)) fs.mkdirSync(`./tmp`, { recursive: true });
|
|
38
37
|
fs.writeFileSync(`./tmp/await-deploy`, '', 'utf8');
|
|
39
|
-
if (fs.existsSync(`./engine-private/conf/${
|
|
40
|
-
|
|
38
|
+
if (fs.existsSync(`./engine-private/conf/${deployContext}`))
|
|
39
|
+
return loadConf(deployContext, process.env.NODE_ENV, subConf);
|
|
40
|
+
if (fs.existsSync(`./engine-private/replica/${deployContext}`))
|
|
41
|
+
return loadConf(deployContext, process.env.NODE_ENV, subConf);
|
|
41
42
|
|
|
42
|
-
if (
|
|
43
|
+
if (deployContext === 'deploy') return;
|
|
43
44
|
|
|
44
|
-
if (
|
|
45
|
+
if (deployContext === 'proxy') {
|
|
46
|
+
if (!deployList) deployList = process.argv[3];
|
|
47
|
+
if (!subConf) subConf = process.argv[4];
|
|
45
48
|
this.default.server = {};
|
|
46
|
-
for (const deployId of
|
|
49
|
+
for (const deployId of deployList.split(',')) {
|
|
47
50
|
let confPath = `./engine-private/conf/${deployId}/conf.server.json`;
|
|
48
51
|
const privateConfDevPath = fs.existsSync(`./engine-private/replica/${deployId}/conf.server.json`)
|
|
49
52
|
? `./engine-private/replica/${deployId}/conf.server.json`
|
|
50
|
-
: `./engine-private/conf/${deployId}/conf.server.dev.${
|
|
53
|
+
: `./engine-private/conf/${deployId}/conf.server.dev.${subConf}.json`;
|
|
51
54
|
const confDevPath = fs.existsSync(privateConfDevPath)
|
|
52
55
|
? privateConfDevPath
|
|
53
56
|
: `./engine-private/conf/${deployId}/conf.server.dev.json`;
|
|
@@ -55,7 +58,7 @@ const Config = {
|
|
|
55
58
|
if (process.env.NODE_ENV === 'development' && fs.existsSync(confDevPath)) confPath = confDevPath;
|
|
56
59
|
const serverConf = JSON.parse(fs.readFileSync(confPath, 'utf8'));
|
|
57
60
|
|
|
58
|
-
for (const host of Object.keys(loadReplicas(serverConf))) {
|
|
61
|
+
for (const host of Object.keys(loadReplicas(serverConf, deployContext, subConf))) {
|
|
59
62
|
if (serverConf[host]['/'])
|
|
60
63
|
this.default.server[host] = {
|
|
61
64
|
...this.default.server[host],
|
|
@@ -85,7 +88,15 @@ const Config = {
|
|
|
85
88
|
},
|
|
86
89
|
};
|
|
87
90
|
|
|
88
|
-
const loadConf = (deployId) => {
|
|
91
|
+
const loadConf = (deployId, envInput, subConf) => {
|
|
92
|
+
if (deployId === 'clean') {
|
|
93
|
+
shellExec(`git checkout package.json`);
|
|
94
|
+
shellExec(`git checkout .env.production`);
|
|
95
|
+
shellExec(`git checkout .env.development`);
|
|
96
|
+
shellExec(`git checkout .env.test`);
|
|
97
|
+
shellExec(`git checkout jsdoc.json`);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
89
100
|
const folder = fs.existsSync(`./engine-private/replica/${deployId}`)
|
|
90
101
|
? `./engine-private/replica/${deployId}`
|
|
91
102
|
: `./engine-private/conf/${deployId}`;
|
|
@@ -102,7 +113,8 @@ const loadConf = (deployId) => {
|
|
|
102
113
|
? fs.readFileSync(`${folder}/conf.${typeConf}.json`, 'utf8')
|
|
103
114
|
: JSON.stringify(Config.default[typeConf]);
|
|
104
115
|
if (process.env.NODE_ENV === 'development' && typeConf === 'server') {
|
|
105
|
-
|
|
116
|
+
if (!subConf) subConf = process.argv[3];
|
|
117
|
+
const devConfPath = `${folder}/conf.${typeConf}.dev${subConf ? `.${subConf}` : ''}.json`;
|
|
106
118
|
if (fs.existsSync(devConfPath)) srcConf = fs.readFileSync(devConfPath, 'utf8');
|
|
107
119
|
}
|
|
108
120
|
if (typeConf === 'server') srcConf = JSON.stringify(loadReplicas(JSON.parse(srcConf)), null, 4);
|
|
@@ -111,27 +123,34 @@ const loadConf = (deployId) => {
|
|
|
111
123
|
fs.writeFileSync(`./.env.production`, fs.readFileSync(`${folder}/.env.production`, 'utf8'), 'utf8');
|
|
112
124
|
fs.writeFileSync(`./.env.development`, fs.readFileSync(`${folder}/.env.development`, 'utf8'), 'utf8');
|
|
113
125
|
fs.writeFileSync(`./.env.test`, fs.readFileSync(`${folder}/.env.test`, 'utf8'), 'utf8');
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
126
|
+
const NODE_ENV = envInput || process.env.NODE_ENV;
|
|
127
|
+
if (NODE_ENV) {
|
|
128
|
+
fs.writeFileSync(`./.env`, fs.readFileSync(`${folder}/.env.${NODE_ENV}`, 'utf8'), 'utf8');
|
|
129
|
+
const env = dotenv.parse(fs.readFileSync(`${folder}/.env.${NODE_ENV}`, 'utf8'));
|
|
117
130
|
process.env = {
|
|
118
131
|
...process.env,
|
|
119
132
|
...env,
|
|
120
133
|
};
|
|
121
134
|
}
|
|
122
|
-
|
|
135
|
+
const originPackageJson = JSON.parse(fs.readFileSync(`./package.json`, 'utf8'));
|
|
136
|
+
const packageJson = JSON.parse(fs.readFileSync(`${folder}/package.json`, 'utf8'));
|
|
137
|
+
originPackageJson.scripts.start = packageJson.scripts.start;
|
|
138
|
+
packageJson.scripts = originPackageJson.scripts;
|
|
139
|
+
fs.writeFileSync(`./package.json`, JSON.stringify(packageJson, null, 4), 'utf8');
|
|
123
140
|
return { folder, deployId };
|
|
124
141
|
};
|
|
125
142
|
|
|
126
|
-
const loadReplicas = (confServer) => {
|
|
143
|
+
const loadReplicas = (confServer, deployContext, subConf) => {
|
|
144
|
+
if (!deployContext) deployContext = process.argv[2];
|
|
145
|
+
if (!subConf) subConf = process.argv[3];
|
|
127
146
|
for (const host of Object.keys(confServer)) {
|
|
128
147
|
for (const path of Object.keys(confServer[host])) {
|
|
129
148
|
const { replicas, singleReplica } = confServer[host][path];
|
|
130
149
|
if (
|
|
131
150
|
replicas &&
|
|
132
|
-
(
|
|
151
|
+
(deployContext === 'proxy' ||
|
|
133
152
|
!singleReplica ||
|
|
134
|
-
(singleReplica && process.env.NODE_ENV === 'development' && !
|
|
153
|
+
(singleReplica && process.env.NODE_ENV === 'development' && !subConf))
|
|
135
154
|
)
|
|
136
155
|
for (const replicaPath of replicas) {
|
|
137
156
|
confServer[host][replicaPath] = newInstance(confServer[host][path]);
|
|
@@ -480,6 +499,82 @@ const buildProxyRouter = () => {
|
|
|
480
499
|
return proxyRouter;
|
|
481
500
|
};
|
|
482
501
|
|
|
502
|
+
const pathPortAssignmentFactory = (router, confServer) => {
|
|
503
|
+
const pathPortAssignmentData = {};
|
|
504
|
+
for (const host of Object.keys(confServer)) {
|
|
505
|
+
const pathPortAssignment = [];
|
|
506
|
+
for (const path of Object.keys(confServer[host])) {
|
|
507
|
+
const { peer } = confServer[host][path];
|
|
508
|
+
if (!router[`${host}${path === '/' ? '' : path}`]) continue;
|
|
509
|
+
const port = parseInt(router[`${host}${path === '/' ? '' : path}`].split(':')[2]);
|
|
510
|
+
// logger.info('', { host, port, path });
|
|
511
|
+
pathPortAssignment.push({
|
|
512
|
+
port,
|
|
513
|
+
path,
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
if (peer) {
|
|
517
|
+
// logger.info('', { host, port: port + 1, path: '/peer' });
|
|
518
|
+
pathPortAssignment.push({
|
|
519
|
+
port: port + 1,
|
|
520
|
+
path: '/peer',
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
pathPortAssignmentData[host] = pathPortAssignment;
|
|
525
|
+
}
|
|
526
|
+
return pathPortAssignmentData;
|
|
527
|
+
};
|
|
528
|
+
|
|
529
|
+
const deployRangePortFactory = (router) => {
|
|
530
|
+
const ports = Object.values(router).map((p) => parseInt(p.split(':')[2]));
|
|
531
|
+
const fromPort = Math.min(...ports);
|
|
532
|
+
const toPort = Math.max(...ports);
|
|
533
|
+
return { ports, fromPort, toPort };
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
const buildKindPorts = (from, to) =>
|
|
537
|
+
range(parseInt(from), parseInt(to))
|
|
538
|
+
.map(
|
|
539
|
+
(port) => ` - name: 'tcp-${port}'
|
|
540
|
+
protocol: TCP
|
|
541
|
+
port: ${port}
|
|
542
|
+
targetPort: ${port}
|
|
543
|
+
- name: 'udp-${port}'
|
|
544
|
+
protocol: UDP
|
|
545
|
+
port: ${port}
|
|
546
|
+
targetPort: ${port}
|
|
547
|
+
`,
|
|
548
|
+
)
|
|
549
|
+
.join('\n');
|
|
550
|
+
|
|
551
|
+
const buildPortProxyRouter = (port, proxyRouter) => {
|
|
552
|
+
const hosts = proxyRouter[port];
|
|
553
|
+
const router = {};
|
|
554
|
+
// build router
|
|
555
|
+
Object.keys(hosts).map((hostKey) => {
|
|
556
|
+
let { host, path, target, proxy, peer } = hosts[hostKey];
|
|
557
|
+
if (process.argv.includes('localhost') && process.env.NODE_ENV === 'development') host = `localhost`;
|
|
558
|
+
|
|
559
|
+
if (!proxy.includes(port)) return;
|
|
560
|
+
const absoluteHost = [80, 443].includes(port)
|
|
561
|
+
? `${host}${path === '/' ? '' : path}`
|
|
562
|
+
: `${host}:${port}${path === '/' ? '' : path}`;
|
|
563
|
+
|
|
564
|
+
if (process.argv.includes('localhost')) {
|
|
565
|
+
if (!(absoluteHost in router)) router[absoluteHost] = target;
|
|
566
|
+
} else router[absoluteHost] = target;
|
|
567
|
+
}); // order router
|
|
568
|
+
|
|
569
|
+
if (Object.keys(router).length === 0) return router;
|
|
570
|
+
|
|
571
|
+
const reOrderRouter = {};
|
|
572
|
+
for (const absoluteHostKey of orderArrayFromAttrInt(Object.keys(router), 'length'))
|
|
573
|
+
reOrderRouter[absoluteHostKey] = router[absoluteHostKey];
|
|
574
|
+
|
|
575
|
+
return reOrderRouter;
|
|
576
|
+
};
|
|
577
|
+
|
|
483
578
|
const cliBar = async (time = 5000) => {
|
|
484
579
|
// create new progress bar
|
|
485
580
|
const b = new cliProgress.SingleBar({
|
|
@@ -528,9 +623,25 @@ const cliSpinner = async (time = 5000, message0, message1, color, type = 'dots')
|
|
|
528
623
|
const buildReplicaId = ({ deployId, replica }) => `${deployId}-${replica.slice(1)}`;
|
|
529
624
|
|
|
530
625
|
const getDataDeploy = (
|
|
531
|
-
options = {
|
|
626
|
+
options = {
|
|
627
|
+
buildSingleReplica: false,
|
|
628
|
+
deployGroupId: '',
|
|
629
|
+
deployId: '',
|
|
630
|
+
disableSyncEnvPort: false,
|
|
631
|
+
deployIdConcat: [],
|
|
632
|
+
},
|
|
532
633
|
) => {
|
|
533
|
-
let dataDeploy =
|
|
634
|
+
let dataDeploy =
|
|
635
|
+
options.deployGroupId === 'dd'
|
|
636
|
+
? fs.readFileSync(`./engine-private/deploy/${options.deployGroupId}.router`, 'utf8')
|
|
637
|
+
: fs.readFileSync(`./engine-private/deploy/${options.deployGroupId}`, 'utf8');
|
|
638
|
+
|
|
639
|
+
dataDeploy = dataDeploy
|
|
640
|
+
.split(',')
|
|
641
|
+
.map((deployId) => deployId.trim())
|
|
642
|
+
.filter((deployId) => deployId);
|
|
643
|
+
|
|
644
|
+
if (options.deployIdConcat) dataDeploy = dataDeploy.concat(options.deployIdConcat);
|
|
534
645
|
|
|
535
646
|
if (options.deployId) dataDeploy = dataDeploy.filter((d) => d === options.deployId);
|
|
536
647
|
|
|
@@ -588,6 +699,7 @@ const validateTemplatePath = (absolutePath = '') => {
|
|
|
588
699
|
if (absolutePath.match('src/api') && !confServer.apis.find((p) => absolutePath.match(`src/api/${p}/`))) {
|
|
589
700
|
return false;
|
|
590
701
|
}
|
|
702
|
+
if (absolutePath.match('conf.dd-') && absolutePath.match('.js')) return false;
|
|
591
703
|
if (
|
|
592
704
|
absolutePath.match('src/client/services/') &&
|
|
593
705
|
!clients.find((p) => absolutePath.match(`src/client/services/${p}/`))
|
|
@@ -651,7 +763,7 @@ const validateTemplatePath = (absolutePath = '') => {
|
|
|
651
763
|
return true;
|
|
652
764
|
};
|
|
653
765
|
|
|
654
|
-
const deployTest = async (dataDeploy) => {
|
|
766
|
+
const deployTest = async (dataDeploy = [{ deployId: 'default' }]) => {
|
|
655
767
|
const failed = [];
|
|
656
768
|
for (const deploy of dataDeploy) {
|
|
657
769
|
const deployServerConfPath = fs.existsSync(`./engine-private/replica/${deploy.deployId}/conf.server.json`)
|
|
@@ -695,6 +807,12 @@ const deployTest = async (dataDeploy) => {
|
|
|
695
807
|
return { failed };
|
|
696
808
|
};
|
|
697
809
|
|
|
810
|
+
const awaitDeployMonitor = async (init = false, deltaMs = 1000) => {
|
|
811
|
+
if (init) fs.writeFileSync(`./tmp/await-deploy`, '', 'utf8');
|
|
812
|
+
await timer(deltaMs);
|
|
813
|
+
if (fs.existsSync(`./tmp/await-deploy`)) return await awaitDeployMonitor();
|
|
814
|
+
};
|
|
815
|
+
|
|
698
816
|
const getDeployGroupId = () => {
|
|
699
817
|
const deployGroupIndexArg = process.argv.findIndex((a) => a.match(`deploy-group:`));
|
|
700
818
|
if (deployGroupIndexArg > -1) return process.argv[deployGroupIndexArg].split(':')[1].trim();
|
|
@@ -764,15 +882,16 @@ const deployRun = async (dataDeploy, currentAttempt = 1) => {
|
|
|
764
882
|
if (failed.length > 0) {
|
|
765
883
|
for (const deploy of failed) logger.error(deploy.deployId, Cmd.run(deploy.deployId));
|
|
766
884
|
if (currentAttempt === maxAttempts) return logger.error(`max deploy attempts exceeded`);
|
|
767
|
-
|
|
885
|
+
await read({ prompt: 'Press enter to retry failed processes\n' });
|
|
768
886
|
currentAttempt++;
|
|
769
887
|
await deployRun(failed, currentAttempt);
|
|
770
888
|
} else logger.info(`Deploy process successfully`);
|
|
771
889
|
};
|
|
772
890
|
|
|
773
|
-
const restoreMacroDb = async (deployGroupId = '') => {
|
|
891
|
+
const restoreMacroDb = async (deployGroupId = '', deployId = null) => {
|
|
774
892
|
const dataDeploy = await getDataDeploy({ deployGroupId, buildSingleReplica: false });
|
|
775
893
|
for (const deployGroup of dataDeploy) {
|
|
894
|
+
if (deployId && deployGroup.deployId !== deployId) continue;
|
|
776
895
|
if (!deployGroup.replicaHost) {
|
|
777
896
|
const deployServerConfPath = `./engine-private/conf/${deployGroup.deployId}/conf.server.json`;
|
|
778
897
|
const serverConf = JSON.parse(fs.readFileSync(deployServerConfPath, 'utf8'));
|
|
@@ -790,13 +909,10 @@ const restoreMacroDb = async (deployGroupId = '') => {
|
|
|
790
909
|
}
|
|
791
910
|
};
|
|
792
911
|
|
|
793
|
-
const
|
|
794
|
-
const names = JSON.parse(fs.readFileSync(baseBackJsonPath, 'utf8')).map((p) =>
|
|
795
|
-
p.replaceAll(`\\`, '/').replaceAll('C:/', '/').replaceAll('c:/', '/'),
|
|
796
|
-
);
|
|
912
|
+
const mergeFile = async (parts = [], outputFilePath) => {
|
|
797
913
|
await new Promise((resolve) => {
|
|
798
914
|
splitFile
|
|
799
|
-
.mergeFiles(
|
|
915
|
+
.mergeFiles(parts, outputFilePath)
|
|
800
916
|
.then(() => {
|
|
801
917
|
resolve();
|
|
802
918
|
})
|
|
@@ -807,6 +923,53 @@ const mergeBackUp = async (baseBackJsonPath, outputFilePath) => {
|
|
|
807
923
|
});
|
|
808
924
|
};
|
|
809
925
|
|
|
926
|
+
const rebuildConfFactory = ({ deployId, valkey, mongo }) => {
|
|
927
|
+
const confServer = loadReplicas(
|
|
928
|
+
JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
|
|
929
|
+
);
|
|
930
|
+
const hosts = {};
|
|
931
|
+
for (const host of Object.keys(confServer)) {
|
|
932
|
+
hosts[host] = {};
|
|
933
|
+
for (const path of Object.keys(confServer[host])) {
|
|
934
|
+
if (!confServer[host][path].db) continue;
|
|
935
|
+
const { singleReplica, replicas, db } = confServer[host][path];
|
|
936
|
+
const { provider } = db;
|
|
937
|
+
if (singleReplica) {
|
|
938
|
+
for (const replica of replicas) {
|
|
939
|
+
const deployIdReplica = buildReplicaId({ replica, deployId });
|
|
940
|
+
const confServerReplica = JSON.parse(
|
|
941
|
+
fs.readFileSync(`./engine-private/replica/${deployIdReplica}/conf.server.json`, 'utf8'),
|
|
942
|
+
);
|
|
943
|
+
for (const _host of Object.keys(confServerReplica)) {
|
|
944
|
+
for (const _path of Object.keys(confServerReplica[_host])) {
|
|
945
|
+
hosts[host][_path] = { replica: { host, path } };
|
|
946
|
+
confServerReplica[_host][_path].valkey = valkey;
|
|
947
|
+
switch (provider) {
|
|
948
|
+
case 'mongoose':
|
|
949
|
+
confServerReplica[_host][_path].db.host = mongo.host;
|
|
950
|
+
break;
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
fs.writeFileSync(
|
|
955
|
+
`./engine-private/replica/${deployIdReplica}/conf.server.json`,
|
|
956
|
+
JSON.stringify(confServerReplica, null, 4),
|
|
957
|
+
'utf8',
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
} else hosts[host][path] = {};
|
|
961
|
+
confServer[host][path].valkey = valkey;
|
|
962
|
+
switch (provider) {
|
|
963
|
+
case 'mongoose':
|
|
964
|
+
confServer[host][path].db.host = mongo.host;
|
|
965
|
+
break;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
fs.writeFileSync(`./engine-private/conf/${deployId}/conf.server.json`, JSON.stringify(confServer, null, 4), 'utf8');
|
|
970
|
+
return { hosts };
|
|
971
|
+
};
|
|
972
|
+
|
|
810
973
|
const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deployId: '' }) => {
|
|
811
974
|
const { host, path, conf, deployId } = options;
|
|
812
975
|
const { runtime, db, git, directory } = conf[host][path];
|
|
@@ -848,11 +1011,13 @@ const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deplo
|
|
|
848
1011
|
{
|
|
849
1012
|
if (process.argv.includes('cron')) {
|
|
850
1013
|
cmd = `mysql -u ${user} -p${password} ${name} < ${baseBackUpPath}/${currentBackupTimestamp}/${name}.sql`;
|
|
851
|
-
if (fs.existsSync(`${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`))
|
|
852
|
-
|
|
853
|
-
`${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`,
|
|
854
|
-
|
|
855
|
-
|
|
1014
|
+
if (fs.existsSync(`${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`)) {
|
|
1015
|
+
const names = JSON.parse(
|
|
1016
|
+
fs.readFileSync(`${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`, 'utf8'),
|
|
1017
|
+
).map((p) => p.replaceAll(`\\`, '/').replaceAll('C:/', '/').replaceAll('c:/', '/'));
|
|
1018
|
+
|
|
1019
|
+
await mergeFile(names, `${baseBackUpPath}/${currentBackupTimestamp}/${name}.sql`);
|
|
1020
|
+
}
|
|
856
1021
|
} else {
|
|
857
1022
|
cmd = `mysql -u ${user} -p${password} ${name} < ${
|
|
858
1023
|
backupPath ? backupPath : `./engine-private/sql-backups/${name}.sql`
|
|
@@ -863,15 +1028,23 @@ const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deplo
|
|
|
863
1028
|
backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
|
|
864
1029
|
}/${name}-parths.json`,
|
|
865
1030
|
)
|
|
866
|
-
)
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
1031
|
+
) {
|
|
1032
|
+
const names = JSON.parse(
|
|
1033
|
+
fs.readFileSync(
|
|
1034
|
+
`${
|
|
1035
|
+
backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
|
|
1036
|
+
}/${name}-parths.json`,
|
|
1037
|
+
'utf8',
|
|
1038
|
+
),
|
|
1039
|
+
).map((p) => p.replaceAll(`\\`, '/').replaceAll('C:/', '/').replaceAll('c:/', '/'));
|
|
1040
|
+
|
|
1041
|
+
await mergeFile(
|
|
1042
|
+
names,
|
|
871
1043
|
`${
|
|
872
1044
|
backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
|
|
873
1045
|
}/${name}.sql`,
|
|
874
1046
|
);
|
|
1047
|
+
}
|
|
875
1048
|
}
|
|
876
1049
|
}
|
|
877
1050
|
break;
|
|
@@ -890,20 +1063,31 @@ const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deplo
|
|
|
890
1063
|
return cmd;
|
|
891
1064
|
};
|
|
892
1065
|
|
|
1066
|
+
const getPathsSSR = (conf) => {
|
|
1067
|
+
const paths = ['src/client/ssr/Render.js'];
|
|
1068
|
+
for (const o of conf.head) paths.push(`src/client/ssr/head/${o}.js`);
|
|
1069
|
+
for (const o of conf.body) paths.push(`src/client/ssr/body/${o}.js`);
|
|
1070
|
+
for (const o of Object.keys(conf.mailer)) paths.push(`src/client/ssr/mailer/${conf.mailer[o]}.js`);
|
|
1071
|
+
for (const o of conf.offline) paths.push(`src/client/ssr/mailer/${o.client}.js`);
|
|
1072
|
+
for (const o of conf.pages) paths.push(`src/client/ssr/pages/${o.client}.js`);
|
|
1073
|
+
return paths;
|
|
1074
|
+
};
|
|
1075
|
+
|
|
893
1076
|
const Cmd = {
|
|
894
1077
|
delete: (deployId) => `pm2 delete ${deployId}`,
|
|
895
|
-
run: (
|
|
1078
|
+
run: () => `npm start`,
|
|
896
1079
|
build: (deployId) => `node bin/deploy build-full-client ${deployId}${process.argv.includes('l') ? ' l' : ''}`,
|
|
897
1080
|
conf: (deployId, env) => `node bin/deploy conf ${deployId} ${env ? env : 'production'}`,
|
|
898
1081
|
replica: (deployId, host, path) => `node bin/deploy build-single-replica ${deployId} ${host} ${path}`,
|
|
899
1082
|
syncPorts: (deployGroupId) => `node bin/deploy sync-env-port ${deployGroupId}`,
|
|
900
|
-
cron: (
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
1083
|
+
cron: (deployList, jobList, name, expression, options) =>
|
|
1084
|
+
`pm2 start ./bin/index.js --no-autorestart --instances 1 --cron "${expression}" --name ${name} -- cron ${
|
|
1085
|
+
options?.itc ? `--itc ` : ''
|
|
1086
|
+
}${options?.git ? `--git ` : ''}${deployList} ${jobList}`,
|
|
904
1087
|
};
|
|
905
1088
|
|
|
906
1089
|
const fixDependencies = async () => {
|
|
1090
|
+
return;
|
|
907
1091
|
// sed -i "$line_number s,.*,$new_text," "$file"
|
|
908
1092
|
// sed -i "$line_number c \\$new_text" "$file"
|
|
909
1093
|
const dep = fs.readFileSync(`./node_modules/peer/dist/module.mjs`, 'utf8');
|
|
@@ -933,14 +1117,60 @@ const maintenanceMiddleware = (req, res, port, proxyRouter) => {
|
|
|
933
1117
|
}
|
|
934
1118
|
};
|
|
935
1119
|
|
|
1120
|
+
const splitFileFactory = async (name, _path) => {
|
|
1121
|
+
const stats = fs.statSync(_path);
|
|
1122
|
+
const maxSizeInBytes = 1024 * 1024 * 50; // 50 mb
|
|
1123
|
+
const fileSizeInBytes = stats.size;
|
|
1124
|
+
if (fileSizeInBytes > maxSizeInBytes) {
|
|
1125
|
+
logger.info('splitFileFactory input', { name, from: _path });
|
|
1126
|
+
return await new Promise((resolve) => {
|
|
1127
|
+
splitFile
|
|
1128
|
+
.splitFileBySize(_path, maxSizeInBytes) // 50 mb
|
|
1129
|
+
.then((names) => {
|
|
1130
|
+
logger.info('splitFileFactory output', { parts: names });
|
|
1131
|
+
fs.writeFileSync(
|
|
1132
|
+
`${_path.split('/').slice(0, -1).join('/')}/${name}-parths.json`,
|
|
1133
|
+
JSON.stringify(names, null, 4),
|
|
1134
|
+
'utf8',
|
|
1135
|
+
);
|
|
1136
|
+
fs.removeSync(_path);
|
|
1137
|
+
return resolve(true);
|
|
1138
|
+
})
|
|
1139
|
+
.catch((err) => {
|
|
1140
|
+
console.log('Error: ', err);
|
|
1141
|
+
return resolve(false);
|
|
1142
|
+
});
|
|
1143
|
+
});
|
|
1144
|
+
}
|
|
1145
|
+
return false;
|
|
1146
|
+
};
|
|
1147
|
+
|
|
936
1148
|
const setUpProxyMaintenanceServer = ({ deployGroupId }) => {
|
|
937
1149
|
shellExec(`pm2 kill`);
|
|
938
1150
|
shellExec(`node bin/deploy valkey-service`);
|
|
939
1151
|
const proxyDeployId = fs.readFileSync(`./engine-private/deploy/${deployGroupId}.proxy`, 'utf8').trim();
|
|
940
1152
|
shellExec(`node bin/deploy conf ${proxyDeployId} production`);
|
|
941
|
-
shellExec(`
|
|
1153
|
+
shellExec(`npm start ${proxyDeployId} maintenance`);
|
|
942
1154
|
};
|
|
943
1155
|
|
|
1156
|
+
const getNpmRootPath = () =>
|
|
1157
|
+
shellExec(`npm root -g`, {
|
|
1158
|
+
stdout: true,
|
|
1159
|
+
disableLog: true,
|
|
1160
|
+
silent: true,
|
|
1161
|
+
}).trim();
|
|
1162
|
+
|
|
1163
|
+
const getUnderpostRootPath = () => `${getNpmRootPath()}/underpost`;
|
|
1164
|
+
|
|
1165
|
+
const writeEnv = (envPath, envObj) =>
|
|
1166
|
+
fs.writeFileSync(
|
|
1167
|
+
envPath,
|
|
1168
|
+
Object.keys(envObj)
|
|
1169
|
+
.map((key) => `${key}=${envObj[key]}`)
|
|
1170
|
+
.join(`\n`),
|
|
1171
|
+
'utf8',
|
|
1172
|
+
);
|
|
1173
|
+
|
|
944
1174
|
export {
|
|
945
1175
|
Cmd,
|
|
946
1176
|
Config,
|
|
@@ -967,9 +1197,21 @@ export {
|
|
|
967
1197
|
deployRun,
|
|
968
1198
|
getCronBackUpFolder,
|
|
969
1199
|
getRestoreCronCmd,
|
|
970
|
-
|
|
1200
|
+
mergeFile,
|
|
971
1201
|
fixDependencies,
|
|
972
1202
|
getDeployId,
|
|
973
1203
|
maintenanceMiddleware,
|
|
974
1204
|
setUpProxyMaintenanceServer,
|
|
1205
|
+
getPathsSSR,
|
|
1206
|
+
buildKindPorts,
|
|
1207
|
+
buildPortProxyRouter,
|
|
1208
|
+
splitFileFactory,
|
|
1209
|
+
getNpmRootPath,
|
|
1210
|
+
getUnderpostRootPath,
|
|
1211
|
+
writeEnv,
|
|
1212
|
+
deployTest,
|
|
1213
|
+
pathPortAssignmentFactory,
|
|
1214
|
+
deployRangePortFactory,
|
|
1215
|
+
awaitDeployMonitor,
|
|
1216
|
+
rebuildConfFactory,
|
|
975
1217
|
};
|