underpost 3.2.4 → 3.2.8
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/.github/workflows/release.cd.yml +1 -2
- package/CHANGELOG.md +268 -1
- package/CLI-HELP.md +26 -13
- package/Dockerfile +0 -4
- package/README.md +3 -3
- package/bin/build.js +13 -3
- package/bin/deploy.js +570 -1
- package/bin/file.js +5 -0
- package/conf.js +11 -2
- package/jsconfig.json +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -3
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +2 -3
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
- package/manifests/deployment/dd-test-development/deployment.yaml +136 -66
- package/manifests/deployment/dd-test-development/proxy.yaml +41 -5
- package/package.json +20 -11
- package/src/api/core/core.controller.js +10 -10
- package/src/api/core/core.service.js +10 -10
- package/src/api/default/default.controller.js +10 -10
- package/src/api/default/default.service.js +10 -10
- package/src/api/document/document.controller.js +12 -12
- package/src/api/document/document.model.js +10 -16
- package/src/api/file/file.controller.js +8 -8
- package/src/api/file/file.model.js +10 -10
- package/src/api/file/file.service.js +36 -36
- package/src/api/test/test.controller.js +8 -8
- package/src/api/test/test.service.js +8 -8
- package/src/api/user/guest.service.js +99 -0
- package/src/api/user/user.controller.js +6 -6
- package/src/api/user/user.model.js +8 -13
- package/src/api/user/user.service.js +3 -20
- package/src/cli/deploy.js +33 -30
- package/src/cli/fs.js +62 -5
- package/src/cli/image.js +43 -1
- package/src/cli/index.js +5 -1
- package/src/cli/release.js +58 -2
- package/src/cli/repository.js +35 -3
- package/src/cli/run.js +304 -38
- package/src/cli/ssh.js +1 -1
- package/src/cli/static.js +43 -115
- package/src/client/Default.index.js +21 -33
- package/src/client/components/core/404.js +4 -4
- package/src/client/components/core/500.js +4 -4
- package/src/client/components/core/Account.js +73 -60
- package/src/client/components/core/AgGrid.js +23 -33
- package/src/client/components/core/Alert.js +12 -13
- package/src/client/components/core/AppStore.js +1 -1
- package/src/client/components/core/Auth.js +20 -32
- package/src/client/components/core/Badge.js +7 -13
- package/src/client/components/core/BtnIcon.js +15 -17
- package/src/client/components/core/CalendarCore.js +42 -63
- package/src/client/components/core/Chat.js +13 -15
- package/src/client/components/core/ClientEvents.js +87 -0
- package/src/client/components/core/ColorPaletteElement.js +309 -0
- package/src/client/components/core/Content.js +17 -14
- package/src/client/components/core/Css.js +15 -71
- package/src/client/components/core/CssCore.js +12 -16
- package/src/client/components/core/D3Chart.js +4 -4
- package/src/client/components/core/Docs.js +60 -59
- package/src/client/components/core/DropDown.js +69 -91
- package/src/client/components/core/EventBus.js +92 -0
- package/src/client/components/core/EventsUI.js +14 -17
- package/src/client/components/core/FileExplorer.js +102 -234
- package/src/client/components/core/FullScreen.js +47 -75
- package/src/client/components/core/Input.js +24 -69
- package/src/client/components/core/Keyboard.js +25 -18
- package/src/client/components/core/KeyboardAvoidance.js +145 -0
- package/src/client/components/core/LoadingAnimation.js +25 -31
- package/src/client/components/core/LogIn.js +41 -41
- package/src/client/components/core/LogOut.js +23 -14
- package/src/client/components/core/Modal.js +397 -176
- package/src/client/components/core/NotificationManager.js +14 -18
- package/src/client/components/core/Panel.js +54 -50
- package/src/client/components/core/PanelForm.js +25 -125
- package/src/client/components/core/Polyhedron.js +110 -214
- package/src/client/components/core/PublicProfile.js +39 -32
- package/src/client/components/core/Recover.js +52 -48
- package/src/client/components/core/Responsive.js +88 -32
- package/src/client/components/core/RichText.js +9 -18
- package/src/client/components/core/Router.js +24 -3
- package/src/client/components/core/SearchBox.js +37 -37
- package/src/client/components/core/SignUp.js +39 -30
- package/src/client/components/core/SocketIo.js +31 -2
- package/src/client/components/core/SocketIoHandler.js +6 -6
- package/src/client/components/core/ToggleSwitch.js +8 -20
- package/src/client/components/core/ToolTip.js +5 -17
- package/src/client/components/core/Translate.js +56 -59
- package/src/client/components/core/Validator.js +26 -16
- package/src/client/components/core/Wallet.js +15 -26
- package/src/client/components/core/Worker.js +140 -25
- package/src/client/components/core/windowGetDimensions.js +7 -7
- package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +87 -87
- package/src/client/components/default/CssDefault.js +12 -12
- package/src/client/components/default/LogInDefault.js +6 -4
- package/src/client/components/default/LogOutDefault.js +6 -4
- package/src/client/components/default/RouterDefault.js +47 -0
- package/src/client/components/default/SettingsDefault.js +4 -4
- package/src/client/components/default/SignUpDefault.js +6 -4
- package/src/client/components/default/TranslateDefault.js +3 -3
- package/src/client/services/core/core.service.js +17 -49
- package/src/client/services/default/default.management.js +139 -242
- package/src/client/services/default/default.service.js +10 -16
- package/src/client/services/document/document.service.js +14 -19
- package/src/client/services/file/file.service.js +8 -13
- package/src/client/services/test/test.service.js +8 -13
- package/src/client/services/user/guest.service.js +79 -0
- package/src/client/services/user/user.management.js +5 -5
- package/src/client/services/user/user.service.js +14 -20
- package/src/client/ssr/body/404.js +3 -3
- package/src/client/ssr/body/500.js +3 -3
- package/src/client/ssr/body/CacheControl.js +5 -2
- package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
- package/src/client/ssr/offline/Maintenance.js +12 -11
- package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
- package/src/client/ssr/pages/Test.js +2 -2
- package/src/client/sw/core.sw.js +212 -0
- package/src/index.js +1 -1
- package/src/runtime/express/Dockerfile +4 -4
- package/src/runtime/lampp/Dockerfile +8 -7
- package/src/runtime/wp/Dockerfile +11 -17
- package/src/server/backup.js +1 -2
- package/src/server/client-build-docs.js +45 -46
- package/src/server/client-build.js +334 -60
- package/src/server/client-formatted.js +47 -16
- package/src/server/conf.js +29 -13
- package/src/server/cron.js +6 -8
- package/src/server/dns.js +2 -1
- package/src/server/ipfs-client.js +232 -91
- package/src/server/process.js +13 -27
- package/src/server/start.js +6 -3
- package/src/server/valkey.js +134 -235
- package/tsconfig.docs.json +15 -0
- package/typedoc.json +20 -0
- package/jsdoc.json +0 -52
- package/src/client/components/core/ColorPalette.js +0 -5267
- package/src/client/components/core/JoyStick.js +0 -80
- package/src/client/components/default/RoutesDefault.js +0 -49
- package/src/client/sw/default.sw.js +0 -127
- package/src/client/sw/template.sw.js +0 -84
package/src/cli/static.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* @module src/cli/static.js
|
|
4
4
|
* @namespace UnderpostStatic
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
6
|
import fs from 'fs-extra';
|
|
8
7
|
import path from 'path';
|
|
9
8
|
import express from 'express';
|
|
@@ -12,9 +11,7 @@ import { shellExec } from '../server/process.js';
|
|
|
12
11
|
import Underpost from '../index.js';
|
|
13
12
|
import { JSONweb } from '../server/client-formatted.js';
|
|
14
13
|
import { loggerFactory, loggerMiddleware } from '../server/logger.js';
|
|
15
|
-
|
|
16
14
|
const logger = loggerFactory(import.meta);
|
|
17
|
-
|
|
18
15
|
/**
|
|
19
16
|
* @typedef {Object} MetadataOptions
|
|
20
17
|
* @memberof UnderpostStatic
|
|
@@ -30,7 +27,6 @@ const logger = loggerFactory(import.meta);
|
|
|
30
27
|
* @property {Object} [openGraph={}] - Additional Open Graph metadata
|
|
31
28
|
* @property {Object} [twitter={}] - Twitter card metadata
|
|
32
29
|
*/
|
|
33
|
-
|
|
34
30
|
/**
|
|
35
31
|
* @typedef {Object} ScriptOptions
|
|
36
32
|
* @memberof UnderpostStatic
|
|
@@ -43,7 +39,6 @@ const logger = loggerFactory(import.meta);
|
|
|
43
39
|
* @property {string} [crossorigin] - CORS settings
|
|
44
40
|
* @property {Object} [attributes={}] - Additional HTML attributes
|
|
45
41
|
*/
|
|
46
|
-
|
|
47
42
|
/**
|
|
48
43
|
* @typedef {Object} StyleOptions
|
|
49
44
|
* @memberof UnderpostStatic
|
|
@@ -53,7 +48,6 @@ const logger = loggerFactory(import.meta);
|
|
|
53
48
|
* @property {string} [integrity] - Subresource integrity hash
|
|
54
49
|
* @property {string} [crossorigin] - CORS settings
|
|
55
50
|
*/
|
|
56
|
-
|
|
57
51
|
/**
|
|
58
52
|
* @typedef {Object} IconOptions
|
|
59
53
|
* @memberof UnderpostStatic
|
|
@@ -62,7 +56,6 @@ const logger = loggerFactory(import.meta);
|
|
|
62
56
|
* @property {string} [manifest] - Web manifest path
|
|
63
57
|
* @property {Object[]} [additional=[]] - Additional icon definitions
|
|
64
58
|
*/
|
|
65
|
-
|
|
66
59
|
/**
|
|
67
60
|
* @typedef {Object} StaticGenerationOptions
|
|
68
61
|
* @memberof UnderpostStatic
|
|
@@ -88,43 +81,40 @@ const logger = loggerFactory(import.meta);
|
|
|
88
81
|
* @property {string} [dir='ltr'] - HTML dir attribute
|
|
89
82
|
* @property {Object} [microdata=[]] - Structured data (JSON-LD)
|
|
90
83
|
*/
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
};
|
|
113
|
-
|
|
84
|
+
class DefaultStaticGenerationOptions {
|
|
85
|
+
static page = '';
|
|
86
|
+
static title = '';
|
|
87
|
+
static outputPath = '';
|
|
88
|
+
static buildPath = '/';
|
|
89
|
+
static env = 'production';
|
|
90
|
+
static dev = false;
|
|
91
|
+
static minify = true;
|
|
92
|
+
static metadata = {};
|
|
93
|
+
static scripts = {};
|
|
94
|
+
static styles = [];
|
|
95
|
+
static headComponents = [];
|
|
96
|
+
static bodyComponents = [];
|
|
97
|
+
static icons = {};
|
|
98
|
+
static customPayload = {};
|
|
99
|
+
static templateHelpers = {};
|
|
100
|
+
static configFile = '';
|
|
101
|
+
static lang = 'en';
|
|
102
|
+
static dir = 'ltr';
|
|
103
|
+
static microdata = [];
|
|
104
|
+
}
|
|
114
105
|
/**
|
|
115
106
|
* Template helper functions for common SSR patterns
|
|
116
107
|
* @namespace TemplateHelpers
|
|
117
108
|
*/
|
|
118
|
-
|
|
109
|
+
class TemplateHelpers {
|
|
119
110
|
/**
|
|
120
111
|
* Generates a script tag from options
|
|
121
112
|
* @param {ScriptOptions} options - Script options
|
|
122
113
|
* @returns {string} HTML script tag
|
|
123
114
|
* @memberof TemplateHelpers
|
|
124
115
|
*/
|
|
125
|
-
createScriptTag(options) {
|
|
116
|
+
static createScriptTag(options) {
|
|
126
117
|
const attrs = [];
|
|
127
|
-
|
|
128
118
|
if (options.type && options.type !== 'text/javascript') {
|
|
129
119
|
attrs.push(`type="${options.type}"`);
|
|
130
120
|
}
|
|
@@ -133,49 +123,41 @@ const TemplateHelpers = {
|
|
|
133
123
|
if (options.src) attrs.push(`src="${options.src}"`);
|
|
134
124
|
if (options.integrity) attrs.push(`integrity="${options.integrity}"`);
|
|
135
125
|
if (options.crossorigin) attrs.push(`crossorigin="${options.crossorigin}"`);
|
|
136
|
-
|
|
137
126
|
// Add custom attributes
|
|
138
127
|
if (options.attributes) {
|
|
139
128
|
Object.entries(options.attributes).forEach(([key, value]) => {
|
|
140
129
|
attrs.push(`${key}="${value}"`);
|
|
141
130
|
});
|
|
142
131
|
}
|
|
143
|
-
|
|
144
132
|
const attrString = attrs.length > 0 ? ` ${attrs.join(' ')}` : '';
|
|
145
133
|
const content = options.content || '';
|
|
146
|
-
|
|
147
134
|
return `<script${attrString}>${content}</script>`;
|
|
148
|
-
}
|
|
149
|
-
|
|
135
|
+
}
|
|
150
136
|
/**
|
|
151
137
|
* Generates a link/style tag from options
|
|
152
138
|
* @param {StyleOptions} options - Style options
|
|
153
139
|
* @returns {string} HTML link or style tag
|
|
154
140
|
* @memberof TemplateHelpers
|
|
155
141
|
*/
|
|
156
|
-
createStyleTag(options) {
|
|
142
|
+
static createStyleTag(options) {
|
|
157
143
|
if (options.content) {
|
|
158
144
|
return `<style>${options.content}</style>`;
|
|
159
145
|
}
|
|
160
|
-
|
|
161
146
|
const attrs = [`rel="stylesheet"`];
|
|
162
147
|
if (options.href) attrs.push(`href="${options.href}"`);
|
|
163
148
|
if (options.media) attrs.push(`media="${options.media}"`);
|
|
164
149
|
if (options.integrity) attrs.push(`integrity="${options.integrity}"`);
|
|
165
150
|
if (options.crossorigin) attrs.push(`crossorigin="${options.crossorigin}"`);
|
|
166
|
-
|
|
167
151
|
return `<link ${attrs.join(' ')}>`;
|
|
168
|
-
}
|
|
169
|
-
|
|
152
|
+
}
|
|
170
153
|
/**
|
|
171
154
|
* Generates icon link tags
|
|
172
155
|
* @param {IconOptions} icons - Icon options
|
|
173
156
|
* @returns {string} HTML icon link tags
|
|
174
157
|
* @memberof TemplateHelpers
|
|
175
158
|
*/
|
|
176
|
-
createIconTags(icons) {
|
|
159
|
+
static createIconTags(icons) {
|
|
177
160
|
const tags = [];
|
|
178
|
-
|
|
179
161
|
if (icons.favicon) {
|
|
180
162
|
tags.push(`<link rel="icon" type="image/x-icon" href="${icons.favicon}">`);
|
|
181
163
|
}
|
|
@@ -193,19 +175,16 @@ const TemplateHelpers = {
|
|
|
193
175
|
tags.push(`<link ${attrs}>`);
|
|
194
176
|
});
|
|
195
177
|
}
|
|
196
|
-
|
|
197
178
|
return tags.join('\n');
|
|
198
|
-
}
|
|
199
|
-
|
|
179
|
+
}
|
|
200
180
|
/**
|
|
201
181
|
* Generates meta tags from metadata object
|
|
202
182
|
* @param {MetadataOptions} metadata - Metadata options
|
|
203
183
|
* @returns {string} HTML meta tags
|
|
204
184
|
* @memberof TemplateHelpers
|
|
205
185
|
*/
|
|
206
|
-
createMetaTags(metadata) {
|
|
186
|
+
static createMetaTags(metadata) {
|
|
207
187
|
const tags = [];
|
|
208
|
-
|
|
209
188
|
if (metadata.description) {
|
|
210
189
|
tags.push(`<meta name="description" content="${metadata.description}">`);
|
|
211
190
|
}
|
|
@@ -218,7 +197,6 @@ const TemplateHelpers = {
|
|
|
218
197
|
if (metadata.themeColor) {
|
|
219
198
|
tags.push(`<meta name="theme-color" content="${metadata.themeColor}">`);
|
|
220
199
|
}
|
|
221
|
-
|
|
222
200
|
// Open Graph
|
|
223
201
|
if (metadata.title) {
|
|
224
202
|
tags.push(`<meta property="og:title" content="${metadata.title}">`);
|
|
@@ -239,7 +217,6 @@ const TemplateHelpers = {
|
|
|
239
217
|
if (metadata.locale) {
|
|
240
218
|
tags.push(`<meta property="og:locale" content="${metadata.locale}">`);
|
|
241
219
|
}
|
|
242
|
-
|
|
243
220
|
// Twitter Card
|
|
244
221
|
tags.push(`<meta name="twitter:card" content="summary_large_image">`);
|
|
245
222
|
if (metadata.twitter) {
|
|
@@ -247,53 +224,46 @@ const TemplateHelpers = {
|
|
|
247
224
|
tags.push(`<meta name="twitter:${key}" content="${value}">`);
|
|
248
225
|
});
|
|
249
226
|
}
|
|
250
|
-
|
|
251
227
|
// Additional Open Graph
|
|
252
228
|
if (metadata.openGraph) {
|
|
253
229
|
Object.entries(metadata.openGraph).forEach(([key, value]) => {
|
|
254
230
|
tags.push(`<meta property="og:${key}" content="${value}">`);
|
|
255
231
|
});
|
|
256
232
|
}
|
|
257
|
-
|
|
258
233
|
return tags.join('\n');
|
|
259
|
-
}
|
|
260
|
-
|
|
234
|
+
}
|
|
261
235
|
/**
|
|
262
236
|
* Generates JSON-LD structured data script tags
|
|
263
237
|
* @param {Object[]} microdata - Array of structured data objects
|
|
264
238
|
* @returns {string} HTML script tags with JSON-LD
|
|
265
239
|
* @memberof TemplateHelpers
|
|
266
240
|
*/
|
|
267
|
-
createMicrodataTags(microdata) {
|
|
241
|
+
static createMicrodataTags(microdata) {
|
|
268
242
|
if (!microdata || !Array.isArray(microdata) || microdata.length === 0) {
|
|
269
243
|
return '';
|
|
270
244
|
}
|
|
271
|
-
|
|
272
245
|
return microdata
|
|
273
246
|
.map((data) => `<script type="application/ld+json">\n${JSON.stringify(data, null, 2)}\n</script>`)
|
|
274
247
|
.join('\n');
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
248
|
+
}
|
|
249
|
+
}
|
|
278
250
|
/**
|
|
279
251
|
* Configuration validator
|
|
280
252
|
* @namespace ConfigValidator
|
|
281
253
|
*/
|
|
282
|
-
|
|
254
|
+
class ConfigValidator {
|
|
283
255
|
/**
|
|
284
256
|
* Validates static generation options
|
|
285
257
|
* @param {StaticGenerationOptions} options - Options to validate
|
|
286
258
|
* @returns {Object} Validation result with isValid flag and errors array
|
|
287
259
|
* @memberof ConfigValidator
|
|
288
260
|
*/
|
|
289
|
-
validate(options) {
|
|
261
|
+
static validate(options) {
|
|
290
262
|
const errors = [];
|
|
291
|
-
|
|
292
263
|
// Validate page path
|
|
293
264
|
if (options.page && !fs.existsSync(options.page)) {
|
|
294
265
|
errors.push(`Page component does not exist: ${options.page}`);
|
|
295
266
|
}
|
|
296
|
-
|
|
297
267
|
// Validate head components
|
|
298
268
|
if (options.headComponents && Array.isArray(options.headComponents)) {
|
|
299
269
|
options.headComponents.forEach((comp) => {
|
|
@@ -302,7 +272,6 @@ const ConfigValidator = {
|
|
|
302
272
|
}
|
|
303
273
|
});
|
|
304
274
|
}
|
|
305
|
-
|
|
306
275
|
// Validate body components
|
|
307
276
|
if (options.bodyComponents && Array.isArray(options.bodyComponents)) {
|
|
308
277
|
options.bodyComponents.forEach((comp) => {
|
|
@@ -311,61 +280,55 @@ const ConfigValidator = {
|
|
|
311
280
|
}
|
|
312
281
|
});
|
|
313
282
|
}
|
|
314
|
-
|
|
315
283
|
// Validate environment
|
|
316
284
|
if (options.env && !['development', 'production'].includes(options.env)) {
|
|
317
285
|
logger.warn(`Invalid environment: ${options.env}. Using 'production' as default.`);
|
|
318
286
|
}
|
|
319
|
-
|
|
320
287
|
return {
|
|
321
288
|
isValid: errors.length === 0,
|
|
322
289
|
errors,
|
|
323
290
|
};
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
291
|
+
}
|
|
292
|
+
}
|
|
327
293
|
/**
|
|
328
294
|
* Configuration file loader
|
|
329
295
|
* @namespace ConfigLoader
|
|
330
296
|
*/
|
|
331
|
-
|
|
297
|
+
class ConfigLoader {
|
|
332
298
|
/**
|
|
333
299
|
* Loads configuration from a JSON file
|
|
334
300
|
* @param {string} configPath - Path to config file
|
|
335
301
|
* @returns {Object} Configuration object
|
|
336
302
|
* @memberof ConfigLoader
|
|
337
303
|
*/
|
|
338
|
-
load(configPath) {
|
|
304
|
+
static load(configPath) {
|
|
339
305
|
try {
|
|
340
306
|
if (!fs.existsSync(configPath)) {
|
|
341
307
|
logger.error(`Config file not found: ${configPath}`);
|
|
342
308
|
return {};
|
|
343
309
|
}
|
|
344
|
-
|
|
345
310
|
const content = fs.readFileSync(configPath, 'utf8');
|
|
346
311
|
return JSON.parse(content);
|
|
347
312
|
} catch (error) {
|
|
348
313
|
logger.error(`Error loading config file: ${error.message}`);
|
|
349
314
|
return {};
|
|
350
315
|
}
|
|
351
|
-
}
|
|
352
|
-
|
|
316
|
+
}
|
|
353
317
|
/**
|
|
354
318
|
* Saves configuration to a JSON file
|
|
355
319
|
* @param {string} configPath - Path to save config
|
|
356
320
|
* @param {Object} config - Configuration object
|
|
357
321
|
* @memberof ConfigLoader
|
|
358
322
|
*/
|
|
359
|
-
save(configPath, config) {
|
|
323
|
+
static save(configPath, config) {
|
|
360
324
|
try {
|
|
361
325
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
|
|
362
326
|
logger.info(`Config saved to: ${configPath}`);
|
|
363
327
|
} catch (error) {
|
|
364
328
|
logger.error(`Error saving config file: ${error.message}`);
|
|
365
329
|
}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
330
|
+
}
|
|
331
|
+
}
|
|
369
332
|
/**
|
|
370
333
|
* @class UnderpostStatic
|
|
371
334
|
* @description Enhanced static site generation class with comprehensive customization
|
|
@@ -406,7 +369,6 @@ class UnderpostStatic {
|
|
|
406
369
|
const configPath = typeof options.generateConfig === 'string' ? options.generateConfig : './static-config.json';
|
|
407
370
|
return Underpost.static.generateConfigTemplate(configPath);
|
|
408
371
|
}
|
|
409
|
-
|
|
410
372
|
// Parse comma-separated options
|
|
411
373
|
if (options.keywords) {
|
|
412
374
|
options.keywords = options.keywords.split(',').map((k) => k.trim());
|
|
@@ -428,7 +390,6 @@ class UnderpostStatic {
|
|
|
428
390
|
if (options.bodyComponents) {
|
|
429
391
|
options.bodyComponents = options.bodyComponents.split(',').map((c) => c.trim());
|
|
430
392
|
}
|
|
431
|
-
|
|
432
393
|
// Build metadata object from individual options
|
|
433
394
|
options.metadata = {
|
|
434
395
|
...(options.title && { title: options.title }),
|
|
@@ -441,7 +402,6 @@ class UnderpostStatic {
|
|
|
441
402
|
...(options.locale && { locale: options.locale }),
|
|
442
403
|
...(options.siteName && { siteName: options.siteName }),
|
|
443
404
|
};
|
|
444
|
-
|
|
445
405
|
// Build icons object
|
|
446
406
|
if (options.favicon || options.appleTouchIcon || options.manifest) {
|
|
447
407
|
options.icons = {
|
|
@@ -450,13 +410,11 @@ class UnderpostStatic {
|
|
|
450
410
|
...(options.manifest && { manifest: options.manifest }),
|
|
451
411
|
};
|
|
452
412
|
}
|
|
453
|
-
|
|
454
413
|
// Load config from file if specified
|
|
455
414
|
if (options.configFile) {
|
|
456
415
|
const fileConfig = ConfigLoader.load(options.configFile);
|
|
457
416
|
options = { ...fileConfig, ...options }; // CLI options override file config
|
|
458
417
|
}
|
|
459
|
-
|
|
460
418
|
// Set defaults
|
|
461
419
|
if (!options.outputPath) options.outputPath = '.';
|
|
462
420
|
if (!options.buildPath) options.buildPath = '/';
|
|
@@ -465,7 +423,6 @@ class UnderpostStatic {
|
|
|
465
423
|
if (!options.metadata) options.metadata = {};
|
|
466
424
|
if (!options.lang) options.lang = 'en';
|
|
467
425
|
if (!options.dir) options.dir = 'ltr';
|
|
468
|
-
|
|
469
426
|
// Merge title for backwards compatibility
|
|
470
427
|
if (options.title && !options.metadata.title) {
|
|
471
428
|
options.metadata.title = options.title;
|
|
@@ -473,7 +430,6 @@ class UnderpostStatic {
|
|
|
473
430
|
if (!options.metadata.title) {
|
|
474
431
|
options.metadata.title = 'Home';
|
|
475
432
|
}
|
|
476
|
-
|
|
477
433
|
// Validate options
|
|
478
434
|
const validation = ConfigValidator.validate(options);
|
|
479
435
|
if (!validation.isValid) {
|
|
@@ -483,44 +439,35 @@ class UnderpostStatic {
|
|
|
483
439
|
return; // Exit if critical path errors
|
|
484
440
|
}
|
|
485
441
|
}
|
|
486
|
-
|
|
487
442
|
// Generate page HTML
|
|
488
443
|
if (options.page) {
|
|
489
444
|
try {
|
|
490
445
|
logger.info(`Generating static page: ${options.page}`);
|
|
491
|
-
|
|
492
446
|
const Render = await ssrFactory();
|
|
493
447
|
const SsrComponent = await ssrFactory(options.page);
|
|
494
|
-
|
|
495
448
|
// Build head components
|
|
496
449
|
let ssrHeadComponents = '';
|
|
497
|
-
|
|
498
450
|
// Add custom meta tags
|
|
499
451
|
if (options.metadata) {
|
|
500
452
|
ssrHeadComponents += TemplateHelpers.createMetaTags(options.metadata);
|
|
501
453
|
}
|
|
502
|
-
|
|
503
454
|
// Add custom icons
|
|
504
455
|
if (options.icons) {
|
|
505
456
|
ssrHeadComponents += '\n' + TemplateHelpers.createIconTags(options.icons);
|
|
506
457
|
}
|
|
507
|
-
|
|
508
458
|
// Add custom styles
|
|
509
459
|
if (options.styles && Array.isArray(options.styles)) {
|
|
510
460
|
ssrHeadComponents += '\n' + options.styles.map((style) => TemplateHelpers.createStyleTag(style)).join('\n');
|
|
511
461
|
}
|
|
512
|
-
|
|
513
462
|
// Add custom head scripts
|
|
514
463
|
if (options.scripts?.head && Array.isArray(options.scripts.head)) {
|
|
515
464
|
ssrHeadComponents +=
|
|
516
465
|
'\n' + options.scripts.head.map((script) => TemplateHelpers.createScriptTag(script)).join('\n');
|
|
517
466
|
}
|
|
518
|
-
|
|
519
467
|
// Add microdata/structured data
|
|
520
468
|
if (options.microdata && Array.isArray(options.microdata)) {
|
|
521
469
|
ssrHeadComponents += '\n' + TemplateHelpers.createMicrodataTags(options.microdata);
|
|
522
470
|
}
|
|
523
|
-
|
|
524
471
|
// Load additional head components
|
|
525
472
|
if (options.headComponents && Array.isArray(options.headComponents)) {
|
|
526
473
|
for (const compPath of options.headComponents) {
|
|
@@ -538,10 +485,8 @@ class UnderpostStatic {
|
|
|
538
485
|
}
|
|
539
486
|
}
|
|
540
487
|
}
|
|
541
|
-
|
|
542
488
|
// Build body components
|
|
543
489
|
let ssrBodyComponents = SsrComponent();
|
|
544
|
-
|
|
545
490
|
// Load additional body components
|
|
546
491
|
if (options.bodyComponents && Array.isArray(options.bodyComponents)) {
|
|
547
492
|
for (const compPath of options.bodyComponents) {
|
|
@@ -553,20 +498,17 @@ class UnderpostStatic {
|
|
|
553
498
|
}
|
|
554
499
|
}
|
|
555
500
|
}
|
|
556
|
-
|
|
557
501
|
// Add custom body scripts
|
|
558
502
|
if (options.scripts?.body && Array.isArray(options.scripts.body)) {
|
|
559
503
|
ssrBodyComponents +=
|
|
560
504
|
'\n' + options.scripts.body.map((script) => TemplateHelpers.createScriptTag(script)).join('\n');
|
|
561
505
|
}
|
|
562
|
-
|
|
563
506
|
// Build render payload
|
|
564
507
|
const renderPayload = {
|
|
565
508
|
version: Underpost.version,
|
|
566
509
|
...(options.env === 'development' ? { dev: true } : undefined),
|
|
567
510
|
...options.customPayload,
|
|
568
511
|
};
|
|
569
|
-
|
|
570
512
|
// Generate HTML
|
|
571
513
|
const htmlSrc = Render({
|
|
572
514
|
title: options.metadata.title,
|
|
@@ -578,13 +520,11 @@ class UnderpostStatic {
|
|
|
578
520
|
JSONweb,
|
|
579
521
|
},
|
|
580
522
|
});
|
|
581
|
-
|
|
582
523
|
// Write output file
|
|
583
524
|
const outputDir = path.dirname(options.outputPath);
|
|
584
525
|
if (!fs.existsSync(outputDir)) {
|
|
585
526
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
586
527
|
}
|
|
587
|
-
|
|
588
528
|
fs.writeFileSync(options.outputPath, htmlSrc, 'utf8');
|
|
589
529
|
logger.info(`Static page generated: ${options.outputPath}`);
|
|
590
530
|
} catch (error) {
|
|
@@ -593,7 +533,6 @@ class UnderpostStatic {
|
|
|
593
533
|
throw error;
|
|
594
534
|
}
|
|
595
535
|
}
|
|
596
|
-
|
|
597
536
|
// Start standalone static file server if --run-sv is specified
|
|
598
537
|
if (options.runSv !== undefined) {
|
|
599
538
|
const port = typeof options.runSv === 'string' ? parseInt(options.runSv, 10) : 5000;
|
|
@@ -601,25 +540,19 @@ class UnderpostStatic {
|
|
|
601
540
|
options.outputPath && options.outputPath !== '.'
|
|
602
541
|
? path.dirname(path.resolve(options.outputPath))
|
|
603
542
|
: path.resolve('.');
|
|
604
|
-
|
|
605
543
|
if (!fs.existsSync(servePath)) {
|
|
606
544
|
logger.error(`Serve path does not exist: ${servePath}`);
|
|
607
545
|
return;
|
|
608
546
|
}
|
|
609
|
-
|
|
610
547
|
const app = express();
|
|
611
|
-
|
|
612
548
|
app.use(loggerMiddleware(import.meta, 'debug', () => false));
|
|
613
|
-
|
|
614
549
|
app.use('/', express.static(servePath));
|
|
615
|
-
|
|
616
550
|
app.listen(port, () => {
|
|
617
551
|
logger.info(`Static file server running at http://localhost:${port}`);
|
|
618
552
|
logger.info(`Serving files from: ${servePath}`);
|
|
619
553
|
});
|
|
620
554
|
}
|
|
621
555
|
},
|
|
622
|
-
|
|
623
556
|
/**
|
|
624
557
|
* Helper method to generate a config template file
|
|
625
558
|
*
|
|
@@ -693,26 +626,22 @@ class UnderpostStatic {
|
|
|
693
626
|
customFeature: true,
|
|
694
627
|
},
|
|
695
628
|
};
|
|
696
|
-
|
|
697
629
|
ConfigLoader.save(outputPath, template);
|
|
698
630
|
logger.info(`Config template generated: ${outputPath}`);
|
|
699
631
|
},
|
|
700
632
|
};
|
|
701
|
-
|
|
702
633
|
/**
|
|
703
634
|
* Export template helpers for external use
|
|
704
635
|
* @static
|
|
705
636
|
* @memberof UnderpostStatic
|
|
706
637
|
*/
|
|
707
638
|
static TemplateHelpers = TemplateHelpers;
|
|
708
|
-
|
|
709
639
|
/**
|
|
710
640
|
* Export config validator for external use
|
|
711
641
|
* @static
|
|
712
642
|
* @memberof UnderpostStatic
|
|
713
643
|
*/
|
|
714
644
|
static ConfigValidator = ConfigValidator;
|
|
715
|
-
|
|
716
645
|
/**
|
|
717
646
|
* Export config loader for external use
|
|
718
647
|
* @static
|
|
@@ -720,6 +649,5 @@ class UnderpostStatic {
|
|
|
720
649
|
*/
|
|
721
650
|
static ConfigLoader = ConfigLoader;
|
|
722
651
|
}
|
|
723
|
-
|
|
724
652
|
export default UnderpostStatic;
|
|
725
653
|
export { TemplateHelpers, ConfigValidator, ConfigLoader };
|
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { Worker } from './components/core/Worker.js';
|
|
4
|
+
import { RouterDefault } from './components/default/RouterDefault.js';
|
|
5
|
+
import { AppShellDefault } from './components/default/AppShellDefault.js';
|
|
6
|
+
import { AppStoreDefault } from './components/default/AppStoreDefault.js';
|
|
7
|
+
import { SocketIoDefault } from './components/default/SocketIoDefault.js';
|
|
6
8
|
import { LogInDefault } from './components/default/LogInDefault.js';
|
|
7
9
|
import { LogOutDefault } from './components/default/LogOutDefault.js';
|
|
8
10
|
import { SignUpDefault } from './components/default/SignUpDefault.js';
|
|
9
|
-
import { MenuDefault } from './components/default/MenuDefault.js';
|
|
10
|
-
import { RouterDefault } from './components/default/RoutesDefault.js';
|
|
11
|
-
import { TranslateDefault } from './components/default/TranslateDefault.js';
|
|
12
|
-
import { Worker } from './components/core/Worker.js';
|
|
13
|
-
import { Keyboard } from './components/core/Keyboard.js';
|
|
14
|
-
import { SocketIo } from './components/core/SocketIo.js';
|
|
15
|
-
import { SocketIoDefault } from './components/default/SocketIoDefault.js';
|
|
16
|
-
import { AppStoreDefault } from './components/default/AppStoreDefault.js';
|
|
17
11
|
import { CssDefaultDark, CssDefaultLight } from './components/default/CssDefault.js';
|
|
12
|
+
import { TranslateDefault } from './components/default/TranslateDefault.js';
|
|
18
13
|
import { EventsUI } from './components/core/EventsUI.js';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const htmlMainBody = async () => {
|
|
14
|
+
const DefaultTemplate = async () => {
|
|
22
15
|
setTimeout(() => {
|
|
23
16
|
EventsUI.onClick('.get-started-button', (e) => {
|
|
24
17
|
e.preventDefault();
|
|
@@ -32,11 +25,10 @@ const htmlMainBody = async () => {
|
|
|
32
25
|
<span class="greeting">Hello, World!</span>
|
|
33
26
|
<span class="subtitle">Welcome to Our Platform</span>
|
|
34
27
|
</h1>
|
|
35
|
-
|
|
36
28
|
<div class="features">
|
|
37
29
|
<div class="feature-card">
|
|
38
30
|
<i class="icon">🚀</i>
|
|
39
|
-
<h3>Fast & Reliable</h3>
|
|
31
|
+
<h3>Fast & Reliable</h3>
|
|
40
32
|
<p>Lightning-fast performance with 99.9% uptime</p>
|
|
41
33
|
</div>
|
|
42
34
|
<div class="feature-card">
|
|
@@ -50,7 +42,6 @@ const htmlMainBody = async () => {
|
|
|
50
42
|
<p>Everything you need in one place</p>
|
|
51
43
|
</div>
|
|
52
44
|
</div>
|
|
53
|
-
|
|
54
45
|
<button class="cta-button get-started-button">
|
|
55
46
|
Get Started
|
|
56
47
|
<span class="button-icon">→</span>
|
|
@@ -60,24 +51,21 @@ const htmlMainBody = async () => {
|
|
|
60
51
|
`;
|
|
61
52
|
};
|
|
62
53
|
|
|
54
|
+
const CssDefaultThemes = [CssDefaultDark, CssDefaultLight];
|
|
55
|
+
|
|
63
56
|
window.onload = () =>
|
|
64
57
|
Worker.instance({
|
|
65
58
|
router: RouterDefault,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
await LogInDefault();
|
|
78
|
-
await LogOutDefault();
|
|
79
|
-
await SignUpDefault();
|
|
80
|
-
await Keyboard.Init();
|
|
81
|
-
await Modal.RenderSeoSanitizer();
|
|
59
|
+
template: DefaultTemplate,
|
|
60
|
+
themes: CssDefaultThemes,
|
|
61
|
+
translate: TranslateDefault,
|
|
62
|
+
render: AppShellDefault,
|
|
63
|
+
appStore: AppStoreDefault,
|
|
64
|
+
socketPath: '/',
|
|
65
|
+
session: {
|
|
66
|
+
socket: SocketIoDefault,
|
|
67
|
+
login: LogInDefault,
|
|
68
|
+
signout: LogOutDefault,
|
|
69
|
+
signup: SignUpDefault,
|
|
82
70
|
},
|
|
83
71
|
});
|
|
@@ -2,8 +2,8 @@ import { Alert } from './Alert.js';
|
|
|
2
2
|
import { Modal } from './Modal.js';
|
|
3
3
|
import { s } from './VanillaJs.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
class Page404 {
|
|
6
|
+
static async instance(options = { idModal: '' }) {
|
|
7
7
|
setTimeout(() => {
|
|
8
8
|
Modal.Data[options.idModal].onObserverListener['404'] = () => {
|
|
9
9
|
if (s(`.container-404-${options.idModal}`))
|
|
@@ -14,7 +14,7 @@ const Page404 = {
|
|
|
14
14
|
Modal.Data[options.idModal].onObserverListener['404']();
|
|
15
15
|
});
|
|
16
16
|
return html`<div class="in container-404-${options.idModal}">${await Alert.e404()}</div>`;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
19
|
|
|
20
20
|
export { Page404 };
|
|
@@ -2,8 +2,8 @@ import { Alert } from './Alert.js';
|
|
|
2
2
|
import { Modal } from './Modal.js';
|
|
3
3
|
import { s } from './VanillaJs.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
class Page500 {
|
|
6
|
+
static async instance(options = { idModal: '' }) {
|
|
7
7
|
setTimeout(() => {
|
|
8
8
|
Modal.Data[options.idModal].onObserverListener['500'] = () => {
|
|
9
9
|
if (s(`.container-500-${options.idModal}`))
|
|
@@ -14,7 +14,7 @@ const Page500 = {
|
|
|
14
14
|
Modal.Data[options.idModal].onObserverListener['500']();
|
|
15
15
|
});
|
|
16
16
|
return html`<div class="in container-500-${options.idModal}">${await Alert.e500()}</div>`;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
19
|
|
|
20
20
|
export { Page500 };
|