underpost 2.8.84 → 2.8.86

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 (128) hide show
  1. package/.env.development +1 -0
  2. package/.env.production +1 -0
  3. package/.env.test +1 -0
  4. package/.github/workflows/{ghpkg.yml → ghpkg.ci.yml} +1 -1
  5. package/.github/workflows/{npmpkg.yml → npmpkg.ci.yml} +1 -1
  6. package/.github/workflows/{publish.yml → publish.ci.yml} +1 -1
  7. package/.github/workflows/{pwa-microservices-template.page.yml → pwa-microservices-template-page.cd.yml} +2 -2
  8. package/.github/workflows/{pwa-microservices-template.test.yml → pwa-microservices-template-test.ci.yml} +1 -1
  9. package/.github/workflows/release.cd.yml +37 -0
  10. package/.vscode/settings.json +0 -1
  11. package/README.md +16 -10
  12. package/bin/build.js +15 -5
  13. package/bin/cyberia0.js +78 -0
  14. package/bin/db.js +1 -3
  15. package/bin/deploy.js +29 -431
  16. package/bin/file.js +26 -9
  17. package/cli.md +102 -61
  18. package/conf.js +1 -1
  19. package/manifests/deployment/{dd-template-development → dd-default-development}/deployment.yaml +16 -16
  20. package/manifests/deployment/{dd-template-development → dd-default-development}/proxy.yaml +3 -3
  21. package/manifests/grafana/deployment.yaml +57 -0
  22. package/manifests/grafana/kustomization.yaml +7 -0
  23. package/manifests/grafana/pvc.yaml +12 -0
  24. package/manifests/grafana/service.yaml +14 -0
  25. package/manifests/maas/gpu-diag.sh +1 -1
  26. package/manifests/maas/ssh-cluster-info.sh +14 -0
  27. package/manifests/prometheus/deployment.yaml +82 -0
  28. package/package.json +4 -7
  29. package/src/api/user/user.router.js +24 -1
  30. package/src/api/user/user.service.js +9 -38
  31. package/src/cli/cluster.js +83 -29
  32. package/src/cli/cron.js +12 -45
  33. package/src/cli/db.js +149 -0
  34. package/src/cli/deploy.js +40 -81
  35. package/src/cli/index.js +29 -6
  36. package/src/cli/monitor.js +9 -16
  37. package/src/cli/repository.js +12 -5
  38. package/src/cli/run.js +175 -7
  39. package/src/cli/ssh.js +32 -0
  40. package/src/client/Default.index.js +7 -5
  41. package/src/client/components/core/Account.js +7 -3
  42. package/src/client/components/core/Chat.js +1 -1
  43. package/src/client/components/core/CommonJs.js +24 -22
  44. package/src/client/components/core/Content.js +12 -12
  45. package/src/client/components/core/Css.js +262 -18
  46. package/src/client/components/core/CssCore.js +8 -8
  47. package/src/client/components/core/Docs.js +14 -61
  48. package/src/client/components/core/DropDown.js +137 -82
  49. package/src/client/components/core/EventsUI.js +92 -5
  50. package/src/client/components/core/Input.js +6 -1
  51. package/src/client/components/core/LoadingAnimation.js +8 -15
  52. package/src/client/components/core/LogIn.js +3 -0
  53. package/src/client/components/core/LogOut.js +1 -1
  54. package/src/client/components/core/Modal.js +601 -137
  55. package/src/client/components/core/NotificationManager.js +2 -2
  56. package/src/client/components/core/ObjectLayerEngine.js +638 -0
  57. package/src/client/components/core/Panel.js +158 -34
  58. package/src/client/components/core/PanelForm.js +12 -3
  59. package/src/client/components/core/Recover.js +6 -3
  60. package/src/client/components/core/Router.js +77 -17
  61. package/src/client/components/core/Scroll.js +65 -120
  62. package/src/client/components/core/SignUp.js +1 -0
  63. package/src/client/components/core/SocketIo.js +3 -3
  64. package/src/client/components/core/Translate.js +6 -2
  65. package/src/client/components/core/VanillaJs.js +48 -5
  66. package/src/client/components/core/Worker.js +3 -1
  67. package/src/client/components/default/CssDefault.js +17 -3
  68. package/src/client/components/default/MenuDefault.js +266 -47
  69. package/src/client/components/default/RoutesDefault.js +8 -14
  70. package/src/client/public/default/android-chrome-144x144.png +0 -0
  71. package/src/client/public/default/android-chrome-192x192.png +0 -0
  72. package/src/client/public/default/android-chrome-256x256.png +0 -0
  73. package/src/client/public/default/android-chrome-36x36.png +0 -0
  74. package/src/client/public/default/android-chrome-48x48.png +0 -0
  75. package/src/client/public/default/android-chrome-72x72.png +0 -0
  76. package/src/client/public/default/android-chrome-96x96.png +0 -0
  77. package/src/client/public/default/apple-touch-icon-114x114-precomposed.png +0 -0
  78. package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
  79. package/src/client/public/default/apple-touch-icon-120x120-precomposed.png +0 -0
  80. package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
  81. package/src/client/public/default/apple-touch-icon-144x144-precomposed.png +0 -0
  82. package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
  83. package/src/client/public/default/apple-touch-icon-152x152-precomposed.png +0 -0
  84. package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
  85. package/src/client/public/default/apple-touch-icon-180x180-precomposed.png +0 -0
  86. package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
  87. package/src/client/public/default/apple-touch-icon-57x57-precomposed.png +0 -0
  88. package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
  89. package/src/client/public/default/apple-touch-icon-60x60-precomposed.png +0 -0
  90. package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
  91. package/src/client/public/default/apple-touch-icon-72x72-precomposed.png +0 -0
  92. package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
  93. package/src/client/public/default/apple-touch-icon-76x76-precomposed.png +0 -0
  94. package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
  95. package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
  96. package/src/client/public/default/apple-touch-icon.png +0 -0
  97. package/src/client/public/default/assets/background/dark.jpg +0 -0
  98. package/src/client/public/default/assets/background/dark.svg +557 -0
  99. package/src/client/public/default/assets/logo/base-icon.png +0 -0
  100. package/src/client/public/default/assets/logo/underpost.gif +0 -0
  101. package/src/client/public/default/assets/mailer/api-user-check.png +0 -0
  102. package/src/client/public/default/assets/mailer/api-user-invalid-token.png +0 -0
  103. package/src/client/public/default/assets/mailer/api-user-recover.png +0 -0
  104. package/src/client/public/default/favicon-16x16.png +0 -0
  105. package/src/client/public/default/favicon-32x32.png +0 -0
  106. package/src/client/public/default/favicon.ico +0 -0
  107. package/src/client/public/default/mstile-144x144.png +0 -0
  108. package/src/client/public/default/mstile-150x150.png +0 -0
  109. package/src/client/public/default/mstile-310x150.png +0 -0
  110. package/src/client/public/default/mstile-310x310.png +0 -0
  111. package/src/client/public/default/mstile-70x70.png +0 -0
  112. package/src/client/public/default/safari-pinned-tab.svg +24 -0
  113. package/src/client/ssr/body/DefaultSplashScreen.js +2 -2
  114. package/src/index.js +9 -1
  115. package/src/mailer/MailerProvider.js +37 -0
  116. package/src/monitor.js +24 -0
  117. package/src/runtime/lampp/Dockerfile +30 -39
  118. package/src/runtime/lampp/Lampp.js +11 -2
  119. package/src/server/client-build-docs.js +205 -0
  120. package/src/server/client-build-live.js +1 -1
  121. package/src/server/client-build.js +16 -166
  122. package/src/server/client-dev-server.js +1 -1
  123. package/src/server/conf.js +14 -277
  124. package/src/server/proxy.js +1 -2
  125. package/src/server/start.js +3 -3
  126. package/src/server/valkey.js +102 -41
  127. package/docker-compose.yml +0 -67
  128. package/prometheus.yml +0 -36
