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.
Files changed (66) hide show
  1. package/.env.production +3 -0
  2. package/.github/workflows/ghpkg.ci.yml +1 -1
  3. package/.github/workflows/npmpkg.ci.yml +1 -1
  4. package/.github/workflows/publish.ci.yml +5 -5
  5. package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -1
  6. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  7. package/CHANGELOG.md +145 -1
  8. package/Dockerfile +1 -1
  9. package/README.md +3 -3
  10. package/bin/build.js +18 -9
  11. package/bin/deploy.js +93 -187
  12. package/cli.md +2 -2
  13. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  14. package/manifests/deployment/dd-test-development/deployment.yaml +54 -54
  15. package/manifests/deployment/dd-test-development/proxy.yaml +4 -4
  16. package/manifests/lxd/underpost-setup.sh +5 -5
  17. package/package.json +3 -3
  18. package/scripts/ssl.sh +164 -0
  19. package/src/cli/baremetal.js +7 -7
  20. package/src/cli/cloud-init.js +1 -1
  21. package/src/cli/cluster.js +10 -3
  22. package/src/cli/cron.js +1 -1
  23. package/src/cli/db.js +1 -1
  24. package/src/cli/deploy.js +33 -1
  25. package/src/cli/fs.js +2 -2
  26. package/src/cli/image.js +7 -0
  27. package/src/cli/monitor.js +33 -1
  28. package/src/cli/run.js +315 -51
  29. package/src/cli/script.js +32 -0
  30. package/src/cli/secrets.js +34 -0
  31. package/src/cli/test.js +42 -1
  32. package/src/client/components/core/Css.js +0 -8
  33. package/src/client/components/core/windowGetDimensions.js +229 -162
  34. package/src/index.js +2 -2
  35. package/src/mailer/MailerProvider.js +1 -0
  36. package/src/runtime/express/Express.js +12 -4
  37. package/src/runtime/lampp/Dockerfile +1 -1
  38. package/src/server/backup.js +20 -0
  39. package/src/server/client-build-live.js +12 -10
  40. package/src/server/client-build.js +136 -91
  41. package/src/server/client-dev-server.js +16 -2
  42. package/src/server/client-icons.js +19 -0
  43. package/src/server/conf.js +470 -60
  44. package/src/server/dns.js +184 -42
  45. package/src/server/downloader.js +65 -24
  46. package/src/server/object-layer.js +260 -162
  47. package/src/server/peer.js +2 -8
  48. package/src/server/proxy.js +93 -76
  49. package/src/server/runtime.js +15 -16
  50. package/src/server/ssr.js +4 -4
  51. package/src/server/tls.js +251 -0
  52. package/src/server/valkey.js +11 -10
  53. package/src/ws/IoInterface.js +2 -1
  54. package/src/ws/IoServer.js +2 -1
  55. package/src/ws/core/core.ws.connection.js +1 -1
  56. package/src/ws/core/core.ws.emit.js +1 -1
  57. package/src/ws/core/core.ws.server.js +1 -1
  58. package/manifests/maas/lxd-preseed.yaml +0 -32
  59. package/src/server/ssl.js +0 -108
  60. /package/{manifests/maas → scripts}/device-scan.sh +0 -0
  61. /package/{manifests/maas → scripts}/gpu-diag.sh +0 -0
  62. /package/{manifests/maas → scripts}/maas-setup.sh +0 -0
  63. /package/{manifests/maas → scripts}/nat-iptables.sh +0 -0
  64. /package/{manifests/maas → scripts}/nvim.sh +0 -0
  65. /package/{manifests/maas → scripts}/snap-clean.sh +0 -0
  66. /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 Underpost
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
- * 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();
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
- * 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.
6
+ * @module src/client/components/core/windowGetDimensions.js
7
+ * @namespace PwaWindowDimensions
19
8
  */
20
9
 
21
- // Helper: coerce a candidate to a finite integer (or null if not usable)
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
- * Try visualViewport values (most accurate for "what's actually visible").
29
- * @returns {{height: number|null, width: number|null}}
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 getFromVisualViewport = () => {
32
- if (typeof window !== 'undefined' && window.visualViewport) {
33
- const { height, width } = window.visualViewport;
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 { height: null, width: null };
35
+ return null;
37
36
  };
38
37
 
38
+ // --- Core Dimension Class ---
39
+
39
40
  /**
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}}
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
- const getFromDocumentElement = () => {
45
- if (typeof document !== 'undefined' && document.documentElement) {
46
- const { clientHeight, clientWidth } = document.documentElement;
47
- return { height: toInt(clientHeight), width: toInt(clientWidth) };
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
- * 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) };
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
- * 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) };
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
- * 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
- };
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
- * 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) };
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
- * 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);
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
- return null;
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
- * 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
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] - when true, prefer visualViewport if present
125
- * @returns {number|null} height in px (rounded integer) or null if none found
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
- * 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
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] - when true, prefer visualViewport if present
157
- * @returns {number|null} width in px (rounded integer) or null if none found
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
- return pickFirst(de.width, wi.width, bd.width, vv.width, sc.width, ot.width) || null;
174
- };
263
+ // --- Default Export ---
175
264
 
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
- * --------------------------------------------------------------------------*/
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.885';
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
- await UnderpostStartUp.API.listenPortController(server, port, runningData);
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/setup_23.x | bash -
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
 
@@ -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');