underpost 2.8.1 → 2.8.7

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 (145) hide show
  1. package/.dockerignore +1 -0
  2. package/.github/workflows/ghpkg.yml +19 -49
  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 +12 -4
  6. package/.github/workflows/pwa-microservices-template.test.yml +2 -2
  7. package/.vscode/extensions.json +18 -71
  8. package/.vscode/settings.json +20 -3
  9. package/AUTHORS.md +16 -5
  10. package/CHANGELOG.md +123 -3
  11. package/Dockerfile +27 -70
  12. package/README.md +39 -29
  13. package/bin/build.js +186 -0
  14. package/bin/db.js +2 -24
  15. package/bin/deploy.js +1467 -236
  16. package/bin/file.js +67 -16
  17. package/bin/hwt.js +0 -10
  18. package/bin/index.js +1 -77
  19. package/bin/ssl.js +19 -11
  20. package/bin/util.js +9 -104
  21. package/bin/vs.js +26 -2
  22. package/cli.md +451 -0
  23. package/conf.js +29 -138
  24. package/docker-compose.yml +1 -1
  25. package/jsdoc.json +1 -1
  26. package/manifests/calico-custom-resources.yaml +25 -0
  27. package/manifests/deployment/adminer/deployment.yaml +32 -0
  28. package/manifests/deployment/adminer/kustomization.yaml +7 -0
  29. package/manifests/deployment/adminer/service.yaml +13 -0
  30. package/manifests/deployment/fastapi/backend-deployment.yml +120 -0
  31. package/manifests/deployment/fastapi/backend-service.yml +19 -0
  32. package/manifests/deployment/fastapi/frontend-deployment.yml +54 -0
  33. package/manifests/deployment/fastapi/frontend-service.yml +15 -0
  34. package/manifests/deployment/kafka/deployment.yaml +69 -0
  35. package/manifests/deployment/mongo-express/deployment.yaml +60 -0
  36. package/manifests/deployment/phpmyadmin/deployment.yaml +54 -0
  37. package/manifests/kind-config-dev.yaml +12 -0
  38. package/manifests/kind-config.yaml +12 -0
  39. package/manifests/kubeadm-calico-config.yaml +119 -0
  40. package/manifests/letsencrypt-prod.yaml +15 -0
  41. package/manifests/mariadb/config.yaml +10 -0
  42. package/manifests/mariadb/kustomization.yaml +9 -0
  43. package/manifests/mariadb/pv.yaml +12 -0
  44. package/manifests/mariadb/pvc.yaml +10 -0
  45. package/manifests/mariadb/secret.yaml +8 -0
  46. package/manifests/mariadb/service.yaml +10 -0
  47. package/manifests/mariadb/statefulset.yaml +55 -0
  48. package/manifests/mongodb/backup-access.yaml +16 -0
  49. package/manifests/mongodb/backup-cronjob.yaml +42 -0
  50. package/manifests/mongodb/backup-pv-pvc.yaml +22 -0
  51. package/manifests/mongodb/configmap.yaml +26 -0
  52. package/manifests/mongodb/headless-service.yaml +10 -0
  53. package/manifests/mongodb/kustomization.yaml +11 -0
  54. package/manifests/mongodb/pv-pvc.yaml +23 -0
  55. package/manifests/mongodb/statefulset.yaml +125 -0
  56. package/manifests/mongodb-4.4/kustomization.yaml +7 -0
  57. package/manifests/mongodb-4.4/pv-pvc.yaml +23 -0
  58. package/manifests/mongodb-4.4/service-deployment.yaml +63 -0
  59. package/manifests/postgresql/configmap.yaml +9 -0
  60. package/manifests/postgresql/kustomization.yaml +10 -0
  61. package/manifests/postgresql/pv.yaml +15 -0
  62. package/manifests/postgresql/pvc.yaml +13 -0
  63. package/manifests/postgresql/service.yaml +10 -0
  64. package/manifests/postgresql/statefulset.yaml +37 -0
  65. package/manifests/valkey/kustomization.yaml +7 -0
  66. package/manifests/valkey/service.yaml +17 -0
  67. package/manifests/valkey/statefulset.yaml +41 -0
  68. package/package.json +127 -136
  69. package/src/api/core/core.service.js +1 -1
  70. package/src/api/default/default.service.js +1 -1
  71. package/src/api/user/user.model.js +16 -3
  72. package/src/api/user/user.service.js +15 -12
  73. package/src/cli/cluster.js +389 -0
  74. package/src/cli/cron.js +121 -0
  75. package/src/cli/db.js +222 -0
  76. package/src/cli/deploy.js +487 -0
  77. package/src/cli/env.js +58 -0
  78. package/src/cli/fs.js +161 -0
  79. package/src/cli/image.js +66 -0
  80. package/src/cli/index.js +312 -0
  81. package/src/cli/monitor.js +236 -0
  82. package/src/cli/repository.js +128 -0
  83. package/src/cli/script.js +53 -0
  84. package/src/cli/secrets.js +37 -0
  85. package/src/cli/test.js +118 -0
  86. package/src/client/components/core/Account.js +28 -24
  87. package/src/client/components/core/Auth.js +22 -4
  88. package/src/client/components/core/Blockchain.js +1 -1
  89. package/src/client/components/core/CalendarCore.js +128 -121
  90. package/src/client/components/core/CommonJs.js +283 -19
  91. package/src/client/components/core/CssCore.js +16 -4
  92. package/src/client/components/core/Docs.js +1 -2
  93. package/src/client/components/core/DropDown.js +5 -1
  94. package/src/client/components/core/EventsUI.js +3 -3
  95. package/src/client/components/core/FileExplorer.js +86 -78
  96. package/src/client/components/core/Input.js +22 -6
  97. package/src/client/components/core/JoyStick.js +2 -2
  98. package/src/client/components/core/LoadingAnimation.js +3 -12
  99. package/src/client/components/core/LogIn.js +3 -3
  100. package/src/client/components/core/LogOut.js +1 -1
  101. package/src/client/components/core/Modal.js +54 -20
  102. package/src/client/components/core/Panel.js +109 -90
  103. package/src/client/components/core/PanelForm.js +23 -30
  104. package/src/client/components/core/Recover.js +3 -3
  105. package/src/client/components/core/RichText.js +1 -11
  106. package/src/client/components/core/Router.js +3 -1
  107. package/src/client/components/core/Scroll.js +1 -0
  108. package/src/client/components/core/SignUp.js +2 -2
  109. package/src/client/components/core/Translate.js +47 -9
  110. package/src/client/components/core/Validator.js +9 -1
  111. package/src/client/components/core/VanillaJs.js +0 -9
  112. package/src/client/components/core/Worker.js +34 -31
  113. package/src/client/components/default/RoutesDefault.js +3 -2
  114. package/src/client/services/core/core.service.js +15 -10
  115. package/src/client/services/default/default.management.js +46 -37
  116. package/src/client/ssr/Render.js +6 -1
  117. package/src/client/ssr/body/CacheControl.js +2 -3
  118. package/src/client/sw/default.sw.js +3 -3
  119. package/src/db/mongo/MongooseDB.js +29 -1
  120. package/src/index.js +101 -19
  121. package/src/mailer/MailerProvider.js +3 -0
  122. package/src/runtime/lampp/Dockerfile +65 -0
  123. package/src/runtime/lampp/Lampp.js +1 -13
  124. package/src/runtime/xampp/Xampp.js +0 -13
  125. package/src/server/auth.js +3 -3
  126. package/src/server/backup.js +49 -93
  127. package/src/server/client-build.js +49 -46
  128. package/src/server/client-formatted.js +6 -3
  129. package/src/server/conf.js +297 -55
  130. package/src/server/dns.js +75 -62
  131. package/src/server/downloader.js +0 -8
  132. package/src/server/json-schema.js +77 -0
  133. package/src/server/logger.js +15 -10
  134. package/src/server/network.js +20 -161
  135. package/src/server/peer.js +2 -2
  136. package/src/server/process.js +25 -2
  137. package/src/server/proxy.js +7 -29
  138. package/src/server/runtime.js +53 -40
  139. package/src/server/ssl.js +1 -1
  140. package/src/server/start.js +122 -0
  141. package/src/server/valkey.js +27 -11
  142. package/test/api.test.js +0 -8
  143. package/src/dns.js +0 -22
  144. package/src/server/prompt-optimizer.js +0 -28
  145. package/startup.js +0 -11