@@ -17,11 +17,11 @@ import dotenv from 'dotenv';
17
17
  import AdmZip from 'adm-zip';
18
18
  import * as dir from 'path';
19
19
  import { shellExec } from './process.js';
20
- import swaggerAutoGen from 'swagger-autogen';
21
20
  import { SitemapStream, streamToPromise } from 'sitemap';
22
21
  import { Readable } from 'stream';
23
22
  import { buildIcons, buildTextImg, getBufferPngText } from './client-icons.js';
24
23
  import Underpost from '../index.js';
24
+ import { buildDocs } from './client-build-docs.js';
25
25
 
26
26
  dotenv.config();
27
27
 
@@ -333,14 +333,7 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
333
333
  minifyBuild || process.env.NODE_ENV === 'production' ? UglifyJS.minify(jsSrc).code : jsSrc,
334
334
  'utf8',
335
335
  );
336
-
337
- // const title = `${metadata && metadata.title ? metadata.title : cap(client)}${
338
- // view.title ? ` | ${view.title}` : view.path !== '/' ? ` | ${titleFormatted(view.path)}` : ''
339
- // }`;
340
-
341
- const title = `${
342
- view.title ? `${view.title} | ` : view.path !== '/' ? `${titleFormatted(view.path)} | ` : ''
343
- }${metadata && metadata.title ? metadata.title : cap(client)}`;
336
+ const title = metadata.title ? metadata.title : title;
344
337
 
