underpost 2.90.1 → 2.90.4
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/README.md +3 -3
- package/bin/deploy.js +16 -0
- package/cli.md +31 -5
- package/examples/QUICK-REFERENCE.md +499 -0
- package/examples/README.md +447 -0
- package/examples/STATIC-GENERATOR-GUIDE.md +807 -0
- package/examples/ssr-components/CustomPage.js +579 -0
- package/examples/static-config-example.json +183 -0
- package/examples/static-config-simple.json +57 -0
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
- package/package.json +1 -1
- package/src/api/document/document.model.js +7 -0
- package/src/api/document/document.service.js +4 -1
- package/src/cli/index.js +91 -4
- package/src/cli/run.js +1 -1
- package/src/cli/static.js +785 -49
- package/src/client/components/core/Input.js +6 -4
- package/src/client/components/core/Modal.js +13 -18
- package/src/client/components/core/Panel.js +26 -6
- package/src/client/components/core/PanelForm.js +67 -52
- package/src/index.js +1 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Example static site configuration file for Underpost Static Generator",
|
|
3
|
+
"_usage": "Use with: underpost static --config-file ./static-config-example.json",
|
|
4
|
+
|
|
5
|
+
"page": "./src/client/ssr/body/DefaultSplashScreen.js",
|
|
6
|
+
"outputPath": "./dist/index.html",
|
|
7
|
+
"env": "production",
|
|
8
|
+
"minify": true,
|
|
9
|
+
"lang": "en",
|
|
10
|
+
"dir": "ltr",
|
|
11
|
+
|
|
12
|
+
"metadata": {
|
|
13
|
+
"_comment": "SEO and social media metadata",
|
|
14
|
+
"title": "My Awesome Application",
|
|
15
|
+
"description": "A comprehensive example of a static site with full metadata customization",
|
|
16
|
+
"keywords": ["static site", "generator", "underpost", "seo", "progressive web app"],
|
|
17
|
+
"author": "Your Name or Company",
|
|
18
|
+
"themeColor": "#4CAF50",
|
|
19
|
+
"canonicalURL": "https://example.com",
|
|
20
|
+
"thumbnail": "https://example.com/images/og-thumbnail.png",
|
|
21
|
+
"locale": "en-US",
|
|
22
|
+
"siteName": "My Awesome Site",
|
|
23
|
+
"openGraph": {
|
|
24
|
+
"_comment": "Additional Open Graph properties",
|
|
25
|
+
"type": "website",
|
|
26
|
+
"image:width": "1200",
|
|
27
|
+
"image:height": "630"
|
|
28
|
+
},
|
|
29
|
+
"twitter": {
|
|
30
|
+
"_comment": "Twitter card specific metadata",
|
|
31
|
+
"site": "@yourhandle",
|
|
32
|
+
"creator": "@creatorhandle"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
"scripts": {
|
|
37
|
+
"_comment": "Scripts to inject into head and body sections",
|
|
38
|
+
"head": [
|
|
39
|
+
{
|
|
40
|
+
"_comment": "External analytics script with async loading",
|
|
41
|
+
"src": "https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID",
|
|
42
|
+
"async": true
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"_comment": "Inline configuration script",
|
|
46
|
+
"content": "window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'GA_MEASUREMENT_ID');",
|
|
47
|
+
"type": "text/javascript"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"_comment": "App configuration as inline script",
|
|
51
|
+
"content": "window.appConfig = { apiUrl: 'https://api.example.com', version: '1.0.0', features: { analytics: true, debugging: false } };",
|
|
52
|
+
"type": "text/javascript"
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"body": [
|
|
56
|
+
{
|
|
57
|
+
"_comment": "Main application bundle as ES module",
|
|
58
|
+
"src": "/dist/app.js",
|
|
59
|
+
"type": "module",
|
|
60
|
+
"defer": true
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"_comment": "Service worker registration",
|
|
64
|
+
"content": "if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js').then(reg => console.log('SW registered', reg)).catch(err => console.log('SW error', err)); }",
|
|
65
|
+
"type": "text/javascript"
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
"styles": [
|
|
71
|
+
{
|
|
72
|
+
"_comment": "Main stylesheet",
|
|
73
|
+
"href": "/styles/main.css"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"_comment": "External font",
|
|
77
|
+
"href": "https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"_comment": "Critical inline CSS for faster rendering",
|
|
81
|
+
"content": "body { margin: 0; padding: 0; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; } * { box-sizing: border-box; }"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"_comment": "Print stylesheet",
|
|
85
|
+
"href": "/styles/print.css",
|
|
86
|
+
"media": "print"
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
|
|
90
|
+
"icons": {
|
|
91
|
+
"_comment": "Icon configuration for various platforms",
|
|
92
|
+
"favicon": "/favicon.ico",
|
|
93
|
+
"appleTouchIcon": "/apple-touch-icon.png",
|
|
94
|
+
"manifest": "/manifest.json",
|
|
95
|
+
"additional": [
|
|
96
|
+
{
|
|
97
|
+
"rel": "icon",
|
|
98
|
+
"type": "image/png",
|
|
99
|
+
"sizes": "32x32",
|
|
100
|
+
"href": "/favicon-32x32.png"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"rel": "icon",
|
|
104
|
+
"type": "image/png",
|
|
105
|
+
"sizes": "16x16",
|
|
106
|
+
"href": "/favicon-16x16.png"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"rel": "mask-icon",
|
|
110
|
+
"href": "/safari-pinned-tab.svg",
|
|
111
|
+
"color": "#4CAF50"
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
"_headComponents_comment": "SSR components disabled in this example - they require specific data structures",
|
|
117
|
+
"headComponents": [],
|
|
118
|
+
|
|
119
|
+
"_bodyComponents_comment": "Additional SSR components to include in body section",
|
|
120
|
+
"bodyComponents": [],
|
|
121
|
+
|
|
122
|
+
"microdata": [
|
|
123
|
+
{
|
|
124
|
+
"_comment": "Organization schema for better SEO",
|
|
125
|
+
"@context": "https://schema.org",
|
|
126
|
+
"@type": "Organization",
|
|
127
|
+
"name": "My Organization",
|
|
128
|
+
"url": "https://example.com",
|
|
129
|
+
"logo": "https://example.com/logo.png",
|
|
130
|
+
"contactPoint": {
|
|
131
|
+
"@type": "ContactPoint",
|
|
132
|
+
"telephone": "+1-555-123-4567",
|
|
133
|
+
"contactType": "Customer Service"
|
|
134
|
+
},
|
|
135
|
+
"sameAs": [
|
|
136
|
+
"https://twitter.com/yourhandle",
|
|
137
|
+
"https://linkedin.com/company/yourcompany",
|
|
138
|
+
"https://github.com/yourorg"
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"_comment": "WebSite schema",
|
|
143
|
+
"@context": "https://schema.org",
|
|
144
|
+
"@type": "WebSite",
|
|
145
|
+
"name": "My Awesome Site",
|
|
146
|
+
"url": "https://example.com",
|
|
147
|
+
"potentialAction": {
|
|
148
|
+
"@type": "SearchAction",
|
|
149
|
+
"target": "https://example.com/search?q={search_term_string}",
|
|
150
|
+
"query-input": "required name=search_term_string"
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"_comment": "WebPage schema",
|
|
155
|
+
"@context": "https://schema.org",
|
|
156
|
+
"@type": "WebPage",
|
|
157
|
+
"name": "Home Page",
|
|
158
|
+
"description": "Welcome to our awesome site",
|
|
159
|
+
"url": "https://example.com"
|
|
160
|
+
}
|
|
161
|
+
],
|
|
162
|
+
|
|
163
|
+
"customPayload": {
|
|
164
|
+
"_comment": "Custom data injected into window.renderPayload",
|
|
165
|
+
"apiEndpoint": "https://api.example.com",
|
|
166
|
+
"cdnUrl": "https://cdn.example.com",
|
|
167
|
+
"features": {
|
|
168
|
+
"chat": true,
|
|
169
|
+
"notifications": true,
|
|
170
|
+
"darkMode": true
|
|
171
|
+
},
|
|
172
|
+
"externalServices": {
|
|
173
|
+
"analytics": "GA_MEASUREMENT_ID",
|
|
174
|
+
"maps": "GOOGLE_MAPS_API_KEY"
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
"buildPath": "/",
|
|
179
|
+
"deployId": "",
|
|
180
|
+
"buildHost": "",
|
|
181
|
+
"build": false,
|
|
182
|
+
"dev": false
|
|
183
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"page": "./examples/ssr-components/CustomPage.js",
|
|
3
|
+
"outputPath": "./public/default.net/example.html",
|
|
4
|
+
"env": "production",
|
|
5
|
+
"minify": true,
|
|
6
|
+
"lang": "en",
|
|
7
|
+
"dir": "ltr",
|
|
8
|
+
|
|
9
|
+
"metadata": {
|
|
10
|
+
"title": "Simple Example Page",
|
|
11
|
+
"description": "A simple working example of the static site generator",
|
|
12
|
+
"keywords": ["example", "static", "generator"],
|
|
13
|
+
"author": "Underpost",
|
|
14
|
+
"themeColor": "#667eea",
|
|
15
|
+
"canonicalURL": "https://example.com",
|
|
16
|
+
"thumbnail": "https://example.com/images/thumbnail.png",
|
|
17
|
+
"locale": "en-US",
|
|
18
|
+
"siteName": "Example Site"
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
"scripts": {
|
|
22
|
+
"head": [
|
|
23
|
+
{
|
|
24
|
+
"content": "console.log('Page loaded successfully');"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"body": []
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
"styles": [
|
|
31
|
+
{
|
|
32
|
+
"content": "/* Additional custom styles can go here */"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
|
|
36
|
+
"icons": {
|
|
37
|
+
"favicon": "/favicon.ico"
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
"headComponents": [],
|
|
41
|
+
"bodyComponents": [],
|
|
42
|
+
|
|
43
|
+
"microdata": [
|
|
44
|
+
{
|
|
45
|
+
"@context": "https://schema.org",
|
|
46
|
+
"@type": "WebPage",
|
|
47
|
+
"name": "Simple Example Page",
|
|
48
|
+
"description": "A simple working example",
|
|
49
|
+
"url": "https://example.com"
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
|
|
53
|
+
"customPayload": {
|
|
54
|
+
"example": true,
|
|
55
|
+
"message": "This is a simple working example"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -17,7 +17,7 @@ spec:
|
|
|
17
17
|
spec:
|
|
18
18
|
containers:
|
|
19
19
|
- name: dd-default-development-blue
|
|
20
|
-
image: localhost/rockylinux9-underpost:v2.90.
|
|
20
|
+
image: localhost/rockylinux9-underpost:v2.90.4
|
|
21
21
|
# resources:
|
|
22
22
|
# requests:
|
|
23
23
|
# memory: "124Ki"
|
|
@@ -100,7 +100,7 @@ spec:
|
|
|
100
100
|
spec:
|
|
101
101
|
containers:
|
|
102
102
|
- name: dd-default-development-green
|
|
103
|
-
image: localhost/rockylinux9-underpost:v2.90.
|
|
103
|
+
image: localhost/rockylinux9-underpost:v2.90.4
|
|
104
104
|
# resources:
|
|
105
105
|
# requests:
|
|
106
106
|
# memory: "124Ki"
|
|
@@ -18,7 +18,7 @@ spec:
|
|
|
18
18
|
spec:
|
|
19
19
|
containers:
|
|
20
20
|
- name: dd-test-development-blue
|
|
21
|
-
image: localhost/rockylinux9-underpost:v2.90.
|
|
21
|
+
image: localhost/rockylinux9-underpost:v2.90.4
|
|
22
22
|
|
|
23
23
|
command:
|
|
24
24
|
- /bin/sh
|
|
@@ -103,7 +103,7 @@ spec:
|
|
|
103
103
|
spec:
|
|
104
104
|
containers:
|
|
105
105
|
- name: dd-test-development-green
|
|
106
|
-
image: localhost/rockylinux9-underpost:v2.90.
|
|
106
|
+
image: localhost/rockylinux9-underpost:v2.90.4
|
|
107
107
|
|
|
108
108
|
command:
|
|
109
109
|
- /bin/sh
|
package/package.json
CHANGED
|
@@ -58,6 +58,7 @@ const DocumentService = {
|
|
|
58
58
|
.limit(limit)
|
|
59
59
|
.skip(skip)
|
|
60
60
|
.populate(DocumentDto.populate.file())
|
|
61
|
+
.populate(DocumentDto.populate.mdFile())
|
|
61
62
|
.populate(user && user.role !== 'guest' ? DocumentDto.populate.user() : null);
|
|
62
63
|
|
|
63
64
|
const lastDoc = await Document.findOne(queryPayload, '_id').sort({ createdAt: 1 });
|
|
@@ -74,7 +75,9 @@ const DocumentService = {
|
|
|
74
75
|
return await Document.find({
|
|
75
76
|
userId: req.auth.user._id,
|
|
76
77
|
...(req.params.id ? { _id: req.params.id } : undefined),
|
|
77
|
-
})
|
|
78
|
+
})
|
|
79
|
+
.populate(DocumentDto.populate.file())
|
|
80
|
+
.populate(DocumentDto.populate.mdFile());
|
|
78
81
|
}
|
|
79
82
|
},
|
|
80
83
|
delete: async (req, res, options) => {
|
package/src/cli/index.js
CHANGED
|
@@ -120,17 +120,105 @@ program
|
|
|
120
120
|
program
|
|
121
121
|
.command('static')
|
|
122
122
|
.option('--page <ssr-component-path>', 'Build custom static pages.')
|
|
123
|
-
.option('--title <title>', 'Sets a custom title for the static page.')
|
|
123
|
+
.option('--title <title>', 'Sets a custom title for the static page (deprecated: use --config-file).')
|
|
124
124
|
.option('--output-path <output-path>', 'Sets the output path for the generated static page.')
|
|
125
125
|
|
|
126
|
+
// Metadata options
|
|
127
|
+
.option('--description <description>', 'Page description for SEO.')
|
|
128
|
+
.option('--keywords <keywords>', 'Comma-separated keywords for SEO.')
|
|
129
|
+
.option('--author <author>', 'Page author.')
|
|
130
|
+
.option('--theme-color <color>', 'Theme color for mobile browsers.')
|
|
131
|
+
.option('--canonical-url <url>', 'Canonical URL for SEO.')
|
|
132
|
+
.option('--thumbnail <url>', 'Open Graph thumbnail image URL.')
|
|
133
|
+
.option('--locale <locale>', 'Page locale (default: en-US).')
|
|
134
|
+
.option('--site-name <name>', 'Site name for Open Graph.')
|
|
135
|
+
|
|
136
|
+
// Script and style options
|
|
137
|
+
.option('--head-scripts <paths>', 'Comma-separated paths to scripts for head section.')
|
|
138
|
+
.option('--body-scripts <paths>', 'Comma-separated paths to scripts for body section.')
|
|
139
|
+
.option('--styles <paths>', 'Comma-separated paths to stylesheets.')
|
|
140
|
+
|
|
141
|
+
// Icon options
|
|
142
|
+
.option('--favicon <path>', 'Favicon path.')
|
|
143
|
+
.option('--apple-touch-icon <path>', 'Apple touch icon path.')
|
|
144
|
+
.option('--manifest <path>', 'Web manifest path.')
|
|
145
|
+
|
|
146
|
+
// Component options
|
|
147
|
+
.option('--head-components <paths>', 'Comma-separated SSR head component paths.')
|
|
148
|
+
.option('--body-components <paths>', 'Comma-separated SSR body component paths.')
|
|
149
|
+
|
|
150
|
+
// Build options
|
|
126
151
|
.option('--deploy-id <deploy-id>', 'Build static assets for a specific deployment ID.')
|
|
127
152
|
.option('--build', 'Triggers the static build process for the specified deployment ID.')
|
|
128
153
|
.option('--build-host <build-host>', 'Sets a custom build host for static documents or assets.')
|
|
129
154
|
.option('--build-path <build-path>', 'Sets a custom build path for static documents or assets.')
|
|
130
155
|
.option('--env <env>', 'Sets the environment for the static build (e.g., "development", "production").')
|
|
156
|
+
.option('--minify', 'Minify HTML output (default: true for production).')
|
|
157
|
+
.option('--no-minify', 'Disable HTML minification.')
|
|
158
|
+
|
|
159
|
+
// Config file options
|
|
160
|
+
.option('--config-file <path>', 'Path to JSON configuration file.')
|
|
161
|
+
.option('--generate-config [path]', 'Generate a template configuration file.')
|
|
162
|
+
|
|
163
|
+
// Other options
|
|
164
|
+
.option('--lang <lang>', 'HTML lang attribute (default: en).')
|
|
165
|
+
.option('--dir <dir>', 'HTML dir attribute (default: ltr).')
|
|
131
166
|
.option('--dev', 'Sets the development cli context')
|
|
132
|
-
|
|
133
|
-
.
|
|
167
|
+
|
|
168
|
+
.description(`Manages static build of page, bundles, and documentation with comprehensive customization options.`)
|
|
169
|
+
.action((options) => {
|
|
170
|
+
// Handle config template generation
|
|
171
|
+
if (options.generateConfig) {
|
|
172
|
+
const configPath = typeof options.generateConfig === 'string' ? options.generateConfig : './static-config.json';
|
|
173
|
+
return UnderpostStatic.API.generateConfigTemplate(configPath);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Parse comma-separated options
|
|
177
|
+
if (options.keywords) {
|
|
178
|
+
options.keywords = options.keywords.split(',').map((k) => k.trim());
|
|
179
|
+
}
|
|
180
|
+
if (options.headScripts) {
|
|
181
|
+
options.scripts = options.scripts || {};
|
|
182
|
+
options.scripts.head = options.headScripts.split(',').map((s) => ({ src: s.trim() }));
|
|
183
|
+
}
|
|
184
|
+
if (options.bodyScripts) {
|
|
185
|
+
options.scripts = options.scripts || {};
|
|
186
|
+
options.scripts.body = options.bodyScripts.split(',').map((s) => ({ src: s.trim() }));
|
|
187
|
+
}
|
|
188
|
+
if (options.styles) {
|
|
189
|
+
options.styles = options.styles.split(',').map((s) => ({ href: s.trim() }));
|
|
190
|
+
}
|
|
191
|
+
if (options.headComponents) {
|
|
192
|
+
options.headComponents = options.headComponents.split(',').map((c) => c.trim());
|
|
193
|
+
}
|
|
194
|
+
if (options.bodyComponents) {
|
|
195
|
+
options.bodyComponents = options.bodyComponents.split(',').map((c) => c.trim());
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Build metadata object from individual options
|
|
199
|
+
options.metadata = {
|
|
200
|
+
...(options.title && { title: options.title }),
|
|
201
|
+
...(options.description && { description: options.description }),
|
|
202
|
+
...(options.keywords && { keywords: options.keywords }),
|
|
203
|
+
...(options.author && { author: options.author }),
|
|
204
|
+
...(options.themeColor && { themeColor: options.themeColor }),
|
|
205
|
+
...(options.canonicalUrl && { canonicalURL: options.canonicalUrl }),
|
|
206
|
+
...(options.thumbnail && { thumbnail: options.thumbnail }),
|
|
207
|
+
...(options.locale && { locale: options.locale }),
|
|
208
|
+
...(options.siteName && { siteName: options.siteName }),
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// Build icons object
|
|
212
|
+
if (options.favicon || options.appleTouchIcon || options.manifest) {
|
|
213
|
+
options.icons = {
|
|
214
|
+
...(options.favicon && { favicon: options.favicon }),
|
|
215
|
+
...(options.appleTouchIcon && { appleTouchIcon: options.appleTouchIcon }),
|
|
216
|
+
...(options.manifest && { manifest: options.manifest }),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return UnderpostStatic.API.callback(options);
|
|
221
|
+
});
|
|
134
222
|
|
|
135
223
|
// 'config' command: Manage Underpost configurations
|
|
136
224
|
program
|
|
@@ -462,7 +550,6 @@ program
|
|
|
462
550
|
'--resource-template-id <resource-template-id >',
|
|
463
551
|
'Specifies a resource template ID for the runner execution.',
|
|
464
552
|
)
|
|
465
|
-
.option('--etcHosts', 'Enables /etc/hosts management for the runner execution.')
|
|
466
553
|
.option('--expose', 'Enables service exposure for the runner execution.')
|
|
467
554
|
.option('--conf-server-path <conf-server-path>', 'Sets a custom configuration server path.')
|
|
468
555
|
.option('--underpost-root <underpost-root>', 'Sets a custom Underpost root path.')
|
package/src/cli/run.js
CHANGED
|
@@ -767,7 +767,7 @@ EOF
|
|
|
767
767
|
* @memberof UnderpostRun
|
|
768
768
|
*/
|
|
769
769
|
'ls-deployments': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
770
|
-
console.table(await UnderpostDeploy.API.get(path, 'deployments'));
|
|
770
|
+
console.table(await UnderpostDeploy.API.get(path, 'deployments', options.namespace));
|
|
771
771
|
},
|
|
772
772
|
/**
|
|
773
773
|
* @method ls-images
|