webspresso 0.0.63 → 0.0.65

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/src/server.js CHANGED
@@ -55,28 +55,118 @@ function getDefaultHelmetConfig(isDev) {
55
55
  };
56
56
  }
57
57
 
58
+ /**
59
+ * Shared CSS for built-in HTML error pages (viewport-safe, fluid type, dark mode)
60
+ */
61
+ function defaultErrorPageStyles() {
62
+ return `
63
+ :root { color-scheme: light dark; }
64
+ * { box-sizing: border-box; }
65
+ body {
66
+ font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
67
+ margin: 0;
68
+ min-height: 100vh;
69
+ min-height: 100dvh;
70
+ display: flex;
71
+ align-items: center;
72
+ justify-content: center;
73
+ padding: max(1rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) max(1rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left));
74
+ background: #f5f5f5;
75
+ color: #1a1a1a;
76
+ -webkit-text-size-adjust: 100%;
77
+ }
78
+ @media (prefers-color-scheme: dark) {
79
+ body { background: #121212; color: #e8e8e8; }
80
+ .card { background: #1e1e1e; border-color: #333; box-shadow: 0 1px 3px rgba(0,0,0,.35); }
81
+ h1 { color: #f5f5f5; }
82
+ .muted { color: #a3a3a3; }
83
+ a { color: #7cc4ff; }
84
+ pre { background: #0d0d0d; color: #e5e5e5; border-color: #333; }
85
+ }
86
+ .container {
87
+ width: 100%;
88
+ max-width: min(100%, 26rem);
89
+ text-align: center;
90
+ }
91
+ .card {
92
+ background: #fff;
93
+ border: 1px solid #e5e5e5;
94
+ border-radius: 12px;
95
+ padding: clamp(1.25rem, 5vw, 2rem);
96
+ box-shadow: 0 1px 3px rgba(0,0,0,.06);
97
+ }
98
+ h1 {
99
+ font-size: clamp(2.5rem, 12vw, 4rem);
100
+ font-weight: 700;
101
+ line-height: 1.05;
102
+ margin: 0 0 0.35rem;
103
+ letter-spacing: -0.02em;
104
+ color: #262626;
105
+ }
106
+ .muted {
107
+ margin: 0 0 1rem;
108
+ line-height: 1.55;
109
+ color: #525252;
110
+ font-size: clamp(0.9375rem, 3.8vw, 1.0625rem);
111
+ }
112
+ a {
113
+ display: inline-flex;
114
+ align-items: center;
115
+ justify-content: center;
116
+ gap: 0.35rem;
117
+ margin-top: 0.25rem;
118
+ color: #0066cc;
119
+ text-decoration: none;
120
+ font-weight: 500;
121
+ font-size: clamp(0.875rem, 3.5vw, 1rem);
122
+ min-height: 44px;
123
+ padding: 0.25rem 0.5rem;
124
+ }
125
+ a:hover { text-decoration: underline; }
126
+ a:focus-visible {
127
+ outline: 2px solid currentColor;
128
+ outline-offset: 3px;
129
+ border-radius: 4px;
130
+ }
131
+ pre {
132
+ margin: 1rem 0 0;
133
+ padding: clamp(0.75rem, 3vw, 1rem);
134
+ border-radius: 8px;
135
+ text-align: left;
136
+ font-size: clamp(0.625rem, 2.75vw, 0.8125rem);
137
+ line-height: 1.45;
138
+ overflow-x: auto;
139
+ max-width: 100%;
140
+ width: 100%;
141
+ white-space: pre-wrap;
142
+ word-break: break-word;
143
+ background: #fff;
144
+ border: 1px solid #e5e5e5;
145
+ -webkit-overflow-scrolling: touch;
146
+ }
147
+ `;
148
+ }
149
+
58
150
  /**
59
151
  * Default 404 page HTML
60
152
  */
