underpost 2.8.637 → 2.8.646

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.
package/bin/build.js CHANGED
@@ -47,7 +47,7 @@ if (process.argv.includes('conf')) {
47
47
  if (!fs.existsSync(`../${privateRepoName}`)) {
48
48
  shellExec(`cd .. && underpost clone ${privateGitUri}`, { silent: true });
49
49
  } else {
50
- shellExec(`cd ../${privateRepoName} && underpost pull . ${privateGitUri}`);
50
+ shellExec(`cd ../${privateRepoName} && git checkout . && git clean -f -d && underpost pull . ${privateGitUri}`);
51
51
  }
52
52
  const toPath = `../${privateRepoName}/conf/${_confName}`;
53
53
  fs.removeSync(toPath);
package/bin/deploy.js CHANGED
@@ -33,8 +33,9 @@ import { MongooseDB } from '../src/db/mongo/MongooseDB.js';
33
33
  import { Lampp } from '../src/runtime/lampp/Lampp.js';
34
34
  import { DefaultConf } from '../conf.js';
35
35
  import { JSONweb } from '../src/server/client-formatted.js';
36
- import ejs from 'easy-json-schema';
36
+
37
37
  import { Xampp } from '../src/runtime/xampp/Xampp.js';
38
+ import { ejs } from '../src/server/json-schema.js';
38
39
 
39
40
  const logger = loggerFactory(import.meta);
40
41
 
package/bin/index.js CHANGED
@@ -22,6 +22,15 @@ program
22
22
  .description('Create a new project')
23
23
  .action(Underpost.repo.new);
24
24
 
25
+ program
26
+ .command('start')
27
+ .argument('<deploy-id>', 'Deploy configuration id')
28
+ .argument('[env]', 'Optional environment, for default is development')
29
+ .option('--run', 'Run app servers and monitor health server')
30
+ .option('--build', 'Build app client')
31
+ .action(Underpost.start.callback)
32
+ .description('Start up server, build pipelines, or services');
33
+
25
34
  program
26
35
  .command('clone')
27
36
  .argument(`<uri>`, 'e.g. username/repository')
@@ -105,6 +114,7 @@ program
105
114
  .option('--info-util', 'Display kubectl util management commands')
106
115
  .option('--cert', 'Reset tls/ssl certificate secrets')
107
116
  .option('--build-manifest', 'Build kind yaml manifests: deployments, services, proxy and secrets')
117
+ .option('--dashboard-update', 'Update dashboard instance data with current router config')
108
118
  .option('--version', 'Set custom version')
109
119
  .description('Manage deployment, for default deploy development pods')
110
120
  .action(Underpost.deploy.callback);
@@ -124,15 +134,6 @@ program
124
134
  if (args[1].init) return Underpost.secret[args[0]].init();
125
135
  });
126
136
 
127
- program
128
- .command('dockerfile-node-script')
129
- .argument('<deploy-id>', 'Deploy configuration id')
130
- .argument('[env]', 'Optional environment, for default is development')
131
- .option('--run', 'Run custom entry point script')
132
- .option('--build', 'Build custom image container scripts')
133
- .description('Dockerfile custom node build script')
134
- .action(Underpost.image.dockerfile.script);
135
-
136
137
  program
137
138
  .command('dockerfile-image-build')
138
139
  .option('--path [path]', 'Dockerfile path')
@@ -195,6 +196,7 @@ program
195
196
  .option('--itc', 'Inside container execution context')
196
197
  .option('--init', 'Init cron jobs for cron job default deploy id')
197
198
  .option('--git', 'Upload to github')
199
+ .option('--dashboard-update', 'Update dashboard cron data with current jobs config')
198
200
  .description('Cron jobs management')
199
201
  .action(Underpost.cron.callback);
200
202
 
@@ -58,7 +58,7 @@ services:
58
58
  cpus: '0.25'
59
59
  memory: 20M
60
60
  labels: # labels in Compose file instead of Dockerfile
61
- engine.version: '2.8.637'
61
+ engine.version: '2.8.646'
62
62
  networks:
