underpost 2.8.532 → 2.8.612

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 (44) hide show
  1. package/.github/workflows/ghpkg.yml +1 -1
  2. package/.github/workflows/npmpkg.yml +1 -1
  3. package/.github/workflows/pwa-microservices-template.page.yml +1 -1
  4. package/.vscode/settings.json +3 -0
  5. package/bin/build.js +9 -0
  6. package/bin/index.js +33 -6
  7. package/bin/vs.js +1 -0
  8. package/docker-compose.yml +1 -1
  9. package/manifests/kind-config-dev.yaml +12 -0
  10. package/manifests/mongodb/kustomization.yaml +2 -2
  11. package/manifests/mongodb-4.4/service-deployment.yaml +5 -4
  12. package/package.json +8 -7
  13. package/src/cli/cluster.js +58 -32
  14. package/src/cli/cron.js +1 -1
  15. package/src/cli/db.js +102 -38
  16. package/src/cli/deploy.js +84 -38
  17. package/src/cli/env.js +1 -1
  18. package/src/cli/fs.js +149 -0
  19. package/src/cli/image.js +36 -8
  20. package/src/cli/repository.js +21 -0
  21. package/src/cli/script.js +2 -2
  22. package/src/cli/test.js +19 -8
  23. package/src/client/components/core/CalendarCore.js +12 -1
  24. package/src/client/components/core/CommonJs.js +52 -1
  25. package/src/client/components/core/CssCore.js +2 -4
  26. package/src/client/components/core/Docs.js +1 -2
  27. package/src/client/components/core/Input.js +4 -2
  28. package/src/client/components/core/LoadingAnimation.js +8 -1
  29. package/src/client/components/core/Modal.js +31 -7
  30. package/src/client/components/core/Panel.js +8 -6
  31. package/src/client/components/core/PanelForm.js +23 -7
  32. package/src/client/services/core/core.service.js +15 -10
  33. package/src/client/ssr/Render.js +4 -1
  34. package/src/client/ssr/body/CacheControl.js +2 -3
  35. package/src/client/sw/default.sw.js +3 -3
  36. package/src/index.js +9 -1
  37. package/src/server/backup.js +2 -2
  38. package/src/server/client-build.js +32 -23
  39. package/src/server/client-formatted.js +2 -1
  40. package/src/server/conf.js +1 -1
  41. package/src/server/dns.js +2 -2
  42. package/src/server/runtime.js +16 -1
  43. package/manifests/valkey/underpost-engine-valkey-service.yaml +0 -17
  44. package/manifests/valkey/underpost-engine-valkey-statefulset.yaml +0 -39
package/src/cli/deploy.js CHANGED
@@ -32,7 +32,7 @@ class UnderpostDeploy {
32
32
  await Config.build(undefined, 'proxy', deployList);
33
33
  return buildPortProxyRouter(env === 'development' ? 80 : 443, buildProxyRouter());
34
34
  },