61
153
  function default404Html() {
62
154
  return `<!DOCTYPE html>
63
- <html>
155
+ <html lang="en">
64
156
  <head>
157
+ <meta charset="UTF-8" />
158
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
65
159
  <title>404 - Not Found</title>
66
- <style>
67
- body { font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: #f5f5f5; }
68
- .container { text-align: center; }
69
- h1 { font-size: 4rem; margin: 0; color: #333; }
70
- p { color: #666; margin: 1rem 0; }
71
- a { color: #0066cc; text-decoration: none; }
72
- a:hover { text-decoration: underline; }
73
- </style>
160
+ <style>${defaultErrorPageStyles()}
161
+ </style>
74
162
  </head>
75
163
  <body>
76
164
  <div class="container">
77
- <h1>404</h1>
78
- <p>Page not found</p>
79
- <a href="/">← Back to Home</a>
165
+ <div class="card">
166
+ <h1>404</h1>
167
+ <p class="muted">Page not found</p>
168
+ <a href="/">← Back to Home</a>
169
+ </div>
80
170
  </div>
81
171
  </body>
82
172
  </html>`;
@@ -86,26 +176,30 @@ function default404Html() {
86
176
  * Default 500 page HTML
87
177
  */
88
178
  function default500Html(err, isDev) {
179
+ const detail =
180
+ isDev && err
181
+ ? `<pre>${String(err.stack || err.message)
182
+ .replace(/&/g, '&amp;')
183
+ .replace(/</g, '&lt;')
184
+ .replace(/>/g, '&gt;')}</pre>`
185
+ : '';
89
186
  return `<!DOCTYPE html>
90
- <html>
187
+ <html lang="en">
91
188
  <head>
189
+ <meta charset="UTF-8" />
190
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
92
191
  <title>500 - Server Error</title>
93
- <style>
94
- body { font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: #f5f5f5; }
95
- .container { text-align: center; }
96
- h1 { font-size: 4rem; margin: 0; color: #333; }
97
- p { color: #666; margin: 1rem 0; }
98
- pre { background: #fff; padding: 1rem; border-radius: 4px; text-align: left; overflow: auto; max-width: 600px; }
99
- a { color: #0066cc; text-decoration: none; }
100
- a:hover { text-decoration: underline; }
192
+ <style>${defaultErrorPageStyles()}
101
193
  </style>
102
194
  </head>
103
195
  <body>
104
196
  <div class="container">
105
- <h1>500</h1>
106
- <p>Internal Server Error</p>
107
- ${isDev && err ? `<pre>${err.stack || err.message}</pre>` : ''}
108
- <a href="/">← Back to Home</a>
197
+ <div class="card">
198
+ <h1>500</h1>
199
+ <p class="muted">Internal Server Error</p>
200
+ ${detail}
201
+ <a href="/">← Back to Home</a>
202
+ </div>
109
203
  </div>
110
204
  </body>
111
205
  </html>`;
@@ -116,23 +210,21 @@ function default500Html(err, isDev) {
116
210
  */
117
211
  function default503Html() {
118
212
  return `<!DOCTYPE html>
119
- <html>
213
+ <html lang="en">
120
214
  <head>
215
+ <meta charset="UTF-8" />
216
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
121
217
  <title>503 - Service Unavailable</title>
122
- <style>
123
- body { font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: #f5f5f5; }
124
- .container { text-align: center; }
125
- h1 { font-size: 4rem; margin: 0; color: #333; }
126
- p { color: #666; margin: 1rem 0; }
127
- a { color: #0066cc; text-decoration: none; }
128
- a:hover { text-decoration: underline; }
218
+ <style>${defaultErrorPageStyles()}
129
219
  </style>
130
220
  </head>
131
221
  <body>
132
222
  <div class="container">
133
- <h1>503</h1>
134
- <p>Request timed out. Please try again.</p>
135
- <a href="/">← Back to Home</a>
223
+ <div class="card">
224
+ <h1>503</h1>
225
+ <p class="muted">Request timed out. Please try again.</p>
226
+ <a href="/">← Back to Home</a>
227
+ </div>
136
228
  </div>
137
229
  </body>
138
230
  </html>`;