345
338
  const canonicalURL = `https://${host}${path}${
346
339
  view.path === '/' ? (path === '/' ? '' : '/') : path === '/' ? `${view.path.slice(1)}/` : `${view.path}/`
@@ -441,27 +434,13 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
441
434
  case 'CyberiaDefaultSplashScreen':
442
435
  case 'NexodevSplashScreen':
443
436
  case 'DefaultSplashScreen':
444
- if (backgroundImage) {
437
+ if (backgroundImage)
445
438
  ssrHeadComponents += SrrComponent({
439
+ ...metadata,
446
440
  backgroundImage: (path === '/' ? path : `${path}/`) + backgroundImage,
447
441
  });
448
- // `data:image/${backgroundImage.split('.').pop()};base64,${fs
449
- // .readFileSync()
450
- // .toString('base64')}`,
451
- break;
452
- } else {
453
- ssrHeadComponents += SrrComponent({ metadata });
454
- break;
455
- const bufferBackgroundImage = await getBufferPngText({
456
- text: ' ',
457
- textColor: metadata?.themeColor ? metadata.themeColor : '#ececec',
458
- size: '100x100',
459
- bgColor: metadata?.themeColor ? metadata.themeColor : '#ececec',
460
- });
461
- ssrHeadComponents += SrrComponent({
462
- backgroundImage: `data:image/png;base64,${bufferBackgroundImage.toString('base64')}`,
463
- });
464
- }
442
+ else ssrHeadComponents += SrrComponent({ metadata });
443
+ break;
465
444
 
