underpost 2.8.885 → 2.8.886

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 (66) hide show
  1. package/.env.production +3 -0
  2. package/.github/workflows/ghpkg.ci.yml +1 -1
  3. package/.github/workflows/npmpkg.ci.yml +1 -1
  4. package/.github/workflows/publish.ci.yml +5 -5
  5. package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -1
  6. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  7. package/CHANGELOG.md +145 -1
  8. package/Dockerfile +1 -1
  9. package/README.md +3 -3
  10. package/bin/build.js +18 -9
  11. package/bin/deploy.js +93 -187
  12. package/cli.md +2 -2
  13. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  14. package/manifests/deployment/dd-test-development/deployment.yaml +54 -54
  15. package/manifests/deployment/dd-test-development/proxy.yaml +4 -4
  16. package/manifests/lxd/underpost-setup.sh +5 -5
  17. package/package.json +3 -3
  18. package/scripts/ssl.sh +164 -0
  19. package/src/cli/baremetal.js +7 -7
  20. package/src/cli/cloud-init.js +1 -1
  21. package/src/cli/cluster.js +10 -3
  22. package/src/cli/cron.js +1 -1
  23. package/src/cli/db.js +1 -1
  24. package/src/cli/deploy.js +33 -1
  25. package/src/cli/fs.js +2 -2
  26. package/src/cli/image.js +7 -0
  27. package/src/cli/monitor.js +33 -1
  28. package/src/cli/run.js +315 -51
  29. package/src/cli/script.js +32 -0
  30. package/src/cli/secrets.js +34 -0
  31. package/src/cli/test.js +42 -1
  32. package/src/client/components/core/Css.js +0 -8
  33. package/src/client/components/core/windowGetDimensions.js +229 -162
  34. package/src/index.js +2 -2
  35. package/src/mailer/MailerProvider.js +1 -0
  36. package/src/runtime/express/Express.js +12 -4
  37. package/src/runtime/lampp/Dockerfile +1 -1
  38. package/src/server/backup.js +20 -0
  39. package/src/server/client-build-live.js +12 -10
  40. package/src/server/client-build.js +136 -91
  41. package/src/server/client-dev-server.js +16 -2
  42. package/src/server/client-icons.js +19 -0
  43. package/src/server/conf.js +470 -60
  44. package/src/server/dns.js +184 -42
  45. package/src/server/downloader.js +65 -24
  46. package/src/server/object-layer.js +260 -162
  47. package/src/server/peer.js +2 -8
  48. package/src/server/proxy.js +93 -76
  49. package/src/server/runtime.js +15 -16
  50. package/src/server/ssr.js +4 -4
  51. package/src/server/tls.js +251 -0
  52. package/src/server/valkey.js +11 -10
  53. package/src/ws/IoInterface.js +2 -1
  54. package/src/ws/IoServer.js +2 -1
  55. package/src/ws/core/core.ws.connection.js +1 -1
  56. package/src/ws/core/core.ws.emit.js +1 -1
  57. package/src/ws/core/core.ws.server.js +1 -1
  58. package/manifests/maas/lxd-preseed.yaml +0 -32
  59. package/src/server/ssl.js +0 -108
  60. /package/{manifests/maas → scripts}/device-scan.sh +0 -0
  61. /package/{manifests/maas → scripts}/gpu-diag.sh +0 -0
  62. /package/{manifests/maas → scripts}/maas-setup.sh +0 -0
  63. /package/{manifests/maas → scripts}/nat-iptables.sh +0 -0
  64. /package/{manifests/maas → scripts}/nvim.sh +0 -0
  65. /package/{manifests/maas → scripts}/snap-clean.sh +0 -0
  66. /package/{manifests/maas → scripts}/ssh-cluster-info.sh +0 -0
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Provides utilities for building, loading, and managing server configurations,
3
+ * deployment contexts, and service configurations (API, Client, WS).
4
+ * @module src/server/conf.js
5
+ * @namespace ServerConfBuilder
6
+ */
7
+
1
8
  import fs from 'fs-extra';
2
9
  import dotenv from 'dotenv';
