@underpostnet/underpost 2.8.1 → 2.8.5
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 +20 -50
- package/.github/workflows/npmpkg.yml +67 -0
- package/.github/workflows/publish.yml +5 -5
- package/.github/workflows/pwa-microservices-template.page.yml +13 -5
- package/.github/workflows/pwa-microservices-template.test.yml +2 -2
- package/.vscode/extensions.json +17 -71
- package/.vscode/settings.json +14 -3
- package/AUTHORS.md +16 -5
- package/CHANGELOG.md +79 -3
- package/Dockerfile +24 -66
- package/README.md +1 -28
- package/bin/build.js +161 -0
- package/bin/db.js +2 -24
- package/bin/deploy.js +111 -82
- package/bin/file.js +59 -16
- package/bin/index.js +168 -58
- package/bin/ssl.js +19 -11
- package/bin/util.js +9 -97
- package/bin/vs.js +25 -2
- package/conf.js +31 -138
- package/docker-compose.yml +1 -1
- package/manifests/core/kustomization.yaml +11 -0
- package/manifests/core/underpost-engine-backup-access.yaml +16 -0
- package/manifests/core/underpost-engine-backup-pv-pvc.yaml +22 -0
- package/manifests/core/underpost-engine-headless-service.yaml +10 -0
- package/manifests/core/underpost-engine-mongodb-backup-cronjob.yaml +40 -0
- package/manifests/core/underpost-engine-mongodb-configmap.yaml +26 -0
- package/manifests/core/underpost-engine-pv-pvc.yaml +23 -0
- package/manifests/core/underpost-engine-statefulset.yaml +91 -0
- package/manifests/deployment/mongo-express/deployment.yaml +60 -0
- package/manifests/deployment/phpmyadmin/deployment.yaml +54 -0
- package/manifests/kind-config.yaml +12 -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/valkey/kustomization.yaml +7 -0
- package/manifests/valkey/service.yaml +17 -0
- package/manifests/valkey/statefulset.yaml +39 -0
- package/manifests/valkey/underpost-engine-valkey-service.yaml +17 -0
- package/manifests/valkey/underpost-engine-valkey-statefulset.yaml +39 -0
- package/package.json +26 -31
- package/src/api/core/core.service.js +1 -1
- package/src/api/user/user.model.js +16 -3
- package/src/api/user/user.service.js +1 -1
- package/src/cli/cluster.js +154 -0
- package/src/cli/cron.js +90 -0
- package/src/cli/db.js +148 -0
- package/src/cli/deploy.js +277 -0
- package/src/cli/env.js +52 -0
- package/src/cli/image.js +125 -0
- package/src/cli/repository.js +104 -0
- package/src/cli/script.js +29 -0
- package/src/cli/secrets.js +37 -0
- package/src/cli/test.js +83 -0
- package/src/client/components/core/Auth.js +22 -4
- package/src/client/components/core/CalendarCore.js +115 -49
- package/src/client/components/core/CommonJs.js +231 -19
- package/src/client/components/core/Css.js +1 -0
- package/src/client/components/core/CssCore.js +6 -0
- package/src/client/components/core/DropDown.js +5 -1
- package/src/client/components/core/Input.js +18 -4
- package/src/client/components/core/Modal.js +10 -6
- package/src/client/components/core/Panel.js +84 -25
- package/src/client/components/core/PanelForm.js +4 -18
- package/src/client/components/core/Scroll.js +1 -0
- 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/services/default/default.management.js +4 -2
- package/src/client/ssr/body/CacheControl.js +2 -2
- package/src/db/mongo/MongooseDB.js +13 -1
- package/src/index.js +77 -19
- 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 +4 -23
- package/src/server/client-formatted.js +5 -3
- package/src/server/conf.js +193 -45
- package/src/server/dns.js +49 -67
- package/src/server/logger.js +15 -10
- package/src/server/network.js +17 -43
- package/src/server/process.js +25 -2
- package/src/server/proxy.js +4 -26
- package/src/server/runtime.js +14 -29
- package/src/server/ssl.js +1 -1
- package/src/server/valkey.js +2 -0
- 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,7 +16,6 @@ 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';
|
|
@@ -18,13 +24,14 @@ import { ssrFactory } from './client-formatted.js';
|
|
|
18
24
|
|
|
19
25
|
// axios.defaults.baseURL = BASE_URL;
|
|
20
26
|
|
|
21
|
-
const httpsAgent = new https.Agent({
|
|
22
|
-
|
|
23
|
-
});
|
|
27
|
+
// const httpsAgent = new https.Agent({
|
|
28
|
+
// rejectUnauthorized: false,
|
|
29
|
+
// });
|
|
24
30
|
|
|
25
|
-
axios.defaults.httpsAgent = httpsAgent;
|
|
31
|
+
// axios.defaults.httpsAgent = httpsAgent;
|
|
26
32
|
|
|
27
33
|
colors.enable();
|
|
34
|
+
|
|
28
35
|
dotenv.config();
|
|
29
36
|
|
|
30
37
|
const logger = loggerFactory(import.meta);
|
|
@@ -33,21 +40,26 @@ const logger = loggerFactory(import.meta);
|
|
|
33
40
|
|
|
34
41
|
const Config = {
|
|
35
42
|
default: DefaultConf,
|
|
36
|
-
build: async function (options = { folder: '' }) {
|
|
43
|
+
build: async function (options = { folder: '' }, deployContext, deployList, subConf) {
|
|
44
|
+
if (!deployContext) deployContext = process.argv[2];
|
|
37
45
|
if (!fs.existsSync(`./tmp`)) fs.mkdirSync(`./tmp`, { recursive: true });
|
|
38
46
|
fs.writeFileSync(`./tmp/await-deploy`, '', 'utf8');
|
|
39
|
-
if (fs.existsSync(`./engine-private/conf/${
|
|
40
|
-
|
|
47
|
+
if (fs.existsSync(`./engine-private/conf/${deployContext}`))
|
|
48
|
+
return loadConf(deployContext, process.env.NODE_ENV, subConf);
|
|
49
|
+
if (fs.existsSync(`./engine-private/replica/${deployContext}`))
|
|
50
|
+
return loadConf(deployContext, process.env.NODE_ENV, subConf);
|
|
41
51
|
|
|
42
|
-
if (
|
|
52
|
+
if (deployContext === 'deploy') return;
|
|
43
53
|
|
|
44
|
-
if (
|
|
54
|
+
if (deployContext === 'proxy') {
|
|
55
|
+
if (!deployList) deployList = process.argv[3];
|
|
56
|
+
if (!subConf) subConf = process.argv[4];
|
|
45
57
|
this.default.server = {};
|
|
46
|
-
for (const deployId of
|
|
58
|
+
for (const deployId of deployList.split(',')) {
|
|
47
59
|
let confPath = `./engine-private/conf/${deployId}/conf.server.json`;
|
|
48
60
|
const privateConfDevPath = fs.existsSync(`./engine-private/replica/${deployId}/conf.server.json`)
|
|
49
61
|
? `./engine-private/replica/${deployId}/conf.server.json`
|
|
50
|
-
: `./engine-private/conf/${deployId}/conf.server.dev.${
|
|
62
|
+
: `./engine-private/conf/${deployId}/conf.server.dev.${subConf}.json`;
|
|
51
63
|
const confDevPath = fs.existsSync(privateConfDevPath)
|
|
52
64
|
? privateConfDevPath
|
|
53
65
|
: `./engine-private/conf/${deployId}/conf.server.dev.json`;
|
|
@@ -55,7 +67,7 @@ const Config = {
|
|
|
55
67
|
if (process.env.NODE_ENV === 'development' && fs.existsSync(confDevPath)) confPath = confDevPath;
|
|
56
68
|
const serverConf = JSON.parse(fs.readFileSync(confPath, 'utf8'));
|
|
57
69
|
|
|
58
|
-
for (const host of Object.keys(loadReplicas(serverConf))) {
|
|
70
|
+
for (const host of Object.keys(loadReplicas(serverConf, deployContext, subConf))) {
|
|
59
71
|
if (serverConf[host]['/'])
|
|
60
72
|
this.default.server[host] = {
|
|
61
73
|
...this.default.server[host],
|
|
@@ -85,7 +97,15 @@ const Config = {
|
|
|
85
97
|
},
|
|
86
98
|
};
|
|
87
99
|
|
|
88
|
-
const loadConf = (deployId) => {
|
|
100
|
+
const loadConf = (deployId, envInput, subConf) => {
|
|
101
|
+
if (deployId === 'clean') {
|
|
102
|
+
shellExec(`git checkout package.json`);
|
|
103
|
+
shellExec(`git checkout .env.production`);
|
|
104
|
+
shellExec(`git checkout .env.development`);
|
|
105
|
+
shellExec(`git checkout .env.test`);
|
|
106
|
+
shellExec(`git checkout jsdoc.json`);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
89
109
|
const folder = fs.existsSync(`./engine-private/replica/${deployId}`)
|
|
90
110
|
? `./engine-private/replica/${deployId}`
|
|
91
111
|
: `./engine-private/conf/${deployId}`;
|
|
@@ -102,7 +122,8 @@ const loadConf = (deployId) => {
|
|
|
102
122
|
? fs.readFileSync(`${folder}/conf.${typeConf}.json`, 'utf8')
|
|
103
123
|
: JSON.stringify(Config.default[typeConf]);
|
|
104
124
|
if (process.env.NODE_ENV === 'development' && typeConf === 'server') {
|
|
105
|
-
|
|
125
|
+
if (!subConf) subConf = process.argv[3];
|
|
126
|
+
const devConfPath = `${folder}/conf.${typeConf}.dev${subConf ? `.${subConf}` : ''}.json`;
|
|
106
127
|
if (fs.existsSync(devConfPath)) srcConf = fs.readFileSync(devConfPath, 'utf8');
|
|
107
128
|
}
|
|
108
129
|
if (typeConf === 'server') srcConf = JSON.stringify(loadReplicas(JSON.parse(srcConf)), null, 4);
|
|
@@ -111,27 +132,34 @@ const loadConf = (deployId) => {
|
|
|
111
132
|
fs.writeFileSync(`./.env.production`, fs.readFileSync(`${folder}/.env.production`, 'utf8'), 'utf8');
|
|
112
133
|
fs.writeFileSync(`./.env.development`, fs.readFileSync(`${folder}/.env.development`, 'utf8'), 'utf8');
|
|
113
134
|
fs.writeFileSync(`./.env.test`, fs.readFileSync(`${folder}/.env.test`, 'utf8'), 'utf8');
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
135
|
+
const NODE_ENV = envInput || process.env.NODE_ENV;
|
|
136
|
+
if (NODE_ENV) {
|
|
137
|
+
fs.writeFileSync(`./.env`, fs.readFileSync(`${folder}/.env.${NODE_ENV}`, 'utf8'), 'utf8');
|
|
138
|
+
const env = dotenv.parse(fs.readFileSync(`${folder}/.env.${NODE_ENV}`, 'utf8'));
|
|
117
139
|
process.env = {
|
|
118
140
|
...process.env,
|
|
119
141
|
...env,
|
|
120
142
|
};
|
|
121
143
|
}
|
|
122
|
-
|
|
144
|
+
const originPackageJson = JSON.parse(fs.readFileSync(`./package.json`, 'utf8'));
|
|
145
|
+
const packageJson = JSON.parse(fs.readFileSync(`${folder}/package.json`, 'utf8'));
|
|
146
|
+
originPackageJson.scripts.start = packageJson.scripts.start;
|
|
147
|
+
packageJson.scripts = originPackageJson.scripts;
|
|
148
|
+
fs.writeFileSync(`./package.json`, JSON.stringify(packageJson, null, 4), 'utf8');
|
|
123
149
|
return { folder, deployId };
|
|
124
150
|
};
|
|
125
151
|
|
|
126
|
-
const loadReplicas = (confServer) => {
|
|
152
|
+
const loadReplicas = (confServer, deployContext, subConf) => {
|
|
153
|
+
if (!deployContext) deployContext = process.argv[2];
|
|
154
|
+
if (!subConf) subConf = process.argv[3];
|
|
127
155
|
for (const host of Object.keys(confServer)) {
|
|
128
156
|
for (const path of Object.keys(confServer[host])) {
|
|
129
157
|
const { replicas, singleReplica } = confServer[host][path];
|
|
130
158
|
if (
|
|
131
159
|
replicas &&
|
|
132
|
-
(
|
|
160
|
+
(deployContext === 'proxy' ||
|
|
133
161
|
!singleReplica ||
|
|
134
|
-
(singleReplica && process.env.NODE_ENV === 'development' && !
|
|
162
|
+
(singleReplica && process.env.NODE_ENV === 'development' && !subConf))
|
|
135
163
|
)
|
|
136
164
|
for (const replicaPath of replicas) {
|
|
137
165
|
confServer[host][replicaPath] = newInstance(confServer[host][path]);
|
|
@@ -480,6 +508,48 @@ const buildProxyRouter = () => {
|
|
|
480
508
|
return proxyRouter;
|
|
481
509
|
};
|
|
482
510
|
|
|
511
|
+
const buildKindPorts = (from, to) =>
|
|
512
|
+
range(parseInt(from), parseInt(to))
|
|
513
|
+
.map(
|
|
514
|
+
(port) => ` - name: 'tcp-${port}'
|
|
515
|
+
protocol: TCP
|
|
516
|
+
port: ${port}
|
|
517
|
+
targetPort: ${port}
|
|
518
|
+
- name: 'udp-${port}'
|
|
519
|
+
protocol: UDP
|
|
520
|
+
port: ${port}
|
|
521
|
+
targetPort: ${port}
|
|
522
|
+
`,
|
|
523
|
+
)
|
|
524
|
+
.join('\n');
|
|
525
|
+
|
|
526
|
+
const buildPortProxyRouter = (port, proxyRouter) => {
|
|
527
|
+
const hosts = proxyRouter[port];
|
|
528
|
+
const router = {};
|
|
529
|
+
// build router
|
|
530
|
+
Object.keys(hosts).map((hostKey) => {
|
|
531
|
+
let { host, path, target, proxy, peer } = hosts[hostKey];
|
|
532
|
+
if (process.argv.includes('localhost') && process.env.NODE_ENV === 'development') host = `localhost`;
|
|
533
|
+
|
|
534
|
+
if (!proxy.includes(port)) return;
|
|
535
|
+
const absoluteHost = [80, 443].includes(port)
|
|
536
|
+
? `${host}${path === '/' ? '' : path}`
|
|
537
|
+
: `${host}:${port}${path === '/' ? '' : path}`;
|
|
538
|
+
|
|
539
|
+
if (process.argv.includes('localhost')) {
|
|
540
|
+
if (!(absoluteHost in router)) router[absoluteHost] = target;
|
|
541
|
+
} else router[absoluteHost] = target;
|
|
542
|
+
}); // order router
|
|
543
|
+
|
|
544
|
+
if (Object.keys(router).length === 0) return router;
|
|
545
|
+
|
|
546
|
+
const reOrderRouter = {};
|
|
547
|
+
for (const absoluteHostKey of orderArrayFromAttrInt(Object.keys(router), 'length'))
|
|
548
|
+
reOrderRouter[absoluteHostKey] = router[absoluteHostKey];
|
|
549
|
+
|
|
550
|
+
return reOrderRouter;
|
|
551
|
+
};
|
|
552
|
+
|
|
483
553
|
const cliBar = async (time = 5000) => {
|
|
484
554
|
// create new progress bar
|
|
485
555
|
const b = new cliProgress.SingleBar({
|
|
@@ -530,7 +600,15 @@ const buildReplicaId = ({ deployId, replica }) => `${deployId}-${replica.slice(1
|
|
|
530
600
|
const getDataDeploy = (
|
|
531
601
|
options = { buildSingleReplica: false, deployGroupId: '', deployId: '', disableSyncEnvPort: false },
|
|
532
602
|
) => {
|
|
533
|
-
let dataDeploy =
|
|
603
|
+
let dataDeploy =
|
|
604
|
+
options.deployGroupId === 'dd'
|
|
605
|
+
? fs.readFileSync(`./engine-private/deploy/${options.deployGroupId}.router`, 'utf8')
|
|
606
|
+
: fs.readFileSync(`./engine-private/deploy/${options.deployGroupId}`, 'utf8');
|
|
607
|
+
|
|
608
|
+
dataDeploy = dataDeploy
|
|
609
|
+
.split(',')
|
|
610
|
+
.map((deployId) => deployId.trim())
|
|
611
|
+
.filter((deployId) => deployId);
|
|
534
612
|
|
|
535
613
|
if (options.deployId) dataDeploy = dataDeploy.filter((d) => d === options.deployId);
|
|
536
614
|
|
|
@@ -588,6 +666,7 @@ const validateTemplatePath = (absolutePath = '') => {
|
|
|
588
666
|
if (absolutePath.match('src/api') && !confServer.apis.find((p) => absolutePath.match(`src/api/${p}/`))) {
|
|
589
667
|
return false;
|
|
590
668
|
}
|
|
669
|
+
if (absolutePath.match('conf.dd-') && absolutePath.match('.js')) return false;
|
|
591
670
|
if (
|
|
592
671
|
absolutePath.match('src/client/services/') &&
|
|
593
672
|
!clients.find((p) => absolutePath.match(`src/client/services/${p}/`))
|
|
@@ -770,9 +849,10 @@ const deployRun = async (dataDeploy, currentAttempt = 1) => {
|
|
|
770
849
|
} else logger.info(`Deploy process successfully`);
|
|
771
850
|
};
|
|
772
851
|
|
|
773
|
-
const restoreMacroDb = async (deployGroupId = '') => {
|
|
852
|
+
const restoreMacroDb = async (deployGroupId = '', deployId = null) => {
|
|
774
853
|
const dataDeploy = await getDataDeploy({ deployGroupId, buildSingleReplica: false });
|
|
775
854
|
for (const deployGroup of dataDeploy) {
|
|
855
|
+
if (deployId && deployGroup.deployId !== deployId) continue;
|
|
776
856
|
if (!deployGroup.replicaHost) {
|
|
777
857
|
const deployServerConfPath = `./engine-private/conf/${deployGroup.deployId}/conf.server.json`;
|
|
778
858
|
const serverConf = JSON.parse(fs.readFileSync(deployServerConfPath, 'utf8'));
|
|
@@ -790,13 +870,10 @@ const restoreMacroDb = async (deployGroupId = '') => {
|
|
|
790
870
|
}
|
|
791
871
|
};
|
|
792
872
|
|
|
793
|
-
const
|
|
794
|
-
const names = JSON.parse(fs.readFileSync(baseBackJsonPath, 'utf8')).map((p) =>
|
|
795
|
-
p.replaceAll(`\\`, '/').replaceAll('C:/', '/').replaceAll('c:/', '/'),
|
|
796
|
-
);
|
|
873
|
+
const mergeFile = async (parts = [], outputFilePath) => {
|
|
797
874
|
await new Promise((resolve) => {
|
|
798
875
|
splitFile
|
|
799
|
-
.mergeFiles(
|
|
876
|
+
.mergeFiles(parts, outputFilePath)
|
|
800
877
|
.then(() => {
|
|
801
878
|
resolve();
|
|
802
879
|
})
|
|
@@ -848,11 +925,13 @@ const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deplo
|
|
|
848
925
|
{
|
|
849
926
|
if (process.argv.includes('cron')) {
|
|
850
927
|
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
|
-
|
|
928
|
+
if (fs.existsSync(`${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`)) {
|
|
929
|
+
const names = JSON.parse(
|
|
930
|
+
fs.readFileSync(`${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`, 'utf8'),
|
|
931
|
+
).map((p) => p.replaceAll(`\\`, '/').replaceAll('C:/', '/').replaceAll('c:/', '/'));
|
|
932
|
+
|
|
933
|
+
await mergeFile(names, `${baseBackUpPath}/${currentBackupTimestamp}/${name}.sql`);
|
|
934
|
+
}
|
|
856
935
|
} else {
|
|
857
936
|
cmd = `mysql -u ${user} -p${password} ${name} < ${
|
|
858
937
|
backupPath ? backupPath : `./engine-private/sql-backups/${name}.sql`
|
|
@@ -863,15 +942,23 @@ const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deplo
|
|
|
863
942
|
backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
|
|
864
943
|
}/${name}-parths.json`,
|
|
865
944
|
)
|
|
866
|
-
)
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
945
|
+
) {
|
|
946
|
+
const names = JSON.parse(
|
|
947
|
+
fs.readFileSync(
|
|
948
|
+
`${
|
|
949
|
+
backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
|
|
950
|
+
}/${name}-parths.json`,
|
|
951
|
+
'utf8',
|
|
952
|
+
),
|
|
953
|
+
).map((p) => p.replaceAll(`\\`, '/').replaceAll('C:/', '/').replaceAll('c:/', '/'));
|
|
954
|
+
|
|
955
|
+
await mergeFile(
|
|
956
|
+
names,
|
|
871
957
|
`${
|
|
872
958
|
backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
|
|
873
959
|
}/${name}.sql`,
|
|
874
960
|
);
|
|
961
|
+
}
|
|
875
962
|
}
|
|
876
963
|
}
|
|
877
964
|
break;
|
|
@@ -890,6 +977,16 @@ const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deplo
|
|
|
890
977
|
return cmd;
|
|
891
978
|
};
|
|
892
979
|
|
|
980
|
+
const getPathsSSR = (conf) => {
|
|
981
|
+
const paths = ['src/client/ssr/Render.js'];
|
|
982
|
+
for (const o of conf.head) paths.push(`src/client/ssr/head/${o}.js`);
|
|
983
|
+
for (const o of conf.body) paths.push(`src/client/ssr/body/${o}.js`);
|
|
984
|
+
for (const o of Object.keys(conf.mailer)) paths.push(`src/client/ssr/mailer/${conf.mailer[o]}.js`);
|
|
985
|
+
for (const o of conf.offline) paths.push(`src/client/ssr/mailer/${o.client}.js`);
|
|
986
|
+
for (const o of conf.pages) paths.push(`src/client/ssr/pages/${o.client}.js`);
|
|
987
|
+
return paths;
|
|
988
|
+
};
|
|
989
|
+
|
|
893
990
|
const Cmd = {
|
|
894
991
|
delete: (deployId) => `pm2 delete ${deployId}`,
|
|
895
992
|
run: (deployId) => `node bin/deploy run ${deployId}`,
|
|
@@ -897,13 +994,14 @@ const Cmd = {
|
|
|
897
994
|
conf: (deployId, env) => `node bin/deploy conf ${deployId} ${env ? env : 'production'}`,
|
|
898
995
|
replica: (deployId, host, path) => `node bin/deploy build-single-replica ${deployId} ${host} ${path}`,
|
|
899
996
|
syncPorts: (deployGroupId) => `node bin/deploy sync-env-port ${deployGroupId}`,
|
|
900
|
-
cron: (
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
997
|
+
cron: (deployList, jobList, name, expression, options) =>
|
|
998
|
+
`pm2 start ./bin/index.js --no-autorestart --instances 1 --cron "${expression}" --name ${name} -- cron ${
|
|
999
|
+
options?.disableKindCluster ? `--disable-kind-cluster ` : ''
|
|
1000
|
+
}${deployList} ${jobList}`,
|
|
904
1001
|
};
|
|
905
1002
|
|
|
906
1003
|
const fixDependencies = async () => {
|
|
1004
|
+
return;
|
|
907
1005
|
// sed -i "$line_number s,.*,$new_text," "$file"
|
|
908
1006
|
// sed -i "$line_number c \\$new_text" "$file"
|
|
909
1007
|
const dep = fs.readFileSync(`./node_modules/peer/dist/module.mjs`, 'utf8');
|
|
@@ -933,6 +1031,34 @@ const maintenanceMiddleware = (req, res, port, proxyRouter) => {
|
|
|
933
1031
|
}
|
|
934
1032
|
};
|
|
935
1033
|
|
|
1034
|
+
const splitFileFactory = async (name, _path) => {
|
|
1035
|
+
const stats = fs.statSync(_path);
|
|
1036
|
+
const maxSizeInBytes = 1024 * 1024 * 50; // 50 mb
|
|
1037
|
+
const fileSizeInBytes = stats.size;
|
|
1038
|
+
if (fileSizeInBytes > maxSizeInBytes) {
|
|
1039
|
+
logger.info('splitFileFactory input', { name, from: _path });
|
|
1040
|
+
return await new Promise((resolve) => {
|
|
1041
|
+
splitFile
|
|
1042
|
+
.splitFileBySize(_path, maxSizeInBytes) // 50 mb
|
|
1043
|
+
.then((names) => {
|
|
1044
|
+
logger.info('splitFileFactory output', { parts: names });
|
|
1045
|
+
fs.writeFileSync(
|
|
1046
|
+
`${_path.split('/').slice(0, -1).join('/')}/${name}-parths.json`,
|
|
1047
|
+
JSON.stringify(names, null, 4),
|
|
1048
|
+
'utf8',
|
|
1049
|
+
);
|
|
1050
|
+
fs.removeSync(_path);
|
|
1051
|
+
return resolve(true);
|
|
1052
|
+
})
|
|
1053
|
+
.catch((err) => {
|
|
1054
|
+
console.log('Error: ', err);
|
|
1055
|
+
return resolve(false);
|
|
1056
|
+
});
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
return false;
|
|
1060
|
+
};
|
|
1061
|
+
|
|
936
1062
|
const setUpProxyMaintenanceServer = ({ deployGroupId }) => {
|
|
937
1063
|
shellExec(`pm2 kill`);
|
|
938
1064
|
shellExec(`node bin/deploy valkey-service`);
|
|
@@ -941,6 +1067,22 @@ const setUpProxyMaintenanceServer = ({ deployGroupId }) => {
|
|
|
941
1067
|
shellExec(`node bin/deploy run ${proxyDeployId} maintenance`);
|
|
942
1068
|
};
|
|
943
1069
|
|
|
1070
|
+
const getNpmRootPath = () =>
|
|
1071
|
+
shellExec(`npm root -g`, {
|
|
1072
|
+
stdout: true,
|
|
1073
|
+
disableLog: true,
|
|
1074
|
+
silent: true,
|
|
1075
|
+
}).trim();
|
|
1076
|
+
|
|
1077
|
+
const writeEnv = (envPath, envObj) =>
|
|
1078
|
+
fs.writeFileSync(
|
|
1079
|
+
envPath,
|
|
1080
|
+
Object.keys(envObj)
|
|
1081
|
+
.map((key) => `${key}=${envObj[key]}`)
|
|
1082
|
+
.join(`\n`),
|
|
1083
|
+
'utf8',
|
|
1084
|
+
);
|
|
1085
|
+
|
|
944
1086
|
export {
|
|
945
1087
|
Cmd,
|
|
946
1088
|
Config,
|
|
@@ -967,9 +1109,15 @@ export {
|
|
|
967
1109
|
deployRun,
|
|
968
1110
|
getCronBackUpFolder,
|
|
969
1111
|
getRestoreCronCmd,
|
|
970
|
-
|
|
1112
|
+
mergeFile,
|
|
971
1113
|
fixDependencies,
|
|
972
1114
|
getDeployId,
|
|
973
1115
|
maintenanceMiddleware,
|
|
974
1116
|
setUpProxyMaintenanceServer,
|
|
1117
|
+
getPathsSSR,
|
|
1118
|
+
buildKindPorts,
|
|
1119
|
+
buildPortProxyRouter,
|
|
1120
|
+
splitFileFactory,
|
|
1121
|
+
getNpmRootPath,
|
|
1122
|
+
writeEnv,
|
|
975
1123
|
};
|
package/src/server/dns.js
CHANGED
|
@@ -2,10 +2,9 @@ import axios from 'axios';
|
|
|
2
2
|
import dotenv from 'dotenv';
|
|
3
3
|
import fs from 'fs';
|
|
4
4
|
import https from 'https';
|
|
5
|
-
|
|
5
|
+
import validator from 'validator';
|
|
6
6
|
import { ip } from './network.js';
|
|
7
7
|
import { loggerFactory } from './logger.js';
|
|
8
|
-
import { isIPv4 } from 'is-ip';
|
|
9
8
|
import { shellExec } from './process.js';
|
|
10
9
|
|
|
11
10
|
const httpsAgent = new https.Agent({
|
|
@@ -18,10 +17,8 @@ dotenv.config();
|
|
|
18
17
|
|
|
19
18
|
const logger = loggerFactory(import.meta);
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
callback: () => null,
|
|
24
|
-
InitIpDaemon: async function ({ deployId }) {
|
|
20
|
+
class Dns {
|
|
21
|
+
static callback = async function (deployList) {
|
|
25
22
|
// NAT-VPS modem/router device configuration:
|
|
26
23
|
// LAN --> [NAT-VPS] --> WAN
|
|
27
24
|
// enabled DMZ Host to proxy IP 80-443 (79-444) sometimes router block first port
|
|
@@ -31,56 +28,55 @@ const Dns = {
|
|
|
31
28
|
// LAN server or device's local servers port -> 3000-3100 (2999-3101)
|
|
32
29
|
// DNS Records: [ANAME](Address Dynamic) -> [A](ipv4) host | [AAAA](ipv6) host -> [public-ip]
|
|
33
30
|
// Forward the router's TCP/UDP ports to the LAN device's IP address
|
|
34
|
-
|
|
31
|
+
for (const _deployId of deployList.split(',')) {
|
|
32
|
+
const deployId = _deployId.trim();
|
|
35
33
|
const privateCronConfPath = `./engine-private/conf/${deployId}/conf.cron.json`;
|
|
36
|
-
|
|
37
34
|
const confCronPath = fs.existsSync(privateCronConfPath) ? privateCronConfPath : './conf/conf.cron.json';
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
logger.info(`Current ip`, Dns.ip);
|
|
42
|
-
const callback = async () => {
|
|
43
|
-
logger.info('init dns ip callback');
|
|
44
|
-
await logger.setUpInfo();
|
|
45
|
-
let testIp;
|
|
46
|
-
try {
|
|
47
|
-
testIp = await ip.public.ipv4();
|
|
48
|
-
} catch (error) {
|
|
49
|
-
logger.error(error, { testIp, stack: error.stack });
|
|
50
|
-
}
|
|
51
|
-
if (testIp && typeof testIp === 'string' && isIPv4(testIp) && Dns.ip !== testIp) {
|
|
52
|
-
logger.info(`New ip`, testIp);
|
|
53
|
-
for (const recordType of Object.keys(confCronData.records)) {
|
|
54
|
-
switch (recordType) {
|
|
55
|
-
case 'A':
|
|
56
|
-
for (const dnsProvider of confCronData.records[recordType]) {
|
|
57
|
-
if (typeof Dns.services.updateIp[dnsProvider.dns] === 'function')
|
|
58
|
-
await Dns.services.updateIp[dnsProvider.dns]({ ...dnsProvider, ip: testIp });
|
|
59
|
-
}
|
|
60
|
-
break;
|
|
35
|
+
const confCronData = JSON.parse(fs.readFileSync(confCronPath, 'utf8'));
|
|
36
|
+
|
|
37
|
+
let testIp;
|
|
61
38
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
39
|
+
try {
|
|
40
|
+
testIp = await ip.public.ipv4();
|
|
41
|
+
} catch (error) {
|
|
42
|
+
logger.error(error, { testIp, stack: error.stack });
|
|
43
|
+
}
|
|
44
|
+
const ipFileName = `${deployId}.ip`;
|
|
45
|
+
const currentIp = fs.existsSync(`./engine-private/deploy/${ipFileName}`)
|
|
46
|
+
? fs.readFileSync(`./engine-private/deploy/${ipFileName}`, 'utf8')
|
|
47
|
+
: undefined;
|
|
48
|
+
|
|
49
|
+
if (testIp && typeof testIp === 'string' && validator.isIP(testIp) && currentIp !== testIp) {
|
|
50
|
+
logger.info(`new ip`, testIp);
|
|
51
|
+
for (const recordType of Object.keys(confCronData.records)) {
|
|
52
|
+
switch (recordType) {
|
|
53
|
+
case 'A':
|
|
54
|
+
for (const dnsProvider of confCronData.records[recordType]) {
|
|
55
|
+
if (typeof Dns.services.updateIp[dnsProvider.dns] === 'function')
|
|
56
|
+
await Dns.services.updateIp[dnsProvider.dns]({ ...dnsProvider, ip: testIp });
|
|
57
|
+
}
|
|
58
|
+
break;
|
|
59
|
+
|
|
60
|
+
default:
|
|
61
|
+
break;
|
|
65
62
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const ipUrlTest = `https://${process.env.DEFAULT_DEPLOY_HOST}`;
|
|
66
|
+
const response = await axios.get(ipUrlTest);
|
|
67
|
+
const verifyIp = response.request.socket.remoteAddress;
|
|
68
|
+
logger.info(ipUrlTest + ' IP', verifyIp);
|
|
69
|
+
if (verifyIp === testIp) {
|
|
70
|
+
fs.writeFileSync(`./engine-private/deploy/${ipFileName}`, testIp, 'utf8');
|
|
71
|
+
} else logger.error('ip not updated');
|
|
72
|
+
} catch (error) {
|
|
73
|
+
logger.error(error), 'ip not updated';
|
|
76
74
|
}
|
|
77
75
|
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
},
|
|
83
|
-
services: {
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
static services = {
|
|
84
80
|
updateIp: {
|
|
85
81
|
dondominio: (options) => {
|
|
86
82
|
const { user, api_key, host, dns, ip } = options;
|
|
@@ -101,21 +97,7 @@ const Dns = {
|
|
|
101
97
|
});
|
|
102
98
|
},
|
|
103
99
|
},
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
Dns.ip = ip;
|
|
107
|
-
confCronData.ipDaemon.ip = ip;
|
|
108
|
-
fs.writeFileSync(confCronPath, JSON.stringify(confCronData, null, 4), 'utf8');
|
|
109
|
-
shellExec(
|
|
110
|
-
`cd ./engine-private` +
|
|
111
|
-
` && git pull ${Dns.repoUrl}` +
|
|
112
|
-
` && git add . && git commit -m "update ip ${new Date().toLocaleDateString()}"` +
|
|
113
|
-
` && git push ${Dns.repoUrl}`,
|
|
114
|
-
{
|
|
115
|
-
disableLog: true,
|
|
116
|
-
},
|
|
117
|
-
);
|
|
118
|
-
},
|
|
119
|
-
};
|
|
100
|
+
};
|
|
101
|
+
}
|
|
120
102
|
|
|
121
|
-
export
|
|
103
|
+
export default Dns;
|
package/src/server/logger.js
CHANGED
|
@@ -12,7 +12,6 @@ import morgan from 'morgan';
|
|
|
12
12
|
import colorize from 'json-colorizer';
|
|
13
13
|
import colors from 'colors';
|
|
14
14
|
import v8 from 'v8';
|
|
15
|
-
import isAdmin from 'is-admin';
|
|
16
15
|
import { clearTerminalStringColor, formatBytes } from '../client/components/core/CommonJs.js';
|
|
17
16
|
|
|
18
17
|
colors.enable();
|
|
@@ -79,18 +78,16 @@ const format = (meta) =>
|
|
|
79
78
|
*
|
|
80
79
|
* This function is used to log details about
|
|
81
80
|
* the execution context, such as command-line arguments,
|
|
82
|
-
* environment variables, the
|
|
83
|
-
* and the maximum available heap space size.
|
|
81
|
+
* environment variables, and the maximum available heap space size.
|
|
84
82
|
*
|
|
85
83
|
* @param {winston.Logger} logger - A pre-configured Winston logger object.
|
|
86
84
|
* @memberof Logger
|
|
87
85
|
*/
|
|
88
86
|
const setUpInfo = async (logger = new winston.Logger()) => {
|
|
89
|
-
logger.info('npm_package_version', process.env.npm_package_version);
|
|
90
87
|
logger.info('argv', process.argv);
|
|
88
|
+
logger.info('cwd', process.cwd());
|
|
91
89
|
logger.info('platform', process.platform);
|
|
92
90
|
logger.info('env', process.env.NODE_ENV);
|
|
93
|
-
logger.info('admin', await isAdmin());
|
|
94
91
|
logger.info('--max-old-space-size', {
|
|
95
92
|
total_available_size: formatBytes(v8.getHeapStatistics().total_available_size),
|
|
96
93
|
});
|
|
@@ -115,10 +112,10 @@ const loggerFactory = (meta = { url: '' }) => {
|
|
|
115
112
|
// Allow the use the terminal to print the messages
|
|
116
113
|
new winston.transports.Console(),
|
|
117
114
|
// Allow to print all the error level messages inside the error.log file
|
|
118
|
-
new winston.transports.File({
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}),
|
|
115
|
+
// new winston.transports.File({
|
|
116
|
+
// filename: `logs/${meta}/error.log`,
|
|
117
|
+
// level: 'error',
|
|
118
|
+
// }),
|
|
122
119
|
// Allow to print all the error message inside the all.log file
|
|
123
120
|
// (also the error log that are also printed inside the error.log(
|
|
124
121
|
new winston.transports.File({ filename: `logs/${meta}/all.log` }),
|
|
@@ -189,4 +186,12 @@ const underpostASCI = () => `
|
|
|
189
186
|
░╚═════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚═╝░░░░░░╚════╝░╚═════╝░░░░╚═╝░░░
|
|
190
187
|
`;
|
|
191
188
|
|
|
192
|
-
|
|
189
|
+
const actionInitLog = () =>
|
|
190
|
+
console.log(
|
|
191
|
+
underpostASCI() +
|
|
192
|
+
`
|
|
193
|
+
https://www.nexodev.org/docs
|
|
194
|
+
`,
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
export { loggerFactory, loggerMiddleware, setUpInfo, underpostASCI, actionInitLog };
|