@underpostnet/underpost 2.97.5 → 2.98.1

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 (34) hide show
  1. package/.vscode/settings.json +7 -8
  2. package/README.md +2 -2
  3. package/bin/build.js +21 -5
  4. package/bin/deploy.js +1 -0
  5. package/bin/file.js +2 -1
  6. package/bin/util.js +0 -17
  7. package/cli.md +2 -2
  8. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  9. package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
  10. package/package.json +2 -4
  11. package/scripts/rocky-pwa.sh +200 -0
  12. package/scripts/rocky-setup.sh +12 -39
  13. package/src/api/document/document.model.js +1 -1
  14. package/src/api/document/document.service.js +88 -98
  15. package/src/cli/cluster.js +5 -9
  16. package/src/cli/repository.js +9 -9
  17. package/src/cli/run.js +108 -106
  18. package/src/client/components/core/Auth.js +2 -0
  19. package/src/client/components/core/Content.js +52 -4
  20. package/src/client/components/core/Css.js +30 -0
  21. package/src/client/components/core/FileExplorer.js +699 -42
  22. package/src/client/components/core/Input.js +3 -1
  23. package/src/client/components/core/Panel.js +93 -23
  24. package/src/client/components/core/PanelForm.js +1 -0
  25. package/src/client/components/core/Responsive.js +15 -7
  26. package/src/client/components/core/SearchBox.js +0 -110
  27. package/src/client/components/core/Translate.js +58 -0
  28. package/src/client/services/default/default.management.js +327 -148
  29. package/src/client/sw/default.sw.js +107 -184
  30. package/src/index.js +58 -20
  31. package/src/client/components/core/ObjectLayerEngine.js +0 -1520
  32. package/src/client/components/core/ObjectLayerEngineModal.js +0 -1245
  33. package/src/client/components/core/ObjectLayerEngineViewer.js +0 -880
  34. package/src/server/object-layer.js +0 -335
@@ -6,199 +6,122 @@
6
6
  * @namespace PwaServiceWorker
7
7
  */
8
8
 