466
445
  case 'CyberiaSplashScreenLore': {
467
446
  ssrBodyComponents += SrrComponent({
@@ -557,145 +536,16 @@ Sitemap: https://${host}${path === '/' ? '' : path}/sitemap.xml`,
557
536
  }
558
537
 
559
538
  if (!enableLiveRebuild && !process.argv.includes('l') && !process.argv.includes('deploy') && docsBuild) {
560
- // https://www.pullrequest.com/blog/leveraging-jsdoc-for-better-code-documentation-in-javascript/
561
- // https://jsdoc.app/about-configuring-jsdoc
562
- // https://jsdoc.app/ Block tags
563
-
564
- const jsDocsConfig = JSON.parse(fs.readFileSync(`./jsdoc.json`, 'utf8'));
565
- jsDocsConfig.opts.destination = `./public/${host}${path === '/' ? path : `${path}/`}docs/`;
566
- jsDocsConfig.opts.theme_opts.title = metadata && metadata.title ? metadata.title : undefined;
567
- jsDocsConfig.opts.theme_opts.favicon = `./public/${host}${path === '/' ? path : `${path}/favicon.ico`}`;
568
- fs.writeFileSync(`./jsdoc.json`, JSON.stringify(jsDocsConfig, null, 4), 'utf8');
569
- logger.warn('build jsdoc view', jsDocsConfig.opts.destination);
570
- shellExec(`npm run docs`, { silent: true });
571
-
572
- // coverage
573
- if (!fs.existsSync(`./coverage`)) {
574
- shellExec(`npm test`);
575
- }
576
- const coverageBuildPath = `${jsDocsConfig.opts.destination}/coverage`;
577
- fs.mkdirSync(coverageBuildPath, { recursive: true });
578
- fs.copySync(`./coverage`, coverageBuildPath);
579
-
580
- // uml
581
- // shellExec(`node bin/deploy uml ${host} ${path}`);
582
-
583
- // https://swagger-autogen.github.io/docs/
584
-
585
- const basePath = path === '/' ? `${process.env.BASE_API}` : `/${process.env.BASE_API}`;
586
-
587
- const doc = {
588
- info: {
589
- version: packageData.version, // by default: '1.0.0'
590
- title: metadata?.title ? `${metadata.title}` : 'REST API', // by default: 'REST API'
591
- description: metadata?.description ? metadata.description : '', // by default: ''
592
- },
593
- servers: [
594
- {
595
- url:
596
- process.env.NODE_ENV === 'development'
597
- ? `http://localhost:${port}${path}${basePath}`
598
- : `https://${host}${path}${basePath}`, // by default: 'http://localhost:3000'
599
- description: `${process.env.NODE_ENV} server`, // by default: ''
600
- },
601
- ],
602
- tags: [
603
- // by default: empty Array
604
- {
605
- name: 'user', // Tag name
606
- description: 'User API operations', // Tag description
607
- },
608
- ],
609
- components: {
610
- schemas: {
611
- userRequest: {
612
- username: 'user123',
613
- password: 'Password123',
614
- email: 'user@example.com',
615
- },
616
- userResponse: {
617
- status: 'success',
618
- data: {
619
- token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7Il9pZCI6IjY2YzM3N2Y1N2Y5OWU1OTY5YjgxZG...',
620
- user: {
621
- _id: '66c377f57f99e5969b81de89',
622
- email: 'user@example.com',
623
- emailConfirmed: false,
624
- username: 'user123',
625
- role: 'user',
626
- profileImageId: '66c377f57f99e5969b81de87',
627
- },
628
- },
629
- },
630
- userUpdateResponse: {
631
- status: 'success',
632
- data: {
633
- _id: '66c377f57f99e5969b81de89',
634
- email: 'user@example.com',
635
- emailConfirmed: false,
636
- username: 'user123222',
637
- role: 'user',
638
- profileImageId: '66c377f57f99e5969b81de87',
639
- },
640
- },
641
- userGetResponse: {
642
- status: 'success',
643
- data: {
644
- _id: '66c377f57f99e5969b81de89',
645
- email: 'user@example.com',
646
- emailConfirmed: false,
647
- username: 'user123222',
648
- role: 'user',
649
- profileImageId: '66c377f57f99e5969b81de87',
650
- },
651
- },
652
- userLogInRequest: {
653
- email: 'user@example.com',
654
- password: 'Password123',
655
- },
656
- userBadRequestResponse: {
657
- status: 'error',
658
- message: 'Bad request. Please check your inputs, and try again',
659
- },
660
- },
661
- securitySchemes: {
662
- bearerAuth: {
663
- type: 'http',
664
- scheme: 'bearer',
665
- },
666
- },
667
- },
668
- };
669
-
670
- // plantuml
671
- logger.info('copy plantuml', `${rootClientPath}/docs/plantuml`);
672
- fs.copySync(`./src/client/public/default/plantuml`, `${rootClientPath}/docs/plantuml`);
673
-
674
- logger.warn('build swagger api docs', doc.info);
675
-
676
- const outputFile = `./public/${host}${path === '/' ? path : `${path}/`}swagger-output.json`;
677
- const routes = [];
678
- for (const api of apis) {
679
- if (['user'].includes(api)) routes.push(`./src/api/${api}/${api}.router.js`);
680
- }
681
-
682
- /* NOTE: If you are using the express Router, you must pass in the 'routes' only the
683
- root file where the route starts, such as index.js, app.js, routes.js, etc ... */
684
-
685
- await swaggerAutoGen({ openapi: '3.0.0' })(outputFile, routes, doc);
686
-
687
- const htmlFiles = await fs.readdir(`./public/${host}/docs/engine/${Underpost.version.replace('v', '')}`);
688
- for (const htmlFile of htmlFiles) {
689
- if (htmlFile.match('.html')) {
690
- fs.writeFileSync(
691
- `./public/${host}/docs/engine/${Underpost.version.replace('v', '')}/${htmlFile}`,
692
- fs
693
- .readFileSync(`./public/${host}/docs/engine/${Underpost.version.replace('v', '')}/${htmlFile}`, 'utf8')
694
- .replaceAll('Tutorials', 'References'),
695
- 'utf8',
696
- );
697
- }
698
- }
539
+ await buildDocs({
540
+ host,
541
+ path,
542
+ port,
543
+ metadata,
544
+ apis,
545
+ publicClientId,
546
+ rootClientPath,
547
+ packageData,
548
+ });
699
549
  }
700
550
 
701
551
  if (client) {
@@ -7,7 +7,7 @@ const logger = loggerFactory(import.meta);
7
7
 
8
8
  const createClientDevServer = () => {
9
9
  // process.argv.slice(2).join(' ')
10
- shellExec(`env-cmd -f .env.development node bin/deploy build-full-client ${process.argv.slice(2).join(' ')} l`);
10
+ shellExec(`env-cmd -f .env.development node bin/deploy build-full-client ${process.argv.slice(2).join(' ')}`);
11
11
  shellExec(
12
12
  `env-cmd -f .env.development node src/api ${process.argv[2]}${process.argv[5] ? ` ${process.argv[5]}` : ''}${
13
13
  process.argv.includes('static') ? ' static' : ''
@@ -89,14 +89,22 @@ const Config = {
89
89
  };
90
90
 
91
91
  const loadConf = (deployId, envInput, subConf) => {
92
+ if (deployId === 'current') {
93
+ console.log(process.env.DEPLOY_ID);
94
+ return;
95
+ }
92
96
  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`);
97
+ const path = envInput ?? '.';
98
+ fs.removeSync(`${path}/.env`);
99
+ shellExec(`git checkout ${path}/.env.production`);
100
+ shellExec(`git checkout ${path}/.env.development`);
101
+ shellExec(`git checkout ${path}/.env.test`);
102
+ if (fs.existsSync(`${path}/jsdoc.json`)) shellExec(`git checkout ${path}/jsdoc.json`);
103
+ shellExec(`git checkout ${path}/package.json`);
104
+ shellExec(`git checkout ${path}/package-lock.json`);
98
105
  return;
99
106
  }
107
+ if (!deployId.startsWith('dd-')) deployId = 'dd-default';
100
108
  const folder = fs.existsSync(`./engine-private/replica/${deployId}`)
101
109
  ? `./engine-private/replica/${deployId}`
102
110
  : `./engine-private/conf/${deployId}`;
@@ -763,152 +771,22 @@ const validateTemplatePath = (absolutePath = '') => {
763
771
  return true;
764
772
  };
765
773
 
766
- const deployTest = async (dataDeploy = [{ deployId: 'default' }]) => {
767
- const failed = [];
768
- for (const deploy of dataDeploy) {
769
- const deployServerConfPath = fs.existsSync(`./engine-private/replica/${deploy.deployId}/conf.server.json`)
770
- ? `./engine-private/replica/${deploy.deployId}/conf.server.json`
771
- : `./engine-private/conf/${deploy.deployId}/conf.server.json`;
772
- const serverConf = loadReplicas(JSON.parse(fs.readFileSync(deployServerConfPath, 'utf8')));
773
- let fail = false;
774
- for (const host of Object.keys(serverConf))
775
- for (const path of Object.keys(serverConf[host])) {
776
- const { singleReplica } = serverConf[host][path];
777
- if (singleReplica) continue;
778
- const urlTest = `https://${host}${path}`;
779
- try {
780
- const result = await axios.get(urlTest, { timeout: 10000 });
781
- const test = result.data.split('<title>');
782
- if (test[1])
783
- logger.info('Success deploy', {
784
- ...deploy,
785
- result: test[1].split('</title>')[0],
786
- urlTest,
787
- });
788
- else {
789
- logger.error('Error deploy', {
790
- ...deploy,
791
- result: result.data,
792
- urlTest,
793
- });
794
- fail = true;
795
- }
796
- } catch (error) {
797
- logger.error('Error deploy', {
798
- ...deploy,
799
- message: error.message,
800
- urlTest,
801
- });
802
- fail = true;
803
- }
804
- }
805
- if (fail) failed.push(deploy);
806
- }
807
- return { failed };
808
- };
809
-
810
774
  const awaitDeployMonitor = async (init = false, deltaMs = 1000) => {
811
775
  if (init) fs.writeFileSync(`./tmp/await-deploy`, '', 'utf8');
812
776
  await timer(deltaMs);
813
777
  if (fs.existsSync(`./tmp/await-deploy`)) return await awaitDeployMonitor();
814
778
  };
815
779
 
816
- const getDeployGroupId = () => {
817
- const deployGroupIndexArg = process.argv.findIndex((a) => a.match(`deploy-group:`));
818
- if (deployGroupIndexArg > -1) return process.argv[deployGroupIndexArg].split(':')[1].trim();
819
- return 'dd';
820
- };
821
-
822
780
  const getDeployId = () => {
823
781
  const deployIndexArg = process.argv.findIndex((a) => a.match(`deploy-id:`));
824
782
  if (deployIndexArg > -1) return process.argv[deployIndexArg].split(':')[1].trim();
825
- for (const deployId of process.argv) {
826
- if (fs.existsSync(`./engine-private/conf/${deployId}`)) return deployId;
827
- else if (fs.existsSync(`./engine-private/replica/${deployId}`)) return deployId;
828
- }
829
- return 'default';
783
+ return 'dd-default';
830
784
  };
831
785
 
832
786
  const getCronBackUpFolder = (host = '', path = '') => {
833
787
  return `${host}${path.replace(/\\/g, '/').replace(`/`, '-')}`;
834
788
  };
835
789
 
836
- const execDeploy = async (options = { deployId: 'default' }, currentAttempt = 1) => {
837
- const { deployId } = options;
838
- shellExec(Cmd.delete(deployId));
839
- shellExec(Cmd.conf(deployId));
840
- shellExec(Cmd.run(deployId));
841
- const maxTime = 1000 * 60;
842
- const minTime = 20 * 1000;
843
- const intervalTime = 1000;
844
- return await new Promise(async (resolve) => {
845
- let currentTime = 0;
846
- const attempt = () => {
847
- if (currentTime >= minTime && !fs.existsSync(`./tmp/await-deploy`)) {
848
- clearInterval(processMonitor);
849
- return resolve(true);
850
- }
851
- cliSpinner(
852
- intervalTime,
853
- `[deploy.js] `,
854
- ` Load instance | attempt:${currentAttempt} | elapsed time ${currentTime / 1000}s / ${maxTime / 1000}s`,
855
- 'yellow',
856
- 'material',
857
- );
858
- currentTime += intervalTime;
859
- if (currentTime >= maxTime) {
860
- clearInterval(processMonitor);
861
- return resolve(false);
862
- }
863
- };
864
- const processMonitor = setInterval(attempt, intervalTime);
865
- });
866
- };
867
-
868
- const deployRun = async (dataDeploy, currentAttempt = 1) => {
869
- if (!fs.existsSync(`./tmp`)) fs.mkdirSync(`./tmp`, { recursive: true });
870
- await fixDependencies();
871
- const maxAttempts = 3;
872
- for (const deploy of dataDeploy) {
873
- let currentAttempt = 1;
874
- const attempt = async () => {
875
- const success = await execDeploy(deploy, currentAttempt);
876
- currentAttempt++;
877
- if (!success && currentAttempt <= maxAttempts) await attempt();
878
- };
879
- await attempt();
880
- }
881
- const { failed } = await deployTest(dataDeploy);
882
- if (failed.length > 0) {
883
- for (const deploy of failed) logger.error(deploy.deployId, Cmd.run(deploy.deployId));
884
- if (currentAttempt === maxAttempts) return logger.error(`max deploy attempts exceeded`);
885
- await read({ prompt: 'Press enter to retry failed processes\n' });
886
- currentAttempt++;
887
- await deployRun(failed, currentAttempt);
888
- } else logger.info(`Deploy process successfully`);
889
- };
890
-
891
- const restoreMacroDb = async (deployGroupId = '', deployId = null) => {
892
- const dataDeploy = await getDataDeploy({ deployGroupId, buildSingleReplica: false });
893
- for (const deployGroup of dataDeploy) {
894
- if (deployId && deployGroup.deployId !== deployId) continue;
895
- if (!deployGroup.replicaHost) {
896
- const deployServerConfPath = `./engine-private/conf/${deployGroup.deployId}/conf.server.json`;
897
- const serverConf = JSON.parse(fs.readFileSync(deployServerConfPath, 'utf8'));
898
-
899
- for (const host of Object.keys(serverConf)) {
900
- for (const path of Object.keys(serverConf[host])) {
901
- const { db, singleReplica } = serverConf[host][path];
902
- if (db && !singleReplica) {
903
- const cmd = `node bin/db ${host}${path} import ${deployGroup.deployId} cron`;
904
- shellExec(cmd);
905
- }
906
- }
907
- }
908
- }
909
- }
910
- };
911
-
912
790
  const mergeFile = async (parts = [], outputFilePath) => {
913
791
  await new Promise((resolve) => {
914
792
  splitFile
@@ -970,99 +848,6 @@ const rebuildConfFactory = ({ deployId, valkey, mongo }) => {
970
848
  return { hosts };
971
849
  };
972
850
 
973
- const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deployId: '' }) => {
974
- const { host, path, conf, deployId } = options;
975
- const { runtime, db, git, directory } = conf[host][path];
976
- const { provider, name, user, password = '', backupPath = '' } = db;
977
-
978
- if (['xampp', 'lampp'].includes(runtime)) {
979
- logger.info('Create database', `node bin/db ${host}${path} create ${deployId}`);
980
- shellExec(`node bin/db ${host}${path} create ${deployId}`);
981
- }
982
-
983
- if (git) {
984
- if (directory && !fs.existsSync(directory)) fs.mkdirSync(directory, { recursive: true });
985
-
986
- shellExec(`git clone ${git}`);
987
-
988
- // fs.mkdirSync(`./public/${host}${path}`, { recursive: true });
989
-
990
- if (fs.existsSync(`./${git.split('/').pop()}`))
991
- fs.moveSync(`./${git.split('/').pop()}`, directory ? directory : `./public/${host}${path}`, {
992
- overwrite: true,
993
- });
994
- }
995
-
996
- let cmd, currentBackupTimestamp, baseBackUpPath;
997
-
998
- if (process.argv.includes('cron')) {
999
- baseBackUpPath = `${process.cwd()}/engine-private/cron-backups/${getCronBackUpFolder(host, path)}`;
1000
-
1001
- const files = await fs.readdir(baseBackUpPath, { withFileTypes: true });
1002
-
1003
- currentBackupTimestamp = files
1004
- .map((fileObj) => parseInt(fileObj.name))
1005
- .sort((a, b) => a - b)
1006
- .reverse()[0];
1007
- }
1008
-
1009
- switch (provider) {
1010
- case 'mariadb':
1011
- {
1012
- if (process.argv.includes('cron')) {
1013
- cmd = `mysql -u ${user} -p${password} ${name} < ${baseBackUpPath}/${currentBackupTimestamp}/${name}.sql`;
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
- }
1021
- } else {
1022
- cmd = `mysql -u ${user} -p${password} ${name} < ${
1023
- backupPath ? backupPath : `./engine-private/sql-backups/${name}.sql`
1024
- }`;
1025
- if (
1026
- fs.existsSync(
1027
- `${
1028
- backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
1029
- }/${name}-parths.json`,
1030
- )
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,
1043
- `${
1044
- backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
1045
- }/${name}.sql`,
1046
- );
1047
- }
1048
- }
1049
- }
1050
- break;
1051
-
1052
- case 'mongoose':
1053
- {
1054
- if (process.argv.includes('cron')) {
1055
- cmd = `mongorestore -d ${name} ${baseBackUpPath}/${currentBackupTimestamp}/${name}`;
1056
- } else cmd = `mongorestore -d ${name} ${backupPath ? backupPath : `./engine-private/mongodb-backup/${name}`}`;
1057
- }
1058
- break;
1059
- }
1060
-
1061
- // logger.info('Restore', cmd);
1062
-
1063
- return cmd;
1064
- };
1065
-
1066
851
  const getPathsSSR = (conf) => {
1067
852
  const paths = ['src/client/ssr/Render.js'];
1068
853
  for (const o of conf.head) paths.push(`src/client/ssr/head/${o}.js`);
@@ -1086,37 +871,6 @@ const Cmd = {
1086
871
  }${options?.git ? `--git ` : ''}${deployList} ${jobList}`,
1087
872
  };
1088
873
 
1089
- const fixDependencies = async () => {
1090
- return;
1091
- // sed -i "$line_number s,.*,$new_text," "$file"
1092
- // sed -i "$line_number c \\$new_text" "$file"
1093
- const dep = fs.readFileSync(`./node_modules/peer/dist/module.mjs`, 'utf8');
1094
- const errorLine = `import {WebSocketServer as $hSjDC$WebSocketServer} from "ws";`;
1095
-
1096
- fs.writeFileSync(
1097
- `./node_modules/peer/dist/module.mjs`,
1098
- dep.replaceAll(
1099
- errorLine,
1100
- `import WebSocketServer from "ws";
1101
- let $hSjDC$WebSocketServer = WebSocketServer.Server;`,
1102
- ),
1103
- 'utf8',
1104
- );
1105
- };
1106
-
1107
- const maintenanceMiddleware = (req, res, port, proxyRouter) => {
1108
- if (process.argv.includes('maintenance') && globalThis.defaultHtmlSrcMaintenance) {
1109
- if (req.method.toUpperCase() === 'GET') {
1110
- res.set('Content-Type', 'text/html');
1111
- return res.status(503).send(globalThis.defaultHtmlSrcMaintenance);
1112
- }
1113
- return res.status(503).json({
1114
- status: 'error',
1115
- message: 'Server is under maintenance',
1116
- });
1117
- }
1118
- };
1119
-
1120
874
  const splitFileFactory = async (name, _path) => {
1121
875
  const stats = fs.statSync(_path);
1122
876
  const maxSizeInBytes = 1024 * 1024 * 50; // 50 mb
@@ -1145,14 +899,6 @@ const splitFileFactory = async (name, _path) => {
1145
899
  return false;
1146
900
  };
1147
901
 
1148
- const setUpProxyMaintenanceServer = ({ deployGroupId }) => {
1149
- shellExec(`pm2 kill`);
1150
- shellExec(`node bin/deploy valkey-service`);
1151
- const proxyDeployId = fs.readFileSync(`./engine-private/deploy/${deployGroupId}.proxy`, 'utf8').trim();
1152
- shellExec(`node bin/deploy conf ${proxyDeployId} production`);
1153
- shellExec(`npm start ${proxyDeployId} maintenance`);
1154
- };
1155
-
1156
902
  const getNpmRootPath = () =>
1157
903
  shellExec(`npm root -g`, {
1158
904
  stdout: true,
@@ -1251,17 +997,9 @@ export {
1251
997
  getDataDeploy,
1252
998
  validateTemplatePath,
1253
999
  buildReplicaId,
1254
- restoreMacroDb,
1255
- getDeployGroupId,
1256
- execDeploy,
1257
- deployRun,
1258
1000
  getCronBackUpFolder,
1259
- getRestoreCronCmd,
1260
1001
  mergeFile,
1261
- fixDependencies,
1262
1002
  getDeployId,
1263
- maintenanceMiddleware,
1264
- setUpProxyMaintenanceServer,
1265
1003
  getPathsSSR,
1266
1004
  buildKindPorts,
1267
1005
  buildPortProxyRouter,
@@ -1269,7 +1007,6 @@ export {
1269
1007
  getNpmRootPath,
1270
1008
  getUnderpostRootPath,
1271
1009
  writeEnv,
1272
- deployTest,
1273
1010
  pathPortAssignmentFactory,
1274
1011
  deployRangePortFactory,
1275
1012
  awaitDeployMonitor,
@@ -6,7 +6,7 @@ import dotenv from 'dotenv';
6
6
  import { createProxyMiddleware } from 'http-proxy-middleware';
7
7
  import { loggerFactory, loggerMiddleware } from './logger.js';
8
8
  import { createSslServer, sslRedirectMiddleware } from './ssl.js';
9
- import { buildPortProxyRouter, buildProxyRouter, maintenanceMiddleware } from './conf.js';
9
+ import { buildPortProxyRouter, buildProxyRouter } from './conf.js';
10
10
  import UnderpostStartUp from './start.js';
11
11
 
12
12
  dotenv.config();
@@ -48,7 +48,6 @@ const buildProxy = async () => {
48
48
  onProxyReq: (proxyReq, req, res, options) => {
49
49
  // https://wtools.io/check-http-status-code
50
50
  // http://nexodev.org
51
- maintenanceMiddleware(req, res, port, proxyRouter);
52
51
  sslRedirectMiddleware(req, res, port, proxyRouter);
53
52
  },
54
53
  pathRewrite: {
@@ -79,11 +79,11 @@ class UnderpostStartUp {
79
79
  }
80
80
  }),
81
81
 
82
- async callback(deployId = 'default', env = 'development', options = { build: false, run: false }) {
82
+ async callback(deployId = 'dd-default', env = 'development', options = { build: false, run: false }) {
83
83
  if (options.build === true) await UnderpostStartUp.API.build(deployId, env);
84
84
  if (options.run === true) await UnderpostStartUp.API.run(deployId, env);
85
85
  },
86
- async build(deployId = 'default', env = 'development') {
86
+ async build(deployId = 'dd-default', env = 'development') {
87
87
  const buildBasePath = `/home/dd`;
88
88
  const repoName = `engine-${deployId.split('-')[1]}`;
89
89
  shellExec(`cd ${buildBasePath} && underpost clone underpostnet/${repoName}`);
@@ -100,7 +100,7 @@ class UnderpostStartUp {
100
100
  }
101
101
  shellExec(`node bin/deploy build-full-client ${deployId}`);
102
102
  },
103
- async run(deployId = 'default', env = 'development') {
103
+ async run(deployId = 'dd-default', env = 'development') {
104
104
  const runCmd = env === 'production' ? 'run prod-img' : 'run dev-img';
105
105
  if (fs.existsSync(`./engine-private/replica`)) {
106
106
  const replicas = await fs.readdir(`./engine-private/replica`);