35
- async buildManifest(deployList, env) {
35
+ async buildManifest(deployList, env, version) {
36
36
  for (const _deployId of deployList.split(',')) {
37
37
  const deployId = _deployId.trim();
38
38
  if (!deployId) continue;
@@ -69,7 +69,27 @@ spec:
69
69
  spec:
70
70
  containers:
71
71
  - name: ${deployId}-${env}
72
- image: localhost/${deployId}-${env}:${Underpost.version}
72
+ image: localhost/underpost-engine:${version && typeof version === 'string' ? version : Underpost.version}
73
+ lifecycle:
74
+ postStart:
75
+ exec:
76
+ command:
77
+ - /bin/sh
78
+ - -c
79
+ - >
80
+ sleep 60 &&
81
+ npm install -g underpost
82
+ underpost secret underpost --create-from-file /etc/config/.env.${env}
83
+ underpost config set deploy-id ${deployId} &&
84
+ underpost config set deploy-env ${env}
85
+ volumeMounts:
86
+ - name: config-volume
87
+ mountPath: /etc/config
88
+ volumes:
89
+ - name: config-volume
90
+ configMap:
91
+ name: underpost-config
92
+ # image: localhost/${deployId}-${env}:${version && typeof version === 'string' ? version : Underpost.version}
73
93
  ---
74
94
  apiVersion: v1
75
95
  kind: Service
@@ -180,32 +200,59 @@ spec:
180
200
  async callback(
181
201
  deployList = 'default',
182
202
  env = 'development',
183
- options = { remove: false, infoRouter: false, sync: false, buildManifest: false },
203
+ options = {
204
+ remove: false,
205
+ infoRouter: false,
206
+ sync: false,
207
+ buildManifest: false,
208
+ infoUtil: false,
209
+ expose: false,
210
+ cert: false,
211
+ version: '',
212
+ },
184
213
  ) {
214
+ if (options.infoUtil === true)
215
+ return logger.info(`
216
+ kubectl rollout restart deployment/deployment-name
217
+ kubectl rollout undo deployment/deployment-name
218
+ kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
219
+ `);
185
220
  if (deployList === 'dd' && fs.existsSync(`./engine-private/deploy/dd.router`))
186
221
  deployList = fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8');
187
222
  if (options.sync) UnderpostDeploy.API.sync(deployList);
188
- if (options.buildManifest === true) await UnderpostDeploy.API.buildManifest(deployList, env);
223
+ if (options.buildManifest === true) await UnderpostDeploy.API.buildManifest(deployList, env, options.version);
189
224
  if (options.infoRouter === true)
190
225
  return logger.info('router', await UnderpostDeploy.API.routerFactory(deployList, env));
226
+ shellExec(`kubectl delete configmap underpost-config`);
227
+ shellExec(
228
+ `kubectl create configmap underpost-config --from-file=/home/dd/engine/engine-private/conf/dd-cron/.env.${env}`,
229
+ );
230
+ const etcHost = (
231
+ concat,
232
+ ) => `127.0.0.1 ${concat} localhost localhost.localdomain localhost4 localhost4.localdomain4
233
+ ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6`;
234
+ let concatHots = '';
191
235
 
192
236
  for (const _deployId of deployList.split(',')) {
193
237
  const deployId = _deployId.trim();
194
238
  if (!deployId) continue;
195
-
239
+ if (options.expose === true) {
240
+ const svc = UnderpostDeploy.API.get(deployId, 'svc')[0];
241
+ const port = parseInt(svc[`PORT(S)`].split('/TCP')[0]);
242
+ logger.info(deployId, {
243
+ svc,
244
+ port,
245
+ });
246
+ shellExec(`sudo kubectl port-forward -n default svc/${svc.NAME} ${port}:${port}`, { async: true });
247
+ continue;
248
+ }
196
249
  shellExec(`sudo kubectl delete svc ${deployId}-${env}-service`);
197
250
  shellExec(`sudo kubectl delete deployment ${deployId}-${env}`);
198
251
 
199
- const etcHost = (
200
- concat,
201
- ) => `127.0.0.1 ${concat} localhost localhost.localdomain localhost4 localhost4.localdomain4
202
- ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6`;
203
- let concatHots = '';
204
-
205
252
  const confServer = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'));
206
253
  for (const host of Object.keys(confServer)) {
207
254
  shellExec(`sudo kubectl delete HTTPProxy ${host}`);
208
- if (env === 'production') shellExec(`sudo kubectl delete Certificate ${host}`);
255
+ if (env === 'production' && options.cert === true) shellExec(`sudo kubectl delete Certificate ${host}`);
209
256
  if (!options.remove === true && env === 'development') concatHots += ` ${host}`;
210
257
  }
211
258
 
@@ -217,39 +264,38 @@ spec:
217
264
  if (!options.remove === true) {
218
265
  shellExec(`sudo kubectl apply -f ./${manifestsPath}/deployment.yaml`);
219
266
  shellExec(`sudo kubectl apply -f ./${manifestsPath}/proxy.yaml`);
220
- if (env === 'production') shellExec(`sudo kubectl apply -f ./${manifestsPath}/secret.yaml`);
267
+ if (env === 'production' && options.cert === true)
268
+ shellExec(`sudo kubectl apply -f ./${manifestsPath}/secret.yaml`);
221
269
  }
270
+ }
271
+ let renderHosts;
272
+ switch (process.platform) {
273
+ case 'linux':
274
+ {
275
+ switch (env) {
276
+ case 'development':
277
+ renderHosts = etcHost(concatHots);
278
+ fs.writeFileSync(`/etc/hosts`, renderHosts, 'utf8');
222
279
 
223
- let renderHosts;
224
-
225
- switch (process.platform) {
226
- case 'linux':
227
- {
228
- switch (env) {
229
- case 'development':
230
- renderHosts = etcHost(concatHots);
231
- fs.writeFileSync(`/etc/hosts`, renderHosts, 'utf8');
232
-
233
- break;
280
+ break;
234
281
 
235
- default:
236
- break;
237
- }
282
+ default:
283
+ break;
238
284
  }
239
- break;
285
+ }
286
+ break;
240
287
 
241
- default:
242
- break;
243
- }
244
- if (renderHosts)
245
- logger.info(
246
- `
247
- ` + renderHosts,
248
- );
288
+ default:
289
+ break;
249
290
  }
291
+ if (renderHosts)
292
+ logger.info(
293
+ `
294
+ ` + renderHosts,
295
+ );
250
296
  },
251
- getPods(deployId) {
252
- const raw = shellExec(`sudo kubectl get pods --all-namespaces -o wide`, {
297
+ get(deployId, kindType = 'pods') {
298
+ const raw = shellExec(`sudo kubectl get ${kindType} --all-namespaces -o wide`, {
253
299
  stdout: true,
254
300
  disableLog: true,
255
301
  silent: true,
package/src/cli/env.js CHANGED
@@ -30,7 +30,7 @@ class UnderpostRootEnv {
30
30
  const envPath = `${exeRootPath}/.env`;
31
31
  if (!fs.existsSync(envPath)) return logger.error(`Unable to find underpost root environment`);
32
32
  const env = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
33
- logger.info('underpost root', { [key]: env[key] });
33
+ logger.info(`${key}(${typeof env[key]})`, env[key]);
34
34
  return env[key];
35
35
  },
36
36
  list() {
package/src/cli/fs.js ADDED
@@ -0,0 +1,149 @@
1
+ import { v2 as cloudinary } from 'cloudinary';
2
+ import { loggerFactory } from '../server/logger.js';
3
+ import dotenv from 'dotenv';
4
+ import AdmZip from 'adm-zip';
5
+ import * as dir from 'path';
6
+ import fs from 'fs-extra';
7
+ import { Downloader } from '../server/downloader.js';
8
+ import UnderpostRepository from './repository.js';
9
+ import { shellExec } from '../server/process.js';
10
+ dotenv.config();
11
+
12
+ const logger = loggerFactory(import.meta);
13
+
14
+ class UnderpostFileStorage {
15
+ static API = {
16
+ cloudinaryConfig() {
17
+ // https://console.cloudinary.com/
18
+ cloudinary.config({
19
+ cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
20
+ api_key: process.env.CLOUDINARY_API_KEY,
21
+ api_secret: process.env.CLOUDINARY_API_SECRET,
22
+ });
23
+ },
24
+ getStorageConf(options) {
25
+ let storage, storageConf;
26
+ if (options.deployId && typeof options.deployId === 'string') {
27
+ storageConf = `./engine-private/conf/${options.deployId}/storage.json`;
28
+ if (!fs.existsSync(storageConf)) fs.writeFileSync(storageConf, JSON.stringify({}), 'utf8');
29
+ storage = JSON.parse(fs.readFileSync(storageConf, 'utf8'));
30
+ }
31
+ return { storage, storageConf };
32
+ },
33
+ writeStorageConf(storage, storageConf) {
34
+ if (storage) fs.writeFileSync(storageConf, JSON.stringify(storage, null, 4), 'utf8');
35
+ },
36
+ async recursiveCallback(
37
+ path,
38
+ options = { rm: false, recursive: false, deployId: '', force: false, pull: false, git: false },
39
+ ) {
40
+ const { storage, storageConf } = UnderpostFileStorage.API.getStorageConf(options);
41
+ const deleteFiles = UnderpostRepository.API.getDeleteFiles(path);
42
+ for (const relativePath of deleteFiles) {
43
+ const _path = path + '/' + relativePath;
44
+ if (_path in storage) {
45
+ await UnderpostFileStorage.API.delete(_path);
46
+ delete storage[_path];
47
+ }
48
+ }
49
+ const files =
50
+ options.git === true
51
+ ? UnderpostRepository.API.getChangedFiles(path)
52
+ : await fs.readdir(path, { recursive: true });
53
+ if (options.pull === true) {
54
+ for (const _path of Object.keys(storage)) {
55
+ if (!fs.existsSync(_path) || options.force === true) {
56
+ if (options.force === true && fs.existsSync(_path)) fs.removeSync(_path);
57
+ await UnderpostFileStorage.API.pull(_path, options);
58
+ } else logger.warn(`Pull path already exists`, _path);
59
+ }
60
+ } else
61
+ for (const relativePath of files) {
62
+ const _path = path + '/' + relativePath;
63
+ if (fs.statSync(_path).isDirectory()) {
64
+ if (options.pull === true && !fs.existsSync(_path)) fs.mkdirSync(_path, { recursive: true });
65
+ continue;
66
+ } else if (!(_path in storage) || options.force === true) {
67
+ await UnderpostFileStorage.API.upload(_path, options);
68
+ if (storage) storage[_path] = {};
69
+ } else logger.warn('File already exists', _path);
70
+ }
71
+ UnderpostFileStorage.API.writeStorageConf(storage, storageConf);
72
+ if (options.git === true) {
73
+ shellExec(`cd ${path} && git add .`);
74
+ shellExec(`underpost cmt ${path} feat`);
75
+ }
76
+ },
77
+ async callback(
78
+ path,
79
+ options = { rm: false, recursive: false, deployId: '', force: false, pull: false, git: false },
80
+ ) {
81
+ if (options.recursive === true || options.git === true)
82
+ return await UnderpostFileStorage.API.recursiveCallback(path, options);
83
+ if (options.pull === true) return await UnderpostFileStorage.API.pull(path, options);
84
+ if (options.rm === true) return await UnderpostFileStorage.API.delete(path, options);
85
+ return await UnderpostFileStorage.API.upload(path, options);
86
+ },
87
+ async upload(path, options = { rm: false, recursive: false, deployId: '', force: false, pull: false }) {
88
+ UnderpostFileStorage.API.cloudinaryConfig();
89
+ const { storage, storageConf } = UnderpostFileStorage.API.getStorageConf(options);
90
+ // path = UnderpostFileStorage.API.file2Zip(path);
91
+ const uploadResult = await cloudinary.uploader
92
+ .upload(path, {
93
+ public_id: path,
94
+ resource_type: 'raw',
95
+ overwrite: options.force === true ? true : false,
96
+ })
97
+ .catch((error) => {
98
+ logger.error(error, { path, stack: error.stack });
99
+ });
100
+ logger.info('upload result', uploadResult);
101
+ if (storage) storage[path] = {};
102
+ UnderpostFileStorage.API.writeStorageConf(storage, storageConf);
103
+ return uploadResult;
104
+ },
105
+ async pull(path) {
106
+ UnderpostFileStorage.API.cloudinaryConfig();
107
+ const folder = dir.dirname(path);
108
+ if (!fs.existsSync(folder)) fs.mkdirSync(folder, { recursive: true });
109
+ const downloadResult = await cloudinary.utils.download_archive_url({
110
+ public_ids: [path],
111
+ resource_type: 'raw',
112
+ });
113
+ logger.info('download result', downloadResult);
114
+ await Downloader(downloadResult, path + '.zip');
115
+ path = UnderpostFileStorage.API.zip2File(path + '.zip');
116
+ fs.removeSync(path + '.zip');
117
+ },
118
+ async delete(path) {
119
+ UnderpostFileStorage.API.cloudinaryConfig();
120
+ const deleteResult = await cloudinary.api
121
+ .delete_resources([path], { type: 'upload', resource_type: 'raw' })
122
+ .catch((error) => {
123
+ logger.error(error, { path, stack: error.stack });
124
+ });
125
+ logger.info('delete result', deleteResult);
126
+ return deleteResult;
127
+ },
128
+ file2Zip(path) {
129
+ const zip = new AdmZip();
130
+ zip.addLocalFile(path, '/');
131
+ path = path + '.zip';
132
+ zip.writeZip(path);
133
+ return path;
134
+ },
135
+ zip2File(path) {
136
+ const zip = new AdmZip(path);
137
+ path = path.replaceAll('.zip', '');
138
+ zip.extractEntryTo(
139
+ /*entry name*/ path.split('/').pop(),
140
+ /*target path*/ dir.dirname(path),
141
+ /*maintainEntryPath*/ false,
142
+ /*overwrite*/ true,
143
+ );
144
+ return path;
145
+ },
146
+ };
147
+ }
148
+
149
+ export default UnderpostFileStorage;
package/src/cli/image.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import fs from 'fs-extra';
2
2
  import Underpost from '../index.js';
3
- import { shellExec } from '../server/process.js';
3
+ import { shellCd, shellExec } from '../server/process.js';
4
4
  import dotenv from 'dotenv';
5
5
  import { getNpmRootPath } from '../server/conf.js';
6
6
  import { timer } from '../client/components/core/CommonJs.js';
7
+ import UnderpostRootEnv from './env.js';
7
8
 
8
9
  dotenv.config();
9
10
 
@@ -17,9 +18,13 @@ class UnderpostImage {
17
18
  deployId = 'default',
18
19
  env = 'development',
19
20
  path = '.',
20
- options = { imageArchive: false, podmanSave: false },
21
+ options = { imageArchive: false, podmanSave: false, imageName: '', imageVersion: '' },
21
22
  ) {
22
- const imgName = `${deployId}-${env}:${Underpost.version}`;
23
+ const imgName = `${
24
+ options.imageName && typeof options.imageName === 'string' ? options.imageName : `${deployId}-${env}`
25
+ }:${
26
+ options.imageVersion && typeof options.imageVersions === 'string' ? options.imageVersion : Underpost.version
27
+ }`;
23
28
  const podManImg = `localhost/${imgName}`;
24
29
  const imagesStoragePath = `/images`;
25
30
  if (!fs.existsSync(`${path}${imagesStoragePath}`))
@@ -38,17 +43,40 @@ class UnderpostImage {
38
43
  }
39
44
  // --rm --no-cache
40
45
  if (options.imageArchive !== true) {
41
- fs.copyFile(`${getNpmRootPath()}/underpost/.env`, `${path}/.env.underpost`);
42
46
  shellExec(
43
47
  `cd ${path}${secrets}&& sudo podman build -f ./Dockerfile -t ${imgName} --pull=never --cap-add=CAP_AUDIT_WRITE${secretDockerInput}`,
44
48
  );
45
- fs.removeSync(`${path}/.env.underpost`);
46
49
  }
47
50
  if (options.imageArchive !== true || options.podmanSave === true)
48
51
  shellExec(`cd ${path} && podman save -o ${tarFile} ${podManImg}`);
49
52
  shellExec(`cd ${path} && sudo kind load image-archive ${tarFile}`);
50
53
  },
51
- async script(deployId = 'default', env = 'development', options = { run: false }) {
54
+ async script(deployId = 'default', env = 'development', options = { run: false, build: false }) {
55
+ if (deployId === 'service') {
56
+ const _deployId = UnderpostRootEnv.API.get('deploy-id');
57
+ const _env = UnderpostRootEnv.API.get('deploy-env');
58
+ process.env.GITHUB_TOKEN = UnderpostRootEnv.API.get('GITHUB_TOKEN');
59
+ if (_deployId && process.env.GITHUB_TOKEN) {
60
+ deployId = _deployId;
61
+ if (_env) env = _env;
62
+ } else {
63
+ await timer(30 * 1000);
64
+ return await UnderpostImage.API.dockerfile.script(deployId, env, options);
65
+ }
66
+ }
67
+ if (options.build === true) {
68
+ const buildBasePath = `/home/dd`;
69
+ const repoName = `engine-${deployId.split('-')[1]}`;
70
+ shellExec(`cd ${buildBasePath} && underpost clone underpostnet/${repoName}`);
71
+ shellExec(`cd ${buildBasePath} && sudo mv ./${repoName} ./engine`);
72
+ shellExec(`cd ${buildBasePath}/engine && underpost clone underpostnet/${repoName}-private`);
73
+ shellExec(`cd ${buildBasePath}/engine && sudo mv ./${repoName}-private ./engine-private`);
74
+ shellCd(`${buildBasePath}/engine`);
75
+ shellExec(`npm install`);
76
+ const itcScripts = 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
+ }
52
80
  switch (deployId) {
53
81
  case 'dd-lampp':
54
82
  {
@@ -97,7 +125,7 @@ class UnderpostImage {
97
125
  const replicas = await fs.readdir(`./engine-private/replica`);
98
126
  for (const replica of replicas) {
99
127
  shellExec(`node bin/deploy conf ${replica} ${env}`);
100
- shellExec(`npm ${runCmd} ${replica} deploy`, { async: true });
128
+ shellExec(`npm ${runCmd} deploy deploy-id:${replica}`, { async: true });
101
129
  fs.writeFileSync(`./tmp/await-deploy`, '', 'utf8');
102
130
  const monitor = async () => {
103
131
  await timer(1000);
@@ -107,7 +135,7 @@ class UnderpostImage {
107
135
  }
108
136
  shellExec(`node bin/deploy conf ${deployId} ${env}`);
109
137
  }
110
- shellExec(`npm ${runCmd} ${deployId} deploy`);
138
+ shellExec(`npm ${runCmd} deploy deploy-id:${deployId}`);
111
139
  }
112
140
  },
113
141
  },
@@ -98,6 +98,27 @@ class UnderpostRepository {
98
98
  }
99
99
  });
100
100
  },
101
+
102
+ getDeleteFiles(path = '.') {
103
+ const commandUntrack = `cd ${path} && git ls-files --deleted`;
104
+ const diffUntrackOutput = shellExec(commandUntrack, { stdout: true, silent: true });
105
+ return diffUntrackOutput.toString().split('\n').filter(Boolean);
106
+ },
107
+
108
+ getChangedFiles(path = '.', extension = '', head = false) {
109
+ const extensionFilter = extension ? `-- '***.${extension}'` : '';
110
+ const command = `cd ${path} && git diff ${head ? 'HEAD^ HEAD ' : ''}--name-only ${extensionFilter}`;
111
+ const commandUntrack = `cd ${path} && git ls-files --others --exclude-standard`;
112
+ const diffOutput = shellExec(command, { stdout: true, silent: true });
113
+ const diffUntrackOutput = shellExec(commandUntrack, { stdout: true, silent: true });
114
+ const deleteFiles = UnderpostRepository.API.getDeleteFiles(path);
115
+ return diffOutput
116
+ .toString()
117
+ .split('\n')
118
+ .filter(Boolean)
119
+ .concat(diffUntrackOutput.toString().split('\n').filter(Boolean))
120
+ .filter((f) => !deleteFiles.includes(f));
121
+ },
101
122
  };
102
123
  }
103
124
 
package/src/cli/script.js CHANGED
@@ -26,13 +26,13 @@ class UnderpostScript {
26
26
  const podMatch = options.podName && typeof options.podName === 'string' ? options.podName : key;
27
27
 
28
28
  if (fs.existsSync(`${value}`)) {
29
- for (const pod of UnderpostDeploy.API.getPods(podMatch)) {
29
+ for (const pod of UnderpostDeploy.API.get(podMatch)) {
30
30
  shellExec(`sudo kubectl cp ${value} ${nameSpace}/${pod.NAME}:${podScriptPath}`);
31
31
  const cmd = `node ${podScriptPath}`;
32
32
  shellExec(`sudo kubectl exec -i ${pod.NAME} -- sh -c "${cmd}"`);
33
33
  }
34
34
  } else {
35
- for (const pod of UnderpostDeploy.API.getPods(podMatch)) {
35
+ for (const pod of UnderpostDeploy.API.get(podMatch)) {
36
36
  shellExec(`sudo kubectl exec -i ${pod.NAME} -- sh -c "${value}"`);
37
37
  }
38
38
  }
package/src/cli/test.js CHANGED
@@ -36,10 +36,10 @@ class UnderpostTest {
36
36
  options.podStatus &&
37
37
  typeof options.podStatus === 'string'
38
38
  )
39
- return await UnderpostTest.API.podStatusMonitor(options.podName, options.podStatus);
39
+ return await UnderpostTest.API.statusMonitor(options.podName, options.podStatus, options.kindType);
40
40
 
41
41
  if (options.sh === true || options.logs === true) {
42
- const [pod] = UnderpostDeploy.API.getPods(deployList);
42
+ const [pod] = UnderpostDeploy.API.get(deployList);
43
43
  if (pod) {
44
44
  if (options.sh) return pbcopy(`sudo kubectl exec -it ${pod.NAME} -- sh`);
45
45
  if (options.logs) return shellExec(`sudo kubectl logs -f ${pod.NAME}`);
@@ -73,7 +73,7 @@ class UnderpostTest {
73
73
  break;
74
74
  }
75
75
  else {
76
- const pods = UnderpostDeploy.API.getPods(deployId);
76
+ const pods = UnderpostDeploy.API.get(deployId);
77
77
  if (pods.length > 0)
78
78
  for (const deployData of pods) {
79
79
  const { NAME } = deployData;
@@ -86,16 +86,27 @@ class UnderpostTest {
86
86
  }
87
87
  } else return UnderpostTest.API.run();
88
88
  },
89
- podStatusMonitor(podName, status = 'Running', deltaMs = 1000) {
89
+ statusMonitor(podName, status = 'Running', kindType = '', deltaMs = 1000, maxAttempts = 60 * 5) {
90
+ if (!(kindType && typeof kindType === 'string')) kindType = 'pods';
90
91
  return new Promise(async (resolve) => {
91
92
  let index = 0;
92
- logger.info(`Loading ${podName} instance`, { status, deltaMs });
93
+ logger.info(`Loading instance`, { podName, status, kindType, deltaMs, maxAttempts });
93
94
  const _monitor = async () => {
94
95
  await timer(deltaMs);
95
- const result = UnderpostDeploy.API.getPods(podName).find((p) => p.STATUS === status);
96
- logger.info(`Testing pod ${podName}... ${result ? 1 : 0}/1 - elapsed time ${deltaMs * (index + 1)}ms`);
97
- if (result) return resolve();
96
+ const pods = UnderpostDeploy.API.get(podName, kindType);
97
+ const result = pods.find((p) => p.STATUS === status);
98
+ logger.info(
99
+ `Testing pod ${podName}... ${result ? 1 : 0}/1 - elapsed time ${deltaMs * (index + 1)}s - attempt ${
100
+ index + 1
101
+ }/${maxAttempts}`,
102
+ pods[0] ? pods[0].STATUS : 'Not found kind object',
103
+ );
104
+ if (result) return resolve(true);
98
105
  index++;
106
+ if (index === maxAttempts) {
107
+ logger.error(`Failed to test pod ${podName} within ${maxAttempts} attempts`);
108
+ return resolve(false);
109
+ }
99
110
  return _monitor();
100
111
  };
101
112
  await _monitor();
@@ -404,7 +404,15 @@ const CalendarCore = {
404
404
  <div class="in" style="margin-bottom: 100px"></div>`;
405
405
  };
406
406
 
407
+ let delayBlock = false;
407
408
  this.Data[options.idModal].updatePanel = async () => {
409
+ if (delayBlock) return;
410
+ else {
411
+ delayBlock = true;
412
+ setTimeout(() => {
413
+ delayBlock = false;
414
+ }, 500);
415
+ }
408
416
  const cid = getQueryParams().cid ? getQueryParams().cid : '';
409
417
  if (options.route === 'home') Modal.homeCid = newInstance(cid);
410
418
  if (s(`.main-body-calendar-${options.idModal}`)) {
@@ -426,7 +434,10 @@ const CalendarCore = {
426
434
  },
427
435
  });
428
436
 
429
- if (options.route === 'home') setTimeout(CalendarCore.Data[options.idModal].updatePanel);
437
+ // if (options.route === 'home')
438
+ setTimeout(() => {
439
+ CalendarCore.Data[options.idModal].updatePanel();
440
+ });
430
441
 
431
442
  return html`
432
443
  <style>
@@ -890,8 +890,58 @@ const commitData = {
890
890
  },
891
891
  };
892
892
 
893
- const userRoleEnum = ['admin', 'moderator', 'user', 'guest'];
893
+ const emotionsData = [
894
+ {
895
+ name: 'like',
896
+ ad_display: {
897
+ es: 'Me gusta',
898
+ en: 'Like',
899
+ },
900
+ emoji: '👍',
901
+ },
902
+ {
903
+ name: 'love',
904
+ ad_display: {
905
+ es: 'Me encanta',
906
+ en: 'Love',
907
+ },
908
+ emoji: '❤️',
909
+ },
910
+ {
911
+ name: 'haha',
912
+ ad_display: {
913
+ es: 'Me divierte',
914
+ en: 'Haha',
915
+ },
916
+ emoji: '😂',
917
+ },
918
+ {
919
+ name: 'wow',
920
+ ad_display: {
921
+ es: 'Me asombra',
922
+ en: 'Wow',
923
+ },
924
+ emoji: '😮',
925
+ },
926
+ {
927
+ name: 'sad',
928
+ ad_display: {
929
+ es: 'Me entristece',
930
+ en: 'Sad',
931
+ },
932
+ emoji: '😢',
933
+ },
934
+ {
935
+ name: 'angry',
936
+ ad_display: {
937
+ es: 'Me enoja',
938
+ en: 'Angry',
939
+ },
940
+ emoji: '😠',
941
+ },
942
+ ];
894
943
 
944
+ const userRoleEnum = ['admin', 'moderator', 'user', 'guest'];
895
945
  const commonAdminGuard = (role) => userRoleEnum.indexOf(role) === userRoleEnum.indexOf('admin');
896
946
  const commonModeratorGuard = (role) => userRoleEnum.indexOf(role) <= userRoleEnum.indexOf('moderator');
897
947
 
@@ -954,4 +1004,5 @@ export {
954
1004
  getCurrentTrace,
955
1005
  userRoleEnum,
956
1006
  commitData,
1007
+ emotionsData,
957
1008
  };
@@ -396,8 +396,7 @@ const CssCoreDark = {
396
396
  text-align: center;
397
397
  background: #1a1a1a;
398
398
  font-size: 17px;
399
- padding-top: 7px;
400
- padding-bottom: 6px;
399
+ height: 35px;
401
400
  }
402
401
  ::placeholder {
403
402
  color: #c6c4c4;
@@ -701,8 +700,7 @@ const CssCoreLight = {
701
700
  text-align: center;
702
701
  background: #eaeaea;
703
702
  font-size: 17px;
704
- padding-top: 7px;
705
- padding-bottom: 6px;
703
+ height: 35px;
706
704
  }
707
705
  ::placeholder {
708
706
  color: #333;
@@ -1,4 +1,3 @@
1
- import { _VERSION, CoreService } from '../../services/core/core.service.js';
2
1
  import { Badge } from './Badge.js';
3
2
  import { BtnIcon } from './BtnIcon.js';
4
3
  import { rgbToHex } from './CommonJs.js';
@@ -80,7 +79,7 @@ const Docs = {
80
79
  icon: html`<i class="fa-brands fa-osi"></i>`,
81
80
  text: 'Source Docs',
82
81
  url: function () {
83
- return `${getProxyPath()}docs/engine/${_VERSION}`;
82
+ return `${getProxyPath()}docs/engine/${window.renderPayload.version}`;
84
83
  },
85
84
  },
86
85
  {
@@ -88,8 +88,10 @@ const Input = {
88
88
  <div class="fl input-row-${id}">
89
89
  <div class="in fll" style="width: 80%;">${inputElement}</div>
90
90
  <div class="in fll btn-eye-password btn-eye-${id}" style="width: 20%;">
91
- <i class="fas fa-eye fa-eye-${id} eye-password"></i>
92
- <i class="fas fa-eye-slash fa-eye-slash-${id} eye-password" style="display: none"></i>
91
+ <div class="abs center">
92
+ <i class="fas fa-eye fa-eye-${id} eye-password"></i>
93
+ <i class="fas fa-eye-slash fa-eye-slash-${id} eye-password" style="display: none"></i>
94
+ </div>
93
95
  </div>
94
96
  </div>
95
97
  `