@underpostnet/underpost 2.8.4 → 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 (61) hide show
  1. package/.github/workflows/ghpkg.yml +13 -46
  2. package/.github/workflows/npmpkg.yml +67 -0
  3. package/.github/workflows/publish.yml +5 -5
  4. package/.github/workflows/pwa-microservices-template.page.yml +3 -2
  5. package/.github/workflows/pwa-microservices-template.test.yml +2 -2
  6. package/.vscode/settings.json +6 -1
  7. package/CHANGELOG.md +16 -0
  8. package/Dockerfile +6 -27
  9. package/bin/build.js +52 -169
  10. package/bin/deploy.js +6 -27
  11. package/bin/file.js +29 -15
  12. package/bin/index.js +158 -30
  13. package/bin/util.js +0 -8
  14. package/docker-compose.yml +1 -1
  15. package/manifests/mongodb/backup-access.yaml +16 -0
  16. package/manifests/mongodb/backup-cronjob.yaml +42 -0
  17. package/manifests/mongodb/backup-pv-pvc.yaml +22 -0
  18. package/manifests/mongodb/configmap.yaml +26 -0
  19. package/manifests/mongodb/headless-service.yaml +10 -0
  20. package/manifests/mongodb/kustomization.yaml +11 -0
  21. package/manifests/mongodb/pv-pvc.yaml +23 -0
  22. package/manifests/mongodb/statefulset.yaml +125 -0
  23. package/manifests/valkey/kustomization.yaml +2 -2
  24. package/manifests/valkey/service.yaml +17 -0
  25. package/manifests/valkey/statefulset.yaml +39 -0
  26. package/package.json +21 -5
  27. package/src/api/core/core.service.js +1 -1
  28. package/src/cli/cluster.js +154 -0
  29. package/src/cli/cron.js +90 -0
  30. package/src/cli/db.js +148 -0
  31. package/src/cli/deploy.js +277 -0
  32. package/src/cli/env.js +52 -0
  33. package/src/cli/image.js +125 -0
  34. package/src/cli/repository.js +104 -0
  35. package/src/cli/script.js +29 -0
  36. package/src/cli/secrets.js +37 -0
  37. package/src/cli/test.js +83 -0
  38. package/src/client/components/core/Auth.js +22 -4
  39. package/src/client/components/core/CommonJs.js +82 -1
  40. package/src/client/components/core/Css.js +1 -0
  41. package/src/client/components/core/Input.js +1 -1
  42. package/src/client/components/core/Modal.js +0 -1
  43. package/src/client/components/core/Scroll.js +1 -0
  44. package/src/client/components/core/Translate.js +4 -0
  45. package/src/client/components/core/VanillaJs.js +0 -9
  46. package/src/client/components/core/Worker.js +34 -31
  47. package/src/client/ssr/body/CacheControl.js +2 -2
  48. package/src/index.js +77 -26
  49. package/src/server/backup.js +49 -93
  50. package/src/server/client-build.js +1 -10
  51. package/src/server/client-formatted.js +5 -3
  52. package/src/server/conf.js +68 -187
  53. package/src/server/dns.js +48 -65
  54. package/src/server/logger.js +7 -7
  55. package/src/server/network.js +17 -7
  56. package/src/server/runtime.js +8 -22
  57. package/src/dns.js +0 -22
  58. package/src/server/project.js +0 -39
  59. package/startup.cjs +0 -12
  60. /package/manifests/deployment/{mongo-express.yaml → mongo-express/deployment.yaml} +0 -0
  61. /package/manifests/deployment/{phpmyadmin.yaml → phpmyadmin/deployment.yaml} +0 -0
