@blinkk/root 1.0.0-beta.3 → 1.0.0-beta.30
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/bin/root.js +3 -0
- package/dist/{chunk-WVRC46JG.js → chunk-DXD5LKU3.js} +18 -18
- package/dist/chunk-DXD5LKU3.js.map +1 -0
- package/dist/{chunk-DTEQ2AIW.js → chunk-QKBMWK5B.js} +1 -1
- package/dist/chunk-QKBMWK5B.js.map +1 -0
- package/dist/{chunk-WTSNW7BB.js → chunk-WX2GLKRC.js} +1 -1
- package/dist/chunk-WX2GLKRC.js.map +1 -0
- package/dist/{chunk-LTSJAEBG.js → chunk-XGD3RBFM.js} +5 -4
- package/dist/chunk-XGD3RBFM.js.map +1 -0
- package/dist/cli.d.ts +13 -4
- package/dist/cli.js +212 -141
- package/dist/cli.js.map +1 -1
- package/dist/core.d.ts +5 -7
- package/dist/core.js +10 -10
- package/dist/core.js.map +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +2 -2
- package/dist/render.d.ts +1 -1
- package/dist/render.js +397 -203
- package/dist/render.js.map +1 -1
- package/dist/{types-47b9b530.d.ts → types-8e8129ea.d.ts} +81 -30
- package/package.json +1 -1
- package/dist/chunk-DTEQ2AIW.js.map +0 -1
- package/dist/chunk-LTSJAEBG.js.map +0 -1
- package/dist/chunk-WTSNW7BB.js.map +0 -1
- package/dist/chunk-WVRC46JG.js.map +0 -1
package/dist/render.js
CHANGED
|
@@ -2,17 +2,340 @@ import {
|
|
|
2
2
|
htmlMinify,
|
|
3
3
|
htmlPretty,
|
|
4
4
|
parseTagNames
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-DXD5LKU3.js";
|
|
6
6
|
import {
|
|
7
7
|
HTML_CONTEXT,
|
|
8
8
|
I18N_CONTEXT,
|
|
9
9
|
REQUEST_CONTEXT,
|
|
10
10
|
getTranslations
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-WX2GLKRC.js";
|
|
12
12
|
|
|
13
13
|
// src/render/render.tsx
|
|
14
14
|
import renderToString from "preact-render-to-string";
|
|
15
15
|
|
|
16
|
+
// src/core/pages/ErrorPage.tsx
|
|
17
|
+
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
18
|
+
var STYLES = `
|
|
19
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');
|
|
20
|
+
|
|
21
|
+
:root {
|
|
22
|
+
--font-family-text: "Inter", sans-serif;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
body {
|
|
26
|
+
font-family: var(--font-family-text);
|
|
27
|
+
background: #F5F5F5;
|
|
28
|
+
padding: 40px 16px;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.root {
|
|
32
|
+
max-width: 1200px;
|
|
33
|
+
margin: 0 auto;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.root.align-center {
|
|
37
|
+
text-align: center;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
h1.title {
|
|
41
|
+
margin-top: 0;
|
|
42
|
+
margin-bottom: 24px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
p.message {
|
|
46
|
+
margin-top: 0;
|
|
47
|
+
margin-bottom: 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.box {
|
|
51
|
+
font-size: 16px;
|
|
52
|
+
line-height: 1.5;
|
|
53
|
+
padding: 16px;
|
|
54
|
+
border-radius: 12px;
|
|
55
|
+
background: #ffffff;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
pre.box {
|
|
59
|
+
white-space: pre-wrap;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@media (min-width: 500px) {
|
|
63
|
+
body {
|
|
64
|
+
padding: 40px;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.box {
|
|
68
|
+
padding: 24px;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@media (min-width: 1024px) {
|
|
73
|
+
body {
|
|
74
|
+
padding: 100px;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
`;
|
|
78
|
+
function ErrorPage(props) {
|
|
79
|
+
const { code, message } = props;
|
|
80
|
+
const title = props.title || code;
|
|
81
|
+
return /* @__PURE__ */ jsxs(Fragment, {
|
|
82
|
+
children: [
|
|
83
|
+
/* @__PURE__ */ jsx("style", {
|
|
84
|
+
dangerouslySetInnerHTML: { __html: STYLES }
|
|
85
|
+
}),
|
|
86
|
+
/* @__PURE__ */ jsxs("div", {
|
|
87
|
+
className: `root align-${props.align || "left"}`,
|
|
88
|
+
children: [
|
|
89
|
+
/* @__PURE__ */ jsx("h1", {
|
|
90
|
+
className: "title",
|
|
91
|
+
children: title
|
|
92
|
+
}),
|
|
93
|
+
message && /* @__PURE__ */ jsx("p", {
|
|
94
|
+
className: "message",
|
|
95
|
+
children: message
|
|
96
|
+
}),
|
|
97
|
+
props.children
|
|
98
|
+
]
|
|
99
|
+
})
|
|
100
|
+
]
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/core/pages/DevErrorPage.tsx
|
|
105
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
|
|
106
|
+
function DevErrorPage(props) {
|
|
107
|
+
var _a;
|
|
108
|
+
const req = props.req;
|
|
109
|
+
const err = props.error;
|
|
110
|
+
const route = props.route;
|
|
111
|
+
const routeParams = props.routeParams;
|
|
112
|
+
let errMsg = String(err);
|
|
113
|
+
if (err && err.stack) {
|
|
114
|
+
errMsg = err.stack.replace(/\(.*node_modules/g, "(node_modules").replace(/at \/.*node_modules/g, "at node_modules");
|
|
115
|
+
if ((_a = req.rootConfig) == null ? void 0 : _a.rootDir) {
|
|
116
|
+
errMsg = errMsg.replaceAll(req.rootConfig.rootDir, "<root>");
|
|
117
|
+
}
|
|
118
|
+
if (process.env.HOME) {
|
|
119
|
+
errMsg = errMsg.replaceAll(process.env.HOME, "$HOME");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return /* @__PURE__ */ jsxs2(ErrorPage, {
|
|
123
|
+
code: 500,
|
|
124
|
+
title: "Something went wrong",
|
|
125
|
+
children: [
|
|
126
|
+
errMsg && /* @__PURE__ */ jsxs2(Fragment2, {
|
|
127
|
+
children: [
|
|
128
|
+
/* @__PURE__ */ jsx2("h2", {
|
|
129
|
+
children: "Error"
|
|
130
|
+
}),
|
|
131
|
+
/* @__PURE__ */ jsx2("pre", {
|
|
132
|
+
className: "box",
|
|
133
|
+
children: /* @__PURE__ */ jsx2("code", {
|
|
134
|
+
children: errMsg
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
]
|
|
138
|
+
}),
|
|
139
|
+
/* @__PURE__ */ jsx2("h2", {
|
|
140
|
+
children: "Debug Info"
|
|
141
|
+
}),
|
|
142
|
+
/* @__PURE__ */ jsx2("pre", {
|
|
143
|
+
className: "box",
|
|
144
|
+
children: /* @__PURE__ */ jsx2("code", {
|
|
145
|
+
children: `url: ${req.originalUrl}
|
|
146
|
+
route: ${(route == null ? void 0 : route.src) || "null"}
|
|
147
|
+
routeParams: ${routeParams && JSON.stringify(routeParams) || "null"}`
|
|
148
|
+
})
|
|
149
|
+
})
|
|
150
|
+
]
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// src/core/pages/DevNotFoundPage.tsx
|
|
155
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
|
|
156
|
+
function DevNotFoundPage(props) {
|
|
157
|
+
const req = props.req;
|
|
158
|
+
const routesListMap = {};
|
|
159
|
+
let srcMaxLength = 0;
|
|
160
|
+
Object.keys(props.sitemap).forEach((urlPath) => {
|
|
161
|
+
const route = props.sitemap[urlPath].route;
|
|
162
|
+
routesListMap[route.src] ??= [];
|
|
163
|
+
routesListMap[route.src].push({ route, urlPath });
|
|
164
|
+
if (route.src.length > srcMaxLength) {
|
|
165
|
+
srcMaxLength = route.src.length;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
const routeSrcs = Object.keys(routesListMap).sort(sortRouteFiles);
|
|
169
|
+
const lines = [];
|
|
170
|
+
routeSrcs.forEach((routeSrc) => {
|
|
171
|
+
const routeUrls = routesListMap[routeSrc].sort(sortRouteURLs);
|
|
172
|
+
routeUrls.forEach((routeUrl, i) => {
|
|
173
|
+
const urlPath = routeUrl.urlPath;
|
|
174
|
+
if (i === 0) {
|
|
175
|
+
lines.push(`${routeSrc.padEnd(srcMaxLength, " ")} => ${urlPath}`);
|
|
176
|
+
} else {
|
|
177
|
+
lines.push(`${"".padEnd(srcMaxLength, " ")} => ${urlPath}`);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
const routesListString = lines.join("\n");
|
|
182
|
+
return /* @__PURE__ */ jsxs3(ErrorPage, {
|
|
183
|
+
code: 404,
|
|
184
|
+
title: "Not found",
|
|
185
|
+
children: [
|
|
186
|
+
/* @__PURE__ */ jsx3("h2", {
|
|
187
|
+
children: "Routes"
|
|
188
|
+
}),
|
|
189
|
+
Object.keys(routesListMap).length > 0 ? /* @__PURE__ */ jsx3("pre", {
|
|
190
|
+
className: "box",
|
|
191
|
+
children: /* @__PURE__ */ jsx3("code", {
|
|
192
|
+
children: routesListString
|
|
193
|
+
})
|
|
194
|
+
}) : /* @__PURE__ */ jsxs3("div", {
|
|
195
|
+
className: "box",
|
|
196
|
+
children: [
|
|
197
|
+
"Add your first route at ",
|
|
198
|
+
/* @__PURE__ */ jsx3("code", {
|
|
199
|
+
children: "/routes/index.tsx"
|
|
200
|
+
})
|
|
201
|
+
]
|
|
202
|
+
}),
|
|
203
|
+
/* @__PURE__ */ jsx3("h2", {
|
|
204
|
+
children: "Debug Info"
|
|
205
|
+
}),
|
|
206
|
+
/* @__PURE__ */ jsx3("pre", {
|
|
207
|
+
className: "box",
|
|
208
|
+
children: /* @__PURE__ */ jsx3("code", {
|
|
209
|
+
children: `url: ${req.originalUrl}`
|
|
210
|
+
})
|
|
211
|
+
})
|
|
212
|
+
]
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
function sortRouteFiles(a, b) {
|
|
216
|
+
if (a === "routes/index.tsx") {
|
|
217
|
+
return -1;
|
|
218
|
+
}
|
|
219
|
+
if (b === "routes/index.tsx") {
|
|
220
|
+
return 1;
|
|
221
|
+
}
|
|
222
|
+
return a.localeCompare(b);
|
|
223
|
+
}
|
|
224
|
+
function sortRouteURLs(a, b) {
|
|
225
|
+
if (a.route.isDefaultLocale && !b.route.isDefaultLocale) {
|
|
226
|
+
return -1;
|
|
227
|
+
}
|
|
228
|
+
if (!a.route.isDefaultLocale && b.route.isDefaultLocale) {
|
|
229
|
+
return 1;
|
|
230
|
+
}
|
|
231
|
+
return a.urlPath.localeCompare(b.urlPath);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// src/render/accept-language.ts
|
|
235
|
+
var ACCEPT_LANG_RE = /((([a-zA-Z]+(-[a-zA-Z0-9]+){0,2})|\*)(;q=[0-1](\.[0-9]+)?)?)*/g;
|
|
236
|
+
function parseAcceptLanguage(value) {
|
|
237
|
+
const matches = String(value).match(ACCEPT_LANG_RE);
|
|
238
|
+
if (!matches) {
|
|
239
|
+
return [];
|
|
240
|
+
}
|
|
241
|
+
const results = [];
|
|
242
|
+
matches.forEach((m) => {
|
|
243
|
+
if (!m) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const parts = m.split(";");
|
|
247
|
+
const ietf = parts[0].split("-");
|
|
248
|
+
const hasScript = ietf.length === 3;
|
|
249
|
+
results.push({
|
|
250
|
+
code: ietf[0],
|
|
251
|
+
script: hasScript ? ietf[1] : void 0,
|
|
252
|
+
region: hasScript ? ietf[2] : ietf[1],
|
|
253
|
+
quality: parts[1] ? parseFloat(parts[1].split("=")[1]) : 1
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
results.sort((a, b) => b.quality - a.quality);
|
|
257
|
+
return results;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// src/render/i18n-fallbacks.ts
|
|
261
|
+
var UNKNOWN_COUNTRY = "zz";
|
|
262
|
+
function getFallbackLocales(req) {
|
|
263
|
+
var _a, _b;
|
|
264
|
+
const hl = getFirstQueryParam(req, "hl");
|
|
265
|
+
const countryCode = getCountry(req);
|
|
266
|
+
if (isWebCrawler(req)) {
|
|
267
|
+
const defaultLocale = ((_b = (_a = req.rootConfig) == null ? void 0 : _a.i18n) == null ? void 0 : _b.defaultLocale) || "en";
|
|
268
|
+
if (hl && hl !== defaultLocale) {
|
|
269
|
+
return [hl, defaultLocale];
|
|
270
|
+
}
|
|
271
|
+
return [defaultLocale];
|
|
272
|
+
}
|
|
273
|
+
const locales = /* @__PURE__ */ new Set();
|
|
274
|
+
if (hl) {
|
|
275
|
+
const langCode = hl;
|
|
276
|
+
locales.add(`${langCode}_${countryCode}`);
|
|
277
|
+
locales.add(`${langCode}_ALL`);
|
|
278
|
+
locales.add(langCode);
|
|
279
|
+
}
|
|
280
|
+
const langs = getFallbackLanguages(req);
|
|
281
|
+
langs.forEach((langCode) => {
|
|
282
|
+
locales.add(`${langCode}_${countryCode}`);
|
|
283
|
+
});
|
|
284
|
+
locales.add(`ALL_${countryCode}`);
|
|
285
|
+
langs.forEach((langCode) => {
|
|
286
|
+
locales.add(`${langCode}_ALL`);
|
|
287
|
+
locales.add(langCode);
|
|
288
|
+
});
|
|
289
|
+
return Array.from(locales);
|
|
290
|
+
}
|
|
291
|
+
function getCountry(req) {
|
|
292
|
+
const normalize = (countryCode) => String(countryCode).toLowerCase();
|
|
293
|
+
const gl = getFirstQueryParam(req, "gl");
|
|
294
|
+
if (gl) {
|
|
295
|
+
return normalize(gl);
|
|
296
|
+
}
|
|
297
|
+
const gaeCountry = req.get("x-appengine-country");
|
|
298
|
+
if (gaeCountry) {
|
|
299
|
+
return normalize(gaeCountry);
|
|
300
|
+
}
|
|
301
|
+
return UNKNOWN_COUNTRY;
|
|
302
|
+
}
|
|
303
|
+
function getFallbackLanguages(req) {
|
|
304
|
+
const langs = /* @__PURE__ */ new Set();
|
|
305
|
+
const acceptLangHeader = req.get("accept-language") || "";
|
|
306
|
+
if (acceptLangHeader) {
|
|
307
|
+
parseAcceptLanguage(acceptLangHeader).forEach((lang) => {
|
|
308
|
+
if (lang.region) {
|
|
309
|
+
langs.add(`${lang.code}-${lang.region}`);
|
|
310
|
+
}
|
|
311
|
+
langs.add(lang.code);
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
langs.add("en");
|
|
315
|
+
return Array.from(langs);
|
|
316
|
+
}
|
|
317
|
+
function getFirstQueryParam(req, key) {
|
|
318
|
+
const val = req.query[key];
|
|
319
|
+
if (val === null || val === void 0) {
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
if (Array.isArray(val)) {
|
|
323
|
+
if (val.length === 0) {
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
return String(val[0]);
|
|
327
|
+
}
|
|
328
|
+
return String(val);
|
|
329
|
+
}
|
|
330
|
+
function isWebCrawler(req) {
|
|
331
|
+
const userAgentHeader = req.get("User-Agent");
|
|
332
|
+
if (!userAgentHeader) {
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
const userAgent = userAgentHeader.toLowerCase();
|
|
336
|
+
return userAgent.includes("googlebot") || userAgent.includes("bingbot") || userAgent.includes("twitterbot");
|
|
337
|
+
}
|
|
338
|
+
|
|
16
339
|
// src/render/router.ts
|
|
17
340
|
import path from "node:path";
|
|
18
341
|
|
|
@@ -170,6 +493,7 @@ function getRoutes(config) {
|
|
|
170
493
|
src,
|
|
171
494
|
module: routes[modulePath],
|
|
172
495
|
locale: defaultLocale,
|
|
496
|
+
isDefaultLocale: true,
|
|
173
497
|
routePath,
|
|
174
498
|
localeRoutePath
|
|
175
499
|
});
|
|
@@ -180,6 +504,7 @@ function getRoutes(config) {
|
|
|
180
504
|
src,
|
|
181
505
|
module: routes[modulePath],
|
|
182
506
|
locale,
|
|
507
|
+
isDefaultLocale: false,
|
|
183
508
|
routePath,
|
|
184
509
|
localeRoutePath
|
|
185
510
|
});
|
|
@@ -242,186 +567,6 @@ function pathContainsPlaceholders(urlPath) {
|
|
|
242
567
|
});
|
|
243
568
|
}
|
|
244
569
|
|
|
245
|
-
// src/core/pages/ErrorPage.tsx
|
|
246
|
-
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
247
|
-
var STYLES = `
|
|
248
|
-
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');
|
|
249
|
-
|
|
250
|
-
:root {
|
|
251
|
-
--font-family-text: "Inter", sans-serif;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
body {
|
|
255
|
-
font-family: var(--font-family-text);
|
|
256
|
-
background: #F5F5F5;
|
|
257
|
-
padding: 40px 16px;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
.root {
|
|
261
|
-
max-width: 1200px;
|
|
262
|
-
margin: 0 auto;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
h1 {
|
|
266
|
-
margin-bottom: 40px;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
h2 {
|
|
270
|
-
margin-top: 30px;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
.box {
|
|
274
|
-
font-size: 16px;
|
|
275
|
-
line-height: 1.5;
|
|
276
|
-
padding: 16px;
|
|
277
|
-
border-radius: 12px;
|
|
278
|
-
background: #ffffff;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
pre.box {
|
|
282
|
-
white-space: pre-wrap;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
@media (min-width: 500px) {
|
|
286
|
-
body {
|
|
287
|
-
padding: 40px;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
.box {
|
|
291
|
-
padding: 24px;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
@media (min-width: 1024px) {
|
|
296
|
-
body {
|
|
297
|
-
padding: 100px;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
`;
|
|
301
|
-
function ErrorPage(props) {
|
|
302
|
-
const { code, message } = props;
|
|
303
|
-
const title = props.title ? `${code} | ${props.title}` : code;
|
|
304
|
-
return /* @__PURE__ */ jsxs(Fragment, {
|
|
305
|
-
children: [
|
|
306
|
-
/* @__PURE__ */ jsx("style", {
|
|
307
|
-
dangerouslySetInnerHTML: { __html: STYLES }
|
|
308
|
-
}),
|
|
309
|
-
/* @__PURE__ */ jsxs("div", {
|
|
310
|
-
className: "root",
|
|
311
|
-
children: [
|
|
312
|
-
/* @__PURE__ */ jsx("h1", {
|
|
313
|
-
children: title
|
|
314
|
-
}),
|
|
315
|
-
message && /* @__PURE__ */ jsx("p", {
|
|
316
|
-
children: message
|
|
317
|
-
}),
|
|
318
|
-
props.children
|
|
319
|
-
]
|
|
320
|
-
})
|
|
321
|
-
]
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// src/core/pages/DevNotFoundPage.tsx
|
|
326
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
|
|
327
|
-
function DevNotFoundPage(props) {
|
|
328
|
-
const req = props.req;
|
|
329
|
-
const routesList = [];
|
|
330
|
-
let urlMaxLength = 0;
|
|
331
|
-
Object.keys(props.sitemap).forEach((urlPath) => {
|
|
332
|
-
const route = props.sitemap[urlPath].route;
|
|
333
|
-
routesList.push(Object.assign({}, route, { urlPath }));
|
|
334
|
-
if (urlPath.length > urlMaxLength) {
|
|
335
|
-
urlMaxLength = urlPath.length;
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
const routesListString = routesList.map((route) => {
|
|
339
|
-
return `${route.urlPath.padEnd(urlMaxLength, " ")} => ${route.src}`;
|
|
340
|
-
}).join("\n");
|
|
341
|
-
return /* @__PURE__ */ jsxs2(ErrorPage, {
|
|
342
|
-
code: 404,
|
|
343
|
-
title: "Root.js",
|
|
344
|
-
children: [
|
|
345
|
-
/* @__PURE__ */ jsx2("h2", {
|
|
346
|
-
children: "Routes"
|
|
347
|
-
}),
|
|
348
|
-
routesList.length > 0 ? /* @__PURE__ */ jsx2("pre", {
|
|
349
|
-
className: "box",
|
|
350
|
-
children: /* @__PURE__ */ jsx2("code", {
|
|
351
|
-
children: routesListString
|
|
352
|
-
})
|
|
353
|
-
}) : /* @__PURE__ */ jsxs2("div", {
|
|
354
|
-
className: "box",
|
|
355
|
-
children: [
|
|
356
|
-
"Add your first route at ",
|
|
357
|
-
/* @__PURE__ */ jsx2("code", {
|
|
358
|
-
children: "/routes/index.tsx"
|
|
359
|
-
})
|
|
360
|
-
]
|
|
361
|
-
}),
|
|
362
|
-
/* @__PURE__ */ jsx2("h2", {
|
|
363
|
-
children: "Debug Info"
|
|
364
|
-
}),
|
|
365
|
-
/* @__PURE__ */ jsx2("pre", {
|
|
366
|
-
className: "box",
|
|
367
|
-
children: /* @__PURE__ */ jsx2("code", {
|
|
368
|
-
children: `url: ${req.originalUrl}`
|
|
369
|
-
})
|
|
370
|
-
})
|
|
371
|
-
]
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// src/core/pages/DevErrorPage.tsx
|
|
376
|
-
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
|
|
377
|
-
function DevErrorPage(props) {
|
|
378
|
-
var _a;
|
|
379
|
-
const req = props.req;
|
|
380
|
-
const err = props.error;
|
|
381
|
-
const route = props.route;
|
|
382
|
-
const routeParams = props.routeParams;
|
|
383
|
-
let errMsg = String(err);
|
|
384
|
-
if (err && err.stack) {
|
|
385
|
-
errMsg = err.stack.replace(/\(.*node_modules/g, "(node_modules").replace(/at \/.*node_modules/g, "at node_modules");
|
|
386
|
-
if ((_a = req.rootConfig) == null ? void 0 : _a.rootDir) {
|
|
387
|
-
errMsg = errMsg.replaceAll(req.rootConfig.rootDir, "<root>");
|
|
388
|
-
}
|
|
389
|
-
if (process.env.HOME) {
|
|
390
|
-
errMsg = errMsg.replaceAll(process.env.HOME, "$HOME");
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
return /* @__PURE__ */ jsxs3(ErrorPage, {
|
|
394
|
-
code: 500,
|
|
395
|
-
title: "Root.js",
|
|
396
|
-
children: [
|
|
397
|
-
errMsg && /* @__PURE__ */ jsxs3(Fragment2, {
|
|
398
|
-
children: [
|
|
399
|
-
/* @__PURE__ */ jsx3("h2", {
|
|
400
|
-
children: "Error"
|
|
401
|
-
}),
|
|
402
|
-
/* @__PURE__ */ jsx3("pre", {
|
|
403
|
-
className: "box",
|
|
404
|
-
children: /* @__PURE__ */ jsx3("code", {
|
|
405
|
-
children: errMsg
|
|
406
|
-
})
|
|
407
|
-
})
|
|
408
|
-
]
|
|
409
|
-
}),
|
|
410
|
-
/* @__PURE__ */ jsx3("h2", {
|
|
411
|
-
children: "Debug Info"
|
|
412
|
-
}),
|
|
413
|
-
/* @__PURE__ */ jsx3("pre", {
|
|
414
|
-
className: "box",
|
|
415
|
-
children: /* @__PURE__ */ jsx3("code", {
|
|
416
|
-
children: `url: ${req.originalUrl}
|
|
417
|
-
route: ${(route == null ? void 0 : route.src) || "null"}
|
|
418
|
-
routeParams: ${routeParams && JSON.stringify(routeParams) || "null"}`
|
|
419
|
-
})
|
|
420
|
-
})
|
|
421
|
-
]
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
|
|
425
570
|
// src/render/render.tsx
|
|
426
571
|
import { jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
|
|
427
572
|
var Renderer = class {
|
|
@@ -438,18 +583,26 @@ var Renderer = class {
|
|
|
438
583
|
next();
|
|
439
584
|
return;
|
|
440
585
|
}
|
|
586
|
+
if (route.locale) {
|
|
587
|
+
routeParams.$locale = route.locale;
|
|
588
|
+
}
|
|
589
|
+
const fallbackLocales = route.isDefaultLocale ? getFallbackLocales(req) : [route.locale];
|
|
441
590
|
const render404 = async () => {
|
|
442
591
|
next();
|
|
443
592
|
};
|
|
444
|
-
const render = async (props2) => {
|
|
593
|
+
const render = async (props2, options) => {
|
|
445
594
|
if (!route.module.default) {
|
|
446
595
|
console.error(`no default component exported in route: ${route.src}`);
|
|
447
596
|
render404();
|
|
448
597
|
return;
|
|
449
598
|
}
|
|
599
|
+
const locale = (options == null ? void 0 : options.locale) || route.locale;
|
|
600
|
+
const translations = options == null ? void 0 : options.translations;
|
|
450
601
|
const output = await this.renderComponent(route.module.default, props2, {
|
|
451
602
|
route,
|
|
452
|
-
routeParams
|
|
603
|
+
routeParams,
|
|
604
|
+
locale,
|
|
605
|
+
translations
|
|
453
606
|
});
|
|
454
607
|
let html = output.html;
|
|
455
608
|
if (this.rootConfig.prettyHtml) {
|
|
@@ -472,6 +625,7 @@ var Renderer = class {
|
|
|
472
625
|
const handlerContext = {
|
|
473
626
|
route,
|
|
474
627
|
params: routeParams,
|
|
628
|
+
i18nFallbackLocales: fallbackLocales,
|
|
475
629
|
render,
|
|
476
630
|
render404
|
|
477
631
|
};
|
|
@@ -495,8 +649,11 @@ var Renderer = class {
|
|
|
495
649
|
}
|
|
496
650
|
async renderComponent(Component, props, options) {
|
|
497
651
|
const { route, routeParams } = options;
|
|
498
|
-
const locale =
|
|
499
|
-
const translations =
|
|
652
|
+
const locale = options.locale;
|
|
653
|
+
const translations = {
|
|
654
|
+
...getTranslations(locale),
|
|
655
|
+
...options.translations || {}
|
|
656
|
+
};
|
|
500
657
|
const ctx = {
|
|
501
658
|
route,
|
|
502
659
|
props,
|
|
@@ -571,6 +728,9 @@ var Renderer = class {
|
|
|
571
728
|
}
|
|
572
729
|
async renderRoute(route, options) {
|
|
573
730
|
const routeParams = options.routeParams;
|
|
731
|
+
if (route.locale) {
|
|
732
|
+
routeParams.$locale = route.locale;
|
|
733
|
+
}
|
|
574
734
|
const Component = route.module.default;
|
|
575
735
|
if (!Component) {
|
|
576
736
|
throw new Error(
|
|
@@ -578,6 +738,8 @@ var Renderer = class {
|
|
|
578
738
|
);
|
|
579
739
|
}
|
|
580
740
|
let props = {};
|
|
741
|
+
let locale = route.locale;
|
|
742
|
+
let translations = void 0;
|
|
581
743
|
if (route.module.getStaticProps) {
|
|
582
744
|
const propsData = await route.module.getStaticProps({
|
|
583
745
|
rootConfig: this.rootConfig,
|
|
@@ -589,8 +751,19 @@ var Renderer = class {
|
|
|
589
751
|
if (propsData.props) {
|
|
590
752
|
props = propsData.props;
|
|
591
753
|
}
|
|
754
|
+
if (propsData.locale) {
|
|
755
|
+
locale = propsData.locale;
|
|
756
|
+
}
|
|
757
|
+
if (propsData.translations) {
|
|
758
|
+
translations = propsData.translations;
|
|
759
|
+
}
|
|
592
760
|
}
|
|
593
|
-
return this.renderComponent(Component, props, {
|
|
761
|
+
return this.renderComponent(Component, props, {
|
|
762
|
+
route,
|
|
763
|
+
routeParams,
|
|
764
|
+
locale,
|
|
765
|
+
translations
|
|
766
|
+
});
|
|
594
767
|
}
|
|
595
768
|
async getSitemap() {
|
|
596
769
|
const sitemap = {};
|
|
@@ -635,16 +808,30 @@ ${renderToString(page)}
|
|
|
635
808
|
const [route, routeParams] = this.routes.get("/404");
|
|
636
809
|
if (route && route.src === "routes/404.tsx" && route.module.default) {
|
|
637
810
|
const Component = route.module.default;
|
|
638
|
-
return this.renderComponent(
|
|
811
|
+
return this.renderComponent(
|
|
812
|
+
Component,
|
|
813
|
+
{},
|
|
814
|
+
{ route, routeParams, locale: "en" }
|
|
815
|
+
);
|
|
639
816
|
}
|
|
640
|
-
const mainHtml = renderToString(
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
817
|
+
const mainHtml = renderToString(
|
|
818
|
+
/* @__PURE__ */ jsx4(ErrorPage, {
|
|
819
|
+
code: 404,
|
|
820
|
+
title: "Not found",
|
|
821
|
+
message: "Double-check the URL entered and try again.",
|
|
822
|
+
align: "center"
|
|
823
|
+
})
|
|
824
|
+
);
|
|
644
825
|
const html = await this.renderHtml(mainHtml, {
|
|
645
|
-
headComponents: [
|
|
646
|
-
|
|
647
|
-
|
|
826
|
+
headComponents: [
|
|
827
|
+
/* @__PURE__ */ jsx4("title", {
|
|
828
|
+
children: "404 Not Found"
|
|
829
|
+
}),
|
|
830
|
+
/* @__PURE__ */ jsx4("meta", {
|
|
831
|
+
name: "viewport",
|
|
832
|
+
content: "width=device-width, initial-scale=1.0"
|
|
833
|
+
})
|
|
834
|
+
]
|
|
648
835
|
});
|
|
649
836
|
return { html };
|
|
650
837
|
}
|
|
@@ -655,20 +842,27 @@ ${renderToString(page)}
|
|
|
655
842
|
return this.renderComponent(
|
|
656
843
|
Component,
|
|
657
844
|
{ error: err },
|
|
658
|
-
{ route, routeParams }
|
|
845
|
+
{ route, routeParams, locale: "en" }
|
|
659
846
|
);
|
|
660
847
|
}
|
|
661
848
|
const mainHtml = renderToString(
|
|
662
849
|
/* @__PURE__ */ jsx4(ErrorPage, {
|
|
663
850
|
code: 500,
|
|
664
|
-
title: "
|
|
665
|
-
message: "An unknown error occurred."
|
|
851
|
+
title: "Something went wrong",
|
|
852
|
+
message: "An unknown error occurred.",
|
|
853
|
+
align: "center"
|
|
666
854
|
})
|
|
667
855
|
);
|
|
668
856
|
const html = await this.renderHtml(mainHtml, {
|
|
669
|
-
headComponents: [
|
|
670
|
-
|
|
671
|
-
|
|
857
|
+
headComponents: [
|
|
858
|
+
/* @__PURE__ */ jsx4("title", {
|
|
859
|
+
children: "500 Error"
|
|
860
|
+
}),
|
|
861
|
+
/* @__PURE__ */ jsx4("meta", {
|
|
862
|
+
name: "viewport",
|
|
863
|
+
content: "width=device-width, initial-scale=1.0"
|
|
864
|
+
})
|
|
865
|
+
]
|
|
672
866
|
});
|
|
673
867
|
return { html };
|
|
674
868
|
}
|
|
@@ -682,7 +876,7 @@ ${renderToString(page)}
|
|
|
682
876
|
);
|
|
683
877
|
const html = await this.renderHtml(mainHtml, {
|
|
684
878
|
headComponents: [/* @__PURE__ */ jsx4("title", {
|
|
685
|
-
children: "404 | Root.js"
|
|
879
|
+
children: "404 Not found | Root.js"
|
|
686
880
|
})]
|
|
687
881
|
});
|
|
688
882
|
return { html };
|
|
@@ -699,7 +893,7 @@ ${renderToString(page)}
|
|
|
699
893
|
);
|
|
700
894
|
const html = await this.renderHtml(mainHtml, {
|
|
701
895
|
headComponents: [/* @__PURE__ */ jsx4("title", {
|
|
702
|
-
children: "500 | Root.js"
|
|
896
|
+
children: "500 Error | Root.js"
|
|
703
897
|
})]
|
|
704
898
|
});
|
|
705
899
|
return { html };
|