@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.
Files changed (105) hide show
  1. package/.dockerignore +1 -0
  2. package/.github/workflows/ghpkg.yml +20 -50
  3. package/.github/workflows/npmpkg.yml +67 -0
  4. package/.github/workflows/publish.yml +5 -5
  5. package/.github/workflows/pwa-microservices-template.page.yml +13 -5
  6. package/.github/workflows/pwa-microservices-template.test.yml +2 -2
  7. package/.vscode/extensions.json +17 -71
  8. package/.vscode/settings.json +14 -3
  9. package/AUTHORS.md +16 -5
  10. package/CHANGELOG.md +79 -3
  11. package/Dockerfile +24 -66
  12. package/README.md +1 -28
  13. package/bin/build.js +161 -0
  14. package/bin/db.js +2 -24
  15. package/bin/deploy.js +111 -82
  16. package/bin/file.js +59 -16
  17. package/bin/index.js +168 -58
  18. package/bin/ssl.js +19 -11
  19. package/bin/util.js +9 -97
  20. package/bin/vs.js +25 -2
  21. package/conf.js +31 -138
  22. package/docker-compose.yml +1 -1
  23. package/manifests/core/kustomization.yaml +11 -0
  24. package/manifests/core/underpost-engine-backup-access.yaml +16 -0
  25. package/manifests/core/underpost-engine-backup-pv-pvc.yaml +22 -0
  26. package/manifests/core/underpost-engine-headless-service.yaml +10 -0
  27. package/manifests/core/underpost-engine-mongodb-backup-cronjob.yaml +40 -0
  28. package/manifests/core/underpost-engine-mongodb-configmap.yaml +26 -0
  29. package/manifests/core/underpost-engine-pv-pvc.yaml +23 -0
  30. package/manifests/core/underpost-engine-statefulset.yaml +91 -0
  31. package/manifests/deployment/mongo-express/deployment.yaml +60 -0
  32. package/manifests/deployment/phpmyadmin/deployment.yaml +54 -0
  33. package/manifests/kind-config.yaml +12 -0
  34. package/manifests/letsencrypt-prod.yaml +15 -0
  35. package/manifests/mariadb/config.yaml +10 -0
  36. package/manifests/mariadb/kustomization.yaml +9 -0
  37. package/manifests/mariadb/pv.yaml +12 -0
  38. package/manifests/mariadb/pvc.yaml +10 -0
  39. package/manifests/mariadb/secret.yaml +8 -0
  40. package/manifests/mariadb/service.yaml +10 -0
  41. package/manifests/mariadb/statefulset.yaml +55 -0
  42. package/manifests/mongodb/backup-access.yaml +16 -0
  43. package/manifests/mongodb/backup-cronjob.yaml +42 -0
  44. package/manifests/mongodb/backup-pv-pvc.yaml +22 -0
  45. package/manifests/mongodb/configmap.yaml +26 -0
  46. package/manifests/mongodb/headless-service.yaml +10 -0
  47. package/manifests/mongodb/kustomization.yaml +11 -0
  48. package/manifests/mongodb/pv-pvc.yaml +23 -0
  49. package/manifests/mongodb/statefulset.yaml +125 -0
  50. package/manifests/valkey/kustomization.yaml +7 -0
  51. package/manifests/valkey/service.yaml +17 -0
  52. package/manifests/valkey/statefulset.yaml +39 -0
  53. package/manifests/valkey/underpost-engine-valkey-service.yaml +17 -0
  54. package/manifests/valkey/underpost-engine-valkey-statefulset.yaml +39 -0
  55. package/package.json +26 -31
  56. package/src/api/core/core.service.js +1 -1
  57. package/src/api/user/user.model.js +16 -3
  58. package/src/api/user/user.service.js +1 -1
  59. package/src/cli/cluster.js +154 -0
  60. package/src/cli/cron.js +90 -0
  61. package/src/cli/db.js +148 -0
  62. package/src/cli/deploy.js +277 -0
  63. package/src/cli/env.js +52 -0
  64. package/src/cli/image.js +125 -0
  65. package/src/cli/repository.js +104 -0
  66. package/src/cli/script.js +29 -0
  67. package/src/cli/secrets.js +37 -0
  68. package/src/cli/test.js +83 -0
  69. package/src/client/components/core/Auth.js +22 -4
  70. package/src/client/components/core/CalendarCore.js +115 -49
  71. package/src/client/components/core/CommonJs.js +231 -19
  72. package/src/client/components/core/Css.js +1 -0
  73. package/src/client/components/core/CssCore.js +6 -0
  74. package/src/client/components/core/DropDown.js +5 -1
  75. package/src/client/components/core/Input.js +18 -4
  76. package/src/client/components/core/Modal.js +10 -6
  77. package/src/client/components/core/Panel.js +84 -25
  78. package/src/client/components/core/PanelForm.js +4 -18
  79. package/src/client/components/core/Scroll.js +1 -0
  80. package/src/client/components/core/Translate.js +47 -9
  81. package/src/client/components/core/Validator.js +9 -1
  82. package/src/client/components/core/VanillaJs.js +0 -9
  83. package/src/client/components/core/Worker.js +34 -31
  84. package/src/client/services/default/default.management.js +4 -2
  85. package/src/client/ssr/body/CacheControl.js +2 -2
  86. package/src/db/mongo/MongooseDB.js +13 -1
  87. package/src/index.js +77 -19
  88. package/src/runtime/lampp/Lampp.js +1 -13
  89. package/src/runtime/xampp/Xampp.js +0 -13
  90. package/src/server/auth.js +3 -3
  91. package/src/server/backup.js +49 -93
  92. package/src/server/client-build.js +4 -23
  93. package/src/server/client-formatted.js +5 -3
  94. package/src/server/conf.js +193 -45
  95. package/src/server/dns.js +49 -67
  96. package/src/server/logger.js +15 -10
  97. package/src/server/network.js +17 -43
  98. package/src/server/process.js +25 -2
  99. package/src/server/proxy.js +4 -26
  100. package/src/server/runtime.js +14 -29
  101. package/src/server/ssl.js +1 -1
  102. package/src/server/valkey.js +2 -0
  103. package/src/dns.js +0 -22
  104. package/src/server/prompt-optimizer.js +0 -28
  105. package/startup.js +0 -11