@@ -0,0 +1,83 @@
1
+ import { MariaDB } from '../db/mariadb/MariaDB.js';
2
+ import { getNpmRootPath } from '../server/conf.js';
3
+ import { actionInitLog, loggerFactory, setUpInfo } from '../server/logger.js';
4
+ import { pbcopy, shellExec } from '../server/process.js';
5
+ import UnderpostDeploy from './deploy.js';
6
+
7
+ const logger = loggerFactory(import.meta);
8
+
9
+ class UnderpostTest {
10
+ static API = {
11
+ /**
12
+ * Logs information about the current process environment to the console.
13
+ *
14
+ * This function is used to log details about
15
+ * the execution context, such as command-line arguments,
16
+ * environment variables, the process's administrative privileges,
17
+ * and the maximum available heap space size.
18
+ *
19
+ * @static
20
+ * @method setUpInfo
21
+ * @returns {Promise<void>}
22
+ * @memberof Underpost
23
+ */
24
+ async setUpInfo() {
25
+ return await setUpInfo(logger);
26
+ },
27
+ run() {
28
+ actionInitLog();
29
+ shellExec(`cd ${getNpmRootPath()}/underpost && npm run test`);
30
+ },
31
+ async callback(deployList = '', options = { insideContainer: false, sh: false, logs: false }) {
32
+ if (options.sh === true || options.logs === true) {
33
+ const [pod] = UnderpostDeploy.API.getPods(deployList);
34
+ if (pod) {
35
+ if (options.sh) return pbcopy(`sudo kubectl exec -it ${pod.NAME} -- sh`);
36
+ if (options.logs) return shellExec(`sudo kubectl logs -f ${pod.NAME}`);
37
+ }
38
+ return logger.warn(`Couldn't find pods in deployment`, deployList);
39
+ }
40
+ if (deployList) {
41
+ for (const _deployId of deployList.split(',')) {
42
+ const deployId = _deployId.trim();
43
+ if (!deployId) continue;
44
+ if (options.insideContainer === true)
45
+ switch (deployId) {
46
+ case 'dd-lampp':
47
+ {
48
+ const { MARIADB_HOST, MARIADB_USER, MARIADB_PASSWORD, DD_LAMPP_TEST_DB_0 } = process.env;
49
+
50
+ await MariaDB.query({
51
+ host: MARIADB_HOST,
52
+ user: MARIADB_USER,
53
+ password: MARIADB_PASSWORD,
54
+ query: `SHOW TABLES FROM ${DD_LAMPP_TEST_DB_0}`,
55
+ });
56
+ }
57
+ break;
58
+
59
+ default:
60
+ {
61
+ shellExec('npm run test');
62
+ }
63
+
64
+ break;
65
+ }
66
+ else {
67
+ const pods = UnderpostDeploy.API.getPods(deployId);
68
+ if (pods.length > 0)
69
+ for (const deployData of pods) {
70
+ const { NAME } = deployData;
71
+ shellExec(
72
+ `sudo kubectl exec -i ${NAME} -- sh -c "cd /home/dd/engine && underpost test ${deployId} --inside-container"`,
73
+ );
74
+ }
75
+ else logger.warn(`Couldn't find pods in deployment`, { deployId });
76
+ }
77
+ }
78
+ } else return UnderpostTest.API.run();
79
+ },
80
+ };
81
+ }
82
+
83
+ export default UnderpostTest;
@@ -3,7 +3,10 @@ import { Account } from './Account.js';
3
3
  import { loggerFactory } from './Logger.js';
4
4
  import { LogIn } from './LogIn.js';
5
5
  import { LogOut } from './LogOut.js';
6
+ import { NotificationManager } from './NotificationManager.js';
6
7
  import { SignUp } from './SignUp.js';
8
+ import { Translate } from './Translate.js';
9
+ import { s } from './VanillaJs.js';
7
10
 
8
11
  const logger = loggerFactory(import.meta);
9
12
 
