underpost 2.8.62 → 2.8.65

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 (50) hide show
  1. package/Dockerfile +9 -10
  2. package/bin/build.js +2 -2
  3. package/bin/deploy.js +40 -2
  4. package/bin/index.js +39 -18
  5. package/docker-compose.yml +1 -1
  6. package/package.json +2 -9
  7. package/src/api/default/default.service.js +1 -1
  8. package/src/api/user/user.service.js +14 -11
  9. package/src/cli/cluster.js +45 -2
  10. package/src/cli/cron.js +39 -8
  11. package/src/cli/db.js +18 -8
  12. package/src/cli/deploy.js +173 -80
  13. package/src/cli/fs.js +7 -6
  14. package/src/cli/image.js +39 -101
  15. package/src/cli/monitor.js +182 -0
  16. package/src/cli/repository.js +5 -2
  17. package/src/client/components/core/Account.js +28 -24
  18. package/src/client/components/core/Blockchain.js +1 -1
  19. package/src/client/components/core/CalendarCore.js +14 -84
  20. package/src/client/components/core/CommonJs.js +2 -1
  21. package/src/client/components/core/Css.js +0 -1
  22. package/src/client/components/core/CssCore.js +10 -2
  23. package/src/client/components/core/Docs.js +1 -1
  24. package/src/client/components/core/EventsUI.js +3 -3
  25. package/src/client/components/core/FileExplorer.js +86 -78
  26. package/src/client/components/core/LoadingAnimation.js +1 -17
  27. package/src/client/components/core/LogIn.js +3 -3
  28. package/src/client/components/core/LogOut.js +1 -1
  29. package/src/client/components/core/Modal.js +12 -7
  30. package/src/client/components/core/Panel.js +19 -61
  31. package/src/client/components/core/PanelForm.js +13 -22
  32. package/src/client/components/core/Recover.js +3 -3
  33. package/src/client/components/core/RichText.js +1 -11
  34. package/src/client/components/core/Router.js +3 -1
  35. package/src/client/components/core/SignUp.js +2 -2
  36. package/src/client/components/default/RoutesDefault.js +3 -2
  37. package/src/client/services/default/default.management.js +45 -38
  38. package/src/client/ssr/Render.js +2 -0
  39. package/src/index.js +18 -2
  40. package/src/mailer/MailerProvider.js +3 -0
  41. package/src/runtime/lampp/Dockerfile +65 -0
  42. package/src/server/conf.js +89 -1
  43. package/src/server/dns.js +9 -1
  44. package/src/server/json-schema.js +77 -0
  45. package/src/server/network.js +7 -122
  46. package/src/server/peer.js +2 -2
  47. package/src/server/proxy.js +4 -4
  48. package/src/server/runtime.js +22 -11
  49. package/src/server/start.js +123 -0
  50. package/src/server/valkey.js +25 -11
@@ -5,9 +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 } from './network.js';
9
8
  import { createSslServer, sslRedirectMiddleware } from './ssl.js';
10
9
  import { buildPortProxyRouter, buildProxyRouter, maintenanceMiddleware } from './conf.js';
10
+ import UnderpostStartUp from './start.js';
11
11
 
12
12
  dotenv.config();
13
13
 
