@teamvelix/velix 5.2.9 → 5.3.0
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/dist/build/index.js +2 -2
- package/dist/{chunk-YZDIHMDS.js → chunk-H27Z2PL5.js} +3 -3
- package/dist/{chunk-YZDIHMDS.js.map → chunk-H27Z2PL5.js.map} +1 -1
- package/dist/{chunk-RU23OKU5.js → chunk-IH5DV2WC.js} +3 -3
- package/dist/{chunk-RU23OKU5.js.map → chunk-IH5DV2WC.js.map} +1 -1
- package/dist/{chunk-HMCBOHTD.js → chunk-OKEPYKAP.js} +576 -303
- package/dist/chunk-OKEPYKAP.js.map +1 -0
- package/dist/config.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/runtime/start-build.js +1 -1
- package/dist/runtime/start-build.js.map +1 -1
- package/dist/runtime/start-dev.js +574 -303
- package/dist/runtime/start-dev.js.map +1 -1
- package/dist/runtime/start-prod.js +574 -303
- package/dist/runtime/start-prod.js.map +1 -1
- package/dist/server/index.js +2 -2
- package/package.json +3 -3
- package/dist/chunk-HMCBOHTD.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { definePlugin, PluginHooks, logger_default, loadPlugins, pluginManager, buildRouteTree, matchRoute, VERSION } from './chunk-
|
|
1
|
+
import { definePlugin, PluginHooks, logger_default, loadPlugins, pluginManager, buildRouteTree, matchRoute, VERSION } from './chunk-IH5DV2WC.js';
|
|
2
2
|
import { loadConfig, resolvePaths } from './chunk-F24Q2MX3.js';
|
|
3
3
|
import { getRegisteredIslands, generateAdvancedHydrationScript } from './chunk-JI2HJFUT.js';
|
|
4
4
|
import { __dirname as __dirname$1, __require } from './chunk-BQ4HFLRL.js';
|
|
@@ -861,73 +861,76 @@ function generateDevToolsHtml(isDev, ctx = {}) {
|
|
|
861
861
|
return `
|
|
862
862
|
<style>
|
|
863
863
|
/* \u2500\u2500 Velix DevTools v5.1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
864
|
-
#__vdt-btn{position:fixed;bottom:16px;left:16px;z-index:9999;width:40px;height:40px;border-radius:
|
|
865
|
-
#__vdt-btn:hover{transform:scale(1.
|
|
866
|
-
#__vdt-
|
|
867
|
-
#__vdt
|
|
864
|
+
#__vdt-btn{position:fixed;bottom:16px;left:16px;z-index:9999;min-width:40px;height:40px;border-radius:20px;background:#0B1120;border:1px solid rgba(255,255,255,0.1);display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 16px rgba(0,0,0,.5);transition:all .3s cubic-bezier(0.4, 0, 0.2, 1);outline:none;padding:0 12px;gap:8px;color:#fff;overflow:hidden;}
|
|
865
|
+
#__vdt-btn:hover{transform:scale(1.05);background:#0F172A;border-color:rgba(255,255,255,0.2);}
|
|
866
|
+
#__vdt-status-text{font-size:12px;font-weight:600;white-space:nowrap;opacity:0;max-width:0;transition:all .3s cubic-bezier(0.4, 0, 0.2, 1);font-family:ui-sans-serif,system-ui,sans-serif;letter-spacing:0.3px;}
|
|
867
|
+
#__vdt-btn.vdt-compiling #__vdt-status-text, #__vdt-btn.vdt-navigating #__vdt-status-text{opacity:1;max-width:120px;}
|
|
868
|
+
|
|
869
|
+
#__vdt-dot{display:none;}
|
|
870
|
+
#__vdt{display:none;position:fixed;bottom:68px;left:16px;width:340px;background:#0B1120;color:#f3f4f6;border-radius:14px;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;font-size:13px;box-shadow:0 24px 60px rgba(0,0,0,.6);z-index:10000;border:1px solid #0F172A;overflow:hidden;}
|
|
868
871
|
/* header */
|
|
869
|
-
.__vdt-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid #
|
|
872
|
+
.__vdt-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid #0F172A;}
|
|
870
873
|
.__vdt-brand{display:flex;align-items:center;gap:8px;font-weight:700;font-size:14px;color:#f9fafb;}
|
|
871
|
-
.__vdt-badge{font-size:11px;font-weight:600;background:#
|
|
874
|
+
.__vdt-badge{font-size:11px;font-weight:600;background:#0F172A;color:#9ca3af;border-radius:5px;padding:2px 7px;letter-spacing:.3px;}
|
|
872
875
|
.__vdt-close{background:none;border:none;color:#6b7280;cursor:pointer;font-size:20px;line-height:1;padding:0;transition:color .15s;}
|
|
873
876
|
.__vdt-close:hover{color:#f9fafb;}
|
|
874
877
|
/* tabs */
|
|
875
|
-
.__vdt-tabs{display:flex;border-bottom:1px solid #
|
|
878
|
+
.__vdt-tabs{display:flex;border-bottom:1px solid #0F172A;}
|
|
876
879
|
.__vdt-tab{flex:1;padding:10px 0;background:none;border:none;color:#6b7280;font-size:12px;font-weight:500;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:5px;border-bottom:2px solid transparent;transition:color .15s,border-color .15s;font-family:inherit;letter-spacing:.1px;}
|
|
877
880
|
.__vdt-tab:hover{color:#d1d5db;}
|
|
878
|
-
.__vdt-tab.active{color:#
|
|
881
|
+
.__vdt-tab.active{color:#2563EB;border-bottom-color:#2563EB;}
|
|
879
882
|
/* body */
|
|
880
883
|
.__vdt-body{padding:14px 16px;min-height:200px;}
|
|
881
884
|
.__vdt-section{margin-bottom:14px;}
|
|
882
885
|
.__vdt-label{font-size:11px;color:#6b7280;text-transform:uppercase;letter-spacing:.6px;margin-bottom:8px;}
|
|
883
|
-
.__vdt-box{background:#
|
|
884
|
-
.__vdt-row{display:flex;align-items:center;justify-content:space-between;padding:9px 13px;background:#
|
|
886
|
+
.__vdt-box{background:#0F172A;border-radius:8px;padding:10px 13px;font-size:13px;color:#e5e7eb;font-family:ui-monospace,'Cascadia Code','Fira Code',monospace;border:1px solid #162032;}
|
|
887
|
+
.__vdt-row{display:flex;align-items:center;justify-content:space-between;padding:9px 13px;background:#0F172A;border-radius:8px;margin-bottom:6px;border:1px solid #162032;}
|
|
885
888
|
.__vdt-row-left{display:flex;align-items:center;gap:8px;color:#d1d5db;}
|
|
886
|
-
.__vdt-row-right{font-family:ui-monospace,'Cascadia Code',monospace;color:#
|
|
889
|
+
.__vdt-row-right{font-family:ui-monospace,'Cascadia Code',monospace;color:#2563EB;font-size:12px;font-weight:500;}
|
|
887
890
|
.__vdt-pill{font-size:10px;font-weight:600;padding:2px 7px;border-radius:4px;letter-spacing:.2px;}
|
|
888
|
-
.__vdt-pill-green{background:#
|
|
891
|
+
.__vdt-pill-green{background:#162032;color:#38BDF8;border:1px solid #2563EB;}
|
|
889
892
|
.__vdt-pill-blue{background:#0c1a3a;color:#60a5fa;border:1px solid #1e3a8a;}
|
|
890
|
-
.__vdt-render{display:flex;align-items:center;gap:6px;padding:8px 13px;background:#
|
|
893
|
+
.__vdt-render{display:flex;align-items:center;gap:6px;padding:8px 13px;background:#0F172A;border-radius:8px;border:1px solid #162032;color:#9ca3af;font-size:12px;}
|
|
891
894
|
.__vdt-render svg{color:#6b7280;}
|
|
892
895
|
/* vitals */
|
|
893
|
-
.__vdt-vital{display:flex;align-items:center;justify-content:space-between;padding:9px 13px;background:#
|
|
896
|
+
.__vdt-vital{display:flex;align-items:center;justify-content:space-between;padding:9px 13px;background:#0F172A;border-radius:8px;margin-bottom:6px;border:1px solid #162032;}
|
|
894
897
|
.__vdt-vital-left{display:flex;align-items:center;gap:8px;}
|
|
895
|
-
.__vdt-dot-good{width:8px;height:8px;border-radius:50%;background:#
|
|
898
|
+
.__vdt-dot-good{width:8px;height:8px;border-radius:50%;background:#2563EB;flex-shrink:0;}
|
|
896
899
|
.__vdt-dot-warn{width:8px;height:8px;border-radius:50%;background:#f59e0b;flex-shrink:0;}
|
|
897
900
|
.__vdt-dot-bad{width:8px;height:8px;border-radius:50%;background:#ef4444;flex-shrink:0;}
|
|
898
901
|
.__vdt-vital-name{color:#d1d5db;font-weight:500;}
|
|
899
|
-
.__vdt-vital-val{font-family:ui-monospace,'Cascadia Code',monospace;color:#
|
|
900
|
-
.__vdt-build{display:flex;align-items:center;justify-content:space-between;padding:9px 13px;color:#9ca3af;font-size:12px;border-top:1px solid #
|
|
902
|
+
.__vdt-vital-val{font-family:ui-monospace,'Cascadia Code',monospace;color:#2563EB;font-size:12px;font-weight:600;}
|
|
903
|
+
.__vdt-build{display:flex;align-items:center;justify-content:space-between;padding:9px 13px;color:#9ca3af;font-size:12px;border-top:1px solid #162032;margin-top:8px;padding-top:12px;}
|
|
901
904
|
/* info rows */
|
|
902
|
-
.__vdt-info-row{display:flex;align-items:center;justify-content:space-between;padding:9px 13px;background:#
|
|
905
|
+
.__vdt-info-row{display:flex;align-items:center;justify-content:space-between;padding:9px 13px;background:#0F172A;border-radius:8px;margin-bottom:6px;border:1px solid #162032;}
|
|
903
906
|
.__vdt-info-left{display:flex;align-items:center;gap:8px;color:#d1d5db;}
|
|
904
907
|
.__vdt-info-val{font-family:ui-monospace,'Cascadia Code',monospace;color:#9ca3af;font-size:12px;}
|
|
905
|
-
.__vdt-dev-badge{display:flex;align-items:center;gap:8px;padding:10px 13px;background:#
|
|
908
|
+
.__vdt-dev-badge{display:flex;align-items:center;gap:8px;padding:10px 13px;background:#162032;border:1px solid #2563EB;border-radius:8px;color:#38BDF8;font-size:12px;font-weight:500;margin-top:10px;}
|
|
906
909
|
/* footer */
|
|
907
|
-
.__vdt-footer{padding:10px 16px;border-top:1px solid #
|
|
910
|
+
.__vdt-footer{padding:10px 16px;border-top:1px solid #0F172A;display:flex;align-items:center;justify-content:space-between;}
|
|
908
911
|
.__vdt-host{color:#6b7280;font-size:11px;font-family:ui-monospace,'Cascadia Code',monospace;}
|
|
909
|
-
.__vdt-conn{display:flex;align-items:center;gap:5px;font-size:11px;color:#
|
|
910
|
-
.__vdt-conn-dot{width:6px;height:6px;border-radius:50%;background:#
|
|
912
|
+
.__vdt-conn{display:flex;align-items:center;gap:5px;font-size:11px;color:#2563EB;}
|
|
913
|
+
.__vdt-conn-dot{width:6px;height:6px;border-radius:50%;background:#2563EB;}
|
|
911
914
|
|
|
912
915
|
/* \u2500\u2500 Widget state colors \u2500\u2500 */
|
|
913
916
|
.vdt-idle{border-color:#22D3EE !important;}
|
|
914
|
-
.vdt-compiling{border-color:#
|
|
917
|
+
.vdt-compiling{border-color:#38BDF8 !important;}
|
|
915
918
|
.vdt-rendering{border-color:#fb923c !important;}
|
|
916
919
|
.vdt-navigating{border-color:#60a5fa !important;}
|
|
917
920
|
.vdt-error{border-color:#f87171 !important;}
|
|
918
921
|
#__vdt-dot.idle{background:#22D3EE;}
|
|
919
|
-
#__vdt-dot.compiling{background:#
|
|
922
|
+
#__vdt-dot.compiling{background:#38BDF8;}
|
|
920
923
|
#__vdt-dot.rendering{background:#fb923c;}
|
|
921
924
|
#__vdt-dot.navigating{background:#60a5fa;}
|
|
922
925
|
#__vdt-dot.error{background:#f87171;}
|
|
923
926
|
@keyframes __vdt-pulse{0%,100%{opacity:1;}50%{opacity:.4;}}
|
|
924
|
-
.vdt-compiling
|
|
927
|
+
.vdt-compiling svg, .vdt-navigating svg{animation:__vdt-pulse .8s alternate infinite;}
|
|
925
928
|
</style>
|
|
926
929
|
|
|
927
930
|
<!-- \u2500\u2500 Floating button \u2500\u2500 -->
|
|
928
931
|
<button id="__vdt-btn" class="vdt-idle" onclick="__vdtOpen()" title="Velix DevTools (${version})">
|
|
929
932
|
${ICON_LOGO}
|
|
930
|
-
<
|
|
933
|
+
<span id="__vdt-status-text"></span>
|
|
931
934
|
</button>
|
|
932
935
|
|
|
933
936
|
<!-- \u2500\u2500 Panel \u2500\u2500 -->
|
|
@@ -1078,7 +1081,7 @@ function generateDevToolsHtml(isDev, ctx = {}) {
|
|
|
1078
1081
|
dot.className = v <= threshGood ? '__vdt-dot-good' : v <= threshOk ? '__vdt-dot-warn' : '__vdt-dot-bad';
|
|
1079
1082
|
}
|
|
1080
1083
|
if(el && typeof v === 'number'){
|
|
1081
|
-
el.style.color = v <= threshGood ? '#
|
|
1084
|
+
el.style.color = v <= threshGood ? '#2563EB' : v <= threshOk ? '#f59e0b' : '#ef4444';
|
|
1082
1085
|
}
|
|
1083
1086
|
}
|
|
1084
1087
|
|
|
@@ -1128,13 +1131,18 @@ function generateDevToolsHtml(isDev, ctx = {}) {
|
|
|
1128
1131
|
|
|
1129
1132
|
function setStatus(s){
|
|
1130
1133
|
if(btn){ btn.className = 'vdt-' + s; }
|
|
1131
|
-
|
|
1134
|
+
var text = document.getElementById('__vdt-status-text');
|
|
1135
|
+
if(text) {
|
|
1136
|
+
if(s === 'compiling') text.textContent = 'Compiling...';
|
|
1137
|
+
else if(s === 'navigating') text.textContent = 'Loading...';
|
|
1138
|
+
else text.textContent = '';
|
|
1139
|
+
}
|
|
1132
1140
|
}
|
|
1133
1141
|
|
|
1134
1142
|
function setConn(ok){
|
|
1135
|
-
if(connDot) connDot.style.background = ok ? '#
|
|
1143
|
+
if(connDot) connDot.style.background = ok ? '#2563EB' : '#ef4444';
|
|
1136
1144
|
if(connText) connText.textContent = ok ? 'connected' : 'disconnected';
|
|
1137
|
-
if(connText) connText.style.color = ok ? '#
|
|
1145
|
+
if(connText) connText.style.color = ok ? '#2563EB' : '#ef4444';
|
|
1138
1146
|
}
|
|
1139
1147
|
|
|
1140
1148
|
var ws = new WebSocket('ws://' + window.location.host + '/__velix_hmr');
|
|
@@ -1188,88 +1196,203 @@ function generate404Page(pathname = "/") {
|
|
|
1188
1196
|
<head>
|
|
1189
1197
|
<meta charset="UTF-8">
|
|
1190
1198
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1191
|
-
<title>404
|
|
1199
|
+
<title>404 \u2014 Page Not Found | Velix v${VERSION}</title>
|
|
1192
1200
|
<link rel="icon" href="/favicon.webp">
|
|
1201
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
1202
|
+
<link href="https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
1193
1203
|
<style>
|
|
1194
1204
|
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
1205
|
+
|
|
1206
|
+
@keyframes fadeUp {
|
|
1207
|
+
from { opacity: 0; transform: translateY(16px); }
|
|
1208
|
+
to { opacity: 1; transform: translateY(0); }
|
|
1209
|
+
}
|
|
1210
|
+
@keyframes pulse {
|
|
1211
|
+
0%, 100% { opacity: 1; }
|
|
1212
|
+
50% { opacity: 0.4; }
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1195
1215
|
body {
|
|
1196
|
-
background: #
|
|
1197
|
-
|
|
1198
|
-
|
|
1216
|
+
background-color: #0B1120;
|
|
1217
|
+
background-image:
|
|
1218
|
+
linear-gradient(to right, rgba(255, 255, 255, 0.05) 1px, transparent 1px),
|
|
1219
|
+
linear-gradient(to bottom, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
|
|
1220
|
+
background-size: 60px 60px;
|
|
1221
|
+
color: #F8FAFC;
|
|
1222
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
1199
1223
|
display: flex;
|
|
1224
|
+
flex-direction: column;
|
|
1200
1225
|
align-items: center;
|
|
1201
1226
|
justify-content: center;
|
|
1202
1227
|
min-height: 100vh;
|
|
1228
|
+
padding: 2rem;
|
|
1203
1229
|
-webkit-font-smoothing: antialiased;
|
|
1204
1230
|
}
|
|
1205
|
-
|
|
1231
|
+
|
|
1232
|
+
/* radial vignette over the grid */
|
|
1233
|
+
body::before {
|
|
1234
|
+
content: '';
|
|
1235
|
+
position: fixed;
|
|
1236
|
+
inset: 0;
|
|
1237
|
+
background: radial-gradient(ellipse 80% 60% at 50% 50%, transparent 0%, #0B1120 80%);
|
|
1238
|
+
pointer-events: none;
|
|
1239
|
+
z-index: 0;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
.card {
|
|
1243
|
+
position: relative;
|
|
1244
|
+
z-index: 1;
|
|
1206
1245
|
display: flex;
|
|
1246
|
+
flex-direction: column;
|
|
1207
1247
|
align-items: center;
|
|
1208
|
-
|
|
1209
|
-
|
|
1248
|
+
text-align: center;
|
|
1249
|
+
max-width: 480px;
|
|
1250
|
+
animation: fadeUp 0.25s ease forwards;
|
|
1210
1251
|
}
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1252
|
+
|
|
1253
|
+
/* \u2500\u2500 glowing 404 number \u2500\u2500 */
|
|
1254
|
+
.status-number {
|
|
1255
|
+
font-family: 'DM Mono', monospace;
|
|
1256
|
+
font-size: clamp(80px, 18vw, 140px);
|
|
1257
|
+
font-weight: 500;
|
|
1214
1258
|
line-height: 1;
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
}
|
|
1219
|
-
.body h1 {
|
|
1220
|
-
font-size: 18px;
|
|
1221
|
-
font-weight: 600;
|
|
1222
|
-
color: #ededed;
|
|
1259
|
+
letter-spacing: -0.04em;
|
|
1260
|
+
color: #F8FAFC;
|
|
1261
|
+
position: relative;
|
|
1223
1262
|
margin-bottom: 8px;
|
|
1224
1263
|
}
|
|
1225
|
-
.
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1264
|
+
.status-number::after {
|
|
1265
|
+
content: attr(data-value);
|
|
1266
|
+
position: absolute;
|
|
1267
|
+
inset: 0;
|
|
1268
|
+
color: #2563EB;
|
|
1269
|
+
opacity: 0.12;
|
|
1270
|
+
filter: blur(24px);
|
|
1271
|
+
pointer-events: none;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
/* \u2500\u2500 accent line \u2500\u2500 */
|
|
1275
|
+
.accent-line {
|
|
1276
|
+
width: 40px;
|
|
1277
|
+
height: 3px;
|
|
1278
|
+
background: #2563EB;
|
|
1279
|
+
border-radius: 9999px;
|
|
1280
|
+
margin-bottom: 24px;
|
|
1229
1281
|
}
|
|
1230
|
-
|
|
1231
|
-
|
|
1282
|
+
|
|
1283
|
+
/* \u2500\u2500 heading \u2500\u2500 */
|
|
1284
|
+
h1 {
|
|
1285
|
+
font-size: 22px;
|
|
1286
|
+
font-weight: 700;
|
|
1287
|
+
color: #fff;
|
|
1288
|
+
margin-bottom: 10px;
|
|
1289
|
+
letter-spacing: -0.01em;
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
/* \u2500\u2500 route badge \u2500\u2500 */
|
|
1293
|
+
.route-badge {
|
|
1294
|
+
display: inline-flex;
|
|
1295
|
+
align-items: center;
|
|
1296
|
+
gap: 8px;
|
|
1297
|
+
font-family: 'DM Mono', monospace;
|
|
1232
1298
|
font-size: 13px;
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
border
|
|
1236
|
-
|
|
1299
|
+
color: #94A3B8;
|
|
1300
|
+
background: #0F172A;
|
|
1301
|
+
border: 1px solid #1E293B;
|
|
1302
|
+
padding: 5px 14px;
|
|
1303
|
+
border-radius: 9999px;
|
|
1304
|
+
margin-bottom: 32px;
|
|
1305
|
+
}
|
|
1306
|
+
.route-badge .dot {
|
|
1307
|
+
width: 6px;
|
|
1308
|
+
height: 6px;
|
|
1309
|
+
border-radius: 50%;
|
|
1310
|
+
background: #ff6b6b;
|
|
1311
|
+
animation: pulse 1.8s ease-in-out infinite;
|
|
1312
|
+
flex-shrink: 0;
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
/* \u2500\u2500 actions \u2500\u2500 */
|
|
1316
|
+
.actions {
|
|
1317
|
+
display: flex;
|
|
1318
|
+
gap: 12px;
|
|
1237
1319
|
}
|
|
1238
|
-
.actions { display: flex; gap: 10px; }
|
|
1239
1320
|
.btn {
|
|
1240
|
-
display: inline-
|
|
1241
|
-
|
|
1242
|
-
|
|
1321
|
+
display: inline-flex;
|
|
1322
|
+
align-items: center;
|
|
1323
|
+
gap: 6px;
|
|
1324
|
+
padding: 10px 22px;
|
|
1325
|
+
border-radius: 10px;
|
|
1243
1326
|
font-size: 14px;
|
|
1244
|
-
font-weight:
|
|
1327
|
+
font-weight: 600;
|
|
1245
1328
|
text-decoration: none;
|
|
1246
|
-
transition: all .15s;
|
|
1247
|
-
border: 1px solid transparent;
|
|
1329
|
+
transition: all 0.15s ease;
|
|
1248
1330
|
}
|
|
1249
1331
|
.btn-primary {
|
|
1250
|
-
background: #
|
|
1251
|
-
color: #
|
|
1332
|
+
background: #2563EB;
|
|
1333
|
+
color: #0B1120;
|
|
1334
|
+
border: 1px solid #2563EB;
|
|
1335
|
+
}
|
|
1336
|
+
.btn-primary:hover {
|
|
1337
|
+
background: #3B82F6;
|
|
1338
|
+
transform: translateY(-1px);
|
|
1339
|
+
box-shadow: 0 0 20px rgba(37, 99, 235, 0.35);
|
|
1252
1340
|
}
|
|
1253
|
-
.btn-primary:hover { background: #e5e5e5; }
|
|
1254
1341
|
.btn-secondary {
|
|
1255
|
-
background:
|
|
1256
|
-
color: #
|
|
1257
|
-
border
|
|
1342
|
+
background: transparent;
|
|
1343
|
+
color: #F8FAFC;
|
|
1344
|
+
border: 1px solid #1E293B;
|
|
1345
|
+
}
|
|
1346
|
+
.btn-secondary:hover {
|
|
1347
|
+
background: #0F172A;
|
|
1348
|
+
border-color: #334155;
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
/* \u2500\u2500 footer branding \u2500\u2500 */
|
|
1352
|
+
.brand {
|
|
1353
|
+
position: fixed;
|
|
1354
|
+
bottom: 28px;
|
|
1355
|
+
left: 50%;
|
|
1356
|
+
transform: translateX(-50%);
|
|
1357
|
+
display: flex;
|
|
1358
|
+
align-items: center;
|
|
1359
|
+
gap: 8px;
|
|
1360
|
+
font-size: 12px;
|
|
1361
|
+
color: #475569;
|
|
1362
|
+
font-family: 'DM Mono', monospace;
|
|
1363
|
+
}
|
|
1364
|
+
.brand-dot {
|
|
1365
|
+
width: 6px;
|
|
1366
|
+
height: 6px;
|
|
1367
|
+
border-radius: 50%;
|
|
1368
|
+
background: #2563EB;
|
|
1258
1369
|
}
|
|
1259
|
-
.btn-secondary:hover { background: rgba(255,255,255,0.1); }
|
|
1260
1370
|
</style>
|
|
1261
1371
|
</head>
|
|
1262
1372
|
<body>
|
|
1263
|
-
<div class="
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1373
|
+
<div class="card">
|
|
1374
|
+
<div class="status-number" data-value="404">404</div>
|
|
1375
|
+
<div class="accent-line"></div>
|
|
1376
|
+
<h1>Page not found</h1>
|
|
1377
|
+
<div class="route-badge">
|
|
1378
|
+
<span class="dot"></span>
|
|
1379
|
+
<span>${escapeHtml2(pathname)}</span>
|
|
1380
|
+
</div>
|
|
1381
|
+
<div class="actions">
|
|
1382
|
+
<a href="/" class="btn btn-primary">
|
|
1383
|
+
<svg width="14" height="14" fill="none" viewBox="0 0 24 24"><path d="M3 12L12 3l9 9M5 10v9a1 1 0 001 1h4v-5h4v5h4a1 1 0 001-1v-9" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
1384
|
+
Home
|
|
1385
|
+
</a>
|
|
1386
|
+
<a href="javascript:history.back()" class="btn btn-secondary">
|
|
1387
|
+
<svg width="14" height="14" fill="none" viewBox="0 0 24 24"><path d="M19 12H5M5 12l7-7M5 12l7 7" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
1388
|
+
Go back
|
|
1389
|
+
</a>
|
|
1390
|
+
</div>
|
|
1391
|
+
</div>
|
|
1392
|
+
|
|
1393
|
+
<div class="brand">
|
|
1394
|
+
<span class="brand-dot"></span>
|
|
1395
|
+
Velix v${VERSION}
|
|
1273
1396
|
</div>
|
|
1274
1397
|
</body>
|
|
1275
1398
|
</html>`;
|
|
@@ -1300,14 +1423,23 @@ function generate500Page(options) {
|
|
|
1300
1423
|
const src = fs4.readFileSync(errorFile, "utf-8").split("\n");
|
|
1301
1424
|
const start = Math.max(0, errorLine - 4);
|
|
1302
1425
|
const end = Math.min(src.length, errorLine + 3);
|
|
1426
|
+
const syntaxHighlight = (code) => {
|
|
1427
|
+
let hl = code;
|
|
1428
|
+
hl = hl.replace(/\\b(let|const|function|return|import|export|if|else|for|while|await|async|class|var)\\b/g, '<span style="color:#c084fc">$1</span>');
|
|
1429
|
+
hl = hl.replace(/(".*?"|'.*?'|`.*?`)/g, '<span style="color:#86efac">$1</span>');
|
|
1430
|
+
hl = hl.replace(/(\\/\\/.*)$/g, '<span style="color:#94A3B8">$1</span>');
|
|
1431
|
+
hl = hl.replace(/\\b(\\d+)\\b/g, '<span style="color:#f59e0b">$1</span>');
|
|
1432
|
+
return hl;
|
|
1433
|
+
};
|
|
1303
1434
|
sourceSnippet = src.slice(start, end).map((l, i) => {
|
|
1304
1435
|
const num = start + i + 1;
|
|
1305
1436
|
const isErr = num === errorLine;
|
|
1306
1437
|
const numStr = String(num).padStart(3, " ");
|
|
1438
|
+
const highlightedLine = syntaxHighlight(escapeHtml2(l));
|
|
1307
1439
|
if (isErr) {
|
|
1308
|
-
return `<div class="src-line src-err"><span class="ln">${numStr}</span>${
|
|
1440
|
+
return `<div class="src-line src-err"><span class="ln">${numStr}</span><span class="active-arrow">\u25B6</span><span class="code-content">${highlightedLine}</span></div>`;
|
|
1309
1441
|
}
|
|
1310
|
-
return `<div class="src-line"><span class="ln">${numStr}</span>${
|
|
1442
|
+
return `<div class="src-line"><span class="ln">${numStr}</span><span class="active-arrow"> </span><span class="code-content">${highlightedLine}</span></div>`;
|
|
1311
1443
|
}).join("");
|
|
1312
1444
|
}
|
|
1313
1445
|
} catch (_) {
|
|
@@ -1315,6 +1447,13 @@ function generate500Page(options) {
|
|
|
1315
1447
|
}
|
|
1316
1448
|
}
|
|
1317
1449
|
}
|
|
1450
|
+
const formatErrorMessage = (msg) => {
|
|
1451
|
+
let formatted = escapeHtml2(msg);
|
|
1452
|
+
const pathSpan = `<span style="color:#2563EB;cursor:pointer;" onclick="console.log('open in editor')">`;
|
|
1453
|
+
formatted = formatted.replace(/([A-Z]:\\[^\s<]+|\/(?:Users|home|var|srv)\/[^\s<]+)/g, pathSpan + "$1</span>");
|
|
1454
|
+
formatted = formatted.replace(/(ERROR:)/g, '<strong style="color:#ff6b6b">$1</strong>');
|
|
1455
|
+
return formatted;
|
|
1456
|
+
};
|
|
1318
1457
|
const userFrames = frames.filter((f) => f.file && !f.file.includes("node_modules"));
|
|
1319
1458
|
const ignoredFrames = frames.filter((f) => !f.file || f.file.includes("node_modules"));
|
|
1320
1459
|
const shortFile = errorFile.replace(/\\/g, "/").replace(/.*\/(?=app\/|server\/|src\/|pages\/)/, "");
|
|
@@ -1329,7 +1468,7 @@ function generate500Page(options) {
|
|
|
1329
1468
|
<style>
|
|
1330
1469
|
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
1331
1470
|
body {
|
|
1332
|
-
background: #
|
|
1471
|
+
background: #0B1120;
|
|
1333
1472
|
color: #ededed;
|
|
1334
1473
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
|
1335
1474
|
display: flex; align-items: center; justify-content: center;
|
|
@@ -1364,327 +1503,459 @@ function generate500Page(options) {
|
|
|
1364
1503
|
<title>Error | Velix v${VERSION}</title>
|
|
1365
1504
|
<link rel="icon" href="/favicon.webp">
|
|
1366
1505
|
<style>
|
|
1506
|
+
@import url('https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap');
|
|
1507
|
+
|
|
1367
1508
|
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
1368
1509
|
|
|
1510
|
+
@keyframes fadeIn {
|
|
1511
|
+
from { opacity: 0; transform: translateY(10px); }
|
|
1512
|
+
to { opacity: 1; transform: translateY(0); }
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1369
1515
|
body {
|
|
1370
|
-
background:
|
|
1371
|
-
|
|
1372
|
-
|
|
1516
|
+
background-color: #0B1120;
|
|
1517
|
+
background-image:
|
|
1518
|
+
linear-gradient(to right, rgba(255, 255, 255, 0.03) 1px, transparent 1px),
|
|
1519
|
+
linear-gradient(to bottom, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
|
|
1520
|
+
background-size: 60px 60px;
|
|
1521
|
+
color: #F8FAFC;
|
|
1522
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
|
1373
1523
|
min-height: 100vh;
|
|
1374
1524
|
display: flex;
|
|
1375
|
-
align-items:
|
|
1525
|
+
align-items: flex-start;
|
|
1376
1526
|
justify-content: center;
|
|
1377
|
-
padding:
|
|
1527
|
+
padding: 2rem;
|
|
1378
1528
|
-webkit-font-smoothing: antialiased;
|
|
1379
1529
|
}
|
|
1380
1530
|
|
|
1381
|
-
/*
|
|
1382
|
-
.
|
|
1531
|
+
/* Radial mask for the grid background */
|
|
1532
|
+
.bg-mask {
|
|
1533
|
+
position: fixed;
|
|
1534
|
+
top: 0; left: 0; right: 0; bottom: 0;
|
|
1535
|
+
background: radial-gradient(circle at center, transparent 0%, #0B1120 80%);
|
|
1536
|
+
z-index: -1;
|
|
1537
|
+
pointer-events: none;
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
/* \u2500\u2500 Main Container \u2500\u2500 */
|
|
1541
|
+
.container {
|
|
1383
1542
|
width: 100%;
|
|
1384
|
-
max-width:
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
border-radius: 12px;
|
|
1388
|
-
box-shadow: 0 24px 64px rgba(0,0,0,0.6);
|
|
1389
|
-
overflow: hidden;
|
|
1543
|
+
max-width: 780px;
|
|
1544
|
+
margin-top: 4vh;
|
|
1545
|
+
animation: fadeIn 0.2s ease forwards;
|
|
1390
1546
|
display: flex;
|
|
1391
1547
|
flex-direction: column;
|
|
1392
|
-
|
|
1548
|
+
gap: 24px;
|
|
1393
1549
|
}
|
|
1394
1550
|
|
|
1395
1551
|
/* \u2500\u2500 Header Bar \u2500\u2500 */
|
|
1396
1552
|
.header {
|
|
1553
|
+
position: relative;
|
|
1554
|
+
background: transparent;
|
|
1397
1555
|
display: flex;
|
|
1398
1556
|
align-items: center;
|
|
1399
1557
|
justify-content: space-between;
|
|
1400
|
-
padding: 12px
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1558
|
+
padding-top: 12px;
|
|
1559
|
+
}
|
|
1560
|
+
.header::before {
|
|
1561
|
+
content: '';
|
|
1562
|
+
position: absolute;
|
|
1563
|
+
top: -12px; left: 0; right: 0;
|
|
1564
|
+
height: 4px;
|
|
1565
|
+
background: #ff6b6b;
|
|
1566
|
+
border-radius: 4px;
|
|
1405
1567
|
}
|
|
1406
1568
|
.header-left {
|
|
1407
1569
|
display: flex;
|
|
1408
1570
|
align-items: center;
|
|
1409
|
-
gap:
|
|
1410
|
-
font-size: 13px;
|
|
1411
|
-
color: #888;
|
|
1571
|
+
gap: 12px;
|
|
1412
1572
|
}
|
|
1413
|
-
.
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1573
|
+
.header-icon {
|
|
1574
|
+
width: 20px;
|
|
1575
|
+
height: 20px;
|
|
1576
|
+
fill: #ff6b6b;
|
|
1577
|
+
}
|
|
1578
|
+
.header-title {
|
|
1579
|
+
font-size: 18px;
|
|
1580
|
+
font-weight: 700;
|
|
1581
|
+
color: #fff;
|
|
1582
|
+
}
|
|
1583
|
+
.dev-badge {
|
|
1584
|
+
background: rgba(255, 107, 107, 0.1);
|
|
1585
|
+
border: 1px solid rgba(255, 107, 107, 0.2);
|
|
1586
|
+
color: #ff6b6b;
|
|
1587
|
+
padding: 2px 10px;
|
|
1588
|
+
border-radius: 9999px;
|
|
1418
1589
|
font-size: 12px;
|
|
1419
|
-
|
|
1420
|
-
|
|
1590
|
+
font-weight: 600;
|
|
1591
|
+
letter-spacing: 0.05em;
|
|
1421
1592
|
}
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
border-radius: 6px;
|
|
1426
|
-
color: #888;
|
|
1427
|
-
cursor: pointer;
|
|
1428
|
-
width: 24px;
|
|
1429
|
-
height: 24px;
|
|
1593
|
+
|
|
1594
|
+
/* \u2500\u2500 Status & Route \u2500\u2500 */
|
|
1595
|
+
.status-bar {
|
|
1430
1596
|
display: flex;
|
|
1431
1597
|
align-items: center;
|
|
1432
|
-
|
|
1598
|
+
gap: 12px;
|
|
1599
|
+
margin-top: 8px;
|
|
1600
|
+
font-family: 'DM Mono', monospace;
|
|
1433
1601
|
font-size: 13px;
|
|
1434
|
-
transition: all .15s;
|
|
1435
1602
|
}
|
|
1436
|
-
.
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
font-size: 12px;
|
|
1443
|
-
color: #666;
|
|
1603
|
+
.status-badge {
|
|
1604
|
+
background: #0F172A;
|
|
1605
|
+
border: 1px solid #1E293B;
|
|
1606
|
+
color: #ff6b6b;
|
|
1607
|
+
padding: 4px 10px;
|
|
1608
|
+
border-radius: 6px;
|
|
1444
1609
|
}
|
|
1445
|
-
.
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1610
|
+
.route-badge {
|
|
1611
|
+
background: #0F172A;
|
|
1612
|
+
border: 1px solid #1E293B;
|
|
1613
|
+
color: #2563EB;
|
|
1614
|
+
padding: 4px 10px;
|
|
1615
|
+
border-radius: 6px;
|
|
1451
1616
|
}
|
|
1617
|
+
.separator { color: #94A3B8; }
|
|
1618
|
+
.timestamp { color: #94A3B8; font-family: system-ui; font-size: 13px; }
|
|
1452
1619
|
|
|
1453
|
-
/* \u2500\u2500
|
|
1454
|
-
.
|
|
1455
|
-
|
|
1456
|
-
|
|
1620
|
+
/* \u2500\u2500 Error Message \u2500\u2500 */
|
|
1621
|
+
.error-message-box {
|
|
1622
|
+
background: #0F172A;
|
|
1623
|
+
border: 1px solid #1E293B;
|
|
1624
|
+
border-left: 3px solid #ff6b6b;
|
|
1625
|
+
border-radius: 10px;
|
|
1626
|
+
padding: 1rem 1.25rem;
|
|
1627
|
+
font-family: 'DM Mono', monospace;
|
|
1628
|
+
font-size: 14px;
|
|
1629
|
+
color: #F8FAFC;
|
|
1630
|
+
line-height: 1.6;
|
|
1631
|
+
white-space: pre-wrap;
|
|
1632
|
+
word-break: break-word;
|
|
1457
1633
|
}
|
|
1458
1634
|
|
|
1459
|
-
/* \u2500\u2500
|
|
1460
|
-
.
|
|
1461
|
-
|
|
1462
|
-
|
|
1635
|
+
/* \u2500\u2500 Source Code Viewer \u2500\u2500 */
|
|
1636
|
+
.source-viewer {
|
|
1637
|
+
display: flex;
|
|
1638
|
+
flex-direction: column;
|
|
1639
|
+
gap: 12px;
|
|
1463
1640
|
}
|
|
1464
|
-
.
|
|
1465
|
-
display:
|
|
1641
|
+
.source-header {
|
|
1642
|
+
display: flex;
|
|
1466
1643
|
align-items: center;
|
|
1467
|
-
|
|
1468
|
-
font-size: 11px;
|
|
1469
|
-
font-weight: 700;
|
|
1470
|
-
letter-spacing: 0.08em;
|
|
1471
|
-
text-transform: uppercase;
|
|
1472
|
-
color: #f87171;
|
|
1473
|
-
background: rgba(248, 113, 113, 0.1);
|
|
1474
|
-
border: 1px solid rgba(248, 113, 113, 0.25);
|
|
1475
|
-
padding: 3px 8px;
|
|
1476
|
-
border-radius: 4px;
|
|
1477
|
-
margin-bottom: 14px;
|
|
1478
|
-
}
|
|
1479
|
-
.error-label svg { width: 10px; height: 10px; fill: currentColor; }
|
|
1480
|
-
.error-message {
|
|
1481
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
1482
|
-
font-size: 18px;
|
|
1483
|
-
font-weight: 600;
|
|
1484
|
-
line-height: 1.5;
|
|
1485
|
-
color: #fff;
|
|
1486
|
-
word-break: break-word;
|
|
1644
|
+
justify-content: space-between;
|
|
1487
1645
|
}
|
|
1488
|
-
.
|
|
1489
|
-
|
|
1646
|
+
.source-filepath {
|
|
1647
|
+
font-family: 'DM Mono', monospace;
|
|
1490
1648
|
font-size: 13px;
|
|
1491
|
-
color: #
|
|
1649
|
+
color: #2563EB;
|
|
1492
1650
|
}
|
|
1493
|
-
.
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
border-bottom: 1px solid #1e1e1e;
|
|
1498
|
-
}
|
|
1499
|
-
.source-topbar {
|
|
1651
|
+
.open-in-editor {
|
|
1652
|
+
color: #94A3B8;
|
|
1653
|
+
cursor: pointer;
|
|
1654
|
+
transition: color 0.15s;
|
|
1500
1655
|
display: flex;
|
|
1501
1656
|
align-items: center;
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
gap: 8px;
|
|
1506
|
-
font-size: 12px;
|
|
1507
|
-
color: #666;
|
|
1657
|
+
gap: 6px;
|
|
1658
|
+
font-size: 13px;
|
|
1659
|
+
text-decoration: none;
|
|
1508
1660
|
}
|
|
1509
|
-
.
|
|
1510
|
-
.
|
|
1511
|
-
|
|
1661
|
+
.open-in-editor:hover { color: #F8FAFC; }
|
|
1662
|
+
.open-in-editor svg { width: 14px; height: 14px; stroke: currentColor; fill: none; }
|
|
1663
|
+
|
|
1664
|
+
.source-body {
|
|
1665
|
+
background: #020617;
|
|
1666
|
+
border: 1px solid #1E293B;
|
|
1667
|
+
border-radius: 8px;
|
|
1668
|
+
padding: 16px 0;
|
|
1512
1669
|
overflow-x: auto;
|
|
1513
|
-
|
|
1514
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
1670
|
+
font-family: 'DM Mono', monospace;
|
|
1515
1671
|
font-size: 13px;
|
|
1516
|
-
line-height: 1.
|
|
1672
|
+
line-height: 1.6;
|
|
1517
1673
|
}
|
|
1518
1674
|
.src-line {
|
|
1519
1675
|
display: flex;
|
|
1520
|
-
|
|
1521
|
-
padding: 0 20px;
|
|
1522
|
-
white-space: pre;
|
|
1523
|
-
color: #555;
|
|
1676
|
+
padding: 0 16px;
|
|
1524
1677
|
}
|
|
1525
|
-
.
|
|
1526
|
-
color: #
|
|
1678
|
+
.ln {
|
|
1679
|
+
color: #475569;
|
|
1680
|
+
width: 32px;
|
|
1527
1681
|
text-align: right;
|
|
1528
|
-
width: 36px;
|
|
1529
1682
|
margin-right: 16px;
|
|
1530
|
-
flex-shrink: 0;
|
|
1531
1683
|
user-select: none;
|
|
1684
|
+
flex-shrink: 0;
|
|
1532
1685
|
}
|
|
1533
|
-
.
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1686
|
+
.active-arrow {
|
|
1687
|
+
color: transparent;
|
|
1688
|
+
margin-right: 12px;
|
|
1689
|
+
width: 14px;
|
|
1690
|
+
text-align: center;
|
|
1691
|
+
flex-shrink: 0;
|
|
1537
1692
|
}
|
|
1538
|
-
.
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
left: 0;
|
|
1543
|
-
top: 0; bottom: 0;
|
|
1544
|
-
width: 3px;
|
|
1545
|
-
background: #ef4444;
|
|
1693
|
+
.code-content { white-space: pre; }
|
|
1694
|
+
|
|
1695
|
+
.src-err {
|
|
1696
|
+
background: rgba(37, 99, 235, 0.04);
|
|
1546
1697
|
}
|
|
1698
|
+
.src-err .ln { color: #2563EB; }
|
|
1699
|
+
.src-err .active-arrow { color: #2563EB; }
|
|
1700
|
+
.src-err .code-content { color: #F8FAFC; }
|
|
1547
1701
|
|
|
1548
1702
|
/* \u2500\u2500 Call Stack \u2500\u2500 */
|
|
1549
|
-
.callstack {
|
|
1550
|
-
|
|
1703
|
+
.callstack-section {
|
|
1704
|
+
margin-top: 16px;
|
|
1705
|
+
display: flex;
|
|
1706
|
+
flex-direction: column;
|
|
1707
|
+
gap: 12px;
|
|
1551
1708
|
}
|
|
1552
1709
|
.callstack-header {
|
|
1553
1710
|
display: flex;
|
|
1554
1711
|
align-items: center;
|
|
1555
1712
|
justify-content: space-between;
|
|
1556
|
-
margin-bottom: 14px;
|
|
1557
1713
|
}
|
|
1558
1714
|
.callstack-title {
|
|
1559
|
-
font-size:
|
|
1715
|
+
font-size: 16px;
|
|
1560
1716
|
font-weight: 600;
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1717
|
+
display: flex;
|
|
1718
|
+
align-items: center;
|
|
1719
|
+
gap: 12px;
|
|
1564
1720
|
}
|
|
1565
|
-
.
|
|
1721
|
+
.callstack-count {
|
|
1722
|
+
background: #1E293B;
|
|
1723
|
+
color: #F8FAFC;
|
|
1724
|
+
padding: 2px 10px;
|
|
1725
|
+
border-radius: 9999px;
|
|
1566
1726
|
font-size: 12px;
|
|
1567
|
-
|
|
1727
|
+
font-weight: 500;
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
.toggle-node-modules {
|
|
1731
|
+
color: #94A3B8;
|
|
1732
|
+
font-size: 13px;
|
|
1568
1733
|
background: none;
|
|
1569
1734
|
border: none;
|
|
1570
1735
|
cursor: pointer;
|
|
1736
|
+
transition: color 0.15s;
|
|
1737
|
+
}
|
|
1738
|
+
.toggle-node-modules:hover { color: #F8FAFC; }
|
|
1739
|
+
|
|
1740
|
+
.frame {
|
|
1741
|
+
background: #0F172A;
|
|
1742
|
+
border: 1px solid #1E293B;
|
|
1743
|
+
border-radius: 8px;
|
|
1744
|
+
padding: 0.875rem 1rem;
|
|
1571
1745
|
display: flex;
|
|
1746
|
+
justify-content: space-between;
|
|
1572
1747
|
align-items: center;
|
|
1748
|
+
transition: background-color 0.15s, transform 0.15s;
|
|
1749
|
+
}
|
|
1750
|
+
.frame:hover { background: #1E293B; }
|
|
1751
|
+
|
|
1752
|
+
.frame-info {
|
|
1753
|
+
display: flex;
|
|
1754
|
+
flex-direction: column;
|
|
1573
1755
|
gap: 4px;
|
|
1574
|
-
transition: color .15s;
|
|
1575
1756
|
}
|
|
1576
|
-
.
|
|
1577
|
-
|
|
1578
|
-
|
|
1757
|
+
.frame-call {
|
|
1758
|
+
font-family: 'DM Mono', monospace;
|
|
1759
|
+
font-size: 14px;
|
|
1760
|
+
font-weight: 700;
|
|
1761
|
+
color: #2563EB;
|
|
1762
|
+
}
|
|
1763
|
+
.frame-file {
|
|
1764
|
+
font-family: 'DM Mono', monospace;
|
|
1765
|
+
font-size: 13px;
|
|
1766
|
+
color: #94A3B8;
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
.frame.node-modules .frame-call { color: #94A3B8; font-weight: 400; }
|
|
1770
|
+
.frame.node-modules .frame-file { color: #475569; }
|
|
1771
|
+
|
|
1772
|
+
.frame-number {
|
|
1773
|
+
background: #1E293B;
|
|
1774
|
+
color: #94A3B8;
|
|
1775
|
+
padding: 2px 8px;
|
|
1776
|
+
border-radius: 6px;
|
|
1777
|
+
font-size: 12px;
|
|
1778
|
+
font-variant-numeric: tabular-nums;
|
|
1779
|
+
}
|
|
1579
1780
|
|
|
1580
|
-
.
|
|
1581
|
-
|
|
1781
|
+
.pagination {
|
|
1782
|
+
display: flex;
|
|
1783
|
+
justify-content: flex-end;
|
|
1784
|
+
gap: 8px;
|
|
1785
|
+
margin-top: 8px;
|
|
1786
|
+
}
|
|
1787
|
+
.page-btn {
|
|
1788
|
+
background: transparent;
|
|
1789
|
+
border: 1px solid #1E293B;
|
|
1790
|
+
color: #F8FAFC;
|
|
1791
|
+
padding: 6px 14px;
|
|
1582
1792
|
border-radius: 6px;
|
|
1583
|
-
margin-bottom: 4px;
|
|
1584
1793
|
font-size: 13px;
|
|
1585
|
-
cursor:
|
|
1794
|
+
cursor: pointer;
|
|
1795
|
+
transition: all 0.15s;
|
|
1586
1796
|
}
|
|
1587
|
-
.
|
|
1588
|
-
.
|
|
1589
|
-
|
|
1797
|
+
.page-btn:hover:not(:disabled) { background: #1E293B; }
|
|
1798
|
+
.page-btn:disabled { opacity: 0.3; cursor: default; }
|
|
1799
|
+
|
|
1800
|
+
.node-modules-list { display: none; flex-direction: column; gap: 12px; margin-top: 12px; }
|
|
1801
|
+
.node-modules-list.visible { display: flex; }
|
|
1802
|
+
|
|
1803
|
+
/* \u2500\u2500 Footer \u2500\u2500 */
|
|
1804
|
+
.footer {
|
|
1805
|
+
margin-top: 32px;
|
|
1806
|
+
padding-top: 24px;
|
|
1807
|
+
border-top: 1px solid #1E293B;
|
|
1808
|
+
display: flex;
|
|
1809
|
+
justify-content: space-between;
|
|
1810
|
+
align-items: center;
|
|
1811
|
+
}
|
|
1812
|
+
.footer-left {
|
|
1813
|
+
display: flex;
|
|
1814
|
+
align-items: center;
|
|
1815
|
+
gap: 8px;
|
|
1816
|
+
font-size: 13px;
|
|
1590
1817
|
font-weight: 600;
|
|
1591
|
-
color: #
|
|
1592
|
-
margin-bottom: 3px;
|
|
1818
|
+
color: #F8FAFC;
|
|
1593
1819
|
}
|
|
1594
|
-
.
|
|
1595
|
-
|
|
1820
|
+
.velix-dot { width: 8px; height: 8px; border-radius: 50%; background: #2563EB; }
|
|
1821
|
+
.footer-right {
|
|
1822
|
+
display: flex;
|
|
1823
|
+
align-items: center;
|
|
1824
|
+
gap: 16px;
|
|
1825
|
+
}
|
|
1826
|
+
.footer-link {
|
|
1827
|
+
color: #94A3B8;
|
|
1828
|
+
text-decoration: none;
|
|
1829
|
+
font-size: 13px;
|
|
1830
|
+
transition: color 0.15s;
|
|
1831
|
+
}
|
|
1832
|
+
.footer-link:hover { color: #F8FAFC; }
|
|
1833
|
+
.dev-pill {
|
|
1834
|
+
background: #1E293B;
|
|
1835
|
+
color: #F8FAFC;
|
|
1836
|
+
padding: 4px 12px;
|
|
1837
|
+
border-radius: 9999px;
|
|
1596
1838
|
font-size: 12px;
|
|
1597
|
-
color: #555;
|
|
1598
1839
|
}
|
|
1599
|
-
.frame.ignored .frame-call { color: #444; }
|
|
1600
|
-
|
|
1601
|
-
.ignored-section { margin-top: 8px; display: none; }
|
|
1602
|
-
.ignored-section.open { display: block; }
|
|
1603
1840
|
</style>
|
|
1604
1841
|
</head>
|
|
1605
1842
|
<body>
|
|
1606
|
-
<div class="
|
|
1607
|
-
|
|
1608
|
-
|
|
1843
|
+
<div class="bg-mask"></div>
|
|
1844
|
+
<div class="container">
|
|
1845
|
+
|
|
1846
|
+
<!-- Header -->
|
|
1609
1847
|
<div class="header">
|
|
1610
1848
|
<div class="header-left">
|
|
1611
|
-
<
|
|
1612
|
-
<
|
|
1613
|
-
<button class="nav-btn" disabled>\u203A</button>
|
|
1614
|
-
<span style="margin-left: 4px;">Unhandled Runtime Error</span>
|
|
1849
|
+
<svg class="header-icon" viewBox="0 0 24 24"><path d="M12 2L1 21h22L12 2zm0 3.83L19.17 19H4.83L12 5.83zM11 10h2v5h-2v-5zm0 6h2v2h-2v-2z"/></svg>
|
|
1850
|
+
<div class="header-title">Unhandled Runtime Error</div>
|
|
1615
1851
|
</div>
|
|
1616
|
-
<div class="
|
|
1852
|
+
<div class="dev-badge">DEV</div>
|
|
1617
1853
|
</div>
|
|
1618
1854
|
|
|
1619
|
-
<!--
|
|
1620
|
-
<div class="
|
|
1855
|
+
<!-- Status & Route -->
|
|
1856
|
+
<div class="status-bar">
|
|
1857
|
+
<div class="status-badge">${options.statusCode || 500}</div>
|
|
1858
|
+
<div class="separator">\xB7</div>
|
|
1859
|
+
<div class="route-badge">Route: ${pathname || "/"}</div>
|
|
1860
|
+
<div class="separator">\xB7</div>
|
|
1861
|
+
<div class="timestamp">just now</div>
|
|
1862
|
+
</div>
|
|
1621
1863
|
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
Runtime Error
|
|
1627
|
-
</div>
|
|
1628
|
-
<div class="error-message">${escapeHtml2(message)}</div>
|
|
1629
|
-
${pathname ? `<div class="error-location">in <strong>${escapeHtml2(pathname)}</strong></div>` : ""}
|
|
1630
|
-
</div>
|
|
1864
|
+
<!-- Error Message -->
|
|
1865
|
+
<div class="error-message-box">
|
|
1866
|
+
${formatErrorMessage(message)}
|
|
1867
|
+
</div>
|
|
1631
1868
|
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1869
|
+
${sourceSnippet ? `
|
|
1870
|
+
<!-- Source Viewer -->
|
|
1871
|
+
<div class="source-viewer">
|
|
1872
|
+
<div class="source-header">
|
|
1873
|
+
<div class="source-filepath">${escapeHtml2(shortFile)}${errorLine ? ` (${errorLine})` : ""} @ runtime</div>
|
|
1874
|
+
<a href="#" class="open-in-editor" onclick="console.log('Open in editor clicked')">
|
|
1875
|
+
Open in editor
|
|
1876
|
+
<svg viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path></svg>
|
|
1877
|
+
</a>
|
|
1640
1878
|
</div>
|
|
1641
|
-
|
|
1879
|
+
<div class="source-body">
|
|
1880
|
+
${sourceSnippet}
|
|
1881
|
+
</div>
|
|
1882
|
+
</div>
|
|
1883
|
+
` : ""}
|
|
1642
1884
|
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
<
|
|
1649
|
-
<svg class="ignore-caret" width="12" height="12" viewBox="0 0 12 12" fill="none">
|
|
1650
|
-
<path d="M4.5 3L7.5 6L4.5 9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1651
|
-
</svg>
|
|
1652
|
-
${ignoredFrames.length} ignored frames
|
|
1653
|
-
</button>
|
|
1654
|
-
` : ""}
|
|
1885
|
+
<!-- Call Stack -->
|
|
1886
|
+
<div class="callstack-section">
|
|
1887
|
+
<div class="callstack-header">
|
|
1888
|
+
<div class="callstack-title">
|
|
1889
|
+
Call Stack
|
|
1890
|
+
<div class="callstack-count">${frames.length}</div>
|
|
1655
1891
|
</div>
|
|
1892
|
+
${ignoredFrames.length > 0 ? `
|
|
1893
|
+
<button class="toggle-node-modules" id="toggleNodeModules" onclick="toggleNodeModules()">
|
|
1894
|
+
Show ${ignoredFrames.length} node_modules frames
|
|
1895
|
+
</button>
|
|
1896
|
+
` : ""}
|
|
1897
|
+
</div>
|
|
1656
1898
|
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
<div class="frame">
|
|
1899
|
+
${userFrames.map((f, i) => `
|
|
1900
|
+
<div class="frame">
|
|
1901
|
+
<div class="frame-info">
|
|
1660
1902
|
<div class="frame-call">${escapeHtml2(f.call)}</div>
|
|
1661
|
-
<div class="frame-
|
|
1903
|
+
<div class="frame-file">${escapeHtml2(f.file.replace(/\\\\/g, "/"))}${f.line ? `:${f.line}` : ""}</div>
|
|
1662
1904
|
</div>
|
|
1663
|
-
|
|
1905
|
+
<div class="frame-number">${i + 1}</div>
|
|
1906
|
+
</div>
|
|
1907
|
+
`).join("")}
|
|
1664
1908
|
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
<div class="frame
|
|
1909
|
+
${ignoredFrames.length > 0 ? `
|
|
1910
|
+
<div class="node-modules-list" id="nodeModulesList">
|
|
1911
|
+
${ignoredFrames.map((f, i) => `
|
|
1912
|
+
<div class="frame node-modules">
|
|
1913
|
+
<div class="frame-info">
|
|
1670
1914
|
<div class="frame-call">${escapeHtml2(f.call)}</div>
|
|
1671
|
-
<div class="frame-
|
|
1915
|
+
<div class="frame-file">${escapeHtml2(f.file)}${f.line ? `:${f.line}` : ""}</div>
|
|
1672
1916
|
</div>
|
|
1673
|
-
|
|
1917
|
+
<div class="frame-number">${userFrames.length + i + 1}</div>
|
|
1674
1918
|
</div>
|
|
1675
|
-
`
|
|
1919
|
+
`).join("")}
|
|
1920
|
+
</div>
|
|
1921
|
+
` : ""}
|
|
1922
|
+
|
|
1923
|
+
<div class="pagination">
|
|
1924
|
+
<button class="page-btn" disabled>Previous</button>
|
|
1925
|
+
<button class="page-btn" disabled>Next</button>
|
|
1926
|
+
</div>
|
|
1927
|
+
</div>
|
|
1928
|
+
|
|
1929
|
+
<!-- Footer -->
|
|
1930
|
+
<div class="footer">
|
|
1931
|
+
<div class="footer-left">
|
|
1932
|
+
<div class="velix-dot"></div>
|
|
1933
|
+
Velix v${VERSION}
|
|
1676
1934
|
</div>
|
|
1935
|
+
<div class="footer-right">
|
|
1936
|
+
<a href="/" class="footer-link">Home</a>
|
|
1937
|
+
<a href="#" class="footer-link" onclick="window.location.reload()">Reload</a>
|
|
1938
|
+
<a href="https://velixcloud.io/docs" class="footer-link" target="_blank">Documentation</a>
|
|
1939
|
+
<div class="dev-pill">Development Mode</div>
|
|
1940
|
+
</div>
|
|
1941
|
+
</div>
|
|
1677
1942
|
|
|
1678
|
-
|
|
1679
|
-
</div><!-- /overlay -->
|
|
1943
|
+
</div>
|
|
1680
1944
|
|
|
1681
1945
|
<script>
|
|
1682
|
-
function
|
|
1683
|
-
const
|
|
1684
|
-
const
|
|
1685
|
-
if (!
|
|
1686
|
-
|
|
1687
|
-
|
|
1946
|
+
function toggleNodeModules() {
|
|
1947
|
+
const list = document.getElementById('nodeModulesList');
|
|
1948
|
+
const btn = document.getElementById('toggleNodeModules');
|
|
1949
|
+
if (!list || !btn) return;
|
|
1950
|
+
|
|
1951
|
+
const isVisible = list.classList.contains('visible');
|
|
1952
|
+
if (isVisible) {
|
|
1953
|
+
list.classList.remove('visible');
|
|
1954
|
+
btn.textContent = 'Show ' + list.children.length + ' node_modules frames';
|
|
1955
|
+
} else {
|
|
1956
|
+
list.classList.add('visible');
|
|
1957
|
+
btn.textContent = 'Hide node_modules frames';
|
|
1958
|
+
}
|
|
1688
1959
|
}
|
|
1689
1960
|
</script>
|
|
1690
1961
|
</body>
|
|
@@ -1805,6 +2076,7 @@ async function createServer(options = {}) {
|
|
|
1805
2076
|
if (!res.headersSent) {
|
|
1806
2077
|
res.writeHead(500, { "Content-Type": "text/html; charset=utf-8" });
|
|
1807
2078
|
res.end(generate500Page({
|
|
2079
|
+
statusCode: 500,
|
|
1808
2080
|
message: err.message || "An unexpected error occurred",
|
|
1809
2081
|
stack: isDev ? err.stack : void 0,
|
|
1810
2082
|
isDev,
|
|
@@ -2140,6 +2412,7 @@ async function handlePageRoute(route, routes, req, res, url, config, isDev, proj
|
|
|
2140
2412
|
logger_default.error(`Render error: ${route.path}`, error);
|
|
2141
2413
|
res.writeHead(500, { "Content-Type": "text/html; charset=utf-8" });
|
|
2142
2414
|
res.end(generate500Page({
|
|
2415
|
+
statusCode: 500,
|
|
2143
2416
|
message: error.message || "Failed to render page",
|
|
2144
2417
|
stack: isDev ? error.stack : void 0,
|
|
2145
2418
|
isDev,
|
|
@@ -2318,5 +2591,5 @@ function parseRawBody(req) {
|
|
|
2318
2591
|
var server_default = { createServer, tailwindPlugin };
|
|
2319
2592
|
|
|
2320
2593
|
export { RedirectError, bindArgs, callServerAction, composeMiddleware, cookies, createServer, deserializeArgs, executeAction, formAction, generateJsonLd, generateMetadataTags, generateRobotsTxt, generateSitemap, getAction, getMethod, getPathname, headers, html, isMethod, json, jsonLd, loadMiddleware, mergeMetadata, middlewares, notFound, parseFormData, parseJson, parseSearchParams, redirect, registerAction, runMiddleware, serverAction, server_default, tailwindPlugin, text, useActionContext, useVelixAction };
|
|
2321
|
-
//# sourceMappingURL=chunk-
|
|
2322
|
-
//# sourceMappingURL=chunk-
|
|
2594
|
+
//# sourceMappingURL=chunk-OKEPYKAP.js.map
|
|
2595
|
+
//# sourceMappingURL=chunk-OKEPYKAP.js.map
|