63
63
  - load-balancer
64
64
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "underpost",
5
- "version": "2.8.637",
5
+ "version": "2.8.646",
6
6
  "description": "pwa api rest template",
7
7
  "scripts": {
8
8
  "start": "env-cmd -f .env.production node --max-old-space-size=8192 src/server",
@@ -69,7 +69,6 @@
69
69
  "cors": "^2.8.5",
70
70
  "d3": "^7.9.0",
71
71
  "dotenv": "^16.3.1",
72
- "easy-json-schema": "^0.0.2-beta",
73
72
  "easymde": "^2.18.0",
74
73
  "env-cmd": "^10.1.0",
75
74
  "express": "^4.18.2",
@@ -119,13 +118,7 @@
119
118
  "vanilla-jsoneditor": "^2.3.2",
120
119
  "winston": "^3.11.0"
121
120
  },
122
- "devDependencies": {
123
- "clean-jsdoc-theme": "^4.3.0",
124
- "easy-json-schema": "^0.0.2-beta",
125
- "mocha": "^10.8.2",
126
- "plantuml": "^0.0.2",
127
- "swagger-autogen": "^2.23.7"
128
- },
121
+ "devDependencies": {},
129
122
  "publishConfig": {
130
123
  "provenance": true,
131
124
  "access": "public",
@@ -24,7 +24,7 @@ const DefaultService = {
24
24
  /** @type {import('./default.model.js').DefaultModel} */
25
25
  const Default = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.Default;
26
26
  if (req.params.id) return await Default.findByIdAndDelete(req.params.id);
27
- else return await await Default.deleteMany();
27
+ else return await Default.deleteMany();
28
28
  },
29
29
  };
30
30
 
