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.
- package/.env.production +3 -0
- package/.github/workflows/ghpkg.ci.yml +1 -1
- package/.github/workflows/npmpkg.ci.yml +1 -1
- package/.github/workflows/publish.ci.yml +5 -5
- package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -1
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/CHANGELOG.md +145 -1
- package/Dockerfile +1 -1
- package/README.md +3 -3
- package/bin/build.js +18 -9
- package/bin/deploy.js +93 -187
- package/cli.md +2 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +54 -54
- package/manifests/deployment/dd-test-development/proxy.yaml +4 -4
- package/manifests/lxd/underpost-setup.sh +5 -5
- package/package.json +3 -3
- package/scripts/ssl.sh +164 -0
- package/src/cli/baremetal.js +7 -7
- package/src/cli/cloud-init.js +1 -1
- package/src/cli/cluster.js +10 -3
- package/src/cli/cron.js +1 -1
- package/src/cli/db.js +1 -1
- package/src/cli/deploy.js +33 -1
- package/src/cli/fs.js +2 -2
- package/src/cli/image.js +7 -0
- package/src/cli/monitor.js +33 -1
- package/src/cli/run.js +315 -51
- package/src/cli/script.js +32 -0
- package/src/cli/secrets.js +34 -0
- package/src/cli/test.js +42 -1
- package/src/client/components/core/Css.js +0 -8
- package/src/client/components/core/windowGetDimensions.js +229 -162
- package/src/index.js +2 -2
- package/src/mailer/MailerProvider.js +1 -0
- package/src/runtime/express/Express.js +12 -4
- package/src/runtime/lampp/Dockerfile +1 -1
- package/src/server/backup.js +20 -0
- package/src/server/client-build-live.js +12 -10
- package/src/server/client-build.js +136 -91
- package/src/server/client-dev-server.js +16 -2
- package/src/server/client-icons.js +19 -0
- package/src/server/conf.js +470 -60
- package/src/server/dns.js +184 -42
- package/src/server/downloader.js +65 -24
- package/src/server/object-layer.js +260 -162
- package/src/server/peer.js +2 -8
- package/src/server/proxy.js +93 -76
- package/src/server/runtime.js +15 -16
- package/src/server/ssr.js +4 -4
- package/src/server/tls.js +251 -0
- package/src/server/valkey.js +11 -10
- package/src/ws/IoInterface.js +2 -1
- package/src/ws/IoServer.js +2 -1
- package/src/ws/core/core.ws.connection.js +1 -1
- package/src/ws/core/core.ws.emit.js +1 -1
- package/src/ws/core/core.ws.server.js +1 -1
- package/manifests/maas/lxd-preseed.yaml +0 -32
- package/src/server/ssl.js +0 -108
- /package/{manifests/maas → scripts}/device-scan.sh +0 -0
- /package/{manifests/maas → scripts}/gpu-diag.sh +0 -0
- /package/{manifests/maas → scripts}/maas-setup.sh +0 -0
- /package/{manifests/maas → scripts}/nat-iptables.sh +0 -0
- /package/{manifests/maas → scripts}/nvim.sh +0 -0
- /package/{manifests/maas → scripts}/snap-clean.sh +0 -0
- /package/{manifests/maas → scripts}/ssh-cluster-info.sh +0 -0
package/src/cli/test.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test module for running tests on the application.
|
|
3
|
+
* @module src/cli/test.js
|
|
4
|
+
* @namespace UnderpostTest
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
import { timer } from '../client/components/core/CommonJs.js';
|
|
2
8
|
import { MariaDB } from '../db/mariadb/MariaDB.js';
|
|
3
9
|
import { getNpmRootPath } from '../server/conf.js';
|
|
@@ -7,6 +13,11 @@ import UnderpostDeploy from './deploy.js';
|
|
|
7
13
|
|
|
8
14
|
const logger = loggerFactory(import.meta);
|
|
9
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @class UnderpostTest
|
|
18
|
+
* @description Manages the test of the application.
|
|
19
|
+
* @memberof UnderpostTest
|
|
20
|
+
*/
|
|
10
21
|
class UnderpostTest {
|
|
11
22
|
static API = {
|
|
12
23
|
/**
|
|
@@ -20,15 +31,35 @@ class UnderpostTest {
|
|
|
20
31
|
* @static
|
|
21
32
|
* @method setUpInfo
|
|
22
33
|
* @returns {Promise<void>}
|
|
23
|
-
* @memberof
|
|
34
|
+
* @memberof UnderpostTest
|
|
24
35
|
*/
|
|
25
36
|
async setUpInfo() {
|
|
26
37
|
return await setUpInfo(logger);
|
|
27
38
|
},
|
|
39
|
+
/**
|
|
40
|
+
* @method run
|
|
41
|
+
* @description Runs the test of the application.
|
|
42
|
+
* @memberof UnderpostTest
|
|
43
|
+
*/
|
|
28
44
|
run() {
|
|
29
45
|
actionInitLog();
|
|
30
46
|
shellExec(`cd ${getNpmRootPath()}/underpost && npm run test`);
|
|
31
47
|
},
|
|
48
|
+
/**
|
|
49
|
+
* @method callback
|
|
50
|
+
* @description Manages the test of the application.
|
|
51
|
+
* @param {string} deployList - The list of deployments to test.
|
|
52
|
+
* @param {object} options - The options for the test.
|
|
53
|
+
* @param {boolean} options.itc - If true, tests the inside container.
|
|
54
|
+
* @param {boolean} options.sh - If true, tests the shell.
|
|
55
|
+
* @param {boolean} options.logs - If true, tests the logs.
|
|
56
|
+
* @param {string} options.podName - The name of the pod to test.
|
|
57
|
+
* @param {string} options.podStatus - The status of the pod to test.
|
|
58
|
+
* @param {string} options.kindType - The type of the kind to test.
|
|
59
|
+
* @param {number} options.deltaMs - The delta time in milliseconds.
|
|
60
|
+
* @param {number} options.maxAttempts - The maximum number of attempts.
|
|
61
|
+
* @memberof UnderpostTest
|
|
62
|
+
*/
|
|
32
63
|
async callback(deployList = '', options = { itc: false, sh: false, logs: false }) {
|
|
33
64
|
if (
|
|
34
65
|
options.podName &&
|
|
@@ -86,6 +117,16 @@ class UnderpostTest {
|
|
|
86
117
|
}
|
|
87
118
|
} else return UnderpostTest.API.run();
|
|
88
119
|
},
|
|
120
|
+
/**
|
|
121
|
+
* @method statusMonitor
|
|
122
|
+
* @description Monitors the status of a pod.
|
|
123
|
+
* @param {string} podName - The name of the pod to monitor.
|
|
124
|
+
* @param {string} status - The status of the pod to monitor.
|
|
125
|
+
* @param {string} kindType - The type of the kind to monitor.
|
|
126
|
+
* @param {number} deltaMs - The delta time in milliseconds.
|
|
127
|
+
* @param {number} maxAttempts - The maximum number of attempts.
|
|
128
|
+
* @memberof UnderpostTest
|
|
129
|
+
*/
|
|
89
130
|
statusMonitor(podName, status = 'Running', kindType = '', deltaMs = 1000, maxAttempts = 60 * 5) {
|
|
90
131
|
if (!(kindType && typeof kindType === 'string')) kindType = 'pods';
|
|
91
132
|
return new Promise(async (resolve) => {
|
|
@@ -690,14 +690,6 @@ const scrollBarLightRender = () => {
|
|
|
690
690
|
.join('');
|
|
691
691
|
};
|
|
692
692
|
|
|
693
|
-
/**
|
|
694
|
-
* Adjust hex color brightness toward white/black ("mix") or by modifying HSL lightness ("hsl").
|
|
695
|
-
*
|
|
696
|
-
* @param {string} hex - Color as '#rrggbb', 'rrggbb', '#rgb', or 'rgb'.
|
|
697
|
-
* @param {number} factor - -1..1 or -100..100 (percent). Positive = lighten, negative = darken.
|
|
698
|
-
* @param {{mode?: 'mix'|'hsl'}} [options]
|
|
699
|
-
* @returns {string} - Adjusted color as '#rrggbb' (lowercase).
|
|
700
|
-
*/
|
|
701
693
|
function adjustHex(hex, factor = 0.1, options = {}) {
|
|
702
694
|
if (typeof hex !== 'string') throw new TypeError('hex must be a string');
|
|
703
695
|
if (typeof factor !== 'number') throw new TypeError('factor must be a number');
|
|
@@ -1,202 +1,269 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* from modern to old browsers.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* import { windowGetH, windowGetW } from './windowGetDimensions.js';
|
|
9
|
-
* const h = windowGetH();
|
|
10
|
-
* const w = windowGetW();
|
|
1
|
+
/**
|
|
2
|
+
* This module exports utility functions (`windowGetH`, `windowGetW`) for reliably
|
|
3
|
+
* determining the browser viewport dimensions, refactored into a class structure
|
|
4
|
+
* for encapsulation and better organization.
|
|
11
5
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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.
|
|
6
|
+
* @module src/client/components/core/windowGetDimensions.js
|
|
7
|
+
* @namespace PwaWindowDimensions
|
|
19
8
|
*/
|
|
20
9
|
|
|
21
|
-
//
|
|
10
|
+
// --- Internal Helper Functions ---
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Helper: coerce a candidate value to a finite integer (or null if not usable).
|
|
14
|
+
* @private
|
|
15
|
+
* @param {*} v - The value to coerce (e.g., height/width from a window object).
|
|
16
|
+
* @returns {number|null} The rounded positive integer, or null if invalid.
|
|
17
|
+
* @memberof PwaWindowDimensions
|
|
18
|
+
*/
|
|
22
19
|
const toInt = (v) => {
|
|
23
20
|
const n = Number(v);
|
|
24
21
|
return Number.isFinite(n) && n > 0 ? Math.round(n) : null;
|
|
25
22
|
};
|
|
26
23
|
|
|
27
24
|
/**
|
|
28
|
-
*
|
|
29
|
-
* @
|
|
25
|
+
* Helper: Merge candidates in priority order and return first valid value.
|
|
26
|
+
* @private
|
|
27
|
+
* @param {...(number|null)[]} candidates - A list of number or null values.
|
|
28
|
+
* @returns {number|null} The first finite, positive integer found, or null.
|
|
29
|
+
* @memberof PwaWindowDimensions
|
|
30
30
|
*/
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return { height: toInt(height), width: toInt(width) };
|
|
31
|
+
const pickFirst = (...candidates) => {
|
|
32
|
+
for (const c of candidates) {
|
|
33
|
+
if (Number.isFinite(c) && c > 0) return Math.round(c);
|
|
35
34
|
}
|
|
36
|
-
return
|
|
35
|
+
return null;
|
|
37
36
|
};
|
|
38
37
|
|
|
38
|
+
// --- Core Dimension Class ---
|
|
39
|
+
|
|
39
40
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* @
|
|
41
|
+
* @namespace PwaWindowDimensions
|
|
42
|
+
* @class
|
|
43
|
+
* @classdesc Utility class containing static methods for reliably determining the
|
|
44
|
+
* browser viewport dimensions, prioritizing visual viewport, then layout viewport,
|
|
45
|
+
* and finally screen dimensions as fallbacks.
|
|
46
|
+
*
|
|
47
|
+
* Usage:
|
|
48
|
+
* import PwaWindowDimensions from './windowGetDimensions.js';
|
|
49
|
+
* const h = PwaWindowDimensions.getH();
|
|
50
|
+
* @memberof PwaWindowDimensions
|
|
43
51
|
*/
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
52
|
+
export class PwaWindowDimensions {
|
|
53
|
+
// --- Private Static Getters (Encapsulating browser APIs) ---
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @private
|
|
57
|
+
* @static
|
|
58
|
+
* Try visualViewport values (most accurate for "what's actually visible").
|
|
59
|
+
* @returns {{height: number|null, width: number|null}}
|
|
60
|
+
* @memberof PwaWindowDimensions
|
|
61
|
+
*/
|
|
62
|
+
static #getFromVisualViewport() {
|
|
63
|
+
if (typeof window !== 'undefined' && window.visualViewport) {
|
|
64
|
+
const { height, width } = window.visualViewport;
|
|
65
|
+
return { height: toInt(height), width: toInt(width) };
|
|
66
|
+
}
|
|
67
|
+
return { height: null, width: null };
|
|
48
68
|
}
|
|
49
|
-
return { height: null, width: null };
|
|
50
|
-
};
|
|
51
69
|
|
|
52
|
-
/**
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
70
|
+
/**
|
|
71
|
+
* @private
|
|
72
|
+
* @static
|
|
73
|
+
* Try layout viewport (doctype-root) measurements.
|
|
74
|
+
* document.documentElement.clientHeight/clientWidth are stable and widely used.
|
|
75
|
+
* @returns {{height: number|null, width: number|null}}
|
|
76
|
+
* @memberof PwaWindowDimensions
|
|
77
|
+
*/
|
|
78
|
+
static #getFromDocumentElement() {
|
|
79
|
+
if (typeof document !== 'undefined' && document.documentElement) {
|
|
80
|
+
const { clientHeight, clientWidth } = document.documentElement;
|
|
81
|
+
return { height: toInt(clientHeight), width: toInt(clientWidth) };
|
|
82
|
+
}
|
|
83
|
+
return { height: null, width: null };
|
|
59
84
|
}
|
|
60
|
-
return { height: null, width: null };
|
|
61
|
-
};
|
|
62
85
|
|
|
63
|
-
/**
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
86
|
+
/**
|
|
87
|
+
* @private
|
|
88
|
+
* @static
|
|
89
|
+
* Try window.* measurements (innerHeight/innerWidth are widely supported).
|
|
90
|
+
* @returns {{height: number|null, width: number|null}}
|
|
91
|
+
* @memberof PwaWindowDimensions
|
|
92
|
+
*/
|
|
93
|
+
static #getFromWindowInner() {
|
|
94
|
+
if (typeof window !== 'undefined') {
|
|
95
|
+
return { height: toInt(window.innerHeight), width: toInt(window.innerWidth) };
|
|
96
|
+
}
|
|
97
|
+
return { height: null, width: null };
|
|
70
98
|
}
|
|
71
|
-
return { height: null, width: null };
|
|
72
|
-
};
|
|
73
99
|
|
|
74
|
-
/**
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
height: toInt(
|
|
84
|
-
|
|
85
|
-
};
|
|
100
|
+
/**
|
|
101
|
+
* @private
|
|
102
|
+
* @static
|
|
103
|
+
* Try body measurements (less reliable, used as a fallback).
|
|
104
|
+
* @returns {{height: number|null, width: number|null}}
|
|
105
|
+
* @memberof PwaWindowDimensions
|
|
106
|
+
*/
|
|
107
|
+
static #getFromBody() {
|
|
108
|
+
if (typeof document !== 'undefined' && document.body) {
|
|
109
|
+
return { height: toInt(document.body.clientHeight), width: toInt(document.body.clientWidth) };
|
|
110
|
+
}
|
|
111
|
+
return { height: null, width: null };
|
|
86
112
|
}
|
|
87
|
-
return { height: null, width: null };
|
|
88
|
-
};
|
|
89
113
|
|
|
90
|
-
/**
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
114
|
+
/**
|
|
115
|
+
* @private
|
|
116
|
+
* @static
|
|
117
|
+
* Try screen measurements (physical screen/last-resort fallback).
|
|
118
|
+
* @returns {{height: number|null, width: number|null}}
|
|
119
|
+
* @memberof PwaWindowDimensions
|
|
120
|
+
*/
|
|
121
|
+
static #getFromScreen() {
|
|
122
|
+
if (typeof window !== 'undefined' && window.screen) {
|
|
123
|
+
const { availHeight, availWidth, height, width } = window.screen;
|
|
124
|
+
return {
|
|
125
|
+
height: toInt(availHeight) || toInt(height) || null,
|
|
126
|
+
width: toInt(availWidth) || toInt(width) || null,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return { height: null, width: null };
|
|
97
130
|
}
|
|
98
|
-
return { height: null, width: null };
|
|
99
|
-
};
|
|
100
131
|
|
|
101
|
-
/**
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
132
|
+
/**
|
|
133
|
+
* @private
|
|
134
|
+
* @static
|
|
135
|
+
* Try outer dimensions (less reliable, sometimes available fallback).
|
|
136
|
+
* @returns {{height: number|null, width: number|null}}
|
|
137
|
+
* @memberof PwaWindowDimensions
|
|
138
|
+
*/
|
|
139
|
+
static #getFromOuter() {
|
|
140
|
+
if (typeof window !== 'undefined') {
|
|
141
|
+
return { height: toInt(window.outerHeight), width: toInt(window.outerWidth) };
|
|
142
|
+
}
|
|
143
|
+
return { height: null, width: null };
|
|
109
144
|
}
|
|
110
|
-
|
|
111
|
-
|
|
145
|
+
|
|
146
|
+
// --- Public Static Methods ---
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Get the best-available viewport height in pixels.
|
|
150
|
+
*
|
|
151
|
+
* Priority (from most reliable for "visible" to least):
|
|
152
|
+
* 1. window.visualViewport.height (if `preferVisualViewport` is true)
|
|
153
|
+
* 2. document.documentElement.clientHeight (Layout viewport)
|
|
154
|
+
* 3. window.innerHeight (Window size)
|
|
155
|
+
* 4. document.body.clientHeight (Body size)
|
|
156
|
+
* 5. window.visualViewport.height (if `preferVisualViewport` is false)
|
|
157
|
+
* 6. window.screen.availHeight / window.screen.height (Physical screen)
|
|
158
|
+
* 7. window.outerHeight (Last resort)
|
|
159
|
+
*
|
|
160
|
+
* @memberof PwaWindowDimensions
|
|
161
|
+
* @static
|
|
162
|
+
* @param {Object} [options]
|
|
163
|
+
* @param {boolean} [options.preferVisualViewport=true] - When true, visualViewport is checked first (best for visible screen size, e.g., above mobile keyboard).
|
|
164
|
+
* @returns {number|null} Height in px (rounded integer) or null if none found.
|
|
165
|
+
* @memberof PwaWindowDimensions
|
|
166
|
+
*/
|
|
167
|
+
static getH(options = {}) {
|
|
168
|
+
const { preferVisualViewport = true } = options;
|
|
169
|
+
|
|
170
|
+
const vv = PwaWindowDimensions.#getFromVisualViewport();
|
|
171
|
+
const de = PwaWindowDimensions.#getFromDocumentElement();
|
|
172
|
+
const wi = PwaWindowDimensions.#getFromWindowInner();
|
|
173
|
+
const bd = PwaWindowDimensions.#getFromBody();
|
|
174
|
+
const sc = PwaWindowDimensions.#getFromScreen();
|
|
175
|
+
const ot = PwaWindowDimensions.#getFromOuter();
|
|
176
|
+
|
|
177
|
+
// Determine the prioritized list of height candidates
|
|
178
|
+
let candidates = [de.height, wi.height, bd.height];
|
|
179
|
+
if (preferVisualViewport) {
|
|
180
|
+
candidates = [vv.height, ...candidates]; // vv first
|
|
181
|
+
} else {
|
|
182
|
+
candidates.push(vv.height); // vv later
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Add final fallbacks
|
|
186
|
+
candidates.push(sc.height, ot.height);
|
|
187
|
+
|
|
188
|
+
return pickFirst(...candidates) || null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Get the best-available viewport width in pixels.
|
|
193
|
+
*
|
|
194
|
+
* Priority (from most reliable for "visible" to least):
|
|
195
|
+
* 1. window.visualViewport.width (if `preferVisualViewport` is true)
|
|
196
|
+
* 2. document.documentElement.clientWidth (Layout viewport)
|
|
197
|
+
* 3. window.innerWidth (Window size)
|
|
198
|
+
* 4. document.body.clientWidth (Body size)
|
|
199
|
+
* 5. window.visualViewport.width (if `preferVisualViewport` is false)
|
|
200
|
+
* 6. window.screen.availWidth / window.screen.width (Physical screen)
|
|
201
|
+
* 7. window.outerWidth (Last resort)
|
|
202
|
+
*
|
|
203
|
+
* @memberof PwaWindowDimensions
|
|
204
|
+
* @static
|
|
205
|
+
* @param {Object} [options]
|
|
206
|
+
* @param {boolean} [options.preferVisualViewport=true] - When true, visualViewport is checked first.
|
|
207
|
+
* @returns {number|null} Width in px (rounded integer) or null if none found.
|
|
208
|
+
* @memberof PwaWindowDimensions
|
|
209
|
+
*/
|
|
210
|
+
static getW(options = {}) {
|
|
211
|
+
const { preferVisualViewport = true } = options;
|
|
212
|
+
|
|
213
|
+
const vv = PwaWindowDimensions.#getFromVisualViewport();
|
|
214
|
+
const de = PwaWindowDimensions.#getFromDocumentElement();
|
|
215
|
+
const wi = PwaWindowDimensions.#getFromWindowInner();
|
|
216
|
+
const bd = PwaWindowDimensions.#getFromBody();
|
|
217
|
+
const sc = PwaWindowDimensions.#getFromScreen();
|
|
218
|
+
const ot = PwaWindowDimensions.#getFromOuter();
|
|
219
|
+
|
|
220
|
+
// Determine the prioritized list of width candidates
|
|
221
|
+
let candidates = [de.width, wi.width, bd.width];
|
|
222
|
+
if (preferVisualViewport) {
|
|
223
|
+
candidates = [vv.width, ...candidates]; // vv first
|
|
224
|
+
} else {
|
|
225
|
+
candidates.push(vv.width); // vv later
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Add final fallbacks
|
|
229
|
+
candidates.push(sc.width, ot.width);
|
|
230
|
+
|
|
231
|
+
return pickFirst(...candidates) || null;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// --- Backward Compatibility Exports (Legacy API) ---
|
|
112
236
|
|
|
113
237
|
/**
|
|
114
238
|
* Get the best-available viewport height in pixels.
|
|
115
|
-
*
|
|
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
|
|
239
|
+
* This function exists for backward compatibility; it wraps PwaWindowDimensions.getH().
|
|
122
240
|
*
|
|
241
|
+
* @function windowGetH
|
|
242
|
+
* @memberof PwaWindowDimensions
|
|
123
243
|
* @param {Object} [options]
|
|
124
|
-
* @param {boolean} [options.preferVisualViewport=true] -
|
|
125
|
-
* @returns {number|null}
|
|
244
|
+
* @param {boolean} [options.preferVisualViewport=true] - When true, visualViewport is checked first.
|
|
245
|
+
* @returns {number|null} Height in px (rounded integer) or null if none found.
|
|
246
|
+
* @memberof PwaWindowDimensions
|
|
126
247
|
*/
|
|
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
|
-
};
|
|
248
|
+
export const windowGetH = (options = {}) => PwaWindowDimensions.getH(options);
|
|
144
249
|
|
|
145
250
|
/**
|
|
146
251
|
* Get the best-available viewport width in pixels.
|
|
147
|
-
*
|
|
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
|
|
252
|
+
* This function exists for backward compatibility; it wraps PwaWindowDimensions.getW().
|
|
154
253
|
*
|
|
254
|
+
* @function windowGetW
|
|
255
|
+
* @memberof PwaWindowDimensions
|
|
155
256
|
* @param {Object} [options]
|
|
156
|
-
* @param {boolean} [options.preferVisualViewport=true] -
|
|
157
|
-
* @returns {number|null}
|
|
257
|
+
* @param {boolean} [options.preferVisualViewport=true] - When true, prefer visualViewport if present
|
|
258
|
+
* @returns {number|null} Width in px (rounded integer) or null if none found.
|
|
259
|
+
* @memberof PwaWindowDimensions
|
|
158
260
|
*/
|
|
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
|
-
}
|
|
261
|
+
export const windowGetW = (options = {}) => PwaWindowDimensions.getW(options);
|
|
172
262
|
|
|
173
|
-
|
|
174
|
-
};
|
|
263
|
+
// --- Default Export ---
|
|
175
264
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
-
* --------------------------------------------------------------------------*/
|
|
265
|
+
/**
|
|
266
|
+
* @typedef {PwaWindowDimensions} PwaWindowDimensions
|
|
267
|
+
* @memberof PwaWindowDimensions
|
|
268
|
+
*/
|
|
269
|
+
export default PwaWindowDimensions;
|
package/src/index.js
CHANGED
|
@@ -25,7 +25,7 @@ import UnderpostStartUp from './server/start.js';
|
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Underpost main module methods
|
|
28
|
-
* @class
|
|
28
|
+
* @class Underpost
|
|
29
29
|
* @memberof Underpost
|
|
30
30
|
*/
|
|
31
31
|
class Underpost {
|
|
@@ -35,7 +35,7 @@ class Underpost {
|
|
|
35
35
|
* @type {String}
|
|
36
36
|
* @memberof Underpost
|
|
37
37
|
*/
|
|
38
|
-
static version = 'v2.8.
|
|
38
|
+
static version = 'v2.8.886';
|
|
39
39
|
/**
|
|
40
40
|
* Repository cli API
|
|
41
41
|
* @static
|
|
@@ -27,6 +27,7 @@ const logger = loggerFactory(import.meta);
|
|
|
27
27
|
* @property {string} [host=''] - Application host for context.
|
|
28
28
|
* @property {string} [path=''] - Application path for context.
|
|
29
29
|
* @property {object.<string, string>} templates - Map of template keys to SSR component file names.
|
|
30
|
+
* @memberof MailerProviderNamespace
|
|
30
31
|
*/
|
|
31
32
|
|
|
32
33
|
/**
|
|
@@ -21,6 +21,8 @@ import { createPeerServer } from '../../server/peer.js';
|
|
|
21
21
|
import { createValkeyConnection } from '../../server/valkey.js';
|
|
22
22
|
import { applySecurity, authMiddlewareFactory } from '../../server/auth.js';
|
|
23
23
|
import { ssrMiddlewareFactory } from '../../server/ssr.js';
|
|
24
|
+
import { TLS } from '../../server/tls.js';
|
|
25
|
+
import { shellExec } from '../../server/process.js';
|
|
24
26
|
|
|
25
27
|
const logger = loggerFactory(import.meta);
|
|
26
28
|
|
|
@@ -43,6 +45,7 @@ class ExpressService {
|
|
|
43
45
|
* @param {string[]} [config.apis] - A list of API names to load and attach routers for.
|
|
44
46
|
* @param {string[]} config.origins - Allowed origins for CORS.
|
|
45
47
|
* @param {string} [config.directory] - The directory for static files (if overriding default).
|
|
48
|
+
* @param {boolean} [config.useLocalSsl] - Whether to use local SSL for the instance.
|
|
46
49
|
* @param {string} [config.ws] - The WebSocket server name to use.
|
|
47
50
|
* @param {object} [config.mailer] - Mailer configuration.
|
|
48
51
|
* @param {object} [config.db] - Database configuration.
|
|
@@ -65,6 +68,7 @@ class ExpressService {
|
|
|
65
68
|
apis,
|
|
66
69
|
origins,
|
|
67
70
|
directory,
|
|
71
|
+
useLocalSsl,
|
|
68
72
|
ws,
|
|
69
73
|
mailer,
|
|
70
74
|
db,
|
|
@@ -111,7 +115,6 @@ class ExpressService {
|
|
|
111
115
|
|
|
112
116
|
// Logging, Compression, and Body Parsers
|
|
113
117
|
app.use(loggerMiddleware(import.meta));
|
|
114
|
-
// Compression filter logic is correctly inlined here
|
|
115
118
|
app.use(compression({ filter: (req, res) => !req.headers['x-no-compression'] && compression.filter(req, res) }));
|
|
116
119
|
app.use(express.json({ limit: '100MB' }));
|
|
117
120
|
app.use(express.urlencoded({ extended: true, limit: '20MB' }));
|
|
@@ -165,6 +168,9 @@ class ExpressService {
|
|
|
165
168
|
}
|
|
166
169
|
|
|
167
170
|
// Security and CORS
|
|
171
|
+
if (process.env.NODE_ENV === 'development' && useLocalSsl)
|
|
172
|
+
origins = origins.map((origin) => origin.replace('http', 'https'));
|
|
173
|
+
|
|
168
174
|
applySecurity(app, {
|
|
169
175
|
origin: origins,
|
|
170
176
|
});
|
|
@@ -219,9 +225,7 @@ class ExpressService {
|
|
|
219
225
|
const peerPort = newInstance(port + portsUsed); // portsUsed is 1 here
|
|
220
226
|
const { options, meta, peerServer } = await createPeerServer({
|
|
221
227
|
port: peerPort,
|
|
222
|
-
devPort: port,
|
|
223
228
|
origins,
|
|
224
|
-
host,
|
|
225
229
|
path,
|
|
226
230
|
});
|
|
227
231
|
await UnderpostStartUp.API.listenPortController(peerServer, peerPort, {
|
|
@@ -239,7 +243,11 @@ class ExpressService {
|
|
|
239
243
|
for (const [_, ssrMiddleware] of Object.entries(ssr)) app.use(ssrMiddleware);
|
|
240
244
|
|
|
241
245
|
// Start listening on the main port
|
|
242
|
-
|
|
246
|
+
if (useLocalSsl && process.env.NODE_ENV === 'development') {
|
|
247
|
+
if (!TLS.validateSecureContext()) shellExec(`node bin/deploy tls`);
|
|
248
|
+
const { ServerSSL } = await TLS.createSslServer(app);
|
|
249
|
+
await UnderpostStartUp.API.listenPortController(ServerSSL, port, runningData);
|
|
250
|
+
} else await UnderpostStartUp.API.listenPortController(server, port, runningData);
|
|
243
251
|
|
|
244
252
|
return { portsUsed };
|
|
245
253
|
}
|
|
@@ -32,7 +32,7 @@ RUN mkdir -p /opt/lampp/htdocs && \
|
|
|
32
32
|
chmod -R a+rX /opt/lampp/htdocs
|
|
33
33
|
|
|
34
34
|
# Install Node.js
|
|
35
|
-
RUN curl -fsSL https://rpm.nodesource.com/
|
|
35
|
+
RUN curl -fsSL https://rpm.nodesource.com/setup_24.x | bash -
|
|
36
36
|
RUN dnf install nodejs -y
|
|
37
37
|
RUN dnf clean all
|
|
38
38
|
|
package/src/server/backup.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages backup operations for deployments.
|
|
3
|
+
* @module src/server/backup.js
|
|
4
|
+
* @namespace BackUp
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
import fs from 'fs-extra';
|
|
2
8
|
import { loggerFactory } from './logger.js';
|
|
3
9
|
import { shellExec } from './process.js';
|
|
@@ -8,7 +14,21 @@ dotenv.config();
|
|
|
8
14
|
|
|
9
15
|
const logger = loggerFactory(import.meta);
|
|
10
16
|
|
|
17
|
+
/**
|
|
18
|
+
* @class BackUp
|
|
19
|
+
* @description Manages backup operations for deployments.
|
|
20
|
+
* @memberof BackUp
|
|
21
|
+
*/
|
|
11
22
|
class BackUp {
|
|
23
|
+
/**
|
|
24
|
+
* @method callback
|
|
25
|
+
* @description Initiates a backup operation for the specified deployment list.
|
|
26
|
+
* @param {string} deployList - The list of deployments to backup.
|
|
27
|
+
* @param {Object} options - The options for the backup operation.
|
|
28
|
+
* @param {boolean} options.itc - Whether to backup inside container data.
|
|
29
|
+
* @param {boolean} options.git - Whether to backup data using Git.
|
|
30
|
+
* @memberof BackUp
|
|
31
|
+
*/
|
|
12
32
|
static callback = async function (deployList, options = { itc: false, git: false }) {
|
|
13
33
|
if ((!deployList || deployList === 'dd') && fs.existsSync(`./engine-private/deploy/dd.router`))
|
|
14
34
|
deployList = fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8');
|