@blinkk/root 1.0.0-rc.3 → 1.0.0-rc.31
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/LICENSE +22 -0
- package/bin/root.js +1 -0
- package/dist/chunk-IUQLRDFW.js +237 -0
- package/dist/chunk-IUQLRDFW.js.map +1 -0
- package/dist/{chunk-J2ANSYAE.js → chunk-JH33OQEK.js} +64 -2
- package/dist/chunk-JH33OQEK.js.map +1 -0
- package/dist/{chunk-WNXIRMFF.js → chunk-O74GNZTB.js} +3 -2
- package/dist/chunk-O74GNZTB.js.map +1 -0
- package/dist/{chunk-CY3DVKXO.js → chunk-QQOTOKPH.js} +164 -48
- package/dist/chunk-QQOTOKPH.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +4 -4
- package/dist/core.d.ts +3 -3
- package/dist/core.js.map +1 -1
- package/dist/functions.d.ts +1 -1
- package/dist/functions.js +4 -4
- package/dist/middleware.d.ts +4 -4
- package/dist/middleware.js +1 -1
- package/dist/node.d.ts +10 -2
- package/dist/node.js +5 -1
- package/dist/render.d.ts +1 -1
- package/dist/render.js +203 -266
- package/dist/render.js.map +1 -1
- package/dist/{types-9209ea89.d.ts → types-oson8XS0.d.ts} +27 -8
- package/package.json +35 -34
- package/dist/chunk-CY3DVKXO.js.map +0 -1
- package/dist/chunk-DFBTOMQF.js +0 -61
- package/dist/chunk-DFBTOMQF.js.map +0 -1
- package/dist/chunk-J2ANSYAE.js.map +0 -1
- package/dist/chunk-WNXIRMFF.js.map +0 -1
package/dist/render.js
CHANGED
|
@@ -5,10 +5,11 @@ import {
|
|
|
5
5
|
getTranslations
|
|
6
6
|
} from "./chunk-MJCIAH6K.js";
|
|
7
7
|
import {
|
|
8
|
+
RouteTrie,
|
|
8
9
|
htmlMinify,
|
|
9
10
|
htmlPretty,
|
|
10
11
|
parseTagNames
|
|
11
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-IUQLRDFW.js";
|
|
12
13
|
|
|
13
14
|
// src/render/render.tsx
|
|
14
15
|
import renderToString from "preact-render-to-string";
|
|
@@ -203,6 +204,46 @@ function parseAcceptLanguage(value) {
|
|
|
203
204
|
|
|
204
205
|
// src/render/i18n-fallbacks.ts
|
|
205
206
|
var UNKNOWN_COUNTRY = "zz";
|
|
207
|
+
var ES_419_COUNTRIES = [
|
|
208
|
+
"ar",
|
|
209
|
+
// Argentina
|
|
210
|
+
"bo",
|
|
211
|
+
// Bolivia
|
|
212
|
+
"cl",
|
|
213
|
+
// Chile
|
|
214
|
+
"co",
|
|
215
|
+
// Colombia
|
|
216
|
+
"cr",
|
|
217
|
+
// Costa Rica
|
|
218
|
+
"cu",
|
|
219
|
+
// Cuba
|
|
220
|
+
"do",
|
|
221
|
+
// Dominican Republic
|
|
222
|
+
"ec",
|
|
223
|
+
// Ecuador
|
|
224
|
+
"sv",
|
|
225
|
+
// El Salvador
|
|
226
|
+
"gt",
|
|
227
|
+
// Guatemala
|
|
228
|
+
"hn",
|
|
229
|
+
// Honduras
|
|
230
|
+
"mx",
|
|
231
|
+
// Mexico
|
|
232
|
+
"ni",
|
|
233
|
+
// Nicaragua
|
|
234
|
+
"pa",
|
|
235
|
+
// Panama
|
|
236
|
+
"py",
|
|
237
|
+
// Paraguay
|
|
238
|
+
"pe",
|
|
239
|
+
// Peru
|
|
240
|
+
"pr",
|
|
241
|
+
// Puerto Rico
|
|
242
|
+
"uy",
|
|
243
|
+
// Uruguay
|
|
244
|
+
"ve"
|
|
245
|
+
// Venezuela
|
|
246
|
+
];
|
|
206
247
|
function getFallbackLocales(req) {
|
|
207
248
|
var _a, _b;
|
|
208
249
|
const hl = getFirstQueryParam(req, "hl");
|
|
@@ -226,9 +267,14 @@ function getFallbackLocales(req) {
|
|
|
226
267
|
locales.add(`${langCode}_${countryCode}`);
|
|
227
268
|
});
|
|
228
269
|
locales.add(`ALL_${countryCode}`);
|
|
270
|
+
const isEs419Country = test419Country(countryCode);
|
|
229
271
|
langs.forEach((langCode) => {
|
|
230
272
|
locales.add(`${langCode}_ALL`);
|
|
231
273
|
locales.add(langCode);
|
|
274
|
+
if (langCode === "es" && isEs419Country) {
|
|
275
|
+
locales.add("es-419_ALL");
|
|
276
|
+
locales.add("es-419");
|
|
277
|
+
}
|
|
232
278
|
});
|
|
233
279
|
return Array.from(locales);
|
|
234
280
|
}
|
|
@@ -251,6 +297,9 @@ function getFallbackLanguages(req) {
|
|
|
251
297
|
parseAcceptLanguage(acceptLangHeader).forEach((lang) => {
|
|
252
298
|
if (lang.region) {
|
|
253
299
|
langs.add(`${lang.code}-${lang.region}`);
|
|
300
|
+
if (lang.code === "es" && test419Country(lang.region)) {
|
|
301
|
+
langs.add("es-419");
|
|
302
|
+
}
|
|
254
303
|
}
|
|
255
304
|
langs.add(lang.code);
|
|
256
305
|
});
|
|
@@ -279,275 +328,135 @@ function isWebCrawler(req) {
|
|
|
279
328
|
const userAgent = userAgentHeader.toLowerCase();
|
|
280
329
|
return userAgent.includes("googlebot") || userAgent.includes("bingbot") || userAgent.includes("twitterbot");
|
|
281
330
|
}
|
|
331
|
+
function test419Country(countryCode) {
|
|
332
|
+
return ES_419_COUNTRIES.includes(countryCode);
|
|
333
|
+
}
|
|
282
334
|
|
|
283
335
|
// src/render/router.ts
|
|
284
336
|
import path from "node:path";
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if (!this.paramNodes) {
|
|
314
|
-
this.paramNodes = {};
|
|
315
|
-
}
|
|
316
|
-
const paramName = head.slice(1, -1);
|
|
317
|
-
if (!this.paramNodes[paramName]) {
|
|
318
|
-
this.paramNodes[paramName] = new ParamNode(paramName);
|
|
319
|
-
}
|
|
320
|
-
nextNode = this.paramNodes[paramName].trie;
|
|
321
|
-
} else {
|
|
322
|
-
nextNode = this.children[head];
|
|
323
|
-
if (!nextNode) {
|
|
324
|
-
nextNode = new _RouteTrie();
|
|
325
|
-
this.children[head] = nextNode;
|
|
337
|
+
var ROUTES_FILES = import.meta.glob(
|
|
338
|
+
["/routes/*.ts", "/routes/**/*.ts", "/routes/*.tsx", "/routes/**/*.tsx"],
|
|
339
|
+
{ eager: true }
|
|
340
|
+
);
|
|
341
|
+
var Router = class {
|
|
342
|
+
constructor(rootConfig) {
|
|
343
|
+
this.rootConfig = rootConfig;
|
|
344
|
+
this.routeTrie = this.initRouteTrie();
|
|
345
|
+
}
|
|
346
|
+
get(url) {
|
|
347
|
+
return this.routeTrie.get(url);
|
|
348
|
+
}
|
|
349
|
+
async walk(cb) {
|
|
350
|
+
await this.routeTrie.walk(cb);
|
|
351
|
+
}
|
|
352
|
+
initRouteTrie() {
|
|
353
|
+
var _a, _b;
|
|
354
|
+
const locales = ((_a = this.rootConfig.i18n) == null ? void 0 : _a.locales) || [];
|
|
355
|
+
const basePath = this.rootConfig.base || "/";
|
|
356
|
+
const defaultLocale = ((_b = this.rootConfig.i18n) == null ? void 0 : _b.defaultLocale) || "en";
|
|
357
|
+
const trie = new RouteTrie();
|
|
358
|
+
Object.keys(ROUTES_FILES).forEach((modulePath) => {
|
|
359
|
+
var _a2;
|
|
360
|
+
const src = modulePath.slice(1);
|
|
361
|
+
let relativeRoutePath = modulePath.replace(/^\/routes/, "");
|
|
362
|
+
const parts = path.parse(relativeRoutePath);
|
|
363
|
+
if (parts.name.startsWith("_")) {
|
|
364
|
+
return;
|
|
326
365
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
* Returns a route mapped to the given path and any parameter values from the
|
|
332
|
-
* URL.
|
|
333
|
-
*/
|
|
334
|
-
get(path2) {
|
|
335
|
-
const params = {};
|
|
336
|
-
const route = this.getRoute(path2, params);
|
|
337
|
-
return [route, params];
|
|
338
|
-
}
|
|
339
|
-
/**
|
|
340
|
-
* Walks the route trie and calls a callback function for each route.
|
|
341
|
-
*/
|
|
342
|
-
walk(cb) {
|
|
343
|
-
const promises = [];
|
|
344
|
-
const addPromise = (promise) => {
|
|
345
|
-
if (promise) {
|
|
346
|
-
promises.push(promise);
|
|
366
|
+
if (parts.name === "index") {
|
|
367
|
+
relativeRoutePath = parts.dir;
|
|
368
|
+
} else {
|
|
369
|
+
relativeRoutePath = path.join(parts.dir, parts.name);
|
|
347
370
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
371
|
+
const urlFormat = "/[base]/[path]";
|
|
372
|
+
const i18nUrlFormat = toSquareBrackets(
|
|
373
|
+
((_a2 = this.rootConfig.i18n) == null ? void 0 : _a2.urlFormat) || "/[locale]/[base]/[path]"
|
|
374
|
+
);
|
|
375
|
+
const placeholders = {
|
|
376
|
+
base: removeSlashes(basePath),
|
|
377
|
+
path: removeSlashes(relativeRoutePath)
|
|
378
|
+
};
|
|
379
|
+
const formatUrl = (format) => {
|
|
380
|
+
var _a3;
|
|
381
|
+
const url = format.replaceAll("[base]", placeholders.base).replaceAll("[path]", placeholders.path);
|
|
382
|
+
return normalizeUrlPath(url, {
|
|
383
|
+
trailingSlash: (_a3 = this.rootConfig.server) == null ? void 0 : _a3.trailingSlash
|
|
358
384
|
});
|
|
385
|
+
};
|
|
386
|
+
const routePath = formatUrl(urlFormat);
|
|
387
|
+
const localeRoutePath = formatUrl(i18nUrlFormat);
|
|
388
|
+
trie.add(routePath, {
|
|
389
|
+
src,
|
|
390
|
+
module: ROUTES_FILES[modulePath],
|
|
391
|
+
locale: defaultLocale,
|
|
392
|
+
isDefaultLocale: true,
|
|
393
|
+
routePath,
|
|
394
|
+
localeRoutePath
|
|
359
395
|
});
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
return Promise.all(promises).then(() => {
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Removes all routes from the trie.
|
|
380
|
-
*/
|
|
381
|
-
clear() {
|
|
382
|
-
this.children = {};
|
|
383
|
-
this.paramNodes = void 0;
|
|
384
|
-
this.catchAllNodes = void 0;
|
|
385
|
-
this.optCatchAllNodes = void 0;
|
|
386
|
-
this.route = void 0;
|
|
387
|
-
}
|
|
388
|
-
getRoute(urlPath, params) {
|
|
389
|
-
urlPath = this.normalizePath(urlPath);
|
|
390
|
-
if (urlPath === "") {
|
|
391
|
-
if (this.route) {
|
|
392
|
-
return this.route;
|
|
393
|
-
}
|
|
394
|
-
if (this.optCatchAllNodes) {
|
|
395
|
-
if (urlPath) {
|
|
396
|
-
params[this.optCatchAllNodes.name] = urlPath;
|
|
397
|
-
}
|
|
398
|
-
return this.optCatchAllNodes.route;
|
|
399
|
-
}
|
|
400
|
-
return void 0;
|
|
401
|
-
}
|
|
402
|
-
const [head, tail] = this.splitPath(urlPath);
|
|
403
|
-
const child = this.children[head];
|
|
404
|
-
if (child) {
|
|
405
|
-
const route = child.getRoute(tail, params);
|
|
406
|
-
if (route) {
|
|
407
|
-
return route;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
if (this.paramNodes) {
|
|
411
|
-
for (const paramChild of Object.values(this.paramNodes)) {
|
|
412
|
-
const route = paramChild.trie.getRoute(tail, params);
|
|
413
|
-
if (route) {
|
|
414
|
-
params[paramChild.name] = head;
|
|
415
|
-
return route;
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
if (this.catchAllNodes) {
|
|
420
|
-
params[this.catchAllNodes.name] = urlPath;
|
|
421
|
-
return this.catchAllNodes.route;
|
|
422
|
-
}
|
|
423
|
-
if (this.optCatchAllNodes) {
|
|
424
|
-
params[this.optCatchAllNodes.name] = urlPath;
|
|
425
|
-
return this.optCatchAllNodes.route;
|
|
426
|
-
}
|
|
427
|
-
return void 0;
|
|
428
|
-
}
|
|
429
|
-
/**
|
|
430
|
-
* Normalizes a path for inclusion into the route trie.
|
|
431
|
-
*/
|
|
432
|
-
normalizePath(path2) {
|
|
433
|
-
return path2.replace(/^\/+/g, "").replace(/\/+$/g, "");
|
|
434
|
-
}
|
|
435
|
-
/**
|
|
436
|
-
* Splits the parent directory from its children, e.g.:
|
|
437
|
-
*
|
|
438
|
-
* splitPath("foo/bar/baz") -> ["foo", "bar/baz"]
|
|
439
|
-
*/
|
|
440
|
-
splitPath(path2) {
|
|
441
|
-
const i = path2.indexOf("/");
|
|
442
|
-
if (i === -1) {
|
|
443
|
-
return [path2, ""];
|
|
444
|
-
}
|
|
445
|
-
return [path2.slice(0, i), path2.slice(i + 1)];
|
|
446
|
-
}
|
|
447
|
-
};
|
|
448
|
-
var ParamNode = class {
|
|
449
|
-
constructor(name) {
|
|
450
|
-
this.trie = new RouteTrie();
|
|
451
|
-
this.name = name;
|
|
452
|
-
}
|
|
453
|
-
};
|
|
454
|
-
var CatchAllNode = class {
|
|
455
|
-
constructor(name, route) {
|
|
456
|
-
this.name = name;
|
|
457
|
-
this.route = route;
|
|
458
|
-
}
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
// src/render/router.ts
|
|
462
|
-
function getRoutes(config) {
|
|
463
|
-
var _a, _b, _c;
|
|
464
|
-
const locales = ((_a = config.i18n) == null ? void 0 : _a.locales) || [];
|
|
465
|
-
const i18nUrlFormat = ((_b = config.i18n) == null ? void 0 : _b.urlFormat) || "/{locale}/{path}";
|
|
466
|
-
const defaultLocale = ((_c = config.i18n) == null ? void 0 : _c.defaultLocale) || "en";
|
|
467
|
-
const routes = import.meta.glob(
|
|
468
|
-
["/routes/*.ts", "/routes/**/*.ts", "/routes/*.tsx", "/routes/**/*.tsx"],
|
|
469
|
-
{
|
|
470
|
-
eager: true
|
|
471
|
-
}
|
|
472
|
-
);
|
|
473
|
-
const trie = new RouteTrie();
|
|
474
|
-
Object.keys(routes).forEach((modulePath) => {
|
|
475
|
-
const src = modulePath.slice(1);
|
|
476
|
-
let routePath = modulePath.replace(/^\/routes/, "");
|
|
477
|
-
const parts = path.parse(routePath);
|
|
478
|
-
if (parts.name.startsWith("_")) {
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
if (parts.name === "index") {
|
|
482
|
-
routePath = parts.dir;
|
|
483
|
-
} else {
|
|
484
|
-
routePath = path.join(parts.dir, parts.name);
|
|
485
|
-
}
|
|
486
|
-
const localeRoutePath = i18nUrlFormat.replace("{locale}", "[locale]").replace("{path}", routePath.replace(/^\/*/, ""));
|
|
487
|
-
trie.add(routePath, {
|
|
488
|
-
src,
|
|
489
|
-
module: routes[modulePath],
|
|
490
|
-
locale: defaultLocale,
|
|
491
|
-
isDefaultLocale: true,
|
|
492
|
-
routePath: normalizeUrlPath(routePath),
|
|
493
|
-
localeRoutePath: normalizeUrlPath(localeRoutePath)
|
|
494
|
-
});
|
|
495
|
-
locales.forEach((locale) => {
|
|
496
|
-
const localePath = localeRoutePath.replace("[locale]", locale);
|
|
497
|
-
if (localePath !== routePath) {
|
|
498
|
-
trie.add(localePath, {
|
|
499
|
-
src,
|
|
500
|
-
module: routes[modulePath],
|
|
501
|
-
locale,
|
|
502
|
-
isDefaultLocale: false,
|
|
503
|
-
routePath,
|
|
504
|
-
localeRoutePath
|
|
396
|
+
if (i18nUrlFormat.includes("[locale]")) {
|
|
397
|
+
locales.forEach((locale) => {
|
|
398
|
+
const localePath = localeRoutePath.replace("[locale]", locale);
|
|
399
|
+
if (localePath !== relativeRoutePath) {
|
|
400
|
+
trie.add(localePath, {
|
|
401
|
+
src,
|
|
402
|
+
module: ROUTES_FILES[modulePath],
|
|
403
|
+
locale,
|
|
404
|
+
isDefaultLocale: false,
|
|
405
|
+
routePath,
|
|
406
|
+
localeRoutePath
|
|
407
|
+
});
|
|
408
|
+
}
|
|
505
409
|
});
|
|
506
410
|
}
|
|
507
411
|
});
|
|
508
|
-
|
|
509
|
-
return trie;
|
|
510
|
-
}
|
|
511
|
-
async function getAllPathsForRoute(urlPathFormat, route) {
|
|
512
|
-
const routeModule = route.module;
|
|
513
|
-
if (!routeModule.default) {
|
|
514
|
-
return [];
|
|
412
|
+
return trie;
|
|
515
413
|
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
414
|
+
async getAllPathsForRoute(urlPathFormat, route) {
|
|
415
|
+
const routeModule = route.module;
|
|
416
|
+
if (!routeModule.default) {
|
|
417
|
+
return [];
|
|
418
|
+
}
|
|
419
|
+
const urlPaths = [];
|
|
420
|
+
if (routeModule.getStaticPaths) {
|
|
421
|
+
const staticPaths = await routeModule.getStaticPaths({
|
|
422
|
+
rootConfig: this.rootConfig
|
|
423
|
+
});
|
|
424
|
+
if (staticPaths.paths) {
|
|
425
|
+
staticPaths.paths.forEach(
|
|
426
|
+
(pathParams) => {
|
|
427
|
+
const urlPath = replaceParams(
|
|
428
|
+
urlPathFormat,
|
|
429
|
+
pathParams.params || {}
|
|
526
430
|
);
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
}
|
|
431
|
+
if (pathContainsPlaceholders(urlPath)) {
|
|
432
|
+
console.warn(
|
|
433
|
+
`path contains placeholders: ${urlPathFormat}, double check getStaticPaths() and ensure all params are returned. more info: https://rootjs.dev/guide/routes#getStaticPaths`
|
|
434
|
+
);
|
|
435
|
+
} else {
|
|
436
|
+
urlPaths.push({
|
|
437
|
+
urlPath: normalizeUrlPath(urlPath),
|
|
438
|
+
params: pathParams.params || {}
|
|
439
|
+
});
|
|
440
|
+
}
|
|
532
441
|
}
|
|
533
|
-
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
} else if (routeModule.getStaticProps && !pathContainsPlaceholders(urlPathFormat)) {
|
|
445
|
+
urlPaths.push({ urlPath: normalizeUrlPath(urlPathFormat), params: {} });
|
|
446
|
+
} else if (!routeModule.handle && !pathContainsPlaceholders(urlPathFormat)) {
|
|
447
|
+
urlPaths.push({ urlPath: normalizeUrlPath(urlPathFormat), params: {} });
|
|
448
|
+
} else if (pathContainsPlaceholders(urlPathFormat) && !routeModule.handle && !routeModule.getStaticPaths) {
|
|
449
|
+
console.warn(
|
|
450
|
+
[
|
|
451
|
+
`warning: path contains placeholders: ${urlPathFormat}.`,
|
|
452
|
+
`define either ssg getStaticPaths() or ssr handle() for route: ${route.src}.`,
|
|
453
|
+
"more info: https://rootjs.dev/guide/routes"
|
|
454
|
+
].join("\n")
|
|
534
455
|
);
|
|
535
456
|
}
|
|
536
|
-
|
|
537
|
-
urlPaths.push({ urlPath: normalizeUrlPath(urlPathFormat), params: {} });
|
|
538
|
-
} else if (!routeModule.handle && !pathContainsPlaceholders(urlPathFormat)) {
|
|
539
|
-
urlPaths.push({ urlPath: normalizeUrlPath(urlPathFormat), params: {} });
|
|
540
|
-
} else if (pathContainsPlaceholders(urlPathFormat) && !routeModule.handle && !routeModule.getStaticPaths) {
|
|
541
|
-
console.warn(
|
|
542
|
-
[
|
|
543
|
-
`warning: path contains placeholders: ${urlPathFormat}.`,
|
|
544
|
-
`define either ssg getStaticPaths() or ssr handle() for route: ${route.src}.`,
|
|
545
|
-
"more info: https://rootjs.dev/guide/routes"
|
|
546
|
-
].join("\n")
|
|
547
|
-
);
|
|
457
|
+
return urlPaths;
|
|
548
458
|
}
|
|
549
|
-
|
|
550
|
-
}
|
|
459
|
+
};
|
|
551
460
|
function replaceParams(urlPathFormat, params) {
|
|
552
461
|
const urlPath = urlPathFormat.replaceAll(
|
|
553
462
|
/\[\[?(\.\.\.)?([\w\-_]*)\]?\]/g,
|
|
@@ -561,10 +470,17 @@ function replaceParams(urlPathFormat, params) {
|
|
|
561
470
|
);
|
|
562
471
|
return urlPath;
|
|
563
472
|
}
|
|
564
|
-
function normalizeUrlPath(urlPath) {
|
|
565
|
-
|
|
473
|
+
function normalizeUrlPath(urlPath, options) {
|
|
474
|
+
urlPath = urlPath.replace(/\/+/g, "/");
|
|
475
|
+
if ((options == null ? void 0 : options.trailingSlash) === false && urlPath !== "/" && urlPath.endsWith("/")) {
|
|
566
476
|
urlPath = urlPath.replace(/\/*$/g, "");
|
|
567
477
|
}
|
|
478
|
+
if (urlPath.endsWith("/index")) {
|
|
479
|
+
urlPath = urlPath.slice(0, -6);
|
|
480
|
+
}
|
|
481
|
+
if (!urlPath.startsWith("/")) {
|
|
482
|
+
urlPath = `/${urlPath}`;
|
|
483
|
+
}
|
|
568
484
|
return urlPath;
|
|
569
485
|
}
|
|
570
486
|
function pathContainsPlaceholders(urlPath) {
|
|
@@ -573,19 +489,30 @@ function pathContainsPlaceholders(urlPath) {
|
|
|
573
489
|
return segment.startsWith("[") && segment.endsWith("]");
|
|
574
490
|
});
|
|
575
491
|
}
|
|
492
|
+
function removeSlashes(str) {
|
|
493
|
+
return str.replace(/^\/*/g, "").replace(/\/*$/g, "");
|
|
494
|
+
}
|
|
495
|
+
function toSquareBrackets(str) {
|
|
496
|
+
if (str.includes("{") || str.includes("}")) {
|
|
497
|
+
const val = str.replaceAll("{", "[").replaceAll("}", "]");
|
|
498
|
+
console.warn(`"${str}" is a deprecated format, please switch to "${val}"`);
|
|
499
|
+
return val;
|
|
500
|
+
}
|
|
501
|
+
return str;
|
|
502
|
+
}
|
|
576
503
|
|
|
577
504
|
// src/render/render.tsx
|
|
578
505
|
import { jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
|
|
579
506
|
var Renderer = class {
|
|
580
507
|
constructor(rootConfig, options) {
|
|
581
508
|
this.rootConfig = rootConfig;
|
|
582
|
-
this.routes = getRoutes(this.rootConfig);
|
|
583
509
|
this.assetMap = options.assetMap;
|
|
584
510
|
this.elementGraph = options.elementGraph;
|
|
511
|
+
this.router = new Router(rootConfig);
|
|
585
512
|
}
|
|
586
513
|
async handle(req, res, next) {
|
|
587
|
-
const url = req.path
|
|
588
|
-
const [route, routeParams] = this.
|
|
514
|
+
const url = req.path;
|
|
515
|
+
const [route, routeParams] = this.router.get(url);
|
|
589
516
|
if (!route) {
|
|
590
517
|
next();
|
|
591
518
|
return;
|
|
@@ -697,7 +624,12 @@ var Renderer = class {
|
|
|
697
624
|
const routeAsset = await this.assetMap.get(route.src);
|
|
698
625
|
if (routeAsset) {
|
|
699
626
|
const routeCssDeps = await routeAsset.getCssDeps();
|
|
700
|
-
routeCssDeps.forEach((dep) =>
|
|
627
|
+
routeCssDeps.forEach((dep) => {
|
|
628
|
+
if (dep.endsWith("?inline")) {
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
cssDeps.add(dep);
|
|
632
|
+
});
|
|
701
633
|
}
|
|
702
634
|
await this.collectElementDeps(mainHtml, jsDeps, cssDeps);
|
|
703
635
|
await Promise.all(
|
|
@@ -780,8 +712,8 @@ var Renderer = class {
|
|
|
780
712
|
}
|
|
781
713
|
async getSitemap() {
|
|
782
714
|
const sitemap = {};
|
|
783
|
-
await this.
|
|
784
|
-
const routePaths = await getAllPathsForRoute(urlPath, route);
|
|
715
|
+
await this.router.walk(async (urlPath, route) => {
|
|
716
|
+
const routePaths = await this.router.getAllPathsForRoute(urlPath, route);
|
|
785
717
|
routePaths.forEach((routePath) => {
|
|
786
718
|
sitemap[routePath.urlPath] = {
|
|
787
719
|
route,
|
|
@@ -808,7 +740,7 @@ ${renderToString(page)}
|
|
|
808
740
|
}
|
|
809
741
|
async render404(options) {
|
|
810
742
|
const currentPath = (options == null ? void 0 : options.currentPath) || "/404";
|
|
811
|
-
const [route, routeParams] = this.
|
|
743
|
+
const [route, routeParams] = this.router.get("/404");
|
|
812
744
|
if (route && route.src === "routes/404.tsx" && route.module.default) {
|
|
813
745
|
const Component = route.module.default;
|
|
814
746
|
return this.renderComponent(
|
|
@@ -844,7 +776,7 @@ ${renderToString(page)}
|
|
|
844
776
|
}
|
|
845
777
|
async renderError(err, options) {
|
|
846
778
|
const currentPath = (options == null ? void 0 : options.currentPath) || "/500";
|
|
847
|
-
const [route, routeParams] = this.
|
|
779
|
+
const [route, routeParams] = this.router.get("/500");
|
|
848
780
|
if (route && route.src === "routes/500.tsx" && route.module.default) {
|
|
849
781
|
const Component = route.module.default;
|
|
850
782
|
return this.renderComponent(
|
|
@@ -889,7 +821,7 @@ ${renderToString(page)}
|
|
|
889
821
|
return { html };
|
|
890
822
|
}
|
|
891
823
|
async renderDevServer500(req, error) {
|
|
892
|
-
const [route, routeParams] = this.
|
|
824
|
+
const [route, routeParams] = this.router.get(req.path);
|
|
893
825
|
const mainHtml = renderToString(
|
|
894
826
|
/* @__PURE__ */ jsx4(
|
|
895
827
|
DevErrorPage,
|
|
@@ -932,7 +864,12 @@ ${renderToString(page)}
|
|
|
932
864
|
const assetJsDeps = await asset.getJsDeps();
|
|
933
865
|
assetJsDeps.forEach((dep) => jsDeps.add(dep));
|
|
934
866
|
const assetCssDeps = await asset.getCssDeps();
|
|
935
|
-
assetCssDeps.forEach((dep) =>
|
|
867
|
+
assetCssDeps.forEach((dep) => {
|
|
868
|
+
if (dep.endsWith("?inline")) {
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
cssDeps.add(dep);
|
|
872
|
+
});
|
|
936
873
|
})
|
|
937
874
|
);
|
|
938
875
|
return { jsDeps, cssDeps };
|