reroute-js 0.45.12-beta.1 → 0.46.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/README.md +100 -2
- package/_/blog/src/client/routes/blog/[layout].tsx +45 -13
- package/_/blog/src/client/routes/blog/content/pt-BR/1-hello-world.tsx +27 -0
- package/_/blog/src/client/routes/index.tsx +4 -4
- package/_/search/src/client/routes/docs/content/content-collections.md +18 -0
- package/cli/bin.d.ts +2 -2
- package/cli/bin.js +980 -337
- package/cli/bin.js.map +29 -21
- package/cli/index.d.ts +2 -2
- package/cli/index.js +5 -5
- package/cli/index.js.map +1 -1
- package/cli/src/cli.d.ts +2 -2
- package/cli/src/commands/analyze.d.ts +2 -2
- package/cli/src/commands/build.d.ts +2 -2
- package/cli/src/commands/dev.d.ts +2 -2
- package/cli/src/commands/gen.d.ts +2 -2
- package/cli/src/commands/gen.d.ts.map +1 -1
- package/cli/src/commands/index.d.ts +2 -2
- package/cli/src/commands/init.d.ts +2 -2
- package/cli/src/commands/lib/assets.d.ts +2 -2
- package/cli/src/commands/lib/bundler.d.ts +2 -2
- package/cli/src/commands/lib/command.d.ts +2 -2
- package/cli/src/commands/lib/env.d.ts +2 -2
- package/cli/src/commands/lib/index.d.ts +2 -2
- package/cli/src/commands/lib/log.d.ts +2 -2
- package/cli/src/commands/lib/markdown/availability.d.ts +2 -2
- package/cli/src/commands/lib/markdown/index.d.ts +2 -2
- package/cli/src/commands/lib/markdown/processor.d.ts +2 -2
- package/cli/src/commands/lib/production.d.ts +2 -2
- package/cli/src/commands/lib/server.d.ts +2 -2
- package/cli/src/commands/lib/streaming/analyzer.d.ts +2 -2
- package/cli/src/commands/lib/streaming/suspense.d.ts +2 -2
- package/cli/src/commands/lib/tailwind.d.ts +2 -2
- package/cli/src/commands/lib/terminal-ui.d.ts +2 -2
- package/cli/src/commands/lib/version.d.ts +2 -2
- package/cli/src/commands/og.d.ts +2 -2
- package/cli/src/commands/start.d.ts +2 -2
- package/cli/src/index.d.ts +2 -2
- package/core/index.d.ts +2 -2
- package/core/index.js +667 -117
- package/core/index.js.map +28 -20
- package/core/src/bundler/hash.d.ts +2 -2
- package/core/src/bundler/index.d.ts +2 -2
- package/core/src/config.d.ts +6 -3
- package/core/src/config.d.ts.map +1 -1
- package/core/src/content/discovery.d.ts +2 -2
- package/core/src/content/index.d.ts +2 -2
- package/core/src/content/metadata.d.ts +2 -2
- package/core/src/i18n/catalog.d.ts +17 -0
- package/core/src/i18n/catalog.d.ts.map +1 -0
- package/core/src/i18n/discover.d.ts +19 -0
- package/core/src/i18n/discover.d.ts.map +1 -0
- package/core/src/i18n/index.d.ts +17 -0
- package/core/src/i18n/index.d.ts.map +1 -0
- package/core/src/i18n/messages.d.ts +18 -0
- package/core/src/i18n/messages.d.ts.map +1 -0
- package/core/src/i18n/negotiate.d.ts +18 -0
- package/core/src/i18n/negotiate.d.ts.map +1 -0
- package/core/src/i18n/pathname.d.ts +34 -0
- package/core/src/i18n/pathname.d.ts.map +1 -0
- package/core/src/i18n/resolve.d.ts +22 -0
- package/core/src/i18n/resolve.d.ts.map +1 -0
- package/core/src/i18n/types.d.ts +68 -0
- package/core/src/i18n/types.d.ts.map +1 -0
- package/core/src/index.d.ts +3 -2
- package/core/src/index.d.ts.map +1 -1
- package/core/src/llms/extractor.d.ts +2 -2
- package/core/src/llms/formatter.d.ts +2 -2
- package/core/src/llms/full-generator.d.ts +2 -2
- package/core/src/llms/index-generator.d.ts +2 -2
- package/core/src/llms/index.d.ts +2 -2
- package/core/src/og/discovery.d.ts +2 -2
- package/core/src/og/index.d.ts +2 -2
- package/core/src/og/meta.d.ts +2 -2
- package/core/src/og/render.d.ts +2 -2
- package/core/src/og/types.d.ts +2 -2
- package/core/src/robots/discovery.d.ts +2 -2
- package/core/src/robots/generator.d.ts +2 -2
- package/core/src/robots/index.d.ts +2 -2
- package/core/src/robots/policies.d.ts +2 -2
- package/core/src/rss/discovery.d.ts +4 -2
- package/core/src/rss/discovery.d.ts.map +1 -1
- package/core/src/rss/generator.d.ts +2 -2
- package/core/src/rss/index.d.ts +2 -2
- package/core/src/sitemap/discovery.d.ts +7 -2
- package/core/src/sitemap/discovery.d.ts.map +1 -1
- package/core/src/sitemap/generator.d.ts +2 -2
- package/core/src/sitemap/generator.d.ts.map +1 -1
- package/core/src/sitemap/index.d.ts +2 -2
- package/core/src/ssr/index.d.ts +2 -2
- package/core/src/ssr/lib/cache.d.ts +2 -2
- package/core/src/ssr/lib/cleanup.d.ts +2 -2
- package/core/src/ssr/lib/collections.d.ts +2 -2
- package/core/src/ssr/lib/compression.d.ts +2 -2
- package/core/src/ssr/lib/compute/content.d.ts +2 -9
- package/core/src/ssr/lib/compute/content.d.ts.map +1 -1
- package/core/src/ssr/lib/compute/index.d.ts +2 -2
- package/core/src/ssr/lib/compute/layouts.d.ts +2 -2
- package/core/src/ssr/lib/compute/routes.d.ts +2 -2
- package/core/src/ssr/lib/compute/routes.d.ts.map +1 -1
- package/core/src/ssr/lib/content-path.d.ts +22 -0
- package/core/src/ssr/lib/content-path.d.ts.map +1 -0
- package/core/src/ssr/lib/data.d.ts +2 -2
- package/core/src/ssr/lib/data.d.ts.map +1 -1
- package/core/src/ssr/lib/html.d.ts +2 -2
- package/core/src/ssr/lib/imports.d.ts +2 -2
- package/core/src/ssr/lib/index.d.ts +2 -2
- package/core/src/ssr/lib/layouts.d.ts +2 -2
- package/core/src/ssr/lib/metadata.d.ts +2 -2
- package/core/src/ssr/lib/metadata.d.ts.map +1 -1
- package/core/src/ssr/lib/mime.d.ts +2 -2
- package/core/src/ssr/lib/modules.d.ts +4 -4
- package/core/src/ssr/lib/modules.d.ts.map +1 -1
- package/core/src/ssr/lib/path.d.ts +2 -2
- package/core/src/ssr/lib/preload.d.ts +2 -2
- package/core/src/ssr/lib/preload.d.ts.map +1 -1
- package/core/src/ssr/lib/route-match.d.ts +2 -2
- package/core/src/ssr/lib/scripts/collections.d.ts +2 -2
- package/core/src/ssr/lib/scripts/data.d.ts +3 -3
- package/core/src/ssr/lib/scripts/data.d.ts.map +1 -1
- package/core/src/ssr/lib/scripts/escape.d.ts +2 -2
- package/core/src/ssr/lib/scripts/feeds.d.ts +2 -2
- package/core/src/ssr/lib/scripts/index.d.ts +2 -2
- package/core/src/ssr/lib/seed.d.ts +2 -2
- package/core/src/ssr/lib/seed.d.ts.map +1 -1
- package/core/src/ssr/lib/serialize.d.ts +2 -2
- package/core/src/ssr/lib/setup.d.ts +3 -3
- package/core/src/ssr/lib/setup.d.ts.map +1 -1
- package/core/src/ssr/lib/styles.d.ts +2 -2
- package/core/src/ssr/lib/template.d.ts +2 -2
- package/core/src/ssr/lib/types.d.ts +2 -2
- package/core/src/ssr/render.d.ts +4 -2
- package/core/src/ssr/render.d.ts.map +1 -1
- package/core/src/ssr/stream.d.ts +4 -2
- package/core/src/ssr/stream.d.ts.map +1 -1
- package/elysia/index.d.ts +2 -2
- package/elysia/index.js +872 -177
- package/elysia/index.js.map +32 -23
- package/elysia/src/index.d.ts +2 -2
- package/elysia/src/libs/assets.d.ts +2 -2
- package/elysia/src/libs/cache.d.ts +2 -2
- package/elysia/src/libs/caching.d.ts +2 -2
- package/elysia/src/libs/http.d.ts +2 -2
- package/elysia/src/libs/i18n.d.ts +26 -0
- package/elysia/src/libs/i18n.d.ts.map +1 -0
- package/elysia/src/libs/image.d.ts +2 -2
- package/elysia/src/libs/index.d.ts +2 -2
- package/elysia/src/libs/llms.d.ts +2 -2
- package/elysia/src/libs/response.d.ts +2 -2
- package/elysia/src/libs/serving.d.ts +2 -2
- package/elysia/src/plugin.d.ts +2 -2
- package/elysia/src/routes/artifacts.d.ts +2 -2
- package/elysia/src/routes/content.d.ts +2 -2
- package/elysia/src/routes/image.d.ts +2 -2
- package/elysia/src/routes/index.d.ts +2 -2
- package/elysia/src/routes/internal.d.ts +2 -2
- package/elysia/src/routes/llms.d.ts +2 -2
- package/elysia/src/routes/og.d.ts +2 -2
- package/elysia/src/routes/redirects.d.ts +2 -2
- package/elysia/src/routes/robots.d.ts +2 -2
- package/elysia/src/routes/rss.d.ts +2 -2
- package/elysia/src/routes/rss.d.ts.map +1 -1
- package/elysia/src/routes/search.d.ts +2 -2
- package/elysia/src/routes/search.d.ts.map +1 -1
- package/elysia/src/routes/sitemap.d.ts +2 -2
- package/elysia/src/routes/ssr.d.ts +2 -2
- package/elysia/src/routes/ssr.d.ts.map +1 -1
- package/elysia/src/routes/static.d.ts +2 -2
- package/elysia/src/types.d.ts +2 -2
- package/package.json +7 -6
- package/react/index.d.ts +2 -2
- package/react/index.js +560 -170
- package/react/index.js.map +12 -10
- package/react/src/components/ClientOnly.d.ts +2 -2
- package/react/src/components/ContentRoute.d.ts +3 -3
- package/react/src/components/ContentRoute.d.ts.map +1 -1
- package/react/src/components/Image.d.ts +2 -2
- package/react/src/components/LazyRoute.d.ts +2 -2
- package/react/src/components/Link.d.ts +2 -2
- package/react/src/components/Link.d.ts.map +1 -1
- package/react/src/components/Markdown.d.ts +2 -2
- package/react/src/components/Outlet.d.ts +2 -2
- package/react/src/components/index.d.ts +2 -2
- package/react/src/hooks/index.d.ts +2 -2
- package/react/src/hooks/useContent.d.ts +2 -2
- package/react/src/hooks/useContent.d.ts.map +1 -1
- package/react/src/hooks/useData.d.ts +2 -2
- package/react/src/hooks/useFeed.d.ts +2 -2
- package/react/src/hooks/useLayoutData.d.ts +2 -2
- package/react/src/hooks/useLlms.d.ts +2 -2
- package/react/src/hooks/useNavigate.d.ts +2 -2
- package/react/src/hooks/useParams.d.ts +2 -2
- package/react/src/hooks/useRouter.d.ts +2 -2
- package/react/src/hooks/useSearch.d.ts +2 -2
- package/react/src/hooks/useSearch.d.ts.map +1 -1
- package/react/src/hooks/useSearchParams.d.ts +2 -2
- package/react/src/hooks/useToc.d.ts +2 -2
- package/react/src/i18n/LocaleProvider.d.ts +49 -0
- package/react/src/i18n/LocaleProvider.d.ts.map +1 -0
- package/react/src/i18n/helpers.d.ts +24 -0
- package/react/src/i18n/helpers.d.ts.map +1 -0
- package/react/src/i18n/index.d.ts +13 -0
- package/react/src/i18n/index.d.ts.map +1 -0
- package/react/src/index.d.ts +3 -2
- package/react/src/index.d.ts.map +1 -1
- package/react/src/lib/collection.d.ts +2 -2
- package/react/src/lib/content.d.ts +4 -3
- package/react/src/lib/content.d.ts.map +1 -1
- package/react/src/lib/head.d.ts +2 -2
- package/react/src/lib/index.d.ts +2 -2
- package/react/src/lib/lazy-route.d.ts +2 -2
- package/react/src/lib/route-loader.d.ts +2 -2
- package/react/src/providers/ContentProvider.d.ts +3 -3
- package/react/src/providers/ContentProvider.d.ts.map +1 -1
- package/react/src/providers/RerouteProvider.d.ts +8 -6
- package/react/src/providers/RerouteProvider.d.ts.map +1 -1
- package/react/src/providers/RouterProvider.d.ts +2 -2
- package/react/src/providers/index.d.ts +2 -2
- package/react/src/types/any.d.ts +2 -2
- package/react/src/types/index.d.ts +2 -2
- package/react/src/types/router.d.ts +2 -2
- package/telemetry/react.d.ts +2 -2
- package/telemetry/react.js +3 -3
- package/telemetry/react.js.map +1 -1
- package/telemetry/server.d.ts +2 -2
- package/telemetry/server.js +56 -4
- package/telemetry/server.js.map +20 -15
- package/telemetry/src/react/api.d.ts +2 -2
- package/telemetry/src/react/context.d.ts +2 -2
- package/telemetry/src/react/index.d.ts +2 -2
- package/telemetry/src/react/telemetry.d.ts +2 -2
- package/telemetry/src/server/context.d.ts +2 -2
- package/telemetry/src/server/headers/extractor.d.ts +2 -2
- package/telemetry/src/server/headers/index.d.ts +2 -2
- package/telemetry/src/server/headers/presets.d.ts +2 -2
- package/telemetry/src/server/index.d.ts +2 -2
- package/telemetry/src/server/instrumentation.d.ts +2 -2
- package/telemetry/src/server/plugin.d.ts +2 -2
- package/telemetry/src/server/sourcemap.d.ts +2 -2
package/cli/bin.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
3
|
/**
|
|
4
|
-
* reroute-js v0.
|
|
4
|
+
* reroute-js v0.46.0
|
|
5
5
|
*
|
|
6
6
|
* @license MIT
|
|
7
7
|
* @copyright 2026 stewones <hi@stewan.io>
|
|
8
|
-
* @see https://github.com/
|
|
8
|
+
* @see https://github.com/Intenseloop/reroute
|
|
9
9
|
*
|
|
10
10
|
* Built with Bun <3
|
|
11
11
|
*/
|
|
@@ -66,7 +66,7 @@ async function getVersionString() {
|
|
|
66
66
|
}
|
|
67
67
|
async function getVersion() {
|
|
68
68
|
if (true) {
|
|
69
|
-
return "0.
|
|
69
|
+
return "0.46.0";
|
|
70
70
|
}
|
|
71
71
|
const possiblePaths = [
|
|
72
72
|
path.join(import.meta.dir, "../../../../package.json"),
|
|
@@ -84,7 +84,7 @@ async function getVersion() {
|
|
|
84
84
|
}
|
|
85
85
|
async function getCommit() {
|
|
86
86
|
if (true) {
|
|
87
|
-
return "
|
|
87
|
+
return "9116acf";
|
|
88
88
|
}
|
|
89
89
|
return "dev";
|
|
90
90
|
}
|
|
@@ -536,6 +536,364 @@ var init_content = __esm(() => {
|
|
|
536
536
|
init_metadata();
|
|
537
537
|
});
|
|
538
538
|
|
|
539
|
+
// packages/core/src/i18n/catalog.ts
|
|
540
|
+
function getMessage(catalog, key) {
|
|
541
|
+
if (!(catalog && key))
|
|
542
|
+
return;
|
|
543
|
+
const parts = key.split(".");
|
|
544
|
+
let current = catalog;
|
|
545
|
+
for (const part of parts) {
|
|
546
|
+
if (current == null || typeof current === "string")
|
|
547
|
+
return;
|
|
548
|
+
current = current[part];
|
|
549
|
+
}
|
|
550
|
+
return typeof current === "string" ? current : undefined;
|
|
551
|
+
}
|
|
552
|
+
function lookupMessage(catalogs, locale, defaultLocale, key) {
|
|
553
|
+
return getMessage(catalogs[locale], key) ?? (locale !== defaultLocale ? getMessage(catalogs[defaultLocale], key) : undefined);
|
|
554
|
+
}
|
|
555
|
+
var init_catalog = () => {};
|
|
556
|
+
|
|
557
|
+
// packages/core/src/i18n/discover.ts
|
|
558
|
+
import { readdir as readdir3 } from "node:fs/promises";
|
|
559
|
+
import { join as join3 } from "node:path";
|
|
560
|
+
async function loadCatalog(filePath) {
|
|
561
|
+
try {
|
|
562
|
+
const text = await Bun.file(filePath).text();
|
|
563
|
+
return JSON.parse(text);
|
|
564
|
+
} catch {
|
|
565
|
+
return null;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
async function loadLocaleCatalogs(absDir) {
|
|
569
|
+
const entries = await readdir3(absDir, { withFileTypes: true });
|
|
570
|
+
const catalogs = {};
|
|
571
|
+
const locales = [];
|
|
572
|
+
for (const entry of entries) {
|
|
573
|
+
if (!(entry.isFile() && entry.name.endsWith(".json")))
|
|
574
|
+
continue;
|
|
575
|
+
const locale = entry.name.slice(0, -".json".length);
|
|
576
|
+
if (!locale)
|
|
577
|
+
continue;
|
|
578
|
+
const catalog = await loadCatalog(join3(absDir, entry.name));
|
|
579
|
+
if (!catalog)
|
|
580
|
+
continue;
|
|
581
|
+
catalogs[locale] = catalog;
|
|
582
|
+
locales.push(locale);
|
|
583
|
+
}
|
|
584
|
+
return { catalogs, locales };
|
|
585
|
+
}
|
|
586
|
+
function sortLocales(locales, defaultLocale) {
|
|
587
|
+
locales.sort((a, b) => {
|
|
588
|
+
if (a === defaultLocale)
|
|
589
|
+
return -1;
|
|
590
|
+
if (b === defaultLocale)
|
|
591
|
+
return 1;
|
|
592
|
+
return a.localeCompare(b);
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
async function discoverI18n(cwd, options = {}) {
|
|
596
|
+
const localesDir = options.localesDir ?? DEFAULT_LOCALES_DIR;
|
|
597
|
+
const defaultLocale = options.defaultLocale ?? DEFAULT_LOCALE;
|
|
598
|
+
const cookie = options.cookie ?? DEFAULT_COOKIE;
|
|
599
|
+
const redirectContentOnNegotiate = options.redirectContentOnNegotiate ?? true;
|
|
600
|
+
const absDir = join3(cwd, localesDir);
|
|
601
|
+
const disabled = {
|
|
602
|
+
enabled: false,
|
|
603
|
+
defaultLocale,
|
|
604
|
+
locales: [],
|
|
605
|
+
localesDir,
|
|
606
|
+
cookie,
|
|
607
|
+
redirectContentOnNegotiate,
|
|
608
|
+
catalogs: {}
|
|
609
|
+
};
|
|
610
|
+
let catalogs;
|
|
611
|
+
let locales;
|
|
612
|
+
try {
|
|
613
|
+
({ catalogs, locales } = await loadLocaleCatalogs(absDir));
|
|
614
|
+
} catch {
|
|
615
|
+
return disabled;
|
|
616
|
+
}
|
|
617
|
+
if (locales.length === 0) {
|
|
618
|
+
return disabled;
|
|
619
|
+
}
|
|
620
|
+
sortLocales(locales, defaultLocale);
|
|
621
|
+
if (!catalogs[defaultLocale]) {
|
|
622
|
+
console.warn(`[reroute/i18n] defaultLocale "${defaultLocale}" has no catalog; using "${locales[0]}"`);
|
|
623
|
+
}
|
|
624
|
+
return {
|
|
625
|
+
enabled: true,
|
|
626
|
+
defaultLocale: catalogs[defaultLocale] ? defaultLocale : locales[0],
|
|
627
|
+
locales,
|
|
628
|
+
localesDir,
|
|
629
|
+
cookie,
|
|
630
|
+
redirectContentOnNegotiate,
|
|
631
|
+
catalogs
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
var DEFAULT_LOCALE = "en-US", DEFAULT_LOCALES_DIR = "locales", DEFAULT_COOKIE = "reroute-locale";
|
|
635
|
+
var init_discover = () => {};
|
|
636
|
+
|
|
637
|
+
// packages/core/src/i18n/messages.ts
|
|
638
|
+
import { IntlMessageFormat } from "intl-messageformat";
|
|
639
|
+
function formatMessage(message, locale, values) {
|
|
640
|
+
if (!values || Object.keys(values).length === 0) {
|
|
641
|
+
if (!/\{[^}]+\}/.test(message))
|
|
642
|
+
return message;
|
|
643
|
+
}
|
|
644
|
+
const cacheKey = `${locale}\x00${message}`;
|
|
645
|
+
let formatter = formatterCache.get(cacheKey);
|
|
646
|
+
if (!formatter) {
|
|
647
|
+
formatter = new IntlMessageFormat(message, locale);
|
|
648
|
+
formatterCache.set(cacheKey, formatter);
|
|
649
|
+
}
|
|
650
|
+
try {
|
|
651
|
+
const result = formatter.format(values);
|
|
652
|
+
return typeof result === "string" ? result : String(result);
|
|
653
|
+
} catch {
|
|
654
|
+
return message;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
function createTranslator(catalogs, locale, defaultLocale) {
|
|
658
|
+
return (key, values) => {
|
|
659
|
+
const message = lookupMessage(catalogs, locale, defaultLocale, key);
|
|
660
|
+
if (message == null)
|
|
661
|
+
return key;
|
|
662
|
+
return formatMessage(message, locale, values);
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
var formatterCache;
|
|
666
|
+
var init_messages = __esm(() => {
|
|
667
|
+
init_catalog();
|
|
668
|
+
formatterCache = new Map;
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
// packages/core/src/i18n/negotiate.ts
|
|
672
|
+
function negotiateLocale(acceptLanguage, availableLocales, defaultLocale) {
|
|
673
|
+
if (!availableLocales.length)
|
|
674
|
+
return defaultLocale;
|
|
675
|
+
if (!acceptLanguage)
|
|
676
|
+
return defaultLocale;
|
|
677
|
+
const availableLower = new Map(availableLocales.map((l) => [l.toLowerCase(), l]));
|
|
678
|
+
const byLang = new Map;
|
|
679
|
+
for (const locale of availableLocales) {
|
|
680
|
+
const lang = locale.split("-")[0].toLowerCase();
|
|
681
|
+
if (!byLang.has(lang))
|
|
682
|
+
byLang.set(lang, locale);
|
|
683
|
+
}
|
|
684
|
+
const ranges = acceptLanguage.split(",").map((part) => {
|
|
685
|
+
const [tag, ...params] = part.trim().split(";");
|
|
686
|
+
let q = 1;
|
|
687
|
+
for (const p of params) {
|
|
688
|
+
const [k, v] = p.trim().split("=");
|
|
689
|
+
if (k === "q" && v)
|
|
690
|
+
q = Number.parseFloat(v) || 0;
|
|
691
|
+
}
|
|
692
|
+
return { tag: tag.trim().toLowerCase(), q };
|
|
693
|
+
}).filter((r) => r.tag && r.q > 0).sort((a, b) => b.q - a.q);
|
|
694
|
+
for (const { tag } of ranges) {
|
|
695
|
+
if (tag === "*")
|
|
696
|
+
return defaultLocale;
|
|
697
|
+
const exact = availableLower.get(tag);
|
|
698
|
+
if (exact)
|
|
699
|
+
return exact;
|
|
700
|
+
const langOnly = byLang.get(tag.split("-")[0]);
|
|
701
|
+
if (langOnly)
|
|
702
|
+
return langOnly;
|
|
703
|
+
}
|
|
704
|
+
return defaultLocale;
|
|
705
|
+
}
|
|
706
|
+
function parseCookieValue(cookieHeader, name) {
|
|
707
|
+
if (!cookieHeader)
|
|
708
|
+
return;
|
|
709
|
+
const parts = cookieHeader.split(";");
|
|
710
|
+
for (const part of parts) {
|
|
711
|
+
const idx = part.indexOf("=");
|
|
712
|
+
if (idx === -1)
|
|
713
|
+
continue;
|
|
714
|
+
const key = part.slice(0, idx).trim();
|
|
715
|
+
if (key === name) {
|
|
716
|
+
return decodeURIComponent(part.slice(idx + 1).trim());
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
function buildLocaleCookie(name, locale, maxAgeSeconds = 60 * 60 * 24 * 365) {
|
|
722
|
+
return `${name}=${encodeURIComponent(locale)}; Path=/; Max-Age=${maxAgeSeconds}; SameSite=Lax`;
|
|
723
|
+
}
|
|
724
|
+
var init_negotiate = () => {};
|
|
725
|
+
|
|
726
|
+
// packages/core/src/i18n/pathname.ts
|
|
727
|
+
var exports_pathname = {};
|
|
728
|
+
__export(exports_pathname, {
|
|
729
|
+
toOgLocale: () => toOgLocale,
|
|
730
|
+
parseContentPath: () => parseContentPath,
|
|
731
|
+
normalizePathname: () => normalizePathname,
|
|
732
|
+
looksLikeLocale: () => looksLikeLocale,
|
|
733
|
+
localizeHref: () => localizeHref,
|
|
734
|
+
localizeContentHref: () => localizeContentHref,
|
|
735
|
+
hreflangTags: () => hreflangTags,
|
|
736
|
+
contentKey: () => contentKey
|
|
737
|
+
});
|
|
738
|
+
function looksLikeLocale(segment) {
|
|
739
|
+
return /^[a-z]{2}(?:-[A-Za-z0-9]{2,8})*$/i.test(segment);
|
|
740
|
+
}
|
|
741
|
+
function normalizePathname(pathname) {
|
|
742
|
+
const pathOnly = pathname.split("?")[0].split("#")[0];
|
|
743
|
+
if (!pathOnly || pathOnly === "/")
|
|
744
|
+
return "/";
|
|
745
|
+
return pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
|
|
746
|
+
}
|
|
747
|
+
function parseContentPath(pathname, availableLocales = [], collections) {
|
|
748
|
+
const normalized = normalizePathname(pathname);
|
|
749
|
+
const parts = normalized.split("/").filter(Boolean);
|
|
750
|
+
if (parts.length < 2)
|
|
751
|
+
return;
|
|
752
|
+
const [collection, second, third] = parts;
|
|
753
|
+
if (collections && !collections.includes(collection)) {
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
const localeSet = new Set(availableLocales.map((l) => l.toLowerCase()));
|
|
757
|
+
if (parts.length >= 3 && third) {
|
|
758
|
+
const secondIsLocale = localeSet.size > 0 ? localeSet.has(second.toLowerCase()) : looksLikeLocale(second);
|
|
759
|
+
if (secondIsLocale) {
|
|
760
|
+
const locale = availableLocales.find((l) => l.toLowerCase() === second.toLowerCase()) || second;
|
|
761
|
+
return {
|
|
762
|
+
collection,
|
|
763
|
+
name: third,
|
|
764
|
+
locale,
|
|
765
|
+
routingPathname: `/${collection}/${third}`,
|
|
766
|
+
pathname: normalized
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
return {
|
|
771
|
+
collection,
|
|
772
|
+
name: second,
|
|
773
|
+
routingPathname: `/${collection}/${second}`,
|
|
774
|
+
pathname: normalized
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
function localizeContentHref(collection, name, locale, defaultLocale) {
|
|
778
|
+
if (!locale || locale === defaultLocale) {
|
|
779
|
+
return `/${collection}/${name}`;
|
|
780
|
+
}
|
|
781
|
+
return `/${collection}/${locale}/${name}`;
|
|
782
|
+
}
|
|
783
|
+
function localizeHref(to, locale, defaultLocale, availableLocales = [], collections) {
|
|
784
|
+
try {
|
|
785
|
+
const url = new URL(to, "http://local");
|
|
786
|
+
const parsed = parseContentPath(url.pathname, availableLocales, collections);
|
|
787
|
+
if (!parsed)
|
|
788
|
+
return to;
|
|
789
|
+
url.pathname = localizeContentHref(parsed.collection, parsed.name, locale, defaultLocale);
|
|
790
|
+
return `${url.pathname}${url.search}${url.hash}`;
|
|
791
|
+
} catch {
|
|
792
|
+
return to;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
function contentKey(collection, name, locale, defaultLocale = "en-US") {
|
|
796
|
+
if (locale && locale !== defaultLocale) {
|
|
797
|
+
return `${collection}:${name}:${locale}`;
|
|
798
|
+
}
|
|
799
|
+
return `${collection}:${name}`;
|
|
800
|
+
}
|
|
801
|
+
function toOgLocale(locale) {
|
|
802
|
+
return locale.replace(/-/g, "_");
|
|
803
|
+
}
|
|
804
|
+
function hreflangTags(baseUrl, collection, name, locales, defaultLocale) {
|
|
805
|
+
const base = baseUrl.replace(/\/$/, "");
|
|
806
|
+
const tags = [];
|
|
807
|
+
for (const locale of locales) {
|
|
808
|
+
const path2 = localizeContentHref(collection, name, locale, defaultLocale);
|
|
809
|
+
tags.push(`<link rel="alternate" hreflang="${locale}" href="${base}${path2}" />`);
|
|
810
|
+
}
|
|
811
|
+
const defaultPath = localizeContentHref(collection, name, defaultLocale, defaultLocale);
|
|
812
|
+
tags.push(`<link rel="alternate" hreflang="x-default" href="${base}${defaultPath}" />`);
|
|
813
|
+
return tags.join(`
|
|
814
|
+
`);
|
|
815
|
+
}
|
|
816
|
+
var init_pathname = () => {};
|
|
817
|
+
|
|
818
|
+
// packages/core/src/i18n/resolve.ts
|
|
819
|
+
function resolveLocale(input) {
|
|
820
|
+
const {
|
|
821
|
+
pathname,
|
|
822
|
+
cookieHeader,
|
|
823
|
+
acceptLanguage,
|
|
824
|
+
availableLocales,
|
|
825
|
+
defaultLocale,
|
|
826
|
+
cookieName = DEFAULT_COOKIE,
|
|
827
|
+
collections
|
|
828
|
+
} = input;
|
|
829
|
+
const parsed = parseContentPath(pathname, availableLocales, collections);
|
|
830
|
+
const availableLower = new Set(availableLocales.map((l) => l.toLowerCase()));
|
|
831
|
+
const isAvailable = (locale) => !!locale && availableLower.has(locale.toLowerCase());
|
|
832
|
+
if (parsed?.locale && isAvailable(parsed.locale)) {
|
|
833
|
+
const locale = availableLocales.find((l) => l.toLowerCase() === parsed.locale?.toLowerCase()) || parsed.locale;
|
|
834
|
+
if (locale === defaultLocale && parsed.pathname !== parsed.routingPathname) {
|
|
835
|
+
return {
|
|
836
|
+
locale,
|
|
837
|
+
routingPathname: parsed.routingPathname,
|
|
838
|
+
fromPath: true,
|
|
839
|
+
redirectTo: parsed.routingPathname,
|
|
840
|
+
parsed: { ...parsed, locale }
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
return {
|
|
844
|
+
locale,
|
|
845
|
+
routingPathname: parsed.routingPathname,
|
|
846
|
+
fromPath: true,
|
|
847
|
+
parsed: { ...parsed, locale }
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
const routingPathname = parsed?.routingPathname ?? pathname.split("?")[0];
|
|
851
|
+
const cookieLocale = parseCookieValue(cookieHeader, cookieName);
|
|
852
|
+
if (isAvailable(cookieLocale)) {
|
|
853
|
+
const locale = availableLocales.find((l) => l.toLowerCase() === cookieLocale.toLowerCase()) || cookieLocale;
|
|
854
|
+
return {
|
|
855
|
+
locale,
|
|
856
|
+
routingPathname,
|
|
857
|
+
fromPath: false,
|
|
858
|
+
parsed: parsed ? { ...parsed, locale: undefined } : undefined
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
const negotiated = negotiateLocale(acceptLanguage, availableLocales, defaultLocale);
|
|
862
|
+
return {
|
|
863
|
+
locale: negotiated,
|
|
864
|
+
routingPathname,
|
|
865
|
+
fromPath: false,
|
|
866
|
+
parsed: parsed ? { ...parsed, locale: undefined } : undefined
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
function contentNegotiateRedirect(resolution, defaultLocale, enabled) {
|
|
870
|
+
if (!enabled)
|
|
871
|
+
return;
|
|
872
|
+
if (resolution.fromPath)
|
|
873
|
+
return;
|
|
874
|
+
if (resolution.locale === defaultLocale)
|
|
875
|
+
return;
|
|
876
|
+
const parsed = resolution.parsed;
|
|
877
|
+
if (!parsed)
|
|
878
|
+
return;
|
|
879
|
+
return localizeContentHref(parsed.collection, parsed.name, resolution.locale, defaultLocale);
|
|
880
|
+
}
|
|
881
|
+
var init_resolve = __esm(() => {
|
|
882
|
+
init_discover();
|
|
883
|
+
init_negotiate();
|
|
884
|
+
init_pathname();
|
|
885
|
+
});
|
|
886
|
+
|
|
887
|
+
// packages/core/src/i18n/index.ts
|
|
888
|
+
var init_i18n = __esm(() => {
|
|
889
|
+
init_catalog();
|
|
890
|
+
init_discover();
|
|
891
|
+
init_messages();
|
|
892
|
+
init_negotiate();
|
|
893
|
+
init_pathname();
|
|
894
|
+
init_resolve();
|
|
895
|
+
});
|
|
896
|
+
|
|
539
897
|
// packages/telemetry/src/server/context.ts
|
|
540
898
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
541
899
|
var contextStorage;
|
|
@@ -1227,6 +1585,51 @@ function matchRoutes(routes, pathname) {
|
|
|
1227
1585
|
return null;
|
|
1228
1586
|
}
|
|
1229
1587
|
|
|
1588
|
+
// packages/core/src/ssr/lib/content-path.ts
|
|
1589
|
+
var exports_content_path = {};
|
|
1590
|
+
__export(exports_content_path, {
|
|
1591
|
+
resolveContentPathParts: () => resolveContentPathParts
|
|
1592
|
+
});
|
|
1593
|
+
function resolveContentPathParts(pathname) {
|
|
1594
|
+
const pathOnly = pathname.split("?")[0].split("#")[0];
|
|
1595
|
+
const parts = pathOnly.split("/").filter(Boolean);
|
|
1596
|
+
if (parts.length < 2)
|
|
1597
|
+
return null;
|
|
1598
|
+
const g = globalThis;
|
|
1599
|
+
const locales = g.__REROUTE_I18N__?.locales || [];
|
|
1600
|
+
const defaultLocale = g.__REROUTE_I18N__?.defaultLocale || "en-US";
|
|
1601
|
+
const parsed = parseContentPath(pathOnly, locales);
|
|
1602
|
+
if (parsed) {
|
|
1603
|
+
const locale = parsed.locale || defaultLocale;
|
|
1604
|
+
return {
|
|
1605
|
+
collection: parsed.collection,
|
|
1606
|
+
name: parsed.name,
|
|
1607
|
+
locale: parsed.locale,
|
|
1608
|
+
key: contentKey(parsed.collection, parsed.name, locale, defaultLocale),
|
|
1609
|
+
routingPathname: parsed.routingPathname
|
|
1610
|
+
};
|
|
1611
|
+
}
|
|
1612
|
+
if (parts.length >= 3 && looksLikeLocale(parts[1])) {
|
|
1613
|
+
const locale = parts[1];
|
|
1614
|
+
return {
|
|
1615
|
+
collection: parts[0],
|
|
1616
|
+
name: parts[2],
|
|
1617
|
+
locale,
|
|
1618
|
+
key: contentKey(parts[0], parts[2], locale, defaultLocale),
|
|
1619
|
+
routingPathname: `/${parts[0]}/${parts[2]}`
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1622
|
+
return {
|
|
1623
|
+
collection: parts[0],
|
|
1624
|
+
name: parts[1],
|
|
1625
|
+
key: `${parts[0]}:${parts[1]}`,
|
|
1626
|
+
routingPathname: `/${parts[0]}/${parts[1]}`
|
|
1627
|
+
};
|
|
1628
|
+
}
|
|
1629
|
+
var init_content_path = __esm(() => {
|
|
1630
|
+
init_pathname();
|
|
1631
|
+
});
|
|
1632
|
+
|
|
1230
1633
|
// packages/core/src/ssr/lib/compute/content.ts
|
|
1231
1634
|
function checkStatusCache(statusCacheKey, maxAgeMs) {
|
|
1232
1635
|
if (maxAgeMs <= 0)
|
|
@@ -1279,6 +1682,14 @@ async function handleNonStreamingMode(ssrData, pathname, task, cacheKey, statusC
|
|
|
1279
1682
|
}
|
|
1280
1683
|
return result;
|
|
1281
1684
|
}
|
|
1685
|
+
async function runContentDataTask(streaming, ssrData, pathname, task, set, cacheKey, statusCacheKey, maxAgeMs, pendingTasks) {
|
|
1686
|
+
if (streaming) {
|
|
1687
|
+
handleStreamingMode(ssrData, pathname, task, set, cacheKey, statusCacheKey, maxAgeMs, pendingTasks);
|
|
1688
|
+
} else {
|
|
1689
|
+
await handleNonStreamingMode(ssrData, pathname, task, cacheKey, statusCacheKey, maxAgeMs);
|
|
1690
|
+
}
|
|
1691
|
+
return set.status !== 200 ? set.status : undefined;
|
|
1692
|
+
}
|
|
1282
1693
|
async function computeContentData(pathname, options, searchParams, sharedSsrData) {
|
|
1283
1694
|
const streaming = options.streaming === true;
|
|
1284
1695
|
const ssrData = streaming && sharedSsrData ? sharedSsrData : {};
|
|
@@ -1288,18 +1699,20 @@ async function computeContentData(pathname, options, searchParams, sharedSsrData
|
|
|
1288
1699
|
const maxAge = options.maxAge || 0;
|
|
1289
1700
|
const maxAgeMs = maxAge * 1000;
|
|
1290
1701
|
try {
|
|
1291
|
-
const
|
|
1292
|
-
if (
|
|
1702
|
+
const resolved = resolveContentPathParts(pathname);
|
|
1703
|
+
if (!resolved) {
|
|
1293
1704
|
return { data: ssrData, pendingTasks };
|
|
1294
1705
|
}
|
|
1706
|
+
const parts = [resolved.collection, resolved.name];
|
|
1707
|
+
if (resolved.locale)
|
|
1708
|
+
parts.splice(1, 0, resolved.locale);
|
|
1295
1709
|
const g = globalThis;
|
|
1296
|
-
const
|
|
1297
|
-
const exp = g.__REROUTE_SSR_EXPORTS__?.[key];
|
|
1710
|
+
const exp = g.__REROUTE_SSR_EXPORTS__?.[resolved.key];
|
|
1298
1711
|
const dataFn = exp?.ssr?.data;
|
|
1299
1712
|
if (typeof dataFn !== "function") {
|
|
1300
1713
|
return { data: ssrData, pendingTasks };
|
|
1301
1714
|
}
|
|
1302
|
-
const cacheKey = `content:${pathname}:${
|
|
1715
|
+
const cacheKey = `content:${pathname}:${resolved.name}:${resolved.locale || ""}`;
|
|
1303
1716
|
const statusCacheKey = `status:${cacheKey}`;
|
|
1304
1717
|
const cachedStatus = checkStatusCache(statusCacheKey, maxAgeMs);
|
|
1305
1718
|
if (cachedStatus && cachedStatus !== 200) {
|
|
@@ -1312,22 +1725,13 @@ async function computeContentData(pathname, options, searchParams, sharedSsrData
|
|
|
1312
1725
|
}
|
|
1313
1726
|
const set = { status: 200 };
|
|
1314
1727
|
const task = createDataTask(dataFn, pathname, parts, searchParams, set, options.headers);
|
|
1315
|
-
|
|
1316
|
-
handleStreamingMode(ssrData, pathname, task, set, cacheKey, statusCacheKey, maxAgeMs, pendingTasks);
|
|
1317
|
-
if (set.status !== 200) {
|
|
1318
|
-
statusOverride = set.status;
|
|
1319
|
-
}
|
|
1320
|
-
} else {
|
|
1321
|
-
await handleNonStreamingMode(ssrData, pathname, task, cacheKey, statusCacheKey, maxAgeMs);
|
|
1322
|
-
if (set.status !== 200) {
|
|
1323
|
-
statusOverride = set.status;
|
|
1324
|
-
}
|
|
1325
|
-
}
|
|
1728
|
+
statusOverride = await runContentDataTask(streaming, ssrData, pathname, task, set, cacheKey, statusCacheKey, maxAgeMs, pendingTasks) ?? statusOverride;
|
|
1326
1729
|
} catch {}
|
|
1327
1730
|
return { data: ssrData, error, statusOverride, pendingTasks };
|
|
1328
1731
|
}
|
|
1329
1732
|
var init_content2 = __esm(() => {
|
|
1330
1733
|
init_cache();
|
|
1734
|
+
init_content_path();
|
|
1331
1735
|
init_imports();
|
|
1332
1736
|
});
|
|
1333
1737
|
|
|
@@ -1526,7 +1930,8 @@ async function computeRouteData(pathname, clientDir, _cwd, isWatchMode, options,
|
|
|
1526
1930
|
}).catch(() => {}));
|
|
1527
1931
|
};
|
|
1528
1932
|
try {
|
|
1529
|
-
const
|
|
1933
|
+
const resolved = resolveContentPathParts(pathname);
|
|
1934
|
+
const pathnameOnly = (resolved?.routingPathname || pathname).split("?")[0];
|
|
1530
1935
|
const match = typeof routesModule?.matchRoute === "function" ? routesModule.matchRoute(pathnameOnly) : null;
|
|
1531
1936
|
const route = match?.route;
|
|
1532
1937
|
const params = match?.params || {};
|
|
@@ -1689,6 +2094,7 @@ function handleFlattenedResult(entries, set, ctx, cache, setError, setStatus) {
|
|
|
1689
2094
|
}
|
|
1690
2095
|
var init_routes = __esm(() => {
|
|
1691
2096
|
init_cache();
|
|
2097
|
+
init_content_path();
|
|
1692
2098
|
init_imports();
|
|
1693
2099
|
});
|
|
1694
2100
|
|
|
@@ -1781,33 +2187,31 @@ var init_compute = __esm(() => {
|
|
|
1781
2187
|
});
|
|
1782
2188
|
|
|
1783
2189
|
// packages/core/src/ssr/lib/modules.ts
|
|
1784
|
-
import { readdir as
|
|
2190
|
+
import { readdir as readdir4, stat as stat3 } from "node:fs/promises";
|
|
1785
2191
|
async function importContentModuleForPath(pathname, clientDir, cwd, isWatchMode) {
|
|
1786
2192
|
try {
|
|
1787
|
-
const
|
|
1788
|
-
|
|
1789
|
-
if (parts.length < 2)
|
|
2193
|
+
const resolved = resolveContentPathParts(pathname);
|
|
2194
|
+
if (!resolved)
|
|
1790
2195
|
return null;
|
|
1791
|
-
const collection =
|
|
1792
|
-
const
|
|
1793
|
-
const registryModule = await tryRegistryImport(collection, name, cwd, isWatchMode);
|
|
2196
|
+
const { collection, name, locale } = resolved;
|
|
2197
|
+
const registryModule = await tryRegistryImport(collection, name, cwd, isWatchMode, locale);
|
|
1794
2198
|
if (registryModule)
|
|
1795
2199
|
return registryModule;
|
|
1796
2200
|
const chunkModule = await tryChunkImport(collection, name, cwd, isWatchMode);
|
|
1797
2201
|
if (chunkModule)
|
|
1798
2202
|
return chunkModule;
|
|
1799
|
-
const sourceModule = await trySourceImport(collection, name, clientDir, isWatchMode);
|
|
2203
|
+
const sourceModule = await trySourceImport(collection, name, clientDir, isWatchMode, locale);
|
|
1800
2204
|
if (sourceModule)
|
|
1801
2205
|
return sourceModule;
|
|
1802
2206
|
} catch {}
|
|
1803
2207
|
return null;
|
|
1804
2208
|
}
|
|
1805
|
-
async function tryRegistryImport(collection, name, cwd, isWatchMode) {
|
|
2209
|
+
async function tryRegistryImport(collection, name, cwd, isWatchMode, locale) {
|
|
1806
2210
|
try {
|
|
1807
2211
|
const registryPath = join2(cwd, ".reroute", "content.ts");
|
|
1808
2212
|
const reg = await dynamicImport(registryPath, isWatchMode);
|
|
1809
2213
|
const get = reg?.getContentEntry;
|
|
1810
|
-
const entry = typeof get === "function" ? get(collection, name) : undefined;
|
|
2214
|
+
const entry = typeof get === "function" ? get(collection, name, locale) : undefined;
|
|
1811
2215
|
const moduleUrl = entry?.module;
|
|
1812
2216
|
if (!moduleUrl?.endsWith(".js"))
|
|
1813
2217
|
return null;
|
|
@@ -1833,7 +2237,7 @@ async function tryRegistryImport(collection, name, cwd, isWatchMode) {
|
|
|
1833
2237
|
async function tryChunkImport(collection, name, cwd, isWatchMode) {
|
|
1834
2238
|
try {
|
|
1835
2239
|
const chunkDir = join2(cwd, ".reroute", "chunks", collection);
|
|
1836
|
-
const files = await
|
|
2240
|
+
const files = await readdir4(chunkDir);
|
|
1837
2241
|
const matches = files.filter((n) => n.startsWith(`${name}.`) && n.endsWith(".js"));
|
|
1838
2242
|
if (!matches.length)
|
|
1839
2243
|
return null;
|
|
@@ -1853,23 +2257,23 @@ async function tryChunkImport(collection, name, cwd, isWatchMode) {
|
|
|
1853
2257
|
} catch {}
|
|
1854
2258
|
return null;
|
|
1855
2259
|
}
|
|
1856
|
-
async function trySourceImport(collection, name, clientDir, isWatchMode) {
|
|
2260
|
+
async function trySourceImport(collection, name, clientDir, isWatchMode, locale) {
|
|
1857
2261
|
try {
|
|
1858
|
-
const
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
if (await Bun.file(srcTsx).exists()) {
|
|
1862
|
-
absSrc = srcTsx;
|
|
1863
|
-
} else if (await Bun.file(srcTs).exists()) {
|
|
1864
|
-
absSrc = srcTs;
|
|
2262
|
+
const candidates = [];
|
|
2263
|
+
if (locale) {
|
|
2264
|
+
candidates.push(join2(clientDir, "routes", collection, "content", locale, `${name}.tsx`), join2(clientDir, "routes", collection, "content", locale, `${name}.ts`));
|
|
1865
2265
|
}
|
|
1866
|
-
|
|
1867
|
-
|
|
2266
|
+
candidates.push(join2(clientDir, "routes", collection, "content", `${name}.tsx`), join2(clientDir, "routes", collection, "content", `${name}.ts`));
|
|
2267
|
+
for (const absSrc of candidates) {
|
|
2268
|
+
if (await Bun.file(absSrc).exists()) {
|
|
2269
|
+
return await dynamicImport(absSrc, isWatchMode);
|
|
2270
|
+
}
|
|
1868
2271
|
}
|
|
1869
2272
|
} catch {}
|
|
1870
2273
|
return null;
|
|
1871
2274
|
}
|
|
1872
2275
|
var init_modules = __esm(() => {
|
|
2276
|
+
init_content_path();
|
|
1873
2277
|
init_imports();
|
|
1874
2278
|
});
|
|
1875
2279
|
|
|
@@ -1900,14 +2304,11 @@ function touchModule(key) {
|
|
|
1900
2304
|
}
|
|
1901
2305
|
async function seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode) {
|
|
1902
2306
|
try {
|
|
1903
|
-
const
|
|
1904
|
-
|
|
1905
|
-
if (parts.length < 2) {
|
|
2307
|
+
const resolved = resolveContentPathParts(pathname);
|
|
2308
|
+
if (!resolved) {
|
|
1906
2309
|
return;
|
|
1907
2310
|
}
|
|
1908
|
-
const
|
|
1909
|
-
const name = parts[1];
|
|
1910
|
-
const key = `${collection}:${name}`;
|
|
2311
|
+
const { key } = resolved;
|
|
1911
2312
|
const mod = await importContentModuleForPath(pathname, clientDir, cwd, isWatchMode);
|
|
1912
2313
|
if (!mod) {
|
|
1913
2314
|
return;
|
|
@@ -1927,6 +2328,7 @@ async function seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode) {
|
|
|
1927
2328
|
}
|
|
1928
2329
|
var MAX_SSR_MODULES = 200, moduleAccessOrder;
|
|
1929
2330
|
var init_seed = __esm(() => {
|
|
2331
|
+
init_content_path();
|
|
1930
2332
|
init_modules();
|
|
1931
2333
|
moduleAccessOrder = [];
|
|
1932
2334
|
});
|
|
@@ -1934,17 +2336,17 @@ var init_seed = __esm(() => {
|
|
|
1934
2336
|
// packages/core/src/ssr/lib/data.ts
|
|
1935
2337
|
function loadContentData(pathname, searchParams) {
|
|
1936
2338
|
try {
|
|
1937
|
-
const
|
|
1938
|
-
if (
|
|
2339
|
+
const resolved = resolveContentPathParts(pathname);
|
|
2340
|
+
if (!resolved)
|
|
1939
2341
|
return null;
|
|
1940
|
-
const key =
|
|
2342
|
+
const key = resolved.key;
|
|
1941
2343
|
const g = globalThis;
|
|
1942
2344
|
const exp = g.__REROUTE_SSR_EXPORTS__?.[key];
|
|
1943
2345
|
const dataFn = exp?.ssr?.data;
|
|
1944
2346
|
if (typeof dataFn === "function") {
|
|
1945
2347
|
const rawResult = dataFn({
|
|
1946
2348
|
pathname,
|
|
1947
|
-
params: { name:
|
|
2349
|
+
params: { name: resolved.name },
|
|
1948
2350
|
searchParams
|
|
1949
2351
|
});
|
|
1950
2352
|
const result = processDataResult(rawResult, pathname, pathname);
|
|
@@ -2107,6 +2509,7 @@ function createLazyMarker(pathname, key) {
|
|
|
2107
2509
|
};
|
|
2108
2510
|
}
|
|
2109
2511
|
var init_data = __esm(() => {
|
|
2512
|
+
init_content_path();
|
|
2110
2513
|
init_imports();
|
|
2111
2514
|
init_seed();
|
|
2112
2515
|
});
|
|
@@ -2307,14 +2710,14 @@ function replaceAppRoot(html, appHtml, appId) {
|
|
|
2307
2710
|
var init_html = () => {};
|
|
2308
2711
|
|
|
2309
2712
|
// packages/core/src/og/discovery.ts
|
|
2310
|
-
import { readdir as
|
|
2713
|
+
import { readdir as readdir5 } from "node:fs/promises";
|
|
2311
2714
|
import { pathToFileURL as pathToFileURL4 } from "node:url";
|
|
2312
2715
|
function isCatchAllRouteDirectory(name) {
|
|
2313
2716
|
return CATCH_ALL_ROUTE_DIRECTORY.test(name);
|
|
2314
2717
|
}
|
|
2315
2718
|
async function listDynamicRouteDirectories(baseDir) {
|
|
2316
2719
|
try {
|
|
2317
|
-
const entries = await
|
|
2720
|
+
const entries = await readdir5(baseDir, { withFileTypes: true });
|
|
2318
2721
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => DYNAMIC_ROUTE_DIRECTORY.test(name)).sort((a, b) => {
|
|
2319
2722
|
const aIsCatchAll = isCatchAllRouteDirectory(a);
|
|
2320
2723
|
const bIsCatchAll = isCatchAllRouteDirectory(b);
|
|
@@ -2334,7 +2737,7 @@ async function collectOGCandidatePaths(currentDir, parts, depth, pathsToTry, all
|
|
|
2334
2737
|
}
|
|
2335
2738
|
const literalDir = join2(currentDir, parts[depth]);
|
|
2336
2739
|
try {
|
|
2337
|
-
await
|
|
2740
|
+
await readdir5(literalDir);
|
|
2338
2741
|
await collectOGCandidatePaths(literalDir, parts, depth + 1, pathsToTry, true);
|
|
2339
2742
|
} catch {}
|
|
2340
2743
|
const dynamicDirs = await listDynamicRouteDirectories(currentDir);
|
|
@@ -2489,7 +2892,9 @@ async function extractPageMetadata(pathname, clientDir, cwd, isWatchMode, curren
|
|
|
2489
2892
|
let perPageHead = "";
|
|
2490
2893
|
let pageLang;
|
|
2491
2894
|
let statusOverride = currentStatusOverride;
|
|
2492
|
-
|
|
2895
|
+
const resolved = resolveContentPathParts(pathname);
|
|
2896
|
+
const routingPathname = resolved?.routingPathname || pathname;
|
|
2897
|
+
await extractLayoutMetadata(routingPathname, clientDir, cwd, isWatchMode, (head) => {
|
|
2493
2898
|
perPageHead += head;
|
|
2494
2899
|
}, (lang) => {
|
|
2495
2900
|
if (!pageLang)
|
|
@@ -2524,8 +2929,8 @@ ${ogMetaTags}`;
|
|
|
2524
2929
|
perPageHead += head;
|
|
2525
2930
|
}, (lang) => {
|
|
2526
2931
|
pageLang = lang;
|
|
2527
|
-
}, ogConfig, titleSuffix);
|
|
2528
|
-
const routeResult = await extractRouteMetadata(pathname, clientDir, cwd, isWatchMode, statusOverride, ssrData, ogConfig, titleSuffix);
|
|
2932
|
+
}, ogConfig, titleSuffix, baseUrl);
|
|
2933
|
+
const routeResult = await extractRouteMetadata(pathname, clientDir, cwd, isWatchMode, statusOverride, ssrData, ogConfig, titleSuffix, routingPathname);
|
|
2529
2934
|
perPageHead += routeResult.head;
|
|
2530
2935
|
if (routeResult.lang)
|
|
2531
2936
|
pageLang = routeResult.lang;
|
|
@@ -2565,14 +2970,42 @@ async function extractLayoutMetadata(pathname, clientDir, cwd, isWatchMode, addH
|
|
|
2565
2970
|
}
|
|
2566
2971
|
} catch {}
|
|
2567
2972
|
}
|
|
2568
|
-
function
|
|
2973
|
+
function resolveContentLocales(collection, name, fallbackLocales) {
|
|
2974
|
+
const g = globalThis;
|
|
2975
|
+
const byCollection = g.__REROUTE_COLLECTIONS__;
|
|
2976
|
+
const items = byCollection?.[collection] || [];
|
|
2977
|
+
const localesForEntry = [
|
|
2978
|
+
...new Set(items.filter((it) => it.name === name && it.locale).map((it) => String(it.locale)))
|
|
2979
|
+
];
|
|
2980
|
+
return localesForEntry.length > 0 ? localesForEntry : fallbackLocales;
|
|
2981
|
+
}
|
|
2982
|
+
function addContentI18nHead(addHead, baseUrl, collection, name, locales, defaultLocale, activeLocale) {
|
|
2983
|
+
if (locales.length > 1) {
|
|
2984
|
+
addHead(`
|
|
2985
|
+
${hreflangTags(baseUrl, collection, name, locales, defaultLocale)}`);
|
|
2986
|
+
}
|
|
2987
|
+
addHead(`
|
|
2988
|
+
<meta property="og:locale" content="${toOgLocale(activeLocale)}" />`);
|
|
2989
|
+
for (const loc of locales) {
|
|
2990
|
+
if (loc === activeLocale)
|
|
2991
|
+
continue;
|
|
2992
|
+
addHead(`
|
|
2993
|
+
<meta property="og:locale:alternate" content="${toOgLocale(loc)}" />`);
|
|
2994
|
+
}
|
|
2995
|
+
const canonicalPath = localizeContentHref(collection, name, activeLocale, defaultLocale);
|
|
2996
|
+
const base = baseUrl.replace(/\/$/, "");
|
|
2997
|
+
addHead(`
|
|
2998
|
+
<link rel="canonical" href="${base}${canonicalPath}" />`);
|
|
2999
|
+
addHead(`
|
|
3000
|
+
<meta property="og:url" content="${base}${canonicalPath}" />`);
|
|
3001
|
+
}
|
|
3002
|
+
function extractContentMetadata(pathname, addHead, setLang, ogConfig, titleSuffix, baseUrl) {
|
|
2569
3003
|
try {
|
|
2570
|
-
const
|
|
2571
|
-
if (
|
|
3004
|
+
const resolved = resolveContentPathParts(pathname);
|
|
3005
|
+
if (!resolved)
|
|
2572
3006
|
return;
|
|
2573
|
-
const key = `${parts[0]}:${parts[1]}`;
|
|
2574
3007
|
const g = globalThis;
|
|
2575
|
-
const exp = g.__REROUTE_SSR_EXPORTS__?.[key];
|
|
3008
|
+
const exp = g.__REROUTE_SSR_EXPORTS__?.[resolved.key];
|
|
2576
3009
|
const meta = exp?.meta;
|
|
2577
3010
|
const ssr = exp?.ssr;
|
|
2578
3011
|
addHead(buildHeadFromMeta(meta, ogConfig, titleSuffix));
|
|
@@ -2583,15 +3016,20 @@ ${ssrHead}`);
|
|
|
2583
3016
|
const lang = extractSSRLang(ssr);
|
|
2584
3017
|
if (lang)
|
|
2585
3018
|
setLang(lang);
|
|
3019
|
+
const i18n = g.__REROUTE_I18N__;
|
|
3020
|
+
if (i18n?.enabled && baseUrl && i18n.locales && i18n.locales.length > 1) {
|
|
3021
|
+
const locales = resolveContentLocales(resolved.collection, resolved.name, i18n.locales);
|
|
3022
|
+
addContentI18nHead(addHead, baseUrl, resolved.collection, resolved.name, locales, i18n.defaultLocale || "en-US", i18n.locale || i18n.defaultLocale || "en-US");
|
|
3023
|
+
}
|
|
2586
3024
|
} catch {}
|
|
2587
3025
|
}
|
|
2588
3026
|
function getContentMetaFromExports(pathname) {
|
|
2589
3027
|
try {
|
|
2590
|
-
const
|
|
2591
|
-
if (
|
|
3028
|
+
const resolved = resolveContentPathParts(pathname);
|
|
3029
|
+
if (!resolved)
|
|
2592
3030
|
return;
|
|
2593
|
-
const slug =
|
|
2594
|
-
const key =
|
|
3031
|
+
const slug = resolved.name;
|
|
3032
|
+
const key = resolved.key;
|
|
2595
3033
|
const g = globalThis;
|
|
2596
3034
|
const exp = g.__REROUTE_SSR_EXPORTS__?.[key];
|
|
2597
3035
|
const meta = exp?.meta;
|
|
@@ -2605,9 +3043,10 @@ function getContentMetaFromExports(pathname) {
|
|
|
2605
3043
|
return;
|
|
2606
3044
|
}
|
|
2607
3045
|
}
|
|
2608
|
-
async function extractMatchedRouteMetadata(pathname, clientDir, m, isWatchMode, statusOverride, ssrData, ogConfig, titleSuffix) {
|
|
3046
|
+
async function extractMatchedRouteMetadata(pathname, clientDir, m, isWatchMode, statusOverride, ssrData, ogConfig, titleSuffix, routingPathname) {
|
|
2609
3047
|
const pathnameOnly = pathname.split("?")[0];
|
|
2610
|
-
const
|
|
3048
|
+
const matchPath = (routingPathname || pathname).split("?")[0];
|
|
3049
|
+
const match = typeof m.matchRoute === "function" ? m.matchRoute(matchPath) : null;
|
|
2611
3050
|
const r = match?.route;
|
|
2612
3051
|
if (!r) {
|
|
2613
3052
|
return { head: "", statusOverride: statusOverride || 404 };
|
|
@@ -2647,7 +3086,7 @@ ${ssrHead}`;
|
|
|
2647
3086
|
}
|
|
2648
3087
|
return { head: "", statusOverride };
|
|
2649
3088
|
}
|
|
2650
|
-
async function extractRouteMetadata(pathname, clientDir, cwd, isWatchMode, currentStatusOverride, ssrData, ogConfig, titleSuffix) {
|
|
3089
|
+
async function extractRouteMetadata(pathname, clientDir, cwd, isWatchMode, currentStatusOverride, ssrData, ogConfig, titleSuffix, routingPathname) {
|
|
2651
3090
|
let head = "";
|
|
2652
3091
|
let lang;
|
|
2653
3092
|
let statusOverride = currentStatusOverride;
|
|
@@ -2657,14 +3096,14 @@ async function extractRouteMetadata(pathname, clientDir, cwd, isWatchMode, curre
|
|
|
2657
3096
|
if (!m) {
|
|
2658
3097
|
return { head, lang, statusOverride: statusOverride || 404 };
|
|
2659
3098
|
}
|
|
2660
|
-
const
|
|
2661
|
-
const match = typeof m.matchRoute === "function" ? m.matchRoute(
|
|
3099
|
+
const matchPath = (routingPathname || pathname).split("?")[0];
|
|
3100
|
+
const match = typeof m.matchRoute === "function" ? m.matchRoute(matchPath) : null;
|
|
2662
3101
|
const r = match?.route;
|
|
2663
3102
|
if (!r) {
|
|
2664
3103
|
statusOverride = statusOverride || 404;
|
|
2665
3104
|
}
|
|
2666
3105
|
if (r && typeof r.path === "string") {
|
|
2667
|
-
const result = await extractMatchedRouteMetadata(pathname, clientDir, m, isWatchMode, statusOverride, ssrData, ogConfig, titleSuffix);
|
|
3106
|
+
const result = await extractMatchedRouteMetadata(pathname, clientDir, m, isWatchMode, statusOverride, ssrData, ogConfig, titleSuffix, routingPathname);
|
|
2668
3107
|
head = result.head;
|
|
2669
3108
|
lang = result.lang;
|
|
2670
3109
|
statusOverride = result.statusOverride;
|
|
@@ -2839,34 +3278,34 @@ function applyTitleSuffixToHead(headContent, titleSuffix) {
|
|
|
2839
3278
|
}
|
|
2840
3279
|
var init_metadata2 = __esm(() => {
|
|
2841
3280
|
init_metadata();
|
|
3281
|
+
init_pathname();
|
|
2842
3282
|
init_meta();
|
|
2843
3283
|
init_compute();
|
|
3284
|
+
init_content_path();
|
|
2844
3285
|
init_imports();
|
|
2845
3286
|
});
|
|
2846
3287
|
|
|
2847
3288
|
// packages/core/src/ssr/lib/preload.ts
|
|
2848
|
-
import { readdir as
|
|
3289
|
+
import { readdir as readdir6, stat as stat4 } from "node:fs/promises";
|
|
2849
3290
|
async function preloadContentModule(pathname, clientDir, cwd, isWatchMode) {
|
|
2850
3291
|
let extraHead = "";
|
|
2851
3292
|
let hydrationScript = "";
|
|
2852
3293
|
let statusOverride;
|
|
2853
3294
|
try {
|
|
2854
|
-
const
|
|
2855
|
-
const
|
|
2856
|
-
if (
|
|
3295
|
+
const { resolveContentPathParts: resolveContentPathParts2 } = await Promise.resolve().then(() => (init_content_path(), exports_content_path));
|
|
3296
|
+
const resolved = resolveContentPathParts2(pathname);
|
|
3297
|
+
if (!resolved) {
|
|
2857
3298
|
return { extraHead, hydrationScript };
|
|
2858
3299
|
}
|
|
2859
|
-
const collection =
|
|
2860
|
-
const name = parts[1];
|
|
3300
|
+
const { collection, name, key, locale } = resolved;
|
|
2861
3301
|
if (!await isContentCollection(clientDir, collection)) {
|
|
2862
3302
|
return { extraHead, hydrationScript };
|
|
2863
3303
|
}
|
|
2864
|
-
const modulePath = await findContentModulePath(collection, name, clientDir, cwd, isWatchMode);
|
|
3304
|
+
const modulePath = await findContentModulePath(collection, name, clientDir, cwd, isWatchMode, locale);
|
|
2865
3305
|
if (!modulePath) {
|
|
2866
3306
|
statusOverride = 404;
|
|
2867
3307
|
return { extraHead, hydrationScript, statusOverride };
|
|
2868
3308
|
}
|
|
2869
|
-
const key = `${collection}:${name}`;
|
|
2870
3309
|
extraHead += `
|
|
2871
3310
|
<link rel="modulepreload" href="${modulePath}" />`;
|
|
2872
3311
|
hydrationScript += `<script>
|
|
@@ -2908,12 +3347,12 @@ async function findLatestCandidate(chunkDir, candidates) {
|
|
|
2908
3347
|
}
|
|
2909
3348
|
return latest;
|
|
2910
3349
|
}
|
|
2911
|
-
async function findContentModulePath(collection, name, clientDir, cwd, isWatchMode) {
|
|
3350
|
+
async function findContentModulePath(collection, name, clientDir, cwd, isWatchMode, locale) {
|
|
2912
3351
|
try {
|
|
2913
3352
|
const registryPath = join2(cwd, ".reroute", "content.ts");
|
|
2914
3353
|
const reg = await dynamicImport(registryPath, isWatchMode);
|
|
2915
3354
|
const get = reg?.getContentEntry;
|
|
2916
|
-
const entry = typeof get === "function" ? get(collection, name) : undefined;
|
|
3355
|
+
const entry = typeof get === "function" ? get(collection, name, locale) : undefined;
|
|
2917
3356
|
const moduleUrl = entry?.module;
|
|
2918
3357
|
if (moduleUrl?.endsWith(".js")) {
|
|
2919
3358
|
return moduleUrl;
|
|
@@ -2921,7 +3360,7 @@ async function findContentModulePath(collection, name, clientDir, cwd, isWatchMo
|
|
|
2921
3360
|
} catch {}
|
|
2922
3361
|
try {
|
|
2923
3362
|
const chunkDir = join2(cwd, ".reroute", "chunks", collection);
|
|
2924
|
-
const files = await
|
|
3363
|
+
const files = await readdir6(chunkDir);
|
|
2925
3364
|
const candidates = files.filter((n) => n.startsWith(`${name}.`) && n.endsWith(".js"));
|
|
2926
3365
|
if (candidates.length) {
|
|
2927
3366
|
const latest = await findLatestCandidate(chunkDir, candidates);
|
|
@@ -2929,13 +3368,18 @@ async function findContentModulePath(collection, name, clientDir, cwd, isWatchMo
|
|
|
2929
3368
|
}
|
|
2930
3369
|
} catch {}
|
|
2931
3370
|
try {
|
|
2932
|
-
const
|
|
2933
|
-
const
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
3371
|
+
const contentRoot = join2(clientDir, "routes", collection, "content");
|
|
3372
|
+
const candidates = locale ? [
|
|
3373
|
+
join2(contentRoot, locale, `${name}.tsx`),
|
|
3374
|
+
join2(contentRoot, locale, `${name}.ts`),
|
|
3375
|
+
join2(contentRoot, `${name}.tsx`),
|
|
3376
|
+
join2(contentRoot, `${name}.ts`)
|
|
3377
|
+
] : [join2(contentRoot, `${name}.tsx`), join2(contentRoot, `${name}.ts`)];
|
|
3378
|
+
for (const abs of candidates) {
|
|
3379
|
+
if (await Bun.file(abs).exists()) {
|
|
3380
|
+
const rel = abs.startsWith(clientDir) ? abs.slice(clientDir.length).replace(/^[/\\]/, "") : join2("routes", collection, "content", `${name}.tsx`);
|
|
3381
|
+
return `/${rel.replace(/\\+/g, "/")}`;
|
|
3382
|
+
}
|
|
2939
3383
|
}
|
|
2940
3384
|
} catch {}
|
|
2941
3385
|
return null;
|
|
@@ -3129,11 +3573,18 @@ function duplicateQueryParamData(ssrData) {
|
|
|
3129
3573
|
return duplicated;
|
|
3130
3574
|
}
|
|
3131
3575
|
function getContentKeyFromPathname(pathname) {
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3576
|
+
return resolveContentPathParts(pathname)?.key ?? null;
|
|
3577
|
+
}
|
|
3578
|
+
function createI18nScript(i18n) {
|
|
3579
|
+
if (!i18n?.enabled)
|
|
3580
|
+
return "";
|
|
3581
|
+
try {
|
|
3582
|
+
const json2 = escapeJsonForScript(JSON.stringify(i18n));
|
|
3583
|
+
return `<script>(function(){try{var w=(typeof window!=='undefined'?window:globalThis);w.__REROUTE_I18N__=${json2};}catch(e){}})();</script>`;
|
|
3584
|
+
} catch (error) {
|
|
3585
|
+
console.error("[reroute] Failed to serialize i18n hydration:", error);
|
|
3586
|
+
return "";
|
|
3587
|
+
}
|
|
3137
3588
|
}
|
|
3138
3589
|
function createContentCaptureScript() {
|
|
3139
3590
|
return `<script>(function(){try{var w=window;w.__REROUTE_INITIAL_HYDRATION__=true;var h={};document.querySelectorAll('[data-reroute-key]').forEach(function(el){var k=el.getAttribute('data-reroute-key');if(k)h[k]=el.innerHTML;});w.__REROUTE_CONTENT_HTML__=h;var r=document.querySelector('[data-reroute-route="ssr"]');if(r)w.__REROUTE_ROUTE_HTML__=r.innerHTML;}catch(e){}})();</script>`;
|
|
@@ -3209,13 +3660,14 @@ function createSSRPathnameScript(pathname) {
|
|
|
3209
3660
|
return "";
|
|
3210
3661
|
}
|
|
3211
3662
|
}
|
|
3212
|
-
function createDataScript(ssrData, errorMsg, pathname, browserTelemetryConfig, traceContext, titleSuffix) {
|
|
3663
|
+
function createDataScript(ssrData, errorMsg, pathname, browserTelemetryConfig, traceContext, titleSuffix, i18n) {
|
|
3213
3664
|
let script = "";
|
|
3214
3665
|
script += createContentCaptureScript();
|
|
3215
3666
|
script += createSSRPathnameScript(pathname);
|
|
3216
3667
|
if (pathname) {
|
|
3217
3668
|
script += createSSRExportsScript(pathname);
|
|
3218
3669
|
}
|
|
3670
|
+
script += createI18nScript(i18n);
|
|
3219
3671
|
script += createTelemetryConfigScript(browserTelemetryConfig);
|
|
3220
3672
|
script += createTraceContextScript(traceContext);
|
|
3221
3673
|
script += createTitleSuffixScript(titleSuffix);
|
|
@@ -3235,7 +3687,9 @@ function createDataScript(ssrData, errorMsg, pathname, browserTelemetryConfig, t
|
|
|
3235
3687
|
}
|
|
3236
3688
|
return script;
|
|
3237
3689
|
}
|
|
3238
|
-
var init_data2 = () => {
|
|
3690
|
+
var init_data2 = __esm(() => {
|
|
3691
|
+
init_content_path();
|
|
3692
|
+
});
|
|
3239
3693
|
|
|
3240
3694
|
// packages/core/src/ssr/lib/scripts/feeds.ts
|
|
3241
3695
|
function createFeedsScript() {
|
|
@@ -3463,10 +3917,10 @@ function generateCollectionScripts(byCollectionForSSR) {
|
|
|
3463
3917
|
} catch {}
|
|
3464
3918
|
return "";
|
|
3465
3919
|
}
|
|
3466
|
-
function generateHydrationScripts(ssrData, isWatchMode, ssrError, collectionScripts = "", preloadScript = "", bundleUrl = "", pathname = "", browserTelemetryConfig, traceContext, titleSuffix) {
|
|
3920
|
+
function generateHydrationScripts(ssrData, isWatchMode, ssrError, collectionScripts = "", preloadScript = "", bundleUrl = "", pathname = "", browserTelemetryConfig, traceContext, titleSuffix, i18n) {
|
|
3467
3921
|
let scripts = preloadScript;
|
|
3468
3922
|
scripts += collectionScripts;
|
|
3469
|
-
scripts += createDataScript(ssrData, isWatchMode ? ssrError : undefined, pathname, browserTelemetryConfig, traceContext, titleSuffix);
|
|
3923
|
+
scripts += createDataScript(ssrData, isWatchMode ? ssrError : undefined, pathname, browserTelemetryConfig, traceContext, titleSuffix, i18n);
|
|
3470
3924
|
scripts += createFeedsScript();
|
|
3471
3925
|
scripts += createLlmsScript();
|
|
3472
3926
|
if (bundleUrl) {
|
|
@@ -3629,7 +4083,7 @@ async function renderSSRDocument(options) {
|
|
|
3629
4083
|
const browserTelemetryConfig = serializeBrowserTelemetryConfig2(browserTelemetryConfigRaw);
|
|
3630
4084
|
const traceContext = getTraceContextForInjection(options.parentSpan);
|
|
3631
4085
|
const hydrationScript = await withSpan("ssr.generate.scripts", async (span) => {
|
|
3632
|
-
const script = generateHydrationScripts(setup2.ssrData, isWatchMode, setup2.ssrError, collectionScripts, setup2.preloadHydrationScript, bundleUrl, pathname, browserTelemetryConfig, traceContext, options.titleSuffix);
|
|
4086
|
+
const script = generateHydrationScripts(setup2.ssrData, isWatchMode, setup2.ssrError, collectionScripts, setup2.preloadHydrationScript, bundleUrl, pathname, browserTelemetryConfig, traceContext, options.titleSuffix, options.i18n);
|
|
3633
4087
|
span.setAttribute("reroute.scripts.size", script.length);
|
|
3634
4088
|
return script;
|
|
3635
4089
|
});
|
|
@@ -3647,12 +4101,13 @@ async function renderSSRDocument(options) {
|
|
|
3647
4101
|
dedent(setup2.metadataResult.perPageHead)
|
|
3648
4102
|
].filter(Boolean).join(`
|
|
3649
4103
|
`));
|
|
4104
|
+
const i18nLocale = options.i18n?.enabled ? String(options.i18n.locale || "") : "";
|
|
3650
4105
|
const html2 = withSpanSync("ssr.apply.template", (span) => {
|
|
3651
4106
|
const result = applyIndexTemplate(baseTemplate, appHtml, {
|
|
3652
4107
|
head: [setup2.inlineStyleTag, combinedHead].filter(Boolean).join(`
|
|
3653
4108
|
`),
|
|
3654
4109
|
hydrationScript,
|
|
3655
|
-
lang: setup2.metadataResult.pageLang || lang,
|
|
4110
|
+
lang: setup2.metadataResult.pageLang || i18nLocale || lang,
|
|
3656
4111
|
appId
|
|
3657
4112
|
});
|
|
3658
4113
|
span.setAttributes({
|
|
@@ -4830,6 +5285,55 @@ async function discoverRoutes(cwd, isWatchMode) {
|
|
|
4830
5285
|
}
|
|
4831
5286
|
return { staticRoutes, dynamicRoutes };
|
|
4832
5287
|
}
|
|
5288
|
+
function groupNamedCollectionItems(items) {
|
|
5289
|
+
const byName = new Map;
|
|
5290
|
+
for (const item of items) {
|
|
5291
|
+
const name = String(item.name || "");
|
|
5292
|
+
if (!name)
|
|
5293
|
+
continue;
|
|
5294
|
+
const list = byName.get(name) || [];
|
|
5295
|
+
list.push(item);
|
|
5296
|
+
byName.set(name, list);
|
|
5297
|
+
}
|
|
5298
|
+
return byName;
|
|
5299
|
+
}
|
|
5300
|
+
function resolveItemHref(collection, item, defaultLocale, localize) {
|
|
5301
|
+
const name = String(item.name || "");
|
|
5302
|
+
const locale = item.locale || defaultLocale;
|
|
5303
|
+
if (name)
|
|
5304
|
+
return localize(collection, name, locale, defaultLocale);
|
|
5305
|
+
return String(item.href || "");
|
|
5306
|
+
}
|
|
5307
|
+
function buildNamedCollectionSitemapEntries(collection, name, variants, defaultLocale, base, localize) {
|
|
5308
|
+
const locales = [
|
|
5309
|
+
...new Set(variants.map((v) => v.locale || defaultLocale).filter(Boolean))
|
|
5310
|
+
];
|
|
5311
|
+
const alternates = locales.length > 1 ? [
|
|
5312
|
+
...locales.map((locale) => ({
|
|
5313
|
+
hreflang: locale,
|
|
5314
|
+
href: `${base}${localize(collection, name, locale, defaultLocale)}`
|
|
5315
|
+
})),
|
|
5316
|
+
{
|
|
5317
|
+
hreflang: "x-default",
|
|
5318
|
+
href: `${base}${localize(collection, name, defaultLocale, defaultLocale)}`
|
|
5319
|
+
}
|
|
5320
|
+
] : undefined;
|
|
5321
|
+
const entries = [];
|
|
5322
|
+
for (const item of variants) {
|
|
5323
|
+
const href = resolveItemHref(collection, item, defaultLocale, localize);
|
|
5324
|
+
if (!href)
|
|
5325
|
+
continue;
|
|
5326
|
+
const meta = item.meta || {};
|
|
5327
|
+
entries.push({
|
|
5328
|
+
loc: `${base}${href}`,
|
|
5329
|
+
lastmod: meta.date ? new Date(meta.date).toISOString() : undefined,
|
|
5330
|
+
changefreq: "weekly",
|
|
5331
|
+
priority: 0.7,
|
|
5332
|
+
alternates
|
|
5333
|
+
});
|
|
5334
|
+
}
|
|
5335
|
+
return entries;
|
|
5336
|
+
}
|
|
4833
5337
|
async function discoverCollectionContent(cwd, collection, isWatchMode, baseUrl) {
|
|
4834
5338
|
const entries = [];
|
|
4835
5339
|
try {
|
|
@@ -4841,18 +5345,26 @@ async function discoverCollectionContent(cwd, collection, isWatchMode, baseUrl)
|
|
|
4841
5345
|
const url = `${Bun.pathToFileURL(collectionFile).href}${isWatchMode ? `?t=${Date.now()}` : ""}`;
|
|
4842
5346
|
const mod = await import(url);
|
|
4843
5347
|
const items = mod.items || [];
|
|
5348
|
+
const defaultLocale = mod.defaultLocale || "en-US";
|
|
5349
|
+
const { localizeContentHref: localizeContentHref2 } = await Promise.resolve().then(() => (init_pathname(), exports_pathname));
|
|
5350
|
+
const base = baseUrl.replace(/\/$/, "");
|
|
5351
|
+
const byName = groupNamedCollectionItems(items);
|
|
5352
|
+
for (const [name, variants] of byName) {
|
|
5353
|
+
entries.push(...buildNamedCollectionSitemapEntries(collection, name, variants, defaultLocale, base, localizeContentHref2));
|
|
5354
|
+
}
|
|
4844
5355
|
for (const item of items) {
|
|
5356
|
+
if (item.name)
|
|
5357
|
+
continue;
|
|
4845
5358
|
const href = String(item.href || "");
|
|
5359
|
+
if (!href)
|
|
5360
|
+
continue;
|
|
4846
5361
|
const meta = item.meta || {};
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
};
|
|
4854
|
-
entries.push(entry);
|
|
4855
|
-
}
|
|
5362
|
+
entries.push({
|
|
5363
|
+
loc: `${base}${href}`,
|
|
5364
|
+
lastmod: meta.date ? new Date(meta.date).toISOString() : undefined,
|
|
5365
|
+
changefreq: "weekly",
|
|
5366
|
+
priority: 0.7
|
|
5367
|
+
});
|
|
4856
5368
|
}
|
|
4857
5369
|
} catch (error) {
|
|
4858
5370
|
console.error(`[reroute] Failed to discover collection ${collection}:`, error);
|
|
@@ -5147,11 +5659,17 @@ async function discoverCollectionFeedItems(cwd, collection, isWatchMode, baseUrl
|
|
|
5147
5659
|
const url = `${Bun.pathToFileURL(collectionFile).href}${isWatchMode ? `?t=${Date.now()}` : ""}`;
|
|
5148
5660
|
const mod = await import(url);
|
|
5149
5661
|
const contentItems = mod.items || [];
|
|
5662
|
+
const defaultLocale = mod.defaultLocale || "en-US";
|
|
5663
|
+
const { localizeContentHref: localizeContentHref2 } = await Promise.resolve().then(() => (init_pathname(), exports_pathname));
|
|
5150
5664
|
for (const item of contentItems) {
|
|
5151
|
-
const
|
|
5665
|
+
const name = String(item.name || "");
|
|
5666
|
+
const locale = item.locale || defaultLocale;
|
|
5667
|
+
const href = name ? localizeContentHref2(collection, name, locale, defaultLocale) : String(item.href || "");
|
|
5152
5668
|
const meta = item.meta || {};
|
|
5153
5669
|
if (href) {
|
|
5154
|
-
|
|
5670
|
+
const rssItem = createRSSItemFromMetaAndHref(href, meta, baseUrl, item, rssConfig);
|
|
5671
|
+
rssItem.locale = locale;
|
|
5672
|
+
items.push(rssItem);
|
|
5155
5673
|
}
|
|
5156
5674
|
}
|
|
5157
5675
|
} catch (error) {
|
|
@@ -5417,7 +5935,7 @@ function generateRSSXML(feed, options = {}) {
|
|
|
5417
5935
|
<link>${escapeXml(feed.link)}</link>
|
|
5418
5936
|
<description>${escapeXml(feed.description)}</description>
|
|
5419
5937
|
<lastBuildDate>${lastBuildDate}</lastBuildDate>
|
|
5420
|
-
<language
|
|
5938
|
+
<language>${escapeXml(feed.language || "en")}</language>
|
|
5421
5939
|
<atom:link href="${escapeXml(feed.link)}" rel="self" type="application/rss+xml" />
|
|
5422
5940
|
${itemsXML}
|
|
5423
5941
|
</channel>
|
|
@@ -5579,6 +6097,7 @@ async function generateSitemap(discovery4, baseUrl, options = {}) {
|
|
|
5579
6097
|
return createSingleSitemap(allEntries);
|
|
5580
6098
|
}
|
|
5581
6099
|
function generateSitemapXML(entries) {
|
|
6100
|
+
const hasAlternates = entries.some((e) => e.alternates && e.alternates.length > 0);
|
|
5582
6101
|
const urlsetEntries = entries.map((entry) => {
|
|
5583
6102
|
let xml = ` <url>
|
|
5584
6103
|
<loc>${escapeXml2(entry.loc)}</loc>`;
|
|
@@ -5594,13 +6113,20 @@ function generateSitemapXML(entries) {
|
|
|
5594
6113
|
xml += `
|
|
5595
6114
|
<priority>${entry.priority.toFixed(1)}</priority>`;
|
|
5596
6115
|
}
|
|
6116
|
+
if (entry.alternates?.length) {
|
|
6117
|
+
for (const alt of entry.alternates) {
|
|
6118
|
+
xml += `
|
|
6119
|
+
<xhtml:link rel="alternate" hreflang="${escapeXml2(alt.hreflang)}" href="${escapeXml2(alt.href)}" />`;
|
|
6120
|
+
}
|
|
6121
|
+
}
|
|
5597
6122
|
xml += `
|
|
5598
6123
|
</url>`;
|
|
5599
6124
|
return xml;
|
|
5600
6125
|
}).join(`
|
|
5601
6126
|
`);
|
|
6127
|
+
const xhtmlNs = hasAlternates ? ' xmlns:xhtml="http://www.w3.org/1999/xhtml"' : "";
|
|
5602
6128
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
5603
|
-
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
6129
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"${xhtmlNs}>
|
|
5604
6130
|
${urlsetEntries}
|
|
5605
6131
|
</urlset>`;
|
|
5606
6132
|
}
|
|
@@ -5698,7 +6224,8 @@ async function renderSSRDocumentStream(options) {
|
|
|
5698
6224
|
...parts
|
|
5699
6225
|
};
|
|
5700
6226
|
});
|
|
5701
|
-
const
|
|
6227
|
+
const i18nLocale = options.i18n?.enabled ? String(options.i18n.locale || "") : "";
|
|
6228
|
+
const pageLang = setup2.metadataResult.pageLang || i18nLocale || lang;
|
|
5702
6229
|
let headWithLang = htmlHead.replace(/<html([^>]*)>/i, (_m, attrs) => {
|
|
5703
6230
|
const hasLang = /(^|\s)lang\s*=/.test(attrs);
|
|
5704
6231
|
const newAttrs = hasLang ? attrs.replace(/lang\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)/i, `lang="${pageLang}"`) : `${attrs} lang="${pageLang}"`;
|
|
@@ -5741,7 +6268,8 @@ async function renderSSRDocumentStream(options) {
|
|
|
5741
6268
|
parentSpan: options.parentSpan,
|
|
5742
6269
|
timeout: options.timeout,
|
|
5743
6270
|
ssrExport: setup2.metadataResult.ssrExport,
|
|
5744
|
-
titleSuffix: options.titleSuffix
|
|
6271
|
+
titleSuffix: options.titleSuffix,
|
|
6272
|
+
i18n: options.i18n
|
|
5745
6273
|
});
|
|
5746
6274
|
if (debug)
|
|
5747
6275
|
console.log(`[renderStream] ${pathname} - returning stream: ${(performance.now() - t0).toFixed(2)}ms`);
|
|
@@ -5854,7 +6382,7 @@ function buildStreamingScripts(ctx) {
|
|
|
5854
6382
|
ssrDataSnapshot[key] = value;
|
|
5855
6383
|
}
|
|
5856
6384
|
}
|
|
5857
|
-
const dataScript = createDataScript(ssrDataSnapshot, ctx.isWatchMode ? ctx.ssrError : undefined, ctx.pathname, ctx.browserTelemetryConfig, ctx.traceContext, ctx.titleSuffix);
|
|
6385
|
+
const dataScript = createDataScript(ssrDataSnapshot, ctx.isWatchMode ? ctx.ssrError : undefined, ctx.pathname, ctx.browserTelemetryConfig, ctx.traceContext, ctx.titleSuffix, ctx.i18n);
|
|
5858
6386
|
const feedsScript = createFeedsScript();
|
|
5859
6387
|
const llmsScript = createLlmsScript();
|
|
5860
6388
|
let allScripts = dataScript + feedsScript + llmsScript + collectionScripts + ctx.preloadHydrationScript;
|
|
@@ -5986,6 +6514,7 @@ var init_src = __esm(() => {
|
|
|
5986
6514
|
init_bundler();
|
|
5987
6515
|
init_config();
|
|
5988
6516
|
init_content();
|
|
6517
|
+
init_i18n();
|
|
5989
6518
|
init_llms();
|
|
5990
6519
|
init_og();
|
|
5991
6520
|
init_robots();
|
|
@@ -5998,6 +6527,7 @@ var init_src = __esm(() => {
|
|
|
5998
6527
|
var exports_core = {};
|
|
5999
6528
|
__export(exports_core, {
|
|
6000
6529
|
toPromise: () => toPromise,
|
|
6530
|
+
toOgLocale: () => toOgLocale,
|
|
6001
6531
|
toBytes: () => toBytes,
|
|
6002
6532
|
stripStart: () => stripStart,
|
|
6003
6533
|
stripHtmlTags: () => stripHtmlTags,
|
|
@@ -6009,6 +6539,7 @@ __export(exports_core, {
|
|
|
6009
6539
|
setGlobalSSRData: () => setGlobalSSRData,
|
|
6010
6540
|
setGlobalCollections: () => setGlobalCollections,
|
|
6011
6541
|
seedSSRModuleForPath: () => seedSSRModuleForPath,
|
|
6542
|
+
resolveLocale: () => resolveLocale,
|
|
6012
6543
|
resetSSRAccessTracking: () => resetSSRAccessTracking,
|
|
6013
6544
|
renderSSRDocumentStream: () => renderSSRDocumentStream,
|
|
6014
6545
|
renderSSRDocument: () => renderSSRDocument,
|
|
@@ -6017,9 +6548,17 @@ __export(exports_core, {
|
|
|
6017
6548
|
processCollections: () => processCollections,
|
|
6018
6549
|
preloadContentModule: () => preloadContentModule,
|
|
6019
6550
|
performSSRSetup: () => performSSRSetup,
|
|
6551
|
+
parseCookieValue: () => parseCookieValue,
|
|
6552
|
+
parseContentPath: () => parseContentPath,
|
|
6553
|
+
normalizePathname: () => normalizePathname,
|
|
6554
|
+
negotiateLocale: () => negotiateLocale,
|
|
6020
6555
|
mergeLayoutData: () => mergeLayoutData,
|
|
6021
6556
|
matchRoutes: () => matchRoutes,
|
|
6022
6557
|
matchRoutePattern: () => matchRoutePattern,
|
|
6558
|
+
lookupMessage: () => lookupMessage,
|
|
6559
|
+
looksLikeLocale: () => looksLikeLocale,
|
|
6560
|
+
localizeHref: () => localizeHref,
|
|
6561
|
+
localizeContentHref: () => localizeContentHref,
|
|
6023
6562
|
loadRoutesModule: () => loadRoutesModule,
|
|
6024
6563
|
loadOGImageComponent: () => loadOGImageComponent,
|
|
6025
6564
|
loadIndexHtml: () => loadIndexHtml,
|
|
@@ -6032,11 +6571,13 @@ __export(exports_core, {
|
|
|
6032
6571
|
inlineTailwindCSS: () => inlineTailwindCSS,
|
|
6033
6572
|
importContentModuleForPath: () => importContentModuleForPath,
|
|
6034
6573
|
htmlToMarkdown: () => htmlToMarkdown,
|
|
6574
|
+
hreflangTags: () => hreflangTags,
|
|
6035
6575
|
gzipIfAccepted: () => gzipIfAccepted,
|
|
6036
6576
|
getSitemapExcludedRoutes: () => getSitemapExcludedRoutes,
|
|
6037
6577
|
getRedirectSourcePaths: () => getRedirectSourcePaths,
|
|
6038
6578
|
getPatternDepth: () => getPatternDepth,
|
|
6039
6579
|
getMimeType: () => getMimeType,
|
|
6580
|
+
getMessage: () => getMessage,
|
|
6040
6581
|
getMatchingLayouts: () => getMatchingLayouts,
|
|
6041
6582
|
getContentMeta: () => getContentMeta,
|
|
6042
6583
|
generateSitemapXML: () => generateSitemapXML,
|
|
@@ -6053,6 +6594,7 @@ __export(exports_core, {
|
|
|
6053
6594
|
generateContentHash: () => generateContentHash,
|
|
6054
6595
|
generateCollectionScripts: () => generateCollectionScripts,
|
|
6055
6596
|
generateAtomXML: () => generateAtomXML,
|
|
6597
|
+
formatMessage: () => formatMessage,
|
|
6056
6598
|
formatAsText: () => formatAsText,
|
|
6057
6599
|
formatAsMarkdown: () => formatAsMarkdown,
|
|
6058
6600
|
findOGImageForPath: () => findOGImageForPath,
|
|
@@ -6072,10 +6614,12 @@ __export(exports_core, {
|
|
|
6072
6614
|
discoverRoutes: () => discoverRoutes,
|
|
6073
6615
|
discoverRobotsData: () => discoverRobotsData,
|
|
6074
6616
|
discoverRSSData: () => discoverRSSData,
|
|
6617
|
+
discoverI18n: () => discoverI18n,
|
|
6075
6618
|
discoverCollections: () => discoverCollections,
|
|
6076
6619
|
discoverCollectionContent: () => discoverCollectionContent,
|
|
6077
6620
|
defineConfig: () => defineConfig,
|
|
6078
6621
|
deduplicateMetaTags: () => deduplicateMetaTags,
|
|
6622
|
+
createTranslator: () => createTranslator,
|
|
6079
6623
|
createLlmsScript: () => createLlmsScript,
|
|
6080
6624
|
createLayoutDataKey: () => createLayoutDataKey,
|
|
6081
6625
|
createLayoutCacheKey: () => createLayoutCacheKey,
|
|
@@ -6083,6 +6627,8 @@ __export(exports_core, {
|
|
|
6083
6627
|
createDataScript: () => createDataScript,
|
|
6084
6628
|
createCollectionScript: () => createCollectionScript,
|
|
6085
6629
|
createBundlePreload: () => createBundlePreload,
|
|
6630
|
+
contentNegotiateRedirect: () => contentNegotiateRedirect,
|
|
6631
|
+
contentKey: () => contentKey,
|
|
6086
6632
|
computeSSRDataForPath: () => computeSSRDataForPath,
|
|
6087
6633
|
computeSSRData: () => computeSSRData,
|
|
6088
6634
|
computeRouteData: () => computeRouteData,
|
|
@@ -6091,6 +6637,7 @@ __export(exports_core, {
|
|
|
6091
6637
|
compressStreamIfAccepted: () => compressStreamIfAccepted,
|
|
6092
6638
|
compareRouteSpecificity: () => compareRouteSpecificity,
|
|
6093
6639
|
cleanupPathScopedSSRData: () => cleanupPathScopedSSRData,
|
|
6640
|
+
buildLocaleCookie: () => buildLocaleCookie,
|
|
6094
6641
|
buildHeadFromMeta: () => buildHeadFromMeta,
|
|
6095
6642
|
blockSearchCrawlers: () => blockSearchCrawlers,
|
|
6096
6643
|
blockAITrainingCrawlers: () => blockAITrainingCrawlers,
|
|
@@ -6106,6 +6653,9 @@ __export(exports_core, {
|
|
|
6106
6653
|
SEARCH_CRAWLERS: () => SEARCH_CRAWLERS,
|
|
6107
6654
|
LRUCache: () => LRUCache,
|
|
6108
6655
|
DefaultOGTemplate: () => DefaultOGTemplate,
|
|
6656
|
+
DEFAULT_LOCALES_DIR: () => DEFAULT_LOCALES_DIR,
|
|
6657
|
+
DEFAULT_LOCALE: () => DEFAULT_LOCALE,
|
|
6658
|
+
DEFAULT_COOKIE: () => DEFAULT_COOKIE,
|
|
6109
6659
|
AI_CRAWLERS: () => AI_CRAWLERS
|
|
6110
6660
|
});
|
|
6111
6661
|
var init_core = __esm(() => {
|
|
@@ -6130,7 +6680,7 @@ function getNamingConfig(options) {
|
|
|
6130
6680
|
|
|
6131
6681
|
// packages/cli/src/commands/lib/env.ts
|
|
6132
6682
|
import { existsSync as existsSync2, readFileSync } from "node:fs";
|
|
6133
|
-
import { join as
|
|
6683
|
+
import { join as join4 } from "node:path";
|
|
6134
6684
|
function parseEnvFile(content2) {
|
|
6135
6685
|
const env = {};
|
|
6136
6686
|
const lines = content2.split(`
|
|
@@ -6156,7 +6706,7 @@ function loadEnvFiles(cwd, mode = "development") {
|
|
|
6156
6706
|
const env = {};
|
|
6157
6707
|
const loadedFiles = [];
|
|
6158
6708
|
for (const file of envFiles) {
|
|
6159
|
-
const filePath =
|
|
6709
|
+
const filePath = join4(cwd, file);
|
|
6160
6710
|
if (existsSync2(filePath)) {
|
|
6161
6711
|
try {
|
|
6162
6712
|
const content2 = readFileSync(filePath, "utf-8");
|
|
@@ -6200,11 +6750,11 @@ var init_env = () => {};
|
|
|
6200
6750
|
|
|
6201
6751
|
// packages/cli/src/commands/lib/markdown/availability.ts
|
|
6202
6752
|
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
6203
|
-
import { dirname, join as
|
|
6753
|
+
import { dirname, join as join5 } from "node:path";
|
|
6204
6754
|
function isPackageAvailable(cwd, packageName) {
|
|
6205
6755
|
let currentDir = cwd;
|
|
6206
6756
|
for (let i = 0;i < 5; i++) {
|
|
6207
|
-
const packageJsonPath =
|
|
6757
|
+
const packageJsonPath = join5(currentDir, "package.json");
|
|
6208
6758
|
if (existsSync3(packageJsonPath)) {
|
|
6209
6759
|
try {
|
|
6210
6760
|
const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
|
|
@@ -6276,7 +6826,7 @@ var init_availability = () => {};
|
|
|
6276
6826
|
|
|
6277
6827
|
// packages/cli/src/commands/lib/markdown/processor.ts
|
|
6278
6828
|
import { existsSync as existsSync4, readFileSync as readFileSync3 } from "node:fs";
|
|
6279
|
-
import { basename as basename2, dirname as dirname2, extname as extname2, join as
|
|
6829
|
+
import { basename as basename2, dirname as dirname2, extname as extname2, join as join6, relative, resolve } from "node:path";
|
|
6280
6830
|
import matter from "gray-matter";
|
|
6281
6831
|
function convertPropertiesToJsx(properties) {
|
|
6282
6832
|
const newProperties = {};
|
|
@@ -6335,7 +6885,7 @@ function processMarkdownFile(filePath) {
|
|
|
6335
6885
|
function isMdxAvailable2(cwd) {
|
|
6336
6886
|
let currentDir = cwd;
|
|
6337
6887
|
for (let i = 0;i < 5; i++) {
|
|
6338
|
-
const packageJsonPath =
|
|
6888
|
+
const packageJsonPath = join6(currentDir, "package.json");
|
|
6339
6889
|
if (existsSync4(packageJsonPath)) {
|
|
6340
6890
|
try {
|
|
6341
6891
|
const packageJson = JSON.parse(readFileSync3(packageJsonPath, "utf-8"));
|
|
@@ -6359,10 +6909,10 @@ function isMdxAvailable2(cwd) {
|
|
|
6359
6909
|
}
|
|
6360
6910
|
function tryLoadModule(cwd, moduleName) {
|
|
6361
6911
|
const pathsToTry = [
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6912
|
+
join6(cwd, `node_modules/${moduleName}`),
|
|
6913
|
+
join6(cwd, `../node_modules/${moduleName}`),
|
|
6914
|
+
join6(cwd, `../../node_modules/${moduleName}`),
|
|
6915
|
+
join6(cwd, `../../../node_modules/${moduleName}`)
|
|
6366
6916
|
];
|
|
6367
6917
|
for (const modulePath of pathsToTry) {
|
|
6368
6918
|
try {
|
|
@@ -6692,7 +7242,7 @@ function isProductionMode(args = []) {
|
|
|
6692
7242
|
}
|
|
6693
7243
|
|
|
6694
7244
|
// packages/cli/src/commands/lib/streaming/analyzer.ts
|
|
6695
|
-
import { dirname as dirname3, join as
|
|
7245
|
+
import { dirname as dirname3, join as join7 } from "node:path";
|
|
6696
7246
|
function hasSSRDataExport(source) {
|
|
6697
7247
|
if (SSR_DATA_INLINE_EXPORT_REGEX.test(source)) {
|
|
6698
7248
|
return true;
|
|
@@ -6720,10 +7270,10 @@ async function analyzeRouteForStreaming(options) {
|
|
|
6720
7270
|
}
|
|
6721
7271
|
async function findSkeletonForTarget(routesDir, relativePath, type) {
|
|
6722
7272
|
const dirName = normalizeRelativePath(dirname3(relativePath));
|
|
6723
|
-
const baseDir = dirName === "." ? routesDir :
|
|
7273
|
+
const baseDir = dirName === "." ? routesDir : join7(routesDir, dirName).replace(/\\/g, "/");
|
|
6724
7274
|
const candidates = type === "layout" ? ["[layout+skeleton].tsx", "[layout+skeleton].ts"] : ["[skeleton].tsx", "[skeleton].ts"];
|
|
6725
7275
|
for (const candidate of candidates) {
|
|
6726
|
-
const candidatePath =
|
|
7276
|
+
const candidatePath = join7(baseDir, candidate);
|
|
6727
7277
|
try {
|
|
6728
7278
|
const file = Bun.file(candidatePath);
|
|
6729
7279
|
if (await file.exists()) {
|
|
@@ -6744,12 +7294,12 @@ var init_analyzer = __esm(() => {
|
|
|
6744
7294
|
});
|
|
6745
7295
|
|
|
6746
7296
|
// packages/cli/src/commands/lib/streaming/suspense.ts
|
|
6747
|
-
import { dirname as dirname4, join as
|
|
7297
|
+
import { dirname as dirname4, join as join8, relative as relative2 } from "node:path";
|
|
6748
7298
|
async function generateStreamingWrapper(options) {
|
|
6749
7299
|
const { cwd, relativeFilePath, analysis, config: config2 } = options;
|
|
6750
|
-
const streamingModulePath =
|
|
7300
|
+
const streamingModulePath = join8(cwd, ".reroute", "streaming", relativeFilePath).replace(/\.(tsx|ts)$/, ".tsx");
|
|
6751
7301
|
const wrapperDir = dirname4(streamingModulePath);
|
|
6752
|
-
const originalModuleWithoutExt = removeExtension(
|
|
7302
|
+
const originalModuleWithoutExt = removeExtension(join8(cwd, "src", "client", "routes", relativeFilePath));
|
|
6753
7303
|
const originalImportPath = toImportPath(wrapperDir, originalModuleWithoutExt);
|
|
6754
7304
|
const skeletonImportBlock = await resolveSkeletonBlock({
|
|
6755
7305
|
analysis,
|
|
@@ -6791,7 +7341,7 @@ async function resolveSkeletonBlock(args) {
|
|
|
6791
7341
|
}
|
|
6792
7342
|
function resolveConfiguredSkeletonPath(value, cwd) {
|
|
6793
7343
|
if (typeof value === "string" && value.trim().length > 0) {
|
|
6794
|
-
return value.startsWith("/") ? value :
|
|
7344
|
+
return value.startsWith("/") ? value : join8(cwd, value);
|
|
6795
7345
|
}
|
|
6796
7346
|
if (value && !warnedSkeletonType) {
|
|
6797
7347
|
console.warn("[reroute/streaming] default skeletons must be provided as string module paths in reroute.config.ts");
|
|
@@ -6828,13 +7378,13 @@ var init_suspense = () => {};
|
|
|
6828
7378
|
// packages/cli/src/commands/lib/tailwind.ts
|
|
6829
7379
|
import { spawn } from "node:child_process";
|
|
6830
7380
|
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "node:fs";
|
|
6831
|
-
import { join as
|
|
7381
|
+
import { join as join9 } from "node:path";
|
|
6832
7382
|
function isTailwindAvailable(cwd) {
|
|
6833
7383
|
const pathsToTry = [
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
7384
|
+
join9(cwd, "package.json"),
|
|
7385
|
+
join9(cwd, "../package.json"),
|
|
7386
|
+
join9(cwd, "../../package.json"),
|
|
7387
|
+
join9(cwd, "../../../package.json")
|
|
6838
7388
|
];
|
|
6839
7389
|
for (const packageJsonPath of pathsToTry) {
|
|
6840
7390
|
if (!existsSync5(packageJsonPath)) {
|
|
@@ -6855,8 +7405,8 @@ function isTailwindAvailable(cwd) {
|
|
|
6855
7405
|
return false;
|
|
6856
7406
|
}
|
|
6857
7407
|
function getTailwindPaths(cwd) {
|
|
6858
|
-
const input =
|
|
6859
|
-
const output =
|
|
7408
|
+
const input = join9(cwd, "src/client/theme.css");
|
|
7409
|
+
const output = join9(cwd, ".reroute/theme.css");
|
|
6860
7410
|
return { input, output };
|
|
6861
7411
|
}
|
|
6862
7412
|
function hasTailwindInput(cwd) {
|
|
@@ -6873,10 +7423,10 @@ function hasTailwindInput(cwd) {
|
|
|
6873
7423
|
}
|
|
6874
7424
|
function resolveTailwindBin(cwd) {
|
|
6875
7425
|
const pathsToTry = [
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
7426
|
+
join9(cwd, "node_modules/.bin/tailwindcss"),
|
|
7427
|
+
join9(cwd, "../node_modules/.bin/tailwindcss"),
|
|
7428
|
+
join9(cwd, "../../node_modules/.bin/tailwindcss"),
|
|
7429
|
+
join9(cwd, "../../../node_modules/.bin/tailwindcss")
|
|
6880
7430
|
];
|
|
6881
7431
|
for (const binPath of pathsToTry) {
|
|
6882
7432
|
if (existsSync5(binPath)) {
|
|
@@ -6947,12 +7497,12 @@ __export(exports_gen, {
|
|
|
6947
7497
|
default: () => gen
|
|
6948
7498
|
});
|
|
6949
7499
|
import { watch } from "node:fs";
|
|
6950
|
-
import { mkdir as mkdir2, readdir as
|
|
6951
|
-
import { dirname as dirname5, join as
|
|
7500
|
+
import { mkdir as mkdir2, readdir as readdir7, rm } from "node:fs/promises";
|
|
7501
|
+
import { dirname as dirname5, join as join10 } from "node:path";
|
|
6952
7502
|
import { pathToFileURL as pathToFileURL8 } from "node:url";
|
|
6953
7503
|
async function bundleThemeCssIntoArtifacts(cwd) {
|
|
6954
|
-
const themeCssPath =
|
|
6955
|
-
const artifactsPath =
|
|
7504
|
+
const themeCssPath = join10(cwd, ".reroute", "theme.css");
|
|
7505
|
+
const artifactsPath = join10(cwd, OUTPUT_ARTIFACTS);
|
|
6956
7506
|
try {
|
|
6957
7507
|
const cssContent = await Bun.file(themeCssPath).text();
|
|
6958
7508
|
if (!cssContent)
|
|
@@ -6978,11 +7528,11 @@ async function bundleThemeCssIntoArtifacts(cwd) {
|
|
|
6978
7528
|
async function ensureOutputDir(cwd, options = {}) {
|
|
6979
7529
|
const { clean = true } = options;
|
|
6980
7530
|
try {
|
|
6981
|
-
const outputPath =
|
|
7531
|
+
const outputPath = join10(cwd, OUTPUT_DIR);
|
|
6982
7532
|
if (clean) {
|
|
6983
7533
|
let needsCleanup = false;
|
|
6984
7534
|
try {
|
|
6985
|
-
const entries = await
|
|
7535
|
+
const entries = await readdir7(outputPath);
|
|
6986
7536
|
needsCleanup = entries.length > 0;
|
|
6987
7537
|
} catch {}
|
|
6988
7538
|
if (needsCleanup) {
|
|
@@ -6991,9 +7541,9 @@ async function ensureOutputDir(cwd, options = {}) {
|
|
|
6991
7541
|
}
|
|
6992
7542
|
}
|
|
6993
7543
|
await mkdir2(outputPath, { recursive: true });
|
|
6994
|
-
await mkdir2(
|
|
6995
|
-
await mkdir2(
|
|
6996
|
-
await mkdir2(
|
|
7544
|
+
await mkdir2(join10(cwd, OUTPUT_COLLECTIONS_DIR), { recursive: true });
|
|
7545
|
+
await mkdir2(join10(cwd, ".reroute/bundles"), { recursive: true });
|
|
7546
|
+
await mkdir2(join10(cwd, ".reroute/streaming"), { recursive: true });
|
|
6997
7547
|
} catch {}
|
|
6998
7548
|
}
|
|
6999
7549
|
async function writeStubFiles(cwd) {
|
|
@@ -7051,11 +7601,11 @@ import './artifacts';
|
|
|
7051
7601
|
import './routes'; // Import routes (bundles all route components)
|
|
7052
7602
|
import '../src/index';
|
|
7053
7603
|
`;
|
|
7054
|
-
await Bun.write(
|
|
7055
|
-
await Bun.write(
|
|
7056
|
-
await Bun.write(
|
|
7057
|
-
await Bun.write(
|
|
7058
|
-
await Bun.write(
|
|
7604
|
+
await Bun.write(join10(cwd, OUTPUT_ROUTES), STUB_ROUTES);
|
|
7605
|
+
await Bun.write(join10(cwd, OUTPUT_CONTENT_TS), STUB_CONTENT);
|
|
7606
|
+
await Bun.write(join10(cwd, OUTPUT_ARTIFACTS), STUB_ARTIFACTS);
|
|
7607
|
+
await Bun.write(join10(cwd, OUTPUT_INDEX), STUB_INDEX);
|
|
7608
|
+
await Bun.write(join10(cwd, ".reroute/entry.ts"), STUB_ENTRY);
|
|
7059
7609
|
console.log("[reroute/gen] Initialized stub files");
|
|
7060
7610
|
}
|
|
7061
7611
|
function shouldSkipFile(relativePath, entryName) {
|
|
@@ -7075,10 +7625,10 @@ function shouldSkipFile(relativePath, entryName) {
|
|
|
7075
7625
|
}
|
|
7076
7626
|
async function scanDirectory(dir, base = "") {
|
|
7077
7627
|
const files = [];
|
|
7078
|
-
const entries = await
|
|
7628
|
+
const entries = await readdir7(dir, { withFileTypes: true });
|
|
7079
7629
|
for (const entry of entries) {
|
|
7080
|
-
const fullPath =
|
|
7081
|
-
const relativePath =
|
|
7630
|
+
const fullPath = join10(dir, entry.name);
|
|
7631
|
+
const relativePath = join10(base, entry.name);
|
|
7082
7632
|
if (entry.isDirectory()) {
|
|
7083
7633
|
if (entry.name === "content")
|
|
7084
7634
|
continue;
|
|
@@ -7094,10 +7644,10 @@ async function scanDirectory(dir, base = "") {
|
|
|
7094
7644
|
}
|
|
7095
7645
|
async function scan404Files(dir, base = "") {
|
|
7096
7646
|
const files = [];
|
|
7097
|
-
const entries = await
|
|
7647
|
+
const entries = await readdir7(dir, { withFileTypes: true });
|
|
7098
7648
|
for (const entry of entries) {
|
|
7099
|
-
const fullPath =
|
|
7100
|
-
const relativePath =
|
|
7649
|
+
const fullPath = join10(dir, entry.name);
|
|
7650
|
+
const relativePath = join10(base, entry.name);
|
|
7101
7651
|
if (entry.isDirectory()) {
|
|
7102
7652
|
const nested = await scan404Files(fullPath, relativePath);
|
|
7103
7653
|
files.push(...nested);
|
|
@@ -7110,10 +7660,10 @@ async function scan404Files(dir, base = "") {
|
|
|
7110
7660
|
}
|
|
7111
7661
|
async function scanOgFiles(dir, base = "") {
|
|
7112
7662
|
const files = [];
|
|
7113
|
-
const entries = await
|
|
7663
|
+
const entries = await readdir7(dir, { withFileTypes: true });
|
|
7114
7664
|
for (const entry of entries) {
|
|
7115
|
-
const fullPath =
|
|
7116
|
-
const relativePath =
|
|
7665
|
+
const fullPath = join10(dir, entry.name);
|
|
7666
|
+
const relativePath = join10(base, entry.name);
|
|
7117
7667
|
if (entry.isDirectory()) {
|
|
7118
7668
|
if (entry.name === "content")
|
|
7119
7669
|
continue;
|
|
@@ -7367,7 +7917,7 @@ function matchPattern(route: Route, pathname: string): Record<string, string> |
|
|
|
7367
7917
|
`;
|
|
7368
7918
|
}
|
|
7369
7919
|
async function buildStreamingWrappersForTree(cwd, routesPath, tree, config2) {
|
|
7370
|
-
const streamingDir =
|
|
7920
|
+
const streamingDir = join10(cwd, ".reroute", "streaming");
|
|
7371
7921
|
const analyses = new Map;
|
|
7372
7922
|
const candidates = [
|
|
7373
7923
|
...tree.routes.map((route) => ({
|
|
@@ -7386,7 +7936,7 @@ async function buildStreamingWrappersForTree(cwd, routesPath, tree, config2) {
|
|
|
7386
7936
|
for (const candidate of candidates) {
|
|
7387
7937
|
if (!/\.(tsx|ts)$/.test(candidate.filePath))
|
|
7388
7938
|
continue;
|
|
7389
|
-
const absolutePath =
|
|
7939
|
+
const absolutePath = join10(routesPath, candidate.filePath);
|
|
7390
7940
|
const analysis = await analyzeRouteForStreaming({
|
|
7391
7941
|
absolutePath,
|
|
7392
7942
|
relativePath: candidate.filePath,
|
|
@@ -7395,7 +7945,7 @@ async function buildStreamingWrappersForTree(cwd, routesPath, tree, config2) {
|
|
|
7395
7945
|
});
|
|
7396
7946
|
if (!analysis.needsStreaming)
|
|
7397
7947
|
continue;
|
|
7398
|
-
const wrapperPath =
|
|
7948
|
+
const wrapperPath = join10(streamingDir, candidate.filePath).replace(/\.(tsx|ts)$/, ".tsx");
|
|
7399
7949
|
await mkdir2(dirname5(wrapperPath), { recursive: true });
|
|
7400
7950
|
const code = await generateStreamingWrapper({
|
|
7401
7951
|
cwd,
|
|
@@ -7412,10 +7962,42 @@ async function buildStreamingWrappersForTree(cwd, routesPath, tree, config2) {
|
|
|
7412
7962
|
}
|
|
7413
7963
|
return analyses;
|
|
7414
7964
|
}
|
|
7965
|
+
function isLocaleDirName(name) {
|
|
7966
|
+
return /^[a-z]{2}(?:-[A-Za-z0-9]{2,8})*$/i.test(name);
|
|
7967
|
+
}
|
|
7968
|
+
function isContentFileName(name) {
|
|
7969
|
+
return /\.(tsx|ts|md|mdx)$/.test(name) && !name.startsWith("_");
|
|
7970
|
+
}
|
|
7971
|
+
async function listLocaleContentFiles(collectionDir, locale) {
|
|
7972
|
+
try {
|
|
7973
|
+
const nested = await readdir7(join10(collectionDir, locale), {
|
|
7974
|
+
withFileTypes: true
|
|
7975
|
+
});
|
|
7976
|
+
const files = [];
|
|
7977
|
+
for (const n of nested) {
|
|
7978
|
+
if (n.isFile() && isContentFileName(n.name)) {
|
|
7979
|
+
files.push({ relativePath: join10(locale, n.name), locale });
|
|
7980
|
+
}
|
|
7981
|
+
}
|
|
7982
|
+
return files;
|
|
7983
|
+
} catch {
|
|
7984
|
+
return [];
|
|
7985
|
+
}
|
|
7986
|
+
}
|
|
7415
7987
|
async function listContentFiles2(collectionDir) {
|
|
7416
7988
|
try {
|
|
7417
|
-
const entries = await
|
|
7418
|
-
|
|
7989
|
+
const entries = await readdir7(collectionDir, { withFileTypes: true });
|
|
7990
|
+
const files = [];
|
|
7991
|
+
for (const entry of entries) {
|
|
7992
|
+
if (entry.isFile() && isContentFileName(entry.name)) {
|
|
7993
|
+
files.push({ relativePath: entry.name });
|
|
7994
|
+
continue;
|
|
7995
|
+
}
|
|
7996
|
+
if (entry.isDirectory() && isLocaleDirName(entry.name)) {
|
|
7997
|
+
files.push(...await listLocaleContentFiles(collectionDir, entry.name));
|
|
7998
|
+
}
|
|
7999
|
+
}
|
|
8000
|
+
return files;
|
|
7419
8001
|
} catch {
|
|
7420
8002
|
return [];
|
|
7421
8003
|
}
|
|
@@ -7472,11 +8054,14 @@ ${spaces}}`;
|
|
|
7472
8054
|
}
|
|
7473
8055
|
return serializeValue(config2);
|
|
7474
8056
|
}
|
|
7475
|
-
async function buildSingleContentChunk(cwd, collection,
|
|
7476
|
-
const
|
|
7477
|
-
const
|
|
8057
|
+
async function buildSingleContentChunk(cwd, collection, fileRef, contentDir, args, defaultLocale) {
|
|
8058
|
+
const file = fileRef.relativePath;
|
|
8059
|
+
const locale = fileRef.locale || defaultLocale;
|
|
8060
|
+
const baseName = file.split("/").pop() || file;
|
|
8061
|
+
const name = baseName.replace(/\.(tsx|ts|md|mdx)$/, "");
|
|
8062
|
+
const absSrc = join10(contentDir, file);
|
|
7478
8063
|
const isMarkdown = /\.(md|mdx)$/.test(file);
|
|
7479
|
-
const buildSrc = isMarkdown ?
|
|
8064
|
+
const buildSrc = isMarkdown ? join10(cwd, ".reroute", "markdown", collection, "content", file.replace(/\.(md|mdx)$/, ".tsx")) : absSrc;
|
|
7480
8065
|
if (isMarkdown) {
|
|
7481
8066
|
try {
|
|
7482
8067
|
const exists = await Bun.file(buildSrc).exists();
|
|
@@ -7522,10 +8107,11 @@ async function buildSingleContentChunk(cwd, collection, file, contentDir, args)
|
|
|
7522
8107
|
return null;
|
|
7523
8108
|
}
|
|
7524
8109
|
const hash2 = await sha8(code);
|
|
7525
|
-
const chunkRelDir =
|
|
7526
|
-
const chunkAbsDir =
|
|
7527
|
-
const
|
|
7528
|
-
const
|
|
8110
|
+
const chunkRelDir = join10(".reroute", "bundles");
|
|
8111
|
+
const chunkAbsDir = join10(cwd, chunkRelDir);
|
|
8112
|
+
const localeSuffix = locale !== defaultLocale ? `${locale}-` : "";
|
|
8113
|
+
const outFile = `${collection}-${localeSuffix}${name}.${hash2}.js`;
|
|
8114
|
+
const absOut = join10(chunkAbsDir, outFile);
|
|
7529
8115
|
if (sourcemapContent) {
|
|
7530
8116
|
code = code.replace(/\/\/# sourceMappingURL=.*\.js\.map/, `//# sourceMappingURL=${outFile}.map`);
|
|
7531
8117
|
}
|
|
@@ -7555,26 +8141,27 @@ async function buildSingleContentChunk(cwd, collection, file, contentDir, args)
|
|
|
7555
8141
|
slug: name,
|
|
7556
8142
|
href: `/${collection}/${name}`,
|
|
7557
8143
|
moduleUrl: `/bundles/${outFile}`,
|
|
7558
|
-
meta
|
|
8144
|
+
meta,
|
|
8145
|
+
locale
|
|
7559
8146
|
};
|
|
7560
8147
|
}
|
|
7561
|
-
async function buildContentChunks(cwd, args = []) {
|
|
7562
|
-
const routesRoot =
|
|
8148
|
+
async function buildContentChunks(cwd, args = [], defaultLocale = "en-US") {
|
|
8149
|
+
const routesRoot = join10(cwd, ROUTES_DIR);
|
|
7563
8150
|
console.log(`[reroute/content] scan ${routesRoot}`);
|
|
7564
|
-
const collections2 = await
|
|
8151
|
+
const collections2 = await readdir7(routesRoot, { withFileTypes: true });
|
|
7565
8152
|
const results = [];
|
|
7566
8153
|
for (const c of collections2) {
|
|
7567
8154
|
if (!c.isDirectory())
|
|
7568
8155
|
continue;
|
|
7569
8156
|
const collection = c.name;
|
|
7570
|
-
const contentDir =
|
|
8157
|
+
const contentDir = join10(routesRoot, collection, "content");
|
|
7571
8158
|
console.log(`[reroute/content] collection ${collection} dir ${contentDir}`);
|
|
7572
8159
|
const files = await listContentFiles2(contentDir);
|
|
7573
8160
|
console.log(`[reroute/content] files ${files.length}`);
|
|
7574
8161
|
if (!files.length)
|
|
7575
8162
|
continue;
|
|
7576
8163
|
for (const file of files) {
|
|
7577
|
-
const result = await buildSingleContentChunk(cwd, collection, file, contentDir, args);
|
|
8164
|
+
const result = await buildSingleContentChunk(cwd, collection, file, contentDir, args, defaultLocale);
|
|
7578
8165
|
if (result) {
|
|
7579
8166
|
results.push(result);
|
|
7580
8167
|
}
|
|
@@ -7587,7 +8174,7 @@ async function buildContentChunks(cwd, args = []) {
|
|
|
7587
8174
|
lines.push("");
|
|
7588
8175
|
lines.push("export const contents = [");
|
|
7589
8176
|
for (const e of results) {
|
|
7590
|
-
lines.push(" { collection: '" + e.collection + "', slug: '" + e.slug + "', name: '" + e.name + "', href: '" + e.href + "', module: '" + e.moduleUrl + "', meta: " + JSON.stringify(e.meta || {}) + " },");
|
|
8177
|
+
lines.push(" { collection: '" + e.collection + "', slug: '" + e.slug + "', name: '" + e.name + "', href: '" + e.href + "', module: '" + e.moduleUrl + "', locale: '" + e.locale + "', meta: " + JSON.stringify(e.meta || {}) + " },");
|
|
7591
8178
|
}
|
|
7592
8179
|
lines.push("] as const;");
|
|
7593
8180
|
lines.push("");
|
|
@@ -7595,20 +8182,31 @@ async function buildContentChunks(cwd, args = []) {
|
|
|
7595
8182
|
lines.push("for (const c of contents) { (byCollection[c.collection] ||= []).push(c as any); }");
|
|
7596
8183
|
lines.push("");
|
|
7597
8184
|
lines.push("export const byCollectionAndName: Record<string, Record<string, any>> = {};");
|
|
7598
|
-
lines.push("for (const c of contents) {
|
|
8185
|
+
lines.push("for (const c of contents) {");
|
|
8186
|
+
lines.push(` const cur = (byCollectionAndName[c.collection] ||= {})[c.name];`);
|
|
8187
|
+
lines.push(` if (!cur || c.locale === ${JSON.stringify(defaultLocale)}) (byCollectionAndName[c.collection] ||= {})[c.name] = c as any;`);
|
|
8188
|
+
lines.push("}");
|
|
8189
|
+
lines.push("");
|
|
8190
|
+
lines.push("export const byCollectionNameLocale: Record<string, Record<string, Record<string, any>>> = {};");
|
|
8191
|
+
lines.push("for (const c of contents) { (((byCollectionNameLocale[c.collection] ||= {})[c.name] ||= {})[c.locale] = c as any); }");
|
|
7599
8192
|
lines.push("");
|
|
7600
8193
|
lines.push("export type Collections = keyof typeof byCollection;");
|
|
7601
8194
|
lines.push("export type Names<C extends Collections> = keyof (typeof byCollectionAndName)[C];");
|
|
7602
8195
|
lines.push("export type ContentEntry = (typeof contents)[number];");
|
|
7603
8196
|
lines.push("");
|
|
7604
|
-
lines.push("export function getContentEntry<C extends string, N extends string>(collection: C, name: N) {");
|
|
8197
|
+
lines.push("export function getContentEntry<C extends string, N extends string>(collection: C, name: N, locale?: string) {");
|
|
8198
|
+
lines.push(" if (locale) {");
|
|
8199
|
+
lines.push(" const byLocale = (byCollectionNameLocale as any)[collection]?.[name];");
|
|
8200
|
+
lines.push(" if (byLocale?.[locale]) return byLocale[locale];");
|
|
8201
|
+
lines.push(` if (byLocale?.[${JSON.stringify(defaultLocale)}]) return byLocale[${JSON.stringify(defaultLocale)}];`);
|
|
8202
|
+
lines.push(" }");
|
|
7605
8203
|
lines.push(" const m = (byCollectionAndName as any)[collection];");
|
|
7606
8204
|
lines.push(" return m ? (m as Record<string, any>)[name] : undefined;");
|
|
7607
8205
|
lines.push("}");
|
|
7608
8206
|
lines.push("");
|
|
7609
8207
|
const writes = [];
|
|
7610
8208
|
writes.push({
|
|
7611
|
-
path:
|
|
8209
|
+
path: join10(cwd, OUTPUT_CONTENT_TS),
|
|
7612
8210
|
content: lines.join(`
|
|
7613
8211
|
`)
|
|
7614
8212
|
});
|
|
@@ -7620,20 +8218,29 @@ async function buildContentChunks(cwd, args = []) {
|
|
|
7620
8218
|
js.push("");
|
|
7621
8219
|
js.push("export const items = [");
|
|
7622
8220
|
for (const e of items) {
|
|
7623
|
-
js.push(` { collection: '${e.collection}', slug: '${e.slug}', name: '${e.name}', href: '${e.href}', module: '${e.moduleUrl}', meta: ${JSON.stringify(e.meta || {})} },`);
|
|
8221
|
+
js.push(` { collection: '${e.collection}', slug: '${e.slug}', name: '${e.name}', href: '${e.href}', module: '${e.moduleUrl}', locale: '${e.locale}', meta: ${JSON.stringify(e.meta || {})} },`);
|
|
7624
8222
|
}
|
|
7625
8223
|
js.push("];");
|
|
7626
8224
|
js.push("");
|
|
7627
8225
|
js.push("export const byName = {};");
|
|
7628
|
-
js.push("
|
|
8226
|
+
js.push("export const byNameLocale = {};");
|
|
8227
|
+
js.push("for (const it of items) {");
|
|
8228
|
+
js.push(" ((byNameLocale[it.name] ||= {})[it.locale] = it);");
|
|
8229
|
+
js.push(` if (!byName[it.name] || it.locale === ${JSON.stringify(defaultLocale)}) byName[it.name] = it;`);
|
|
8230
|
+
js.push("}");
|
|
7629
8231
|
js.push("");
|
|
7630
|
-
js.push(
|
|
8232
|
+
js.push(`export const defaultLocale = ${JSON.stringify(defaultLocale)};`);
|
|
8233
|
+
js.push("");
|
|
8234
|
+
js.push("export function get(collectionName, name, locale) {");
|
|
7631
8235
|
js.push(` if (collectionName !== '${collection}') return undefined;`);
|
|
8236
|
+
js.push(" if (locale && byNameLocale[name]) {");
|
|
8237
|
+
js.push(" return byNameLocale[name][locale] || byNameLocale[name][defaultLocale] || byName[name];");
|
|
8238
|
+
js.push(" }");
|
|
7632
8239
|
js.push(" return byName[name];");
|
|
7633
8240
|
js.push("}");
|
|
7634
8241
|
js.push("");
|
|
7635
8242
|
writes.push({
|
|
7636
|
-
path:
|
|
8243
|
+
path: join10(cwd, OUTPUT_COLLECTIONS_DIR, `${collection}.js`),
|
|
7637
8244
|
content: js.join(`
|
|
7638
8245
|
`)
|
|
7639
8246
|
});
|
|
@@ -7657,8 +8264,10 @@ async function buildSearchIndex(cwd, config2, args = []) {
|
|
|
7657
8264
|
minHeadingLevel = 1,
|
|
7658
8265
|
maxHeadingLevel = 6
|
|
7659
8266
|
} = searchConfig;
|
|
7660
|
-
const routesRoot =
|
|
7661
|
-
const collections2 = await
|
|
8267
|
+
const routesRoot = join10(cwd, ROUTES_DIR);
|
|
8268
|
+
const collections2 = await readdir7(routesRoot, { withFileTypes: true });
|
|
8269
|
+
const i18n2 = await discoverI18n(cwd, config2.i18n);
|
|
8270
|
+
const defaultLocale = i18n2.defaultLocale;
|
|
7662
8271
|
const searchIndex = [];
|
|
7663
8272
|
for (const c of collections2) {
|
|
7664
8273
|
if (!c.isDirectory())
|
|
@@ -7667,14 +8276,17 @@ async function buildSearchIndex(cwd, config2, args = []) {
|
|
|
7667
8276
|
if (targetCollections.length > 0 && !targetCollections.includes(collection)) {
|
|
7668
8277
|
continue;
|
|
7669
8278
|
}
|
|
7670
|
-
const contentDir =
|
|
8279
|
+
const contentDir = join10(routesRoot, collection, "content");
|
|
7671
8280
|
try {
|
|
7672
|
-
const files = await
|
|
7673
|
-
for (const
|
|
8281
|
+
const files = await listContentFiles2(contentDir);
|
|
8282
|
+
for (const fileRef of files) {
|
|
8283
|
+
const file = fileRef.relativePath;
|
|
7674
8284
|
if (!/\.(md|mdx)$/.test(file))
|
|
7675
8285
|
continue;
|
|
7676
|
-
const
|
|
7677
|
-
const
|
|
8286
|
+
const baseName = file.split("/").pop() || file;
|
|
8287
|
+
const name = baseName.replace(/\.(md|mdx)$/, "");
|
|
8288
|
+
const locale = fileRef.locale || defaultLocale;
|
|
8289
|
+
const filePath = join10(contentDir, file);
|
|
7678
8290
|
try {
|
|
7679
8291
|
const processed = processMarkdownFile(filePath);
|
|
7680
8292
|
const { frontmatter, content: content2 } = processed;
|
|
@@ -7688,16 +8300,18 @@ async function buildSearchIndex(cwd, config2, args = []) {
|
|
|
7688
8300
|
maxLevel: maxHeadingLevel
|
|
7689
8301
|
});
|
|
7690
8302
|
const excerpt = String(frontmatter?.excerpt || frontmatter?.description || stripMarkdown(content2).slice(0, 160));
|
|
8303
|
+
const href = localizeContentHref(collection, name, locale, defaultLocale);
|
|
7691
8304
|
const entry = {
|
|
7692
|
-
id: `${collection}:${name}`,
|
|
8305
|
+
id: locale !== defaultLocale ? `${collection}:${name}:${locale}` : `${collection}:${name}`,
|
|
7693
8306
|
collection,
|
|
7694
8307
|
name,
|
|
7695
8308
|
slug: name,
|
|
7696
|
-
href
|
|
8309
|
+
href,
|
|
7697
8310
|
title: String(frontmatter?.title || name),
|
|
7698
8311
|
excerpt,
|
|
7699
8312
|
headings,
|
|
7700
|
-
meta: {}
|
|
8313
|
+
meta: {},
|
|
8314
|
+
locale
|
|
7701
8315
|
};
|
|
7702
8316
|
for (const field of metaFields) {
|
|
7703
8317
|
if (frontmatter[field] !== undefined) {
|
|
@@ -7720,13 +8334,13 @@ async function buildSearchIndex(cwd, config2, args = []) {
|
|
|
7720
8334
|
generated: new Date().toISOString(),
|
|
7721
8335
|
entries: searchIndex
|
|
7722
8336
|
};
|
|
7723
|
-
await Bun.write(
|
|
7724
|
-
console.log(`[reroute/search] Generated search index with ${searchIndex.length} entries: ${
|
|
8337
|
+
await Bun.write(join10(cwd, OUTPUT_SEARCH_INDEX), JSON.stringify(indexData, null, 2));
|
|
8338
|
+
console.log(`[reroute/search] Generated search index with ${searchIndex.length} entries: ${join10(cwd, OUTPUT_SEARCH_INDEX)}`);
|
|
7725
8339
|
}
|
|
7726
8340
|
async function preprocessMarkdownFiles(cwd, config2) {
|
|
7727
8341
|
console.log("[reroute/markdown] Starting markdown preprocessing...");
|
|
7728
|
-
const routesPath =
|
|
7729
|
-
const markdownDir =
|
|
8342
|
+
const routesPath = join10(cwd, ROUTES_DIR);
|
|
8343
|
+
const markdownDir = join10(cwd, ".reroute", "markdown");
|
|
7730
8344
|
try {
|
|
7731
8345
|
await rm(markdownDir, { force: true, recursive: true });
|
|
7732
8346
|
} catch {}
|
|
@@ -7734,10 +8348,10 @@ async function preprocessMarkdownFiles(cwd, config2) {
|
|
|
7734
8348
|
async function scanMarkdown(dir, base = "") {
|
|
7735
8349
|
const files = [];
|
|
7736
8350
|
try {
|
|
7737
|
-
const entries = await
|
|
8351
|
+
const entries = await readdir7(dir, { withFileTypes: true });
|
|
7738
8352
|
for (const entry of entries) {
|
|
7739
|
-
const fullPath =
|
|
7740
|
-
const relativePath =
|
|
8353
|
+
const fullPath = join10(dir, entry.name);
|
|
8354
|
+
const relativePath = join10(base, entry.name);
|
|
7741
8355
|
if (entry.isDirectory()) {
|
|
7742
8356
|
const nested = await scanMarkdown(fullPath, relativePath);
|
|
7743
8357
|
files.push(...nested);
|
|
@@ -7759,8 +8373,8 @@ async function preprocessMarkdownFiles(cwd, config2) {
|
|
|
7759
8373
|
}
|
|
7760
8374
|
console.log(`[reroute/markdown] Found ${markdownFiles.length} markdown file(s)`);
|
|
7761
8375
|
for (const file of markdownFiles) {
|
|
7762
|
-
const sourcePath =
|
|
7763
|
-
const targetPath =
|
|
8376
|
+
const sourcePath = join10(routesPath, file);
|
|
8377
|
+
const targetPath = join10(markdownDir, file.replace(/\.mdx?$/, ".tsx"));
|
|
7764
8378
|
try {
|
|
7765
8379
|
const processed = processMarkdownFile(sourcePath);
|
|
7766
8380
|
const isMdx = file.endsWith(".mdx");
|
|
@@ -7786,8 +8400,8 @@ async function preprocessMarkdownFiles(cwd, config2) {
|
|
|
7786
8400
|
}
|
|
7787
8401
|
async function buildEntrypointBundle(cwd, args = []) {
|
|
7788
8402
|
const buildStartTime = performance.now();
|
|
7789
|
-
const clientDir =
|
|
7790
|
-
const entrypoint =
|
|
8403
|
+
const clientDir = join10(cwd, "src", "client");
|
|
8404
|
+
const entrypoint = join10(clientDir, "index.tsx");
|
|
7791
8405
|
const exists = await Bun.file(entrypoint).exists();
|
|
7792
8406
|
if (!exists) {
|
|
7793
8407
|
console.log("[reroute/gen] No index.tsx found, skipping bundle build");
|
|
@@ -7795,7 +8409,7 @@ async function buildEntrypointBundle(cwd, args = []) {
|
|
|
7795
8409
|
}
|
|
7796
8410
|
console.log("[reroute/gen] Building entrypoint bundle...");
|
|
7797
8411
|
const isProd = args.includes("--prod");
|
|
7798
|
-
const bundlesDir =
|
|
8412
|
+
const bundlesDir = join10(cwd, ".reroute", "bundles");
|
|
7799
8413
|
await mkdir2(bundlesDir, { recursive: true });
|
|
7800
8414
|
const mode = isProd ? "production" : "development";
|
|
7801
8415
|
const publicEnv = getPublicEnvVars(cwd, mode);
|
|
@@ -7894,10 +8508,10 @@ async function buildEntrypointBundle(cwd, args = []) {
|
|
|
7894
8508
|
}
|
|
7895
8509
|
const newFiles = new Set(outputs.map((o) => o.fileName));
|
|
7896
8510
|
try {
|
|
7897
|
-
const existingFiles = await
|
|
8511
|
+
const existingFiles = await readdir7(bundlesDir);
|
|
7898
8512
|
for (const file of existingFiles) {
|
|
7899
8513
|
if (/^(index|chunk|asset)\.[a-z0-9]+\.(js|css|js\.map|css\.map)(\.gz|\.br)?$/i.test(file) && !newFiles.has(file.replace(/\.(gz|br)$/, ""))) {
|
|
7900
|
-
await rm(
|
|
8514
|
+
await rm(join10(bundlesDir, file), { force: true });
|
|
7901
8515
|
}
|
|
7902
8516
|
}
|
|
7903
8517
|
} catch (_error) {}
|
|
@@ -7913,7 +8527,7 @@ async function buildEntrypointBundle(cwd, args = []) {
|
|
|
7913
8527
|
}
|
|
7914
8528
|
}
|
|
7915
8529
|
await Promise.all(outputs.map(async (output) => {
|
|
7916
|
-
const destPath =
|
|
8530
|
+
const destPath = join10(bundlesDir, output.fileName);
|
|
7917
8531
|
await Bun.write(destPath, output.content);
|
|
7918
8532
|
if (shouldPreCompress) {
|
|
7919
8533
|
const shouldCompress = /\.(js|css)$/i.test(output.fileName) && !output.fileName.endsWith(".map");
|
|
@@ -7982,7 +8596,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
7982
8596
|
await writeStubFiles(cwd);
|
|
7983
8597
|
}
|
|
7984
8598
|
await perfTrack("Markdown preprocessing", () => preprocessMarkdownFiles(cwd, config2));
|
|
7985
|
-
const routesPath =
|
|
8599
|
+
const routesPath = join10(cwd, ROUTES_DIR);
|
|
7986
8600
|
try {
|
|
7987
8601
|
await perfTrack("Routes generation", async () => {
|
|
7988
8602
|
const files = await scanDirectory(routesPath);
|
|
@@ -7991,19 +8605,36 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
7991
8605
|
const tree = generateRouteTree(all.map((f) => f.replace(/\\/g, "/")));
|
|
7992
8606
|
const streamingAnalyses = streamingEnabled ? await buildStreamingWrappersForTree(cwd, routesPath, tree, config2) : new Map;
|
|
7993
8607
|
const ts = generateTypeScript(tree, streamingAnalyses);
|
|
7994
|
-
await Bun.write(
|
|
8608
|
+
await Bun.write(join10(cwd, OUTPUT_ROUTES), ts);
|
|
7995
8609
|
});
|
|
7996
8610
|
if (!showPerformance) {
|
|
7997
|
-
console.log(`[reroute/gen] Generated routes: ${
|
|
8611
|
+
console.log(`[reroute/gen] Generated routes: ${join10(cwd, OUTPUT_ROUTES)}`);
|
|
7998
8612
|
}
|
|
7999
8613
|
} catch (error) {
|
|
8000
8614
|
console.error("[reroute/gen] Failed to generate routes:", error);
|
|
8001
8615
|
throw error;
|
|
8002
8616
|
}
|
|
8617
|
+
const i18n2 = await discoverI18n(cwd, config2.i18n);
|
|
8618
|
+
const defaultLocale = i18n2.defaultLocale;
|
|
8619
|
+
try {
|
|
8620
|
+
await Bun.write(join10(cwd, ".reroute", "i18n.json"), JSON.stringify({
|
|
8621
|
+
enabled: i18n2.enabled,
|
|
8622
|
+
defaultLocale: i18n2.defaultLocale,
|
|
8623
|
+
locales: i18n2.locales,
|
|
8624
|
+
cookie: i18n2.cookie,
|
|
8625
|
+
redirectContentOnNegotiate: i18n2.redirectContentOnNegotiate,
|
|
8626
|
+
catalogs: i18n2.catalogs
|
|
8627
|
+
}, null, 2));
|
|
8628
|
+
if (i18n2.enabled && !showPerformance) {
|
|
8629
|
+
console.log(`[reroute/gen] i18n enabled: ${i18n2.locales.join(", ")} (default ${i18n2.defaultLocale})`);
|
|
8630
|
+
}
|
|
8631
|
+
} catch (error) {
|
|
8632
|
+
console.warn("[reroute/gen] Failed to write i18n.json:", error);
|
|
8633
|
+
}
|
|
8003
8634
|
try {
|
|
8004
|
-
await perfTrack("Content building", () => buildContentChunks(cwd, args));
|
|
8635
|
+
await perfTrack("Content building", () => buildContentChunks(cwd, args, defaultLocale));
|
|
8005
8636
|
if (!showPerformance) {
|
|
8006
|
-
console.log(`[reroute/gen] Generated content: ${
|
|
8637
|
+
console.log(`[reroute/gen] Generated content: ${join10(cwd, OUTPUT_CONTENT_TS)} + collections/*.js`);
|
|
8007
8638
|
}
|
|
8008
8639
|
} catch (error) {
|
|
8009
8640
|
console.error("[reroute/gen] Failed to generate content:", error);
|
|
@@ -8011,22 +8642,25 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
8011
8642
|
}
|
|
8012
8643
|
try {
|
|
8013
8644
|
await perfTrack("Manifest generation", async () => {
|
|
8014
|
-
const routesPath2 =
|
|
8645
|
+
const routesPath2 = join10(cwd, OUTPUT_ROUTES);
|
|
8015
8646
|
const routesModule = await import(`file://${routesPath2}?t=${Date.now()}`);
|
|
8016
8647
|
const routes = routesModule.routes || [];
|
|
8017
8648
|
const staticRoutes = routes.filter((r) => !r.params || r.params.length === 0).map((r) => r.pattern);
|
|
8018
8649
|
const contentRoutes = [];
|
|
8019
|
-
const collectionsDir =
|
|
8650
|
+
const collectionsDir = join10(cwd, ".reroute", "collections");
|
|
8020
8651
|
try {
|
|
8021
|
-
const collectionFiles = await
|
|
8652
|
+
const collectionFiles = await readdir7(collectionsDir);
|
|
8022
8653
|
for (const file of collectionFiles) {
|
|
8023
8654
|
if (file.endsWith(".js")) {
|
|
8024
|
-
const collectionPath =
|
|
8655
|
+
const collectionPath = join10(collectionsDir, file);
|
|
8025
8656
|
const collectionModule = await import(`file://${collectionPath}?t=${Date.now()}`);
|
|
8026
8657
|
const items = collectionModule.items || [];
|
|
8027
8658
|
for (const item of items) {
|
|
8028
8659
|
if (item.href) {
|
|
8029
8660
|
contentRoutes.push(item.href);
|
|
8661
|
+
if (i18n2.enabled && item.locale && item.locale !== defaultLocale && item.name) {
|
|
8662
|
+
contentRoutes.push(localizeContentHref(item.collection || file.replace(/\.js$/, ""), item.name, item.locale, defaultLocale));
|
|
8663
|
+
}
|
|
8030
8664
|
}
|
|
8031
8665
|
}
|
|
8032
8666
|
}
|
|
@@ -8043,7 +8677,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
8043
8677
|
dynamicRoutes,
|
|
8044
8678
|
version: 1
|
|
8045
8679
|
};
|
|
8046
|
-
await Bun.write(
|
|
8680
|
+
await Bun.write(join10(cwd, ".reroute", "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
8047
8681
|
});
|
|
8048
8682
|
} catch (error) {
|
|
8049
8683
|
console.error("[reroute/gen] Failed to generate manifest:", error);
|
|
@@ -8064,7 +8698,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
8064
8698
|
mdComponentsLines.push("");
|
|
8065
8699
|
mdComponentsLines.push(`import markdownComponents from '${componentsPath}';`);
|
|
8066
8700
|
mdComponentsLines.push("export { markdownComponents };");
|
|
8067
|
-
await Bun.write(
|
|
8701
|
+
await Bun.write(join10(cwd, ".reroute/markdown-components.ts"), mdComponentsLines.join(`
|
|
8068
8702
|
`));
|
|
8069
8703
|
}
|
|
8070
8704
|
const indexLines = [];
|
|
@@ -8084,7 +8718,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
8084
8718
|
const ogTemplatePath = config2.ogImage.defaultTemplate.startsWith(".") ? `../${config2.ogImage.defaultTemplate}` : config2.ogImage.defaultTemplate;
|
|
8085
8719
|
indexLines.push(`import OGTemplate from '${ogTemplatePath}';`);
|
|
8086
8720
|
}
|
|
8087
|
-
const ogFiles = await scanOgFiles(
|
|
8721
|
+
const ogFiles = await scanOgFiles(join10(cwd, ROUTES_DIR));
|
|
8088
8722
|
const ogImports = [];
|
|
8089
8723
|
for (let i = 0;i < ogFiles.length; i++) {
|
|
8090
8724
|
const ogFile = ogFiles[i];
|
|
@@ -8130,7 +8764,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
8130
8764
|
}
|
|
8131
8765
|
indexLines.push("};");
|
|
8132
8766
|
}
|
|
8133
|
-
const templatePath =
|
|
8767
|
+
const templatePath = join10(cwd, "src", "client", "index.html");
|
|
8134
8768
|
try {
|
|
8135
8769
|
const templateContent = await Bun.file(templatePath).text();
|
|
8136
8770
|
indexLines.push("");
|
|
@@ -8142,7 +8776,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
8142
8776
|
indexLines.push(`(globalThis as any).__REROUTE_CONFIG__ = ${serializeConfig(config2)};`);
|
|
8143
8777
|
indexLines.push("");
|
|
8144
8778
|
indexLines.push("export type RerouteBundle = typeof bundle;");
|
|
8145
|
-
await Bun.write(
|
|
8779
|
+
await Bun.write(join10(cwd, OUTPUT_ARTIFACTS), indexLines.join(`
|
|
8146
8780
|
`));
|
|
8147
8781
|
const barrelLines = [
|
|
8148
8782
|
"// \uD83D\uDEA8 Auto-generated by Reroute - DO NOT EDIT \uD83D\uDEA8",
|
|
@@ -8152,7 +8786,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
8152
8786
|
"",
|
|
8153
8787
|
"export * from './artifacts';"
|
|
8154
8788
|
];
|
|
8155
|
-
await Bun.write(
|
|
8789
|
+
await Bun.write(join10(cwd, OUTPUT_INDEX), barrelLines.join(`
|
|
8156
8790
|
`));
|
|
8157
8791
|
const entryLines = [
|
|
8158
8792
|
"// \uD83D\uDEA8 Auto-generated by Reroute - DO NOT EDIT \uD83D\uDEA8",
|
|
@@ -8168,10 +8802,10 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
8168
8802
|
"import './routes'; // Import routes (bundles all route components)",
|
|
8169
8803
|
"import '../src/index'; // Import user's server entry"
|
|
8170
8804
|
];
|
|
8171
|
-
await Bun.write(
|
|
8805
|
+
await Bun.write(join10(cwd, ".reroute/entry.ts"), entryLines.join(`
|
|
8172
8806
|
`));
|
|
8173
8807
|
if (!showPerformance) {
|
|
8174
|
-
console.log(`[reroute/gen] Generated artifacts: ${
|
|
8808
|
+
console.log(`[reroute/gen] Generated artifacts: ${join10(cwd, OUTPUT_ARTIFACTS)}`);
|
|
8175
8809
|
}
|
|
8176
8810
|
await perfTrack("Bundle building", () => buildEntrypointBundle(cwd, args));
|
|
8177
8811
|
const endTime = performance.now();
|
|
@@ -8298,7 +8932,7 @@ async function gen(args) {
|
|
|
8298
8932
|
const mediumDebounce = createDebouncer(150);
|
|
8299
8933
|
const slowDebounce = createDebouncer(300);
|
|
8300
8934
|
const loadedConfig = await loadConfig(cwd);
|
|
8301
|
-
const configPath =
|
|
8935
|
+
const configPath = join10(cwd, "reroute.config.ts");
|
|
8302
8936
|
let configWatcher = null;
|
|
8303
8937
|
try {
|
|
8304
8938
|
configWatcher = watch(configPath, () => {
|
|
@@ -8320,7 +8954,7 @@ async function gen(args) {
|
|
|
8320
8954
|
];
|
|
8321
8955
|
const envWatchers = [];
|
|
8322
8956
|
for (const envFile of envFiles) {
|
|
8323
|
-
const envPath =
|
|
8957
|
+
const envPath = join10(cwd, envFile);
|
|
8324
8958
|
try {
|
|
8325
8959
|
const envWatcher = watch(envPath, () => {
|
|
8326
8960
|
mediumDebounce(() => {
|
|
@@ -8339,15 +8973,15 @@ async function gen(args) {
|
|
|
8339
8973
|
let packagesWatcher = null;
|
|
8340
8974
|
const isRerouteWorkspace = async () => {
|
|
8341
8975
|
try {
|
|
8342
|
-
const packagesPath =
|
|
8343
|
-
const exists = await Bun.file(
|
|
8976
|
+
const packagesPath = join10(cwd, "..", "..", "packages");
|
|
8977
|
+
const exists = await Bun.file(join10(packagesPath, "core", "index.ts")).exists();
|
|
8344
8978
|
return exists;
|
|
8345
8979
|
} catch {
|
|
8346
8980
|
return false;
|
|
8347
8981
|
}
|
|
8348
8982
|
};
|
|
8349
8983
|
if (await isRerouteWorkspace()) {
|
|
8350
|
-
const packagesPath =
|
|
8984
|
+
const packagesPath = join10(cwd, "..", "..", "packages");
|
|
8351
8985
|
console.log("[reroute/watch] \uD83D\uDD27 Workspace development mode enabled");
|
|
8352
8986
|
console.log(`[reroute/watch] \uD83D\uDD27 Watching ${packagesPath}...`);
|
|
8353
8987
|
packagesWatcher = watch(packagesPath, { recursive: true }, (_ev, filename) => {
|
|
@@ -8370,7 +9004,7 @@ async function gen(args) {
|
|
|
8370
9004
|
});
|
|
8371
9005
|
});
|
|
8372
9006
|
}
|
|
8373
|
-
const routesPath =
|
|
9007
|
+
const routesPath = join10(cwd, ROUTES_DIR);
|
|
8374
9008
|
console.log(`[reroute/watch] \uD83D\uDCC1 Watching ${routesPath}...`);
|
|
8375
9009
|
const routesWatcher = watch(routesPath, { recursive: true }, (_ev, filename) => {
|
|
8376
9010
|
if (!filename)
|
|
@@ -8392,7 +9026,16 @@ async function gen(args) {
|
|
|
8392
9026
|
}
|
|
8393
9027
|
console.log("[reroute/watch] ├─ Building content chunks...");
|
|
8394
9028
|
const contentStart = performance.now();
|
|
8395
|
-
await
|
|
9029
|
+
const watchI18n = await discoverI18n(cwd, loadedConfig.i18n);
|
|
9030
|
+
await Bun.write(join10(cwd, ".reroute", "i18n.json"), JSON.stringify({
|
|
9031
|
+
enabled: watchI18n.enabled,
|
|
9032
|
+
defaultLocale: watchI18n.defaultLocale,
|
|
9033
|
+
locales: watchI18n.locales,
|
|
9034
|
+
cookie: watchI18n.cookie,
|
|
9035
|
+
redirectContentOnNegotiate: watchI18n.redirectContentOnNegotiate,
|
|
9036
|
+
catalogs: watchI18n.catalogs
|
|
9037
|
+
}, null, 2));
|
|
9038
|
+
await buildContentChunks(cwd, args, watchI18n.defaultLocale);
|
|
8396
9039
|
const contentTime = ((performance.now() - contentStart) / 1000).toFixed(2);
|
|
8397
9040
|
console.log(`[reroute/watch] └─ Content: ${contentTime}s`);
|
|
8398
9041
|
if (loadedConfig.search?.enabled) {
|
|
@@ -8421,7 +9064,7 @@ async function gen(args) {
|
|
|
8421
9064
|
}, "routes change");
|
|
8422
9065
|
});
|
|
8423
9066
|
});
|
|
8424
|
-
const clientPath =
|
|
9067
|
+
const clientPath = join10(cwd, "src", "client");
|
|
8425
9068
|
console.log(`[reroute/watch] \uD83D\uDCE6 Watching ${clientPath}...`);
|
|
8426
9069
|
const twWatcher = watch(clientPath, { recursive: true }, (_ev, filename) => {
|
|
8427
9070
|
if (!filename)
|
|
@@ -9034,7 +9677,7 @@ var require_alias = __commonJS((exports) => {
|
|
|
9034
9677
|
|
|
9035
9678
|
// node_modules/.bun/blessed@0.1.81/node_modules/blessed/lib/tput.js
|
|
9036
9679
|
var require_tput = __commonJS((exports, module) => {
|
|
9037
|
-
var __dirname = "/
|
|
9680
|
+
var __dirname = "/home/runner/work/reroute/reroute/node_modules/.bun/blessed@0.1.81/node_modules/blessed/lib";
|
|
9038
9681
|
var assert = __require("assert");
|
|
9039
9682
|
var path3 = __require("path");
|
|
9040
9683
|
var fs = __require("fs");
|
|
@@ -13279,7 +13922,7 @@ var require_program = __commonJS((exports, module) => {
|
|
|
13279
13922
|
}
|
|
13280
13923
|
break;
|
|
13281
13924
|
case "underline":
|
|
13282
|
-
if (!blink) {}
|
|
13925
|
+
if (!blink) {}
|
|
13283
13926
|
break;
|
|
13284
13927
|
case "line":
|
|
13285
13928
|
if (!blink) {
|
|
@@ -100543,7 +101186,7 @@ var require_lodash = __commonJS((exports, module) => {
|
|
|
100543
101186
|
}
|
|
100544
101187
|
return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
|
|
100545
101188
|
});
|
|
100546
|
-
function
|
|
101189
|
+
function join11(array, separator) {
|
|
100547
101190
|
return array == null ? "" : nativeJoin.call(array, separator);
|
|
100548
101191
|
}
|
|
100549
101192
|
function last(array) {
|
|
@@ -102475,7 +103118,7 @@ __p += '`;
|
|
|
102475
103118
|
lodash.isUndefined = isUndefined;
|
|
102476
103119
|
lodash.isWeakMap = isWeakMap;
|
|
102477
103120
|
lodash.isWeakSet = isWeakSet;
|
|
102478
|
-
lodash.join =
|
|
103121
|
+
lodash.join = join11;
|
|
102479
103122
|
lodash.kebabCase = kebabCase;
|
|
102480
103123
|
lodash.last = last;
|
|
102481
103124
|
lodash.lastIndexOf = lastIndexOf;
|
|
@@ -103157,19 +103800,19 @@ __export(exports_dev, {
|
|
|
103157
103800
|
});
|
|
103158
103801
|
import { spawn as spawn2 } from "node:child_process";
|
|
103159
103802
|
import { existsSync as existsSync6 } from "node:fs";
|
|
103160
|
-
import { join as
|
|
103803
|
+
import { join as join11 } from "node:path";
|
|
103161
103804
|
function getRerouteCommand() {
|
|
103162
|
-
const binPath =
|
|
103805
|
+
const binPath = join11(import.meta.dir, "..", "..", "bin.ts");
|
|
103163
103806
|
const isBunDev = existsSync6(binPath);
|
|
103164
103807
|
if (isBunDev) {
|
|
103165
103808
|
return `bun ${binPath}`;
|
|
103166
103809
|
}
|
|
103167
103810
|
const cwd = process.cwd();
|
|
103168
103811
|
const nodeModulesPaths = [
|
|
103169
|
-
|
|
103170
|
-
|
|
103171
|
-
|
|
103172
|
-
|
|
103812
|
+
join11(cwd, "node_modules", ".bin", "reroute"),
|
|
103813
|
+
join11(cwd, "..", "node_modules", ".bin", "reroute"),
|
|
103814
|
+
join11(cwd, "..", "..", "node_modules", ".bin", "reroute"),
|
|
103815
|
+
join11(cwd, "..", "..", "..", "node_modules", ".bin", "reroute")
|
|
103173
103816
|
];
|
|
103174
103817
|
for (const binPath2 of nodeModulesPaths) {
|
|
103175
103818
|
if (existsSync6(binPath2)) {
|
|
@@ -103325,19 +103968,19 @@ __export(exports_start, {
|
|
|
103325
103968
|
});
|
|
103326
103969
|
import { spawn as spawn3 } from "node:child_process";
|
|
103327
103970
|
import { existsSync as existsSync7 } from "node:fs";
|
|
103328
|
-
import { join as
|
|
103971
|
+
import { join as join12 } from "node:path";
|
|
103329
103972
|
function getRerouteCommand2() {
|
|
103330
|
-
const binPath =
|
|
103973
|
+
const binPath = join12(import.meta.dir, "..", "..", "bin.ts");
|
|
103331
103974
|
const isBunDev = existsSync7(binPath);
|
|
103332
103975
|
if (isBunDev) {
|
|
103333
103976
|
return `bun ${binPath}`;
|
|
103334
103977
|
}
|
|
103335
103978
|
const cwd = process.cwd();
|
|
103336
103979
|
const nodeModulesPaths = [
|
|
103337
|
-
|
|
103338
|
-
|
|
103339
|
-
|
|
103340
|
-
|
|
103980
|
+
join12(cwd, "node_modules", ".bin", "reroute"),
|
|
103981
|
+
join12(cwd, "..", "node_modules", ".bin", "reroute"),
|
|
103982
|
+
join12(cwd, "..", "..", "node_modules", ".bin", "reroute"),
|
|
103983
|
+
join12(cwd, "..", "..", "..", "node_modules", ".bin", "reroute")
|
|
103341
103984
|
];
|
|
103342
103985
|
for (const binPath2 of nodeModulesPaths) {
|
|
103343
103986
|
if (existsSync7(binPath2)) {
|
|
@@ -103465,12 +104108,12 @@ import {
|
|
|
103465
104108
|
mkdirSync,
|
|
103466
104109
|
readdirSync
|
|
103467
104110
|
} from "node:fs";
|
|
103468
|
-
import { join as
|
|
104111
|
+
import { join as join13 } from "node:path";
|
|
103469
104112
|
function copyAssetsToReroute(cwd, sourceAssetsDir, rerouteAssetsDir) {
|
|
103470
104113
|
if (!existsSync8(sourceAssetsDir)) {
|
|
103471
104114
|
return 0;
|
|
103472
104115
|
}
|
|
103473
|
-
const rerouteDir =
|
|
104116
|
+
const rerouteDir = join13(cwd, ".reroute");
|
|
103474
104117
|
if (!existsSync8(rerouteDir)) {
|
|
103475
104118
|
mkdirSync(rerouteDir, { recursive: true });
|
|
103476
104119
|
}
|
|
@@ -103482,7 +104125,7 @@ function countFiles(dir) {
|
|
|
103482
104125
|
const entries = readdirSync(dir, { withFileTypes: true });
|
|
103483
104126
|
for (const entry of entries) {
|
|
103484
104127
|
if (entry.isDirectory()) {
|
|
103485
|
-
count += countFiles(
|
|
104128
|
+
count += countFiles(join13(dir, entry.name));
|
|
103486
104129
|
} else {
|
|
103487
104130
|
count++;
|
|
103488
104131
|
}
|
|
@@ -103498,19 +104141,19 @@ __export(exports_build, {
|
|
|
103498
104141
|
});
|
|
103499
104142
|
import { spawn as spawn4 } from "node:child_process";
|
|
103500
104143
|
import { existsSync as existsSync9, readFileSync as readFileSync5, rmSync, unlinkSync } from "node:fs";
|
|
103501
|
-
import { join as
|
|
104144
|
+
import { join as join14 } from "node:path";
|
|
103502
104145
|
function getRerouteCommand3() {
|
|
103503
|
-
const binPath =
|
|
104146
|
+
const binPath = join14(import.meta.dir, "..", "..", "bin.ts");
|
|
103504
104147
|
const isBunDev = existsSync9(binPath);
|
|
103505
104148
|
if (isBunDev) {
|
|
103506
104149
|
return `bun ${binPath}`;
|
|
103507
104150
|
}
|
|
103508
104151
|
const cwd = process.cwd();
|
|
103509
104152
|
const nodeModulesPaths = [
|
|
103510
|
-
|
|
103511
|
-
|
|
103512
|
-
|
|
103513
|
-
|
|
104153
|
+
join14(cwd, "node_modules", ".bin", "reroute"),
|
|
104154
|
+
join14(cwd, "..", "node_modules", ".bin", "reroute"),
|
|
104155
|
+
join14(cwd, "..", "..", "node_modules", ".bin", "reroute"),
|
|
104156
|
+
join14(cwd, "..", "..", "..", "node_modules", ".bin", "reroute")
|
|
103514
104157
|
];
|
|
103515
104158
|
for (const binPath2 of nodeModulesPaths) {
|
|
103516
104159
|
if (existsSync9(binPath2)) {
|
|
@@ -103521,7 +104164,7 @@ function getRerouteCommand3() {
|
|
|
103521
104164
|
}
|
|
103522
104165
|
function getOutputName() {
|
|
103523
104166
|
const cwd = process.cwd();
|
|
103524
|
-
const packageJsonPath =
|
|
104167
|
+
const packageJsonPath = join14(cwd, "package.json");
|
|
103525
104168
|
if (existsSync9(packageJsonPath)) {
|
|
103526
104169
|
try {
|
|
103527
104170
|
const packageJson = JSON.parse(readFileSync5(packageJsonPath, "utf-8"));
|
|
@@ -103553,7 +104196,7 @@ function parseBuildArgs(args) {
|
|
|
103553
104196
|
return { outfile, compileBinary, noCompression, externalArgs };
|
|
103554
104197
|
}
|
|
103555
104198
|
function cleanDistFolder(cwd) {
|
|
103556
|
-
const distDir =
|
|
104199
|
+
const distDir = join14(cwd, "dist");
|
|
103557
104200
|
if (existsSync9(distDir)) {
|
|
103558
104201
|
process.stdout.write(colorizeLogPrefixAnsi(`[reroute/build] Cleaning dist folder...
|
|
103559
104202
|
`));
|
|
@@ -103561,7 +104204,7 @@ function cleanDistFolder(cwd) {
|
|
|
103561
104204
|
}
|
|
103562
104205
|
}
|
|
103563
104206
|
async function cleanRerouteFolder(cwd) {
|
|
103564
|
-
const rerouteDir =
|
|
104207
|
+
const rerouteDir = join14(cwd, ".reroute");
|
|
103565
104208
|
if (existsSync9(rerouteDir)) {
|
|
103566
104209
|
process.stdout.write(colorizeLogPrefixAnsi(`[reroute/build] Cleaning .reroute folder...
|
|
103567
104210
|
`));
|
|
@@ -103618,8 +104261,8 @@ async function copyAssets(cwd) {
|
|
|
103618
104261
|
const appSrc = config2.app?.src ?? "./src/client/App";
|
|
103619
104262
|
const dirname6 = __require("node:path").dirname;
|
|
103620
104263
|
const assetsPath = dirname6(appSrc);
|
|
103621
|
-
const sourceAssetsDir =
|
|
103622
|
-
const rerouteAssetsDir =
|
|
104264
|
+
const sourceAssetsDir = join14(cwd, assetsPath, "assets");
|
|
104265
|
+
const rerouteAssetsDir = join14(cwd, ".reroute", "assets");
|
|
103623
104266
|
process.stdout.write(colorizeLogPrefixAnsi(`[reroute/build] Copying assets...
|
|
103624
104267
|
`));
|
|
103625
104268
|
const fileCount = copyAssetsToReroute(cwd, sourceAssetsDir, rerouteAssetsDir);
|
|
@@ -103634,9 +104277,9 @@ async function copyAssets(cwd) {
|
|
|
103634
104277
|
async function buildBundle(cwd, buildArgs) {
|
|
103635
104278
|
const external = [...buildArgs.externalArgs, "sharp", "@vercel/og"];
|
|
103636
104279
|
const buildResult = await Bun.build({
|
|
103637
|
-
entrypoints: [
|
|
104280
|
+
entrypoints: [join14(cwd, ".reroute/entry.ts")],
|
|
103638
104281
|
target: "bun",
|
|
103639
|
-
outdir:
|
|
104282
|
+
outdir: join14(cwd, "dist"),
|
|
103640
104283
|
sourcemap: "external",
|
|
103641
104284
|
...getCommonBuildOptions(),
|
|
103642
104285
|
external,
|
|
@@ -103679,7 +104322,7 @@ function cleanupBundledFiles(rerouteDir) {
|
|
|
103679
104322
|
"markdown-components.ts"
|
|
103680
104323
|
];
|
|
103681
104324
|
for (const file of tsFilesToRemove) {
|
|
103682
|
-
const filePath =
|
|
104325
|
+
const filePath = join14(rerouteDir, file);
|
|
103683
104326
|
if (existsSync9(filePath)) {
|
|
103684
104327
|
try {
|
|
103685
104328
|
unlinkSync(filePath);
|
|
@@ -103689,7 +104332,7 @@ function cleanupBundledFiles(rerouteDir) {
|
|
|
103689
104332
|
}
|
|
103690
104333
|
const dirsToRemove = ["markdown", "streaming"];
|
|
103691
104334
|
for (const dir of dirsToRemove) {
|
|
103692
|
-
const dirPath =
|
|
104335
|
+
const dirPath = join14(rerouteDir, dir);
|
|
103693
104336
|
if (existsSync9(dirPath)) {
|
|
103694
104337
|
try {
|
|
103695
104338
|
rmSync(dirPath, { recursive: true });
|
|
@@ -103723,7 +104366,7 @@ async function build(args) {
|
|
|
103723
104366
|
await runGenCommand(rerouteCmd, useShell, buildArgs.noCompression);
|
|
103724
104367
|
await copyAssets(cwd);
|
|
103725
104368
|
await buildBundle(cwd, buildArgs);
|
|
103726
|
-
const rerouteDir =
|
|
104369
|
+
const rerouteDir = join14(cwd, ".reroute");
|
|
103727
104370
|
cleanupBundledFiles(rerouteDir);
|
|
103728
104371
|
logBuildComplete(buildStartTime, buildArgs);
|
|
103729
104372
|
process.exit(0);
|
|
@@ -103745,19 +104388,19 @@ __export(exports_command, {
|
|
|
103745
104388
|
getRerouteCommand: () => getRerouteCommand4
|
|
103746
104389
|
});
|
|
103747
104390
|
import { existsSync as existsSync10 } from "node:fs";
|
|
103748
|
-
import { join as
|
|
104391
|
+
import { join as join15 } from "node:path";
|
|
103749
104392
|
function getRerouteCommand4() {
|
|
103750
|
-
const binPath =
|
|
104393
|
+
const binPath = join15(import.meta.dir, "..", "..", "bin.ts");
|
|
103751
104394
|
const isBunDev = existsSync10(binPath);
|
|
103752
104395
|
if (isBunDev) {
|
|
103753
104396
|
return `bun ${binPath}`;
|
|
103754
104397
|
}
|
|
103755
104398
|
const cwd = process.cwd();
|
|
103756
104399
|
const nodeModulesPaths = [
|
|
103757
|
-
|
|
103758
|
-
|
|
103759
|
-
|
|
103760
|
-
|
|
104400
|
+
join15(cwd, "node_modules", ".bin", "reroute"),
|
|
104401
|
+
join15(cwd, "..", "node_modules", ".bin", "reroute"),
|
|
104402
|
+
join15(cwd, "..", "..", "node_modules", ".bin", "reroute"),
|
|
104403
|
+
join15(cwd, "..", "..", "..", "node_modules", ".bin", "reroute")
|
|
103761
104404
|
];
|
|
103762
104405
|
for (const binPath2 of nodeModulesPaths) {
|
|
103763
104406
|
if (existsSync10(binPath2)) {
|
|
@@ -103774,24 +104417,24 @@ __export(exports_analyze, {
|
|
|
103774
104417
|
default: () => analyze
|
|
103775
104418
|
});
|
|
103776
104419
|
import { existsSync as existsSync11, statSync } from "node:fs";
|
|
103777
|
-
import { readdir as
|
|
103778
|
-
import { basename as basename3, join as
|
|
104420
|
+
import { readdir as readdir8, readFile, stat as stat5, writeFile } from "node:fs/promises";
|
|
104421
|
+
import { basename as basename3, join as join16, relative as relative3 } from "node:path";
|
|
103779
104422
|
import Table from "cli-table3";
|
|
103780
104423
|
async function findChunkBundles(cwd) {
|
|
103781
104424
|
const bundles = [];
|
|
103782
|
-
const chunksDir =
|
|
104425
|
+
const chunksDir = join16(cwd, ".reroute", "chunks");
|
|
103783
104426
|
if (!existsSync11(chunksDir))
|
|
103784
104427
|
return bundles;
|
|
103785
|
-
const collections2 = await
|
|
104428
|
+
const collections2 = await readdir8(chunksDir, { withFileTypes: true });
|
|
103786
104429
|
for (const collection of collections2) {
|
|
103787
104430
|
if (!collection.isDirectory())
|
|
103788
104431
|
continue;
|
|
103789
|
-
const collectionDir =
|
|
103790
|
-
const files = await
|
|
104432
|
+
const collectionDir = join16(chunksDir, collection.name);
|
|
104433
|
+
const files = await readdir8(collectionDir);
|
|
103791
104434
|
for (const file of files) {
|
|
103792
104435
|
if (!file.endsWith(".js"))
|
|
103793
104436
|
continue;
|
|
103794
|
-
const filePath =
|
|
104437
|
+
const filePath = join16(collectionDir, file);
|
|
103795
104438
|
const stats = await stat5(filePath);
|
|
103796
104439
|
const content2 = await Bun.file(filePath).arrayBuffer();
|
|
103797
104440
|
const gzippedSize = Bun.gzipSync(new Uint8Array(content2)).length;
|
|
@@ -103809,12 +104452,12 @@ async function findChunkBundles(cwd) {
|
|
|
103809
104452
|
}
|
|
103810
104453
|
async function findDistBundles(cwd) {
|
|
103811
104454
|
const bundles = [];
|
|
103812
|
-
const distDir =
|
|
104455
|
+
const distDir = join16(cwd, "dist");
|
|
103813
104456
|
if (!existsSync11(distDir))
|
|
103814
104457
|
return bundles;
|
|
103815
|
-
const files = await
|
|
104458
|
+
const files = await readdir8(distDir);
|
|
103816
104459
|
for (const file of files) {
|
|
103817
|
-
const filePath =
|
|
104460
|
+
const filePath = join16(distDir, file);
|
|
103818
104461
|
const stats = statSync(filePath);
|
|
103819
104462
|
if (stats.isFile() && !file.endsWith(".map") && !file.endsWith(".d.ts")) {
|
|
103820
104463
|
const content2 = await Bun.file(filePath).arrayBuffer();
|
|
@@ -103840,9 +104483,9 @@ async function findBundles(cwd) {
|
|
|
103840
104483
|
}
|
|
103841
104484
|
async function findBrowserEntry(cwd) {
|
|
103842
104485
|
try {
|
|
103843
|
-
const clientDir =
|
|
103844
|
-
const tsxEntry =
|
|
103845
|
-
const tsEntry =
|
|
104486
|
+
const clientDir = join16(cwd, "src", "client");
|
|
104487
|
+
const tsxEntry = join16(clientDir, "index.tsx");
|
|
104488
|
+
const tsEntry = join16(clientDir, "index.ts");
|
|
103846
104489
|
let sourceEntry = null;
|
|
103847
104490
|
if (existsSync11(tsxEntry)) {
|
|
103848
104491
|
sourceEntry = tsxEntry;
|
|
@@ -103875,12 +104518,12 @@ async function findBrowserEntry(cwd) {
|
|
|
103875
104518
|
console.warn("[reroute/analyze] Browser build produced no outputs");
|
|
103876
104519
|
return null;
|
|
103877
104520
|
}
|
|
103878
|
-
const tempDir =
|
|
104521
|
+
const tempDir = join16(cwd, ".reroute", "browser");
|
|
103879
104522
|
await import("node:fs/promises").then((fs) => fs.mkdir(tempDir, { recursive: true }));
|
|
103880
104523
|
const output = result.outputs[0];
|
|
103881
104524
|
const code = await output.text();
|
|
103882
104525
|
const actualHash = await generateContentHash2(code);
|
|
103883
|
-
const bundlePath =
|
|
104526
|
+
const bundlePath = join16(tempDir, `index.${actualHash}.js`);
|
|
103884
104527
|
await writeFile(bundlePath, code, "utf-8");
|
|
103885
104528
|
const mapOutput = result.outputs.find((o) => o.path.endsWith(".map"));
|
|
103886
104529
|
if (mapOutput) {
|
|
@@ -103932,7 +104575,7 @@ function calculateStats(bundles) {
|
|
|
103932
104575
|
}
|
|
103933
104576
|
async function getInstalledPackageSizes(cwd) {
|
|
103934
104577
|
const packageSizes = new Map;
|
|
103935
|
-
const nodeModulesDir =
|
|
104578
|
+
const nodeModulesDir = join16(cwd, "node_modules");
|
|
103936
104579
|
if (!existsSync11(nodeModulesDir))
|
|
103937
104580
|
return packageSizes;
|
|
103938
104581
|
try {
|
|
@@ -103988,7 +104631,7 @@ async function buildDependencyTree(entryPath, cwd) {
|
|
|
103988
104631
|
if (!pkgNode) {
|
|
103989
104632
|
pkgNode = {
|
|
103990
104633
|
name: pkgName || "unknown",
|
|
103991
|
-
path:
|
|
104634
|
+
path: join16(cwd, "node_modules", pkgName || ""),
|
|
103992
104635
|
size: 0,
|
|
103993
104636
|
children: []
|
|
103994
104637
|
};
|
|
@@ -104009,7 +104652,7 @@ async function buildDependencyTree(entryPath, cwd) {
|
|
|
104009
104652
|
if (!child) {
|
|
104010
104653
|
child = {
|
|
104011
104654
|
name: part,
|
|
104012
|
-
path:
|
|
104655
|
+
path: join16(cwd, ...parts.slice(0, i + 1)),
|
|
104013
104656
|
size: 0,
|
|
104014
104657
|
children: []
|
|
104015
104658
|
};
|
|
@@ -104040,7 +104683,7 @@ async function buildDependencyTree(entryPath, cwd) {
|
|
|
104040
104683
|
const modulePattern = /\/\/\s*(.+?\.(?:ts|tsx|js|jsx|mjs|cjs))\s*$/gm;
|
|
104041
104684
|
const nodeModulesNode = {
|
|
104042
104685
|
name: "node_modules",
|
|
104043
|
-
path:
|
|
104686
|
+
path: join16(cwd, "node_modules"),
|
|
104044
104687
|
size: 0,
|
|
104045
104688
|
children: []
|
|
104046
104689
|
};
|
|
@@ -104106,7 +104749,7 @@ async function buildTreeFromSourceMap(bundlePath, cwd) {
|
|
|
104106
104749
|
if (sourcePath.startsWith("/") || sourcePath.match(/^[A-Za-z]:\\/))
|
|
104107
104750
|
return sourcePath;
|
|
104108
104751
|
const bundleDir = bundlePath.substring(0, bundlePath.lastIndexOf("/"));
|
|
104109
|
-
return
|
|
104752
|
+
return join16(bundleDir, sourceRoot || "", sourcePath);
|
|
104110
104753
|
}, computeSizes = function(node) {
|
|
104111
104754
|
if (node.children && node.children.length > 0) {
|
|
104112
104755
|
node.size = node.children.reduce((s, c) => s + computeSizes(c), 0);
|
|
@@ -104178,7 +104821,7 @@ async function buildTreeFromSourceMap(bundlePath, cwd) {
|
|
|
104178
104821
|
};
|
|
104179
104822
|
const nodeModulesNode = {
|
|
104180
104823
|
name: "node_modules",
|
|
104181
|
-
path:
|
|
104824
|
+
path: join16(cwd, "node_modules"),
|
|
104182
104825
|
size: 0,
|
|
104183
104826
|
children: []
|
|
104184
104827
|
};
|
|
@@ -104218,7 +104861,7 @@ async function buildTreeFromSourceMap(bundlePath, cwd) {
|
|
|
104218
104861
|
if (!pkgNode) {
|
|
104219
104862
|
pkgNode = {
|
|
104220
104863
|
name: pkgName || "unknown",
|
|
104221
|
-
path:
|
|
104864
|
+
path: join16(cwd, "node_modules", pkgName || ""),
|
|
104222
104865
|
size: 0,
|
|
104223
104866
|
children: []
|
|
104224
104867
|
};
|
|
@@ -104239,7 +104882,7 @@ async function buildTreeFromSourceMap(bundlePath, cwd) {
|
|
|
104239
104882
|
if (!child) {
|
|
104240
104883
|
child = {
|
|
104241
104884
|
name: part,
|
|
104242
|
-
path:
|
|
104885
|
+
path: join16(cwd, ...parts.slice(0, i2 + 1)),
|
|
104243
104886
|
size: 0,
|
|
104244
104887
|
children: []
|
|
104245
104888
|
};
|
|
@@ -104269,11 +104912,11 @@ async function generateHTMLReport(stats, depTree, mainInfo, browserDepTree, brow
|
|
|
104269
104912
|
let actualServerBinarySize = null;
|
|
104270
104913
|
let actualServerBinaryGzipped = null;
|
|
104271
104914
|
try {
|
|
104272
|
-
const distDir =
|
|
104915
|
+
const distDir = join16(process.cwd(), "dist");
|
|
104273
104916
|
if (existsSync11(distDir)) {
|
|
104274
|
-
const files = await
|
|
104917
|
+
const files = await readdir8(distDir);
|
|
104275
104918
|
for (const file of files) {
|
|
104276
|
-
const filePath =
|
|
104919
|
+
const filePath = join16(distDir, file);
|
|
104277
104920
|
const stats2 = statSync(filePath);
|
|
104278
104921
|
if (stats2.isFile() && !file.includes(".")) {
|
|
104279
104922
|
actualServerBinarySize = stats2.size;
|
|
@@ -105755,11 +106398,11 @@ async function printConsoleReport(stats, depTree, mainInfo, browserDepTree, brow
|
|
|
105755
106398
|
let actualServerBinarySize = null;
|
|
105756
106399
|
let actualServerBinaryGzipped = null;
|
|
105757
106400
|
try {
|
|
105758
|
-
const distDir =
|
|
106401
|
+
const distDir = join16(process.cwd(), "dist");
|
|
105759
106402
|
if (existsSync11(distDir)) {
|
|
105760
|
-
const files = await
|
|
106403
|
+
const files = await readdir8(distDir);
|
|
105761
106404
|
for (const file of files) {
|
|
105762
|
-
const filePath =
|
|
106405
|
+
const filePath = join16(distDir, file);
|
|
105763
106406
|
const stats2 = statSync(filePath);
|
|
105764
106407
|
if (stats2.isFile() && !file.includes(".")) {
|
|
105765
106408
|
actualServerBinarySize = stats2.size;
|
|
@@ -105793,7 +106436,7 @@ async function analyze(args) {
|
|
|
105793
106436
|
const isProd = isProductionMode(args);
|
|
105794
106437
|
const searchIndex = args.indexOf("--search");
|
|
105795
106438
|
const initialSearch = searchIndex !== -1 && args[searchIndex + 1] ? args[searchIndex + 1] : "";
|
|
105796
|
-
const rerouteIndexPath =
|
|
106439
|
+
const rerouteIndexPath = join16(cwd, ".reroute", "index.ts");
|
|
105797
106440
|
if (!existsSync11(rerouteIndexPath)) {
|
|
105798
106441
|
console.log(colorizeLogPrefixAnsi(`[reroute/analyze] .reroute artifacts not found, running build...
|
|
105799
106442
|
`));
|
|
@@ -105856,12 +106499,12 @@ async function analyze(args) {
|
|
|
105856
106499
|
let entry = null;
|
|
105857
106500
|
let depTree = null;
|
|
105858
106501
|
let mainInfo = null;
|
|
105859
|
-
const srcEntry =
|
|
106502
|
+
const srcEntry = join16(cwd, "src", "index.ts");
|
|
105860
106503
|
if (existsSync11(srcEntry)) {
|
|
105861
106504
|
console.log(colorizeLogPrefixAnsi(`[reroute/analyze] Building server binary for analysis...
|
|
105862
106505
|
`));
|
|
105863
106506
|
const { mkdir: mkdir3 } = await import("node:fs/promises");
|
|
105864
|
-
const serverAnalysisDir =
|
|
106507
|
+
const serverAnalysisDir = join16(cwd, ".reroute", "server");
|
|
105865
106508
|
await mkdir3(serverAnalysisDir, { recursive: true });
|
|
105866
106509
|
const result = await Bun.build({
|
|
105867
106510
|
entrypoints: [srcEntry],
|
|
@@ -105874,7 +106517,7 @@ async function analyze(args) {
|
|
|
105874
106517
|
if (result.success && result.outputs.length > 0) {
|
|
105875
106518
|
const output = result.outputs[0];
|
|
105876
106519
|
const code = await output.text();
|
|
105877
|
-
const analysisEntry =
|
|
106520
|
+
const analysisEntry = join16(serverAnalysisDir, "index.js");
|
|
105878
106521
|
await writeFile(analysisEntry, code, "utf-8");
|
|
105879
106522
|
const mapOutput = result.outputs.find((o) => o.path.endsWith(".map"));
|
|
105880
106523
|
if (mapOutput) {
|
|
@@ -105892,7 +106535,7 @@ async function analyze(args) {
|
|
|
105892
106535
|
`));
|
|
105893
106536
|
const installedSizes = await getInstalledPackageSizes(cwd);
|
|
105894
106537
|
if (depTree) {
|
|
105895
|
-
const packageJsonPath =
|
|
106538
|
+
const packageJsonPath = join16(cwd, "package.json");
|
|
105896
106539
|
if (existsSync11(packageJsonPath)) {
|
|
105897
106540
|
try {
|
|
105898
106541
|
const packageJson = JSON.parse(await readFile(packageJsonPath, "utf-8"));
|
|
@@ -105904,7 +106547,7 @@ async function analyze(args) {
|
|
|
105904
106547
|
if (!trackedPkgs.has(pkgName) && installedSizes.has(pkgName)) {
|
|
105905
106548
|
nodeModulesNode.children?.push({
|
|
105906
106549
|
name: pkgName,
|
|
105907
|
-
path:
|
|
106550
|
+
path: join16(cwd, "node_modules", pkgName),
|
|
105908
106551
|
size: installedSizes.get(pkgName) || 0
|
|
105909
106552
|
});
|
|
105910
106553
|
}
|
|
@@ -105935,10 +106578,10 @@ async function analyze(args) {
|
|
|
105935
106578
|
const fullOutput = args.includes("--full");
|
|
105936
106579
|
await printConsoleReport(stats, depTree, mainInfo, browserDepTree, browserInfo, fullOutput);
|
|
105937
106580
|
if (outputHtml || openBrowser) {
|
|
105938
|
-
const htmlPath =
|
|
106581
|
+
const htmlPath = join16(cwd, ".reroute", "analysis.html");
|
|
105939
106582
|
const html2 = await generateHTMLReport(stats, depTree, mainInfo, browserDepTree, browserInfo, initialSearch);
|
|
105940
106583
|
const { mkdir: mkdir3 } = await import("node:fs/promises");
|
|
105941
|
-
await mkdir3(
|
|
106584
|
+
await mkdir3(join16(cwd, ".reroute"), { recursive: true });
|
|
105942
106585
|
await writeFile(htmlPath, html2, "utf-8");
|
|
105943
106586
|
console.log(colorizeLogPrefixAnsi(`[reroute/analyze] HTML report generated: ${relative3(cwd, htmlPath)}
|
|
105944
106587
|
`));
|
|
@@ -106001,8 +106644,8 @@ __export(exports_og, {
|
|
|
106001
106644
|
default: () => og2
|
|
106002
106645
|
});
|
|
106003
106646
|
import { spawn as spawn5 } from "node:child_process";
|
|
106004
|
-
import { readdir as
|
|
106005
|
-
import { join as
|
|
106647
|
+
import { readdir as readdir9 } from "node:fs/promises";
|
|
106648
|
+
import { join as join17 } from "node:path";
|
|
106006
106649
|
function getPortFromConfig(baseUrl) {
|
|
106007
106650
|
if (!baseUrl)
|
|
106008
106651
|
return 3000;
|
|
@@ -106079,10 +106722,10 @@ Error output:`, errorOutput);
|
|
|
106079
106722
|
}
|
|
106080
106723
|
async function scanForOgTemplates(dir, base, routes) {
|
|
106081
106724
|
try {
|
|
106082
|
-
const entries = await
|
|
106725
|
+
const entries = await readdir9(dir, { withFileTypes: true });
|
|
106083
106726
|
for (const entry of entries) {
|
|
106084
|
-
const fullPath =
|
|
106085
|
-
const relativePath =
|
|
106727
|
+
const fullPath = join17(dir, entry.name);
|
|
106728
|
+
const relativePath = join17(base, entry.name);
|
|
106086
106729
|
if (entry.isDirectory()) {
|
|
106087
106730
|
if (entry.name === "content")
|
|
106088
106731
|
continue;
|
|
@@ -106099,13 +106742,13 @@ function findFirstContentFile(contentFiles) {
|
|
|
106099
106742
|
}
|
|
106100
106743
|
async function addContentRoutes(routesPath, routes) {
|
|
106101
106744
|
try {
|
|
106102
|
-
const entries = await
|
|
106745
|
+
const entries = await readdir9(routesPath, { withFileTypes: true });
|
|
106103
106746
|
for (const entry of entries) {
|
|
106104
106747
|
if (!entry.isDirectory())
|
|
106105
106748
|
continue;
|
|
106106
|
-
const contentDir =
|
|
106749
|
+
const contentDir = join17(routesPath, entry.name, "content");
|
|
106107
106750
|
try {
|
|
106108
|
-
const contentFiles = await
|
|
106751
|
+
const contentFiles = await readdir9(contentDir);
|
|
106109
106752
|
if (contentFiles.length === 0)
|
|
106110
106753
|
continue;
|
|
106111
106754
|
const firstFile = findFirstContentFile(contentFiles);
|
|
@@ -106120,7 +106763,7 @@ async function addContentRoutes(routesPath, routes) {
|
|
|
106120
106763
|
async function findRoutesWithOG(cwd) {
|
|
106121
106764
|
const routes = [];
|
|
106122
106765
|
try {
|
|
106123
|
-
const manifestPath =
|
|
106766
|
+
const manifestPath = join17(cwd, ".reroute", "manifest.json");
|
|
106124
106767
|
const manifestFile = Bun.file(manifestPath);
|
|
106125
106768
|
const manifest = await manifestFile.json();
|
|
106126
106769
|
if (manifest.staticRoutes && Array.isArray(manifest.staticRoutes)) {
|
|
@@ -106131,7 +106774,7 @@ async function findRoutesWithOG(cwd) {
|
|
|
106131
106774
|
}
|
|
106132
106775
|
} catch {
|
|
106133
106776
|
console.warn("⚠️ .reroute/manifest.json not found, scanning routes directory...");
|
|
106134
|
-
const routesPath =
|
|
106777
|
+
const routesPath = join17(cwd, ROUTES_DIR2);
|
|
106135
106778
|
await scanForOgTemplates(routesPath, "", routes);
|
|
106136
106779
|
await addContentRoutes(routesPath, routes);
|
|
106137
106780
|
}
|
|
@@ -106383,7 +107026,7 @@ async function getVersionString2() {
|
|
|
106383
107026
|
}
|
|
106384
107027
|
async function getVersion2() {
|
|
106385
107028
|
if (true) {
|
|
106386
|
-
return "0.
|
|
107029
|
+
return "0.46.0";
|
|
106387
107030
|
}
|
|
106388
107031
|
const possiblePaths = [
|
|
106389
107032
|
path3.join(import.meta.dir, "../../../package.json"),
|
|
@@ -106400,10 +107043,10 @@ async function getVersion2() {
|
|
|
106400
107043
|
}
|
|
106401
107044
|
async function getCommit2() {
|
|
106402
107045
|
if (true) {
|
|
106403
|
-
return "
|
|
107046
|
+
return "9116acf";
|
|
106404
107047
|
}
|
|
106405
107048
|
return "dev";
|
|
106406
107049
|
}
|
|
106407
107050
|
main();
|
|
106408
107051
|
|
|
106409
|
-
//# debugId=
|
|
107052
|
+
//# debugId=0B12295AB270224764756E2164756E21
|