@@ -378,7 +378,7 @@ const UserService = {
378
378
  switch (user.role) {
379
379
  case 'admin': {
380
380
  if (req.params.id) return await User.findByIdAndDelete(req.params.id);
381
- else return await await User.deleteMany();
381
+ else return await User.deleteMany();
382
382
  }
383
383
  default:
384
384
  if (req.auth.user._id !== req.params.id) throw new Error(`Invalid token user id`);
package/src/cli/cron.js CHANGED
@@ -4,20 +4,24 @@
4
4
  * @namespace UnderpostCron
5
5
  */
6
6
 
7
- import Underpost from '../index.js';
7
+ import { DataBaseProvider } from '../db/DataBaseProvider.js';
8
8
  import BackUp from '../server/backup.js';
9
9
  import { Cmd } from '../server/conf.js';
10
10
  import Dns from '../server/dns.js';
11
- import { netWorkCron, saveRuntimeCron } from '../server/network.js';
11
+ import { loggerFactory } from '../server/logger.js';
12
+
12
13
  import { shellExec } from '../server/process.js';
13
14
  import fs from 'fs-extra';
14
15
 
16
+ const logger = loggerFactory(import.meta);
17
+
15
18
  /**
16
19
  * UnderpostCron main module methods
17
20
  * @class
18
21
  * @memberof UnderpostCron
19
22
  */
20
23
  class UnderpostCron {
24
+ static NETWORK = [];
21
25
  static JOB = {
22
26
  /**
23
27
  * DNS cli API
@@ -46,10 +50,10 @@ class UnderpostCron {
46
50
  callback: async function (
47
51
  deployList = 'default',
48
52
  jobList = Object.keys(UnderpostCron.JOB),
49
- options = { itc: false, init: false, git: false },
53
+ options = { itc: false, init: false, git: false, dashboardUpdate: false },
50
54
  ) {
51
55
  if (options.init === true) {
52
- await Underpost.test.setUpInfo();
56
+ UnderpostCron.NETWORK = [];
53
57
  const jobDeployId = fs.readFileSync('./engine-private/deploy/dd.cron', 'utf8').trim();
54
58
  deployList = fs.readFileSync('./engine-private/deploy/dd.router', 'utf8').trim();
55
59
  const confCronConfig = JSON.parse(fs.readFileSync(`./engine-private/conf/${jobDeployId}/conf.cron.json`));
@@ -57,7 +61,7 @@ class UnderpostCron {
57
61
  for (const job of Object.keys(confCronConfig.jobs)) {
58
62
  const name = `${jobDeployId}-${job}`;
59
63
  let deployId;
60
- shellExec(Cmd.delete(name));
64
+ if (!options.dashboardUpdate) shellExec(Cmd.delete(name));
61
65
  switch (job) {
62
66
  case 'dns':
63
67
  deployId = jobDeployId;
@@ -67,15 +71,16 @@ class UnderpostCron {
67
71
  deployId = deployList;
68
72
  break;
69
73
  }
70
- shellExec(Cmd.cron(deployId, job, name, confCronConfig.jobs[job].expression, options));
71
- netWorkCron.push({
74
+ if (!options.dashboardUpdate)
75
+ shellExec(Cmd.cron(deployId, job, name, confCronConfig.jobs[job].expression, options));
76
+ UnderpostCron.NETWORK.push({
72
77
  deployId,
73
78
  jobId: job,
74
79
  expression: confCronConfig.jobs[job].expression,
75
80
  });
76
81
  }
77
82
  }
78
- await saveRuntimeCron();
83
+ if (options.dashboardUpdate === true) await UnderpostCron.API.updateDashboardData();
79
84
  if (fs.existsSync(`./tmp/await-deploy`)) fs.remove(`./tmp/await-deploy`);
80
85
  return;
81
86
  }
@@ -84,6 +89,32 @@ class UnderpostCron {
84
89
  if (UnderpostCron.JOB[jobId]) await UnderpostCron.JOB[jobId].callback(deployList, options);
85
90
  }
86
91
  },
92
+ async updateDashboardData() {
93
+ try {
94
+ const deployId = process.env.DEFAULT_DEPLOY_ID;
95
+ const host = process.env.DEFAULT_DEPLOY_HOST;
96
+ const path = process.env.DEFAULT_DEPLOY_PATH;
97
+ const confServerPath = `./engine-private/conf/${deployId}/conf.server.json`;
98
+ const confServer = JSON.parse(fs.readFileSync(confServerPath, 'utf8'));
99
+ const { db } = confServer[host][path];
100
+
101
+ await DataBaseProvider.load({ apis: ['cron'], host, path, db });
102
+
103
+ /** @type {import('../api/cron/cron.model.js').CronModel} */
104
+ const Cron = DataBaseProvider.instance[`${host}${path}`].mongoose.models.Cron;
105
+
106
+ await Cron.deleteMany();
107
+
108
+ for (const cronInstance of UnderpostCron.NETWORK) {
109
+ logger.info('save', cronInstance);
110
+ await new Cron(cronInstance).save();
111
+ }
112
+
113
+ await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
114
+ } catch (error) {
115
+ logger.error(error, error.stack);
116
+ }
117
+ },
87
118
  };
88
119
  }
89
120
 
package/src/cli/deploy.js CHANGED
@@ -12,11 +12,12 @@ import { loggerFactory } from '../server/logger.js';
12
12
  import { shellExec } from '../server/process.js';
13
13
  import fs from 'fs-extra';
14
14
  import dotenv from 'dotenv';
15
- import Underpost from '../index.js';
15
+ import { DataBaseProvider } from '../db/DataBaseProvider.js';
16
16
 
17
17
  const logger = loggerFactory(import.meta);
18
18
 