@@ -1,6 +1,13 @@
1
1
  import fs from 'fs-extra';
2
2
  import dotenv from 'dotenv';
3
- import { capFirst, getCapVariableName, newInstance, range, timer } from '../client/components/core/CommonJs.js';
3
+ import {
4
+ capFirst,
5
+ getCapVariableName,
6
+ newInstance,
7
+ orderArrayFromAttrInt,
8
+ range,
9
+ timer,
10
+ } from '../client/components/core/CommonJs.js';
4
11
  import * as dir from 'path';
5
12
  import cliProgress from 'cli-progress';
6
13
  import cliSpinners from 'cli-spinners';
@@ -9,22 +16,13 @@ import colors from 'colors';
9
16
  import { loggerFactory } from './logger.js';
10
17
  import { shellExec } from './process.js';
11
18
  import { DefaultConf } from '../../conf.js';
12
- import ncp from 'copy-paste';
13
19
  import read from 'read';
14
20
  import splitFile from 'split-file';
15
21
  import axios from 'axios';
16
- import https from 'https';
17
22
  import { ssrFactory } from './client-formatted.js';
18
23
 
19
- // axios.defaults.baseURL = BASE_URL;
20
-
21
- const httpsAgent = new https.Agent({
22
- rejectUnauthorized: false,
23
- });
24
-
25
- axios.defaults.httpsAgent = httpsAgent;
26
-
27
24
  colors.enable();