@@ -65,6 +68,7 @@ const Auth = {
65
68
  const _result = await UserService.get({ id: 'auth' });
66
69
  return {
67
70
  status: _result.status,
71
+ message: _result.message,
68
72
  data: {
69
73
  user: _result.data,
70
74
  },
@@ -77,6 +81,15 @@ const Auth = {
77
81
  await Account.updateForm(data.user);
78
82
  return { user: data.user };
79
83
  }
84
+ if (message && message.match('expired'))
85
+ setTimeout(() => {
86
+ s(`.main-btn-log-in`).click();
87
+ NotificationManager.Push({
88
+ html: Translate.Render(`expired-session`),
89
+ status: 'warning',
90
+ });
91
+ });
92
+ return await Auth.sessionOut();
80
93
  }
81
94
 
82
95
  // anon guest session
@@ -92,20 +105,25 @@ const Auth = {
92
105
 
93
106
  this.setGuestToken(guestToken);
94
107
  let { data, status, message } = await UserService.get({ id: 'auth' });
95
- if (status === 'error') throw new Error(message);
108
+ if (status === 'error') {
109
+ if (message && message.match('expired')) {
110
+ localStorage.removeItem('jwt.g');
111
+ return await Auth.sessionOut();
112
+ } else throw new Error(message);
113
+ }
96
114
  await Account.updateForm(data);
97
115
  return { user: data };
98
116
  } catch (error) {
99
117
  logger.error(error);
100
- localStorage.removeItem('jwt');
101
- localStorage.removeItem('jwt.g');
102
118
  return { user: UserMock.default };
103
119
  }
104
120
  },
105
121
  sessionOut: async function () {
106
122
  this.deleteToken();
107
123
  localStorage.removeItem('jwt');
108
- await LogOut.Trigger(await this.sessionIn());
124
+ const result = await this.sessionIn();
125
+ await LogOut.Trigger(result);
126
+ return result;
109
127
  },
110
128
  };
111
129
 
@@ -573,6 +573,14 @@ const isValidFormat = (value, format) => {
573
573
  }
574
574
  };
575
575
 