19
19
  class UnderpostDeploy {
20
+ static NETWORK = {};
20
21
  static API = {
21
22
  sync(deployList) {
22
23
  const deployGroupId = 'dd.tmp';
@@ -50,7 +51,7 @@ class UnderpostDeploy {
50
51
  if (env === 'development') fs.mkdirSync(`./manifests/deployment/${deployId}-${env}`, { recursive: true });
51
52
 
52
53
  logger.info('port range', { deployId, fromPort, toPort });
53
- // const customImg = `underpost-engine:${version && typeof version === 'string' ? version : Underpost.version}`;
54
+ // const customImg = `underpost-engine:${version && typeof version === 'string' ? version : '0.0.0'}`;
54
55
  // lifecycle:
55
56
  // postStart:
56
57
  // exec:
@@ -85,13 +86,9 @@ spec:
85
86
  - -c
86
87
  - >
87
88
  npm install -g npm@11.2.0 &&
88
- npm config delete proxy &&
89
- npm config delete http-proxy &&
90
- npm config delete https-proxy &&
91
- npm config set registry http://registry.npmjs.org/ &&
92
- npm install --unsafe-perm --ignore-scripts -g underpost &&
89
+ npm install -g underpost &&
93
90
  underpost secret underpost --create-from-file /etc/config/.env.${env} &&
94
- underpost dockerfile-node-script --build --run ${deployId} ${env}
91
+ underpost start --build --run ${deployId} ${env}
95
92
  volumeMounts:
96
93
  - name: config-volume
97
94
  mountPath: /etc/config
@@ -99,7 +96,7 @@ spec:
99
96
  - name: config-volume
100
97
  configMap:
101
98
  name: underpost-config
102
- # image: localhost/${deployId}-${env}:${version && typeof version === 'string' ? version : Underpost.version}
99
+ # image: localhost/${deployId}-${env}:${version && typeof version === 'string' ? version : '0.0.0'}
103
100
  ---
104
101
  apiVersion: v1
105
102
  kind: Service
@@ -200,6 +197,7 @@ spec:
200
197
  expose: false,
201
198
  cert: false,
202
199
  version: '',
200
+ dashboardUpdate: false,
203
201
  },
204
202
  ) {
205
203
  if (options.infoUtil === true)
@@ -212,8 +210,9 @@ kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
212
210
  deployList = fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8');
213
211
  if (options.sync) UnderpostDeploy.API.sync(deployList);
214
212
  if (options.buildManifest === true) await UnderpostDeploy.API.buildManifest(deployList, env, options.version);
215
- if (options.infoRouter === true)
216
- return logger.info('router', await UnderpostDeploy.API.routerFactory(deployList, env));
213
+ if (options.infoRouter === true) logger.info('router', await UnderpostDeploy.API.routerFactory(deployList, env));
214
+ if (options.dashboardUpdate === true) await UnderpostDeploy.API.updateDashboardData(deployList, env, options);
215
+ if (options.infoRouter === true) return;
217
216
  shellExec(`kubectl delete configmap underpost-config`);
218
217
  shellExec(
219
218
  `kubectl create configmap underpost-config --from-file=/home/dd/engine/engine-private/conf/dd-cron/.env.${env}`,
@@ -316,6 +315,60 @@ kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
316
315
 
317
316
  return result;
318
317
  },
318
+ async updateDashboardData(deployList, env, options) {
319
+ try {
320
+ const deployId = process.env.DEFAULT_DEPLOY_ID;
321
+ const host = process.env.DEFAULT_DEPLOY_HOST;
322
+ const path = process.env.DEFAULT_DEPLOY_PATH;
323
+ const { db } = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'))[host][
324
+ path
325
+ ];
326
+
327
+ await DataBaseProvider.load({ apis: ['instance'], host, path, db });
328
+
329
+ /** @type {import('../api/instance/instance.model.js').InstanceModel} */
330
+ const Instance = DataBaseProvider.instance[`${host}${path}`].mongoose.models.Instance;
331
+
332
+ await Instance.deleteMany();
333
+
334
+ for (const _deployId of deployList.split(',')) {
335
+ const deployId = _deployId.trim();
336
+ if (!deployId) continue;
337
+ const confServer = loadReplicas(
338
+ JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
339
+ 'proxy',
340
+ );
341
+ const router = await UnderpostDeploy.API.routerFactory(deployId, env);
342
+ const pathPortAssignmentData = pathPortAssignmentFactory(router, confServer);
343
+
344
+ for (const host of Object.keys(confServer)) {
345
+ for (const { path, port } of pathPortAssignmentData[host]) {
346
+ if (!confServer[host][path]) continue;
347
+
348
+ const { client, runtime, apis } = confServer[host][path];
349
+
350
+ const body = {
351
+ deployId,
352
+ host,
353
+ path,
354
+ port,
355
+ client,
356
+ runtime,
357
+ apis,
358
+ };
359
+
360
+ logger.info('save', body);
361
+
362
+ await new Instance(body).save();
363
+ }
364
+ }
365
+ }
366
+
367
+ await DataBaseProvider.instance[`${host}${path}`].mongoose.close();
368
+ } catch (error) {
369
+ logger.error(error, error.stack);
370
+ }
371
+ },
319
372
  };
320
373
  }
