@blinkk/root 1.0.0-beta.9 → 1.0.0-rc.1
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 +14 -11
- 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 +455 -307
- package/dist/render.js.map +1 -1
- package/dist/{types-8310f09f.d.ts → types-9209ea89.d.ts} +160 -43
- package/package.json +63 -28
- 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();
|
|
@@ -548,7 +676,8 @@ var Renderer = class {
|
|
|
548
676
|
if (!scriptDep.src) {
|
|
549
677
|
return;
|
|
550
678
|
}
|
|
551
|
-
const
|
|
679
|
+
const assetId = String(scriptDep.src).slice(1);
|
|
680
|
+
const scriptAsset = await this.assetMap.get(assetId);
|
|
552
681
|
if (scriptAsset) {
|
|
553
682
|
jsDeps.add(scriptAsset.assetUrl);
|
|
554
683
|
const scriptJsDeps = await scriptAsset.getJsDeps();
|
|
@@ -557,16 +686,10 @@ var Renderer = class {
|
|
|
557
686
|
})
|
|
558
687
|
);
|
|
559
688
|
const styleTags = Array.from(cssDeps).map((cssUrl) => {
|
|
560
|
-
return /* @__PURE__ */ jsx4("link", {
|
|
561
|
-
rel: "stylesheet",
|
|
562
|
-
href: cssUrl
|
|
563
|
-
});
|
|
689
|
+
return /* @__PURE__ */ jsx4("link", { rel: "stylesheet", href: cssUrl });
|
|
564
690
|
});
|
|
565
691
|
const scriptTags = Array.from(jsDeps).map((jsUrls) => {
|
|
566
|
-
return /* @__PURE__ */ jsx4("script", {
|
|
567
|
-
type: "module",
|
|
568
|
-
src: jsUrls
|
|
569
|
-
});
|
|
692
|
+
return /* @__PURE__ */ jsx4("script", { type: "module", src: jsUrls });
|
|
570
693
|
});
|
|
571
694
|
const html = await this.renderHtml(mainHtml, {
|
|
572
695
|
htmlAttrs: htmlContext.htmlAttrs,
|
|
@@ -580,6 +703,7 @@ var Renderer = class {
|
|
|
580
703
|
});
|
|
581
704
|
return { html };
|
|
582
705
|
}
|
|
706
|
+
/** SSG renders a route. */
|
|
583
707
|
async renderRoute(route, options) {
|
|
584
708
|
const routeParams = options.routeParams;
|
|
585
709
|
if (route.locale) {
|
|
@@ -592,6 +716,8 @@ var Renderer = class {
|
|
|
592
716
|
);
|
|
593
717
|
}
|
|
594
718
|
let props = {};
|
|
719
|
+
let locale = route.locale;
|
|
720
|
+
let translations = void 0;
|
|
595
721
|
if (route.module.getStaticProps) {
|
|
596
722
|
const propsData = await route.module.getStaticProps({
|
|
597
723
|
rootConfig: this.rootConfig,
|
|
@@ -603,8 +729,25 @@ var Renderer = class {
|
|
|
603
729
|
if (propsData.props) {
|
|
604
730
|
props = propsData.props;
|
|
605
731
|
}
|
|
732
|
+
if (propsData.locale) {
|
|
733
|
+
locale = propsData.locale;
|
|
734
|
+
}
|
|
735
|
+
if (propsData.translations) {
|
|
736
|
+
translations = propsData.translations;
|
|
737
|
+
}
|
|
606
738
|
}
|
|
607
|
-
|
|
739
|
+
const routePath = route.isDefaultLocale ? route.routePath : route.localeRoutePath;
|
|
740
|
+
const currentPath = replaceParams(routePath, {
|
|
741
|
+
...routeParams,
|
|
742
|
+
locale
|
|
743
|
+
});
|
|
744
|
+
return this.renderComponent(Component, props, {
|
|
745
|
+
currentPath,
|
|
746
|
+
route,
|
|
747
|
+
routeParams,
|
|
748
|
+
locale,
|
|
749
|
+
translations
|
|
750
|
+
});
|
|
608
751
|
}
|
|
609
752
|
async getSitemap() {
|
|
610
753
|
const sitemap = {};
|
|
@@ -623,80 +766,85 @@ var Renderer = class {
|
|
|
623
766
|
const htmlAttrs = (options == null ? void 0 : options.htmlAttrs) || {};
|
|
624
767
|
const headAttrs = (options == null ? void 0 : options.headAttrs) || {};
|
|
625
768
|
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
|
-
});
|
|
769
|
+
const page = /* @__PURE__ */ jsxs4("html", { ...htmlAttrs, children: [
|
|
770
|
+
/* @__PURE__ */ jsxs4("head", { ...headAttrs, children: [
|
|
771
|
+
/* @__PURE__ */ jsx4("meta", { charSet: "utf-8" }),
|
|
772
|
+
options == null ? void 0 : options.headComponents
|
|
773
|
+
] }),
|
|
774
|
+
/* @__PURE__ */ jsx4("body", { ...bodyAttrs, dangerouslySetInnerHTML: { __html: html } })
|
|
775
|
+
] });
|
|
644
776
|
return `<!doctype html>
|
|
645
777
|
${renderToString(page)}
|
|
646
778
|
`;
|
|
647
779
|
}
|
|
648
|
-
async render404() {
|
|
780
|
+
async render404(options) {
|
|
781
|
+
const currentPath = (options == null ? void 0 : options.currentPath) || "/404";
|
|
649
782
|
const [route, routeParams] = this.routes.get("/404");
|
|
650
783
|
if (route && route.src === "routes/404.tsx" && route.module.default) {
|
|
651
784
|
const Component = route.module.default;
|
|
652
|
-
return this.renderComponent(
|
|
785
|
+
return this.renderComponent(
|
|
786
|
+
Component,
|
|
787
|
+
{},
|
|
788
|
+
{ currentPath, route, routeParams, locale: "en" }
|
|
789
|
+
);
|
|
653
790
|
}
|
|
654
791
|
const mainHtml = renderToString(
|
|
655
|
-
/* @__PURE__ */ jsx4(
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
792
|
+
/* @__PURE__ */ jsx4(
|
|
793
|
+
ErrorPage,
|
|
794
|
+
{
|
|
795
|
+
code: 404,
|
|
796
|
+
title: "Not found",
|
|
797
|
+
message: "Double-check the URL entered and try again.",
|
|
798
|
+
align: "center"
|
|
799
|
+
}
|
|
800
|
+
)
|
|
660
801
|
);
|
|
661
802
|
const html = await this.renderHtml(mainHtml, {
|
|
662
803
|
headComponents: [
|
|
663
|
-
/* @__PURE__ */ jsx4("title", {
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
804
|
+
/* @__PURE__ */ jsx4("title", { children: "404 Not Found" }),
|
|
805
|
+
/* @__PURE__ */ jsx4(
|
|
806
|
+
"meta",
|
|
807
|
+
{
|
|
808
|
+
name: "viewport",
|
|
809
|
+
content: "width=device-width, initial-scale=1.0"
|
|
810
|
+
}
|
|
811
|
+
)
|
|
670
812
|
]
|
|
671
813
|
});
|
|
672
814
|
return { html };
|
|
673
815
|
}
|
|
674
|
-
async renderError(err) {
|
|
816
|
+
async renderError(err, options) {
|
|
817
|
+
const currentPath = (options == null ? void 0 : options.currentPath) || "/500";
|
|
675
818
|
const [route, routeParams] = this.routes.get("/500");
|
|
676
819
|
if (route && route.src === "routes/500.tsx" && route.module.default) {
|
|
677
820
|
const Component = route.module.default;
|
|
678
821
|
return this.renderComponent(
|
|
679
822
|
Component,
|
|
680
823
|
{ error: err },
|
|
681
|
-
{ route, routeParams }
|
|
824
|
+
{ currentPath, route, routeParams, locale: "en" }
|
|
682
825
|
);
|
|
683
826
|
}
|
|
684
827
|
const mainHtml = renderToString(
|
|
685
|
-
/* @__PURE__ */ jsx4(
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
828
|
+
/* @__PURE__ */ jsx4(
|
|
829
|
+
ErrorPage,
|
|
830
|
+
{
|
|
831
|
+
code: 500,
|
|
832
|
+
title: "Something went wrong",
|
|
833
|
+
message: "An unknown error occurred.",
|
|
834
|
+
align: "center"
|
|
835
|
+
}
|
|
836
|
+
)
|
|
690
837
|
);
|
|
691
838
|
const html = await this.renderHtml(mainHtml, {
|
|
692
839
|
headComponents: [
|
|
693
|
-
/* @__PURE__ */ jsx4("title", {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
840
|
+
/* @__PURE__ */ jsx4("title", { children: "500 Error" }),
|
|
841
|
+
/* @__PURE__ */ jsx4(
|
|
842
|
+
"meta",
|
|
843
|
+
{
|
|
844
|
+
name: "viewport",
|
|
845
|
+
content: "width=device-width, initial-scale=1.0"
|
|
846
|
+
}
|
|
847
|
+
)
|
|
700
848
|
]
|
|
701
849
|
});
|
|
702
850
|
return { html };
|
|
@@ -704,35 +852,35 @@ ${renderToString(page)}
|
|
|
704
852
|
async renderDevServer404(req) {
|
|
705
853
|
const sitemap = await this.getSitemap();
|
|
706
854
|
const mainHtml = renderToString(
|
|
707
|
-
/* @__PURE__ */ jsx4(DevNotFoundPage, {
|
|
708
|
-
req,
|
|
709
|
-
sitemap
|
|
710
|
-
})
|
|
855
|
+
/* @__PURE__ */ jsx4(DevNotFoundPage, { req, sitemap })
|
|
711
856
|
);
|
|
712
857
|
const html = await this.renderHtml(mainHtml, {
|
|
713
|
-
headComponents: [/* @__PURE__ */ jsx4("title", {
|
|
714
|
-
children: "404 Not found | Root.js"
|
|
715
|
-
})]
|
|
858
|
+
headComponents: [/* @__PURE__ */ jsx4("title", { children: "404 Not found | Root.js" })]
|
|
716
859
|
});
|
|
717
860
|
return { html };
|
|
718
861
|
}
|
|
719
862
|
async renderDevServer500(req, error) {
|
|
720
863
|
const [route, routeParams] = this.routes.get(req.path);
|
|
721
864
|
const mainHtml = renderToString(
|
|
722
|
-
/* @__PURE__ */ jsx4(
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
865
|
+
/* @__PURE__ */ jsx4(
|
|
866
|
+
DevErrorPage,
|
|
867
|
+
{
|
|
868
|
+
req,
|
|
869
|
+
route,
|
|
870
|
+
routeParams,
|
|
871
|
+
error
|
|
872
|
+
}
|
|
873
|
+
)
|
|
728
874
|
);
|
|
729
875
|
const html = await this.renderHtml(mainHtml, {
|
|
730
|
-
headComponents: [/* @__PURE__ */ jsx4("title", {
|
|
731
|
-
children: "500 Error | Root.js"
|
|
732
|
-
})]
|
|
876
|
+
headComponents: [/* @__PURE__ */ jsx4("title", { children: "500 Error | Root.js" })]
|
|
733
877
|
});
|
|
734
878
|
return { html };
|
|
735
879
|
}
|
|
880
|
+
/**
|
|
881
|
+
* Parses rendered HTML for custom element tags used on the page and
|
|
882
|
+
* automatically adds the JS/CSS deps to the page.
|
|
883
|
+
*/
|
|
736
884
|
async collectElementDeps(html, jsDeps, cssDeps) {
|
|
737
885
|
const elementsMap = this.elementGraph.sourceFiles;
|
|
738
886
|
const assetMap = this.assetMap;
|