576
+ const getCurrentTrace = () => {
577
+ try {
578
+ _stack;
579
+ } catch (error) {
580
+ return error.stack.split('is not defined')[1];
581
+ }
582
+ };
583
+
576
584
  /**
577
585
  * Returns the time difference between UTC time and local time, in minutes.
578
586
  * @memberof CommonJS
@@ -811,6 +819,77 @@ const generateRandomPasswordSelection = (length) => {
811
819
  // 0b = Binary
812
820
  // 0o = Octal
813
821
 
822
+ const commitData = {
823
+ feat: {
824
+ description: 'A new feature',
825
+ title: 'Features',
826
+ emoji: '✨',
827
+ },
828
+ fix: {
829
+ description: 'A bug fix',
830
+ title: 'Bug Fixes',
831
+ emoji: '🐛',
832
+ },
833
+ docs: {
834
+ description: 'Documentation only changes',
835
+ title: 'Documentation',
836
+ emoji: '📚',
837
+ },
838
+ style: {
839
+ description:
840
+ 'Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
841
+ title: 'Styles',
842
+ emoji: '💎',
843
+ },
844
+ refactor: {
845
+ description: 'A code change that neither fixes a bug nor adds a feature',
846
+ title: 'Code Refactoring',
847
+ emoji: '📦',
848
+ },
849
+ perf: {
850
+ description: 'A code change that improves performance',
851
+ title: 'Performance Improvements',
852
+ emoji: '⚡️',
853
+ },
854
+ cd: {
855
+ description:
856
+ 'Changes to our Continuous Delivery configuration files and scripts (example scopes: Jenkins, Spinnaker, ArgoCD)',
857
+ title: 'Continuous Delivery',
858
+ emoji: '🚀',
859
+ },
860
+ test: {
861
+ description: 'Adding missing tests or correcting existing tests',
862
+ title: 'Tests',
863
+ emoji: '🚨',
864
+ },
865
+ build: {
866
+ description: 'Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)',
867
+ title: 'Builds',
868
+ emoji: '🛠',
869
+ },
870
+ ci: {
871
+ description:
872
+ 'Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)',
873
+ title: 'Continuous Integrations',
874
+ emoji: '⚙️',
875
+ },
876
+ chore: {
877
+ description: "Other changes that don't modify src or test files",
878
+ title: 'Chores',
879
+ emoji: '♻️',
880
+ },
881
+ revert: {
882
+ description: 'Reverts a previous commit',
883
+ title: 'Reverts',
884
+ emoji: '🗑',
885
+ },
886
+ backup: {
887
+ description: 'Changes related to backups, including creation, restoration, and maintenance.',
888
+ title: 'Backups',
889
+ emoji: '💾',
890
+ },
891
+ };
892
+
814
893
  const userRoleEnum = ['admin', 'moderator', 'user', 'guest'];
815
894
 
816
895
  const commonAdminGuard = (role) => userRoleEnum.indexOf(role) === userRoleEnum.indexOf('admin');
@@ -869,8 +948,10 @@ export {
869
948
  hexToNumber,
870
949
  numberToHex,
871
950
  generateRandomPasswordSelection,
872
- userRoleEnum,
873
951
  commonAdminGuard,
874
952
  commonModeratorGuard,
875
953
  isChileanIdentityDocument,
954
+ getCurrentTrace,
955
+ userRoleEnum,
956
+ commitData,
876
957
  };
@@ -761,6 +761,7 @@ const renderWave = ({ id }) => {
761
761
  const cssTokensEffect = {};
762
762
  const cssTokensContainer = {};
763
763
  const cssEffect = async (containerSelector, event) => {
764
+ return;
764
765
  // Array.from(event.target.classList)
765
766
  let offsetX, offsetY;
766
767
  if (Array.from(event.srcElement.classList).includes('ripple') && cssTokensContainer[containerSelector]) {
@@ -100,7 +100,7 @@ const Input = {
100
100
  </div>
101
101
  </div>`;
102
102
  },
103
- parseJsonEval: (selector) => {
103
+ parseJson: (selector) => {
104
104
  try {
105
105
  return JSON.parse(s(selector).value);
106
106
  } catch (error) {
@@ -9,7 +9,6 @@ import {
9
9
  htmls,
10
10
  sa,
11
11
  getAllChildNodes,
12
- getCurrentTrace,
13
12
  isActiveElement,
14
13
  } from './VanillaJs.js';
15
14
  import { BtnIcon } from './BtnIcon.js';
@@ -39,6 +39,7 @@ const Scroll = {
39
39
  delete this.topRefreshEvents[id];
40
40
  },
41
41
  pullTopRefresh: function () {
42
+ return;
42
43
  append(
43
44
  'body',
44
45
  html` <style>
@@ -508,6 +508,10 @@ const TranslateCore = {
508
508
  en: 'Invalid identity document',
509
509
  es: 'Documento de identidad inválido',
510
510
  };
511
+ Translate.Data['expired-session'] = {
512
+ en: 'Your session has expired. Please log in again.',
513
+ es: 'Su sesión ha expirado. Por favor, inicie sesión de nuevo.',
514
+ };
511
515
  },
512
516
  };
513
517
 
@@ -419,14 +419,6 @@ const isActiveTab = () => document.hasFocus();
419
419
  const isActiveElement = (classSearch = '') =>
420
420
  document.activeElement?.classList?.value?.match(classSearch) ? true : false;
421
421
 
422
- const getCurrentTrace = () => {
423
- try {
424
- _stack;
425
- } catch (error) {
426
- return error.stack.split('is not defined')[1];
427
- }
428
- };
429
-
430
422
  const isDevInstance = () => location.origin.match('localhost') && location.port;
431
423
 
432
424
  const getDataFromInputFile = async (file) => Array.from(new Uint8Array(await file.arrayBuffer()));
@@ -460,7 +452,6 @@ export {
460
452
  isNavigator,
461
453
  getTimeZone,
462
454
  getAllChildNodes,
463
- getCurrentTrace,
464
455
  isActiveTab,
465
456
  isActiveElement,
466
457
  isDevInstance,
@@ -22,41 +22,44 @@ const Worker = {
22
22
  setTimeout(() => {
23
23
  if ('onLine' in navigator && navigator.onLine) window.ononline();
24
24
  });
25
- navigator.serviceWorker.addEventListener('controllerchange', () => {
26
- logger.info('The controller of current browsing context has changed.');
27
- });
28
- navigator.serviceWorker.ready.then((worker) => {
29
- logger.info('Ready', worker);
30
- // event message
31
- navigator.serviceWorker.addEventListener('message', (event) => {
32
- logger.info('Received event message', event.data);
33
- const { status } = event.data;
25
+ if ('serviceWorker' in navigator) {
26
+ navigator.serviceWorker.addEventListener('controllerchange', () => {
27
+ logger.info('The controller of current browsing context has changed.');
28
+ });
29
+ navigator.serviceWorker.ready.then((worker) => {
30
+ logger.info('Ready', worker);
31
+ // event message
32
+ navigator.serviceWorker.addEventListener('message', (event) => {
33
+ logger.info('Received event message', event.data);
34
+ const { status } = event.data;
34
35
 
35
- switch (status) {
36
- case 'loader':
37
- {
38
- LoadingAnimation.RenderCurrentSrcLoad(event);
39
- }
40
- break;
36
+ switch (status) {
37
+ case 'loader':
38
+ {
39
+ LoadingAnimation.RenderCurrentSrcLoad(event);
40
+ }
41
+ break;
41
42
 
42
- default:
43
- break;
44
- }
45
- });
43
+ default:
44
+ break;
45
+ }
46
+ });
46
47
 
47
- // if (navigator.serviceWorker.controller)
48
- // navigator.serviceWorker.controller.postMessage({
49
- // title: 'Hello from Client event message',
50
- // });
48
+ // if (navigator.serviceWorker.controller)
49
+ // navigator.serviceWorker.controller.postMessage({
50
+ // title: 'Hello from Client event message',
51
+ // });
52
+
53
+ // broadcast message
54
+ // const channel = new BroadcastChannel('sw-messages');
55
+ // channel.addEventListener('message', (event) => {
56
+ // logger.info('Received broadcast message', event.data);
57
+ // });
58
+ // channel.postMessage({ title: 'Hello from Client broadcast message' });
59
+ // channel.close();
60
+ });
61
+ }
51
62
 
52
- // broadcast message
53
- // const channel = new BroadcastChannel('sw-messages');
54
- // channel.addEventListener('message', (event) => {
55
- // logger.info('Received broadcast message', event.data);
56
- // });
57
- // channel.postMessage({ title: 'Hello from Client broadcast message' });
58
- // channel.close();
59
- });
60
63
  this.RouterInstance = router();
61
64
  const isInstall = await this.status();
62
65
  if (!isInstall) await this.install();
@@ -106,10 +106,10 @@ SrrComponent = ({ ttiLoadTimeLimit }) => {
106
106
  </style>
107
107
  ${borderChar(1, 'black', ['.clean-cache-container'])}
108
108
  <script>
109
- window._VERSION = '${process.env.npm_package_version}';
109
+ window._VERSION = '${npm_package_version}';
110
110
  const CacheControl = ${CacheControl};
111
111
  CacheControl({ ttiLoadTimeLimit: ${ttiLoadTimeLimit ? ttiLoadTimeLimit : 1000 * 70 * 1} });
112
112
  </script>
113
- <div class="clean-cache-container">${process.env.npm_package_version}</div>
113
+ <div class="clean-cache-container">${npm_package_version}</div>
114
114
  `;
115
115
  };
package/src/index.js CHANGED
@@ -4,11 +4,16 @@
4
4
  * @namespace Underpost
5
5
  */