321
374
 
package/src/cli/image.js CHANGED
@@ -1,9 +1,7 @@
1
1
  import fs from 'fs-extra';
2
- import Underpost from '../index.js';
3
2
  import { shellCd, shellExec } from '../server/process.js';
4
3
  import dotenv from 'dotenv';
5
4
  import { awaitDeployMonitor, getNpmRootPath } from '../server/conf.js';
6
- import { timer } from '../client/components/core/CommonJs.js';
7
5
  import { loggerFactory } from '../server/logger.js';
8
6
  import UnderpostMonitor from './monitor.js';
9
7
 
@@ -62,74 +60,6 @@ class UnderpostImage {
62
60
  if (podmanSave === true) shellExec(`podman save -o ${tarFile} ${podManImg}`);
63
61
  if (kindLoad === true) shellExec(`sudo kind load image-archive ${tarFile}`);
64
62
  },
65
- async script(deployId = 'default', env = 'development', options = { run: false, build: false }) {
66
- if (options.build === true) {
67
- const buildBasePath = `/home/dd`;
68
- const repoName = `engine-${deployId.split('-')[1]}`;
69
- shellExec(`cd ${buildBasePath} && underpost clone underpostnet/${repoName}`);
70
- shellExec(`cd ${buildBasePath} && sudo mv ./${repoName} ./engine`);
71
- shellExec(`cd ${buildBasePath}/engine && underpost clone underpostnet/${repoName}-private`);
72
- shellExec(`cd ${buildBasePath}/engine && sudo mv ./${repoName}-private ./engine-private`);
73
- shellCd(`${buildBasePath}/engine`);
74
- shellExec(`underpost install`);
75
- if (fs.existsSync('./engine-private/itc-scripts')) {
76
- const itcScripts = await fs.readdir('./engine-private/itc-scripts');
77
- for (const itcScript of itcScripts)
78
- if (itcScript.match(deployId)) shellExec(`node ./engine-private/itc-scripts/${itcScript}`);
79
- }
80
- switch (deployId) {
81
- default:
82
- {
83
- {
84
- const originPath = `./src/db/mongo/MongooseDB.js`;
85
- fs.writeFileSync(
86
- originPath,
87
- fs.readFileSync(originPath, 'utf8').replaceAll(
88
- `connect: async (host, name) => {`,
89
- `connect: async (host, name) => {
90
- host = 'mongodb://mongodb-0.mongodb-service:27017';
91
- `,
92
- ),
93
- 'utf8',
94
- );
95
- }
96
-
97
- {
98
- const originPath = `./src/server/valkey.js`;
99
- fs.writeFileSync(
100
- originPath,
101
- fs.readFileSync(originPath, 'utf8').replaceAll(
102
- ` // port: 6379,
103
- // host: 'service-valkey.default.svc.cluster.local',`,
104
- ` port: 6379,
105
- host: 'service-valkey.default.svc.cluster.local',`,
106
- ),
107
- 'utf8',
108
- );
109
- }
110
- }
111
- break;
112
- }
113
- shellExec(`node bin/deploy conf ${deployId} ${env}`);
114
- shellExec(`node bin/deploy build-full-client ${deployId}`);
115
- }
116
- if (options.run === true) {
117
- const runCmd = env === 'production' ? 'run prod-img' : 'run dev-img';
118
- if (fs.existsSync(`./engine-private/replica`)) {
119
- const replicas = await fs.readdir(`./engine-private/replica`);
120
- for (const replica of replicas) {
121
- if (!replica.match(deployId)) continue;
122
- shellExec(`node bin/deploy conf ${replica} ${env}`);
123
- shellExec(`npm ${runCmd} deploy deploy-id:${replica}`, { async: true });
124
- await awaitDeployMonitor(true);
125
- }
126
- }
127
- shellExec(`node bin/deploy conf ${deployId} ${env}`);
128
- shellExec(`npm ${runCmd} deploy deploy-id:${deployId}`, { async: true });
129
- await awaitDeployMonitor(true);
130
- await UnderpostMonitor.API.callback(deployId, env, { itc: true });
131
- }
132
- },
133
63
  },
