@underpostnet/underpost 2.8.0 → 2.8.31

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 (74) hide show
  1. package/.dockerignore +1 -0
  2. package/.github/workflows/ghpkg.yml +4 -4
  3. package/.vscode/extensions.json +8 -71
  4. package/.vscode/settings.json +2 -1
  5. package/CHANGELOG.md +55 -3
  6. package/Dockerfile +22 -36
  7. package/README.md +0 -27
  8. package/bin/deploy.js +54 -28
  9. package/bin/file.js +30 -2
  10. package/bin/index.js +6 -18
  11. package/bin/ssl.js +19 -11
  12. package/bin/util.js +18 -0
  13. package/bin/vs.js +3 -2
  14. package/conf.js +17 -1
  15. package/docker-compose.yml +1 -1
  16. package/manifests/mariadb/config.yaml +10 -0
  17. package/manifests/mariadb/kustomization.yaml +9 -0
  18. package/manifests/mariadb/pv.yaml +12 -0
  19. package/manifests/mariadb/pvc.yaml +10 -0
  20. package/manifests/mariadb/secret.yaml +8 -0
  21. package/manifests/mariadb/service.yaml +10 -0
  22. package/manifests/mariadb/statefulset.yaml +55 -0
  23. package/manifests/test/mongo-express.yaml +60 -0
  24. package/manifests/test/phpmyadmin.yaml +54 -0
  25. package/manifests/test/underpost-engine-mongodb-configmap.yaml +26 -0
  26. package/manifests/test/underpost-engine-pod.yaml +108 -0
  27. package/manifests/underpost-engine-backup-access.yaml +16 -0
  28. package/manifests/underpost-engine-backup-pv-pvc.yaml +22 -0
  29. package/manifests/underpost-engine-headless-service.yaml +10 -0
  30. package/manifests/underpost-engine-mongodb-backup-cronjob.yaml +40 -0
  31. package/manifests/underpost-engine-pv-pvc.yaml +23 -0
  32. package/manifests/underpost-engine-statefulset.yaml +91 -0
  33. package/manifests/valkey/kustomization.yaml +7 -0
  34. package/manifests/valkey/underpost-engine-valkey-service.yaml +17 -0
  35. package/manifests/valkey/underpost-engine-valkey-statefulset.yaml +39 -0
  36. package/package.json +22 -12
  37. package/src/api/user/user.model.js +9 -1
  38. package/src/api/user/user.service.js +1 -1
  39. package/src/client/components/core/Account.js +4 -2
  40. package/src/client/components/core/Auth.js +2 -2
  41. package/src/client/components/core/CalendarCore.js +112 -49
  42. package/src/client/components/core/CommonJs.js +125 -19
  43. package/src/client/components/core/Css.js +1 -1
  44. package/src/client/components/core/CssCore.js +6 -0
  45. package/src/client/components/core/Docs.js +2 -1
  46. package/src/client/components/core/DropDown.js +5 -1
  47. package/src/client/components/core/Input.js +17 -3
  48. package/src/client/components/core/JoyStick.js +8 -5
  49. package/src/client/components/core/Modal.js +12 -6
  50. package/src/client/components/core/Panel.js +82 -24
  51. package/src/client/components/core/PanelForm.js +11 -19
  52. package/src/client/components/core/SignUp.js +4 -1
  53. package/src/client/components/core/Translate.js +44 -8
  54. package/src/client/public/default/plantuml/client-conf.svg +1 -1
  55. package/src/client/public/default/plantuml/server-conf.svg +1 -1
  56. package/src/client/public/default/plantuml/server-schema.svg +1 -1
  57. package/src/client/public/default/plantuml/ssr-conf.svg +1 -1
  58. package/src/client/public/default/plantuml/ssr-schema.svg +1 -1
  59. package/src/client/services/core/core.service.js +2 -0
  60. package/src/client/ssr/body/CacheControl.js +2 -1
  61. package/src/client/ssr/body/DefaultSplashScreen.js +3 -3
  62. package/src/client/ssr/offline/Maintenance.js +63 -0
  63. package/src/client/sw/default.sw.js +23 -3
  64. package/src/db/mongo/MongooseDB.js +13 -1
  65. package/src/index.js +8 -0
  66. package/src/server/client-build.js +5 -4
  67. package/src/server/client-icons.js +1 -1
  68. package/src/server/conf.js +5 -5
  69. package/src/server/logger.js +8 -6
  70. package/src/server/process.js +25 -2
  71. package/src/server/ssl.js +1 -1
  72. package/src/server/valkey.js +3 -0
  73. package/startup.cjs +12 -0
  74. package/startup.js +0 -11
