underpost 2.8.0 → 2.8.6
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 +17 -71
- package/.vscode/settings.json +20 -4
- package/AUTHORS.md +16 -5
- package/CHANGELOG.md +103 -3
- package/Dockerfile +24 -66
- package/README.md +1 -28
- package/bin/build.js +186 -0
- package/bin/db.js +2 -24
- package/bin/deploy.js +168 -157
- package/bin/file.js +59 -16
- package/bin/hwt.js +0 -10
- package/bin/index.js +201 -61
- package/bin/ssl.js +19 -11
- package/bin/util.js +24 -101
- package/bin/vs.js +26 -2
- package/conf.js +30 -132
- package/docker-compose.yml +1 -1
- 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/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/valkey/kustomization.yaml +7 -0
- package/manifests/valkey/service.yaml +17 -0
- package/manifests/valkey/statefulset.yaml +39 -0
- package/package.json +133 -134
- 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 +202 -0
- package/src/cli/cron.js +90 -0
- package/src/cli/db.js +212 -0
- package/src/cli/deploy.js +318 -0
- package/src/cli/env.js +52 -0
- package/src/cli/fs.js +149 -0
- package/src/cli/image.js +148 -0
- package/src/cli/repository.js +125 -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 +4 -2
- package/src/client/components/core/Auth.js +24 -6
- package/src/client/components/core/CalendarCore.js +127 -50
- package/src/client/components/core/CommonJs.js +282 -19
- package/src/client/components/core/Css.js +2 -1
- package/src/client/components/core/CssCore.js +8 -4
- package/src/client/components/core/Docs.js +1 -1
- package/src/client/components/core/DropDown.js +5 -1
- package/src/client/components/core/Input.js +22 -6
- package/src/client/components/core/JoyStick.js +8 -5
- package/src/client/components/core/LoadingAnimation.js +8 -1
- package/src/client/components/core/Modal.js +47 -18
- package/src/client/components/core/Panel.js +93 -31
- package/src/client/components/core/PanelForm.js +27 -19
- package/src/client/components/core/Scroll.js +1 -0
- package/src/client/components/core/SignUp.js +4 -1
- package/src/client/components/core/Translate.js +61 -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/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 +15 -8
- package/src/client/services/default/default.management.js +4 -2
- package/src/client/ssr/Render.js +4 -1
- package/src/client/ssr/body/CacheControl.js +2 -2
- 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 +26 -6
- package/src/db/mongo/MongooseDB.js +29 -1
- package/src/index.js +91 -17
- 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 +41 -50
- package/src/server/client-formatted.js +6 -3
- package/src/server/client-icons.js +1 -1
- package/src/server/conf.js +207 -57
- package/src/server/dns.js +30 -55
- package/src/server/downloader.js +0 -8
- package/src/server/logger.js +22 -15
- 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 +30 -30
- package/src/server/ssl.js +1 -1
- package/src/server/valkey.js +3 -0
- 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/dns.js
CHANGED
|
@@ -1,29 +1,19 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import dotenv from 'dotenv';
|
|
3
3
|
import fs from 'fs';
|
|
4
|
-
import
|
|
5
|
-
|
|
4
|
+
import validator from 'validator';
|
|
6
5
|
import { ip } from './network.js';
|
|
7
6
|
import { loggerFactory } from './logger.js';
|
|
8
|
-
import
|
|
9
|
-
import { shellExec } from './process.js';
|
|
10
|
-
|
|
11
|
-
const httpsAgent = new https.Agent({
|
|
12
|
-
rejectUnauthorized: false,
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
axios.defaults.httpsAgent = httpsAgent;
|
|
7
|
+
import UnderpostRootEnv from '../cli/env.js';
|
|
16
8
|
|
|
17
9
|
dotenv.config();
|
|
18
10
|
|
|
19
11
|
const logger = loggerFactory(import.meta);
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// NAT-VPS modem/router device configuration:
|
|
26
|
-
// LAN --> [NAT-VPS] --> WAN
|
|
13
|
+
class Dns {
|
|
14
|
+
static callback = async function (deployList) {
|
|
15
|
+
// Network topology configuration:
|
|
16
|
+
// LAN -> [NAT-VPS](modem/router device) -> WAN
|
|
27
17
|
// enabled DMZ Host to proxy IP 80-443 (79-444) sometimes router block first port
|
|
28
18
|
// disabled local red DHCP
|
|
29
19
|
// verify inet ip proxy server address
|
|
@@ -31,25 +21,24 @@ const Dns = {
|
|
|
31
21
|
// LAN server or device's local servers port -> 3000-3100 (2999-3101)
|
|
32
22
|
// DNS Records: [ANAME](Address Dynamic) -> [A](ipv4) host | [AAAA](ipv6) host -> [public-ip]
|
|
33
23
|
// Forward the router's TCP/UDP ports to the LAN device's IP address
|
|
24
|
+
for (const _deployId of deployList.split(',')) {
|
|
25
|
+
const deployId = _deployId.trim();
|
|
26
|
+
const privateCronConfPath = `./engine-private/conf/${deployId}/conf.cron.json`;
|
|
27
|
+
const confCronPath = fs.existsSync(privateCronConfPath) ? privateCronConfPath : './conf/conf.cron.json';
|
|
28
|
+
const confCronData = JSON.parse(fs.readFileSync(confCronPath, 'utf8'));
|
|
34
29
|
|
|
35
|
-
const privateCronConfPath = `./engine-private/conf/${deployId}/conf.cron.json`;
|
|
36
|
-
|
|
37
|
-
const confCronPath = fs.existsSync(privateCronConfPath) ? privateCronConfPath : './conf/conf.cron.json';
|
|
38
|
-
let confCronData = JSON.parse(fs.readFileSync(confCronPath, 'utf8'));
|
|
39
|
-
if (confCronData.ipDaemon.disabled) return;
|
|
40
|
-
Dns.ip = confCronData.ipDaemon.ip;
|
|
41
|
-
logger.info(`Current ip`, Dns.ip);
|
|
42
|
-
const callback = async () => {
|
|
43
|
-
logger.info('init dns ip callback');
|
|
44
|
-
await logger.setUpInfo();
|
|
45
30
|
let testIp;
|
|
31
|
+
|
|
46
32
|
try {
|
|
47
33
|
testIp = await ip.public.ipv4();
|
|
48
34
|
} catch (error) {
|
|
49
35
|
logger.error(error, { testIp, stack: error.stack });
|
|
50
36
|
}
|
|
51
|
-
|
|
52
|
-
|
|
37
|
+
|
|
38
|
+
const currentIp = UnderpostRootEnv.API.get('ip');
|
|
39
|
+
|
|
40
|
+
if (testIp && typeof testIp === 'string' && validator.isIP(testIp) && currentIp !== testIp) {
|
|
41
|
+
logger.info(`new ip`, testIp);
|
|
53
42
|
for (const recordType of Object.keys(confCronData.records)) {
|
|
54
43
|
switch (recordType) {
|
|
55
44
|
case 'A':
|
|
@@ -67,20 +56,20 @@ const Dns = {
|
|
|
67
56
|
const ipUrlTest = `https://${process.env.DEFAULT_DEPLOY_HOST}`;
|
|
68
57
|
const response = await axios.get(ipUrlTest);
|
|
69
58
|
const verifyIp = response.request.socket.remoteAddress;
|
|
70
|
-
logger.info(ipUrlTest + '
|
|
59
|
+
logger.info(ipUrlTest + ' verify ip', verifyIp);
|
|
71
60
|
if (verifyIp === testIp) {
|
|
72
|
-
|
|
73
|
-
|
|
61
|
+
logger.info('ip updated successfully', testIp);
|
|
62
|
+
UnderpostRootEnv.API.set('ip', testIp);
|
|
63
|
+
} else logger.error('ip not updated', testIp);
|
|
74
64
|
} catch (error) {
|
|
75
|
-
logger.error(error
|
|
65
|
+
logger.error(error, error.stack);
|
|
66
|
+
logger.error('ip not updated', testIp);
|
|
76
67
|
}
|
|
77
68
|
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
},
|
|
83
|
-
services: {
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
static services = {
|
|
84
73
|
updateIp: {
|
|
85
74
|
dondominio: (options) => {
|
|
86
75
|
const { user, api_key, host, dns, ip } = options;
|
|
@@ -101,21 +90,7 @@ const Dns = {
|
|
|
101
90
|
});
|
|
102
91
|
},
|
|
103
92
|
},
|
|
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
|
-
};
|
|
93
|
+
};
|
|
94
|
+
}
|
|
120
95
|
|
|
121
|
-
export
|
|
96
|
+
export default Dns;
|
package/src/server/downloader.js
CHANGED
|
@@ -2,16 +2,8 @@ import axios from 'axios';
|
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import { loggerFactory } from './logger.js';
|
|
4
4
|
import dotenv from 'dotenv';
|
|
5
|
-
import https from 'https';
|
|
6
|
-
|
|
7
5
|
dotenv.config();
|
|
8
6
|
|
|
9
|
-
const httpsAgent = new https.Agent({
|
|
10
|
-
rejectUnauthorized: false,
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
axios.defaults.httpsAgent = httpsAgent;
|
|
14
|
-
|
|
15
7
|
const logger = loggerFactory(import.meta);
|
|
16
8
|
|
|
17
9
|
const Downloader = (url, fullPath, options = { method: 'get', responseType: 'stream' }) =>
|
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()) => {
|
|
89
87
|
logger.info('argv', process.argv);
|
|
88
|
+
logger.info('cwd', process.cwd());
|
|
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
|
});
|
|
@@ -114,10 +112,10 @@ const loggerFactory = (meta = { url: '' }) => {
|
|
|
114
112
|
// Allow the use the terminal to print the messages
|
|
115
113
|
new winston.transports.Console(),
|
|
116
114
|
// Allow to print all the error level messages inside the error.log file
|
|
117
|
-
new winston.transports.File({
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}),
|
|
115
|
+
// new winston.transports.File({
|
|
116
|
+
// filename: `logs/${meta}/error.log`,
|
|
117
|
+
// level: 'error',
|
|
118
|
+
// }),
|
|
121
119
|
// Allow to print all the error message inside the all.log file
|
|
122
120
|
// (also the error log that are also printed inside the error.log(
|
|
123
121
|
new winston.transports.File({ filename: `logs/${meta}/all.log` }),
|
|
@@ -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 = () =>
|
|
190
|
+
console.log(
|
|
191
|
+
underpostASCI() +
|
|
192
|
+
`
|
|
193
|
+
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 {
|
|
6
|
-
import { loggerFactory } from './logger.js';
|
|
7
|
-
import { orderArrayFromAttrInt } from '../client/components/core/CommonJs.js';
|
|
4
|
+
import { actionInitLog, loggerFactory } from './logger.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'
|
|
@@ -74,8 +39,8 @@ const saveRuntimeRouter = async () => {
|
|
|
74
39
|
const host = process.env.DEFAULT_DEPLOY_HOST;
|
|
75
40
|
const path = process.env.DEFAULT_DEPLOY_PATH;
|
|
76
41
|
const confServerPath = `./engine-private/conf/${deployId}/conf.server.json`;
|
|
77
|
-
if (!deployId || !host || !path) {
|
|
78
|
-
logger.warn('default deploy instance not found');
|
|
42
|
+
if (!deployId || !host || !path || !fs.existsSync(confServerPath)) {
|
|
43
|
+
// logger.warn('default deploy instance not found');
|
|
79
44
|
return;
|
|
80
45
|
}
|
|
81
46
|
const confServer = JSON.parse(fs.readFileSync(confServerPath, 'utf8'));
|
|
@@ -112,7 +77,7 @@ const saveRuntimeRouter = async () => {
|
|
|
112
77
|
|
|
113
78
|
if (closeConn) await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
|
|
114
79
|
} catch (error) {
|
|
115
|
-
logger.error(error);
|
|
80
|
+
logger.error(error, error.stack);
|
|
116
81
|
}
|
|
117
82
|
};
|
|
118
83
|
|
|
@@ -149,20 +114,30 @@ const saveRuntimeCron = async () => {
|
|
|
149
114
|
|
|
150
115
|
if (closeConn) await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
|
|
151
116
|
} catch (error) {
|
|
152
|
-
logger.error(error);
|
|
117
|
+
logger.error(error, error.stack);
|
|
153
118
|
}
|
|
154
119
|
};
|
|
155
120
|
|
|
156
121
|
const listenServerFactory = (logic = async () => {}) => {
|
|
157
122
|
return {
|
|
158
|
-
listen: async (...args) => (
|
|
123
|
+
listen: async (...args) => (
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
const message = 'Listen server factory timeout';
|
|
126
|
+
logger.error(message);
|
|
127
|
+
throw new Error(message);
|
|
128
|
+
}, 80000000), // ~ 55 days
|
|
129
|
+
(logic ? await logic(...args) : undefined, args[1]())
|
|
130
|
+
),
|
|
159
131
|
};
|
|
160
132
|
};
|
|
161
133
|
|
|
162
134
|
const listenPortController = async (server, port, metadata) =>
|
|
163
135
|
new Promise((resolve) => {
|
|
164
136
|
try {
|
|
165
|
-
if (
|
|
137
|
+
if (port === ':') {
|
|
138
|
+
server.listen(port, actionInitLog);
|
|
139
|
+
return resolve(true);
|
|
140
|
+
}
|
|
166
141
|
|
|
167
142
|
const { host, path, client, runtime, meta } = metadata;
|
|
168
143
|
const error = [];
|
|
@@ -202,7 +177,6 @@ const listenPortController = async (server, port, metadata) =>
|
|
|
202
177
|
|
|
203
178
|
export {
|
|
204
179
|
ip,
|
|
205
|
-
network,
|
|
206
180
|
listenPortController,
|
|
207
181
|
networkRouter,
|
|
208
182
|
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 };
|
package/src/server/proxy.js
CHANGED
|
@@ -5,10 +5,9 @@ import dotenv from 'dotenv';
|
|
|
5
5
|
|
|
6
6
|
import { createProxyMiddleware } from 'http-proxy-middleware';
|
|
7
7
|
import { loggerFactory, loggerMiddleware } from './logger.js';
|
|
8
|
-
import { listenPortController
|
|
9
|
-
import { orderArrayFromAttrInt } from '../client/components/core/CommonJs.js';
|
|
8
|
+
import { listenPortController } from './network.js';
|
|
10
9
|
import { createSslServer, sslRedirectMiddleware } from './ssl.js';
|
|
11
|
-
import { buildProxyRouter, maintenanceMiddleware } from './conf.js';
|
|
10
|
+
import { buildPortProxyRouter, buildProxyRouter, maintenanceMiddleware } from './conf.js';
|
|
12
11
|
|
|
13
12
|
dotenv.config();
|
|
14
13
|
|
|
@@ -16,7 +15,7 @@ const logger = loggerFactory(import.meta);
|
|
|
16
15
|
|
|
17
16
|
const buildProxy = async () => {
|
|
18
17
|
// default target
|
|
19
|
-
|
|
18
|
+
|
|
20
19
|
express().listen(process.env.PORT);
|
|
21
20
|
|
|
22
21
|
const proxyRouter = buildProxyRouter();
|
|
@@ -57,27 +56,7 @@ const buildProxy = async () => {
|
|
|
57
56
|
// '^/target-path': '/',
|
|
58
57
|
},
|
|
59
58
|
};
|
|
60
|
-
if (!process.argv.includes('maintenance'))
|
|
61
|
-
// build router
|
|
62
|
-
Object.keys(hosts).map((hostKey) => {
|
|
63
|
-
let { host, path, target, proxy, peer } = hosts[hostKey];
|
|
64
|
-
if (process.env.NODE_ENV === 'development') host = `localhost`;
|
|
65
|
-
|
|
66
|
-
if (!proxy.includes(port)) return;
|
|
67
|
-
const absoluteHost = [80, 443].includes(port)
|
|
68
|
-
? `${host}${path === '/' ? '' : path}`
|
|
69
|
-
: `${host}:${port}${path === '/' ? '' : path}`;
|
|
70
|
-
|
|
71
|
-
if (!(absoluteHost in options.router)) options.router[absoluteHost] = target;
|
|
72
|
-
});
|
|
73
|
-
if (Object.keys(options.router).length === 0) continue;
|
|
74
|
-
|
|
75
|
-
// order router
|
|
76
|
-
const router = {};
|
|
77
|
-
for (const absoluteHostKey of orderArrayFromAttrInt(Object.keys(options.router), 'length'))
|
|
78
|
-
router[absoluteHostKey] = options.router[absoluteHostKey];
|
|
79
|
-
options.router = router;
|
|
80
|
-
}
|
|
59
|
+
if (!process.argv.includes('maintenance')) options.router = buildPortProxyRouter(port, proxyRouter);
|
|
81
60
|
|
|
82
61
|
const filter = false
|
|
83
62
|
? (pathname, req) => {
|
|
@@ -86,7 +65,6 @@ const buildProxy = async () => {
|
|
|
86
65
|
}
|
|
87
66
|
: proxyPath;
|
|
88
67
|
app.use(proxyPath, createProxyMiddleware(filter, options));
|
|
89
|
-
await network.port.portClean(port);
|
|
90
68
|
|
|
91
69
|
switch (process.env.NODE_ENV) {
|
|
92
70
|
case 'production':
|
package/src/server/runtime.js
CHANGED
|
@@ -9,17 +9,18 @@ import compression from 'compression';
|
|
|
9
9
|
|
|
10
10
|
import { createServer } from 'http';
|
|
11
11
|
import { getRootDirectory } from './process.js';
|
|
12
|
-
import {
|
|
12
|
+
import { listenPortController, saveRuntimeRouter, logRuntimeRouter, listenServerFactory } from './network.js';
|
|
13
13
|
import { loggerFactory, loggerMiddleware } from './logger.js';
|
|
14
14
|
import { getCapVariableName, newInstance } from '../client/components/core/CommonJs.js';
|
|
15
15
|
import { Xampp } from '../runtime/xampp/Xampp.js';
|
|
16
16
|
import { MailerProvider } from '../mailer/MailerProvider.js';
|
|
17
17
|
import { DataBaseProvider } from '../db/DataBaseProvider.js';
|
|
18
|
-
import { createProxyMiddleware } from 'http-proxy-middleware';
|
|
18
|
+
// import { createProxyMiddleware } from 'http-proxy-middleware';
|
|
19
19
|
import { createPeerServer } from './peer.js';
|
|
20
20
|
import { Lampp } from '../runtime/lampp/Lampp.js';
|
|
21
21
|
import { getDeployId } from './conf.js';
|
|
22
|
-
import { ssrFactory } from './client-formatted.js';
|
|
22
|
+
import { JSONweb, ssrFactory } from './client-formatted.js';
|
|
23
|
+
import Underpost from '../index.js';
|
|
23
24
|
|
|
24
25
|
dotenv.config();
|
|
25
26
|
|
|
@@ -31,20 +32,6 @@ const buildRuntime = async () => {
|
|
|
31
32
|
const collectDefaultMetrics = promClient.collectDefaultMetrics;
|
|
32
33
|
collectDefaultMetrics();
|
|
33
34
|
|
|
34
|
-
if (fs.existsSync(`/root/.bashrc`) && !fs.readFileSync(`/root/.bashrc`, 'utf8').match(`underpost-engine`)) {
|
|
35
|
-
fs.writeFileSync(
|
|
36
|
-
`/root/.bashrc`,
|
|
37
|
-
`${fs.readFileSync(`/root/.bashrc`, 'utf8')}
|
|
38
|
-
` +
|
|
39
|
-
`export NVM_DIR="$HOME/.nvm"
|
|
40
|
-
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
|
41
|
-
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm underpost-engine bash_completion
|
|
42
|
-
|
|
43
|
-
export PATH=$PATH:/opt/lampp/bin`,
|
|
44
|
-
'utf8',
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
35
|
const promCounterOption = {
|
|
49
36
|
name: `${deployId.replaceAll('-', '_')}_http_requests_total`,
|
|
50
37
|
help: 'Total number of HTTP requests',
|
|
@@ -54,7 +41,6 @@ export PATH=$PATH:/opt/lampp/bin`,
|
|
|
54
41
|
// logger.info('promCounterOption', promCounterOption);
|
|
55
42
|
|
|
56
43
|
const requestCounter = new promClient.Counter(promCounterOption);
|
|
57
|
-
|
|
58
44
|
const ipInstance = ''; // await ip.public.ipv4();
|
|
59
45
|
const initPort = parseInt(process.env.PORT) + 1;
|
|
60
46
|
let currentPort = initPort;
|
|
@@ -101,12 +87,13 @@ export PATH=$PATH:/opt/lampp/bin`,
|
|
|
101
87
|
apis,
|
|
102
88
|
};
|
|
103
89
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
90
|
+
const redirectTarget = redirect
|
|
91
|
+
? redirect[redirect.length - 1] === '/'
|
|
92
|
+
? redirect.slice(0, -1)
|
|
93
|
+
: redirect
|
|
94
|
+
: undefined;
|
|
95
|
+
|
|
96
|
+
// if (redirect) logger.info('redirect', new URL(redirect));
|
|
110
97
|
|
|
111
98
|
switch (runtime) {
|
|
112
99
|
case 'lampp':
|
|
@@ -295,7 +282,7 @@ export PATH=$PATH:/opt/lampp/bin`,
|
|
|
295
282
|
logger.info('Build static server runtime', `${host}${path}`);
|
|
296
283
|
currentPort += 2;
|
|
297
284
|
const staticPort = newInstance(currentPort);
|
|
298
|
-
|
|
285
|
+
|
|
299
286
|
await listenPortController(app, staticPort, runningData);
|
|
300
287
|
currentPort++;
|
|
301
288
|
continue;
|
|
@@ -346,7 +333,7 @@ export PATH=$PATH:/opt/lampp/bin`,
|
|
|
346
333
|
// changeOrigin: true,
|
|
347
334
|
// }),
|
|
348
335
|
// );
|
|
349
|
-
|
|
336
|
+
|
|
350
337
|
await listenPortController(app, port, runningData);
|
|
351
338
|
break;
|
|
352
339
|
}
|
|
@@ -398,6 +385,13 @@ export PATH=$PATH:/opt/lampp/bin`,
|
|
|
398
385
|
ssrPath,
|
|
399
386
|
ssrHeadComponents: '',
|
|
400
387
|
ssrBodyComponents: (await ssrFactory(`./src/client/ssr/body/404.js`))(),
|
|
388
|
+
renderPayload: {
|
|
389
|
+
apiBasePath: process.env.BASE_API,
|
|
390
|
+
version: Underpost.version,
|
|
391
|
+
},
|
|
392
|
+
renderApi: {
|
|
393
|
+
JSONweb,
|
|
394
|
+
},
|
|
401
395
|
});
|
|
402
396
|
const path404 = `${directory ? directory : `${getRootDirectory()}${rootHostPath}`}/404/index.html`;
|
|
403
397
|
const page404 = fs.existsSync(path404) ? `${path === '/' ? '' : path}/404` : undefined;
|
|
@@ -414,6 +408,13 @@ export PATH=$PATH:/opt/lampp/bin`,
|
|
|
414
408
|
ssrPath,
|
|
415
409
|
ssrHeadComponents: '',
|
|
416
410
|
ssrBodyComponents: (await ssrFactory(`./src/client/ssr/body/500.js`))(),
|
|
411
|
+
renderPayload: {
|
|
412
|
+
apiBasePath: process.env.BASE_API,
|
|
413
|
+
version: Underpost.version,
|
|
414
|
+
},
|
|
415
|
+
renderApi: {
|
|
416
|
+
JSONweb,
|
|
417
|
+
},
|
|
417
418
|
});
|
|
418
419
|
const path500 = `${directory ? directory : `${getRootDirectory()}${rootHostPath}`}/500/index.html`;
|
|
419
420
|
const page500 = fs.existsSync(path500) ? `${path === '/' ? '' : path}/500` : undefined;
|
|
@@ -460,7 +461,7 @@ export PATH=$PATH:/opt/lampp/bin`,
|
|
|
460
461
|
host,
|
|
461
462
|
path,
|
|
462
463
|
});
|
|
463
|
-
|
|
464
|
+
|
|
464
465
|
await listenPortController(peerServer, peerPort, {
|
|
465
466
|
runtime: 'nodejs',
|
|
466
467
|
client: null,
|
|
@@ -470,7 +471,6 @@ export PATH=$PATH:/opt/lampp/bin`,
|
|
|
470
471
|
});
|
|
471
472
|
}
|
|
472
473
|
|
|
473
|
-
await network.port.portClean(port);
|
|
474
474
|
await listenPortController(server, port, runningData);
|
|
475
475
|
|
|
476
476
|
break;
|
|
@@ -481,8 +481,8 @@ export PATH=$PATH:/opt/lampp/bin`,
|
|
|
481
481
|
}
|
|
482
482
|
}
|
|
483
483
|
|
|
484
|
-
if (Xampp.enabled() && Xampp.router)
|
|
485
|
-
if (Lampp.enabled() && Lampp.router)
|
|
484
|
+
if (Xampp.enabled() && Xampp.router) Xampp.initService();
|
|
485
|
+
if (Lampp.enabled() && Lampp.router) Lampp.initService();
|
|
486
486
|
|
|
487
487
|
saveRuntimeRouter();
|
|
488
488
|
logRuntimeRouter();
|
package/src/server/ssl.js
CHANGED
|
@@ -70,7 +70,7 @@ const validateSecureContext = (host) => {
|
|
|
70
70
|
const buildSecureContext = (host) => {
|
|
71
71
|
return {
|
|
72
72
|
key: fs.readFileSync(`./engine-private/ssl/${host}/key.key`, 'utf8'),
|
|
73
|
-
cert: fs.readFileSync(`./engine-private/ssl/${host}/
|
|
73
|
+
cert: fs.readFileSync(`./engine-private/ssl/${host}/ca_bundle.crt`, 'utf8'),
|
|
74
74
|
ca: fs.readFileSync(`./engine-private/ssl/${host}/ca_bundle.crt`, 'utf8'),
|
|
75
75
|
};
|
|
76
76
|
};
|
package/src/server/valkey.js
CHANGED
|
@@ -21,6 +21,8 @@ const selectDtoFactory = (payload, select) => {
|
|
|
21
21
|
|
|
22
22
|
const valkeyClientFactory = async () => {
|
|
23
23
|
const valkey = new Valkey({
|
|
24
|
+
// port: 6379,
|
|
25
|
+
// host: 'service-valkey.default.svc.cluster.local',
|
|
24
26
|
retryStrategy: (attempt) => {
|
|
25
27
|
if (attempt === 1) {
|
|
26
28
|
valkey.disconnect();
|
|
@@ -53,6 +55,7 @@ const getValkeyObject = async (key = '') => {
|
|
|
53
55
|
try {
|
|
54
56
|
return JSON.parse(object);
|
|
55
57
|
} catch (error) {
|
|
58
|
+
logger.error(error);
|
|
56
59
|
return object;
|
|
57
60
|
}
|
|
58
61
|
};
|
package/test/api.test.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import axios from 'axios';
|
|
4
4
|
import dotenv from 'dotenv';
|
|
5
|
-
import https from 'https';
|
|
6
5
|
|
|
7
6
|
import { expect } from 'chai';
|
|
8
7
|
import { loggerFactory } from '../src/server/logger.js';
|
|
@@ -20,13 +19,6 @@ const BASE_URL =
|
|
|
20
19
|
? `http://localhost:${PORT}/${process.env.BASE_API}`
|
|
21
20
|
: `https://www.nexodev.org/api`;
|
|
22
21
|
|
|
23
|
-
axios.defaults.baseURL = BASE_URL;
|
|
24
|
-
|
|
25
|
-
const httpsAgent = new https.Agent({
|
|
26
|
-
rejectUnauthorized: false,
|
|
27
|
-
});
|
|
28
|
-
axios.defaults.httpsAgent = httpsAgent;
|
|
29
|
-
|
|
30
22
|
describe(`GET 'Test' API Request `, async () => {
|
|
31
23
|
{
|
|
32
24
|
const url = `${BASE_URL}/test/youtube-id/?url=https://www.youtube.com/watch?v=o4f42SbyDMk`;
|
package/src/dns.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// https://nodejs.org/api
|
|
4
|
-
// https://expressjs.com/en/4x/api.html
|
|
5
|
-
|
|
6
|
-
import dotenv from 'dotenv';
|
|
7
|
-
import { loggerFactory } from './server/logger.js';
|
|
8
|
-
import { Dns } from './server/dns.js';
|
|
9
|
-
import { ProcessController } from './server/process.js';
|
|
10
|
-
import { Config } from './server/conf.js';
|
|
11
|
-
|
|
12
|
-
dotenv.config();
|
|
13
|
-
|
|
14
|
-
await Config.build();
|
|
15
|
-
|
|
16
|
-
const logger = loggerFactory(import.meta);
|
|
17
|
-
|
|
18
|
-
await logger.setUpInfo();
|
|
19
|
-
|
|
20
|
-
await Dns.InitIpDaemon();
|
|
21
|
-
|
|
22
|
-
ProcessController.init(logger);
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
// https://github.com/xenova/transformers.js/blob/f43d3dd348fd7b293008802590bb3a1afa218dc7/src/models.js#L10
|
|
2
|
-
|
|
3
|
-
import { AutoModelForSeq2SeqLM, AutoTokenizer } from '@xenova/transformers';
|
|
4
|
-
import { loggerFactory } from './logger.js';
|
|
5
|
-
import dotenv from 'dotenv';
|
|
6
|
-
|
|
7
|
-
dotenv.config();
|
|
8
|
-
|
|
9
|
-
const logger = loggerFactory(import.meta);
|
|
10
|
-
|
|
11
|
-
const tokenizer = await AutoTokenizer.from_pretrained('Xenova/t5-small');
|
|
12
|
-
|
|
13
|
-
const model = await AutoModelForSeq2SeqLM.from_pretrained('Xenova/t5-small');
|
|
14
|
-
|
|
15
|
-
const prompt = 'translate English to German: I love transformers!';
|
|
16
|
-
|
|
17
|
-
logger.info('input', { prompt });
|
|
18
|
-
|
|
19
|
-
const tokenizerData = await tokenizer(prompt);
|
|
20
|
-
|
|
21
|
-
const { input_ids } = tokenizerData;
|
|
22
|
-
|
|
23
|
-
const outputs = await model.generate(input_ids);
|
|
24
|
-
|
|
25
|
-
for (const output of outputs) {
|
|
26
|
-
const decoded = tokenizer.decode(output, { skip_special_tokens: true });
|
|
27
|
-
logger.info('decoded', { decoded });
|
|
28
|
-
}
|