9
- /**
10
- * Class representing a Progressive Web App (PWA) Service Worker with caching strategies.
11
- * @class
12
- * @memberof PwaServiceWorker
13
- */
14
- class PwaServiceWorker {
15
- /**
16
- * Initializes the service worker configuration by reading from self.renderPayload.
17
- * If properties are not found, defaults are used.
18
- * @constructor
19
- * @property {Array<string>} PRE_CACHED_RESOURCES - List of resources to precache.
20
- * @property {string} CACHE_NAME - Name of the cache storage.
21
- * @property {string} PROXY_PATH - Base path for proxying requests.
22
- */
23
- constructor() {
24
- // Configuration properties equivalent to the original global constants
25
- this.PRE_CACHED_RESOURCES = self.renderPayload?.PRE_CACHED_RESOURCES ?? [];
26
- this.CACHE_NAME = self.renderPayload?.CACHE_NAME ?? 'app-cache';
27
- this.PROXY_PATH = self.renderPayload?.PROXY_PATH ?? '/';
28
-
29
- console.log(`Service Worker Initialized. Cache: ${this.CACHE_NAME}, Proxy: ${this.PROXY_PATH}`);
30
- }
31
-
32
- /**
33
- * Registers event listeners for the service worker lifecycle and requests.
34
- * @method
35
- * @memberof PwaServiceWorker
36
- */
37
- run() {
38
- // Bind methods to 'this' (the instance) before attaching to self
39
- self.addEventListener('install', this._onInstall.bind(this));
40
- self.addEventListener('activate', this._onActivate.bind(this));
41
- self.addEventListener('fetch', this._onFetch.bind(this));
42
- }
43
-
44
- /**
45
- * Handles the 'install' event. Skips waiting and precaches static assets.
46
- * @param {ExtendableEvent} event
47
- * @memberof PwaServiceWorker
48
- */
49
- _onInstall(event) {
50
- // Activate right away
51
- self.skipWaiting();
52
-
53
- event.waitUntil(
54
- (async () => {
55
- // Open the app's cache using the configured name.
56
- const cache = await caches.open(this.CACHE_NAME);
57
- // Cache all static resources.
58
- try {
59
- console.log(`Precaching ${this.PRE_CACHED_RESOURCES.length} resources...`);
60
- await cache.addAll(this.PRE_CACHED_RESOURCES);
61
- } catch (error) {
62
- console.error('Error during precaching resources:', error);
63
- }
64
- })(),
65
- );
66
- }
67
-
68
- /**
69
- * Handles the 'activate' event. Enables navigation preload and takes control
70
- * of uncontrolled clients immediately.
71
- * @param {ExtendableEvent} event
72
- * @memberof PwaServiceWorker
73
- */
74
- _onActivate(event) {
75
- event.waitUntil(
76
- (async () => {
77
- // Enable navigation preload if it's supported.
78
- if ('navigationPreload' in self.registration) {
79
- await self.registration.navigationPreload.enable();
80
- console.log('Navigation Preload enabled.');
81
- }
82
- })(),
83
- );
84
- // Tell the active service worker to take control of the page immediately.
85
- self.clients.claim();
86
- }
87
-
88
- /**
89
- * Handles the 'fetch' event, implementing the Cache-First strategy with
90
- * complex offline and maintenance fallbacks.
91
- * @param {FetchEvent} event
92
- * @memberof PwaServiceWorker
93
- */
94
- _onFetch(event) {
95
- // Only handle HTTP/HTTPS requests that are not cross-origin (optional, but robust)
96
- if (event.request.url.startsWith('http')) {
97
- event.respondWith(this._handleFetchRequest(event));
98
- }
99
- }
100
-
101
- /**
102
- * Core logic to handle fetching, caching, and fallbacks.
103
- * @param {FetchEvent} event
104
- * @returns {Promise<Response>}
105
- * @memberof PwaServiceWorker
106
- */
107
- async _handleFetchRequest(event) {
108
- // 1. Try Navigation Preload (if available) or network first
109
- try {
110
- const preloadResponse = await event.preloadResponse;
111
- if (preloadResponse) return preloadResponse;
112
-
113
- // Fall through to network request if no preload response
114
- const networkResponse = await fetch(event.request);
115
-
116
- // OPTIONAL: If the network request is successful, cache it for future use (stale-while-revalidate logic)
117
- // Omitted for strict equivalence, as original only had complex fallback, not runtime caching.
118
-
119
- return networkResponse;
120
- } catch (error) {
121
- console.error('Network request failed. Attempting cache/fallback logic.', event.request.url, error);
122
-
123
- // 2. Try to match the request in the cache
9
+ const PRE_CACHED_RESOURCES = self.renderPayload?.PRE_CACHED_RESOURCES ? self.renderPayload.PRE_CACHED_RESOURCES : [];
10
+ const CACHE_NAME = self.renderPayload?.CACHE_NAME ? self.renderPayload.CACHE_NAME : 'app-cache';
11
+ const PROXY_PATH = self.renderPayload?.PROXY_PATH ? self.renderPayload.PROXY_PATH : '/';
12
+ self.addEventListener('install', (event) => {
13
+ // Activate right away
14
+ self.skipWaiting();
15
+
16
+ event.waitUntil(
17
+ (async () => {
18
+ // Open the app's cache.
19
+ const cache = await caches.open(CACHE_NAME);
20
+ // Cache all static resources.
124
21
  try {
125
- const cachedResponse = await caches.match(event.request);
126
- if (cachedResponse) {
127
- console.log(`Cache hit for: ${event.request.url}`);
128
- return cachedResponse;
129
- }
130
-
131
- // 3. Try to match a precached resource path (e.g., if requesting /page, match /page/index.html)
132
- const path = this.PRE_CACHED_RESOURCES.find((p) => event.request.url.match(p.replaceAll('/index.html', '')));
133
-
134
- if (path) {
135
- const cache = await caches.open(this.CACHE_NAME);
136
- const preCachedResponse = await cache.match(path);
137
- if (preCachedResponse) {
138
- console.log(`Matched precached resource for: ${event.request.url} via path: ${path}`);
139
- return preCachedResponse;
22
+ await cache.addAll(PRE_CACHED_RESOURCES);
23
+ } catch (error) {
24
+ console.error(error);
25
+ }
26
+ // for (const cacheKey of PRE_CACHED_RESOURCES) {
27
+ // try {
28
+ // await cache.add(cacheKey);
29
+ // } catch (error) {
30
+ // console.error(error, cacheKey);
31
+ // }
32
+ // }
33
+ })(),
34
+ );
35
+ });
36
+
37
+ self.addEventListener('activate', (event) => {
38
+ event.waitUntil(
39
+ (async () => {
40
+ // Enable navigation preload if it's supported.
41
+ // See https://developers.google.com/web/updates/2017/02/navigation-preload
42
+ if ('navigationPreload' in self.registration) {
43
+ await self.registration.navigationPreload.enable();
44
+ }
45
+ })(),
46
+ );
47
+ // Tell the active service worker to take control of the page immediately.
48
+ self.clients.claim();
49
+ });
50
+
51
+ self.addEventListener('fetch', (event) => {
52
+ // Cache-First Strategy
53
+ event.respondWith(
54
+ (async () => {
55
+ // First, try to use the navigation preload response if it's supported.
56
+ try {
57
+ (async () => {
58
+ // Get the client.
59
+ if (event.request.url.match(location.origin)) {
60
+ const client = await clients.get(event.clientId);
61
+ if (client)
62
+ client.postMessage({
63
+ status: 'loader',
64
+ path: event.request.url.slice(location.origin.length),
65
+ });
140
66
  }
141
- }
142
-
143
- // If neither cache match nor precache path match worked, fall through to complex fallback
144
- throw new Error('Cache miss and no precache match.');
145
- } catch (cacheError) {
146
- console.error('Error in primary cache lookup. Falling back to offline/maintenance pages.', {
147
- url: event.request.url,
148
- cacheError,
149
- onLine: navigator.onLine,
150
- });
67
+ })();
68
+ const preloadResponse = await event.preloadResponse;
69
+ if (preloadResponse) return preloadResponse;
70
+ return await fetch(event.request);
71
+ } catch (error) {
72
+ console.error('Fetch failed; returning offline page instead.', event.request.url, error);
73
+ // Fallback to the offline page.
74
+ const path = PRE_CACHED_RESOURCES.find((path) => event.request.url.match(path.replaceAll('/index.html', '')));
151
75
 
152
- // 4. Complex Fallback Logic (Offline or Maintenance)
153
76
  try {
154
- const cache = await caches.open(this.CACHE_NAME);
155
-
156
- if (!navigator.onLine) {
157
- // A. OFFLINE FALLBACK
77
+ const cachedResponse = await caches.match(event.request);
78
+ if (cachedResponse) return cachedResponse;
79
+ const cache = await caches.open(CACHE_NAME);
80
+ const preCachedResponse = await cache.match(path);
81
+ if (!preCachedResponse) throw new Error(error.message);
82
+ return preCachedResponse;
83
+ } catch (error) {
84
+ console.error('Error opening cache for pre cached page', {
85
+ url: event.request.url,
86
+ error,
87
+ onLine: navigator.onLine,
88
+ });
89
+ try {
90
+ if (!navigator.onLine) {
91
+ if (event.request.method.toUpperCase() === 'GET') {
92
+ const cache = await caches.open(CACHE_NAME);
93
+ const preCachedResponse = await cache.match(
94
+ `${PROXY_PATH === '/' ? '' : PROXY_PATH}/offline/index.html`,
95
+ );
96
+ if (!preCachedResponse) throw new Error(error.message);
97
+ return preCachedResponse;
98
+ }
99
+ const response = new Response(JSON.stringify({ status: 'error', message: 'offline test response' }));
100
+ // response.status = 200;
101
+ response.headers.set('Content-Type', 'application/json');
102
+ return response;
103
+ }
158
104
  if (event.request.method.toUpperCase() === 'GET') {
159
- const offlinePath = `${this.PROXY_PATH === '/' ? '' : this.PROXY_PATH}/offline/index.html`;
160
- const preCachedResponse = await cache.match(offlinePath);
161
-
162
- if (!preCachedResponse) throw new Error(`Offline page not found in cache: ${offlinePath}`);
163
-
164
- console.log('Serving offline HTML page.');
105
+ const cache = await caches.open(CACHE_NAME);
106
+ const preCachedResponse = await cache.match(
107
+ `${PROXY_PATH === '/' ? '' : PROXY_PATH}/maintenance/index.html`,
108
+ );
109
+ if (!preCachedResponse) throw new Error(error.message);
165
110
  return preCachedResponse;
166
111
  }
167
-
168
- // B. OFFLINE API FALLBACK (Non-GET requests)
169
- console.log('Serving offline JSON response for non-GET request.');
170
- const response = new Response(JSON.stringify({ status: 'error', message: 'offline test response' }));
112
+ const response = new Response(JSON.stringify({ status: 'error', message: 'server in maintenance' }));
113
+ // response.status = 200;
114
+ response.headers.set('Content-Type', 'application/json');
115
+ return response;
116
+ } catch (error) {
117
+ console.error('Error opening cache for offline page', event.request.url, error);
118
+ const response = new Response(JSON.stringify({ status: 'error', message: error.message }));
119
+ // response.status = 200;
171
120
  response.headers.set('Content-Type', 'application/json');
172
121
  return response;
173
122
  }
174
-
175
- // C. MAINTENANCE FALLBACK (Online, but network failed - interpreted as maintenance)
176
- if (event.request.method.toUpperCase() === 'GET') {
177
- const maintenancePath = `${this.PROXY_PATH === '/' ? '' : this.PROXY_PATH}/maintenance/index.html`;
178
- const preCachedResponse = await cache.match(maintenancePath);
179
-
180
- if (!preCachedResponse) throw new Error(`Maintenance page not found in cache: ${maintenancePath}`);
181
-
182
- console.log('Serving maintenance HTML page.');
183
- return preCachedResponse;
184
- }
185
-
186
- // D. MAINTENANCE API FALLBACK (Non-GET requests)
187
- console.log('Serving maintenance JSON response for non-GET request.');
188
- const response = new Response(JSON.stringify({ status: 'error', message: 'server in maintenance' }));
189
- response.headers.set('Content-Type', 'application/json');
190
- return response;
191
- } catch (finalError) {
192
- // 5. Final fail-safe response
193
- console.error('Final fail-safe execution failed.', event.request.url, finalError);
194
- const response = new Response(JSON.stringify({ status: 'error', message: finalError.message }));
195
- response.headers.set('Content-Type', 'application/json');
196
- return response;
197
123
  }
198
124
  }
199
- }
200
- }
201
- }
202
-
203
- // Instantiate and run the service worker class
204
- new PwaServiceWorker().run();
125
+ })(),
126
+ );
127
+ });
package/src/index.js CHANGED
@@ -36,42 +36,52 @@ class Underpost {
36
36
  * @type {String}
37
37
  * @memberof Underpost
38
38
  */
39
- static version = 'v2.97.5';
39
+ static version = 'v2.98.1';
40
40
  /**
41
41
  * Repository cli API
42
42
  * @static
43
43
  * @type {UnderpostRepository.API}
44
44
  * @memberof Underpost
45
45
  */
46
- static repo = UnderpostRepository.API;
46
+ static get repo() {
47
+ return UnderpostRepository.API;
48
+ }
47
49
  /**
48
50
  * Root Env cli API
49
51
  * @static
50
52
  * @type {UnderpostRootEnv.API}
51
53
  * @memberof Underpost
52
54
  */
53
- static env = UnderpostRootEnv.API;
55
+ static get env() {
56
+ return UnderpostRootEnv.API;
57
+ }
54
58
  /**
55
59
  * Test cli API
56
60
  * @static
57
61
  * @type {UnderpostTest.API}
58
62
  * @memberof Underpost
59
63
  */
60
- static test = UnderpostTest.API;
64
+ static get test() {
65
+ return UnderpostTest.API;
66
+ }
61
67
  /**
62
68
  * Underpost Start Up cli API
63
69
  * @static
64
70
  * @type {UnderpostStartUp.API}
65
71
  * @memberof Underpost
66
72
  */
67
- static start = UnderpostStartUp.API;
73
+ static get start() {
74
+ return UnderpostStartUp.API;
75
+ }
68
76
  /**
69
77
  * Static cli API
70
78
  * @static
71
79
  * @type {UnderpostStatic.API}
72
80
  * @memberof Underpost
73
81
  */
74
- static static = UnderpostStatic.API;
82
+ static get static() {
83
+ return UnderpostStatic.API;
84
+ }
75
85
 
76
86
  /**
77
87
  * Cluster cli API
@@ -79,77 +89,99 @@ class Underpost {
79
89
  * @type {UnderpostCluster.API}
80
90
  * @memberof Underpost
81
91
  */
82
- static cluster = UnderpostCluster.API;
92
+ static get cluster() {
93
+ return UnderpostCluster.API;
94
+ }
83
95
  /**
84
96
  * Image cli API
85
97
  * @static
86
98
  * @type {UnderpostImage.API}
87
99
  * @memberof Underpost
88
100
  */
89
- static image = UnderpostImage.API;
101
+ static get image() {
102
+ return UnderpostImage.API;
103
+ }
90
104
  /**
91
105
  * Secrets cli API
92
106
  * @static
93
107
  * @type {UnderpostSecret.API}
94
108
  * @memberof Underpost
95
109
  */
96
- static secret = UnderpostSecret.API;
110
+ static get secret() {
111
+ return UnderpostSecret.API;
112
+ }
97
113
  /**
98
114
  * Scripts cli API
99
115
  * @static
100
116
  * @type {UnderpostScript.API}
101
117
  * @memberof Underpost
102
118
  */
103
- static script = UnderpostScript.API;
119
+ static get script() {
120
+ return UnderpostScript.API;
121
+ }
104
122
  /**
105
123
  * Database cli API
106
124
  * @static
107
125
  * @type {UnderpostDB.API}
108
126
  * @memberof Underpost
109
127
  */
110
- static db = UnderpostDB.API;
128
+ static get db() {
129
+ return UnderpostDB.API;
130
+ }
111
131
  /**
112
132
  * Deployment cli API
113
133
  * @static
114
134
  * @type {UnderpostDeploy.API}
115
135
  * @memberof Underpost
116
136
  */
117
- static deploy = UnderpostDeploy.API;
137
+ static get deploy() {
138
+ return UnderpostDeploy.API;
139
+ }
118
140
  /**
119
141
  * Cron cli API
120
142
  * @static
121
143
  * @type {UnderpostCron.API}
122
144
  * @memberof Underpost
123
145
  */
124
- static cron = UnderpostCron.API;
146
+ static get cron() {
147
+ return UnderpostCron.API;
148
+ }
125
149
  /**
126
150
  * File Storage cli API
127
151
  * @static
128
152
  * @type {UnderpostFileStorage.API}
129
153
  * @memberof Underpost
130
154
  */
131
- static fs = UnderpostFileStorage.API;
155
+ static get fs() {
156
+ return UnderpostFileStorage.API;
157
+ }
132
158
  /**
133
159
  * Monitor cli API
134
160
  * @static
135
161
  * @type {UnderpostMonitor.API}
136
162
  * @memberof Underpost
137
163
  */
138
- static monitor = UnderpostMonitor.API;
164
+ static get monitor() {
165
+ return UnderpostMonitor.API;
166
+ }
139
167
  /**
140
168
  * SSH cli API
141
169
  * @static
142
170
  * @type {UnderpostSSH.API}
143
171
  * @memberof Underpost
144
172
  */
145
- static ssh = UnderpostSSH.API;
173
+ static get ssh() {
174
+ return UnderpostSSH.API;
175
+ }
146
176
  /**
147
177
  * LXD cli API
148
178
  * @static
149
179
  * @type {UnderpostLxd.API}
150
180
  * @memberof Underpost
151
181
  */
152
- static lxd = UnderpostLxd.API;
182
+ static get lxd() {
183
+ return UnderpostLxd.API;
184
+ }
153
185
 
154
186
  /**
155
187
  * Cloud Init cli API
@@ -157,7 +189,9 @@ class Underpost {
157
189
  * @type {UnderpostCloudInit.API}
158
190
  * @memberof Underpost
159
191
  */
160
- static cloudInit = UnderpostCloudInit.API;
192
+ static get cloudInit() {
193
+ return UnderpostCloudInit.API;
194
+ }
161
195
 
162
196
  /**
163
197
  * Run cli API
@@ -165,7 +199,9 @@ class Underpost {
165
199
  * @type {UnderpostRun.API}
166
200
  * @memberof Underpost
167
201
  */
168
- static run = UnderpostRun.API;
202
+ static get run() {
203
+ return UnderpostRun.API;
204
+ }
169
205
 
170
206
  /**
171
207
  * Baremetal cli API
@@ -173,7 +209,9 @@ class Underpost {
173
209
  * @type {UnderpostBaremetal.API}
174
210
  * @memberof Underpost
175
211
  */
176
- static baremetal = UnderpostBaremetal.API;
212
+ static get baremetal() {
213
+ return UnderpostBaremetal.API;
214
+ }
177
215
  }
178
216
 
179
217
  const up = Underpost;