134
64
  };
135
65
  }
@@ -4,7 +4,7 @@ import { pbcopy, shellExec } from '../server/process.js';
4
4
  import { actionInitLog, loggerFactory } from '../server/logger.js';
5
5
  import fs from 'fs-extra';
6
6
  import { getNpmRootPath } from '../server/conf.js';
7
- import { listenPortController, listenServerFactory } from '../server/network.js';
7
+ import UnderpostStartUp from '../server/start.js';
8
8
 
9
9
  dotenv.config();
10
10
 
@@ -78,7 +78,10 @@ class UnderpostRepository {
78
78
  return new Promise(async (resolve, reject) => {
79
79
  try {
80
80
  await logger.setUpInfo();
81
- if (repositoryName === 'service') return resolve(await listenPortController(listenServerFactory(), ':'));
81
+ if (repositoryName === 'service')
82
+ return resolve(
83
+ await UnderpostStartUp.API.listenPortController(UnderpostStartUp.API.listenServerFactory(), ':'),
84
+ );
82
85
  else actionInitLog();
83
86
  const exeRootPath = `${getNpmRootPath()}/underpost`;
84
87
  const destFolder = `./${repositoryName}`;
@@ -151,23 +151,27 @@ const Account = {
151
151
  // s(`.btn-close-modal-account`).click();
152
152
  s(`.main-btn-recover`).click();
153
153
  };
154
- s(`.btn-account-delete-confirm`).onclick = async (e) => {
155
- e.preventDefault();
156
- const confirmResult = await Modal.RenderConfirm({
157
- html: async () => {
158
- return html`
159
- <div class="in section-mp" style="text-align: center">
160
- ${Translate.Render('confirm-delete-account')}
161
- </div>
162
- `;
163
- },
164
- id: 'delete-account-modal',
165
- });
166
- if (confirmResult.status === 'cancelled') return;
167
- s(`.btn-account-delete-confirm`).classList.add('hide');
168
- s(`.btn-account-delete`).classList.remove('hide');
169
- s(`.btn-account-delete`).click();
170
- };
154
+ EventsUI.onClick(
155
+ `.btn-account-delete-confirm`,
156
+ async (e) => {
157
+ e.preventDefault();
158
+ const confirmResult = await Modal.RenderConfirm({
159
+ html: async () => {
160
+ return html`
161
+ <div class="in section-mp" style="text-align: center">
162
+ ${Translate.Render('confirm-delete-account')}
163
+ </div>
164
+ `;
165
+ },
166
+ id: 'delete-account-modal',
167
+ });
168
+ if (confirmResult.status === 'cancelled') return;
169
+ s(`.btn-account-delete-confirm`).classList.add('hide');
170
+ s(`.btn-account-delete`).classList.remove('hide');
171
+ s(`.btn-account-delete`).click();
172
+ },
173
+ { context: 'modal' },
174
+ );
171
175
  EventsUI.onClick(`.btn-account-delete`, async (e) => {
172
176
  e.preventDefault();
173
177
  const result = await UserService.delete({ id: user._id });
@@ -178,7 +182,7 @@ const Account = {
178
182
  s(`.btn-account-delete-confirm`).classList.remove('hide');
179
183
  s(`.btn-account-delete`).classList.add('hide');
180
184
  if (result.status === 'success') {
181
- s(`.main-btn-home`).click();
185
+ Modal.onHomeRouterEvent();
182
186
  await Auth.sessionOut();
183
187
  }
184
188
  });