6
6
 
7
- import { runTest } from './server/conf.js';
8
- import { loggerFactory, setUpInfo } from './server/logger.js';
9
- import Project from './server/project.js';
10
-
11
- const logger = loggerFactory(import.meta);
7
+ import UnderpostCluster from './cli/cluster.js';
8
+ import UnderpostCron from './cli/cron.js';
9
+ import UnderpostDB from './cli/db.js';
10
+ import UnderpostDeploy from './cli/deploy.js';
11
+ import UnderpostRootEnv from './cli/env.js';
12
+ import UnderpostImage from './cli/image.js';
13
+ import UnderpostRepository from './cli/repository.js';
14
+ import UnderpostScript from './cli/script.js';
15
+ import UnderpostSecret from './cli/secrets.js';
16
+ import UnderpostTest from './cli/test.js';
12
17
 
13
18
  /**
14
19
  * Underpost main module methods
@@ -22,31 +27,77 @@ class Underpost {
22
27
  * @type {String}
23
28
  * @memberof Underpost
24
29
  */
25
- static version = 'v2.8.4';
26
- static project = Project;
27
-
28
- constructor() {}
29
-
30
+ static version = 'v2.8.5';
30
31
  /**
31
- * Logs information about the current process environment to the console.
32
- *
33
- * This function is used to log details about
34
- * the execution context, such as command-line arguments,
35
- * environment variables, the process's administrative privileges,
36
- * and the maximum available heap space size.
37
- *
32
+ * Repository cli API
38
33
  * @static
39
- * @method setUpInfo
40
- * @returns {Promise<void>}
34
+ * @type {UnderpostRepository.API}
41
35
  * @memberof Underpost
42
36
  */
