@underpostnet/underpost 2.7.82

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 (290) hide show
  1. package/.dockerignore +14 -0
  2. package/.env.development +6 -0
  3. package/.env.production +6 -0
  4. package/.env.test +6 -0
  5. package/.github/workflows/ghpkg.yml +75 -0
  6. package/.github/workflows/publish.yml +84 -0
  7. package/.github/workflows/pwa-microservices-template.test.yml +30 -0
  8. package/.nycrc +9 -0
  9. package/.prettierignore +13 -0
  10. package/.prettierrc +9 -0
  11. package/.vscode/extensions.json +72 -0
  12. package/.vscode/settings.json +100 -0
  13. package/AUTHORS.md +10 -0
  14. package/CHANGELOG.md +37 -0
  15. package/Dockerfile +90 -0
  16. package/LICENSE +21 -0
  17. package/README.md +96 -0
  18. package/bin/db.js +172 -0
  19. package/bin/deploy.js +674 -0
  20. package/bin/file.js +93 -0
  21. package/bin/index.js +82 -0
  22. package/bin/ssl.js +55 -0
  23. package/bin/util.js +182 -0
  24. package/bin/vs.js +35 -0
  25. package/conf.js +251 -0
  26. package/docker-compose.yml +67 -0
  27. package/jsconfig.json +7 -0
  28. package/jsdoc.json +32 -0
  29. package/nodemon.json +6 -0
  30. package/package.json +134 -0
  31. package/prometheus.yml +36 -0
  32. package/src/api/core/core.controller.js +69 -0
  33. package/src/api/core/core.model.js +11 -0
  34. package/src/api/core/core.router.js +23 -0
  35. package/src/api/core/core.service.js +29 -0
  36. package/src/api/crypto/crypto.controller.js +51 -0
  37. package/src/api/crypto/crypto.model.js +23 -0
  38. package/src/api/crypto/crypto.router.js +20 -0
  39. package/src/api/crypto/crypto.service.js +64 -0
  40. package/src/api/default/default.controller.js +69 -0
  41. package/src/api/default/default.model.js +20 -0
  42. package/src/api/default/default.router.js +23 -0
  43. package/src/api/default/default.service.js +31 -0
  44. package/src/api/file/file.controller.js +53 -0
  45. package/src/api/file/file.model.js +19 -0
  46. package/src/api/file/file.router.js +21 -0
  47. package/src/api/file/file.service.js +80 -0
  48. package/src/api/instance/instance.controller.js +69 -0
  49. package/src/api/instance/instance.model.js +36 -0
  50. package/src/api/instance/instance.router.js +33 -0
  51. package/src/api/instance/instance.service.js +48 -0
  52. package/src/api/test/test.controller.js +59 -0
  53. package/src/api/test/test.model.js +14 -0
  54. package/src/api/test/test.router.js +21 -0
  55. package/src/api/test/test.service.js +35 -0
  56. package/src/api/user/user.build.js +16 -0
  57. package/src/api/user/user.controller.js +70 -0
  58. package/src/api/user/user.model.js +65 -0
  59. package/src/api/user/user.router.js +345 -0
  60. package/src/api/user/user.service.js +479 -0
  61. package/src/api.js +23 -0
  62. package/src/client/Default.index.js +40 -0
  63. package/src/client/components/core/Account.js +290 -0
  64. package/src/client/components/core/AgGrid.js +160 -0
  65. package/src/client/components/core/Auth.js +19 -0
  66. package/src/client/components/core/Badge.js +32 -0
  67. package/src/client/components/core/Blockchain.js +41 -0
  68. package/src/client/components/core/Blog.js +9 -0
  69. package/src/client/components/core/BtnIcon.js +101 -0
  70. package/src/client/components/core/CalendarCore.js +458 -0
  71. package/src/client/components/core/Chat.js +64 -0
  72. package/src/client/components/core/ColorPalette.js +5267 -0
  73. package/src/client/components/core/CommonJs.js +742 -0
  74. package/src/client/components/core/Content.js +193 -0
  75. package/src/client/components/core/Css.js +846 -0
  76. package/src/client/components/core/CssCore.js +817 -0
  77. package/src/client/components/core/D3Chart.js +44 -0
  78. package/src/client/components/core/Docs.js +231 -0
  79. package/src/client/components/core/DropDown.js +164 -0
  80. package/src/client/components/core/EventsUI.js +46 -0
  81. package/src/client/components/core/FileExplorer.js +699 -0
  82. package/src/client/components/core/FullScreen.js +45 -0
  83. package/src/client/components/core/Input.js +346 -0
  84. package/src/client/components/core/JoyStick.js +77 -0
  85. package/src/client/components/core/Keyboard.js +73 -0
  86. package/src/client/components/core/LoadingAnimation.js +178 -0
  87. package/src/client/components/core/LogIn.js +187 -0
  88. package/src/client/components/core/LogOut.js +58 -0
  89. package/src/client/components/core/Logger.js +26 -0
  90. package/src/client/components/core/Modal.js +1612 -0
  91. package/src/client/components/core/NotificationManager.js +84 -0
  92. package/src/client/components/core/Panel.js +613 -0
  93. package/src/client/components/core/PanelForm.js +468 -0
  94. package/src/client/components/core/Polyhedron.js +162 -0
  95. package/src/client/components/core/Recover.js +204 -0
  96. package/src/client/components/core/Responsive.js +53 -0
  97. package/src/client/components/core/RichText.js +51 -0
  98. package/src/client/components/core/Router.js +76 -0
  99. package/src/client/components/core/Scroll.js +34 -0
  100. package/src/client/components/core/SignUp.js +125 -0
  101. package/src/client/components/core/SocketIo.js +72 -0
  102. package/src/client/components/core/Stream.js +113 -0
  103. package/src/client/components/core/ToggleSwitch.js +87 -0
  104. package/src/client/components/core/ToolTip.js +26 -0
  105. package/src/client/components/core/Translate.js +446 -0
  106. package/src/client/components/core/Validator.js +100 -0
  107. package/src/client/components/core/VanillaJs.js +463 -0
  108. package/src/client/components/core/Wallet.js +106 -0
  109. package/src/client/components/core/Webhook.js +25 -0
  110. package/src/client/components/core/Worker.js +282 -0
  111. package/src/client/components/default/CommonDefault.js +29 -0
  112. package/src/client/components/default/CssDefault.js +13 -0
  113. package/src/client/components/default/ElementsDefault.js +38 -0
  114. package/src/client/components/default/LogInDefault.js +41 -0
  115. package/src/client/components/default/LogOutDefault.js +28 -0
  116. package/src/client/components/default/MenuDefault.js +389 -0
  117. package/src/client/components/default/RoutesDefault.js +48 -0
  118. package/src/client/components/default/SettingsDefault.js +16 -0
  119. package/src/client/components/default/SignUpDefault.js +9 -0
  120. package/src/client/components/default/SocketIoDefault.js +54 -0
  121. package/src/client/components/default/TranslateDefault.js +7 -0
  122. package/src/client/public/default/android-chrome-144x144.png +0 -0
  123. package/src/client/public/default/android-chrome-192x192.png +0 -0
  124. package/src/client/public/default/android-chrome-256x256.png +0 -0
  125. package/src/client/public/default/android-chrome-36x36.png +0 -0
  126. package/src/client/public/default/android-chrome-384x384.png +0 -0
  127. package/src/client/public/default/android-chrome-48x48.png +0 -0
  128. package/src/client/public/default/android-chrome-512x512.png +0 -0
  129. package/src/client/public/default/android-chrome-72x72.png +0 -0
  130. package/src/client/public/default/android-chrome-96x96.png +0 -0
  131. package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
  132. package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
  133. package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
  134. package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
  135. package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
  136. package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
  137. package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
  138. package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
  139. package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
  140. package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
  141. package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
  142. package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
  143. package/src/client/public/default/apple-touch-icon.png +0 -0
  144. package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
  145. package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
  146. package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
  147. package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
  148. package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
  149. package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
  150. package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
  151. package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
  152. package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
  153. package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
  154. package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
  155. package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
  156. package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
  157. package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
  158. package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
  159. package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
  160. package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
  161. package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
  162. package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
  163. package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
  164. package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
  165. package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
  166. package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
  167. package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
  168. package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
  169. package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
  170. package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
  171. package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
  172. package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
  173. package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
  174. package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
  175. package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
  176. package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
  177. package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
  178. package/src/client/public/default/assets/background/white.jpg +0 -0
  179. package/src/client/public/default/assets/background/white0-min.jpg +0 -0
  180. package/src/client/public/default/assets/background/white0.jpg +0 -0
  181. package/src/client/public/default/assets/logo/base-icon.png +0 -0
  182. package/src/client/public/default/assets/mailer/api-user-check.png +0 -0
  183. package/src/client/public/default/assets/mailer/api-user-invalid-token.png +0 -0
  184. package/src/client/public/default/assets/mailer/api-user-recover.png +0 -0
  185. package/src/client/public/default/browserconfig.xml +12 -0
  186. package/src/client/public/default/favicon-16x16.png +0 -0
  187. package/src/client/public/default/favicon-32x32.png +0 -0
  188. package/src/client/public/default/favicon-48x48.png +0 -0
  189. package/src/client/public/default/favicon.ico +0 -0
  190. package/src/client/public/default/manifest.webmanifest +69 -0
  191. package/src/client/public/default/mstile-144x144.png +0 -0
  192. package/src/client/public/default/mstile-150x150.png +0 -0
  193. package/src/client/public/default/mstile-310x150.png +0 -0
  194. package/src/client/public/default/mstile-310x310.png +0 -0
  195. package/src/client/public/default/mstile-70x70.png +0 -0
  196. package/src/client/public/default/plantuml/client-conf.svg +1 -0
  197. package/src/client/public/default/plantuml/client-schema.svg +1 -0
  198. package/src/client/public/default/plantuml/cron-conf.svg +1 -0
  199. package/src/client/public/default/plantuml/cron-schema.svg +1 -0
  200. package/src/client/public/default/plantuml/server-conf.svg +1 -0
  201. package/src/client/public/default/plantuml/server-schema.svg +1 -0
  202. package/src/client/public/default/plantuml/ssr-conf.svg +1 -0
  203. package/src/client/public/default/plantuml/ssr-schema.svg +1 -0
  204. package/src/client/public/default/sitemap +148 -0
  205. package/src/client/public/default/yandex-browser-50x50.png +0 -0
  206. package/src/client/public/default/yandex-browser-manifest.json +9 -0
  207. package/src/client/public/doc/favicon.ico +0 -0
  208. package/src/client/public/doc/sitemap +148 -0
  209. package/src/client/public/test/favicon.ico +0 -0
  210. package/src/client/public/test/sitemap +148 -0
  211. package/src/client/services/core/core.service.js +170 -0
  212. package/src/client/services/crypto/crypto.service.js +70 -0
  213. package/src/client/services/default/default.management.js +343 -0
  214. package/src/client/services/default/default.service.js +89 -0
  215. package/src/client/services/file/file.service.js +70 -0
  216. package/src/client/services/instance/instance.management.js +74 -0
  217. package/src/client/services/instance/instance.service.js +89 -0
  218. package/src/client/services/test/test.service.js +70 -0
  219. package/src/client/services/user/user.management.js +50 -0
  220. package/src/client/services/user/user.service.js +89 -0
  221. package/src/client/ssr/Render.js +237 -0
  222. package/src/client/ssr/common/Alert.js +75 -0
  223. package/src/client/ssr/common/SsrCore.js +91 -0
  224. package/src/client/ssr/common/Translate.js +26 -0
  225. package/src/client/ssr/common/Worker.js +28 -0
  226. package/src/client/ssr/components/body/CacheControl.js +114 -0
  227. package/src/client/ssr/components/body/DefaultSplashScreen.js +90 -0
  228. package/src/client/ssr/components/email/DefaultRecoverEmail.js +21 -0
  229. package/src/client/ssr/components/email/DefaultVerifyEmail.js +17 -0
  230. package/src/client/ssr/components/head/Css.js +241 -0
  231. package/src/client/ssr/components/head/DefaultScripts.js +3 -0
  232. package/src/client/ssr/components/head/PwaDefault.js +60 -0
  233. package/src/client/ssr/offline/default.index.js +31 -0
  234. package/src/client/ssr/pages/404.js +12 -0
  235. package/src/client/ssr/pages/500.js +12 -0
  236. package/src/client/sw/default.sw.js +203 -0
  237. package/src/client/sw/template.sw.js +84 -0
  238. package/src/client.build.js +22 -0
  239. package/src/client.dev.js +21 -0
  240. package/src/cron.js +30 -0
  241. package/src/db/DataBaseProvider.js +34 -0
  242. package/src/db/mariadb/MariaDB.js +33 -0
  243. package/src/db/mongo/MongooseDB.js +125 -0
  244. package/src/dns.js +22 -0
  245. package/src/index.js +43 -0
  246. package/src/mailer/EmailRender.js +69 -0
  247. package/src/mailer/MailerProvider.js +96 -0
  248. package/src/proxy.js +22 -0
  249. package/src/runtime/lampp/Lampp.js +115 -0
  250. package/src/runtime/nginx/Nginx.js +3 -0
  251. package/src/runtime/xampp/Xampp.js +49 -0
  252. package/src/server/auth.js +235 -0
  253. package/src/server/backup.js +108 -0
  254. package/src/server/client-build-live.js +98 -0
  255. package/src/server/client-build.js +821 -0
  256. package/src/server/client-dev-server.js +60 -0
  257. package/src/server/client-formatted.js +58 -0
  258. package/src/server/client-icons.js +151 -0
  259. package/src/server/conf.js +883 -0
  260. package/src/server/cron.js +35 -0
  261. package/src/server/dns.js +89 -0
  262. package/src/server/downloader.js +42 -0
  263. package/src/server/logger.js +190 -0
  264. package/src/server/network.js +122 -0
  265. package/src/server/peer.js +33 -0
  266. package/src/server/process.js +66 -0
  267. package/src/server/prompt-optimizer.js +28 -0
  268. package/src/server/proxy.js +118 -0
  269. package/src/server/runtime.js +461 -0
  270. package/src/server/ssl.js +120 -0
  271. package/src/server.js +25 -0
  272. package/src/ws/IoInterface.js +45 -0
  273. package/src/ws/IoServer.js +39 -0
  274. package/src/ws/core/channels/core.ws.chat.js +23 -0
  275. package/src/ws/core/channels/core.ws.mailer.js +35 -0
  276. package/src/ws/core/channels/core.ws.stream.js +31 -0
  277. package/src/ws/core/core.ws.connection.js +28 -0
  278. package/src/ws/core/core.ws.emit.js +14 -0
  279. package/src/ws/core/core.ws.server.js +24 -0
  280. package/src/ws/core/management/core.ws.chat.js +8 -0
  281. package/src/ws/core/management/core.ws.mailer.js +16 -0
  282. package/src/ws/core/management/core.ws.stream.js +8 -0
  283. package/src/ws/default/channels/default.ws.main.js +16 -0
  284. package/src/ws/default/default.ws.connection.js +22 -0
  285. package/src/ws/default/default.ws.emit.js +14 -0
  286. package/src/ws/default/default.ws.server.js +20 -0
  287. package/src/ws/default/management/default.ws.main.js +8 -0
  288. package/startup.js +11 -0
  289. package/supervisord-openssh-server.conf +5 -0
  290. package/test/api.test.js +60 -0