3
10
  import {
@@ -22,18 +29,45 @@ dotenv.config();
22
29
 
23
30
  const logger = loggerFactory(import.meta);
24
31
 
32
+ /**
33
+ * @class Config
34
+ * @description Manages the configuration of the server.
35
+ * This class provides a set of static methods to automate various
36
+ * infrastructure operations, including NFS management, control server setup,
37
+ * and system provisioning for different architectures.
38
+ * @memberof ServerConfBuilder
39
+ */
25
40
  const Config = {
41
+ /**
42
+ * @method default
43
+ * @description The default configuration of the server.
44
+ * @memberof ServerConfBuilder
45
+ */
26
46
  default: DefaultConf,
47
+ /**
48
+ * @method build
49
+ * @description Builds the configuration of the server.
50
+ * @param {string} [deployContext='dd-default'] - The deploy context.
51
+ * @param {string} [deployList=''] - The deploy list.
52
+ * @param {string} [subConf=''] - The sub configuration.
53
+ * @memberof ServerConfBuilder
54
+ */
27
55
  build: async function (deployContext = 'dd-default', deployList, subConf) {
28
56
  if (process.argv[2] && typeof process.argv[2] === 'string' && process.argv[2].startsWith('dd-'))
29
57
  deployContext = process.argv[2];
30
58
  if (!subConf && process.argv[3] && typeof process.argv[3] === 'string') subConf = process.argv[3];
31
59
  if (!fs.existsSync(`./tmp`)) fs.mkdirSync(`./tmp`, { recursive: true });
32
60
  UnderpostRootEnv.API.set('await-deploy', new Date().toISOString());
33
- if (fs.existsSync(`./engine-private/replica/${deployContext}`)) return loadConf(deployContext, subConf);
34
- else if (deployContext.startsWith('dd-')) return loadConf(deployContext, subConf);
35
- if (deployContext === 'proxy') Config.buildProxy(deployList, subConf);
61
+ if (deployContext.startsWith('dd-')) loadConf(deployContext, subConf);
62
+ if (deployContext === 'proxy') await Config.buildProxy(deployList, subConf);
36
63
  },
64
+ /**
65
+ * @method deployIdFactory
66
+ * @description Creates a new deploy ID.
67
+ * @param {string} [deployId='dd-default'] - The deploy ID.
68
+ * @param {object} [options={ cluster: false }] - The options.
69
+ * @memberof ServerConfBuilder
70
+ */
37
71
  deployIdFactory: function (deployId = 'dd-default', options = { cluster: false }) {
38
72
  if (!deployId.startsWith('dd-')) deployId = `dd-${deployId}`;
39
73
 
@@ -102,43 +136,72 @@ const Config = {
102
136
 
103
137
  return { deployIdFolder: folder, deployId };
104
138
  },
139
+ /**
140
+ * @method buildTmpConf
141
+ * @description Builds the temporary configuration of the server.
142
+ * @param {string} [folder='./conf'] - The folder.
143
+ * @memberof ServerConfBuilder
144
+ */
105
145
  buildTmpConf: function (folder = './conf') {
106
146
  for (const confType of Object.keys(this.default))
107
147
  fs.writeFileSync(`${folder}/conf.${confType}.json`, JSON.stringify(this.default[confType], null, 4), 'utf8');
108
148
  },
109
- buildProxy: function (deployList = 'dd-default', subConf = '') {
149
+ /**
150
+ * @method buildProxyByDeployId
151
+ * @description Builds the proxy by deploy ID.
152
+ * @param {string} [deployId='dd-default'] - The deploy ID.
153
+ * @param {string} [subConf=''] - The sub configuration.
154
+ * @memberof ServerConfBuilder
155
+ */
156
+ buildProxyByDeployId: function (deployId = 'dd-default', subConf = '') {
157
+ let confPath = `./engine-private/conf/${deployId}/conf.server.json`;
158
+ const privateConfDevPath = fs.existsSync(`./engine-private/replica/${deployId}/conf.server.json`)
159
+ ? `./engine-private/replica/${deployId}/conf.server.json`
160
+ : `./engine-private/conf/${deployId}/conf.server.dev.${subConf}.json`;
161
+ const confDevPath = fs.existsSync(privateConfDevPath)
162
+ ? privateConfDevPath
163
+ : `./engine-private/conf/${deployId}/conf.server.dev.json`;
164
+
165
+ if (fs.existsSync(confDevPath)) confPath = confDevPath;
166
+ const serverConf = JSON.parse(fs.readFileSync(confPath, 'utf8'));
167
+
168
+ for (const host of Object.keys(loadReplicas(serverConf)))
169
+ this.default.server[host] = {
170
+ ...this.default.server[host],
171
+ ...serverConf[host],
172
+ };
173
+ },
174
+ /**
175
+ * @method buildProxy
176
+ * @description Builds the proxy.
177
+ * @param {string} [deployList='dd-default'] - The deploy list.
178
+ * @param {string} [subConf=''] - The sub configuration.
179
+ * @memberof ServerConfBuilder
180
+ */
181
+ buildProxy: async function (deployList = 'dd-default', subConf = '') {
110
182
  if (!deployList) deployList = process.argv[3];
111
183
  if (!subConf) subConf = process.argv[4];
112
184
  this.default.server = {};
113
185
  for (const deployId of deployList.split(',')) {
114
- let confPath = `./engine-private/conf/${deployId}/conf.server.json`;
115
- const privateConfDevPath = fs.existsSync(`./engine-private/replica/${deployId}/conf.server.json`)
116
- ? `./engine-private/replica/${deployId}/conf.server.json`
117
- : `./engine-private/conf/${deployId}/conf.server.dev.${subConf}.json`;
118
- const confDevPath = fs.existsSync(privateConfDevPath)
119
- ? privateConfDevPath
120
- : `./engine-private/conf/${deployId}/conf.server.dev.json`;
121
-
122
- if (process.env.NODE_ENV === 'development' && fs.existsSync(confDevPath)) confPath = confDevPath;
123
- const serverConf = JSON.parse(fs.readFileSync(confPath, 'utf8'));
124
-
125
- for (const host of Object.keys(loadReplicas(serverConf))) {
126
- if (serverConf[host]['/'])
127
- this.default.server[host] = {
128
- ...this.default.server[host],
129
- ...serverConf[host],
130
- };
131
- else
132
- this.default.server[host] = {
133
- ...serverConf[host],
134
- ...this.default.server[host],
135
- };
186
+ this.buildProxyByDeployId(deployId, subConf);
187
+ if (fs.existsSync(`./engine-private/replica`)) {
188
+ const singleReplicas = await fs.readdir(`./engine-private/replica`);
189
+ for (let replica of singleReplicas) {
190
+ if (replica.startsWith(deployId)) this.buildProxyByDeployId(replica, subConf);
191
+ }
136
192
  }
137
193
  }
138
194
  this.buildTmpConf();
139
195
  },
140
196
  };
141
197
 
198
+ /**
199
+ * @method loadConf
200
+ * @description Loads the configuration of the server.
201
+ * @param {string} [deployId='dd-default'] - The deploy ID.
202
+ * @param {string} [subConf=''] - The sub configuration.
203
+ * @memberof ServerConfBuilder
204
+ */
142
205
  const loadConf = (deployId = 'dd-default', subConf) => {
143
206
  if (deployId === 'current') {
144
207
  console.log(process.env.DEPLOY_ID);
@@ -164,7 +227,7 @@ const loadConf = (deployId = 'dd-default', subConf) => {
164
227
 
165
228
  for (const typeConf of Object.keys(Config.default)) {
166
229
  let srcConf = fs.readFileSync(`${folder}/conf.${typeConf}.json`, 'utf8');
167
- if (process.env.NODE_ENV === 'development' && typeConf === 'server') {
230
+ if (process.env.NODE_ENV === 'development' && typeConf === 'server' && subConf) {
168
231
  const devConfPath = `${folder}/conf.${typeConf}.dev${subConf ? `.${subConf}` : ''}.json`;
169
232
  if (fs.existsSync(devConfPath)) srcConf = fs.readFileSync(devConfPath, 'utf8');
170
233
  }
@@ -194,6 +257,12 @@ const loadConf = (deployId = 'dd-default', subConf) => {
194
257
  return { folder, deployId };
195
258
  };
196
259
 
260
+ /**
261
+ * @method loadReplicas
262
+ * @description Loads the replicas of the server.
263
+ * @param {object} confServer - The server configuration.
264
+ * @memberof ServerConfBuilder
265
+ */
197
266
  const loadReplicas = (confServer) => {
198
267
  for (const host of Object.keys(confServer)) {
199
268
  for (const path of Object.keys(confServer[host])) {
@@ -210,6 +279,14 @@ const loadReplicas = (confServer) => {
210
279
  return confServer;
211
280
  };
212
281
 
282
+ /**
283
+ * @method cloneConf
284
+ * @description Clones the configuration of the server.
285
+ * @param {object} toOptions - The options for the target configuration.
286
+ * @param {object} fromOptions - The options for the source configuration.
287
+ * @param {object} [fromDefaultOptions={ deployId: 'dd-default', clientId: 'default' }] - The default options for the source configuration.
288
+ * @memberof ServerConfBuilder
289
+ */
213
290
  const cloneConf = async (
214
291
  { toOptions, fromOptions },
215
292
  fromDefaultOptions = { deployId: 'dd-default', clientId: 'default' },
@@ -253,6 +330,14 @@ const cloneConf = async (
253
330
  fs.writeFileSync(`${confToFolder}/package.json`, JSON.stringify(packageData, null, 4), 'utf8');
254
331
  };
255
332
 
333
+ /**
334
+ * @method addClientConf
335
+ * @description Adds the client configuration to the server.
336
+ * @param {object} toOptions - The options for the target configuration.
337
+ * @param {object} fromOptions - The options for the source configuration.
338
+ * @param {object} [fromDefaultOptions={ deployId: 'dd-default', clientId: 'default' }] - The default options for the source configuration.
339
+ * @memberof ServerConfBuilder
340
+ */
256
341
  const addClientConf = async (
257
342
  { toOptions, fromOptions },
258
343
  fromDefaultOptions = { deployId: 'dd-default', clientId: 'default' },
@@ -292,6 +377,14 @@ const addClientConf = async (
292
377
  fs.writeFileSync(`${confToFolder}/conf.ssr.json`, JSON.stringify(toSsrConf, null, 4), 'utf8');
293
378
  };
294
379
 
380
+ /**
381
+ * @method buildClientSrc
382
+ * @description Builds the client source code.
383
+ * @param {object} toOptions - The options for the target configuration.
384
+ * @param {object} fromOptions - The options for the source configuration.
385
+ * @param {object} [fromDefaultOptions={ deployId: 'dd-default', clientId: 'default' }] - The default options for the source configuration.
386
+ * @memberof ServerConfBuilder
387
+ */
295
388
  const buildClientSrc = async (
296
389
  { toOptions, fromOptions },
297
390
  fromDefaultOptions = { deployId: 'dd-default', clientId: 'default' },
@@ -334,6 +427,14 @@ const buildClientSrc = async (
334
427
  fs.copySync(`./src/client/public/${fromOptions.clientId}`, `./src/client/public/${toOptions.clientId}`);
335
428
  };
336
429
 
430
+ /**
431
+ * @method buildApiSrc
432
+ * @description Builds the API source code.
433
+ * @param {object} toOptions - The options for the target configuration.
434
+ * @param {object} fromOptions - The options for the source configuration.
435
+ * @param {object} [fromDefaultOptions={ apiId: 'default', deployId: 'dd-default', clientId: 'default' }] - The default options for the source configuration.
436
+ * @memberof ServerConfBuilder
437
+ */
337
438
  const buildApiSrc = async (
338
439
  { toOptions, fromOptions },
339
440
  fromDefaultOptions = { apiId: 'default', deployId: 'dd-default', clientId: 'default' },
@@ -371,17 +472,16 @@ const buildApiSrc = async (
371
472
  ),
372
473
  'utf8',
373
474
  );
374
- return;
375
- if (fs.existsSync(`./src/client/services/${fromOptions.apiId}/${fromOptions.apiId}.management.js`))
376
- fs.writeFileSync(
377
- `./src/client/services/${toOptions.apiId}/${toOptions.apiId}.management.js`,
378
- formattedSrc(
379
- fs.readFileSync(`./src/client/services/${fromOptions.apiId}/${fromOptions.apiId}.management.js`, 'utf8'),
380
- ),
381
- 'utf8',
382
- );
383
475
  };
384
476
 
477
+ /**
478
+ * @method addApiConf
479
+ * @description Adds the API configuration to the server.
480
+ * @param {object} toOptions - The options for the target configuration.
481
+ * @param {object} fromOptions - The options for the source configuration.
482
+ * @param {object} [fromDefaultOptions={ apiId: 'default', deployId: 'dd-default', clientId: 'default' }] - The default options for the source configuration.
483
+ * @memberof ServerConfBuilder
484
+ */
385
485
  const addApiConf = async (
386
486
  { toOptions, fromOptions },
387
487
  fromDefaultOptions = { apiId: 'default', deployId: 'dd-default', clientId: 'default' },
@@ -407,6 +507,14 @@ const addApiConf = async (
407
507
  fs.writeFileSync(`${confToFolder}/conf.client.json`, JSON.stringify(confClient, null, 4), 'utf8');
408
508
  };
409
509
 
510
+ /**
511
+ * @method addWsConf
512
+ * @description Adds the WebSocket configuration to the server.
513
+ * @param {object} toOptions - The options for the target configuration.
514
+ * @param {object} fromOptions - The options for the source configuration.
515
+ * @param {object} [fromDefaultOptions={ wsId: 'default', deployId: 'dd-default', host: 'default.net', paths: '/' }] - The default options for the source configuration.
516
+ * @memberof ServerConfBuilder
517
+ */
410
518
  const addWsConf = async (
411
519
  { toOptions, fromOptions },
412
520
  fromDefaultOptions = { wsId: 'default', deployId: 'dd-default', host: 'default.net', paths: '/' },
@@ -432,6 +540,14 @@ const addWsConf = async (
432
540
  fs.writeFileSync(`${confToFolder}/conf.server.json`, JSON.stringify(confServer, null, 4), 'utf8');
433
541
  };
434
542
 
543
+ /**
544
+ * @method buildWsSrc
545
+ * @description Builds the WebSocket source code.
546
+ * @param {object} toOptions - The options for the target configuration.
547
+ * @param {object} fromOptions - The options for the source configuration.
548
+ * @param {object} [fromDefaultOptions={ wsId: 'default', deployId: 'dd-default', host: 'default.net', paths: '/' }] - The default options for the source configuration.
549
+ * @memberof ServerConfBuilder
550
+ */
435
551
  const buildWsSrc = async (
436
552
  { toOptions, fromOptions },
437
553
  fromDefaultOptions = { wsId: 'default', deployId: 'dd-default', host: 'default.net', paths: '/' },
@@ -466,6 +582,13 @@ const buildWsSrc = async (
466
582
  }
467
583
  };
468
584
 
585
+ /**
586
+ * @method cloneSrcComponents
587
+ * @description Clones the source components.
588
+ * @param {object} toOptions - The options for the target configuration.
589
+ * @param {object} fromOptions - The options for the source configuration.
590
+ * @memberof ServerConfBuilder
591
+ */
469
592
  const cloneSrcComponents = async ({ toOptions, fromOptions }) => {
470
593
  const toClientVariableName = getCapVariableName(toOptions.componentsFolder);
471
594
  const fromClientVariableName = getCapVariableName(fromOptions.componentsFolder);
@@ -489,24 +612,25 @@ const cloneSrcComponents = async ({ toOptions, fromOptions }) => {
489
612
  }
490
613
  };
491
614
 
615
+ /**
616
+ * @method buildProxyRouter
617
+ * @description Builds the proxy router.
618
+ * @memberof ServerConfBuilder
619
+ */
492
620
  const buildProxyRouter = () => {
493
621
  const confServer = JSON.parse(fs.readFileSync(`./conf/conf.server.json`, 'utf8'));
494
622
  let currentPort = parseInt(process.env.PORT) + 1;
495
623
  const proxyRouter = {};
496
- const singleReplicaHosts = [];
497
624
  for (const host of Object.keys(confServer)) {
498
625
  for (const path of Object.keys(confServer[host])) {
499
- if (confServer[host][path].singleReplica && !singleReplicaHosts.includes(host)) {
500
- singleReplicaHosts.push(host);
501
- currentPort++;
502
- continue;
503
- }
626
+ if (confServer[host][path].singleReplica) continue;
627
+
504
628
  confServer[host][path].port = newInstance(currentPort);
505
629
  for (const port of confServer[host][path].proxy) {
506
630
  if (!(port in proxyRouter)) proxyRouter[port] = {};
507
631
  proxyRouter[port][`${host}${path}`] = {
508
632
  // target: `http://${host}:${confServer[host][path].port}${path}`,
509
- target: `http://localhost:${confServer[host][path].port - singleReplicaHosts.length}`,
633
+ target: `http://localhost:${confServer[host][path].port}`,
510
634
  // target: `http://127.0.0.1:${confServer[host][path].port}`,
511
635
  proxy: confServer[host][path].proxy,
512
636
  redirect: confServer[host][path].redirect,
@@ -523,7 +647,7 @@ const buildProxyRouter = () => {
523
647
  if (!(port in proxyRouter)) proxyRouter[port] = {};
524
648
  proxyRouter[port][`${host}${peerPath}`] = {
525
649
  // target: `http://${host}:${confServer[host][peerPath].port}${peerPath}`,
526
- target: `http://localhost:${confServer[host][peerPath].port - singleReplicaHosts.length}`,
650
+ target: `http://localhost:${confServer[host][peerPath].port}`,
527
651
  // target: `http://127.0.0.1:${confServer[host][peerPath].port}`,
528
652
  proxy: confServer[host][peerPath].proxy,
529
653
  host,
@@ -538,7 +662,15 @@ const buildProxyRouter = () => {
538
662
  return proxyRouter;
539
663
  };
540
664
 
541
- const pathPortAssignmentFactory = (router, confServer) => {
665
+ /**
666
+ * @method pathPortAssignmentFactory
667
+ * @description Creates the path port assignment.
668
+ * @param {string} deployId - The deploy ID.
669
+ * @param {object} router - The router.
670
+ * @param {object} confServer - The server configuration.
671
+ * @memberof ServerConfBuilder
672
+ */
673
+ const pathPortAssignmentFactory = async (deployId, router, confServer) => {
542
674
  const pathPortAssignmentData = {};
543
675
  for (const host of Object.keys(confServer)) {
544
676
  const pathPortAssignment = [];
@@ -556,15 +688,54 @@ const pathPortAssignmentFactory = (router, confServer) => {
556
688
  // logger.info('', { host, port: port + 1, path: '/peer' });
557
689
  pathPortAssignment.push({
558
690
  port: port + 1,
559
- path: '/peer',
691
+ path: `${path === '/' ? '' : path}/peer`,
560
692
  });
561
693
  }
562
694
  }
563
695
  pathPortAssignmentData[host] = pathPortAssignment;
564
696
  }
697
+ if (fs.existsSync(`./engine-private/replica`)) {
698
+ const singleReplicas = await fs.readdir(`./engine-private/replica`);
699
+ for (let replica of singleReplicas) {
700
+ if (replica.startsWith(deployId)) {
701
+ const replicaServerConf = JSON.parse(
702
+ fs.readFileSync(`./engine-private/replica/${replica}/conf.server.json`, 'utf8'),
703
+ );
704
+ for (const host of Object.keys(replicaServerConf)) {
705
+ const pathPortAssignment = [];
706
+ for (const path of Object.keys(replicaServerConf[host])) {
707
+ const { peer } = replicaServerConf[host][path];
708
+ if (!router[`${host}${path === '/' ? '' : path}`]) continue;
709
+ const port = parseInt(router[`${host}${path === '/' ? '' : path}`].split(':')[2]);
710
+ // logger.info('', { host, port, path });
711
+ pathPortAssignment.push({
712
+ port,
713
+ path,
714
+ });
715
+
716
+ if (peer) {
717
+ // logger.info('', { host, port: port + 1, path: '/peer' });
718
+ pathPortAssignment.push({
719
+ port: port + 1,
720
+ path: `${path === '/' ? '' : path}/peer`,
721
+ });
722
+ }
723
+ }
724
+ pathPortAssignmentData[host] = pathPortAssignmentData[host].concat(pathPortAssignment);
725
+ }
726
+ }
727
+ }
728
+ }
565
729
  return pathPortAssignmentData;
566
730
  };
567
731
 
732
+ /**
733
+ * @method deployRangePortFactory
734
+ * @description Creates the deploy range port factory.
735
+ * @param {object} router - The router.
736
+ * @returns {object} - The deploy range port factory.
737
+ * @memberof ServerConfBuilder
738
+ */
568
739
  const deployRangePortFactory = (router) => {
569
740
  const ports = Object.values(router).map((p) => parseInt(p.split(':')[2]));
570
741
  const fromPort = Math.min(...ports);
@@ -572,6 +743,14 @@ const deployRangePortFactory = (router) => {
572
743
  return { ports, fromPort, toPort };
573
744
  };
574
745
 
746
+ /**
747
+ * @method buildKindPorts
748
+ * @description Builds the kind ports.
749
+ * @param {number} from - The from port.
750
+ * @param {number} to - The to port.
751
+ * @returns {string} - The kind ports.
752
+ * @memberof ServerConfBuilder
753
+ */
575
754
  const buildKindPorts = (from, to) =>
576
755
  range(parseInt(from), parseInt(to))
577
756
  .map(
@@ -587,13 +766,21 @@ const buildKindPorts = (from, to) =>
587
766
  )
588
767
  .join('\n');
589
768
 
590
- const buildPortProxyRouter = (port, proxyRouter) => {
769
+ /**
770
+ * @method buildPortProxyRouter
771
+ * @description Builds the port proxy router.
772
+ * @param {number} port - The port.
773
+ * @param {object} proxyRouter - The proxy router.
774
+ * @param {object} [options={ orderByPathLength: false }] - The options.
775
+ * @returns {object} - The port proxy router.
776
+ * @memberof ServerConfBuilder
777
+ */
778
+ const buildPortProxyRouter = (port, proxyRouter, options = { orderByPathLength: false }) => {
591
779
  const hosts = proxyRouter[port];
592
780
  const router = {};
593
781
  // build router
594
782
  Object.keys(hosts).map((hostKey) => {
595
783
  let { host, path, target, proxy, peer } = hosts[hostKey];
596
- if (process.env.NODE_ENV === 'development' && process.argv.includes('localhost')) host = `localhost`;
597
784
 
598
785
  if (!proxy.includes(port)) {
599
786
  logger.warn('Proxy port not set on conf', { port, host, path, proxy, target });
@@ -615,15 +802,38 @@ const buildPortProxyRouter = (port, proxyRouter) => {
615
802
 
616
803
  if (Object.keys(router).length === 0) return router;
617
804
 
618
- const reOrderRouter = {};
619
- for (const absoluteHostKey of orderArrayFromAttrInt(Object.keys(router), 'length'))
620
- reOrderRouter[absoluteHostKey] = router[absoluteHostKey];
805
+ if (options.orderByPathLength === true) {
806
+ const reOrderRouter = {};
807
+ for (const absoluteHostKey of orderArrayFromAttrInt(Object.keys(router), 'length'))
808
+ reOrderRouter[absoluteHostKey] = router[absoluteHostKey];
809
+ return reOrderRouter;
810
+ }
621
811
 
622
- return reOrderRouter;
812
+ return router;
623
813
  };
624
814
 
815
+ /**
816
+ * @method buildReplicaId
817
+ * @description Builds the replica ID.
818
+ * @param {object} options - The options.
819
+ * @param {string} options.deployId - The deploy ID.
820
+ * @param {string} options.replica - The replica.
821
+ * @returns {string} - The replica ID.
822
+ * @memberof ServerConfBuilder
823
+ */
625
824
  const buildReplicaId = ({ deployId, replica }) => `${deployId}-${replica.slice(1)}`;
626
825
 
826
+ /**
827
+ * @method getDataDeploy
828
+ * @description Gets the data deploy.
829
+ * @param {object} options - The options.
830
+ * @param {boolean} [options.buildSingleReplica=false] - The build single replica.
831
+ * @param {string} options.deployGroupId - The deploy group ID.
832
+ * @param {string} options.deployId - The deploy ID.
833
+ * @param {boolean} [options.disableSyncEnvPort=false] - The disable sync env port.
834
+ * @returns {object} - The data deploy.
835
+ * @memberof ServerConfBuilder
836
+ */
627
837
  const getDataDeploy = (
628
838
  options = {
629
839
  buildSingleReplica: false,
@@ -685,6 +895,13 @@ const getDataDeploy = (
685
895
  return buildDataDeploy;
686
896
  };
687
897
 
898
+ /**
899
+ * @method validateTemplatePath
900
+ * @description Validates the template path.
901
+ * @param {string} absolutePath - The absolute path.
902
+ * @returns {boolean} - The validation result.
903
+ * @memberof ServerConfBuilder
904
+ */
688
905
  const validateTemplatePath = (absolutePath = '') => {
689
906
  const host = 'default.net';
690
907
  const path = '/';
@@ -762,16 +979,40 @@ const validateTemplatePath = (absolutePath = '') => {
762
979
  return true;
763
980
  };
764
981
 
982
+ /**
983
+ * @method awaitDeployMonitor
984
+ * @description Waits for the deploy monitor.
985
+ * @param {boolean} [init=false] - The init flag.
986
+ * @param {number} [deltaMs=1000] - The delta ms.
987
+ * @returns {Promise<void>} - The await deploy monitor.
988
+ * @memberof ServerConfBuilder
989
+ */
765
990
  const awaitDeployMonitor = async (init = false, deltaMs = 1000) => {
766
991
  if (init) UnderpostRootEnv.API.set('await-deploy', new Date().toISOString());
767
992
  await timer(deltaMs);
768
993
  if (UnderpostRootEnv.API.get('await-deploy')) return await awaitDeployMonitor();
769
994
  };
770
995
 
996
+ /**
997
+ * @method getCronBackUpFolder
998
+ * @description Gets the cron back up folder.
999
+ * @param {string} host - The host.
1000
+ * @param {string} path - The path.
1001
+ * @returns {string} - The cron back up folder.
1002
+ * @memberof ServerConfBuilder
1003
+ */
771
1004
  const getCronBackUpFolder = (host = '', path = '') => {
772
1005
  return `${host}${path.replace(/\\/g, '/').replace(`/`, '-')}`;
773
1006
  };
774
1007
 
1008
+ /**
1009
+ * @method mergeFile
1010
+ * @description Merges the file.
1011
+ * @param {Array} parts - The parts.
1012
+ * @param {string} outputFilePath - The output file path.
1013
+ * @returns {Promise<void>} - The merge file.
1014
+ * @memberof ServerConfBuilder
1015
+ */
775
1016
  const mergeFile = async (parts = [], outputFilePath) => {
776
1017
  await new Promise((resolve) => {
777
1018
  splitFile
@@ -786,6 +1027,16 @@ const mergeFile = async (parts = [], outputFilePath) => {
786
1027
  });
787
1028
  };
788
1029
 
1030
+ /**
1031
+ * @method rebuildConfFactory
1032
+ * @description Rebuilds the conf factory.
1033
+ * @param {object} options - The options.
1034
+ * @param {string} options.deployId - The deploy ID.
1035
+ * @param {string} options.valkey - The valkey.
1036
+ * @param {boolean} [options.mongo=false] - The mongo.
1037
+ * @returns {object} - The rebuild conf factory.
1038
+ * @memberof ServerConfBuilder
1039
+ */
789
1040
  const rebuildConfFactory = ({ deployId, valkey, mongo }) => {
790
1041
  const confServer = loadReplicas(
791
1042
  JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
@@ -833,6 +1084,13 @@ const rebuildConfFactory = ({ deployId, valkey, mongo }) => {
833
1084
  return { hosts };
834
1085
  };
835
1086
 
1087
+ /**
1088
+ * @method getPathsSSR
1089
+ * @description Gets the paths SSR.
1090
+ * @param {object} conf - The conf.
1091
+ * @returns {Array} - The paths SSR.
1092
+ * @memberof ServerConfBuilder
1093
+ */
836
1094
  const getPathsSSR = (conf) => {
837
1095
  const paths = ['src/client/ssr/Render.js'];
838
1096
  for (const o of conf.head) paths.push(`src/client/ssr/head/${o}.js`);
@@ -843,19 +1101,87 @@ const getPathsSSR = (conf) => {
843
1101
  return paths;
844
1102
  };
845
1103
 
1104
+ /**
1105
+ * @method Cmd
1106
+ * @description The command factory.
1107
+ * @memberof ServerConfBuilder
1108
+ */
846
1109
  const Cmd = {
1110
+ /**
1111
+ * @method delete
1112
+ * @description Deletes the deploy.
1113
+ * @param {string} deployId - The deploy ID.
1114
+ * @returns {string} - The delete command.
1115
+ * @memberof Cmd
1116
+ */
847
1117
  delete: (deployId) => `pm2 delete ${deployId}`,
1118
+ /**
1119
+ * @method run
1120
+ * @description Runs the deploy.
1121
+ * @returns {string} - The run command.
1122
+ * @memberof Cmd
1123
+ */
848
1124
  run: () => `npm start`,
1125
+ /**
1126
+ * @method build
1127
+ * @description Builds the deploy.
1128
+ * @param {string} deployId - The deploy ID.
1129
+ * @returns {string} - The build command.
1130
+ * @memberof Cmd
1131
+ */
849
1132
  build: (deployId) => `node bin/deploy build-full-client ${deployId}${process.argv.includes('l') ? ' l' : ''}`,
1133
+ /**
1134
+ * @method conf
1135
+ * @description Configures the deploy.
1136
+ * @param {string} deployId - The deploy ID.
1137
+ * @param {string} env - The environment.
1138
+ * @returns {string} - The conf command.
1139
+ * @memberof Cmd
1140
+ */
850
1141
  conf: (deployId, env) => `node bin/deploy conf ${deployId} ${env ? env : 'production'}`,
1142
+ /**
1143
+ * @method replica
1144
+ * @description Builds the replica.
1145
+ * @param {string} deployId - The deploy ID.
1146
+ * @param {string} host - The host.
1147
+ * @param {string} path - The path.
1148
+ * @returns {string} - The replica command.
1149
+ * @memberof Cmd
1150
+ */
851
1151
  replica: (deployId, host, path) => `node bin/deploy build-single-replica ${deployId} ${host} ${path}`,
1152
+ /**
1153
+ * @method syncPorts
1154
+ * @description Syncs the ports.
1155
+ * @param {string} deployGroupId - The deploy group ID.
1156
+ * @returns {string} - The sync ports command.
1157
+ * @memberof Cmd
1158
+ */
852
1159
  syncPorts: (deployGroupId) => `node bin/deploy sync-env-port ${deployGroupId}`,
1160
+ /**
1161
+ * @method cron
1162
+ * @description Creates a cron job.
1163
+ * @param {string} deployList - The deploy list.
1164
+ * @param {string} jobList - The job list.
1165
+ * @param {string} name - The name.
1166
+ * @param {string} expression - The expression.
1167
+ * @param {object} options - The options.
1168
+ * @returns {string} - The cron command.
1169
+ * @memberof Cmd
1170
+ */
853
1171
  cron: (deployList, jobList, name, expression, options) =>
854
1172
  `pm2 start ./bin/index.js --no-autorestart --instances 1 --cron "${expression}" --name ${name} -- cron ${
855
1173
  options?.itc ? `--itc ` : ''
856
1174
  }${options?.git ? `--git ` : ''}${deployList} ${jobList}`,
857
1175
  };
858
1176
 
1177
+ /**
1178
+ * @method splitFileFactory
1179
+ * @description Splits the file factory.
1180
+ * @param {string} name - The name.
1181
+ * @param {string} _path - The path.
1182
+ * @returns {Promise<boolean>} - The split file factory.
1183
+ * @memberof ServerConfBuilder
1184
+ */
859
1185
  const splitFileFactory = async (name, _path) => {
860
1186
  const stats = fs.statSync(_path);
861
1187
  const maxSizeInBytes = 1024 * 1024 * 50; // 50 mb
@@ -884,6 +1210,12 @@ const splitFileFactory = async (name, _path) => {
884
1210
  return false;
885
1211
  };
886
1212
 
1213
+ /**
1214
+ * @method getNpmRootPath
1215
+ * @description Gets the npm root path.
1216
+ * @returns {string} - The npm root path.
1217
+ * @memberof ServerConfBuilder
1218
+ */
887
1219
  const getNpmRootPath = () =>
888
1220
  shellExec(`npm root -g`, {
889
1221
  stdout: true,
@@ -891,8 +1223,21 @@ const getNpmRootPath = () =>
891
1223
  silent: true,
892
1224
  }).trim();
893
1225
 
1226
+ /**
1227
+ * @method getUnderpostRootPath
1228
+ * @description Gets the underpost root path.
1229
+ * @returns {string} - The underpost root path.
1230
+ * @memberof ServerConfBuilder
1231
+ */
894
1232
  const getUnderpostRootPath = () => `${getNpmRootPath()}/underpost`;
895
1233
 
1234
+ /**
1235
+ * @method writeEnv
1236
+ * @description Writes the environment variables.
1237
+ * @param {string} envPath - The environment path.
1238
+ * @param {object} envObj - The environment object.
1239
+ * @memberof ServerConfBuilder
1240
+ */
896
1241
  const writeEnv = (envPath, envObj) =>
897
1242
  fs.writeFileSync(
898
1243
  envPath,
@@ -902,6 +1247,14 @@ const writeEnv = (envPath, envObj) =>
902
1247
  'utf8',
903
1248
  );
904
1249
 
1250
+ /**
1251
+ * @method buildCliDoc
1252
+ * @description Builds the CLI documentation.
1253
+ * @param {object} program - The program.
1254
+ * @param {string} oldVersion - The old version.
1255
+ * @param {string} newVersion - The new version.
1256
+ * @memberof ServerConfBuilder
1257
+ */
905
1258
  const buildCliDoc = (program, oldVersion, newVersion) => {
906
1259
  let md = shellExec(`node bin help`, { silent: true, stdout: true }).split('Options:');
907
1260
  const baseOptions =
@@ -962,13 +1315,35 @@ const buildCliDoc = (program, oldVersion, newVersion) => {
962
1315
  );
963
1316
  };
964
1317
 
965
- const getInstanceContext = async (options = { singleReplica, replicas, redirect: '' }) => {
966
- const { singleReplica, replicas, redirect } = options;
967
-
968
- if (singleReplica && replicas && replicas.length > 0)
969
- return {
970
- singleReplicaHost: true,
971
- };
1318
+ /**
1319
+ * @method getInstanceContext
1320
+ * @description Gets the instance context.
1321
+ * @param {object} options - The options.
1322
+ * @param {string} options.deployId - The deploy ID.
1323
+ * @param {boolean} options.singleReplica - The single replica.
1324
+ * @param {Array} options.replicas - The replicas.
1325
+ * @param {string} options.redirect - The redirect.
1326
+ * @returns {object} - The instance context.
1327
+ * @memberof ServerConfBuilder
1328
+ */
1329
+ const getInstanceContext = async (options = { deployId, singleReplica, replicas, redirect: '' }) => {
1330
+ const { deployId, singleReplica, replicas, redirect } = options;
1331
+ let singleReplicaOffsetPortSum = 0;
1332
+
1333
+ if (singleReplica && replicas && replicas.length > 0) {
1334
+ for (const replica of replicas) {
1335
+ const replicaDeployId = buildReplicaId({ deployId, replica });
1336
+ const confReplicaServer = JSON.parse(
1337
+ fs.readFileSync(`./engine-private/replica/${replicaDeployId}/conf.server.json`, 'utf8'),
1338
+ );
1339
+ for (const host of Object.keys(confReplicaServer)) {
1340
+ for (const path of Object.keys(confReplicaServer[host])) {
1341
+ singleReplicaOffsetPortSum++;
1342
+ if (confReplicaServer[host][path].peer) singleReplicaOffsetPortSum++;
1343
+ }
1344
+ }
1345
+ }
1346
+ }
972
1347
 
973
1348
  const redirectTarget = redirect
974
1349
  ? redirect[redirect.length - 1] === '/'
@@ -976,9 +1351,21 @@ const getInstanceContext = async (options = { singleReplica, replicas, redirect:
976
1351
  : redirect
977
1352
  : undefined;
978
1353
 
979
- return { redirectTarget };
1354
+ return { redirectTarget, singleReplicaOffsetPortSum };
980
1355
  };
981
1356
 
1357
+ /**
1358
+ * @method buildApiConf
1359
+ * @description Builds the API configuration.
1360
+ * @param {object} options - The options.
1361
+ * @param {string} options.deployId - The deploy ID.
1362
+ * @param {string} options.subConf - The sub configuration.
1363
+ * @param {string} options.host - The host.
1364
+ * @param {string} options.path - The path.
1365
+ * @param {string} options.origin - The origin.
1366
+ * @returns {object} - The API configuration.
1367
+ * @memberof ServerConfBuilder
1368
+ */
982
1369
  const buildApiConf = async (options = { deployId: '', subConf: '', host: '', path: '', origin: '' }) => {
983
1370
  let { deployId, subConf, host, path, origin } = options;
984
1371
  if (!deployId) deployId = process.argv[2].trim();
@@ -1007,6 +1394,18 @@ const buildApiConf = async (options = { deployId: '', subConf: '', host: '', pat
1007
1394
  );
1008
1395
  };
1009
1396
 
1397
+ /**
1398
+ * @method buildClientStaticConf
1399
+ * @description Builds the client static configuration.
1400
+ * @param {object} options - The options.
1401
+ * @param {string} options.deployId - The deploy ID.
1402
+ * @param {string} options.subConf - The sub configuration.
1403
+ * @param {string} options.apiBaseHost - The API base host.
1404
+ * @param {string} options.host - The host.
1405
+ * @param {string} options.path - The path.
1406
+ * @returns {void}
1407
+ * @memberof ServerConfBuilder
1408
+ */
1010
1409
  const buildClientStaticConf = async (options = { deployId: '', subConf: '', apiBaseHost: '', host: '', path: '' }) => {
1011
1410
  let { deployId, subConf, host, path } = options;
1012
1411
  if (!deployId) deployId = process.argv[2].trim();
@@ -1033,6 +1432,16 @@ const buildClientStaticConf = async (options = { deployId: '', subConf: '', apiB
1033
1432
  );
1034
1433
  };
1035
1434
 
1435
+ /**
1436
+ * @method isDeployRunnerContext
1437
+ * @description Checks if the deploy runner context is valid.
1438
+ * @param {string} path - The path.
1439
+ * @param {object} options - The options.
1440
+ * @returns {boolean} - The deploy runner context.
1441
+ * @memberof ServerConfBuilder
1442
+ */
1443
+ const isDeployRunnerContext = (path, options) => !options.build && path && path !== 'template-deploy';
1444
+
1036
1445
  export {
1037
1446
  Cmd,
1038
1447
  Config,
@@ -1068,4 +1477,5 @@ export {
1068
1477
  getInstanceContext,
1069
1478
  buildApiConf,
1070
1479
  buildClientStaticConf,
1480
+ isDeployRunnerContext,
1071
1481
  };