@@ -71,11 +71,11 @@ const buildProxy = async () => {
71
71
  switch (port) {
72
72
  case 443:
73
73
  const { ServerSSL } = await createSslServer(app, hosts);
74
- await listenPortController(ServerSSL, port, runningData);
74
+ await UnderpostStartUp.API.listenPortController(ServerSSL, port, runningData);
75
75
  break;
76
76
 
77
77
  default:
78
- await listenPortController(app, port, runningData);
78
+ await UnderpostStartUp.API.listenPortController(app, port, runningData);
79
79
 
80
80
  break;
81
81
  }
@@ -83,7 +83,7 @@ const buildProxy = async () => {
83
83
  break;
84
84
 
85
85
  default:
86
- await listenPortController(app, port, runningData);
86
+ await UnderpostStartUp.API.listenPortController(app, port, runningData);
87
87
 
88
88
  break;
89
89
  }
@@ -9,7 +9,7 @@ import compression from 'compression';
9
9
 
10
10
  import { createServer } from 'http';
11
11
  import { getRootDirectory } from './process.js';
12
- import { listenPortController, saveRuntimeRouter, logRuntimeRouter, listenServerFactory } from './network.js';
12
+ import UnderpostStartUp from './start.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';
@@ -21,6 +21,7 @@ import { Lampp } from '../runtime/lampp/Lampp.js';
21
21
  import { getDeployId } from './conf.js';
22
22
  import { JSONweb, ssrFactory } from './client-formatted.js';
23
23
  import Underpost from '../index.js';
24
+ import { createValkeyConnection } from './valkey.js';
24
25
 
25
26
  dotenv.config();
26
27
 
@@ -41,7 +42,6 @@ const buildRuntime = async () => {
41
42
  // logger.info('promCounterOption', promCounterOption);
42
43
 
43
44
  const requestCounter = new promClient.Counter(promCounterOption);
44
- const ipInstance = ''; // await ip.public.ipv4();
45
45
  const initPort = parseInt(process.env.PORT) + 1;
46
46
  let currentPort = initPort;
47
47
  const confServer = JSON.parse(fs.readFileSync(`./conf/conf.server.json`, 'utf8'));
@@ -68,6 +68,7 @@ const buildRuntime = async () => {
68
68
  peer,
69
69
  singleReplica,
70
70
  replicas,
71
+ valkey,
71
72
  } = confServer[host][path];
72
73
 
73
74
  if (singleReplica && replicas && replicas.length > 0 && !singleReplicaHosts.includes(host)) {
@@ -183,7 +184,11 @@ const buildRuntime = async () => {
183
184
  // RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
184
185
  // RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
185
186
 
186
- await listenPortController(listenServerFactory(), port, runningData);
187
+ await UnderpostStartUp.API.listenPortController(
188
+ UnderpostStartUp.API.listenServerFactory(),
189
+ port,
190
+ runningData,
191
+ );
187
192
  break;
188
193
  case 'xampp':
189
194
  if (!Xampp.enabled()) continue;
@@ -230,7 +235,11 @@ const buildRuntime = async () => {
230
235
  // if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
231
236
  // $_SERVER['HTTPS'] = 'on';
232
237
  // }
233
- await listenPortController(listenServerFactory(), port, runningData);
238
+ await UnderpostStartUp.API.listenPortController(
239
+ UnderpostStartUp.API.listenServerFactory(),
240
+ port,
241
+ runningData,
242
+ );
234
243
  break;
235
244
  case 'nodejs':
236
245
  const app = express();
@@ -283,7 +292,7 @@ const buildRuntime = async () => {
283
292
  currentPort += 2;
284
293
  const staticPort = newInstance(currentPort);
285
294
 
286
- await listenPortController(app, staticPort, runningData);
295
+ await UnderpostStartUp.API.listenPortController(app, staticPort, runningData);
287
296
  currentPort++;
288
297
  continue;
289
298
  }
@@ -334,7 +343,7 @@ const buildRuntime = async () => {
334
343
  // }),
335
344
  // );
336
345
 
337
- await listenPortController(app, port, runningData);
346
+ await UnderpostStartUp.API.listenPortController(app, port, runningData);
338
347
  break;
339
348
  }
340
349
 
@@ -354,6 +363,9 @@ const buildRuntime = async () => {
354
363
 
355
364
  if (db && apis) await DataBaseProvider.load({ apis, host, path, db });
356
365
 
366
+ // valkey server
367
+ await createValkeyConnection({ host, path }, valkey);
368
+
357
369
  if (mailer) {
358
370
  const mailerSsrConf = confSSR[getCapVariableName(client)];
359
371
  await MailerProvider.load({
@@ -442,7 +454,7 @@ const buildRuntime = async () => {
442
454
  port,
443
455
  origins,
444
456
  });
445
- await listenPortController(listenServerFactory(), port, {
457
+ await UnderpostStartUp.API.listenPortController(UnderpostStartUp.API.listenServerFactory(), port, {
446
458
  runtime: 'nodejs',
447
459
  client: null,
448
460
  host,
@@ -462,7 +474,7 @@ const buildRuntime = async () => {
462
474
  path,
463
475
  });
464
476
 
465
- await listenPortController(peerServer, peerPort, {
477
+ await UnderpostStartUp.API.listenPortController(peerServer, peerPort, {
466
478
  runtime: 'nodejs',
467
479
  client: null,
468
480
  host,
@@ -471,7 +483,7 @@ const buildRuntime = async () => {
471
483
  });
472
484
  }
473
485
 
474
- await listenPortController(server, port, runningData);
486
+ await UnderpostStartUp.API.listenPortController(server, port, runningData);
475
487
 
476
488
  break;
477
489
  default:
@@ -484,8 +496,7 @@ const buildRuntime = async () => {
484
496
  if (Xampp.enabled() && Xampp.router) Xampp.initService();
485
497
  if (Lampp.enabled() && Lampp.router) Lampp.initService();
486
498
 
487
- saveRuntimeRouter();
488
- logRuntimeRouter();
499
+ UnderpostStartUp.API.logRuntimeRouter();
489
500
  };
490
501
 
491
502
  export { buildRuntime };
@@ -0,0 +1,123 @@
1
+ import UnderpostDeploy from '../cli/deploy.js';
2
+ import UnderpostMonitor from '../cli/monitor.js';
3
+ import fs from 'fs-extra';
4
+ import { awaitDeployMonitor } from './conf.js';
5
+ import { actionInitLog, loggerFactory } from './logger.js';
6
+ import { shellCd, shellExec } from './process.js';
7
+ import UnderpostRootEnv from '../cli/env.js';
8
+
9
+ const logger = loggerFactory(import.meta);
10
+
11
+ class UnderpostStartUp {
12
+ static API = {
13
+ logRuntimeRouter: () => {
14
+ const displayLog = {};
15
+
16
+ for (const host of Object.keys(UnderpostDeploy.NETWORK))
17
+ for (const path of Object.keys(UnderpostDeploy.NETWORK[host]))
18
+ displayLog[UnderpostDeploy.NETWORK[host][path].publicHost] = UnderpostDeploy.NETWORK[host][path].local;
19
+
20
+ logger.info('Runtime network', displayLog);
21
+ },
22
+ listenServerFactory: (logic = async () => {}) => {
23
+ return {
24
+ listen: async (...args) => {
25
+ const msDelta = 1000;
26
+ const msMax = 30 * 24 * 60 * 60 * 1000; // ~ 1 month
27
+ let msCount = 0;
28
+ setInterval(() => {
29
+ msCount += msDelta;
30
+ if (msCount >= msMax) {
31
+ const message = 'Listen server factory timeout';
32
+ logger.error(message);
33
+ throw new Error(message);
34
+ }
35
+ }, msDelta);
36
+ return logic ? await logic(...args) : undefined, args[1]();
37
+ },
38
+ };
39
+ },
40
+ listenPortController: async (server, port, metadata) =>
41
+ new Promise((resolve) => {
42
+ try {
43
+ if (port === ':') {
44
+ server.listen(port, actionInitLog);
45
+ return resolve(true);
46
+ }
47
+
48
+ const { host, path, client, runtime, meta } = metadata;
49
+ const error = [];
50
+ if (port === undefined) error.push(`port`);
51
+ if (host === undefined) error.push(`host`);
52
+ if (path === undefined) error.push(`path`);
53
+ if (client === undefined) error.push(`client`);
54
+ if (runtime === undefined) error.push(`runtime`);
55
+ if (meta === undefined) error.push(`meta`);
56
+ if (error.length > 0) throw new Error('Listen port controller requires values: ' + error.join(', '));
57
+
58
+ server.listen(port, () => {
59
+ if (!UnderpostDeploy.NETWORK[host]) UnderpostDeploy.NETWORK[host] = {};
60
+ UnderpostDeploy.NETWORK[host][path] = {
61
+ meta,
62
+ client,
63
+ runtime,
64
+ port,
65
+ publicHost:
66
+ port === 80
67
+ ? `http://${host}${path}`
68
+ : port === 443
69
+ ? `https://${host}${path}`
70
+ : `http://${host}:${port}${path}`,
71
+ local: `http://localhost:${port}${path}`,
72
+ apis: metadata.apis,
73
+ };
74
+
75
+ return resolve(true);
76
+ });
77
+ } catch (error) {
78
+ logger.error(error, { metadata, port, stack: error.stack });
79
+ resolve(false);
80
+ }
81
+ }),
82
+
83
+ async callback(deployId = 'default', env = 'development', options = { build: false, run: false }) {
84
+ if (options.build === true) await UnderpostStartUp.API.build(deployId, env);
85
+ if (options.run === true) await UnderpostStartUp.API.run(deployId, env);
86
+ },
87
+ async build(deployId = 'default', env = 'development') {
88
+ const buildBasePath = `/home/dd`;
89
+ const repoName = `engine-${deployId.split('-')[1]}`;
90
+ shellExec(`cd ${buildBasePath} && underpost clone underpostnet/${repoName}`);
91
+ shellExec(`cd ${buildBasePath} && sudo mv ./${repoName} ./engine`);
92
+ shellExec(`cd ${buildBasePath}/engine && underpost clone underpostnet/${repoName}-private`);
93
+ shellExec(`cd ${buildBasePath}/engine && sudo mv ./${repoName}-private ./engine-private`);
94
+ shellCd(`${buildBasePath}/engine`);
95
+ shellExec(`npm install`);
96
+ shellExec(`node bin/deploy conf ${deployId} ${env}`);
97
+ if (fs.existsSync('./engine-private/itc-scripts')) {
98
+ const itcScripts = await fs.readdir('./engine-private/itc-scripts');
99
+ for (const itcScript of itcScripts)
100
+ if (itcScript.match(deployId)) shellExec(`node ./engine-private/itc-scripts/${itcScript}`);
101
+ }
102
+ shellExec(`node bin/deploy build-full-client ${deployId}`);
103
+ },
104
+ async run(deployId = 'default', env = 'development') {
105
+ const runCmd = env === 'production' ? 'run prod-img' : 'run dev-img';
106
+ if (fs.existsSync(`./engine-private/replica`)) {
107
+ const replicas = await fs.readdir(`./engine-private/replica`);
108
+ for (const replica of replicas) {
109
+ if (!replica.match(deployId)) continue;
110
+ shellExec(`node bin/deploy conf ${replica} ${env}`);
111
+ shellExec(`npm ${runCmd} deploy deploy-id:${replica}`, { async: true });
112
+ await awaitDeployMonitor(true);
113
+ }
114
+ }
115
+ shellExec(`node bin/deploy conf ${deployId} ${env}`);
116
+ shellExec(`npm ${runCmd} deploy deploy-id:${deployId}`, { async: true });
117
+ await awaitDeployMonitor(true);
118
+ UnderpostRootEnv.API.set('container-status', `${deployId}-${env}-running-deployment`);
119
+ },
120
+ };
121
+ }
122
+
123
+ export default UnderpostStartUp;
@@ -5,12 +5,24 @@ import { loggerFactory } from './logger.js';
5
5
 
6
6
  const logger = loggerFactory(import.meta);
7
7
 
8
+ const ValkeyInstances = {};
9
+
8
10
  let valkeyEnabled = true;
9
11
 
10
12
  const disableValkeyErrorMessage = 'valkey is not enabled';
11
13
 
12
14
  const isValkeyEnable = () => valkeyEnabled;
13
15
 
16
+ const createValkeyConnection = async (
17
+ instance = { host: '', port: 0 },
18
+ valkeyServerConnectionOptions = { host: '', port: 0 },
19
+ ) => {
20
+ ValkeyInstances[`${instance.host}${instance.path}`] = await ValkeyAPI.valkeyClientFactory(
21
+ valkeyServerConnectionOptions,
22
+ );
23
+ return ValkeyInstances[`${instance.host}${instance.path}`];
24
+ };
25
+
14
26
  const selectDtoFactory = (payload, select) => {
15
27
  const result = {};
16
28
  for (const key of Object.keys(select)) {
@@ -19,10 +31,12 @@ const selectDtoFactory = (payload, select) => {
19
31
  return result;
20
32
  };
21
33
 
22
- const valkeyClientFactory = async () => {
34
+ const valkeyClientFactory = async (options) => {
23
35
  const valkey = new Valkey({
24
36
  // port: 6379,
25
37
  // host: 'service-valkey.default.svc.cluster.local',
38
+ port: options?.port ? options.port : undefined,
39
+ host: options?.port ? options.host : undefined,
26
40
  retryStrategy: (attempt) => {
27
41
  if (attempt === 1) {
28
42
  valkey.disconnect();
@@ -46,12 +60,12 @@ const valkeyClientFactory = async () => {
46
60
  return valkey;
47
61
  };
48
62
 
49
- const getValkeyObject = async (key = '') => {
63
+ const getValkeyObject = async (options = { host: '', port: 0 }, key = '') => {
50
64
  if (!valkeyEnabled) {
51
65
  logger.warn(disableValkeyErrorMessage + ' get', key);
52
66
  return null;
53
67
  }
54
- const object = await valkey.get(key);
68
+ const object = await ValkeyInstances[`${options.host}${options.path}`].get(key);
55
69
  try {
56
70
  return JSON.parse(object);
57
71
  } catch (error) {
@@ -60,19 +74,19 @@ const getValkeyObject = async (key = '') => {
60
74
  }
61
75
  };
62
76
 
63
- const setValkeyObject = async (key = '', payload = {}) => {
77
+ const setValkeyObject = async (options = { host: '', port: 0 }, key = '', payload = {}) => {
64
78
  if (!valkeyEnabled) throw new Error(disableValkeyErrorMessage);
65
- return await valkey.set(key, JSON.stringify(payload));
79
+ return await ValkeyInstances[`${options.host}${options.path}`].set(key, JSON.stringify(payload));
66
80
  };
67
81
 
68
- const updateValkeyObject = async (key = '', payload = {}) => {
82
+ const updateValkeyObject = async (options = { host: '', port: 0 }, key = '', payload = {}) => {
69
83
  if (!valkeyEnabled) throw new Error(disableValkeyErrorMessage);
70
- const object = await getValkeyObject(key, valkey);
84
+ const object = await getValkeyObject(key);
71
85
  object.updatedAt = new Date().toISOString();
72
- return await valkey.set(key, JSON.stringify({ ...object, ...payload }));
86
+ return await ValkeyInstances[`${options.host}${options.path}`].set(key, JSON.stringify({ ...object, ...payload }));
73
87
  };
74
88
 
75
- const valkeyObjectFactory = async (module = '', options = { host: 'localhost', object: {} }) => {
89
+ const valkeyObjectFactory = async (options = { host: 'localhost', object: {} }, module = '') => {
76
90
  if (!valkeyEnabled) throw new Error(disableValkeyErrorMessage);
77
91
  const idoDate = new Date().toISOString();
78
92
  options.object = options.object || {};
@@ -112,10 +126,9 @@ const ValkeyAPI = {
112
126
  setValkeyObject,
113
127
  valkeyObjectFactory,
114
128
  updateValkeyObject,
129
+ createValkeyConnection,
115
130
  };
116
131
 
117
- const valkey = await ValkeyAPI.valkeyClientFactory();
118
-
119
132
  export {
120
133
  valkeyClientFactory,
121
134
  selectDtoFactory,
@@ -124,5 +137,6 @@ export {
124
137
  valkeyObjectFactory,
125
138
  updateValkeyObject,
126
139
  isValkeyEnable,
140
+ createValkeyConnection,
127
141
  ValkeyAPI,
128
142
  };