@@ -0,0 +1,883 @@
1
+ import fs from 'fs-extra';
2
+ import dotenv from 'dotenv';
3
+ import { cap, capFirst, getCapVariableName, newInstance, range, timer } from '../client/components/core/CommonJs.js';
4
+ import * as dir from 'path';
5
+ import cliProgress from 'cli-progress';
6
+ import cliSpinners from 'cli-spinners';
7
+ import logUpdate from 'log-update';
8
+ import colors from 'colors';
9
+ import { loggerFactory } from './logger.js';
10
+ import { shellExec, shellCd } from './process.js';
11
+ import { DefaultConf } from '../../conf.js';
12
+ import ncp from 'copy-paste';
13
+ import read from 'read';
14
+ import splitFile from 'split-file';
15
+ import axios from 'axios';
16
+ import https from 'https';
17
+
18
+ // axios.defaults.baseURL = BASE_URL;
19
+
20
+ const httpsAgent = new https.Agent({
21
+ rejectUnauthorized: false,
22
+ });
23
+
24
+ axios.defaults.httpsAgent = httpsAgent;
25
+
26
+ colors.enable();
27
+ dotenv.config();
28
+
29
+ const logger = loggerFactory(import.meta);
30
+
31
+ // monitoring: https://app.pm2.io/
32
+
33
+ const Config = {
34
+ default: DefaultConf,
35
+ build: async function (options = { folder: '' }) {
36
+ if (!fs.existsSync(`./tmp`)) fs.mkdirSync(`./tmp`, { recursive: true });
37
+ fs.writeFileSync(`./tmp/await-deploy`, '', 'utf8');
38
+ if (fs.existsSync(`./engine-private/conf/${process.argv[2]}`)) return loadConf(process.argv[2]);
39
+ if (fs.existsSync(`./engine-private/replica/${process.argv[2]}`)) return loadConf(process.argv[2]);
40
+
41
+ if (process.argv[2] === 'deploy') return;
42
+
43
+ if (process.argv[2] === 'proxy') {
44
+ this.default.server = {};
45
+ for (const deployId of process.argv[3].split(',')) {
46
+ let confPath = `./engine-private/conf/${deployId}/conf.server.json`;
47
+ const privateConfDevPath = `./engine-private/conf/${deployId}/conf.server.dev.${process.argv[4]}.json`;
48
+ const confDevPath = fs.existsSync(privateConfDevPath)
49
+ ? privateConfDevPath
50
+ : `./engine-private/conf/${deployId}/conf.server.dev.json`;
51
+
52
+ if (process.env.NODE_ENV === 'development' && fs.existsSync(confDevPath)) confPath = confDevPath;
53
+ const serverConf = JSON.parse(fs.readFileSync(confPath, 'utf8'));
54
+
55
+ for (const host of Object.keys(loadReplicas(serverConf))) {
56
+ if (serverConf[host]['/'])
57
+ this.default.server[host] = {
58
+ ...this.default.server[host],
59
+ ...serverConf[host],
60
+ };
61
+ else
62
+ this.default.server[host] = {
63
+ ...serverConf[host],
64
+ ...this.default.server[host],
65
+ };
66
+ }
67
+ }
68
+ }
69
+ if (!options || !options.folder)
70
+ options = {
71
+ ...options,
72
+ folder: `./conf`,
73
+ };
74
+ if (!fs.existsSync(options.folder)) fs.mkdirSync(options.folder, { recursive: true });
75
+ for (const confType of Object.keys(this.default)) {
76
+ fs.writeFileSync(
77
+ `${options.folder}/conf.${confType}.json`,
78
+ JSON.stringify(this.default[confType], null, 4),
79
+ 'utf8',
80
+ );
81
+ }
82
+ },
83
+ };
84
+
85
+ const loadConf = (deployId) => {
86
+ const folder = fs.existsSync(`./engine-private/replica/${deployId}`)
87
+ ? `./engine-private/replica/${deployId}`
88
+ : `./engine-private/conf/${deployId}`;
89
+ if (!fs.existsSync(`./conf`)) fs.mkdirSync(`./conf`);
90
+ if (!fs.existsSync(`./tmp`)) fs.mkdirSync(`./tmp`, { recursive: true });
91
+ const isValidDeployId = fs.existsSync(`${folder}`);
92
+ for (const typeConf of Object.keys(Config.default)) {
93
+ let srcConf = isValidDeployId
94
+ ? fs.readFileSync(`${folder}/conf.${typeConf}.json`, 'utf8')
95
+ : JSON.stringify(Config.default[typeConf]);
96
+ if (process.env.NODE_ENV === 'development' && typeConf === 'server') {
97
+ const devConfPath = `${folder}/conf.${typeConf}.dev${process.argv[3] ? `.${process.argv[3]}` : ''}.json`;
98
+ if (fs.existsSync(devConfPath)) srcConf = fs.readFileSync(devConfPath, 'utf8');
99
+ }
100
+ if (typeConf === 'server') srcConf = JSON.stringify(loadReplicas(JSON.parse(srcConf)), null, 4);
101
+ fs.writeFileSync(`./conf/conf.${typeConf}.json`, srcConf, 'utf8');
102
+ }
103
+ if (!isValidDeployId) return {};
104
+ fs.writeFileSync(`./.env.production`, fs.readFileSync(`${folder}/.env.production`, 'utf8'), 'utf8');
105
+ fs.writeFileSync(`./.env.development`, fs.readFileSync(`${folder}/.env.development`, 'utf8'), 'utf8');
106
+ fs.writeFileSync(`./.env.test`, fs.readFileSync(`${folder}/.env.test`, 'utf8'), 'utf8');
107
+ if (process.env.NODE_ENV) {
108
+ fs.writeFileSync(`./.env`, fs.readFileSync(`${folder}/.env.${process.env.NODE_ENV}`, 'utf8'), 'utf8');
109
+ const env = dotenv.parse(fs.readFileSync(`${folder}/.env.${process.env.NODE_ENV}`, 'utf8'));
110
+ process.env = {
111
+ ...process.env,
112
+ ...env,
113
+ };
114
+ }
115
+ fs.writeFileSync(`./package.json`, fs.readFileSync(`${folder}/package.json`, 'utf8'), 'utf8');
116
+ return { folder, deployId };
117
+ };
118
+
119
+ const loadReplicas = (confServer) => {
120
+ for (const host of Object.keys(confServer)) {
121
+ for (const path of Object.keys(confServer[host])) {
122
+ const { replicas, singleReplica } = confServer[host][path];
123
+ if (replicas && (process.argv[2] === 'proxy' || !singleReplica))
124
+ for (const replicaPath of replicas) {
125
+ confServer[host][replicaPath] = newInstance(confServer[host][path]);
126
+ delete confServer[host][replicaPath].replicas;
127
+ }
128
+ }
129
+ }
130
+ return confServer;
131
+ };
132
+
133
+ const cloneConf = async (
134
+ { toOptions, fromOptions },
135
+ fromDefaultOptions = { deployId: 'dd-default', clientId: 'default' },
136
+ ) => {
137
+ if (!fromOptions.deployId) fromOptions.deployId = fromDefaultOptions.deployId;
138
+ if (!fromOptions.clientId) fromOptions.clientId = fromDefaultOptions.clientId;
139
+
140
+ const confFromFolder = `./engine-private/conf/${fromOptions.deployId}`;
141
+ const confToFolder = `./engine-private/conf/${toOptions.deployId}`;
142
+
143
+ const toClientVariableName = getCapVariableName(toOptions.clientId);
144
+ const fromClientVariableName = getCapVariableName(fromOptions.clientId);
145
+
146
+ const formattedSrc = (dataConf) =>
147
+ JSON.stringify(dataConf, null, 4)
148
+ .replaceAll(fromClientVariableName, toClientVariableName)
149
+ .replaceAll(fromOptions.clientId, toOptions.clientId);
150
+
151
+ const isMergeConf = fs.existsSync(confToFolder);
152
+ if (!isMergeConf) fs.mkdirSync(confToFolder, { recursive: true });
153
+
154
+ fs.writeFileSync(
155
+ `${confToFolder}/.env.production`,
156
+ fs.readFileSync(`${confFromFolder}/.env.production`, 'utf8'),
157
+ 'utf8',
158
+ );
159
+ fs.writeFileSync(
160
+ `${confToFolder}/.env.development`,
161
+ fs.readFileSync(`${confFromFolder}/.env.development`, 'utf8'),
162
+ 'utf8',
163
+ );
164
+ fs.writeFileSync(`${confToFolder}/.env.test`, fs.readFileSync(`${confFromFolder}/.env.test`, 'utf8'), 'utf8');
165
+
166
+ for (const confTypeId of ['server', 'client', 'cron', 'ssr']) {
167
+ const confFromData = JSON.parse(fs.readFileSync(`${confFromFolder}/conf.${confTypeId}.json`, 'utf8'));
168
+ fs.writeFileSync(`${confToFolder}/conf.${confTypeId}.json`, formattedSrc(confFromData), 'utf8');
169
+ }
170
+
171
+ const packageData = JSON.parse(fs.readFileSync(`${confFromFolder}/package.json`, 'utf8'));
172
+ packageData.scripts.start = packageData.scripts.start.replaceAll(fromOptions.deployId, toOptions.deployId);
173
+ fs.writeFileSync(`${confToFolder}/package.json`, JSON.stringify(packageData, null, 4), 'utf8');
174
+ };
175
+
176
+ const addClientConf = async (
177
+ { toOptions, fromOptions },
178
+ fromDefaultOptions = { deployId: 'dd-default', clientId: 'default' },
179
+ ) => {
180
+ if (!fromOptions.deployId) fromOptions.deployId = fromDefaultOptions.deployId;
181
+ if (!fromOptions.clientId) fromOptions.clientId = fromDefaultOptions.clientId;
182
+
183
+ const confFromFolder = `./engine-private/conf/${fromOptions.deployId}`;
184
+ const confToFolder = `./engine-private/conf/${toOptions.deployId}`;
185
+
186
+ const toClientConf = JSON.parse(fs.readFileSync(`${confToFolder}/conf.client.json`, 'utf8'));
187
+ const fromClientConf = JSON.parse(fs.readFileSync(`${confFromFolder}/conf.client.json`, 'utf8'));
188
+
189
+ const toClientVariableName = getCapVariableName(toOptions.clientId);
190
+ const fromClientVariableName = getCapVariableName(fromOptions.clientId);
191
+
192
+ const { host, path } = toOptions;
193
+
194
+ toClientConf[fromOptions.clientId] = fromClientConf[fromOptions.clientId];
195
+
196
+ fs.writeFileSync(`${confToFolder}/conf.client.json`, JSON.stringify(toClientConf, null, 4), 'utf8');
197
+
198
+ const toServerConf = JSON.parse(fs.readFileSync(`${confToFolder}/conf.server.json`, 'utf8'));
199
+ const fromServerConf = JSON.parse(fs.readFileSync(`${confToFolder}/conf.server.json`, 'utf8'));
200
+
201
+ toServerConf[host][path].client = fromOptions.clientId;
202
+ toServerConf[host][path].runtime = 'nodejs';
203
+ toServerConf[host][path].apis = fromClientConf[fromOptions.clientId].services;
204
+
205
+ fs.writeFileSync(`${confToFolder}/conf.server.json`, JSON.stringify(toServerConf, null, 4), 'utf8');
206
+
207
+ const fromSsrConf = JSON.parse(fs.readFileSync(`${confFromFolder}/conf.ssr.json`, 'utf8'));
208
+ const toSsrConf = JSON.parse(fs.readFileSync(`${confToFolder}/conf.ssr.json`, 'utf8'));
209
+
210
+ toSsrConf[fromClientVariableName] = fromSsrConf[fromClientVariableName];
211
+
212
+ fs.writeFileSync(`${confToFolder}/conf.ssr.json`, JSON.stringify(toSsrConf, null, 4), 'utf8');
213
+ };
214
+
215
+ const buildClientSrc = async (
216
+ { toOptions, fromOptions },
217
+ fromDefaultOptions = { deployId: 'dd-default', clientId: 'default' },
218
+ ) => {
219
+ if (!fromOptions.deployId) fromOptions.deployId = fromDefaultOptions.deployId;
220
+ if (!fromOptions.clientId) fromOptions.clientId = fromDefaultOptions.clientId;
221
+
222
+ const confFromFolder = `./src/client/components/${fromOptions.clientId}`;
223
+ const confToFolder = `./src/client/components/${toOptions.clientId}`;
224
+
225
+ const toClientVariableName = getCapVariableName(toOptions.clientId);
226
+ const fromClientVariableName = getCapVariableName(fromOptions.clientId);
227
+
228
+ const formattedSrc = (src) =>
229
+ src.replaceAll(fromClientVariableName, toClientVariableName).replaceAll(fromOptions.clientId, toOptions.clientId);
230
+
231
+ const isMergeConf = fs.existsSync(confToFolder);
232
+ if (!isMergeConf) fs.mkdirSync(confToFolder, { recursive: true });
233
+
234
+ const files = await fs.readdir(confFromFolder, { recursive: true });
235
+ for (const relativePath of files) {
236
+ const fromFilePath = dir.resolve(`${confFromFolder}/${relativePath}`);
237
+ const toFilePath = dir.resolve(`${confToFolder}/${relativePath}`);
238
+
239
+ fs.writeFileSync(formattedSrc(toFilePath), formattedSrc(fs.readFileSync(fromFilePath, 'utf8')), 'utf8');
240
+ }
241
+
242
+ fs.writeFileSync(
243
+ `./src/client/ssr/components/head/${toClientVariableName}Scripts.js`,
244
+ formattedSrc(fs.readFileSync(`./src/client/ssr/components/head/${fromClientVariableName}Scripts.js`, 'utf8')),
245
+ 'utf8',
246
+ );
247
+
248
+ fs.writeFileSync(
249
+ `./src/client/${toClientVariableName}.js`,
250
+ formattedSrc(fs.readFileSync(`./src/client/${fromClientVariableName}.js`, 'utf8')),
251
+ 'utf8',
252
+ );
253
+
254
+ fs.copySync(`./src/client/public/${fromOptions.clientId}`, `./src/client/public/${toOptions.clientId}`);
255
+ };
256
+
257
+ const buildApiSrc = async (
258
+ { toOptions, fromOptions },
259
+ fromDefaultOptions = { apiId: 'default', deployId: 'dd-default', clientId: 'default' },
260
+ ) => {
261
+ if (!fromOptions.apiId) fromOptions.apiId = fromDefaultOptions.apiId;
262
+ if (!fromOptions.deployId) fromOptions.deployId = fromDefaultOptions.deployId;
263
+ if (!fromOptions.clientId) fromOptions.clientId = fromDefaultOptions.clientId;
264
+
265
+ const toClientVariableName = getCapVariableName(toOptions.apiId);
266
+ const fromClientVariableName = getCapVariableName(fromOptions.apiId);
267
+
268
+ const formattedSrc = (src) =>
269
+ src.replaceAll(fromClientVariableName, toClientVariableName).replaceAll(fromOptions.apiId, toOptions.apiId);
270
+
271
+ const apiToFolder = `./src/api/${toOptions.apiId}`;
272
+ const apiFromFolder = `./src/api/${fromOptions.apiId}`;
273
+
274
+ const isMergeConf = fs.existsSync(apiToFolder);
275
+ if (!isMergeConf) fs.mkdirSync(apiToFolder, { recursive: true });
276
+
277
+ for (const srcApiType of ['model', 'controller', 'service', 'router']) {
278
+ fs.writeFileSync(
279
+ `${apiToFolder}/${toOptions.apiId}.${srcApiType}.js`,
280
+ formattedSrc(fs.readFileSync(`${apiFromFolder}/${fromOptions.apiId}.${srcApiType}.js`, 'utf8')),
281
+ 'utf8',
282
+ );
283
+ }
284
+
285
+ fs.mkdirSync(`./src/client/services/${toOptions.apiId}`, { recursive: true });
286
+ if (fs.existsSync(`./src/client/services/${fromOptions.apiId}/${fromOptions.apiId}.service.js`))
287
+ fs.writeFileSync(
288
+ `./src/client/services/${toOptions.apiId}/${toOptions.apiId}.service.js`,
289
+ formattedSrc(
290
+ fs.readFileSync(`./src/client/services/${fromOptions.apiId}/${fromOptions.apiId}.service.js`, 'utf8'),
291
+ ),
292
+ 'utf8',
293
+ );
294
+ return;
295
+ if (fs.existsSync(`./src/client/services/${fromOptions.apiId}/${fromOptions.apiId}.management.js`))
296
+ fs.writeFileSync(
297
+ `./src/client/services/${toOptions.apiId}/${toOptions.apiId}.management.js`,
298
+ formattedSrc(
299
+ fs.readFileSync(`./src/client/services/${fromOptions.apiId}/${fromOptions.apiId}.management.js`, 'utf8'),
300
+ ),
301
+ 'utf8',
302
+ );
303
+ };
304
+
305
+ const addApiConf = async (
306
+ { toOptions, fromOptions },
307
+ fromDefaultOptions = { apiId: 'default', deployId: 'dd-default', clientId: 'default' },
308
+ ) => {
309
+ if (!fromOptions.apiId) fromOptions.apiId = fromDefaultOptions.apiId;
310
+ if (!fromOptions.deployId) fromOptions.deployId = fromDefaultOptions.deployId;
311
+ if (!fromOptions.clientId) fromOptions.clientId = fromDefaultOptions.clientId;
312
+
313
+ const toClientVariableName = getCapVariableName(toOptions.apiId);
314
+ const fromClientVariableName = getCapVariableName(fromOptions.apiId);
315
+
316
+ const confFromFolder = `./engine-private/conf/${fromOptions.deployId}`;
317
+ const confToFolder = `./engine-private/conf/${toOptions.deployId}`;
318
+
319
+ const confServer = JSON.parse(fs.readFileSync(`${confToFolder}/conf.server.json`, 'utf8'));
320
+ for (const host of Object.keys(confServer))
321
+ for (const path of Object.keys(confServer[host]))
322
+ if (confServer[host][path].apis) confServer[host][path].apis.push(toOptions.apiId);
323
+ fs.writeFileSync(`${confToFolder}/conf.server.json`, JSON.stringify(confServer, null, 4), 'utf8');
324
+
325
+ const confClient = JSON.parse(fs.readFileSync(`${confToFolder}/conf.client.json`, 'utf8'));
326
+ confClient[toOptions.clientId].services.push(toOptions.apiId);
327
+ fs.writeFileSync(`${confToFolder}/conf.client.json`, JSON.stringify(confClient, null, 4), 'utf8');
328
+ };
329
+
330
+ const addWsConf = async (
331
+ { toOptions, fromOptions },
332
+ fromDefaultOptions = { wsId: 'default', deployId: 'dd-default', host: 'default.net', paths: '/' },
333
+ ) => {
334
+ if (!fromOptions.wsId) fromOptions.wsId = fromDefaultOptions.wsId;
335
+ if (!fromOptions.deployId) fromOptions.deployId = fromDefaultOptions.deployId;
336
+ if (!fromOptions.host) fromOptions.host = fromDefaultOptions.host;
337
+ if (!fromOptions.paths) fromOptions.paths = fromDefaultOptions.paths;
338
+
339
+ const toClientVariableName = getCapVariableName(toOptions.apiId);
340
+ const fromClientVariableName = getCapVariableName(fromOptions.apiId);
341
+
342
+ const confFromFolder = `./engine-private/conf/${fromOptions.deployId}`;
343
+ const confToFolder = `./engine-private/conf/${toOptions.deployId}`;
344
+
345
+ const paths = toOptions.paths.split(',');
346
+
347
+ const confServer = JSON.parse(fs.readFileSync(`${confToFolder}/conf.server.json`, 'utf8'));
348
+ for (const host of Object.keys(confServer))
349
+ for (const path of Object.keys(confServer[host]))
350
+ if (host === toOptions.host && paths.includes(path) && confServer[host][path])
351
+ confServer[host][path].ws = toOptions.wsId;
352
+ fs.writeFileSync(`${confToFolder}/conf.server.json`, JSON.stringify(confServer, null, 4), 'utf8');
353
+ };
354
+
355
+ const buildWsSrc = async (
356
+ { toOptions, fromOptions },
357
+ fromDefaultOptions = { wsId: 'default', deployId: 'dd-default', host: 'default.net', paths: '/' },
358
+ ) => {
359
+ if (!fromOptions.wsId) fromOptions.wsId = fromDefaultOptions.wsId;
360
+ if (!fromOptions.deployId) fromOptions.deployId = fromDefaultOptions.deployId;
361
+ if (!fromOptions.host) fromOptions.host = fromDefaultOptions.host;
362
+ if (!fromOptions.paths) fromOptions.paths = fromDefaultOptions.paths;
363
+
364
+ const toClientVariableName = getCapVariableName(toOptions.wsId);
365
+ const fromClientVariableName = getCapVariableName(fromOptions.wsId);
366
+
367
+ const confFromFolder = `./src/ws/${fromOptions.wsId}`;
368
+ const confToFolder = `./src/ws/${toOptions.wsId}`;
369
+
370
+ const paths = toOptions.paths.split(',');
371
+
372
+ const formattedSrc = (src) =>
373
+ src.replaceAll(fromClientVariableName, toClientVariableName).replaceAll(fromOptions.wsId, toOptions.wsId);
374
+
375
+ const files = await fs.readdir(confFromFolder, { recursive: true });
376
+ for (const relativePath of files) {
377
+ const fromFilePath = dir.resolve(`${confFromFolder}/${relativePath}`);
378
+ const toFilePath = dir.resolve(`${confToFolder}/${relativePath}`);
379
+
380
+ if (fs.lstatSync(fromFilePath).isDirectory() && !fs.existsSync(formattedSrc(toFilePath)))
381
+ fs.mkdirSync(formattedSrc(toFilePath), { recursive: true });
382
+
383
+ if (fs.lstatSync(fromFilePath).isFile() && !fs.existsSync(formattedSrc(toFilePath))) {
384
+ fs.writeFileSync(formattedSrc(toFilePath), formattedSrc(fs.readFileSync(fromFilePath, 'utf8')), 'utf8');
385
+ }
386
+ }
387
+ };
388
+
389
+ const cloneSrcComponents = async ({ toOptions, fromOptions }) => {
390
+ const toClientVariableName = getCapVariableName(toOptions.componentsFolder);
391
+ const fromClientVariableName = getCapVariableName(fromOptions.componentsFolder);
392
+
393
+ const formattedSrc = (src) =>
394
+ src
395
+ .replaceAll(fromClientVariableName, toClientVariableName)
396
+ .replaceAll(fromOptions.componentsFolder, toOptions.componentsFolder);
397
+
398
+ const confFromFolder = `./src/client/components/${fromOptions.componentsFolder}`;
399
+ const confToFolder = `./src/client/components/${toOptions.componentsFolder}`;
400
+
401
+ fs.mkdirSync(confToFolder, { recursive: true });
402
+
403
+ const files = await fs.readdir(confFromFolder);
404
+ for (const relativePath of files) {
405
+ const fromFilePath = dir.resolve(`${confFromFolder}/${relativePath}`);
406
+ const toFilePath = dir.resolve(`${confToFolder}/${relativePath}`);
407
+
408
+ fs.writeFileSync(formattedSrc(toFilePath), formattedSrc(fs.readFileSync(fromFilePath, 'utf8')), 'utf8');
409
+ }
410
+ };
411
+
412
+ const buildProxyRouter = () => {
413
+ const confServer = JSON.parse(fs.readFileSync(`./conf/conf.server.json`, 'utf8'));
414
+ let currentPort = parseInt(process.env.PORT) + 1;
415
+ const proxyRouter = {};
416
+ const singleReplicaHosts = [];
417
+ for (const host of Object.keys(confServer)) {
418
+ for (const path of Object.keys(confServer[host])) {
419
+ if (confServer[host][path].singleReplica && !singleReplicaHosts.includes(host)) {
420
+ singleReplicaHosts.push(host);
421
+ currentPort++;
422
+ continue;
423
+ }
424
+ confServer[host][path].port = newInstance(currentPort);
425
+ for (const port of confServer[host][path].proxy) {
426
+ if (!(port in proxyRouter)) proxyRouter[port] = {};
427
+ proxyRouter[port][`${host}${path}`] = {
428
+ // target: `http://${host}:${confServer[host][path].port}${path}`,
429
+ target: `http://localhost:${confServer[host][path].port - singleReplicaHosts.length}`,
430
+ // target: `http://127.0.0.1:${confServer[host][path].port}`,
431
+ proxy: confServer[host][path].proxy,
432
+ redirect: confServer[host][path].redirect,
433
+ host,
434
+ path,
435
+ };
436
+ }
437
+ currentPort++;
438
+ if (confServer[host][path].peer) {
439
+ const peerPath = path === '/' ? `/peer` : `${path}/peer`;
440
+ confServer[host][peerPath] = newInstance(confServer[host][path]);
441
+ confServer[host][peerPath].port = newInstance(currentPort);
442
+ for (const port of confServer[host][path].proxy) {
443
+ if (!(port in proxyRouter)) proxyRouter[port] = {};
444
+ proxyRouter[port][`${host}${peerPath}`] = {
445
+ // target: `http://${host}:${confServer[host][peerPath].port}${peerPath}`,
446
+ target: `http://localhost:${confServer[host][peerPath].port - singleReplicaHosts.length}`,
447
+ // target: `http://127.0.0.1:${confServer[host][peerPath].port}`,
448
+ proxy: confServer[host][peerPath].proxy,
449
+ host,
450
+ path: peerPath,
451
+ };
452
+ }
453
+ currentPort++;
454
+ }
455
+ }
456
+ }
457
+ return proxyRouter;
458
+ };
459
+
460
+ const cliBar = async (time = 5000) => {
461
+ // create new progress bar
462
+ const b = new cliProgress.SingleBar({
463
+ format: 'Delay | {bar} | {percentage}% || {value}/{total} Chunks || Speed: {speed}',
464
+ barCompleteChar: '\u2588',
465
+ barIncompleteChar: '\u2591',
466
+ hideCursor: true,
467
+ });
468
+
469
+ const maxValueDisplay = 200;
470
+ const minValueDisplay = 0;
471
+ const steps = 10;
472
+ const incrementValue = 200 / steps;
473
+ const delayTime = time / steps;
474
+ // initialize the bar - defining payload token "speed" with the default value "N/A"
475
+ b.start(maxValueDisplay, minValueDisplay, {
476
+ speed: 'N/A',
477
+ });
478
+
479
+ // update values
480
+ // b1.increment();
481
+ // b1.update(20);
482
+
483
+ for (const step of range(1, steps)) {
484
+ b.increment(incrementValue);
485
+ await timer(delayTime);
486
+ }
487
+
488
+ // stop the bar
489
+ b.stop();
490
+ };
491
+
492
+ const cliSpinner = async (time = 5000, message0, message1, color, type = 'dots') => {
493
+ const { frames, interval } = cliSpinners[type];
494
+ const steps = parseInt(time / interval);
495
+ let index = 0;
496
+ for (const step of range(1, steps)) {
497
+ const msg = `${message0 ? message0 : ''}${frames[index]}${message1 ? message1 : ''}`;
498
+ logUpdate(color ? msg[color] : msg);
499
+ await timer(interval);
500
+ index++;
501
+ if (index === frames.length) index = 0;
502
+ }
503
+ };
504
+
505
+ const buildReplicaId = ({ deployId, replica }) => `${deployId}-${replica.slice(1)}`;
506
+
507
+ const getDataDeploy = (
508
+ options = { buildSingleReplica: false, deployGroupId: '', deployId: '', disableSyncEnvPort: false },
509
+ ) => {
510
+ let dataDeploy = JSON.parse(fs.readFileSync(`./engine-private/deploy/${options.deployGroupId}.json`, 'utf8'));
511
+
512
+ if (options.deployId) dataDeploy = dataDeploy.filter((d) => d === options.deployId);
513
+
514
+ dataDeploy = dataDeploy.map((deployId) => {
515
+ return {
516
+ deployId,
517
+ };
518
+ });
519
+
520
+ if (options && options.buildSingleReplica && fs.existsSync(`./engine-private/replica`))
521
+ fs.removeSync(`./engine-private/replica`);
522
+
523
+ let buildDataDeploy = [];
524
+ for (const deployObj of dataDeploy) {
525
+ const serverConf = loadReplicas(
526
+ JSON.parse(fs.readFileSync(`./engine-private/conf/${deployObj.deployId}/conf.server.json`, 'utf8')),
527
+ );
528
+ let replicaDataDeploy = [];
529
+ for (const host of Object.keys(serverConf))
530
+ for (const path of Object.keys(serverConf[host])) {
531
+ if (serverConf[host][path].replicas && serverConf[host][path].singleReplica) {
532
+ if (options && options.buildSingleReplica) shellExec(Cmd.replica(deployObj.deployId, host, path));
533
+ replicaDataDeploy = replicaDataDeploy.concat(
534
+ serverConf[host][path].replicas.map((r) => {
535
+ return {
536
+ deployId: buildReplicaId({ deployId: deployObj.deployId, replica: r }),
537
+ replicaHost: host,
538
+ };
539
+ }),
540
+ );
541
+ }
542
+ }
543
+ buildDataDeploy.push(deployObj);
544
+ if (replicaDataDeploy.length > 0) buildDataDeploy = buildDataDeploy.concat(replicaDataDeploy);
545
+ }
546
+
547
+ const enableSyncEnvPort = !options.disableSyncEnvPort && options.buildSingleReplica;
548
+ if (enableSyncEnvPort) shellExec(Cmd.syncPorts(options.deployGroupId));
549
+
550
+ logger.info('buildDataDeploy', { buildDataDeploy, enableSyncEnvPort });
551
+
552
+ return buildDataDeploy;
553
+ };
554
+
555
+ const validateTemplatePath = (absolutePath = '') => {
556
+ const host = 'default.net';
557
+ const path = '/';
558
+ const client = 'default';
559
+ const ssr = 'Default';
560
+ const confServer = DefaultConf.server[host][path];
561
+ const confClient = DefaultConf.client[client];
562
+ const confSsr = DefaultConf.ssr[ssr];
563
+ const clients = Object.keys(confClient).concat(['core', 'test', 'default']);
564
+
565
+ if (absolutePath.match('src/api') && !confServer.apis.find((p) => absolutePath.match(`src/api/${p}/`))) {
566
+ return false;
567
+ }
568
+ if (
569
+ absolutePath.match('src/client/services/') &&
570
+ !clients.find((p) => absolutePath.match(`src/client/services/${p}/`))
571
+ ) {
572
+ return false;
573
+ }
574
+ if (absolutePath.match('src/client/public/') && !clients.find((p) => absolutePath.match(`src/client/public/${p}/`))) {
575
+ return false;
576
+ }
577
+ if (
578
+ absolutePath.match('src/client/components/') &&
579
+ !clients.find((p) => absolutePath.match(`src/client/components/${p}/`))
580
+ ) {
581
+ return false;
582
+ }
583
+ if (absolutePath.match('src/client/sw/') && !clients.find((p) => absolutePath.match(`src/client/sw/${p}.sw.js`))) {
584
+ return false;
585
+ }
586
+ if (
587
+ absolutePath.match('src/client/ssr/components/body') &&
588
+ !confSsr.body.find((p) => absolutePath.match(`src/client/ssr/components/body/${p}.js`))
589
+ ) {
590
+ return false;
591
+ }
592
+ if (
593
+ absolutePath.match('src/client/ssr/components/head') &&
594
+ !confSsr.head.find((p) => absolutePath.match(`src/client/ssr/components/head/${p}.js`))
595
+ ) {
596
+ return false;
597
+ }
598
+ if (absolutePath.match('hardhat/')) return false;
599
+ if (
600
+ absolutePath.match('/client') &&
601
+ absolutePath.match('.index.js') &&
602
+ !absolutePath.match('/offline') &&
603
+ !clients.find((p) => absolutePath.match(`src/client/${capFirst(p)}.index.js`))
604
+ ) {
605
+ return false;
606
+ }
607
+ if (absolutePath.match('src/ws/') && !clients.find((p) => absolutePath.match(`src/ws/${p}/`))) {
608
+ return false;
609
+ }
610
+ return true;
611
+ };
612
+
613
+ const deployTest = async (dataDeploy) => {
614
+ const failed = [];
615
+ for (const deploy of dataDeploy) {
616
+ const deployServerConfPath = fs.existsSync(`./engine-private/replica/${deploy.deployId}/conf.server.json`)
617
+ ? `./engine-private/replica/${deploy.deployId}/conf.server.json`
618
+ : `./engine-private/conf/${deploy.deployId}/conf.server.json`;
619
+ const serverConf = loadReplicas(JSON.parse(fs.readFileSync(deployServerConfPath, 'utf8')));
620
+ let fail = false;
621
+ for (const host of Object.keys(serverConf))
622
+ for (const path of Object.keys(serverConf[host])) {
623
+ const { singleReplica } = serverConf[host][path];
624
+ if (singleReplica) continue;
625
+ const urlTest = `https://${host}${path}`;
626
+ try {
627
+ const result = await axios.get(urlTest);
628
+ const test = result.data.split('<title>');
629
+ if (test[1])
630
+ logger.info('Success deploy', {
631
+ ...deploy,
632
+ result: test[1].split('</title>')[0],
633
+ urlTest,
634
+ });
635
+ else {
636
+ logger.error('Error deploy', {
637
+ ...deploy,
638
+ result: result.data,
639
+ urlTest,
640
+ });
641
+ fail = true;
642
+ }
643
+ } catch (error) {
644
+ logger.error('Error deploy', {
645
+ ...deploy,
646
+ message: error.message,
647
+ urlTest,
648
+ });
649
+ fail = true;
650
+ }
651
+ }
652
+ if (fail) failed.push(deploy);
653
+ }
654
+ return { failed };
655
+ };
656
+
657
+ const getDeployGroupId = () => {
658
+ const deployGroupIndexArg = process.argv.findIndex((a) => a.match(`deploy-group:`));
659
+ if (deployGroupIndexArg > -1) return process.argv[deployGroupIndexArg].split(':')[1].trim();
660
+ return 'dd';
661
+ };
662
+
663
+ const getCronBackUpFolder = (host = '', path = '') => {
664
+ return `${host}${path.replace(/\\/g, '/').replace(`/`, '-')}`;
665
+ };
666
+
667
+ const execDeploy = async (options = { deployId: 'default' }) => {
668
+ const { deployId } = options;
669
+ shellExec(Cmd.delete(deployId));
670
+ shellExec(Cmd.conf(deployId));
671
+ shellExec(Cmd.run(deployId));
672
+ return await new Promise(async (resolve) => {
673
+ const maxTime = 1000 * 60 * 5;
674
+ const minTime = 10000 * 2;
675
+ const intervalTime = 1000;
676
+ let currentTime = 0;
677
+ const attempt = () => {
678
+ if (currentTime >= minTime && !fs.existsSync(`./tmp/await-deploy`)) {
679
+ clearInterval(processMonitor);
680
+ return resolve(true);
681
+ }
682
+ cliSpinner(
683
+ intervalTime,
684
+ `[deploy.js] `,
685
+ ` Load instance | elapsed time ${currentTime / 1000}s / ${maxTime / 1000}s`,
686
+ 'yellow',
687
+ 'material',
688
+ );
689
+ currentTime += intervalTime;
690
+ if (currentTime >= maxTime) return resolve(false);
691
+ };
692
+ const processMonitor = setInterval(attempt, intervalTime);
693
+ });
694
+ };
695
+
696
+ const deployRun = async (dataDeploy, reset) => {
697
+ if (!fs.existsSync(`./tmp`)) fs.mkdirSync(`./tmp`, { recursive: true });
698
+ if (reset) fs.writeFileSync(`./tmp/runtime-router.json`, '{}', 'utf8');
699
+ await fixDependencies();
700
+ for (const deploy of dataDeploy) await execDeploy(deploy);
701
+ const { failed } = await deployTest(dataDeploy);
702
+ if (failed.length > 0) {
703
+ for (const deploy of failed) logger.error(deploy.deployId, Cmd.run(deploy.deployId));
704
+ await read({ prompt: 'Press enter to retry failed processes\n' });
705
+ await deployRun(failed);
706
+ } else logger.info(`Deploy process successfully`);
707
+ };
708
+
709
+ const restoreMacroDb = async (deployGroupId = '') => {
710
+ const dataDeploy = await getDataDeploy({ deployGroupId, buildSingleReplica: false });
711
+ for (const deployGroup of dataDeploy) {
712
+ if (!deployGroup.replicaHost) {
713
+ const deployServerConfPath = `./engine-private/conf/${deployGroup.deployId}/conf.server.json`;
714
+ const serverConf = JSON.parse(fs.readFileSync(deployServerConfPath, 'utf8'));
715
+
716
+ for (const host of Object.keys(serverConf)) {
717
+ for (const path of Object.keys(serverConf[host])) {
718
+ const { db, singleReplica } = serverConf[host][path];
719
+ if (db && !singleReplica) {
720
+ const cmd = `node bin/db ${host}${path} import ${deployGroup.deployId} cron`;
721
+ shellExec(cmd);
722
+ }
723
+ }
724
+ }
725
+ }
726
+ }
727
+ };
728
+
729
+ const mergeBackUp = async (baseBackJsonPath, outputFilePath) => {
730
+ const names = JSON.parse(fs.readFileSync(baseBackJsonPath, 'utf8')).map((p) =>
731
+ p.replaceAll(`\\`, '/').replaceAll('C:/', '/').replaceAll('c:/', '/'),
732
+ );
733
+ await new Promise((resolve) => {
734
+ splitFile
735
+ .mergeFiles(names, outputFilePath)
736
+ .then(() => {
737
+ resolve();
738
+ })
739
+ .catch((err) => {
740
+ console.log('Error: ', err);
741
+ resolve();
742
+ });
743
+ });
744
+ };
745
+
746
+ const getRestoreCronCmd = async (options = { host: '', path: '', conf: {}, deployId: '' }) => {
747
+ const { host, path, conf, deployId } = options;
748
+ const { runtime, db, git, directory } = conf[host][path];
749
+ const { provider, name, user, password = '', backupPath = '' } = db;
750
+
751
+ if (['xampp', 'lampp'].includes(runtime)) {
752
+ logger.info('Create database', `node bin/db ${host}${path} create ${deployId}`);
753
+ shellExec(`node bin/db ${host}${path} create ${deployId}`);
754
+ }
755
+
756
+ if (git) {
757
+ if (directory && !fs.existsSync(directory)) fs.mkdirSync(directory, { recursive: true });
758
+
759
+ shellExec(`git clone ${git}`);
760
+
761
+ // fs.mkdirSync(`./public/${host}${path}`, { recursive: true });
762
+
763
+ if (fs.existsSync(`./${git.split('/').pop()}`))
764
+ fs.moveSync(`./${git.split('/').pop()}`, directory ? directory : `./public/${host}${path}`, {
765
+ overwrite: true,
766
+ });
767
+ }
768
+
769
+ let cmd, currentBackupTimestamp, baseBackUpPath;
770
+
771
+ if (process.argv.includes('cron')) {
772
+ baseBackUpPath = `${process.cwd()}/engine-private/cron-backups/${getCronBackUpFolder(host, path)}`;
773
+
774
+ const files = await fs.readdir(baseBackUpPath, { withFileTypes: true });
775
+
776
+ currentBackupTimestamp = files
777
+ .map((fileObj) => parseInt(fileObj.name))
778
+ .sort((a, b) => a - b)
779
+ .reverse()[0];
780
+ }
781
+
782
+ switch (provider) {
783
+ case 'mariadb':
784
+ {
785
+ if (process.argv.includes('cron')) {
786
+ cmd = `mysql -u ${user} -p${password} ${name} < ${baseBackUpPath}/${currentBackupTimestamp}/${name}.sql`;
787
+ if (fs.existsSync(`${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`))
788
+ await mergeBackUp(
789
+ `${baseBackUpPath}/${currentBackupTimestamp}/${name}-parths.json`,
790
+ `${baseBackUpPath}/${currentBackupTimestamp}/${name}.sql`,
791
+ );
792
+ } else {
793
+ cmd = `mysql -u ${user} -p${password} ${name} < ${
794
+ backupPath ? backupPath : `./engine-private/sql-backups/${name}.sql`
795
+ }`;
796
+ if (
797
+ fs.existsSync(
798
+ `${
799
+ backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
800
+ }/${name}-parths.json`,
801
+ )
802
+ )
803
+ await mergeBackUp(
804
+ `${
805
+ backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
806
+ }/${name}-parths.json`,
807
+ `${
808
+ backupPath ? backupPath.split('/').slice(0, -1).join('/') : `./engine-private/sql-backups`
809
+ }/${name}.sql`,
810
+ );
811
+ }
812
+ }
813
+ break;
814
+
815
+ case 'mongoose':
816
+ {
817
+ if (process.argv.includes('cron')) {
818
+ cmd = `mongorestore -d ${name} ${baseBackUpPath}/${currentBackupTimestamp}/${name}`;
819
+ } else cmd = `mongorestore -d ${name} ${backupPath ? backupPath : `./engine-private/mongodb-backup/${name}`}`;
820
+ }
821
+ break;
822
+ }
823
+
824
+ // logger.info('Restore', cmd);
825
+
826
+ return cmd;
827
+ };
828
+
829
+ const Cmd = {
830
+ delete: (deployId) => `pm2 delete ${deployId}`,
831
+ run: (deployId) => `node bin/deploy run ${deployId}`,
832
+ build: (deployId) => `node bin/deploy build-full-client ${deployId}${process.argv.includes('l') ? ' l' : ''}`,
833
+ conf: (deployId, env) => `node bin/deploy conf ${deployId} ${env ? env : 'production'}`,
834
+ replica: (deployId, host, path) => `node bin/deploy build-single-replica ${deployId} ${host} ${path}`,
835
+ syncPorts: (deployGroupId) => `node bin/deploy sync-env-port ${deployGroupId}`,
836
+ };
837
+
838
+ const fixDependencies = async () => {
839
+ // sed -i "$line_number s,.*,$new_text," "$file"
840
+ // sed -i "$line_number c \\$new_text" "$file"
841
+ const dep = fs.readFileSync(`./node_modules/peer/dist/module.mjs`, 'utf8');
842
+ const errorLine = `import {WebSocketServer as $hSjDC$WebSocketServer} from "ws";`;
843
+
844
+ fs.writeFileSync(
845
+ `./node_modules/peer/dist/module.mjs`,
846
+ dep.replaceAll(
847
+ errorLine,
848
+ `import WebSocketServer from "ws";
849
+ let $hSjDC$WebSocketServer = WebSocketServer.Server;`,
850
+ ),
851
+ 'utf8',
852
+ );
853
+ };
854
+
855
+ export {
856
+ Cmd,
857
+ Config,
858
+ loadConf,
859
+ loadReplicas,
860
+ cloneConf,
861
+ getCapVariableName,
862
+ buildClientSrc,
863
+ buildApiSrc,
864
+ addApiConf,
865
+ addClientConf,
866
+ addWsConf,
867
+ buildWsSrc,
868
+ cloneSrcComponents,
869
+ buildProxyRouter,
870
+ cliBar,
871
+ cliSpinner,
872
+ getDataDeploy,
873
+ validateTemplatePath,
874
+ buildReplicaId,
875
+ restoreMacroDb,
876
+ getDeployGroupId,
877
+ execDeploy,
878
+ deployRun,
879
+ getCronBackUpFolder,
880
+ getRestoreCronCmd,
881
+ mergeBackUp,
882
+ fixDependencies,
883
+ };