43
- static async setUpInfo() {
44
- return await setUpInfo(logger);
45
- }
46
-
47
- static runTest() {
48
- return runTest(Underpost.version);
49
- }
37
+ static repo = UnderpostRepository.API;
38
+ /**
39
+ * Root Env cli API
40
+ * @static
41
+ * @type {UnderpostRootEnv.API}
42
+ * @memberof Underpost
43
+ */
44
+ static env = UnderpostRootEnv.API;
45
+ /**
46
+ * Test cli API
47
+ * @static
48
+ * @type {UnderpostTest.API}
49
+ * @memberof Underpost
50
+ */
51
+ static test = UnderpostTest.API;
52
+ /**
53
+ * Cluster cli API
54
+ * @static
55
+ * @type {UnderpostCluster.API}
56
+ * @memberof Underpost
57
+ */
58
+ static cluster = UnderpostCluster.API;
59
+ /**
60
+ * Image cli API
61
+ * @static
62
+ * @type {UnderpostImage.API}
63
+ * @memberof Underpost
64
+ */
65
+ static image = UnderpostImage.API;
66
+ /**
67
+ * Secrets cli API
68
+ * @static
69
+ * @type {UnderpostSecret.API}
70
+ * @memberof Underpost
71
+ */
72
+ static secret = UnderpostSecret.API;
73
+ /**
74
+ * Scripts cli API
75
+ * @static
76
+ * @type {UnderpostScript.API}
77
+ * @memberof Underpost
78
+ */
79
+ static script = UnderpostScript.API;
80
+ /**
81
+ * Database cli API
82
+ * @static
83
+ * @type {UnderpostDB.API}
84
+ * @memberof Underpost
85
+ */
86
+ static db = UnderpostDB.API;
87
+ /**
88
+ * Deployment cli API
89
+ * @static
90
+ * @type {UnderpostDeploy.API}
91
+ * @memberof Underpost
92
+ */
93
+ static deploy = UnderpostDeploy.API;
94
+ /**
95
+ * Cron cli API
96
+ * @static
97
+ * @type {UnderpostCron.API}
98
+ * @memberof Underpost
99
+ */
100
+ static cron = UnderpostCron.API;
50
101
  }
51
102
 
52
103
  const up = Underpost;