@blinkk/root 1.0.0-rc.1 → 1.0.0-rc.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-LTNLNQWC.js → chunk-G7ZCTWGB.js} +17 -6
- package/dist/chunk-G7ZCTWGB.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1 -1
- package/dist/core.d.ts +2 -2
- package/dist/core.js.map +1 -1
- package/dist/functions.js +1 -1
- package/dist/middleware.d.ts +2 -2
- package/dist/node.d.ts +1 -1
- package/dist/render.d.ts +1 -1
- package/dist/render.js +181 -57
- package/dist/render.js.map +1 -1
- package/dist/{types-9209ea89.d.ts → types-b48ee619.d.ts} +6 -2
- package/package.json +2 -2
- package/dist/chunk-LTNLNQWC.js.map +0 -1
package/dist/render.js
CHANGED
|
@@ -203,6 +203,46 @@ function parseAcceptLanguage(value) {
|
|
|
203
203
|
|
|
204
204
|
// src/render/i18n-fallbacks.ts
|
|
205
205
|
var UNKNOWN_COUNTRY = "zz";
|
|
206
|
+
var ES_419_COUNTRIES = [
|
|
207
|
+
"ar",
|
|
208
|
+
// Argentina
|
|
209
|
+
"bo",
|
|
210
|
+
// Bolivia
|
|
211
|
+
"cl",
|
|
212
|
+
// Chile
|
|
213
|
+
"co",
|
|
214
|
+
// Colombia
|
|
215
|
+
"cr",
|
|
216
|
+
// Costa Rica
|
|
217
|
+
"cu",
|
|
218
|
+
// Cuba
|
|
219
|
+
"do",
|
|
220
|
+
// Dominican Republic
|
|
221
|
+
"ec",
|
|
222
|
+
// Ecuador
|
|
223
|
+
"sv",
|
|
224
|
+
// El Salvador
|
|
225
|
+
"gt",
|
|
226
|
+
// Guatemala
|
|
227
|
+
"hn",
|
|
228
|
+
// Honduras
|
|
229
|
+
"mx",
|
|
230
|
+
// Mexico
|
|
231
|
+
"ni",
|
|
232
|
+
// Nicaragua
|
|
233
|
+
"pa",
|
|
234
|
+
// Panama
|
|
235
|
+
"py",
|
|
236
|
+
// Paraguay
|
|
237
|
+
"pe",
|
|
238
|
+
// Peru
|
|
239
|
+
"pr",
|
|
240
|
+
// Puerto Rico
|
|
241
|
+
"uy",
|
|
242
|
+
// Uruguay
|
|
243
|
+
"ve"
|
|
244
|
+
// Venezuela
|
|
245
|
+
];
|
|
206
246
|
function getFallbackLocales(req) {
|
|
207
247
|
var _a, _b;
|
|
208
248
|
const hl = getFirstQueryParam(req, "hl");
|
|
@@ -226,9 +266,14 @@ function getFallbackLocales(req) {
|
|
|
226
266
|
locales.add(`${langCode}_${countryCode}`);
|
|
227
267
|
});
|
|
228
268
|
locales.add(`ALL_${countryCode}`);
|
|
269
|
+
const isEs419Country = test419Country(countryCode);
|
|
229
270
|
langs.forEach((langCode) => {
|
|
230
271
|
locales.add(`${langCode}_ALL`);
|
|
231
272
|
locales.add(langCode);
|
|
273
|
+
if (langCode === "es" && isEs419Country) {
|
|
274
|
+
locales.add("es-419_ALL");
|
|
275
|
+
locales.add("es-419");
|
|
276
|
+
}
|
|
232
277
|
});
|
|
233
278
|
return Array.from(locales);
|
|
234
279
|
}
|
|
@@ -251,6 +296,9 @@ function getFallbackLanguages(req) {
|
|
|
251
296
|
parseAcceptLanguage(acceptLangHeader).forEach((lang) => {
|
|
252
297
|
if (lang.region) {
|
|
253
298
|
langs.add(`${lang.code}-${lang.region}`);
|
|
299
|
+
if (lang.code === "es" && test419Country(lang.region)) {
|
|
300
|
+
langs.add("es-419");
|
|
301
|
+
}
|
|
254
302
|
}
|
|
255
303
|
langs.add(lang.code);
|
|
256
304
|
});
|
|
@@ -279,6 +327,9 @@ function isWebCrawler(req) {
|
|
|
279
327
|
const userAgent = userAgentHeader.toLowerCase();
|
|
280
328
|
return userAgent.includes("googlebot") || userAgent.includes("bingbot") || userAgent.includes("twitterbot");
|
|
281
329
|
}
|
|
330
|
+
function test419Country(countryCode) {
|
|
331
|
+
return ES_419_COUNTRIES.includes(countryCode);
|
|
332
|
+
}
|
|
282
333
|
|
|
283
334
|
// src/render/router.ts
|
|
284
335
|
import path from "node:path";
|
|
@@ -298,21 +349,26 @@ var RouteTrie = class _RouteTrie {
|
|
|
298
349
|
return;
|
|
299
350
|
}
|
|
300
351
|
const [head, tail] = this.splitPath(path2);
|
|
352
|
+
if (head.startsWith("[[...") && head.endsWith("]]")) {
|
|
353
|
+
const paramName = head.slice(5, -2);
|
|
354
|
+
this.optCatchAllNodes = new CatchAllNode(paramName, route);
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
301
357
|
if (head.startsWith("[...") && head.endsWith("]")) {
|
|
302
358
|
const paramName = head.slice(4, -1);
|
|
303
|
-
this.
|
|
359
|
+
this.catchAllNodes = new CatchAllNode(paramName, route);
|
|
304
360
|
return;
|
|
305
361
|
}
|
|
306
362
|
let nextNode;
|
|
307
363
|
if (head.startsWith("[") && head.endsWith("]")) {
|
|
308
|
-
if (!this.
|
|
309
|
-
this.
|
|
364
|
+
if (!this.paramNodes) {
|
|
365
|
+
this.paramNodes = {};
|
|
310
366
|
}
|
|
311
367
|
const paramName = head.slice(1, -1);
|
|
312
|
-
if (!this.
|
|
313
|
-
this.
|
|
368
|
+
if (!this.paramNodes[paramName]) {
|
|
369
|
+
this.paramNodes[paramName] = new ParamNode(paramName);
|
|
314
370
|
}
|
|
315
|
-
nextNode = this.
|
|
371
|
+
nextNode = this.paramNodes[paramName].trie;
|
|
316
372
|
} else {
|
|
317
373
|
nextNode = this.children[head];
|
|
318
374
|
if (!nextNode) {
|
|
@@ -344,8 +400,8 @@ var RouteTrie = class _RouteTrie {
|
|
|
344
400
|
if (this.route) {
|
|
345
401
|
addPromise(cb("/", this.route));
|
|
346
402
|
}
|
|
347
|
-
if (this.
|
|
348
|
-
Object.values(this.
|
|
403
|
+
if (this.paramNodes) {
|
|
404
|
+
Object.values(this.paramNodes).forEach((paramChild) => {
|
|
349
405
|
const param = `[${paramChild.name}]`;
|
|
350
406
|
paramChild.trie.walk((childPath, route) => {
|
|
351
407
|
const paramUrlPath = `/${param}${childPath}`;
|
|
@@ -353,9 +409,13 @@ var RouteTrie = class _RouteTrie {
|
|
|
353
409
|
});
|
|
354
410
|
});
|
|
355
411
|
}
|
|
356
|
-
if (this.
|
|
357
|
-
const wildcardUrlPath = `/[...${this.
|
|
358
|
-
addPromise(cb(wildcardUrlPath, this.
|
|
412
|
+
if (this.catchAllNodes) {
|
|
413
|
+
const wildcardUrlPath = `/[...${this.catchAllNodes.name}]`;
|
|
414
|
+
addPromise(cb(wildcardUrlPath, this.catchAllNodes.route));
|
|
415
|
+
}
|
|
416
|
+
if (this.optCatchAllNodes) {
|
|
417
|
+
const wildcardUrlPath = `/[[...${this.optCatchAllNodes.name}]]`;
|
|
418
|
+
addPromise(cb(wildcardUrlPath, this.optCatchAllNodes.route));
|
|
359
419
|
}
|
|
360
420
|
for (const subpath of Object.keys(this.children)) {
|
|
361
421
|
const childTrie = this.children[subpath];
|
|
@@ -371,14 +431,24 @@ var RouteTrie = class _RouteTrie {
|
|
|
371
431
|
*/
|
|
372
432
|
clear() {
|
|
373
433
|
this.children = {};
|
|
374
|
-
this.
|
|
375
|
-
this.
|
|
434
|
+
this.paramNodes = void 0;
|
|
435
|
+
this.catchAllNodes = void 0;
|
|
436
|
+
this.optCatchAllNodes = void 0;
|
|
376
437
|
this.route = void 0;
|
|
377
438
|
}
|
|
378
439
|
getRoute(urlPath, params) {
|
|
379
440
|
urlPath = this.normalizePath(urlPath);
|
|
380
441
|
if (urlPath === "") {
|
|
381
|
-
|
|
442
|
+
if (this.route) {
|
|
443
|
+
return this.route;
|
|
444
|
+
}
|
|
445
|
+
if (this.optCatchAllNodes) {
|
|
446
|
+
if (urlPath) {
|
|
447
|
+
params[this.optCatchAllNodes.name] = urlPath;
|
|
448
|
+
}
|
|
449
|
+
return this.optCatchAllNodes.route;
|
|
450
|
+
}
|
|
451
|
+
return void 0;
|
|
382
452
|
}
|
|
383
453
|
const [head, tail] = this.splitPath(urlPath);
|
|
384
454
|
const child = this.children[head];
|
|
@@ -388,8 +458,8 @@ var RouteTrie = class _RouteTrie {
|
|
|
388
458
|
return route;
|
|
389
459
|
}
|
|
390
460
|
}
|
|
391
|
-
if (this.
|
|
392
|
-
for (const paramChild of Object.values(this.
|
|
461
|
+
if (this.paramNodes) {
|
|
462
|
+
for (const paramChild of Object.values(this.paramNodes)) {
|
|
393
463
|
const route = paramChild.trie.getRoute(tail, params);
|
|
394
464
|
if (route) {
|
|
395
465
|
params[paramChild.name] = head;
|
|
@@ -397,9 +467,13 @@ var RouteTrie = class _RouteTrie {
|
|
|
397
467
|
}
|
|
398
468
|
}
|
|
399
469
|
}
|
|
400
|
-
if (this.
|
|
401
|
-
params[this.
|
|
402
|
-
return this.
|
|
470
|
+
if (this.catchAllNodes) {
|
|
471
|
+
params[this.catchAllNodes.name] = urlPath;
|
|
472
|
+
return this.catchAllNodes.route;
|
|
473
|
+
}
|
|
474
|
+
if (this.optCatchAllNodes) {
|
|
475
|
+
params[this.optCatchAllNodes.name] = urlPath;
|
|
476
|
+
return this.optCatchAllNodes.route;
|
|
403
477
|
}
|
|
404
478
|
return void 0;
|
|
405
479
|
}
|
|
@@ -407,7 +481,7 @@ var RouteTrie = class _RouteTrie {
|
|
|
407
481
|
* Normalizes a path for inclusion into the route trie.
|
|
408
482
|
*/
|
|
409
483
|
normalizePath(path2) {
|
|
410
|
-
return path2.replace(/^\/+/g, "");
|
|
484
|
+
return path2.replace(/^\/+/g, "").replace(/\/+$/g, "");
|
|
411
485
|
}
|
|
412
486
|
/**
|
|
413
487
|
* Splits the parent directory from its children, e.g.:
|
|
@@ -422,13 +496,13 @@ var RouteTrie = class _RouteTrie {
|
|
|
422
496
|
return [path2.slice(0, i), path2.slice(i + 1)];
|
|
423
497
|
}
|
|
424
498
|
};
|
|
425
|
-
var
|
|
499
|
+
var ParamNode = class {
|
|
426
500
|
constructor(name) {
|
|
427
501
|
this.trie = new RouteTrie();
|
|
428
502
|
this.name = name;
|
|
429
503
|
}
|
|
430
504
|
};
|
|
431
|
-
var
|
|
505
|
+
var CatchAllNode = class {
|
|
432
506
|
constructor(name, route) {
|
|
433
507
|
this.name = name;
|
|
434
508
|
this.route = route;
|
|
@@ -436,11 +510,11 @@ var WildcardChild = class {
|
|
|
436
510
|
};
|
|
437
511
|
|
|
438
512
|
// src/render/router.ts
|
|
439
|
-
function getRoutes(
|
|
440
|
-
var _a, _b
|
|
441
|
-
const locales = ((_a =
|
|
442
|
-
const
|
|
443
|
-
const defaultLocale = ((
|
|
513
|
+
function getRoutes(rootConfig) {
|
|
514
|
+
var _a, _b;
|
|
515
|
+
const locales = ((_a = rootConfig.i18n) == null ? void 0 : _a.locales) || [];
|
|
516
|
+
const basePath = rootConfig.base || "/";
|
|
517
|
+
const defaultLocale = ((_b = rootConfig.i18n) == null ? void 0 : _b.defaultLocale) || "en";
|
|
444
518
|
const routes = import.meta.glob(
|
|
445
519
|
["/routes/*.ts", "/routes/**/*.ts", "/routes/*.tsx", "/routes/**/*.tsx"],
|
|
446
520
|
{
|
|
@@ -449,39 +523,58 @@ function getRoutes(config) {
|
|
|
449
523
|
);
|
|
450
524
|
const trie = new RouteTrie();
|
|
451
525
|
Object.keys(routes).forEach((modulePath) => {
|
|
526
|
+
var _a2;
|
|
452
527
|
const src = modulePath.slice(1);
|
|
453
|
-
let
|
|
454
|
-
const parts = path.parse(
|
|
528
|
+
let relativeRoutePath = modulePath.replace(/^\/routes/, "");
|
|
529
|
+
const parts = path.parse(relativeRoutePath);
|
|
455
530
|
if (parts.name.startsWith("_")) {
|
|
456
531
|
return;
|
|
457
532
|
}
|
|
458
533
|
if (parts.name === "index") {
|
|
459
|
-
|
|
534
|
+
relativeRoutePath = parts.dir;
|
|
460
535
|
} else {
|
|
461
|
-
|
|
536
|
+
relativeRoutePath = path.join(parts.dir, parts.name);
|
|
462
537
|
}
|
|
463
|
-
const
|
|
538
|
+
const urlFormat = "/[base]/[path]";
|
|
539
|
+
const i18nUrlFormat = toSquareBrackets(
|
|
540
|
+
((_a2 = rootConfig.i18n) == null ? void 0 : _a2.urlFormat) || "/[locale]/[base]/[path]"
|
|
541
|
+
);
|
|
542
|
+
const placeholders = {
|
|
543
|
+
base: removeSlashes(basePath),
|
|
544
|
+
path: removeSlashes(relativeRoutePath)
|
|
545
|
+
};
|
|
546
|
+
const formatUrl = (format) => {
|
|
547
|
+
var _a3;
|
|
548
|
+
const url = format.replaceAll("[base]", placeholders.base).replaceAll("[path]", placeholders.path);
|
|
549
|
+
return normalizeUrlPath(url, {
|
|
550
|
+
trailingSlash: (_a3 = rootConfig.server) == null ? void 0 : _a3.trailingSlash
|
|
551
|
+
});
|
|
552
|
+
};
|
|
553
|
+
const routePath = formatUrl(urlFormat);
|
|
554
|
+
const localeRoutePath = formatUrl(i18nUrlFormat);
|
|
464
555
|
trie.add(routePath, {
|
|
465
556
|
src,
|
|
466
557
|
module: routes[modulePath],
|
|
467
558
|
locale: defaultLocale,
|
|
468
559
|
isDefaultLocale: true,
|
|
469
|
-
routePath
|
|
470
|
-
localeRoutePath
|
|
471
|
-
});
|
|
472
|
-
locales.forEach((locale) => {
|
|
473
|
-
const localePath = localeRoutePath.replace("[locale]", locale);
|
|
474
|
-
if (localePath !== routePath) {
|
|
475
|
-
trie.add(localePath, {
|
|
476
|
-
src,
|
|
477
|
-
module: routes[modulePath],
|
|
478
|
-
locale,
|
|
479
|
-
isDefaultLocale: false,
|
|
480
|
-
routePath,
|
|
481
|
-
localeRoutePath
|
|
482
|
-
});
|
|
483
|
-
}
|
|
560
|
+
routePath,
|
|
561
|
+
localeRoutePath
|
|
484
562
|
});
|
|
563
|
+
if (i18nUrlFormat.includes("[locale]")) {
|
|
564
|
+
locales.forEach((locale) => {
|
|
565
|
+
const localePath = localeRoutePath.replace("[locale]", locale);
|
|
566
|
+
if (localePath !== relativeRoutePath) {
|
|
567
|
+
trie.add(localePath, {
|
|
568
|
+
src,
|
|
569
|
+
module: routes[modulePath],
|
|
570
|
+
locale,
|
|
571
|
+
isDefaultLocale: false,
|
|
572
|
+
routePath,
|
|
573
|
+
localeRoutePath
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
}
|
|
485
578
|
});
|
|
486
579
|
return trie;
|
|
487
580
|
}
|
|
@@ -510,18 +603,24 @@ async function getAllPathsForRoute(urlPathFormat, route) {
|
|
|
510
603
|
}
|
|
511
604
|
);
|
|
512
605
|
}
|
|
513
|
-
} else if (
|
|
606
|
+
} else if (routeModule.getStaticProps && !pathContainsPlaceholders(urlPathFormat)) {
|
|
607
|
+
urlPaths.push({ urlPath: normalizeUrlPath(urlPathFormat), params: {} });
|
|
608
|
+
} else if (!routeModule.handle && !pathContainsPlaceholders(urlPathFormat)) {
|
|
609
|
+
urlPaths.push({ urlPath: normalizeUrlPath(urlPathFormat), params: {} });
|
|
610
|
+
} else if (pathContainsPlaceholders(urlPathFormat) && !routeModule.handle && !routeModule.getStaticPaths) {
|
|
514
611
|
console.warn(
|
|
515
|
-
|
|
612
|
+
[
|
|
613
|
+
`warning: path contains placeholders: ${urlPathFormat}.`,
|
|
614
|
+
`define either ssg getStaticPaths() or ssr handle() for route: ${route.src}.`,
|
|
615
|
+
"more info: https://rootjs.dev/guide/routes"
|
|
616
|
+
].join("\n")
|
|
516
617
|
);
|
|
517
|
-
} else {
|
|
518
|
-
urlPaths.push({ urlPath: normalizeUrlPath(urlPathFormat), params: {} });
|
|
519
618
|
}
|
|
520
619
|
return urlPaths;
|
|
521
620
|
}
|
|
522
621
|
function replaceParams(urlPathFormat, params) {
|
|
523
622
|
const urlPath = urlPathFormat.replaceAll(
|
|
524
|
-
/\[(\.\.\.)?([\w\-_]*)\]/g,
|
|
623
|
+
/\[\[?(\.\.\.)?([\w\-_]*)\]?\]/g,
|
|
525
624
|
(match, _wildcard, key) => {
|
|
526
625
|
const val = params[key];
|
|
527
626
|
if (!val) {
|
|
@@ -532,10 +631,14 @@ function replaceParams(urlPathFormat, params) {
|
|
|
532
631
|
);
|
|
533
632
|
return urlPath;
|
|
534
633
|
}
|
|
535
|
-
function normalizeUrlPath(urlPath) {
|
|
536
|
-
|
|
634
|
+
function normalizeUrlPath(urlPath, options) {
|
|
635
|
+
urlPath = urlPath.replace(/\/+/g, "/");
|
|
636
|
+
if ((options == null ? void 0 : options.trailingSlash) === false && urlPath !== "/" && urlPath.endsWith("/")) {
|
|
537
637
|
urlPath = urlPath.replace(/\/*$/g, "");
|
|
538
638
|
}
|
|
639
|
+
if (!urlPath.startsWith("/")) {
|
|
640
|
+
urlPath = `/${urlPath}`;
|
|
641
|
+
}
|
|
539
642
|
return urlPath;
|
|
540
643
|
}
|
|
541
644
|
function pathContainsPlaceholders(urlPath) {
|
|
@@ -544,6 +647,17 @@ function pathContainsPlaceholders(urlPath) {
|
|
|
544
647
|
return segment.startsWith("[") && segment.endsWith("]");
|
|
545
648
|
});
|
|
546
649
|
}
|
|
650
|
+
function removeSlashes(str) {
|
|
651
|
+
return str.replace(/^\/*/g, "").replace(/\/*$/g, "");
|
|
652
|
+
}
|
|
653
|
+
function toSquareBrackets(str) {
|
|
654
|
+
if (str.includes("{") || str.includes("}")) {
|
|
655
|
+
const val = str.replaceAll("{", "[").replaceAll("}", "]");
|
|
656
|
+
console.warn(`"${str}" is a deprecated format, please switch to "${val}"`);
|
|
657
|
+
return val;
|
|
658
|
+
}
|
|
659
|
+
return str;
|
|
660
|
+
}
|
|
547
661
|
|
|
548
662
|
// src/render/render.tsx
|
|
549
663
|
import { jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
|
|
@@ -555,7 +669,7 @@ var Renderer = class {
|
|
|
555
669
|
this.elementGraph = options.elementGraph;
|
|
556
670
|
}
|
|
557
671
|
async handle(req, res, next) {
|
|
558
|
-
const url = req.path
|
|
672
|
+
const url = req.path;
|
|
559
673
|
const [route, routeParams] = this.routes.get(url);
|
|
560
674
|
if (!route) {
|
|
561
675
|
next();
|
|
@@ -668,7 +782,12 @@ var Renderer = class {
|
|
|
668
782
|
const routeAsset = await this.assetMap.get(route.src);
|
|
669
783
|
if (routeAsset) {
|
|
670
784
|
const routeCssDeps = await routeAsset.getCssDeps();
|
|
671
|
-
routeCssDeps.forEach((dep) =>
|
|
785
|
+
routeCssDeps.forEach((dep) => {
|
|
786
|
+
if (dep.endsWith("?inline")) {
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
cssDeps.add(dep);
|
|
790
|
+
});
|
|
672
791
|
}
|
|
673
792
|
await this.collectElementDeps(mainHtml, jsDeps, cssDeps);
|
|
674
793
|
await Promise.all(
|
|
@@ -903,7 +1022,12 @@ ${renderToString(page)}
|
|
|
903
1022
|
const assetJsDeps = await asset.getJsDeps();
|
|
904
1023
|
assetJsDeps.forEach((dep) => jsDeps.add(dep));
|
|
905
1024
|
const assetCssDeps = await asset.getCssDeps();
|
|
906
|
-
assetCssDeps.forEach((dep) =>
|
|
1025
|
+
assetCssDeps.forEach((dep) => {
|
|
1026
|
+
if (dep.endsWith("?inline")) {
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
cssDeps.add(dep);
|
|
1030
|
+
});
|
|
907
1031
|
})
|
|
908
1032
|
);
|
|
909
1033
|
return { jsDeps, cssDeps };
|