25
+
28
26
  dotenv.config();
29
27
 
30
28
  const logger = loggerFactory(import.meta);
@@ -33,21 +31,26 @@ const logger = loggerFactory(import.meta);
33
31
 
34
32
  const Config = {
35
33
  default: DefaultConf,
36
- build: async function (options = { folder: '' }) {
34
+ build: async function (options = { folder: '' }, deployContext, deployList, subConf) {
35
+ if (!deployContext) deployContext = process.argv[2];
37
36
  if (!fs.existsSync(`./tmp`)) fs.mkdirSync(`./tmp`, { recursive: true });
38
37
  fs.writeFileSync(`./tmp/await-deploy`, '', 'utf8');
39
- if (fs.existsSync(`./engine-private/conf/${process.argv[2]}`)) return loadConf(process.argv[2]);
40
- if (fs.existsSync(`./engine-private/replica/${process.argv[2]}`)) return loadConf(process.argv[2]);
38
+ if (fs.existsSync(`./engine-private/conf/${deployContext}`))
39
+ return loadConf(deployContext, process.env.NODE_ENV, subConf);
40
+ if (fs.existsSync(`./engine-private/replica/${deployContext}`))
41
+ return loadConf(deployContext, process.env.NODE_ENV, subConf);
41
42
 
42
- if (process.argv[2] === 'deploy') return;
43
+ if (deployContext === 'deploy') return;
43
44
 
44
- if (process.argv[2] === 'proxy') {
45
+ if (deployContext === 'proxy') {
46
+ if (!deployList) deployList = process.argv[3];
47
+ if (!subConf) subConf = process.argv[4];
45
48
  this.default.server = {};
46
- for (const deployId of process.argv[3].split(',')) {
49
+ for (const deployId of deployList.split(',')) {
47
50
  let confPath = `./engine-private/conf/${deployId}/conf.server.json`;
48
51
  const privateConfDevPath = fs.existsSync(`./engine-private/replica/${deployId}/conf.server.json`)
49
52
  ? `./engine-private/replica/${deployId}/conf.server.json`
50
- : `./engine-private/conf/${deployId}/conf.server.dev.${process.argv[4]}.json`;
53
+ : `./engine-private/conf/${deployId}/conf.server.dev.${subConf}.json`;
51
54
  const confDevPath = fs.existsSync(privateConfDevPath)
52
55
  ? privateConfDevPath
53
56
  : `./engine-private/conf/${deployId}/conf.server.dev.json`;
@@ -55,7 +58,7 @@ const Config = {
55
58
  if (process.env.NODE_ENV === 'development' && fs.existsSync(confDevPath)) confPath = confDevPath;
56
59
  const serverConf = JSON.parse(fs.readFileSync(confPath, 'utf8'));
57
60
 
58
- for (const host of Object.keys(loadReplicas(serverConf))) {
61
+ for (const host of Object.keys(loadReplicas(serverConf, deployContext, subConf))) {
59
62
  if (serverConf[host]['/'])
60
63
  this.default.server[host] = {
61
64
  ...this.default.server[host],
@@ -85,7 +88,15 @@ const Config = {
85
88
  },
86
89
  };
87
90
 
88
- const loadConf = (deployId) => {
91
+ const loadConf = (deployId, envInput, subConf) => {
92
+ if (deployId === 'clean') {
93
+ shellExec(`git checkout package.json`);
94
+ shellExec(`git checkout .env.production`);
95
+ shellExec(`git checkout .env.development`);
96
+ shellExec(`git checkout .env.test`);
97
+ shellExec(`git checkout jsdoc.json`);
98
+ return;
99
+ }
89
100
  const folder = fs.existsSync(`./engine-private/replica/${deployId}`)
90
101
  ? `./engine-private/replica/${deployId}`
91
102
  : `./engine-private/conf/${deployId}`;
@@ -102,7 +113,8 @@ const loadConf = (deployId) => {
102
113
  ? fs.readFileSync(`${folder}/conf.${typeConf}.json`, 'utf8')
103
114
  : JSON.stringify(Config.default[typeConf]);
104
115
  if (process.env.NODE_ENV === 'development' && typeConf === 'server') {
105
- const devConfPath = `${folder}/conf.${typeConf}.dev${process.argv[3] ? `.${process.argv[3]}` : ''}.json`;
116
+ if (!subConf) subConf = process.argv[3];
117
+ const devConfPath = `${folder}/conf.${typeConf}.dev${subConf ? `.${subConf}` : ''}.json`;
106
118
  if (fs.existsSync(devConfPath)) srcConf = fs.readFileSync(devConfPath, 'utf8');
107
119
  }
108
120
  if (typeConf === 'server') srcConf = JSON.stringify(loadReplicas(JSON.parse(srcConf)), null, 4);
@@ -111,27 +123,34 @@ const loadConf = (deployId) => {
111
123
  fs.writeFileSync(`./.env.production`, fs.readFileSync(`${folder}/.env.production`, 'utf8'), 'utf8');
112
124
  fs.writeFileSync(`./.env.development`, fs.readFileSync(`${folder}/.env.development`, 'utf8'), 'utf8');
113
125
  fs.writeFileSync(`./.env.test`, fs.readFileSync(`${folder}/.env.test`, 'utf8'), 'utf8');
114
- if (process.env.NODE_ENV) {
115
- fs.writeFileSync(`./.env`, fs.readFileSync(`${folder}/.env.${process.env.NODE_ENV}`, 'utf8'), 'utf8');
116
- const env = dotenv.parse(fs.readFileSync(`${folder}/.env.${process.env.NODE_ENV}`, 'utf8'));
126
+ const NODE_ENV = envInput || process.env.NODE_ENV;
127
+ if (NODE_ENV) {
128
+ fs.writeFileSync(`./.env`, fs.readFileSync(`${folder}/.env.${NODE_ENV}`, 'utf8'), 'utf8');
129
+ const env = dotenv.parse(fs.readFileSync(`${folder}/.env.${NODE_ENV}`, 'utf8'));
117
130
  process.env = {
118
131
  ...process.env,
119
132
  ...env,
120
133
  };
121
134
  }
122
- fs.writeFileSync(`./package.json`, fs.readFileSync(`${folder}/package.json`, 'utf8'), 'utf8');
135
+ const originPackageJson = JSON.parse(fs.readFileSync(`./package.json`, 'utf8'));
136
+ const packageJson = JSON.parse(fs.readFileSync(`${folder}/package.json`, 'utf8'));
137
+ originPackageJson.scripts.start = packageJson.scripts.start;
138
+ packageJson.scripts = originPackageJson.scripts;
139
+ fs.writeFileSync(`./package.json`, JSON.stringify(packageJson, null, 4), 'utf8');
123
140
  return { folder, deployId };
124
141
  };
125
142
 
126
- const loadReplicas = (confServer) => {
143
+ const loadReplicas = (confServer, deployContext, subConf) => {
144
+ if (!deployContext) deployContext = process.argv[2];
145
+ if (!subConf) subConf = process.argv[3];
127
146
  for (const host of Object.keys(confServer)) {
128
147
  for (const path of Object.keys(confServer[host])) {
129
148
  const { replicas, singleReplica } = confServer[host][path];
130
149
  if (
131
150
  replicas &&
132
- (process.argv[2] === 'proxy' ||
151
+ (deployContext === 'proxy' ||
133
152
  !singleReplica ||
134
- (singleReplica && process.env.NODE_ENV === 'development' && !process.argv[3]))
153
+ (singleReplica && process.env.NODE_ENV === 'development' && !subConf))
135
154
  )
136
155
  for (const replicaPath of replicas) {
137
156
  confServer[host][replicaPath] = newInstance(confServer[host][path]);
@@ -480,6 +499,82 @@ const buildProxyRouter = () => {
480
499
  return proxyRouter;
481
500
  };
482
501
 
502
+ const pathPortAssignmentFactory = (router, confServer) => {
503
+ const pathPortAssignmentData = {};
504
+ for (const host of Object.keys(confServer)) {
505
+ const pathPortAssignment = [];
506
+ for (const path of Object.keys(confServer[host])) {
507
+ const { peer } = confServer[host][path];
508
+ if (!router[`${host}${path === '/' ? '' : path}`]) continue;
509
+ const port = parseInt(router[`${host}${path === '/' ? '' : path}`].split(':')[2]);
510
+ // logger.info('', { host, port, path });
511
+ pathPortAssignment.push({
512
+ port,
513
+ path,
514
+ });
515
+
516
+ if (peer) {
517
+ // logger.info('', { host, port: port + 1, path: '/peer' });
518
+ pathPortAssignment.push({
519
+ port: port + 1,
520
+ path: '/peer',
521
+ });
522
+ }
523
+ }
524
+ pathPortAssignmentData[host] = pathPortAssignment;
525
+ }
526
+ return pathPortAssignmentData;
527
+ };
528
+
529
+ const deployRangePortFactory = (router) => {
530
+ const ports = Object.values(router).map((p) => parseInt(p.split(':')[2]));
531
+ const fromPort = Math.min(...ports);
532
+ const toPort = Math.max(...ports);
533
+ return { ports, fromPort, toPort };
534
+ };
535
+
536
+ const buildKindPorts = (from, to) =>
537
+ range(parseInt(from), parseInt(to))
538
+ .map(
539
+ (port) => ` - name: 'tcp-${port}'
540
+ protocol: TCP
541
+ port: ${port}
542
+ targetPort: ${port}
543
+ - name: 'udp-${port}'
544
+ protocol: UDP
545
+ port: ${port}
546
+ targetPort: ${port}
547
+ `,
548
+ )
549
+ .join('\n');
550
+
551
+ const buildPortProxyRouter = (port, proxyRouter) => {
552
+ const hosts = proxyRouter[port];
553
+ const router = {};
554
+ // build router
555
+ Object.keys(hosts).map((hostKey) => {
556
+ let { host, path, target, proxy, peer } = hosts[hostKey];
557
+ if (process.argv.includes('localhost') && process.env.NODE_ENV === 'development') host = `localhost`;
558
+
559
+ if (!proxy.includes(port)) return;
560
+ const absoluteHost = [80, 443].includes(port)
561
+ ? `${host}${path === '/' ? '' : path}`
562
+ : `${host}:${port}${path === '/' ? '' : path}`;
563
+
564
+ if (process.argv.includes('localhost')) {
565
+ if (!(absoluteHost in router)) router[absoluteHost] = target;
566
+ } else router[absoluteHost] = target;
567
+ }); // order router
568
+
569
+ if (Object.keys(router).length === 0) return router;
570
+
571
+ const reOrderRouter = {};
572
+ for (const absoluteHostKey of orderArrayFromAttrInt(Object.keys(router), 'length'))
573
+ reOrderRouter[absoluteHostKey] = router[absoluteHostKey];
574
+
575
+ return reOrderRouter;
576
+ };
577
+
483
578
  const cliBar = async (time = 5000) => {
484
579
  // create new progress bar
485
580
  const b = new cliProgress.SingleBar({
@@ -528,9 +623,25 @@ const cliSpinner = async (time = 5000, message0, message1, color, type = 'dots')
528
623
  const buildReplicaId = ({ deployId, replica }) => `${deployId}-${replica.slice(1)}`;
529
624
 
530
625
  const getDataDeploy = (
531
- options = { buildSingleReplica: false, deployGroupId: '', deployId: '', disableSyncEnvPort: false },
626
+ options = {
627
+ buildSingleReplica: false,
628
+ deployGroupId: '',
629
+ deployId: '',
630
+ disableSyncEnvPort: false,
631
+ deployIdConcat: [],
632
+ },
532
633
  ) => {
533
- let dataDeploy = JSON.parse(fs.readFileSync(`./engine-private/deploy/${options.deployGroupId}.json`, 'utf8'));
634
+ let dataDeploy =
635
+ options.deployGroupId === 'dd'
636
+ ? fs.readFileSync(`./engine-private/deploy/${options.deployGroupId}.router`, 'utf8')
637
+ : fs.readFileSync(`./engine-private/deploy/${options.deployGroupId}`, 'utf8');
638
+
639
+ dataDeploy = dataDeploy
640
+ .split(',')
641
+ .map((deployId) => deployId.trim())
642
+ .filter((deployId) => deployId);
643
+
644
+ if (options.deployIdConcat) dataDeploy = dataDeploy.concat(options.deployIdConcat);
534
645
 
535
646
  if (options.deployId) dataDeploy = dataDeploy.filter((d) => d === options.deployId);
536
647
 
@@ -588,6 +699,7 @@ const validateTemplatePath = (absolutePath = '') => {
588
699
  if (absolutePath.match('src/api') && !confServer.apis.find((p) => absolutePath.match(`src/api/${p}/`))) {
589
700
  return false;
590
701
  }
702
+ if (absolutePath.match('conf.dd-') && absolutePath.match('.js')) return false;
591
703
  if (
592
704
  absolutePath.match('src/client/services/') &&
593
705
  !clients.find((p) => absolutePath.match(`src/client/services/${p}/`))
@@ -651,7 +763,7 @@ const validateTemplatePath = (absolutePath = '') => {
651
763
  return true;
652
764
  };
653
765
 
654
- const deployTest = async (dataDeploy) => {
766
+ const deployTest = async (dataDeploy = [{ deployId: 'default' }]) => {
655
767
  const failed = [];
656
768
  for (const deploy of dataDeploy) {
657
769
  const deployServerConfPath = fs.existsSync(`./engine-private/replica/${deploy.deployId}/conf.server.json`)
@@ -695,6 +807,12 @@ const deployTest = async (dataDeploy) => {
695
807
  return { failed };
696
808
  };
697
809
 
810
+ const awaitDeployMonitor = async (init = false, deltaMs = 1000) => {
811
+ if (init) fs.writeFileSync(`./tmp/await-deploy`, '', 'utf8');
812
+ await timer(deltaMs);
813
+ if (fs.existsSync(`./tmp/await-deploy`)) return await awaitDeployMonitor();
814
+ };
815
+
698
816
  const getDeployGroupId = () => {
699
817
  const deployGroupIndexArg = process.argv.findIndex((a) => a.match(`deploy-group:`));
700
818
  if (deployGroupIndexArg > -1) return process.argv[deployGroupIndexArg].split(':')[1].trim();
@@ -764,15 +882,16 @@ const deployRun = async (dataDeploy, currentAttempt = 1) => {
764
882
  if (failed.length > 0) {
765
883
  for (const deploy of failed) logger.error(deploy.deployId, Cmd.run(deploy.deployId));
766
884
  if (currentAttempt === maxAttempts) return logger.error(`max deploy attempts exceeded`);
767
- if (process.argv.includes('manual')) await read({ prompt: 'Press enter to retry failed processes\n' });
885
+ await read({ prompt: 'Press enter to retry failed processes\n' });
768
886
  currentAttempt++;
769
887
  await deployRun(failed, currentAttempt);
770
888
  } else logger.info(`Deploy process successfully`);
771
889
  };
772
890
 
773
- const restoreMacroDb = async (deployGroupId = '') => {
891
+ const restoreMacroDb = async (deployGroupId = '', deployId = null) => {
774
892
  const dataDeploy = await getDataDeploy({ deployGroupId, buildSingleReplica: false });
775
893
  for (const deployGroup of dataDeploy) {
894
+ if (deployId && deployGroup.deployId !== deployId) continue;
776
895
  if (!deployGroup.replicaHost) {
777
896
  const deployServerConfPath = `./engine-private/conf/${deployGroup.deployId}/conf.server.json`;
778
897
  const serverConf = JSON.parse(fs.readFileSync(deployServerConfPath, 'utf8'));
@@ -790,13 +909,10 @@ const restoreMacroDb = async (deployGroupId = '') => {
790
909
  }
791
910
  };
792
911
 
793
- const mergeBackUp = async (baseBackJsonPath, outputFilePath) => {
794
- const names = JSON.parse(fs.readFileSync(baseBackJsonPath, 'utf8')).map((p) =>
795
- p.replaceAll(`\\`, '/').replaceAll('C:/', '/').replaceAll('c:/', '/'),
796
- );
912
+ const mergeFile = async (parts = [], outputFilePath) => {
797
913
  await new Promise((resolve) => {
798
914
  splitFile
799
- .mergeFiles(names, outputFilePath)
915
+ .mergeFiles(parts, outputFilePath)
800
916
  .then(() => {
801
917
  resolve();
802
918
  })
@@ -807,6 +923,53 @@ const mergeBackUp = async (baseBackJsonPath, outputFilePath) => {
807
923
  });
808
924
  };
809
925
 
926
+ const rebuildConfFactory = ({ deployId, valkey, mongo }) => {
927
+ const confServer = loadReplicas(
928
+ JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
929
+ );
930
+ const hosts = {};
931
+ for (const host of Object.keys(confServer)) {
932
+ hosts[host] = {};
933
+ for (const path of Object.keys(confServer[host])) {
934
+ if (!confServer[host][path].db) continue;
935
+ const { singleReplica, replicas, db } = confServer[host][path];
936
+ const { provider } = db;
937
+ if (singleReplica) {
938
+ for (const replica of replicas) {
939
+ const deployIdReplica = buildReplicaId({ replica, deployId });
940
+ const confServerReplica = JSON.parse(
941
+ fs.readFileSync(`./engine-private/replica/${deployIdReplica}/conf.server.json`, 'utf8'),
942
+ );
943
+ for (const _host of Object.keys(confServerReplica)) {
944
+ for (const _path of Object.keys(confServerReplica[_host])) {
945
+ hosts[host][_path] = { replica: { host, path } };
946
+ confServerReplica[_host][_path].valkey = valkey;
947
+ switch (provider) {
948
+ case 'mongoose':
949
+ confServerReplica[_host][_path].db.host = mongo.host;
950
+ break;
951
+ }
952
+ }
953
+ }
954
+ fs.writeFileSync(
955
+ `./engine-private/replica/${deployIdReplica}/conf.server.json`,
956
+ JSON.stringify(confServerReplica, null, 4),
957
+ 'utf8',
958
+ );
959
+ }
960
+ } else hosts[host][path] = {};
961
+ confServer[host][path].valkey = valkey;
962
+ switch (provider) {
963
+ case 'mongoose':
964
+ confServer[host][path].db.host = mongo.host;
965
+ break;
966
+ }
967
+ }
968
+ }
969
+ fs.writeFileSync(`./engine-private/conf/${deployId}/conf.server.json`, JSON.stringify(confServer, null, 4), 'utf8');
970
+ return { hosts };
971
+ };
972
+
810
973
  const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deployId: '' }) => {
811
974
  const { host, path, conf, deployId } = options;
812
975
  const { runtime, db, git, directory } = conf[host][path];
@@ -848,11 +1011,13 @@ const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deplo
848
1011
  {
849
1012
  if (process.argv.includes('cron')) {
850
1013
  cmd = `mysql -u ${user} -p${password} ${name} < ${baseBackUpPath}/${currentBackupTimestamp}/${name}.sql`;
851
- if (fs.existsSync(`${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`))
852
- await mergeBackUp(
853
- `${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`,
854
- `${baseBackUpPath}/${currentBackupTimestamp}/${name}.sql`,
855
- );
1014
+ if (fs.existsSync(`${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`)) {
1015
+ const names = JSON.parse(
1016
+ fs.readFileSync(`${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`, 'utf8'),
1017
+ ).map((p) => p.replaceAll(`\\`, '/').replaceAll('C:/', '/').replaceAll('c:/', '/'));
1018
+
1019
+ await mergeFile(names, `${baseBackUpPath}/${currentBackupTimestamp}/${name}.sql`);
1020
+ }
856
1021
  } else {
857
1022
  cmd = `mysql -u ${user} -p${password} ${name} < ${
858
1023
  backupPath ? backupPath : `./engine-private/sql-backups/${name}.sql`
@@ -863,15 +1028,23 @@ const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deplo
863
1028
  backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
864
1029
  }/${name}-parths.json`,
865
1030
  )
866
- )
867
- await mergeBackUp(
868
- `${
869
- backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
870
- }/${name}-parths.json`,
1031
+ ) {
1032
+ const names = JSON.parse(
1033
+ fs.readFileSync(
1034
+ `${
1035
+ backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
1036
+ }/${name}-parths.json`,
1037
+ 'utf8',
1038
+ ),
1039
+ ).map((p) => p.replaceAll(`\\`, '/').replaceAll('C:/', '/').replaceAll('c:/', '/'));
1040
+
1041
+ await mergeFile(
1042
+ names,
871
1043
  `${
872
1044
  backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
873
1045
  }/${name}.sql`,
874
1046
  );
1047
+ }
875
1048
  }
876
1049
  }
877
1050
  break;
@@ -890,20 +1063,31 @@ const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deplo
890
1063
  return cmd;
891
1064
  };
892
1065
 
1066
+ const getPathsSSR = (conf) => {
1067
+ const paths = ['src/client/ssr/Render.js'];
1068
+ for (const o of conf.head) paths.push(`src/client/ssr/head/${o}.js`);
1069
+ for (const o of conf.body) paths.push(`src/client/ssr/body/${o}.js`);
1070
+ for (const o of Object.keys(conf.mailer)) paths.push(`src/client/ssr/mailer/${conf.mailer[o]}.js`);
1071
+ for (const o of conf.offline) paths.push(`src/client/ssr/mailer/${o.client}.js`);
1072
+ for (const o of conf.pages) paths.push(`src/client/ssr/pages/${o.client}.js`);
1073
+ return paths;
1074
+ };
1075
+
893
1076
  const Cmd = {
894
1077
  delete: (deployId) => `pm2 delete ${deployId}`,
895
- run: (deployId) => `node bin/deploy run ${deployId}`,
1078
+ run: () => `npm start`,
896
1079
  build: (deployId) => `node bin/deploy build-full-client ${deployId}${process.argv.includes('l') ? ' l' : ''}`,
897
1080
  conf: (deployId, env) => `node bin/deploy conf ${deployId} ${env ? env : 'production'}`,
898
1081
  replica: (deployId, host, path) => `node bin/deploy build-single-replica ${deployId} ${host} ${path}`,
899
1082
  syncPorts: (deployGroupId) => `node bin/deploy sync-env-port ${deployGroupId}`,
900
- cron: (deployId, job, expression) => {
901
- shellExec(Cmd.delete(`${deployId}-${job}`));
902
- return `env-cmd -f .env.production pm2 start bin/cron.js --no-autorestart --instances 1 --cron "${expression}" --name ${deployId}-${job} -- ${job} ${deployId}`;
903
- },
1083
+ cron: (deployList, jobList, name, expression, options) =>
1084
+ `pm2 start ./bin/index.js --no-autorestart --instances 1 --cron "${expression}" --name ${name} -- cron ${
1085
+ options?.itc ? `--itc ` : ''
1086
+ }${options?.git ? `--git ` : ''}${deployList} ${jobList}`,
904
1087
  };
905
1088
 
906
1089
  const fixDependencies = async () => {
1090
+ return;
907
1091
  // sed -i "$line_number s,.*,$new_text," "$file"
908
1092
  // sed -i "$line_number c \\$new_text" "$file"
909
1093
  const dep = fs.readFileSync(`./node_modules/peer/dist/module.mjs`, 'utf8');
@@ -933,14 +1117,60 @@ const maintenanceMiddleware = (req, res, port, proxyRouter) => {
933
1117
  }
934
1118
  };
935
1119
 
1120
+ const splitFileFactory = async (name, _path) => {
1121
+ const stats = fs.statSync(_path);
1122
+ const maxSizeInBytes = 1024 * 1024 * 50; // 50 mb
1123
+ const fileSizeInBytes = stats.size;
1124
+ if (fileSizeInBytes > maxSizeInBytes) {
1125
+ logger.info('splitFileFactory input', { name, from: _path });
1126
+ return await new Promise((resolve) => {
1127
+ splitFile
1128
+ .splitFileBySize(_path, maxSizeInBytes) // 50 mb
1129
+ .then((names) => {
1130
+ logger.info('splitFileFactory output', { parts: names });
1131
+ fs.writeFileSync(
1132
+ `${_path.split('/').slice(0, -1).join('/')}/${name}-parths.json`,
1133
+ JSON.stringify(names, null, 4),
1134
+ 'utf8',
1135
+ );
1136
+ fs.removeSync(_path);
1137
+ return resolve(true);
1138
+ })
1139
+ .catch((err) => {
1140
+ console.log('Error: ', err);
1141
+ return resolve(false);
1142
+ });
1143
+ });
1144
+ }
1145
+ return false;
1146
+ };
1147
+
936
1148
  const setUpProxyMaintenanceServer = ({ deployGroupId }) => {
937
1149
  shellExec(`pm2 kill`);
938
1150
  shellExec(`node bin/deploy valkey-service`);
939
1151
  const proxyDeployId = fs.readFileSync(`./engine-private/deploy/${deployGroupId}.proxy`, 'utf8').trim();
940
1152
  shellExec(`node bin/deploy conf ${proxyDeployId} production`);
941
- shellExec(`node bin/deploy run ${proxyDeployId} maintenance`);
1153
+ shellExec(`npm start ${proxyDeployId} maintenance`);
942
1154
  };
943
1155
 
1156
+ const getNpmRootPath = () =>
1157
+ shellExec(`npm root -g`, {
1158
+ stdout: true,
1159
+ disableLog: true,
1160
+ silent: true,
1161
+ }).trim();
1162
+
1163
+ const getUnderpostRootPath = () => `${getNpmRootPath()}/underpost`;
1164
+
1165
+ const writeEnv = (envPath, envObj) =>
1166
+ fs.writeFileSync(
1167
+ envPath,
1168
+ Object.keys(envObj)
1169
+ .map((key) => `${key}=${envObj[key]}`)
1170
+ .join(`\n`),
1171
+ 'utf8',
1172
+ );
1173
+
944
1174
  export {
945
1175
  Cmd,
946
1176
  Config,
@@ -967,9 +1197,21 @@ export {
967
1197
  deployRun,
968
1198
  getCronBackUpFolder,
969
1199
  getRestoreCronCmd,
970
- mergeBackUp,
1200
+ mergeFile,
971
1201
  fixDependencies,
972
1202
  getDeployId,
973
1203
  maintenanceMiddleware,
974
1204
  setUpProxyMaintenanceServer,
1205
+ getPathsSSR,
1206
+ buildKindPorts,
1207
+ buildPortProxyRouter,
1208
+ splitFileFactory,
1209
+ getNpmRootPath,
1210
+ getUnderpostRootPath,
1211
+ writeEnv,
1212
+ deployTest,
1213
+ pathPortAssignmentFactory,
1214
+ deployRangePortFactory,
1215
+ awaitDeployMonitor,
1216
+ rebuildConfFactory,
975
1217
  };