underpost 2.8.881 → 2.8.883

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 (36) hide show
  1. package/.github/workflows/release.cd.yml +1 -2
  2. package/README.md +50 -36
  3. package/bin/db.js +1 -4
  4. package/cli.md +86 -86
  5. package/conf.js +1 -0
  6. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  7. package/manifests/deployment/dd-test-development/deployment.yaml +6 -6
  8. package/manifests/maas/device-scan.sh +1 -1
  9. package/package.json +1 -1
  10. package/src/api/document/document.service.js +9 -1
  11. package/src/cli/repository.js +2 -0
  12. package/src/client/components/core/Auth.js +258 -89
  13. package/src/client/components/core/BtnIcon.js +10 -1
  14. package/src/client/components/core/CssCore.js +36 -27
  15. package/src/client/components/core/Docs.js +188 -85
  16. package/src/client/components/core/LoadingAnimation.js +5 -10
  17. package/src/client/components/core/Modal.js +262 -120
  18. package/src/client/components/core/ObjectLayerEngine.js +154 -158
  19. package/src/client/components/core/Panel.js +2 -0
  20. package/src/client/components/core/PanelForm.js +94 -60
  21. package/src/client/components/core/Router.js +15 -15
  22. package/src/client/components/core/ToolTip.js +83 -19
  23. package/src/client/components/core/Translate.js +1 -1
  24. package/src/client/components/core/VanillaJs.js +4 -3
  25. package/src/client/components/core/windowGetDimensions.js +202 -0
  26. package/src/client/components/default/MenuDefault.js +11 -0
  27. package/src/client/ssr/Render.js +1 -1
  28. package/src/index.js +1 -1
  29. package/src/runtime/lampp/Lampp.js +253 -128
  30. package/src/server/auth.js +68 -17
  31. package/src/server/crypto.js +195 -76
  32. package/src/server/peer.js +47 -5
  33. package/src/server/process.js +85 -1
  34. package/src/server/runtime.js +13 -32
  35. package/test/crypto.test.js +117 -0
  36. package/src/runtime/xampp/Xampp.js +0 -83
@@ -1,25 +1,89 @@
1
- import { append } from './VanillaJs.js';
1
+ import { renderCssAttr } from './Css.js';
2
+ import { append, s } from './VanillaJs.js';
3
+ import { Modal } from './Modal.js';
2
4
 