@@ -62,15 +62,35 @@ self.addEventListener('fetch', (event) => {
62
62
  if (!preCachedResponse) throw new Error(error.message);
63
63
  return preCachedResponse;
64
64
  } catch (error) {
65
- console.error('Error opening cache for pre cached page', event.request.url, error);
65
+ console.error('Error opening cache for pre cached page', {
66
+ url: event.request.url,
67
+ error,
68
+ onLine: navigator.onLine,
69
+ });
66
70
  try {
71
+ if (!navigator.onLine) {
72
+ if (event.request.method.toUpperCase() === 'GET') {
73
+ const cache = await caches.open(CACHE_NAME);
74
+ const preCachedResponse = await cache.match(
75
+ `${PROXY_PATH === '/' ? '' : PROXY_PATH}/offline/index.html`,
76
+ );
77
+ if (!preCachedResponse) throw new Error(error.message);
78
+ return preCachedResponse;
79
+ }
80
+ const response = new Response(JSON.stringify({ status: 'error', message: 'offline test response' }));
81
+ // response.status = 200;
82
+ response.headers.set('Content-Type', 'application/json');
83
+ return response;
84
+ }
67
85
  if (event.request.method.toUpperCase() === 'GET') {
68
86
  const cache = await caches.open(CACHE_NAME);
69
- const preCachedResponse = await cache.match(`${PROXY_PATH === '/' ? '' : PROXY_PATH}/offline/index.html`);
87
+ const preCachedResponse = await cache.match(
88
+ `${PROXY_PATH === '/' ? '' : PROXY_PATH}/maintenance/index.html`,
89
+ );
70
90
  if (!preCachedResponse) throw new Error(error.message);
71
91
  return preCachedResponse;
72
92
  }
73
- const response = new Response(JSON.stringify({ status: 'error', message: 'offline test response' }));
93
+ const response = new Response(JSON.stringify({ status: 'error', message: 'server in maintenance' }));
74
94
  // response.status = 200;
75
95
  response.headers.set('Content-Type', 'application/json');
76
96
  return response;
@@ -9,7 +9,12 @@ const MongooseDB = {
9
9
  connect: async (host, name) => {
10
10
  const uri = `${host}/${name}`;
11
11
  // logger.info('MongooseDB connect', { host, name, uri });
12
- return await mongoose.createConnection(uri).asPromise();
12
+ return await mongoose
13
+ .createConnection(uri, {
14
+ // useNewUrlParser: true,
15
+ // useUnifiedTopology: true,
16
+ })
17
+ .asPromise();
13
18
  return new Promise((resolve, reject) =>
14
19
  mongoose
15
20
  .connect(
@@ -67,8 +72,15 @@ const MongooseDB = {
67
72
  shellExec(`sudo rm -r /var/lib/mongodb`);
68
73
  // restore lib
69
74
  // shellExec(`sudo chown -R mongodb:mongodb /var/lib/mongodb/*`);
75
+ // mongod --repair
70
76
 
71
77
  if (process.argv.includes('legacy')) {
78
+ // TODO:
79
+ if (process.argv.includes('rocky')) {
80
+ // https://github.com/mongodb/mongodb-selinux
81
+ // https://www.mongodb.com/docs/v7.0/tutorial/install-mongodb-enterprise-on-red-hat/
82
+ shellExec(`sudo chown -R mongod:mongod /var/lib/mongo`);
83
+ }
72
84
  logger.info('install legacy 4.4');
73
85
  shellExec(`wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -`);
74
86
 
package/src/index.js CHANGED
@@ -14,6 +14,14 @@ const logger = loggerFactory(import.meta);
14
14
  * @memberof Underpost
15
15
  */
16
16
  class Underpost {
17
+ /**
18
+ * Underpost engine version
19
+ * @static
20
+ * @type {String}
21
+ * @memberof Underpost
22
+ */
23
+ static version = 'v2.8.31';
24
+
17
25
  constructor() {}
18
26
 
19
27
  /**
@@ -465,10 +465,11 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
465
465
  case 'DefaultSplashScreen':
466
466
  if (backgroundImage) {
467
467
  ssrHeadComponents += SrrComponent({
468
- base64BackgroundImage: `data:image/${backgroundImage.split('.').pop()};base64,${fs
469
- .readFileSync(backgroundImage)
470
- .toString('base64')}`,
468
+ backgroundImage: (path === '/' ? path : `${path}/`) + backgroundImage,
471
469
  });
470
+ // `data:image/${backgroundImage.split('.').pop()};base64,${fs
471
+ // .readFileSync()
472
+ // .toString('base64')}`,
472
473
  break;
473
474
  } else {
474
475
  ssrHeadComponents += SrrComponent({ metadata });
@@ -480,7 +481,7 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
480
481
  bgColor: metadata?.themeColor ? metadata.themeColor : '#ececec',
481
482
  });
482
483
  ssrHeadComponents += SrrComponent({
483
- base64BackgroundImage: `data:image/png;base64,${bufferBackgroundImage.toString('base64')}`,
484
+ backgroundImage: `data:image/png;base64,${bufferBackgroundImage.toString('base64')}`,
484
485
  });
485
486
  }
486
487
 
@@ -141,7 +141,7 @@ const buildIcons = async ({
141
141
  for (const file of response.files)
142
142
  fs.writeFileSync(`./src/client/public/${publicClientId}/${file.name}`, file.contents, 'utf8');
143
143
 
144
- const ssrPath = `./src/client/ssr/components/head/Pwa${getCapVariableName(publicClientId)}.js`;
144
+ const ssrPath = `./src/client/ssr/head/Pwa${getCapVariableName(publicClientId)}.js`;
145
145
  if (!fs.existsSync(ssrPath))
146
146
  fs.writeFileSync(ssrPath, 'SrrComponent = () => html`' + response.html.join(`\n`) + '`;', 'utf8');
147
147
  } catch (error) {
@@ -9,7 +9,6 @@ import colors from 'colors';
9
9
  import { loggerFactory } from './logger.js';
10
10
  import { shellExec } from './process.js';
11
11
  import { DefaultConf } from '../../conf.js';
12
- import ncp from 'copy-paste';
13
12
  import read from 'read';
14
13
  import splitFile from 'split-file';
15
14
  import axios from 'axios';
@@ -253,8 +252,8 @@ const buildClientSrc = async (
253
252
  }
254
253
 
255
254
  fs.writeFileSync(
256
- `./src/client/ssr/components/head/${toClientVariableName}Scripts.js`,
257
- formattedSrc(fs.readFileSync(`./src/client/ssr/components/head/${fromClientVariableName}Scripts.js`, 'utf8')),
255
+ `./src/client/ssr/head/${toClientVariableName}Scripts.js`,
256
+ formattedSrc(fs.readFileSync(`./src/client/ssr/head/${fromClientVariableName}Scripts.js`, 'utf8')),
258
257
  'utf8',
259
258
  );
260
259
 
@@ -473,7 +472,7 @@ const buildProxyRouter = () => {
473
472
  title: 'Site in maintenance',
474
473
  ssrPath: '/',
475
474
  ssrHeadComponents: '',
476
- ssrBodyComponents: (await ssrFactory(`./src/client/ssr/body/Maintenance.js`))(),
475
+ ssrBodyComponents: (await ssrFactory(`./src/client/ssr/offline/Maintenance.js`))(),
477
476
  });
478
477
  })();
479
478
 
@@ -770,9 +769,10 @@ const deployRun = async (dataDeploy, currentAttempt = 1) => {
770
769
  } else logger.info(`Deploy process successfully`);
771
770
  };
772
771
 
773
- const restoreMacroDb = async (deployGroupId = '') => {
772
+ const restoreMacroDb = async (deployGroupId = '', deployId = null) => {
774
773
  const dataDeploy = await getDataDeploy({ deployGroupId, buildSingleReplica: false });
775
774
  for (const deployGroup of dataDeploy) {
775
+ if (deployId && deployGroup.deployId !== deployId) continue;
776
776
  if (!deployGroup.replicaHost) {
777
777
  const deployServerConfPath = `./engine-private/conf/${deployGroup.deployId}/conf.server.json`;
778
778
  const serverConf = JSON.parse(fs.readFileSync(deployServerConfPath, 'utf8'));
@@ -86,6 +86,7 @@ const format = (meta) =>
86
86
  * @memberof Logger
87
87
  */
88
88
  const setUpInfo = async (logger = new winston.Logger()) => {
89
+ logger.info('npm_package_version', process.env.npm_package_version);
89
90
  logger.info('argv', process.argv);
90
91
  logger.info('platform', process.platform);
91
92
  logger.info('env', process.env.NODE_ENV);
@@ -179,12 +180,13 @@ const loggerMiddleware = (meta = { url: '' }) => {
179
180
  };
180
181
 
181
182
  const underpostASCI = () => `
182
- ▗▖ ▗▖▗▖ ▗▖▗▄▄▄ ▗▄▄▄▖▗▄▄▖ ▄▄▄▄ ▄▄▄ ▄▄▄ ■
183
- ▐▌ ▐▌▐▛▚▖▐▌▐▌ █ ▐▌ ▐▌ ▐▌█ █ █ █ ▀▄▄▗▄▟▙▄▖
184
- ▐▌ ▐▌▐▌ ▝▜▌▐▌ █ ▐▛▀▀▘▐▛▀▚▖█▄▄▄▀ ▀▄▄▄▀ ▄▄▄▀ ▐▌
185
- ▝▚▄▞▘▐▌ ▐▌▐▙▄▄▀ ▐▙▄▄▖▐▌ ▐▌█ ▐▌
186
- ▀ ▐▌
187
-
183
+
184
+ ██╗░░░██╗███╗░░██╗██████╗░███████╗██████╗░██████╗░░█████╗░░██████╗████████╗
185
+ ██║░░░██║████╗░██║██╔══██╗██╔════╝██╔══██╗██╔══██╗██╔══██╗██╔════╝╚══██╔══╝
186
+ ██║░░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██████╔╝██║░░██║╚█████╗░░░░██║░░░
187
+ ██║░░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██╔═══╝░██║░░██║░╚═══██╗░░░██║░░░
188
+ ╚██████╔╝██║░╚███║██████╔╝███████╗██║░░██║██║░░░░░╚█████╔╝██████╔╝░░░██║░░░
189
+ ░╚═════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚═╝░░░░░░╚════╝░╚═════╝░░░░╚═╝░░░
188
190
  `;
189
191
 
190
192
  export { loggerFactory, loggerMiddleware, setUpInfo, underpostASCI };
@@ -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 };
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();
@@ -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/startup.cjs ADDED
@@ -0,0 +1,12 @@
1
+ const shell = require('shelljs');
2
+
3
+ // /usr/bin/supervisord -n
4
+ // /usr/sbin/sshd -D
5
+
6
+ shell.exec(`/usr/bin/supervisord -n`, { async: true });
7
+
8
+ // shell.exec(`sudo /opt/lampp/lampp start`, { async: true });
9
+
10
+ // shell.exec(`/usr/bin/mongod -f /etc/mongod.conf`, { async: true });
11
+
12
+ shell.exec(`underpost new app`);
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`);