@underpostnet/underpost 2.8.0 → 2.8.4
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 +14 -11
- package/.github/workflows/pwa-microservices-template.page.yml +10 -3
- package/.vscode/extensions.json +17 -71
- package/.vscode/settings.json +12 -5
- package/AUTHORS.md +16 -5
- package/CHANGELOG.md +63 -3
- package/Dockerfile +41 -62
- package/README.md +1 -28
- package/bin/build.js +278 -0
- package/bin/db.js +2 -24
- package/bin/deploy.js +107 -71
- package/bin/file.js +33 -4
- package/bin/index.js +35 -54
- package/bin/ssl.js +19 -11
- package/bin/util.js +27 -89
- package/bin/vs.js +25 -2
- package/conf.js +32 -132
- 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.yaml +60 -0
- package/manifests/deployment/phpmyadmin.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/valkey/kustomization.yaml +7 -0
- package/manifests/valkey/underpost-engine-valkey-service.yaml +17 -0
- package/manifests/valkey/underpost-engine-valkey-statefulset.yaml +39 -0
- package/package.json +16 -35
- package/src/api/user/user.model.js +16 -3
- package/src/api/user/user.service.js +1 -1
- package/src/client/components/core/Account.js +4 -2
- package/src/client/components/core/Auth.js +2 -2
- package/src/client/components/core/CalendarCore.js +115 -49
- package/src/client/components/core/CommonJs.js +150 -19
- package/src/client/components/core/Css.js +1 -1
- package/src/client/components/core/CssCore.js +6 -0
- package/src/client/components/core/Docs.js +2 -1
- package/src/client/components/core/DropDown.js +5 -1
- package/src/client/components/core/Input.js +17 -3
- package/src/client/components/core/JoyStick.js +8 -5
- package/src/client/components/core/Modal.js +17 -11
- package/src/client/components/core/Panel.js +85 -25
- package/src/client/components/core/PanelForm.js +11 -19
- package/src/client/components/core/SignUp.js +4 -1
- package/src/client/components/core/Translate.js +57 -9
- package/src/client/components/core/Validator.js +9 -1
- package/src/client/public/default/plantuml/client-conf.svg +1 -1
- package/src/client/public/default/plantuml/server-conf.svg +1 -1
- package/src/client/public/default/plantuml/server-schema.svg +1 -1
- package/src/client/public/default/plantuml/ssr-conf.svg +1 -1
- package/src/client/public/default/plantuml/ssr-schema.svg +1 -1
- package/src/client/services/core/core.service.js +2 -0
- package/src/client/services/default/default.management.js +4 -2
- package/src/client/ssr/body/CacheControl.js +2 -1
- package/src/client/ssr/body/DefaultSplashScreen.js +3 -3
- package/src/client/ssr/offline/Maintenance.js +63 -0
- package/src/client/sw/default.sw.js +23 -3
- package/src/db/mongo/MongooseDB.js +13 -1
- package/src/index.js +15 -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/client-build.js +8 -17
- package/src/server/client-icons.js +1 -1
- package/src/server/conf.js +299 -32
- package/src/server/dns.js +2 -3
- package/src/server/logger.js +18 -11
- package/src/server/network.js +0 -36
- package/src/server/process.js +25 -2
- package/src/server/project.js +39 -0
- package/src/server/proxy.js +4 -26
- package/src/server/runtime.js +6 -7
- package/src/server/ssl.js +1 -1
- package/src/server/valkey.js +3 -0
- package/startup.cjs +12 -0
- package/src/server/prompt-optimizer.js +0 -28
- package/startup.js +0 -11
package/src/server/conf.js
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
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';
|
|
7
14
|
import logUpdate from 'log-update';
|
|
8
15
|
import colors from 'colors';
|
|
9
|
-
import { loggerFactory } from './logger.js';
|
|
10
|
-
import { shellExec } from './process.js';
|
|
16
|
+
import { actionInitLog, loggerFactory } from './logger.js';
|
|
17
|
+
import { pbcopy, 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);
|
|
@@ -85,7 +92,7 @@ const Config = {
|
|
|
85
92
|
},
|
|
86
93
|
};
|
|
87
94
|
|
|
88
|
-
const loadConf = (deployId) => {
|
|
95
|
+
const loadConf = (deployId, envInput) => {
|
|
89
96
|
const folder = fs.existsSync(`./engine-private/replica/${deployId}`)
|
|
90
97
|
? `./engine-private/replica/${deployId}`
|
|
91
98
|
: `./engine-private/conf/${deployId}`;
|
|
@@ -111,9 +118,10 @@ const loadConf = (deployId) => {
|
|
|
111
118
|
fs.writeFileSync(`./.env.production`, fs.readFileSync(`${folder}/.env.production`, 'utf8'), 'utf8');
|
|
112
119
|
fs.writeFileSync(`./.env.development`, fs.readFileSync(`${folder}/.env.development`, 'utf8'), 'utf8');
|
|
113
120
|
fs.writeFileSync(`./.env.test`, fs.readFileSync(`${folder}/.env.test`, 'utf8'), 'utf8');
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
121
|
+
const NODE_ENV = envInput || process.env.NODE_ENV;
|
|
122
|
+
if (NODE_ENV) {
|
|
123
|
+
fs.writeFileSync(`./.env`, fs.readFileSync(`${folder}/.env.${NODE_ENV}`, 'utf8'), 'utf8');
|
|
124
|
+
const env = dotenv.parse(fs.readFileSync(`${folder}/.env.${NODE_ENV}`, 'utf8'));
|
|
117
125
|
process.env = {
|
|
118
126
|
...process.env,
|
|
119
127
|
...env,
|
|
@@ -253,8 +261,8 @@ const buildClientSrc = async (
|
|
|
253
261
|
}
|
|
254
262
|
|
|
255
263
|
fs.writeFileSync(
|
|
256
|
-
`./src/client/ssr/
|
|
257
|
-
formattedSrc(fs.readFileSync(`./src/client/ssr/
|
|
264
|
+
`./src/client/ssr/head/${toClientVariableName}Scripts.js`,
|
|
265
|
+
formattedSrc(fs.readFileSync(`./src/client/ssr/head/${fromClientVariableName}Scripts.js`, 'utf8')),
|
|
258
266
|
'utf8',
|
|
259
267
|
);
|
|
260
268
|
|
|
@@ -473,13 +481,51 @@ const buildProxyRouter = () => {
|
|
|
473
481
|
title: 'Site in maintenance',
|
|
474
482
|
ssrPath: '/',
|
|
475
483
|
ssrHeadComponents: '',
|
|
476
|
-
ssrBodyComponents: (await ssrFactory(`./src/client/ssr/
|
|
484
|
+
ssrBodyComponents: (await ssrFactory(`./src/client/ssr/offline/Maintenance.js`))(),
|
|
477
485
|
});
|
|
478
486
|
})();
|
|
479
487
|
|
|
480
488
|
return proxyRouter;
|
|
481
489
|
};
|
|
482
490
|
|
|
491
|
+
const buildKindPorts = (from, to) =>
|
|
492
|
+
range(parseInt(from), parseInt(to))
|
|
493
|
+
.map(
|
|
494
|
+
(port) => ` - name: 'tcp-${port}'
|
|
495
|
+
protocol: TCP
|
|
496
|
+
port: ${port}
|
|
497
|
+
targetPort: ${port}
|
|
498
|
+
- name: 'udp-${port}'
|
|
499
|
+
protocol: UDP
|
|
500
|
+
port: ${port}
|
|
501
|
+
targetPort: ${port}
|
|
502
|
+
`,
|
|
503
|
+
)
|
|
504
|
+
.join('\n');
|
|
505
|
+
|
|
506
|
+
const buildPortProxyRouter = (port, proxyRouter) => {
|
|
507
|
+
const hosts = proxyRouter[port];
|
|
508
|
+
const router = {};
|
|
509
|
+
// build router
|
|
510
|
+
Object.keys(hosts).map((hostKey) => {
|
|
511
|
+
let { host, path, target, proxy, peer } = hosts[hostKey];
|
|
512
|
+
if (process.env.NODE_ENV === 'development') host = `localhost`;
|
|
513
|
+
|
|
514
|
+
if (!proxy.includes(port)) return;
|
|
515
|
+
const absoluteHost = [80, 443].includes(port)
|
|
516
|
+
? `${host}${path === '/' ? '' : path}`
|
|
517
|
+
: `${host}:${port}${path === '/' ? '' : path}`;
|
|
518
|
+
|
|
519
|
+
if (!(absoluteHost in router)) router[absoluteHost] = target;
|
|
520
|
+
}); // order router
|
|
521
|
+
|
|
522
|
+
if (Object.keys(router).length === 0) return router;
|
|
523
|
+
|
|
524
|
+
for (const absoluteHostKey of orderArrayFromAttrInt(Object.keys(router), 'length'))
|
|
525
|
+
router[absoluteHostKey] = router[absoluteHostKey];
|
|
526
|
+
return router;
|
|
527
|
+
};
|
|
528
|
+
|
|
483
529
|
const cliBar = async (time = 5000) => {
|
|
484
530
|
// create new progress bar
|
|
485
531
|
const b = new cliProgress.SingleBar({
|
|
@@ -588,6 +634,7 @@ const validateTemplatePath = (absolutePath = '') => {
|
|
|
588
634
|
if (absolutePath.match('src/api') && !confServer.apis.find((p) => absolutePath.match(`src/api/${p}/`))) {
|
|
589
635
|
return false;
|
|
590
636
|
}
|
|
637
|
+
if (absolutePath.match('conf.dd-') && absolutePath.match('.js')) return false;
|
|
591
638
|
if (
|
|
592
639
|
absolutePath.match('src/client/services/') &&
|
|
593
640
|
!clients.find((p) => absolutePath.match(`src/client/services/${p}/`))
|
|
@@ -770,9 +817,10 @@ const deployRun = async (dataDeploy, currentAttempt = 1) => {
|
|
|
770
817
|
} else logger.info(`Deploy process successfully`);
|
|
771
818
|
};
|
|
772
819
|
|
|
773
|
-
const restoreMacroDb = async (deployGroupId = '') => {
|
|
820
|
+
const restoreMacroDb = async (deployGroupId = '', deployId = null) => {
|
|
774
821
|
const dataDeploy = await getDataDeploy({ deployGroupId, buildSingleReplica: false });
|
|
775
822
|
for (const deployGroup of dataDeploy) {
|
|
823
|
+
if (deployId && deployGroup.deployId !== deployId) continue;
|
|
776
824
|
if (!deployGroup.replicaHost) {
|
|
777
825
|
const deployServerConfPath = `./engine-private/conf/${deployGroup.deployId}/conf.server.json`;
|
|
778
826
|
const serverConf = JSON.parse(fs.readFileSync(deployServerConfPath, 'utf8'));
|
|
@@ -790,13 +838,10 @@ const restoreMacroDb = async (deployGroupId = '') => {
|
|
|
790
838
|
}
|
|
791
839
|
};
|
|
792
840
|
|
|
793
|
-
const
|
|
794
|
-
const names = JSON.parse(fs.readFileSync(baseBackJsonPath, 'utf8')).map((p) =>
|
|
795
|
-
p.replaceAll(`\\`, '/').replaceAll('C:/', '/').replaceAll('c:/', '/'),
|
|
796
|
-
);
|
|
841
|
+
const mergeFile = async (parts = [], outputFilePath) => {
|
|
797
842
|
await new Promise((resolve) => {
|
|
798
843
|
splitFile
|
|
799
|
-
.mergeFiles(
|
|
844
|
+
.mergeFiles(parts, outputFilePath)
|
|
800
845
|
.then(() => {
|
|
801
846
|
resolve();
|
|
802
847
|
})
|
|
@@ -848,11 +893,13 @@ const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deplo
|
|
|
848
893
|
{
|
|
849
894
|
if (process.argv.includes('cron')) {
|
|
850
895
|
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
|
-
|
|
896
|
+
if (fs.existsSync(`${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`)) {
|
|
897
|
+
const names = JSON.parse(
|
|
898
|
+
fs.readFileSync(`${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`, 'utf8'),
|
|
899
|
+
).map((p) => p.replaceAll(`\\`, '/').replaceAll('C:/', '/').replaceAll('c:/', '/'));
|
|
900
|
+
|
|
901
|
+
await mergeFile(names, `${baseBackUpPath}/${currentBackupTimestamp}/${name}.sql`);
|
|
902
|
+
}
|
|
856
903
|
} else {
|
|
857
904
|
cmd = `mysql -u ${user} -p${password} ${name} < ${
|
|
858
905
|
backupPath ? backupPath : `./engine-private/sql-backups/${name}.sql`
|
|
@@ -863,15 +910,23 @@ const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deplo
|
|
|
863
910
|
backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
|
|
864
911
|
}/${name}-parths.json`,
|
|
865
912
|
)
|
|
866
|
-
)
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
913
|
+
) {
|
|
914
|
+
const names = JSON.parse(
|
|
915
|
+
fs.readFileSync(
|
|
916
|
+
`${
|
|
917
|
+
backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
|
|
918
|
+
}/${name}-parths.json`,
|
|
919
|
+
'utf8',
|
|
920
|
+
),
|
|
921
|
+
).map((p) => p.replaceAll(`\\`, '/').replaceAll('C:/', '/').replaceAll('c:/', '/'));
|
|
922
|
+
|
|
923
|
+
await mergeFile(
|
|
924
|
+
names,
|
|
871
925
|
`${
|
|
872
926
|
backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
|
|
873
927
|
}/${name}.sql`,
|
|
874
928
|
);
|
|
929
|
+
}
|
|
875
930
|
}
|
|
876
931
|
}
|
|
877
932
|
break;
|
|
@@ -890,6 +945,16 @@ const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deplo
|
|
|
890
945
|
return cmd;
|
|
891
946
|
};
|
|
892
947
|
|
|
948
|
+
const getPathsSSR = (conf) => {
|
|
949
|
+
const paths = ['src/client/ssr/Render.js'];
|
|
950
|
+
for (const o of conf.head) paths.push(`src/client/ssr/head/${o}.js`);
|
|
951
|
+
for (const o of conf.body) paths.push(`src/client/ssr/body/${o}.js`);
|
|
952
|
+
for (const o of Object.keys(conf.mailer)) paths.push(`src/client/ssr/mailer/${conf.mailer[o]}.js`);
|
|
953
|
+
for (const o of conf.offline) paths.push(`src/client/ssr/mailer/${o.client}.js`);
|
|
954
|
+
for (const o of conf.pages) paths.push(`src/client/ssr/pages/${o.client}.js`);
|
|
955
|
+
return paths;
|
|
956
|
+
};
|
|
957
|
+
|
|
893
958
|
const Cmd = {
|
|
894
959
|
delete: (deployId) => `pm2 delete ${deployId}`,
|
|
895
960
|
run: (deployId) => `node bin/deploy run ${deployId}`,
|
|
@@ -904,6 +969,7 @@ const Cmd = {
|
|
|
904
969
|
};
|
|
905
970
|
|
|
906
971
|
const fixDependencies = async () => {
|
|
972
|
+
return;
|
|
907
973
|
// sed -i "$line_number s,.*,$new_text," "$file"
|
|
908
974
|
// sed -i "$line_number c \\$new_text" "$file"
|
|
909
975
|
const dep = fs.readFileSync(`./node_modules/peer/dist/module.mjs`, 'utf8');
|
|
@@ -933,6 +999,34 @@ const maintenanceMiddleware = (req, res, port, proxyRouter) => {
|
|
|
933
999
|
}
|
|
934
1000
|
};
|
|
935
1001
|
|
|
1002
|
+
const splitFileFactory = async (name, _path) => {
|
|
1003
|
+
const stats = fs.statSync(_path);
|
|
1004
|
+
const maxSizeInBytes = 1024 * 1024 * 50; // 50 mb
|
|
1005
|
+
const fileSizeInBytes = stats.size;
|
|
1006
|
+
if (fileSizeInBytes > maxSizeInBytes) {
|
|
1007
|
+
logger.info('splitFileFactory input', { name, from: _path });
|
|
1008
|
+
return await new Promise((resolve) => {
|
|
1009
|
+
splitFile
|
|
1010
|
+
.splitFileBySize(_path, maxSizeInBytes) // 50 mb
|
|
1011
|
+
.then((names) => {
|
|
1012
|
+
logger.info('splitFileFactory output', { parts: names });
|
|
1013
|
+
fs.writeFileSync(
|
|
1014
|
+
`${_path.split('/').slice(0, -1).join('/')}/${name}-parths.json`,
|
|
1015
|
+
JSON.stringify(names, null, 4),
|
|
1016
|
+
'utf8',
|
|
1017
|
+
);
|
|
1018
|
+
fs.removeSync(_path);
|
|
1019
|
+
return resolve(true);
|
|
1020
|
+
})
|
|
1021
|
+
.catch((err) => {
|
|
1022
|
+
console.log('Error: ', err);
|
|
1023
|
+
return resolve(false);
|
|
1024
|
+
});
|
|
1025
|
+
});
|
|
1026
|
+
}
|
|
1027
|
+
return false;
|
|
1028
|
+
};
|
|
1029
|
+
|
|
936
1030
|
const setUpProxyMaintenanceServer = ({ deployGroupId }) => {
|
|
937
1031
|
shellExec(`pm2 kill`);
|
|
938
1032
|
shellExec(`node bin/deploy valkey-service`);
|
|
@@ -941,6 +1035,168 @@ const setUpProxyMaintenanceServer = ({ deployGroupId }) => {
|
|
|
941
1035
|
shellExec(`node bin/deploy run ${proxyDeployId} maintenance`);
|
|
942
1036
|
};
|
|
943
1037
|
|
|
1038
|
+
const repoClone = (gitUri = 'underpostnet/pwa-microservices-template') => {
|
|
1039
|
+
const repoName = gitUri.split('/').pop();
|
|
1040
|
+
if (fs.existsSync(`./${repoName}`)) fs.removeSync(`./${repoName}`);
|
|
1041
|
+
shellExec(
|
|
1042
|
+
`git clone https://${process.env.GITHUB_TOKEN ? `${process.env.GITHUB_TOKEN}@` : ''}github.com/${gitUri}.git`,
|
|
1043
|
+
);
|
|
1044
|
+
if (process.env.GITHUB_TOKEN) {
|
|
1045
|
+
shellExec(
|
|
1046
|
+
`git clone https://${
|
|
1047
|
+
process.env.GITHUB_TOKEN ? `${process.env.GITHUB_TOKEN}@` : ''
|
|
1048
|
+
}github.com/${gitUri}-private.git`,
|
|
1049
|
+
);
|
|
1050
|
+
fs.moveSync(`./${repoName}-private`, `./${repoName}/engine-private`, {
|
|
1051
|
+
overwrite: true,
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
};
|
|
1055
|
+
|
|
1056
|
+
const repoPull = (repoPath = './', gitUri = 'underpostnet/pwa-microservices-template') => {
|
|
1057
|
+
shellExec(`cd ${repoPath} && git pull https://${process.env.GITHUB_TOKEN}@github.com/${gitUri}.git`, {
|
|
1058
|
+
disableLog: true,
|
|
1059
|
+
});
|
|
1060
|
+
};
|
|
1061
|
+
|
|
1062
|
+
const commitData = {
|
|
1063
|
+
feat: {
|
|
1064
|
+
description: 'A new feature',
|
|
1065
|
+
title: 'Features',
|
|
1066
|
+
emoji: '✨',
|
|
1067
|
+
},
|
|
1068
|
+
fix: {
|
|
1069
|
+
description: 'A bug fix',
|
|
1070
|
+
title: 'Bug Fixes',
|
|
1071
|
+
emoji: '🐛',
|
|
1072
|
+
},
|
|
1073
|
+
docs: {
|
|
1074
|
+
description: 'Documentation only changes',
|
|
1075
|
+
title: 'Documentation',
|
|
1076
|
+
emoji: '📚',
|
|
1077
|
+
},
|
|
1078
|
+
style: {
|
|
1079
|
+
description:
|
|
1080
|
+
'Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
|
|
1081
|
+
title: 'Styles',
|
|
1082
|
+
emoji: '💎',
|
|
1083
|
+
},
|
|
1084
|
+
refactor: {
|
|
1085
|
+
description: 'A code change that neither fixes a bug nor adds a feature',
|
|
1086
|
+
title: 'Code Refactoring',
|
|
1087
|
+
emoji: '📦',
|
|
1088
|
+
},
|
|
1089
|
+
perf: {
|
|
1090
|
+
description: 'A code change that improves performance',
|
|
1091
|
+
title: 'Performance Improvements',
|
|
1092
|
+
emoji: '⚡️',
|
|
1093
|
+
},
|
|
1094
|
+
cd: {
|
|
1095
|
+
description:
|
|
1096
|
+
'Changes to our Continuous Delivery configuration files and scripts (example scopes: Jenkins, Spinnaker, ArgoCD)',
|
|
1097
|
+
title: 'Continuous Delivery',
|
|
1098
|
+
emoji: '🚀',
|
|
1099
|
+
},
|
|
1100
|
+
test: {
|
|
1101
|
+
description: 'Adding missing tests or correcting existing tests',
|
|
1102
|
+
title: 'Tests',
|
|
1103
|
+
emoji: '🚨',
|
|
1104
|
+
},
|
|
1105
|
+
build: {
|
|
1106
|
+
description: 'Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)',
|
|
1107
|
+
title: 'Builds',
|
|
1108
|
+
emoji: '🛠',
|
|
1109
|
+
},
|
|
1110
|
+
ci: {
|
|
1111
|
+
description:
|
|
1112
|
+
'Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)',
|
|
1113
|
+
title: 'Continuous Integrations',
|
|
1114
|
+
emoji: '⚙️',
|
|
1115
|
+
},
|
|
1116
|
+
chore: {
|
|
1117
|
+
description: "Other changes that don't modify src or test files",
|
|
1118
|
+
title: 'Chores',
|
|
1119
|
+
emoji: '♻️',
|
|
1120
|
+
},
|
|
1121
|
+
revert: {
|
|
1122
|
+
description: 'Reverts a previous commit',
|
|
1123
|
+
title: 'Reverts',
|
|
1124
|
+
emoji: '🗑',
|
|
1125
|
+
},
|
|
1126
|
+
backup: {
|
|
1127
|
+
description: 'Changes related to backups, including creation, restoration, and maintenance.',
|
|
1128
|
+
title: 'Backups',
|
|
1129
|
+
emoji: '💾',
|
|
1130
|
+
},
|
|
1131
|
+
};
|
|
1132
|
+
|
|
1133
|
+
const repoCommit = (
|
|
1134
|
+
repoPath = './',
|
|
1135
|
+
commitType = 'feat',
|
|
1136
|
+
subModule = '',
|
|
1137
|
+
message = '',
|
|
1138
|
+
options = {
|
|
1139
|
+
copy: false,
|
|
1140
|
+
info: false,
|
|
1141
|
+
empty: false,
|
|
1142
|
+
},
|
|
1143
|
+
) => {
|
|
1144
|
+
if (options.info) return logger.info('', commitData);
|
|
1145
|
+
const _message = `${commitType}${subModule ? `(${subModule})` : ''}${process.argv.includes('!') ? '!' : ''}: ${
|
|
1146
|
+
commitData[commitType].emoji
|
|
1147
|
+
} ${message ? message : commitData[commitType].description}`;
|
|
1148
|
+
if (options.copy) return pbcopy(_message);
|
|
1149
|
+
shellExec(`cd ${repoPath} && git commit ${options?.empty ? `--allow-empty ` : ''}-m "${_message}"`);
|
|
1150
|
+
};
|
|
1151
|
+
|
|
1152
|
+
const repoPush = (repoPath = './', gitUri = 'underpostnet/pwa-microservices-template') => {
|
|
1153
|
+
shellExec(`cd ${repoPath} && git push https://${process.env.GITHUB_TOKEN}@github.com/${gitUri}.git`, {
|
|
1154
|
+
disableLog: true,
|
|
1155
|
+
});
|
|
1156
|
+
logger.info(
|
|
1157
|
+
'commit url',
|
|
1158
|
+
`http://github.com/${gitUri}/commit/${shellExec(`cd ${repoPath} && git rev-parse --verify HEAD`, {
|
|
1159
|
+
stdout: true,
|
|
1160
|
+
}).trim()}`,
|
|
1161
|
+
);
|
|
1162
|
+
};
|
|
1163
|
+
|
|
1164
|
+
const getNpmRootPath = () =>
|
|
1165
|
+
shellExec(`npm root -g`, {
|
|
1166
|
+
stdout: true,
|
|
1167
|
+
}).trim();
|
|
1168
|
+
|
|
1169
|
+
const newProject = (repositoryName, version) => {
|
|
1170
|
+
return new Promise(async (resolve, reject) => {
|
|
1171
|
+
try {
|
|
1172
|
+
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
1173
|
+
// const exeRootPath = '/home/dd/pwa-microservices-template';
|
|
1174
|
+
actionInitLog(version);
|
|
1175
|
+
await logger.setUpInfo();
|
|
1176
|
+
const destFolder = `${process.cwd()}/${repositoryName}`;
|
|
1177
|
+
logger.info('Note: This process may take several minutes to complete');
|
|
1178
|
+
logger.info('build app', { destFolder });
|
|
1179
|
+
fs.mkdirSync(destFolder, { recursive: true });
|
|
1180
|
+
fs.copySync(exeRootPath, destFolder);
|
|
1181
|
+
if (fs.existsSync(`${destFolder}/node_modules`)) fs.removeSync(`${destFolder}/node_modules`);
|
|
1182
|
+
fs.writeFileSync(`${destFolder}/.gitignore`, fs.readFileSync(`${exeRootPath}/.dockerignore`, 'utf8'), 'utf8');
|
|
1183
|
+
shellExec(`cd ${destFolder} && git init && git add . && git commit -m "Base template implementation"`);
|
|
1184
|
+
shellExec(`cd ${destFolder} && npm install`);
|
|
1185
|
+
shellExec(`cd ${destFolder} && npm run build`);
|
|
1186
|
+
shellExec(`cd ${destFolder} && npm run dev`);
|
|
1187
|
+
return resolve();
|
|
1188
|
+
} catch (error) {
|
|
1189
|
+
logger.error(error, error.stack);
|
|
1190
|
+
return reject(error.message);
|
|
1191
|
+
}
|
|
1192
|
+
});
|
|
1193
|
+
};
|
|
1194
|
+
|
|
1195
|
+
const runTest = (version) => {
|
|
1196
|
+
actionInitLog(version);
|
|
1197
|
+
shellExec(`cd ${getNpmRootPath()}/underpost && npm run test`);
|
|
1198
|
+
};
|
|
1199
|
+
|
|
944
1200
|
export {
|
|
945
1201
|
Cmd,
|
|
946
1202
|
Config,
|
|
@@ -967,9 +1223,20 @@ export {
|
|
|
967
1223
|
deployRun,
|
|
968
1224
|
getCronBackUpFolder,
|
|
969
1225
|
getRestoreCronCmd,
|
|
970
|
-
|
|
1226
|
+
mergeFile,
|
|
971
1227
|
fixDependencies,
|
|
972
1228
|
getDeployId,
|
|
973
1229
|
maintenanceMiddleware,
|
|
974
1230
|
setUpProxyMaintenanceServer,
|
|
1231
|
+
getPathsSSR,
|
|
1232
|
+
buildKindPorts,
|
|
1233
|
+
buildPortProxyRouter,
|
|
1234
|
+
splitFileFactory,
|
|
1235
|
+
repoClone,
|
|
1236
|
+
repoPull,
|
|
1237
|
+
repoCommit,
|
|
1238
|
+
repoPush,
|
|
1239
|
+
newProject,
|
|
1240
|
+
runTest,
|
|
1241
|
+
getNpmRootPath,
|
|
975
1242
|
};
|
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({
|
|
@@ -48,7 +47,7 @@ const Dns = {
|
|
|
48
47
|
} catch (error) {
|
|
49
48
|
logger.error(error, { testIp, stack: error.stack });
|
|
50
49
|
}
|
|
51
|
-
if (testIp && typeof testIp === 'string' &&
|
|
50
|
+
if (testIp && typeof testIp === 'string' && validator.isIP(testIp) && Dns.ip !== testIp) {
|
|
52
51
|
logger.info(`New ip`, testIp);
|
|
53
52
|
for (const recordType of Object.keys(confCronData.records)) {
|
|
54
53
|
switch (recordType) {
|
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,17 +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()) => {
|
|
87
|
+
logger.info('npm_package_version', process.env.npm_package_version);
|
|
89
88
|
logger.info('argv', process.argv);
|
|
90
89
|
logger.info('platform', process.platform);
|
|
91
90
|
logger.info('env', process.env.NODE_ENV);
|
|
92
|
-
logger.info('admin', await isAdmin());
|
|
93
91
|
logger.info('--max-old-space-size', {
|
|
94
92
|
total_available_size: formatBytes(v8.getHeapStatistics().total_available_size),
|
|
95
93
|
});
|
|
@@ -179,12 +177,21 @@ const loggerMiddleware = (meta = { url: '' }) => {
|
|
|
179
177
|
};
|
|
180
178
|
|
|
181
179
|
const underpostASCI = () => `
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
180
|
+
|
|
181
|
+
██╗░░░██╗███╗░░██╗██████╗░███████╗██████╗░██████╗░░█████╗░░██████╗████████╗
|
|
182
|
+
██║░░░██║████╗░██║██╔══██╗██╔════╝██╔══██╗██╔══██╗██╔══██╗██╔════╝╚══██╔══╝
|
|
183
|
+
██║░░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██████╔╝██║░░██║╚█████╗░░░░██║░░░
|
|
184
|
+
██║░░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██╔═══╝░██║░░██║░╚═══██╗░░░██║░░░
|
|
185
|
+
╚██████╔╝██║░╚███║██████╔╝███████╗██║░░██║██║░░░░░╚█████╔╝██████╔╝░░░██║░░░
|
|
186
|
+
░╚═════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚═╝░░░░░░╚════╝░╚═════╝░░░░╚═╝░░░
|
|
188
187
|
`;
|
|
189
188
|
|
|
190
|
-
|
|
189
|
+
const actionInitLog = (version = '0.0.0') =>
|
|
190
|
+
console.log(
|
|
191
|
+
underpostASCI() +
|
|
192
|
+
`
|
|
193
|
+
${version} https://www.nexodev.org/docs
|
|
194
|
+
`,
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
export { loggerFactory, loggerMiddleware, setUpInfo, underpostASCI, actionInitLog };
|
package/src/server/network.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import detect from 'detect-port';
|
|
2
1
|
import fs from 'fs-extra';
|
|
3
2
|
|
|
4
3
|
import { publicIp, publicIpv4, publicIpv6 } from 'public-ip';
|
|
5
|
-
import { killPortProcess } from 'kill-port-process';
|
|
6
4
|
import { loggerFactory } from './logger.js';
|
|
7
|
-
import { orderArrayFromAttrInt } from '../client/components/core/CommonJs.js';
|
|
8
5
|
import { DataBaseProvider } from '../db/DataBaseProvider.js';
|
|
9
6
|
import { getDeployId } from './conf.js';
|
|
10
7
|
|
|
@@ -15,38 +12,6 @@ import { getDeployId } from './conf.js';
|
|
|
15
12
|
|
|
16
13
|
const logger = loggerFactory(import.meta);
|
|
17
14
|
|
|
18
|
-
const network = {
|
|
19
|
-
port: {
|
|
20
|
-
status: async (ports) => {
|
|
21
|
-
const status = [];
|
|
22
|
-
for (const port of ports) {
|
|
23
|
-
status.push({
|
|
24
|
-
port,
|
|
25
|
-
open: await new Promise((resolve) =>
|
|
26
|
-
detect(port)
|
|
27
|
-
.then((_port) => {
|
|
28
|
-
if (port == _port)
|
|
29
|
-
// `port: ${port} was not occupied`
|
|
30
|
-
return resolve(false);
|
|
31
|
-
|
|
32
|
-
// `port: ${port} was occupied, try port: ${_port}`
|
|
33
|
-
return resolve(true);
|
|
34
|
-
})
|
|
35
|
-
.catch((error) => resolve(`${error.message}`)),
|
|
36
|
-
),
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
return status;
|
|
40
|
-
},
|
|
41
|
-
kill: async (ports) => await killPortProcess(ports),
|
|
42
|
-
portClean: async function (port) {
|
|
43
|
-
const [portStatus] = await this.status([port]);
|
|
44
|
-
// logger.info('port status', portStatus);
|
|
45
|
-
if (portStatus.open) await this.kill([port]);
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
|
|
50
15
|
const ip = {
|
|
51
16
|
public: {
|
|
52
17
|
get: async () => await publicIp(), // => 'fe80::200:f8ff:fe21:67cf'
|
|
@@ -202,7 +167,6 @@ const listenPortController = async (server, port, metadata) =>
|
|
|
202
167
|
|
|
203
168
|
export {
|
|
204
169
|
ip,
|
|
205
|
-
network,
|
|
206
170
|
listenPortController,
|
|
207
171
|
networkRouter,
|
|
208
172
|
netWorkCron,
|
package/src/server/process.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
import shell from 'shelljs';
|
|
4
4
|
import dotenv from 'dotenv';
|
|
5
5
|
import fs from 'fs-extra';
|
|
6
|
-
|
|
7
6
|
import { loggerFactory } from './logger.js';
|
|
7
|
+
import clipboard from 'clipboardy';
|
|
8
8
|
|
|
9
9
|
dotenv.config();
|
|
10
10
|
|
|
@@ -63,4 +63,27 @@ const shellCd = (cd, options = { disableLog: false }) => {
|
|
|
63
63
|
return shell.cd(cd);
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
function pbcopy(data) {
|
|
67
|
+
switch (process.platform) {
|
|
68
|
+
case 'linux':
|
|
69
|
+
{
|
|
70
|
+
// sudo dnf install xclip
|
|
71
|
+
// sudo apt update
|
|
72
|
+
// sudo apt install xclip
|
|
73
|
+
// paste: xclip -o
|
|
74
|
+
// copy:
|
|
75
|
+
// shellExec(`echo "${data}" | xclip -sel clip`, { async: true });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
break;
|
|
79
|
+
|
|
80
|
+
default:
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
clipboard.writeSync(data || '🦄');
|
|
85
|
+
|
|
86
|
+
logger.info(`copied to clipboard`, clipboard.readSync());
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { ProcessController, getRootDirectory, shellExec, shellCd, pbcopy };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { loadConf, newProject, repoClone, repoCommit, repoPull, repoPush } from './conf.js';
|
|
2
|
+
|
|
3
|
+
class Project {
|
|
4
|
+
constructor(repositoryName, version) {
|
|
5
|
+
return newProject(repositoryName, version);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
static clone(gitUri = 'underpostnet/pwa-microservices-template') {
|
|
9
|
+
return repoClone(gitUri);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static useEnv(deployId = 'default', env = 'production') {
|
|
13
|
+
return loadConf(deployId, env);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static pull(repoPath = './', gitUri = 'underpostnet/pwa-microservices-template') {
|
|
17
|
+
return repoPull(repoPath, gitUri);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static commit(
|
|
21
|
+
repoPath = './',
|
|
22
|
+
commitType = 'feat',
|
|
23
|
+
subModule = '',
|
|
24
|
+
message = '',
|
|
25
|
+
options = {
|
|
26
|
+
copy: false,
|
|
27
|
+
info: false,
|
|
28
|
+
empty: false,
|
|
29
|
+
},
|
|
30
|
+
) {
|
|
31
|
+
return repoCommit(repoPath, commitType, subModule, message, options);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static push(repoPath = './', gitUri = 'underpostnet/pwa-microservices-template') {
|
|
35
|
+
return repoPush(repoPath, gitUri);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default Project;
|