3
5
  const ToolTip = {
4
6
  Tokens: {},
5
- Render: async function (options = { container: '', htmlRender: '', id: '', classList: '' }) {
6
- const { container, htmlRender, id } = options;
7
- const tooltipId = 'tooltip-' + id;
8
- append(
9
- container,
10
- html`
11
- <style>
12
- ${container}:hover .${tooltipId} {
13
- visibility: visible;
14
- }
15
- .${tooltipId} {
16
- visibility: hidden;
17
- }
18
- </style>
19
- <div class="tooltip ${options?.classList ? `${options.classList} ` : ' '}${tooltipId}">${htmlRender}</div>
20
- `,
21
- );
22
- return '';
7
+ Render: async function (
8
+ options = { container: '', htmlRender: '', id: '', classList: '', useVisibilityHover: false, useMenuBtn: false },
9
+ ) {
10
+ const { container, htmlRender, id, useVisibilityHover } = options;
11
+
12
+ if (useVisibilityHover) {
13
+ const tooltipId = 'tooltip-' + id;
14
+ append(
15
+ container,
16
+ html`
17
+ <style>
18
+ ${container}:hover .${tooltipId} {
19
+ visibility: visible;
20
+ }
21
+ .${tooltipId} {
22
+ visibility: hidden;
23
+ }
24
+ </style>
25
+ <div class="tooltip ${options?.classList ? `${options.classList} ` : ' '}${tooltipId}">${htmlRender}</div>
26
+ `,
27
+ );
28
+ return;
29
+ }
30
+
31
+ const containerEl = s(container);
32
+ if (!containerEl) return;
33
+
34
+ const tooltipId = `tooltip-${id}`;
35
+ const tooltip = html`
36
+ <div
37
+ class="fix fix-tooltip ${tooltipId}"
38
+ style="${renderCssAttr({
39
+ style: {
40
+ 'z-index': 10,
41
+ position: 'absolute',
42
+ opacity: 0,
43
+ transition: 'opacity 0.2s ease-in-out',
44
+ 'pointer-events': 'none',
45
+ },
46
+ })}"
47
+ >
48
+ ${htmlRender}
49
+ </div>
50
+ `;
51
+ append('body', tooltip);
52
+
53
+ const tooltipEl = s(`.${tooltipId}`);
54
+
55
+ containerEl.addEventListener('mouseenter', () => {
56
+ if (
57
+ options.useMenuBtn &&
58
+ s(
59
+ `.btn-icon-menu-mode-${Modal.Data['modal-menu'].options.mode === 'slide-menu-right' ? 'left' : 'right'}`,
60
+ ).classList.contains('hide')
61
+ )
62
+ return;
63
+
64
+ const containerRect = containerEl.getBoundingClientRect();
65
+ const tooltipRect = tooltipEl.getBoundingClientRect();
66
+
67
+ let top = containerRect.bottom + window.scrollY + 5;
68
+ let left = containerRect.left + window.scrollX + containerRect.width / 2 - tooltipRect.width / 2;
69
+
70
+ // Adjust if it goes off-screen
71
+ if (left < 0) left = 5;
72
+ if (left + tooltipRect.width > window.innerWidth) {
73
+ left = window.innerWidth - tooltipRect.width - 5;
74
+ }
75
+ if (top + tooltipRect.height > window.innerHeight) {
76
+ top = containerRect.top + window.scrollY - tooltipRect.height - 5;
77
+ }
78
+
79
+ tooltipEl.style.top = `${top}px`;
80
+ tooltipEl.style.left = `${left}px`;
81
+ tooltipEl.style.opacity = '1';
82
+ });
83
+
84
+ containerEl.addEventListener('mouseleave', () => {
85
+ tooltipEl.style.opacity = '0';
86
+ });
23
87
  },
24
88
  };
25
89
 
@@ -34,7 +34,7 @@ const Translate = {
34
34
  Render: function (keyLang, placeholder, options = { disableTextFormat: false }) {
35
35
  if (!(keyLang in this.Data)) {
36
36
  // TODO: add translate package or library for this case
37
- logger.warn('translate key lang does not exist: ', keyLang);
37
+ // logger.warn('translate key lang does not exist: ', keyLang);
38
38
  return options.disableTextFormat ? keyLang : textFormatted(keyLang);
39
39
  }
40
40
  if (placeholder) this.Data[keyLang].placeholder = placeholder;
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import { s4 } from './CommonJs.js';
8
+ import { windowGetH, windowGetW } from './windowGetDimensions.js';
8
9
 
9
10
  /*
10
11
 
@@ -232,10 +233,10 @@ const fullScreenIn = () => {
232
233
  * @memberof VanillaJS
233
234
  */
234
235
  const getResponsiveData = () => {
235
- const inner = { width: window.innerWidth, height: window.innerHeight };
236
+ const inner = { width: windowGetW(), height: windowGetH() };
236
237
  return inner.width > inner.height
237
- ? { ...inner, minValue: window.innerHeight, maxValue: window.innerWidth, minType: 'height', maxType: 'width' }
238
- : { ...inner, minValue: window.innerWidth, maxValue: window.innerHeight, minType: 'width', maxType: 'height' };
238
+ ? { ...inner, minValue: windowGetH(), maxValue: windowGetW(), minType: 'height', maxType: 'width' }
239
+ : { ...inner, minValue: windowGetW(), maxValue: windowGetH(), minType: 'width', maxType: 'height' };
239
240
  };
240
241
 
241
242
  /**
@@ -0,0 +1,202 @@
1
+ /*
2
+ * windowGetDimensions.js
3
+ * ES6 vanilla utilities: windowGetH and windowGetW
4
+ * Returns the most reliable viewport height/width available, with fallbacks
5
+ * from modern to old browsers.
6
+ *
7
+ * Usage:
8
+ * import { windowGetH, windowGetW } from './windowGetDimensions.js';
9
+ * const h = windowGetH();
10
+ * const w = windowGetW();
11
+ *
12
+ * Notes:
13
+ * - visualViewport (when present) reflects the *visible* viewport (changes when
14
+ * the on-screen keyboard opens, or when mobile address/toolbars show/hide).
15
+ * - documentElement.clientHeight/Width reflect the layout viewport.
16
+ * - window.innerHeight/innerWidth include scrollbars and are widely supported.
17
+ * - screen.* values are last-resort and reflect the physical screen, not the
18
+ * browser chrome.
19
+ */
20
+
21
+ // Helper: coerce a candidate to a finite integer (or null if not usable)
22
+ const toInt = (v) => {
23
+ const n = Number(v);
24
+ return Number.isFinite(n) && n > 0 ? Math.round(n) : null;
25
+ };
26
+
27
+ /**
28
+ * Try visualViewport values (most accurate for "what's actually visible").
29
+ * @returns {{height: number|null, width: number|null}}
30
+ */
31
+ const getFromVisualViewport = () => {
32
+ if (typeof window !== 'undefined' && window.visualViewport) {
33
+ const { height, width } = window.visualViewport;
34
+ return { height: toInt(height), width: toInt(width) };
35
+ }
36
+ return { height: null, width: null };
37
+ };
38
+
39
+ /**
40
+ * Try layout viewport (doctype-root) measurements.
41
+ * document.documentElement.clientHeight/clientWidth are stable and widely used.
42
+ * @returns {{height: number|null, width: number|null}}
43
+ */
44
+ const getFromDocumentElement = () => {
45
+ if (typeof document !== 'undefined' && document.documentElement) {
46
+ const { clientHeight, clientWidth } = document.documentElement;
47
+ return { height: toInt(clientHeight), width: toInt(clientWidth) };
48
+ }
49
+ return { height: null, width: null };
50
+ };
51
+
52
+ /**
53
+ * Try window.* measurements (innerHeight/innerWidth are widely supported).
54
+ * @returns {{height: number|null, width: number|null}}
55
+ */
56
+ const getFromWindowInner = () => {
57
+ if (typeof window !== 'undefined') {
58
+ return { height: toInt(window.innerHeight), width: toInt(window.innerWidth) };
59
+ }
60
+ return { height: null, width: null };
61
+ };
62
+
63
+ /**
64
+ * Try body measurements.
65
+ * @returns {{height: number|null, width: number|null}}
66
+ */
67
+ const getFromBody = () => {
68
+ if (typeof document !== 'undefined' && document.body) {
69
+ return { height: toInt(document.body.clientHeight), width: toInt(document.body.clientWidth) };
70
+ }
71
+ return { height: null, width: null };
72
+ };
73
+
74
+ /**
75
+ * Try screen measurements (physical screen/fallback).
76
+ * screen.availHeight/availWidth are often available; outer* might also exist.
77
+ * @returns {{height: number|null, width: number|null}}
78
+ */
79
+ const getFromScreen = () => {
80
+ if (typeof window !== 'undefined' && window.screen) {
81
+ const { availHeight, availWidth, height, width } = window.screen;
82
+ return {
83
+ height: toInt(availHeight) || toInt(height) || null,
84
+ width: toInt(availWidth) || toInt(width) || null,
85
+ };
86
+ }
87
+ return { height: null, width: null };
88
+ };
89
+
90
+ /**
91
+ * Try outer dimensions (less reliable, but sometimes available).
92
+ * @returns {{height: number|null, width: number|null}}
93
+ */
94
+ const getFromOuter = () => {
95
+ if (typeof window !== 'undefined') {
96
+ return { height: toInt(window.outerHeight), width: toInt(window.outerWidth) };
97
+ }
98
+ return { height: null, width: null };
99
+ };
100
+
101
+ /**
102
+ * Merge candidates in priority order and return first valid value.
103
+ * @param {...(number|null)[]} candidates
104
+ * @returns {number|null}
105
+ */
106
+ const pickFirst = (...candidates) => {
107
+ for (const c of candidates) {
108
+ if (Number.isFinite(c) && c > 0) return Math.round(c);
109
+ }
110
+ return null;
111
+ };
112
+
113
+ /**
114
+ * Get the best-available viewport height in pixels.
115
+ * Priority (from most reliable for "visible" to least):
116
+ * 1. window.visualViewport.height
117
+ * 2. document.documentElement.clientHeight
118
+ * 3. window.innerHeight
119
+ * 4. document.body.clientHeight
120
+ * 5. window.screen.availHeight / window.screen.height
121
+ * 6. window.outerHeight
122
+ *
123
+ * @param {Object} [options]
124
+ * @param {boolean} [options.preferVisualViewport=true] - when true, prefer visualViewport if present
125
+ * @returns {number|null} height in px (rounded integer) or null if none found
126
+ */
127
+ export const windowGetH = (options = {}) => {
128
+ const { preferVisualViewport = true } = options;
129
+
130
+ const vv = getFromVisualViewport();
131
+ const de = getFromDocumentElement();
132
+ const wi = getFromWindowInner();
133
+ const bd = getFromBody();
134
+ const sc = getFromScreen();
135
+ const ot = getFromOuter();
136
+
137
+ if (preferVisualViewport) {
138
+ return pickFirst(vv.height, de.height, wi.height, bd.height, sc.height, ot.height) || null;
139
+ }
140
+
141
+ // if not preferring visualViewport, still include it but later
142
+ return pickFirst(de.height, wi.height, bd.height, vv.height, sc.height, ot.height) || null;
143
+ };
144
+
145
+ /**
146
+ * Get the best-available viewport width in pixels.
147
+ * Priority (from most reliable for "visible" to least):
148
+ * 1. window.visualViewport.width
149
+ * 2. document.documentElement.clientWidth
150
+ * 3. window.innerWidth
151
+ * 4. document.body.clientWidth
152
+ * 5. window.screen.availWidth / window.screen.width
153
+ * 6. window.outerWidth
154
+ *
155
+ * @param {Object} [options]
156
+ * @param {boolean} [options.preferVisualViewport=true] - when true, prefer visualViewport if present
157
+ * @returns {number|null} width in px (rounded integer) or null if none found
158
+ */
159
+ export const windowGetW = (options = {}) => {
160
+ const { preferVisualViewport = true } = options;
161
+
162
+ const vv = getFromVisualViewport();
163
+ const de = getFromDocumentElement();
164
+ const wi = getFromWindowInner();
165
+ const bd = getFromBody();
166
+ const sc = getFromScreen();
167
+ const ot = getFromOuter();
168
+
169
+ if (preferVisualViewport) {
170
+ return pickFirst(vv.width, de.width, wi.width, bd.width, sc.width, ot.width) || null;
171
+ }
172
+
173
+ return pickFirst(de.width, wi.width, bd.width, vv.width, sc.width, ot.width) || null;
174
+ };
175
+
176
+ // Convenience default export (optional)
177
+ export default {
178
+ windowGetH,
179
+ windowGetW,
180
+ };
181
+
182
+ /* --------------------------------------------------------------------------
183
+ * Example usage:
184
+ *
185
+ * import { windowGetH, windowGetW } from './windowGetDimensions.js';
186
+ *
187
+ * // Get values now
188
+ * const currentH = windowGetH();
189
+ * const currentW = windowGetW();
190
+ *
191
+ * // React to changes (recommended on mobile)
192
+ * if (window.visualViewport) {
193
+ * window.visualViewport.addEventListener('resize', () => {
194
+ * console.log('visualViewport resize ->', windowGetH(), windowGetW());
195
+ * });
196
+ * } else {
197
+ * window.addEventListener('resize', () => {
198
+ * console.log('window resize ->', windowGetH(), windowGetW());
199
+ * });
200
+ * }
201
+ *
202
+ * --------------------------------------------------------------------------*/
@@ -51,6 +51,7 @@ const MenuDefault = {
51
51
  <div class="fl menu-btn-container">
52
52
  ${await BtnIcon.Render({
53
53
  class: 'in wfa main-btn-menu main-btn-home main-btn-menu-active',
54
+ useMenuBtn: true,
54
55
  label: renderMenuLabel({
55
56
  icon: html`<i class="fas fa-home"></i>`,
56
57
  text: html`<span class="menu-label-text">${Translate.Render('home')}</span>`,
@@ -63,6 +64,7 @@ const MenuDefault = {
63
64
  })}
64
65
  ${await BtnIcon.Render({
65
66
  class: 'in wfa main-btn-menu main-btn-log-in',
67
+ useMenuBtn: true,
66
68
  label: renderMenuLabel({
67
69
  icon: html`<i class="fas fa-sign-in-alt"></i>`,
68
70
  text: html`<span class="menu-label-text">${Translate.Render('log-in')}</span>`,
@@ -74,6 +76,7 @@ const MenuDefault = {
74
76
  })}
75
77
  ${await BtnIcon.Render({
76
78
  class: 'in wfa main-btn-menu main-btn-sign-up',
79
+ useMenuBtn: true,
77
80
  label: renderMenuLabel({
78
81
  icon: html`<i class="fas fa-user-plus"></i>`,
79
82
  text: html`<span class="menu-label-text">${Translate.Render('sign-up')}</span>`,
@@ -85,6 +88,7 @@ const MenuDefault = {
85
88
  })}
86
89
  ${await BtnIcon.Render({
87
90
  class: 'in wfa main-btn-menu main-btn-log-out',
91
+ useMenuBtn: true,
88
92
  label: renderMenuLabel({
89
93
  icon: html`<i class="fas fa-sign-out-alt"></i>`,
90
94
  text: html`<span class="menu-label-text">${Translate.Render('log-out')}</span>`,
@@ -97,6 +101,7 @@ const MenuDefault = {
97
101
  })}
98
102
  ${await BtnIcon.Render({
99
103
  class: 'in wfa main-btn-menu main-btn-account',
104
+ useMenuBtn: true,
100
105
  label: renderMenuLabel({
101
106
  icon: html`<i class="fas fa-user-circle"></i>`,
102
107
  text: html`<span class="menu-label-text">${Translate.Render('account')}</span>`,
@@ -109,6 +114,7 @@ const MenuDefault = {
109
114
  })}
110
115
  ${await BtnIcon.Render({
111
116
  class: 'in wfa main-btn-menu main-btn-settings',
117
+ useMenuBtn: true,
112
118
  label: renderMenuLabel({
113
119
  icon: html`<i class="fas fa-sliders-h"></i>`,
114
120
  text: html`<span class="menu-label-text">${Translate.Render('settings')}</span>`,
@@ -120,6 +126,7 @@ const MenuDefault = {
120
126
  })}
121
127
  ${await BtnIcon.Render({
122
128
  class: 'in wfa main-btn-menu main-btn-recover hide',
129
+ useMenuBtn: true,
123
130
  label: renderMenuLabel({
124
131
  icon: html`<i class="fa-solid fa-arrow-rotate-left"></i>`,
125
132
  text: html`<span class="menu-label-text">${Translate.Render('recover')}</span>`,
@@ -131,6 +138,7 @@ const MenuDefault = {
131
138
  })}
132
139
  ${await BtnIcon.Render({
133
140
  class: 'in wfa main-btn-menu main-btn-default-management',
141
+ useMenuBtn: true,
134
142
  label: renderMenuLabel({
135
143
  icon: html`<i class="fa-solid fa-rectangle-list"></i>`,
136
144
  text: html`<span class="menu-label-text">${Translate.Render('default-management')}</span>`,
@@ -142,6 +150,7 @@ const MenuDefault = {
142
150
  })}
143
151
  ${await BtnIcon.Render({
144
152
  class: 'in wfa main-btn-menu main-btn-404 hide',
153
+ useMenuBtn: true,
145
154
  label: renderMenuLabel({
146
155
  icon: html`<i class="fa-solid fa-triangle-exclamation"></i>`,
147
156
  text: html`<span class="menu-label-text">${Translate.Render('404')}</span>`,
@@ -153,6 +162,7 @@ const MenuDefault = {
153
162
  })}
154
163
  ${await BtnIcon.Render({
155
164
  class: 'in wfa main-btn-menu main-btn-500 hide',
165
+ useMenuBtn: true,
156
166
  label: renderMenuLabel({
157
167
  icon: html`<i class="fa-solid fa-circle-exclamation"></i>`,
158
168
  text: html`<span class="menu-label-text">${Translate.Render('500')}</span>`,
@@ -164,6 +174,7 @@ const MenuDefault = {
164
174
  })}
165
175
  ${await BtnIcon.Render({
166
176
  class: 'in wfa main-btn-menu main-btn-blog',
177
+ useMenuBtn: true,
167
178
  label: renderMenuLabel({
168
179
  icon: html`<i class="fa-solid fa-file-invoice"></i>`,
169
180
  text: html`<span class="menu-label-text">${Translate.Render('blog')}</span>`,
@@ -5,7 +5,7 @@ SrrComponent = ({ title, ssrPath, buildId, ssrHeadComponents, ssrBodyComponents,
5
5
  <title>${title}</title>
6
6
  <link rel="icon" type="image/x-icon" href="${ssrPath}favicon.ico" />
7
7
  <meta charset="UTF-8" />
8
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
9
9
  <script>
10
10
  window.renderPayload = ${renderApi.JSONweb(renderPayload)};
11
11
  </script>
package/src/index.js CHANGED
@@ -35,7 +35,7 @@ class Underpost {
35
35
  * @type {String}
36
36
  * @memberof Underpost
37
37
  */
38
- static version = 'v2.8.881';
38
+ static version = 'v2.8.883';
39
39
  /**
40
40
  * Repository cli API
41
41
  * @static