@blinkk/root 1.0.0-beta.8 → 1.0.0-rc.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/bin/root.js +4 -0
- package/dist/{chunk-WVRC46JG.js → chunk-DFBTOMQF.js} +18 -18
- package/dist/chunk-DFBTOMQF.js.map +1 -0
- package/dist/{chunk-LTSJAEBG.js → chunk-J2ANSYAE.js} +21 -6
- package/dist/chunk-J2ANSYAE.js.map +1 -0
- package/dist/chunk-LTNLNQWC.js +1298 -0
- package/dist/chunk-LTNLNQWC.js.map +1 -0
- package/dist/{chunk-WTSNW7BB.js → chunk-MJCIAH6K.js} +2 -4
- package/dist/chunk-MJCIAH6K.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-WNXIRMFF.js +183 -0
- package/dist/chunk-WNXIRMFF.js.map +1 -0
- package/dist/cli.d.ts +14 -4
- package/dist/cli.js +12 -1140
- package/dist/cli.js.map +1 -1
- package/dist/core.d.ts +10 -7
- package/dist/core.js +15 -16
- package/dist/core.js.map +1 -1
- package/dist/functions.d.ts +14 -0
- package/dist/functions.js +30 -0
- package/dist/functions.js.map +1 -0
- package/dist/middleware.d.ts +34 -0
- package/dist/middleware.js +17 -0
- package/dist/middleware.js.map +1 -0
- package/dist/node.d.ts +1 -1
- package/dist/node.js +2 -2
- package/dist/render.d.ts +1 -1
- package/dist/render.js +453 -306
- package/dist/render.js.map +1 -1
- package/dist/{types-8310f09f.d.ts → types-6dd5c0c0.d.ts} +151 -34
- package/package.json +42 -6
- 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
|
@@ -1,26 +1,296 @@
|
|
|
1
|
-
import {
|
|
2
|
-
htmlMinify,
|
|
3
|
-
htmlPretty,
|
|
4
|
-
parseTagNames
|
|
5
|
-
} from "./chunk-WVRC46JG.js";
|
|
6
1
|
import {
|
|
7
2
|
HTML_CONTEXT,
|
|
8
3
|
I18N_CONTEXT,
|
|
9
4
|
REQUEST_CONTEXT,
|
|
10
5
|
getTranslations
|
|
11
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-MJCIAH6K.js";
|
|
7
|
+
import {
|
|
8
|
+
htmlMinify,
|
|
9
|
+
htmlPretty,
|
|
10
|
+
parseTagNames
|
|
11
|
+
} from "./chunk-DFBTOMQF.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, { children: [
|
|
82
|
+
/* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: STYLES } }),
|
|
83
|
+
/* @__PURE__ */ jsxs("div", { className: `root align-${props.align || "left"}`, children: [
|
|
84
|
+
/* @__PURE__ */ jsx("h1", { className: "title", children: title }),
|
|
85
|
+
message && /* @__PURE__ */ jsx("p", { className: "message", children: message }),
|
|
86
|
+
props.children
|
|
87
|
+
] })
|
|
88
|
+
] });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/core/pages/DevErrorPage.tsx
|
|
92
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
|
|
93
|
+
function DevErrorPage(props) {
|
|
94
|
+
var _a;
|
|
95
|
+
const req = props.req;
|
|
96
|
+
const err = props.error;
|
|
97
|
+
const route = props.route;
|
|
98
|
+
const routeParams = props.routeParams;
|
|
99
|
+
let errMsg = String(err);
|
|
100
|
+
if (err && err.stack) {
|
|
101
|
+
errMsg = err.stack.replace(/\(.*node_modules/g, "(node_modules").replace(/at \/.*node_modules/g, "at node_modules");
|
|
102
|
+
if ((_a = req.rootConfig) == null ? void 0 : _a.rootDir) {
|
|
103
|
+
errMsg = errMsg.replaceAll(req.rootConfig.rootDir, "<root>");
|
|
104
|
+
}
|
|
105
|
+
if (process.env.HOME) {
|
|
106
|
+
errMsg = errMsg.replaceAll(process.env.HOME, "$HOME");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return /* @__PURE__ */ jsxs2(ErrorPage, { code: 500, title: "Something went wrong", children: [
|
|
110
|
+
errMsg && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
111
|
+
/* @__PURE__ */ jsx2("h2", { children: "Error" }),
|
|
112
|
+
/* @__PURE__ */ jsx2("pre", { className: "box", children: /* @__PURE__ */ jsx2("code", { children: errMsg }) })
|
|
113
|
+
] }),
|
|
114
|
+
/* @__PURE__ */ jsx2("h2", { children: "Debug Info" }),
|
|
115
|
+
/* @__PURE__ */ jsx2("pre", { className: "box", children: /* @__PURE__ */ jsx2("code", { children: `url: ${req.originalUrl}
|
|
116
|
+
route: ${(route == null ? void 0 : route.src) || "null"}
|
|
117
|
+
routeParams: ${routeParams && JSON.stringify(routeParams) || "null"}` }) })
|
|
118
|
+
] });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/core/pages/DevNotFoundPage.tsx
|
|
122
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
|
|
123
|
+
function DevNotFoundPage(props) {
|
|
124
|
+
const req = props.req;
|
|
125
|
+
const routesListMap = {};
|
|
126
|
+
let srcMaxLength = 0;
|
|
127
|
+
Object.keys(props.sitemap).forEach((urlPath) => {
|
|
128
|
+
const route = props.sitemap[urlPath].route;
|
|
129
|
+
routesListMap[route.src] ??= [];
|
|
130
|
+
routesListMap[route.src].push({ route, urlPath });
|
|
131
|
+
if (route.src.length > srcMaxLength) {
|
|
132
|
+
srcMaxLength = route.src.length;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
const routeSrcs = Object.keys(routesListMap).sort(sortRouteFiles);
|
|
136
|
+
const lines = [];
|
|
137
|
+
routeSrcs.forEach((routeSrc) => {
|
|
138
|
+
const routeUrls = routesListMap[routeSrc].sort(sortRouteURLs);
|
|
139
|
+
routeUrls.forEach((routeUrl, i) => {
|
|
140
|
+
const urlPath = routeUrl.urlPath;
|
|
141
|
+
if (i === 0) {
|
|
142
|
+
lines.push(`${routeSrc.padEnd(srcMaxLength, " ")} => ${urlPath}`);
|
|
143
|
+
} else {
|
|
144
|
+
lines.push(`${"".padEnd(srcMaxLength, " ")} => ${urlPath}`);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
const routesListString = lines.join("\n");
|
|
149
|
+
return /* @__PURE__ */ jsxs3(ErrorPage, { code: 404, title: "Not found", children: [
|
|
150
|
+
/* @__PURE__ */ jsx3("h2", { children: "Routes" }),
|
|
151
|
+
Object.keys(routesListMap).length > 0 ? /* @__PURE__ */ jsx3("pre", { className: "box", children: /* @__PURE__ */ jsx3("code", { children: routesListString }) }) : /* @__PURE__ */ jsxs3("div", { className: "box", children: [
|
|
152
|
+
"Add your first route at ",
|
|
153
|
+
/* @__PURE__ */ jsx3("code", { children: "/routes/index.tsx" })
|
|
154
|
+
] }),
|
|
155
|
+
/* @__PURE__ */ jsx3("h2", { children: "Debug Info" }),
|
|
156
|
+
/* @__PURE__ */ jsx3("pre", { className: "box", children: /* @__PURE__ */ jsx3("code", { children: `url: ${req.originalUrl}` }) })
|
|
157
|
+
] });
|
|
158
|
+
}
|
|
159
|
+
function sortRouteFiles(a, b) {
|
|
160
|
+
if (a === "routes/index.tsx") {
|
|
161
|
+
return -1;
|
|
162
|
+
}
|
|
163
|
+
if (b === "routes/index.tsx") {
|
|
164
|
+
return 1;
|
|
165
|
+
}
|
|
166
|
+
return a.localeCompare(b);
|
|
167
|
+
}
|
|
168
|
+
function sortRouteURLs(a, b) {
|
|
169
|
+
if (a.route.isDefaultLocale && !b.route.isDefaultLocale) {
|
|
170
|
+
return -1;
|
|
171
|
+
}
|
|
172
|
+
if (!a.route.isDefaultLocale && b.route.isDefaultLocale) {
|
|
173
|
+
return 1;
|
|
174
|
+
}
|
|
175
|
+
return a.urlPath.localeCompare(b.urlPath);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// src/render/accept-language.ts
|
|
179
|
+
var ACCEPT_LANG_RE = /((([a-zA-Z]+(-[a-zA-Z0-9]+){0,2})|\*)(;q=[0-1](\.[0-9]+)?)?)*/g;
|
|
180
|
+
function parseAcceptLanguage(value) {
|
|
181
|
+
const matches = String(value).match(ACCEPT_LANG_RE);
|
|
182
|
+
if (!matches) {
|
|
183
|
+
return [];
|
|
184
|
+
}
|
|
185
|
+
const results = [];
|
|
186
|
+
matches.forEach((m) => {
|
|
187
|
+
if (!m) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const parts = m.split(";");
|
|
191
|
+
const ietf = parts[0].split("-");
|
|
192
|
+
const hasScript = ietf.length === 3;
|
|
193
|
+
results.push({
|
|
194
|
+
code: ietf[0],
|
|
195
|
+
script: hasScript ? ietf[1] : void 0,
|
|
196
|
+
region: hasScript ? ietf[2] : ietf[1],
|
|
197
|
+
quality: parts[1] ? parseFloat(parts[1].split("=")[1]) : 1
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
results.sort((a, b) => b.quality - a.quality);
|
|
201
|
+
return results;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// src/render/i18n-fallbacks.ts
|
|
205
|
+
var UNKNOWN_COUNTRY = "zz";
|
|
206
|
+
function getFallbackLocales(req) {
|
|
207
|
+
var _a, _b;
|
|
208
|
+
const hl = getFirstQueryParam(req, "hl");
|
|
209
|
+
const countryCode = getCountry(req);
|
|
210
|
+
if (isWebCrawler(req)) {
|
|
211
|
+
const defaultLocale = ((_b = (_a = req.rootConfig) == null ? void 0 : _a.i18n) == null ? void 0 : _b.defaultLocale) || "en";
|
|
212
|
+
if (hl && hl !== defaultLocale) {
|
|
213
|
+
return [hl, defaultLocale];
|
|
214
|
+
}
|
|
215
|
+
return [defaultLocale];
|
|
216
|
+
}
|
|
217
|
+
const locales = /* @__PURE__ */ new Set();
|
|
218
|
+
if (hl) {
|
|
219
|
+
const langCode = hl;
|
|
220
|
+
locales.add(`${langCode}_${countryCode}`);
|
|
221
|
+
locales.add(`${langCode}_ALL`);
|
|
222
|
+
locales.add(langCode);
|
|
223
|
+
}
|
|
224
|
+
const langs = getFallbackLanguages(req);
|
|
225
|
+
langs.forEach((langCode) => {
|
|
226
|
+
locales.add(`${langCode}_${countryCode}`);
|
|
227
|
+
});
|
|
228
|
+
locales.add(`ALL_${countryCode}`);
|
|
229
|
+
langs.forEach((langCode) => {
|
|
230
|
+
locales.add(`${langCode}_ALL`);
|
|
231
|
+
locales.add(langCode);
|
|
232
|
+
});
|
|
233
|
+
return Array.from(locales);
|
|
234
|
+
}
|
|
235
|
+
function getCountry(req) {
|
|
236
|
+
const normalize = (countryCode) => String(countryCode).toLowerCase();
|
|
237
|
+
const gl = getFirstQueryParam(req, "gl");
|
|
238
|
+
if (gl) {
|
|
239
|
+
return normalize(gl);
|
|
240
|
+
}
|
|
241
|
+
const gaeCountry = req.get("x-country-code") || req.get("x-appengine-country");
|
|
242
|
+
if (gaeCountry) {
|
|
243
|
+
return normalize(gaeCountry);
|
|
244
|
+
}
|
|
245
|
+
return UNKNOWN_COUNTRY;
|
|
246
|
+
}
|
|
247
|
+
function getFallbackLanguages(req) {
|
|
248
|
+
const langs = /* @__PURE__ */ new Set();
|
|
249
|
+
const acceptLangHeader = req.get("accept-language") || "";
|
|
250
|
+
if (acceptLangHeader) {
|
|
251
|
+
parseAcceptLanguage(acceptLangHeader).forEach((lang) => {
|
|
252
|
+
if (lang.region) {
|
|
253
|
+
langs.add(`${lang.code}-${lang.region}`);
|
|
254
|
+
}
|
|
255
|
+
langs.add(lang.code);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
langs.add("en");
|
|
259
|
+
return Array.from(langs);
|
|
260
|
+
}
|
|
261
|
+
function getFirstQueryParam(req, key) {
|
|
262
|
+
const val = req.query[key];
|
|
263
|
+
if (val === null || val === void 0) {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
if (Array.isArray(val)) {
|
|
267
|
+
if (val.length === 0) {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
return String(val[0]);
|
|
271
|
+
}
|
|
272
|
+
return String(val);
|
|
273
|
+
}
|
|
274
|
+
function isWebCrawler(req) {
|
|
275
|
+
const userAgentHeader = req.get("User-Agent");
|
|
276
|
+
if (!userAgentHeader) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
const userAgent = userAgentHeader.toLowerCase();
|
|
280
|
+
return userAgent.includes("googlebot") || userAgent.includes("bingbot") || userAgent.includes("twitterbot");
|
|
281
|
+
}
|
|
282
|
+
|
|
16
283
|
// src/render/router.ts
|
|
17
284
|
import path from "node:path";
|
|
18
285
|
|
|
19
286
|
// src/render/route-trie.ts
|
|
20
|
-
var RouteTrie = class {
|
|
287
|
+
var RouteTrie = class _RouteTrie {
|
|
21
288
|
constructor() {
|
|
22
289
|
this.children = {};
|
|
23
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Adds a route to the trie.
|
|
293
|
+
*/
|
|
24
294
|
add(path2, route) {
|
|
25
295
|
path2 = this.normalizePath(path2);
|
|
26
296
|
if (path2 === "") {
|
|
@@ -35,25 +305,35 @@ var RouteTrie = class {
|
|
|
35
305
|
}
|
|
36
306
|
let nextNode;
|
|
37
307
|
if (head.startsWith("[") && head.endsWith("]")) {
|
|
38
|
-
if (!this.
|
|
39
|
-
|
|
40
|
-
this.paramChild = new ParamChild(paramName);
|
|
308
|
+
if (!this.paramChildren) {
|
|
309
|
+
this.paramChildren = {};
|
|
41
310
|
}
|
|
42
|
-
|
|
311
|
+
const paramName = head.slice(1, -1);
|
|
312
|
+
if (!this.paramChildren[paramName]) {
|
|
313
|
+
this.paramChildren[paramName] = new ParamChild(paramName);
|
|
314
|
+
}
|
|
315
|
+
nextNode = this.paramChildren[paramName].trie;
|
|
43
316
|
} else {
|
|
44
317
|
nextNode = this.children[head];
|
|
45
318
|
if (!nextNode) {
|
|
46
|
-
nextNode = new
|
|
319
|
+
nextNode = new _RouteTrie();
|
|
47
320
|
this.children[head] = nextNode;
|
|
48
321
|
}
|
|
49
322
|
}
|
|
50
323
|
nextNode.add(tail, route);
|
|
51
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Returns a route mapped to the given path and any parameter values from the
|
|
327
|
+
* URL.
|
|
328
|
+
*/
|
|
52
329
|
get(path2) {
|
|
53
330
|
const params = {};
|
|
54
331
|
const route = this.getRoute(path2, params);
|
|
55
332
|
return [route, params];
|
|
56
333
|
}
|
|
334
|
+
/**
|
|
335
|
+
* Walks the route trie and calls a callback function for each route.
|
|
336
|
+
*/
|
|
57
337
|
walk(cb) {
|
|
58
338
|
const promises = [];
|
|
59
339
|
const addPromise = (promise) => {
|
|
@@ -64,11 +344,13 @@ var RouteTrie = class {
|
|
|
64
344
|
if (this.route) {
|
|
65
345
|
addPromise(cb("/", this.route));
|
|
66
346
|
}
|
|
67
|
-
if (this.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
347
|
+
if (this.paramChildren) {
|
|
348
|
+
Object.values(this.paramChildren).forEach((paramChild) => {
|
|
349
|
+
const param = `[${paramChild.name}]`;
|
|
350
|
+
paramChild.trie.walk((childPath, route) => {
|
|
351
|
+
const paramUrlPath = `/${param}${childPath}`;
|
|
352
|
+
addPromise(cb(paramUrlPath, route));
|
|
353
|
+
});
|
|
72
354
|
});
|
|
73
355
|
}
|
|
74
356
|
if (this.wildcardChild) {
|
|
@@ -84,9 +366,12 @@ var RouteTrie = class {
|
|
|
84
366
|
return Promise.all(promises).then(() => {
|
|
85
367
|
});
|
|
86
368
|
}
|
|
369
|
+
/**
|
|
370
|
+
* Removes all routes from the trie.
|
|
371
|
+
*/
|
|
87
372
|
clear() {
|
|
88
373
|
this.children = {};
|
|
89
|
-
this.
|
|
374
|
+
this.paramChildren = void 0;
|
|
90
375
|
this.wildcardChild = void 0;
|
|
91
376
|
this.route = void 0;
|
|
92
377
|
}
|
|
@@ -103,11 +388,13 @@ var RouteTrie = class {
|
|
|
103
388
|
return route;
|
|
104
389
|
}
|
|
105
390
|
}
|
|
106
|
-
if (this.
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
391
|
+
if (this.paramChildren) {
|
|
392
|
+
for (const paramChild of Object.values(this.paramChildren)) {
|
|
393
|
+
const route = paramChild.trie.getRoute(tail, params);
|
|
394
|
+
if (route) {
|
|
395
|
+
params[paramChild.name] = head;
|
|
396
|
+
return route;
|
|
397
|
+
}
|
|
111
398
|
}
|
|
112
399
|
}
|
|
113
400
|
if (this.wildcardChild) {
|
|
@@ -116,9 +403,17 @@ var RouteTrie = class {
|
|
|
116
403
|
}
|
|
117
404
|
return void 0;
|
|
118
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* Normalizes a path for inclusion into the route trie.
|
|
408
|
+
*/
|
|
119
409
|
normalizePath(path2) {
|
|
120
410
|
return path2.replace(/^\/+/g, "");
|
|
121
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Splits the parent directory from its children, e.g.:
|
|
414
|
+
*
|
|
415
|
+
* splitPath("foo/bar/baz") -> ["foo", "bar/baz"]
|
|
416
|
+
*/
|
|
122
417
|
splitPath(path2) {
|
|
123
418
|
const i = path2.indexOf("/");
|
|
124
419
|
if (i === -1) {
|
|
@@ -170,8 +465,9 @@ function getRoutes(config) {
|
|
|
170
465
|
src,
|
|
171
466
|
module: routes[modulePath],
|
|
172
467
|
locale: defaultLocale,
|
|
173
|
-
|
|
174
|
-
|
|
468
|
+
isDefaultLocale: true,
|
|
469
|
+
routePath: normalizeUrlPath(routePath),
|
|
470
|
+
localeRoutePath: normalizeUrlPath(localeRoutePath)
|
|
175
471
|
});
|
|
176
472
|
locales.forEach((locale) => {
|
|
177
473
|
const localePath = localeRoutePath.replace("[locale]", locale);
|
|
@@ -180,6 +476,7 @@ function getRoutes(config) {
|
|
|
180
476
|
src,
|
|
181
477
|
module: routes[modulePath],
|
|
182
478
|
locale,
|
|
479
|
+
isDefaultLocale: false,
|
|
183
480
|
routePath,
|
|
184
481
|
localeRoutePath
|
|
185
482
|
});
|
|
@@ -206,19 +503,19 @@ async function getAllPathsForRoute(urlPathFormat, route) {
|
|
|
206
503
|
);
|
|
207
504
|
} else {
|
|
208
505
|
urlPaths.push({
|
|
209
|
-
urlPath:
|
|
506
|
+
urlPath: normalizeUrlPath(urlPath),
|
|
210
507
|
params: pathParams.params || {}
|
|
211
508
|
});
|
|
212
509
|
}
|
|
213
510
|
}
|
|
214
511
|
);
|
|
215
512
|
}
|
|
216
|
-
} else if (pathContainsPlaceholders(urlPathFormat)) {
|
|
513
|
+
} else if (pathContainsPlaceholders(urlPathFormat) && !routeModule.handle) {
|
|
217
514
|
console.warn(
|
|
218
515
|
`path contains placeholders: ${urlPathFormat}, did you forget to define getStaticPaths()? more info: https://rootjs.dev/guide/routes#getStaticPaths`
|
|
219
516
|
);
|
|
220
517
|
} else {
|
|
221
|
-
urlPaths.push({ urlPath: urlPathFormat, params: {} });
|
|
518
|
+
urlPaths.push({ urlPath: normalizeUrlPath(urlPathFormat), params: {} });
|
|
222
519
|
}
|
|
223
520
|
return urlPaths;
|
|
224
521
|
}
|
|
@@ -235,6 +532,12 @@ function replaceParams(urlPathFormat, params) {
|
|
|
235
532
|
);
|
|
236
533
|
return urlPath;
|
|
237
534
|
}
|
|
535
|
+
function normalizeUrlPath(urlPath) {
|
|
536
|
+
if (urlPath !== "/" && urlPath.endsWith("/")) {
|
|
537
|
+
urlPath = urlPath.replace(/\/*$/g, "");
|
|
538
|
+
}
|
|
539
|
+
return urlPath;
|
|
540
|
+
}
|
|
238
541
|
function pathContainsPlaceholders(urlPath) {
|
|
239
542
|
const segments = urlPath.split("/");
|
|
240
543
|
return segments.some((segment) => {
|
|
@@ -242,194 +545,6 @@ function pathContainsPlaceholders(urlPath) {
|
|
|
242
545
|
});
|
|
243
546
|
}
|
|
244
547
|
|
|
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
|
-
.root.align-center {
|
|
266
|
-
text-align: center;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
h1.title {
|
|
270
|
-
margin-top: 0;
|
|
271
|
-
margin-bottom: 24px;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
p.message {
|
|
275
|
-
margin-top: 0;
|
|
276
|
-
margin-bottom: 0;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
.box {
|
|
280
|
-
font-size: 16px;
|
|
281
|
-
line-height: 1.5;
|
|
282
|
-
padding: 16px;
|
|
283
|
-
border-radius: 12px;
|
|
284
|
-
background: #ffffff;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
pre.box {
|
|
288
|
-
white-space: pre-wrap;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
@media (min-width: 500px) {
|
|
292
|
-
body {
|
|
293
|
-
padding: 40px;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
.box {
|
|
297
|
-
padding: 24px;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
@media (min-width: 1024px) {
|
|
302
|
-
body {
|
|
303
|
-
padding: 100px;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
`;
|
|
307
|
-
function ErrorPage(props) {
|
|
308
|
-
const { code, message } = props;
|
|
309
|
-
const title = props.title || code;
|
|
310
|
-
return /* @__PURE__ */ jsxs(Fragment, {
|
|
311
|
-
children: [
|
|
312
|
-
/* @__PURE__ */ jsx("style", {
|
|
313
|
-
dangerouslySetInnerHTML: { __html: STYLES }
|
|
314
|
-
}),
|
|
315
|
-
/* @__PURE__ */ jsxs("div", {
|
|
316
|
-
className: `root align-${props.align || "left"}`,
|
|
317
|
-
children: [
|
|
318
|
-
/* @__PURE__ */ jsx("h1", {
|
|
319
|
-
className: "title",
|
|
320
|
-
children: title
|
|
321
|
-
}),
|
|
322
|
-
message && /* @__PURE__ */ jsx("p", {
|
|
323
|
-
className: "message",
|
|
324
|
-
children: message
|
|
325
|
-
}),
|
|
326
|
-
props.children
|
|
327
|
-
]
|
|
328
|
-
})
|
|
329
|
-
]
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// src/core/pages/DevNotFoundPage.tsx
|
|
334
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
|
|
335
|
-
function DevNotFoundPage(props) {
|
|
336
|
-
const req = props.req;
|
|
337
|
-
const routesList = [];
|
|
338
|
-
let urlMaxLength = 0;
|
|
339
|
-
Object.keys(props.sitemap).forEach((urlPath) => {
|
|
340
|
-
const route = props.sitemap[urlPath].route;
|
|
341
|
-
routesList.push(Object.assign({}, route, { urlPath }));
|
|
342
|
-
if (urlPath.length > urlMaxLength) {
|
|
343
|
-
urlMaxLength = urlPath.length;
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
const routesListString = routesList.map((route) => {
|
|
347
|
-
return `${route.urlPath.padEnd(urlMaxLength, " ")} => ${route.src}`;
|
|
348
|
-
}).join("\n");
|
|
349
|
-
return /* @__PURE__ */ jsxs2(ErrorPage, {
|
|
350
|
-
code: 404,
|
|
351
|
-
title: "Not found",
|
|
352
|
-
children: [
|
|
353
|
-
/* @__PURE__ */ jsx2("h2", {
|
|
354
|
-
children: "Routes"
|
|
355
|
-
}),
|
|
356
|
-
routesList.length > 0 ? /* @__PURE__ */ jsx2("pre", {
|
|
357
|
-
className: "box",
|
|
358
|
-
children: /* @__PURE__ */ jsx2("code", {
|
|
359
|
-
children: routesListString
|
|
360
|
-
})
|
|
361
|
-
}) : /* @__PURE__ */ jsxs2("div", {
|
|
362
|
-
className: "box",
|
|
363
|
-
children: [
|
|
364
|
-
"Add your first route at ",
|
|
365
|
-
/* @__PURE__ */ jsx2("code", {
|
|
366
|
-
children: "/routes/index.tsx"
|
|
367
|
-
})
|
|
368
|
-
]
|
|
369
|
-
}),
|
|
370
|
-
/* @__PURE__ */ jsx2("h2", {
|
|
371
|
-
children: "Debug Info"
|
|
372
|
-
}),
|
|
373
|
-
/* @__PURE__ */ jsx2("pre", {
|
|
374
|
-
className: "box",
|
|
375
|
-
children: /* @__PURE__ */ jsx2("code", {
|
|
376
|
-
children: `url: ${req.originalUrl}`
|
|
377
|
-
})
|
|
378
|
-
})
|
|
379
|
-
]
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// src/core/pages/DevErrorPage.tsx
|
|
384
|
-
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
|
|
385
|
-
function DevErrorPage(props) {
|
|
386
|
-
var _a;
|
|
387
|
-
const req = props.req;
|
|
388
|
-
const err = props.error;
|
|
389
|
-
const route = props.route;
|
|
390
|
-
const routeParams = props.routeParams;
|
|
391
|
-
let errMsg = String(err);
|
|
392
|
-
if (err && err.stack) {
|
|
393
|
-
errMsg = err.stack.replace(/\(.*node_modules/g, "(node_modules").replace(/at \/.*node_modules/g, "at node_modules");
|
|
394
|
-
if ((_a = req.rootConfig) == null ? void 0 : _a.rootDir) {
|
|
395
|
-
errMsg = errMsg.replaceAll(req.rootConfig.rootDir, "<root>");
|
|
396
|
-
}
|
|
397
|
-
if (process.env.HOME) {
|
|
398
|
-
errMsg = errMsg.replaceAll(process.env.HOME, "$HOME");
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
return /* @__PURE__ */ jsxs3(ErrorPage, {
|
|
402
|
-
code: 500,
|
|
403
|
-
title: "Something went wrong",
|
|
404
|
-
children: [
|
|
405
|
-
errMsg && /* @__PURE__ */ jsxs3(Fragment2, {
|
|
406
|
-
children: [
|
|
407
|
-
/* @__PURE__ */ jsx3("h2", {
|
|
408
|
-
children: "Error"
|
|
409
|
-
}),
|
|
410
|
-
/* @__PURE__ */ jsx3("pre", {
|
|
411
|
-
className: "box",
|
|
412
|
-
children: /* @__PURE__ */ jsx3("code", {
|
|
413
|
-
children: errMsg
|
|
414
|
-
})
|
|
415
|
-
})
|
|
416
|
-
]
|
|
417
|
-
}),
|
|
418
|
-
/* @__PURE__ */ jsx3("h2", {
|
|
419
|
-
children: "Debug Info"
|
|
420
|
-
}),
|
|
421
|
-
/* @__PURE__ */ jsx3("pre", {
|
|
422
|
-
className: "box",
|
|
423
|
-
children: /* @__PURE__ */ jsx3("code", {
|
|
424
|
-
children: `url: ${req.originalUrl}
|
|
425
|
-
route: ${(route == null ? void 0 : route.src) || "null"}
|
|
426
|
-
routeParams: ${routeParams && JSON.stringify(routeParams) || "null"}`
|
|
427
|
-
})
|
|
428
|
-
})
|
|
429
|
-
]
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
|
|
433
548
|
// src/render/render.tsx
|
|
434
549
|
import { jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
|
|
435
550
|
var Renderer = class {
|
|
@@ -440,7 +555,7 @@ var Renderer = class {
|
|
|
440
555
|
this.elementGraph = options.elementGraph;
|
|
441
556
|
}
|
|
442
557
|
async handle(req, res, next) {
|
|
443
|
-
const url = req.path;
|
|
558
|
+
const url = req.path.toLowerCase();
|
|
444
559
|
const [route, routeParams] = this.routes.get(url);
|
|
445
560
|
if (!route) {
|
|
446
561
|
next();
|
|
@@ -449,18 +564,35 @@ var Renderer = class {
|
|
|
449
564
|
if (route.locale) {
|
|
450
565
|
routeParams.$locale = route.locale;
|
|
451
566
|
}
|
|
567
|
+
const fallbackLocales = route.isDefaultLocale ? getFallbackLocales(req) : [route.locale];
|
|
568
|
+
const getPreferredLocale = (availableLocales) => {
|
|
569
|
+
var _a, _b;
|
|
570
|
+
const lowerLocales = availableLocales.map((l) => l.toLowerCase());
|
|
571
|
+
for (const fallbackLocale of fallbackLocales) {
|
|
572
|
+
if (lowerLocales.includes(fallbackLocale.toLowerCase())) {
|
|
573
|
+
return fallbackLocale;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return ((_b = (_a = req.rootConfig) == null ? void 0 : _a.i18n) == null ? void 0 : _b.defaultLocale) || "en";
|
|
577
|
+
};
|
|
452
578
|
const render404 = async () => {
|
|
453
579
|
next();
|
|
454
580
|
};
|
|
455
|
-
const render = async (props2) => {
|
|
581
|
+
const render = async (props2, options) => {
|
|
456
582
|
if (!route.module.default) {
|
|
457
583
|
console.error(`no default component exported in route: ${route.src}`);
|
|
458
584
|
render404();
|
|
459
585
|
return;
|
|
460
586
|
}
|
|
587
|
+
const currentPath = req.path;
|
|
588
|
+
const locale = (options == null ? void 0 : options.locale) || route.locale;
|
|
589
|
+
const translations = options == null ? void 0 : options.translations;
|
|
461
590
|
const output = await this.renderComponent(route.module.default, props2, {
|
|
591
|
+
currentPath,
|
|
462
592
|
route,
|
|
463
|
-
routeParams
|
|
593
|
+
routeParams,
|
|
594
|
+
locale,
|
|
595
|
+
translations
|
|
464
596
|
});
|
|
465
597
|
let html = output.html;
|
|
466
598
|
if (this.rootConfig.prettyHtml) {
|
|
@@ -469,7 +601,7 @@ var Renderer = class {
|
|
|
469
601
|
html = await htmlMinify(html, this.rootConfig.minifyHtmlOptions);
|
|
470
602
|
}
|
|
471
603
|
if (req.viteServer) {
|
|
472
|
-
html = await req.viteServer.transformIndexHtml(
|
|
604
|
+
html = await req.viteServer.transformIndexHtml(currentPath, html);
|
|
473
605
|
}
|
|
474
606
|
let statusCode = 200;
|
|
475
607
|
if (route.src === "routes/404.tsx") {
|
|
@@ -477,12 +609,15 @@ var Renderer = class {
|
|
|
477
609
|
} else if (route.src === "routes/500.tsx") {
|
|
478
610
|
statusCode = 500;
|
|
479
611
|
}
|
|
612
|
+
req.hooks.trigger("preRender");
|
|
480
613
|
res.status(statusCode).set({ "Content-Type": "text/html" }).end(html);
|
|
481
614
|
};
|
|
482
615
|
if (route.module.handle) {
|
|
483
616
|
const handlerContext = {
|
|
484
617
|
route,
|
|
485
618
|
params: routeParams,
|
|
619
|
+
i18nFallbackLocales: fallbackLocales,
|
|
620
|
+
getPreferredLocale,
|
|
486
621
|
render,
|
|
487
622
|
render404
|
|
488
623
|
};
|
|
@@ -505,10 +640,14 @@ var Renderer = class {
|
|
|
505
640
|
await render(props);
|
|
506
641
|
}
|
|
507
642
|
async renderComponent(Component, props, options) {
|
|
508
|
-
const { route, routeParams } = options;
|
|
509
|
-
const locale =
|
|
510
|
-
const translations =
|
|
643
|
+
const { currentPath, route, routeParams } = options;
|
|
644
|
+
const locale = options.locale;
|
|
645
|
+
const translations = {
|
|
646
|
+
...getTranslations(locale),
|
|
647
|
+
...options.translations || {}
|
|
648
|
+
};
|
|
511
649
|
const ctx = {
|
|
650
|
+
currentPath,
|
|
512
651
|
route,
|
|
513
652
|
props,
|
|
514
653
|
routeParams,
|
|
@@ -522,18 +661,7 @@ var Renderer = class {
|
|
|
522
661
|
bodyAttrs: {},
|
|
523
662
|
scriptDeps: []
|
|
524
663
|
};
|
|
525
|
-
const vdom = /* @__PURE__ */ jsx4(REQUEST_CONTEXT.Provider, {
|
|
526
|
-
value: ctx,
|
|
527
|
-
children: /* @__PURE__ */ jsx4(I18N_CONTEXT.Provider, {
|
|
528
|
-
value: { locale, translations },
|
|
529
|
-
children: /* @__PURE__ */ jsx4(HTML_CONTEXT.Provider, {
|
|
530
|
-
value: htmlContext,
|
|
531
|
-
children: /* @__PURE__ */ jsx4(Component, {
|
|
532
|
-
...props
|
|
533
|
-
})
|
|
534
|
-
})
|
|
535
|
-
})
|
|
536
|
-
});
|
|
664
|
+
const vdom = /* @__PURE__ */ jsx4(REQUEST_CONTEXT.Provider, { value: ctx, children: /* @__PURE__ */ jsx4(I18N_CONTEXT.Provider, { value: { locale, translations }, children: /* @__PURE__ */ jsx4(HTML_CONTEXT.Provider, { value: htmlContext, children: /* @__PURE__ */ jsx4(Component, { ...props }) }) }) });
|
|
537
665
|
const mainHtml = renderToString(vdom);
|
|
538
666
|
const jsDeps = /* @__PURE__ */ new Set();
|
|
539
667
|
const cssDeps = /* @__PURE__ */ new Set();
|
|
@@ -557,16 +685,10 @@ var Renderer = class {
|
|
|
557
685
|
})
|
|
558
686
|
);
|
|
559
687
|
const styleTags = Array.from(cssDeps).map((cssUrl) => {
|
|
560
|
-
return /* @__PURE__ */ jsx4("link", {
|
|
561
|
-
rel: "stylesheet",
|
|
562
|
-
href: cssUrl
|
|
563
|
-
});
|
|
688
|
+
return /* @__PURE__ */ jsx4("link", { rel: "stylesheet", href: cssUrl });
|
|
564
689
|
});
|
|
565
690
|
const scriptTags = Array.from(jsDeps).map((jsUrls) => {
|
|
566
|
-
return /* @__PURE__ */ jsx4("script", {
|
|
567
|
-
type: "module",
|
|
568
|
-
src: jsUrls
|
|
569
|
-
});
|
|
691
|
+
return /* @__PURE__ */ jsx4("script", { type: "module", src: jsUrls });
|
|
570
692
|
});
|
|
571
693
|
const html = await this.renderHtml(mainHtml, {
|
|
572
694
|
htmlAttrs: htmlContext.htmlAttrs,
|
|
@@ -580,6 +702,7 @@ var Renderer = class {
|
|
|
580
702
|
});
|
|
581
703
|
return { html };
|
|
582
704
|
}
|
|
705
|
+
/** SSG renders a route. */
|
|
583
706
|
async renderRoute(route, options) {
|
|
584
707
|
const routeParams = options.routeParams;
|
|
585
708
|
if (route.locale) {
|
|
@@ -592,6 +715,8 @@ var Renderer = class {
|
|
|
592
715
|
);
|
|
593
716
|
}
|
|
594
717
|
let props = {};
|
|
718
|
+
let locale = route.locale;
|
|
719
|
+
let translations = void 0;
|
|
595
720
|
if (route.module.getStaticProps) {
|
|
596
721
|
const propsData = await route.module.getStaticProps({
|
|
597
722
|
rootConfig: this.rootConfig,
|
|
@@ -603,8 +728,25 @@ var Renderer = class {
|
|
|
603
728
|
if (propsData.props) {
|
|
604
729
|
props = propsData.props;
|
|
605
730
|
}
|
|
731
|
+
if (propsData.locale) {
|
|
732
|
+
locale = propsData.locale;
|
|
733
|
+
}
|
|
734
|
+
if (propsData.translations) {
|
|
735
|
+
translations = propsData.translations;
|
|
736
|
+
}
|
|
606
737
|
}
|
|
607
|
-
|
|
738
|
+
const routePath = route.isDefaultLocale ? route.routePath : route.localeRoutePath;
|
|
739
|
+
const currentPath = replaceParams(routePath, {
|
|
740
|
+
...routeParams,
|
|
741
|
+
locale
|
|
742
|
+
});
|
|
743
|
+
return this.renderComponent(Component, props, {
|
|
744
|
+
currentPath,
|
|
745
|
+
route,
|
|
746
|
+
routeParams,
|
|
747
|
+
locale,
|
|
748
|
+
translations
|
|
749
|
+
});
|
|
608
750
|
}
|
|
609
751
|
async getSitemap() {
|
|
610
752
|
const sitemap = {};
|
|
@@ -623,80 +765,85 @@ var Renderer = class {
|
|
|
623
765
|
const htmlAttrs = (options == null ? void 0 : options.htmlAttrs) || {};
|
|
624
766
|
const headAttrs = (options == null ? void 0 : options.headAttrs) || {};
|
|
625
767
|
const bodyAttrs = (options == null ? void 0 : options.bodyAttrs) || {};
|
|
626
|
-
const page = /* @__PURE__ */ jsxs4("html", {
|
|
627
|
-
...
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
charSet: "utf-8"
|
|
634
|
-
}),
|
|
635
|
-
options == null ? void 0 : options.headComponents
|
|
636
|
-
]
|
|
637
|
-
}),
|
|
638
|
-
/* @__PURE__ */ jsx4("body", {
|
|
639
|
-
...bodyAttrs,
|
|
640
|
-
dangerouslySetInnerHTML: { __html: html }
|
|
641
|
-
})
|
|
642
|
-
]
|
|
643
|
-
});
|
|
768
|
+
const page = /* @__PURE__ */ jsxs4("html", { ...htmlAttrs, children: [
|
|
769
|
+
/* @__PURE__ */ jsxs4("head", { ...headAttrs, children: [
|
|
770
|
+
/* @__PURE__ */ jsx4("meta", { charSet: "utf-8" }),
|
|
771
|
+
options == null ? void 0 : options.headComponents
|
|
772
|
+
] }),
|
|
773
|
+
/* @__PURE__ */ jsx4("body", { ...bodyAttrs, dangerouslySetInnerHTML: { __html: html } })
|
|
774
|
+
] });
|
|
644
775
|
return `<!doctype html>
|
|
645
776
|
${renderToString(page)}
|
|
646
777
|
`;
|
|
647
778
|
}
|
|
648
|
-
async render404() {
|
|
779
|
+
async render404(options) {
|
|
780
|
+
const currentPath = (options == null ? void 0 : options.currentPath) || "/404";
|
|
649
781
|
const [route, routeParams] = this.routes.get("/404");
|
|
650
782
|
if (route && route.src === "routes/404.tsx" && route.module.default) {
|
|
651
783
|
const Component = route.module.default;
|
|
652
|
-
return this.renderComponent(
|
|
784
|
+
return this.renderComponent(
|
|
785
|
+
Component,
|
|
786
|
+
{},
|
|
787
|
+
{ currentPath, route, routeParams, locale: "en" }
|
|
788
|
+
);
|
|
653
789
|
}
|
|
654
790
|
const mainHtml = renderToString(
|
|
655
|
-
/* @__PURE__ */ jsx4(
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
791
|
+
/* @__PURE__ */ jsx4(
|
|
792
|
+
ErrorPage,
|
|
793
|
+
{
|
|
794
|
+
code: 404,
|
|
795
|
+
title: "Not found",
|
|
796
|
+
message: "Double-check the URL entered and try again.",
|
|
797
|
+
align: "center"
|
|
798
|
+
}
|
|
799
|
+
)
|
|
660
800
|
);
|
|
661
801
|
const html = await this.renderHtml(mainHtml, {
|
|
662
802
|
headComponents: [
|
|
663
|
-
/* @__PURE__ */ jsx4("title", {
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
803
|
+
/* @__PURE__ */ jsx4("title", { children: "404 Not Found" }),
|
|
804
|
+
/* @__PURE__ */ jsx4(
|
|
805
|
+
"meta",
|
|
806
|
+
{
|
|
807
|
+
name: "viewport",
|
|
808
|
+
content: "width=device-width, initial-scale=1.0"
|
|
809
|
+
}
|
|
810
|
+
)
|
|
670
811
|
]
|
|
671
812
|
});
|
|
672
813
|
return { html };
|
|
673
814
|
}
|
|
674
|
-
async renderError(err) {
|
|
815
|
+
async renderError(err, options) {
|
|
816
|
+
const currentPath = (options == null ? void 0 : options.currentPath) || "/500";
|
|
675
817
|
const [route, routeParams] = this.routes.get("/500");
|
|
676
818
|
if (route && route.src === "routes/500.tsx" && route.module.default) {
|
|
677
819
|
const Component = route.module.default;
|
|
678
820
|
return this.renderComponent(
|
|
679
821
|
Component,
|
|
680
822
|
{ error: err },
|
|
681
|
-
{ route, routeParams }
|
|
823
|
+
{ currentPath, route, routeParams, locale: "en" }
|
|
682
824
|
);
|
|
683
825
|
}
|
|
684
826
|
const mainHtml = renderToString(
|
|
685
|
-
/* @__PURE__ */ jsx4(
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
827
|
+
/* @__PURE__ */ jsx4(
|
|
828
|
+
ErrorPage,
|
|
829
|
+
{
|
|
830
|
+
code: 500,
|
|
831
|
+
title: "Something went wrong",
|
|
832
|
+
message: "An unknown error occurred.",
|
|
833
|
+
align: "center"
|
|
834
|
+
}
|
|
835
|
+
)
|
|
690
836
|
);
|
|
691
837
|
const html = await this.renderHtml(mainHtml, {
|
|
692
838
|
headComponents: [
|
|
693
|
-
/* @__PURE__ */ jsx4("title", {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
839
|
+
/* @__PURE__ */ jsx4("title", { children: "500 Error" }),
|
|
840
|
+
/* @__PURE__ */ jsx4(
|
|
841
|
+
"meta",
|
|
842
|
+
{
|
|
843
|
+
name: "viewport",
|
|
844
|
+
content: "width=device-width, initial-scale=1.0"
|
|
845
|
+
}
|
|
846
|
+
)
|
|
700
847
|
]
|
|
701
848
|
});
|
|
702
849
|
return { html };
|
|
@@ -704,35 +851,35 @@ ${renderToString(page)}
|
|
|
704
851
|
async renderDevServer404(req) {
|
|
705
852
|
const sitemap = await this.getSitemap();
|
|
706
853
|
const mainHtml = renderToString(
|
|
707
|
-
/* @__PURE__ */ jsx4(DevNotFoundPage, {
|
|
708
|
-
req,
|
|
709
|
-
sitemap
|
|
710
|
-
})
|
|
854
|
+
/* @__PURE__ */ jsx4(DevNotFoundPage, { req, sitemap })
|
|
711
855
|
);
|
|
712
856
|
const html = await this.renderHtml(mainHtml, {
|
|
713
|
-
headComponents: [/* @__PURE__ */ jsx4("title", {
|
|
714
|
-
children: "404 Not found | Root.js"
|
|
715
|
-
})]
|
|
857
|
+
headComponents: [/* @__PURE__ */ jsx4("title", { children: "404 Not found | Root.js" })]
|
|
716
858
|
});
|
|
717
859
|
return { html };
|
|
718
860
|
}
|
|
719
861
|
async renderDevServer500(req, error) {
|
|
720
862
|
const [route, routeParams] = this.routes.get(req.path);
|
|
721
863
|
const mainHtml = renderToString(
|
|
722
|
-
/* @__PURE__ */ jsx4(
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
864
|
+
/* @__PURE__ */ jsx4(
|
|
865
|
+
DevErrorPage,
|
|
866
|
+
{
|
|
867
|
+
req,
|
|
868
|
+
route,
|
|
869
|
+
routeParams,
|
|
870
|
+
error
|
|
871
|
+
}
|
|
872
|
+
)
|
|
728
873
|
);
|
|
729
874
|
const html = await this.renderHtml(mainHtml, {
|
|
730
|
-
headComponents: [/* @__PURE__ */ jsx4("title", {
|
|
731
|
-
children: "500 Error | Root.js"
|
|
732
|
-
})]
|
|
875
|
+
headComponents: [/* @__PURE__ */ jsx4("title", { children: "500 Error | Root.js" })]
|
|
733
876
|
});
|
|
734
877
|
return { html };
|
|
735
878
|
}
|
|
879
|
+
/**
|
|
880
|
+
* Parses rendered HTML for custom element tags used on the page and
|
|
881
|
+
* automatically adds the JS/CSS deps to the page.
|
|
882
|
+
*/
|
|
736
883
|
async collectElementDeps(html, jsDeps, cssDeps) {
|
|
737
884
|
const elementsMap = this.elementGraph.sourceFiles;
|
|
738
885
|
const assetMap = this.assetMap;
|