@@ -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
- 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) => (logic ? await logic(...args) : undefined, args[1]()),
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 (!server) server = listenServerFactory();
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,
@@ -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
- export { ProcessController, getRootDirectory, shellExec, shellCd };
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 };
@@ -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, network } from './network.js';
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
- await network.port.portClean(process.env.PORT);
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':
@@ -9,13 +9,13 @@ import compression from 'compression';
9
9
 
10
10
  import { createServer } from 'http';
11
11
  import { getRootDirectory } from './process.js';
12
- import { network, listenPortController, saveRuntimeRouter, logRuntimeRouter, listenServerFactory } from './network.js';
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';
@@ -31,20 +31,6 @@ const buildRuntime = async () => {
31
31
  const collectDefaultMetrics = promClient.collectDefaultMetrics;
32
32
  collectDefaultMetrics();
33
33
 
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
34
  const promCounterOption = {
49
35
  name: `${deployId.replaceAll('-', '_')}_http_requests_total`,
50
36
  help: 'Total number of HTTP requests',
@@ -54,7 +40,6 @@ export PATH=$PATH:/opt/lampp/bin`,
54
40
  // logger.info('promCounterOption', promCounterOption);
55
41
 
56
42
  const requestCounter = new promClient.Counter(promCounterOption);
57
-
58
43
  const ipInstance = ''; // await ip.public.ipv4();
59
44
  const initPort = parseInt(process.env.PORT) + 1;
60
45
  let currentPort = initPort;
@@ -101,12 +86,13 @@ export PATH=$PATH:/opt/lampp/bin`,
101
86
  apis,
102
87
  };
103
88
 
104
- let redirectUrl;
105
- let redirectTarget;
106
- if (redirect) {
107
- redirectUrl = new URL(redirect);
108
- redirectTarget = redirect[redirect.length - 1] === '/' ? redirect.slice(0, -1) : redirect;
109
- }
89
+ const redirectTarget = redirect
90
+ ? redirect[redirect.length - 1] === '/'
91
+ ? redirect.slice(0, -1)
92
+ : redirect
93
+ : undefined;
94
+
95
+ // if (redirect) logger.info('redirect', new URL(redirect));
110
96
 
111
97
  switch (runtime) {
112
98
  case 'lampp':
@@ -295,7 +281,7 @@ export PATH=$PATH:/opt/lampp/bin`,
295
281
  logger.info('Build static server runtime', `${host}${path}`);
296
282
  currentPort += 2;
297
283
  const staticPort = newInstance(currentPort);
298
- await network.port.portClean(staticPort);
284
+
299
285
  await listenPortController(app, staticPort, runningData);
300
286
  currentPort++;
301
287
  continue;
@@ -346,7 +332,7 @@ export PATH=$PATH:/opt/lampp/bin`,
346
332
  // changeOrigin: true,
347
333
  // }),
348
334
  // );
349
- await network.port.portClean(port);
335
+
350
336
  await listenPortController(app, port, runningData);
351
337
  break;
352
338
  }
@@ -460,7 +446,7 @@ export PATH=$PATH:/opt/lampp/bin`,
460
446
  host,
461
447
  path,
462
448
  });
463
- await network.port.portClean(peerPort);
449
+
464
450
  await listenPortController(peerServer, peerPort, {
465
451
  runtime: 'nodejs',
466
452
  client: null,
@@ -470,7 +456,6 @@ export PATH=$PATH:/opt/lampp/bin`,
470
456
  });
471
457
  }
472
458
 
473
- await network.port.portClean(port);
474
459
  await listenPortController(server, port, runningData);
475
460
 
476
461
  break;
@@ -481,8 +466,8 @@ export PATH=$PATH:/opt/lampp/bin`,
481
466
  }
482
467
  }
483
468
 
484
- if (Xampp.enabled() && Xampp.router) await Xampp.initService({ daemon: true });
485
- if (Lampp.enabled() && Lampp.router) await Lampp.initService({ daemon: true });
469
+ if (Xampp.enabled() && Xampp.router) Xampp.initService();
470
+ if (Lampp.enabled() && Lampp.router) Lampp.initService();
486
471
 
487
472
  saveRuntimeRouter();
488
473
  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}/crt.crt`, 'utf8'),
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
  };
@@ -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();
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
- }
package/startup.js DELETED
@@ -1,11 +0,0 @@
1
- import { shellExec } from './src/server/process.js';
2
-
3
- // /usr/bin/supervisord -n
4
- // /usr/sbin/sshd -D
5
- shellExec(`/usr/bin/supervisord -n`, { async: true });
6
-
7
- shellExec(`sudo /opt/lampp/lampp start`, { async: true });
8
-
9
- shellExec(`/usr/bin/mongod -f /etc/mongod.conf`, { async: true });
10
-
11
- shellExec(`underpost new app server`);