underpost 2.8.85 → 2.8.87
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/.env.development +7 -2
- package/.env.production +7 -2
- package/.env.test +7 -2
- package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -1
- package/.github/workflows/release.cd.yml +37 -0
- package/README.md +7 -24
- package/bin/build.js +1 -0
- package/bin/db.js +1 -3
- package/bin/deploy.js +43 -368
- package/bin/file.js +16 -3
- package/bin/util.js +1 -56
- package/cli.md +46 -21
- package/conf.js +3 -3
- package/manifests/deployment/{dd-template-development → dd-default-development}/deployment.yaml +16 -16
- package/manifests/deployment/{dd-template-development → dd-default-development}/proxy.yaml +3 -3
- package/manifests/deployment/mongo-express/deployment.yaml +12 -12
- package/manifests/grafana/deployment.yaml +57 -0
- package/manifests/grafana/kustomization.yaml +7 -0
- package/manifests/grafana/pvc.yaml +12 -0
- package/manifests/grafana/service.yaml +14 -0
- package/manifests/maas/nvim.sh +91 -0
- package/manifests/maas/ssh-cluster-info.sh +14 -0
- package/manifests/prometheus/deployment.yaml +82 -0
- package/package.json +3 -12
- package/src/api/file/file.service.js +28 -8
- package/src/api/user/user.router.js +31 -5
- package/src/api/user/user.service.js +11 -38
- package/src/cli/cluster.js +45 -25
- package/src/cli/cron.js +12 -45
- package/src/cli/db.js +149 -19
- package/src/cli/deploy.js +41 -110
- package/src/cli/fs.js +1 -0
- package/src/cli/index.js +24 -7
- package/src/cli/monitor.js +1 -4
- package/src/cli/repository.js +15 -6
- package/src/cli/run.js +94 -16
- package/src/client/Default.index.js +0 -2
- package/src/client/components/core/Account.js +6 -2
- package/src/client/components/core/Content.js +11 -7
- package/src/client/components/core/Css.js +5 -1
- package/src/client/components/core/CssCore.js +12 -0
- package/src/client/components/core/FullScreen.js +19 -28
- package/src/client/components/core/Input.js +7 -1
- package/src/client/components/core/LogIn.js +3 -0
- package/src/client/components/core/LogOut.js +1 -1
- package/src/client/components/core/Modal.js +32 -43
- package/src/client/components/core/ObjectLayerEngine.js +229 -4
- package/src/client/components/core/ObjectLayerEngineModal.js +441 -0
- package/src/client/components/core/Recover.js +5 -2
- package/src/client/components/core/Scroll.js +65 -120
- package/src/client/components/core/SignUp.js +1 -0
- package/src/client/components/core/ToggleSwitch.js +15 -1
- package/src/client/components/core/VanillaJs.js +48 -2
- package/src/client/components/default/MenuDefault.js +2 -2
- package/src/client/components/default/RoutesDefault.js +3 -3
- package/src/client/public/default/assets/mailer/api-user-default-avatar.png +0 -0
- package/src/index.js +1 -1
- package/src/mailer/MailerProvider.js +37 -0
- package/src/server/client-build-docs.js +1 -1
- package/src/server/client-build-live.js +1 -1
- package/src/server/client-build.js +4 -12
- package/src/server/client-dev-server.js +1 -1
- package/src/server/client-icons.js +6 -78
- package/src/server/conf.js +83 -408
- package/src/server/proxy.js +2 -3
- package/src/server/runtime.js +1 -2
- package/src/server/start.js +5 -5
- package/test/api.test.js +3 -2
- package/docker-compose.yml +0 -67
- package/prometheus.yml +0 -36
|
@@ -67,7 +67,7 @@ const ToggleSwitch = {
|
|
|
67
67
|
|
|
68
68
|
if (options.type === 'checkbox') {
|
|
69
69
|
}
|
|
70
|
-
|
|
70
|
+
const htmlRender = html`
|
|
71
71
|
${options?.displayMode === 'checkbox'
|
|
72
72
|
? html`<div class="${options?.containerClass ? options.containerClass : 'inl box-content-border'} ${id}">
|
|
73
73
|
<div class="in ${id}-content toggle-switch-content-checkbox">
|
|
@@ -81,6 +81,20 @@ const ToggleSwitch = {
|
|
|
81
81
|
</div>`}
|
|
82
82
|
<input type="checkbox" class="${id}-checkbox" style="display: none" />
|
|
83
83
|
`;
|
|
84
|
+
if (options.wrapper) {
|
|
85
|
+
setTimeout(() => (s(`.toggle-form-container-${id}`).onclick = () => ToggleSwitch.Tokens[`${id}`].click()));
|
|
86
|
+
return html`
|
|
87
|
+
<div class="in toggle-form-container toggle-form-container-${id} hover">
|
|
88
|
+
<div class="fl ">
|
|
89
|
+
<div class="in fll" style="width: 70%">
|
|
90
|
+
<div class="in">${options.wrapperLabel}</div>
|
|
91
|
+
</div>
|
|
92
|
+
<div class="in fll" style="width: 30%">${htmlRender}</div>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
`;
|
|
96
|
+
}
|
|
97
|
+
return htmlRender;
|
|
84
98
|
},
|
|
85
99
|
};
|
|
86
100
|
|
|
@@ -147,8 +147,40 @@ const pasteData = () => new Promise((resolve) => navigator.clipboard.readText().
|
|
|
147
147
|
* @memberof VanillaJS
|
|
148
148
|
*/
|
|
149
149
|
const setPath = (path = '/', stateStorage = {}, title = '') => {
|
|
150
|
-
if (
|
|
151
|
-
|
|
150
|
+
if (!path) path = '/';
|
|
151
|
+
|
|
152
|
+
const [inputPath, inputSearch] = `${path}`.split('?');
|
|
153
|
+
|
|
154
|
+
let sanitizedPath = (inputPath[0] !== '/' ? `/${inputPath}` : inputPath)
|
|
155
|
+
.trim()
|
|
156
|
+
.replaceAll('//', '/')
|
|
157
|
+
.replaceAll(`\\`, '/');
|
|
158
|
+
|
|
159
|
+
if (sanitizedPath.length > 1 && sanitizedPath[sanitizedPath.length - 1] === '/')
|
|
160
|
+
sanitizedPath = sanitizedPath.slice(0, -1);
|
|
161
|
+
|
|
162
|
+
if (window.location.pathname === sanitizedPath && (!inputSearch || inputSearch === location.search)) {
|
|
163
|
+
console.warn('Prevent overwriting same path', {
|
|
164
|
+
inputPath: inputPath,
|
|
165
|
+
inputSearch: inputSearch,
|
|
166
|
+
sanitizedPath: sanitizedPath,
|
|
167
|
+
currentLocationSearch: location.search,
|
|
168
|
+
currentLocationHash: location.hash,
|
|
169
|
+
});
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
console.warn('Set path', {
|
|
173
|
+
inputPath: inputPath,
|
|
174
|
+
inputSearch: inputSearch,
|
|
175
|
+
sanitizedPath: sanitizedPath,
|
|
176
|
+
currentLocationSearch: location.search,
|
|
177
|
+
currentLocationHash: location.hash,
|
|
178
|
+
});
|
|
179
|
+
return history.pushState(
|
|
180
|
+
stateStorage,
|
|
181
|
+
title,
|
|
182
|
+
`${sanitizedPath}${inputSearch ? `?${inputSearch}` : ''}${location.hash ?? ''}`,
|
|
183
|
+
);
|
|
152
184
|
};
|
|
153
185
|
|
|
154
186
|
/**
|
|
@@ -425,6 +457,19 @@ const getLang = () =>
|
|
|
425
457
|
.slice(0, 2)
|
|
426
458
|
.toLowerCase();
|
|
427
459
|
|
|
460
|
+
function hexToRgbA(hex) {
|
|
461
|
+
let c;
|
|
462
|
+
if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) {
|
|
463
|
+
c = hex.substring(1).split('');
|
|
464
|
+
if (c.length == 3) {
|
|
465
|
+
c = [c[0], c[0], c[1], c[1], c[2], c[2]];
|
|
466
|
+
}
|
|
467
|
+
c = '0x' + c.join('');
|
|
468
|
+
return [(c >> 16) & 255, (c >> 8) & 255, c & 255];
|
|
469
|
+
}
|
|
470
|
+
throw new Error('Invalid Hex');
|
|
471
|
+
}
|
|
472
|
+
|
|
428
473
|
export {
|
|
429
474
|
s,
|
|
430
475
|
htmls,
|
|
@@ -454,4 +499,5 @@ export {
|
|
|
454
499
|
isDevInstance,
|
|
455
500
|
getDataFromInputFile,
|
|
456
501
|
getLang,
|
|
502
|
+
hexToRgbA,
|
|
457
503
|
};
|
|
@@ -35,7 +35,7 @@ const MenuDefault = {
|
|
|
35
35
|
const id = getId(this.Data, 'menu-');
|
|
36
36
|
this.Data[id] = {};
|
|
37
37
|
const RouterInstance = RouterDefault();
|
|
38
|
-
const {
|
|
38
|
+
const { BannerAppTemplate } = RouterInstance;
|
|
39
39
|
const { barConfig } = await Themes[Css.currentTheme]();
|
|
40
40
|
const heightTopBar = 50;
|
|
41
41
|
const heightBottomBar = 50;
|
|
@@ -162,7 +162,7 @@ const MenuDefault = {
|
|
|
162
162
|
</div>
|
|
163
163
|
`,
|
|
164
164
|
barConfig: newInstance(barConfig),
|
|
165
|
-
title:
|
|
165
|
+
title: BannerAppTemplate,
|
|
166
166
|
// titleClass: 'hide',
|
|
167
167
|
titleRender: () => {
|
|
168
168
|
ThemeEvents['titleRender'] = () => {
|
|
@@ -4,7 +4,7 @@ import { getProxyPath, s } from '../core/VanillaJs.js';
|
|
|
4
4
|
|
|
5
5
|
const logger = loggerFactory(import.meta);
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const BannerAppTemplate = html`<strong class="inl" style="font-family: system-ui">PWA</strong>`;
|
|
8
8
|
|
|
9
9
|
// Router
|
|
10
10
|
const RoutesDefault = () => {
|
|
@@ -39,7 +39,7 @@ const RoutesDefault = () => {
|
|
|
39
39
|
window.Routes = RoutesDefault;
|
|
40
40
|
|
|
41
41
|
const RouterDefault = () => {
|
|
42
|
-
return { Routes: RoutesDefault,
|
|
42
|
+
return { Routes: RoutesDefault, BannerAppTemplate };
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
export { RoutesDefault, RouterDefault,
|
|
45
|
+
export { RoutesDefault, RouterDefault, BannerAppTemplate };
|
package/src/index.js
CHANGED
|
@@ -48,6 +48,43 @@ const MailerProvider = {
|
|
|
48
48
|
...options,
|
|
49
49
|
transporter,
|
|
50
50
|
templates: await EmailRender.getTemplates(options),
|
|
51
|
+
translateTemplates: {
|
|
52
|
+
confirmEmail: {
|
|
53
|
+
H1: {
|
|
54
|
+
en: 'Confirm Your Email',
|
|
55
|
+
es: 'Confirma tu correo electrónico',
|
|
56
|
+
},
|
|
57
|
+
P1: {
|
|
58
|
+
en: `Email confirmed! Thanks.
|
|
59
|
+
<br />
|
|
60
|
+
<span style="font-size: 12px; color: gray">
|
|
61
|
+
If it is not automatically verified,
|
|
62
|
+
please allow the image to be seen, thank you.
|
|
63
|
+
</span>
|
|
64
|
+
`,
|
|
65
|
+
es: `Correo electrónico confirmado! Gracias.
|
|
66
|
+
<br />
|
|
67
|
+
<span style="font-size: 12px; color: gray">
|
|
68
|
+
Si no se verifica automáticamente, por favor permita que se vea la imagen, gracias.
|
|
69
|
+
</span>
|
|
70
|
+
`,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
recoverEmail: {
|
|
74
|
+
H1: {
|
|
75
|
+
en: 'Recover your account',
|
|
76
|
+
es: 'Recupera tu cuenta',
|
|
77
|
+
},
|
|
78
|
+
P1: {
|
|
79
|
+
en: 'To recover your account, please click the button below:',
|
|
80
|
+
es: 'Para recuperar tu cuenta, haz click en el botón de abajo:',
|
|
81
|
+
},
|
|
82
|
+
BTN_LABEL: {
|
|
83
|
+
en: 'Recover Password',
|
|
84
|
+
es: 'Recuperar Contraseña',
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
51
88
|
};
|
|
52
89
|
|
|
53
90
|
return this.instance[id];
|
|
@@ -159,7 +159,7 @@ const buildCoverage = async ({ host, path }) => {
|
|
|
159
159
|
shellExec(`npm test`);
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
const coverageBuildPath = `${jsDocsConfig.opts.destination}
|
|
162
|
+
const coverageBuildPath = `${jsDocsConfig.opts.destination}coverage`;
|
|
163
163
|
fs.mkdirSync(coverageBuildPath, { recursive: true });
|
|
164
164
|
fs.copySync(`./coverage`, coverageBuildPath);
|
|
165
165
|
|
|
@@ -59,7 +59,7 @@ const clientLiveBuild = async () => {
|
|
|
59
59
|
const updates = JSON.parse(fs.readFileSync(`./tmp/client.build.json`, 'utf8'));
|
|
60
60
|
const liveClientBuildPaths = [];
|
|
61
61
|
for (let srcPath of updates) {
|
|
62
|
-
srcPath = srcPath.replaceAll('/', `\\`);
|
|
62
|
+
srcPath = srcPath.replaceAll('/', `\\`);
|
|
63
63
|
|
|
64
64
|
const srcBuildPath = `./src${srcPath.split('src')[1].replace(/\\/g, '/')}`;
|
|
65
65
|
if (
|
|
@@ -19,7 +19,7 @@ import * as dir from 'path';
|
|
|
19
19
|
import { shellExec } from './process.js';
|
|
20
20
|
import { SitemapStream, streamToPromise } from 'sitemap';
|
|
21
21
|
import { Readable } from 'stream';
|
|
22
|
-
import { buildIcons
|
|
22
|
+
import { buildIcons } from './client-icons.js';
|
|
23
23
|
import Underpost from '../index.js';
|
|
24
24
|
import { buildDocs } from './client-build-docs.js';
|
|
25
25
|
|
|
@@ -65,16 +65,8 @@ const fullBuild = async ({
|
|
|
65
65
|
fs.removeSync(rootClientPath);
|
|
66
66
|
|
|
67
67
|
if (fs.existsSync(`./src/client/public/${publicClientId}`)) {
|
|
68
|
-
if (iconsBuild) {
|
|
69
|
-
|
|
70
|
-
if (!fs.existsSync(defaultBaseIconFolderPath)) fs.mkdirSync(defaultBaseIconFolderPath, { recursive: true });
|
|
71
|
-
const defaultBaseIconPath = `${defaultBaseIconFolderPath}/base-icon.png`;
|
|
72
|
-
if (!fs.existsSync(defaultBaseIconPath))
|
|
73
|
-
await buildTextImg(metadata.title, { debugFilename: defaultBaseIconPath });
|
|
74
|
-
|
|
75
|
-
if (!fs.existsSync(`./src/client/public/${publicClientId}/site.webmanifest`))
|
|
76
|
-
await buildIcons({ publicClientId, metadata });
|
|
77
|
-
}
|
|
68
|
+
if (iconsBuild === true) await buildIcons({ publicClientId, metadata });
|
|
69
|
+
|
|
78
70
|
fs.copySync(
|
|
79
71
|
`./src/client/public/${publicClientId}`,
|
|
80
72
|
rootClientPath /* {
|
|
@@ -535,7 +527,7 @@ Sitemap: https://${host}${path === '/' ? '' : path}/sitemap.xml`,
|
|
|
535
527
|
);
|
|
536
528
|
}
|
|
537
529
|
|
|
538
|
-
if (
|
|
530
|
+
if (fullBuildEnabled && !enableLiveRebuild && !process.argv.includes('l') && docsBuild) {
|
|
539
531
|
await buildDocs({
|
|
540
532
|
host,
|
|
541
533
|
path,
|
|
@@ -7,7 +7,7 @@ const logger = loggerFactory(import.meta);
|
|
|
7
7
|
|
|
8
8
|
const createClientDevServer = () => {
|
|
9
9
|
// process.argv.slice(2).join(' ')
|
|
10
|
-
shellExec(`env-cmd -f .env.development node bin/deploy build-full-client ${process.argv.slice(2).join(' ')}
|
|
10
|
+
shellExec(`env-cmd -f .env.development node bin/deploy build-full-client ${process.argv.slice(2).join(' ')}`);
|
|
11
11
|
shellExec(
|
|
12
12
|
`env-cmd -f .env.development node src/api ${process.argv[2]}${process.argv[5] ? ` ${process.argv[5]}` : ''}${
|
|
13
13
|
process.argv.includes('static') ? ' static' : ''
|
|
@@ -1,80 +1,17 @@
|
|
|
1
1
|
import { favicons } from 'favicons';
|
|
2
|
-
// TODO: search alternatives
|
|
3
|
-
// import textToImage from 'text-to-image';
|
|
4
2
|
import { loggerFactory } from './logger.js';
|
|
5
3
|
import fs from 'fs-extra';
|
|
6
|
-
import { getCapVariableName
|
|
7
|
-
import { FileFactory } from '../api/file/file.service.js';
|
|
8
|
-
import { svg, png, png3x } from 'font-awesome-assets';
|
|
4
|
+
import { getCapVariableName } from '../client/components/core/CommonJs.js';
|
|
9
5
|
|
|
10
6
|
const logger = loggerFactory(import.meta);
|
|
11
7
|
|
|
12
|
-
const faBase64Png = (faId = 'check', width = 100, height = 100, color = '#209e00') => {
|
|
13
|
-
const b64Src = png3x(faId, color, width, height);
|
|
14
|
-
return b64Src.split('src="data:image/png;base64,')[1].split('"')[0];
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const defaultBaseTextImgOptions = {
|
|
18
|
-
debug: true,
|
|
19
|
-
fontFamily: 'Arial',
|
|
20
|
-
fontWeight: 'bold',
|
|
21
|
-
bgColor: 'black',
|
|
22
|
-
textColor: 'white',
|
|
23
|
-
debugFilename: 'src/client/public/text-image.png',
|
|
24
|
-
verticalAlign: 'center',
|
|
25
|
-
textAlign: 'center',
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const defaultBaseTextImgOptionsSizes = {
|
|
29
|
-
'70x70': {
|
|
30
|
-
maxWidth: 70,
|
|
31
|
-
customHeight: 70,
|
|
32
|
-
fontSize: 25,
|
|
33
|
-
margin: 10,
|
|
34
|
-
},
|
|
35
|
-
'100x100': {
|
|
36
|
-
maxWidth: 100,
|
|
37
|
-
customHeight: 100,
|
|
38
|
-
fontSize: 30,
|
|
39
|
-
margin: 12,
|
|
40
|
-
},
|
|
41
|
-
'100x300': {
|
|
42
|
-
maxWidth: 300,
|
|
43
|
-
customHeight: 100,
|
|
44
|
-
fontSize: 30,
|
|
45
|
-
margin: 12,
|
|
46
|
-
},
|
|
47
|
-
'1200x1200': {
|
|
48
|
-
maxWidth: 1200,
|
|
49
|
-
customHeight: 1200,
|
|
50
|
-
fontSize: 500,
|
|
51
|
-
margin: 50,
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const buildTextImg = async (text = 'APP', options, size = '1200x1200') => {
|
|
56
|
-
options = { ...defaultBaseTextImgOptions, ...defaultBaseTextImgOptionsSizes[size], ...options };
|
|
57
|
-
// await textToImage.generate(text, options);
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const getBufferPngText = async ({ text, textColor, bgColor, size, debugFilename }) => {
|
|
61
|
-
if (!text) text = 'Hello World!';
|
|
62
|
-
if (!textColor) textColor = '#000000';
|
|
63
|
-
if (!bgColor) bgColor = '#ffffff';
|
|
64
|
-
if (!size) size = '100x300';
|
|
65
|
-
if (!debugFilename) debugFilename = `./${s4()}${s4()}${s4()}.png`;
|
|
66
|
-
await buildTextImg(text, { textColor, bgColor, size, debugFilename }, size);
|
|
67
|
-
if (!fs.existsSync(debugFilename)) return Buffer.alloc(0); // Return empty buffer if file not found
|
|
68
|
-
const bufferImage = fs.readFileSync(debugFilename);
|
|
69
|
-
fs.removeSync(debugFilename);
|
|
70
|
-
return bufferImage;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
8
|
const buildIcons = async ({
|
|
74
9
|
publicClientId,
|
|
75
|
-
metadata: { title, description, keywords, author, thumbnail, themeColor },
|
|
10
|
+
metadata: { title, description, keywords, author, thumbnail, themeColor, baseBuildIconReference },
|
|
76
11
|
}) => {
|
|
77
|
-
const source =
|
|
12
|
+
const source = baseBuildIconReference
|
|
13
|
+
? baseBuildIconReference
|
|
14
|
+
: `src/client/public/${publicClientId}/assets/logo/base-icon.png`; // Source image(s). `string`, `buffer` or array of `string`
|
|
78
15
|
|
|
79
16
|
const configuration = {
|
|
80
17
|
path: '/', // Path for overriding default icons path. `string`
|
|
@@ -149,13 +86,4 @@ const buildIcons = async ({
|
|
|
149
86
|
}
|
|
150
87
|
};
|
|
151
88
|
|
|
152
|
-
|
|
153
|
-
const faId = 'user';
|
|
154
|
-
const tmpFilePath = `./tmp/${faId}-${s4() + s4()}.svg`;
|
|
155
|
-
fs.writeFileSync(tmpFilePath, svg(faId, '#f5f5f5d1'), 'utf8');
|
|
156
|
-
const file = await new File(FileFactory.svg(fs.readFileSync(tmpFilePath), `${faId}.svg`)).save();
|
|
157
|
-
fs.removeSync(tmpFilePath);
|
|
158
|
-
return file._id;
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
export { buildIcons, buildTextImg, defaultBaseTextImgOptions, faBase64Png, getBufferPngText, getDefaultProfileImageId };
|
|
89
|
+
export { buildIcons };
|